OGS
StaggeredHTFEM-impl.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 <typeinfo>
7
13#include "StaggeredHTFEM.h"
14
15namespace ProcessLib
16{
17namespace HT
18{
19template <typename ShapeFunction, int GlobalDim>
21 double const t, double const dt, Eigen::VectorXd const& local_x,
22 Eigen::VectorXd const& local_x_prev, int const process_id,
23 std::vector<double>& local_M_data, std::vector<double>& local_K_data,
24 std::vector<double>& local_b_data)
25{
26 if (process_id == this->_process_data.heat_transport_process_id)
27 {
28 assembleHeatTransportEquation(t, dt, local_x, local_M_data,
29 local_K_data);
30 return;
31 }
32
33 assembleHydraulicEquation(t, dt, local_x, local_x_prev, local_M_data,
34 local_K_data, local_b_data);
35}
36
37template <typename ShapeFunction, int GlobalDim>
39 double const t, double const dt, Eigen::VectorXd const& local_x,
40 Eigen::VectorXd const& local_x_prev, std::vector<double>& local_M_data,
41 std::vector<double>& local_K_data, std::vector<double>& local_b_data)
42{
43 auto const local_p =
44 local_x.template segment<pressure_size>(pressure_index);
45 auto const local_T =
46 local_x.template segment<temperature_size>(temperature_index);
47
48 auto const local_T_prev =
49 local_x_prev.template segment<temperature_size>(temperature_index);
50
52 local_M_data, pressure_size, pressure_size);
54 local_K_data, pressure_size, pressure_size);
55 auto local_b = MathLib::createZeroedVector<LocalVectorType>(local_b_data,
57
58 auto const& process_data = this->_process_data;
59 auto const& medium =
60 *this->_process_data.media_map.getMedium(this->_element.getID());
61 auto const& liquid_phase =
63 auto const& solid_phase =
65 bool const has_solid_thermal_expansivity = solid_phase.hasProperty(
67
68 auto const& b =
69 process_data
70 .projected_specific_body_force_vectors[this->_element.getID()];
71
73
74 unsigned const n_integration_points =
75 this->_integration_method.getNumberOfPoints();
76
77 auto const& Ns =
78 process_data.shape_matrix_cache
79 .template NsHigherOrder<typename ShapeFunction::MeshElement>();
80
81 for (unsigned ip(0); ip < n_integration_points; ip++)
82 {
83 auto const& ip_data = this->_ip_data[ip];
84 auto const& dNdx = ip_data.dNdx;
85 auto const& N = Ns[ip];
86 auto const& w = ip_data.integration_weight;
87
89 std::nullopt, this->_element.getID(),
92 this->_element, N))};
93
94 double p_int_pt = 0.0;
95 double T_int_pt = 0.0;
96 NumLib::shapeFunctionInterpolate(local_p, N, p_int_pt);
97 NumLib::shapeFunctionInterpolate(local_T, N, T_int_pt);
98
99 vars.temperature = T_int_pt;
100 vars.liquid_phase_pressure = p_int_pt;
101
102 vars.liquid_saturation = 1.0;
103
104 auto const porosity =
106 .template value<double>(vars, pos, t, dt);
107 vars.porosity = porosity;
108
109 auto const fluid_density =
110 liquid_phase.property(MaterialPropertyLib::PropertyType::density)
111 .template value<double>(vars, pos, t, dt);
112
113 vars.density = fluid_density;
114 const double dfluid_density_dp =
115 liquid_phase.property(MaterialPropertyLib::PropertyType::density)
116 .template dValue<double>(
118 pos, t, dt);
119
120 // Use the viscosity model to compute the viscosity
121 auto const viscosity =
123 .template value<double>(vars, pos, t, dt);
124
125 auto const specific_storage =
127 .template value<double>(vars, pos, t, dt);
128
129 auto const intrinsic_permeability =
132 .value(vars, pos, t, dt));
133 GlobalDimMatrixType const K_over_mu =
134 intrinsic_permeability / viscosity;
135
136 double const scaling_factor =
137 process_data.is_volume_balance_equation_type ? 1.0 : fluid_density;
138
139 // matrix assembly
140 local_M.noalias() += (scaling_factor * w *
141 (porosity * dfluid_density_dp / fluid_density +
142 specific_storage)) *
143 N.transpose() * N;
144
145 local_K.noalias() +=
146 (scaling_factor * w) * dNdx.transpose() * K_over_mu * dNdx;
147
148 if (process_data.has_gravity)
149 {
150 local_b.noalias() += (scaling_factor * w * fluid_density) *
151 dNdx.transpose() * K_over_mu * b;
152 }
153
154 // Add the thermal expansion term
155 {
156 double const eff_thermal_expansivity =
158 t, dt, pos, vars, medium, liquid_phase, solid_phase,
159 has_solid_thermal_expansivity, specific_storage);
160
161 double const Tdot_int_pt = (T_int_pt - local_T_prev.dot(N)) / dt;
162 local_b.noalias() +=
163 (scaling_factor * eff_thermal_expansivity * Tdot_int_pt * w) *
164 N;
165 }
166 }
167}
168
169template <typename ShapeFunction, int GlobalDim>
171 double const t,
172 double const dt,
173 Eigen::VectorXd const& local_x,
174 std::vector<double>& local_M_data,
175 std::vector<double>& local_K_data)
176{
177 auto const local_p =
178 local_x.template segment<pressure_size>(pressure_index);
179 auto const local_T =
180 local_x.template segment<temperature_size>(temperature_index);
181
183 local_M_data, temperature_size, temperature_size);
185 local_K_data, temperature_size, temperature_size);
186
187 auto const& process_data = this->_process_data;
188 auto const& medium =
189 *process_data.media_map.getMedium(this->_element.getID());
190 auto const& liquid_phase =
192
193 auto const& b =
194 process_data
195 .projected_specific_body_force_vectors[this->_element.getID()];
196
198
199 unsigned const n_integration_points =
200 this->_integration_method.getNumberOfPoints();
201
202 std::vector<GlobalDimVectorType> ip_flux_vector;
203 double average_velocity_norm = 0.0;
204 ip_flux_vector.reserve(n_integration_points);
205
206 auto const& Ns =
207 process_data.shape_matrix_cache
208 .template NsHigherOrder<typename ShapeFunction::MeshElement>();
209
210 for (unsigned ip(0); ip < n_integration_points; ip++)
211 {
212 auto const& ip_data = this->_ip_data[ip];
213 auto const& dNdx = ip_data.dNdx;
214 auto const& N = Ns[ip];
215 auto const& w = ip_data.integration_weight;
216
218 std::nullopt, this->_element.getID(),
221 this->_element, N))};
222
223 double p_at_xi = 0.;
224 NumLib::shapeFunctionInterpolate(local_p, N, p_at_xi);
225 double T_at_xi = 0.;
226 NumLib::shapeFunctionInterpolate(local_T, N, T_at_xi);
227
228 vars.temperature = T_at_xi;
229 vars.liquid_phase_pressure = p_at_xi;
230
231 vars.liquid_saturation = 1.0;
232
233 auto const porosity =
235 .template value<double>(vars, pos, t, dt);
236 vars.porosity = porosity;
237
238 // Use the fluid density model to compute the density
239 auto const fluid_density =
240 liquid_phase.property(MaterialPropertyLib::PropertyType::density)
241 .template value<double>(vars, pos, t, dt);
242 vars.density = fluid_density;
243 auto const specific_heat_capacity_fluid =
245 .template value<double>(vars, pos, t, dt);
246
247 // Assemble mass matrix
248 local_M.noalias() += w *
250 vars, porosity, fluid_density,
251 specific_heat_capacity_fluid, pos, t, dt) *
252 N.transpose() * N;
253
254 // Assemble Laplace matrix
255 auto const viscosity =
257 .template value<double>(vars, pos, t, dt);
258
259 auto const intrinsic_permeability =
262 .value(vars, pos, t, dt));
263
264 GlobalDimMatrixType const K_over_mu =
265 intrinsic_permeability / viscosity;
266 GlobalDimVectorType const velocity =
267 process_data.has_gravity
268 ? GlobalDimVectorType(-K_over_mu *
269 (dNdx * local_p - fluid_density * b))
270 : GlobalDimVectorType(-K_over_mu * dNdx * local_p);
271
272 GlobalDimMatrixType const thermal_conductivity_dispersivity =
274 vars, fluid_density, specific_heat_capacity_fluid, velocity,
275 pos, t, dt);
276
277 local_K.noalias() +=
278 w * dNdx.transpose() * thermal_conductivity_dispersivity * dNdx;
279
280 ip_flux_vector.emplace_back(velocity * fluid_density *
281 specific_heat_capacity_fluid);
282 average_velocity_norm += velocity.norm();
283 }
284
286 process_data.stabilizer, this->_ip_data,
287 process_data.shape_matrix_cache, ip_flux_vector,
288 average_velocity_norm / static_cast<double>(n_integration_points),
289 local_K);
290}
291
292template <typename ShapeFunction, int GlobalDim>
293std::vector<double> const&
295 const double t,
296 std::vector<GlobalVector*> const& x,
297 std::vector<NumLib::LocalToGlobalIndexMap const*> const& dof_table,
298 std::vector<double>& cache) const
299{
300 assert(x.size() == dof_table.size());
301 auto const n_processes = dof_table.size();
302
303 std::vector<std::vector<GlobalIndexType>> indices_of_all_coupled_processes;
304 indices_of_all_coupled_processes.reserve(n_processes);
305 for (std::size_t process_id = 0; process_id < n_processes; ++process_id)
306 {
307 auto const indices =
308 NumLib::getIndices(this->_element.getID(), *dof_table[process_id]);
309 assert(!indices.empty());
310 indices_of_all_coupled_processes.push_back(indices);
311 }
312 auto const local_xs =
313 getCoupledLocalSolutions(x, indices_of_all_coupled_processes);
314
315 return this->getIntPtDarcyVelocityLocal(t, local_xs, cache);
316}
317} // namespace HT
318} // namespace ProcessLib
std::vector< double > const & getIntPtDarcyVelocityLocal(const double t, std::vector< double > const &local_x, std::vector< double > &cache) const
Definition HTFEM.h:339
NumLib::GenericIntegrationMethod const & _integration_method
Definition HTFEM.h:270
static const int temperature_index
Definition HTFEM.h:424
static const int temperature_size
Definition HTFEM.h:425
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:273
static const int pressure_size
Definition HTFEM.h:423
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:298
MeshLib::Element const & _element
Definition HTFEM.h:267
HTProcessData const & _process_data
Definition HTFEM.h:268
std::vector< IntegrationPointData< GlobalDimNodalMatrixType > > _ip_data
Definition HTFEM.h:271
static const int pressure_index
Definition HTFEM.h:422
void assembleForStaggeredScheme(double const t, double const dt, Eigen::VectorXd const &local_x, Eigen::VectorXd const &local_x_prev, int const process_id, std::vector< double > &local_M_data, std::vector< double > &local_K_data, std::vector< double > &local_b_data) override
typename ShapeMatricesType::GlobalDimVectorType GlobalDimVectorType
void assembleHydraulicEquation(double const t, double const dt, Eigen::VectorXd const &local_x, Eigen::VectorXd const &local_x_prev, std::vector< double > &local_M_data, std::vector< double > &local_K_data, std::vector< double > &local_b_data)
void assembleHeatTransportEquation(double const t, double const dt, Eigen::VectorXd const &local_x, std::vector< double > &local_M_data, std::vector< double > &local_K_data)
typename ShapeMatricesType::GlobalDimMatrixType GlobalDimMatrixType
std::vector< double > const & getIntPtDarcyVelocity(const double t, std::vector< GlobalVector * > const &x, std::vector< NumLib::LocalToGlobalIndexMap const * > const &dof_table, std::vector< double > &cache) const override
ShapeMatrixPolicyType< ShapeFunction, GlobalDim > ShapeMatricesType
constexpr Eigen::Matrix< double, GlobalDim, GlobalDim > formEigenTensor(MaterialPropertyLib::PropertyDataType const &values)
Eigen::Map< Vector > createZeroedVector(std::vector< double > &data, Eigen::VectorXd::Index size)
Eigen::Map< Matrix > createZeroedMatrix(std::vector< double > &data, Eigen::MatrixXd::Index rows, Eigen::MatrixXd::Index cols)
void shapeFunctionInterpolate(const NodalValues &, const ShapeMatrix &)
void assembleAdvectionMatrix(IPData const &ip_data_vector, NumLib::ShapeMatrixCache const &shape_matrix_cache, std::vector< FluxVectorType > const &ip_flux_vector, Eigen::MatrixBase< Derived > &laplacian_matrix)
std::vector< GlobalIndexType > getIndices(std::size_t const mesh_item_id, NumLib::LocalToGlobalIndexMap const &dof_table)
std::array< double, 3 > interpolateCoordinates(MeshLib::Element const &e, typename ShapeMatricesType::ShapeMatrices::ShapeType const &N)
double evalEffectiveThermalExpansivity(double const t, double const dt, ParameterLib::SpatialPosition const &pos, MaterialPropertyLib::VariableArray const &vars, MaterialPropertyLib::Medium const &medium, MaterialPropertyLib::Phase const &liquid_phase, MaterialPropertyLib::Phase const &solid_phase, bool const has_solid_thermal_expansivity, double const specific_storage)
Definition HTFEM.cpp:43
std::vector< double > getCoupledLocalSolutions(std::vector< GlobalVector * > const &global_solutions, std::vector< std::vector< GlobalIndexType > > const &indices)