Example #1
0
    def setUp(self):
        self.myfloat = Problem()
        self.myfloat.model = FloatingSE()
        self.myfloat.setup()

        # Remove all offset columns
        self.myfloat['number_of_offset_columns'] = 0
        self.myfloat['cross_attachment_pontoons_int'] = 0
        self.myfloat['lower_attachment_pontoons_int'] = 0
        self.myfloat['upper_attachment_pontoons_int'] = 0
        self.myfloat['lower_ring_pontoons_int'] = 0
        self.myfloat['upper_ring_pontoons_int'] = 0
        self.myfloat['outer_cross_pontoons_int'] = 0

        # Wind and water properties
        self.myfloat['air_density'] = 1.226  # Density of air [kg/m^3]
        self.myfloat['air_viscosity'] = 1.78e-5  # Viscosity of air [kg/m/s]
        self.myfloat['water_density'] = 1025.0  # Density of water [kg/m^3]
        self.myfloat[
            'water_viscosity'] = 1.08e-3  # Viscosity of water [kg/m/s]
        self.myfloat['shearExp'] = 0.11  # Shear exponent in wind power law
        self.myfloat['cm'] = 2.0  # Added mass coefficient
        self.myfloat['Uc'] = 0.0  # Mean current speed
        self.myfloat['wind_z0'] = 0.0  # Water line
        self.myfloat['yaw'] = 0.0  # Turbine yaw angle
        self.myfloat['beta'] = 0.0  # Wind beta angle
        self.myfloat['cd_usr'] = -1.0  # Compute drag coefficient

        # Material properties
        self.myfloat['material_density'] = self.myfloat[
            'main.material_density'] = self.myfloat[
                'off.material_density'] = 7850.0  # Steel [kg/m^3]
        self.myfloat['E'] = 200e9  # Young's modulus [N/m^2]
        self.myfloat['G'] = 79.3e9  # Shear modulus [N/m^2]
        self.myfloat['yield_stress'] = 3.45e8  # Elastic yield stress [N/m^2]
        self.myfloat['nu'] = 0.26  # Poisson's ratio
        self.myfloat['permanent_ballast_density'] = 5000.0  # [kg/m^3]

        # Mass and cost scaling factors
        self.myfloat[
            'bulkhead_mass_factor'] = 1.0  # Scaling for unaccounted bulkhead mass
        self.myfloat[
            'ring_mass_factor'] = 1.0  # Scaling for unaccounted stiffener mass
        self.myfloat[
            'shell_mass_factor'] = 1.0  # Scaling for unaccounted shell mass
        self.myfloat[
            'column_mass_factor'] = 1.0  # Scaling for unaccounted column mass
        self.myfloat[
            'outfitting_mass_fraction'] = 0.0  # Fraction of additional outfitting mass for each column
        self.myfloat[
            'ballast_cost_rate'] = 0.1  # Cost factor for ballast mass [$/kg]
        self.myfloat[
            'material_cost_rate'] = 1.1  # Cost factor for column mass [$/kg]
        self.myfloat[
            'labor_cost_rate'] = 1.0  # Cost factor for labor time [$/min]
        self.myfloat[
            'painting_cost_rate'] = 14.4  # Cost factor for column surface finishing [$/m^2]
        self.myfloat[
            'outfitting_cost_rate'] = 1.5 * 1.1  # Cost factor for outfitting mass [$/kg]
        self.myfloat[
            'mooring_cost_factor'] = 1.1  # Cost factor for mooring mass [$/kg]

        # Safety factors
        self.myfloat['gamma_f'] = 1.0  # Safety factor on loads
        self.myfloat['gamma_b'] = 1.0  # Safety factor on buckling
        self.myfloat['gamma_m'] = 1.0  # Safety factor on materials
        self.myfloat[
            'gamma_n'] = 1.0  # Safety factor on consequence of failure
        self.myfloat['gamma_fatigue'] = 1.0  # Not used

        # Properties of rotor-nacelle-assembly (RNA)
        self.myfloat['rna_mass'] = 350e3  # Mass [kg]
        self.myfloat['rna_I'] = 1e5 * np.array([1.0, 1.0, 1.0, 0.0, 0.0, 0.0])
        self.myfloat['rna_cg'] = np.zeros(3)
        self.myfloat['rna_force'] = np.zeros(3)
        self.myfloat['rna_moment'] = np.zeros(3)

        # Mooring constraints
        self.myfloat['max_offset'] = 0.1 * self.myfloat[
            'water_depth']  # Max surge/sway offset [m]
        self.myfloat[
            'max_survival_heel'] = 10.0  # Max heel (pitching) angle [deg]
        self.myfloat[
            'operational_heel'] = 5.0  # Max heel (pitching) angle [deg]

        # Design constraints
        self.myfloat[
            'max_draft'] = 200.0  # For manufacturability of rolling steel
        self.myfloat[
            'max_taper_ratio'] = 0.4  # For manufacturability of rolling steel
        self.myfloat[
            'min_diameter_thickness_ratio'] = 120.0  # For weld-ability

        # API 2U flag
        self.myfloat['loading'] = 'axial'  #'hydrostatic'

        # Porperties of turbine tower
        self.myfloat[
            'hub_height'] = 77.6  # Length from tower main to top (not including freeboard) [m]
        self.myfloat['tower_section_height'] = 77.6 / nSecTow * np.ones(
            nSecTow)  # Length of each tower section [m]
        self.myfloat['tower_outer_diameter'] = np.linspace(
            6.5, 3.87, nSecTow + 1
        )  # Diameter at each tower section node (linear lofting between) [m]
        self.myfloat['tower_wall_thickness'] = np.linspace(
            0.027, 0.019, nSecTow
        )  # Diameter at each tower section node (linear lofting between) [m]
        self.myfloat[
            'tower_buckling_length'] = 30.0  # Tower buckling reinforcement spacing [m]
        self.myfloat[
            'tower_outfitting_factor'] = 1.07  # Scaling for unaccounted tower mass in outfitting
Example #2
0
    def test_betz(self):
        from openmdao.api import Problem, ScipyOptimizer, IndepVarComp, ExplicitComponent

        class ActuatorDisc(ExplicitComponent):
            """Simple wind turbine model based on actuator disc theory"""
            def setup(self):

                # Inputs
                self.add_input('a', 0.5, desc="Induced Velocity Factor")
                self.add_input('Area',
                               10.0,
                               units="m**2",
                               desc="Rotor disc area")
                self.add_input('rho',
                               1.225,
                               units="kg/m**3",
                               desc="air density")
                self.add_input(
                    'Vu',
                    10.0,
                    units="m/s",
                    desc="Freestream air velocity, upstream of rotor")

                # Outputs
                self.add_output('Vr',
                                0.0,
                                units="m/s",
                                desc="Air velocity at rotor exit plane")
                self.add_output(
                    'Vd',
                    0.0,
                    units="m/s",
                    desc="Slipstream air velocity, downstream of rotor")
                self.add_output('Ct', 0.0, desc="Thrust Coefficient")
                self.add_output('thrust',
                                0.0,
                                units="N",
                                desc="Thrust produced by the rotor")
                self.add_output('Cp', 0.0, desc="Power Coefficient")
                self.add_output('power',
                                0.0,
                                units="W",
                                desc="Power produced by the rotor")

                self.declare_partials('Vr', ['a', 'Vu'])
                self.declare_partials('Vd', 'a')
                self.declare_partials('Ct', 'a')
                self.declare_partials('thrust', ['a', 'Area', 'rho', 'Vu'])
                self.declare_partials('Cp', 'a')
                self.declare_partials('power', ['a', 'Area', 'rho', 'Vu'])

            def compute(self, inputs, outputs):
                """ Considering the entire rotor as a single disc that extracts
                velocity uniformly from the incoming flow and converts it to
                power."""

                a = inputs['a']
                Vu = inputs['Vu']

                qA = .5 * inputs['rho'] * inputs['Area'] * Vu**2

                outputs['Vd'] = Vd = Vu * (1 - 2 * a)
                outputs['Vr'] = .5 * (Vu + Vd)

                outputs['Ct'] = Ct = 4 * a * (1 - a)
                outputs['thrust'] = Ct * qA

                outputs['Cp'] = Cp = Ct * (1 - a)
                outputs['power'] = Cp * qA * Vu

            def compute_partials(self, inputs, J):
                """ Jacobian of partial derivatives."""

                a = inputs['a']
                Vu = inputs['Vu']
                Area = inputs['Area']
                rho = inputs['rho']

                # pre-compute commonly needed quantities
                a_times_area = a * Area
                one_minus_a = 1.0 - a
                a_area_rho_vu = a_times_area * rho * Vu

                J['Vr', 'a'] = -Vu
                J['Vr', 'Vu'] = one_minus_a

                J['Vd', 'a'] = -2.0 * Vu

                J['Ct', 'a'] = 4.0 - 8.0 * a

                J['thrust', 'a'] = .5 * rho * Vu**2 * Area * J['Ct', 'a']
                J['thrust', 'Area'] = 2.0 * Vu**2 * a * rho * one_minus_a
                J['thrust', 'rho'] = 2.0 * a_times_area * Vu**2 * (one_minus_a)
                J['thrust', 'Vu'] = 4.0 * a_area_rho_vu * (one_minus_a)

                J['Cp',
                  'a'] = 4.0 * a * (2.0 * a - 2.0) + 4.0 * (one_minus_a)**2

                J['power', 'a'] = 2.0 * Area * Vu**3 * a * rho * (
                    2.0 * a - 2.0) + 2.0 * Area * Vu**3 * rho * one_minus_a**2
                J['power', 'Area'] = 2.0 * Vu**3 * a * rho * one_minus_a**2
                J['power',
                  'rho'] = 2.0 * a_times_area * Vu**3 * (one_minus_a)**2
                J['power',
                  'Vu'] = 6.0 * Area * Vu**2 * a * rho * one_minus_a**2

        # build the model
        prob = Problem()
        indeps = prob.model.add_subsystem('indeps',
                                          IndepVarComp(),
                                          promotes=['*'])
        indeps.add_output('a', .5)
        indeps.add_output('Area', 10.0, units='m**2')
        indeps.add_output('rho', 1.225, units='kg/m**3')
        indeps.add_output('Vu', 10.0, units='m/s')

        prob.model.add_subsystem('a_disk',
                                 ActuatorDisc(),
                                 promotes_inputs=['a', 'Area', 'rho', 'Vu'])

        # setup the optimization
        prob.driver = ScipyOptimizer()
        prob.driver.options['optimizer'] = 'SLSQP'

        prob.model.add_design_var('a', lower=0., upper=1.)
        prob.model.add_design_var('Area', lower=0., upper=1.)
        # negative one so we maximize the objective
        prob.model.add_objective('a_disk.Cp', scaler=-1)

        prob.setup()
        prob.run_driver()

        # minimum value
        assert_rel_error(self, prob['a_disk.Cp'], 16. / 27., 1e-4)
