https://gitlab.opengeosys.org/ogs/ogs.git
Raw File
Tip revision: a33aee383a0ed359a8484ceb35c448cbf6bbe487 authored by Dmitry Yu. Naumov on 30 January 2023, 20:11:52 UTC
Merge branch 'IwyuOnBaseLib' into 'master'
Tip revision: a33aee3
ShapeMatrixCache.h
/**
 * \file
 * \copyright
 * Copyright (c) 2012-2023, OpenGeoSys Community (http://www.opengeosys.org)
 *            Distributed under a Modified BSD License.
 *              See accompanying file LICENSE.txt or
 *              http://www.opengeosys.org/project/license
 *
 */

#pragma once

#include <boost/mp11.hpp>

#include "NumLib/Fem/FiniteElement/ElementTraitsLagrange.h"
#include "NumLib/Fem/ShapeMatrixPolicy.h"

namespace NumLib
{
namespace detail
{
template <typename ElementTraitsLagrange>
using GetMeshElement = typename ElementTraitsLagrange::Element;

template <typename ElementTraitsLagrange>
using GetShapeFunctionHigherOrder =
    typename ElementTraitsLagrange::ShapeFunction;

template <typename ElementTraitsLagrange>
using GetShapeFunctionLowerOrder =
    typename ElementTraitsLagrange::LowerOrderShapeFunction;

template <typename ShapeFunction>
using GetShapeMatrixPolicy =
    // dim does not matter, here, but
    // NumLib::detail::naturalCoordinatesMappingComputeShapeMatrices<>()
    // must be instantiated for this dim.
    ShapeMatrixPolicyType<ShapeFunction, 3 /* dim */>;

template <typename ShapeMatrixPolicy>
using GetShapeMatrix_N = typename ShapeMatrixPolicy::ShapeMatrices::ShapeType;
}  // namespace detail

class ShapeMatrixCache
{
    using ETLs = NumLib::AllElementTraitsLagrange;

    using MeshElements =
        boost::mp11::mp_transform<detail::GetMeshElement, ETLs>;

    // Higher order shape functions

    using ShapeFunctionsHigherOrder =
        boost::mp11::mp_transform<detail::GetShapeFunctionHigherOrder, ETLs>;
    using ShapeMatrixPoliciesHigherOrder =
        boost::mp11::mp_transform<detail::GetShapeMatrixPolicy,
                                  ShapeFunctionsHigherOrder>;
    using ShapeMatricesHigherOrder_N =
        boost::mp11::mp_transform<detail::GetShapeMatrix_N,
                                  ShapeMatrixPoliciesHigherOrder>;

    // std::tuple<std::vector<ShapeMatrix_N>, ...>
    using ShapeMatrixVectorsHigherOrder_N =
        boost::mp11::mp_transform<std::vector, ShapeMatricesHigherOrder_N>;

    static_assert(
        std::is_same_v<ShapeMatrixVectorsHigherOrder_N,
                       boost::mp11::mp_rename<ShapeMatrixVectorsHigherOrder_N,
                                              std::tuple>>,
        "The type alias ShapeMatrixVectorsHigherOrder_N must be a "
        "std::tuple<...>.");

    // Lower order shape functions

    using ShapeFunctionsLowerOrder =
        boost::mp11::mp_transform<detail::GetShapeFunctionLowerOrder, ETLs>;
    using ShapeMatrixPoliciesLowerOrder =
        boost::mp11::mp_transform<detail::GetShapeMatrixPolicy,
                                  ShapeFunctionsLowerOrder>;
    using ShapeMatricesLowerOrder_N =
        boost::mp11::mp_transform<detail::GetShapeMatrix_N,
                                  ShapeMatrixPoliciesLowerOrder>;

    // std::tuple<std::vector<ShapeMatrix_N>, ...>
    using ShapeMatrixVectorsLowerOrder_N =
        boost::mp11::mp_transform<std::vector, ShapeMatricesLowerOrder_N>;

    static_assert(
        std::is_same_v<
            ShapeMatrixVectorsLowerOrder_N,
            boost::mp11::mp_rename<ShapeMatrixVectorsLowerOrder_N, std::tuple>>,
        "The type alias ShapeMatrixVectorsLowerOrder_N must be a "
        "std::tuple<...>.");

public:
    explicit ShapeMatrixCache(unsigned const integration_order);

    template <typename MeshElement>
    auto const& NsHigherOrder() const
    {
        using Index = boost::mp11::mp_find<MeshElements, MeshElement>;
        return std::get<Index::value>(Nss_higher_order_);
    }

    template <typename MeshElement>
    auto const& NsLowerOrder() const
    {
        using Index = boost::mp11::mp_find<MeshElements, MeshElement>;
        return std::get<Index::value>(Nss_lower_order_);
    }

    /// Returns the number of elements in the ShapeMatrixVectorsHigherOrder_N
    /// tuple.
    static constexpr std::size_t size()
    {
        return boost::mp11::mp_size<ETLs>::value;
    }

    template <typename MeshElement>
    using ShapeFunctionHigherOrder =
        boost::mp11::mp_at<ShapeFunctionsHigherOrder,
                           boost::mp11::mp_find<MeshElements, MeshElement>>;

    template <typename MeshElement>
    using ShapeFunctionLowerOrder =
        boost::mp11::mp_at<ShapeFunctionsLowerOrder,
                           boost::mp11::mp_find<MeshElements, MeshElement>>;

private:
    ShapeMatrixVectorsHigherOrder_N Nss_higher_order_;
    ShapeMatrixVectorsLowerOrder_N Nss_lower_order_;
};
}  // namespace NumLib
back to top