def test_raise_no_error_on_singular(self): prob = Problem() model = prob.model comp = IndepVarComp() comp.add_output('dXdt:TAS', val=1.0) comp.add_output('accel_target', val=2.0) model.add_subsystem('des_vars', comp, promotes=['*']) teg = model.add_subsystem('thrust_equilibrium_group', subsys=Group()) teg.add_subsystem('dynamics', ExecComp('z = 2.0*thrust'), promotes=['*']) thrust_bal = BalanceComp() thrust_bal.add_balance(name='thrust', val=1207.1, lhs_name='dXdt:TAS', rhs_name='accel_target', eq_units='m/s**2', lower=-10.0, upper=10000.0) teg.add_subsystem(name='thrust_bal', subsys=thrust_bal, promotes_inputs=['dXdt:TAS', 'accel_target'], promotes_outputs=['thrust']) teg.linear_solver = DirectSolver(assemble_jac=False) teg.nonlinear_solver = NewtonSolver() teg.nonlinear_solver.options['solve_subsystems'] = True teg.nonlinear_solver.options['max_sub_solves'] = 1 teg.nonlinear_solver.options['atol'] = 1e-4 prob.setup(check=False) prob.set_solver_print(level=0) teg.linear_solver.options['err_on_singular'] = False prob.run_model()
def test_shape(self): n = 100 bal = BalanceComp() bal.add_balance('x', shape=(n,)) tgt = IndepVarComp(name='y_tgt', val=4*np.ones(n)) exe = ExecComp('y=x**2', x=np.zeros(n), y=np.zeros(n)) model = Group() model.add_subsystem('tgt', tgt, promotes_outputs=['y_tgt']) model.add_subsystem('exe', exe) model.add_subsystem('bal', bal) model.connect('y_tgt', 'bal.rhs:x') model.connect('bal.x', 'exe.x') model.connect('exe.y', 'bal.lhs:x') model.linear_solver = DirectSolver(assemble_jac=True) model.nonlinear_solver = NewtonSolver(maxiter=100, iprint=0) prob = Problem(model) prob.setup() prob['bal.x'] = np.random.rand(n) prob.run_model() assert_almost_equal(prob['bal.x'], 2.0*np.ones(n), decimal=7)
def test_feature_scalar_with_default_mult(self): from numpy.testing import assert_almost_equal from openmdao.api import Problem, Group, IndepVarComp, ExecComp, NewtonSolver, \ DirectSolver, BalanceComp prob = Problem() bal = BalanceComp() bal.add_balance('x', use_mult=True, mult_val=2.0) tgt = IndepVarComp(name='y_tgt', val=4) exec_comp = ExecComp('y=x**2', x={'value': 1}, y={'value': 1}) prob.model.add_subsystem(name='target', subsys=tgt, promotes_outputs=['y_tgt']) prob.model.add_subsystem(name='exec', subsys=exec_comp) prob.model.add_subsystem(name='balance', subsys=bal) prob.model.connect('y_tgt', 'balance.rhs:x') prob.model.connect('balance.x', 'exec.x') prob.model.connect('exec.y', 'balance.lhs:x') prob.model.linear_solver = DirectSolver(assemble_jac=True) prob.model.nonlinear_solver = NewtonSolver(maxiter=100, iprint=0) prob.setup(check=False) # A reasonable initial guess to find the positive root. prob['balance.x'] = 1.0 prob.run_model() assert_almost_equal(prob['balance.x'], np.sqrt(2), decimal=7)
def test_scalar_with_guess_func_additional_input(self): model = Group(assembled_jac_type='dense') bal = BalanceComp() bal.add_balance('x') bal.add_input('guess_x', val=0.0) ivc = IndepVarComp() ivc.add_output(name='y_tgt', val=4) ivc.add_output(name='guess_x', val=2.5) exec_comp = ExecComp('y=x**2', x={'value': 1}, y={'value': 1}) model.add_subsystem(name='ivc', subsys=ivc, promotes_outputs=['y_tgt', 'guess_x']) model.add_subsystem(name='exec', subsys=exec_comp) model.add_subsystem(name='balance', subsys=bal) model.connect('guess_x', 'balance.guess_x') model.connect('y_tgt', 'balance.rhs:x') model.connect('balance.x', 'exec.x') model.connect('exec.y', 'balance.lhs:x') model.linear_solver = DirectSolver(assemble_jac=True) model.nonlinear_solver = NewtonSolver(maxiter=100, iprint=0) prob = Problem(model) prob.setup() # run problem without a guess function prob['balance.x'] = .5 prob.run_model() assert_almost_equal(prob['balance.x'], 2.0, decimal=7) iters_no_guess = model.nonlinear_solver._iter_count # run problem with same initial value and a guess function def guess_function(inputs, outputs, resids): outputs['x'] = inputs['guess_x'] bal.options['guess_func'] = guess_function prob['balance.x'] = .5 prob.run_model() assert_almost_equal(prob['balance.x'], 2.0, decimal=7) iters_with_guess = model.nonlinear_solver._iter_count # verify it converges faster with the guess function self.assertTrue(iters_with_guess < iters_no_guess)
def test_scalar_example(self): prob = Problem(model=Group()) bal = BalanceComp() bal.add_balance('x', val=1.0) tgt = IndepVarComp(name='y_tgt', val=2) exec_comp = ExecComp('y=x**2') prob.model.add_subsystem(name='target', subsys=tgt, promotes_outputs=['y_tgt']) prob.model.add_subsystem(name='exec', subsys=exec_comp) prob.model.add_subsystem(name='balance', subsys=bal) prob.model.connect('y_tgt', 'balance.rhs:x') prob.model.connect('balance.x', 'exec.x') prob.model.connect('exec.y', 'balance.lhs:x') # do one test in an unconverged state, to capture accuracy of partials prob.setup() prob['y_tgt'] = 100000 #set rhs and lhs to very different values. Trying to capture some derivatives wrt prob['exec.y'] = .001 prob.run_model() cpd = prob.check_partials() for (of, wrt) in cpd['balance']: assert_almost_equal(cpd['balance'][of, wrt]['abs error'], 0.0, decimal=5) # set an actual solver, and re-setup. Then check derivatives at a converged point prob.model.linear_solver = DirectSolver() prob.model.nonlinear_solver = NewtonSolver() prob.setup() prob.run_model() assert_almost_equal(prob['balance.x'], np.sqrt(2), decimal=7) np.set_printoptions(linewidth=1024) cpd = prob.check_partials() for (of, wrt) in cpd['balance']: assert_almost_equal(cpd['balance'][of, wrt]['abs error'], 0.0, decimal=5)
def test_renamed_vars(self): n = 1 prob = Problem(model=Group()) bal = BalanceComp() bal.add_balance('x', use_mult=True, mult_name='MUL', lhs_name='XSQ', rhs_name='TARGETXSQ') tgt = IndepVarComp(name='y_tgt', val=4) mult_ivc = IndepVarComp(name='mult', val=2.0) exec_comp = ExecComp('y=x**2', x={'value': 1}, y={'value': 1}) prob.model.add_subsystem(name='target', subsys=tgt, promotes_outputs=['y_tgt']) prob.model.add_subsystem(name='mult_comp', subsys=mult_ivc, promotes_outputs=['mult']) prob.model.add_subsystem(name='exec', subsys=exec_comp) prob.model.add_subsystem(name='balance', subsys=bal) prob.model.connect('y_tgt', 'balance.TARGETXSQ') prob.model.connect('mult', 'balance.MUL') prob.model.connect('balance.x', 'exec.x') prob.model.connect('exec.y', 'balance.XSQ') prob.model.linear_solver = DirectSolver() prob.model.nonlinear_solver = NewtonSolver() prob.model.nonlinear_solver.options['maxiter'] = 100 prob.model.nonlinear_solver.options['iprint'] = 0 prob.model.jacobian = DenseJacobian() prob.setup() prob['balance.x'] = np.random.rand(n) prob.run_model() assert_almost_equal(prob['balance.x'], np.sqrt(2), decimal=7) np.set_printoptions(linewidth=1024) cpd = prob.check_partials() for (of, wrt) in cpd['balance']: assert_almost_equal(cpd['balance'][of, wrt]['abs error'], 0.0, decimal=5)
def test_scalar_with_guess_func_additional_input(self): n = 1 prob = Problem(model=Group()) bal = BalanceComp() bal.add_balance('x', guess_func=lambda inputs, resids: inputs['guess_x']) bal.add_input('guess_x', val=0.0) ivc = IndepVarComp() ivc.add_output(name='y_tgt', val=4) ivc.add_output(name='guess_x', val=2.5) exec_comp = ExecComp('y=x**2', x={'value': 1}, y={'value': 1}) prob.model.add_subsystem(name='ivc', subsys=ivc, promotes_outputs=['y_tgt', 'guess_x']) prob.model.add_subsystem(name='exec', subsys=exec_comp) prob.model.add_subsystem(name='balance', subsys=bal) prob.model.connect('guess_x', 'balance.guess_x') prob.model.connect('y_tgt', 'balance.rhs:x') prob.model.connect('balance.x', 'exec.x') prob.model.connect('exec.y', 'balance.lhs:x') prob.model.linear_solver = DirectSolver() prob.model.nonlinear_solver = NewtonSolver() prob.model.nonlinear_solver.options['maxiter'] = 100 prob.model.nonlinear_solver.options['iprint'] = 0 prob.model.jacobian = DenseJacobian() prob.setup() prob['balance.x'] = np.random.rand(n) prob.run_model() assert_almost_equal(prob['balance.x'], 2.0, decimal=7) np.set_printoptions(linewidth=1024) cpd = prob.check_partials() for (of, wrt) in cpd['balance']: assert_almost_equal(cpd['balance'][of, wrt]['abs error'], 0.0, decimal=5)
def test_feature_scalar(self): from numpy.testing import assert_almost_equal from openmdao.api import Problem, Group, IndepVarComp, ExecComp, NewtonSolver, DirectSolver, DenseJacobian, BalanceComp n = 1 prob = Problem(model=Group()) bal = BalanceComp() bal.add_balance('x', use_mult=True) tgt = IndepVarComp(name='y_tgt', val=4) mult_ivc = IndepVarComp(name='mult', val=2.0) exec_comp = ExecComp('y=x**2', x={'value': 1}, y={'value': 1}) prob.model.add_subsystem(name='target', subsys=tgt, promotes_outputs=['y_tgt']) prob.model.add_subsystem(name='mult_comp', subsys=mult_ivc, promotes_outputs=['mult']) prob.model.add_subsystem(name='exec', subsys=exec_comp) prob.model.add_subsystem(name='balance', subsys=bal) prob.model.connect('y_tgt', 'balance.rhs:x') prob.model.connect('mult', 'balance.mult:x') prob.model.connect('balance.x', 'exec.x') prob.model.connect('exec.y', 'balance.lhs:x') prob.model.linear_solver = DirectSolver() prob.model.nonlinear_solver = NewtonSolver() prob.model.nonlinear_solver.options['maxiter'] = 100 prob.model.nonlinear_solver.options['iprint'] = 0 prob.model.jacobian = DenseJacobian() prob.setup(check=False) # A reasonable initial guess to find the positive root. prob['balance.x'] = 1.0 prob.run_model() print('x = ', prob['balance.x']) assert_almost_equal(prob['balance.x'], np.sqrt(2), decimal=7)
def test_debug_after_raised_error(self): prob = Problem() model = prob.model comp = IndepVarComp() comp.add_output('dXdt:TAS', val=1.0) comp.add_output('accel_target', val=2.0) model.add_subsystem('des_vars', comp, promotes=['*']) teg = model.add_subsystem('thrust_equilibrium_group', subsys=Group()) teg.add_subsystem('dynamics', ExecComp('z = 2.0*thrust'), promotes=['*']) thrust_bal = BalanceComp() thrust_bal.add_balance(name='thrust', val=1207.1, lhs_name='dXdt:TAS', rhs_name='accel_target', eq_units='m/s**2', lower=-10.0, upper=10000.0) teg.add_subsystem(name='thrust_bal', subsys=thrust_bal, promotes_inputs=['dXdt:TAS', 'accel_target'], promotes_outputs=['thrust']) teg.linear_solver = DirectSolver() teg.nonlinear_solver = NewtonSolver() teg.nonlinear_solver.options['solve_subsystems'] = True teg.nonlinear_solver.options['max_sub_solves'] = 1 teg.nonlinear_solver.options['atol'] = 1e-4 teg.nonlinear_solver.options['debug_print'] = True prob.setup(check=False) prob.set_solver_print(level=0) stdout = sys.stdout strout = StringIO() sys.stdout = strout with self.assertRaises(RuntimeError) as cm: prob.run_model() sys.stdout = stdout output = strout.getvalue() target = "'thrust_equilibrium_group.thrust_bal.thrust'" self.assertTrue(target in output, msg=target + "NOT FOUND IN" + output) # Make sure exception is unchanged. expected_msg = "Singular entry found in 'thrust_equilibrium_group' for row associated with state/residual 'thrust'." self.assertEqual(expected_msg, str(cm.exception))
def test_vectorized(self): n = 100 prob = Problem(model=Group()) bal = BalanceComp() bal.add_balance('x', val=np.ones(n)) tgt = IndepVarComp(name='y_tgt', val=4*np.ones(n)) exec_comp = ExecComp('y=x**2', x={'value': np.ones(n)}, y={'value': np.ones(n)}) prob.model.add_subsystem(name='target', subsys=tgt, promotes_outputs=['y_tgt']) prob.model.add_subsystem(name='exec', subsys=exec_comp) prob.model.add_subsystem(name='balance', subsys=bal) prob.model.connect('y_tgt', 'balance.rhs:x') prob.model.connect('balance.x', 'exec.x') prob.model.connect('exec.y', 'balance.lhs:x') prob.model.linear_solver = DirectSolver() prob.model.nonlinear_solver = NewtonSolver() prob.model.nonlinear_solver.options['maxiter'] = 100 prob.model.nonlinear_solver.options['iprint'] = 0 prob.model.jacobian = DenseJacobian() prob.setup() prob['balance.x'] = np.random.rand(n) prob.run_model() assert_almost_equal(prob['balance.x'], 2.0, decimal=7) np.set_printoptions(linewidth=1024) cpd = prob.check_partials() for (of, wrt) in cpd['balance']: assert_almost_equal(cpd['balance'][of, wrt]['abs error'], 0.0, decimal=5)
def test_vectorized(self): n = 100 prob = Problem(model=Group(assembled_jac_type='dense')) bal = BalanceComp() bal.add_balance('x', val=np.ones(n)) tgt = IndepVarComp(name='y_tgt', val=4 * np.ones(n)) exec_comp = ExecComp('y=x**2', x={'value': np.ones(n)}, y={'value': np.ones(n)}) prob.model.add_subsystem(name='target', subsys=tgt, promotes_outputs=['y_tgt']) prob.model.add_subsystem(name='exec', subsys=exec_comp) prob.model.add_subsystem(name='balance', subsys=bal) prob.model.connect('y_tgt', 'balance.rhs:x') prob.model.connect('balance.x', 'exec.x') prob.model.connect('exec.y', 'balance.lhs:x') prob.model.linear_solver = DirectSolver(assemble_jac=True) prob.model.nonlinear_solver = NewtonSolver(maxiter=100, iprint=0) prob.setup() prob['balance.x'] = np.random.rand(n) prob.run_model() assert_almost_equal(prob['balance.x'], 2.0, decimal=7) cpd = prob.check_partials(out_stream=None) for (of, wrt) in cpd['balance']: assert_almost_equal(cpd['balance'][of, wrt]['abs error'], 0.0, decimal=5)
def test_feature_scalar(self): n = 1 prob = Problem(model=Group()) bal = BalanceComp() bal.add_balance('x') tgt = IndepVarComp(name='y_tgt', val=4) mult_ivc = IndepVarComp(name='mult', val=2.0) exec_comp = ExecComp('y=x**2', x={'value': 1}, y={'value': 1}) prob.model.add_subsystem(name='target', subsys=tgt, promotes_outputs=['y_tgt']) prob.model.add_subsystem(name='mult_comp', subsys=mult_ivc, promotes_outputs=['mult']) prob.model.add_subsystem(name='exec', subsys=exec_comp) prob.model.add_subsystem(name='balance', subsys=bal) prob.model.connect('y_tgt', 'balance.rhs:x') prob.model.connect('mult', 'balance.mult:x') prob.model.connect('balance.x', 'exec.x') prob.model.connect('exec.y', 'balance.lhs:x') prob.model.linear_solver = DirectSolver() prob.model.nonlinear_solver = NewtonSolver() prob.model.nonlinear_solver.options['maxiter'] = 100 prob.model.nonlinear_solver.options['iprint'] = 0 prob.model.jacobian = DenseJacobian() prob.setup(check=False) # A reasonable initial guess to find the positive root. prob['balance.x'] = 1.0 prob.run_model() print('x = ', prob['balance.x']) assert_almost_equal(prob['balance.x'], np.sqrt(2), decimal=7)
def test_scalar(self): n = 1 prob = Problem(model=Group()) bal = BalanceComp() bal.add_balance('x') tgt = IndepVarComp(name='y_tgt', val=4) exec_comp = ExecComp('y=x**2', x={'value': 1}, y={'value': 1}) prob.model.add_subsystem(name='target', subsys=tgt, promotes_outputs=['y_tgt']) prob.model.add_subsystem(name='exec', subsys=exec_comp) prob.model.add_subsystem(name='balance', subsys=bal) prob.model.connect('y_tgt', 'balance.rhs:x') prob.model.connect('balance.x', 'exec.x') prob.model.connect('exec.y', 'balance.lhs:x') prob.model.linear_solver = DirectSolver() prob.model.nonlinear_solver = NewtonSolver() prob.model.nonlinear_solver.options['maxiter'] = 100 prob.model.nonlinear_solver.options['iprint'] = 0 prob.model.jacobian = DenseJacobian() prob.setup() prob['balance.x'] = np.random.rand(n) prob.run_model() assert_almost_equal(prob['balance.x'], 2.0, decimal=7) np.set_printoptions(linewidth=1024) cpd = prob.check_partials() for (of, wrt) in cpd['balance']: assert_almost_equal(cpd['balance'][of, wrt]['abs error'], 0.0, decimal=5)
def test_scalar_with_mult(self): n = 1 prob = Problem(model=Group(assembled_jac_type='dense')) bal = BalanceComp() bal.add_balance('x', use_mult=True) tgt = IndepVarComp(name='y_tgt', val=4) mult_ivc = IndepVarComp(name='mult', val=2.0) exec_comp = ExecComp('y=x**2', x={'value': 1}, y={'value': 1}) prob.model.add_subsystem(name='target', subsys=tgt, promotes_outputs=['y_tgt']) prob.model.add_subsystem(name='mult_comp', subsys=mult_ivc, promotes_outputs=['mult']) prob.model.add_subsystem(name='exec', subsys=exec_comp) prob.model.add_subsystem(name='balance', subsys=bal) prob.model.connect('y_tgt', 'balance.rhs:x') prob.model.connect('mult', 'balance.mult:x') prob.model.connect('balance.x', 'exec.x') prob.model.connect('exec.y', 'balance.lhs:x') prob.model.linear_solver = DirectSolver(assemble_jac=True) prob.model.nonlinear_solver = NewtonSolver(maxiter=100, iprint=0) prob.setup() prob['balance.x'] = np.random.rand(n) prob.run_model() assert_almost_equal(prob['balance.x'], np.sqrt(2), decimal=7) with printoptions(linewidth=1024): cpd = prob.check_partials() for (of, wrt) in cpd['balance']: assert_almost_equal(cpd['balance'][of, wrt]['abs error'], 0.0, decimal=5)
def test_raise_error_on_singular_with_densejac(self): prob = Problem() model = prob.model comp = IndepVarComp() comp.add_output('dXdt:TAS', val=1.0) comp.add_output('accel_target', val=2.0) model.add_subsystem('des_vars', comp, promotes=['*']) teg = model.add_subsystem('thrust_equilibrium_group', subsys=Group()) teg.add_subsystem('dynamics', ExecComp('z = 2.0*thrust'), promotes=['*']) thrust_bal = BalanceComp() thrust_bal.add_balance(name='thrust', val=1207.1, lhs_name='dXdt:TAS', rhs_name='accel_target', eq_units='m/s**2', lower=-10.0, upper=10000.0) teg.add_subsystem(name='thrust_bal', subsys=thrust_bal, promotes_inputs=['dXdt:TAS', 'accel_target'], promotes_outputs=['thrust']) teg.linear_solver = DirectSolver(assemble_jac=True) teg.options['assembled_jac_type'] = 'dense' teg.nonlinear_solver = NewtonSolver() teg.nonlinear_solver.options['solve_subsystems'] = True teg.nonlinear_solver.options['max_sub_solves'] = 1 teg.nonlinear_solver.options['atol'] = 1e-4 prob.setup(check=False) prob.set_solver_print(level=0) with self.assertRaises(RuntimeError) as cm: prob.run_model() expected_msg = "Singular entry found in 'thrust_equilibrium_group' for column associated with state/residual 'thrust'." self.assertEqual(expected_msg, str(cm.exception))
def test_feature_scalar_with_default_mult(self): from numpy.testing import assert_almost_equal from openmdao.api import Problem, Group, IndepVarComp, ExecComp, NewtonSolver, \ DirectSolver, DenseJacobian, BalanceComp prob = Problem(model=Group()) bal = BalanceComp() bal.add_balance('x', use_mult=True, mult_val=2.0) tgt = IndepVarComp(name='y_tgt', val=4) exec_comp = ExecComp('y=x**2', x={'value': 1}, y={'value': 1}) prob.model.add_subsystem(name='target', subsys=tgt, promotes_outputs=['y_tgt']) prob.model.add_subsystem(name='exec', subsys=exec_comp) prob.model.add_subsystem(name='balance', subsys=bal) prob.model.connect('y_tgt', 'balance.rhs:x') prob.model.connect('balance.x', 'exec.x') prob.model.connect('exec.y', 'balance.lhs:x') prob.model.linear_solver = DirectSolver() prob.model.nonlinear_solver = NewtonSolver() prob.model.nonlinear_solver.options['maxiter'] = 100 prob.model.nonlinear_solver.options['iprint'] = 0 prob.model.jacobian = DenseJacobian() prob.setup(check=False) # A reasonable initial guess to find the positive root. prob['balance.x'] = 1.0 prob.run_model() print('x = ', prob['balance.x']) assert_almost_equal(prob['balance.x'], np.sqrt(2), decimal=7)
def test_complex_step(self): n = 1 prob = Problem(model=Group(assembled_jac_type='dense')) bal = BalanceComp() bal.add_balance('x') tgt = IndepVarComp(name='y_tgt', val=4) exec_comp = ExecComp('y=x**2', x={'value': 1}, y={'value': 1}) prob.model.add_subsystem(name='target', subsys=tgt, promotes_outputs=['y_tgt']) prob.model.add_subsystem(name='exec', subsys=exec_comp) prob.model.add_subsystem(name='balance', subsys=bal) prob.model.connect('y_tgt', 'balance.rhs:x') prob.model.connect('balance.x', 'exec.x') prob.model.connect('exec.y', 'balance.lhs:x') prob.model.linear_solver = DirectSolver(assemble_jac=True) prob.model.nonlinear_solver = NewtonSolver(maxiter=100, iprint=0) prob.setup(force_alloc_complex=True) prob['balance.x'] = np.random.rand(n) prob.run_model() with warnings.catch_warnings(): warnings.filterwarnings(action="error", category=np.ComplexWarning) cpd = prob.check_partials(out_stream=None, method='cs') for (of, wrt) in cpd['balance']: assert_almost_equal(cpd['balance'][of, wrt]['abs error'], 0.0, decimal=10)
def test_feature_scalar(self): from numpy.testing import assert_almost_equal from openmdao.api import Problem, Group, IndepVarComp, ExecComp, NewtonSolver, \ DirectSolver, BalanceComp prob = Problem(model=Group(assembled_jac_type='dense')) bal = BalanceComp() bal.add_balance('x', use_mult=True) tgt = IndepVarComp(name='y_tgt', val=4) mult_ivc = IndepVarComp(name='mult', val=2.0) exec_comp = ExecComp('y=x**2', x={'value': 1}, y={'value': 1}) prob.model.add_subsystem(name='target', subsys=tgt, promotes_outputs=['y_tgt']) prob.model.add_subsystem(name='mult_comp', subsys=mult_ivc, promotes_outputs=['mult']) prob.model.add_subsystem(name='exec', subsys=exec_comp) prob.model.add_subsystem(name='balance', subsys=bal) prob.model.connect('y_tgt', 'balance.rhs:x') prob.model.connect('mult', 'balance.mult:x') prob.model.connect('balance.x', 'exec.x') prob.model.connect('exec.y', 'balance.lhs:x') prob.model.linear_solver = DirectSolver(assemble_jac=True) prob.model.nonlinear_solver = NewtonSolver(maxiter=100, iprint=0) prob.setup(check=False) # A reasonable initial guess to find the positive root. prob['balance.x'] = 1.0 prob.run_model() print('x = ', prob['balance.x']) assert_almost_equal(prob['balance.x'], np.sqrt(2), decimal=7)
def test_scalar_with_guess_func(self): n = 1 prob = Problem(model=Group(assembled_jac_type='dense')) bal = BalanceComp() bal.add_balance('x', guess_func=lambda inputs, outputs, resids: np.sqrt(inputs['rhs:x'])) tgt = IndepVarComp(name='y_tgt', val=4) exec_comp = ExecComp('y=x**2', x={'value': 1}, y={'value': 1}) prob.model.add_subsystem(name='target', subsys=tgt, promotes_outputs=['y_tgt']) prob.model.add_subsystem(name='exec', subsys=exec_comp) prob.model.add_subsystem(name='balance', subsys=bal) prob.model.connect('y_tgt', 'balance.rhs:x') prob.model.connect('balance.x', 'exec.x') prob.model.connect('exec.y', 'balance.lhs:x') prob.model.linear_solver = DirectSolver(assemble_jac=True) prob.model.nonlinear_solver = NewtonSolver(maxiter=100, iprint=0) prob.setup() prob['balance.x'] = np.random.rand(n) prob.run_model() assert_almost_equal(prob['balance.x'], 2.0, decimal=7) with printoptions(linewidth=1024): cpd = prob.check_partials() for (of, wrt) in cpd['balance']: assert_almost_equal(cpd['balance'][of, wrt]['abs error'], 0.0, decimal=5)
def test_vectorized_no_normalization(self): n = 100 prob = Problem(model=Group(assembled_jac_type='dense')) bal = BalanceComp() bal.add_balance('x', val=np.ones(n), normalize=False) tgt = IndepVarComp(name='y_tgt', val=1.7*np.ones(n)) exec_comp = ExecComp('y=x**2', x={'value': np.ones(n)}, y={'value': np.ones(n)}) prob.model.add_subsystem(name='target', subsys=tgt, promotes_outputs=['y_tgt']) prob.model.add_subsystem(name='exec', subsys=exec_comp) prob.model.add_subsystem(name='balance', subsys=bal) prob.model.connect('y_tgt', 'balance.rhs:x') prob.model.connect('balance.x', 'exec.x') prob.model.connect('exec.y', 'balance.lhs:x') prob.model.linear_solver = DirectSolver(assemble_jac=True) prob.model.nonlinear_solver = NewtonSolver(maxiter=100, iprint=0) prob.setup() prob['balance.x'] = np.random.rand(n) prob.run_model() assert_almost_equal(prob['balance.x'], np.sqrt(1.7), decimal=7) cpd = prob.check_partials(out_stream=None) for (of, wrt) in cpd['balance']: assert_almost_equal(cpd['balance'][of, wrt]['abs error'], 0.0, decimal=5)
def setup(self): thermo_data = self.options['thermo_data'] elements = self.options['elements'] self.add_subsystem('fs', FlowStart(thermo_data=thermo_data, elements=elements), promotes_outputs=['Fl_O:*'], promotes_inputs=['W']) balance = BalanceComp() balance.add_balance('P', val=10., units='psi', eq_units='psi', lhs_name='Ps_computed', rhs_name='Ps', lower=1e-1) #guess_func=lambda inputs, resids: 5.) balance.add_balance('T', val=800., units='degR', eq_units='ft/s', lhs_name='V_computed', rhs_name='V', lower=1e-1) #guess_func=lambda inputs, resids: 400.) balance.add_balance('MN', val=.3, eq_units='inch**2', lhs_name='area_computed', rhs_name='area', lower=1e-6) #guess_func=lambda inputs, resids: .6) self.add_subsystem('balance', balance, promotes_inputs=['Ps', 'V', 'area']) self.connect('Fl_O:stat:P', 'balance.Ps_computed') self.connect('Fl_O:stat:V', 'balance.V_computed') self.connect('Fl_O:stat:area', 'balance.area_computed') self.connect('balance.P', 'fs.P') self.connect('balance.T', 'fs.T') self.connect('balance.MN', 'fs.MN') newton = self.nonlinear_solver = NewtonSolver() newton.options['solve_subsystems'] = True newton.options['maxiter'] = 10 # newton.linesearch = BoundsEnforceLS() # newton.linesearch.options['print_bound_enforce'] = True self.linear_solver = DirectSolver(assemble_jac=True)
def compute_drag_polar(Mach, alphas, surfaces, trimmed=False): if isinstance(surfaces, dict): surfaces = [ surfaces, ] # Create the OpenMDAO problem prob = Problem() # Create an independent variable component that will supply the flow # conditions to the problem. indep_var_comp = IndepVarComp() indep_var_comp.add_output('v', val=248.136, units='m/s') indep_var_comp.add_output('alpha', val=0., units='deg') indep_var_comp.add_output('Mach_number', val=Mach) indep_var_comp.add_output('re', val=1.e6, units='1/m') indep_var_comp.add_output('rho', val=0.38, units='kg/m**3') indep_var_comp.add_output('cg', val=np.zeros((3)), units='m') # Add this IndepVarComp to the problem model prob.model.add_subsystem('prob_vars', indep_var_comp, promotes=['*']) for surface in surfaces: name = surface['name'] # Create and add a group that handles the geometry for the # aerodynamic lifting surface geom_group = Geometry(surface=surface) prob.model.add_subsystem(name, geom_group) # Connect the mesh from the geometry component to the analysis point prob.model.connect(name + '.mesh', 'aero.' + name + '.def_mesh') # Perform the connections with the modified names within the # 'aero_states' group. prob.model.connect(name + '.mesh', 'aero.aero_states.' + name + '_def_mesh') # Create the aero point group, which contains the actual aerodynamic # analyses point_name = 'aero' aero_group = AeroPoint(surfaces=surfaces) prob.model.add_subsystem( point_name, aero_group, promotes_inputs=['v', 'alpha', 'Mach_number', 're', 'rho', 'cg']) # For trimmed polar, setup balance component if trimmed == True: bal = BalanceComp() bal.add_balance(name='tail_rotation', rhs_val=0., units='deg') prob.model.add_subsystem('balance', bal, promotes_outputs=['tail_rotation']) prob.model.connect('aero.CM', 'balance.lhs:tail_rotation', src_indices=[1]) prob.model.connect('tail_rotation', 'tail.twist_cp') prob.model.nonlinear_solver = NonlinearBlockGS(use_aitken=True) prob.model.nonlinear_solver.options['iprint'] = 2 prob.model.nonlinear_solver.options['maxiter'] = 100 prob.model.linear_solver = DirectSolver() prob.setup() #prob['tail_rotation'] = -0.75 prob.run_model() #prob.check_partials(compact_print = True) #prob.model.list_outputs(prom_name = True) prob.model.list_outputs(residuals=True) CLs = [] CDs = [] CMs = [] for a in alphas: prob['alpha'] = a prob.run_model() CLs.append(prob['aero.CL'][0]) CDs.append(prob['aero.CD'][0]) CMs.append(prob['aero.CM'][1]) # Take only the longitudinal CM #print(a, prob['aero.CL'], prob['aero.CD'], prob['aero.CM'][1]) # Plot CL vs alpha and drag polar fig, axes = plt.subplots(nrows=3) axes[0].plot(alphas, CLs) axes[1].plot(alphas, CMs) axes[2].plot(CLs, CDs) fig.savefig('drag_polar.pdf') #plt.show() return CLs, CDs, CMs
def setup(self): map_data = self.options['map_data'] design = self.options['design'] method = self.options['interp_method'] extrap = self.options['extrap'] params = map_data.param_data outputs = map_data.output_data # Define map which will be used readmap = MetaModelStructuredComp(method=method, extrapolate=extrap) for p in params: readmap.add_input(p['name'], val=p['default'], units=p['units'], training_data=p['values']) for o in outputs: readmap.add_output(o['name'], val=o['default'], units=o['units'], training_data=o['values']) # Create instance of map for evaluating actual operating point if design: # In design mode, operating point specified by default values for RlineMap, NcMap and alphaMap mapDesPt = IndepVarComp() mapDesPt.add_output('NcMap', val=map_data.defaults['NcMap'], units='rpm') mapDesPt.add_output('RlineMap', val=map_data.defaults['RlineMap'], units=None) self.add_subsystem('mapDesPt', subsys=mapDesPt, promotes=['*']) # Evaluate map using design point values self.add_subsystem( 'map', readmap, promotes_inputs=['RlineMap', 'NcMap', 'alphaMap'], promotes_outputs=['effMap', 'PRmap', 'WcMap']) # Compute map scalars based on input PR, eff, Nc and Wc as well as unscaled map values self.add_subsystem( 'scalars', MapScalars(), promotes_inputs=[ 'PR', 'eff', 'Nc', 'Wc', 'NcMap', 'effMap', 'PRmap', 'WcMap' ], promotes_outputs=['s_Nc', 's_PR', 's_eff', 's_Wc']) else: # In off-design mode, RlineMap, NcMap and alphaMap are input to map self.add_subsystem( 'map', readmap, promotes_inputs=['RlineMap', 'NcMap', 'alphaMap'], promotes_outputs=['effMap', 'PRmap', 'WcMap']) # Compute scaled map outputs base on input scalars and unscaled map values self.add_subsystem('scaledOutput', ScaledMapValues(), promotes_inputs=[ 's_PR', 's_eff', 's_Wc', 's_Nc', 'NcMap', 'effMap', 'PRmap', 'WcMap' ], promotes_outputs=['PR', 'eff']) # Use balance component to vary NcMap and RlineMap to match incoming corrected flow and speed map_bal = BalanceComp() map_bal.add_balance('NcMap', val=map_data.defaults['NcMap'], units='rpm', eq_units='rpm') map_bal.add_balance('RlineMap', val=map_data.defaults['RlineMap'], units=None, eq_units='lbm/s', lower=map_data.RlineStall) self.add_subsystem(name='map_bal', subsys=map_bal, promotes_inputs=[('lhs:NcMap', 'Nc'), ('lhs:RlineMap', 'Wc')], promotes_outputs=['NcMap', 'RlineMap']) self.connect('scaledOutput.Nc', 'map_bal.rhs:NcMap') self.connect('scaledOutput.Wc', 'map_bal.rhs:RlineMap') # Define the Rline corresponding to stall RlineStall = IndepVarComp() RlineStall.add_output('RlineStall', val=map_data.RlineStall, units=None) self.add_subsystem('stall_R', subsys=RlineStall) # Evaluate map for the constant speed stall margin (SMN) SMN_map = MetaModelStructuredComp(method=method, extrapolate=extrap) for p in params: SMN_map.add_input(p['name'], val=p['default'], units=p['units'], training_data=p['values']) for o in outputs: SMN_map.add_output(o['name'], val=o['default'], units=o['units'], training_data=o['values']) self.add_subsystem('SMN_map', SMN_map, promotes_inputs=['NcMap', 'alphaMap']) self.connect('stall_R.RlineStall', 'SMN_map.RlineMap') # Evaluate map for the constant speed stall margin (SMN) SMW_map = MetaModelStructuredComp(method=method, extrapolate=extrap) for p in params: SMW_map.add_input(p['name'], val=p['default'], units=p['units'], training_data=p['values']) for o in outputs: SMW_map.add_output(o['name'], val=o['default'], units=o['units'], training_data=o['values']) self.add_subsystem('SMW_map', SMW_map, promotes_inputs=['alphaMap']) self.connect('stall_R.RlineStall', 'SMW_map.RlineMap') # Use balance to vary NcMap on SMW map to hold corrected flow constant SMW_bal = BalanceComp() SMW_bal.add_balance('NcMap', val=map_data.defaults['NcMap'], units='rpm', eq_units='lbm/s') self.add_subsystem(name='SMW_bal', subsys=SMW_bal) self.connect('SMW_bal.NcMap', 'SMW_map.NcMap') self.connect('WcMap', 'SMW_bal.lhs:NcMap') self.connect('SMW_map.WcMap', 'SMW_bal.rhs:NcMap') # Compute the stall margins self.add_subsystem('stall_margins', StallCalcs(), promotes_inputs=[('PR_actual', 'PRmap'), ('Wc_actual', 'WcMap')], promotes_outputs=['SMN', 'SMW']) self.connect('SMN_map.PRmap', 'stall_margins.PR_SMN') self.connect('SMW_map.PRmap', 'stall_margins.PR_SMW') self.connect('SMN_map.WcMap', 'stall_margins.Wc_SMN')
def test_result(self): import numpy as np from numpy.testing import assert_almost_equal from openmdao.api import Problem, Group, IndepVarComp, BalanceComp, \ ExecComp, DirectSolver, NewtonSolver prob = Problem(model=Group()) ivc = IndepVarComp() ivc.add_output(name='M', val=0.0, units='deg', desc='Mean anomaly') ivc.add_output(name='ecc', val=0.0, units=None, desc='orbit eccentricity') bal = BalanceComp() bal.add_balance(name='E', val=0.0, units='rad', eq_units='rad', rhs_name='M') # Override the guess_nonlinear method, always initialize E to the value of M def guess_func(inputs, outputs, residuals): outputs['E'] = inputs['M'] bal.guess_nonlinear = guess_func # ExecComp used to compute the LHS of Kepler's equation. lhs_comp = ExecComp('lhs=E - ecc * sin(E)', lhs={'value': 0.0, 'units': 'rad'}, E={'value': 0.0, 'units': 'rad'}, ecc={'value': 0.0}) prob.model.add_subsystem(name='ivc', subsys=ivc, promotes_outputs=['M', 'ecc']) prob.model.add_subsystem(name='balance', subsys=bal, promotes_inputs=['M'], promotes_outputs=['E']) prob.model.add_subsystem(name='lhs_comp', subsys=lhs_comp, promotes_inputs=['E', 'ecc']) # Explicit connections prob.model.connect('lhs_comp.lhs', 'balance.lhs:E') # Setup solvers prob.model.linear_solver = DirectSolver() prob.model.nonlinear_solver = NewtonSolver() prob.model.nonlinear_solver.options['maxiter'] = 100 prob.model.nonlinear_solver.options['iprint'] = 0 prob.setup() prob['M'] = 85.0 prob['ecc'] = 0.6 prob.run_model() assert_almost_equal(np.degrees(prob['E']), 115.9, decimal=1) print('E (deg) = ', np.degrees(prob['E'][0]))
def compute_drag_polar(Mach, alphas, surfaces, trimmed=False): if isinstance(surfaces, dict): surfaces = [surfaces,] # Create the OpenMDAO problem prob = Problem() # Create an independent variable component that will supply the flow # conditions to the problem. indep_var_comp = IndepVarComp() indep_var_comp.add_output('v', val=248.136, units='m/s') indep_var_comp.add_output('alpha', val=0., units = 'deg') indep_var_comp.add_output('M', val=Mach) indep_var_comp.add_output('re', val=1.e6, units='1/m') indep_var_comp.add_output('rho', val=0.38, units='kg/m**3') indep_var_comp.add_output('cg', val=np.zeros((3)), units='m') # Add this IndepVarComp to the problem model prob.model.add_subsystem('prob_vars', indep_var_comp, promotes=['*']) for surface in surfaces: name = surface['name'] # Create and add a group that handles the geometry for the # aerodynamic lifting surface geom_group = Geometry(surface=surface) prob.model.add_subsystem(name, geom_group) # Connect the mesh from the geometry component to the analysis point prob.model.connect(name + '.mesh', 'aero.' + name + '.def_mesh') # Perform the connections with the modified names within the # 'aero_states' group. prob.model.connect(name + '.mesh', 'aero.aero_states.' + name + '_def_mesh') # Create the aero point group, which contains the actual aerodynamic # analyses point_name = 'aero' aero_group = AeroPoint(surfaces=surfaces) prob.model.add_subsystem(point_name, aero_group, promotes_inputs=['v', 'alpha', 'M', 're', 'rho', 'cg']) # For trimmed polar, setup balance component if trimmed == True: bal = BalanceComp() bal.add_balance(name='tail_rotation', rhs_val = 0., units = 'deg') prob.model.add_subsystem('balance', bal, promotes_outputs = ['tail_rotation']) prob.model.connect('aero.CM', 'balance.lhs:tail_rotation', src_indices = [1]) prob.model.connect('tail_rotation', 'tail.twist_cp', src_indices = np.zeros((1,5), dtype = int)) # Use Newton Solver # prob.model.nonlinear_solver = NewtonSolver() # prob.model.nonlinear_solver.options['solve_subsystems'] = True # Use Broyden Solver prob.model.nonlinear_solver = BroydenSolver() prob.model.nonlinear_solver.options['state_vars'] = ['tail_rotation'] # prob.model.nonlinear_solver.linesearch = ArmijoGoldsteinLS() prob.model.nonlinear_solver.options['iprint'] = 2 prob.model.nonlinear_solver.options['maxiter'] = 20 prob.model.linear_solver = DirectSolver() prob.setup() #prob['tail_rotation'] = -0.75 prob.run_model() #prob.check_partials(compact_print = True) #prob.model.list_outputs(prom_name = True) prob.model.list_outputs(residuals = True) CLs = [] CDs = [] CMs = [] for a in alphas: prob['alpha'] = a prob.run_model() CLs.append(prob['aero.CL'][0]) CDs.append(prob['aero.CD'][0]) CMs.append(prob['aero.CM'][1]) # Take only the longitudinal CM #print(a, prob['aero.CL'], prob['aero.CD'], prob['aero.CM'][1]) # Plot CL vs alpha and drag polar fig,axes = plt.subplots(nrows=3) axes[0].plot(alphas, CLs) axes[1].plot(alphas, CMs) axes[2].plot(CLs, CDs) fig.savefig('drag_polar.pdf') #plt.show() return CLs, CDs, CMs
def test_result(self): import numpy as np from numpy.testing import assert_almost_equal from openmdao.api import Problem, Group, IndepVarComp, BalanceComp, \ ExecComp, DirectSolver, NewtonSolver, DenseJacobian prob = Problem(model=Group()) ivc = IndepVarComp() ivc.add_output(name='M', val=0.0, units='deg', desc='Mean anomaly') ivc.add_output(name='ecc', val=0.0, units=None, desc='orbit eccentricity') bal = BalanceComp() bal.add_balance(name='E', val=0.0, units='rad', eq_units='rad', rhs_name='M') # Override the guess_nonlinear method, always initialize E to the value of M def guess_func(inputs, outputs, residuals): outputs['E'] = inputs['M'] bal.guess_nonlinear = guess_func # ExecComp used to compute the LHS of Kepler's equation. lhs_comp = ExecComp('lhs=E - ecc * sin(E)', lhs={ 'value': 0.0, 'units': 'rad' }, E={ 'value': 0.0, 'units': 'rad' }, ecc={'value': 0.0}) prob.model.add_subsystem(name='ivc', subsys=ivc, promotes_outputs=['M', 'ecc']) prob.model.add_subsystem(name='balance', subsys=bal, promotes_inputs=['M'], promotes_outputs=['E']) prob.model.add_subsystem(name='lhs_comp', subsys=lhs_comp, promotes_inputs=['E', 'ecc']) # Explicit connections prob.model.connect('lhs_comp.lhs', 'balance.lhs:E') # Setup solvers prob.model.linear_solver = DirectSolver() prob.model.nonlinear_solver = NewtonSolver() prob.model.nonlinear_solver.options['maxiter'] = 100 prob.model.nonlinear_solver.options['iprint'] = 0 prob.setup() prob['M'] = 85.0 prob['ecc'] = 0.6 prob.run_model() assert_almost_equal(np.degrees(prob['E']), 115.9, decimal=1) print('E (deg) = ', np.degrees(prob['E'][0]))
def setup(self): map_data = self.options['map_data'] design = self.options['design'] method = self.options['interp_method'] extrap = self.options['extrap'] params = map_data.param_data outputs = map_data.output_data # Define map which will be used readmap = MetaModelStructuredComp(method=method, extrapolate=extrap) for p in params: readmap.add_input(p['name'], val=p['default'], units=p['units'], training_data=p['values']) for o in outputs: readmap.add_output(o['name'], val=o['default'], units=o['units'], training_data=o['values']) if design: # In design mode, operating point specified by default values for RlineMap, NcMap and alphaMap mapDesPt = IndepVarComp() mapDesPt.add_output('NpMap', val=map_data.defaults['NpMap'], units='rpm') mapDesPt.add_output('PRmap', val=map_data.defaults['PRmap'], units=None) self.add_subsystem('mapDesPt', subsys=mapDesPt, promotes=['*']) # Evaluate map using design point values self.add_subsystem('readMap', readmap, promotes_inputs=['alphaMap', 'NpMap', 'PRmap'], promotes_outputs=['effMap', 'WpMap']) # Compute map scalars based on input PR, eff, Np and Wp as well as unscaled map values self.add_subsystem( 'scalars', MapScalars(), promotes_inputs=[ 'PR', 'eff', 'Np', 'Wp', 'NpMap', 'effMap', 'PRmap', 'WpMap' ], promotes_outputs=['s_Np', 's_PR', 's_eff', 's_Wp']) else: # In off-design mode, PRmap, NpMap and alphaMap are input to map self.add_subsystem('readMap', readmap, promotes_inputs=['alphaMap', 'NpMap', 'PRmap'], promotes_outputs=['effMap', 'WpMap']) # Compute scaled map outputs base on input scalars and unscaled map values self.add_subsystem('scaledOutput', ScaledMapValues(), promotes_inputs=[ 's_PR', 's_eff', 's_Wp', 's_Np', 'NpMap', 'effMap', 'PRmap', 'WpMap' ], promotes_outputs=['PR', 'eff']) # Use balance component to vary NpMap and PRmap to match incoming corrected flow and speed map_bal = BalanceComp() map_bal.add_balance('NpMap', val=map_data.defaults['NpMap'], units='rpm', eq_units='rpm', lower=1., upper=200.) map_bal.add_balance('PRmap', val=map_data.defaults['PRmap'], units=None, eq_units='lbm/s', lower=1.01) self.add_subsystem(name='map_bal', subsys=map_bal, promotes_inputs=[('lhs:NpMap', 'Np'), ('lhs:PRmap', 'Wp')], promotes_outputs=['NpMap', 'PRmap']) self.connect('scaledOutput.Np', 'map_bal.rhs:NpMap') self.connect('scaledOutput.Wp', 'map_bal.rhs:PRmap')