OGS
StaggeredHTFEM-impl.h
Go to the documentation of this file.
1 
12 #pragma once
13 
14 #include "StaggeredHTFEM.h"
15 
16 #include "MaterialLib/MPL/Medium.h"
19 
20 namespace ProcessLib
21 {
22 namespace HT
23 {
24 template <typename ShapeFunction, typename IntegrationMethod, int GlobalDim>
26  assembleForStaggeredScheme(double const t, double const dt,
27  Eigen::VectorXd const& local_x,
28  Eigen::VectorXd const& local_xdot,
29  int const process_id,
30  std::vector<double>& local_M_data,
31  std::vector<double>& local_K_data,
32  std::vector<double>& local_b_data)
33 {
34  if (process_id == this->_process_data.heat_transport_process_id)
35  {
36  assembleHeatTransportEquation(t, dt, local_x, local_M_data,
37  local_K_data);
38  return;
39  }
40 
41  assembleHydraulicEquation(t, dt, local_x, local_xdot, local_M_data,
42  local_K_data, local_b_data);
43 }
44 
45 template <typename ShapeFunction, typename IntegrationMethod, int GlobalDim>
47  assembleHydraulicEquation(double const t, double const dt,
48  Eigen::VectorXd const& local_x,
49  Eigen::VectorXd const& local_xdot,
50  std::vector<double>& local_M_data,
51  std::vector<double>& local_K_data,
52  std::vector<double>& local_b_data)
53 {
54  auto const local_p =
55  local_x.template segment<pressure_size>(pressure_index);
56  auto const local_T =
57  local_x.template segment<temperature_size>(temperature_index);
58 
59  auto const local_Tdot =
60  local_xdot.template segment<temperature_size>(temperature_index);
61 
62  auto local_M = MathLib::createZeroedMatrix<LocalMatrixType>(
63  local_M_data, pressure_size, pressure_size);
64  auto local_K = MathLib::createZeroedMatrix<LocalMatrixType>(
65  local_K_data, pressure_size, pressure_size);
66  auto local_b = MathLib::createZeroedVector<LocalVectorType>(local_b_data,
67  pressure_size);
68 
70  pos.setElementID(this->_element.getID());
71 
72  auto const& process_data = this->_process_data;
73  auto const& medium = *this->_process_data.media_map->getMedium(
74  this->_element.getID());
75  auto const& liquid_phase = medium.phase("AqueousLiquid");
76  auto const& solid_phase = medium.phase("Solid");
77 
78  auto const& b = process_data.specific_body_force;
79 
81 
82  unsigned const n_integration_points =
83  this->_integration_method.getNumberOfPoints();
84 
85  for (unsigned ip(0); ip < n_integration_points; ip++)
86  {
87  pos.setIntegrationPoint(ip);
88 
89  auto const& ip_data = this->_ip_data[ip];
90  auto const& N = ip_data.N;
91  auto const& dNdx = ip_data.dNdx;
92  auto const& w = ip_data.integration_weight;
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[static_cast<int>(MaterialPropertyLib::Variable::temperature)] =
100  T_int_pt;
101  vars[static_cast<int>(MaterialPropertyLib::Variable::phase_pressure)] =
102  p_int_pt;
103 
104  vars[static_cast<int>(MaterialPropertyLib::Variable::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  const double dfluid_density_dp =
114  liquid_phase.property(MaterialPropertyLib::PropertyType::density)
115  .template dValue<double>(
117  dt);
118 
119  // Use the viscosity model to compute the viscosity
120  auto const viscosity =
121  liquid_phase.property(MaterialPropertyLib::PropertyType::viscosity)
122  .template value<double>(vars, pos, t, dt);
123 
124  // \todo the argument to getValue() has to be changed for non
125  // constant storage model
126  auto const specific_storage =
127  solid_phase.property(MaterialPropertyLib::PropertyType::storage)
128  .template value<double>(vars, pos, t, dt);
129 
130  auto const intrinsic_permeability =
131  MaterialPropertyLib::formEigenTensor<GlobalDim>(
133  .value(vars, pos, t, dt));
134  GlobalDimMatrixType const K_over_mu =
135  intrinsic_permeability / viscosity;
136 
137  // matrix assembly
138  local_M.noalias() +=
139  w *
140  (porosity * dfluid_density_dp / fluid_density + specific_storage) *
141  N.transpose() * N;
142 
143  local_K.noalias() += w * dNdx.transpose() * K_over_mu * dNdx;
144 
145  if (process_data.has_gravity)
146  {
147  local_b.noalias() +=
148  w * fluid_density * dNdx.transpose() * K_over_mu * b;
149  }
150 
151  if (!process_data.has_fluid_thermal_expansion)
152  {
153  return;
154  }
155 
156  // Add the thermal expansion term
157  {
158  auto const solid_thermal_expansion =
159  process_data.solid_thermal_expansion(t, pos)[0];
160  const double dfluid_density_dT =
161  liquid_phase
163  .template dValue<double>(
165  t, dt);
166  double Tdot_int_pt = 0.;
167  NumLib::shapeFunctionInterpolate(local_Tdot, N, Tdot_int_pt);
168  auto const biot_constant =
169  process_data.biot_constant(t, pos)[0];
170  const double eff_thermal_expansion =
171  3.0 * (biot_constant - porosity) * solid_thermal_expansion -
172  porosity * dfluid_density_dT / fluid_density;
173  local_b.noalias() += eff_thermal_expansion * Tdot_int_pt * w * N;
174  }
175  }
176 }
177 
178 template <typename ShapeFunction, typename IntegrationMethod, int GlobalDim>
180  assembleHeatTransportEquation(double const t,
181  double const dt,
182  Eigen::VectorXd const& local_x,
183  std::vector<double>& local_M_data,
184  std::vector<double>& local_K_data)
185 {
186  auto const local_p =
187  local_x.template segment<pressure_size>(pressure_index);
188  auto const local_T =
189  local_x.template segment<temperature_size>(temperature_index);
190 
191  auto local_M = MathLib::createZeroedMatrix<LocalMatrixType>(
192  local_M_data, temperature_size, temperature_size);
193  auto local_K = MathLib::createZeroedMatrix<LocalMatrixType>(
194  local_K_data, temperature_size, temperature_size);
195 
197  pos.setElementID(this->_element.getID());
198 
199  auto const& process_data = this->_process_data;
200  auto const& medium =
201  *process_data.media_map->getMedium(this->_element.getID());
202  auto const& liquid_phase = medium.phase("AqueousLiquid");
203 
204  auto const& b = process_data.specific_body_force;
205 
206  GlobalDimMatrixType const& I(
207  GlobalDimMatrixType::Identity(GlobalDim, GlobalDim));
208 
210 
211  unsigned const n_integration_points =
212  this->_integration_method.getNumberOfPoints();
213 
214  for (unsigned ip(0); ip < n_integration_points; ip++)
215  {
216  pos.setIntegrationPoint(ip);
217 
218  auto const& ip_data = this->_ip_data[ip];
219  auto const& N = ip_data.N;
220  auto const& dNdx = ip_data.dNdx;
221  auto const& w = ip_data.integration_weight;
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[static_cast<int>(MaterialPropertyLib::Variable::temperature)] =
229  T_at_xi;
230  vars[static_cast<int>(MaterialPropertyLib::Variable::phase_pressure)] =
231  p_at_xi;
232 
233  vars[static_cast<int>(MaterialPropertyLib::Variable::liquid_saturation)] = 1.0;
234 
235  auto const porosity =
237  .template value<double>(vars, pos, t, dt);
238  vars[static_cast<int>(MaterialPropertyLib::Variable::porosity)] =
239  porosity;
240 
241  // Use the fluid density model to compute the density
242  auto const fluid_density =
243  liquid_phase.property(MaterialPropertyLib::PropertyType::density)
244  .template value<double>(vars, pos, t, dt);
245  auto const specific_heat_capacity_fluid =
246  liquid_phase.property(MaterialPropertyLib::specific_heat_capacity)
247  .template value<double>(vars, pos, t, dt);
248 
249  // Assemble mass matrix
250  local_M.noalias() += w *
251  this->getHeatEnergyCoefficient(
252  vars, porosity, fluid_density,
253  specific_heat_capacity_fluid, pos, t, dt) *
254  N.transpose() * N;
255 
256  // Assemble Laplace matrix
257  auto const viscosity =
258  liquid_phase.property(MaterialPropertyLib::PropertyType::viscosity)
259  .template value<double>(vars, pos, t, dt);
260 
261  auto const intrinsic_permeability =
262  MaterialPropertyLib::formEigenTensor<GlobalDim>(
263  medium
265  .value(vars, pos, t, dt));
266 
267  GlobalDimMatrixType const K_over_mu =
268  intrinsic_permeability / viscosity;
269  GlobalDimVectorType const velocity =
270  process_data.has_gravity
271  ? GlobalDimVectorType(-K_over_mu *
272  (dNdx * local_p - fluid_density * b))
273  : GlobalDimVectorType(-K_over_mu * dNdx * local_p);
274 
275  GlobalDimMatrixType const thermal_conductivity_dispersivity =
276  this->getThermalConductivityDispersivity(
277  vars, fluid_density, specific_heat_capacity_fluid,
278  velocity, I, pos, t, dt);
279 
280  local_K.noalias() +=
281  w * (dNdx.transpose() * thermal_conductivity_dispersivity * dNdx +
282  N.transpose() * velocity.transpose() * dNdx * fluid_density *
283  specific_heat_capacity_fluid);
284  }
285 }
286 
287 template <typename ShapeFunction, typename IntegrationMethod, int GlobalDim>
288 std::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)
typename ShapeMatricesType::GlobalDimVectorType GlobalDimVectorType
Definition: HTFEM.h:40
typename ShapeMatricesType::GlobalDimMatrixType GlobalDimMatrixType
Definition: HTFEM.h:43
void assembleForStaggeredScheme(double const t, double const dt, Eigen::VectorXd const &local_x, Eigen::VectorXd const &local_xdot, int const process_id, std::vector< double > &local_M_data, std::vector< double > &local_K_data, std::vector< double > &local_b_data) override
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)
void assembleHydraulicEquation(double const t, double const dt, Eigen::VectorXd const &local_x, Eigen::VectorXd const &local_xdot, std::vector< double > &local_M_data, std::vector< double > &local_K_data, std::vector< double > &local_b_data)
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
std::array< VariableType, static_cast< int >(Variable::number_of_variables)> VariableArray
Definition: VariableType.h:108
void shapeFunctionInterpolate(const NodalValues &nodal_values, const ShapeMatrix &shape_matrix_N, double &interpolated_value, ScalarTypes &... interpolated_values)
Definition: Interpolation.h:79
std::vector< GlobalIndexType > getIndices(std::size_t const mesh_item_id, NumLib::LocalToGlobalIndexMap const &dof_table)
double fluid_density(const double p, const double T, const double x)
std::vector< double > getCoupledLocalSolutions(std::vector< GlobalVector * > const &global_solutions, std::vector< std::vector< GlobalIndexType >> const &indices)