From 12519e6ab234b5847b02951b118a35a47590f168 Mon Sep 17 00:00:00 2001 From: Wenqing Wang <wenqing.wang@ufz.de> Date: Wed, 18 Oct 2017 17:16:23 +0200 Subject: [PATCH] [HT] Modified the velocity calculation in order that it can be used for both the monolithic and staggered schemes. --- ProcessLib/HT/HTFEM.h | 130 +++++++++++----------- ProcessLib/HT/HTLocalAssemblerInterface.h | 21 ++++ ProcessLib/HT/HTProcess.cpp | 18 ++- ProcessLib/HT/HTProcess.h | 8 +- ProcessLib/HT/MonolithicHTFEM.h | 20 ++++ ProcessLib/HT/StaggeredHTFEM-impl.h | 24 +++- ProcessLib/HT/StaggeredHTFEM.h | 6 + ProcessLib/UncoupledProcessesTimeLoop.cpp | 7 +- 8 files changed, 152 insertions(+), 82 deletions(-) diff --git a/ProcessLib/HT/HTFEM.h b/ProcessLib/HT/HTFEM.h index da24a85a767..1b0eed69354 100644 --- a/ProcessLib/HT/HTFEM.h +++ b/ProcessLib/HT/HTFEM.h @@ -49,7 +49,8 @@ public: unsigned const integration_order, HTMaterialProperties const& material_properties, const unsigned dof_per_node) - : _element(element), + : HTLocalAssemblerInterface(), + _element(element), _material_properties(material_properties), _integration_method(integration_order) { @@ -86,72 +87,6 @@ public: return Eigen::Map<const Eigen::RowVectorXd>(N.data(), N.size()); } - std::vector<double> const& getIntPtDarcyVelocity( - const double t, - GlobalVector const& current_solution, - NumLib::LocalToGlobalIndexMap const& dof_table, - std::vector<double>& cache) const override - { - auto 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()); - - MaterialLib::Fluid::FluidProperty::ArrayType vars; - - auto const p_nodal_values = Eigen::Map<const NodalVectorType>( - &local_x[ShapeFunction::NPOINTS], ShapeFunction::NPOINTS); - - for (unsigned ip = 0; ip < n_integration_points; ++ip) - { - auto const& ip_data = _ip_data[ip]; - auto const& N = ip_data.N; - auto const& dNdx = ip_data.dNdx; - - pos.setIntegrationPoint(ip); - - double T_int_pt = 0.0; - double p_int_pt = 0.0; - NumLib::shapeFunctionInterpolate(local_x, N, T_int_pt, p_int_pt); - vars[static_cast<int>( - MaterialLib::Fluid::PropertyVariableType::T)] = T_int_pt; - vars[static_cast<int>( - MaterialLib::Fluid::PropertyVariableType::p)] = p_int_pt; - - auto const K = - _material_properties.porous_media_properties.getIntrinsicPermeability( - t, pos).getValue(t, pos, 0.0, T_int_pt); - - auto const mu = _material_properties.fluid_properties->getValue( - MaterialLib::Fluid::FluidPropertyType::Viscosity, vars); - GlobalDimMatrixType const K_over_mu = K / mu; - - cache_mat.col(ip).noalias() = -K_over_mu * dNdx * p_nodal_values; - - if (_material_properties.has_gravity) - { - auto const rho_w = - _material_properties.fluid_properties->getValue( - MaterialLib::Fluid::FluidPropertyType::Density, vars); - auto const b = _material_properties.specific_body_force; - // here it is assumed that the vector b is directed 'downwards' - cache_mat.col(ip).noalias() += K_over_mu * rho_w * b; - } - } - - return cache; - } - protected: MeshLib::Element const& _element; HTMaterialProperties const& _material_properties; @@ -212,6 +147,67 @@ protected: return thermal_conductivity * I + thermal_dispersivity; } + + std::vector<double> const& getIntPtDarcyVelocityLocal( + const double t, std::vector<double> const& local_p, + std::vector<double> const& local_T, std::vector<double>& cache) const + { + auto const n_integration_points = + _integration_method.getNumberOfPoints(); + + 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()); + + MaterialLib::Fluid::FluidProperty::ArrayType vars; + + auto const p_nodal_values = Eigen::Map<const NodalVectorType>( + &local_p[0], ShapeFunction::NPOINTS); + + for (unsigned ip = 0; ip < n_integration_points; ++ip) + { + auto const& ip_data = _ip_data[ip]; + auto const& N = ip_data.N; + auto const& dNdx = ip_data.dNdx; + + pos.setIntegrationPoint(ip); + + double T_int_pt = 0.0; + double p_int_pt = 0.0; + NumLib::shapeFunctionInterpolate(local_p, N, p_int_pt); + NumLib::shapeFunctionInterpolate(local_T, N, T_int_pt); + vars[static_cast<int>( + MaterialLib::Fluid::PropertyVariableType::T)] = T_int_pt; + vars[static_cast<int>( + MaterialLib::Fluid::PropertyVariableType::p)] = p_int_pt; + + auto const K = _material_properties.porous_media_properties + .getIntrinsicPermeability(t, pos) + .getValue(t, pos, 0.0, T_int_pt); + + auto const mu = _material_properties.fluid_properties->getValue( + MaterialLib::Fluid::FluidPropertyType::Viscosity, vars); + GlobalDimMatrixType const K_over_mu = K / mu; + + cache_mat.col(ip).noalias() = -K_over_mu * dNdx * p_nodal_values; + + if (_material_properties.has_gravity) + { + auto const rho_w = + _material_properties.fluid_properties->getValue( + MaterialLib::Fluid::FluidPropertyType::Density, vars); + auto const b = _material_properties.specific_body_force; + // here it is assumed that the vector b is directed 'downwards' + cache_mat.col(ip).noalias() += K_over_mu * rho_w * b; + } + } + + return cache; + } }; } // namespace HT diff --git a/ProcessLib/HT/HTLocalAssemblerInterface.h b/ProcessLib/HT/HTLocalAssemblerInterface.h index 82408a4d99f..ecb4d10faf5 100644 --- a/ProcessLib/HT/HTLocalAssemblerInterface.h +++ b/ProcessLib/HT/HTLocalAssemblerInterface.h @@ -17,6 +17,8 @@ namespace ProcessLib { +struct CoupledSolutionsForStaggeredScheme; + namespace HT { template <typename NodalRowVectorType, typename GlobalDimNodalMatrixType> @@ -42,11 +44,30 @@ class HTLocalAssemblerInterface : public ProcessLib::LocalAssemblerInterface, public NumLib::ExtrapolatableElement { public: + HTLocalAssemblerInterface() : _coupled_solutions(nullptr) {} + void setStaggeredCoupledSolutions( + std::size_t const /*mesh_item_id*/, + CoupledSolutionsForStaggeredScheme* const coupling_term) + { + _coupled_solutions = coupling_term; + } + virtual std::vector<double> const& getIntPtDarcyVelocity( const double /*t*/, GlobalVector const& /*current_solution*/, NumLib::LocalToGlobalIndexMap const& /*dof_table*/, std::vector<double>& /*cache*/) const = 0; + +protected: + // TODO: remove _coupled_solutions or move integration point data from local + // assembler class to a new class to make local assembler unique for each + // process. + /** Pointer to CoupledSolutionsForStaggeredScheme that is set in a member of + * Process class, setCoupledTermForTheStaggeredSchemeToLocalAssemblers. + * It is used for calculate the secondary variables like velocity for + * coupled processes. + */ + CoupledSolutionsForStaggeredScheme* _coupled_solutions; }; } // namespace HT diff --git a/ProcessLib/HT/HTProcess.cpp b/ProcessLib/HT/HTProcess.cpp index c17570c121a..f76fa2a9fa6 100644 --- a/ProcessLib/HT/HTProcess.cpp +++ b/ProcessLib/HT/HTProcess.cpp @@ -104,9 +104,9 @@ void HTProcess::assembleWithJacobianConcreteProcess( } void HTProcess::preTimestepConcreteProcess(GlobalVector const& x, - const double /*t*/, - const double /*delta_t*/, - const int process_id) + const double /*t*/, + const double /*delta_t*/, + const int process_id) { assert(process_id < 2); @@ -123,11 +123,19 @@ void HTProcess::preTimestepConcreteProcess(GlobalVector const& x, auto& x0 = *_xs_previous_timestep[process_id]; MathLib::LinAlg::copy(x, x0); } - + auto& x0 = *_xs_previous_timestep[process_id]; MathLib::LinAlg::setLocalAccessibleVector(x0); } +void HTProcess::setCoupledTermForTheStaggeredSchemeToLocalAssemblers() +{ + DBUG("Set the coupled term for the staggered scheme to local assembers."); + + GlobalExecutor::executeMemberOnDereferenced( + &HTLocalAssemblerInterface::setStaggeredCoupledSolutions, + _local_assemblers, _coupled_solutions); +} + } // namespace HT } // namespace ProcessLib - diff --git a/ProcessLib/HT/HTProcess.h b/ProcessLib/HT/HTProcess.h index 61b399d572a..0d5672d187a 100644 --- a/ProcessLib/HT/HTProcess.h +++ b/ProcessLib/HT/HTProcess.h @@ -67,6 +67,8 @@ public: return _xs_previous_timestep[process_id].get(); } + void setCoupledTermForTheStaggeredSchemeToLocalAssemblers() override; + private: void initializeConcreteProcess( NumLib::LocalToGlobalIndexMap const& dof_table, @@ -82,9 +84,9 @@ private: const double dxdot_dx, const double dx_dx, GlobalMatrix& M, GlobalMatrix& K, GlobalVector& b, GlobalMatrix& Jac) override; - void preTimestepConcreteProcess( - GlobalVector const& x, double const t, double const dt, - const int process_id) override; + void preTimestepConcreteProcess(GlobalVector const& x, double const t, + double const dt, + const int process_id) override; const std::unique_ptr<HTMaterialProperties> _material_properties; diff --git a/ProcessLib/HT/MonolithicHTFEM.h b/ProcessLib/HT/MonolithicHTFEM.h index 6aed470778d..775b56f1370 100644 --- a/ProcessLib/HT/MonolithicHTFEM.h +++ b/ProcessLib/HT/MonolithicHTFEM.h @@ -183,6 +183,26 @@ public: * in buoyancy effects */ } } + + std::vector<double> const& getIntPtDarcyVelocity( + const double t, + GlobalVector const& current_solution, + NumLib::LocalToGlobalIndexMap const& dof_table, + std::vector<double>& cache) const override + { + auto const indices = + NumLib::getIndices(this->_element.getID(), dof_table); + assert(!indices.empty()); + auto local_x = current_solution.get(indices); + + std::vector<double> local_T( + std::make_move_iterator(local_x.begin() + local_x.size() / 2), + std::make_move_iterator(local_x.end())); + // only p is kept in local_x + local_x.erase(local_x.begin() + local_x.size() / 2, local_x.end()); + + return this->getIntPtDarcyVelocityLocal(t, local_x, local_T, cache); + } }; } // namespace HT diff --git a/ProcessLib/HT/StaggeredHTFEM-impl.h b/ProcessLib/HT/StaggeredHTFEM-impl.h index 5a2a916180d..7389c7a63bc 100644 --- a/ProcessLib/HT/StaggeredHTFEM-impl.h +++ b/ProcessLib/HT/StaggeredHTFEM-impl.h @@ -30,13 +30,13 @@ void StaggeredHTFEM<ShapeFunction, IntegrationMethod, GlobalDim>:: { if (coupled_term.variable_id == 0) { - assembleHydraulicEquation(t, local_M_data, local_K_data, local_b_data, - coupled_term); + assembleHeatTransportEquation(t, local_M_data, local_K_data, + local_b_data, coupled_term); return; } - assembleHeatTransportEquation(t, local_M_data, local_K_data, local_b_data, - coupled_term); + assembleHydraulicEquation(t, local_M_data, local_K_data, local_b_data, + coupled_term); } template <typename ShapeFunction, typename IntegrationMethod, @@ -267,5 +267,21 @@ void StaggeredHTFEM<ShapeFunction, IntegrationMethod, GlobalDim>:: } } +template <typename ShapeFunction, typename IntegrationMethod, + unsigned GlobalDim> +std::vector<double> const& +StaggeredHTFEM<ShapeFunction, IntegrationMethod, GlobalDim>:: + getIntPtDarcyVelocity(const double t, + GlobalVector const& /*current_solution*/, + NumLib::LocalToGlobalIndexMap const& dof_table, + std::vector<double>& cache) const +{ + auto const indices = NumLib::getIndices(this->_element.getID(), dof_table); + assert(!indices.empty()); + auto const local_xs = + getCurrentLocalSolutions(*(this->_coupled_solutions), indices); + + return this->getIntPtDarcyVelocityLocal(t, local_xs[0], local_xs[1], cache); +} } // namespace HT } // namespace ProcessLib diff --git a/ProcessLib/HT/StaggeredHTFEM.h b/ProcessLib/HT/StaggeredHTFEM.h index ca1217cee25..b2ee534b49b 100644 --- a/ProcessLib/HT/StaggeredHTFEM.h +++ b/ProcessLib/HT/StaggeredHTFEM.h @@ -67,6 +67,12 @@ public: std::vector<double>& local_K_data, std::vector<double>& local_b_data, LocalCoupledSolutions const& coupled_term) override; + std::vector<double> const& getIntPtDarcyVelocity( + const double t, + GlobalVector const& current_solution, + NumLib::LocalToGlobalIndexMap const& dof_table, + std::vector<double>& cache) const override; + private: void assembleHydraulicEquation(double const t, std::vector<double>& local_M_data, diff --git a/ProcessLib/UncoupledProcessesTimeLoop.cpp b/ProcessLib/UncoupledProcessesTimeLoop.cpp index 92f8a612967..00f19e43d7f 100644 --- a/ProcessLib/UncoupledProcessesTimeLoop.cpp +++ b/ProcessLib/UncoupledProcessesTimeLoop.cpp @@ -987,11 +987,12 @@ void UncoupledProcessesTimeLoop::outputSolutions( spd->timestepper->getTimeStep().dt(), pcs_idx); if (is_staggered_coupling) { - CoupledSolutionsForStaggeredScheme coupled_xs( + CoupledSolutionsForStaggeredScheme coupled_solutions( _solutions_of_coupled_processes, 0.0, pcs_idx); - spd->process.setCoupledSolutionsForStaggeredScheme(&coupled_xs); - spd->process.setStaggeredCouplingTermToLocalAssemblers(); + spd->process.setCoupledSolutionsForStaggeredScheme( + &coupled_solutions); + spd->process.setCoupledTermForTheStaggeredSchemeToLocalAssemblers(); (output_object.*output_class_member)(pcs, spd->process_output, timestep, t, x); } -- GitLab