<jupyter_start><jupyter_text>```{note}This feature requires MPI, and may not be able to be run on Colab.```  Adding ConstraintsTo add a constraint to an optimization, use the `add_constraint` method on System. ```{eval-rst}    .. automethod:: openmdao.core.system.System.add_constraint        :noindex:```  Specifying unitsYou can specify units when adding a constraint. When this is done, the constraint value 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 limits in the constraint definition should be specified using these units.<jupyter_code>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]))
print(prob.get_val('comp2.y2', indices=[0]))
print(prob.get_val('comp1.y1', indices=[0]))
print('Driver variables')
dv = prob.driver.get_design_var_values()
print(dv['x'][0])
obj = prob.driver.get_objective_values(driver_scaling=True)
print(obj['comp2.y2'][0])
con = prob.driver.get_constraint_values(driver_scaling=True)
print(con['comp1.y1'][0])
import numpy as np
from openmdao.utils.assert_utils import assert_near_equal

assert_near_equal(prob.get_val('x', indices=[0]), 35.)
assert_near_equal(prob.get_val('comp2.y2', indices=[0]), 105.)
assert_near_equal(prob.get_val('comp1.y1', indices=[0]), 70.)
assert_near_equal(dv['x'][0], 1.6666666666666983)
assert_near_equal(obj['comp2.y2'][0], 40.555555555555586)
assert_near_equal(con['comp1.y1'][0], 21.111111111111143)<jupyter_output><empty_output><jupyter_text>Using the output of a distributed component as a constraintYou can use an output of a distributed component as a constraint or an objective. OpenMDAO automatically collects the values from all processors and provides them to the driver.Here is an example where we perform optimization on a model that contains a `DistParabFeature` component that is distributed. The output is declared as a inequality constraint.<jupyter_code>%%px
import openmdao.api as om
om.display_source("openmdao.test_suite.components.paraboloid_distributed.DistParabFeature")
%%px

import numpy as np
import openmdao.api as om

from openmdao.test_suite.components.paraboloid_distributed import DistParabFeature

size = 7

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

ivc = om.IndepVarComp()
ivc.add_output('x', np.ones(size))
ivc.add_output('y', -1.42 * np.ones(size))

model.add_subsystem('p', ivc, promotes=['*'])
model.add_subsystem("parab", DistParabFeature(arr_size=size), promotes=['*'])

model.add_design_var('x', lower=-50.0, upper=50.0)
model.add_constraint('f_xy', lower=0.0)
model.add_objective('f_sum', index=-1)

prob.driver = om.pyOptSparseDriver(optimizer='SLSQP')
prob.setup()
        
prob.run_driver()
%%px

desvar = prob.get_val('p.x', get_remote=True)
obj = prob.get_val('f_sum', get_remote=True)

print(desvar)
%%px

print(obj)
%%px

from openmdao.utils.assert_utils import assert_near_equal

assert_near_equal(prob.get_val('p.x'), np.array([2.65752672, 2.60433212, 2.51005989, 1.91021257, 1.3100763,  0.70992863, 0.10978096]), 1e-6 )
assert_near_equal(prob.get_val('f_sum'),11.50150011, 1e-6 )<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1447433981066268, 'fraction_numerical': 0.05281514698555057, 'mean_word_length': 4.686968838526912, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 3, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '237947', 'license': 'Apache-2.0', 'n_tokens_mistral': 1479, 'n_tokens_neox': 1365, 'n_words': 322, 'path': 'openmdao/docs/openmdao_book/features/core_features/adding_desvars_cons_objs/adding_constraint.ipynb', 'repo_name': 'rivasjc/OpenMDAO', 'size': '4014'}