OGS
StaggeredHTFEM-impl.h
Go to the documentation of this file.
1
12#pragma once
13
14#include <typeinfo>
15
19#include "StaggeredHTFEM.h"
20
21namespace ProcessLib
22{
23namespace HT
24{
25template <typename ShapeFunction, int GlobalDim>
27 double const t, double const dt, Eigen::VectorXd const& local_x,
28 Eigen::VectorXd const& local_x_prev, int const process_id,
29 std::vector<double>& local_M_data, std::vector<double>& local_K_data,
30 std::vector<double>& local_b_data)
31{
32 if (process_id == this->_process_data.heat_transport_process_id)
33 {
34 assembleHeatTransportEquation(t, dt, local_x, local_M_data,
35 local_K_data);
36 return;
37 }
38
39 assembleHydraulicEquation(t, dt, local_x, local_x_prev, local_M_data,
40 local_K_data, local_b_data);
41}
42
43template <typename ShapeFunction, int GlobalDim>
45 double const t, double const dt, Eigen::VectorXd const& local_x,
46 Eigen::VectorXd const& local_x_prev, std::vector<double>& local_M_data,
47 std::vector<double>& local_K_data, std::vector<double>& local_b_data)
48{
49 auto const local_p =
50 local_x.template segment<pressure_size>(pressure_index);
51 auto const local_T =
52 local_x.template segment<temperature_size>(temperature_index);
53
54 auto const local_T_prev =
55 local_x_prev.template segment<temperature_size>(temperature_index);
56
57 auto local_M = MathLib::createZeroedMatrix<LocalMatrixType>(
58 local_M_data, pressure_size, pressure_size);
59 auto local_K = MathLib::createZeroedMatrix<LocalMatrixType>(
60 local_K_data, pressure_size, pressure_size);
61 auto local_b = MathLib::createZeroedVector<LocalVectorType>(local_b_data,
62 pressure_size);
63
65 pos.setElementID(this->_element.getID());
66
67 auto const& process_data = this->_process_data;
68 auto const& medium =
69 *this->_process_data.media_map.getMedium(this->_element.getID());
70 auto const& liquid_phase = medium.phase("AqueousLiquid");
71 auto const& solid_phase = medium.phase("Solid");
72
73 auto const& b =
74 process_data
75 .projected_specific_body_force_vectors[this->_element.getID()];
76
78
79 unsigned const n_integration_points =
80 this->_integration_method.getNumberOfPoints();
81
82 for (unsigned ip(0); ip < n_integration_points; ip++)
83 {
84 pos.setIntegrationPoint(ip);
85
86 auto const& ip_data = this->_ip_data[ip];
87 auto const& N = ip_data.N;
88 auto const& dNdx = ip_data.dNdx;
89 auto const& w = ip_data.integration_weight;
90
91 double p_int_pt = 0.0;
92 double T_int_pt = 0.0;
93 NumLib::shapeFunctionInterpolate(local_p, N, p_int_pt);
94 NumLib::shapeFunctionInterpolate(local_T, N, T_int_pt);
95
96 vars.temperature = T_int_pt;
97 vars.liquid_phase_pressure = p_int_pt;
98
99 vars.liquid_saturation = 1.0;
100
101 auto const porosity =
103 .template value<double>(vars, pos, t, dt);
104 auto const fluid_density =
105 liquid_phase.property(MaterialPropertyLib::PropertyType::density)
106 .template value<double>(vars, pos, t, dt);
107
108 vars.density = fluid_density;
109 const double dfluid_density_dp =
110 liquid_phase.property(MaterialPropertyLib::PropertyType::density)
111 .template dValue<double>(
113 pos, t, dt);
114
115 // Use the viscosity model to compute the viscosity
116 auto const viscosity =
118 .template value<double>(vars, pos, t, dt);
119
120 // \todo the argument to getValue() has to be changed for non
121 // constant storage model
122 auto const specific_storage =
124 .template value<double>(vars, pos, t, dt);
125
126 auto const intrinsic_permeability =
127 MaterialPropertyLib::formEigenTensor<GlobalDim>(
129 .value(vars, pos, t, dt));
130 GlobalDimMatrixType const K_over_mu =
131 intrinsic_permeability / viscosity;
132
133 // matrix assembly
134 local_M.noalias() +=
135 w *
136 (porosity * dfluid_density_dp / fluid_density + specific_storage) *
137 N.transpose() * N;
138
139 local_K.noalias() += w * dNdx.transpose() * K_over_mu * dNdx;
140
141 if (process_data.has_gravity)
142 {
143 local_b.noalias() +=
144 w * fluid_density * dNdx.transpose() * K_over_mu * b;
145 }
146
147 if (!process_data.has_fluid_thermal_expansion)
148 {
149 return;
150 }
151
152 // Add the thermal expansion term
153 {
154 auto const solid_thermal_expansion =
155 process_data.solid_thermal_expansion(t, pos)[0];
156 const double dfluid_density_dT =
157 liquid_phase
159 .template dValue<double>(
161 t, dt);
162 double const Tdot_int_pt = (T_int_pt - local_T_prev.dot(N)) / dt;
163 auto const biot_constant = process_data.biot_constant(t, pos)[0];
164 const double eff_thermal_expansion =
165 3.0 * (biot_constant - porosity) * solid_thermal_expansion -
166 porosity * dfluid_density_dT / fluid_density;
167 local_b.noalias() += eff_thermal_expansion * Tdot_int_pt * w * N;
168 }
169 }
170}
171
172template <typename ShapeFunction, int GlobalDim>
174 double const t,
175 double const dt,
176 Eigen::VectorXd const& local_x,
177 std::vector<double>& local_M_data,
178 std::vector<double>& local_K_data)
179{
180 auto const local_p =
181 local_x.template segment<pressure_size>(pressure_index);
182 auto const local_T =
183 local_x.template segment<temperature_size>(temperature_index);
184
185 auto local_M = MathLib::createZeroedMatrix<LocalMatrixType>(
186 local_M_data, temperature_size, temperature_size);
187 auto local_K = MathLib::createZeroedMatrix<LocalMatrixType>(
188 local_K_data, temperature_size, temperature_size);
189
191 pos.setElementID(this->_element.getID());
192
193 auto const& process_data = this->_process_data;
194 auto const& medium =
195 *process_data.media_map.getMedium(this->_element.getID());
196 auto const& liquid_phase = medium.phase("AqueousLiquid");
197
198 auto const& b =
199 process_data
200 .projected_specific_body_force_vectors[this->_element.getID()];
201
203
204 unsigned const n_integration_points =
205 this->_integration_method.getNumberOfPoints();
206
207 std::vector<GlobalDimVectorType> ip_flux_vector;
208 double average_velocity_norm = 0.0;
209 ip_flux_vector.reserve(n_integration_points);
210
211 for (unsigned ip(0); ip < n_integration_points; ip++)
212 {
213 pos.setIntegrationPoint(ip);
214
215 auto const& ip_data = this->_ip_data[ip];
216 auto const& N = ip_data.N;
217 auto const& dNdx = ip_data.dNdx;
218 auto const& w = ip_data.integration_weight;
219
220 double p_at_xi = 0.;
221 NumLib::shapeFunctionInterpolate(local_p, N, p_at_xi);
222 double T_at_xi = 0.;
223 NumLib::shapeFunctionInterpolate(local_T, N, T_at_xi);
224
225 vars.temperature = T_at_xi;
226 vars.liquid_phase_pressure = p_at_xi;
227
228 vars.liquid_saturation = 1.0;
229
230 auto const porosity =
232 .template value<double>(vars, pos, t, dt);
233 vars.porosity = porosity;
234
235 // Use the fluid density model to compute the density
236 auto const fluid_density =
237 liquid_phase.property(MaterialPropertyLib::PropertyType::density)
238 .template value<double>(vars, pos, t, dt);
239 vars.density = fluid_density;
240 auto const specific_heat_capacity_fluid =
242 .template value<double>(vars, pos, t, dt);
243
244 // Assemble mass matrix
245 local_M.noalias() += w *
246 this->getHeatEnergyCoefficient(
247 vars, porosity, fluid_density,
248 specific_heat_capacity_fluid, pos, t, dt) *
249 N.transpose() * N;
250
251 // Assemble Laplace matrix
252 auto const viscosity =
254 .template value<double>(vars, pos, t, dt);
255
256 auto const intrinsic_permeability =
257 MaterialPropertyLib::formEigenTensor<GlobalDim>(
259 .value(vars, pos, t, dt));
260
261 GlobalDimMatrixType const K_over_mu =
262 intrinsic_permeability / viscosity;
263 GlobalDimVectorType const velocity =
264 process_data.has_gravity
265 ? GlobalDimVectorType(-K_over_mu *
266 (dNdx * local_p - fluid_density * b))
267 : GlobalDimVectorType(-K_over_mu * dNdx * local_p);
268
269 GlobalDimMatrixType const thermal_conductivity_dispersivity =
270 this->getThermalConductivityDispersivity(
271 vars, fluid_density, specific_heat_capacity_fluid, velocity,
272 pos, t, dt);
273
274 local_K.noalias() +=
275 w * dNdx.transpose() * thermal_conductivity_dispersivity * dNdx;
276
277 ip_flux_vector.emplace_back(velocity * fluid_density *
278 specific_heat_capacity_fluid);
279 average_velocity_norm += velocity.norm();
280 }
281
283 process_data.stabilizer, this->_ip_data, ip_flux_vector,
284 average_velocity_norm / static_cast<double>(n_integration_points),
285 local_K);
286}
287
288template <typename ShapeFunction, int GlobalDim>
289std::vector<double> const&
291 const double t,
292 std::vector<GlobalVector*> const& x,
293 std::vector<NumLib::LocalToGlobalIndexMap const*> const& dof_table,
294 std::vector<double>& cache) const
295{
296 assert(x.size() == dof_table.size());
297 auto const n_processes = dof_table.size();
298
299 std::vector<std::vector<GlobalIndexType>> indices_of_all_coupled_processes;
300 indices_of_all_coupled_processes.reserve(n_processes);
301 for (std::size_t process_id = 0; process_id < n_processes; ++process_id)
302 {
303 auto const indices =
304 NumLib::getIndices(this->_element.getID(), *dof_table[process_id]);
305 assert(!indices.empty());
306 indices_of_all_coupled_processes.push_back(indices);
307 }
308 auto const local_xs =
309 getCoupledLocalSolutions(x, indices_of_all_coupled_processes);
310
311 return this->getIntPtDarcyVelocityLocal(t, local_xs, cache);
312}
313} // namespace HT
314} // namespace ProcessLib
void setElementID(std::size_t element_id)
void setIntegrationPoint(unsigned integration_point)
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
void assembleAdvectionMatrix(IPData const &ip_data_vector, std::vector< FluxVectorType > const &ip_flux_vector, Eigen::MatrixBase< Derived > &laplacian_matrix)
void shapeFunctionInterpolate(const NodalValues &, const ShapeMatrix &)
Definition: Interpolation.h:27
std::vector< GlobalIndexType > getIndices(std::size_t const mesh_item_id, NumLib::LocalToGlobalIndexMap const &dof_table)
std::vector< double > getCoupledLocalSolutions(std::vector< GlobalVector * > const &global_solutions, std::vector< std::vector< GlobalIndexType > > const &indices)