[properties] continue with splice mechanism

This commit is contained in:
Bernd Flemisch 2020-03-13 11:25:43 +01:00
parent 2ffc13e9c3
commit 4f890ed379
4 changed files with 70 additions and 95 deletions

View File

@ -50,6 +50,11 @@ class MultiPhaseBaseModel;
BEGIN_PROPERTIES
namespace TTag {
struct ParallelBiCGStabLinearSolver;
struct FiniteDifferenceLocalLinearizer;
}
//! The generic type tag for problems using the immiscible multi-phase model
NEW_TYPE_TAG(MultiPhaseBaseModel, INHERITS_FROM(NumericModel, VtkMultiPhase, VtkTemperature));
@ -59,7 +64,7 @@ NEW_TYPE_TAG(MultiPhaseBaseModel, INHERITS_FROM(NumericModel, VtkMultiPhase, Vtk
template<class TypeTag>
struct Splices<TypeTag, TTag::MultiPhaseBaseModel>
{
using tuple = std::tuple<GetPropType<TypeTag, Properties::SpatialDiscretizationSplice>>;
using type = std::tuple<GetSplicePropType<TypeTag, Properties::SpatialDiscretizationSplice>>;
};
//! Set the default spatial discretization

View File

@ -51,6 +51,14 @@ NEW_TYPE_TAG(FvBaseDiscretization,
//SET_SPLICES(FvBaseDiscretization, LinearSolverSplice, LocalLinearizerSplice);
template<class TypeTag>
struct Splices<TypeTag, TTag::FvBaseDiscretization>
{
// using type = std::tuple<GetSplicePropType<TypeTag, Properties::LinearSolverSplice>,
// GetSplicePropType<TypeTag, Properties::LocalLinearizerSplice>>;
using type = std::tuple<TTag::ParallelBiCGStabLinearSolver,
TTag::FiniteDifferenceLocalLinearizer>;
};
//! use a parallel BiCGStab linear solver by default
SET_TAG_PROP(FvBaseDiscretization, LinearSolverSplice, ParallelBiCGStabLinearSolver);

View File

@ -100,7 +100,7 @@ NEW_PROP_TAG(ThreadManager);
NEW_PROP_TAG(NewtonMethod);
NEW_PROP_TAG(SolutionVector);
NEW_PROP_TAG(GlobalEqVector);
//NEW_PROP_TAG(VtkOutputFormat);
NEW_PROP_TAG(VtkOutputFormat);
//! Specifies the type of a solution for a single degee of freedom
NEW_PROP_TAG(PrimaryVariables);
@ -318,6 +318,7 @@ NEW_PROP_TAG(LinearSolverMaxError);
NEW_PROP_TAG(LinearSolverSplice);
NEW_PROP_TAG(LocalLinearizerSplice);
NEW_PROP_TAG(SpatialDiscretizationSplice);
//! The discretization specific part of he implementing the Newton algorithm
NEW_PROP_TAG(DiscNewtonMethod);

View File

@ -39,7 +39,7 @@ struct UndefinedProperty {};
template <class TypeTag, class MyTypeTag>
struct Splices
{
using tuple = std::tuple<>;
using type = std::tuple<>;
};
@ -133,124 +133,82 @@ struct GetDefined<TypeTag, Property, std::tuple<FirstTypeTag, Args...>>
};
//! helper struct to get the first property that is defined in the TypeTag hierarchy
template<class TypeTag, class TTagList>
struct GetDefinedSplice;
//! helper struct to iterate over the TypeTag hierarchy
template<class TypeTag, class TTagList, class Enable>
struct GetNextSpliceTypeTag;
template<class TypeTag, class LastTypeTag>
struct GetNextSpliceTypeTag<TypeTag, std::tuple<LastTypeTag>, std::enable_if_t<hasParentTypeTag<LastTypeTag>(int{}), void>>
{ using type = typename GetDefinedSplice<TypeTag, typename LastTypeTag::InheritsFrom>::type; };
template<class TypeTag, class LastTypeTag>
struct GetNextSpliceTypeTag<TypeTag, std::tuple<LastTypeTag>, std::enable_if_t<!hasParentTypeTag<LastTypeTag>(int{}), void>>
{ using type = std::tuple<>; };
template<class TypeTag, class FirstTypeTag, class ...Args>
struct GetNextSpliceTypeTag<TypeTag, std::tuple<FirstTypeTag, Args...>, std::enable_if_t<hasParentTypeTag<FirstTypeTag>(int{}), void>>
{ using type = typename GetDefinedSplice<TypeTag, ConCatTuples<typename FirstTypeTag::InheritsFrom, std::tuple<Args...>>>::type; };
template<class TypeTag, class FirstTypeTag, class ...Args>
struct GetNextSpliceTypeTag<TypeTag, std::tuple<FirstTypeTag, Args...>, std::enable_if_t<!hasParentTypeTag<FirstTypeTag>(int{}), void>>
{ using type = typename GetDefinedSplice<TypeTag, std::tuple<Args...>>::type; };
//! check if a splice S is defined
template<class S>
constexpr auto isDefinedSplice(int)
-> decltype(std::integral_constant<bool, !std::is_same<typename S::tuple, std::tuple<>>::value>{})
-> decltype(std::integral_constant<bool, !std::is_same<typename S::type, std::tuple<>>::value>{})
{ return {}; }
//! fall back if a splice is defined
template<class S>
constexpr std::true_type isDefinedSplice(...) { return {}; }
template<class TypeTag, class TTagList>
struct GetSplicesTypeTags;
template<class TypeTag, class TTagList, class Enable>
struct GetNextSplicesTypeTag;
template<class TypeTag, class LastTypeTag>
struct GetNextSplicesTypeTag<TypeTag, std::tuple<LastTypeTag>, std::enable_if_t<hasParentTypeTag<LastTypeTag>(int{}), void>>
{ using tuple = typename GetSplicesTypeTags<TypeTag, typename LastTypeTag::InheritsFrom>::tuple; };
template<class TypeTag, class LastTypeTag>
struct GetNextSplicesTypeTag<TypeTag, std::tuple<LastTypeTag>, std::enable_if_t<!hasParentTypeTag<LastTypeTag>(int{}), void>>
{ using tuple = std::tuple<>; };
template<class TypeTag, class FirstTypeTag, class ...Args>
struct GetNextSplicesTypeTag<TypeTag, std::tuple<FirstTypeTag, Args...>, std::enable_if_t<hasParentTypeTag<FirstTypeTag>(int{}), void>>
{ using tuple = typename GetSplicesTypeTags<TypeTag, ConCatTuples<typename FirstTypeTag::InheritsFrom, std::tuple<Args...>>>::tuple; };
template<class TypeTag, class FirstTypeTag, class ...Args>
struct GetNextSplicesTypeTag<TypeTag, std::tuple<FirstTypeTag, Args...>, std::enable_if_t<!hasParentTypeTag<FirstTypeTag>(int{}), void>>
{ using tuple = typename GetSplicesTypeTags<TypeTag, std::tuple<Args...>>::tuple; };
template<class TypeTag, class LastTypeTag>
struct GetSplicesTypeTags<TypeTag, std::tuple<LastTypeTag>>
struct GetDefinedSplice<TypeTag, std::tuple<LastTypeTag>>
{
using LastSplices = Splices<TypeTag, LastTypeTag>;
using nexttuple = typename GetNextSplicesTypeTag<TypeTag, std::tuple<LastTypeTag>, void>::tuple;
// originally intended
// using tuple = std::conditional_t<isDefinedSplice<LastSplices>(int{}),
// typename ConCatTuples<nexttuple, typename LastSplices::tuple>::tuple,
// nexttuple>;
using tuple = std::conditional_t<isDefinedSplice<LastSplices>(int{}),
typename LastSplices::tuple,
typename GetNextSplicesTypeTag<TypeTag, std::tuple<LastTypeTag>, void>::tuple>;
using LastSplice = Splices<TypeTag, LastTypeTag>;
using nexttuple = typename GetNextSpliceTypeTag<TypeTag, std::tuple<LastTypeTag>, void>::type;
using type = std::conditional_t<isDefinedSplice<LastSplice>(int{}),
ConCatTuples<nexttuple, typename LastSplice::type>,
nexttuple>;
};
template<class TypeTag, class FirstTypeTag, class ...Args>
struct GetSplicesTypeTags<TypeTag, std::tuple<FirstTypeTag, Args...>>
struct GetDefinedSplice<TypeTag, std::tuple<FirstTypeTag, Args...>>
{
using FirstSplices = Splices<TypeTag, FirstTypeTag>;
using nexttuple = typename GetNextSplicesTypeTag<TypeTag, std::tuple<FirstTypeTag, Args...>, void>::tuple;
// originally intended
// using tuple = std::conditional_t<isDefinedSplice<FirstSplices>(int{}),
// typename ConCatTuples<typename FirstSplices::tuple, nexttuple>::tuple,
// nexttuple>;
using tuple = std::conditional_t<isDefinedSplice<FirstSplices>(int{}),
typename FirstSplices::tuple,
typename GetNextSplicesTypeTag<TypeTag, std::tuple<FirstTypeTag, Args...>, void>::tuple>;
using FirstSplice = Splices<TypeTag, FirstTypeTag>;
using nexttuple = typename GetNextSpliceTypeTag<TypeTag, std::tuple<FirstTypeTag, Args...>, void>::type;
using type = std::conditional_t<isDefinedSplice<FirstSplice>(int{}),
ConCatTuples<typename FirstSplice::type, nexttuple>,
nexttuple>;
};
} // end namespace Detail
template<class TypeTag, class MyTypeTag>
struct SpatialDiscretizationSplice { using type = UndefinedProperty; };
namespace TTag {
struct MyTTag {};
struct MySDTTag {};
}
template<class TypeTag>
struct SpatialDiscretizationSplice<TypeTag, TTag::MyTTag>
{ using type = TTag::MySDTTag; };
template<class TypeTag, class MyTypeTag>
struct VtkOutputFormat { using type = UndefinedProperty; };
template<class TypeTag>
struct VtkOutputFormat<TypeTag, TTag::MySDTTag>
{ static constexpr auto value = 2; };
namespace TTag {
struct FvBaseDiscretization;
struct VcfvDiscretization;
struct MultiPhaseBaseModel;
}
namespace Detail {
//! helper struct to extract get the Property specilization given a TypeTag, asserts that the property is defined
//! helper struct to extract get the Property specilization given a TypeTag, asserts that the property is defined
template<class TypeTag, template<class,class> class Property>
struct GetPropImpl
{
using PType = Properties::SpatialDiscretizationSplice<TypeTag, TTag::MyTTag>;
using testtype = std::conditional_t<isDefinedProperty<PType>(int{}), PType, UndefinedProperty>;
static_assert(!std::is_same<testtype, UndefinedProperty>::value, "SpatialDiscretizationSplice is undefined in MyTTag!");
using QType = Properties::VtkOutputFormat<TypeTag, TTag::MySDTTag>;
using testtype2 = std::conditional_t<isDefinedProperty<QType>(int{}), QType, UndefinedProperty>;
static_assert(!std::is_same<testtype2, UndefinedProperty>::value, "VtkOutputFormat is undefined in MySDTTag!");
using RType = Properties::VtkOutputFormat<TypeTag, TTag::FvBaseDiscretization>;
using testtype3 = std::conditional_t<isDefinedProperty<RType>(int{}), RType, UndefinedProperty>;
static_assert(!std::is_same<testtype3, UndefinedProperty>::value, "VtkOutputFormat is undefined in FvBaseDiscretization!");
// works:
// using type = typename Detail::GetDefined<TypeTag,
// Property,
// std::tuple<TypeTag, TTag::VcfvDiscretization>
// >::type;
using tuple = typename GetSplicesTypeTags<TypeTag, std::tuple<TypeTag>>::tuple;
using splice = typename Detail::GetDefinedSplice<TypeTag, std::tuple<TypeTag>>::type;
using tuple = std::conditional_t<std::is_same<splice, std::tuple<>>::value, std::tuple<>, splice>;
using type = typename Detail::GetDefined<TypeTag,
Property,
typename ConCatTuples<std::tuple<TypeTag>, tuple>::type
ConCatTuples<std::tuple<TypeTag>, tuple>
>::type;
static_assert(!std::is_same<type, UndefinedProperty>::value, "Property is undefined!");
};
template<class TypeTag, template<class,class> class Property>
struct GetSplicePropImpl
{
using type = typename Detail::GetDefined<TypeTag, Property, std::tuple<TypeTag>>::type;
static_assert(!std::is_same<type, std::tuple<>>::value, "Splice is undefined!");
};
} // end namespace Detail
} // end namespace Property
@ -267,6 +225,9 @@ using GetProp = typename Properties::Detail::GetPropImpl<TypeTag, Property>::typ
template<class TypeTag, template<class,class> class Property>
using GetPropType = typename Properties::Detail::GetPropImpl<TypeTag, Property>::type::type;
template<class TypeTag, template<class,class> class Property>
using GetSplicePropType = typename Properties::Detail::GetSplicePropImpl<TypeTag, Property>::type::type;
//! get the value data member of a property
template<class TypeTag, template<class,class> class Property>
constexpr auto getPropValue() { return Properties::Detail::GetPropImpl<TypeTag, Property>::type::value; }