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
13#include "NumLib/DOF/LocalDOF.h"
21
22namespace ProcessLib
23{
25{
26namespace MPL = MaterialPropertyLib;
27
28template <typename ShapeFunctionDisplacement, typename ShapeFunction,
29 int DisplacementDim, typename ConstitutiveTraits>
31 : public LocalAssemblerInterface<DisplacementDim, ConstitutiveTraits>
32{
33 static constexpr int temperature_index = 0;
34 static constexpr int temperature_size = ShapeFunction::NPOINTS;
35 static constexpr int pressure_index = temperature_size;
36 static constexpr int pressure_size = ShapeFunction::NPOINTS;
37 static constexpr int displacement_index = 2 * ShapeFunction::NPOINTS;
38 static constexpr int displacement_size =
39 ShapeFunctionDisplacement::NPOINTS * DisplacementDim;
40
41public:
44 // Note: temperature variable uses the same shape functions as that are used
45 // by pressure variable.
48
51
55
57 ShapeMatricesType, DisplacementDim,
58 ShapeFunctionDisplacement::NPOINTS>;
59
60 static int const KelvinVectorSize =
63
64 using SymmetricTensor = Eigen::Matrix<double, KelvinVectorSize, 1>;
65
66 static constexpr auto& N_u_op = MathLib::eigenBlockMatrixView<
67 DisplacementDim,
69
74
76 MeshLib::Element const& e,
77 std::size_t const /*local_matrix_size*/,
78 NumLib::GenericIntegrationMethod const& integration_method,
79 bool const is_axially_symmetric,
81 process_data);
82
83 void setInitialConditionsConcrete(Eigen::VectorXd const local_x,
84 double const t,
85 int const process_id) override;
86
88 {
90
91 static auto constexpr local_matrix_dim =
93
94 template <Eigen::Index rows, Eigen::Index cols>
95 using Mat =
96 typename ShapeMatricesTypeDisplacement::template MatrixType<rows,
97 cols>;
98 using Vec = typename ShapeMatricesTypeDisplacement::template VectorType<
100
101 public:
102 void setZero()
103 {
104 M_TT = NodalMatrix::Zero(temperature_size, temperature_size);
105 M_Tp = NodalMatrix::Zero(temperature_size, pressure_size);
106 K_TT = NodalMatrix::Zero(temperature_size, temperature_size);
107 K_Tp = NodalMatrix::Zero(temperature_size, pressure_size);
108 dK_TT_dp = NodalMatrix::Zero(temperature_size, pressure_size);
109
112
113 M_pT = NodalMatrix::Zero(pressure_size, temperature_size);
114
115 K_pp = NodalMatrix::Zero(pressure_size, pressure_size);
116 K_pT = NodalMatrix::Zero(pressure_size, temperature_size);
117
118 storage_p_a_p = NodalMatrix::Zero(pressure_size, pressure_size);
119 storage_p_a_S_Jpp = NodalMatrix::Zero(pressure_size, pressure_size);
120 storage_p_a_S = NodalMatrix::Zero(pressure_size, pressure_size);
121
124 res = Vec::Zero(local_matrix_dim);
125 }
126
128 {
129 M_TT += other.M_TT;
130 M_Tp += other.M_Tp;
131 K_TT += other.K_TT;
132 K_Tp += other.K_Tp;
133 dK_TT_dp += other.dK_TT_dp;
134
135 M_pu += other.M_pu;
136
137 M_pT += other.M_pT;
138
139 K_pp += other.K_pp;
140 K_pT += other.K_pT;
141
145
146 Jac += other.Jac;
147 res += other.res;
148
149 return *this;
150 }
151
152 LocalMatrices& operator*=(double const a)
153 {
154 M_TT *= a;
155 M_Tp *= a;
156 K_TT *= a;
157 K_Tp *= a;
158 dK_TT_dp *= a;
159
160 M_pu *= a;
161
162 M_pT *= a;
163
164 K_pp *= a;
165 K_pT *= a;
166
167 storage_p_a_p *= a;
169 storage_p_a_S *= a;
170
171 Jac *= a;
172 res *= a;
173
174 return *this;
175 }
176
177 template <typename OStream>
178 friend OStream& operator<<(OStream& os, LocalMatrices const& loc_mat)
179 {
180 os << "- M_TT:\n"
181 << loc_mat.M_TT //
182 << "\n- M_Tp:\n"
183 << loc_mat.M_Tp //
184 << "\n- K_TT:\n"
185 << loc_mat.K_TT //
186 << "\n- K_Tp:\n"
187 << loc_mat.K_Tp //
188 << "\n- dK_TT_dp:\n"
189 << loc_mat.dK_TT_dp //
190 << "\n- M_pu:\n"
191 << loc_mat.M_pu //
192 << "\n- M_pT:\n"
193 << loc_mat.M_pT //
194 << "\n- K_pp:\n"
195 << loc_mat.K_pp //
196 << "\n- K_pT:\n"
197 << loc_mat.K_pT //
198 << "\n- storage_p_a_p:\n"
199 << loc_mat.storage_p_a_p //
200 << "\n- storage_p_a_S_Jpp:\n"
201 << loc_mat.storage_p_a_S_Jpp //
202 << "\n- storage_p_a_S:\n"
203 << loc_mat.storage_p_a_S //
204 << "\n- Jac:\n"
205 << loc_mat.Jac //
206 << "\n- res:\n"
207 << loc_mat.res;
208 return os;
209 }
210
216
218
220
223
227
231
235 };
236
237 void assembleWithJacobian(double const t, double const dt,
238 std::vector<double> const& local_x,
239 std::vector<double> const& local_x_prev,
240 std::vector<double>& local_rhs_data,
241 std::vector<double>& local_Jac_data) override;
242
244 {
245 return displacement_size;
246 }
247
248private:
250 double const t, double const dt,
251 ParameterLib::SpatialPosition const& x_position,
252 std::vector<double> const& local_x,
253 std::vector<double> const& local_x_prev, IpData const& ip_data,
254 typename ConstitutiveTraits::ConstitutiveSetting& CS,
255 MaterialPropertyLib::Medium& medium, LocalMatrices& out,
256 typename ConstitutiveTraits::StatefulData& current_state,
257 typename ConstitutiveTraits::StatefulDataPrev const& prev_state,
259 typename ConstitutiveTraits::OutputData& output_data) const;
260
261 void addToLocalMatrixData(double const dt,
262 std::vector<double> const& local_x,
263 std::vector<double> const& local_x_prev,
264 LocalMatrices const& loc_mat,
265 std::vector<double>& local_rhs_data,
266 std::vector<double>& local_Jac_data) const;
267
268 void massLumping(LocalMatrices& loc_mat) const;
269
270public:
271 void initializeConcrete() override
272 {
273 unsigned const n_integration_points =
274 this->integration_method_.getNumberOfPoints();
275 auto const time_independent = std::numeric_limits<double>::quiet_NaN();
276 auto const& medium =
277 *this->process_data_.media_map.getMedium(this->element_.getID());
278
279 for (unsigned ip = 0; ip < n_integration_points; ip++)
280 {
281 ParameterLib::SpatialPosition const x_position{
282 std::nullopt, this->element_.getID(),
284 ShapeFunctionDisplacement,
286 this->element_, this->ip_data_[ip].N_u))};
287 auto& current_state = this->current_states_[ip];
288
289 // Set initial stress from parameter.
290 if (this->process_data_.initial_stress.value)
291 {
292 ConstitutiveTraits::ConstitutiveSetting::statefulStress(
293 current_state) =
295 DisplacementDim>(
296 (*this->process_data_.initial_stress.value)(
297 time_independent, x_position));
298 }
299
300 if (*this->process_data_.initialize_porosity_from_medium_property)
301 {
302 // Initial porosity. Could be read from integration point data
303 // or mesh.
304 std::get<PorosityData>(current_state).phi =
305 medium.property(MPL::porosity)
306 .template initialValue<double>(x_position,
307 time_independent);
308
309 if (medium.hasProperty(MPL::PropertyType::transport_porosity))
310 {
311 std::get<TransportPorosityData>(current_state).phi =
312 medium.property(MPL::transport_porosity)
313 .template initialValue<double>(x_position,
314 time_independent);
315 }
316 else
317 {
318 std::get<TransportPorosityData>(current_state).phi =
319 std::get<PorosityData>(current_state).phi;
320 }
321 }
322
323 double const t = 0; // TODO (naumov) pass t from top
324 this->solid_material_.initializeInternalStateVariables(
325 t, x_position,
326 *this->material_states_[ip].material_state_variables);
327 }
328
329 for (unsigned ip = 0; ip < n_integration_points; ip++)
330 {
331 this->material_states_[ip].pushBackState();
332 }
333
334 for (unsigned ip = 0; ip < n_integration_points; ip++)
335 {
336 this->prev_states_[ip] = this->current_states_[ip];
337 }
338 }
339
341 double const t, double const dt, Eigen::VectorXd const& local_x,
342 Eigen::VectorXd const& local_x_prev) override;
343
344 Eigen::Map<const Eigen::RowVectorXd> getShapeMatrix(
345 const unsigned integration_point) const override
346 {
347 auto const& N_u = ip_data_[integration_point].N_u;
348
349 // assumes N is stored contiguously in memory
350 return Eigen::Map<const Eigen::RowVectorXd>(N_u.data(), N_u.size());
351 }
352
353private:
354 std::vector<IpData> ip_data_;
355
356 static constexpr auto localDOF(std::vector<double> const& x)
357 {
358 return NumLib::localDOF<
361 }
362
363 static auto block_uu(auto& mat)
364 {
365 return mat.template block<displacement_size, displacement_size>(
367 }
368 static auto block_up(auto& mat)
369 {
370 return mat.template block<displacement_size, pressure_size>(
372 }
373 static auto block_uT(auto& mat)
374 {
375 return mat.template block<displacement_size, temperature_size>(
377 }
378 static auto block_pu(auto& mat)
379 {
380 return mat.template block<pressure_size, displacement_size>(
382 }
383 static auto block_pp(auto& mat)
384 {
385 return mat.template block<pressure_size, pressure_size>(pressure_index,
387 }
388 static auto block_pT(auto& mat)
389 {
390 return mat.template block<pressure_size, temperature_size>(
392 }
393 static auto block_Tp(auto& mat)
394 {
395 return mat.template block<temperature_size, pressure_size>(
397 }
398 static auto block_TT(auto& mat)
399 {
400 return mat.template block<temperature_size, temperature_size>(
402 }
403
404 static auto block_u(auto& vec)
405 {
406 return vec.template segment<displacement_size>(displacement_index);
407 }
408 static auto block_p(auto& vec)
409 {
410 return vec.template segment<pressure_size>(pressure_index);
411 }
412 static auto block_T(auto& vec)
413 {
414 return vec.template segment<temperature_size>(temperature_index);
415 }
416
424 unsigned const ip, double const t,
425 ParameterLib::SpatialPosition const x_position,
426 MaterialPropertyLib::Medium const& medium,
427 MPL::VariableArray const& variables, double const p_at_ip);
428};
429
430} // namespace ThermoRichardsMechanics
431} // namespace ProcessLib
432
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)