From 0b7058887db88f9a3d7c3ee7cbf53231bdb1cc16 Mon Sep 17 00:00:00 2001 From: Wenqing Wang <wenqing.wang@ufz.de> Date: Tue, 17 Jan 2017 18:13:12 +0100 Subject: [PATCH] [Coupling] Moved the definitions of the members of liquid flow process coupling terms of Heat process to another file. --- .../HeatConduction/HeatConductionFEM-impl.h | 161 ++++++++++++++++++ ProcessLib/HeatConduction/HeatConductionFEM.h | 159 ++++++----------- ProcessLib/LiquidFlow/LiquidFlowProcess.h | 5 + 3 files changed, 221 insertions(+), 104 deletions(-) create mode 100644 ProcessLib/HeatConduction/HeatConductionFEM-impl.h diff --git a/ProcessLib/HeatConduction/HeatConductionFEM-impl.h b/ProcessLib/HeatConduction/HeatConductionFEM-impl.h new file mode 100644 index 00000000000..e25da3e41b8 --- /dev/null +++ b/ProcessLib/HeatConduction/HeatConductionFEM-impl.h @@ -0,0 +1,161 @@ +/** + * \copyright + * Copyright (c) 2012-2017, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/project/license + * + * \file HeatConductionFEM-impl.h + * Created on January 17, 2017, 3:41 PM + */ + +#pragma once + +#include "HeatConductionFEM.h" + +namespace ProcessLib +{ +namespace HeatConduction +{ +template <typename ShapeFunction, typename IntegrationMethod, + unsigned GlobalDim> +template <typename LiquidFlowVelocityCalculator> +void LocalAssemblerData<ShapeFunction, IntegrationMethod, GlobalDim>:: + assembleHeatTransportLiquidFlow( + double const t, int const material_id, SpatialPosition& pos, + int const gravitational_axis_id, + double const gravitational_acceleration, Eigen::MatrixXd const& perm, + ProcessLib::LiquidFlow::LiquidFlowMaterialProperties const& + liquid_flow_prop, + std::vector<double> const& local_x, std::vector<double> const& local_p, + std::vector<double>& local_M_data, std::vector<double>& local_K_data) +{ + auto const local_matrix_size = local_x.size(); + // This assertion is valid only if all nodal d.o.f. use the same shape + // matrices. + assert(local_matrix_size == ShapeFunction::NPOINTS * NUM_NODAL_DOF); + + auto local_M = MathLib::createZeroedMatrix<NodalMatrixType>( + local_M_data, local_matrix_size, local_matrix_size); + auto local_K = MathLib::createZeroedMatrix<NodalMatrixType>( + local_K_data, local_matrix_size, local_matrix_size); + const auto local_p_vec = + MathLib::toVector<NodalVectorType>(local_p, local_matrix_size); + + unsigned const n_integration_points = + _integration_method.getNumberOfPoints(); + + const double porosity_variable = 0.; + for (unsigned ip = 0; ip < n_integration_points; ip++) + { + pos.setIntegrationPoint(ip); + auto const& sm = _shape_matrices[ip]; + auto const& wp = _integration_method.getWeightedPoint(ip); + double p = 0.; + NumLib::shapeFunctionInterpolate(local_p, sm.N, p); + double T = 0.; + NumLib::shapeFunctionInterpolate(local_x, sm.N, T); + + // Material parameters of solid phase + auto const k_s = _process_data.thermal_conductivity(t, pos)[0]; + auto const cp_s = _process_data.heat_capacity(t, pos)[0]; + auto const rho_s = _process_data.density(t, pos)[0]; + + // Material parameters of fluid phase + double const cp_f = liquid_flow_prop.getHeatCapacity(p, T); + double const k_f = liquid_flow_prop.getThermalConductivity(p, T); + double const rho_f = liquid_flow_prop.getLiquidDensity(p, T); + + // Material parameter of porosity + double const poro = + liquid_flow_prop.getPorosity(material_id, porosity_variable, T); + + double const effective_cp = + (1.0 - poro) * cp_s * rho_s + poro * cp_f * rho_f; + double const effective_K = (1.0 - poro) * k_s + poro * k_f; + + double const integration_factor = + sm.detJ * wp.getWeight() * sm.integralMeasure; + + local_M.noalias() += + effective_cp * sm.N.transpose() * sm.N * integration_factor; + local_K.noalias() += + sm.dNdx.transpose() * effective_K * sm.dNdx * integration_factor; + + // Compute fluid flow velocity + double const mu = liquid_flow_prop.getViscosity(p, T); // Viscosity + GlobalDimVectorType const& darcy_velocity = + LiquidFlowVelocityCalculator::calculateVelocity( + local_p_vec, sm, perm, mu, rho_f * gravitational_acceleration, + gravitational_axis_id); + // Add the advection term + local_K.noalias() += cp_f * rho_f * sm.N.transpose() * + (darcy_velocity.transpose() * sm.dNdx) * + integration_factor; + } +} + +template <typename ShapeFunction, typename IntegrationMethod, + unsigned GlobalDim> +void LocalAssemblerData<ShapeFunction, IntegrationMethod, GlobalDim>:: + coupling_assemble(double const t, std::vector<double> const& local_x, + std::vector<double>& local_M_data, + std::vector<double>& local_K_data, + std::vector<double>& /*local_b_data*/, + LocalCouplingTerm const& coupled_term) +{ + auto it = coupled_term.coupled_processes.begin(); + while (it != coupled_term.coupled_processes.end()) + { + switch (it->first) + { + case ProcessLib::ProcessType::LiquidFlowProcess: + { + ProcessLib::LiquidFlow::LiquidFlowProcess const& pcs = + static_cast< + ProcessLib::LiquidFlow::LiquidFlowProcess const&>( + it->second); + const auto liquid_flow_prop = + pcs.getLiquidFlowMaterialProperties(); + + const auto local_p = coupled_term.local_coupled_xs.at( + ProcessLib::ProcessType::LiquidFlowProcess); + + SpatialPosition pos; + pos.setElementID(_element.getID()); + const int material_id = liquid_flow_prop->getMaterialID(pos); + + const Eigen::MatrixXd& perm = liquid_flow_prop->getPermeability( + material_id, t, pos, _element.getDimension()); + + if (perm.size() == 1) + { + assembleHeatTransportLiquidFlow< + IsotropicLiquidFlowVelocityCalculator>( + t, material_id, pos, pcs.getGravitationalAxisID(), + pcs.getGravitationalacceleration(), perm, + *liquid_flow_prop, local_x, local_p, local_M_data, + local_K_data); + } + else + { + assembleHeatTransportLiquidFlow< + AnisotropicLiquidFlowVelocityCalculator>( + t, material_id, pos, pcs.getGravitationalAxisID(), + pcs.getGravitationalacceleration(), perm, + *liquid_flow_prop, local_x, local_p, local_M_data, + local_K_data); + } + } + break; + default: + OGS_FATAL( + "This coupled process is not presented for " + "HeatConduction process"); + } + it++; + } +} + +} // namespace HeatConduction +} // namespace ProcessLib diff --git a/ProcessLib/HeatConduction/HeatConductionFEM.h b/ProcessLib/HeatConduction/HeatConductionFEM.h index 397ab852307..bf8a41ca964 100644 --- a/ProcessLib/HeatConduction/HeatConductionFEM.h +++ b/ProcessLib/HeatConduction/HeatConductionFEM.h @@ -87,7 +87,7 @@ public: void assemble(double const t, std::vector<double> const& local_x, std::vector<double>& local_M_data, std::vector<double>& local_K_data, - std::vector<double>& local_b_data) override + std::vector<double>& /*local_b_data*/) override { auto const local_matrix_size = local_x.size(); // This assertion is valid only if all nodal d.o.f. use the same shape @@ -122,112 +122,11 @@ public: } } - void assembleHeatTransportLiquidFlow( - double const t, int const gravitational_axis_id, - ProcessLib::LiquidFlow::LiquidFlowMaterialProperties const& - liquid_flow_prop, - std::vector<double> const& local_x, std::vector<double> const& local_p, - std::vector<double>& local_M_data, std::vector<double>& local_K_data, - std::vector<double>& local_b_data) - { - auto const local_matrix_size = local_x.size(); - // This assertion is valid only if all nodal d.o.f. use the same shape - // matrices. - assert(local_matrix_size == ShapeFunction::NPOINTS * NUM_NODAL_DOF); - - auto local_M = MathLib::createZeroedMatrix<NodalMatrixType>( - local_M_data, local_matrix_size, local_matrix_size); - auto local_K = MathLib::createZeroedMatrix<NodalMatrixType>( - local_K_data, local_matrix_size, local_matrix_size); - - unsigned const n_integration_points = - _integration_method.getNumberOfPoints(); - - SpatialPosition pos; - pos.setElementID(_element.getID()); - const int material_id = liquid_flow_prop.getMaterialID(pos); - - const Eigen::MatrixXd& perm = liquid_flow_prop.getPermeability( - material_id, t, pos, _element.getDimension()); - - const double porosity_variable = 0.; - for (unsigned ip = 0; ip < n_integration_points; ip++) - { - pos.setIntegrationPoint(ip); - auto const& sm = _shape_matrices[ip]; - auto const& wp = _integration_method.getWeightedPoint(ip); - double p = 0.; - NumLib::shapeFunctionInterpolate(local_p, sm.N, p); - double T = 0.; - NumLib::shapeFunctionInterpolate(local_x, sm.N, T); - - // Material parameters of solid phase - auto const k_s = _process_data.thermal_conductivity(t, pos)[0]; - auto const cp_s = _process_data.heat_capacity(t, pos)[0]; - auto const rho_s = _process_data.density(t, pos)[0]; - - // Material parameters of fluid phase - double const cp_f = liquid_flow_prop.getHeatCapacity(p, T); - double const k_f = liquid_flow_prop.getThermalConductivity(p, T); - double rho_f = liquid_flow_prop.getLiquidDensity(p, T); - - // Material parameter of porosity - double const poro = - liquid_flow_prop.getPorosity(material_id, porosity_variable, T); - - double const effective_cp = - (1.0 - poro) * cp_s * rho_s + poro * cp_f * rho_f; - double const effective_K = (1.0 - poro) * k_s + poro * k_f; - - double const integration_factor = - sm.detJ * wp.getWeight() * sm.integralMeasure; - - local_M.noalias() += - effective_cp * sm.N.transpose() * sm.N * integration_factor; - local_K.noalias() += sm.dNdx.transpose() * effective_K * sm.dNdx * - integration_factor; - } - } - void coupling_assemble(double const t, std::vector<double> const& local_x, std::vector<double>& local_M_data, std::vector<double>& local_K_data, - std::vector<double>& local_b_data, - LocalCouplingTerm const& coupled_term) override - { - auto it = coupled_term.coupled_processes.begin(); - while (it != coupled_term.coupled_processes.end()) - { - switch (it->first) - { - case ProcessLib::ProcessType::LiquidFlowProcess: - { - ProcessLib::LiquidFlow::LiquidFlowProcess const& pcs = - static_cast< - ProcessLib::LiquidFlow::LiquidFlowProcess const&>( - it->second); - const auto liquid_flow_prop = - pcs.getLiquidFlowMaterialProperties(); - - const auto local_p = coupled_term.local_coupled_xs.at( - ProcessLib::ProcessType::LiquidFlowProcess); - - int const gravitational_axis_id = - pcs.getGravitationalAxisID(); - - assembleHeatTransportLiquidFlow( - t, gravitational_axis_id, *liquid_flow_prop, local_x, - local_p, local_M_data, local_K_data, local_b_data); - } - break; - default: - OGS_FATAL( - "This coupled process is not presented for " - "HeatConduction process"); - } - it++; - } - } + std::vector<double>& /*local_b_data*/, + LocalCouplingTerm const& coupled_term) override; void computeSecondaryVariableConcrete( const double t, std::vector<double> const& local_x) override @@ -299,7 +198,59 @@ private: _shape_matrices; std::vector<std::vector<double>> _heat_fluxes; + + template <typename LiquidFlowVelocityCalculator> + void assembleHeatTransportLiquidFlow( double const t, + int const material_id, SpatialPosition& pos, + int const gravitational_axis_id, + double const gravitational_acceleration, Eigen::MatrixXd const& perm, + ProcessLib::LiquidFlow::LiquidFlowMaterialProperties const& + liquid_flow_prop, + std::vector<double> const& local_x, std::vector<double> const& local_p, + std::vector<double>& local_M_data, std::vector<double>& local_K_data); + + /// Calculator of liquid fluid flow velocity for anisotropic permeability + /// tensor + struct IsotropicLiquidFlowVelocityCalculator + { + static GlobalDimVectorType calculateVelocity( + Eigen::Map<const NodalVectorType> const& local_p, + ShapeMatrices const& sm, Eigen::MatrixXd const& perm, + double const mu, double const rho_g, + int const gravitational_axis_id) + { + const double K = perm(0, 0) / mu; + // Compute the velocity + GlobalDimVectorType darcy_velocity = -K * sm.dNdx * local_p; + // gravity term + if (gravitational_axis_id >= 0) + darcy_velocity[gravitational_axis_id] -= K * rho_g; + return darcy_velocity; + } + }; + + /// Calculator of liquid fluid flow velocity for isotropic permeability + /// tensor + struct AnisotropicLiquidFlowVelocityCalculator + { + static GlobalDimVectorType calculateVelocity( + Eigen::Map<const NodalVectorType> const& local_p, + ShapeMatrices const& sm, Eigen::MatrixXd const& perm, + double const mu, double const rho_g, + int const gravitational_axis_id) + { + GlobalDimVectorType darcy_velocity = -perm * sm.dNdx * local_p / mu; + if (gravitational_axis_id >= 0) + { + darcy_velocity.noalias() -= + rho_g * perm.col(gravitational_axis_id) / mu; + } + return darcy_velocity; + } + }; }; } // namespace HeatConduction } // namespace ProcessLib + +#include "HeatConductionFEM-impl.h" diff --git a/ProcessLib/LiquidFlow/LiquidFlowProcess.h b/ProcessLib/LiquidFlow/LiquidFlowProcess.h index 6d90f828fbd..a57f6642377 100644 --- a/ProcessLib/LiquidFlow/LiquidFlowProcess.h +++ b/ProcessLib/LiquidFlow/LiquidFlowProcess.h @@ -82,6 +82,11 @@ public: return _gravitational_axis_id; } + double getGravitationalacceleration() const + { + return _gravitational_acceleration; + } + LiquidFlowMaterialProperties* getLiquidFlowMaterialProperties() const { return _material_properties.get(); -- GitLab