예제 #1
0
eig_funcs = np.asarray(
    [ef.SecondOrderDirichletEigenfunction(eig_freq[i], param, spatial_domain.bounds, norm_fac[i]) for i in range(n)])
re.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, 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)
예제 #2
0
 def test_spat_term(self):
     law = ct.LawEvaluator(
         ct.approximate_control_law(ct.ControlLaw([self.term2])))
     res = law(self.weights, self.weight_label)["output"]
     self.assertAlmostEqual(res, 0)
예제 #3
0
 def test_temp_term(self):
     law = ct.LawEvaluator(
         ct.approximate_control_law(ct.ControlLaw([self.term1])))
     res = law(self.weights, self.weight_label)["output"]
     self.assertTrue(np.equal(res, 6))
예제 #4
0
    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_()
예제 #5
0
    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_()
예제 #6
0
 def test_product_term(self):
     law = ct.LawEvaluator(
         ct.approximate_control_law(ct.ControlLaw([self.term3])))
     res = law(self.weights, self.weight_label)["output"]