Loading [MathJax]/extensions/tex2jax.js
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
58 local_M_data, pressure_size, pressure_size);
60 local_K_data, pressure_size, pressure_size);
61 auto local_b = MathLib::createZeroedVector<LocalVectorType>(local_b_data,
62 pressure_size);
63
64 auto const& process_data = this->_process_data;
65 auto const& medium =
66 *this->_process_data.media_map.getMedium(this->_element.getID());
67 auto const& liquid_phase = medium.phase("AqueousLiquid");
68 auto const& solid_phase = medium.phase("Solid");
69
70 auto const& b =
71 process_data
72 .projected_specific_body_force_vectors[this->_element.getID()];
73
75
76 unsigned const n_integration_points =
77 this->_integration_method.getNumberOfPoints();
78
79 auto const& Ns =
80 process_data.shape_matrix_cache
81 .template NsHigherOrder<typename ShapeFunction::MeshElement>();
82
83 for (unsigned ip(0); ip < n_integration_points; ip++)
84 {
85 auto const& ip_data = this->_ip_data[ip];
86 auto const& dNdx = ip_data.dNdx;
87 auto const& N = Ns[ip];
88 auto const& w = ip_data.integration_weight;
89
91 std::nullopt, this->_element.getID(),
94 this->_element, N))};
95
96 double p_int_pt = 0.0;
97 double T_int_pt = 0.0;
98 NumLib::shapeFunctionInterpolate(local_p, N, p_int_pt);
99 NumLib::shapeFunctionInterpolate(local_T, N, T_int_pt);
100
101 vars.temperature = T_int_pt;
102 vars.liquid_phase_pressure = p_int_pt;
103
104 vars.liquid_saturation = 1.0;
105
106 auto const porosity =
108 .template value<double>(vars, pos, t, dt);
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 // \todo the argument to getValue() has to be changed for non
126 // constant storage model
127 auto const specific_storage =
129 .template value<double>(vars, pos, t, dt);
130
131 auto const intrinsic_permeability =
134 .value(vars, pos, t, dt));
135 GlobalDimMatrixType const K_over_mu =
136 intrinsic_permeability / viscosity;
137
138 // matrix assembly
139 local_M.noalias() +=
140 w *
141 (porosity * dfluid_density_dp / fluid_density + specific_storage) *
142 N.transpose() * N;
143
144 local_K.noalias() += w * dNdx.transpose() * K_over_mu * dNdx;
145
146 if (process_data.has_gravity)
147 {
148 local_b.noalias() +=
149 w * fluid_density * dNdx.transpose() * K_over_mu * b;
150 }
151
152 if (!process_data.has_fluid_thermal_expansion)
153 {
154 return;
155 }
156
157 // Add the thermal expansion term
158 {
159 auto const solid_thermal_expansion =
160 process_data.solid_thermal_expansion(t, pos)[0];
161 const double dfluid_density_dT =
162 liquid_phase
164 .template dValue<double>(
166 t, dt);
167 double const Tdot_int_pt = (T_int_pt - local_T_prev.dot(N)) / dt;
168 auto const biot_constant = process_data.biot_constant(t, pos)[0];
169 const double eff_thermal_expansion =
170 3.0 * (biot_constant - porosity) * solid_thermal_expansion -
171 porosity * dfluid_density_dT / fluid_density;
172 local_b.noalias() += eff_thermal_expansion * Tdot_int_pt * w * N;
173 }
174 }
175}
176
177template <typename ShapeFunction, int GlobalDim>
179 double const t,
180 double const dt,
181 Eigen::VectorXd const& local_x,
182 std::vector<double>& local_M_data,
183 std::vector<double>& local_K_data)
184{
185 auto const local_p =
186 local_x.template segment<pressure_size>(pressure_index);
187 auto const local_T =
188 local_x.template segment<temperature_size>(temperature_index);
189
191 local_M_data, temperature_size, temperature_size);
193 local_K_data, temperature_size, temperature_size);
194
195 auto const& process_data = this->_process_data;
196 auto const& medium =
197 *process_data.media_map.getMedium(this->_element.getID());
198 auto const& liquid_phase = medium.phase("AqueousLiquid");
199
200 auto const& b =
201 process_data
202 .projected_specific_body_force_vectors[this->_element.getID()];
203
205
206 unsigned const n_integration_points =
207 this->_integration_method.getNumberOfPoints();
208
209 std::vector<GlobalDimVectorType> ip_flux_vector;
210 double average_velocity_norm = 0.0;
211 ip_flux_vector.reserve(n_integration_points);
212
213 auto const& Ns =
214 process_data.shape_matrix_cache
215 .template NsHigherOrder<typename ShapeFunction::MeshElement>();
216
217 for (unsigned ip(0); ip < n_integration_points; ip++)
218 {
219 auto const& ip_data = this->_ip_data[ip];
220 auto const& dNdx = ip_data.dNdx;
221 auto const& N = Ns[ip];
222 auto const& w = ip_data.integration_weight;
223
225 std::nullopt, this->_element.getID(),
228 this->_element, N))};
229
230 double p_at_xi = 0.;
231 NumLib::shapeFunctionInterpolate(local_p, N, p_at_xi);
232 double T_at_xi = 0.;
233 NumLib::shapeFunctionInterpolate(local_T, N, T_at_xi);
234
235 vars.temperature = T_at_xi;
236 vars.liquid_phase_pressure = p_at_xi;
237
238 vars.liquid_saturation = 1.0;
239
240 auto const porosity =
242 .template value<double>(vars, pos, t, dt);
243 vars.porosity = porosity;
244
245 // Use the fluid density model to compute the density
246 auto const fluid_density =
247 liquid_phase.property(MaterialPropertyLib::PropertyType::density)
248 .template value<double>(vars, pos, t, dt);
249 vars.density = fluid_density;
250 auto const specific_heat_capacity_fluid =
252 .template value<double>(vars, pos, t, dt);
253
254 // Assemble mass matrix
255 local_M.noalias() += w *
256 this->getHeatEnergyCoefficient(
257 vars, porosity, fluid_density,
258 specific_heat_capacity_fluid, pos, t, dt) *
259 N.transpose() * N;
260
261 // Assemble Laplace matrix
262 auto const viscosity =
264 .template value<double>(vars, pos, t, dt);
265
266 auto const intrinsic_permeability =
269 .value(vars, pos, t, dt));
270
271 GlobalDimMatrixType const K_over_mu =
272 intrinsic_permeability / viscosity;
273 GlobalDimVectorType const velocity =
274 process_data.has_gravity
275 ? GlobalDimVectorType(-K_over_mu *
276 (dNdx * local_p - fluid_density * b))
277 : GlobalDimVectorType(-K_over_mu * dNdx * local_p);
278
279 GlobalDimMatrixType const thermal_conductivity_dispersivity =
280 this->getThermalConductivityDispersivity(
281 vars, fluid_density, specific_heat_capacity_fluid, velocity,
282 pos, t, dt);
283
284 local_K.noalias() +=
285 w * dNdx.transpose() * thermal_conductivity_dispersivity * dNdx;
286
287 ip_flux_vector.emplace_back(velocity * fluid_density *
288 specific_heat_capacity_fluid);
289 average_velocity_norm += velocity.norm();
290 }
291
293 process_data.stabilizer, this->_ip_data,
294 process_data.shape_matrix_cache, ip_flux_vector,
295 average_velocity_norm / static_cast<double>(n_integration_points),
296 local_K);
297}
298
299template <typename ShapeFunction, int GlobalDim>
300std::vector<double> const&
302 const double t,
303 std::vector<GlobalVector*> const& x,
304 std::vector<NumLib::LocalToGlobalIndexMap const*> const& dof_table,
305 std::vector<double>& cache) const
306{
307 assert(x.size() == dof_table.size());
308 auto const n_processes = dof_table.size();
309
310 std::vector<std::vector<GlobalIndexType>> indices_of_all_coupled_processes;
311 indices_of_all_coupled_processes.reserve(n_processes);
312 for (std::size_t process_id = 0; process_id < n_processes; ++process_id)
313 {
314 auto const indices =
315 NumLib::getIndices(this->_element.getID(), *dof_table[process_id]);
316 assert(!indices.empty());
317 indices_of_all_coupled_processes.push_back(indices);
318 }
319 auto const local_xs =
320 getCoupledLocalSolutions(x, indices_of_all_coupled_processes);
321
322 return this->getIntPtDarcyVelocityLocal(t, local_xs, cache);
323}
324} // namespace HT
325} // namespace ProcessLib
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
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)
std::vector< double > getCoupledLocalSolutions(std::vector< GlobalVector * > const &global_solutions, std::vector< std::vector< GlobalIndexType > > const &indices)