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>& ,
107 std::vector<double>& ,
108 std::vector<double>& local_rhs_data,
109 std::vector<double>& local_Jac_data)
111 assert(local_x.size() == pressure_size + displacement_size);
113 auto p = Eigen::Map<
typename ShapeMatricesTypePressure::template VectorType<
114 pressure_size>
const>(local_x.data() + pressure_index, pressure_size);
117 Eigen::Map<
typename ShapeMatricesTypeDisplacement::template VectorType<
118 displacement_size>
const>(local_x.data() + displacement_index,
122 Eigen::Map<
typename ShapeMatricesTypePressure::template VectorType<
123 pressure_size>
const>(local_x_prev.data() + pressure_index,
126 Eigen::Map<
typename ShapeMatricesTypeDisplacement::template VectorType<
127 displacement_size>
const>(local_x_prev.data() + displacement_index,
131 typename ShapeMatricesTypeDisplacement::template MatrixType<
132 displacement_size + pressure_size,
133 displacement_size + pressure_size>>(
134 local_Jac_data, displacement_size + pressure_size,
135 displacement_size + pressure_size);
138 typename ShapeMatricesTypeDisplacement::template VectorType<
139 displacement_size + pressure_size>>(
140 local_rhs_data, displacement_size + pressure_size);
143 ShapeMatricesTypePressure::NodalMatrixType::Zero(pressure_size,
147 ShapeMatricesTypePressure::NodalMatrixType::Zero(pressure_size,
151 ShapeMatricesTypePressure::NodalMatrixType::Zero(pressure_size,
154 typename ShapeMatricesTypeDisplacement::template MatrixType<
155 displacement_size, pressure_size>
156 Kup = ShapeMatricesTypeDisplacement::template MatrixType<
157 displacement_size, pressure_size>::Zero(displacement_size,
160 typename ShapeMatricesTypeDisplacement::template MatrixType<
161 pressure_size, displacement_size>
162 Kpu = ShapeMatricesTypeDisplacement::template MatrixType<
163 pressure_size, displacement_size>::Zero(pressure_size,
166 typename ShapeMatricesTypeDisplacement::template MatrixType<
167 pressure_size, displacement_size>
168 Kpu_k = ShapeMatricesTypeDisplacement::template MatrixType<
169 pressure_size, displacement_size>::Zero(pressure_size,
172 auto const& solid_material =
174 _process_data.solid_materials, _process_data.material_ids,
180 unsigned const n_integration_points =
181 _integration_method.getNumberOfPoints();
183 auto const& b = _process_data.specific_body_force;
184 auto const& medium = _process_data.media_map.getMedium(_element.getID());
185 auto const& solid = medium->phase(
"Solid");
186 auto const& fluid = fluidPhase(*medium);
187 auto const& phase_pressure = _process_data.phase_pressure;
191 medium->property(MPL::PropertyType::reference_temperature)
192 .template value<double>(vars, x_position, t, dt);
195 auto const& identity2 = Invariants::identity2;
197 for (
unsigned ip = 0; ip < n_integration_points; ip++)
200 auto const& w = _ip_data[ip].integration_weight;
202 auto const& N_u = _ip_data[ip].N_u;
203 auto const& dNdx_u = _ip_data[ip].dNdx_u;
205 auto const& N_p = _ip_data[ip].N_p;
206 auto const& dNdx_p = _ip_data[ip].dNdx_p;
214 ShapeFunctionDisplacement::NPOINTS,
216 dNdx_u, N_u, x_coord, _is_axially_symmetric);
218 auto& eps = _ip_data[ip].eps;
219 eps.noalias() = B * u;
220 auto const& sigma_eff = _ip_data[ip].sigma_eff;
222 double const p_int_pt = N_p.dot(p);
228 auto const C_el = _ip_data[ip].computeElasticTangentStiffness(
229 t, x_position, dt, T_ref);
230 auto const K_S = solid_material.getBulkModulus(t, x_position, &C_el);
232 auto const alpha = medium->property(MPL::PropertyType::biot_coefficient)
233 .template value<double>(vars, x_position, t, dt);
236 solid.property(MPL::PropertyType::density)
237 .template value<double>(vars, x_position, t, dt);
238 auto const porosity =
239 medium->property(MPL::PropertyType::porosity)
240 .template value<double>(vars, x_position, t, dt);
247 if (fluid.hasProperty(MPL::PropertyType::molar_mass))
250 fluid.property(MPL::PropertyType::molar_mass)
251 .template value<double>(vars, x_position, t, dt);
254 fluid.property(MPL::PropertyType::density)
255 .template value<double>(vars, x_position, t, dt);
258 auto const mu = fluid.property(MPL::PropertyType::viscosity)
259 .template value<double>(vars, x_position, t, dt);
261 auto const beta_p = fluid.property(MPL::PropertyType::density)
262 .template dValue<double>(vars, phase_pressure,
269 auto const sigma_total =
270 (_ip_data[ip].sigma_eff - alpha * p_int_pt * identity2).eval();
279 _ip_data[ip].material_state_variables->getEquivalentPlasticStrain();
284 auto const K = MPL::formEigenTensor<DisplacementDim>(
285 medium->property(MPL::PropertyType::permeability)
286 .value(vars, x_position, t, dt));
289 (*medium)[MPL::PropertyType::permeability].dValue(
290 vars, MPL::Variable::mechanical_strain, x_position, t, dt));
292 auto const K_over_mu = K / mu;
294 auto C = _ip_data[ip].updateConstitutiveRelation(vars, t, x_position,
301 .template block<displacement_size, displacement_size>(
302 displacement_index, displacement_index)
303 .noalias() += B.transpose() * C * B * w;
305 double const rho = rho_sr * (1 - porosity) + porosity * rho_fr;
306 local_rhs.template segment<displacement_size>(displacement_index)
308 (B.transpose() * sigma_eff - N_u_op(N_u).transpose() * rho * b) * w;
313 Kup.noalias() += B.transpose() * alpha * identity2 * N_p * w;
318 laplace_p.noalias() +=
319 rho_fr * dNdx_p.transpose() * K_over_mu * dNdx_p * w;
321 storage_p.noalias() +=
322 rho_fr * N_p.transpose() * N_p * w *
323 ((alpha - porosity) * (1.0 - alpha) / K_S + porosity * beta_p);
327 add_p_derivative.noalias() += rho_fr * beta_p * dNdx_p.transpose() *
329 (dNdx_p * p - 2.0 * rho_fr * b) * N_p * w;
331 local_rhs.template segment<pressure_size>(pressure_index).noalias() +=
332 dNdx_p.transpose() * rho_fr * rho_fr * K_over_mu * b * w;
338 rho_fr * alpha * N_p.transpose() * identity2.transpose() * B * w;
342 MathLib::KelvinVector::liftVectorToKelvin<DisplacementDim>(
343 dNdx_p * p - rho_fr * b) *
344 dkde * B * rho_fr / mu * w;
348 .template block<displacement_size, pressure_size>(displacement_index,
352 if (_process_data.mass_lumping)
354 storage_p = storage_p.colwise().sum().eval().asDiagonal();
356 if constexpr (pressure_size == displacement_size)
358 Kpu = Kpu.colwise().sum().eval().asDiagonal();
359 Kpu_k = Kpu_k.colwise().sum().eval().asDiagonal();
365 .template block<pressure_size, pressure_size>(pressure_index,
367 .noalias() += laplace_p + storage_p / dt + add_p_derivative;
371 .template block<pressure_size, displacement_size>(pressure_index,
373 .noalias() += Kpu / dt + Kpu_k;
376 local_rhs.template segment<pressure_size>(pressure_index).noalias() -=
377 laplace_p * p + storage_p * (p - p_prev) / dt + Kpu * (u - u_prev) / dt;
380 local_rhs.template segment<displacement_size>(displacement_index)
381 .noalias() += Kup * p;
387 ShapeFunctionDisplacement, ShapeFunctionPressure, DisplacementDim>::
388 getIntPtDarcyVelocity(
390 std::vector<GlobalVector*>
const& x,
391 std::vector<NumLib::LocalToGlobalIndexMap const*>
const& dof_table,
392 std::vector<double>& cache)
const
394 int const hydraulic_process_id = _process_data.hydraulic_process_id;
397 assert(!indices.empty());
398 auto const local_x = x[hydraulic_process_id]->get(indices);
400 unsigned const n_integration_points =
401 _integration_method.getNumberOfPoints();
404 double, DisplacementDim, Eigen::Dynamic, Eigen::RowMajor>>(
405 cache, DisplacementDim, n_integration_points);
407 auto p = Eigen::Map<
typename ShapeMatricesTypePressure::template VectorType<
408 pressure_size>
const>(local_x.data() + pressure_index, pressure_size);
413 auto const& medium = _process_data.media_map.getMedium(_element.getID());
414 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++)
428 x_position.setIntegrationPoint(ip);
430 double const p_int_pt = _ip_data[ip].N_p.dot(p);
436 auto const alpha = medium->property(MPL::PropertyType::biot_coefficient)
437 .template value<double>(vars, x_position, t, dt);
441 auto const sigma_total =
442 (_ip_data[ip].sigma_eff - alpha * p_int_pt * identity2).eval();
449 _ip_data[ip].material_state_variables->getEquivalentPlasticStrain();
454 auto const K = MPL::formEigenTensor<DisplacementDim>(
455 medium->property(MPL::PropertyType::permeability)
456 .value(vars, x_position, t, dt));
463 if (fluid.hasProperty(MPL::PropertyType::molar_mass))
466 fluid.property(MPL::PropertyType::molar_mass)
467 .template value<double>(vars, x_position, t, dt);
471 fluid.property(MPL::PropertyType::density)
472 .template value<double>(vars, x_position, t, dt);
475 auto const mu = fluid.property(MPL::PropertyType::viscosity)
476 .template value<double>(vars, x_position, t, dt);
478 auto const K_over_mu = K / mu;
480 auto const& b = _process_data.specific_body_force;
483 auto const& dNdx_p = _ip_data[ip].dNdx_p;
484 cache_matrix.col(ip).noalias() =
485 -K_over_mu * dNdx_p * p + K_over_mu * rho_fr * b;
494 ShapeFunctionPressure, DisplacementDim>::
495 assembleWithJacobianForPressureEquations(
496 const double t,
double const dt, Eigen::VectorXd
const& local_x,
497 Eigen::VectorXd
const& local_x_prev, std::vector<double>& local_b_data,
498 std::vector<double>& local_Jac_data)
502 template VectorType<pressure_size>>(
503 local_b_data, pressure_size);
508 auto const p = local_x.template segment<pressure_size>(pressure_index);
511 local_x_prev.template segment<pressure_size>(pressure_index);
514 typename ShapeMatricesTypeDisplacement::template MatrixType<
515 pressure_size, pressure_size>>(local_Jac_data, pressure_size,
519 ShapeMatricesTypePressure::NodalMatrixType::Zero(pressure_size,
523 ShapeMatricesTypePressure::NodalMatrixType::Zero(pressure_size,
527 ShapeMatricesTypePressure::NodalMatrixType::Zero(pressure_size,
530 auto const& solid_material =
532 _process_data.solid_materials, _process_data.material_ids,
538 auto const& medium = _process_data.media_map.getMedium(_element.getID());
539 auto const& fluid = fluidPhase(*medium);
540 auto const& phase_pressure = _process_data.phase_pressure;
544 medium->property(MPL::PropertyType::reference_temperature)
545 .template value<double>(vars, x_position, t, dt);
548 auto const& identity2 = Invariants::identity2;
550 auto const staggered_scheme =
551 std::get<Staggered>(_process_data.coupling_scheme);
552 auto const fixed_stress_stabilization_parameter =
553 staggered_scheme.fixed_stress_stabilization_parameter;
554 auto const fixed_stress_over_time_step =
555 staggered_scheme.fixed_stress_over_time_step;
557 int const n_integration_points = _integration_method.getNumberOfPoints();
558 for (
int ip = 0; ip < n_integration_points; ip++)
561 auto const& w = _ip_data[ip].integration_weight;
563 auto const& N_p = _ip_data[ip].N_p;
564 auto const& dNdx_p = _ip_data[ip].dNdx_p;
566 double const p_int_pt = N_p.dot(p);
572 auto const C_el = _ip_data[ip].computeElasticTangentStiffness(
573 t, x_position, dt, T_ref);
574 auto const K_S = solid_material.getBulkModulus(t, x_position, &C_el);
577 medium->property(MPL::PropertyType::biot_coefficient)
578 .template value<double>(vars, x_position, t, dt);
582 auto const sigma_total =
583 (_ip_data[ip].sigma_eff - alpha_b * p_int_pt * identity2).eval();
590 _ip_data[ip].material_state_variables->getEquivalentPlasticStrain();
595 auto const K = MPL::formEigenTensor<DisplacementDim>(
596 medium->property(MPL::PropertyType::permeability)
597 .value(vars, x_position, t, dt));
598 auto const porosity =
599 medium->property(MPL::PropertyType::porosity)
600 .template value<double>(vars, x_position, t, dt);
607 if (fluid.hasProperty(MPL::PropertyType::molar_mass))
610 fluid.property(MPL::PropertyType::molar_mass)
611 .template value<double>(vars, x_position, t, dt);
614 fluid.property(MPL::PropertyType::density)
615 .template value<double>(vars, x_position, t, dt);
618 auto const mu = fluid.property(MPL::PropertyType::viscosity)
619 .template value<double>(vars, x_position, t, dt);
620 auto const beta_p = fluid.property(MPL::PropertyType::density)
621 .template dValue<double>(vars, phase_pressure,
625 auto const K_over_mu = K / mu;
628 rho_fr * dNdx_p.transpose() * K_over_mu * dNdx_p * w;
632 fixed_stress_stabilization_parameter * alpha_b * alpha_b / K_S;
634 storage.noalias() += rho_fr * N_p.transpose() * N_p * w *
635 ((alpha_b - porosity) * (1.0 - alpha_b) / K_S +
636 porosity * beta_p + beta_FS);
638 auto const& b = _process_data.specific_body_force;
641 local_rhs.noalias() +=
642 dNdx_p.transpose() * rho_fr * rho_fr * K_over_mu * b * w;
647 add_p_derivative.noalias() += rho_fr * beta_p * dNdx_p.transpose() *
649 (dNdx_p * p - 2.0 * rho_fr * b) * N_p * w;
651 if (!fixed_stress_over_time_step)
653 auto const& eps = _ip_data[ip].eps;
654 auto const& eps_prev = _ip_data[ip].eps_prev;
655 const double eps_v_dot =
656 (Invariants::trace(eps) - Invariants::trace(eps_prev)) / dt;
659 double const strain_rate_b =
660 alpha_b * eps_v_dot -
661 beta_FS * _ip_data[ip].strain_rate_variable;
663 local_rhs.noalias() -= strain_rate_b * rho_fr * N_p * w;
668 local_rhs.noalias() -=
669 alpha_b * _ip_data[ip].strain_rate_variable * rho_fr * N_p * w;
672 local_Jac.noalias() = laplace + storage / dt + add_p_derivative;
674 local_rhs.noalias() -= laplace * p + storage * (p - p_prev) / dt;
680 ShapeFunctionPressure, DisplacementDim>::
681 assembleWithJacobianForDeformationEquations(
682 const double t,
double const dt, Eigen::VectorXd
const& local_x,
683 std::vector<double>& local_b_data, std::vector<double>& local_Jac_data)
685 auto const p = local_x.template segment<pressure_size>(pressure_index);
687 local_x.template segment<displacement_size>(displacement_index);
690 typename ShapeMatricesTypeDisplacement::template MatrixType<
691 displacement_size, displacement_size>>(
692 local_Jac_data, displacement_size, displacement_size);
696 template VectorType<displacement_size>>(
697 local_b_data, displacement_size);
702 auto const& medium = _process_data.media_map.getMedium(_element.getID());
703 auto const& solid = medium->phase(
"Solid");
704 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;
740 auto const alpha = medium->property(MPL::PropertyType::biot_coefficient)
741 .template value<double>(vars, x_position, t, dt);
743 solid.property(MPL::PropertyType::density)
744 .template value<double>(vars, x_position, t, dt);
745 auto const porosity =
746 medium->property(MPL::PropertyType::porosity)
747 .template value<double>(vars, x_position, t, dt);
754 if (fluid.hasProperty(MPL::PropertyType::molar_mass))
757 fluid.property(MPL::PropertyType::molar_mass)
758 .template value<double>(vars, x_position, t, dt);
761 fluid.property(MPL::PropertyType::density)
762 .template value<double>(vars, x_position, t, dt);
764 auto const& b = _process_data.specific_body_force;
767 DisplacementDim)>::identity2;
769 eps.noalias() = B * u;
774 auto C = _ip_data[ip].updateConstitutiveRelation(vars, t, x_position,
777 local_Jac.noalias() += B.transpose() * C * B * w;
782 double const rho = rho_sr * (1 - porosity) + porosity * rho_fr;
783 local_rhs.noalias() -=
784 (B.transpose() * (sigma_eff - alpha * identity2 * p_at_xi) -
785 N_u_op(N_u).transpose() * rho * b) *
962 DisplacementDim>::postTimestepConcrete(Eigen::VectorXd
const& local_x,
963 Eigen::VectorXd
const& local_x_prev,
964 double const t,
double const dt,
965 int const process_id)
967 auto const staggered_scheme_ptr =
968 std::get_if<Staggered>(&_process_data.coupling_scheme);
970 if (staggered_scheme_ptr &&
971 process_id == _process_data.hydraulic_process_id)
973 if (staggered_scheme_ptr->fixed_stress_over_time_step)
975 auto const fixed_stress_stabilization_parameter =
976 staggered_scheme_ptr->fixed_stress_stabilization_parameter;
979 local_x.template segment<pressure_size>(pressure_index);
981 local_x_prev.template segment<pressure_size>(pressure_index);
986 auto const& solid_material =
988 _process_data.solid_materials, _process_data.material_ids,
992 _process_data.media_map.getMedium(_element.getID());
996 medium->property(MPL::PropertyType::reference_temperature)
997 .template value<double>(vars, x_position, t, dt);
1000 int const n_integration_points =
1001 _integration_method.getNumberOfPoints();
1002 for (
int ip = 0; ip < n_integration_points; ip++)
1004 auto& ip_data = _ip_data[ip];
1006 auto const& N_p = ip_data.N_p;
1008 auto const& eps = ip_data.eps;
1009 auto const& eps_prev = ip_data.eps_prev;
1010 const double eps_v_dot =
1011 (Invariants::trace(eps) - Invariants::trace(eps_prev)) / dt;
1013 auto const C_el = ip_data.computeElasticTangentStiffness(
1014 t, x_position, dt, T_ref);
1016 solid_material.getBulkModulus(t, x_position, &C_el);
1018 auto const alpha_b =
1019 medium->property(MPL::PropertyType::biot_coefficient)
1020 .template value<double>(vars, x_position, t, dt);
1022 ip_data.strain_rate_variable =
1023 eps_v_dot - fixed_stress_stabilization_parameter * alpha_b *
1024 N_p.dot(p - p_prev) / dt / K_S;
1029 unsigned const n_integration_points =
1030 _integration_method.getNumberOfPoints();
1032 for (
unsigned ip = 0; ip < n_integration_points; ip++)
1034 _ip_data[ip].pushBackState();
1144 ShapeFunctionPressure, DisplacementDim>::
1145 computeSecondaryVariableConcrete(
double const t,
double const dt,
1146 Eigen::VectorXd
const& local_x,
1147 Eigen::VectorXd
const& )
1149 auto const p = local_x.template segment<pressure_size>(pressure_index);
1152 ShapeFunctionPressure,
typename ShapeFunctionDisplacement::MeshElement,
1153 DisplacementDim>(_element, _is_axially_symmetric, p,
1154 *_process_data.pressure_interpolated);
1156 int const elem_id = _element.getID();
1159 unsigned const n_integration_points =
1160 _integration_method.getNumberOfPoints();
1162 auto const& medium = _process_data.media_map.getMedium(elem_id);
1166 auto sigma_eff_sum = MathLib::KelvinVector::tensorToKelvin<DisplacementDim>(
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);
1189 auto const sigma_total =
1190 (_ip_data[ip].sigma_eff - alpha * p_int_pt * identity2).eval();
1198 _ip_data[ip].material_state_variables->getEquivalentPlasticStrain();
1203 k_sum += MPL::getSymmetricTensor<DisplacementDim>(
1204 medium->property(MPL::PropertyType::permeability)
1205 .value(vars, x_position, t, dt));
1208 Eigen::Map<Eigen::VectorXd>(
1209 &(*_process_data.permeability)[elem_id * KelvinVectorSize],
1210 KelvinVectorSize) = k_sum / n_integration_points;
1212 Eigen::Matrix<double, 3, 3, 0, 3, 3>
const sigma_avg =
1214 n_integration_points;
1216 Eigen::SelfAdjointEigenSolver<Eigen::Matrix<double, 3, 3>> e_s(sigma_avg);
1218 Eigen::Map<Eigen::Vector3d>(
1219 &(*_process_data.principal_stress_values)[elem_id * 3], 3) =
1222 auto eigen_vectors = e_s.eigenvectors();
1224 for (
auto i = 0; i < 3; i++)
1226 Eigen::Map<Eigen::Vector3d>(
1227 &(*_process_data.principal_stress_vector[i])[elem_id * 3], 3) =
1228 eigen_vectors.col(i);