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

Poem 092 - User-defined function hook for pre-processing option setva… #186

Merged
merged 1 commit into from
Oct 5, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions POEM_092.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
POEM ID: 092
Title: User-defined function hook for pre-processing option set.
authors: Kenneth-T-Moore (Ken Moore)
Competing POEMs:
Related POEMs:
Associated implementation PR: [PR xxx](https://github.com/OpenMDAO/OpenMDAO/pull/xxx)

Status:

- [ ] Active
- [x] Requesting decision
- [ ] Accepted
- [ ] Rejected
- [ ] Integrated

## Motivation

OpenMDAO's component options feature is sometimes used to define constant quantities with units. When coupled with
the top-level setting of system options, this creates as situation where an option might be specified in the
wrong units. As a general solution, this POEM proposes the addition of a pre-set function hook that the user
can define to pre-process a value and compute a new value before setting the option in a component. This hook
could be used to convert units, or it could be used for other processing.

## Proposed Solution

The only API change from this POEM is an additional argument to the `declare` method of OptionDictionary. The
new argument is "set_function", which takes a function whose input parameters are a dictionary that contains
the option's metadata and a value, and whose return is a new value.


## Example

```language=python
import openmdao.api as om
from openmdao.utils.units import convert_units


def units_setter(opt_meta, value):
"""
Check and convert new units tuple into

Parameters
----------
opt_meta : dict
Dictionary of entries for the option.
value : any
New value for the option.

Returns
-------
any
Post processed value to set into the option.
"""
new_val, new_units = value
old_val, units = opt_meta['val']

converted_val = convert_units(new_val, new_units, units)
return (converted_val, units)


class AviaryComp(om.ExplicitComponent):

def setup(self):

self.add_input('x', 3.0)
self.add_output('y', 3.0)

def initialize(self):
self.options.declare('length', default=(12.0, 'inch'),
set_function=units_setter)

def compute(self, inputs, outputs):
length = self.options['length'][0]

x = inputs['x']
outputs['y'] = length * x


class Fakeviary(om.Group):

def setup(self):
self.add_subsystem('mass', AviaryComp())


prob = om.Problem()
model = prob.model

model.add_subsystem('statics', Fakeviary())

prob.model_options['*'] = {'length': (2.0, 'ft')}
prob.setup()

prob.run_model()
print('The following should be 72 if the units convert correctly.')
print(prob.get_val('statics.mass.y'))
print('done')
```


## Notes