From 5502a7c3d60c17425787953559b6d1627f1e23d7 Mon Sep 17 00:00:00 2001 From: Katharina Heck <katharina.heck@iws.uni-stuttgart.de> Date: Wed, 20 Dec 2017 16:15:39 +0100 Subject: [PATCH] [feature] port obstacletest box and cc --- .../mpnc/implicit/CMakeLists.txt | 76 +++--- .../mpnc/implicit/obstacleproblem.hh | 177 +++++------- .../mpnc/implicit/obstaclespatialparams.hh | 68 ++--- .../mpnc/implicit/test_boxmpnc.cc | 59 ---- .../mpnc/implicit/test_boxmpnc.input | 14 - .../mpnc/implicit/test_ccmpnc.cc | 59 ---- .../{test_ccmpnc.input => test_mpnc.input} | 4 +- .../mpnc/implicit/test_mpnc_obstacle_fv.cc | 252 ++++++++++++++++++ 8 files changed, 377 insertions(+), 332 deletions(-) delete mode 100644 test/porousmediumflow/mpnc/implicit/test_boxmpnc.cc delete mode 100644 test/porousmediumflow/mpnc/implicit/test_boxmpnc.input delete mode 100644 test/porousmediumflow/mpnc/implicit/test_ccmpnc.cc rename test/porousmediumflow/mpnc/implicit/{test_ccmpnc.input => test_mpnc.input} (80%) create mode 100644 test/porousmediumflow/mpnc/implicit/test_mpnc_obstacle_fv.cc diff --git a/test/porousmediumflow/mpnc/implicit/CMakeLists.txt b/test/porousmediumflow/mpnc/implicit/CMakeLists.txt index 5ca0dbc762..880da4effd 100644 --- a/test/porousmediumflow/mpnc/implicit/CMakeLists.txt +++ b/test/porousmediumflow/mpnc/implicit/CMakeLists.txt @@ -1,47 +1,44 @@ add_input_file_links() -add_dumux_test(test_boxmpnc test_boxmpnc test_boxmpnc.cc - ${CMAKE_SOURCE_DIR}/bin/testing/runtest.py - --script fuzzy - --files ${CMAKE_SOURCE_DIR}/test/references/obstaclebox-reference.vtu - ${CMAKE_CURRENT_BINARY_DIR}/obstaclebox-00009.vtu - --command "${CMAKE_CURRENT_BINARY_DIR}/test_boxmpnc") +dune_add_test(NAME test_boxmpnc + SOURCES test_mpnc_obstacle_fv.cc + COMPILE_DEFINITIONS TYPETAG=ObstacleBoxProblem + COMMAND ${CMAKE_SOURCE_DIR}/bin/testing/runtest.py + CMD_ARGS --script fuzzy + --files ${CMAKE_SOURCE_DIR}/test/references/obstaclebox-reference.vtu + ${CMAKE_CURRENT_BINARY_DIR}/test_boxmpnc-00009.vtu + --command "${CMAKE_CURRENT_BINARY_DIR}/test_boxmpnc test_mpnc.input -Problem.Name test_boxmpnc") -add_dumux_test(test_ccmpnc test_ccmpnc test_ccmpnc.cc - ${CMAKE_SOURCE_DIR}/bin/testing/runtest.py - --script fuzzy - --files ${CMAKE_SOURCE_DIR}/test/references/obstaclecc-reference.vtu - ${CMAKE_CURRENT_BINARY_DIR}/obstaclecc-00009.vtu - --command "${CMAKE_CURRENT_BINARY_DIR}/test_ccmpnc") - -# build target for the one-phase Forchheimer test problem -add_dumux_test(test_forchheimer1p test_forchheimer1p test_forchheimer1p.cc - ${CMAKE_SOURCE_DIR}/bin/testing/runtest.py - --script fuzzy - --files ${CMAKE_SOURCE_DIR}/test/references/forchheimer1p-reference.vtp - ${CMAKE_CURRENT_BINARY_DIR}/test_forchheimer1p-00001.vtp - --command "${CMAKE_CURRENT_BINARY_DIR}/test_forchheimer1p") - -# build target for the two-phase Forchheimer test problem -add_dumux_test(test_forchheimer2p test_forchheimer2p test_forchheimer2p.cc - ${CMAKE_SOURCE_DIR}/bin/testing/runtest.py - --script fuzzy - --files ${CMAKE_SOURCE_DIR}/test/references/forchheimer2p-reference.vtu - ${CMAKE_CURRENT_BINARY_DIR}/test_forchheimer2p-00008.vtu - --command "${CMAKE_CURRENT_BINARY_DIR}/test_forchheimer2p") +dune_add_test(NAME test_ccmpnc + SOURCES test_mpnc_obstacle_fv.cc + COMPILE_DEFINITIONS TYPETAG=ObstacleCCProblem + COMMAND ${CMAKE_SOURCE_DIR}/bin/testing/runtest.py + CMD_ARGS --script fuzzy + --files ${CMAKE_SOURCE_DIR}/test/references/obstaclecc-reference.vtu + ${CMAKE_CURRENT_BINARY_DIR}/test_ccmpnc-00009.vtu + --command "${CMAKE_CURRENT_BINARY_DIR}/test_ccmpnc test_mpnc.input -Problem.Name test_ccmpnc") # build target for the full kinetic test problem -add_dumux_test(test_boxmpnckinetic test_boxmpnckinetic test_boxmpnckinetic.cc - ${CMAKE_SOURCE_DIR}/bin/testing/runtest.py - --script fuzzy - --files ${CMAKE_SOURCE_DIR}/test/references/evaporationatmosphere-reference.vtu - ${CMAKE_CURRENT_BINARY_DIR}/evaporationatmosphere-00005.vtu - --command "${CMAKE_CURRENT_BINARY_DIR}/test_boxmpnckinetic" - --zeroThreshold {"TnMinusTs":0.5,"TwMinusTn":0.5,"velocity_w_1":2e-12}) +dune_add_test(NAME test_boxmpnckinetic + SOURCES test_boxmpnckinetic.cc + COMPILE_DEFINITIONS TYPETAG=EvaporationAtmosphereBoxProblem + COMMAND ${CMAKE_SOURCE_DIR}/bin/testing/runtest.py + CMD_ARGS --script fuzzy + --files ${CMAKE_SOURCE_DIR}/test/references/evaporationatmosphere-reference.vtu + ${CMAKE_CURRENT_BINARY_DIR}/test_boxmpnckinetic-00011.vtu + --command "${CMAKE_CURRENT_BINARY_DIR}/test_boxmpnckinetic test_boxmpnckinetic.input -Problem.Name test_boxmpnckinetic") # build target for the energy kinetic test problem, two energy balance equations -add_dumux_test(test_boxmpncthermalnonequil test_boxmpncthermalnonequil test_boxmpncthermalnonequil.cc - "${CMAKE_CURRENT_BINARY_DIR}/test_boxmpncthermalnonequil") +dune_add_test(NAME test_boxmpncthermalnonequil + SOURCES test_boxmpncthermalnonequil.cc + COMPILE_DEFINITIONS TYPETAG=CombustionProblemOneComponentBoxProblem + COMMAND ${CMAKE_SOURCE_DIR}/bin/testing/runtest.py + CMD_ARGS --script fuzzy + --files ${CMAKE_SOURCE_DIR}/test/references/combustion-reference.vtp + ${CMAKE_CURRENT_BINARY_DIR}/test_boxmpncthermalnonequil-00084.vtp + --command "${CMAKE_CURRENT_BINARY_DIR}/test_boxmpncthermalnonequil test_boxmpncthermalnonequil.input -Problem.Name test_boxmpncthermalnonequil") + + #install sources install(FILES @@ -49,15 +46,10 @@ combustionproblem1c.hh combustionspatialparams.hh evaporationatmosphereproblem.hh evaporationatmospherespatialparams.hh -forchheimer1pproblem.hh -forchheimer2pproblem.hh -forchheimerspatialparams.hh obstacleproblem.hh obstaclespatialparams.hh test_boxmpnc.cc test_boxmpnckinetic.cc test_boxmpncthermalnonequil.cc test_ccmpnc.cc -test_forchheimer1p.cc -test_forchheimer2p.cc DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dumux/test/implicit/mpnc) diff --git a/test/porousmediumflow/mpnc/implicit/obstacleproblem.hh b/test/porousmediumflow/mpnc/implicit/obstacleproblem.hh index 921f8925e9..561f42979c 100644 --- a/test/porousmediumflow/mpnc/implicit/obstacleproblem.hh +++ b/test/porousmediumflow/mpnc/implicit/obstacleproblem.hh @@ -27,12 +27,15 @@ #include <dune/common/parametertreeparser.hh> -#include <dumux/porousmediumflow/mpnc/implicit/model.hh> -#include <dumux/porousmediumflow/implicit/problem.hh> +#include <dumux/discretization/box/properties.hh> +#include <dumux/discretization/cellcentered/tpfa/properties.hh> + +#include <dumux/porousmediumflow/mpnc/model.hh> +#include <dumux/porousmediumflow/problem.hh> #include <dumux/material/fluidsystems/h2on2.hh> -#include <dumux/material/constraintsolvers/computefromreferencephase.hh> #include <dumux/material/fluidstates/compositional.hh> +#include <dumux/material/constraintsolvers/computefromreferencephase.hh> #include "obstaclespatialparams.hh" @@ -46,7 +49,7 @@ namespace Properties { NEW_TYPE_TAG(ObstacleProblem, INHERITS_FROM(MPNC, ObstacleSpatialParams)); NEW_TYPE_TAG(ObstacleBoxProblem, INHERITS_FROM(BoxModel, ObstacleProblem)); -NEW_TYPE_TAG(ObstacleCCProblem, INHERITS_FROM(CCModel, ObstacleProblem)); +NEW_TYPE_TAG(ObstacleCCProblem, INHERITS_FROM(CCTpfaModel, ObstacleProblem)); // Set the grid type SET_TYPE_PROP(ObstacleProblem, Grid, Dune::YaspGrid<2>); @@ -57,24 +60,9 @@ SET_TYPE_PROP(ObstacleProblem, ObstacleProblem<TypeTag>); // Set fluid configuration -SET_PROP(ObstacleProblem, FluidSystem) -{ private: - using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); -public: - using type = FluidSystems::H2ON2<Scalar, /*useComplexRelations=*/false>; -}; - -// Enable smooth upwinding? -SET_BOOL_PROP(ObstacleProblem, ImplicitEnableSmoothUpwinding, true); - -// Enable molecular diffusion of the components? -SET_BOOL_PROP(ObstacleProblem, EnableDiffusion, true); - -// Enable the re-use of the jacobian matrix whenever possible? -SET_BOOL_PROP(ObstacleProblem, ImplicitEnableJacobianRecycling, true); - -// Reassemble the jacobian matrix only where it changed? -SET_BOOL_PROP(ObstacleProblem, ImplicitEnablePartialReassemble, true); +SET_TYPE_PROP(ObstacleProblem, + FluidSystem, + FluidSystems::H2ON2<typename GET_PROP_TYPE(TypeTag, Scalar), /*useComplexRelations=*/false>); // decide which type to use for floating values (double / quad) SET_TYPE_PROP(ObstacleProblem, Scalar, double); @@ -111,19 +99,28 @@ SET_TYPE_PROP(ObstacleProblem, Scalar, double); */ template <class TypeTag> class ObstacleProblem - : public ImplicitPorousMediaProblem<TypeTag> + : public PorousMediumFlowProblem<TypeTag> { - using ParentType = ImplicitPorousMediaProblem<TypeTag>; - using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using ParentType = PorousMediumFlowProblem<TypeTag>; using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); - using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); + using Indices = typename GET_PROP_TYPE(TypeTag, Indices); using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); - using ParameterCache = typename FluidSystem::ParameterCache; + using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); + using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); + using Sources = typename GET_PROP_TYPE(TypeTag, NumEqVector); + using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables); + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); + using SubControlVolume = typename GET_PROP_TYPE(TypeTag, SubControlVolume); + using SubControlVolumeFace = typename GET_PROP_TYPE(TypeTag, SubControlVolumeFace); + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using Element = typename GridView::template Codim<0>::Entity; + using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); + using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector); + using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables); + using ElementSolutionVector = typename GET_PROP_TYPE(TypeTag, ElementSolutionVector); using FluidState = typename GET_PROP_TYPE(TypeTag, FluidState); using MaterialLaw = typename GET_PROP_TYPE(TypeTag, MaterialLaw); - using MaterialLawParams = typename GET_PROP_TYPE(TypeTag, MaterialLaw)::Params; - using Indices = typename GET_PROP_TYPE(TypeTag, Indices); + using ParameterCache = typename FluidSystem::ParameterCache; // world dimension enum {dimWorld = GridView::dimensionworld}; @@ -137,13 +134,10 @@ class ObstacleProblem enum {s0Idx = Indices::s0Idx}; enum {p0Idx = Indices::p0Idx}; - using Element = typename GridView::template Codim<0>::Entity; - using Intersection = typename GridView::Intersection; - using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); - using GlobalPosition = Dune::FieldVector<typename GridView::Grid::ctype, dimWorld>; + + using GlobalPosition = Dune::FieldVector<Scalar, dimWorld>; using PhaseVector = Dune::FieldVector<Scalar, numPhases>; - using TimeManager = typename GET_PROP_TYPE(TypeTag, TimeManager); - enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) }; + static constexpr bool isBox = GET_PROP_VALUE(TypeTag, DiscretizationMethod) == DiscretizationMethods::Box; public: /*! @@ -152,8 +146,8 @@ public: * \param timeManager The time manager * \param gridView The grid view */ - ObstacleProblem(TimeManager &timeManager, const GridView &gridView) - : ParentType(timeManager, gridView) + ObstacleProblem(std::shared_ptr<const FVGridGeometry> fvGridGeometry) + : ParentType(fvGridGeometry) { temperature_ = 273.15 + 25; // -> 25°C @@ -167,42 +161,7 @@ public: int np = 1000; FluidSystem::init(Tmin, Tmax, nT, pmin, pmax, np); - name_ = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, std::string, Problem, Name); - } - - /*! - * \brief User defined output after the time integration - * - * Will be called diretly after the time integration. - */ - void postTimeStep() - { - // Calculate storage terms of the individual phases - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { - PrimaryVariables phaseStorage; - this->model().globalPhaseStorage(phaseStorage, phaseIdx); - - if (this->gridView().comm().rank() == 0) { - std::cout - <<"Storage in " - << FluidSystem::phaseName(phaseIdx) - << "Phase: [" - << phaseStorage - << "]" - << "\n"; - } - } - - // Calculate total storage terms - PrimaryVariables storage; - this->model().globalStorage(storage); - - // Write mass balance information for rank 0 - if (this->gridView().comm().rank() == 0) { - std::cout - <<"Storage total: [" << storage << "]" - << "\n"; - } + name_ = getParam<std::string>("Problem.Name"); } /*! @@ -223,7 +182,7 @@ public: * * \param globalPos The global position */ - Scalar temperatureAtPos(const GlobalPosition &globalPos) const + Scalar temperature() const { return temperature_; } /*! @@ -240,37 +199,31 @@ public: * \name Boundary conditions */ // \{ - /*! * \brief Specifies which kind of boundary condition should be - * used for which equation on a given boundary control volume. + * used for which equation on a given boundary segment * - * \param values The boundary types for the conservation equations - * \param globalPos The position of the center of the finite volume + * \param globalPos The global position */ - void boundaryTypesAtPos(BoundaryTypes &values, - const GlobalPosition &globalPos) const + BoundaryTypes boundaryTypesAtPos(const GlobalPosition &globalPos) const { + BoundaryTypes bcTypes; if (onInlet_(globalPos) || onOutlet_(globalPos)) - values.setAllDirichlet(); + bcTypes.setAllDirichlet(); else - values.setAllNeumann(); + bcTypes.setAllNeumann(); + return bcTypes; } /*! - * \brief Evaluate the boundary conditions for a dirichlet - * control volume. + * \brief Evaluates the boundary conditions for a Dirichlet + * boundary segment * - * \param values Stores the Dirichlet values for the conservation equations in - * \f$ [ \textnormal{unit of primary variable} ] \f$ - * \param globalPos The center of the finite volume which ought to be set. - * - * For this method, the \a values parameter stores primary variables. + * \param globalPos The global position */ - void dirichletAtPos(PrimaryVariables &values, - const GlobalPosition &globalPos) const + PrimaryVariables dirichletAtPos(const GlobalPosition &globalPos) const { - initial_(values, globalPos); + return initial_(globalPos); } /*! @@ -287,13 +240,13 @@ public: * * Negative values mean influx. */ - void neumann(PrimaryVariables &values, - const Element &element, - const FVElementGeometry &fvGeometry, - const Intersection &intersection, - const unsigned int scvIdx, - const unsigned int boundaryFaceIdx) const - { values = 0.; } + PrimaryVariables neumann(const Element& element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars, + const SubControlVolumeFace& scvf) const + { + return PrimaryVariables(0.0); + } // \} @@ -314,12 +267,13 @@ public: * * Positive values mean that mass is created, negative ones mean that it vanishes. */ - void source(PrimaryVariables &values, - const Element &element, - const FVElementGeometry &fvGeometry, - const unsigned int scvIdx) const + //! \copydoc Dumux::ImplicitProblem::source() + PrimaryVariables source(const Element &element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars, + const SubControlVolume &scv) const { - values = Scalar(0.0); + return PrimaryVariables(0.0); } /*! @@ -331,20 +285,18 @@ public: * For this method, the \a values parameter stores primary * variables. */ - void initialAtPos(PrimaryVariables &values, - const GlobalPosition &globalPos) const + PrimaryVariables initialAtPos(const GlobalPosition &globalPos) const { - initial_(values, globalPos); - Valgrind::CheckDefined(values); + return initial_(globalPos); } // \} private: // the internal method for the initial condition - void initial_(PrimaryVariables &values, - const GlobalPosition &globalPos) const + PrimaryVariables initial_(const GlobalPosition &globalPos) const { + PrimaryVariables values(0.0); FluidState fs; int refPhaseIdx; @@ -389,7 +341,7 @@ private: fs.setSaturation(otherPhaseIdx, 1.0 - fs.saturation(refPhaseIdx)); // calulate the capillary pressure - const MaterialLawParams &matParams = + const auto& matParams = this->spatialParams().materialLawParamsAtPos(globalPos); PhaseVector pc; MaterialLaw::capillaryPressures(pc, matParams, fs); @@ -422,6 +374,7 @@ private: // first pressure values[p0Idx] = fs.pressure(/*phaseIdx=*/0); + return values; } bool onInlet_(const GlobalPosition &globalPos) const diff --git a/test/porousmediumflow/mpnc/implicit/obstaclespatialparams.hh b/test/porousmediumflow/mpnc/implicit/obstaclespatialparams.hh index e9565a2c89..16bb62b5b5 100644 --- a/test/porousmediumflow/mpnc/implicit/obstaclespatialparams.hh +++ b/test/porousmediumflow/mpnc/implicit/obstaclespatialparams.hh @@ -29,7 +29,6 @@ #include <dumux/material/fluidmatrixinteractions/2p/regularizedlinearmaterial.hh> #include <dumux/material/fluidmatrixinteractions/2p/efftoabslaw.hh> -#include <dumux/porousmediumflow/mpnc/implicit/model.hh> #include <dumux/material/fluidmatrixinteractions/mp/mplinearmaterial.hh> #include <dumux/material/fluidmatrixinteractions/mp/2padapter.hh> @@ -73,26 +72,24 @@ template<class TypeTag> class ObstacleSpatialParams : public FVSpatialParams<TypeTag> { using ParentType = FVSpatialParams<TypeTag>; - using Grid = typename GET_PROP_TYPE(TypeTag, Grid); - using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector); - using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); - using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); - using CoordScalar = typename Grid::ctype; + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using Element = typename GridView::template Codim<0>::Entity; + using SubControlVolume = typename GET_PROP_TYPE(TypeTag, SubControlVolume); + using ElementSolutionVector = typename GET_PROP_TYPE(TypeTag, ElementSolutionVector); + using GlobalPosition = Dune::FieldVector<Scalar, GridView::dimension>; + using MaterialLaw = typename GET_PROP_TYPE(TypeTag, MaterialLaw); + using MaterialLawParams = typename MaterialLaw::Params; enum {dimWorld=GridView::dimensionworld}; - enum {wPhaseIdx = FluidSystem::wPhaseIdx}; - - using Element = typename GridView::template Codim<0>::Entity; - using DimWorldVector = Dune::FieldVector<CoordScalar, dimWorld>; public: - using MaterialLaw = typename GET_PROP_TYPE(TypeTag, MaterialLaw); - using MaterialLawParams = typename MaterialLaw::Params; + using PermeabilityType = Scalar; - ObstacleSpatialParams(const GridView &gridView) - : ParentType(gridView) + + ObstacleSpatialParams(const Problem &problem) + : ParentType(problem) { // intrinsic permeabilities coarseK_ = 1e-12; @@ -118,31 +115,14 @@ public: ~ObstacleSpatialParams() {} - /*! - * \brief Update the spatial parameters with the flow solution - * after a timestep. - * - * \param globalSol The current solution vector - */ - void update(const SolutionVector &globalSol) + PermeabilityType permeability(const Element& element, + const SubControlVolume& scv, + const ElementSolutionVector& elemSol) const { - } - - /*! - * \brief Returns the intrinsic permeability tensor. - * - * \param element The current finite element - * \param fvGeometry The current finite volume geometry of the element - * \param scvIdx The index sub-control volume where the - * intrinsic permeability is given. - */ - Scalar intrinsicPermeability(const Element &element, - const FVElementGeometry &fvGeometry, - const unsigned int scvIdx) const - { - if (isFineMaterial_(fvGeometry.subContVol[scvIdx].global)) + if (isFineMaterial_(scv.dofPosition())) return fineK_; - return coarseK_; + else + return coarseK_; } /*! @@ -153,9 +133,9 @@ public: * \param scvIdx The local index of the sub-control volume where * the porosity needs to be defined */ - double porosity(const Element &element, - const FVElementGeometry &fvGeometry, - const unsigned int scvIdx) const + Scalar porosity(const Element &element, + const SubControlVolume &scv, + const ElementSolutionVector &elemSol) const { return porosity_; } @@ -166,9 +146,9 @@ public: * \param pos The global position of the sub-control volume. * \return the material parameters object */ - const MaterialLawParams& materialLawParamsAtPos(const DimWorldVector &pos) const + const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const { - if (isFineMaterial_(pos)) + if (isFineMaterial_(globalPos)) return fineMaterialParams_; else return coarseMaterialParams_; @@ -179,7 +159,7 @@ private: * \brief Returns whether a given global position is in the * fine-permeability region or not. */ - static bool isFineMaterial_(const DimWorldVector &pos) + static bool isFineMaterial_(const GlobalPosition &pos) { return 10 - eps_ <= pos[0] && pos[0] <= 20 + eps_ && diff --git a/test/porousmediumflow/mpnc/implicit/test_boxmpnc.cc b/test/porousmediumflow/mpnc/implicit/test_boxmpnc.cc deleted file mode 100644 index 64f79caa08..0000000000 --- a/test/porousmediumflow/mpnc/implicit/test_boxmpnc.cc +++ /dev/null @@ -1,59 +0,0 @@ -// -*- 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 2 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 <http://www.gnu.org/licenses/>. * - *****************************************************************************/ - -/** - * \file - * - * \brief Test for the MpNc box model. - */ -#include <config.h> -#include "obstacleproblem.hh" -#include <dumux/common/start.hh> - -/*! - * \brief Provides an interface for customizing error messages associated with - * reading in parameters. - * - * \param progName The name of the program, that was tried to be started. - * \param errorMsg The error message that was issued by the start function. - * Comprises the thing that went wrong and a general help message. - */ -void usage(const char *progName, const std::string &errorMsg) -{ - if (errorMsg.size() > 0) { - std::string errorMessageOut = "\nUsage: "; - errorMessageOut += progName; - errorMessageOut += " [options]\n"; - errorMessageOut += errorMsg; - errorMessageOut += "\n\nThe list of mandatory options for this program is:\n" - "\t-TimeManager.TEnd End of the simulation [s] \n" - "\t-TimeManager.DtInitial Initial timestep size [s] \n" - "\t-Grid.File Name of the file containing the grid \n" - "\t definition in DGF format\n"; - - std::cout << errorMessageOut - << "\n"; - } -} - -int main(int argc, char** argv) -{ - using ProblemTypeTag = TTAG(ObstacleBoxProblem); - return Dumux::start<ProblemTypeTag>(argc, argv, usage); -} diff --git a/test/porousmediumflow/mpnc/implicit/test_boxmpnc.input b/test/porousmediumflow/mpnc/implicit/test_boxmpnc.input deleted file mode 100644 index 1c58b3803a..0000000000 --- a/test/porousmediumflow/mpnc/implicit/test_boxmpnc.input +++ /dev/null @@ -1,14 +0,0 @@ -[TimeManager] -DtInitial = 250 # [s] -TEnd = 1e4 # [s] - -[Grid] -UpperRight = 60 40 -Cells = 24 16 - -[LinearSolver] -ResidualReduction = 1e-12 - -[Problem] -Name = obstaclebox - diff --git a/test/porousmediumflow/mpnc/implicit/test_ccmpnc.cc b/test/porousmediumflow/mpnc/implicit/test_ccmpnc.cc deleted file mode 100644 index 6c0340f8d9..0000000000 --- a/test/porousmediumflow/mpnc/implicit/test_ccmpnc.cc +++ /dev/null @@ -1,59 +0,0 @@ -// -*- 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 2 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 <http://www.gnu.org/licenses/>. * - *****************************************************************************/ - -/** - * \file - * - * \brief Test for the MpNc CC model. - */ -#include <config.h> -#include "obstacleproblem.hh" -#include <dumux/common/start.hh> - -/*! - * \brief Provides an interface for customizing error messages associated with - * reading in parameters. - * - * \param progName The name of the program, that was tried to be started. - * \param errorMsg The error message that was issued by the start function. - * Comprises the thing that went wrong and a general help message. - */ -void usage(const char *progName, const std::string &errorMsg) -{ - if (errorMsg.size() > 0) { - std::string errorMessageOut = "\nUsage: "; - errorMessageOut += progName; - errorMessageOut += " [options]\n"; - errorMessageOut += errorMsg; - errorMessageOut += "\n\nThe list of mandatory options for this program is:\n" - "\t-TimeManager.TEnd End of the simulation [s] \n" - "\t-TimeManager.DtInitial Initial timestep size [s] \n" - "\t-Grid.File Name of the file containing the grid \n" - "\t definition in DGF format\n"; - - std::cout << errorMessageOut - << "\n"; - } -} - -int main(int argc, char** argv) -{ - using ProblemTypeTag = TTAG(ObstacleCCProblem); - return Dumux::start<ProblemTypeTag>(argc, argv, usage); -} diff --git a/test/porousmediumflow/mpnc/implicit/test_ccmpnc.input b/test/porousmediumflow/mpnc/implicit/test_mpnc.input similarity index 80% rename from test/porousmediumflow/mpnc/implicit/test_ccmpnc.input rename to test/porousmediumflow/mpnc/implicit/test_mpnc.input index dbb4c29d38..0ca290b167 100644 --- a/test/porousmediumflow/mpnc/implicit/test_ccmpnc.input +++ b/test/porousmediumflow/mpnc/implicit/test_mpnc.input @@ -1,4 +1,4 @@ -[TimeManager] +[TimeLoop] DtInitial = 250 # [s] TEnd = 1e4 # [s] @@ -10,5 +10,5 @@ Cells = 24 16 ResidualReduction = 1e-12 [Problem] -Name = obstaclecc +Name = obstacle diff --git a/test/porousmediumflow/mpnc/implicit/test_mpnc_obstacle_fv.cc b/test/porousmediumflow/mpnc/implicit/test_mpnc_obstacle_fv.cc new file mode 100644 index 0000000000..664daa0e1c --- /dev/null +++ b/test/porousmediumflow/mpnc/implicit/test_mpnc_obstacle_fv.cc @@ -0,0 +1,252 @@ +// -*- 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 2 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 <http://www.gnu.org/licenses/>. * + *****************************************************************************/ +/*! + * \file + * + * \brief test for the mpnc porousmedium box flow model + */ +#include <config.h> + +#include <ctime> +#include <iostream> + +#include <dune/common/parallel/mpihelper.hh> +#include <dune/common/timer.hh> +#include <dune/grid/io/file/dgfparser/dgfexception.hh> +#include <dune/grid/io/file/vtk.hh> +#include <dune/istl/io.hh> + +#include "obstacleproblem.hh" + +#include <dumux/common/properties.hh> +#include <dumux/common/parameters.hh> +#include <dumux/common/valgrind.hh> +#include <dumux/common/dumuxmessage.hh> +#include <dumux/common/defaultusagemessage.hh> + +#include <dumux/linear/amgbackend.hh> +#include <dumux/nonlinear/newtonmethod.hh> +#include <dumux/nonlinear/newtoncontroller.hh> + +#include <dumux/assembly/fvassembler.hh> +#include <dumux/assembly/diffmethod.hh> + +#include <dumux/discretization/methods.hh> + +#include <dumux/io/vtkoutputmodule.hh> + +/*! + * \brief Provides an interface for customizing error messages associated with + * reading in parameters. + * + * \param progName The name of the program, that was tried to be started. + * \param errorMsg The error message that was issued by the start function. + * Comprises the thing that went wrong and a general help message. + */ +void usage(const char *progName, const std::string &errorMsg) +{ + if (errorMsg.size() > 0) { + std::string errorMessageOut = "\nUsage: "; + errorMessageOut += progName; + errorMessageOut += " [options]\n"; + errorMessageOut += errorMsg; + errorMessageOut += "\n\nThe list of mandatory arguments for this program is:\n" + "\t-TimeManager.TEnd End of the simulation [s] \n" + "\t-TimeManager.DtInitial Initial timestep size [s] \n" + "\t-Grid.LowerLeft Lower left corner coordinates\n" + "\t-Grid.UpperRight Upper right corner coordinates\n" + "\t-Grid.Cells Number of cells in respective coordinate directions\n" + "\t definition in DGF format\n" + "\t-SpatialParams.LensLowerLeft coordinates of the lower left corner of the lens [m] \n" + "\t-SpatialParams.LensUpperRight coordinates of the upper right corner of the lens [m] \n" + "\t-SpatialParams.Permeability Permeability of the domain [m^2] \n" + "\t-SpatialParams.PermeabilityLens Permeability of the lens [m^2] \n"; + + std::cout << errorMessageOut + << "\n"; + } +} + +int main(int argc, char** argv) try +{ + using namespace Dumux; + + // define the type tag for this problem + using TypeTag = TTAG(TYPETAG); + + // initialize MPI, finalize is done automatically on exit + const auto& mpiHelper = Dune::MPIHelper::instance(argc, argv); + + // print dumux start message + if (mpiHelper.rank() == 0) + DumuxMessage::print(/*firstCall=*/true); + + // parse command line arguments and input file + Parameters::init(argc, argv, usage); + + // try to create a grid (from the given grid file or the input file) + using GridCreator = typename GET_PROP_TYPE(TypeTag, GridCreator); + GridCreator::makeGrid(); + GridCreator::loadBalance(); + + //////////////////////////////////////////////////////////// + // run instationary non-linear problem on this grid + //////////////////////////////////////////////////////////// + + // we compute on the leaf grid view + const auto& leafGridView = GridCreator::grid().leafGridView(); + + // create the finite volume grid geometry + using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); + auto fvGridGeometry = std::make_shared<FVGridGeometry>(leafGridView); + fvGridGeometry->update(); + + // the problem (initial and boundary conditions) + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); + auto problem = std::make_shared<Problem>(fvGridGeometry); + + // the solution vector + using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector); + SolutionVector x(fvGridGeometry->numDofs()); + problem->applyInitialSolution(x); + auto xOld = x; + + // the grid variables + using GridVariables = typename GET_PROP_TYPE(TypeTag, GridVariables); + auto gridVariables = std::make_shared<GridVariables>(problem, fvGridGeometry); + gridVariables->init(x, xOld); + + // get some time loop parameters + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + const auto tEnd = getParam<Scalar>("TimeLoop.TEnd"); + const auto maxDivisions = getParam<int>("TimeLoop.MaxTimeStepDivisions"); + const auto maxDt = getParam<Scalar>("TimeLoop.MaxTimeStepSize"); + auto dt = getParam<Scalar>("TimeLoop.DtInitial"); + + // check if we are about to restart a previously interrupted simulation + Scalar restartTime = 0; + if (Parameters::getTree().hasKey("Restart") || Parameters::getTree().hasKey("TimeLoop.Restart")) + restartTime = getParam<Scalar>("TimeLoop.Restart"); + + // intialize the vtk output module + using VtkOutputFields = typename GET_PROP_TYPE(TypeTag, VtkOutputFields); + VtkOutputModule<TypeTag> vtkWriter(*problem, *fvGridGeometry, *gridVariables, x, problem->name()); + VtkOutputFields::init(vtkWriter); //! Add model specific output fields + vtkWriter.write(0.0); + + // instantiate time loop + auto timeLoop = std::make_shared<TimeLoop<Scalar>>(restartTime, dt, tEnd); + timeLoop->setMaxTimeStepSize(maxDt); + + // the assembler with time loop for instationary problem + using Assembler = FVAssembler<TypeTag, DiffMethod::numeric>; + auto assembler = std::make_shared<Assembler>(problem, fvGridGeometry, gridVariables, timeLoop); + + // the linear solver + using LinearSolver = AMGBackend<TypeTag>; + auto linearSolver = std::make_shared<LinearSolver>(leafGridView, fvGridGeometry->dofMapper()); + + // the non-linear solver + using NewtonController = NewtonController<TypeTag>; + using NewtonMethod = NewtonMethod<NewtonController, Assembler, LinearSolver>; + auto newtonController = std::make_shared<NewtonController>(leafGridView.comm(), timeLoop); + NewtonMethod nonLinearSolver(newtonController, assembler, linearSolver); + + // time loop + timeLoop->start(); do + { + // set previous solution for storage evaluations + assembler->setPreviousSolution(xOld); + + // try solving the non-linear system + for (int i = 0; i < maxDivisions; ++i) + { + // linearize & solve + auto converged = nonLinearSolver.solve(x); + + if (converged) + break; + + if (!converged && i == maxDivisions-1) + DUNE_THROW(Dune::MathError, + "Newton solver didn't converge after " + << maxDivisions + << " time-step divisions. dt=" + << timeLoop->timeStepSize() + << ".\nThe solutions of the current and the previous time steps " + << "have been saved to restart files."); + } + + // make the new solution the old solution + xOld = x; + gridVariables->advanceTimeStep(); + + // advance to the time loop to the next step + timeLoop->advanceTimeStep(); + + // write vtk output + vtkWriter.write(timeLoop->time()); + + // report statistics of this time step + timeLoop->reportTimeStep(); + + // set new dt as suggested by newton controller + timeLoop->setTimeStepSize(newtonController->suggestTimeStepSize(timeLoop->timeStepSize())); + + } while (!timeLoop->finished()); + + timeLoop->finalize(leafGridView.comm()); + + //////////////////////////////////////////////////////////// + // finalize, print dumux message to say goodbye + //////////////////////////////////////////////////////////// + + // print dumux end message + if (mpiHelper.rank() == 0) + { + Parameters::print(); + DumuxMessage::print(/*firstCall=*/false); + } + + return 0; +} // end main +catch (Dumux::ParameterException &e) +{ + std::cerr << std::endl << e << " ---> Abort!" << std::endl; + return 1; +} +catch (Dune::DGFException & e) +{ + std::cerr << "DGF exception thrown (" << e << + "). Most likely, the DGF file name is wrong " + "or the DGF file is corrupted, " + "e.g. missing hash at end of file or wrong number (dimensions) of entries." + << " ---> Abort!" << std::endl; + return 2; +} +catch (Dune::Exception &e) +{ + std::cerr << "Dune reported error: " << e << " ---> Abort!" << std::endl; + return 3; +} +catch (...) +{ + std::cerr << "Unknown exception thrown! ---> Abort!" << std::endl; + return 4; +} -- GitLab