diff --git a/opm/models/blackoil/blackoilmodel.hh b/opm/models/blackoil/blackoilmodel.hh index 42ada382c..4d240da2d 100644 --- a/opm/models/blackoil/blackoilmodel.hh +++ b/opm/models/blackoil/blackoilmodel.hh @@ -153,12 +153,9 @@ private: public: typedef Scalar type; - static const Scalar value; + static constexpr Scalar value = 1.0/(30.0*4184.0*alpha); }; -PROP_STATIC_CONST_MEMBER_DEFINITION_PREFIX_(BlackOilModel, BlackOilEnergyScalingFactor) - ::value = 1.0/(30*4184.0*alpha); - // by default, ebos formulates the conservation equations in terms of mass not surface // volumes SET_BOOL_PROP(BlackOilModel, BlackoilConserveSurfaceVolume, false); diff --git a/opm/models/blackoil/blackoilnewtonmethod.hh b/opm/models/blackoil/blackoilnewtonmethod.hh index 345a67d3b..3abe41914 100644 --- a/opm/models/blackoil/blackoilnewtonmethod.hh +++ b/opm/models/blackoil/blackoilnewtonmethod.hh @@ -31,11 +31,15 @@ #include "blackoilproperties.hh" #include +#include #include BEGIN_PROPERTIES +template +struct DiscNewtonMethod; + NEW_PROP_TAG(DpMaxRel); NEW_PROP_TAG(DsMax); NEW_PROP_TAG(PriVarOscilationThreshold); diff --git a/opm/models/blackoil/blackoilproperties.hh b/opm/models/blackoil/blackoilproperties.hh index 56ae6dfa6..e84cdf61b 100644 --- a/opm/models/blackoil/blackoilproperties.hh +++ b/opm/models/blackoil/blackoilproperties.hh @@ -36,14 +36,6 @@ BEGIN_PROPERTIES //! Specifies if the simulation should write output files that are //! compatible with those produced by the commercial Eclipse simulator NEW_PROP_TAG(EnableEclipseOutput); -//! The material law for thermal conduction -NEW_PROP_TAG(ThermalConductionLaw); -//! The parameters of the material law for thermal conduction -NEW_PROP_TAG(ThermalConductionLawParams); -//! The material law for energy storage of the rock -NEW_PROP_TAG(SolidEnergyLaw); -//! The parameters for material law for energy storage of the rock -NEW_PROP_TAG(SolidEnergyLawParams); //! Enable the ECL-blackoil extension for solvents. ("Second gas") NEW_PROP_TAG(EnableSolvent); //! Enable the ECL-blackoil extension for polymer. @@ -62,11 +54,6 @@ NEW_PROP_TAG(EnableBrine); //! in the black-oil model NEW_PROP_TAG(EnableTemperature); -//! Enable the ECL-blackoil extension for energy conservation -//! -//! Setting this property to true implies EnableTemperature. -NEW_PROP_TAG(EnableEnergy); - //! The relative weight of the residual of the energy equation compared to the mass //! residuals //! diff --git a/opm/models/common/darcyfluxmodule.hh b/opm/models/common/darcyfluxmodule.hh index 410cbbed5..42cc7f421 100644 --- a/opm/models/common/darcyfluxmodule.hh +++ b/opm/models/common/darcyfluxmodule.hh @@ -42,12 +42,6 @@ #include -BEGIN_PROPERTIES - -NEW_PROP_TAG(MaterialLaw); - -END_PROPERTIES - namespace Opm { template diff --git a/opm/models/common/diffusionmodule.hh b/opm/models/common/diffusionmodule.hh index 4cb12d538..c2785b847 100644 --- a/opm/models/common/diffusionmodule.hh +++ b/opm/models/common/diffusionmodule.hh @@ -37,12 +37,6 @@ #include -BEGIN_PROPERTIES - -NEW_PROP_TAG(Indices); - -END_PROPERTIES - namespace Opm { /*! diff --git a/opm/models/common/energymodule.hh b/opm/models/common/energymodule.hh index 53da3b2c2..c52379f4c 100644 --- a/opm/models/common/energymodule.hh +++ b/opm/models/common/energymodule.hh @@ -40,17 +40,6 @@ #include -BEGIN_PROPERTIES - -NEW_PROP_TAG(Indices); -NEW_PROP_TAG(EnableEnergy); -NEW_PROP_TAG(ThermalConductionLaw); -NEW_PROP_TAG(ThermalConductionLawParams); -NEW_PROP_TAG(SolidEnergyLaw); -NEW_PROP_TAG(SolidEnergyLawParams); - -END_PROPERTIES - namespace Opm { /*! * \ingroup Energy diff --git a/opm/models/common/forchheimerfluxmodule.hh b/opm/models/common/forchheimerfluxmodule.hh index 81a5fa369..45ce29fdc 100644 --- a/opm/models/common/forchheimerfluxmodule.hh +++ b/opm/models/common/forchheimerfluxmodule.hh @@ -43,12 +43,6 @@ #include -BEGIN_PROPERTIES - -NEW_PROP_TAG(MaterialLaw); - -END_PROPERTIES - namespace Opm { template class ForchheimerIntensiveQuantities; diff --git a/opm/models/common/multiphasebasemodel.hh b/opm/models/common/multiphasebasemodel.hh index e6c6346cd..6c7640f9b 100644 --- a/opm/models/common/multiphasebasemodel.hh +++ b/opm/models/common/multiphasebasemodel.hh @@ -36,6 +36,8 @@ #include #include +#include +#include #include #include diff --git a/opm/models/common/multiphasebaseproblem.hh b/opm/models/common/multiphasebaseproblem.hh index a5b8c7c5b..2097acba4 100644 --- a/opm/models/common/multiphasebaseproblem.hh +++ b/opm/models/common/multiphasebaseproblem.hh @@ -41,15 +41,6 @@ #include #include -BEGIN_PROPERTIES - -NEW_PROP_TAG(SolidEnergyLawParams); -NEW_PROP_TAG(ThermalConductionLawParams); -NEW_PROP_TAG(EnableGravity); -NEW_PROP_TAG(FluxModule); - -END_PROPERTIES - namespace Opm { /*! diff --git a/opm/models/common/multiphasebaseproperties.hh b/opm/models/common/multiphasebaseproperties.hh index ec391e49e..f9c48b87f 100644 --- a/opm/models/common/multiphasebaseproperties.hh +++ b/opm/models/common/multiphasebaseproperties.hh @@ -30,9 +30,7 @@ #ifndef EWOMS_MULTI_PHASE_BASE_PROPERTIES_HH #define EWOMS_MULTI_PHASE_BASE_PROPERTIES_HH -#include -#include -#include +#include BEGIN_PROPERTIES @@ -61,8 +59,12 @@ NEW_PROP_TAG(FluidSystem); //! Specifies the relation used for velocity NEW_PROP_TAG(FluxModule); +//! Specify whether energy should be considered as a conservation quantity or not +NEW_PROP_TAG(EnableEnergy); //! Returns whether gravity is considered in the problem NEW_PROP_TAG(EnableGravity); +//! Enable diffusive fluxes? +NEW_PROP_TAG(EnableDiffusion); END_PROPERTIES diff --git a/opm/models/discretefracture/discretefractureproblem.hh b/opm/models/discretefracture/discretefractureproblem.hh index 8793a3d4d..1f45d53b1 100644 --- a/opm/models/discretefracture/discretefractureproblem.hh +++ b/opm/models/discretefracture/discretefractureproblem.hh @@ -39,14 +39,6 @@ #include #include -BEGIN_PROPERTIES - -NEW_PROP_TAG(ThermalConductionLawParams); -NEW_PROP_TAG(EnableGravity); -NEW_PROP_TAG(FluxModule); - -END_PROPERTIES - namespace Opm { /*! diff --git a/opm/models/discretization/common/baseauxiliarymodule.hh b/opm/models/discretization/common/baseauxiliarymodule.hh index 3f0381200..b4dbb6fe6 100644 --- a/opm/models/discretization/common/baseauxiliarymodule.hh +++ b/opm/models/discretization/common/baseauxiliarymodule.hh @@ -38,14 +38,6 @@ BEGIN_PROPERTIES NEW_TYPE_TAG(AuxModule); -// declare the properties required by the for the ecl grid manager -NEW_PROP_TAG(Grid); -NEW_PROP_TAG(GridView); -NEW_PROP_TAG(Scalar); -NEW_PROP_TAG(DofMapper); -NEW_PROP_TAG(GlobalEqVector); -NEW_PROP_TAG(SparseMatrixAdapter); - END_PROPERTIES namespace Opm { diff --git a/opm/models/discretization/common/fvbaseadlocallinearizer.hh b/opm/models/discretization/common/fvbaseadlocallinearizer.hh index 5bc9d53ce..ea7fc34e7 100644 --- a/opm/models/discretization/common/fvbaseadlocallinearizer.hh +++ b/opm/models/discretization/common/fvbaseadlocallinearizer.hh @@ -51,18 +51,6 @@ BEGIN_PROPERTIES // declare the property tags required for the finite differences local linearizer NEW_TYPE_TAG(AutoDiffLocalLinearizer); -NEW_PROP_TAG(LocalLinearizer); -NEW_PROP_TAG(Evaluation); - -NEW_PROP_TAG(LocalResidual); -NEW_PROP_TAG(Simulator); -NEW_PROP_TAG(Problem); -NEW_PROP_TAG(Model); -NEW_PROP_TAG(PrimaryVariables); -NEW_PROP_TAG(ElementContext); -NEW_PROP_TAG(Scalar); -NEW_PROP_TAG(Evaluation); -NEW_PROP_TAG(GridView); // set the properties to be spliced in SET_TYPE_PROP(AutoDiffLocalLinearizer, LocalLinearizer, diff --git a/opm/models/discretization/common/fvbaseconstraints.hh b/opm/models/discretization/common/fvbaseconstraints.hh index ad3af67da..feb7b259e 100644 --- a/opm/models/discretization/common/fvbaseconstraints.hh +++ b/opm/models/discretization/common/fvbaseconstraints.hh @@ -31,12 +31,6 @@ #include #include -BEGIN_PROPERTIES - -NEW_PROP_TAG(PrimaryVariables); - -END_PROPERTIES - namespace Opm { /*! diff --git a/opm/models/discretization/common/fvbasediscretization.hh b/opm/models/discretization/common/fvbasediscretization.hh index c65d4d2f0..d969e414c 100644 --- a/opm/models/discretization/common/fvbasediscretization.hh +++ b/opm/models/discretization/common/fvbasediscretization.hh @@ -54,6 +54,7 @@ #include #include #include +#include #include #include diff --git a/opm/models/discretization/common/fvbaseextensivequantities.hh b/opm/models/discretization/common/fvbaseextensivequantities.hh index c15b8f41d..4ea3dbe2f 100644 --- a/opm/models/discretization/common/fvbaseextensivequantities.hh +++ b/opm/models/discretization/common/fvbaseextensivequantities.hh @@ -30,6 +30,8 @@ #include "fvbaseproperties.hh" +#include + #include #include diff --git a/opm/models/discretization/common/fvbasefdlocallinearizer.hh b/opm/models/discretization/common/fvbasefdlocallinearizer.hh index c53ed18b5..f27189cbe 100644 --- a/opm/models/discretization/common/fvbasefdlocallinearizer.hh +++ b/opm/models/discretization/common/fvbasefdlocallinearizer.hh @@ -30,6 +30,7 @@ #include #include +#include #include #include @@ -54,21 +55,8 @@ BEGIN_PROPERTIES // declare the property tags required for the finite differences local linearizer NEW_TYPE_TAG(FiniteDifferenceLocalLinearizer); -NEW_PROP_TAG(LocalLinearizer); -NEW_PROP_TAG(Evaluation); NEW_PROP_TAG(NumericDifferenceMethod); NEW_PROP_TAG(BaseEpsilon); -NEW_PROP_TAG(SparseMatrixAdapter); -NEW_PROP_TAG(LocalResidual); -NEW_PROP_TAG(Simulator); -NEW_PROP_TAG(Problem); -NEW_PROP_TAG(Model); -NEW_PROP_TAG(PrimaryVariables); -NEW_PROP_TAG(ElementContext); -NEW_PROP_TAG(Scalar); -NEW_PROP_TAG(Evaluation); -NEW_PROP_TAG(GridView); -NEW_PROP_TAG(NumEq); // set the properties to be spliced in SET_TYPE_PROP(FiniteDifferenceLocalLinearizer, LocalLinearizer, diff --git a/opm/models/discretization/common/fvbasenewtonconvergencewriter.hh b/opm/models/discretization/common/fvbasenewtonconvergencewriter.hh index b66b44bbd..6b7e26290 100644 --- a/opm/models/discretization/common/fvbasenewtonconvergencewriter.hh +++ b/opm/models/discretization/common/fvbasenewtonconvergencewriter.hh @@ -37,11 +37,14 @@ BEGIN_PROPERTIES // forward declaration of the required property tags -NEW_PROP_TAG(GridView); -NEW_PROP_TAG(NewtonMethod); -NEW_PROP_TAG(SolutionVector); -NEW_PROP_TAG(GlobalEqVector); -NEW_PROP_TAG(VtkOutputFormat); +template +struct SolutionVector; +template +struct GlobalEqVector; +template +struct NewtonMethod; +template +struct VtkOutputFormat; END_PROPERTIES //! \endcond diff --git a/opm/models/discretization/common/fvbasenewtonmethod.hh b/opm/models/discretization/common/fvbasenewtonmethod.hh index c482ea086..e5addb85d 100644 --- a/opm/models/discretization/common/fvbasenewtonmethod.hh +++ b/opm/models/discretization/common/fvbasenewtonmethod.hh @@ -47,25 +47,9 @@ BEGIN_PROPERTIES //! create a type tag for the Newton method of the finite-volume discretization NEW_TYPE_TAG(FvBaseNewtonMethod, INHERITS_FROM(NewtonMethod)); -//! The class dealing with the balance equations -NEW_PROP_TAG(Model); - -//! The class storing primary variables plus pseudo primary variables -NEW_PROP_TAG(PrimaryVariables); - -//! The class storing values of conservation equations (e.g., a "naked" primary varible -//! vector) -NEW_PROP_TAG(EqVector); - -//! The number of balance equations. -NEW_PROP_TAG(NumEq); - //! The discretization specific part of he implementing the Newton algorithm NEW_PROP_TAG(DiscNewtonMethod); -//! The class implementing the Newton algorithm -NEW_PROP_TAG(NewtonMethod); - // set default values SET_TYPE_PROP(FvBaseNewtonMethod, DiscNewtonMethod, Opm::FvBaseNewtonMethod); diff --git a/opm/models/discretization/common/fvbaseproblem.hh b/opm/models/discretization/common/fvbaseproblem.hh index b493f9397..12601376b 100644 --- a/opm/models/discretization/common/fvbaseproblem.hh +++ b/opm/models/discretization/common/fvbaseproblem.hh @@ -45,6 +45,13 @@ #include +BEGIN_PROPERTIES + +template +struct NewtonMethod; + +END_PROPERTIES + namespace Opm { /*! diff --git a/opm/models/discretization/common/fvbaseproperties.hh b/opm/models/discretization/common/fvbaseproperties.hh index bf643f100..3d336830c 100644 --- a/opm/models/discretization/common/fvbaseproperties.hh +++ b/opm/models/discretization/common/fvbaseproperties.hh @@ -30,16 +30,18 @@ #ifndef EWOMS_FV_BASE_PROPERTIES_HH #define EWOMS_FV_BASE_PROPERTIES_HH -#include "fvbasenewtonmethod.hh" -#include "fvbaseproperties.hh" -#include "fvbasefdlocallinearizer.hh" - #include -#include +#include #include BEGIN_PROPERTIES +namespace TTag { +struct FvBaseNewtonMethod; +struct VtkPrimaryVars; +struct FiniteDifferenceLocalLinearizer; +} + //! The type tag for models based on the finite volume schemes NEW_TYPE_TAG(FvBaseDiscretization, INHERITS_FROM(ImplicitModel, @@ -49,11 +51,7 @@ NEW_TYPE_TAG(FvBaseDiscretization, //! set the splices for the finite volume discretizations NEW_PROP_TAG(LinearSolverSplice); -NEW_PROP_TAG(ParallelBiCGStabLinearSolver); - NEW_PROP_TAG(LocalLinearizerSplice); -NEW_PROP_TAG(FiniteDifferenceLocalLinearizer); - SET_SPLICES(FvBaseDiscretization, LinearSolverSplice, LocalLinearizerSplice); //! use a parallel BiCGStab linear solver by default @@ -72,11 +70,6 @@ SET_TAG_PROP(FvBaseDiscretization, LocalLinearizerSplice, FiniteDifferenceLocalL */ NEW_PROP_TAG(Evaluation); -//! The type of the DUNE grid -NEW_PROP_TAG(Grid); -//! The type of the grid view -NEW_PROP_TAG(GridView); - //! The class describing the stencil of the spatial discretization NEW_PROP_TAG(Stencil); @@ -87,10 +80,6 @@ NEW_PROP_TAG(DiscreteFunctionSpace); NEW_PROP_TAG(Problem); //! The type of the base class for all problems which use this model NEW_PROP_TAG(BaseProblem); -//! The type of the model -NEW_PROP_TAG(Model); -//! Number of equations in the system of PDEs -NEW_PROP_TAG(NumEq); //! The type of the spatial discretization used by the model NEW_PROP_TAG(Discretization); @@ -106,15 +95,11 @@ NEW_PROP_TAG(LinearizeNonLocalElements); //! Linearizes the global non-linear system of equations NEW_PROP_TAG(BaseLinearizer); -//! The class that allows to manipulate sparse matrices -NEW_PROP_TAG(SparseMatrixAdapter); //! A vector of holding a quantity for each equation (usually at a given spatial location) NEW_PROP_TAG(EqVector); //! A vector of holding a quantity for each equation for each DOF of an element NEW_PROP_TAG(ElementEqVector); -//! Vector containing a quantity of for equation for each DOF of the whole grid -NEW_PROP_TAG(GlobalEqVector); //! Vector containing volumetric or areal rates of quantities NEW_PROP_TAG(RateVector); @@ -170,9 +155,6 @@ NEW_PROP_TAG(UseLinearizationLock); // high-level simulation control -//! Manages the simulation time -NEW_PROP_TAG(Simulator); - /*! * \brief Switch to enable or disable grid adaptation * @@ -292,14 +274,6 @@ NEW_PROP_TAG(ElementMapper); */ NEW_PROP_TAG(DofMapper); -/*! - * \brief The class which marks the border indices associated with the - * degrees of freedom on a process boundary. - * - * This is required for the algebraic overlap stuff. - */ -NEW_PROP_TAG(BorderListCreator); - /*! * \brief The history size required by the time discretization */ @@ -319,6 +293,8 @@ NEW_PROP_TAG(UseVolumetricResidual); //! Specify if experimental features should be enabled or not. NEW_PROP_TAG(EnableExperiments); +SET_TYPE_PROP(NumericModel, Vanguard, Opm::DgfVanguard); + END_PROPERTIES #endif diff --git a/opm/models/flash/flashproperties.hh b/opm/models/flash/flashproperties.hh index 108b6d63b..fb12be56e 100644 --- a/opm/models/flash/flashproperties.hh +++ b/opm/models/flash/flashproperties.hh @@ -37,23 +37,11 @@ BEGIN_PROPERTIES -//! Provides the thermodynamic relations -NEW_PROP_TAG(FluidSystem); //! The type of the flash constraint solver NEW_PROP_TAG(FlashSolver); //! The maximum accepted error of the flash solver NEW_PROP_TAG(FlashTolerance); -//! The thermal conduction law which ought to be used -NEW_PROP_TAG(ThermalConductionLaw); -//! The parameters of the thermal conduction law -NEW_PROP_TAG(ThermalConductionLawParams); - -//! Specifies whether energy should be considered as a conservation quantity or not -NEW_PROP_TAG(EnableEnergy); -//! Enable diffusive fluxes? -NEW_PROP_TAG(EnableDiffusion); - END_PROPERTIES #endif diff --git a/opm/models/immiscible/immiscibleproperties.hh b/opm/models/immiscible/immiscibleproperties.hh index 77380a375..0eaa087c1 100644 --- a/opm/models/immiscible/immiscibleproperties.hh +++ b/opm/models/immiscible/immiscibleproperties.hh @@ -35,24 +35,16 @@ BEGIN_PROPERTIES -//!The fluid systems including the information about the phases -NEW_PROP_TAG(FluidSystem); -//! Specify whether energy should be considered as a conservation quantity or not -NEW_PROP_TAG(EnableEnergy); - // these properties only make sense for the ImmiscibleTwoPhase type tag - //! The wetting phase for two-phase models NEW_PROP_TAG(WettingPhase); //! The non-wetting phase for two-phase models NEW_PROP_TAG(NonwettingPhase); // these properties only make sense for the ImmiscibleSinglePhase type tag - //! The fluid used by the model NEW_PROP_TAG(Fluid); - END_PROPERTIES #endif diff --git a/opm/models/io/baseoutputmodule.hh b/opm/models/io/baseoutputmodule.hh index fc18a5ba9..c2909b015 100644 --- a/opm/models/io/baseoutputmodule.hh +++ b/opm/models/io/baseoutputmodule.hh @@ -31,6 +31,9 @@ #include #include +#include +#include +#include #include @@ -46,19 +49,8 @@ BEGIN_PROPERTIES -// forward definition of property tags -NEW_PROP_TAG(NumPhases); -NEW_PROP_TAG(NumComponents); -NEW_PROP_TAG(NumEq); - -NEW_PROP_TAG(Model); -NEW_PROP_TAG(Simulator); -NEW_PROP_TAG(Scalar); -NEW_PROP_TAG(Evaluation); -NEW_PROP_TAG(GridView); -NEW_PROP_TAG(ElementContext); -NEW_PROP_TAG(FluidSystem); -NEW_PROP_TAG(DiscBaseOutputModule); +template +struct FluidSystem; END_PROPERTIES diff --git a/opm/models/io/basevanguard.hh b/opm/models/io/basevanguard.hh index 061de0764..e484ccf04 100644 --- a/opm/models/io/basevanguard.hh +++ b/opm/models/io/basevanguard.hh @@ -27,7 +27,7 @@ #ifndef EWOMS_BASE_VANGUARD_HH #define EWOMS_BASE_VANGUARD_HH -#include +#include #include #include @@ -39,19 +39,6 @@ #include #include -BEGIN_PROPERTIES - -NEW_PROP_TAG(Grid); -NEW_PROP_TAG(Vanguard); -NEW_PROP_TAG(GridView); -NEW_PROP_TAG(GridPart); -NEW_PROP_TAG(GridViewLevel); -NEW_PROP_TAG(GridFile); -NEW_PROP_TAG(GridGlobalRefinements); -NEW_PROP_TAG(Simulator); - -END_PROPERTIES - namespace Opm { /*! diff --git a/opm/models/io/cubegridvanguard.hh b/opm/models/io/cubegridvanguard.hh index 4ee8d474a..0037a48a0 100644 --- a/opm/models/io/cubegridvanguard.hh +++ b/opm/models/io/cubegridvanguard.hh @@ -38,23 +38,6 @@ #include -BEGIN_PROPERTIES - -NEW_PROP_TAG(Scalar); -NEW_PROP_TAG(Grid); - -NEW_PROP_TAG(DomainSizeX); -NEW_PROP_TAG(DomainSizeY); -NEW_PROP_TAG(DomainSizeZ); - -NEW_PROP_TAG(CellsX); -NEW_PROP_TAG(CellsY); -NEW_PROP_TAG(CellsZ); - -NEW_PROP_TAG(GridGlobalRefinements); - -END_PROPERTIES - namespace Opm { /*! diff --git a/opm/models/io/dgfvanguard.hh b/opm/models/io/dgfvanguard.hh index 15a9bd0e8..64d0b46be 100644 --- a/opm/models/io/dgfvanguard.hh +++ b/opm/models/io/dgfvanguard.hh @@ -39,17 +39,6 @@ #include #include -BEGIN_PROPERTIES - -NEW_PROP_TAG(Grid); -NEW_PROP_TAG(GridFile); -NEW_PROP_TAG(Vanguard); -NEW_PROP_TAG(GridGlobalRefinements); -NEW_PROP_TAG(Scalar); -NEW_PROP_TAG(Simulator); - -END_PROPERTIES - namespace Opm { /*! diff --git a/opm/models/io/simplexvanguard.hh b/opm/models/io/simplexvanguard.hh index a12165a4f..6add92600 100644 --- a/opm/models/io/simplexvanguard.hh +++ b/opm/models/io/simplexvanguard.hh @@ -36,23 +36,6 @@ #include -BEGIN_PROPERTIES - -NEW_PROP_TAG(Scalar); -NEW_PROP_TAG(Grid); - -NEW_PROP_TAG(DomainSizeX); -NEW_PROP_TAG(DomainSizeY); -NEW_PROP_TAG(DomainSizeZ); - -NEW_PROP_TAG(CellsX); -NEW_PROP_TAG(CellsY); -NEW_PROP_TAG(CellsZ); - -NEW_PROP_TAG(GridGlobalRefinements); - -END_PROPERTIES - namespace Opm { /*! * \brief Provides a simulator vanguard which a creates regular grid made of simplices. diff --git a/opm/models/io/structuredgridvanguard.hh b/opm/models/io/structuredgridvanguard.hh index 3e143737c..c79e9a478 100644 --- a/opm/models/io/structuredgridvanguard.hh +++ b/opm/models/io/structuredgridvanguard.hh @@ -56,20 +56,6 @@ BEGIN_PROPERTIES NEW_TYPE_TAG(StructuredGridVanguard); -// declare the properties required by the for the structured grid simulator vanguard -NEW_PROP_TAG(Grid); -NEW_PROP_TAG(Scalar); - -NEW_PROP_TAG(DomainSizeX); -NEW_PROP_TAG(DomainSizeY); -NEW_PROP_TAG(DomainSizeZ); - -NEW_PROP_TAG(CellsX); -NEW_PROP_TAG(CellsY); -NEW_PROP_TAG(CellsZ); - -NEW_PROP_TAG(GridGlobalRefinements); - // GRIDDIM is only set by the finger problem #ifndef GRIDDIM static const int dim = 2; diff --git a/opm/models/io/vtkblackoilenergymodule.hh b/opm/models/io/vtkblackoilenergymodule.hh index 54fed458c..b8b7c4a14 100644 --- a/opm/models/io/vtkblackoilenergymodule.hh +++ b/opm/models/io/vtkblackoilenergymodule.hh @@ -50,8 +50,6 @@ NEW_PROP_TAG(VtkWriteRockInternalEnergy); NEW_PROP_TAG(VtkWriteTotalThermalConductivity); NEW_PROP_TAG(VtkWriteFluidInternalEnergies); NEW_PROP_TAG(VtkWriteFluidEnthalpies); -NEW_PROP_TAG(VtkOutputFormat); -NEW_PROP_TAG(EnableVtkOutput); // set default values for what quantities to output SET_BOOL_PROP(VtkBlackOilEnergy, VtkWriteRockInternalEnergy, true); diff --git a/opm/models/io/vtkblackoilmodule.hh b/opm/models/io/vtkblackoilmodule.hh index ec0d251ce..449163236 100644 --- a/opm/models/io/vtkblackoilmodule.hh +++ b/opm/models/io/vtkblackoilmodule.hh @@ -46,8 +46,6 @@ BEGIN_PROPERTIES NEW_TYPE_TAG(VtkBlackOil); // create the property tags needed for the multi phase module -NEW_PROP_TAG(EnableVtkOutput); -NEW_PROP_TAG(VtkOutputFormat); NEW_PROP_TAG(VtkWriteGasDissolutionFactor); NEW_PROP_TAG(VtkWriteOilVaporizationFactor); NEW_PROP_TAG(VtkWriteOilFormationVolumeFactor); diff --git a/opm/models/io/vtkblackoilpolymermodule.hh b/opm/models/io/vtkblackoilpolymermodule.hh index 03a9ea78c..ff5c54d37 100644 --- a/opm/models/io/vtkblackoilpolymermodule.hh +++ b/opm/models/io/vtkblackoilpolymermodule.hh @@ -46,8 +46,6 @@ BEGIN_PROPERTIES NEW_TYPE_TAG(VtkBlackOilPolymer); // create the property tags needed for the polymer output module -NEW_PROP_TAG(EnablePolymer); -NEW_PROP_TAG(EnableVtkOutput); NEW_PROP_TAG(VtkWritePolymerConcentration); NEW_PROP_TAG(VtkWritePolymerDeadPoreVolume); NEW_PROP_TAG(VtkWritePolymerAdsorption); diff --git a/opm/models/io/vtkblackoilsolventmodule.hh b/opm/models/io/vtkblackoilsolventmodule.hh index cbdcd75fa..07f6050fd 100644 --- a/opm/models/io/vtkblackoilsolventmodule.hh +++ b/opm/models/io/vtkblackoilsolventmodule.hh @@ -46,8 +46,6 @@ BEGIN_PROPERTIES NEW_TYPE_TAG(VtkBlackOilSolvent); // create the property tags needed for the solvent output module -NEW_PROP_TAG(EnableSolvent); -NEW_PROP_TAG(EnableVtkOutput); NEW_PROP_TAG(VtkWriteSolventSaturation); NEW_PROP_TAG(VtkWriteSolventDensity); NEW_PROP_TAG(VtkWriteSolventViscosity); diff --git a/opm/models/io/vtkcompositionmodule.hh b/opm/models/io/vtkcompositionmodule.hh index 172e53bdc..1ae2d5a99 100644 --- a/opm/models/io/vtkcompositionmodule.hh +++ b/opm/models/io/vtkcompositionmodule.hh @@ -48,8 +48,6 @@ NEW_PROP_TAG(VtkWriteTotalMoleFractions); NEW_PROP_TAG(VtkWriteMolarities); NEW_PROP_TAG(VtkWriteFugacities); NEW_PROP_TAG(VtkWriteFugacityCoeffs); -NEW_PROP_TAG(VtkOutputFormat); -NEW_PROP_TAG(EnableVtkOutput); // set default values for what quantities to output SET_BOOL_PROP(VtkComposition, VtkWriteMassFractions, false); diff --git a/opm/models/io/vtkdiffusionmodule.hh b/opm/models/io/vtkdiffusionmodule.hh index ac9d75c7c..d72547f40 100644 --- a/opm/models/io/vtkdiffusionmodule.hh +++ b/opm/models/io/vtkdiffusionmodule.hh @@ -47,8 +47,6 @@ NEW_TYPE_TAG(VtkDiffusion); NEW_PROP_TAG(VtkWriteTortuosities); NEW_PROP_TAG(VtkWriteDiffusionCoefficients); NEW_PROP_TAG(VtkWriteEffectiveDiffusionCoefficients); -NEW_PROP_TAG(VtkOutputFormat); -NEW_PROP_TAG(EnableVtkOutput); // set default values for what quantities to output SET_BOOL_PROP(VtkDiffusion, VtkWriteTortuosities, false); diff --git a/opm/models/io/vtkdiscretefracturemodule.hh b/opm/models/io/vtkdiscretefracturemodule.hh index bf4dc6188..3c535d7b1 100644 --- a/opm/models/io/vtkdiscretefracturemodule.hh +++ b/opm/models/io/vtkdiscretefracturemodule.hh @@ -45,7 +45,6 @@ BEGIN_PROPERTIES NEW_TYPE_TAG(VtkDiscreteFracture); // create the property tags needed for the multi phase module -NEW_PROP_TAG(Vanguard); NEW_PROP_TAG(VtkWriteFractureSaturations); NEW_PROP_TAG(VtkWriteFractureMobilities); NEW_PROP_TAG(VtkWriteFractureRelativePermeabilities); @@ -53,9 +52,6 @@ NEW_PROP_TAG(VtkWriteFracturePorosity); NEW_PROP_TAG(VtkWriteFractureIntrinsicPermeabilities); NEW_PROP_TAG(VtkWriteFractureFilterVelocities); NEW_PROP_TAG(VtkWriteFractureVolumeFraction); -NEW_PROP_TAG(VtkOutputFormat); -NEW_PROP_TAG(EnableVtkOutput); -NEW_PROP_TAG(DiscBaseOutputModule); // set default values for what quantities to output SET_BOOL_PROP(VtkDiscreteFracture, VtkWriteFractureSaturations, true); diff --git a/opm/models/io/vtkenergymodule.hh b/opm/models/io/vtkenergymodule.hh index f0e6323c0..b23bd5bc4 100644 --- a/opm/models/io/vtkenergymodule.hh +++ b/opm/models/io/vtkenergymodule.hh @@ -45,8 +45,6 @@ NEW_PROP_TAG(VtkWriteSolidInternalEnergy); NEW_PROP_TAG(VtkWriteThermalConductivity); NEW_PROP_TAG(VtkWriteInternalEnergies); NEW_PROP_TAG(VtkWriteEnthalpies); -NEW_PROP_TAG(VtkOutputFormat); -NEW_PROP_TAG(EnableVtkOutput); // set default values for what quantities to output SET_BOOL_PROP(VtkEnergy, VtkWriteSolidInternalEnergy, false); diff --git a/opm/models/io/vtkmultiphasemodule.hh b/opm/models/io/vtkmultiphasemodule.hh index 2cc4763b5..8f1f0b376 100644 --- a/opm/models/io/vtkmultiphasemodule.hh +++ b/opm/models/io/vtkmultiphasemodule.hh @@ -58,8 +58,6 @@ NEW_PROP_TAG(VtkWritePorosity); NEW_PROP_TAG(VtkWriteIntrinsicPermeabilities); NEW_PROP_TAG(VtkWritePotentialGradients); NEW_PROP_TAG(VtkWriteFilterVelocities); -NEW_PROP_TAG(VtkOutputFormat); -NEW_PROP_TAG(EnableVtkOutput); // set default values for what quantities to output SET_BOOL_PROP(VtkMultiPhase, VtkWriteExtrusionFactor, false); diff --git a/opm/models/io/vtkphasepresencemodule.hh b/opm/models/io/vtkphasepresencemodule.hh index 21bd832cc..a6fccf3b0 100644 --- a/opm/models/io/vtkphasepresencemodule.hh +++ b/opm/models/io/vtkphasepresencemodule.hh @@ -40,8 +40,6 @@ NEW_TYPE_TAG(VtkPhasePresence); // create the property tags needed for the primary variables module NEW_PROP_TAG(VtkWritePhasePresence); -NEW_PROP_TAG(VtkOutputFormat); -NEW_PROP_TAG(EnableVtkOutput); SET_BOOL_PROP(VtkPhasePresence, VtkWritePhasePresence, false); diff --git a/opm/models/io/vtkprimaryvarsmodule.hh b/opm/models/io/vtkprimaryvarsmodule.hh index bace701ba..90c9fe26a 100644 --- a/opm/models/io/vtkprimaryvarsmodule.hh +++ b/opm/models/io/vtkprimaryvarsmodule.hh @@ -36,15 +36,12 @@ BEGIN_PROPERTIES // create new type tag for the VTK primary variables output -NEW_PROP_TAG(EnableVtkOutput); NEW_TYPE_TAG(VtkPrimaryVars); // create the property tags needed for the primary variables module NEW_PROP_TAG(VtkWritePrimaryVars); NEW_PROP_TAG(VtkWriteProcessRank); NEW_PROP_TAG(VtkWriteDofIndex); -NEW_PROP_TAG(VtkOutputFormat); -NEW_PROP_TAG(EnableVtkOutput); SET_BOOL_PROP(VtkPrimaryVars, VtkWritePrimaryVars, false); SET_BOOL_PROP(VtkPrimaryVars, VtkWriteProcessRank, false); diff --git a/opm/models/io/vtktemperaturemodule.hh b/opm/models/io/vtktemperaturemodule.hh index ed9d7e9b0..6135df00f 100644 --- a/opm/models/io/vtktemperaturemodule.hh +++ b/opm/models/io/vtktemperaturemodule.hh @@ -42,8 +42,6 @@ NEW_TYPE_TAG(VtkTemperature); // create the property tags needed for the temperature module NEW_PROP_TAG(VtkWriteTemperature); -NEW_PROP_TAG(VtkOutputFormat); -NEW_PROP_TAG(EnableVtkOutput); // set default values for what quantities to output SET_BOOL_PROP(VtkTemperature, VtkWriteTemperature, true); diff --git a/opm/models/ncp/ncpnewtonmethod.hh b/opm/models/ncp/ncpnewtonmethod.hh index 001564655..ef3b5eea0 100644 --- a/opm/models/ncp/ncpnewtonmethod.hh +++ b/opm/models/ncp/ncpnewtonmethod.hh @@ -30,11 +30,20 @@ #include "ncpproperties.hh" +#include + #include #include #include +BEGIN_PROPERTIES + +template +struct DiscNewtonMethod; + +END_PROPERTIES + namespace Opm { /*! diff --git a/opm/models/ncp/ncpproperties.hh b/opm/models/ncp/ncpproperties.hh index bd49ae6c0..7b9909702 100644 --- a/opm/models/ncp/ncpproperties.hh +++ b/opm/models/ncp/ncpproperties.hh @@ -37,12 +37,6 @@ BEGIN_PROPERTIES -//! Enable the energy equation? -NEW_PROP_TAG(EnableEnergy); - -//! Enable diffusive fluxes? -NEW_PROP_TAG(EnableDiffusion); - //! The unmodified weight for the pressure primary variable NEW_PROP_TAG(NcpPressureBaseWeight); //! The weight for the saturation primary variables diff --git a/opm/models/nonlinear/newtonmethod.hh b/opm/models/nonlinear/newtonmethod.hh index 27649c11d..e4c389397 100644 --- a/opm/models/nonlinear/newtonmethod.hh +++ b/opm/models/nonlinear/newtonmethod.hh @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -65,48 +66,12 @@ BEGIN_PROPERTIES //! are attached NEW_TYPE_TAG(NewtonMethod); -//! The simulation management class of the simulation -NEW_PROP_TAG(Simulator); - -//! The physical model which we would like to solve -NEW_PROP_TAG(Problem); - -//! The model describing the PDEs for the conservation quantities -NEW_PROP_TAG(Model); - -//! The type of scalar values -NEW_PROP_TAG(Scalar); - //! Specifies the type of the actual Newton method NEW_PROP_TAG(NewtonMethod); -//! Specifies the type of a solution -NEW_PROP_TAG(SolutionVector); - -//! Specifies the type of a solution for a single degee of freedom -NEW_PROP_TAG(PrimaryVariables); - -//! Specifies whether the problem to be simulated exhibits contraint degrees of freedom -NEW_PROP_TAG(EnableConstraints); - -//! Specifies the type of objects which specify constraints for a single degee of freedom -NEW_PROP_TAG(Constraints); - -//! Vector containing a quantity of for equation on the whole grid -NEW_PROP_TAG(GlobalEqVector); - -//! Vector containing a quantity of for equation for a single degee of freedom -NEW_PROP_TAG(EqVector); - //! The class which linearizes the non-linear system of equations NEW_PROP_TAG(Linearizer); -//! Specifies the type of a global Jacobian matrix -NEW_PROP_TAG(SparseMatrixAdapter); - -//! Specifies the type of the linear solver to be used -NEW_PROP_TAG(LinearSolverBackend); - //! Specifies whether the Newton method should print messages or not NEW_PROP_TAG(NewtonVerbose); diff --git a/opm/models/nonlinear/nullconvergencewriter.hh b/opm/models/nonlinear/nullconvergencewriter.hh index b58377801..009e7642a 100644 --- a/opm/models/nonlinear/nullconvergencewriter.hh +++ b/opm/models/nonlinear/nullconvergencewriter.hh @@ -34,10 +34,8 @@ BEGIN_PROPERTIES -NEW_PROP_TAG(NewtonMethod); - -NEW_PROP_TAG(SolutionVector); -NEW_PROP_TAG(GlobalEqVector); +template +struct NewtonMethod; END_PROPERTIES diff --git a/opm/models/parallel/threadmanager.hh b/opm/models/parallel/threadmanager.hh index 7f89df0c2..6ecb29d3e 100644 --- a/opm/models/parallel/threadmanager.hh +++ b/opm/models/parallel/threadmanager.hh @@ -38,12 +38,6 @@ #include -BEGIN_PROPERTIES - -NEW_PROP_TAG(ThreadsPerProcess); - -END_PROPERTIES - namespace Opm { /*! diff --git a/opm/models/pvs/pvsnewtonmethod.hh b/opm/models/pvs/pvsnewtonmethod.hh index 3bbb0efd2..10d8769a4 100644 --- a/opm/models/pvs/pvsnewtonmethod.hh +++ b/opm/models/pvs/pvsnewtonmethod.hh @@ -30,6 +30,15 @@ #include "pvsproperties.hh" +#include + +BEGIN_PROPERTIES + +template +struct DiscNewtonMethod; + +END_PROPERTIES + namespace Opm { /*! diff --git a/opm/models/pvs/pvsproperties.hh b/opm/models/pvs/pvsproperties.hh index 7bcb183dc..c1db5df8b 100644 --- a/opm/models/pvs/pvsproperties.hh +++ b/opm/models/pvs/pvsproperties.hh @@ -40,11 +40,6 @@ BEGIN_PROPERTIES -//! Specifies whether energy is considered as a conservation quantity or not -NEW_PROP_TAG(EnableEnergy); -//! Enable diffusive fluxes? -NEW_PROP_TAG(EnableDiffusion); - //! The verbosity of the model (0 -> do not print anything, 2 -> spam stdout a lot) NEW_PROP_TAG(PvsVerbosity); //! The basis value for the weight of the pressure primary variable diff --git a/opm/models/richards/richardsproperties.hh b/opm/models/richards/richardsproperties.hh index 424a11cc8..1748286f9 100644 --- a/opm/models/richards/richardsproperties.hh +++ b/opm/models/richards/richardsproperties.hh @@ -34,9 +34,6 @@ // \{ BEGIN_PROPERTIES -//! The fluid system used for the problem -NEW_PROP_TAG(FluidSystem); - //! The fluid used as the wetting phase (by default, we set the fluid //! system to the immiscible one, which requires this property.) NEW_PROP_TAG(WettingFluid); diff --git a/opm/models/utils/basicproperties.hh b/opm/models/utils/basicproperties.hh index 2eb64d5a9..b82430994 100644 --- a/opm/models/utils/basicproperties.hh +++ b/opm/models/utils/basicproperties.hh @@ -32,7 +32,6 @@ #include #include -#include #if HAVE_DUNE_FEM #include @@ -65,15 +64,24 @@ NEW_TYPE_TAG(ImplicitModel, INHERITS_FROM(NumericModel)); //! Property to specify the type of scalar values. NEW_PROP_TAG(Scalar); +//! Number of equations in the system of PDEs +NEW_PROP_TAG(NumEq); + //! Property which provides a Dune::ParameterTree. NEW_PROP_TAG(ParameterTree); +//! The type of the model +NEW_PROP_TAG(Model); + //! Property which defines the group that is queried for parameters by default NEW_PROP_TAG(ModelParameterGroup); //! Property which provides a Vanguard (manages grids) NEW_PROP_TAG(Vanguard); +//! The type of the DUNE grid +NEW_PROP_TAG(Grid); + NEW_PROP_TAG(GridView); #if HAVE_DUNE_FEM @@ -116,6 +124,33 @@ NEW_PROP_TAG(RestartTime); //! The name of the file with a number of forced time step lengths NEW_PROP_TAG(PredeterminedTimeStepsFile); +//! domain size +NEW_PROP_TAG(DomainSizeX); +NEW_PROP_TAG(DomainSizeY); +NEW_PROP_TAG(DomainSizeZ); + +//! grid resolution +NEW_PROP_TAG(CellsX); +NEW_PROP_TAG(CellsY); +NEW_PROP_TAG(CellsZ); + +//! name of the grid file +NEW_PROP_TAG(GridFile); + +//! level of the grid view +NEW_PROP_TAG(GridViewLevel); + +//! Manages the simulation time +NEW_PROP_TAG(Simulator); + +/*! + * \brief The class which marks the border indices associated with the + * degrees of freedom on a process boundary. + * + * This is required for the algebraic overlap stuff. + */ +NEW_PROP_TAG(BorderListCreator); + /////////////////////////////////// // Values for the properties /////////////////////////////////// @@ -138,9 +173,6 @@ SET_PROP(NumericModel, ParameterTree) //! use the global group as default for the model's parameter group SET_STRING_PROP(NumericModel, ModelParameterGroup, ""); -//! Use the DgfVanguard by default -SET_TYPE_PROP(NumericModel, Vanguard, Opm::DgfVanguard); - //! Set a value for the GridFile property SET_STRING_PROP(NumericModel, GridFile, ""); diff --git a/opm/models/utils/parametersystem.hh b/opm/models/utils/parametersystem.hh index a1f5f6af0..e3f7f14b0 100644 --- a/opm/models/utils/parametersystem.hh +++ b/opm/models/utils/parametersystem.hh @@ -74,8 +74,8 @@ * \endcode */ #define EWOMS_REGISTER_PARAM(TypeTag, ParamType, ParamName, Description) \ - ::Opm::Parameters::registerParam( \ - #ParamName, #ParamName, Description) + ::Opm::Parameters::registerParam( \ + #ParamName, #ParamName, GET_PROP_VALUE(TypeTag, ParamName), Description) /*! * \ingroup Parameter @@ -85,7 +85,7 @@ * This allows to deal with unused parameters */ #define EWOMS_HIDE_PARAM(TypeTag, ParamName) \ - ::Opm::Parameters::hideParam(#ParamName) + ::Opm::Parameters::hideParam(#ParamName, GET_PROP_VALUE(TypeTag, ParamName)) /*! * \ingroup Parameter @@ -115,14 +115,14 @@ * \endcode */ #define EWOMS_GET_PARAM(TypeTag, ParamType, ParamName) \ - (::Opm::Parameters::get(#ParamName, \ - #ParamName)) + (::Opm::Parameters::get(#ParamName, #ParamName, \ + GET_PROP_VALUE(TypeTag, ParamName))) //!\cond SKIP_THIS #define EWOMS_GET_PARAM_(TypeTag, ParamType, ParamName) \ - (::Opm::Parameters::get( \ - #ParamName, #ParamName, \ - /*errorIfNotRegistered=*/false)) + (::Opm::Parameters::get(#ParamName, #ParamName, \ + GET_PROP_VALUE(TypeTag, ParamName), \ + /*errorIfNotRegistered=*/false)) /*! * \ingroup Parameter @@ -148,8 +148,7 @@ * If the parameter in question has not been registered, this throws an exception. */ #define EWOMS_PARAM_IS_SET(TypeTag, ParamType, ParamName) \ - (::Opm::Parameters::isSet(#ParamName, \ - #ParamName)) + (::Opm::Parameters::isSet(#ParamName, #ParamName)) namespace Opm { namespace Parameters { @@ -180,6 +179,11 @@ template const ParamType get(const char *propTagName, const char *paramName, bool errorIfNotRegistered = true); +template +const ParamType get(const char *propTagName, + const char *paramName, + const ParamType& defaultValue, + bool errorIfNotRegistered = true); class ParamRegFinalizerBase_ { @@ -189,12 +193,13 @@ public: virtual void retrieve() = 0; }; -template +template class ParamRegFinalizer_ : public ParamRegFinalizerBase_ { public: - ParamRegFinalizer_(const std::string& paramName) + ParamRegFinalizer_(const std::string& paramName, const ParamType& defaultValue) : paramName_(paramName) + , defaultValue_(defaultValue) {} virtual void retrieve() override @@ -202,13 +207,15 @@ public: // retrieve the parameter once to make sure that its value does // not contain a syntax error. ParamType __attribute__((unused)) dummy = - get(/*propTagName=*/paramName_.data(), - paramName_.data(), - /*errorIfNotRegistered=*/true); + get(/*propTagName=*/paramName_.data(), + paramName_.data(), + defaultValue_, + /*errorIfNotRegistered=*/true); } private: std::string paramName_; + ParamType defaultValue_; }; } // namespace Parameters @@ -943,21 +950,28 @@ class Param public: template - static const ParamType get(const char *propTagName, - const char *paramName, - bool errorIfNotRegistered = true) + static ParamType get(const char *propTagName, + const char *paramName, + bool errorIfNotRegistered = true) { - return retrieve_(propTagName, - paramName, - errorIfNotRegistered); + return retrieve_(propTagName, paramName, getPropValue(), errorIfNotRegistered); } - + + template + static ParamType get(const char *propTagName, + const char *paramName, + const ParamType& defaultValue, + bool errorIfNotRegistered = true) + { + return retrieve_(propTagName, paramName, defaultValue, errorIfNotRegistered); + } + static void clear() { ParamsMeta::clear(); } - template + template static bool isSet(const char *propTagName OPM_OPTIM_UNUSED, const char *paramName OPM_OPTIM_UNUSED, bool errorIfNotRegistered = true) @@ -1035,10 +1049,11 @@ private: } } - template - static const ParamType retrieve_(const char OPM_OPTIM_UNUSED *propTagName, - const char *paramName, - bool errorIfNotRegistered = true) + template + static ParamType retrieve_(const char OPM_OPTIM_UNUSED *propTagName, + const char *paramName, + const ParamType& defaultValue, + bool errorIfNotRegistered = true) { #ifndef NDEBUG // make sure that the parameter is used consistently. since @@ -1066,8 +1081,7 @@ private: std::string canonicalName(paramName); // retrieve actual parameter from the parameter tree - const ParamType defaultValue = GET_PROP_VALUE_(TypeTag, PropTag); - return ParamsMeta::tree().template get(canonicalName, defaultValue ); + return ParamsMeta::tree().template get(canonicalName, defaultValue); } }; @@ -1079,6 +1093,12 @@ const ParamType get(const char *propTagName, const char *paramName, bool errorIf errorIfNotRegistered); } +template +const ParamType get(const char *propTagName, const char *paramName, const ParamType& defaultValue, bool errorIfNotRegistered) +{ + return Param::template get(propTagName, paramName, defaultValue, errorIfNotRegistered); +} + template void getLists(Container& usedParams, Container& unusedParams) { @@ -1113,16 +1133,16 @@ void reset() return Param::clear(); } -template +template bool isSet(const char *propTagName, const char *paramName, bool errorIfNotRegistered = true) { - return Param::template isSet(propTagName, - paramName, - errorIfNotRegistered); + return Param::template isSet(propTagName, + paramName, + errorIfNotRegistered); } -template -void registerParam(const char *paramName, const char *propertyName, const char *usageString) +template +void registerParam(const char *paramName, const char *propertyName, const ParamType& defaultValue, const char *usageString) { typedef typename GET_PROP(TypeTag, ParameterMetaData) ParamsMeta; if (!ParamsMeta::registrationOpen()) @@ -1130,7 +1150,7 @@ void registerParam(const char *paramName, const char *propertyName, const char * "the parameter '"+std::string(paramName)+"' was registered."); ParamsMeta::registrationFinalizers().emplace_back( - new ParamRegFinalizer_(paramName)); + new ParamRegFinalizer_(paramName, defaultValue)); ParamInfo paramInfo; paramInfo.paramName = paramName; @@ -1140,7 +1160,7 @@ void registerParam(const char *paramName, const char *propertyName, const char * paramInfo.propertyName = propertyName; paramInfo.usageString = usageString; std::ostringstream oss; - oss << GET_PROP_VALUE_(TypeTag, PropTag); + oss << defaultValue; paramInfo.compileTimeValue = oss.str(); paramInfo.isHidden = false; if (ParamsMeta::registry().find(paramName) != ParamsMeta::registry().end()) { @@ -1155,13 +1175,9 @@ void registerParam(const char *paramName, const char *propertyName, const char * ParamsMeta::mutableRegistry()[paramName] = paramInfo; } -template -void hideParam(const char *paramName) +template +void hideParam(const char *paramName, const ParamType& defaultValue) { - // make sure that a property with the parameter name exists. we cannot check if a - // parameter exists at compile time, so this will only be caught at runtime - static const auto defaultValue OPM_UNUSED = GET_PROP_VALUE_(TypeTag, PropTag); - typedef typename GET_PROP(TypeTag, ParameterMetaData) ParamsMeta; if (!ParamsMeta::registrationOpen()) throw std::logic_error("Parameter '"+std::string(paramName)+"' declared as hidden" diff --git a/opm/models/utils/propertysystem.hh b/opm/models/utils/propertysystem.hh index a6a3368ed..916d2a59c 100644 --- a/opm/models/utils/propertysystem.hh +++ b/opm/models/utils/propertysystem.hh @@ -1,132 +1,258 @@ // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- // vi: set et ts=4 sw=4 sts=4: -/* - This file is part of the Open Porous Media project (OPM). - - OPM is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. - - OPM is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OPM. If not, see . - - Consult the COPYING file in the top-level source directory of this - module for the precise wording of the license and the list of - copyright holders. -*/ +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *****************************************************************************/ /*! * \file - * \brief Provides the magic behind the eWoms property system. - * - * Properties allow to associate arbitrary data types to - * identifiers. A property is always defined on a pair (\c TypeTag, - * \c PropertyTag) where \c TypeTag is the identifier for the object the - * property is defined for and \c PropertyTag is an unique identifier of - * the property. - * - * Type tags are hierarchic and inherit properties defined on their - * ancesters. At each level, properties defined on lower levels can be - * overwritten or even made undefined. - * - * Properties may use other properties for the respective type tag and - * these properties can also be defined on an arbitrary level of the - * hierarchy. The only restriction on this is that cycles are not - * allowed when defining properties. + * \ingroup Properties + * \ingroup TypeTraits + * \author Timo Koch + * \brief The Opm property system, traits with inheritance */ -#ifndef EWOMS_PROPERTIES_HH -#define EWOMS_PROPERTIES_HH +#ifndef OPM_PROPERTY_SYSTEM_HH +#define OPM_PROPERTY_SYSTEM_HH -#include -#include - -#include - -#include // required for 'is_base_of' -#include -#include -#include -#include -#include -#include -#include #include -#include - -//! \cond SKIP_THIS +#include +#include namespace Opm { namespace Properties { -#define EWOMS_GET_HEAD_(Arg1, ...) Arg1 +//! a tag to mark properties as undefined +struct UndefinedProperty {}; -#if !defined NO_PROPERTY_INTROSPECTION +template +struct Splices +{ + using type = std::tuple<>; +}; -//! Internal macro which is only required if the property introspection is enabled -#define PROP_INFO_(EffTypeTagName, PropKind, PropTagName, ...) \ - template <> \ - struct PropertyInfo \ - { \ - static int init() { \ - PropertyRegistryKey key( \ - /*effTypeTagName=*/ Dune::className(), \ - /*kind=*/PropKind, \ - /*name=*/propertyName(), \ - /*value=*/#__VA_ARGS__, \ - /*file=*/__FILE__, \ - /*line=*/__LINE__); \ - PropertyRegistry::addKey(key); \ - return 0; \ - } \ - static std::string propertyName() { return #PropTagName; } \ - }; \ - namespace fooPropInfo_ ## EffTypeTagName { \ - static const int foo_ ## PropTagName OPM_UNUSED = \ - PropertyInfo::init(); \ - } +//! implementation details for template meta programming +namespace Detail { + +//! check if a property P is defined +template +constexpr auto isDefinedProperty(int) +-> decltype(std::integral_constant::value>{}) +{ return {}; } + +//! fall back if a Property is defined +template +constexpr std::true_type isDefinedProperty(...) { return {}; } + +//! check if a TypeTag inherits from other TypeTags +//! the enable_if portion of decltype is only needed for the macro hack to work, if no macros are in use anymore it can be removed, +//! i.e. then trailing return type is then -> decltype(std::declval(), std::true_type{}) +template +constexpr auto hasParentTypeTag(int) +-> decltype(std::declval(), std::enable_if_t::value, int>{}, std::true_type{}) +{ return {}; } + +//! fall back if a TypeTag doesn't inherit +template +constexpr std::false_type hasParentTypeTag(...) { return {}; } + +//! helper alias to concatenate multiple tuples +template +using ConCatTuples = decltype(std::tuple_cat(std::declval()...)); + +//! helper struct to get the first property that is defined in the TypeTag hierarchy +template class Property, class TTagList> +struct GetDefined; + +//! helper struct to iterate over the TypeTag hierarchy +template class Property, class TTagList, class Enable> +struct GetNextTypeTag; + +template class Property, class LastTypeTag> +struct GetNextTypeTag, std::enable_if_t(int{}), void>> +{ using type = typename GetDefined::type; }; + +template class Property, class LastTypeTag> +struct GetNextTypeTag, std::enable_if_t(int{}), void>> +{ using type = UndefinedProperty; }; + +template class Property, class FirstTypeTag, class ...Args> +struct GetNextTypeTag, std::enable_if_t(int{}), void>> +{ using type = typename GetDefined>>::type; }; + +template class Property, class FirstTypeTag, class ...Args> +struct GetNextTypeTag, std::enable_if_t(int{}), void>> +{ using type = typename GetDefined>::type; }; + +template class Property, class LastTypeTag> +struct GetDefined> +{ +// For clang, the following alias triggers compiler warnings if instantiated +// from something like `GetPropType<..., DeprecatedProperty>`, even if that is +// contained in a diagnostic pragma construct that should prevent these warnings. +// As a workaround, also add the pragmas around this line. +// See the discussion in MR 1647 for more details. +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#endif + using LastType = Property; +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + using type = std::conditional_t(int{}), LastType, + typename GetNextTypeTag, void>::type>; +}; + +template class Property, class FirstTypeTag, class ...Args> +struct GetDefined> +{ +// See the comment above. +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#endif + using FirstType = Property; +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + using type = std::conditional_t(int{}), FirstType, + typename GetNextTypeTag, void>::type>; +}; -//! Internal macro which is only required if the property introspection is enabled -#define TTAG_INFO_(TagName, ...) \ - template <> \ - struct TypeTagInfo \ - { \ - static int init() { \ - TypeTagRegistry::addAllChildren(); \ - return 0; \ - } \ - }; \ - static const int fooTypeTagInfo_ ## TagName OPM_UNUSED = \ - TypeTagInfo::init(); +//! helper struct to get the first property that is defined in the TypeTag hierarchy +template +struct GetDefinedSplice; -//! Internal macro which is only required if the property introspection is enabled -#define SPLICE_INFO_(SpliceName, ...) \ - template <> \ - struct SpliceInfo \ - { \ - static int init() { \ - TypeTagRegistry::addAllSplices(); \ - return 0; \ - } \ - }; \ - static const int fooSpliceInfo_ ## SpliceName OPM_UNUSED = \ - SpliceInfo::init(); +//! helper struct to iterate over the TypeTag hierarchy +template +struct GetNextSpliceTypeTag; -#else -//! Don't do anything if introspection is disabled -#define PROP_INFO_(EffTypeTagName, PropKind, PropTagName, ...) -#define TTAG_INFO_(EffTypeTagName, ...) -#define SPLICE_INFO_(EffTypeTagName, ...) +template +struct GetNextSpliceTypeTag, std::enable_if_t(int{}), void>> +{ using type = typename GetDefinedSplice::type; }; + +template +struct GetNextSpliceTypeTag, std::enable_if_t(int{}), void>> +{ using type = std::tuple<>; }; + +template +struct GetNextSpliceTypeTag, std::enable_if_t(int{}), void>> +{ using type = typename GetDefinedSplice>>::type; }; + +template +struct GetNextSpliceTypeTag, std::enable_if_t(int{}), void>> +{ using type = typename GetDefinedSplice>::type; }; + +//! check if a splice S is defined +template +constexpr auto isDefinedSplice(int) +-> decltype(std::integral_constant>::value>{}) +{ return {}; } + +//! fall back if a splice is defined +template +constexpr std::true_type isDefinedSplice(...) { return {}; } + +template +struct GetDefinedSplice> +{ + using LastSplice = Splices; + using nexttuple = typename GetNextSpliceTypeTag, + typename LastSplice::type + >, + void>::type; + + using type = std::conditional_t(int{}), + ConCatTuples, + nexttuple>; +}; + +template +struct GetDefinedSplice> +{ + using FirstSplice = Splices; + using nexttuple = typename GetNextSpliceTypeTag, + typename FirstSplice::type + >, + void>::type; + + using type = std::conditional_t(int{}), + ConCatTuples, + nexttuple>; +}; + +//! helper struct to extract get the Property specilization given a TypeTag, asserts that the property is defined +template class Property> +struct GetPropImpl +{ + using tuple = typename Detail::GetDefinedSplice>::type; + using type = typename Detail::GetDefined, tuple> + >::type; + static_assert(!std::is_same::value, "Property is undefined!"); +}; + +template class Property> +struct GetSplicePropImpl +{ + using type = typename Detail::GetDefined>::type; + static_assert(!std::is_same>::value, "Splice is undefined!"); +}; + +} // end namespace Detail +} // end namespace Property + +//! get the type of a property (equivalent to old macro GET_PROP(...)) +template class Property> +using GetProp = typename Properties::Detail::GetPropImpl::type; + +// See the comment above. +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#endif +//! get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(...)) +template class Property> +using GetPropType = typename Properties::Detail::GetPropImpl::type::type; + +template class Property> +using GetSplicePropType = typename Properties::Detail::GetSplicePropImpl::type::type; + +//! get the value data member of a property +template class Property> +constexpr auto getPropValue() { return Properties::Detail::GetPropImpl::type::value; } +#ifdef __clang__ +#pragma clang diagnostic pop #endif -// some macros for simplification - -//! \endcond +namespace Properties { +template +void printValues(std::ostream& os = std::cout) +{ + os << + "The eWoms property system was compiled with the macro\n" + "NO_PROPERTY_INTROSPECTION defined.\n" + "No diagnostic messages this time, sorry.\n"; +} +} /*! * \ingroup Properties @@ -140,1070 +266,16 @@ namespace Properties { */ #define END_PROPERTIES }} -/*! - * \ingroup Properties - * \brief Convert a type tag name to a type - * - * The main advantage of the type of a \c TypeTag is that it can be - * passed as a template argument. - */ -#define TTAG(TypeTagName) Opm::Properties::TTag::TypeTagName +} // end namespace Opm -/*! - * \ingroup Properties - * \brief Makes a type out of a property tag name - * - * Again property type names can be passed as template argument. This - * is rarely needed, though. - */ -#define PTAG(PropTagName) Opm::Properties::PTag::PropTagName - -/*! - * \ingroup Properties - * \brief Define a new type tag. - * - * A type tag can inherit the properties defined on up to five parent - * type tags. Examples: - * - * \code - * // The type tag doesn't inherit any properties from other type tags - * NEW_TYPE_TAG(FooTypeTag); - * - * // BarTypeTag inherits all properties from FooTypeTag - * NEW_TYPE_TAG(BarTypeTag, INHERITS_FROM(FooTypeTag)); - * - * // FooBarTypeTag inherits the properties of FooTypeTag as well as - * // those of BarTypeTag. Properties defined on BarTypeTag have - * // preceedence over those defined for FooTypeTag: - * NEW_TYPE_TAG(FooBarTypeTag, INHERITS_FROM(FooTypeTag, BarTypeTag)); - * \endcode - */ -#define NEW_TYPE_TAG(...) \ - namespace TTag { \ - struct EWOMS_GET_HEAD_(__VA_ARGS__, dontcare) \ - : public TypeTag<__VA_ARGS__> \ - { }; \ - TTAG_INFO_(__VA_ARGS__, void) \ - } \ - extern int semicolonHack_ - -/*! - * \ingroup Properties - * \brief Define splices for a given type tag. - * - * Splices can be seen as children which can be overridden lower in - * the hierarchy. It can thus be seen as a "deferred inheritance" - * mechanism. Example: - * - * \code - * // First, define type tags for two different linear solvers: - * // BiCGStab and SuperLU. The first needs the "MaxIterations" - * // property, the second defines the "UsePivoting" property. - * NEW_TYPE_TAG(BiCGStabSolver); - * NEW_PROP_TAG(MaxIterations); - * SET_INT_PROP(BiCGStabSolver, MaxIterations, 100); - * - * NEW_TYPE_TAG(SuperLUSolver); - * NEW_PROP_TAG(UsePivoting); - * SET_BOOL_PROP(SuperLUSolver, UsePivoting, true); - * - * // The model type tag defines the splice 'LinearSolver' and sets it - * // to the 'BiCGStabSolver' type tag. - * NEW_TYPE_TAG(ModelTypeTag); - * NEW_PROP_TAG(LinearSolver); - * SET_SPLICES(ModelTypeTag, LinearSolver); - * SET_TAG_PROP(ModelTypeTag, LinearSolver, BiCGStabSolver); - * - * // The problem type tag is derived from the model type tag, but uses - * // the SuperLU solver. Since this is done using a splice, all properties - * // defined for the "SuperLUSolver" are inherited and the ones for the - * // BiCGStabSolver type tag are undefined - * NEW_TYPE_TAG(ProblemTypeTag, INHERITS_FROM(ModelTypeTag)); - * SET_TAG_PROP(ProblemTypeTag, LinearSolver, SuperLUSolver); - * \endcode - */ -#define SET_SPLICES(TypeTagName, ...) \ - namespace PTag { \ - template<> \ - struct Splices \ - { \ - typedef RevertedTuple<__VA_ARGS__>::type tuple; \ - }; \ - SPLICE_INFO_(TypeTagName, __VA_ARGS__) \ - } \ - extern int semicolonHack_ - -/*! - * \ingroup Properties - * \brief Syntactic sugar for NEW_TYPE_TAG. - * - * See the documentation for NEW_TYPE_TAG. - */ -#define INHERITS_FROM(...) __VA_ARGS__ - -/*! -// * \ingroup Properties - * \brief Define a property tag. - * - * A property tag is the unique identifier for a property. It may only - * be declared once in your program. There is also no hierarchy of - * property tags as for type tags. - * - * Examples: - * - * \code - * NEW_PROP_TAG(blubbPropTag); - * NEW_PROP_TAG(blabbPropTag); - * \endcode - */ -#define NEW_PROP_TAG(PTagName) \ - namespace PTag { \ - struct PTagName; } extern int semicolonHack_ - -//! \cond SKIP_THIS -#define SET_PROP_(EffTypeTagName, PropKind, PropTagName, ...) \ - template \ - struct Property; \ - PROP_INFO_(EffTypeTagName, \ - /*kind=*/PropKind, \ - PropTagName, \ - /*value=*/__VA_ARGS__) \ - template \ - struct Property -//! \endcond - -/*! - * \ingroup Properties - * \brief Set a property for a specific type tag. - * - * After this macro, you must to specify a complete body of a class - * template, including the trailing semicolon. If you need to retrieve - * another property within the class body, you can use \c TypeTag as the - * argument for the type tag for the \c GET_PROP macro. - * - * Example: - * - * \code - * SET_PROP(FooTypeTag, blubbPropTag) - * { - * static int value = 10; - * static int calculate(int arg) - * { calculateInternal_(arg); } - * - * private: - * // retrieve the blabbProp property for the TypeTag the - * // property is defined on. Note that blabbProb does not need to - * // be defined on FooTypeTag, but can also be defined for some - * // derived type tag. - * typedef typename GET_PROP(TypeTag, blabbProp) blabb; - * - * static int calculateInternal_(int arg) - * { return arg * blabb::value; }; - * \endcode - * }; - */ -#define SET_PROP(EffTypeTagName, PropTagName) \ - template \ - struct Property; \ - PROP_INFO_(EffTypeTagName, \ - /*kind=*/"opaque", \ - PropTagName, \ - /*value=*/"") \ - template \ - struct Property - -/*! - * \ingroup Properties - * \brief Explicitly unset a property for a type tag. - * - * This means that the property will not be inherited from the type - * tag's parents. - * - * Example: - * - * \code - * // make the blabbPropTag property undefined for the BarTypeTag. - * UNSET_PROP(BarTypeTag, blabbPropTag); - * \endcode - */ -#define UNSET_PROP(EffTypeTagName, PropTagName) \ - template <> \ - struct PropertyUnset; \ - PROP_INFO_(EffTypeTagName, \ - /*kind=*/"withdraw", \ - PropTagName, \ - /*value=*/) \ - template <> \ - struct PropertyUnset \ - : public PropertyExplicitlyUnset \ - {} - -/*! - * \ingroup Properties - * \brief Set a property to a simple constant integer value. - * - * The constant can be accessed by the \c value attribute. - */ -#define SET_INT_PROP(EffTypeTagName, PropTagName, /*Value*/...) \ - SET_PROP_(EffTypeTagName, \ - /*kind=*/"int ", \ - PropTagName, \ - /*value=*/__VA_ARGS__) \ - { \ - typedef int type; \ - static const int value = __VA_ARGS__; \ - } - -/*! - * \ingroup Properties - * \brief Set a property to a simple constant boolean value. - * - * The constant can be accessed by the \c value attribute. - */ -#define SET_BOOL_PROP(EffTypeTagName, PropTagName, /*Value*/...) \ - SET_PROP_(EffTypeTagName, \ - /*kind=*/"bool ", \ - PropTagName, \ - /*value=*/__VA_ARGS__) \ - { \ - typedef bool type; \ - static const bool value = __VA_ARGS__; \ - } - -/*! - * \ingroup Properties - * \brief Set a property which defines a type. - * - * The type can be accessed by the \c type attribute. - */ -#define SET_TYPE_PROP(EffTypeTagName, PropTagName, /*Value*/...) \ - SET_PROP_(EffTypeTagName, \ - /*kind=*/"type ", \ - PropTagName, \ - /*value=*/__VA_ARGS__) \ - { \ - typedef __VA_ARGS__ type; \ - } - -/*! - * \ingroup Properties - * \brief This macro provides the boiler plate code to declare a static constant member - * outside of a property definition. - * - * This macro is fairly low-level and there should rarely be a need to use it. - */ -#define PROP_STATIC_CONST_MEMBER_DEFINITION_PREFIX_(EffTypeTagName, PropTagName) \ - template \ - const typename Property::type \ - Property - -/*! - * \ingroup Properties - * \brief This macro provides the boiler plate code to declare a static member outside of - * a property definition. - * - * This macro is fairly low-level and there should rarely be a need to use it. - */ -#define PROP_STATIC_MEMBER_DEFINITION_PREFIX_(EffTypeTagName, PropTagName) \ - template \ - typename Property::type \ - Property - -/*! - * \ingroup Properties - * \brief Set a property to a simple constant scalar value. - * - * The constant can be accessed by the \c value attribute. In order to - * use this macro, the property tag \c Scalar needs to be defined for - * the type tag. - */ -#define SET_SCALAR_PROP(EffTypeTagName, PropTagName, ...) \ - SET_PROP_(EffTypeTagName, \ - /*kind=*/"scalar", \ - PropTagName, \ - /*value=*/__VA_ARGS__) \ - { \ - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; \ - public: \ - typedef Scalar type; \ - static const Scalar value; \ - }; \ - PROP_STATIC_CONST_MEMBER_DEFINITION_PREFIX_(EffTypeTagName, PropTagName)::value(__VA_ARGS__) - -/*! - * \ingroup Properties - * \brief Set a property to a simple constant string value. - * - * The constant can be accessed by the \c value attribute and is of - * type std::string. - */ -#define SET_STRING_PROP(EffTypeTagName, PropTagName, ...) \ - SET_PROP_(EffTypeTagName, \ - /*kind=*/"string", \ - PropTagName, \ - /*value=*/__VA_ARGS__) \ - { \ - public: \ - typedef std::string type; \ - static const std::string value; \ - }; \ - PROP_STATIC_CONST_MEMBER_DEFINITION_PREFIX_(EffTypeTagName, PropTagName)::value(__VA_ARGS__) - -/*! - * \ingroup Properties - * \brief Define a property containing a type tag. - * - * This is convenient for splices. - */ -#define SET_TAG_PROP(EffTypeTagName, PropTagName, ValueTypeTagName) \ - SET_PROP_(EffTypeTagName, \ - /*kind=*/"tag ", \ - PropTagName, \ - /*value=*/TTAG(ValueTypeTagName)) \ - { \ - typedef TTAG(ValueTypeTagName) type; \ - } - - -/*! - * \ingroup Properties - * \brief Retrieve a property for a type tag. - * - * If you use \c GET_PROP within a template and want to refer to some - * type (including the property itself), \c GET_PROP must be preceeded by - * the '\c typename' keyword. - */ -#define GET_PROP(TypeTag, PropTagName) \ - ::Opm::Properties::GetProperty::p -//!\cond SKIP_THIS -#define GET_PROP_(TypeTag, PropTag) \ - ::Opm::Properties::GetProperty::p -//!\endcond - -/*! - * \ingroup Properties - * \brief Access the \c value attribute of a property for a type tag. - * - * This is just for convenience and equivalent to - * GET_PROP(TypeTag, PropTag)::value . If the property doesn't - * have an attribute named \c value, this yields a compiler error. - */ -#define GET_PROP_VALUE(TypeTag, PropTagName) \ - ::Opm::Properties::GetProperty::p::value -//!\cond SKIP_THIS -#define GET_PROP_VALUE_(TypeTag, PropTag) \ - ::Opm::Properties::GetProperty::p::value -//!\endcond - -/*! - * \ingroup Properties - * \brief Access the \c type attribute of a property for a type tag. - * - * This is just for convenience and equivalent to - * GET_PROP(TypeTag, PropTag)::type. If the property doesn't - * have an attribute named \c type, this yields a compiler error. Also, - * if you use this macro within a template, it must be preceeded by - * the \c typename keyword. - */ -#define GET_PROP_TYPE(TypeTag, PropTagName) \ - ::Opm::Properties::GetProperty::p::type -//!\cond SKIP_THIS -#define GET_PROP_TYPE_(TypeTag, PropTag) \ - ::Opm::Properties::GetProperty::p::type -//!\endcond - -#if !defined NO_PROPERTY_INTROSPECTION -/*! - * \ingroup Properties - * \brief Return a human readable diagnostic message how exactly a - * property was defined. - * - * This is only enabled if the \c NO_PROPERTY_INTROSPECTION macro is not - * defined. - * - * Example: - * - * \code - * int main() - * { - * std::cout << PROP_DIAGNOSTIC(FooBarTypeTag, blabbPropTag) << "\n"; - * }; - * \endcode - */ -#define PROP_DIAGNOSTIC(TypeTag, PropTagName) \ - ::Opm::Properties::getDiagnostic(#PropTagName) - -#else -#define PROP_DIAGNOSTIC(TypeTag, PropTagName) "Property introspection disabled by macro NO_PROPERTY_INTROSPECTION." +// remove this after release 2020.10 to disable macros per default +#ifndef OPM_ENABLE_OLD_PROPERTY_MACROS +#define OPM_ENABLE_OLD_PROPERTY_MACROS 1 #endif -////////////////////////////////////////////// -// some serious template kung fu. Don't look at it too closely, it -// might damage your brain! -////////////////////////////////////////////// - -//! \cond SKIP_THIS - -namespace PTag {} -namespace TTag {} - -#if !defined NO_PROPERTY_INTROSPECTION - -namespace TTag -{ -template -struct TypeTagInfo -{}; -} - -namespace PTag -{ -template -struct SpliceInfo -{}; -} - -template -struct PropertyInfo -{}; - -class PropertyRegistryKey -{ -public: - PropertyRegistryKey() - {} - - PropertyRegistryKey(const std::string& effTypeTagName, - const std::string& propertyKind, - const std::string& propertyName, - const std::string& propertyValue, - const std::string& fileDefined, - int lineDefined) - : effTypeTagName_(effTypeTagName) - , propertyKind_(propertyKind) - , propertyName_(propertyName) - , propertyValue_(propertyValue) - , fileDefined_(fileDefined) - , lineDefined_(lineDefined) - { } - - // copy constructor - PropertyRegistryKey(const PropertyRegistryKey&) = default; - PropertyRegistryKey& operator=(const PropertyRegistryKey&) = default; - - const std::string& effTypeTagName() const - { return effTypeTagName_; } - const std::string& propertyKind() const - { return propertyKind_; } - const std::string& propertyName() const - { return propertyName_; } - const std::string& propertyValue() const - { return propertyValue_; } - const std::string& fileDefined() const - { return fileDefined_; } - int lineDefined() const - { return lineDefined_; } - -private: - std::string effTypeTagName_; - std::string propertyKind_; - std::string propertyName_; - std::string propertyValue_; - std::string fileDefined_; - int lineDefined_; -}; - - -template -struct GetProperty; - -class TypeTagRegistry -{ -public: - struct SpliceRegistryEntry { - SpliceRegistryEntry(const std::string& name) - { name_ = name; } - - std::string propertyName() const - { return name_; } - - private: - std::string name_; - }; - - typedef std::list > SpliceList; - typedef std::map SpliceListMap; - - typedef std::list ChildrenList; - typedef std::map ChildrenListMap; - - // this method adds the children of a type tag to the registry if the registry does - // not yet contain an entry for that type tag - template - static void addAllChildren() - { - std::string typeTagName = Dune::className(); - - if (children_().find(typeTagName) == children_().end()) - addChildren(); - } - - - // end of recursion. the last argument is not a child, but 'void' - // which is required for the macro magic... - template - static void addChildren() - {} - - // the last argument is not a child, but 'void' which is required - // for the macro magic... - template - static void addChildren() - { - std::string typeTagName = Dune::className(); - - children_()[typeTagName].emplace_front(Dune::className()); - - addChildren(); - } - - // this method adds the splices of a type tag to the registry if the registry does - // not yet contain an entry for that type tag - template - static void addAllSplices() - { - std::string typeTagName = Dune::className(); - - if (splices_().find(typeTagName) == splices_().end()) - addSplices(); - } - - - // end of recursion. the last argument is not a child, but 'void' - // which is required for the macro magic... - template - static void addSplices() - { } - - // the last argument is not a child, but 'void' which is required - // for the macro magic... - template - static void addSplices() - { - const std::string& typeTagName = Dune::className(); - const std::string& propName = - PropertyInfo::template GetEffectiveTypeTag_::type, Splice1>::propertyName(); - - splices_()[typeTagName].emplace_front(new SpliceRegistryEntry(propName)); - - addSplices(); - } - - static const SpliceList& splices(const std::string& typeTagName) - { return splices_()[typeTagName]; } - - static const ChildrenList& children(const std::string& typeTagName) - { return children_()[typeTagName]; } - -private: - static SpliceListMap& splices_() - { - static SpliceListMap data; - return data; - } - static ChildrenListMap& children_() - { - static ChildrenListMap data; - return data; - } -}; - -class PropertyRegistry -{ - typedef Opm::Properties::TypeTagRegistry TypeTagRegistry; - -public: - typedef std::map KeyList; - typedef std::map KeyListMap; - - static void addKey(const PropertyRegistryKey& key) - { - keys_()[key.effTypeTagName()][key.propertyName()] = key; - } - - static const std::string& getSpliceTypeTagName(const std::string& typeTagName, - const std::string& propertyName) - { - const auto& keyIt = keys_().find(typeTagName); - const auto& keyEndIt = keys_().end(); - if (keyIt == keyEndIt) - throw std::runtime_error("Unknown type tag key '"+typeTagName+"'"); - - // check whether the propery is directly defined for the type tag currently - // checked, ... - const auto& propIt = keyIt->second.find(propertyName); - const auto& propEndIt = keyIt->second.end(); - if (propIt != propEndIt) - return propIt->second.propertyValue(); - - // ..., if not, check all splices, ... - typedef typename TypeTagRegistry::SpliceList SpliceList; - const SpliceList& splices = TypeTagRegistry::splices(typeTagName); - SpliceList::const_iterator spliceIt = splices.begin(); - for (; spliceIt != splices.end(); ++spliceIt) { - const auto& spliceTypeTagName = - PropertyRegistry::getSpliceTypeTagName(typeTagName, - (*spliceIt)->propertyName()); - - if (spliceTypeTagName == "") - continue; - - const auto& tmp = getSpliceTypeTagName(spliceTypeTagName, propertyName); - if (tmp != "") - return tmp; - } - - // .. if still not, check all normal children. - typedef TypeTagRegistry::ChildrenList ChildrenList; - const ChildrenList& children = TypeTagRegistry::children(typeTagName); - ChildrenList::const_iterator ttagIt = children.begin(); - for (; ttagIt != children.end(); ++ttagIt) { - const auto& tmp = getSpliceTypeTagName(*ttagIt, propertyName); - if (tmp != "") - return tmp; - } - - // if the property was not defined on a given type tag, return - // the empty string. - static std::string tmp(""); - return tmp; - } - - static const PropertyRegistryKey& getKey(const std::string& effTypeTagName, - const std::string& propertyName) - { return keys_()[effTypeTagName][propertyName]; } - - static const KeyList& getKeys(const std::string& effTypeTagName) - { return keys_()[effTypeTagName]; } - -private: - static KeyListMap& keys_() - { - static KeyListMap data; - return data; - } -}; - -#endif // !defined NO_PROPERTY_INTROSPECTION - -struct PropertyUndefined { }; -class PropertyExplicitlyUnset {}; - -template -struct Property : public PropertyUndefined -{}; - -template -struct PropertyUnset : public PropertyUndefined -{}; - -template -struct propertyExplicitlyUnset -{ - const static bool value = - std::is_base_of - >::value; -}; - -template -class propertyExplicitlyUnsetOnTree -{ - static const bool explicitlyUnset = propertyExplicitlyUnset::value; - - template - struct unsetOnAllChildren - { static const bool value = true; }; - - template - struct unsetOnAllChildren > - { static const bool value = - propertyExplicitlyUnsetOnTree::value - && unsetOnAllChildren >::value; }; - -public: - static const bool value = - (explicitlyUnset || (!Tree::isLeaf && unsetOnAllChildren::value)); -}; - -template -struct propertyExplicitlyUnsetOnTree -{ - const static bool value = std::true_type::value; -}; - -template -struct propertyDefinedOnSelf -{ - const static bool value = - ! std::is_base_of >::value; -}; - -// template class to revert the order or a std::tuple's arguments. This is required to -// make the properties of children defined on the right overwrite the properties of the -// children on the left. See https://sydius.me/2011/07/reverse-tuple-in-c/ -template -class RevertedTuple -{ -private: - template - struct RevertedTupleOuter - { - template - struct RevertedTupleInner: RevertedTupleOuter::template RevertedTupleInner { }; - }; - - template - struct RevertedTupleOuter<0, All...> - { - template - struct RevertedTupleInner { - typedef std::tuple type; - }; - }; - -public: - typedef typename RevertedTupleOuter::template RevertedTupleInner::type type; -}; - -template -class TypeTag -{ -public: - typedef SelfT SelfType; - - typedef typename RevertedTuple::type ChildrenTuple; - static const bool isLeaf = std::is_same >::value; -}; - -namespace PTag { -// this class needs to be located in the PTag namespace for reasons -// you don't really want to know... -template -struct Splices -{ - typedef typename std::tuple<> tuple; -}; -} // namespace PTag - -template -struct GetProperty -{ - // find the type tag for which the property is defined - template ::value> - struct GetEffectiveTypeTag_ - { typedef typename CurTree::SelfType type; }; - - template - struct SearchTypeTagList_; - - template - struct SearchTypeTagList_FirstThenRemaining_; - - template - struct SearchSpliceList_; - - template - struct SearchSpliceList_FirstThenRemaining_; - - // find the first type tag in a tuple for which the property is - // defined - template - struct SearchTypeTagTuple_ - { typedef void type; }; - - template - struct SearchTypeTagTuple_ > - { typedef typename SearchTypeTagList_::type type; }; - - template - struct SearchTypeTagList_ - { typedef void type; }; - - template - struct SearchTypeTagList_ - { - typedef typename SearchTypeTagList_FirstThenRemaining_< - typename GetEffectiveTypeTag_::type, - RemainingElements...>::type type; - }; - - template - struct SearchTypeTagList_FirstThenRemaining_ - { typedef EffectiveTypeTag type; }; - - template - struct SearchTypeTagList_FirstThenRemaining_ - { typedef typename SearchTypeTagList_::type type; }; - - // find the first type tag in a tuple of splices for which the - // property is defined - template - struct SearchSpliceTuple_ - { typedef void type; }; - - template - struct SearchSpliceTuple_ > - { typedef typename SearchSpliceList_::type type; }; - - template - struct SearchSpliceList_ - { typedef void type; }; - - template - struct SearchSpliceList_ - { - typedef typename SearchSpliceList_FirstThenRemaining_< - typename GetEffectiveTypeTag_::p::type>::type, - RemainingSplices...>::type type; - }; - - template - struct SearchSpliceList_FirstThenRemaining_ - { typedef EffectiveTypeTag type; }; - - template - struct SearchSpliceList_FirstThenRemaining_ - { typedef typename SearchSpliceList_::type type; }; - - // find the splice or the child type tag for which the property is defined - template ::tuple >::type > - struct SearchSplicesThenChildren_ - { typedef SpliceTypeTag type; }; - - template - struct SearchSplicesThenChildren_ - { typedef typename SearchTypeTagTuple_::type type; }; - - template - struct GetEffectiveTypeTag_ - { typedef typename SearchSplicesThenChildren_::type type; }; - -public: - typedef Property::type, PropertyTag> p; -}; - -#if !defined NO_PROPERTY_INTROSPECTION -inline int myReplaceAll_(std::string& s, - const std::string& pattern, - const std::string& replacement); -inline int myReplaceAll_(std::string& s, - const std::string& pattern, - const std::string& replacement) -{ - size_t pos; - int i = 0; - while ( (pos = s.find(pattern)) != s.npos) { - s.replace(pos, pattern.size(), replacement); - ++i; - }; - return i; -} - -inline std::string canonicalTypeTagNameToName_(const std::string& canonicalName); -inline std::string canonicalTypeTagNameToName_(const std::string& canonicalName) -{ - std::string result(canonicalName); - myReplaceAll_(result, "Opm::Properties::TTag::", "TTAG("); - myReplaceAll_(result, "::", ""); - result += ")"; - return result; -} - -inline bool getDiagnostic_(const std::string& typeTagName, - const std::string& propTagName, - std::string& result, - const std::string indent) -{ - const PropertyRegistryKey *key = 0; - - const typename PropertyRegistry::KeyList& keys = - PropertyRegistry::getKeys(typeTagName); - typename PropertyRegistry::KeyList::const_iterator it = keys.begin(); - for (; it != keys.end(); ++it) { - if (it->second.propertyName() == propTagName) { - key = &it->second; - break; - }; - } - - if (key) { - std::ostringstream oss; - oss << indent - << key->propertyKind() << " " - << key->propertyName() << " defined on '" - << canonicalTypeTagNameToName_(key->effTypeTagName()) << "' at " - << key->fileDefined() << ":" << key->lineDefined() << "\n"; - result = oss.str(); - return true; - } - - // print properties defined on children - typedef typename TypeTagRegistry::ChildrenList ChildrenList; - const ChildrenList& children = TypeTagRegistry::children(typeTagName); - ChildrenList::const_iterator ttagIt = children.begin(); - std::string newIndent = indent + " "; - for (; ttagIt != children.end(); ++ttagIt) { - if (getDiagnostic_(*ttagIt, propTagName, result, newIndent)) { - result.insert(0, indent + "Inherited from " + canonicalTypeTagNameToName_(typeTagName) + "\n"); - return true; - } - } - - return false; -} - -template -const std::string getDiagnostic(std::string propTagName) -{ - std::string result; - - std::string TypeTagName(Dune::className()); - - propTagName.replace(0, strlen("PTag("), ""); - auto n = propTagName.length(); - propTagName.replace(n - 1, 1, ""); - //TypeTagName.replace(0, strlen("Opm::Properties::TTag::"), ""); - - return result; -} - -inline void print_(const std::string& rootTypeTagName, - const std::string& curTypeTagName, - const std::string& splicePropName, - std::ostream& os, - const std::string indent, - std::set& printedProperties) -{ - if (indent == "") { - os << indent << "###########\n"; - os << indent << "# Properties\n"; - os << indent << "###########\n"; - os << indent << "Properties for " << canonicalTypeTagNameToName_(curTypeTagName) << ":"; - } - else if (splicePropName != "") - os << indent << "Inherited from splice " << splicePropName << " (set to " << canonicalTypeTagNameToName_(curTypeTagName) << "):"; - else - os << indent << "Inherited from " << canonicalTypeTagNameToName_(curTypeTagName) << ":"; - const typename PropertyRegistry::KeyList& keys = - PropertyRegistry::getKeys(curTypeTagName); - typename PropertyRegistry::KeyList::const_iterator it = keys.begin(); - bool somethingPrinted = false; - for (; it != keys.end(); ++it) { - const PropertyRegistryKey& key = it->second; - if (printedProperties.count(key.propertyName()) > 0) - continue; // property already printed - if (!somethingPrinted) { - os << "\n"; - somethingPrinted = true; - } - os << indent << " " - << key.propertyKind() << " " << key.propertyName(); - if (key.propertyKind() != "opaque") { - std::string s(key.propertyValue()); - myReplaceAll_(s, "typename ", ""); - if (myReplaceAll_(s, "::Opm::Properties::TTag::", "TTAG(")) - s += ')'; - myReplaceAll_(s, "::Opm::Properties::PTag::", ""); - myReplaceAll_(s, "::Opm::Properties::GetProperty<", "GET_PROP("); - myReplaceAll_(s, ">::p::", ")::"); - myReplaceAll_(s, "GET_PROP(TypeTag, Scalar)::type", "Scalar"); - - os << " = '" << s << "'"; - } - os << " defined at " << key.fileDefined() - << ":" << key.lineDefined() - << "\n"; - printedProperties.insert(key.propertyName()); - }; - if (!somethingPrinted) - os << " (none)\n"; - // print properties defined on splices or children - std::string newIndent = indent + " "; - - // first, iterate over the splices, ... - typedef TypeTagRegistry::SpliceList SpliceList; - const SpliceList& splices = TypeTagRegistry::splices(curTypeTagName); - SpliceList::const_iterator spliceIt = splices.begin(); - for (; spliceIt != splices.end(); ++ spliceIt) { - const auto& spliceTypeTagName = PropertyRegistry::getSpliceTypeTagName(rootTypeTagName, - (*spliceIt)->propertyName()); - print_(rootTypeTagName, spliceTypeTagName, (*spliceIt)->propertyName(), os, newIndent, printedProperties); - } - - // ... then, over the children - typedef typename TypeTagRegistry::ChildrenList ChildrenList; - const ChildrenList& children = TypeTagRegistry::children(curTypeTagName); - ChildrenList::const_iterator ttagIt = children.begin(); - for (; ttagIt != children.end(); ++ttagIt) { - print_(rootTypeTagName, *ttagIt, /*splicePropName=*/"", os, newIndent, printedProperties); - } -} - -template -void printValues(std::ostream& os = std::cout) -{ - std::set printedProps; - print_(Dune::className(), Dune::className(), /*splicePropertyName=*/"", os, /*indent=*/"", printedProps); -} -#else // !defined NO_PROPERTY_INTROSPECTION -template -void printValues(std::ostream& os = std::cout) -{ - os << - "The eWoms property system was compiled with the macro\n" - "NO_PROPERTY_INTROSPECTION defined.\n" - "No diagnostic messages this time, sorry.\n"; -} - -template -const std::string getDiagnostic(std::string propTagName) -{ - std::string result; - result = - "The eWoms property system was compiled with the macro\n" - "NO_PROPERTY_INTROSPECTION defined.\n" - "No diagnostic messages this time, sorry.\n"; - return result; -} - -#endif // !defined NO_PROPERTY_INTROSPECTION - -//! \endcond - -} // namespace Properties -} // namespace Opm +// remove this after release 2021.04 to remove macros completely +#if OPM_ENABLE_OLD_PROPERTY_MACROS +#include +#endif // OPM_ENABLE_OLD_PROPERTY_MACROS #endif diff --git a/opm/models/utils/propertysystemmacros.hh b/opm/models/utils/propertysystemmacros.hh new file mode 100644 index 000000000..1746f8200 --- /dev/null +++ b/opm/models/utils/propertysystemmacros.hh @@ -0,0 +1,378 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTBILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *****************************************************************************/ +/*! + * \file + * \ingroup Properties + * \brief Provides the magic behind the DuMuX property system. + * + * Properties allow to associate arbitrary data types to + * identifiers. A property is always defined on a pair (TypeTag, + * PropertyTag) where TypeTag is the identifier for the object the + * property is defined for and PropertyTag is an unique identifier of + * the property. + * + * Type tags are hierarchic and inherit properties defined on their + * ancesters. At each level, properties defined on lower levels can be + * overwritten or even made undefined. It is also possible to define + * defaults for properties if it makes sense. + * + * Properties may make use other properties for the respective type + * tag and these properties can also be defined on an arbitrary level + * of the hierarchy. + */ +#ifndef OPM_PROPERTY_SYSTEM_MACROS_HH +#define OPM_PROPERTY_SYSTEM_MACROS_HH +#warning "Property macros are deprecated and will be removed after release 2021.04. \ +If you are not using property macros you can disable this warning by \ +setting OPM_ENABLE_OLD_PROPERTY_MACROS to 0 (false) when configuring OPM. \ +OPM_ENABLE_OLD_PROPERTY_MACROS defaults to 1 (true) until release 2020.10. \ +After release 2020.10 it will default to 0 (false) so you will have to manually \ +enable property macros in order to use them." + +#include + +namespace Opm { +namespace Properties { + +namespace TTag {} + +/*! + * \brief Makes a type out of a type tag name + */ +#define TTAG(TypeTagName) ::Opm::Properties::TTag::TypeTagName + +/*! + * \brief Makes a type out of a property tag name + */ +//#define PTAG(PropTagName) PropTagName + +/*! + * \brief Makes a type out of a property tag name + */ +#define PTAG_(PropTagName) ::Opm::Properties::PropTagName + + +// in the old property system the order in inherit_from was the other way around +// this flips the order of a tuple to restore old behaviour when using the macro. +// when you are using non-macro version make sure to flip the order. +template +struct ReverseTupleImpl; + +template +struct ReverseTupleImpl> +{ + using type = std::tuple...>; +}; + +// revert tuple argument order +template +using ReverseTuple = typename ReverseTupleImpl::value>>::type; + +// a temporary hack to make the macro still work, we set using InheritsFrom = void, +// which gets picked up by the new property as non inheritance, this can be removed +// once all macros are gone +namespace Detail { +template +struct GetTypeTagInheritance; + +template +struct GetTypeTagInheritance> +{ + using type = void; +}; + +template +struct GetTypeTagInheritance> +{ + // reverse order to restore old behaviour + using type = ReverseTuple>; +}; +} // end namespace Detail + +/*! + * \ingroup Properties + * \brief Define a new type tag. + * + * A type tag can inherit the properties defined on up to five parent + * type tags. Examples: + * + * \code + * // The type tag doesn't inherit any properties from other type tags + * NEW_TYPE_TAG(FooTypeTag); + * + * // BarTypeTag inherits all properties from FooTypeTag + * NEW_TYPE_TAG(BarTypeTag, INHERITS_FROM(FooTypeTag)); + * + * // FooBarTypeTag inherits the properties of FooTypeTag as well as + * // those of BarTypeTag. Properties defined on BarTypeTag have + * // preceedence over those defined for FooTypeTag: + * NEW_TYPE_TAG(FooBarTypeTag, INHERITS_FROM(FooTypeTag, BarTypeTag)); + * \endcode + */ +#define OPM_GET_HEAD_(Arg1, ...) Arg1 + +#define NEW_TYPE_TAG(...) \ + namespace TTag { \ + struct OPM_GET_HEAD_(__VA_ARGS__) \ + { using InheritsFrom = Detail::GetTypeTagInheritance>::type; }; \ + } extern int semicolonHack_ + +/*! + * \ingroup Properties + * \brief Syntactic sugar for NEW_TYPE_TAG. + * + * See the documentation for NEW_TYPE_TAG. + */ +#define INHERITS_FROM(...) __VA_ARGS__ + +/*! + * \ingroup Properties + * \brief Define a property tag. + * + * A property tag is the unique identifier for a property. It may only + * be declared once in your program. There is also no hierarchy of + * property tags as for type tags. + * + * Examples: + * + * \code + * NEW_PROP_TAG(blubbPropTag); + * NEW_PROP_TAG(blabbPropTag); + * \endcode + */ +#define NEW_PROP_TAG(PTagName) \ + template \ + struct PTagName { using type = UndefinedProperty; }; \ + extern int semicolonHack_ + +/*! + * \ingroup Properties + * \brief Set a property for a specific type tag. + * + * After this macro, you must to specify a complete body of a class + * template, including the trailing semicolon. If you need to retrieve + * another property within the class body, you can use TypeTag as the + * argument for the type tag for the GET_PROP macro. + * + * Example: + * + * \code + * SET_PROP(FooTypeTag, blubbPropTag) + * { + * static int value = 10; + * static int calculate(int arg) + * { calculateInternal_(arg); } + * + * private: + * // retrieve the blabbProp property for the real TypeTag the + * // property is defined on. Note that blabbProb does not need to + * // be defined on FooTypeTag, but can also be defined for some + * // derived type tag. + * using blabb = typename GET_PROP(TypeTag, blabbProp); + * + * static int calculateInternal_(int arg) + * { return arg * blabb::value; }; + * \endcode + * }; + */ +#define SET_PROP(EffTypeTagName, PropTagName) \ + template \ + struct PropTagName + +/*! + * \ingroup Properties + * \brief Set a property to a simple constant integer value. + * + * The constant can be accessed by the 'value' attribute. + */ +#define SET_INT_PROP(EffTypeTagName, PropTagName, /*Value*/...) \ + template \ + struct PropTagName \ + { \ + using type = int; \ + static constexpr int value = __VA_ARGS__; \ + } + +/*! + * \ingroup Properties + * \brief Set a property to a simple constant boolean value. + * + * The constant can be accessed by the 'value' attribute. + */ +#define SET_BOOL_PROP(EffTypeTagName, PropTagName, /*Value*/...) \ + template \ + struct PropTagName \ + { \ + using type = bool; \ + static constexpr bool value = __VA_ARGS__; \ + } + +/*! + * \ingroup Properties + * \brief Set a property which defines a type. + * + * The type can be accessed by the 'type' attribute. + */ +#define SET_TYPE_PROP(EffTypeTagName, PropTagName, /*Value*/...) \ + template \ + struct PropTagName \ + { \ + using type = __VA_ARGS__; \ + } + +template +struct Scalar; + +/*! + * \ingroup Properties + * \brief Set a property to a simple constant scalar value. + * + * The constant can be accessed by the 'value' attribute. In order to + * use this macro, the property tag "Scalar" needs to be defined for + * the real type tag. + */ +#define SET_SCALAR_PROP(EffTypeTagName, PropTagName, ...) \ + template \ + struct PropTagName \ + { \ + using Scalar = Opm::GetPropType; \ + public: \ + using type = Scalar; \ + static const Scalar value; \ + }; \ + template \ + const typename PropTagName::type \ + PropTagName::value(__VA_ARGS__) + +/*! + * \ingroup Properties + * \brief Set a property to a simple constant string value. + * + * The constant can be accessed by the 'value' attribute and is of + * type std::string. + */ +#define SET_STRING_PROP(EffTypeTagName, PropTagName, ...) \ + template \ + struct PropTagName \ + { \ + public: \ + using type = std::string; \ + static const std::string value; \ + }; \ + template \ + const typename PropTagName::type \ + PropTagName::value(__VA_ARGS__) + + +// getters +#define GET_PROP(TypeTag, PropTagName) ::Opm::Properties::Detail::GetPropImpl::type +#define GET_PROP_VALUE(TypeTag, PropTagName) ::Opm::Properties::Detail::GetPropImpl::type::value +#define GET_PROP_TYPE(TypeTag, PropTagName) ::Opm::Properties::Detail::GetPropImpl::type::type + +/*! + * \ingroup Properties + * \brief Define splices for a given type tag. + * + * Splices can be seen as children which can be overridden lower in + * the hierarchy. It can thus be seen as a "deferred inheritance" + * mechanism. Example: + * + * \code + * // First, define type tags for two different linear solvers: + * // BiCGStab and SuperLU. The first needs the "MaxIterations" + * // property, the second defines the "UsePivoting" property. + * NEW_TYPE_TAG(BiCGStabSolver); + * NEW_PROP_TAG(MaxIterations); + * SET_INT_PROP(BiCGStabSolver, MaxIterations, 100); + * + * NEW_TYPE_TAG(SuperLUSolver); + * NEW_PROP_TAG(UsePivoting); + * SET_BOOL_PROP(SuperLUSolver, UsePivoting, true); + * + * // The model type tag defines the splice 'LinearSolver' and sets it + * // to the 'BiCGStabSolver' type tag. + * NEW_TYPE_TAG(ModelTypeTag); + * NEW_PROP_TAG(LinearSolver); + * SET_SPLICES(ModelTypeTag, LinearSolver); + * SET_TAG_PROP(ModelTypeTag, LinearSolver, BiCGStabSolver); + * + * // The problem type tag is derived from the model type tag, but uses + * // the SuperLU solver. Since this is done using a splice, all properties + * // defined for the "SuperLUSolver" are inherited and the ones for the + * // BiCGStabSolver type tag are undefined + * NEW_TYPE_TAG(ProblemTypeTag, INHERITS_FROM(ModelTypeTag)); + * SET_TAG_PROP(ProblemTypeTag, LinearSolver, SuperLUSolver); + * \endcode + */ + +#define SET_ONE_SPLICE(TypeTagName, SpliceName) \ +template \ +struct Splices \ +{ \ + using type = std::tuple>; \ +}; \ +extern int semicolonHack_ + +#define SET_TWO_SPLICES(TypeTagName, SpliceName1, SpliceName2) \ +template \ +struct Splices \ +{ \ + using type = std::tuple, \ + GetSplicePropType>; \ +}; \ +extern int semicolonHack_ + +#define SET_THREE_SPLICES(TypeTagName, SpliceName1, SpliceName2, SpliceName3) \ +template \ +struct Splices \ +{ \ + using type = std::tuple, \ + GetSplicePropType, \ + GetSplicePropType>; \ +}; \ +extern int semicolonHack_ + +// From https://stackoverflow.com/questions/11761703/overloading-macro-on-number-of-arguments +#define GET_MACRO(_1, _2, _3, _4, NAME, ...) NAME +#define SET_SPLICES(...) GET_MACRO(__VA_ARGS__, SET_THREE_SPLICES, SET_TWO_SPLICES, SET_ONE_SPLICE)(__VA_ARGS__) + +#define SET_PROP_(EffTypeTagName, PropKind, PropTagName, ...) \ +template \ +struct PropTagName + + +/*! + * \ingroup Properties + * \brief Define a property containing a type tag. + * + * This is convenient for splices. +*/ +#define SET_TAG_PROP(EffTypeTagName, PropTagName, ValueTypeTagName) \ +SET_PROP_(EffTypeTagName, \ + /*kind=*/"tag ", \ + PropTagName, \ + /*value=*/TTAG(ValueTypeTagName)) \ +{ \ + typedef TTAG(ValueTypeTagName) type; \ +} + +} // namespace Properties +} // namespace Opm + +#endif // OPM_PROPERTY_SYSTEM_HH diff --git a/opm/models/utils/simulator.hh b/opm/models/utils/simulator.hh index 11f8b850d..207623e4b 100644 --- a/opm/models/utils/simulator.hh +++ b/opm/models/utils/simulator.hh @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -46,20 +47,6 @@ #include #include -BEGIN_PROPERTIES - -NEW_PROP_TAG(Scalar); -NEW_PROP_TAG(Vanguard); -NEW_PROP_TAG(GridView); -NEW_PROP_TAG(Model); -NEW_PROP_TAG(Problem); -NEW_PROP_TAG(EndTime); -NEW_PROP_TAG(RestartTime); -NEW_PROP_TAG(InitialTimeStepSize); -NEW_PROP_TAG(PredeterminedTimeStepsFile); - -END_PROPERTIES - #define EWOMS_CATCH_PARALLEL_EXCEPTIONS_FATAL(code) \ { \ const auto& comm = Dune::MPIHelper::getCollectiveCommunication(); \ @@ -984,6 +971,11 @@ private: bool finished_; bool verbose_; }; + +namespace Properties { +SET_TYPE_PROP(NumericModel, Simulator, Opm::Simulator); +} + } // namespace Opm #endif diff --git a/opm/models/utils/start.hh b/opm/models/utils/start.hh index 92af8ab9c..7ff3fc778 100644 --- a/opm/models/utils/start.hh +++ b/opm/models/utils/start.hh @@ -27,6 +27,7 @@ #ifndef EWOMS_START_HH #define EWOMS_START_HH +#include #include // the following header is not required here, but it must be included before // dune/common/densematrix.hh because of some c++ ideosyncrasies @@ -68,19 +69,6 @@ #include #endif -BEGIN_PROPERTIES - -// forward declaration of property tags -NEW_PROP_TAG(Scalar); -NEW_PROP_TAG(Simulator); -NEW_PROP_TAG(ThreadManager); -NEW_PROP_TAG(PrintProperties); -NEW_PROP_TAG(PrintParameters); -NEW_PROP_TAG(ParameterFile); -NEW_PROP_TAG(Problem); - -END_PROPERTIES - //! \cond SKIP_THIS namespace Opm { diff --git a/opm/simulators/linalg/istlpreconditionerwrappers.hh b/opm/simulators/linalg/istlpreconditionerwrappers.hh index 8a78b982d..e83ab2de0 100644 --- a/opm/simulators/linalg/istlpreconditionerwrappers.hh +++ b/opm/simulators/linalg/istlpreconditionerwrappers.hh @@ -45,20 +45,12 @@ #include #include +#include #include #include -BEGIN_PROPERTIES -NEW_PROP_TAG(Scalar); -NEW_PROP_TAG(SparseMatrixAdapter); -NEW_PROP_TAG(OverlappingMatrix); -NEW_PROP_TAG(OverlappingVector); -NEW_PROP_TAG(PreconditionerOrder); -NEW_PROP_TAG(PreconditionerRelaxation); -END_PROPERTIES - namespace Opm { namespace Linear { #define EWOMS_WRAP_ISTL_PRECONDITIONER(PREC_NAME, ISTL_PREC_TYPE) \ diff --git a/opm/simulators/linalg/istlsolverwrappers.hh b/opm/simulators/linalg/istlsolverwrappers.hh index 615f8a034..25c315a60 100644 --- a/opm/simulators/linalg/istlsolverwrappers.hh +++ b/opm/simulators/linalg/istlsolverwrappers.hh @@ -45,22 +45,10 @@ #include #include +#include #include -BEGIN_PROPERTIES - -NEW_PROP_TAG(Scalar); -NEW_PROP_TAG(SparseMatrixAdapter); -NEW_PROP_TAG(OverlappingMatrix); -NEW_PROP_TAG(OverlappingVector); -NEW_PROP_TAG(GMResRestart); -NEW_PROP_TAG(LinearSolverTolerance); -NEW_PROP_TAG(LinearSolverMaxIterations); -NEW_PROP_TAG(LinearSolverVerbosity); - -END_PROPERTIES - namespace Opm { namespace Linear { diff --git a/opm/simulators/linalg/linalgproperties.hh b/opm/simulators/linalg/linalgproperties.hh new file mode 100644 index 000000000..9f9d68e87 --- /dev/null +++ b/opm/simulators/linalg/linalgproperties.hh @@ -0,0 +1,103 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/* + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . + + Consult the COPYING file in the top-level source directory of this + module for the precise wording of the license and the list of + copyright holders. +*/ +/*! + * \file + * \ingroup BlackOilModel + * + * \brief Declares the properties required by the black oil model. + */ +#ifndef EWOMS_LINALG_PROPERTIES_HH +#define EWOMS_LINALG_PROPERTIES_HH + +#include + +BEGIN_PROPERTIES + +//! The type of the linear solver to be used +NEW_PROP_TAG(LinearSolverBackend); + +//! the preconditioner used by the linear solver +NEW_PROP_TAG(PreconditionerWrapper); + + +//! The floating point type used internally by the linear solver +NEW_PROP_TAG(LinearSolverScalar); + +/*! + * \brief The size of the algebraic overlap of the linear solver. + * + * Algebraic overlaps can be thought as being the same as the overlap + * of a grid, but it is only existant for the linear system of + * equations. + */ +NEW_PROP_TAG(LinearSolverOverlapSize); + +/*! + * \brief Maximum accepted error of the solution of the linear solver. + */ +NEW_PROP_TAG(LinearSolverTolerance); + +/*! + * \brief Maximum accepted error of the norm of the residual. + */ +NEW_PROP_TAG(LinearSolverAbsTolerance); + +/*! + * \brief Specifies the verbosity of the linear solver + * + * By default it is 0, i.e. it doesn't print anything. Setting this + * property to 1 prints aggregated convergence rates, 2 prints the + * convergence rate of every iteration of the scheme. + */ +NEW_PROP_TAG(LinearSolverVerbosity); + +//! Maximum number of iterations eyecuted by the linear solver +NEW_PROP_TAG(LinearSolverMaxIterations); + +//! The order of the sequential preconditioner +NEW_PROP_TAG(PreconditionerOrder); + +//! The relaxation factor of the preconditioner +NEW_PROP_TAG(PreconditionerRelaxation); + +//! number of iterations between solver restarts for the GMRES solver +NEW_PROP_TAG(GMResRestart); + +//! The class that allows to manipulate sparse matrices +NEW_PROP_TAG(SparseMatrixAdapter); + +//! Vector containing a quantity of for equation for each DOF of the whole grid +NEW_PROP_TAG(GlobalEqVector); + +NEW_PROP_TAG(AmgCoarsenTarget); +NEW_PROP_TAG(LinearSolverMaxError); +NEW_PROP_TAG(LinearSolverWrapper); +NEW_PROP_TAG(Overlap); +NEW_PROP_TAG(OverlappingLinearOperator); +NEW_PROP_TAG(OverlappingMatrix); +NEW_PROP_TAG(OverlappingScalarProduct); +NEW_PROP_TAG(OverlappingVector); + +END_PROPERTIES + +#endif diff --git a/opm/simulators/linalg/parallelamgbackend.hh b/opm/simulators/linalg/parallelamgbackend.hh index f3ac560c2..cc30c393e 100644 --- a/opm/simulators/linalg/parallelamgbackend.hh +++ b/opm/simulators/linalg/parallelamgbackend.hh @@ -27,6 +27,7 @@ #ifndef EWOMS_PARALLEL_AMG_BACKEND_HH #define EWOMS_PARALLEL_AMG_BACKEND_HH +#include "linalgproperties.hh" #include "parallelbasebackend.hh" #include "bicgstabsolver.hh" #include "combinedcriterion.hh" @@ -51,9 +52,6 @@ BEGIN_PROPERTIES NEW_TYPE_TAG(ParallelAmgLinearSolver, INHERITS_FROM(ParallelBaseLinearSolver)); -NEW_PROP_TAG(AmgCoarsenTarget); -NEW_PROP_TAG(LinearSolverMaxError); - //! The target number of DOFs per processor for the parallel algebraic //! multi-grid solver SET_INT_PROP(ParallelAmgLinearSolver, AmgCoarsenTarget, 5000); diff --git a/opm/simulators/linalg/parallelbasebackend.hh b/opm/simulators/linalg/parallelbasebackend.hh index 221e8f393..25232f524 100644 --- a/opm/simulators/linalg/parallelbasebackend.hh +++ b/opm/simulators/linalg/parallelbasebackend.hh @@ -40,6 +40,7 @@ #include #include #include +#include #include @@ -53,69 +54,6 @@ BEGIN_PROPERTIES NEW_TYPE_TAG(ParallelBaseLinearSolver); -// forward declaration of the required property tags -NEW_PROP_TAG(Simulator); -NEW_PROP_TAG(Scalar); -NEW_PROP_TAG(NumEq); -NEW_PROP_TAG(SparseMatrixAdapter); -NEW_PROP_TAG(GlobalEqVector); -NEW_PROP_TAG(VertexMapper); -NEW_PROP_TAG(GridView); - -NEW_PROP_TAG(BorderListCreator); -NEW_PROP_TAG(Overlap); -NEW_PROP_TAG(OverlappingVector); -NEW_PROP_TAG(OverlappingMatrix); -NEW_PROP_TAG(OverlappingScalarProduct); -NEW_PROP_TAG(OverlappingLinearOperator); - -//! The type of the linear solver to be used -NEW_PROP_TAG(LinearSolverBackend); - -//! the preconditioner used by the linear solver -NEW_PROP_TAG(PreconditionerWrapper); - - -//! The floating point type used internally by the linear solver -NEW_PROP_TAG(LinearSolverScalar); - -/*! - * \brief The size of the algebraic overlap of the linear solver. - * - * Algebraic overlaps can be thought as being the same as the overlap - * of a grid, but it is only existant for the linear system of - * equations. - */ -NEW_PROP_TAG(LinearSolverOverlapSize); - -/*! - * \brief Maximum accepted error of the solution of the linear solver. - */ -NEW_PROP_TAG(LinearSolverTolerance); - -/*! - * \brief Maximum accepted error of the norm of the residual. - */ -NEW_PROP_TAG(LinearSolverAbsTolerance); - -/*! - * \brief Specifies the verbosity of the linear solver - * - * By default it is 0, i.e. it doesn't print anything. Setting this - * property to 1 prints aggregated convergence rates, 2 prints the - * convergence rate of every iteration of the scheme. - */ -NEW_PROP_TAG(LinearSolverVerbosity); - -//! Maximum number of iterations eyecuted by the linear solver -NEW_PROP_TAG(LinearSolverMaxIterations); - -//! The order of the sequential preconditioner -NEW_PROP_TAG(PreconditionerOrder); - -//! The relaxation factor of the preconditioner -NEW_PROP_TAG(PreconditionerRelaxation); - //! Set the type of a global jacobian matrix for linear solvers that are based on //! dune-istl. SET_PROP(ParallelBaseLinearSolver, SparseMatrixAdapter) diff --git a/opm/simulators/linalg/parallelbicgstabbackend.hh b/opm/simulators/linalg/parallelbicgstabbackend.hh index 19bd5c97c..036370b3b 100644 --- a/opm/simulators/linalg/parallelbicgstabbackend.hh +++ b/opm/simulators/linalg/parallelbicgstabbackend.hh @@ -27,6 +27,7 @@ #ifndef EWOMS_PARALLEL_BICGSTAB_BACKEND_HH #define EWOMS_PARALLEL_BICGSTAB_BACKEND_HH +#include "linalgproperties.hh" #include "parallelbasebackend.hh" #include "bicgstabsolver.hh" #include "combinedcriterion.hh" @@ -44,8 +45,6 @@ BEGIN_PROPERTIES NEW_TYPE_TAG(ParallelBiCGStabLinearSolver, INHERITS_FROM(ParallelBaseLinearSolver)); -NEW_PROP_TAG(LinearSolverMaxError); - SET_TYPE_PROP(ParallelBiCGStabLinearSolver, LinearSolverBackend, Opm::Linear::ParallelBiCGStabSolverBackend); diff --git a/opm/simulators/linalg/parallelistlbackend.hh b/opm/simulators/linalg/parallelistlbackend.hh index 5c7ad2c53..577f31a92 100644 --- a/opm/simulators/linalg/parallelistlbackend.hh +++ b/opm/simulators/linalg/parallelistlbackend.hh @@ -27,6 +27,7 @@ #ifndef EWOMS_PARALLEL_ISTL_BACKEND_HH #define EWOMS_PARALLEL_ISTL_BACKEND_HH +#include "linalgproperties.hh" #include "parallelbasebackend.hh" #include "istlsolverwrappers.hh" #include "istlsparsematrixadapter.hh" @@ -37,12 +38,6 @@ BEGIN_PROPERTIES NEW_TYPE_TAG(ParallelIstlLinearSolver, INHERITS_FROM(ParallelBaseLinearSolver)); -NEW_PROP_TAG(LinearSolverWrapper); -NEW_PROP_TAG(SparseMatrixAdapter); - -//! number of iterations between solver restarts for the GMRES solver -NEW_PROP_TAG(GMResRestart); - END_PROPERTIES namespace Opm { diff --git a/opm/simulators/linalg/superlubackend.hh b/opm/simulators/linalg/superlubackend.hh index a9624d2b7..2c1d0190c 100644 --- a/opm/simulators/linalg/superlubackend.hh +++ b/opm/simulators/linalg/superlubackend.hh @@ -31,6 +31,7 @@ #include #include +#include #include @@ -40,14 +41,6 @@ BEGIN_PROPERTIES -// forward declaration of the required property tags -NEW_PROP_TAG(Scalar); -NEW_PROP_TAG(NumEq); -NEW_PROP_TAG(Simulator); -NEW_PROP_TAG(SparseMatrixAdapter); -NEW_PROP_TAG(GlobalEqVector); -NEW_PROP_TAG(LinearSolverVerbosity); -NEW_PROP_TAG(LinearSolverBackend); NEW_TYPE_TAG(SuperLULinearSolver); END_PROPERTIES diff --git a/tests/models/test_propertysystem.cpp b/tests/models/test_propertysystem.cpp index 3d7cc76ac..a7071e9be 100644 --- a/tests/models/test_propertysystem.cpp +++ b/tests/models/test_propertysystem.cpp @@ -32,6 +32,7 @@ #include "config.h" #include +#include #include @@ -120,10 +121,6 @@ SET_INT_PROP(Pickup, Payload, 5); SET_INT_PROP(HummerH1, TopSpeed, GET_PROP_VALUE(TTAG(Pickup), TopSpeed)); -/////////////////// -// Unmount the canon from the Hummer -UNSET_PROP(HummerH1, CanonCaliber); - END_PROPERTIES @@ -176,23 +173,6 @@ int main() std::cout << "(HummerH1, GasUsage) = " << GET_PROP_VALUE(TTAG(HummerH1), GasUsage) << "\n"; std::cout << "(HummerH1, Payload) = " << GET_PROP_VALUE(TTAG(HummerH1), Payload) << "\n"; std::cout << "(HummerH1, AutomaticTransmission) = " << GET_PROP_VALUE(TTAG(HummerH1), AutomaticTransmission) << "\n"; - // CanonCaliber is explcitly unset for the Hummer -> this would not compile: - // std::cout << "(HummerH1, CanonCaliber) = " << GET_PROP_VALUE(TTAG(HummerH1), CanonCaliber) << "\n"; - - std::cout << "\n"; - std::cout << "---------------------------------------\n"; - std::cout << "-- Diagnostic messages\n"; - std::cout << "---------------------------------------\n"; - - std::cout << "---- All properties for Sedan ---\n"; - Opm::Properties::printValues(); - - std::cout << "---- Message for (HummerH1, CanonCaliber) ---\n" - << PROP_DIAGNOSTIC(TTAG(HummerH1), CanonCaliber); - std::cout << "---- Message for (HummerH1, GasUsage) ---\n" - << PROP_DIAGNOSTIC(TTAG(HummerH1), GasUsage); - std::cout << "---- Message for (HummerH1, AutomaticTransmission) ---\n" - << PROP_DIAGNOSTIC(TTAG(HummerH1), AutomaticTransmission); return 0; }