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
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)
(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()
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)
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'])
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)
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)
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')
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
# -*- 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)
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]))
def create_problem(magdrag): root = Group() prob = Problem(root) prob.root.add('comp', magdrag) return prob
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.')
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()
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()
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)
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")
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'])
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)
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.)
# 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)
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)
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)
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