def test_assembled_stiffness_p2():
    """
    Testing assembling routine in the case of p2 finite element space on one element.
    """
    p = 2.3
    fe_space = fe_sp.FiniteElementSpace(mesh.Mesh([0.0, 1.0]), fe_order=2, quad_order=2)
    stiffness = stiffness_assembler.assemble_stiffness(fe_space, lambda s: p)
    np_test.assert_array_almost_equal(stiffness.data.data, [7.0 * p / 3.0, -8.0 * p / 3.0, p / 3.0, -8.0 * p / 3.0,
                                                            16.0 * p / 3.0, -8.0 * p / 3.0, p / 3.0, -8.0 * p / 3.0,
                                                            7.0 * p / 3.0])
示例#2
0
    def initialize(self, timestep=None, cfl_factor=0.95):
        """
        Initializing discrete propagator.
        :param timestep: intput timestep, if timestep is None, time step is computed using CFL condition.
        :param cfl_factor: factor to be applied on CFL condition.
        """
        ndof_h1 = self.fe_space.get_ndof()
        ndof_l2 = self.fe_space.get_nelem() * self.fe_space.get_nlocaldof()

        # Allocating displacement unknown.
        self.u0 = np.zeros(ndof_h1)
        self.u1 = np.zeros(ndof_h1)
        self.u2 = np.zeros(ndof_h1)
        self.ustar = np.zeros(ndof_h1)

        # Allocating internal variable unknown.
        self.s0 = np.zeros(ndof_l2)
        self.s1 = np.zeros(ndof_l2)
        self.sstar = np.zeros(ndof_l2)

        # Extracting material parameteris.
        rho = self.config.density
        modulus = self.config.modulus
        eta = self.config.eta
        tau = self.config.tau

        # Definition of material parameters used in assembling procedures.
        def tau_s(x):
            return 1.0 / (tau(x) * (eta(x) - modulus(x)))

        def tau_prime_s(x):
            return 1.0 / (eta(x) - modulus(x))

        # Assembling displacement operators.
        mass_rho = mass_assembler.assemble_mass(self.fe_space, rho,
                                                fe_op.AssemblyType.LUMPED)
        stiffness_MR = stiffness_assembler.assemble_stiffness(
            self.fe_space, modulus)

        # Assembling internal variable operators.
        mass_tau_s = mass_assembler.assemble_discontinuous_mass(
            self.fe_space, tau_s, fe_op.AssemblyType.LUMPED)
        mass_tau_prime_s = mass_assembler.assemble_discontinuous_mass(
            self.fe_space, tau_prime_s, fe_op.AssemblyType.LUMPED)

        # Computing gradient operators.
        self.gradient = gradient_assembler.assemble_gradient(self.fe_space)
        self.transposed_gradient = gradient_assembler.assemble_transposed_gradient(
            self.fe_space)

        # Computing CFL or setting timestep
        if timestep is None:
            stiffness_k1 = stiffness_assembler.assemble_stiffness(
                self.fe_space, eta)
            cfl = 2.0 / np.sqrt(fe_op.spectral_radius(mass_rho, stiffness_k1))
            self.timestep = cfl_factor * cfl
        else:
            self.timestep = timestep

        # Computing operator applied on u1
        self.operator1_u = fe_op.linear_combination(2.0, mass_rho,
                                                    -self.timestep**2,
                                                    stiffness_MR)

        # Computing operator applied on u2
        self.operator2_u = fe_op.clone(-1.0, mass_rho)
        self.__add_boundary_contrib_operator2(
            self.config.left_boundary_condition, self.fe_space.get_left_idx())
        self.__add_boundary_contrib_operator2(
            self.config.right_boundary_condition,
            self.fe_space.get_right_idx())

        # Computing inv operator applied on displacement unknown.
        self.inv_operator_u = fe_op.clone(1.0, mass_rho)
        self.__add_boundary_contrib_inv_operator(
            self.config.left_boundary_condition, self.fe_space.get_left_idx())
        self.__add_boundary_contrib_inv_operator(
            self.config.right_boundary_condition,
            self.fe_space.get_right_idx())
        fe_op.inv(self.inv_operator_u)

        # Computing operator applied on s1.
        self.operator1_s = fe_op.linear_combination(1.0, mass_tau_prime_s,
                                                    -self.timestep * 0.5,
                                                    mass_tau_s)

        # Computing inv operator applied on internal variable.
        self.inv_operator_s = fe_op.linear_combination(1.0, mass_tau_prime_s,
                                                       self.timestep * 0.5,
                                                       mass_tau_s)
        fe_op.inv(self.inv_operator_s)

        # Computing rhs operator.
        if self.config.rhs is not None:
            raise NotImplementedError()

        # Applying initial conditions.
        if self.init_cond_type is not InitialConditionType.NONE:
            raise NotImplementedError()
    def initialize(self, timestep=None, cfl_factor=0.95):
        """
        Initializing discrete propagator.
        :param timestep: intput timestep, if timestep is None, time step is computed using CFL condition.
        :param cfl_factor: factor to be applied on CFL condition.
        """
        # Allocating and applying initial conditions.
        ndof = self.fe_space.get_ndof()
        self.u0 = np.zeros(ndof)
        self.u1 = np.zeros(ndof)
        self.u2 = np.zeros(ndof)
        self.ustar = np.zeros(ndof)

        # Assembling mass, stiffness and viscosity operators.
        mass = mass_assembler.assemble_mass(self.fe_space, self.config.density,
                                            fe_op.AssemblyType.LUMPED)
        stiffness = stiffness_assembler.assemble_stiffness(
            self.fe_space, self.config.modulus)
        viscosity = stiffness_assembler.assemble_stiffness(
            self.fe_space, self.config.eta)

        if self.scheme_type is SchemeType.IMPLICIT_ORDERTWO:

            # Computing CFL or setting timestep.
            if timestep is None:
                cfl = 2.0 / np.sqrt(fe_op.spectral_radius(mass, stiffness))
                self.timestep = cfl_factor * cfl
            else:
                self.timestep = timestep

            # Computing operator to apply on u1.
            self.operator1 = fe_op.linear_combination(2.0, mass,
                                                      -self.timestep**2,
                                                      stiffness)

            # Computing operator to apply on u2.
            self.operator2 = fe_op.linear_combination(-1.0, mass,
                                                      self.timestep * 0.5,
                                                      viscosity)
            self.__add_boundary_contrib_operator2(
                self.config.left_boundary_condition,
                self.fe_space.get_left_idx())
            self.__add_boundary_contrib_operator2(
                self.config.right_boundary_condition,
                self.fe_space.get_right_idx())

            # Computing rhs operator.
            if self.config.rhs is not None:
                self.rhs_operator = mass_assembler.assemble_mass(
                    lambda x: 1.0, self.fe_space, fe_op.AssemblyType.LUMPED)

            # Computing inv operator.
            self.inv_operator = fe_op.linear_combination(
                1.0, mass, self.timestep * 0.5, viscosity)
            self.__add_boundary_contrib_inv_operator(
                self.config.left_boundary_condition,
                self.fe_space.get_left_idx())
            self.__add_boundary_contrib_inv_operator(
                self.config.right_boundary_condition,
                self.fe_space.get_right_idx())
            fe_op.inv(self.inv_operator)

        elif self.scheme_type is SchemeType.EXPLICIT_ORDERONE:

            # Computing CFL or setting timestep.
            if timestep is None:
                r_stiff = fe_op.spectral_radius(mass, stiffness)
                r_visc = fe_op.spectral_radius(mass, viscosity)
                cfl = (np.sqrt((4.0 * r_stiff) /
                               (r_visc**2) + 1.0) - 1.0) * (r_visc / r_stiff)
                self.timestep = cfl_factor * cfl
            else:
                self.timestep = timestep

            # Computing operator to apply on u1.
            tmp_operator = fe_op.linear_combination(2.0, mass,
                                                    -self.timestep**2,
                                                    stiffness)
            self.operator1 = fe_op.linear_combination(1.0, tmp_operator,
                                                      -self.timestep,
                                                      viscosity)

            # Computing operator to apply on u2.
            self.operator2 = fe_op.linear_combination(-1.0, mass,
                                                      self.timestep, viscosity)
            self.__add_boundary_contrib_operator2(
                self.config.left_boundary_condition,
                self.fe_space.get_left_idx())
            self.__add_boundary_contrib_operator2(
                self.config.right_boundary_condition,
                self.fe_space.get_right_idx())

            # Computing rhs operator.
            if self.config.rhs is not None:
                self.rhs_operator = mass_assembler.assemble_mass(
                    lambda x: 1.0, self.fe_space, fe_op.AssemblyType.LUMPED)

            # Computing inv operator.
            self.inv_operator = fe_op.clone(1.0, mass)
            self.__add_boundary_contrib_inv_operator(
                self.config.left_boundary_condition,
                self.fe_space.get_left_idx())
            self.__add_boundary_contrib_inv_operator(
                self.config.right_boundary_condition,
                self.fe_space.get_right_idx())
            fe_op.inv(self.inv_operator)

        # Applying initial conditions.
        if self.init_cond_type is not InitialConditionType.NONE:
            raise NotImplementedError()