Example #3
0
                                                (rRoot**2) * alum_stress)
            mRoot = 2.0 * math.pi * rRoot * t * rootLength * alum_rho

            # Total weight
            mass = nBlades * (np.sum(m[0:-1] * np.diff(x)) + 2.0 * mRib +
                              mRoot)
            error = abs(mass - massOld)
            massOld = mass

        mass = fudge * mass  # Fudge factor

        unknowns['mass'] = mass


if __name__ == "__main__":  # DEBUG
    top = Problem()
    root = top.root = Group()

    # Sample Inputs
    indep_vars_constants = [('rProp', 1.4), ('thrust', 10000.0)]

    root.add('Inputs', IndepVarComp(indep_vars_constants))

    root.add('Example', prop_mass())

    root.connect('Inputs.rProp', 'Example.rProp')
    root.connect('Inputs.thrust', 'Example.thrust')

    top.setup()
    top.run()
Example #4
0
def main(tot_iter):
    objectives = {0: "compliance", 1: "stress"}

    # TODO: folder path and restart # must be manually input each time
    loadFolder = loadFolder0 + ""
    restart_iter = 26

    import os
    try:
        os.mkdir(loadFolder + 'restart_' + str(restart_iter))
    except:
        pass

    try:
        os.mkdir(loadFolder + 'restart_' + str(restart_iter) + '/figs')
    except:
        pass

    inspctFlag = False
    if tot_iter < 0:
        inspctFlag = True
        tot_iter = restart_iter + 1

    # Select which problem to solve
    obj_flag = 1
    print(locals())
    print("solving single physics %s problem" % objectives[obj_flag])

    print("restarting from %d ..." % restart_iter)
    fname0 = loadFolder + 'phi%03i.pkl' % restart_iter

    with open(fname0, 'rb') as f:
        raw = pickle.load(f)

    phi0 = raw['phi']

    fname0 = loadFolder0 + 'const.pkl'
    with open(fname0, 'rb') as f:
        raw = pickle.load(f)

    # nodes = raw['mesh']
    nodes = raw['nodes']
    elem = raw['elem']
    GF_e = raw['GF_e']
    BCid_e = raw['BCid_e']
    E = raw['E']
    nu = raw['nu']
    f = raw['f']
    nelx = raw['nelx']
    nely = raw['nely']
    length_x = raw['length_x']
    length_y = raw['length_y']
    coord_e = raw['coord_e']
    tol_e = raw['tol_e']

    ############################################################################
    ###########################         FEA          ###########################
    ############################################################################
    # NB: only Q4 elements + integer-spaced mesh are assumed

    ls2fe_x = length_x / float(nelx)
    ls2fe_y = length_y / float(nely)

    num_nodes_x = nelx + 1
    num_nodes_y = nely + 1

    nELEM = nelx * nely
    nNODE = num_nodes_x * num_nodes_y

    # Declare FEA object (OpenLSTO_FEA) ==============================
    fea_solver = py_FEA(lx=length_x,
                        ly=length_y,
                        nelx=nelx,
                        nely=nely,
                        element_order=2)
    [node, elem, elem_dof] = fea_solver.get_mesh()

    ## validate the mesh
    if nELEM != elem.shape[0]:
        error("error found in the element")
    if nNODE != node.shape[0]:
        error("error found in the node")

    nDOF_e = nNODE * 2  # each node has two displacement DOFs

    # constitutive properties ========================================
    fea_solver.set_material(E=E, nu=nu, rho=1.0)

    # Boundary Conditions ============================================
    fea_solver.set_boundary(coord=coord_e, tol=tol_e)
    BCid_e = fea_solver.get_boundary()
    nDOF_e_wLag = nDOF_e + len(BCid_e)  # elasticity DOF

    ############################################################################
    ###########################         LSM          ###########################
    ############################################################################
    movelimit = 0.5

    # Declare Level-set object
    lsm_solver = py_LSM(nelx=nelx, nely=nely, moveLimit=movelimit)
    lsm_solver.add_holes([], [], [])
    lsm_solver.set_levelset()

    lsm_solver.set_phi_re(phi0)

    lsm_solver.reinitialise()

    ############################################################################
    ########################         T.O. LOOP          ########################
    ############################################################################
    for i_HJ in range(restart_iter, tot_iter):
        (bpts_xy, areafraction, seglength) = lsm_solver.discretise()

        # OpenMDAO ===================================================
        ## Define Group
        if (objectives[obj_flag] == "compliance"):
            model = ComplianceGroup(fea_solver=fea_solver,
                                    lsm_solver=lsm_solver,
                                    nelx=nelx,
                                    nely=nely,
                                    force=GF_e,
                                    movelimit=movelimit,
                                    BCid=BCid_e)
        elif (objectives[obj_flag] == "stress"):
            model = StressGroup(fea_solver=fea_solver,
                                lsm_solver=lsm_solver,
                                nelx=nelx,
                                nely=nely,
                                force=GF_e,
                                movelimit=movelimit,
                                pval=6.0,
                                BCid=BCid_e)

        ## Define problem for OpenMDAO object
        prob = Problem(model)

        ## Setup the problem
        prob.driver = pyOptSparseDriver()
        prob.driver.options['optimizer'] = 'IPOPT'
        prob.driver.opt_settings['linear_solver'] = 'ma27'
        prob.setup(check=False)
        prob.run_model()

        ## Total derivative using MAUD
        if (objectives[obj_flag] == "compliance"):
            ff = total['compliance_comp.compliance', 'inputs_comp.Vn'][0]
            gg = total['weight_comp.weight', 'inputs_comp.Vn'][0]
        elif (objectives[obj_flag] == "stress"):
            ff = total['pnorm_comp.pnorm', 'inputs_comp.Vn'][0]
            gg = total['weight_comp.weight', 'inputs_comp.Vn'][0]

        ## Assign object function sensitivities
        nBpts = int(bpts_xy.shape[0])
        Sf = -ff[:nBpts]  # equal to M2DO-perturbation
        Cf = np.multiply(
            Sf, seglength)  # Shape sensitivity (integral coefficients)

        ## Assign constraint sensitivities
        Sg = -gg[:nBpts]
        Sg[Sg <
           -1.5] = -1.5  # apply caps (bracketing) to constraint sensitivities
        Sg[Sg >
           0.5] = 0.5  # apply caps (bracketing) to constraint sensitivities
        Cg = np.multiply(
            Sg, seglength)  # Shape sensitivity (integral coefficients)

        # Suboptimize ================================================
        if 1:
            suboptim = Solvers(bpts_xy=bpts_xy,
                               Sf=Sf,
                               Sg=Sg,
                               Cf=Cf,
                               Cg=Cg,
                               length_x=length_x,
                               length_y=length_y,
                               areafraction=areafraction,
                               movelimit=movelimit)
            # suboptimization
            if 1:  # simplex
                Bpt_Vel = suboptim.simplex(isprint=False)
            else:  # bisection..
                Bpt_Vel = suboptim.bisection(isprint=False)
            timestep = 1.0
        elif 1:  # works okay now.
            bpts_sens = np.zeros((nBpts, 2))
            # issue: scaling problem
            #
            bpts_sens[:, 0] = Sf
            bpts_sens[:, 1] = Sg

            lsm_solver.set_BptsSens(bpts_sens)
            scales = lsm_solver.get_scale_factors()
            (lb2, ub2) = lsm_solver.get_Lambda_Limits()
            constraint_distance = (0.4 * nelx * nely) - areafraction.sum()

            model = LSM2D_slpGroup(lsm_solver=lsm_solver,
                                   num_bpts=nBpts,
                                   b=ub2,
                                   lb=lb2,
                                   Sf=bpts_sens[:, 0],
                                   Sg=bpts_sens[:, 1],
                                   constraintDistance=constraint_distance,
                                   movelimit=movelimit)

            subprob = Problem(model)
            subprob.setup()

            subprob.driver = ScipyOptimizeDriver()
            subprob.driver.options['optimizer'] = 'SLSQP'
            subprob.driver.options['disp'] = True
            subprob.driver.options['tol'] = 1e-10

            subprob.run_driver()
            lambdas = subprob['inputs_comp.lambdas']
            displacements_ = subprob['displacement_comp.displacements']

            displacements_[displacements_ > movelimit] = movelimit
            displacements_[displacements_ < -movelimit] = -movelimit
            timestep = 1.0  #abs(lambdas[0]*scales[0])

            Bpt_Vel = displacements_ / timestep
            # print(timestep)
            del subprob
        else:  # branch: perturb-suboptim
            bpts_sens = np.zeros((nBpts, 2))
            # issue: scaling problem
            #
            bpts_sens[:, 0] = Sf
            bpts_sens[:, 1] = Sg

            lsm_solver.set_BptsSens(bpts_sens)
            scales = lsm_solver.get_scale_factors()
            (lb2, ub2) = lsm_solver.get_Lambda_Limits()

            constraint_distance = (0.4 * nelx * nely) - areafraction.sum()
            constraintDistance = np.array([constraint_distance])
            scaled_constraintDist = lsm_solver.compute_scaledConstraintDistance(
                constraintDistance)

            def objF_nocallback(x):
                displacement = lsm_solver.compute_displacement(x)
                displacement_np = np.asarray(displacement)
                return lsm_solver.compute_delF(displacement_np)

            def conF_nocallback(x):
                displacement = lsm_solver.compute_displacement(x)
                displacement_np = np.asarray(displacement)
                return lsm_solver.compute_delG(displacement_np,
                                               scaled_constraintDist, 1)

            cons = ({'type': 'eq', 'fun': lambda x: conF_nocallback(x)})
            res = sp_optim.minimize(objF_nocallback,
                                    np.zeros(2),
                                    method='SLSQP',
                                    options={'disp': True},
                                    bounds=((lb2[0], ub2[0]), (lb2[1],
                                                               ub2[1])),
                                    constraints=cons)

            lambdas = res.x
            displacements_ = lsm_solver.compute_unscaledDisplacement(lambdas)
            displacements_[displacements_ > movelimit] = movelimit
            displacements_[displacements_ < -movelimit] = -movelimit
            timestep = 1.0  #abs(lambdas[0]*scales[0])
            Bpt_Vel = displacements_ / timestep
            # scaling
            # Bpt_Vel = Bpt_Vel#/np.max(np.abs(Bpt_Vel))

        lsm_solver.advect(Bpt_Vel, timestep)
        lsm_solver.reinitialise()

        if not inspctFlag:  # quickplot
            plt.figure(1)
            plt.clf()
            plt.scatter(bpts_xy[:, 0], bpts_xy[:, 1], 10)
            plt.axis("equal")
            plt.savefig(loadFolder + 'restart_' + str(restart_iter) + "/" +
                        "figs/bpts_%d.png" % i_HJ)

        print('loop %d is finished' % i_HJ)
        area = areafraction.sum() / (nelx * nely)
        u = prob['disp_comp.disp']
        compliance = np.dot(u, GF_e[:nDOF_e])

        # Printing/Plotting ==========================================
        if 1:  # quickplot
            plt.figure(1)
            plt.clf()
            plt.scatter(bpts_xy[:, 0], bpts_xy[:, 1], 10)
            plt.axis("equal")
            plt.savefig(loadFolder + 'restart_' + str(restart_iter) + "/" +
                        "figs/bpts_%d.png" % i_HJ)

        if (objectives[obj_flag] == "compliance" and not inspctFlag):
            compliance = prob['compliance_comp.compliance']
            print(compliance, area)

            fid = open(
                loadFolder + 'restart_' + str(restart_iter) + "/" + "log.txt",
                "a+")
            fid.write(str(compliance) + ", " + str(area) + "\n")
            fid.close()
        elif (objectives[obj_flag] == "stress" and not inspctFlag):
            print(prob['pnorm_comp.pnorm'][0], area)

            fid = open(
                loadFolder + 'restart_' + str(restart_iter) + "/" + "log.txt",
                "a+")
            fid.write(
                str(prob['pnorm_comp.pnorm'][0]) + ", " + str(area) + "\n")
            fid.close()

        ## Saving Phi
        phi = lsm_solver.get_phi()

        if not inspctFlag:
            raw = {}
            raw['phi'] = phi
            filename = loadFolder + 'restart_' + str(
                restart_iter) + '/' + 'phi%03i.pkl' % i_HJ
            with open(filename, 'wb') as f:
                pickle.dump(raw, f)

        del model
        del prob

        mem = virtual_memory()
        print(str(mem.available / 1024. / 1024. / 1024.) + "GB")
        if mem.available / 1024. / 1024. / 1024. < 3.0:
            print("memory explodes at iteration %3i " % i_HJ)
            exit()
