24namespace ThermoMechanics
26template <
typename ShapeFunction,
int DisplacementDim>
32 bool const is_axially_symmetric,
34 : _process_data(process_data),
35 _integration_method(integration_method),
37 _is_axially_symmetric(is_axially_symmetric)
39 unsigned const n_integration_points =
42 _ip_data.reserve(n_integration_points);
45 auto const shape_matrices =
47 DisplacementDim>(e, is_axially_symmetric,
53 for (
unsigned ip = 0; ip < n_integration_points; ip++)
55 _ip_data.emplace_back(solid_material);
57 ip_data.integration_weight =
59 shape_matrices[ip].integralMeasure * shape_matrices[ip].detJ;
61 static const int kelvin_vector_size =
64 ip_data.sigma.setZero(kelvin_vector_size);
65 ip_data.eps.setZero(kelvin_vector_size);
68 ip_data.sigma_prev.resize(kelvin_vector_size);
69 ip_data.eps_prev.resize(kelvin_vector_size);
71 ip_data.eps_m.setZero(kelvin_vector_size);
72 ip_data.eps_m_prev.setZero(kelvin_vector_size);
75 ip_data.N = shape_matrices[ip].N;
76 ip_data.dNdx = shape_matrices[ip].dNdx;
82template <
typename ShapeFunction,
int DisplacementDim>
86 int const integration_order)
88 if (integration_order !=
89 static_cast<int>(_integration_method.getIntegrationOrder()))
92 "Setting integration point initial conditions; The integration "
93 "order of the local assembler for element {:d} is different from "
94 "the integration order in the initial condition.",
98 if (name ==
"sigma_ip")
100 return setSigma(values);
102 if (name ==
"epsilon_ip")
104 return setEpsilon(values);
106 if (name ==
"epsilon_m_ip")
108 return setEpsilonMechanical(values);
114template <
typename ShapeFunction,
int DisplacementDim>
117 std::vector<double>
const& local_x,
118 std::vector<double>
const& local_x_prev,
119 std::vector<double>& ,
120 std::vector<double>& ,
121 std::vector<double>& local_rhs_data,
122 std::vector<double>& local_Jac_data)
124 auto const local_matrix_size = local_x.size();
125 assert(local_matrix_size == temperature_size + displacement_size);
127 auto T = Eigen::Map<
typename ShapeMatricesType::template VectorType<
128 temperature_size>
const>(local_x.data() + temperature_index,
131 auto u = Eigen::Map<
typename ShapeMatricesType::template VectorType<
132 displacement_size>
const>(local_x.data() + displacement_index,
134 bool const is_u_non_zero = u.norm() > 0.0;
136 auto T_prev = Eigen::Map<
typename ShapeMatricesType::template VectorType<
137 temperature_size>
const>(local_x_prev.data() + temperature_index,
140 auto local_Jac = MathLib::createZeroedMatrix<JacobianMatrix>(
141 local_Jac_data, local_matrix_size, local_matrix_size);
143 auto local_rhs = MathLib::createZeroedVector<RhsVector>(local_rhs_data,
146 typename ShapeMatricesType::template MatrixType<displacement_size,
149 KuT.setZero(displacement_size, temperature_size);
152 KTT.setZero(temperature_size, temperature_size);
155 DTT.setZero(temperature_size, temperature_size);
157 unsigned const n_integration_points =
158 _integration_method.getNumberOfPoints();
165 auto const& medium = _process_data.media_map.getMedium(_element.getID());
166 auto const& solid_phase = medium->phase(
"Solid");
168 for (
unsigned ip = 0; ip < n_integration_points; ip++)
171 auto const& w = _ip_data[ip].integration_weight;
172 auto const& N = _ip_data[ip].N;
173 auto const& dNdx = _ip_data[ip].dNdx;
176 NumLib::interpolateXCoordinate<ShapeFunction, ShapeMatricesType>(
180 ShapeFunction::NPOINTS,
182 dNdx, N, x_coord, _is_axially_symmetric);
184 auto& sigma = _ip_data[ip].sigma;
185 auto const& sigma_prev = _ip_data[ip].sigma_prev;
187 auto& eps = _ip_data[ip].eps;
188 auto const& eps_prev = _ip_data[ip].eps_prev;
190 auto& eps_m = _ip_data[ip].eps_m;
191 auto const& eps_m_prev = _ip_data[ip].eps_m_prev;
193 auto& state = _ip_data[ip].material_state_variables;
195 const double T_ip = N.dot(T);
196 double const T_prev_ip = N.dot(T_prev);
199 auto const solid_linear_thermal_expansivity_vector =
200 MPL::formKelvinVector<DisplacementDim>(
204 .value(variables, x_position, t, dt));
208 solid_linear_thermal_expansivity_vector * (T_ip - T_prev_ip);
218 eps.noalias() = B * u;
221 eps_m.noalias() = eps_m_prev + eps - eps_prev - dthermal_strain;
235 auto&& solution = _ip_data[ip].solid_material.integrateStress(
236 variables_prev, variables, t, x_position, dt, *state);
240 OGS_FATAL(
"Computation of local constitutive relation failed.");
244 std::tie(sigma, state, C) = std::move(*solution);
247 .template block<displacement_size, displacement_size>(
248 displacement_index, displacement_index)
249 .noalias() += B.transpose() * C * B * w;
251 typename ShapeMatricesType::template MatrixType<DisplacementDim,
253 N_u = ShapeMatricesType::template MatrixType<
254 DisplacementDim, displacement_size>::Zero(DisplacementDim,
257 for (
int i = 0; i < DisplacementDim; ++i)
259 N_u.template block<1, displacement_size / DisplacementDim>(
260 i, i * displacement_size / DisplacementDim)
265 solid_phase.property(MPL::PropertyType::density)
266 .template value<double>(variables, x_position, t, dt);
268 auto const& b = _process_data.specific_body_force;
269 local_rhs.template block<displacement_size, 1>(displacement_index, 0)
271 (B.transpose() * sigma - N_u.transpose() * rho_s * b) * w;
276 auto const alpha_T_tensor =
278 solid_linear_thermal_expansivity_vector);
279 KuT.noalias() += B.transpose() * (C * alpha_T_tensor) * N * w;
281 if (_ip_data[ip].solid_material.getConstitutiveModel() ==
284 auto const s = Invariants::deviatoric_projection * sigma;
285 double const norm_s = Invariants::FrobeniusNorm(s);
286 const double creep_coefficient =
287 _ip_data[ip].solid_material.getTemperatureRelatedCoefficient(
288 t, dt, x_position, T_ip, norm_s);
289 KuT.noalias() += creep_coefficient * B.transpose() * s * N * w;
299 .value(variables, x_position, t, dt);
302 MaterialPropertyLib::formEigenTensor<DisplacementDim>(lambda);
304 KTT.noalias() += dNdx.transpose() * thermal_conductivity * dNdx * w;
310 .template value<double>(variables, x_position, t, dt);
311 DTT.noalias() += N.transpose() * rho_s * c * N * w;
316 .template block<temperature_size, temperature_size>(temperature_index,
318 .noalias() += KTT + DTT / dt;
322 .template block<displacement_size, temperature_size>(displacement_index,
326 local_rhs.template block<temperature_size, 1>(temperature_index, 0)
327 .noalias() -= KTT * T + DTT * (T - T_prev) / dt;
330template <
typename ShapeFunction,
int DisplacementDim>
333 const double t,
double const dt, Eigen::VectorXd
const& local_x,
334 Eigen::VectorXd
const& local_x_prev,
int const process_id,
335 std::vector<double>& ,
336 std::vector<double>& ,
337 std::vector<double>& local_b_data, std::vector<double>& local_Jac_data)
340 if (process_id == _process_data.heat_conduction_process_id)
342 assembleWithJacobianForHeatConductionEquations(
343 t, dt, local_x, local_x_prev, local_b_data, local_Jac_data);
348 assembleWithJacobianForDeformationEquations(t, dt, local_x, local_x_prev,
349 local_b_data, local_Jac_data);
352template <
typename ShapeFunction,
int DisplacementDim>
355 const double t,
double const dt, Eigen::VectorXd
const& local_x,
356 Eigen::VectorXd
const& local_x_prev, std::vector<double>& local_b_data,
357 std::vector<double>& local_Jac_data)
360 local_x.template segment<temperature_size>(temperature_index);
362 auto const local_T_prev =
363 local_x_prev.template segment<temperature_size>(temperature_index);
366 local_x.template segment<displacement_size>(displacement_index);
367 bool const is_u_non_zero = local_u.norm() > 0.0;
370 typename ShapeMatricesType::template MatrixType<displacement_size,
372 local_Jac_data, displacement_size, displacement_size);
375 typename ShapeMatricesType::template VectorType<displacement_size>>(
376 local_b_data, displacement_size);
378 unsigned const n_integration_points =
379 _integration_method.getNumberOfPoints();
385 auto const& medium = _process_data.media_map.getMedium(_element.getID());
386 auto const& solid_phase = medium->phase(
"Solid");
388 for (
unsigned ip = 0; ip < n_integration_points; ip++)
391 auto const& w = _ip_data[ip].integration_weight;
392 auto const& N = _ip_data[ip].N;
393 auto const& dNdx = _ip_data[ip].dNdx;
396 NumLib::interpolateXCoordinate<ShapeFunction, ShapeMatricesType>(
400 ShapeFunction::NPOINTS,
402 dNdx, N, x_coord, _is_axially_symmetric);
404 auto& sigma = _ip_data[ip].sigma;
405 auto const& sigma_prev = _ip_data[ip].sigma_prev;
407 auto& eps = _ip_data[ip].eps;
408 auto const& eps_prev = _ip_data[ip].eps_prev;
410 auto& eps_m = _ip_data[ip].eps_m;
411 auto const& eps_m_prev = _ip_data[ip].eps_m_prev;
413 auto& state = _ip_data[ip].material_state_variables;
415 const double T_ip = N.dot(local_T);
417 double const dT_ip = T_ip - N.dot(local_T_prev);
427 eps.noalias() = B * local_u;
431 auto const solid_linear_thermal_expansivity_vector =
432 MPL::formKelvinVector<DisplacementDim>(
436 .value(variables, x_position, t, dt));
439 dthermal_strain = solid_linear_thermal_expansivity_vector * dT_ip;
441 eps_m.noalias() = eps_m_prev + eps - eps_prev - dthermal_strain;
454 auto&& solution = _ip_data[ip].solid_material.integrateStress(
455 variables_prev, variables, t, x_position, dt, *state);
459 OGS_FATAL(
"Computation of local constitutive relation failed.");
463 std::tie(sigma, state, C) = std::move(*solution);
465 local_Jac.noalias() += B.transpose() * C * B * w;
467 typename ShapeMatricesType::template MatrixType<DisplacementDim,
469 N_u = ShapeMatricesType::template MatrixType<
470 DisplacementDim, displacement_size>::Zero(DisplacementDim,
473 for (
int i = 0; i < DisplacementDim; ++i)
475 N_u.template block<1, displacement_size / DisplacementDim>(
476 i, i * displacement_size / DisplacementDim)
481 solid_phase.property(MPL::PropertyType::density)
482 .template value<double>(variables, x_position, t, dt);
484 auto const& b = _process_data.specific_body_force;
485 local_rhs.noalias() -=
486 (B.transpose() * sigma - N_u.transpose() * rho_s * b) * w;
490template <
typename ShapeFunction,
int DisplacementDim>
493 const double t,
double const dt, Eigen::VectorXd
const& local_x,
494 Eigen::VectorXd
const& local_x_prev, std::vector<double>& local_b_data,
495 std::vector<double>& local_Jac_data)
498 local_x.template segment<temperature_size>(temperature_index);
500 auto const local_T_prev =
501 local_x_prev.template segment<temperature_size>(temperature_index);
504 typename ShapeMatricesType::template MatrixType<temperature_size,
506 local_Jac_data, temperature_size, temperature_size);
509 typename ShapeMatricesType::template VectorType<temperature_size>>(
510 local_b_data, temperature_size);
513 mass.setZero(temperature_size, temperature_size);
516 laplace.setZero(temperature_size, temperature_size);
518 unsigned const n_integration_points =
519 _integration_method.getNumberOfPoints();
523 auto const& medium = _process_data.media_map.getMedium(_element.getID());
524 auto const& solid_phase = medium->phase(
"Solid");
527 for (
unsigned ip = 0; ip < n_integration_points; ip++)
530 auto const& w = _ip_data[ip].integration_weight;
531 auto const& N = _ip_data[ip].N;
532 auto const& dNdx = _ip_data[ip].dNdx;
534 const double T_ip = N.dot(local_T);
538 solid_phase.property(MPL::PropertyType::density)
539 .template value<double>(variables, x_position, t, dt);
541 solid_phase.property(MPL::PropertyType::specific_heat_capacity)
542 .template value<double>(variables, x_position, t, dt);
544 mass.noalias() += N.transpose() * rho_s * c_p * N * w;
550 .value(variables, x_position, t, dt);
553 MaterialPropertyLib::formEigenTensor<DisplacementDim>(lambda);
555 laplace.noalias() += dNdx.transpose() * thermal_conductivity * dNdx * w;
557 local_Jac.noalias() += laplace + mass / dt;
559 local_rhs.noalias() -=
560 laplace * local_T + mass * (local_T - local_T_prev) / dt;
563template <
typename ShapeFunction,
int DisplacementDim>
566 double const* values)
568 return ProcessLib::setIntegrationPointKelvinVectorData<DisplacementDim>(
569 values, _ip_data, &IpData::sigma);
572template <
typename ShapeFunction,
int DisplacementDim>
576 constexpr int kelvin_vector_size =
579 return transposeInPlace<kelvin_vector_size>(
580 [
this](std::vector<double>& values)
581 {
return getIntPtSigma(0, {}, {}, values); });
584template <
typename ShapeFunction,
int DisplacementDim>
585std::vector<double>
const&
588 std::vector<GlobalVector*>
const& ,
589 std::vector<NumLib::LocalToGlobalIndexMap const*>
const& ,
590 std::vector<double>& cache)
const
592 return ProcessLib::getIntegrationPointKelvinVectorData<DisplacementDim>(
593 _ip_data, &IpData::sigma, cache);
596template <
typename ShapeFunction,
int DisplacementDim>
599 double const* values)
601 return ProcessLib::setIntegrationPointKelvinVectorData<DisplacementDim>(
602 values, _ip_data, &IpData::eps);
605template <
typename ShapeFunction,
int DisplacementDim>
607 ShapeFunction, DisplacementDim>::getEpsilon()
const
609 constexpr int kelvin_vector_size =
612 return transposeInPlace<kelvin_vector_size>(
613 [
this](std::vector<double>& values)
614 {
return getIntPtEpsilon(0, {}, {}, values); });
617template <
typename ShapeFunction,
int DisplacementDim>
618std::vector<double>
const&
621 std::vector<GlobalVector*>
const& ,
622 std::vector<NumLib::LocalToGlobalIndexMap const*>
const& ,
623 std::vector<double>& cache)
const
625 return ProcessLib::getIntegrationPointKelvinVectorData<DisplacementDim>(
626 _ip_data, &IpData::eps, cache);
629template <
typename ShapeFunction,
int DisplacementDim>
630std::vector<double>
const&
634 std::vector<GlobalVector*>
const& ,
635 std::vector<NumLib::LocalToGlobalIndexMap const*>
const& ,
636 std::vector<double>& cache)
const
638 return ProcessLib::getIntegrationPointKelvinVectorData<DisplacementDim>(
639 _ip_data, &IpData::eps_m, cache);
642template <
typename ShapeFunction,
int DisplacementDim>
644 ShapeFunction, DisplacementDim>::setEpsilonMechanical(
double const* values)
646 return ProcessLib::setIntegrationPointKelvinVectorData<DisplacementDim>(
647 values, _ip_data, &IpData::eps_m);
649template <
typename ShapeFunction,
int DisplacementDim>
651 ShapeFunction, DisplacementDim>::getEpsilonMechanical()
const
653 constexpr int kelvin_vector_size =
656 return transposeInPlace<kelvin_vector_size>(
657 [
this](std::vector<double>& values)
658 {
return getIntPtEpsilonMechanical(0, {}, {}, values); });
661template <
typename ShapeFunction,
int DisplacementDim>
663 ShapeFunction, DisplacementDim>::getNumberOfIntegrationPoints()
const
665 return _integration_method.getNumberOfPoints();
668template <
typename ShapeFunction,
int DisplacementDim>
670 DisplacementDim>::getMaterialID()
const
672 return _process_data.material_ids ==
nullptr
674 : (*_process_data.material_ids)[_element.getID()];
677template <
typename ShapeFunction,
int DisplacementDim>
679 DisplacementDim>::MaterialStateVariables
const&
683 return *_ip_data[integration_point].material_state_variables;
std::variant< std::monostate, Eigen::Matrix< double, 4, 1 >, Eigen::Matrix< double, 6, 1 > > mechanical_strain
std::variant< std::monostate, Eigen::Matrix< double, 4, 1 >, Eigen::Matrix< double, 6, 1 > > 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
Local assembler of ThermoMechanics process.
std::vector< double > const & getIntPtEpsilonMechanical(const double t, std::vector< GlobalVector * > const &x, std::vector< NumLib::LocalToGlobalIndexMap const * > const &dof_table, std::vector< double > &cache) const override
SecondaryData< typename ShapeMatrices::ShapeType > _secondary_data
std::size_t setSigma(double const *values)
std::vector< double > const & getIntPtSigma(const double t, std::vector< GlobalVector * > const &x, std::vector< NumLib::LocalToGlobalIndexMap const * > const &dof_table, std::vector< double > &cache) const override
MeshLib::Element const & _element
ThermoMechanicsLocalAssembler(ThermoMechanicsLocalAssembler const &)=delete
MaterialLib::Solids::MechanicsBase< DisplacementDim >::MaterialStateVariables const & getMaterialStateVariablesAt(unsigned integration_point) const override
void assembleWithJacobianForStaggeredScheme(double const t, double const dt, Eigen::VectorXd const &local_x, Eigen::VectorXd const &local_x_prev, int const process_id, std::vector< double > &local_M_data, std::vector< double > &local_K_data, std::vector< double > &local_b_data, std::vector< double > &local_Jac_data) override
ThermoMechanicsProcessData< DisplacementDim > & _process_data
NumLib::GenericIntegrationMethod const & _integration_method
void assembleWithJacobianForHeatConductionEquations(const double t, double const dt, Eigen::VectorXd const &local_x, Eigen::VectorXd const &local_x_prev, std::vector< double > &local_b_data, std::vector< double > &local_Jac_data)
ShapeMatrixPolicyType< ShapeFunction, DisplacementDim > ShapeMatricesType
void assembleWithJacobianForDeformationEquations(const double t, double const dt, Eigen::VectorXd const &local_x, Eigen::VectorXd const &local_x_prev, std::vector< double > &local_b_data, std::vector< double > &local_Jac_data)
std::size_t setEpsilon(double const *values)
typename ShapeMatricesType::GlobalDimMatrixType GlobalDimMatrixType
std::vector< double > getSigma() const override
void assembleWithJacobian(double const t, double const dt, std::vector< double > const &local_x, std::vector< double > const &local_x_prev, std::vector< double > &local_M_data, std::vector< double > &local_K_data, std::vector< double > &local_rhs_data, std::vector< double > &local_Jac_data) override
std::vector< IpData, Eigen::aligned_allocator< IpData > > _ip_data
std::size_t setIPDataInitialConditions(std::string const &name, double const *values, int const integration_order) override
Returns number of read integration points.
std::vector< double > const & getIntPtEpsilon(const double t, std::vector< GlobalVector * > const &x, std::vector< NumLib::LocalToGlobalIndexMap const * > const &dof_table, std::vector< double > &cache) const override
auto & selectSolidConstitutiveRelation(SolidMaterialsMap const &constitutive_relations, MeshLib::PropertyVector< int > const *const material_ids, std::size_t const element_id)
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, kelvin_vector_dimensions(DisplacementDim), kelvin_vector_dimensions(DisplacementDim), Eigen::RowMajor > KelvinMatrixType
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)
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.
MatrixType< ShapeFunction::NPOINTS, ShapeFunction::NPOINTS > NodalMatrixType
std::vector< ShapeMatrixType, Eigen::aligned_allocator< ShapeMatrixType > > N