Skip to content

Commit

Permalink
Merge branch 'IndependentTangentOperatorBlock' into 'master'
Browse files Browse the repository at this point in the history
MFrontGeneric: Extract Forces/Grads product

See merge request ogs/ogs!4717
  • Loading branch information
endJunction committed Sep 14, 2023
2 parents 17aa044 + 03b4e85 commit e0317d3
Show file tree
Hide file tree
Showing 9 changed files with 171 additions and 70 deletions.
15 changes: 8 additions & 7 deletions MaterialLib/SolidModels/MFront/MFront.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ template <int DisplacementDim>
class MFront : private MFrontGeneric<DisplacementDim,
boost::mp11::mp_list<Strain>,
boost::mp11::mp_list<Stress>,
boost::mp11::mp_list<>>,
boost::mp11::mp_list<Temperature>>,
public MechanicsBase<DisplacementDim>
{
using Base = MFrontGeneric<DisplacementDim,
boost::mp11::mp_list<Strain>,
boost::mp11::mp_list<Stress>,
boost::mp11::mp_list<>>;
boost::mp11::mp_list<Temperature>>;
using KelvinVector = typename Base::KelvinVector;
using KelvinMatrix = typename Base::KelvinMatrix;

Expand Down Expand Up @@ -118,11 +118,12 @@ class MFront : private MFrontGeneric<DisplacementDim,
}

private:
OGSMFrontTangentOperatorBlocksView<DisplacementDim,
boost::mp11::mp_list<Strain>,
boost::mp11::mp_list<Stress>,
boost::mp11::mp_list<>>
blocks_view_{this->createTangentOperatorBlocksView()};
OGSMFrontTangentOperatorBlocksView<
DisplacementDim,
ForcesGradsCombinations<boost::mp11::mp_list<Strain>,
boost::mp11::mp_list<Stress>,
boost::mp11::mp_list<Temperature>>::type>
blocks_view_ = this->createTangentOperatorBlocksView();
};

extern template class MFront<2>;
Expand Down
17 changes: 10 additions & 7 deletions MaterialLib/SolidModels/MFront/MFrontGeneric.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "ParameterLib/Parameter.h"
#include "TangentOperatorBlocksView.h"
#include "ThermodynamicForcesView.h"
#include "Variable.h"

