Adding an Objective#
To add an objective to an optimization, use the add_objective
method on System.
- System.add_objective(name, ref=None, ref0=None, index=None, units=None, adder=None, scaler=None, parallel_deriv_color=None, cache_linear_solution=False, flat_indices=False, alias=None)[source]
Add a response variable to this system.
- Parameters:
- namestr
Name of the response variable in the system.
- reffloat or ndarray, optional
Value of response variable that scales to 1.0 in the driver.
- ref0float or ndarray, optional
Value of response variable that scales to 0.0 in the driver.
- indexint, optional
If variable is an array, this indicates which entry is of interest for this particular response. This may be a positive or negative integer.
- unitsstr, optional
Units to convert to before applying scaling.
- adderfloat or ndarray, optional
Value to add to the model value to get the scaled value for the driver. adder is first in precedence. adder and scaler are an alterantive to using ref and ref0.
- scalerfloat or ndarray, optional
Value to multiply the model value to get the scaled value for the driver. scaler is second in precedence. adder and scaler are an alterantive to using ref and ref0.
- parallel_deriv_colorstr
If specified, this design var will be grouped for parallel derivative calculations with other variables sharing the same parallel_deriv_color.
- cache_linear_solutionbool
If True, store the linear solution vectors for this variable so they can be used to start the next linear solution with an initial guess equal to the solution from the previous linear solve.
- flat_indicesbool
If True, interpret specified indices as being indices into a flat source array.
- aliasstr
Alias for this response. Necessary when adding multiple objectives on different indices or slices of a single variable.
Notes
The objective can be scaled using scaler and adder, where
\[x_{scaled} = scaler(x + adder)\]or through the use of ref/ref0, which map to scaler and adder through the equations:
\[ \begin{align}\begin{aligned}0 = scaler(ref_0 + adder)\\1 = scaler(ref + adder)\end{aligned}\end{align} \]which results in:
\[ \begin{align}\begin{aligned}adder = -ref_0\\scaler = \frac{1}{ref + adder}\end{aligned}\end{align} \]
Specifying units#
You can specify units when adding an objective. When this is done, the quanitity is converted from the target output’s units to the desired unit before giving it to the optimizer. If you also specify scaling, that scaling is applied after the unit conversion. Moreover, the upper and lower bound should be specified using these units.
import openmdao.api as om
prob = om.Problem()
model = prob.model
model.add_subsystem('comp1', om.ExecComp('y1 = 2.0*x',
x={'val': 2.0, 'units': 'degF'},
y1={'val': 2.0, 'units': 'degF'}),
promotes=['x', 'y1'])
model.add_subsystem('comp2', om.ExecComp('y2 = 3.0*x',
x={'val': 2.0, 'units': 'degF'},
y2={'val': 2.0, 'units': 'degF'}),
promotes=['x', 'y2'])
model.set_input_defaults('x', 35.0, units='degF')
model.add_design_var('x', units='degC', lower=0.0, upper=100.0)
model.add_constraint('y1', units='degC', lower=0.0, upper=100.0)
model.add_objective('y2', units='degC')
prob.setup()
prob.run_driver()
print('Model variables')
print(prob.get_val('x', indices=[0]))
Model variables
[35.]
print(prob.get_val('comp2.y2', indices=[0]))
[105.]
print(prob.get_val('comp1.y1', indices=[0]))
[70.]
print('Driver variables')
dv = prob.driver.get_design_var_values()
print(dv['x'][0])
Driver variables
1.6666666666666983
obj = prob.driver.get_objective_values(driver_scaling=True)
print(obj['y2'][0])
40.555555555555586
con = prob.driver.get_constraint_values(driver_scaling=True)
print(con['y1'][0])
21.111111111111143