Ejemplo n.º 1
0
    def setUp(self):

        self.u = CorrectInput()

        # setup temp and spat domain
        spat_domain = sim.Domain((0, 1), num=3)
        nodes, ini_funcs = sf.cure_interval(sf.LagrangeFirstOrder,
                                            spat_domain.bounds,
                                            node_count=3)
        register_base("init_funcs", ini_funcs, overwrite=True)

        # enter string with mass equations for testing
        int1 = ph.IntegralTerm(
            ph.Product(ph.TemporalDerivedFieldVariable("init_funcs", 2),
                       ph.TestFunction("init_funcs")), spat_domain.bounds)
        s1 = ph.ScalarTerm(
            ph.Product(
                ph.TemporalDerivedFieldVariable("init_funcs", 2, location=0),
                ph.TestFunction("init_funcs", location=0)))
        int2 = ph.IntegralTerm(
            ph.Product(ph.SpatialDerivedFieldVariable("init_funcs", 1),
                       ph.TestFunction("init_funcs", order=1)),
            spat_domain.bounds)
        s2 = ph.ScalarTerm(
            ph.Product(ph.Input(self.u),
                       ph.TestFunction("init_funcs", location=1)), -1)

        string_pde = sim.WeakFormulation([int1, s1, int2, s2])
        self.cf = sim.parse_weak_formulation(string_pde)
        self.ic = np.zeros((3, 2))
Ejemplo n.º 2
0
    def setUp(self):

        self.u = CorrectInput()

        # setup temp and spat domain
        spat_domain = sim.Domain((0, 1), num=3)
        nodes, ini_funcs = sf.cure_interval(sf.LagrangeFirstOrder, spat_domain.bounds, node_count=3)
        register_base("init_funcs", ini_funcs, overwrite=True)

        # enter string with mass equations for testing
        int1 = ph.IntegralTerm(
            ph.Product(ph.TemporalDerivedFieldVariable("init_funcs", 2),
                       ph.TestFunction("init_funcs")), spat_domain.bounds)
        s1 = ph.ScalarTerm(
            ph.Product(ph.TemporalDerivedFieldVariable("init_funcs", 2, location=0),
                       ph.TestFunction("init_funcs", location=0)))
        int2 = ph.IntegralTerm(
            ph.Product(ph.SpatialDerivedFieldVariable("init_funcs", 1),
                       ph.TestFunction("init_funcs", order=1)), spat_domain.bounds)
        s2 = ph.ScalarTerm(
            ph.Product(ph.Input(self.u), ph.TestFunction("init_funcs", location=1)), -1)

        string_pde = sim.WeakFormulation([int1, s1, int2, s2])
        self.cf = sim.parse_weak_formulation(string_pde)
        self.ic = np.zeros((3, 2))
Ejemplo n.º 3
0
    def _build_bases(self, n_modal, orig_params, tar_params, spatial_domain):
        """
        Compute approximation bases for original and target system
        """
        # eigenvalues and -vectors of the original system
        orig_eig_values, orig_eig_vectors = \
            pi.SecondOrderDirichletEigenfunction.cure_interval(spatial_domain,
                                                               param=orig_params,
                                                               n=n_modal)
        norm_orig_eig_vectors = pi.normalize_base(orig_eig_vectors)
        pi.register_base(self.orig_base_lbl, norm_orig_eig_vectors)

        # eigenvectors of the target system (slightly different)
        target_eig_freq = pi.SecondOrderDirichletEigenfunction.eigval_tf_eigfreq(
            tar_params, eig_val=orig_eig_values)
        orig_scale = np.array(
            [vec(0) for vec in norm_orig_eig_vectors.derive(1)])
        tar_scale = orig_scale / target_eig_freq
        _, tar_eig_vectors = pi.SecondOrderDirichletEigenfunction.cure_interval(
            spatial_domain,
            param=tar_params,
            eig_val=orig_eig_values,
            scale=tar_scale)
        pi.register_base(self.tar_base_lbl, tar_eig_vectors)
        if self.verbose:
            pi.visualize_functions(orig_eig_vectors)
            pi.visualize_functions(norm_orig_eig_vectors)
            pi.visualize_functions(tar_eig_vectors)
Ejemplo n.º 4
0
    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_()
Ejemplo n.º 5
0
    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_()
Ejemplo n.º 6
0
    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))
Ejemplo n.º 7
0
    def setUp(self):
        self.u = np.sin
        self.input = ph.Input(self.u)  # control input
        nodes, self.ini_funcs = pyinduct.shapefunctions.cure_interval(pyinduct.shapefunctions.LagrangeFirstOrder, (0, 1), node_count=3)
        register_base("ini_funcs", self.ini_funcs, overwrite=True)

        self.phi = ph.TestFunction("ini_funcs")  # eigenfunction or something else
        self.dphi = ph.TestFunction("ini_funcs", order=1)  # eigenfunction or something else
        self.dphi_at1 = ph.TestFunction("ini_funcs", order=1, location=1)  # eigenfunction or something else
        self.field_var = ph.FieldVariable("ini_funcs")
        self.field_var_at1 = ph.FieldVariable("ini_funcs", location=1)
Ejemplo n.º 8
0
    def setUp(self):
        self.input = ph.Input(np.sin)
        self.phi = np.array([cr.Function(lambda x: 2*x)])
        register_base("phi", self.phi, overwrite=True)
        self.test_func = ph.TestFunction("phi")

        nodes, self.ini_funcs = pyinduct.shapefunctions.cure_interval(pyinduct.shapefunctions.LagrangeFirstOrder, (0, 1), node_count=2)
        register_base("ini_funcs", self.ini_funcs, overwrite=True)
        self.xdt = ph.TemporalDerivedFieldVariable("ini_funcs", order=1)
        self.xdz_at1 = ph.SpatialDerivedFieldVariable("ini_funcs", order=1, location=1)

        self.prod = ph.Product(self.input, self.xdt)
Ejemplo n.º 9
0
    def setUp(self):
        self.node_cnt = 5
        self.time_step = 1e-1
        self.dates = np.arange(0, 10, self.time_step)
        self.spat_int = (0, 1)
        self.nodes = np.linspace(self.spat_int[0], self.spat_int[1], self.node_cnt)

        # create initial functions
        self.nodes, self.funcs = sh.cure_interval(sh.LagrangeFirstOrder, self.spat_int, node_count=self.node_cnt)
        register_base("approx_funcs", self.funcs, overwrite=True)

        # create a slow rising, nearly horizontal line
        self.weights = np.array(list(range(self.node_cnt*self.dates.size))).reshape((self.dates.size, len(self.nodes)))
Ejemplo n.º 10
0
    def setUp(self):
        interval = (0, 10)
        node_cnt = 11
        self.nodes, self.initial_functions = shapefunctions.cure_interval(shapefunctions.LagrangeFirstOrder, interval,
                                                                          node_count=node_cnt)
        register_base("ini_funcs", self.initial_functions, overwrite=True)

        # "real" functions
        self.z_values = np.linspace(interval[0], interval[1], 100*node_cnt)  # because we are smarter
        self.funcs = [core.Function(lambda x: 2),
                      core.Function(lambda x: 2*x),
                      core.Function(lambda x: x**2),
                      core.Function(lambda x: np.sin(x))
                      ]
        self.real_values = [func(self.z_values) for func in self.funcs]
Ejemplo n.º 11
0
    def setUp(self):
        self.input = ph.Input(np.sin)
        self.phi = np.array([cr.Function(lambda x: 2 * x)])
        register_base("phi", self.phi, overwrite=True)
        self.test_func = ph.TestFunction("phi")

        nodes, self.ini_funcs = cure_interval(LagrangeFirstOrder, (0, 1),
                                              node_count=2)
        register_base("ini_funcs", self.ini_funcs, overwrite=True)
        self.xdt = ph.TemporalDerivedFieldVariable("ini_funcs", order=1)
        self.xdz_at1 = ph.SpatialDerivedFieldVariable("ini_funcs",
                                                      order=1,
                                                      location=1)

        self.prod = ph.Product(self.input, self.xdt)
Ejemplo n.º 12
0
    def setUp(self):
        self.u = np.sin
        self.input = ph.Input(self.u)  # control input
        nodes, self.ini_funcs = cure_interval(LagrangeFirstOrder, (0, 1),
                                              node_count=3)
        register_base("ini_funcs", self.ini_funcs, overwrite=True)

        self.phi = ph.TestFunction(
            "ini_funcs")  # eigenfunction or something else
        self.dphi = ph.TestFunction("ini_funcs",
                                    order=1)  # eigenfunction or something else
        self.dphi_at1 = ph.TestFunction(
            "ini_funcs", order=1,
            location=1)  # eigenfunction or something else
        self.field_var = ph.FieldVariable("ini_funcs")
        self.field_var_at1 = ph.FieldVariable("ini_funcs", location=1)
Ejemplo n.º 13
0
    def setUp(self):
        interval = (0, 1)
        nodes, funcs = sf.cure_interval(sf.LagrangeFirstOrder, interval, 3)
        register_base("funcs", funcs, overwrite=True)
        x = ph.FieldVariable("funcs")
        x_dt = ph.TemporalDerivedFieldVariable("funcs", 1)
        x_dz = ph.SpatialDerivedFieldVariable("funcs", 1)
        register_base("scal_func", cr.Function(np.exp), overwrite=True)
        exp = ph.ScalarFunction("scal_func")

        alpha = 2
        self.term1 = ph.IntegralTerm(x_dt, interval, 1 + alpha)
        self.term2 = ph.IntegralTerm(x_dz, interval, 2)
        self.term3 = ph.IntegralTerm(ph.Product(x, exp), interval)

        self.weight_label = "funcs"
        self.weights = np.hstack([1, 1, 1, 2, 2, 2])
Ejemplo n.º 14
0
    def setUp(self):
        interval = (0, 1)
        nodes, funcs = sf.cure_interval(sf.LagrangeFirstOrder, interval, 3)
        register_base("funcs", funcs, overwrite=True)
        x = ph.FieldVariable("funcs")
        x_dt = ph.TemporalDerivedFieldVariable("funcs", 1)
        x_dz = ph.SpatialDerivedFieldVariable("funcs", 1)
        register_base("scal_func", cr.Function(np.exp), overwrite=True)
        exp = ph.ScalarFunction("scal_func")

        alpha = 2
        self.term1 = ph.IntegralTerm(x_dt, interval, 1 + alpha)
        self.term2 = ph.IntegralTerm(x_dz, interval, 2)
        self.term3 = ph.IntegralTerm(ph.Product(x, exp), interval)

        self.weight_label = "funcs"
        self.weights = np.hstack([1, 1, 1, 2, 2, 2])
Ejemplo n.º 15
0
    def setUp(self):
        self.node_cnt = 5
        self.time_step = 1e-1
        self.dates = np.arange(0, 10, self.time_step)
        self.spat_int = (0, 1)
        self.nodes = np.linspace(self.spat_int[0], self.spat_int[1],
                                 self.node_cnt)

        # create initial functions
        self.nodes, self.funcs = sh.cure_interval(sh.LagrangeFirstOrder,
                                                  self.spat_int,
                                                  node_count=self.node_cnt)
        register_base("approx_funcs", self.funcs, overwrite=True)

        # create a slow rising, nearly horizontal line
        self.weights = np.array(list(range(
            self.node_cnt * self.dates.size))).reshape(
                (self.dates.size, len(self.nodes)))
Ejemplo n.º 16
0
    def setUp(self):
        interval = (0, 1)
        nodes, funcs = sf.cure_interval(sf.LagrangeFirstOrder, interval, 3)
        register_base("funcs", funcs, overwrite=True)
        x_at1 = ph.FieldVariable("funcs", location=1)
        x_dt_at1 = ph.TemporalDerivedFieldVariable("funcs", 1, location=1)
        x_dz_at0 = ph.SpatialDerivedFieldVariable("funcs", 1, location=0)

        exp_func = cr.Function(np.exp)
        register_base("exp_func", exp_func, overwrite=True)
        exp_at1 = ph.ScalarFunction("exp_func", location=1)

        alpha = 2
        self.term1 = ph.ScalarTerm(x_dt_at1, 1 + alpha)
        self.term2 = ph.ScalarTerm(x_dz_at0, 2)
        self.term3 = ph.ScalarTerm(ph.Product(x_at1, exp_at1))

        self.weight_label = "funcs"
        self.weights = np.array([1, 1, 1, 2, 2, 2])
Ejemplo n.º 17
0
    def setUp(self):
        interval = (0, 1)
        nodes, funcs = sf.cure_interval(sf.LagrangeFirstOrder, interval, 3)
        register_base("funcs", funcs, overwrite=True)
        x_at1 = ph.FieldVariable("funcs", location=1)
        x_dt_at1 = ph.TemporalDerivedFieldVariable("funcs", 1, location=1)
        x_dz_at0 = ph.SpatialDerivedFieldVariable("funcs", 1, location=0)

        exp_func = cr.Function(np.exp)
        register_base("exp_func", exp_func, overwrite=True)
        exp_at1 = ph.ScalarFunction("exp_func", location=1)

        alpha = 2
        self.term1 = ph.ScalarTerm(x_dt_at1, 1 + alpha)
        self.term2 = ph.ScalarTerm(x_dz_at0, 2)
        self.term3 = ph.ScalarTerm(ph.Product(x_at1, exp_at1))

        self.weight_label = "funcs"
        self.weights = np.array([1, 1, 1, 2, 2, 2])
