def test_projection_on_lag1st(self): weights = [] # convenience wrapper for non array input -> constant function weight = core.project_on_base(self.funcs[0], self.initial_functions[1]) self.assertAlmostEqual(weight, 1.5*self.funcs[0](self.nodes[1])) # linear function -> should be fitted exactly weights.append(core.project_on_base(self.funcs[1], self.initial_functions)) self.assertTrue(np.allclose(weights[-1], self.funcs[1](self.nodes))) # quadratic function -> should be fitted somehow close weights.append(core.project_on_base(self.funcs[2], self.initial_functions)) self.assertTrue(np.allclose(weights[-1], self.funcs[2](self.nodes), atol=.5)) # trig function -> will be crappy weights.append(core.project_on_base(self.funcs[3], self.initial_functions)) if show_plots: # since test function are lagrange1st order, plotting the results is fairly easy for idx, w in enumerate(weights): pw = pg.plot(title="Weights {0}".format(idx)) pw.plot(x=self.z_values, y=self.real_values[idx+1], pen="r") pw.plot(x=self.nodes, y=w, pen="b") app.exec_()
def test_it(self): actuation_type = 'robin' bound_cond_type = 'robin' param = [2., 1.5, -3., -1., -.5] adjoint_param = ef.get_adjoint_rad_evp_param(param) a2, a1, a0, alpha, beta = param l = 1. spatial_disc = 10 dz = sim.Domain(bounds=(0, l), num=spatial_disc) T = 1. temporal_disc = 1e2 dt = sim.Domain(bounds=(0, T), num=temporal_disc) n = 10 eig_freq, eig_val = ef.compute_rad_robin_eigenfrequencies(param, l, n) init_eig_funcs = np.array([ef.SecondOrderRobinEigenfunction(om, param, dz.bounds) for om in eig_freq]) init_adjoint_eig_funcs = np.array([ef.SecondOrderRobinEigenfunction(om, adjoint_param, dz.bounds) for om in eig_freq]) # normalize eigenfunctions and adjoint eigenfunctions adjoint_and_eig_funcs = [cr.normalize_function(init_eig_funcs[i], init_adjoint_eig_funcs[i]) for i in range(n)] eig_funcs = np.array([f_tuple[0] for f_tuple in adjoint_and_eig_funcs]) adjoint_eig_funcs = np.array([f_tuple[1] for f_tuple in adjoint_and_eig_funcs]) # register eigenfunctions register_base("eig_funcs", eig_funcs, overwrite=True) register_base("adjoint_eig_funcs", adjoint_eig_funcs, overwrite=True) # derive initial field variable x(z,0) and weights start_state = cr.Function(lambda z: 0., domain=(0, l)) initial_weights = cr.project_on_base(start_state, adjoint_eig_funcs) # init trajectory u = tr.RadTrajectory(l, T, param, bound_cond_type, actuation_type) # determine (A,B) with weak-formulation (pyinduct) rad_pde = ut.get_parabolic_robin_weak_form("eig_funcs", "adjoint_eig_funcs", u, param, dz.bounds) cf = sim.parse_weak_formulation(rad_pde) ss_weak = cf.convert_to_state_space() # determine (A,B) with modal-transfomation A = np.diag(np.real_if_close(eig_val)) B = a2*np.array([adjoint_eig_funcs[i](l) for i in xrange(len(eig_freq))]) ss_modal = sim.StateSpace("eig_funcs", A, B) # check if ss_modal.(A,B) is close to ss_weak.(A,B) self.assertTrue(np.allclose(np.sort(np.linalg.eigvals(ss_weak.A)), np.sort(np.linalg.eigvals(ss_modal.A)), rtol=1e-05, atol=0.)) self.assertTrue(np.allclose(np.array([i[0] for i in ss_weak.B]), ss_modal.B)) # display results if show_plots: t, q = sim.simulate_state_space(ss_modal, u, initial_weights, dt) eval_d = ut.evaluate_approximation("eig_funcs", q, t, dz, spat_order=1) win1 = vis.PgAnimatedPlot([eval_d], title="Test") win2 = vis.PgSurfacePlot(eval_d[0]) app.exec_()
def test_it(self): actuation_type = 'dirichlet' bound_cond_type = 'dirichlet' param = [1., -2., -1., None, None] adjoint_param = ef.get_adjoint_rad_evp_param(param) a2, a1, a0, _, _ = param l = 1. spatial_disc = 10 dz = sim.Domain(bounds=(0, l), num=spatial_disc) T = 1. temporal_disc = 1e2 dt = sim.Domain(bounds=(0, T), num=temporal_disc) omega = np.array([(i+1)*np.pi/l for i in xrange(spatial_disc)]) eig_values = a0 - a2*omega**2 - a1**2/4./a2 norm_fak = np.ones(omega.shape)*np.sqrt(2) eig_funcs = np.array([ef.SecondOrderDirichletEigenfunction(omega[i], param, dz.bounds, norm_fak[i]) for i in range(spatial_disc)]) register_base("eig_funcs", eig_funcs, overwrite=True) adjoint_eig_funcs = np.array([ef.SecondOrderDirichletEigenfunction(omega[i], adjoint_param, dz.bounds, norm_fak[i]) for i in range(spatial_disc)]) register_base("adjoint_eig_funcs", adjoint_eig_funcs, overwrite=True) # derive initial field variable x(z,0) and weights start_state = cr.Function(lambda z: 0., domain=(0, l)) initial_weights = cr.project_on_base(start_state, adjoint_eig_funcs) # init trajectory u = tr.RadTrajectory(l, T, param, bound_cond_type, actuation_type) # determine (A,B) with weak-formulation (pyinduct) # derive sate-space system rad_pde = ut.get_parabolic_dirichlet_weak_form("eig_funcs", "adjoint_eig_funcs", u, param, dz.bounds) cf = sim.parse_weak_formulation(rad_pde) ss_weak = cf.convert_to_state_space() # determine (A,B) with modal-transfomation A = np.diag(eig_values) B = -a2*np.array([adjoint_eig_funcs[i].derive()(l) for i in xrange(spatial_disc)]) ss_modal = sim.StateSpace("eig_funcs", A, B) # TODO: resolve the big tolerance (rtol=3e-01) between ss_modal.A and ss_weak.A # check if ss_modal.(A,B) is close to ss_weak.(A,B) self.assertTrue(np.allclose(np.sort(np.linalg.eigvals(ss_weak.A)), np.sort(np.linalg.eigvals(ss_modal.A)), rtol=3e-1, atol=0.)) self.assertTrue(np.allclose(np.array([i[0] for i in ss_weak.B]), ss_modal.B)) # display results if show_plots: t, q = sim.simulate_state_space(ss_modal, u, initial_weights, dt) eval_d = ut.evaluate_approximation("eig_funcs", q, t, dz, spat_order=1) win2 = vis.PgSurfacePlot(eval_d) app.exec_()
def test_fem(self): """ use best documented fem case to test all steps in simulation process """ # enter string with mass equations nodes, ini_funcs = pyinduct.shapefunctions.cure_interval(pyinduct.shapefunctions.LagrangeSecondOrder, self.dz.bounds, node_count=10) register_base("init_funcs", ini_funcs, overwrite=True) int1 = ph.IntegralTerm( ph.Product(ph.TemporalDerivedFieldVariable("init_funcs", 2), ph.TestFunction("init_funcs")), self.dz.bounds, scale=self.params.sigma*self.params.tau**2) s1 = ph.ScalarTerm( ph.Product(ph.TemporalDerivedFieldVariable("init_funcs", 2, location=0), ph.TestFunction("init_funcs", location=0)), scale=self.params.m) int2 = ph.IntegralTerm( ph.Product(ph.SpatialDerivedFieldVariable("init_funcs", 1), ph.TestFunction("init_funcs", order=1)), self.dz.bounds, scale=self.params.sigma) s2 = ph.ScalarTerm( ph.Product(ph.Input(self.u), ph.TestFunction("init_funcs", location=1)), -self.params.sigma) # derive sate-space system string_pde = sim.WeakFormulation([int1, s1, int2, s2], name="fem_test") self.cf = sim.parse_weak_formulation(string_pde) ss = self.cf.convert_to_state_space() # generate initial conditions for weights q0 = np.array([cr.project_on_base(self.ic[idx], ini_funcs) for idx in range(2)]).flatten() # simulate t, q = sim.simulate_state_space(ss, self.cf.input_function, q0, self.dt) # calculate result data eval_data = [] for der_idx in range(2): eval_data.append( ut.evaluate_approximation("init_funcs", q[:, der_idx * ini_funcs.size:(der_idx + 1) * ini_funcs.size], t, self.dz)) eval_data[-1].name = "{0}{1}".format(self.cf.name, "_"+"".join(["d" for x in range(der_idx)]) + "t" if der_idx > 0 else "") # display results if show_plots: win = vis.PgAnimatedPlot(eval_data[:2], title="fem approx and derivative") win2 = vis.PgSurfacePlot(eval_data[0]) app.exec_() # test for correct transition self.assertTrue(np.isclose(eval_data[0].output_data[-1, 0], self.y_end, atol=1e-3)) # TODO dump in pyinduct/tests/ressources file_path = os.sep.join(["resources", "test_data.res"]) if not os.path.isdir("resources"): os.makedirs("resources") with open(file_path, "w") as f: f.write(dumps(eval_data))
def setUp(self): # real function self.z_values = np.linspace(0, 1, 1000) self.real_func = core.Function(lambda x: x) self.real_func_handle = np.vectorize(self.real_func) # approximation by lag1st self.nodes, self.src_test_funcs = shapefunctions.cure_interval(shapefunctions.LagrangeFirstOrder, (0, 1), node_count=2) register_base("test_funcs", self.src_test_funcs, overwrite=True) self.src_weights = core.project_on_base(self.real_func, self.src_test_funcs) self.assertTrue(np.allclose(self.src_weights, [0, 1])) # just to be sure self.src_approx_handle = core.back_project_from_base(self.src_weights, self.src_test_funcs) # approximation by sin(w*x) def trig_factory(freq): def func(x): return np.sin(freq*x) return func self.trig_test_funcs = np.array([core.Function(trig_factory(w), domain=(0, 1)) for w in range(1, 3)])
def test_it(self): # original system parameters a2 = 1.5; a1 = 2.5; a0 = 28; alpha = -2; beta = -3 param = [a2, a1, a0, alpha, beta] adjoint_param = ef.get_adjoint_rad_evp_param(param) # target system parameters (controller parameters) a1_t = -5; a0_t = -25; alpha_t = 3; beta_t = 2 # a1_t = a1; a0_t = a0; alpha_t = alpha; beta_t = beta param_t = [a2, a1_t, a0_t, alpha_t, beta_t] # original intermediate ("_i") and traget intermediate ("_ti") system parameters _, _, a0_i, alpha_i, beta_i = ef.transform2intermediate(param) _, _, a0_ti, alpha_ti, beta_ti = ef.transform2intermediate(param_t) # system/simulation parameters actuation_type = 'robin' bound_cond_type = 'robin' self.l = 1. spatial_disc = 10 dz = sim.Domain(bounds=(0, self.l), num=spatial_disc) T = 1. temporal_disc = 1e2 dt = sim.Domain(bounds=(0, T), num=temporal_disc) n = 10 # create (not normalized) eigenfunctions eig_freq, eig_val = ef.compute_rad_robin_eigenfrequencies(param, self.l, n) init_eig_funcs = np.array([ef.SecondOrderRobinEigenfunction(om, param, dz.bounds) for om in eig_freq]) init_adjoint_eig_funcs = np.array([ef.SecondOrderRobinEigenfunction(om, adjoint_param, dz.bounds) for om in eig_freq]) # normalize eigenfunctions and adjoint eigenfunctions adjoint_and_eig_funcs = [cr.normalize_function(init_eig_funcs[i], init_adjoint_eig_funcs[i]) for i in range(n)] eig_funcs = np.array([f_tuple[0] for f_tuple in adjoint_and_eig_funcs]) adjoint_eig_funcs = np.array([f_tuple[1] for f_tuple in adjoint_and_eig_funcs]) # eigenfunctions from target system ("_t") eig_freq_t = np.sqrt(-a1_t ** 2 / 4 / a2 ** 2 + (a0_t - eig_val) / a2) eig_funcs_t = np.array([ef.SecondOrderRobinEigenfunction(eig_freq_t[i], param_t, dz.bounds).scale(eig_funcs[i](0)) for i in range(n)]) # register eigenfunctions register_base("eig_funcs", eig_funcs, overwrite=True) register_base("adjoint_eig_funcs", adjoint_eig_funcs, overwrite=True) register_base("eig_funcs_t", eig_funcs_t, overwrite=True) # derive initial field variable x(z,0) and weights start_state = cr.Function(lambda z: 0., domain=(0, self.l)) initial_weights = cr.project_on_base(start_state, adjoint_eig_funcs) # controller initialization x_at_l = ph.FieldVariable("eig_funcs", location=self.l) xd_at_l = ph.SpatialDerivedFieldVariable("eig_funcs", 1, location=self.l) x_t_at_l = ph.FieldVariable("eig_funcs_t", weight_label="eig_funcs", location=self.l) xd_t_at_l = ph.SpatialDerivedFieldVariable("eig_funcs_t", 1, weight_label="eig_funcs", location=self.l) combined_transform = lambda z: np.exp((a1_t - a1) / 2 / a2 * z) int_kernel_zz = lambda z: alpha_ti - alpha_i + (a0_i - a0_ti) / 2 / a2 * z controller = ct.Controller( ct.ControlLaw([ph.ScalarTerm(x_at_l, (beta_i - beta_ti - int_kernel_zz(self.l))), ph.ScalarTerm(x_t_at_l, -beta_ti * combined_transform(self.l)), ph.ScalarTerm(x_at_l, beta_ti), ph.ScalarTerm(xd_t_at_l, -combined_transform(self.l)), ph.ScalarTerm(x_t_at_l, -a1_t / 2 / a2 * combined_transform(self.l)), ph.ScalarTerm(xd_at_l, 1), ph.ScalarTerm(x_at_l, a1 / 2 / a2 + int_kernel_zz(self.l)) ])) # init trajectory traj = tr.RadTrajectory(self.l, T, param_t, bound_cond_type, actuation_type) traj.scale = combined_transform(self.l) # input with feedback control_law = sim.SimulationInputSum([traj, controller]) # control_law = sim.simInputSum([traj]) # determine (A,B) with modal-transformation A = np.diag(np.real(eig_val)) B = a2 * np.array([adjoint_eig_funcs[i](self.l) for i in range(len(eig_freq))]) ss_modal = sim.StateSpace("eig_funcs", A, B, input_handle=control_law) # simulate t, q = sim.simulate_state_space(ss_modal, initial_weights, dt) eval_d = sim.evaluate_approximation("eig_funcs", q, t, dz) x_0t = eval_d.output_data[:, 0] yc, tc = tr.gevrey_tanh(T, 1) x_0t_desired = np.interp(t, tc, yc[0, :]) self.assertLess(np.average((x_0t - x_0t_desired) ** 2), 1e-4) # display results if show_plots: win1 = vis.PgAnimatedPlot([eval_d], title="Test") win2 = vis.PgSurfacePlot(eval_d) app.exec_()
def test_it(self): # original system parameters a2 = 1 a1 = 0 # attention: only a2 = 1., a1 =0 supported in this test case a0 = 0 param = [a2, a1, a0, None, None] # target system parameters (controller parameters) a1_t = 0 a0_t = 0 # attention: only a2 = 1., a1 =0 and a0 =0 supported in this test case param_t = [a2, a1_t, a0_t, None, None] # system/simulation parameters actuation_type = 'dirichlet' bound_cond_type = 'dirichlet' l = 1. spatial_disc = 10 dz = sim.Domain(bounds=(0, l), num=spatial_disc) T = 1. temporal_disc = 1e2 dt = sim.Domain(bounds=(0, T), num=temporal_disc) n = 10 # eigenvalues /-functions original system eig_freq = np.array([(i + 1) * np.pi / l for i in range(n)]) eig_values = a0 - a2 * eig_freq ** 2 - a1 ** 2 / 4. / a2 norm_fac = np.ones(eig_freq.shape) * np.sqrt(2) eig_funcs = np.asarray([ef.SecondOrderDirichletEigenfunction(eig_freq[i], param, dz.bounds, norm_fac[i]) for i in range(n)]) register_base("eig_funcs", eig_funcs, overwrite=True) # eigenfunctions target system eig_freq_t = np.sqrt(-eig_values.astype(complex)) norm_fac_t = norm_fac * eig_freq / eig_freq_t eig_funcs_t = np.asarray([ef.SecondOrderDirichletEigenfunction(eig_freq_t[i], param_t, dz.bounds, norm_fac_t[i]) for i in range(n)]) register_base("eig_funcs_t", eig_funcs_t, overwrite=True) # derive initial field variable x(z,0) and weights start_state = cr.Function(lambda z: 0., domain=(0, l)) initial_weights = cr.project_on_base(start_state, eig_funcs) # init trajectory / input of target system traj = tr.RadTrajectory(l, T, param_t, bound_cond_type, actuation_type) # init controller x_at_1 = ph.FieldVariable("eig_funcs", location=1) xt_at_1 = ph.FieldVariable("eig_funcs_t", weight_label="eig_funcs", location=1) controller = ct.Controller(ct.ControlLaw([ph.ScalarTerm(x_at_1, 1), ph.ScalarTerm(xt_at_1, -1)])) # input with feedback control_law = sim.SimulationInputSum([traj, controller]) # determine (A,B) with modal-transfomation A = np.diag(eig_values) B = -a2 * np.array([eig_funcs[i].derive()(l) for i in range(n)]) ss = sim.StateSpace("eig_funcs", A, B, input_handle=control_law) # simulate t, q = sim.simulate_state_space(ss, initial_weights, dt) eval_d = sim.evaluate_approximation("eig_funcs", q, t, dz) x_0t = eval_d.output_data[:, 0] yc, tc = tr.gevrey_tanh(T, 1) x_0t_desired = np.interp(t, tc, yc[0, :]) self.assertLess(np.average((x_0t - x_0t_desired) ** 2), 0.5) # display results if show_plots: eval_d = sim.evaluate_approximation("eig_funcs", q, t, dz) win2 = vis.PgSurfacePlot(eval_d) app.exec_()
# eigenfunctions target system eig_freq_t = np.sqrt(-eig_values.astype(complex)) norm_fac_t = norm_fac * eig_freq / eig_freq_t eig_funcs_t = np.asarray( [ef.SecondOrderDirichletEigenfunction(eig_freq_t[i], param_t, spatial_domain.bounds, norm_fac_t[i]) for i in range(n)]) re.register_base("eig_funcs_t", eig_funcs_t, overwrite=True) # init controller x_at_1 = ph.FieldVariable("eig_funcs", location=1) xt_at_1 = ph.FieldVariable("eig_funcs_t", weight_label="eig_funcs", location=1) controller = ct.Controller(ct.ControlLaw([ph.ScalarTerm(x_at_1, 1), ph.ScalarTerm(xt_at_1, -1)])) # derive initial field variable x(z,0) and weights start_state = cr.Function(lambda z: init_profile) initial_weights = cr.project_on_base(start_state, eig_funcs) # init trajectory traj = tr.RadTrajectory(l, T, param_t, bound_cond_type, actuation_type) # input with feedback control_law = sim.SimulationInputSum([traj, controller]) # determine (A,B) with modal-transfomation A = np.diag(eig_values) B = -a2 * np.array([eig_funcs[i].derive()(l) for i in xrange(n)]) ss = sim.StateSpace("eig_funcs", A, B) # evaluate desired output data z_d = np.linspace(0, l, len(spatial_domain)) y_d, t_d = tr.gevrey_tanh(T, 80)
# eigenfunctions target system eig_freq_t = np.sqrt(-eig_values.astype(complex)) norm_fac_t = norm_fac * eig_freq / eig_freq_t eig_funcs_t = np.asarray( [ef.SecondOrderDirichletEigenfunction(eig_freq_t[i], param_t, spatial_domain.bounds, norm_fac_t[i]) for i in range(n)]) re.register_base("eig_funcs_t", eig_funcs_t, overwrite=True) # init controller x_at_1 = ph.FieldVariable("eig_funcs", location=1) xt_at_1 = ph.FieldVariable("eig_funcs_t", weight_label="eig_funcs", location=1) controller = ct.Controller(ct.ControlLaw([ph.ScalarTerm(x_at_1, 1), ph.ScalarTerm(xt_at_1, -1)])) # derive initial field variable x(z,0) and weights start_state = cr.Function(lambda z: init_profile) initial_weights = cr.project_on_base(start_state, eig_funcs) # init trajectory traj = tr.RadTrajectory(l, T, param_t, bound_cond_type, actuation_type) # input with feedback control_law = sim.SimulationInputSum([traj, controller]) # determine (A,B) with modal-transfomation A = np.diag(eig_values) B = -a2 * np.array([eig_funcs[i].derive()(l) for i in range(n)]) ss = sim.StateSpace("eig_funcs", A, B, input_handle=control_law) # evaluate desired output data z_d = np.linspace(0, l, len(spatial_domain)) y_d, t_d = tr.gevrey_tanh(T, 80)
def test_it(self): # original system parameters a2 = 1.5 a1 = 2.5 a0 = 28 alpha = -2 beta = -3 param = [a2, a1, a0, alpha, beta] adjoint_param = ef.get_adjoint_rad_evp_param(param) # target system parameters (controller parameters) a1_t = -5 a0_t = -25 alpha_t = 3 beta_t = 2 # a1_t = a1; a0_t = a0; alpha_t = alpha; beta_t = beta param_t = [a2, a1_t, a0_t, alpha_t, beta_t] # original intermediate ("_i") and traget intermediate ("_ti") system parameters _, _, a0_i, alpha_i, beta_i = ef.transform2intermediate(param) _, _, a0_ti, alpha_ti, beta_ti = ef.transform2intermediate(param_t) # system/simulation parameters actuation_type = 'robin' bound_cond_type = 'robin' self.l = 1. spatial_disc = 10 dz = sim.Domain(bounds=(0, self.l), num=spatial_disc) T = 1. temporal_disc = 1e2 dt = sim.Domain(bounds=(0, T), num=temporal_disc) n = 10 # create (not normalized) eigenfunctions eig_freq, eig_val = ef.compute_rad_robin_eigenfrequencies( param, self.l, n) init_eig_funcs = np.array([ ef.SecondOrderRobinEigenfunction(om, param, dz.bounds) for om in eig_freq ]) init_adjoint_eig_funcs = np.array([ ef.SecondOrderRobinEigenfunction(om, adjoint_param, dz.bounds) for om in eig_freq ]) # normalize eigenfunctions and adjoint eigenfunctions adjoint_and_eig_funcs = [ cr.normalize_function(init_eig_funcs[i], init_adjoint_eig_funcs[i]) for i in range(n) ] eig_funcs = np.array([f_tuple[0] for f_tuple in adjoint_and_eig_funcs]) adjoint_eig_funcs = np.array( [f_tuple[1] for f_tuple in adjoint_and_eig_funcs]) # eigenfunctions from target system ("_t") eig_freq_t = np.sqrt(-a1_t**2 / 4 / a2**2 + (a0_t - eig_val) / a2) eig_funcs_t = np.array([ ef.SecondOrderRobinEigenfunction(eig_freq_t[i], param_t, dz.bounds).scale(eig_funcs[i](0)) for i in range(n) ]) # register eigenfunctions register_base("eig_funcs", eig_funcs, overwrite=True) register_base("adjoint_eig_funcs", adjoint_eig_funcs, overwrite=True) register_base("eig_funcs_t", eig_funcs_t, overwrite=True) # derive initial field variable x(z,0) and weights start_state = cr.Function(lambda z: 0., domain=(0, self.l)) initial_weights = cr.project_on_base(start_state, adjoint_eig_funcs) # controller initialization x_at_l = ph.FieldVariable("eig_funcs", location=self.l) xd_at_l = ph.SpatialDerivedFieldVariable("eig_funcs", 1, location=self.l) x_t_at_l = ph.FieldVariable("eig_funcs_t", weight_label="eig_funcs", location=self.l) xd_t_at_l = ph.SpatialDerivedFieldVariable("eig_funcs_t", 1, weight_label="eig_funcs", location=self.l) combined_transform = lambda z: np.exp((a1_t - a1) / 2 / a2 * z) int_kernel_zz = lambda z: alpha_ti - alpha_i + (a0_i - a0_ti ) / 2 / a2 * z controller = ct.Controller( ct.ControlLaw([ ph.ScalarTerm(x_at_l, (beta_i - beta_ti - int_kernel_zz(self.l))), ph.ScalarTerm(x_t_at_l, -beta_ti * combined_transform(self.l)), ph.ScalarTerm(x_at_l, beta_ti), ph.ScalarTerm(xd_t_at_l, -combined_transform(self.l)), ph.ScalarTerm(x_t_at_l, -a1_t / 2 / a2 * combined_transform(self.l)), ph.ScalarTerm(xd_at_l, 1), ph.ScalarTerm(x_at_l, a1 / 2 / a2 + int_kernel_zz(self.l)) ])) # init trajectory traj = tr.RadTrajectory(self.l, T, param_t, bound_cond_type, actuation_type) traj.scale = combined_transform(self.l) # input with feedback control_law = sim.SimulationInputSum([traj, controller]) # control_law = sim.simInputSum([traj]) # determine (A,B) with modal-transformation A = np.diag(np.real(eig_val)) B = a2 * np.array( [adjoint_eig_funcs[i](self.l) for i in range(len(eig_freq))]) ss_modal = sim.StateSpace("eig_funcs", A, B, input_handle=control_law) # simulate t, q = sim.simulate_state_space(ss_modal, initial_weights, dt) eval_d = sim.evaluate_approximation("eig_funcs", q, t, dz) x_0t = eval_d.output_data[:, 0] yc, tc = tr.gevrey_tanh(T, 1) x_0t_desired = np.interp(t, tc, yc[0, :]) self.assertLess(np.average((x_0t - x_0t_desired)**2), 1e-4) # display results if show_plots: win1 = vis.PgAnimatedPlot([eval_d], title="Test") win2 = vis.PgSurfacePlot(eval_d) app.exec_()
def test_it(self): # original system parameters a2 = 1 a1 = 0 # attention: only a2 = 1., a1 =0 supported in this test case a0 = 0 param = [a2, a1, a0, None, None] # target system parameters (controller parameters) a1_t = 0 a0_t = 0 # attention: only a2 = 1., a1 =0 and a0 =0 supported in this test case param_t = [a2, a1_t, a0_t, None, None] # system/simulation parameters actuation_type = 'dirichlet' bound_cond_type = 'dirichlet' l = 1. spatial_disc = 10 dz = sim.Domain(bounds=(0, l), num=spatial_disc) T = 1. temporal_disc = 1e2 dt = sim.Domain(bounds=(0, T), num=temporal_disc) n = 10 # eigenvalues /-functions original system eig_freq = np.array([(i + 1) * np.pi / l for i in range(n)]) eig_values = a0 - a2 * eig_freq**2 - a1**2 / 4. / a2 norm_fac = np.ones(eig_freq.shape) * np.sqrt(2) eig_funcs = np.asarray([ ef.SecondOrderDirichletEigenfunction(eig_freq[i], param, dz.bounds, norm_fac[i]) for i in range(n) ]) register_base("eig_funcs", eig_funcs, overwrite=True) # eigenfunctions target system eig_freq_t = np.sqrt(-eig_values.astype(complex)) norm_fac_t = norm_fac * eig_freq / eig_freq_t eig_funcs_t = np.asarray([ ef.SecondOrderDirichletEigenfunction(eig_freq_t[i], param_t, dz.bounds, norm_fac_t[i]) for i in range(n) ]) register_base("eig_funcs_t", eig_funcs_t, overwrite=True) # derive initial field variable x(z,0) and weights start_state = cr.Function(lambda z: 0., domain=(0, l)) initial_weights = cr.project_on_base(start_state, eig_funcs) # init trajectory / input of target system traj = tr.RadTrajectory(l, T, param_t, bound_cond_type, actuation_type) # init controller x_at_1 = ph.FieldVariable("eig_funcs", location=1) xt_at_1 = ph.FieldVariable("eig_funcs_t", weight_label="eig_funcs", location=1) controller = ct.Controller( ct.ControlLaw( [ph.ScalarTerm(x_at_1, 1), ph.ScalarTerm(xt_at_1, -1)])) # input with feedback control_law = sim.SimulationInputSum([traj, controller]) # determine (A,B) with modal-transfomation A = np.diag(eig_values) B = -a2 * np.array([eig_funcs[i].derive()(l) for i in range(n)]) ss = sim.StateSpace("eig_funcs", A, B, input_handle=control_law) # simulate t, q = sim.simulate_state_space(ss, initial_weights, dt) eval_d = sim.evaluate_approximation("eig_funcs", q, t, dz) x_0t = eval_d.output_data[:, 0] yc, tc = tr.gevrey_tanh(T, 1) x_0t_desired = np.interp(t, tc, yc[0, :]) self.assertLess(np.average((x_0t - x_0t_desired)**2), 0.5) # display results if show_plots: eval_d = sim.evaluate_approximation("eig_funcs", q, t, dz) win2 = vis.PgSurfacePlot(eval_d) app.exec_()
def test_it(self): actuation_type = 'dirichlet' bound_cond_type = 'dirichlet' param = [1., -2., -1., None, None] adjoint_param = ef.get_adjoint_rad_evp_param(param) a2, a1, a0, _, _ = param l = 1. spatial_disc = 10 dz = sim.Domain(bounds=(0, l), num=spatial_disc) T = 1. temporal_disc = 1e2 dt = sim.Domain(bounds=(0, T), num=temporal_disc) omega = np.array([(i + 1) * np.pi / l for i in range(spatial_disc)]) eig_values = a0 - a2 * omega**2 - a1**2 / 4. / a2 norm_fak = np.ones(omega.shape) * np.sqrt(2) eig_funcs = np.array([ ef.SecondOrderDirichletEigenfunction(omega[i], param, dz.bounds, norm_fak[i]) for i in range(spatial_disc) ]) register_base("eig_funcs", eig_funcs, overwrite=True) adjoint_eig_funcs = np.array([ ef.SecondOrderDirichletEigenfunction(omega[i], adjoint_param, dz.bounds, norm_fak[i]) for i in range(spatial_disc) ]) register_base("adjoint_eig_funcs", adjoint_eig_funcs, overwrite=True) # derive initial field variable x(z,0) and weights start_state = cr.Function(lambda z: 0., domain=(0, l)) initial_weights = cr.project_on_base(start_state, adjoint_eig_funcs) # init trajectory u = tr.RadTrajectory(l, T, param, bound_cond_type, actuation_type) # determine (A,B) with weak-formulation (pyinduct) # derive sate-space system rad_pde = ut.get_parabolic_dirichlet_weak_form("eig_funcs", "adjoint_eig_funcs", u, param, dz.bounds) cf = sim.parse_weak_formulation(rad_pde) ss_weak = cf.convert_to_state_space() # determine (A,B) with modal-transfomation A = np.diag(eig_values) B = -a2 * np.array( [adjoint_eig_funcs[i].derive()(l) for i in range(spatial_disc)]) ss_modal = sim.StateSpace("eig_funcs", A, B, input_handle=u) # TODO: resolve the big tolerance (rtol=3e-01) between ss_modal.A and ss_weak.A # check if ss_modal.(A,B) is close to ss_weak.(A,B) self.assertTrue( np.allclose(np.sort(np.linalg.eigvals(ss_weak.A[1])), np.sort(np.linalg.eigvals(ss_modal.A[1])), rtol=3e-1, atol=0.)) self.assertTrue( np.allclose(np.array([i[0] for i in ss_weak.B[1]]), ss_modal.B[1])) # display results if show_plots: t, q = sim.simulate_state_space(ss_modal, initial_weights, dt) eval_d = sim.evaluate_approximation("eig_funcs", q, t, dz, spat_order=1) win2 = vis.PgSurfacePlot(eval_d) app.exec_()
def test_fem(self): """ use best documented fem case to test all steps in simulation process """ # enter string with mass equations # nodes, ini_funcs = sf.cure_interval(sf.LagrangeFirstOrder, nodes, ini_funcs = sf.cure_interval(sf.LagrangeSecondOrder, self.dz.bounds, node_count=11) register_base("init_funcs", ini_funcs, overwrite=True) int1 = ph.IntegralTerm(ph.Product( ph.TemporalDerivedFieldVariable("init_funcs", 2), ph.TestFunction("init_funcs")), self.dz.bounds, scale=self.params.sigma * self.params.tau**2) s1 = ph.ScalarTerm(ph.Product( ph.TemporalDerivedFieldVariable("init_funcs", 2, location=0), ph.TestFunction("init_funcs", location=0)), scale=self.params.m) int2 = ph.IntegralTerm(ph.Product( ph.SpatialDerivedFieldVariable("init_funcs", 1), ph.TestFunction("init_funcs", order=1)), self.dz.bounds, scale=self.params.sigma) s2 = ph.ScalarTerm( ph.Product(ph.Input(self.u), ph.TestFunction("init_funcs", location=1)), -self.params.sigma) # derive sate-space system string_pde = sim.WeakFormulation([int1, s1, int2, s2], name="fem_test") self.cf = sim.parse_weak_formulation(string_pde) ss = self.cf.convert_to_state_space() # generate initial conditions for weights q0 = np.array([ cr.project_on_base(self.ic[idx], ini_funcs) for idx in range(2) ]).flatten() # simulate t, q = sim.simulate_state_space(ss, q0, self.dt) # calculate result data eval_data = [] for der_idx in range(2): eval_data.append( sim.evaluate_approximation( "init_funcs", q[:, der_idx * ini_funcs.size:(der_idx + 1) * ini_funcs.size], t, self.dz)) eval_data[-1].name = "{0}{1}".format( self.cf.name, "_" + "".join(["d" for x in range(der_idx)]) + "t" if der_idx > 0 else "") # display results if show_plots: win = vis.PgAnimatedPlot(eval_data[:2], title="fem approx and derivative") win2 = vis.PgSurfacePlot(eval_data[0]) app.exec_() # test for correct transition self.assertTrue( np.isclose(eval_data[0].output_data[-1, 0], self.y_end, atol=1e-3)) # save some test data for later use root_dir = os.getcwd() if root_dir.split(os.sep)[-1] == "tests": res_dir = os.sep.join([os.getcwd(), "resources"]) else: res_dir = os.sep.join([os.getcwd(), "tests", "resources"]) if not os.path.isdir(res_dir): os.makedirs(res_dir) file_path = os.sep.join([res_dir, "test_data.res"]) with open(file_path, "w+b") as f: dump(eval_data, f)
def test_it(self): actuation_type = 'robin' bound_cond_type = 'robin' param = [2., 1.5, -3., -1., -.5] adjoint_param = ef.get_adjoint_rad_evp_param(param) a2, a1, a0, alpha, beta = param l = 1. spatial_disc = 10 dz = sim.Domain(bounds=(0, l), num=spatial_disc) T = 1. temporal_disc = 1e2 dt = sim.Domain(bounds=(0, T), num=temporal_disc) n = 10 eig_freq, eig_val = ef.compute_rad_robin_eigenfrequencies(param, l, n) init_eig_funcs = np.array([ ef.SecondOrderRobinEigenfunction(om, param, dz.bounds) for om in eig_freq ]) init_adjoint_eig_funcs = np.array([ ef.SecondOrderRobinEigenfunction(om, adjoint_param, dz.bounds) for om in eig_freq ]) # normalize eigenfunctions and adjoint eigenfunctions adjoint_and_eig_funcs = [ cr.normalize_function(init_eig_funcs[i], init_adjoint_eig_funcs[i]) for i in range(n) ] eig_funcs = np.array([f_tuple[0] for f_tuple in adjoint_and_eig_funcs]) adjoint_eig_funcs = np.array( [f_tuple[1] for f_tuple in adjoint_and_eig_funcs]) # register eigenfunctions register_base("eig_funcs", eig_funcs, overwrite=True) register_base("adjoint_eig_funcs", adjoint_eig_funcs, overwrite=True) # derive initial field variable x(z,0) and weights start_state = cr.Function(lambda z: 0., domain=(0, l)) initial_weights = cr.project_on_base(start_state, adjoint_eig_funcs) # init trajectory u = tr.RadTrajectory(l, T, param, bound_cond_type, actuation_type) # determine (A,B) with weak-formulation (pyinduct) rad_pde = ut.get_parabolic_robin_weak_form("eig_funcs", "adjoint_eig_funcs", u, param, dz.bounds) cf = sim.parse_weak_formulation(rad_pde) ss_weak = cf.convert_to_state_space() # determine (A,B) with modal-transfomation A = np.diag(np.real_if_close(eig_val)) B = a2 * np.array( [adjoint_eig_funcs[i](l) for i in range(len(eig_freq))]) ss_modal = sim.StateSpace("eig_funcs", A, B, input_handle=u) # check if ss_modal.(A,B) is close to ss_weak.(A,B) self.assertTrue( np.allclose(np.sort(np.linalg.eigvals(ss_weak.A[1])), np.sort(np.linalg.eigvals(ss_modal.A[1])), rtol=1e-05, atol=0.)) self.assertTrue( np.allclose(np.array([i[0] for i in ss_weak.B[1]]), ss_modal.B[1])) # display results if show_plots: t, q = sim.simulate_state_space(ss_modal, initial_weights, dt) eval_d = sim.evaluate_approximation("eig_funcs", q, t, dz, spat_order=1) win1 = vis.PgAnimatedPlot([eval_d], title="Test") win2 = vis.PgSurfacePlot(eval_d) app.exec_()