231 ShapeFunctionDisplacement, ShapeFunctionPressure, DisplacementDim>::
232 updateConstitutiveRelations(
233 Eigen::Ref<Eigen::VectorXd const>
const local_x,
234 Eigen::Ref<Eigen::VectorXd const>
const local_x_prev,
236 double const dt,
IpData& ip_data,
239 assert(local_x.size() ==
242 auto const [T, p, u] =
localDOF(local_x);
243 auto const [T_prev, p_prev, u_prev] =
localDOF(local_x_prev);
245 auto const& solid_material =
251 auto const& liquid_phase =
253 auto const& solid_phase =
255 auto*
const frozen_liquid_phase =
261 auto const& N_u = ip_data.
N_u;
262 auto const& dNdx_u = ip_data.
dNdx_u;
264 auto const& N = ip_data.
N;
265 auto const& dNdx = ip_data.
dNdx;
267 auto const T_int_pt = N.dot(T);
268 auto const T_prev_int_pt = N.dot(T_prev);
269 double const dT_int_pt = T_int_pt - T_prev_int_pt;
275 ShapeFunctionDisplacement::NPOINTS,
281 auto& eps = ip_data.
eps;
282 eps.noalias() = B * u;
287 double const p_int_pt = N.dot(p);
289 double const p_prev_int_pt = N.dot(p_prev);
290 double const dp_int_pt = p_int_pt - p_prev_int_pt;
293 auto const solid_density =
295 .template value<double>(vars, x_position, t, dt);
297 auto const drho_SR_dT =
299 .template dValue<double>(vars,
303 auto const porosity =
305 .template value<double>(vars, x_position, t, dt);
311 .template value<double>(vars, x_position, t, dt);
312 auto const& alpha = crv.alpha_biot;
315 t, x_position, dt,
static_cast<double>(T_int_pt));
316 auto const solid_skeleton_compressibility =
317 1 / solid_material.getBulkModulus(t, x_position, &C_el);
319 crv.beta_SR = (1 - alpha) * solid_skeleton_compressibility;
325 auto const sigma_total =
326 (ip_data.
sigma_eff - alpha * p_int_pt * identity2).eval();
335 auto const intrinsic_permeability =
338 .value(vars, x_position, t, dt));
340 auto const fluid_density =
342 .template value<double>(vars, x_position, t, dt);
348 .template dValue<double>(
351 crv.drho_LR_dp = drho_dp;
353 crv.fluid_compressibility = 1 / fluid_density * drho_dp;
357 .template dValue<double>(vars,
361 double const fluid_volumetric_thermal_expansion_coefficient =
363 liquid_phase, vars, fluid_density, x_position, t, dt);
368 .template value<double>(vars, x_position, t, dt);
369 crv.K_over_mu = intrinsic_permeability / ip_data_output.
viscosity;
373 if (frozen_liquid_phase)
377 .template value<double>(vars, x_position, t, dt);
379 double const dphi_fr_dT =
381 .template dValue<double>(
394 .template value<double>(vars, x_position, t, dt);
398 auto const dk_rel_dphi_ice =
402 .template dValue<double>(
405 crv.dk_rel_dT = dk_rel_dphi_ice * dphi_fr_dT / porosity;
411 crv.solid_linear_thermal_expansion_coefficient =
416 .value(vars, x_position, t, dt));
420 crv.solid_linear_thermal_expansion_coefficient * dT_int_pt;
422 crv.K_pT_thermal_osmosis =
423 (solid_phase.hasProperty(
428 thermal_osmosis_coefficient)
429 .value(vars, x_position, t, dt))
430 : Eigen::MatrixXd::Zero(DisplacementDim, DisplacementDim));
433 -crv.k_rel * crv.K_over_mu * dNdx * p -
434 crv.K_pT_thermal_osmosis * dNdx * T +
435 (fluid_density * crv.k_rel) * crv.K_over_mu * b;
438 -crv.dk_rel_dT * crv.K_over_mu * dNdx * p +
440 (crv.dk_rel_dT * fluid_density + crv.k_rel * crv.drho_LR_dT) *
446 auto& eps_m = ip_data.
eps_m;
448 eps_m.noalias() = eps_m_prev + eps - eps_prev - dthermal_strain;
459 crv.rho = solid_density * (1 - porosity) + porosity * fluid_density;
462 porosity * fluid_volumetric_thermal_expansion_coefficient +
477 .template value<double>(vars, x_position, t, dt);
478 crv.effective_thermal_conductivity =
483 .value(vars, x_position, t, dt));
493 crv.effective_thermal_conductivity.noalias() +=
494 fluid_density * crv.c_f *
497 GlobalDimMatrixType::Zero(DisplacementDim, DisplacementDim),
504 .template value<double>(vars, x_position, t, dt);
507 crv.effective_volumetric_heat_capacity =
508 porosity * fluid_density * crv.c_f +
509 (1.0 - porosity) * solid_density * c_s;
510 double dC_eff_dT = porosity * crv.drho_LR_dT * crv.c_f +
511 (1.0 - porosity) * drho_SR_dT * c_s;
513 if (frozen_liquid_phase)
516 double const phi_fr = ip_data.
phi_fr;
518 auto const frozen_liquid_value =
521 return (*frozen_liquid_phase)[p].template value<double>(
522 vars, x_position, t, dt);
525 double const c_fr = frozen_liquid_value(
528 double const l_fr = frozen_liquid_value(
531 double const dphi_fr_dT =
533 .template dValue<double>(
537 double const d2phi_fr_dT2 =
539 .template d2Value<double>(
544 double const phi_fr_prev = [&]()
549 .template value<double>(vars_prev, x_position, t, dt);
553 double const rho_fr =
555 ip_data_output.
rho_fr = rho_fr;
557 crv.rho += ip_data.
phi_fr * rho_fr - ip_data.
phi_fr * fluid_density;
559 -dphi_fr_dT * porosity * (1. - rho_fr / fluid_density);
560 double const dmass_exchange_dT =
561 -d2phi_fr_dT2 * porosity * (1. - rho_fr / fluid_density) +
562 dphi_fr_dT * porosity * rho_fr * crv.drho_LR_dT /
563 (fluid_density * fluid_density);
567 DisplacementDim>
const ice_linear_thermal_expansion_coefficient =
572 .value(vars, x_position, t, dt));
575 dthermal_strain_ice =
576 ice_linear_thermal_expansion_coefficient * dT_int_pt;
583 crv.solid_linear_thermal_expansion_coefficient);
588 phase_change_expansion_coefficient =
592 phase_change_expansivity)
593 .value(vars, x_position, t, dt));
596 dphase_change_strain = phase_change_expansion_coefficient *
597 (phi_fr - phi_fr_prev) / porosity;
601 auto& eps0 = ip_data.
eps0;
602 auto const& eps0_prev = ip_data.
eps0_prev;
608 eps_m_ice.noalias() = eps_m_ice_prev + eps - eps_prev -
609 (eps0 - eps0_prev) - dthermal_strain_ice -
610 dphase_change_strain;
616 *
_process_data.ice_constitutive_relation, vars_ice, t, x_position,
621 static_cast<double>(T_int_pt));
623 1. /
_process_data.ice_constitutive_relation->getBulkModulus(
624 t, x_position, &C_el_ice);
626 crv.effective_volumetric_heat_capacity +=
627 -phi_fr * fluid_density * crv.c_f + phi_fr * rho_fr * c_fr -
628 l_fr * rho_fr * dphi_fr_dT;
630 crv.J_uu_fr = phi_fr * C_IR;
633 crv.r_u_fr = phi_fr * sigma_eff_ice;
635 crv.J_uT_fr = phi_fr * C_IR * ice_linear_thermal_expansion_coefficient;
638 dC_eff_dT += -dphi_fr_dT * fluid_density * crv.c_f -
639 phi_fr * crv.drho_LR_dT * crv.c_f +
640 dphi_fr_dT * rho_fr * c_fr - l_fr * rho_fr * d2phi_fr_dT2;
641 double const storage_p_fr_coeff =
642 (porosity * crv.beta_IR + (alpha - porosity) * crv.beta_SR) *
643 rho_fr / fluid_density -
644 (porosity * crv.fluid_compressibility +
645 (alpha - porosity) * crv.beta_SR);
646 crv.storage_p_fr = phi_fr / porosity * storage_p_fr_coeff;
648 double const dstorage_p_fr_coeff_dT =
649 (porosity * crv.beta_IR + (alpha - porosity) * crv.beta_SR) *
650 crv.drho_LR_dT / (fluid_density * fluid_density);
652 crv.J_pT_fr = (dphi_fr_dT * storage_p_fr_coeff +
653 phi_fr * dstorage_p_fr_coeff_dT) /
654 porosity * dp_int_pt / dt;
658 (crv.beta_T_SI * rho_fr / fluid_density - crv.beta) -
660 double const dstorage_T_fr_dT =
661 dphi_fr_dT / porosity *
662 (crv.beta_T_SI * rho_fr / fluid_density - crv.beta) +
663 phi_fr / porosity * crv.beta_T_SI * rho_fr * crv.drho_LR_dT /
664 (fluid_density * fluid_density) -
666 crv.J_pT_fr += dstorage_T_fr_dT * dT_int_pt / dt;
668 crv.J_TT = dC_eff_dT * dT_int_pt / dt;
679 std::vector<double>
const& local_x,
680 std::vector<double>
const&
682 std::vector<double>& local_rhs_data,
683 std::vector<double>& local_Jac_data)
685 assert(local_x.size() ==
689 Eigen::Map<Eigen::VectorXd const>(local_x.data(), local_x.size());
690 auto const x_prev = Eigen::Map<Eigen::VectorXd const>(local_x_prev.data(),
691 local_x_prev.size());
693 auto const [T, p, u] =
localDOF(local_x);
694 auto const [T_prev, p_prev, u_prev] =
localDOF(local_x_prev);
697 typename ShapeMatricesTypeDisplacement::template MatrixType<
704 typename ShapeMatricesTypeDisplacement::template VectorType<
735 typename ShapeMatricesTypeDisplacement::template MatrixType<
740 typename ShapeMatricesTypeDisplacement::template MatrixType<
749 bool const has_frozen_liquid_phase =
752 unsigned const n_integration_points =
755 std::vector<GlobalDimVectorType> ip_flux_vector;
756 double average_velocity_norm = 0.0;
757 ip_flux_vector.reserve(n_integration_points);
759 for (
unsigned ip = 0; ip < n_integration_points; ip++)
762 auto const& N_u = ip_data.N_u;
773 auto const& w = ip_data.integration_weight;
775 auto const& dNdx_u = ip_data.dNdx_u;
777 auto const& N = ip_data.N;
778 auto const& dNdx = ip_data.dNdx;
780 auto const T_int_pt = N.dot(T);
786 ShapeFunctionDisplacement::NPOINTS,
797 auto const C_eff = has_frozen_liquid_phase
798 ? (crv.C + crv.J_uu_fr).eval()
801 .template block<displacement_size, displacement_size>(
803 .noalias() += B.transpose() * C_eff * B * w;
805 auto const uT_coeff =
806 has_frozen_liquid_phase
808 crv.C * crv.solid_linear_thermal_expansion_coefficient)
810 : (crv.C * crv.solid_linear_thermal_expansion_coefficient)
813 if (has_frozen_liquid_phase)
816 .noalias() -= B.transpose() * crv.r_u_fr * w;
820 .template block<displacement_size, temperature_size>(
822 .noalias() -= B.transpose() * uT_coeff * N * w;
825 .noalias() -= (B.transpose() * ip_data.sigma_eff -
826 N_u_op(N_u).transpose() * crv.rho * b) *
833 double const up_coeff =
834 has_frozen_liquid_phase
835 ? crv.alpha_biot * ip_data.phi_fr / ip_data.porosity *
845 double const scaling_factor =
846 _process_data.is_volume_balance_equation_type ? 1.0 : fluid_density;
848 laplace_p.noalias() += dNdx.transpose() * crv.K_over_mu * dNdx *
849 (crv.k_rel * scaling_factor * w);
853 .noalias() += dNdx.transpose() * crv.K_over_mu * (dNdx * p) * N *
854 (crv.dk_rel_dT * scaling_factor * w);
856 double const storage_p_coeff_no_fr =
857 ip_data.porosity * crv.fluid_compressibility +
858 (crv.alpha_biot - ip_data.porosity) * crv.beta_SR;
859 double const storage_p_coeff =
860 has_frozen_liquid_phase ? crv.storage_p_fr + storage_p_coeff_no_fr
861 : storage_p_coeff_no_fr;
863 storage_p.noalias() +=
864 N.transpose() * N * (storage_p_coeff * scaling_factor * w);
866 if (has_frozen_liquid_phase)
869 .template block<pressure_size, temperature_size>(
872 N.transpose() * crv.J_pT_fr * N * scaling_factor * w;
875 laplace_T.noalias() += dNdx.transpose() * crv.K_pT_thermal_osmosis *
876 dNdx * scaling_factor * w;
880 local_rhs.template segment<pressure_size>(
pressure_index).noalias() -=
881 N * (up_coeff * crv.eps_v_dot * scaling_factor * w);
883 local_rhs.template segment<pressure_size>(
pressure_index).noalias() +=
884 dNdx.transpose() * crv.K_over_mu * b *
885 (fluid_density * crv.k_rel * scaling_factor * w);
889 .noalias() -= dNdx.transpose() * crv.K_over_mu * b * N *
890 (fluid_density * crv.dk_rel_dT * scaling_factor * w);
896 double const storage_T_coeff =
897 has_frozen_liquid_phase ? crv.storage_T_fr + crv.beta : crv.beta;
899 storage_T.noalias() +=
900 N.transpose() * storage_T_coeff * N * scaling_factor * w;
910 B * (up_coeff * scaling_factor * w);
916 double const storage_p_solid_coeff =
917 (crv.alpha_biot - ip_data.porosity) * crv.beta_SR;
919 double const p_dot = N.dot(p - p_prev) / dt;
920 double const T_dot = N.dot(T - T_prev) / dt;
921 double const drho_dp_coeff = storage_p_solid_coeff * p_dot +
922 storage_T_coeff * T_dot +
923 up_coeff * crv.eps_v_dot;
930 N.transpose() * N * (drho_dp_coeff * crv.drho_LR_dp * w);
932 .template block<pressure_size, temperature_size>(
936 N.transpose() * N * (drho_dp_coeff * crv.drho_LR_dT * w);
941 auto const dlaplace_temporal_factor =
942 (-velocity - (fluid_density * crv.k_rel) * crv.K_over_mu * b);
946 .noalias() += dNdx.transpose() * dlaplace_temporal_factor * N *
947 (crv.drho_LR_dp * w);
949 .template block<pressure_size, temperature_size>(
951 .noalias() += dNdx.transpose() * dlaplace_temporal_factor * N *
952 (crv.drho_LR_dT * w);
959 dNdx.transpose() * crv.effective_thermal_conductivity * dNdx * w;
960 dKTT_dT_T.noalias() +=
961 dNdx.transpose() * crv.dlambda_eff_dT * dNdx * T * N * w;
963 ip_flux_vector.emplace_back(velocity * fluid_density * crv.c_f);
968 crv.dvelocity_dT * fluid_density * crv.c_f +
969 velocity * crv.drho_LR_dT * crv.c_f;
970 dKTT_dT_T.noalias() +=
971 N.transpose() * dip_flux_vector_dT.transpose() * dNdx * T * N * w;
972 average_velocity_norm += velocity.norm();
975 N.transpose() * crv.effective_volumetric_heat_capacity * N * w;
977 .template block<temperature_size, temperature_size>(
979 .noalias() += N.transpose() * crv.J_TT * N * w;
985 dNdx.transpose() * crv.K_pT_thermal_osmosis * dNdx * (T_int_pt * w);
988 dKTT_dp_T.noalias() -= N.transpose() * (dNdx * T).transpose() *
989 crv.K_over_mu * dNdx *
990 (fluid_density * crv.c_f * crv.k_rel * w);
1037 average_velocity_norm /
static_cast<double>(n_integration_points), KTT);
1043 .noalias() += KTT + dKTT_dT_T + MTT / dt;
1049 .noalias() += KTp + dKTT_dp_T;
1061 .noalias() += -storage_T / dt + laplace_T;
1067 .noalias() += laplace_p + storage_p / dt;
1073 .template block<pressure_size, displacement_size>(
1075 .noalias() += Kup.transpose() / dt;
1080 .template block<pressure_size, displacement_size>(
1082 .noalias() += Kpu / dt;
1086 local_rhs.template segment<pressure_size>(
pressure_index).noalias() -=
1087 laplace_p * p + laplace_T * T + storage_p * (p - p_prev) / dt -
1088 storage_T * (T - T_prev) / dt;
1092 .noalias() += Kup * p;
1096 KTT * T + MTT * (T - T_prev) / dt;