OGS
ThermoHydroMechanicsFEM-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 <limits>
7#include <typeinfo>
8
24
25namespace ProcessLib
26{
28{
29template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
30 int DisplacementDim>
31ThermoHydroMechanicsLocalAssembler<ShapeFunctionDisplacement,
32 ShapeFunctionPressure, DisplacementDim>::
33 ThermoHydroMechanicsLocalAssembler(
34 MeshLib::Element const& e,
35 std::size_t const /*local_matrix_size*/,
36 NumLib::GenericIntegrationMethod const& integration_method,
37 bool const is_axially_symmetric,
39 : _process_data(process_data),
40 _integration_method(integration_method),
41 _element(e),
42 _is_axially_symmetric(is_axially_symmetric)
43{
44 unsigned const n_integration_points =
45 _integration_method.getNumberOfPoints();
46
47 _ip_data.reserve(n_integration_points);
48 _ip_data_output.resize(n_integration_points);
49 _secondary_data.N_u.resize(n_integration_points);
50
51 auto const shape_matrices_u =
52 NumLib::initShapeMatrices<ShapeFunctionDisplacement,
54 DisplacementDim>(e, is_axially_symmetric,
56
57 auto const shape_matrices_p =
58 NumLib::initShapeMatrices<ShapeFunctionPressure,
59 ShapeMatricesTypePressure, DisplacementDim>(
60 e, is_axially_symmetric, _integration_method);
61
62 auto const& solid_material =
64 _process_data.solid_materials, _process_data.material_ids,
65 e.getID());
66
67 // Consistency check: if frozen liquid phase is given, then the constitutive
68 // relation for ice must also be given, and vice versa.
69 auto const& medium = _process_data.media_map.getMedium(_element.getID());
71 (_process_data.ice_constitutive_relation != nullptr))
72 {
74 "Frozen liquid phase is {:s} and the solid material constitutive "
75 "relation for ice is {:s}. But both must be given (or both "
76 "omitted).",
78 ? "specified"
79 : "not specified",
80 _process_data.ice_constitutive_relation != nullptr
81 ? "specified"
82 : "not specified");
83 }
84 for (unsigned ip = 0; ip < n_integration_points; ip++)
85 {
86 _ip_data.emplace_back(solid_material);
87 auto& ip_data = _ip_data[ip];
88 auto const& sm_u = shape_matrices_u[ip];
89 ip_data.integration_weight =
90 _integration_method.getWeightedPoint(ip).getWeight() *
91 sm_u.integralMeasure * sm_u.detJ;
92
93 ip_data.N_u = sm_u.N;
94 ip_data.dNdx_u = sm_u.dNdx;
95
96 ip_data.N = shape_matrices_p[ip].N;
97 ip_data.dNdx = shape_matrices_p[ip].dNdx;
98
99 _secondary_data.N_u[ip] = shape_matrices_u[ip].N;
100 }
101}
102
103template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
104 int DisplacementDim>
106 ShapeFunctionDisplacement, ShapeFunctionPressure,
107 DisplacementDim>::setIPDataInitialConditions(std::string_view name,
108 double const* values,
109 int const integration_order)
110{
111 if (integration_order !=
112 static_cast<int>(_integration_method.getIntegrationOrder()))
113 {
114 OGS_FATAL(
115 "Setting integration point initial conditions; The integration "
116 "order of the local assembler for element {:d} is different from "
117 "the integration order in the initial condition.",
118 _element.getID());
119 }
120
121 if (name == "sigma")
122 {
123 if (_process_data.initial_stress.value)
124 {
125 OGS_FATAL(
126 "Setting initial conditions for stress from integration "
127 "point data and from a parameter '{:s}' is not possible "
128 "simultaneously.",
129 _process_data.initial_stress.value->name);
130 }
131
133 values, _ip_data, &IpData::sigma_eff);
134 }
135 if (name == "epsilon_m")
136 {
138 values, _ip_data, &IpData::eps_m);
139 }
140 if (name == "epsilon")
141 {
143 values, _ip_data, &IpData::eps);
144 }
145 if (name.starts_with("material_state_variable_"))
146 {
147 name.remove_prefix(24);
148
149 // Using first ip data for solid material. TODO (naumov) move solid
150 // material into element, store only material state in IPs.
151 auto const& internal_variables =
152 _ip_data[0].solid_material.getInternalVariables();
153 if (auto const iv = std::find_if(
154 begin(internal_variables), end(internal_variables),
155 [&name](auto const& iv) { return iv.name == name; });
156 iv != end(internal_variables))
157 {
158 DBUG("Setting material state variable '{:s}'", name);
161 iv->reference);
162 }
163
164 int const element_id = _element.getID();
165 DBUG(
166 "The solid material of element {:d} (material ID {:d}) does not "
167 "have an internal state variable called {:s}.",
168 element_id, (*_process_data.material_ids)[element_id], name);
169 }
170
171 return 0;
172}
173template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
174 int DisplacementDim>
176 ShapeFunctionDisplacement, ShapeFunctionPressure,
177 DisplacementDim>::setInitialConditionsConcrete(Eigen::VectorXd const
178 local_x,
179 double const t,
180 int const /*process_id*/)
181{
182 // TODO: For staggered scheme, overload
183 // LocalAssemblerInterface::setInitialConditions to enable local_x contains
184 // the primary variables from all coupled processes.
185 auto const [T, p, u] = localDOF(local_x);
186
187 constexpr double dt = std::numeric_limits<double>::quiet_NaN();
188
190 auto const& medium = _process_data.media_map.getMedium(_element.getID());
191 auto* const frozen_liquid_phase =
194 : nullptr;
195
196 int const n_integration_points = _integration_method.getNumberOfPoints();
197 for (int ip = 0; ip < n_integration_points; ip++)
198 {
199 auto& ip_data = _ip_data[ip];
200 auto const& N = ip_data.N;
201 auto const& N_u = ip_data.N_u;
202 ParameterLib::SpatialPosition const x_position{
203 std::nullopt, _element.getID(),
205 NumLib::interpolateCoordinates<ShapeFunctionDisplacement,
207 _element, N_u))};
208
209 auto& sigma_eff = ip_data.sigma_eff;
210 if (_process_data.initial_stress.isTotalStress())
211 {
212 auto const alpha_b =
214 .template value<double>(vars, x_position, t, dt);
215
216 sigma_eff.noalias() += alpha_b * N.dot(p) * Invariants::identity2;
217 }
218 ip_data.sigma_eff_prev.noalias() = sigma_eff;
219
220 vars.temperature = N.dot(T);
221 if (frozen_liquid_phase)
222 {
223 auto const porosity =
225 .template value<double>(vars, x_position, t, dt);
226 auto const S_fr =
227 (*medium)[MaterialPropertyLib::PropertyType::
228 frozen_liquid_saturation]
229 .template value<double>(vars, x_position, t, dt);
230 ip_data.phi_fr = S_fr * porosity;
231 }
232 }
233}
234
235template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
236 int DisplacementDim>
238 ShapeFunctionDisplacement, ShapeFunctionPressure, DisplacementDim>::
239 updateConstitutiveRelations(
240 Eigen::Ref<Eigen::VectorXd const> const local_x,
241 Eigen::Ref<Eigen::VectorXd const> const local_x_prev,
242 ParameterLib::SpatialPosition const& x_position, double const t,
243 double const dt, IpData& ip_data,
245{
246 assert(local_x.size() ==
248
249 auto const [T, p, u] = localDOF(local_x);
250 auto const [T_prev, p_prev, u_prev] = localDOF(local_x_prev);
251
252 auto const& solid_material =
254 _process_data.solid_materials, _process_data.material_ids,
255 _element.getID());
256
257 auto const& medium = _process_data.media_map.getMedium(_element.getID());
258 auto const& liquid_phase =
260 auto const& solid_phase =
262 auto* const frozen_liquid_phase =
265 : nullptr;
267
268 auto const& N_u = ip_data.N_u;
269 auto const& dNdx_u = ip_data.dNdx_u;
270
271 auto const& N = ip_data.N;
272 auto const& dNdx = ip_data.dNdx;
273
274 auto const T_int_pt = N.dot(T);
275 auto const T_prev_int_pt = N.dot(T_prev);
276 double const dT_int_pt = T_int_pt - T_prev_int_pt;
277
278 auto const x_coord =
279 x_position.getCoordinates().value()[0]; // r for axisymmetry
280 auto const B =
281 LinearBMatrix::computeBMatrix<DisplacementDim,
282 ShapeFunctionDisplacement::NPOINTS,
284 dNdx_u, N_u, x_coord, _is_axially_symmetric);
285
287
288 auto& eps = ip_data.eps;
289 eps.noalias() = B * u;
291 B * u_prev;
292
293 vars.temperature = T_int_pt;
294 double const p_int_pt = N.dot(p);
295 vars.liquid_phase_pressure = p_int_pt;
296 double const p_prev_int_pt = N.dot(p_prev);
297 double const dp_int_pt = p_int_pt - p_prev_int_pt;
298 vars.liquid_saturation = 1.0;
299
300 auto const solid_density =
302 .template value<double>(vars, x_position, t, dt);
303
304 auto const drho_SR_dT =
306 .template dValue<double>(vars,
308 x_position, t, dt);
309
310 auto const porosity =
312 .template value<double>(vars, x_position, t, dt);
313 vars.porosity = porosity;
314 ip_data.porosity = porosity;
315
316 crv.alpha_biot =
318 .template value<double>(vars, x_position, t, dt);
319 auto const& alpha = crv.alpha_biot;
320
321 auto const C_el = ip_data.computeElasticTangentStiffness(
322 t, x_position, dt, static_cast<double>(T_int_pt));
323 auto const solid_skeleton_compressibility =
324 1 / solid_material.getBulkModulus(t, x_position, &C_el);
325
326 crv.beta_SR = (1 - alpha) * solid_skeleton_compressibility;
327
328 // Set mechanical variables for the intrinsic permeability model
329 // For stress dependent permeability.
330 {
331 auto const& identity2 = Invariants::identity2;
332 auto const sigma_total =
333 (ip_data.sigma_eff - alpha * p_int_pt * identity2).eval();
334 vars.total_stress.emplace<SymmetricTensor>(
336 }
337 // For strain dependent permeability
340 ip_data.material_state_variables->getEquivalentPlasticStrain();
341
342 auto const intrinsic_permeability =
345 .value(vars, x_position, t, dt));
346
347 auto const fluid_density =
348 liquid_phase.property(MaterialPropertyLib::PropertyType::density)
349 .template value<double>(vars, x_position, t, dt);
350 ip_data_output.fluid_density = fluid_density;
351 vars.density = fluid_density;
352
353 auto const drho_dp =
354 liquid_phase.property(MaterialPropertyLib::PropertyType::density)
355 .template dValue<double>(
357 x_position, t, dt);
358 crv.drho_LR_dp = drho_dp;
359
360 crv.fluid_compressibility = 1 / fluid_density * drho_dp;
361
362 crv.drho_LR_dT =
363 liquid_phase.property(MaterialPropertyLib::PropertyType::density)
364 .template dValue<double>(vars,
366 x_position, t, dt);
367
368 double const fluid_volumetric_thermal_expansion_coefficient =
370 liquid_phase, vars, fluid_density, x_position, t, dt);
371
372 // Use the viscosity model to compute the viscosity
373 ip_data_output.viscosity =
375 .template value<double>(vars, x_position, t, dt);
376 crv.K_over_mu = intrinsic_permeability / ip_data_output.viscosity;
377
378 crv.k_rel = 1.;
379 crv.dk_rel_dT = 0;
380 if (frozen_liquid_phase)
381 {
382 auto const S_fr =
383 (*medium)
385 .template value<double>(vars, x_position, t, dt);
386 ip_data.phi_fr = S_fr * porosity;
387
388 // The Sigmoid returns the frozen liquid (ice) saturation, i.e. the
389 // fraction of the pore space occupied by ice. dS_fr/dT is its
390 // temperature derivative; the absolute frozen volume fraction and its
391 // derivative are obtained by multiplying with the porosity.
392 auto const dS_fr_dT =
393 (*medium)
395 .template dValue<double>(
397 x_position, t, dt);
398
399 // Set frozen_liquid_saturation variable for the relative permeability
400 // calculation (fraction of pore space occupied by ice).
401 vars.frozen_liquid_saturation = S_fr;
402
403 crv.k_rel =
404 liquid_phase
405 .property(
407 .template value<double>(vars, x_position, t, dt);
408
409 // dk_rel/dT = (dk_rel/dS_fr) * (dS_fr/dT)
410 auto const dk_rel_dS_fr =
411 liquid_phase
412 .property(
414 .template dValue<double>(
415 vars,
417 x_position, t, dt);
418 crv.dk_rel_dT = dk_rel_dS_fr * dS_fr_dT;
419 }
420
421 auto const& b = _process_data.specific_body_force;
422
423 // Consider also anisotropic thermal expansion.
424 crv.solid_linear_thermal_expansion_coefficient =
426 solid_phase
427 .property(
429 .value(vars, x_position, t, dt));
430
432 dthermal_strain =
433 crv.solid_linear_thermal_expansion_coefficient * dT_int_pt;
434
435 crv.K_pT_thermal_osmosis =
437 *medium, vars, x_position, t, dt, intrinsic_permeability,
438 ip_data_output.viscosity);
439
440 GlobalDimVectorType const velocity =
441 -crv.k_rel * crv.K_over_mu * dNdx * p -
442 crv.K_pT_thermal_osmosis * dNdx * T +
443 (fluid_density * crv.k_rel) * crv.K_over_mu * b;
444 ip_data_output.velocity = velocity;
445 crv.dvelocity_dT =
446 -crv.dk_rel_dT * crv.K_over_mu * dNdx * p +
447 // TODO(naumov): - crv.K_pT_thermal_osmosis * dNdx * dT_dT +
448 (crv.dk_rel_dT * fluid_density + crv.k_rel * crv.drho_LR_dT) *
449 crv.K_over_mu * b;
450
451 //
452 // displacement equation, displacement part
453 //
454 auto& eps_m = ip_data.eps_m;
455 auto& eps_m_prev = ip_data.eps_m_prev;
456 eps_m.noalias() = eps_m_prev + eps - eps_prev - dthermal_strain;
457
458 crv.eps_v_dot = (vars.volumetric_strain - Invariants::trace(eps_prev)) / dt;
459
462 eps_m);
463
464 crv.C = ip_data.updateConstitutiveRelation(vars, t, x_position, dt,
465 T_prev_int_pt);
466
467 crv.rho = solid_density * (1 - porosity) + porosity * fluid_density;
468
469 crv.beta =
470 porosity * fluid_volumetric_thermal_expansion_coefficient +
471 (alpha - porosity) *
472 Invariants::trace(crv.solid_linear_thermal_expansion_coefficient);
473
474 //
475 // pressure equation, displacement part.
476 //
477 // Reusing Kup.transpose().
478
479 //
480 // temperature equation, temperature part.
481 //
482 crv.c_f =
483 liquid_phase
485 .template value<double>(vars, x_position, t, dt);
486 crv.effective_thermal_conductivity =
488 medium
489 ->property(
491 .value(vars, x_position, t, dt));
492
494 medium
497 x_position, t, dt));
498
499 // Thermal conductivity is moved outside and zero matrix is passed instead
500 // due to multiplication with fluid's density times specific heat capacity.
501 crv.effective_thermal_conductivity.noalias() +=
502 fluid_density * crv.c_f *
504 _process_data.stabilizer, _element.getID(),
505 GlobalDimMatrixType::Zero(DisplacementDim, DisplacementDim),
506 velocity, 0. /* phi */, 0. /* dispersivity_transversal */,
507 0. /*dispersivity_longitudinal*/);
508
509 double const c_s =
510 solid_phase
512 .template value<double>(vars, x_position, t, dt);
513
514 // Sensible part (no latent term here). Also modified by freezing terms.
515 crv.sensible_volumetric_heat_capacity =
516 porosity * fluid_density * crv.c_f +
517 (1.0 - porosity) * solid_density * c_s;
518 double dC_eff_dT = porosity * crv.drho_LR_dT * crv.c_f +
519 (1.0 - porosity) * drho_SR_dT * c_s;
520
521 if (frozen_liquid_phase)
522 {
524 double const phi_fr = ip_data.phi_fr;
525
526 auto const frozen_liquid_value =
528 {
529 return (*frozen_liquid_phase)[p].template value<double>(
530 vars, x_position, t, dt);
531 };
532
533 double const c_fr = frozen_liquid_value(
535
536 double const l_fr = frozen_liquid_value(
538
539 auto const dS_fr_dT =
540 (*medium)
542 .template dValue<double>(
544 x_position, t, dt);
545 double const dphi_fr_dT = dS_fr_dT * porosity;
546
547 auto const d2S_fr_dT2 =
548 (*medium)
550 .template d2Value<double>(
553 t, dt);
554 double const d2phi_fr_dT2 = d2S_fr_dT2 * porosity;
555
556 double const phi_fr_prev = [&]()
557 {
559 vars_prev.temperature = T_prev_int_pt;
560 auto const S_fr_prev =
561 (*medium)[MaterialPropertyLib::PropertyType::
562 frozen_liquid_saturation]
563 .template value<double>(vars_prev, x_position, t, dt);
564 return S_fr_prev * porosity;
565 }();
566 ip_data.phi_fr_prev = phi_fr_prev;
567
568 double const rho_fr =
570 ip_data_output.rho_fr = rho_fr;
571
572 crv.rho += ip_data.phi_fr * rho_fr - ip_data.phi_fr * fluid_density;
573 crv.mass_exchange =
574 -dphi_fr_dT * porosity * (1. - rho_fr / fluid_density);
575 double const dmass_exchange_dT =
576 -d2phi_fr_dT2 * porosity * (1. - rho_fr / fluid_density) +
577 dphi_fr_dT * porosity * rho_fr * crv.drho_LR_dT /
578 (fluid_density * fluid_density);
579
580 // alpha_T^I
582 DisplacementDim> const ice_linear_thermal_expansion_coefficient =
584 frozen_liquid_phase
585 ->property(
587 .value(vars, x_position, t, dt));
588
590 dthermal_strain_ice =
591 ice_linear_thermal_expansion_coefficient * dT_int_pt;
592
593 crv.beta_T_SI =
594 porosity *
595 Invariants::trace(ice_linear_thermal_expansion_coefficient) +
596 (alpha - porosity) *
598 crv.solid_linear_thermal_expansion_coefficient);
599
600 // alpha_{phi_I} -- linear expansion coeff. due to water-to-ice
601 // transition (phase change), and related phase_change_strain term
603 phase_change_expansion_coefficient =
605 frozen_liquid_phase
607 phase_change_expansivity)
608 .value(vars, x_position, t, dt));
609
611 dphase_change_strain = phase_change_expansion_coefficient *
612 (phi_fr - phi_fr_prev) / porosity;
613
614 // eps0 ia a 'history variable' -- a solid matrix strain accrued
615 // prior to the onset of ice forming
616 auto& eps0 = ip_data.eps0;
617 auto const& eps0_prev = ip_data.eps0_prev;
618
619 // definition of eps_m_ice
620 auto& eps_m_ice = ip_data.eps_m_ice;
621 auto const& eps_m_ice_prev = ip_data.eps_m_ice_prev;
622
623 eps_m_ice.noalias() = eps_m_ice_prev + eps - eps_prev -
624 (eps0 - eps0_prev) - dthermal_strain_ice -
625 dphase_change_strain;
626
627 vars_ice.mechanical_strain
629 eps_m_ice);
630 auto const C_IR = ip_data.updateConstitutiveRelationIce(
631 *_process_data.ice_constitutive_relation, vars_ice, t, x_position,
632 dt, T_prev_int_pt);
633
634 auto const C_el_ice = ip_data.computeElasticTangentStiffnessIce(
635 *_process_data.ice_constitutive_relation, t, x_position, dt,
636 static_cast<double>(T_int_pt));
637 crv.beta_IR =
638 1. / _process_data.ice_constitutive_relation->getBulkModulus(
639 t, x_position, &C_el_ice);
640
641 // Latent contribution L (effective = sensible - L).
642 crv.latent_volumetric_heat_capacity = l_fr * rho_fr * dphi_fr_dT;
643
644 // Freezing modifies only the sensible part; latent kept separate.
645 crv.sensible_volumetric_heat_capacity +=
646 -phi_fr * fluid_density * crv.c_f + phi_fr * rho_fr * c_fr;
647
648 crv.J_uu_fr = phi_fr * C_IR;
649
650 auto const& sigma_eff_ice = ip_data.sigma_eff_ice;
651 crv.r_u_fr = phi_fr * sigma_eff_ice;
652
653 crv.J_uT_fr = phi_fr * C_IR * ice_linear_thermal_expansion_coefficient;
654
655 // part of dMTT_dT derivative for freezing
656 dC_eff_dT += -dphi_fr_dT * fluid_density * crv.c_f -
657 phi_fr * crv.drho_LR_dT * crv.c_f +
658 dphi_fr_dT * rho_fr * c_fr - l_fr * rho_fr * d2phi_fr_dT2;
659 double const storage_p_fr_coeff =
660 (porosity * crv.beta_IR + (alpha - porosity) * crv.beta_SR) *
661 rho_fr / fluid_density -
662 (porosity * crv.fluid_compressibility +
663 (alpha - porosity) * crv.beta_SR);
664 crv.storage_p_fr = phi_fr / porosity * storage_p_fr_coeff;
665
666 double const dstorage_p_fr_coeff_dT =
667 (porosity * crv.beta_IR + (alpha - porosity) * crv.beta_SR) *
668 crv.drho_LR_dT / (fluid_density * fluid_density);
669
670 crv.J_pT_fr = (dphi_fr_dT * storage_p_fr_coeff +
671 phi_fr * dstorage_p_fr_coeff_dT) /
672 porosity * dp_int_pt / dt;
673
674 crv.storage_T_fr =
675 phi_fr / porosity *
676 (crv.beta_T_SI * rho_fr / fluid_density - crv.beta) -
677 crv.mass_exchange;
678 double const dstorage_T_fr_dT =
679 dphi_fr_dT / porosity *
680 (crv.beta_T_SI * rho_fr / fluid_density - crv.beta) +
681 phi_fr / porosity * crv.beta_T_SI * rho_fr * crv.drho_LR_dT /
682 (fluid_density * fluid_density) -
683 dmass_exchange_dT;
684 crv.J_pT_fr += dstorage_T_fr_dT * dT_int_pt / dt;
685 }
686 crv.J_TT = dC_eff_dT * dT_int_pt / dt;
687 return crv;
688}
689
690// Assembles the local Jacobian matrix. So far, the linearisation of HT part is
691// not considered as that in HT process.
692template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
693 int DisplacementDim>
695 ShapeFunctionDisplacement, ShapeFunctionPressure,
696 DisplacementDim>::assembleWithJacobian(double const t, double const dt,
697 std::vector<double> const& local_x,
698 std::vector<double> const&
699 local_x_prev,
700 std::vector<double>& local_rhs_data,
701 std::vector<double>& local_Jac_data)
702{
703 assert(local_x.size() ==
705
706 auto const x =
707 Eigen::Map<Eigen::VectorXd const>(local_x.data(), local_x.size());
708 auto const x_prev = Eigen::Map<Eigen::VectorXd const>(local_x_prev.data(),
709 local_x_prev.size());
710
711 auto const [T, p, u] = localDOF(local_x);
712 auto const [T_prev, p_prev, u_prev] = localDOF(local_x_prev);
713
714 auto local_Jac = MathLib::createZeroedMatrix<
715 typename ShapeMatricesTypeDisplacement::template MatrixType<
720
721 auto local_rhs = MathLib::createZeroedVector<
722 typename ShapeMatricesTypeDisplacement::template VectorType<
725
728
731
733 KTp.setZero(temperature_size, pressure_size);
734
736 dKTT_dT_T.setZero(temperature_size, pressure_size);
737
739 dKTT_dp_T.setZero(temperature_size, pressure_size);
740
742 laplace_p.setZero(pressure_size, pressure_size);
743
745 laplace_T.setZero(pressure_size, temperature_size);
746
748 storage_p.setZero(pressure_size, pressure_size);
749
751 storage_T.setZero(pressure_size, temperature_size);
752
753 typename ShapeMatricesTypeDisplacement::template MatrixType<
755 Kup;
756 Kup.setZero(displacement_size, pressure_size);
757
758 typename ShapeMatricesTypeDisplacement::template MatrixType<
760 Kpu;
761 if (!_process_data.is_volume_balance_equation_type)
762 {
763 Kpu.setZero(pressure_size, displacement_size);
764 }
765
766 auto const& medium = _process_data.media_map.getMedium(_element.getID());
767 bool const has_frozen_liquid_phase =
769
770 unsigned const n_integration_points =
771 _integration_method.getNumberOfPoints();
772
773 std::vector<GlobalDimVectorType> ip_flux_vector;
774 double average_velocity_norm = 0.0;
775 ip_flux_vector.reserve(n_integration_points);
776
777 for (unsigned ip = 0; ip < n_integration_points; ip++)
778 {
779 auto& ip_data = _ip_data[ip];
780 auto const& N_u = ip_data.N_u;
781 ParameterLib::SpatialPosition const x_position{
782 std::nullopt, _element.getID(),
784 NumLib::interpolateCoordinates<ShapeFunctionDisplacement,
786 _element, N_u))};
787
788 auto const crv = updateConstitutiveRelations(
789 x, x_prev, x_position, t, dt, ip_data, _ip_data_output[ip]);
790
791 auto const& w = ip_data.integration_weight;
792
793 auto const& dNdx_u = ip_data.dNdx_u;
794
795 auto const& N = ip_data.N;
796 auto const& dNdx = ip_data.dNdx;
797
798 auto const T_int_pt = N.dot(T);
799
800 auto const x_coord =
801 x_position.getCoordinates().value()[0]; // r for axisymmetry
802 auto const B =
803 LinearBMatrix::computeBMatrix<DisplacementDim,
804 ShapeFunctionDisplacement::NPOINTS,
806 dNdx_u, N_u, x_coord, _is_axially_symmetric);
807
808 auto const& b = _process_data.specific_body_force;
809 auto const velocity = _ip_data_output[ip].velocity;
810
811 //
812 // displacement equation, displacement part
813 //
814
815 auto const C_eff = has_frozen_liquid_phase
816 ? (crv.C + crv.J_uu_fr).eval()
817 : crv.C.eval();
818 local_Jac
819 .template block<displacement_size, displacement_size>(
821 .noalias() += B.transpose() * C_eff * B * w;
822
823 auto const uT_coeff =
824 has_frozen_liquid_phase
825 ? (crv.J_uT_fr +
826 crv.C * crv.solid_linear_thermal_expansion_coefficient)
827 .eval()
828 : (crv.C * crv.solid_linear_thermal_expansion_coefficient)
829 .eval();
830
831 if (has_frozen_liquid_phase)
832 {
833 local_rhs.template segment<displacement_size>(displacement_index)
834 .noalias() -= B.transpose() * crv.r_u_fr * w;
835 }
836
837 local_Jac
838 .template block<displacement_size, temperature_size>(
840 .noalias() -= B.transpose() * uT_coeff * N * w;
841
842 local_rhs.template segment<displacement_size>(displacement_index)
843 .noalias() -= (B.transpose() * ip_data.sigma_eff -
844 N_u_op(N_u).transpose() * crv.rho * b) *
845 w;
846
847 //
848 // displacement equation, pressure part (K_up)
849 //
850 double const fluid_density = _ip_data_output[ip].fluid_density;
851 double const up_coeff =
852 has_frozen_liquid_phase
853 ? crv.alpha_biot * ip_data.phi_fr / ip_data.porosity *
854 (_ip_data_output[ip].rho_fr / fluid_density - 1) +
855 crv.alpha_biot
856 : crv.alpha_biot;
857 Kup.noalias() +=
858 B.transpose() * Invariants::identity2 * N * (up_coeff * w);
859
860 //
861 // pressure equation, pressure part (K_pp and M_pp).
862 //
863 double const scaling_factor =
864 _process_data.is_volume_balance_equation_type ? 1.0 : fluid_density;
865
866 laplace_p.noalias() += dNdx.transpose() * crv.K_over_mu * dNdx *
867 (crv.k_rel * scaling_factor * w);
868 local_Jac
869 .template block<pressure_size, temperature_size>(pressure_index,
871 .noalias() += dNdx.transpose() * crv.K_over_mu * (dNdx * p) * N *
872 (crv.dk_rel_dT * scaling_factor * w);
873
874 double const storage_p_coeff_no_fr =
875 ip_data.porosity * crv.fluid_compressibility +
876 (crv.alpha_biot - ip_data.porosity) * crv.beta_SR;
877 double const storage_p_coeff =
878 has_frozen_liquid_phase ? crv.storage_p_fr + storage_p_coeff_no_fr
879 : storage_p_coeff_no_fr;
880
881 storage_p.noalias() +=
882 N.transpose() * N * (storage_p_coeff * scaling_factor * w);
883
884 if (has_frozen_liquid_phase)
885 {
886 local_Jac
887 .template block<pressure_size, temperature_size>(
889 .noalias() +=
890 N.transpose() * crv.J_pT_fr * N * scaling_factor * w;
891 }
892
893 laplace_T.noalias() += dNdx.transpose() * crv.K_pT_thermal_osmosis *
894 dNdx * scaling_factor * w;
895 //
896 // RHS, pressure part
897 //
898 local_rhs.template segment<pressure_size>(pressure_index).noalias() -=
899 N * (up_coeff * crv.eps_v_dot * scaling_factor * w);
900
901 local_rhs.template segment<pressure_size>(pressure_index).noalias() +=
902 dNdx.transpose() * crv.K_over_mu * b *
903 (fluid_density * crv.k_rel * scaling_factor * w);
904 local_Jac
905 .template block<pressure_size, temperature_size>(pressure_index,
907 .noalias() -= dNdx.transpose() * crv.K_over_mu * b * N *
908 (fluid_density * crv.dk_rel_dT * scaling_factor * w);
909
910 //
911 // pressure equation, temperature part (M_pT)
912 //
913
914 double const storage_T_coeff =
915 has_frozen_liquid_phase ? crv.storage_T_fr + crv.beta : crv.beta;
916
917 storage_T.noalias() +=
918 N.transpose() * storage_T_coeff * N * scaling_factor * w;
919
920 //
921 // pressure equation, displacement part.
922 //
923 // reusing Kup.transpose() if the equation balance type is not volume.
924
925 if (!_process_data.is_volume_balance_equation_type)
926 {
927 Kpu.noalias() += N.transpose() * Invariants::identity2.transpose() *
928 B * (up_coeff * scaling_factor * w);
929
930 //
931 // The contribution to Jacobian from d()/ drho
932 // drho/dp, d()/ drho drho/dT:
933 //
934 double const storage_p_solid_coeff =
935 (crv.alpha_biot - ip_data.porosity) * crv.beta_SR;
936
937 double const p_dot = N.dot(p - p_prev) / dt;
938 double const T_dot = N.dot(T - T_prev) / dt;
939 double const drho_dp_coeff = storage_p_solid_coeff * p_dot +
940 storage_T_coeff * T_dot +
941 up_coeff * crv.eps_v_dot;
942
943 local_Jac
944 .template block<pressure_size, pressure_size>(pressure_index,
946 .noalias() +=
947 // TODO (WW) : Add ip_data.porosity * d2rho_LR_dp2 * w.
948 N.transpose() * N * (drho_dp_coeff * crv.drho_LR_dp * w);
949 local_Jac
950 .template block<pressure_size, temperature_size>(
952 .noalias() +=
953 // TODO (WW) : Add ip_data.porosity * d2rho_LR_dpdT * w.
954 N.transpose() * N * (drho_dp_coeff * crv.drho_LR_dT * w);
955
956 // The term from d (rho_L K(grad p - rho_L b)/dp:
957 // derivative of rhp_L * K_over_mu * k_rel (grad p + rho_l g) with
958 // respect to pressure and temperature.
959 auto const dlaplace_temporal_factor =
960 (-velocity - (fluid_density * crv.k_rel) * crv.K_over_mu * b);
961 local_Jac
962 .template block<pressure_size, pressure_size>(pressure_index,
964 .noalias() += dNdx.transpose() * dlaplace_temporal_factor * N *
965 (crv.drho_LR_dp * w);
966 local_Jac
967 .template block<pressure_size, temperature_size>(
969 .noalias() += dNdx.transpose() * dlaplace_temporal_factor * N *
970 (crv.drho_LR_dT * w);
971 }
972
973 //
974 // temperature equation, temperature part.
975 //
976 KTT.noalias() +=
977 dNdx.transpose() * crv.effective_thermal_conductivity * dNdx * w;
978 dKTT_dT_T.noalias() +=
979 dNdx.transpose() * crv.dlambda_eff_dT * dNdx * T * N * w;
980
981 ip_flux_vector.emplace_back(velocity * fluid_density * crv.c_f);
982 // Without any flux correction the flux derivative is as follows. The
983 // contribution to KTT is different if any stabilization scheme is used,
984 // but this is ignored for the moment.
985 GlobalDimVectorType const dip_flux_vector_dT =
986 crv.dvelocity_dT * fluid_density * crv.c_f +
987 velocity * crv.drho_LR_dT * crv.c_f;
988 dKTT_dT_T.noalias() +=
989 N.transpose() * dip_flux_vector_dT.transpose() * dNdx * T * N * w;
990 average_velocity_norm += velocity.norm();
991
992 MTT.noalias() += N.transpose() *
993 (crv.sensible_volumetric_heat_capacity -
994 crv.latent_volumetric_heat_capacity) *
995 N * w;
996 local_Jac
997 .template block<temperature_size, temperature_size>(
999 .noalias() += N.transpose() * crv.J_TT * N * w;
1000
1001 //
1002 // temperature equation, pressure part
1003 //
1004 KTp.noalias() +=
1005 dNdx.transpose() * crv.K_pT_thermal_osmosis * dNdx * (T_int_pt * w);
1006
1007 // linearized darcy
1008 dKTT_dp_T.noalias() -= N.transpose() * (dNdx * T).transpose() *
1009 crv.K_over_mu * dNdx *
1010 (fluid_density * crv.c_f * crv.k_rel * w);
1011
1012 /* TODO (Joerg) Temperature changes due to thermal dilatation of the
1013 * fluid, which are usually discarded as being very small.
1014 * Zhou et al. (10.1016/S0020-7683(98)00089-4) states that:
1015 * "Biot (1956) neglected this term and it is included here for
1016 * completeness"
1017 * Keeping the code here in the case these are needed for the named
1018 * effects in the future.
1019 if (fluid_compressibility != 0)
1020 {
1021 auto const C_el = ip_data.computeElasticTangentStiffness(
1022 t, x_position, dt, static_cast<double>(T_int_pt));
1023 auto const solid_skeleton_compressibility =
1024 1 / solid_material.getBulkModulus(t, x_position, &C_el);
1025 double const fluid_volumetric_thermal_expansion_coefficient =
1026 MaterialPropertyLib::getLiquidThermalExpansivity(
1027 liquid_phase, vars, fluid_density, x_position, t, dt);
1028
1029 KTT.noalias() +=
1030 dNdx.transpose() *
1031 (-T_int_pt * fluid_volumetric_thermal_expansion_coefficient *
1032 K_pT_thermal_osmosis / fluid_compressibility) *
1033 dNdx * w;
1034
1035 local_rhs.template segment<temperature_size>(temperature_index)
1036 .noalias() +=
1037 dNdx.transpose() *
1038 (-T_int_pt * fluid_volumetric_thermal_expansion_coefficient /
1039 fluid_compressibility) *
1040 fluid_density * crv.k_rel * K_over_mu * b * w;
1041 MTu part for rhs and Jacobian:
1042 (-T_int_pt *
1043 Invariants::trace(solid_linear_thermal_expansion_coefficient) /
1044 solid_skeleton_compressibility) *
1045 N.transpose() * identity2.transpose() * B * w;
1046 KTp part for rhs and Jacobian:
1047 dNdx.transpose() *
1048 (T_int_pt * fluid_volumetric_thermal_expansion_coefficient *
1049 crv.k_rel * K_over_mu / fluid_compressibility) *
1050 dNdx * w;
1051 }
1052 */
1053 }
1054
1056 _process_data.stabilizer, _ip_data, ip_flux_vector,
1057 average_velocity_norm / static_cast<double>(n_integration_points), KTT);
1058
1059 // temperature equation, temperature part
1060 local_Jac
1061 .template block<temperature_size, temperature_size>(temperature_index,
1063 .noalias() += KTT + dKTT_dT_T + MTT / dt;
1064
1065 // temperature equation, pressure part
1066 local_Jac
1067 .template block<temperature_size, pressure_size>(temperature_index,
1069 .noalias() += KTp + dKTT_dp_T;
1070
1071 // displacement equation, pressure part
1072 local_Jac
1073 .template block<displacement_size, pressure_size>(displacement_index,
1075 .noalias() -= Kup;
1076
1077 // pressure equation, temperature part.
1078 local_Jac
1079 .template block<pressure_size, temperature_size>(pressure_index,
1081 .noalias() += -storage_T / dt + laplace_T;
1082
1083 // pressure equation, pressure part.
1084 local_Jac
1085 .template block<pressure_size, pressure_size>(pressure_index,
1087 .noalias() += laplace_p + storage_p / dt;
1088
1089 // pressure equation, displacement part.
1090 if (_process_data.is_volume_balance_equation_type)
1091 {
1092 local_Jac
1093 .template block<pressure_size, displacement_size>(
1095 .noalias() += Kup.transpose() / dt;
1096 }
1097 else
1098 {
1099 local_Jac
1100 .template block<pressure_size, displacement_size>(
1102 .noalias() += Kpu / dt;
1103 }
1104
1105 // pressure equation (f_p)
1106 local_rhs.template segment<pressure_size>(pressure_index).noalias() -=
1107 laplace_p * p + laplace_T * T + storage_p * (p - p_prev) / dt -
1108 storage_T * (T - T_prev) / dt;
1109
1110 // displacement equation (f_u)
1111 local_rhs.template segment<displacement_size>(displacement_index)
1112 .noalias() += Kup * p;
1113
1114 // temperature equation (f_T)
1115 local_rhs.template segment<temperature_size>(temperature_index).noalias() -=
1116 KTT * T + MTT * (T - T_prev) / dt;
1117
1118 local_rhs.template segment<temperature_size>(temperature_index).noalias() -=
1119 KTp * p;
1120}
1121
1122template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
1123 int DisplacementDim>
1124std::vector<double> const& ThermoHydroMechanicsLocalAssembler<
1125 ShapeFunctionDisplacement, ShapeFunctionPressure, DisplacementDim>::
1126 getIntPtDarcyVelocity(
1127 const double /*t*/,
1128 std::vector<GlobalVector*> const& /*x*/,
1129 std::vector<NumLib::LocalToGlobalIndexMap const*> const& /*dof_table*/,
1130 std::vector<double>& cache) const
1131{
1132 unsigned const n_integration_points =
1133 _integration_method.getNumberOfPoints();
1134
1135 cache.clear();
1136 auto cache_matrix = MathLib::createZeroedMatrix<Eigen::Matrix<
1137 double, DisplacementDim, Eigen::Dynamic, Eigen::RowMajor>>(
1138 cache, DisplacementDim, n_integration_points);
1139
1140 for (unsigned ip = 0; ip < n_integration_points; ip++)
1141 {
1142 cache_matrix.col(ip).noalias() = _ip_data_output[ip].velocity;
1143 }
1144
1145 return cache;
1146}
1147
1148template <typename ShapeFunctionDisplacement, typename ShapeFunction,
1149 int DisplacementDim>
1150std::vector<double> const& ThermoHydroMechanicsLocalAssembler<
1151 ShapeFunctionDisplacement, ShapeFunction, DisplacementDim>::
1152 getIntPtFluidDensity(
1153 const double /*t*/,
1154 std::vector<GlobalVector*> const& /*x*/,
1155 std::vector<NumLib::LocalToGlobalIndexMap const*> const& /*dof_table*/,
1156 std::vector<double>& cache) const
1157{
1161}
1162
1163template <typename ShapeFunctionDisplacement, typename ShapeFunction,
1164 int DisplacementDim>
1165std::vector<double> const& ThermoHydroMechanicsLocalAssembler<
1166 ShapeFunctionDisplacement, ShapeFunction, DisplacementDim>::
1167 getIntPtViscosity(
1168 const double /*t*/,
1169 std::vector<GlobalVector*> const& /*x*/,
1170 std::vector<NumLib::LocalToGlobalIndexMap const*> const& /*dof_table*/,
1171 std::vector<double>& cache) const
1172{
1176}
1177
1178template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
1179 int DisplacementDim>
1181 ShapeFunctionDisplacement, ShapeFunctionPressure, DisplacementDim>::
1182 computeSecondaryVariableConcrete(double const /*t*/, double const /*dt*/,
1183 Eigen::VectorXd const& local_x,
1184 Eigen::VectorXd const& /*local_x_prev*/)
1185{
1186 auto const p = local_x.template segment<pressure_size>(pressure_index);
1187 auto const T =
1188 local_x.template segment<temperature_size>(temperature_index);
1189
1190 unsigned const n_integration_points =
1191 _integration_method.getNumberOfPoints();
1192
1193 double phi_fr_avg = 0;
1194 double fluid_density_avg = 0;
1195 double viscosity_avg = 0;
1196
1198 KV sigma_avg = KV::Zero();
1199 KV sigma_ice_avg = KV::Zero();
1200
1201 for (unsigned ip = 0; ip < n_integration_points; ip++)
1202 {
1203 auto& ip_data = _ip_data[ip];
1204
1205 phi_fr_avg += ip_data.phi_fr;
1206 fluid_density_avg += _ip_data_output[ip].fluid_density;
1207 viscosity_avg += _ip_data_output[ip].viscosity;
1208 sigma_avg += ip_data.sigma_eff;
1209 sigma_ice_avg += ip_data.sigma_eff_ice;
1210 }
1211
1212 phi_fr_avg /= n_integration_points;
1213 fluid_density_avg /= n_integration_points;
1214 viscosity_avg /= n_integration_points;
1215 sigma_avg /= n_integration_points;
1216 sigma_ice_avg /= n_integration_points;
1217
1218 (*_process_data.element_phi_fr)[_element.getID()] = phi_fr_avg;
1219 (*_process_data.element_fluid_density)[_element.getID()] =
1220 fluid_density_avg;
1221 (*_process_data.element_viscosity)[_element.getID()] = viscosity_avg;
1222
1223 Eigen::Map<KV>(&(*_process_data.element_stresses)[_element.getID() *
1224 KV::RowsAtCompileTime]) =
1226
1227 Eigen::Map<KV>(&(
1229 .element_ice_stresses)[_element.getID() * KV::RowsAtCompileTime]) =
1231
1233 ShapeFunctionPressure, typename ShapeFunctionDisplacement::MeshElement,
1234 DisplacementDim>(_element, _is_axially_symmetric, p,
1235 *_process_data.pressure_interpolated);
1236
1238 ShapeFunctionPressure, typename ShapeFunctionDisplacement::MeshElement,
1239 DisplacementDim>(_element, _is_axially_symmetric, T,
1240 *_process_data.temperature_interpolated);
1241}
1242} // namespace ThermoHydroMechanics
1243} // namespace ProcessLib
#define OGS_FATAL(...)
Definition Error.h:10
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:22
std::size_t getID() const
Returns the ID of the element.
Definition Element.h:80
std::optional< MathLib::Point3d > const getCoordinates() const
MatrixType< _kelvin_vector_size, _number_of_dof > BMatrixType
void setInitialConditionsConcrete(Eigen::VectorXd const local_x, double const t, int const process_id) override
ConstitutiveRelationsValues< DisplacementDim > updateConstitutiveRelations(Eigen::Ref< Eigen::VectorXd const > const local_x, Eigen::Ref< Eigen::VectorXd const > const local_x_prev, ParameterLib::SpatialPosition const &x_position, double const t, double const dt, IpData &ip_data, IntegrationPointDataForOutput< DisplacementDim > &ip_data_output) const
ShapeMatrixPolicyType< ShapeFunctionDisplacement, DisplacementDim > ShapeMatricesTypeDisplacement
typename ShapeMatricesTypePressure::GlobalDimVectorType GlobalDimVectorType
void assembleWithJacobian(double const t, double const dt, std::vector< double > const &local_x, std::vector< double > const &local_x_prev, std::vector< double > &local_rhs_data, std::vector< double > &local_Jac_data) override
IntegrationPointData< BMatricesType, ShapeMatricesTypeDisplacement, ShapeMatricesTypePressure, DisplacementDim, ShapeFunctionDisplacement::NPOINTS > IpData
ThermoHydroMechanicsProcessData< DisplacementDim > & _process_data
std::vector< IntegrationPointDataForOutput< DisplacementDim >, Eigen::aligned_allocator< IntegrationPointDataForOutput< DisplacementDim > > > _ip_data_output
SecondaryData< typename ShapeMatricesTypeDisplacement::ShapeMatrices::ShapeType > _secondary_data
ShapeMatrixPolicyType< ShapeFunctionPressure, DisplacementDim > ShapeMatricesTypePressure
std::vector< IpData, Eigen::aligned_allocator< IpData > > _ip_data
auto & selectSolidConstitutiveRelation(SolidMaterialsMap const &constitutive_relations, MeshLib::PropertyVector< int > const *const material_ids, std::size_t const element_id)
constexpr Eigen::Matrix< double, GlobalDim, GlobalDim > formEigenTensor(MaterialPropertyLib::PropertyDataType const &values)
MathLib::KelvinVector::KelvinVectorType< GlobalDim > formKelvinVector(MaterialPropertyLib::PropertyDataType const &values)
A function to form a Kelvin vector from strain or stress alike property like thermal expansivity for ...
double getLiquidThermalExpansivity(Phase const &phase, VariableArray const &vars, const double density, ParameterLib::SpatialPosition const &pos, double const t, double const dt)
Eigen::Matrix< double, 4, 1 > kelvinVectorToSymmetricTensor(Eigen::Matrix< double, 4, 1, Eigen::ColMajor, 4, 1 > const &v)
Eigen::Matrix< double, kelvin_vector_dimensions(DisplacementDim), 1, Eigen::ColMajor > KelvinVectorType
Eigen::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 assembleAdvectionMatrix(IPData const &ip_data_vector, NumLib::ShapeMatrixCache const &shape_matrix_cache, std::vector< FluxVectorType > const &ip_flux_vector, Eigen::MatrixBase< Derived > &laplacian_matrix)
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)
Eigen::MatrixXd computeHydrodynamicDispersion(NumericalStabilization const &stabilizer, std::size_t const element_id, Eigen::MatrixXd const &pore_diffusion_coefficient, Eigen::VectorXd const &velocity, double const porosity, double const solute_dispersivity_transverse, double const solute_dispersivity_longitudinal)
std::array< double, 3 > interpolateCoordinates(MeshLib::Element const &e, typename ShapeMatricesType::ShapeMatrices::ShapeType const &N)
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::vector< double > const & getIntegrationPointScalarData(IntegrationPointDataVector const &ip_data_vector, MemberType IpData::*const member, std::vector< double > &cache)
std::size_t setIntegrationPointDataMaterialStateVariables(double const *values, IntegrationPointDataVector &ip_data_vector, MemberType member, std::function< std::span< double >(MaterialStateVariables &)> get_values_span)
Eigen::Matrix< double, GlobalDim, GlobalDim > getThermoOsmoticCoefficient(MaterialPropertyLib::Medium const &medium, MaterialPropertyLib::VariableArray const &variable_array, ParameterLib::SpatialPosition const &pos, double const t, double const dt, Eigen::Matrix< double, GlobalDim, GlobalDim > const &intrinsic_permeability, double const liquid_dynamic_viscosity)
std::size_t setIntegrationPointKelvinVectorData(double const *values, IntegrationPointDataVector &ip_data_vector, MemberType IpData::*const member)
void setIPDataInitialConditions(std::vector< std::unique_ptr< MeshLib::IntegrationPointWriter > > const &_integration_point_writer, MeshLib::Properties const &mesh_properties, LocalAssemblersVector &local_assemblers)
MatrixType< ShapeFunction::NPOINTS, ShapeFunction::NPOINTS > NodalMatrixType
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.
BMatricesType::KelvinMatrixType updateConstitutiveRelation(MaterialPropertyLib::VariableArray const &variable_array, double const t, ParameterLib::SpatialPosition const &x_position, double const dt, double const temperature_prev)
MathLib::KelvinVector::KelvinMatrixType< DisplacementDim > computeElasticTangentStiffness(double const t, ParameterLib::SpatialPosition const &x_position, double const dt, double const temperature)
MathLib::KelvinVector::KelvinMatrixType< DisplacementDim > computeElasticTangentStiffnessIce(MaterialLib::Solids::MechanicsBase< DisplacementDim > const &ice_constitutive_relation, double const t, ParameterLib::SpatialPosition const &x_position, double const dt, double const temperature)
BMatricesType::KelvinMatrixType updateConstitutiveRelationIce(MaterialLib::Solids::MechanicsBase< DisplacementDim > const &ice_constitutive_relation, MaterialPropertyLib::VariableArray const &variable_array, double const t, ParameterLib::SpatialPosition const &x_position, double const dt, double const temperature_prev)