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,
243 double const dt,
IpData& ip_data,
246 assert(local_x.size() ==
249 auto const [T, p, u] =
localDOF(local_x);
250 auto const [T_prev, p_prev, u_prev] =
localDOF(local_x_prev);
252 auto const& solid_material =
258 auto const& liquid_phase =
260 auto const& solid_phase =
262 auto*
const frozen_liquid_phase =
268 auto const& N_u = ip_data.
N_u;
269 auto const& dNdx_u = ip_data.
dNdx_u;
271 auto const& N = ip_data.
N;
272 auto const& dNdx = ip_data.
dNdx;
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;
282 ShapeFunctionDisplacement::NPOINTS,
288 auto& eps = ip_data.
eps;
289 eps.noalias() = B * u;
294 double const p_int_pt = N.dot(p);
296 double const p_prev_int_pt = N.dot(p_prev);
297 double const dp_int_pt = p_int_pt - p_prev_int_pt;
300 auto const solid_density =
302 .template value<double>(vars, x_position, t, dt);
304 auto const drho_SR_dT =
306 .template dValue<double>(vars,
310 auto const porosity =
312 .template value<double>(vars, x_position, t, dt);
318 .template value<double>(vars, x_position, t, dt);
319 auto const& alpha = crv.alpha_biot;
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);
326 crv.beta_SR = (1 - alpha) * solid_skeleton_compressibility;
332 auto const sigma_total =
333 (ip_data.
sigma_eff - alpha * p_int_pt * identity2).eval();
342 auto const intrinsic_permeability =
345 .value(vars, x_position, t, dt));
347 auto const fluid_density =
349 .template value<double>(vars, x_position, t, dt);
355 .template dValue<double>(
358 crv.drho_LR_dp = drho_dp;
360 crv.fluid_compressibility = 1 / fluid_density * drho_dp;
364 .template dValue<double>(vars,
368 double const fluid_volumetric_thermal_expansion_coefficient =
370 liquid_phase, vars, fluid_density, x_position, t, dt);
375 .template value<double>(vars, x_position, t, dt);
376 crv.K_over_mu = intrinsic_permeability / ip_data_output.
viscosity;
380 if (frozen_liquid_phase)
385 .template value<double>(vars, x_position, t, dt);
386 ip_data.
phi_fr = S_fr * porosity;
392 auto const dS_fr_dT =
395 .template dValue<double>(
407 .template value<double>(vars, x_position, t, dt);
410 auto const dk_rel_dS_fr =
414 .template dValue<double>(
418 crv.dk_rel_dT = dk_rel_dS_fr * dS_fr_dT;
424 crv.solid_linear_thermal_expansion_coefficient =
429 .value(vars, x_position, t, dt));
433 crv.solid_linear_thermal_expansion_coefficient * dT_int_pt;
435 crv.K_pT_thermal_osmosis =
437 *medium, vars, x_position, t, dt, intrinsic_permeability,
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;
446 -crv.dk_rel_dT * crv.K_over_mu * dNdx * p +
448 (crv.dk_rel_dT * fluid_density + crv.k_rel * crv.drho_LR_dT) *
454 auto& eps_m = ip_data.
eps_m;
456 eps_m.noalias() = eps_m_prev + eps - eps_prev - dthermal_strain;
467 crv.rho = solid_density * (1 - porosity) + porosity * fluid_density;
470 porosity * fluid_volumetric_thermal_expansion_coefficient +
485 .template value<double>(vars, x_position, t, dt);
486 crv.effective_thermal_conductivity =
491 .value(vars, x_position, t, dt));
501 crv.effective_thermal_conductivity.noalias() +=
502 fluid_density * crv.c_f *
505 GlobalDimMatrixType::Zero(DisplacementDim, DisplacementDim),
512 .template value<double>(vars, x_position, t, dt);
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;
521 if (frozen_liquid_phase)
524 double const phi_fr = ip_data.
phi_fr;
526 auto const frozen_liquid_value =
529 return (*frozen_liquid_phase)[p].template value<double>(
530 vars, x_position, t, dt);
533 double const c_fr = frozen_liquid_value(
536 double const l_fr = frozen_liquid_value(
539 auto const dS_fr_dT =
542 .template dValue<double>(
545 double const dphi_fr_dT = dS_fr_dT * porosity;
547 auto const d2S_fr_dT2 =
550 .template d2Value<double>(
554 double const d2phi_fr_dT2 = d2S_fr_dT2 * porosity;
556 double const phi_fr_prev = [&]()
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;
568 double const rho_fr =
570 ip_data_output.
rho_fr = rho_fr;
572 crv.rho += ip_data.
phi_fr * rho_fr - ip_data.
phi_fr * fluid_density;
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);
582 DisplacementDim>
const ice_linear_thermal_expansion_coefficient =
587 .value(vars, x_position, t, dt));
590 dthermal_strain_ice =
591 ice_linear_thermal_expansion_coefficient * dT_int_pt;
598 crv.solid_linear_thermal_expansion_coefficient);
603 phase_change_expansion_coefficient =
607 phase_change_expansivity)
608 .value(vars, x_position, t, dt));
611 dphase_change_strain = phase_change_expansion_coefficient *
612 (phi_fr - phi_fr_prev) / porosity;
616 auto& eps0 = ip_data.
eps0;
617 auto const& eps0_prev = ip_data.
eps0_prev;
623 eps_m_ice.noalias() = eps_m_ice_prev + eps - eps_prev -
624 (eps0 - eps0_prev) - dthermal_strain_ice -
625 dphase_change_strain;
631 *
_process_data.ice_constitutive_relation, vars_ice, t, x_position,
636 static_cast<double>(T_int_pt));
638 1. /
_process_data.ice_constitutive_relation->getBulkModulus(
639 t, x_position, &C_el_ice);
642 crv.latent_volumetric_heat_capacity = l_fr * rho_fr * dphi_fr_dT;
645 crv.sensible_volumetric_heat_capacity +=
646 -phi_fr * fluid_density * crv.c_f + phi_fr * rho_fr * c_fr;
648 crv.J_uu_fr = phi_fr * C_IR;
651 crv.r_u_fr = phi_fr * sigma_eff_ice;
653 crv.J_uT_fr = phi_fr * C_IR * ice_linear_thermal_expansion_coefficient;
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;
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);
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;
676 (crv.beta_T_SI * rho_fr / fluid_density - crv.beta) -
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) -
684 crv.J_pT_fr += dstorage_T_fr_dT * dT_int_pt / dt;
686 crv.J_TT = dC_eff_dT * dT_int_pt / dt;
697 std::vector<double>
const& local_x,
698 std::vector<double>
const&
700 std::vector<double>& local_rhs_data,
701 std::vector<double>& local_Jac_data)
703 assert(local_x.size() ==
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());
711 auto const [T, p, u] =
localDOF(local_x);
712 auto const [T_prev, p_prev, u_prev] =
localDOF(local_x_prev);
715 typename ShapeMatricesTypeDisplacement::template MatrixType<
722 typename ShapeMatricesTypeDisplacement::template VectorType<
753 typename ShapeMatricesTypeDisplacement::template MatrixType<
758 typename ShapeMatricesTypeDisplacement::template MatrixType<
767 bool const has_frozen_liquid_phase =
770 unsigned const n_integration_points =
773 std::vector<GlobalDimVectorType> ip_flux_vector;
774 double average_velocity_norm = 0.0;
775 ip_flux_vector.reserve(n_integration_points);
777 for (
unsigned ip = 0; ip < n_integration_points; ip++)
780 auto const& N_u = ip_data.N_u;
791 auto const& w = ip_data.integration_weight;
793 auto const& dNdx_u = ip_data.dNdx_u;
795 auto const& N = ip_data.N;
796 auto const& dNdx = ip_data.dNdx;
798 auto const T_int_pt = N.dot(T);
804 ShapeFunctionDisplacement::NPOINTS,
815 auto const C_eff = has_frozen_liquid_phase
816 ? (crv.C + crv.J_uu_fr).eval()
819 .template block<displacement_size, displacement_size>(
821 .noalias() += B.transpose() * C_eff * B * w;
823 auto const uT_coeff =
824 has_frozen_liquid_phase
826 crv.C * crv.solid_linear_thermal_expansion_coefficient)
828 : (crv.C * crv.solid_linear_thermal_expansion_coefficient)
831 if (has_frozen_liquid_phase)
834 .noalias() -= B.transpose() * crv.r_u_fr * w;
838 .template block<displacement_size, temperature_size>(
840 .noalias() -= B.transpose() * uT_coeff * N * w;
843 .noalias() -= (B.transpose() * ip_data.sigma_eff -
844 N_u_op(N_u).transpose() * crv.rho * b) *
851 double const up_coeff =
852 has_frozen_liquid_phase
853 ? crv.alpha_biot * ip_data.phi_fr / ip_data.porosity *
863 double const scaling_factor =
864 _process_data.is_volume_balance_equation_type ? 1.0 : fluid_density;
866 laplace_p.noalias() += dNdx.transpose() * crv.K_over_mu * dNdx *
867 (crv.k_rel * scaling_factor * w);
871 .noalias() += dNdx.transpose() * crv.K_over_mu * (dNdx * p) * N *
872 (crv.dk_rel_dT * scaling_factor * w);
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;
881 storage_p.noalias() +=
882 N.transpose() * N * (storage_p_coeff * scaling_factor * w);
884 if (has_frozen_liquid_phase)
887 .template block<pressure_size, temperature_size>(
890 N.transpose() * crv.J_pT_fr * N * scaling_factor * w;
893 laplace_T.noalias() += dNdx.transpose() * crv.K_pT_thermal_osmosis *
894 dNdx * scaling_factor * w;
898 local_rhs.template segment<pressure_size>(
pressure_index).noalias() -=
899 N * (up_coeff * crv.eps_v_dot * scaling_factor * w);
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);
907 .noalias() -= dNdx.transpose() * crv.K_over_mu * b * N *
908 (fluid_density * crv.dk_rel_dT * scaling_factor * w);
914 double const storage_T_coeff =
915 has_frozen_liquid_phase ? crv.storage_T_fr + crv.beta : crv.beta;
917 storage_T.noalias() +=
918 N.transpose() * storage_T_coeff * N * scaling_factor * w;
928 B * (up_coeff * scaling_factor * w);
934 double const storage_p_solid_coeff =
935 (crv.alpha_biot - ip_data.porosity) * crv.beta_SR;
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;
948 N.transpose() * N * (drho_dp_coeff * crv.drho_LR_dp * w);
950 .template block<pressure_size, temperature_size>(
954 N.transpose() * N * (drho_dp_coeff * crv.drho_LR_dT * w);
959 auto const dlaplace_temporal_factor =
960 (-velocity - (fluid_density * crv.k_rel) * crv.K_over_mu * b);
964 .noalias() += dNdx.transpose() * dlaplace_temporal_factor * N *
965 (crv.drho_LR_dp * w);
967 .template block<pressure_size, temperature_size>(
969 .noalias() += dNdx.transpose() * dlaplace_temporal_factor * N *
970 (crv.drho_LR_dT * w);
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;
981 ip_flux_vector.emplace_back(velocity * fluid_density * crv.c_f);
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();
992 MTT.noalias() += N.transpose() *
993 (crv.sensible_volumetric_heat_capacity -
994 crv.latent_volumetric_heat_capacity) *
997 .template block<temperature_size, temperature_size>(
999 .noalias() += N.transpose() * crv.J_TT * N * w;
1005 dNdx.transpose() * crv.K_pT_thermal_osmosis * dNdx * (T_int_pt * w);
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);
1057 average_velocity_norm /
static_cast<double>(n_integration_points), KTT);
1063 .noalias() += KTT + dKTT_dT_T + MTT / dt;
1069 .noalias() += KTp + dKTT_dp_T;
1081 .noalias() += -storage_T / dt + laplace_T;
1087 .noalias() += laplace_p + storage_p / dt;
1093 .template block<pressure_size, displacement_size>(
1095 .noalias() += Kup.transpose() / dt;
1100 .template block<pressure_size, displacement_size>(
1102 .noalias() += Kpu / dt;
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;
1112 .noalias() += Kup * p;
1116 KTT * T + MTT * (T - T_prev) / dt;