示例#4
0
    def initialize(self, timestep=None, cfl_factor=0.95):
        """
        Initializing discrete propagator.
        :param timestep: intput timestep, if timestep is None, time step is computed using CFL condition.
        :param cfl_factor: factor to be applied on CFL condition.
        """
        # Allocating and applying initial conditions.
        ndof = self.fe_space.get_ndof()
        self.u0 = np.zeros(ndof)
        self.u1 = np.zeros(ndof)
        self.u2 = np.zeros(ndof)
        self.ustar = np.zeros(ndof)

        # Assembling mass and stiffness operators.
        mass = mass_assembler.assemble_mass(self.fe_space, self.config.alpha,
                                            self.mass_assembly_type)
        stiffness = stiffness_assembler.assemble_stiffness(
            self.fe_space, self.config.beta, self.stiffness_assembly_type)

        # Computing CFL or setting timestep.
        if timestep is None:
            cfl = 2.0 / np.sqrt(fe_op.spectral_radius(mass, stiffness))
            self.timestep = cfl_factor * cfl
        else:
            self.timestep = timestep

        # Computing operator to apply on u1.
        self.operator1 = fe_op.linear_combination(2.0, mass, -self.timestep**2,
                                                  stiffness)

        # Computing operator to apply on u2.
        self.operator2 = fe_op.clone(-1.0, mass)
        self.__add_boundary_contrib_operator2(
            self.config.left_boundary_condition, self.fe_space.get_left_idx())
        self.__add_boundary_contrib_operator2(
            self.config.right_boundary_condition,
            self.fe_space.get_right_idx())

        # Computing rhs operator.
        if self.config.rhs is not None:
            self.rhs_operator = mass_assembler.assemble_mass(
                lambda x: 1.0, self.fe_space, self.mass_assembly_type)

        # Computing inv operator.
        self.inv_operator = fe_op.clone(1.0, mass)
        self.__add_boundary_contrib_inv_operator(
            self.config.left_boundary_condition, self.fe_space.get_left_idx())
        self.__add_boundary_contrib_inv_operator(
            self.config.right_boundary_condition,
            self.fe_space.get_right_idx())
        fe_op.inv(self.inv_operator)

        # Applying initial conditions.
        if self.init_cond_type is InitialConditionType.ORDERONE:

            for i, x in enumerate(self.fe_space.get_dof_coords()):
                self.u2[i] = self.config.init_field(x)
                self.u1[i] = self.timestep * self.config.init_velocity(
                    x) + self.u2[i]

        elif self.init_cond_type is InitialConditionType.ORDERTWO:

            for i, x in enumerate(self.fe_space.get_dof_coords()):
                self.u2[i] = self.config.init_field(x)

            fe_op.mlt(stiffness, self.u2, self.ustar)
            fe_op.inv(mass)
            fe_op.mlt(mass, self.ustar, self.u1)

            for i, x in enumerate(self.fe_space.get_dof_coords()):
                self.u1[i] = self.timestep * self.config.init_velocity(x) + self.u2[i] \
                             - 0.5 * (self.timestep ** 2) * self.u1[i]
示例#5
0
fig, ax = plt.subplots()
ax.plot(*np.array(observer).T, label='observer values')
ax.legend(loc='upper right')
ax.set_xlabel('time')
ax.set_title('observable (velocity at $x=L$)')
# plt.show()

# Step 2: perform Newton iterative descent
# ========================================

propag_builder = partial(elastic_propagator.Elastic,
                         fe_space=fe_space,
                         mass_assembly_type=fe_op.AssemblyType.LUMPED,
                         stiffness_assembly_type=fe_op.AssemblyType.ASSEMBLED)

k = stiffness_assembler.assemble_stiffness(fe_space)
minv = mass_assembler.assemble_mass(fe_space,
                                    density=alpha,
                                    assembly_type=fe_op.AssemblyType.LUMPED)
fe_op.inv(minv)
minv.data = scipy.sparse.dia_matrix((minv.data, [0]), shape=k.data.shape)
minv_k = fe_op.make_from_data(minv.data * k.data,
                              assembly_type=fe_op.AssemblyType.ASSEMBLED)

current_theta = THETA_INIT
convergence_reached = False
step = 0

while not convergence_reached:
    dthetaJ = JREGUL * current_theta
    d2thetaJ = JREGUL