Loading [MathJax]/extensions/tex2jax.js
OGS
RichardsMechanicsFEM-impl.h
Go to the documentation of this file.
1
12#pragma once
13
14#include <Eigen/LU>
15#include <cassert>
16
29
30namespace ProcessLib
31{
32namespace RichardsMechanics
33{
34template <int DisplacementDim>
36 MaterialPropertyLib::Medium const& medium,
37 MaterialPropertyLib::Phase const& solid_phase,
39 double const rho_LR, double const mu,
40 std::optional<MicroPorosityParameters> micro_porosity_parameters,
41 double const alpha, double const phi, double const p_cap_ip,
42 MPL::VariableArray& variables, MPL::VariableArray& variables_prev,
43 ParameterLib::SpatialPosition const& x_position, double const t,
44 double const dt,
46 SwellingDataStateful<DisplacementDim>& sigma_sw,
48 ConstitutiveStress_StrainTemperature::SwellingDataStateful<
49 DisplacementDim>> const& sigma_sw_prev,
51 phi_M_prev,
54 PrevState<MicroPressure> const p_L_m_prev,
55 PrevState<MicroSaturation> const S_L_m_prev, MicroPressure& p_L_m,
56 MicroSaturation& S_L_m)
57{
58 auto const& identity2 = MathLib::KelvinVector::Invariants<
60 DisplacementDim)>::identity2;
61
62 if (!medium.hasProperty(MPL::PropertyType::saturation_micro))
63 {
64 // If there is swelling, compute it. Update volumetric strain rate,
65 // s.t. it corresponds to the mechanical part only.
66 sigma_sw = *sigma_sw_prev;
67 if (solid_phase.hasProperty(MPL::PropertyType::swelling_stress_rate))
68 {
69 auto const sigma_sw_dot =
72 solid_phase[MPL::PropertyType::swelling_stress_rate]
73 .value(variables, variables_prev, x_position, t,
74 dt)));
75 sigma_sw.sigma_sw += sigma_sw_dot * dt;
76
78 variables.volumetric_strain +
79 identity2.transpose() * C_el.inverse() * sigma_sw.sigma_sw;
80 variables_prev.volumetric_mechanical_strain =
81 variables_prev.volumetric_strain + identity2.transpose() *
82 C_el.inverse() *
83 sigma_sw_prev->sigma_sw;
84 }
85 else
86 {
88 variables.volumetric_strain;
89 variables_prev.volumetric_mechanical_strain =
90 variables_prev.volumetric_strain;
91 }
92 }
93
94 // TODO (naumov) saturation_micro must be always defined together with
95 // the micro_porosity_parameters.
96 if (medium.hasProperty(MPL::PropertyType::saturation_micro))
97 {
98 double const phi_m_prev = phi_prev->phi - phi_M_prev->phi;
99
100 auto const [delta_phi_m, delta_e_sw, delta_p_L_m, delta_sigma_sw] =
102 identity2.transpose() * C_el.inverse(), rho_LR, mu,
103 *micro_porosity_parameters, alpha, phi, -p_cap_ip, **p_L_m_prev,
104 variables_prev, **S_L_m_prev, phi_m_prev, x_position, t, dt,
105 medium.property(MPL::PropertyType::saturation_micro),
106 solid_phase.property(MPL::PropertyType::swelling_stress_rate));
107
108 phi_M.phi = phi - (phi_m_prev + delta_phi_m);
109 variables_prev.transport_porosity = phi_M_prev->phi;
110 variables.transport_porosity = phi_M.phi;
111
112 *p_L_m = **p_L_m_prev + delta_p_L_m;
113 { // Update micro saturation.
114 MPL::VariableArray variables_prev;
115 variables_prev.capillary_pressure = -**p_L_m_prev;
116 MPL::VariableArray variables;
117 variables.capillary_pressure = -*p_L_m;
118
119 *S_L_m = medium.property(MPL::PropertyType::saturation_micro)
120 .template value<double>(variables, x_position, t, dt);
121 }
122 sigma_sw.sigma_sw = sigma_sw_prev->sigma_sw + delta_sigma_sw;
123 }
124}
125
126template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
127 int DisplacementDim>
128RichardsMechanicsLocalAssembler<ShapeFunctionDisplacement,
129 ShapeFunctionPressure, DisplacementDim>::
130 RichardsMechanicsLocalAssembler(
131 MeshLib::Element const& e,
132 std::size_t const /*local_matrix_size*/,
133 NumLib::GenericIntegrationMethod const& integration_method,
134 bool const is_axially_symmetric,
136 : LocalAssemblerInterface<DisplacementDim>{
137 e, integration_method, is_axially_symmetric, process_data}
138{
139 unsigned const n_integration_points =
140 this->integration_method_.getNumberOfPoints();
141
142 _ip_data.resize(n_integration_points);
143 _secondary_data.N_u.resize(n_integration_points);
144
145 auto const shape_matrices_u =
146 NumLib::initShapeMatrices<ShapeFunctionDisplacement,
147 ShapeMatricesTypeDisplacement,
148 DisplacementDim>(e, is_axially_symmetric,
149 this->integration_method_);
150
151 auto const shape_matrices_p =
152 NumLib::initShapeMatrices<ShapeFunctionPressure,
153 ShapeMatricesTypePressure, DisplacementDim>(
154 e, is_axially_symmetric, this->integration_method_);
155
156 auto const& medium =
157 this->process_data_.media_map.getMedium(this->element_.getID());
158
160 x_position.setElementID(this->element_.getID());
161 for (unsigned ip = 0; ip < n_integration_points; ip++)
162 {
163 auto& ip_data = _ip_data[ip];
164 auto const& sm_u = shape_matrices_u[ip];
165 _ip_data[ip].integration_weight =
166 this->integration_method_.getWeightedPoint(ip).getWeight() *
167 sm_u.integralMeasure * sm_u.detJ;
168
169 ip_data.N_u = sm_u.N;
170 ip_data.dNdx_u = sm_u.dNdx;
171
172 ip_data.N_p = shape_matrices_p[ip].N;
173 ip_data.dNdx_p = shape_matrices_p[ip].dNdx;
174
175 // Initial porosity. Could be read from integration point data or mesh.
176 auto& porosity =
177 std::get<ProcessLib::ThermoRichardsMechanics::PorosityData>(
178 this->current_states_[ip])
179 .phi;
180 porosity = medium->property(MPL::porosity)
181 .template initialValue<double>(
182 x_position,
183 std::numeric_limits<
184 double>::quiet_NaN() /* t independent */);
185
186 auto& transport_porosity =
187 std::get<
189 this->current_states_[ip])
190 .phi;
191 transport_porosity = porosity;
192 if (medium->hasProperty(MPL::PropertyType::transport_porosity))
193 {
194 transport_porosity =
195 medium->property(MPL::transport_porosity)
196 .template initialValue<double>(
197 x_position,
198 std::numeric_limits<
199 double>::quiet_NaN() /* t independent */);
200 }
201
202 _secondary_data.N_u[ip] = shape_matrices_u[ip].N;
203 }
204}
205
206template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
207 int DisplacementDim>
208void RichardsMechanicsLocalAssembler<ShapeFunctionDisplacement,
209 ShapeFunctionPressure, DisplacementDim>::
210 setInitialConditionsConcrete(Eigen::VectorXd const local_x,
211 double const t,
212 int const /*process_id*/)
213{
214 assert(local_x.size() == pressure_size + displacement_size);
215
216 auto const [p_L, u] = localDOF(local_x);
217
218 constexpr double dt = std::numeric_limits<double>::quiet_NaN();
219 auto const& medium =
220 this->process_data_.media_map.getMedium(this->element_.getID());
221 MPL::VariableArray variables;
222
224 x_position.setElementID(this->element_.getID());
225
226 auto const& solid_phase = medium->phase("Solid");
227
228 auto const& identity2 = MathLib::KelvinVector::Invariants<
230 DisplacementDim)>::identity2;
231
232 unsigned const n_integration_points =
233 this->integration_method_.getNumberOfPoints();
234 for (unsigned ip = 0; ip < n_integration_points; ip++)
235 {
236 auto const& N_p = _ip_data[ip].N_p;
237
238 double p_cap_ip;
239 NumLib::shapeFunctionInterpolate(-p_L, N_p, p_cap_ip);
240
241 variables.capillary_pressure = p_cap_ip;
242 variables.liquid_phase_pressure = -p_cap_ip;
243 // setting pG to 1 atm
244 // TODO : rewrite equations s.t. p_L = pG-p_cap
245 variables.gas_phase_pressure = 1.0e5;
246
247 {
248 auto& p_L_m = std::get<MicroPressure>(this->current_states_[ip]);
249 auto& p_L_m_prev =
250 std::get<PrevState<MicroPressure>>(this->prev_states_[ip]);
251 **p_L_m_prev = -p_cap_ip;
252 *p_L_m = -p_cap_ip;
253 }
254
255 auto const temperature =
256 medium->property(MPL::PropertyType::reference_temperature)
257 .template value<double>(variables, x_position, t, dt);
258 variables.temperature = temperature;
259
260 auto& S_L_prev =
261 std::get<
263 this->prev_states_[ip])
264 ->S_L;
265 S_L_prev = medium->property(MPL::PropertyType::saturation)
266 .template value<double>(variables, x_position, t, dt);
267
268 if (this->process_data_.initial_stress.isTotalStress())
269 {
270 auto const alpha_b =
271 medium->property(MPL::PropertyType::biot_coefficient)
272 .template value<double>(variables, x_position, t, dt);
273
274 variables.liquid_saturation = S_L_prev;
275 double const chi_S_L =
276 medium->property(MPL::PropertyType::bishops_effective_stress)
277 .template value<double>(variables, x_position, t, dt);
278
279 // Initial stresses are total stress, which were assigned to
280 // sigma_eff in
281 // RichardsMechanicsLocalAssembler::initializeConcrete().
282 auto& sigma_eff =
284 DisplacementDim>>(this->current_states_[ip]);
285
286 auto& sigma_eff_prev =
287 std::get<PrevState<ProcessLib::ConstitutiveRelations::
288 EffectiveStressData<DisplacementDim>>>(
289 this->prev_states_[ip]);
290
291 // Reset sigma_eff to effective stress
292 sigma_eff.sigma_eff.noalias() +=
293 chi_S_L * alpha_b * (-p_cap_ip) * identity2;
294 sigma_eff_prev->sigma_eff = sigma_eff.sigma_eff;
295 }
296
297 if (medium->hasProperty(MPL::PropertyType::saturation_micro))
298 {
300 vars.capillary_pressure = p_cap_ip;
301
302 auto& S_L_m = std::get<MicroSaturation>(this->current_states_[ip]);
303 auto& S_L_m_prev =
304 std::get<PrevState<MicroSaturation>>(this->prev_states_[ip]);
305
306 *S_L_m = medium->property(MPL::PropertyType::saturation_micro)
307 .template value<double>(vars, x_position, t, dt);
308 *S_L_m_prev = S_L_m;
309 }
310
311 // Set eps_m_prev from potentially non-zero eps and sigma_sw from
312 // restart.
313 auto const C_el = _ip_data[ip].computeElasticTangentStiffness(
314 t, x_position, dt, temperature, this->solid_material_,
315 *this->material_states_[ip].material_state_variables);
316
317 auto const& N_u = _ip_data[ip].N_u;
318 auto const& dNdx_u = _ip_data[ip].dNdx_u;
319 auto const x_coord =
320 NumLib::interpolateXCoordinate<ShapeFunctionDisplacement,
322 this->element_, N_u);
323 auto const B =
324 LinearBMatrix::computeBMatrix<DisplacementDim,
325 ShapeFunctionDisplacement::NPOINTS,
327 dNdx_u, N_u, x_coord, this->is_axially_symmetric_);
328 auto& eps =
329 std::get<StrainData<DisplacementDim>>(this->current_states_[ip])
330 .eps;
331 eps.noalias() = B * u;
332
333 auto const& sigma_sw =
334 std::get<ProcessLib::ThermoRichardsMechanics::
335 ConstitutiveStress_StrainTemperature::
336 SwellingDataStateful<DisplacementDim>>(
337 this->current_states_[ip])
338 .sigma_sw;
339 auto& eps_m_prev =
340 std::get<PrevState<ProcessLib::ConstitutiveRelations::
341 MechanicalStrainData<DisplacementDim>>>(
342 this->prev_states_[ip])
343 ->eps_m;
344
345 eps_m_prev.noalias() =
346 solid_phase.hasProperty(MPL::PropertyType::swelling_stress_rate)
347 ? eps + C_el.inverse() * sigma_sw
348 : eps;
349 }
350}
351
352template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
353 int DisplacementDim>
355 ShapeFunctionDisplacement, ShapeFunctionPressure,
356 DisplacementDim>::assemble(double const t, double const dt,
357 std::vector<double> const& local_x,
358 std::vector<double> const& local_x_prev,
359 std::vector<double>& local_M_data,
360 std::vector<double>& local_K_data,
361 std::vector<double>& local_rhs_data)
362{
363 assert(local_x.size() == pressure_size + displacement_size);
364
365 auto const [p_L, u] = localDOF(local_x);
366 auto const [p_L_prev, u_prev] = localDOF(local_x_prev);
367
369 typename ShapeMatricesTypeDisplacement::template MatrixType<
370 displacement_size + pressure_size,
371 displacement_size + pressure_size>>(
372 local_K_data, displacement_size + pressure_size,
373 displacement_size + pressure_size);
374
376 typename ShapeMatricesTypeDisplacement::template MatrixType<
377 displacement_size + pressure_size,
378 displacement_size + pressure_size>>(
379 local_M_data, displacement_size + pressure_size,
380 displacement_size + pressure_size);
381
383 typename ShapeMatricesTypeDisplacement::template VectorType<
384 displacement_size + pressure_size>>(
385 local_rhs_data, displacement_size + pressure_size);
386
387 auto const& identity2 = MathLib::KelvinVector::Invariants<
389 DisplacementDim)>::identity2;
390
391 auto const& medium =
392 this->process_data_.media_map.getMedium(this->element_.getID());
393 auto const& liquid_phase = medium->phase("AqueousLiquid");
394 auto const& solid_phase = medium->phase("Solid");
395 MPL::VariableArray variables;
396 MPL::VariableArray variables_prev;
397
399 x_position.setElementID(this->element_.getID());
400
401 unsigned const n_integration_points =
402 this->integration_method_.getNumberOfPoints();
403 for (unsigned ip = 0; ip < n_integration_points; ip++)
404 {
405 auto const& w = _ip_data[ip].integration_weight;
406
407 auto const& N_u = _ip_data[ip].N_u;
408 auto const& dNdx_u = _ip_data[ip].dNdx_u;
409
410 auto const& N_p = _ip_data[ip].N_p;
411 auto const& dNdx_p = _ip_data[ip].dNdx_p;
412
413 auto const x_coord =
414 NumLib::interpolateXCoordinate<ShapeFunctionDisplacement,
416 this->element_, N_u);
417 auto const B =
418 LinearBMatrix::computeBMatrix<DisplacementDim,
419 ShapeFunctionDisplacement::NPOINTS,
421 dNdx_u, N_u, x_coord, this->is_axially_symmetric_);
422
423 auto& eps =
424 std::get<StrainData<DisplacementDim>>(this->current_states_[ip]);
425 eps.eps.noalias() = B * u;
426
427 auto& S_L =
428 std::get<ProcessLib::ThermoRichardsMechanics::SaturationData>(
429 this->current_states_[ip])
430 .S_L;
431 auto const S_L_prev =
432 std::get<
434 this->prev_states_[ip])
435 ->S_L;
436
437 double p_cap_ip;
438 NumLib::shapeFunctionInterpolate(-p_L, N_p, p_cap_ip);
439
440 double p_cap_prev_ip;
441 NumLib::shapeFunctionInterpolate(-p_L_prev, N_p, p_cap_prev_ip);
442
443 variables.capillary_pressure = p_cap_ip;
444 variables.liquid_phase_pressure = -p_cap_ip;
445 // setting pG to 1 atm
446 // TODO : rewrite equations s.t. p_L = pG-p_cap
447 variables.gas_phase_pressure = 1.0e5;
448
449 auto const temperature =
450 medium->property(MPL::PropertyType::reference_temperature)
451 .template value<double>(variables, x_position, t, dt);
452 variables.temperature = temperature;
453
454 auto const alpha =
455 medium->property(MPL::PropertyType::biot_coefficient)
456 .template value<double>(variables, x_position, t, dt);
457 auto const C_el = _ip_data[ip].computeElasticTangentStiffness(
458 t, x_position, dt, temperature, this->solid_material_,
459 *this->material_states_[ip].material_state_variables);
460
461 auto const beta_SR = (1 - alpha) / this->solid_material_.getBulkModulus(
462 t, x_position, &C_el);
463 variables.grain_compressibility = beta_SR;
464
465 auto const rho_LR =
466 liquid_phase.property(MPL::PropertyType::density)
467 .template value<double>(variables, x_position, t, dt);
468 variables.density = rho_LR;
469
470 auto const& b = this->process_data_.specific_body_force;
471
472 S_L = medium->property(MPL::PropertyType::saturation)
473 .template value<double>(variables, x_position, t, dt);
474 variables.liquid_saturation = S_L;
475 variables_prev.liquid_saturation = S_L_prev;
476
477 // tangent derivative for Jacobian
478 double const dS_L_dp_cap =
479 medium->property(MPL::PropertyType::saturation)
480 .template dValue<double>(variables,
481 MPL::Variable::capillary_pressure,
482 x_position, t, dt);
483 // secant derivative from time discretization for storage
484 // use tangent, if secant is not available
485 double const DeltaS_L_Deltap_cap =
486 (p_cap_ip == p_cap_prev_ip)
487 ? dS_L_dp_cap
488 : (S_L - S_L_prev) / (p_cap_ip - p_cap_prev_ip);
489
490 auto const chi = [medium, x_position, t, dt](double const S_L)
491 {
493 vs.liquid_saturation = S_L;
494 return medium->property(MPL::PropertyType::bishops_effective_stress)
495 .template value<double>(vs, x_position, t, dt);
496 };
497 double const chi_S_L = chi(S_L);
498 double const chi_S_L_prev = chi(S_L_prev);
499
500 double const p_FR = -chi_S_L * p_cap_ip;
501 variables.effective_pore_pressure = p_FR;
502 variables_prev.effective_pore_pressure = -chi_S_L_prev * p_cap_prev_ip;
503
504 // Set volumetric strain rate for the general case without swelling.
505 variables.volumetric_strain = Invariants::trace(eps.eps);
506 variables_prev.volumetric_strain = Invariants::trace(B * u_prev);
507
508 auto& phi = std::get<ProcessLib::ThermoRichardsMechanics::PorosityData>(
509 this->current_states_[ip])
510 .phi;
511 { // Porosity update
512 auto const phi_prev = std::get<PrevState<
514 this->prev_states_[ip])
515 ->phi;
516 variables_prev.porosity = phi_prev;
517 phi = medium->property(MPL::PropertyType::porosity)
518 .template value<double>(variables, variables_prev,
519 x_position, t, dt);
520 variables.porosity = phi;
521 }
522
523 if (alpha < phi)
524 {
525 OGS_FATAL(
526 "RichardsMechanics: Biot-coefficient {} is smaller than "
527 "porosity {} in element/integration point {}/{}.",
528 alpha, phi, this->element_.getID(), ip);
529 }
530
531 // Swelling and possibly volumetric strain rate update.
532 {
533 auto& sigma_sw =
534 std::get<ProcessLib::ThermoRichardsMechanics::
535 ConstitutiveStress_StrainTemperature::
536 SwellingDataStateful<DisplacementDim>>(
537 this->current_states_[ip])
538 .sigma_sw;
539 auto const& sigma_sw_prev = std::get<PrevState<
540 ProcessLib::ThermoRichardsMechanics::
541 ConstitutiveStress_StrainTemperature::SwellingDataStateful<
542 DisplacementDim>>>(this->prev_states_[ip])
543 ->sigma_sw;
544
545 // If there is swelling, compute it. Update volumetric strain rate,
546 // s.t. it corresponds to the mechanical part only.
547 sigma_sw = sigma_sw_prev;
548 if (solid_phase.hasProperty(
549 MPL::PropertyType::swelling_stress_rate))
550 {
551 auto const sigma_sw_dot =
554 solid_phase[MPL::PropertyType::swelling_stress_rate]
555 .value(variables, variables_prev, x_position, t,
556 dt)));
557 sigma_sw += sigma_sw_dot * dt;
558
560 variables.volumetric_strain +
561 identity2.transpose() * C_el.inverse() * sigma_sw;
562 variables_prev.volumetric_mechanical_strain =
563 variables_prev.volumetric_strain +
564 identity2.transpose() * C_el.inverse() * sigma_sw_prev;
565 }
566 else
567 {
569 variables.volumetric_strain;
570 variables_prev.volumetric_mechanical_strain =
571 variables_prev.volumetric_strain;
572 }
573
574 if (medium->hasProperty(MPL::PropertyType::transport_porosity))
575 {
576 auto& transport_porosity =
577 std::get<ProcessLib::ThermoRichardsMechanics::
578 TransportPorosityData>(
579 this->current_states_[ip])
580 .phi;
581 auto const transport_porosity_prev =
582 std::get<PrevState<ProcessLib::ThermoRichardsMechanics::
583 TransportPorosityData>>(
584 this->prev_states_[ip])
585 ->phi;
586 variables_prev.transport_porosity = transport_porosity_prev;
587
588 transport_porosity =
589 medium->property(MPL::PropertyType::transport_porosity)
590 .template value<double>(variables, variables_prev,
591 x_position, t, dt);
592 variables.transport_porosity = transport_porosity;
593 }
594 else
595 {
596 variables.transport_porosity = phi;
597 }
598 }
599
600 double const k_rel =
601 medium->property(MPL::PropertyType::relative_permeability)
602 .template value<double>(variables, x_position, t, dt);
603 auto const mu =
604 liquid_phase.property(MPL::PropertyType::viscosity)
605 .template value<double>(variables, x_position, t, dt);
606
607 auto const& sigma_sw =
608 std::get<ProcessLib::ThermoRichardsMechanics::
609 ConstitutiveStress_StrainTemperature::
610 SwellingDataStateful<DisplacementDim>>(
611 this->current_states_[ip])
612 .sigma_sw;
613 auto const& sigma_eff =
615 DisplacementDim>>(this->current_states_[ip])
616 .sigma_eff;
617
618 // Set mechanical variables for the intrinsic permeability model
619 // For stress dependent permeability.
620 {
621 auto const sigma_total =
622 (sigma_eff - alpha * p_FR * identity2).eval();
623
624 // For stress dependent permeability.
625 variables.total_stress.emplace<SymmetricTensor>(
627 sigma_total));
628 }
629
630 variables.equivalent_plastic_strain =
631 this->material_states_[ip]
632 .material_state_variables->getEquivalentPlasticStrain();
633
634 auto const K_intrinsic = MPL::formEigenTensor<DisplacementDim>(
635 medium->property(MPL::PropertyType::permeability)
636 .value(variables, x_position, t, dt));
637
638 GlobalDimMatrixType const rho_K_over_mu =
639 K_intrinsic * rho_LR * k_rel / mu;
640
641 //
642 // displacement equation, displacement part
643 //
644 {
645 auto& eps_m = std::get<ProcessLib::ConstitutiveRelations::
646 MechanicalStrainData<DisplacementDim>>(
647 this->current_states_[ip])
648 .eps_m;
649 eps_m.noalias() =
650 solid_phase.hasProperty(MPL::PropertyType::swelling_stress_rate)
651 ? eps.eps + C_el.inverse() * sigma_sw
652 : eps.eps;
653 variables.mechanical_strain.emplace<
655 eps_m);
656 }
657
658 {
659 auto& SD = this->current_states_[ip];
660 auto const& SD_prev = this->prev_states_[ip];
661 auto& sigma_eff =
663 DisplacementDim>>(SD);
664 auto const& sigma_eff_prev =
665 std::get<PrevState<ProcessLib::ConstitutiveRelations::
666 EffectiveStressData<DisplacementDim>>>(
667 SD_prev);
668 auto const& eps_m =
669 std::get<ProcessLib::ConstitutiveRelations::
670 MechanicalStrainData<DisplacementDim>>(SD);
671 auto& eps_m_prev =
672 std::get<PrevState<ProcessLib::ConstitutiveRelations::
673 MechanicalStrainData<DisplacementDim>>>(
674 SD_prev);
675
676 _ip_data[ip].updateConstitutiveRelation(
677 variables, t, x_position, dt, temperature, sigma_eff,
678 sigma_eff_prev, eps_m, eps_m_prev, this->solid_material_,
679 this->material_states_[ip].material_state_variables);
680 }
681
682 // p_SR
683 variables.solid_grain_pressure =
684 p_FR - sigma_eff.dot(identity2) / (3 * (1 - phi));
685 auto const rho_SR =
686 solid_phase.property(MPL::PropertyType::density)
687 .template value<double>(variables, x_position, t, dt);
688
689 //
690 // displacement equation, displacement part
691 //
692 double const rho = rho_SR * (1 - phi) + S_L * phi * rho_LR;
693 rhs.template segment<displacement_size>(displacement_index).noalias() -=
694 (B.transpose() * sigma_eff - N_u_op(N_u).transpose() * rho * b) * w;
695
696 //
697 // pressure equation, pressure part.
698 //
699 auto const beta_LR =
700 1 / rho_LR *
701 liquid_phase.property(MPL::PropertyType::density)
702 .template dValue<double>(variables,
703 MPL::Variable::liquid_phase_pressure,
704 x_position, t, dt);
705
706 double const a0 = S_L * (alpha - phi) * beta_SR;
707 // Volumetric average specific storage of the solid and fluid phases.
708 double const specific_storage =
709 DeltaS_L_Deltap_cap * (p_cap_ip * a0 - phi) +
710 S_L * (phi * beta_LR + a0);
711 M.template block<pressure_size, pressure_size>(pressure_index,
712 pressure_index)
713 .noalias() += N_p.transpose() * rho_LR * specific_storage * N_p * w;
714
715 K.template block<pressure_size, pressure_size>(pressure_index,
716 pressure_index)
717 .noalias() += dNdx_p.transpose() * rho_K_over_mu * dNdx_p * w;
718
719 rhs.template segment<pressure_size>(pressure_index).noalias() +=
720 dNdx_p.transpose() * rho_LR * rho_K_over_mu * b * w;
721
722 //
723 // displacement equation, pressure part
724 //
725 K.template block<displacement_size, pressure_size>(displacement_index,
726 pressure_index)
727 .noalias() -= B.transpose() * alpha * chi_S_L * identity2 * N_p * w;
728
729 //
730 // pressure equation, displacement part.
731 //
732 M.template block<pressure_size, displacement_size>(pressure_index,
733 displacement_index)
734 .noalias() += N_p.transpose() * S_L * rho_LR * alpha *
735 identity2.transpose() * B * w;
736 }
737
738 if (this->process_data_.apply_mass_lumping)
739 {
740 auto Mpp = M.template block<pressure_size, pressure_size>(
741 pressure_index, pressure_index);
742 Mpp = Mpp.colwise().sum().eval().asDiagonal();
743 }
744}
745
746template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
747 int DisplacementDim>
748void RichardsMechanicsLocalAssembler<ShapeFunctionDisplacement,
749 ShapeFunctionPressure, DisplacementDim>::
750 assembleWithJacobianEvalConstitutiveSetting(
751 double const t, double const dt,
752 ParameterLib::SpatialPosition const& x_position,
753 RichardsMechanicsLocalAssembler<ShapeFunctionDisplacement,
754 ShapeFunctionPressure,
755 DisplacementDim>::IpData& ip_data,
756 MPL::VariableArray& variables, MPL::VariableArray& variables_prev,
757 MPL::Medium const* const medium, TemperatureData const T_data,
762 std::optional<MicroPorosityParameters> const& micro_porosity_parameters,
764 solid_material,
766 material_state_data)
767{
768 auto const& liquid_phase = medium->phase("AqueousLiquid");
769 auto const& solid_phase = medium->phase("Solid");
770
771 auto const& identity2 = MathLib::KelvinVector::Invariants<
773 DisplacementDim)>::identity2;
774
775 double const temperature = T_data();
776 double const p_cap_ip = p_cap_data.p_cap;
777 double const p_cap_prev_ip = p_cap_data.p_cap_prev;
778
779 auto const& eps = std::get<StrainData<DisplacementDim>>(SD);
780 auto& S_L =
781 std::get<ProcessLib::ThermoRichardsMechanics::SaturationData>(SD).S_L;
782 auto const S_L_prev =
783 std::get<
785 SD_prev)
786 ->S_L;
787 auto const alpha =
788 medium->property(MPL::PropertyType::biot_coefficient)
789 .template value<double>(variables, x_position, t, dt);
790 *std::get<ProcessLib::ThermoRichardsMechanics::BiotData>(CD) = alpha;
791
792 auto const C_el = ip_data.computeElasticTangentStiffness(
793 t, x_position, dt, temperature, solid_material,
794 *material_state_data.material_state_variables);
795
796 auto const beta_SR =
797 (1 - alpha) / solid_material.getBulkModulus(t, x_position, &C_el);
798 variables.grain_compressibility = beta_SR;
799 std::get<ProcessLib::ThermoRichardsMechanics::SolidCompressibilityData>(CD)
800 .beta_SR = beta_SR;
801
802 auto const rho_LR =
803 liquid_phase.property(MPL::PropertyType::density)
804 .template value<double>(variables, x_position, t, dt);
805 variables.density = rho_LR;
806 *std::get<LiquidDensity>(CD) = rho_LR;
807
808 S_L = medium->property(MPL::PropertyType::saturation)
809 .template value<double>(variables, x_position, t, dt);
810 variables.liquid_saturation = S_L;
811 variables_prev.liquid_saturation = S_L_prev;
812
813 // tangent derivative for Jacobian
814 double const dS_L_dp_cap =
815 medium->property(MPL::PropertyType::saturation)
816 .template dValue<double>(variables,
817 MPL::Variable::capillary_pressure,
818 x_position, t, dt);
819 std::get<ProcessLib::ThermoRichardsMechanics::SaturationDataDeriv>(CD)
820 .dS_L_dp_cap = dS_L_dp_cap;
821 // secant derivative from time discretization for storage
822 // use tangent, if secant is not available
823 double const DeltaS_L_Deltap_cap =
824 (p_cap_ip == p_cap_prev_ip)
825 ? dS_L_dp_cap
826 : (S_L - S_L_prev) / (p_cap_ip - p_cap_prev_ip);
827 std::get<SaturationSecantDerivative>(CD).DeltaS_L_Deltap_cap =
828 DeltaS_L_Deltap_cap;
829
830 auto const chi = [medium, x_position, t, dt](double const S_L)
831 {
833 vs.liquid_saturation = S_L;
834 return medium->property(MPL::PropertyType::bishops_effective_stress)
835 .template value<double>(vs, x_position, t, dt);
836 };
837 double const chi_S_L = chi(S_L);
838 std::get<ProcessLib::ThermoRichardsMechanics::BishopsData>(CD).chi_S_L =
839 chi_S_L;
840 double const chi_S_L_prev = chi(S_L_prev);
841 std::get<PrevState<ProcessLib::ThermoRichardsMechanics::BishopsData>>(CD)
842 ->chi_S_L = chi_S_L_prev;
843
844 auto const dchi_dS_L =
845 medium->property(MPL::PropertyType::bishops_effective_stress)
846 .template dValue<double>(
847 variables, MPL::Variable::liquid_saturation, x_position, t, dt);
848 std::get<ProcessLib::ThermoRichardsMechanics::BishopsData>(CD).dchi_dS_L =
849 dchi_dS_L;
850
851 double const p_FR = -chi_S_L * p_cap_ip;
852 variables.effective_pore_pressure = p_FR;
853 variables_prev.effective_pore_pressure = -chi_S_L_prev * p_cap_prev_ip;
854
855 // Set volumetric strain rate for the general case without swelling.
856 variables.volumetric_strain = Invariants::trace(eps.eps);
857 // TODO (CL) changed that, using eps_prev for the moment, not B * u_prev
858 // variables_prev.volumetric_strain = Invariants::trace(B * u_prev);
859 variables_prev.volumetric_strain = Invariants::trace(
860 std::get<PrevState<StrainData<DisplacementDim>>>(SD_prev)->eps);
861
862 auto& phi =
863 std::get<ProcessLib::ThermoRichardsMechanics::PorosityData>(SD).phi;
864 { // Porosity update
865 auto const phi_prev =
866 std::get<
868 SD_prev)
869 ->phi;
870 variables_prev.porosity = phi_prev;
871 phi = medium->property(MPL::PropertyType::porosity)
872 .template value<double>(variables, variables_prev, x_position,
873 t, dt);
874 variables.porosity = phi;
875 }
876 std::get<ProcessLib::ThermoRichardsMechanics::PorosityData>(CD).phi = phi;
877
878 if (alpha < phi)
879 {
880 auto const eid =
881 x_position.getElementID()
882 ? static_cast<std::ptrdiff_t>(*x_position.getElementID())
883 : static_cast<std::ptrdiff_t>(-1);
884 OGS_FATAL(
885 "RichardsMechanics: Biot-coefficient {} is smaller than porosity "
886 "{} in element {}.",
887 alpha, phi, eid);
888 }
889
890 auto const mu = liquid_phase.property(MPL::PropertyType::viscosity)
891 .template value<double>(variables, x_position, t, dt);
892 *std::get<ProcessLib::ThermoRichardsMechanics::LiquidViscosityData>(CD) =
893 mu;
894
895 {
896 // Swelling and possibly volumetric strain rate update.
897 auto& sigma_sw =
898 std::get<ProcessLib::ThermoRichardsMechanics::
899 ConstitutiveStress_StrainTemperature::
900 SwellingDataStateful<DisplacementDim>>(SD);
901 auto const& sigma_sw_prev =
902 std::get<PrevState<ProcessLib::ThermoRichardsMechanics::
903 ConstitutiveStress_StrainTemperature::
904 SwellingDataStateful<DisplacementDim>>>(
905 SD_prev);
906 auto const transport_porosity_prev = std::get<PrevState<
908 SD_prev);
909 auto const phi_prev = std::get<
911 SD_prev);
912 auto& transport_porosity = std::get<
914 auto& p_L_m = std::get<MicroPressure>(SD);
915 auto const p_L_m_prev = std::get<PrevState<MicroPressure>>(SD_prev);
916 auto& S_L_m = std::get<MicroSaturation>(SD);
917 auto const S_L_m_prev = std::get<PrevState<MicroSaturation>>(SD_prev);
918
920 *medium, solid_phase, C_el, rho_LR, mu, micro_porosity_parameters,
921 alpha, phi, p_cap_ip, variables, variables_prev, x_position, t, dt,
922 sigma_sw, sigma_sw_prev, transport_porosity_prev, phi_prev,
923 transport_porosity, p_L_m_prev, S_L_m_prev, p_L_m, S_L_m);
924 }
925
926 if (medium->hasProperty(MPL::PropertyType::transport_porosity))
927 {
928 if (!medium->hasProperty(MPL::PropertyType::saturation_micro))
929 {
930 auto& transport_porosity =
931 std::get<
933 SD)
934 .phi;
935 auto const transport_porosity_prev = std::get<PrevState<
937 SD_prev)
938 ->phi;
939 variables_prev.transport_porosity = transport_porosity_prev;
940
941 transport_porosity =
942 medium->property(MPL::PropertyType::transport_porosity)
943 .template value<double>(variables, variables_prev,
944 x_position, t, dt);
945 variables.transport_porosity = transport_porosity;
946 }
947 }
948 else
949 {
950 variables.transport_porosity = phi;
951 }
952
953 // Set mechanical variables for the intrinsic permeability model
954 // For stress dependent permeability.
955 {
956 // TODO mechanical constitutive relation will be evaluated afterwards
957 auto const sigma_total =
959 DisplacementDim>>(SD)
960 .sigma_eff +
961 alpha * p_FR * identity2)
962 .eval();
963 // For stress dependent permeability.
964 variables.total_stress.emplace<SymmetricTensor>(
966 }
967
968 variables.equivalent_plastic_strain =
969 material_state_data.material_state_variables
970 ->getEquivalentPlasticStrain();
971
972 double const k_rel =
973 medium->property(MPL::PropertyType::relative_permeability)
974 .template value<double>(variables, x_position, t, dt);
975
976 auto const K_intrinsic = MPL::formEigenTensor<DisplacementDim>(
977 medium->property(MPL::PropertyType::permeability)
978 .value(variables, x_position, t, dt));
979
980 std::get<
982 CD)
983 .k_rel = k_rel;
984 std::get<
986 CD)
987 .Ki = K_intrinsic;
988
989 //
990 // displacement equation, displacement part
991 //
992
993 {
994 auto& sigma_sw =
995 std::get<ProcessLib::ThermoRichardsMechanics::
996 ConstitutiveStress_StrainTemperature::
997 SwellingDataStateful<DisplacementDim>>(SD)
998 .sigma_sw;
999
1000 auto& eps_m =
1002 DisplacementDim>>(SD)
1003 .eps_m;
1004 eps_m.noalias() =
1005 solid_phase.hasProperty(MPL::PropertyType::swelling_stress_rate)
1006 ? eps.eps + C_el.inverse() * sigma_sw
1007 : eps.eps;
1008 variables.mechanical_strain
1010 eps_m);
1011 }
1012
1013 {
1014 auto& sigma_eff =
1016 DisplacementDim>>(SD);
1017 auto const& sigma_eff_prev =
1018 std::get<PrevState<ProcessLib::ConstitutiveRelations::
1019 EffectiveStressData<DisplacementDim>>>(
1020 SD_prev);
1021 auto const& eps_m =
1023 DisplacementDim>>(SD);
1024 auto& eps_m_prev =
1025 std::get<PrevState<ProcessLib::ConstitutiveRelations::
1026 MechanicalStrainData<DisplacementDim>>>(
1027 SD_prev);
1028
1029 auto C = ip_data.updateConstitutiveRelation(
1030 variables, t, x_position, dt, temperature, sigma_eff,
1031 sigma_eff_prev, eps_m, eps_m_prev, solid_material,
1032 material_state_data.material_state_variables);
1033
1034 *std::get<StiffnessTensor<DisplacementDim>>(CD) = std::move(C);
1035 }
1036
1037 // p_SR
1038 variables.solid_grain_pressure =
1040 DisplacementDim>>(SD)
1041 .sigma_eff.dot(identity2) /
1042 (3 * (1 - phi));
1043 auto const rho_SR =
1044 solid_phase.property(MPL::PropertyType::density)
1045 .template value<double>(variables, x_position, t, dt);
1046
1047 double const rho = rho_SR * (1 - phi) + S_L * phi * rho_LR;
1048 *std::get<Density>(CD) = rho;
1049}
1050
1051template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
1052 int DisplacementDim>
1053void RichardsMechanicsLocalAssembler<ShapeFunctionDisplacement,
1054 ShapeFunctionPressure, DisplacementDim>::
1055 assembleWithJacobian(double const t, double const dt,
1056 std::vector<double> const& local_x,
1057 std::vector<double> const& local_x_prev,
1058 std::vector<double>& local_rhs_data,
1059 std::vector<double>& local_Jac_data)
1060{
1061 assert(local_x.size() == pressure_size + displacement_size);
1062
1063 auto const [p_L, u] = localDOF(local_x);
1064 auto const [p_L_prev, u_prev] = localDOF(local_x_prev);
1065
1066 auto local_Jac = MathLib::createZeroedMatrix<
1067 typename ShapeMatricesTypeDisplacement::template MatrixType<
1068 displacement_size + pressure_size,
1069 displacement_size + pressure_size>>(
1070 local_Jac_data, displacement_size + pressure_size,
1071 displacement_size + pressure_size);
1072
1073 auto local_rhs = MathLib::createZeroedVector<
1074 typename ShapeMatricesTypeDisplacement::template VectorType<
1075 displacement_size + pressure_size>>(
1076 local_rhs_data, displacement_size + pressure_size);
1077
1078 auto const& identity2 = MathLib::KelvinVector::Invariants<
1080 DisplacementDim)>::identity2;
1081
1083 ShapeMatricesTypePressure::NodalMatrixType::Zero(pressure_size,
1084 pressure_size);
1085
1086 typename ShapeMatricesTypePressure::NodalMatrixType storage_p_a_p =
1087 ShapeMatricesTypePressure::NodalMatrixType::Zero(pressure_size,
1088 pressure_size);
1089
1090 typename ShapeMatricesTypePressure::NodalMatrixType storage_p_a_S_Jpp =
1091 ShapeMatricesTypePressure::NodalMatrixType::Zero(pressure_size,
1092 pressure_size);
1093
1094 typename ShapeMatricesTypePressure::NodalMatrixType storage_p_a_S =
1095 ShapeMatricesTypePressure::NodalMatrixType::Zero(pressure_size,
1096 pressure_size);
1097
1098 typename ShapeMatricesTypeDisplacement::template MatrixType<
1099 displacement_size, pressure_size>
1100 Kup = ShapeMatricesTypeDisplacement::template MatrixType<
1101 displacement_size, pressure_size>::Zero(displacement_size,
1102 pressure_size);
1103
1104 typename ShapeMatricesTypeDisplacement::template MatrixType<
1105 pressure_size, displacement_size>
1106 Kpu = ShapeMatricesTypeDisplacement::template MatrixType<
1107 pressure_size, displacement_size>::Zero(pressure_size,
1108 displacement_size);
1109
1110 auto const& medium =
1111 this->process_data_.media_map.getMedium(this->element_.getID());
1112 auto const& liquid_phase = medium->phase("AqueousLiquid");
1113 auto const& solid_phase = medium->phase("Solid");
1114 MPL::VariableArray variables;
1115 MPL::VariableArray variables_prev;
1116
1118 x_position.setElementID(this->element_.getID());
1119
1120 unsigned const n_integration_points =
1121 this->integration_method_.getNumberOfPoints();
1122 for (unsigned ip = 0; ip < n_integration_points; ip++)
1123 {
1125 auto& SD = this->current_states_[ip];
1126 auto const& SD_prev = this->prev_states_[ip];
1127 [[maybe_unused]] auto models = createConstitutiveModels(
1128 this->process_data_, this->solid_material_);
1129
1130 auto const& w = _ip_data[ip].integration_weight;
1131
1132 auto const& N_u = _ip_data[ip].N_u;
1133 auto const& dNdx_u = _ip_data[ip].dNdx_u;
1134
1135 auto const& N_p = _ip_data[ip].N_p;
1136 auto const& dNdx_p = _ip_data[ip].dNdx_p;
1137
1138 auto const x_coord =
1139 NumLib::interpolateXCoordinate<ShapeFunctionDisplacement,
1141 this->element_, N_u);
1142 auto const B =
1143 LinearBMatrix::computeBMatrix<DisplacementDim,
1144 ShapeFunctionDisplacement::NPOINTS,
1146 dNdx_u, N_u, x_coord, this->is_axially_symmetric_);
1147
1148 double p_cap_ip;
1149 NumLib::shapeFunctionInterpolate(-p_L, N_p, p_cap_ip);
1150
1151 double p_cap_prev_ip;
1152 NumLib::shapeFunctionInterpolate(-p_L_prev, N_p, p_cap_prev_ip);
1153
1154 variables.capillary_pressure = p_cap_ip;
1155 variables.liquid_phase_pressure = -p_cap_ip;
1156 // setting pG to 1 atm
1157 // TODO : rewrite equations s.t. p_L = pG-p_cap
1158 variables.gas_phase_pressure = 1.0e5;
1159
1160 auto const temperature =
1161 medium->property(MPL::PropertyType::reference_temperature)
1162 .template value<double>(variables, x_position, t, dt);
1163 variables.temperature = temperature;
1164
1165 std::get<StrainData<DisplacementDim>>(SD).eps.noalias() = B * u;
1166
1167 assembleWithJacobianEvalConstitutiveSetting(
1168 t, dt, x_position, _ip_data[ip], variables, variables_prev, medium,
1169 TemperatureData{temperature},
1171 p_cap_ip, p_cap_prev_ip,
1172 Eigen::Vector<double, DisplacementDim>::Zero()},
1173 CD, SD, SD_prev, this->process_data_.micro_porosity_parameters,
1174 this->solid_material_, this->material_states_[ip]);
1175
1176 {
1177 auto const& C = *std::get<StiffnessTensor<DisplacementDim>>(CD);
1178 local_Jac
1179 .template block<displacement_size, displacement_size>(
1180 displacement_index, displacement_index)
1181 .noalias() += B.transpose() * C * B * w;
1182 }
1183
1184 auto const& b = this->process_data_.specific_body_force;
1185
1186 {
1187 auto const& sigma_eff =
1189 DisplacementDim>>(this->current_states_[ip])
1190 .sigma_eff;
1191 double const rho = *std::get<Density>(CD);
1192 local_rhs.template segment<displacement_size>(displacement_index)
1193 .noalias() -= (B.transpose() * sigma_eff -
1194 N_u_op(N_u).transpose() * rho * b) *
1195 w;
1196 }
1197
1198 //
1199 // displacement equation, pressure part
1200 //
1201
1202 double const alpha =
1203 *std::get<ProcessLib::ThermoRichardsMechanics::BiotData>(CD);
1204 double const dS_L_dp_cap =
1205 std::get<ProcessLib::ThermoRichardsMechanics::SaturationDataDeriv>(
1206 CD)
1207 .dS_L_dp_cap;
1208
1209 {
1210 double const chi_S_L =
1211 std::get<ProcessLib::ThermoRichardsMechanics::BishopsData>(CD)
1212 .chi_S_L;
1213 Kup.noalias() +=
1214 B.transpose() * alpha * chi_S_L * identity2 * N_p * w;
1215 double const dchi_dS_L =
1216 std::get<ProcessLib::ThermoRichardsMechanics::BishopsData>(CD)
1217 .dchi_dS_L;
1218
1219 local_Jac
1220 .template block<displacement_size, pressure_size>(
1221 displacement_index, pressure_index)
1222 .noalias() -= B.transpose() * alpha *
1223 (chi_S_L + dchi_dS_L * p_cap_ip * dS_L_dp_cap) *
1224 identity2 * N_p * w;
1225 }
1226
1227 double const phi =
1228 std::get<ProcessLib::ThermoRichardsMechanics::PorosityData>(CD).phi;
1229 double const rho_LR = *std::get<LiquidDensity>(CD);
1230 local_Jac
1231 .template block<displacement_size, pressure_size>(
1232 displacement_index, pressure_index)
1233 .noalias() +=
1234 N_u_op(N_u).transpose() * phi * rho_LR * dS_L_dp_cap * b * N_p * w;
1235
1236 // For the swelling stress with double structure model the corresponding
1237 // Jacobian u-p entry would be required, but it does not improve
1238 // convergence and sometimes worsens it:
1239 // if (medium->hasProperty(MPL::PropertyType::saturation_micro))
1240 // {
1241 // -B.transpose() *
1242 // dsigma_sw_dS_L_m* dS_L_m_dp_cap_m*(p_L_m - p_L_m_prev) /
1243 // (p_cap_ip - p_cap_prev_ip) * N_p* w;
1244 // }
1245 if (!medium->hasProperty(MPL::PropertyType::saturation_micro) &&
1246 solid_phase.hasProperty(MPL::PropertyType::swelling_stress_rate))
1247 {
1248 using DimMatrix = Eigen::Matrix<double, 3, 3>;
1249 auto const dsigma_sw_dS_L =
1251 solid_phase
1252 .property(MPL::PropertyType::swelling_stress_rate)
1253 .template dValue<DimMatrix>(
1254 variables, variables_prev,
1255 MPL::Variable::liquid_saturation, x_position, t,
1256 dt));
1257 local_Jac
1258 .template block<displacement_size, pressure_size>(
1259 displacement_index, pressure_index)
1260 .noalias() +=
1261 B.transpose() * dsigma_sw_dS_L * dS_L_dp_cap * N_p * w;
1262 }
1263 //
1264 // pressure equation, displacement part.
1265 //
1266 double const S_L =
1267 std::get<ProcessLib::ThermoRichardsMechanics::SaturationData>(
1268 this->current_states_[ip])
1269 .S_L;
1270 if (this->process_data_.explicit_hm_coupling_in_unsaturated_zone)
1271 {
1272 double const chi_S_L_prev = std::get<PrevState<
1274 ->chi_S_L;
1275 Kpu.noalias() += N_p.transpose() * chi_S_L_prev * rho_LR * alpha *
1276 identity2.transpose() * B * w;
1277 }
1278 else
1279 {
1280 Kpu.noalias() += N_p.transpose() * S_L * rho_LR * alpha *
1281 identity2.transpose() * B * w;
1282 }
1283
1284 //
1285 // pressure equation, pressure part.
1286 //
1287
1288 double const k_rel =
1290 DisplacementDim>>(CD)
1291 .k_rel;
1292 auto const& K_intrinsic =
1294 DisplacementDim>>(CD)
1295 .Ki;
1296 double const mu =
1297 *std::get<ProcessLib::ThermoRichardsMechanics::LiquidViscosityData>(
1298 CD);
1299
1300 GlobalDimMatrixType const rho_Ki_over_mu = K_intrinsic * rho_LR / mu;
1301
1302 laplace_p.noalias() +=
1303 dNdx_p.transpose() * k_rel * rho_Ki_over_mu * dNdx_p * w;
1304
1305 auto const beta_LR =
1306 1 / rho_LR *
1307 liquid_phase.property(MPL::PropertyType::density)
1308 .template dValue<double>(variables,
1309 MPL::Variable::liquid_phase_pressure,
1310 x_position, t, dt);
1311
1312 double const beta_SR =
1313 std::get<
1315 CD)
1316 .beta_SR;
1317 double const a0 = (alpha - phi) * beta_SR;
1318 double const specific_storage_a_p = S_L * (phi * beta_LR + S_L * a0);
1319 double const specific_storage_a_S = phi - p_cap_ip * S_L * a0;
1320
1321 double const dspecific_storage_a_p_dp_cap =
1322 dS_L_dp_cap * (phi * beta_LR + 2 * S_L * a0);
1323 double const dspecific_storage_a_S_dp_cap =
1324 -a0 * (S_L + p_cap_ip * dS_L_dp_cap);
1325
1326 storage_p_a_p.noalias() +=
1327 N_p.transpose() * rho_LR * specific_storage_a_p * N_p * w;
1328
1329 double const DeltaS_L_Deltap_cap =
1330 std::get<SaturationSecantDerivative>(CD).DeltaS_L_Deltap_cap;
1331 storage_p_a_S.noalias() -= N_p.transpose() * rho_LR *
1332 specific_storage_a_S * DeltaS_L_Deltap_cap *
1333 N_p * w;
1334
1335 local_Jac
1336 .template block<pressure_size, pressure_size>(pressure_index,
1337 pressure_index)
1338 .noalias() += N_p.transpose() * (p_cap_ip - p_cap_prev_ip) / dt *
1339 rho_LR * dspecific_storage_a_p_dp_cap * N_p * w;
1340
1341 double const S_L_prev =
1342 std::get<
1344 this->prev_states_[ip])
1345 ->S_L;
1346 storage_p_a_S_Jpp.noalias() -=
1347 N_p.transpose() * rho_LR *
1348 ((S_L - S_L_prev) * dspecific_storage_a_S_dp_cap +
1349 specific_storage_a_S * dS_L_dp_cap) /
1350 dt * N_p * w;
1351
1352 if (!this->process_data_.explicit_hm_coupling_in_unsaturated_zone)
1353 {
1354 local_Jac
1355 .template block<pressure_size, pressure_size>(pressure_index,
1356 pressure_index)
1357 .noalias() -= N_p.transpose() * rho_LR * dS_L_dp_cap * alpha *
1358 identity2.transpose() * B * (u - u_prev) / dt *
1359 N_p * w;
1360 }
1361
1362 double const dk_rel_dS_l =
1363 medium->property(MPL::PropertyType::relative_permeability)
1364 .template dValue<double>(variables,
1365 MPL::Variable::liquid_saturation,
1366 x_position, t, dt);
1368 grad_p_cap = -dNdx_p * p_L;
1369 local_Jac
1370 .template block<pressure_size, pressure_size>(pressure_index,
1371 pressure_index)
1372 .noalias() += dNdx_p.transpose() * rho_Ki_over_mu * grad_p_cap *
1373 dk_rel_dS_l * dS_L_dp_cap * N_p * w;
1374
1375 local_Jac
1376 .template block<pressure_size, pressure_size>(pressure_index,
1377 pressure_index)
1378 .noalias() += dNdx_p.transpose() * rho_LR * rho_Ki_over_mu * b *
1379 dk_rel_dS_l * dS_L_dp_cap * N_p * w;
1380
1381 local_rhs.template segment<pressure_size>(pressure_index).noalias() +=
1382 dNdx_p.transpose() * rho_LR * k_rel * rho_Ki_over_mu * b * w;
1383
1384 if (medium->hasProperty(MPL::PropertyType::saturation_micro))
1385 {
1386 double const alpha_bar =
1387 this->process_data_.micro_porosity_parameters
1388 ->mass_exchange_coefficient;
1389 auto const p_L_m =
1390 *std::get<MicroPressure>(this->current_states_[ip]);
1391 local_rhs.template segment<pressure_size>(pressure_index)
1392 .noalias() -=
1393 N_p.transpose() * alpha_bar / mu * (-p_cap_ip - p_L_m) * w;
1394
1395 local_Jac
1396 .template block<pressure_size, pressure_size>(pressure_index,
1397 pressure_index)
1398 .noalias() += N_p.transpose() * alpha_bar / mu * N_p * w;
1399 if (p_cap_ip != p_cap_prev_ip)
1400 {
1401 auto const p_L_m_prev = **std::get<PrevState<MicroPressure>>(
1402 this->prev_states_[ip]);
1403 local_Jac
1404 .template block<pressure_size, pressure_size>(
1405 pressure_index, pressure_index)
1406 .noalias() += N_p.transpose() * alpha_bar / mu *
1407 (p_L_m - p_L_m_prev) /
1408 (p_cap_ip - p_cap_prev_ip) * N_p * w;
1409 }
1410 }
1411 }
1412
1413 if (this->process_data_.apply_mass_lumping)
1414 {
1415 storage_p_a_p = storage_p_a_p.colwise().sum().eval().asDiagonal();
1416 storage_p_a_S = storage_p_a_S.colwise().sum().eval().asDiagonal();
1417 storage_p_a_S_Jpp =
1418 storage_p_a_S_Jpp.colwise().sum().eval().asDiagonal();
1419 }
1420
1421 // pressure equation, pressure part.
1422 local_Jac
1423 .template block<pressure_size, pressure_size>(pressure_index,
1424 pressure_index)
1425 .noalias() += laplace_p + storage_p_a_p / dt + storage_p_a_S_Jpp;
1426
1427 // pressure equation, displacement part.
1428 local_Jac
1429 .template block<pressure_size, displacement_size>(pressure_index,
1430 displacement_index)
1431 .noalias() = Kpu / dt;
1432
1433 // pressure equation
1434 local_rhs.template segment<pressure_size>(pressure_index).noalias() -=
1435 laplace_p * p_L +
1436 (storage_p_a_p + storage_p_a_S) * (p_L - p_L_prev) / dt +
1437 Kpu * (u - u_prev) / dt;
1438
1439 // displacement equation
1440 local_rhs.template segment<displacement_size>(displacement_index)
1441 .noalias() += Kup * p_L;
1442}
1443
1444template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
1445 int DisplacementDim>
1446void RichardsMechanicsLocalAssembler<ShapeFunctionDisplacement,
1447 ShapeFunctionPressure, DisplacementDim>::
1448 assembleWithJacobianForPressureEquations(
1449 const double /*t*/, double const /*dt*/,
1450 Eigen::VectorXd const& /*local_x*/,
1451 Eigen::VectorXd const& /*local_x_prev*/,
1452 std::vector<double>& /*local_b_data*/,
1453 std::vector<double>& /*local_Jac_data*/)
1454{
1455 OGS_FATAL("RichardsMechanics; The staggered scheme is not implemented.");
1456}
1457
1458template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
1459 int DisplacementDim>
1460void RichardsMechanicsLocalAssembler<ShapeFunctionDisplacement,
1461 ShapeFunctionPressure, DisplacementDim>::
1462 assembleWithJacobianForDeformationEquations(
1463 const double /*t*/, double const /*dt*/,
1464 Eigen::VectorXd const& /*local_x*/,
1465 Eigen::VectorXd const& /*local_x_prev*/,
1466 std::vector<double>& /*local_b_data*/,
1467 std::vector<double>& /*local_Jac_data*/)
1468{
1469 OGS_FATAL("RichardsMechanics; The staggered scheme is not implemented.");
1470}
1471
1472template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
1473 int DisplacementDim>
1474void RichardsMechanicsLocalAssembler<ShapeFunctionDisplacement,
1475 ShapeFunctionPressure, DisplacementDim>::
1476 assembleWithJacobianForStaggeredScheme(double const t, double const dt,
1477 Eigen::VectorXd const& local_x,
1478 Eigen::VectorXd const& local_x_prev,
1479 int const process_id,
1480 std::vector<double>& local_b_data,
1481 std::vector<double>& local_Jac_data)
1482{
1483 // For the equations with pressure
1484 if (process_id == 0)
1485 {
1486 assembleWithJacobianForPressureEquations(t, dt, local_x, local_x_prev,
1487 local_b_data, local_Jac_data);
1488 return;
1489 }
1490
1491 // For the equations with deformation
1492 assembleWithJacobianForDeformationEquations(t, dt, local_x, local_x_prev,
1493 local_b_data, local_Jac_data);
1494}
1495
1496template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
1497 int DisplacementDim>
1498void RichardsMechanicsLocalAssembler<ShapeFunctionDisplacement,
1499 ShapeFunctionPressure, DisplacementDim>::
1500 computeSecondaryVariableConcrete(double const t, double const dt,
1501 Eigen::VectorXd const& local_x,
1502 Eigen::VectorXd const& local_x_prev)
1503{
1504 auto const [p_L, u] = localDOF(local_x);
1505 auto const [p_L_prev, u_prev] = localDOF(local_x_prev);
1506
1507 auto const& identity2 = MathLib::KelvinVector::Invariants<
1509 DisplacementDim)>::identity2;
1510
1511 auto const& medium =
1512 this->process_data_.media_map.getMedium(this->element_.getID());
1513 auto const& liquid_phase = medium->phase("AqueousLiquid");
1514 auto const& solid_phase = medium->phase("Solid");
1515 MPL::VariableArray variables;
1516 MPL::VariableArray variables_prev;
1517
1519 x_position.setElementID(this->element_.getID());
1520
1521 unsigned const n_integration_points =
1522 this->integration_method_.getNumberOfPoints();
1523
1524 double saturation_avg = 0;
1525 double porosity_avg = 0;
1526
1528 KV sigma_avg = KV::Zero();
1529
1530 for (unsigned ip = 0; ip < n_integration_points; ip++)
1531 {
1532 auto const& N_p = _ip_data[ip].N_p;
1533 auto const& N_u = _ip_data[ip].N_u;
1534 auto const& dNdx_u = _ip_data[ip].dNdx_u;
1535
1536 auto const x_coord =
1537 NumLib::interpolateXCoordinate<ShapeFunctionDisplacement,
1539 this->element_, N_u);
1540 auto const B =
1541 LinearBMatrix::computeBMatrix<DisplacementDim,
1542 ShapeFunctionDisplacement::NPOINTS,
1544 dNdx_u, N_u, x_coord, this->is_axially_symmetric_);
1545
1546 double p_cap_ip;
1547 NumLib::shapeFunctionInterpolate(-p_L, N_p, p_cap_ip);
1548
1549 double p_cap_prev_ip;
1550 NumLib::shapeFunctionInterpolate(-p_L_prev, N_p, p_cap_prev_ip);
1551
1552 variables.capillary_pressure = p_cap_ip;
1553 variables.liquid_phase_pressure = -p_cap_ip;
1554 // setting pG to 1 atm
1555 // TODO : rewrite equations s.t. p_L = pG-p_cap
1556 variables.gas_phase_pressure = 1.0e5;
1557
1558 auto const temperature =
1559 medium->property(MPL::PropertyType::reference_temperature)
1560 .template value<double>(variables, x_position, t, dt);
1561 variables.temperature = temperature;
1562
1563 auto& eps =
1564 std::get<StrainData<DisplacementDim>>(this->current_states_[ip])
1565 .eps;
1566 eps.noalias() = B * u;
1567 auto& S_L =
1568 std::get<ProcessLib::ThermoRichardsMechanics::SaturationData>(
1569 this->current_states_[ip])
1570 .S_L;
1571 auto const S_L_prev =
1572 std::get<
1574 this->prev_states_[ip])
1575 ->S_L;
1576 S_L = medium->property(MPL::PropertyType::saturation)
1577 .template value<double>(variables, x_position, t, dt);
1578 variables.liquid_saturation = S_L;
1579 variables_prev.liquid_saturation = S_L_prev;
1580
1581 auto const chi = [medium, x_position, t, dt](double const S_L)
1582 {
1584 vs.liquid_saturation = S_L;
1585 return medium->property(MPL::PropertyType::bishops_effective_stress)
1586 .template value<double>(vs, x_position, t, dt);
1587 };
1588 double const chi_S_L = chi(S_L);
1589 double const chi_S_L_prev = chi(S_L_prev);
1590
1591 auto const alpha =
1592 medium->property(MPL::PropertyType::biot_coefficient)
1593 .template value<double>(variables, x_position, t, dt);
1594
1595 auto const C_el = _ip_data[ip].computeElasticTangentStiffness(
1596 t, x_position, dt, temperature, this->solid_material_,
1597 *this->material_states_[ip].material_state_variables);
1598
1599 auto const beta_SR = (1 - alpha) / this->solid_material_.getBulkModulus(
1600 t, x_position, &C_el);
1601 variables.grain_compressibility = beta_SR;
1602
1603 variables.effective_pore_pressure = -chi_S_L * p_cap_ip;
1604 variables_prev.effective_pore_pressure = -chi_S_L_prev * p_cap_prev_ip;
1605
1606 // Set volumetric strain rate for the general case without swelling.
1607 variables.volumetric_strain = Invariants::trace(eps);
1608 variables_prev.volumetric_strain = Invariants::trace(B * u_prev);
1609
1610 auto& phi = std::get<ProcessLib::ThermoRichardsMechanics::PorosityData>(
1611 this->current_states_[ip])
1612 .phi;
1613 { // Porosity update
1614 auto const phi_prev = std::get<PrevState<
1616 this->prev_states_[ip])
1617 ->phi;
1618 variables_prev.porosity = phi_prev;
1619 phi = medium->property(MPL::PropertyType::porosity)
1620 .template value<double>(variables, variables_prev,
1621 x_position, t, dt);
1622 variables.porosity = phi;
1623 }
1624
1625 auto const rho_LR =
1626 liquid_phase.property(MPL::PropertyType::density)
1627 .template value<double>(variables, x_position, t, dt);
1628 variables.density = rho_LR;
1629 auto const mu =
1630 liquid_phase.property(MPL::PropertyType::viscosity)
1631 .template value<double>(variables, x_position, t, dt);
1632
1633 {
1634 // Swelling and possibly volumetric strain rate update.
1635 auto& sigma_sw =
1636 std::get<ProcessLib::ThermoRichardsMechanics::
1637 ConstitutiveStress_StrainTemperature::
1638 SwellingDataStateful<DisplacementDim>>(
1639 this->current_states_[ip]);
1640 auto const& sigma_sw_prev = std::get<
1641 PrevState<ProcessLib::ThermoRichardsMechanics::
1642 ConstitutiveStress_StrainTemperature::
1643 SwellingDataStateful<DisplacementDim>>>(
1644 this->prev_states_[ip]);
1645 auto const transport_porosity_prev = std::get<PrevState<
1647 this->prev_states_[ip]);
1648 auto const phi_prev = std::get<
1650 this->prev_states_[ip]);
1651 auto& transport_porosity = std::get<
1653 this->current_states_[ip]);
1654 auto& p_L_m = std::get<MicroPressure>(this->current_states_[ip]);
1655 auto const p_L_m_prev =
1656 std::get<PrevState<MicroPressure>>(this->prev_states_[ip]);
1657 auto& S_L_m = std::get<MicroSaturation>(this->current_states_[ip]);
1658 auto const S_L_m_prev =
1659 std::get<PrevState<MicroSaturation>>(this->prev_states_[ip]);
1660
1662 *medium, solid_phase, C_el, rho_LR, mu,
1663 this->process_data_.micro_porosity_parameters, alpha, phi,
1664 p_cap_ip, variables, variables_prev, x_position, t, dt,
1665 sigma_sw, sigma_sw_prev, transport_porosity_prev, phi_prev,
1666 transport_porosity, p_L_m_prev, S_L_m_prev, p_L_m, S_L_m);
1667 }
1668
1669 if (medium->hasProperty(MPL::PropertyType::transport_porosity))
1670 {
1671 if (!medium->hasProperty(MPL::PropertyType::saturation_micro))
1672 {
1673 auto& transport_porosity =
1674 std::get<ProcessLib::ThermoRichardsMechanics::
1675 TransportPorosityData>(
1676 this->current_states_[ip])
1677 .phi;
1678 auto const transport_porosity_prev =
1679 std::get<PrevState<ProcessLib::ThermoRichardsMechanics::
1680 TransportPorosityData>>(
1681 this->prev_states_[ip])
1682 ->phi;
1683
1684 variables_prev.transport_porosity = transport_porosity_prev;
1685
1686 transport_porosity =
1687 medium->property(MPL::PropertyType::transport_porosity)
1688 .template value<double>(variables, variables_prev,
1689 x_position, t, dt);
1690 variables.transport_porosity = transport_porosity;
1691 }
1692 }
1693 else
1694 {
1695 variables.transport_porosity = phi;
1696 }
1697
1698 auto const& sigma_eff =
1700 DisplacementDim>>(this->current_states_[ip])
1701 .sigma_eff;
1702
1703 // Set mechanical variables for the intrinsic permeability model
1704 // For stress dependent permeability.
1705 {
1706 auto const sigma_total =
1707 (sigma_eff + alpha * chi_S_L * identity2 * p_cap_ip).eval();
1708 // For stress dependent permeability.
1709 variables.total_stress.emplace<SymmetricTensor>(
1711 sigma_total));
1712 }
1713
1714 variables.equivalent_plastic_strain =
1715 this->material_states_[ip]
1716 .material_state_variables->getEquivalentPlasticStrain();
1717
1718 auto const K_intrinsic = MPL::formEigenTensor<DisplacementDim>(
1719 medium->property(MPL::PropertyType::permeability)
1720 .value(variables, x_position, t, dt));
1721
1722 double const k_rel =
1723 medium->property(MPL::PropertyType::relative_permeability)
1724 .template value<double>(variables, x_position, t, dt);
1725
1726 GlobalDimMatrixType const K_over_mu = k_rel * K_intrinsic / mu;
1727
1728 double const p_FR = -chi_S_L * p_cap_ip;
1729 // p_SR
1730 variables.solid_grain_pressure =
1731 p_FR - sigma_eff.dot(identity2) / (3 * (1 - phi));
1732 auto const rho_SR =
1733 solid_phase.property(MPL::PropertyType::density)
1734 .template value<double>(variables, x_position, t, dt);
1735 *std::get<DrySolidDensity>(this->output_data_[ip]) = (1 - phi) * rho_SR;
1736
1737 {
1738 auto& SD = this->current_states_[ip];
1739 auto const& sigma_sw =
1740 std::get<ProcessLib::ThermoRichardsMechanics::
1741 ConstitutiveStress_StrainTemperature::
1742 SwellingDataStateful<DisplacementDim>>(SD)
1743 .sigma_sw;
1744 auto& eps_m =
1745 std::get<ProcessLib::ConstitutiveRelations::
1746 MechanicalStrainData<DisplacementDim>>(SD)
1747 .eps_m;
1748 eps_m.noalias() =
1749 solid_phase.hasProperty(MPL::PropertyType::swelling_stress_rate)
1750 ? eps + C_el.inverse() * sigma_sw
1751 : eps;
1752 variables.mechanical_strain.emplace<
1754 eps_m);
1755 }
1756
1757 {
1758 auto& SD = this->current_states_[ip];
1759 auto const& SD_prev = this->prev_states_[ip];
1760 auto& sigma_eff =
1762 DisplacementDim>>(SD);
1763 auto const& sigma_eff_prev =
1764 std::get<PrevState<ProcessLib::ConstitutiveRelations::
1765 EffectiveStressData<DisplacementDim>>>(
1766 SD_prev);
1767 auto const& eps_m =
1768 std::get<ProcessLib::ConstitutiveRelations::
1769 MechanicalStrainData<DisplacementDim>>(SD);
1770 auto const& eps_m_prev =
1771 std::get<PrevState<ProcessLib::ConstitutiveRelations::
1772 MechanicalStrainData<DisplacementDim>>>(
1773 SD_prev);
1774
1775 _ip_data[ip].updateConstitutiveRelation(
1776 variables, t, x_position, dt, temperature, sigma_eff,
1777 sigma_eff_prev, eps_m, eps_m_prev, this->solid_material_,
1778 this->material_states_[ip].material_state_variables);
1779 }
1780
1781 auto const& b = this->process_data_.specific_body_force;
1782
1783 // Compute the velocity
1784 auto const& dNdx_p = _ip_data[ip].dNdx_p;
1785 std::get<
1787 this->output_data_[ip])
1788 ->noalias() = -K_over_mu * dNdx_p * p_L + rho_LR * K_over_mu * b;
1789
1790 saturation_avg += S_L;
1791 porosity_avg += phi;
1792 sigma_avg += sigma_eff;
1793 }
1794 saturation_avg /= n_integration_points;
1795 porosity_avg /= n_integration_points;
1796 sigma_avg /= n_integration_points;
1797
1798 (*this->process_data_.element_saturation)[this->element_.getID()] =
1799 saturation_avg;
1800 (*this->process_data_.element_porosity)[this->element_.getID()] =
1801 porosity_avg;
1802
1803 Eigen::Map<KV>(
1804 &(*this->process_data_.element_stresses)[this->element_.getID() *
1805 KV::RowsAtCompileTime]) =
1807
1809 ShapeFunctionPressure, typename ShapeFunctionDisplacement::MeshElement,
1810 DisplacementDim>(this->element_, this->is_axially_symmetric_, p_L,
1811 *this->process_data_.pressure_interpolated);
1812}
1813} // namespace RichardsMechanics
1814} // namespace ProcessLib
#define OGS_FATAL(...)
Definition Error.h:26
Phase const & phase(std::size_t index) const
Definition Medium.cpp:33
Property const & property(PropertyType const &p) const
Definition Medium.cpp:54
bool hasProperty(PropertyType const &p) const
Definition Medium.cpp:70
Property const & property(PropertyType const &p) const
Definition Phase.cpp:53
bool hasProperty(PropertyType const &p) const
Definition Phase.cpp:69
virtual PropertyDataType value() const
Definition Property.cpp:76
std::optional< std::size_t > getElementID() const
void setElementID(std::size_t element_id)
MatrixType< _kelvin_vector_size, _number_of_dof > BMatrixType
Eigen::Matrix< double, KelvinVectorSize, 1 > SymmetricTensor
typename ShapeMatricesTypePressure::GlobalDimMatrixType GlobalDimMatrixType
template Eigen::Matrix< double, 3, 3 > formEigenTensor< 3 >(MaterialPropertyLib::PropertyDataType const &values)
Eigen::Matrix< double, GlobalDim, GlobalDim > formEigenTensor(MaterialPropertyLib::PropertyDataType const &values)
Eigen::Matrix< double, 4, 1 > kelvinVectorToSymmetricTensor(Eigen::Matrix< double, 4, 1, Eigen::ColMajor, 4, 1 > const &v)
constexpr int kelvin_vector_dimensions(int const displacement_dim)
Kelvin vector dimensions for given displacement dimension.
Eigen::Matrix< double, kelvin_vector_dimensions(DisplacementDim), 1, Eigen::ColMajor > KelvinVectorType
KelvinVectorType< DisplacementDim > tensorToKelvin(Eigen::Matrix< double, 3, 3 > const &m)
Eigen::Matrix< double, kelvin_vector_dimensions(DisplacementDim), kelvin_vector_dimensions(DisplacementDim), Eigen::RowMajor > KelvinMatrixType
Eigen::Map< Vector > createZeroedVector(std::vector< double > &data, Eigen::VectorXd::Index size)
Eigen::Map< Matrix > createZeroedMatrix(std::vector< double > &data, Eigen::MatrixXd::Index rows, Eigen::MatrixXd::Index cols)
void shapeFunctionInterpolate(const NodalValues &, const ShapeMatrix &)
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 computeBMatrix(DNDX_Type const &dNdx, N_Type const &N, const double radius, const bool is_axially_symmetric)
Fills a B-matrix based on given shape function dN/dx values.
void updateSwellingStressAndVolumetricStrain(MaterialPropertyLib::Medium const &medium, MaterialPropertyLib::Phase const &solid_phase, MathLib::KelvinVector::KelvinMatrixType< DisplacementDim > const &C_el, double const rho_LR, double const mu, std::optional< MicroPorosityParameters > micro_porosity_parameters, double const alpha, double const phi, double const p_cap_ip, MPL::VariableArray &variables, MPL::VariableArray &variables_prev, ParameterLib::SpatialPosition const &x_position, double const t, double const dt, ProcessLib::ThermoRichardsMechanics::ConstitutiveStress_StrainTemperature::SwellingDataStateful< DisplacementDim > &sigma_sw, PrevState< ProcessLib::ThermoRichardsMechanics::ConstitutiveStress_StrainTemperature::SwellingDataStateful< DisplacementDim > > const &sigma_sw_prev, PrevState< ProcessLib::ThermoRichardsMechanics::TransportPorosityData > const phi_M_prev, PrevState< ProcessLib::ThermoRichardsMechanics::PorosityData > const phi_prev, ProcessLib::ThermoRichardsMechanics::TransportPorosityData &phi_M, PrevState< MicroPressure > const p_L_m_prev, PrevState< MicroSaturation > const S_L_m_prev, MicroPressure &p_L_m, MicroSaturation &S_L_m)
ProcessLib::ConstitutiveRelations::PrevStateOf< StatefulData< DisplacementDim > > StatefulDataPrev
std::tuple< StrainData< DisplacementDim >, ProcessLib::ConstitutiveRelations::EffectiveStressData< DisplacementDim >, ProcessLib::ThermoRichardsMechanics::ConstitutiveStress_StrainTemperature:: SwellingDataStateful< DisplacementDim >, ProcessLib::ConstitutiveRelations::MechanicalStrainData< DisplacementDim >, ProcessLib::ThermoRichardsMechanics::SaturationData, ProcessLib::ThermoRichardsMechanics::PorosityData, ProcessLib::ThermoRichardsMechanics::TransportPorosityData, MicroPressure, MicroSaturation > StatefulData
Data whose state must be tracked by the process.
ConstitutiveModels< DisplacementDim > createConstitutiveModels(TRMProcessData const &process_data, MaterialLib::Solids::MechanicsBase< DisplacementDim > const &solid_material)
std::tuple< StiffnessTensor< DisplacementDim >, ProcessLib::ThermoRichardsMechanics::PorosityData, Density, LiquidDensity, ProcessLib::ThermoRichardsMechanics::BiotData, ProcessLib::ThermoRichardsMechanics::SaturationDataDeriv, ProcessLib::ThermoRichardsMechanics::LiquidViscosityData, ProcessLib::ThermoRichardsMechanics::SolidCompressibilityData, ProcessLib::ThermoRichardsMechanics::BishopsData, PrevState< ProcessLib::ThermoRichardsMechanics::BishopsData >, ProcessLib::ThermoRichardsMechanics::PermeabilityData< DisplacementDim >, SaturationSecantDerivative > ConstitutiveData
Data that is needed for the equation system assembly.
MicroPorosityStateSpace< DisplacementDim > computeMicroPorosity(MathLib::KelvinVector::KelvinVectorType< DisplacementDim > const &I_2_C_el_inverse, double const rho_LR_m, double const mu_LR, MicroPorosityParameters const &micro_porosity_parameters, double const alpha_B, double const phi, double const p_L, double const p_L_m_prev, MaterialPropertyLib::VariableArray const &, double const S_L_m_prev, double const phi_m_prev, ParameterLib::SpatialPosition const pos, double const t, double const dt, MaterialPropertyLib::Property const &saturation_micro, MaterialPropertyLib::Property const &swelling_stress_rate)
MatrixType< ShapeFunction::NPOINTS, ShapeFunction::NPOINTS > NodalMatrixType
VectorType< GlobalDim > GlobalDimVectorType
virtual double getBulkModulus(double const, ParameterLib::SpatialPosition const &, KelvinMatrix const *const =nullptr) const
MathLib::KelvinVector::KelvinVectorType< DisplacementDim > sigma_eff
Represents a previous state of type T.
Definition Base.h:21