From 6a41f4ea4a131ba9aa429af0d409b02eadbdd275 Mon Sep 17 00:00:00 2001 From: Rene Gassmoeller Date: Fri, 22 Nov 2024 14:18:56 +0100 Subject: [PATCH] Unify assembly patterns --- source/mesh_deformation/diffusion.cc | 21 +++---- source/mesh_deformation/free_surface.cc | 24 +++++--- source/mesh_deformation/interface.cc | 43 +++++++++----- source/postprocess/dynamic_topography.cc | 28 +++++---- source/simulator/assemblers/stokes.cc | 28 +++++---- source/simulator/melt.cc | 57 ++++++++++++------- source/utilities.cc | 43 +++++++------- source/volume_of_fluid/assembler.cc | 8 ++- .../setup_initial_conditions.cc | 18 +++--- 9 files changed, 163 insertions(+), 107 deletions(-) diff --git a/source/mesh_deformation/diffusion.cc b/source/mesh_deformation/diffusion.cc index a39cfb075f9..0993292bb56 100644 --- a/source/mesh_deformation/diffusion.cc +++ b/source/mesh_deformation/diffusion.cc @@ -281,10 +281,10 @@ namespace aspect cell_matrix = 0; // Loop over the quadrature points of the current face - for (unsigned int point=0; point direction = -(this->get_gravity_model().gravity_vector(fs_fe_face_values.quadrature_point(point))); + Tensor<1,dim> direction = -(this->get_gravity_model().gravity_vector(fs_fe_face_values.quadrature_point(q))); // Normalize direction vector if (direction.norm() > 0.0) direction *= 1./direction.norm(); @@ -299,15 +299,16 @@ namespace aspect // Compute the total displacement in the gravity direction, // i.e. the initial topography + any additional mesh displacement. - const double displacement = direction * (displacement_values[point] + initial_topography_values[point]); + const double displacement = direction * (displacement_values[q] + initial_topography_values[q]); // To project onto the tangent space of the surface, // we define the projection P:= I- n x n, // with I the unit tensor and n the unit normal to the surface. // The surface gradient then is P times the usual gradient of the shape functions. const Tensor<2, dim, double> projection = unit_symmetric_tensor() - - outer_product(fs_fe_face_values.normal_vector(point), fs_fe_face_values.normal_vector(point)); + outer_product(fs_fe_face_values.normal_vector(q), fs_fe_face_values.normal_vector(q)); + const double JxW = fs_fe_face_values.JxW(q); // The shape values for the i-loop std::vector phi(dofs_per_cell); @@ -327,12 +328,12 @@ namespace aspect if (mesh_deformation_dof_handler.get_fe().system_to_component_index(i).first == dim-1) { // Precompute shape values and projected shape value gradients - phi[i] = fs_fe_face_values.shape_value (i, point); - projected_grad_phi[i] = projection * fs_fe_face_values.shape_grad(i, point); + phi[i] = fs_fe_face_values.shape_value (i, q); + projected_grad_phi[i] = projection * fs_fe_face_values.shape_grad(i, q); // Assemble the RHS // RHS = M*H_old - cell_vector(i) += phi[i] * displacement * fs_fe_face_values.JxW(point); + cell_vector(i) += phi[i] * displacement * JxW; for (unsigned int j=0; jget_timestep() * diffusivity * projected_grad_phi[i] * - (projection * fs_fe_face_values.shape_grad(j, point)) + (projection * fs_fe_face_values.shape_grad(j, q)) ) - * fs_fe_face_values.JxW(point); + * JxW; } } } diff --git a/source/mesh_deformation/free_surface.cc b/source/mesh_deformation/free_surface.cc index 06e5edfc17c..43b04db1f91 100644 --- a/source/mesh_deformation/free_surface.cc +++ b/source/mesh_deformation/free_surface.cc @@ -156,31 +156,37 @@ namespace aspect cell_vector = 0; cell_matrix = 0; - for (unsigned int point=0; point direction; if ( advection_direction == SurfaceAdvection::normal ) // project onto normal vector - direction = fs_fe_face_values.normal_vector(point); + direction = fs_fe_face_values.normal_vector(q); else if ( advection_direction == SurfaceAdvection::vertical ) // project onto local gravity - direction = this->get_gravity_model().gravity_vector(fs_fe_face_values.quadrature_point(point)); + direction = this->get_gravity_model().gravity_vector(fs_fe_face_values.quadrature_point(q)); else AssertThrow(false, ExcInternalError()); direction *= ( direction.norm() > 0.0 ? 1./direction.norm() : 0.0 ); + const double JxW = fs_fe_face_values.JxW(q); + + small_vector> phi_u(dofs_per_cell); + for (unsigned int i=0; iget_material_model().evaluate(scratch.face_material_model_inputs, scratch.face_material_model_outputs); - for (unsigned int q_point = 0; q_point < n_face_q_points; ++q_point) + for (unsigned int q = 0; q < n_face_q_points; ++q) { for (unsigned int i = 0, i_stokes = 0; i_stokes < stokes_dofs_per_cell; /*increment at end of loop*/) { if (introspection.is_stokes_component(fe.system_to_component_index(i).first)) { - scratch.phi_u[i_stokes] = scratch.face_finite_element_values[introspection.extractors.velocities].value(i, q_point); + scratch.phi_u[i_stokes] = scratch.face_finite_element_values[introspection.extractors.velocities].value(i, q); ++i_stokes; } ++i; } const Tensor<1,dim> - gravity = this->get_gravity_model().gravity_vector(scratch.face_finite_element_values.quadrature_point(q_point)); + gravity = this->get_gravity_model().gravity_vector(scratch.face_finite_element_values.quadrature_point(q)); const double g_norm = gravity.norm(); // construct the relevant vectors - const Tensor<1,dim> n_hat = scratch.face_finite_element_values.normal_vector(q_point); + const Tensor<1,dim> n_hat = scratch.face_finite_element_values.normal_vector(q); const Tensor<1,dim> g_hat = (g_norm == 0.0 ? Tensor<1,dim>() : gravity/g_norm); - const double pressure_perturbation = scratch.face_material_model_outputs.densities[q_point] * + small_vector phi_u_times_g_hat(stokes_dofs_per_cell); + small_vector phi_u_times_n_hat(stokes_dofs_per_cell); + for (unsigned int i=0; iget_timestep() * free_surface_theta * g_norm; + const double JxW = scratch.face_finite_element_values.JxW(q); + // see Kaus et al 2010 for details of the stabilization term for (unsigned int i=0; i< stokes_dofs_per_cell; ++i) for (unsigned int j=0; j< stokes_dofs_per_cell; ++j) { // The fictive stabilization stress is (phi_u[i].g)*(phi_u[j].n) const double stress_value = -pressure_perturbation* - (scratch.phi_u[i]*g_hat) * (scratch.phi_u[j]*n_hat) - *scratch.face_finite_element_values.JxW(q_point); + phi_u_times_g_hat[i] * phi_u_times_n_hat[j] + * JxW; data.local_matrix(i,j) += stress_value; } @@ -867,14 +877,17 @@ namespace aspect cell_vector = 0; cell_matrix = 0; - for (unsigned int point=0; pointget_material_model().is_compressible(); const Tensor<1,dim> gravity = this->get_gravity_model().gravity_vector(in_volume.position[q]); + const double JxW = fe_volume_values.JxW(q); // Set up shape function values for (unsigned int k=0; kintrospection().extractors.velocities].value(i,q) * - fe_face_values[this->introspection().extractors.velocities].value(i,q) * - fe_face_values.JxW(q); + { + const double JxW = fe_face_values.JxW(q); + for (unsigned int i=0; i phi_u = fe_face_values[this->introspection().extractors.velocities].value(i,q); + local_mass_matrix(i) += phi_u * + phi_u * + JxW; + } + } cell->distribute_local_to_global(local_vector, rhs_vector); cell->distribute_local_to_global(local_mass_matrix, mass_matrix); @@ -330,21 +337,22 @@ namespace aspect const Point point = fe_output_values.quadrature_point(q); const Tensor<1,dim> normal = fe_output_values.normal_vector(q); const double gravity_norm = this->get_gravity_model().gravity_vector(point).norm(); + const double JxW = fe_output_values.JxW(q); if (at_upper_surface) { const double delta_rho = out_output.densities[q] - density_above; dynamic_topography += (-stress_output_values[q]*normal - surface_pressure) - / delta_rho / gravity_norm * fe_output_values.JxW(q); + / delta_rho / gravity_norm * JxW; } else { const double delta_rho = out_output.densities[q] - density_below; dynamic_topography += (-stress_output_values[q]*normal - bottom_pressure) - / delta_rho / gravity_norm * fe_output_values.JxW(q); + / delta_rho / gravity_norm * JxW; } - face_area += fe_output_values.JxW(q); + face_area += JxW; } // Get the average dynamic topography for the cell dynamic_topography = dynamic_topography * (backward_advection ? -1. : 1.) / face_area; diff --git a/source/simulator/assemblers/stokes.cc b/source/simulator/assemblers/stokes.cc index 83f5661a68a..de8d3b10ced 100644 --- a/source/simulator/assemblers/stokes.cc +++ b/source/simulator/assemblers/stokes.cc @@ -908,16 +908,19 @@ namespace aspect const unsigned int n_q_points = scratch.finite_element_values.n_quadrature_points; for (unsigned int q=0; qget_melt_handler().limited_darcy_coefficient(melt_outputs->permeabilities[q] / melt_outputs->fluid_viscosities[q], is_melt_cell); + const double JxW = scratch.face_finite_element_values.JxW(q); + const Tensor<1,dim> normal_vector = scratch.face_finite_element_values.normal_vector(q); + for (unsigned int i=0, i_stokes=0; i_stokesget_pressure_scaling() * K_D * (density_f - * (scratch.face_finite_element_values.normal_vector(q) * gravity) + * (normal_vector * gravity) - grad_p_f[q]) - * scratch.face_finite_element_values.JxW(q)); + * JxW); ++i_stokes; } ++i; @@ -842,6 +845,8 @@ namespace aspect density_c_P_melt = 1.0; } + const double JxW = scratch.finite_element_values.JxW(q); + // do the actual assembly. note that we only need to loop over the advection // shape functions because these are the only contributions we compute here for (unsigned int i=0; i @@ -1050,6 +1056,8 @@ namespace aspect scratch.face_finite_element_values.quadrature_point(q), scratch.face_finite_element_values.normal_vector(q)); + const double JxW = scratch.face_finite_element_values.JxW(q); + for (unsigned int i=0, i_stokes=0; i_stokes n_hat = scratch.face_finite_element_values.normal_vector(q_point); const Tensor<1,dim> g_hat = (g_norm == 0.0 ? Tensor<1,dim>() : gravity/g_norm); + small_vector phi_u_times_g_hat(stokes_dofs_per_cell); + small_vector phi_u_times_n_hat(stokes_dofs_per_cell); + for (unsigned int i=0; iget_timestep() * free_surface_theta * g_norm; + const double JxW = scratch.face_finite_element_values.JxW(q_point); // see Kaus et al 2010 for details of the stabilization term for (unsigned int i=0; i< stokes_dofs_per_cell; ++i) @@ -1919,8 +1936,8 @@ namespace aspect { // The fictive stabilization stress is (phi_u[i].g)*(phi_u[j].n) const double stress_value = - pressure_perturbation - * (scratch.phi_u[i] * g_hat) * (scratch.phi_u[j] * n_hat) - * scratch.face_finite_element_values.JxW(q_point); + * phi_u_times_g_hat[i] * phi_u_times_n_hat[j] + * JxW; data.local_matrix(i,j) += stress_value; } diff --git a/source/utilities.cc b/source/utilities.cc index 059705ee6fc..3a586b63b07 100644 --- a/source/utilities.cc +++ b/source/utilities.cc @@ -2891,26 +2891,29 @@ namespace aspect cell_vector = 0; local_mass_matrix = 0; - for (unsigned int point=0; pointface_indices()) diff --git a/source/volume_of_fluid/setup_initial_conditions.cc b/source/volume_of_fluid/setup_initial_conditions.cc index 41209956832..96a2371a119 100644 --- a/source/volume_of_fluid/setup_initial_conditions.cc +++ b/source/volume_of_fluid/setup_initial_conditions.cc @@ -100,12 +100,13 @@ namespace aspect double volume_of_fluid_val = 0.0; double cell_vol = 0.0; - for (unsigned int i = 0; i < fe_init.n_quadrature_points; ++i) + for (unsigned int q = 0; q < fe_init.n_quadrature_points; ++q) { - const double fraction_at_point = this->get_initial_composition_manager().initial_composition(fe_init.quadrature_point(i), + const double fraction_at_point = this->get_initial_composition_manager().initial_composition(fe_init.quadrature_point(q), field.composition_index); - volume_of_fluid_val += fraction_at_point * fe_init.JxW (i); - cell_vol += fe_init.JxW(i); + const double JxW = fe_init.JxW(q); + volume_of_fluid_val += fraction_at_point * JxW; + cell_vol += JxW; } volume_of_fluid_val /= cell_vol; @@ -184,11 +185,11 @@ namespace aspect { // For each quadrature point compute an approximation to the fluid fraction in the surrounding region - for (unsigned int i = 0; i < fe_init.n_quadrature_points; ++i) + for (unsigned int q = 0; q < fe_init.n_quadrature_points; ++q) { double d = 0.0; Tensor<1, dim, double> grad; - Point xU = quadrature.point (i); + Point xU = quadrature.point (q); // Get an approximation to local normal at the closest interface (level set gradient) // and the distance to the closest interface (value of level set function) @@ -208,8 +209,9 @@ namespace aspect } // Use the basic fluid fraction formula to compute an approximation to the fluid fraction const double fraction_at_point = VolumeOfFluid::Utilities::compute_fluid_fraction (grad, d); - volume_of_fluid_val += fraction_at_point * fe_init.JxW (i); - cell_vol += fe_init.JxW (i); + const double JxW = fe_init.JxW(q); + volume_of_fluid_val += fraction_at_point * JxW; + cell_vol += JxW; } volume_of_fluid_val /= cell_vol; }