namespace MaterialLib::Solids::MFront
{
Expand Down Expand Up @@ -302,6 +303,10 @@ class MFrontGeneric

auto const hypothesis = _behaviour.hypothesis;

static_assert(
std::is_same_v<ExtStateVars, boost::mp11::mp_list<Temperature>>,
"Temperature is the only allowed external state variable.");

if (!_behaviour.esvs.empty())
{
if (_behaviour.esvs[0].name != "Temperature")
Expand Down Expand Up @@ -596,16 +601,14 @@ class MFrontGeneric
return internal_variables;
}

OGSMFrontTangentOperatorBlocksView<DisplacementDim,
Gradients,
TDynForces,
ExtStateVars>
template <typename ForcesGradsCombinations =
typename ForcesGradsCombinations<Gradients, TDynForces,
ExtStateVars>::type>
OGSMFrontTangentOperatorBlocksView<DisplacementDim, ForcesGradsCombinations>
createTangentOperatorBlocksView() const
{
return OGSMFrontTangentOperatorBlocksView<DisplacementDim,
Gradients,
TDynForces,
ExtStateVars>{
ForcesGradsCombinations>{
_behaviour.to_blocks};
}

Expand Down
95 changes: 68 additions & 27 deletions MaterialLib/SolidModels/MFront/TangentOperatorBlocksView.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@

#include <MGIS/Behaviour/Variable.hxx>
#include <boost/mp11.hpp>
#include <range/v3/view/enumerate.hpp>
#include <range/v3/view/filter.hpp>
#include <range/v3/view/map.hpp>
#include <range/v3/view/zip.hpp>

#include "BaseLib/cpp23.h"
#include "MathLib/KelvinVector.h"
Expand All @@ -34,10 +38,10 @@ struct OGSMFrontTangentOperatorData
};

/**
* Provides convenient access to the individual blocks of MFront's tangent
* operator data.
* A list of MFront's tangent operator blocks. The list consists of pairs of
* types, first a thermodynamic force, and second a gradient or external state
* variable.
*
* \tparam DisplacementDim the displacement dimension
* \tparam Gradients a list (of types) of gradients driving the MFront behaviour
* \tparam TDynForces a list (of types) of thermodynamic forces
* \tparam ExtStateVars a list (of types) of external state variables
Expand All @@ -54,15 +58,9 @@ struct OGSMFrontTangentOperatorData
* these lists is expected to behave like Strain and the other classes in
* Variable.h.
*
* MFront's tangent operator blocks are stored in a single vector of double
* values. The implementer of an MFront behaviour can decide which blocks she
* wants to provide and in which order.
*/
template <int DisplacementDim,
typename Gradients,
typename TDynForces,
typename ExtStateVars>
class OGSMFrontTangentOperatorBlocksView
template <typename Gradients, typename TDynForces, typename ExtStateVars>
struct ForcesGradsCombinations
{
static_assert(boost::mp11::mp_is_set<Gradients>::value);
static_assert(boost::mp11::mp_is_set<TDynForces>::value);
Expand All @@ -73,8 +71,27 @@ class OGSMFrontTangentOperatorBlocksView

static_assert(boost::mp11::mp_is_set<GradientsAndExtStateVars>::value);

using ForcesGradsCombinations = boost::mp11::
using type = boost::mp11::
mp_product<boost::mp11::mp_list, TDynForces, GradientsAndExtStateVars>;
};

/**
* Provides convenient access to the individual blocks of MFront's tangent
* operator data.
*
* \tparam DisplacementDim the displacement dimension
* \tparam ForcesGradsCombinations a list of pairs types corresponding to the
* tangent operator blocks' variables. See ForcesGradsCombinations template for
* details.
*
* MFront's tangent operator blocks are stored in a single vector of double
* values. The implementer of an MFront behaviour can decide which blocks she
* wants to provide and in which order.
*/
template <int DisplacementDim, typename ForcesGradsCombinations>
class OGSMFrontTangentOperatorBlocksView
{
static_assert(boost::mp11::mp_is_set<ForcesGradsCombinations>::value);

/// Indicates that the associated tangent operator block is not present in
/// the data.
Expand All @@ -89,25 +106,52 @@ class OGSMFrontTangentOperatorBlocksView
{
offsets_.fill(invalid_offset_);

std::vector<bool> used_blocks(
to_blocks.size(), false); // checked after creation of all offsets.

boost::mp11::mp_for_each<ForcesGradsCombinations>(
[&to_blocks, this]<typename Force, typename GradOrExtStateVar>(
[&to_blocks,
&used_blocks,
this]<typename Force, typename GradOrExtStateVar>(
boost::mp11::mp_list<Force, GradOrExtStateVar>)
{
std::size_t data_offset = 0;
for (auto const& [force, grad] : to_blocks)
for (auto [block, is_used] :
ranges::views::zip(to_blocks, used_blocks))
{
auto const& [force, grad] = block;
if (force.name == Force::name &&
grad.name == GradOrExtStateVar::name)
{
auto const block_idx =
auto constexpr block_idx =
blockIndex<Force, GradOrExtStateVar>();
offsets_[block_idx] = data_offset;
is_used = true;
return;
}

data_offset += size(force.type) * size(grad.type);
}
});

// Indices of unused blocks.
auto indices = ranges::views::enumerate(used_blocks) |
ranges::views::filter([](auto const& pair)
{ return !pair.second; }) |
ranges::views::keys;

if (!indices.empty())
{
ERR("There are unused tangent operator blocks provided by MFront. "
"Following blocks are unused:");

for (auto const i : indices)
{
auto const& [force, grad] = to_blocks[i];
ERR("\t{}/{}", force.name, grad.name);
}
OGS_FATAL("All tangent operator blocks must be used.");
}
}

/// Read access to the block dForce/dGradOrExtStateVar.
Expand All @@ -121,9 +165,12 @@ class OGSMFrontTangentOperatorBlocksView
GradOrExtStateVar,
OGSMFrontTangentOperatorData const& data) const
{
static_assert(boost::mp11::mp_contains<TDynForces, Force>::value);
static_assert(boost::mp11::mp_contains<GradientsAndExtStateVars,
GradOrExtStateVar>::value);
static_assert(
boost::mp11::mp_contains<
ForcesGradsCombinations,
boost::mp11::mp_list<Force, GradOrExtStateVar>>::value,
"Requested tangent block was not created in the "
"OGSMFrontTangentOperatorBlocksView.");

constexpr auto index = blockIndex<Force, GradOrExtStateVar>();
const auto offset = offsets_[index];
Expand Down Expand Up @@ -184,15 +231,9 @@ class OGSMFrontTangentOperatorBlocksView
template <typename Force, typename GradOrExtStateVar>
static constexpr std::size_t blockIndex()
{
constexpr auto force_idx =
boost::mp11::mp_find<TDynForces, Force>::value;
constexpr auto grad_idx =
boost::mp11::mp_find<GradientsAndExtStateVars,
GradOrExtStateVar>::value;
constexpr auto stride =
boost::mp11::mp_size<GradientsAndExtStateVars>::value;

return force_idx * stride + grad_idx;
return boost::mp11::mp_find<
ForcesGradsCombinations,
boost::mp11::mp_list<Force, GradOrExtStateVar>>::value;
}

/// Stores the data offsets of each tangent operator block.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ struct ElasticTangentStiffnessModel
SolidConstitutiveRelation<DisplacementDim> const& solid_material)
: solid_material_(solid_material),
tangent_operator_blocks_view_{
solid_material.createTangentOperatorBlocksView()}
solid_material.template createTangentOperatorBlocksView()}
{
}

Expand All @@ -38,9 +38,10 @@ struct ElasticTangentStiffnessModel

MSM::OGSMFrontTangentOperatorBlocksView<
DisplacementDim,
boost::mp11::mp_list<MSM::Strain, MSM::LiquidPressure>,
boost::mp11::mp_list<MSM::Stress, MSM::Saturation>,
boost::mp11::mp_list<MSM::Temperature>>
MSM::ForcesGradsCombinations<
boost::mp11::mp_list<MSM::Strain, MSM::LiquidPressure>,
boost::mp11::mp_list<MSM::Stress, MSM::Saturation>,
boost::mp11::mp_list<MSM::Temperature>>::type>
tangent_operator_blocks_view_;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ struct SolidMechanicsModel
SolidConstitutiveRelation<DisplacementDim> const& solid_material)
: solid_material_(solid_material),
tangent_operator_blocks_view_{
solid_material.createTangentOperatorBlocksView()}
solid_material.template createTangentOperatorBlocksView()}
{
}

