Part 2: Editing the OpenMDAO Assembly

This is the second 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 2 is editing the assembly to remove the characteristic_lenghts component from it. This is done by editing the JSON file and creating a new JSON file that only has the definitions of the components needed to do the calculations.

We also re-order the components to move the nacelles and canard component to the top of the assembly to demonstrate how easy it is to change the order of the components in the assembly.

Note: In this example the manipulation of the Python dictionary that was created from the JSON file is very manual and not automated. This was just done to demonstrate the ability to edit the JSON directly. Automation in Python or any other language can be developed to make this easier and less error prone.
Note: For example, we could develop a GUI that creates the JSON file, or write a converter that takes the structure assembled in ModelCenter or even Cameo and then instantiate the OpenMDAO model from that. Demonstrating these ideas is not part of this contract.

We start by loading the JSON file. Note that we use the json_numpy library since we allow saving of NumPy arrays in a compressed format.

import json_numpy
import copy
file_name = 'demo_group_NASA.json'
with open(file_name, "r") as infile:
    full_info = json_numpy.load(infile)
---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
Cell In[1], line 4
      1 import json_numpy
      2 import copy
      3 file_name = 'demo_group_NASA.json'
----> 4 with open(file_name, "r") as infile:
      5     full_info = json_numpy.load(infile)

FileNotFoundError: [Errno 2] No such file or directory: 'demo_group_NASA.json'

In the next step we copy the dictionary with the information about the assembly, and then manipulate it. As mentioned before, this should be automated, right now this was manually implemented to remove the characteristic_lengths component from the assembly, including any references to its inputs or outputs.

We also re-order the components in the prep_geom group.

new_info = copy.deepcopy(full_info)
# Delete the 'characteristic_lengths' component from the order list.
del(new_info['components']['prep_geom']['component_order'][-2])
# We also want to move the 'nacelles' and 'canard' components to the start of the assembly
new_info['components']['prep_geom']['component_order'] =['nacelles', 'canard', 'fuselage_prelim', 'wing_prelim', 'prelim', 'wing', 'tail', 'fuselage', 'total_wetted_area']

# We now also delete the 'characteristic_lengths' component completely from the assembly
del(new_info['components']['prep_geom']['components']['characteristic_lengths'])
# We also need to delete the promotions. Note that we have to do this both for the 'prep_geom' group and the overall model.
del(new_info['components']['prep_geom']['promotions']['characteristic_lengths'])
del(new_info['promotions']['prep_geom'][3])
del(new_info['promotions']['prep_geom'][4])
del(new_info['promotions']['prep_geom'][77:89])

# Delete the entry in the linkage for a variable from 'characteristic_lenghts'
del(new_info['components']['prep_geom']['linkage'][-1])
# Delete the input variables for 'characteristic_lenghts'. 
del(new_info['components']['prep_geom']['inputs'][3])
del(new_info['components']['prep_geom']['inputs'][3])
del(new_info['inputs'][3])
del(new_info['inputs'][3])
# Delete the outputs from 'characteristic_lenghts'.
del(new_info['outputs'][40])
del(new_info['outputs'][1:13])
del(new_info['components']['prep_geom']['outputs'][1:13])

The final step of this part of the demonstration is to save the information in a new JSON file.

Note: We added the `indent=4` option when writing the JSON file to make it more human readable. This will also make it easier to compare different versions of the file, although a comparison tool that understands JSON would be better for comparing the contents of multiple JSON files.
new_file_name = "after.json"
with open(new_file_name, "w") as outfile:
        json_numpy.dump(new_info, outfile, indent=4)