def get_initial_state(self, initial_profile, u): full_initial_state = pi.project_on_base(initial_profile, pi.get_base(self.base_lbl)) hom_initial_state = full_initial_state[1:-1] u0 = u(time=0, weights=hom_initial_state, weight_lbl=self.base_lbl) bar_initial_state = (self.a_tilde @ hom_initial_state - (self.b1 * u0).flatten()) return bar_initial_state
def transform_feedback(self, k_src, src_base): """ Transform the given feedback to work with the simulated system """ fem_base = pi.get_base(self.base_lbl) t_fem_mod = pi.calculate_base_transformation_matrix(fem_base, src_base) # in the following, we set \tilde A = I k_fem = k_src @ t_fem_mod k_inhom_0 = k_fem[:, 0] k_hom = k_fem[:, 1:-1] k_inhom_1 = k_fem[:, -1] k_sim = -(k_hom + k_inhom_0 * 0) / (k_hom @ self.b1 + k_inhom_1 - 1) return k_sim
def test_back_projection_from_lagrange_1st(self): vec_real_func = np.vectorize(self.funcs[1]) real_weights = vec_real_func(self.nodes) approx_func = core.back_project_from_base(real_weights, self.initial_functions) approx_func_dz = core.back_project_from_base(real_weights, get_base("ini_funcs", 1)) self.assertTrue(np.allclose(approx_func(self.z_values), vec_real_func(self.z_values))) if show_plots: # lines should match exactly pw = pg.plot(title="back projected linear function") pw.plot(x=self.z_values, y=vec_real_func(self.z_values), pen="r") pw.plot(x=self.z_values, y=approx_func(self.z_values), pen="g") pw.plot(x=self.z_values, y=approx_func_dz(self.z_values), pen="b") app.exec_()
def _build_feedback(self): """ Approximate the analytic kernel with the simulation basis """ def _kernel_factory(frac): def _kernel_func(y): return self._bst_kernel(1, y) * frac(y) return _kernel_func sys_base = pi.get_base(self.sym_sys.base_lbl) areas = [self.dom.bounds] k_sys = np.atleast_2d([integrate_function(_kernel_factory(f), areas)[0] for f in sys_base]) if isinstance(self.sym_sys, ModalApproximation): self.k_sim = k_sys elif isinstance(self.sym_sys, FEMApproximation): # manually compute feedback vector self.k_sim = self.sym_sys.transform_feedback(k_sys, sys_base) else: raise NotImplementedError
def _build_feedback(self): # weak form of the controller orig_x = pi.FieldVariable(self.orig_base_lbl) tar_x = pi.FieldVariable(self.tar_base_lbl, weight_label=self.orig_base_lbl) cont_weak_form = pi.WeakFormulation([ pi.ScalarTerm(orig_x(1)), pi.ScalarTerm(tar_x(1), scale=-1)], name="feedback_law") # create implementation that fits the simulated system if isinstance(self.sym_sys, ModalApproximation): # simply use pyinduct feedback framework self.approx_cont = pi.StateFeedback(cont_weak_form) elif isinstance(self.sym_sys, FEMApproximation): # manually compute feedback vector ce = pi.parse_weak_formulation(cont_weak_form, finalize=False) k_mod = ce.dynamic_forms[self.orig_base_lbl].matrices["E"][0][1] modal_base = pi.get_base(self.orig_base_lbl) self.k_sim = self.sym_sys.transform_feedback(k_mod, modal_base) else: raise NotImplementedError
def get_initial_state(self, initial_profile, u): eig_vectors = pi.get_base(self.base_lbl) initial_weights = pi.project_on_base(initial_profile, eig_vectors) return initial_weights