Expand All @@ -68,9 +68,11 @@ struct SolidMechanicsModel
SolidConstitutiveRelation<DisplacementDim> const& solid_material_;

MSM::OGSMFrontTangentOperatorBlocksView<
DisplacementDim, boost::mp11::mp_list<MSM::Strain, MSM::LiquidPressure>,
boost::mp11::mp_list<MSM::Stress, MSM::Saturation>,
boost::mp11::mp_list<MSM::Temperature>>
DisplacementDim,
MSM::ForcesGradsCombinations<
boost::mp11::mp_list<MSM::Strain, MSM::LiquidPressure>,
boost::mp11::mp_list<MSM::Stress, MSM::Saturation>,
boost::mp11::mp_list<MSM::Temperature>>::type>
tangent_operator_blocks_view_;
};

Expand Down
4 changes: 2 additions & 2 deletions Tests/MaterialLib/CheckParamPassingMFront.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ auto createMFront(
return MSM::createMFrontGeneric<
3, boost::mp11::mp_list<MSM::Strain, MSM::LiquidPressure>,
boost::mp11::mp_list<MSM::Stress, MSM::Saturation>,
boost::mp11::mp_list<>>(parameters, local_coordinate_system,
config_tree, false);
boost::mp11::mp_list<MSM::Temperature>>(
parameters, local_coordinate_system, config_tree, false);
}

TEST(MaterialLib_CheckParamPassingMFront, SuccessTest)
Expand Down
12 changes: 3 additions & 9 deletions Tests/MaterialLib/CheckStiffnessMatrixMFront.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#include "MaterialLib/SolidModels/MFront/Variable.h"
#include "Tests/TestTools.h"

namespace MSM = MaterialLib::Solids::MFront;

template <typename ExtStateVars>
auto createMFront(std::string const& behaviour)
{
Expand All @@ -36,8 +38,6 @@ auto createMFront(std::string const& behaviour)
&BaseLib::ConfigTree::onerror,
&BaseLib::ConfigTree::onwarning);

namespace MSM = MaterialLib::Solids::MFront;

return MSM::createMFrontGeneric<
3, boost::mp11::mp_list<MSM::Strain, MSM::LiquidPressure>,
boost::mp11::mp_list<MSM::Stress, MSM::Saturation>, ExtStateVars>(
Expand Down Expand Up @@ -81,7 +81,7 @@ struct TestDataBase
class MaterialLib_CheckStiffnessMatrixMFront : public ::testing::Test
{
protected:
template <typename ExtStateVars = boost::mp11::mp_list<>>
template <typename ExtStateVars = boost::mp11::mp_list<MSM::Temperature>>
void run(std::string const& behaviour, TestDataBase const& data) const
{
run<ExtStateVars>(behaviour, data,
Expand All @@ -92,8 +92,6 @@ class MaterialLib_CheckStiffnessMatrixMFront : public ::testing::Test
void run(std::string const& behaviour, TestDataBase const& data,
AdditionalChecks&& checks) const
{
namespace MSM = MaterialLib::Solids::MFront;

// Create MFront behaviour
// /////////////////////////////////////////////////

Expand Down Expand Up @@ -173,8 +171,6 @@ class MaterialLib_CheckStiffnessMatrixMFront : public ::testing::Test
{2301, 2302, 2303, 2304, 2305, 2306}));
EXPECT_DOUBLE_EQ(2307, S_L);

namespace MSM = MaterialLib::Solids::MFront;

auto const blocks_view =
mfront_model->createTangentOperatorBlocksView();

Expand Down Expand Up @@ -238,8 +234,6 @@ TEST_F(MaterialLib_CheckStiffnessMatrixMFront, SomeBlocksMissing)

TEST_F(MaterialLib_CheckStiffnessMatrixMFront, DSigmaDTBlock)
{
namespace MSM = MaterialLib::Solids::MFront;

run<boost::mp11::mp_list<MSM::Temperature>>(
"CheckStiffnessMatrixExcessBlocks", TestDataBase{},
[](auto const& blocks_view, auto const& tangent_operator_data)
Expand Down
Loading

0 comments on commit e0317d3

Please sign in to comment.