options.models.electrical = TopologyHybridHeuristic
options.models.support = TeamPlay
options.models.opex = OM_model1
options.models.apex = TeamPlayCostModel

# Define number of windrose sampling points
options.samples.wind_speeds = 7
options.samples.wind_sector_angle = 30.0

# Define paths to site and turbine defining input files.
options.input.site.windrose_file = "Input/weibull_windrose_12unique.dat"
options.input.site.bathymetry_file = "Input/bathymetry_table.dat"
options.input.turbine.power_file = "Input/power_dtu10.dat"
options.input.turbine.ct_file = "Input/ct_dtu10.dat"

# Instantiate OpenMDAO problemlem class
problem = Problem()
problem.model = WorkingGroup(options)

problem.setup()

### Uncomment below to plot N2 diagram in a browser.
# view_model(problem)
problem.run_model()

lcoe = problem['lcoe.LCOE'][0]
aep = problem['AeroAEP.AEP'][0]

print_nice("LCOE", lcoe)
print_nice("AEP", aep)
    def test(self):

        # Create a dictionary to store options about the surface
        mesh_dict = {
            'num_y': 7,
            'wing_type': 'CRM',
            'symmetry': True,
            'num_twist_cp': 5
        }

        mesh, twist_cp = generate_mesh(mesh_dict)

        surf_dict = {
            # Wing definition
            'name': 'wing',  # name of the surface
            'symmetry': True,  # if true, model one half of wing
            # reflected across the plane y = 0
            'fem_model_type': 'tube',
            'mesh': mesh,
            'radius_cp': np.ones((5)) * 0.5,

            # Structural values are based on aluminum 7075
            'E': 70.e9,  # [Pa] Young's modulus of the spar
            'G': 30.e9,  # [Pa] shear modulus of the spar
            'yield':
            500.e6 / 2.5,  # [Pa] yield stress divided by 2.5 for limiting case
            'mrho': 3.e3,  # [kg/m^3] material density
            'fem_origin': 0.35,  # normalized chordwise location of the spar
            't_over_c_cp': np.array([0.15]),  # maximum airfoil thickness
            'thickness_cp': np.ones((3)) * .1,
            'wing_weight_ratio': 2.,
            'struct_weight_relief':
            False,  # True to add the weight of the structure to the loads on the structure
            'distributed_fuel_weight': False,
            'exact_failure_constraint': False,
        }

        # Create the problem and assign the model group
        prob = Problem()

        ny = surf_dict['mesh'].shape[1]

        indep_var_comp = IndepVarComp()
        indep_var_comp.add_output('loads',
                                  val=np.ones((ny, 6)) * 2e5,
                                  units='N')
        indep_var_comp.add_output('load_factor', val=1.)

        struct_group = SpatialBeamAlone(surface=surf_dict)

        # Add indep_vars to the structural group
        struct_group.add_subsystem('indep_vars',
                                   indep_var_comp,
                                   promotes=['*'])

        prob.model.add_subsystem(surf_dict['name'], struct_group)

        # Set up the problem
        prob.setup()

        prob.run_model()

        assert_rel_error(self, prob['wing.structural_mass'][0], 117819.798089,
                         1e-4)
Example #7
0
    return rotor


if __name__ == "__main__":

    # Turbine Ontology input
    # fname_input = "turbine_inputs/nrel5mw_mod_update.yaml"
    fname_input = "/mnt/c/Users/egaertne/WISDEM2/wisdem/Design_Opt/nrel15mw/inputs/NREL15MW_prelim_v3.0.yaml"

    # Initialize blade design
    refBlade = ReferenceBlade()
    refBlade.verbose = True
    refBlade.NINPUT = NINPUT
    refBlade.NPTS = 50
    refBlade.validate = False
    refBlade.fname_schema = "turbine_inputs/IEAontology_schema.yaml"

    refBlade.spar_var = ['Spar_Cap_SS', 'Spar_Cap_PS']
    refBlade.te_var = 'TE_reinforcement'
    # refBlade.le_var       = 'le_reinf'
    blade = refBlade.initialize(fname_input)

    # setup
    rotor = Problem()
    rotor.model = RotorGeometry(RefBlade=blade, topLevelFlag=True)
    rotor.setup()
    rotor = Init_RotorGeometry_wRefBlade(rotor, blade)
    rotor.run_driver()

    print(rotor['total_blade_cost'])
Example #8
0
    def test_basic_apply(self):
        """Test that output values and total derivatives are correct."""
        class SrcCompa(ExplicitComponent):
            """Source provides degrees Celsius."""
            def setup(self):
                self.add_input('x1', 100.0)
                self.add_output('x2', 100.0, units='degC')

            def compute(self, inputs, outputs):
                """ Pass through."""
                outputs['x2'] = inputs['x1']

            def compute_jacvec_product(self, inputs, d_inputs, d_outputs,
                                       mode):
                """ Derivative is 1.0"""

                if mode == 'fwd':
                    d_outputs['x2'] += d_inputs['x1']
                else:
                    d_inputs['x1'] += d_outputs['x2']

        class TgtCompFa(ExplicitComponent):
            """Target expressed in degrees F."""
            def setup(self):
                self.add_input('x2', 100.0, units='degF')
                self.add_output('x3', 100.0)

            def compute(self, inputs, outputs):
                """ Pass through."""
                outputs['x3'] = inputs['x2']

            def compute_jacvec_product(self, inputs, d_inputs, d_outputs,
                                       mode):
                """ Derivative is 1.0"""

                if mode == 'fwd':
                    d_outputs['x3'] += d_inputs['x2']
                else:
                    d_inputs['x2'] += d_outputs['x3']

        prob = Problem()
        model = prob.model = Group()

        model.add_subsystem('px1', IndepVarComp('x1', 100.0))
        model.add_subsystem('src', SrcCompa())
        model.add_subsystem('tgtF', TgtCompFa())

        model.connect('px1.x1', 'src.x1')
        model.connect('src.x2', 'tgtF.x2')

        # Check the outputs after running to test the unit conversions
        prob.setup(check=False, mode='fwd')
        prob.run_model()

        assert_rel_error(self, prob['src.x2'], 100.0, 1e-6)
        assert_rel_error(self, prob['tgtF.x3'], 212.0, 1e-6)

        # Check the total derivatives in forward mode
        wrt = ['px1.x1']
        of = ['tgtF.x3']
        J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict')

        assert_rel_error(self, J['tgtF.x3', 'px1.x1'][0][0], 1.8, 1e-6)

        # Check the total derivatives in reverse mode
        prob.setup(check=False, mode='rev')
        prob.run_model()
        J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict')

        assert_rel_error(self, J['tgtF.x3', 'px1.x1'][0][0], 1.8, 1e-6)
