OGS
ThermoRichardsMechanicsFEM.h
Go to the documentation of this file.
1
11#pragma once
12
13#include <memory>
14#include <vector>
15
20#include "NumLib/DOF/LocalDOF.h"
28
29namespace ProcessLib
30{
31namespace ThermoRichardsMechanics
32{
33namespace MPL = MaterialPropertyLib;
34
35template <typename ShapeFunctionDisplacement, typename ShapeFunction,
36 int DisplacementDim, typename ConstitutiveTraits>
38 : public LocalAssemblerInterface<DisplacementDim, ConstitutiveTraits>
39{
40 static constexpr int temperature_index = 0;
41 static constexpr int temperature_size = ShapeFunction::NPOINTS;
42 static constexpr int pressure_index = temperature_size;
43 static constexpr int pressure_size = ShapeFunction::NPOINTS;
44 static constexpr int displacement_index = 2 * ShapeFunction::NPOINTS;
45 static constexpr int displacement_size =
46 ShapeFunctionDisplacement::NPOINTS * DisplacementDim;
47
48public:
51 // Note: temperature variable uses the same shape functions as that are used
52 // by pressure variable.
55
58
62
64 ShapeMatricesType, DisplacementDim,
65 ShapeFunctionDisplacement::NPOINTS>;
66
67 static int const KelvinVectorSize =
70
71 using SymmetricTensor = Eigen::Matrix<double, KelvinVectorSize, 1>;
72
73 static constexpr auto& N_u_op = MathLib::eigenBlockMatrixView<
74 DisplacementDim,
76
81
83 MeshLib::Element const& e,
84 std::size_t const /*local_matrix_size*/,
85 NumLib::GenericIntegrationMethod const& integration_method,
86 bool const is_axially_symmetric,
88 process_data);
89
90 void setInitialConditionsConcrete(Eigen::VectorXd const local_x,
91 double const t,
92 int const process_id) override;
93
95 {
97
98 static auto constexpr local_matrix_dim =
100
101 template <Eigen::Index rows, Eigen::Index cols>
102 using Mat =
103 typename ShapeMatricesTypeDisplacement::template MatrixType<rows,
104 cols>;
105 using Vec = typename ShapeMatricesTypeDisplacement::template VectorType<
107
108 public:
109 void setZero()
110 {
111 M_TT = NodalMatrix::Zero(temperature_size, temperature_size);
112 M_Tp = NodalMatrix::Zero(temperature_size, pressure_size);
113 K_TT = NodalMatrix::Zero(temperature_size, temperature_size);
114 K_Tp = NodalMatrix::Zero(temperature_size, pressure_size);
115 dK_TT_dp = NodalMatrix::Zero(temperature_size, pressure_size);
116
119
120 M_pT = NodalMatrix::Zero(pressure_size, temperature_size);
121
122 K_pp = NodalMatrix::Zero(pressure_size, pressure_size);
123 K_pT = NodalMatrix::Zero(pressure_size, temperature_size);
124
125 storage_p_a_p = NodalMatrix::Zero(pressure_size, pressure_size);
126 storage_p_a_S_Jpp = NodalMatrix::Zero(pressure_size, pressure_size);
127 storage_p_a_S = NodalMatrix::Zero(pressure_size, pressure_size);
128
131 res = Vec::Zero(local_matrix_dim);
132 }
133
135 {
136 M_TT += other.M_TT;
137 M_Tp += other.M_Tp;
138 K_TT += other.K_TT;
139 K_Tp += other.K_Tp;
140 dK_TT_dp += other.dK_TT_dp;
141
142 M_pu += other.M_pu;
143
144 M_pT += other.M_pT;
145
146 K_pp += other.K_pp;
147 K_pT += other.K_pT;
148
152
153 Jac += other.Jac;
154 res += other.res;
155
156 return *this;
157 }
158
159 LocalMatrices& operator*=(double const a)
160 {
161 M_TT *= a;
162 M_Tp *= a;
163 K_TT *= a;
164 K_Tp *= a;
165 dK_TT_dp *= a;
166
167 M_pu *= a;
168
169 M_pT *= a;
170
171 K_pp *= a;
172 K_pT *= a;
173
174 storage_p_a_p *= a;
176 storage_p_a_S *= a;
177
178 Jac *= a;
179 res *= a;
180
181 return *this;
182 }
183
184 template <typename OStream>
185 friend OStream& operator<<(OStream& os, LocalMatrices const& loc_mat)
186 {
187 os << "- M_TT:\n"
188 << loc_mat.M_TT //
189 << "\n- M_Tp:\n"
190 << loc_mat.M_Tp //
191 << "\n- K_TT:\n"
192 << loc_mat.K_TT //
193 << "\n- K_Tp:\n"
194 << loc_mat.K_Tp //
195 << "\n- dK_TT_dp:\n"
196 << loc_mat.dK_TT_dp //
197 << "\n- M_pu:\n"
198 << loc_mat.M_pu //
199 << "\n- M_pT:\n"
200 << loc_mat.M_pT //
201 << "\n- K_pp:\n"
202 << loc_mat.K_pp //
203 << "\n- K_pT:\n"
204 << loc_mat.K_pT //
205 << "\n- storage_p_a_p:\n"
206 << loc_mat.storage_p_a_p //
207 << "\n- storage_p_a_S_Jpp:\n"
208 << loc_mat.storage_p_a_S_Jpp //
209 << "\n- storage_p_a_S:\n"
210 << loc_mat.storage_p_a_S //
211 << "\n- Jac:\n"
212 << loc_mat.Jac //
213 << "\n- res:\n"
214 << loc_mat.res;
215 return os;
216 }
217
223
225
227
230
234
238
242 };
243
244 void assembleWithJacobian(double const t, double const dt,
245 std::vector<double> const& local_x,
246 std::vector<double> const& local_x_prev,
247 std::vector<double>& /*local_M_data*/,
248 std::vector<double>& /*local_K_data*/,
249 std::vector<double>& local_rhs_data,
250 std::vector<double>& local_Jac_data) override;
251
252private:
254 double const t, double const dt,
255 ParameterLib::SpatialPosition const& x_position,
256 std::vector<double> const& local_x,
257 std::vector<double> const& local_x_prev, IpData const& ip_data,
258 typename ConstitutiveTraits::ConstitutiveSetting& CS,
260 typename ConstitutiveTraits::StatefulData& current_state,
261 typename ConstitutiveTraits::StatefulDataPrev const& prev_state,
263 typename ConstitutiveTraits::OutputData& output_data) const;
264
265 void addToLocalMatrixData(double const dt,
266 std::vector<double> const& local_x,
267 std::vector<double> const& local_x_prev,
268 LocalMatrices const& loc_mat,
269 std::vector<double>& local_rhs_data,
270 std::vector<double>& local_Jac_data) const;
271
272 void massLumping(LocalMatrices& loc_mat) const;
273
274public:
275 void initializeConcrete() override
276 {
277 unsigned const n_integration_points =
279 auto const time_independent = std::numeric_limits<double>::quiet_NaN();
280 auto const& medium =
281 *this->process_data_.media_map.getMedium(this->element_.getID());
282
283 for (unsigned ip = 0; ip < n_integration_points; ip++)
284 {
285 ParameterLib::SpatialPosition const x_position{
286 std::nullopt, this->element_.getID(), ip,
288 ShapeFunctionDisplacement,
290 this->element_, this->ip_data_[ip].N_u))};
291 auto& current_state = this->current_states_[ip];
292
293 // Set initial stress from parameter.
294 if (this->process_data_.initial_stress.value)
295 {
296 ConstitutiveTraits::ConstitutiveSetting::statefulStress(
297 current_state) =
299 DisplacementDim>(
300 (*this->process_data_.initial_stress.value)(
301 time_independent, x_position));
302 }
303
304 if (*this->process_data_.initialize_porosity_from_medium_property)
305 {
306 // Initial porosity. Could be read from integration point data
307 // or mesh.
308 std::get<PorosityData>(current_state).phi =
309 medium.property(MPL::porosity)
310 .template initialValue<double>(x_position,
311 time_independent);
312
313 if (medium.hasProperty(MPL::PropertyType::transport_porosity))
314 {
315 std::get<TransportPorosityData>(current_state).phi =
316 medium.property(MPL::transport_porosity)
317 .template initialValue<double>(x_position,
318 time_independent);
319 }
320 else
321 {
322 std::get<TransportPorosityData>(current_state).phi =
323 std::get<PorosityData>(current_state).phi;
324 }
325 }
326
327 double const t = 0; // TODO (naumov) pass t from top
328 this->solid_material_.initializeInternalStateVariables(
329 t, x_position,
330 *this->material_states_[ip].material_state_variables);
331 }
332
333 for (unsigned ip = 0; ip < n_integration_points; ip++)
334 {
335 this->material_states_[ip].pushBackState();
336 }
337
338 for (unsigned ip = 0; ip < n_integration_points; ip++)
339 {
340 this->prev_states_[ip] = this->current_states_[ip];
341 }
342 }
343
345 double const t, double const dt, Eigen::VectorXd const& local_x,
346 Eigen::VectorXd const& local_x_prev) override;
347
348 Eigen::Map<const Eigen::RowVectorXd> getShapeMatrix(
349 const unsigned integration_point) const override
350 {
351 auto const& N_u = ip_data_[integration_point].N_u;
352
353 // assumes N is stored contiguously in memory
354 return Eigen::Map<const Eigen::RowVectorXd>(N_u.data(), N_u.size());
355 }
356
357private:
358 std::vector<IpData> ip_data_;
359
360 static constexpr auto localDOF(std::vector<double> const& x)
361 {
362 return NumLib::localDOF<
363 ShapeFunction, ShapeFunction,
365 }
366
367 static auto block_uu(auto& mat)
368 {
369 return mat.template block<displacement_size, displacement_size>(
371 }
372 static auto block_up(auto& mat)
373 {
374 return mat.template block<displacement_size, pressure_size>(
376 }
377 static auto block_uT(auto& mat)
378 {
379 return mat.template block<displacement_size, temperature_size>(
381 }
382 static auto block_pu(auto& mat)
383 {
384 return mat.template block<pressure_size, displacement_size>(
386 }
387 static auto block_pp(auto& mat)
388 {
389 return mat.template block<pressure_size, pressure_size>(pressure_index,
391 }
392 static auto block_pT(auto& mat)
393 {
394 return mat.template block<pressure_size, temperature_size>(
396 }
397 static auto block_Tp(auto& mat)
398 {
399 return mat.template block<temperature_size, pressure_size>(
401 }
402 static auto block_TT(auto& mat)
403 {
404 return mat.template block<temperature_size, temperature_size>(
406 }
407
408 static auto block_u(auto& vec)
409 {
410 return vec.template segment<displacement_size>(displacement_index);
411 }
412 static auto block_p(auto& vec)
413 {
414 return vec.template segment<pressure_size>(pressure_index);
415 }
416 static auto block_T(auto& vec)
417 {
418 return vec.template segment<temperature_size>(temperature_index);
419 }
420
428 unsigned const ip, double const t,
429 ParameterLib::SpatialPosition const x_position,
430 MaterialPropertyLib::Medium const& medium,
431 MPL::VariableArray const& variables, double const p_at_ip);
432};
433
434} // namespace ThermoRichardsMechanics
435} // namespace ProcessLib
436
std::size_t getID() const
Returns the ID of the element.
Definition Element.h:89
VectorType< _kelvin_vector_size > KelvinVectorType
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
void assembleWithJacobian(double const t, double const dt, std::vector< double > const &local_x, std::vector< double > const &local_x_prev, std::vector< double > &, std::vector< double > &, std::vector< double > &local_rhs_data, std::vector< double > &local_Jac_data) override
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
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:64
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_
std::vector< typename ConstitutiveTraits::StatefulDataPrev > prev_states_
std::vector< MaterialStateData< DisplacementDim > > material_states_
ConstitutiveTraits::SolidConstitutiveRelation const & solid_material_
std::vector< typename ConstitutiveTraits::StatefulData > current_states_