diff --git a/dumux/freeflow/compositional/navierstokesncmodel.hh b/dumux/freeflow/compositional/navierstokesncmodel.hh index 97918804c01e54fa4ebbebe8909e330058d61889..a4c28bd3ba7bfd6b77b767dd928a1189cd3f8626 100644 --- a/dumux/freeflow/compositional/navierstokesncmodel.hh +++ b/dumux/freeflow/compositional/navierstokesncmodel.hh @@ -109,7 +109,7 @@ struct NavierStokesNCModelTraits : NavierStokesModelTraits<dimension> { const std::string xString = useMoles() ? "x" : "X"; if (pvIdx == 0) - return NavierStokesModelTraits<dimension>::primaryVariableNameCell(pvIdx, state); + return NavierStokesModelTraits<dimension>::template primaryVariableNameCell<FluidSystem>(pvIdx, state); else return xString + "^" + FluidSystem::componentName(pvIdx) + "_" + FluidSystem::phaseName(0); diff --git a/dumux/freeflow/navierstokes/model.hh b/dumux/freeflow/navierstokes/model.hh index 42e0b2e4bd739eaff5d136affb26cc985884d0f2..cf67e919bb18e25b2051d75a852741026310593f 100644 --- a/dumux/freeflow/navierstokes/model.hh +++ b/dumux/freeflow/navierstokes/model.hh @@ -105,13 +105,15 @@ struct NavierStokesModelTraits using Indices = NavierStokesIndices<dim()>; //! return the names of the primary variables in cells - static std::string primaryVariableNameCell(int pvIdx = 0) + template <class FluidSystem = void> + static std::string primaryVariableNameCell(int pvIdx = 0, int state = 0) { return "p"; } //! return the names of the primary variables on faces - static std::string primaryVariableNameFace(int pvIdx = 0) + template <class FluidSystem = void> + static std::string primaryVariableNameFace(int pvIdx = 0, int state = 0) { return "v"; } diff --git a/dumux/freeflow/nonisothermal/model.hh b/dumux/freeflow/nonisothermal/model.hh index 647e681f0cf5f361619b6c34ef842b48db79ff65..c8d057b5cc914657bbad18c9c2ba46f4cddfb591 100644 --- a/dumux/freeflow/nonisothermal/model.hh +++ b/dumux/freeflow/nonisothermal/model.hh @@ -63,15 +63,7 @@ struct FreeflowNIModelTraits : public IsothermalTraits //! the indices using Indices = FreeflowNonIsothermalIndices<typename IsothermalTraits::Indices, numEq()>; - static std::string primaryVariableName(int pvIdx, int state = 0) - { - if (pvIdx < numEq() - 1) - return IsothermalTraits::primaryVariableName(pvIdx, state); - else - return "T"; - } - - template <class FluidSystem> + template <class FluidSystem = void> static std::string primaryVariableName(int pvIdx, int state = 0) { if (pvIdx < numEq() - 1) diff --git a/dumux/freeflow/rans/oneeq/model.hh b/dumux/freeflow/rans/oneeq/model.hh index e0f66267f5b8aa7c08133d8054083eae2c1797ce..02c14b9a0a6e5213b046193856eec8d120f30324 100644 --- a/dumux/freeflow/rans/oneeq/model.hh +++ b/dumux/freeflow/rans/oneeq/model.hh @@ -114,11 +114,12 @@ struct OneEqModelTraits : RANSModelTraits<dimension> using Indices = OneEqIndices<dim(), numComponents()>; //! return the names of the primary variables in cells + template <class FluidSystem = void> static std::string primaryVariableNameCell(int pvIdx, int state = 0) { using ParentType = RANSModelTraits<dimension>; if (pvIdx == 0) - return ParentType::primaryVariableNameCell(pvIdx, state); + return ParentType::template primaryVariableNameCell<FluidSystem>(pvIdx, state); else return "nu_tilde"; } diff --git a/dumux/freeflow/rans/twoeq/kepsilon/model.hh b/dumux/freeflow/rans/twoeq/kepsilon/model.hh index 7dd1d1885e7a161717a7e53142b4749ba45454c6..d3bcfd46aae0e9f2f8610c5bdfcdca448d31019b 100644 --- a/dumux/freeflow/rans/twoeq/kepsilon/model.hh +++ b/dumux/freeflow/rans/twoeq/kepsilon/model.hh @@ -101,12 +101,13 @@ struct KEpsilonModelTraits : RANSModelTraits<dimension> using Indices = KEpsilonIndices<dim(), numComponents()>; //! return the names of the primary variables in cells + template<class FluidSystem = void> static std::string primaryVariableNameCell(int pvIdx, int state = 0) { using ParentType = RANSModelTraits<dimension>; switch (pvIdx) { case 0: - return ParentType::primaryVariableNameCell(pvIdx, state); + return ParentType::template primaryVariableNameCell<FluidSystem>(pvIdx, state); case 1: return "k"; default: diff --git a/dumux/freeflow/rans/twoeq/komega/model.hh b/dumux/freeflow/rans/twoeq/komega/model.hh index 40027de429dce0fb5fe50037c748e7ab34f55302..718d2c1c5acf5288efabc6009de174adb7ae1897 100644 --- a/dumux/freeflow/rans/twoeq/komega/model.hh +++ b/dumux/freeflow/rans/twoeq/komega/model.hh @@ -108,12 +108,13 @@ struct KOmegaModelTraits : RANSModelTraits<dimension> using Indices = KOmegaIndices<dim(), numComponents()>; //! return the names of the primary variables in cells + template<class FluidSystem = void> static std::string primaryVariableNameCell(int pvIdx, int state = 0) { using ParentType = RANSModelTraits<dimension>; switch (pvIdx) { case 0: - return ParentType::primaryVariableNameCell(pvIdx, state); + return ParentType::template primaryVariableNameCell<FluidSystem>(pvIdx, state); case 1: return "k"; default: diff --git a/dumux/freeflow/rans/twoeq/lowrekepsilon/model.hh b/dumux/freeflow/rans/twoeq/lowrekepsilon/model.hh index c1162f54e1ade491a2d0cbe11c112e505a6ccc5d..1fa9cd6cf7a3e8296601570e8ea75cbe067a4ddf 100644 --- a/dumux/freeflow/rans/twoeq/lowrekepsilon/model.hh +++ b/dumux/freeflow/rans/twoeq/lowrekepsilon/model.hh @@ -117,12 +117,13 @@ struct LowReKEpsilonModelTraits : RANSModelTraits<dimension> using Indices = LowReKEpsilonIndices<dim(), numComponents()>; //! return the names of the primary variables in cells + template<class FluidSystem = void> static std::string primaryVariableNameCell(int pvIdx, int state = 0) { using ParentType = RANSModelTraits<dimension>; switch (pvIdx) { case 0: - return ParentType::primaryVariableNameCell(pvIdx, state); + return ParentType::template primaryVariableNameCell<FluidSystem>(pvIdx, state); case 1: return "k"; default: diff --git a/dumux/io/loadsolution.hh b/dumux/io/loadsolution.hh index 26be5e1282dec2ef68783968a2b76f8e88af0e41..5519764afb5d9bad00ca31bf61f9afb5b5ecf966 100644 --- a/dumux/io/loadsolution.hh +++ b/dumux/io/loadsolution.hh @@ -30,6 +30,7 @@ #include <unordered_set> #include <unordered_map> #include <type_traits> +#include <functional> #include <dune/common/exceptions.hh> #include <dune/common/indices.hh> @@ -121,10 +122,8 @@ auto loadSolutionFromVtkFile(SolutionVector& sol, for (size_t pvIdx = 0; pvIdx < PrimaryVariables::dimension; ++pvIdx) { - const auto pvName = pvNameFunc(pvIdx); + const auto pvName = pvNameFunc(pvIdx, 0); auto vec = vtu.readData<std::vector<Scalar>>(pvName, dataType); - if (vec.size() != sol.size()) - DUNE_THROW(Dune::IOError, "Size mismatch between solution vector and read data (" << sol.size() << " != " << vec.size() << ")"); if (dataType == VTKReader::DataType::cellData) { @@ -190,25 +189,9 @@ auto loadSolutionFromVtkFile(SolutionVector& sol, using Scalar = typename PrimaryVariables::field_type; for (size_t pvIdx = 0; pvIdx < PrimaryVariables::dimension; ++pvIdx) { - // check if the primary variable is state invariant - bool isStateInvariant = true; - for (const auto& state : states) - isStateInvariant = isStateInvariant && pvNameFunc(pvIdx, state) == pvNameFunc(pvIdx, *states.begin()); - std::unordered_map<int, std::vector<Scalar>> data; - if (isStateInvariant) - data[0] = vtu.readData<std::vector<Scalar>>(pvNameFunc(pvIdx, *states.begin()), dataType); - - // the primary variable changes with the state - // read the data for all occuring states from the file - else - for (const auto& state : states) - data[state] = vtu.readData<std::vector<Scalar>>(pvNameFunc(pvIdx, state), dataType); - - // sanity check - for (const auto& d : data) - if (d.second.size() != sol.size()) - DUNE_THROW(Dune::IOError, "Size mismatch between solution vector and read data (" << sol.size() << " != " << d.second.size() << ")"); + for (const auto& state : states) + data[state] = vtu.readData<std::vector<Scalar>>(pvNameFunc(pvIdx, state), dataType); if (dataType == VTKReader::DataType::cellData) { @@ -216,9 +199,9 @@ auto loadSolutionFromVtkFile(SolutionVector& sol, for (const auto& element : elements(fvGridGeometry.gridView(), Dune::Partitions::interior)) { const auto eIdx = fvGridGeometry.elementMapper().index(element); - const auto state = isStateInvariant ? 0 : stateAtDof[i]; + const auto state = stateAtDof[i]; sol[eIdx][pvIdx] = data[state][i++]; - sol[eIdx][pvIdx].setState(state); + sol[eIdx].setState(state); } } else @@ -233,9 +216,9 @@ auto loadSolutionFromVtkFile(SolutionVector& sol, const auto vIdxGlobal = fvGridGeometry.vertexMapper().subIndex(element, vIdxLocal, dim); if (!visited[vIdxGlobal]) { - const auto state = isStateInvariant ? 0 : stateAtDof[i]; + const auto state = stateAtDof[i]; sol[vIdxGlobal][pvIdx] = data[state][i++]; - sol[vIdxGlobal][pvIdx].setState(state); + sol[vIdxGlobal].setState(state); visited[vIdxGlobal] = true; } } @@ -249,24 +232,26 @@ auto loadSolutionFromVtkFile(SolutionVector& sol, * \brief helper function to determine the primary variable names of a model with privar state * \note use this as input for the load solution function */ -template<class ModelTraits, class FluidSystem> -std::string pvNameWithState(int pvIdx, int state, const std::string& paramGroup = "") +template<class ModelTraits, class FluidSystem = void> +std::function<std::string(int,int)> createPVNameFunctionWithState(const std::string& paramGroup = "") { - static auto numStates = (1 << ModelTraits::numPhases()) - 1; - const auto paramNameWithState = "LoadSolution.PriVarNamesState" + std::to_string(state); - - if (hasParamInGroup(paramGroup, "LoadSolution.PriVarNames") && !hasParamInGroup(paramGroup, paramNameWithState)) - DUNE_THROW(Dune::NotImplemented, "please provide LoadSolution.PriVarNamesState1..." << numStates - << " or remove LoadSolution.PriVarNames to use the model's default primary variable names"); + return [paramGroup](int pvIdx, int state = 0) + { + static auto numStates = (1 << ModelTraits::numPhases()) - 1; + const auto paramNameWithState = "LoadSolution.PriVarNamesState" + std::to_string(state); - else if (hasParamInGroup(paramGroup, paramNameWithState)) - { - static const auto pvNames = getParamFromGroup<std::vector<std::string>>(paramGroup, paramNameWithState); - return pvNames[pvIdx]; - } + if (hasParamInGroup(paramGroup, "LoadSolution.PriVarNames") && !hasParamInGroup(paramGroup, paramNameWithState)) + DUNE_THROW(Dune::NotImplemented, "please provide LoadSolution.PriVarNamesState1..." << numStates + << " or remove LoadSolution.PriVarNames to use the model's default primary variable names"); - else - return ModelTraits::template primaryVariableName<FluidSystem>(pvIdx, state); + else if (hasParamInGroup(paramGroup, paramNameWithState)) + { + const auto pvName = getParamFromGroup<std::vector<std::string>>(paramGroup, paramNameWithState); + return pvName[pvIdx]; + } + else + return ModelTraits::template primaryVariableName<FluidSystem>(pvIdx, state); + }; } /*! @@ -274,16 +259,16 @@ std::string pvNameWithState(int pvIdx, int state, const std::string& paramGroup * \brief helper function to determine the primary variable names of a model without state * \note use this as input for the load solution function */ -template<class ModelTraits> -std::string pvName(int pvIdx, int state, const std::string& paramGroup = "") +template<class ModelTraits, class FluidSystem = void> +std::function<std::string(int,int)> createPVNameFunction(const std::string& paramGroup = "") { if (hasParamInGroup(paramGroup, "LoadSolution.PriVarNames")) { - static const auto pvNames = getParamFromGroup<std::vector<std::string>>(paramGroup, "LoadSolution.PriVarNames"); - return pvNames[pvIdx]; + const auto pvName = getParamFromGroup<std::vector<std::string>>(paramGroup, "LoadSolution.PriVarNames"); + return [n = std::move(pvName)](int pvIdx, int state = 0){ return n[pvIdx]; }; } else - return ModelTraits::primaryVariableName(pvIdx, 0); + return [](int pvIdx, int state = 0){ return ModelTraits::template primaryVariableName<FluidSystem>(pvIdx, state); }; } /*! diff --git a/dumux/porousmediumflow/1p/model.hh b/dumux/porousmediumflow/1p/model.hh index ed3918bccb6cedf5757dd68511d3335d57d82f60..44e6c1b6501ca7b2686315093a027c691bc37767 100644 --- a/dumux/porousmediumflow/1p/model.hh +++ b/dumux/porousmediumflow/1p/model.hh @@ -75,6 +75,7 @@ struct OnePModelTraits static constexpr bool enableMolecularDiffusion() { return false; } static constexpr bool enableEnergyBalance() { return false; } + template <class FluidSystem = void> static std::string primaryVariableName(int pvIdx = 0, int state = 0) { return "p"; diff --git a/dumux/porousmediumflow/2p/model.hh b/dumux/porousmediumflow/2p/model.hh index 8538caca456b96334bd64a941ffa61ae3c41507f..4a363dacf90af47fc7b2af16e0ee8888c16503c2 100644 --- a/dumux/porousmediumflow/2p/model.hh +++ b/dumux/porousmediumflow/2p/model.hh @@ -99,6 +99,7 @@ struct TwoPModelTraits static constexpr bool enableMolecularDiffusion() { return false; } static constexpr bool enableEnergyBalance() { return false; } + template <class FluidSystem = void> static std::string primaryVariableName(int pvIdx, int state = 0) { if (priVarFormulation() == TwoPFormulation::p0s1) diff --git a/dumux/porousmediumflow/2p1c/model.hh b/dumux/porousmediumflow/2p1c/model.hh index 52804d681d3fc47d645db343e5b85d287122beb4..dee1f2b12ee357e663a17237273a657e5d552486 100644 --- a/dumux/porousmediumflow/2p1c/model.hh +++ b/dumux/porousmediumflow/2p1c/model.hh @@ -96,7 +96,7 @@ struct TwoPOneCModelTraits static constexpr bool enableMolecularDiffusion() { return false; } static constexpr bool enableEnergyBalance() { return false; } - template <class FluidSystem> + template <class FluidSystem = void> static std::string primaryVariableName(int pvIdx, int state) { if (pvIdx == 0) diff --git a/dumux/porousmediumflow/3p/model.hh b/dumux/porousmediumflow/3p/model.hh index c72075ed0a1f7ce73011e0d5286fcff35194c48d..858dd85e5d23840df8ef4e2ca6a99e3bb117225d 100644 --- a/dumux/porousmediumflow/3p/model.hh +++ b/dumux/porousmediumflow/3p/model.hh @@ -90,15 +90,14 @@ struct ThreePModelTraits static constexpr bool enableMolecularDiffusion() { return false; } static constexpr bool enableEnergyBalance() { return false; } + template <class FluidSystem = void> static std::string primaryVariableName(int pvIdx, int state = 0) { - switch (pvIdx) { - case 0: - return "p_g"; - case 1: - return "S_w"; - default: - return "S_n"; + switch (pvIdx) + { + case 0: return "p_g"; + case 1: return "S_w"; + default: return "S_n"; } } }; diff --git a/dumux/porousmediumflow/3p3c/model.hh b/dumux/porousmediumflow/3p3c/model.hh index 0da465d7729e3040ffa26087c32be8268b3d3d49..15eb6906601e3e9b4920d8b8cd4491d3cf516d38 100644 --- a/dumux/porousmediumflow/3p3c/model.hh +++ b/dumux/porousmediumflow/3p3c/model.hh @@ -123,9 +123,10 @@ struct ThreePThreeCModelTraits static constexpr bool useMoles() { return useMol; } template <class FluidSystem> - static std::string primaryVariableName(int pvIdx, int state = 0) + static std::string primaryVariableName(int pvIdx, int state) { - switch (state) { + switch (state) + { case Indices::threePhases: const std::vector<std::string> s1 = {"p_g", "S_w", diff --git a/dumux/porousmediumflow/3pwateroil/model.hh b/dumux/porousmediumflow/3pwateroil/model.hh index 8f3c18248d1d645e107db3f503052def37152183..557061de497d4a510f044b1f6e187c66aed03d75 100644 --- a/dumux/porousmediumflow/3pwateroil/model.hh +++ b/dumux/porousmediumflow/3pwateroil/model.hh @@ -113,9 +113,10 @@ struct ThreePWaterOilModelTraits static constexpr bool onlyGasPhaseCanDisappear() { return onlyGasPhase; } template <class FluidSystem> - static std::string primaryVariableName(int pvIdx, int state = 0) + static std::string primaryVariableName(int pvIdx, int state) { - switch (state) { + switch (state) + { case Indices::threePhases: const std::vector<std::string> s1 = {"p_g", "S_w", diff --git a/dumux/porousmediumflow/nonisothermal/model.hh b/dumux/porousmediumflow/nonisothermal/model.hh index 45d65df4092104ecee94ab3b7e0e1d8e24d76fd5..1af387e2424af748bf55fbe90dfe8eb141b4fa08 100644 --- a/dumux/porousmediumflow/nonisothermal/model.hh +++ b/dumux/porousmediumflow/nonisothermal/model.hh @@ -75,15 +75,7 @@ struct PorousMediumFlowNIModelTraits : public IsothermalTraits //! The indices related to the non-isothermal model using Indices = EnergyIndices< typename IsothermalTraits::Indices, numEq()>; - static std::string primaryVariableName(int pvIdx, int state = 0) - { - if (pvIdx < numEq() - 1) - return IsothermalTraits::primaryVariableName(pvIdx, state); - else - return "T"; - } - - template <class FluidSystem> + template <class FluidSystem = void> static std::string primaryVariableName(int pvIdx, int state = 0) { if (pvIdx < numEq() - 1) diff --git a/dumux/porousmediumflow/richards/model.hh b/dumux/porousmediumflow/richards/model.hh index b6c4c67839b806a2f99e96073e9dc2969d3f000e..365e077131ffa2bb623ebf7a66100883888f08a3 100644 --- a/dumux/porousmediumflow/richards/model.hh +++ b/dumux/porousmediumflow/richards/model.hh @@ -136,6 +136,7 @@ struct RichardsModelTraits static constexpr bool enableMolecularDiffusion() { return enableDiff; } static constexpr bool enableEnergyBalance() { return false; } + template<class FluidSystem = void> static std::string primaryVariableName(int pvIdx, int state) { if (state == Indices::gasPhaseOnly) diff --git a/dumux/porousmediumflow/tracer/model.hh b/dumux/porousmediumflow/tracer/model.hh index 580e7795b35e7cbb97e86dda4bad01898f5d55a0..c157b2eaa7383917b6e330cdff7e65b11ccdc2d0 100644 --- a/dumux/porousmediumflow/tracer/model.hh +++ b/dumux/porousmediumflow/tracer/model.hh @@ -16,8 +16,6 @@ * You should have received a copy of the GNU General Public License * * along with this program. If not, see <http://www.gnu.org/licenses/>. * *****************************************************************************/ -#ifndef DUMUX_TRACER_MODEL_HH -#define DUMUX_TRACER_MODEL_HH /*! * \file @@ -50,6 +48,9 @@ * The velocity output is fully compatible with the tracer model if you want to write the velocity field to vtk. */ +#ifndef DUMUX_TRACER_MODEL_HH +#define DUMUX_TRACER_MODEL_HH + #include <dumux/common/properties.hh> #include <dumux/material/spatialparams/fv1p.hh> #include <dumux/discretization/stationaryvelocityfield.hh> diff --git a/test/freeflow/navierstokes/test_channel.cc b/test/freeflow/navierstokes/test_channel.cc index 6776a9595a2e563c282b03f88ca91567fee1470d..7a087d937c11b34381e8e632324cbc2bfa616b37 100644 --- a/test/freeflow/navierstokes/test_channel.cc +++ b/test/freeflow/navierstokes/test_channel.cc @@ -145,7 +145,7 @@ int main(int argc, char** argv) try auto fileNameCell = getParamFromGroup<std::string>("CellCenter", "Restart.File"); loadSolution(x[FVGridGeometry::cellCenterIdx()], fileNameCell, - [](int pvIdx){ return "p"; }, // test option with lambda + [](int pvIdx, int state){ return "p"; }, // test option with lambda *fvGridGeometry); auto fileNameFace = getParamFromGroup<std::string>("Face", "Restart.File"); diff --git a/test/porousmediumflow/1p/implicit/test_1pnifv.cc b/test/porousmediumflow/1p/implicit/test_1pnifv.cc index 22116b726c60e61f5a63e768bed664c1d33e1f7d..2009502d47141da80085ef2e08d9f7e71b58c83b 100644 --- a/test/porousmediumflow/1p/implicit/test_1pnifv.cc +++ b/test/porousmediumflow/1p/implicit/test_1pnifv.cc @@ -133,7 +133,7 @@ int main(int argc, char** argv) try { using ModelTraits = typename GET_PROP_TYPE(TypeTag, ModelTraits); const auto fileName = getParam<std::string>("Restart.File"); - loadSolution(x, fileName, primaryVariableName<ModelTraits>, *fvGridGeometry); + loadSolution(x, fileName, createPVNameFunction<ModelTraits>(), *fvGridGeometry); } else problem->applyInitialSolution(x); diff --git a/test/porousmediumflow/2p/implicit/incompressible/test_2p_fv.cc b/test/porousmediumflow/2p/implicit/incompressible/test_2p_fv.cc index adfbcfc2c38992857b26c7cef90911e84846b3ec..475a49fdfb7d30947ac067079e23c080c5025070 100644 --- a/test/porousmediumflow/2p/implicit/incompressible/test_2p_fv.cc +++ b/test/porousmediumflow/2p/implicit/incompressible/test_2p_fv.cc @@ -138,7 +138,7 @@ int main(int argc, char** argv) try { using ModelTraits = typename GET_PROP_TYPE(TypeTag, ModelTraits); const auto fileName = getParam<std::string>("Restart.File"); - loadSolution(x, fileName, primaryVariableName<ModelTraits>, *fvGridGeometry); + loadSolution(x, fileName, createPVNameFunction<ModelTraits>(), *fvGridGeometry); } else problem->applyInitialSolution(x); diff --git a/test/porousmediumflow/2p2c/implicit/test_2p2c_fv.cc b/test/porousmediumflow/2p2c/implicit/test_2p2c_fv.cc index 134ab6cb94f100971cd696bd9649dbc95387c062..d40a89200e94a7ae33aa34a1dffc7a65ccbe7ed3 100644 --- a/test/porousmediumflow/2p2c/implicit/test_2p2c_fv.cc +++ b/test/porousmediumflow/2p2c/implicit/test_2p2c_fv.cc @@ -107,7 +107,8 @@ int main(int argc, char** argv) try using ModelTraits = typename GET_PROP_TYPE(TypeTag, ModelTraits); using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); const auto fileName = getParam<std::string>("Restart.File"); - loadSolution(x, fileName, primaryVariableName<ModelTraits, FluidSystem>, *fvGridGeometry); + const auto pvName = createPVNameFunctionWithState<ModelTraits, FluidSystem>(); + loadSolution(x, fileName, pvName, *fvGridGeometry); } else problem->applyInitialSolution(x);