Ejemplo n.º 1
0
def test_lumped_mass_p2():
    """
    Testing mass lumping routine in the case of p2 finite element spaces.
    """
    def density(x):
        return 2.3 * x + 1.3

    fe_space = fe_sp.FiniteElementSpace(mesh.Mesh([0.0, 1.0, 4.0]),
                                        fe_order=2,
                                        quad_order=2)
    assemb_mass = mass_assembler.assemble_mass(
        fe_space, density, fe_op.AssemblyType.ASSEMBLED).data.todense()
    lumped_mass = np.diag(
        mass_assembler.assemble_mass(fe_space, density,
                                     fe_op.AssemblyType.LUMPED).data)
    np_test.assert_array_almost_equal(assemb_mass, lumped_mass)
Ejemplo n.º 2
0
def test_assembled_mass_p1():
    """
    Testing assembling routine in the case of p1 finite element space on one element.
    """
    cte_density = 2.3
    fe_space = fe_sp.FiniteElementSpace(mesh.Mesh([0.0, 1.0]),
                                        fe_order=1,
                                        quad_order=2)
    mass = mass_assembler.assemble_mass(fe_space, lambda s: cte_density)
    np_test.assert_array_almost_equal(mass.data.data, [
        cte_density / 3.0, cte_density / 6.0, cte_density / 6.0,
        cte_density / 3.0
    ])
Ejemplo n.º 3
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()
Ejemplo n.º 5
0
# Creating finite element space.
fe_space = fe_sp.FiniteElementSpace(mesh=mesh.make_mesh_from_npt(
    0.0, 1.5, 140),
                                    fe_order=5,
                                    quad_order=5)

# Creating propagator.
propag = elastic_propagator.Elastic(
    config=config,
    fe_space=fe_space,
    mass_assembly_type=fe_op.AssemblyType.LUMPED,
    stiffness_assembly_type=fe_op.AssemblyType.ASSEMBLED)

# Computing mass operator.
mass = mass_assembler.assemble_mass(fe_space,
                                    assembly_type=fe_op.AssemblyType.LUMPED)

# Initializing.
propag.initialize()

# Runing.
fig, ax = plt.subplots()
lines = ax.plot(propag.u0)
ax.set_ylim((-1, 1))
for i in range(10000):
    propag.forward()
    if i % 15 == 0:
        lines[0].set_ydata(propag.u0)
        ax.set_title('Absorbing param: {} Energy: {}'.format(
            absorbing_param,
            fe_op.apply_as_linear_form(
Ejemplo n.º 6
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]
Ejemplo n.º 7
0
config_theta_bar = configuration.Elastic(alpha=alpha,
                                         beta=true_beta,
                                         left_bc=left_bc)

fe_space = fe_sp.FiniteElementSpace(mesh=mesh.make_mesh_from_npt(
    0.0, 1.5, 200),
                                    fe_order=5,
                                    quad_order=5)

propag = elastic_propagator.Elastic(
    config=config_theta_bar,
    fe_space=fe_space,
    mass_assembly_type=fe_op.AssemblyType.LUMPED,
    stiffness_assembly_type=fe_op.AssemblyType.ASSEMBLED)

mass = mass_assembler.assemble_mass(fe_space,
                                    assembly_type=fe_op.AssemblyType.LUMPED)

propag.initialize()

# Computing observer values using forward model
observer = []
while propag.time < TMAX:
    propag.forward()
    # u0 is the newly computed value, u1 and u2 previous timesteps
    value = np.square((propag.u0[-1] - propag.u2[-1]) / (2 * propag.timestep))
    observer.append((propag.time, value))
    propag.swap()

interp_observer = interp1d(np.array(observer)[:, 0],
                           np.array(observer)[:, 1],
                           bounds_error=False,