Part 3: Reading and running the modified OpenMDAO Assembly
This is the last of three Jupyter Notebooks that show an example of the workflow pictured below:
In this notebook engineer 3 is getting the modified assembly JSON file, and can load this in their Jupyter Notebook environment and create a new OpenMDAO assembly. This can now be executed. We also use the subset of the state from the original setup. Note that someone can even edit the HDF5 file separately and that would be reflected in this.
Note: Someone can even edit the HDF5 file separately and that would be reflected in this.
from standard_evaluator import load_assembly
import openmdao.api as om
matlabengine not available.
new_file_name = "after.json"
# Now loading the structure and state from these files
new_problem = load_assembly(assembly_name=new_file_name, state_name='state.h5')
** This is a group, special handling needed for prep_geom in group
Adding nacelles component
Building class nacelles
Importing class Nacelles from aviary.subsystems.geometry.flops_based.nacelle
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Cell In[2], line 3
1 new_file_name = "after.json"
2 # Now loading the structure and state from these files
----> 3 new_problem = load_assembly(assembly_name=new_file_name, state_name='state.h5')
File /opt/hostedtoolcache/Python/3.11.15/x64/lib/python3.11/site-packages/standard_evaluator/om_converter.py:540, in load_assembly(assembly_name, state_name)
538 info_dict = convert_dict(info_dict)
539 info = GroupInfo.model_validate(info_dict)
--> 540 problem = create_problem(info)
541 # We want to make sure we use the actual info from the problem
542 info = get_interface(problem.model)
File /opt/hostedtoolcache/Python/3.11.15/x64/lib/python3.11/site-packages/standard_evaluator/om_converter.py:482, in create_problem(info, state, opt_problem)
480 def create_problem(info: JoinedInfo, state: typing.Dict[str, np.array] = {}, opt_problem: OptProblem = None) -> om.Problem:
481 """ Create an OpenMDAO problem based on the information in the JoinedInfo instance"""
--> 482 component = add_group(info)
484 # prob = om.Problem(my_group)
485 prob = om.Problem(component)
File /opt/hostedtoolcache/Python/3.11.15/x64/lib/python3.11/site-packages/standard_evaluator/om_converter.py:466, in add_group(comp_info)
464 if local_info.class_type == 'GroupInfo':
465 print(f"** This is a group, special handling needed for {local_name} in group {comp_info.name}")
--> 466 component = add_group(comp_info=local_info)
467 else:
468 # This is a component, so we directly create it.
469 print(f"Adding {local_name} component")
File /opt/hostedtoolcache/Python/3.11.15/x64/lib/python3.11/site-packages/standard_evaluator/om_converter.py:470, in add_group(comp_info)
467 else:
468 # This is a component, so we directly create it.
469 print(f"Adding {local_name} component")
--> 470 component = add_group(local_info)
471 final_component.add_subsystem(name=local_name,
472 subsys=component,
473 promotes=clean_promotions(comp_info.promotions[local_name], local_name))
474 # Now create the linkages between components
File /opt/hostedtoolcache/Python/3.11.15/x64/lib/python3.11/site-packages/standard_evaluator/om_converter.py:459, in add_group(comp_info)
457 final_component = create_equation_component(comp_info)
458 elif comp_info.class_type == 'EvaluatorInfo':
--> 459 final_component = create_explicit_component(comp_info)
460 else:
461 final_component = om.Group()
File /opt/hostedtoolcache/Python/3.11.15/x64/lib/python3.11/site-packages/standard_evaluator/om_converter.py:395, in create_explicit_component(info)
393 # Import the library that defines the component
394 local_library = importlib.import_module(package)
--> 395 local_class = getattr(local_library, class_name)
396 openmdao_options = create_openmdao_options(copy.deepcopy(info.options['openmdao_options']))
397 return(local_class(**openmdao_options))
AttributeError: module 'aviary.subsystems.geometry.flops_based.nacelle' has no attribute 'Nacelles'
After loading and recreating the model we can run it and see its inputs and outputs.
new_problem.run_model()
_ = new_problem.model.list_inputs(shape=True, units=True)
59 Input(s) in 'model'
varname val units shape prom_name
--------------------------------------------------- --------------- -------- ----- -----------------------------------------------
prep_geom
nacelles
aircraft:nacelle:avg_diameter [7.94] ft (1,) aircraft:nacelle:avg_diameter
aircraft:nacelle:avg_length [12.3] ft (1,) aircraft:nacelle:avg_length
aircraft:nacelle:wetted_area_scaler [1.] unitless (1,) aircraft:nacelle:wetted_area_scaler
canard
aircraft:canard:area [0.] ft**2 (1,) aircraft:canard:area
aircraft:canard:thickness_to_chord [0.] unitless (1,) aircraft:canard:thickness_to_chord
aircraft:canard:wetted_area_scaler [1.] unitless (1,) aircraft:canard:wetted_area_scaler
fuselage_prelim
aircraft:fuselage:length [128.] ft (1,) aircraft:fuselage:length
aircraft:fuselage:max_height [13.17] ft (1,) aircraft:fuselage:max_height
aircraft:fuselage:max_width [12.33] ft (1,) aircraft:fuselage:max_width
wing_prelim
aircraft:wing:area [1370.] ft**2 (1,) aircraft:wing:area
aircraft:wing:glove_and_bat [134.] ft**2 (1,) aircraft:wing:glove_and_bat
aircraft:wing:span [117.83] ft (1,) aircraft:wing:span
prelim
aircraft:fuselage:avg_diameter [12.75] ft (1,) aircraft:fuselage:avg_diameter
aircraft:fuselage:max_width [12.33] ft (1,) aircraft:fuselage:max_width
aircraft:horizontal_tail:area [355.] ft**2 (1,) aircraft:horizontal_tail:area
aircraft:horizontal_tail:aspect_ratio [6.] unitless (1,) aircraft:horizontal_tail:aspect_ratio
aircraft:horizontal_tail:taper_ratio [0.22] unitless (1,) aircraft:horizontal_tail:taper_ratio
aircraft:horizontal_tail:thickness_to_chord [0.125] unitless (1,) aircraft:horizontal_tail:thickness_to_chord
aircraft:vertical_tail:area [284.] ft**2 (1,) aircraft:vertical_tail:area
aircraft:vertical_tail:aspect_ratio [1.75] unitless (1,) aircraft:vertical_tail:aspect_ratio
aircraft:vertical_tail:taper_ratio [0.33] unitless (1,) aircraft:vertical_tail:taper_ratio
aircraft:vertical_tail:thickness_to_chord [0.1195] unitless (1,) aircraft:vertical_tail:thickness_to_chord
aircraft:wing:area [1370.] ft**2 (1,) aircraft:wing:area
aircraft:wing:glove_and_bat [134.] ft**2 (1,) aircraft:wing:glove_and_bat
aircraft:wing:span [117.83] ft (1,) aircraft:wing:span
aircraft:wing:taper_ratio [0.278] unitless (1,) aircraft:wing:taper_ratio
aircraft:wing:thickness_to_chord [0.13] unitless (1,) aircraft:wing:thickness_to_chord
wing
prep_geom:_Names:CROOT [16.415788] unitless (1,) wing.prep_geom:_Names:CROOT
prep_geom:_Names:CROOTB [15.13330021] unitless (1,) wing.prep_geom:_Names:CROOTB
prep_geom:_Names:XDX [12.75] unitless (1,) wing.prep_geom:_Names:XDX
prep_geom:_Names:XMULT [2.05031] unitless (1,) wing.prep_geom:_Names:XMULT
aircraft:wing:area [1370.] ft**2 (1,) aircraft:wing:area
aircraft:wing:wetted_area_scaler [1.] unitless (1,) aircraft:wing:wetted_area_scaler
tail
prep_geom:_Names:XMULTH [2.048375] unitless (1,) tail.prep_geom:_Names:XMULTH
prep_geom:_Names:XMULTV [2.0462465] unitless (1,) tail.prep_geom:_Names:XMULTV
aircraft:horizontal_tail:area [355.] ft**2 (1,) aircraft:horizontal_tail:area
aircraft:horizontal_tail:vertical_tail_fraction [0.] unitless (1,) aircraft:horizontal_tail:vertical_tail_fraction
aircraft:horizontal_tail:wetted_area_scaler [1.] unitless (1,) aircraft:horizontal_tail:wetted_area_scaler
aircraft:vertical_tail:area [284.] ft**2 (1,) aircraft:vertical_tail:area
aircraft:vertical_tail:wetted_area_scaler [1.] unitless (1,) aircraft:vertical_tail:wetted_area_scaler
fuselage
prep_geom:_Names:CROOTB [15.13330021] unitless (1,) fuselage.prep_geom:_Names:CROOTB
prep_geom:_Names:CROTVT [19.15660306] unitless (1,) fuselage.prep_geom:_Names:CROTVT
prep_geom:_Names:CRTHTB [13.50207305] unitless (1,) fuselage.prep_geom:_Names:CRTHTB
aircraft:fuselage:avg_diameter [12.75] ft (1,) aircraft:fuselage:avg_diameter
aircraft:fuselage:length [128.] ft (1,) aircraft:fuselage:length
aircraft:fuselage:wetted_area_scaler [1.] unitless (1,) aircraft:fuselage:wetted_area_scaler
aircraft:horizontal_tail:thickness_to_chord [0.125] unitless (1,) aircraft:horizontal_tail:thickness_to_chord
aircraft:horizontal_tail:vertical_tail_fraction [0.] unitless (1,) aircraft:horizontal_tail:vertical_tail_fraction
aircraft:vertical_tail:thickness_to_chord [0.1195] unitless (1,) aircraft:vertical_tail:thickness_to_chord
aircraft:wing:area [1370.] ft**2 (1,) aircraft:wing:area
aircraft:wing:aspect_ratio [11.232936] unitless (1,) aircraft:wing:aspect_ratio
aircraft:wing:glove_and_bat [134.] ft**2 (1,) aircraft:wing:glove_and_bat
aircraft:wing:thickness_to_chord [0.13] unitless (1,) aircraft:wing:thickness_to_chord
total_wetted_area
aircraft:canard:wetted_area [0.] ft**2 (1,) aircraft:canard:wetted_area
aircraft:fuselage:wetted_area [4158.62066062] ft**2 (1,) aircraft:fuselage:wetted_area
aircraft:horizontal_tail:wetted_area [592.64609688] ft**2 (1,) aircraft:horizontal_tail:wetted_area
aircraft:nacelle:total_wetted_area [546.9072] ft**2 (1,) aircraft:nacelle:total_wetted_area
aircraft:vertical_tail:wetted_area [581.134006] ft**2 (1,) aircraft:vertical_tail:wetted_area
aircraft:wing:wetted_area [2396.55520449] ft**2 (1,) aircraft:wing:wetted_area
_ = new_problem.model.list_outputs(shape=True)
25 Explicit Output(s) in 'model'
varname val shape prom_name
------------------------------------------- --------------- ----- ---------------------------------------
prep_geom
nacelles
aircraft:nacelle:total_wetted_area [546.9072] (1,) aircraft:nacelle:total_wetted_area
aircraft:nacelle:wetted_area [273.4536] (1,) aircraft:nacelle:wetted_area
canard
aircraft:canard:wetted_area [0.] (1,) aircraft:canard:wetted_area
fuselage_prelim
aircraft:fuselage:avg_diameter [12.75] (1,) aircraft:fuselage:avg_diameter
aircraft:fuselage:planform_area [1578.24] (1,) aircraft:fuselage:planform_area
wing_prelim
aircraft:wing:aspect_ratio [11.232936] (1,) aircraft:wing:aspect_ratio
prelim
prep_geom:_Names:CROOT [16.415788] (1,) prelim.prep_geom:_Names:CROOT
prep_geom:_Names:CROOTB [15.13330021] (1,) prelim.prep_geom:_Names:CROOTB
prep_geom:_Names:CROTM [0.92187473] (1,) prelim.prep_geom:_Names:CROTM
prep_geom:_Names:CROTVT [19.15660306] (1,) prelim.prep_geom:_Names:CROTVT
prep_geom:_Names:CRTHTB [13.50207305] (1,) prelim.prep_geom:_Names:CRTHTB
prep_geom:_Names:SPANHT [46.15192304] (1,) prelim.prep_geom:_Names:SPANHT
prep_geom:_Names:SPANVT [22.29349681] (1,) prelim.prep_geom:_Names:SPANVT
prep_geom:_Names:XDX [12.75] (1,) prelim.prep_geom:_Names:XDX
prep_geom:_Names:XMULT [2.05031] (1,) prelim.prep_geom:_Names:XMULT
prep_geom:_Names:XMULTH [2.048375] (1,) prelim.prep_geom:_Names:XMULTH
prep_geom:_Names:XMULTV [2.0462465] (1,) prelim.prep_geom:_Names:XMULTV
wing
aircraft:wing:wetted_area [2396.55520449] (1,) aircraft:wing:wetted_area
tail
aircraft:horizontal_tail:wetted_area [592.64609688] (1,) aircraft:horizontal_tail:wetted_area
aircraft:vertical_tail:wetted_area [581.134006] (1,) aircraft:vertical_tail:wetted_area
fuselage
aircraft:fuselage:cross_section [127.67628894] (1,) aircraft:fuselage:cross_section
aircraft:fuselage:diameter_to_wing_span [0.10820674] (1,) aircraft:fuselage:diameter_to_wing_span
aircraft:fuselage:length_to_diameter [10.03921569] (1,) aircraft:fuselage:length_to_diameter
aircraft:fuselage:wetted_area [4158.62066062] (1,) aircraft:fuselage:wetted_area
total_wetted_area
aircraft:design:total_wetted_area [8275.86316799] (1,) aircraft:design:total_wetted_area
0 Implicit Output(s) in 'model'
We can now also look at the N2 diagram of the model, and see the re-ordering happened, and the characteristic_lenghts component is no longer in the model.
import os
# Check if running in VS Code
if 'VSCODE_PID' in os.environ:
display_in_notebook = False
else:
display_in_notebook = True
om.n2(new_problem, 'after.n2.html', display_in_notebook=display_in_notebook, )