示例#1
0
    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')
示例#3
0
    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)
示例#5
0
    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
示例#6
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)
示例#8
0
    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)
示例#10
0
    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()
示例#11
0
    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)
示例#12
0
    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)
示例#13
0
    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)
示例#15
0
    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)
示例#16
0
    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)
示例#17
0
    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)
示例#19
0
    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)
示例#21
0
    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
示例#22
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
示例#23
0
    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)
示例#24
0
    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)
示例#25
0
    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)
示例#26
0
    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")
示例#27
0
    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")
示例#28
0
    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")
示例#29
0
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()