Adding Design Variables

To add a design variable to an optimization, use the add_design_var method on System.

System.add_design_var(name, lower=None, upper=None, ref=None, ref0=None, indices=None, adder=None, scaler=None, units=None, parallel_deriv_color=None, cache_linear_solution=False, flat_indices=False)[source]

Add a design variable to this system.

Parameters
namestr

Name of the design variable in the system.

lowerfloat or ndarray, optional

Lower boundary for the input.

upperupper or ndarray, optional

Upper boundary for the input.

reffloat or ndarray, optional

Value of design var that scales to 1.0 in the driver.

ref0float or ndarray, optional

Value of design var that scales to 0.0 in the driver.

indicesiter of int, optional

If an input is an array, these indicate which entries are of interest for this particular design variable. These may be positive or negative integers.

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.

unitsstr, optional

Units to convert to before applying scaling.

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.

Notes

The response can be scaled using ref and ref0. The argument ref0 represents the physical value when the scaled value is 0. The argument ref represents the physical value when the scaled value is 1.

Specifying units

You can specify units when adding a design variable. When this is done, the quanitity is converted from the target output’s units to the desired unit before giving it to the optimizer. When the optimizer commands a new design variable, it is assumed to be in the given units, and converted to the units of the input before setting the value in your model. If you also specify scaling, that scaling is applied after the unit conversion when being passed from the model to the optimizer, and before the unit conversion when being passed back into the model. 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['comp2.y2'][0])
40.555555555555586
con = prob.driver.get_constraint_values(driver_scaling=True)
print(con['comp1.y1'][0])
21.111111111111143