def transfer_loads(def_mesh, sec_forces, comp): """ Perform aerodynamic load transfer. Apply the computed sectional forces on the aerodynamic surfaces to obtain the deformed mesh FEM loads. Parameters ---------- def_mesh[nx, ny, 3] : numpy array Flattened array defining the lifting surfaces after deformation. sec_forces[nx-1, ny-1, 3] : numpy array Flattened array containing the sectional forces acting on each panel. Stored in Fortran order (only relevant when more than one chordwise panel). comp : Either OpenAeroStruct component object (better), or surface dict. Returns ------- loads[ny, 6] : numpy array Flattened array containing the loads applied on the FEM component, computed from the sectional forces. """ if not isinstance(comp, Component): surface = comp comp = TransferLoads(surface) params = {'def_mesh': def_mesh, 'sec_forces': sec_forces} unknowns = {'loads': np.zeros((comp.ny, 6), dtype=complex)} resids = None comp.solve_nonlinear(params, unknowns, resids) loads = unknowns.get('loads') return loads
def __init__(self, num_x, num_y, num_w, E, G, mrho, fem_origin, SBEIG, t): super(SingleStep, self).__init__() name_def_mesh = 'def_mesh_%d' % t name_vlmstates = 'vlmstates_%d' % t name_loads = 'loads_%d' % t name_spatialbeamstates = 'spatialbeamstates_%d' % t self.add_subsystem(name_def_mesh, TransferDisplacements(nx=num_x, n=num_y, t=t, fem_origin=fem_origin), promotes=['*']) self.add_subsystem(name_vlmstates, UVLMStates(num_x, num_y, num_w, t), promotes=['*']) self.add_subsystem(name_loads, TransferLoads(nx=num_x, n=num_y, t=t, fem_origin=fem_origin), promotes=['*']) self.add_subsystem(name_spatialbeamstates, SpatialBeamStates(num_x, num_y, E, G, mrho, SBEIG, t), promotes=['*'])
def transfer_loads(def_mesh, sec_forces, comp): """ Perform aerodynamic load transfer. Apply the computed sectional forces on the aerodynamic surfaces to obtain the deformed mesh FEM loads. Parameters ---------- def_mesh[nx, ny, 3] : numpy array Flattened array defining the lifting surfaces after deformation. sec_forces[nx-1, ny-1, 3] : numpy array Flattened array containing the sectional forces acting on each panel. Stored in Fortran order (only relevant when more than one chordwise panel). comp : Either OpenAeroStruct component object (better), or surface dict. Returns ------- loads[ny, 6] : numpy array Flattened array containing the loads applied on the FEM component, computed from the sectional forces. """ if not isinstance(comp, Component): surface = comp comp=TransferLoads(surface) params={ 'def_mesh': def_mesh, 'sec_forces': sec_forces } unknowns={ 'loads': np.zeros((comp.ny, 6), dtype=complex) } resids=None comp.solve_nonlinear(params, unknowns, resids) loads=unknowns.get('loads') return loads
def __init__(self, num_x, num_y, num_w, E, G, mrho, fem_origin, t): super(SingleAeroStep, self).__init__() name_def_mesh = 'def_mesh_%d' % t name_vlmstates = 'vlmstates_%d' % t name_loads = 'loads_%d' % t name_spatialbeamstates = 'spatialbeamstates_%d' % t self.add(name_def_mesh, TransferDisplacements(num_x, num_y, t, fem_origin), promotes=['*']) self.add(name_vlmstates, UVLMStates(num_x, num_y, num_w, t), promotes=['*']) self.add(name_loads, TransferLoads(num_x, num_y, t, fem_origin), promotes=['*'])
] ############################################################### # Problem 2a: # These are your components. Here we simply create the objects. ############################################################### indep_vars_comp = IndepVarComp(indep_vars) tube_comp = MaterialsTube(surface) mesh_comp = GeometryMesh(surface) geom_comp = VLMGeometry(surface) spatialbeamstates_comp = SpatialBeamStates(surface) def_mesh_comp = TransferDisplacements(surface) vlmstates_comp = VLMStates(OAS_prob.surfaces, OAS_prob.prob_dict) loads_comp = TransferLoads(surface) vlmfuncs_comp = VLMFunctionals(surface) spatialbeamfuncs_comp = SpatialBeamFunctionals(surface) fuelburn_comp = FunctionalBreguetRange(OAS_prob.surfaces, OAS_prob.prob_dict) eq_con_comp = FunctionalEquilibrium(OAS_prob.surfaces, OAS_prob.prob_dict) ################################################################# # Problem 2a: # Now add the components you created above to the correct groups. # indep_vars_comp, tube_comp, and vlm_funcs have been # done for you as examples. ################################################################# # Add functional components here
('twist', numpy.zeros(num_y)), ('v', v), ('alpha', alpha), ('rho', rho), ('r', r), ('t', t), ] indep_vars_comp = IndepVarComp(indep_vars) tube_comp = MaterialsTube(num_y) mesh_comp = GeometryMesh(mesh, aero_ind, num_twist) spatialbeamstates_comp = SpatialBeamStates(num_y, E, G) def_mesh_comp = TransferDisplacements(num_y) vlmstates_comp = VLMStates(num_y) loads_comp = TransferLoads(num_y) vlmfuncs_comp = VLMFunctionals(num_y, CL0, CD0) spatialbeamfuncs_comp = SpatialBeamFunctionals(num_y, E, G, stress, mrho) fuelburn_comp = FunctionalBreguetRange(W0, CT, a, R, M) eq_con_comp = FunctionalEquilibrium(W0) root.add('indep_vars', indep_vars_comp, promotes=['*']) root.add('tube', tube_comp, promotes=['*']) # Add components to the MDA here coupled = Group() coupled.add('mesh', mesh_comp, promotes=["*"]) coupled.add('spatialbeamstates', spatialbeamstates_comp, promotes=["*"]) coupled.add('def_mesh', def_mesh_comp, promotes=["*"]) coupled.add('vlmstates', vlmstates_comp, promotes=["*"])
def aero(def_mesh=None, params=None): if (params is None) or (def_mesh is None): tmpmesh, params = setup() if not def_mesh: def_mesh = tmpmesh # Unpack variables mesh = params.get('mesh') num_x = params.get('num_x') num_y = params.get('num_y') span = params.get('span') twist_cp = params.get('twist_cp') thickness_cp = params.get('thickness_cp') v = params.get('v') alpha = params.get('alpha') rho = params.get('rho') r = params.get('r') t = params.get('t') aero_ind = params.get('aero_ind') fem_ind = params.get('fem_ind') num_thickness = params.get('num_thickness') num_twist = params.get('num_twist') sweep = params.get('sweep') taper = params.get('taper') disp = params.get('disp') dihedral = params.get('dihedral') check = params.get('check') out_stream = params.get('out_stream') # Define Jacobians for b-spline controls tot_n_fem = np.sum(fem_ind[:, 0]) num_surf = fem_ind.shape[0] jac_twist = get_bspline_mtx(num_twist, num_y) jac_thickness = get_bspline_mtx(num_thickness, tot_n_fem - num_surf) disp = np.zeros((num_y, 6)) # for display? # Define the design variables des_vars = [('twist_cp', np.zeros(num_twist)), ('dihedral', dihedral), ('sweep', sweep), ('span', span), ('taper', taper), ('v', v), ('alpha', alpha), ('rho', rho), ('disp', np.zeros((tot_n_fem, 6))), ('def_mesh', def_mesh)] root = Group() root.add('des_vars', IndepVarComp(des_vars), promotes=[ 'twist_cp', 'span', 'v', 'alpha', 'rho', 'disp', 'dihedral', 'def_mesh' ]) # root.add('twist_bsp', # What is this doing? # Bspline('twist_cp', 'twist', jac_twist), # promotes=['*']) # root.add('thickness_bsp', # What is this doing? # Bspline('thickness_cp', 'thickness', jac_thickness), # promotes=['*']) # root.add('tube', # MaterialsTube(fem_ind), # promotes=['*']) root.add( 'VLMstates', VLMStates(aero_ind), promotes=[ 'def_mesh', 'b_pts', 'mid_b', 'c_pts', 'widths', 'normals', 'S_ref', # VLMGeometry 'alpha', 'circulations', 'v', # VLMCirculations 'rho', 'sec_forces' # VLMForces ]) root.add('loads', TransferLoads(aero_ind, fem_ind), promotes=['def_mesh', 'sec_forces', 'loads']) prob = Problem() prob.root = root prob.setup(check=check, out_stream=out_stream) prob.run() return prob['loads'] # Output the Loads matrix
root.add('tube', MaterialsTube(num_y), promotes=['*']) coupled = Group() # add components for MDA to this group coupled.add('mesh', GeometryMesh(mesh, aero_ind, num_twist), promotes=['*']) coupled.add('def_mesh', TransferDisplacements(num_y), promotes=['*']) coupled.add('vlmstates', VLMStates(num_y), promotes=['*']) coupled.add('loads', TransferLoads(num_y), promotes=['*']) coupled.add('spatialbeamstates', SpatialBeamStates(num_y, cons, E, G), promotes=['*']) coupled.nl_solver = Newton() coupled.nl_solver.options['iprint'] = 1 coupled.nl_solver.line_search.options['iprint'] = 1 # LNGS Solver # coupled.ln_solver = LinearGaussSeidel() # coupled.ln_solver.options['maxiter'] = 100 # Krylov Solver - No preconditioning # coupled.ln_solver = ScipyGMRES()
############################################################ # These are your components, put them in the correct groups. # indep_vars_comp, tube_comp, and weiss_func_comp have been # done for you as examples ############################################################ indep_vars_comp = IndepVarComp(indep_vars) twist_comp = Bspline('twist_cp', 'twist', jac_twist) thickness_comp = Bspline('thickness_cp', 'thickness', jac_thickness) tube_comp = MaterialsTube(fem_ind) mesh_comp = GeometryMesh(mesh, aero_ind) spatialbeamstates_comp = SpatialBeamStates(aero_ind, fem_ind, E, G) def_mesh_comp = TransferDisplacements(aero_ind, fem_ind) vlmstates_comp = VLMStates(aero_ind) loads_comp = TransferLoads(aero_ind, fem_ind) vlmfuncs_comp = VLMFunctionals(aero_ind, CL0, CD0) spatialbeamfuncs_comp = SpatialBeamFunctionals(aero_ind, fem_ind, E, G, stress, mrho) fuelburn_comp = FunctionalBreguetRange(W0, CT, a, R, M, aero_ind) eq_con_comp = FunctionalEquilibrium(W0, aero_ind) ############################################################ ############################################################ root.add('indep_vars', indep_vars_comp, promotes=['*']) root.add('twist_bsp', twist_comp, promotes=['*'])
def setup(prob_dict={}, surfaces=[{}]): ''' Setup the aerostruct mesh Default wing mesh (single lifting surface): ------------------------------------------- name = 'wing' # name of the surface num_x = 3 # number of chordwise points num_y = 5 # number of spanwise points root_chord = 1. # root chord span_cos_spacing = 1 # 0 for uniform spanwise panels # 1 for cosine-spaced panels # any value between 0 and 1 for a mixed spacing chord_cos_spacing = 0. # 0 for uniform chordwise panels # 1 for cosine-spaced panels # any value between 0 and 1 for a mixed spacing wing_type = 'rect' # initial shape of the wing either 'CRM' or 'rect' # 'CRM' can have different options after it, such as 'CRM:alpha_2.75' for the CRM shape at alpha=2.75 offset = np.array([0., 0., 0.]) # coordinates to offset the surface from its default location symmetry = True # if true, model one half of wing reflected across the plane y = 0 S_ref_type = 'wetted' # 'wetted' or 'projected' # Simple Geometric Variables span = 10. # full wingspan dihedral = 0. # wing dihedral angle in degrees positive is upward sweep = 0. # wing sweep angle in degrees positive sweeps back taper = 1. # taper ratio; 1. is uniform chord # B-spline Geometric Variables. The number of control points for each of these variables can be specified in surf_dict # by adding the prefix "num" to the variable (e.g. num_twist) twist_cp = None chord_cp = None xshear_cp = None zshear_cp = None thickness_cp = None Default wing parameters: ------------------------ Zero-lift aerodynamic performance CL0 = 0.0 # CL value at AoA (alpha) = 0 CD0 = 0.0 # CD value at AoA (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 = 0.12 # thickness over chord ratio (NACA0012) c_max_t = .303 # chordwise location of maximum (NACA0012) thickness Structural values are based on aluminum E = 70.e9 # [Pa] Young's modulus of the spar G = 30.e9 # [Pa] shear modulus of the spar stress = 20.e6 # [Pa] yield stress mrho = 3.e3 # [kg/m^3] material density fem_origin = 0.35 # chordwise location of the spar Other W0 = 0.4 * 3e5 # [kg] MTOW of B777 is 3e5 kg with fuel Default problem parameters: --------------------------- Re = 1e6 # Reynolds number reynolds_length = 1.0 # characteristic Reynolds length alpha = 5. # angle of attack CT = 9.80665 * 17.e-6 # [1/s] (9.81 N/kg * 17e-6 kg/N/s) R = 14.3e6 # [m] maximum range M = 0.84 # Mach number at cruise rho = 0.38 # [kg/m^3] air density at 35,000 ft a = 295.4 # [m/s] speed of sound at 35,000 ft with_viscous = False # if true, compute viscous drag ''' # Use steps in run_aerostruct.py to add wing surface to problem # Set problem type prob_dict.update({ 'type': 'aerostruct' }) # this doesn't really matter since we aren't calling OASProblem.setup() # Instantiate problem OAS_prob = OASProblem(prob_dict) for surface in surfaces: # Add SpatialBeamFEM size FEMsize = 6 * surface['num_y'] + 6 surface.update({'FEMsize': FEMsize}) # Add the specified wing surface to the problem. OAS_prob.add_surface(surface) # Add materials properties for the wing surface to the surface dict in OAS_prob for idx, surface in enumerate(OAS_prob.surfaces): A, Iy, Iz, J = materials_tube(surface['radius'], surface['thickness'], surface) OAS_prob.surfaces[idx].update({'A': A, 'Iy': Iy, 'Iz': Iz, 'J': J}) # Get total panels and save in prob_dict tot_panels = 0 for surface in OAS_prob.surfaces: ny = surface['num_y'] nx = surface['num_x'] tot_panels += (nx - 1) * (ny - 1) OAS_prob.prob_dict.update({'tot_panels': tot_panels}) # Assume we are only using a single lifting surface for now surface = OAS_prob.surfaces[0] # Initialize the OpenAeroStruct components and save them in a component dictionary comp_dict = {} comp_dict['MaterialsTube'] = MaterialsTube(surface) comp_dict['GeometryMesh'] = GeometryMesh(surface) comp_dict['TransferDisplacements'] = TransferDisplacements(surface) comp_dict['VLMGeometry'] = VLMGeometry(surface) comp_dict['AssembleAIC'] = AssembleAIC([surface]) comp_dict['AeroCirculations'] = AeroCirculations( OAS_prob.prob_dict['tot_panels']) comp_dict['VLMForces'] = VLMForces([surface]) comp_dict['TransferLoads'] = TransferLoads(surface) comp_dict['ComputeNodes'] = ComputeNodes(surface) comp_dict['AssembleK'] = AssembleK(surface) comp_dict['SpatialBeamFEM'] = SpatialBeamFEM(surface['FEMsize']) comp_dict['SpatialBeamDisp'] = SpatialBeamDisp(surface) OAS_prob.comp_dict = comp_dict return OAS_prob
tot_panels += (nx - 1) * (ny - 1) OAS_prob.prob_dict.update({'tot_panels': tot_panels}) # Assume we are only using a single lifting surface for now surface = OAS_prob.surfaces[0] # Initialize the OpenAeroStruct components and save them in a component dictionary comp_dict = {} comp_dict['MaterialsTube'] = MaterialsTube(surface) comp_dict['GeometryMesh'] = GeometryMesh(surface) comp_dict['TransferDisplacements'] = TransferDisplacements(surface) comp_dict['VLMGeometry'] = VLMGeometry(surface) comp_dict['AssembleAIC'] = AssembleAIC([surface]) comp_dict['AeroCirculations'] = AeroCirculations(OAS_prob.prob_dict['tot_panels']) comp_dict['VLMForces'] = VLMForces([surface]) comp_dict['TransferLoads'] = TransferLoads(surface) comp_dict['ComputeNodes'] = ComputeNodes(surface) comp_dict['AssembleK'] = AssembleK(surface) comp_dict['SpatialBeamFEM'] = SpatialBeamFEM(surface['FEMsize']) comp_dict['SpatialBeamDisp'] = SpatialBeamDisp(surface) OAS_prob.comp_dict = comp_dict <<<<<<< HEAD # return the surfaces list, problem dict, and component dict surfaces = [surface] prob_dict = OAS_prob.prob_dict # return surfaces, prob_dict, comp_dict ======= >>>>>>> 7eefd15e6c26c95cbbd9f303d23ecb4716c2fea3 return OAS_prob