Skip to content

Commit

Permalink
Rework canProvideResultType() (#312)
Browse files Browse the repository at this point in the history
  • Loading branch information
henrij22 authored Jul 25, 2024
1 parent 5f6f492 commit 90adeac
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 47 deletions.
30 changes: 30 additions & 0 deletions ikarus/finiteelements/feresulttypes.hh
Original file line number Diff line number Diff line change
Expand Up @@ -252,4 +252,34 @@ auto toString() {
template <template <typename, int, int> class RT1, template <typename, int, int> class RT2>
constexpr bool isSameResultType = std::is_same_v<Impl::DummyRT<RT1>, Impl::DummyRT<RT2>>;

namespace Impl {
template <typename T, typename Tuple>
struct hasType;

template <typename T, typename... Us>
struct hasType<T, std::tuple<Us...>> : std::disjunction<std::is_same<T, Us>...>
{
};
} // namespace Impl

/**
* \brief Base class for element definitions that provides common functionality for ResultTypes
*
* \tparam ResultTypes supported ResultTypes
*/
template <template <typename, int, int> typename... ResultTypes>
struct ResultTypeBase
{
/**
* \brief Returns whether a ResultType is provided by the element
* \tparam RT requested ResultType
*/
template <template <typename, int, int> typename RT>
static consteval bool supportsResultType() {
return Impl::hasType<decltype(makeRT<RT>()), SupportedResultTypes>::value;
}

using SupportedResultTypes = std::tuple<decltype(makeRT<ResultTypes>())...>;
};

} // namespace Ikarus
2 changes: 0 additions & 2 deletions ikarus/finiteelements/mechanics/enhancedassumedstrains.hh
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,6 @@ public:
using GridView = typename Traits::GridView;
using Pre = EnhancedAssumedStrainsPre;

using SupportedResultTypes = std::tuple<decltype(makeRT<ResultTypes::linearStress>())>;

/**
* \brief Constructor for Enhanced Assumed Strains elements.
* \param pre The pre finite element
Expand Down
17 changes: 3 additions & 14 deletions ikarus/finiteelements/mechanics/kirchhoffloveshell.hh
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include <ikarus/finiteelements/fehelper.hh>
#include <ikarus/finiteelements/ferequirements.hh>
#include <ikarus/finiteelements/feresulttypes.hh>
#include <ikarus/finiteelements/mechanics/loads.hh>
#include <ikarus/finiteelements/mechanics/membranestrains.hh>
#include <ikarus/finiteelements/physicshelper.hh>
Expand Down Expand Up @@ -46,7 +47,7 @@ struct KirchhoffLoveShellPre
* \tparam FE Type of the finite element.
*/
template <typename PreFE, typename FE>
class KirchhoffLoveShell
class KirchhoffLoveShell : public ResultTypeBase<>
{
public:
using Traits = PreFE::Traits;
Expand Down Expand Up @@ -152,18 +153,6 @@ public:
[[nodiscard]] size_t numberOfNodes() const { return numberOfNodes_; }
[[nodiscard]] int order() const { return order_; }

/**
* \brief Returns whether an element can provide a requested result. Can be used in constant expressions
* \tparam RT The type representing the requested result.
* \return boolean indicating if a requested result can be provided
*/
template <template <typename, int, int> class RT>
static consteval bool canProvideResultType() {
return false;
}

using SupportedResultTypes = std::tuple<>;

/**
* \brief Calculates a requested result at a specific local position.
*
Expand All @@ -174,7 +163,7 @@ public:
* \tparam RT The type representing the requested result.
*/
template <template <typename, int, int> class RT>
requires(canProvideResultType<RT>())
requires(supportsResultType<RT>())
auto calculateAtImpl([[maybe_unused]] const Requirement& req,
[[maybe_unused]] const Dune::FieldVector<double, Traits::mydim>& local)
-> ResultWrapper<RT<double, myDim, worldDim>, ResultShape::Vector> {
Expand Down
12 changes: 3 additions & 9 deletions ikarus/finiteelements/mechanics/linearelastic.hh
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include <ikarus/finiteelements/fehelper.hh>
#include <ikarus/finiteelements/ferequirements.hh>
#include <ikarus/finiteelements/feresulttypes.hh>
#include <ikarus/finiteelements/mechanics/materials.hh>
#include <ikarus/finiteelements/physicshelper.hh>

Expand Down Expand Up @@ -48,7 +49,7 @@ struct LinearElasticPre
* \tparam FE The type of the finite element.
*/
template <typename PreFE, typename FE>
class LinearElastic
class LinearElastic : public ResultTypeBase<ResultTypes::linearStress>
{
public:
using Traits = PreFE::Traits;
Expand Down Expand Up @@ -154,13 +155,6 @@ public:
[[nodiscard]] size_t numberOfNodes() const { return numberOfNodes_; }
[[nodiscard]] int order() const { return order_; }

using SupportedResultTypes = std::tuple<decltype(makeRT<ResultTypes::linearStress>())>;

template <template <typename, int, int> class RT>
static consteval bool canProvideResultType() {
return isSameResultType<RT, ResultTypes::linearStress>;
}

public:
/**
* \brief Calculates a requested result at a specific local position.
Expand All @@ -173,7 +167,7 @@ public:
* \tparam RT The type representing the requested result.
*/
template <template <typename, int, int> class RT>
requires(canProvideResultType<RT>())
requires(supportsResultType<RT>())
auto calculateAtImpl(const Requirement& req, const Dune::FieldVector<double, Traits::mydim>& local,
Dune::PriorityTag<1>) const {
using RTWrapper = ResultWrapper<RT<typename Traits::ctype, myDim, Traits::worlddim>, ResultShape::Vector>;
Expand Down
12 changes: 2 additions & 10 deletions ikarus/finiteelements/mechanics/nonlinearelastic.hh
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ struct NonLinearElasticPre
* \tparam PRE The type of the non-linear elastic pre finite element.
*/
template <typename PreFE, typename FE, typename PRE>
class NonLinearElastic
class NonLinearElastic : public ResultTypeBase<ResultTypes::PK2Stress>
{
public:
using Traits = PreFE::Traits;
Expand Down Expand Up @@ -201,14 +201,6 @@ public:
[[nodiscard]] size_t numberOfNodes() const { return numberOfNodes_; }
[[nodiscard]] int order() const { return order_; }

using SupportedResultTypes = std::tuple<decltype(makeRT<ResultTypes::PK2Stress>())>;

private:
template <template <typename, int, int> class RT>
static consteval bool canProvideResultType() {
return isSameResultType<RT, ResultTypes::PK2Stress>;
}

public:
/**
* \brief Calculates a requested result at a specific local position.
Expand All @@ -220,7 +212,7 @@ public:
* \tparam RT The type representing the requested result.
*/
template <template <typename, int, int> class RT>
requires(canProvideResultType<RT>())
requires(supportsResultType<RT>())
auto calculateAtImpl(const Requirement& req, const Dune::FieldVector<double, Traits::mydim>& local,
Dune::PriorityTag<1>) const {
using namespace Dune::DerivativeDirections;
Expand Down
14 changes: 2 additions & 12 deletions ikarus/finiteelements/mechanics/truss.hh
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ struct TrussPre
*/
template <typename PreFE, typename FE>
class Truss
: public ResultTypeBase<ResultTypes::cauchyAxialForce, ResultTypes::PK2AxialForce, ResultTypes::linearAxialForce>
{
public:
using Traits = PreFE::Traits;
Expand Down Expand Up @@ -156,17 +157,6 @@ public:
return kin;
}

using SupportedResultTypes =
std::tuple<decltype(makeRT<ResultTypes::cauchyAxialForce>()), decltype(makeRT<ResultTypes::PK2AxialForce>()),
decltype(makeRT<ResultTypes::linearAxialForce>())>;

private:
template <template <typename, int, int> class RT>
static consteval bool canProvideResultType() {
return isSameResultType<RT, ResultTypes::cauchyAxialForce> or isSameResultType<RT, ResultTypes::PK2AxialForce> or
isSameResultType<RT, ResultTypes::linearAxialForce>;
}

public:
/**
* \brief Calculates a requested result at a specific local position.
Expand All @@ -179,7 +169,7 @@ public:
* \tparam RT The type representing the requested result.
*/
template <template <typename, int, int> class RT>
requires(canProvideResultType<RT>())
requires(supportsResultType<RT>())
auto calculateAtImpl(const Requirement& req, [[maybe_unused]] const Dune::FieldVector<double, Traits::mydim>& local,
Dune::PriorityTag<0>) const {
using RTWrapper = ResultWrapper<RT<double, myDim, myDim>, ResultShape::Vector>;
Expand Down
9 changes: 9 additions & 0 deletions tests/src/testfeelement.hh
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <dune/fufem/boundarypatch.hh>

#include <ikarus/assembler/simpleassemblers.hh>
#include "ikarus/finiteelements/feresulttypes.hh"
#include <ikarus/finiteelements/fefactory.hh>
#include <ikarus/finiteelements/ferequirements.hh>
#include <ikarus/finiteelements/mechanics/loads.hh>
Expand Down Expand Up @@ -107,6 +108,14 @@ auto testFEElement(const PreBasis& preBasis, const std::string& elementName, con
<< "The element is \n"
<< Dune::className<FEType>();

t.check(FEType::template supportsResultType<ResultTypes::linearStress>() == true)
<< "Element should support result type LinearStress, but doesn't"
<< "\nThe supported types are " << Dune::className<typename FEType::SupportedResultTypes>() << "\n";

t.check(FEType::template supportsResultType<ResultTypes::PK2Stress>() == false)
<< "Element should not support result type PK2Stress, but does"
<< "\nThe supported types are " << Dune::className<typename FEType::SupportedResultTypes>() << "\n";

sparseAssembler->bind(requirements, Ikarus::AffordanceCollections::elastoStatics);
auto nonLinOp = Ikarus::NonLinearOperatorFactory::op(sparseAssembler);

Expand Down

0 comments on commit 90adeac

Please sign in to comment.