16#include <MGIS/Behaviour/Behaviour.hxx>
19#include <MGIS/Behaviour/BehaviourData.hxx>
20#include <MGIS/Behaviour/Integrate.hxx>
21#include <boost/mp11.hpp>
34namespace MPL = MaterialPropertyLib;
41template <
typename Derived>
45 Eigen::Matrix<
typename Derived::Scalar, Derived::RowsAtCompileTime,
46 Derived::ColsAtCompileTime>;
48 return Matrix::NullaryExpr(
49 matrix.rows(), matrix.cols(),
50 [&m = matrix.derived()](Eigen::Index
const row, Eigen::Index
const col)
52 constexpr std::ptrdiff_t result[6] = {0, 1, 2, 3, 5, 4};
53 return m(result[row], result[col]);
64template <
int DisplacementDim,
typename Derived>
68 Eigen::Matrix<
typename Derived::Scalar, Derived::RowsAtCompileTime,
69 Derived::ColsAtCompileTime>;
71 if constexpr (DisplacementDim == 2)
73 return Matrix::NullaryExpr(
74 matrix.rows(), matrix.cols(),
75 [&m = matrix.derived()](Eigen::Index
const row,
76 Eigen::Index
const col)
78 constexpr std::ptrdiff_t result[5] = {0, 3, 4, 1, 2};
79 return m(result[row], result[col]);
82 if constexpr (DisplacementDim == 3)
84 return Matrix::NullaryExpr(
85 matrix.rows(), matrix.cols(),
86 [&m = matrix.derived()](Eigen::Index
const row,
87 Eigen::Index
const col)
89 constexpr std::ptrdiff_t result[9] = {0, 4, 8, 1, 3,
91 return m(result[row], result[col]);
105template <
int DisplacementDim>
107 std::vector<double>
const& mfront_data,
110 mgis::behaviour::Behaviour
const& behaviour);
112extern template OGSMFrontTangentOperatorData tangentOperatorDataMFrontToOGS<2>(
113 std::vector<double>
const& mfront_data,
115 mgis::behaviour::Behaviour
const& behaviour);
116extern template OGSMFrontTangentOperatorData tangentOperatorDataMFrontToOGS<3>(
117 std::vector<double>
const& mfront_data,
119 mgis::behaviour::Behaviour
const& behaviour);
122template <
int DisplacementDim>
127 int const equivalent_plastic_strain_offset,
128 mgis::behaviour::Behaviour
const& b)
149 .internal_state_variables[
static_cast<mgis::size_type
>(
160template <
int DisplacementDim, mgis::behaviour::Variable::Type MFrontType>
163template <
int DisplacementDim>
169template <
int DisplacementDim>
175template <
int DisplacementDim>
181template <
int DisplacementDim, mgis::behaviour::Variable::Type MFrontType>
186template <
int DisplacementDim>
194 template <
typename Grad>
197 auto constexpr num_comp = Grad::template size<DisplacementDim>();
199 if constexpr (Grad::type == mgis::behaviour::Variable::Type::SCALAR)
203 else if constexpr (Grad::type ==
204 mgis::behaviour::Variable::Type::STENSOR)
207 auto const& grad_ogs =
210 auto const grad_mfront =
213 std::copy_n(grad_mfront.data(), num_comp,
target);
215 else if constexpr (Grad::type ==
216 mgis::behaviour::Variable::Type::TENSOR)
219 auto const& grad_ogs =
224 OGS_FATAL(
"Rotations of tensors are not implemented.");
227 Eigen::Map<Eigen::Vector<double, num_comp>>{
target} =
232 OGS_FATAL(
"Unsupported gradient type {}.",
243template <
int DisplacementDim,
246 typename ExtStateVars>
249 static_assert(boost::mp11::mp_is_set<Gradients>::value);
250 static_assert(boost::mp11::mp_is_set<TDynForces>::value);
251 static_assert(boost::mp11::mp_is_set<ExtStateVars>::value);
254 boost::mp11::mp_append<Gradients, ExtStateVars>;
256 static_assert(boost::mp11::mp_is_set<GradientsAndExtStateVars>::value);
267 mgis::behaviour::Behaviour&& behaviour,
271 state_variables_initial_properties,
272 std::optional<ParameterLib::CoordinateSystem>
const&
273 local_coordinate_system)
279 std::move(state_variables_initial_properties)),
281 ? &local_coordinate_system.value()
285 auto check_gradient = [&grads =
_behaviour.gradients,
287 i = 0]<
typename Grad>(Grad)
mutable
290 if (grads[i].name != Grad::name)
293 "OGS expects the {}th gradient to be {} but MFront "
295 i, Grad::name, grads[i].name);
298 if (grads[i].type != Grad::type)
301 "The behaviour's {}th driver ({}) must be of type {}.",
305 if (mgis::behaviour::getVariableSize(grads[i], hyp) !=
306 Grad::template size<DisplacementDim>())
309 "The behaviour's {}th driver's ({}) size in OGS is {} "
312 Grad::template size<DisplacementDim>(),
313 mgis::behaviour::getVariableSize(grads[i], hyp));
320 boost::mp11::mp_size<Gradients>::value)
322 "The behaviour must have exactly {} gradients as input.",
323 boost::mp11::mp_size<Gradients>::value);
325 boost::mp11::mp_for_each<Gradients>(check_gradient);
329 auto check_tdyn_force = [&tdfs =
_behaviour.thermodynamic_forces,
331 i = 0]<
typename TDF>(TDF)
mutable
333 if (tdfs[i].name != TDF::name)
336 "OGS expects the {}th thermodynamic force to be {} but "
337 "MFront provides {}.",
338 i, TDF::name, tdfs[i].name);
341 if (tdfs[i].type != TDF::type)
344 "The behaviour's {}th thermodynamic force ({}) must be "
349 if (mgis::behaviour::getVariableSize(tdfs[i], hyp) !=
350 TDF::template size<DisplacementDim>())
353 "The behaviour's {}th thermodynamic force ({}) must "
354 "have size {} instead of {}.",
355 i, tdfs[i].name, TDF::template size<DisplacementDim>(),
356 mgis::behaviour::getVariableSize(tdfs[i], hyp));
363 boost::mp11::mp_size<TDynForces>::value)
365 "The behaviour must compute exactly {} thermodynamic "
367 boost::mp11::mp_size<TDynForces>::value);
369 boost::mp11::mp_for_each<TDynForces>(check_tdyn_force);
372 auto const hypothesis =
_behaviour.hypothesis;
375 std::is_same_v<ExtStateVars, boost::mp11::mp_list<Temperature>>,
376 "Temperature is the only allowed external state variable.");
380 if (_behaviour.esvs[0].name !=
"Temperature")
383 "Only temperature is supported as external state "
387 if (mgis::behaviour::getVariableSize(
_behaviour.esvs[0],
390 "Temperature must be a scalar instead of having {:d} "
392 mgis::behaviour::getVariableSize(
393 _behaviour.thermodynamic_forces[0], hypothesis));
396 if (_behaviour.mps.size() != _material_properties.size())
398 ERR(
"There are {:d} material properties in the loaded behaviour:",
399 _behaviour.mps.size());
400 for (auto const& mp : _behaviour.mps)
402 ERR(
"\t{:s}", mp.name);
404 OGS_FATAL(
"But the number of passed material properties is {:d}.",
405 _material_properties.size());
410 typename MechanicsBase<DisplacementDim>::MaterialStateVariables>
413 return std::make_unique<MaterialStateVariablesMFront<DisplacementDim>>(
421 material_state_variables)
const
424 &material_state_variables));
428 material_state_variables);
438 {
return iv.name == name; },
440 {
OGS_FATAL(
"Internal variable `{:s}' not found.", name); });
443 std::vector<double> values = (*parameter)(t, x);
446 auto const values_span = iv.reference(state);
447 assert(values.size() == values_span.size());
448 std::copy_n(begin(values), values_span.size(), values_span.begin());
451 auto const& s1 = state._behaviour_data.s1.internal_state_variables;
452 auto& s0 = state._behaviour_data.s0.internal_state_variables;
453 std::copy(begin(s1), end(s1), begin(s0));
458 DisplacementDim>::MaterialStateVariables>,
467 material_state_variables)
const
473 &material_state_variables));
475 auto state = std::make_unique<
478 material_state_variables));
481 behaviour_data.dt = dt;
482 behaviour_data.rdt = 1.0;
483 behaviour_data.K[0] =
486 if (behaviour_data.s0.b.btype ==
487 mgis::behaviour::Behaviour::STANDARDFINITESTRAINBEHAVIOUR)
489 behaviour_data.K[1] = 1.0;
491 behaviour_data.K[2] =
500 auto out = behaviour_data.s0.material_properties.begin();
503 auto const& vals = (*param)(
t - dt, x);
504 out = std::copy(vals.begin(), vals.end(), out);
506 assert(out == behaviour_data.s0.material_properties.end());
510 auto out = behaviour_data.s1.material_properties.begin();
513 auto const& vals = (*param)(
t, x);
514 out = std::copy(vals.begin(), vals.end(), out);
516 assert(out == behaviour_data.s1.material_properties.end());
522 if (!behaviour_data.s0.external_state_variables.empty())
527 behaviour_data.s0.external_state_variables[0] =
531 if (!behaviour_data.s1.external_state_variables.empty())
536 behaviour_data.s1.external_state_variables[0] =
541 std::optional<KelvinMatrixType<DisplacementDim>> Q;
548 boost::mp11::mp_for_each<Gradients>(
550 variable_array_prev, Q, behaviour_data.s0.gradients.data()});
551 boost::mp11::mp_for_each<Gradients>(
553 variable_array, Q, behaviour_data.s1.gradients.data()});
558 boost::mp11::mp_for_each<TDynForces>(
560 variable_array_prev, Q,
561 behaviour_data.s0.thermodynamic_forces.data()});
562 boost::mp11::mp_for_each<TDynForces>(
564 variable_array_prev, Q,
565 behaviour_data.s1.thermodynamic_forces.data()});
567 auto v = mgis::behaviour::make_view(behaviour_data);
568 auto const status = mgis::behaviour::integrate(
v,
_behaviour);
572 "MFront: integration failed with status " +
573 std::to_string(status) +
".");
577 tdyn_forces_data.
data.resize(
579 behaviour_data.s1.thermodynamic_forces.size());
581 boost::mp11::mp_for_each<TDynForces>(
582 [&out_data = tdyn_forces_data,
583 &in_data = behaviour_data.s1.thermodynamic_forces,
584 &Q]<
typename TDF>(TDF tdf)
586 OGSMFrontThermodynamicForcesView<DisplacementDim, TDynForces>
589 if constexpr (TDF::type ==
590 mgis::behaviour::Variable::Type::STENSOR)
594 view.block(tdf, out_data) =
595 *Q * eigenSwap45View(view.block(tdf, in_data));
599 view.block(tdf, out_data) =
600 eigenSwap45View(view.block(tdf, in_data));
603 else if constexpr (TDF::type ==
604 mgis::behaviour::Variable::Type::SCALAR)
606 view.block(tdf, out_data) = view.block(tdf, in_data);
614 return std::make_optional(
617 DisplacementDim>::MaterialStateVariables>,
619 std::move(tdyn_forces_data),
622 behaviour_data.K, Q, _behaviour)));
627 std::vector<InternalVariable> internal_variables;
631 auto const name = iv.name;
632 auto const offset = mgis::behaviour::getVariableOffset(
635 mgis::behaviour::getVariableSize(iv,
_behaviour.hypothesis);
643 name,
static_cast<int>(size),
646 DisplacementDim>::MaterialStateVariables
const& state,
647 std::vector<double>& cache) -> std::vector<double>
const&
650 DisplacementDim
> const*>(&state) !=
nullptr);
651 auto const& internal_state_variables =
653 DisplacementDim
> const&>(state)
654 ._behaviour_data.s1.internal_state_variables;
657 std::copy_n(internal_state_variables.data() + offset,
663 DisplacementDim>::MaterialStateVariables& state)
667 DisplacementDim
> const*>(&state) !=
nullptr);
668 auto& internal_state_variables =
672 ._behaviour_data.s1.internal_state_variables;
674 return {internal_state_variables.data() + offset, size};
676 internal_variables.push_back(new_variable);
679 return internal_variables;
706 "MFront::getBulkModulus() requires the tangent stiffness C "
708 "argument to be valid.");
726 return std::numeric_limits<double>::quiet_NaN();
733 std::map<std::string, ParameterLib::Parameter<double>
const*>
std::optional< std::tuple< OGSMFrontThermodynamicForcesData, std::unique_ptr< typename MechanicsBase< DisplacementDim >::MaterialStateVariables >, OGSMFrontTangentOperatorData > > integrateStress(MaterialPropertyLib::VariableArray const &variable_array_prev, MaterialPropertyLib::VariableArray const &variable_array, double const t, ParameterLib::SpatialPosition const &x, double const dt, typename MechanicsBase< DisplacementDim >::MaterialStateVariables const &material_state_variables) const
int const equivalent_plastic_strain_offset_
mgis::behaviour::Behaviour _behaviour
OGSMFrontTangentOperatorBlocksView< DisplacementDim, ForcesGradsCombinations > createTangentOperatorBlocksView() const
std::vector< InternalVariable > getInternalVariables() const
std::unique_ptr< typename MechanicsBase< DisplacementDim >::MaterialStateVariables > createMaterialStateVariables() const
MathLib::KelvinVector::KelvinVectorType< DisplacementDim > KelvinVector
double computeFreeEnergyDensity(double const, ParameterLib::SpatialPosition const &, double const, KelvinVector const &, KelvinVector const &, typename MechanicsBase< DisplacementDim >::MaterialStateVariables const &) const
OGSMFrontThermodynamicForcesView< DisplacementDim, TDynForces > createThermodynamicForcesView() const
std::vector< ParameterLib::Parameter< double > const * > _material_properties
void initializeInternalStateVariables(double const t, ParameterLib::SpatialPosition const &x, typename MechanicsBase< DisplacementDim >::MaterialStateVariables &material_state_variables) const
typename MechanicsBase< DisplacementDim >::InternalVariable InternalVariable
std::map< std::string, ParameterLib::Parameter< double > const * > _state_variables_initial_properties
boost::mp11::mp_append< boost::mp11::mp_list< Strain >, boost::mp11::mp_list< Temperature > > GradientsAndExtStateVars
MFrontGeneric(mgis::behaviour::Behaviour &&behaviour, std::vector< ParameterLib::Parameter< double > const * > &&material_properties, std::map< std::string, ParameterLib::Parameter< double > const * > &&state_variables_initial_properties, std::optional< ParameterLib::CoordinateSystem > const &local_coordinate_system)
double getBulkModulus(double const, ParameterLib::SpatialPosition const &, KelvinMatrix const *const C) const
ParameterLib::CoordinateSystem const *const _local_coordinate_system
MathLib::KelvinVector::KelvinMatrixType< DisplacementDim > KelvinMatrix
ranges::range_reference_t< Range > findElementOrError(Range &range, std::predicate< ranges::range_reference_t< Range > > auto &&predicate, std::invocable auto error_callback)
typename MapToMPLType< DisplacementDim, MFrontType >::type MapToMPLType_t
OGSMFrontTangentOperatorData tangentOperatorDataMFrontToOGS(std::vector< double > const &mfront_data, std::optional< MathLib::KelvinVector::KelvinMatrixType< DisplacementDim > > const &Q, mgis::behaviour::Behaviour const &behaviour)
constexpr auto ogsTensorToMFrontTensor(Eigen::MatrixBase< Derived > const &matrix)
constexpr auto eigenSwap45View(Eigen::MatrixBase< Derived > const &matrix)
const char * varTypeToString(int v)
int getEquivalentPlasticStrainOffset(mgis::behaviour::Behaviour const &b)
Eigen::Matrix< double, tensorSize(Dim), 1 > Tensor
Eigen::Matrix< double, symmetric_tensor_size< GlobalDim >, 1 > SymmetricTensor
KelvinMatrixType< DisplacementDim > fourthOrderRotationMatrix(Eigen::Matrix< double, DisplacementDim, DisplacementDim, Eigen::ColMajor, DisplacementDim, DisplacementDim > const &transformation)
constexpr int kelvin_vector_dimensions(int const displacement_dim)
Kelvin vector dimensions for given displacement dimension.
Eigen::Matrix< double, kelvin_vector_dimensions(DisplacementDim), 1, Eigen::ColMajor > KelvinVectorType
const Eigen::Matrix< double, KelvinVectorSize, 1 > Invariants< KelvinVectorSize >::identity2
Eigen::Matrix< double, kelvin_vector_dimensions(DisplacementDim), kelvin_vector_dimensions(DisplacementDim), Eigen::RowMajor > KelvinMatrixType
int const equivalent_plastic_strain_offset_
MaterialStateVariablesMFront(int const equivalent_plastic_strain_offset, mgis::behaviour::Behaviour const &b)
MaterialStateVariablesMFront(MaterialStateVariablesMFront< DisplacementDim > &&)=delete
void pushBackState() override
mgis::behaviour::BehaviourData _behaviour_data
MaterialStateVariablesMFront(MaterialStateVariablesMFront< DisplacementDim > const &)=default
double getEquivalentPlasticStrain() const override
Used for disambiguation with MFront's thermodynamic forces data.
Used for disambiguation with MFront's tangent operator blocks data.
std::vector< double > data
MaterialPropertyLib::Tensor< DisplacementDim > type
MaterialPropertyLib::SymmetricTensor< DisplacementDim > type
A struct mapping a MGIS variable type to its corresponding OGS type.
std::optional< MathLib::KelvinVector::KelvinMatrixType< DisplacementDim > > const & Q
MaterialPropertyLib::VariableArray const & variable_array
Helper type for providing access to internal variables.
A local coordinate system used for tensor transformations.