Example #9
0
    def test_basic_fd_comps(self):

        prob = Problem()
        prob.model = Group()
        prob.model.add_subsystem('px1',
                                 IndepVarComp('x1', 100.0),
                                 promotes=['x1'])
        prob.model.add_subsystem('src', SrcCompFD())
        prob.model.add_subsystem('tgtF', TgtCompFFD())
        prob.model.add_subsystem('tgtC', TgtCompCFD())
        prob.model.add_subsystem('tgtK', TgtCompKFD())
        prob.model.connect('x1', 'src.x1')
        prob.model.connect('src.x2', 'tgtF.x2')
        prob.model.connect('src.x2', 'tgtC.x2')
        prob.model.connect('src.x2', 'tgtK.x2')

        prob.setup(check=False)
        prob.run_model()

        assert_rel_error(self, prob['src.x2'], 100.0, 1e-6)
        assert_rel_error(self, prob['tgtF.x3'], 212.0, 1e-6)
        assert_rel_error(self, prob['tgtC.x3'], 100.0, 1e-6)
        assert_rel_error(self, prob['tgtK.x3'], 373.15, 1e-6)

        indep_list = ['x1']
        unknown_list = ['tgtF.x3', 'tgtC.x3', 'tgtK.x3']
        J = prob.compute_totals(of=unknown_list,
                                wrt=indep_list,
                                return_format='dict')

        assert_rel_error(self, J['tgtF.x3']['x1'][0][0], 1.8, 1e-6)
        assert_rel_error(self, J['tgtC.x3']['x1'][0][0], 1.0, 1e-6)
        assert_rel_error(self, J['tgtK.x3']['x1'][0][0], 1.0, 1e-6)

        prob.setup(check=False, mode='rev')
        prob.run_model()
        J = prob.compute_totals(of=unknown_list,
                                wrt=indep_list,
                                return_format='dict')

        assert_rel_error(self, J['tgtF.x3']['x1'][0][0], 1.8, 1e-6)
        assert_rel_error(self, J['tgtC.x3']['x1'][0][0], 1.0, 1e-6)
        assert_rel_error(self, J['tgtK.x3']['x1'][0][0], 1.0, 1e-6)

        prob.model.approx_totals(method='fd')
        prob.setup(check=False, mode='rev')
        prob.run_model()
        J = prob.compute_totals(of=unknown_list,
                                wrt=indep_list,
                                return_format='dict')

        assert_rel_error(self, J['tgtF.x3']['x1'][0][0], 1.8, 1e-6)
        assert_rel_error(self, J['tgtC.x3']['x1'][0][0], 1.0, 1e-6)
        assert_rel_error(self, J['tgtK.x3']['x1'][0][0], 1.0, 1e-6)

        # Make sure check partials handles conversion
        data = prob.check_partials()

        for key1, val1 in iteritems(data):
            for key2, val2 in iteritems(val1):
                assert_rel_error(self, val2['abs error'][0], 0.0, 1e-6)
                assert_rel_error(self, val2['abs error'][1], 0.0, 1e-6)
                assert_rel_error(self, val2['abs error'][2], 0.0, 1e-6)
                assert_rel_error(self, val2['rel error'][0], 0.0, 1e-6)
                assert_rel_error(self, val2['rel error'][1], 0.0, 1e-6)
                assert_rel_error(self, val2['rel error'][2], 0.0, 1e-6)
Example #10
0
    def test_is_local(self):
        p = Problem()
        p.model.add_subsystem('indep', IndepVarComp('x', 1.0))
        par = p.model.add_subsystem('par', ParallelGroup())
        par.add_subsystem('C1', ExecComp('y=2*x'))
        par.add_subsystem('C2', ExecComp('y=3*x'))
        p.model.connect('indep.x', ['par.C1.x', 'par.C2.x'])

        with self.assertRaises(RuntimeError) as cm:
            loc = p.is_local('indep.x')
        self.assertEqual(
            str(cm.exception),
            "Problem: is_local('indep.x') was called before setup() completed."
        )

        with self.assertRaises(RuntimeError) as cm:
            loc = p.is_local('par.C1')
        self.assertEqual(
            str(cm.exception),
            "Problem: is_local('par.C1') was called before setup() completed.")

        with self.assertRaises(RuntimeError) as cm:
            loc = p.is_local('par.C1.y')
        self.assertEqual(
            str(cm.exception),
            "Problem: is_local('par.C1.y') was called before setup() completed."
        )

        with self.assertRaises(RuntimeError) as cm:
            loc = p.is_local('par.C1.x')
        self.assertEqual(
            str(cm.exception),
            "Problem: is_local('par.C1.x') was called before setup() completed."
        )

        p.setup()
        p.final_setup()

        self.assertTrue(p.is_local('indep'), 'indep should be local')
        self.assertTrue(p.is_local('indep.x'), 'indep.x should be local')

        if p.comm.rank == 0:
            self.assertTrue(p.is_local('par.C1'), 'par.C1 should be local')
            self.assertTrue(p.is_local('par.C1.x'), 'par.C1.x should be local')
            self.assertTrue(p.is_local('par.C1.y'), 'par.C1.y should be local')

            self.assertFalse(p.is_local('par.C2'), 'par.C1 should be remote')
            self.assertFalse(p.is_local('par.C2.x'),
                             'par.C1.x should be remote')
            self.assertFalse(p.is_local('par.C2.y'),
                             'par.C1.y should be remote')
        else:
            self.assertFalse(p.is_local('par.C1'), 'par.C1 should be remote')
            self.assertFalse(p.is_local('par.C1.x'),
                             'par.C1.x should be remote')
            self.assertFalse(p.is_local('par.C1.y'),
                             'par.C1.y should be remote')

            self.assertTrue(p.is_local('par.C2'), 'par.C2 should be local')
            self.assertTrue(p.is_local('par.C2.x'), 'par.C2.x should be local')
            self.assertTrue(p.is_local('par.C2.y'), 'par.C2.y should be local')
Example #11
0
        self.add_output('time', val=0.0)

    def solve_nonlinear(self, params, unknowns, resids):

        try:
            with open('time.txt', 'r') as f_in:
                unknowns['time'] = time.time() - float(f_in.readline())
        except IOError:
            unknowns['time'] = -1.0


if __name__ == '__main__':

    # Instantiate a sub-level Problem 'OptimizationProblem'.
    # Instantiate a Group and add it to OptimizationProblem.
    optimizationProblem = Problem()
    optimizationProblem.root = Group()

    # Add the 'Paraboloid' Component to paraboloidProblem's root Group.
    optimizationProblem.root.add('Paraboloid', Paraboloid())

    # Initialize x and y values in seperate IndepVarComps and add them to paraboloidProblem's root group
    # These are added for the two Problem Inputs 'x' and 'y'
    optimizationProblem.root.add('p1', IndepVarComp('x', 0.0))
    optimizationProblem.root.add('p2', IndepVarComp('y', 0.0))

    # Connect the IndepVarComps 'p1.x' and 'p2.y' to 'T.Paraboloid.x' and 'T.Paraboloid.y' respectively
    optimizationProblem.root.connect('p1.x', 'Paraboloid.x')
    optimizationProblem.root.connect('p2.y', 'Paraboloid.y')

    # We'll need to create ExecComps so that we can pass out the IndepVarComps values as expressed by connecting the Problem Inputs to the Problem Outputs in OpenMETA
Example #12
0
# -*- coding: utf-8 -*-
"""
  run_analysis.py generated by WhatsOpt 1.9.4
"""
# DO NOT EDIT unless you know what you are doing
# analysis_id: 735

from openmdao.api import Problem
from run_parameters_init import initialize
from trajectory_version2 import TrajectoryVersion2 

pb = Problem(TrajectoryVersion2())
pb.setup()  

initialize(pb)

pb.run_model()   
pb.model.list_inputs(print_arrays=False)
pb.model.list_outputs(print_arrays=False)

Example #13
0
    def test_result(self):
        prob = Problem(model=Group())

        ivc = IndepVarComp()

        ivc.add_output(name='M', val=0.0, units='deg', desc='Mean anomaly')

        ivc.add_output(name='ecc',
                       val=0.0,
                       units=None,
                       desc='orbit eccentricity')

        bal = BalanceComp()

        bal.add_balance(name='E',
                        val=0.0,
                        units='rad',
                        eq_units='rad',
                        rhs_name='M')

        # Override the guess_nonlinear method, always initialize E to the value of M
        def guess_func(inputs, outputs, residuals):
            outputs['E'] = inputs['M']

        bal.guess_nonlinear = guess_func

        # ExecComp used to compute the LHS of Kepler's equation.
        lhs_comp = ExecComp('lhs=E - ecc * sin(E)',
                            lhs={
                                'value': 0.0,
                                'units': 'rad'
                            },
                            E={
                                'value': 0.0,
                                'units': 'rad'
                            },
                            ecc={'value': 0.0})

        prob.model.add_subsystem(name='ivc',
                                 subsys=ivc,
                                 promotes_outputs=['M', 'ecc'])

        prob.model.add_subsystem(name='balance',
                                 subsys=bal,
                                 promotes_inputs=['M'],
                                 promotes_outputs=['E'])

        prob.model.add_subsystem(name='lhs_comp',
                                 subsys=lhs_comp,
                                 promotes_inputs=['E', 'ecc'])

        # Explicit connections
        prob.model.connect('lhs_comp.lhs', 'balance.lhs:E')

        # Setup solvers
        prob.model.linear_solver = DirectSolver()
        prob.model.nonlinear_solver = NewtonSolver()
        prob.model.nonlinear_solver.options['maxiter'] = 100
        prob.model.nonlinear_solver.options['iprint'] = 0

        prob.setup()

        prob['M'] = 85.0
        prob['ecc'] = 0.6

        prob.run_model()

        assert_almost_equal(np.degrees(prob['E']), 115.9, decimal=1)

        print('E (deg) = ', np.degrees(prob['E'][0]))
