def setup(self): surfaces = self.options['surfaces'] rotational = self.options['rotational'] num_collocation_points = 0 for surface in surfaces: mesh = surface['mesh'] nx = self.nx = mesh.shape[0] ny = self.ny = mesh.shape[1] num_collocation_points += (ny - 1) * (nx - 1) num_force_points = num_collocation_points # Get collocation points self.add_subsystem( 'collocation_points', CollocationPoints(surfaces=surfaces), promotes_inputs=['*'], promotes_outputs=['coll_pts', 'force_pts', 'bound_vecs']) # Compute the vortex mesh based off the deformed aerodynamic mesh self.add_subsystem('vortex_mesh', VortexMesh(surfaces=surfaces), promotes_inputs=['*'], promotes_outputs=['*']) # Get vectors from mesh points to collocation points self.add_subsystem('get_vectors', GetVectors(surfaces=surfaces, num_eval_points=num_collocation_points, eval_name='coll_pts'), promotes_inputs=['*'], promotes_outputs=['*']) # Construct matrix based on rings, not horseshoes self.add_subsystem('mtx_assy', EvalVelMtx(surfaces=surfaces, num_eval_points=num_collocation_points, eval_name='coll_pts'), promotes_inputs=['*'], promotes_outputs=['*']) # Convert freestream velocity to array of velocities if rotational: self.add_subsystem('rotational_velocity', RotationalVelocity(surfaces=surfaces), promotes_inputs=['*'], promotes_outputs=['*']) self.add_subsystem('convert_velocity', ConvertVelocity(surfaces=surfaces, rotational=rotational), promotes_inputs=['*'], promotes_outputs=['*']) # Construct RHS and full matrix of system self.add_subsystem('mtx_rhs', VLMMtxRHSComp(surfaces=surfaces), promotes_inputs=['*'], promotes_outputs=['*']) # Solve Mtx RHS to get ring circs self.add_subsystem('solve_matrix', SolveMatrix(surfaces=surfaces), promotes_inputs=['*'], promotes_outputs=['*']) # Convert ring circs to horseshoe circs self.add_subsystem('horseshoe_circulations', HorseshoeCirculations(surfaces=surfaces), promotes_inputs=['*'], promotes_outputs=['*']) # Eval force vectors self.add_subsystem('get_vectors_force', GetVectors(surfaces=surfaces, num_eval_points=num_force_points, eval_name='force_pts'), promotes_inputs=['*'], promotes_outputs=['*']) # Set up force mtx self.add_subsystem('mtx_assy_forces', EvalVelMtx(surfaces=surfaces, num_eval_points=num_force_points, eval_name='force_pts'), promotes_inputs=['*'], promotes_outputs=['*']) # Multiply by horseshoe circs to get velocities self.add_subsystem('eval_velocities', EvalVelocities(surfaces=surfaces, num_eval_points=num_force_points, eval_name='force_pts'), promotes_inputs=['*'], promotes_outputs=['*']) # Get sectional panel forces self.add_subsystem('panel_forces', PanelForces(surfaces=surfaces), promotes_inputs=['*'], promotes_outputs=['*']) # Get panel forces for each lifting surface individually self.add_subsystem('panel_forces_surf', PanelForcesSurf(surfaces=surfaces), promotes_inputs=['*'], promotes_outputs=['*']) # Get nodal forces for each lifting surface individually self.add_subsystem('mesh_point_forces_surf', MeshPointForces(surfaces=surfaces), promotes_inputs=['*'], promotes_outputs=['*'])
def test_groundplane(self): surfaces = get_ground_effect_surfaces() comp = VortexMesh(surfaces=surfaces) run_test(self, comp, atol=1e6)
def setup(self): surfaces = self.options['surfaces'] rotational = self.options['rotational'] num_collocation_points = 0 for surface in surfaces: mesh = surface['mesh'] nx = self.nx = mesh.shape[0] ny = self.ny = mesh.shape[1] num_collocation_points += (ny - 1) * (nx - 1) num_force_points = num_collocation_points #---------------------------------------------------------------- # Step 0: Need to calculate a few things prior to transformation. #---------------------------------------------------------------- # Get collocation points self.add_subsystem('collocation_points', CollocationPoints(surfaces=surfaces), promotes_inputs=['*']) # Convert freestream velocity to array of velocities if rotational: self.add_subsystem('rotational_velocity', RotationalVelocity(surfaces=surfaces), promotes_inputs=['cg', 'omega']) self.connect('collocation_points.coll_pts', 'rotational_velocity.coll_pts') #---------------------------------------- # Step 1: Transform geometry to PG domain #---------------------------------------- self.connect('collocation_points.coll_pts', 'pg_transform.coll_pts') self.connect('collocation_points.bound_vecs', 'pg_transform.bound_vecs') self.connect('collocation_points.force_pts', 'pg_transform.force_pts') if rotational: self.connect('rotational_velocity.rotational_velocities', 'pg_transform.rotational_velocities') prom_in = ['alpha', 'beta', 'Mach_number'] for surface in surfaces: name = surface['name'] vname = name + '_def_mesh' prom_in.append(vname) self.connect('pg_transform.' + vname + '_pg', 'vortex_mesh.' + vname) vname = name + '_normals' prom_in.append(vname) self.connect('pg_transform.' + vname + '_pg', 'mtx_rhs.' + vname) self.add_subsystem('pg_transform', PGTransform(surfaces=surfaces, rotational=rotational), promotes_inputs=prom_in) self.connect('pg_transform.coll_pts_pg', 'coll_pts') self.connect('pg_transform.bound_vecs_pg', 'bound_vecs') self.connect('pg_transform.force_pts_pg', 'force_pts') if rotational: self.connect('pg_transform.rotational_velocities_pg', 'rotational_velocities') #--------------------------------------------------- # Step 2: Solve incompressible problem in PG domain #--------------------------------------------------- # Compute the vortex mesh based off the deformed aerodynamic mesh self.add_subsystem('vortex_mesh', VortexMesh(surfaces=surfaces), promotes_outputs=['*']) # Get vectors from mesh points to collocation points self.add_subsystem('get_vectors', GetVectors(surfaces=surfaces, num_eval_points=num_collocation_points, eval_name='coll_pts'), promotes_inputs=['*'], promotes_outputs=['*']) # In the PG domain, alpha and beta are zero. indep_var_comp = IndepVarComp() indep_var_comp.add_output('alpha_pg', val=0., units='deg') indep_var_comp.add_output('beta_pg', val=0., units='deg') self.add_subsystem('pg_frame', indep_var_comp) # Construct matrix based on rings, not horseshoes self.add_subsystem('mtx_assy', EvalVelMtx(surfaces=surfaces, num_eval_points=num_collocation_points, eval_name='coll_pts'), promotes_inputs=['*_vectors'], promotes_outputs=['*']) self.connect('pg_frame.alpha_pg', 'mtx_assy.alpha') # Convert freestream velocity to array of velocities # Note, don't want to promote Alpha or Beta here because we are in the transformed system. prom_in = ['v'] if rotational: prom_in.append('rotational_velocities') self.add_subsystem('convert_velocity', ConvertVelocity(surfaces=surfaces, rotational=rotational), promotes_inputs=prom_in, promotes_outputs=['*']) self.connect('pg_frame.alpha_pg', 'convert_velocity.alpha') self.connect('pg_frame.beta_pg', 'convert_velocity.beta') # Construct RHS and full matrix of system self.add_subsystem( 'mtx_rhs', VLMMtxRHSComp(surfaces=surfaces), promotes_inputs=['freestream_velocities', '*coll_pts_vel_mtx'], promotes_outputs=['*']) # Solve Mtx RHS to get ring circs self.add_subsystem('solve_matrix', SolveMatrix(surfaces=surfaces), promotes_inputs=['*'], promotes_outputs=['*']) # Convert ring circs to horseshoe circs self.add_subsystem('horseshoe_circulations', HorseshoeCirculations(surfaces=surfaces), promotes_inputs=['*'], promotes_outputs=['*']) # Eval force vectors self.add_subsystem('get_vectors_force', GetVectors(surfaces=surfaces, num_eval_points=num_force_points, eval_name='force_pts'), promotes_inputs=['*'], promotes_outputs=['*']) # Set up force mtx # Note, don't want to promote Alpha here because we are in the transformed system. self.add_subsystem('mtx_assy_forces', EvalVelMtx(surfaces=surfaces, num_eval_points=num_force_points, eval_name='force_pts'), promotes_inputs=['*_force_pts_vectors'], promotes_outputs=['*']) self.connect('pg_frame.alpha_pg', 'mtx_assy_forces.alpha') # Multiply by horseshoe circs to get velocities self.add_subsystem('eval_velocities', EvalVelocities(surfaces=surfaces, num_eval_points=num_force_points, eval_name='force_pts'), promotes_inputs=['*'], promotes_outputs=['*']) # Get sectional panel forces self.add_subsystem('panel_forces', PanelForces(surfaces=surfaces), promotes_inputs=['*'], promotes_outputs=['*']) # Get panel forces for each lifting surface individually self.add_subsystem('panel_forces_surf', PanelForcesSurf(surfaces=surfaces), promotes_inputs=['*']) #----------------------------------------------------------- # Step 3: Transform forces from PG domain to physical domain #----------------------------------------------------------- prom_out = [] for surface in surfaces: vname = surface['name'] + '_sec_forces' prom_out.append(vname) self.connect('panel_forces_surf.' + vname, 'inverse_pg_transform.' + vname + '_pg') self.add_subsystem('inverse_pg_transform', InversePGTransform(surfaces=surfaces), promotes_inputs=['alpha', 'beta', 'Mach_number'], promotes_outputs=prom_out) #--------------------------------------------------------------- # Step 4: Mesh point forces are downstream, already transformed. #--------------------------------------------------------------- # Get nodal forces for each lifting surface individually self.add_subsystem('mesh_point_forces_surf', MeshPointForces(surfaces=surfaces), promotes_inputs=['*'], promotes_outputs=['*'])
def test(self): surfaces = get_default_surfaces() comp = VortexMesh(surfaces=surfaces) run_test(self, comp)