OGS
ThermoRichardsMechanicsFEM.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 <memory>
7#include <vector>
8
14#include "NumLib/DOF/LocalDOF.h"
22
23namespace ProcessLib
24{
26{
27namespace MPL = MaterialPropertyLib;
28
29template <typename ShapeFunctionDisplacement, typename ShapeFunction,
30 int DisplacementDim, typename ConstitutiveTraits>
32 : public LocalAssemblerInterface<DisplacementDim, ConstitutiveTraits>
33{
34 static constexpr int temperature_index = 0;
35 static constexpr int temperature_size = ShapeFunction::NPOINTS;
36 static constexpr int pressure_index = temperature_size;
37 static constexpr int pressure_size = ShapeFunction::NPOINTS;
38 static constexpr int displacement_index = 2 * ShapeFunction::NPOINTS;
39 static constexpr int displacement_size =
40 ShapeFunctionDisplacement::NPOINTS * DisplacementDim;
41
42public:
45 // Note: temperature variable uses the same shape functions as that are used
46 // by pressure variable.
49
52
56
58 ShapeMatricesType, DisplacementDim,
59 ShapeFunctionDisplacement::NPOINTS>;
60
61 static int const KelvinVectorSize =
64
65 using SymmetricTensor = Eigen::Matrix<double, KelvinVectorSize, 1>;
66
67 static constexpr auto& N_u_op = MathLib::eigenBlockMatrixView<
68 DisplacementDim,
70
75
77 MeshLib::Element const& e,
78 std::size_t const /*local_matrix_size*/,
79 NumLib::GenericIntegrationMethod const& integration_method,
80 bool const is_axially_symmetric,
82 process_data);
83
84 void setInitialConditionsConcrete(Eigen::VectorXd const local_x,
85 double const t,
86 int const process_id) override;
87
89 {
91
92 static auto constexpr local_matrix_dim =
94
95 template <Eigen::Index rows, Eigen::Index cols>
96 using Mat =
97 typename ShapeMatricesTypeDisplacement::template MatrixType<rows,
98 cols>;
99 using Vec = typename ShapeMatricesTypeDisplacement::template VectorType<
101
102 public:
103 void setZero()
104 {
105 M_TT = NodalMatrix::Zero(temperature_size, temperature_size);
106 M_Tp = NodalMatrix::Zero(temperature_size, pressure_size);
107 K_TT = NodalMatrix::Zero(temperature_size, temperature_size);
108 K_Tp = NodalMatrix::Zero(temperature_size, pressure_size);
109 dK_TT_dp = NodalMatrix::Zero(temperature_size, pressure_size);
110
113
114 M_pT = NodalMatrix::Zero(pressure_size, temperature_size);
115
116 K_pp = NodalMatrix::Zero(pressure_size, pressure_size);
117 K_pT = NodalMatrix::Zero(pressure_size, temperature_size);
118
119 storage_p_a_p = NodalMatrix::Zero(pressure_size, pressure_size);
120 storage_p_a_S_Jpp = NodalMatrix::Zero(pressure_size, pressure_size);
121 storage_p_a_S = NodalMatrix::Zero(pressure_size, pressure_size);
122
125 res = Vec::Zero(local_matrix_dim);
126 }
127
129 {
130 M_TT += other.M_TT;
131 M_Tp += other.M_Tp;
132 K_TT += other.K_TT;
133 K_Tp += other.K_Tp;
134 dK_TT_dp += other.dK_TT_dp;
135
136 M_pu += other.M_pu;
137
138 M_pT += other.M_pT;
139
140 K_pp += other.K_pp;
141 K_pT += other.K_pT;
142
146
147 Jac += other.Jac;
148 res += other.res;
149
150 return *this;
151 }
152
153 LocalMatrices& operator*=(double const a)
154 {
155 M_TT *= a;
156 M_Tp *= a;
157 K_TT *= a;
158 K_Tp *= a;
159 dK_TT_dp *= a;
160
161 M_pu *= a;
162
163 M_pT *= a;
164
165 K_pp *= a;
166 K_pT *= a;
167
168 storage_p_a_p *= a;
170 storage_p_a_S *= a;
171
172 Jac *= a;
173 res *= a;
174
175 return *this;
176 }
177
178 template <typename OStream>
179 friend OStream& operator<<(OStream& os, LocalMatrices const& loc_mat)
180 {
181 os << "- M_TT:\n"
182 << loc_mat.M_TT //
183 << "\n- M_Tp:\n"
184 << loc_mat.M_Tp //
185 << "\n- K_TT:\n"
186 << loc_mat.K_TT //
187 << "\n- K_Tp:\n"
188 << loc_mat.K_Tp //
189 << "\n- dK_TT_dp:\n"
190 << loc_mat.dK_TT_dp //
191 << "\n- M_pu:\n"
192 << loc_mat.M_pu //
193 << "\n- M_pT:\n"
194 << loc_mat.M_pT //
195 << "\n- K_pp:\n"
196 << loc_mat.K_pp //
197 << "\n- K_pT:\n"
198 << loc_mat.K_pT //
199 << "\n- storage_p_a_p:\n"
200 << loc_mat.storage_p_a_p //
201 << "\n- storage_p_a_S_Jpp:\n"
202 << loc_mat.storage_p_a_S_Jpp //
203 << "\n- storage_p_a_S:\n"
204 << loc_mat.storage_p_a_S //
205 << "\n- Jac:\n"
206 << loc_mat.Jac //
207 << "\n- res:\n"
208 << loc_mat.res;
209 return os;
210 }
211
217
219
221
224
228
232
236 };
237
238 void assembleWithJacobian(double const t, double const dt,
239 std::vector<double> const& local_x,
240 std::vector<double> const& local_x_prev,
241 std::vector<double>& local_rhs_data,
242 std::vector<double>& local_Jac_data) override;
243
245 {
246 return displacement_size;
247 }
248
249private:
251 double const t, double const dt,
252 ParameterLib::SpatialPosition const& x_position,
253 std::vector<double> const& local_x,
254 std::vector<double> const& local_x_prev, IpData const& ip_data,
255 typename ConstitutiveTraits::ConstitutiveSetting& CS,
256 MaterialPropertyLib::Medium& medium, LocalMatrices& out,
257 typename ConstitutiveTraits::StatefulData& current_state,
258 typename ConstitutiveTraits::StatefulDataPrev const& prev_state,
260 typename ConstitutiveTraits::OutputData& output_data) const;
261
262 void addToLocalMatrixData(double const dt,
263 std::vector<double> const& local_x,
264 std::vector<double> const& local_x_prev,
265 LocalMatrices const& loc_mat,
266 std::vector<double>& local_rhs_data,
267 std::vector<double>& local_Jac_data) const;
268
269 void massLumping(LocalMatrices& loc_mat) const;
270
271public:
272 void initializeConcrete() override
273 {
274 unsigned const n_integration_points =
275 this->integration_method_.getNumberOfPoints();
276 auto const time_independent = std::numeric_limits<double>::quiet_NaN();
277 auto const& medium =
278 *this->process_data_.media_map.getMedium(this->element_.getID());
279
280 for (unsigned ip = 0; ip < n_integration_points; ip++)
281 {
282 ParameterLib::SpatialPosition const x_position{
283 std::nullopt, this->element_.getID(),
285 ShapeFunctionDisplacement,
287 this->element_, this->ip_data_[ip].N_u))};
288 auto& current_state = this->current_states_[ip];
289
290 // Set initial stress from parameter.
291 if (this->process_data_.initial_stress.value)
292 {
293 ConstitutiveTraits::ConstitutiveSetting::statefulStress(
294 current_state) =
296 DisplacementDim>(
297 (*this->process_data_.initial_stress.value)(
298 time_independent, x_position));
299 }
300
301 if (*this->process_data_.initialize_porosity_from_medium_property)
302 {
303 // Initial porosity. Could be read from integration point data
304 // or mesh.
305 std::get<PorosityData>(current_state).phi =
306 medium.property(MPL::porosity)
307 .template initialValue<double>(x_position,
308 time_independent);
309
310 if (medium.hasProperty(MPL::PropertyType::transport_porosity))
311 {
312 std::get<TransportPorosityData>(current_state).phi =
313 medium.property(MPL::transport_porosity)
314 .template initialValue<double>(x_position,
315 time_independent);
316 }
317 else
318 {
319 std::get<TransportPorosityData>(current_state).phi =
320 std::get<PorosityData>(current_state).phi;
321 }
322 }
323
324 double const t = 0; // TODO (naumov) pass t from top
325 this->solid_material_.initializeInternalStateVariables(
326 t, x_position,
327 *this->material_states_[ip].material_state_variables);
328 }
329
330 for (unsigned ip = 0; ip < n_integration_points; ip++)
331 {
332 this->material_states_[ip].pushBackState();
333 }
334
335 for (unsigned ip = 0; ip < n_integration_points; ip++)
336 {
337 this->prev_states_[ip] = this->current_states_[ip];
338 }
339 }
340
342 double const t, double const dt, Eigen::VectorXd const& local_x,
343 Eigen::VectorXd const& local_x_prev) override;
344
345 Eigen::Map<const Eigen::RowVectorXd> getShapeMatrix(
346 const unsigned integration_point) const override
347 {
348 auto const& N_u = ip_data_[integration_point].N_u;
349
350 // assumes N is stored contiguously in memory
351 return Eigen::Map<const Eigen::RowVectorXd>(N_u.data(), N_u.size());
352 }
353
354private:
355 std::vector<IpData> ip_data_;
356
357 static constexpr auto localDOF(std::vector<double> const& x)
358 {
359 return NumLib::localDOF<
362 }
363
364 static auto block_uu(auto& mat)
365 {
366 return mat.template block<displacement_size, displacement_size>(
368 }
369 static auto block_up(auto& mat)
370 {
371 return mat.template block<displacement_size, pressure_size>(
373 }
374 static auto block_uT(auto& mat)
375 {
376 return mat.template block<displacement_size, temperature_size>(
378 }
379 static auto block_pu(auto& mat)
380 {
381 return mat.template block<pressure_size, displacement_size>(
383 }
384 static auto block_pp(auto& mat)
385 {
386 return mat.template block<pressure_size, pressure_size>(pressure_index,
388 }
389 static auto block_pT(auto& mat)
390 {
391 return mat.template block<pressure_size, temperature_size>(
393 }
394 static auto block_Tp(auto& mat)
395 {
396 return mat.template block<temperature_size, pressure_size>(
398 }
399 static auto block_TT(auto& mat)
400 {
401 return mat.template block<temperature_size, temperature_size>(
403 }
404
405 static auto block_u(auto& vec)
406 {
407 return vec.template segment<displacement_size>(displacement_index);
408 }
409 static auto block_p(auto& vec)
410 {
411 return vec.template segment<pressure_size>(pressure_index);
412 }
413 static auto block_T(auto& vec)
414 {
415 return vec.template segment<temperature_size>(temperature_index);
416 }
417
425 unsigned const ip, double const t,
426 ParameterLib::SpatialPosition const x_position,
427 MaterialPropertyLib::Medium const& medium,
428 MPL::VariableArray const& variables, double const p_at_ip);
429};
430
431} // namespace ThermoRichardsMechanics
432} // namespace ProcessLib
433
EigenFixedShapeMatrixPolicy< ShapeFunction, GlobalDim > ShapeMatrixPolicyType
typename ShapeMatricesTypeDisplacement::template MatrixType< rows, cols > Mat
typename ShapeMatricesTypeDisplacement::template VectorType< local_matrix_dim > Vec
void addToLocalMatrixData(double const dt, std::vector< double > const &local_x, std::vector< double > const &local_x_prev, LocalMatrices const &loc_mat, std::vector< double > &local_rhs_data, std::vector< double > &local_Jac_data) const
Eigen::Map< const Eigen::RowVectorXd > getShapeMatrix(const unsigned integration_point) const override
Provides the shape matrix at the given integration point.
void computeSecondaryVariableConcrete(double const t, double const dt, Eigen::VectorXd const &local_x, Eigen::VectorXd const &local_x_prev) override
void assembleWithJacobianSingleIP(double const t, double const dt, ParameterLib::SpatialPosition const &x_position, std::vector< double > const &local_x, std::vector< double > const &local_x_prev, IpData const &ip_data, typename ConstitutiveTraits::ConstitutiveSetting &CS, MaterialPropertyLib::Medium &medium, LocalMatrices &out, typename ConstitutiveTraits::StatefulData &current_state, typename ConstitutiveTraits::StatefulDataPrev const &prev_state, MaterialStateData< DisplacementDim > &mat_state, typename ConstitutiveTraits::OutputData &output_data) const
ShapeMatrixPolicyType< ShapeFunctionDisplacement, DisplacementDim > ShapeMatricesTypeDisplacement
ThermoRichardsMechanicsLocalAssembler(ThermoRichardsMechanicsLocalAssembler &&)=delete
void convertInitialStressType(unsigned const ip, double const t, ParameterLib::SpatialPosition const x_position, MaterialPropertyLib::Medium const &medium, MPL::VariableArray const &variables, double const p_at_ip)
ThermoRichardsMechanicsLocalAssembler(ThermoRichardsMechanicsLocalAssembler const &)=delete
void setInitialConditionsConcrete(Eigen::VectorXd const local_x, double const t, int const process_id) override
ShapeMatrixPolicyType< ShapeFunction, DisplacementDim > ShapeMatricesType
IntegrationPointData< ShapeMatricesTypeDisplacement, ShapeMatricesType, DisplacementDim, ShapeFunctionDisplacement::NPOINTS > IpData
void assembleWithJacobian(double const t, double const dt, std::vector< double > const &local_x, std::vector< double > const &local_x_prev, std::vector< double > &local_rhs_data, std::vector< double > &local_Jac_data) override
BMatrixPolicyType< ShapeFunctionDisplacement, DisplacementDim > BMatricesType
constexpr int kelvin_vector_dimensions(int const displacement_dim)
Kelvin vector dimensions for given displacement dimension.
Eigen::Matrix< double, Eigen::MatrixBase< Derived >::RowsAtCompileTime, 1 > symmetricTensorToKelvinVector(Eigen::MatrixBase< Derived > const &v)
constexpr Eigen::CwiseNullaryOp< EigenBlockMatrixViewFunctor< D, M >, typename EigenBlockMatrixViewFunctor< D, M >::Matrix > eigenBlockMatrixView(const Eigen::MatrixBase< M > &matrix)
auto localDOF(ElementDOFVector const &x)
Definition LocalDOF.h:56
std::array< double, 3 > interpolateCoordinates(MeshLib::Element const &e, typename ShapeMatricesType::ShapeMatrices::ShapeType const &N)
MatrixType< ShapeFunction::NPOINTS, ShapeFunction::NPOINTS > NodalMatrixType
MatrixType< GlobalDim, GlobalDim > GlobalDimMatrixType
VectorType< GlobalDim > GlobalDimVectorType
RowVectorType< ShapeFunction::NPOINTS > NodalRowVectorType
ThermoRichardsMechanicsProcessData< DisplacementDim, ConstitutiveTraits > & process_data_
LocalAssemblerInterface(MeshLib::Element const &e, NumLib::GenericIntegrationMethod const &integration_method, bool const is_axially_symmetric, ThermoRichardsMechanicsProcessData< DisplacementDim, ConstitutiveTraits > &process_data)