Example #14
0
def create_problem(magdrag):
    root = Group()
    prob = Problem(root)
    prob.root.add('comp', magdrag)
    return prob
Example #15
0
    def test_analysis_error(self):
        class ParaboloidAE(ExplicitComponent):
            """ Evaluates the equation f(x,y) = (x-3)^2 + xy + (y+4)^2 - 3
            This version raises an analysis error if x < 2.0
            The AE in ParaboloidAE stands for AnalysisError."""
            def __init__(self):
                super(ParaboloidAE, self).__init__()
                self.fail_hard = False

            def setup(self):
                self.add_input('x', val=0.0)
                self.add_input('y', val=0.0)

                self.add_output('f_xy', val=0.0)

                self.declare_partials(of='*', wrt='*')

            def compute(self, inputs, outputs):
                """f(x,y) = (x-3)^2 + xy + (y+4)^2 - 3
                Optimal solution (minimum): x = 6.6667; y = -7.3333
                """
                x = inputs['x']
                y = inputs['y']

                if x < 1.75:
                    raise AnalysisError('Try Again.')

                outputs['f_xy'] = (x - 3.0)**2 + x * y + (y + 4.0)**2 - 3.0

            def compute_partials(self, inputs, partials):
                """ Jacobian for our paraboloid."""
                x = inputs['x']
                y = inputs['y']

                partials['f_xy', 'x'] = 2.0 * x - 6.0 + y
                partials['f_xy', 'y'] = 2.0 * y + 8.0 + x

        top = Problem()
        top.model = Group()
        top.model.add_subsystem('px', IndepVarComp('x', 1.0))
        top.model.add_subsystem('comp', ImplCompTwoStates())
        top.model.add_subsystem('par', ParaboloidAE())
        top.model.connect('px.x', 'comp.x')
        top.model.connect('comp.z', 'par.x')

        top.model.nonlinear_solver = NewtonSolver()
        top.model.nonlinear_solver.options['maxiter'] = 1
        top.model.linear_solver = ScipyIterativeSolver()

        ls = top.model.nonlinear_solver.linesearch = ArmijoGoldsteinLS(
            bound_enforcement='vector')
        ls.options['maxiter'] = 10
        ls.options['alpha'] = 1.0
        top.set_solver_print(level=0)

        top.setup(check=False)

        # Test lower bound: should go as far as it can without going past 1.75 and triggering an
        # AnalysisError. It doesn't do a great job, so ends up at 1.8 instead of 1.75
        top['px.x'] = 2.0
        top['comp.y'] = 0.0
        top['comp.z'] = 2.1
        top.run_model()
        assert_rel_error(self, top['comp.z'], 1.8, 1e-8)

        # Test the behavior with the switch turned off.

        top = Problem()
        top.model = Group()
        top.model.add_subsystem('px', IndepVarComp('x', 1.0))
        top.model.add_subsystem('comp', ImplCompTwoStates())
        top.model.add_subsystem('par', ParaboloidAE())
        top.model.connect('px.x', 'comp.x')
        top.model.connect('comp.z', 'par.x')

        top.model.nonlinear_solver = NewtonSolver()
        top.model.nonlinear_solver.options['maxiter'] = 1
        top.model.linear_solver = ScipyIterativeSolver()

        ls = top.model.nonlinear_solver.linesearch = ArmijoGoldsteinLS(
            bound_enforcement='vector')
        ls.options['maxiter'] = 10
        ls.options['alpha'] = 1.0
        ls.options['retry_on_analysis_error'] = False
        top.set_solver_print(level=0)

        top.setup(check=False)

        top['px.x'] = 2.0
        top['comp.y'] = 0.0
        top['comp.z'] = 2.1

        with self.assertRaises(AnalysisError) as context:
            top.run_model()

        self.assertEqual(str(context.exception), 'Try Again.')
Example #16
0
 def test_dangling_input_w_units(self):
     prob = Problem(model=Group())
     prob.model.add_subsystem(
         'C1', ExecComp('y=x', x={'units': 'ft'}, y={'units': 'm'}))
     prob.setup()
     prob.run_model()
Example #17
0
ref_area_m2 = aircraft_data['areaRef_m2']
Wac_1e6_N = aircraft_data['Wac_1e6_N']
Mach_mode = 'TAS'

propulsion_model = get_prop_smt_model()
aerodynamics_model = get_aero_smt_model()

xt, yt, xlimits = get_rans_crm_wing()
aerodynamics_model.xt = xt

prob = Problem(model=AllocationMissionDesignGroup(
    flight_conditions=flight_conditions,
    aircraft_data=aircraft_data,
    general_allocation_data=general_allocation_data,
    allocation_data=allocation_data,
    ref_area_m2=ref_area_m2,
    Wac_1e6_N=Wac_1e6_N,
    Mach_mode=Mach_mode,
    propulsion_model=propulsion_model,
    aerodynamics_model=aerodynamics_model,
    initial_mission_vars=initial_mission_vars))

print("Running Setup")
prob.setup(vector_class=PETScVector)
print("Setup Complete")
for key, value in iteritems(initial_dvs):
    prob[key] = value

prob.run_model()

