From 19df81f16aab7ff7ae54722efa2b7b26e34b6e08 Mon Sep 17 00:00:00 2001 From: Thomas Fischer <thomas.fischer@ufz.de> Date: Tue, 6 Jun 2017 14:45:46 +0200 Subject: [PATCH] [PL] RichardsComponentTransport: Update secondary var. computation. --- .../RichardsComponentTransportFEM.h | 173 +++++++++--------- .../RichardsComponentTransportProcess.cpp | 36 +--- .../RichardsComponentTransportProcess.h | 4 - 3 files changed, 94 insertions(+), 119 deletions(-) diff --git a/ProcessLib/RichardsComponentTransport/RichardsComponentTransportFEM.h b/ProcessLib/RichardsComponentTransport/RichardsComponentTransportFEM.h index a36c0bd4051..3b54b1b96fa 100644 --- a/ProcessLib/RichardsComponentTransport/RichardsComponentTransportFEM.h +++ b/ProcessLib/RichardsComponentTransport/RichardsComponentTransportFEM.h @@ -16,6 +16,7 @@ #include "RichardsComponentTransportProcessData.h" #include "MaterialLib/Fluid/FluidProperties/FluidProperties.h" #include "MathLib/LinAlg/Eigen/EigenMapTools.h" +#include "NumLib/DOF/DOFTableUtil.h" #include "NumLib/Extrapolation/ExtrapolatableElement.h" #include "NumLib/Fem/FiniteElement/TemplateIsoparametric.h" #include "NumLib/Fem/ShapeMatrixPolicy.h" @@ -64,23 +65,11 @@ public: NumLib::LocalToGlobalIndexMap const& /*dof_table*/, std::vector<double>& /*cache*/) const = 0; - virtual std::vector<double> const& getIntPtDarcyVelocityX( - const double /*t*/, - GlobalVector const& /*current_solution*/, - NumLib::LocalToGlobalIndexMap const& /*dof_table*/, - std::vector<double>& /*cache*/) const = 0; - - virtual std::vector<double> const& getIntPtDarcyVelocityY( - const double /*t*/, - GlobalVector const& /*current_solution*/, - NumLib::LocalToGlobalIndexMap const& /*dof_table*/, - std::vector<double>& /*cache*/) const = 0; - - virtual std::vector<double> const& getIntPtDarcyVelocityZ( - const double /*t*/, - GlobalVector const& /*current_solution*/, - NumLib::LocalToGlobalIndexMap const& /*dof_table*/, - std::vector<double>& /*cache*/) const = 0; + virtual std::vector<double> const& getIntPtDarcyVelocity( + const double t, + GlobalVector const& current_solution, + NumLib::LocalToGlobalIndexMap const& dof_table, + std::vector<double>& cache) const = 0; }; template <typename ShapeFunction, typename IntegrationMethod, @@ -116,12 +105,7 @@ public: RichardsComponentTransportProcessData const& process_data) : _element(element), _process_data(process_data), - _integration_method(integration_order), - _saturation( - std::vector<double>(_integration_method.getNumberOfPoints())), - _darcy_velocities( - GlobalDim, - std::vector<double>(_integration_method.getNumberOfPoints())) + _integration_method(integration_order) { // This assertion is valid only if all nodal d.o.f. use the same shape // matrices. @@ -219,7 +203,6 @@ public: .getCapillaryPressureSaturationModel(t, pos) .getSaturation(pc_int_pt) : 1.0; - _saturation[ip] = Sw; double const dSw_dpc = (pc_int_pt > 0) @@ -228,6 +211,7 @@ public: .getCapillaryPressureSaturationModel(t, pos) .getdPcdS(Sw) : 0.; + // \todo the first argument has to be changed for non constant // porosity model auto const porosity = @@ -262,7 +246,6 @@ public: // Use the viscosity model to compute the viscosity auto const mu = _process_data.fluid_properties->getValue( MaterialLib::Fluid::FluidPropertyType::Viscosity, vars); - auto const K_times_k_rel_over_mu = K * (k_rel/mu); GlobalDimVectorType const velocity = @@ -315,24 +298,29 @@ public: } } - void computeSecondaryVariableConcrete( - double const t, std::vector<double> const& local_x) override + std::vector<double> const& getIntPtDarcyVelocity( + const double t, + GlobalVector const& current_solution, + NumLib::LocalToGlobalIndexMap const& dof_table, + std::vector<double>& cache) const override { + unsigned const n_integration_points = + _integration_method.getNumberOfPoints(); + + auto const indices = NumLib::getIndices(_element.getID(), dof_table); + assert(!indices.empty()); + auto const local_x = current_solution.get(indices); + + cache.clear(); + auto cache_mat = MathLib::createZeroedMatrix< + Eigen::Matrix<double, GlobalDim, Eigen::Dynamic, Eigen::RowMajor>>( + cache, GlobalDim, n_integration_points); + SpatialPosition pos; pos.setElementID(_element.getID()); - auto const& K = - _process_data.porous_media_properties.getIntrinsicPermeability(t, - pos); MaterialLib::Fluid::FluidProperty::ArrayType vars; - auto const mu = _process_data.fluid_properties->getValue( - MaterialLib::Fluid::FluidPropertyType::Viscosity, vars); - GlobalDimMatrixType const K_over_mu = K / mu; - - unsigned const n_integration_points = - _integration_method.getNumberOfPoints(); - auto const p_nodal_values = Eigen::Map<const NodalVectorType>( &local_x[ShapeFunction::NPOINTS], ShapeFunction::NPOINTS); @@ -342,13 +330,34 @@ public: auto const& N = ip_data.N; auto const& dNdx = ip_data.dNdx; - GlobalDimVectorType velocity = -K_over_mu * dNdx * p_nodal_values; + pos.setIntegrationPoint(ip); + + auto const& K = + _process_data.porous_media_properties.getIntrinsicPermeability( + t, pos); + auto const mu = _process_data.fluid_properties->getValue( + MaterialLib::Fluid::FluidPropertyType::Viscosity, vars); + + double C_int_pt = 0.0; + double p_int_pt = 0.0; + NumLib::shapeFunctionInterpolate(local_x, N, C_int_pt, p_int_pt); + + // saturation + double const pc_int_pt = -p_int_pt; + double const Sw = + (pc_int_pt > 0) + ? _process_data.porous_media_properties + .getCapillaryPressureSaturationModel(t, pos) + .getSaturation(pc_int_pt) + : 1.0; + + auto const& k_rel = _process_data.porous_media_properties + .getRelativePermeability(t, pos) + .getValue(Sw); + + cache_mat.col(ip).noalias() = -dNdx * p_nodal_values; if (_process_data.has_gravity) { - double C_int_pt = 0.0; - double p_int_pt = 0.0; - NumLib::shapeFunctionInterpolate(local_x, N, C_int_pt, - p_int_pt); vars[static_cast<int>( MaterialLib::Fluid::PropertyVariableType::C)] = C_int_pt; vars[static_cast<int>( @@ -358,14 +367,11 @@ public: MaterialLib::Fluid::FluidPropertyType::Density, vars); auto const b = _process_data.specific_body_force; // here it is assumed that the vector b is directed 'downwards' - velocity += K_over_mu * rho_w * b; - } - - for (unsigned d = 0; d < GlobalDim; ++d) - { - _darcy_velocities[d][ip] = velocity[d]; + cache_mat.col(ip).noalias() += rho_w * b; } + cache_mat.col(ip).noalias() = k_rel/mu * (K * cache_mat.col(ip)); } + return cache; } Eigen::Map<const Eigen::RowVectorXd> getShapeMatrix( @@ -378,43 +384,46 @@ public: } std::vector<double> const& getIntPtSaturation( - const double /*t*/, - GlobalVector const& /*current_solution*/, - NumLib::LocalToGlobalIndexMap const& /*dof_table*/, - std::vector<double>& /*cache*/) const override + const double t, + GlobalVector const& current_solution, + NumLib::LocalToGlobalIndexMap const& dof_table, + std::vector<double>& cache) const override { - assert(!_saturation.empty()); - return _saturation; - } + SpatialPosition pos; + pos.setElementID(_element.getID()); - std::vector<double> const& getIntPtDarcyVelocityX( - const double /*t*/, - GlobalVector const& /*current_solution*/, - NumLib::LocalToGlobalIndexMap const& /*dof_table*/, - std::vector<double>& /*cache*/) const override - { - assert(_darcy_velocities.size() > 0); - return _darcy_velocities[0]; - } + unsigned const n_integration_points = + _integration_method.getNumberOfPoints(); - std::vector<double> const& getIntPtDarcyVelocityY( - const double /*t*/, - GlobalVector const& /*current_solution*/, - NumLib::LocalToGlobalIndexMap const& /*dof_table*/, - std::vector<double>& /*cache*/) const override - { - assert(_darcy_velocities.size() > 1); - return _darcy_velocities[1]; - } + auto const indices = NumLib::getIndices(_element.getID(), dof_table); + assert(!indices.empty()); + auto const local_x = current_solution.get(indices); - std::vector<double> const& getIntPtDarcyVelocityZ( - const double /*t*/, - GlobalVector const& /*current_solution*/, - NumLib::LocalToGlobalIndexMap const& /*dof_table*/, - std::vector<double>& /*cache*/) const override - { - assert(_darcy_velocities.size() > 2); - return _darcy_velocities[2]; + cache.clear(); + auto cache_vec = MathLib::createZeroedVector<LocalVectorType>( + cache, n_integration_points); + + for (unsigned ip = 0; ip < n_integration_points; ++ip) + { + auto const& ip_data = _ip_data[ip]; + auto const& N = ip_data.N; + + double C_int_pt = 0.0; + double p_int_pt = 0.0; + NumLib::shapeFunctionInterpolate(local_x, N, C_int_pt, p_int_pt); + + // saturation + double const pc_int_pt = -p_int_pt; + double const Sw = + (pc_int_pt > 0) + ? _process_data.porous_media_properties + .getCapillaryPressureSaturationModel(t, pos) + .getSaturation(pc_int_pt) + : 1.0; + cache_vec[ip] = Sw; + } + + return cache; } private: @@ -428,8 +437,6 @@ private: Eigen::aligned_allocator<IntegrationPointData< NodalRowVectorType, GlobalDimNodalMatrixType, NodalMatrixType>>> _ip_data; - std::vector<double> _saturation; - std::vector<std::vector<double>> _darcy_velocities; }; } // namespace RichardsComponentTransport diff --git a/ProcessLib/RichardsComponentTransport/RichardsComponentTransportProcess.cpp b/ProcessLib/RichardsComponentTransport/RichardsComponentTransportProcess.cpp index f15258fac5b..67a93c25251 100644 --- a/ProcessLib/RichardsComponentTransport/RichardsComponentTransportProcess.cpp +++ b/ProcessLib/RichardsComponentTransport/RichardsComponentTransportProcess.cpp @@ -45,29 +45,12 @@ void RichardsComponentTransportProcess::initializeConcreteProcess( mesh.isAxiallySymmetric(), integration_order, _process_data); _secondary_variables.addSecondaryVariable( - "darcy_velocity_x", - makeExtrapolator(1, getExtrapolator(), _local_assemblers, + "darcy_velocity", + makeExtrapolator(mesh.getDimension(), getExtrapolator(), + _local_assemblers, &RichardsComponentTransportLocalAssemblerInterface:: - getIntPtDarcyVelocityX)); + getIntPtDarcyVelocity)); - if (mesh.getDimension() > 1) - { - _secondary_variables.addSecondaryVariable( - "darcy_velocity_y", - makeExtrapolator( - 1, getExtrapolator(), _local_assemblers, - &RichardsComponentTransportLocalAssemblerInterface:: - getIntPtDarcyVelocityY)); - } - if (mesh.getDimension() > 2) - { - _secondary_variables.addSecondaryVariable( - "darcy_velocity_z", - makeExtrapolator( - 1, getExtrapolator(), _local_assemblers, - &RichardsComponentTransportLocalAssemblerInterface:: - getIntPtDarcyVelocityZ)); - } _secondary_variables.addSecondaryVariable( "saturation", makeExtrapolator(1, getExtrapolator(), _local_assemblers, @@ -104,17 +87,6 @@ void RichardsComponentTransportProcess::assembleWithJacobianConcreteProcess( dx_dx, M, K, b, Jac, _coupling_term); } -void RichardsComponentTransportProcess::computeSecondaryVariableConcrete( - double const t, GlobalVector const& x, - StaggeredCouplingTerm const& coupling_term) -{ - DBUG("Compute the Darcy velocity for RichardsComponentTransportProcess."); - GlobalExecutor::executeMemberOnDereferenced( - &RichardsComponentTransportLocalAssemblerInterface:: - computeSecondaryVariable, - _local_assemblers, *_local_to_global_index_map, t, x, coupling_term); -} - } // namespace RichardsComponentTransport } // namespace ProcessLib diff --git a/ProcessLib/RichardsComponentTransport/RichardsComponentTransportProcess.h b/ProcessLib/RichardsComponentTransport/RichardsComponentTransportProcess.h index d1967fea7d7..f56d1c4b148 100644 --- a/ProcessLib/RichardsComponentTransport/RichardsComponentTransportProcess.h +++ b/ProcessLib/RichardsComponentTransport/RichardsComponentTransportProcess.h @@ -58,10 +58,6 @@ public: bool isLinear() const override { return false; } //! @} - void computeSecondaryVariableConcrete( - double const t, GlobalVector const& x, - StaggeredCouplingTerm const& coupling_term) override; - private: void initializeConcreteProcess( NumLib::LocalToGlobalIndexMap const& dof_table, -- GitLab