Open iiwolf opened 4 weeks ago
After some ripgrep
ing I found the Jupyter notebook that Externally Computed Aero is based off of. This was great because apparently page was hiding the code I needed to see. Namely the definition of ExternalAero
and the definition of the compute
method (look at that, I guessed right!).
I'm understanding better now, but this example doesn't actually run/solve the Aviary problem. When I added a prob.run_aviary_problem('history.db')
to the end of the Jupyter notebook, it fails with the error shown below.
Traceback (most recent call last):
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\solvers\linear\direct.py", line 320, in _linearize
self._lu = scipy.sparse.linalg.splu(matrix)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\scipy\sparse\linalg\_dsolve\linsolve.py", line 438, in splu
return _superlu.gstrf(N, A.nnz, A.data, indices, indptr,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
RuntimeError: Factor is exactly singular
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\UserA\projects\aviary\working_dir\plane\run_level2_external_aero.py", line 149, in <module>
prob.run_aviary_problem(record_filename)
File "C:\Users\UserA\projects\aviary\aviary\interface\methods_for_level2.py", line 2314, in run_aviary_problem
failed = dm.run_problem(self, run_driver=run_driver, simulate=simulate, make_plots=make_plots,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\dymos\run_problem.py", line 96, in run_problem
failed = _refine_iter(problem, refine_iteration_limit, refine_method, case_prefix=case_prefix,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\dymos\grid_refinement\refinement.py", line 40, in _refine_iter
failed = problem.run_driver(case_prefix=case_prefix if refine_iteration_limit > 0 else _case_prefix,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\utils\hooks.py", line 372, in __call__
ret = self.func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\core\problem.py", line 745, in run_driver
return driver._run()
^^^^^^^^^^^^^
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\core\driver.py", line 791, in _run
self.result.success = not self.run()
^^^^^^^^^^
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\drivers\scipy_optimizer.py", line 268, in run
self._run_solve_nonlinear()
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\core\driver.py", line 177, in wrapper
ret = func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\core\driver.py", line 1237, in _run_solve_nonlinear
return self._problem().model.run_solve_nonlinear()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\core\system.py", line 4676, in run_solve_nonlinear
self._solve_nonlinear()
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\core\group.py", line 3484, in _solve_nonlinear
self._nonlinear_solver._solve_with_cache_check()
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\solvers\nonlinear\nonlinear_runonce.py", line 26, in _solve_with_cache_check
self.solve() # don't use caching
^^^^^^^^^^^^
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\solvers\nonlinear\nonlinear_runonce.py", line 45, in solve
self._gs_iter()
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\solvers\solver.py", line 865, in _gs_iter
subsys._solve_nonlinear()
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\core\group.py", line 3484, in _solve_nonlinear
self._nonlinear_solver._solve_with_cache_check()
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\solvers\nonlinear\nonlinear_runonce.py", line 26, in _solve_with_cache_check
self.solve() # don't use caching
^^^^^^^^^^^^
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\solvers\nonlinear\nonlinear_runonce.py", line 45, in solve
self._gs_iter()
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\solvers\solver.py", line 865, in _gs_iter
subsys._solve_nonlinear()
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\core\group.py", line 3484, in _solve_nonlinear
self._nonlinear_solver._solve_with_cache_check()
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\solvers\nonlinear\nonlinear_runonce.py", line 26, in _solve_with_cache_check
self.solve() # don't use caching
^^^^^^^^^^^^
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\solvers\nonlinear\nonlinear_runonce.py", line 45, in solve
self._gs_iter()
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\solvers\solver.py", line 865, in _gs_iter
subsys._solve_nonlinear()
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\core\group.py", line 3484, in _solve_nonlinear
self._nonlinear_solver._solve_with_cache_check()
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\solvers\nonlinear\nonlinear_runonce.py", line 26, in _solve_with_cache_check
self.solve() # don't use caching
^^^^^^^^^^^^
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\solvers\nonlinear\nonlinear_runonce.py", line 45, in solve
self._gs_iter()
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\solvers\solver.py", line 865, in _gs_iter
subsys._solve_nonlinear()
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\core\group.py", line 3484, in _solve_nonlinear
self._nonlinear_solver._solve_with_cache_check()
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\solvers\solver.py", line 907, in _solve_with_cache_check
self.solve()
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\solvers\solver.py", line 669, in solve
raise err
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\solvers\solver.py", line 665, in solve
self._solve()
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\solvers\solver.py", line 712, in _solve
norm0, norm = self._iter_initialize()
^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\solvers\nonlinear\newton.py", line 196, in _iter_initialize
self._gs_iter()
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\solvers\solver.py", line 865, in _gs_iter
subsys._solve_nonlinear()
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\core\group.py", line 3484, in _solve_nonlinear
self._nonlinear_solver._solve_with_cache_check()
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\solvers\solver.py", line 907, in _solve_with_cache_check
self.solve()
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\solvers\solver.py", line 669, in solve
raise err
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\solvers\solver.py", line 665, in solve
self._solve()
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\solvers\solver.py", line 752, in _solve
self._single_iteration()
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\solvers\nonlinear\newton.py", line 233, in _single_iteration
self._linearize()
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\solvers\nonlinear\newton.py", line 161, in _linearize
self.linear_solver._linearize()
File "C:\Users\UserA\Anaconda3\envs\aviary\Lib\site-packages\openmdao\solvers\linear\direct.py", line 322, in _linearize
raise RuntimeError(format_singular_error(system, matrix))
RuntimeError: Singular entry found in 'traj.phases.climb.rhs_all.core_aerodynamics' <class SolvedAlphaGroup> for column associated with
state/residual 'balance.alpha' ('traj.phases.climb.rhs_all.core_aerodynamics.balance.alpha') index 0.
I saw the note about the compute
function doing nothing in this case, just returning the table values. If I understand correctly, that should look up CL/CD based on in inputs
to the function correct? I'm a little confused on the different between inputs and options. At the risk of seeming dumb, it seems to me they are switched? In the majority of cases area and span are constant, and you want to lookup on mach, alpha, and altitude. I may be misunderstanding the purpose of this block though.
def setup(self):
altitude = self.options['altitude']
mach = self.options['mach']
angle_of_attack = self.options['angle_of_attack']
self.add_input(Aircraft.Wing.AREA, 1.0, units='ft**2')
self.add_input(Aircraft.Wing.SPAN, 1.0, units='ft')
shape = (len(altitude), len(mach), len(angle_of_attack))
self.add_output('drag_table', shape=shape, units='unitless')
self.add_output('lift_table', shape=shape, units='unitless')
def compute(self, inputs, outputs):
"""
This component doesn't do anything, except set the drag and lift
polars from the file we read in.
"""
outputs['drag_table'] = CD
outputs['lift_table'] = CL
Thanks for your time!
Hey, iiwolf. Yeah, that drag polar component is purely notional. A real one would actually calculate lift and drag using inputs like area and span, but this was meant to be a simple test and example, so it basically "cheats".
As for the NANs -- I think there must be something else wrong in this model. We will have to take a look. We have done some recent refactoring, so this might be an example we missed.
Yeah, looks like there's a hole in our docs on available options for aero. Let me try and fill that gap here.
Aerodynamics has many methodologies you can use during a given mission phase. For example, for FLOPS-based aero you can select computed
, low_speed
, or tabular
in your phase_info
file.
What's missing is that there are additional options that can be selected for each of these methods. For tabular areo, I can point you to the part of the code that reads in that table. We have some options for that component related to passing data. You want CD0_data
(that's a zero, not an "o"), and CDI_data
, which can be either a filepath or a NamedValues
object with the data in memory.
So your phase info might have something like this for a given phase:
{'core_aerodynamics': {'method': 'tabular',
'CD0_table': 'path/to/data/table'
'CDI_table': 'path/to/other/table'}
Sorry I'm just seeing these now - in the future if you post general questions in discussions I will see them much faster
Ok great this is helping clear things up. I have a few follow-ups but I will post them in discussions as suggested.
Thank you!
Desired documentation content.
Hello,
Apologies if I've missed it somewhere, but is there an example on how to use an existing aero deck? Some examples come close, but never actually detail how to use the files. I believe I have formatted the aero deck as it should be, e.g.
But then how do I specify that in an input file or even level 2 script? e.g. I figured you could do something like this
My existing research / what I tried
ExternalAero
should return. i.e. do I have to write acompute
orlookup
method?aero_data_file
);", yet that is the only time that is mentioned in the guideripgrep
ing the repo for places that might assignaero_data_file
,drag_polar
orlift_polar
, but didn't find any examples.Thanks!
Is there any existing documentation on your requested topic? Please describe.
https://openmdao.github.io/Aviary/user_guide/aerodynamics.html#user-specified-tabular-drag-polars https://openmdao.github.io/Aviary/user_guide/external_aero.html https://openmdao.github.io/Aviary/getting_started/onboarding_level2.html#summary