102 ShapeFunctionPressure, DisplacementDim>::
103 assembleWithJacobian(
double const t,
double const dt,
104 std::vector<double>
const& local_x,
105 std::vector<double>
const& local_x_prev,
106 std::vector<double>& local_rhs_data,
107 std::vector<double>& local_Jac_data)
109 assert(local_x.size() == pressure_size + displacement_size);
111 auto p = Eigen::Map<
typename ShapeMatricesTypePressure::template VectorType<
112 pressure_size>
const>(local_x.data() + pressure_index, pressure_size);
115 Eigen::Map<
typename ShapeMatricesTypeDisplacement::template VectorType<
116 displacement_size>
const>(local_x.data() + displacement_index,
120 Eigen::Map<
typename ShapeMatricesTypePressure::template VectorType<
121 pressure_size>
const>(local_x_prev.data() + pressure_index,
124 Eigen::Map<
typename ShapeMatricesTypeDisplacement::template VectorType<
125 displacement_size>
const>(local_x_prev.data() + displacement_index,
129 typename ShapeMatricesTypeDisplacement::template MatrixType<
130 displacement_size + pressure_size,
131 displacement_size + pressure_size>>(
132 local_Jac_data, displacement_size + pressure_size,
133 displacement_size + pressure_size);
136 typename ShapeMatricesTypeDisplacement::template VectorType<
137 displacement_size + pressure_size>>(
138 local_rhs_data, displacement_size + pressure_size);
141 ShapeMatricesTypePressure::NodalMatrixType::Zero(pressure_size,
145 ShapeMatricesTypePressure::NodalMatrixType::Zero(pressure_size,
149 ShapeMatricesTypePressure::NodalMatrixType::Zero(pressure_size,
152 typename ShapeMatricesTypeDisplacement::template MatrixType<
153 displacement_size, pressure_size>
154 Kup = ShapeMatricesTypeDisplacement::template MatrixType<
155 displacement_size, pressure_size>::Zero(displacement_size,
158 typename ShapeMatricesTypeDisplacement::template MatrixType<
159 pressure_size, displacement_size>
160 Kpu = ShapeMatricesTypeDisplacement::template MatrixType<
161 pressure_size, displacement_size>::Zero(pressure_size,
164 typename ShapeMatricesTypeDisplacement::template MatrixType<
165 pressure_size, displacement_size>
166 Kpu_k = ShapeMatricesTypeDisplacement::template MatrixType<
167 pressure_size, displacement_size>::Zero(pressure_size,
170 auto const& solid_material =
172 _process_data.solid_materials, _process_data.material_ids,
178 unsigned const n_integration_points =
179 _integration_method.getNumberOfPoints();
181 auto const& b = _process_data.specific_body_force;
182 auto const& medium = _process_data.media_map.getMedium(_element.getID());
183 auto const& solid = medium->phase(
"Solid");
184 auto const& fluid = fluidPhase(*medium);
190 medium->property(MPL::PropertyType::reference_temperature)
191 .template value<double>(vars, x_position, t, dt);
194 auto const& identity2 = Invariants::identity2;
196 for (
unsigned ip = 0; ip < n_integration_points; ip++)
199 auto const& w = _ip_data[ip].integration_weight;
201 auto const& N_u = _ip_data[ip].N_u;
202 auto const& dNdx_u = _ip_data[ip].dNdx_u;
204 auto const& N_p = _ip_data[ip].N_p;
205 auto const& dNdx_p = _ip_data[ip].dNdx_p;
213 ShapeFunctionDisplacement::NPOINTS,
215 dNdx_u, N_u, x_coord, _is_axially_symmetric);
217 auto& eps = _ip_data[ip].eps;
218 eps.noalias() = B * u;
219 auto const& sigma_eff = _ip_data[ip].sigma_eff;
221 double const p_int_pt = N_p.dot(p);
223 phase_pressure = p_int_pt;
225 auto const C_el = _ip_data[ip].computeElasticTangentStiffness(
226 t, x_position, dt, T_ref);
227 auto const K_S = solid_material.getBulkModulus(t, x_position, &C_el);
229 auto const alpha = medium->property(MPL::PropertyType::biot_coefficient)
230 .template value<double>(vars, x_position, t, dt);
233 solid.property(MPL::PropertyType::density)
234 .template value<double>(vars, x_position, t, dt);
235 auto const porosity =
236 medium->property(MPL::PropertyType::porosity)
237 .template value<double>(vars, x_position, t, dt);
244 if (fluid.hasProperty(MPL::PropertyType::molar_mass))
247 fluid.property(MPL::PropertyType::molar_mass)
248 .template value<double>(vars, x_position, t, dt);
251 fluid.property(MPL::PropertyType::density)
252 .template value<double>(vars, x_position, t, dt);
255 auto const mu = fluid.property(MPL::PropertyType::viscosity)
256 .template value<double>(vars, x_position, t, dt);
259 fluid.property(MPL::PropertyType::density)
260 .template dValue<double>(vars, _process_data.phase_variable,
267 auto const sigma_total =
268 (_ip_data[ip].sigma_eff - alpha * p_int_pt * identity2).eval();
277 _ip_data[ip].material_state_variables->getEquivalentPlasticStrain();
283 medium->property(MPL::PropertyType::permeability)
284 .value(vars, x_position, t, dt));
287 (*medium)[MPL::PropertyType::permeability].dValue(
288 vars, MPL::Variable::mechanical_strain, x_position, t, dt));
290 auto const K_over_mu = K / mu;
292 auto C = _ip_data[ip].updateConstitutiveRelation(vars, t, x_position,
299 .template block<displacement_size, displacement_size>(
300 displacement_index, displacement_index)
301 .noalias() += B.transpose() * C * B * w;
303 double const rho = rho_sr * (1 - porosity) + porosity * rho_fr;
304 local_rhs.template segment<displacement_size>(displacement_index)
306 (B.transpose() * sigma_eff - N_u_op(N_u).transpose() * rho * b) * w;
311 Kup.noalias() += B.transpose() * alpha * identity2 * N_p * w;
316 laplace_p.noalias() +=
317 rho_fr * dNdx_p.transpose() * K_over_mu * dNdx_p * w;
319 storage_p.noalias() +=
320 rho_fr * N_p.transpose() * N_p * w *
321 ((alpha - porosity) * (1.0 - alpha) / K_S + porosity * beta_p);
325 add_p_derivative.noalias() += rho_fr * beta_p * dNdx_p.transpose() *
327 (dNdx_p * p - 2.0 * rho_fr * b) * N_p * w;
329 local_rhs.template segment<pressure_size>(pressure_index).noalias() +=
330 dNdx_p.transpose() * rho_fr * rho_fr * K_over_mu * b * w;
336 rho_fr * alpha * N_p.transpose() * identity2.transpose() * B * w;
341 dNdx_p * p - rho_fr * b) *
342 dkde * B * rho_fr / mu * w;
346 .template block<displacement_size, pressure_size>(displacement_index,
350 if (_process_data.mass_lumping)
352 storage_p = storage_p.colwise().sum().eval().asDiagonal();
354 if constexpr (pressure_size == displacement_size)
356 Kpu = Kpu.colwise().sum().eval().asDiagonal();
357 Kpu_k = Kpu_k.colwise().sum().eval().asDiagonal();
363 .template block<pressure_size, pressure_size>(pressure_index,
365 .noalias() += laplace_p + storage_p / dt + add_p_derivative;
369 .template block<pressure_size, displacement_size>(pressure_index,
371 .noalias() += Kpu / dt + Kpu_k;
374 local_rhs.template segment<pressure_size>(pressure_index).noalias() -=
375 laplace_p * p + storage_p * (p - p_prev) / dt + Kpu * (u - u_prev) / dt;
378 local_rhs.template segment<displacement_size>(displacement_index)
379 .noalias() += Kup * p;
385 ShapeFunctionDisplacement, ShapeFunctionPressure, DisplacementDim>::
386 getIntPtDarcyVelocity(
388 std::vector<GlobalVector*>
const& x,
389 std::vector<NumLib::LocalToGlobalIndexMap const*>
const& dof_table,
390 std::vector<double>& cache)
const
392 int const hydraulic_process_id = _process_data.hydraulic_process_id;
395 assert(!indices.empty());
396 auto const local_x = x[hydraulic_process_id]->get(indices);
398 unsigned const n_integration_points =
399 _integration_method.getNumberOfPoints();
402 double, DisplacementDim, Eigen::Dynamic, Eigen::RowMajor>>(
403 cache, DisplacementDim, n_integration_points);
405 auto p = Eigen::Map<
typename ShapeMatricesTypePressure::template VectorType<
406 pressure_size>
const>(local_x.data() + pressure_index, pressure_size);
411 auto const& medium = _process_data.media_map.getMedium(_element.getID());
412 auto const& fluid = fluidPhase(*medium);
419 double const dt = std::numeric_limits<double>::quiet_NaN();
421 medium->property(MPL::PropertyType::reference_temperature)
422 .template value<double>(vars, x_position, t, dt);
424 auto const& identity2 = Invariants::identity2;
426 for (
unsigned ip = 0; ip < n_integration_points; ip++)
430 double const p_int_pt = _ip_data[ip].N_p.dot(p);
432 phase_pressure = p_int_pt;
434 auto const alpha = medium->property(MPL::PropertyType::biot_coefficient)
435 .template value<double>(vars, x_position, t, dt);
439 auto const sigma_total =
440 (_ip_data[ip].sigma_eff - alpha * p_int_pt * identity2).eval();
447 _ip_data[ip].material_state_variables->getEquivalentPlasticStrain();
453 medium->property(MPL::PropertyType::permeability)
454 .value(vars, x_position, t, dt));
461 if (fluid.hasProperty(MPL::PropertyType::molar_mass))
464 fluid.property(MPL::PropertyType::molar_mass)
465 .template value<double>(vars, x_position, t, dt);
469 fluid.property(MPL::PropertyType::density)
470 .template value<double>(vars, x_position, t, dt);
473 auto const mu = fluid.property(MPL::PropertyType::viscosity)
474 .template value<double>(vars, x_position, t, dt);
476 auto const K_over_mu = K / mu;
478 auto const& b = _process_data.specific_body_force;
481 auto const& dNdx_p = _ip_data[ip].dNdx_p;
482 cache_matrix.col(ip).noalias() =
483 -K_over_mu * dNdx_p * p + K_over_mu * rho_fr * b;
492 ShapeFunctionPressure, DisplacementDim>::
493 assembleWithJacobianForPressureEquations(
494 const double t,
double const dt, Eigen::VectorXd
const& local_x,
495 Eigen::VectorXd
const& local_x_prev, std::vector<double>& local_b_data,
496 std::vector<double>& local_Jac_data)
500 template VectorType<pressure_size>>(
501 local_b_data, pressure_size);
506 auto const p = local_x.template segment<pressure_size>(pressure_index);
509 local_x_prev.template segment<pressure_size>(pressure_index);
512 typename ShapeMatricesTypeDisplacement::template MatrixType<
513 pressure_size, pressure_size>>(local_Jac_data, pressure_size,
517 ShapeMatricesTypePressure::NodalMatrixType::Zero(pressure_size,
521 ShapeMatricesTypePressure::NodalMatrixType::Zero(pressure_size,
525 ShapeMatricesTypePressure::NodalMatrixType::Zero(pressure_size,
528 auto const& solid_material =
530 _process_data.solid_materials, _process_data.material_ids,
536 auto const& medium = _process_data.media_map.getMedium(_element.getID());
537 auto const& fluid = fluidPhase(*medium);
543 medium->property(MPL::PropertyType::reference_temperature)
544 .template value<double>(vars, x_position, t, dt);
547 auto const& identity2 = Invariants::identity2;
549 auto const staggered_scheme =
550 std::get<Staggered>(_process_data.coupling_scheme);
551 auto const fixed_stress_stabilization_parameter =
552 staggered_scheme.fixed_stress_stabilization_parameter;
553 auto const fixed_stress_over_time_step =
554 staggered_scheme.fixed_stress_over_time_step;
556 int const n_integration_points = _integration_method.getNumberOfPoints();
557 for (
int ip = 0; ip < n_integration_points; ip++)
560 auto const& w = _ip_data[ip].integration_weight;
562 auto const& N_p = _ip_data[ip].N_p;
563 auto const& dNdx_p = _ip_data[ip].dNdx_p;
565 double const p_int_pt = N_p.dot(p);
567 phase_pressure = p_int_pt;
569 auto const C_el = _ip_data[ip].computeElasticTangentStiffness(
570 t, x_position, dt, T_ref);
571 auto const K_S = solid_material.getBulkModulus(t, x_position, &C_el);
574 medium->property(MPL::PropertyType::biot_coefficient)
575 .template value<double>(vars, x_position, t, dt);
579 auto const sigma_total =
580 (_ip_data[ip].sigma_eff - alpha_b * p_int_pt * identity2).eval();
587 _ip_data[ip].material_state_variables->getEquivalentPlasticStrain();
593 medium->property(MPL::PropertyType::permeability)
594 .value(vars, x_position, t, dt));
595 auto const porosity =
596 medium->property(MPL::PropertyType::porosity)
597 .template value<double>(vars, x_position, t, dt);
604 if (fluid.hasProperty(MPL::PropertyType::molar_mass))
607 fluid.property(MPL::PropertyType::molar_mass)
608 .template value<double>(vars, x_position, t, dt);
611 fluid.property(MPL::PropertyType::density)
612 .template value<double>(vars, x_position, t, dt);
615 auto const mu = fluid.property(MPL::PropertyType::viscosity)
616 .template value<double>(vars, x_position, t, dt);
618 fluid.property(MPL::PropertyType::density)
619 .template dValue<double>(vars, _process_data.phase_variable,
623 auto const K_over_mu = K / mu;
626 rho_fr * dNdx_p.transpose() * K_over_mu * dNdx_p * w;
630 fixed_stress_stabilization_parameter * alpha_b * alpha_b / K_S;
632 storage.noalias() += rho_fr * N_p.transpose() * N_p * w *
633 ((alpha_b - porosity) * (1.0 - alpha_b) / K_S +
634 porosity * beta_p + beta_FS);
636 auto const& b = _process_data.specific_body_force;
639 local_rhs.noalias() +=
640 dNdx_p.transpose() * rho_fr * rho_fr * K_over_mu * b * w;
645 add_p_derivative.noalias() += rho_fr * beta_p * dNdx_p.transpose() *
647 (dNdx_p * p - 2.0 * rho_fr * b) * N_p * w;
649 if (!fixed_stress_over_time_step)
651 auto const& eps = _ip_data[ip].eps;
652 auto const& eps_prev = _ip_data[ip].eps_prev;
653 const double eps_v_dot =
654 (Invariants::trace(eps) - Invariants::trace(eps_prev)) / dt;
657 double const strain_rate_b =
658 alpha_b * eps_v_dot -
659 beta_FS * _ip_data[ip].strain_rate_variable;
661 local_rhs.noalias() -= strain_rate_b * rho_fr * N_p * w;
666 local_rhs.noalias() -=
667 alpha_b * _ip_data[ip].strain_rate_variable * rho_fr * N_p * w;
670 local_Jac.noalias() = laplace + storage / dt + add_p_derivative;
672 local_rhs.noalias() -= laplace * p + storage * (p - p_prev) / dt;
678 ShapeFunctionPressure, DisplacementDim>::
679 assembleWithJacobianForDeformationEquations(
680 const double t,
double const dt, Eigen::VectorXd
const& local_x,
681 std::vector<double>& local_b_data, std::vector<double>& local_Jac_data)
683 auto const p = local_x.template segment<pressure_size>(pressure_index);
685 local_x.template segment<displacement_size>(displacement_index);
688 typename ShapeMatricesTypeDisplacement::template MatrixType<
689 displacement_size, displacement_size>>(
690 local_Jac_data, displacement_size, displacement_size);
694 template VectorType<displacement_size>>(
695 local_b_data, displacement_size);
700 auto const& medium = _process_data.media_map.getMedium(_element.getID());
701 auto const& solid = medium->phase(
"Solid");
702 auto const& fluid = fluidPhase(*medium);
708 medium->property(MPL::PropertyType::reference_temperature)
709 .template value<double>(vars, x_position, t, dt);
712 int const n_integration_points = _integration_method.getNumberOfPoints();
713 for (
int ip = 0; ip < n_integration_points; ip++)
715 x_position.setIntegrationPoint(ip);
716 auto const& w = _ip_data[ip].integration_weight;
718 auto const& N_u = _ip_data[ip].N_u;
719 auto const& dNdx_u = _ip_data[ip].dNdx_u;
721 auto const& N_p = _ip_data[ip].N_p;
729 ShapeFunctionDisplacement::NPOINTS,
731 dNdx_u, N_u, x_coord, _is_axially_symmetric);
733 auto& eps = _ip_data[ip].eps;
734 auto const& sigma_eff = _ip_data[ip].sigma_eff;
736 phase_pressure = N_p.dot(p);
738 auto const alpha = medium->property(MPL::PropertyType::biot_coefficient)
739 .template value<double>(vars, x_position, t, dt);
741 solid.property(MPL::PropertyType::density)
742 .template value<double>(vars, x_position, t, dt);
743 auto const porosity =
744 medium->property(MPL::PropertyType::porosity)
745 .template value<double>(vars, x_position, t, dt);
752 if (fluid.hasProperty(MPL::PropertyType::molar_mass))
755 fluid.property(MPL::PropertyType::molar_mass)
756 .template value<double>(vars, x_position, t, dt);
759 fluid.property(MPL::PropertyType::density)
760 .template value<double>(vars, x_position, t, dt);
762 auto const& b = _process_data.specific_body_force;
765 DisplacementDim)>::identity2;
767 eps.noalias() = B * u;
772 auto C = _ip_data[ip].updateConstitutiveRelation(vars, t, x_position,
775 local_Jac.noalias() += B.transpose() * C * B * w;
780 double const rho = rho_sr * (1 - porosity) + porosity * rho_fr;
781 local_rhs.noalias() -=
782 (B.transpose() * (sigma_eff - alpha * identity2 * p_at_xi) -
783 N_u_op(N_u).transpose() * rho * b) *
874 ShapeFunctionPressure, DisplacementDim>::
875 postNonLinearSolverConcrete(Eigen::VectorXd
const& local_x,
876 Eigen::VectorXd
const& local_x_prev,
877 double const t,
double const dt,
878 int const process_id)
884 int const n_integration_points = _integration_method.getNumberOfPoints();
886 auto const staggered_scheme_ptr =
887 std::get_if<Staggered>(&_process_data.coupling_scheme);
889 if (staggered_scheme_ptr &&
890 process_id == _process_data.hydraulic_process_id)
892 if (!staggered_scheme_ptr->fixed_stress_over_time_step)
895 local_x.template segment<pressure_size>(pressure_index);
897 local_x_prev.template segment<pressure_size>(pressure_index);
899 for (
int ip = 0; ip < n_integration_points; ip++)
901 auto& ip_data = _ip_data[ip];
903 auto const& N_p = ip_data.N_p;
905 ip_data.strain_rate_variable = N_p.dot(p - p_prev) / dt;
910 if (!staggered_scheme_ptr ||
911 process_id == _process_data.mechanics_related_process_id)
917 _process_data.media_map.getMedium(_element.getID());
920 medium->property(MPL::PropertyType::reference_temperature)
925 local_x.template segment<displacement_size>(displacement_index);
930 for (
int ip = 0; ip < n_integration_points; ip++)
933 auto const& N_u = _ip_data[ip].N_u;
934 auto const& dNdx_u = _ip_data[ip].dNdx_u;
941 DisplacementDim, ShapeFunctionDisplacement::NPOINTS,
943 _is_axially_symmetric);
945 auto& eps = _ip_data[ip].eps;
946 eps.noalias() = B * u;
950 _ip_data[ip].updateConstitutiveRelation(vars, t, x_position, dt, u,
960 DisplacementDim>::postTimestepConcrete(Eigen::VectorXd
const& local_x,
961 Eigen::VectorXd
const& local_x_prev,
962 double const t,
double const dt,
963 int const process_id)
965 auto const staggered_scheme_ptr =
966 std::get_if<Staggered>(&_process_data.coupling_scheme);
968 if (staggered_scheme_ptr &&
969 process_id == _process_data.hydraulic_process_id)
971 if (staggered_scheme_ptr->fixed_stress_over_time_step)
973 auto const fixed_stress_stabilization_parameter =
974 staggered_scheme_ptr->fixed_stress_stabilization_parameter;
977 local_x.template segment<pressure_size>(pressure_index);
979 local_x_prev.template segment<pressure_size>(pressure_index);
984 auto const& solid_material =
986 _process_data.solid_materials, _process_data.material_ids,
990 _process_data.media_map.getMedium(_element.getID());
994 medium->property(MPL::PropertyType::reference_temperature)
995 .template value<double>(vars, x_position, t, dt);
998 int const n_integration_points =
999 _integration_method.getNumberOfPoints();
1000 for (
int ip = 0; ip < n_integration_points; ip++)
1002 auto& ip_data = _ip_data[ip];
1004 auto const& N_p = ip_data.N_p;
1006 auto const& eps = ip_data.eps;
1007 auto const& eps_prev = ip_data.eps_prev;
1008 const double eps_v_dot =
1009 (Invariants::trace(eps) - Invariants::trace(eps_prev)) / dt;
1011 auto const C_el = ip_data.computeElasticTangentStiffness(
1012 t, x_position, dt, T_ref);
1014 solid_material.getBulkModulus(t, x_position, &C_el);
1016 auto const alpha_b =
1017 medium->property(MPL::PropertyType::biot_coefficient)
1018 .template value<double>(vars, x_position, t, dt);
1020 ip_data.strain_rate_variable =
1021 eps_v_dot - fixed_stress_stabilization_parameter * alpha_b *
1022 N_p.dot(p - p_prev) / dt / K_S;
1027 unsigned const n_integration_points =
1028 _integration_method.getNumberOfPoints();
1030 for (
unsigned ip = 0; ip < n_integration_points; ip++)
1032 _ip_data[ip].pushBackState();
1142 ShapeFunctionPressure, DisplacementDim>::
1143 computeSecondaryVariableConcrete(
double const t,
double const dt,
1144 Eigen::VectorXd
const& local_x,
1145 Eigen::VectorXd
const& )
1147 auto const p = local_x.template segment<pressure_size>(pressure_index);
1150 ShapeFunctionPressure,
typename ShapeFunctionDisplacement::MeshElement,
1151 DisplacementDim>(_element, _is_axially_symmetric, p,
1152 *_process_data.pressure_interpolated);
1154 int const elem_id = _element.getID();
1157 unsigned const n_integration_points =
1158 _integration_method.getNumberOfPoints();
1160 auto const& medium = _process_data.media_map.getMedium(elem_id);
1167 Eigen::Matrix<double, 3, 3>::Zero());
1169 auto const& identity2 = Invariants::identity2;
1171 for (
unsigned ip = 0; ip < n_integration_points; ip++)
1175 auto const& eps = _ip_data[ip].eps;
1176 sigma_eff_sum += _ip_data[ip].sigma_eff;
1178 auto const alpha = medium->property(MPL::PropertyType::biot_coefficient)
1179 .template value<double>(vars, x_position, t, dt);
1180 double const p_int_pt = _ip_data[ip].N_p.dot(p);
1182 phase_pressure = p_int_pt;
1187 auto const sigma_total =
1188 (_ip_data[ip].sigma_eff - alpha * p_int_pt * identity2).eval();
1196 _ip_data[ip].material_state_variables->getEquivalentPlasticStrain();
1202 medium->property(MPL::PropertyType::permeability)
1203 .value(vars, x_position, t, dt));
1206 Eigen::Map<Eigen::VectorXd>(
1207 &(*_process_data.permeability)[elem_id * KelvinVectorSize],
1208 KelvinVectorSize) = k_sum / n_integration_points;
1210 Eigen::Matrix<double, 3, 3, 0, 3, 3>
const sigma_avg =
1212 n_integration_points;
1214 Eigen::SelfAdjointEigenSolver<Eigen::Matrix<double, 3, 3>> e_s(sigma_avg);
1216 Eigen::Map<Eigen::Vector3d>(
1217 &(*_process_data.principal_stress_values)[elem_id * 3], 3) =
1220 auto eigen_vectors = e_s.eigenvectors();
1222 for (
auto i = 0; i < 3; i++)
1224 Eigen::Map<Eigen::Vector3d>(
1225 &(*_process_data.principal_stress_vector[i])[elem_id * 3], 3) =
1226 eigen_vectors.col(i);