From 04dcb4523c507cac782c51fcbb7c5bca45addac8 Mon Sep 17 00:00:00 2001 From: Wenqing Wang <wenqing.wang@ufz.de> Date: Mon, 20 Feb 2023 17:28:55 +0100 Subject: [PATCH] [HC] Refactored the implementation of the isotropic diffusion stability --- .../ComponentTransportFEM.h | 113 +++++++++++------- 1 file changed, 71 insertions(+), 42 deletions(-) diff --git a/ProcessLib/ComponentTransport/ComponentTransportFEM.h b/ProcessLib/ComponentTransport/ComponentTransportFEM.h index 7eae80a42c6..1e7bd7ad69d 100644 --- a/ProcessLib/ComponentTransport/ComponentTransportFEM.h +++ b/ProcessLib/ComponentTransport/ComponentTransportFEM.h @@ -12,6 +12,7 @@ #include <Eigen/Core> #include <Eigen/Sparse> +#include <functional> #include <numeric> #include <vector> @@ -237,6 +238,10 @@ class LocalAssemblerData : public ComponentTransportLocalAssemblerInterface using GlobalDimNodalMatrixType = typename ShapeMatricesType::GlobalDimNodalMatrixType; using GlobalDimMatrixType = typename ShapeMatricesType::GlobalDimMatrixType; + using LaplaceCoefficientFunction = std::function<GlobalDimMatrixType( + const LocalAssemblerData<ShapeFunction, GlobalDim>&, + GlobalDimMatrixType const&, GlobalDimMatrixType const&, + GlobalDimVectorType const&, double const, double const, double const)>; public: LocalAssemblerData( @@ -286,6 +291,12 @@ public: _ip_data[ip].pushBackState(); } + _laplace_coefficient_function = + _process_data.stabilizer + ? &LocalAssemblerData<ShapeFunction, GlobalDim>:: + getHydrodynamicDispersionWithArtificialDiffusion + : &LocalAssemblerData<ShapeFunction, + GlobalDim>::getHydrodynamicDispersion; } void setChemicalSystemID(std::size_t const /*mesh_item_id*/) override @@ -543,38 +554,6 @@ public: } } - GlobalDimMatrixType getHydrodynamicDispersion( - GlobalDimMatrixType const& I, - GlobalDimMatrixType const& pore_diffusion_coefficient, - GlobalDimVectorType const& velocity, - double const porosity, - double const solute_dispersivity_transverse, - double const solute_dispersivity_longitudinal) - { - double const velocity_magnitude = velocity.norm(); - - if (velocity_magnitude == 0.0) - { - return porosity * pore_diffusion_coefficient; - } - - GlobalDimMatrixType const D_c = GlobalDimMatrixType( - porosity * pore_diffusion_coefficient + - solute_dispersivity_transverse * velocity_magnitude * I + - (solute_dispersivity_longitudinal - - solute_dispersivity_transverse) / - velocity_magnitude * velocity * velocity.transpose()); - - if (!_process_data.stabilizer) - { - return D_c; - } - - return D_c + _process_data.stabilizer->computeArtificialDiffusion( - _element.getID(), velocity_magnitude) * - I; - } - void assembleBlockMatrices( GlobalDimVectorType const& b, int const component_id, double const t, double const dt, @@ -692,10 +671,10 @@ public: t, dt); GlobalDimMatrixType const hydrodynamic_dispersion = - getHydrodynamicDispersion(I, pore_diffusion_coefficient, - velocity, porosity, - solute_dispersivity_transverse, - solute_dispersivity_longitudinal); + _laplace_coefficient_function( + *this, I, pore_diffusion_coefficient, velocity, porosity, + solute_dispersivity_transverse, + solute_dispersivity_longitudinal); const double R_times_phi(retardation_factor * porosity); GlobalDimVectorType const mass_density_flow = velocity * density; @@ -1053,10 +1032,10 @@ public: : GlobalDimVectorType(-K_over_mu * dNdx * local_p); GlobalDimMatrixType const hydrodynamic_dispersion = - getHydrodynamicDispersion(I, pore_diffusion_coefficient, - velocity, porosity, - solute_dispersivity_transverse, - solute_dispersivity_longitudinal); + _laplace_coefficient_function( + *this, I, pore_diffusion_coefficient, velocity, porosity, + solute_dispersivity_transverse, + solute_dispersivity_longitudinal); double const R_times_phi = retardation_factor * porosity; auto const N_t_N = (N.transpose() * N).eval(); @@ -1341,8 +1320,8 @@ public: ? GlobalDimVectorType(-k / mu * (dNdx * p - rho * b)) : GlobalDimVectorType(-k / mu * dNdx * p); - GlobalDimMatrixType const D = - getHydrodynamicDispersion(I, Dp, q, phi, alpha_T, alpha_L); + GlobalDimMatrixType const D = _laplace_coefficient_function( + *this, I, Dp, q, phi, alpha_T, alpha_L); // matrix assembly local_Jac.noalias() += @@ -1820,6 +1799,56 @@ private: Eigen::aligned_allocator< IntegrationPointData<NodalRowVectorType, GlobalDimNodalMatrixType>>> _ip_data; + + LaplaceCoefficientFunction _laplace_coefficient_function; + + GlobalDimMatrixType getHydrodynamicDispersion( + GlobalDimMatrixType const& I, + GlobalDimMatrixType const& pore_diffusion_coefficient, + GlobalDimVectorType const& velocity, + double const porosity, + double const solute_dispersivity_transverse, + double const solute_dispersivity_longitudinal) const + { + double const velocity_magnitude = velocity.norm(); + if (velocity_magnitude == 0.0) + { + return porosity * pore_diffusion_coefficient; + } + + return GlobalDimMatrixType( + porosity * pore_diffusion_coefficient + + solute_dispersivity_transverse * velocity_magnitude * I + + (solute_dispersivity_longitudinal - + solute_dispersivity_transverse) / + velocity_magnitude * velocity * velocity.transpose()); + } + + GlobalDimMatrixType getHydrodynamicDispersionWithArtificialDiffusion( + GlobalDimMatrixType const& I, + GlobalDimMatrixType const& pore_diffusion_coefficient, + GlobalDimVectorType const& velocity, + double const porosity, + double const solute_dispersivity_transverse, + double const solute_dispersivity_longitudinal) const + { + double const velocity_magnitude = velocity.norm(); + if (velocity_magnitude == 0.0) + { + return porosity * pore_diffusion_coefficient; + } + + GlobalDimMatrixType const D_c = GlobalDimMatrixType( + porosity * pore_diffusion_coefficient + + solute_dispersivity_transverse * velocity_magnitude * I + + (solute_dispersivity_longitudinal - + solute_dispersivity_transverse) / + velocity_magnitude * velocity * velocity.transpose()); + + return D_c + _process_data.stabilizer->computeArtificialDiffusion( + _element.getID(), velocity_magnitude) * + I; + } }; } // namespace ComponentTransport -- GitLab