Skip to content

Convenient block access to MFront's thermodynamic forces data

Christoph Lehmann requested to merge chleh/ogs:mfront-tdyn-forces-view into master
  1. Feature description was added to the changelog
  2. Tests covering your feature were added?
  3. Any new feature or behavior change was documented?

MFront/MGIS returns its material behaviour data as a std::vector of double values, i.e., flattened and all physical quantities are put next to each other.

This MR adds a view for accessing individual physical quantities (blocks) in this data. The view can be used as follows (see also the unit tests):

    namespace MSM = MaterialLib::Solids::MFront;

    using TDynForces = boost::mp11::mp_list<MSM::Stress, MSM::Saturation>;

    MSM::OGSMFrontThermodynamicForcesData const data{{
        1, 2, 3, 4, 5, 6,  // stress
        7                  // saturation
    }};

    MSM::OGSMFrontThermodynamicForcesView<3, TDynForces> view;

    auto const stress = view.block(MSM::stress, data);          // access the stress block
    auto const saturation = view.block(MSM::saturation, data);  // access the saturation block

This view mechanism will be used by the extended OGS-MFront interface. There the views will be created by the MFront material model. And the user won't need to care about the order and offsets of the different blocks.

In an upcoming MR I'll introduce another view for MFront's tangent operator data.

Similar views might also be nice in the local assemblers for expressions such as

local_Jac
            .template block<displacement_size, displacement_size>(
                displacement_index, displacement_index)
            .noalias() += ...

New dependency

This MR adds boost::mp11 as a new dependency. That library provides many convenient features for template metaprogramming. My plan is to drop BaseLib/TMP.h in favour of it in the future.

This MR contains a bit of template metaprogramming code, but thanks to boost::mp11 I think it's quite readable. E.g. from dataOffset():

        using ForceIndex = mp_find<TDynForces, Force>;

        using ForcesHead = mp_take<TDynForces, ForceIndex>;

        using Sizes = mp_transform<SizeOf, ForcesHead>;

        return mp_apply<mp_plus, Sizes>::value;

Other additions

This MR also adds a googletest predicate that compares two Eigen matrices. It can be used as follows:

    auto const tensor = view.block(Tensor{}, data);
    auto const tensor_expected = (Eigen::Matrix2d{} << 3, 4, 5, 6).finished();

    ASSERT_PRED_FORMAT2(Tests::EigenIsNear{}, tensor, tensor_expected);
Edited by Christoph Lehmann

Merge request reports