def assemble(self, track_body=False): r""" Assembles the linearised UVLM system, removes the desired inputs and adds linearised control surfaces (if present). With all possible inputs present, these are ordered as .. math:: \mathbf{u} = [\boldsymbol{\zeta},\,\dot{\boldsymbol{\zeta}},\,\mathbf{w},\,\delta] Control surface inputs are ordered last as: .. math:: [\delta_1, \delta_2, \dots, \dot{\delta}_1, \dot{\delta_2}] """ self.sys.assemble_ss() if self.scaled: self.sys.nondimss() self.ss = self.sys.SS self.C_to_vertex_forces = self.ss.C.copy() nzeta = 3 * self.sys.Kzeta if self.settings['remove_inputs']: self.remove_inputs(self.settings['remove_inputs']) if self.gust_assembler is not None: A, B, C, D = self.gust_assembler.generate(self.sys, aero=None) ss_gust = libss.ss(A, B, C, D, dt=self.ss.dt) self.gust_assembler.ss_gust = ss_gust self.ss = libss.series(ss_gust, self.ss) if self.control_surface is not None: Kzeta_delta, Kdzeta_ddelta = self.control_surface.generate() n_zeta, n_ctrl_sfc = Kzeta_delta.shape # Modify the state space system with a gain at the input side # such that the control surface deflections are last if self.sys.use_sparse: gain_cs = sp.eye(self.ss.inputs, self.ss.inputs + 2 * self.control_surface.n_control_surfaces, format='lil') gain_cs[:n_zeta, self.ss.inputs:self.ss.inputs + n_ctrl_sfc] = Kzeta_delta gain_cs[n_zeta:2 * n_zeta, self.ss.inputs + n_ctrl_sfc:self.ss.inputs + 2 * n_ctrl_sfc] = Kdzeta_ddelta gain_cs = libsp.csc_matrix(gain_cs) else: gain_cs = np.eye( self.ss.inputs, self.ss.inputs + 2 * self.control_surface.n_control_surfaces) gain_cs[:n_zeta, self.ss.inputs:self.ss.inputs + n_ctrl_sfc] = Kzeta_delta gain_cs[n_zeta:2 * n_zeta, self.ss.inputs + n_ctrl_sfc:self.ss.inputs + 2 * n_ctrl_sfc] = Kdzeta_ddelta self.ss.addGain(gain_cs, where='in') self.gain_cs = gain_cs
for node in range(data.structure.num_node): node_bc = data.structure.boundary_conditions[node] if node_bc != 1: node_ndof = 6 vertical_force_index = np.array([0, 0, 1, 0, 0, 0]) / qS K_Fz[:, wdof:wdof + node_ndof] = vertical_force_index else: node_ndof = 0 wdof += node_ndof uvlm.SS.addGain(K_Fz, where='out') # Join systems sears_ss = libss.series(ss_gust, uvlm.SS) # wt = np.linspace(0.01, 14, 100) # Y_test = sears_ss.freqresp(wt) # # plt.plot(wt, Y_test[0, 0, :].real) # plt.plot(wt, Y_test[0, 0, :].imag) # plt.savefig(fig_folder + 'Test_MxG.eps') # ROM rom = krylovrom.KrylovReducedOrderModel() rom.initialise(data, sears_ss) frequency_continuous_w = 2 * u_inf * frequency_continuous_k / ws.c_ref frequency_dt = np.exp(frequency_continuous_k * dt) rom.run(algorithm, krylov_r, frequency_dt) # Time Domain Simulation