def test_err_on_non_converge(self): # Raise AnalysisError when it fails to converge prob = om.Problem() nlsolver = om.NewtonSolver() prob.model = SellarDerivatives(nonlinear_solver=nlsolver, linear_solver=om.LinearBlockGS()) nlsolver.options['err_on_non_converge'] = True nlsolver.options['maxiter'] = 1 prob.setup() prob.set_solver_print(level=0) with self.assertRaises(om.AnalysisError) as context: prob.run_driver() msg = "Solver 'NL: Newton' on system '' failed to converge in 1 iterations." self.assertEqual(str(context.exception), msg)
def setUp(self): p = self.p = om.Problem() root = p.model root.linear_solver = om.LinearBlockGS() root.linear_solver.options['err_on_non_converge'] = True inputs = root.add_subsystem("inputs", om.IndepVarComp("x", 1.0)) G1 = root.add_subsystem("G1", om.Group()) dparam = G1.add_subsystem("dparam", om.ExecComp("y = .5*x")) G1_inputs = G1.add_subsystem("inputs", om.IndepVarComp("x", 1.5)) start = G1.add_subsystem("start", om.ExecComp("y = .7*x")) timecomp = G1.add_subsystem("time", om.ExecComp("y = -.2*x")) G2 = G1.add_subsystem("G2", om.Group()) stage_step = G2.add_subsystem( "stage_step", om.ExecComp("y = -0.1*x + .5*x2 - .4*x3 + .9*x4")) ode = G2.add_subsystem("ode", om.ExecComp("y = .8*x - .6*x2")) dummy = G2.add_subsystem("dummy", om.IndepVarComp("x", 1.3)) step = G1.add_subsystem("step", om.ExecComp("y = -.2*x + .4*x2 - .4*x3")) output = G1.add_subsystem("output", om.ExecComp("y = .6*x")) con = root.add_subsystem("con", om.ExecComp("y = .2 * x")) obj = root.add_subsystem("obj", om.ExecComp("y = .3 * x")) root.connect("inputs.x", "G1.dparam.x") G1.connect("inputs.x", ["start.x", "time.x"]) G1.connect("dparam.y", "G2.ode.x") G1.connect("start.y", ["step.x", "G2.stage_step.x4"]) G1.connect("time.y", ["step.x2", "G2.stage_step.x3"]) G1.connect("step.y", "output.x") G1.connect("G2.ode.y", ["step.x3", "G2.stage_step.x"]) G2.connect("stage_step.y", "ode.x2") G2.connect("dummy.x", "stage_step.x2") root.connect("G1.output.y", ["con.x", "obj.x"]) root.add_design_var('inputs.x') root.add_constraint('con.y') root.add_constraint('obj.y')
def test_sellar_derivs(self): # Test top level Sellar (i.e., not grouped). # Also, piggybacked testing that makes sure we only call apply_nonlinear # on the head component behind the cycle break. prob = om.Problem() prob.model = SellarDerivatives( nonlinear_solver=om.NewtonSolver(solve_subsystems=False), linear_solver=om.LinearBlockGS()) prob.setup() prob.set_solver_print(level=0) prob.run_model() assert_near_equal(prob.get_val('y1'), 25.58830273, .00001) assert_near_equal(prob.get_val('y2'), 12.05848819, .00001) # Make sure we aren't iterating like crazy self.assertLess(prob.model.nonlinear_solver._iter_count, 8)
def test_feature_basic(self): import numpy as np import openmdao.api as om from openmdao.test_suite.components.sellar import SellarDis1withDerivatives, SellarDis2withDerivatives prob = om.Problem() model = prob.model model.add_subsystem('px', om.IndepVarComp('x', 1.0), promotes=['x']) model.add_subsystem('pz', om.IndepVarComp('z', np.array([5.0, 2.0])), promotes=['z']) model.add_subsystem('d1', SellarDis1withDerivatives(), promotes=['x', 'z', 'y1', 'y2']) model.add_subsystem('d2', SellarDis2withDerivatives(), promotes=['z', 'y1', 'y2']) model.add_subsystem('obj_cmp', om.ExecComp('obj = x**2 + z[1] + y1 + exp(-y2)', z=np.array([0.0, 0.0]), x=0.0), promotes=['obj', 'x', 'z', 'y1', 'y2']) model.add_subsystem('con_cmp1', om.ExecComp('con1 = 3.16 - y1'), promotes=['con1', 'y1']) model.add_subsystem('con_cmp2', om.ExecComp('con2 = y2 - 24.0'), promotes=['con2', 'y2']) model.linear_solver = om.LinearBlockGS() model.nonlinear_solver = om.NonlinearBlockJac() prob.setup() prob.run_model() assert_rel_error(self, prob['y1'], 25.58830273, .00001) assert_rel_error(self, prob['y2'], 12.05848819, .00001)
def setup(self): if self.options[PAYLOAD_FROM_NPAX]: self.add_subsystem( "payload", RegisterSubmodel.get_submodel(SERVICE_PAYLOAD_MASS), promotes=["*"]) self.add_subsystem("owe", RegisterSubmodel.get_submodel(SERVICE_OWE), promotes=["*"]) self.add_subsystem("update_mzfw_and_mlw", UpdateMLWandMZFW(), promotes=["*"]) # Solvers setup self.nonlinear_solver = om.NonlinearBlockGS() self.nonlinear_solver.options["iprint"] = 0 self.nonlinear_solver.options["maxiter"] = 50 self.linear_solver = om.LinearBlockGS() self.linear_solver.options["iprint"] = 0
def test_err_message_inf_nan(self): prob = om.Problem() nlsolver = om.NewtonSolver(solve_subsystems=False) prob.model = SellarDerivatives(nonlinear_solver=nlsolver, linear_solver=om.LinearBlockGS()) nlsolver.options['err_on_non_converge'] = True nlsolver.options['maxiter'] = 1 prob.setup() prob.set_solver_print(level=0) prob['x'] = np.nan with self.assertRaises(om.AnalysisError) as context: prob.run_model() msg = "Solver 'NL: Newton' on system '': residuals contain 'inf' or 'NaN' after 0 iterations." self.assertEqual(str(context.exception), msg)
def test_specify_solver(self): prob = om.Problem() model = prob.model model.add_subsystem('d1', SellarDis1withDerivatives(), promotes=['x', 'z', 'y1', 'y2']) model.add_subsystem('d2', SellarDis2withDerivatives(), promotes=['z', 'y1', 'y2']) model.add_subsystem('obj_cmp', om.ExecComp('obj = x**2 + z[1] + y1 + exp(-y2)', z=np.array([0.0, 0.0]), x=0.0), promotes=['obj', 'x', 'z', 'y1', 'y2']) model.add_subsystem('con_cmp1', om.ExecComp('con1 = 3.16 - y1'), promotes=['con1', 'y1']) model.add_subsystem('con_cmp2', om.ExecComp('con2 = y2 - 24.0'), promotes=['con2', 'y2']) model.linear_solver = om.LinearBlockGS() model.nonlinear_solver = om.NonlinearBlockGS() prob.setup() prob.set_val('x', 1.) prob.set_val('z', np.array([5.0, 2.0])) prob.run_model() wrt = ['z'] of = ['obj'] J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict') assert_near_equal(J['obj', 'z'][0][0], 9.61001056, .00001) assert_near_equal(J['obj', 'z'][0][1], 1.78448534, .00001)
def setup(self): self.add_subsystem( "ht_cg", RegisterSubmodel.get_submodel(SERVICE_HORIZONTAL_TAIL_CG), promotes=["*"]) self.add_subsystem( "vt_cg", RegisterSubmodel.get_submodel(SERVICE_VERTICAL_TAIL_CG), promotes=["*"]) self.add_subsystem("compute_cg_wing", RegisterSubmodel.get_submodel(SERVICE_WING_CG), promotes=["*"]) self.add_subsystem( "compute_cg_control_surface", RegisterSubmodel.get_submodel(SERVICE_FLIGHT_CONTROLS_CG), promotes=["*"], ) self.add_subsystem("compute_cg_tanks", RegisterSubmodel.get_submodel(SERVICE_TANKS_CG), promotes=["*"]) self.add_subsystem("compute_cg_others", RegisterSubmodel.get_submodel(SERVICE_OTHERS_CG), promotes=["*"]) self.add_subsystem("compute_cg", RegisterSubmodel.get_submodel(SERVICE_GLOBAL_CG), promotes=["*"]) self.add_subsystem("update_mlg", RegisterSubmodel.get_submodel(SERVICE_MLG_CG), promotes=["*"]) self.add_subsystem("aircraft", RegisterSubmodel.get_submodel(SERVICE_AIRCRAFT_CG), promotes=["*"]) # Solvers setup self.nonlinear_solver = om.NonlinearBlockGS() self.nonlinear_solver.options["iprint"] = 0 self.nonlinear_solver.options["maxiter"] = 200 self.linear_solver = om.LinearBlockGS() self.linear_solver.options["iprint"] = 0
def test_dataflow_1_level(self): p = om.Problem() root = p.model root.add_subsystem("indep", om.IndepVarComp('x', 1.0)) root.add_subsystem("C1", MyComp()) root.add_subsystem("C2", MyComp()) root.add_subsystem("C3", MyComp()) root.add_subsystem("C4", MyComp()) root.connect("C4.y", "C2.a") root.connect("C4.y", "C3.a") root.connect("C2.y", "C1.a") root.connect("C1.y", "C4.a") # make sure no system has dangling inputs so we avoid that warning root.connect("indep.x", "C1.b") root.connect("indep.x", "C2.b") root.connect("indep.x", "C3.b") root.connect("indep.x", "C4.b") # set iterative solvers since we have cycles root.linear_solver = om.LinearBlockGS() root.nonlinear_solver = om.NonlinearBlockGS() testlogger = TestLogger() p.setup(check=['cycles', 'out_of_order'], logger=testlogger) p.final_setup() expected_info = ( "The following groups contain cycles:\n" " Group '' has the following cycles: [['C1', 'C2', 'C4']]\n" ) expected_warning = ( "The following systems are executed out-of-order:\n" " System 'C3' executes out-of-order with respect to its source systems ['C4']\n" ) testlogger.find_in('info', expected_info) testlogger.find_in('warning', expected_warning)
def __init__(self, comp_class=QuadraticCompVectorized): super().__init__() model = self.model comp1 = model.add_subsystem('p', om.IndepVarComp()) comp1.add_output('a', np.array([1.0, 2.0, 3.0])) comp1.add_output('b', np.array([2.0, 3.0, 4.0])) comp1.add_output('c', np.array([-1.0, -2.0, -3.0])) model.add_subsystem('comp', comp_class()) model.connect('p.a', 'comp.a') model.connect('p.b', 'comp.b') model.connect('p.c', 'comp.c') model.add_design_var('p.a', vectorize_derivs=True) model.add_design_var('p.b', vectorize_derivs=True) model.add_design_var('p.c', vectorize_derivs=True) model.add_constraint('comp.x', vectorize_derivs=True) model.linear_solver = om.LinearBlockGS()
def test_dup_par_par_derivs(self): # duplicated output, parallel input prob = om.Problem() model = prob.model model.add_subsystem('indep', om.IndepVarComp('x', 1.0)) par = model.add_subsystem('par', om.ParallelGroup()) par.add_subsystem('C1', om.ExecComp('y = 2.5 * x')) par.add_subsystem('C2', om.ExecComp('y = 7 * x')) model.connect('indep.x', 'par.C1.x') model.connect('indep.x', 'par.C2.x') model.add_design_var('indep.x') model.add_constraint('par.C1.y', upper=0.0, parallel_deriv_color='parc') model.add_constraint('par.C2.y', upper=0.0, parallel_deriv_color='parc') # of=['par.C1.y', 'par.C2.y'] # wrt=['indep.x'] prob.model.linear_solver = om.LinearBlockGS() #import wingdbstub prob.setup(check=False, mode='rev') prob.set_solver_print(level=0) prob.run_model() assert_near_equal(prob.get_val('par.C1.y', get_remote=True), 2.5, 1e-6) assert_near_equal(prob.get_val('par.C2.y', get_remote=True), 7., 1e-6) J = prob.driver._compute_totals() assert_near_equal(J['par.C1.y', 'indep.x'][0][0], 2.5, 1e-6) assert_near_equal(prob.get_val('par.C1.y', get_remote=True), 2.5, 1e-6) assert_near_equal(J['par.C2.y', 'indep.x'][0][0], 7., 1e-6) assert_near_equal(prob.get_val('par.C2.y', get_remote=True), 7., 1e-6)
def test_specify_precon(self): prob = om.Problem() model = prob.model model.add_subsystem('d1', SellarDis1withDerivatives(), promotes=['x', 'z', 'y1', 'y2']) model.add_subsystem('d2', SellarDis2withDerivatives(), promotes=['z', 'y1', 'y2']) model.add_subsystem('obj_cmp', om.ExecComp('obj = x**2 + z[1] + y1 + exp(-y2)', z=np.array([0.0, 0.0]), x=0.0), promotes=['obj', 'x', 'z', 'y1', 'y2']) model.add_subsystem('con_cmp1', om.ExecComp('con1 = 3.16 - y1'), promotes=['con1', 'y1']) model.add_subsystem('con_cmp2', om.ExecComp('con2 = y2 - 24.0'), promotes=['con2', 'y2']) model.nonlinear_solver = om.NewtonSolver(solve_subsystems=False) model.linear_solver = om.PETScKrylov() model.linear_solver.precon = om.LinearBlockGS() model.linear_solver.precon.options['maxiter'] = 2 prob.setup() prob.set_val('x', 1.) prob.set_val('z', np.array([5.0, 2.0])) prob.run_model() assert_near_equal(prob.get_val('y1'), 25.58830273, .00001) assert_near_equal(prob.get_val('y2'), 12.05848819, .00001)
def test_distributed_norm_parallel_group(self): prob = om.Problem() model = prob.model comp = om.IndepVarComp() comp.add_output('v1', val=np.array([3.0, 5.0, 8.0])) comp.add_output('v2', val=np.array([17.0])) model.add_subsystem('des_vars', comp) sub = model.add_subsystem('pp', om.ParallelGroup()) sub.add_subsystem( 'calc1', om.ExecComp('y = 2.0*x', x=np.ones((3, )), y=np.ones((3, )))) sub.add_subsystem( 'calc2', om.ExecComp('y = 5.0*x', x=np.ones((3, )), y=np.ones((3, )))) sub.add_subsystem( 'calc3', om.ExecComp('y = 7.0*x', x=np.ones((3, )), y=np.ones((3, )))) model.connect('des_vars.v1', 'pp.calc1.x') model.connect('des_vars.v1', 'pp.calc2.x') model.connect('des_vars.v1', 'pp.calc3.x') model.linear_solver = om.LinearBlockGS() prob.setup() prob.run_model() vec = prob.model._vectors['output']['nonlinear'] norm_val = vec.get_norm() assert_rel_error(self, norm_val, 89.61584681293817, 1e-10) J = prob.compute_totals(of=['pp.calc1.y', 'pp.calc2.y', 'pp.calc3.y'], wrt=['des_vars.v1']) vec = prob.model._vectors['output']['linear'] norm_val = vec.get_norm() assert_rel_error(self, norm_val, 8.888194417315589, 1e-10)
def test_feature_rtol(self): prob = om.Problem() model = prob.model model.add_subsystem('d1', SellarDis1withDerivatives(), promotes=['x', 'z', 'y1', 'y2']) model.add_subsystem('d2', SellarDis2withDerivatives(), promotes=['z', 'y1', 'y2']) model.add_subsystem('obj_cmp', om.ExecComp('obj = x**2 + z[1] + y1 + exp(-y2)', z=np.array([0.0, 0.0]), x=0.0), promotes=['obj', 'x', 'z', 'y1', 'y2']) model.add_subsystem('con_cmp1', om.ExecComp('con1 = 3.16 - y1'), promotes=['con1', 'y1']) model.add_subsystem('con_cmp2', om.ExecComp('con2 = y2 - 24.0'), promotes=['con2', 'y2']) model.linear_solver = om.LinearBlockGS() nlbgs = model.nonlinear_solver = om.NonlinearBlockJac() nlbgs.options['rtol'] = 1e-3 prob.setup() prob.set_val('x', 1.) prob.set_val('z', np.array([5.0, 2.0])) prob.run_model() assert_near_equal(prob.get_val('y1'), 25.5891491526, .00001) assert_near_equal(prob.get_val('y2'), 12.0569142166, .00001)
def test_feature_rtol(self): import numpy as np import openmdao.api as om from openmdao.test_suite.components.sellar import SellarDis1withDerivatives, SellarDis2withDerivatives prob = om.Problem() model = prob.model model.add_subsystem('d1', SellarDis1withDerivatives(), promotes=['x', 'z', 'y1', 'y2']) model.add_subsystem('d2', SellarDis2withDerivatives(), promotes=['z', 'y1', 'y2']) model.add_subsystem('obj_cmp', om.ExecComp('obj = x**2 + z[1] + y1 + exp(-y2)', z=np.array([0.0, 0.0]), x=0.0), promotes=['obj', 'x', 'z', 'y1', 'y2']) model.add_subsystem('con_cmp1', om.ExecComp('con1 = 3.16 - y1'), promotes=['con1', 'y1']) model.add_subsystem('con_cmp2', om.ExecComp('con2 = y2 - 24.0'), promotes=['con2', 'y2']) model.nonlinear_solver = om.NonlinearBlockGS() model.linear_solver = om.LinearBlockGS() model.linear_solver.options['rtol'] = 1.0e-3 prob.setup() prob.set_val('x', 1.) prob.set_val('z', np.array([5.0, 2.0])) prob.run_model() wrt = ['z'] of = ['obj'] J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict') assert_near_equal(J['obj', 'z'][0][0], 9.61016296175, .00001) assert_near_equal(J['obj', 'z'][0][1], 1.78456955704, .00001)
def test_circuit(self): import openmdao.api as om from openmdao.test_suite.scripts.circuit_analysis import Circuit p = om.Problem() model = p.model model.add_subsystem('circuit', Circuit(), promotes_inputs=[('Vg', 'V'), ('I_in', 'I')]) model.set_input_defaults('V', 0., units='V') model.set_input_defaults('I', 0.1, units='A') p.setup() # Replace existing solver with om.BroydenSolver model.circuit.nonlinear_solver = om.BroydenSolver() model.circuit.nonlinear_solver.options['maxiter'] = 20 # Specify states for Broyden to solve model.circuit.nonlinear_solver.options['state_vars'] = ['n1.V', 'n2.V'] model.nonlinear_solver.linear_solver = om.LinearBlockGS() # set some initial guesses p.set_val('circuit.n1.V', 10.) p.set_val('circuit.n2.V', 1.) p.set_solver_print(level=2) p.run_model() assert_near_equal(p.get_val('circuit.n1.V'), 9.90804735, 1e-5) assert_near_equal(p.get_val('circuit.n2.V'), 0.71278226, 1e-5) # sanity check: should sum to .1 Amps assert_near_equal( p.get_val('circuit.R1.I') + p.get_val('circuit.D1.I'), .1, 1e-6)
def test_circuit(self): import openmdao.api as om from openmdao.test_suite.scripts.circuit_analysis import Circuit p = om.Problem() model = p.model model.add_subsystem('ground', om.IndepVarComp('V', 0., units='V')) model.add_subsystem('source', om.IndepVarComp('I', 0.1, units='A')) model.add_subsystem('circuit', Circuit()) model.connect('source.I', 'circuit.I_in') model.connect('ground.V', 'circuit.Vg') p.setup() # Replace existing solver with om.BroydenSolver model.circuit.nonlinear_solver = om.BroydenSolver() model.circuit.nonlinear_solver.options['maxiter'] = 20 # Specify states for Broyden to solve model.circuit.nonlinear_solver.options['state_vars'] = ['n1.V', 'n2.V'] model.nonlinear_solver.linear_solver = om.LinearBlockGS() # set some initial guesses p['circuit.n1.V'] = 10. p['circuit.n2.V'] = 1. p.set_solver_print(level=2) p.run_model() assert_rel_error(self, p['circuit.n1.V'], 9.90804735, 1e-5) assert_rel_error(self, p['circuit.n2.V'], 0.71278226, 1e-5) # sanity check: should sum to .1 Amps assert_rel_error(self, p['circuit.R1.I'] + p['circuit.D1.I'], .1, 1e-6)
def test_feature_basic(self): prob = om.Problem() model = prob.model model.add_subsystem('d1', SellarDis1withDerivatives(), promotes=['x', 'z', 'y1', 'y2']) model.add_subsystem('d2', SellarDis2withDerivatives(), promotes=['z', 'y1', 'y2']) model.add_subsystem('obj_cmp', om.ExecComp('obj = x**2 + z[1] + y1 + exp(-y2)', z=np.array([0.0, 0.0]), x=0.0), promotes=['obj', 'x', 'z', 'y1', 'y2']) model.add_subsystem('con_cmp1', om.ExecComp('con1 = 3.16 - y1'), promotes=['con1', 'y1']) model.add_subsystem('con_cmp2', om.ExecComp('con2 = y2 - 24.0'), promotes=['con2', 'y2']) model.linear_solver = om.LinearBlockGS() model.nonlinear_solver = om.NonlinearBlockJac() prob.setup() prob.set_val('x', 1.) prob.set_val('z', np.array([5.0, 2.0])) prob.run_model() assert_near_equal(prob['y1'], 25.58830273, .00001) assert_near_equal(prob['y2'], 12.05848819, .00001)
def test_feature_maxiter(self): import numpy as np import openmdao.api as om from openmdao.test_suite.components.sellar import SellarDis1withDerivatives, SellarDis2withDerivatives prob = om.Problem() model = prob.model model.add_subsystem('px', om.IndepVarComp('x', 1.0), promotes=['x']) model.add_subsystem('pz', om.IndepVarComp('z', np.array([5.0, 2.0])), promotes=['z']) model.add_subsystem('d1', SellarDis1withDerivatives(), promotes=['x', 'z', 'y1', 'y2']) model.add_subsystem('d2', SellarDis2withDerivatives(), promotes=['z', 'y1', 'y2']) model.add_subsystem('obj_cmp', om.ExecComp('obj = x**2 + z[1] + y1 + exp(-y2)', z=np.array([0.0, 0.0]), x=0.0), promotes=['obj', 'x', 'z', 'y1', 'y2']) model.add_subsystem('con_cmp1', om.ExecComp('con1 = 3.16 - y1'), promotes=['con1', 'y1']) model.add_subsystem('con_cmp2', om.ExecComp('con2 = y2 - 24.0'), promotes=['con2', 'y2']) model.nonlinear_solver = om.NonlinearBlockGS() model.linear_solver = om.LinearBlockGS() model.linear_solver.options['maxiter'] = 2 prob.setup() prob.run_model() wrt = ['z'] of = ['obj'] J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict') assert_rel_error(self, J['obj', 'z'][0][0], 9.60230118004, .00001) assert_rel_error(self, J['obj', 'z'][0][1], 1.78022500547, .00001)
def test_specify_precon(self): import numpy as np import openmdao.api as om from openmdao.test_suite.components.quad_implicit import QuadraticComp prob = om.Problem() model = prob.model sub1 = model.add_subsystem('sub1', om.Group()) sub1.add_subsystem('q1', QuadraticComp()) sub1.add_subsystem('z1', om.ExecComp('y = -6.0 + .01 * x')) sub2 = model.add_subsystem('sub2', om.Group()) sub2.add_subsystem('q2', QuadraticComp()) sub2.add_subsystem('z2', om.ExecComp('y = -6.0 + .01 * x')) model.connect('sub1.q1.x', 'sub1.z1.x') model.connect('sub1.z1.y', 'sub2.q2.c') model.connect('sub2.q2.x', 'sub2.z2.x') model.connect('sub2.z2.y', 'sub1.q1.c') model.nonlinear_solver = om.NewtonSolver() model.linear_solver = om.ScipyKrylov() prob.setup() model.sub1.linear_solver = om.DirectSolver() model.sub2.linear_solver = om.DirectSolver() model.linear_solver.precon = om.LinearBlockGS() prob.set_solver_print(level=2) prob.run_model() assert_rel_error(self, prob['sub1.q1.x'], 1.996, .0001) assert_rel_error(self, prob['sub2.q2.x'], 1.996, .0001)
def setup(self): self.add_subsystem("ht_cg", ComputeHTcg(), promotes=["*"]) self.add_subsystem("vt_cg", ComputeVTcg(), promotes=["*"]) self.add_subsystem("compute_cg_wing", ComputeWingCG(), promotes=["*"]) self.add_subsystem("compute_cg_control_surface", ComputeControlSurfacesCG(), promotes=["*"]) self.add_subsystem("compute_cg_tanks", ComputeTanksCG(), promotes=["*"]) self.add_subsystem("compute_cg_others", ComputeOthersCG(), promotes=["*"]) self.add_subsystem("compute_cg", ComputeGlobalCG(), promotes=["*"]) self.add_subsystem("update_mlg", UpdateMLG(), promotes=["*"]) self.add_subsystem("aircraft", ComputeAircraftCG(), promotes=["*"]) # Solvers setup self.nonlinear_solver = om.NonlinearBlockGS() self.nonlinear_solver.options["iprint"] = 0 self.nonlinear_solver.options["maxiter"] = 200 self.linear_solver = om.LinearBlockGS() self.linear_solver.options["iprint"] = 0
def setup(self): if self.options[PAYLOAD_FROM_NPAX]: self.add_subsystem("payload", ComputePayload(), promotes=["*"]) self.add_subsystem("owe", ComputeOperatingWeightEmpty( propulsion_id=self.options["propulsion_id"]), promotes=["*"]) self.add_subsystem("update_mzfw_and_mlw", UpdateMLWandMZFW(), promotes=["*"]) # Solvers setup self.nonlinear_solver = om.NonlinearBlockGS() self.nonlinear_solver.options["debug_print"] = True self.nonlinear_solver.options["err_on_non_converge"] = True self.nonlinear_solver.options["iprint"] = 0 self.nonlinear_solver.options["maxiter"] = 50 # self.nonlinear_solver.options["reraise_child_analysiserror"] = True # self.nonlinear_solver.options["rtol"] = 1e-3 self.linear_solver = om.LinearBlockGS() self.linear_solver.options["err_on_non_converge"] = True self.linear_solver.options["iprint"] = 0 self.linear_solver.options["maxiter"] = 10
def test_list_residuals_with_tol(self): import openmdao.api as om from openmdao.test_suite.components.sellar import SellarImplicitDis1, SellarImplicitDis2 prob = om.Problem() model = prob.model model.add_subsystem('p1', om.IndepVarComp('x', 1.0)) model.add_subsystem('d1', SellarImplicitDis1()) model.add_subsystem('d2', SellarImplicitDis2()) model.connect('d1.y1', 'd2.y1') model.connect('d2.y2', 'd1.y2') model.nonlinear_solver = om.NewtonSolver() model.nonlinear_solver.options['maxiter'] = 5 model.linear_solver = om.ScipyKrylov() model.linear_solver.precon = om.LinearBlockGS() prob.setup() prob.set_solver_print(level=-1) prob.run_model() outputs = model.list_outputs(residuals_tol=0.01, residuals=True) print(outputs)
def test_hierarchy_list_vars_options(self): prob = om.Problem() model = prob.model model.add_subsystem('pz', om.IndepVarComp('z', np.array([5.0, 2.0]))) sub1 = model.add_subsystem('sub1', om.Group()) sub2 = sub1.add_subsystem('sub2', om.Group()) g1 = sub2.add_subsystem('g1', SubSellar()) g2 = model.add_subsystem('g2', SubSellar()) model.connect('pz.z', 'sub1.sub2.g1.z') model.connect('sub1.sub2.g1.y2', 'g2.x') model.connect('g2.y2', 'sub1.sub2.g1.x') model.nonlinear_solver = om.NewtonSolver() model.linear_solver = om.ScipyKrylov() model.nonlinear_solver.options['solve_subsystems'] = True model.nonlinear_solver.options['max_sub_solves'] = 0 g1.nonlinear_solver = om.NewtonSolver(solve_subsystems=False) g1.linear_solver = om.LinearBlockGS() g2.nonlinear_solver = om.NewtonSolver(solve_subsystems=False) g2.linear_solver = om.ScipyKrylov() g2.linear_solver.precon = om.LinearBlockGS() g2.linear_solver.precon.options['maxiter'] = 2 prob.setup() prob.run_driver() # logging inputs # out_stream - not hierarchical - extras - no print_arrays stream = StringIO() prob.model.list_inputs(values=True, units=True, hierarchical=False, print_arrays=False, out_stream=stream) text = stream.getvalue() self.assertEqual(1, text.count("10 Input(s) in 'model'")) # make sure they are in the correct order self.assertTrue( text.find("sub1.sub2.g1.d1.z") < text.find('sub1.sub2.g1.d1.x') < text.find('sub1.sub2.g1.d1.y2') < text.find('sub1.sub2.g1.d2.z') < text.find('sub1.sub2.g1.d2.y1') < text.find('g2.d1.z') < text.find( 'g2.d1.x') < text.find('g2.d1.y2') < text.find( 'g2.d2.z') < text.find('g2.d2.y1')) num_non_empty_lines = sum([1 for s in text.splitlines() if s.strip()]) self.assertEqual(14, num_non_empty_lines) # out_stream - hierarchical - extras - no print_arrays stream = StringIO() prob.model.list_inputs(values=True, units=True, hierarchical=True, print_arrays=False, out_stream=stream) text = stream.getvalue() self.assertEqual(1, text.count("10 Input(s) in 'model'")) num_non_empty_lines = sum([1 for s in text.splitlines() if s.strip()]) self.assertEqual(22, num_non_empty_lines) self.assertEqual(1, text.count('\nsub1')) self.assertEqual(1, text.count('\n sub2')) self.assertEqual(1, text.count('\n g1')) self.assertEqual(1, text.count('\n d1')) self.assertEqual(2, text.count('\n z')) # logging outputs # out_stream - not hierarchical - extras - no print_arrays stream = StringIO() prob.model.list_outputs(values=True, units=True, shape=True, bounds=True, residuals=True, scaling=True, hierarchical=False, print_arrays=False, out_stream=stream) text = stream.getvalue() self.assertEqual(text.count('5 Explicit Output'), 1) # make sure they are in the correct order self.assertTrue( text.find("pz.z") < text.find('sub1.sub2.g1.d1.y1') < text.find( 'sub1.sub2.g1.d2.y2') < text.find('g2.d1.y1') < text.find( 'g2.d2.y2')) num_non_empty_lines = sum([1 for s in text.splitlines() if s.strip()]) self.assertEqual(11, num_non_empty_lines) # Hierarchical stream = StringIO() prob.model.list_outputs(values=True, units=True, shape=True, bounds=True, residuals=True, scaling=True, hierarchical=True, print_arrays=False, out_stream=stream) text = stream.getvalue() self.assertEqual(text.count('\n y1'), 1) self.assertEqual(text.count('\ng2'), 1) num_non_empty_lines = sum([1 for s in text.splitlines() if s.strip()]) self.assertEqual(num_non_empty_lines, 20)
def test_solve_linear_ksp_precon(self): """Solve implicit system with PETScKrylov using a preconditioner.""" group = TestImplicitGroup(lnSolverClass=om.PETScKrylov) precon = group.linear_solver.precon = om.LinearBlockGS() p = om.Problem(group) p.setup() p.set_solver_print(level=0) # Conclude setup but don't run model. p.final_setup() d_inputs, d_outputs, d_residuals = group.get_linear_vectors() # forward d_residuals.set_val(1.0) d_outputs.set_val(0.0) group.run_solve_linear(['linear'], 'fwd') output = d_outputs._data assert_near_equal(output, group.expected_solution, 1e-15) self.assertTrue(precon._iter_count > 0) # reverse d_outputs.set_val(1.0) d_residuals.set_val(0.0) group.run_solve_linear(['linear'], 'rev') output = d_residuals._data assert_near_equal(output, group.expected_solution, 3e-15) self.assertTrue(precon._iter_count > 0) # test the direct solver and make sure KSP correctly recurses for _linearize precon = group.linear_solver.precon = om.DirectSolver( assemble_jac=False) p.setup() # Conclude setup but don't run model. p.final_setup() d_inputs, d_outputs, d_residuals = group.get_linear_vectors() # forward d_residuals.set_val(1.0) d_outputs.set_val(0.0) group.linear_solver._linearize() group.run_solve_linear(['linear'], 'fwd') output = d_outputs._data assert_near_equal(output, group.expected_solution, 1e-15) # reverse d_outputs.set_val(1.0) d_residuals.set_val(0.0) group.linear_solver._linearize() group.run_solve_linear(['linear'], 'rev') output = d_residuals._data assert_near_equal(output, group.expected_solution, 3e-15)
def setup(self): opt = self.options["modeling_options"]["WISDEM"]["DriveSE"] n_dlcs = self.options["n_dlcs"] direct = opt["direct"] dogen = self.options["modeling_options"]["flags"]["generator"] n_pc = self.options["modeling_options"]["WISDEM"]["RotorSE"]["n_pc"] self.set_input_defaults("machine_rating", units="kW") self.set_input_defaults("planet_numbers", [3, 3, 0]) self.set_input_defaults("gear_configuration", "eep") self.set_input_defaults("hvac_mass_coeff", 0.025, units="kg/kW/m") # self.set_input_defaults('mb1Type', 'CARB') # self.set_input_defaults('mb2Type', 'SRB') self.set_input_defaults("uptower", True) self.set_input_defaults("upwind", True) self.set_input_defaults("n_blades", 3) # Materials prep self.add_subsystem( "mat", DriveMaterials( direct=direct, n_mat=self.options["modeling_options"]["materials"]["n_mat"]), promotes=["*"], ) # Need to do these first, before the layout self.add_subsystem("hub", Hub_System(modeling_options=opt["hub"]), promotes=["*"]) self.add_subsystem("gear", Gearbox(direct_drive=direct), promotes=["*"]) # Layout and mass for the big items if direct: self.add_subsystem("layout", lay.DirectLayout(), promotes=["*"]) else: self.add_subsystem("layout", lay.GearedLayout(), promotes=["*"]) # All the smaller items self.add_subsystem("bear1", dc.MainBearing()) self.add_subsystem("bear2", dc.MainBearing()) self.add_subsystem("brake", dc.Brake(direct_drive=direct), promotes=["*"]) self.add_subsystem("elec", dc.Electronics(), promotes=["*"]) self.add_subsystem("yaw", dc.YawSystem(), promotes=[ "yaw_mass", "yaw_I", "yaw_cm", "rotor_diameter", "D_top" ]) # Generator self.add_subsystem("rpm", dc.RPM_Input(n_pc=n_pc), promotes=["*"]) if dogen: gentype = self.options["modeling_options"]["WISDEM"][ "GeneratorSE"]["type"] self.add_subsystem( "generator", Generator(design=gentype, n_pc=n_pc), promotes=[ "generator_mass", "generator_cost", "generator_I", "machine_rating", "generator_efficiency", "rated_torque", ("rotor_mass", "generator_rotor_mass"), ("rotor_I", "generator_rotor_I"), ("stator_mass", "generator_stator_mass"), ("stator_I", "generator_stator_I"), ], ) else: self.add_subsystem("gensimp", dc.GeneratorSimple(direct_drive=direct, n_pc=n_pc), promotes=["*"]) # Final tallying self.add_subsystem("misc", dc.MiscNacelleComponents(), promotes=["*"]) self.add_subsystem("nac", dc.NacelleSystemAdder(), promotes=["*"]) self.add_subsystem("rna", dc.RNA_Adder(), promotes=["*"]) # Structural analysis self.add_subsystem("lss", ds.Hub_Rotor_LSS_Frame(n_dlcs=n_dlcs, modeling_options=opt, direct_drive=direct), promotes=["*"]) if direct: self.add_subsystem("nose", ds.Nose_Stator_Bedplate_Frame( modeling_options=opt, n_dlcs=n_dlcs), promotes=["*"]) else: self.add_subsystem("hss", ds.HSS_Frame(modeling_options=opt, n_dlcs=n_dlcs), promotes=["*"]) self.add_subsystem("bed", ds.Bedplate_IBeam_Frame(modeling_options=opt, n_dlcs=n_dlcs), promotes=["*"]) # Output-to-input connections self.connect("bedplate_rho", ["pitch_system.rho", "spinner.metal_rho"]) self.connect("bedplate_Xy", ["pitch_system.Xy", "spinner.Xy"]) self.connect("bedplate_mat_cost", "spinner.metal_cost") self.connect("hub_rho", ["hub_shell.rho", "rho_castiron"]) self.connect("hub_Xy", "hub_shell.Xy") self.connect("hub_mat_cost", "hub_shell.metal_cost") self.connect("spinner_rho", ["spinner.composite_rho", "rho_fiberglass"]) self.connect("spinner_Xt", "spinner.composite_Xt") self.connect("spinner_mat_cost", "spinner.composite_cost") if direct: self.connect("D_bearing1", "bear1.D_bearing") self.connect("D_bearing2", "bear2.D_bearing") self.connect("bear1.mb_mass", "mb1_mass") self.connect("bear1.mb_I", "mb1_I") self.connect("bear1.mb_max_defl_ang", "mb1_max_defl_ang") self.connect("s_mb1", "mb1_cm") self.connect("bear2.mb_mass", "mb2_mass") self.connect("bear2.mb_I", "mb2_I") self.connect("bear2.mb_max_defl_ang", "mb2_max_defl_ang") self.connect("s_mb2", "mb2_cm") self.connect("bedplate_rho", "yaw.rho") self.connect("s_gearbox", "gearbox_cm") self.connect("s_generator", "generator_cm") if dogen: self.connect("generator.R_out", "R_generator") self.connect("bedplate_E", "generator.E") self.connect("bedplate_G", "generator.G") if direct: self.connect("lss_rpm", "generator.shaft_rpm") self.connect("torq_deflection", "generator.y_sh") self.connect("torq_rotation", "generator.theta_sh") self.connect("stator_deflection", "generator.y_bd") self.connect("stator_rotation", "generator.theta_bd") self.linear_solver = lbgs = om.LinearBlockGS() self.nonlinear_solver = nlbgs = om.NonlinearBlockGS() nlbgs.options["maxiter"] = 3 nlbgs.options["atol"] = nlbgs.options["atol"] = 1e-2 nlbgs.options["iprint"] = 0 else: self.connect("hss_rpm", "generator.shaft_rpm")
def setup(self): modeling_options = self.options["modeling_options"] opt_options = self.options["opt_options"] if modeling_options["flags"]["blade"] and modeling_options["flags"][ "nacelle"]: self.linear_solver = lbgs = om.LinearBlockGS() self.nonlinear_solver = nlbgs = om.NonlinearBlockGS() nlbgs.options["maxiter"] = 5 nlbgs.options["atol"] = 1e-2 nlbgs.options["rtol"] = 1e-8 nlbgs.options["iprint"] = 0 # Analysis components self.add_subsystem( "wt_init", WindTurbineOntologyOpenMDAO(modeling_options=modeling_options, opt_options=opt_options), promotes=["*"], ) if modeling_options["flags"]["blade"]: self.add_subsystem( "rotorse", RotorSE(modeling_options=modeling_options, opt_options=opt_options)) if modeling_options["flags"]["nacelle"]: self.add_subsystem( "drivese", DrivetrainSE(modeling_options=modeling_options, n_dlcs=1)) if modeling_options["flags"][ "tower"] and not modeling_options["flags"]["floating"]: self.add_subsystem("towerse", TowerSE(modeling_options=modeling_options)) if modeling_options["flags"]["floating"]: self.add_subsystem("floatingse", FloatingSE(modeling_options=modeling_options)) if modeling_options["flags"]["blade"] and modeling_options["flags"][ "tower"]: self.add_subsystem( "tcons", TurbineConstraints(modeling_options=modeling_options)) self.add_subsystem( "tcc", Turbine_CostsSE_2015( verbosity=modeling_options["General"]["verbosity"])) if modeling_options["flags"]["blade"]: n_span = modeling_options["WISDEM"]["RotorSE"]["n_span"] # Conncetions to ccblade self.connect("blade.pa.chord_param", "rotorse.chord") self.connect("blade.pa.twist_param", "rotorse.ccblade.twist") self.connect("blade.opt_var.s_opt_chord", "rotorse.ccblade.s_opt_chord") self.connect("blade.opt_var.s_opt_twist", "rotorse.ccblade.s_opt_twist") self.connect("blade.outer_shape_bem.s", "rotorse.s") self.connect("assembly.r_blade", "rotorse.r") self.connect("assembly.rotor_radius", "rotorse.Rtip") self.connect("hub.radius", "rotorse.Rhub") self.connect("blade.interp_airfoils.r_thick_interp", "rotorse.ccblade.rthick") self.connect("airfoils.aoa", "rotorse.airfoils_aoa") self.connect("airfoils.Re", "rotorse.airfoils_Re") self.connect("blade.interp_airfoils.cl_interp", "rotorse.airfoils_cl") self.connect("blade.interp_airfoils.cd_interp", "rotorse.airfoils_cd") self.connect("blade.interp_airfoils.cm_interp", "rotorse.airfoils_cm") self.connect("assembly.hub_height", "rotorse.hub_height") self.connect("hub.cone", "rotorse.precone") self.connect("nacelle.uptilt", "rotorse.tilt") self.connect("assembly.blade_ref_axis", "rotorse.precurve", src_indices=[(i, 0) for i in np.arange(n_span)]) self.connect("assembly.blade_ref_axis", "rotorse.precurveTip", src_indices=[(-1, 0)]) self.connect("assembly.blade_ref_axis", "rotorse.presweep", src_indices=[(i, 1) for i in np.arange(n_span)]) self.connect("assembly.blade_ref_axis", "rotorse.presweepTip", src_indices=[(-1, 1)]) if modeling_options["flags"]["control"]: self.connect("control.rated_pitch", "rotorse.pitch") self.connect("control.rated_TSR", "rotorse.tsr") self.connect("env.rho_air", "rotorse.rho_air") self.connect("env.mu_air", "rotorse.mu_air") self.connect("env.shear_exp", "rotorse.shearExp") self.connect( "configuration.n_blades", [ "rotorse.nBlades", "rotorse.re.precomp.n_blades", "rotorse.rs.constr.blade_number" ], ) self.connect("configuration.ws_class", "rotorse.wt_class.turbine_class") self.connect("blade.ps.layer_thickness_param", "rotorse.re.precomp.layer_thickness") # Connections to rotor elastic and frequency analysis self.connect("nacelle.uptilt", "rotorse.re.precomp.uptilt") self.connect("blade.outer_shape_bem.pitch_axis", "rotorse.re.pitch_axis") self.connect("blade.interp_airfoils.coord_xy_interp", "rotorse.re.coord_xy_interp") self.connect("blade.internal_structure_2d_fem.layer_start_nd", "rotorse.re.precomp.layer_start_nd") self.connect("blade.internal_structure_2d_fem.layer_end_nd", "rotorse.re.precomp.layer_end_nd") self.connect("blade.internal_structure_2d_fem.layer_web", "rotorse.re.precomp.layer_web") self.connect("blade.internal_structure_2d_fem.definition_layer", "rotorse.re.precomp.definition_layer") self.connect("blade.internal_structure_2d_fem.web_start_nd", "rotorse.re.precomp.web_start_nd") self.connect("blade.internal_structure_2d_fem.web_end_nd", "rotorse.re.precomp.web_end_nd") self.connect("blade.internal_structure_2d_fem.joint_position", "rotorse.re.precomp.joint_position") self.connect("blade.internal_structure_2d_fem.joint_mass", "rotorse.re.precomp.joint_mass") self.connect("blade.internal_structure_2d_fem.joint_cost", "rotorse.re.precomp.joint_cost") self.connect("materials.name", "rotorse.re.precomp.mat_name") self.connect("materials.orth", "rotorse.re.precomp.orth") self.connect("materials.E", "rotorse.re.precomp.E") self.connect("materials.G", "rotorse.re.precomp.G") self.connect("materials.nu", "rotorse.re.precomp.nu") self.connect("materials.rho", "rotorse.re.precomp.rho") self.connect("materials.component_id", "rotorse.re.precomp.component_id") self.connect("materials.unit_cost", "rotorse.re.precomp.unit_cost") self.connect("materials.waste", "rotorse.re.precomp.waste") self.connect("materials.rho_fiber", "rotorse.re.precomp.rho_fiber") self.connect("materials.rho_area_dry", "rotorse.re.precomp.rho_area_dry") self.connect("materials.ply_t", "rotorse.re.precomp.ply_t") self.connect("materials.fvf", "rotorse.re.precomp.fvf") self.connect("materials.fwf", "rotorse.re.precomp.fwf") self.connect("materials.roll_mass", "rotorse.re.precomp.roll_mass") # Conncetions to rail transport module if opt_options["constraints"]["blade"]["rail_transport"]["flag"]: self.connect("assembly.blade_ref_axis", "rotorse.re.rail.blade_ref_axis") # Connections from blade struct parametrization to rotor load anlysis self.connect("blade.opt_var.s_opt_spar_cap_ss", "rotorse.rs.constr.s_opt_spar_cap_ss") self.connect("blade.opt_var.s_opt_spar_cap_ps", "rotorse.rs.constr.s_opt_spar_cap_ps") # Connections to RotorPower self.connect("control.V_in", "rotorse.rp.v_min") self.connect("control.V_out", "rotorse.rp.v_max") self.connect("configuration.rated_power", "rotorse.rp.rated_power") self.connect("control.minOmega", "rotorse.rp.omega_min") self.connect("control.maxOmega", "rotorse.rp.omega_max") self.connect("control.max_TS", "rotorse.rp.control_maxTS") self.connect("configuration.gearbox_type", "rotorse.rp.drivetrainType") self.connect("nacelle.gearbox_efficiency", "rotorse.rp.powercurve.gearbox_efficiency") if modeling_options["flags"]["nacelle"]: self.connect("drivese.lss_rpm", "rotorse.rp.powercurve.lss_rpm") self.connect("drivese.generator_efficiency", "rotorse.rp.powercurve.generator_efficiency") self.connect("env.weibull_k", "rotorse.rp.cdf.k") self.connect("configuration.turb_class", "rotorse.rp.gust.turbulence_class") # Connections to RotorStructure self.connect("blade.internal_structure_2d_fem.d_f", "rotorse.rs.brs.d_f") self.connect("blade.internal_structure_2d_fem.sigma_max", "rotorse.rs.brs.sigma_max") self.connect("blade.pa.chord_param", "rotorse.rs.brs.rootD", src_indices=[0]) self.connect("blade.ps.layer_thickness_param", "rotorse.rs.brs.layer_thickness") self.connect("blade.internal_structure_2d_fem.layer_start_nd", "rotorse.rs.brs.layer_start_nd") self.connect("blade.internal_structure_2d_fem.layer_end_nd", "rotorse.rs.brs.layer_end_nd") # Connections to DriveSE if modeling_options["flags"]["nacelle"]: self.connect("hub.diameter", "drivese.hub_diameter") self.connect("hub.hub_in2out_circ", "drivese.hub_in2out_circ") self.connect("hub.flange_t2shell_t", "drivese.flange_t2shell_t") self.connect("hub.flange_OD2hub_D", "drivese.flange_OD2hub_D") self.connect("hub.flange_ID2flange_OD", "drivese.flange_ID2flange_OD") self.connect("hub.hub_stress_concentration", "drivese.hub_stress_concentration") self.connect("hub.n_front_brackets", "drivese.n_front_brackets") self.connect("hub.n_rear_brackets", "drivese.n_rear_brackets") self.connect("hub.clearance_hub_spinner", "drivese.clearance_hub_spinner") self.connect("hub.spin_hole_incr", "drivese.spin_hole_incr") self.connect("hub.pitch_system_scaling_factor", "drivese.pitch_system_scaling_factor") self.connect("hub.spinner_gust_ws", "drivese.spinner_gust_ws") self.connect("configuration.n_blades", "drivese.n_blades") self.connect("assembly.rotor_diameter", "drivese.rotor_diameter") self.connect("configuration.upwind", "drivese.upwind") self.connect("control.minOmega", "drivese.minimum_rpm") self.connect("rotorse.rp.powercurve.rated_Omega", "drivese.rated_rpm") self.connect("rotorse.rp.powercurve.rated_Q", "drivese.rated_torque") self.connect("configuration.rated_power", "drivese.machine_rating") if modeling_options["flags"]["tower"]: self.connect("tower.diameter", "drivese.D_top", src_indices=[-1]) self.connect("rotorse.rs.aero_hub_loads.Fhub", "drivese.F_hub") self.connect("rotorse.rs.aero_hub_loads.Mhub", "drivese.M_hub") self.connect("rotorse.rs.frame.root_M", "drivese.pitch_system.BRFM", src_indices=[1]) self.connect("blade.pa.chord_param", "drivese.blade_root_diameter", src_indices=[0]) self.connect("rotorse.re.precomp.blade_mass", "drivese.blade_mass") self.connect("rotorse.re.precomp.mass_all_blades", "drivese.blades_mass") self.connect("rotorse.re.precomp.I_all_blades", "drivese.blades_I") self.connect("nacelle.distance_hub2mb", "drivese.L_h1") self.connect("nacelle.distance_mb2mb", "drivese.L_12") self.connect("nacelle.L_generator", "drivese.L_generator") self.connect("nacelle.overhang", "drivese.overhang") self.connect("nacelle.distance_tt_hub", "drivese.drive_height") self.connect("nacelle.uptilt", "drivese.tilt") self.connect("nacelle.gear_ratio", "drivese.gear_ratio") self.connect("nacelle.damping_ratio", "drivese.damping_ratio") self.connect("nacelle.mb1Type", "drivese.bear1.bearing_type") self.connect("nacelle.mb2Type", "drivese.bear2.bearing_type") self.connect("nacelle.lss_diameter", "drivese.lss_diameter") self.connect("nacelle.lss_wall_thickness", "drivese.lss_wall_thickness") if modeling_options["WISDEM"]["DriveSE"]["direct"]: self.connect("nacelle.nose_diameter", "drivese.bear1.D_shaft", src_indices=[0]) self.connect("nacelle.nose_diameter", "drivese.bear2.D_shaft", src_indices=[-1]) else: self.connect("nacelle.lss_diameter", "drivese.bear1.D_shaft", src_indices=[0]) self.connect("nacelle.lss_diameter", "drivese.bear2.D_shaft", src_indices=[-1]) self.connect("nacelle.uptower", "drivese.uptower") self.connect("nacelle.brake_mass_user", "drivese.brake_mass_user") self.connect("nacelle.hvac_mass_coeff", "drivese.hvac_mass_coeff") self.connect("nacelle.converter_mass_user", "drivese.converter_mass_user") self.connect("nacelle.transformer_mass_user", "drivese.transformer_mass_user") if modeling_options["WISDEM"]["DriveSE"]["direct"]: self.connect("nacelle.nose_diameter", "drivese.nose_diameter") # only used in direct self.connect( "nacelle.nose_wall_thickness", "drivese.nose_wall_thickness") # only used in direct self.connect( "nacelle.bedplate_wall_thickness", "drivese.bedplate_wall_thickness") # only used in direct else: self.connect("nacelle.hss_length", "drivese.L_hss") # only used in geared self.connect("nacelle.hss_diameter", "drivese.hss_diameter") # only used in geared self.connect( "nacelle.hss_wall_thickness", "drivese.hss_wall_thickness") # only used in geared self.connect("nacelle.hss_material", "drivese.hss_material") self.connect("nacelle.planet_numbers", "drivese.planet_numbers") # only used in geared self.connect( "nacelle.gear_configuration", "drivese.gear_configuration") # only used in geared self.connect( "nacelle.bedplate_flange_width", "drivese.bedplate_flange_width") # only used in geared self.connect( "nacelle.bedplate_flange_thickness", "drivese.bedplate_flange_thickness") # only used in geared self.connect( "nacelle.bedplate_web_thickness", "drivese.bedplate_web_thickness") # only used in geared self.connect("hub.hub_material", "drivese.hub_material") self.connect("hub.spinner_material", "drivese.spinner_material") self.connect("nacelle.lss_material", "drivese.lss_material") self.connect("nacelle.bedplate_material", "drivese.bedplate_material") self.connect("materials.name", "drivese.material_names") self.connect("materials.E", "drivese.E_mat") self.connect("materials.G", "drivese.G_mat") self.connect("materials.rho", "drivese.rho_mat") self.connect("materials.sigma_y", "drivese.sigma_y_mat") self.connect("materials.Xt", "drivese.Xt_mat") self.connect("materials.unit_cost", "drivese.unit_cost_mat") if modeling_options["flags"]["generator"]: self.connect("generator.B_r", "drivese.generator.B_r") self.connect("generator.P_Fe0e", "drivese.generator.P_Fe0e") self.connect("generator.P_Fe0h", "drivese.generator.P_Fe0h") self.connect("generator.S_N", "drivese.generator.S_N") self.connect("generator.alpha_p", "drivese.generator.alpha_p") self.connect("generator.b_r_tau_r", "drivese.generator.b_r_tau_r") self.connect("generator.b_ro", "drivese.generator.b_ro") self.connect("generator.b_s_tau_s", "drivese.generator.b_s_tau_s") self.connect("generator.b_so", "drivese.generator.b_so") self.connect("generator.cofi", "drivese.generator.cofi") self.connect("generator.freq", "drivese.generator.freq") self.connect("generator.h_i", "drivese.generator.h_i") self.connect("generator.h_sy0", "drivese.generator.h_sy0") self.connect("generator.h_w", "drivese.generator.h_w") self.connect("generator.k_fes", "drivese.generator.k_fes") self.connect("generator.k_fillr", "drivese.generator.k_fillr") self.connect("generator.k_fills", "drivese.generator.k_fills") self.connect("generator.k_s", "drivese.generator.k_s") self.connect("generator.m", "drivese.generator.m") self.connect("generator.mu_0", "drivese.generator.mu_0") self.connect("generator.mu_r", "drivese.generator.mu_r") self.connect("generator.p", "drivese.generator.p") self.connect("generator.phi", "drivese.generator.phi") self.connect("generator.q1", "drivese.generator.q1") self.connect("generator.q2", "drivese.generator.q2") self.connect("generator.ratio_mw2pp", "drivese.generator.ratio_mw2pp") self.connect("generator.resist_Cu", "drivese.generator.resist_Cu") self.connect("generator.sigma", "drivese.generator.sigma") self.connect("generator.y_tau_p", "drivese.generator.y_tau_p") self.connect("generator.y_tau_pr", "drivese.generator.y_tau_pr") self.connect("generator.I_0", "drivese.generator.I_0") self.connect("generator.d_r", "drivese.generator.d_r") self.connect("generator.h_m", "drivese.generator.h_m") self.connect("generator.h_0", "drivese.generator.h_0") self.connect("generator.h_s", "drivese.generator.h_s") self.connect("generator.len_s", "drivese.generator.len_s") self.connect("generator.n_r", "drivese.generator.n_r") self.connect("generator.rad_ag", "drivese.generator.rad_ag") self.connect("generator.t_wr", "drivese.generator.t_wr") self.connect("generator.n_s", "drivese.generator.n_s") self.connect("generator.b_st", "drivese.generator.b_st") self.connect("generator.d_s", "drivese.generator.d_s") self.connect("generator.t_ws", "drivese.generator.t_ws") self.connect("generator.rho_Copper", "drivese.generator.rho_Copper") self.connect("generator.rho_Fe", "drivese.generator.rho_Fe") self.connect("generator.rho_Fes", "drivese.generator.rho_Fes") self.connect("generator.rho_PM", "drivese.generator.rho_PM") self.connect("generator.C_Cu", "drivese.generator.C_Cu") self.connect("generator.C_Fe", "drivese.generator.C_Fe") self.connect("generator.C_Fes", "drivese.generator.C_Fes") self.connect("generator.C_PM", "drivese.generator.C_PM") if modeling_options["WISDEM"]["GeneratorSE"]["type"] in [ "pmsg_outer" ]: self.connect("generator.N_c", "drivese.generator.N_c") self.connect("generator.b", "drivese.generator.b") self.connect("generator.c", "drivese.generator.c") self.connect("generator.E_p", "drivese.generator.E_p") self.connect("generator.h_yr", "drivese.generator.h_yr") self.connect("generator.h_ys", "drivese.generator.h_ys") self.connect("generator.h_sr", "drivese.generator.h_sr") self.connect("generator.h_ss", "drivese.generator.h_ss") self.connect("generator.t_r", "drivese.generator.t_r") self.connect("generator.t_s", "drivese.generator.t_s") self.connect("generator.u_allow_pcent", "drivese.generator.u_allow_pcent") self.connect("generator.y_allow_pcent", "drivese.generator.y_allow_pcent") self.connect("generator.z_allow_deg", "drivese.generator.z_allow_deg") self.connect("generator.B_tmax", "drivese.generator.B_tmax") self.connect("rotorse.rp.powercurve.rated_mech", "drivese.generator.P_mech") if modeling_options["WISDEM"]["GeneratorSE"]["type"] in [ "eesg", "pmsg_arms", "pmsg_disc" ]: self.connect("generator.tau_p", "drivese.generator.tau_p") self.connect("generator.h_ys", "drivese.generator.h_ys") self.connect("generator.h_yr", "drivese.generator.h_yr") self.connect("generator.b_arm", "drivese.generator.b_arm") elif modeling_options["WISDEM"]["GeneratorSE"]["type"] in [ "scig", "dfig" ]: self.connect("generator.B_symax", "drivese.generator.B_symax") self.connect("generator.S_Nmax", "drivese.generator.S_Nmax") if modeling_options["WISDEM"]["DriveSE"]["direct"]: self.connect("nacelle.nose_diameter", "drivese.generator.D_nose", src_indices=[-1]) self.connect("nacelle.lss_diameter", "drivese.generator.D_shaft", src_indices=[0]) else: self.connect("nacelle.hss_diameter", "drivese.generator.D_shaft", src_indices=[-1]) else: self.connect("generator.generator_radius_user", "drivese.generator_radius_user") self.connect("generator.generator_mass_user", "drivese.generator_mass_user") self.connect("generator.generator_efficiency_user", "drivese.generator_efficiency_user") # Connections to TowerSE if modeling_options["flags"][ "tower"] and not modeling_options["flags"]["floating"]: if modeling_options["flags"]["nacelle"]: self.connect("drivese.base_F", "towerse.pre.rna_F") self.connect("drivese.base_M", "towerse.pre.rna_M") self.connect("drivese.rna_I_TT", "towerse.rna_I") self.connect("drivese.rna_cm", "towerse.rna_cg") self.connect("drivese.rna_mass", "towerse.rna_mass") if modeling_options["flags"]["blade"]: self.connect("rotorse.rp.gust.V_gust", "towerse.wind.Uref") self.connect("assembly.hub_height", "towerse.wind_reference_height") self.connect("assembly.hub_height", "towerse.hub_height") self.connect("env.rho_air", "towerse.rho_air") self.connect("env.mu_air", "towerse.mu_air") self.connect("env.shear_exp", "towerse.shearExp") self.connect("tower_grid.foundation_height", "towerse.tower_foundation_height") self.connect("tower.diameter", "towerse.tower_outer_diameter_in") self.connect("tower_grid.height", "towerse.tower_height") self.connect("tower_grid.s", "towerse.tower_s") self.connect("tower.layer_thickness", "towerse.tower_layer_thickness") self.connect("tower.outfitting_factor", "towerse.tower_outfitting_factor") self.connect("tower.layer_mat", "towerse.tower_layer_materials") self.connect("materials.name", "towerse.material_names") self.connect("materials.E", "towerse.E_mat") self.connect("materials.G", "towerse.G_mat") self.connect("materials.rho", "towerse.rho_mat") self.connect("materials.sigma_y", "towerse.sigma_y_mat") self.connect("materials.unit_cost", "towerse.unit_cost_mat") self.connect("costs.labor_rate", "towerse.labor_cost_rate") self.connect("costs.painting_rate", "towerse.painting_cost_rate") if modeling_options["flags"]["monopile"]: self.connect("env.water_depth", "towerse.water_depth") self.connect("env.rho_water", "towerse.rho_water") self.connect("env.mu_water", "towerse.mu_water") if modeling_options["WISDEM"]["TowerSE"]["soil_springs"]: self.connect("env.G_soil", "towerse.G_soil") self.connect("env.nu_soil", "towerse.nu_soil") self.connect("env.Hsig_wave", "towerse.Hsig_wave") self.connect("env.Tsig_wave", "towerse.Tsig_wave") self.connect("monopile.diameter", "towerse.monopile_outer_diameter_in") self.connect("monopile.foundation_height", "towerse.monopile_foundation_height") self.connect("monopile.height", "towerse.monopile_height") self.connect("monopile.s", "towerse.monopile_s") self.connect("monopile.layer_thickness", "towerse.monopile_layer_thickness") self.connect("monopile.layer_mat", "towerse.monopile_layer_materials") self.connect("monopile.outfitting_factor", "towerse.monopile_outfitting_factor") self.connect("monopile.transition_piece_cost", "towerse.transition_piece_cost") self.connect("monopile.transition_piece_mass", "towerse.transition_piece_mass") self.connect("monopile.gravity_foundation_mass", "towerse.gravity_foundation_mass") if modeling_options["flags"]["floating"]: self.connect("env.rho_water", "floatingse.rho_water") self.connect("env.water_depth", "floatingse.water_depth") self.connect("env.mu_water", "floatingse.mu_water") self.connect("env.Hsig_wave", "floatingse.Hsig_wave") self.connect("env.Tsig_wave", "floatingse.Tsig_wave") self.connect("env.rho_air", "floatingse.rho_air") self.connect("env.mu_air", "floatingse.mu_air") self.connect("env.shear_exp", "floatingse.shearExp") self.connect("assembly.hub_height", "floatingse.zref") if modeling_options["flags"]["blade"]: self.connect("rotorse.rp.gust.V_gust", "floatingse.Uref") self.connect("materials.name", "floatingse.material_names") self.connect("materials.E", "floatingse.E_mat") self.connect("materials.G", "floatingse.G_mat") self.connect("materials.rho", "floatingse.rho_mat") self.connect("materials.sigma_y", "floatingse.sigma_y_mat") self.connect("materials.unit_cost", "floatingse.unit_cost_mat") self.connect("costs.labor_rate", "floatingse.labor_cost_rate") self.connect("costs.painting_rate", "floatingse.painting_cost_rate") self.connect("tower.diameter", "floatingse.tower.outer_diameter_in") self.connect("tower_grid.s", "floatingse.tower.s") self.connect("tower.layer_thickness", "floatingse.tower.layer_thickness") self.connect("tower.outfitting_factor", "floatingse.tower.outfitting_factor_in") self.connect("tower.layer_mat", "floatingse.tower.layer_materials") self.connect("floating.transition_node", "floatingse.transition_node") if modeling_options["flags"]["tower"]: self.connect("tower_grid.height", "floatingse.tower_height") if modeling_options["flags"]["nacelle"]: self.connect("drivese.base_F", "floatingse.rna_F") self.connect("drivese.base_M", "floatingse.rna_M") self.connect("drivese.rna_I_TT", "floatingse.rna_I") self.connect("drivese.rna_cm", "floatingse.rna_cg") self.connect("drivese.rna_mass", "floatingse.rna_mass") # Individual member connections for k, kname in enumerate( modeling_options["floating"]["members"]["name"]): idx = modeling_options["floating"]["members"]["name2idx"][ kname] self.connect(f"floating.memgrp{idx}.outer_diameter", f"floatingse.member{k}.outer_diameter_in") self.connect(f"floating.memgrp{idx}.outfitting_factor", f"floatingse.member{k}.outfitting_factor_in") for var in [ "s", "layer_thickness", "layer_materials", "bulkhead_grid", "bulkhead_thickness", "ballast_grid", "ballast_volume", "ballast_materials", "grid_axial_joints", "ring_stiffener_web_height", "ring_stiffener_web_thickness", "ring_stiffener_flange_width", "ring_stiffener_flange_thickness", "ring_stiffener_spacing", "axial_stiffener_web_height", "axial_stiffener_web_thickness", "axial_stiffener_flange_width", "axial_stiffener_flange_thickness", "axial_stiffener_spacing", ]: self.connect(f"floating.memgrp{idx}.{var}", f"floatingse.member{k}.{var}") for var in ["joint1", "joint2", "s_ghost1", "s_ghost2"]: self.connect(f"floating.member_{kname}:{var}", f"floatingse.member{k}.{var}") # Mooring connections self.connect("mooring.unstretched_length", "floatingse.line_length", src_indices=[0]) for var in [ "fairlead", "fairlead_radius", "anchor_radius", "anchor_cost", "line_diameter", "line_mass_density_coeff", "line_stiffness_coeff", "line_breaking_load_coeff", "line_cost_rate_coeff", ]: self.connect("mooring." + var, "floatingse." + var, src_indices=[0]) # Connections to turbine constraints if modeling_options["flags"]["blade"] and modeling_options["flags"][ "tower"]: self.connect("configuration.rotor_orientation", "tcons.rotor_orientation") self.connect("rotorse.rs.tip_pos.tip_deflection", "tcons.tip_deflection") self.connect("assembly.rotor_radius", "tcons.Rtip") self.connect("assembly.blade_ref_axis", "tcons.ref_axis_blade") self.connect("hub.cone", "tcons.precone") self.connect("nacelle.uptilt", "tcons.tilt") self.connect("nacelle.overhang", "tcons.overhang") self.connect("assembly.tower_ref_axis", "tcons.ref_axis_tower") self.connect("tower.diameter", "tcons.d_full") if modeling_options["flags"]["floating"]: self.connect("floatingse.tower_freqs", "tcons.tower_freq", src_indices=[0]) else: self.connect("towerse.tower.structural_frequencies", "tcons.tower_freq", src_indices=[0]) self.connect("configuration.n_blades", "tcons.blade_number") self.connect("rotorse.rp.powercurve.rated_Omega", "tcons.rated_Omega") # Connections to turbine capital cost self.connect("configuration.n_blades", "tcc.blade_number") self.connect("configuration.rated_power", "tcc.machine_rating") if modeling_options["flags"]["blade"]: self.connect("rotorse.re.precomp.blade_mass", "tcc.blade_mass") self.connect("rotorse.re.precomp.total_blade_cost", "tcc.blade_cost_external") if modeling_options["flags"]["nacelle"]: self.connect("drivese.hub_mass", "tcc.hub_mass") self.connect("drivese.pitch_mass", "tcc.pitch_system_mass") self.connect("drivese.spinner_mass", "tcc.spinner_mass") self.connect("drivese.lss_mass", "tcc.lss_mass") self.connect("drivese.mean_bearing_mass", "tcc.main_bearing_mass") self.connect("drivese.gearbox_mass", "tcc.gearbox_mass") self.connect("drivese.hss_mass", "tcc.hss_mass") self.connect("drivese.brake_mass", "tcc.brake_mass") self.connect("drivese.generator_mass", "tcc.generator_mass") self.connect("drivese.total_bedplate_mass", "tcc.bedplate_mass") self.connect("drivese.yaw_mass", "tcc.yaw_mass") self.connect("drivese.converter_mass", "tcc.converter_mass") self.connect("drivese.transformer_mass", "tcc.transformer_mass") self.connect("drivese.hvac_mass", "tcc.hvac_mass") self.connect("drivese.cover_mass", "tcc.cover_mass") self.connect("drivese.platform_mass", "tcc.platforms_mass") if modeling_options["flags"]["generator"]: self.connect("drivese.generator_cost", "tcc.generator_cost_external") if modeling_options["flags"][ "tower"] and not modeling_options["flags"]["floating"]: self.connect("towerse.structural_mass", "tcc.tower_mass") self.connect("towerse.structural_cost", "tcc.tower_cost_external") elif modeling_options["flags"]["floating"]: self.connect("floatingse.tower_mass", "tcc.tower_mass") self.connect("floatingse.tower_cost", "tcc.tower_cost_external") self.connect("costs.blade_mass_cost_coeff", "tcc.blade_mass_cost_coeff") self.connect("costs.hub_mass_cost_coeff", "tcc.hub_mass_cost_coeff") self.connect("costs.pitch_system_mass_cost_coeff", "tcc.pitch_system_mass_cost_coeff") self.connect("costs.spinner_mass_cost_coeff", "tcc.spinner_mass_cost_coeff") self.connect("costs.lss_mass_cost_coeff", "tcc.lss_mass_cost_coeff") self.connect("costs.bearing_mass_cost_coeff", "tcc.bearing_mass_cost_coeff") self.connect("costs.gearbox_mass_cost_coeff", "tcc.gearbox_mass_cost_coeff") self.connect("costs.hss_mass_cost_coeff", "tcc.hss_mass_cost_coeff") self.connect("costs.generator_mass_cost_coeff", "tcc.generator_mass_cost_coeff") self.connect("costs.bedplate_mass_cost_coeff", "tcc.bedplate_mass_cost_coeff") self.connect("costs.yaw_mass_cost_coeff", "tcc.yaw_mass_cost_coeff") self.connect("costs.converter_mass_cost_coeff", "tcc.converter_mass_cost_coeff") self.connect("costs.transformer_mass_cost_coeff", "tcc.transformer_mass_cost_coeff") self.connect("costs.hvac_mass_cost_coeff", "tcc.hvac_mass_cost_coeff") self.connect("costs.cover_mass_cost_coeff", "tcc.cover_mass_cost_coeff") self.connect("costs.elec_connec_machine_rating_cost_coeff", "tcc.elec_connec_machine_rating_cost_coeff") self.connect("costs.platforms_mass_cost_coeff", "tcc.platforms_mass_cost_coeff") self.connect("costs.tower_mass_cost_coeff", "tcc.tower_mass_cost_coeff") self.connect("costs.controls_machine_rating_cost_coeff", "tcc.controls_machine_rating_cost_coeff") self.connect("costs.crane_cost", "tcc.crane_cost")
def setup(self): modeling_options = self.options["modeling_options"] opt_options = self.options["opt_options"] if modeling_options["flags"]["blade"] and modeling_options["flags"][ "nacelle"]: self.linear_solver = lbgs = om.LinearBlockGS() self.nonlinear_solver = nlbgs = om.NonlinearBlockGS() nlbgs.options["maxiter"] = 5 nlbgs.options["atol"] = 1e-2 nlbgs.options["rtol"] = 1e-8 nlbgs.options["iprint"] = 0 # Analysis components self.add_subsystem( "wt_init", WindTurbineOntologyOpenMDAO(modeling_options=modeling_options, opt_options=opt_options), promotes=["*"], ) if modeling_options["flags"]["blade"]: self.add_subsystem( "ccblade", CCBladeTwist(modeling_options=modeling_options, opt_options=opt_options) ) # Run standalong CCBlade and possibly determine optimal twist from user-defined margin to stall self.add_subsystem("wt_class", TurbineClass()) self.add_subsystem( "re", RotorElasticity(modeling_options=modeling_options, opt_options=opt_options)) self.add_subsystem( "rp", RotorPower(modeling_options=modeling_options)) # Aero analysis self.add_subsystem( "stall_check", NoStallConstraint(modeling_options=modeling_options)) self.add_subsystem( "rs", RotorStructure(modeling_options=modeling_options, opt_options=opt_options, freq_run=False)) if modeling_options["flags"]["nacelle"]: self.add_subsystem( "drivese", DrivetrainSE(modeling_options=modeling_options, n_dlcs=1)) if modeling_options["flags"]["tower"]: self.add_subsystem("towerse", TowerSE(modeling_options=modeling_options)) if modeling_options["flags"]["blade"] and modeling_options["flags"][ "tower"]: self.add_subsystem( "tcons", TurbineConstraints(modeling_options=modeling_options)) self.add_subsystem( "tcc", Turbine_CostsSE_2015( verbosity=modeling_options["General"]["verbosity"])) if modeling_options["flags"]["blade"]: n_span = modeling_options["RotorSE"]["n_span"] # Conncetions to ccblade self.connect("blade.pa.chord_param", "ccblade.chord") self.connect("blade.pa.twist_param", "ccblade.twist") self.connect("blade.opt_var.s_opt_chord", "ccblade.s_opt_chord") self.connect("blade.opt_var.s_opt_twist", "ccblade.s_opt_twist") self.connect("assembly.r_blade", "ccblade.r") self.connect("assembly.rotor_radius", "ccblade.Rtip") self.connect("hub.radius", "ccblade.Rhub") self.connect("blade.interp_airfoils.r_thick_interp", "ccblade.rthick") self.connect("airfoils.aoa", "ccblade.airfoils_aoa") self.connect("airfoils.Re", "ccblade.airfoils_Re") self.connect("blade.interp_airfoils.cl_interp", "ccblade.airfoils_cl") self.connect("blade.interp_airfoils.cd_interp", "ccblade.airfoils_cd") self.connect("blade.interp_airfoils.cm_interp", "ccblade.airfoils_cm") self.connect("assembly.hub_height", "ccblade.hub_height") self.connect("hub.cone", "ccblade.precone") self.connect("nacelle.uptilt", "ccblade.tilt") self.connect("assembly.blade_ref_axis", "ccblade.precurve", src_indices=[(i, 0) for i in np.arange(n_span)]) self.connect("assembly.blade_ref_axis", "ccblade.precurveTip", src_indices=[(-1, 0)]) self.connect("assembly.blade_ref_axis", "ccblade.presweep", src_indices=[(i, 1) for i in np.arange(n_span)]) self.connect("assembly.blade_ref_axis", "ccblade.presweepTip", src_indices=[(-1, 1)]) self.connect("configuration.n_blades", "ccblade.nBlades") if modeling_options["flags"]["control"]: self.connect("control.rated_pitch", "ccblade.pitch") self.connect("control.rated_TSR", "ccblade.tsr") self.connect("env.rho_air", "ccblade.rho") self.connect("env.mu_air", "ccblade.mu") self.connect("env.shear_exp", "ccblade.shearExp") # Connections to wind turbine class self.connect("configuration.ws_class", "wt_class.turbine_class") # Connections from blade aero parametrization to other modules self.connect("blade.pa.twist_param", ["re.theta", "rs.theta"]) # self.connect('blade.pa.twist_param', 'rs.tip_pos.theta_tip', src_indices=[-1]) self.connect("blade.pa.chord_param", "re.chord") self.connect("blade.pa.chord_param", ["rs.chord"]) if modeling_options["flags"]["blade"]: self.connect("blade.pa.twist_param", "rp.theta") self.connect("blade.pa.chord_param", "rp.chord") self.connect("configuration.n_blades", "rs.constr.blade_number") # Connections from blade struct parametrization to rotor elasticity self.connect("blade.ps.layer_thickness_param", "re.precomp.layer_thickness") # Connections to rotor elastic and frequency analysis self.connect("nacelle.uptilt", "re.precomp.uptilt") self.connect("configuration.n_blades", "re.precomp.n_blades") self.connect("assembly.r_blade", "re.r") self.connect("blade.outer_shape_bem.pitch_axis", "re.precomp.pitch_axis") self.connect("blade.interp_airfoils.coord_xy_interp", "re.precomp.coord_xy_interp") self.connect("blade.internal_structure_2d_fem.layer_start_nd", "re.precomp.layer_start_nd") self.connect("blade.internal_structure_2d_fem.layer_end_nd", "re.precomp.layer_end_nd") self.connect("blade.internal_structure_2d_fem.layer_web", "re.precomp.layer_web") self.connect("blade.internal_structure_2d_fem.definition_layer", "re.precomp.definition_layer") self.connect("blade.internal_structure_2d_fem.web_start_nd", "re.precomp.web_start_nd") self.connect("blade.internal_structure_2d_fem.web_end_nd", "re.precomp.web_end_nd") self.connect("materials.name", "re.precomp.mat_name") self.connect("materials.orth", "re.precomp.orth") self.connect("materials.E", "re.precomp.E") self.connect("materials.G", "re.precomp.G") self.connect("materials.nu", "re.precomp.nu") self.connect("materials.rho", "re.precomp.rho") self.connect("materials.component_id", "re.precomp.component_id") self.connect("materials.unit_cost", "re.precomp.unit_cost") self.connect("materials.waste", "re.precomp.waste") self.connect("materials.rho_fiber", "re.precomp.rho_fiber") self.connect("materials.rho_area_dry", "re.precomp.rho_area_dry") self.connect("materials.ply_t", "re.precomp.ply_t") self.connect("materials.fvf", "re.precomp.fvf") self.connect("materials.fwf", "re.precomp.fwf") self.connect("materials.roll_mass", "re.precomp.roll_mass") # Conncetions to rail transport module if opt_options["constraints"]["blade"]["rail_transport"]["flag"]: self.connect("blade.outer_shape_bem.pitch_axis", "re.rail.pitch_axis") self.connect("assembly.blade_ref_axis", "re.rail.blade_ref_axis") self.connect("blade.interp_airfoils.coord_xy_dim", "re.rail.coord_xy_dim") self.connect("blade.interp_airfoils.coord_xy_interp", "re.rail.coord_xy_interp") # Connections from blade struct parametrization to rotor load anlysis self.connect("blade.ps.s_opt_spar_cap_ss", "rs.constr.s_opt_spar_cap_ss") self.connect("blade.ps.s_opt_spar_cap_ps", "rs.constr.s_opt_spar_cap_ps") # Connection from ra to rs for the rated conditions # self.connect('rp.powercurve.rated_V', 'rs.aero_rated.V_load') self.connect("rp.powercurve.rated_V", "rp.gust.V_hub") self.connect("rp.gust.V_gust", ["rs.aero_gust.V_load", "rs.aero_hub_loads.V_load"]) self.connect("env.shear_exp", ["rp.powercurve.shearExp", "rs.aero_gust.shearExp"]) self.connect( "rp.powercurve.rated_Omega", [ "rs.Omega_load", "rs.tot_loads_gust.aeroloads_Omega", "rs.constr.rated_Omega" ], ) self.connect( "rp.powercurve.rated_pitch", ["rs.pitch_load", "rs.tot_loads_gust.aeroloads_pitch"]) # Connections to RotorPower self.connect("control.V_in", "rp.v_min") self.connect("control.V_out", "rp.v_max") self.connect("configuration.rated_power", "rp.rated_power") self.connect("control.minOmega", "rp.omega_min") self.connect("control.maxOmega", "rp.omega_max") self.connect("control.max_TS", "rp.control_maxTS") self.connect("control.rated_TSR", "rp.tsr_operational") self.connect("control.rated_pitch", "rp.control_pitch") self.connect("configuration.gearbox_type", "rp.drivetrainType") self.connect("nacelle.gearbox_efficiency", "rp.powercurve.gearbox_efficiency") if modeling_options["flags"]["nacelle"]: self.connect("drivese.lss_rpm", "rp.powercurve.lss_rpm") self.connect("drivese.generator_efficiency", "rp.powercurve.generator_efficiency") self.connect("assembly.r_blade", "rp.r") # self.connect('blade.pa.chord_param', 'rp.chord') # self.connect('blade.pa.twist_param', 'rp.theta') self.connect("hub.radius", "rp.Rhub") self.connect("assembly.rotor_radius", "rp.Rtip") self.connect("assembly.hub_height", "rp.hub_height") self.connect("hub.cone", "rp.precone") self.connect("nacelle.uptilt", "rp.tilt") self.connect("assembly.blade_ref_axis", "rp.precurve", src_indices=[(i, 0) for i in np.arange(n_span)]) self.connect("assembly.blade_ref_axis", "rp.precurveTip", src_indices=[(-1, 0)]) self.connect("assembly.blade_ref_axis", "rp.presweep", src_indices=[(i, 1) for i in np.arange(n_span)]) self.connect("assembly.blade_ref_axis", "rp.presweepTip", src_indices=[(-1, 1)]) self.connect("airfoils.aoa", "rp.airfoils_aoa") self.connect("airfoils.Re", "rp.airfoils_Re") self.connect("blade.interp_airfoils.cl_interp", "rp.airfoils_cl") self.connect("blade.interp_airfoils.cd_interp", "rp.airfoils_cd") self.connect("blade.interp_airfoils.cm_interp", "rp.airfoils_cm") self.connect("configuration.n_blades", "rp.nBlades") self.connect("env.rho_air", "rp.rho") self.connect("env.mu_air", "rp.mu") self.connect("wt_class.V_mean", "rp.cdf.xbar") self.connect("env.weibull_k", "rp.cdf.k") # Connections to rotorse-rs-gustetm self.connect("wt_class.V_mean", "rp.gust.V_mean") self.connect("configuration.turb_class", "rp.gust.turbulence_class") # Connections to the stall check self.connect("blade.outer_shape_bem.s", "stall_check.s") self.connect("airfoils.aoa", "stall_check.airfoils_aoa") self.connect("blade.interp_airfoils.cl_interp", "stall_check.airfoils_cl") self.connect("blade.interp_airfoils.cd_interp", "stall_check.airfoils_cd") self.connect("blade.interp_airfoils.cm_interp", "stall_check.airfoils_cm") if modeling_options["flags"]["blade"]: self.connect("rp.powercurve.aoa_regII", "stall_check.aoa_along_span") else: self.connect("ccblade.alpha", "stall_check.aoa_along_span") # Connections to rotor load analysis self.connect("blade.interp_airfoils.cl_interp", "rs.airfoils_cl") self.connect("blade.interp_airfoils.cd_interp", "rs.airfoils_cd") self.connect("blade.interp_airfoils.cm_interp", "rs.airfoils_cm") self.connect("airfoils.aoa", "rs.airfoils_aoa") self.connect("airfoils.Re", "rs.airfoils_Re") self.connect("assembly.rotor_radius", "rs.Rtip") self.connect("hub.radius", "rs.Rhub") self.connect("env.rho_air", "rs.rho") self.connect("env.mu_air", "rs.mu") self.connect("env.shear_exp", "rs.aero_hub_loads.shearExp") self.connect("assembly.hub_height", "rs.hub_height") self.connect("configuration.n_blades", "rs.nBlades") self.connect("assembly.r_blade", "rs.r") self.connect("hub.cone", "rs.precone") self.connect("nacelle.uptilt", "rs.tilt") self.connect("re.A", "rs.A") self.connect("re.EA", "rs.EA") self.connect("re.EIxx", "rs.EIxx") self.connect("re.EIyy", "rs.EIyy") self.connect("re.EIxy", "rs.EIxy") self.connect("re.GJ", "rs.GJ") self.connect("re.rhoA", "rs.rhoA") self.connect("re.rhoJ", "rs.rhoJ") self.connect("re.x_ec", "rs.x_ec") self.connect("re.y_ec", "rs.y_ec") self.connect("re.precomp.xu_strain_spar", "rs.xu_strain_spar") self.connect("re.precomp.xl_strain_spar", "rs.xl_strain_spar") self.connect("re.precomp.yu_strain_spar", "rs.yu_strain_spar") self.connect("re.precomp.yl_strain_spar", "rs.yl_strain_spar") self.connect("re.precomp.xu_strain_te", "rs.xu_strain_te") self.connect("re.precomp.xl_strain_te", "rs.xl_strain_te") self.connect("re.precomp.yu_strain_te", "rs.yu_strain_te") self.connect("re.precomp.yl_strain_te", "rs.yl_strain_te") self.connect("blade.outer_shape_bem.s", "rs.constr.s") # Connections to rotorse-rc # self.connect('blade.length', 'rotorse.rc.blade_length') # self.connect('blade.outer_shape_bem.s', 'rotorse.rc.s') # self.connect('blade.outer_shape_bem.pitch_axis', 'rotorse.rc.pitch_axis') # self.connect('blade.interp_airfoils.coord_xy_interp', 'rotorse.rc.coord_xy_interp') # self.connect('blade.internal_structure_2d_fem.layer_start_nd', 'rotorse.rc.layer_start_nd') # self.connect('blade.internal_structure_2d_fem.layer_end_nd', 'rotorse.rc.layer_end_nd') # self.connect('blade.internal_structure_2d_fem.layer_web', 'rotorse.rc.layer_web') # self.connect('blade.internal_structure_2d_fem.web_start_nd', 'rotorse.rc.web_start_nd') # self.connect('blade.internal_structure_2d_fem.web_end_nd', 'rotorse.rc.web_end_nd') # self.connect('materials.name', 'rotorse.rc.mat_name') # self.connect('materials.rho', 'rotorse.rc.rho') # Connections to DriveSE if modeling_options["flags"]["nacelle"]: self.connect("hub.diameter", "drivese.hub_diameter") self.connect("hub.hub_in2out_circ", "drivese.hub_in2out_circ") self.connect("hub.flange_t2shell_t", "drivese.flange_t2shell_t") self.connect("hub.flange_OD2hub_D", "drivese.flange_OD2hub_D") self.connect("hub.flange_ID2flange_OD", "drivese.flange_ID2flange_OD") self.connect("hub.hub_stress_concentration", "drivese.hub_stress_concentration") self.connect("hub.n_front_brackets", "drivese.n_front_brackets") self.connect("hub.n_rear_brackets", "drivese.n_rear_brackets") self.connect("hub.clearance_hub_spinner", "drivese.clearance_hub_spinner") self.connect("hub.spin_hole_incr", "drivese.spin_hole_incr") self.connect("hub.pitch_system_scaling_factor", "drivese.pitch_system_scaling_factor") self.connect("hub.spinner_gust_ws", "drivese.spinner_gust_ws") self.connect("configuration.n_blades", "drivese.n_blades") self.connect("assembly.rotor_diameter", "drivese.rotor_diameter") self.connect("configuration.upwind", "drivese.upwind") self.connect("control.minOmega", "drivese.minimum_rpm") self.connect("rp.powercurve.rated_Omega", "drivese.rated_rpm") self.connect("rp.powercurve.rated_Q", "drivese.rated_torque") self.connect("configuration.rated_power", "drivese.machine_rating") if modeling_options["flags"]["tower"]: self.connect("tower.diameter", "drivese.D_top", src_indices=[-1]) self.connect("rs.aero_hub_loads.Fxyz_hub_aero", "drivese.F_hub") self.connect("rs.aero_hub_loads.Mxyz_hub_aero", "drivese.M_hub") self.connect("rs.frame.root_M", "drivese.pitch_system.BRFM", src_indices=[1]) self.connect("blade.pa.chord_param", "drivese.blade_root_diameter", src_indices=[0]) self.connect("re.precomp.blade_mass", "drivese.blade_mass") self.connect("re.precomp.mass_all_blades", "drivese.blades_mass") self.connect("re.precomp.I_all_blades", "drivese.blades_I") self.connect("nacelle.distance_hub2mb", "drivese.L_h1") self.connect("nacelle.distance_mb2mb", "drivese.L_12") self.connect("nacelle.L_generator", "drivese.L_generator") self.connect("nacelle.overhang", "drivese.overhang") self.connect("nacelle.distance_tt_hub", "drivese.drive_height") self.connect("nacelle.uptilt", "drivese.tilt") self.connect("nacelle.gear_ratio", "drivese.gear_ratio") self.connect("nacelle.mb1Type", "drivese.bear1.bearing_type") self.connect("nacelle.mb2Type", "drivese.bear2.bearing_type") self.connect("nacelle.lss_diameter", "drivese.lss_diameter") self.connect("nacelle.lss_wall_thickness", "drivese.lss_wall_thickness") if modeling_options["DriveSE"]["direct"]: self.connect("nacelle.nose_diameter", "drivese.bear1.D_shaft", src_indices=[0]) self.connect("nacelle.nose_diameter", "drivese.bear2.D_shaft", src_indices=[-1]) else: self.connect("nacelle.lss_diameter", "drivese.bear1.D_shaft", src_indices=[0]) self.connect("nacelle.lss_diameter", "drivese.bear2.D_shaft", src_indices=[-1]) self.connect("nacelle.uptower", "drivese.uptower") self.connect("nacelle.brake_mass_user", "drivese.brake_mass_user") self.connect("nacelle.hvac_mass_coeff", "drivese.hvac_mass_coeff") self.connect("nacelle.converter_mass_user", "drivese.converter_mass_user") self.connect("nacelle.transformer_mass_user", "drivese.transformer_mass_user") if modeling_options["DriveSE"]["direct"]: self.connect("nacelle.nose_diameter", "drivese.nose_diameter") # only used in direct self.connect( "nacelle.nose_wall_thickness", "drivese.nose_wall_thickness") # only used in direct self.connect( "nacelle.bedplate_wall_thickness", "drivese.bedplate_wall_thickness") # only used in direct else: self.connect("nacelle.hss_length", "drivese.L_hss") # only used in geared self.connect("nacelle.hss_diameter", "drivese.hss_diameter") # only used in geared self.connect( "nacelle.hss_wall_thickness", "drivese.hss_wall_thickness") # only used in geared self.connect("nacelle.hss_material", "drivese.hss_material") self.connect("nacelle.planet_numbers", "drivese.planet_numbers") # only used in geared self.connect( "nacelle.gear_configuration", "drivese.gear_configuration") # only used in geared self.connect( "nacelle.bedplate_flange_width", "drivese.bedplate_flange_width") # only used in geared self.connect( "nacelle.bedplate_flange_thickness", "drivese.bedplate_flange_thickness") # only used in geared self.connect( "nacelle.bedplate_web_thickness", "drivese.bedplate_web_thickness") # only used in geared self.connect("hub.hub_material", "drivese.hub_material") self.connect("hub.spinner_material", "drivese.spinner_material") self.connect("nacelle.lss_material", "drivese.lss_material") self.connect("nacelle.bedplate_material", "drivese.bedplate_material") self.connect("materials.name", "drivese.material_names") self.connect("materials.E", "drivese.E_mat") self.connect("materials.G", "drivese.G_mat") self.connect("materials.rho", "drivese.rho_mat") self.connect("materials.sigma_y", "drivese.sigma_y_mat") self.connect("materials.Xt", "drivese.Xt_mat") self.connect("materials.unit_cost", "drivese.unit_cost_mat") if modeling_options["flags"]["generator"]: self.connect("generator.B_r", "drivese.generator.B_r") self.connect("generator.P_Fe0e", "drivese.generator.P_Fe0e") self.connect("generator.P_Fe0h", "drivese.generator.P_Fe0h") self.connect("generator.S_N", "drivese.generator.S_N") self.connect("generator.alpha_p", "drivese.generator.alpha_p") self.connect("generator.b_r_tau_r", "drivese.generator.b_r_tau_r") self.connect("generator.b_ro", "drivese.generator.b_ro") self.connect("generator.b_s_tau_s", "drivese.generator.b_s_tau_s") self.connect("generator.b_so", "drivese.generator.b_so") self.connect("generator.cofi", "drivese.generator.cofi") self.connect("generator.freq", "drivese.generator.freq") self.connect("generator.h_i", "drivese.generator.h_i") self.connect("generator.h_sy0", "drivese.generator.h_sy0") self.connect("generator.h_w", "drivese.generator.h_w") self.connect("generator.k_fes", "drivese.generator.k_fes") self.connect("generator.k_fillr", "drivese.generator.k_fillr") self.connect("generator.k_fills", "drivese.generator.k_fills") self.connect("generator.k_s", "drivese.generator.k_s") self.connect("generator.m", "drivese.generator.m") self.connect("generator.mu_0", "drivese.generator.mu_0") self.connect("generator.mu_r", "drivese.generator.mu_r") self.connect("generator.p", "drivese.generator.p") self.connect("generator.phi", "drivese.generator.phi") self.connect("generator.q1", "drivese.generator.q1") self.connect("generator.q2", "drivese.generator.q2") self.connect("generator.ratio_mw2pp", "drivese.generator.ratio_mw2pp") self.connect("generator.resist_Cu", "drivese.generator.resist_Cu") self.connect("generator.sigma", "drivese.generator.sigma") self.connect("generator.y_tau_p", "drivese.generator.y_tau_p") self.connect("generator.y_tau_pr", "drivese.generator.y_tau_pr") self.connect("generator.I_0", "drivese.generator.I_0") self.connect("generator.d_r", "drivese.generator.d_r") self.connect("generator.h_m", "drivese.generator.h_m") self.connect("generator.h_0", "drivese.generator.h_0") self.connect("generator.h_s", "drivese.generator.h_s") self.connect("generator.len_s", "drivese.generator.len_s") self.connect("generator.n_r", "drivese.generator.n_r") self.connect("generator.rad_ag", "drivese.generator.rad_ag") self.connect("generator.t_wr", "drivese.generator.t_wr") self.connect("generator.n_s", "drivese.generator.n_s") self.connect("generator.b_st", "drivese.generator.b_st") self.connect("generator.d_s", "drivese.generator.d_s") self.connect("generator.t_ws", "drivese.generator.t_ws") self.connect("generator.rho_Copper", "drivese.generator.rho_Copper") self.connect("generator.rho_Fe", "drivese.generator.rho_Fe") self.connect("generator.rho_Fes", "drivese.generator.rho_Fes") self.connect("generator.rho_PM", "drivese.generator.rho_PM") self.connect("generator.C_Cu", "drivese.generator.C_Cu") self.connect("generator.C_Fe", "drivese.generator.C_Fe") self.connect("generator.C_Fes", "drivese.generator.C_Fes") self.connect("generator.C_PM", "drivese.generator.C_PM") if modeling_options["GeneratorSE"]["type"] in ["pmsg_outer"]: self.connect("generator.N_c", "drivese.generator.N_c") self.connect("generator.b", "drivese.generator.b") self.connect("generator.c", "drivese.generator.c") self.connect("generator.E_p", "drivese.generator.E_p") self.connect("generator.h_yr", "drivese.generator.h_yr") self.connect("generator.h_ys", "drivese.generator.h_ys") self.connect("generator.h_sr", "drivese.generator.h_sr") self.connect("generator.h_ss", "drivese.generator.h_ss") self.connect("generator.t_r", "drivese.generator.t_r") self.connect("generator.t_s", "drivese.generator.t_s") self.connect("generator.u_allow_pcent", "drivese.generator.u_allow_pcent") self.connect("generator.y_allow_pcent", "drivese.generator.y_allow_pcent") self.connect("generator.z_allow_deg", "drivese.generator.z_allow_deg") self.connect("generator.B_tmax", "drivese.generator.B_tmax") self.connect("rp.powercurve.rated_mech", "drivese.generator.P_mech") if modeling_options["GeneratorSE"]["type"] in [ "eesg", "pmsg_arms", "pmsg_disc" ]: self.connect("generator.tau_p", "drivese.generator.tau_p") self.connect("generator.h_ys", "drivese.generator.h_ys") self.connect("generator.h_yr", "drivese.generator.h_yr") self.connect("generator.b_arm", "drivese.generator.b_arm") elif modeling_options["GeneratorSE"]["type"] in [ "scig", "dfig" ]: self.connect("generator.B_symax", "drivese.generator.B_symax") self.connect("generator.S_Nmax", "drivese.generator.S_Nmax") if modeling_options["DriveSE"]["direct"]: self.connect("nacelle.nose_diameter", "drivese.generator.D_nose", src_indices=[-1]) self.connect("nacelle.lss_diameter", "drivese.generator.D_shaft", src_indices=[0]) else: self.connect("nacelle.hss_diameter", "drivese.generator.D_shaft", src_indices=[-1]) else: self.connect("generator.generator_mass_user", "drivese.generator_mass_user") self.connect("generator.generator_efficiency_user", "drivese.generator_efficiency_user") # Connections to TowerSE if modeling_options["flags"]["tower"]: if modeling_options["flags"]["nacelle"]: self.connect("drivese.base_F", "towerse.pre.rna_F") self.connect("drivese.base_M", "towerse.pre.rna_M") self.connect("drivese.rna_I_TT", "towerse.rna_I") self.connect("drivese.rna_cm", "towerse.rna_cg") self.connect("drivese.rna_mass", "towerse.rna_mass") if modeling_options["flags"]["blade"]: self.connect("rp.gust.V_gust", "towerse.wind.Uref") self.connect("assembly.hub_height", "towerse.wind_reference_height") # TODO- environment self.connect("env.rho_air", "towerse.rho_air") self.connect("env.mu_air", "towerse.mu_air") self.connect("env.shear_exp", "towerse.shearExp") self.connect("assembly.hub_height", "towerse.hub_height") self.connect( "tower_grid.foundation_height", "towerse.tower_foundation_height") # TODO: towerse.wind_z0" self.connect("tower.diameter", "towerse.tower_outer_diameter_in") self.connect("tower_grid.height", "towerse.tower_height") self.connect("tower_grid.s", "towerse.tower_s") self.connect("tower.layer_thickness", "towerse.tower_layer_thickness") self.connect("tower.outfitting_factor", "towerse.tower_outfitting_factor") self.connect("tower.layer_mat", "towerse.tower_layer_materials") self.connect("materials.name", "towerse.material_names") self.connect("materials.E", "towerse.E_mat") self.connect("materials.G", "towerse.G_mat") self.connect("materials.rho", "towerse.rho_mat") self.connect("materials.sigma_y", "towerse.sigma_y_mat") self.connect("materials.unit_cost", "towerse.unit_cost_mat") self.connect("costs.labor_rate", "towerse.labor_cost_rate") self.connect("costs.painting_rate", "towerse.painting_cost_rate") if modeling_options["flags"]["monopile"]: self.connect("env.water_depth", "towerse.water_depth") self.connect("env.rho_water", "towerse.rho_water") self.connect("env.mu_water", "towerse.mu_water") self.connect("env.G_soil", "towerse.G_soil") self.connect("env.nu_soil", "towerse.nu_soil") self.connect("env.Hsig_wave", "towerse.Hsig_wave") self.connect("env.Tsig_wave", "towerse.Tsig_wave") self.connect("monopile.diameter", "towerse.monopile_outer_diameter_in") self.connect("monopile.foundation_height", "towerse.monopile_foundation_height") self.connect("monopile.height", "towerse.monopile_height") self.connect("monopile.s", "towerse.monopile_s") self.connect("monopile.layer_thickness", "towerse.monopile_layer_thickness") self.connect("monopile.layer_mat", "towerse.monopile_layer_materials") self.connect("monopile.outfitting_factor", "towerse.monopile_outfitting_factor") self.connect("monopile.transition_piece_cost", "towerse.transition_piece_cost") self.connect("monopile.transition_piece_mass", "towerse.transition_piece_mass") self.connect("monopile.gravity_foundation_mass", "towerse.gravity_foundation_mass") # Connections to turbine constraints if modeling_options["flags"]["blade"] and modeling_options["flags"][ "tower"]: self.connect("configuration.rotor_orientation", "tcons.rotor_orientation") self.connect("rs.tip_pos.tip_deflection", "tcons.tip_deflection") self.connect("assembly.rotor_radius", "tcons.Rtip") self.connect("assembly.blade_ref_axis", "tcons.ref_axis_blade") self.connect("hub.cone", "tcons.precone") self.connect("nacelle.uptilt", "tcons.tilt") self.connect("nacelle.overhang", "tcons.overhang") self.connect("assembly.tower_ref_axis", "tcons.ref_axis_tower") self.connect("tower.diameter", "tcons.d_full") self.connect("towerse.tower.freqs", "tcons.tower_freq", src_indices=[0]) self.connect("configuration.n_blades", "tcons.blade_number") self.connect("rp.powercurve.rated_Omega", "tcons.rated_Omega") # Connections to turbine capital cost self.connect("configuration.n_blades", "tcc.blade_number") self.connect("configuration.rated_power", "tcc.machine_rating") if modeling_options["flags"]["blade"]: self.connect("re.precomp.blade_mass", "tcc.blade_mass") self.connect("re.precomp.total_blade_cost", "tcc.blade_cost_external") if modeling_options["flags"]["nacelle"]: self.connect("drivese.hub_mass", "tcc.hub_mass") self.connect("drivese.pitch_mass", "tcc.pitch_system_mass") self.connect("drivese.spinner_mass", "tcc.spinner_mass") self.connect("drivese.lss_mass", "tcc.lss_mass") self.connect("drivese.mean_bearing_mass", "tcc.main_bearing_mass") self.connect("drivese.gearbox_mass", "tcc.gearbox_mass") self.connect("drivese.hss_mass", "tcc.hss_mass") self.connect("drivese.brake_mass", "tcc.brake_mass") self.connect("drivese.generator_mass", "tcc.generator_mass") self.connect("drivese.total_bedplate_mass", "tcc.bedplate_mass") self.connect("drivese.yaw_mass", "tcc.yaw_mass") self.connect("drivese.converter_mass", "tcc.converter_mass") self.connect("drivese.transformer_mass", "tcc.transformer_mass") self.connect("drivese.hvac_mass", "tcc.hvac_mass") self.connect("drivese.cover_mass", "tcc.cover_mass") self.connect("drivese.platform_mass", "tcc.platforms_mass") if modeling_options["flags"]["generator"]: self.connect("drivese.generator_cost", "tcc.generator_cost_external") if modeling_options["flags"]["tower"]: self.connect("towerse.structural_mass", "tcc.tower_mass") self.connect("towerse.structural_cost", "tcc.tower_cost_external") self.connect("costs.blade_mass_cost_coeff", "tcc.blade_mass_cost_coeff") self.connect("costs.hub_mass_cost_coeff", "tcc.hub_mass_cost_coeff") self.connect("costs.pitch_system_mass_cost_coeff", "tcc.pitch_system_mass_cost_coeff") self.connect("costs.spinner_mass_cost_coeff", "tcc.spinner_mass_cost_coeff") self.connect("costs.lss_mass_cost_coeff", "tcc.lss_mass_cost_coeff") self.connect("costs.bearing_mass_cost_coeff", "tcc.bearing_mass_cost_coeff") self.connect("costs.gearbox_mass_cost_coeff", "tcc.gearbox_mass_cost_coeff") self.connect("costs.hss_mass_cost_coeff", "tcc.hss_mass_cost_coeff") self.connect("costs.generator_mass_cost_coeff", "tcc.generator_mass_cost_coeff") self.connect("costs.bedplate_mass_cost_coeff", "tcc.bedplate_mass_cost_coeff") self.connect("costs.yaw_mass_cost_coeff", "tcc.yaw_mass_cost_coeff") self.connect("costs.converter_mass_cost_coeff", "tcc.converter_mass_cost_coeff") self.connect("costs.transformer_mass_cost_coeff", "tcc.transformer_mass_cost_coeff") self.connect("costs.hvac_mass_cost_coeff", "tcc.hvac_mass_cost_coeff") self.connect("costs.cover_mass_cost_coeff", "tcc.cover_mass_cost_coeff") self.connect("costs.elec_connec_machine_rating_cost_coeff", "tcc.elec_connec_machine_rating_cost_coeff") self.connect("costs.platforms_mass_cost_coeff", "tcc.platforms_mass_cost_coeff") self.connect("costs.tower_mass_cost_coeff", "tcc.tower_mass_cost_coeff") self.connect("costs.controls_machine_rating_cost_coeff", "tcc.controls_machine_rating_cost_coeff") self.connect("costs.crane_cost", "tcc.crane_cost")
import openmdao.api as om from openmdao.test_suite.components.double_sellar import DoubleSellar prob = om.Problem() model = prob.model = DoubleSellar() # each SubSellar group converges itself g1 = model.g1 g1.nonlinear_solver = om.NewtonSolver() g1.linear_solver = om.DirectSolver() # used for derivatives g2 = model.g2 g2.nonlinear_solver = om.NewtonSolver() g2.linear_solver = om.DirectSolver() # Converge the outer loop with Gauss Seidel, with a looser tolerance. model.nonlinear_solver = om.NonlinearBlockGS(rtol=1.0e-5) model.linear_solver = om.ScipyKrylov() model.linear_solver.precon = om.LinearBlockGS() prob.setup() prob.run_model()