prob.check_totals()
Example #18
0
    def test_relevance(self):
        p = Problem()
        model = p.model

        indep1 = model.add_subsystem("indep1", IndepVarComp('x', 1.0))
        G1 = model.add_subsystem('G1', Group())
        G1.add_subsystem('C1', ExecComp(['x=2.0*a', 'y=2.0*b', 'z=2.0*a']))
        G1.add_subsystem('C2', ExecComp(['x=2.0*a', 'y=2.0*b', 'z=2.0*b']))
        model.add_subsystem("C3", ExecComp(['x=2.0*a', 'y=2.0*b+3.0*c']))
        model.add_subsystem("C4", ExecComp(['x=2.0*a', 'y=2.0*b']))
        indep2 = model.add_subsystem("indep2", IndepVarComp('x', 1.0))
        G2 = model.add_subsystem('G2', Group())
        G2.add_subsystem('C5', ExecComp(['x=2.0*a', 'y=2.0*b+3.0*c']))
        G2.add_subsystem('C6', ExecComp(['x=2.0*a', 'y=2.0*b+3.0*c']))
        G2.add_subsystem('C7', ExecComp(['x=2.0*a', 'y=2.0*b']))
        model.add_subsystem("C8", ExecComp(['y=1.5*a+2.0*b']))
        model.add_subsystem("Unconnected", ExecComp('y=99.*x'))

        model.connect('indep1.x', 'G1.C1.a')
        model.connect('indep2.x', 'G2.C6.a')
        model.connect('G1.C1.x', 'G1.C2.b')
        model.connect('G1.C2.z', 'C4.b')
        model.connect('G1.C1.z', ('C3.b', 'C3.c', 'G2.C5.a'))
        model.connect('C3.y', 'G2.C5.b')
        model.connect('C3.x', 'C4.a')
        model.connect('G2.C6.y', 'G2.C7.b')
        model.connect('G2.C5.x', 'C8.b')
        model.connect('G2.C7.x', 'C8.a')

        p.setup(check=False, mode='rev')

        relevant = get_relevant_vars(model._conn_global_abs_in2out,
                                     ['indep1.x', 'indep2.x'],
                                     ['C8.y', 'Unconnected.y'],
                                     mode='rev')

        indep1_ins = set(
            ['C3.b', 'C3.c', 'C8.b', 'G1.C1.a', 'G2.C5.a', 'G2.C5.b'])
        indep1_outs = set(['C3.y', 'C8.y', 'G1.C1.z', 'G2.C5.x', 'indep1.x'])
        indep1_sys = set(
            ['C3', 'C8', 'G1.C1', 'G2.C5', 'indep1', 'G1', 'G2', ''])

        dct, systems = relevant['C8.y']['indep1.x']
        inputs = dct['input']
        outputs = dct['output']

        self.assertEqual(inputs, indep1_ins)
        self.assertEqual(outputs, indep1_outs)
        self.assertEqual(systems, indep1_sys)

        dct, systems = relevant['C8.y']['indep1.x']
        inputs = dct['input']
        outputs = dct['output']

        self.assertEqual(inputs, indep1_ins)
        self.assertEqual(outputs, indep1_outs)
        self.assertEqual(systems, indep1_sys)

        indep2_ins = set(['C8.a', 'G2.C6.a', 'G2.C7.b'])
        indep2_outs = set(['C8.y', 'G2.C6.y', 'G2.C7.x', 'indep2.x'])
        indep2_sys = set(['C8', 'G2.C6', 'G2.C7', 'indep2', 'G2', ''])

        dct, systems = relevant['C8.y']['indep2.x']
        inputs = dct['input']
        outputs = dct['output']

        self.assertEqual(inputs, indep2_ins)
        self.assertEqual(outputs, indep2_outs)
        self.assertEqual(systems, indep2_sys)

        dct, systems = relevant['C8.y']['indep2.x']
        inputs = dct['input']
        outputs = dct['output']

        self.assertEqual(inputs, indep2_ins)
        self.assertEqual(outputs, indep2_outs)
        self.assertEqual(systems, indep2_sys)

        dct, systems = relevant['C8.y']['@all']
        inputs = dct['input']
        outputs = dct['output']

        self.assertEqual(inputs, indep1_ins | indep2_ins)
        self.assertEqual(outputs, indep1_outs | indep2_outs)
        self.assertEqual(systems, indep1_sys | indep2_sys)
    def test(self):
        # Create a dictionary to store options about the surface
        mesh_dict = {
            'num_y': 5,
            'num_x': 2,
            'wing_type': 'CRM',
            'symmetry': True,
            'num_twist_cp': 5
        }

        mesh, twist_cp = generate_mesh(mesh_dict)

        surf_dict = {
            # Wing definition
            'name': 'wing',  # name of the surface
            'symmetry': True,  # if true, model one half of wing
            # reflected across the plane y = 0
            'S_ref_type': 'wetted',  # how we compute the wing area,
            # can be 'wetted' or 'projected'
            'fem_model_type': 'tube',
            'thickness_cp': np.array([.1, .2, .3]),
            'twist_cp': twist_cp,
            'mesh': mesh,

            # Aerodynamic performance of the lifting surface at
            # an angle of attack of 0 (alpha=0).
            # These CL0 and CD0 values are added to the CL and CD
            # obtained from aerodynamic analysis of the surface to get
            # the total CL and CD.
            # These CL0 and CD0 values do not vary wrt alpha.
            'CL0': 0.0,  # CL of the surface at alpha=0
            'CD0': 0.015,  # CD of the surface at alpha=0

            # Airfoil properties for viscous drag calculation
            'k_lam': 0.05,  # percentage of chord with laminar
            # flow, used for viscous drag
            't_over_c_cp':
            np.array([0.15]),  # thickness over chord ratio (NACA0015)
            'c_max_t': .303,  # chordwise location of maximum (NACA0015)
            # thickness
            'with_viscous': True,
            'with_wave': False,  # if true, compute wave drag

            # Structural values are based on aluminum 7075
            'E': 70.e9,  # [Pa] Young's modulus of the spar
            'G': 30.e9,  # [Pa] shear modulus of the spar
            'yield':
            500.e6 / 2.5,  # [Pa] yield stress divided by 2.5 for limiting case
            'mrho': 3.e3,  # [kg/m^3] material density
            'fem_origin': 0.35,  # normalized chordwise location of the spar
            'wing_weight_ratio': 2.,
            'struct_weight_relief':
            False,  # True to add the weight of the structure to the loads on the structure
            'distributed_fuel_weight': False,
            # Constraints
            'exact_failure_constraint': False,  # if false, use KS function
        }

        surfaces = [surf_dict]

        # Create the problem and assign the model group
        prob = Problem()

        # Add problem information as an independent variables component
        indep_var_comp = IndepVarComp()
        indep_var_comp.add_output('v', val=248.136, units='m/s')
        indep_var_comp.add_output('alpha', val=5., units='deg')
        indep_var_comp.add_output('Mach_number', val=0.84)
        indep_var_comp.add_output('re', val=1.e6, units='1/m')
        indep_var_comp.add_output('rho', val=0.38, units='kg/m**3')
        indep_var_comp.add_output('CT',
                                  val=grav_constant * 17.e-6,
                                  units='1/s')
        indep_var_comp.add_output('R', val=11.165e6, units='m')
        indep_var_comp.add_output('W0', val=0.4 * 3e5, units='kg')
        indep_var_comp.add_output('speed_of_sound', val=295.4, units='m/s')
        indep_var_comp.add_output('load_factor', val=1.)
        indep_var_comp.add_output('empty_cg', val=np.zeros((3)), units='m')
        indep_var_comp.add_output('S_ref_total', val=150.0, units='m**2')

        prob.model.add_subsystem('prob_vars', indep_var_comp, promotes=['*'])

        # Loop over each surface in the surfaces list
        for surface in surfaces:

            # Get the surface name and create a group to contain components
            # only for this surface
            name = surface['name']

            aerostruct_group = AerostructGeometry(surface=surface)

            # Add tmp_group to the problem with the name of the surface.
            prob.model.add_subsystem(name, aerostruct_group)

        # Loop through and add a certain number of aero points
        for i in range(1):

            point_name = 'AS_point_{}'.format(i)
            # Connect the parameters within the model for each aero point

            # Create the aero point group and add it to the model
            AS_point = AerostructPoint(surfaces=surfaces,
                                       user_specified_Sref=True)

            prob.model.add_subsystem(point_name, AS_point)

            # Connect flow properties to the analysis point
            prob.model.connect('v', point_name + '.v')
            prob.model.connect('alpha', point_name + '.alpha')
            prob.model.connect('Mach_number', point_name + '.Mach_number')
            prob.model.connect('re', point_name + '.re')
            prob.model.connect('rho', point_name + '.rho')
            prob.model.connect('CT', point_name + '.CT')
            prob.model.connect('R', point_name + '.R')
            prob.model.connect('W0', point_name + '.W0')
            prob.model.connect('speed_of_sound',
                               point_name + '.speed_of_sound')
            prob.model.connect('empty_cg', point_name + '.empty_cg')
            prob.model.connect('load_factor', point_name + '.load_factor')
            prob.model.connect('S_ref_total', point_name + '.S_ref_total')

            for surface in surfaces:

                com_name = point_name + '.' + name + '_perf'
                prob.model.connect(
                    name + '.local_stiff_transformed', point_name +
                    '.coupled.' + name + '.local_stiff_transformed')
                prob.model.connect(name + '.nodes',
                                   point_name + '.coupled.' + name + '.nodes')

                # Connect aerodyamic mesh to coupled group mesh
                prob.model.connect(name + '.mesh',
                                   point_name + '.coupled.' + name + '.mesh')

                # Connect performance calculation variables
                prob.model.connect(name + '.radius', com_name + '.radius')
                prob.model.connect(name + '.thickness',
                                   com_name + '.thickness')
                prob.model.connect(name + '.nodes', com_name + '.nodes')
                prob.model.connect(
                    name + '.cg_location',
                    point_name + '.' + 'total_perf.' + name + '_cg_location')
                prob.model.connect(
                    name + '.structural_mass', point_name + '.' +
                    'total_perf.' + name + '_structural_mass')
                prob.model.connect(name + '.t_over_c', com_name + '.t_over_c')

        # Set up the problem
        prob.setup()

        # from openmdao.api import view_model
        # view_model(prob)

        prob.run_model()

        assert_rel_error(self, prob['AS_point_0.CL'][0], 1.5775046966345903,
                         1e-6)
        assert_rel_error(self, prob['AS_point_0.CM'][1], -1.61358383281, 1e-5)
Example #20
0
 def setUp(self):
     self.thermo = species_data.Thermo(species_data.janaf, init_reacts=constants.AIR_MIX)
     p = self.p = Problem(model=Group())
     p.model.suppress_solver_output = True
     p.model.set_input_defaults('P', 1.034210, units="bar")
Example #21
0

if __name__ == '__main__':
    from openmdao.api import Problem, Group, IndepVarComp
    from numpy import sqrt

    class RSSMerge(AbstractWakeMerging):
        def compute(self, inputs, outputs):
            all_du = inputs['all_du']
            add = 0.0
            for du in all_du:
                add += du**2.0
            root = sqrt(add)

            outputs['u'] = root

    model = Group()
    ivc = IndepVarComp()

    ivc.add_output('deficits', [0.16, 0.14, 0.15, 0.18])

    model.add_subsystem('indep', ivc)
    model.add_subsystem('rms', RSSMerge(4))

    model.connect('indep.deficits', 'rms.all_du')

    prob = Problem(model)
    prob.setup()
    prob.run_model()
    print(prob['rms.u'])
Example #22
0
    def test_multi_cycles(self):
        p = Problem(model=Group())
        root = p.model

        indep = root.add_subsystem("indep", IndepVarComp('x', 1.0))

        def make_cycle(root, start, end):
            # systems within a cycle will be declared out of order, but
            # should not be reported since they're internal to a cycle.
            for i in range(end, start - 1, -1):
                root.add_subsystem("C%d" % i, MyComp())

            for i in range(start, end):
                root.connect("C%d.y" % i, "C%d.a" % (i + 1))
            root.connect("C%d.y" % end, "C%d.a" % start)

        G1 = root.add_subsystem('G1', Group())

        make_cycle(G1, 1, 3)

        G1.add_subsystem("N1", MyComp())

        make_cycle(G1, 11, 13)

        G1.add_subsystem("N2", MyComp())

        make_cycle(G1, 21, 23)

        G1.add_subsystem("N3", MyComp())

        G1.connect("N1.z", "C12.b")
        G1.connect("C13.z", "N2.b")
        G1.connect("N2.z", "C21.b")
        G1.connect("C23.z", "N3.b")
        G1.connect("N3.z", "C2.b")
        G1.connect("C11.z", "C3.b")

        # set iterative solvers since we have cycles
        root.linear_solver = LinearBlockGS()
        root.nonlinear_solver = NonlinearBlockGS()

        testlogger = TestLogger()
        p.setup(check=True, logger=testlogger)

        # Conclude setup but don't run model.
        p.final_setup()

        warnings = testlogger.get('warning')
        self.assertEqual(len(warnings), 2)

        info = testlogger.get('info')
        self.assertEqual(len(info), 1)

        self.assertEqual(
            info[0],
            "The following groups contain cycles:\n   Group 'G1' has the following cycles: [['C13', 'C12', 'C11'], ['C23', 'C22', 'C21'], ['C3', 'C2', 'C1']]\n"
        )
        self.assertEqual(
            warnings[0],
            "The following systems are executed out-of-order:\n   System 'G1.C2' executes out-of-order with respect to its source systems ['G1.N3']\n   System 'G1.C3' executes out-of-order with respect to its source systems ['G1.C11']\n"
        )
        self.assertTrue(
            "The following inputs are not connected:" in warnings[1])
        self.connect('scale2.scaled', 'OperatingCost.rProp')
        self.connect('ToolingCost.toolCostPerVehicle',
                     'OperatingCost.toolingCost')
        self.connect('indep7.vehicle', 'OperatingCost.Vehicle')

        self.connect('ReserveMission.E', 'con1.EReserve')  # Constraint inputs
        self.connect('scale4.scaled', 'con1.mBattery')
        self.connect('HoverPower.hoverPower_PMax', 'con2.hoverPower_PMax')
        self.connect('scale5.scaled', 'con2.mMotors')
        self.connect('ConfigWeight.mass_W', 'con3.mass_W')
        self.connect('scale6.scaled', 'con3.mtow')


