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)
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 ])
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()
# 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(
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]
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,