Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Aviary Options overhaul: Replace aviary_options with individual options on the analysis components. #553

Open
wants to merge 58 commits into
base: main
Choose a base branch
from

Conversation

Kenneth-T-Moore
Copy link
Member

Summary

Major overhaul of options passing in Aviary.

  1. The option "aviary_inputs" has been removed from all components.
  2. Individual options have been added to all components, replacing the ones that used to be fished out of aviary_inputs.
  3. All options are now passed to the components using the OpenMDAO model options feature.
  4. Some options have units. OpenMDAO supports this, but the option's value becomes a tuple with a value and units string (e.g., (100.0 , 'ft') ).
  5. Added the setup_model_options method to sets the model options. This is used in tests and in level 3 models.

Due to this change, the "default value" and "types" fields in the variable metadata are now serving a dual role for type-checking in the AivaryValues user-facing API and in the OptionsDictionary.

  1. Some types related to propulsion were changed to include container types (list, ndarray, tuple).
  2. Some other default values were also added or tweaked.
  3. The FlapType and GaspEngineType enums were converted to IntEnums to match behavior of the other enums, which were changed in earlier PRs. This means we won't be able to set them by their string; this may not be ideal. The problem is that AviaryValues has its own special checking for Enums that OpenMDAO's OptionsDictionary does not have.

There are some matters that are left to possibly be addressed in the future:

  1. Many groups in Aviary still contain aviary_inputs, particular any group that calls builders.
  2. Builders still use aviary_inputs, which is an argument to build_*, so removing it at this level would be tricky.

Related Issues

Backwards incompatibilities

There shouldn't be any changes to the level 1 and level 2 user.

For level 3, a new helper function "setup_model_options" has been added to handle the model options. Level 3 users will need to call this before setup.

New Dependencies

None

aviary/interface/methods_for_level2.py Outdated Show resolved Hide resolved
aviary/subsystems/aerodynamics/gasp_based/gaspaero.py Outdated Show resolved Hide resolved
aviary/subsystems/aerodynamics/gasp_based/gaspaero.py Outdated Show resolved Hide resolved
aviary/subsystems/propulsion/test/test_engine_sizing.py Outdated Show resolved Hide resolved
@@ -190,7 +190,8 @@ def setUp(self):

pp = prob.model.add_subsystem(
'pp',
PropellerPerformance(num_nodes=num_nodes, aviary_options=options),
PropellerPerformance(num_nodes=num_nodes,
aviary_options=options),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The interpolator builder still uses aviary_options. I am pretty sure we can remove it from there too, though that can be a nice compact follow-on.

@@ -3,13 +3,10 @@
from aviary.variable_info.variables import Aircraft


def check_fold_location_definition(inputs, options: AviaryValues):
def check_fold_location_definition(inputs, choose_fold_location, has_strut):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these might need defaults, these conflict checks were originally intended to have a standardized interface.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What default values would you recommend for the 2 options?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

originally, all of the conflict checks (half dozen or so) all took inputs and options as positional args. Since this is the only one left, maybe it would be fine to just remove inputs and have it just take the variables it needs

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

aviary/utils/preprocessors.py Outdated Show resolved Hide resolved
aviary/utils/test/test_aviary_values.py Outdated Show resolved Hide resolved
@jkirk5 jkirk5 self-requested a review October 21, 2024 17:34
@crecine crecine requested review from ehariton and removed request for jkirk5 October 30, 2024 20:15
self.assertTrue(vals.get_val(Aircraft.Engine.TYPE)
== GASPEngineType.TURBOJET)
except:
self.fail('Expecting to be able to set the value of an Enum from an int.')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be string

Copy link
Contributor

@jkirk5 jkirk5 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some questions on engine handling that may need further discussion

desc='fraction of (scaled) engine mass used to calculate additional propulsion '
'system mass added to engine control and starter mass, or used to '
'calculate engine installation mass',
types=(float, int, list, np.ndarray),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding list as an expected type here could potentially mess up a lot of multi-engine stuff.

Currently metadata type is used by propulsion to see what the type should be for a singular engine, which is important to distinguish the difference between an array which represents all engines, or an array that only represents one engine (such as for WING_LOCATIONS). If type is updated like this, it is impossible for the preprocessor to know what the user intended.

It also makes it difficult to type check arrays (you could give this var a list of strings and it would pass type checks now)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For more detail, engines shouldn't be getting passed the vectorized values for all engines (an engine doesn't need to know the options of another engine). The use of aviary_options in the build_mission() and build_premission() methods of EngineModel can probably get removed, since they are instead given options during init.

elif isinstance(value, str):
return getattr(enum_class, value)

elif isinstance(value, list):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or numpy array? I could see situations like preprocessors defaulting to sticking things in a numpy array

Comment on lines +157 to +164
if isinstance(value, Enum):
return value

elif isinstance(value, int):
return enum_class(value)

elif isinstance(value, str):
return getattr(enum_class, value)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these checks are actually redundant - feeding value in to enum_class will correctly return the Enum value in all three scenarios, and invalid values can be caught with an except - e.g. VERBOSITY(VERBOSITY.BRIEF) and VERBOSITY(1) will both return VERBOSITY.BRIEF

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Options Traceability
3 participants