12 #include <MGIS/Behaviour/Integrate.hxx>
44 template <
typename Derived>
45 typename Derived::PlainObject
OGSToMFront(Eigen::DenseBase<Derived>
const& m)
47 static_assert(Derived::RowsAtCompileTime != Eigen::Dynamic,
"Error");
48 static_assert(Derived::ColsAtCompileTime != Eigen::Dynamic,
"Error");
50 typename Derived::PlainObject n;
53 for (std::ptrdiff_t
r = 0; r < Eigen::DenseBase<Derived>::RowsAtCompileTime;
57 for (std::ptrdiff_t
c = 0;
58 c < Eigen::DenseBase<Derived>::ColsAtCompileTime;
70 template <
typename Derived>
71 typename Derived::PlainObject
MFrontToOGS(Eigen::DenseBase<Derived>
const& m)
73 static_assert(Derived::RowsAtCompileTime != Eigen::Dynamic,
"Error");
74 static_assert(Derived::ColsAtCompileTime != Eigen::Dynamic,
"Error");
76 typename Derived::PlainObject n;
79 for (std::ptrdiff_t
r = 0; r < Eigen::DenseBase<Derived>::RowsAtCompileTime;
83 for (std::ptrdiff_t
c = 0;
84 c < Eigen::DenseBase<Derived>::ColsAtCompileTime;
103 const char*
toString(mgis::behaviour::Behaviour::Kinematic kin)
105 using K = mgis::behaviour::Behaviour::Kinematic;
108 case K::UNDEFINEDKINEMATIC:
109 return "UNDEFINEDKINEMATIC";
110 case K::SMALLSTRAINKINEMATIC:
111 return "SMALLSTRAINKINEMATIC";
112 case K::COHESIVEZONEKINEMATIC:
113 return "COHESIVEZONEKINEMATIC";
114 case K::FINITESTRAINKINEMATIC_F_CAUCHY:
115 return "FINITESTRAINKINEMATIC_F_CAUCHY";
116 case K::FINITESTRAINKINEMATIC_ETO_PK1:
117 return "FINITESTRAINKINEMATIC_ETO_PK1";
120 OGS_FATAL(
"Unknown kinematic {:d}.", kin);
123 const char*
toString(mgis::behaviour::Behaviour::Symmetry sym)
125 using S = mgis::behaviour::Behaviour::Symmetry;
131 return "ORTHOTROPIC";
134 OGS_FATAL(
"Unknown symmetry {:d}.", sym);
138 using B = mgis::behaviour::Behaviour;
139 if (btype == B::GENERALBEHAVIOUR)
140 return "GENERALBEHAVIOUR";
141 if (btype == B::STANDARDSTRAINBASEDBEHAVIOUR)
142 return "STANDARDSTRAINBASEDBEHAVIOUR";
143 if (btype == B::STANDARDFINITESTRAINBEHAVIOUR)
144 return "STANDARDFINITESTRAINBEHAVIOUR";
145 if (btype == B::COHESIVEZONEMODEL)
146 return "COHESIVEZONEMODEL";
148 OGS_FATAL(
"Unknown behaviour type {:d}.", btype);
162 OGS_FATAL(
"Unknown variable type {:d}.", v);
168 ? mgis::behaviour::getVariableOffset(
169 b.isvs,
"EquivalentPlasticStrain", b.hypothesis)
173 template <
int DisplacementDim>
175 mgis::behaviour::Behaviour&& behaviour,
177 std::optional<ParameterLib::CoordinateSystem>
const&
178 local_coordinate_system)
179 : _behaviour(std::move(behaviour)),
180 equivalent_plastic_strain_offset_(
182 _material_properties(std::move(material_properties)),
183 _local_coordinate_system(
184 local_coordinate_system ? &local_coordinate_system.value() : nullptr)
186 auto const hypothesis = behaviour.hypothesis;
190 "The behaviour must have exactly a single gradient as input.");
193 OGS_FATAL(
"The behaviour must be driven by strain.");
195 if (
_behaviour.gradients[0].type != mgis::behaviour::Variable::STENSOR)
196 OGS_FATAL(
"Strain must be a symmetric tensor.");
198 if (mgis::behaviour::getVariableSize(
_behaviour.gradients[0], hypothesis) !=
200 OGS_FATAL(
"Strain must have {:d} components instead of {:d}.",
202 mgis::behaviour::getVariableSize(
_behaviour.gradients[0],
205 if (
_behaviour.thermodynamic_forces.size() != 1)
207 "The behaviour must compute exactly one thermodynamic force.");
209 if (
_behaviour.thermodynamic_forces[0].name !=
"Stress")
210 OGS_FATAL(
"The behaviour must compute stress.");
212 if (
_behaviour.thermodynamic_forces[0].type !=
213 mgis::behaviour::Variable::STENSOR)
214 OGS_FATAL(
"Stress must be a symmetric tensor.");
216 if (mgis::behaviour::getVariableSize(
_behaviour.thermodynamic_forces[0],
219 OGS_FATAL(
"Stress must have {:d} components instead of {:d}.",
221 mgis::behaviour::getVariableSize(
222 _behaviour.thermodynamic_forces[0], hypothesis));
229 "Only temperature is supported as external state variable.");
232 if (mgis::behaviour::getVariableSize(
_behaviour.esvs[0], hypothesis) !=
235 "Temperature must be a scalar instead of having {:d} "
237 mgis::behaviour::getVariableSize(
238 _behaviour.thermodynamic_forces[0], hypothesis));
243 ERR(
"There are {:d} material properties in the loaded behaviour:",
247 ERR(
"\t{:s}", mp.name);
249 OGS_FATAL(
"But the number of passed material properties is {:d}.",
254 template <
int DisplacementDim>
255 std::unique_ptr<typename MechanicsBase<DisplacementDim>::MaterialStateVariables>
258 return std::make_unique<MaterialStateVariables>(
259 equivalent_plastic_strain_offset_, _behaviour);
262 template <
int DisplacementDim>
263 std::optional<std::tuple<typename MFront<DisplacementDim>::KelvinVector,
265 DisplacementDim>::MaterialStateVariables>,
274 material_state_variables)
const
281 auto state = std::make_unique<MaterialStateVariables>(
283 auto& behaviour_data = state->_behaviour_data;
286 behaviour_data.dt = dt;
287 behaviour_data.rdt = 1.0;
288 behaviour_data.K[0] = 4.0;
293 auto out = behaviour_data.s1.material_properties.begin();
294 for (
auto* param : _material_properties)
296 auto const& vals = (*param)(t, x);
297 out =
std::copy(vals.begin(), vals.end(), out);
299 assert(out == behaviour_data.s1.material_properties.end());
302 if (!behaviour_data.s0.external_state_variables.empty())
305 if (!std::holds_alternative<double>(
306 variable_array_prev[
static_cast<int>(
310 "MPL::Variable::temperature is not set for variable_array_prev "
311 "before calling MFront::integrateStress.");
314 behaviour_data.s1.external_state_variables[0] = std::get<double>(
318 if (!behaviour_data.s1.external_state_variables.empty())
321 if (!std::holds_alternative<double>(
325 "MPL::Variable::temperature is not set for variable_array "
326 "before calling MFront::integrateStress");
329 behaviour_data.s1.external_state_variables[0] = std::get<double>(
336 if (!_local_coordinate_system)
341 _local_coordinate_system->transformation<DisplacementDim>(x));
344 auto const& eps_m_prev = std::get<MPL::SymmetricTensor<DisplacementDim>>(
345 variable_array_prev[
static_cast<int>(
346 MPL::Variable::mechanical_strain)]);
351 DisplacementDim)>() *
353 std::copy_n(eps_prev_MFront.data(), KelvinVector::SizeAtCompileTime,
354 behaviour_data.s0.gradients.data());
356 auto const& eps = std::get<MPL::SymmetricTensor<DisplacementDim>>(
357 variable_array[
static_cast<int>(MPL::Variable::mechanical_strain)]);
362 DisplacementDim)>() *
364 std::copy_n(eps_MFront.data(), KelvinVector::SizeAtCompileTime,
365 behaviour_data.s1.gradients.data());
367 auto const& sigma_prev = std::get<MPL::SymmetricTensor<DisplacementDim>>(
368 variable_array_prev[
static_cast<int>(MPL::Variable::stress)]);
373 DisplacementDim)>() *
375 std::copy_n(sigma_prev_MFront.data(), KelvinVector::SizeAtCompileTime,
376 behaviour_data.s0.thermodynamic_forces.data());
377 std::copy_n(sigma_prev_MFront.data(), KelvinVector::SizeAtCompileTime,
378 behaviour_data.s1.thermodynamic_forces.data());
380 auto v = mgis::behaviour::make_view(behaviour_data);
381 auto const status = mgis::behaviour::integrate(v, _behaviour);
385 "MFront: integration failed with status" + std::to_string(status) +
390 std::copy_n(behaviour_data.s1.thermodynamic_forces.data(),
391 KelvinVector::SizeAtCompileTime, sigma.data());
399 if (behaviour_data.K.size() !=
400 KelvinMatrix::RowsAtCompileTime * KelvinMatrix::ColsAtCompileTime)
401 OGS_FATAL(
"Stiffness matrix has wrong size.");
404 Q *
MFrontToOGS(Eigen::Map<KelvinMatrix>(behaviour_data.K.data())) *
410 return std::make_optional(
415 std::move(sigma), std::move(state), std::move(C)));
418 template <
int DisplacementDim>
419 std::vector<typename MechanicsBase<DisplacementDim>::InternalVariable>
422 std::vector<typename MechanicsBase<DisplacementDim>::InternalVariable>
425 for (
auto const& iv : _behaviour.isvs)
427 auto const name = iv.name;
428 auto const offset = mgis::behaviour::getVariableOffset(
429 _behaviour.isvs,
name, _behaviour.hypothesis);
431 mgis::behaviour::getVariableSize(iv, _behaviour.hypothesis);
438 name,
static_cast<int>(size),
442 std::vector<double>& cache) -> std::vector<double>
const&
446 auto const& internal_state_variables =
448 ._behaviour_data.s1.internal_state_variables;
451 std::copy_n(internal_state_variables.data() + offset,
462 auto& internal_state_variables =
464 ._behaviour_data.s1.internal_state_variables;
466 return {internal_state_variables.data() + offset, size};
468 internal_variables.push_back(new_variable);
471 return internal_variables;
474 template <
int DisplacementDim>
483 "MFront::getBulkModulus() requires the tangent stiffness C input "
484 "argument to be valid.");
488 DisplacementDim)>::identity2;
489 return 1. / 9. * identity2.transpose() * *C * identity2;
492 template <
int DisplacementDim>
503 return std::numeric_limits<double>::quiet_NaN();
506 template <
int DisplacementDim>
508 DisplacementDim>::MaterialStateVariables::getEquivalentPlasticStrain()
const
510 if (equivalent_plastic_strain_offset_ >= 0)
512 return _behaviour_data.s1
513 .internal_state_variables[
static_cast<mgis::size_type
>(
514 equivalent_plastic_strain_offset_)];
void ERR(char const *fmt, Args const &... args)
mgis::behaviour::Behaviour _behaviour
std::vector< ParameterLib::Parameter< double > const * > _material_properties
MathLib::KelvinVector::KelvinVectorType< DisplacementDim > KelvinVector
MathLib::KelvinVector::KelvinMatrixType< DisplacementDim > KelvinMatrix
bool contains(Container const &container, typename Container::value_type const &element)
const char * btypeToString(int btype)
Converts MGIS behaviour type to a string representation.
const char * toString(mgis::behaviour::Behaviour::Kinematic kin)
Converts MGIS kinematic to a string representation.
const char * varTypeToString(int v)
Converts MGIS variable type to a string representation.
int getEquivalentPlasticStrainOffset(mgis::behaviour::Behaviour const &b)
std::array< VariableType, static_cast< int >(Variable::number_of_variables)> VariableArray
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
KelvinMatrixType< DisplacementDim > fourthOrderRotationMatrix(Eigen::Matrix< double, DisplacementDim, DisplacementDim, Eigen::ColMajor, DisplacementDim, DisplacementDim > const &transformation)
void copy(PETScVector const &x, PETScVector &y)
Derived::PlainObject OGSToMFront(Eigen::DenseBase< Derived > const &m)
Converts between OGSes and MFront's Kelvin vectors and matrices.
Derived::PlainObject MFrontToOGS(Eigen::DenseBase< Derived > const &m)
Converts between OGSes and MFront's Kelvin vectors and matrices.
Helper type for providing access to internal variables.
MathLib::KelvinVector::KelvinVectorType< DisplacementDim > KelvinVector
MathLib::KelvinVector::KelvinMatrixType< DisplacementDim > KelvinMatrix