'remove_predictor': remove_predictor, 'use_sparse': use_sparse, 'ScalingDict': scaling_factors, 'rigid_body_motion': True, 'use_euler': use_euler } # Linearisation # Original data point tsaero0 = data.aero.timestep_info[-1] tsstruct0 = data.structure.timestep_info[-1] tsaero0.rho = rho flex_dof = data.structure.num_dof.value # Create aeroelastic system aeroelastic_system = linaeroelastic.LinAeroEla(data, lin_settings) beam = aeroelastic_system.lingebm_str uvlm = aeroelastic_system.linuvlm # Parametrise orientation in terms of euler angles if use_euler: beam.Mstr = beam.Mstr[:-1, :-1] beam.Cstr = beam.Cstr[:-1, :-1] beam.Kstr = beam.Kstr[:-1, :-1] # structure to UVLM gains aeroelastic_system.get_gebm2uvlm_gains() # beam.Kstr[:flex_dof, :flex_dof] += aeroelastic_system.Kss
'density': 1 } #rho} # Linear Aeroelastic System lin_settings = { 'dt': dt, 'integr_order': integration_order, 'density': rho, 'remove_predictor': remove_predictor, 'use_sparse': use_sparse, 'ScalingDict': scaling_factors, 'rigid_body_motion': True, 'use_euler': True } aeroelastic_system = linaeroelastic.LinAeroEla( data, custom_settings_linear=lin_settings) beam = aeroelastic_system.lingebm_str uvlm = aeroelastic_system.linuvlm # Trim matrices to reduce state dimensionality by 1 (Euler instead of quaternion) beam.Mstr = beam.Mstr[:-1, :-1] beam.Cstr = beam.Cstr[:-1, :-1] beam.Kstr = beam.Kstr[:-1, :-1] # Get BEAM <-> UVLM gain matrices aeroelastic_system.get_gebm2uvlm_gains() # Non-zero aerodynamic forces at the linearisation point addition to the beam matrices beam.Kstr[:flex_dof, :flex_dof] += aeroelastic_system.Kss C_rigid_effects = np.block( [[np.zeros((flex_dof, flex_dof)), aeroelastic_system.Csr],
# Linearise - reduce UVLM and project onto modes # Linearisation # Original data point tsaero0 = data.aero.timestep_info[-1] tsstruct0 = data.structure.timestep_info[-1] dt = data.settings['DynamicCoupled']['dt'] tsaero0.rho = rho scaling_factors = {'length': 0.5*ws.c_ref, 'speed': u_inf, 'density': rho} # Create aeroelastic system aeroelastic_system = linaeroelastic.LinAeroEla(data) beam = aeroelastic_system.lingebm_str # Beam model # structure to UVLM gains aeroelastic_system.get_gebm2uvlm_gains() # Clamped structure, no rigid body modes zero_matrix = np.zeros((3*aeroelastic_system.linuvlm.Kzeta, beam.num_dof)) gain_struct_2_aero = np.block([[aeroelastic_system.Kdisp[:, :-10], zero_matrix], [aeroelastic_system.Kvel_disp[:, :-10], aeroelastic_system.Kvel_vel[:, :-10]]]) gain_aero_2_struct = aeroelastic_system.Kforces[:-10, :] # Linear structural solver solution settings beam.dlti = True
Cga = algebra.quat2rotation(tsstr0.quat) Cab = algebra.crv2rotation(tsstr0.psi[0][0]) Cgb = np.dot(Cga, Cab) ### rolled FoR: # note that, if RollNodes is False, this is equivalent to the FoR A. While # this transformation is redundant for RollNodes=False, we keep it for debug Roll0Rad = np.pi / 180. * Roll0Deg crv_roll = Roll0Rad * np.array([1., 0., 0.]) Cgr = algebra.crv2rotation(crv_roll) Crg = Cgr.T Crb = np.dot(Crg, Cgb) Cra = np.dot(Crg, Cga) ### ----- linearisation Sol = lin_aeroelastic.LinAeroEla(data0) Sol.linuvlm.assemble_ss() Sol.get_gebm2uvlm_gains() # gains, str -> aero Zblock = np.zeros((3 * Sol.linuvlm.Kzeta, Sol.num_dof_str)) Kas = np.block([[Sol.Kdisp, Sol.Kdisp_vel], [Sol.Kvel_disp, Sol.Kvel_vel], [Zblock, Zblock]]) Zblock = None # gains, aero -> str Ksa = Sol.Kforces # ----------------------- project forces at nodes and total in rolled FoR R T0 = algebra.crv2tan(tsstr0.psi[0][0]) T0Tinv = np.linalg.inv(T0.T)
def extract_from_data(data, assemble=True, zeta_pole=np.zeros((3, )), build_Asteady_inv=False): """ Extract relevant info from data structure. If assemble is True, it will also generate a linear UVLM and the displacements/velocities gain matrices """ ### extract aero info - gets info from every panel in every surface # from an NxM matrix and reshapes it into an K by 1 column vector tsaero = data.aero.timestep_info[0] zeta = np.concatenate([ tsaero.zeta[ss].reshape(-1, order='C') for ss in range(tsaero.n_surf) ]) zeta_dot = np.concatenate([ tsaero.zeta_dot[ss].reshape(-1, order='C') for ss in range(tsaero.n_surf) ]) uext = np.concatenate([ tsaero.u_ext[ss].reshape(-1, order='C') for ss in range(tsaero.n_surf) ]) ftot, mtot = comp_tot_force(tsaero.forces, tsaero.zeta, zeta_pole=zeta_pole) ## TEST WHETHER SETTINGS RUN settings = dict() settings['LinearUvlm'] = { 'dt': 0.1, 'integr_order': 2, 'density': 1.225, 'ScalingDict': { 'length': 1., 'speed': 1., 'density': 1. } } ### extract structural info Sol = lin_aeroelastic.LinAeroEla(data, settings) gebm = Sol.lingebm_str q = Sol.q qdot = Sol.dq ### assemble if assemble is True: uvlm = Sol.linuvlm uvlm.assemble_ss() uvlm.get_total_forces_gain(zeta_pole=zeta_pole) Sol.get_gebm2uvlm_gains() Kas = np.block( [[Sol.Kdisp, np.zeros((3 * uvlm.Kzeta, gebm.num_dof + 10))], [Sol.Kvel_disp, Sol.Kvel_vel], [np.zeros((3 * uvlm.Kzeta, 2 * gebm.num_dof + 20))]]) SSbeam = libss.addGain(uvlm.SS, Kas, where='in') if build_Asteady_inv: Asteady_inv = np.linalg.inv(np.eye(*uvlm.SS.A.shape) - uvlm.SS.A) else: Asteady_inv = None Out = Info(zeta, zeta_dot, uext, ftot, mtot, q, qdot, uvlm.SS, SSbeam, Kas, uvlm.Kftot, uvlm.Kmtot, uvlm.Kmtot_disp, Asteady_inv) else: Out = Info(zeta, zeta_dot, uext, ftot, mtot, q, qdot) return Out