OGS
TH2MFEM-impl.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
4#pragma once
5
6#include <Eigen/LU>
7
19#include "TH2MProcessData.h"
20
21namespace ProcessLib
22{
23namespace TH2M
24{
25namespace MPL = MaterialPropertyLib;
26
27template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
28 int DisplacementDim>
29TH2MLocalAssembler<ShapeFunctionDisplacement, ShapeFunctionPressure,
30 DisplacementDim>::
31 TH2MLocalAssembler(
32 MeshLib::Element const& e,
33 std::size_t const /*local_matrix_size*/,
34 NumLib::GenericIntegrationMethod const& integration_method,
35 bool const is_axially_symmetric,
37 : LocalAssemblerInterface<DisplacementDim>(
38 e, integration_method, is_axially_symmetric, process_data)
39{
40 unsigned const n_integration_points =
41 this->integration_method_.getNumberOfPoints();
42
43 _ip_data.resize(n_integration_points);
44 _secondary_data.N_u.resize(n_integration_points);
45
46 auto const shape_matrices_u =
47 NumLib::initShapeMatrices<ShapeFunctionDisplacement,
49 DisplacementDim>(e, is_axially_symmetric,
51
52 auto const shape_matrices_p =
53 NumLib::initShapeMatrices<ShapeFunctionPressure,
54 ShapeMatricesTypePressure, DisplacementDim>(
55 e, is_axially_symmetric, this->integration_method_);
56
57 for (unsigned ip = 0; ip < n_integration_points; ip++)
58 {
59 auto& ip_data = _ip_data[ip];
60 auto const& sm_u = shape_matrices_u[ip];
61 ip_data.integration_weight =
62 this->integration_method_.getWeightedPoint(ip).getWeight() *
63 sm_u.integralMeasure * sm_u.detJ;
64
65 ip_data.N_u = sm_u.N;
66 ip_data.dNdx_u = sm_u.dNdx;
67
68 ip_data.N_p = shape_matrices_p[ip].N;
69 ip_data.dNdx_p = shape_matrices_p[ip].dNdx;
70
71 _secondary_data.N_u[ip] = shape_matrices_u[ip].N;
72 }
73}
74
75template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
76 int DisplacementDim>
77std::tuple<
78 std::vector<ConstitutiveRelations::ConstitutiveData<DisplacementDim>>,
79 std::vector<ConstitutiveRelations::ConstitutiveTempData<DisplacementDim>>>
80TH2MLocalAssembler<ShapeFunctionDisplacement, ShapeFunctionPressure,
81 DisplacementDim>::
82 updateConstitutiveVariables(
83 Eigen::VectorXd const& local_x, Eigen::VectorXd const& local_x_prev,
84 double const t, double const dt,
86 models)
87{
88 [[maybe_unused]] auto const matrix_size =
91
92 assert(local_x.size() == matrix_size);
93
94 auto const gas_pressure =
95 local_x.template segment<gas_pressure_size>(gas_pressure_index);
96 auto const gas_pressure_prev =
97 local_x_prev.template segment<gas_pressure_size>(gas_pressure_index);
98 auto const capillary_pressure =
99 local_x.template segment<capillary_pressure_size>(
101 auto const capillary_pressure_prev =
102 local_x_prev.template segment<capillary_pressure_size>(
104
105 auto const temperature =
106 local_x.template segment<temperature_size>(temperature_index);
107 auto const temperature_prev =
108 local_x_prev.template segment<temperature_size>(temperature_index);
109
110 auto const displacement =
111 local_x.template segment<displacement_size>(displacement_index);
112 auto const displacement_prev =
113 local_x_prev.template segment<displacement_size>(displacement_index);
114
115 auto const& medium =
116 *this->process_data_.media_map.getMedium(this->element_.getID());
117 ConstitutiveRelations::MediaData media_data{medium};
118
119 unsigned const n_integration_points =
120 this->integration_method_.getNumberOfPoints();
121
122 std::vector<ConstitutiveRelations::ConstitutiveData<DisplacementDim>>
123 ip_constitutive_data(n_integration_points);
124 std::vector<ConstitutiveRelations::ConstitutiveTempData<DisplacementDim>>
125 ip_constitutive_variables(n_integration_points);
126
127 for (unsigned ip = 0; ip < n_integration_points; ip++)
128 {
129 auto& ip_data = _ip_data[ip];
130 auto& ip_cv = ip_constitutive_variables[ip];
131 auto& ip_cd = ip_constitutive_data[ip];
132 auto& ip_out = this->output_data_[ip];
133 auto& current_state = this->current_states_[ip];
134 auto& prev_state = this->prev_states_[ip];
135
136 auto const& Np = ip_data.N_p;
137 auto const& NT = Np;
138 auto const& Nu = ip_data.N_u;
139 auto const& gradNu = ip_data.dNdx_u;
140 auto const& gradNp = ip_data.dNdx_p;
142 std::nullopt, this->element_.getID(),
144 NumLib::interpolateCoordinates<ShapeFunctionDisplacement,
146 this->element_, Nu))};
147
148 auto const x_coord =
149 pos.getCoordinates().value()[0]; // r for axisymmetry
150
151 double const T = NT.dot(temperature);
152 double const T_prev = NT.dot(temperature_prev);
153 double const pG = Np.dot(gas_pressure);
154 double const pG_prev = Np.dot(gas_pressure_prev);
155 double const pCap = Np.dot(capillary_pressure);
156 double const pCap_prev = Np.dot(capillary_pressure_prev);
157 ConstitutiveRelations::TemperatureData const T_data{T, T_prev};
158 ConstitutiveRelations::GasPressureData const pGR_data{pG, pG_prev};
160 pCap_prev};
162 grad_p_GR{gradNp * gas_pressure};
164 DisplacementDim> const grad_p_cap{gradNp * capillary_pressure};
166 grad_T{gradNp * temperature};
167
168 // medium properties
169 models.elastic_tangent_stiffness_model.eval({pos, t, dt}, T_data,
170 ip_cv.C_el_data);
171
172 models.biot_model.eval({pos, t, dt}, media_data, ip_cv.biot_data);
173
174 auto const Bu =
175 LinearBMatrix::computeBMatrix<DisplacementDim,
176 ShapeFunctionDisplacement::NPOINTS,
178 gradNu, Nu, x_coord, this->is_axially_symmetric_);
179
180 ip_out.eps_data.eps.noalias() = Bu * displacement;
181 models.S_L_model.eval({pos, t, dt}, media_data, pCap_data,
182 current_state.S_L_data);
183
184 models.chi_S_L_model.eval({pos, t, dt}, media_data,
185 current_state.S_L_data,
186 current_state.chi_S_L);
187
188 models.chi_S_L_prev_model.eval({pos, t, dt}, media_data,
189 prev_state.S_L_data, prev_state.chi_S_L);
190
191 // solid phase compressibility
192 models.beta_p_SR_model.eval({pos, t, dt}, ip_cv.biot_data,
193 ip_cv.C_el_data, ip_cv.beta_p_SR);
194
195 // If there is swelling stress rate, compute swelling stress.
196 models.swelling_model.eval(
197 {pos, t, dt}, media_data, ip_cv.C_el_data, current_state.S_L_data,
198 prev_state.S_L_data, prev_state.swelling_data,
199 current_state.swelling_data, ip_cv.swelling_data);
200
201 // solid phase linear thermal expansion coefficient
202 models.s_therm_exp_model.eval({pos, t, dt}, media_data,
203 ip_cv.s_therm_exp_data);
204
205 models.mechanical_strain_model.eval(
206 T_data, ip_cv.s_therm_exp_data, ip_out.eps_data,
207 Bu * displacement_prev, prev_state.mechanical_strain_data,
208 ip_cv.swelling_data, current_state.mechanical_strain_data);
209
210 models.s_mech_model.eval(
211 {pos, t, dt}, T_data, current_state.mechanical_strain_data,
212 prev_state.mechanical_strain_data, prev_state.eff_stress_data,
213 current_state.eff_stress_data, this->material_states_[ip],
214 ip_cd.s_mech_data, ip_cv.equivalent_plastic_strain_data);
215
216 models.total_stress_model.eval(current_state.eff_stress_data,
217 ip_cv.biot_data, current_state.chi_S_L,
218 pGR_data, pCap_data,
219 ip_out.total_stress_data);
220
221 models.pure_liquid_density_model.eval({pos, t, dt}, media_data,
222 pGR_data, pCap_data, T_data,
223 current_state.rho_W_LR);
224
226 {pos, t, dt}, media_data, pGR_data, pCap_data, T_data,
227 current_state.rho_W_LR, ip_out.fluid_enthalpy_data,
228 ip_out.mass_mole_fractions_data, ip_out.fluid_density_data,
229 ip_out.vapour_pressure_data, current_state.constituent_density_data,
230 ip_cv.phase_transition_data);
231
232 models.viscosity_model.eval({pos, t, dt}, media_data, T_data,
233 ip_out.mass_mole_fractions_data,
234 ip_cv.viscosity_data);
235
236 models.porosity_model.eval(
237 {pos, t, dt}, media_data, current_state.S_L_data,
238 prev_state.S_L_data, pCap_data, pGR_data, current_state.chi_S_L,
239 prev_state.chi_S_L, ip_cv.beta_p_SR, ip_out.eps_data,
240 Bu * displacement_prev, prev_state.porosity_data,
241 current_state.porosity_data);
242
243 if (medium.hasProperty(MPL::PropertyType::transport_porosity))
244 {
245 models.transport_porosity_model.eval(
246 {pos, t, dt}, media_data, current_state.S_L_data,
247 prev_state.S_L_data, pCap_data, pGR_data, current_state.chi_S_L,
248 prev_state.chi_S_L, ip_cv.beta_p_SR,
249 current_state.mechanical_strain_data,
250 prev_state.mechanical_strain_data,
251 prev_state.transport_porosity_data, current_state.porosity_data,
252 current_state.transport_porosity_data);
253 }
254 else
255 {
256 current_state.transport_porosity_data.phi =
257 current_state.porosity_data.phi;
258 }
259
260 models.permeability_model.eval(
261 {pos, t, dt}, media_data, current_state.S_L_data, pGR_data,
262 pCap_data, T_data, current_state.transport_porosity_data,
263 ip_out.total_stress_data, current_state.mechanical_strain_data,
264 ip_out.eps_data, ip_cv.equivalent_plastic_strain_data,
265 ip_out.permeability_data);
266
267 models.solid_density_model.eval(
268 {pos, t, dt}, media_data, T_data, current_state.eff_stress_data,
269 pCap_data, pGR_data, current_state.chi_S_L,
270 current_state.porosity_data, ip_out.solid_density_data);
271
272 models.solid_heat_capacity_model.eval({pos, t, dt}, media_data, T_data,
273 ip_cv.solid_heat_capacity_data);
274
275 models.thermal_conductivity_model.eval(
276 {pos, t, dt}, media_data, T_data, current_state.porosity_data,
277 current_state.S_L_data, ip_cv.thermal_conductivity_data);
278
279 models.advection_model.eval(current_state.constituent_density_data,
280 ip_out.permeability_data,
281 current_state.rho_W_LR,
282 ip_cv.viscosity_data,
283 ip_cv.advection_data);
284
285 models.gravity_model.eval(
286 ip_out.fluid_density_data,
287 current_state.porosity_data,
288 current_state.S_L_data,
289 ip_out.solid_density_data,
291 this->process_data_.specific_body_force),
292 ip_cv.volumetric_body_force);
293
294 models.diffusion_velocity_model.eval(grad_p_cap,
295 grad_p_GR,
296 ip_out.mass_mole_fractions_data,
297 ip_cv.phase_transition_data,
298 current_state.porosity_data,
299 current_state.S_L_data,
300 grad_T,
301 ip_out.diffusion_velocity_data);
302
303 models.solid_enthalpy_model.eval(ip_cv.solid_heat_capacity_data, T_data,
304 ip_out.solid_enthalpy_data);
305
306 models.internal_energy_model.eval(ip_out.fluid_density_data,
307 ip_cv.phase_transition_data,
308 current_state.porosity_data,
309 current_state.S_L_data,
310 ip_out.solid_density_data,
311 ip_out.solid_enthalpy_data,
312 current_state.internal_energy_data);
313
315 ip_out.fluid_density_data,
316 ip_out.fluid_enthalpy_data,
317 current_state.porosity_data,
318 current_state.S_L_data,
319 ip_out.solid_density_data,
320 ip_out.solid_enthalpy_data,
321 ip_cv.effective_volumetric_enthalpy_data);
322
323 models.fC_1_model.eval(ip_cv.advection_data, ip_out.fluid_density_data,
324 ip_cv.fC_1);
325
326 if (!this->process_data_.apply_mass_lumping)
327 {
328 models.fC_2a_model.eval(ip_cv.biot_data,
329 pCap_data,
330 current_state.constituent_density_data,
331 current_state.porosity_data,
332 current_state.S_L_data,
333 ip_cv.beta_p_SR,
334 ip_cv.fC_2a);
335 }
336 models.fC_3a_model.eval(dt,
337 current_state.constituent_density_data,
338 prev_state.constituent_density_data,
339 current_state.S_L_data,
340 ip_cv.fC_3a);
341
342 models.fC_4_LCpG_model.eval(ip_cv.advection_data,
343 ip_out.fluid_density_data,
344 ip_cv.phase_transition_data,
345 current_state.porosity_data,
346 current_state.S_L_data,
347 ip_cv.fC_4_LCpG);
348
349 models.fC_4_LCpC_model.eval(ip_cv.advection_data,
350 ip_out.fluid_density_data,
351 ip_cv.phase_transition_data,
352 current_state.porosity_data,
353 current_state.S_L_data,
354 ip_cv.fC_4_LCpC);
355
356 models.fC_4_LCT_model.eval(ip_out.fluid_density_data,
357 ip_cv.phase_transition_data,
358 current_state.porosity_data,
359 current_state.S_L_data,
360 ip_cv.fC_4_LCT);
361
362 models.fC_4_MCpG_model.eval(ip_cv.biot_data,
363 current_state.constituent_density_data,
364 current_state.porosity_data,
365 current_state.S_L_data,
366 ip_cv.beta_p_SR,
367 ip_cv.fC_4_MCpG);
368
369 models.fC_4_MCpC_model.eval(ip_cv.biot_data,
370 pCap_data,
371 current_state.constituent_density_data,
372 current_state.porosity_data,
373 prev_state.S_L_data,
374 current_state.S_L_data,
375 ip_cv.beta_p_SR,
376 ip_cv.fC_4_MCpC);
377
378 models.fC_4_MCT_model.eval(ip_cv.biot_data,
379 current_state.constituent_density_data,
380 current_state.porosity_data,
381 current_state.S_L_data,
382 ip_cv.s_therm_exp_data,
383 ip_cv.fC_4_MCT);
384
385 models.fC_4_MCu_model.eval(ip_cv.biot_data,
386 current_state.constituent_density_data,
387 current_state.S_L_data,
388 ip_cv.fC_4_MCu);
389
390 models.fW_1_model.eval(ip_cv.advection_data, ip_out.fluid_density_data,
391 ip_cv.fW_1);
392
393 if (!this->process_data_.apply_mass_lumping)
394 {
395 models.fW_2_model.eval(ip_cv.biot_data,
396 pCap_data,
397 current_state.constituent_density_data,
398 current_state.porosity_data,
399 current_state.rho_W_LR,
400 current_state.S_L_data,
401 ip_cv.beta_p_SR,
402 ip_cv.fW_2);
403 }
404 models.fW_3a_model.eval(dt,
405 current_state.constituent_density_data,
406 prev_state.constituent_density_data,
407 prev_state.rho_W_LR,
408 current_state.rho_W_LR,
409 current_state.S_L_data,
410 ip_cv.fW_3a);
411
412 models.fW_4_LWpG_model.eval(ip_cv.advection_data,
413 ip_out.fluid_density_data,
414 ip_cv.phase_transition_data,
415 current_state.porosity_data,
416 current_state.S_L_data,
417 ip_cv.fW_4_LWpG);
418
419 models.fW_4_LWpC_model.eval(ip_cv.advection_data,
420 ip_out.fluid_density_data,
421 ip_cv.phase_transition_data,
422 current_state.porosity_data,
423 current_state.S_L_data,
424 ip_cv.fW_4_LWpC);
425
426 models.fW_4_LWT_model.eval(ip_out.fluid_density_data,
427 ip_cv.phase_transition_data,
428 current_state.porosity_data,
429 current_state.S_L_data,
430 ip_cv.fW_4_LWT);
431
432 models.fW_4_MWpG_model.eval(ip_cv.biot_data,
433 current_state.constituent_density_data,
434 current_state.porosity_data,
435 current_state.rho_W_LR,
436 current_state.S_L_data,
437 ip_cv.beta_p_SR,
438 ip_cv.fW_4_MWpG);
439
440 models.fW_4_MWpC_model.eval(ip_cv.biot_data,
441 pCap_data,
442 current_state.constituent_density_data,
443 current_state.porosity_data,
444 prev_state.S_L_data,
445 current_state.rho_W_LR,
446 current_state.S_L_data,
447 ip_cv.beta_p_SR,
448 ip_cv.fW_4_MWpC);
449
450 models.fW_4_MWT_model.eval(ip_cv.biot_data,
451 current_state.constituent_density_data,
452 current_state.porosity_data,
453 current_state.rho_W_LR,
454 current_state.S_L_data,
455 ip_cv.s_therm_exp_data,
456 ip_cv.fW_4_MWT);
457
458 models.fW_4_MWu_model.eval(ip_cv.biot_data,
459 current_state.constituent_density_data,
460 current_state.rho_W_LR,
461 current_state.S_L_data,
462 ip_cv.fW_4_MWu);
463
464 models.fT_1_model.eval(dt,
465 current_state.internal_energy_data,
466 prev_state.internal_energy_data,
467 ip_cv.fT_1);
468
469 // ---------------------------------------------------------------------
470 // Derivatives for Jacobian
471 // ---------------------------------------------------------------------
472
473 models.darcy_velocity_model.eval(
474 grad_p_cap,
475 ip_out.fluid_density_data,
476 grad_p_GR,
477 ip_out.permeability_data,
479 this->process_data_.specific_body_force),
480 ip_cv.viscosity_data,
481 ip_out.darcy_velocity_data);
482
483 models.fT_2_model.eval(ip_out.darcy_velocity_data,
484 ip_out.fluid_density_data,
485 ip_out.fluid_enthalpy_data,
486 ip_cv.fT_2);
487
488 models.fT_3_model.eval(
489 current_state.constituent_density_data,
490 ip_out.darcy_velocity_data,
491 ip_out.diffusion_velocity_data,
492 ip_out.fluid_density_data,
493 ip_cv.phase_transition_data,
495 this->process_data_.specific_body_force),
496 ip_cv.fT_3);
497
498 models.fu_2_KupC_model.eval(ip_cv.biot_data, current_state.chi_S_L,
499 ip_cv.fu_2_KupC);
500 }
501
502 return {ip_constitutive_data, ip_constitutive_variables};
503}
504
505template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
506 int DisplacementDim>
507std::vector<ConstitutiveRelations::DerivativesData<DisplacementDim>>
508TH2MLocalAssembler<ShapeFunctionDisplacement, ShapeFunctionPressure,
509 DisplacementDim>::
510 updateConstitutiveVariablesDerivatives(
511 Eigen::VectorXd const& local_x, Eigen::VectorXd const& local_x_prev,
512 double const t, double const dt,
513 std::vector<
515 ip_constitutive_data,
516 std::vector<
518 ip_constitutive_variables,
520 models)
521{
522 [[maybe_unused]] auto const matrix_size =
525
526 assert(local_x.size() == matrix_size);
527
528 auto const gas_pressure =
529 local_x.template segment<gas_pressure_size>(gas_pressure_index);
530 auto const gas_pressure_prev =
531 local_x_prev.template segment<gas_pressure_size>(gas_pressure_index);
532 auto const temperature =
533 local_x.template segment<temperature_size>(temperature_index);
534 auto const temperature_prev =
535 local_x_prev.template segment<temperature_size>(temperature_index);
536 auto const displacement_prev =
537 local_x_prev.template segment<displacement_size>(displacement_index);
538
539 auto const capillary_pressure =
540 local_x.template segment<capillary_pressure_size>(
542 auto const capillary_pressure_prev =
543 local_x_prev.template segment<capillary_pressure_size>(
545
546 auto const& medium =
547 *this->process_data_.media_map.getMedium(this->element_.getID());
548 ConstitutiveRelations::MediaData media_data{medium};
549
550 unsigned const n_integration_points =
551 this->integration_method_.getNumberOfPoints();
552
553 std::vector<ConstitutiveRelations::DerivativesData<DisplacementDim>>
554 ip_d_data(n_integration_points);
555
556 for (unsigned ip = 0; ip < n_integration_points; ip++)
557 {
558 auto const& ip_data = _ip_data[ip];
559 auto& ip_dd = ip_d_data[ip];
560 auto const& ip_cd = ip_constitutive_data[ip];
561 auto const& ip_cv = ip_constitutive_variables[ip];
562 auto const& ip_out = this->output_data_[ip];
563 auto const& current_state = this->current_states_[ip];
564 auto const& prev_state = this->prev_states_[ip];
565
566 auto const& Nu = ip_data.N_u;
567 auto const& Np = ip_data.N_p;
568 auto const& NT = Np;
569 auto const& gradNu = ip_data.dNdx_u;
570
572 std::nullopt, this->element_.getID(),
574 NumLib::interpolateCoordinates<ShapeFunctionDisplacement,
576 this->element_, Nu))};
577
578 auto const x_coord = pos.getCoordinates().value()[0];
579
580 double const T = NT.dot(temperature);
581 double const T_prev = NT.dot(temperature_prev);
582 double const pG = Np.dot(gas_pressure);
583 double const pG_prev = Np.dot(gas_pressure_prev);
584 double const pCap = Np.dot(capillary_pressure);
585 double const pCap_prev = Np.dot(capillary_pressure_prev);
586 ConstitutiveRelations::TemperatureData const T_data{T, T_prev};
587 ConstitutiveRelations::GasPressureData const pGR_data{pG, pG_prev};
589 pCap_prev};
590
591 auto const Bu =
592 LinearBMatrix::computeBMatrix<DisplacementDim,
593 ShapeFunctionDisplacement::NPOINTS,
595 gradNu, Nu, x_coord, this->is_axially_symmetric_);
596
597 models.S_L_model.dEval({pos, t, dt}, media_data, pCap_data,
598 ip_dd.dS_L_dp_cap);
599
600 models.advection_model.dEval(current_state.constituent_density_data,
601 ip_out.permeability_data,
602 ip_cv.viscosity_data,
603 ip_dd.dS_L_dp_cap,
604 ip_cv.phase_transition_data,
605 ip_dd.advection_d_data);
606
607 models.porosity_model.dEval(
608 {pos, t, dt}, media_data, current_state.S_L_data,
609 prev_state.S_L_data, pCap_data, pGR_data, current_state.chi_S_L,
610 prev_state.chi_S_L, ip_cv.beta_p_SR, ip_out.eps_data,
611 Bu * displacement_prev, prev_state.porosity_data,
612 ip_dd.porosity_d_data);
613
614 models.thermal_conductivity_model.dEval(
615 {pos, t, dt}, media_data, T_data, current_state.porosity_data,
616 ip_dd.porosity_d_data, current_state.S_L_data,
617 ip_dd.thermal_conductivity_d_data);
618
619 models.solid_density_model.dEval(
620 {pos, t, dt}, media_data, T_data, current_state.eff_stress_data,
621 pCap_data, pGR_data, current_state.chi_S_L,
622 current_state.porosity_data, ip_dd.solid_density_d_data);
623
625 ip_out.fluid_density_data,
626 ip_cv.phase_transition_data,
627 current_state.porosity_data,
628 ip_dd.porosity_d_data,
629 current_state.S_L_data,
630 ip_out.solid_density_data,
631 ip_dd.solid_density_d_data,
632 ip_out.solid_enthalpy_data,
633 ip_cv.solid_heat_capacity_data,
634 ip_dd.effective_volumetric_internal_energy_d_data);
635
637 ip_out.fluid_density_data,
638 ip_out.fluid_enthalpy_data,
639 ip_cv.phase_transition_data,
640 current_state.porosity_data,
641 ip_dd.porosity_d_data,
642 current_state.S_L_data,
643 ip_out.solid_density_data,
644 ip_dd.solid_density_d_data,
645 ip_out.solid_enthalpy_data,
646 ip_cv.solid_heat_capacity_data,
647 ip_dd.effective_volumetric_enthalpy_d_data);
648 if (!this->process_data_.apply_mass_lumping)
649 {
650 models.fC_2a_model.dEval(ip_cv.biot_data,
651 pCap_data,
652 current_state.constituent_density_data,
653 ip_cv.phase_transition_data,
654 current_state.porosity_data,
655 ip_dd.porosity_d_data,
656 current_state.S_L_data,
657 ip_dd.dS_L_dp_cap,
658 ip_cv.beta_p_SR,
659 ip_dd.dfC_2a);
660 }
661 models.fC_3a_model.dEval(dt,
662 current_state.constituent_density_data,
663 prev_state.constituent_density_data,
664 ip_cv.phase_transition_data,
665 current_state.S_L_data,
666 ip_dd.dS_L_dp_cap,
667 ip_dd.dfC_3a);
668
669 models.fC_4_LCpG_model.dEval(ip_out.permeability_data,
670 ip_cv.viscosity_data,
671 ip_cv.phase_transition_data,
672 ip_dd.advection_d_data,
673 ip_dd.dfC_4_LCpG);
674
675 models.fC_4_LCpC_model.dEval(current_state.constituent_density_data,
676 ip_out.permeability_data,
677 ip_cv.phase_transition_data,
678 ip_dd.dS_L_dp_cap,
679 ip_cv.viscosity_data,
680 ip_dd.dfC_4_LCpC);
681
682 models.fC_4_MCpG_model.dEval(ip_cv.biot_data,
683 current_state.constituent_density_data,
684 ip_cv.phase_transition_data,
685 current_state.porosity_data,
686 ip_dd.porosity_d_data,
687 current_state.S_L_data,
688 ip_cv.beta_p_SR,
689 ip_dd.dfC_4_MCpG);
690
691 models.fC_4_MCT_model.dEval(ip_cv.biot_data,
692 current_state.constituent_density_data,
693 ip_cv.phase_transition_data,
694 current_state.porosity_data,
695 ip_dd.porosity_d_data,
696 current_state.S_L_data,
697 ip_cv.s_therm_exp_data,
698 ip_dd.dfC_4_MCT);
699
700 models.fC_4_MCu_model.dEval(ip_cv.biot_data,
701 ip_cv.phase_transition_data,
702 current_state.S_L_data,
703 ip_dd.dfC_4_MCu);
704
705 if (!this->process_data_.apply_mass_lumping)
706 {
707 models.fW_2_model.dEval(ip_cv.biot_data,
708 pCap_data,
709 current_state.constituent_density_data,
710 ip_cv.phase_transition_data,
711 current_state.porosity_data,
712 ip_dd.porosity_d_data,
713 current_state.rho_W_LR,
714 current_state.S_L_data,
715 ip_dd.dS_L_dp_cap,
716 ip_cv.beta_p_SR,
717 ip_dd.dfW_2);
718 }
719
720 models.fW_3a_model.dEval(dt,
721 current_state.constituent_density_data,
722 ip_cv.phase_transition_data,
723 prev_state.constituent_density_data,
724 prev_state.rho_W_LR,
725 current_state.rho_W_LR,
726 current_state.S_L_data,
727 ip_dd.dS_L_dp_cap,
728 ip_dd.dfW_3a);
729
730 models.fW_4_LWpG_model.dEval(current_state.constituent_density_data,
731 ip_out.permeability_data,
732 ip_cv.phase_transition_data,
733 current_state.rho_W_LR,
734 ip_dd.dS_L_dp_cap,
735 ip_cv.viscosity_data,
736 ip_dd.dfW_4_LWpG);
737
738 models.fW_4_LWpC_model.dEval(ip_cv.advection_data,
739 ip_out.fluid_density_data,
740 ip_out.permeability_data,
741 ip_cv.phase_transition_data,
742 current_state.porosity_data,
743 current_state.rho_W_LR,
744 current_state.S_L_data,
745 ip_dd.dS_L_dp_cap,
746 ip_cv.viscosity_data,
747 ip_dd.dfW_4_LWpC);
748
749 models.fT_1_model.dEval(
750 dt, ip_dd.effective_volumetric_internal_energy_d_data, ip_dd.dfT_1);
751
752 models.fT_2_model.dEval(
753 ip_out.darcy_velocity_data,
754 ip_out.fluid_density_data,
755 ip_out.fluid_enthalpy_data,
756 ip_out.permeability_data,
757 ip_cv.phase_transition_data,
759 this->process_data_.specific_body_force),
760 ip_cv.viscosity_data,
761 ip_dd.dfT_2);
762
763 models.fu_1_KuT_model.dEval(ip_cd.s_mech_data, ip_cv.s_therm_exp_data,
764 ip_dd.dfu_1_KuT);
765
766 models.fu_2_KupC_model.dEval(ip_cv.biot_data,
767 current_state.chi_S_L,
768 pCap_data,
769 ip_dd.dS_L_dp_cap,
770 ip_dd.dfu_2_KupC);
771 }
772
773 return ip_d_data;
774}
775
776template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
777 int DisplacementDim>
778std::size_t TH2MLocalAssembler<
779 ShapeFunctionDisplacement, ShapeFunctionPressure,
780 DisplacementDim>::setIPDataInitialConditions(std::string_view name,
781 double const* values,
782 int const integration_order)
783{
784 if (integration_order !=
785 static_cast<int>(this->integration_method_.getIntegrationOrder()))
786 {
787 OGS_FATAL(
788 "Setting integration point initial conditions; The integration "
789 "order of the local assembler for element {:d} is different "
790 "from the integration order in the initial condition.",
791 this->element_.getID());
792 }
793
794 if (name == "sigma" && this->process_data_.initial_stress.value)
795 {
796 OGS_FATAL(
797 "Setting initial conditions for stress from integration "
798 "point data and from a parameter '{:s}' is not possible "
799 "simultaneously.",
800 this->process_data_.initial_stress.value->name);
801 }
802
803 if (name.starts_with("material_state_variable_"))
804 {
805 name.remove_prefix(24);
806 DBUG("Setting material state variable '{:s}'", name);
807
808 auto const& internal_variables =
809 this->solid_material_.getInternalVariables();
810 if (auto const iv = std::find_if(
811 begin(internal_variables), end(internal_variables),
812 [&name](auto const& iv) { return iv.name == name; });
813 iv != end(internal_variables))
814 {
815 DBUG("Setting material state variable '{:s}'", name);
817 values, this->material_states_,
819 DisplacementDim>::material_state_variables,
820 iv->reference);
821 }
822
823 WARN(
824 "Could not find variable {:s} in solid material model's "
825 "internal variables.",
826 name);
827 return 0;
828 }
829
830 // TODO this logic could be pulled out of the local assembler into the
831 // process. That might lead to a slightly better performance due to less
832 // string comparisons.
834 name, values, this->current_states_);
835}
836
837template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
838 int DisplacementDim>
839void TH2MLocalAssembler<ShapeFunctionDisplacement, ShapeFunctionPressure,
840 DisplacementDim>::
841 setInitialConditionsConcrete(Eigen::VectorXd const local_x,
842 double const t,
843 int const /*process_id*/)
844{
845 [[maybe_unused]] auto const matrix_size =
848
849 assert(local_x.size() == matrix_size);
850
851 auto const capillary_pressure =
852 local_x.template segment<capillary_pressure_size>(
854
855 auto const p_GR =
856 local_x.template segment<gas_pressure_size>(gas_pressure_index);
857
858 auto const temperature =
859 local_x.template segment<temperature_size>(temperature_index);
860
861 auto const displacement =
862 local_x.template segment<displacement_size>(displacement_index);
863
864 auto const& medium =
865 *this->process_data_.media_map.getMedium(this->element_.getID());
866 auto const& solid_phase =
868
870 this->solid_material_, *this->process_data_.phase_transition_model_};
871
872 unsigned const n_integration_points =
873 this->integration_method_.getNumberOfPoints();
874
875 for (unsigned ip = 0; ip < n_integration_points; ip++)
876 {
878
879 auto& ip_data = _ip_data[ip];
880 auto& ip_out = this->output_data_[ip];
881 auto& prev_state = this->prev_states_[ip];
882 auto const& Np = ip_data.N_p;
883 auto const& NT = Np;
884 auto const& Nu = ip_data.N_u;
885 auto const& gradNu = ip_data.dNdx_u;
886
888 std::nullopt, this->element_.getID(),
890 NumLib::interpolateCoordinates<ShapeFunctionDisplacement,
892 this->element_, ip_data.N_u))};
893
894 auto const x_coord = pos.getCoordinates().value()[0];
895
896 double const pCap = Np.dot(capillary_pressure);
897 vars.capillary_pressure = pCap;
898
899 double const T = NT.dot(temperature);
901 T, T}; // T_prev = T in initialization.
902 vars.temperature = T;
903
904 auto const Bu =
905 LinearBMatrix::computeBMatrix<DisplacementDim,
906 ShapeFunctionDisplacement::NPOINTS,
908 gradNu, Nu, x_coord, this->is_axially_symmetric_);
909
910 auto& eps = ip_out.eps_data.eps;
911 eps.noalias() = Bu * displacement;
912
913 // Set volumetric strain rate for the general case without swelling.
915
916 double const S_L =
917 medium.property(MPL::PropertyType::saturation)
918 .template value<double>(
919 vars, pos, t, std::numeric_limits<double>::quiet_NaN());
920 this->prev_states_[ip].S_L_data->S_L = S_L;
921
922 // TODO (naumov) Double computation of C_el might be avoided if
923 // updateConstitutiveVariables is called before. But it might interfere
924 // with eps_m initialization.
926 C_el_data;
927 // dt = 0 at initialization: there is no time step yet, which yields
928 // the elastic tangent. Other property evaluations at initialization
929 // pass NaN for dt to keep initialization and integration strictly
930 // separated.
931 models.elastic_tangent_stiffness_model.eval({pos, t, 0.0 /*dt*/},
932 T_data, C_el_data);
933 auto const& C_el = C_el_data.stiffness_tensor;
934
935 // Set eps_m_prev from potentially non-zero eps and sigma_sw from
936 // restart.
937 auto const& sigma_sw = this->current_states_[ip].swelling_data.sigma_sw;
938 prev_state.mechanical_strain_data->eps_m.noalias() =
939 solid_phase.hasProperty(MPL::PropertyType::swelling_stress_rate)
940 ? eps + C_el.inverse() * sigma_sw
941 : eps;
942
943 if (this->process_data_.initial_stress.isTotalStress())
944 {
945 auto const alpha_b =
947 .template value<double>(vars, pos, t, 0.0 /*dt*/);
948
949 vars.liquid_saturation = S_L;
950 double const bishop =
952 .template value<double>(vars, pos, t, 0.0 /*dt*/);
953
954 this->current_states_[ip].eff_stress_data.sigma_eff.noalias() +=
955 alpha_b * Np.dot(p_GR - bishop * capillary_pressure) *
957 this->prev_states_[ip].eff_stress_data =
958 this->current_states_[ip].eff_stress_data;
959 }
960 }
961
962 // local_x_prev equal to local_x s.t. the local_x_dot is zero.
963 updateConstitutiveVariables(local_x, local_x, t, 0, models);
964
965 for (unsigned ip = 0; ip < n_integration_points; ip++)
966 {
967 this->material_states_[ip].pushBackState();
968 this->prev_states_[ip] = this->current_states_[ip];
969 }
970}
971
972template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
973 int DisplacementDim>
975 ShapeFunctionDisplacement, ShapeFunctionPressure,
976 DisplacementDim>::assemble(double const t, double const dt,
977 std::vector<double> const& local_x,
978 std::vector<double> const& local_x_prev,
979 std::vector<double>& local_M_data,
980 std::vector<double>& local_K_data,
981 std::vector<double>& local_rhs_data)
982{
983 auto const matrix_size = gas_pressure_size + capillary_pressure_size +
985 assert(local_x.size() == matrix_size);
986
987 auto const capillary_pressure =
988 Eigen::Map<VectorType<capillary_pressure_size> const>(
990
991 auto const capillary_pressure_prev =
992 Eigen::Map<VectorType<capillary_pressure_size> const>(
993 local_x_prev.data() + capillary_pressure_index,
995
996 // pointer to local_M_data vector
997 auto local_M =
999 local_M_data, matrix_size, matrix_size);
1000
1001 // pointer to local_K_data vector
1002 auto local_K =
1004 local_K_data, matrix_size, matrix_size);
1005
1006 // pointer to local_rhs_data vector
1008 local_rhs_data, matrix_size);
1009
1010 // component-formulation
1011 // W - liquid phase main component
1012 // C - gas phase main component
1013 // pointer-matrices to the mass matrix - C component equation
1014 auto MCpG = local_M.template block<C_size, gas_pressure_size>(
1016 auto MCpC = local_M.template block<C_size, capillary_pressure_size>(
1018 auto MCT = local_M.template block<C_size, temperature_size>(
1020 auto MCu = local_M.template block<C_size, displacement_size>(
1022
1023 // pointer-matrices to the stiffness matrix - C component equation
1024 auto LCpG = local_K.template block<C_size, gas_pressure_size>(
1026 auto LCpC = local_K.template block<C_size, capillary_pressure_size>(
1028 auto LCT = local_K.template block<C_size, temperature_size>(
1030
1031 // pointer-matrices to the mass matrix - W component equation
1032 auto MWpG = local_M.template block<W_size, gas_pressure_size>(
1034 auto MWpC = local_M.template block<W_size, capillary_pressure_size>(
1036 auto MWT = local_M.template block<W_size, temperature_size>(
1038 auto MWu = local_M.template block<W_size, displacement_size>(
1040
1041 // pointer-matrices to the stiffness matrix - W component equation
1042 auto LWpG = local_K.template block<W_size, gas_pressure_size>(
1044 auto LWpC = local_K.template block<W_size, capillary_pressure_size>(
1046 auto LWT = local_K.template block<W_size, temperature_size>(
1048
1049 // pointer-matrices to the mass matrix - temperature equation
1050 auto MTu = local_M.template block<temperature_size, displacement_size>(
1052
1053 // pointer-matrices to the stiffness matrix - temperature equation
1054 auto KTT = local_K.template block<temperature_size, temperature_size>(
1056
1057 // pointer-matrices to the stiffness matrix - displacement equation
1058 auto KUpG = local_K.template block<displacement_size, gas_pressure_size>(
1060 auto KUpC =
1061 local_K.template block<displacement_size, capillary_pressure_size>(
1063
1064 auto KUU = local_K.template block<displacement_size, displacement_size>(
1066
1067 // pointer-vectors to the right hand side terms - C-component equation
1068 auto fC = local_f.template segment<C_size>(C_index);
1069 // pointer-vectors to the right hand side terms - W-component equation
1070 auto fW = local_f.template segment<W_size>(W_index);
1071 // pointer-vectors to the right hand side terms - temperature equation
1072 auto fT = local_f.template segment<temperature_size>(temperature_index);
1073 // pointer-vectors to the right hand side terms - displacement equation
1074 auto fU = local_f.template segment<displacement_size>(displacement_index);
1075
1076 unsigned const n_integration_points =
1077 this->integration_method_.getNumberOfPoints();
1078
1080 this->solid_material_, *this->process_data_.phase_transition_model_};
1081
1082 auto const [ip_constitutive_data, ip_constitutive_variables] =
1084 Eigen::Map<Eigen::VectorXd const>(local_x.data(), local_x.size()),
1085 Eigen::Map<Eigen::VectorXd const>(local_x_prev.data(),
1086 local_x_prev.size()),
1087 t, dt, models);
1088
1089 for (unsigned int_point = 0; int_point < n_integration_points; int_point++)
1090 {
1091 auto& ip = _ip_data[int_point];
1092 auto& ip_cv = ip_constitutive_variables[int_point];
1093 auto& ip_cd = ip_constitutive_data[int_point];
1094
1095 auto& current_state = this->current_states_[int_point];
1096 auto const& prev_state = this->prev_states_[int_point];
1097
1098 auto const& Np = ip.N_p;
1099 auto const& Nu = ip.N_u;
1101 std::nullopt, this->element_.getID(),
1103 NumLib::interpolateCoordinates<ShapeFunctionDisplacement,
1105 this->element_, Nu))};
1106
1107 auto const& NpT = Np.transpose().eval();
1108 auto const& NTT = NpT;
1109
1110 auto const& gradNp = ip.dNdx_p;
1111 auto const& gradNT = gradNp;
1112 auto const& gradNu = ip.dNdx_u;
1113
1114 auto const& gradNpT = gradNp.transpose().eval();
1115 auto const& gradNTT = gradNpT;
1116
1117 auto const& w = ip.integration_weight;
1118
1119 auto const x_coord =
1120 pos.getCoordinates().value()[0]; // r for axisymetric
1121 auto const Bu =
1122 LinearBMatrix::computeBMatrix<DisplacementDim,
1123 ShapeFunctionDisplacement::NPOINTS,
1125 gradNu, Nu, x_coord, this->is_axially_symmetric_);
1126
1127 auto const NTN = (Np.transpose() * Np).eval();
1128 auto const BTI2N = (Bu.transpose() * Invariants::identity2 * Np).eval();
1129
1130 double const pCap = Np.dot(capillary_pressure);
1131 double const pCap_prev = Np.dot(capillary_pressure_prev);
1132
1133 auto const s_L = current_state.S_L_data.S_L;
1134 auto const s_L_dot = (s_L - prev_state.S_L_data->S_L) / dt;
1135
1136 auto const& b = this->process_data_.specific_body_force;
1137
1138 // ---------------------------------------------------------------------
1139 // C-component equation
1140 // ---------------------------------------------------------------------
1141
1142 MCpG.noalias() += NTN * (ip_cv.fC_4_MCpG.m * w);
1143 MCpC.noalias() += NTN * (ip_cv.fC_4_MCpC.m * w);
1144
1145 if (this->process_data_.apply_mass_lumping)
1146 {
1147 if (pCap - pCap_prev != 0.) // avoid division by Zero
1148 {
1149 MCpC.noalias() +=
1150 NTN * (ip_cv.fC_4_MCpC.ml / (pCap - pCap_prev) * w);
1151 }
1152 }
1153
1154 MCT.noalias() += NTN * (ip_cv.fC_4_MCT.m * w);
1155 MCu.noalias() += BTI2N.transpose() * (ip_cv.fC_4_MCu.m * w);
1156
1157 LCpG.noalias() += gradNpT * ip_cv.fC_4_LCpG.L * gradNp * w;
1158
1159 LCpC.noalias() += gradNpT * ip_cv.fC_4_LCpC.L * gradNp * w;
1160
1161 LCT.noalias() += gradNpT * ip_cv.fC_4_LCT.L * gradNp * w;
1162
1163 fC.noalias() += gradNpT * ip_cv.fC_1.A * b * w;
1164
1165 if (!this->process_data_.apply_mass_lumping)
1166 {
1167 fC.noalias() -= NpT * (ip_cv.fC_2a.a * s_L_dot * w);
1168 }
1169 // fC_III
1170 fC.noalias() -=
1171 NpT * (current_state.porosity_data.phi * ip_cv.fC_3a.a * w);
1172
1173 // ---------------------------------------------------------------------
1174 // W-component equation
1175 // ---------------------------------------------------------------------
1176
1177 MWpG.noalias() += NTN * (ip_cv.fW_4_MWpG.m * w);
1178 MWpC.noalias() += NTN * (ip_cv.fW_4_MWpC.m * w);
1179
1180 if (this->process_data_.apply_mass_lumping)
1181 {
1182 if (pCap - pCap_prev != 0.) // avoid division by Zero
1183 {
1184 MWpC.noalias() +=
1185 NTN * (ip_cv.fW_4_MWpC.ml / (pCap - pCap_prev) * w);
1186 }
1187 }
1188
1189 MWT.noalias() += NTN * (ip_cv.fW_4_MWT.m * w);
1190
1191 MWu.noalias() += BTI2N.transpose() * (ip_cv.fW_4_MWu.m * w);
1192
1193 LWpG.noalias() += gradNpT * ip_cv.fW_4_LWpG.L * gradNp * w;
1194
1195 LWpC.noalias() += gradNpT * ip_cv.fW_4_LWpC.L * gradNp * w;
1196
1197 LWT.noalias() += gradNpT * ip_cv.fW_4_LWT.L * gradNp * w;
1198
1199 fW.noalias() += gradNpT * ip_cv.fW_1.A * b * w;
1200
1201 if (!this->process_data_.apply_mass_lumping)
1202 {
1203 fW.noalias() -= NpT * (ip_cv.fW_2.a * s_L_dot * w);
1204 }
1205
1206 fW.noalias() -=
1207 NpT * (current_state.porosity_data.phi * ip_cv.fW_3a.a * w);
1208
1209 // ---------------------------------------------------------------------
1210 // - temperature equation
1211 // ---------------------------------------------------------------------
1212
1213 MTu.noalias() +=
1214 BTI2N.transpose() *
1215 (ip_cv.effective_volumetric_enthalpy_data.rho_h_eff * w);
1216
1217 KTT.noalias() +=
1218 gradNTT * ip_cv.thermal_conductivity_data.lambda * gradNT * w;
1219
1220 fT.noalias() -= NTT * (ip_cv.fT_1.m * w);
1221
1222 fT.noalias() += gradNTT * ip_cv.fT_2.A * w;
1223
1224 fT.noalias() += gradNTT * ip_cv.fT_3.gradN * w;
1225
1226 fT.noalias() += NTT * (ip_cv.fT_3.N * w);
1227
1228 // ---------------------------------------------------------------------
1229 // - displacement equation
1230 // ---------------------------------------------------------------------
1231
1232 KUpG.noalias() -= BTI2N * (ip_cv.biot_data() * w);
1233
1234 KUpC.noalias() += BTI2N * (ip_cv.fu_2_KupC.m * w);
1235
1236 auto const BuTC =
1237 (Bu.transpose() * ip_cd.s_mech_data.stiffness_tensor).eval();
1238 KUU.noalias() += BuTC * Bu * w;
1239
1240 fU.noalias() -=
1241 (Bu.transpose() * current_state.eff_stress_data.sigma_eff -
1242 N_u_op(Nu).transpose() * ip_cv.volumetric_body_force()) *
1243 w;
1244
1245 if (this->process_data_.apply_mass_lumping)
1246 {
1247 MCpG = MCpG.colwise().sum().eval().asDiagonal();
1248 MCpC = MCpC.colwise().sum().eval().asDiagonal();
1249 MWpG = MWpG.colwise().sum().eval().asDiagonal();
1250 MWpC = MWpC.colwise().sum().eval().asDiagonal();
1251 }
1252 } // int_point-loop
1253}
1254
1255// Assembles the local Jacobian matrix. So far, the linearisation of HT part is
1256// not considered as that in HT process.
1257template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
1258 int DisplacementDim>
1259void TH2MLocalAssembler<ShapeFunctionDisplacement, ShapeFunctionPressure,
1260 DisplacementDim>::
1261 assembleWithJacobian(double const t, double const dt,
1262 std::vector<double> const& local_x,
1263 std::vector<double> const& local_x_prev,
1264 std::vector<double>& local_rhs_data,
1265 std::vector<double>& local_Jac_data)
1266{
1267 auto const matrix_size = gas_pressure_size + capillary_pressure_size +
1269 assert(local_x.size() == matrix_size);
1270
1271 auto const temperature = Eigen::Map<VectorType<temperature_size> const>(
1272 local_x.data() + temperature_index, temperature_size);
1273
1274 auto const gas_pressure = Eigen::Map<VectorType<gas_pressure_size> const>(
1275 local_x.data() + gas_pressure_index, gas_pressure_size);
1276
1277 auto const capillary_pressure =
1278 Eigen::Map<VectorType<capillary_pressure_size> const>(
1280
1281 auto const displacement = Eigen::Map<VectorType<displacement_size> const>(
1282 local_x.data() + displacement_index, displacement_size);
1283
1284 auto const gas_pressure_prev =
1285 Eigen::Map<VectorType<gas_pressure_size> const>(
1286 local_x_prev.data() + gas_pressure_index, gas_pressure_size);
1287
1288 auto const capillary_pressure_prev =
1289 Eigen::Map<VectorType<capillary_pressure_size> const>(
1290 local_x_prev.data() + capillary_pressure_index,
1292
1293 auto const temperature_prev =
1294 Eigen::Map<VectorType<temperature_size> const>(
1295 local_x_prev.data() + temperature_index, temperature_size);
1296
1297 auto const displacement_prev =
1298 Eigen::Map<VectorType<displacement_size> const>(
1299 local_x_prev.data() + displacement_index, displacement_size);
1300
1301 auto local_Jac =
1303 local_Jac_data, matrix_size, matrix_size);
1304
1306 local_rhs_data, matrix_size);
1307
1308 // component-formulation
1309 // W - liquid phase main component
1310 // C - gas phase main component
1311
1312 // C component equation matrices
1322
1330
1331 // mass matrix - W component equation
1341
1342 // stiffness matrix - W component equation
1350
1351 // mass matrix - temperature equation
1355
1356 // stiffness matrix - temperature equation
1360
1361 // stiffness matrices - displacement equation coupling into pressures
1368
1369 // pointer-vectors to the right hand side terms - C-component equation
1370 auto fC = local_f.template segment<C_size>(C_index);
1371 // pointer-vectors to the right hand side terms - W-component equation
1372 auto fW = local_f.template segment<W_size>(W_index);
1373 // pointer-vectors to the right hand side terms - temperature equation
1374 auto fT = local_f.template segment<temperature_size>(temperature_index);
1375 // pointer-vectors to the right hand side terms - displacement equation
1376 auto fU = local_f.template segment<displacement_size>(displacement_index);
1377
1378 unsigned const n_integration_points =
1379 this->integration_method_.getNumberOfPoints();
1380
1382 this->solid_material_, *this->process_data_.phase_transition_model_};
1383
1384 auto const [ip_constitutive_data, ip_constitutive_variables] =
1386 Eigen::Map<Eigen::VectorXd const>(local_x.data(), local_x.size()),
1387 Eigen::Map<Eigen::VectorXd const>(local_x_prev.data(),
1388 local_x_prev.size()),
1389 t, dt, models);
1390
1391 auto const ip_d_data = updateConstitutiveVariablesDerivatives(
1392 Eigen::Map<Eigen::VectorXd const>(local_x.data(), local_x.size()),
1393 Eigen::Map<Eigen::VectorXd const>(local_x_prev.data(),
1394 local_x_prev.size()),
1395 t, dt, ip_constitutive_data, ip_constitutive_variables, models);
1396
1397 for (unsigned int_point = 0; int_point < n_integration_points; int_point++)
1398 {
1399 auto& ip = _ip_data[int_point];
1400 auto& ip_cd = ip_constitutive_data[int_point];
1401 auto& ip_dd = ip_d_data[int_point];
1402 auto& ip_cv = ip_constitutive_variables[int_point];
1403 auto& current_state = this->current_states_[int_point];
1404 auto& prev_state = this->prev_states_[int_point];
1405
1406 auto const& Np = ip.N_p;
1407 auto const& NT = Np;
1408 auto const& Nu = ip.N_u;
1410 std::nullopt, this->element_.getID(),
1412 NumLib::interpolateCoordinates<ShapeFunctionDisplacement,
1414 this->element_, Nu))};
1415
1416 auto const& NpT = Np.transpose().eval();
1417 auto const& NTT = NpT;
1418
1419 auto const& gradNp = ip.dNdx_p;
1420 auto const& gradNT = gradNp;
1421 auto const& gradNu = ip.dNdx_u;
1422
1423 auto const& gradNpT = gradNp.transpose().eval();
1424 auto const& gradNTT = gradNpT;
1425
1426 auto const& w = ip.integration_weight;
1427
1428 auto const x_coord =
1429 pos.getCoordinates().value()[0]; // r for axisymetric
1430 auto const Bu =
1431 LinearBMatrix::computeBMatrix<DisplacementDim,
1432 ShapeFunctionDisplacement::NPOINTS,
1434 gradNu, Nu, x_coord, this->is_axially_symmetric_);
1435
1436 auto const NTN = (Np.transpose() * Np).eval();
1437 auto const BTI2N = (Bu.transpose() * Invariants::identity2 * Np).eval();
1438
1439 double const div_u_dot =
1440 Invariants::trace(Bu * (displacement - displacement_prev) / dt);
1441
1442 double const pGR = Np.dot(gas_pressure);
1443 double const pCap = Np.dot(capillary_pressure);
1444 double const T = NT.dot(temperature);
1445
1446 GlobalDimVectorType const gradpGR = gradNp * gas_pressure;
1447 GlobalDimVectorType const gradpCap = gradNp * capillary_pressure;
1448 GlobalDimVectorType const gradT = gradNT * temperature;
1449
1450 double const pGR_prev = Np.dot(gas_pressure_prev);
1451 double const pCap_prev = Np.dot(capillary_pressure_prev);
1452 double const T_prev = NT.dot(temperature_prev);
1453
1454 auto const& s_L = current_state.S_L_data.S_L;
1455 auto const s_L_dot = (s_L - prev_state.S_L_data->S_L) / dt;
1456
1457 auto const& b = this->process_data_.specific_body_force;
1458
1459 // ---------------------------------------------------------------------
1460 // C-component equation
1461 // ---------------------------------------------------------------------
1462
1463 MCpG.noalias() += NTN * (ip_cv.fC_4_MCpG.m * w);
1464 MCpC.noalias() += NTN * (ip_cv.fC_4_MCpC.m * w);
1465
1466 if (this->process_data_.apply_mass_lumping)
1467 {
1468 if (pCap - pCap_prev != 0.) // avoid division by Zero
1469 {
1470 MCpC.noalias() +=
1471 NTN * (ip_cv.fC_4_MCpC.ml / (pCap - pCap_prev) * w);
1472 }
1473 }
1474
1475 MCT.noalias() += NTN * (ip_cv.fC_4_MCT.m * w);
1476 // d (fC_4_MCT * T_dot)/d T
1477 local_Jac
1478 .template block<C_size, temperature_size>(C_index,
1480 .noalias() += NTN * (ip_dd.dfC_4_MCT.dT * (T - T_prev) / dt * w);
1481
1482 MCu.noalias() += BTI2N.transpose() * (ip_cv.fC_4_MCu.m * w);
1483 // d (fC_4_MCu * u_dot)/d T
1484 local_Jac
1485 .template block<C_size, temperature_size>(C_index,
1487 .noalias() += NTN * (ip_dd.dfC_4_MCu.dT * div_u_dot * w);
1488
1489 LCpG.noalias() += gradNpT * ip_cv.fC_4_LCpG.L * gradNp * w;
1490
1491 // d (fC_4_LCpG * grad p_GR)/d p_GR
1492 local_Jac.template block<C_size, C_size>(C_index, C_index).noalias() +=
1493 gradNpT * ip_dd.dfC_4_LCpG.dp_GR * gradpGR * Np * w;
1494
1495 // d (fC_4_LCpG * grad p_GR)/d p_cap
1496 local_Jac.template block<C_size, W_size>(C_index, W_index).noalias() +=
1497 gradNpT * ip_dd.dfC_4_LCpG.dp_cap * gradpGR * Np * w;
1498
1499 // d (fC_4_LCpG * grad p_GR)/d T
1500 local_Jac
1501 .template block<C_size, temperature_size>(C_index,
1503 .noalias() += gradNpT * ip_dd.dfC_4_LCpG.dT * gradpGR * NT * w;
1504
1505 // d (fC_4_MCpG * p_GR_dot)/d p_GR
1506 local_Jac.template block<C_size, C_size>(C_index, C_index).noalias() +=
1507 NTN * (ip_dd.dfC_4_MCpG.dp_GR * (pGR - pGR_prev) / dt * w);
1508
1509 // d (fC_4_MCpG * p_GR_dot)/d T
1510 local_Jac
1511 .template block<C_size, temperature_size>(C_index,
1513 .noalias() +=
1514 NTN * (ip_dd.dfC_4_MCpG.dT * (pGR - pGR_prev) / dt * w);
1515
1516 LCpC.noalias() -= gradNpT * ip_cv.fC_4_LCpC.L * gradNp * w;
1517
1518 /* TODO (naumov) This part is not tested by any of the current ctests.
1519 // d (fC_4_LCpC * grad p_cap)/d p_GR
1520 local_Jac.template block<C_size, C_size>(C_index, C_index).noalias() +=
1521 gradNpT * ip_dd.dfC_4_LCpC.dp_GR * gradpCap * Np * w;
1522 // d (fC_4_LCpC * grad p_cap)/d p_cap
1523 local_Jac.template block<C_size, W_size>(C_index, W_index).noalias() +=
1524 gradNpT * ip_dd.dfC_4_LCpC.dp_cap * gradpCap * Np * w;
1525
1526 local_Jac
1527 .template block<C_size, temperature_size>(C_index,
1528 temperature_index)
1529 .noalias() += gradNpT * ip_dd.dfC_4_LCpC.dT * gradpCap * Np * w;
1530 */
1531
1532 LCT.noalias() += gradNpT * ip_cv.fC_4_LCT.L * gradNp * w;
1533
1534 // fC_1
1535 fC.noalias() += gradNpT * ip_cv.fC_1.A * b * w;
1536
1537 if (!this->process_data_.apply_mass_lumping)
1538 {
1539 // fC_2 = \int a * s_L_dot
1540 fC.noalias() -= NpT * (ip_cv.fC_2a.a * s_L_dot * w);
1541
1542 local_Jac.template block<C_size, C_size>(C_index, C_index)
1543 .noalias() +=
1544 NTN * ((ip_dd.dfC_2a.dp_GR * s_L_dot
1545 /*- ip_cv.fC_2a.a * (ds_L_dp_GR = 0) / dt*/) *
1546 w);
1547
1548 local_Jac.template block<C_size, W_size>(C_index, W_index)
1549 .noalias() +=
1550 NTN * ((ip_dd.dfC_2a.dp_cap * s_L_dot +
1551 ip_cv.fC_2a.a * ip_dd.dS_L_dp_cap() / dt) *
1552 w);
1553
1554 local_Jac
1555 .template block<C_size, temperature_size>(C_index,
1557 .noalias() += NTN * (ip_dd.dfC_2a.dT * s_L_dot * w);
1558 }
1559 {
1560 // fC_3 = \int phi * a
1561 fC.noalias() -=
1562 NpT * (current_state.porosity_data.phi * ip_cv.fC_3a.a * w);
1563
1564 local_Jac.template block<C_size, C_size>(C_index, C_index)
1565 .noalias() += NTN * (current_state.porosity_data.phi *
1566 ip_dd.dfC_3a.dp_GR * w);
1567
1568 local_Jac.template block<C_size, W_size>(C_index, W_index)
1569 .noalias() += NTN * (current_state.porosity_data.phi *
1570 ip_dd.dfC_3a.dp_cap * w);
1571
1572 local_Jac
1573 .template block<C_size, temperature_size>(C_index,
1575 .noalias() +=
1576 NTN * ((ip_dd.porosity_d_data.dphi_dT * ip_cv.fC_3a.a +
1577 current_state.porosity_data.phi * ip_dd.dfC_3a.dT) *
1578 w);
1579 }
1580 // ---------------------------------------------------------------------
1581 // W-component equation
1582 // ---------------------------------------------------------------------
1583
1584 MWpG.noalias() += NTN * (ip_cv.fW_4_MWpG.m * w);
1585 MWpC.noalias() += NTN * (ip_cv.fW_4_MWpC.m * w);
1586
1587 if (this->process_data_.apply_mass_lumping)
1588 {
1589 if (pCap - pCap_prev != 0.) // avoid division by Zero
1590 {
1591 MWpC.noalias() +=
1592 NTN * (ip_cv.fW_4_MWpC.ml / (pCap - pCap_prev) * w);
1593 }
1594 }
1595
1596 MWT.noalias() += NTN * (ip_cv.fW_4_MWT.m * w);
1597
1598 MWu.noalias() += BTI2N.transpose() * (ip_cv.fW_4_MWu.m * w);
1599
1600 LWpG.noalias() += gradNpT * ip_cv.fW_4_LWpG.L * gradNp * w;
1601
1602 // fW_4 LWpG' parts; LWpG = \int grad (a + d) grad
1603 local_Jac.template block<W_size, C_size>(W_index, C_index).noalias() +=
1604 gradNpT * ip_dd.dfW_4_LWpG.dp_GR * gradpGR * Np * w;
1605
1606 local_Jac.template block<W_size, W_size>(W_index, W_index).noalias() +=
1607 gradNpT * ip_dd.dfW_4_LWpG.dp_cap * gradpGR * Np * w;
1608
1609 local_Jac
1610 .template block<W_size, temperature_size>(W_index,
1612 .noalias() += gradNpT * ip_dd.dfW_4_LWpG.dT * gradpGR * NT * w;
1613
1614 LWpC.noalias() += gradNpT * ip_cv.fW_4_LWpC.L * gradNp * w;
1615
1616 // fW_4 LWp_cap' parts; LWpC = \int grad (a + d) grad
1617 local_Jac.template block<W_size, C_size>(W_index, C_index).noalias() -=
1618 gradNpT * ip_dd.dfW_4_LWpC.dp_GR * gradpCap * Np * w;
1619
1620 local_Jac.template block<W_size, W_size>(W_index, W_index).noalias() -=
1621 gradNpT * ip_dd.dfW_4_LWpC.dp_cap * gradpCap * Np * w;
1622
1623 local_Jac
1624 .template block<W_size, temperature_size>(W_index,
1626 .noalias() -= gradNpT * ip_dd.dfW_4_LWpC.dT * gradpCap * NT * w;
1627
1628 LWT.noalias() += gradNpT * ip_cv.fW_4_LWT.L * gradNp * w;
1629
1630 // fW_1
1631 fW.noalias() += gradNpT * ip_cv.fW_1.A * b * w;
1632
1633 // fW_2 = \int a * s_L_dot
1634 if (!this->process_data_.apply_mass_lumping)
1635 {
1636 fW.noalias() -= NpT * (ip_cv.fW_2.a * s_L_dot * w);
1637
1638 local_Jac.template block<W_size, C_size>(W_index, C_index)
1639 .noalias() += NTN * (ip_dd.dfW_2.dp_GR * s_L_dot * w);
1640
1641 // sign negated because of dp_cap = -dp_LR
1642 // TODO (naumov) Had to change the sign to get equal Jacobian WW
1643 // blocks in A2 Test. Where is the error?
1644 local_Jac.template block<W_size, W_size>(W_index, W_index)
1645 .noalias() += NTN * ((ip_dd.dfW_2.dp_cap * s_L_dot +
1646 ip_cv.fW_2.a * ip_dd.dS_L_dp_cap() / dt) *
1647 w);
1648
1649 local_Jac
1650 .template block<W_size, temperature_size>(W_index,
1652 .noalias() += NTN * (ip_dd.dfW_2.dT * s_L_dot * w);
1653 }
1654
1655 // fW_3 = \int phi * a
1656 fW.noalias() -=
1657 NpT * (current_state.porosity_data.phi * ip_cv.fW_3a.a * w);
1658
1659 local_Jac.template block<W_size, C_size>(W_index, C_index).noalias() +=
1660 NTN * (current_state.porosity_data.phi * ip_dd.dfW_3a.dp_GR * w);
1661
1662 local_Jac.template block<W_size, W_size>(W_index, W_index).noalias() +=
1663 NTN * (current_state.porosity_data.phi * ip_dd.dfW_3a.dp_cap * w);
1664
1665 local_Jac
1666 .template block<W_size, temperature_size>(W_index,
1668 .noalias() +=
1669 NTN * ((ip_dd.porosity_d_data.dphi_dT * ip_cv.fW_3a.a +
1670 current_state.porosity_data.phi * ip_dd.dfW_3a.dT) *
1671 w);
1672
1673 // ---------------------------------------------------------------------
1674 // - temperature equation
1675 // ---------------------------------------------------------------------
1676
1677 MTu.noalias() +=
1678 BTI2N.transpose() *
1679 (ip_cv.effective_volumetric_enthalpy_data.rho_h_eff * w);
1680
1681 // dfT_4/dp_GR
1682 // d (MTu * u_dot)/dp_GR
1683 local_Jac
1684 .template block<temperature_size, C_size>(temperature_index,
1685 C_index)
1686 .noalias() +=
1687 NTN * (ip_dd.effective_volumetric_enthalpy_d_data.drho_h_eff_dp_GR *
1688 div_u_dot * w);
1689
1690 // dfT_4/dp_cap
1691 // d (MTu * u_dot)/dp_cap
1692 local_Jac
1693 .template block<temperature_size, W_size>(temperature_index,
1694 W_index)
1695 .noalias() -=
1696 NTN *
1697 (ip_dd.effective_volumetric_enthalpy_d_data.drho_h_eff_dp_cap *
1698 div_u_dot * w);
1699
1700 // dfT_4/dT
1701 // d (MTu * u_dot)/dT
1702 local_Jac
1703 .template block<temperature_size, temperature_size>(
1705 .noalias() +=
1706 NTN * (ip_dd.effective_volumetric_enthalpy_d_data.drho_h_eff_dT *
1707 div_u_dot * w);
1708
1709 KTT.noalias() +=
1710 gradNTT * ip_cv.thermal_conductivity_data.lambda * gradNT * w;
1711
1712 // d KTT/dp_GR * T
1713 // TODO (naumov) always zero if lambda_xR have no derivatives wrt. p_GR.
1714 // dlambda_dp_GR =
1715 // (dphi_G_dp_GR = 0) * lambdaGR + phi_G * dlambda_GR_dp_GR +
1716 // (dphi_L_dp_GR = 0) * lambdaLR + phi_L * dlambda_LR_dp_GR +
1717 // (dphi_S_dp_GR = 0) * lambdaSR + phi_S * dlambda_SR_dp_GR +
1718 // = 0
1719 //
1720 // Since dlambda/dp_GR is 0 the derivative is omitted:
1721 // local_Jac
1722 // .template block<temperature_size, C_size>(temperature_index,
1723 // C_index)
1724 // .noalias() += gradNTT * dlambda_dp_GR * gradT * Np * w;
1725
1726 // d KTT/dp_cap * T
1727 local_Jac
1728 .template block<temperature_size, W_size>(temperature_index,
1729 W_index)
1730 .noalias() += gradNTT *
1731 ip_dd.thermal_conductivity_d_data.dlambda_dp_cap *
1732 gradT * Np * w;
1733
1734 // d KTT/dT * T
1735 local_Jac
1736 .template block<temperature_size, temperature_size>(
1738 .noalias() += gradNTT *
1739 ip_dd.thermal_conductivity_d_data.dlambda_dT * gradT *
1740 NT * w;
1741
1742 // fT_1
1743 fT.noalias() -= NTT * (ip_cv.fT_1.m * w);
1744
1745 // dfT_1/dp_GR
1746 local_Jac
1747 .template block<temperature_size, C_size>(temperature_index,
1748 C_index)
1749 .noalias() += NTN * (ip_dd.dfT_1.dp_GR * w);
1750
1751 // dfT_1/dp_cap
1752 local_Jac
1753 .template block<temperature_size, W_size>(temperature_index,
1754 W_index)
1755 .noalias() += NTN * (ip_dd.dfT_1.dp_cap * w);
1756
1757 // dfT_1/dT
1758 // MTT
1759 local_Jac
1760 .template block<temperature_size, temperature_size>(
1762 .noalias() += NTN * (ip_dd.dfT_1.dT * w);
1763
1764 // fT_2
1765 fT.noalias() += gradNTT * ip_cv.fT_2.A * w;
1766
1767 // dfT_2/dp_GR
1768 local_Jac
1769 .template block<temperature_size, C_size>(temperature_index,
1770 C_index)
1771 .noalias() -=
1772 // dfT_2/dp_GR first part
1773 gradNTT * ip_dd.dfT_2.dp_GR_Npart * Np * w +
1774 // dfT_2/dp_GR second part
1775 gradNTT * ip_dd.dfT_2.dp_GR_gradNpart * gradNp * w;
1776
1777 // dfT_2/dp_cap
1778 local_Jac
1779 .template block<temperature_size, W_size>(temperature_index,
1780 W_index)
1781 .noalias() -=
1782 // first part of dfT_2/dp_cap
1783 gradNTT * (-ip_dd.dfT_2.dp_cap_Npart) * Np * w +
1784 // second part of dfT_2/dp_cap
1785 gradNTT * (-ip_dd.dfT_2.dp_cap_gradNpart) * gradNp * w;
1786
1787 // dfT_2/dT
1788 local_Jac
1789 .template block<temperature_size, temperature_size>(
1791 .noalias() -= gradNTT * ip_dd.dfT_2.dT * NT * w;
1792
1793 // fT_3
1794 fT.noalias() += NTT * (ip_cv.fT_3.N * w);
1795
1796 fT.noalias() += gradNTT * ip_cv.fT_3.gradN * w;
1797
1798 // ---------------------------------------------------------------------
1799 // - displacement equation
1800 // ---------------------------------------------------------------------
1801
1802 KUpG.noalias() -= BTI2N * (ip_cv.biot_data() * w);
1803
1804 // dfU_2/dp_GR = dKUpG/dp_GR * p_GR + KUpG. The former is zero, the
1805 // latter is handled below.
1806
1807 KUpC.noalias() += BTI2N * (ip_cv.fu_2_KupC.m * w);
1808
1809 // dfU_2/dp_cap = dKUpC/dp_cap * p_cap + KUpC. The former is handled
1810 // here, the latter below.
1811 local_Jac
1812 .template block<displacement_size, W_size>(displacement_index,
1813 W_index)
1814 .noalias() += BTI2N * (ip_dd.dfu_2_KupC.dp_cap * w);
1815
1816 auto const BuTC =
1817 (Bu.transpose() * ip_cd.s_mech_data.stiffness_tensor).eval();
1818 local_Jac
1819 .template block<displacement_size, displacement_size>(
1821 .noalias() += BuTC * Bu * w;
1822
1823 // fU_1
1824 fU.noalias() -=
1825 (Bu.transpose() * current_state.eff_stress_data.sigma_eff -
1826 N_u_op(Nu).transpose() * ip_cv.volumetric_body_force()) *
1827 w;
1828
1829 // KuT
1830 local_Jac
1831 .template block<displacement_size, temperature_size>(
1833 .noalias() -= Bu.transpose() * ip_dd.dfu_1_KuT.dT * NT * w;
1834
1835 /* TODO (naumov) Test with gravity needed to check this Jacobian part.
1836 local_Jac
1837 .template block<displacement_size, temperature_size>(
1838 displacement_index, temperature_index)
1839 .noalias() += N_u_op(Nu).transpose() * ip_cv.drho_dT * b *
1840 N_u_op(Nu).transpose() * w;
1841 */
1842
1843 if (this->process_data_.apply_mass_lumping)
1844 {
1845 MCpG = MCpG.colwise().sum().eval().asDiagonal();
1846 MCpC = MCpC.colwise().sum().eval().asDiagonal();
1847 MWpG = MWpG.colwise().sum().eval().asDiagonal();
1848 MWpC = MWpC.colwise().sum().eval().asDiagonal();
1849 }
1850 } // int_point-loop
1851
1852 // --- Gas ---
1853 // fC_4
1854 fC.noalias() -= LCpG * gas_pressure + LCpC * capillary_pressure +
1855 LCT * temperature +
1856 MCpG * (gas_pressure - gas_pressure_prev) / dt +
1857 MCpC * (capillary_pressure - capillary_pressure_prev) / dt +
1858 MCT * (temperature - temperature_prev) / dt +
1859 MCu * (displacement - displacement_prev) / dt;
1860
1861 local_Jac.template block<C_size, C_size>(C_index, C_index).noalias() +=
1862 LCpG + MCpG / dt;
1863 local_Jac.template block<C_size, W_size>(C_index, W_index).noalias() +=
1864 LCpC + MCpC / dt;
1865 local_Jac
1866 .template block<C_size, temperature_size>(C_index, temperature_index)
1867 .noalias() += LCT + MCT / dt;
1868 local_Jac
1869 .template block<C_size, displacement_size>(C_index, displacement_index)
1870 .noalias() += MCu / dt;
1871
1872 // --- Capillary pressure ---
1873 // fW_4
1874 fW.noalias() -= LWpG * gas_pressure + LWpC * capillary_pressure +
1875 LWT * temperature +
1876 MWpG * (gas_pressure - gas_pressure_prev) / dt +
1877 MWpC * (capillary_pressure - capillary_pressure_prev) / dt +
1878 MWT * (temperature - temperature_prev) / dt +
1879 MWu * (displacement - displacement_prev) / dt;
1880
1881 local_Jac.template block<W_size, W_size>(W_index, W_index).noalias() +=
1882 LWpC + MWpC / dt;
1883 local_Jac.template block<W_size, C_size>(W_index, C_index).noalias() +=
1884 LWpG + MWpG / dt;
1885 local_Jac
1886 .template block<W_size, temperature_size>(W_index, temperature_index)
1887 .noalias() += LWT + MWT / dt;
1888 local_Jac
1889 .template block<W_size, displacement_size>(W_index, displacement_index)
1890 .noalias() += MWu / dt;
1891
1892 // --- Temperature ---
1893 // fT_4
1894 fT.noalias() -=
1895 KTT * temperature + MTu * (displacement - displacement_prev) / dt;
1896
1897 local_Jac
1898 .template block<temperature_size, temperature_size>(temperature_index,
1900 .noalias() += KTT;
1901 local_Jac
1902 .template block<temperature_size, displacement_size>(temperature_index,
1904 .noalias() += MTu / dt;
1905
1906 // --- Displacement ---
1907 // fU_2
1908 fU.noalias() -= KUpG * gas_pressure + KUpC * capillary_pressure;
1909
1910 local_Jac
1911 .template block<displacement_size, C_size>(displacement_index, C_index)
1912 .noalias() += KUpG;
1913 local_Jac
1914 .template block<displacement_size, W_size>(displacement_index, W_index)
1915 .noalias() += KUpC;
1916}
1917
1918template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
1919 int DisplacementDim>
1920void TH2MLocalAssembler<ShapeFunctionDisplacement, ShapeFunctionPressure,
1921 DisplacementDim>::
1922 computeSecondaryVariableConcrete(double const t, double const dt,
1923 Eigen::VectorXd const& local_x,
1924 Eigen::VectorXd const& local_x_prev)
1925{
1926 auto const gas_pressure =
1927 local_x.template segment<gas_pressure_size>(gas_pressure_index);
1928 auto const capillary_pressure =
1929 local_x.template segment<capillary_pressure_size>(
1931 auto const liquid_pressure = (gas_pressure - capillary_pressure).eval();
1932
1934 ShapeFunctionPressure, typename ShapeFunctionDisplacement::MeshElement,
1935 DisplacementDim>(this->element_, this->is_axially_symmetric_,
1936 gas_pressure,
1937 *this->process_data_.gas_pressure_interpolated);
1938
1940 ShapeFunctionPressure, typename ShapeFunctionDisplacement::MeshElement,
1941 DisplacementDim>(this->element_, this->is_axially_symmetric_,
1942 capillary_pressure,
1943 *this->process_data_.capillary_pressure_interpolated);
1944
1946 ShapeFunctionPressure, typename ShapeFunctionDisplacement::MeshElement,
1947 DisplacementDim>(this->element_, this->is_axially_symmetric_,
1948 liquid_pressure,
1949 *this->process_data_.liquid_pressure_interpolated);
1950
1951 auto const temperature =
1952 local_x.template segment<temperature_size>(temperature_index);
1953
1955 ShapeFunctionPressure, typename ShapeFunctionDisplacement::MeshElement,
1956 DisplacementDim>(this->element_, this->is_axially_symmetric_,
1957 temperature,
1958 *this->process_data_.temperature_interpolated);
1959
1961 this->solid_material_, *this->process_data_.phase_transition_model_};
1962
1963 updateConstitutiveVariables(local_x, local_x_prev, t, dt, models);
1964}
1965
1966} // namespace TH2M
1967} // namespace ProcessLib
#define OGS_FATAL(...)
Definition Error.h:10
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:22
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:34
std::optional< MathLib::Point3d > const getCoordinates() const
MatrixType< _kelvin_vector_size, _number_of_dof > BMatrixType
void assemble(double const, double const, std::vector< double > const &, std::vector< double > const &, std::vector< double > &, std::vector< double > &, std::vector< double > &) override
static constexpr auto & N_u_op
Definition TH2MFEM.h:70
static const int capillary_pressure_index
Definition TH2MFEM.h:255
ShapeMatrixPolicyType< ShapeFunctionDisplacement, DisplacementDim > ShapeMatricesTypeDisplacement
Definition TH2MFEM.h:46
std::vector< ConstitutiveRelations::DerivativesData< DisplacementDim > > updateConstitutiveVariablesDerivatives(Eigen::VectorXd const &local_x, Eigen::VectorXd const &local_x_prev, double const t, double const dt, std::vector< ConstitutiveRelations::ConstitutiveData< DisplacementDim > > const &ip_constitutive_data, std::vector< ConstitutiveRelations::ConstitutiveTempData< DisplacementDim > > const &ip_constitutive_variables, ConstitutiveRelations::ConstitutiveModels< DisplacementDim > const &models)
SecondaryData< typename ShapeMatricesTypeDisplacement::ShapeMatrices::ShapeType > _secondary_data
Definition TH2MFEM.h:249
static const int capillary_pressure_size
Definition TH2MFEM.h:256
typename ShapeMatricesTypePressure::template MatrixType< M, N > MatrixType
Definition TH2MFEM.h:57
static const int gas_pressure_index
Definition TH2MFEM.h:253
ShapeMatrixPolicyType< ShapeFunctionPressure, DisplacementDim > ShapeMatricesTypePressure
Definition TH2MFEM.h:49
std::tuple< std::vector< ConstitutiveRelations::ConstitutiveData< DisplacementDim > >, std::vector< ConstitutiveRelations::ConstitutiveTempData< DisplacementDim > > > updateConstitutiveVariables(Eigen::VectorXd const &local_x, Eigen::VectorXd const &local_x_prev, double const t, double const dt, ConstitutiveRelations::ConstitutiveModels< DisplacementDim > const &models)
typename ShapeMatricesTypePressure::GlobalDimVectorType GlobalDimVectorType
Definition TH2MFEM.h:63
static const int displacement_index
Definition TH2MFEM.h:259
std::vector< IpData > _ip_data
Definition TH2MFEM.h:245
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 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)
std::array< double, 3 > interpolateCoordinates(MeshLib::Element const &e, typename ShapeMatricesType::ShapeMatrices::ShapeType const &N)
BaseLib::StrongType< GlobalDimVector< DisplacementDim >, struct SpecificBodyForceTag > SpecificBodyForce
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.
std::size_t reflectSetIPData(std::string_view const name, double const *values, std::vector< IPData > &ip_data_vector)
BaseLib::StrongType< GlobalDimVector< DisplacementDim >, struct GasPressureGradientTag > GasPressureGradientData
BaseLib::StrongType< GlobalDimVector< DisplacementDim >, struct TemperatureGradientTag > TemperatureGradientData
BaseLib::StrongType< GlobalDimVector< DisplacementDim >, struct CapillaryPressureGradientTag > CapillaryPressureGradientData
std::size_t setIntegrationPointDataMaterialStateVariables(double const *values, IntegrationPointDataVector &ip_data_vector, MemberType member, std::function< std::span< double >(MaterialStateVariables &)> get_values_span)
void setIPDataInitialConditions(std::vector< std::unique_ptr< MeshLib::IntegrationPointWriter > > const &_integration_point_writer, MeshLib::Properties const &mesh_properties, LocalAssemblersVector &local_assemblers)
static Eigen::Matrix< double, KelvinVectorSize, 1 > const identity2
Kelvin mapping of 2nd order identity tensor.
static double trace(Eigen::Matrix< double, KelvinVectorSize, 1 > const &v)
Trace of the corresponding tensor.
void eval(SpaceTimeData const &x_t, MediaData const &media_data, BiotData &out) const
void eval(SpaceTimeData const &x_t, MediaData const &media_data, SaturationData const &S_L_data, BishopsData &out) const
Definition Bishops.cpp:28
void eval(SpaceTimeData const &x_t, MediaData const &media_data, PrevState< SaturationData > const &S_L_data, PrevState< BishopsData > &out) const
Definition Bishops.cpp:33
SolidCompressibilityModel< DisplacementDim, SolidConstitutiveRelation< DisplacementDim > > beta_p_SR_model
void dEval(FluidDensityData const &fluid_density_data, FluidEnthalpyData const &fluid_enthalpy_data, PhaseTransitionData const &phase_transition_data, PorosityData const &porosity_data, PorosityDerivativeData const &porosity_d_data, SaturationData const &S_L_data, SolidDensityData const &solid_density_data, SolidDensityDerivativeData const &solid_density_d_data, SolidEnthalpyData const &solid_enthalpy_data, SolidHeatCapacityData const &solid_heat_capacity_data, EffectiveVolumetricEnthalpyDerivatives &effective_volumetric_enthalpy_d_data) const
Definition Enthalpy.cpp:29
void eval(FluidDensityData const &fluid_density_data, FluidEnthalpyData const &fluid_enthalpy_data, PorosityData const &porosity_data, SaturationData const &S_L_data, SolidDensityData const &solid_density_data, SolidEnthalpyData const &solid_enthalpy_data, EffectiveVolumetricEnthalpy &effective_volumetric_enthalpy_data) const
Definition Enthalpy.cpp:10
void dEval(BiotData const &biot_data, CapillaryPressureData const pCap, ConstituentDensityData const &constituent_density_data, PhaseTransitionData const &phase_transition_data, PorosityData const &porosity_data, PorosityDerivativeData const &porosity_d_data, SaturationData const &S_L_data, SaturationDataDeriv const &dS_L_dp_cap, SolidCompressibilityData const &beta_p_SR, FC2aDerivativeData &dfC_2a) const
Definition CEquation.cpp:41
void eval(BiotData const biot_data, CapillaryPressureData const pCap, ConstituentDensityData const &constituent_density_data, PorosityData const &porosity_data, SaturationData const &S_L_data, SolidCompressibilityData const beta_p_SR, FC2aData &fC_2a) const
Definition CEquation.cpp:23
void eval(double const dt, ConstituentDensityData const &constituent_density_data, PrevState< ConstituentDensityData > const &constituent_density_data_prev, SaturationData const &S_L_data, FC3aData &fC_3a) const
Definition CEquation.cpp:96
void dEval(double const dt, ConstituentDensityData const &constituent_density_data, PrevState< ConstituentDensityData > const &constituent_density_data_prev, PhaseTransitionData const &phase_transition_data, SaturationData const &S_L_data, SaturationDataDeriv const &dS_L_dp_cap, FC3aDerivativeData &dfC_3a) const
void eval(BiotData const &biot_data, CapillaryPressureData const pCap, ConstituentDensityData const &constituent_density_data, PorosityData const &porosity_data, PrevState< SaturationData > const &S_L_data_prev, SaturationData const &S_L_data, SolidCompressibilityData const &beta_p_SR, FC4MCpCData &fC_4_MCpC) const
void eval(BiotData const &biot_data, ConstituentDensityData const &constituent_density_data, PorosityData const &porosity_data, SaturationData const &S_L_data, SolidCompressibilityData const &beta_p_SR, FC4MCpGData &fC_4_MCpG) const
void dEval(BiotData const &biot_data, ConstituentDensityData const &constituent_density_data, PhaseTransitionData const &phase_transition_data, PorosityData const &porosity_data, PorosityDerivativeData const &porosity_d_data, SaturationData const &S_L_data, SolidCompressibilityData const &beta_p_SR, FC4MCpGDerivativeData &dfC_4_MCpG) const
void eval(BiotData const &biot_data, ConstituentDensityData const &constituent_density_data, SaturationData const &S_L_data, FC4MCuData &fC_4_MCu) const
void dEval(BiotData const &biot_data, PhaseTransitionData const &phase_transition_data, SaturationData const &S_L_data, FC4MCuDerivativeData &dfC_4_MCu) const
void dEval(double const dt, EffectiveVolumetricInternalEnergyDerivatives const &effective_volumetric_internal_energy_d_data, FT1DerivativeData &dfT_1) const
Definition TEquation.cpp:27
void eval(double const dt, InternalEnergyData const &internal_energy_data, PrevState< InternalEnergyData > const &internal_energy_data_prev, FT1Data &fT_1) const
Definition TEquation.cpp:10
void dEval(BiotData const &biot_data, BishopsData const &chi_S_L, CapillaryPressureData const &p_cap, SaturationDataDeriv const &dS_L_dp_cap, FU2KUpCDerivativeData &dfu_2_KupC) const
Definition UEquation.cpp:30
void eval(BiotData const &biot_data, BishopsData const &chi_S_L, FU2KUpCData &fu_2_KupC) const
Definition UEquation.cpp:23
void dEval(BiotData const &biot_data, CapillaryPressureData const pCap, ConstituentDensityData const &constituent_density_data, PhaseTransitionData const &phase_transition_data, PorosityData const &porosity_data, PorosityDerivativeData const &porosity_d_data, PureLiquidDensityData const &rho_W_LR, SaturationData const &S_L_data, SaturationDataDeriv const &dS_L_dp_cap, SolidCompressibilityData const &beta_p_SR, FW2DerivativeData &dfW_2) const
Definition WEquation.cpp:42
void eval(BiotData const biot_data, CapillaryPressureData const pCap, ConstituentDensityData const &constituent_density_data, PorosityData const &porosity_data, PureLiquidDensityData const &rho_W_LR, SaturationData const &S_L_data, SolidCompressibilityData const beta_p_SR, FW2Data &fW_2) const
Definition WEquation.cpp:23
void dEval(double const dt, ConstituentDensityData const &constituent_density_data, PhaseTransitionData const &phase_transition_data, PrevState< ConstituentDensityData > const &constituent_density_data_prev, PrevState< PureLiquidDensityData > const &rho_W_LR_prev, PureLiquidDensityData const &rho_W_LR, SaturationData const &S_L_data, SaturationDataDeriv const &dS_L_dp_cap, FW3aDerivativeData &dfW_3a) const
void eval(double const dt, ConstituentDensityData const &constituent_density_data, PrevState< ConstituentDensityData > const &constituent_density_data_prev, PrevState< PureLiquidDensityData > const &rho_W_LR_prev, PureLiquidDensityData const &rho_W_LR, SaturationData const &S_L_data, FW3aData &fW_3a) const
void eval(BiotData const &biot_data, CapillaryPressureData const pCap, ConstituentDensityData const &constituent_density_data, PorosityData const &porosity_data, PrevState< SaturationData > const &S_L_data_prev, PureLiquidDensityData const &rho_W_LR, SaturationData const &S_L_data, SolidCompressibilityData const &beta_p_SR, FW4MWpCData &fW_4_MWpC) const
void eval(BiotData const &biot_data, ConstituentDensityData const &constituent_density_data, PorosityData const &porosity_data, PureLiquidDensityData const &rho_W_LR, SaturationData const &S_L_data, SolidCompressibilityData const &beta_p_SR, FW4MWpGData &fW_4_MWpG) const
void eval(BiotData const &biot_data, ConstituentDensityData const &constituent_density_data, PureLiquidDensityData const &rho_W_LR, SaturationData const &S_L_data, FW4MWuData &fW_4_MWu) const
void eval(FluidDensityData const &fluid_density_data, PhaseTransitionData const &phase_transition_data, PorosityData const &porosity_data, SaturationData const &S_L_data, SolidDensityData const &solid_density_data, SolidEnthalpyData const &solid_enthalpy_data, InternalEnergyData &internal_energy_data) const
void dEval(FluidDensityData const &fluid_density_data, PhaseTransitionData const &phase_transition_data, PorosityData const &porosity_data, PorosityDerivativeData const &porosity_d_data, SaturationData const &S_L_data, SolidDensityData const &solid_density_data, SolidDensityDerivativeData const &solid_density_d_data, SolidEnthalpyData const &solid_enthalpy_data, SolidHeatCapacityData const &solid_heat_capacity_data, EffectiveVolumetricInternalEnergyDerivatives &effective_volumetric_internal_energy_d_data) const
virtual void eval(SpaceTimeData const &x_t, MediaData const &media_data, GasPressureData const &p_GR, CapillaryPressureData const &p_cap, TemperatureData const &T_data, PureLiquidDensityData const &rho_W_LR, FluidEnthalpyData &fluid_enthalpy_data, MassMoleFractionsData &mass_mole_fractions_data, FluidDensityData &fluid_density_data, VapourPartialPressureData &vapour_pressure_data, ConstituentDensityData &constituent_density_data, PhaseTransitionData &cv) const =0
void eval(SpaceTimeData const &x_t, MediaData const &media_data, GasPressureData const &p_GR, CapillaryPressureData const &p_cap, TemperatureData const &T_data, PureLiquidDensityData &out) const
void dEval(SpaceTimeData const &x_t, MediaData const &media_data, CapillaryPressureData const &p_cap, SaturationDataDeriv &dS_L_data) const
void eval(SpaceTimeData const &x_t, MediaData const &media_data, CapillaryPressureData const &p_cap, SaturationData &S_L_data) const
void eval(SolidHeatCapacityData const &solid_heat_capacity_data, TemperatureData const &T_data, SolidEnthalpyData &solid_enthalpy_data) const
Definition Enthalpy.cpp:86
void eval(SpaceTimeData const &x_t, MediaData const &media_data, TemperatureData const &T_data, SolidHeatCapacityData &solid_heat_capacity) const
void eval(SpaceTimeData const &x_t, MediaData const &media_data, TemperatureData const &T_data, MassMoleFractionsData const &mass_mole_fractions_data, ViscosityData &viscosity_data) const
Definition Viscosity.cpp:10
NumLib::GenericIntegrationMethod const & integration_method_
LocalAssemblerInterface(MeshLib::Element const &e, NumLib::GenericIntegrationMethod const &integration_method, bool const is_axially_symmetric, TH2MProcessData< DisplacementDim > &process_data)
TH2MProcessData< DisplacementDim > & process_data_
ConstitutiveRelations::SolidConstitutiveRelation< DisplacementDim > const & solid_material_
std::vector< typename ConstitutiveRelations::StatefulData< DisplacementDim > > current_states_
std::vector< typename ConstitutiveRelations::StatefulDataPrev< DisplacementDim > > prev_states_
std::vector< ConstitutiveRelations::OutputData< DisplacementDim > > output_data_
std::vector< ConstitutiveRelations::MaterialStateData< DisplacementDim > > material_states_