OGS
HTFEM.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
4#pragma once
5
6#include <Eigen/Core>
7#include <vector>
8
10#include "HTProcessData.h"
21
22namespace ProcessLib
23{
24namespace HT
25{
26template <typename ShapeFunction, int GlobalDim>
28{
31
34
39
40public:
41 HTFEM(MeshLib::Element const& element,
42 std::size_t const local_matrix_size,
43 NumLib::GenericIntegrationMethod const& integration_method,
44 bool const is_axially_symmetric,
45 HTProcessData const& process_data,
46 const unsigned dof_per_node)
48 _element(element),
49 _process_data(process_data),
50 _integration_method(integration_method)
51 {
52 // This assertion is valid only if all nodal d.o.f. use the same shape
53 // matrices.
54 assert(local_matrix_size == ShapeFunction::NPOINTS * dof_per_node);
55 (void)local_matrix_size;
56 (void)dof_per_node;
57
58 unsigned const n_integration_points =
59 _integration_method.getNumberOfPoints();
60 _ip_data.reserve(n_integration_points);
61
63 pos.setElementID(_element.getID());
64
65 double const aperture_size = _process_data.aperture_size(0.0, pos)[0];
66
67 auto const shape_matrices =
69 GlobalDim>(element, is_axially_symmetric,
71
72 for (unsigned ip = 0; ip < n_integration_points; ip++)
73 {
74 _ip_data.emplace_back(
75 shape_matrices[ip].dNdx,
76 _integration_method.getWeightedPoint(ip).getWeight() *
77 shape_matrices[ip].integralMeasure *
78 shape_matrices[ip].detJ * aperture_size);
79 }
80 }
81
82 Eigen::Map<const Eigen::RowVectorXd> getShapeMatrix(
83 const unsigned integration_point) const override
84 {
85 auto const& N = _process_data.shape_matrix_cache.NsHigherOrder<
86 typename ShapeFunction::MeshElement>()[integration_point];
87
88 // assumes N is stored contiguously in memory
89 return Eigen::Map<const Eigen::RowVectorXd>(N.data(), N.size());
90 }
91
94 Eigen::Vector3d getFlux(MathLib::Point3d const& pnt_local_coords,
95 double const t,
96 std::vector<double> const& local_x) const override
97 {
98 // Eval shape matrices at given point
99 // Note: Axial symmetry is set to false here, because we only need dNdx
100 // here, which is not affected by axial symmetry.
101 auto const shape_matrices =
103 GlobalDim>(
104 _element, false /*is_axially_symmetric*/,
105 std::array{pnt_local_coords})[0];
106
108 pos.setElementID(this->_element.getID());
109
111
112 // local_x contains the local temperature and pressure values
113 double T_int_pt = 0.0;
114 double p_int_pt = 0.0;
115 NumLib::shapeFunctionInterpolate(local_x, shape_matrices.N, T_int_pt,
116 p_int_pt);
117
118 vars.temperature = T_int_pt;
119 vars.liquid_phase_pressure = p_int_pt;
120
121 auto const& medium =
122 *_process_data.media_map.getMedium(_element.getID());
123 auto const& liquid_phase = medium.phase("AqueousLiquid");
124
125 // TODO (naumov) Temporary value not used by current material models.
126 // Need extension of secondary variables interface.
127 double const dt = std::numeric_limits<double>::quiet_NaN();
128 // fetch permeability, viscosity, density
131 .value(vars, pos, t, dt));
132
133 auto const mu =
135 .template value<double>(vars, pos, t, dt);
136 GlobalDimMatrixType const K_over_mu = K / mu;
137
138 auto const p_nodal_values = Eigen::Map<const NodalVectorType>(
139 &local_x[local_x.size() / 2], ShapeFunction::NPOINTS);
141 -K_over_mu * shape_matrices.dNdx * p_nodal_values;
142
143 if (this->_process_data.has_gravity)
144 {
145 auto const rho_w =
146 liquid_phase
148 .template value<double>(vars, pos, t, dt);
149 auto const b =
150 this->_process_data.projected_specific_body_force_vectors
151 [this->_element.getID()];
152 q += K_over_mu * rho_w * b;
153 }
154
155 Eigen::Vector3d flux;
156 flux.head<GlobalDim>() = q;
157 return flux;
158 }
159
160protected:
163
165 std::vector<IntegrationPointData<GlobalDimNodalMatrixType>> _ip_data;
166
168 MaterialPropertyLib::VariableArray const& vars, const double porosity,
169 const double fluid_density, const double specific_heat_capacity_fluid,
170 ParameterLib::SpatialPosition const& pos, double const t,
171 double const dt)
172 {
173 auto const& medium =
174 *_process_data.media_map.getMedium(this->_element.getID());
175 auto const& solid_phase = medium.phase("Solid");
176
177 auto const specific_heat_capacity_solid =
178 solid_phase
179 .property(
181 .template value<double>(vars, pos, t, dt);
182
183 auto const solid_density =
185 .template value<double>(vars, pos, t, dt);
186
187 return solid_density * specific_heat_capacity_solid * (1 - porosity) +
188 fluid_density * specific_heat_capacity_fluid * porosity;
189 }
190
193 const double fluid_density, const double specific_heat_capacity_fluid,
194 const GlobalDimVectorType& velocity,
195 ParameterLib::SpatialPosition const& pos, double const t,
196 double const dt)
197 {
198 auto const& medium =
199 *_process_data.media_map.getMedium(_element.getID());
200
201 auto thermal_conductivity =
203 medium
204 .property(
206 .value(vars, pos, t, dt));
207
208 auto const thermal_dispersivity_transversal =
209 medium
211 thermal_transversal_dispersivity)
212 .template value<double>();
213
214 auto const thermal_dispersivity_longitudinal =
215 medium
217 thermal_longitudinal_dispersivity)
218 .template value<double>();
219
220 // Thermal conductivity is moved outside and zero matrix is passed
221 // instead due to multiplication with fluid's density times specific
222 // heat capacity.
223 return thermal_conductivity +
224 fluid_density * specific_heat_capacity_fluid *
226 _process_data.stabilizer, _element.getID(),
227 GlobalDimMatrixType::Zero(GlobalDim, GlobalDim),
228 velocity, 0 /* phi */, thermal_dispersivity_transversal,
229 thermal_dispersivity_longitudinal);
230 }
231
232 std::vector<double> const& getIntPtDarcyVelocityLocal(
233 const double t, std::vector<double> const& local_x,
234 std::vector<double>& cache) const
235 {
236 std::vector<double> local_p{
237 local_x.data() + pressure_index,
238 local_x.data() + pressure_index + pressure_size};
239 std::vector<double> local_T{
240 local_x.data() + temperature_index,
241 local_x.data() + temperature_index + temperature_size};
242
243 auto const n_integration_points =
244 _integration_method.getNumberOfPoints();
245
246 cache.clear();
247 auto cache_mat = MathLib::createZeroedMatrix<
248 Eigen::Matrix<double, GlobalDim, Eigen::Dynamic, Eigen::RowMajor>>(
249 cache, GlobalDim, n_integration_points);
250
252 pos.setElementID(_element.getID());
253
255
256 auto const p_nodal_values = Eigen::Map<const NodalVectorType>(
257 &local_p[0], ShapeFunction::NPOINTS);
258
259 auto const& medium =
260 *_process_data.media_map.getMedium(_element.getID());
261 auto const& liquid_phase = medium.phase("AqueousLiquid");
262
263 auto const& Ns =
264 _process_data.shape_matrix_cache
265 .NsHigherOrder<typename ShapeFunction::MeshElement>();
266
267 for (unsigned ip = 0; ip < n_integration_points; ++ip)
268 {
269 auto const& ip_data = _ip_data[ip];
270 auto const& dNdx = ip_data.dNdx;
271 auto const& N = Ns[ip];
272
273 double T_int_pt = 0.0;
274 double p_int_pt = 0.0;
275 NumLib::shapeFunctionInterpolate(local_p, N, p_int_pt);
276 NumLib::shapeFunctionInterpolate(local_T, N, T_int_pt);
277
278 vars.temperature = T_int_pt;
279 vars.liquid_phase_pressure = p_int_pt;
280
281 // TODO (naumov) Temporary value not used by current material
282 // models. Need extension of secondary variables interface.
283 double const dt = std::numeric_limits<double>::quiet_NaN();
286 .value(vars, pos, t, dt));
287
288 auto const mu =
289 liquid_phase
291 .template value<double>(vars, pos, t, dt);
292 GlobalDimMatrixType const K_over_mu = K / mu;
293
294 cache_mat.col(ip).noalias() = -K_over_mu * dNdx * p_nodal_values;
295
296 if (_process_data.has_gravity)
297 {
298 auto const rho_w =
299 liquid_phase
301 .template value<double>(vars, pos, t, dt);
302 auto const b =
303 _process_data.projected_specific_body_force_vectors
304 [_element.getID()];
305 // here it is assumed that the vector b is directed 'downwards'
306 cache_mat.col(ip).noalias() += K_over_mu * rho_w * b;
307 }
308 }
309
310 return cache;
311 }
312
313protected:
314 static const int pressure_index = ShapeFunction::NPOINTS;
315 static const int pressure_size = ShapeFunction::NPOINTS;
316 static const int temperature_index = 0;
317 static const int temperature_size = ShapeFunction::NPOINTS;
318};
319
320} // namespace HT
321} // namespace ProcessLib
EigenFixedShapeMatrixPolicy< ShapeFunction, GlobalDim > ShapeMatrixPolicyType
std::size_t getID() const
Returns the ID of the element.
Definition Element.h:80
void setElementID(std::size_t element_id)
typename ShapeMatricesType::GlobalDimMatrixType GlobalDimMatrixType
Definition HTFEM.h:38
std::vector< double > const & getIntPtDarcyVelocityLocal(const double t, std::vector< double > const &local_x, std::vector< double > &cache) const
Definition HTFEM.h:232
typename ShapeMatricesType::ShapeMatrices ShapeMatrices
Definition HTFEM.h:30
NumLib::GenericIntegrationMethod const & _integration_method
Definition HTFEM.h:164
typename ShapeMatricesType::GlobalDimNodalMatrixType GlobalDimNodalMatrixType
Definition HTFEM.h:36
static const int temperature_index
Definition HTFEM.h:316
typename ShapeMatricesType::NodalVectorType NodalVectorType
Definition HTFEM.h:32
static const int temperature_size
Definition HTFEM.h:317
double getHeatEnergyCoefficient(MaterialPropertyLib::VariableArray const &vars, const double porosity, const double fluid_density, const double specific_heat_capacity_fluid, ParameterLib::SpatialPosition const &pos, double const t, double const dt)
Definition HTFEM.h:167
HTFEM(MeshLib::Element const &element, std::size_t const local_matrix_size, NumLib::GenericIntegrationMethod const &integration_method, bool const is_axially_symmetric, HTProcessData const &process_data, const unsigned dof_per_node)
Definition HTFEM.h:41
static const int pressure_size
Definition HTFEM.h:315
ShapeMatrixPolicyType< ShapeFunction, GlobalDim > ShapeMatricesType
Definition HTFEM.h:29
typename ShapeMatricesType::GlobalDimVectorType GlobalDimVectorType
Definition HTFEM.h:35
GlobalDimMatrixType getThermalConductivityDispersivity(MaterialPropertyLib::VariableArray const &vars, const double fluid_density, const double specific_heat_capacity_fluid, const GlobalDimVectorType &velocity, ParameterLib::SpatialPosition const &pos, double const t, double const dt)
Definition HTFEM.h:191
Eigen::Vector3d getFlux(MathLib::Point3d const &pnt_local_coords, double const t, std::vector< double > const &local_x) const override
Definition HTFEM.h:94
Eigen::Map< const Eigen::RowVectorXd > getShapeMatrix(const unsigned integration_point) const override
Provides the shape matrix at the given integration point.
Definition HTFEM.h:82
MeshLib::Element const & _element
Definition HTFEM.h:161
HTProcessData const & _process_data
Definition HTFEM.h:162
std::vector< IntegrationPointData< GlobalDimNodalMatrixType > > _ip_data
Definition HTFEM.h:165
static const int pressure_index
Definition HTFEM.h:314
typename ShapeMatricesType::NodalRowVectorType NodalRowVectorType
Definition HTFEM.h:33
constexpr Eigen::Matrix< double, GlobalDim, GlobalDim > formEigenTensor(MaterialPropertyLib::PropertyDataType const &values)
Eigen::Map< Matrix > createZeroedMatrix(std::vector< double > &data, Eigen::MatrixXd::Index rows, Eigen::MatrixXd::Index cols)
void shapeFunctionInterpolate(const NodalValues &, const ShapeMatrix &)
std::vector< typename ShapeMatricesType::ShapeMatrices, Eigen::aligned_allocator< typename ShapeMatricesType::ShapeMatrices > > initShapeMatrices(MeshLib::Element const &e, bool const is_axially_symmetric, IntegrationMethod const &integration_method)
std::vector< typename ShapeMatricesType::ShapeMatrices, Eigen::aligned_allocator< typename ShapeMatricesType::ShapeMatrices > > computeShapeMatrices(MeshLib::Element const &e, bool const is_axially_symmetric, PointContainer const &points)
Eigen::MatrixXd computeHydrodynamicDispersion(NumericalStabilization const &stabilizer, std::size_t const element_id, Eigen::MatrixXd const &pore_diffusion_coefficient, Eigen::VectorXd const &velocity, double const porosity, double const solute_dispersivity_transverse, double const solute_dispersivity_longitudinal)
NumLib::ShapeMatrices< NodalRowVectorType, DimNodalMatrixType, DimMatrixType, GlobalDimNodalMatrixType > ShapeMatrices
MatrixType< GlobalDim, ShapeFunction::NPOINTS > GlobalDimNodalMatrixType
MatrixType< GlobalDim, GlobalDim > GlobalDimMatrixType
VectorType< GlobalDim > GlobalDimVectorType
VectorType< ShapeFunction::NPOINTS > NodalVectorType
RowVectorType< ShapeFunction::NPOINTS > NodalRowVectorType