Ejemplo n.º 18
0
    def shape_generator(self, cls, der_order):
        """
        verify the correct connection with visual feedback
        """

        dz = pi.Domain((0, 1), step=.001)
        dt = pi.Domain((0, 0), num=1)

        nodes, funcs = pi.cure_interval(cls, dz.bounds, node_count=11)
        pi.register_base("test", funcs, overwrite=True)

        # approx_func = pi.Function(np.cos, domain=dz.bounds,
        #                           derivative_handles=[lambda z: -np.sin(z), lambda z: -np.cos(z)])
        approx_func = pi.Function(lambda z: np.sin(3*z), domain=dz.bounds,
                                  derivative_handles=[lambda z: 3*np.cos(3*z), lambda z: -9*np.sin(3*z)])

        weights = approx_func(nodes)

        hull = pi.evaluate_approximation("test", np.atleast_2d(weights),
                                         temp_domain=dt, spat_domain=dz, spat_order=der_order)

        if show_plots:
            # plot shapefunctions
            c_map = pi.visualization.create_colormap(len(funcs))
            pw = pg.plot(title="{}-Test".format(cls.__name__))
            pw.addLegend()
            pw.showGrid(x=True, y=True, alpha=0.5)

            [pw.addItem(pg.PlotDataItem(np.array(dz),
                                        weights[idx]*func.derive(der_order)(dz),
                                        pen=pg.mkPen(color=c_map[idx]),
                                        name="{}.{}".format(cls.__name__, idx)))
             for idx, func in enumerate(funcs)]

            # plot hull curve
            pw.addItem(pg.PlotDataItem(np.array(hull.input_data[1]), hull.output_data[0, :],
                                       pen=pg.mkPen(width=2), name="hull-curve"))
            # plot original function
            pw.addItem(pg.PlotDataItem(np.array(dz), approx_func.derive(der_order)(dz),
                                       pen=pg.mkPen(color="m", width=2, style=pg.QtCore.Qt.DashLine), name="original"))
            pg.QtCore.QCoreApplication.instance().exec_()

        return np.sum(np.abs(hull.output_data[0, :] - approx_func.derive(der_order)(dz)))
Ejemplo n.º 19
0
    def __init__(self, params, n_modal, spat_dom):
        a2 = params[0]
        z_start, z_end = spat_dom.bounds
        self.base_lbl = "eigen_vectors"

        # eigenvalues and -vectors of the system system
        eig_values, eig_vectors = \
            pi.SecondOrderDirichletEigenfunction.cure_interval(spat_dom,
                                                               param=params,
                                                               n=n_modal)
        # pi.visualize_functions(orig_eig_vectors)
        norm_eig_vectors = pi.normalize_base(eig_vectors)
        # pi.visualize_functions(normalized_eig_vectors)
        pi.register_base(self.base_lbl, norm_eig_vectors)

        self.a_mat = np.diag(np.real_if_close(eig_values))
        b_mat = -a2 * np.array(
            [eig_vect.derive()(z_end) for eig_vect in norm_eig_vectors])
        self.b_mat = np.reshape(b_mat, (b_mat.size, 1))
Ejemplo n.º 20
0
    def setUp(self):
        # enter string with mass equations
        self.u = cr.Function(lambda x: 0)
        interval = (0, 1)
        nodes, ini_funcs = pyinduct.shapefunctions.cure_interval(pyinduct.shapefunctions.LagrangeFirstOrder, interval, node_count=3)
        register_base("init_funcs", ini_funcs, overwrite=True)
        int1 = ph.IntegralTerm(
            ph.Product(ph.TemporalDerivedFieldVariable("init_funcs", 2),
                       ph.TestFunction("init_funcs")), interval)
        s1 = ph.ScalarTerm(
            ph.Product(ph.TemporalDerivedFieldVariable("init_funcs", 2, location=0),
                       ph.TestFunction("init_funcs", location=0)))
        int2 = ph.IntegralTerm(
            ph.Product(ph.SpatialDerivedFieldVariable("init_funcs", 1),
                       ph.TestFunction("init_funcs", order=1)), interval)
        s2 = ph.ScalarTerm(
            ph.Product(ph.Input(self.u), ph.TestFunction("init_funcs", location=1)), -1)

        string_pde = sim.WeakFormulation([int1, s1, int2, s2])
        self.cf = sim.parse_weak_formulation(string_pde)
Ejemplo n.º 21
0
    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)])
Ejemplo n.º 22
0
    def setUp(self):
        self.input = ph.Input(np.sin)

        phi = cr.Function(np.sin)
        psi = cr.Function(np.cos)
        self.t_funcs = np.array([phi, psi])
        register_base("funcs", self.t_funcs, overwrite=True)
        self.test_funcs = ph.TestFunction("funcs")

        self.s_funcs = np.array([cr.Function(self.scale)])[[0, 0]]
        register_base("scale_funcs", self.s_funcs, overwrite=True)
        self.scale_funcs = ph.ScalarFunction("scale_funcs")

        nodes, self.ini_funcs = pyinduct.shapefunctions.cure_interval(pyinduct.shapefunctions.LagrangeFirstOrder, (0, 1), node_count=2)
        register_base("prod_ini_funcs", self.ini_funcs, overwrite=True)
        self.field_var = ph.FieldVariable("prod_ini_funcs")
        self.field_var_dz = ph.SpatialDerivedFieldVariable("prod_ini_funcs", 1)
Ejemplo n.º 23
0
    def setUp(self):
        self.input = ph.Input(np.sin)

        phi = cr.Function(np.sin)
        psi = cr.Function(np.cos)
        self.t_funcs = np.array([phi, psi])
        register_base("funcs", self.t_funcs, overwrite=True)
        self.test_funcs = ph.TestFunction("funcs")

        self.s_funcs = np.array([cr.Function(self.scale)])[[0, 0]]
        register_base("scale_funcs", self.s_funcs, overwrite=True)
        self.scale_funcs = ph.ScalarFunction("scale_funcs")

        nodes, self.ini_funcs = cure_interval(LagrangeFirstOrder, (0, 1),
                                              node_count=2)
        register_base("prod_ini_funcs", self.ini_funcs, overwrite=True)
        self.field_var = ph.FieldVariable("prod_ini_funcs")
        self.field_var_dz = ph.SpatialDerivedFieldVariable("prod_ini_funcs", 1)
