From 9227f850a6fb742fd3dcc68067515c580fc6b2a9 Mon Sep 17 00:00:00 2001 From: Timo Koch <timo.koch@iws.uni-stuttgart.de> Date: Mon, 30 Jul 2018 17:20:17 +0200 Subject: [PATCH] [io][loadsolution] Make privarnames functions consistent * We require the signature std::string(int, int) signature for all pv names functions passed to load solution. You can still wrap a function that just takes a privar index into a lambda with these two arguments. * We make FluidSystem an optional template parameter for all functions that don't make use of it. This way they can be also used directly in loadSolution when not using the convenience free function pvNames. * We return a function from the convenience free function now to be able to include the param group --- .../compositional/navierstokesncmodel.hh | 2 +- dumux/freeflow/navierstokes/model.hh | 6 +- dumux/freeflow/nonisothermal/model.hh | 10 +-- dumux/freeflow/rans/oneeq/model.hh | 3 +- dumux/freeflow/rans/twoeq/kepsilon/model.hh | 3 +- dumux/freeflow/rans/twoeq/komega/model.hh | 3 +- .../rans/twoeq/lowrekepsilon/model.hh | 3 +- dumux/io/loadsolution.hh | 75 ++++++++----------- dumux/porousmediumflow/1p/model.hh | 1 + dumux/porousmediumflow/2p/model.hh | 1 + dumux/porousmediumflow/2p1c/model.hh | 2 +- dumux/porousmediumflow/3p/model.hh | 13 ++-- dumux/porousmediumflow/3p3c/model.hh | 5 +- dumux/porousmediumflow/3pwateroil/model.hh | 5 +- dumux/porousmediumflow/nonisothermal/model.hh | 10 +-- dumux/porousmediumflow/richards/model.hh | 1 + dumux/porousmediumflow/tracer/model.hh | 5 +- test/freeflow/navierstokes/test_channel.cc | 2 +- .../1p/implicit/test_1pnifv.cc | 2 +- .../2p/implicit/incompressible/test_2p_fv.cc | 2 +- .../2p2c/implicit/test_2p2c_fv.cc | 3 +- 21 files changed, 69 insertions(+), 88 deletions(-) diff --git a/dumux/freeflow/compositional/navierstokesncmodel.hh b/dumux/freeflow/compositional/navierstokesncmodel.hh index 97918804c0..a4c28bd3ba 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 42e0b2e4bd..cf67e919bb 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 647e681f0c..c8d057b5cc 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 e0f66267f5..02c14b9a0a 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 7dd1d1885e..d3bcfd46aa 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 40027de429..718d2c1c5a 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 c1162f54e1..1fa9cd6cf7 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 26be5e1282..5519764afb 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 ed3918bccb..44e6c1b650 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 8538caca45..4a363dacf9 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 52804d681d..dee1f2b12e 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 c72075ed0a..858dd85e5d 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 0da465d772..15eb690660 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 8f3c18248d..557061de49 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 45d65df409..1af387e242 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 b6c4c67839..365e077131 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 580e7795b3..c157b2eaa7 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 6776a9595a..7a087d937c 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 22116b726c..2009502d47 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 adfbcfc2c3..475a49fdfb 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 134ab6cb94..d40a89200e 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); -- GitLab