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:

Process showing separation of creation, editing, and use of MDAO models

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,  )