Ejemplo n.º 24
0
    def test_it(self):
        # system/simulation parameters
        actuation_type = 'robin'
        bound_cond_type = 'robin'

        self.l = 1.
        spatial_disc = 10
        self.dz = sim.Domain(bounds=(0, self.l), num=spatial_disc)

        self.T = 1.
        temporal_disc = 1e2
        self.dt = sim.Domain(bounds=(0, self.T), num=temporal_disc)

        self.n = 10

        # original system parameters
        a2 = 1.5
        a1_z = cr.Function(lambda z: 1, derivative_handles=[lambda z: 0])
        a0_z = lambda z: 3
        alpha = -2
        beta = -3
        self.param = [a2, a1_z, a0_z, alpha, beta]

        # target system parameters (controller parameters)
        a1_t = -5
        a0_t = -25
        alpha_t = 3
        beta_t = 2
        self.param_t = [a2, a1_t, a0_t, alpha_t, beta_t]
        adjoint_param_t = ef.get_adjoint_rad_evp_param(self.param_t)

        # original intermediate ("_i") and traget intermediate ("_ti") system parameters
        _, _, a0_i, alpha_i, beta_i = ef.transform2intermediate(self.param, d_end=self.l)
        self.param_i = a2, 0, a0_i, alpha_i, beta_i
        _, _, a0_ti, alpha_ti, beta_ti = ef.transform2intermediate(self.param_t)
        self.param_ti = a2, 0, a0_ti, alpha_ti, beta_ti

        # create (not normalized) target (_t) eigenfunctions
        eig_freq_t, self.eig_val_t = ef.compute_rad_robin_eigenfrequencies(self.param_t, self.l, self.n)
        init_eig_funcs_t = np.array([ef.SecondOrderRobinEigenfunction(om, self.param_t, self.dz.bounds)
                                     for om in eig_freq_t])
        init_adjoint_eig_funcs_t = np.array([ef.SecondOrderRobinEigenfunction(om, adjoint_param_t, self.dz.bounds)
                                             for om in eig_freq_t])

        # normalize eigenfunctions and adjoint eigenfunctions
        adjoint_and_eig_funcs_t = [cr.normalize_function(init_eig_funcs_t[i], init_adjoint_eig_funcs_t[i])
                                   for i in range(self.n)]
        eig_funcs_t = np.array([f_tuple[0] for f_tuple in adjoint_and_eig_funcs_t])
        self.adjoint_eig_funcs_t = np.array([f_tuple[1] for f_tuple in adjoint_and_eig_funcs_t])

        # # transformed original eigenfunctions
        self.eig_funcs = np.array([ef.TransformedSecondOrderEigenfunction(self.eig_val_t[i],
                                                                          [eig_funcs_t[i](0), alpha * eig_funcs_t[i](0),
                                                                           0, 0],
                                                                          [a2, a1_z, a0_z],
                                                                          np.linspace(0, self.l, 1e4))
                                   for i in range(self.n)])

        # create testfunctions
        nodes, self.fem_funcs = sf.cure_interval(sf.LagrangeFirstOrder,
                                                                      self.dz.bounds,
                                                                      node_count=self.n)

        # register functions
        register_base("eig_funcs_t", eig_funcs_t, overwrite=True)
        register_base("adjoint_eig_funcs_t", self.adjoint_eig_funcs_t, overwrite=True)
        register_base("eig_funcs", self.eig_funcs, overwrite=True)
        register_base("fem_funcs", self.fem_funcs, overwrite=True)

        # init trajectory
        self.traj = tr.RadTrajectory(self.l, self.T, self.param_ti, bound_cond_type, actuation_type)

        # original () and target (_t) field variable
        fem_field_variable = ph.FieldVariable("fem_funcs", location=self.l)
        field_variable_t = ph.FieldVariable("eig_funcs_t", weight_label="eig_funcs", location=self.l)
        d_field_variable_t = ph.SpatialDerivedFieldVariable("eig_funcs_t", 1, weight_label="eig_funcs", location=self.l)
        field_variable = ph.FieldVariable("eig_funcs", location=self.l)
        d_field_variable = ph.SpatialDerivedFieldVariable("eig_funcs", 1, location=self.l)
        # intermediate (_i) and target intermediate (_ti) transformations by z=l

        #  x_i  = x   * transform_i_at_l
        self.transform_i_at_l = np.exp(integrate.quad(lambda z: a1_z(z) / 2 / a2, 0, self.l)[0])

        # x  = x_i   * inv_transform_i_at_l
        self.inv_transform_i_at_l = np.exp(-integrate.quad(lambda z: a1_z(z) / 2 / a2, 0, self.l)[0])

        # x_ti = x_t * transform_ti_at_l
        self.transform_ti_at_l = np.exp(a1_t / 2 / a2 * self.l)

        # intermediate (_i) and target intermediate (_ti) field variable (list of scalar terms = sum of scalar terms)
        self.x_fem_i_at_l = [ph.ScalarTerm(fem_field_variable, self.transform_i_at_l)]
        self.x_i_at_l = [ph.ScalarTerm(field_variable, self.transform_i_at_l)]
        self.xd_i_at_l = [ph.ScalarTerm(d_field_variable, self.transform_i_at_l),
                          ph.ScalarTerm(field_variable, self.transform_i_at_l * a1_z(self.l) / 2 / a2)]
        self.x_ti_at_l = [ph.ScalarTerm(field_variable_t, self.transform_ti_at_l)]
        self.xd_ti_at_l = [ph.ScalarTerm(d_field_variable_t, self.transform_ti_at_l),
                           ph.ScalarTerm(field_variable_t, self.transform_ti_at_l * a1_t / 2 / a2)]

        # discontinuous operator (Kx)(t) = int_kernel_zz(l)*x(l,t)
        self.int_kernel_zz = alpha_ti - alpha_i + integrate.quad(lambda z: (a0_i(z) - a0_ti) / 2 / a2, 0, self.l)[0]

        controller = ut.get_parabolic_robin_backstepping_controller(state=self.x_fem_i_at_l,
                                                                    approx_state=self.x_i_at_l,
                                                                    d_approx_state=self.xd_i_at_l,
                                                                    approx_target_state=self.x_ti_at_l,
                                                                    d_approx_target_state=self.xd_ti_at_l,
                                                                    integral_kernel_zz=self.int_kernel_zz,
                                                                    original_beta=beta_i,
                                                                    target_beta=beta_ti,
                                                                    trajectory=self.traj,
                                                                    scale=self.inv_transform_i_at_l)

        rad_pde = ut.get_parabolic_robin_weak_form("fem_funcs", "fem_funcs", controller, self.param, self.dz.bounds)
        cf = sim.parse_weak_formulation(rad_pde)
        ss_weak = cf.convert_to_state_space()

        # simulate
        t, q = sim.simulate_state_space(ss_weak, np.zeros((len(self.fem_funcs))), self.dt)
        eval_d = sim.evaluate_approximation("fem_funcs", q, t, self.dz)
        x_0t = eval_d.output_data[:, 0]
        yc, tc = tr.gevrey_tanh(self.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_()
Ejemplo n.º 25
0
    def setUp(self):
        # original system parameters
        a2 = 1.5
        a1 = 2.5
        a0 = 28
        alpha = -2
        beta = -3
        self.param = [a2, a1, a0, alpha, beta]
        adjoint_param = ef.get_adjoint_rad_evp_param(self.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
        self.param_t = [a2, a1_t, a0_t, alpha_t, beta_t]

        # original intermediate ("_i") and target intermediate ("_ti") system parameters
        _, _, a0_i, self.alpha_i, self.beta_i = ef.transform2intermediate(self.param)
        self.param_i = a2, 0, a0_i, self.alpha_i, self.beta_i
        _, _, a0_ti, self.alpha_ti, self.beta_ti = ef.transform2intermediate(self.param_t)
        self.param_ti = a2, 0, a0_ti, self.alpha_ti, self.beta_ti

        # system/simulation parameters
        actuation_type = 'robin'
        bound_cond_type = 'robin'
        self.l = 1.
        spatial_disc = 10
        self.dz = sim.Domain(bounds=(0, self.l), num=spatial_disc)

        self.T = 1.
        temporal_disc = 1e2
        self.dt = sim.Domain(bounds=(0, self.T), num=temporal_disc)
        self.n = 10

        # create (not normalized) eigenfunctions
        eig_freq, self.eig_val = ef.compute_rad_robin_eigenfrequencies(self.param, self.l, self.n)
        init_eig_funcs = np.array([ef.SecondOrderRobinEigenfunction(om, self.param, self.dz.bounds) for om in eig_freq])
        init_adjoint_eig_funcs = np.array([ef.SecondOrderRobinEigenfunction(om, adjoint_param, self.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(self.n)]
        eig_funcs = np.array([f_tuple[0] for f_tuple in adjoint_and_eig_funcs])
        self.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 - self.eig_val) / a2)
        eig_funcs_t = np.array([ef.SecondOrderRobinEigenfunction(eig_freq_t[i],
                                                                 self.param_t, self.dz.bounds).scale(eig_funcs[i](0))
                                for i in range(self.n)])

        # create testfunctions
        nodes, self.fem_funcs = sf.cure_interval(sf.LagrangeFirstOrder,
                                                                      self.dz.bounds,
                                                                      node_count=self.n)

        # register eigenfunctions
        register_base("eig_funcs", eig_funcs, overwrite=True)
        register_base("adjoint_eig_funcs", self.adjoint_eig_funcs, overwrite=True)
        register_base("eig_funcs_t", eig_funcs_t, overwrite=True)
        register_base("fem_funcs", self.fem_funcs, overwrite=True)

        # init trajectory
        self.traj = tr.RadTrajectory(self.l, self.T, self.param_ti, bound_cond_type, actuation_type)

        # original () and target (_t) field variable
        fem_field_variable = ph.FieldVariable("fem_funcs", location=self.l)
        field_variable = ph.FieldVariable("eig_funcs", location=self.l)
        d_field_variable = ph.SpatialDerivedFieldVariable("eig_funcs", 1, location=self.l)
        field_variable_t = ph.FieldVariable("eig_funcs_t", weight_label="eig_funcs", location=self.l)
        d_field_variable_t = ph.SpatialDerivedFieldVariable("eig_funcs_t", 1, weight_label="eig_funcs", location=self.l)

        # intermediate (_i) and target intermediate (_ti) transformations by z=l
        self.transform_i = lambda z: np.exp(a1 / 2 / a2 * z)  # x_i  = x   * transform_i
        self.transform_ti = lambda z: np.exp(a1_t / 2 / a2 * z)  # x_ti = x_t * transform_ti

        # intermediate (_i) and target intermediate (_ti) field variable (list of scalar terms = sum of scalar terms)
        self.x_fem_i_at_l = [ph.ScalarTerm(fem_field_variable, self.transform_i(self.l))]
        self.x_i_at_l = [ph.ScalarTerm(field_variable, self.transform_i(self.l))]
        self.xd_i_at_l = [ph.ScalarTerm(d_field_variable, self.transform_i(self.l)),
                          ph.ScalarTerm(field_variable, self.transform_i(self.l) * a1 / 2 / a2)]
        self.x_ti_at_l = [ph.ScalarTerm(field_variable_t, self.transform_ti(self.l))]
        self.xd_ti_at_l = [ph.ScalarTerm(d_field_variable_t, self.transform_ti(self.l)),
                           ph.ScalarTerm(field_variable_t, self.transform_ti(self.l) * a1_t / 2 / a2)]

        # discontinuous operator (Kx)(t) = int_kernel_zz(l)*x(l,t)
        self.int_kernel_zz = lambda z: self.alpha_ti - self.alpha_i + (a0_i - a0_ti) / 2 / a2 * z
Ejemplo n.º 26
0
 def setUp(self):
     self.psi = cr.Function(np.sin)
     register_base("funcs", self.psi, overwrite=True)
     self.funcs = ph.TestFunction("funcs")
Ejemplo n.º 27
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_()
Ejemplo n.º 28
0
    def setUp(self):
        # original system parameters
        a2 = 1.5
        a1 = 2.5
        a0 = 28
        alpha = -2
        beta = -3
        self.param = [a2, a1, a0, alpha, beta]
        adjoint_param = ef.get_adjoint_rad_evp_param(self.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
        self.param_t = [a2, a1_t, a0_t, alpha_t, beta_t]

        # original intermediate ("_i") and target intermediate ("_ti") system parameters
        _, _, a0_i, self.alpha_i, self.beta_i = ef.transform2intermediate(
            self.param)
        self.param_i = a2, 0, a0_i, self.alpha_i, self.beta_i
        _, _, a0_ti, self.alpha_ti, self.beta_ti = ef.transform2intermediate(
            self.param_t)
        self.param_ti = a2, 0, a0_ti, self.alpha_ti, self.beta_ti

        # system/simulation parameters
        actuation_type = 'robin'
        bound_cond_type = 'robin'
        self.l = 1.
        spatial_disc = 10
        self.dz = sim.Domain(bounds=(0, self.l), num=spatial_disc)

        self.T = 1.
        temporal_disc = 1e2
        self.dt = sim.Domain(bounds=(0, self.T), num=temporal_disc)
        self.n = 10

        # create (not normalized) eigenfunctions
        eig_freq, self.eig_val = ef.compute_rad_robin_eigenfrequencies(
            self.param, self.l, self.n)
        init_eig_funcs = np.array([
            ef.SecondOrderRobinEigenfunction(om, self.param, self.dz.bounds)
            for om in eig_freq
        ])
        init_adjoint_eig_funcs = np.array([
            ef.SecondOrderRobinEigenfunction(om, adjoint_param, self.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(self.n)
        ]
        eig_funcs = np.array([f_tuple[0] for f_tuple in adjoint_and_eig_funcs])
        self.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 - self.eig_val) / a2)
        eig_funcs_t = np.array([
            ef.SecondOrderRobinEigenfunction(eig_freq_t[i], self.param_t,
                                             self.dz.bounds).scale(
                                                 eig_funcs[i](0))
            for i in range(self.n)
        ])

        # create testfunctions
        nodes, self.fem_funcs = sf.cure_interval(sf.LagrangeFirstOrder,
                                                 self.dz.bounds,
                                                 node_count=self.n)

        # register eigenfunctions
        register_base("eig_funcs", eig_funcs, overwrite=True)
        register_base("adjoint_eig_funcs",
                      self.adjoint_eig_funcs,
                      overwrite=True)
        register_base("eig_funcs_t", eig_funcs_t, overwrite=True)
        register_base("fem_funcs", self.fem_funcs, overwrite=True)

        # init trajectory
        self.traj = tr.RadTrajectory(self.l, self.T, self.param_ti,
                                     bound_cond_type, actuation_type)

        # original () and target (_t) field variable
        fem_field_variable = ph.FieldVariable("fem_funcs", location=self.l)
        field_variable = ph.FieldVariable("eig_funcs", location=self.l)
        d_field_variable = ph.SpatialDerivedFieldVariable("eig_funcs",
                                                          1,
                                                          location=self.l)
        field_variable_t = ph.FieldVariable("eig_funcs_t",
                                            weight_label="eig_funcs",
                                            location=self.l)
        d_field_variable_t = ph.SpatialDerivedFieldVariable(
            "eig_funcs_t", 1, weight_label="eig_funcs", location=self.l)

        # intermediate (_i) and target intermediate (_ti) transformations by z=l
        self.transform_i = lambda z: np.exp(a1 / 2 / a2 * z
                                            )  # x_i  = x   * transform_i
        self.transform_ti = lambda z: np.exp(a1_t / 2 / a2 * z
                                             )  # x_ti = x_t * transform_ti

        # intermediate (_i) and target intermediate (_ti) field variable (list of scalar terms = sum of scalar terms)
        self.x_fem_i_at_l = [
            ph.ScalarTerm(fem_field_variable, self.transform_i(self.l))
        ]
        self.x_i_at_l = [
            ph.ScalarTerm(field_variable, self.transform_i(self.l))
        ]
        self.xd_i_at_l = [
            ph.ScalarTerm(d_field_variable, self.transform_i(self.l)),
            ph.ScalarTerm(field_variable,
                          self.transform_i(self.l) * a1 / 2 / a2)
        ]
        self.x_ti_at_l = [
            ph.ScalarTerm(field_variable_t, self.transform_ti(self.l))
        ]
        self.xd_ti_at_l = [
            ph.ScalarTerm(d_field_variable_t, self.transform_ti(self.l)),
            ph.ScalarTerm(field_variable_t,
                          self.transform_ti(self.l) * a1_t / 2 / a2)
        ]

        # discontinuous operator (Kx)(t) = int_kernel_zz(l)*x(l,t)
        self.int_kernel_zz = lambda z: self.alpha_ti - self.alpha_i + (
            a0_i - a0_ti) / 2 / a2 * z
Ejemplo n.º 29
0
    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_()
Ejemplo n.º 30
0
    def test_modal(self):
        order = 8

        def char_eq(w):
            return w * (np.sin(w) + self.params.m * w * np.cos(w))

        def phi_k_factory(freq, derivative_order=0):
            def eig_func(z):
                return np.cos(
                    freq * z) - self.params.m * freq * np.sin(freq * z)

            def eig_func_dz(z):
                return -freq * (np.sin(freq * z) +
                                self.params.m * freq * np.cos(freq * z))

            def eig_func_ddz(z):
                return freq**2 * (-np.cos(freq * z) +
                                  self.params.m * freq * np.sin(freq * z))

            if derivative_order == 0:
                return eig_func
            elif derivative_order == 1:
                return eig_func_dz
            elif derivative_order == 2:
                return eig_func_ddz
            else:
                raise ValueError

        # create eigenfunctions
        eig_frequencies = ut.find_roots(char_eq,
                                        n_roots=order,
                                        grid=np.arange(0, 1e3, 2),
                                        rtol=-2)
        print("eigenfrequencies:")
        print(eig_frequencies)

        # create eigen function vectors
        class SWMFunctionVector(cr.ComposedFunctionVector):
            """
            String With Mass Function Vector, necessary due to manipulated scalar product
            """
            @property
            def func(self):
                return self.members["funcs"][0]

            @property
            def scalar(self):
                return self.members["scalars"][0]

        eig_vectors = []
        for n in range(order):
            eig_vectors.append(
                SWMFunctionVector(
                    cr.Function(phi_k_factory(eig_frequencies[n]),
                                derivative_handles=[
                                    phi_k_factory(eig_frequencies[n],
                                                  der_order)
                                    for der_order in range(1, 3)
                                ],
                                domain=self.dz.bounds,
                                nonzero=self.dz.bounds),
                    phi_k_factory(eig_frequencies[n])(0)))

        # normalize eigen vectors
        norm_eig_vectors = [cr.normalize_function(vec) for vec in eig_vectors]
        norm_eig_funcs = np.array([vec.func for vec in norm_eig_vectors])
        register_base("norm_eig_funcs", norm_eig_funcs, overwrite=True)

        norm_eig_funcs[0](1)

        # debug print eigenfunctions
        if 0:
            func_vals = []
            for vec in eig_vectors:
                func_vals.append(np.vectorize(vec.func)(self.dz))

            norm_func_vals = []
            for func in norm_eig_funcs:
                norm_func_vals.append(np.vectorize(func)(self.dz))

            clrs = ["r", "g", "b", "c", "m", "y", "k", "w"]
            for n in range(1, order + 1, len(clrs)):
                pw_phin_k = pg.plot(title="phin_k for k in [{0}, {1}]".format(
                    n, min(n + len(clrs), order)))
                for k in range(len(clrs)):
                    if k + n > order:
                        break
                    pw_phin_k.plot(x=np.array(self.dz),
                                   y=norm_func_vals[n + k - 1],
                                   pen=clrs[k])

            app.exec_()

        # create terms of weak formulation
        terms = [
            ph.IntegralTerm(ph.Product(
                ph.FieldVariable("norm_eig_funcs", order=(2, 0)),
                ph.TestFunction("norm_eig_funcs")),
                            self.dz.bounds,
                            scale=-1),
            ph.ScalarTerm(ph.Product(
                ph.FieldVariable("norm_eig_funcs", order=(2, 0), location=0),
                ph.TestFunction("norm_eig_funcs", location=0)),
                          scale=-1),
            ph.ScalarTerm(
                ph.Product(ph.Input(self.u),
                           ph.TestFunction("norm_eig_funcs", location=1))),
            ph.ScalarTerm(ph.Product(
                ph.FieldVariable("norm_eig_funcs", location=1),
                ph.TestFunction("norm_eig_funcs", order=1, location=1)),
                          scale=-1),
            ph.ScalarTerm(
                ph.Product(
                    ph.FieldVariable("norm_eig_funcs", location=0),
                    ph.TestFunction("norm_eig_funcs", order=1, location=0))),
            ph.IntegralTerm(
                ph.Product(ph.FieldVariable("norm_eig_funcs"),
                           ph.TestFunction("norm_eig_funcs", order=2)),
                self.dz.bounds)
        ]
        modal_pde = sim.WeakFormulation(terms, name="swm_lib-modal")
        eval_data = sim.simulate_system(modal_pde,
                                        self.ic,
                                        self.dt,
                                        self.dz,
                                        der_orders=(2, 0))

        # display results
        if show_plots:
            win = vis.PgAnimatedPlot(eval_data[0:2],
                                     title="modal 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))
Ejemplo n.º 31
0
    def test_modal(self):
        order = 8

        def char_eq(w):
            return w * (np.sin(w) + self.params.m * w * np.cos(w))

        def phi_k_factory(freq, derivative_order=0):
            def eig_func(z):
                return np.cos(freq * z) - self.params.m * freq * np.sin(freq * z)

            def eig_func_dz(z):
                return -freq * (np.sin(freq * z) + self.params.m * freq * np.cos(freq * z))

            def eig_func_ddz(z):
                return freq ** 2 * (-np.cos(freq * z) + self.params.m * freq * np.sin(freq * z))

            if derivative_order == 0:
                return eig_func
            elif derivative_order == 1:
                return eig_func_dz
            elif derivative_order == 2:
                return eig_func_ddz
            else:
                raise ValueError

        # create eigenfunctions
        eig_frequencies = ut.find_roots(char_eq, n_roots=order, grid=np.arange(0, 1e3, 2), rtol=-2)
        print("eigenfrequencies:")
        print eig_frequencies

        # create eigen function vectors
        class SWMFunctionVector(cr.ComposedFunctionVector):
            """
            String With Mass Function Vector, necessary due to manipulated scalar product
            """
            @property
            def func(self):
                return self.members["funcs"][0]

            @property
            def scalar(self):
                return self.members["scalars"][0]

        eig_vectors = []
        for n in range(order):
            eig_vectors.append(SWMFunctionVector(cr.Function(phi_k_factory(eig_frequencies[n]),
                                                             derivative_handles=[
                                                                 phi_k_factory(eig_frequencies[n], der_order)
                                                                 for der_order in range(1, 3)],
                                                             domain=self.dz.bounds,
                                                             nonzero=self.dz.bounds),
                                                 phi_k_factory(eig_frequencies[n])(0)))

        # normalize eigen vectors
        norm_eig_vectors = [cr.normalize_function(vec) for vec in eig_vectors]
        norm_eig_funcs = np.array([vec.func for vec in norm_eig_vectors])
        register_base("norm_eig_funcs", norm_eig_funcs, overwrite=True)

        norm_eig_funcs[0](1)

        # debug print eigenfunctions
        if 0:
            func_vals = []
            for vec in eig_vectors:
                func_vals.append(np.vectorize(vec.func)(self.dz))

            norm_func_vals = []
            for func in norm_eig_funcs:
                norm_func_vals.append(np.vectorize(func)(self.dz))

            clrs = ["r", "g", "b", "c", "m", "y", "k", "w"]
            for n in range(1, order + 1, len(clrs)):
                pw_phin_k = pg.plot(title="phin_k for k in [{0}, {1}]".format(n, min(n + len(clrs), order)))
                for k in range(len(clrs)):
                    if k + n > order:
                        break
                    pw_phin_k.plot(x=np.array(self.dz), y=norm_func_vals[n + k - 1], pen=clrs[k])

            app.exec_()

        # create terms of weak formulation
        terms = [ph.IntegralTerm(ph.Product(ph.FieldVariable("norm_eig_funcs", order=(2, 0)),
                                            ph.TestFunction("norm_eig_funcs")),
                                 self.dz.bounds, scale=-1),
                 ph.ScalarTerm(ph.Product(
                     ph.FieldVariable("norm_eig_funcs", order=(2, 0), location=0),
                     ph.TestFunction("norm_eig_funcs", location=0)),
                     scale=-1),
                 ph.ScalarTerm(ph.Product(ph.Input(self.u),
                                          ph.TestFunction("norm_eig_funcs", location=1))),
                 ph.ScalarTerm(
                     ph.Product(ph.FieldVariable("norm_eig_funcs", location=1),
                                ph.TestFunction("norm_eig_funcs", order=1, location=1)),
                     scale=-1),
                 ph.ScalarTerm(ph.Product(ph.FieldVariable("norm_eig_funcs", location=0),
                                          ph.TestFunction("norm_eig_funcs", order=1,
                                                          location=0))),
                 ph.IntegralTerm(ph.Product(ph.FieldVariable("norm_eig_funcs"),
                                            ph.TestFunction("norm_eig_funcs", order=2)),
                                 self.dz.bounds)]
        modal_pde = sim.WeakFormulation(terms, name="swm_lib-modal")
        eval_data = sim.simulate_system(modal_pde, self.ic, self.dt, self.dz, der_orders=(2, 0))

        # display results
        if show_plots:
            win = vis.PgAnimatedPlot(eval_data[0:2], title="modal 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))
Ejemplo n.º 32
0
    def setUp(self):
        # scalars
        self.scalars = ph.Scalars(np.vstack(list(range(3))))

        # inputs
        self.u = np.sin
        self.input = ph.Input(self.u)
        self.input_squared = ph.Input(self.u, exponent=2)

        nodes, self.ini_funcs = sf.cure_interval(sf.LagrangeFirstOrder, (0, 1),
                                                 node_count=3)

        # TestFunctions
        register_base("ini_funcs", self.ini_funcs, overwrite=True)
        self.phi = ph.TestFunction("ini_funcs")
        self.phi_at0 = ph.TestFunction("ini_funcs", location=0)
        self.phi_at1 = ph.TestFunction("ini_funcs", location=1)
        self.dphi = ph.TestFunction("ini_funcs", order=1)
        self.dphi_at1 = ph.TestFunction("ini_funcs", order=1, location=1)

        # FieldVars
        self.field_var = ph.FieldVariable("ini_funcs")
        self.field_var_squared = ph.FieldVariable("ini_funcs", exponent=2)

        self.odd_weight_field_var = ph.FieldVariable(
            "ini_funcs", weight_label="special_weights")
        self.field_var_at1 = ph.FieldVariable("ini_funcs", location=1)
        self.field_var_at1_squared = ph.FieldVariable("ini_funcs",
                                                      location=1,
                                                      exponent=2)

        self.field_var_dz = ph.SpatialDerivedFieldVariable("ini_funcs", 1)
        self.field_var_dz_at1 = ph.SpatialDerivedFieldVariable("ini_funcs",
                                                               1,
                                                               location=1)

        self.field_var_ddt = ph.TemporalDerivedFieldVariable("ini_funcs", 2)
        self.field_var_ddt_at0 = ph.TemporalDerivedFieldVariable("ini_funcs",
                                                                 2,
                                                                 location=0)
        self.field_var_ddt_at1 = ph.TemporalDerivedFieldVariable("ini_funcs",
                                                                 2,
                                                                 location=1)

        # create all possible kinds of input variables
        self.input_term1 = ph.ScalarTerm(ph.Product(self.phi_at1, self.input))
        self.input_term1_swapped = ph.ScalarTerm(
            ph.Product(self.input, self.phi_at1))
        self.input_term1_squared = ph.ScalarTerm(
            ph.Product(self.input_squared, self.phi_at1))

        self.input_term2 = ph.ScalarTerm(ph.Product(self.dphi_at1, self.input))
        self.func_term = ph.ScalarTerm(self.phi_at1)

        # same goes for field variables
        self.field_term_at1 = ph.ScalarTerm(self.field_var_at1)
        self.field_term_at1_squared = ph.ScalarTerm(self.field_var_at1_squared)
        self.field_term_dz_at1 = ph.ScalarTerm(self.field_var_dz_at1)
        self.field_term_ddt_at1 = ph.ScalarTerm(self.field_var_ddt_at1)

        self.field_int = ph.IntegralTerm(self.field_var, (0, 1))
        self.field_squared_int = ph.IntegralTerm(self.field_var_squared,
                                                 (0, 1))
        self.field_dz_int = ph.IntegralTerm(self.field_var_dz, (0, 1))
        self.field_ddt_int = ph.IntegralTerm(self.field_var_ddt, (0, 1))

        self.prod_term_fs_at1 = ph.ScalarTerm(
            ph.Product(self.field_var_at1, self.scalars))
        self.prod_int_fs = ph.IntegralTerm(
            ph.Product(self.field_var, self.scalars), (0, 1))
        self.prod_int_f_f = ph.IntegralTerm(
            ph.Product(self.field_var, self.phi), (0, 1))
        self.prod_int_f_squared_f = ph.IntegralTerm(
            ph.Product(self.field_var_squared, self.phi), (0, 1))
        self.prod_int_f_f_swapped = ph.IntegralTerm(
            ph.Product(self.phi, self.field_var), (0, 1))

        self.prod_int_f_at1_f = ph.IntegralTerm(
            ph.Product(self.field_var_at1, self.phi), (0, 1))
        self.prod_int_f_at1_squared_f = ph.IntegralTerm(
            ph.Product(self.field_var_at1_squared, self.phi), (0, 1))

        self.prod_int_f_f_at1 = ph.IntegralTerm(
            ph.Product(self.field_var, self.phi_at1), (0, 1))
        self.prod_int_f_squared_f_at1 = ph.IntegralTerm(
            ph.Product(self.field_var_squared, self.phi_at1), (0, 1))

        self.prod_term_f_at1_f_at1 = ph.ScalarTerm(
            ph.Product(self.field_var_at1, self.phi_at1))
        self.prod_term_f_at1_squared_f_at1 = ph.ScalarTerm(
            ph.Product(self.field_var_at1_squared, self.phi_at1))

        self.prod_int_fddt_f = ph.IntegralTerm(
            ph.Product(self.field_var_ddt, self.phi), (0, 1))
        self.prod_term_fddt_at0_f_at0 = ph.ScalarTerm(
            ph.Product(self.field_var_ddt_at0, self.phi_at0))

        self.prod_term_f_at1_dphi_at1 = ph.ScalarTerm(
            ph.Product(self.field_var_at1, self.dphi_at1))

        self.temp_int = ph.IntegralTerm(
            ph.Product(self.field_var_ddt, self.phi), (0, 1))
        self.spat_int = ph.IntegralTerm(
            ph.Product(self.field_var_dz, self.dphi), (0, 1))
        self.spat_int_asymmetric = ph.IntegralTerm(
            ph.Product(self.field_var_dz, self.phi), (0, 1))

        self.alternating_weights_term = ph.IntegralTerm(
            self.odd_weight_field_var, (0, 1))
Ejemplo n.º 33
0
 def setUp(self):
     nodes, ini_funcs = cure_interval(LagrangeFirstOrder, (0, 1),
                                      node_count=2)
     register_base("test_funcs", ini_funcs, overwrite=True)
Ejemplo n.º 34
0
 def setUp(self):
     nodes, ini_funcs = cure_interval(LagrangeFirstOrder, (0, 1), node_count=2)
     register_base("test_funcs", ini_funcs, overwrite=True)
Ejemplo n.º 35
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_()
Ejemplo n.º 36
0
    def test_fem(self):

        # system/simulation parameters
        actuation_type = 'robin'
        bound_cond_type = 'robin'

        self.l = 1.
        spatial_disc = 30
        self.dz = sim.Domain(bounds=(0, self.l), num=spatial_disc)

        self.T = 1.
        temporal_disc = 1e2
        self.dt = sim.Domain(bounds=(0, self.T), num=temporal_disc)
        self.n = 12

        # original system parameters
        a2 = 1.5
        a1 = 2.5
        a0 = 28
        alpha = -2
        beta = -3
        self.param = [a2, a1, a0, alpha, beta]
        adjoint_param = ef.get_adjoint_rad_evp_param(self.param)

        # target system parameters (controller parameters)
        a1_t = -5
        a0_t = -25
        alpha_t = 3
        beta_t = 2
        self.param_t = [a2, a1_t, a0_t, alpha_t, beta_t]

        # actuation_type by b which is close to b_desired on a k times subdivided spatial domain
        b_desired = self.l / 2
        k = 51  # = k1 + k2
        k1, k2, self.b = ut.split_domain(k, b_desired, self.l, mode='coprime')[0:3]
        M = np.linalg.inv(ut.get_inn_domain_transformation_matrix(k1, k2, mode="2n"))

        # original intermediate ("_i") and traget intermediate ("_ti") system parameters
        _, _, a0_i, self.alpha_i, self.beta_i = ef.transform2intermediate(self.param)
        self.param_i = a2, 0, a0_i, self.alpha_i, self.beta_i
        _, _, a0_ti, self.alpha_ti, self.beta_ti = ef.transform2intermediate(self.param_t)
        self.param_ti = a2, 0, a0_ti, self.alpha_ti, self.beta_ti

        # create (not normalized) eigenfunctions
        eig_freq, self.eig_val = ef.compute_rad_robin_eigenfrequencies(self.param, self.l, self.n)
        init_eig_funcs = np.array([ef.SecondOrderRobinEigenfunction(om, self.param, self.dz.bounds) for om in eig_freq])
        init_adjoint_eig_funcs = np.array(
            [ef.SecondOrderRobinEigenfunction(om, adjoint_param, self.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(self.n)]
        eig_funcs = np.array([f_tuple[0] for f_tuple in adjoint_and_eig_funcs])
        self.adjoint_eig_funcs = np.array([f_tuple[1] for f_tuple in adjoint_and_eig_funcs])

        # eigenfunctions of the in-domain intermediate (_id) and the intermediate (_i) system
        eig_freq_i, eig_val_i = ef.compute_rad_robin_eigenfrequencies(self.param_i, self.l, self.n)
        self.assertTrue(all(np.isclose(eig_val_i, self.eig_val)))
        eig_funcs_id = np.array([ef.SecondOrderRobinEigenfunction(eig_freq_i[i],
                                                                  self.param_i,
                                                                  self.dz.bounds,
                                                                  eig_funcs[i](0))
                                 for i in range(self.n)])
        eig_funcs_i = np.array([ef.SecondOrderRobinEigenfunction(eig_freq_i[i],
                                                                 self.param_i,
                                                                 self.dz.bounds,
                                                                 eig_funcs[i](0) * eig_funcs_id[i](self.l) /
                                                                 eig_funcs_id[i](self.b))
                                for i in range(self.n)])

        # eigenfunctions from target system ("_ti")
        eig_freq_ti = np.sqrt((a0_ti - self.eig_val) / a2)
        eig_funcs_ti = np.array([ef.SecondOrderRobinEigenfunction(eig_freq_ti[i],
                                                                  self.param_ti,
                                                                  self.dz.bounds,
                                                                  eig_funcs_i[i](0))
                                 for i in range(self.n)])

        # create testfunctions
        nodes, self.fem_funcs = sf.cure_interval(sf.LagrangeFirstOrder,
                                                                      self.dz.bounds,
                                                                      node_count=self.n)

        # register eigenfunctions
        # register_functions("eig_funcs", eig_funcs, overwrite=True)
        register_base("adjoint_eig_funcs", self.adjoint_eig_funcs, overwrite=True)
        register_base("eig_funcs", eig_funcs, overwrite=True)
        register_base("eig_funcs_i", eig_funcs_i, overwrite=True)
        register_base("eig_funcs_ti", eig_funcs_ti, overwrite=True)
        register_base("fem_funcs", self.fem_funcs, overwrite=True)

        # init trajectory
        self.traj = tr.RadTrajectory(self.l, self.T, self.param_ti, bound_cond_type, actuation_type)

        # original () and target (_t) field variable
        fem_field_variable = ph.FieldVariable("fem_funcs", location=self.l)
        field_variable_i = ph.FieldVariable("eig_funcs_i", weight_label="eig_funcs", location=self.l)
        d_field_variable_i = ph.SpatialDerivedFieldVariable("eig_funcs_i", 1, weight_label="eig_funcs", location=self.l)
        field_variable_ti = ph.FieldVariable("eig_funcs_ti", weight_label="eig_funcs", location=self.l)
        d_field_variable_ti = ph.SpatialDerivedFieldVariable("eig_funcs_ti", 1, weight_label="eig_funcs",
                                                             location=self.l)

        # intermediate (_i) and target intermediate (_ti) field variable (list of scalar terms = sum of scalar terms)
        self.x_fem_i_at_l = [ph.ScalarTerm(fem_field_variable)]
        self.x_i_at_l = [ph.ScalarTerm(field_variable_i)]
        self.xd_i_at_l = [ph.ScalarTerm(d_field_variable_i)]
        self.x_ti_at_l = [ph.ScalarTerm(field_variable_ti)]
        self.xd_ti_at_l = [ph.ScalarTerm(d_field_variable_ti)]

        # shift transformation
        shifted_fem_funcs_i = np.array(
            [ef.FiniteTransformFunction(func, M, self.b, self.l, scale_func=lambda z: np.exp(a1 / 2 / a2 * z))
             for func in self.fem_funcs])
        shifted_eig_funcs_id = np.array([ef.FiniteTransformFunction(func, M, self.b, self.l) for func in eig_funcs_id])
        register_base("sh_fem_funcs_i", shifted_fem_funcs_i, overwrite=True)
        register_base("sh_eig_funcs_id", shifted_eig_funcs_id, overwrite=True)
        sh_fem_field_variable_i = ph.FieldVariable("sh_fem_funcs_i", weight_label="fem_funcs", location=self.l)
        sh_field_variable_id = ph.FieldVariable("sh_eig_funcs_id", weight_label="eig_funcs", location=self.l)
        self.sh_x_fem_i_at_l = [ph.ScalarTerm(sh_fem_field_variable_i),
                                ph.ScalarTerm(field_variable_i),
                                ph.ScalarTerm(sh_field_variable_id, -1)]

        # discontinuous operator (Kx)(t) = int_kernel_zz(l)*x(l,t)
        self.int_kernel_zz = lambda z: self.alpha_ti - self.alpha_i + (a0_i - a0_ti) / 2 / a2 * z

        a2, a1, _, _, _ = self.param
        controller = ut.get_parabolic_robin_backstepping_controller(state=self.sh_x_fem_i_at_l,
                                                                    approx_state=self.x_i_at_l,
                                                                    d_approx_state=self.xd_i_at_l,
                                                                    approx_target_state=self.x_ti_at_l,
                                                                    d_approx_target_state=self.xd_ti_at_l,
                                                                    integral_kernel_zz=self.int_kernel_zz(self.l),
                                                                    original_beta=self.beta_i,
                                                                    target_beta=self.beta_ti,
                                                                    trajectory=self.traj,
                                                                    scale=np.exp(-a1 / 2 / a2 * self.b))

        # determine (A,B) with modal-transfomation
        rad_pde = ut.get_parabolic_robin_weak_form("fem_funcs", "fem_funcs", controller, self.param, self.dz.bounds,
                                                   self.b)
        cf = sim.parse_weak_formulation(rad_pde)
        ss_weak = cf.convert_to_state_space()

        # simulate
        t, q = sim.simulate_state_space(ss_weak, np.zeros((len(self.fem_funcs))), self.dt)

        # weights of the intermediate system
        mat = cr.calculate_base_transformation_matrix(self.fem_funcs, eig_funcs)
        q_i = np.zeros((q.shape[0], len(eig_funcs_i)))
        for i in range(q.shape[0]):
            q_i[i, :] = np.dot(q[i, :], np.transpose(mat))

        eval_i = sim.evaluate_approximation("eig_funcs_i", q_i, t, self.dz)
        x_0t = eval_i.output_data[:, 0]
        yc, tc = tr.gevrey_tanh(self.T, 1)
        x_0t_desired = np.interp(t, tc, yc[0, :])
        self.assertLess(np.average((x_0t - x_0t_desired) ** 2), 1e-2)

        # display results
        if show_plots:
            eval_d = sim.evaluate_approximation("fem_funcs", q, t, self.dz)
            win1 = vis.PgSurfacePlot(eval_i)
            win2 = vis.PgSurfacePlot(eval_d)
            app.exec_()
Ejemplo n.º 37
0
 def setUp(self):
     self.psi = cr.Function(np.sin)
     register_base("funcs", self.psi, overwrite=True)
     self.funcs = ph.TestFunction("funcs")
Ejemplo n.º 38
0
    def test_fem(self):

        # system/simulation parameters
        actuation_type = 'robin'
        bound_cond_type = 'robin'

        self.l = 1.
        spatial_disc = 30
        self.dz = sim.Domain(bounds=(0, self.l), num=spatial_disc)

        self.T = 1.
        temporal_disc = 1e2
        self.dt = sim.Domain(bounds=(0, self.T), num=temporal_disc)
        self.n = 12

        # original system parameters
        a2 = 1.5
        a1 = 2.5
        a0 = 28
        alpha = -2
        beta = -3
        self.param = [a2, a1, a0, alpha, beta]
        adjoint_param = ef.get_adjoint_rad_evp_param(self.param)

        # target system parameters (controller parameters)
        a1_t = -5
        a0_t = -25
        alpha_t = 3
        beta_t = 2
        self.param_t = [a2, a1_t, a0_t, alpha_t, beta_t]

        # actuation_type by b which is close to b_desired on a k times subdivided spatial domain
        b_desired = self.l / 2
        k = 51  # = k1 + k2
        k1, k2, self.b = ut.split_domain(k, b_desired, self.l,
                                         mode='coprime')[0:3]
        M = np.linalg.inv(
            ut.get_inn_domain_transformation_matrix(k1, k2, mode="2n"))

        # original intermediate ("_i") and traget intermediate ("_ti") system parameters
        _, _, a0_i, self.alpha_i, self.beta_i = ef.transform2intermediate(
            self.param)
        self.param_i = a2, 0, a0_i, self.alpha_i, self.beta_i
        _, _, a0_ti, self.alpha_ti, self.beta_ti = ef.transform2intermediate(
            self.param_t)
        self.param_ti = a2, 0, a0_ti, self.alpha_ti, self.beta_ti

        # create (not normalized) eigenfunctions
        eig_freq, self.eig_val = ef.compute_rad_robin_eigenfrequencies(
            self.param, self.l, self.n)
        init_eig_funcs = np.array([
            ef.SecondOrderRobinEigenfunction(om, self.param, self.dz.bounds)
            for om in eig_freq
        ])
        init_adjoint_eig_funcs = np.array([
            ef.SecondOrderRobinEigenfunction(om, adjoint_param, self.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(self.n)
        ]
        eig_funcs = np.array([f_tuple[0] for f_tuple in adjoint_and_eig_funcs])
        self.adjoint_eig_funcs = np.array(
            [f_tuple[1] for f_tuple in adjoint_and_eig_funcs])

        # eigenfunctions of the in-domain intermediate (_id) and the intermediate (_i) system
        eig_freq_i, eig_val_i = ef.compute_rad_robin_eigenfrequencies(
            self.param_i, self.l, self.n)
        self.assertTrue(all(np.isclose(eig_val_i, self.eig_val)))
        eig_funcs_id = np.array([
            ef.SecondOrderRobinEigenfunction(eig_freq_i[i], self.param_i,
                                             self.dz.bounds, eig_funcs[i](0))
            for i in range(self.n)
        ])
        eig_funcs_i = np.array([
            ef.SecondOrderRobinEigenfunction(
                eig_freq_i[i], self.param_i, self.dz.bounds, eig_funcs[i](0) *
                eig_funcs_id[i](self.l) / eig_funcs_id[i](self.b))
            for i in range(self.n)
        ])

        # eigenfunctions from target system ("_ti")
        eig_freq_ti = np.sqrt((a0_ti - self.eig_val) / a2)
        eig_funcs_ti = np.array([
            ef.SecondOrderRobinEigenfunction(eig_freq_ti[i], self.param_ti,
                                             self.dz.bounds, eig_funcs_i[i](0))
            for i in range(self.n)
        ])

        # create testfunctions
        nodes, self.fem_funcs = sf.cure_interval(sf.LagrangeFirstOrder,
                                                 self.dz.bounds,
                                                 node_count=self.n)

        # register eigenfunctions
        # register_functions("eig_funcs", eig_funcs, overwrite=True)
        register_base("adjoint_eig_funcs",
                      self.adjoint_eig_funcs,
                      overwrite=True)
        register_base("eig_funcs", eig_funcs, overwrite=True)
        register_base("eig_funcs_i", eig_funcs_i, overwrite=True)
        register_base("eig_funcs_ti", eig_funcs_ti, overwrite=True)
        register_base("fem_funcs", self.fem_funcs, overwrite=True)

        # init trajectory
        self.traj = tr.RadTrajectory(self.l, self.T, self.param_ti,
                                     bound_cond_type, actuation_type)

        # original () and target (_t) field variable
        fem_field_variable = ph.FieldVariable("fem_funcs", location=self.l)
        field_variable_i = ph.FieldVariable("eig_funcs_i",
                                            weight_label="eig_funcs",
                                            location=self.l)
        d_field_variable_i = ph.SpatialDerivedFieldVariable(
            "eig_funcs_i", 1, weight_label="eig_funcs", location=self.l)
        field_variable_ti = ph.FieldVariable("eig_funcs_ti",
                                             weight_label="eig_funcs",
                                             location=self.l)
        d_field_variable_ti = ph.SpatialDerivedFieldVariable(
            "eig_funcs_ti", 1, weight_label="eig_funcs", location=self.l)

        # intermediate (_i) and target intermediate (_ti) field variable (list of scalar terms = sum of scalar terms)
        self.x_fem_i_at_l = [ph.ScalarTerm(fem_field_variable)]
        self.x_i_at_l = [ph.ScalarTerm(field_variable_i)]
        self.xd_i_at_l = [ph.ScalarTerm(d_field_variable_i)]
        self.x_ti_at_l = [ph.ScalarTerm(field_variable_ti)]
        self.xd_ti_at_l = [ph.ScalarTerm(d_field_variable_ti)]

        # shift transformation
        shifted_fem_funcs_i = np.array([
            ef.FiniteTransformFunction(
                func,
                M,
                self.b,
                self.l,
                scale_func=lambda z: np.exp(a1 / 2 / a2 * z))
            for func in self.fem_funcs
        ])
        shifted_eig_funcs_id = np.array([
            ef.FiniteTransformFunction(func, M, self.b, self.l)
            for func in eig_funcs_id
        ])
        register_base("sh_fem_funcs_i", shifted_fem_funcs_i, overwrite=True)
        register_base("sh_eig_funcs_id", shifted_eig_funcs_id, overwrite=True)
        sh_fem_field_variable_i = ph.FieldVariable("sh_fem_funcs_i",
                                                   weight_label="fem_funcs",
                                                   location=self.l)
        sh_field_variable_id = ph.FieldVariable("sh_eig_funcs_id",
                                                weight_label="eig_funcs",
                                                location=self.l)
        self.sh_x_fem_i_at_l = [
            ph.ScalarTerm(sh_fem_field_variable_i),
            ph.ScalarTerm(field_variable_i),
            ph.ScalarTerm(sh_field_variable_id, -1)
        ]

        # discontinuous operator (Kx)(t) = int_kernel_zz(l)*x(l,t)
        self.int_kernel_zz = lambda z: self.alpha_ti - self.alpha_i + (
            a0_i - a0_ti) / 2 / a2 * z

        a2, a1, _, _, _ = self.param
        controller = ut.get_parabolic_robin_backstepping_controller(
            state=self.sh_x_fem_i_at_l,
            approx_state=self.x_i_at_l,
            d_approx_state=self.xd_i_at_l,
            approx_target_state=self.x_ti_at_l,
            d_approx_target_state=self.xd_ti_at_l,
            integral_kernel_zz=self.int_kernel_zz(self.l),
            original_beta=self.beta_i,
            target_beta=self.beta_ti,
            trajectory=self.traj,
            scale=np.exp(-a1 / 2 / a2 * self.b))

        # determine (A,B) with modal-transfomation
        rad_pde = ut.get_parabolic_robin_weak_form("fem_funcs", "fem_funcs",
                                                   controller, self.param,
                                                   self.dz.bounds, self.b)
        cf = sim.parse_weak_formulation(rad_pde)
        ss_weak = cf.convert_to_state_space()

        # simulate
        t, q = sim.simulate_state_space(ss_weak, np.zeros(
            (len(self.fem_funcs))), self.dt)

        # weights of the intermediate system
        mat = cr.calculate_base_transformation_matrix(self.fem_funcs,
                                                      eig_funcs)
        q_i = np.zeros((q.shape[0], len(eig_funcs_i)))
        for i in range(q.shape[0]):
            q_i[i, :] = np.dot(q[i, :], np.transpose(mat))

        eval_i = sim.evaluate_approximation("eig_funcs_i", q_i, t, self.dz)
        x_0t = eval_i.output_data[:, 0]
        yc, tc = tr.gevrey_tanh(self.T, 1)
        x_0t_desired = np.interp(t, tc, yc[0, :])
        self.assertLess(np.average((x_0t - x_0t_desired)**2), 1e-2)

        # display results
        if show_plots:
            eval_d = sim.evaluate_approximation("fem_funcs", q, t, self.dz)
            win1 = vis.PgSurfacePlot(eval_i)
            win2 = vis.PgSurfacePlot(eval_d)
            app.exec_()
Ejemplo n.º 39
0
    def shape_generator(self, cls, der_order):
        """
        verify the correct connection with visual feedback
        """

        dz = pi.Domain((0, 1), step=.001)
        dt = pi.Domain((0, 0), num=1)

        nodes, funcs = pi.cure_interval(cls, dz.bounds, node_count=11)
        pi.register_base("test", funcs, overwrite=True)

        # approx_func = pi.Function(np.cos, domain=dz.bounds,
        #                           derivative_handles=[lambda z: -np.sin(z), lambda z: -np.cos(z)])
        approx_func = pi.Function(lambda z: np.sin(3 * z),
                                  domain=dz.bounds,
                                  derivative_handles=[
                                      lambda z: 3 * np.cos(3 * z),
                                      lambda z: -9 * np.sin(3 * z)
                                  ])

        weights = approx_func(nodes)

        hull = pi.evaluate_approximation("test",
                                         np.atleast_2d(weights),
                                         temp_domain=dt,
                                         spat_domain=dz,
                                         spat_order=der_order)

        if show_plots:
            # plot shapefunctions
            c_map = pi.visualization.create_colormap(len(funcs))
            pw = pg.plot(title="{}-Test".format(cls.__name__))
            pw.addLegend()
            pw.showGrid(x=True, y=True, alpha=0.5)

            [
                pw.addItem(
                    pg.PlotDataItem(np.array(dz),
                                    weights[idx] * func.derive(der_order)(dz),
                                    pen=pg.mkPen(color=c_map[idx]),
                                    name="{}.{}".format(cls.__name__, idx)))
                for idx, func in enumerate(funcs)
            ]

            # plot hull curve
            pw.addItem(
                pg.PlotDataItem(np.array(hull.input_data[1]),
                                hull.output_data[0, :],
                                pen=pg.mkPen(width=2),
                                name="hull-curve"))
            # plot original function
            pw.addItem(
                pg.PlotDataItem(np.array(dz),
                                approx_func.derive(der_order)(dz),
                                pen=pg.mkPen(color="m",
                                             width=2,
                                             style=pg.QtCore.Qt.DashLine),
                                name="original"))
            pg.QtCore.QCoreApplication.instance().exec_()

        return np.sum(
            np.abs(hull.output_data[0, :] - approx_func.derive(der_order)(dz)))
Ejemplo n.º 40
0
    def test_it(self):
        # system/simulation parameters
        actuation_type = 'robin'
        bound_cond_type = 'robin'

        self.l = 1.
        spatial_disc = 10
        self.dz = sim.Domain(bounds=(0, self.l), num=spatial_disc)

        self.T = 1.
        temporal_disc = 1e2
        self.dt = sim.Domain(bounds=(0, self.T), num=temporal_disc)

        self.n = 10

        # original system parameters
        a2 = 1.5
        a1_z = cr.Function(lambda z: 1, derivative_handles=[lambda z: 0])
        a0_z = lambda z: 3
        alpha = -2
        beta = -3
        self.param = [a2, a1_z, a0_z, alpha, beta]

        # target system parameters (controller parameters)
        a1_t = -5
        a0_t = -25
        alpha_t = 3
        beta_t = 2
        self.param_t = [a2, a1_t, a0_t, alpha_t, beta_t]
        adjoint_param_t = ef.get_adjoint_rad_evp_param(self.param_t)

        # original intermediate ("_i") and traget intermediate ("_ti") system parameters
        _, _, a0_i, alpha_i, beta_i = ef.transform2intermediate(self.param,
                                                                d_end=self.l)
        self.param_i = a2, 0, a0_i, alpha_i, beta_i
        _, _, a0_ti, alpha_ti, beta_ti = ef.transform2intermediate(
            self.param_t)
        self.param_ti = a2, 0, a0_ti, alpha_ti, beta_ti

        # create (not normalized) target (_t) eigenfunctions
        eig_freq_t, self.eig_val_t = ef.compute_rad_robin_eigenfrequencies(
            self.param_t, self.l, self.n)
        init_eig_funcs_t = np.array([
            ef.SecondOrderRobinEigenfunction(om, self.param_t, self.dz.bounds)
            for om in eig_freq_t
        ])
        init_adjoint_eig_funcs_t = np.array([
            ef.SecondOrderRobinEigenfunction(om, adjoint_param_t,
                                             self.dz.bounds)
            for om in eig_freq_t
        ])

        # normalize eigenfunctions and adjoint eigenfunctions
        adjoint_and_eig_funcs_t = [
            cr.normalize_function(init_eig_funcs_t[i],
                                  init_adjoint_eig_funcs_t[i])
            for i in range(self.n)
        ]
        eig_funcs_t = np.array(
            [f_tuple[0] for f_tuple in adjoint_and_eig_funcs_t])
        self.adjoint_eig_funcs_t = np.array(
            [f_tuple[1] for f_tuple in adjoint_and_eig_funcs_t])

        # # transformed original eigenfunctions
        self.eig_funcs = np.array([
            ef.TransformedSecondOrderEigenfunction(
                self.eig_val_t[i],
                [eig_funcs_t[i](0), alpha * eig_funcs_t[i](0), 0, 0],
                [a2, a1_z, a0_z], np.linspace(0, self.l, 1e4))
            for i in range(self.n)
        ])

        # create testfunctions
        nodes, self.fem_funcs = sf.cure_interval(sf.LagrangeFirstOrder,
                                                 self.dz.bounds,
                                                 node_count=self.n)

        # register functions
        register_base("eig_funcs_t", eig_funcs_t, overwrite=True)
        register_base("adjoint_eig_funcs_t",
                      self.adjoint_eig_funcs_t,
                      overwrite=True)
        register_base("eig_funcs", self.eig_funcs, overwrite=True)
        register_base("fem_funcs", self.fem_funcs, overwrite=True)

        # init trajectory
        self.traj = tr.RadTrajectory(self.l, self.T, self.param_ti,
                                     bound_cond_type, actuation_type)

        # original () and target (_t) field variable
        fem_field_variable = ph.FieldVariable("fem_funcs", location=self.l)
        field_variable_t = ph.FieldVariable("eig_funcs_t",
                                            weight_label="eig_funcs",
                                            location=self.l)
        d_field_variable_t = ph.SpatialDerivedFieldVariable(
            "eig_funcs_t", 1, weight_label="eig_funcs", location=self.l)
        field_variable = ph.FieldVariable("eig_funcs", location=self.l)
        d_field_variable = ph.SpatialDerivedFieldVariable("eig_funcs",
                                                          1,
                                                          location=self.l)
        # intermediate (_i) and target intermediate (_ti) transformations by z=l

        #  x_i  = x   * transform_i_at_l
        self.transform_i_at_l = np.exp(
            integrate.quad(lambda z: a1_z(z) / 2 / a2, 0, self.l)[0])

        # x  = x_i   * inv_transform_i_at_l
        self.inv_transform_i_at_l = np.exp(
            -integrate.quad(lambda z: a1_z(z) / 2 / a2, 0, self.l)[0])

        # x_ti = x_t * transform_ti_at_l
        self.transform_ti_at_l = np.exp(a1_t / 2 / a2 * self.l)

        # intermediate (_i) and target intermediate (_ti) field variable (list of scalar terms = sum of scalar terms)
        self.x_fem_i_at_l = [
            ph.ScalarTerm(fem_field_variable, self.transform_i_at_l)
        ]
        self.x_i_at_l = [ph.ScalarTerm(field_variable, self.transform_i_at_l)]
        self.xd_i_at_l = [
            ph.ScalarTerm(d_field_variable, self.transform_i_at_l),
            ph.ScalarTerm(field_variable,
                          self.transform_i_at_l * a1_z(self.l) / 2 / a2)
        ]
        self.x_ti_at_l = [
            ph.ScalarTerm(field_variable_t, self.transform_ti_at_l)
        ]
        self.xd_ti_at_l = [
            ph.ScalarTerm(d_field_variable_t, self.transform_ti_at_l),
            ph.ScalarTerm(field_variable_t,
                          self.transform_ti_at_l * a1_t / 2 / a2)
        ]

        # discontinuous operator (Kx)(t) = int_kernel_zz(l)*x(l,t)
        self.int_kernel_zz = alpha_ti - alpha_i + integrate.quad(
            lambda z: (a0_i(z) - a0_ti) / 2 / a2, 0, self.l)[0]

        controller = ut.get_parabolic_robin_backstepping_controller(
            state=self.x_fem_i_at_l,
            approx_state=self.x_i_at_l,
            d_approx_state=self.xd_i_at_l,
            approx_target_state=self.x_ti_at_l,
            d_approx_target_state=self.xd_ti_at_l,
            integral_kernel_zz=self.int_kernel_zz,
            original_beta=beta_i,
            target_beta=beta_ti,
            trajectory=self.traj,
            scale=self.inv_transform_i_at_l)

        rad_pde = ut.get_parabolic_robin_weak_form("fem_funcs", "fem_funcs",
                                                   controller, self.param,
                                                   self.dz.bounds)
        cf = sim.parse_weak_formulation(rad_pde)
        ss_weak = cf.convert_to_state_space()

        # simulate
        t, q = sim.simulate_state_space(ss_weak, np.zeros(
            (len(self.fem_funcs))), self.dt)
        eval_d = sim.evaluate_approximation("fem_funcs", q, t, self.dz)
        x_0t = eval_d.output_data[:, 0]
        yc, tc = tr.gevrey_tanh(self.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_()
Ejemplo n.º 41
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_()
Ejemplo n.º 42
0
    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)
Ejemplo n.º 43
0
    def _build_system(self):
        # initial and test functions
        nodes = pi.Domain(self.bounds, num=self.approx_cnt)
        full_fem_base = pi.LagrangeFirstOrder.cure_interval(nodes)
        act_fem_base = pi.Base(full_fem_base[-1])
        not_act_fem_base = pi.Base(full_fem_base[1:-1])
        pi.register_base("act_base", act_fem_base)
        pi.register_base("sim_base", not_act_fem_base)
        pi.register_base(self.base_lbl, full_fem_base)

        a2, a1, a0, _, _ = self.params

        # weak form
        x = pi.FieldVariable("sim_base")
        x_dt = x.derive(temp_order=1)
        x_dz = x.derive(spat_order=1)
        phi = pi.TestFunction("sim_base")
        phi_dz = phi.derive(1)
        act_phi = pi.ScalarFunction("act_base")
        act_phi_dz = act_phi.derive(1)
        u = pi.ConstantTrajectory(0)  # dummy input

        weak_form = pi.WeakFormulation(
            [
                # ... of the homogeneous part of the system
                pi.IntegralTerm(pi.Product(x_dt, phi), limits=self.bounds),
                pi.IntegralTerm(
                    pi.Product(x_dz, phi_dz), limits=self.bounds, scale=a2),
                pi.IntegralTerm(
                    pi.Product(x_dz, phi), limits=self.bounds, scale=-a1),
                pi.IntegralTerm(
                    pi.Product(x, phi), limits=self.bounds, scale=-a0),

                # ... of the inhomogeneous part of the system
                pi.IntegralTerm(pi.Product(pi.Product(act_phi, phi),
                                           pi.Input(u, order=1)),
                                limits=self.bounds),
                pi.IntegralTerm(pi.Product(pi.Product(act_phi_dz, phi_dz),
                                           pi.Input(u)),
                                limits=self.bounds,
                                scale=a2),
                pi.IntegralTerm(pi.Product(pi.Product(act_phi_dz, phi),
                                           pi.Input(u)),
                                limits=self.bounds,
                                scale=-a1),
                pi.IntegralTerm(pi.Product(pi.Product(act_phi, phi),
                                           pi.Input(u)),
                                limits=self.bounds,
                                scale=-a0)
            ],
            name="main_system")

        # system matrices \dot x = A x + b0 u + b1 \dot u
        cf = pi.parse_weak_formulation(weak_form)
        ss = pi.create_state_space(cf)

        a_mat = ss.A[1]
        b0 = ss.B[0][1]
        self.b1 = ss.B[1][1]

        # Idea: \bar x = \tilde A x + b1 u
        self.a_tilde = np.diag(np.ones(a_mat.shape[0]), 0)
        self.a_tilde_inv = np.linalg.inv(self.a_tilde)

        # Yields: \dot \bar x = \bar A \bar x + \bar b u
        self.a_bar = (self.a_tilde @ a_mat) @ self.a_tilde_inv
        self.b_bar = self.a_tilde @ (a_mat @ self.b1) + b0
Ejemplo n.º 44
0
    def test_it(self):
        param = [2., -1.5, -3., 2., .5]
        a2, a1, a0, alpha, beta = param

        l = 1.
        spatial_disc = 10
        dz = sim.Domain(bounds=(0, l), num=spatial_disc)

        T = 1.
        temporal_disc = 2e2
        dt = sim.Domain(bounds=(0, T), num=temporal_disc)

        # create test functions
        nodes_1, ini_funcs_1 = pyinduct.shapefunctions.cure_interval(pyinduct.shapefunctions.LagrangeFirstOrder,
                                                                     dz.bounds,
                                                                     node_count=spatial_disc)
        register_base("init_funcs_1", ini_funcs_1, overwrite=True)
        nodes_2, ini_funcs_2 = pyinduct.shapefunctions.cure_interval(pyinduct.shapefunctions.LagrangeSecondOrder,
                                                                     dz.bounds,
                                                                     node_count=spatial_disc)
        register_base("init_funcs_2", ini_funcs_2, overwrite=True)

        def test_dd():
            # trajectory
            bound_cond_type = 'dirichlet'
            actuation_type = 'dirichlet'
            u = tr.RadTrajectory(l, T, param, bound_cond_type, actuation_type)

            # derive state-space system
            rad_pde = ut.get_parabolic_dirichlet_weak_form("init_funcs_2", "init_funcs_2", u, param, dz.bounds)
            cf = sim.parse_weak_formulation(rad_pde)
            ss = cf.convert_to_state_space()

            # simulate system
            t, q = sim.simulate_state_space(ss, cf.input_function, np.zeros(ini_funcs_2.shape), dt)

            return t, q

        def test_rd():
            # trajectory
            bound_cond_type = 'robin'
            actuation_type = 'dirichlet'
            u = tr.RadTrajectory(l, T, param, bound_cond_type, actuation_type)

            # integral terms
            int1 = ph.IntegralTerm(ph.Product(ph.TemporalDerivedFieldVariable("init_funcs_2", order=1),
                                              ph.TestFunction("init_funcs_2", order=0)), dz.bounds)
            int2 = ph.IntegralTerm(ph.Product(ph.SpatialDerivedFieldVariable("init_funcs_2", order=0),
                                              ph.TestFunction("init_funcs_2", order=2)), dz.bounds, -a2)
            int3 = ph.IntegralTerm(ph.Product(ph.SpatialDerivedFieldVariable("init_funcs_2", order=1),
                                              ph.TestFunction("init_funcs_2", order=0)), dz.bounds, -a1)
            int4 = ph.IntegralTerm(ph.Product(ph.SpatialDerivedFieldVariable("init_funcs_2", order=0),
                                              ph.TestFunction("init_funcs_2", order=0)), dz.bounds, -a0)
            # scalar terms from int 2
            s1 = ph.ScalarTerm(ph.Product(ph.SpatialDerivedFieldVariable("init_funcs_2", order=1, location=l),
                                          ph.TestFunction("init_funcs_2", order=0, location=l)), -a2)
            s2 = ph.ScalarTerm(ph.Product(ph.SpatialDerivedFieldVariable("init_funcs_2", order=0, location=0),
                                          ph.TestFunction("init_funcs_2", order=0, location=0)), a2*alpha)
            s3 = ph.ScalarTerm(ph.Product(ph.SpatialDerivedFieldVariable("init_funcs_2", order=0, location=0),
                                          ph.TestFunction("init_funcs_2", order=1, location=0)), -a2)
            s4 = ph.ScalarTerm(ph.Product(ph.Input(u),
                                          ph.TestFunction("init_funcs_2", order=1, location=l)), a2)

            # derive state-space system
            rad_pde = sim.WeakFormulation([int1, int2, int3, int4, s1, s2, s3, s4])
            cf = sim.parse_weak_formulation(rad_pde)
            ss = cf.convert_to_state_space()

            # simulate system
            t, q = sim.simulate_state_space(ss, cf.input_function, np.zeros(ini_funcs_2.shape), dt)

            return t, q

        def test_dr():
            # trajectory
            bound_cond_type = 'dirichlet'
            actuation_type = 'robin'
            u = tr.RadTrajectory(l, T, param, bound_cond_type, actuation_type)
            # integral terms
            int1 = ph.IntegralTerm(ph.Product(ph.TemporalDerivedFieldVariable("init_funcs_1", order=1),
                                              ph.TestFunction("init_funcs_1", order=0)), dz.bounds)
            int2 = ph.IntegralTerm(ph.Product(ph.SpatialDerivedFieldVariable("init_funcs_1", order=1),
                                              ph.TestFunction("init_funcs_1", order=1)), dz.bounds, a2)
            int3 = ph.IntegralTerm(ph.Product(ph.SpatialDerivedFieldVariable("init_funcs_1", order=0),
                                              ph.TestFunction("init_funcs_1", order=1)), dz.bounds, a1)
            int4 = ph.IntegralTerm(ph.Product(ph.SpatialDerivedFieldVariable("init_funcs_1", order=0),
                                              ph.TestFunction("init_funcs_1", order=0)), dz.bounds, -a0)
            # scalar terms from int 2
            s1 = ph.ScalarTerm(ph.Product(ph.SpatialDerivedFieldVariable("init_funcs_1", order=0, location=l),
                                          ph.TestFunction("init_funcs_1", order=0, location=l)), -a1)
            s2 = ph.ScalarTerm(ph.Product(ph.SpatialDerivedFieldVariable("init_funcs_1", order=0, location=l),
                                          ph.TestFunction("init_funcs_1", order=0, location=l)), a2*beta)
            s3 = ph.ScalarTerm(ph.Product(ph.SpatialDerivedFieldVariable("init_funcs_1", order=1, location=0),
                                          ph.TestFunction("init_funcs_1", order=0, location=0)), a2)
            s4 = ph.ScalarTerm(ph.Product(ph.Input(u),
                                          ph.TestFunction("init_funcs_1", order=0, location=l)), -a2)
            # derive state-space system
            rad_pde = sim.WeakFormulation([int1, int2, int3, int4, s1, s2, s3, s4])
            cf = sim.parse_weak_formulation(rad_pde)
            ss = cf.convert_to_state_space()

            # simulate system
            t, q = sim.simulate_state_space(ss, cf.input_function, np.zeros(ini_funcs_1.shape), dt)

            # check if (x'(0,t_end) - 1.) < 0.1
            self.assertLess(np.abs(ini_funcs_1[0].derive(1)(sys.float_info.min) * (q[-1, 0] - q[-1, 1])) - 1, 0.1)
            return t, q

        def test_rr():
            # trajectory
            bound_cond_type = 'robin'
            actuation_type = 'robin'
            u = tr.RadTrajectory(l, T, param, bound_cond_type, actuation_type)
            # derive state-space system
            rad_pde = ut.get_parabolic_robin_weak_form("init_funcs_1", "init_funcs_1", u, param, dz.bounds)
            cf = sim.parse_weak_formulation(rad_pde)
            ss = cf.convert_to_state_space()

            # simulate system
            t, q = sim.simulate_state_space(ss, cf.input_function, np.zeros(ini_funcs_1.shape), dt)

            # check if (x(0,t_end) - 1.) < 0.1
            self.assertLess(np.abs(ini_funcs_1[0].derive(0)(0) * q[-1, 0]) - 1, 0.1)
            return t, q

        t, q = test_dr()
        _, _ = test_rr()
        # TODO: fit LagrangeSecondOrder to test_dd and test_rd
        # t, q = test_dd()
        # t, q = test_rd()

        # display results
        if show_plots:
            eval_d = ut.evaluate_approximation("init_funcs_1", q, t, dz, spat_order=1)
            win1 = vis.PgAnimatedPlot([eval_d], title="Test")
            win2 = vis.PgSurfacePlot(eval_d)
            app.exec_()
Ejemplo n.º 45
0
    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_()
Ejemplo n.º 46
0
    def setUp(self):
        # scalars
        self.scalars = ph.Scalars(np.vstack(range(3)))

        # inputs
        self.u = np.sin
        self.input = ph.Input(self.u)  # control input

        # TestFunctions
        nodes, self.ini_funcs = pyinduct.shapefunctions.cure_interval(pyinduct.shapefunctions.LagrangeFirstOrder,
                                                                      (0, 1), node_count=3)
        register_base("ini_funcs", self.ini_funcs, overwrite=True)
        self.phi = ph.TestFunction("ini_funcs")  # eigenfunction or something else
        self.phi_at0 = ph.TestFunction("ini_funcs", location=0)  # eigenfunction or something else
        self.phi_at1 = ph.TestFunction("ini_funcs", location=1)  # eigenfunction or something else
        self.dphi = ph.TestFunction("ini_funcs", order=1)  # eigenfunction or something else
        self.dphi_at1 = ph.TestFunction("ini_funcs", order=1, location=1)  # eigenfunction or something else

        # FieldVars
        self.field_var = ph.FieldVariable("ini_funcs")
        self.odd_weight_field_var = ph.FieldVariable("ini_funcs", weight_label="special_weights")
        self.field_var_at1 = ph.FieldVariable("ini_funcs", location=1)
        self.field_var_dz = ph.SpatialDerivedFieldVariable("ini_funcs", 1)
        self.field_var_dz_at1 = ph.SpatialDerivedFieldVariable("ini_funcs", 1, location=1)
        self.field_var_ddt = ph.TemporalDerivedFieldVariable("ini_funcs", 2)
        self.field_var_ddt_at0 = ph.TemporalDerivedFieldVariable("ini_funcs", 2, location=0)
        self.field_var_ddt_at1 = ph.TemporalDerivedFieldVariable("ini_funcs", 2, location=1)

        # create all possible kinds of input variables
        self.input_term1 = ph.ScalarTerm(ph.Product(self.phi_at1, self.input))
        self.input_term1_swapped = ph.ScalarTerm(ph.Product(self.input, self.phi_at1))

        self.input_term2 = ph.ScalarTerm(ph.Product(self.dphi_at1, self.input))
        self.func_term = ph.ScalarTerm(self.phi_at1)

        self.field_term_at1 = ph.ScalarTerm(self.field_var_at1)
        self.field_term_dz_at1 = ph.ScalarTerm(self.field_var_dz_at1)
        self.field_term_ddt_at1 = ph.ScalarTerm(self.field_var_ddt_at1)

        self.field_int = ph.IntegralTerm(self.field_var, (0, 1))
        self.field_dz_int = ph.IntegralTerm(self.field_var_dz, (0, 1))
        self.field_ddt_int = ph.IntegralTerm(self.field_var_ddt, (0, 1))

        self.prod_term_fs_at1 = ph.ScalarTerm(
            ph.Product(self.field_var_at1, self.scalars))
        self.prod_int_fs = ph.IntegralTerm(ph.Product(self.field_var, self.scalars), (0, 1))
        self.prod_int_f_f = ph.IntegralTerm(ph.Product(self.field_var, self.phi), (0, 1))
        self.prod_int_f_f_swapped = ph.IntegralTerm(ph.Product(self.phi, self.field_var), (0, 1))
        self.prod_int_f_at1_f = ph.IntegralTerm(
            ph.Product(self.field_var_at1, self.phi), (0, 1))
        self.prod_int_f_f_at1 = ph.IntegralTerm(
            ph.Product(self.field_var, self.phi_at1), (0, 1))
        self.prod_term_f_at1_f_at1 = ph.ScalarTerm(
            ph.Product(self.field_var_at1, self.phi_at1))

        self.prod_int_fddt_f = ph.IntegralTerm(
            ph.Product(self.field_var_ddt, self.phi), (0, 1))
        self.prod_term_fddt_at0_f_at0 = ph.ScalarTerm(
            ph.Product(self.field_var_ddt_at0, self.phi_at0))

        self.prod_term_f_at1_dphi_at1 = ph.ScalarTerm(
            ph.Product(self.field_var_at1, self.dphi_at1))

        self.temp_int = ph.IntegralTerm(ph.Product(self.field_var_ddt, self.phi), (0, 1))
        self.spat_int = ph.IntegralTerm(ph.Product(self.field_var_dz, self.dphi), (0, 1))
        self.spat_int_asymmetric = ph.IntegralTerm(
            ph.Product(self.field_var_dz, self.phi), (0, 1))

        self.alternating_weights_term = ph.IntegralTerm(self.odd_weight_field_var, (0, 1))
Ejemplo n.º 47
0
    def test_it(self):
        param = [2., -1.5, -3., 2., .5]
        a2, a1, a0, alpha, beta = param

        l = 1.
        spatial_disc = 11
        dz = sim.Domain(bounds=(0, l), num=spatial_disc)

        T = 1.
        temporal_disc = 2e2
        dt = sim.Domain(bounds=(0, T), num=temporal_disc)

        # create test functions
        nodes_1, ini_funcs_1 = sf.cure_interval(sf.LagrangeFirstOrder,
                                                dz.bounds,
                                                node_count=spatial_disc)
        register_base("init_funcs_1", ini_funcs_1, overwrite=True)
        nodes_2, ini_funcs_2 = sf.cure_interval(sf.LagrangeSecondOrder,
                                                dz.bounds,
                                                node_count=spatial_disc)
        register_base("init_funcs_2", ini_funcs_2, overwrite=True)

        def test_dd():
            # trajectory
            bound_cond_type = 'dirichlet'
            actuation_type = 'dirichlet'
            u = tr.RadTrajectory(l, T, param, bound_cond_type, actuation_type)

            # derive state-space system
            rad_pde = ut.get_parabolic_dirichlet_weak_form(
                "init_funcs_2", "init_funcs_2", u, param, dz.bounds)
            cf = sim.parse_weak_formulation(rad_pde)
            ss = cf.convert_to_state_space()

            # simulate system
            t, q = sim.simulate_state_space(ss, np.zeros(ini_funcs_2.shape),
                                            dt)

            return t, q

        def test_rd():
            # trajectory
            bound_cond_type = 'robin'
            actuation_type = 'dirichlet'
            u = tr.RadTrajectory(l, T, param, bound_cond_type, actuation_type)

            # integral terms
            int1 = ph.IntegralTerm(
                ph.Product(
                    ph.TemporalDerivedFieldVariable("init_funcs_2", order=1),
                    ph.TestFunction("init_funcs_2", order=0)), dz.bounds)
            int2 = ph.IntegralTerm(
                ph.Product(
                    ph.SpatialDerivedFieldVariable("init_funcs_2", order=0),
                    ph.TestFunction("init_funcs_2", order=2)), dz.bounds, -a2)
            int3 = ph.IntegralTerm(
                ph.Product(
                    ph.SpatialDerivedFieldVariable("init_funcs_2", order=1),
                    ph.TestFunction("init_funcs_2", order=0)), dz.bounds, -a1)
            int4 = ph.IntegralTerm(
                ph.Product(
                    ph.SpatialDerivedFieldVariable("init_funcs_2", order=0),
                    ph.TestFunction("init_funcs_2", order=0)), dz.bounds, -a0)
            # scalar terms from int 2
            s1 = ph.ScalarTerm(
                ph.Product(
                    ph.SpatialDerivedFieldVariable("init_funcs_2",
                                                   order=1,
                                                   location=l),
                    ph.TestFunction("init_funcs_2", order=0, location=l)), -a2)
            s2 = ph.ScalarTerm(
                ph.Product(
                    ph.SpatialDerivedFieldVariable("init_funcs_2",
                                                   order=0,
                                                   location=0),
                    ph.TestFunction("init_funcs_2", order=0, location=0)),
                a2 * alpha)
            s3 = ph.ScalarTerm(
                ph.Product(
                    ph.SpatialDerivedFieldVariable("init_funcs_2",
                                                   order=0,
                                                   location=0),
                    ph.TestFunction("init_funcs_2", order=1, location=0)), -a2)
            s4 = ph.ScalarTerm(
                ph.Product(
                    ph.Input(u),
                    ph.TestFunction("init_funcs_2", order=1, location=l)), a2)

            # derive state-space system
            rad_pde = sim.WeakFormulation(
                [int1, int2, int3, int4, s1, s2, s3, s4])
            cf = sim.parse_weak_formulation(rad_pde)
            ss = cf.convert_to_state_space()

            # simulate system
            t, q = sim.simulate_state_space(ss, np.zeros(ini_funcs_2.shape),
                                            dt)

            return t, q

        def test_dr():
            # trajectory
            bound_cond_type = 'dirichlet'
            actuation_type = 'robin'
            u = tr.RadTrajectory(l, T, param, bound_cond_type, actuation_type)
            # integral terms
            int1 = ph.IntegralTerm(
                ph.Product(
                    ph.TemporalDerivedFieldVariable("init_funcs_1", order=1),
                    ph.TestFunction("init_funcs_1", order=0)), dz.bounds)
            int2 = ph.IntegralTerm(
                ph.Product(
                    ph.SpatialDerivedFieldVariable("init_funcs_1", order=1),
                    ph.TestFunction("init_funcs_1", order=1)), dz.bounds, a2)
            int3 = ph.IntegralTerm(
                ph.Product(
                    ph.SpatialDerivedFieldVariable("init_funcs_1", order=0),
                    ph.TestFunction("init_funcs_1", order=1)), dz.bounds, a1)
            int4 = ph.IntegralTerm(
                ph.Product(
                    ph.SpatialDerivedFieldVariable("init_funcs_1", order=0),
                    ph.TestFunction("init_funcs_1", order=0)), dz.bounds, -a0)
            # scalar terms from int 2
            s1 = ph.ScalarTerm(
                ph.Product(
                    ph.SpatialDerivedFieldVariable("init_funcs_1",
                                                   order=0,
                                                   location=l),
                    ph.TestFunction("init_funcs_1", order=0, location=l)), -a1)
            s2 = ph.ScalarTerm(
                ph.Product(
                    ph.SpatialDerivedFieldVariable("init_funcs_1",
                                                   order=0,
                                                   location=l),
                    ph.TestFunction("init_funcs_1", order=0, location=l)),
                a2 * beta)
            s3 = ph.ScalarTerm(
                ph.Product(
                    ph.SpatialDerivedFieldVariable("init_funcs_1",
                                                   order=1,
                                                   location=0),
                    ph.TestFunction("init_funcs_1", order=0, location=0)), a2)
            s4 = ph.ScalarTerm(
                ph.Product(
                    ph.Input(u),
                    ph.TestFunction("init_funcs_1", order=0, location=l)), -a2)
            # derive state-space system
            rad_pde = sim.WeakFormulation(
                [int1, int2, int3, int4, s1, s2, s3, s4])
            cf = sim.parse_weak_formulation(rad_pde)
            ss = cf.convert_to_state_space()

            # simulate system
            t, q = sim.simulate_state_space(ss, np.zeros(ini_funcs_1.shape),
                                            dt)

            # check if (x'(0,t_end) - 1.) < 0.1
            self.assertLess(
                np.abs(ini_funcs_1[0].derive(1)(sys.float_info.min) *
                       (q[-1, 0] - q[-1, 1])) - 1, 0.1)
            return t, q

        def test_rr():
            # trajectory
            bound_cond_type = 'robin'
            actuation_type = 'robin'
            u = tr.RadTrajectory(l, T, param, bound_cond_type, actuation_type)
            # derive state-space system
            rad_pde = ut.get_parabolic_robin_weak_form("init_funcs_1",
                                                       "init_funcs_1", u,
                                                       param, dz.bounds)
            cf = sim.parse_weak_formulation(rad_pde)
            ss = cf.convert_to_state_space()

            # simulate system
            t, q = sim.simulate_state_space(ss, np.zeros(ini_funcs_1.shape),
                                            dt)

            # check if (x(0,t_end) - 1.) < 0.1
            self.assertLess(
                np.abs(ini_funcs_1[0].derive(0)(0) * q[-1, 0]) - 1, 0.1)
            return t, q

        t, q = test_dr()
        _, _ = test_rr()
        # TODO: fit LagrangeSecondOrder to test_dd and test_rd
        # t, q = test_dd()
        # t, q = test_rd()

        # display results
        if show_plots:
            eval_d = sim.evaluate_approximation("init_funcs_1",
                                                q,
                                                t,
                                                dz,
                                                spat_order=1)
            win1 = vis.PgAnimatedPlot([eval_d], title="Test")
            win2 = vis.PgSurfacePlot(eval_d)
            app.exec_()
Ejemplo n.º 48
0
adjoint_eig_funcs_t = np.array([f_tuple[1] for f_tuple in adjoint_and_eig_funcs_t])

# transformed original eigenfunctions
eig_funcs = np.array([ef.TransformedSecondOrderEigenfunction(eig_val_t[i],
                                                             [eig_funcs_t[i](0), alpha * eig_funcs_t[i](0), 0, 0],
                                                             [a2, a1_z, a0_z],
                                                             np.linspace(0, l, 1e4))
                      for i in range(n)])

# create testfunctions
nodes, fem_funcs = sh.cure_interval(sh.LagrangeFirstOrder,
                                    spatial_domain.bounds,
                                    node_count=len(spatial_domain))

# register functions
register_base("eig_funcs_t", eig_funcs_t, overwrite=True)
register_base("adjoint_eig_funcs_t", adjoint_eig_funcs_t, overwrite=True)
register_base("eig_funcs", eig_funcs, overwrite=True)
register_base("fem_funcs", fem_funcs, overwrite=True)

# init trajectory
traj = tr.RadTrajectory(l, T, param_ti, bound_cond_type, actuation_type)

# original () and target (_t) field variable
fem_field_variable = ph.FieldVariable("fem_funcs", location=l)
field_variable_t = ph.FieldVariable("eig_funcs_t", weight_label="eig_funcs", location=l)
d_field_variable_t = ph.SpatialDerivedFieldVariable("eig_funcs_t", 1, weight_label="eig_funcs", location=l)
field_variable = ph.FieldVariable("eig_funcs", location=l)
d_field_variable = ph.SpatialDerivedFieldVariable("eig_funcs", 1, location=l)

# intermediate (_i) and target intermediate (_ti) transformations by z=l
Ejemplo n.º 49
0
 def setUp(self):
     nodes, ini_funcs = pyinduct.shapefunctions.cure_interval(pyinduct.shapefunctions.LagrangeFirstOrder, (0, 1), node_count=2)
     register_base("test_funcs", ini_funcs, overwrite=True)
Ejemplo n.º 50
0
    [f_tuple[1] for f_tuple in adjoint_and_eig_funcs_t])

# transformed original eigenfunctions
eig_funcs = np.array([
    ef.TransformedSecondOrderEigenfunction(
        eig_val_t[i], [eig_funcs_t[i](0), alpha * eig_funcs_t[i](0), 0, 0],
        [a2, a1_z, a0_z], np.linspace(0, l, 1e4)) for i in range(n)
])

# create testfunctions
nodes, fem_funcs = sh.cure_interval(sh.LagrangeFirstOrder,
                                    spatial_domain.bounds,
                                    node_count=len(spatial_domain))

# register functions
register_base("eig_funcs_t", eig_funcs_t, overwrite=True)
register_base("adjoint_eig_funcs_t", adjoint_eig_funcs_t, overwrite=True)
register_base("eig_funcs", eig_funcs, overwrite=True)
register_base("fem_funcs", fem_funcs, overwrite=True)

# init trajectory
traj = tr.RadTrajectory(l, T, param_ti, bound_cond_type, actuation_type)

# original () and target (_t) field variable
fem_field_variable = ph.FieldVariable("fem_funcs", location=l)
field_variable_t = ph.FieldVariable("eig_funcs_t",
                                    weight_label="eig_funcs",
                                    location=l)
d_field_variable_t = ph.SpatialDerivedFieldVariable("eig_funcs_t",
                                                    1,
                                                    weight_label="eig_funcs",
Ejemplo n.º 51
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_()