if __name__ == '__main__':
    # SubProblem: define a Problem to optimize the system
    sub = Problem(root=TopLevelSystem())

    # SubProblem: set up the optimizer
    sub.driver = ScipyOptimizer()
    sub.driver.options[
        'optimizer'] = 'COBYLA'  # The 'COBYLA' optimizer is supported by OpenMETA.
    # Unlike the 'SLSQP' optimizer, the 'COBYLA' optimizer doesn't require a Jacobian matrix.
    sub.driver.options['disp'] = True  # enable optimizer output
    sub.driver.options['maxiter'] = 1000
    sub.driver.options['tol'] = 0.01
    #sub.driver.opt_settings['rhobeg'] = 100.0

    # SubProblem: set design variables for sub.driver
    sub.driver.add_desvar('indep2.rProp', lower=30.0, upper=200.0)
    sub.driver.add_desvar('indep3.cruiseSpeed', lower=45.5, upper=80.0)
    sub.driver.add_desvar('indep4.batteryMass', lower=1.0, upper=99.90)
Example #24
0
    def test_guess_nonlinear_feature(self):
        from openmdao.api import Problem, Group, ImplicitComponent, IndepVarComp, NewtonSolver, ScipyKrylov

        class ImpWithInitial(ImplicitComponent):
            def setup(self):
                self.add_input('a', val=1.)
                self.add_input('b', val=1.)
                self.add_input('c', val=1.)
                self.add_output('x', val=0.)

                self.declare_partials(of='*', wrt='*')

            def apply_nonlinear(self, inputs, outputs, residuals):
                a = inputs['a']
                b = inputs['b']
                c = inputs['c']
                x = outputs['x']
                residuals['x'] = a * x**2 + b * x + c

            def solve_nonlinear(self, inputs, outputs):
                a = inputs['a']
                b = inputs['b']
                c = inputs['c']
                outputs['x'] = (-b + (b**2 - 4 * a * c)**0.5) / 2 / a

            def linearize(self, inputs, outputs, partials):
                a = inputs['a']
                b = inputs['b']
                c = inputs['c']
                x = outputs['x']

                partials['x', 'a'] = x**2
                partials['x', 'b'] = x
                partials['x', 'c'] = 1.0
                partials['x', 'x'] = 2 * a * x + b

                self.inv_jac = 1.0 / (2 * a * x + b)

            def solve_nonlinear(self, inputs, outputs):
                """ Do nothing. """
                pass

            def guess_nonlinear(self, inputs, outputs, resids):
                # Solution at 1 and 3. Default value takes us to -1 solution. Here
                # we set it to a value that will tke us to the 3 solution.
                outputs['x'] = 5.0

        prob = Problem()
        model = prob.model = Group()

        model.add_subsystem('pa', IndepVarComp('a', 1.0))
        model.add_subsystem('pb', IndepVarComp('b', 1.0))
        model.add_subsystem('pc', IndepVarComp('c', 1.0))
        model.add_subsystem('comp2', ImpWithInitial())
        model.connect('pa.a', 'comp2.a')
        model.connect('pb.b', 'comp2.b')
        model.connect('pc.c', 'comp2.c')

        model.nonlinear_solver = NewtonSolver()
        model.nonlinear_solver.options['solve_subsystems'] = True
        model.nonlinear_solver.options['max_sub_solves'] = 1
        model.linear_solver = ScipyKrylov()

        prob.setup(check=False)

        prob['pa.a'] = 1.
        prob['pb.b'] = -4.
        prob['pc.c'] = 3.

        prob.run_model()

        assert_rel_error(self, prob['comp2.x'], 3.)
Example #25
0
        # Compute the stall margins
        self.add_subsystem('stall_margins',
                           StallCalcs(),
                           promotes_inputs=[('PR_actual', 'PRmap'),
                                            ('Wc_actual', 'WcMap')],
                           promotes_outputs=['SMN', 'SMW'])
        self.connect('SMN_map.PRmap', 'stall_margins.PR_SMN')
        self.connect('SMW_map.PRmap', 'stall_margins.PR_SMW')
        self.connect('SMN_map.WcMap', 'stall_margins.Wc_SMN')


if __name__ == "__main__":
    from openmdao.api import Problem, IndepVarComp
    from pycycle.maps.ncp01 import NCP01

    p1 = Problem()
    ivc = p1.model.add_subsystem('ivc', IndepVarComp(), promotes=['*'])
    # Design variables
    ivc.add_output('alphaMap', 0.0)
    ivc.add_output('PR', 2.0)
    ivc.add_output('Nc', 1000.0, units='rpm')
    ivc.add_output('eff', .9)
    ivc.add_output('Wc', 3000., units='lbm/s')

    # Off-design variables
    # ivc.add_output('alphaMap', 0.0)
    # ivc.add_output('Nc', 1000.0, units='rpm')
    # ivc.add_output('Wc', 3000., units='lbm/s')
    # ivc.add_output('s_Nc', 1.0)
    # ivc.add_output('s_Wc', 1.0)
    # ivc.add_output('s_PR', 1.0)
