# Optimization with OpenMDAO models minimize x^4 + y^4 subject to x>=0, x+y=1, x-y>=1 ```python '''Optimization with OpenMDAO models: minimize x^4 + y^4 subject to x>=0, x+y=1, x-y>=1''' import openmdao.api as om import numpy as np # minimize x^4 + y^4 subject to x>=0, x+y=1, x-y>=1. class QuarticFunc(om.ExplicitComponent): def setup(self): # add_inputs self.add_input('x', 1.) self.add_input('y', 1.) # add_outputs self.add_output('objective') self.add_output('constraint_1') self.add_output('constraint_2') # declare_partials self.declare_partials(of='objective', wrt='*') # self.declare_partials(of='objective', wrt='*', method='cs') self.declare_partials(of='constraint_1', wrt='x', val=1.) self.declare_partials(of='constraint_1', wrt='y', val=1.) self.declare_partials(of='constraint_2', wrt='x', val=1.) self.declare_partials(of='constraint_2', wrt='y', val=-1.) def compute(self, inputs, outputs): x = inputs['x'] y = inputs['y'] outputs['objective'] = x**4 + y**4 outputs['constraint_1'] = x + y outputs['constraint_2'] = x - y def compute_partials(self, inputs, partials): x = inputs['x'] y = inputs['y'] partials['objective', 'x'] = 4 * x**3 partials['objective', 'y'] = 4 * y**3 if __name__ == "__main__": # Create OpenMDAO Problem om_prob = om.Problem() # Add subsystem to the OpenMDAO Problem model om_prob.model.add_subsystem('quartic', QuarticFunc(), promotes=['*']) # Add optimization variables and functions to the Problem model om_prob.model.add_design_var('x', lower=0., scaler=4., adder=1.) om_prob.model.add_design_var('y', scaler=1., adder=0.) om_prob.model.add_objective('objective', scaler=1., adder=1.) om_prob.model.add_constraint('constraint_1', equals=1., scaler=1., adder=0.) om_prob.model.add_constraint('constraint_2', lower=1., scaler=1., adder=0.) # Setup the OpenMDAO problem om_prob.setup() # Set initial values om_prob.set_val('x', 5.0) om_prob.set_val('y', 10.0) # Print UNSCALED variables print('Initial x value: ', om_prob.get_val('x')) print('Initial y value: ', om_prob.get_val('y')) # Run the model with initial values to compute the objective and constraints # om_prob.run_model() print('Initial objective value: ', om_prob.get_val('objective')) print('Initial constraint 1 value: ', om_prob.get_val('constraint_1')) print('Initial constraint 2 value: ', om_prob.get_val('constraint_2')) from modopt import OpenMDAOProblem # Instantiate the modopt OpenMDAOProblem() object that wraps for modopt # the Problem() object defined earlier, and name your problem prob = OpenMDAOProblem(problem_name='quartic', om_problem=om_prob) from modopt import SQP, SLSQP, SNOPT # Setup your preferred optimizer (here, SLSQP) with the Problem object # Pass in the options for your chosen optimizer optimizer = SLSQP(prob, solver_options={'maxiter':20, 'ftol':1e-6}, readable_outputs=['x']) # optimizer = SQP(prob, maxiter=20) snopt_options = { 'Infinite bound': 1.0e20, 'Verify level': 3, 'Verbose': True, } # optimizer = SNOPT(prob, solver_options=snopt_options) # Check first derivatives at the initial guess, if needed # optimizer.check_first_derivatives(prob.x0) # om_prob.check_totals(compact_print=True) # Solve your optimization problem optimizer.solve() # Print results of optimization (summary_table contains information from each iteration) optimizer.print_results(summary_table=True) print('Num model evals: ', prob.model_evals) print('Num deriv evals: ', prob.deriv_evals) print('Optimal x value: ', om_prob.get_val('x')) print('Optimal y value: ', om_prob.get_val('y')) print('Optimal objective value: ', om_prob.get_val('objective')) print('Optimal constraint 1 value: ', om_prob.get_val('constraint_1')) print('Optimal constraint 2 value: ', om_prob.get_val('constraint_2')) ```