OGS
HydroMechanicsLocalAssemblerMatrix-impl.h
Go to the documentation of this file.
1
11#pragma once
12
22
23namespace ProcessLib
24{
25namespace LIE
26{
27namespace HydroMechanics
28{
29template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
30 int GlobalDim>
31HydroMechanicsLocalAssemblerMatrix<ShapeFunctionDisplacement,
32 ShapeFunctionPressure, GlobalDim>::
33 HydroMechanicsLocalAssemblerMatrix(
34 MeshLib::Element const& e,
35 std::size_t const n_variables,
36 std::size_t const /*local_matrix_size*/,
37 std::vector<unsigned> const& dofIndex_to_localIndex,
38 NumLib::GenericIntegrationMethod const& integration_method,
39 bool const is_axially_symmetric,
42 e, is_axially_symmetric, integration_method,
43 (n_variables - 1) * ShapeFunctionDisplacement::NPOINTS * GlobalDim +
44 ShapeFunctionPressure::NPOINTS,
45 dofIndex_to_localIndex),
46 _process_data(process_data)
47{
48 unsigned const n_integration_points =
49 integration_method.getNumberOfPoints();
50
51 _ip_data.reserve(n_integration_points);
52 _secondary_data.N.resize(n_integration_points);
53
54 auto const shape_matrices_u =
55 NumLib::initShapeMatrices<ShapeFunctionDisplacement,
57 e, is_axially_symmetric, integration_method);
58
59 auto const shape_matrices_p =
60 NumLib::initShapeMatrices<ShapeFunctionPressure,
61 ShapeMatricesTypePressure, GlobalDim>(
62 e, is_axially_symmetric, integration_method);
63
65 _process_data.solid_materials, _process_data.material_ids, e.getID());
66
68 x_position.setElementID(e.getID());
69 for (unsigned ip = 0; ip < n_integration_points; ip++)
70 {
71 x_position.setIntegrationPoint(ip);
72
73 _ip_data.emplace_back(solid_material);
74 auto& ip_data = _ip_data[ip];
75 auto const& sm_u = shape_matrices_u[ip];
76 auto const& sm_p = shape_matrices_p[ip];
77
78 ip_data.integration_weight =
79 sm_u.detJ * sm_u.integralMeasure *
80 integration_method.getWeightedPoint(ip).getWeight();
81 ip_data.darcy_velocity.setZero();
82
83 ip_data.N_u = sm_u.N;
84 ip_data.dNdx_u = sm_u.dNdx;
85 ip_data.H_u.setZero(GlobalDim, displacement_size);
86 for (int i = 0; i < GlobalDim; ++i)
87 {
88 ip_data.H_u
89 .template block<1, displacement_size / GlobalDim>(
90 i, i * displacement_size / GlobalDim)
91 .noalias() = ip_data.N_u;
92 }
93
94 ip_data.N_p = sm_p.N;
95 ip_data.dNdx_p = sm_p.dNdx;
96
97 _secondary_data.N[ip] = sm_u.N;
98
99 ip_data.sigma_eff.setZero(kelvin_vector_size);
100 ip_data.eps.setZero(kelvin_vector_size);
101
102 ip_data.sigma_eff_prev.resize(kelvin_vector_size);
103 ip_data.eps_prev.resize(kelvin_vector_size);
104 ip_data.C.resize(kelvin_vector_size, kelvin_vector_size);
105
106 auto const initial_effective_stress =
107 _process_data.initial_effective_stress(0, x_position);
108 for (unsigned i = 0; i < kelvin_vector_size; i++)
109 {
110 ip_data.sigma_eff[i] = initial_effective_stress[i];
111 ip_data.sigma_eff_prev[i] = initial_effective_stress[i];
112 }
113 }
114}
115
116template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
117 int GlobalDim>
118void HydroMechanicsLocalAssemblerMatrix<ShapeFunctionDisplacement,
119 ShapeFunctionPressure, GlobalDim>::
120 assembleWithJacobianConcrete(double const t, double const dt,
121 Eigen::VectorXd const& local_x,
122 Eigen::VectorXd const& local_x_prev,
123 Eigen::VectorXd& local_rhs,
124 Eigen::MatrixXd& local_Jac)
125{
126 auto p = const_cast<Eigen::VectorXd&>(local_x).segment(pressure_index,
127 pressure_size);
128 auto p_prev = const_cast<Eigen::VectorXd&>(local_x_prev)
129 .segment(pressure_index, pressure_size);
130
131 if (_process_data.deactivate_matrix_in_flow)
132 {
133 setPressureOfInactiveNodes(t, p);
134 }
135
136 auto u = local_x.segment(displacement_index, displacement_size);
137 auto u_prev = local_x_prev.segment(displacement_index, displacement_size);
138
139 auto rhs_p = local_rhs.template segment<pressure_size>(pressure_index);
140 auto rhs_u =
141 local_rhs.template segment<displacement_size>(displacement_index);
142
143 auto J_pp = local_Jac.template block<pressure_size, pressure_size>(
144 pressure_index, pressure_index);
145 auto J_pu = local_Jac.template block<pressure_size, displacement_size>(
146 pressure_index, displacement_index);
147 auto J_uu = local_Jac.template block<displacement_size, displacement_size>(
148 displacement_index, displacement_index);
149 auto J_up = local_Jac.template block<displacement_size, pressure_size>(
150 displacement_index, pressure_index);
151
152 assembleBlockMatricesWithJacobian(t, dt, p, p_prev, u, u_prev, rhs_p, rhs_u,
153 J_pp, J_pu, J_uu, J_up);
154}
155
156template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
157 int GlobalDim>
158void HydroMechanicsLocalAssemblerMatrix<ShapeFunctionDisplacement,
159 ShapeFunctionPressure, GlobalDim>::
160 assembleBlockMatricesWithJacobian(
161 double const t, double const dt,
162 Eigen::Ref<const Eigen::VectorXd> const& p,
163 Eigen::Ref<const Eigen::VectorXd> const& p_prev,
164 Eigen::Ref<const Eigen::VectorXd> const& u,
165 Eigen::Ref<const Eigen::VectorXd> const& u_prev,
166 Eigen::Ref<Eigen::VectorXd> rhs_p, Eigen::Ref<Eigen::VectorXd> rhs_u,
167 Eigen::Ref<Eigen::MatrixXd> J_pp, Eigen::Ref<Eigen::MatrixXd> J_pu,
168 Eigen::Ref<Eigen::MatrixXd> J_uu, Eigen::Ref<Eigen::MatrixXd> J_up)
169{
170 assert(this->_element.getDimension() == GlobalDim);
171
173 ShapeMatricesTypePressure::NodalMatrixType::Zero(pressure_size,
174 pressure_size);
175
177 ShapeMatricesTypePressure::NodalMatrixType::Zero(pressure_size,
178 pressure_size);
179
180 typename ShapeMatricesTypeDisplacement::template MatrixType<
181 displacement_size, pressure_size>
182 Kup = ShapeMatricesTypeDisplacement::template MatrixType<
183 displacement_size, pressure_size>::Zero(displacement_size,
184 pressure_size);
185
186 auto const& gravity_vec = _process_data.specific_body_force;
187
188 MPL::VariableArray variables;
189 MPL::VariableArray variables_prev;
191 x_position.setElementID(_element.getID());
192
193 auto const B_dil_bar = getDilatationalBBarMatrix();
194
195 unsigned const n_integration_points = _ip_data.size();
196 for (unsigned ip = 0; ip < n_integration_points; ip++)
197 {
198 x_position.setIntegrationPoint(ip);
199
200 auto& ip_data = _ip_data[ip];
201 auto const& ip_w = ip_data.integration_weight;
202 auto const& N_u = ip_data.N_u;
203 auto const& dNdx_u = ip_data.dNdx_u;
204 auto const& N_p = ip_data.N_p;
205 auto const& dNdx_p = ip_data.dNdx_p;
206 auto const& H_u = ip_data.H_u;
207
208 auto const x_coord =
209 NumLib::interpolateXCoordinate<ShapeFunctionDisplacement,
211 _element, N_u);
213 GlobalDim, ShapeFunctionDisplacement::NPOINTS, BBarMatrixType,
215 dNdx_u, N_u, B_dil_bar, x_coord, this->_is_axially_symmetric);
216
217 auto const& eps_prev = ip_data.eps_prev;
218 auto const& sigma_eff_prev = ip_data.sigma_eff_prev;
219 auto& sigma_eff = ip_data.sigma_eff;
220
221 auto& eps = ip_data.eps;
222 auto& state = ip_data.material_state_variables;
223
224 auto const alpha = _process_data.biot_coefficient(t, x_position)[0];
225 auto const rho_sr = _process_data.solid_density(t, x_position)[0];
226 auto const rho_fr = _process_data.fluid_density(t, x_position)[0];
227 auto const porosity = _process_data.porosity(t, x_position)[0];
228
229 double const rho = rho_sr * (1 - porosity) + porosity * rho_fr;
230 auto const& identity2 =
232
233 eps.noalias() = B * u;
234
235 variables.mechanical_strain
237
238 variables_prev.stress
240 sigma_eff_prev);
241 variables_prev.mechanical_strain
243 eps_prev);
244 variables_prev.temperature = _process_data.reference_temperature;
245
246 auto&& solution = _ip_data[ip].solid_material.integrateStress(
247 variables_prev, variables, t, x_position, dt, *state);
248
249 if (!solution)
250 {
251 OGS_FATAL("Computation of local constitutive relation failed.");
252 }
253
255 std::tie(sigma_eff, state, C) = std::move(*solution);
256
257 J_uu.noalias() += B.transpose() * C * B * ip_w;
258
259 rhs_u.noalias() -= B.transpose() * sigma_eff * ip_w;
260 rhs_u.noalias() -= -H_u.transpose() * rho * gravity_vec * ip_w;
261
262 //
263 // pressure equation, pressure part and displacement equation, pressure
264 // part
265 //
266 if (!_process_data.deactivate_matrix_in_flow) // Only for hydraulically
267 // active matrix
268 {
269 Kup.noalias() += B.transpose() * alpha * identity2 * N_p * ip_w;
270
271 double const k_over_mu =
272 _process_data.intrinsic_permeability(t, x_position)[0] /
273 _process_data.fluid_viscosity(t, x_position)[0];
274 double const S = _process_data.specific_storage(t, x_position)[0];
275
276 auto q = ip_data.darcy_velocity.head(GlobalDim);
277 q.noalias() = -k_over_mu * (dNdx_p * p + rho_fr * gravity_vec);
278
279 laplace_p.noalias() +=
280 dNdx_p.transpose() * k_over_mu * dNdx_p * ip_w;
281 storage_p.noalias() += N_p.transpose() * S * N_p * ip_w;
282
283 rhs_p.noalias() +=
284 dNdx_p.transpose() * rho_fr * k_over_mu * gravity_vec * ip_w;
285 }
286 }
287
288 // displacement equation, pressure part
289 J_up.noalias() -= Kup;
290
291 // pressure equation, pressure part.
292 J_pp.noalias() += laplace_p + storage_p / dt;
293
294 // pressure equation, displacement part.
295 J_pu.noalias() += Kup.transpose() / dt;
296
297 // pressure equation
298 rhs_p.noalias() -= laplace_p * p + storage_p * (p - p_prev) / dt +
299 Kup.transpose() * (u - u_prev) / dt;
300
301 // displacement equation
302 rhs_u.noalias() -= -Kup * p;
303}
304
305template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
306 int GlobalDim>
308 ShapeFunctionDisplacement, ShapeFunctionPressure,
309 GlobalDim>::postTimestepConcreteWithVector(double const t, double const dt,
310 Eigen::VectorXd const& local_x)
311{
312 auto p = const_cast<Eigen::VectorXd&>(local_x).segment(pressure_index,
313 pressure_size);
314 if (_process_data.deactivate_matrix_in_flow)
315 {
316 setPressureOfInactiveNodes(t, p);
317 }
318 auto u = local_x.segment(displacement_index, displacement_size);
319
320 postTimestepConcreteWithBlockVectors(t, dt, p, u);
321}
322
323template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
324 int GlobalDim>
325void HydroMechanicsLocalAssemblerMatrix<ShapeFunctionDisplacement,
326 ShapeFunctionPressure, GlobalDim>::
327 postTimestepConcreteWithBlockVectors(
328 double const t, double const dt,
329 Eigen::Ref<const Eigen::VectorXd> const& p,
330 Eigen::Ref<const Eigen::VectorXd> const& u)
331{
332 MPL::VariableArray variables;
333 MPL::VariableArray variables_prev;
335
336 auto const e_id = _element.getID();
337 x_position.setElementID(e_id);
338
340 KV sigma_avg = KV::Zero();
341 GlobalDimVector velocity_avg;
342 velocity_avg.setZero();
343
344 unsigned const n_integration_points = _ip_data.size();
345 auto const B_dil_bar = getDilatationalBBarMatrix();
346
347 for (unsigned ip = 0; ip < n_integration_points; ip++)
348 {
349 x_position.setIntegrationPoint(ip);
350
351 auto& ip_data = _ip_data[ip];
352
353 auto const& eps_prev = ip_data.eps_prev;
354 auto const& sigma_eff_prev = ip_data.sigma_eff_prev;
355
356 auto& eps = ip_data.eps;
357 auto& sigma_eff = ip_data.sigma_eff;
358 auto& state = ip_data.material_state_variables;
359
360 auto const& N_u = ip_data.N_u;
361 auto const& dNdx_u = ip_data.dNdx_u;
362
363 auto const x_coord =
364 NumLib::interpolateXCoordinate<ShapeFunctionDisplacement,
366 _element, N_u);
368 GlobalDim, ShapeFunctionDisplacement::NPOINTS, BBarMatrixType,
370 dNdx_u, N_u, B_dil_bar, x_coord, this->_is_axially_symmetric);
371
372 eps.noalias() = B * u;
373
374 variables.mechanical_strain
376
377 variables_prev.stress
379 sigma_eff_prev);
380 variables_prev.mechanical_strain
382 eps_prev);
383 variables_prev.temperature = _process_data.reference_temperature;
384
385 auto&& solution = _ip_data[ip].solid_material.integrateStress(
386 variables_prev, variables, t, x_position, dt, *state);
387
388 if (!solution)
389 {
390 OGS_FATAL("Computation of local constitutive relation failed.");
391 }
392
394 std::tie(sigma_eff, state, C) = std::move(*solution);
395
396 sigma_avg += ip_data.sigma_eff;
397
398 if (!_process_data.deactivate_matrix_in_flow) // Only for hydraulically
399 // active matrix
400 {
401 double const k_over_mu =
402 _process_data.intrinsic_permeability(t, x_position)[0] /
403 _process_data.fluid_viscosity(t, x_position)[0];
404 auto const rho_fr = _process_data.fluid_density(t, x_position)[0];
405 auto const& gravity_vec = _process_data.specific_body_force;
406 auto const& dNdx_p = ip_data.dNdx_p;
407
408 ip_data.darcy_velocity.head(GlobalDim).noalias() =
409 -k_over_mu * (dNdx_p * p + rho_fr * gravity_vec);
410 velocity_avg += ip_data.darcy_velocity.head(GlobalDim);
411 }
412 }
413
414 sigma_avg /= n_integration_points;
415 velocity_avg /= n_integration_points;
416
417 Eigen::Map<KV>(
418 &(*_process_data.element_stresses)[e_id * KV::RowsAtCompileTime]) =
420
421 Eigen::Map<GlobalDimVector>(
422 &(*_process_data.element_velocities)[e_id * GlobalDim]) = velocity_avg;
423
425 ShapeFunctionPressure, typename ShapeFunctionDisplacement::MeshElement,
426 GlobalDim>(_element, _is_axially_symmetric, p,
427 *_process_data.mesh_prop_nodal_p);
428}
429
430template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
431 int GlobalDim>
432void HydroMechanicsLocalAssemblerMatrix<ShapeFunctionDisplacement,
433 ShapeFunctionPressure, GlobalDim>::
434 setPressureOfInactiveNodes(double const t, Eigen::Ref<Eigen::VectorXd> p)
435{
437 x_position.setElementID(_element.getID());
438 for (unsigned i = 0; i < pressure_size; i++)
439 {
440 // only inactive nodes
441 if (_process_data.p_element_status->isActiveNode(_element.getNode(i)))
442 {
443 continue;
444 }
445 x_position.setNodeID(getNodeIndex(_element, i));
446 auto const p0 = (*_process_data.p0)(t, x_position)[0];
447 p[i] = p0;
448 }
449}
450
451template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
452 int GlobalDim>
453std::vector<double> const& HydroMechanicsLocalAssemblerMatrix<
454 ShapeFunctionDisplacement, ShapeFunctionPressure, GlobalDim>::
455 getIntPtSigma(
456 const double /*t*/,
457 std::vector<GlobalVector*> const& /*x*/,
458 std::vector<NumLib::LocalToGlobalIndexMap const*> const& /*dof_table*/,
459 std::vector<double>& cache) const
460{
462 _ip_data, &IntegrationPointDataType::sigma_eff, cache);
463}
464template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
465 int GlobalDim>
466std::vector<double> const& HydroMechanicsLocalAssemblerMatrix<
467 ShapeFunctionDisplacement, ShapeFunctionPressure, GlobalDim>::
468 getIntPtEpsilon(
469 const double /*t*/,
470 std::vector<GlobalVector*> const& /*x*/,
471 std::vector<NumLib::LocalToGlobalIndexMap const*> const& /*dof_table*/,
472 std::vector<double>& cache) const
473{
475 _ip_data, &IntegrationPointDataType::eps, cache);
476}
477
478template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
479 int GlobalDim>
480std::vector<double> const& HydroMechanicsLocalAssemblerMatrix<
481 ShapeFunctionDisplacement, ShapeFunctionPressure, GlobalDim>::
482 getIntPtDarcyVelocity(
483 const double /*t*/,
484 std::vector<GlobalVector*> const& /*x*/,
485 std::vector<NumLib::LocalToGlobalIndexMap const*> const& /*dof_table*/,
486 std::vector<double>& cache) const
487{
488 unsigned const n_integration_points = _ip_data.size();
489
490 cache.clear();
491 auto cache_matrix = MathLib::createZeroedMatrix<
492 Eigen::Matrix<double, GlobalDim, Eigen::Dynamic, Eigen::RowMajor>>(
493 cache, GlobalDim, n_integration_points);
494
495 for (unsigned ip = 0; ip < n_integration_points; ip++)
496 {
497 cache_matrix.col(ip).noalias() = _ip_data[ip].darcy_velocity;
498 }
499
500 return cache;
501}
502} // namespace HydroMechanics
503} // namespace LIE
504} // namespace ProcessLib
Definition of the ElementStatus class.
#define OGS_FATAL(...)
Definition Error.h:26
double getWeight() const
std::size_t getID() const
Returns the ID of the element.
Definition Element.h:89
MathLib::WeightedPoint const & getWeightedPoint(unsigned const igp) const
void setNodeID(std::size_t node_id)
void setElementID(std::size_t element_id)
void setIntegrationPoint(unsigned integration_point)
MatrixType< _kelvin_vector_size, _number_of_dof > BMatrixType
ShapeMatrixPolicyType< ShapeFunctionDisplacement, GlobalDim > ShapeMatricesTypeDisplacement
SecondaryData< typename ShapeMatricesTypeDisplacement::ShapeMatrices::ShapeType > _secondary_data
std::vector< IntegrationPointDataType, Eigen::aligned_allocator< IntegrationPointDataType > > _ip_data
ShapeMatrixPolicyType< ShapeFunctionPressure, GlobalDim > ShapeMatricesTypePressure
auto & selectSolidConstitutiveRelation(SolidMaterialsMap const &constitutive_relations, MeshLib::PropertyVector< int > const *const material_ids, std::size_t const element_id)
Eigen::Matrix< double, 4, 1 > kelvinVectorToSymmetricTensor(Eigen::Matrix< double, 4, 1, Eigen::ColMajor, 4, 1 > const &v)
Eigen::Matrix< double, kelvin_vector_dimensions(DisplacementDim), 1, Eigen::ColMajor > KelvinVectorType
Eigen::Matrix< double, kelvin_vector_dimensions(DisplacementDim), kelvin_vector_dimensions(DisplacementDim), Eigen::RowMajor > KelvinMatrixType
Eigen::Map< Matrix > createZeroedMatrix(std::vector< double > &data, Eigen::MatrixXd::Index rows, Eigen::MatrixXd::Index cols)
double interpolateXCoordinate(MeshLib::Element const &e, typename ShapeMatricesType::ShapeMatrices::ShapeType const &N)
void interpolateToHigherOrderNodes(MeshLib::Element const &element, bool const is_axially_symmetric, Eigen::MatrixBase< EigenMatrixType > const &node_values, MeshLib::PropertyVector< double > &interpolated_values_global_vector)
std::vector< typename ShapeMatricesType::ShapeMatrices, Eigen::aligned_allocator< typename ShapeMatricesType::ShapeMatrices > > initShapeMatrices(MeshLib::Element const &e, bool const is_axially_symmetric, IntegrationMethod const &integration_method)
BMatrixType computeBMatrixPossiblyWithBbar(DNDX_Type const &dNdx, N_Type const &N, std::optional< BBarMatrixType > const &B_dil_bar, const double radius, const bool is_axially_symmetric)
Fills a B matrix, or a B bar matrix if required.
std::vector< double > const & getIntegrationPointKelvinVectorData(IntegrationPointDataVector const &ip_data_vector, MemberType IpData::*const member, std::vector< double > &cache)
MatrixType< ShapeFunction::NPOINTS, ShapeFunction::NPOINTS > NodalMatrixType
std::vector< ShapeMatrixType, Eigen::aligned_allocator< ShapeMatrixType > > N