OpenMDAO / OpenMDAO

OpenMDAO repository.
http://openmdao.org
Other
563 stars 254 forks source link

Assigning complex value to component output raises a warning #668

Closed bbrelje closed 5 years ago

bbrelje commented 6 years ago

Discovered this while writing unit tests for a new component. Within the component, I allocate a numpy placeholder array as complex if the user specifies complex=True as an option (in case they're using CS derivatives for testing).

I think the following warning is being raised when I assign output['my_variable'] = computed_value within the compute() method of my component, but pytest isn't providing the entire stack trace so I can't be sure.

force_alloc_complex is True and the cs derivatives are being computed correctly.

`openconcept/utilities/math/tests/test_multiply_divide_comp.py::TestElementMultiplyDivideDivisionFirst::test_partials C:\Users\Ben\Anaconda3\lib\site-packages\openmdao\vectors\vector.py:421: ComplexWarning: Casting complex values to real discards the imaginary part self._views[abs_name][slc] = value

openconcept/utilities/math/tests/test_multiply_divide_comp.py::TestElementMultiplyDivideDivisionFirst::test_results C:\Users\Ben\Anaconda3\lib\site-packages\openmdao\vectors\vector.py:421: ComplexWarning: Casting complex values to real discards the imaginary part self._views[abs_name][slc] = value`

Kenneth-T-Moore commented 5 years ago

Hey, bbrelje.

We have a way now to deal with placeholder arrays like the one you mention. Every component has a flag named under_complex_step that you can query so that you know if you are under complex step. In yourcompute function, when that flag is True, then you should allocate your placeholder array as complex instead of float. So, something like this:

if self.under_complex_step:
    placeholder = np.zeros(shape, dtype=np.complex)
else:
    placeholder = np.zeros(shape)

There is a small example in the docs:

http://openmdao.org/twodocs/versions/latest/features/core_features/working_with_derivatives/approximating_partials.html#complex-step

bbrelje commented 5 years ago

Thanks! I'll start using that. That's an elegant way to fix the issue. Is it fair to say that each and every time self.under_complex_step is true that self._views[abs_name][slc] will be complex as well (thus not throwing the ComplexWarning)?

Kenneth-T-Moore commented 5 years ago

That is correct. Underneath the covers, the vector swaps its views between a float and a complex one depending on whether you are under complex step.