Reputation: 10083
How can I compute the gradient of my constraints without computing the gradient of my objective? I've tried this,
self._problem().compute_totals(of=self.consList, wrt=self._dvlist,
return_format='array')
but this still calls the objective function gradients. (self.consList is a list with one element, which is the name of my constraint component).
Here is an example of this issue:
import openmdao.api as om
prob = om.Problem()
model = prob.model
class comp1(om.ExplicitComponent):
def setup(self):
self.add_input('x', 2, units="degF")
self.add_output('y1', 2, units="degF")
def setup_partials(self):
self.declare_partials('y1', ['x'])
def compute(self, inputs, outputs):
outputs['y1'] = 2.0 * inputs['x']
def compute_partials(self, inputs, J):
print('I need these partials')
J['y1', 'x'] = 2.0
class comp2(om.ExplicitComponent):
def setup(self):
self.add_input('x', 2, units="degF")
self.add_output('y2', 2, units="degF")
def setup_partials(self):
self.declare_partials('y2', ['x'])
def compute(self, inputs, outputs):
outputs['y2'] = 3.0 * inputs['x']
def compute_partials(self, inputs, J):
print('I dont need these partials')
J['y2', 'x'] = 3.0
model.add_subsystem('comp1', comp1(), promotes=['*'])
model.add_subsystem('comp2', comp2(), promotes=['*'])
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_model()
print('computing constraint partials')
res = prob.driver._compute_totals(of='y1', wrt='x')
Upvotes: 0
Views: 84
Reputation: 10083
You could add a custom attribute to stop your model from computing the gradient of the second component:
import openmdao.api as om
prob = om.Problem()
model = prob.model
class comp1(om.ExplicitComponent):
def setup(self):
self.add_input('x', 2, units="degF")
self.add_output('y1', 2, units="degF")
def setup_partials(self):
self.declare_partials('y1', ['x'])
def compute(self, inputs, outputs):
outputs['y1'] = 2.0 * inputs['x']
def compute_partials(self, inputs, J):
print('I need these partials')
J['y1', 'x'] = 2.0
class comp2(om.ExplicitComponent):
def setup(self):
self.add_input('x', 2, units="degF")
self.add_output('y2', 2, units="degF")
self.skip_partial = False
def setup_partials(self):
self.declare_partials('y2', ['x'])
def compute(self, inputs, outputs):
outputs['y2'] = 3.0 * inputs['x']
def compute_partials(self, inputs, J):
if self.skip_partial: return
print('I dont need these partials')
J['y2', 'x'] = 3.0
model.add_subsystem('comp1', comp1(), promotes=['*'])
model.add_subsystem('comp2', comp2(), promotes=['*'])
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_model()
prob.model._subsystems_myproc[2].skip_partial = True
print('computing constraint partials')
res = prob.driver._compute_totals(of='y1', wrt='x')
Upvotes: 0