14#include <Eigen/Eigenvalues>
29namespace HydroMechanics
33template <
typename ShapeFunctionDisplacement,
typename ShapeFunctionPressure,
35HydroMechanicsLocalAssembler<ShapeFunctionDisplacement, ShapeFunctionPressure,
37 HydroMechanicsLocalAssembler(
41 bool const is_axially_symmetric,
43 : _process_data(process_data),
44 _integration_method(integration_method),
46 _is_axially_symmetric(is_axially_symmetric)
48 unsigned const n_integration_points =
51 _ip_data.reserve(n_integration_points);
54 auto const shape_matrices_u =
57 DisplacementDim>(e, is_axially_symmetric,
60 auto const shape_matrices_p =
65 auto const& solid_material =
70 for (
unsigned ip = 0; ip < n_integration_points; ip++)
72 _ip_data.emplace_back(solid_material);
74 auto const& sm_u = shape_matrices_u[ip];
75 ip_data.integration_weight =
77 sm_u.integralMeasure * sm_u.detJ;
80 static const int kelvin_vector_size =
82 ip_data.sigma_eff.setZero(kelvin_vector_size);
83 ip_data.eps.setZero(kelvin_vector_size);
86 ip_data.eps_prev.resize(kelvin_vector_size);
87 ip_data.sigma_eff_prev.resize(kelvin_vector_size);
90 ip_data.dNdx_u = sm_u.dNdx;
92 ip_data.N_p = shape_matrices_p[ip].N;
93 ip_data.dNdx_p = shape_matrices_p[ip].dNdx;
99template <
typename ShapeFunctionDisplacement,
typename ShapeFunctionPressure,
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);
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);
224 auto const C_el = _ip_data[ip].computeElasticTangentStiffness(
225 t, x_position, dt, T_ref);
226 auto const K_S = solid_material.getBulkModulus(t, x_position, &C_el);
228 auto const alpha = medium->property(MPL::PropertyType::biot_coefficient)
229 .template value<double>(vars, x_position, t, dt);
232 solid.property(MPL::PropertyType::density)
233 .template value<double>(vars, x_position, t, dt);
234 auto const porosity =
235 medium->property(MPL::PropertyType::porosity)
236 .template value<double>(vars, x_position, t, dt);
243 if (fluid.hasProperty(MPL::PropertyType::molar_mass))
246 fluid.property(MPL::PropertyType::molar_mass)
247 .template value<double>(vars, x_position, t, dt);
250 fluid.property(MPL::PropertyType::density)
251 .template value<double>(vars, x_position, t, dt);
254 auto const mu = fluid.property(MPL::PropertyType::viscosity)
255 .template value<double>(vars, x_position, t, dt);
258 fluid.property(MPL::PropertyType::density)
259 .template dValue<double>(vars, MPL::Variable::phase_pressure,
266 auto const sigma_total =
267 (_ip_data[ip].sigma_eff - alpha * p_int_pt * identity2).eval();
276 _ip_data[ip].material_state_variables->getEquivalentPlasticStrain();
281 auto const K = MPL::formEigenTensor<DisplacementDim>(
282 medium->property(MPL::PropertyType::permeability)
283 .value(vars, x_position, t, dt));
286 (*medium)[MPL::PropertyType::permeability].dValue(
287 vars, MPL::Variable::mechanical_strain, x_position, t, dt));
289 auto const K_over_mu = K / mu;
291 auto C = _ip_data[ip].updateConstitutiveRelation(vars, t, x_position,
298 .template block<displacement_size, displacement_size>(
299 displacement_index, displacement_index)
300 .noalias() += B.transpose() * C * B * w;
302 double const rho = rho_sr * (1 - porosity) + porosity * rho_fr;
303 local_rhs.template segment<displacement_size>(displacement_index)
305 (B.transpose() * sigma_eff - N_u_op(N_u).transpose() * rho * b) * w;
310 Kup.noalias() += B.transpose() * alpha * identity2 * N_p * w;
315 laplace_p.noalias() +=
316 rho_fr * dNdx_p.transpose() * K_over_mu * dNdx_p * w;
318 storage_p.noalias() +=
319 rho_fr * N_p.transpose() * N_p * w *
320 ((alpha - porosity) * (1.0 - alpha) / K_S + porosity * beta_p);
324 add_p_derivative.noalias() += rho_fr * beta_p * dNdx_p.transpose() *
326 (dNdx_p * p - 2.0 * rho_fr * b) * N_p * w;
328 local_rhs.template segment<pressure_size>(pressure_index).noalias() +=
329 dNdx_p.transpose() * rho_fr * rho_fr * K_over_mu * b * w;
335 rho_fr * alpha * N_p.transpose() * identity2.transpose() * B * w;
339 MathLib::KelvinVector::liftVectorToKelvin<DisplacementDim>(
340 dNdx_p * p - rho_fr * b) *
341 dkde * B * rho_fr / mu * w;
345 .template block<displacement_size, pressure_size>(displacement_index,
349 if (_process_data.mass_lumping)
351 storage_p = storage_p.colwise().sum().eval().asDiagonal();
353 if constexpr (pressure_size == displacement_size)
355 Kpu = Kpu.colwise().sum().eval().asDiagonal();
356 Kpu_k = Kpu_k.colwise().sum().eval().asDiagonal();
362 .template block<pressure_size, pressure_size>(pressure_index,
364 .noalias() += laplace_p + storage_p / dt + add_p_derivative;
368 .template block<pressure_size, displacement_size>(pressure_index,
370 .noalias() += Kpu / dt + Kpu_k;
373 local_rhs.template segment<pressure_size>(pressure_index).noalias() -=
374 laplace_p * p + storage_p * (p - p_prev) / dt + Kpu * (u - u_prev) / dt;
377 local_rhs.template segment<displacement_size>(displacement_index)
378 .noalias() += Kup * p;
381template <
typename ShapeFunctionDisplacement,
typename ShapeFunctionPressure,
384 ShapeFunctionDisplacement, ShapeFunctionPressure, DisplacementDim>::
385 getIntPtDarcyVelocity(
387 std::vector<GlobalVector*>
const& x,
388 std::vector<NumLib::LocalToGlobalIndexMap const*>
const& dof_table,
389 std::vector<double>& cache)
const
391 int const hydraulic_process_id = _process_data.hydraulic_process_id;
394 assert(!indices.empty());
395 auto const local_x = x[hydraulic_process_id]->get(indices);
397 unsigned const n_integration_points =
398 _integration_method.getNumberOfPoints();
401 double, DisplacementDim, Eigen::Dynamic, Eigen::RowMajor>>(
402 cache, DisplacementDim, n_integration_points);
404 auto p = Eigen::Map<
typename ShapeMatricesTypePressure::template VectorType<
405 pressure_size>
const>(local_x.data() + pressure_index, pressure_size);
410 auto const& medium = _process_data.media_map.getMedium(_element.getID());
411 auto const& fluid = fluidPhase(*medium);
416 double const dt = std::numeric_limits<double>::quiet_NaN();
418 medium->property(MPL::PropertyType::reference_temperature)
419 .template value<double>(vars, x_position, t, dt);
421 auto const& identity2 = Invariants::identity2;
423 for (
unsigned ip = 0; ip < n_integration_points; ip++)
425 x_position.setIntegrationPoint(ip);
427 double const p_int_pt = _ip_data[ip].N_p.dot(p);
430 auto const alpha = medium->property(MPL::PropertyType::biot_coefficient)
431 .template value<double>(vars, x_position, t, dt);
435 auto const sigma_total =
436 (_ip_data[ip].sigma_eff - alpha * p_int_pt * identity2).eval();
443 _ip_data[ip].material_state_variables->getEquivalentPlasticStrain();
448 auto const K = MPL::formEigenTensor<DisplacementDim>(
449 medium->property(MPL::PropertyType::permeability)
450 .value(vars, x_position, t, dt));
457 if (fluid.hasProperty(MPL::PropertyType::molar_mass))
460 fluid.property(MPL::PropertyType::molar_mass)
461 .template value<double>(vars, x_position, t, dt);
465 fluid.property(MPL::PropertyType::density)
466 .template value<double>(vars, x_position, t, dt);
469 auto const mu = fluid.property(MPL::PropertyType::viscosity)
470 .template value<double>(vars, x_position, t, dt);
472 auto const K_over_mu = K / mu;
474 auto const& b = _process_data.specific_body_force;
477 auto const& dNdx_p = _ip_data[ip].dNdx_p;
478 cache_matrix.col(ip).noalias() =
479 -K_over_mu * dNdx_p * p + K_over_mu * rho_fr * b;
485template <
typename ShapeFunctionDisplacement,
typename ShapeFunctionPressure,
488 ShapeFunctionPressure, DisplacementDim>::
489 assembleWithJacobianForPressureEquations(
490 const double t,
double const dt, Eigen::VectorXd
const& local_x,
491 Eigen::VectorXd
const& local_x_prev, std::vector<double>& local_b_data,
492 std::vector<double>& local_Jac_data)
496 template VectorType<pressure_size>>(
497 local_b_data, pressure_size);
502 auto const p = local_x.template segment<pressure_size>(pressure_index);
505 local_x_prev.template segment<pressure_size>(pressure_index);
508 typename ShapeMatricesTypeDisplacement::template MatrixType<
509 pressure_size, pressure_size>>(local_Jac_data, pressure_size,
513 ShapeMatricesTypePressure::NodalMatrixType::Zero(pressure_size,
517 ShapeMatricesTypePressure::NodalMatrixType::Zero(pressure_size,
521 ShapeMatricesTypePressure::NodalMatrixType::Zero(pressure_size,
524 auto const& solid_material =
526 _process_data.solid_materials, _process_data.material_ids,
532 auto const& medium = _process_data.media_map.getMedium(_element.getID());
533 auto const& fluid = fluidPhase(*medium);
537 medium->property(MPL::PropertyType::reference_temperature)
538 .template value<double>(vars, x_position, t, dt);
541 auto const& identity2 = Invariants::identity2;
543 auto const staggered_scheme =
544 std::get<Staggered>(_process_data.coupling_scheme);
545 auto const fixed_stress_stabilization_parameter =
546 staggered_scheme.fixed_stress_stabilization_parameter;
547 auto const fixed_stress_over_time_step =
548 staggered_scheme.fixed_stress_over_time_step;
550 int const n_integration_points = _integration_method.getNumberOfPoints();
551 for (
int ip = 0; ip < n_integration_points; ip++)
554 auto const& w = _ip_data[ip].integration_weight;
556 auto const& N_p = _ip_data[ip].N_p;
557 auto const& dNdx_p = _ip_data[ip].dNdx_p;
559 double const p_int_pt = N_p.dot(p);
562 auto const C_el = _ip_data[ip].computeElasticTangentStiffness(
563 t, x_position, dt, T_ref);
564 auto const K_S = solid_material.getBulkModulus(t, x_position, &C_el);
567 medium->property(MPL::PropertyType::biot_coefficient)
568 .template value<double>(vars, x_position, t, dt);
572 auto const sigma_total =
573 (_ip_data[ip].sigma_eff - alpha_b * p_int_pt * identity2).eval();
580 _ip_data[ip].material_state_variables->getEquivalentPlasticStrain();
585 auto const K = MPL::formEigenTensor<DisplacementDim>(
586 medium->property(MPL::PropertyType::permeability)
587 .value(vars, x_position, t, dt));
588 auto const porosity =
589 medium->property(MPL::PropertyType::porosity)
590 .template value<double>(vars, x_position, t, dt);
597 if (fluid.hasProperty(MPL::PropertyType::molar_mass))
600 fluid.property(MPL::PropertyType::molar_mass)
601 .template value<double>(vars, x_position, t, dt);
604 fluid.property(MPL::PropertyType::density)
605 .template value<double>(vars, x_position, t, dt);
608 auto const mu = fluid.property(MPL::PropertyType::viscosity)
609 .template value<double>(vars, x_position, t, dt);
611 fluid.property(MPL::PropertyType::density)
612 .template dValue<double>(vars, MPL::Variable::phase_pressure,
616 auto const K_over_mu = K / mu;
619 rho_fr * dNdx_p.transpose() * K_over_mu * dNdx_p * w;
623 fixed_stress_stabilization_parameter * alpha_b * alpha_b / K_S;
625 storage.noalias() += rho_fr * N_p.transpose() * N_p * w *
626 ((alpha_b - porosity) * (1.0 - alpha_b) / K_S +
627 porosity * beta_p + beta_FS);
629 auto const& b = _process_data.specific_body_force;
632 local_rhs.noalias() +=
633 dNdx_p.transpose() * rho_fr * rho_fr * K_over_mu * b * w;
638 add_p_derivative.noalias() += rho_fr * beta_p * dNdx_p.transpose() *
640 (dNdx_p * p - 2.0 * rho_fr * b) * N_p * w;
642 if (!fixed_stress_over_time_step)
644 auto const& eps = _ip_data[ip].eps;
645 auto const& eps_prev = _ip_data[ip].eps_prev;
646 const double eps_v_dot =
647 (Invariants::trace(eps) - Invariants::trace(eps_prev)) / dt;
650 double const strain_rate_b =
651 alpha_b * eps_v_dot -
652 beta_FS * _ip_data[ip].strain_rate_variable;
654 local_rhs.noalias() -= strain_rate_b * rho_fr * N_p * w;
659 local_rhs.noalias() -=
660 alpha_b * _ip_data[ip].strain_rate_variable * rho_fr * N_p * w;
663 local_Jac.noalias() = laplace + storage / dt + add_p_derivative;
665 local_rhs.noalias() -= laplace * p + storage * (p - p_prev) / dt;
668template <
typename ShapeFunctionDisplacement,
typename ShapeFunctionPressure,
671 ShapeFunctionPressure, DisplacementDim>::
672 assembleWithJacobianForDeformationEquations(
673 const double t,
double const dt, Eigen::VectorXd
const& local_x,
674 std::vector<double>& local_b_data, std::vector<double>& local_Jac_data)
676 auto const p = local_x.template segment<pressure_size>(pressure_index);
678 local_x.template segment<displacement_size>(displacement_index);
681 typename ShapeMatricesTypeDisplacement::template MatrixType<
682 displacement_size, displacement_size>>(
683 local_Jac_data, displacement_size, displacement_size);
687 template VectorType<displacement_size>>(
688 local_b_data, displacement_size);
693 auto const& medium = _process_data.media_map.getMedium(_element.getID());
694 auto const& solid = medium->phase(
"Solid");
695 auto const& fluid = fluidPhase(*medium);
699 medium->property(MPL::PropertyType::reference_temperature)
700 .template value<double>(vars, x_position, t, dt);
703 int const n_integration_points = _integration_method.getNumberOfPoints();
704 for (
int ip = 0; ip < n_integration_points; ip++)
706 x_position.setIntegrationPoint(ip);
707 auto const& w = _ip_data[ip].integration_weight;
709 auto const& N_u = _ip_data[ip].N_u;
710 auto const& dNdx_u = _ip_data[ip].dNdx_u;
712 auto const& N_p = _ip_data[ip].N_p;
720 ShapeFunctionDisplacement::NPOINTS,
722 dNdx_u, N_u, x_coord, _is_axially_symmetric);
724 auto& eps = _ip_data[ip].eps;
725 auto const& sigma_eff = _ip_data[ip].sigma_eff;
729 auto const alpha = medium->property(MPL::PropertyType::biot_coefficient)
730 .template value<double>(vars, x_position, t, dt);
732 solid.property(MPL::PropertyType::density)
733 .template value<double>(vars, x_position, t, dt);
734 auto const porosity =
735 medium->property(MPL::PropertyType::porosity)
736 .template value<double>(vars, x_position, t, dt);
743 if (fluid.hasProperty(MPL::PropertyType::molar_mass))
746 fluid.property(MPL::PropertyType::molar_mass)
747 .template value<double>(vars, x_position, t, dt);
750 fluid.property(MPL::PropertyType::density)
751 .template value<double>(vars, x_position, t, dt);
753 auto const& b = _process_data.specific_body_force;
756 DisplacementDim)>::identity2;
758 eps.noalias() = B * u;
763 auto C = _ip_data[ip].updateConstitutiveRelation(vars, t, x_position,
766 local_Jac.noalias() += B.transpose() * C * B * w;
771 double const rho = rho_sr * (1 - porosity) + porosity * rho_fr;
772 local_rhs.noalias() -=
773 (B.transpose() * (sigma_eff - alpha * identity2 * p_at_xi) -
774 N_u_op(N_u).transpose() * rho * b) *
779template <
typename ShapeFunctionDisplacement,
typename ShapeFunctionPressure,
782 ShapeFunctionPressure, DisplacementDim>::
783 assembleWithJacobianForStaggeredScheme(
784 const double t,
double const dt, Eigen::VectorXd
const& local_x,
785 Eigen::VectorXd
const& local_x_prev,
int const process_id,
786 std::vector<double>& ,
787 std::vector<double>& ,
788 std::vector<double>& local_b_data, std::vector<double>& local_Jac_data)
791 if (process_id == _process_data.hydraulic_process_id)
793 assembleWithJacobianForPressureEquations(t, dt, local_x, local_x_prev,
794 local_b_data, local_Jac_data);
799 assembleWithJacobianForDeformationEquations(t, dt, local_x, local_b_data,
803template <
typename ShapeFunctionDisplacement,
typename ShapeFunctionPressure,
806 ShapeFunctionPressure, DisplacementDim>::
807 setInitialConditionsConcrete(std::vector<double>
const& local_x,
809 bool const use_monolithic_scheme,
810 int const process_id)
812 if (!use_monolithic_scheme &&
813 process_id == _process_data.hydraulic_process_id)
818 if (use_monolithic_scheme ||
819 process_id == _process_data.mechanics_related_process_id)
824 const int displacement_offset =
825 use_monolithic_scheme ? displacement_index : 0;
827 auto u = Eigen::Map<
typename ShapeMatricesTypeDisplacement::
828 template VectorType<displacement_size>
const>(
829 local_x.data() + displacement_offset, displacement_size);
833 int const n_integration_points =
834 _integration_method.getNumberOfPoints();
835 for (
int ip = 0; ip < n_integration_points; ip++)
838 auto const& N_u = _ip_data[ip].N_u;
839 auto const& dNdx_u = _ip_data[ip].dNdx_u;
846 DisplacementDim, ShapeFunctionDisplacement::NPOINTS,
848 _is_axially_symmetric);
850 auto& eps = _ip_data[ip].eps;
851 eps.noalias() = B * u;
852 vars.mechanical_strain.emplace<
858template <
typename ShapeFunctionDisplacement,
typename ShapeFunctionPressure,
861 ShapeFunctionPressure, DisplacementDim>::
862 postNonLinearSolverConcrete(std::vector<double>
const& local_x,
863 std::vector<double>
const& local_x_prev,
864 double const t,
double const dt,
866 int const process_id)
872 int const n_integration_points = _integration_method.getNumberOfPoints();
874 auto const staggered_scheme_ptr =
875 std::get_if<Staggered>(&_process_data.coupling_scheme);
877 if (staggered_scheme_ptr &&
878 process_id == _process_data.hydraulic_process_id)
880 if (!staggered_scheme_ptr->fixed_stress_over_time_step)
883 Eigen::Map<
typename ShapeMatricesTypePressure::
884 template VectorType<pressure_size>
const>(
885 local_x.data(), pressure_size);
888 Eigen::Map<
typename ShapeMatricesTypePressure::
889 template VectorType<pressure_size>
const>(
890 local_x_prev.data(), pressure_size);
892 for (
int ip = 0; ip < n_integration_points; ip++)
894 auto& ip_data = _ip_data[ip];
896 auto const& N_p = ip_data.N_p;
898 ip_data.strain_rate_variable = N_p.dot(p - p_prev) / dt;
903 if (!staggered_scheme_ptr ||
904 process_id == _process_data.mechanics_related_process_id)
910 _process_data.media_map.getMedium(_element.getID());
913 medium->property(MPL::PropertyType::reference_temperature)
917 const int displacement_offset =
918 (!staggered_scheme_ptr) ? displacement_index : 0;
920 auto u = Eigen::Map<
typename ShapeMatricesTypeDisplacement::
921 template VectorType<displacement_size>
const>(
922 local_x.data() + displacement_offset, displacement_size);
927 for (
int ip = 0; ip < n_integration_points; ip++)
930 auto const& N_u = _ip_data[ip].N_u;
931 auto const& dNdx_u = _ip_data[ip].dNdx_u;
938 DisplacementDim, ShapeFunctionDisplacement::NPOINTS,
940 _is_axially_symmetric);
942 auto& eps = _ip_data[ip].eps;
943 eps.noalias() = B * u;
944 vars.mechanical_strain.emplace<
947 _ip_data[ip].updateConstitutiveRelation(vars, t, x_position, dt, u,
953template <
typename ShapeFunctionDisplacement,
typename ShapeFunctionPressure,
956 ShapeFunctionDisplacement, ShapeFunctionPressure,
957 DisplacementDim>::postTimestepConcrete(Eigen::VectorXd
const& local_x,
958 Eigen::VectorXd
const& local_x_prev,
959 double const t,
double const dt,
961 int const process_id)
963 auto const staggered_scheme_ptr =
964 std::get_if<Staggered>(&_process_data.coupling_scheme);
966 if (staggered_scheme_ptr &&
967 process_id == _process_data.hydraulic_process_id)
969 if (staggered_scheme_ptr->fixed_stress_over_time_step)
971 auto const fixed_stress_stabilization_parameter =
972 staggered_scheme_ptr->fixed_stress_stabilization_parameter;
975 local_x.template segment<pressure_size>(pressure_index);
977 local_x_prev.template segment<pressure_size>(pressure_index);
982 auto const& solid_material =
984 _process_data.solid_materials, _process_data.material_ids,
988 _process_data.media_map.getMedium(_element.getID());
992 medium->property(MPL::PropertyType::reference_temperature)
993 .template value<double>(vars, x_position, t, dt);
996 int const n_integration_points =
997 _integration_method.getNumberOfPoints();
998 for (
int ip = 0; ip < n_integration_points; ip++)
1000 auto& ip_data = _ip_data[ip];
1002 auto const& N_p = ip_data.N_p;
1004 auto const& eps = ip_data.eps;
1005 auto const& eps_prev = ip_data.eps_prev;
1006 const double eps_v_dot =
1007 (Invariants::trace(eps) - Invariants::trace(eps_prev)) / dt;
1009 auto const C_el = ip_data.computeElasticTangentStiffness(
1010 t, x_position, dt, T_ref);
1012 solid_material.getBulkModulus(t, x_position, &C_el);
1014 auto const alpha_b =
1015 medium->property(MPL::PropertyType::biot_coefficient)
1016 .template value<double>(vars, x_position, t, dt);
1018 ip_data.strain_rate_variable =
1019 eps_v_dot - fixed_stress_stabilization_parameter * alpha_b *
1020 N_p.dot(p - p_prev) / dt / K_S;
1025 unsigned const n_integration_points =
1026 _integration_method.getNumberOfPoints();
1028 for (
unsigned ip = 0; ip < n_integration_points; ip++)
1030 _ip_data[ip].pushBackState();
1034template <
typename ShapeFunctionDisplacement,
typename ShapeFunctionPressure,
1035 int DisplacementDim>
1037 ShapeFunctionDisplacement, ShapeFunctionPressure,
1039 double const* values,
1040 int const integration_order)
1042 if (integration_order !=
1043 static_cast<int>(_integration_method.getIntegrationOrder()))
1046 "Setting integration point initial conditions; The integration "
1047 "order of the local assembler for element {:d} is different from "
1048 "the integration order in the initial condition.",
1052 if (name ==
"sigma_ip")
1054 if (_process_data.initial_stress !=
nullptr)
1057 "Setting initial conditions for stress from integration "
1058 "point data and from a parameter '{:s}' is not possible "
1060 _process_data.initial_stress->name);
1063 return ProcessLib::setIntegrationPointKelvinVectorData<DisplacementDim>(
1064 values, _ip_data, &IpData::sigma_eff);
1067 if (name ==
"epsilon_ip")
1069 return ProcessLib::setIntegrationPointKelvinVectorData<DisplacementDim>(
1070 values, _ip_data, &IpData::eps);
1073 if (name ==
"strain_rate_variable_ip")
1076 values, _ip_data, &IpData::strain_rate_variable);
1082template <
typename ShapeFunctionDisplacement,
typename ShapeFunctionPressure,
1083 int DisplacementDim>
1086 DisplacementDim>::getSigma()
const
1088 return ProcessLib::getIntegrationPointKelvinVectorData<DisplacementDim>(
1089 _ip_data, &IpData::sigma_eff);
1092template <
typename ShapeFunctionDisplacement,
typename ShapeFunctionPressure,
1093 int DisplacementDim>
1096 DisplacementDim>::getEpsilon()
const
1098 auto const kelvin_vector_size =
1100 unsigned const n_integration_points =
1101 _integration_method.getNumberOfPoints();
1103 std::vector<double> ip_epsilon_values;
1105 double, Eigen::Dynamic, kelvin_vector_size, Eigen::RowMajor>>(
1106 ip_epsilon_values, n_integration_points, kelvin_vector_size);
1108 for (
unsigned ip = 0; ip < n_integration_points; ++ip)
1110 auto const& eps = _ip_data[ip].eps;
1115 return ip_epsilon_values;
1118template <
typename ShapeFunctionDisplacement,
typename ShapeFunctionPressure,
1119 int DisplacementDim>
1122 DisplacementDim>::getStrainRateVariable()
const
1124 unsigned const n_integration_points =
1125 _integration_method.getNumberOfPoints();
1127 std::vector<double> ip_strain_rate_variables(n_integration_points);
1129 for (
unsigned ip = 0; ip < n_integration_points; ++ip)
1131 ip_strain_rate_variables[ip] = _ip_data[ip].strain_rate_variable;
1134 return ip_strain_rate_variables;
1137template <
typename ShapeFunctionDisplacement,
typename ShapeFunctionPressure,
1138 int DisplacementDim>
1140 ShapeFunctionPressure, DisplacementDim>::
1141 computeSecondaryVariableConcrete(
double const t,
double const dt,
1142 Eigen::VectorXd
const& local_x,
1143 Eigen::VectorXd
const& )
1145 auto const p = local_x.template segment<pressure_size>(pressure_index);
1148 ShapeFunctionPressure,
typename ShapeFunctionDisplacement::MeshElement,
1149 DisplacementDim>(_element, _is_axially_symmetric, p,
1150 *_process_data.pressure_interpolated);
1152 int const elem_id = _element.getID();
1155 unsigned const n_integration_points =
1156 _integration_method.getNumberOfPoints();
1158 auto const& medium = _process_data.media_map.getMedium(elem_id);
1162 auto sigma_eff_sum = MathLib::KelvinVector::tensorToKelvin<DisplacementDim>(
1163 Eigen::Matrix<double, 3, 3>::Zero());
1165 auto const& identity2 = Invariants::identity2;
1167 for (
unsigned ip = 0; ip < n_integration_points; ip++)
1171 auto const& eps = _ip_data[ip].eps;
1172 sigma_eff_sum += _ip_data[ip].sigma_eff;
1174 auto const alpha = medium->property(MPL::PropertyType::biot_coefficient)
1175 .template value<double>(vars, x_position, t, dt);
1176 double const p_int_pt = _ip_data[ip].N_p.dot(p);
1182 auto const sigma_total =
1183 (_ip_data[ip].sigma_eff - alpha * p_int_pt * identity2).eval();
1191 _ip_data[ip].material_state_variables->getEquivalentPlasticStrain();
1196 k_sum += MPL::getSymmetricTensor<DisplacementDim>(
1197 medium->property(MPL::PropertyType::permeability)
1198 .value(vars, x_position, t, dt));
1201 Eigen::Map<Eigen::VectorXd>(
1202 &(*_process_data.permeability)[elem_id * KelvinVectorSize],
1203 KelvinVectorSize) = k_sum / n_integration_points;
1205 Eigen::Matrix<double, 3, 3, 0, 3, 3>
const sigma_avg =
1207 n_integration_points;
1209 Eigen::SelfAdjointEigenSolver<Eigen::Matrix<double, 3, 3>> e_s(sigma_avg);
1211 Eigen::Map<Eigen::Vector3d>(
1212 &(*_process_data.principal_stress_values)[elem_id * 3], 3) =
1215 auto eigen_vectors = e_s.eigenvectors();
1217 for (
auto i = 0; i < 3; i++)
1219 Eigen::Map<Eigen::Vector3d>(
1220 &(*_process_data.principal_stress_vector[i])[elem_id * 3], 3) =
1221 eigen_vectors.col(i);
1225template <
typename ShapeFunctionDisplacement,
typename ShapeFunctionPressure,
1226 int DisplacementDim>
1228 ShapeFunctionDisplacement, ShapeFunctionPressure,
1229 DisplacementDim>::getNumberOfIntegrationPoints()
const
1231 return _integration_method.getNumberOfPoints();
1234template <
typename ShapeFunctionDisplacement,
typename ShapeFunctionPressure,
1235 int DisplacementDim>
1237 ShapeFunctionPressure,
1238 DisplacementDim>::getMaterialID()
const
1240 return _process_data.material_ids ==
nullptr
1242 : (*_process_data.material_ids)[_element.getID()];
1245template <
typename ShapeFunctionDisplacement,
typename ShapeFunctionPressure,
1246 int DisplacementDim>
1248 DisplacementDim>::MaterialStateVariables
const&
1251 getMaterialStateVariablesAt(
unsigned integration_point)
const
1253 return *_ip_data[integration_point].material_state_variables;
std::variant< std::monostate, Eigen::Matrix< double, 4, 1 >, Eigen::Matrix< double, 6, 1 > > mechanical_strain
double equivalent_plastic_strain
std::variant< std::monostate, Eigen::Matrix< double, 4, 1 >, Eigen::Matrix< double, 6, 1 > > total_stress
virtual std::size_t getID() const final
Returns the ID of the element.
MathLib::WeightedPoint const & getWeightedPoint(unsigned const igp) const
unsigned getNumberOfPoints() const
void setElementID(std::size_t element_id)
void setIntegrationPoint(unsigned integration_point)
MatrixType< _kelvin_vector_size, _number_of_dof > BMatrixType
NumLib::GenericIntegrationMethod const & _integration_method
Eigen::Matrix< double, KelvinVectorSize, 1 > SymmetricTensor
ShapeMatrixPolicyType< ShapeFunctionPressure, DisplacementDim > ShapeMatricesTypePressure
ShapeMatrixPolicyType< ShapeFunctionDisplacement, DisplacementDim > ShapeMatricesTypeDisplacement
HydroMechanicsProcessData< DisplacementDim > & _process_data
SecondaryData< typename ShapeMatricesTypeDisplacement::ShapeMatrices::ShapeType > _secondary_data
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)
Eigen::Matrix< double, GlobalDim, GlobalDim > formEigenTensor(MaterialPropertyLib::PropertyDataType const &values)
Eigen::Matrix< double, kelvin_vector_dimensions(DisplacementDim), 1, Eigen::ColMajor > KelvinVectorType
Eigen::Matrix< double, 4, 1 > kelvinVectorToSymmetricTensor(Eigen::Matrix< double, 4, 1, Eigen::ColMajor, 4, 1 > const &v)
constexpr int kelvin_vector_dimensions(int const displacement_dim)
Kelvin vector dimensions for given displacement dimension.
Eigen::Matrix< double, 3, 3 > kelvinVectorToTensor(Eigen::Matrix< double, 4, 1, Eigen::ColMajor, 4, 1 > const &v)
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 shapeFunctionInterpolate(const NodalValues &, const ShapeMatrix &)
double interpolateXCoordinate(MeshLib::Element const &e, typename ShapeMatricesType::ShapeMatrices::ShapeType const &N)
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< GlobalIndexType > getIndices(std::size_t const mesh_item_id, NumLib::LocalToGlobalIndexMap const &dof_table)
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)
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.
void setIPDataInitialConditions(std::vector< std::unique_ptr< MeshLib::IntegrationPointWriter > > const &_integration_point_writer, MeshLib::Properties const &mesh_properties, LocalAssemblersVector &local_assemblers, bool const remove_name_suffix=false)
std::size_t setIntegrationPointScalarData(double const *values, IntegrationPointDataVector &ip_data_vector, MemberType IpData::*const member)
MatrixType< ShapeFunction::NPOINTS, ShapeFunction::NPOINTS > NodalMatrixType
std::vector< ShapeMatrixType, Eigen::aligned_allocator< ShapeMatrixType > > N_u