Example #26
0
    def test_simple_list_vars_options(self):
        from openmdao.api import Group, Problem, IndepVarComp

        class QuadraticComp(ImplicitComponent):
            """
            A Simple Implicit Component representing a Quadratic Equation.

            R(a, b, c, x) = ax^2 + bx + c

            Solution via Quadratic Formula:
            x = (-b + sqrt(b^2 - 4ac)) / 2a
            """
            def setup(self):
                self.add_input('a', val=1., units='ft')
                self.add_input('b', val=1., units='inch')
                self.add_input('c', val=1., units='ft')
                self.add_output('x',
                                val=0.,
                                lower=1.0,
                                upper=100.0,
                                ref=1.1,
                                ref0=2.1,
                                units='inch')

                self.declare_partials(of='*', wrt='*')

            def apply_nonlinear(self, inputs, outputs, residuals):
                a = inputs['a']
                b = inputs['b']
                c = inputs['c']
                x = outputs['x']
                residuals['x'] = a * x**2 + b * x + c

            def solve_nonlinear(self, inputs, outputs):
                a = inputs['a']
                b = inputs['b']
                c = inputs['c']
                outputs['x'] = (-b + (b**2 - 4 * a * c)**0.5) / (2 * a)

        group = Group()

        comp1 = group.add_subsystem('comp1', IndepVarComp())
        comp1.add_output('a', 1.0, units='ft')
        comp1.add_output('b', 1.0, units='inch')
        comp1.add_output('c', 1.0, units='ft')

        sub = group.add_subsystem('sub', Group())
        sub.add_subsystem('comp2', QuadraticComp())
        sub.add_subsystem('comp3', QuadraticComp())

        group.connect('comp1.a', 'sub.comp2.a')
        group.connect('comp1.b', 'sub.comp2.b')
        group.connect('comp1.c', 'sub.comp2.c')

        group.connect('comp1.a', 'sub.comp3.a')
        group.connect('comp1.b', 'sub.comp3.b')
        group.connect('comp1.c', 'sub.comp3.c')

        global prob
        prob = Problem(model=group)
        prob.setup()

        prob['comp1.a'] = 1.
        prob['comp1.b'] = -4.
        prob['comp1.c'] = 3.
        prob.run_model()

        # list_inputs test
        stream = cStringIO()
        inputs = prob.model.list_inputs(values=False, out_stream=stream)
        text = stream.getvalue()
        self.assertEqual(sorted(inputs), [
            ('sub.comp2.a', {}),
            ('sub.comp2.b', {}),
            ('sub.comp2.c', {}),
            ('sub.comp3.a', {}),
            ('sub.comp3.b', {}),
            ('sub.comp3.c', {}),
        ])
        self.assertEqual(1, text.count("6 Input(s) in 'model'"))
        self.assertEqual(1, text.count("top"))
        self.assertEqual(1, text.count("  sub"))
        self.assertEqual(1, text.count("    comp2"))
        self.assertEqual(2, text.count("      a"))
        num_non_empty_lines = sum([1 for s in text.splitlines() if s.strip()])
        self.assertEqual(num_non_empty_lines, 14)

        # list_outputs tests
        # list implicit outputs
        outputs = prob.model.list_outputs(explicit=False, out_stream=None)
        text = stream.getvalue()
        self.assertEqual(sorted(outputs), [('sub.comp2.x', {
            'value': [3.]
        }), ('sub.comp3.x', {
            'value': [3.]
        })])
        # list explicit outputs
        stream = cStringIO()
        outputs = prob.model.list_outputs(implicit=False, out_stream=None)
        self.assertEqual(sorted(outputs), [
            ('comp1.a', {
                'value': [1.]
            }),
            ('comp1.b', {
                'value': [-4.]
            }),
            ('comp1.c', {
                'value': [3.]
            }),
        ])
    def test_brachistochrone_quick_start(self):
        import numpy as np
        from openmdao.api import Problem, Group, ScipyOptimizeDriver
        import dymos as dm
        import matplotlib
        matplotlib.use('Agg')
        import matplotlib.pyplot as plt

        #
        # Define the OpenMDAO problem
        #
        p = Problem(model=Group())

        #
        # Define a Trajectory object
        #
        traj = dm.Trajectory()

        p.model.add_subsystem('traj', subsys=traj)

        #
        # Define a Dymos Phase object with GaussLobatto Transcription
        #
        phase = dm.Phase(ode_class=BrachistochroneODE,
                         transcription=dm.GaussLobatto(num_segments=10, order=3))

        traj.add_phase(name='phase0', phase=phase)

        #
        # Set the time options
        # Time has no targets in our ODE.
        # We fix the initial time so that the it is not a design variable in the optimization.
        # The duration of the phase is allowed to be optimized, but is bounded on [0.5, 10].
        #
        phase.set_time_options(fix_initial=True, duration_bounds=(0.5, 10.0), units='s')

        #
        # Set the time options
        # Initial values of positions and velocity are all fixed.
        # The final value of position are fixed, but the final velocity is a free variable.
        # The equations of motion are not functions of position, so 'x' and 'y' have no targets.
        # The rate source points to the output in the ODE which provides the time derivative of the
        # given state.
        phase.set_state_options('x', fix_initial=True, fix_final=True, units='m', rate_source='xdot')
        phase.set_state_options('y', fix_initial=True, fix_final=True, units='m', rate_source='ydot')
        phase.set_state_options('v', fix_initial=True, fix_final=False, units='m/s',
                                rate_source='vdot', targets=['v'])

        # Define theta as a control.
        phase.add_control(name='theta', units='rad', lower=0, upper=np.pi, targets=['theta'])

        # Minimize final time.
        phase.add_objective('time', loc='final')

        # Set the driver.
        p.driver = ScipyOptimizeDriver()

        # Allow OpenMDAO to automatically determine our sparsity pattern.
        # Doing so can significant speed up the execution of Dymos.
        p.driver.options['dynamic_simul_derivs'] = True

        # Setup the problem
        p.setup(check=True)

        # Now that the OpenMDAO problem is setup, we can set the values of the states.
        p.set_val('traj.phase0.states:x',
                  phase.interpolate(ys=[0, 10], nodes='state_input'),
                  units='m')

        p.set_val('traj.phase0.states:y',
                  phase.interpolate(ys=[10, 5], nodes='state_input'),
                  units='m')

        p.set_val('traj.phase0.states:v',
                  phase.interpolate(ys=[0, 5], nodes='state_input'),
                  units='m/s')

        p.set_val('traj.phase0.controls:theta',
                  phase.interpolate(ys=[90, 90], nodes='control_input'),
                  units='deg')

        # Run the driver to solve the problem
        p.run_driver()

        # Check the validity of our results by using scipy.integrate.solve_ivp to
        # integrate the solution.
        sim_out = traj.simulate()

        # Plot the results
        fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(12, 4.5))

        axes[0].plot(p.get_val('traj.phase0.timeseries.states:x'),
                     p.get_val('traj.phase0.timeseries.states:y'),
                     'ro', label='solution')

        axes[0].plot(sim_out.get_val('traj.phase0.timeseries.states:x'),
                     sim_out.get_val('traj.phase0.timeseries.states:y'),
                     'b-', label='simulation')

        axes[0].set_xlabel('x (m)')
        axes[0].set_ylabel('y (m/s)')
        axes[0].legend()
        axes[0].grid()

        axes[1].plot(p.get_val('traj.phase0.timeseries.time'),
                     p.get_val('traj.phase0.timeseries.controls:theta', units='deg'),
                     'ro', label='solution')

        axes[1].plot(sim_out.get_val('traj.phase0.timeseries.time'),
                     sim_out.get_val('traj.phase0.timeseries.controls:theta', units='deg'),
                     'b-', label='simulation')

        axes[1].set_xlabel('time (s)')
        axes[1].set_ylabel(r'$\theta$ (deg)')
        axes[1].legend()
        axes[1].grid()

        plt.show()
    def test_multi_cycles_non_default(self):
        p = Problem()
        root = p.model

        root.add_subsystem("indep", IndepVarComp('x', 1.0))

        def make_cycle(root, start, end):
            # systems within a cycle will be declared out of order, but
            # should not be reported since they're internal to a cycle.
            for i in range(end, start - 1, -1):
                root.add_subsystem("C%d" % i, MyComp())

            for i in range(start, end):
                root.connect("C%d.y" % i, "C%d.a" % (i + 1))
            root.connect("C%d.y" % end, "C%d.a" % start)

        G1 = root.add_subsystem('G1', Group())

        make_cycle(G1, 1, 3)

        G1.add_subsystem("N1", MyComp())

        make_cycle(G1, 11, 13)

        G1.add_subsystem("N2", MyComp())

        make_cycle(G1, 21, 23)

        G1.add_subsystem("N3", MyComp())

        G1.connect("N1.z", "C12.b")
        G1.connect("C13.z", "N2.b")
        G1.connect("N2.z", "C21.b")
        G1.connect("C23.z", "N3.b")
        G1.connect("N3.z", "C2.b")
        G1.connect("C11.z", "C3.b")

        # set iterative solvers since we have cycles
        root.linear_solver = LinearBlockGS()
        root.nonlinear_solver = NonlinearBlockGS()

        testlogger = TestLogger()
        p.setup(check=['cycles', 'out_of_order', 'unconnected_inputs'],
                logger=testlogger)
        p.final_setup()

        expected_info = (
            "The following groups contain cycles:\n"
            "   Group 'G1' has the following cycles: "
            "[['C13', 'C12', 'C11'], ['C23', 'C22', 'C21'], ['C3', 'C2', 'C1']]\n"
        )

        expected_warning_1 = (
            "The following systems are executed out-of-order:\n"
            "   System 'G1.C2' executes out-of-order with respect to its source systems ['G1.N3']\n"
            "   System 'G1.C3' executes out-of-order with respect to its source systems ['G1.C11']\n"
        )

        expected_warning_2 = ('The following inputs are not connected:\n'
                              '   G1.C1.b      [ 1.]\n'
                              '   G1.C11.b     [ 1.]\n'
                              '   G1.C13.b     [ 1.]\n'
                              '   G1.C22.b     [ 1.]\n'
                              '   G1.C23.b     [ 1.]\n'
                              '   G1.N1.a      [ 1.]\n'
                              '   G1.N1.b      [ 1.]\n'
                              '   G1.N2.a      [ 1.]\n'
                              '   G1.N3.a      [ 1.]\n')

        testlogger.find_in('info', expected_info)
        testlogger.find_in('warning', expected_warning_1)
        testlogger.find_in('warning', expected_warning_2)
Example #29
0
        in_name = self.options['in_name']
        out_name = self.options['out_name']
        partials[out_name, in_name] = 1.0 - (
            (1.0 / np.tanh(inputs[in_name]))**2).flatten()


if __name__ == "__main__":
    from openmdao.api import Problem, IndepVarComp, Group
    n = 100
    val = np.random.rand(n)
    indeps = IndepVarComp()
    indeps.add_output(
        'x',
        val=val,
        shape=(n, ),
    )
    prob = Problem()
    prob.model = Group()
    prob.model.add_subsystem(
        'indeps',
        indeps,
        promotes=['*'],
    )
    prob.model.add_subsystem(
        'coth',
        CotanhComp(in_name='x', out_name='y', shape=(n, )),
        promotes=['*'],
    )
    prob.setup()
    prob.check_partials(compact_print=True)
Example #30
0
    def simulate(self,
                 times_per_seg=10,
                 method='RK45',
                 atol=1.0E-9,
                 rtol=1.0E-9,
                 record_file=None):
        """
        Simulate the Trajectory using scipy.integrate.solve_ivp.

        Parameters
        ----------
        times_per_seg : int or None
            Number of equally spaced times per segment at which output is requested.  If None,
            output will be provided at all Nodes.
        method : str
            The scipy.integrate.solve_ivp integration method.
        atol : float
            Absolute convergence tolerance for scipy.integrate.solve_ivp.
        rtol : float
            Relative convergence tolerance for scipy.integrate.solve_ivp.
        record_file : str or None
            If a string, the file to which the result of the simulation will be saved.
            If None, no record of the simulation will be saved.

        Returns
        -------
        problem
            An OpenMDAO Problem in which the simulation is implemented.  This Problem interface
            can be interrogated to obtain timeseries outputs in the same manner as other Phases
            to obtain results at the requested times.
        """
        sim_traj = Trajectory()

        for name, phs in iteritems(self._phases):
            sim_phs = phs.get_simulation_phase(times_per_seg=times_per_seg,
                                               method=method,
                                               atol=atol,
                                               rtol=rtol)
            sim_traj.add_phase(name, sim_phs)

        sim_traj.design_parameter_options.update(self.design_parameter_options)
        sim_traj.input_parameter_options.update(self.input_parameter_options)

        sim_prob = Problem(model=Group())

        sim_prob.model.add_subsystem(self.name, sim_traj)

        if record_file is not None:
            rec = SqliteRecorder(record_file)
            sim_prob.model.recording_options['includes'] = ['*.timeseries.*']
            sim_prob.model.add_recorder(rec)

        sim_prob.setup(check=True)

        traj_op_dict = dict([
            (name, opts)
            for (name, opts) in self.list_outputs(units=True, out_stream=None)
        ])

        # Assign trajectory design parameter values
        for name, options in iteritems(self.design_parameter_options):
            op = traj_op_dict['{0}.design_params.design_parameters:{1}'.format(
                self.pathname, name)]
            var_name = '{0}.design_parameters:{1}'.format(self.name, name)
            sim_prob[var_name] = op['value'][0, ...]

        # Assign trajectory input parameter values
        for name, options in iteritems(self.input_parameter_options):
            op = traj_op_dict[
                '{0}.input_params.input_parameters:{1}_out'.format(
                    self.pathname, name)]
            var_name = '{0}.input_parameters:{1}'.format(self.name, name)
            sim_prob[var_name] = op['value'][0, ...]

        for phase_name, phs in iteritems(sim_traj._phases):
            phs.initialize_values_from_phase(sim_prob,
                                             self._phases[phase_name])

        print('\nSimulating trajectory {0}'.format(self.pathname))
        sim_prob.run_model()
        print('Done simulating trajectory {0}'.format(self.pathname))

        return sim_prob