From f1fe505fb47013dd0a921f6897c18bf5ff3cb8c8 Mon Sep 17 00:00:00 2001 From: Kai Wendel Date: Mon, 18 Jun 2018 13:04:35 +0200 Subject: [PATCH 01/60] [lecture] first steps to adapt to 3.0 --- lecture/efm/1p2c_2p_2p2c/lens1p2cproblem.hh | 2 - lecture/efm/1p2cvs2p/exercise1.input | 2 +- lecture/efm/1p2cvs2p/lens1p2cexercise1.cc | 183 +++++++++- lecture/efm/1p2cvs2p/lens1p2cproblem.hh | 233 +++++------- lecture/efm/1p2cvs2p/lens2pexercise1.cc | 177 ++++++++- lecture/efm/1p2cvs2p/lens2pproblem.hh | 181 ++++----- lecture/efm/2p/lens2pexercise2.cc | 196 +++++++++- lecture/efm/2p/lens2pexercise2.input | 2 +- lecture/efm/2p/lens2pproblem.hh | 240 +++++------- lecture/mhs/groundwater/groundwater.cc | 170 ++++++++- lecture/mhs/groundwater/groundwater.input | 2 +- lecture/mhs/groundwater/groundwaterproblem.hh | 103 ++++-- .../groundwater/groundwaterspatialparams.hh | 35 +- .../buckleyleverettanalyticsolution.hh | 31 +- .../buckleyleverettexercise.cc | 1 + .../buckleyleverettexercise.input | 2 +- .../buckleyleverett/buckleyleverettproblem.hh | 107 ++++-- .../buckleyleverettspatialparams.hh | 37 +- lecture/mm/buckleyleverett/pseudoh2o.hh | 4 +- lecture/mm/buckleyleverett/pseudooil.hh | 2 + lecture/mm/co2plume/co2plumeshapeproblem.hh | 55 +-- .../mm/columnxylene/columnxyleneexercise.cc | 172 ++++++++- .../columnxylene/columnxyleneexercise.input | 2 +- .../mm/columnxylene/columnxyleneproblem.hh | 95 +++-- .../mm/columnxylene/columnxyleneproblem2.hh | 24 +- .../columnxylenespatialparams2.hh | 54 +-- lecture/mm/convectivemixing/convmixproblem.hh | 69 ++-- .../convectivemixing/convmixspatialparams.hh | 16 +- lecture/mm/fuelcell/fuelcell.cc | 172 ++++++++- lecture/mm/fuelcell/fuelcell.input | 2 +- lecture/mm/fuelcell/fuelcellproblem.hh | 342 +++++++++--------- lecture/mm/fuelcell/fuelcellspatialparams.hh | 126 +++---- .../material/thermalconductivityconstant.hh | 4 +- lecture/mm/heatpipe/heatpipe.cc | 173 ++++++++- lecture/mm/heatpipe/heatpipe.input | 2 +- lecture/mm/heatpipe/heatpipeproblem.hh | 97 +++-- lecture/mm/heatpipe/heatpipespatialparams.hh | 67 ++-- lecture/mm/heatpipe/krpcheatpipe.hh | 6 +- lecture/mm/heavyoil/sagd/problem.hh | 133 +++---- lecture/mm/heavyoil/sagd/sagd.cc | 181 ++++++++- lecture/mm/heavyoil/sagd/sagd.input | 2 +- lecture/mm/heavyoil/sagd/spatialparams.hh | 102 +++--- lecture/mm/heavyoil/sagdcyclic/problem.hh | 133 ++++--- lecture/mm/heavyoil/sagdcyclic/sagd_cyclic.cc | 157 +++++++- .../mm/heavyoil/sagdcyclic/sagd_cyclic.input | 2 +- .../mm/heavyoil/sagdcyclic/spatialparams.hh | 69 ++-- lecture/mm/heavyoil/sagdcyclichyst/problem.hh | 125 ++++--- .../sagdcyclichyst/sagd_cyclic_hyst.cc | 157 +++++++- .../sagdcyclichyst/sagd_cyclic_hyst.input | 2 +- .../heavyoil/sagdcyclichyst/spatialparams.hh | 66 ++-- .../mm/henryproblem/henry1p2c/henry1p2c.cc | 170 ++++++++- .../mm/henryproblem/henry1p2c/henry1p2c.input | 1 - .../henry1p2c/henry1p2cproblem.hh | 113 +++--- .../henry1p2c/henry1p2cspatialparameters.hh | 40 +- .../henry1p2c/watersaltfluidsystem.hh | 17 +- lecture/mm/henryproblem/henry2p/henry2p.cc | 169 ++++++++- lecture/mm/henryproblem/henry2p/henry2p.input | 2 +- .../mm/henryproblem/henry2p/henry2pproblem.hh | 175 ++++----- .../henry2p/henry2pspatialparams.hh | 41 +-- .../henryproblem/henry2p/simplesaltwater.hh | 11 +- .../mm/mcwhorter/mcwhorteranalyticsolution.hh | 22 +- lecture/mm/mcwhorter/mcwhorterexercise.cc | 170 ++++++++- lecture/mm/mcwhorter/mcwhorterexercise.input | 2 +- lecture/mm/mcwhorter/mcwhorterproblem.hh | 96 +++-- .../naplinfiltration/3p/naplinfiltration3p.cc | 175 ++++++++- .../3p/naplinfiltration3p.input | 4 +- lecture/mm/naplinfiltration/3p/problem.hh | 125 +++---- .../3p3c/naplinfiltration3p3c.cc | 196 +++++++++- lecture/mm/naplinfiltration/3p3c/problem.hh | 111 +++--- .../naplinfiltration/h2oairnaplfluidsystem.hh | 38 +- lecture/mm/naplinfiltration/spatialparams.hh | 83 +++-- .../remediationscenariosexercise.cc | 195 +++++++++- .../remediationscenariosexercise.input | 2 +- .../remediationscenariosproblem.hh | 148 ++++---- .../remediationscenariosspatialparams.hh | 17 +- 75 files changed, 4510 insertions(+), 1930 deletions(-) diff --git a/lecture/efm/1p2c_2p_2p2c/lens1p2cproblem.hh b/lecture/efm/1p2c_2p_2p2c/lens1p2cproblem.hh index a146593..e277e66 100644 --- a/lecture/efm/1p2c_2p_2p2c/lens1p2cproblem.hh +++ b/lecture/efm/1p2c_2p_2p2c/lens1p2cproblem.hh @@ -128,8 +128,6 @@ public: /*! * \brief The constructor * - * \param timeManager The time manager - * \param gridView The grid view */ LensOnePTwoCProblem(std::shared_ptr fvGridGeometry ) diff --git a/lecture/efm/1p2cvs2p/exercise1.input b/lecture/efm/1p2cvs2p/exercise1.input index f6c73d5..4df2de2 100644 --- a/lecture/efm/1p2cvs2p/exercise1.input +++ b/lecture/efm/1p2cvs2p/exercise1.input @@ -1,4 +1,4 @@ -[TimeManager] +[TimeLoop] MaxTimeStepSize = 5.0e1 # maximal time step size [s] TEnd = 5.0e3 # end time of the simulation [s] DtInitial = 1e1 # initial time step for the simulation [s] diff --git a/lecture/efm/1p2cvs2p/lens1p2cexercise1.cc b/lecture/efm/1p2cvs2p/lens1p2cexercise1.cc index 2ce8af1..d39b3df 100644 --- a/lecture/efm/1p2cvs2p/lens1p2cexercise1.cc +++ b/lecture/efm/1p2cvs2p/lens1p2cexercise1.cc @@ -16,10 +16,35 @@ * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * *****************************************************************************/ -#include "config.h" +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include + +#include #include "lens1p2cproblem.hh" -#include /*! * \brief Provides an interface for customizing error messages associated with @@ -29,6 +54,8 @@ * \param errorMsg The error message that was issued by the start function. * Comprises the thing that went wrong and a general help message. */ + +// TODO: Do we need this function? void usage(const char *progName, const std::string &errorMsg) { if (errorMsg.size() > 0) { @@ -60,8 +87,158 @@ void usage(const char *progName, const std::string &errorMsg) //////////////////////// // the main function //////////////////////// -int main(int argc, char** argv) +/* int main(int argc, char** argv) { typedef TTAG(LensOnePTwoCProblem) TypeTag; return Dumux::start(argc, argv, usage); +}*/ + +int main(int argc, char** argv) try +{ + using namespace Dumux; + + // define the type tag for this problem + using TypeTag = TTAG(LensOnePTwoCProblem); + + // 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(leafGridView); + fvGridGeometry->update(); + + // the problem (initial and boundary conditions) + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); + auto problem = std::make_shared(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(problem, fvGridGeometry); + gridVariables->init(x, xOld); + + // get some time loop parameters + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + const auto tEnd = getParam("TimeLoop.TEnd"); + const auto maxDt = getParam("TimeLoop.MaxTimeStepSize"); + auto dt = getParam("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("TimeLoop.Restart"); + + // intialize the vtk output module + using VtkOutputFields = typename GET_PROP_TYPE(TypeTag, VtkOutputFields); + VtkOutputModule 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>(restartTime, dt, tEnd); + timeLoop->setMaxTimeStepSize(maxDt); + problem->setTimeLoop(timeLoop); + + // the assembler with time loop for instationary problem + using Assembler = FVAssembler; + auto assembler = std::make_shared(problem, fvGridGeometry, gridVariables, timeLoop); + + // the linear solver + using LinearSolver = AMGBackend; + auto linearSolver = std::make_shared(leafGridView, fvGridGeometry->dofMapper()); + + // the non-linear solver + using NewtonSolver = Dumux::NewtonSolver; + NewtonSolver nonLinearSolver(assembler, linearSolver); + + // time loop + timeLoop->start(); do + { + // set previous solution for storage evaluations + assembler->setPreviousSolution(xOld); + + // solve the non-linear system with time step control + nonLinearSolver.solve(x, *timeLoop); + + // 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 the Newton solver + timeLoop->setTimeStepSize(nonLinearSolver.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; } diff --git a/lecture/efm/1p2cvs2p/lens1p2cproblem.hh b/lecture/efm/1p2cvs2p/lens1p2cproblem.hh index 77782f6..7ba76e2 100644 --- a/lecture/efm/1p2cvs2p/lens1p2cproblem.hh +++ b/lecture/efm/1p2cvs2p/lens1p2cproblem.hh @@ -25,24 +25,28 @@ #ifndef DUMUX_LENS_1P2C_PROBLEM_HH #define DUMUX_LENS_1P2C_PROBLEM_HH -#include -#include +#include +#include #include +#include +#include #include "../1p2c_2p_2p2c/lens1p2cspatialparams.hh" + +// TODO: see in dumux test porousmediumflow 1pnc implicit 1p2ctestproblem.hh an example for correct implementation of neumann BC. namespace Dumux { template -class LensOnePTwoCProblem; +class LensOnePTwoCProblem; // : public PorousMediumFlowProblem; ////////// // Specify the properties for the lens problem ////////// namespace Properties { -NEW_TYPE_TAG(LensOnePTwoCProblem, INHERITS_FROM(BoxOnePTwoC)); +NEW_TYPE_TAG(LensOnePTwoCProblem, INHERITS_FROM(OnePNC, BoxModel)); // Set the grid type SET_TYPE_PROP(LensOnePTwoCProblem, Grid, Dune::YaspGrid<2>); @@ -51,22 +55,25 @@ SET_TYPE_PROP(LensOnePTwoCProblem, Grid, Dune::YaspGrid<2>); SET_TYPE_PROP(LensOnePTwoCProblem, Problem, LensOnePTwoCProblem); // set fluid system -SET_TYPE_PROP(LensOnePTwoCProblem, FluidSystem, H2ON2FluidSystem); +SET_PROP(LensOnePTwoCProblem, FluidSystem) +{ +private: + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + static const bool useComplexRelations = true; +public: + using type = FluidSystems::H2ON2; +}; // Set the spatial parameters -SET_TYPE_PROP(LensOnePTwoCProblem, SpatialParams, Lens1p2cSpatialParams); - -// Enable partial reassembly of the jacobian matrix? -SET_BOOL_PROP(LensOnePTwoCProblem, ImplicitEnablePartialReassemble, false); - -// Define whether mole(true) or mass(false) fractions are used -SET_BOOL_PROP(LensOnePTwoCProblem, UseMoles, true); - -// Disable gravity -SET_BOOL_PROP(LensOnePTwoCProblem, ProblemEnableGravity, true); +SET_PROP(LensOnePTwoCProblem, SpatialParams) +{ +private: + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); +public: + using type = Lens1p2cSpatialParams; +}; -// Disable Jacobian recycling -SET_BOOL_PROP(LensOnePTwoCProblem, ImplicitEnableJacobianRecycling, false); } /*! @@ -97,85 +104,63 @@ SET_BOOL_PROP(LensOnePTwoCProblem, ImplicitEnableJacobianRecycling, false); * To run the simulation execute the following line in shell: * ./lens_1p2c 50000 100 */ -template -class LensOnePTwoCProblem : public ImplicitPorousMediaProblem +template +class LensOnePTwoCProblem : public PorousMediumFlowProblem { - typedef ImplicitPorousMediaProblem ParentType; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum - { - // Grid and world dimension - dim = GridView::dimension, - dimWorld = GridView::dimensionworld, + using ParentType = PorousMediumFlowProblem; - // indices of the equations - conti0EqIdx = Indices::conti0EqIdx, - transportEqIdx = Indices::transportEqIdx, - - // indices of the primary variables - pressureIdx = Indices::pressureIdx, - massOrMoleFracIdx = Indices::massOrMoleFracIdx - }; + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using ModelTraits = typename GET_PROP_TYPE(TypeTag, ModelTraits); + using Indices = typename ModelTraits::Indices; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes; - typedef typename GET_PROP_TYPE(TypeTag, TimeManager) TimeManager; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef Dune::FieldVector GlobalPosition; - typedef typename GET_PROP(TypeTag, ParameterTree) ParameterTree; - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; + // using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); + using GridView = typename GET_PROP_TYPE(TypeTag, GridView);// TODO: Do we use now GridCreator? + using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); + + using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; + + using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector); + + using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace; + using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector); + + static constexpr int dim = GridView::dimension; + static constexpr int dimWorld = GridView::dimensionworld; + using Element = typename GridView::template Codim<0>::Entity; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + + using TimeLoopPtr = std::shared_ptr>; + public: /*! * \brief The constructor * - * \param timeManager The time manager - * \param gridView The grid view + * \param fvGridGeometry The Finite-Volume-Grid-Geometry */ - LensOnePTwoCProblem(TimeManager &timeManager, const GridView &gridView) - : ParentType(timeManager, gridView), eps_(1e-8) + LensOnePTwoCProblem( std::shared_ptr fvGridGeometry ) + : ParentType(fvGridGeometry) { FluidSystem::init(); //This overwrites the lens settings made in the spatialparameter file this->spatialParams().setLensCoords({0.8, 2.0}, {4.0, 3.0}); - infiltrationRate_ = getParam("Boundary.InfiltrationRate"); // GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Boundary, InfiltrationRate); + infiltrationRate_ = getParam("Boundary.InfiltrationRate"); infiltrationStartTime_= 1.0e-9; //The infiltrations starts always after the first time step! - infiltrationEndTime_= getParam("Boundary.InfiltrationEndTime"); // GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Boundary, InfiltrationEndTime); + infiltrationEndTime_= getParam("Boundary.InfiltrationEndTime"); - episodeLength_ = getParam("TimeManager.EpisodeLength"); // (TypeTag, Scalar, TimeManager, EpisodeLength); - this->timeManager().startNextEpisode(episodeLength_); + // episodeLength_ = getParam("TimeManager.EpisodeLength"); // (TypeTag, Scalar, TimeManager, EpisodeLength); + // this->timeManager().startNextEpisode(episodeLength_); // the boundary condition data - lowerPressure_ = getParam("Boundary.LowerPressure"); //GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Boundary, LowerPressure); - upperPressure_ = getParam("Boundary.UpperPressure"); // GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Boundary, UpperPressure); + lowerPressure_ = getParam("Boundary.LowerPressure"); + upperPressure_ = getParam("Boundary.UpperPressure"); - paraviewOutput_ = ParameterTree::tree().template get("Output.paraviewOutput", true); - if (!paraviewOutput_) - { - // the number of cells in x and y direction - numCells_ = getParam >("Grid.Cells"); // GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, std::vector, Grid, Cells); - - // Write header for output file - std::ofstream dataFile; - dataFile.open("dumux-out.vgfc"); - // dataFile << "Gridplot" << std::endl; - dataFile << "## This is a DuMuX output for the ViPLab graphics driver. \n"; - dataFile << "## This output file was generated at " << __TIME__ <<", "<< __DATE__<< "\n"; - dataFile << "# x-range " << this->bBoxMin()[0] << " " << this->bBoxMax()[0] << "\n" ; - dataFile << "# y-range " << this->bBoxMin()[1] << " " << this->bBoxMax()[1] << "\n" ; - dataFile << "# x-count " << numCells_[0]+1 << "\n" ; - dataFile << "# y-count " << numCells_[1]+1 << "\n" ; - // dataFile << "# min-color 0 0 0\n"; - // dataFile << "# max-color 255 255 255\n"; - dataFile.close(); - } } /*! @@ -227,9 +212,9 @@ public: values.setAllNeumann(); if (onInlet_(globalPos)) - values.setNeumann(transportEqIdx); + values.setNeumann(FluidSystem::N2Idx); - return BoundaryTypes; + return values; } /*! @@ -247,15 +232,12 @@ public: if (onUpperBoundary_(globalPos)) { - values[pressureIdx] = upperPressure_; - values[massOrMoleFracIdx] = 0.0; + values[Indices::pressureIdx] = upperPressure_; } else if (onLowerBoundary_(globalPos)) { - values[pressureIdx] = lowerPressure_; - values[massOrMoleFracIdx] = 0.0; + values[Indices::pressureIdx] = lowerPressure_; } - // else {values = 0.0;} return values; } @@ -271,11 +253,12 @@ public: */ PrimaryVariables neumannAtPos(const GlobalPosition &globalPos) const { - PrimaryVaribles values(0.0); - // TODO: Apply the new kind of time Management implementation. Or is it maybe already done???? - const Scalar time = this->timeManager().time(); - if (time <= infiltrationEndTime_ && infiltrationStartTime_ <= time && onInlet_(globalPos)) - values[transportEqIdx] = -infiltrationRate_; + PrimaryVariables values(0.0); + + if (time() <= infiltrationEndTime_ && infiltrationStartTime_ <= time() && onInlet_(globalPos)) + values[FluidSystem::N2Idx] = -infiltrationRate_; + + return values; } /*! @@ -292,14 +275,11 @@ public: * generated or annihilate per volume unit. Positive values mean * that mass is created, negative ones mean that it vanishes. */ - /* - void sourceAtPos(PrimaryVariables &values, const GlobalPosition& globalPos) const + NumEqVector sourceAtPos(const GlobalPosition &globalPos) const { - values = Scalar(0.0); - }*/ + return NumEqVector(0.0); - NumEqVector sourceAtPos(const GlobalPosition &globalPos) const - { return NumEqVector(0.0); } + } /*! * \brief Evaluate the initial value for a control volume. @@ -312,63 +292,24 @@ public: */ PrimaryVariables initialAtPos(const GlobalPosition& globalPos) const { - PrimaryVariables values; + PrimaryVariables values(0.0); // no contaminant, hydrostatic pressure - const Scalar depth = this->bBoxMax()[1] - globalPos[1]; - const Scalar height = this->bBoxMax()[1] - this->bBoxMin()[1]; + const Scalar depth = this->fvGridGeometry().bBoxMax()[1] - globalPos[1]; + const Scalar height = this->fvGridGeometry().bBoxMax()[1] - this->fvGridGeometry().bBoxMin()[1]; - values[conti0EqIdx] = upperPressure_ - depth/height*(upperPressure_-lowerPressure_); - values[transportEqIdx] = 0.0; + values[Indices::pressureIdx] = upperPressure_ - depth/height*(upperPressure_-lowerPressure_); return values; } - void writeOutput() + void setTimeLoop(TimeLoopPtr timeLoop) { - if (paraviewOutput_) ParentType::writeOutput(); - else - { - //TODO: This is not finished yet - - const Scalar time = this->timeManager().time(); - if (time<0) return; - - const SolutionVector &sol = this->model().curSol(); - - std::ofstream dataFile; - dataFile.open("dumux-out.vgfc", std::fstream::app); - - dataFile << "# time "<< time <<"\n" ; - dataFile << "# label Concentration \n"; - dataFile << "# min-color 0 0 0\n"; - dataFile << "# max-color 255 255 255\n"; - - for (int j=0; j < numCells_[1]+1; j++) - { - for (int i=0; i < numCells_[0]+1; i++) - { - int currentIdx = i*(numCells_[1]+1)+j; - dataFile << sol[currentIdx][massOrMoleFracIdx]; - if(i != numCells_[0]) // all but last entry - dataFile << " "; - else // write the last entry - dataFile << "\n"; - } - } - dataFile.close(); - } + timeLoop_ = timeLoop; } - bool shouldWriteOutput() const + Scalar time() const { - return this->timeManager().timeStepIndex() == 0 || - this->timeManager().episodeWillBeFinished() || - this->timeManager().willBeFinished(); - } - - void episodeEnd() - { - this->timeManager().startNextEpisode(episodeLength_); + return timeLoop_->time(); } private: @@ -378,7 +319,7 @@ private: */ bool onLowerBoundary_(const GlobalPosition &globalPos) const { - return globalPos[1] < this->bBoxMin()[1] + eps_; + return globalPos[1] < this->fvGridGeometry().bBoxMin()[1] + eps_; } /*! * \brief Returns true if the point is located on the upper boundary @@ -386,7 +327,7 @@ private: */ bool onUpperBoundary_(const GlobalPosition &globalPos) const { - return globalPos[1] > this->bBoxMax()[1] - eps_; + return globalPos[1] > this->fvGridGeometry().bBoxMax()[1] - eps_; } /*! @@ -395,13 +336,14 @@ private: */ bool onInlet_(const GlobalPosition &globalPos) const { - Scalar width = this->bBoxMax()[0] - this->bBoxMin()[0]; - Scalar lambda = (this->bBoxMax()[0] - globalPos[0])/width; - return (onUpperBoundary_(globalPos) && (this->bBoxMax()[0]-0.45*width)/width > lambda - && lambda > (this->bBoxMax()[0]-0.55*width)/width); + Scalar width = this->fvGridGeometry().bBoxMax()[0] - this->fvGridGeometry().bBoxMin()[0]; + Scalar lambda = (this->fvGridGeometry().bBoxMax()[0] - globalPos[0])/width; + + return (onUpperBoundary_(globalPos) && (this->fvGridGeometry().bBoxMax()[0]-0.45*width)/width > lambda + && lambda > (this->fvGridGeometry().bBoxMax()[0]-0.55*width)/width); } - Scalar eps_; + Scalar eps_ = 1e-8; Scalar episodeLength_; Scalar upperPressure_; @@ -410,6 +352,7 @@ private: Scalar infiltrationStartTime_; Scalar infiltrationEndTime_; bool paraviewOutput_; + TimeLoopPtr timeLoop_; std::vector numCells_; }; } //end namespace diff --git a/lecture/efm/1p2cvs2p/lens2pexercise1.cc b/lecture/efm/1p2cvs2p/lens2pexercise1.cc index 6dc2401..4614259 100644 --- a/lecture/efm/1p2cvs2p/lens2pexercise1.cc +++ b/lecture/efm/1p2cvs2p/lens2pexercise1.cc @@ -21,9 +21,32 @@ * * \brief DOC ME! */ -#include "config.h" #include "lens2pproblem.hh" -#include + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include + +#include /*! * \brief Provides an interface for customizing error messages associated with @@ -76,8 +99,152 @@ void usage(const char *progName, const std::string &errorMsg) //////////////////////// // the main function //////////////////////// -int main(int argc, char** argv) +int main(int argc, char** argv) try +{ + using namespace Dumux; + + // define the type tag for this problem + using TypeTag = TTAG(LensOnePTwoCProblem); + + // 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(leafGridView); + fvGridGeometry->update(); + + // the problem (initial and boundary conditions) + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); + auto problem = std::make_shared(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(problem, fvGridGeometry); + gridVariables->init(x, xOld); + + // get some time loop parameters + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + const auto tEnd = getParam("TimeLoop.TEnd"); + const auto maxDivisions = getParam("TimeLoop.MaxTimeStepDivisions"); + const auto maxDt = getParam("TimeLoop.MaxTimeStepSize"); + auto dt = getParam("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("TimeLoop.Restart"); + + // intialize the vtk output module + using VtkOutputFields = typename GET_PROP_TYPE(TypeTag, VtkOutputFields); + VtkOutputModule 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>(restartTime, dt, tEnd); + timeLoop->setMaxTimeStepSize(maxDt); + + // the assembler with time loop for instationary problem + using Assembler = FVAssembler; + auto assembler = std::make_shared(problem, fvGridGeometry, gridVariables, timeLoop); + + // the linear solver + using LinearSolver = AMGBackend; + auto linearSolver = std::make_shared(leafGridView, fvGridGeometry->dofMapper()); + + // the non-linear solver + using NewtonSolver = Dumux::NewtonSolver; + NewtonSolver nonLinearSolver(assembler, linearSolver); + + // time loop + timeLoop->start(); do + { + // set previous solution for storage evaluations + assembler->setPreviousSolution(xOld); + + // solve the non-linear system with time step control + nonLinearSolver.solve(x, *timeLoop); + + // 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 the Newton solver + timeLoop->setTimeStepSize(nonLinearSolver.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 (...) { - typedef TTAG(LensTwoPProblem) TypeTag; - return Dumux::start(argc, argv, usage); + std::cerr << "Unknown exception thrown! ---> Abort!" << std::endl; + return 4; } diff --git a/lecture/efm/1p2cvs2p/lens2pproblem.hh b/lecture/efm/1p2cvs2p/lens2pproblem.hh index c3c14b3..f042629 100644 --- a/lecture/efm/1p2cvs2p/lens2pproblem.hh +++ b/lecture/efm/1p2cvs2p/lens2pproblem.hh @@ -25,18 +25,21 @@ #ifndef DUMUX_LENS2P_PROBLEM_HH #define DUMUX_LENS2P_PROBLEM_HH -#include -#include +#include +#include +#include #include -#include -#include +#include + +#include // old header file: liquidphase.hh +#include // To get the indices??? #include "../1p2c_2p_2p2c/lens2pspatialparams.hh" namespace Dumux { -template +template class LensTwoPProblem; ////////// @@ -44,7 +47,7 @@ class LensTwoPProblem; ////////// namespace Properties { -NEW_TYPE_TAG(LensTwoPProblem, INHERITS_FROM(BoxTwoP, Lens2pSpatialParams)); +NEW_TYPE_TAG(LensTwoPProblem, INHERITS_FROM(TwoP, BoxModel, Lens2pSpatialParams)); // Set the grid type SET_TYPE_PROP(LensTwoPProblem, Grid, Dune::YaspGrid<2>); @@ -53,35 +56,27 @@ SET_TYPE_PROP(LensTwoPProblem, Grid, Dune::YaspGrid<2>); SET_TYPE_PROP(LensTwoPProblem, Problem, LensTwoPProblem); // Set the wetting phase -SET_PROP(LensTwoPProblem, WettingPhase) +/* SET_PROP(LensTwoPProblem, Indices::phase0Idx) // TODO: Component Indices?? { -private: typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; -public: typedef FluidSystems::LiquidPhase > type; -}; +private: using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); +public: using type = typedef FluidSystems::LiquidPhase >; +};*/ + +// TODO : Set the Fluid-System +SET_TYPE_PROP(LensTwoPProblem, + FluidSystem, + FluidSystems:: // Set the non-wetting phase SET_PROP(LensTwoPProblem, NonwettingPhase) { -private: typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; -public: typedef FluidSystems::LiquidPhase > type; +private: using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); +public: using type = typedef FluidSystems::LiquidPhase >; }; -SET_TYPE_PROP(LensTwoPProblem, FluidSystem, TwoPImmiscibleFluidSystem); - -// Enable partial reassembly of the jacobian matrix? -SET_BOOL_PROP(LensTwoPProblem, ImplicitEnablePartialReassemble, false); - -// Enable reuse of jacobian matrices? -SET_BOOL_PROP(LensTwoPProblem, ImplicitEnableJacobianRecycling, true); - -// Write the solutions of individual newton iterations? -SET_BOOL_PROP(LensTwoPProblem, NewtonWriteConvergence, false); +using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; +SET_TYPE_PROP(LensTwoPProblem, FluidSystem, TwoPImmiscibleFluidSystem); -// Use forward differences instead of central differences -SET_INT_PROP(LensTwoPProblem, ImplicitNumericDifferenceMethod, +1); - -// Enable gravity -SET_BOOL_PROP(LensTwoPProblem, ProblemEnableGravity, true); } /*! @@ -118,43 +113,54 @@ SET_BOOL_PROP(LensTwoPProblem, ProblemEnableGravity, true); * To run the simulation execute the following line in shell: * ./test_2p -parameterFile test_2p.input */ -template -class LensTwoPProblem : public ImplicitPorousMediaProblem +template +class LensTwoPProblem : public PorousMediumFlowProblem { - typedef ImplicitPorousMediaProblem ParentType; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; + using ParentType = PorousMediumFlowProblem; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState; - typedef typename GET_PROP_TYPE(TypeTag, WettingPhase) WettingPhase; - typedef typename GET_PROP_TYPE(TypeTag, NonwettingPhase) NonwettingPhase; + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); - enum - { - // primary variable indices - pressureIdx = Indices::pressureIdx, - snIdx = Indices::snIdx, + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using Indices = typename GET_PROP_TYPE(TypeTag, Indices); - // equation indices - contiNEqIdx = Indices::contiNEqIdx, + using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); - // phase indices - wPhaseIdx = Indices::wPhaseIdx, - nPhaseIdx = Indices::nPhaseIdx, + using Element = typename GridView::template Codim<0>::Entity; + using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables); + // using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables); + + + using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); + using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); + + using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; + using SubControlVolume = typename FVElementGeometry::SubControlVolume; + using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace; - // Grid and world dimension - dim = GridView::dimension, - dimWorld = GridView::dimensionworld - }; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes; - typedef typename GET_PROP_TYPE(TypeTag, TimeManager) TimeManager; + using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector); + using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector); + using ElementSolutionVector = typename GET_PROP_TYPE(TypeTag, ElementSolutionVector); - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef Dune::FieldVector GlobalPosition; + // primary variable indices + static constexpr int pressureIdx = Indices::pressureIdx; + static constexpr int snIdx = Indices::snIdx; + // equation indices + static constexpr int contiNEqIdx = Indices::contiNEqIdx; + + // phase indices + static constexpr int wPhaseIdx = Indices::phase0Idx; + static constexpr int nPhaseIdx = Indices::phase1Idx; + + static constexpr int dim = GridView::dimension; + static constexpr int dimWorld = GridView::dimensionworld; + using Element = typename Element::Geometry::GlobalCoordinate; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + // using GlobalPosition = Dune::FieldVector; + + using TimeLoopPtr = std::shared_ptr>; public: /*! * \brief The constructor @@ -162,25 +168,20 @@ public: * \param timeManager The time manager * \param gridView The grid view */ - LensTwoPProblem(TimeManager &timeManager, - const GridView &gridView) - : ParentType(timeManager, gridView), - eps_(1e-8) + LensTwoPProblem(std::shared_ptr fvGridGeometry) + : ParentType(fvGridGeometry) { //This overwrites the lens settings made in the spatialparameter file + // TODO Is this an up to date implementation? this->spatialParams().setLensCoords({0.8, 2.0}, {4.0, 3.0}); - episodeLength_ = getParam("TimeManager.EpisodeLength"); // GET_RUNTIME_PARAM(TypeTag, Scalar, TimeManager.EpisodeLength); - // TODO: Correct this - this->timeManager().startNextEpisode(episodeLength_); - // the boundary condition data - lowerPressure_ = getParam("Boundary.LowerPressure"); //GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Boundary, LowerPressure); - upperPressure_ = getParam(("Boundary.UpperPressure"); //GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Boundary, UpperPressure); + lowerPressure_ = getParam("Boundary.LowerPressure"); + upperPressure_ = getParam(("Boundary.UpperPressure"); - infiltrationRate_ = getParam("Boundary.InfiltrationRate"); // GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Boundary, InfiltrationRate); + infiltrationRate_ = getParam("Boundary.InfiltrationRate"); infiltrationStartTime_= 1.0e-9; //The infiltrations starts always after the first time step! - infiltrationEndTime_= getParam("Boundary.InfiltratinoEndTime"); //GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Boundary, InfiltrationEndTime); + infiltrationEndTime_= getParam("Boundary.InfiltratinoEndTime"); } /*! @@ -269,11 +270,12 @@ public: * For this method, the \a values parameter stores the mass flux * in normal direction of each phase. Negative values mean influx. */ - PrimaryVariables neumannAtPos( - const GlobalPosition &globalPos) const + + PrimaryVariables neumannAtPos( const GlobalPosition &globalPos) const { PrimaryVariables values(0.0); - const Scalar time = this->timeManager().time(); + + const Scalar time = this->timeLoop().time(); if (time <= infiltrationEndTime_ && onInlet_(globalPos)) values[contiNEqIdx] = -infiltrationRate_; // kg/(m*s) @@ -300,10 +302,9 @@ public: * generated or annihilate per volume unit. Positive values mean * that mass is created, negative ones mean that it vanishes. */ - PrimaryVariables sourceAtPos(const GlobalPosition &globalPos) const + numEqVector sourceAtPos(const GlobalPosition &globalPos) const { - PrimaryVariables values (0.0); - return values; + return numEqVector(0.0); } @@ -319,14 +320,15 @@ public: PrimaryVariables initialAtPos( const GlobalPosition &globalPos) const { PrimaryVariables values(0.0); + FluidState fluidState; fluidState.setTemperature(this->temperature()); fluidState.setPressure(FluidSystem::wPhaseIdx, /*pressure=*/1e5); fluidState.setPressure(FluidSystem::nPhaseIdx, /*pressure=*/1e5); // no DNAPL, hydrostatic pressure - const Scalar depth = this->bBoxMax()[1] - globalPos[1]; - const Scalar height = this->bBoxMax()[1] - this->bBoxMin()[1]; + const Scalar depth = this->fvGridGeometry().bBoxMax()[1] - globalPos[1]; + const Scalar height = this->fvGridGeometry().bBoxMax()[1] - this->fvGridGeometry().bBoxMin()[1]; values[pressureIdx] = upperPressure_ - depth/height*(upperPressure_-lowerPressure_); values[snIdx] = 0.0; @@ -335,18 +337,18 @@ public: } // \} - bool shouldWriteOutput() const + + void setTimeLoop(TimeLoopPtr timeLoop) { - return this->timeManager().timeStepIndex() == 0 || - this->timeManager().episodeWillBeFinished() || - this->timeManager().willBeFinished(); + timeLoop_ = timeLoop; } - void episodeEnd() + Scalar time() const { - this->timeManager().startNextEpisode(episodeLength_); + return timeLoop_->time(); } + private: /*! * \brief Returns true if the point is located on the lower boundary @@ -354,7 +356,7 @@ private: */ bool onLowerBoundary_(const GlobalPosition &globalPos) const { - return globalPos[1] < this->bBoxMin()[1] + eps_; + return globalPos[1] < this->fvGridGeometry().bBoxMin()[1] + eps_; } /*! * \brief Returns true if the point is located on the upper boundary @@ -362,7 +364,7 @@ private: */ bool onUpperBoundary_(const GlobalPosition &globalPos) const { - return globalPos[1] > this->bBoxMax()[1] - eps_; + return globalPos[1] > this->fvGridGeometry().bBoxMax()[1] - eps_; } /*! @@ -371,13 +373,13 @@ private: */ bool onInlet_(const GlobalPosition &globalPos) const { - const Scalar width = this->bBoxMax()[0] - this->bBoxMin()[0]; - const Scalar lambda = (this->bBoxMax()[0] - globalPos[0])/width; - return (onUpperBoundary_(globalPos) && (this->bBoxMax()[0]-0.45*width)/width > lambda + eps_ - && (this->bBoxMax()[0]-0.55*width)/width < lambda - eps_); + const Scalar width = this->fvGridGeometry().bBoxMax()[0] - this->fvGridGeometry().bBoxMin()[0]; + const Scalar lambda = (this->fvGridGeometry().bBoxMax()[0] - globalPos[0])/width; + return (onUpperBoundary_(globalPos) && (this->fvGridGeometry().bBoxMax()[0]-0.45*width)/width > lambda + eps_ + && (this->fvGridGeometry().bBoxMax()[0]-0.55*width)/width < lambda - eps_); } - Scalar eps_; + static constexpr Scalar eps_ =1e-8; Scalar episodeLength_; Scalar upperPressure_; @@ -386,6 +388,7 @@ private: Scalar infiltrationStartTime_; Scalar infiltrationEndTime_; }; -} //end namespace + +} //end namespace Dumux #endif diff --git a/lecture/efm/2p/lens2pexercise2.cc b/lecture/efm/2p/lens2pexercise2.cc index 6dc2401..cbe7ca0 100755 --- a/lecture/efm/2p/lens2pexercise2.cc +++ b/lecture/efm/2p/lens2pexercise2.cc @@ -23,7 +23,31 @@ */ #include "config.h" #include "lens2pproblem.hh" -#include + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include + +#include /*! * \brief Provides an interface for customizing error messages associated with @@ -76,8 +100,172 @@ void usage(const char *progName, const std::string &errorMsg) //////////////////////// // the main function //////////////////////// -int main(int argc, char** argv) +int main(int argc, char** argv) try +{ + // typedef TTAG(LensOnePTwoCProblem) TypeTag; + // return Dumux::start(argc, argv, usage); + using namespace Dumux; + + // define the type tag for this problem + using TypeTag = TTAG(LensTwoPProblem); + + // 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(leafGridView); + fvGridGeometry->update(); + + // the problem (initial and boundary conditions) + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); + auto problem = std::make_shared(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(problem, fvGridGeometry); + gridVariables->init(x, xOld); + + // get some time loop parameters + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + const auto tEnd = getParam("TimeLoop.TEnd"); + const auto maxDivisions = getParam("TimeLoop.MaxTimeStepDivisions"); // Q: What is this? Do we need this here? + const auto maxDt = getParam("TimeLoop.MaxTimeStepSize"); + auto dt = getParam("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")) // Fehlt ebenso + restartTime = getParam("TimeLoop.Restart"); + + // intialize the vtk output module + using VtkOutputFields = typename GET_PROP_TYPE(TypeTag, VtkOutputFields); + VtkOutputModule 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>(restartTime, dt, tEnd); + timeLoop->setMaxTimeStepSize(maxDt); + + // the assembler with time loop for instationary problem + using Assembler = FVAssembler; + auto assembler = std::make_shared(problem, fvGridGeometry, gridVariables, timeLoop); + + // the linear solver + using LinearSolver = AMGBackend; + auto linearSolver = std::make_shared(leafGridView, fvGridGeometry->dofMapper()); + + // the non-linear solver + using NewtonSolver = Dumux::NewtonSolver; + NewtonSolver nonLinearSolver(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 the Newton solver + timeLoop->setTimeStepSize(nonLinearSolver.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); + } + + + +} + +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 (...) { - typedef TTAG(LensTwoPProblem) TypeTag; - return Dumux::start(argc, argv, usage); + std::cerr << "Unknown exception thrown! ---> Abort!" << std::endl; + return 4; } diff --git a/lecture/efm/2p/lens2pexercise2.input b/lecture/efm/2p/lens2pexercise2.input index 6cdbee5..1cf657d 100755 --- a/lecture/efm/2p/lens2pexercise2.input +++ b/lecture/efm/2p/lens2pexercise2.input @@ -1,4 +1,4 @@ -[TimeManager] +[TimeLoop] MaxTimeStepSize = 1.0e5 # maximal time step size [s] TEnd = 5.0e6 # end time of the simulation [s] DtInitial = 1e2 # initial time step for the simulation [s] diff --git a/lecture/efm/2p/lens2pproblem.hh b/lecture/efm/2p/lens2pproblem.hh index d8b86e9..92547c8 100644 --- a/lecture/efm/2p/lens2pproblem.hh +++ b/lecture/efm/2p/lens2pproblem.hh @@ -25,19 +25,25 @@ #ifndef DUMUX_LENS2P_PROBLEM_HH #define DUMUX_LENS2P_PROBLEM_HH -#include -#include +#include +#include #include -#include -#include + +// TODO: dnapl.hh does not exist anymore -> changed to trichloroethylene.hh +#include +// liquidphase.hh does not exist anymore -> changed to liquidphase2c.hh +#include #include +#include +// #include +#include #include "../1p2c_2p_2p2c/lens2pspatialparams.hh" namespace Dumux { -template +template class LensTwoPProblem; ////////// @@ -47,34 +53,45 @@ class LensTwoPProblem; namespace Properties { -NEW_TYPE_TAG(LensTwoPProblem, INHERITS_FROM(BoxTwoP, Lens2pSpatialParams)); - +// NEW_TYPE_TAG(LensTwoPProblem, INHERITS_FROM(TwoP, BoxModel, Lens2pSpatialParams)); + // TODO: Which Tags are the correct ancestors? +NEW_TYPE_TAG(LensTwoPProblem, INHERITS_FROM(TwoP, Lens2pSpatialParams)); // Set the grid type SET_TYPE_PROP(LensTwoPProblem, Grid, Dune::YaspGrid<2>); // Set the problem property SET_TYPE_PROP(LensTwoPProblem, Problem, LensTwoPProblem); -// Set the wetting phase +// TODO: Do we need this? : Set the problem Type +// SET_TYPE_PROP(LensTwoPProblem, FluidSystem, TwoPImmiscibleFluidSystem); + +/* + * This is the old way to implement the fluid system. +// Set the wetting phase -> This is the 0th-Phase SET_PROP(LensTwoPProblem, WettingPhase) { -private: typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; +private: using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); -public: typedef FluidSystems::LiquidPhase > type; +public: using type = typedef FluidSystems::LiquidPhase >; // original version: typedef FluidSystems::LiquidPhase > type; }; - -// Set the non-wetting phase +// Set the non-wetting phase -> This is the 1st-Phase SET_PROP(LensTwoPProblem, NonwettingPhase) { -private: typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - -public: typedef FluidSystems::LiquidPhase > type; +private: using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); +public: using type = typedef FluidSystems::LiquidPhase >;// original version: typedef FluidSystems::LiquidPhase > type; +}; +*/ +//kaiw: new vesion according to dumux/test/porousmediumflow/2p/implicit/boxdfm/problem.hh +// Set the fluid fluid system +SET_PROP(LensTwoPProblem, FluidSystem) +{ + using Scalar = typename GET_PROP_TYPE(TypeTag,Scalar); + using WettingPhase = FluidSystems::OnePLiquid >; + using NonwettingPhase = FluidSystems::OnePLiquid >; + using type = FluidSystems::TwoPImmiscible; }; -SET_TYPE_PROP(LensTwoPProblem, FluidSystem, TwoPImmiscibleFluidSystem); -// Enable gravity -SET_BOOL_PROP(LensTwoPProblem, ProblemEnableGravity, true); } /*! * \ingroup TwoPBoxProblems @@ -107,49 +124,47 @@ SET_BOOL_PROP(LensTwoPProblem, ProblemEnableGravity, true); * To run the simulation execute the following line in shell: * ./lens_2p 50000 100 */ -template -class LensTwoPProblem : public ImplicitPorousMediaProblem +template +class LensTwoPProblem : public PorousMediumFlowProblem { - typedef ImplicitPorousMediaProblem ParentType; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; + using ParentType = typename PorousMediumFlowProblem; - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; + using Params = typename GET_PROP(TypeTag, ParameterTree); - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState; - typedef typename GET_PROP_TYPE(TypeTag, WettingPhase) WettingPhase; - typedef typename GET_PROP_TYPE(TypeTag, NonwettingPhase) NonwettingPhase; - // TODO: get all using-directives which have to be defined - // New (kaiw): - using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); - using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using Indices = typename GET_PROP_TYPE(TypeTag, Indices); + + using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); + using FluidState = typename GET_PROP_TYPE(TypeTag, FluidState); + using WettingPhase = typename GET_PROP_TYPE(TypeTag, WettingPhase); // kaiw: New PropertyTag for this and the next line? Check this if there are compilererrors. + using NonwettingPhase = typename GET_PROP_TYPE(TypeTag, NonwettingPhase); + + using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); + using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); - enum - { // primary variable indices - pressureIdx = Indices::pressureIdx, - snIdx = Indices::snIdx, + static constexpr int pressureIdx = Indices::pressureIdx; + static constexpr int snIdx = Indices::snIdx; // equation indices - contiNEqIdx = Indices::contiNEqIdx, + static constexpr int contiNEqIdx = Indices::contiNEqIdx; // phase indices - wPhaseIdx = Indices::wPhaseIdx, - nPhaseIdx = Indices::nPhaseIdx, - + // static constexpr int wPhaseIdx = Indices::wPhaseIdx, + static constexpr int wPhaseIdx = Indices::phase0Idx; + // static constexpr int nPhaseIdx = Indices::nPhaseIdx, + static constexpr int nPhaseIdx = Indices:phase1Idx; // Grid and world dimension - dim = GridView::dimension, - dimWorld = GridView::dimensionworld + // dim = GridView::dimension, + // dimWorld = GridView::dimensionworld }; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes; - typedef typename GET_PROP_TYPE(TypeTag, TimeManager) TimeManager; - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector; + static constexpr int dim = GridView::dimension; + static constexpr int dimWorld = GridView::dimensionworld; + using GlobalPosition = Dune::FieldVector; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef Dune::FieldVector GlobalPosition; - typedef typename GET_PROP(TypeTag, ParameterTree) Params; + using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector); public: /*! @@ -158,28 +173,30 @@ public: * \param timeManager The time manager * \param gridView The grid view */ - LensTwoPProblem(TimeManager &timeManager, const GridView &gridView) - : ParentType(timeManager, gridView), eps_(1e-6) + LensTwoPProblem( std::shared_ptr fvGridGeometry) + : ParentType(fvGridGeometry) { - episodeLength_ = getParam("TimeManager.EpisodeLength"); //GET_RUNTIME_PARAM(TypeTag, Scalar, TimeManager.EpisodeLength); - this->timeManager().startNextEpisode(episodeLength_); + // TODO Check if all the timeManager related actions are now implemented in the main-function + episodeLength_ = getParam("TimeLoop.EpisodeLength"); + // this->timeManager().startNextEpisode(episodeLength_); //this overwrites the settings in the spatialparameters file! - this->spatialParams().setLensCoords({0.0, 0.5}, {3.0, 1.0}); + // this->spatialParams().setLensCoords({0.0, 0.5}, {3.0, 1.0}); // the boundary condition data - lowerPressure_ = getParam("Boundary.LowerPressure"); // GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Boundary, LowerPressure); - upperPressure_ = getParam("Boundary.UpperPressure"); // GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Boundary, UpperPressure); + lowerPressure_ = getParam("Boundary.LowerPressure"); + upperPressure_ = getParam("Boundary.UpperPressure"); // infiltration parameters - infiltrationRate_ = getParam("Boundary.InfiltrationRate"); // GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Boundary, InfiltrationRate); + infiltrationRate_ = getParam("Boundary.InfiltrationRate"); infiltrationStartTime_= 1.0e-9; //The infiltrations starts always after the first time step! - infiltrationEndTime_= getParam("Boundary.InfiltrationEndTime"); // GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Boundary, InfiltrationEndTime); + infiltrationEndTime_= getParam("Boundary.InfiltrationEndTime"); + // TODO Check, if this is now in the main-function paraviewOutput_ = Params::tree().template get("Output.paraviewOutput", true); if (!paraviewOutput_) { - numCells_ = getParam >("Grid.Cells"); // GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, std::vector, Grid, Cells); + numCells_ = getParam >("Grid.Cells"); // Write header for output file std::ofstream dataFile; @@ -187,8 +204,8 @@ public: // dataFile << "Gridplot" << std::endl; dataFile << "## This is a DuMuX output for the ViPLab graphics driver. \n"; dataFile << "## This output file was generated at " << __TIME__ <<", "<< __DATE__<< "\n"; - dataFile << "# x-range " << this->bBoxMin()[0] << " " << this->bBoxMax()[0] << "\n" ; - dataFile << "# y-range " << this->bBoxMin()[1] << " " << this->bBoxMax()[1] << "\n" ; + dataFile << "# x-range " << this->fvGridGeometry().bBoxMin()[0] << " " << this->fvGridGeometry().bBoxMax()[0] << "\n" ; + dataFile << "# y-range " << this->fvGridGeometry().bBoxMin()[1] << " " << this->fvGridGeometry().bBoxMax()[1] << "\n" ; dataFile << "# x-count " << numCells_[0]+1 << "\n" ; dataFile << "# y-count " << numCells_[1]+1 << "\n" ; // dataFile << "# min-color 0 0 0\n"; @@ -235,21 +252,6 @@ public: * \param values The boundary types for the conservation equations * \param globalPos The position of the center of the finite volume */ - - - /* void boundaryTypesAtPos(BoundaryTypes &values, - const GlobalPosition &globalPos) const - { - if (onUpperBoundary_(globalPos) || onLowerBoundary_(globalPos)) - values.setAllDirichlet(); - else - values.setAllNeumann(); - - if (onInlet_(globalPos)) - values.setNeumann(contiNEqIdx); - }*/ - - // Neu (kaiw): BoundaryTypes boundaryTypesAtPos(const GlobalPosition &globalPos) { BoundaryTypes bcTypes; @@ -272,7 +274,6 @@ public: * * For this method, the \a values parameter stores primary variables. */ - PrimaryVariables dirichletAtPos(const GlobalPosition &globalPos) const { PrimaryVariables Values(0.0); @@ -291,8 +292,6 @@ public: values[pressureIdx] = lowerPressure_; values[snIdx] = 0.0; } - /* else // kaiw: This is not necessary anymore because of the definition in line 278 where the object values is defined. - values = 0.0;*/ return Values; } @@ -313,8 +312,7 @@ public: { PrimaryVariables values(0.0); - // TODO: Find out, how the TimeManager is now implemented and change this paragraph - const Scalar time = this->timeManager().time(); + const Scalar time = this->timeLoop().time(); if (time >= infiltrationStartTime_ && time <= infiltrationEndTime_ && onInlet_(globalPos)) values[contiNEqIdx] = -infiltrationRate_; // kg/(m*s) @@ -340,12 +338,9 @@ public: * generated or annihilate per volume unit. Positive values mean * that mass is created, negative ones mean that it vanishes. */ - - // kaiw: changed - PointSource sourceAtPos(const GlobalPosition &globalPos) const + numEqVector sourceAtPos(const GlobalPosition &globalPos) const { - PointSource ps; - return ps; + return numEqVector(0.0); } @@ -367,8 +362,8 @@ public: fluidState.setPressure(FluidSystem::nPhaseIdx, /*pressure=*/1e5); // no DNAPL, hydrostatic pressure - const Scalar depth = this->bBoxMax()[1] - globalPos[1]; - const Scalar height = this->bBoxMax()[1] - this->bBoxMin()[1]; + const Scalar depth = this->fvGridGeometry().bBoxMax()[1] - globalPos[1]; + const Scalar height = this->fvGridGeometry().bBoxMax()[1] - this->bBoxMin()[1]; values[pressureIdx] = upperPressure_ - depth/height*(upperPressure_-lowerPressure_); values[snIdx] = 0.0; @@ -376,58 +371,6 @@ public: return values; } - void writeOutput() - { - if (paraviewOutput_) ParentType::writeOutput(); - else - { - //TODO: This is not finished yet - - const Scalar time = this->timeManager().time(); - if (time<0) return; - - const SolutionVector &sol = this->model().curSol(); - - std::ofstream dataFile; - dataFile.open("dumux-out.vgfc", std::fstream::app); - - dataFile << "# time "<< time <<"\n" ; - dataFile << "# label Concentration \n"; - dataFile << "# min-color 0 0 0\n"; - dataFile << "# max-color 255 255 255\n"; - - for (int j=0; j < numCells_[1]+1; j++) - { - for (int i=0; i < numCells_[0]+1; i++) - { - int currentIdx = i*(numCells_[1]+1)+j; - dataFile << sol[currentIdx][snIdx]; - if(i != numCells_[0]) // all but last entry - dataFile << " "; - else // write the last entry - { - dataFile << "\n"; - } - } - } - dataFile.close(); - } - } - // \} - - bool shouldWriteOutput() const - { - return - this->timeManager().timeStepIndex() == 0 || - this->timeManager().episodeWillBeFinished() || - this->timeManager().willBeFinished(); - } - - void episodeEnd() - { - this->timeManager().startNextEpisode(episodeLength_); - } - private: /*! * \brief Returns true if the point is located on the lower boundary @@ -435,7 +378,7 @@ private: */ bool onLowerBoundary_(const GlobalPosition &globalPos) const { - return globalPos[1] < this->bBoxMin()[1] + eps_; + return globalPos[1] < this->fvGridGeometry().bBoxMin()[1] + eps_; } /*! * \brief Returns true if the point is located on the upper boundary @@ -443,7 +386,7 @@ private: */ bool onUpperBoundary_(const GlobalPosition &globalPos) const { - return globalPos[1] > this->bBoxMax()[1] - eps_; + return globalPos[1] > this->fvGridGeometry().bBoxMax()[1] - eps_; } /*! @@ -454,13 +397,14 @@ private: */ bool onInlet_(const GlobalPosition &globalPos) const { - const Scalar width = this->bBoxMax()[0] - this->bBoxMin()[0]; - const Scalar lambda = (this->bBoxMax()[0] - globalPos[0])/width; - return (onUpperBoundary_(globalPos) && (this->bBoxMax()[0]-0.40*width)/width > lambda + eps_ - && (this->bBoxMax()[0]-0.60*width)/width < lambda - eps_); + const Scalar width = this->fvGridGeometry().bBoxMax()[0] - this->fvGridGeometry().bBoxMin()[0]; + const Scalar lambda = (this->fvGridGeometry().bBoxMax()[0] - globalPos[0])/width; + return (onUpperBoundary_(globalPos) && (this->fvGridGeometry().bBoxMax()[0]-0.40*width)/width > lambda + eps_ + && (this->fvGridGeometry().bBoxMax()[0]-0.60*width)/width < lambda - eps_); } - Scalar eps_; + static constexpr Scalar eps_ = 1e-6; + Scalar episodeLength_; Scalar upperPressure_; @@ -468,9 +412,11 @@ private: Scalar infiltrationRate_; Scalar infiltrationStartTime_; Scalar infiltrationEndTime_; + bool paraviewOutput_; + std::vector numCells_; }; } //end namespace -#endif +#endif // DUMUX_LENS2P_PROBLEM_HH diff --git a/lecture/mhs/groundwater/groundwater.cc b/lecture/mhs/groundwater/groundwater.cc index eac2c87..695dd6e 100644 --- a/lecture/mhs/groundwater/groundwater.cc +++ b/lecture/mhs/groundwater/groundwater.cc @@ -57,8 +57,172 @@ void usage(const char *progName, const std::string &errorMsg) //////////////////////// // the main function //////////////////////// -int main(int argc, char** argv) +int main(int argc, char** argv) try { - typedef TTAG(GroundwaterProblem) ProblemTypeTag; - return Dumux::start(argc, argv, usage); + // typedef TTAG(LensOnePTwoCProblem) TypeTag; + // return Dumux::start(argc, argv, usage); + using namespace Dumux; + + // define the type tag for this problem + using TypeTag = TTAG(GroundwaterProblem); + + // 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(leafGridView); + fvGridGeometry->update(); + + // the problem (initial and boundary conditions) + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); + auto problem = std::make_shared(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(problem, fvGridGeometry); + gridVariables->init(x, xOld); + + // get some time loop parameters + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + const auto tEnd = getParam("TimeLoop.TEnd"); + const auto maxDivisions = getParam("TimeLoop.MaxTimeStepDivisions"); // Q: What is this? Do we need this here? + const auto maxDt = getParam("TimeLoop.MaxTimeStepSize"); + auto dt = getParam("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")) // Fehlt ebenso + restartTime = getParam("TimeLoop.Restart"); + + // intialize the vtk output module + using VtkOutputFields = typename GET_PROP_TYPE(TypeTag, VtkOutputFields); + VtkOutputModule 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>(restartTime, dt, tEnd); + timeLoop->setMaxTimeStepSize(maxDt); + + // the assembler with time loop for instationary problem + using Assembler = FVAssembler; + auto assembler = std::make_shared(problem, fvGridGeometry, gridVariables, timeLoop); + + // the linear solver + using LinearSolver = AMGBackend; + auto linearSolver = std::make_shared(leafGridView, fvGridGeometry->dofMapper()); + + // the non-linear solver + using NewtonSolver = Dumux::NewtonSolver; + NewtonSolver nonLinearSolver(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 the Newton solver + timeLoop->setTimeStepSize(nonLinearSolver.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); + } + + + +} + +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; } diff --git a/lecture/mhs/groundwater/groundwater.input b/lecture/mhs/groundwater/groundwater.input index 189eea1..e4576e2 100644 --- a/lecture/mhs/groundwater/groundwater.input +++ b/lecture/mhs/groundwater/groundwater.input @@ -1,4 +1,4 @@ -[TimeManager] +[TimeLoop] TEnd = 1.0 DtInitial = 1.0 diff --git a/lecture/mhs/groundwater/groundwaterproblem.hh b/lecture/mhs/groundwater/groundwaterproblem.hh index 033614b..fae369a 100644 --- a/lecture/mhs/groundwater/groundwaterproblem.hh +++ b/lecture/mhs/groundwater/groundwaterproblem.hh @@ -60,9 +60,6 @@ public: // Set the spatial parameters SET_TYPE_PROP(GroundwaterProblem, SpatialParams, Dumux::GroundwaterSpatialParams); -// Enable gravity -SET_BOOL_PROP(GroundwaterProblem, ProblemEnableGravity, false); - //Set the problem SET_TYPE_PROP(GroundwaterProblem, Problem, Dumux::GroundwaterProblem); } @@ -73,15 +70,31 @@ SET_TYPE_PROP(GroundwaterProblem, Problem, Dumux::GroundwaterProblem); * \brief Dumux-equivalent for GRUWA (1p-stationary, finite volumes) */ template -class GroundwaterProblem: public DiffusionProblem1P +class GroundwaterProblem: public PorousMediumFlowProblem // TODO: old version: DiffusionProblem1P now correct? { - typedef DiffusionProblem1P ParentType; - typedef typename GET_PROP_TYPE(TypeTag, TimeManager) TimeManager; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, Fluid) Fluid; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes; - typedef typename GET_PROP_TYPE(TypeTag, CellData) CellData; + using ParentType = PorousMediumFlowProblem; + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); + + using Indices = typename GET_PROP_TYPE(TypeTag, Indices); + + + using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); + using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); + + using Element = typename GridView::template Codim<0>::Entity; + + + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; + using SubControlVolume = typename FVElementGeometry::SubControlVolume; + using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace; + using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); + using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables); + + using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector); + using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector); + using ResolutionVector = typename Dune::FieldVector; enum { @@ -89,13 +102,7 @@ class GroundwaterProblem: public DiffusionProblem1P dim = GridView::dimension, dimWorld = GridView::dimensionworld }; - - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GridView::Traits::template Codim<0>::Entity Element; - typedef Dune::FieldVector GlobalPosition; - typedef typename Dune::FieldVector ResolutionVector; - - static constexpr double eps_ = 1e-6; + using GlobalPosition = Dune::FieldVector; struct BoundarySegment { @@ -108,6 +115,7 @@ class GroundwaterProblem: public DiffusionProblem1P { return globalPos[axis] > from - eps_ && globalPos[axis] < to + eps_; } }; + // TODO: Is this to be changed? Do we now do this with NumEqVector? struct Source { Dune::FieldVector globalPos; @@ -116,16 +124,16 @@ class GroundwaterProblem: public DiffusionProblem1P }; public: - GroundwaterProblem(TimeManager& timeManager, const GridView &gridView) - : ParentType(timeManager, gridView), velocity_(*this) + GroundwaterProblem(std::shared_ptr fvGridGeometry) + : ParentType(fvGridGeometry) // TODO where to place: velocity_(*this) { Fluid::Component::setViscosity(0.001); Fluid::Component::setDensity(1000); // Read input parameters and write them into private variables - domainSize_ = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, GlobalPosition, Grid, UpperRight); - geometryDepth_ = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Grid, Depth); - numCells_ = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, ResolutionVector, Grid, Cells); + domainSize_ = getParam("Grid.UpperRight"); + geometryDepth_ = getParam("Grid._Depth"); + numCells_ = getParam("Grid.Cells"); // check input for too large grid size if (numCells_[0]*numCells_[1] > 10000) @@ -141,7 +149,8 @@ public: } // Read sources - std::vector sources = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, std::vector, Source, Sources); + // TODO: Has this to be changed? Implementation with class PointSource? + std::vector sources = getParam >("Source.Sources"); unsigned int numSources = std::trunc(sources.size()/3); for (int sourceCount = 0; sourceCount < numSources; sourceCount++) @@ -158,8 +167,9 @@ public: } // Read boundary conditions - std::vector bc = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, std::vector, BoundaryConditions, Left); + std::vector bc = getParam >("BoundaryConditions.Left"); int NumberOfSegments = std::trunc(bc.size()/4); + for (int segmentCount = 0; segmentCount < NumberOfSegments; segmentCount++) { BoundarySegment tempSegment; @@ -169,7 +179,7 @@ public: tempSegment.value = bc[segmentCount*4+3]; boundaryConditions_[2].push_back(tempSegment); } - bc = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, std::vector, BoundaryConditions, Right); + bc = getParam >("BoundaryConditions.Right"); NumberOfSegments = std::trunc(bc.size()/4); for (int segmentCount = 0; segmentCount < NumberOfSegments; segmentCount++) { @@ -180,7 +190,7 @@ public: tempSegment.value = bc[segmentCount*4+3]; boundaryConditions_[3].push_back(tempSegment); } - bc = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, std::vector, BoundaryConditions, Bottom); + bc = getParam >("BoundaryConditions.Bottom"); NumberOfSegments = std::trunc(bc.size()/4); for (int segmentCount = 0; segmentCount < NumberOfSegments; segmentCount++) { @@ -191,7 +201,7 @@ public: tempSegment.value = bc[segmentCount*4+3]; boundaryConditions_[1].push_back(tempSegment); } - bc = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, std::vector, BoundaryConditions, Top); + bc = getParam >("BoundaryConditions.Top"); NumberOfSegments = std::trunc(bc.size()/4); for (int segmentCount = 0; segmentCount < NumberOfSegments; segmentCount++) { @@ -239,15 +249,17 @@ public: } //!source term [kg/(m^3 s)] (or in 2D [kg/(m^2 s)]). - void source(PrimaryVariables& values, const Element& element) const + NumEqVector source(, const Element& element) const { - values = 0; + NumEqVector values(0.0); Scalar density=Fluid::density(0.0,0.0); for (unsigned int sourceCount = 0; sourceCount != sources_.size(); sourceCount++) { if (this->variables().index(element) == sources_[sourceCount].index) values += sources_[sourceCount].q*density/element.geometry().volume()/geometryDepth_; } + + return values; } /*! @@ -255,9 +267,10 @@ public: * * BC can be dirichlet (pressure) or neumann (flux). */ - void boundaryTypesAtPos(BoundaryTypes &bcType, - const GlobalPosition& globalPos) const + BoundaryTypes boundaryTypesAtPos(const GlobalPosition& globalPos) const { + BoundaryTypes bcType; + double coordinate = 0.0; int boundaryIndex = 0; // top boundary @@ -296,16 +309,18 @@ public: bcType.setAllNeumann(); else bcType.setAllDirichlet(); - return; + return; // kaiw: What is this here?! } } bcType.setAllNeumann(); + + return bcType; } //! return Dirichlet conditions (pressure, [Pa]) - void dirichletAtPos(PrimaryVariables &values, - const GlobalPosition &globalPos) const + PrimaryVariables dirichletAtPos( const GlobalPosition &globalPos) const { + PrimaryVariables values; double coordinate = 0; int boundaryIndex = 0; // top boundary @@ -344,12 +359,16 @@ public: return; } } - values = 0; + + return values; // original version: values = 0; } //! return Neumann conditions (flux, [kg/(m^2 s)]) - void neumannAtPos(PrimaryVariables &values, const GlobalPosition& globalPos) const + PrimaryVariables + neumannAtPos(const GlobalPosition& globalPos) const { + PrimaryVariables values; + double coordinate = 0; int boundaryIndex = 0; // top boundary @@ -389,13 +408,16 @@ public: } } values = 0; + + return values; } - bool shouldWriteOutput () + /* bool shouldWriteOutput () { return (this->timeManager().time() >= 0); - } + }*/ + // kaiw: do we need this anymore? void writeOutput() { ParentType::writeOutput(); @@ -471,11 +493,12 @@ public: } private: - std::vector sources_; + std::vector sources_; // TODO change type to NumEqVector? std::vector boundaryConditions_[4]; GlobalPosition domainSize_; ResolutionVector numCells_; + static constexpr double eps_ = 1e-6; Scalar geometryDepth_; Dumux::FVVelocity velocity_; }; diff --git a/lecture/mhs/groundwater/groundwaterspatialparams.hh b/lecture/mhs/groundwater/groundwaterspatialparams.hh index 39c20b6..d27e926 100644 --- a/lecture/mhs/groundwater/groundwaterspatialparams.hh +++ b/lecture/mhs/groundwater/groundwaterspatialparams.hh @@ -31,21 +31,24 @@ namespace Dumux * \ingroup IMPETtests * \brief spatial parameters for the test problem for diffusion models. */ -template -class GroundwaterSpatialParams: public FVSpatialParamsOneP +template< +class GroundwaterSpatialParams: public FVSpatialParamsOneP { - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - enum + /*enum { // grid and world dimension dim = GridView::dimension, dimWorld = GridView::dimensionworld - }; + };*/ + static constexpr dim = GridView::dimension; + static constexpr dimWorld = GridView::dimensionworld; - typedef Dune::FieldVector GlobalPosition; - typedef Dune::FieldMatrix Tensor; + using Element = typename GridView::template Codim<0>::Entity; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + using Tensor = Dune::FieldMatrix;// original: typedef Dune::FieldMatrix Tensor; struct Lens { @@ -56,8 +59,6 @@ class GroundwaterSpatialParams: public FVSpatialParamsOneP const GlobalPosition lowerLeft; const Scalar permeability; }; - - typedef typename GridView::Traits::template Codim<0>::Entity Element; static const unsigned int numEq = 1; public: @@ -68,11 +69,11 @@ public: const Scalar permFactor = 0.001/(1000*9.81); // the background permeability - auto kii = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, SpatialParams, Permeability)*permFactor; + auto kii = getParam("SpatialParams.Permeability")*permFactor; permeability_ = {{kii, 0}, {0, kii}}; // Read the lenses - std::vector lenses = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, std::vector, SpatialParams, Lenses); + std::vector lenses = getParam >("SpatialParams.Lenses"); unsigned int numLenses = std::trunc(lenses.size()/5); // make it robust by truncating for (unsigned int lensIdx = 0; lensIdx < numLenses; ++lensIdx) @@ -94,6 +95,7 @@ public: { // the permeabilty is the lens permeability lensPermeability_ = {{lens.permeability, 0}, {0, lens.permeability}}; + return lensPermeability_; } } @@ -103,23 +105,30 @@ public: } Scalar porosity(const Element& element) const - { return porosity_; } + { + return porosity_; + } private: + bool isInLens_(const Lens& lens, const GlobalPosition& globalPos) const { for (unsigned int dimIdx = 0; dimIdx < dimWorld; ++dimIdx) { if (globalPos[dimIdx] < lens.lowerLeft[dimIdx] + eps_ || globalPos[dimIdx] > lens.upperRight[dimIdx] - eps_) + return false; } + return true; } const Scalar eps_ = 1e-6; + const Scalar porosity_ = 0.2; Tensor permeability_; mutable Tensor lensPermeability_; + std::vector lenses_; }; diff --git a/lecture/mm/buckleyleverett/buckleyleverettanalyticsolution.hh b/lecture/mm/buckleyleverett/buckleyleverettanalyticsolution.hh index b80a6a5..0d448c7 100644 --- a/lecture/mm/buckleyleverett/buckleyleverettanalyticsolution.hh +++ b/lecture/mm/buckleyleverett/buckleyleverettanalyticsolution.hh @@ -67,20 +67,20 @@ struct CheckMaterialLaw > > template class BuckleyLeverettAnalytic { - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, Grid) Grid; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); + using Grid = typename GET_PROP_TYPE(TypeTag, Grid); + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using Scalar typename GET_PROP_TYPE(TypeTag, Scalar); - typedef typename GET_PROP_TYPE(TypeTag, SpatialParams) SpatialParams; - typedef typename SpatialParams::MaterialLaw MaterialLaw; - typedef typename MaterialLaw::Params MaterialLawParams; + using SpatialParams = typename GET_PROP_TYPE(TypeTag, SpatialParams); + using MaterialLaw = typename SpatialParams::MaterialLaw; + using MaterialLawParams = typename MaterialLaw::Params; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState; + using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); + using FluidState = typename GET_PROP_TYPE(TypeTag, FluidState); - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - typedef typename GET_PROP_TYPE(TypeTag, CellData) CellData; + using Indices = typename GET_PROP_TYPE(TypeTag, Indices); + using CellData = typename GET_PROP_TYPE(TypeTag, CellData); enum { @@ -93,10 +93,10 @@ template class BuckleyLeverettAnalytic satEqIdx = Indices::satEqIdx, }; - typedef Dune::BlockVector > BlockVector; - typedef typename GridView::Traits::template Codim<0>::Entity Element; - typedef typename GridView::template Codim<0>::Iterator ElementIterator; - typedef Dune::FieldVector GlobalPosition; + using BlockVector = Dune::BlockVector >; + using Element = typename GridView::Traits::template Codim<0>::Entity; + using ElementIterator typename GridView::template Codim<0>::Iterator; + using GlobalPosition 0 Dune::FieldVector; public: @@ -113,6 +113,7 @@ public: return; } + /*! * \brief DOC ME! * \param materialLawParams DOC ME! diff --git a/lecture/mm/buckleyleverett/buckleyleverettexercise.cc b/lecture/mm/buckleyleverett/buckleyleverettexercise.cc index 942d733..cb5dafe 100644 --- a/lecture/mm/buckleyleverett/buckleyleverettexercise.cc +++ b/lecture/mm/buckleyleverett/buckleyleverettexercise.cc @@ -63,6 +63,7 @@ void usage(const char *progName, const std::string &errorMsg) } } +// TODO: From what kind of test should we copy the main function? int main(int argc, char** argv) { typedef TTAG(BuckleyLeverettProblem) TypeTag; diff --git a/lecture/mm/buckleyleverett/buckleyleverettexercise.input b/lecture/mm/buckleyleverett/buckleyleverettexercise.input index 96b1718..de60138 100644 --- a/lecture/mm/buckleyleverett/buckleyleverettexercise.input +++ b/lecture/mm/buckleyleverett/buckleyleverettexercise.input @@ -1,4 +1,4 @@ -[TimeManager] +[TimeLoop] TEnd = 2e7 # end time of the simulation [s] DtInitial = 1e3 # initial time step for the simulation [s] diff --git a/lecture/mm/buckleyleverett/buckleyleverettproblem.hh b/lecture/mm/buckleyleverett/buckleyleverettproblem.hh index 0855661..4d18ac6 100644 --- a/lecture/mm/buckleyleverett/buckleyleverettproblem.hh +++ b/lecture/mm/buckleyleverett/buckleyleverettproblem.hh @@ -36,7 +36,7 @@ namespace Dumux { -template +template class BuckleyLeverettProblem; ////////// @@ -85,22 +85,22 @@ template class BuckleyLeverettProblem: public IMPESProblem2P { typedef IMPESProblem2P ParentType; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; + using Indices = typename GET_PROP_TYPE(TypeTag, Indices); - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState; + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - typedef typename GET_PROP_TYPE(TypeTag, WettingPhase) WettingPhase; - typedef typename GET_PROP_TYPE(TypeTag, NonwettingPhase) NonwettingPhase; + using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); + using FluidState = typename GET_PROP_TYPE(TypeTag, FluidState); - typedef typename GET_PROP_TYPE(TypeTag, TimeManager) TimeManager; + using WettingPhase = typename GET_PROP_TYPE(TypeTag, WettingPhase); + using NonwettingPhase = typename GET_PROP_TYPE(TypeTag, NonwettingPhase); - typedef typename GET_PROP_TYPE(TypeTag, CellData) CellData; + using CellData = typename GET_PROP_TYPE(TypeTag, CellData); - typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes; - typedef typename GET_PROP(TypeTag, SolutionTypes)::PrimaryVariables PrimaryVariables; + using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); + using PrimaryVariables = typename GET_PROP(TypeTag, SolutionTypes)::PrimaryVariables; enum { @@ -117,11 +117,10 @@ class BuckleyLeverettProblem: public IMPESProblem2P satEqIdx = Indices::satEqIdx }; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GridView::Traits::template Codim<0>::Entity Element; - typedef typename GridView::Intersection Intersection; - typedef Dune::FieldVector GlobalPosition; - typedef typename GET_PROP(TypeTag, ParameterTree) Params; + using Element = typename GridView::Traits::template Codim<0>::Entity; + using Intersection = typename GridView::Intersection; + using GlobalPosition = Dune::FieldVector; + using Params = typename GET_PROP(TypeTag, ParameterTree); public: /*! @@ -129,32 +128,35 @@ public: * \param timeManager DOC ME! * \param gridView DOC ME! */ - BuckleyLeverettProblem(TimeManager& timeManager, const GridView &gridView) - : ParentType(timeManager, gridView), eps_(1e-8), pLeftBc_(2.0e5), - analyticSolution_(*this, 3e-7), viplabOutput_(*this) + BuckleyLeverettProblem(std::shared_ptr fvGridGeometry) + : ParentType(fvGridGeometry) + { + // TODO: What are these: analyticSolution_(*this, 3e-7), viplabOutput_(*this) + // check the cell size restriction - const auto cells = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, std::vector, Grid, Cells); + const auto cells = getParam >("Grid.Cells"); if (cells[1] != 1) DUNE_THROW(Dune::IOError, "This is a 1D problem. Do not change the number of cells in y-direction!"); if (cells[0] > 200) DUNE_THROW(Dune::IOError, "Maximum allowed number of cells in x-direction for this problem is: 200!"); - upperRight_ = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, GlobalPosition, Grid, UpperRight); + upperRight_ = getParam("Grid.UpperRight"); - WettingPhase::Component::setViscosity(GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Fluid, ViscosityW)); - NonwettingPhase::Component::setViscosity(GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Fluid, ViscosityNW)); + WettingPhase::Component::setViscosity( getParam("Fluid.ViscosityW") ); + NonwettingPhase::Component::setViscosity( getParam("Fluid.ViscosityNW") ); - WettingPhase::Component::setDensity(GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Fluid, DensityW)); - NonwettingPhase::Component::setDensity(GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Fluid, DensityNW)); + WettingPhase::Component::setDensity( getParam("Fluid.DensityW") ); + NonwettingPhase::Component::setDensity( getParam("Fluid.DensityNW") ); - densityNonWetting_ = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Fluid, DensityNW); + densityNonWetting_ = getParam("Fluid.DensityNW"); - swr_ = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, SpatialParams, ResidualSaturationWetting); - snr_ = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, SpatialParams ,ResidualSaturationNonWetting); + swr_ = getParam("SpatialParams.ResidualSaturationWetting"); + snr_ = getParam("SpatialParams.ResidualSaturationNonWetting"); paraviewOutput_ = Params::tree().template get("Output.paraviewOutput", true); - // create output for ViPLab if no output for Paraview is created + + /*// create output for ViPLab if no output for Paraview is created if (!paraviewOutput_) { //Write header for ViPLab-Outputfile @@ -162,7 +164,7 @@ public: dataFile.open("vipplot.vgf"); dataFile.close(); } - } + }*/ void init() { @@ -209,26 +211,36 @@ public: return 273.15 + 10; // -> 10°C } + /*! + * \brief Returns the pressure within the domain. + * + * This problem assumes a pressure of 1bar (which is equal to 1e5 Pa) + * \param GlobalPos DOC ME! + */ Scalar referencePressureAtPos(const GlobalPosition& globalPos) const { return 1.0e5; // -> 1 bar } + /*! * \brief DOC ME! * \param values DOC ME! * \param globalPos DOC ME! */ - void sourceAtPos(PrimaryVariables &values,const GlobalPosition& globalPos) const + numEqVector sourceAtPos(const GlobalPosition& globalPos) const { - values = 0; + return numEqVector(0.0); } + /*! * \brief DOC ME! * \param bcTypes DOC ME! * \param globalPos DOC ME! */ - void boundaryTypesAtPos(BoundaryTypes &bcTypes, const GlobalPosition& globalPos) const + BoundaryTypes boundaryTypesAtPos( const GlobalPosition& globalPos) const { + BoundaryTypes bcTypes; + if (globalPos[0] < eps_)//all Dirichlet at west boundary { bcTypes.setAllDirichlet(); @@ -243,24 +255,34 @@ public: { bcTypes.setAllNeumann(); } + + return bcTypes; } + /*! * \brief DOC ME! * \param values DOC ME! * \param globalPos DOC ME */ - void dirichletAtPos(PrimaryVariables &values, const GlobalPosition& globalPos) const + PrimaryVariables dirichletAtPos( const GlobalPosition& globalPos) const { + PrimaryVariables values; + values[pressureIdx] = pLeftBc_; values[swIdx] = 1.0 - snr_; + + return values; } + /*! * \brief DOC ME! * \param values DOC ME! * \param globalPos DOC ME */ - void neumannAtPos(PrimaryVariables &values, const GlobalPosition& globalPos) const + PrimaryVariables neumannAtPos( const GlobalPosition& globalPos) const { + PrimaryVariables values; + values = 0; //no-flow Neumann at top and bottom if (globalPos[0] > upperRight_[0] - eps_) //east boundary { @@ -269,17 +291,23 @@ public: const Scalar referenceDensity = 1000.0; values[nPhaseIdx] = 3e-4 * densityNonWetting_/referenceDensity; } + + return values; } + /*! * \brief DOC ME! * \param values DOC ME! * \param globalPos DOC ME */ - void initialAtPos(PrimaryVariables &values, - const GlobalPosition &globalPos) const + PrimaryVariables initialAtPos( const GlobalPosition &globalPos) const { + PrimaryVariables values; + values[pressureIdx] = pLeftBc_; values[swIdx] = swr_; + + return values; } /** @@ -311,12 +339,15 @@ public: private: GlobalPosition upperRight_; - Scalar eps_, swr_, snr_; + Scalar eps_ = 1e-8; + Scalar swr_, snr_; Scalar pLeftBc_; Scalar densityNonWetting_; BuckleyLeverettAnalytic analyticSolution_; ViplabOutput viplabOutput_; bool paraviewOutput_; }; + + } #endif // DUMUX_LECTURE_MM_BUCKLEYLEVERETT_BUCKLEYLEVERETTPROBLEM_HH diff --git a/lecture/mm/buckleyleverett/buckleyleverettspatialparams.hh b/lecture/mm/buckleyleverett/buckleyleverettspatialparams.hh index 3b75909..42d6c60 100644 --- a/lecture/mm/buckleyleverett/buckleyleverettspatialparams.hh +++ b/lecture/mm/buckleyleverett/buckleyleverettspatialparams.hh @@ -43,7 +43,7 @@ SET_TYPE_PROP(BuckleyLeverettSpatialParams, SpatialParams, Dumux::BuckleyLeveret SET_PROP(BuckleyLeverettSpatialParams, MaterialLaw) { private: - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); typedef RegularizedBrooksCorey RawMaterialLaw; // typedef LinearMaterial RawMaterialLaw; public: @@ -56,22 +56,23 @@ public: template class BuckleyLeverettSpatialParams: public FVSpatialParams { - typedef typename GET_PROP_TYPE(TypeTag, Grid) Grid; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef FVSpatialParams ParentType; - typedef typename Grid::ctype CoordScalar; + using Grid = typename GET_PROP_TYPE(TypeTag, Grid); + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar) + typedef FVSpatialParams ParentType; // TODO: How to change this thing here? + using CoordScalar = typename Grid::ctype; enum {dim=Grid::dimension, dimWorld=Grid::dimensionworld, numEq=1}; - typedef typename Grid::Traits::template Codim<0>::Entity Element; - typedef Dune::FieldVector GlobalPosition; - typedef Dune::FieldMatrix FieldMatrix; + using Element = typename Grid::Traits::template Codim<0>::Entity; + + using GlobalPosition = Dune::FieldVector; + using FieldMatrix = Dune::FieldMatrix; public: - typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw; - typedef typename MaterialLaw::Params MaterialLawParams; + using MaterialLaw = typename GET_PROP_TYPE(TypeTag, MaterialLaw); + using MaterialLawParams = typename MaterialLaw::Params; Scalar intrinsicPermeability (const Element& element) const @@ -96,14 +97,14 @@ public: } - BuckleyLeverettSpatialParams(const GridView& gridView) + BuckleyLeverettSpatialParams(const GridView& gridView) // TODO How to change this? :ParentType(gridView) { Scalar permFactor = 1.0;//0.001/(1000*9.81); - constPermeability_ = GET_RUNTIME_PARAM(TypeTag,double, SpatialParams.Permeability)*permFactor; - materialLawParams_.setSwr(GET_RUNTIME_PARAM(TypeTag,double, SpatialParams.ResidualSaturationWetting)); - materialLawParams_.setSnr(GET_RUNTIME_PARAM(TypeTag,double, SpatialParams.ResidualSaturationNonWetting)); + constPermeability_ = getParam("SpatialParams.Permeability")*permFactor; + materialLawParams_.setSwr( getParam("SpatialParams.ResidualSaturationWetting") ); + materialLawParams_.setSnr( getParam("SpatialParams.ResidualSaturationNonWetting") ); // if( GET_RUNTIME_PARAM(TypeTag,bool, SpatialParams.LinearLaw)/* true -> linear law */ ){ // //set parameters @@ -112,11 +113,11 @@ public: // } // else{ //set Brooks-Corey parameters - materialLawParams_.setPe(GET_RUNTIME_PARAM(TypeTag,double, SpatialParams.BrooksCoreyEntryPressure)); - materialLawParams_.setLambda(GET_RUNTIME_PARAM(TypeTag,double, SpatialParams.BrooksCoreyLambda)); + materialLawParams_.setPe( getParam("SpatialParams.BrooksCoreyEntryPressure") ); + materialLawParams_.setLambda( getParam("SpatialParams.BrooksCoreyLambda") ); // } - porosity_ = GET_RUNTIME_PARAM(TypeTag,double, SpatialParams.Porosity); + porosity_ = getParam("SpatialParams.Porosity"); } private: diff --git a/lecture/mm/buckleyleverett/pseudoh2o.hh b/lecture/mm/buckleyleverett/pseudoh2o.hh index 829c8ad..83cb85f 100644 --- a/lecture/mm/buckleyleverett/pseudoh2o.hh +++ b/lecture/mm/buckleyleverett/pseudoh2o.hh @@ -32,7 +32,7 @@ namespace Dumux /*! * \brief Rough estimate for testing purposes of some water. */ -template +template // TODO: Must change this to Scalar? class PseudoH2O : public Component > { typedef Component > ParentType; @@ -63,6 +63,7 @@ public: { return viscosity_; }; + /*! * \brief DOC ME! * \param viscosity DOC ME! @@ -71,6 +72,7 @@ public: { viscosity_ = viscosity; } + /*! * \brief DOC ME! * \param density DOC ME! diff --git a/lecture/mm/buckleyleverett/pseudooil.hh b/lecture/mm/buckleyleverett/pseudooil.hh index 9dc2c26..3405a7c 100644 --- a/lecture/mm/buckleyleverett/pseudooil.hh +++ b/lecture/mm/buckleyleverett/pseudooil.hh @@ -68,6 +68,7 @@ public: { return viscosity_; }; + /*! * \brief DOC ME! * \param viscosity DOC ME! @@ -76,6 +77,7 @@ public: { viscosity_ = viscosity; } + /*! * \brief DOC ME! * \param density DOC ME! diff --git a/lecture/mm/co2plume/co2plumeshapeproblem.hh b/lecture/mm/co2plume/co2plumeshapeproblem.hh index 0b8bde0..f0cb751 100644 --- a/lecture/mm/co2plume/co2plumeshapeproblem.hh +++ b/lecture/mm/co2plume/co2plumeshapeproblem.hh @@ -105,14 +105,14 @@ SET_BOOL_PROP(PlumeShapeProblem, UseMoles, false); * * */ template -class PlumeShapeProblem : public ImplicitPorousMediaProblem +class PlumeShapeProblem : public PorousMediumFlowProblem { - typedef ImplicitPorousMediaProblem ParentType; + typedef PorousMediumFlowProblem ParentType; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, CO2Table) CO2Tables; + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); + using CO2Tables = typename GET_PROP_TYPE(TypeTag, CO2Table); enum { // Grid and world dimension @@ -160,24 +160,26 @@ public: * \param timeManager The time manager * \param gridView The grid view */ - PlumeShapeProblem(TimeManager &timeManager, const GridView &gridView) - : ParentType(timeManager, gridView), eps_(1e-6) + PlumeShapeProblem(std::shared_ptr< const FVGridGeometry> fvGridGeometry) + : ParentType(fvGridGeometry) { - nTemperature_ = GET_RUNTIME_PARAM(TypeTag, int, FluidSystem.NTemperature); - nPressure_ = GET_RUNTIME_PARAM(TypeTag, int, FluidSystem.NPressure); - pressureLow_ = GET_RUNTIME_PARAM(TypeTag, Scalar, FluidSystem.PressureLow); - pressureHigh_ = GET_RUNTIME_PARAM(TypeTag, Scalar, FluidSystem.PressureHigh); - pressure_ = GET_RUNTIME_PARAM(TypeTag, Scalar, InitialConditions.Pressure); // hydrodynamic pressure at top layer - temperatureLow_ = GET_RUNTIME_PARAM(TypeTag, Scalar, FluidSystem.TemperatureLow); - temperatureHigh_ = GET_RUNTIME_PARAM(TypeTag, Scalar, FluidSystem.TemperatureHigh); - temperature_ = GET_RUNTIME_PARAM(TypeTag, Scalar, InitialConditions.Temperature); - injectionRate_ = GET_RUNTIME_PARAM(TypeTag, Scalar, BoundaryConditions.InjectionRate); - injectionTemperature_ = GET_RUNTIME_PARAM(TypeTag, Scalar, BoundaryConditions.InjectionTemperature); - dipAngle_ = GET_RUNTIME_PARAM(TypeTag, Scalar, SpatialParams.DipAngle); // [deg] - name_ = GET_RUNTIME_PARAM(TypeTag, std::string, SimulationControl.Name); - - episodeLength_ = GET_RUNTIME_PARAM(TypeTag, Scalar, TimeManager.EpisodeLength); - this->timeManager().startNextEpisode(episodeLength_); + + // TODO Change int to Scalar? Or is int the type for an index? + nTemperature_ = getParam("FluidSystem.NTemperature"); + nPressure_ = getParam("FluidSystem.NPressure"); + pressureLow_ = getParam("FluidSystem.PressureLow"); + pressureHigh_ = getParam("FluidSystem.PressureHigh"); + pressure_ = getParam("InitialConditions.Pressure"); // hydrodynamic pressure at top layer + temperatureLow_ = getParam("FluidSystem.TemperatureLow"); + temperatureHigh_ = getParam("FluidSystem.TemperatureHigh"); + temperature_ = getParam("InitialConditions.Temperature"); + injectionRate_ = getParam("BoundaryConditions.InjectionRate"); + injectionTemperature_ = getParam("BoundaryConditions.InjectionTemperature"); + dipAngle_ = getParam("SpatialParams.DipAngle"); // [deg] + name_ = getParam("SimulationControl.Name"); + + episodeLength_ = getParam("TimeLoop.EpisodeLength"); + // this->timeManager().startNextEpisode(episodeLength_); dipAngleRadians_ = (dipAngle_ * M_PI)/180.0; // [rad] // rotate the coordinate system / gravity: @@ -281,8 +283,10 @@ public: * \param values The boundary types for the conservation equations * \param vertex The vertex for which the boundary type is set */ - void boundaryTypes(BoundaryTypes &values, const Vertex &vertex) const + BoundaryTypes boundaryTypes( const Vertex &vertex) const { + BoundaryTypes values; + const GlobalPosition& globalPos = vertex.geometry().center(); values.setAllNeumann(); @@ -299,6 +303,7 @@ public: values.setDirichlet(temperatureIdx, energyEqIdx); #endif } + return values; } /*! @@ -433,7 +438,7 @@ private: Scalar temperature_,injectionTemperature_; Scalar depthBOR_; - Scalar eps_; + Scalar eps_ = 1e-6; Scalar injectionRate_; Scalar episodeLength_; Scalar dipAngleRadians_, dipAngle_; diff --git a/lecture/mm/columnxylene/columnxyleneexercise.cc b/lecture/mm/columnxylene/columnxyleneexercise.cc index a2ae9f1..55c48df 100644 --- a/lecture/mm/columnxylene/columnxyleneexercise.cc +++ b/lecture/mm/columnxylene/columnxyleneexercise.cc @@ -52,9 +52,175 @@ void usage(const char *progName, const std::string &errorMsg) << "\n"; } } +//////////////////////// +// the main function +//////////////////////// +int main(int argc, char** argv) try +{ + // typedef TTAG(LensOnePTwoCProblem) TypeTag; + // return Dumux::start(argc, argv, usage); + using namespace Dumux; + + // define the type tag for this problem + using TypeTag = TTAG(ColumnProblem); + + // 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(leafGridView); + fvGridGeometry->update(); + + // the problem (initial and boundary conditions) + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); + auto problem = std::make_shared(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(problem, fvGridGeometry); + gridVariables->init(x, xOld); + + // get some time loop parameters + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + const auto tEnd = getParam("TimeLoop.TEnd"); + const auto maxDivisions = getParam("TimeLoop.MaxTimeStepDivisions"); // Q: What is this? Do we need this here? + const auto maxDt = getParam("TimeLoop.MaxTimeStepSize"); + auto dt = getParam("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")) // Fehlt ebenso + restartTime = getParam("TimeLoop.Restart"); + + // intialize the vtk output module + using VtkOutputFields = typename GET_PROP_TYPE(TypeTag, VtkOutputFields); + VtkOutputModule 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>(restartTime, dt, tEnd); + timeLoop->setMaxTimeStepSize(maxDt); + + // the assembler with time loop for instationary problem + using Assembler = FVAssembler; + auto assembler = std::make_shared(problem, fvGridGeometry, gridVariables, timeLoop); + + // the linear solver + using LinearSolver = AMGBackend; + auto linearSolver = std::make_shared(leafGridView, fvGridGeometry->dofMapper()); + + // the non-linear solver + using NewtonSolver = Dumux::NewtonSolver; + NewtonSolver nonLinearSolver(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; -int main(int argc, char** argv) + 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 the Newton solver + timeLoop->setTimeStepSize(nonLinearSolver.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); + } + + + +} + +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 (...) { - typedef TTAG(ColumnProblem) ProblemTypeTag; - return Dumux::start(argc, argv, usage); + std::cerr << "Unknown exception thrown! ---> Abort!" << std::endl; + return 4; } diff --git a/lecture/mm/columnxylene/columnxyleneexercise.input b/lecture/mm/columnxylene/columnxyleneexercise.input index 372fd21..52a8647 100644 --- a/lecture/mm/columnxylene/columnxyleneexercise.input +++ b/lecture/mm/columnxylene/columnxyleneexercise.input @@ -1,6 +1,6 @@ -[TimeManager] +[TimeLoop] DtInitial = 1 # [s] TEnd = 1800 # [s] OutputInterval = 1 diff --git a/lecture/mm/columnxylene/columnxyleneproblem.hh b/lecture/mm/columnxylene/columnxyleneproblem.hh index 6b8fd73..fb02ed0 100644 --- a/lecture/mm/columnxylene/columnxyleneproblem.hh +++ b/lecture/mm/columnxylene/columnxyleneproblem.hh @@ -55,9 +55,6 @@ SET_TYPE_PROP(ColumnProblem, FluidSystem, FluidSystems::H2OAirXylene); -// Enable gravity -SET_BOOL_PROP(ColumnProblem, ProblemEnableGravity, true); - // Maximum tolerated relative error in the Newton method SET_SCALAR_PROP(ColumnProblem, NewtonMaxRelativeShift, 1e-4); } @@ -68,16 +65,17 @@ SET_SCALAR_PROP(ColumnProblem, NewtonMaxRelativeShift, 1e-4); * * */ template -class ColumnProblem : public ImplicitPorousMediaProblem +class ColumnProblem : public PorousMediumFlowProblem { - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::Grid Grid; + using ParentType = PorousMediumFlowProblem; - typedef ImplicitPorousMediaProblem ParentType; + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using Grid = typename GridView::Grid; // copy some indices for convenience typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; + enum { pressureIdx = Indices::pressureIdx, @@ -94,19 +92,17 @@ class ColumnProblem : public ImplicitPorousMediaProblem dimWorld = GridView::dimensionworld }; + using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); + using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes; - typedef typename GET_PROP_TYPE(TypeTag, TimeManager) TimeManager; - - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GridView::template Codim::Entity Vertex; - typedef typename GridView::Intersection Intersection; + using Element = typename GridView::template Codim<0>::Entity; + using Vertex = typename GridView::template Codim::Entity; + using Intersection = typename GridView::Intersection; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); + using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); - typedef Dune::FieldVector GlobalPosition; + using GlobalPosition = Dune::FieldVector; public: /*! @@ -115,8 +111,9 @@ public: * \param timeManager The time manager * \param gridView The grid view */ - ColumnProblem(TimeManager &timeManager, const GridView &gridView) - : ParentType(timeManager, gridView), eps_(1e-6) + + ColumnProblem(std::shared_ptr fvElementGeometry) + : ParentType(fvElementGeometry) { FluidSystem::init(); } @@ -135,10 +132,9 @@ public: { return "columnxylol"; } - void sourceAtPos(PrimaryVariables &values, - const GlobalPosition &globalPos) const + NumEqVector sourceAtPos( const GlobalPosition &globalPos) const { - values = 0; + return NumEqVector(0.0); } // \} @@ -155,14 +151,18 @@ public: * \param values The boundary types for the conservation equations * \param vertex The vertex for which the boundary type is set */ - void boundaryTypes(BoundaryTypes &values, const Vertex &vertex) const + BoundaryTypes boundaryTypes( const Vertex &vertex) const { + BoundaryTypes values; + const GlobalPosition globalPos = vertex.geometry().center(); if(globalPos[1] < eps_) values.setAllDirichlet(); else values.setAllNeumann(); + + return values; } /*! @@ -174,11 +174,15 @@ public: * * For this method, the \a values parameter stores primary variables. */ - void dirichlet(PrimaryVariables &values, const Vertex &vertex) const + PrimaryVariables dirichlet( const Vertex &vertex) const { + PrimaryVariables values; + const GlobalPosition globalPos = vertex.geometry().center(); initial_(values, globalPos); + + return values; } /*! @@ -195,24 +199,27 @@ public: * For this method, the \a values parameter stores the mass flux * in normal direction of each phase. Negative values mean influx. */ - void neumann(PrimaryVariables &values, - const Element &element, + PrimaryVariables neumann( const Element &element, const FVElementGeometry &fvElemGeom, const Intersection &is, int scvIdx, int boundaryFaceIdx) const { + PrimaryVariables values; + const GlobalPosition &globalPos = element.geometry().corner(scvIdx); values = 0; // negative values for injection if (globalPos[1] > 1.2 - eps_) { - values[Indices::contiWEqIdx] = GET_RUNTIME_PARAM(TypeTag, Scalar, steamFlux); + values[Indices::contiWEqIdx] = getParam("steamFlux"); values[Indices::contiGEqIdx] = -0.000001; values[Indices::contiNEqIdx] = -0.00; - values[Indices::energyEqIdx] = GET_RUNTIME_PARAM(TypeTag, Scalar, enthalpyFlux); + values[Indices::energyEqIdx] = getParam("enthalpyFlux"); } + + return values; } // \} @@ -233,15 +240,17 @@ public: * For this method, the \a values parameter stores primary * variables. */ - void initial(PrimaryVariables &values, - const Element &element, + PrimaryVariables initial( const Element &element, const FVElementGeometry &fvElemGeom, int scvIdx) const { + PrimaryVariables values; + const GlobalPosition &globalPos = element.geometry().corner(scvIdx); initial_(values, globalPos); + return values; } /*! @@ -254,30 +263,14 @@ public: return threePhases; } - bool shouldWriteRestartFile() const - { - return 0; - } - - - - bool shouldWriteOutput() const - { - - int outputInterval = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, int, TimeManager, OutputInterval); - - return (this->timeManager().timeStepIndex() % outputInterval == 0 || - this->timeManager().willBeFinished()); - } - - private: // internal method for the initial condition (reused for the // dirichlet conditions!) - void initial_(PrimaryVariables &values, - const GlobalPosition &globalPos) const + PrimaryVariables initial_( const GlobalPosition &globalPos) const { + PrimaryVariables values; + const Scalar y = globalPos[1]; values[temperatureIdx] = 296.15; @@ -315,7 +308,7 @@ private: } - const Scalar eps_; + const Scalar eps_ = 1e-6; }; } //end namespace diff --git a/lecture/mm/columnxylene/columnxyleneproblem2.hh b/lecture/mm/columnxylene/columnxyleneproblem2.hh index 1eff909..d812a5e 100644 --- a/lecture/mm/columnxylene/columnxyleneproblem2.hh +++ b/lecture/mm/columnxylene/columnxyleneproblem2.hh @@ -61,11 +61,13 @@ SET_TYPE_PROP(ColumnProblem, FluidSystem, FluidSystems::H2OAirXylene); -// Enable gravity -SET_BOOL_PROP(ColumnProblem, ProblemEnableGravity, true); +// Enable Gravity + // Maximum tolerated relative error in the Newton method -SET_SCALAR_PROP(ColumnProblem, NewtonMaxRelativeShift, 1e-4); +// SET_SCALAR_PROP(ColumnProblem, NewtonMaxRelativeShift, 1e-4); + + } @@ -74,16 +76,17 @@ SET_SCALAR_PROP(ColumnProblem, NewtonMaxRelativeShift, 1e-4); * * */ template -class ColumnProblem : public ImplicitPorousMediaProblem +class ColumnProblem : public PorousMediumFlowProblem { - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::Grid Grid; + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using Grid = typename GridView::Grid; typedef ImplicitPorousMediaProblem ParentType; // copy some indices for convenience - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; + using Indices = typename GET_PROP_TYPE(TypeTag, Indices); + enum { pressureIdx = Indices::pressureIdx, @@ -101,9 +104,8 @@ class ColumnProblem : public ImplicitPorousMediaProblem }; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes; - typedef typename GET_PROP_TYPE(TypeTag, TimeManager) TimeManager; + using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); + using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); typedef typename GridView::template Codim<0>::Entity Element; typedef typename GridView::template Codim::Entity Vertex; diff --git a/lecture/mm/columnxylene/columnxylenespatialparams2.hh b/lecture/mm/columnxylene/columnxylenespatialparams2.hh index 25b2293..e315d97 100644 --- a/lecture/mm/columnxylene/columnxylenespatialparams2.hh +++ b/lecture/mm/columnxylene/columnxylenespatialparams2.hh @@ -68,41 +68,45 @@ SET_PROP(ColumnSpatialParams, MaterialLaw) * \brief Definition of the spatial parameters for the column problem */ template -class ColumnSpatialParams : public ImplicitSpatialParams +class ColumnSpatialParams : public PorousMediumFlowProblem { - typedef ImplicitSpatialParams ParentType; + using ParentType = PorousMediumFlowProblem; + + using Grid = typename GET_PROP_TYPE(TypeTag, Grid); + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using CoordScalar = typename Grid::ctype; + + using Indices = typename GET_PROP_TYPE(TypeTag, Indices); - typedef typename GET_PROP_TYPE(TypeTag, Grid) Grid; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename Grid::ctype CoordScalar; enum { dim=GridView::dimension, dimWorld=GridView::dimensionworld }; - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; + + enum { wPhaseIdx = Indices::wPhaseIdx, nPhaseIdx = Indices::nPhaseIdx }; - typedef Dune::FieldVector GlobalPosition; - typedef Dune::FieldVector Vector; + using GlobalPosition = Dune::FieldVector; + using Vector = Dune::FieldVector; - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector; + using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector); - typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; + using FluxVariables = typename GET_PROP_TYPE(TypeTag, FluxVariables); + using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables); - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GridView::template Codim<0>::Entity Element; + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); + using Element = typename GridView::template Codim<0>::Entity; public: - typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw; - typedef typename MaterialLaw::Params MaterialLawParams; + using MaterialLaw = typename GET_PROP_TYPE(TypeTag, MaterialLaw); + using MaterialLawParams = typename MaterialLaw::Params; /*! * \brief The constructor @@ -125,20 +129,21 @@ public: lambdaSolid_ = 2.8; // residual saturations - fineMaterialParams_.setSwr(GET_RUNTIME_PARAM(TypeTag, Scalar, swr)); - fineMaterialParams_.setSnr(GET_RUNTIME_PARAM(TypeTag, Scalar, snr)); - fineMaterialParams_.setSgr(GET_RUNTIME_PARAM(TypeTag, Scalar, Sgr)); + // TODO There is no branch in the param-tree for the following variables. Is this thought to be a good solution? Should it be changed? + fineMaterialParams_.setSwr( getParam("swr") ); + fineMaterialParams_.setSnr( getParam("snr") ); + fineMaterialParams_.setSgr( getParam("Sgr") ); // parameters for the 3phase van Genuchten law - fineMaterialParams_.setVgAlpha(GET_RUNTIME_PARAM(TypeTag, Scalar, vanGenuchtenAlpha)); - fineMaterialParams_.setVgn(GET_RUNTIME_PARAM(TypeTag, Scalar, vanGenuchtenN)); + fineMaterialParams_.setVgAlpha( getParam("vanGenuchtenAlpha") ); + fineMaterialParams_.setVgn( getParam("vanGenuchtenN") ); fineMaterialParams_.setKrRegardsSnr(true); // parameters for the scaling of capillary pressure (GW = 1); - fineMaterialParams_.setBetaNw(GET_RUNTIME_PARAM(TypeTag, Scalar, betaNW)); - fineMaterialParams_.setBetaGn(GET_RUNTIME_PARAM(TypeTag, Scalar, betaGN)); - fineMaterialParams_.setBetaGw(GET_RUNTIME_PARAM(TypeTag, Scalar, betaGW)); + fineMaterialParams_.setBetaNw( getParam("betaNW") ); + fineMaterialParams_.setBetaGn( getParam("betaGN") ); + fineMaterialParams_.setBetaGw( getParam("betaGW") ); // parameters for adsorption fineMaterialParams_.setKdNAPL(0.); @@ -189,7 +194,6 @@ public: return finePorosity_; } - /*! * \brief return the parameter object for the Brooks-Corey material law which depends on the position * diff --git a/lecture/mm/convectivemixing/convmixproblem.hh b/lecture/mm/convectivemixing/convmixproblem.hh index 657d48f..c42e8f6 100644 --- a/lecture/mm/convectivemixing/convmixproblem.hh +++ b/lecture/mm/convectivemixing/convmixproblem.hh @@ -68,51 +68,50 @@ SET_BOOL_PROP(ConvectiveMixingProblem, ProblemEnableGravity, true); } template -class ConvectiveMixingProblem : public ImplicitPorousMediaProblem +class ConvectiveMixingProblem : public PorousMediumFlowProblem { - typedef ImplicitPorousMediaProblem ParentType; + using ParentType = PorousMediumFlowProblem; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes; - typedef typename GET_PROP_TYPE(TypeTag, TimeManager) TimeManager; + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); + using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables); + using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); + using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); // copy some indices for convenience - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum { - // Grid and world dimension - dim = GridView::dimension, - dimWorld = GridView::dimensionworld, - - // indices of the primary variables - pressureIdx = Indices::pressureIdx, // index for the pressure primary variable - massFracIdx = Indices::massOrMoleFracIdx, // index for the CO2 massfraction primary variable - - // indices of the equations - conti0EqIdx = Indices::conti0EqIdx, // index for the continuity equation - transportEqIdx = Indices::transportEqIdx, // index for the transport equation - }; + using ModelTraits = typename GET_PROP_TYPE(TypeTag, ModelTraits); + using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; + + // Grid and world dimension + static constexpr int dim = GridView::dimension; + static constexpr int dimWorld = GridView::dimensionworld; + + // indices of the primary variables + static constexpr int pressureIdx = Indices::pressureIdx; // index for the pressure primary variable + static constexpr int massFracIdx = Indices::massOrMoleFracIdx; // index for the CO2 massfraction primary variable + + // indices of the equations + static constexpr int conti0EqIdx = Indices::conti0EqIdx; // index for the continuity equation + static constexpr int transportEqIdx = Indices::transportEqIdx; // index for the transport equation + + using Element = typename GridView::template Codim<0>::Entity; + using ElementIterator = typename GridView::template Codim<0>::Iterator; + using Vertex = typename GridView::template Codim::Entity; + using Intersection = typename GridView::Intersection; - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GridView::template Codim<0>::Iterator ElementIterator; - typedef typename GridView::template Codim::Entity Vertex; - typedef typename GridView::Intersection Intersection; + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef Dune::FieldVector GlobalPosition; - typedef typename GET_PROP_TYPE(TypeTag, PTAG(CO2Table)) CO2Table; - typedef Dumux::CO2 CO2; - typedef Dumux::BinaryCoeff::Brine_CO2 Brine_CO2; + using CO2Table = typename GET_PROP_TYPE(TypeTag, PTAG(CO2Table)); + using CO2 = Dumux::CO2; + using Brine_CO2 = Dumux::BinaryCoeff::Brine_CO2; public: - ConvectiveMixingProblem(TimeManager &timeManager, const GridView &gridView) - : ParentType(timeManager, gridView) + ConvectiveMixingProblem(std::shared_ptr fvGridGeometry ) : ParentType(fvGridGeometry) { - depthBOR_ = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.DepthBOR); + depthBOR_ = get_Param(TypeTag, Scalar, Problem.DepthBOR); name_ = GET_RUNTIME_PARAM(TypeTag, std::string, Problem.Name); FluidSystem::init(); diff --git a/lecture/mm/convectivemixing/convmixspatialparams.hh b/lecture/mm/convectivemixing/convmixspatialparams.hh index 58742f4..98f0c4f 100644 --- a/lecture/mm/convectivemixing/convmixspatialparams.hh +++ b/lecture/mm/convectivemixing/convmixspatialparams.hh @@ -27,7 +27,7 @@ namespace Dumux { //forward declaration -template +template class ConvMixSpatialParams; namespace Properties @@ -44,14 +44,14 @@ SET_TYPE_PROP(ConvMixSpatialParams, SpatialParams, Dumux::ConvMixSpatialParams -class ConvMixSpatialParams : public ImplicitSpatialParamsOneP +template +class ConvMixSpatialParams : public FVSpatialParams> { - typedef ImplicitSpatialParamsOneP ParentType; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GridView::template Codim<0>::Entity Element; + using ParentType = PorousMediumFlowProblem; + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); + using Element = typename GridView::template Codim<0>::Entity; public: ConvMixSpatialParams(const GridView &gridView) diff --git a/lecture/mm/fuelcell/fuelcell.cc b/lecture/mm/fuelcell/fuelcell.cc index efa1044..54ef144 100644 --- a/lecture/mm/fuelcell/fuelcell.cc +++ b/lecture/mm/fuelcell/fuelcell.cc @@ -24,9 +24,24 @@ * * The 2pncMin box model used for water management in PEM fuel cells adapted to the Acosta(paper 2006) problem. */ -#include "config.h" +#include #include -#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include + +#include //O: NON-ISOTHERMAL MODEL, 1: ISOTHERMAL MODEL #define ISOTHERMAL 0 @@ -66,8 +81,157 @@ void usage(const char *progName, const std::string &errorMsg) << "\n"; } } +//////////////////////// +// the main function +//////////////////////// +int main(int argc, char** argv) try +{ + using namespace Dumux; + + // define the type tag for this problem + using TypeTag = TTAG(FuelCellLectureProblem); + + // 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(leafGridView); + fvGridGeometry->update(); + + // the problem (initial and boundary conditions) + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); + auto problem = std::make_shared(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(problem, fvGridGeometry); + gridVariables->init(x, xOld); + + // get some time loop parameters + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + const auto tEnd = getParam("TimeLoop.TEnd"); + const auto maxDt = getParam("TimeLoop.MaxTimeStepSize"); + auto dt = getParam("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")) // Fehlt ebenso + restartTime = getParam("TimeLoop.Restart"); + + // intialize the vtk output module + using VtkOutputFields = typename GET_PROP_TYPE(TypeTag, VtkOutputFields); + VtkOutputModule 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>(restartTime, dt, tEnd); + timeLoop->setMaxTimeStepSize(maxDt); + + // the assembler with time loop for instationary problem + using Assembler = FVAssembler; + auto assembler = std::make_shared(problem, fvGridGeometry, gridVariables, timeLoop); + + // the linear solver + using LinearSolver = AMGBackend; + auto linearSolver = std::make_shared(leafGridView, fvGridGeometry->dofMapper()); + + // the non-linear solver + using NewtonSolver = PriVarSwitchNewtonSolver; + NewtonSolver nonLinearSolver(assembler, linearSolver); + + // time loop + timeLoop->start(); do + { + // set previous solution for storage evaluations + assembler->setPreviousSolution(xOld); + + // solve the non-linear system with time step control + nonLinearSolver.solve(x, *timeLoop); + + // make the new solution the old solution + xOld = x; + gridVariables->advanceTimeStep(); + + // advance to the time loop to the next step + timeLoop->advanceTimeStep(); + + // update the output fields with the current solution before write + problem->updateVtkFields(x); + + // write vtk output + vtkWriter.write(timeLoop->time()); + + // report statistics of this time step + timeLoop->reportTimeStep(); + + // set new dt as suggested by the newton solver + timeLoop->setTimeStepSize(nonLinearSolver.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); + } +} -int main(int argc, char** argv) +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 (...) { - return Dumux::start(argc, argv, usage); + std::cerr << "Unknown exception thrown! ---> Abort!" << std::endl; + return 4; } diff --git a/lecture/mm/fuelcell/fuelcell.input b/lecture/mm/fuelcell/fuelcell.input index f9758de..24acda3 100644 --- a/lecture/mm/fuelcell/fuelcell.input +++ b/lecture/mm/fuelcell/fuelcell.input @@ -1,4 +1,4 @@ -[TimeManager] +[TimeLoop] DtInitial = 1e-2 # small because of Acosta pc law MaxTimeStepSize = 20 TEnd = 20 #equilibrium time diff --git a/lecture/mm/fuelcell/fuelcellproblem.hh b/lecture/mm/fuelcell/fuelcellproblem.hh index 4ad3837..fafd731 100644 --- a/lecture/mm/fuelcell/fuelcellproblem.hh +++ b/lecture/mm/fuelcell/fuelcellproblem.hh @@ -24,10 +24,11 @@ #ifndef DUMUX_FUELCELL_LECTURE_PROBLEM_HH #define DUMUX_FUELCELL_LECTURE_PROBLEM_HH -#include -#include +#include +#include #include #include +#include #if !ISOTHERMAL #include @@ -47,9 +48,9 @@ namespace Properties { #if ISOTHERMAL -NEW_TYPE_TAG(FuelCellLectureProblem, INHERITS_FROM(BoxTwoPNC, FuelCellLectureSpatialParams)); +NEW_TYPE_TAG(FuelCellLectureProblem, INHERITS_FROM(TwoPNC, BoxModel, FuelCellLectureSpatialParams)); #else -NEW_TYPE_TAG(FuelCellLectureProblem, INHERITS_FROM(BoxTwoPNCNI, FuelCellLectureSpatialParams)); +NEW_TYPE_TAG(FuelCellLectureProblem, INHERITS_FROM(TwoPNCNI, BoxModel, FuelCellLectureSpatialParams)); #endif // Set the grid type @@ -59,22 +60,20 @@ SET_TYPE_PROP(FuelCellLectureProblem, Grid, Dune::YaspGrid<2>); SET_TYPE_PROP(FuelCellLectureProblem, Problem, FuelCellLectureProblem); // Set the primary variable combination for the 2pnc model -SET_INT_PROP(FuelCellLectureProblem, Formulation, TwoPNCFormulation::pnsw); +SET_PROP(FuelCellLectureProblem, Formulation) +{ static constexpr auto value = TwoPFormulation::p1s0; }; // Set fluid configuration SET_PROP(FuelCellLectureProblem, FluidSystem) { private: - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - static const bool useComplexRelations = true; + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + static constexpr bool useComplexRelations = true; public: - typedef FluidSystems::H2ON2O2 type; + using type = FluidSystems::H2ON2O2; }; //define which component balance equation gets replaced by total balance {0,1,2,..,numComponents(none)} SET_INT_PROP(FuelCellLectureProblem, ReplaceCompEqIdx, 3); - -// Disable gravity -SET_BOOL_PROP(FuelCellLectureProblem, ProblemEnableGravity, false); } /*! @@ -85,90 +84,93 @@ SET_BOOL_PROP(FuelCellLectureProblem, ProblemEnableGravity, false); * ./test_fuelcell -parameterFile ./test_fuelcell.input */ template -class FuelCellLectureProblem : public ImplicitPorousMediaProblem +class FuelCellLectureProblem : public PorousMediumFlowProblem { - typedef ImplicitPorousMediaProblem ParentType; + using ParentType = PorousMediumFlowProblem; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); + using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView; + using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables); + using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; + using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector); - enum { dim = GridView::dimension }; - enum { dimWorld = GridView::dimensionworld }; - enum { numComponents = FluidSystem::numComponents }; - enum { numSecComponents = FluidSystem::numSecComponents }; + static constexpr int dim = GridView::dimension; + static constexpr int dimWorld = GridView::dimensionWorld; + static constexpr int numComponents = GET_PROP_TYPE(TypeTag, ModelTraits)::numComponents(); // copy some indices for convenience - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum { - wPhaseIdx = Indices::wPhaseIdx, - nPhaseIdx = Indices::nPhaseIdx - }; - enum { - wCompIdx = FluidSystem::wCompIdx, //major component of the liquid phase - nCompIdx = FluidSystem::nCompIdx //major component of the gas phase - }; - enum { + static constexpr int wPhaseIdx = Indices::Phase0Idx; + static constexpr int nPhaseIdx = Indices::Phase1Idx; + + static constexpr int wCompIdx = FluidSystem::Comp0Idx; //major component of the liquid phase + static constexpr int nCompIdx = FluidSystem::Comp1Idx; //major component of the gas phase + + + // enum { #if !ISOTHERMAL - temperatureIdx = Indices::temperatureIdx, //temperature + static constexpr int temperatureIdx = Indices::temperatureIdx; //temperature #endif - pressureIdx = Indices::pressureIdx, //gas-phase pressure - switchIdx = Indices::switchIdx //liquid saturation or mole fraction - }; - enum { + static constexpr int pressureIdx = Indices::pressureIdx; //gas-phase pressure + static constexpr int switchIdx = Indices::switchIdx; //liquid saturation or mole fraction + // }; + + // enum { #if !ISOTHERMAL - energyEqIdx = Indices::energyEqIdx, //energy equation + static constexpr int energyEqIdx = Indices::energyEqIdx; //energy equation #endif - conti0EqIdx = Indices::conti0EqIdx - }; + static constexpr int conti0EqIdx = Indices::conti0EqIdx; + // }; + + using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); + using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); + using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes; - typedef typename GET_PROP_TYPE(TypeTag, TimeManager) TimeManager; + using Element = typename GridView::template Codim<0>::Entity; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GridView::template Codim::Entity Vertex; - typedef typename GridView::Intersection Intersection; + using Vertex = typename GridView::template Codim::Entity; + // TODO: Why is here no using keyword? Is it correct this way? + using Intersection = typename GridView::Intersection; + + using FVElementGeometry = typename FVGridGeometry::LocalView; + using SubControlVolume = typename FVElementGeometry::SubControlVolume; + using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector); - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, SpatialParams) SpatialParams; - typedef Dune::FieldVector GlobalPosition; #if !ISOTHERMAL - typedef typename Dumux::ElectroChemistryNI ElectroChemistry; + using ElectroChemistry = typename Dumux::ElectroChemistryNI; #else - typedef typename Dumux::ElectroChemistry ElectroChemistry; + using ElectroChemistry = typename Dumux::ElectroChemistry; #endif - typedef Dumux::Constants Constant; + using Constant = Dumux::Constants; - enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) }; - enum { dofCodim = isBox ? dim : 0 }; + static constexpr bool isBox = FVGridGeometry::discMethod == DiscretizationMethod::box; + static constexpr int dofCodim = isBox ? dim : 0; public: /*! * \brief The constructor * - * \param timeManager The time manager - * \param gridView The grid view + * \param fvGridGeometry Contains the Finite-Volume-Grid-Geometry */ - FuelCellLectureProblem(TimeManager &timeManager, const GridView &gridView) - : ParentType(timeManager, gridView) + FuelCellLectureProblem(std::shared_ptr fvGridGeometry) + : ParentType(fvGridGeometry) { - nTemperature_ = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.NTemperature); - nPressure_ = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.NPressure); - pressureLow_ = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.PressureLow); - pressureHigh_ = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.PressureHigh); - temperatureLow_ = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.TemperatureLow); - temperatureHigh_ = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.TemperatureHigh); - temperature_ = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.InitialTemperature); - name_ = GET_RUNTIME_PARAM(TypeTag, std::string, Problem.Name); - - pO2Inlet_ = GET_RUNTIME_PARAM(TypeTag, Scalar, ElectroChemistry.pO2Inlet); - pgInlet1_ = GET_RUNTIME_PARAM(TypeTag, Scalar, OperationalConditions.GasPressureInlet1); - pgInlet2_ = GET_RUNTIME_PARAM(TypeTag, Scalar, OperationalConditions.GasPressureInlet2); - swInlet_ = GET_RUNTIME_PARAM(TypeTag, Scalar, OperationalConditions.LiquidWaterSaturationInlet); + nTemperature_ = getParam("Problem.NTemperature"); + nPressure_ = getParam("Problem.NPressure"); + pressureLow_ = getParam("Problem.PressureLow"); + pressureHigh_ = getParam("Problem.PressureHigh"); + temperatureLow_ = getParam("Problem.TemperatureLow"); + temperatureHigh_ = getParam("Problem.TemperatureHigh"); + temperature_ = getParam("Problem.InitialTemperature"); + name_ = getParam("Problem.Name"); + + pO2Inlet_ = getParam("ElectroChemistry.pO2Inlet"); + pgInlet1_ = getParam("OperationalConditions.GasPressureInlet1"); + pgInlet2_ = getParam("OperationalConditions.GasPressureInlet2"); + swInlet_ = getParam("OperationalConditions.LiquidWaterSaturationInlet"); eps_ = 1e-6; @@ -205,19 +207,21 @@ public: Scalar temperature() const { return temperature_; } - //! \copydoc Dumux::ImplicitProblem::solDependentSource() - void solDependentSource(PrimaryVariables &values, const Element &element, - const FVElementGeometry &fvGeometry, - int scvIdx, const ElementVolumeVariables &elemVolVars) const + //! \copydoc Dumux::FVProblem::source() + NumEqVector source(const Element &element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars, + const SubControlVolume &scv) const { + NumEqVector values; - const GlobalPosition globalPos = element.geometry().corner(scvIdx); - const VolumeVariables& volVars = elemVolVars[scvIdx]; + const GlobalPosition globalPos = scv.dofPosition(); + const VolumeVariables& volVars = elemVolVars[scv]; values = 0.0; //reaction sources from electro chemistry - Scalar reactionLayerWidth = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.ReactionLayerWidth); + Scalar reactionLayerWidth = getParam("Problem.ReactionLayerWidth"); if(globalPos[0] < reactionLayerWidth + eps_) { @@ -226,7 +230,10 @@ public: auto currentDensity = ElectroChemistry::calculateCurrentDensity(volVars)/2; ElectroChemistry::reactionSource(values, currentDensity); } + + return values; } + // \} /*! @@ -236,14 +243,14 @@ public: /*! * \brief Specifies which kind of boundary condition should be - * used for which equation on a given boundary segment. + * used for which equation on a given boundary segment * - * \param values The boundary types for the conservation equations - * \param vertex The vertex for which the boundary type is set + * \param globalPos The global position */ - void boundaryTypes(BoundaryTypes &values, const Vertex &vertex) const + BoundaryTypes boundaryTypesAtPos(const GlobalPosition &globalPos) const { - const GlobalPosition globalPos = vertex.geometry().center(); + BoundaryTypes values; + values.setAllNeumann(); if((globalPos[1]>=0 && globalPos[1]<=0.0005 && globalPos[0] > 0.0005 - eps_) @@ -251,21 +258,20 @@ public: { values.setAllDirichlet(); } + + + return values; } /*! - * \brief Evaluate the boundary conditions for a dirichlet - * boundary segment. + * \brief Evaluates the boundary conditions for a Dirichlet + * boundary segment * - * \param values The dirichlet values for the primary variables - * \param vertex The vertex for which the boundary type is set - * - * For this method, the \a values parameter stores primary variables. + * \param globalPos The global position */ - void dirichlet(PrimaryVariables &values, const Vertex &vertex) const + PrimaryVariables dirichletAtPos(const GlobalPosition &globalPos) const { - const GlobalPosition globalPos = vertex.geometry().center(); - initial_(values, globalPos); + PrimaryVariables values = initial_(globalPos); //lower inlet if((globalPos[1] >= 0 && globalPos[1] <= 0.0005 && globalPos[0] > 0.0005 - eps_)) @@ -285,6 +291,7 @@ public: #if !ISOTHERMAL values[temperatureIdx] = 343.15; #endif + return values; } @@ -292,33 +299,23 @@ public: * \brief Evaluate the boundary conditions for a neumann * boundary segment. * - * \param values The neumann values for the conservation equations - * \param element The finite element - * \param fvGeometry The finite-volume geometry in the box scheme - * \param is The intersection between element and boundary - * \param scvIdx The local vertex index - * \param boundaryFaceIdx The index of the boundary face + * \param values Stores the Neumann values for the conservation equations in + * \f$ [ \textnormal{unit of conserved quantity} / (m^(dim-1) \cdot s )] \f$ + * \param globalPos The global position * - * For this method, the \a values parameter stores the mass flux - * in normal direction of each phase. Negative values mean influx. + * The \a values store the mass flux of each phase normal to the boundary. + * Negative values indicate an inflow. */ - void neumann(PrimaryVariables &values, - const Element &element, - const FVElementGeometry &fvGeometry, - const Intersection &is, - int scvIdx, - int boundaryFaceIdx) const + NumEqVector neumannAtPos(const GlobalPosition &globalPos) const { - - const GlobalPosition globalPos = element.geometry().corner(scvIdx); - - values = 0.0; + PrimaryVariables values(0.0); #if !ISOTHERMAL if (globalPos[1] >= 0.0005 && globalPos[1] <= 0.0015 && globalPos[0] > 0.0005 - eps_) values[energyEqIdx] = 9800; // [W/m^2]; heat conduction flow thorough the shoulder;from Acosta-paper: lambda_shoulder/delta_shoulder*DeltaT #endif + return values; } // \} @@ -328,25 +325,12 @@ public: // \{ /*! - * \brief Evaluate the initial value for a control volume. + * \brief Evaluates the initial values for a control volume * - * \param values The initial values for the primary variables - * \param element The finite element - * \param fvGeometry The finite-volume geometry in the box scheme - * \param scvIdx The local vertex index - * - * For this method, the \a values parameter stores primary - * variables. + * \param globalPos The global position */ - void initial(PrimaryVariables &values, - const Element &element, - const FVElementGeometry &fvGeometry, - int scvIdx) const - { - const GlobalPosition &globalPos = element.geometry().corner(scvIdx); - - initial_(values, globalPos); - } + PrimaryVariables initialAtPos(const GlobalPosition &globalPos) const + { return initial_(globalPos); } /*! * \brief Return the initial phase state inside a control volume. @@ -372,90 +356,88 @@ public: /*! * \brief Returns true if a VTK output file should be written. */ + /* bool shouldWriteOutput() const { - const int freqOutput = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, int, Output, FreqOutput); + const int freqOutput = getParam("Output.FreqOutput"); if (this->timeManager().timeStepIndex() % freqOutput == 0 || this->timeManager().episodeWillBeFinished()) return true; return false; - } + }*/ + /*! - * \brief Add problem specific vtk output for the electrochemistry + * \brief Adds additional VTK output data to the VTKWriter. Function is called by the output module on every write. */ - void addOutputVtkFields() + template + void addVtkFields(VTKWriter& vtk) { - // add the output field specific to the electrochemistry - typedef Dune::BlockVector > ScalarField; - - // get the number of degrees of freedom - unsigned numDofs = this->model().numDofs(); + const auto& gridView = this->fvGridGeometry().gridView(); + currentDensity_.resize(gridView.size(dofCodim)); + reactionSourceH2O_.resize(gridView.size(dofCodim)); + reactionSourceO2_.resize(gridView.size(dofCodim)); +#if !ISOTHERMAL + reactionSourceTemp_.resize(gridView.size(dofCodim)); +#endif - // create the required scalar fields - ScalarField *currentDensity = this->resultWriter().allocateManagedBuffer (numDofs); - ScalarField *reactionSourceH2O = this->resultWriter().allocateManagedBuffer (numDofs); - ScalarField *reactionSourceO2 = this->resultWriter().allocateManagedBuffer (numDofs); + vtk.addField(currentDensity_, "currentDensity [A/cm^2]"); + vtk.addField(reactionSourceH2O_, "reactionSourceH2O [mol/(sm^2)]"); + vtk.addField(reactionSourceO2_, "reactionSourceO2 [mol/(sm^2)]"); #if !ISOTHERMAL - ScalarField *reactionSourceTemp = this->resultWriter().allocateManagedBuffer (numDofs); + vtk.addField(reactionSourceTemp_, "reactionSourceTemp [J/(sm^2)]"); #endif - for (const auto& element : elements(this->gridView())) + } + + void updateVtkFields(const SolutionVector& curSol) + { + for (const auto& element : elements(this->fvGridGeometry().gridView())) { - FVElementGeometry fvGeometry; - fvGeometry.update(this->gridView(), element); + auto elemSol = elementSolution(element, curSol, this->fvGridGeometry()); - ElementVolumeVariables elemVolVars; - elemVolVars.update(*this, - element, - fvGeometry, - false /* oldSol? */); + auto fvGeometry = localView(this->fvGridGeometry()); + fvGeometry.bindElement(element); - for (int scvIdx = 0; scvIdx < fvGeometry.numScv; ++scvIdx) + for (auto&& scv : scvs(fvGeometry)) { - int dofIdxGlobal = this->model().dofMapper().subIndex(element, scvIdx, dofCodim); + VolumeVariables volVars; + volVars.update(elemSol, *this, element, scv); + const auto& globalPos = scv.dofPosition(); + const auto dofIdxGlobal = scv.dofIndex(); - //reactionSource Output - const GlobalPosition& globalPos = element.geometry().corner(scvIdx); - static Scalar reactionLayerWidth = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.ReactionLayerWidth); - PrimaryVariables source(0.0); + static Scalar reactionLayerWidth = getParam("Problem.ReactionLayerWidth"); if(globalPos[0] < reactionLayerWidth + eps_) { - // Hack for Acosta solution (see solDependetSource comment) - auto i = ElectroChemistry::calculateCurrentDensity(elemVolVars[scvIdx])/2; + //reactionSource Output + PrimaryVariables source; + auto i = ElectroChemistry::calculateCurrentDensity(volVars); ElectroChemistry::reactionSource(source, i); - (*reactionSourceH2O)[dofIdxGlobal] = source[wPhaseIdx]; - (*reactionSourceO2)[dofIdxGlobal] = source[numComponents-1]; + reactionSourceH2O_[dofIdxGlobal] = source[Indices::conti0EqIdx + FluidSystem::H2OIdx]; + reactionSourceO2_[dofIdxGlobal] = source[Indices::conti0EqIdx + FluidSystem::O2Idx]; #if !ISOTHERMAL - (*reactionSourceTemp)[dofIdxGlobal] = source[numComponents]; + reactionSourceTemp_[dofIdxGlobal] = source[numComponents]; #endif - (*currentDensity)[dofIdxGlobal] = i/10000; + + //Current Output in A/cm^2 + currentDensity_[dofIdxGlobal] = i/10000; } else { - (*reactionSourceH2O)[dofIdxGlobal] = 0.0; - (*reactionSourceO2)[dofIdxGlobal] = 0.0; + reactionSourceH2O_[dofIdxGlobal] = 0.0; + reactionSourceO2_[dofIdxGlobal] = 0.0; #if !ISOTHERMAL - (*reactionSourceTemp)[dofIdxGlobal] = 0.0; + reactionSourceTemp_[dofIdxGlobal] = 0.0; #endif - (*currentDensity)[dofIdxGlobal] = 0.0; + currentDensity_[dofIdxGlobal] = 0.0; } } - } - - this->resultWriter().attachDofData(*reactionSourceH2O, "reactionSourceH2O [mol/(sm^2)]", isBox); - this->resultWriter().attachDofData(*reactionSourceO2, "reactionSourceO2 [mol/(sm^2)]", isBox); - this->resultWriter().attachDofData(*currentDensity, "currentDensity [A/cm^2]", isBox); -#if !ISOTHERMAL - this->resultWriter().attachDofData(*reactionSourceTemp, "reactionSource Heat [J/(sm^2)]", isBox); -#endif } private: - void initial_(PrimaryVariables &values, - const GlobalPosition &globalPos) const + PrimaryVariables initial_( const GlobalPosition &globalPos) const { // the internal method for the initial condition @@ -465,6 +447,8 @@ private: *if wPhaseOnly, set initial values for pg (pressureIdx), xN2l (switchIdx), xO2l [mol/m3] (switchIdx+1) */ + PrimaryVariables values; + values[pressureIdx] = pgInlet1_; values[switchIdx] = swInlet_; values[switchIdx+1] = pO2Inlet_/Dumux::BinaryCoeff::H2O_O2::henry(temperature_); @@ -472,6 +456,7 @@ private: #if !ISOTHERMAL values[temperatureIdx] = 343.15; #endif + return values; } @@ -490,6 +475,13 @@ private: Scalar pgInlet1_; Scalar pgInlet2_; Scalar swInlet_; + + std::vector currentDensity_; + std::vector reactionSourceH2O_; + std::vector reactionSourceO2_; +#if !ISOTHERMAL + std::vector reactionSourceTemp_; +#endif }; } //end namespace diff --git a/lecture/mm/fuelcell/fuelcellspatialparams.hh b/lecture/mm/fuelcell/fuelcellspatialparams.hh index ee0d994..437b4e4 100644 --- a/lecture/mm/fuelcell/fuelcellspatialparams.hh +++ b/lecture/mm/fuelcell/fuelcellspatialparams.hh @@ -26,12 +26,13 @@ #ifndef DUMUX_FUELCELL_LECTURE_SPATIAL_PARAMS_HH #define DUMUX_FUELCELL_LECTURE_SPATIAL_PARAMS_HH -#include +// #include +#include #include -//#include -//#include +#include +#include #include -//#include +// #include #include "./material/regularizedacosta.hh" #include "./material/thermalconductivityconstant.hh" @@ -49,29 +50,12 @@ namespace Properties NEW_TYPE_TAG(FuelCellLectureSpatialParams); // Set the spatial parameters -SET_TYPE_PROP(FuelCellLectureSpatialParams, SpatialParams, Dumux::FuelCellLectureSpatialParams); +SET_TYPE_PROP(FuelCellLectureSpatialParams, SpatialParams, FuelCellLectureSpatialParams); // Set the constant thermal conductivity law as in Acosta paper #if !ISOTHERMAL SET_TYPE_PROP(FuelCellLectureSpatialParams, ThermalConductivityModel, Dumux::ThermalConductivityConstant); #endif - -// Set the material Law -SET_PROP(FuelCellLectureSpatialParams, MaterialLaw) -{ - private: - // define the material law which is parameterized by effective - // saturations - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - //typedef RegularizedBrooksCorey EffMaterialLaw; - //typedef RegularizedVanGenuchten EffMaterialLaw; - typedef RegularizedAcosta EffMaterialLaw; - - public: - // define the material law parameterized by absolute saturations - typedef EffToAbsLaw type; - //typedef PhilToPhobLaw type; -}; } /*! @@ -81,35 +65,43 @@ SET_PROP(FuelCellLectureSpatialParams, MaterialLaw) * problem which uses the (non-)isothermal 2pnc box model */ template -class FuelCellLectureSpatialParams : public ImplicitSpatialParams +class FuelCellLectureSpatialParams +: public FVSpatialParams> { - typedef ImplicitSpatialParams ParentType; - typedef typename GET_PROP_TYPE(TypeTag, Grid) Grid; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - - enum { dim=GridView::dimension }; - enum { dimworld=GridView::dimensionworld }; - enum { wPhaseIdx = FluidSystem::wPhaseIdx }; - - typedef Dune::FieldVector GlobalPosition; - typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GridView::template Codim<0>::Entity Element; + using ThisType = FuelCellLectureSpatialParams; + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); + using ParentType = FVSpatialParams; + // using Grid = typename GET_PROP_TYPE(TypeTag, Grid); + using GridView = typename FVGridGeometry::GridView; + using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); + + static constexpr int dim=GridView::dimension; + static constexpr int dimworld=GridView::dimensionworld; + static constexpr int wPhaseIdx = FluidSystem::wPhaseIdx; + + using Element = typename GridView::template Codim<0>::Entity; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + + using FVElementGeometry = typename FVGridGeometry::LocalView; + using SubControlVolume = typename FVElementGeometry::SubControlVolume; + + using EffectiveLaw = RegularizedAcosta; public: - typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw; - typedef typename MaterialLaw::Params MaterialLawParams; + using MaterialLaw = EffToAbsLaw; + using MaterialLawParams = typename MaterialLaw::Params; + using PermeabilityType = Scalar; /*! * \brief The constructor * * \param gridView The grid view */ - FuelCellLectureSpatialParams(const GridView &gridView) - : ParentType(gridView), K_(0) + FuelCellLectureSpatialParams(std::shared_ptr fvGridGeometry) + : ParentType(fvGridGeometry), K_(0) { // intrinsic permeabilities K_ = 5.2e-11; // Acosta absolute permeability diffusion layer @@ -139,45 +131,27 @@ public: materialParams_.setAcC(-0.2); //imbition -0.2; drainage -16; materialParams_.setAcD(-700); //imbition -700; drainage -3300; materialParams_.setAcE(0.0); //imbition 0.0; drainage 800; - - eps_ = 1e-6; - - } ~FuelCellLectureSpatialParams() {} /*! - * \brief Apply the intrinsic permeability tensor to a pressure - * potential gradient. + * \brief Returns the hydraulic conductivity \f$[m^2]\f$ * - * \param element The current finite element - * \param fvGeometry The current finite volume geometry of the element - * \param scvIdx The index of the sub-control volume + * \param globalPos The global position */ - const Scalar intrinsicPermeability(const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx) const - { - return K_; - } + PermeabilityType permeabilityAtPos(const GlobalPosition& globalPos) const + { return K_; } /*! * \brief Define the porosity \f$[-]\f$ of the spatial parameters * - * \param element The finite element - * \param fvGeometry The finite volume geometry - * \param scvIdx The local index of the sub-control volume where - * the porosity needs to be defined + * \param globalPos The global position */ - Scalar porosity(const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx) const - { - const GlobalPosition &globalPos = fvGeometry.subContVol[scvIdx].global; - - Scalar reactionLayerWidth = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.ReactionLayerWidth); + Scalar porosityAtPos(const GlobalPosition& globalPos) const + { + static Scalar reactionLayerWidth = getParam("Problem.ReactionLayerWidth"); if (globalPos[0] < reactionLayerWidth + eps_) return 0.07; @@ -190,16 +164,10 @@ public: /*! * \brief return the parameter object for the Brooks-Corey material law which depends on the position * - * \param element The current finite element - * \param fvGeometry The current finite volume geometry of the element - * \param scvIdx The index of the sub-control volume + * \param globalPos The global position */ - const MaterialLawParams& materialLawParams(const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx) const - { - return materialParams_; - } + const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const + { return materialParams_; } /*! * \brief Returns the heat capacity \f$[J / (kg K)]\f$ of the rock matrix. @@ -210,6 +178,7 @@ public: * \param fvGeometry The finite volume geometry * \param scvIdx The local index of the sub-control volume */ + template Scalar solidHeatCapacity(const Element &element, const FVElementGeometry &fvGeometry, const int scvIdx) const @@ -226,6 +195,7 @@ public: * \param fvGeometry The finite volume geometry * \param scvIdx The local index of the sub-control volume */ + template Scalar solidDensity(const Element &element, const FVElementGeometry &fvGeometry, const int scvIdx) const @@ -244,7 +214,7 @@ public: */ Scalar solidThermalConductivity(const Element &element, const FVElementGeometry &fvGeometry, - const int scvIdx) const + const SubControlVolume& scv) const { return lambdaSolid_; } diff --git a/lecture/mm/fuelcell/material/thermalconductivityconstant.hh b/lecture/mm/fuelcell/material/thermalconductivityconstant.hh index 932ad6e..1cb128b 100644 --- a/lecture/mm/fuelcell/material/thermalconductivityconstant.hh +++ b/lecture/mm/fuelcell/material/thermalconductivityconstant.hh @@ -52,8 +52,8 @@ public: const SpatialParams& spatialParams, const Element& element, const FVGeometry& fvGeometry, - int scvIdx) - { return spatialParams.solidThermalConductivity(element, fvGeometry, scvIdx); } + const typename FVGeometry::SubControlVolume& scv) + { return spatialParams.solidThermalConductivity(element, fvGeometry, scv); } }; } #endif diff --git a/lecture/mm/heatpipe/heatpipe.cc b/lecture/mm/heatpipe/heatpipe.cc index d6fd721..6201e57 100644 --- a/lecture/mm/heatpipe/heatpipe.cc +++ b/lecture/mm/heatpipe/heatpipe.cc @@ -51,8 +51,175 @@ void usage(const char *progName, const std::string &errorMsg) } } -int main(int argc, char** argv) +//////////////////////// +// the main function +//////////////////////// +int main(int argc, char** argv) try { - typedef TTAG(HeatpipeProblem) ProblemTypeTag; - return Dumux::start(argc, argv, usage); + // typedef TTAG(LensOnePTwoCProblem) TypeTag; + // return Dumux::start(argc, argv, usage); + using namespace Dumux; + + // define the type tag for this problem + using TypeTag = TTAG(HeatpipeProblem); + + // 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(leafGridView); + fvGridGeometry->update(); + + // the problem (initial and boundary conditions) + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); + auto problem = std::make_shared(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(problem, fvGridGeometry); + gridVariables->init(x, xOld); + + // get some time loop parameters + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + const auto tEnd = getParam("TimeLoop.TEnd"); + const auto maxDivisions = getParam("TimeLoop.MaxTimeStepDivisions"); // Q: What is this? Do we need this here? + const auto maxDt = getParam("TimeLoop.MaxTimeStepSize"); + auto dt = getParam("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")) // Fehlt ebenso + restartTime = getParam("TimeLoop.Restart"); + + // intialize the vtk output module + using VtkOutputFields = typename GET_PROP_TYPE(TypeTag, VtkOutputFields); + VtkOutputModule 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>(restartTime, dt, tEnd); + timeLoop->setMaxTimeStepSize(maxDt); + + // the assembler with time loop for instationary problem + using Assembler = FVAssembler; + auto assembler = std::make_shared(problem, fvGridGeometry, gridVariables, timeLoop); + + // the linear solver + using LinearSolver = AMGBackend; + auto linearSolver = std::make_shared(leafGridView, fvGridGeometry->dofMapper()); + + // the non-linear solver + using NewtonSolver = Dumux::NewtonSolver; + NewtonSolver nonLinearSolver(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 the Newton solver + timeLoop->setTimeStepSize(nonLinearSolver.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); + } + + + +} + +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; } diff --git a/lecture/mm/heatpipe/heatpipe.input b/lecture/mm/heatpipe/heatpipe.input index 8b65002..8ca51f4 100644 --- a/lecture/mm/heatpipe/heatpipe.input +++ b/lecture/mm/heatpipe/heatpipe.input @@ -1,6 +1,6 @@ -[TimeManager] +[TimeLoop] DtInitial = 1 # [s] TEnd = 2.2e12 # [s] EpisodeLength = 1.e11 diff --git a/lecture/mm/heatpipe/heatpipeproblem.hh b/lecture/mm/heatpipe/heatpipeproblem.hh index 0ae6e29..7d0e5f9 100644 --- a/lecture/mm/heatpipe/heatpipeproblem.hh +++ b/lecture/mm/heatpipe/heatpipeproblem.hh @@ -51,33 +51,23 @@ SET_TYPE_PROP(HeatpipeProblem, Problem, HeatpipeProblem); // Set the fluid system SET_TYPE_PROP(HeatpipeProblem, FluidSystem, FluidSystems::H2OAir); -// Disable gravity -SET_BOOL_PROP(HeatpipeProblem, ProblemEnableGravity, false); - -// Use central differences -SET_INT_PROP(HeatpipeProblem, ImplicitNumericDifferenceMethod, 0); - -// Write newton convergence -SET_BOOL_PROP(HeatpipeProblem, NewtonWriteConvergence, false); -} - - /* This problem uses the \ref TwoPTwoCNIModel model. * * To run the simulation execute the following line in shell: * ./heatpipe -ParameterFile heatpipe.input * */ template -class HeatpipeProblem : public ImplicitPorousMediaProblem +class HeatpipeProblem : public PorouMediumFlowProblem { - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::Grid Grid; + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using Grid = typename GridView::Grid; - typedef ImplicitPorousMediaProblem ParentType; + using ParentType = ImplicitPorousMediaProblem; // copy some indices for convenience - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; + using Indices = typename GET_PROP_TYPE(TypeTag, Indices); + enum { pressureIdx = Indices::pressureIdx, @@ -95,20 +85,18 @@ class HeatpipeProblem : public ImplicitPorousMediaProblem conti0EqIdx = Indices::conti0EqIdx, contiNEqIdx = conti0EqIdx + Indices::nCompIdx }; + using GlobalPosition = Dune::FieldVector; + using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); + using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes; - typedef typename GET_PROP_TYPE(TypeTag, TimeManager) TimeManager; + using Element = typename GridView::template Codim<0>::Entity; + using Vertex = typename GridView::template Codim::Entity; + using Intersection = typename GridView::Intersection; - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GridView::template Codim::Entity Vertex; - typedef typename GridView::Intersection Intersection; + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); + using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - - typedef Dune::FieldVector GlobalPosition; public: /*! @@ -117,13 +105,13 @@ public: * \param timeManager The time manager * \param gridView The grid view */ - HeatpipeProblem(TimeManager &timeManager, const GridView &gridView) - : ParentType(timeManager, gridView) + HeatpipeProblem(std::shared_ptr(const FVElementGeometry) fvElementGeometry) + : ParentType(fvElementGeometry) { eps_ = 1e-6; FluidSystem::init(); - episodeLength_ = GET_RUNTIME_PARAM(TypeTag, Scalar, TimeManager.EpisodeLength); + episodeLength_ = getParam("TimeLoop.EpisodeLength"); this->timeManager().startNextEpisode(episodeLength_); } @@ -140,10 +128,9 @@ public: std::string name() const { return "heatpipe"; } - void sourceAtPos(PrimaryVariables &values, - const GlobalPosition &globalPos) const + numEqVector sourceAtPos(const GlobalPosition &globalPos) const { - values = 0; + return numEqVector(0.0); } // \} @@ -160,14 +147,18 @@ public: * \param values The boundary types for the conservation equations * \param vertex The vertex for which the boundary type is set */ - void boundaryTypes(BoundaryTypes &values, const Vertex &vertex) const + BoundaryTypes boundaryTypes(const Vertex &vertex) const { + BoundaryTypes values; + const GlobalPosition globalPos = vertex.geometry().center(); if(globalPos[0] < eps_) values.setAllDirichlet(); else values.setAllNeumann(); + + return values; } /*! @@ -179,11 +170,15 @@ public: * * For this method, the \a values parameter stores primary variables. */ - void dirichlet(PrimaryVariables &values, const Vertex &vertex) const + PrimaryVariables dirichlet(const Vertex &vertex) const { + PrimaryVariables values; + values[pressureIdx] = 1.013e5; values[switchIdx] = 0.01; values[temperatureIdx] = 341.75; + + return values; } /*! @@ -197,16 +192,17 @@ public: * For this method, the \a values parameter stores the mass flux * in normal direction of each phase. Negative values mean influx. */ - void neumannAtPos(PrimaryVariables &values, - const GlobalPosition &globalPos) const + PrimaryVariables neumannAtPos( const GlobalPosition &globalPos) const { - values = 0; + PrimaryVariables values(0.0); // negative values for injection if (globalPos[0] > (this->bBoxMax()[0] - eps_)) { values[energyEqIdx] = GET_RUNTIME_PARAM(TypeTag, Scalar, heatFlux); } + + return values; } // \} @@ -227,14 +223,16 @@ public: * For this method, the \a values parameter stores primary * variables. */ - void initial(PrimaryVariables &values, - const Element &element, + PrimaryVariables initial(const Element &element, const FVElementGeometry &fvGeometry, int scvIdx) const { + PrimaryVariables values; const GlobalPosition &globalPos = element.geometry().corner(scvIdx); initial_(values, globalPos); + + return values; } /*! @@ -252,27 +250,18 @@ public: return 0; } - bool shouldWriteOutput() const - { - return - this->timeManager().timeStepIndex() == 0 || - this->timeManager().episodeWillBeFinished() || - this->timeManager().willBeFinished(); - } - - void episodeEnd() - { - this->timeManager().startNextEpisode(episodeLength_); - } private: // internal method for the initial condition (reused for the // dirichlet conditions!) - void initial_(PrimaryVariables &values, - const GlobalPosition &globalPos) const + PrimaryVariables initial_(const GlobalPosition &globalPos) const { + PrimaryVariables values; + values[pressureIdx] = 1.013e5; values[switchIdx] = 0.5; values[temperatureIdx] = 343.15; + + return values; } Scalar eps_; diff --git a/lecture/mm/heatpipe/heatpipespatialparams.hh b/lecture/mm/heatpipe/heatpipespatialparams.hh index 38ee5f6..5e385a3 100644 --- a/lecture/mm/heatpipe/heatpipespatialparams.hh +++ b/lecture/mm/heatpipe/heatpipespatialparams.hh @@ -50,9 +50,9 @@ SET_TYPE_PROP(HeatpipeSpatialParams, SpatialParams, Dumux::HeatpipeSpatialParams SET_PROP(HeatpipeSpatialParams, MaterialLaw) { private: - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); public: - typedef KrPcHeatpipe type; + using type = KrPcHeatpipe; }; } @@ -61,48 +61,53 @@ SET_PROP(HeatpipeSpatialParams, MaterialLaw) * \ingroup BoxTestProblems * \brief Definition of the spatial parameters for the water-air problem */ -template -class HeatpipeSpatialParams : public ImplicitSpatialParams +template +class HeatpipeSpatialParams : public FVSpatialParams > { - typedef ImplicitSpatialParams ParentType; - - typedef typename GET_PROP_TYPE(TypeTag, Grid) Grid; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename Grid::ctype CoordScalar; - enum { - dim=GridView::dimension, - dimWorld=GridView::dimensionworld - }; - - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum { + using ParentType = ImplicitSpatialParams; + using ParentType = FVSpatialParams; + + using Element = typename GridView::template Codim<0>::Entity; + + // using Grid = typename GET_PROP_TYPE(TypeTag, Grid); + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using CoordScalar = typename Grid::ctype; + + static constexpr auto dim=GridView::dimension; + static constexpr auto dimWorld=GridView::dimensionworld; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + + using ModelTraits = typename GET_PROP_TYPE(TypeTag, ModelTraits); + using Indices = typename ModelTraits::Indices; + +/* enum { wPhaseIdx = Indices::wPhaseIdx - }; + };*/ + static constexpr wPhaseIdx = Indices::wPhaseIdx; + + using DimVector = Dune::FieldVector; // TODO: Implementation is Up-to date? - typedef Dune::FieldVector GlobalPosition; - typedef Dune::FieldVector DimVector; + using FluxVariables = typename GET_PROP_TYPE(TypeTag, FluxVariables); + using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables); - typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GridView::template Codim<0>::Entity Element; public: - typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw; - typedef typename MaterialLaw::Params MaterialLawParams; + using MaterialLaw = typename GET_PROP_TYPE(TypeTag, MaterialLaw); + using MaterialLawParams = typename MaterialLaw::Params; /*! * \brief The constructor * * \param gridView The grid view */ - HeatpipeSpatialParams(const GridView &gridView) - : ParentType(gridView) + HeatpipeSpatialParams(std::shared_ptr fvGridGeometry) + : ParentType(fvGridGeometry) { // intrinsic permeabilities - K_ = GET_RUNTIME_PARAM(TypeTag, Scalar, permeability); + K_ = getParam("permeability"); // param in a no-name branch: Should this be changed? // porosities Porosity_ = 0.4; @@ -207,7 +212,7 @@ public: const FVElementGeometry &fvGeometry, const int scvIdx) const { - return 2.8*GET_RUNTIME_PARAM(TypeTag, Scalar, multiplierHeatCond); + return 2.8*getParam("multiplierHeatCond"); } @@ -222,4 +227,4 @@ private: } -#endif +#endif // DUMUX_HEATPIPE_SPATIAL_PARAMS_HH diff --git a/lecture/mm/heatpipe/krpcheatpipe.hh b/lecture/mm/heatpipe/krpcheatpipe.hh index 1da6ee6..57d5ab6 100644 --- a/lecture/mm/heatpipe/krpcheatpipe.hh +++ b/lecture/mm/heatpipe/krpcheatpipe.hh @@ -46,8 +46,8 @@ template +#include #include -#include +#include #include "spatialparams.hh" #define ISOTHERMAL 0 @@ -56,9 +56,7 @@ SET_TYPE_PROP(SagdProblem, Dumux::FluidSystems::H2OHeavyOil); -// Enable gravity -SET_BOOL_PROP(SagdProblem, ProblemEnableGravity, true); - +// TODO: Do we need the following Properties? // Use forward differences instead of central differences SET_INT_PROP(SagdProblem, ImplicitNumericDifferenceMethod, +1); @@ -80,59 +78,51 @@ SET_BOOL_PROP(SagdProblem, UseMassOutput, true); * * */ template -class SagdProblem : public ImplicitPorousMediaProblem +class SagdProblem : public PorousMediumFlowProblem { - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::Grid Grid; + using ParentType = PorousMediumFlowProblem; - typedef ImplicitPorousMediaProblem ParentType; + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using Grid = typename GridView::Grid; // copy some indices for convenience - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum { - pressureIdx = Indices::pressureIdx, - switch1Idx = Indices::switch1Idx, - switch2Idx = Indices::switch2Idx, - - energyEqIdx = Indices::energyEqIdx, + using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; - // phase and component indices - wPhaseIdx = Indices::wPhaseIdx, - nPhaseIdx = Indices::nPhaseIdx, - gPhaseIdx = Indices::gPhaseIdx, - wCompIdx = Indices::wCompIdx, - nCompIdx = Indices::nCompIdx, + static constexpr pressureIdx = Indices::pressureIdx; + static constexpr switch1Idx = Indices::switch1Idx; + static constexpr switch2Idx = Indices::switch2Idx; - // Phase State - wPhaseOnly = Indices::wPhaseOnly, - wnPhaseOnly = Indices::wnPhaseOnly, - wgPhaseOnly = Indices::wgPhaseOnly, - threePhases = Indices::threePhases, + static constexpr energyEqIdx = Indices::energyEqIdx; - //contiWEqIdx = Indices::contiWEqIdx, - //contiNEqIdx = Indices::contiNEqIdx, - // Grid and world dimension - dim = GridView::dimension, - dimWorld = GridView::dimensionworld - }; + // phase and component indices + static constexpr wPhaseIdx = Indices::Phase0Idx; + static constexpr nPhaseIdx = Indices::Phase1Idx; + static constexpr gPhaseIdx = Indices::Phase2Idx; + static constexpr wCompIdx = Indices::wCompIdx; + static constexpr nCompIdx = Indices::nCompIdx; + // Phase State + static constexpr wPhaseOnly = Indices::wPhaseOnly; + static constexpr wnPhaseOnly = Indices::wnPhaseOnly; + static constexpr wgPhaseOnly = Indices::wgPhaseOnly; + static constexpr threePhases = Indices::threePhases; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes; - typedef typename GET_PROP_TYPE(TypeTag, TimeManager) TimeManager; + static constexpr int dim = GridView::dimension; + static constexpr int dimWorld = GridView::dimensionworld; + using GlobalPosition = Dune::FieldVector; - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GridView::template Codim::Entity Vertex; - typedef typename GridView::Intersection Intersection; + using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); + using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; + //typedef typename GridView::template Codim<0>::Entity Element; + //typedef typename GridView::template Codim::Entity Vertex; + //typedef typename GridView::Intersection Intersection; - typedef Dune::FieldVector GlobalPosition; + using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); + using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); - enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) }; + static constexpr isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox); public: @@ -143,8 +133,7 @@ public: * \param gridView The grid view */ - SagdProblem(TimeManager &timeManager, const GridView &gridView) - : ParentType(timeManager, gridView), eps_(1e-6), pOut_(4e6) + SagdProblem(std::shared_ptr fvGridGeometry) : ParentType(fvGridGeometry) { maxDepth_ = 400.0; // [m] @@ -152,11 +141,11 @@ public: totalMassProducedOil_ =0; totalMassProducedWater_ =0; - this->timeManager().startNextEpisode(86400); + this->timeManager().startNextEpisode(86400); // TODO: correct this - name_ = GET_RUNTIME_PARAM(TypeTag, std::string, Problem.Name); + name_ = getParam("Problem.Name"); } - +/* bool shouldWriteRestartFile() const { return @@ -165,8 +154,8 @@ public: this->timeManager().episodeWillBeFinished() || this->timeManager().willBeFinished(); } - - bool shouldWriteOutput() const +*/ + /* bool shouldWriteOutput() const { return this->timeManager().timeStepIndex() == 0 || @@ -174,12 +163,12 @@ public: this->timeManager().episodeWillBeFinished() || this->timeManager().willBeFinished(); } - +*/ /*! * \brief Called directly after the time integration. */ - +/* void postTimeStep() { double time = this->timeManager().time(); @@ -232,7 +221,8 @@ public: std::cout<<" totalMassProducedWater_ : "<< totalMassProducedWater_ << " Time: " << time+dt << std::endl; } } - +*/ +/* void episodeEnd() { // Start new episode if episode is over @@ -240,7 +230,7 @@ public: this->timeManager().startNextEpisode(3600*24*1.); //episode length sent to 1 day std::cout<<"Episode index is set to: "<timeManager().episodeIndex()< +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "problem.hh" /*! * \brief Provides an interface for customizing error messages associated with @@ -34,6 +56,7 @@ * \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) { @@ -52,12 +75,156 @@ void usage(const char *progName, const std::string &errorMsg) } } -int main(int argc, char** argv) +//////////////////////// +// the main function +//////////////////////// +int main(int argc, char** argv) try { + // typedef TTAG(LensOnePTwoCProblem) TypeTag; + // return Dumux::start(argc, argv, usage); + using namespace Dumux; + + // define the type tag for this problem + using TypeTag = TTAG(SagdBoxProblem); +Box + // 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(leafGridView); + fvGridGeometry->update(); + + // the problem (initial and boundary conditions) + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); + auto problem = std::make_shared(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(problem, fvGridGeometry); + gridVariables->init(x, xOld); + + // get some time loop parameters + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + const auto tEnd = getParam("TimeLoop.TEnd"); + const auto maxDt = getParam("TimeLoop.MaxTimeStepSize"); + auto dt = getParam("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")) // Fehlt ebenso + restartTime = getParam("TimeLoop.Restart"); + + // intialize the vtk output module + using VtkOutputFields = typename GET_PROP_TYPE(TypeTag, VtkOutputFields); + VtkOutputModule vtkWriter(*problem, *fvGridGeometry, *gridVariables, x, problem->name()); + VtkOutputFields::init(vtkWriter); //!< Add model specific output fields + vtkWriter.write(0.0); - typedef TTAG(SagdBoxProblem) ProblemTypeTag; - //typedef TTAG(SagdCCProblem) ProblemTypeTag; - return Dumux::start(argc, argv, usage); + // instantiate time loop + auto timeLoop = std::make_shared>(restartTime, dt, tEnd); + timeLoop->setMaxTimeStepSize(maxDt); + // the assembler with time loop for instationary problem + using Assembler = FVAssembler; + auto assembler = std::make_shared(problem, fvGridGeometry, gridVariables, timeLoop); + // the linear solver + using LinearSolver = AMGBackend; + auto linearSolver = std::make_shared(leafGridView, fvGridGeometry->dofMapper()); + + // the non-linear solver + using NewtonSolver = PriVarSwitchNewtonSolver; + NewtonSolver nonLinearSolver(assembler, linearSolver); + + // time loop + timeLoop->start(); do + { + // set previous solution for storage evaluations + assembler->setPreviousSolution(xOld); + + // solve the non-linear system with time step control + nonLinearSolver.solve(x, *timeLoop); + + // 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 the Newton solver + timeLoop->setTimeStepSize(nonLinearSolver.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); + } +} + +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; } diff --git a/lecture/mm/heavyoil/sagd/sagd.input b/lecture/mm/heavyoil/sagd/sagd.input index 1863a0b..686798d 100644 --- a/lecture/mm/heavyoil/sagd/sagd.input +++ b/lecture/mm/heavyoil/sagd/sagd.input @@ -1,4 +1,4 @@ -[TimeManager] +[TimeLoop] DtInitial = 1800 # [s] TEnd = 31467600 # [s] a year MaxTimeStepSize = 1800 # [s] diff --git a/lecture/mm/heavyoil/sagd/spatialparams.hh b/lecture/mm/heavyoil/sagd/spatialparams.hh index 034a607..578bd81 100644 --- a/lecture/mm/heavyoil/sagd/spatialparams.hh +++ b/lecture/mm/heavyoil/sagd/spatialparams.hh @@ -25,7 +25,7 @@ #ifndef DUMUX_SAGD_SPATIAL_PARAMS_HH #define DUMUX_SAGD_SPATIAL_PARAMS_HH -#include +#include #include #include "../3p/parkervangenuchtenzero.hh" @@ -35,7 +35,7 @@ namespace Dumux { //forward declaration -template +template class SagdSpatialParams; namespace Properties @@ -47,13 +47,15 @@ NEW_TYPE_TAG(SagdSpatialParams); SET_TYPE_PROP(SagdSpatialParams, SpatialParams, Dumux::SagdSpatialParams); // Set the material Law -SET_PROP(SagdSpatialParams, MaterialLaw) +SET_PROP(SagdSpatialParams, Problem::SpatialParams::MaterialLaw) { private: - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; + using Scalar = GET_PROP_TYPE(TypeTag, Scalar); public: - typedef ParkerVanGenZero3P type; + using type = ParkerVanGenZero3P; }; + using MaterialLaw = typename Problem::SpatialParams::MaterialLaw + using MaterialLawParams = typename MaterialLaw::Params; } /*! @@ -61,50 +63,46 @@ SET_PROP(SagdSpatialParams, MaterialLaw) * * \brief Definition of the spatial parameters for the SAGD problem */ -template -class SagdSpatialParams : public ImplicitSpatialParams +template +class SagdSpatialParams : public FVSpatialParams > { - typedef ImplicitSpatialParams ParentType; + using ParentType = FVSpatialParams >; - typedef typename GET_PROP_TYPE(TypeTag, Grid) Grid; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename Grid::ctype CoordScalar; - enum { - dim=GridView::dimension, - dimWorld=GridView::dimensionworld - }; + using Grid = typename GET_PROP_TYPE(TypeTag, Grid): + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using CoordScalar = typename Grid::ctype; - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum { - wPhaseIdx = Indices::wPhaseIdx, - nPhaseIdx = Indices::nPhaseIdx - }; + static constexpr int dim = GridView::dimension; + static constexpr int dimWorld = GridView::dimensionworld; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + using DimVecotr = Dune::FieldVector; // TODO: What is this? - typedef Dune::FieldVector GlobalPosition; - typedef Dune::FieldVector DimVector; + using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; + static constexpr int wPhaseIdx = Indices::Phase0Idx; + static constexpr int nPhaseIdx = Indices::Phase1Idx; - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector; + using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector); - typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; + // typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; + // typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GridView::template Codim<0>::Entity Element; + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); + using Element = typename GridView::template Codim<0>::Entity; public: - typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw; - typedef typename MaterialLaw::Params MaterialLawParams; + using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; + using MaterialLawParams = typename MaterialLaw::Params; /*! * \brief The constructor * * \param gridView The grid view */ - SagdSpatialParams(const GridView &gridView) - : ParentType(gridView) + SagdSpatialParams(std::shared_ptr fvGridGeometry) + : ParentType(fvGridGeometry) { layerBottom_ = 35.0; @@ -151,12 +149,18 @@ public: * \param fvElemGeom The current finite volume geometry of the element * \param scvIdx The index of the sub-control volume */ - Scalar intrinsicPermeability(const Element &element, + + // TODO: How to change this correctly? + /* Scalar intrinsicPermeability(const Element &element, const FVElementGeometry &fvElemGeom, - int scvIdx) const + int scvIdx) const */ + template + Scalar permeability(const Element element, + const SubControlVolume &scv, + const ElementSolution &elemSol) const { - const GlobalPosition &pos = fvElemGeom.subContVol[scvIdx].global; - if (isFineMaterial_(pos)) + // const GlobalPosition &pos = element.geometry().center(); // fvElemGeom.subContVol[scvIdx].global; + if (isFineMaterial_(element.geometry().center() )) // kaiw: inspired from /run/media/kaiw/workspace4/DUMUX/dumux-lecture/lecture/efm/1p2c_2p_2p2c/lens2pspatialparams.hh line 131 return fineK_; return coarseK_; } @@ -169,12 +173,13 @@ public: * \param scvIdx The local index of the sub-control volume where * the porosity needs to be defined */ + template Scalar porosity(const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx) const + const SubControlVolume& scv, + const ElementSolution& elemSol) const { - const GlobalPosition &pos = fvGeometry.subContVol[scvIdx].global; - if (isFineMaterial_(pos)) + // const GlobalPosition &pos = fvGeometry.subContVol[scvIdx].global; + if (isFineMaterial_(element.geometry().center() )) return finePorosity_; else return coarsePorosity_; @@ -208,12 +213,13 @@ public: * \param fvGeometry The finite volume geometry * \param scvIdx The local index of the sub-control volume */ + template Scalar solidHeatCapacity(const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx) const + const SubControlVolume& scv, + const ElementSolution& elemSol) const { - const GlobalPosition &pos = fvGeometry.subContVol[scvIdx].global; - if (isFineMaterial_(pos)) + // const GlobalPosition &pos = fvGeometry.subContVol[scvIdx].global; + if (isFineMaterial_( element.geometry().center() )) return fineHeatCap_; else return coarseHeatCap_; @@ -229,8 +235,8 @@ public: * \param scvIdx The local index of the sub-control volume */ Scalar solidDensity(const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx) const + const SubControlVolume& scv, + const ElementSolution& elemSol) const { return 2650; // density of sand [kg/m^3] } @@ -245,8 +251,8 @@ public: * \param scvIdx The local index of the sub-control volume */ Scalar solidThermalConductivity(const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx) const + const SubControlVolume& scv, + const ElementSolution& elemSol) const { return lambdaSolid_; } diff --git a/lecture/mm/heavyoil/sagdcyclic/problem.hh b/lecture/mm/heavyoil/sagdcyclic/problem.hh index cf9928c..741cbbb 100644 --- a/lecture/mm/heavyoil/sagdcyclic/problem.hh +++ b/lecture/mm/heavyoil/sagdcyclic/problem.hh @@ -82,57 +82,54 @@ SET_BOOL_PROP(SagdCyclicProblem, UseSimpleModel, true); * * */ template -class SagdCyclicProblem : public ImplicitPorousMediaProblem +class SagdCyclicProblem : public PorousMediumFlowProblem { - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::Grid Grid; + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using Grid = typename GridView::Grid; - typedef ImplicitPorousMediaProblem ParentType; + using ParentType = ImplicitPorousMediaProblem; // copy some indices for convenience - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum { - pressureIdx = Indices::pressureIdx, - switch1Idx = Indices::switch1Idx, - switch2Idx = Indices::switch2Idx, - - energyEqIdx = Indices::energyEqIdx, - - // phase and component indices - wPhaseIdx = Indices::wPhaseIdx, - nPhaseIdx = Indices::nPhaseIdx, - gPhaseIdx = Indices::gPhaseIdx, - wCompIdx = Indices::wCompIdx, - nCompIdx = Indices::nCompIdx, - - // Phase State - wPhaseOnly = Indices::wPhaseOnly, - wnPhaseOnly = Indices::wnPhaseOnly, - wgPhaseOnly = Indices::wgPhaseOnly, - threePhases = Indices::threePhases, + using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; + + static constexpr int pressureIdx = Indices::pressureIdx; + static constexpr int switch1Idx = Indices::switch1Id; + static constexpr int switch2Idx = Indices::switch2Idx; + + static constexpr int energyEqIdx = Indices::energyEqIdx; + + // phase and component indices + static constexpr int wPhaseIdx = Indices::Phase0Idx; + static constexpr int PhaseIdx = Indices::Phase1Idx; + static constexpr int gPhaseIdx = Indices::Phase2Idx; + static constexpr int wCompIdx = Indices::Comp0Idx; + static constexpr int nCompIdx = Indices::Comp1Idx; + + // Phase State + static constexpr int wPhaseOnly = Indices::wPhaseOnly; + static constexpr int wnPhaseOnly = Indices::wnPhaseOnly; + static constexpr int wgPhaseOnly = Indices::wgPhaseOnly; + static constexpr int threePhases = Indices::threePhases; //contiWEqIdx = Indices::contiWEqIdx, //contiNEqIdx = Indices::contiNEqIdx, - // Grid and world dimension - dim = GridView::dimension, - dimWorld = GridView::dimensionworld - }; - - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes; - typedef typename GET_PROP_TYPE(TypeTag, TimeManager) TimeManager; + // Grid and world dimension + static constexpr int dim = GridView::dimension; + static constexpr int dimWorld = GridView::dimensionworld; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GridView::template Codim::Entity Vertex; - typedef typename GridView::Intersection Intersection; + using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); + using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; + using Element = typename GridView::template Codim<0>::Entity; + // typename GridView::template Codim::Entity Vertex; + // typedef typename GridView::Intersection Intersection; - typedef Dune::FieldVector GlobalPosition; + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); + using FluidSystem 0 typename GET_PROP_TYPE(TypeTag, FluidSystem); + using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables); enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) }; @@ -143,8 +140,7 @@ public: * \param timeManager The time manager * \param gridView The grid view */ - SagdCyclicProblem(TimeManager &timeManager, const GridView &gridView) - : ParentType(timeManager, gridView), eps_(1e-6), pOut_(4.0e6) + SagdCyclicProblem(std::shared_ptr fvGridGeom : ParentType(fvGridGeom) { maxDepth_ = 400.0; // [m] FluidSystem::init(); @@ -152,33 +148,33 @@ public: totalMassProducedWater_ = 0; //episodeLength_ = 3600*12; //12 hours episodeLength - this->timeManager().startNextEpisode(3600*12.); - name_ = GET_RUNTIME_PARAM(TypeTag, std::string, Problem.Name); + this->timeLoop().startNextEpisode(3600*12.); + name_ = getParam("Problem.Name"); } - bool shouldWriteRestartFile() const +/* bool shouldWriteRestartFile() const { return - this->timeManager().timeStepIndex() == 0 || - this->timeManager().timeStepIndex() % 10000 == 0 || - this->timeManager().episodeWillBeFinished() || - this->timeManager().willBeFinished(); + this->timeLoop().timeStepIndex() == 0 || + this->timeLoop().timeStepIndex() % 10000 == 0 || + this->timeLoop().episodeWillBeFinished() || + this->timeLoop().willBeFinished(); } - - bool shouldWriteOutput() const +*/ +/* bool shouldWriteOutput() const { return - this->timeManager().timeStepIndex() == 0 || - this->timeManager().timeStepIndex() % 10000 == 0 || - this->timeManager().episodeWillBeFinished() || - this->timeManager().willBeFinished(); + this->timeLoop().timeStepIndex() == 0 || + this->timeLoop().timeStepIndex() % 10000 == 0 || + this->timeLoop().episodeWillBeFinished() || + this->timeLoop().willBeFinished(); } - - void postTimeStep() +*/ +/* void postTimeStep() { - Scalar time = this->timeManager().time(); - Scalar dt = this->timeManager().timeStepSize(); + Scalar time = this->timeLoop().time(); + Scalar dt = this->timeLoop().timeStepSize(); // Calculate storage terms PrimaryVariables storage; @@ -195,7 +191,7 @@ public: massBalance.close(); } - +*/ //mass of Oil Scalar newMassProducedOil_ = massProducedOil_; //std::cout<<" newMassProducedOil_ : "<< newMassProducedOil_ << " Time: " << time+dt << std::endl; @@ -209,10 +205,10 @@ public: totalMassProducedWater_ += newMassProducedWater_; //std::cout<<" totalMassProducedWater_ : "<< totalMassProducedWater_ << " Time: " << time+dt << std::endl; - const int timeStepIndex = this->timeManager().timeStepIndex(); + const int timeStepIndex = this->timeLoop().timeStepIndex(); if (timeStepIndex == 0 || timeStepIndex % 100 == 0 - || this->timeManager().episodeWillBeFinished() - || this->timeManager().willBeFinished()) + || this->timeLoop().episodeWillBeFinished() + || this->timeLoop().willBeFinished()) { //std::cout<<" newMassProducedOil_ : "<< newMassProducedOil_ << " Time: " << time+dt << std::endl; @@ -227,11 +223,11 @@ public: void episodeEnd() { - indexEpisode_ = this->timeManager().episodeIndex(); + indexEpisode_ = this->timeLoop().episodeIndex(); // Start new episode if episode is over // for first 10 year episode length is 1 year - this->timeManager().startNextEpisode(3600*12); //episode length sent to 12 hours + this->timeLoop().startNextEpisode(3600*12); //episode length sent to 12 hours std::cout<<"Episode index is set to: "<timeManager().episodeIndex(); + int indexEpisode = this->timeLoop().episodeIndex(); GlobalPosition globalPos; if (isBox) @@ -475,10 +471,11 @@ private: values[switch2Idx] = 0.3; //NAPL saturation } + static constexpr Scalar eps_ = 1e-6; + Scalar maxDepth_; - Scalar eps_; Scalar pIn_; - Scalar pOut_; + Scalar pOut_ = 0 4.0e6; Scalar totalMassProducedOil_; Scalar totalMassProducedWater_; // TODO this is a very dirty evil solution diff --git a/lecture/mm/heavyoil/sagdcyclic/sagd_cyclic.cc b/lecture/mm/heavyoil/sagdcyclic/sagd_cyclic.cc index 00087f1..75ede1b 100644 --- a/lecture/mm/heavyoil/sagdcyclic/sagd_cyclic.cc +++ b/lecture/mm/heavyoil/sagdcyclic/sagd_cyclic.cc @@ -52,9 +52,158 @@ void usage(const char *progName, const std::string &errorMsg) } } -int main(int argc, char** argv) +//////////////////////// +// the main function +//////////////////////// +int main(int argc, char** argv) try { - typedef TTAG(SagdCyclicBoxProblem) ProblemTypeTag; - //typedef TTAG(SagdCCProblem) ProblemTypeTag; - return Dumux::start(argc, argv, usage); + // typedef TTAG(LensOnePTwoCProblem) TypeTag; + // return Dumux::start(argc, argv, usage); + using namespace Dumux; + + // define the type tag for this problem + using TypeTag = TTAG(SagdCyclicBoxProblem); + + // 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(leafGridView); + fvGridGeometry->update(); + + // the problem (initial and boundary conditions) + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); + auto problem = std::make_shared(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(problem, fvGridGeometry); + gridVariables->init(x, xOld); + + // get some time loop parameters + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + const auto tEnd = getParam("TimeLoop.TEnd"); + const auto maxDt = getParam("TimeLoop.MaxTimeStepSize"); + auto dt = getParam("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")) // Fehlt ebenso + restartTime = getParam("TimeLoop.Restart"); + + // intialize the vtk output module + using VtkOutputFields = typename GET_PROP_TYPE(TypeTag, VtkOutputFields); + VtkOutputModule 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>(restartTime, dt, tEnd); + timeLoop->setMaxTimeStepSize(maxDt); + + // the assembler with time loop for instationary problem + using Assembler = FVAssembler; + auto assembler = std::make_shared(problem, fvGridGeometry, gridVariables, timeLoop); + + // the linear solver + using LinearSolver = AMGBackend; + auto linearSolver = std::make_shared(leafGridView, fvGridGeometry->dofMapper()); + + // the non-linear solver + using NewtonSolver = Dumux::NewtonSolver; + NewtonSolver nonLinearSolver(assembler, linearSolver); + + // time loop + timeLoop->start(); do + { + // set previous solution for storage evaluations + assembler->setPreviousSolution(xOld); + + // solve the non-linear system with time step control + nonLinearSolver.solve(x, *timeLoop); + + // 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 the Newton solver + timeLoop->setTimeStepSize(nonLinearSolver.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); + } + + + +} + +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; } diff --git a/lecture/mm/heavyoil/sagdcyclic/sagd_cyclic.input b/lecture/mm/heavyoil/sagdcyclic/sagd_cyclic.input index a93eb71..1953432 100644 --- a/lecture/mm/heavyoil/sagdcyclic/sagd_cyclic.input +++ b/lecture/mm/heavyoil/sagdcyclic/sagd_cyclic.input @@ -1,4 +1,4 @@ -[TimeManager] +[TimeLoop] DtInitial = 900 # [s] TEnd = 31467600 # [s] a year MaxTimeStepSize = 1800 # [s] diff --git a/lecture/mm/heavyoil/sagdcyclic/spatialparams.hh b/lecture/mm/heavyoil/sagdcyclic/spatialparams.hh index f87e3b5..3466aeb 100644 --- a/lecture/mm/heavyoil/sagdcyclic/spatialparams.hh +++ b/lecture/mm/heavyoil/sagdcyclic/spatialparams.hh @@ -50,9 +50,9 @@ SET_TYPE_PROP(SagdCyclicSpatialParams, SpatialParams, Dumux::SagdCyclicSpatialPa SET_PROP(SagdCyclicSpatialParams, MaterialLaw) { private: - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); public: - typedef ParkerVanGenZero3P type; + using type = ParkerVanGenZero3P; }; } @@ -62,61 +62,60 @@ public: * \brief Definition of the spatial parameters for the SAGD problem */ template -class SagdCyclicSpatialParams : public ImplicitSpatialParams +class SagdCyclicSpatialParams : public FVSpatialParams > { - typedef ImplicitSpatialParams ParentType; -typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, Grid) Grid; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename Grid::ctype CoordScalar; - enum { - dim=GridView::dimension, - dimWorld=GridView::dimensionworld - }; + using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using ParentType = FVSpatialParams > ; + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); + using Grid = typename GET_PROP_TYPE(TypeTag, Grid); + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using CoordScalar = typename Grid::ctype; - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum { + static constexpr int dim = GridView::dimension; + static constexpr int dimWorld=GridView::dimensionworld; - numPhases = GET_PROP_VALUE(TypeTag, NumPhases), - numComponents = GET_PROP_VALUE(TypeTag, NumComponents), + using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; - wPhaseIdx = Indices::wPhaseIdx, - nPhaseIdx = Indices::nPhaseIdx, - gPhaseIdx = Indices::gPhaseIdx - }; + static constexpr int numPhases = GET_PROP_VALUE(TypeTag, NumPhases); + static constexpr int numComponents = GET_PROP_VALUE(TypeTag, NumComponents); + + static constexpr int wPhaseIdx = Indices::Phase0Idx; + static constexpr int nPhaseIdx = Indices::Phase1Idx; + static constexpr int gPhaseIdx = Indices::Phase2Idx; + + using Element = typename GridView::template Codim<0>::Entity; + using GlobalPosition = typename Element::Geometry::GlobalCoordiante; + using DimVetor = Dune::FieldVector; - typedef Dune::FieldVector GlobalPosition; - typedef Dune::FieldVector DimVector; + using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector); - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector; + using FluxVariables = typename GET_PROP_TYPE(TypeTag, FluxVariables); + using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables); - typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GridView::template Codim<0>::Iterator ElementIterator; - typedef typename GridView::template Codim::Iterator VertexIterator; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; + using ElementIterator = typename GridView::template Codim<0>::Iterator; + using VertexIterator = typename GridView::template Codim::Iterator; + using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables); enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) }; enum { dofCodim = isBox ? dim : 0 }; public: - typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw; - typedef typename MaterialLaw::Params MaterialLawParams; + using MaterialLaw = typename SpatialParams::MaterialLaw; + using MaterialLawParams = typename MaterialLaw::Params; /*! * \brief The constructor * * \param gridView The grid view */ - SagdCyclicSpatialParams(const GridView &gridView) : ParentType(gridView) + SagdCyclicSpatialParams(std::shared_ptr fvGridGeometry) : ParentType(fvGridGeometry) { land_ = 5.0; layerBottom_ = 35.0; @@ -285,7 +284,7 @@ public: void getMaxSaturation(Problem &problem) { - typedef Dune::BlockVector > ScalarField; + using ScalarField = typedef Dune::BlockVector >; // get the number of degrees of freedom FVElementGeometry fvGeometry; diff --git a/lecture/mm/heavyoil/sagdcyclichyst/problem.hh b/lecture/mm/heavyoil/sagdcyclichyst/problem.hh index 750d6ed..e3611a5 100644 --- a/lecture/mm/heavyoil/sagdcyclichyst/problem.hh +++ b/lecture/mm/heavyoil/sagdcyclichyst/problem.hh @@ -81,67 +81,64 @@ SET_BOOL_PROP(SagdCyclicHystProblem, UseMoles, true); * * */ template -class SagdCyclicHystProblem : public ImplicitPorousMediaProblem +class SagdCyclicHystProblem : public PorousMediumFlowProblem { - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::Grid Grid; + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar) + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using Grid = typename GridView::Grid; - typedef ImplicitPorousMediaProblem ParentType; + typedef PorousMediumFlowProblem ParentType; // copy some indices for convenience - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum { + using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; - numPhases = GET_PROP_VALUE(TypeTag, NumPhases), - numComponents = GET_PROP_VALUE(TypeTag, NumComponents), + static constexpr int numPhases = GET_PROP_VALUE(TypeTag, NumPhases); + static constexpr int numComponents = GET_PROP_VALUE(TypeTag, NumComponents); - pressureIdx = Indices::pressureIdx, - switch1Idx = Indices::switch1Idx, - switch2Idx = Indices::switch2Idx, + static constexpr int pressureIdx = Indices::pressureIdx; + static constexpr int switch1Idx = Indices::switch1Idx; + static constexpr int switch2Idx = Indices::switch2Idx; - energyEqIdx = Indices::energyEqIdx, + static constexpr int energyEqIdx = Indices::energyEqIdx; - // phase and component indices - wPhaseIdx = Indices::wPhaseIdx, - nPhaseIdx = Indices::nPhaseIdx, - gPhaseIdx = Indices::gPhaseIdx, - wCompIdx = Indices::wCompIdx, - nCompIdx = Indices::nCompIdx, + // phase and component indices + static constexpr int wPhaseIdx = Indices::Phase0Idx; + static constexpr int nPhaseIdx = Indices::Phase1Idx; + static constexpr int gPhaseIdx = Indices::Phase2Idx; + static constexpr int wCompIdx = Indices::Comp0Idx; + static constexpr int nCompIdx = Indices::Comp1Idx; - // Phase State - wPhaseOnly = Indices::wPhaseOnly, - wnPhaseOnly = Indices::wnPhaseOnly, - wgPhaseOnly = Indices::wgPhaseOnly, - threePhases = Indices::threePhases, + // Phase State + static constexpr int wPhaseOnly = Indices::wPhaseOnly; + static constexpr int wnPhaseOnly = Indices::wnPhaseOnly; + static constexpr int wgPhaseOnly = Indices::wgPhaseOnly; + static constexpr int threePhases = Indices::threePhases; - //contiWEqIdx = Indices::contiWEqIdx, - //contiNEqIdx = Indices::contiNEqIdx, - // Grid and world dimension - dim = GridView::dimension, - dimWorld = GridView::dimensionworld - }; + //contiWEqIdx = Indices::contiWEqIdx, + //contiNEqIdx = Indices::contiNEqIdx, + // Grid and world dimension + static constexpr int dim = GridView::dimension; + static constexpr int dimWorld = GridView::dimensionworld; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; + using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); + using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables); - typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes; - typedef typename GET_PROP_TYPE(TypeTag, TimeManager) TimeManager; + using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GridView::template Codim::Entity Vertex; - typedef typename GridView::Intersection Intersection; + using Element = typename GridView::template Codim<0>::Entity; + using Vertex = typename GridView::template Codim::Entity; + using Intersection = typename GridView::Intersection; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); + using FluidSystem = typedef typename GET_PROP_TYPE(TypeTag, FluidSystem); + using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables); - typedef typename GridView::template Codim<0>::Iterator ElementIterator; - typedef typename GridView::template Codim::Iterator VertexIterator; + using ElementIterator = typename GridView::template Codim<0>::Iterator; + using VertexIterator = typename GridView::template Codim::Iterator; - typedef Dune::FieldVector GlobalPosition; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) }; enum { dofCodim = isBox ? dim : 0 }; @@ -150,11 +147,11 @@ public: /*! * \brief The constructor * - * \param timeManager The time manager + * \param timeLoop The time manager * \param gridView The grid view */ - SagdCyclicHystProblem(TimeManager &timeManager, const GridView &gridView) - : ParentType(timeManager, gridView), eps_(1e-6), pOut_(4.0e6) + SagdCyclicHystProblem(Tstd::shared_ptr fvGridGeometry) + : ParentType(fvGridGeometry), pOut_(4.0e6) { name_ = GET_RUNTIME_PARAM(TypeTag, std::string, Problem.Name); maxDepth_ = 400.0; // [m] @@ -162,7 +159,7 @@ public: totalMassProducedOil_ =0; totalMassProducedWater_ =0; - this->timeManager().startNextEpisode(3600*12.); + this->timeLoop().startNextEpisode(3600*12.); //stateing in the console whether mole or mass fractions are used @@ -175,25 +172,25 @@ public: bool shouldWriteRestartFile() const { return - this->timeManager().timeStepIndex() == 0 || - this->timeManager().timeStepIndex() % 10000 == 0 || - this->timeManager().episodeWillBeFinished() || - this->timeManager().willBeFinished(); + this->timeLoop().timeStepIndex() == 0 || + this->timeLoop().timeStepIndex() % 10000 == 0 || + this->timeLoop().episodeWillBeFinished() || + this->timeLoop().willBeFinished(); } bool shouldWriteOutput() const { return - this->timeManager().timeStepIndex() == 0 || - this->timeManager().timeStepIndex() % 10000 == 0 || - this->timeManager().episodeWillBeFinished() || - this->timeManager().willBeFinished(); + this->timeLoop().timeStepIndex() == 0 || + this->timeLoop().timeStepIndex() % 10000 == 0 || + this->timeLoop().episodeWillBeFinished() || + this->timeLoop().willBeFinished(); } void postTimeStep() { - const Scalar time = this->timeManager().time(); - const Scalar dt = this->timeManager().timeStepSize(); + const Scalar time = this->timeLoop().time(); + const Scalar dt = this->timeLoop().timeStepSize(); // Calculate storage terms PrimaryVariables storage; @@ -222,11 +219,11 @@ public: totalMassProducedWater_ += newMassProducedWater_; - const int timeStepIndex = this->timeManager().timeStepIndex(); + const int timeStepIndex = this->timeLoop().timeStepIndex(); if (timeStepIndex == 0 || timeStepIndex % 100 == 0 || //after every 1000000 secs - this->timeManager().episodeWillBeFinished() || - this->timeManager().willBeFinished()) + this->timeLoop().episodeWillBeFinished() || + this->timeLoop().willBeFinished()) { std::cout<<" totalMassProducedOil_ : "<< totalMassProducedOil_ << " Time: " << time+dt << std::endl; @@ -239,8 +236,8 @@ public: void episodeEnd() { - int indexEpisode = this->timeManager().episodeIndex(); - this->timeManager().startNextEpisode(3600*12); //episode length sent to 12 hours + int indexEpisode = this->timeLoop().episodeIndex(); + this->timeLoop().startNextEpisode(3600*12); //episode length sent to 12 hours std::cout<<"Episode index is set to: "<timeManager().episodeIndex(); + const int indexEpisode = this->timeLoop().episodeIndex(); GlobalPosition globalPos; @@ -481,7 +478,7 @@ private: } Scalar maxDepth_; - Scalar eps_; + static constexpr Scalar eps_ = 1e-6 Scalar pIn_; Scalar pOut_; //int vectorSize; diff --git a/lecture/mm/heavyoil/sagdcyclichyst/sagd_cyclic_hyst.cc b/lecture/mm/heavyoil/sagdcyclichyst/sagd_cyclic_hyst.cc index 9386aef..1f60ad1 100644 --- a/lecture/mm/heavyoil/sagdcyclichyst/sagd_cyclic_hyst.cc +++ b/lecture/mm/heavyoil/sagdcyclichyst/sagd_cyclic_hyst.cc @@ -52,9 +52,158 @@ void usage(const char *progName, const std::string &errorMsg) } } -int main(int argc, char** argv) +//////////////////////// +// the main function +//////////////////////// +int main(int argc, char** argv) try { - typedef TTAG(SagdCyclicHystBoxProblem) ProblemTypeTag; - //typedef TTAG(SagdCCProblem) ProblemTypeTag; - return Dumux::start(argc, argv, usage); + // typedef TTAG(LensOnePTwoCProblem) TypeTag; + // return Dumux::start(argc, argv, usage); + using namespace Dumux; + + // define the type tag for this problem + using TypeTag = TTAG(SagdCyclicHystBoxProblem); + + // 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(leafGridView); + fvGridGeometry->update(); + + // the problem (initial and boundary conditions) + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); + auto problem = std::make_shared(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(problem, fvGridGeometry); + gridVariables->init(x, xOld); + + // get some time loop parameters + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + const auto tEnd = getParam("TimeLoop.TEnd"); + const auto maxDt = getParam("TimeLoop.MaxTimeStepSize"); + auto dt = getParam("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")) // Fehlt ebenso + restartTime = getParam("TimeLoop.Restart"); + + // intialize the vtk output module + using VtkOutputFields = typename GET_PROP_TYPE(TypeTag, VtkOutputFields); + VtkOutputModule 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>(restartTime, dt, tEnd); + timeLoop->setMaxTimeStepSize(maxDt); + + // the assembler with time loop for instationary problem + using Assembler = FVAssembler; + auto assembler = std::make_shared(problem, fvGridGeometry, gridVariables, timeLoop); + + // the linear solver + using LinearSolver = AMGBackend; + auto linearSolver = std::make_shared(leafGridView, fvGridGeometry->dofMapper()); + + // the non-linear solver + using NewtonSolver = Dumux::NewtonSolver; + NewtonSolver nonLinearSolver(assembler, linearSolver); + + // time loop + timeLoop->start(); do + { + // set previous solution for storage evaluations + assembler->setPreviousSolution(xOld); + + // solve the non-linear system with time step control + nonLinearSolver.solve(x, *timeLoop); + + // 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 the Newton solver + timeLoop->setTimeStepSize(nonLinearSolver.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); + } + + + +} + +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; } diff --git a/lecture/mm/heavyoil/sagdcyclichyst/sagd_cyclic_hyst.input b/lecture/mm/heavyoil/sagdcyclichyst/sagd_cyclic_hyst.input index 465d219..bffc9b7 100644 --- a/lecture/mm/heavyoil/sagdcyclichyst/sagd_cyclic_hyst.input +++ b/lecture/mm/heavyoil/sagdcyclichyst/sagd_cyclic_hyst.input @@ -1,4 +1,4 @@ -[TimeManager] +[TimeLoop] DtInitial = 100 # [s] TEnd = 31467600 # [s] a year MaxTimeStepSize = 1800 # [s] diff --git a/lecture/mm/heavyoil/sagdcyclichyst/spatialparams.hh b/lecture/mm/heavyoil/sagdcyclichyst/spatialparams.hh index 8bac29b..8e748f9 100644 --- a/lecture/mm/heavyoil/sagdcyclichyst/spatialparams.hh +++ b/lecture/mm/heavyoil/sagdcyclichyst/spatialparams.hh @@ -56,63 +56,61 @@ SET_PROP(SagdCyclicHystSpatialParams, MaterialLaw) * \brief Definition of the spatial parameters for the SAGD problem */ template -class SagdCyclicHystSpatialParams : public ImplicitSpatialParams +class SagdCyclicHystSpatialParams : public FVSpatialParams > { - typedef ImplicitSpatialParams ParentType; - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; - typedef typename GET_PROP_TYPE(TypeTag, Grid) Grid; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename Grid::ctype CoordScalar; + using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using ParentType = FVSpatialParams > - enum { - dim=GridView::dimension, - dimWorld=GridView::dimensionworld - }; + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); + using Grid = typename GET_PROP_TYPE(TypeTag, Grid); + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using CoordScalar = typename Grid::ctype; - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum { + static constexpr int dim = GridView::dimension; + static constexpr int dimWorld=GridView::dimensionworld; - numPhases = GET_PROP_VALUE(TypeTag, NumPhases), - numComponents = GET_PROP_VALUE(TypeTag, NumComponents), + using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; - wPhaseIdx = Indices::wPhaseIdx, - nPhaseIdx = Indices::nPhaseIdx, - gPhaseIdx = Indices::gPhaseIdx - }; + static constexpr int numPhases = GET_PROP_VALUE(TypeTag, NumPhases); + static constexpr int numComponents = GET_PROP_VALUE(TypeTag, NumComponents); + + static constexpr int wPhaseIdx = Indices::Phase0Idx; + static constexpr int nPhaseIdx = Indices::Phase1Idx; + static constexpr int gPhaseIdx = Indices::Phase2Idx; + + using Element = typename GridView::template Codim<0>::Entity; + using GlobalPosition = typename Element::Geometry::GlobalCoordiante; + using DimVetor = Dune::FieldVector; - typedef Dune::FieldVector GlobalPosition; - typedef Dune::FieldVector DimVector; - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector; + using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector); - typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; + using FluxVariables = typename GET_PROP_TYPE(TypeTag, FluxVariables); + using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables); - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GridView::template Codim<0>::Entity Element; + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); - typedef typename GridView::template Codim<0>::Iterator ElementIterator; - typedef typename GridView::template Codim::Iterator VertexIterator; - typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; + using ElementIterator = typename GridView::template Codim<0>::Iterator; + using VertexIterator = typename GridView::template Codim::Iterator; + using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables); enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) }; enum { dofCodim = isBox ? dim : 0 }; public: - typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw; - typedef typename MaterialLaw::Params MaterialLawParams; - typedef std::vector MaterialLawHystParamsVector; + using MaterialLaw = typename SpatialParams::MaterialLaw; + using MaterialLawParams = typename MaterialLaw::Params; + using MaterialLawHystParamsVector = std::vector; /*! * \brief The constructor * * \param gridView The grid view */ - SagdCyclicHystSpatialParams(const GridView &gridView) - : ParentType(gridView) + SagdCyclicHystSpatialParams(std::shared_ptr fvGridGeometry) : ParentType(fvGridGeometry) { layerBottom_ = 35.0; // intrinsic permeabilities diff --git a/lecture/mm/henryproblem/henry1p2c/henry1p2c.cc b/lecture/mm/henryproblem/henry1p2c/henry1p2c.cc index 147c10d..fcbc05b 100644 --- a/lecture/mm/henryproblem/henry1p2c/henry1p2c.cc +++ b/lecture/mm/henryproblem/henry1p2c/henry1p2c.cc @@ -51,9 +51,173 @@ void usage(const char *progName, const std::string &errorMsg) } } -int main(int argc, char** argv) +//////////////////////// +// the main function +//////////////////////// +int main(int argc, char** argv) try { - typedef TTAG(Henry1p2cProblem) TypeTag; - return Dumux::start(argc, argv, usage); + using namespace Dumux; + // define the type tag for this problem + using TypeTag = TTAG(Henry1p2cProblem); + + // 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(leafGridView); + fvGridGeometry->update(); + + // the problem (initial and boundary conditions) + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); + auto problem = std::make_shared(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(problem, fvGridGeometry); + gridVariables->init(x, xOld); + + // get some time loop parameters + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + const auto tEnd = getParam("TimeLoop.TEnd"); + const auto maxDivisions = getParam("TimeLoop.MaxTimeStepDivisions"); // Q: What is this? Do we need this here? + const auto maxDt = getParam("TimeLoop.MaxTimeStepSize"); + auto dt = getParam("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")) // Fehlt ebenso + restartTime = getParam("TimeLoop.Restart"); + + // intialize the vtk output module + using VtkOutputFields = typename GET_PROP_TYPE(TypeTag, VtkOutputFields); + VtkOutputModule 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>(restartTime, dt, tEnd); + timeLoop->setMaxTimeStepSize(maxDt); + + // the assembler with time loop for instationary problem + using Assembler = FVAssembler; + auto assembler = std::make_shared(problem, fvGridGeometry, gridVariables, timeLoop); + + // the linear solver + using LinearSolver = AMGBackend; + auto linearSolver = std::make_shared(leafGridView, fvGridGeometry->dofMapper()); + + // the non-linear solver + using NewtonSolver = Dumux::NewtonSolver; + NewtonSolver nonLinearSolver(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 the Newton solver + timeLoop->setTimeStepSize(nonLinearSolver.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); + } + + + +} + +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; } diff --git a/lecture/mm/henryproblem/henry1p2c/henry1p2c.input b/lecture/mm/henryproblem/henry1p2c/henry1p2c.input index 0ace057..fb8024c 100644 --- a/lecture/mm/henryproblem/henry1p2c/henry1p2c.input +++ b/lecture/mm/henryproblem/henry1p2c/henry1p2c.input @@ -8,4 +8,3 @@ Problem.diffusionCoefficient = 6.6e-6 # 1.2e-9 #[m2/s] Diffusion coefficient SpatialParams.dispersivityL=0.1 # longitual dispersivity SpatialParams.dispersivityT=0.01 # transversial dispersivity - diff --git a/lecture/mm/henryproblem/henry1p2c/henry1p2cproblem.hh b/lecture/mm/henryproblem/henry1p2c/henry1p2cproblem.hh index 0cc2f99..893e8cb 100644 --- a/lecture/mm/henryproblem/henry1p2c/henry1p2cproblem.hh +++ b/lecture/mm/henryproblem/henry1p2c/henry1p2cproblem.hh @@ -24,8 +24,8 @@ #ifndef DUMUX_HENRY1P2C_PROBLEM_HH #define DUMUX_HENRY1P2C_PROBLEM_HH -#include -#include +#include +#include #include "watersaltfluidsystem.hh" #include "henry1p2cspatialparameters.hh" @@ -38,7 +38,7 @@ class Henry1p2cProblem; namespace Properties { -NEW_TYPE_TAG(Henry1p2cProblem, INHERITS_FROM(BoxOnePTwoC)); +NEW_TYPE_TAG(Henry1p2cProblem, INHERITS_FROM(TwoP, BoxModel)); // Set the grid type SET_TYPE_PROP(Henry1p2cProblem, Grid, Dune::YaspGrid<2>); @@ -60,53 +60,50 @@ SET_BOOL_PROP(Henry1p2cProblem, ProblemEnableGravity, true); template -class Henry1p2cProblem : public ImplicitPorousMediaProblem +class Henry1p2cProblem : public PorousMediumFlowProblem { - typedef ImplicitPorousMediaProblem ParentType; - - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes; - typedef typename GET_PROP_TYPE(TypeTag, TimeManager) TimeManager; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - + using ParentType = PorousMediumFlowProblem; + + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); + using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); + using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); + using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); + using Element = typename GridView::template Codim<0>::Entity; + using ElementIterator = typename GridView::template Codim<0>::Iterator; // copy some indices for convenience - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum { - // Grid and world dimension - dim = GridView::dimension, - dimWorld = GridView::dimensionworld, + using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; - // indices of the primary variables - pressureIdx = Indices::pressureIdx, - massOrMoleFracIdx = Indices::massOrMoleFracIdx, + // Grid and world dimension + static constexpr int dim = GridView::dimension; + static constexpr int dimWorld = GridView::dimensionworld; - // indices of the equations - conti0EqIdx = Indices::conti0EqIdx, - transportEqIdx = Indices::transportEqIdx - }; + // indices of the primary variables + static constexpr int pressureIdx = Indices::pressureIdx; + static constexpr int massOrMoleFracIdx = Indices::massOrMoleFracIdx; + // indices of the equations + static constexpr int conti0EqIdx = Indices::conti0EqIdx; + static constexpr int transportEqIdx = Indices::transportEqIdx; - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GridView::template Codim<0>::Iterator ElementIterator; - typedef typename GridView::template Codim::Entity Vertex; - typedef typename GridView::Intersection Intersection; + using GlobalPosition = Element::Geometry::GlobalCoordinate; - typedef Dune::FieldVector GlobalPosition; + + // TODO: Are vertex and Intersection now in another class included? + using Vertex = typename GridView::template Codim::Entity; + using Intersection = typename GridView::Intersection; public: - Henry1p2cProblem(TimeManager &timeManager, - const GridView &gridView) - : ParentType(timeManager, gridView) + Henry1p2cProblem(std::shared_ptr fvGridGeometry) + : ParentType(fvGridGeometry) { // FVElementGeometry fvGeom; // ElementIterator elemIt = gridView.template begin<0>(); // const ElementIterator endIt = gridView.template end<0>(); - freshWaterFluxRate_= GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.freshWaterFluxRate); + freshWaterFluxRate_= getParam("Problem.freshWaterFluxRate"); } @@ -115,17 +112,6 @@ public: return false; } -// bool shouldWriteOutput() const -// { -// return -// this->timeManager().timeStepIndex() == 0 || -// this->timeManager().timeStepIndex() %5 ==0 || -// this->timeManager().willBeFinished(); -// } - - - - /*! * \name Problem parameters */ @@ -158,8 +144,10 @@ public: * \brief Specifies which kind of boundary condition should be * used for which equation on a given boundary segment. */ - void boundaryTypes(BoundaryTypes &values, const Vertex &vertex) const + BoundaryTypes boundaryTypes(const Vertex &vertex) const { + BoundaryTypes values; + const GlobalPosition globalPos = vertex.geometry().center(); values.setAllDirichlet(); @@ -169,6 +157,7 @@ public: values.setAllNeumann(); } + return values; } /*! @@ -177,8 +166,10 @@ public: * * For this method, the \a values parameter stores primary variables. */ - void dirichlet(PrimaryVariables &values, const Vertex &vertex) const + PrimaryVariables dirichlet( const Vertex &vertex) const { + PrimaryVariables values; + const GlobalPosition globalPos = vertex.geometry().center(); initial_(values, globalPos); @@ -187,6 +178,7 @@ public: values[massOrMoleFracIdx] = 0.03922; } + return values; } /*! @@ -197,21 +189,23 @@ public: * in normal direction of each component. Negative values mean * influx. */ - void neumann(PrimaryVariables &values, - const Element &element, + PrimaryVariables neumann(const Element &element, const FVElementGeometry &fvElemGeom, const Intersection &is, int scvIdx, int boundaryFaceIdx) const { + PrimaryVariables values; + const GlobalPosition &globalPos = element.geometry().corner(scvIdx); values = 0; if(globalPos[0] +#include #include #include #include @@ -41,28 +41,20 @@ namespace Dumux * Henry problem */ template -class Henry1p2cSpatialParams : public ImplicitSpatialParamsOneP +class Henry1p2cSpatialParams : public PorousMediumFlowProblem { - typedef ImplicitSpatialParamsOneP ParentType; - typedef typename GET_PROP_TYPE(TypeTag, Grid) Grid; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename Grid::ctype CoordScalar; - typedef Dune::FieldVector Vector; - enum { - dim=GridView::dimension, - dimWorld=GridView::dimensionworld - }; - - typedef Dune::FieldVector GlobalPosition; - - - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector; - - - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GridView::template Codim<0>::Entity Element; - + using ParentType = PorousMediumFlowProblem; + using Grid = typename GET_PROP_TYPE(TypeTag, Grid); + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using CoordScalar = typename Grid::ctype; + using Vector = Dune::FieldVector; + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); + using Element = typename GridView::template Codim<0>::Entity; + static constexpr int dim=GridView::dimension; + static constexpr int dimWorld=GridView::dimensionworld; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector); public: Henry1p2cSpatialParams(const GridView &gv) @@ -73,8 +65,8 @@ public: porosity_ = 0.35; - dispersivity_[0]= GET_RUNTIME_PARAM(TypeTag, Scalar, SpatialParams.dispersivityL); - dispersivity_[1]= GET_RUNTIME_PARAM(TypeTag, Scalar, SpatialParams.dispersivityT); + dispersivity_[0]= getParam("SpatialParams.dispersivityL"); + dispersivity_[1]= getParam("SpatialParams.dispersivityT"); } diff --git a/lecture/mm/henryproblem/henry1p2c/watersaltfluidsystem.hh b/lecture/mm/henryproblem/henry1p2c/watersaltfluidsystem.hh index b922ba9..b604693 100644 --- a/lecture/mm/henryproblem/henry1p2c/watersaltfluidsystem.hh +++ b/lecture/mm/henryproblem/henry1p2c/watersaltfluidsystem.hh @@ -28,13 +28,16 @@ #include +#include + + #include #include #include -#ifdef DUMUX_PROPERTIES_HH -#include -#endif +// #ifdef DUMUX_PROPERTIES_HH +// #include +// #endif namespace Dumux { @@ -56,10 +59,10 @@ template class WaterSalt : public BaseFluidSystem > { - typedef WaterSalt ThisType; - typedef BaseFluidSystem Base; - typedef Dumux::H2O H2O_IAPWS; - typedef H2O_IAPWS H2O; + using ThisType = Dumux::Components::WaterSalt; + using Base = BaseFluidSystem; + using H2O_IAPWS = Dumux::Components::H2O; + using H2O_IAPWS = Dumux::Components::H2O; public: /**************************************** diff --git a/lecture/mm/henryproblem/henry2p/henry2p.cc b/lecture/mm/henryproblem/henry2p/henry2p.cc index cdf7c53..b47667b 100644 --- a/lecture/mm/henryproblem/henry2p/henry2p.cc +++ b/lecture/mm/henryproblem/henry2p/henry2p.cc @@ -59,8 +59,171 @@ void usage(const char *progName, const std::string &errorMsg) //////////////////////// // the main function //////////////////////// -int main(int argc, char** argv) +int main(int argc, char** argv) try { - typedef TTAG(Henry2pProblem) TypeTag; - return Dumux::start(argc, argv, usage); + + using namespace Dumux; + + // define the type tag for this problem + using TypeTag = TTAG(Henry2pProblem); + + // 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(leafGridView); + fvGridGeometry->update(); + + // the problem (initial and boundary conditions) + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); + auto problem = std::make_shared(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(problem, fvGridGeometry); + gridVariables->init(x, xOld); + + // get some time loop parameters + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + const auto tEnd = getParam("TimeLoop.TEnd"); + const auto maxDivisions = getParam("TimeLoop.MaxTimeStepDivisions"); // Q: What is this? Do we need this here? + const auto maxDt = getParam("TimeLoop.MaxTimeStepSize"); + auto dt = getParam("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")) // Fehlt ebenso + restartTime = getParam("TimeLoop.Restart"); + + // intialize the vtk output module + using VtkOutputFields = typename GET_PROP_TYPE(TypeTag, VtkOutputFields); + VtkOutputModule 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>(restartTime, dt, tEnd); + timeLoop->setMaxTimeStepSize(maxDt); + + // the assembler with time loop for instationary problem + using Assembler = FVAssembler; + auto assembler = std::make_shared(problem, fvGridGeometry, gridVariables, timeLoop); + + // the linear solver + using LinearSolver = AMGBackend; + auto linearSolver = std::make_shared(leafGridView, fvGridGeometry->dofMapper()); + + // the non-linear solver + using NewtonSolver = Dumux::NewtonSolver; + NewtonSolver nonLinearSolver(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 the Newton solver + timeLoop->setTimeStepSize(nonLinearSolver.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); + } + + + +} + +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; } diff --git a/lecture/mm/henryproblem/henry2p/henry2p.input b/lecture/mm/henryproblem/henry2p/henry2p.input index 69e2350..da357c4 100644 --- a/lecture/mm/henryproblem/henry2p/henry2p.input +++ b/lecture/mm/henryproblem/henry2p/henry2p.input @@ -1,6 +1,6 @@ -[TimeManager] +[TimeLoop] DtInitial = 2.5 # [s] TEnd =1e12 # [s] #MaxTimeStepSize = 1e9 diff --git a/lecture/mm/henryproblem/henry2p/henry2pproblem.hh b/lecture/mm/henryproblem/henry2p/henry2pproblem.hh index b3ed961..a15de78 100644 --- a/lecture/mm/henryproblem/henry2p/henry2pproblem.hh +++ b/lecture/mm/henryproblem/henry2p/henry2pproblem.hh @@ -29,8 +29,8 @@ #include #include "simplesaltwater.hh" -#include -#include +#include +#include #include @@ -61,79 +61,68 @@ SET_TYPE_PROP(Henry2pProblem, Problem, Henry2pProblem); SET_PROP(Henry2pProblem, WettingPhase) { private: - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); public: - typedef Dumux::FluidSystems::LiquidPhase > type; + using type = Dumux::FluidSystems::LiquidPhase >; }; // Set the non-wetting phase SET_PROP(Henry2pProblem, NonwettingPhase) { private: - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); public: - typedef FluidSystems::LiquidPhase > type; + using type = FluidSystems::LiquidPhase >; }; #else // OR: set the fluid system SET_TYPE_PROP(Henry2pProblem, FluidSystem, H2ON2FluidSystem); #endif - -// Enable partial reassembly of the jacobian matrix? -SET_BOOL_PROP(Henry2pProblem, ImplicitEnablePartialReassemble, true); - -// Enable reuse of jacobian matrices? -SET_BOOL_PROP(Henry2pProblem, ImplicitEnableJacobianRecycling, true); - // Write the solutions of individual newton iterations? -SET_BOOL_PROP(Henry2pProblem, NewtonWriteConvergence, false); +// SET_BOOL_PROP(Henry2pProblem, NewtonWriteConvergence, false); // Use forward differences instead of central differences SET_INT_PROP(Henry2pProblem, ImplicitNumericDifferenceMethod, +1); SET_SCALAR_PROP(Henry2pProblem, ImplicitMassUpwindWeight, 0.5); -// Enable gravity -SET_BOOL_PROP(Henry2pProblem, ProblemEnableGravity, true); } template -class Henry2pProblem : public ImplicitPorousMediaProblem +class Henry2pProblem : public PorousMediumFlowProblem { - typedef ImplicitPorousMediaProblem ParentType; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; + using ParentType = PorousMediumFlowProblem; + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; + using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, WettingPhase) WettingPhase; - typedef typename GET_PROP_TYPE(TypeTag, NonwettingPhase) NonwettingPhase; + using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); + using WettingPhase = typename GET_PROP_TYPE(TypeTag, WettingPhase); + using NonwettingPhase = typename GET_PROP_TYPE(TypeTag, NonwettingPhase); - enum { + // primary variable indices + static constexpr int pressureIdx = Indices::pressureIdx; + static constexpr int snIdx = Indices::snIdx; - // primary variable indices - pressureIdx = Indices::pressureIdx, - snIdx = Indices::snIdx, + // equation indices + static constexpr int contiNEqIdx = Indices::contiNEqIdx; + static constexpr int contiWEqIdx = Indices::contiWEqIdx; - // equation indices - contiNEqIdx = Indices::contiNEqIdx, - contiWEqIdx = Indices::contiWEqIdx, - // phase indices - wPhaseIdx = Indices::wPhaseIdx, - nPhaseIdx = Indices::nPhaseIdx, + // phase indices + static constexpr int wPhaseIdx = Indices::wPhaseIdx; + static constexpr int nPhaseIdx = Indices::nPhaseIdx; + // Grid and world dimension + static constexpr int dim = GridView::dimension; + static constexpr int dimWorld = GridView::dimensionworld; - // Grid and world dimension - dim = GridView::dimension, - dimWorld = GridView::dimensionworld - }; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes; - typedef typename GET_PROP_TYPE(TypeTag, TimeManager) TimeManager; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef Dune::FieldVector GlobalPosition; + using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); + using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); + + typedef Dune::FieldVector GlobalPosition; // TODO: New Version for this? public: /*! @@ -142,34 +131,17 @@ public: * \param timeManager The time manager * \param gridView The grid view */ - Henry2pProblem(TimeManager &timeManager, - const GridView &gridView) - : ParentType(timeManager, gridView) + Henry2pProblem(std::shared_ptr fvGridGeometry + : ParentType(fvgridGeometry) { eps_ = 3e-6; temperature_ = 273.15 + 20; // -> 20°C - freshWaterFluxRate_= GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.freshWaterFluxRate); - - episodeLength_ = GET_RUNTIME_PARAM(TypeTag, Scalar, TimeManager.EpisodeLength); - this->timeManager().startNextEpisode(episodeLength_); + freshWaterFluxRate_= getParam("Problem.freshWaterFluxRate"); - } + episodeLength_ = getParam("TimeManager.EpisodeLength"); - bool shouldWriteRestartFile() const - { - return false; - } - - -// bool shouldWriteOutput() const -// { -// return -// this->timeManager().timeStepIndex() == 0 || -// this->timeManager().timeStepIndex() %10 ==0 || -// // this->timeManager().time() %31536000 ==0 -// this->timeManager().willBeFinished(); -// } + } /*! * \name Problem parameters @@ -199,18 +171,6 @@ public: } } - bool shouldWriteOutput() const - { - return - this->timeManager().timeStepIndex() == 0 || - this->timeManager().episodeWillBeFinished() || - this->timeManager().willBeFinished(); - } - - void episodeEnd() - { - this->timeManager().startNextEpisode(episodeLength_); - } /*! * \brief Returns the temperature within the domain. @@ -221,10 +181,9 @@ public: { return temperature_; }; - void sourceAtPos(PrimaryVariables &values, - const GlobalPosition &globalPos) const + NumEqVector sourceAtPos( const GlobalPosition &globalPos) const { - values = 0; + return NumEqVector(0.0); } // \} @@ -241,9 +200,10 @@ public: * \param values The boundary types for the conservation equations * \param globalPos The position of the center of the finite volume */ - void boundaryTypesAtPos(BoundaryTypes &values, - const GlobalPosition &globalPos) const + BoundaryTypes boundaryTypesAtPos(const GlobalPosition &globalPos) const { + BoundaryTypes values; + if (globalPos[0]>2-eps_) { values.setAllDirichlet(); @@ -252,6 +212,8 @@ public: { values.setAllNeumann(); } + + return values; } /*! @@ -263,10 +225,11 @@ public: * * For this method, the \a values parameter stores primary variables. */ - void dirichletAtPos(PrimaryVariables &values, - const GlobalPosition &globalPos) const + PrimaryVariables dirichletAtPos(const GlobalPosition &globalPos) const { + PrimaryVariables values; + if (globalPos[0]>2-eps_)// if(onRightBoundary_(globalPos)) { @@ -287,6 +250,8 @@ public: } } + return values; + } /*! @@ -299,13 +264,16 @@ public: * For this method, the \a values parameter stores the mass flux * in normal direction of each phase. Negative values mean influx. */ - void neumannAtPos(PrimaryVariables &values, - const GlobalPosition &globalPos) const + PrimaryVariables neumannAtPos(const GlobalPosition &globalPos) const { + PrimaryVariables values; + values = 0.0; if (onLeftBoundary_(globalPos)) { values[contiWEqIdx] = -freshWaterFluxRate_;//-6.6E-2;// kg / (m * s) } + + return values; } // \} @@ -324,21 +292,24 @@ 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 { - if(globalPos[1]<0.8+eps_) - { - Scalar densityB = 1025; - values[pressureIdx] = 1.0133e5+(depthBOR_-globalPos[1]-0.2)*densityB*9.81+1000*9.81*0.2; - values[snIdx] = 0.0; - } - else { - Scalar densityW = 1000; - values[pressureIdx] = 1.0133e5+(depthBOR_-globalPos[1])*densityW*9.81; - values[snIdx] = 0.0; - } + PrimaryVariables values; + if(globalPos[1]<0.8+eps_) + { + Scalar densityB = 1025; + values[pressureIdx] = 1.0133e5+(depthBOR_-globalPos[1]-0.2)*densityB*9.81+1000*9.81*0.2; + values[snIdx] = 0.0; + } + else + { + Scalar densityW = 1000; + values[pressureIdx] = 1.0133e5+(depthBOR_-globalPos[1])*densityW*9.81; + values[snIdx] = 0.0; + } + + return values; } // \} @@ -347,22 +318,22 @@ private: bool onLeftBoundary_(const GlobalPosition &globalPos) const { - return globalPos[0] < this->bBoxMin()[0] + eps_; + return globalPos[0] < this->fvGridGeometry().bBoxMin()[0] + eps_; } bool onRightBoundary_(const GlobalPosition &globalPos) const { - return globalPos[0] > this->bBoxMax()[0] - eps_; + return globalPos[0] > this->fvGridGeometry().bBoxMax()[0] - eps_; } bool onLowerBoundary_(const GlobalPosition &globalPos) const { - return globalPos[1] < this->bBoxMin()[1] + eps_; + return globalPos[1] < this->fvGridGeometry().bBoxMin()[1] + eps_; } bool onUpperBoundary_(const GlobalPosition &globalPos) const { - return globalPos[1] > this->bBoxMax()[1] - eps_; + return globalPos[1] > this->fvGridGeometry().bBoxMax()[1] - eps_; } static constexpr Scalar depthBOR_ = 1.0; diff --git a/lecture/mm/henryproblem/henry2p/henry2pspatialparams.hh b/lecture/mm/henryproblem/henry2p/henry2pspatialparams.hh index 5c2238e..396be84 100644 --- a/lecture/mm/henryproblem/henry2p/henry2pspatialparams.hh +++ b/lecture/mm/henryproblem/henry2p/henry2pspatialparams.hh @@ -53,11 +53,11 @@ SET_PROP(Henry2pSpatialParams, MaterialLaw) private: // define the material law which is parameterized by effective // saturations - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef LinearMaterial EffectiveLaw; + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using EffectiveLaw = LinearMaterial; public: // define the material law parameterized by absolute saturations - typedef EffToAbsLaw type; + using type = EffToAbsLaw; }; } /*! @@ -66,29 +66,26 @@ public: * \brief The spatial parameters for the Henry2pProblem which uses the * twophase box model */ -template -class Henry2pSpatialParams : public ImplicitSpatialParams +template +class Henry2pSpatialParams : public FVSpatialParamsTwoP> { - typedef ImplicitSpatialParams ParentType; - typedef typename GET_PROP_TYPE(TypeTag, Grid) Grid; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename Grid::ctype CoordScalar; - - enum { - dim=GridView::dimension, - dimWorld=GridView::dimensionworld - }; - - typedef Dune::FieldVector GlobalPosition; - - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; + using ThisType = Henry2pSpatialParams; + using ParentType = FVSpatialParams; + using Grid = typename GET_PROP_TYPE(TypeTag, Grid); + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using CoordScalar = typename Grid::ctype; + using Element = typename GridView::template Codim<0>::Entity; + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); + static constexpr int dim=GridView::dimension; + static constexpr int dimWorld=GridView::dimensionworld; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; public: + //get the material law from the property system - typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw; - typedef typename MaterialLaw::Params MaterialLawParams; + using MaterialLaw = typename GET_PROP_TYPE(TypeTag, MaterialLaw) + using MaterialLawParams = typename MaterialLaw::Params; Henry2pSpatialParams(const GridView& gridView) : ParentType(gridView) diff --git a/lecture/mm/henryproblem/henry2p/simplesaltwater.hh b/lecture/mm/henryproblem/henry2p/simplesaltwater.hh index 0b7c2b6..07b5e7d 100644 --- a/lecture/mm/henryproblem/henry2p/simplesaltwater.hh +++ b/lecture/mm/henryproblem/henry2p/simplesaltwater.hh @@ -27,7 +27,7 @@ #include -#include +#include #include @@ -178,7 +178,8 @@ public: Scalar pressure) { return liquidEnthalpy(temperature, pressure) - - pressure/liquidDensity(temperature, pressure); } + pressure/liquidDensity(temperature, pressure); + } /*! * \brief Returns true iff the gas phase is assumed to be compressible @@ -229,9 +230,7 @@ public: * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$ */ static Scalar liquidDensity(Scalar temperature, Scalar pressure) - { - return 1025.; - } + { return 1025.; } /*! * \brief The pressure of water in \f$\mathrm{[Pa]}\f$ at a given density and temperature. @@ -287,4 +286,4 @@ const Scalar SimpleSaltwater::R = Dumux::Constants::R / 18e-3; } // end namepace -#endif +#endif // DUMUX_SIMPLE_SALTWATER_HH diff --git a/lecture/mm/mcwhorter/mcwhorteranalyticsolution.hh b/lecture/mm/mcwhorter/mcwhorteranalyticsolution.hh index e4db69f..ea8f168 100644 --- a/lecture/mm/mcwhorter/mcwhorteranalyticsolution.hh +++ b/lecture/mm/mcwhorter/mcwhorteranalyticsolution.hh @@ -42,14 +42,12 @@ namespace Dumux template class McWhorterAnalytic { - typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); // typedef typename GET_PROP_TYPE(TypeTag, Grid) Grid; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - typedef typename GET_PROP_TYPE(TypeTag, SpatialParams) SpatialParams; - typedef typename SpatialParams::MaterialLaw MaterialLaw; - typedef typename MaterialLaw::Params MaterialLawParams; + using SpatialParams = typename GET_PROP_TYPE(TypeTag, SpatialParams); typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState; @@ -71,14 +69,16 @@ class McWhorterAnalytic // pressEqIdx = Indices::pressEqIdx, // satEqIdx = Indices::satEqIdx }; + using GlobalPosition = Dune::FieldVector; - typedef Dune::BlockVector > BlockVector; - typedef typename GridView::Traits::template Codim<0>::Entity Element; - typedef typename GridView::template Codim<0>::Iterator ElementIterator; - typedef Dune::FieldVector GlobalPosition; + using BlockVector = Dune::BlockVector >; + using Element = typename GridView::Traits::template Codim<0>::Entity; + using ElementIterator = typename GridView::template Codim<0>::Iterator; public: + using MaterialLaw = typename SpatialParams::MaterialLaw; + using MaterialLawParams = typename MaterialLaw::Params; // functions needed for analytical solution void initializeAnalytic() @@ -136,7 +136,7 @@ public: void prepareAnalytic() { - const MaterialLawParams& materialLawParams(problem_.spatialParams().materialLawParams(dummyElement_)); + const MaterialLawParams& materialLawParams( problem_.spatialParams().materialLawParams(dummyElement_) ); swr_ = materialLawParams.swr(); snr_ = materialLawParams.snr(); diff --git a/lecture/mm/mcwhorter/mcwhorterexercise.cc b/lecture/mm/mcwhorter/mcwhorterexercise.cc index 56188f2..fd7a727 100644 --- a/lecture/mm/mcwhorter/mcwhorterexercise.cc +++ b/lecture/mm/mcwhorter/mcwhorterexercise.cc @@ -62,9 +62,173 @@ void usage(const char *progName, const std::string &errorMsg) << "\n"; } } +//////////////////////// +// the main function +//////////////////////// +int main(int argc, char** argv) try +{ + using namespace Dumux; + + // define the type tag for this problem + using TypeTag = TTAG(McWhorterProblem); + + // 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(leafGridView); + fvGridGeometry->update(); + + // the problem (initial and boundary conditions) + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); + auto problem = std::make_shared(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(problem, fvGridGeometry); + gridVariables->init(x, xOld); + + // get some time loop parameters + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + const auto tEnd = getParam("TimeLoop.TEnd"); + const auto maxDivisions = getParam("TimeLoop.MaxTimeStepDivisions"); // Q: What is this? Do we need this here? + const auto maxDt = getParam("TimeLoop.MaxTimeStepSize"); + auto dt = getParam("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")) // Fehlt ebenso + restartTime = getParam("TimeLoop.Restart"); + + // intialize the vtk output module + using VtkOutputFields = typename GET_PROP_TYPE(TypeTag, VtkOutputFields); + VtkOutputModule 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>(restartTime, dt, tEnd); + timeLoop->setMaxTimeStepSize(maxDt); + + // the assembler with time loop for instationary problem + using Assembler = FVAssembler; + auto assembler = std::make_shared(problem, fvGridGeometry, gridVariables, timeLoop); + + // the linear solver + using LinearSolver = AMGBackend; + auto linearSolver = std::make_shared(leafGridView, fvGridGeometry->dofMapper()); + + // the non-linear solver + using NewtonSolver = Dumux::NewtonSolver; + NewtonSolver nonLinearSolver(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; -int main(int argc, char** argv) + 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 the Newton solver + timeLoop->setTimeStepSize(nonLinearSolver.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); + } + + + +} + +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 (...) { - typedef TTAG(McWhorterProblem) TypeTag; - return Dumux::start(argc, argv, usage); + std::cerr << "Unknown exception thrown! ---> Abort!" << std::endl; + return 4; } diff --git a/lecture/mm/mcwhorter/mcwhorterexercise.input b/lecture/mm/mcwhorter/mcwhorterexercise.input index e87b7a5..19743eb 100644 --- a/lecture/mm/mcwhorter/mcwhorterexercise.input +++ b/lecture/mm/mcwhorter/mcwhorterexercise.input @@ -1,4 +1,4 @@ -[TimeManager] +[TimeLoop] TEnd = 5e6 # end time of the simulation [s] DtInitial = 1e3 # initial time step for the simulation [s] diff --git a/lecture/mm/mcwhorter/mcwhorterproblem.hh b/lecture/mm/mcwhorter/mcwhorterproblem.hh index 32d2b97..7de172b 100644 --- a/lecture/mm/mcwhorter/mcwhorterproblem.hh +++ b/lecture/mm/mcwhorter/mcwhorterproblem.hh @@ -82,26 +82,25 @@ SET_SCALAR_PROP(McWhorterProblem, ImpetCFLFactor, 0.8); * \ingroup DecoupledProblems * \brief McWhorter diffusion problem */ -template -class McWhorterProblem: public IMPESProblem2P +template +class McWhorterProblem: public IMPESProblem2P // TODO: Which is now the correct ancestor class? { - typedef IMPESProblem2P ParentType; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; + using ParentType = IMPESProblem2P; + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState; + using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); + using FluidState = typename GET_PROP_TYPE(TypeTag, FluidState); - typedef typename GET_PROP_TYPE(TypeTag, WettingPhase) WettingPhase; - typedef typename GET_PROP_TYPE(TypeTag, NonwettingPhase) NonwettingPhase; + using WettingPhase = typename GET_PROP_TYPE(TypeTag, WettingPhase); + using NonwettingPhase = typename GET_PROP_TYPE(TypeTag, NonwettingPhase); - typedef typename GET_PROP_TYPE(TypeTag, TimeManager) TimeManager; + using CellData = typename GET_PROP_TYPE(TypeTag, CellData); - typedef typename GET_PROP_TYPE(TypeTag, CellData) CellData; + using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); + using PrimaryVariables = typename GET_PROP(TypeTag, SolutionTypes)::PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes; - typedef typename GET_PROP(TypeTag, SolutionTypes)::PrimaryVariables PrimaryVariables; + using Indices = typename GET_PROP_TYPE(TypeTag, Indices); enum { @@ -117,13 +116,12 @@ class McWhorterProblem: public IMPESProblem2P pressEqIdx = Indices::pressureEqIdx, satEqIdx = Indices::satEqIdx }; + using GlobalPosition = Dune::FieldVector; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; + using Element = typename GridView::Traits::template Codim<0>::Entity; + using Intersection = typename GridView::Intersection; - typedef typename GridView::Traits::template Codim<0>::Entity Element; - typedef typename GridView::Intersection Intersection; - typedef Dune::FieldVector GlobalPosition; - typedef typename GET_PROP(TypeTag, ParameterTree) Params; + using Params = typename GET_PROP(TypeTag, ParameterTree); public: /*! @@ -131,24 +129,24 @@ public: * \param timeManager DOC ME! * \param gridView DOC ME! */ - McWhorterProblem(TimeManager& timeManager, const GridView &gridView) - : ParentType(timeManager, gridView), eps_(1e-8), pLeftBc_ ( 1.0e5 ), - analyticSolution_(*this), viplabOutput_(*this) + McWhorterProblem(std::shared_ptr fvGridGeometry) + : ParentType(fvGridGeometry),// TODO: Implement this in a correct way: eps_(1e-8), pLeftBc_ ( 1.0e5 ), analyticSolution_(*this), viplabOutput_(*this) { - this->setOutputInterval(GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, int, Output, Interval)); + this->setOutputInterval( getParam("Output.Interval") ); - WettingPhase::Component::setViscosity(GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Fluid, ViscosityW)); - NonwettingPhase::Component::setViscosity(GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Fluid, ViscosityNW)); + WettingPhase::Component::setViscosity( getParam("Fluid.ViscosityW") ); + NonwettingPhase::Component::setViscosity( getParam("Fluid.ViscosityNW") ); - WettingPhase::Component::setDensity(GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Fluid, DensityW)); - NonwettingPhase::Component::setDensity(GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Fluid, DensityNW)); + WettingPhase::Component::setDensity( getParam("Fluid.DensityW") ); + NonwettingPhase::Component::setDensity( getParam("Fluid.DensityNW") ); - swr_ = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, SpatialParams, ResidualSaturationWetting); - snr_ = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, SpatialParams, ResidualSaturationNonWetting); + swr_ = getParam("SpatialParams.ResidualSaturationWetting"); + snr_ = getParam("SpatialParams.ResidualSaturationNonWetting"); paraviewOutput_ = Params::tree().template get("Output.paraviewOutput", true); } + // TODO: Is this up to date? void init() { ParentType::init(); @@ -166,6 +164,7 @@ public: bool shouldWriteRestartFile() const { return false; } + // TODO: Is this now in the main-function? void postTimeStep() { analyticSolution_.calculateAnalyticSolution(); @@ -193,62 +192,78 @@ public: { return 1.0e5; // -> 1 bar } + /*! * \brief DOC ME! * \param values DOC ME! * \param globalPos DOC ME! */ - void sourceAtPos(PrimaryVariables &values,const GlobalPosition& globalPos) const + NumEqVector sourceAtPos(const GlobalPosition& globalPos) const { - values = 0; + return NumEqVector(0.0); } + /*! * \brief DOC ME! * \param bcTypes DOC ME! * \param globalPos DOC ME! */ - void boundaryTypesAtPos(BoundaryTypes &bcTypes, const GlobalPosition& globalPos) const + BoundaryTypes boundaryTypesAtPos(const GlobalPosition& globalPos) const { + BoundaryTypes bcTypes; + if (globalPos[0] < eps_) //west bcTypes.setAllDirichlet(); // the other boundary (east) else bcTypes.setAllNeumann(); + + return bcTypes; } + /*! * \brief DOC ME! * \param values DOC ME! * \param globalPos DOC ME! */ - void dirichletAtPos(PrimaryVariables &values, const GlobalPosition& globalPos) const + PrimaryVariables dirichletAtPos(const GlobalPosition& globalPos) const { + PrimaryVariables values; + values[pnIdx] = pLeftBc_; values[swIdx] = 1.0 - snr_; + + return values; } + /*! * \brief DOC ME! * \param values DOC ME! * \param globalPos DOC ME! */ - void neumannAtPos(PrimaryVariables &values, const GlobalPosition& globalPos) const + PrimaryVariables neumannAtPos( const GlobalPosition& globalPos) const { - values = 0; //homogeneous Neumann + return PrimaryVariables(0.0); } + /*! * \brief DOC ME! * \param values DOC ME! * \param globalPos DOC ME! */ - void initialAtPos(PrimaryVariables &values, - const GlobalPosition &globalPos) const + PrimaryVariables initialAtPos(const GlobalPosition &globalPos) const { + PrimaryVariables values; + values[pnIdx] = pLeftBc_; values[swIdx] = swr_; + + return values; } //Override outputfunction for ViPLab-Output - void writeOutput() + /* void writeOutput() { if (paraviewOutput_) ParentType::writeOutput(false); @@ -271,9 +286,10 @@ public: viplabOutput_.writeLegend(); } } - +*/ private: - Scalar eps_, swr_, snr_; + Scalar eps_, + Scalar swr_, snr_; Scalar pLeftBc_; McWhorterAnalytic analyticSolution_; ViplabOutput viplabOutput_; diff --git a/lecture/mm/naplinfiltration/3p/naplinfiltration3p.cc b/lecture/mm/naplinfiltration/3p/naplinfiltration3p.cc index 5de829a..62ac2c5 100644 --- a/lecture/mm/naplinfiltration/3p/naplinfiltration3p.cc +++ b/lecture/mm/naplinfiltration/3p/naplinfiltration3p.cc @@ -21,9 +21,8 @@ * * \brief application, using the 3p box model */ -#include "config.h" +// #include "config.h" #include "problem.hh" -#include /*! * \brief Provides an interface for customizing error messages associated with @@ -51,8 +50,174 @@ void usage(const char *progName, const std::string &errorMsg) } } -int main(int argc, char** argv) +//////////////////////// +// the main function +//////////////////////// +int main(int argc, char** argv) try { - typedef TTAG(InfiltrationProblem) ProblemTypeTag; - return Dumux::start(argc, argv, usage); + + using namespace Dumux; + + // define the type tag for this problem + using TypeTag = TTAG(InfiltrationProblem); + + // 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(leafGridView); + fvGridGeometry->update(); + + // the problem (initial and boundary conditions) + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); + auto problem = std::make_shared(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(problem, fvGridGeometry); + gridVariables->init(x, xOld); + + // get some time loop parameters + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + const auto tEnd = getParam("TimeLoop.TEnd"); + const auto maxDivisions = getParam("TimeLoop.MaxTimeStepDivisions"); // Q: What is this? Do we need this here? + const auto maxDt = getParam("TimeLoop.MaxTimeStepSize"); + auto dt = getParam("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")) // Fehlt ebenso + restartTime = getParam("TimeLoop.Restart"); + + // intialize the vtk output module + using VtkOutputFields = typename GET_PROP_TYPE(TypeTag, VtkOutputFields); + VtkOutputModule 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>(restartTime, dt, tEnd); + timeLoop->setMaxTimeStepSize(maxDt); + + // the assembler with time loop for instationary problem + using Assembler = FVAssembler; + auto assembler = std::make_shared(problem, fvGridGeometry, gridVariables, timeLoop); + + // the linear solver + using LinearSolver = AMGBackend; + auto linearSolver = std::make_shared(leafGridView, fvGridGeometry->dofMapper()); + + // the non-linear solver + using NewtonSolver = Dumux::NewtonSolver; + NewtonSolver nonLinearSolver(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 the Newton solver + timeLoop->setTimeStepSize(nonLinearSolver.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); + } + + + +} + +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; } diff --git a/lecture/mm/naplinfiltration/3p/naplinfiltration3p.input b/lecture/mm/naplinfiltration/3p/naplinfiltration3p.input index ea4efe9..c541161 100644 --- a/lecture/mm/naplinfiltration/3p/naplinfiltration3p.input +++ b/lecture/mm/naplinfiltration/3p/naplinfiltration3p.input @@ -1,4 +1,4 @@ -[TimeManager] +[TimeLoop] DtInitial = 60 # [s] TEnd = 31536000 # [s] #TEnd = 315360000000 # [s] @@ -16,4 +16,4 @@ VanGenuchtenN = 4.0 # [-] MultiplierNaplDensity = 1.0 # 1.0 means Mesitylene (an LNAPL) [-] [Newton] -MaxSteps = 6 \ No newline at end of file +MaxSteps = 6 diff --git a/lecture/mm/naplinfiltration/3p/problem.hh b/lecture/mm/naplinfiltration/3p/problem.hh index 325b6dc..a5a64f4 100644 --- a/lecture/mm/naplinfiltration/3p/problem.hh +++ b/lecture/mm/naplinfiltration/3p/problem.hh @@ -25,9 +25,10 @@ #ifndef DUMUX_NAPLINFILTRATIONPROBLEM_3P_HH #define DUMUX_NAPLINFILTRATIONPROBLEM_3P_HH -#include -#include +// #include +#include +#include #include #include @@ -51,20 +52,19 @@ SET_TYPE_PROP(InfiltrationProblem, FluidSystem, FluidSystems::H2OAirNAPL); -// Enable gravity? -SET_BOOL_PROP(InfiltrationProblem, ProblemEnableGravity, true); + // Write newton convergence? -SET_BOOL_PROP(InfiltrationProblem, NewtonWriteConvergence, false); +// SET_BOOL_PROP(InfiltrationProblem, NewtonWriteConvergence, false); // Maximum tolerated relative error in the Newton method -SET_SCALAR_PROP(InfiltrationProblem, NewtonMaxRelativeShift, 1e-4); +// SET_SCALAR_PROP(InfiltrationProblem, NewtonMaxRelativeShift, 1e-4); // -1 backward differences, 0: central differences, +1: forward differences -SET_INT_PROP(InfiltrationProblem, ImplicitNumericDifferenceMethod, 1); +// SET_INT_PROP(InfiltrationProblem, ImplicitNumericDifferenceMethod, 1); // Set the linear solver -SET_TYPE_PROP(InfiltrationProblem, LinearSolver, ILU0BiCGSTABBackend); +// SET_TYPE_PROP(InfiltrationProblem, LinearSolver, ILU0BiCGSTABBackend); } /*! @@ -98,43 +98,43 @@ SET_TYPE_PROP(InfiltrationProblem, LinearSolver, ILU0BiCGSTABBackend); * ./test_naplfiltrationexercise -ParameterFile test_naplfiltrationexercise.input * */ template -class InfiltrationProblem : public ImplicitPorousMediaProblem +class InfiltrationProblem : public PorousMediumFlowProblem { - typedef ImplicitPorousMediaProblem ParentType; + using ParentType = PorousMediumFlowProblem; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); // copy some indices for convenience - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum { - pressureIdx = Indices::pressureIdx, - switch1Idx = Indices::swIdx, - switch2Idx = Indices::snIdx, + using Indices = typename GET_PROP_TYPE(TypeTag, Indices); + + static constexpr int pressureIdx = Indices::pressureIdx; + static constexpr int switch1Idx = Indices::swIdx; + static constexpr int switch2Idx = Indices::snIdx; - contiWEqIdx = Indices::contiWEqIdx, - contiNEqIdx = Indices::contiNEqIdx, - contiGEqIdx = Indices::contiGEqIdx, + static constexpr int contiWEqIdx = Indices::contiWEqIdx; + static constexpr int contiNEqIdx = Indices::contiNEqIdx; + static constexpr int contiGEqIdx = Indices::contiGEqIdx; // Grid and world dimension - dim = GridView::dimension, - dimWorld = GridView::dimensionworld - }; + static constexpr int dim = GridView::dimension; + static constexpr int dimWorld = GridView::dimensionworld; + using Element = typename GridView::template Codim<0>::Entity; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes; - typedef typename GET_PROP_TYPE(TypeTag, TimeManager) TimeManager; + using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); + using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GridView::template Codim::Entity Vertex; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw; - typedef typename GET_PROP_TYPE(TypeTag, MaterialLawParams) MaterialLawParams; + // using Vertex = typename GridView::template Codim::Entity; + + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); + using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); + using MaterialLaw = typename Problem::SpatialParams::MaterialLaw + using MaterialLawParams = typename SpatialParams::MaterialLaw::Params; + - typedef Dune::FieldVector GlobalPosition; public: /*! @@ -143,14 +143,11 @@ public: * \param timeManager The time manager * \param gridView The grid view */ - InfiltrationProblem(TimeManager &timeManager, const GridView &gridView) - : ParentType(timeManager, gridView), eps_(1e-5) + InfiltrationProblem(std::shared_ptr fvGridGeometry) + : ParentType(fvGridGeometry) { temperature_ = 273.15 + 10.0; // -> 10 degrees Celsius - episodeLength_ = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, TimeManager, EpisodeLength); - this->timeManager().startNextEpisode(episodeLength_); - FluidSystem::init(/*tempMin=*/temperature_ - 1, /*tempMax=*/temperature_ + 1, /*nTemp=*/3, @@ -182,10 +179,10 @@ public: return temperature_; }; - void sourceAtPos(PrimaryVariables &values, - const GlobalPosition &globalPos) const + // DOC ME! + NumEqVector sourceAtPos(const GlobalPosition &globalPos) const { - values = 0; + return NumEqVector(0.0); } // \} @@ -202,15 +199,18 @@ public: * \param values The boundary types for the conservation equations * \param globalPos The position of the finite volume in global coordinates */ - void boundaryTypesAtPos(BoundaryTypes &values, - const GlobalPosition &globalPos) const + BoundaryVariables boundaryTypesAtPos( const GlobalPosition &globalPos) const { - if(globalPos[0] > this->bBoxMax()[0] - eps_) + BoundaryTypes values; + + if(globalPos[0] > this->fvGridGeometr().bBoxMax()[0] - eps_) values.setAllDirichlet(); - else if(globalPos[0] < this->bBoxMin()[0] + eps_) + else if(globalPos[0] < this->fvGridGeometry().bBoxMin()[0] + eps_) values.setAllDirichlet(); else values.setAllNeumann(); + + return values; } /*! @@ -224,10 +224,14 @@ public: * * For this method, the \a values parameter stores primary variables. */ - void dirichletAtPos(PrimaryVariables &values, + PrimaryVariables dirichletAtPos(PrimaryVariables &values, const GlobalPosition &globalPos) const { + PrimaryVariables values; + initial_(values, globalPos); + + return values; } /*! @@ -241,17 +245,20 @@ public: * For this method, the \a values parameter stores the mass flux * in normal direction of each phase. Negative values mean influx. */ + void neumannAtPos(PrimaryVariables &values, const GlobalPosition &globalPos) const { values = 0; // negative values for injection - if (this->timeManager().time() < 2592000) + // TODO: What to do here? + // See if there are conflicts with Dirichlet-BC. If yes, then figure out, how to rewrite. + if (this->timeLoop().time() < 2592000) { if (globalPos[0] < 175.0 + eps_ && globalPos[0] > 150.0 - eps_ - && globalPos[1] > this->bBoxMax()[1] - eps_) // upper boundary + && globalPos[1] > this->fvGridGeometry().bBoxMax()[1] - eps_) // upper boundary { values[contiWEqIdx] = 0.0; // mole flux conversion via M(mesit.) = 0,120 kg/mol --> 1.2e-4 kg/(s*m) @@ -278,22 +285,13 @@ 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); - } + PrimaryVariables values; - bool shouldWriteOutput() const - { - return this->timeManager().timeStepIndex() == 0 || - this->timeManager().episodeWillBeFinished() || - this->timeManager().willBeFinished(); - } + initial_(values, globalPos); - void episodeEnd() - { - this->timeManager().startNextEpisode(episodeLength_); + return values } private: @@ -326,6 +324,8 @@ private: static Scalar invertPcGW_(const Scalar pcIn, const MaterialLawParams &pcParams) { + + Scalar lower(0.0); Scalar upper(1.0); const unsigned int maxIterations = 25; @@ -351,8 +351,9 @@ private: return sw; } + const Scalar eps_ = 1e-5; + Scalar temperature_; - const Scalar eps_; Scalar episodeLength_; }; } //end namespace diff --git a/lecture/mm/naplinfiltration/3p3c/naplinfiltration3p3c.cc b/lecture/mm/naplinfiltration/3p3c/naplinfiltration3p3c.cc index 77f3e53..c0a313a 100644 --- a/lecture/mm/naplinfiltration/3p3c/naplinfiltration3p3c.cc +++ b/lecture/mm/naplinfiltration/3p3c/naplinfiltration3p3c.cc @@ -25,6 +25,29 @@ #include "problem.hh" #include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#include + /*! * \brief Provides an interface for customizing error messages associated with * reading in parameters. @@ -51,8 +74,175 @@ void usage(const char *progName, const std::string &errorMsg) } } -int main(int argc, char** argv) +int main(int argc, char** argv) try +{ + using namespace Dumux; + + // define the type tag for this problem + using TypeTag = TTAG(InfiltrationProblem); + + // 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); + + // 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(leafGridView); + fvGridGeometry->update(); + + // the problem (initial and boundary conditions) + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); + auto problem = std::make_shared(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(problem, fvGridGeometry); + gridVariables->init(x, xOld); + + // get some time loop parameters + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + const Scalar finalStorage = 1.55e5; + const Scalar injectionRate = getParam("BoundaryConditions.InjectionRate"); + const Scalar tEnd = finalStorage/injectionRate; + const auto maxDivisions = getParam("TimeLoop.MaxTimeStepDivisions"); + const auto maxDt = getParam("TimeLoop.MaxTimeStepSize"); + auto dt = getParam("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("TimeLoop.Restart"); + + // intialize the vtk output module + using VtkOutputFields = typename GET_PROP_TYPE(TypeTag, VtkOutputFields); + VtkOutputModule 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>(restartTime, dt, tEnd); + timeLoop->setMaxTimeStepSize(maxDt); + timeLoop->setPeriodicCheckPoint(getParam("TimeLoop.EpisodeLength", std::numeric_limits::max())); + + // the assembler with time loop for instationary problem + using Assembler = FVAssembler; + auto assembler = std::make_shared(problem, fvGridGeometry, gridVariables, timeLoop); + + // the linear solver + using LinearSolver = AMGBackend; + auto linearSolver = std::make_shared(leafGridView, fvGridGeometry->dofMapper()); + + // the non-linear solver + using NewtonController = PriVarSwitchNewtonController; + using NewtonMethod = Dumux::NewtonMethod; + auto newtonController = std::make_shared(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(); + + // report statistics of this time step + timeLoop->reportTimeStep(); + + // set new dt as suggested by newton controller + timeLoop->setTimeStepSize(newtonController->suggestTimeStepSize(timeLoop->timeStepSize())); + + // write vtk output + // if episode length was specificied output only at the end of episodes + if (!haveParam("TimeLoop.EpisodeLength") || timeLoop->isCheckPoint() || timeLoop->finished() || timeLoop->timeStepIndex() == 1) + vtkWriter.write(timeLoop->time()); + + } 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 (...) { - typedef TTAG(InfiltrationProblem) ProblemTypeTag; - return Dumux::start(argc, argv, usage); + std::cerr << "Unknown exception thrown! ---> Abort!" << std::endl; + return 4; } diff --git a/lecture/mm/naplinfiltration/3p3c/problem.hh b/lecture/mm/naplinfiltration/3p3c/problem.hh index 6e0cffc..a1a561b 100644 --- a/lecture/mm/naplinfiltration/3p3c/problem.hh +++ b/lecture/mm/naplinfiltration/3p3c/problem.hh @@ -25,8 +25,8 @@ #ifndef DUMUX_NAPLINFILTRATIONPROBLEM_3P_3C_HH #define DUMUX_NAPLINFILTRATIONPROBLEM_3P_3C_HH -#include -#include +// #include +#include #include #include @@ -51,20 +51,20 @@ SET_TYPE_PROP(InfiltrationProblem, FluidSystem, FluidSystems::H2OAirNAPL); -// Enable gravity? -SET_BOOL_PROP(InfiltrationProblem, ProblemEnableGravity, true); // Write newton convergence? -SET_BOOL_PROP(InfiltrationProblem, NewtonWriteConvergence, false); +// SET_BOOL_PROP(InfiltrationProblem, NewtonWriteConvergence, false); // Maximum tolerated relative error in the Newton method -SET_SCALAR_PROP(InfiltrationProblem, NewtonMaxRelativeShift, 1e-4); +// SET_SCALAR_PROP(InfiltrationProblem, NewtonMaxRelativeShift, 1e-4); // -1 backward differences, 0: central differences, +1: forward differences -SET_INT_PROP(InfiltrationProblem, ImplicitNumericDifferenceMethod, 1); +// SET_INT_PROP(InfiltrationProblem, ImplicitNumericDifferenceMethod, 1); // Set the linear solver -SET_TYPE_PROP(InfiltrationProblem, LinearSolver, ILU0BiCGSTABBackend); +// SET_TYPE_PROP(InfiltrationProblem, LinearSolver, ILU0BiCGSTABBackend); + + } /*! @@ -98,15 +98,16 @@ SET_TYPE_PROP(InfiltrationProblem, LinearSolver, ILU0BiCGSTABBackend); * ./test_naplfiltrationexercise -ParameterFile test_naplfiltrationexercise.input * */ template -class InfiltrationProblem : public ImplicitPorousMediaProblem +class InfiltrationProblem : public PorousMediumFlowProblem { - typedef ImplicitPorousMediaProblem ParentType; + using ParentType = PorousMediumFlowProblem; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); // copy some indices for convenience - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; + using Indices = typename GET_PROP_TYPE(TypeTag, Indices); + enum { pressureIdx = Indices::pressureIdx, @@ -122,37 +123,33 @@ class InfiltrationProblem : public ImplicitPorousMediaProblem dim = GridView::dimension, dimWorld = GridView::dimensionworld }; + using GlobalPosition = Dune::FieldVector; + using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); + using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes; - typedef typename GET_PROP_TYPE(TypeTag, TimeManager) TimeManager; + using Element = typename GridView::template Codim<0>::Entity; + using Vertex = typename GridView::template Codim::Entity; - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GridView::template Codim::Entity Vertex; + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); + using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw; - typedef typename GET_PROP_TYPE(TypeTag, MaterialLawParams) MaterialLawParams; +public: - typedef Dune::FieldVector GlobalPosition; + using MaterialLaw = typename GET_PROP_TYPE(TypeTag, MaterialLaw); + using MaterialLawParams = typename GET_PROP_TYPE(TypeTag, MaterialLawParams); -public: /*! * \brief The constructor * * \param timeManager The time manager * \param gridView The grid view */ - InfiltrationProblem(TimeManager &timeManager, const GridView &gridView) - : ParentType(timeManager, gridView), eps_(1e-5) + InfiltrationProblem(std::shared_ptr fvGridGeometry) + : ParentType(fvGridGeometry) { temperature_ = 273.15 + 10.0; // -> 10 degrees Celsius - episodeLength_ = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, TimeManager, EpisodeLength); - this->timeManager().startNextEpisode(episodeLength_); - FluidSystem::init(/*tempMin=*/temperature_ - 1, /*tempMax=*/temperature_ + 1, /*nTemp=*/3, @@ -184,10 +181,9 @@ public: return temperature_; }; - void sourceAtPos(PrimaryVariables &values, - const GlobalPosition &globalPos) const + NumEqVector sourceAtPos(const GlobalPosition &globalPos) const { - values = 0; + return NumEqVector(0.0); } // \} @@ -204,15 +200,18 @@ public: * \param values The boundary types for the conservation equations * \param globalPos The position of the finite volume in global coordinates */ - void boundaryTypesAtPos(BoundaryTypes &values, - const GlobalPosition &globalPos) const + BoundaryTypes boundaryTypesAtPos(const GlobalPosition &globalPos) const { - if(globalPos[0] > this->bBoxMax()[0] - eps_) + BoundaryTypes values; + + if(globalPos[0] > this->fvGridGeometry().bBoxMax()[0] - eps_) values.setAllDirichlet(); - else if(globalPos[0] < this->bBoxMin()[0] + eps_) + else if(globalPos[0] < this->fvGridGeometry().bBoxMin()[0] + eps_) values.setAllDirichlet(); else values.setAllNeumann(); + + return values; } /*! @@ -226,10 +225,13 @@ public: * * For this method, the \a values parameter stores primary variables. */ - void dirichletAtPos(PrimaryVariables &values, - const GlobalPosition &globalPos) const + PrimaryVariables dirichletAtPos( const GlobalPosition &globalPos) const { + PrimaryVariables values; + initial_(values, globalPos); + + return values; } /*! @@ -243,17 +245,17 @@ public: * For this method, the \a values parameter stores the mass flux * in normal direction of each phase. Negative values mean influx. */ - void neumannAtPos(PrimaryVariables &values, - const GlobalPosition &globalPos) const + Primary Variables neumannAtPos(const GlobalPosition &globalPos) const { - values = 0; + PrimaryVariables values(0.0), // negative values for injection - if (this->timeManager().time() < 2592000) + // TODO: How tho change this correctly? + if (this->timeLoop().time() < 2592000) { if (globalPos[0] < 175.0 + eps_ && globalPos[0] > 150.0 - eps_ - && globalPos[1] > this->bBoxMax()[1] - eps_) // upper boundary + && globalPos[1] > this->fvGridGeometry().bBoxMax()[1] - eps_) // upper boundary { values[contiWEqIdx] = 0.0; // mole flux conversion via M(mesit.) = 0,120 kg/mol --> 1.2e-4 kg/(s*m) @@ -261,6 +263,8 @@ public: values[contiGEqIdx] = 0.0; } } + + return values; } // \} @@ -280,10 +284,13 @@ 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 { + PrimaryVariables values; + initial_(values, globalPos); + + return values; } /*! @@ -296,17 +303,6 @@ public: return Indices::wgPhaseOnly; } - bool shouldWriteOutput() const - { - return this->timeManager().timeStepIndex() == 0 || - this->timeManager().episodeWillBeFinished() || - this->timeManager().willBeFinished(); - } - - void episodeEnd() - { - this->timeManager().startNextEpisode(episodeLength_); - } private: // internal method for the initial condition (reused for the @@ -363,8 +359,9 @@ private: return sw; } + const Scalar eps_ = 1e-5; + Scalar temperature_; - const Scalar eps_; Scalar episodeLength_; }; } //end namespace diff --git a/lecture/mm/naplinfiltration/h2oairnaplfluidsystem.hh b/lecture/mm/naplinfiltration/h2oairnaplfluidsystem.hh index bd62bb4..16086c5 100644 --- a/lecture/mm/naplinfiltration/h2oairnaplfluidsystem.hh +++ b/lecture/mm/naplinfiltration/h2oairnaplfluidsystem.hh @@ -51,36 +51,35 @@ namespace FluidSystems * components in both, the liquid and the gas phase. */ template > > + class H2OType = Components::TabulatedComponent > > class H2OAirNAPL : public BaseFluidSystem > { - typedef H2OAirNAPL ThisType; - typedef BaseFluidSystem Base; + using ThisType = H2OAirNAPL; + using Base = BaseFluidSystem; public: - typedef Dumux::Mesitylene NAPL; - typedef Dumux::Air Air; - typedef H2OType H2O; + using NAPL = Components::Mesitylene; + using Air = Components::Air; + using H2O = H2OType; + static constexpr int numPhases = 3; + static constexpr int numComponents = 3; - static const int numPhases = 3; - static const int numComponents = 3; + static constexpr int wPhaseIdx = 0; // index of the water phase + static constexpr int nPhaseIdx = 1; // index of the NAPL phase + static constexpr int gPhaseIdx = 2; // index of the gas phase - static const int wPhaseIdx = 0; // index of the water phase - static const int nPhaseIdx = 1; // index of the NAPL phase - static const int gPhaseIdx = 2; // index of the gas phase - - static const int H2OIdx = 0; - static const int NAPLIdx = 1; - static const int airIdx = 2; + static constexpr int H2OIdx = 0; + static constexpr int NAPLIdx = 1; + static constexpr int airIdx = 2; // export component indices to indicate the main component // of the corresponding phase at atmospheric pressure 1 bar // and room temperature 20°C: - static const int wCompIdx = H2OIdx; - static const int nCompIdx = NAPLIdx; - static const int gCompIdx = airIdx; + static constexpr int wCompIdx = H2OIdx; + static constexpr int nCompIdx = NAPLIdx; + static constexpr int gCompIdx = airIdx; /*! * \brief Initialize the fluid system's static parameters generically @@ -246,8 +245,7 @@ public: else if (phaseIdx == nPhaseIdx) { // assume pure NAPL for the NAPL phase Scalar pressure = NAPL::liquidIsCompressible()?fluidState.pressure(phaseIdx):1e100; - return GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, SpatialParams, MultiplierNaplDensity) - * NAPL::liquidDensity(fluidState.temperature(phaseIdx), pressure); + return getParam("SpatialParams.MultiplierNaplDensity")*NAPL::liquidDensity(fluidState.temperature(phaseIdx), pressure); } assert (phaseIdx == gPhaseIdx); diff --git a/lecture/mm/naplinfiltration/spatialparams.hh b/lecture/mm/naplinfiltration/spatialparams.hh index 505d395..22e6a3b 100644 --- a/lecture/mm/naplinfiltration/spatialparams.hh +++ b/lecture/mm/naplinfiltration/spatialparams.hh @@ -25,35 +25,38 @@ #define DUMUX_NAPLINFILTRATION_SPATIAL_PARAMS_HH #include -#include +#include #include #include #include +#include namespace Dumux { - //forward declaration -template +template class InfiltrationSpatialParams; namespace Properties { + +using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; + // The spatial parameters TypeTag NEW_TYPE_TAG(InfiltrationSpatialParams); // Set the spatial parameters -SET_TYPE_PROP(InfiltrationSpatialParams, SpatialParams, Dumux::InfiltrationSpatialParams); +SET_TYPE_PROP(InfiltrationSpatialParams, SpatialParams, Dumux::InfiltrationSpatialParams); // Set the material Law -SET_PROP(InfiltrationSpatialParams, MaterialLaw) +SET_PROP(InfiltrationSpatialParams, SpatialParams::MaterialLaw) { private: - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef RegularizedParkerVanGen3P EffectiveLaw; + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using EffectiveLaw = RegularizedParkerVanGen3P; public: // define the material law parameterized by absolute saturations - typedef EffToAbsLaw type; + using type = EffToAbsLaw; }; } @@ -62,55 +65,59 @@ SET_PROP(InfiltrationSpatialParams, MaterialLaw) * * \brief Definition of the spatial parameters for the infiltration problem */ -template -class InfiltrationSpatialParams : public ImplicitSpatialParams +template +class InfiltrationSpatialParams : public FVSpatialParams { - typedef ImplicitSpatialParams ParentType; + using ParentType = FVSpatialParams; + using Element = typename GridView::template Codim<0>::Entity; + using Grid = typename GET_PROP_TYPE(TypeTag, Grid); + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; + using CoordScalar = typename Grid::ctype; - typedef typename GET_PROP_TYPE(TypeTag, Grid) Grid; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - typedef typename Grid::ctype CoordScalar; + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; - enum { - dim=GridView::dimension, - dimWorld=GridView::dimensionworld, - wPhaseIdx = Indices::wPhaseIdx, - nPhaseIdx = Indices::nPhaseIdx - }; + static constexpr int dim=GridView::dimension; + static constexpr int dimWorld=GridView::dimensionworld; - typedef Dune::FieldVector GlobalPosition; - typedef Dune::FieldVector Vector; + static constexpr int wPhaseIdx = Indices::wPhaseIdx; + static constexpr int nPhaseIdx = Indices::nPhaseIdx; - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector; + using GlobalPosition = Dune::FieldVector; + using Vector = Dune::FieldVector; + + using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector); + + using FluxVarialbes = typename GET_PROP_TYPE(TypeTag, FluxVariables); + using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables); - typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GridView::template Codim<0>::Entity Element; public: //get the material law from the property system - typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw; - typedef typename MaterialLaw::Params MaterialLawParams; + // using MaterialLaw = typename GET_PROP_TYPE(TypeTag, MaterialLaw); + using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; + using MaterialLawParams = typename MaterialLaw::Params; /*! * \brief The constructor * * \param gv The grid view */ - InfiltrationSpatialParams(const GridView &gv) - : ParentType(gv), eps_(1.0e-7) + /* old: InfiltrationSpatialParams(const GridView &gv) + : ParentType(gv), eps_(1.0e-7)*/ + InfiltrationSpatialParams(const Problem& problem) + : ParentType(problem) + { // intrinsic permeabilities - permeability_ = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, SpatialParams, Permeability); + permeability_ = getParam("SpatialParams.Permeability"); // porosity - porosity_ = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, SpatialParams, Porosity); + porosity_ = getParam("SpatialParams.Porosity"); // residual saturations MaterialParams_.setSwr(0.12); @@ -119,8 +126,8 @@ public: MaterialParams_.setSgr(0.03); // parameters for the 3phase van Genuchten law - MaterialParams_.setVgAlpha(GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, SpatialParams, VanGenuchtenAlpha)); - MaterialParams_.setVgn(GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, SpatialParams, VanGenuchtenN)); + MaterialParams_.setVgAlpha( getParam("SpatialParams.VanGenuchtenAlpha") ); + MaterialParams_.setVgn( getParam("SpatialParams.VanGenuchtenN") ); MaterialParams_.setKrRegardsSnr(false); // parameters for adsorption @@ -249,7 +256,7 @@ public: } private: - const Scalar eps_; + const Scalar eps_ = 1.0e-7; Scalar permeability_, porosity_; MaterialLawParams MaterialParams_; diff --git a/lecture/mm/remediationscenarios/remediationscenariosexercise.cc b/lecture/mm/remediationscenarios/remediationscenariosexercise.cc index 432648e..13bacbf 100644 --- a/lecture/mm/remediationscenarios/remediationscenariosexercise.cc +++ b/lecture/mm/remediationscenarios/remediationscenariosexercise.cc @@ -23,8 +23,29 @@ */ #include "config.h" #include "remediationscenariosproblem.hh" -#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#include /*! * \brief Provides an interface for customizing error messages associated with @@ -52,8 +73,178 @@ void usage(const char *progName, const std::string &errorMsg) } } -int main(int argc, char** argv) +/* int main(int argc, char** argv) { typedef TTAG(KuevetteProblem) ProblemTypeTag; return Dumux::start(argc, argv, usage); +}*/ +//////////////////////// +// the main function +//////////////////////// +int main(int argc, char** argv) try +{ + // typedef TTAG(LensOnePTwoCProblem) TypeTag; + // return Dumux::start(argc, argv, usage); + using namespace Dumux; + + // define the type tag for this problem + using TypeTag = TTAG(KuevetteProblem); + + // 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(leafGridView); + fvGridGeometry->update(); + + // the problem (initial and boundary conditions) + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); + auto problem = std::make_shared(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(problem, fvGridGeometry); + gridVariables->init(x, xOld); + + // get some time loop parameters + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + const auto tEnd = getParam("TimeLoop.TEnd"); + const auto maxDivisions = getParam("TimeLoop.MaxTimeStepDivisions"); // Q: What is this? Do we need this here? + const auto maxDt = getParam("TimeLoop.MaxTimeStepSize"); + auto dt = getParam("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")) // Fehlt ebenso + restartTime = getParam("TimeLoop.Restart"); + + // intialize the vtk output module + using VtkOutputFields = typename GET_PROP_TYPE(TypeTag, VtkOutputFields); + VtkOutputModule 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>(restartTime, dt, tEnd); + timeLoop->setMaxTimeStepSize(maxDt); + + // the assembler with time loop for instationary problem + using Assembler = FVAssembler; + auto assembler = std::make_shared(problem, fvGridGeometry, gridVariables, timeLoop); + + // the linear solver + using LinearSolver = AMGBackend; + auto linearSolver = std::make_shared(leafGridView, fvGridGeometry->dofMapper()); + + // the non-linear solver + using NewtonSolver = Dumux::NewtonSolver; + NewtonSolver nonLinearSolver(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 the Newton solver + timeLoop->setTimeStepSize(nonLinearSolver.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); + } + +} + +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; } diff --git a/lecture/mm/remediationscenarios/remediationscenariosexercise.input b/lecture/mm/remediationscenarios/remediationscenariosexercise.input index 7c5d998..f683976 100644 --- a/lecture/mm/remediationscenarios/remediationscenariosexercise.input +++ b/lecture/mm/remediationscenarios/remediationscenariosexercise.input @@ -1,4 +1,4 @@ -[TimeManager] +[TimeLoop] DtInitial = 1 # [s] TEnd = 25920000 # [s] : maybe shorter for some scenarios, can be adapted OutputInterval = 25 diff --git a/lecture/mm/remediationscenarios/remediationscenariosproblem.hh b/lecture/mm/remediationscenarios/remediationscenariosproblem.hh index 526ae2a..f940220 100644 --- a/lecture/mm/remediationscenarios/remediationscenariosproblem.hh +++ b/lecture/mm/remediationscenarios/remediationscenariosproblem.hh @@ -28,10 +28,11 @@ #include +#include #include -#include -#include +#include +#include #include "remediationscenariosspatialparams.hh" @@ -55,25 +56,25 @@ SET_TYPE_PROP(KuevetteProblem, Problem,KuevetteProblem); // Set the fluid system SET_TYPE_PROP(KuevetteProblem, FluidSystem, - FluidSystems::H2OAirMesitylene); + FluidSystems::H2OAirMesitylene); // Enable gravity -SET_BOOL_PROP(KuevetteProblem, ProblemEnableGravity, true); +// SET_BOOL_PROP(KuevetteProblem, ProblemEnableGravity, true); // Use central differences (backward -1, forward +1) -SET_INT_PROP(KuevetteProblem, ImplicitNumericDifferenceMethod, 1); +// SET_INT_PROP(KuevetteProblem, ImplicitNumericDifferenceMethod, 1); // Set the maximum time step -SET_SCALAR_PROP(KuevetteProblem, TimeManagerMaxTimeStepSize, 25.0); +// SET_SCALAR_PROP(KuevetteProblem, TimeManagerMaxTimeStepSize, 25.0); // set newton relative tolerance -SET_SCALAR_PROP(KuevetteProblem, NewtonMaxRelativeShift, 1e-4); +// SET_SCALAR_PROP(KuevetteProblem, NewtonMaxRelativeShift, 1e-4); // Use ConstraintSolver -SET_BOOL_PROP(KuevetteProblem, UseConstraintSolver, false); +//SET_BOOL_PROP(KuevetteProblem, UseConstraintSolver, false); // Set the linear solver -SET_TYPE_PROP(KuevetteProblem, LinearSolver, ILU0BiCGSTABBackend); +//SET_TYPE_PROP(KuevetteProblem, LinearSolver, ILU0BiCGSTABBackend); } @@ -111,16 +112,26 @@ SET_TYPE_PROP(KuevetteProblem, LinearSolver, ILU0BiCGSTABBackend); * ./test_3p3cni -parameterFile test_3p3cni.input * */ template -class KuevetteProblem : public ImplicitPorousMediaProblem +class KuevetteProblem : public PorousMediumFlowProblem { - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GridView::Grid Grid; + using ParentType = PorousMediumFlowProblem; - typedef ImplicitPorousMediaProblem ParentType; + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using Indices = typename GET_PROP_TYPE(TypeTag, Indices); + + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using Grid = typename GridView::Grid; + + using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); + using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); + + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); + using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); + + using Element = typename GridView::template Codim<0>::Entity; + using Vertex = typename GridView::template Codim::Entity; + using Intersection = typename GridView::Intersection; - // copy some indices for convenience - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; enum { pressureIdx = Indices::pressureIdx, @@ -137,20 +148,10 @@ class KuevetteProblem : public ImplicitPorousMediaProblem dim = GridView::dimension, dimWorld = GridView::dimensionworld }; + using GlobalPosition = Dune::FieldVectory; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes; - typedef typename GET_PROP_TYPE(TypeTag, TimeManager) TimeManager; - - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GridView::template Codim::Entity Vertex; - typedef typename GridView::Intersection Intersection; - - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef Dune::FieldVector GlobalPosition; public: /*! @@ -159,14 +160,14 @@ public: * \param timeManager The time manager * \param gridView The grid view */ - KuevetteProblem(TimeManager &timeManager, const GridView &gridView) - : ParentType(timeManager, gridView) + KuevetteProblem(std::shared_ptr fvGridGeometry ) + : ParentType(fvGridGeometry) { FluidSystem::init(); - int isSteam = GET_RUNTIME_PARAM(TypeTag, bool, Problem.SteamScenario) ? 1 : 0; - int isSteamAir = GET_RUNTIME_PARAM(TypeTag, bool, Problem.SteamAirScenario) ? 1 : 0; - int isAir = GET_RUNTIME_PARAM(TypeTag, bool, Problem.AirScenario) ? 1 : 0; + int isSteam = getParam("Problem.SteamScenario") ? 1 : 0; + int isSteamAir = getParam("Problem.SteamAirScenario") ? 1 : 0; + int isAir = getParam("Problem.AirScenario") ? 1 : 0; // error checking if (isSteam + isSteamAir + isAir > 1) @@ -174,35 +175,35 @@ public: if (isSteam == 1) { - waterFlux_ = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.WaterFluxS); // 0.3435 [mol/(s m)] in total - airFlux_ = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.AirFluxS); - contaminantFlux_ = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.ContaminantFluxS); - heatFlux_ = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.HeatFluxS); + waterFlux_ = getParam("Problem.WaterFluxS"); // 0.3435 [mol/(s m)] in total + airFlux_ = getParam("Problem.AirFluxS"); + contaminantFlux_ = getParam("Problem.ContaminantFluxS"); + heatFlux_ = getParam("Problem.HeatFluxS"); name_ = "remediation-steam"; } else if (isSteamAir == 1) { - waterFlux_ = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.WaterFluxSA); // 0.3435 [mol/(s m)] in total - airFlux_ = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.AirFluxSA); - contaminantFlux_ = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.ContaminantFluxSA); - heatFlux_ = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.HeatFluxSA); + waterFlux_ = getParam("Problem.WaterFluxSA); // 0.3435 [mol/(s m)] in total + airFlux_ = getParam("Problem.AirFluxSA"); + contaminantFlux_ = getParam("Problem.ContaminantFluxSA"); + heatFlux_ = getParam("Problem.HeatFluxSA"); name_ = "remediation-steamair"; } else if (isAir == 1) { - waterFlux_ = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.WaterFluxA); // 0.3435 [mol/(s m)] in total - airFlux_ = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.AirFluxA); - contaminantFlux_ = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.ContaminantFluxA); - heatFlux_ = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.HeatFluxA); + waterFlux_ = getParam("Problem.WaterFluxA"); // 0.3435 [mol/(s m)] in total + airFlux_ = getParam("Problem.AirFluxA"); + contaminantFlux_ = getParam("Problem.ContaminantFluxA"); + heatFlux_ = getParam("Problem.HeatFluxA"); name_ = "remediation-air"; } else { // free scenario - waterFlux_ = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.WaterFlux); // 0.3435 [mol/(s m)] in total - airFlux_ = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.AirFlux); - contaminantFlux_ = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.ContaminantFlux); - heatFlux_ = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.HeatFlux); + waterFlux_ = getParam("Problem.WaterFlux"); // 0.3435 [mol/(s m)] in total + airFlux_ = getParam("Problem.AirFlux"); + contaminantFlux_ = getParam("Problem.ContaminantFlux"); + heatFlux_ = getParam("Problem.HeatFlux"); name_ = "remediation"; } } @@ -220,10 +221,9 @@ public: const std::string name() const { return name_; } - void sourceAtPos(PrimaryVariables &values, - const GlobalPosition &globalPos) const + NumEqVector sourceAtPos( const GlobalPosition &globalPos) const { - values = 0; + return NumEqVector(0.0); } @@ -241,8 +241,10 @@ public: * \param values The boundary types for the conservation equations * \param vertex The vertex for which the boundary type is set */ - void boundaryTypes(BoundaryTypes &values, const Vertex &vertex) const + BoundaryTypes boundaryTypes( const Vertex &vertex) const { + BoundaryTypes values; + const GlobalPosition globalPos = vertex.geometry().center(); if(globalPos[0] > 1.5 - eps_) @@ -250,6 +252,7 @@ public: else values.setAllNeumann(); + return values; } /*! @@ -261,11 +264,15 @@ public: * * For this method, the \a values parameter stores primary variables. */ - void dirichlet(PrimaryVariables &values, const Vertex &vertex) const + PrimaryVariables dirichlet( const Vertex &vertex) const { + PrimaryVariables values; + const GlobalPosition globalPos = vertex.geometry().center(); initial_(values, globalPos); + + return values; } /*! @@ -282,13 +289,14 @@ public: * For this method, the \a values parameter stores the mass flux * in normal direction of each phase. Negative values mean influx. */ - void neumann(PrimaryVariables &values, - const Element &element, + PrimaryVariables neumann(const Element &element, const FVElementGeometry &fvGeomtry, const Intersection &is, const int scvIdx, int boundaryFaceIdx) const { + PrimaryVariables values; + const GlobalPosition &globalPos = element.geometry().corner(scvIdx); // negative values for injection @@ -306,6 +314,8 @@ public: values[Indices::contiNEqIdx] = contaminantFlux_; values[Indices::energyEqIdx] = heatFlux_; } + + return values; } // \} @@ -326,15 +336,17 @@ public: * For this method, the \a values parameter stores primary * variables. */ - void initial(PrimaryVariables &values, - const Element &element, + PrimaryVariables initial( const Element &element, const FVElementGeometry &fvGeomtry, const int scvIdx) const { + PrimaryVariables values; + const GlobalPosition &globalPos = element.geometry().corner(scvIdx); initial_(values, globalPos); + return values; } /*! @@ -355,28 +367,6 @@ public: } } - bool shouldWriteOutput() const - { - - int outputInterval = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, int, TimeManager, OutputInterval); - - return (this->timeManager().timeStepIndex() % outputInterval == 0 || - this->timeManager().willBeFinished()); - } - - /*! - * \brief Returns true if a restart file should be written to - * disk. - * - * The default behavior is to write one restart file every 5 time - * steps. This file is intended to be overwritten by the - * implementation. - */ - bool shouldWriteRestartFile() const - { - return false; - } - private: // internal method for the initial condition (reused for the diff --git a/lecture/mm/remediationscenarios/remediationscenariosspatialparams.hh b/lecture/mm/remediationscenarios/remediationscenariosspatialparams.hh index f4fdeff..bbf49fb 100644 --- a/lecture/mm/remediationscenarios/remediationscenariosspatialparams.hh +++ b/lecture/mm/remediationscenarios/remediationscenariosspatialparams.hh @@ -24,8 +24,10 @@ #ifndef DUMUX_REMEDIATIONSCENARIOS_SPATIAL_PARAMS_HH #define DUMUX_REMEDIATIONSCENARIOS_SPATIAL_PARAMS_HH -#include -#include +#include +// #include +#include + #include #include #include @@ -71,17 +73,16 @@ class KuevetteSpatialParams : public ImplicitSpatialParams typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; typedef typename Grid::ctype CoordScalar; - enum { - dim=GridView::dimension, - dimWorld=GridView::dimensionworld - }; + typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum { + /*enum { wPhaseIdx = Indices::wPhaseIdx, nPhaseIdx = Indices::nPhaseIdx - }; + };*/ + static constexpr wPhasseIdx = Indices::wPhaseIdx; + static constexpr nPhaseIdx = Indices::nPhaseIdx; typedef Dune::FieldVector GlobalPosition; typedef Dune::FieldVector Vector; -- GitLab From a1c30b8241aaf81d1d3845d95207254db7c6f007 Mon Sep 17 00:00:00 2001 From: Kai Wendel Date: Mon, 6 Aug 2018 13:21:01 +0200 Subject: [PATCH 02/60] UseMoles does not work correctly, see commentaries in henry1p2cproblem.hh --- .../mm/henryproblem/henry1p2c/henry1p2c.cc | 100 +++++++++--------- .../mm/henryproblem/henry1p2c/henry1p2c.input | 19 ++-- .../henry1p2c/henry1p2cproblem.hh | 68 ++++-------- .../henry1p2c/henry1p2cspatialparameters.hh | 37 +++---- 4 files changed, 99 insertions(+), 125 deletions(-) diff --git a/lecture/mm/henryproblem/henry1p2c/henry1p2c.cc b/lecture/mm/henryproblem/henry1p2c/henry1p2c.cc index fcbc05b..90198da 100644 --- a/lecture/mm/henryproblem/henry1p2c/henry1p2c.cc +++ b/lecture/mm/henryproblem/henry1p2c/henry1p2c.cc @@ -21,11 +21,31 @@ * * \brief test for the 1p2c box model */ -#include "config.h" - +#include +#include +#include #include "henry1p2cproblem.hh" +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include -#include void usage(const char *progName, const std::string &errorMsg) @@ -61,6 +81,9 @@ int main(int argc, char** argv) try // define the type tag for this problem using TypeTag = TTAG(Henry1p2cProblem); + //////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////// + // initialize MPI, finalize is done automatically on exit const auto& mpiHelper = Dune::MPIHelper::instance(argc, argv); @@ -68,20 +91,22 @@ int main(int argc, char** argv) try if (mpiHelper.rank() == 0) DumuxMessage::print(/*firstCall=*/true); - // parse command line arguments and input file - Parameters::init(argc, argv, usage); + // initialize parameter tree + Parameters::init(argc, argv); + ////////////////////////////////////////////////////////////////////// // 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(); + ///////////////////////////////////////////////////////////////////// + + GridManager gridManager; + gridManager.init(); //////////////////////////////////////////////////////////// // run instationary non-linear problem on this grid //////////////////////////////////////////////////////////// // we compute on the leaf grid view - const auto& leafGridView = GridCreator::grid().leafGridView(); + const auto& leafGridView = gridManager.grid().leafGridView(); // create the finite volume grid geometry using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); @@ -105,24 +130,18 @@ int main(int argc, char** argv) try // get some time loop parameters using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - const auto tEnd = getParam("TimeLoop.TEnd"); - const auto maxDivisions = getParam("TimeLoop.MaxTimeStepDivisions"); // Q: What is this? Do we need this here? - const auto maxDt = getParam("TimeLoop.MaxTimeStepSize"); + auto tEnd = getParam("TimeLoop.TEnd"); auto dt = getParam("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")) // Fehlt ebenso - restartTime = getParam("TimeLoop.Restart"); + auto maxDt = getParam("TimeLoop.MaxTimeStepSize"); // intialize the vtk output module + VtkOutputModule vtkWriter(*gridVariables, x, problem->name()); using VtkOutputFields = typename GET_PROP_TYPE(TypeTag, VtkOutputFields); - VtkOutputModule 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>(restartTime, dt, tEnd); + auto timeLoop = std::make_shared>(0.0, dt, tEnd); timeLoop->setMaxTimeStepSize(maxDt); // the assembler with time loop for instationary problem @@ -130,12 +149,11 @@ int main(int argc, char** argv) try auto assembler = std::make_shared(problem, fvGridGeometry, gridVariables, timeLoop); // the linear solver - using LinearSolver = AMGBackend; - auto linearSolver = std::make_shared(leafGridView, fvGridGeometry->dofMapper()); + using LinearSolver = ILU0BiCGSTABBackend; + auto linearSolver = std::make_shared(); // the non-linear solver - using NewtonSolver = Dumux::NewtonSolver; - NewtonSolver nonLinearSolver(assembler, linearSolver); + NewtonSolver nonLinearSolver(assembler, linearSolver); // time loop timeLoop->start(); do @@ -143,24 +161,8 @@ int main(int argc, char** argv) try // 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."); - } + // solve the non-linear system with time step control + nonLinearSolver.solve(x, *timeLoop); // make the new solution the old solution xOld = x; @@ -175,7 +177,7 @@ int main(int argc, char** argv) try // report statistics of this time step timeLoop->reportTimeStep(); - // set new dt as suggested by the Newton solver + // set new dt as suggested by the newton solver timeLoop->setTimeStepSize(nonLinearSolver.suggestTimeStepSize(timeLoop->timeStepSize())); } while (!timeLoop->finished()); @@ -188,13 +190,9 @@ int main(int argc, char** argv) try // print dumux end message if (mpiHelper.rank() == 0) - { - Parameters::print(); DumuxMessage::print(/*firstCall=*/false); - } - - + return 0; } catch (Dumux::ParameterException &e) @@ -205,10 +203,10 @@ catch (Dumux::ParameterException &e) 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; + "). 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) diff --git a/lecture/mm/henryproblem/henry1p2c/henry1p2c.input b/lecture/mm/henryproblem/henry1p2c/henry1p2c.input index fb8024c..01bf1f1 100644 --- a/lecture/mm/henryproblem/henry1p2c/henry1p2c.input +++ b/lecture/mm/henryproblem/henry1p2c/henry1p2c.input @@ -1,10 +1,15 @@ +[TimeLoop] +DtInitial = 2.5# [s] +TEnd = 1e12# [s] -TimeManager.DtInitial = 2.5# [s] -TimeManager.TEnd = 1e12# [s] -Grid.File = ./grids/henry.dgf +[Grid] +File = ./grids/henry.dgf -Problem.freshWaterFluxRate = 6.6E-2 # [kg/sm^2] fresh water flux rate at the left boundary -Problem.diffusionCoefficient = 6.6e-6 # 1.2e-9 #[m2/s] Diffusion coefficient +[Problem] +freshWaterFluxRate = 6.6E-2 # [kg/sm^2] fresh water flux rate at the left boundary +diffusionCoefficient = 6.6e-6 # 1.2e-9 #[m2/s] Diffusion coefficient +Name = Henry1p2c -SpatialParams.dispersivityL=0.1 # longitual dispersivity -SpatialParams.dispersivityT=0.01 # transversial dispersivity +[SpatialParams] +dispersivityL=0.1 # longitual dispersivity +dispersivityT=0.01 # transversial dispersivity diff --git a/lecture/mm/henryproblem/henry1p2c/henry1p2cproblem.hh b/lecture/mm/henryproblem/henry1p2c/henry1p2cproblem.hh index 893e8cb..367337c 100644 --- a/lecture/mm/henryproblem/henry1p2c/henry1p2cproblem.hh +++ b/lecture/mm/henryproblem/henry1p2c/henry1p2cproblem.hh @@ -27,6 +27,7 @@ #include #include +#include #include "watersaltfluidsystem.hh" #include "henry1p2cspatialparameters.hh" @@ -38,7 +39,7 @@ class Henry1p2cProblem; namespace Properties { -NEW_TYPE_TAG(Henry1p2cProblem, INHERITS_FROM(TwoP, BoxModel)); +NEW_TYPE_TAG(Henry1p2cProblem, INHERITS_FROM(OnePNC, BoxModel)); // Set the grid type SET_TYPE_PROP(Henry1p2cProblem, Grid, Dune::YaspGrid<2>); @@ -54,45 +55,42 @@ SET_TYPE_PROP(Henry1p2cProblem, Henry1p2cSpatialParams); //Define whether mole(true) or mass (false) fractions are used -SET_BOOL_PROP(Henry1p2cProblem, UseMoles, false); -SET_BOOL_PROP(Henry1p2cProblem, ProblemEnableGravity, true); +SET_BOOL_PROP(Henry1p2cProblem, UseMoles, true); + } template -class Henry1p2cProblem : public PorousMediumFlowProblem +class Henry1p2cProblem : public PorousMediumFlowProblem { - using ParentType = PorousMediumFlowProblem; + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); + using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); using Element = typename GridView::template Codim<0>::Entity; using ElementIterator = typename GridView::template Codim<0>::Iterator; + using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector); // copy some indices for convenience using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; + using ParentType = PorousMediumFlowProblem; // Grid and world dimension static constexpr int dim = GridView::dimension; static constexpr int dimWorld = GridView::dimensionworld; - // indices of the primary variables - static constexpr int pressureIdx = Indices::pressureIdx; - static constexpr int massOrMoleFracIdx = Indices::massOrMoleFracIdx; - // indices of the equations static constexpr int conti0EqIdx = Indices::conti0EqIdx; static constexpr int transportEqIdx = Indices::transportEqIdx; - using GlobalPosition = Element::Geometry::GlobalCoordinate; - + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - // TODO: Are vertex and Intersection now in another class included? - using Vertex = typename GridView::template Codim::Entity; - using Intersection = typename GridView::Intersection; + using Vertex = typename GridView::template Codim::Entity; + using Intersection = typename GridView::Intersection; public: Henry1p2cProblem(std::shared_ptr fvGridGeometry) @@ -117,14 +115,6 @@ public: */ // \{ - /*! - * \brief The problem name. - * - * This is used as a prefix for files generated by the simulation. - */ - std::string name() const - { return "Henry1p2c"; } - /*! * \brief Returns the temperature within the domain. * @@ -144,12 +134,10 @@ public: * \brief Specifies which kind of boundary condition should be * used for which equation on a given boundary segment. */ - BoundaryTypes boundaryTypes(const Vertex &vertex) const + BoundaryTypes boundaryTypesAtPos(const GlobalPosition &globalPos) const { BoundaryTypes values; - const GlobalPosition globalPos = vertex.geometry().center(); - values.setAllDirichlet(); if(globalPos[0]1-eps_) @@ -166,16 +154,14 @@ public: * * For this method, the \a values parameter stores primary variables. */ - PrimaryVariables dirichlet( const Vertex &vertex) const + PrimaryVariables dirichletAtPos(const GlobalPosition &globalPos) const { PrimaryVariables values; - const GlobalPosition globalPos = vertex.geometry().center(); - initial_(values, globalPos); if(globalPos[0]>2-eps_ && globalPos[1]<0.8+eps_) { - values[massOrMoleFracIdx] = 0.03922; + values[FluidSystem::SaltIdx] = 0.03922; } return values; @@ -189,16 +175,9 @@ public: * in normal direction of each component. Negative values mean * influx. */ - PrimaryVariables neumann(const Element &element, - const FVElementGeometry &fvElemGeom, - const Intersection &is, - int scvIdx, - int boundaryFaceIdx) const + PrimaryVariables neumannAtPos(const GlobalPosition &globalPos) const { - PrimaryVariables values; - - const GlobalPosition &globalPos = element.geometry().corner(scvIdx); - values = 0; + PrimaryVariables values(0.0); if(globalPos[0] -class Henry1p2cSpatialParams : public PorousMediumFlowProblem +class Henry1p2cSpatialParams : public FVSpatialParams > { - using ParentType = PorousMediumFlowProblem; + using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using ParentType = FVSpatialParams >; using Grid = typename GET_PROP_TYPE(TypeTag, Grid); using GridView = typename GET_PROP_TYPE(TypeTag, GridView); - using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using CoordScalar = typename Grid::ctype; using Vector = Dune::FieldVector; - using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; using Element = typename GridView::template Codim<0>::Entity; static constexpr int dim=GridView::dimension; static constexpr int dimWorld=GridView::dimensionworld; @@ -57,8 +60,10 @@ class Henry1p2cSpatialParams : public PorousMediumFlowProblem using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector); public: - Henry1p2cSpatialParams(const GridView &gv) - : ParentType(gv) + using PermeabilityType = Scalar; + + Henry1p2cSpatialParams(std::shared_ptr fvGridGeometry) + : ParentType(fvGridGeometry) { // intrinsic permeabilities perm_ = 1.019368e-9; @@ -85,29 +90,21 @@ public: }; /*! - * \brief Define the intrinsic permeability \f$[m^2]\f$. + * \brief Define the intrinsic permeability \f$\mathrm{[m^2]}\f$. * - * \param element The current finite element - * \param fvElemGeom The current finite volume geometry of the element - * \param scvIdx The index of the sub-control volume + * \param globalPos The global position */ - const Scalar intrinsicPermeability(const Element &element, - const FVElementGeometry &fvElemGeom, - int scvIdx) const + PermeabilityType permeabilityAtPos(const GlobalPosition& globalPos) const { return perm_; } /*! - * \brief Define the porosity \f$[-]\f$. + * \brief Define the porosity \f$\mathrm{[-]}\f$. * - * \param element The finite element - * \param fvElemGeom The finite volume geometry - * \param scvIdx The local index of the sub-control volume where + * \param globalPos The global position */ - double porosity(const Element &element, - const FVElementGeometry &fvElemGeom, - int scvIdx) const + double porosityAtPos(const GlobalPosition& globalPos) const { return porosity_; } -- GitLab From 78eef445930e2754685a6f0b788883d3c6d62846 Mon Sep 17 00:00:00 2001 From: Kai Wendel Date: Mon, 6 Aug 2018 13:22:53 +0200 Subject: [PATCH 03/60] update henry2p, new version seems to work better --- .../henry1p2c/watersaltfluidsystem.hh | 41 +++++++-- lecture/mm/henryproblem/henry2p/henry2p.cc | 58 ++++++------ lecture/mm/henryproblem/henry2p/henry2p.input | 4 +- .../mm/henryproblem/henry2p/henry2pproblem.hh | 80 +++++++--------- .../henry2p/henry2pspatialparams.hh | 91 ++++++++----------- .../henryproblem/henry2p/simplesaltwater.hh | 6 +- 6 files changed, 140 insertions(+), 140 deletions(-) diff --git a/lecture/mm/henryproblem/henry1p2c/watersaltfluidsystem.hh b/lecture/mm/henryproblem/henry1p2c/watersaltfluidsystem.hh index b604693..c70d81e 100644 --- a/lecture/mm/henryproblem/henry1p2c/watersaltfluidsystem.hh +++ b/lecture/mm/henryproblem/henry1p2c/watersaltfluidsystem.hh @@ -1,4 +1,4 @@ -// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + // -*- 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. * @@ -59,10 +59,9 @@ template class WaterSalt : public BaseFluidSystem > { - using ThisType = Dumux::Components::WaterSalt; + using ThisType = WaterSalt; using Base = BaseFluidSystem; - using H2O_IAPWS = Dumux::Components::H2O; - using H2O_IAPWS = Dumux::Components::H2O; + using H2O = Dumux::Components::H2O; public: /**************************************** @@ -197,6 +196,32 @@ public: {} + using Base::molarDensity; + /*! + * \brief The molar density \f$\rho_{mol,\alpha}\f$ + * of a fluid phase \f$\alpha\f$ in \f$\mathrm{[mol/m^3]}\f$ + * + * The molar density for the simple relation is defined by the + * mass density \f$\rho_\alpha\f$ and the molar mass of the main component + * + * The molar density for the complrex relation is defined by the + * mass density \f$\rho_\alpha\f$ and the mean molar mass \f$\overline M_\alpha\f$: + * + * \f[\rho_{mol,\alpha} = \frac{\rho_\alpha}{\overline M_\alpha} \;.\f] + */ + template + static Scalar molarDensity(const FluidState &fluidState, int phaseIdx) + { + assert(0 <= phaseIdx && phaseIdx < numPhases); + + Scalar T = fluidState.temperature(phaseIdx); + Scalar p = fluidState.pressure(phaseIdx); + + // assume pure water or that each gas molecule displaces exactly one + // molecule in the liquid. + return H2O::liquidMolarDensity(T, p); + } + /*! * \brief Return the phase density [kg/m^3]. * @@ -480,14 +505,14 @@ template class WaterSaltFluidSystem : public FluidSystems::WaterSalt { - typedef typename GET_PROP_TYPE(TypeTag, PTAG(Scalar)) Scalar; - typedef WaterSaltFluidSystem ThisType; + using Scalar = typename GET_PROP_TYPE(TypeTag, PTAG(Scalar)); + using ThisType = WaterSaltFluidSystem; // typedef typename FluidSystems::WaterSalt WaterSalt1; // typedef BaseFluidSystem Base; -public: typedef Dumux::NullParameterCache ParameterCache; +public: using ParameterCache = Dumux::NullParameterCache; // typedef BaseFluidSystem Base; @@ -517,7 +542,7 @@ public: typedef Dumux::NullParameterCache ParameterCache; // assert(0 <= compIIdx && compIIdx < numComponents); // assert(0 <= compJIdx && compJIdx < numComponents); Scalar diffusionCoefficient_; - diffusionCoefficient_ = GET_RUNTIME_PARAM(TypeTag, Scalar, Problem.diffusionCoefficient); + diffusionCoefficient_ = getParam("Problem.diffusionCoefficient"); return diffusionCoefficient_;//1.2e-9;//6.6e-6; // in [m^2/s] from Mufte modell } diff --git a/lecture/mm/henryproblem/henry2p/henry2p.cc b/lecture/mm/henryproblem/henry2p/henry2p.cc index b47667b..1d98beb 100644 --- a/lecture/mm/henryproblem/henry2p/henry2p.cc +++ b/lecture/mm/henryproblem/henry2p/henry2p.cc @@ -21,9 +21,31 @@ * * \brief test for the two-phase box model */ -#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include #include "henry2pproblem.hh" -#include /*! * \brief Provides an interface for customizing error messages associated with @@ -78,16 +100,15 @@ int main(int argc, char** argv) try 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(); + GridManager gridManager; + gridManager.init(); //////////////////////////////////////////////////////////// // run instationary non-linear problem on this grid //////////////////////////////////////////////////////////// // we compute on the leaf grid view - const auto& leafGridView = GridCreator::grid().leafGridView(); + const auto& leafGridView = gridManager.grid().leafGridView(); // create the finite volume grid geometry using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); @@ -112,7 +133,6 @@ int main(int argc, char** argv) try // get some time loop parameters using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); const auto tEnd = getParam("TimeLoop.TEnd"); - const auto maxDivisions = getParam("TimeLoop.MaxTimeStepDivisions"); // Q: What is this? Do we need this here? const auto maxDt = getParam("TimeLoop.MaxTimeStepSize"); auto dt = getParam("TimeLoop.DtInitial"); @@ -123,7 +143,7 @@ int main(int argc, char** argv) try // intialize the vtk output module using VtkOutputFields = typename GET_PROP_TYPE(TypeTag, VtkOutputFields); - VtkOutputModule vtkWriter(*problem, *fvGridGeometry, *gridVariables, x, problem->name()); + VtkOutputModule vtkWriter(*gridVariables, x, problem->name()); VtkOutputFields::init(vtkWriter); //!< Add model specific output fields vtkWriter.write(0.0); @@ -149,24 +169,8 @@ int main(int argc, char** argv) try // 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."); - } + // solve the non-linear system with time step control + nonLinearSolver.solve(x, *timeLoop); // make the new solution the old solution xOld = x; @@ -181,7 +185,7 @@ int main(int argc, char** argv) try // report statistics of this time step timeLoop->reportTimeStep(); - // set new dt as suggested by the Newton solver + // set new dt as suggested by the newton solver timeLoop->setTimeStepSize(nonLinearSolver.suggestTimeStepSize(timeLoop->timeStepSize())); } while (!timeLoop->finished()); diff --git a/lecture/mm/henryproblem/henry2p/henry2p.input b/lecture/mm/henryproblem/henry2p/henry2p.input index da357c4..4cdb58b 100644 --- a/lecture/mm/henryproblem/henry2p/henry2p.input +++ b/lecture/mm/henryproblem/henry2p/henry2p.input @@ -3,7 +3,7 @@ [TimeLoop] DtInitial = 2.5 # [s] TEnd =1e12 # [s] -#MaxTimeStepSize = 1e9 +MaxTimeStepSize = 1e9 EpisodeLength = 1.e9 # [s] [Grid] @@ -11,4 +11,4 @@ File = ./grids/henry.dgf [Problem] freshWaterFluxRate = 6.6E-2 # [kg/sm^2] fresh water flux rate at the left boundary (6.6E-2) - +Name = Henry2p diff --git a/lecture/mm/henryproblem/henry2p/henry2pproblem.hh b/lecture/mm/henryproblem/henry2p/henry2pproblem.hh index a15de78..7f23bbd 100644 --- a/lecture/mm/henryproblem/henry2p/henry2pproblem.hh +++ b/lecture/mm/henryproblem/henry2p/henry2pproblem.hh @@ -23,12 +23,18 @@ * water saturated medium. */ +/* + * Note: In the new Dumux this problem uses much more time steps, it seems like the solver does not converge very good and therefor it makes the time steps smaller. + * The end results resp. the stationary state do look the same in both versions. In the new version one can see how the systems approaches the steady state so maybe in the new version a few errors are fixed. + */ + #ifndef DUMUX_HENRY2PPROBLEM_HH #define DUMUX_HENRY2PPROBLEM_HH #include #include "simplesaltwater.hh" +#include #include #include @@ -47,7 +53,7 @@ class Henry2pProblem; ////////// namespace Properties { -NEW_TYPE_TAG(Henry2pProblem, INHERITS_FROM(BoxTwoP, Henry2pSpatialParams)); +NEW_TYPE_TAG(Henry2pProblem, INHERITS_FROM(TwoP, BoxModel)); // Set the grid type SET_TYPE_PROP(Henry2pProblem, Grid, Dune::YaspGrid<2>); @@ -55,24 +61,18 @@ SET_TYPE_PROP(Henry2pProblem, Grid, Dune::YaspGrid<2>); // Set the problem property SET_TYPE_PROP(Henry2pProblem, Problem, Henry2pProblem); +// Set the spatial parameters +SET_TYPE_PROP(Henry2pProblem, SpatialParams, Dumux::Henry2pSpatialParams); + // TODO: remove this macro switch #if 1 -// Set the wetting phase -SET_PROP(Henry2pProblem, WettingPhase) -{ -private: - using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); -public: - using type = Dumux::FluidSystems::LiquidPhase >; -}; - -// Set the non-wetting phase -SET_PROP(Henry2pProblem, NonwettingPhase) +// Set the fluid system +SET_PROP(Henry2pProblem, FluidSystem) { -private: using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); -public: - using type = FluidSystems::LiquidPhase >; + using WettingPhase = FluidSystems::OnePLiquid >; + using NonwettingPhase = FluidSystems::OnePLiquid >; + using type = FluidSystems::TwoPImmiscible; }; #else // OR: set the fluid system @@ -82,8 +82,8 @@ SET_TYPE_PROP(Henry2pProblem, FluidSystem, H2ON2FluidSystem); // SET_BOOL_PROP(Henry2pProblem, NewtonWriteConvergence, false); // Use forward differences instead of central differences -SET_INT_PROP(Henry2pProblem, ImplicitNumericDifferenceMethod, +1); -SET_SCALAR_PROP(Henry2pProblem, ImplicitMassUpwindWeight, 0.5); +// SET_INT_PROP(Henry2pProblem, ImplicitNumericDifferenceMethod, +1); +// SET_SCALAR_PROP(Henry2pProblem, ImplicitMassUpwindWeight, 0.5); } @@ -94,24 +94,23 @@ class Henry2pProblem : public PorousMediumFlowProblem using ParentType = PorousMediumFlowProblem; using GridView = typename GET_PROP_TYPE(TypeTag, GridView); using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - + using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; - + using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector); using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); - using WettingPhase = typename GET_PROP_TYPE(TypeTag, WettingPhase); - using NonwettingPhase = typename GET_PROP_TYPE(TypeTag, NonwettingPhase); + //using WettingPhase = typename GET_PROP_TYPE(TypeTag, WettingPhase); + //using NonwettingPhase = typename GET_PROP_TYPE(TypeTag, NonwettingPhase); // primary variable indices static constexpr int pressureIdx = Indices::pressureIdx; - static constexpr int snIdx = Indices::snIdx; + static constexpr int saturationIdx = Indices::saturationIdx; // equation indices - static constexpr int contiNEqIdx = Indices::contiNEqIdx; - static constexpr int contiWEqIdx = Indices::contiWEqIdx; + static constexpr int conti0EqIdx = Indices::conti0EqIdx; // phase indices - static constexpr int wPhaseIdx = Indices::wPhaseIdx; - static constexpr int nPhaseIdx = Indices::nPhaseIdx; + static constexpr int wPhaseIdx = Indices::Phase0Idx; + static constexpr int nPhaseIdx = Indices::Phase1Idx; // Grid and world dimension static constexpr int dim = GridView::dimension; @@ -131,16 +130,12 @@ public: * \param timeManager The time manager * \param gridView The grid view */ - Henry2pProblem(std::shared_ptr fvGridGeometry - : ParentType(fvgridGeometry) + Henry2pProblem(std::shared_ptr fvGridGeometry) + : ParentType(fvGridGeometry) { eps_ = 3e-6; temperature_ = 273.15 + 20; // -> 20°C freshWaterFluxRate_= getParam("Problem.freshWaterFluxRate"); - - episodeLength_ = getParam("TimeManager.EpisodeLength"); - - } /*! @@ -148,14 +143,6 @@ public: */ // \{ - /*! - * \brief The problem name. - * - * This is used as a prefix for files generated by the simulation. - */ - std::string name() const - { return "Henry2p"; } - /*! * \brief Called directly after the time integration. */ @@ -237,16 +224,16 @@ public: { Scalar densityB = 1025; values[pressureIdx] = 1.0133e5+(depthBOR_-globalPos[1]-0.2)*densityB*9.81+1000*9.81*0.2; - values[snIdx] = 1.0; + values[saturationIdx] = 1.0; } else { // Scalar densityW = 1000; // // hydrostatic pressure // values[pressureIdx] = 1.0133e5+(depthBOR_-globalPos[1])*densityW*9.81; -// values[snIdx] = 0.0; +// values[saturationIdx] = 0.0; Scalar densityB = 1025; values[pressureIdx] = 1.0133e5+(depthBOR_-globalPos[1]-0.2)*densityB*9.81+1000*9.81*0.2; - values[snIdx] = 0.0; + values[saturationIdx] = 0.0; } } @@ -270,7 +257,7 @@ public: values = 0.0; if (onLeftBoundary_(globalPos)) { - values[contiWEqIdx] = -freshWaterFluxRate_;//-6.6E-2;// kg / (m * s) + values[conti0EqIdx] = -freshWaterFluxRate_;//-6.6E-2;// kg / (m * s) } return values; @@ -300,13 +287,13 @@ public: { Scalar densityB = 1025; values[pressureIdx] = 1.0133e5+(depthBOR_-globalPos[1]-0.2)*densityB*9.81+1000*9.81*0.2; - values[snIdx] = 0.0; + values[saturationIdx] = 0.0; } else { Scalar densityW = 1000; values[pressureIdx] = 1.0133e5+(depthBOR_-globalPos[1])*densityW*9.81; - values[snIdx] = 0.0; + values[saturationIdx] = 0.0; } return values; @@ -339,7 +326,6 @@ private: static constexpr Scalar depthBOR_ = 1.0; Scalar temperature_; Scalar eps_; - Scalar episodeLength_; Scalar freshWaterFluxRate_; }; } //end namespace diff --git a/lecture/mm/henryproblem/henry2p/henry2pspatialparams.hh b/lecture/mm/henryproblem/henry2p/henry2pspatialparams.hh index 396be84..5e7156d 100644 --- a/lecture/mm/henryproblem/henry2p/henry2pspatialparams.hh +++ b/lecture/mm/henryproblem/henry2p/henry2pspatialparams.hh @@ -25,70 +25,50 @@ #ifndef DUMUX_LENS_SPATIAL_PARAMS_HH #define DUMUX_LENS_SPATIAL_PARAMS_HH -#include +#include #include #include #include -#include +#include namespace Dumux { -//forward declaration -template -class Henry2pSpatialParams; - -namespace Properties -{ -// The spatial parameters TypeTag -NEW_TYPE_TAG(Henry2pSpatialParams); - -// Set the spatial parameters -SET_TYPE_PROP(Henry2pSpatialParams, SpatialParams, Dumux::Henry2pSpatialParams); - -// Set the material Law -SET_PROP(Henry2pSpatialParams, MaterialLaw) -{ -private: - // define the material law which is parameterized by effective - // saturations - using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - using EffectiveLaw = LinearMaterial; -public: - // define the material law parameterized by absolute saturations - using type = EffToAbsLaw; -}; -} /*! * \ingroup TwoPBoxModel * \ingroup BoxTestProblems * \brief The spatial parameters for the Henry2pProblem which uses the * twophase box model */ -template -class Henry2pSpatialParams : public FVSpatialParamsTwoP> +template +class Henry2pSpatialParams : public FVSpatialParams> { - using ThisType = Henry2pSpatialParams; + using ThisType = Henry2pSpatialParams; + using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); using ParentType = FVSpatialParams; using Grid = typename GET_PROP_TYPE(TypeTag, Grid); using GridView = typename GET_PROP_TYPE(TypeTag, GridView); - using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using CoordScalar = typename Grid::ctype; using Element = typename GridView::template Codim<0>::Entity; - using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; static constexpr int dim=GridView::dimension; static constexpr int dimWorld=GridView::dimensionworld; using GlobalPosition = typename Element::Geometry::GlobalCoordinate; public: + using PermeabilityType = Scalar; + //get the material law from the property system - using MaterialLaw = typename GET_PROP_TYPE(TypeTag, MaterialLaw) + using EffectiveLaw = LinearMaterial; + using MaterialLaw = EffToAbsLaw; using MaterialLawParams = typename MaterialLaw::Params; - Henry2pSpatialParams(const GridView& gridView) - : ParentType(gridView) + Henry2pSpatialParams(std::shared_ptr fvGridGeometry) + : ParentType(fvGridGeometry) { try { @@ -116,32 +96,24 @@ public: } /*! - * \brief Intrinsic permability + * \brief Define the intrinsic permeability \f$\mathrm{[m^2]}\f$. * - * \param element The current element - * \param fvElemGeom The current finite volume geometry of the element - * \param scvIdx The index of the sub-control volume. - * \return Intrinsic permeability + * \param globalPos The global position */ - Scalar intrinsicPermeability(const Element &element, - const FVElementGeometry &fvElemGeom, - int scvIdx) const + PermeabilityType permeabilityAtPos(const GlobalPosition& globalPos) const { return K_; } /*! - * \brief Porosity + * \brief Define the porosity \f$\mathrm{[-]}\f$. * - * \param element The current element - * \param fvElemGeom The current finite volume geometry of the element - * \param scvIdx The index of the sub-control volume. - * \return Porosity + * \param globalPos The global position */ - Scalar porosity(const Element &element, - const FVElementGeometry &fvElemGeom, - int scvIdx) const - { return porosity_; } + double porosityAtPos(const GlobalPosition& globalPos) const + { + return porosity_; + } /*! * \brief Function for defining the parameters needed by constitutive relationships (kr-sw, pc-sw, etc.). @@ -151,13 +123,22 @@ public: * \param scvIdx The index of the sub-control volume. * \return the material parameters object */ - const MaterialLawParams& materialLawParams(const Element &element, - const FVElementGeometry &fvElemGeom, - int scvIdx) const + const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const { return materialParams_; } + /*! + * \brief Function for defining which phase is to be considered as the wetting phase. + * + * \return the wetting phase index + * \param globalPos The global position + */ + template + int wettingPhaseAtPos(const GlobalPosition& globalPos) const + { + return FluidSystem::phase0Idx; + } private: diff --git a/lecture/mm/henryproblem/henry2p/simplesaltwater.hh b/lecture/mm/henryproblem/henry2p/simplesaltwater.hh index 07b5e7d..088bc3f 100644 --- a/lecture/mm/henryproblem/henry2p/simplesaltwater.hh +++ b/lecture/mm/henryproblem/henry2p/simplesaltwater.hh @@ -42,7 +42,9 @@ namespace Dumux * \tparam Scalar The type used for scalar values */ template -class SimpleSaltwater : public Component > +class SimpleSaltwater : public Dumux::Components::Base > +, public Components::Liquid > +, public Components::Gas > { typedef Dumux::IdealGas IdealGas; @@ -231,6 +233,8 @@ public: */ static Scalar liquidDensity(Scalar temperature, Scalar pressure) { return 1025.; } + static Scalar liquidMolarDensity(Scalar temperature, Scalar pressure) + { return liquidDensity(temperature, pressure)/molarMass(); } /*! * \brief The pressure of water in \f$\mathrm{[Pa]}\f$ at a given density and temperature. -- GitLab From 239305eaac65c1ec53b7ad0e68a2ba5589c1c579 Mon Sep 17 00:00:00 2001 From: Kai Wendel Date: Mon, 13 Aug 2018 12:54:31 +0200 Subject: [PATCH 04/60] update to Dumux3. Scripts have errors supposedly in the TypeTag System --- .../mm/columnxylene/columnxyleneexercise.cc | 36 +- .../columnxylene/columnxyleneexercise.input | 2 +- .../mm/columnxylene/columnxyleneproblem.hh | 39 +- .../mm/columnxylene/columnxyleneproblem2.hh | 39 +- .../columnxylene/columnxylenespatialparams.hh | 109 +++-- .../columnxylenespatialparams2.hh | 25 +- .../mm/heavyoil/3p/parkervangenuchtenzero.hh | 4 +- .../parkervangenuchtenzerohysteresisparams.hh | 2 +- .../3p/parkervangenuchtenzeroparams.hh | 2 +- .../3p/relativepermeabilityhysteresis.hh | 4 +- .../relativepermeabilityhysteresisparams.hh | 2 +- lecture/mm/heavyoil/sagd/problem.hh | 416 +++++------------- lecture/mm/heavyoil/sagd/sagd.cc | 79 ++-- lecture/mm/heavyoil/sagd/spatialparams.hh | 189 +++----- 14 files changed, 353 insertions(+), 595 deletions(-) diff --git a/lecture/mm/columnxylene/columnxyleneexercise.cc b/lecture/mm/columnxylene/columnxyleneexercise.cc index 55c48df..01bd9fb 100644 --- a/lecture/mm/columnxylene/columnxyleneexercise.cc +++ b/lecture/mm/columnxylene/columnxyleneexercise.cc @@ -23,8 +23,29 @@ */ #include "config.h" #include "columnxyleneproblem.hh" -// #include "columnxyleneproblem2.hh" -#include + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + /*! @@ -62,7 +83,7 @@ int main(int argc, char** argv) try using namespace Dumux; // define the type tag for this problem - using TypeTag = TTAG(ColumnProblem); + using TypeTag = TTAG(ColumnProblemBoxTypeTag); // initialize MPI, finalize is done automatically on exit const auto& mpiHelper = Dune::MPIHelper::instance(argc, argv); @@ -75,20 +96,19 @@ int main(int argc, char** argv) try 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(); + GridManager gridManager; + gridManager.init(); //////////////////////////////////////////////////////////// // run instationary non-linear problem on this grid //////////////////////////////////////////////////////////// // we compute on the leaf grid view - const auto& leafGridView = GridCreator::grid().leafGridView(); + const auto& leafGridView = gridManager.grid().leafGridView(); // create the finite volume grid geometry using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); - auto fvGridGeometry = std::make_shared(leafGridView); + auto fvGridGeometry = std::make_shared(leafGridView); fvGridGeometry->update(); // the problem (initial and boundary conditions) diff --git a/lecture/mm/columnxylene/columnxyleneexercise.input b/lecture/mm/columnxylene/columnxyleneexercise.input index 52a8647..4f9e042 100644 --- a/lecture/mm/columnxylene/columnxyleneexercise.input +++ b/lecture/mm/columnxylene/columnxyleneexercise.input @@ -9,7 +9,7 @@ MaxTimeStepSize = 1 [Grid] File = ./grids/column.dgf -[] +[SpatialParams] steamFlux = -0.39571 # [mol / (s m)] enthalpyFlux = -17452.97 # [J / (s m)] permeability = 1.4e-11 # [m^2] diff --git a/lecture/mm/columnxylene/columnxyleneproblem.hh b/lecture/mm/columnxylene/columnxyleneproblem.hh index fb02ed0..59575f3 100644 --- a/lecture/mm/columnxylene/columnxyleneproblem.hh +++ b/lecture/mm/columnxylene/columnxyleneproblem.hh @@ -27,9 +27,12 @@ #define DUMUX_COLUMNXYLENEPROBLEM_HH #include +#include +#include +#include -#include -#include +#include +#include #include "columnxylenespatialparams.hh" @@ -42,7 +45,10 @@ class ColumnProblem; namespace Properties { -NEW_TYPE_TAG(ColumnProblem, INHERITS_FROM(BoxThreePThreeCNI, ColumnSpatialParams)); +NEW_TYPE_TAG(ColumnProblem, INHERITS_FROM(ThreePThreeCNI, ColumnSpatialParams)); + +NEW_TYPE_TAG(ColumnProblemBoxTypeTag, INHERITS_FROM(BoxModel, ColumnProblem)); +// NEW_TYPE_TAG(ColumnProblemCCTpfaTypeTag, INHERITS_FROM(CCTpfaModel, ColumnProblem)); // Set the grid type SET_TYPE_PROP(ColumnProblem, Grid, Dune::YaspGrid<2>); @@ -56,7 +62,7 @@ SET_TYPE_PROP(ColumnProblem, FluidSystems::H2OAirXylene); // Maximum tolerated relative error in the Newton method -SET_SCALAR_PROP(ColumnProblem, NewtonMaxRelativeShift, 1e-4); + } @@ -74,23 +80,20 @@ class ColumnProblem : public PorousMediumFlowProblem using Grid = typename GridView::Grid; // copy some indices for convenience - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; + using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; - enum { - - pressureIdx = Indices::pressureIdx, - switch1Idx = Indices::switch1Idx, - switch2Idx = Indices::switch2Idx, - temperatureIdx = Indices::temperatureIdx, - energyEqIdx = Indices::energyEqIdx, + static constexpr int pressureIdx = Indices::pressureIdx; + static constexpr int switch1Idx = Indices::switch1Idx; + static constexpr int switch2Idx = Indices::switch2Idx; + static constexpr int temperatureIdx = Indices::temperatureIdx; + static constexpr int energyEqIdx = Indices::energyEqIdx; // Phase State - threePhases = Indices::threePhases, + static constexpr int threePhases = Indices::threePhases; // Grid and world dimension - dim = GridView::dimension, - dimWorld = GridView::dimensionworld - }; + static constexpr int dim = GridView::dimension; + static constexpr int dimWorld = GridView::dimensionworld; using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); @@ -99,9 +102,9 @@ class ColumnProblem : public PorousMediumFlowProblem using Vertex = typename GridView::template Codim::Entity; using Intersection = typename GridView::Intersection; - using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); - + using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector); using GlobalPosition = Dune::FieldVector; public: diff --git a/lecture/mm/columnxylene/columnxyleneproblem2.hh b/lecture/mm/columnxylene/columnxyleneproblem2.hh index d812a5e..427d5e5 100644 --- a/lecture/mm/columnxylene/columnxyleneproblem2.hh +++ b/lecture/mm/columnxylene/columnxyleneproblem2.hh @@ -34,8 +34,8 @@ #include -#include -#include +#include +#include #include "columnxylenespatialparams2.hh" @@ -87,34 +87,31 @@ class ColumnProblem : public PorousMediumFlowProblem // copy some indices for convenience using Indices = typename GET_PROP_TYPE(TypeTag, Indices); - enum { - - pressureIdx = Indices::pressureIdx, - switch1Idx = Indices::switch1Idx, - switch2Idx = Indices::switch2Idx, - temperatureIdx = Indices::temperatureIdx, - energyEqIdx = Indices::energyEqIdx, + static constexpr int pressureIdx = Indices::pressureIdx; + static constexpr int switch1Idx = Indices::switch1Idx; + static constexpr int switch2Idx = Indices::switch2Idx; + static constexpr int temperatureIdx = Indices::temperatureIdx; + static constexpr int energyEqIdx = Indices::energyEqIdx; // Phase State - threePhases = Indices::threePhases, + static constexpr int threePhases = Indices::threePhases; // Grid and world dimension - dim = GridView::dimension, - dimWorld = GridView::dimensionworld - }; + static constexpr int dim = GridView::dimension; + static constexpr int dimWorld = GridView::dimensionworld; using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GridView::template Codim::Entity Vertex; - typedef typename GridView::Intersection Intersection; + using Element = typename GridView::template Codim<0>::Entity; + using Vertex = typename GridView::template Codim::Entity; + using Intersection = typename GridView::Intersection; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; + using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); - typedef Dune::FieldVector GlobalPosition; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; public: /*! @@ -123,8 +120,8 @@ public: * \param timeManager The time manager * \param gridView The grid view */ - ColumnProblem(TimeManager &timeManager, const GridView &gridView) - : ParentType(timeManager, gridView), eps_(1e-6) + ColumnProblem(std::shared_ptr fvGridGeometry) + : ParentType(fvGridGeometry) eps_(1e-6) { FluidSystem::init(); } diff --git a/lecture/mm/columnxylene/columnxylenespatialparams.hh b/lecture/mm/columnxylene/columnxylenespatialparams.hh index 0b4550e..4c7ff03 100644 --- a/lecture/mm/columnxylene/columnxylenespatialparams.hh +++ b/lecture/mm/columnxylene/columnxylenespatialparams.hh @@ -24,8 +24,9 @@ #ifndef DUMUX_COLUMNXYLENE_SPATIAL_PARAMS_HH #define DUMUX_COLUMNXYLENE_SPATIAL_PARAMS_HH -#include -#include +#include +#include +#include #include #include #include @@ -45,16 +46,6 @@ NEW_TYPE_TAG(ColumnSpatialParams); // Set the spatial parameters SET_TYPE_PROP(ColumnSpatialParams, SpatialParams, Dumux::ColumnSpatialParams); -// Set the material Law -SET_PROP(ColumnSpatialParams, MaterialLaw) -{ - private: - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef RegularizedParkerVanGen3P EffectiveLaw; - public: - // define the material law parameterized by absolute saturations - typedef EffToAbsLaw type; -}; } /*! @@ -63,89 +54,91 @@ SET_PROP(ColumnSpatialParams, MaterialLaw) * \brief Definition of the spatial parameters for the column problem */ template -class ColumnSpatialParams : public ImplicitSpatialParams +class ColumnSpatialParams : public FVSpatialParams > { - typedef ImplicitSpatialParams ParentType; - - typedef typename GET_PROP_TYPE(TypeTag, Grid) Grid; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename Grid::ctype CoordScalar; - enum { - dim=GridView::dimension, - dimWorld=GridView::dimensionworld - }; + using ParentType = FVSpatialParams >; - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum { - wPhaseIdx = Indices::wPhaseIdx, - nPhaseIdx = Indices::nPhaseIdx - }; + using Grid = typename GET_PROP_TYPE(TypeTag, Grid); + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using CoordScalar = typename Grid::ctype; + using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; + using Element = typename GridView::template Codim<0>::Entity; + + static constexpr int dim=GridView::dimension; + static constexpr int dimWorld=GridView::dimensionworld; - typedef Dune::FieldVector GlobalPosition; - typedef Dune::FieldVector Vector; + using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; + static constexpr int wPhaseIdx = Indices::wPhaseIdx; + static constexpr int nPhaseIdx = Indices::nPhaseIdx; - typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + using Vector = Dune::FieldVector; - typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GridView::template Codim<0>::Entity Element; + using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector); + using FluxVariables = typename GET_PROP_TYPE(TypeTag, FluxVariables); + using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView; public: - typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw; - typedef typename MaterialLaw::Params MaterialLawParams; + using EffectiveLaw = RegularizedParkerVanGen3P; + using MaterialLaw = EffToAbsLaw; + using MaterialLawParams = typename MaterialLaw::Params; /*! * \brief The constructor * * \param gv The grid view */ - ColumnSpatialParams(const GridView &gv) - : ParentType(gv) + ColumnSpatialParams(std::shared_ptr fvGridGeometry) + : ParentType(fvGridGeometry) { // intrinsic permeabilities - fineK_ = GET_RUNTIME_PARAM(TypeTag, Scalar, permeability); - coarseK_ = GET_RUNTIME_PARAM(TypeTag, Scalar, permeabilityExtDomain); + fineK_ = getParam("SpatialParams.permeability"); + coarseK_ = getParam("SpatialParams.permeabilityExtDomain"); // porosities - finePorosity_ = GET_RUNTIME_PARAM(TypeTag, Scalar, porosity); - coarsePorosity_ = GET_RUNTIME_PARAM(TypeTag, Scalar, porosity); + finePorosity_ = getParam("SpatialParams.porosity"); + coarsePorosity_ = getParam("SpatialParams.porosity"); // specific heat capacities fineHeatCap_ = 850.; - coarseHeatCap_ = GET_RUNTIME_PARAM(TypeTag, Scalar, heatCapExtDomain); + coarseHeatCap_ = getParam("SpatialParams.heatCapExtDomain"); // heat conductivity of granite lambdaSolid_ = 2.8; // residual saturations - fineMaterialParams_.setSwr(GET_RUNTIME_PARAM(TypeTag, Scalar, swr)); - fineMaterialParams_.setSnr(GET_RUNTIME_PARAM(TypeTag, Scalar, snr)); - fineMaterialParams_.setSgr(GET_RUNTIME_PARAM(TypeTag, Scalar, Sgr)); - coarseMaterialParams_.setSwr(GET_RUNTIME_PARAM(TypeTag, Scalar, swr)); - coarseMaterialParams_.setSnr(GET_RUNTIME_PARAM(TypeTag, Scalar, snr)); - coarseMaterialParams_.setSgr(GET_RUNTIME_PARAM(TypeTag, Scalar, Sgr)); + fineMaterialParams_.setSwr(getParam("SpatialParams.swr")); + fineMaterialParams_.setSnr(getParam("SpatialParams.snr")); + fineMaterialParams_.setSgr(getParam("SpatialParams.Sgr")); + coarseMaterialParams_.setSwr(getParam("SpatialParams.swr")); + coarseMaterialParams_.setSnr(getParam("SpatialParams.snr")); + coarseMaterialParams_.setSgr(getParam("SpatialParams.Sgr")); // parameters for the 3phase van Genuchten law - fineMaterialParams_.setVgAlpha(GET_RUNTIME_PARAM(TypeTag, Scalar, vanGenuchtenAlpha)); + fineMaterialParams_.setVgAlpha(getParam("SpatialParams.vanGenuchtenAlpha")); coarseMaterialParams_.setVgAlpha(0.5); - fineMaterialParams_.setVgn(GET_RUNTIME_PARAM(TypeTag, Scalar, vanGenuchtenN)); + fineMaterialParams_.setVgn(getParam("SpatialParams.vanGenuchtenN")); coarseMaterialParams_.setVgn(4.0); coarseMaterialParams_.setKrRegardsSnr(false); fineMaterialParams_.setKrRegardsSnr(true); // parameters for the scaling of capillary pressure (GW = 1); - fineMaterialParams_.setBetaNw(GET_RUNTIME_PARAM(TypeTag, Scalar, betaNW)); - fineMaterialParams_.setBetaGn(GET_RUNTIME_PARAM(TypeTag, Scalar, betaGN)); - fineMaterialParams_.setBetaGw(GET_RUNTIME_PARAM(TypeTag, Scalar, betaGW)); - coarseMaterialParams_.setBetaNw(GET_RUNTIME_PARAM(TypeTag, Scalar, betaNW)); - coarseMaterialParams_.setBetaGn(GET_RUNTIME_PARAM(TypeTag, Scalar, betaGN)); - coarseMaterialParams_.setBetaGw(GET_RUNTIME_PARAM(TypeTag, Scalar, betaGW)); + fineMaterialParams_.setBetaNw(getParam("SpatialParams.betaNW")); + fineMaterialParams_.setBetaGn(getParam("SpatialParams.betaGN")); + fineMaterialParams_.setBetaGw(getParam("SpatialParams.betaGW")); + coarseMaterialParams_.setBetaNw(getParam("SpatialParams.betaNW")); + coarseMaterialParams_.setBetaGn(getParam("SpatialParams.betaGN")); + coarseMaterialParams_.setBetaGw(getParam("SpatialParams.betaGW")); // parameters for adsorption coarseMaterialParams_.setKdNAPL(0.); diff --git a/lecture/mm/columnxylene/columnxylenespatialparams2.hh b/lecture/mm/columnxylene/columnxylenespatialparams2.hh index e315d97..48f7650 100644 --- a/lecture/mm/columnxylene/columnxylenespatialparams2.hh +++ b/lecture/mm/columnxylene/columnxylenespatialparams2.hh @@ -29,8 +29,9 @@ #ifndef DUMUX_COLUMNXYLENE_SPATIAL_PARAMS_HH #define DUMUX_COLUMNXYLENE_SPATIAL_PARAMS_HH -#include -#include +#include +#include +#include #include #include #include @@ -50,16 +51,8 @@ NEW_TYPE_TAG(ColumnSpatialParams); // Set the spatial parameters SET_TYPE_PROP(ColumnSpatialParams, SpatialParams, Dumux::ColumnSpatialParams); -// Set the material Law -SET_PROP(ColumnSpatialParams, MaterialLaw) -{ - private: - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef RegularizedParkerVanGen3P EffectiveLaw; - public: - // define the material law parameterized by absolute saturations - typedef EffToAbsLaw type; -}; + + } /*! @@ -105,7 +98,9 @@ class ColumnSpatialParams : public PorousMediumFlowProblem public: - using MaterialLaw = typename GET_PROP_TYPE(TypeTag, MaterialLaw); + + using EffectiveLaw = RegularizedParkerVanGen3P; + using MaterialLaw = EffToAbsLaw; using MaterialLawParams = typename MaterialLaw::Params; /*! @@ -113,8 +108,8 @@ public: * * \param gv The grid view */ - ColumnSpatialParams(const GridView &gv) - : ParentType(gv) + ColumnSpatialParams(std::shared_ptr fvGridGeometry) + : ParentType(fvGridGeometry) { // intrinsic permeabilities fineK_ = GET_RUNTIME_PARAM(TypeTag, Scalar, permeability); diff --git a/lecture/mm/heavyoil/3p/parkervangenuchtenzero.hh b/lecture/mm/heavyoil/3p/parkervangenuchtenzero.hh index 7db55e6..4bca135 100644 --- a/lecture/mm/heavyoil/3p/parkervangenuchtenzero.hh +++ b/lecture/mm/heavyoil/3p/parkervangenuchtenzero.hh @@ -46,8 +46,8 @@ class ParkerVanGenZero3P { public: - typedef ParamsT Params; - typedef typename Params::Scalar Scalar; + using Params = ParamsT; + using Scalar = typename Params::Scalar; /*! * \brief The capillary pressure-saturation curve. diff --git a/lecture/mm/heavyoil/3p/parkervangenuchtenzerohysteresisparams.hh b/lecture/mm/heavyoil/3p/parkervangenuchtenzerohysteresisparams.hh index c26fe58..5841e6d 100644 --- a/lecture/mm/heavyoil/3p/parkervangenuchtenzerohysteresisparams.hh +++ b/lecture/mm/heavyoil/3p/parkervangenuchtenzerohysteresisparams.hh @@ -39,7 +39,7 @@ template class ParkerVanGenZeroHyst3PParams { public: - typedef ScalarT Scalar; + using Scalar = ScalarT; ParkerVanGenZeroHyst3PParams() {betaGw_ = betaNw_ = betaGn_ = 1.;} diff --git a/lecture/mm/heavyoil/3p/parkervangenuchtenzeroparams.hh b/lecture/mm/heavyoil/3p/parkervangenuchtenzeroparams.hh index 1c72f0f..4ce9645 100644 --- a/lecture/mm/heavyoil/3p/parkervangenuchtenzeroparams.hh +++ b/lecture/mm/heavyoil/3p/parkervangenuchtenzeroparams.hh @@ -39,7 +39,7 @@ template class ParkerVanGenZero3PParams { public: - typedef ScalarT Scalar; + using Scalar = ScalarT; ParkerVanGenZero3PParams() {betaGw_ = betaNw_ = betaGn_ = 1.;} diff --git a/lecture/mm/heavyoil/3p/relativepermeabilityhysteresis.hh b/lecture/mm/heavyoil/3p/relativepermeabilityhysteresis.hh index b0649d5..2be5ff0 100644 --- a/lecture/mm/heavyoil/3p/relativepermeabilityhysteresis.hh +++ b/lecture/mm/heavyoil/3p/relativepermeabilityhysteresis.hh @@ -46,8 +46,8 @@ class relativPermHyst3P { public: - typedef ParamsT Params; - typedef typename Params::Scalar Scalar; + using Params = ParamsT; + using Scalar = typename Params::Scalar; //typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; static Scalar pc(const Params ¶ms, Scalar sw) diff --git a/lecture/mm/heavyoil/3p/relativepermeabilityhysteresisparams.hh b/lecture/mm/heavyoil/3p/relativepermeabilityhysteresisparams.hh index 647c084..0f3ac80 100644 --- a/lecture/mm/heavyoil/3p/relativepermeabilityhysteresisparams.hh +++ b/lecture/mm/heavyoil/3p/relativepermeabilityhysteresisparams.hh @@ -39,7 +39,7 @@ template class relativPermHyst3PParams { public: - typedef ScalarT Scalar; + using Scalar = ScalarT; relativPermHyst3PParams() {betaGw_ = betaNw_ = betaGn_ = 1.;} diff --git a/lecture/mm/heavyoil/sagd/problem.hh b/lecture/mm/heavyoil/sagd/problem.hh index 421172d..1836d78 100644 --- a/lecture/mm/heavyoil/sagd/problem.hh +++ b/lecture/mm/heavyoil/sagd/problem.hh @@ -25,48 +25,59 @@ #ifndef DUMUX_SAGDPROBLEM_HH #define DUMUX_SAGDPROBLEM_HH +#include + #include +#include #include + #include +#include +#include + #include "spatialparams.hh" -#define ISOTHERMAL 0 +namespace Dumux { -namespace Dumux -{ +/*! + * \file + * \ingroup ThreePWaterOilTests + * \brief Non-isothermal SAGD problem + */ template class SagdProblem; -namespace Properties -{ -NEW_TYPE_TAG(SagdProblem, INHERITS_FROM(ThreePWaterOilNI, SagdSpatialParams)); -NEW_TYPE_TAG(SagdBoxProblem, INHERITS_FROM(BoxModel, SagdProblem)); -NEW_TYPE_TAG(SagdCCProblem, INHERITS_FROM(CCModel, SagdProblem)); +namespace Properties { +NEW_TYPE_TAG(SagdTypeTag, INHERITS_FROM(ThreePWaterOilNI)); +NEW_TYPE_TAG(ThreePWaterOilSagdBoxTypeTag, INHERITS_FROM(BoxModel, SagdTypeTag)); // Set the grid type -SET_TYPE_PROP(SagdProblem, Grid, Dune::YaspGrid<2>); +SET_TYPE_PROP(SagdTypeTag, Grid, Dune::YaspGrid<2>); // Set the problem property -SET_TYPE_PROP(SagdProblem, Problem, Dumux::SagdProblem); +SET_TYPE_PROP(SagdTypeTag, Problem, Dumux::SagdProblem); + +// Set the spatial parameters +SET_TYPE_PROP(SagdTypeTag, SpatialParams, SagdSpatialParams); // Set the fluid system -SET_TYPE_PROP(SagdProblem, +SET_TYPE_PROP(SagdTypeTag, FluidSystem, - Dumux::FluidSystems::H2OHeavyOil); - + Dumux::FluidSystems::H2OHeavyOil); -// TODO: Do we need the following Properties? -// Use forward differences instead of central differences -SET_INT_PROP(SagdProblem, ImplicitNumericDifferenceMethod, +1); +SET_BOOL_PROP(SagdTypeTag, OnlyGasPhaseCanDisappear, true); -// Write newton convergence -SET_BOOL_PROP(SagdProblem, NewtonWriteConvergence, false); +SET_BOOL_PROP(SagdTypeTag, UseMoles, true); -SET_BOOL_PROP(SagdProblem, UseSimpleModel, true); - -SET_BOOL_PROP(SagdProblem, UseMassOutput, true); -} +// Set the fluid system +SET_PROP(SagdTypeTag, SolidSystem) +{ + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using InertComponent = Components::Constant<1, Scalar>; + using type = SolidSystems::InertSolidPhase; +}; +} // end namespace Properties /*! @@ -81,176 +92,50 @@ template class SagdProblem : public PorousMediumFlowProblem { using ParentType = PorousMediumFlowProblem; - - using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); using GridView = typename GET_PROP_TYPE(TypeTag, GridView); - using Grid = typename GridView::Grid; - - // copy some indices for convenience + using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; + enum { + pressureIdx = Indices::pressureIdx, + switch1Idx = Indices::switch1Idx, + switch2Idx = Indices::switch2Idx, - static constexpr pressureIdx = Indices::pressureIdx; - static constexpr switch1Idx = Indices::switch1Idx; - static constexpr switch2Idx = Indices::switch2Idx; + contiWEqIdx = Indices::conti0EqIdx + FluidSystem::wCompIdx, + contiNEqIdx = Indices::conti0EqIdx + FluidSystem::nCompIdx, + energyEqIdx = Indices::energyEqIdx, - static constexpr energyEqIdx = Indices::energyEqIdx; + // phase indices + wPhaseIdx = FluidSystem::wPhaseIdx, + nPhaseIdx = FluidSystem::nPhaseIdx, - // phase and component indices - static constexpr wPhaseIdx = Indices::Phase0Idx; - static constexpr nPhaseIdx = Indices::Phase1Idx; - static constexpr gPhaseIdx = Indices::Phase2Idx; - static constexpr wCompIdx = Indices::wCompIdx; - static constexpr nCompIdx = Indices::nCompIdx; + // phase state + wnPhaseOnly = Indices::wnPhaseOnly, - // Phase State - static constexpr wPhaseOnly = Indices::wPhaseOnly; - static constexpr wnPhaseOnly = Indices::wnPhaseOnly; - static constexpr wgPhaseOnly = Indices::wgPhaseOnly; - static constexpr threePhases = Indices::threePhases; - - static constexpr int dim = GridView::dimension; - static constexpr int dimWorld = GridView::dimensionworld; - using GlobalPosition = Dune::FieldVector; + // world dimension + dimWorld = GridView::dimensionworld + }; using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); + using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector); + using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView; using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); - - //typedef typename GridView::template Codim<0>::Entity Element; - //typedef typename GridView::template Codim::Entity Vertex; - //typedef typename GridView::Intersection Intersection; - - using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); - using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); - - static constexpr isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox); + using Element = typename GridView::template Codim<0>::Entity; + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; + using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace; + using GlobalPosition = typename SubControlVolumeFace::GlobalPosition; public: - /*! - * \brief The constructor - * - * \param timeManager The time manager - * \param gridView The grid view - */ - - SagdProblem(std::shared_ptr fvGridGeometry) : ParentType(fvGridGeometry) + SagdProblem(std::shared_ptr fvGridGeometry) + : ParentType(fvGridGeometry), pOut_(4e6) { - maxDepth_ = 400.0; // [m] FluidSystem::init(); - totalMassProducedOil_ =0; - totalMassProducedWater_ =0; - - this->timeManager().startNextEpisode(86400); // TODO: correct this - - name_ = getParam("Problem.Name"); - } -/* - bool shouldWriteRestartFile() const - { - return - this->timeManager().timeStepIndex() == 0 || - this->timeManager().timeStepIndex() % 10000 == 0 || - this->timeManager().episodeWillBeFinished() || - this->timeManager().willBeFinished(); - } -*/ - /* bool shouldWriteOutput() const - { - return - this->timeManager().timeStepIndex() == 0 || - this->timeManager().timeStepIndex() % 10000 == 0 || - this->timeManager().episodeWillBeFinished() || - this->timeManager().willBeFinished(); - } -*/ - /*! - * \brief Called directly after the time integration. - */ - -/* - void postTimeStep() - { - double time = this->timeManager().time(); - double dt = this->timeManager().timeStepSize(); - - // Calculate storage terms - PrimaryVariables storage; - this->model().globalStorage(storage); - - // Write mass balance information for rank 0 - if (this->gridView().comm().rank() == 0) - { - std::cout<<"Storage: " << storage << "Time: " << time+dt << std::endl; - massBalance.open ("massBalance.txt", std::ios::out | std::ios::app ); - massBalance << " Storage " << storage - << " Time " << time+dt - << std::endl; - massBalance.close(); - - } - - // Calculate storage terms - PrimaryVariables storageW, storageN; - //Dune::FieldVector flux(0.0); - this->model().globalPhaseStorage(storageW, wPhaseIdx); - this->model().globalPhaseStorage(storageN, nPhaseIdx); - - //mass of Oil - const Scalar newMassProducedOil_ = massProducedOil_; - std::cout<<" newMassProducedOil_ : "<< newMassProducedOil_ << " Time: " << time+dt << std::endl; - - totalMassProducedOil_ += newMassProducedOil_; - std::cout<<" totalMassProducedOil_ : "<< totalMassProducedOil_ << " Time: " << time+dt << std::endl; - //mass of Water - const Scalar newMassProducedWater_ = massProducedWater_; - //std::cout<<" newMassProducedWater_ : "<< newMassProducedWater_ << " Time: " << time+dt << std::endl; - - totalMassProducedWater_ += newMassProducedWater_; - //std::cout<<" totalMassProducedWater_ : "<< totalMassProducedWater_ << " Time: " << time+dt << std::endl; - - - const int timeStepIndex = this->timeManager().timeStepIndex(); - - if (timeStepIndex == 0 || - timeStepIndex % 100 == 0 || //after every 1000000 secs - this->timeManager().episodeWillBeFinished() || - this->timeManager().willBeFinished()) - { - std::cout<<" totalMassProducedOil_ : "<< totalMassProducedOil_ << " Time: " << time+dt << std::endl; - std::cout<<" totalMassProducedWater_ : "<< totalMassProducedWater_ << " Time: " << time+dt << std::endl; - } + totalMassProducedOil_ = 0.0; + totalMassProducedWater_ = 0.0; } -*/ -/* - void episodeEnd() - { - // Start new episode if episode is over - // for first 10 year episode length is 1 year - this->timeManager().startNextEpisode(3600*24*1.); //episode length sent to 1 day - std::cout<<"Episode index is set to: "<timeManager().episodeIndex()< 8.5 + eps_ && globalPos[1] < 9.5 - eps_) + if (globalPos[1] > 8.5 - eps_ && globalPos[1] < 9.5 + eps_) { - values[Indices::contiNEqIdx] = -0.0; - values[Indices::contiWEqIdx] = -0.193;//*0.5; // (55.5 mol*12.5)/3600 mol/s m = 0.193 - values[Indices::energyEqIdx] = -9132;//*0.5; // J/sec m 9132 + values[contiNEqIdx] = -0.0; + values[contiWEqIdx] = -0.193;//*0.5; // (55.5 mol*12.5)/3600 mol/s m = 0.193 + values[energyEqIdx] = -9132;//*0.5; // J/sec m 9132 } - else if (globalPos[1] > 2.5 + eps_ && globalPos[1] < 3.5 - eps_) // production well + else if (globalPos[1] > 2.5 - eps_ && globalPos[1] < 3.5 + eps_) // production well { - //Scalar satWBound = 1.0; - // const Scalar satW = elemVolVars[scvIdx].saturation(wPhaseIdx); // Saturations - // const Scalar satG = elemVolVars[scvIdx].saturation(gPhaseIdx); - // const Scalar satN = elemVolVars[scvIdx].saturation(nPhaseIdx); - - const Scalar elemPressW = elemVolVars[scvIdx].pressure(wPhaseIdx); //Pressures - // const Scalar elemPressG = elemVolVars[scvIdx].pressure(gPhaseIdx); - const Scalar elemPressN = elemVolVars[scvIdx].pressure(nPhaseIdx); - - const Scalar densityW = elemVolVars[scvIdx].fluidState().density(wPhaseIdx); //Densities - // const Scalar densityG = elemVolVars[scvIdx].fluidState().density(gPhaseIdx); - const Scalar densityN = elemVolVars[scvIdx].fluidState().density(nPhaseIdx); - - // const Scalar moDensityW = elemVolVars[scvIdx].fluidState().molarDensity(wPhaseIdx); //Molar Densities - // const Scalar moDensityG = elemVolVars[scvIdx].fluidState().molarDensity(gPhaseIdx); - // const Scalar moDensityN = elemVolVars[scvIdx].fluidState().molarDensity(nPhaseIdx); - - - // const Scalar maDensityW = elemVolVars[scvIdx].fluidState().density(wPhaseIdx); //Molar Densities - // const Scalar maDensityG = elemVolVars[scvIdx].fluidState().density(gPhaseIdx); - // const Scalar maDensityN = elemVolVars[scvIdx].fluidState().density(nPhaseIdx); + const Scalar elemPressW = elemVolVars[scvf.insideScvIdx()].pressure(wPhaseIdx); //Pressures + const Scalar elemPressN = elemVolVars[scvf.insideScvIdx()].pressure(nPhaseIdx); - const Scalar elemMobW = elemVolVars[scvIdx].mobility(wPhaseIdx); //Mobilities - // const Scalar elemMobG = elemVolVars[scvIdx].mobility(gPhaseIdx); - const Scalar elemMobN = elemVolVars[scvIdx].mobility(nPhaseIdx); + const Scalar densityW = elemVolVars[scvf.insideScvIdx()].fluidState().density(wPhaseIdx); //Densities + const Scalar densityN = elemVolVars[scvf.insideScvIdx()].fluidState().density(nPhaseIdx); - // const Scalar molFracWinW = elemVolVars[scvIdx].fluidState().moleFraction(wPhaseIdx, wCompIdx); - // const Scalar molFracWinN = elemVolVars[scvIdx].fluidState().moleFraction(nPhaseIdx, wCompIdx); - // const Scalar molFracWinG = elemVolVars[scvIdx].fluidState().moleFraction(gPhaseIdx, wCompIdx); - // const Scalar molFracNinW = elemVolVars[scvIdx].fluidState().moleFraction(wPhaseIdx, nCompIdx); - // const Scalar molFracNinN = elemVolVars[scvIdx].fluidState().moleFraction(nPhaseIdx, nCompIdx); - // const Scalar molFracNinG = elemVolVars[scvIdx].fluidState().moleFraction(gPhaseIdx, nCompIdx); + const Scalar elemMobW = elemVolVars[scvf.insideScvIdx()].mobility(wPhaseIdx); //Mobilities + const Scalar elemMobN = elemVolVars[scvf.insideScvIdx()].mobility(nPhaseIdx); - const Scalar enthW = elemVolVars[scvIdx].enthalpy(wPhaseIdx); //Mobilities - // const Scalar enthG = elemVolVars[scvIdx].enthalpy(gPhaseIdx); - const Scalar enthN = elemVolVars[scvIdx].enthalpy(nPhaseIdx); + const Scalar enthW = elemVolVars[scvf.insideScvIdx()].enthalpy(wPhaseIdx); //Enthalpies + const Scalar enthN = elemVolVars[scvf.insideScvIdx()].enthalpy(nPhaseIdx); const Scalar wellRadius = 0.50 * 0.3048; // 0.50 ft as specified by SPE9 - // const Scalar wellArea = M_PI*std::pow(wellRadius,2); // [m^2] const Scalar gridHeight_ = 0.5; const Scalar effectiveRadius_ = 0.208 * gridHeight_; //Peaceman's Well Model - // const Scalar effectiveRadius_ = 0.56; + using std::log; //divided by molarMass() of water to convert from kg/m s to mol/m s - const Scalar qW = (((2*3.1415*0.5*4e-14)/(std::log(effectiveRadius_/wellRadius))) * + const Scalar qW = (((2*3.1415*0.5*4e-14)/(log(effectiveRadius_/wellRadius))) * densityW * elemMobW * ( elemPressW-pOut_))/0.01801528; //divided by molarMass() of HeavyOil to convert from kg/m s to mol/m s - const Scalar qN = (((2*3.1415*0.5*4e-14)/(std::log(effectiveRadius_/wellRadius))) * + const Scalar qN = (((2*3.1415*0.5*4e-14)/(log(effectiveRadius_/wellRadius))) * densityN * elemMobN * (elemPressN-pOut_))/0.35; + Scalar qE; //without cooling: - // const Scalar qE = qW*0.018*enthW + qN*enthN*0.350; + // qE = qW*0.018*enthW + qN*enthN*0.350; //with cooling: see Diplomarbeit Stefan Roll, Sept. 2015 - Scalar wT = elemVolVars[scvIdx].temperature(); // well temperature - Scalar qE; + Scalar wT = elemVolVars[scvf.insideScvIdx()].temperature(); // well temperature if ( wT > 495. ) { qE = qW*0.018*enthW + qN*enthN*0.350 + (wT-495.)*5000.; // ~3x injected enthalpy @@ -412,12 +252,13 @@ public: } - values[Indices::contiWEqIdx] = qW; - values[Indices::contiNEqIdx] = qN; - values[Indices::energyEqIdx] = qE; + values[contiWEqIdx] = qW; + values[contiNEqIdx] = qN; + values[energyEqIdx] = qE; massProducedOil_ = qN; massProducedWater_ = qW; } + return values; } // \} @@ -430,75 +271,38 @@ public: /*! * \brief Evaluate the initial value for a control volume. * - * \param values The initial values for the primary variables * \param globalPos The position for which the initial condition should be evaluated - * - * For this method, the \a values parameter stores primary - * variables. - */ - PrimaryVariables initialAtPos( const GlobalPosition &globalPos) const - { - PrimaryVariables values; - - initial_(values, globalPos); - - return values; - } - - /*! - * \brief Return the initial phase state inside a control volume. - * - * \param globalPos The global position */ - int initialPhasePresenceAtPos(const GlobalPosition &globalPos) const - { - return wnPhaseOnly; - //return threePhases; - } - - void setMassProd (Scalar value) const + PrimaryVariables initialAtPos(const GlobalPosition &globalPos) const { - massProducedOil_ = value; + return initial_(globalPos); } - Scalar getMassProd () - { - return massProducedOil_; - } - - - private: - - static constexpr Scalar eps_ = 1e-6; - // internal method for the initial condition (reused for the // dirichlet conditions!) - void initial_(PrimaryVariables &values, - const GlobalPosition &globalPos) const + PrimaryVariables initial_(const GlobalPosition &globalPos) const { + PrimaryVariables values(0.0); + values.setState(wnPhaseOnly); Scalar densityW = 1000.0; values[pressureIdx] = 101300.0 + (maxDepth_ - globalPos[1])*densityW*9.81; values[switch1Idx] = 295.13; // temperature values[switch2Idx] = 0.3; //NAPL saturation + return values; } Scalar maxDepth_; - + static constexpr Scalar eps_ = 1e-6; Scalar pIn_; - Scalar pOut_ = 4e6 ; + Scalar pOut_; Scalar totalMassProducedOil_; Scalar totalMassProducedWater_; - // TODO this is a very evil hack mutable Scalar massProducedOil_; mutable Scalar massProducedWater_; - //Scalar maxDepth_; - //Scalar episodeLength_; - //Scalar nEpisodes_ ; - //int indexEpisode; - //int episodeType_; + std::string name_; std::ofstream massBalance; diff --git a/lecture/mm/heavyoil/sagd/sagd.cc b/lecture/mm/heavyoil/sagd/sagd.cc index 49bba0c..c969809 100644 --- a/lecture/mm/heavyoil/sagd/sagd.cc +++ b/lecture/mm/heavyoil/sagd/sagd.cc @@ -18,8 +18,8 @@ *****************************************************************************/ /*! * \file - * - * \brief test for the 3p3cni box model + * \ingroup OnePTests + * \brief Test for the three-phase three-component box model */ #include #include @@ -29,14 +29,12 @@ #include #include #include -#include - -#include #include #include #include #include +#include #include #include @@ -44,19 +42,20 @@ #include #include +#include + #include +#include #include "problem.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. + * \ingroup OnePTests * \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) { @@ -65,28 +64,27 @@ void usage(const char *progName, const std::string &errorMsg) 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"; + "\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"; } } -//////////////////////// -// the main function -//////////////////////// int main(int argc, char** argv) try { - // typedef TTAG(LensOnePTwoCProblem) TypeTag; - // return Dumux::start(argc, argv, usage); + using namespace Dumux; // define the type tag for this problem - using TypeTag = TTAG(SagdBoxProblem); -Box + using TypeTag = TTAG(ThreePWaterOilSagdBoxTypeTag); + + //////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////// + // initialize MPI, finalize is done automatically on exit const auto& mpiHelper = Dune::MPIHelper::instance(argc, argv); @@ -98,16 +96,15 @@ Box 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(); + GridManager gridManager; + gridManager.init(); //////////////////////////////////////////////////////////// // run instationary non-linear problem on this grid //////////////////////////////////////////////////////////// // we compute on the leaf grid view - const auto& leafGridView = GridCreator::grid().leafGridView(); + const auto& leafGridView = gridManager.grid().leafGridView(); // create the finite volume grid geometry using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); @@ -135,27 +132,25 @@ Box const auto maxDt = getParam("TimeLoop.MaxTimeStepSize"); auto dt = getParam("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")) // Fehlt ebenso - restartTime = getParam("TimeLoop.Restart"); - // intialize the vtk output module using VtkOutputFields = typename GET_PROP_TYPE(TypeTag, VtkOutputFields); - VtkOutputModule vtkWriter(*problem, *fvGridGeometry, *gridVariables, x, problem->name()); - VtkOutputFields::init(vtkWriter); //!< Add model specific output fields + VtkOutputModule vtkWriter(*gridVariables, x, problem->name()); + using VelocityOutput = typename GET_PROP_TYPE(TypeTag, VelocityOutput); + vtkWriter.addVelocityOutput(std::make_shared(*gridVariables)); + VtkOutputFields::init(vtkWriter); //! Add model specific output fields vtkWriter.write(0.0); // instantiate time loop - auto timeLoop = std::make_shared>(restartTime, dt, tEnd); + auto timeLoop = std::make_shared>(0, dt, tEnd); timeLoop->setMaxTimeStepSize(maxDt); + timeLoop->setPeriodicCheckPoint(getParam("TimeLoop.EpisodeLength", std::numeric_limits::max())); // the assembler with time loop for instationary problem using Assembler = FVAssembler; auto assembler = std::make_shared(problem, fvGridGeometry, gridVariables, timeLoop); // the linear solver - using LinearSolver = AMGBackend; + using LinearSolver = Dumux::AMGBackend; auto linearSolver = std::make_shared(leafGridView, fvGridGeometry->dofMapper()); // the non-linear solver @@ -179,15 +174,15 @@ Box // 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 the Newton solver + // set new dt as suggested by the newton solver timeLoop->setTimeStepSize(nonLinearSolver.suggestTimeStepSize(timeLoop->timeStepSize())); + // write vtk output + vtkWriter.write(timeLoop->time()); + } while (!timeLoop->finished()); timeLoop->finalize(leafGridView.comm()); @@ -202,8 +197,10 @@ Box Parameters::print(); DumuxMessage::print(/*firstCall=*/false); } -} + return 0; + +} catch (Dumux::ParameterException &e) { std::cerr << std::endl << e << " ---> Abort!" << std::endl; @@ -212,10 +209,10 @@ catch (Dumux::ParameterException &e) 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; + "). 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) diff --git a/lecture/mm/heavyoil/sagd/spatialparams.hh b/lecture/mm/heavyoil/sagd/spatialparams.hh index 578bd81..1e17928 100644 --- a/lecture/mm/heavyoil/sagd/spatialparams.hh +++ b/lecture/mm/heavyoil/sagd/spatialparams.hh @@ -25,76 +25,49 @@ #ifndef DUMUX_SAGD_SPATIAL_PARAMS_HH #define DUMUX_SAGD_SPATIAL_PARAMS_HH +#include #include #include + +#include +#include +#include #include "../3p/parkervangenuchtenzero.hh" #include "../3p/parkervangenuchtenzeroparams.hh" -namespace Dumux -{ - -//forward declaration -template -class SagdSpatialParams; - -namespace Properties -{ -// The spatial parameters TypeTag -NEW_TYPE_TAG(SagdSpatialParams); - -// Set the spatial parameters -SET_TYPE_PROP(SagdSpatialParams, SpatialParams, Dumux::SagdSpatialParams); - -// Set the material Law -SET_PROP(SagdSpatialParams, Problem::SpatialParams::MaterialLaw) -{ - private: - using Scalar = GET_PROP_TYPE(TypeTag, Scalar); - public: - using type = ParkerVanGenZero3P; -}; - using MaterialLaw = typename Problem::SpatialParams::MaterialLaw - using MaterialLawParams = typename MaterialLaw::Params; -} +namespace Dumux { /*! * \ingroup ThreePThreeCNIModel * * \brief Definition of the spatial parameters for the SAGD problem */ -template -class SagdSpatialParams : public FVSpatialParams > +template +class SagdSpatialParams: public FVSpatialParams> { - using ParentType = FVSpatialParams >; - - using Grid = typename GET_PROP_TYPE(TypeTag, Grid): - using GridView = typename GET_PROP_TYPE(TypeTag, GridView); using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - using CoordScalar = typename Grid::ctype; + using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); + using GridView = typename FVGridGeometry::GridView; + using FVElementGeometry = typename FVGridGeometry::LocalView; + using SubControlVolume = typename FVElementGeometry::SubControlVolume; - static constexpr int dim = GridView::dimension; - static constexpr int dimWorld = GridView::dimensionworld; - using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - using DimVecotr = Dune::FieldVector; // TODO: What is this? + enum { dimWorld=GridView::dimensionworld }; - using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; + using GlobalPosition = typename SubControlVolume::GlobalPosition; - static constexpr int wPhaseIdx = Indices::Phase0Idx; - static constexpr int nPhaseIdx = Indices::Phase1Idx; - - using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector); - - // typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; - // typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - - using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); using Element = typename GridView::template Codim<0>::Entity; + using ElementSolution = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView; + using ParentType = FVSpatialParams>; + using EffectiveLaw = RegularizedParkerVanGen3P; public: - using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; + using MaterialLaw = EffToAbsLaw; using MaterialLawParams = typename MaterialLaw::Params; + using PermeabilityType = Scalar; /*! * \brief The constructor @@ -102,7 +75,7 @@ public: * \param gridView The grid view */ SagdSpatialParams(std::shared_ptr fvGridGeometry) - : ParentType(fvGridGeometry) + : ParentType(fvGridGeometry), eps_(1e-6) { layerBottom_ = 35.0; @@ -114,7 +87,7 @@ public: finePorosity_ = 0.10; coarsePorosity_ = 0.1; - // heat conductivity of granite + // heat conductivity of granite lambdaSolid_ = 2.8; // specific heat capacities @@ -142,78 +115,74 @@ public: } /*! - * \brief Apply the intrinsic permeability tensor to a pressure - * potential gradient. + * \brief Function for defining the (intrinsic) permeability \f$[m^2]\f$ + * \note It is possibly solution dependent. * - * \param element The current finite element - * \param fvElemGeom The current finite volume geometry of the element - * \param scvIdx The index of the sub-control volume + * \param element The current element + * \param scv The sub-control volume inside the element. + * \param elemSol The solution at the dofs connected to the element. + * \return permeability */ - - // TODO: How to change this correctly? - /* Scalar intrinsicPermeability(const Element &element, - const FVElementGeometry &fvElemGeom, - int scvIdx) const */ template - Scalar permeability(const Element element, - const SubControlVolume &scv, - const ElementSolution &elemSol) const + PermeabilityType permeability(const Element& element, + const SubControlVolume& scv, + const ElementSolution& elemSol) const + { return permeabilityAtPos(scv.dofPosition());} + + /*! + * \brief Returns the intrinsic permeability tensor \f$[m^2]\f$ + * + * \param globalPos The global position + */ + PermeabilityType permeabilityAtPos(const GlobalPosition& globalPos) const { - // const GlobalPosition &pos = element.geometry().center(); // fvElemGeom.subContVol[scvIdx].global; - if (isFineMaterial_(element.geometry().center() )) // kaiw: inspired from /run/media/kaiw/workspace4/DUMUX/dumux-lecture/lecture/efm/1p2c_2p_2p2c/lens2pspatialparams.hh line 131 + if (isFineMaterial_(globalPos)) return fineK_; return coarseK_; } /*! - * \brief Define the porosity \f$[-]\f$ of the spatial parameters + * \brief Returns the porosity \f$[-]\f$ * - * \param element The finite element - * \param fvGeometry The finite volume geometry - * \param scvIdx The local index of the sub-control volume where - * the porosity needs to be defined + * \param globalPos The global position */ - template - Scalar porosity(const Element &element, - const SubControlVolume& scv, - const ElementSolution& elemSol) const + Scalar porosityAtPos(const GlobalPosition& globalPos) const { - // const GlobalPosition &pos = fvGeometry.subContVol[scvIdx].global; - if (isFineMaterial_(element.geometry().center() )) + if (isFineMaterial_(globalPos)) return finePorosity_; else return coarsePorosity_; } + /*! + * \brief Function for defining the parameters needed by constitutive relationships (kr-sw, pc-sw, etc.). + * + * \param element The current element + * \param scv The sub-control volume inside the element. + * \param elemSol The solution at the dofs connected to the element. + * \return the material parameters object + */ + template + const MaterialLawParams& materialLawParams(const Element& element, + const SubControlVolume& scv, + const ElementSolution& elemSol) const + { + return materialLawParamsAtPos(scv.dofPosition()); + } /*! - * \brief return the parameter object for the Brooks-Corey material law which depends on the position + * \brief Returns the parameter object for the capillary-pressure/ + * saturation material law * - * \param element The current finite element - * \param fvGeometry The current finite volume geometry of the element - * \param scvIdx The index of the sub-control volume + * \param globalPos The global position */ - const MaterialLawParams& materialLawParams(const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx) const + const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const { - const GlobalPosition &pos = fvGeometry.subContVol[scvIdx].global; - if (isFineMaterial_(pos)) + if (isFineMaterial_(globalPos)) return fineMaterialParams_; else return coarseMaterialParams_; } - - /*! - * \brief Returns the heat capacity \f$[J / (kg K)]\f$ of the rock matrix. - * - * This is only required for non-isothermal models. - * - * \param element The finite element - * \param fvGeometry The finite volume geometry - * \param scvIdx The local index of the sub-control volume - */ - template Scalar solidHeatCapacity(const Element &element, const SubControlVolume& scv, const ElementSolution& elemSol) const @@ -224,32 +193,12 @@ public: else return coarseHeatCap_; } - - /*! - * \brief Returns the mass density \f$[kg / m^3]\f$ of the rock matrix. - * - * This is only required for non-isothermal models. - * - * \param element The finite element - * \param fvGeometry The finite volume geometry - * \param scvIdx The local index of the sub-control volume - */ Scalar solidDensity(const Element &element, const SubControlVolume& scv, const ElementSolution& elemSol) const { return 2650; // density of sand [kg/m^3] } - - /*! - * \brief Returns the thermal conductivity \f$\mathrm{[W/(m K)]}\f$ of the solid - * - * This is only required for non-isothermal models. - * - * \param element The finite element - * \param fvGeometry The finite volume geometry of the element - * \param scvIdx The local index of the sub-control volume - */ Scalar solidThermalConductivity(const Element &element, const SubControlVolume& scv, const ElementSolution& elemSol) const @@ -260,8 +209,8 @@ public: private: bool isFineMaterial_(const GlobalPosition &pos) const { - return pos[dim-1] > layerBottom_ - eps_; - } + return pos[dimWorld-1] > layerBottom_ - eps_; + }; Scalar layerBottom_; Scalar lambdaSolid_; @@ -278,9 +227,9 @@ private: MaterialLawParams fineMaterialParams_; MaterialLawParams coarseMaterialParams_; - static constexpr Scalar eps_ = 1.5e-7; + Scalar eps_; }; -} +} // End Namespace Dumux #endif -- GitLab From e84b4e2682a4d1cdffbe9a7846dcba76a0615296 Mon Sep 17 00:00:00 2001 From: Kai Wendel Date: Tue, 4 Sep 2018 12:34:03 +0200 Subject: [PATCH 05/60] update buckleyleverett and mcworther --- lecture/common/viplaboutput.hh | 8 +- .../buckleyleverettanalyticsolution.hh | 6 +- .../buckleyleverettexercise.input | 5 +- .../buckleyleverett/buckleyleverettproblem.hh | 101 ++++------- .../buckleyleverettspatialparams.hh | 13 +- lecture/mm/buckleyleverett/pseudoh2o.hh | 8 +- lecture/mm/buckleyleverett/pseudooil.hh | 8 +- lecture/mm/mcwhorter/mcwhorterexercise.cc | 170 +----------------- lecture/mm/mcwhorter/mcwhorterexercise.input | 8 +- lecture/mm/mcwhorter/mcwhorterproblem.hh | 91 ++++------ 10 files changed, 96 insertions(+), 322 deletions(-) diff --git a/lecture/common/viplaboutput.hh b/lecture/common/viplaboutput.hh index aa16d2d..6a25b6f 100644 --- a/lecture/common/viplaboutput.hh +++ b/lecture/common/viplaboutput.hh @@ -35,8 +35,8 @@ namespace Dumux template class ViplabOutput { - using Problem = GET_PROP_TYPE(TypeTag, Problem); - using Scalar = GET_PROP_TYPE(TypeTag, Scalar); + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); using Indices = typename GET_PROP_TYPE(TypeTag, Indices); enum{ wPhaseIdx = Indices::wPhaseIdx }; @@ -92,9 +92,9 @@ public: { setColor(color); - const auto cellNumber = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, std::vector, Grid, Cells); + const auto cellNumber = getParam>("Grid.Cells"); assert(cellNumber[0] == solution.size()); - upperRight_ = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, std::vector, Grid, UpperRight); + upperRight_ = getParam>("Grid.UpperRight"); const Scalar discretizationLength = upperRight_[0] / cellNumber[0]; dataFile_.open(outputName_, std::fstream::app); diff --git a/lecture/mm/buckleyleverett/buckleyleverettanalyticsolution.hh b/lecture/mm/buckleyleverett/buckleyleverettanalyticsolution.hh index 0d448c7..7d3603b 100644 --- a/lecture/mm/buckleyleverett/buckleyleverettanalyticsolution.hh +++ b/lecture/mm/buckleyleverett/buckleyleverettanalyticsolution.hh @@ -70,7 +70,7 @@ template class BuckleyLeverettAnalytic using Problem = typename GET_PROP_TYPE(TypeTag, Problem); using Grid = typename GET_PROP_TYPE(TypeTag, Grid); using GridView = typename GET_PROP_TYPE(TypeTag, GridView); - using Scalar typename GET_PROP_TYPE(TypeTag, Scalar); + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); using SpatialParams = typename GET_PROP_TYPE(TypeTag, SpatialParams); using MaterialLaw = typename SpatialParams::MaterialLaw; @@ -95,8 +95,8 @@ template class BuckleyLeverettAnalytic using BlockVector = Dune::BlockVector >; using Element = typename GridView::Traits::template Codim<0>::Entity; - using ElementIterator typename GridView::template Codim<0>::Iterator; - using GlobalPosition 0 Dune::FieldVector; + using ElementIterator = typename GridView::template Codim<0>::Iterator; + using GlobalPosition = Dune::FieldVector; public: diff --git a/lecture/mm/buckleyleverett/buckleyleverettexercise.input b/lecture/mm/buckleyleverett/buckleyleverettexercise.input index de60138..4c6af3c 100644 --- a/lecture/mm/buckleyleverett/buckleyleverettexercise.input +++ b/lecture/mm/buckleyleverett/buckleyleverettexercise.input @@ -1,7 +1,10 @@ -[TimeLoop] +[TimeManager] TEnd = 2e7 # end time of the simulation [s] DtInitial = 1e3 # initial time step for the simulation [s] +[Problem] +EnableGravity = false + [SpatialParams] Permeability = 1.01936799e-14 # intrinsic permeability of the porous medium [m^2] diff --git a/lecture/mm/buckleyleverett/buckleyleverettproblem.hh b/lecture/mm/buckleyleverett/buckleyleverettproblem.hh index 4d18ac6..4c52b3e 100644 --- a/lecture/mm/buckleyleverett/buckleyleverettproblem.hh +++ b/lecture/mm/buckleyleverett/buckleyleverettproblem.hh @@ -21,7 +21,11 @@ #include -#include +#include + +#include +#include + #include #include #include @@ -52,30 +56,16 @@ SET_TYPE_PROP(BuckleyLeverettProblem, Grid, Dune::YaspGrid<2>); // Set the problem property SET_TYPE_PROP(BuckleyLeverettProblem, Problem, BuckleyLeverettProblem); -// Set the wetting phase -SET_PROP(BuckleyLeverettProblem, WettingPhase) +SET_PROP(BuckleyLeverettProblem, FluidSystem) { -private: - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; -public: - typedef FluidSystems::LiquidPhase > type; -}; - -// Set the non-wetting phase -SET_PROP(BuckleyLeverettProblem, NonwettingPhase) -{ -private: - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; -public: - typedef FluidSystems::LiquidPhase > type; + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using WettingPhase = FluidSystems::OnePLiquid >; + using NonwettingPhase = FluidSystems::OnePLiquid >; + using type = FluidSystems::TwoPImmiscible; }; -// Disable gravity -SET_BOOL_PROP(BuckleyLeverettProblem, ProblemEnableGravity, false); - SET_TYPE_PROP(BuckleyLeverettProblem, EvalCflFluxFunction, EvalCflFluxCoats); SET_INT_PROP(BuckleyLeverettProblem, Formulation, SequentialTwoPCommonIndices::pwsw); -SET_SCALAR_PROP(BuckleyLeverettProblem, ImpetCFLFactor, 0.95); } /*! @@ -90,13 +80,11 @@ class BuckleyLeverettProblem: public IMPESProblem2P using Indices = typename GET_PROP_TYPE(TypeTag, Indices); using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using TimeManager = typename GET_PROP_TYPE(TypeTag, TimeManager); using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); using FluidState = typename GET_PROP_TYPE(TypeTag, FluidState); - using WettingPhase = typename GET_PROP_TYPE(TypeTag, WettingPhase); - using NonwettingPhase = typename GET_PROP_TYPE(TypeTag, NonwettingPhase); - using CellData = typename GET_PROP_TYPE(TypeTag, CellData); using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); @@ -120,7 +108,6 @@ class BuckleyLeverettProblem: public IMPESProblem2P using Element = typename GridView::Traits::template Codim<0>::Entity; using Intersection = typename GridView::Intersection; using GlobalPosition = Dune::FieldVector; - using Params = typename GET_PROP(TypeTag, ParameterTree); public: /*! @@ -128,9 +115,9 @@ public: * \param timeManager DOC ME! * \param gridView DOC ME! */ - BuckleyLeverettProblem(std::shared_ptr fvGridGeometry) - : ParentType(fvGridGeometry) - + BuckleyLeverettProblem(TimeManager& timeManager, typename GridView::Grid &grid) + : ParentType(timeManager, grid), eps_(1e-8), pLeftBc_(2.0e5), + analyticSolution_(*this, 3e-7), viplabOutput_(*this) { // TODO: What are these: analyticSolution_(*this, 3e-7), viplabOutput_(*this) @@ -143,18 +130,18 @@ public: upperRight_ = getParam("Grid.UpperRight"); - WettingPhase::Component::setViscosity( getParam("Fluid.ViscosityW") ); - NonwettingPhase::Component::setViscosity( getParam("Fluid.ViscosityNW") ); + PseudoOil::setViscosity( getParam("Fluid.ViscosityW") ); + PseudoH2O::setViscosity( getParam("Fluid.ViscosityNW") ); - WettingPhase::Component::setDensity( getParam("Fluid.DensityW") ); - NonwettingPhase::Component::setDensity( getParam("Fluid.DensityNW") ); + PseudoOil::setDensity( getParam("Fluid.DensityW") ); + PseudoH2O::setDensity( getParam("Fluid.DensityNW") ); densityNonWetting_ = getParam("Fluid.DensityNW"); swr_ = getParam("SpatialParams.ResidualSaturationWetting"); snr_ = getParam("SpatialParams.ResidualSaturationNonWetting"); - paraviewOutput_ = Params::tree().template get("Output.paraviewOutput", true); + paraviewOutput_ = getParam("Output.paraviewOutput", true); /*// create output for ViPLab if no output for Paraview is created if (!paraviewOutput_) @@ -163,8 +150,8 @@ public: std::ofstream dataFile; dataFile.open("vipplot.vgf"); dataFile.close(); - } - }*/ + }*/ + } void init() { @@ -211,36 +198,26 @@ public: return 273.15 + 10; // -> 10°C } - /*! - * \brief Returns the pressure within the domain. - * - * This problem assumes a pressure of 1bar (which is equal to 1e5 Pa) - * \param GlobalPos DOC ME! - */ Scalar referencePressureAtPos(const GlobalPosition& globalPos) const { return 1.0e5; // -> 1 bar } - /*! * \brief DOC ME! * \param values DOC ME! * \param globalPos DOC ME! */ - numEqVector sourceAtPos(const GlobalPosition& globalPos) const + void sourceAtPos(PrimaryVariables &values,const GlobalPosition& globalPos) const { - return numEqVector(0.0); + values = 0; } - /*! * \brief DOC ME! * \param bcTypes DOC ME! * \param globalPos DOC ME! */ - BoundaryTypes boundaryTypesAtPos( const GlobalPosition& globalPos) const + void boundaryTypesAtPos(BoundaryTypes &bcTypes, const GlobalPosition& globalPos) const { - BoundaryTypes bcTypes; - if (globalPos[0] < eps_)//all Dirichlet at west boundary { bcTypes.setAllDirichlet(); @@ -255,34 +232,24 @@ public: { bcTypes.setAllNeumann(); } - - return bcTypes; } - /*! * \brief DOC ME! * \param values DOC ME! * \param globalPos DOC ME */ - PrimaryVariables dirichletAtPos( const GlobalPosition& globalPos) const + void dirichletAtPos(PrimaryVariables &values, const GlobalPosition& globalPos) const { - PrimaryVariables values; - values[pressureIdx] = pLeftBc_; values[swIdx] = 1.0 - snr_; - - return values; } - /*! * \brief DOC ME! * \param values DOC ME! * \param globalPos DOC ME */ - PrimaryVariables neumannAtPos( const GlobalPosition& globalPos) const + void neumannAtPos(PrimaryVariables &values, const GlobalPosition& globalPos) const { - PrimaryVariables values; - values = 0; //no-flow Neumann at top and bottom if (globalPos[0] > upperRight_[0] - eps_) //east boundary { @@ -291,23 +258,17 @@ public: const Scalar referenceDensity = 1000.0; values[nPhaseIdx] = 3e-4 * densityNonWetting_/referenceDensity; } - - return values; } - /*! * \brief DOC ME! * \param values DOC ME! * \param globalPos DOC ME */ - PrimaryVariables initialAtPos( const GlobalPosition &globalPos) const + void initialAtPos(PrimaryVariables &values, + const GlobalPosition &globalPos) const { - PrimaryVariables values; - values[pressureIdx] = pLeftBc_; values[swIdx] = swr_; - - return values; } /** @@ -339,15 +300,13 @@ public: private: GlobalPosition upperRight_; - Scalar eps_ = 1e-8; - Scalar swr_, snr_; + Scalar eps_, swr_, snr_; Scalar pLeftBc_; Scalar densityNonWetting_; BuckleyLeverettAnalytic analyticSolution_; ViplabOutput viplabOutput_; bool paraviewOutput_; - }; - +}; } #endif // DUMUX_LECTURE_MM_BUCKLEYLEVERETT_BUCKLEYLEVERETTPROBLEM_HH diff --git a/lecture/mm/buckleyleverett/buckleyleverettspatialparams.hh b/lecture/mm/buckleyleverett/buckleyleverettspatialparams.hh index 42d6c60..64e78ee 100644 --- a/lecture/mm/buckleyleverett/buckleyleverettspatialparams.hh +++ b/lecture/mm/buckleyleverett/buckleyleverettspatialparams.hh @@ -19,7 +19,7 @@ #ifndef BUCKLEYLEVERETT_SPATIALPARAMS_HH #define BUCKLEYLEVERETT_SPATIALPARAMS_HH -#include +#include #include #include #include @@ -54,12 +54,13 @@ public: /** \todo Please doc me! */ template -class BuckleyLeverettSpatialParams: public FVSpatialParams +class BuckleyLeverettSpatialParams: public SequentialFVSpatialParams { using Grid = typename GET_PROP_TYPE(TypeTag, Grid); using GridView = typename GET_PROP_TYPE(TypeTag, GridView); - using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar) - typedef FVSpatialParams ParentType; // TODO: How to change this thing here? + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); + typedef SequentialFVSpatialParams ParentType; // TODO: How to change this thing here? using CoordScalar = typename Grid::ctype; enum @@ -97,8 +98,8 @@ public: } - BuckleyLeverettSpatialParams(const GridView& gridView) // TODO How to change this? - :ParentType(gridView) + BuckleyLeverettSpatialParams(const Problem& problem) // TODO How to change this? + :ParentType(problem) { Scalar permFactor = 1.0;//0.001/(1000*9.81); diff --git a/lecture/mm/buckleyleverett/pseudoh2o.hh b/lecture/mm/buckleyleverett/pseudoh2o.hh index 83cb85f..7b529ba 100644 --- a/lecture/mm/buckleyleverett/pseudoh2o.hh +++ b/lecture/mm/buckleyleverett/pseudoh2o.hh @@ -25,7 +25,7 @@ #define DUMUX_PSEUDOH2O_HH -#include +#include namespace Dumux { @@ -33,11 +33,11 @@ namespace Dumux * \brief Rough estimate for testing purposes of some water. */ template // TODO: Must change this to Scalar? -class PseudoH2O : public Component > +class PseudoH2O : public Components::Base > + , public Components::Liquid > { - typedef Component > ParentType; - typedef ScalarT Scalar; public: + typedef ScalarT Scalar; /*! * \brief A human readable name for the water. */ diff --git a/lecture/mm/buckleyleverett/pseudooil.hh b/lecture/mm/buckleyleverett/pseudooil.hh index 3405a7c..bc59783 100644 --- a/lecture/mm/buckleyleverett/pseudooil.hh +++ b/lecture/mm/buckleyleverett/pseudooil.hh @@ -25,7 +25,7 @@ #define DUMUX_PSEUDOOIL_HH -#include +#include //#include "interface_BL.xml" namespace Dumux @@ -34,12 +34,12 @@ namespace Dumux * \brief Rough estimate for testing purposes of some oil. */ template -class PseudoOil : public Component > +class PseudoOil : public Components::Base > + , public Components::Liquid > { - typedef Component > ParentType; +public: typedef ScalarT Scalar; -public: /*! * \brief A human readable name for the water. */ diff --git a/lecture/mm/mcwhorter/mcwhorterexercise.cc b/lecture/mm/mcwhorter/mcwhorterexercise.cc index fd7a727..56188f2 100644 --- a/lecture/mm/mcwhorter/mcwhorterexercise.cc +++ b/lecture/mm/mcwhorter/mcwhorterexercise.cc @@ -62,173 +62,9 @@ void usage(const char *progName, const std::string &errorMsg) << "\n"; } } -//////////////////////// -// the main function -//////////////////////// -int main(int argc, char** argv) try -{ - using namespace Dumux; - - // define the type tag for this problem - using TypeTag = TTAG(McWhorterProblem); - - // 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(leafGridView); - fvGridGeometry->update(); - - // the problem (initial and boundary conditions) - using Problem = typename GET_PROP_TYPE(TypeTag, Problem); - auto problem = std::make_shared(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(problem, fvGridGeometry); - gridVariables->init(x, xOld); - - // get some time loop parameters - using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - const auto tEnd = getParam("TimeLoop.TEnd"); - const auto maxDivisions = getParam("TimeLoop.MaxTimeStepDivisions"); // Q: What is this? Do we need this here? - const auto maxDt = getParam("TimeLoop.MaxTimeStepSize"); - auto dt = getParam("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")) // Fehlt ebenso - restartTime = getParam("TimeLoop.Restart"); - - // intialize the vtk output module - using VtkOutputFields = typename GET_PROP_TYPE(TypeTag, VtkOutputFields); - VtkOutputModule 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>(restartTime, dt, tEnd); - timeLoop->setMaxTimeStepSize(maxDt); - - // the assembler with time loop for instationary problem - using Assembler = FVAssembler; - auto assembler = std::make_shared(problem, fvGridGeometry, gridVariables, timeLoop); - - // the linear solver - using LinearSolver = AMGBackend; - auto linearSolver = std::make_shared(leafGridView, fvGridGeometry->dofMapper()); - - // the non-linear solver - using NewtonSolver = Dumux::NewtonSolver; - NewtonSolver nonLinearSolver(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 the Newton solver - timeLoop->setTimeStepSize(nonLinearSolver.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); - } - - - -} - -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 (...) +int main(int argc, char** argv) { - std::cerr << "Unknown exception thrown! ---> Abort!" << std::endl; - return 4; + typedef TTAG(McWhorterProblem) TypeTag; + return Dumux::start(argc, argv, usage); } diff --git a/lecture/mm/mcwhorter/mcwhorterexercise.input b/lecture/mm/mcwhorter/mcwhorterexercise.input index 19743eb..3793d0c 100644 --- a/lecture/mm/mcwhorter/mcwhorterexercise.input +++ b/lecture/mm/mcwhorter/mcwhorterexercise.input @@ -1,7 +1,10 @@ -[TimeLoop] +[TimeManager] TEnd = 5e6 # end time of the simulation [s] DtInitial = 1e3 # initial time step for the simulation [s] +[Problem] +EnableGravity = false + [SpatialParams] Permeability = 1.01936799e-13 # intrinsic permeability of the porous medium [m^2] Porosity = 0.2 # porosity of the porous medium [-] @@ -24,3 +27,6 @@ Cells = 20 1 # grid resolution in (x, y) directio [Output] Interval = 10 # output only every n-th time step ParaviewOutput = true # create output for either Paraview or ViPLab + +[Impet] +CFLFactor = 0.8 diff --git a/lecture/mm/mcwhorter/mcwhorterproblem.hh b/lecture/mm/mcwhorter/mcwhorterproblem.hh index 7de172b..61a74af 100644 --- a/lecture/mm/mcwhorter/mcwhorterproblem.hh +++ b/lecture/mm/mcwhorter/mcwhorterproblem.hh @@ -19,7 +19,10 @@ #ifndef DUMUX_MCWHORTERPROBLEM_HH #define DUMUX_MCWHORTERPROBLEM_HH -#include +#include + +#include +#include #include #include @@ -54,28 +57,15 @@ SET_TYPE_PROP(McWhorterProblem, Problem, McWhorterProblem); SET_INT_PROP(McWhorterProblem, Formulation, SequentialTwoPCommonIndices::pnsw); // Set the wetting phase -SET_PROP(McWhorterProblem, WettingPhase) +SET_PROP(McWhorterProblem, FluidSystem) { -private: - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; -public: - typedef FluidSystems::LiquidPhase > type; -}; - -// Set the non-wetting phase -SET_PROP(McWhorterProblem, NonwettingPhase) -{ -private: - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; -public: - typedef FluidSystems::LiquidPhase > type; + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using WettingPhase = FluidSystems::OnePLiquid >; + using NonwettingPhase = FluidSystems::OnePLiquid >; + using type = FluidSystems::TwoPImmiscible; }; -// Disable gravity -SET_BOOL_PROP(McWhorterProblem, ProblemEnableGravity, false); - SET_TYPE_PROP(McWhorterProblem, EvalCflFluxFunction, Dumux::EvalCflFluxCoats); -SET_SCALAR_PROP(McWhorterProblem, ImpetCFLFactor, 0.8); } /*! @@ -88,13 +78,11 @@ class McWhorterProblem: public IMPESProblem2P // TODO: Which is now th using ParentType = IMPESProblem2P; using GridView = typename GET_PROP_TYPE(TypeTag, GridView); using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using TimeManager = typename GET_PROP_TYPE(TypeTag, TimeManager); using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); using FluidState = typename GET_PROP_TYPE(TypeTag, FluidState); - using WettingPhase = typename GET_PROP_TYPE(TypeTag, WettingPhase); - using NonwettingPhase = typename GET_PROP_TYPE(TypeTag, NonwettingPhase); - using CellData = typename GET_PROP_TYPE(TypeTag, CellData); using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); @@ -121,32 +109,30 @@ class McWhorterProblem: public IMPESProblem2P // TODO: Which is now th using Element = typename GridView::Traits::template Codim<0>::Entity; using Intersection = typename GridView::Intersection; - using Params = typename GET_PROP(TypeTag, ParameterTree); - public: /*! * \brief DOC ME! * \param timeManager DOC ME! * \param gridView DOC ME! */ - McWhorterProblem(std::shared_ptr fvGridGeometry) - : ParentType(fvGridGeometry),// TODO: Implement this in a correct way: eps_(1e-8), pLeftBc_ ( 1.0e5 ), analyticSolution_(*this), viplabOutput_(*this) + McWhorterProblem(TimeManager& timeManager, typename GridView::Grid &grid) + : ParentType(timeManager, grid), eps_(1e-8), pLeftBc_ ( 1.0e5 ), + analyticSolution_(*this), viplabOutput_(*this) { this->setOutputInterval( getParam("Output.Interval") ); - WettingPhase::Component::setViscosity( getParam("Fluid.ViscosityW") ); - NonwettingPhase::Component::setViscosity( getParam("Fluid.ViscosityNW") ); + PseudoOil::setViscosity( getParam("Fluid.ViscosityW") ); + PseudoH2O::setViscosity( getParam("Fluid.ViscosityNW") ); - WettingPhase::Component::setDensity( getParam("Fluid.DensityW") ); - NonwettingPhase::Component::setDensity( getParam("Fluid.DensityNW") ); + PseudoOil::setDensity( getParam("Fluid.DensityW") ); + PseudoH2O::setDensity( getParam("Fluid.DensityNW") ); swr_ = getParam("SpatialParams.ResidualSaturationWetting"); snr_ = getParam("SpatialParams.ResidualSaturationNonWetting"); - paraviewOutput_ = Params::tree().template get("Output.paraviewOutput", true); + paraviewOutput_ = getParam("Output.paraviewOutput", true); } - // TODO: Is this up to date? void init() { ParentType::init(); @@ -164,7 +150,6 @@ public: bool shouldWriteRestartFile() const { return false; } - // TODO: Is this now in the main-function? void postTimeStep() { analyticSolution_.calculateAnalyticSolution(); @@ -192,78 +177,62 @@ public: { return 1.0e5; // -> 1 bar } - /*! * \brief DOC ME! * \param values DOC ME! * \param globalPos DOC ME! */ - NumEqVector sourceAtPos(const GlobalPosition& globalPos) const + void sourceAtPos(PrimaryVariables &values,const GlobalPosition& globalPos) const { - return NumEqVector(0.0); + values = 0; } - /*! * \brief DOC ME! * \param bcTypes DOC ME! * \param globalPos DOC ME! */ - BoundaryTypes boundaryTypesAtPos(const GlobalPosition& globalPos) const + void boundaryTypesAtPos(BoundaryTypes &bcTypes, const GlobalPosition& globalPos) const { - BoundaryTypes bcTypes; - if (globalPos[0] < eps_) //west bcTypes.setAllDirichlet(); // the other boundary (east) else bcTypes.setAllNeumann(); - - return bcTypes; } - /*! * \brief DOC ME! * \param values DOC ME! * \param globalPos DOC ME! */ - PrimaryVariables dirichletAtPos(const GlobalPosition& globalPos) const + void dirichletAtPos(PrimaryVariables &values, const GlobalPosition& globalPos) const { - PrimaryVariables values; - values[pnIdx] = pLeftBc_; values[swIdx] = 1.0 - snr_; - - return values; } - /*! * \brief DOC ME! * \param values DOC ME! * \param globalPos DOC ME! */ - PrimaryVariables neumannAtPos( const GlobalPosition& globalPos) const + void neumannAtPos(PrimaryVariables &values, const GlobalPosition& globalPos) const { - return PrimaryVariables(0.0); + values = 0; //homogeneous Neumann } - /*! * \brief DOC ME! * \param values DOC ME! * \param globalPos DOC ME! */ - PrimaryVariables initialAtPos(const GlobalPosition &globalPos) const + void initialAtPos(PrimaryVariables &values, + const GlobalPosition &globalPos) const { - PrimaryVariables values; - values[pnIdx] = pLeftBc_; values[swIdx] = swr_; - - return values; } //Override outputfunction for ViPLab-Output - /* void writeOutput() + void writeOutput() { if (paraviewOutput_) ParentType::writeOutput(false); @@ -286,14 +255,14 @@ public: viplabOutput_.writeLegend(); } } -*/ + private: - Scalar eps_, - Scalar swr_, snr_; + Scalar eps_, swr_, snr_; Scalar pLeftBc_; McWhorterAnalytic analyticSolution_; ViplabOutput viplabOutput_; bool paraviewOutput_; }; + } #endif -- GitLab From 6ab1c56356cef4cced4db440096b568070ec7e71 Mon Sep 17 00:00:00 2001 From: Kai Wendel Date: Tue, 4 Sep 2018 14:53:58 +0200 Subject: [PATCH 06/60] Tried to update but small errors remained, reasons whrere not found --- lecture/efm/1p2c_2p_2p2c/lens1p2cexercise3.cc | 12 +- lecture/efm/1p2c_2p_2p2c/lens2p2cexercise3.cc | 12 +- lecture/efm/1p2c_2p_2p2c/lens2pexercise3.cc | 12 +- lecture/efm/1p2cvs2p/lens1p2cexercise1.cc | 12 +- lecture/efm/1p2cvs2p/lens1p2cproblem.hh | 2 +- lecture/efm/1p2cvs2p/lens2pexercise1.cc | 12 +- lecture/efm/1p2cvs2p/lens2pproblem.hh | 1 + lecture/efm/2p/lens2pexercise2.cc | 12 +- lecture/efm/2p/lens2pproblem.hh | 15 +-- .../mm/convectivemixing/convmixexercise.cc | 25 ++++- .../mm/convectivemixing/convmixexercise.input | 2 +- lecture/mm/convectivemixing/convmixproblem.hh | 106 ++++++------------ .../convectivemixing/convmixspatialparams.hh | 12 +- 13 files changed, 118 insertions(+), 117 deletions(-) diff --git a/lecture/efm/1p2c_2p_2p2c/lens1p2cexercise3.cc b/lecture/efm/1p2c_2p_2p2c/lens1p2cexercise3.cc index 3c9a7aa..e5b640a 100755 --- a/lecture/efm/1p2c_2p_2p2c/lens1p2cexercise3.cc +++ b/lecture/efm/1p2c_2p_2p2c/lens1p2cexercise3.cc @@ -40,7 +40,7 @@ #include #include - +#include #include /*! @@ -103,17 +103,19 @@ int main(int argc, char** argv) try // 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(); + ///////////////////////////////////////////////////////////////////// + + GridManager gridManager; + gridManager.init(); //////////////////////////////////////////////////////////// // run instationary non-linear problem on this grid //////////////////////////////////////////////////////////// // we compute on the leaf grid view - const auto& leafGridView = GridCreator::grid().leafGridView(); + const auto& leafGridView = gridManager.grid().leafGridView(); // create the finite volume grid geometry using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); diff --git a/lecture/efm/1p2c_2p_2p2c/lens2p2cexercise3.cc b/lecture/efm/1p2c_2p_2p2c/lens2p2cexercise3.cc index 01d7da4..70e0d7e 100644 --- a/lecture/efm/1p2c_2p_2p2c/lens2p2cexercise3.cc +++ b/lecture/efm/1p2c_2p_2p2c/lens2p2cexercise3.cc @@ -49,7 +49,7 @@ #include #include - +#include #include // #include "config.h" @@ -123,17 +123,19 @@ int main(int argc, char** argv) try // 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(); + ///////////////////////////////////////////////////////////////////// + + GridManager gridManager; + gridManager.init(); //////////////////////////////////////////////////////////// // run instationary non-linear problem on this grid //////////////////////////////////////////////////////////// // we compute on the leaf grid view - const auto& leafGridView = GridCreator::grid().leafGridView(); + const auto& leafGridView = gridManager.grid().leafGridView(); // create the finite volume grid geometry using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); diff --git a/lecture/efm/1p2c_2p_2p2c/lens2pexercise3.cc b/lecture/efm/1p2c_2p_2p2c/lens2pexercise3.cc index a4ebf8b..adbed8d 100755 --- a/lecture/efm/1p2c_2p_2p2c/lens2pexercise3.cc +++ b/lecture/efm/1p2c_2p_2p2c/lens2pexercise3.cc @@ -46,7 +46,7 @@ #include #include - +#include #include /*! @@ -118,17 +118,19 @@ int main(int argc, char** argv) try // 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(); + ///////////////////////////////////////////////////////////////////// + + GridManager gridManager; + gridManager.init(); //////////////////////////////////////////////////////////// // run instationary non-linear problem on this grid //////////////////////////////////////////////////////////// // we compute on the leaf grid view - const auto& leafGridView = GridCreator::grid().leafGridView(); + const auto& leafGridView = gridManager.grid().leafGridView(); // create the finite volume grid geometry using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); diff --git a/lecture/efm/1p2cvs2p/lens1p2cexercise1.cc b/lecture/efm/1p2cvs2p/lens1p2cexercise1.cc index d39b3df..ce75b63 100644 --- a/lecture/efm/1p2cvs2p/lens1p2cexercise1.cc +++ b/lecture/efm/1p2cvs2p/lens1p2cexercise1.cc @@ -43,7 +43,7 @@ #include #include - +#include #include "lens1p2cproblem.hh" /*! @@ -110,17 +110,19 @@ int main(int argc, char** argv) try // 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(); + ///////////////////////////////////////////////////////////////////// + + GridManager gridManager; + gridManager.init(); //////////////////////////////////////////////////////////// // run instationary non-linear problem on this grid //////////////////////////////////////////////////////////// // we compute on the leaf grid view - const auto& leafGridView = GridCreator::grid().leafGridView(); + const auto& leafGridView = gridManager.grid().leafGridView(); // create the finite volume grid geometry using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); diff --git a/lecture/efm/1p2cvs2p/lens1p2cproblem.hh b/lecture/efm/1p2cvs2p/lens1p2cproblem.hh index 7ba76e2..bb28f27 100644 --- a/lecture/efm/1p2cvs2p/lens1p2cproblem.hh +++ b/lecture/efm/1p2cvs2p/lens1p2cproblem.hh @@ -118,7 +118,7 @@ class LensOnePTwoCProblem : public PorousMediumFlowProblem using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); - using GridView = typename GET_PROP_TYPE(TypeTag, GridView);// TODO: Do we use now GridCreator? + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); diff --git a/lecture/efm/1p2cvs2p/lens2pexercise1.cc b/lecture/efm/1p2cvs2p/lens2pexercise1.cc index 4614259..d3e53c5 100644 --- a/lecture/efm/1p2cvs2p/lens2pexercise1.cc +++ b/lecture/efm/1p2cvs2p/lens2pexercise1.cc @@ -45,7 +45,7 @@ #include #include - +#include #include /*! @@ -116,17 +116,19 @@ int main(int argc, char** argv) try // 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(); + ///////////////////////////////////////////////////////////////////// + + GridManager gridManager; + gridManager.init(); //////////////////////////////////////////////////////////// // run instationary non-linear problem on this grid //////////////////////////////////////////////////////////// // we compute on the leaf grid view - const auto& leafGridView = GridCreator::grid().leafGridView(); + const auto& leafGridView = gridManager.grid().leafGridView(); // create the finite volume grid geometry using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); diff --git a/lecture/efm/1p2cvs2p/lens2pproblem.hh b/lecture/efm/1p2cvs2p/lens2pproblem.hh index f042629..814b9e0 100644 --- a/lecture/efm/1p2cvs2p/lens2pproblem.hh +++ b/lecture/efm/1p2cvs2p/lens2pproblem.hh @@ -25,6 +25,7 @@ #ifndef DUMUX_LENS2P_PROBLEM_HH #define DUMUX_LENS2P_PROBLEM_HH +#include #include #include #include diff --git a/lecture/efm/2p/lens2pexercise2.cc b/lecture/efm/2p/lens2pexercise2.cc index cbe7ca0..a39644e 100755 --- a/lecture/efm/2p/lens2pexercise2.cc +++ b/lecture/efm/2p/lens2pexercise2.cc @@ -46,7 +46,7 @@ #include #include - +#include #include /*! @@ -119,17 +119,19 @@ int main(int argc, char** argv) try // 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(); + ///////////////////////////////////////////////////////////////////// + + GridManager gridManager; + gridManager.init(); //////////////////////////////////////////////////////////// // run instationary non-linear problem on this grid //////////////////////////////////////////////////////////// // we compute on the leaf grid view - const auto& leafGridView = GridCreator::grid().leafGridView(); + const auto& leafGridView = gridManager.grid().leafGridView(); // create the finite volume grid geometry using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); diff --git a/lecture/efm/2p/lens2pproblem.hh b/lecture/efm/2p/lens2pproblem.hh index 92547c8..1326a8e 100644 --- a/lecture/efm/2p/lens2pproblem.hh +++ b/lecture/efm/2p/lens2pproblem.hh @@ -28,15 +28,16 @@ #include #include #include +#include -// TODO: dnapl.hh does not exist anymore -> changed to trichloroethylene.hh #include -// liquidphase.hh does not exist anymore -> changed to liquidphase2c.hh + #include #include #include -// #include + +#include #include #include "../1p2c_2p_2p2c/lens2pspatialparams.hh" @@ -129,15 +130,15 @@ class LensTwoPProblem : public PorousMediumFlowProblem { using ParentType = typename PorousMediumFlowProblem; - using Params = typename GET_PROP(TypeTag, ParameterTree); + using Params = typename GET_PROP(TypeTag, ParameterTree); // TODO: What has to be done here? using GridView = typename GET_PROP_TYPE(TypeTag, GridView); using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - using Indices = typename GET_PROP_TYPE(TypeTag, Indices); + using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); using FluidState = typename GET_PROP_TYPE(TypeTag, FluidState); - using WettingPhase = typename GET_PROP_TYPE(TypeTag, WettingPhase); // kaiw: New PropertyTag for this and the next line? Check this if there are compilererrors. + using WettingPhase = typename GET_PROP_TYPE(TypeTag, WettingPhase); using NonwettingPhase = typename GET_PROP_TYPE(TypeTag, NonwettingPhase); using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); @@ -158,7 +159,7 @@ class LensTwoPProblem : public PorousMediumFlowProblem // Grid and world dimension // dim = GridView::dimension, // dimWorld = GridView::dimensionworld - }; + static constexpr int dim = GridView::dimension; static constexpr int dimWorld = GridView::dimensionworld; diff --git a/lecture/mm/convectivemixing/convmixexercise.cc b/lecture/mm/convectivemixing/convmixexercise.cc index 7555d62..4d496d2 100644 --- a/lecture/mm/convectivemixing/convmixexercise.cc +++ b/lecture/mm/convectivemixing/convmixexercise.cc @@ -18,7 +18,30 @@ *****************************************************************************/ #include "config.h" #include "convmixproblem.hh" -#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include + //! Prints a usage/help message if something goes wrong or the user asks for help void usage(const char *progName, const std::string &errorMsg) /*@\label{tutorial-coupled:usage-function}@*/ diff --git a/lecture/mm/convectivemixing/convmixexercise.input b/lecture/mm/convectivemixing/convmixexercise.input index 6d370a2..0f6966a 100644 --- a/lecture/mm/convectivemixing/convmixexercise.input +++ b/lecture/mm/convectivemixing/convmixexercise.input @@ -1,6 +1,6 @@ tau = 0.706 -[TimeManager] +[TimeLoop] TEnd = 1.e9 # duration of the simulation [s] DtInitial = 10 # initial time step size [s] EpisodeLength = 1.e7 diff --git a/lecture/mm/convectivemixing/convmixproblem.hh b/lecture/mm/convectivemixing/convmixproblem.hh index c42e8f6..8a79327 100644 --- a/lecture/mm/convectivemixing/convmixproblem.hh +++ b/lecture/mm/convectivemixing/convmixproblem.hh @@ -19,11 +19,15 @@ #ifndef DUMUX_CONVECTIVE_MIXING_PROBLEM_HH #define DUMUX_CONVECTIVE_MIXING_PROBLEM_HH -#include -#include - +#include +#include +#include +#include #include -#include + +// #include // TODO: How to replace this?? +#include + #include #include @@ -37,7 +41,7 @@ class ConvectiveMixingProblem; namespace Properties { -NEW_TYPE_TAG(ConvectiveMixingProblem, INHERITS_FROM(BoxOnePTwoC, ConvMixSpatialParams)); +NEW_TYPE_TAG(ConvectiveMixingProblem, INHERITS_FROM(BoxModel, ConvMixSpatialParams)); // Set the grid type SET_TYPE_PROP(ConvectiveMixingProblem, Grid, Dune::YaspGrid<2>); @@ -46,7 +50,7 @@ SET_TYPE_PROP(ConvectiveMixingProblem, Grid, Dune::YaspGrid<2>); SET_TYPE_PROP(ConvectiveMixingProblem, Problem, ConvectiveMixingProblem); // Set fluid configuration -SET_TYPE_PROP(ConvectiveMixingProblem, FluidSystem,BrineCO2FluidSystem); +SET_TYPE_PROP(ConvectiveMixingProblem, FluidSystem, BrineCO2); //! The constant tau function is used for the effective diffusivity SET_PROP(ConvectiveMixingProblem, EffectiveDiffusivityModel) @@ -54,7 +58,7 @@ SET_PROP(ConvectiveMixingProblem, EffectiveDiffusivityModel) private: typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; public: - typedef DiffusivityConstantTau type; + typedef DiffusivityConstantTortuosity type; }; // Set the CO2 table to be used; in this case not the the default table @@ -63,8 +67,6 @@ SET_TYPE_PROP(ConvectiveMixingProblem, CO2Table, CO2TablesBenchmarkThree::CO2Tab //Define whether mole(true) or mass (false) fractions are used SET_BOOL_PROP(ConvectiveMixingProblem, UseMoles, false); -// Disable gravity -SET_BOOL_PROP(ConvectiveMixingProblem, ProblemEnableGravity, true); } template @@ -100,8 +102,8 @@ class ConvectiveMixingProblem : public PorousMediumFlowProblem using ElementIterator = typename GridView::template Codim<0>::Iterator; using Vertex = typename GridView::template Codim::Entity; using Intersection = typename GridView::Intersection; - - using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); + using FVGridGeometry = typename GET_PROP_TYPE(TypeTag,FVGridGeometry); + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; using GlobalPosition = typename Element::Geometry::GlobalCoordinate; using CO2Table = typename GET_PROP_TYPE(TypeTag, PTAG(CO2Table)); @@ -111,12 +113,12 @@ class ConvectiveMixingProblem : public PorousMediumFlowProblem public: ConvectiveMixingProblem(std::shared_ptr fvGridGeometry ) : ParentType(fvGridGeometry) { - depthBOR_ = get_Param(TypeTag, Scalar, Problem.DepthBOR); - name_ = GET_RUNTIME_PARAM(TypeTag, std::string, Problem.Name); + depthBOR_ = getParam("Problem.DepthBOR"); + name_ =getParam("Problem.Name"); FluidSystem::init(); - episodeLength_ = GET_RUNTIME_PARAM(TypeTag, Scalar, TimeManager.EpisodeLength); - this->timeManager().startNextEpisode(episodeLength_); + episodeLength_ = getParam("TimeLoop.EpisodeLength"); + this->timeLoop().startNextEpisode(episodeLength_); } /*! @@ -155,8 +157,9 @@ public: * \brief Specifies which kind of boundary condition should be * used for which equation on a given boundary segment. */ - void boundaryTypes(BoundaryTypes &values, const Vertex &vertex) const + BoundaryTypes boundaryTypes(const Vertex &vertex) const { + BoundaryTypes values; const GlobalPosition globalPos = vertex.geometry().center(); values.setAllNeumann(); @@ -170,6 +173,8 @@ public: { values.setAllDirichlet(); // set bottom boundary to Dirichlet for continuity and transport equation } + + return values; } /*! @@ -178,8 +183,9 @@ public: * * For this method, the \a values parameter stores primary variables. */ - void dirichlet(PrimaryVariables &values, const Vertex &vertex) const + PrimaryVariables dirichlet( const Vertex &vertex) const { + PrimaryVariables values; const GlobalPosition& globalPos = vertex.geometry().center(); initial_(values, globalPos); @@ -194,14 +200,13 @@ public: * influx. */ using ParentType::neumann; - void neumann(PrimaryVariables &values, - const Element &element, + PrimaryVariables neumann(const Element &element, const FVElementGeometry &fvElemGeom, const Intersection &is, int scvIdx, int boundaryFaceIdx) const { - values = 0; + return PrimaryVariables(0.0); } // \} @@ -220,10 +225,9 @@ public: * unit. Positive values mean that mass is created, negative ones * mean that it vanishes. */ - void sourceAtPos(PrimaryVariables &values, - const GlobalPosition &globalPos) const + PrimaryVariables sourceAtPos(const GlobalPosition &globalPos) const { - values = 0.0; + return PrimaryVariables(0.0); } /*! @@ -232,70 +236,29 @@ public: * For this method, the \a values parameter stores primary * variables. */ - void initial(PrimaryVariables &values, - const Element &element, + PrimaryVariables initial( const Element &element, const FVElementGeometry &fvElemGeom, int scvIdx) const { + PrimaryVariables values; const GlobalPosition &globalPos = element.geometry().corner(scvIdx); - initial_(values, globalPos); - } - - bool shouldWriteOutput() const - { - return this->timeManager().timeStepIndex() == 0 || - this->timeManager().episodeWillBeFinished() || - this->timeManager().willBeFinished(); - } - + return(initial_(globalPos) ); - // apply a constant timestep size - void preTimeStep() - { - // this->timeManager().setTimeStepSize(1e3); - } - /*! - * \brief Called by Dune::TimeManager whenever a solution for a - * timestep has been computed and the simulation time has - * been updated. - * - * This is used to do some janitorial tasks like writing the - * current solution to disk. - */ - void postTimeStep() - { - PrimaryVariables mass(0); - this->model().globalStorage(mass); - const Scalar time = this->timeManager().time()+this->timeManager().timeStepSize(); - - // Write mass balance information for rank 0 - if (this->gridView().comm().rank() == 0) { - std::cout << "time (in s), mass CO2 (in kg): \n" - <timeManager().startNextEpisode(episodeLength_); - }; - - // \} - private: // the internal method for the initial condition and dirichlet boundary conditions // returns the values for the two primary variables pressure and CO2 massfraction - void initial_(PrimaryVariables &values, - const GlobalPosition &globalPos) const + PrimaryVariables initial_(const GlobalPosition &globalPos) const { + PrimaryVariables values; + const Scalar temp = temperatureAtPos(globalPos); - const Scalar salinity = GET_PARAM_FROM_GROUP(TypeTag, Scalar, Problem, Salinity); + const Scalar salinity = getParam("Problem.Salinity"); values[pressureIdx] = 1.013e5 + (depthBOR_ - globalPos[1]) * 1100 * 9.81; // hydrostatic pressure distribution values[massFracIdx] = 0; // initial condition for the co2 mass fraction @@ -317,6 +280,7 @@ private: { values[massFracIdx] = massFracCO2; // CO2 massfraction at top boundary [-] } + return values; } static constexpr Scalar eps_ = 1e-6; diff --git a/lecture/mm/convectivemixing/convmixspatialparams.hh b/lecture/mm/convectivemixing/convmixspatialparams.hh index 98f0c4f..9c510b3 100644 --- a/lecture/mm/convectivemixing/convmixspatialparams.hh +++ b/lecture/mm/convectivemixing/convmixspatialparams.hh @@ -19,7 +19,7 @@ #ifndef DUMUX_CONVMIX_SPATIAL_PARAMETERS_HH #define DUMUX_CONVMIX_SPATIAL_PARAMETERS_HH -#include +#include #include #include #include @@ -27,7 +27,7 @@ namespace Dumux { //forward declaration -template +template class ConvMixSpatialParams; namespace Properties @@ -44,13 +44,13 @@ SET_TYPE_PROP(ConvMixSpatialParams, SpatialParams, Dumux::ConvMixSpatialParams -class ConvMixSpatialParams : public FVSpatialParams> +template +class ConvMixSpatialParams : public FVSpatialParams> { using ParentType = PorousMediumFlowProblem; using GridView = typename GET_PROP_TYPE(TypeTag, GridView); using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; using Element = typename GridView::template Codim<0>::Entity; public: @@ -58,7 +58,7 @@ public: : ParentType(gridView) { // intrinsic permeability [m^2] - permeability_ = GET_RUNTIME_PARAM(TypeTag, Scalar, SpatialParams.Permeability); + permeability_ = getParam("SpatialParams.Permeability"); } ~ConvMixSpatialParams() -- GitLab From b6811e2e4fc1c3185ddc87ec0985ced4b6b56abe Mon Sep 17 00:00:00 2001 From: Kai Wendel Date: Mon, 17 Sep 2018 14:19:08 +0200 Subject: [PATCH 07/60] fixed typos, henryproblem does work completely, others do have mainly TypeTag errors. Changed TypeTag names so that it can be distinguished from the class names. efm and mhs do still need small corrections --- lecture/common/co2tablesbenchmark3.hh | 12 +- lecture/common/viplaboutput.hh | 11 +- lecture/efm/1p2c_2p_2p2c/lens1p2cexercise3.cc | 13 +- lecture/efm/1p2c_2p_2p2c/lens1p2cproblem.hh | 48 +- .../efm/1p2c_2p_2p2c/lens1p2cspatialparams.hh | 38 +- lecture/efm/1p2c_2p_2p2c/lens2p2cexercise3.cc | 11 +- lecture/efm/1p2c_2p_2p2c/lens2p2cproblem.hh | 45 +- lecture/efm/1p2c_2p_2p2c/lens2pexercise3.cc | 12 +- lecture/efm/1p2c_2p_2p2c/lens2pproblem.hh | 39 +- .../efm/1p2c_2p_2p2c/lens2pspatialparams.hh | 32 +- lecture/efm/1p2cvs2p/lens1p2cexercise1.cc | 9 +- lecture/efm/1p2cvs2p/lens1p2cproblem.hh | 51 +- lecture/efm/1p2cvs2p/lens2pproblem.hh | 61 +-- lecture/efm/2p/lens2pproblem.hh | 103 +--- lecture/mhs/groundwater/groundwater.cc | 37 +- lecture/mhs/groundwater/groundwater.input | 3 +- lecture/mhs/groundwater/groundwaterproblem.hh | 104 ++-- .../groundwater/groundwaterspatialparams.hh | 27 +- .../buckleyleverettanalyticsolution.hh | 79 +-- .../buckleyleverettexercise.cc | 3 +- .../buckleyleverett/buckleyleverettproblem.hh | 90 ++-- .../buckleyleverettspatialparams.hh | 54 +- lecture/mm/buckleyleverett/pseudoh2o.hh | 21 +- lecture/mm/buckleyleverett/pseudooil.hh | 25 +- lecture/mm/co2plume/co2plumeshapeexercise.cc | 243 +++++++-- .../mm/co2plume/co2plumeshapeexercise.input | 7 +- lecture/mm/co2plume/co2plumeshapeproblem.hh | 418 +++++---------- .../co2plumeshapespatialparameters.hh | 209 +++----- .../mm/columnxylene/columnxyleneexercise.cc | 10 +- .../columnxylene/columnxyleneexercise.input | 2 - .../mm/columnxylene/columnxyleneproblem.hh | 148 ++--- .../mm/columnxylene/columnxyleneproblem2.hh | 199 ++++--- .../columnxylene/columnxylenespatialparams.hh | 35 +- .../columnxylenespatialparams2.hh | 80 +-- .../mm/convectivemixing/convmixexercise.cc | 152 +++++- lecture/mm/convectivemixing/convmixproblem.hh | 78 ++- .../convectivemixing/convmixspatialparams.hh | 22 +- lecture/mm/fuelcell/fuelcell.cc | 10 +- lecture/mm/fuelcell/fuelcellproblem.hh | 164 ++---- lecture/mm/fuelcell/fuelcellspatialparams.hh | 69 ++- .../mm/heavyoil/3p/parkervangenuchtenzero.hh | 48 +- .../3p/parkervangenuchtenzerohysteresis.hh | 58 +- .../parkervangenuchtenzerohysteresisparams.hh | 204 +++++-- .../3p/parkervangenuchtenzeroparams.hh | 194 +++++-- .../3p/relativepermeabilityhysteresis.hh | 30 +- .../relativepermeabilityhysteresisparams.hh | 506 +++++++++++++----- lecture/mm/heavyoil/sagd/problem.hh | 76 +-- lecture/mm/heavyoil/sagd/sagd.cc | 7 +- lecture/mm/heavyoil/sagd/spatialparams.hh | 40 +- lecture/mm/heavyoil/sagdcyclic/problem.hh | 188 ++----- lecture/mm/heavyoil/sagdcyclic/sagd_cyclic.cc | 44 +- .../mm/heavyoil/sagdcyclic/spatialparams.hh | 88 ++- lecture/mm/heavyoil/sagdcyclichyst/problem.hh | 157 +++--- .../sagdcyclichyst/sagd_cyclic_hyst.cc | 40 +- .../heavyoil/sagdcyclichyst/spatialparams.hh | 74 ++- .../mm/henryproblem/henry1p2c/henry1p2c.cc | 4 +- .../henry1p2c/henry1p2cproblem.hh | 70 +-- .../henry1p2c/henry1p2cspatialparameters.hh | 19 +- .../henry1p2c/watersaltfluidsystem.hh | 193 +++---- lecture/mm/henryproblem/henry2p/henry2p.cc | 6 +- lecture/mm/henryproblem/henry2p/henry2p.input | 2 - .../mm/henryproblem/henry2p/henry2pproblem.hh | 101 ++-- .../henry2p/henry2pspatialparams.hh | 12 +- .../henryproblem/henry2p/simplesaltwater.hh | 80 +-- .../mm/mcwhorter/mcwhorteranalyticsolution.hh | 157 ++---- lecture/mm/mcwhorter/mcwhorterproblem.hh | 94 ++-- 66 files changed, 2598 insertions(+), 2668 deletions(-) diff --git a/lecture/common/co2tablesbenchmark3.hh b/lecture/common/co2tablesbenchmark3.hh index be5ed36..651a4ac 100644 --- a/lecture/common/co2tablesbenchmark3.hh +++ b/lecture/common/co2tablesbenchmark3.hh @@ -27,14 +27,12 @@ #include -namespace Dumux -{ -namespace CO2TablesBenchmarkThree -{ +namespace Dumux { +namespace CO2TablesBenchmarkThree { // the real work is done by some external program which provides // ready-to-use tables. #include "co2values.inc" -} -} +} // end namespace CO2TablesBenchmarkThree +} // end namespace Dumux -#endif +#endif // DUMUX_HETEROGENEOUS_CO2TABLES_HH diff --git a/lecture/common/viplaboutput.hh b/lecture/common/viplaboutput.hh index 6a25b6f..c8fdab3 100644 --- a/lecture/common/viplaboutput.hh +++ b/lecture/common/viplaboutput.hh @@ -24,8 +24,7 @@ #ifndef DUMUX_VIPLAB_OUTPUT_HH #define DUMUX_VIPLAB_OUTPUT_HH -namespace Dumux -{ +namespace Dumux { /** * \brief Writes output to use with ViPLab. * @@ -108,8 +107,9 @@ public: dataFile_.close(); } - void writeViplabOutput2d(const std::vector &solution){ - + void writeViplabOutput2d(const std::vector &solution) + { + // TODO: check if this is used anymore: // double ymin= *min_element(solution.begin(),solution.end()); // Scalar zmax, zmin; // zmax=problem_.variables().cellData(0).pressure()/(Fluid::density(0,0)*9.81); @@ -254,6 +254,7 @@ private: std::string outputName_; std::vector upperRight_; }; + }//end namespace Dumux -#endif +#endif // DUMUX_VIPLAB_OUTPUT_HH diff --git a/lecture/efm/1p2c_2p_2p2c/lens1p2cexercise3.cc b/lecture/efm/1p2c_2p_2p2c/lens1p2cexercise3.cc index e5b640a..f15abf6 100755 --- a/lecture/efm/1p2c_2p_2p2c/lens1p2cexercise3.cc +++ b/lecture/efm/1p2c_2p_2p2c/lens1p2cexercise3.cc @@ -52,9 +52,6 @@ * Comprises the thing that went wrong and a general help message. */ - - - void usage(const char *progName, const std::string &errorMsg) { if (errorMsg.size() > 0) { @@ -86,12 +83,10 @@ void usage(const char *progName, const std::string &errorMsg) //////////////////////// int main(int argc, char** argv) try { - // typedef TTAG(LensOnePTwoCProblem) TypeTag; - // return Dumux::start(argc, argv, usage); using namespace Dumux; // define the type tag for this problem - using TypeTag = TTAG(LensOnePTwoCProblem); + using TypeTag = TTAG(LensOnePTwoCProblemTypeTag); // initialize MPI, finalize is done automatically on exit const auto& mpiHelper = Dune::MPIHelper::instance(argc, argv); @@ -210,8 +205,7 @@ int main(int argc, char** argv) try DumuxMessage::print(/*firstCall=*/false); } - - + return 0; } catch (Dumux::ParameterException &e) @@ -219,6 +213,7 @@ catch (Dumux::ParameterException &e) std::cerr << std::endl << e << " ---> Abort!" << std::endl; return 1; } + catch (Dune::DGFException & e) { std::cerr << "DGF exception thrown (" << e << @@ -228,11 +223,13 @@ catch (Dune::DGFException & e) << " ---> 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; diff --git a/lecture/efm/1p2c_2p_2p2c/lens1p2cproblem.hh b/lecture/efm/1p2c_2p_2p2c/lens1p2cproblem.hh index e277e66..a3dad9e 100644 --- a/lecture/efm/1p2c_2p_2p2c/lens1p2cproblem.hh +++ b/lecture/efm/1p2c_2p_2p2c/lens1p2cproblem.hh @@ -22,21 +22,18 @@ * \brief Exercise to show the diffusive spreading of contaminants. */ - #ifndef DUMUX_LENS_1P2C_PROBLEM_HH #define DUMUX_LENS_1P2C_PROBLEM_HH #include #include #include -// #include #include #include #include "lens1p2cspatialparams.hh" -namespace Dumux -{ +namespace Dumux { template class LensOnePTwoCProblem; @@ -44,19 +41,20 @@ class LensOnePTwoCProblem; ////////// // Specify the properties for the lens problem ////////// -namespace Properties -{ -NEW_TYPE_TAG(LensOnePTwoCProblem, INHERITS_FROM(BoxModel, OnePNC, Lens1p2cSpatialParams)); +namespace Properties { + +NEW_TYPE_TAG(LensOnePTwoCProblemTypeTag, INHERITS_FROM(BoxModel, OnePNC, Lens1p2cSpatialParamsTypeTag)); // Set the grid type -SET_TYPE_PROP(LensOnePTwoCProblem, Grid, Dune::YaspGrid<2>); +SET_TYPE_PROP(LensOnePTwoCProblemTypeTag, Grid, Dune::YaspGrid<2>); // Set the problem property -SET_TYPE_PROP(LensOnePTwoCProblem, Problem, LensOnePTwoCProblem); +SET_TYPE_PROP(LensOnePTwoCProblemTypeTag, Problem, LensOnePTwoCProblem); // Set fluid configuration -SET_PROP(LensOnePTwoCProblem, FluidSystem) -{private: +SET_PROP(LensOnePTwoCProblemTypeTag, FluidSystem) +{ +private: using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); static const bool useComplexRelations = false; public: @@ -64,9 +62,9 @@ public: }; // Define whether mole(true) or mass(false) fractions are used -SET_BOOL_PROP(LensOnePTwoCProblem, UseMoles, true); +SET_BOOL_PROP(LensOnePTwoCProblemTypeTag, UseMoles, true); -} +} // end namespace Properties /*! * \ingroup TwoPBoxProblems @@ -97,33 +95,22 @@ template class LensOnePTwoCProblem : public PorousMediumFlowProblem { using ParentType = PorousMediumFlowProblem; - using GridView = typename GET_PROP_TYPE(TypeTag, GridView); using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables); - using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; - using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); - using Element = typename GridView::template Codim<0>::Entity; - using GlobalPosition = typename Element::Geometry::GlobalCoordinate; using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; using SubControlVolume = typename FVElementGeometry::SubControlVolume; using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace; using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); - using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector); using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector); - - - - public: /*! * \brief The constructor @@ -131,7 +118,7 @@ public: */ LensOnePTwoCProblem(std::shared_ptr fvGridGeometry ) - : ParentType(fvGridGeometry) + : ParentType(fvGridGeometry) { // the boundary condition data lowerPressure_ = getParam("Boundary.LowerPressure"); @@ -160,7 +147,7 @@ public: Scalar temperature() const { return 273.15 + 10; // -> 10 degrees Celsius - }; + } // \} @@ -182,6 +169,7 @@ public: BoundaryTypes values; if (onUpperBoundary_(globalPos) || onLowerBoundary_(globalPos)) values.setAllDirichlet(); + else values.setAllNeumann(); @@ -205,10 +193,12 @@ public: { values[Indices::pressureIdx] = upperPressure_; } + else if (onLowerBoundary_(globalPos)) { values[Indices::pressureIdx] = lowerPressure_; } + return values; } @@ -310,7 +300,9 @@ private: Scalar infiltrationEndTime_; bool paraviewOutput_; std::vector numCells_; + }; -} //end namespace -#endif +} //end namespace Dumux + +#endif // DUMUX_LENS_1P2C_PROBLEM_HH diff --git a/lecture/efm/1p2c_2p_2p2c/lens1p2cspatialparams.hh b/lecture/efm/1p2c_2p_2p2c/lens1p2cspatialparams.hh index fa5aea3..ea0658a 100644 --- a/lecture/efm/1p2c_2p_2p2c/lens1p2cspatialparams.hh +++ b/lecture/efm/1p2c_2p_2p2c/lens1p2cspatialparams.hh @@ -28,20 +28,18 @@ * @author Bernd Flemisch, Klaus Mosthaf, Markus Wolff */ -namespace Dumux -{ +namespace Dumux { //forward declaration template class Lens1p2cSpatialParams; -namespace Properties -{ +namespace Properties { // The spatial parameters TypeTag -NEW_TYPE_TAG(Lens1p2cSpatialParams); +NEW_TYPE_TAG(Lens1p2cSpatialParamsTypeTag); // Set the spatial parameters -SET_PROP(Lens1p2cSpatialParams, SpatialParams) +SET_PROP(Lens1p2cSpatialParamsTypeTag, SpatialParams) { private: using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); @@ -49,7 +47,8 @@ private: public: using type = Lens1p2cSpatialParams; }; -} + +} // end namespace Properties /** \todo Please doc me! */ @@ -58,12 +57,10 @@ class Lens1p2cSpatialParams : public FVSpatialParamsOneP; using ParentType = FVSpatialParamsOneP; - using GridView = typename FVGridGeometry::GridView; using Element = typename GridView::template Codim<0>::Entity; using FVElementGeometry = typename FVGridGeometry::LocalView; using SubControlVolume = typename FVElementGeometry::SubControlVolume; - static constexpr int dim = GridView::dimension; static constexpr int dimWorld = GridView::dimensionworld; using GlobalPosition = typename Element::Geometry::GlobalCoordinate; @@ -109,6 +106,7 @@ public: { if (isInLens_(globalPos)) return lensK_; + return outerK_; } @@ -116,6 +114,7 @@ public: { if (isInLens_(globalPos)) return lensPorosity_; + return outerPorosity_; } /*! @@ -125,8 +124,7 @@ public: */ //! Set the bounding box of the fine-sand lens - void setLensCoords(const GlobalPosition& lensLowerLeft, - const GlobalPosition& lensUpperRight) + void setLensCoords(const GlobalPosition& lensLowerLeft, const GlobalPosition& lensUpperRight) { lensLowerLeft_ = lensLowerLeft; lensUpperRight_ = lensUpperRight; @@ -140,8 +138,8 @@ public: * \param scvIdx The local index of the sub-control volume where */ Dune::FieldVector dispersivity(const Element &element, - const FVElementGeometry &fvElemGeom, - int scvIdx) const + const FVElementGeometry &fvElemGeom, + int scvIdx) const { Dune::FieldVector values (0); values[0] = longitudinalDispersivity_; // alpha_l @@ -155,14 +153,11 @@ public: * \param vertexI DOC ME! * \param vertexJ DOC ME! */ - bool useTwoPointGradient(const Element &elem, - int vertexI, - int vertexJ) const + bool useTwoPointGradient(const Element &elem, int vertexI, int vertexJ) const { return false; } - private: /*! * \brief DOC ME! @@ -170,10 +165,12 @@ private: */ bool isInLens_(const GlobalPosition &pos) const { - for (int i = 0; i < dimWorld; ++i) { + for (int i = 0; i < dimWorld; ++i) + { if (pos[i] < lensLowerLeft_[i] || pos[i] > lensUpperRight_[i]) return false; } + return true; } @@ -188,5 +185,6 @@ private: Scalar transverseDispersivity_; }; -} // end namespace -#endif +} // end namespace Dumux + +#endif // DUMUX_1P2C_SPATIALPARAMS_HH diff --git a/lecture/efm/1p2c_2p_2p2c/lens2p2cexercise3.cc b/lecture/efm/1p2c_2p_2p2c/lens2p2cexercise3.cc index 70e0d7e..3914288 100644 --- a/lecture/efm/1p2c_2p_2p2c/lens2p2cexercise3.cc +++ b/lecture/efm/1p2c_2p_2p2c/lens2p2cexercise3.cc @@ -52,7 +52,6 @@ #include #include -// #include "config.h" #include "lens2p2cproblem.hh" /*! * \brief Provides an interface for customizing error messages associated with @@ -62,7 +61,6 @@ * \param errorMsg The error message that was issued by the start function. * Comprises the thing that went wrong and a general help message. */ -// TODO: do we need this void-function anymore? void usage(const char *progName, const std::string &errorMsg) { if (errorMsg.size() > 0) { @@ -106,12 +104,10 @@ void usage(const char *progName, const std::string &errorMsg) //////////////////////// int main(int argc, char** argv) try { - // typedef TTAG(LensOnePTwoCProblem) TypeTag; - // return Dumux::start(argc, argv, usage); using namespace Dumux; // define the type tag for this problem - using TypeTag = TTAG(LensTwoPTwoCProblem); + using TypeTag = TTAG(LensTwoPTwoCProblemTypeTag); // initialize MPI, finalize is done automatically on exit const auto& mpiHelper = Dune::MPIHelper::instance(argc, argv); @@ -230,6 +226,8 @@ int main(int argc, char** argv) try Parameters::print(); DumuxMessage::print(/*firstCall=*/false); } + + return 0; } catch (Dumux::ParameterException &e) @@ -237,6 +235,7 @@ catch (Dumux::ParameterException &e) std::cerr << std::endl << e << " ---> Abort!" << std::endl; return 1; } + catch (Dune::DGFException & e) { std::cerr << "DGF exception thrown (" << e << @@ -246,11 +245,13 @@ catch (Dune::DGFException & e) << " ---> 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; diff --git a/lecture/efm/1p2c_2p_2p2c/lens2p2cproblem.hh b/lecture/efm/1p2c_2p_2p2c/lens2p2cproblem.hh index a13705a..3bc5b09 100644 --- a/lecture/efm/1p2c_2p_2p2c/lens2p2cproblem.hh +++ b/lecture/efm/1p2c_2p_2p2c/lens2p2cproblem.hh @@ -28,7 +28,7 @@ #define DUMUX_LENS_2P2C_PROBLEM_HH #include -// #include + #include #include "lens2pspatialparams.hh" @@ -36,11 +36,10 @@ #include #include #include -// #include + #include #include -namespace Dumux -{ +namespace Dumux { template class LensTwoPTwoCProblem; @@ -48,25 +47,27 @@ class LensTwoPTwoCProblem; ////////// // Specify the properties for the lens problem ////////// -namespace Properties -{ -NEW_TYPE_TAG(LensTwoPTwoCProblem, INHERITS_FROM(TwoPTwoC, BoxModel, Lens2pSpatialParams)); +namespace Properties { + +NEW_TYPE_TAG(LensTwoPTwoCProblemTypeTag, INHERITS_FROM(TwoPTwoC, BoxModel, Lens2pSpatialParamsTypeTag)); // Set the grid type -SET_TYPE_PROP(LensTwoPTwoCProblem, Grid, Dune::YaspGrid<2>); +SET_TYPE_PROP(LensTwoPTwoCProblemTypeTag, Grid, Dune::YaspGrid<2>); // Set the problem property -SET_TYPE_PROP(LensTwoPTwoCProblem, Problem, LensTwoPTwoCProblem); +SET_TYPE_PROP(LensTwoPTwoCProblemTypeTag, Problem, LensTwoPTwoCProblem); // Set fluid configuration -SET_PROP(LensTwoPTwoCProblem, FluidSystem) -{private: +SET_PROP(LensTwoPTwoCProblemTypeTag, FluidSystem) +{ +private: using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); static const bool useComplexRelations = false; public: using type = FluidSystems::H2ON2; }; -} + +} // end namespace Properties /*! * \ingroup TwoPTwoCModel @@ -87,35 +88,28 @@ class LensTwoPTwoCProblem: public PorousMediumFlowProblem using ParentType = PorousMediumFlowProblem; using GridView = typename GET_PROP_TYPE(TypeTag, GridView); using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables); using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; - using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); - using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; using SubControlVolume = typename FVElementGeometry::SubControlVolume; using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace; using Element = typename GridView::template Codim<0>::Entity; - using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector); using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector); - static constexpr int dim = GridView::dimension; static constexpr int dimWorld = GridView::dimensionworld; using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - public: /*! * \brief The constructor * * \param gridView The grid view */ - LensTwoPTwoCProblem(std::shared_ptr fvGridGeometry ) : ParentType(fvGridGeometry) { @@ -181,6 +175,7 @@ public: BoundaryTypes values; if (onUpperBoundary_(globalPos) || onLowerBoundary_(globalPos)) values.setAllDirichlet(); + else values.setAllNeumann(); @@ -205,6 +200,7 @@ public: values[Indices::pressureIdx] = upperPressure_; values[Indices::switchIdx] = 0.0; } + else if (onLowerBoundary_(globalPos)) { values[Indices::pressureIdx] = lowerPressure_; @@ -275,6 +271,7 @@ public: if (isInitial_(globalPos)) values.setState(Indices::bothPhases); + else values.setState(Indices::firstPhaseOnly); @@ -289,9 +286,7 @@ public: } // \} - private: - Scalar eps_; Scalar episodeLength_; // [s] Scalar temperature_; // [K] @@ -322,10 +317,10 @@ private: */ bool isInitial_(const GlobalPosition &globalPos) const { - return (globalPos[1] > 1.0 && globalPos[1] < 1.25 && globalPos[0] > 1.7 - && globalPos[0] < 2.3); + return (globalPos[1] > 1.0 && globalPos[1] < 1.25 && globalPos[0] > 1.7 && globalPos[0] < 2.3); } }; -} //end namespace -#endif +} //end namespace Dumux + +#endif // DUMUX_LENS_2P2C_PROBLEM_HH diff --git a/lecture/efm/1p2c_2p_2p2c/lens2pexercise3.cc b/lecture/efm/1p2c_2p_2p2c/lens2pexercise3.cc index adbed8d..5f17a46 100755 --- a/lecture/efm/1p2c_2p_2p2c/lens2pexercise3.cc +++ b/lecture/efm/1p2c_2p_2p2c/lens2pexercise3.cc @@ -57,7 +57,7 @@ * \param errorMsg The error message that was issued by the start function. * Comprises the thing that went wrong and a general help message. */ -// TODO is this void-function still in use? + void usage(const char *progName, const std::string &errorMsg) { if (errorMsg.size() > 0) { @@ -101,12 +101,10 @@ void usage(const char *progName, const std::string &errorMsg) //////////////////////// int main(int argc, char** argv) try { - // typedef TTAG(LensOnePTwoCProblem) TypeTag; - // return Dumux::start(argc, argv, usage); using namespace Dumux; // define the type tag for this problem - using TypeTag = TTAG(LensTwoPProblem); + using TypeTag = TTAG(LensTwoPProblemTypeTag); // initialize MPI, finalize is done automatically on exit const auto& mpiHelper = Dune::MPIHelper::instance(argc, argv); @@ -225,8 +223,7 @@ int main(int argc, char** argv) try DumuxMessage::print(/*firstCall=*/false); } - - + return 0; } catch (Dumux::ParameterException &e) @@ -234,6 +231,7 @@ catch (Dumux::ParameterException &e) std::cerr << std::endl << e << " ---> Abort!" << std::endl; return 1; } + catch (Dune::DGFException & e) { std::cerr << "DGF exception thrown (" << e << @@ -243,11 +241,13 @@ catch (Dune::DGFException & e) << " ---> 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; diff --git a/lecture/efm/1p2c_2p_2p2c/lens2pproblem.hh b/lecture/efm/1p2c_2p_2p2c/lens2pproblem.hh index 84bd9e4..9b7ace1 100644 --- a/lecture/efm/1p2c_2p_2p2c/lens2pproblem.hh +++ b/lecture/efm/1p2c_2p_2p2c/lens2pproblem.hh @@ -38,8 +38,7 @@ #include "lens2pspatialparams.hh" -namespace Dumux -{ +namespace Dumux { template class LensTwoPProblem; @@ -47,25 +46,26 @@ class LensTwoPProblem; ////////// // Specify the properties for the lens problem ////////// -namespace Properties -{ -NEW_TYPE_TAG(LensTwoPProblem, INHERITS_FROM(TwoP, BoxModel, Lens2pSpatialParams)); +namespace Properties { + +NEW_TYPE_TAG(LensTwoPProblemTypeTag, INHERITS_FROM(TwoP, BoxModel, Lens2pSpatialParamsTypeTag)); // Set the grid type -SET_TYPE_PROP(LensTwoPProblem, Grid, Dune::YaspGrid<2>); +SET_TYPE_PROP(LensTwoPProblemTypeTag, Grid, Dune::YaspGrid<2>); // Set the problem property -SET_TYPE_PROP(LensTwoPProblem, Problem, LensTwoPProblem); +SET_TYPE_PROP(LensTwoPProblemTypeTag, Problem, LensTwoPProblem); // Set the fluid system -SET_PROP(LensTwoPProblem, FluidSystem) +SET_PROP(LensTwoPProblemTypeTag, FluidSystem) { using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); using WettingPhase = FluidSystems::OnePLiquid >; using NonwettingPhase = FluidSystems::OnePGas >; using type = FluidSystems::TwoPImmiscible; }; -} + +} // end namespace Properties /*! * \ingroup TwoPBoxProblems @@ -108,14 +108,10 @@ class LensTwoPProblem : public PorousMediumFlowProblem using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); - using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); using FluidState = typename GET_PROP_TYPE(TypeTag, FluidState); - - using Element = typename GridView::template Codim<0>::Entity; using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector); @@ -123,18 +119,13 @@ class LensTwoPProblem : public PorousMediumFlowProblem public: /*! * \brief The constructor - * - * \param timeManager The time manager - * \param gridView The grid view */ LensTwoPProblem(std::shared_ptr fvGridGeometry) : ParentType(fvGridGeometry) { - // this is placed down to the declaration of the private varialbes as it is done in all other cases i have seen eps_ = 3e-6; - // the boundary condition data - lowerPressure_ = getParam("Boundary.LowerPressure"); // GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Boundary, LowerPressure); - upperPressure_ = getParam("Boundary.UpperPressure"); // GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Boundary, UpperPressure); + lowerPressure_ = getParam("Boundary.LowerPressure"); + upperPressure_ = getParam("Boundary.UpperPressure"); } /*! @@ -181,6 +172,7 @@ public: BoundaryTypes values; if (onUpperBoundary_(globalPos) || onLowerBoundary_(globalPos)) values.setAllDirichlet(); + else values.setAllNeumann(); @@ -209,6 +201,7 @@ public: values[Indices::pressureIdx] = upperPressure_; values[Indices::saturationIdx] = 0.0; } + else if (onLowerBoundary_(globalPos)) { values[Indices::pressureIdx] = lowerPressure_; @@ -286,7 +279,6 @@ public: // \} private: - static constexpr Scalar eps_ = 3e-6; Scalar episodeLength_; @@ -320,6 +312,7 @@ private: && globalPos[0] < 2.3 - eps_); } }; -} //end namespace -#endif +} //end namespace Dumux + +#endif // DUMUX_LENS2P_PROBLEM_HH diff --git a/lecture/efm/1p2c_2p_2p2c/lens2pspatialparams.hh b/lecture/efm/1p2c_2p_2p2c/lens2pspatialparams.hh index 8e76790..ba611f4 100644 --- a/lecture/efm/1p2c_2p_2p2c/lens2pspatialparams.hh +++ b/lecture/efm/1p2c_2p_2p2c/lens2pspatialparams.hh @@ -26,29 +26,25 @@ #ifndef DUMUX_LENS2P_SPATIALPARAMS_HH #define DUMUX_LENS2P_SPATIALPARAMS_HH -// #include #include #include #include #include #include - - -namespace Dumux -{ +namespace Dumux { //forward declaration template class Lens2pSpatialParams; -namespace Properties -{ +namespace Properties { + // The spatial parameters TypeTag -NEW_TYPE_TAG(Lens2pSpatialParams); +NEW_TYPE_TAG(Lens2pSpatialParamsTypeTag); // Set the spatial parameters -SET_PROP(Lens2pSpatialParams, SpatialParams) +SET_PROP(Lens2pSpatialParamsTypeTag, SpatialParams) { private: using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); @@ -56,25 +52,23 @@ private: public: using type = Lens2pSpatialParams; }; -} + +} // end namespace Properties /** \todo Please doc me! */ template class Lens2pSpatialParams -: public FVSpatialParams> +: public FVSpatialParams> { using GridView = typename FVGridGeometry::GridView; using Element = typename GridView::template Codim<0>::Entity; using FVElementGeometry = typename FVGridGeometry::LocalView; using SubControlVolume = typename FVElementGeometry::SubControlVolume; using ThisType = Lens2pSpatialParams; - using ParentType = FVSpatialParams; - static constexpr int dimWorld = GridView::dimensionworld; using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - using EffectiveLaw = RegularizedBrooksCorey; public: @@ -131,6 +125,7 @@ public: { if (isInLens_(element.geometry().center())) return lensK_; + else return outerK_; } @@ -152,6 +147,7 @@ public: { if (isInLens_(element.geometry().center())) return lensPorosity_; + else return outerPorosity_; } @@ -172,6 +168,7 @@ public: // const GlobalPosition &pos = fvElemGeom.subContVol[scvIdx].global; if (isInLense_(element.geometry().center() )) return std::cbrt(lensPorosity_); + else return std::cbrt(outerPorosity_); } @@ -192,6 +189,7 @@ public: { if (isInLens_(element.geometry().center())) return lensMaterialParams_; + else return outerMaterialParams_; } @@ -225,6 +223,7 @@ private: { // points on the lens boundary are considered inside for (int i = 0; i < dimWorld; ++i) + if (globalPos[i] < lensLowerLeft_[i] - eps_ || globalPos[i] > lensUpperRight_[i] + eps_) return false; @@ -243,5 +242,6 @@ private: Scalar eps_ = 1e-6; }; -} // end namespace -#endif +} // end namespace Dumux + +#endif // DUMUX_LENS2P_SPATIALPARAMS_HH diff --git a/lecture/efm/1p2cvs2p/lens1p2cexercise1.cc b/lecture/efm/1p2cvs2p/lens1p2cexercise1.cc index ce75b63..622461f 100644 --- a/lecture/efm/1p2cvs2p/lens1p2cexercise1.cc +++ b/lecture/efm/1p2cvs2p/lens1p2cexercise1.cc @@ -54,8 +54,6 @@ * \param errorMsg The error message that was issued by the start function. * Comprises the thing that went wrong and a general help message. */ - -// TODO: Do we need this function? void usage(const char *progName, const std::string &errorMsg) { if (errorMsg.size() > 0) { @@ -87,12 +85,6 @@ void usage(const char *progName, const std::string &errorMsg) //////////////////////// // the main function //////////////////////// -/* int main(int argc, char** argv) -{ - typedef TTAG(LensOnePTwoCProblem) TypeTag; - return Dumux::start(argc, argv, usage); -}*/ - int main(int argc, char** argv) try { using namespace Dumux; @@ -220,6 +212,7 @@ int main(int argc, char** argv) try return 0; } // end main + catch (Dumux::ParameterException &e) { std::cerr << std::endl << e << " ---> Abort!" << std::endl; diff --git a/lecture/efm/1p2cvs2p/lens1p2cproblem.hh b/lecture/efm/1p2cvs2p/lens1p2cproblem.hh index bb28f27..e3a496f 100644 --- a/lecture/efm/1p2cvs2p/lens1p2cproblem.hh +++ b/lecture/efm/1p2cvs2p/lens1p2cproblem.hh @@ -33,29 +33,27 @@ #include #include "../1p2c_2p_2p2c/lens1p2cspatialparams.hh" - -// TODO: see in dumux test porousmediumflow 1pnc implicit 1p2ctestproblem.hh an example for correct implementation of neumann BC. -namespace Dumux -{ +// TODO: see in dumux/test porousmediumflow/1pnc implicit 1p2ctestproblem.hh an example for correct implementation of neumann Boundary Conditions. +namespace Dumux { template -class LensOnePTwoCProblem; // : public PorousMediumFlowProblem; +class LensOnePTwoCProblem; ////////// // Specify the properties for the lens problem ////////// -namespace Properties -{ -NEW_TYPE_TAG(LensOnePTwoCProblem, INHERITS_FROM(OnePNC, BoxModel)); +namespace Properties { + +NEW_TYPE_TAG(LensOnePTwoCProblemTypeTag, INHERITS_FROM(OnePNC, BoxModel)); // Set the grid type -SET_TYPE_PROP(LensOnePTwoCProblem, Grid, Dune::YaspGrid<2>); +SET_TYPE_PROP(LensOnePTwoCProblemTypeTag, Grid, Dune::YaspGrid<2>); // Set the problem property -SET_TYPE_PROP(LensOnePTwoCProblem, Problem, LensOnePTwoCProblem); +SET_TYPE_PROP(LensOnePTwoCProblemTypeTag, Problem, LensOnePTwoCProblem); // set fluid system -SET_PROP(LensOnePTwoCProblem, FluidSystem) +SET_PROP(LensOnePTwoCProblemTypeTag, FluidSystem) { private: using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); @@ -65,7 +63,7 @@ public: }; // Set the spatial parameters -SET_PROP(LensOnePTwoCProblem, SpatialParams) +SET_PROP(LensOnePTwoCProblemTypeTag, SpatialParams) { private: using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); @@ -74,7 +72,7 @@ public: using type = Lens1p2cSpatialParams; }; -} +} // end namespace Properties /*! * \ingroup TwoPBoxProblems @@ -108,32 +106,21 @@ template class LensOnePTwoCProblem : public PorousMediumFlowProblem { using ParentType = PorousMediumFlowProblem; - using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - using ModelTraits = typename GET_PROP_TYPE(TypeTag, ModelTraits); - using Indices = typename ModelTraits::Indices; - - // using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; - + using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); - using GridView = typename GET_PROP_TYPE(TypeTag, GridView); using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); - using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; - using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector); - using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace; using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector); - static constexpr int dim = GridView::dimension; static constexpr int dimWorld = GridView::dimensionworld; using Element = typename GridView::template Codim<0>::Entity; using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - using TimeLoopPtr = std::shared_ptr>; public: @@ -143,7 +130,7 @@ public: * \param fvGridGeometry The Finite-Volume-Grid-Geometry */ LensOnePTwoCProblem( std::shared_ptr fvGridGeometry ) - : ParentType(fvGridGeometry) + : ParentType(fvGridGeometry) { FluidSystem::init(); @@ -154,13 +141,9 @@ public: infiltrationStartTime_= 1.0e-9; //The infiltrations starts always after the first time step! infiltrationEndTime_= getParam("Boundary.InfiltrationEndTime"); - // episodeLength_ = getParam("TimeManager.EpisodeLength"); // (TypeTag, Scalar, TimeManager, EpisodeLength); - // this->timeManager().startNextEpisode(episodeLength_); - // the boundary condition data lowerPressure_ = getParam("Boundary.LowerPressure"); upperPressure_ = getParam("Boundary.UpperPressure"); - } /*! @@ -208,6 +191,7 @@ public: BoundaryTypes values; if (onUpperBoundary_(globalPos) || onLowerBoundary_(globalPos)) values.setAllDirichlet(); + else values.setAllNeumann(); @@ -234,6 +218,7 @@ public: { values[Indices::pressureIdx] = upperPressure_; } + else if (onLowerBoundary_(globalPos)) { values[Indices::pressureIdx] = lowerPressure_; @@ -278,7 +263,6 @@ public: NumEqVector sourceAtPos(const GlobalPosition &globalPos) const { return NumEqVector(0.0); - } /*! @@ -355,6 +339,7 @@ private: TimeLoopPtr timeLoop_; std::vector numCells_; }; -} //end namespace -#endif +} //end namespace Dumux + +#endif // DUMUX_LENS_1P2C_PROBLEM_HH diff --git a/lecture/efm/1p2cvs2p/lens2pproblem.hh b/lecture/efm/1p2cvs2p/lens2pproblem.hh index 814b9e0..2b7d4ed 100644 --- a/lecture/efm/1p2cvs2p/lens2pproblem.hh +++ b/lecture/efm/1p2cvs2p/lens2pproblem.hh @@ -37,8 +37,7 @@ #include "../1p2c_2p_2p2c/lens2pspatialparams.hh" -namespace Dumux -{ +namespace Dumux { template class LensTwoPProblem; @@ -46,27 +45,19 @@ class LensTwoPProblem; ////////// // Specify the properties for the lens problem ////////// -namespace Properties -{ -NEW_TYPE_TAG(LensTwoPProblem, INHERITS_FROM(TwoP, BoxModel, Lens2pSpatialParams)); +namespace Properties { +NEW_TYPE_TAG(LensTwoPProblemTypeTag, INHERITS_FROM(TwoP, BoxModel, Lens2pSpatialParams)); // Set the grid type -SET_TYPE_PROP(LensTwoPProblem, Grid, Dune::YaspGrid<2>); +SET_TYPE_PROP(LensTwoPProblemTypeTag, Grid, Dune::YaspGrid<2>); // Set the problem property -SET_TYPE_PROP(LensTwoPProblem, Problem, LensTwoPProblem); +SET_TYPE_PROP(LensTwoPProblemTypeTag, Problem, LensTwoPProblem); -// Set the wetting phase -/* SET_PROP(LensTwoPProblem, Indices::phase0Idx) // TODO: Component Indices?? -{ -private: using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); -public: using type = typedef FluidSystems::LiquidPhase >; -};*/ - -// TODO : Set the Fluid-System -SET_TYPE_PROP(LensTwoPProblem, +// TODO: Set the Fluid-System +SET_TYPE_PROP(LensTwoPProblemTypeTag, FluidSystem, - FluidSystems:: + FluidSystems::); // Set the non-wetting phase SET_PROP(LensTwoPProblem, NonwettingPhase) @@ -78,7 +69,7 @@ public: using type = typedef FluidSystems::LiquidPhase); -} +} // end namespace Properties /*! * \ingroup TwoPBoxProblems @@ -118,50 +109,35 @@ template class LensTwoPProblem : public PorousMediumFlowProblem { using ParentType = PorousMediumFlowProblem; - using GridView = typename GET_PROP_TYPE(TypeTag, GridView); - using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - using Indices = typename GET_PROP_TYPE(TypeTag, Indices); - + using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits):Indices; using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); - using Element = typename GridView::template Codim<0>::Entity; using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables); - // using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables); - - using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); - using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; using SubControlVolume = typename FVElementGeometry::SubControlVolume; using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace; - - using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector); using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector); using ElementSolutionVector = typename GET_PROP_TYPE(TypeTag, ElementSolutionVector); - // primary variable indices static constexpr int pressureIdx = Indices::pressureIdx; static constexpr int snIdx = Indices::snIdx; - // equation indices static constexpr int contiNEqIdx = Indices::contiNEqIdx; - // phase indices static constexpr int wPhaseIdx = Indices::phase0Idx; static constexpr int nPhaseIdx = Indices::phase1Idx; - static constexpr int dim = GridView::dimension; static constexpr int dimWorld = GridView::dimensionworld; using Element = typename Element::Geometry::GlobalCoordinate; using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - // using GlobalPosition = Dune::FieldVector; - using TimeLoopPtr = std::shared_ptr>; + public: /*! * \brief The constructor @@ -173,7 +149,6 @@ public: : ParentType(fvGridGeometry) { //This overwrites the lens settings made in the spatialparameter file - // TODO Is this an up to date implementation? this->spatialParams().setLensCoords({0.8, 2.0}, {4.0, 3.0}); // the boundary condition data @@ -196,7 +171,9 @@ public: * This is used as a prefix for files generated by the simulation. */ std::string name() const - { return "lens-2p"; } + { + return "lens-2p"; + } /*! * \brief Returns the temperature within the domain. @@ -226,6 +203,7 @@ public: BoundaryTypes values; if (onUpperBoundary_(globalPos) || onLowerBoundary_(globalPos)) values.setAllDirichlet(); + else values.setAllNeumann(); @@ -252,6 +230,7 @@ public: values[pressureIdx] = upperPressure_; values[snIdx] = 0.0; } + else if (onLowerBoundary_(globalPos)) { values[pressureIdx] = lowerPressure_; @@ -306,7 +285,6 @@ public: numEqVector sourceAtPos(const GlobalPosition &globalPos) const { return numEqVector(0.0); - } /*! @@ -338,7 +316,6 @@ public: } // \} - void setTimeLoop(TimeLoopPtr timeLoop) { timeLoop_ = timeLoop; @@ -349,7 +326,6 @@ public: return timeLoop_->time(); } - private: /*! * \brief Returns true if the point is located on the lower boundary @@ -376,11 +352,12 @@ private: { const Scalar width = this->fvGridGeometry().bBoxMax()[0] - this->fvGridGeometry().bBoxMin()[0]; const Scalar lambda = (this->fvGridGeometry().bBoxMax()[0] - globalPos[0])/width; + return (onUpperBoundary_(globalPos) && (this->fvGridGeometry().bBoxMax()[0]-0.45*width)/width > lambda + eps_ && (this->fvGridGeometry().bBoxMax()[0]-0.55*width)/width < lambda - eps_); } - static constexpr Scalar eps_ =1e-8; + static constexpr Scalar eps_ = 1e-8; Scalar episodeLength_; Scalar upperPressure_; @@ -392,4 +369,4 @@ private: } //end namespace Dumux -#endif +#endif // DUMUX_LENS2P_PROBLEM_HH diff --git a/lecture/efm/2p/lens2pproblem.hh b/lecture/efm/2p/lens2pproblem.hh index 1326a8e..a8c9d78 100644 --- a/lecture/efm/2p/lens2pproblem.hh +++ b/lecture/efm/2p/lens2pproblem.hh @@ -41,50 +41,23 @@ #include #include "../1p2c_2p_2p2c/lens2pspatialparams.hh" -namespace Dumux -{ +namespace Dumux { template class LensTwoPProblem; -////////// -// Specify the properties for the lens problem -////////// +namespace Properties { +NEW_TYPE_TAG(LensTwoPProblemTypeTag, INHERITS_FROM(TwoP, BoxModel, Lens2pSpatialParams)); -namespace Properties -{ -// NEW_TYPE_TAG(LensTwoPProblem, INHERITS_FROM(TwoP, BoxModel, Lens2pSpatialParams)); - // TODO: Which Tags are the correct ancestors? -NEW_TYPE_TAG(LensTwoPProblem, INHERITS_FROM(TwoP, Lens2pSpatialParams)); +NEW_TYPE_TAG(LensTwoPProblemTypeTag, INHERITS_FROM(TwoP, Lens2pSpatialParams)); // Set the grid type -SET_TYPE_PROP(LensTwoPProblem, Grid, Dune::YaspGrid<2>); +SET_TYPE_PROP(LensTwoPProblemTypeTag, Grid, Dune::YaspGrid<2>); // Set the problem property -SET_TYPE_PROP(LensTwoPProblem, Problem, LensTwoPProblem); +SET_TYPE_PROP(LensTwoPProblemTypeTag, Problem, LensTwoPProblem); -// TODO: Do we need this? : Set the problem Type -// SET_TYPE_PROP(LensTwoPProblem, FluidSystem, TwoPImmiscibleFluidSystem); - -/* - * This is the old way to implement the fluid system. -// Set the wetting phase -> This is the 0th-Phase -SET_PROP(LensTwoPProblem, WettingPhase) -{ -private: using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - -public: using type = typedef FluidSystems::LiquidPhase >; // original version: typedef FluidSystems::LiquidPhase > type; -}; -// Set the non-wetting phase -> This is the 1st-Phase -SET_PROP(LensTwoPProblem, NonwettingPhase) -{ -private: using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); -public: using type = typedef FluidSystems::LiquidPhase >;// original version: typedef FluidSystems::LiquidPhase > type; -}; -*/ -//kaiw: new vesion according to dumux/test/porousmediumflow/2p/implicit/boxdfm/problem.hh -// Set the fluid fluid system -SET_PROP(LensTwoPProblem, FluidSystem) +SET_PROP(LensTwoPProblemTypeTag, FluidSystem) { using Scalar = typename GET_PROP_TYPE(TypeTag,Scalar); using WettingPhase = FluidSystems::OnePLiquid >; @@ -92,8 +65,8 @@ SET_PROP(LensTwoPProblem, FluidSystem) using type = FluidSystems::TwoPImmiscible; }; +} // end namespace Properties -} /*! * \ingroup TwoPBoxProblems * \brief Soil decontamination problem where DNAPL infiltrates a fully @@ -129,60 +102,38 @@ template class LensTwoPProblem : public PorousMediumFlowProblem { using ParentType = typename PorousMediumFlowProblem; - - using Params = typename GET_PROP(TypeTag, ParameterTree); // TODO: What has to be done here? - + using Params = typename GET_PROP(TypeTag, ParameterTree); using GridView = typename GET_PROP_TYPE(TypeTag, GridView); using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; - using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); using FluidState = typename GET_PROP_TYPE(TypeTag, FluidState); using WettingPhase = typename GET_PROP_TYPE(TypeTag, WettingPhase); using NonwettingPhase = typename GET_PROP_TYPE(TypeTag, NonwettingPhase); - using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); - - // primary variable indices - static constexpr int pressureIdx = Indices::pressureIdx; - static constexpr int snIdx = Indices::snIdx; - - // equation indices - static constexpr int contiNEqIdx = Indices::contiNEqIdx; - - // phase indices - // static constexpr int wPhaseIdx = Indices::wPhaseIdx, - static constexpr int wPhaseIdx = Indices::phase0Idx; - // static constexpr int nPhaseIdx = Indices::nPhaseIdx, - static constexpr int nPhaseIdx = Indices:phase1Idx; - // Grid and world dimension - // dim = GridView::dimension, - // dimWorld = GridView::dimensionworld - - + // primary variable indices + static constexpr int pressureIdx = Indices::pressureIdx; + static constexpr int snIdx = Indices::snIdx; + // equation indices + static constexpr int contiNEqIdx = Indices::contiNEqIdx; + // phase indices + static constexpr int wPhaseIdx = Indices::phase0Idx; + static constexpr int nPhaseIdx = Indices:phase1Idx; static constexpr int dim = GridView::dimension; static constexpr int dimWorld = GridView::dimensionworld; - using GlobalPosition = Dune::FieldVector; - + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector); public: /*! * \brief The constructor - * - * \param timeManager The time manager - * \param gridView The grid view + * DOC ME! */ LensTwoPProblem( std::shared_ptr fvGridGeometry) : ParentType(fvGridGeometry) { - // TODO Check if all the timeManager related actions are now implemented in the main-function episodeLength_ = getParam("TimeLoop.EpisodeLength"); - // this->timeManager().startNextEpisode(episodeLength_); - - //this overwrites the settings in the spatialparameters file! - // this->spatialParams().setLensCoords({0.0, 0.5}, {3.0, 1.0}); // the boundary condition data lowerPressure_ = getParam("Boundary.LowerPressure"); @@ -193,7 +144,6 @@ public: infiltrationStartTime_= 1.0e-9; //The infiltrations starts always after the first time step! infiltrationEndTime_= getParam("Boundary.InfiltrationEndTime"); - // TODO Check, if this is now in the main-function paraviewOutput_ = Params::tree().template get("Output.paraviewOutput", true); if (!paraviewOutput_) { @@ -202,18 +152,14 @@ public: // Write header for output file std::ofstream dataFile; dataFile.open("dumux-out.vgfc"); - // dataFile << "Gridplot" << std::endl; dataFile << "## This is a DuMuX output for the ViPLab graphics driver. \n"; dataFile << "## This output file was generated at " << __TIME__ <<", "<< __DATE__<< "\n"; dataFile << "# x-range " << this->fvGridGeometry().bBoxMin()[0] << " " << this->fvGridGeometry().bBoxMax()[0] << "\n" ; dataFile << "# y-range " << this->fvGridGeometry().bBoxMin()[1] << " " << this->fvGridGeometry().bBoxMax()[1] << "\n" ; dataFile << "# x-count " << numCells_[0]+1 << "\n" ; dataFile << "# y-count " << numCells_[1]+1 << "\n" ; - // dataFile << "# min-color 0 0 0\n"; - // dataFile << "# max-color 255 255 255\n"; dataFile.close(); } - } /*! @@ -227,7 +173,9 @@ public: * This is used as a prefix for files generated by the simulation. */ std::string name() const - { return "lens-2p"; } + { + return "lens-2p"; + } /*! * \brief Returns the temperature within the domain. @@ -258,6 +206,7 @@ public: BoundaryTypes bcTypes; if (onUpperBoundary_(globalPos) || onLowerBoundary_(globalPos)) bcTypes.setAllDirichlet(); + else bcTypes.setAllNeumann(); @@ -288,6 +237,7 @@ public: values[pressureIdx] = upperPressure_; values[snIdx] = 0.0; } + else if (onLowerBoundary_(globalPos)) { values[pressureIdx] = lowerPressure_; @@ -344,7 +294,6 @@ public: return numEqVector(0.0); } - /*! * \brief Evaluate the initial value for a control volume. * @@ -400,6 +349,7 @@ private: { const Scalar width = this->fvGridGeometry().bBoxMax()[0] - this->fvGridGeometry().bBoxMin()[0]; const Scalar lambda = (this->fvGridGeometry().bBoxMax()[0] - globalPos[0])/width; + return (onUpperBoundary_(globalPos) && (this->fvGridGeometry().bBoxMax()[0]-0.40*width)/width > lambda + eps_ && (this->fvGridGeometry().bBoxMax()[0]-0.60*width)/width < lambda - eps_); } @@ -418,6 +368,7 @@ private: std::vector numCells_; }; -} //end namespace + +} //end namespace Dumux #endif // DUMUX_LENS2P_PROBLEM_HH diff --git a/lecture/mhs/groundwater/groundwater.cc b/lecture/mhs/groundwater/groundwater.cc index 695dd6e..27555ee 100644 --- a/lecture/mhs/groundwater/groundwater.cc +++ b/lecture/mhs/groundwater/groundwater.cc @@ -26,7 +26,26 @@ #include #include "groundwaterproblem.hh" -#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include /*! * \brief Provides an interface for customizing error messages associated with @@ -59,12 +78,10 @@ void usage(const char *progName, const std::string &errorMsg) //////////////////////// int main(int argc, char** argv) try { - // typedef TTAG(LensOnePTwoCProblem) TypeTag; - // return Dumux::start(argc, argv, usage); using namespace Dumux; // define the type tag for this problem - using TypeTag = TTAG(GroundwaterProblem); + using TypeTag = TTAG(GroundwaterProblemTypeTag); // initialize MPI, finalize is done automatically on exit const auto& mpiHelper = Dune::MPIHelper::instance(argc, argv); @@ -76,17 +93,19 @@ int main(int argc, char** argv) try // 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(); + ///////////////////////////////////////////////////////////////////// + + GridManager gridManager; + gridManager.init(); //////////////////////////////////////////////////////////// // run instationary non-linear problem on this grid //////////////////////////////////////////////////////////// // we compute on the leaf grid view - const auto& leafGridView = GridCreator::grid().leafGridView(); + const auto& leafGridView = gridManager.grid().leafGridView(); // create the finite volume grid geometry using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); @@ -198,8 +217,6 @@ int main(int argc, char** argv) try DumuxMessage::print(/*firstCall=*/false); } - - } catch (Dumux::ParameterException &e) diff --git a/lecture/mhs/groundwater/groundwater.input b/lecture/mhs/groundwater/groundwater.input index e4576e2..80fcb16 100644 --- a/lecture/mhs/groundwater/groundwater.input +++ b/lecture/mhs/groundwater/groundwater.input @@ -23,6 +23,7 @@ Left = " " Right =" + " Bottom=" @@ -30,6 +31,7 @@ Bottom=" " Top=" + " [SpatialParams] @@ -39,7 +41,6 @@ Permeability = 1e-4 # the background permeability k_f [m/s] # Insert in the following format: # Left Right Bottom Top Permeability - Lenses = " 20 50 50 80 1e-2 " diff --git a/lecture/mhs/groundwater/groundwaterproblem.hh b/lecture/mhs/groundwater/groundwaterproblem.hh index fae369a..0992782 100644 --- a/lecture/mhs/groundwater/groundwaterproblem.hh +++ b/lecture/mhs/groundwater/groundwaterproblem.hh @@ -32,8 +32,7 @@ #include #include "groundwaterspatialparams.hh" -namespace Dumux -{ +namespace Dumux { template class GroundwaterProblem; @@ -41,28 +40,28 @@ class GroundwaterProblem; ////////// // Specify the properties ////////// -namespace Properties -{ -NEW_TYPE_TAG(GroundwaterProblem, INHERITS_FROM(FVPressureOneP)); +namespace Properties { +NEW_TYPE_TAG(GroundwaterProblemTypeTag, INHERITS_FROM(FVPressureOneP)); // Set the grid type -SET_TYPE_PROP(GroundwaterProblem, Grid, Dune::YaspGrid<2>); +SET_TYPE_PROP(GroundwaterProblemTypeTag, Grid, Dune::YaspGrid<2>); // Set the wetting phase -SET_PROP(GroundwaterProblem, Fluid) +SET_PROP(GroundwaterProblemTypeTag, Fluid) { private: - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); public: - typedef FluidSystems::LiquidPhase > type; + using type = FluidSystems::LiquidPhase >; }; // Set the spatial parameters -SET_TYPE_PROP(GroundwaterProblem, SpatialParams, Dumux::GroundwaterSpatialParams); +SET_TYPE_PROP(GroundwaterProblemTypeTag, SpatialParams, Dumux::GroundwaterSpatialParams); //Set the problem -SET_TYPE_PROP(GroundwaterProblem, Problem, Dumux::GroundwaterProblem); -} +SET_TYPE_PROP(GroundwaterProblemTypeTag, Problem, Dumux::GroundwaterProblem); + +} // end namespace Properties /*! * \ingroup MHS @@ -70,40 +69,28 @@ SET_TYPE_PROP(GroundwaterProblem, Problem, Dumux::GroundwaterProblem); * \brief Dumux-equivalent for GRUWA (1p-stationary, finite volumes) */ template -class GroundwaterProblem: public PorousMediumFlowProblem // TODO: old version: DiffusionProblem1P now correct? +class GroundwaterProblem: public PorousMediumFlowProblem { using ParentType = PorousMediumFlowProblem; using GridView = typename GET_PROP_TYPE(TypeTag, GridView); using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); - using Indices = typename GET_PROP_TYPE(TypeTag, Indices); - - using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); - using Element = typename GridView::template Codim<0>::Entity; - - using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; using SubControlVolume = typename FVElementGeometry::SubControlVolume; using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace; using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables); - using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector); using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector); using ResolutionVector = typename Dune::FieldVector; - - enum - { - // grid and world dimension - dim = GridView::dimension, - dimWorld = GridView::dimensionworld - }; - using GlobalPosition = Dune::FieldVector; - + // grid and world dimension + static constexpr int dim = GridView::dimension; + static constexpr int dimWorld = GridView::dimensionworld; + using GlobalPosition = Dune::FieldVector; struct BoundarySegment { Scalar from, to; @@ -115,7 +102,6 @@ class GroundwaterProblem: public PorousMediumFlowProblem // TODO: old v { return globalPos[axis] > from - eps_ && globalPos[axis] < to + eps_; } }; - // TODO: Is this to be changed? Do we now do this with NumEqVector? struct Source { Dune::FieldVector globalPos; @@ -125,7 +111,7 @@ class GroundwaterProblem: public PorousMediumFlowProblem // TODO: old v public: GroundwaterProblem(std::shared_ptr fvGridGeometry) - : ParentType(fvGridGeometry) // TODO where to place: velocity_(*this) + : ParentType(fvGridGeometry), velocity_(*this) { Fluid::Component::setViscosity(0.001); Fluid::Component::setDensity(1000); @@ -141,6 +127,7 @@ public: std::cout << "Number of cells exceeds limit. Choose less than 10000 cells!\n"; exit(2); } + // check input for too small grid size if (numCells_[0] < 2 || numCells_[1] < 2) { @@ -149,7 +136,6 @@ public: } // Read sources - // TODO: Has this to be changed? Implementation with class PointSource? std::vector sources = getParam >("Source.Sources"); unsigned int numSources = std::trunc(sources.size()/3); @@ -179,8 +165,10 @@ public: tempSegment.value = bc[segmentCount*4+3]; boundaryConditions_[2].push_back(tempSegment); } + bc = getParam >("BoundaryConditions.Right"); NumberOfSegments = std::trunc(bc.size()/4); + for (int segmentCount = 0; segmentCount < NumberOfSegments; segmentCount++) { BoundarySegment tempSegment; @@ -190,8 +178,10 @@ public: tempSegment.value = bc[segmentCount*4+3]; boundaryConditions_[3].push_back(tempSegment); } + bc = getParam >("BoundaryConditions.Bottom"); NumberOfSegments = std::trunc(bc.size()/4); + for (int segmentCount = 0; segmentCount < NumberOfSegments; segmentCount++) { BoundarySegment tempSegment; @@ -201,8 +191,10 @@ public: tempSegment.value = bc[segmentCount*4+3]; boundaryConditions_[1].push_back(tempSegment); } + bc = getParam >("BoundaryConditions.Top"); NumberOfSegments = std::trunc(bc.size()/4); + for (int segmentCount = 0; segmentCount < NumberOfSegments; segmentCount++) { BoundarySegment tempSegment; @@ -225,10 +217,14 @@ public: * This is used as a prefix for files generated by the simulation. */ std::string name() const - { return "groundwater"; } + { + return "groundwater"; + } bool shouldWriteRestartFile() const - { return false; } + { + return false; + } /*! * \brief Returns the temperature within the domain. @@ -269,7 +265,7 @@ public: */ BoundaryTypes boundaryTypesAtPos(const GlobalPosition& globalPos) const { - BoundaryTypes bcType; + BoundaryTypes bcTypes; double coordinate = 0.0; int boundaryIndex = 0; @@ -306,15 +302,17 @@ public: (coordinate < boundaryConditions_[boundaryIndex][segmentCount].to)) { if (boundaryConditions_[boundaryIndex][segmentCount].neumann) - bcType.setAllNeumann(); + bcTypes.setAllNeumann(); + else - bcType.setAllDirichlet(); - return; // kaiw: What is this here?! + bcTypes.setAllDirichlet(); + + return bcTypes; } } - bcType.setAllNeumann(); + bcTypes.setAllNeumann(); - return bcType; + return bcTypes; } //! return Dirichlet conditions (pressure, [Pa]) @@ -356,7 +354,8 @@ public: (coordinate < boundaryConditions_[boundaryIndex][segmentCount].to)) { values = boundaryConditions_[boundaryIndex][segmentCount].value*Fluid::density(0.0,0.0)*9.81; - return; + + return values; } } @@ -364,8 +363,7 @@ public: } //! return Neumann conditions (flux, [kg/(m^2 s)]) - PrimaryVariables - neumannAtPos(const GlobalPosition& globalPos) const + PrimaryVariables neumannAtPos(const GlobalPosition& globalPos) const { PrimaryVariables values; @@ -404,7 +402,7 @@ public: (coordinate < boundaryConditions_[boundaryIndex][segmentCount].to)) { values = boundaryConditions_[boundaryIndex][segmentCount].value*Fluid::density(0.0,0.0)*(-1); - return; + return values; } } values = 0; @@ -412,12 +410,6 @@ public: return values; } - /* bool shouldWriteOutput () - { - return (this->timeManager().time() >= 0); - }*/ - - // kaiw: do we need this anymore? void writeOutput() { ParentType::writeOutput(); @@ -456,9 +448,12 @@ public: { int currentIdx = i*numCells_[0]+j; dataFile << this->variables().cellData(currentIdx).pressure()/(Fluid::density(0.0,0.0)*9.81); - if(j != numCells_[0]-1) // all but last entry + // all but last entry + if (j != numCells_[0]-1) dataFile << " "; - else // write the last entry + + // write the last entry + else dataFile << "\n"; } } @@ -488,12 +483,10 @@ public: printf("%10.4g %10.4g %10.4g %13.4g %13.4g\n", x, y, piezo, v_x, v_y); } - - } private: - std::vector sources_; // TODO change type to NumEqVector? + std::vector sources_; std::vector boundaryConditions_[4]; GlobalPosition domainSize_; ResolutionVector numCells_; @@ -502,6 +495,7 @@ private: Scalar geometryDepth_; Dumux::FVVelocity velocity_; }; + } //end namespace Dumux #endif //DUMUX_LECTURE_MHS_GROUNDWATER_PROBLEM_HH diff --git a/lecture/mhs/groundwater/groundwaterspatialparams.hh b/lecture/mhs/groundwater/groundwaterspatialparams.hh index d27e926..5ef2b4e 100644 --- a/lecture/mhs/groundwater/groundwaterspatialparams.hh +++ b/lecture/mhs/groundwater/groundwaterspatialparams.hh @@ -24,8 +24,7 @@ #include -namespace Dumux -{ +namespace Dumux { /*! * \ingroup IMPETtests @@ -36,19 +35,11 @@ class GroundwaterSpatialParams: public FVSpatialParamsOneP::Entity; using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - using Tensor = Dune::FieldMatrix;// original: typedef Dune::FieldMatrix Tensor; + using Tensor = Dune::FieldMatrix; struct Lens { @@ -59,10 +50,10 @@ class GroundwaterSpatialParams: public FVSpatialParamsOneP(gridView) { // factor converting K_f to instrinsic permeability @@ -87,14 +78,19 @@ public: const Tensor& intrinsicPermeabilityAtPos (const GlobalPosition& globalPos) const { - if(!lenses_.empty()) + if (!lenses_.empty()) { // check if we are in one of the lenses for (const auto& lens : lenses_) if (isInLens_(lens, globalPos)) { // the permeabilty is the lens permeability - lensPermeability_ = {{lens.permeability, 0}, {0, lens.permeability}}; + lensPermeability_ = + { + {lens.permeability, 0}, + {0, lens.permeability} + + }; return lensPermeability_; } @@ -110,13 +106,11 @@ public: } private: - bool isInLens_(const Lens& lens, const GlobalPosition& globalPos) const { for (unsigned int dimIdx = 0; dimIdx < dimWorld; ++dimIdx) { if (globalPos[dimIdx] < lens.lowerLeft[dimIdx] + eps_ || globalPos[dimIdx] > lens.upperRight[dimIdx] - eps_) - return false; } @@ -133,4 +127,5 @@ private: }; } // end namespace Dumux + #endif // DUMUX_LECTURE_MHS_GROUNDWATER_SPATIALPARAMS_HH diff --git a/lecture/mm/buckleyleverett/buckleyleverettanalyticsolution.hh b/lecture/mm/buckleyleverett/buckleyleverettanalyticsolution.hh index 7d3603b..d62540e 100644 --- a/lecture/mm/buckleyleverett/buckleyleverettanalyticsolution.hh +++ b/lecture/mm/buckleyleverett/buckleyleverettanalyticsolution.hh @@ -23,15 +23,13 @@ #include #include - /** * @file * @brief Analytical solution of the buckley-leverett problem * @author Markus Wolff */ -namespace Dumux -{ +namespace Dumux { /** * \ingroup fracflow * @brief IMplicit Pressure Explicit Saturation (IMPES) scheme for the solution of @@ -71,28 +69,18 @@ template class BuckleyLeverettAnalytic using Grid = typename GET_PROP_TYPE(TypeTag, Grid); using GridView = typename GET_PROP_TYPE(TypeTag, GridView); using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - using SpatialParams = typename GET_PROP_TYPE(TypeTag, SpatialParams); using MaterialLaw = typename SpatialParams::MaterialLaw; using MaterialLawParams = typename MaterialLaw::Params; - using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); using FluidState = typename GET_PROP_TYPE(TypeTag, FluidState); - using Indices = typename GET_PROP_TYPE(TypeTag, Indices); using CellData = typename GET_PROP_TYPE(TypeTag, CellData); - - enum - { - dim = GridView::dimension, dimworld = GridView::dimensionworld - }; - enum - { - wPhaseIdx = Indices::wPhaseIdx, - nPhaseIdx = Indices::nPhaseIdx, - satEqIdx = Indices::satEqIdx, - }; - + static constexpr int dim = GridView::dimension; + static constexpr int dimworld = GridView::dimensionworld; + static constexpr int wPhaseIdx = Indices::wPhaseIdx; + static constexpr int nPhaseIdx = Indices::nPhaseIdx; + static constexpr int satEqIdx = Indices::satEqIdx; using BlockVector = Dune::BlockVector >; using Element = typename GridView::Traits::template Codim<0>::Entity; using ElementIterator = typename GridView::template Codim<0>::Iterator; @@ -110,8 +98,6 @@ public: error_ = 0; elementVolume_.resize(size_); elementVolume_ = 0; - - return; } /*! @@ -125,15 +111,13 @@ public: swr_ = materialLawParams.swr(); snr_ = materialLawParams.snr(); porosity_ = problem_.spatialParams().porosity(dummyElement_); - time_ = 0; - satVec_ = swr_; + for (int i = 1; i < pointNum_; i++) { satVec_[i] = satVec_[i - 1] + (1 - snr_ - swr_) / intervalNum_; } -// std::cout<<"satVec_ = "< satVec_; Dune::FieldVector fractionalW_; Dune::FieldVector dfwdsw_; @@ -422,5 +369,7 @@ private: GlobalPosition dummyGlobal_; }; -} -#endif + +} // end namespace Dumux + +#endif // DUMUX_BUCKLEYLEVERETT_ANALYTICAL_HH diff --git a/lecture/mm/buckleyleverett/buckleyleverettexercise.cc b/lecture/mm/buckleyleverett/buckleyleverettexercise.cc index cb5dafe..f40882b 100644 --- a/lecture/mm/buckleyleverett/buckleyleverettexercise.cc +++ b/lecture/mm/buckleyleverett/buckleyleverettexercise.cc @@ -63,9 +63,8 @@ void usage(const char *progName, const std::string &errorMsg) } } -// TODO: From what kind of test should we copy the main function? int main(int argc, char** argv) { - typedef TTAG(BuckleyLeverettProblem) TypeTag; + typedef TTAG(BuckleyLeverettProblemTypeTag) TypeTag; return Dumux::start(argc, argv, usage); } diff --git a/lecture/mm/buckleyleverett/buckleyleverettproblem.hh b/lecture/mm/buckleyleverett/buckleyleverettproblem.hh index 4c52b3e..695590e 100644 --- a/lecture/mm/buckleyleverett/buckleyleverettproblem.hh +++ b/lecture/mm/buckleyleverett/buckleyleverettproblem.hh @@ -38,25 +38,25 @@ #include "buckleyleverettanalyticsolution.hh" #include -namespace Dumux -{ +namespace Dumux { + template class BuckleyLeverettProblem; ////////// // Specify the properties ////////// -namespace Properties -{ -NEW_TYPE_TAG(BuckleyLeverettProblem, INHERITS_FROM(FVPressureTwoP, FVTransportTwoP, IMPESTwoP, BuckleyLeverettSpatialParams)); +namespace Properties { + +NEW_TYPE_TAG(BuckleyLeverettProblemTypeTag, INHERITS_FROM(FVPressureTwoP, FVTransportTwoP, IMPESTwoP, BuckleyLeverettSpatialParamsTypeTag)); // Set the grid type -SET_TYPE_PROP(BuckleyLeverettProblem, Grid, Dune::YaspGrid<2>); +SET_TYPE_PROP(BuckleyLeverettProblemTypeTag, Grid, Dune::YaspGrid<2>); // Set the problem property -SET_TYPE_PROP(BuckleyLeverettProblem, Problem, BuckleyLeverettProblem); +SET_TYPE_PROP(BuckleyLeverettProblemTypeTag, Problem, BuckleyLeverettProblem); -SET_PROP(BuckleyLeverettProblem, FluidSystem) +SET_PROP(BuckleyLeverettProblemTypeTag, FluidSystem) { using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); using WettingPhase = FluidSystems::OnePLiquid >; @@ -64,9 +64,10 @@ SET_PROP(BuckleyLeverettProblem, FluidSystem) using type = FluidSystems::TwoPImmiscible; }; -SET_TYPE_PROP(BuckleyLeverettProblem, EvalCflFluxFunction, EvalCflFluxCoats); -SET_INT_PROP(BuckleyLeverettProblem, Formulation, SequentialTwoPCommonIndices::pwsw); -} +SET_TYPE_PROP(BuckleyLeverettProblemTypeTag, EvalCflFluxFunction, EvalCflFluxCoats); +SET_INT_PROP(BuckleyLeverettProblemTypeTag, Formulation, SequentialTwoPCommonIndices::pwsw); + +} // end namespace Properties /*! * \ingroup DecoupledProblems @@ -74,37 +75,24 @@ SET_INT_PROP(BuckleyLeverettProblem, Formulation, SequentialTwoPCommonIndices::p template class BuckleyLeverettProblem: public IMPESProblem2P { - typedef IMPESProblem2P ParentType; + using ParentType = IMPESProblem2P; using GridView = typename GET_PROP_TYPE(TypeTag, GridView); - using Indices = typename GET_PROP_TYPE(TypeTag, Indices); - using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); using TimeManager = typename GET_PROP_TYPE(TypeTag, TimeManager); - using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); using FluidState = typename GET_PROP_TYPE(TypeTag, FluidState); - using CellData = typename GET_PROP_TYPE(TypeTag, CellData); - using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); using PrimaryVariables = typename GET_PROP(TypeTag, SolutionTypes)::PrimaryVariables; - - enum - { - dim = GridView::dimension, - dimWorld = GridView::dimensionworld - }; - enum - { - wPhaseIdx = Indices::wPhaseIdx, - nPhaseIdx = Indices::nPhaseIdx, - pressureIdx = Indices::pressureIdx, - swIdx = Indices::swIdx, - pressEqIdx = Indices::pressureEqIdx, - satEqIdx = Indices::satEqIdx - }; - + static constexpr int dim = GridView::dimension; + static constexpr int dimWorld = GridView::dimensionworld; + static constexpr int wPhaseIdx = Indices::wPhaseIdx; + static constexpr int nPhaseIdx = Indices::nPhaseIdx; + static constexpr int pressureIdx = Indices::pressureIdx; + static constexpr int swIdx = Indices::swIdx; + static constexpr int pressEqIdx = Indices::pressureEqIdx; + static constexpr int satEqIdx = Indices::satEqIdx; using Element = typename GridView::Traits::template Codim<0>::Entity; using Intersection = typename GridView::Intersection; using GlobalPosition = Dune::FieldVector; @@ -116,15 +104,17 @@ public: * \param gridView DOC ME! */ BuckleyLeverettProblem(TimeManager& timeManager, typename GridView::Grid &grid) - : ParentType(timeManager, grid), eps_(1e-8), pLeftBc_(2.0e5), - analyticSolution_(*this, 3e-7), viplabOutput_(*this) + : ParentType(timeManager, grid) + , eps_(1e-8) + , pLeftBc_(2.0e5) + , analyticSolution_(*this, 3e-7) + , viplabOutput_(*this) { - // TODO: What are these: analyticSolution_(*this, 3e-7), viplabOutput_(*this) - // check the cell size restriction const auto cells = getParam >("Grid.Cells"); if (cells[1] != 1) DUNE_THROW(Dune::IOError, "This is a 1D problem. Do not change the number of cells in y-direction!"); + if (cells[0] > 200) DUNE_THROW(Dune::IOError, "Maximum allowed number of cells in x-direction for this problem is: 200!"); @@ -142,15 +132,6 @@ public: snr_ = getParam("SpatialParams.ResidualSaturationNonWetting"); paraviewOutput_ = getParam("Output.paraviewOutput", true); - - /*// create output for ViPLab if no output for Paraview is created - if (!paraviewOutput_) - { - //Write header for ViPLab-Outputfile - std::ofstream dataFile; - dataFile.open("vipplot.vgf"); - dataFile.close(); - }*/ } void init() @@ -170,16 +151,20 @@ public: * This is used as a prefix for files generated by the simulation. */ const std::string name() const - { return "buckleyleverett"; } + { + return "buckleyleverett"; + } bool shouldWriteRestartFile() const - { return false; } + { + return false; + } void postTimeStep() { analyticSolution_.calculateAnalyticSolution(); ParentType::postTimeStep(); - }; + } void addOutputVtkFields() { @@ -222,11 +207,13 @@ public: { bcTypes.setAllDirichlet(); } + else if (globalPos[0] > upperRight_[0] - eps_)//at east boundary { bcTypes.setNeumann(pressEqIdx);//Neumann for the pressure equation bcTypes.setOutflow(satEqIdx);//Outflow for the transport equation } + // all other boundaries, i.e., top and bottom, Neumann else { @@ -251,6 +238,7 @@ public: void neumannAtPos(PrimaryVariables &values, const GlobalPosition& globalPos) const { values = 0; //no-flow Neumann at top and bottom + if (globalPos[0] > upperRight_[0] - eps_) //east boundary { // the volume flux should remain constant, when density is changed @@ -278,6 +266,7 @@ public: { if (paraviewOutput_) ParentType::writeOutput(false); + else { std::size_t numElements = this->gridView().size(0); @@ -308,5 +297,6 @@ private: bool paraviewOutput_; }; -} +} // end namespace Dumux + #endif // DUMUX_LECTURE_MM_BUCKLEYLEVERETT_BUCKLEYLEVERETTPROBLEM_HH diff --git a/lecture/mm/buckleyleverett/buckleyleverettspatialparams.hh b/lecture/mm/buckleyleverett/buckleyleverettspatialparams.hh index 64e78ee..d0fecaa 100644 --- a/lecture/mm/buckleyleverett/buckleyleverettspatialparams.hh +++ b/lecture/mm/buckleyleverett/buckleyleverettspatialparams.hh @@ -24,32 +24,31 @@ #include #include -namespace Dumux -{ +namespace Dumux { //forward declaration template class BuckleyLeverettSpatialParams; -namespace Properties -{ +namespace Properties { + // The spatial parameters TypeTag -NEW_TYPE_TAG(BuckleyLeverettSpatialParams); +NEW_TYPE_TAG(BuckleyLeverettSpatialParamsTypeTag); // Set the spatial parameters -SET_TYPE_PROP(BuckleyLeverettSpatialParams, SpatialParams, Dumux::BuckleyLeverettSpatialParams); +SET_TYPE_PROP(BuckleyLeverettSpatialParamsTypeTag, SpatialParams, BuckleyLeverettSpatialParams); // Set the material law -SET_PROP(BuckleyLeverettSpatialParams, MaterialLaw) +SET_PROP(BuckleyLeverettSpatialParamsTypeTag, MaterialLaw) { private: using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - typedef RegularizedBrooksCorey RawMaterialLaw; -// typedef LinearMaterial RawMaterialLaw; + using RawMaterialLaw = RegularizedBrooksCorey; public: - typedef EffToAbsLaw type; + using type = EffToAbsLaw; }; -} + +} // end namespace Properties /** \todo Please doc me! */ @@ -60,14 +59,11 @@ class BuckleyLeverettSpatialParams: public SequentialFVSpatialParams using GridView = typename GET_PROP_TYPE(TypeTag, GridView); using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); using Problem = typename GET_PROP_TYPE(TypeTag, Problem); - typedef SequentialFVSpatialParams ParentType; // TODO: How to change this thing here? + using ParentType = SequentialFVSpatialParams; using CoordScalar = typename Grid::ctype; - - enum - {dim=Grid::dimension, dimWorld=Grid::dimensionworld, numEq=1}; - + static constexpr int dim=Grid::dimension; + static constexpr int dimWorld=Grid::dimensionworld, numEq=1; using Element = typename Grid::Traits::template Codim<0>::Entity; - using GlobalPosition = Dune::FieldVector; using FieldMatrix = Dune::FieldMatrix; @@ -75,7 +71,6 @@ public: using MaterialLaw = typename GET_PROP_TYPE(TypeTag, MaterialLaw); using MaterialLawParams = typename MaterialLaw::Params; - Scalar intrinsicPermeability (const Element& element) const { return constPermeability_; @@ -97,27 +92,17 @@ public: return materialLawParams_; } - - BuckleyLeverettSpatialParams(const Problem& problem) // TODO How to change this? + BuckleyLeverettSpatialParams(const Problem& problem) :ParentType(problem) { - Scalar permFactor = 1.0;//0.001/(1000*9.81); + Scalar permFactor = 1.0; //0.001/(1000*9.81); constPermeability_ = getParam("SpatialParams.Permeability")*permFactor; materialLawParams_.setSwr( getParam("SpatialParams.ResidualSaturationWetting") ); materialLawParams_.setSnr( getParam("SpatialParams.ResidualSaturationNonWetting") ); - -// if( GET_RUNTIME_PARAM(TypeTag,bool, SpatialParams.LinearLaw)/* true -> linear law */ ){ -// //set parameters -// materialLawParams_.setEntryPc(GET_RUNTIME_PARAM(TypeTag,double, SpatialParams.LinearLawEntryPressure)); -// materialLawParams_.setMaxPc(GET_RUNTIME_PARAM(TypeTag,double, SpatialParams.LinearLawMaxPc)); -// } -// else{ //set Brooks-Corey parameters - materialLawParams_.setPe( getParam("SpatialParams.BrooksCoreyEntryPressure") ); - materialLawParams_.setLambda( getParam("SpatialParams.BrooksCoreyLambda") ); - // } - + materialLawParams_.setPe( getParam("SpatialParams.BrooksCoreyEntryPressure") ); + materialLawParams_.setLambda( getParam("SpatialParams.BrooksCoreyLambda") ); porosity_ = getParam("SpatialParams.Porosity"); } @@ -128,5 +113,6 @@ private: }; -} // end namespace -#endif +} // end namespace Dumux + +#endif // BUCKLEYLEVERETT_SPATIALPARAMS_HH diff --git a/lecture/mm/buckleyleverett/pseudoh2o.hh b/lecture/mm/buckleyleverett/pseudoh2o.hh index 7b529ba..65bbe34 100644 --- a/lecture/mm/buckleyleverett/pseudoh2o.hh +++ b/lecture/mm/buckleyleverett/pseudoh2o.hh @@ -27,22 +27,23 @@ #include -namespace Dumux -{ +namespace Dumux { /*! * \brief Rough estimate for testing purposes of some water. */ -template // TODO: Must change this to Scalar? +template class PseudoH2O : public Components::Base > , public Components::Liquid > { public: - typedef ScalarT Scalar; + using Scalar = ScalarT; /*! * \brief A human readable name for the water. */ static std::string name() - { return "H2O"; } + { + return "H2O"; + } /*! * \brief Rough estimate of the density of oil [kg/m^3]. @@ -62,7 +63,7 @@ public: static Scalar liquidViscosity(Scalar temperature, Scalar pressure) { return viscosity_; - }; + } /*! * \brief DOC ME! @@ -85,11 +86,15 @@ public: private: static Scalar viscosity_; static Scalar density_; + }; + template typename PseudoH2O::Scalar PseudoH2O::viscosity_ = 0.001; + template typename PseudoH2O::Scalar PseudoH2O::density_ = 1000; -} // end namepace -#endif +} // end namepace Dumux + +#endif // DUMUX_PSEUDOH2O_HH diff --git a/lecture/mm/buckleyleverett/pseudooil.hh b/lecture/mm/buckleyleverett/pseudooil.hh index bc59783..dd138e5 100644 --- a/lecture/mm/buckleyleverett/pseudooil.hh +++ b/lecture/mm/buckleyleverett/pseudooil.hh @@ -24,12 +24,10 @@ #ifndef DUMUX_PSEUDOOIL_HH #define DUMUX_PSEUDOOIL_HH - #include -//#include "interface_BL.xml" -namespace Dumux -{ +namespace Dumux { + /*! * \brief Rough estimate for testing purposes of some oil. */ @@ -38,13 +36,15 @@ class PseudoOil : public Components::Base > , public Components::Liquid > { public: - typedef ScalarT Scalar; + using Scalar = ScalarT; /*! * \brief A human readable name for the water. */ static std::string name() - { return "Oil"; } + { + return "Oil"; + } /*! * \brief Rough estimate of the density of oil [kg/m^3]. @@ -55,9 +55,6 @@ public: { return density_; } - // double densityOil = 1000; - // double viscosityWater = interfaceFluidProps.IFP_ViscosityWettingFluid; - // double viscosityOil = interfaceFluidProps.IFP_ViscosityNonWettingFluid; /*! * \brief Rough estimate of the viscosity of oil kg/(ms). @@ -67,7 +64,7 @@ public: static Scalar liquidViscosity(Scalar temperature, Scalar pressure) { return viscosity_; - }; + } /*! * \brief DOC ME! @@ -91,10 +88,14 @@ private: static Scalar viscosity_; static Scalar density_; }; + template typename PseudoOil::Scalar PseudoOil::viscosity_ = 0.01; + template typename PseudoOil::Scalar PseudoOil::density_ = 1000; -} // end namepace -#endif + +} // end namepace Dumux + +#endif // DUMUX_PSEUDOOIL_HH diff --git a/lecture/mm/co2plume/co2plumeshapeexercise.cc b/lecture/mm/co2plume/co2plumeshapeexercise.cc index cd2f475..3288faa 100644 --- a/lecture/mm/co2plume/co2plumeshapeexercise.cc +++ b/lecture/mm/co2plume/co2plumeshapeexercise.cc @@ -19,58 +19,207 @@ /*! * \file * - * \brief test for the 3p3c box model + * \brief Test for the two-phase two-component CC model. */ -#include "config.h" +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#include + +// the problem definitions #include "co2plumeshapeproblem.hh" -#include -/*! - * \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) +int main(int argc, char** argv) try { - 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-tEnd The end of the simulation. [s] \n" - "\t-dtInitial The initial timestep size. [s] \n" - "\t-gridFile The file name of the file containing the grid \n" - "\t definition in DGF format\n" - "\t-FluidSystem.nTemperature Number of tabularization entries [-] \n" - "\t-FluidSystem.nPressure Number of tabularization entries [-] \n" - "\t-FluidSystem.pressureLow Low end for tabularization of fluid properties [Pa] \n" - "\t-FluidSystem.pressureHigh High end for tabularization of fluid properties [Pa] \n" - "\t-FluidSystem.temperatureLow Low end for tabularization of fluid properties [Pa] \n" - "\t-FluidSystem.temperatureHigh High end for tabularization of fluid properties [Pa] \n" - "\t-SpatialParams.K Intrinsic permeability [m^2] \n" - "\t-SpatialParams.phi porosity [-] \n" - "\t-MaterialLaw.swr Residual saturation wetting-phase [-] \n" - "\t-MaterialLaw.snr Residual saturation non-wetting-phase [-] \n" - "\t-MaterialLaw.Pe capillary entry pressure [Pa] \n" - "\t-MaterialLaw.Lambda BrooksCorey paramter [-] \n" - "\t-SimulationControl.name The name of the output files [-] \n" - "\t-InitialConditions.temperature Initial temperature in the reservoir [K] \n"; - // "\t-InitialConditions.depthBOR Depth below ground surface [m] \n"; - - std::cout << errorMessageOut - << "\n"; - } -} + using namespace Dumux; -int main(int argc, char** argv) -{ - typedef TTAG(PlumeShapeProblem) ProblemTypeTag; - return Dumux::start(argc, argv, usage); -} + // define the type tag for this problem + using TypeTag = TTAG(PlumeShapeTypeTag); + + // 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); + + // 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(leafGridView); + fvGridGeometry->update(); + + // the problem (initial and boundary conditions) + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); + auto problem = std::make_shared(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(problem, fvGridGeometry); + gridVariables->init(x, xOld); + + // get some time loop parameters + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + const Scalar finalStorage = 1.55e5; + const Scalar injectionRate = getParam("BoundaryConditions.InjectionRate"); + const Scalar tEnd = finalStorage/injectionRate; + const auto maxDivisions = getParam("TimeLoop.MaxTimeStepDivisions"); + const auto maxDt = getParam("TimeLoop.MaxTimeStepSize"); + auto dt = getParam("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("TimeLoop.Restart"); + // intialize the vtk output module + using VtkOutputFields = typename GET_PROP_TYPE(TypeTag, VtkOutputFields); + VtkOutputModule 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>(restartTime, dt, tEnd); + timeLoop->setMaxTimeStepSize(maxDt); + timeLoop->setPeriodicCheckPoint(getParam("TimeLoop.EpisodeLength", std::numeric_limits::max())); + // the assembler with time loop for instationary problem + using Assembler = FVAssembler; + auto assembler = std::make_shared(problem, fvGridGeometry, gridVariables, timeLoop); + + // the linear solver + using LinearSolver = AMGBackend; + auto linearSolver = std::make_shared(leafGridView, fvGridGeometry->dofMapper()); + + // the non-linear solver + using NewtonController = PriVarSwitchNewtonController; + using NewtonMethod = Dumux::NewtonMethod; + auto newtonController = std::make_shared(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(); + + // report statistics of this time step + timeLoop->reportTimeStep(); + + // set new dt as suggested by newton controller + timeLoop->setTimeStepSize(newtonController->suggestTimeStepSize(timeLoop->timeStepSize())); + + // write vtk output + // if episode length was specificied output only at the end of episodes + if (!haveParam("TimeLoop.EpisodeLength") || timeLoop->isCheckPoint() || timeLoop->finished() || timeLoop->timeStepIndex() == 1) + vtkWriter.write(timeLoop->time()); + + } 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; +} diff --git a/lecture/mm/co2plume/co2plumeshapeexercise.input b/lecture/mm/co2plume/co2plumeshapeexercise.input index 0e701ea..8b15c69 100644 --- a/lecture/mm/co2plume/co2plumeshapeexercise.input +++ b/lecture/mm/co2plume/co2plumeshapeexercise.input @@ -1,6 +1,5 @@ -[TimeManager] +[TimeLoop] DtInitial = 250 # [s] -TEnd = 1e100 # [s] actual end time is controlled by injection rate EpisodeLength = 1e7 # [s] [Grid] @@ -26,7 +25,7 @@ Snr = 0.2 # [-] residual non-wetting phase sat. Pe = 5e3 # [Pa] capillary entry pressure Lambda = 2 # [-] Brooks Corey parameter -[SimulationControl] +[Problem] Name = co2plumeshape # the name of the output files [InitialConditions] @@ -39,4 +38,4 @@ InjectionTemperature = 313.15 # [K] temperature of injected CO2 [Newton] MaxRelativeShift = 1e-8 -SatisfyResidualAndShiftCriterion = true \ No newline at end of file +SatisfyResidualAndShiftCriterion = true diff --git a/lecture/mm/co2plume/co2plumeshapeproblem.hh b/lecture/mm/co2plume/co2plumeshapeproblem.hh index f0cb751..5b60255 100644 --- a/lecture/mm/co2plume/co2plumeshapeproblem.hh +++ b/lecture/mm/co2plume/co2plumeshapeproblem.hh @@ -18,168 +18,104 @@ *****************************************************************************/ /*! * \file - * - * \brief Non-iostohermal CO2 plume migration: CO2 is injected over 30 - * meters at the bottom of the left boundary and moves upwards towards - * an impermeable rock. + * \ingroup CO2Tests + * \brief Definition of a problem, where CO2 is injected in a reservoir. */ -#ifndef CO2_PLUMESHAPE_PROBLEM_HH -#define CO2_PLUMESHAPE_PROBLEM_HH +#ifndef DUMUX_PLUMESHAPE_PROBLEM_HH +#define DUMUX_PLUMESHAPE_PROBLEM_HH -#include +#include + +#include +#include -#include -#include #include -#include -#include +#include #include - #include "co2plumeshapespatialparameters.hh" - -namespace Dumux -{ +namespace Dumux { +/*! + * \ingroup CO2Tests + * \brief Definition of a problem, where CO2 is injected in a reservoir. + */ template class PlumeShapeProblem; -namespace Properties -{ -// for the correct type tag, see 2p2cniproperties.hh -NEW_TYPE_TAG(PlumeShapeProblem, INHERITS_FROM(BoxTwoPTwoCNI, PlumeShapeSpatialParams)); +namespace Properties { +NEW_TYPE_TAG(PlumeShapeTypeTag, INHERITS_FROM(BoxModel, TwoPTwoCCO2, PlumeShapeSpatialParamsTypeTag)); // Set grid to a two-dimensional structured quadrilateral grid -SET_TYPE_PROP(PlumeShapeProblem, Grid, Dune::YaspGrid<2>); +SET_TYPE_PROP(PlumeShapeTypeTag, Grid, Dune::YaspGrid<2>); // Set the problem property -SET_TYPE_PROP(PlumeShapeProblem, Problem, PlumeShapeProblem); +SET_TYPE_PROP(PlumeShapeTypeTag, Problem, PlumeShapeProblem); // Set fluid configuration -SET_TYPE_PROP(PlumeShapeProblem, FluidSystem, BrineCO2FluidSystem); - -// Set the CO2 table to be used; in this case not the the default table -SET_TYPE_PROP(PlumeShapeProblem, CO2Table, CO2TablesBenchmarkThree::CO2Tables); -// Set the salinity mass fraction of the brine in the reservoir -SET_SCALAR_PROP(PlumeShapeProblem, ProblemSalinity, 1e-1); - - -//! the CO2 Model and VolumeVariables properties -SET_TYPE_PROP(PlumeShapeProblem, IsothermalVolumeVariables, CO2VolumeVariables); -SET_TYPE_PROP(PlumeShapeProblem, IsothermalModel, CO2Model); +SET_TYPE_PROP(PlumeShapeTypeTag, FluidSystem, FluidSystems::BrineCO2); +// Use Moles +SET_BOOL_PROP(PlumeShapeTypeTag, UseMoles, false); -SET_TYPE_PROP(PlumeShapeProblem, LinearSolver, ILU0BiCGSTABBackend); +} // end namespace Properties -// Enable gravity? -SET_BOOL_PROP(PlumeShapeProblem, ProblemEnableGravity, true); - -SET_BOOL_PROP(PlumeShapeProblem, ImplicitEnableJacobianRecycling, false); - -// set newton relative tolerance -SET_SCALAR_PROP(PlumeShapeProblem, NewtonMaxRelativeShift, 1e-6); - -SET_BOOL_PROP(PlumeShapeProblem, UseMoles, false); - -} - -/*! - * \ingroup TwoPTwoCNIBoxModel - * \ingroup BoxTestProblems - * \brief Isothermal NAPL infiltration problem: LNAPL contaminates - * the unsaturated and the saturated groundwater zone. - * - * The 2D domain of this test problem is - * - * Left and right boundaries are - * Top and bottom are Neumann boundaries, all no-flow except for the small - * infiltration zone in the upper left part. - * - * This problem uses the \ref TwoPTwoCNIModel. - * - * This problem should typically be simulated for - * A good choice for the initial time step size is - * To adjust the simulation time it is necessary to edit the file - * - * To run the simulation execute the following line in shell: - * - * */ template class PlumeShapeProblem : public PorousMediumFlowProblem { - typedef PorousMediumFlowProblem ParentType; - + using ParentType = PorousMediumFlowProblem; using GridView = typename GET_PROP_TYPE(TypeTag, GridView); using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); - using CO2Tables = typename GET_PROP_TYPE(TypeTag, CO2Table); - - enum { - // Grid and world dimension - dim = GridView::dimension, - dimWorld = GridView::dimensionworld - }; - + using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables); + using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables); + using Indices = typename GET_PROP_TYPE(TypeTag, Indices); + static constexpr int dimWorld = GridView::dimensionworld; // copy some indices for convenience - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - enum { - lPhaseIdx = Indices::wPhaseIdx, - gPhaseIdx = Indices::nPhaseIdx, - - BrineIdx = FluidSystem::BrineIdx, - CO2Idx = FluidSystem::CO2Idx, - - conti0EqIdx = Indices::conti0EqIdx, - contiCO2EqIdx = conti0EqIdx + CO2Idx, - - #if !ISOTHERMAL - temperatureIdx = Indices::temperatureIdx, - energyEqIdx = Indices::energyEqIdx, - #endif - }; - - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; - typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes; - typedef typename GET_PROP_TYPE(TypeTag, TimeManager) TimeManager; - - typedef typename GridView::template Codim<0>::Entity Element; - typedef typename GridView::template Codim::Entity Vertex; - typedef typename GridView::Intersection Intersection; - - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GET_PROP_TYPE(TypeTag, GridCreator) GridCreator; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - - typedef Dune::FieldVector GlobalPosition; - typedef Dumux::CO2 CO2; + static constexpr int pressureIdx = Indices::pressureIdx; + static constexpr int switchIdx = Indices::switchIdx; + static constexpr int wPhaseIdx = Indices::wPhaseIdx; + static constexpr int nPhaseIdx = Indices::nPhaseIdx; + static constexpr int wPhaseOnly = Indices::wPhaseOnly; + static constexpr int nCompIdx = FluidSystem::nCompIdx; + static constexpr int BrineIdx = FluidSystem::BrineIdx; + static constexpr int CO2Idx = FluidSystem::CO2Idx; + static constexpr int conti0EqIdx = Indices::conti0EqIdx; + static constexpr int contiCO2EqIdx = conti0EqIdx + CO2Idx; + using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); + using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector); + using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); + using Element = typename GridView::template Codim<0>::Entity; + using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; + using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace; + using SubControlVolume = typename FVElementGeometry::SubControlVolume; + using GlobalPosition = Dune::FieldVector; + using CO2 = Dumux::CO2; + //! property that defines whether mole or mass fractions are used + static constexpr bool useMoles = GET_PROP_VALUE(TypeTag, UseMoles); + // the discretization method we are using + static constexpr auto discMethod = GET_PROP_TYPE(TypeTag, FVGridGeometry)::discMethod; public: /*! * \brief The constructor - * - * \param timeManager The time manager - * \param gridView The grid view */ - PlumeShapeProblem(std::shared_ptr< const FVGridGeometry> fvGridGeometry) - : ParentType(fvGridGeometry) + PlumeShapeProblem(std::shared_ptr fvGridGeometry) + : ParentType(fvGridGeometry), eps_(1e-6) { - - // TODO Change int to Scalar? Or is int the type for an index? - nTemperature_ = getParam("FluidSystem.NTemperature"); - nPressure_ = getParam("FluidSystem.NPressure"); - pressureLow_ = getParam("FluidSystem.PressureLow"); - pressureHigh_ = getParam("FluidSystem.PressureHigh"); + nTemperature_ = getParam("FluidSystem.NTemperature"); + nPressure_ = getParam("FluidSystem.NPressure"); + pressureLow_ = getParam("FluidSystem.PressureLow"); + pressureHigh_ = getParam("FluidSystem.PressureHigh"); + temperatureLow_ = getParam("FluidSystem.TemperatureLow"); + temperatureHigh_ = getParam("FluidSystem.TemperatureHigh"); + name_ = getParam("Problem.Name"); pressure_ = getParam("InitialConditions.Pressure"); // hydrodynamic pressure at top layer - temperatureLow_ = getParam("FluidSystem.TemperatureLow"); - temperatureHigh_ = getParam("FluidSystem.TemperatureHigh"); temperature_ = getParam("InitialConditions.Temperature"); - injectionRate_ = getParam("BoundaryConditions.InjectionRate"); + injectionRate_ = getParam("BoundaryConditions.InjectionRate"); injectionTemperature_ = getParam("BoundaryConditions.InjectionTemperature"); dipAngle_ = getParam("SpatialParams.DipAngle"); // [deg] - name_ = getParam("SimulationControl.Name"); - - episodeLength_ = getParam("TimeLoop.EpisodeLength"); - // this->timeManager().startNextEpisode(episodeLength_); dipAngleRadians_ = (dipAngle_ * M_PI)/180.0; // [rad] // rotate the coordinate system / gravity: @@ -188,44 +124,11 @@ public: // initialize the tables of the fluid system FluidSystem::init(/*Tmin=*/temperatureLow_, - /*Tmax=*/temperatureHigh_, - /*nT=*/nTemperature_, - /*pmin=*/pressureLow_, - /*pmax=*/pressureHigh_, - /*np=*/nPressure_); - - simulationFinished_ = false; //boolean controlling the simulation end - } - - /*! - * \brief Called directly after the time integration. - */ - void postTimeStep() - { - // Calculate storage terms - PrimaryVariables storageL, storageG; - this->model().globalPhaseStorage(storageL, lPhaseIdx); - this->model().globalPhaseStorage(storageG, gPhaseIdx); - - // Write mass balance information for rank 0 - if (this->gridView().comm().rank() == 0) { - std::cout<<"Storage: liquid=[" << storageL << "]" - << " gas=[" << storageG << "]\n"; - } - - // tell the time manager in case we reached the end of the injection - if(simulationFinished_) - this->timeManager().setFinished(true); - } - - void init() - { - // set the simulation end time - const Scalar finalStorage = 1.55e5; // [kg] - // set TimeManager.TEnd in input file to small value to end the simulation earlier - const Scalar endTime = std::min(finalStorage/injectionRate_, this->timeManager().endTime()); // [s] - this->timeManager().setEndTime(endTime); - ParentType::init(); + /*Tmax=*/temperatureHigh_, + /*nT=*/nTemperature_, + /*pmin=*/pressureLow_, + /*pmax=*/pressureHigh_, + /*np=*/nPressure_); } /*! @@ -238,8 +141,10 @@ public: * * This is used as a prefix for files generated by the simulation. */ - const std::string name() const - { return name_; } + const std::string& name() const + { + return name_; + } /*! * \brief Returns the temperature within the domain. @@ -247,30 +152,12 @@ public: * This problem assumes a temperature of 10 degrees Celsius. */ Scalar temperature() const - { return temperature_; }; - - - /*! - * \brief Evaluate the source term for all phases within a given - * sub-control-volume. - * - * \param values The source and sink values for the conservation equations in units of - * \f$ [ \textnormal{unit of conserved quantity} / (m^3 \cdot s )] \f$ - * \param globalPos The position of the center of the finite volume - * for which the source term ought to be - * specified in global coordinates - * - * For this method, the \a values parameter stores the conserved quantity rate - * generated or annihilate per volume unit. Positive values mean - * that the conserved quantity is created, negative ones mean that it vanishes. - * E.g. for the mass balance that would be a mass rate in \f$ [ kg / (m^3 \cdot s)] \f$. - */ - void sourceAtPos(PrimaryVariables &values, - const GlobalPosition &globalPos) const { - values = 0; + return temperature_; } + // \} + /*! * \name Boundary conditions */ @@ -280,137 +167,109 @@ public: * \brief Specifies which kind of boundary condition should be * used for which equation on a given boundary segment. * - * \param values The boundary types for the conservation equations - * \param vertex The vertex for which the boundary type is set + * \param element The finite element + * \param scvf The sub control volume face */ - BoundaryTypes boundaryTypes( const Vertex &vertex) const + BoundaryTypes boundaryTypesAtPos(const GlobalPosition& globalPos) const { BoundaryTypes values; - const GlobalPosition& globalPos = vertex.geometry().center(); - values.setAllNeumann(); // set East boundaries to Dirichlet values - if ( globalPos[0] > this->bBoxMax()[0] - eps_ ) + if ( globalPos[0] > this->fvGridGeometry().bBoxMax()[0] - eps_ ) { values.setAllDirichlet(); } - // set part of West boundaries to Dirichlet & Neumann values - else if ( globalPos[1] < 30.0 + eps_ && globalPos[0] < eps_) - { -#if !ISOTHERMAL - values.setDirichlet(temperatureIdx, energyEqIdx); -#endif - } - return values; + + return values; } /*! - * \brief Evaluate the boundary conditions for a dirichlet - * boundary segment. + * \brief Evaluates the boundary conditions for a Dirichlet + * boundary segment * - * \param values The dirichlet values for the primary variables - * \param vertex The vertex for which the boundary type is set - * - * For this method, the \a values parameter stores primary variables. + * \param returns the Dirichlet values for the conservation equations in + * \f$ [ \textnormal{unit of primary variable} ] \f$ + * \param globalPos The global position */ - void dirichlet(PrimaryVariables &values, const Vertex &vertex) const + PrimaryVariables dirichletAtPos(const GlobalPosition &globalPos) const { - const GlobalPosition& globalPos = vertex.geometry().center(); - - initial_(values, globalPos); - -#if !ISOTHERMAL - if (globalPos[1] < 30.0 + eps_ && globalPos[0] < eps_) - { - values[temperatureIdx] = injectionTemperature_; //in K - } -#endif + return initial_(globalPos); } /*! * \brief Evaluate the boundary conditions for a neumann * boundary segment. * - * \param values The neumann values for the conservation equations + * This is the method for the case where the Neumann condition is + * potentially solution dependent and requires some quantities that + * are specific to the fully-implicit method. + * + * \param values The neumann values for the conservation equations in units of + * \f$ [ \textnormal{unit of conserved quantity} / (m^2 \cdot s )] \f$ * \param element The finite element - * \param fvElemGeom The finite-volume geometry in the box scheme - * \param is The intersection between element and boundary - * \param scvIdx The local vertex index - * \param boundaryFaceIdx The index of the boundary face + * \param fvGeometry The finite-volume geometry + * \param elemVolVars All volume variables for the element + * \param scvf The sub control volume face * - * For this method, the \a values parameter stores the mass flux + * For this method, the \a values parameter stores the flux * in normal direction of each phase. Negative values mean influx. + * E.g. for the mass balance that would the mass flux in \f$ [ kg / (m^2 \cdot s)] \f$. */ - void solDependentNeumann(PrimaryVariables &values, - const Element &element, - const FVElementGeometry &fvGeometry, - const Intersection &intersection, - const int scvIdx, - const int boundaryFaceIdx, - const ElementVolumeVariables &elemVolVars) const + NumEqVector neumann(const Element& element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolvars, + const SubControlVolumeFace& scvf) const { - const GlobalPosition &globalPos = element.geometry().corner(scvIdx); - const Scalar temperature = elemVolVars[scvIdx].temperature(); - const Scalar pressure = elemVolVars[scvIdx].pressure(gPhaseIdx); - - values = 0; + NumEqVector fluxes(0.0); + // kg/(m^2*s) or mole/(m^2*s) depending on useMoles + auto globalPos = scvf.ipGlobal(); if ( globalPos[1] < 30.0 + eps_ && globalPos[0] < eps_ ) { Scalar massFlux = injectionRate_ /30.0; // [kg/(s*m^2)] - values[contiCO2EqIdx] = -massFlux; // kg/(s*m^2) -#if !ISOTHERMAL - values[energyEqIdx] = -massFlux*CO2::gasEnthalpy(temperature, pressure); // W/(m^2) -#endif + fluxes[contiCO2EqIdx] = -massFlux; // kg/(s*m^2) } + + return fluxes; } + // \} /*! - * \brief Evaluate the initial value for a control volume. - * - * \param values The initial values for the primary variables - * \param element The finite element - * \param fvElemGeom The finite-volume geometry in the box scheme - * \param scvIdx The local vertex index - * - * For this method, the \a values parameter stores primary - * variables. + * \name Volume terms */ - void initial(PrimaryVariables &values, - const Element &element, - const FVElementGeometry &fvElemGeom, - int scvIdx) const - { - const GlobalPosition &globalPos = element.geometry().corner(scvIdx); - initial_(values, globalPos); - } + // \{ /*! - * \brief Return the initial phase state inside a control volume. + * \brief Evaluates the initial values at a position * + * \returns the initial values for the conservation equations in + * \f$ [ \textnormal{unit of primary variables} ] \f$ * \param globalPos The global position */ - int initialPhasePresenceAtPos(const GlobalPosition &globalPos) const - { return Indices::wPhaseOnly; } - - bool shouldWriteOutput() const + PrimaryVariables initialAtPos(const GlobalPosition &globalPos) const { - return this->timeManager().timeStepIndex() == 0 || - this->timeManager().episodeWillBeFinished() || - this->timeManager().willBeFinished(); + return initial_(globalPos); } - void episodeEnd() - { - this->timeManager().startNextEpisode(episodeLength_); - } + // \} + private: - // the internal method for the initial condition - void initial_(PrimaryVariables &values, - const GlobalPosition &globalPos) const + /*! + * \brief Evaluates the initial values for a control volume + * + * The internal method for the initial condition + * + * \param values Stores the initial values for the conservation equations in + * \f$ [ \textnormal{unit of primary variables} ] \f$ + * \param globalPos The global position + */ + PrimaryVariables initial_(const GlobalPosition &globalPos) const { + PrimaryVariables values(0.0); + values.setState(wPhaseOnly); + const Scalar densityW = FluidSystem::Brine::liquidDensity(temperature_, 1e5); const Scalar moleFracLiquidCO2 = 0.00; @@ -422,25 +281,22 @@ private: const Scalar massFracLiquidCO2 = moleFracLiquidCO2*FluidSystem::molarMass(CO2Idx)/meanM; // set initial pressure and pressure Dirichlet conditions: - const Scalar distanceToTopBoundary_ = ( this->bBoxMax()[1] - this->bBoxMin()[1] ) - globalPos[1]; // distance without rotation + const Scalar distanceToTopBoundary_ = ( this->fvGridGeometry().bBoxMax()[1] - this->fvGridGeometry().bBoxMin()[1] ) - globalPos[1]; // distance without rotation const Scalar distanceToTopBoundaryRotated_ = distanceToTopBoundary_ / std::cos(dipAngleRadians_); - const Scalar distanceTopBoundaryToSurface_ = std::sin(dipAngleRadians_) * (this->bBoxMax()[0] - globalPos[0]); + const Scalar distanceTopBoundaryToSurface_ = std::sin(dipAngleRadians_) * (this->fvGridGeometry().bBoxMax()[0] - globalPos[0]); values[Indices::pressureIdx] = pressure_ + densityW * 9.81 * distanceToTopBoundaryRotated_ + densityW * 9.81 * distanceTopBoundaryToSurface_; values[Indices::switchIdx] = massFracLiquidCO2; -#if !ISOTHERMAL - values[temperatureIdx] = temperature_;//290.0 + (depthBOR_ - globalPos[1])*0.03; -#endif + return values; } Scalar temperature_,injectionTemperature_; Scalar depthBOR_; - Scalar eps_ = 1e-6; + Scalar eps_; Scalar injectionRate_; - Scalar episodeLength_; Scalar dipAngleRadians_, dipAngle_; GlobalPosition gravity_; @@ -452,10 +308,8 @@ private: Scalar pressureLow_, pressureHigh_, pressure_; Scalar temperatureLow_, temperatureHigh_; - - bool simulationFinished_; }; -} //end namespace +} //end namespace Dumux -#endif +#endif // DUMUX_PLUMESHAPE_PROBLEM_HH diff --git a/lecture/mm/co2plume/co2plumeshapespatialparameters.hh b/lecture/mm/co2plume/co2plumeshapespatialparameters.hh index a2c331f..1bb3700 100644 --- a/lecture/mm/co2plume/co2plumeshapespatialparameters.hh +++ b/lecture/mm/co2plume/co2plumeshapespatialparameters.hh @@ -16,211 +16,136 @@ * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * *****************************************************************************/ -#ifndef CO2_PLUMESHAPE_SPATIALPARAMETERS_HH -#define CO2_PLUMESHAPE_SPATIALPARAMETERS_HH +#ifndef DUMUX_PLUMESHAPE_SPATIAL_PARAMS_HH +#define DUMUX_PLUMESHAPE_SPATIAL_PARAMS_HH -#include -#include +#include #include #include -#include +#include -namespace Dumux -{ +namespace Dumux { //forward declaration template class PlumeShapeSpatialParams; -namespace Properties -{ +namespace Properties { + // The spatial parameters TypeTag -NEW_TYPE_TAG(PlumeShapeSpatialParams); +NEW_TYPE_TAG(PlumeShapeSpatialParamsTypeTag); // Set the spatial parameters -SET_TYPE_PROP(PlumeShapeSpatialParams, SpatialParams, Dumux::PlumeShapeSpatialParams); +SET_TYPE_PROP(PlumeShapeSpatialParamsTypeTag, SpatialParams, PlumeShapeSpatialParams); // Set the material Law -SET_PROP(PlumeShapeSpatialParams, MaterialLaw) +SET_PROP(PlumeShapeSpatialParamsTypeTag, MaterialLaw) { private: // define the material law which is parameterized by effective // saturations - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef RegularizedBrooksCorey EffMaterialLaw; + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); public: // define the material law parameterized by absolute saturations - typedef EffToAbsLaw type; + using type = EffToAbsLaw>; }; -} - -/*! - * \ingroup TwoPTwoCModel - * \ingroup BoxTestProblems - * \brief Definition of the spatial parameters for the injection - * problem which uses the isothermal 2p2c box model - */ -template -class PlumeShapeSpatialParams : public ImplicitSpatialParams -{ - typedef ImplicitSpatialParams ParentType; - typedef typename GET_PROP_TYPE(TypeTag, Grid) Grid; - typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView; - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - typedef typename Grid::ctype CoordScalar; - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - enum { - dim=GridView::dimension, - dimWorld=GridView::dimensionworld - }; +} // end namespace Properties - typedef Dune::FieldVector GlobalPosition; - - typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; - typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - - typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; - typedef typename GridView::template Codim<0>::Entity Element; +template +class PlumeShapeSpatialParams : public FVSpatialParams +{ + using ParentType = FVSpatialParams; + using GridCreator = typename GET_PROP_TYPE(TypeTag, GridCreator); + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; + using SubControlVolume = typename FVElementGeometry::SubControlVolume; + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using Element = typename GridView::template Codim<0>::Entity; + static constexpr int dimWorld = GridView::dimensionworld; + using GlobalPosition = Dune::FieldVector; public: - typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw; - typedef typename MaterialLaw::Params MaterialLawParams; + using MaterialLaw = typename GET_PROP_TYPE(TypeTag, MaterialLaw); + using MaterialLawParams = typename MaterialLaw::Params; + using PermeabilityType = Scalar; /*! * \brief The constructor * - * \param gv The grid view + * \param gridView The grid view */ - PlumeShapeSpatialParams(const GridView &gridView) - : ParentType(gridView), k_(0) + PlumeShapeSpatialParams(const Problem& problem) + : ParentType(problem) { - // layerBottom_ = 22.0; + // intrinsic permeability + permeability_ = getParam("SpatialParams.Permeability"); - // intrinsic permeabilities - permeability_ = GET_RUNTIME_PARAM(TypeTag, Scalar, SpatialParams.Permeability); - - // porosity and permeability - porosity_ = 0.35; - for (int i=0; i < dim; i++ ) - k_[i][i] = permeability_; // [m^2] - - // porosities - porosity_ = GET_RUNTIME_PARAM(TypeTag, Scalar, SpatialParams.Porosity); + // porosity + porosity_ = getParam("SpatialParams.Porosity"); // residual saturations - materialParams_.setSwr(GET_RUNTIME_PARAM(TypeTag, Scalar, MaterialLaw.Swr)); - materialParams_.setSnr(GET_RUNTIME_PARAM(TypeTag, Scalar, MaterialLaw.Snr)); + materialParams_.setSwr(getParam("MaterialLaw.Swr")); + materialParams_.setSnr(getParam("MaterialLaw.Snr")); // parameters for the Brooks-Corey law - materialParams_.setPe(GET_RUNTIME_PARAM(TypeTag, Scalar, MaterialLaw.Pe)); - materialParams_.setLambda(GET_RUNTIME_PARAM(TypeTag, Scalar, MaterialLaw.Lambda)); + materialParams_.setPe(getParam("MaterialLaw.Pe")); + materialParams_.setLambda(getParam("MaterialLaw.Lambda")); } - ~PlumeShapeSpatialParams() - {} - /*! - * \brief Apply the intrinsic permeability tensor to a pressure - * potential gradient. + * \brief Function for defining the (intrinsic) permeability \f$[m^2]\f$ + * \note It is possibly solution dependent. * - * \param element The current finite element - * \param fvElemGeom The current finite volume geometry of the element - * \param scvIdx The index of the sub-control volume + * \param element The current element + * \param scv The sub-control volume inside the element. + * \param elemSol The solution at the dofs connected to the element. + * \return instrinsic permeability */ - const Dune::FieldMatrix& - intrinsicPermeability(const Element &element, - const FVElementGeometry &fvElemGeom, - int scvIdx) const + template + PermeabilityType permeability(const Element& element, + const SubControlVolume& scv, + const ElementSolution& elemSol) const { - return k_; + return permeability_; } /*! - * \brief Define the porosity \f$[-]\f$ of the spatial parameters + * \brief Returns the porosity \f$[-]\f$ * - * \param element The finite element - * \param fvElemGeom The finite volume geometry - * \param scvIdx The local index of the sub-control volume where - * the porosity needs to be defined + * \param element The current element + * \param scv The sub-control volume inside the element. + * \param elemSol The solution at the dofs connected to the element + * \return porosity */ - const Scalar porosity(const Element &element, - const FVElementGeometry &fvElemGeom, - int scvIdx) const + template + Scalar porosity(const Element& element, + const SubControlVolume& scv, + const ElementSolution& elemSol) const { return porosity_; } - - /*! - * \brief return the parameter object for the Brooks-Corey material law which depends on the position - * - * \param element The current finite element - * \param fvElemGeom The current finite volume geometry of the element - * \param scvIdx The index of the sub-control volume - */ - const MaterialLawParams& materialLawParams(const Element &element, - const FVElementGeometry &fvElemGeom, - int scvIdx) const - { - return materialParams_; - } - /*! - * \brief Returns the heat capacity \f$[J / (kg K)]\f$ of the rock matrix. - * - * This is only required for non-isothermal models. + * \brief Function for defining the parameters needed by constitutive relationships (kr-sw, pc-sw, etc.). * - * \param element The finite element - * \param fvGeometry The finite volume geometry - * \param scvIdx The local index of the sub-control volume + * \return the material parameters object + * \param globalPos The position of the center of the element */ - Scalar solidHeatCapacity(const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx) const + const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const { - return 790; // specific heat capacity of granite [J / (kg K)] - } - - /*! - * \brief Returns the mass density \f$[kg / m^3]\f$ of the rock matrix. - * - * This is only required for non-isothermal models. - * - * \param element The finite element - * \param fvGeometry The finite volume geometry - * \param scvIdx The local index of the sub-control volume - */ - Scalar solidDensity(const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx) const - { - return 2700; // density of granite [kg/m^3] - } - - /*! - * \brief Returns the thermal conductivity \f$[W/m^2]\f$ of the porous material. - * - * \param element The finite element - * \param fvGeometry The finite volume geometry - * \param scvIdx The local index of the sub-control volume where - * the heat capacity needs to be defined - */ - Scalar solidThermalConductivity(const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx) const - { - return 2.8; + return materialParams_; } private: Scalar permeability_; - Dune::FieldMatrix k_; Scalar porosity_; MaterialLawParams materialParams_; }; } // end namespace Dumux -#endif +#endif // DUMUX_PLUMESHAPE_SPATIAL_PARAMS_HH diff --git a/lecture/mm/columnxylene/columnxyleneexercise.cc b/lecture/mm/columnxylene/columnxyleneexercise.cc index 01bd9fb..f5215ac 100644 --- a/lecture/mm/columnxylene/columnxyleneexercise.cc +++ b/lecture/mm/columnxylene/columnxyleneexercise.cc @@ -46,8 +46,6 @@ #include #include - - /*! * \brief Provides an interface for customizing error messages associated with * reading in parameters. @@ -68,7 +66,6 @@ void usage(const char *progName, const std::string &errorMsg) "\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"; } @@ -78,12 +75,10 @@ void usage(const char *progName, const std::string &errorMsg) //////////////////////// int main(int argc, char** argv) try { - // typedef TTAG(LensOnePTwoCProblem) TypeTag; - // return Dumux::start(argc, argv, usage); using namespace Dumux; // define the type tag for this problem - using TypeTag = TTAG(ColumnProblemBoxTypeTag); + using TypeTag = TTAG(ColumnProblemTypeTag); // initialize MPI, finalize is done automatically on exit const auto& mpiHelper = Dune::MPIHelper::instance(argc, argv); @@ -215,9 +210,6 @@ int main(int argc, char** argv) try Parameters::print(); DumuxMessage::print(/*firstCall=*/false); } - - - } catch (Dumux::ParameterException &e) diff --git a/lecture/mm/columnxylene/columnxyleneexercise.input b/lecture/mm/columnxylene/columnxyleneexercise.input index 4f9e042..429229d 100644 --- a/lecture/mm/columnxylene/columnxyleneexercise.input +++ b/lecture/mm/columnxylene/columnxyleneexercise.input @@ -1,5 +1,3 @@ - - [TimeLoop] DtInitial = 1 # [s] TEnd = 1800 # [s] diff --git a/lecture/mm/columnxylene/columnxyleneproblem.hh b/lecture/mm/columnxylene/columnxyleneproblem.hh index 59575f3..0500df9 100644 --- a/lecture/mm/columnxylene/columnxyleneproblem.hh +++ b/lecture/mm/columnxylene/columnxyleneproblem.hh @@ -38,33 +38,29 @@ #define ISOTHERMAL 0 -namespace Dumux -{ +namespace Dumux { + template class ColumnProblem; -namespace Properties -{ -NEW_TYPE_TAG(ColumnProblem, INHERITS_FROM(ThreePThreeCNI, ColumnSpatialParams)); +namespace Properties { +NEW_TYPE_TAG(ColumnProblemTypeTag, INHERITS_FROM(ThreePThreeCNI, ColumnSpatialParamsTypeTag)); -NEW_TYPE_TAG(ColumnProblemBoxTypeTag, INHERITS_FROM(BoxModel, ColumnProblem)); -// NEW_TYPE_TAG(ColumnProblemCCTpfaTypeTag, INHERITS_FROM(CCTpfaModel, ColumnProblem)); +NEW_TYPE_TAG(ColumnProblemBoxTypeTag, INHERITS_FROM(BoxModel, ColumnProblemTypeTag)); +NEW_TYPE_TAG(ColumnProblemTpfaTypeTag, INHERITS_FROM(CCTpfaModel, ColumnProblemTypeTag)); // Set the grid type -SET_TYPE_PROP(ColumnProblem, Grid, Dune::YaspGrid<2>); +SET_TYPE_PROP(ColumnProblemTypeTag, Grid, Dune::YaspGrid<2>); // Set the problem property -SET_TYPE_PROP(ColumnProblem, Problem, ColumnProblem); +SET_TYPE_PROP(ColumnProblemTypeTag, Problem, ColumnProblem); // Set the fluid system -SET_TYPE_PROP(ColumnProblem, +SET_TYPE_PROP(ColumnProblemTypeTag, FluidSystem, FluidSystems::H2OAirXylene); -// Maximum tolerated relative error in the Newton method - -} - +} // end namespace Properties /*! * \ingroup ThreePThreeCNIBoxModel @@ -74,34 +70,26 @@ template class ColumnProblem : public PorousMediumFlowProblem { using ParentType = PorousMediumFlowProblem; - using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); using GridView = typename GET_PROP_TYPE(TypeTag, GridView); using Grid = typename GridView::Grid; - // copy some indices for convenience using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; - static constexpr int pressureIdx = Indices::pressureIdx; static constexpr int switch1Idx = Indices::switch1Idx; static constexpr int switch2Idx = Indices::switch2Idx; static constexpr int temperatureIdx = Indices::temperatureIdx; static constexpr int energyEqIdx = Indices::energyEqIdx; - - // Phase State + // Phase State static constexpr int threePhases = Indices::threePhases; - - // Grid and world dimension + // Grid and world dimension static constexpr int dim = GridView::dimension; static constexpr int dimWorld = GridView::dimensionworld; - using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); - using Element = typename GridView::template Codim<0>::Entity; using Vertex = typename GridView::template Codim::Entity; using Intersection = typename GridView::Intersection; - using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector); @@ -110,13 +98,9 @@ class ColumnProblem : public PorousMediumFlowProblem public: /*! * \brief The constructor - * - * \param timeManager The time manager - * \param gridView The grid view */ - ColumnProblem(std::shared_ptr fvElementGeometry) - : ParentType(fvElementGeometry) + : ParentType(fvElementGeometry) { FluidSystem::init(); } @@ -132,7 +116,9 @@ public: * This is used as a prefix for files generated by the simulation. */ std::string name() const - { return "columnxylol"; } + { + return "columnxylol"; + } NumEqVector sourceAtPos( const GlobalPosition &globalPos) const @@ -157,11 +143,11 @@ public: BoundaryTypes boundaryTypes( const Vertex &vertex) const { BoundaryTypes values; - const GlobalPosition globalPos = vertex.geometry().center(); - if(globalPos[1] < eps_) + if (globalPos[1] < eps_) values.setAllDirichlet(); + else values.setAllNeumann(); @@ -180,7 +166,6 @@ public: PrimaryVariables dirichlet( const Vertex &vertex) const { PrimaryVariables values; - const GlobalPosition globalPos = vertex.geometry().center(); initial_(values, globalPos); @@ -203,10 +188,10 @@ public: * in normal direction of each phase. Negative values mean influx. */ PrimaryVariables neumann( const Element &element, - const FVElementGeometry &fvElemGeom, - const Intersection &is, - int scvIdx, - int boundaryFaceIdx) const + const FVElementGeometry &fvElemGeom, + const Intersection &is, + int scvIdx, + int boundaryFaceIdx) const { PrimaryVariables values; @@ -244,11 +229,10 @@ public: * variables. */ PrimaryVariables initial( const Element &element, - const FVElementGeometry &fvElemGeom, - int scvIdx) const + const FVElementGeometry &fvElemGeom, + int scvIdx) const { PrimaryVariables values; - const GlobalPosition &globalPos = element.geometry().corner(scvIdx); initial_(values, globalPos); @@ -266,10 +250,8 @@ public: return threePhases; } - private: - // internal method for the initial condition (reused for the - // dirichlet conditions!) + // internal method for the initial condition (reused for the dirichlet conditions!) PrimaryVariables initial_( const GlobalPosition &globalPos) const { PrimaryVariables values; @@ -279,40 +261,68 @@ private: values[temperatureIdx] = 296.15; values[pressureIdx] = 1.e5; - if(y > 1.2 - eps_){ + if (y > 1.2 - eps_) + { values[switch2Idx] = 0.112; // almost no contaminant component values[switch1Idx] = 0.005; - } else if(y < 1.2-0.3 + eps_){ // extended domain + } + + else if (y < 1.2-0.3 + eps_) + { + // extended domain values[switch2Idx] = 1.e-4; // almost no contaminant component values[switch1Idx] = 0.005; - } else { - values[switch1Idx] = 0.005; - if((y<1.2-0.001+eps_)&&(y>1.2-0.0148-eps_)) values[switch2Idx] = 0+((1.2-y)/0.0148)*0.112; - if((y<1.2-0.0148-eps_)&&(y>1.2-0.0296-eps_)) values[switch2Idx] = 0.112+(((1.2-y)-0.0148)/0.0148)*(0.120-0.112); - if((y<1.2-0.0296-eps_)&&(y>1.2-0.0444-eps_)) values[switch2Idx] = 0.120+(((1.2-y)-0.0296)/0.0148)*(0.125-0.120); - if((y<1.2-0.0444-eps_)&&(y>1.2-0.0592-eps_)) values[switch2Idx] = 0.125+(((1.2-y)-0.0444)/0.0148)*(0.137-0.125); - if((y<1.2-0.0592-eps_)&&(y>1.2-0.0740-eps_)) values[switch2Idx] = 0.137+(((1.2-y)-0.0592)/0.0148)*(0.150-0.137); - if((y<1.2-0.0740-eps_)&&(y>1.2-0.0888-eps_)) values[switch2Idx] = 0.150+(((1.2-y)-0.0740)/0.0148)*(0.165-0.150); - if((y<1.2-0.0888-eps_)&&(y>1.2-0.1036-eps_)) values[switch2Idx] = 0.165+(((1.2-y)-0.0888)/0.0148)*(0.182-0.165); - if((y<1.2-0.1036-eps_)&&(y>1.2-0.1184-eps_)) values[switch2Idx] = 0.182+(((1.2-y)-0.1036)/0.0148)*(0.202-0.182); - if((y<1.2-0.1184-eps_)&&(y>1.2-0.1332-eps_)) values[switch2Idx] = 0.202+(((1.2-y)-0.1184)/0.0148)*(0.226-0.202); - if((y<1.2-0.1332-eps_)&&(y>1.2-0.1480-eps_)) values[switch2Idx] = 0.226+(((1.2-y)-0.1332)/0.0148)*(0.257-0.226); - if((y<1.2-0.1480-eps_)&&(y>1.2-0.1628-eps_)) values[switch2Idx] = 0.257+(((1.2-y)-0.1480)/0.0148)*(0.297-0.257); - if((y<1.2-0.1628-eps_)&&(y>1.2-0.1776-eps_)) values[switch2Idx] = 0.297+(((1.2-y)-0.1628)/0.0148)*(0.352-0.297); - if((y<1.2-0.1776-eps_)&&(y>1.2-0.1924-eps_)) values[switch2Idx] = 0.352+(((1.2-y)-0.1776)/0.0148)*(0.426-0.352); - if((y<1.2-0.1924-eps_)&&(y>1.2-0.2072-eps_)) values[switch2Idx] = 0.426+(((1.2-y)-0.1924)/0.0148)*(0.522-0.426); - if((y<1.2-0.2072-eps_)&&(y>1.2-0.2220-eps_)) values[switch2Idx] = 0.522+(((1.2-y)-0.2072)/0.0148)*(0.640-0.522); - if((y<1.2-0.2220-eps_)&&(y>1.2-0.2368-eps_)) values[switch2Idx] = 0.640+(((1.2-y)-0.2220)/0.0148)*(0.767-0.640); - if((y<1.2-0.2368-eps_)&&(y>1.2-0.2516-eps_)) values[switch2Idx] = 0.767+(((1.2-y)-0.2368)/0.0148)*(0.878-0.767); - if((y<1.2-0.2516-eps_)&&(y>1.2-0.2664-eps_)) values[switch2Idx] = 0.878+(((1.2-y)-0.2516)/0.0148)*(0.953-0.878); - if((y<1.2-0.2664-eps_)&&(y>1.2-0.2812-eps_)) values[switch2Idx] = 0.953+(((1.2-y)-0.2664)/0.0148)*(0.988-0.953); - if((y<1.2-0.2812-eps_)&&(y>1.2-0.3000-eps_)) values[switch2Idx] = 0.988; } + else + { + values[switch1Idx] = 0.005; + if ((y<1.2-0.001+eps_)&&(y>1.2-0.0148-eps_)) + values[switch2Idx] = 0+((1.2-y)/0.0148)*0.112; + if ((y<1.2-0.0148-eps_)&&(y>1.2-0.0296-eps_)) + values[switch2Idx] = 0.112+(((1.2-y)-0.0148)/0.0148)*(0.120-0.112); + if ((y<1.2-0.0296-eps_)&&(y>1.2-0.0444-eps_)) + values[switch2Idx] = 0.120+(((1.2-y)-0.0296)/0.0148)*(0.125-0.120); + if ((y<1.2-0.0444-eps_)&&(y>1.2-0.0592-eps_)) + values[switch2Idx] = 0.125+(((1.2-y)-0.0444)/0.0148)*(0.137-0.125); + if ((y<1.2-0.0592-eps_)&&(y>1.2-0.0740-eps_)) + values[switch2Idx] = 0.137+(((1.2-y)-0.0592)/0.0148)*(0.150-0.137); + if ((y<1.2-0.0740-eps_)&&(y>1.2-0.0888-eps_)) + values[switch2Idx] = 0.150+(((1.2-y)-0.0740)/0.0148)*(0.165-0.150); + if ((y<1.2-0.0888-eps_)&&(y>1.2-0.1036-eps_)) + values[switch2Idx] = 0.165+(((1.2-y)-0.0888)/0.0148)*(0.182-0.165); + if ((y<1.2-0.1036-eps_)&&(y>1.2-0.1184-eps_)) + values[switch2Idx] = 0.182+(((1.2-y)-0.1036)/0.0148)*(0.202-0.182); + if ((y<1.2-0.1184-eps_)&&(y>1.2-0.1332-eps_)) + values[switch2Idx] = 0.202+(((1.2-y)-0.1184)/0.0148)*(0.226-0.202); + if ((y<1.2-0.1332-eps_)&&(y>1.2-0.1480-eps_)) + values[switch2Idx] = 0.226+(((1.2-y)-0.1332)/0.0148)*(0.257-0.226); + if ((y<1.2-0.1480-eps_)&&(y>1.2-0.1628-eps_)) + values[switch2Idx] = 0.257+(((1.2-y)-0.1480)/0.0148)*(0.297-0.257); + if ((y<1.2-0.1628-eps_)&&(y>1.2-0.1776-eps_)) + values[switch2Idx] = 0.297+(((1.2-y)-0.1628)/0.0148)*(0.352-0.297); + if ((y<1.2-0.1776-eps_)&&(y>1.2-0.1924-eps_)) + values[switch2Idx] = 0.352+(((1.2-y)-0.1776)/0.0148)*(0.426-0.352); + if ((y<1.2-0.1924-eps_)&&(y>1.2-0.2072-eps_)) + values[switch2Idx] = 0.426+(((1.2-y)-0.1924)/0.0148)*(0.522-0.426); + if ((y<1.2-0.2072-eps_)&&(y>1.2-0.2220-eps_)) + values[switch2Idx] = 0.522+(((1.2-y)-0.2072)/0.0148)*(0.640-0.522); + if ((y<1.2-0.2220-eps_)&&(y>1.2-0.2368-eps_)) + values[switch2Idx] = 0.640+(((1.2-y)-0.2220)/0.0148)*(0.767-0.640); + if ((y<1.2-0.2368-eps_)&&(y>1.2-0.2516-eps_)) + values[switch2Idx] = 0.767+(((1.2-y)-0.2368)/0.0148)*(0.878-0.767); + if ((y<1.2-0.2516-eps_)&&(y>1.2-0.2664-eps_)) + values[switch2Idx] = 0.878+(((1.2-y)-0.2516)/0.0148)*(0.953-0.878); + if ((y<1.2-0.2664-eps_)&&(y>1.2-0.2812-eps_)) + values[switch2Idx] = 0.953+(((1.2-y)-0.2664)/0.0148)*(0.988-0.953); + if ((y<1.2-0.2812-eps_)&&(y>1.2-0.3000-eps_)) + values[switch2Idx] = 0.988; + } } const Scalar eps_ = 1e-6; }; -} //end namespace -#endif +} //end namespace Dumux + +#endif // DUMUX_COLUMNXYLENEPROBLEM_HH diff --git a/lecture/mm/columnxylene/columnxyleneproblem2.hh b/lecture/mm/columnxylene/columnxyleneproblem2.hh index 427d5e5..a8e3e58 100644 --- a/lecture/mm/columnxylene/columnxyleneproblem2.hh +++ b/lecture/mm/columnxylene/columnxyleneproblem2.hh @@ -24,7 +24,6 @@ * trapped NAPL contamination. */ - // THIS IS THE SAME EXAMPLE BUT ONLY 0.3m AND WITH DIRICHLET CONDITION // LIKE INITIAL, WHICH MEANS, WE CANNOT REALLY MODEL THE OUTFLOW AT // THE BOTTOM, SINCE THE SATURATION CANNOT CHANGE @@ -41,35 +40,27 @@ #define ISOTHERMAL 0 -namespace Dumux -{ +namespace Dumux { + template class ColumnProblem; -namespace Properties -{ -NEW_TYPE_TAG(ColumnProblem, INHERITS_FROM(BoxThreePThreeCNI, ColumnSpatialParams)); +namespace Properties { + +NEW_TYPE_TAG(ColumnProblemTypeTag, INHERITS_FROM(BoxThreePThreeCNI, ColumnSpatialParamsTypeTag)); // Set the grid type -SET_TYPE_PROP(ColumnProblem, Grid, Dune::YaspGrid<2>); +SET_TYPE_PROP(ColumnProblemTypeTag, Grid, Dune::YaspGrid<2>); // Set the problem property -SET_TYPE_PROP(ColumnProblem, Problem, ColumnProblem); +SET_TYPE_PROP(ColumnProblemTypeTag, Problem, ColumnProblem); // Set the fluid system -SET_TYPE_PROP(ColumnProblem, +SET_TYPE_PROP(ColumnProblemTypeTag, FluidSystem, FluidSystems::H2OAirXylene); -// Enable Gravity - - -// Maximum tolerated relative error in the Newton method -// SET_SCALAR_PROP(ColumnProblem, NewtonMaxRelativeShift, 1e-4); - - -} - +} // end namespace Properties /*! * \ingroup ThreePThreeCNIBoxModel @@ -81,36 +72,26 @@ class ColumnProblem : public PorousMediumFlowProblem using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); using GridView = typename GET_PROP_TYPE(TypeTag, GridView); using Grid = typename GridView::Grid; - - typedef ImplicitPorousMediaProblem ParentType; - + using ParentType = PorousMediumFlowProblem; // copy some indices for convenience - using Indices = typename GET_PROP_TYPE(TypeTag, Indices); - + using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; static constexpr int pressureIdx = Indices::pressureIdx; static constexpr int switch1Idx = Indices::switch1Idx; static constexpr int switch2Idx = Indices::switch2Idx; static constexpr int temperatureIdx = Indices::temperatureIdx; static constexpr int energyEqIdx = Indices::energyEqIdx; - - // Phase State + // Phase State static constexpr int threePhases = Indices::threePhases; - - // Grid and world dimension + // Grid and world dimension static constexpr int dim = GridView::dimension; static constexpr int dimWorld = GridView::dimensionworld; - - using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); - using Element = typename GridView::template Codim<0>::Entity; using Vertex = typename GridView::template Codim::Entity; using Intersection = typename GridView::Intersection; - using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); - using GlobalPosition = typename Element::Geometry::GlobalCoordinate; public: @@ -121,7 +102,8 @@ public: * \param gridView The grid view */ ColumnProblem(std::shared_ptr fvGridGeometry) - : ParentType(fvGridGeometry) eps_(1e-6) + : ParentType(fvGridGeometry) + , eps_(1e-6) { FluidSystem::init(); } @@ -137,13 +119,13 @@ public: * This is used as a prefix for files generated by the simulation. */ std::string name() const - { return "columnxylol"; } - + { + return "columnxylol"; + } - void sourceAtPos(PrimaryVariables &values, - const GlobalPosition &globalPos) const + PrimaryVariables sourceAtPos( const GlobalPosition &globalPos) const { - values = 0; + return PrimaryVariables(0.0); } // \} @@ -160,14 +142,18 @@ public: * \param values The boundary types for the conservation equations * \param vertex The vertex for which the boundary type is set */ - void boundaryTypes(BoundaryTypes &values, const Vertex &vertex) const + BoundaryTypes boundaryTypes(const Vertex &vertex) const { + BoundaryTypes values; const GlobalPosition globalPos = vertex.geometry().center(); - if(globalPos[1] < eps_) + if (globalPos[1] < eps_) values.setAllDirichlet(); + else values.setAllNeumann(); + + return values; } /*! @@ -179,11 +165,13 @@ public: * * For this method, the \a values parameter stores primary variables. */ - void dirichlet(PrimaryVariables &values, const Vertex &vertex) const + PrimaryVariables dirichlet( const Vertex &vertex) const { + PrimaryVariables values; const GlobalPosition globalPos = vertex.geometry().center(); - initial_(values, globalPos); + + return values; } /*! @@ -200,24 +188,25 @@ public: * For this method, the \a values parameter stores the mass flux * in normal direction of each phase. Negative values mean influx. */ - void neumann(PrimaryVariables &values, - const Element &element, - const FVElementGeometry &fvElemGeom, - const Intersection &is, - int scvIdx, - int boundaryFaceIdx) const + PrimaryVariables neumann( const Element &element, + const FVElementGeometry &fvElemGeom, + const Intersection &is, + int scvIdx, + int boundaryFaceIdx) const { + PrimaryVariables values(0.0); const GlobalPosition &globalPos = element.geometry().corner(scvIdx); - values = 0; // negative values for injection if (globalPos[1] > 0.3 - eps_) { - values[Indices::contiWEqIdx] = GET_RUNTIME_PARAM(TypeTag, Scalar, steamFlux); + values[Indices::contiWEqIdx] = getParam("SpatialParams.steamFlux"); values[Indices::contiGEqIdx] = -0.000001; values[Indices::contiNEqIdx] = -0.00; - values[Indices::energyEqIdx] = GET_RUNTIME_PARAM(TypeTag, Scalar, enthalpyFlux); + values[Indices::energyEqIdx] = getParam("SpatialParams.enthalpyFlux"); } + + return values; } // \} @@ -238,15 +227,17 @@ public: * For this method, the \a values parameter stores primary * variables. */ - void initial(PrimaryVariables &values, - const Element &element, - const FVElementGeometry &fvElemGeom, - int scvIdx) const + PrimaryVariables initial( const Element &element, + const FVElementGeometry &fvElemGeom, + int scvIdx) const { + PrimaryVariables values; + const GlobalPosition &globalPos = element.geometry().corner(scvIdx); initial_(values, globalPos); + return values; } /*! @@ -259,66 +250,70 @@ public: return threePhases; } - bool shouldWriteRestartFile() const - { - return 0; - } - - - - bool shouldWriteOutput() const - { - - int outputInterval = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, int, TimeManager, OutputInterval); - - return (this->timeManager().timeStepIndex() % outputInterval == 0 || - this->timeManager().willBeFinished()); - } - - - private: - // internal method for the initial condition (reused for the - // dirichlet conditions!) - void initial_(PrimaryVariables &values, - const GlobalPosition &globalPos) const + // internal method for the initial condition (reused for the dirichlet conditions!) + void initial_(PrimaryVariables &values, const GlobalPosition &globalPos) const { const Scalar y = globalPos[1]; values[temperatureIdx] = 296.15; values[pressureIdx] = 1.e5; - if(y > 0.3 - eps_){ + if (y > 0.3 - eps_) + { values[switch2Idx] = 0.112; // almost no contaminant component values[switch1Idx] = 0.005; - } else { - values[switch1Idx] = 0.005; - if((y<0.3-0.001+eps_)&&(y>0.3-0.0148-eps_)) values[switch2Idx] = 0+((0.3-y)/0.0148)*0.112; - if((y<0.3-0.0148-eps_)&&(y>0.3-0.0296-eps_)) values[switch2Idx] = 0.112+(((0.3-y)-0.0148)/0.0148)*(0.120-0.112); - if((y<0.3-0.0296-eps_)&&(y>0.3-0.0444-eps_)) values[switch2Idx] = 0.120+(((0.3-y)-0.0296)/0.0148)*(0.125-0.120); - if((y<0.3-0.0444-eps_)&&(y>0.3-0.0592-eps_)) values[switch2Idx] = 0.125+(((0.3-y)-0.0444)/0.0148)*(0.137-0.125); - if((y<0.3-0.0592-eps_)&&(y>0.3-0.0740-eps_)) values[switch2Idx] = 0.137+(((0.3-y)-0.0592)/0.0148)*(0.150-0.137); - if((y<0.3-0.0740-eps_)&&(y>0.3-0.0888-eps_)) values[switch2Idx] = 0.150+(((0.3-y)-0.0740)/0.0148)*(0.165-0.150); - if((y<0.3-0.0888-eps_)&&(y>0.3-0.1036-eps_)) values[switch2Idx] = 0.165+(((0.3-y)-0.0888)/0.0148)*(0.182-0.165); - if((y<0.3-0.1036-eps_)&&(y>0.3-0.1184-eps_)) values[switch2Idx] = 0.182+(((0.3-y)-0.1036)/0.0148)*(0.202-0.182); - if((y<0.3-0.1184-eps_)&&(y>0.3-0.1332-eps_)) values[switch2Idx] = 0.202+(((0.3-y)-0.1184)/0.0148)*(0.226-0.202); - if((y<0.3-0.1332-eps_)&&(y>0.3-0.1480-eps_)) values[switch2Idx] = 0.226+(((0.3-y)-0.1332)/0.0148)*(0.257-0.226); - if((y<0.3-0.1480-eps_)&&(y>0.3-0.1628-eps_)) values[switch2Idx] = 0.257+(((0.3-y)-0.1480)/0.0148)*(0.297-0.257); - if((y<0.3-0.1628-eps_)&&(y>0.3-0.1776-eps_)) values[switch2Idx] = 0.297+(((0.3-y)-0.1628)/0.0148)*(0.352-0.297); - if((y<0.3-0.1776-eps_)&&(y>0.3-0.1924-eps_)) values[switch2Idx] = 0.352+(((0.3-y)-0.1776)/0.0148)*(0.426-0.352); - if((y<0.3-0.1924-eps_)&&(y>0.3-0.2072-eps_)) values[switch2Idx] = 0.426+(((0.3-y)-0.1924)/0.0148)*(0.522-0.426); - if((y<0.3-0.2072-eps_)&&(y>0.3-0.2220-eps_)) values[switch2Idx] = 0.522+(((0.3-y)-0.2072)/0.0148)*(0.640-0.522); - if((y<0.3-0.2220-eps_)&&(y>0.3-0.2368-eps_)) values[switch2Idx] = 0.640+(((0.3-y)-0.2220)/0.0148)*(0.767-0.640); - if((y<0.3-0.2368-eps_)&&(y>0.3-0.2516-eps_)) values[switch2Idx] = 0.767+(((0.3-y)-0.2368)/0.0148)*(0.878-0.767); - if((y<0.3-0.2516-eps_)&&(y>0.3-0.2664-eps_)) values[switch2Idx] = 0.878+(((0.3-y)-0.2516)/0.0148)*(0.953-0.878); - if((y<0.3-0.2664-eps_)&&(y>0.3-0.2812-eps_)) values[switch2Idx] = 0.953+(((0.3-y)-0.2664)/0.0148)*(0.988-0.953); - if((y<0.3-0.2812-eps_)&&(y>0.3-0.3000-eps_)) values[switch2Idx] = 0.988; } + else + { + values[switch1Idx] = 0.005; + if((y<0.3-0.001+eps_)&&(y>0.3-0.0148-eps_)) + values[switch2Idx] = 0+((0.3-y)/0.0148)*0.112; + if((y<0.3-0.0148-eps_)&&(y>0.3-0.0296-eps_)) + values[switch2Idx] = 0.112+(((0.3-y)-0.0148)/0.0148)*(0.120-0.112); + if((y<0.3-0.0296-eps_)&&(y>0.3-0.0444-eps_)) + values[switch2Idx] = 0.120+(((0.3-y)-0.0296)/0.0148)*(0.125-0.120); + if((y<0.3-0.0444-eps_)&&(y>0.3-0.0592-eps_)) + values[switch2Idx] = 0.125+(((0.3-y)-0.0444)/0.0148)*(0.137-0.125); + if((y<0.3-0.0592-eps_)&&(y>0.3-0.0740-eps_)) + values[switch2Idx] = 0.137+(((0.3-y)-0.0592)/0.0148)*(0.150-0.137); + if((y<0.3-0.0740-eps_)&&(y>0.3-0.0888-eps_)) + values[switch2Idx] = 0.150+(((0.3-y)-0.0740)/0.0148)*(0.165-0.150); + if((y<0.3-0.0888-eps_)&&(y>0.3-0.1036-eps_)) + values[switch2Idx] = 0.165+(((0.3-y)-0.0888)/0.0148)*(0.182-0.165); + if((y<0.3-0.1036-eps_)&&(y>0.3-0.1184-eps_)) + values[switch2Idx] = 0.182+(((0.3-y)-0.1036)/0.0148)*(0.202-0.182); + if((y<0.3-0.1184-eps_)&&(y>0.3-0.1332-eps_)) + values[switch2Idx] = 0.202+(((0.3-y)-0.1184)/0.0148)*(0.226-0.202); + if((y<0.3-0.1332-eps_)&&(y>0.3-0.1480-eps_)) + values[switch2Idx] = 0.226+(((0.3-y)-0.1332)/0.0148)*(0.257-0.226); + if((y<0.3-0.1480-eps_)&&(y>0.3-0.1628-eps_)) + values[switch2Idx] = 0.257+(((0.3-y)-0.1480)/0.0148)*(0.297-0.257); + if((y<0.3-0.1628-eps_)&&(y>0.3-0.1776-eps_)) + values[switch2Idx] = 0.297+(((0.3-y)-0.1628)/0.0148)*(0.352-0.297); + if((y<0.3-0.1776-eps_)&&(y>0.3-0.1924-eps_)) + values[switch2Idx] = 0.352+(((0.3-y)-0.1776)/0.0148)*(0.426-0.352); + if((y<0.3-0.1924-eps_)&&(y>0.3-0.2072-eps_)) + values[switch2Idx] = 0.426+(((0.3-y)-0.1924)/0.0148)*(0.522-0.426); + if((y<0.3-0.2072-eps_)&&(y>0.3-0.2220-eps_)) + values[switch2Idx] = 0.522+(((0.3-y)-0.2072)/0.0148)*(0.640-0.522); + if((y<0.3-0.2220-eps_)&&(y>0.3-0.2368-eps_)) + values[switch2Idx] = 0.640+(((0.3-y)-0.2220)/0.0148)*(0.767-0.640); + if((y<0.3-0.2368-eps_)&&(y>0.3-0.2516-eps_)) + values[switch2Idx] = 0.767+(((0.3-y)-0.2368)/0.0148)*(0.878-0.767); + if((y<0.3-0.2516-eps_)&&(y>0.3-0.2664-eps_)) + values[switch2Idx] = 0.878+(((0.3-y)-0.2516)/0.0148)*(0.953-0.878); + if((y<0.3-0.2664-eps_)&&(y>0.3-0.2812-eps_)) + values[switch2Idx] = 0.953+(((0.3-y)-0.2664)/0.0148)*(0.988-0.953); + if((y<0.3-0.2812-eps_)&&(y>0.3-0.3000-eps_)) + values[switch2Idx] = 0.988; + } } const Scalar eps_; }; -} //end namespace -#endif +} //end namespace Dumux + +#endif // DUMUX_COLUMNXYLENEPROBLEM_HH diff --git a/lecture/mm/columnxylene/columnxylenespatialparams.hh b/lecture/mm/columnxylene/columnxylenespatialparams.hh index 4c7ff03..6759a5f 100644 --- a/lecture/mm/columnxylene/columnxylenespatialparams.hh +++ b/lecture/mm/columnxylene/columnxylenespatialparams.hh @@ -31,22 +31,21 @@ #include #include -namespace Dumux -{ +namespace Dumux { //forward declaration template class ColumnSpatialParams; -namespace Properties -{ +namespace Properties { + // The spatial parameters TypeTag -NEW_TYPE_TAG(ColumnSpatialParams); +NEW_TYPE_TAG(ColumnSpatialParamsTypeTag); // Set the spatial parameters -SET_TYPE_PROP(ColumnSpatialParams, SpatialParams, Dumux::ColumnSpatialParams); +SET_TYPE_PROP(ColumnSpatialParamsTypeTag, SpatialParams, Dumux::ColumnSpatialParams); -} +} // end namespace Properties /*! * \ingroup ThreePThreeCNIModel @@ -55,8 +54,8 @@ SET_TYPE_PROP(ColumnSpatialParams, SpatialParams, Dumux::ColumnSpatialParams class ColumnSpatialParams : public FVSpatialParams > + typename GET_PROP_TYPE(TypeTag, Scalar), + ColumnSpatialParams > { using ParentType = FVSpatialParams::Entity; - static constexpr int dim=GridView::dimension; static constexpr int dimWorld=GridView::dimensionworld; - using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; - static constexpr int wPhaseIdx = Indices::wPhaseIdx; static constexpr int nPhaseIdx = Indices::nPhaseIdx; - using GlobalPosition = typename Element::Geometry::GlobalCoordinate; using Vector = Dune::FieldVector; - - using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector); - using FluxVariables = typename GET_PROP_TYPE(TypeTag, FluxVariables); using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView; @@ -91,6 +83,7 @@ public: using EffectiveLaw = RegularizedParkerVanGen3P; using MaterialLaw = EffToAbsLaw; using MaterialLawParams = typename MaterialLaw::Params; + using PermeabilityType = Scalar; /*! * \brief The constructor @@ -166,6 +159,7 @@ public: const GlobalPosition &pos = fvElemGeom.subContVol[scvIdx].global; if (isFineMaterial_(pos)) return fineK_; + else return coarseK_; } @@ -184,11 +178,11 @@ public: const GlobalPosition &pos = fvElemGeom.subContVol[scvIdx].global; if (isFineMaterial_(pos)) return finePorosity_; + else return coarsePorosity_; } - /*! * \brief return the parameter object for the Brooks-Corey material law which depends on the position * @@ -203,6 +197,7 @@ public: const GlobalPosition &pos = fvElemGeom.subContVol[scvIdx].global; if (isFineMaterial_(pos)) return fineMaterialParams_; + else return coarseMaterialParams_; } @@ -223,6 +218,7 @@ public: const GlobalPosition &pos = fvGeometry.subContVol[scvIdx].global; if (isFineMaterial_(pos)) return fineHeatCap_; + else return coarseHeatCap_; } @@ -265,6 +261,7 @@ private: { return true; } + else { return false; @@ -288,6 +285,6 @@ private: static constexpr Scalar eps_ = 1.5e-7; }; -} +} // end namespace Dumux -#endif +#endif // DUMUX_COLUMNXYLENE_SPATIAL_PARAMS_HH diff --git a/lecture/mm/columnxylene/columnxylenespatialparams2.hh b/lecture/mm/columnxylene/columnxylenespatialparams2.hh index 48f7650..cf63d50 100644 --- a/lecture/mm/columnxylene/columnxylenespatialparams2.hh +++ b/lecture/mm/columnxylene/columnxylenespatialparams2.hh @@ -36,24 +36,21 @@ #include #include -namespace Dumux -{ +namespace Dumux { //forward declaration template class ColumnSpatialParams; -namespace Properties -{ +namespace Properties { + // The spatial parameters TypeTag -NEW_TYPE_TAG(ColumnSpatialParams); +NEW_TYPE_TAG(ColumnSpatialParamsTypeTag); // Set the spatial parameters -SET_TYPE_PROP(ColumnSpatialParams, SpatialParams, Dumux::ColumnSpatialParams); - +SET_TYPE_PROP(ColumnSpatialParamsTypeTag, SpatialParams, Dumux::ColumnSpatialParams); - -} +} // end namespace Properties /*! * \ingroup ThreePThreeCNIModel @@ -64,58 +61,39 @@ template class ColumnSpatialParams : public PorousMediumFlowProblem { using ParentType = PorousMediumFlowProblem; - using Grid = typename GET_PROP_TYPE(TypeTag, Grid); using GridView = typename GET_PROP_TYPE(TypeTag, GridView); using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); using CoordScalar = typename Grid::ctype; - - using Indices = typename GET_PROP_TYPE(TypeTag, Indices); - - enum { - dim=GridView::dimension, - dimWorld=GridView::dimensionworld - }; - - - - enum { - wPhaseIdx = Indices::wPhaseIdx, - nPhaseIdx = Indices::nPhaseIdx - }; - + using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; + static constexpr int dim=GridView::dimension; + static constexpr int dimWorld=GridView::dimensionworld; + static constexpr int wPhaseIdx = Indices::wPhaseIdx; + static constexpr int nPhaseIdx = Indices::nPhaseIdx; using GlobalPosition = Dune::FieldVector; using Vector = Dune::FieldVector; - - using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector); - using FluxVariables = typename GET_PROP_TYPE(TypeTag, FluxVariables); using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables); - using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); using Element = typename GridView::template Codim<0>::Entity; - public: - using EffectiveLaw = RegularizedParkerVanGen3P; using MaterialLaw = EffToAbsLaw; using MaterialLawParams = typename MaterialLaw::Params; /*! * \brief The constructor - * - * \param gv The grid view */ ColumnSpatialParams(std::shared_ptr fvGridGeometry) : ParentType(fvGridGeometry) { // intrinsic permeabilities - fineK_ = GET_RUNTIME_PARAM(TypeTag, Scalar, permeability); + fineK_ = getParam("SpatialParams.permeability"); // porosities - finePorosity_ = GET_RUNTIME_PARAM(TypeTag, Scalar, porosity); + finePorosity_ = getParam("SpatialParams.porosity"); // specific heat capacities fineHeatCap_ = 850.; @@ -124,21 +102,19 @@ public: lambdaSolid_ = 2.8; // residual saturations - // TODO There is no branch in the param-tree for the following variables. Is this thought to be a good solution? Should it be changed? - fineMaterialParams_.setSwr( getParam("swr") ); - fineMaterialParams_.setSnr( getParam("snr") ); - fineMaterialParams_.setSgr( getParam("Sgr") ); + fineMaterialParams_.setSwr( getParam("SpatialParams.swr") ); + fineMaterialParams_.setSnr( getParam("SpatialParams.snr") ); + fineMaterialParams_.setSgr( getParam("SpatialParams.Sgr") ); // parameters for the 3phase van Genuchten law - fineMaterialParams_.setVgAlpha( getParam("vanGenuchtenAlpha") ); - fineMaterialParams_.setVgn( getParam("vanGenuchtenN") ); - + fineMaterialParams_.setVgAlpha( getParam("SpatialParams.vanGenuchtenAlpha") ); + fineMaterialParams_.setVgn( getParam("SpatialParams.vanGenuchtenN") ); fineMaterialParams_.setKrRegardsSnr(true); // parameters for the scaling of capillary pressure (GW = 1); - fineMaterialParams_.setBetaNw( getParam("betaNW") ); - fineMaterialParams_.setBetaGn( getParam("betaGN") ); - fineMaterialParams_.setBetaGw( getParam("betaGW") ); + fineMaterialParams_.setBetaNw( getParam("SpatialParams.betaNW") ); + fineMaterialParams_.setBetaGn( getParam("SpatialParams.betaGN") ); + fineMaterialParams_.setBetaGw( getParam("SpatialParams.betaGW") ); // parameters for adsorption fineMaterialParams_.setKdNAPL(0.); @@ -148,7 +124,6 @@ public: ~ColumnSpatialParams() {} - /*! * \brief Update the spatial parameters with the flow solution * after a timestep. @@ -157,7 +132,7 @@ public: */ void update(const SolutionVector &globalSolution) { - }; + } /*! * \brief Apply the intrinsic permeability tensor to a pressure @@ -209,7 +184,7 @@ public: * This is only required for non-isothermal models. * * \param element The finite element - * \param fvGeometry The finite volume geometry + * \param fvGeometry The finite volumGET_RUNTIME_PARAMe geometry * \param scvIdx The local index of the sub-control volume */ Scalar solidHeatCapacity(const Element &element, @@ -252,16 +227,13 @@ public: private: Scalar fineK_; - Scalar finePorosity_; - Scalar fineHeatCap_; - MaterialLawParams fineMaterialParams_; - Scalar lambdaSolid_; + }; -} +} // end namespace Dumux -#endif +#endif // DUMUX_COLUMNXYLENE_SPATIAL_PARAMS_HH diff --git a/lecture/mm/convectivemixing/convmixexercise.cc b/lecture/mm/convectivemixing/convmixexercise.cc index 4d496d2..4adeda3 100644 --- a/lecture/mm/convectivemixing/convmixexercise.cc +++ b/lecture/mm/convectivemixing/convmixexercise.cc @@ -64,8 +64,154 @@ void usage(const char *progName, const std::string &errorMsg) /*@\label{tutorial << "\n"; } -int main(int argc, char** argv) +//////////////////////// +// the main function +//////////////////////// +int main(int argc, char** argv) try { - typedef TTAG(ConvectiveMixingProblem) TypeTag; - return Dumux::start < TypeTag > (argc, argv, usage); + using namespace Dumux; + + // define the type tag for this problem + using TypeTag = TTAG(ConvectiveMixingProblemTypeTag); + + // 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) + GridManager gridManager; + gridManager.init(); + + //////////////////////////////////////////////////////////// + // run instationary non-linear problem on this grid + //////////////////////////////////////////////////////////// + + // we compute on the leaf grid view + const auto& leafGridView = gridManager.grid().leafGridView(); + + // create the finite volume grid geometry + using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); + auto fvGridGeometry = std::make_shared(leafGridView); + fvGridGeometry->update(); + + // the problem (initial and boundary conditions) + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); + auto problem = std::make_shared(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(problem, fvGridGeometry); + gridVariables->init(x, xOld); + + // get some time loop parameters + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + const auto tEnd = getParam("TimeLoop.TEnd"); + const auto maxDt = getParam("TimeLoop.MaxTimeStepSize"); + auto dt = getParam("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")) // Fehlt ebenso + restartTime = getParam("TimeLoop.Restart"); + + // intialize the vtk output module + using VtkOutputFields = typename GET_PROP_TYPE(TypeTag, VtkOutputFields); + VtkOutputModule 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>(restartTime, dt, tEnd); + timeLoop->setMaxTimeStepSize(maxDt); + + // the assembler with time loop for instationary problem + using Assembler = FVAssembler; + auto assembler = std::make_shared(problem, fvGridGeometry, gridVariables, timeLoop); + + // the linear solver + using LinearSolver = AMGBackend; + auto linearSolver = std::make_shared(leafGridView, fvGridGeometry->dofMapper()); + + // the non-linear solver + using NewtonSolver = Dumux::NewtonSolver; + NewtonSolver nonLinearSolver(assembler, linearSolver); + + // time loop + timeLoop->start(); do + { + // set previous solution for storage evaluations + assembler->setPreviousSolution(xOld); + + // solve the non-linear system with time step control + nonLinearSolver.solve(x, *timeLoop); + + // 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 the Newton solver + timeLoop->setTimeStepSize(nonLinearSolver.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; +} + +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; } diff --git a/lecture/mm/convectivemixing/convmixproblem.hh b/lecture/mm/convectivemixing/convmixproblem.hh index 8a79327..81d5b00 100644 --- a/lecture/mm/convectivemixing/convmixproblem.hh +++ b/lecture/mm/convectivemixing/convmixproblem.hh @@ -25,7 +25,6 @@ #include #include -// #include // TODO: How to replace this?? #include #include @@ -34,70 +33,63 @@ #include "convmixspatialparams.hh" -namespace Dumux -{ +namespace Dumux { + template class ConvectiveMixingProblem; -namespace Properties -{ -NEW_TYPE_TAG(ConvectiveMixingProblem, INHERITS_FROM(BoxModel, ConvMixSpatialParams)); +namespace Properties { + +NEW_TYPE_TAG(ConvectiveMixingProblemTypeTag, INHERITS_FROM(BoxModel, ConvMixSpatialParamsTypeTag)); // Set the grid type -SET_TYPE_PROP(ConvectiveMixingProblem, Grid, Dune::YaspGrid<2>); +SET_TYPE_PROP(ConvectiveMixingProblemTypeTag, Grid, Dune::YaspGrid<2>); // Set the problem property -SET_TYPE_PROP(ConvectiveMixingProblem, Problem, ConvectiveMixingProblem); +SET_TYPE_PROP(ConvectiveMixingProblemTypeTag, Problem, ConvectiveMixingProblemTypeTag); // Set fluid configuration -SET_TYPE_PROP(ConvectiveMixingProblem, FluidSystem, BrineCO2); +SET_TYPE_PROP(ConvectiveMixingProblemTypeTag, FluidSystem, BrineCO2); //! The constant tau function is used for the effective diffusivity -SET_PROP(ConvectiveMixingProblem, EffectiveDiffusivityModel) +SET_PROP(ConvectiveMixingProblemTypeTag, EffectiveDiffusivityModel) { private: - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); public: - typedef DiffusivityConstantTortuosity type; + using type = DiffusivityConstantTortuosity; }; // Set the CO2 table to be used; in this case not the the default table -SET_TYPE_PROP(ConvectiveMixingProblem, CO2Table, CO2TablesBenchmarkThree::CO2Tables); +SET_TYPE_PROP(ConvectiveMixingProblemTypeTag, CO2Table, CO2TablesBenchmarkThree::CO2Tables); //Define whether mole(true) or mass (false) fractions are used -SET_BOOL_PROP(ConvectiveMixingProblem, UseMoles, false); +SET_BOOL_PROP(ConvectiveMixingProblemTypeTag, UseMoles, false); -} +} // end namespace Properties template class ConvectiveMixingProblem : public PorousMediumFlowProblem { using ParentType = PorousMediumFlowProblem; - using GridView = typename GET_PROP_TYPE(TypeTag, GridView); using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables); using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); - // copy some indices for convenience using ModelTraits = typename GET_PROP_TYPE(TypeTag, ModelTraits); using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; - // Grid and world dimension static constexpr int dim = GridView::dimension; static constexpr int dimWorld = GridView::dimensionworld; - // indices of the primary variables static constexpr int pressureIdx = Indices::pressureIdx; // index for the pressure primary variable static constexpr int massFracIdx = Indices::massOrMoleFracIdx; // index for the CO2 massfraction primary variable - // indices of the equations static constexpr int conti0EqIdx = Indices::conti0EqIdx; // index for the continuity equation static constexpr int transportEqIdx = Indices::transportEqIdx; // index for the transport equation - - using Element = typename GridView::template Codim<0>::Entity; using ElementIterator = typename GridView::template Codim<0>::Iterator; using Vertex = typename GridView::template Codim::Entity; @@ -105,7 +97,6 @@ class ConvectiveMixingProblem : public PorousMediumFlowProblem using FVGridGeometry = typename GET_PROP_TYPE(TypeTag,FVGridGeometry); using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - using CO2Table = typename GET_PROP_TYPE(TypeTag, PTAG(CO2Table)); using CO2 = Dumux::CO2; using Brine_CO2 = Dumux::BinaryCoeff::Brine_CO2; @@ -132,7 +123,9 @@ public: * This is used as a prefix for files generated by the simulation. */ const std::string name() const - { return name_; } + { + return name_; + } /*! * \brief Returns the temperature within the domain. @@ -164,12 +157,12 @@ public: values.setAllNeumann(); - if(globalPos[1] > this->bBoxMax()[1] - eps_) + if (globalPos[1] > this->bBoxMax()[1] - eps_) { values.setDirichlet(massFracIdx, transportEqIdx); // set top boundary to Dirichlet for transport equation } - if(globalPos[1] < eps_) + if (globalPos[1] < eps_) { values.setAllDirichlet(); // set bottom boundary to Dirichlet for continuity and transport equation } @@ -182,13 +175,15 @@ public: * boundary segment. * * For this method, the \a values parameter stores primary variables. - */ + */ //! return Neumann conditions (flux, [kg/(m^2 s)]) PrimaryVariables dirichlet( const Vertex &vertex) const { PrimaryVariables values; const GlobalPosition& globalPos = vertex.geometry().center(); initial_(values, globalPos); + + return values; } /*! @@ -201,10 +196,10 @@ public: */ using ParentType::neumann; PrimaryVariables neumann(const Element &element, - const FVElementGeometry &fvElemGeom, - const Intersection &is, - int scvIdx, - int boundaryFaceIdx) const + const FVElementGeometry &fvElemGeom, + const Intersection &is, + int scvIdx, + int boundaryFaceIdx) const { return PrimaryVariables(0.0); } @@ -237,20 +232,17 @@ public: * variables. */ PrimaryVariables initial( const Element &element, - const FVElementGeometry &fvElemGeom, - int scvIdx) const + const FVElementGeometry &fvElemGeom, + int scvIdx) const { PrimaryVariables values; const GlobalPosition &globalPos = element.geometry().corner(scvIdx); - return(initial_(globalPos) ); - - + return(initial_(globalPos)); } private: - // the internal method for the initial condition and dirichlet boundary conditions // returns the values for the two primary variables pressure and CO2 massfraction PrimaryVariables initial_(const GlobalPosition &globalPos) const @@ -276,10 +268,11 @@ private: const Scalar avgMolarMass = moleFracCO2 * M2 + (1-moleFracCO2) * M1; const Scalar massFracCO2 = moleFracCO2 * FluidSystem::molarMass(1)/avgMolarMass; - if(globalPos[1] > this->bBoxMax()[1] - eps_) + if (globalPos[1] > this->bBoxMax()[1] - eps_) { values[massFracIdx] = massFracCO2; // CO2 massfraction at top boundary [-] } + return values; } @@ -287,6 +280,9 @@ private: Scalar episodeLength_; Scalar depthBOR_; // bottom of reservoir [m] std::string name_ ; -}; //end namespace -} -#endif + +}; + +} // end namespace Dumux + +#endif // DUMUX_CONVECTIVE_MIXING_PROBLEM_HH diff --git a/lecture/mm/convectivemixing/convmixspatialparams.hh b/lecture/mm/convectivemixing/convmixspatialparams.hh index 9c510b3..a64ade3 100644 --- a/lecture/mm/convectivemixing/convmixspatialparams.hh +++ b/lecture/mm/convectivemixing/convmixspatialparams.hh @@ -24,20 +24,22 @@ #include #include -namespace Dumux -{ +namespace Dumux { + //forward declaration template class ConvMixSpatialParams; -namespace Properties -{ +namespace Properties { + // The spatial parameters TypeTag -NEW_TYPE_TAG(ConvMixSpatialParams); +NEW_TYPE_TAG(ConvMixSpatialParamsTypeTag); // Set the spatial parameters -SET_TYPE_PROP(ConvMixSpatialParams, SpatialParams, Dumux::ConvMixSpatialParams); -} +SET_TYPE_PROP(ConvMixSpatialParamsTypeTag, SpatialParams, Dumux::ConvMixSpatialParamsTypeTag); + +} // end namespace Properties + /*! * \ingroup OnePTwoCBoxModel * @@ -54,8 +56,8 @@ class ConvMixSpatialParams : public FVSpatialParams::Entity; public: - ConvMixSpatialParams(const GridView &gridView) - : ParentType(gridView) + ConvMixSpatialParams(std::shared_ptr fvGridGeometry) + : ParentType(fvGridGeometry) { // intrinsic permeability [m^2] permeability_ = getParam("SpatialParams.Permeability"); @@ -113,4 +115,4 @@ private: } // end namespace Dumux -#endif +#endif // DUMUX_CONVMIX_SPATIAL_PARAMETERS_HH diff --git a/lecture/mm/fuelcell/fuelcell.cc b/lecture/mm/fuelcell/fuelcell.cc index 54ef144..487b90a 100644 --- a/lecture/mm/fuelcell/fuelcell.cc +++ b/lecture/mm/fuelcell/fuelcell.cc @@ -33,6 +33,7 @@ #include #include +#include #include #include @@ -89,7 +90,7 @@ int main(int argc, char** argv) try using namespace Dumux; // define the type tag for this problem - using TypeTag = TTAG(FuelCellLectureProblem); + using TypeTag = TTAG(FuelCellLectureProblemTypeTag); // initialize MPI, finalize is done automatically on exit const auto& mpiHelper = Dune::MPIHelper::instance(argc, argv); @@ -102,16 +103,15 @@ int main(int argc, char** argv) try 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(); + GridManager gridManager; + gridManager.init(); //////////////////////////////////////////////////////////// // run instationary non-linear problem on this grid //////////////////////////////////////////////////////////// // we compute on the leaf grid view - const auto& leafGridView = GridCreator::grid().leafGridView(); + const auto& leafGridView = gridManager.grid().leafGridView(); // create the finite volume grid geometry using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); diff --git a/lecture/mm/fuelcell/fuelcellproblem.hh b/lecture/mm/fuelcell/fuelcellproblem.hh index fafd731..fdf736b 100644 --- a/lecture/mm/fuelcell/fuelcellproblem.hh +++ b/lecture/mm/fuelcell/fuelcellproblem.hh @@ -24,6 +24,8 @@ #ifndef DUMUX_FUELCELL_LECTURE_PROBLEM_HH #define DUMUX_FUELCELL_LECTURE_PROBLEM_HH +#include + #include #include #include @@ -38,34 +40,35 @@ #include "fuelcellspatialparams.hh" -namespace Dumux -{ +namespace Dumux { template class FuelCellLectureProblem; -namespace Properties -{ +namespace Properties { #if ISOTHERMAL -NEW_TYPE_TAG(FuelCellLectureProblem, INHERITS_FROM(TwoPNC, BoxModel, FuelCellLectureSpatialParams)); +NEW_TYPE_TAG(FuelCellLectureProblemTypeTag, INHERITS_FROM(TwoPNC, BoxModel, FuelCellLectureSpatialParamsTypeTag)); #else -NEW_TYPE_TAG(FuelCellLectureProblem, INHERITS_FROM(TwoPNCNI, BoxModel, FuelCellLectureSpatialParams)); +NEW_TYPE_TAG(FuelCellLectureProblemTypeTag, INHERITS_FROM(TwoPNCNI, BoxModel, FuelCellLectureSpatialParamsTypeTag)); #endif // Set the grid type -SET_TYPE_PROP(FuelCellLectureProblem, Grid, Dune::YaspGrid<2>); +SET_TYPE_PROP(FuelCellLectureProblemTypeTag, Grid, Dune::YaspGrid<2>); // Set the problem property -SET_TYPE_PROP(FuelCellLectureProblem, Problem, FuelCellLectureProblem); +SET_TYPE_PROP(FuelCellLectureProblemTypeTag, Problem, FuelCellLectureProblem); // Set the primary variable combination for the 2pnc model -SET_PROP(FuelCellLectureProblem, Formulation) -{ static constexpr auto value = TwoPFormulation::p1s0; }; +SET_PROP(FuelCellLectureProblemTypeTag, Formulation) +{ + static constexpr auto value = TwoPFormulation::p1s0; +}; // Set fluid configuration -SET_PROP(FuelCellLectureProblem, FluidSystem) -{ private: +SET_PROP(FuelCellLectureProblemTypeTag, FluidSystem) +{ +private: using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); static constexpr bool useComplexRelations = true; public: @@ -73,8 +76,9 @@ SET_PROP(FuelCellLectureProblem, FluidSystem) }; //define which component balance equation gets replaced by total balance {0,1,2,..,numComponents(none)} -SET_INT_PROP(FuelCellLectureProblem, ReplaceCompEqIdx, 3); -} +SET_INT_PROP(FuelCellLectureProblemTypeTag, ReplaceCompEqIdx, 3); + +} // end namespace Properties /*! * \ingroup TwoPNCModel @@ -87,7 +91,6 @@ template class FuelCellLectureProblem : public PorousMediumFlowProblem { using ParentType = PorousMediumFlowProblem; - using GridView = typename GET_PROP_TYPE(TypeTag, GridView); using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); @@ -95,57 +98,40 @@ class FuelCellLectureProblem : public PorousMediumFlowProblem using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables); using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector); - static constexpr int dim = GridView::dimension; static constexpr int dimWorld = GridView::dimensionWorld; static constexpr int numComponents = GET_PROP_TYPE(TypeTag, ModelTraits)::numComponents(); - // copy some indices for convenience - static constexpr int wPhaseIdx = Indices::Phase0Idx; - static constexpr int nPhaseIdx = Indices::Phase1Idx; - - static constexpr int wCompIdx = FluidSystem::Comp0Idx; //major component of the liquid phase - static constexpr int nCompIdx = FluidSystem::Comp1Idx; //major component of the gas phase - - - // enum { + static constexpr int wPhaseIdx = Indices::Phase0Idx; + static constexpr int nPhaseIdx = Indices::Phase1Idx; + static constexpr int wCompIdx = FluidSystem::Comp0Idx; //major component of the liquid phase + static constexpr int nCompIdx = FluidSystem::Comp1Idx; //major component of the gas phase #if !ISOTHERMAL - static constexpr int temperatureIdx = Indices::temperatureIdx; //temperature + static constexpr int temperatureIdx = Indices::temperatureIdx; //temperature #endif - static constexpr int pressureIdx = Indices::pressureIdx; //gas-phase pressure - static constexpr int switchIdx = Indices::switchIdx; //liquid saturation or mole fraction - // }; - - // enum { + static constexpr int pressureIdx = Indices::pressureIdx; //gas-phase pressure + static constexpr int switchIdx = Indices::switchIdx; //liquid saturation or mole fraction #if !ISOTHERMAL - static constexpr int energyEqIdx = Indices::energyEqIdx; //energy equation + static constexpr int energyEqIdx = Indices::energyEqIdx; //energy equation #endif - static constexpr int conti0EqIdx = Indices::conti0EqIdx; - // }; - + static constexpr int conti0EqIdx = Indices::conti0EqIdx; using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); - using Element = typename GridView::template Codim<0>::Entity; using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - using Vertex = typename GridView::template Codim::Entity; - // TODO: Why is here no using keyword? Is it correct this way? +// TODO: Why is here no usage of this keyword? Is it correct this way? using Intersection = typename GridView::Intersection; - using FVElementGeometry = typename FVGridGeometry::LocalView; using SubControlVolume = typename FVElementGeometry::SubControlVolume; using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector); - - #if !ISOTHERMAL using ElectroChemistry = typename Dumux::ElectroChemistryNI; #else using ElectroChemistry = typename Dumux::ElectroChemistry; #endif using Constant = Dumux::Constants; - static constexpr bool isBox = FVGridGeometry::discMethod == DiscretizationMethod::box; static constexpr int dofCodim = isBox ? dim : 0; @@ -156,7 +142,7 @@ public: * \param fvGridGeometry Contains the Finite-Volume-Grid-Geometry */ FuelCellLectureProblem(std::shared_ptr fvGridGeometry) - : ParentType(fvGridGeometry) + : ParentType(fvGridGeometry) { nTemperature_ = getParam("Problem.NTemperature"); nPressure_ = getParam("Problem.NPressure"); @@ -173,17 +159,12 @@ public: swInlet_ = getParam("OperationalConditions.LiquidWaterSaturationInlet"); eps_ = 1e-6; - - // initialize the tables of the fluid system - //FluidSystem::init(); FluidSystem::init(/*Tmin=*/temperatureLow_, /*Tmax=*/temperatureHigh_, /*nT=*/nTemperature_, /*pmin=*/pressureLow_, /*pmax=*/pressureHigh_, /*np=*/nPressure_); - - } /*! @@ -197,7 +178,9 @@ public: * This is used as a prefix for files generated by the simulation. */ const std::string name() const - { return name_; } + { + return name_; + } /*! * \brief Returns the temperature within the domain. @@ -205,13 +188,15 @@ public: * This problem assumes a temperature of 10 degrees Celsius. */ Scalar temperature() const - { return temperature_; } + { + return temperature_; + } //! \copydoc Dumux::FVProblem::source() NumEqVector source(const Element &element, - const FVElementGeometry& fvGeometry, - const ElementVolumeVariables& elemVolVars, - const SubControlVolume &scv) const + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars, + const SubControlVolume &scv) const { NumEqVector values; @@ -223,12 +208,12 @@ public: //reaction sources from electro chemistry Scalar reactionLayerWidth = getParam("Problem.ReactionLayerWidth"); - if(globalPos[0] < reactionLayerWidth + eps_) + if (globalPos[0] < reactionLayerWidth + eps_) { // Hack: division by two to get to the (wrongly implemented) current density // of the Acosta paper fuelcell model auto currentDensity = ElectroChemistry::calculateCurrentDensity(volVars)/2; - ElectroChemistry::reactionSource(values, currentDensity); + ElectroChemistry::reactionSource(values, currentDensity, ""); } return values; @@ -253,13 +238,12 @@ public: values.setAllNeumann(); - if((globalPos[1]>=0 && globalPos[1]<=0.0005 && globalPos[0] > 0.0005 - eps_) + if ((globalPos[1]>=0 && globalPos[1]<=0.0005 && globalPos[0] > 0.0005 - eps_) || (globalPos[1]<=0.002 && globalPos[1]>=0.0015 && globalPos[0] > 0.0005 - eps_)) { values.setAllDirichlet(); } - return values; } @@ -274,27 +258,25 @@ public: PrimaryVariables values = initial_(globalPos); //lower inlet - if((globalPos[1] >= 0 && globalPos[1] <= 0.0005 && globalPos[0] > 0.0005 - eps_)) + if ((globalPos[1] >= 0 && globalPos[1] <= 0.0005 && globalPos[0] > 0.0005 - eps_)) { values[pressureIdx] = pgInlet2_; values[switchIdx] = swInlet_; //Acosta Inlet liquid water saturation values[switchIdx+1] = pO2Inlet_/Dumux::BinaryCoeff::H2O_O2::henry(temperature_);; } //upper inlet - if((globalPos[1] <= 0.002 && globalPos[1] >= 0.0015 && globalPos[0] > 0.0005 - eps_)) + if ((globalPos[1] <= 0.002 && globalPos[1] >= 0.0015 && globalPos[0] > 0.0005 - eps_)) { values[pressureIdx] = pgInlet1_; values[switchIdx] = swInlet_; //Acosta Inlet liquid water saturation values[switchIdx+1] = pO2Inlet_/Dumux::BinaryCoeff::H2O_O2::henry(temperature_); } - #if !ISOTHERMAL values[temperatureIdx] = 343.15; #endif return values; } - /*! * \brief Evaluate the boundary conditions for a neumann * boundary segment. @@ -309,7 +291,6 @@ public: NumEqVector neumannAtPos(const GlobalPosition &globalPos) const { PrimaryVariables values(0.0); - #if !ISOTHERMAL if (globalPos[1] >= 0.0005 && globalPos[1] <= 0.0015 && globalPos[0] > 0.0005 - eps_) values[energyEqIdx] = 9800; // [W/m^2]; heat conduction flow thorough the shoulder;from Acosta-paper: lambda_shoulder/delta_shoulder*DeltaT @@ -330,43 +311,10 @@ public: * \param globalPos The global position */ PrimaryVariables initialAtPos(const GlobalPosition &globalPos) const - { return initial_(globalPos); } - - /*! - * \brief Return the initial phase state inside a control volume. - * - * \param vertex The vertex - * \param globalIdx The index of the global vertex - * \param globalPos The global position - */ - - /* - *if bothPhases, set initial values for pg (pressureIdx), Sl (switchIdx), xO2l [mol/m3] (switchIdx+1) - *if nPhaseOnly, set initial values for pg (pressureIdx), xH2Og (switchIdx), xO2g [mol/m3] (switchIdx+1) - *if wPhaseOnly, set initial values for pg (pressureIdx), xN2l (switchIdx), xO2l [mol/m3] (switchIdx+1) - */ - - int initialPhasePresence(const Element& element, - const FVElementGeometry& fvGeometry, - unsigned int scvIdx) const { - return Indices::bothPhases; + return initial_(globalPos); } - /*! - * \brief Returns true if a VTK output file should be written. - */ - /* - bool shouldWriteOutput() const - { - const int freqOutput = getParam("Output.FreqOutput"); - if (this->timeManager().timeStepIndex() % freqOutput == 0 - || this->timeManager().episodeWillBeFinished()) - return true; - return false; - }*/ - - /*! * \brief Adds additional VTK output data to the VTKWriter. Function is called by the output module on every write. */ @@ -380,13 +328,13 @@ public: #if !ISOTHERMAL reactionSourceTemp_.resize(gridView.size(dofCodim)); #endif - vtk.addField(currentDensity_, "currentDensity [A/cm^2]"); vtk.addField(reactionSourceH2O_, "reactionSourceH2O [mol/(sm^2)]"); vtk.addField(reactionSourceO2_, "reactionSourceO2 [mol/(sm^2)]"); #if !ISOTHERMAL vtk.addField(reactionSourceTemp_, "reactionSourceTemp [J/(sm^2)]"); #endif + } void updateVtkFields(const SolutionVector& curSol) @@ -406,22 +354,22 @@ public: const auto dofIdxGlobal = scv.dofIndex(); static Scalar reactionLayerWidth = getParam("Problem.ReactionLayerWidth"); - if(globalPos[0] < reactionLayerWidth + eps_) + if (globalPos[0] < reactionLayerWidth + eps_) { //reactionSource Output PrimaryVariables source; auto i = ElectroChemistry::calculateCurrentDensity(volVars); - ElectroChemistry::reactionSource(source, i); + ElectroChemistry::reactionSource(source, i, ""); reactionSourceH2O_[dofIdxGlobal] = source[Indices::conti0EqIdx + FluidSystem::H2OIdx]; reactionSourceO2_[dofIdxGlobal] = source[Indices::conti0EqIdx + FluidSystem::O2Idx]; #if !ISOTHERMAL reactionSourceTemp_[dofIdxGlobal] = source[numComponents]; #endif - //Current Output in A/cm^2 currentDensity_[dofIdxGlobal] = i/10000; } + else { reactionSourceH2O_[dofIdxGlobal] = 0.0; @@ -436,17 +384,9 @@ public: } private: - PrimaryVariables initial_( const GlobalPosition &globalPos) const { // the internal method for the initial condition - - /* - *if bothPhases, set initial values for pg (pressureIdx), Sl (switchIdx), xO2l [mol/m3] (switchIdx+1) - *if nPhaseOnly, set initial values for pg (pressureIdx), xH2Og (switchIdx), xO2g [mol/m3] (switchIdx+1) - *if wPhaseOnly, set initial values for pg (pressureIdx), xN2l (switchIdx), xO2l [mol/m3] (switchIdx+1) - */ - PrimaryVariables values; values[pressureIdx] = pgInlet1_; @@ -456,8 +396,9 @@ private: #if !ISOTHERMAL values[temperatureIdx] = 343.15; #endif - return values; + values.setState(Indices::bothPhases); + return values; } Scalar temperature_; @@ -483,6 +424,7 @@ private: std::vector reactionSourceTemp_; #endif }; -} //end namespace -#endif +} //end namespace Dumux + +#endif // DUMUX_FUELCELL_LECTURE_PROBLEM_HH diff --git a/lecture/mm/fuelcell/fuelcellspatialparams.hh b/lecture/mm/fuelcell/fuelcellspatialparams.hh index 437b4e4..5a10cb2 100644 --- a/lecture/mm/fuelcell/fuelcellspatialparams.hh +++ b/lecture/mm/fuelcell/fuelcellspatialparams.hh @@ -26,37 +26,35 @@ #ifndef DUMUX_FUELCELL_LECTURE_SPATIAL_PARAMS_HH #define DUMUX_FUELCELL_LECTURE_SPATIAL_PARAMS_HH -// #include #include #include #include #include #include -// #include #include "./material/regularizedacosta.hh" #include "./material/thermalconductivityconstant.hh" -namespace Dumux -{ +namespace Dumux { //forward declaration template class FuelCellLectureSpatialParams; -namespace Properties -{ +namespace Properties { + // The spatial parameters TypeTag -NEW_TYPE_TAG(FuelCellLectureSpatialParams); +NEW_TYPE_TAG(FuelCellLectureSpatialParamsTypeTag); // Set the spatial parameters -SET_TYPE_PROP(FuelCellLectureSpatialParams, SpatialParams, FuelCellLectureSpatialParams); +SET_TYPE_PROP(FuelCellLectureSpatialParamsTypeTag, SpatialParams, FuelCellLectureSpatialParams); // Set the constant thermal conductivity law as in Acosta paper #if !ISOTHERMAL -SET_TYPE_PROP(FuelCellLectureSpatialParams, ThermalConductivityModel, Dumux::ThermalConductivityConstant); +SET_TYPE_PROP(FuelCellLectureSpatialParamsTypeTag, ThermalConductivityModel, Dumux::ThermalConductivityConstant); #endif -} + +} // end namespace Properties /*! * \ingroup TwoPNCModel @@ -65,29 +63,23 @@ SET_TYPE_PROP(FuelCellLectureSpatialParams, ThermalConductivityModel, Dumux::The * problem which uses the (non-)isothermal 2pnc box model */ template -class FuelCellLectureSpatialParams -: public FVSpatialParams> +class FuelCellLectureSpatialParams: public FVSpatialParams> { using ThisType = FuelCellLectureSpatialParams; using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); using ParentType = FVSpatialParams; - // using Grid = typename GET_PROP_TYPE(TypeTag, Grid); using GridView = typename FVGridGeometry::GridView; using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); - static constexpr int dim=GridView::dimension; static constexpr int dimworld=GridView::dimensionworld; static constexpr int wPhaseIdx = FluidSystem::wPhaseIdx; - using Element = typename GridView::template Codim<0>::Entity; using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - using FVElementGeometry = typename FVGridGeometry::LocalView; using SubControlVolume = typename FVElementGeometry::SubControlVolume; - using EffectiveLaw = RegularizedAcosta; public: @@ -101,13 +93,13 @@ public: * \param gridView The grid view */ FuelCellLectureSpatialParams(std::shared_ptr fvGridGeometry) - : ParentType(fvGridGeometry), K_(0) + : ParentType(fvGridGeometry) + , K_(0) { // intrinsic permeabilities K_ = 5.2e-11; // Acosta absolute permeability diffusion layer // porosities - porosity_ = 0.78; // Acosta porosity diffusion layer //thermalconductivity @@ -117,14 +109,6 @@ public: materialParams_.setSwr(0.05); //value for imbibition from Acosta materialParams_.setSnr(0.05); //assumption - // parameters for the Brooks-Corey law - //materialParams_.setPe(1.02e4); - //materialParams_.setLambda(1.59); - - //parameters for the vanGenuchten law - //materialParams_.setVgAlpha(6.66e-5); //alpha=1/pcb - //materialParams_.setVgn(3.652); - //parameters for the Acosta saturation capillary pressure relation materialParams_.setAcA(-1168.75); //imbition -1168.75; drainage -600; materialParams_.setAcB(8.5); //imbition 8.5; drainage 25; @@ -142,7 +126,9 @@ public: * \param globalPos The global position */ PermeabilityType permeabilityAtPos(const GlobalPosition& globalPos) const - { return K_; } + { + return K_; + } /*! * \brief Define the porosity \f$[-]\f$ of the spatial parameters @@ -155,11 +141,22 @@ public: if (globalPos[0] < reactionLayerWidth + eps_) return 0.07; + else return porosity_; - } + /*! + * \brief Function for defining which phase is to be considered as the wetting phase. + * + * \return the wetting phase index + * \param globalPos The global position + */ + template + int wettingPhaseAtPos(const GlobalPosition& globalPos) const + { + return FluidSystem::phase0Idx; + } /*! * \brief return the parameter object for the Brooks-Corey material law which depends on the position @@ -167,7 +164,9 @@ public: * \param globalPos The global position */ const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const - { return materialParams_; } + { + return materialParams_; + } /*! * \brief Returns the heat capacity \f$[J / (kg K)]\f$ of the rock matrix. @@ -222,11 +221,11 @@ public: private: Scalar K_; Scalar porosity_; - Scalar eps_; + Scalar eps_ = 1e-6; MaterialLawParams materialParams_; Scalar lambdaSolid_; }; -} +} // end namespace Dumux -#endif +#endif // DUMUX_FUELCELL_LECTURE_SPATIAL_PARAMS_HH diff --git a/lecture/mm/heavyoil/3p/parkervangenuchtenzero.hh b/lecture/mm/heavyoil/3p/parkervangenuchtenzero.hh index 4bca135..fa83194 100644 --- a/lecture/mm/heavyoil/3p/parkervangenuchtenzero.hh +++ b/lecture/mm/heavyoil/3p/parkervangenuchtenzero.hh @@ -29,8 +29,8 @@ #include "parkervangenuchtenzeroparams.hh" -namespace Dumux -{ +namespace Dumux { + /*! * \ingroup material * @@ -44,7 +44,6 @@ namespace Dumux template > class ParkerVanGenZero3P { - public: using Params = ParamsT; using Scalar = typename Params::Scalar; @@ -171,16 +170,14 @@ public: */ static Scalar krw(const Params ¶ms, Scalar saturation, Scalar sn, Scalar sg) { - //transformation to effective saturation - //Scalar se = (saturation - params.swr()) / (1-params.swr()); - Scalar se = (saturation - params.swr()) / (1-params.swr()); - + Scalar se = (saturation - params.swr()) / (1-params.swr()); - - /* regularization */ - if(se > 1.0) return 1.; - if(se < 0.0) return 0.; + // regularization + if (se > 1.0) + return 1.; + if (se < 0.0) + return 0.; Scalar r = 1. - std::pow(1 - std::pow(se, 1/params.vgm()), params.vgm()); return std::sqrt(se)*r*r; @@ -205,14 +202,16 @@ public: */ static Scalar krn(const Params ¶ms, Scalar sw, Scalar saturation, Scalar sg) { - Scalar swe = std::min((sw - params.swr()) / (1 - params.swr()), 1.); Scalar ste = std::min((sw + saturation - params.swr()) / (1 - params.swr()), 1.); // regularization - if(swe <= 0.0) swe = 0.; - if(ste <= 0.0) ste = 0.; - if(ste - swe <= 0.0) return 0.; + if (swe <= 0.0) + swe = 0.; + if (ste <= 0.0) + ste = 0.; + if (ste - swe <= 0.0) + return 0.; Scalar krn_; krn_ = std::pow(1 - std::pow(swe, 1/params.vgm()), params.vgm()); @@ -225,14 +224,13 @@ public: Scalar resIncluded = std::max(std::min((saturation - params.snr()/ (1-params.swr())), 1.), 0.); krn_ *= std::sqrt(resIncluded ); } + else krn_ *= std::sqrt(saturation / (1 - params.swr())); // Hint: (ste - swe) = sn / (1-Srw) - return krn_; }; - /*! * \brief The relative permeability for the non-wetting phase * of the medium implied by van Genuchten's @@ -249,14 +247,16 @@ public: */ static Scalar krg(const Params ¶ms, Scalar sw, Scalar sn, Scalar saturation) { - // se = (sw+sn - Sgr)/(1-Sgr) Scalar se = std::min(((1-saturation) - params.sgr()) / (1 - params.sgr()), 1.); /* regularization */ - if(se > 1.0) return 0.0; - if(se < 0.0) return 1.0; + if(se > 1.0) + return 0.0; + if(se < 0.0) + return 1.0; + Scalar scalFact = 1.; if (saturation<=0.1) { @@ -278,7 +278,6 @@ public: * \param phase indicator, The saturation of all phases. */ static Scalar kr(const Params ¶ms, const int phase, const Scalar sw, const Scalar sn, const Scalar sg) - { switch (phase) { @@ -292,6 +291,7 @@ public: return krg(params, sw, sn, sg); break; } + return 0; }; @@ -303,7 +303,9 @@ public: { return params.rhoBulk() * params.KdNAPL(); } + }; -} -#endif +} // end namespace Dumux + +#endif // DUMUX_PARKERVANGENZERO_3P_HH diff --git a/lecture/mm/heavyoil/3p/parkervangenuchtenzerohysteresis.hh b/lecture/mm/heavyoil/3p/parkervangenuchtenzerohysteresis.hh index b2d9a27..7c3a40b 100644 --- a/lecture/mm/heavyoil/3p/parkervangenuchtenzerohysteresis.hh +++ b/lecture/mm/heavyoil/3p/parkervangenuchtenzerohysteresis.hh @@ -29,8 +29,7 @@ #include "parkervangenuchtenzerohysteresisparams.hh" -namespace Dumux -{ +namespace Dumux { /*! * \ingroup material * @@ -44,10 +43,9 @@ namespace Dumux template > class ParkerVanGenZeroHyst3P { - public: - typedef ParamsT Params; - typedef typename Params::Scalar Scalar; + using Params = ParamsT; + using Scalar = typename Params::Scalar; /*! * \brief The capillary pressure-saturation curve. @@ -117,7 +115,6 @@ public: DUNE_THROW(Dune::NotImplemented, "sw(pc) for three phases not implemented! Do it yourself!"); } - DUNE_DEPRECATED_MSG("use sw() (uncapitalized 's') instead") static Scalar Sw(const Params ¶ms, Scalar pc) { @@ -171,18 +168,17 @@ public: */ static Scalar krw(const Params ¶ms, Scalar saturation, Scalar sn, Scalar sg) { - //transformation to effective saturation - //Scalar se = (saturation - params.swr()) / (1-params.swr()); - Scalar se = (saturation - params.swr()) / (1-params.TrappedSatN()-params.swr()); - + Scalar se = (saturation - params.swr()) / (1-params.TrappedSatN()-params.swr()); - - /* regularization */ - if(se > 1.0) return 1.; - if(se < 0.0) return 0.; + // regularization + if (se > 1.0) + return 1.; + if (se < 0.0) + return 0.; Scalar r = 1. - std::pow(1 - std::pow(se, 1/params.vgm()), params.vgm()); + return std::sqrt(se)*r*r; }; @@ -205,14 +201,16 @@ public: */ static Scalar krn(const Params ¶ms, Scalar sw, Scalar saturation, Scalar sg) { - Scalar swe = std::min((sw - params.swr()) / (1 - params.TrappedSatN()- params.swr()), 1.); Scalar ste = std::min((sw + saturation - params.swr()) / (1 - params.swr()), 1.); // regularization - if(swe <= 0.0) swe = 0.; - if(ste <= 0.0) ste = 0.; - if(ste - swe <= 0.0) return 0.; + if (swe <= 0.0) + swe = 0.; + if (ste <= 0.0) + ste = 0.; + if (ste - swe <= 0.0) + return 0.; Scalar krn_; krn_ = std::pow(1 - std::pow(swe, 1/params.vgm()), params.vgm()); @@ -225,14 +223,13 @@ public: Scalar resIncluded = std::max(std::min((saturation - params.snr()/ (1-params.swr())), 1.), 0.); krn_ *= std::sqrt(resIncluded ); } + else krn_ *= std::sqrt(saturation / (1 - params.swr())); // Hint: (ste - swe) = sn / (1-Srw) - return krn_; }; - /*! * \brief The relative permeability for the non-wetting phase * of the medium implied by van Genuchten's @@ -249,19 +246,22 @@ public: */ static Scalar krg(const Params ¶ms, Scalar sw, Scalar sn, Scalar saturation) { - // se = (sw+sn - Sgr)/(1-Sgr) Scalar se = std::min(((1-saturation) - params.sgr()) / (1 - params.sgr()), 1.); + // regularization + if (se > 1.0) + return 0.0; + if (se < 0.0) + return 1.0; - /* regularization */ - if(se > 1.0) return 0.0; - if(se < 0.0) return 1.0; Scalar scalFact = 1.; + if (saturation<=0.1) { scalFact = (saturation - params.sgr())/(0.1 - params.sgr()); - if (scalFact < 0.) scalFact = 0.; + if (scalFact < 0.) + scalFact = 0.; } Scalar result = scalFact * std::pow(1 - se, 1.0/3.) * std::pow(1 - std::pow(se, 1/params.vgm()), 2*params.vgm()); @@ -278,7 +278,6 @@ public: * \param phase indicator, The saturation of all phases. */ static Scalar kr(const Params ¶ms, const int phase, const Scalar sw, const Scalar sn, const Scalar sg) - { switch (phase) { @@ -292,6 +291,7 @@ public: return krg(params, sw, sn, sg); break; } + return 0; }; @@ -303,7 +303,9 @@ public: { return params.rhoBulk() * params.KdNAPL(); } + }; -} -#endif +} // end namespace Dumux + +#endif // DUMUX_PARKERVANGENZEROHYST_3P_HH diff --git a/lecture/mm/heavyoil/3p/parkervangenuchtenzerohysteresisparams.hh b/lecture/mm/heavyoil/3p/parkervangenuchtenzerohysteresisparams.hh index 5841e6d..744ae92 100644 --- a/lecture/mm/heavyoil/3p/parkervangenuchtenzerohysteresisparams.hh +++ b/lecture/mm/heavyoil/3p/parkervangenuchtenzerohysteresisparams.hh @@ -30,8 +30,7 @@ #include -namespace Dumux -{ +namespace Dumux { /*! * \brief Reference implementation of a van Genuchten params */ @@ -42,10 +41,20 @@ public: using Scalar = ScalarT; ParkerVanGenZeroHyst3PParams() - {betaGw_ = betaNw_ = betaGn_ = 1.;} + { + betaGw_ = betaNw_ = betaGn_ = 1.; + } - ParkerVanGenZeroHyst3PParams(Scalar vgAlpha, Scalar vgn, Scalar KdNAPL, Scalar rhoBulk, Dune::FieldVector residualSaturation, Scalar betaNw = 1., Scalar betaGn = 1., Scalar betaGw = 1., bool regardSnr=false, - Scalar TrappedSatN = 1.) + ParkerVanGenZeroHyst3PParams(Scalar vgAlpha, + Scalar vgn, + Scalar KdNAPL, + Scalar rhoBulk, + Dune::FieldVector residualSaturation, + Scalar betaNw = 1., + Scalar betaGn = 1., + Scalar betaGw = 1., + bool regardSnr=false, + Scalar TrappedSatN = 1.) { setVgAlpha(vgAlpha); setVgn(vgn); @@ -59,40 +68,51 @@ public: setBetaGn(betaGn); setBetaGw(betaGw); setRhoBulk(rhoBulk); - setTrappedSatN(TrappedSatN); }; Scalar TrappedSatN() const - { return TrappedSatN_; } - void setTrappedSatN(Scalar v) - { TrappedSatN_ = v; } + { + return TrappedSatN_; + } + void setTrappedSatN(Scalar v) + { + TrappedSatN_ = v; + } /*! * \brief Return the \f$\alpha\f$ shape parameter of van Genuchten's * curve. */ Scalar vgAlpha() const - { return vgAlpha_; } + { + return vgAlpha_; + } /*! * \brief Set the \f$\alpha\f$ shape parameter of van Genuchten's * curve. */ void setVgAlpha(Scalar v) - { vgAlpha_ = v; } + { + vgAlpha_ = v; + } /*! * \brief Return the \f$m\f$ shape parameter of van Genuchten's * curve. */ Scalar vgm() const - { return vgm_; } + { + return vgm_; + } DUNE_DEPRECATED_MSG("use vgm() (uncapitalized 'm') instead") Scalar vgM() const - { return vgm(); } + { + return vgm(); + } /*! * \brief Set the \f$m\f$ shape parameter of van Genuchten's @@ -101,22 +121,30 @@ public: * The \f$n\f$ shape parameter is set to \f$n = \frac{1}{1 - m}\f$ */ void setVgm(Scalar m) - { vgm_ = m; vgn_ = 1/(1 - vgm_); } + { + vgm_ = m; vgn_ = 1/(1 - vgm_); + } DUNE_DEPRECATED_MSG("use setVgm() (uncapitalized 'm') instead") void setVgM(Scalar m) - { setVgm(m); } + { + setVgm(m); + } /*! * \brief Return the \f$n\f$ shape parameter of van Genuchten's * curve. */ Scalar vgn() const - { return vgn_; } + { + return vgn_; + } DUNE_DEPRECATED_MSG("use vgn() (uncapitalized 'n') instead") Scalar vgN() const - { return vgn(); } + { + return vgn(); + } /*! * \brief Set the \f$n\f$ shape parameter of van Genuchten's @@ -125,11 +153,15 @@ public: * The \f$n\f$ shape parameter is set to \f$m = 1 - \frac{1}{n}\f$ */ void setVgn(Scalar n) - { vgn_ = n; vgm_ = 1 - 1/vgn_; } + { + vgn_ = n; vgm_ = 1 - 1/vgn_; + } DUNE_DEPRECATED_MSG("use setVgn() (uncapitalized 'n') instead") void setVgN(Scalar n) - { setVgn(n); } + { + setVgn(n); + } /*! * \brief Return the residual saturation. @@ -148,6 +180,7 @@ public: return sgr_; break; } + DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx); } @@ -166,152 +199,213 @@ public: * \brief Return the residual wetting saturation. */ Scalar swr() const - { return swr_; } + { + return swr_; + } DUNE_DEPRECATED_MSG("use swr() (uncapitalized 's') instead") Scalar Swr() const - { return swr(); } + { + return swr(); + } /*! * \brief Set the residual wetting saturation. */ void setSwr(Scalar input) - { swr_ = input; } + { + swr_ = input; + } /*! * \brief Return the residual non-wetting saturation. */ Scalar snr() const - { return snr_; } + { + return snr_; + } DUNE_DEPRECATED_MSG("use snr() (uncapitalized 's') instead") Scalar Snr() const - { return snr(); } + { + return snr(); + } /*! * \brief Set the residual non-wetting saturation. */ void setSnr(Scalar input) - { snr_ = input; } + { + snr_ = input; + } /*! * \brief Return the residual gas saturation. */ Scalar sgr() const - { return sgr_; } + { + return sgr_; + } DUNE_DEPRECATED_MSG("use sgr() (uncapitalized 's') instead") Scalar Sgr() const - { return sgr(); } + { + return sgr(); + } /*! * \brief Set the residual gas saturation. */ void setSgr(Scalar input) - { sgr_ = input; } + { + sgr_ = input; + } Scalar swrx() const - { return swrx_; } + { + return swrx_; + } DUNE_DEPRECATED_MSG("use swrx() (uncapitalized 's') instead") Scalar Swrx() const - { return swrx(); } + { + return swrx(); + } /*! * \brief Set the residual gas saturation. */ void setSwrx(Scalar input) - { swrx_ = input; } + { + swrx_ = input; + } /*! * \brief defines the scaling parameters of capillary pressure between the phases (=1 for Gas-Water) */ void setBetaNw(Scalar input) - { betaNw_ = input; } + { + betaNw_ = input; + } DUNE_DEPRECATED_MSG("use setBetaNw() (uncapitalized 'w') instead") void setBetaNW(Scalar input) - { setBetaNw(input); } + { + setBetaNw(input); + } void setBetaGn(Scalar input) - { betaGn_ = input; } + { + betaGn_ = input; + } DUNE_DEPRECATED_MSG("use setBetaGn() (uncapitalized 'n') instead") void setBetaGN(Scalar input) - { setBetaGn(input); } + { + setBetaGn(input); + } void setBetaGw(Scalar input) - { betaGw_ = input; } + { + betaGw_ = input; + } DUNE_DEPRECATED_MSG("use setBetaGw() (uncapitalized 'w') instead") void setBetaGW(Scalar input) - { setBetaGw(input); } + { + setBetaGw(input); + } /*! * \brief Return the values for the beta scaling parameters of capillary pressure between the phases */ Scalar betaNw() const - { return betaNw_; } + { + return betaNw_; + } DUNE_DEPRECATED_MSG("use betaNw() (uncapitalized 'w') instead") Scalar betaNW() const - { return betaNw(); } + { + return betaNw(); + } Scalar betaGn() const - { return betaGn_; } + { + return betaGn_; + } DUNE_DEPRECATED_MSG("use betaGn() (uncapitalized 'n') instead") Scalar betaGN() const - { return betaGn(); } + { + return betaGn(); + } Scalar betaGw() const - { return betaGw_; } + { + return betaGw_; + } DUNE_DEPRECATED_MSG("use betaGw() (uncapitalized 'w') instead") Scalar betaGW() const - { return betaGw(); } + { + return betaGw(); + } /*! * \brief defines if residual n-phase saturation should be regarded in its relative permeability. */ void setKrRegardsSnr(bool input) - { krRegardsSnr_ = input; } + { + krRegardsSnr_ = input; + } DUNE_DEPRECATED_MSG("use setKrRegardsSnr() (capitalized 'K') instead") void setkrRegardsSnr(bool input) - { setKrRegardsSnr(input); } + { + setKrRegardsSnr(input); + } /*! * \brief Calls if residual n-phase saturation should be regarded in its relative permeability. */ bool krRegardsSnr() const - { return krRegardsSnr_; } + { + return krRegardsSnr_; + } /*! * \brief Return the bulk density of the porous medium */ Scalar rhoBulk() const - { return rhoBulk_; } + { + return rhoBulk_; + } /*! * \brief Set the bulk density of the porous medium */ void setRhoBulk(Scalar input) - { rhoBulk_ = input; } + { + rhoBulk_ = input; + } /*! * \brief Return the adsorption coefficient */ Scalar KdNAPL() const - { return KdNAPL_; } + { + return KdNAPL_; + } /*! * \brief Set the adsorption coefficient */ void setKdNAPL(Scalar input) - { KdNAPL_ = input; } - + { + KdNAPL_ = input; + } private: Scalar vgAlpha_; @@ -329,11 +423,11 @@ private: Scalar betaGn_; Scalar betaGw_; -Scalar TrappedSatN_; - + Scalar TrappedSatN_; bool krRegardsSnr_ ; }; -} // namespace Dumux -#endif +} // end namespace Dumux + +#endif // DUMUX_PARKERVANGENZEROHYST_PARAMS_3P_HH diff --git a/lecture/mm/heavyoil/3p/parkervangenuchtenzeroparams.hh b/lecture/mm/heavyoil/3p/parkervangenuchtenzeroparams.hh index 4ce9645..701006e 100644 --- a/lecture/mm/heavyoil/3p/parkervangenuchtenzeroparams.hh +++ b/lecture/mm/heavyoil/3p/parkervangenuchtenzeroparams.hh @@ -30,8 +30,8 @@ #include -namespace Dumux -{ +namespace Dumux { + /*! * \brief Reference implementation of a van Genuchten params */ @@ -44,8 +44,16 @@ public: ParkerVanGenZero3PParams() {betaGw_ = betaNw_ = betaGn_ = 1.;} - ParkerVanGenZero3PParams(Scalar vgAlpha, Scalar vgn, Scalar KdNAPL, Scalar rhoBulk, Dune::FieldVector residualSaturation, Scalar betaNw = 1., Scalar betaGn = 1., Scalar betaGw = 1., bool regardSnr=false, - Scalar TrappedSatN = 1.) + ParkerVanGenZero3PParams(Scalar vgAlpha, + Scalar vgn, + Scalar KdNAPL, + Scalar rhoBulk, + Dune::FieldVector residualSaturation, + Scalar betaNw = 1., + Scalar betaGn = 1., + Scalar betaGw = 1., + bool regardSnr=false, + Scalar TrappedSatN = 1.) { setVgAlpha(vgAlpha); setVgn(vgn); @@ -64,7 +72,9 @@ public: }; Scalar TrappedSatN() const - { return TrappedSatN_; } + { + return TrappedSatN_; + } void setTrappedSatN(Scalar v) { TrappedSatN_ = v; } @@ -74,25 +84,33 @@ public: * curve. */ Scalar vgAlpha() const - { return vgAlpha_; } + { + return vgAlpha_; + } /*! * \brief Set the \f$\alpha\f$ shape parameter of van Genuchten's * curve. */ void setVgAlpha(Scalar v) - { vgAlpha_ = v; } + { + vgAlpha_ = v; + } /*! * \brief Return the \f$m\f$ shape parameter of van Genuchten's * curve. */ Scalar vgm() const - { return vgm_; } + { + return vgm_; + } DUNE_DEPRECATED_MSG("use vgm() (uncapitalized 'm') instead") Scalar vgM() const - { return vgm(); } + { + return vgm(); + } /*! * \brief Set the \f$m\f$ shape parameter of van Genuchten's @@ -101,22 +119,30 @@ public: * The \f$n\f$ shape parameter is set to \f$n = \frac{1}{1 - m}\f$ */ void setVgm(Scalar m) - { vgm_ = m; vgn_ = 1/(1 - vgm_); } + { + vgm_ = m; vgn_ = 1/(1 - vgm_); + } DUNE_DEPRECATED_MSG("use setVgm() (uncapitalized 'm') instead") void setVgM(Scalar m) - { setVgm(m); } + { + setVgm(m); + } /*! * \brief Return the \f$n\f$ shape parameter of van Genuchten's * curve. */ Scalar vgn() const - { return vgn_; } + { + return vgn_; + } DUNE_DEPRECATED_MSG("use vgn() (uncapitalized 'n') instead") Scalar vgN() const - { return vgn(); } + { + return vgn(); + } /*! * \brief Set the \f$n\f$ shape parameter of van Genuchten's @@ -125,11 +151,15 @@ public: * The \f$n\f$ shape parameter is set to \f$m = 1 - \frac{1}{n}\f$ */ void setVgn(Scalar n) - { vgn_ = n; vgm_ = 1 - 1/vgn_; } + { + vgn_ = n; vgm_ = 1 - 1/vgn_; + } DUNE_DEPRECATED_MSG("use setVgn() (uncapitalized 'n') instead") void setVgN(Scalar n) - { setVgn(n); } + { + setVgn(n); + } /*! * \brief Return the residual saturation. @@ -161,157 +191,216 @@ public: setSgr(residualSaturation[2]); } - /*! * \brief Return the residual wetting saturation. */ Scalar swr() const - { return swr_; } + { + return swr_; + } DUNE_DEPRECATED_MSG("use swr() (uncapitalized 's') instead") Scalar Swr() const - { return swr(); } + { + return swr(); + } /*! * \brief Set the residual wetting saturation. */ void setSwr(Scalar input) - { swr_ = input; } + { + swr_ = input; + } /*! * \brief Return the residual non-wetting saturation. */ Scalar snr() const - { return snr_; } + { + return snr_; + } DUNE_DEPRECATED_MSG("use snr() (uncapitalized 's') instead") Scalar Snr() const - { return snr(); } + { + return snr(); + } /*! * \brief Set the residual non-wetting saturation. */ void setSnr(Scalar input) - { snr_ = input; } + { + snr_ = input; + } /*! * \brief Return the residual gas saturation. */ Scalar sgr() const - { return sgr_; } + { + return sgr_; + } DUNE_DEPRECATED_MSG("use sgr() (uncapitalized 's') instead") Scalar Sgr() const - { return sgr(); } + { + return sgr(); + } /*! * \brief Set the residual gas saturation. */ void setSgr(Scalar input) - { sgr_ = input; } + { + sgr_ = input; + } Scalar swrx() const - { return swrx_; } + { + return swrx_; + } DUNE_DEPRECATED_MSG("use swrx() (uncapitalized 's') instead") Scalar Swrx() const - { return swrx(); } + { + return swrx(); + } /*! * \brief Set the residual gas saturation. */ void setSwrx(Scalar input) - { swrx_ = input; } + { + swrx_ = input; + } /*! * \brief defines the scaling parameters of capillary pressure between the phases (=1 for Gas-Water) */ void setBetaNw(Scalar input) - { betaNw_ = input; } + { + betaNw_ = input; + } DUNE_DEPRECATED_MSG("use setBetaNw() (uncapitalized 'w') instead") void setBetaNW(Scalar input) - { setBetaNw(input); } + { + setBetaNw(input); + } void setBetaGn(Scalar input) - { betaGn_ = input; } + { + betaGn_ = input; + } DUNE_DEPRECATED_MSG("use setBetaGn() (uncapitalized 'n') instead") void setBetaGN(Scalar input) - { setBetaGn(input); } + { + setBetaGn(input); + } void setBetaGw(Scalar input) - { betaGw_ = input; } + { + betaGw_ = input; + } DUNE_DEPRECATED_MSG("use setBetaGw() (uncapitalized 'w') instead") void setBetaGW(Scalar input) - { setBetaGw(input); } + { + setBetaGw(input); + } /*! * \brief Return the values for the beta scaling parameters of capillary pressure between the phases */ Scalar betaNw() const - { return betaNw_; } + { + return betaNw_; + } DUNE_DEPRECATED_MSG("use betaNw() (uncapitalized 'w') instead") Scalar betaNW() const - { return betaNw(); } + { + return betaNw(); + } Scalar betaGn() const - { return betaGn_; } + { + return betaGn_; + } DUNE_DEPRECATED_MSG("use betaGn() (uncapitalized 'n') instead") Scalar betaGN() const - { return betaGn(); } + { + return betaGn(); + } Scalar betaGw() const - { return betaGw_; } + { + return betaGw_; + } DUNE_DEPRECATED_MSG("use betaGw() (uncapitalized 'w') instead") Scalar betaGW() const - { return betaGw(); } + { + return betaGw(); + } /*! * \brief defines if residual n-phase saturation should be regarded in its relative permeability. */ void setKrRegardsSnr(bool input) - { krRegardsSnr_ = input; } + { + krRegardsSnr_ = input; + } DUNE_DEPRECATED_MSG("use setKrRegardsSnr() (capitalized 'K') instead") void setkrRegardsSnr(bool input) - { setKrRegardsSnr(input); } + { + setKrRegardsSnr(input); + } /*! * \brief Calls if residual n-phase saturation should be regarded in its relative permeability. */ bool krRegardsSnr() const - { return krRegardsSnr_; } - + { + return krRegardsSnr_; + } /*! * \brief Return the bulk density of the porous medium */ Scalar rhoBulk() const - { return rhoBulk_; } + { + return rhoBulk_; + } /*! * \brief Set the bulk density of the porous medium */ void setRhoBulk(Scalar input) - { rhoBulk_ = input; } + { + rhoBulk_ = input; + } /*! * \brief Return the adsorption coefficient */ Scalar KdNAPL() const - { return KdNAPL_; } + { + return KdNAPL_; + } /*! * \brief Set the adsorption coefficient */ void setKdNAPL(Scalar input) - { KdNAPL_ = input; } - + { + KdNAPL_ = input; + } private: Scalar vgAlpha_; @@ -329,11 +418,10 @@ private: Scalar betaGn_; Scalar betaGw_; -Scalar TrappedSatN_; - - + Scalar TrappedSatN_; bool krRegardsSnr_ ; }; + } // namespace Dumux -#endif +#endif // DUMUX_PARKERVANGENZERO_PARAMS_3P_HH diff --git a/lecture/mm/heavyoil/3p/relativepermeabilityhysteresis.hh b/lecture/mm/heavyoil/3p/relativepermeabilityhysteresis.hh index 2be5ff0..b2c41b8 100644 --- a/lecture/mm/heavyoil/3p/relativepermeabilityhysteresis.hh +++ b/lecture/mm/heavyoil/3p/relativepermeabilityhysteresis.hh @@ -29,8 +29,8 @@ #include "relativepermeabilityhysteresisparams.hh" -namespace Dumux -{ +namespace Dumux { + /*! * \ingroup material * @@ -44,11 +44,9 @@ namespace Dumux template > class relativPermHyst3P { - public: using Params = ParamsT; using Scalar = typename Params::Scalar; - //typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem; static Scalar pc(const Params ¶ms, Scalar sw) { @@ -196,27 +194,18 @@ public: static Scalar s2Pr_w(const Params ¶ms,Scalar sw, Scalar sn, Scalar sg) { - // redSwrn = reduced two phase Residual Saturation (water and non-wetting) - //Scalar s2Pr_w_ = std::min(params.redSwrn(), params.redSwrg()); - Scalar s2Pr_w_ = ((sn - params.Snc()) * params.redSwrn() + ((sg - params.Sgc()) * params.redSwrg()))/ (1-sw-params.Snc()- params.Sgc()); - return s2Pr_w_; }; static Scalar s2Pr_n(const Params ¶ms,Scalar sw, Scalar sn, Scalar sg) { - // Scalar s2Pr_n_ = std::min(params.redSnrw(), params.redSnrg()); - Scalar s2Pr_n_ = ((sw - params.Swc()) * params.redSnrw() + ((sg - params.Sgc()) * params.redSnrg()))/ (1-sn-params.Swc()- params.Sgc()); return s2Pr_n_; }; static Scalar s2Pr_g(const Params ¶ms,Scalar sw, Scalar sn, Scalar sg) { - // redSwrn = reduced two phase Residual Saturation (water and non-wetting) - //Scalar s2Pr_g_ = std::min(params.redSgrw(),params.redSgrn()); - Scalar s2Pr_g_ = ((sw - params.Swc()) * params.redSgrw() + ((sn - params.Snc()) * params.redSgrn()))/ (1-sg-params.Swc()- params.Snc()); return s2Pr_g_; @@ -243,6 +232,7 @@ public: Scalar s3Pr_g_ = std::min(sg, std::max(params.Sgc(), s2Pr_g_ * (1-params.Bg()*(sn - params.Snc())*(sw-params.Sgc())))); return s3Pr_g_; }; + static Scalar krw(const Params ¶ms, Scalar sw, Scalar sn, Scalar sg) { Scalar C1_w_ = C1_w ( params, sw, sn, sg ); @@ -253,15 +243,11 @@ public: Scalar s3Pr_g_ = s3Pr_g ( params, sw, sn, sg ); Scalar normalSw = ((sw - std::min(sw, params.TrappedSatWx()))/(1-(s3Pr_w_ + s3Pr_n_ + s3Pr_g_))); //eq. 4 - //std::cout<<" TrappedSatWx " << params.TrappedSatWx() << std::endl; - //std::cout<<" TrappedSatNx " << params.TrappedSatNx() << std::endl; - //std::cout<<" LandBetaW " << params.LandBetaW() << std::endl; - //std::cout<<" TrappedSatGx " << params.TrappedSatGx() << std::endl; - Scalar krw_ = kr0_w_ * ((1+C2_w_)*std::pow(normalSw,C1_w_)) / (1+C2_w_*std::pow(normalSw,C1_w_*(1+(1/C2_w_)))); return krw_; }; + static Scalar krn(const Params ¶ms, Scalar sw, Scalar sn, Scalar sg) { Scalar C1_n_ = C1_n ( params, sw, sn, sg ); @@ -271,12 +257,12 @@ public: Scalar s3Pr_n_ = s3Pr_n ( params, sw, sn, sg ); Scalar s3Pr_g_ = s3Pr_g ( params, sw, sn, sg ); - Scalar normalSn = ((sn - std::min(sn, params.TrappedSatNx()))/(1-(s3Pr_w_ + s3Pr_n_ + s3Pr_g_))); //eq. 4 Scalar krn_ = kr0_n_ * ((1+C2_n_)*std::pow(normalSn,C1_n_)) / (1+C2_n_*std::pow(normalSn,C1_n_*(1+(1/C2_n_)))); return krn_; }; + static Scalar krg(const Params ¶ms, Scalar sw, Scalar sn, Scalar sg) { Scalar C1_g_ = C1_g ( params, sw, sn, sg ); @@ -306,6 +292,7 @@ public: return krg(params, sw, sn, sg); break; } + return 0; }; @@ -315,6 +302,7 @@ public: } }; -} -#endif +} // end namespace Dumux + +#endif // DUMUX_RELATIVEPERMHYST3P_HH diff --git a/lecture/mm/heavyoil/3p/relativepermeabilityhysteresisparams.hh b/lecture/mm/heavyoil/3p/relativepermeabilityhysteresisparams.hh index 0f3ac80..feac569 100644 --- a/lecture/mm/heavyoil/3p/relativepermeabilityhysteresisparams.hh +++ b/lecture/mm/heavyoil/3p/relativepermeabilityhysteresisparams.hh @@ -30,8 +30,7 @@ #include -namespace Dumux -{ +namespace Dumux { /*! * \brief Reference implementation of a van Genuchten params */ @@ -42,7 +41,9 @@ public: using Scalar = ScalarT; relativPermHyst3PParams() - {betaGw_ = betaNw_ = betaGn_ = 1.;} + { + betaGw_ = betaNw_ = betaGn_ = 1.; + } relativPermHyst3PParams(Scalar vgAlpha, Scalar vgn, Scalar KdNAPL, Scalar rhoBulk, Dune::FieldVector residualSaturation, Scalar betaNw = 1., Scalar betaGn = 1., Scalar betaGw = 1., bool regardSnr=false, Scalar Bw= 1., Scalar Bn= 1., Scalar Bg= 1.,bool firstTimeStepindex=true, @@ -82,7 +83,6 @@ public: setredSgrw(redSgrw); setredSgrn(redSgrn); - setC1_wn(C1_wn); setC1_wg(C1_wg); setC1_ng(C1_ng); @@ -122,207 +122,369 @@ public: }; Scalar Swc() const - { return Swc_; } + { + return Swc_; + } + void setSwc(Scalar v) - { Swc_ = v; } + { + Swc_ = v; + } Scalar Snc() const - { return Snc_; } + { + return Snc_; + } + void setSnc(Scalar v) - { Snc_ = v; } + { + Snc_ = v; + } Scalar Sgc() const - { return Sgc_; } + { + return Sgc_; + } + void setSgc(Scalar v) - { Sgc_ = v; } + { + Sgc_ = v; + } Scalar TrappedSatWx() const - { return TrappedSatWx_; } + { + return TrappedSatWx_; + } + void setTrappedSatWx(Scalar v) - { TrappedSatWx_ = v; } + { + TrappedSatWx_ = v; + } Scalar TrappedSatNx() const - { return TrappedSatNx_; } + { + return TrappedSatNx_; + } + void setTrappedSatNx(Scalar v) - { TrappedSatNx_ = v; } + { + TrappedSatNx_ = v; + } Scalar TrappedSatGx() const - { return TrappedSatGx_; } - void setTrappedSatGx(Scalar v) - { TrappedSatGx_ = v; } - + { + return TrappedSatGx_; + } + void setTrappedSatGx(Scalar v) + { + TrappedSatGx_ = v; + } Scalar Bw() const - { return Bw_; } + { + return Bw_; + } + void setBw(Scalar v) - { Bw_ = v; } + { + Bw_ = v; + } + Scalar Bn() const - { return Bn_; } + { + return Bn_; + } + void setBn(Scalar v) - { Bn_ = v; } + { + Bn_ = v; + } + Scalar Bg() const - { return Bg_; } + { + return Bg_; + } + void setBg(Scalar v) - { Bg_ = v; } + { + Bg_ = v; + } Scalar redSwrn() const //1 - { return redSwrn_; } + { + return redSwrn_; + } + void setredSwrn(Scalar v) - { redSwrn_ = v; } + { + redSwrn_ = v; + } + Scalar redSwrg() const //2 - { return redSwrg_; } + { + return redSwrg_; + } void setredSwrg(Scalar v) - { redSwrg_ = v; } + { + redSwrg_ = v; + } Scalar redSnrw() const //3 - { return redSnrw_; } + { + return redSnrw_; + } void setredSnrw(Scalar v) - { redSnrw_ = v; } + { + redSnrw_ = v; + } Scalar redSnrg() const //4 - { return redSnrg_; } + { + return redSnrg_; + } void setredSnrg(Scalar v) - { redSnrg_ = v; } + { + redSnrg_ = v; + } Scalar redSgrw() const //5 - { return redSgrw_; } + { + return redSgrw_; + } void setredSgrw(Scalar v) - { redSgrw_ = v; } + { + redSgrw_ = v; + } Scalar redSgrn() const //6 - { return redSgrn_; } + { + return redSgrn_; + } void setredSgrn(Scalar v) - { redSgrn_ = v; } + { + redSgrn_ = v; + } Scalar C1_wn() const //1 - { return C1_wn_; } + { + return C1_wn_; + + } void setC1_wn(Scalar v) - { C1_wn_ = v; } + { + C1_wn_ = v; + } Scalar C1_wg() const //1 - { return C1_wg_; } + { + return C1_wg_; + } void setC1_wg(Scalar v) - { C1_wg_ = v; } + { + C1_wg_ = v; + } Scalar C1_ng() const //1 - { return C1_ng_; } + { + return C1_ng_; + } void setC1_ng(Scalar v) - { C1_ng_ = v; } + { + C1_ng_ = v; + } Scalar C2_wn() const //1 - { return C2_wn_; } + { + return C2_wn_; + } void setC2_wn(Scalar v) - { C2_wn_ = v; } + { + C2_wn_ = v; + } Scalar C2_wg() const //1 - { return C2_wg_; } + { + return C2_wg_; + } void setC2_wg(Scalar v) - { C2_wg_ = v; } + { + C2_wg_ = v; + } Scalar C2_ng() const //1 - { return C2_ng_; } + { + return C2_ng_; + } void setC2_ng(Scalar v) - { C2_ng_ = v; } + { + C2_ng_ = v; + } Scalar kr0_wn() const //1 - { return kr0_wn_; } + { + return kr0_wn_; + } void setkr0_wn(Scalar v) - { kr0_wn_ = v; } + { + kr0_wn_ = v; + } Scalar kr0_wg() const //1 - { return kr0_wg_; } + { + return kr0_wg_; + } void setkr0_wg(Scalar v) - { kr0_wg_ = v; } + { + kr0_wg_ = v; + } Scalar kr0_ng() const //1 - { return kr0_ng_; } + { + return kr0_ng_; + + } void setkr0_ng(Scalar v) - { kr0_ng_ = v; } + { + kr0_ng_ = v; + } Scalar SwMax() const - { return SwMax_; } + { + return SwMax_; + } void setSwMax(Scalar v) - { SwMax_ = v; } + { + SwMax_ = v; + } Scalar SnMax() const - { return SnMax_; } + { + return SnMax_; + } void setSnMax(Scalar v) - { SnMax_ = v; } + { + SnMax_ = v; + } Scalar SgMax() const - { return SgMax_; } + { + return SgMax_; + } void setSgMax(Scalar v) - { SgMax_ = v; } - + { + SgMax_ = v; + } Scalar LandAw() const - { return LandAw_; } + { + return LandAw_; + } void setLandAw(Scalar v) - { LandAw_ = v; } + { + LandAw_ = v; + } Scalar LandDw() const - { return LandDw_; } + { + return LandDw_; + } void setLandDw(Scalar v) - { LandDw_ = v; } + { + LandDw_ = v; + } Scalar LandAn() const - { return LandAn_; } + { + return LandAn_; + } void setLandAn(Scalar v) - { LandAn_ = v; } + { + LandAn_ = v; + } Scalar LandDn() const - { return LandDn_; } + { + return LandDn_; + } void setLandDn(Scalar v) - { LandDn_ = v; } + { + LandDn_ = v; + } Scalar LandAg() const - { return LandAg_; } + { + return LandAg_; + } void setLandAg(Scalar v) - { LandAg_ = v; } + { + LandAg_ = v; + } Scalar LandDg() const - { return LandDg_; } + { + return LandDg_; + } void setLandDg(Scalar v) - { LandDg_ = v; } - + { + LandDg_ = v; + } Scalar LandBetaW() const - { return LandBetaW_; } + { + return LandBetaW_; + } void setLandBetaW(Scalar v) - { LandBetaW_ = v; } + { + LandBetaW_ = v; + } Scalar LandBetaN() const - { return LandBetaN_; } + { + return LandBetaN_; + } void setLandBetaN(Scalar v) - { LandBetaN_ = v; } + { + LandBetaN_ = v; + } Scalar LandBetaG() const - { return LandBetaG_; } + { + return LandBetaG_; + } void setLandBetaG(Scalar v) - { LandBetaG_ = v; } - + { + LandBetaG_ = v; + } /*! * \brief Return the \f$\alpha\f$ shape parameter of van Genuchten's * curve. */ Scalar vgAlpha() const - { return vgAlpha_; } + { + return vgAlpha_; + } /*! * \brief Set the \f$\alpha\f$ shape parameter of van Genuchten's * curve. */ void setVgAlpha(Scalar v) - { vgAlpha_ = v; } + { + vgAlpha_ = v; + } /*! * \brief Return the \f$m\f$ shape parameter of van Genuchten's * curve. */ Scalar vgm() const - { return vgm_; } + { + return vgm_; + } DUNE_DEPRECATED_MSG("use vgm() (uncapitalized 'm') instead") Scalar vgM() const - { return vgm(); } + { + return vgm(); + } /*! * \brief Set the \f$m\f$ shape parameter of van Genuchten's @@ -331,22 +493,30 @@ public: * The \f$n\f$ shape parameter is set to \f$n = \frac{1}{1 - m}\f$ */ void setVgm(Scalar m) - { vgm_ = m; vgn_ = 1/(1 - vgm_); } + { + vgm_ = m; vgn_ = 1/(1 - vgm_); + } DUNE_DEPRECATED_MSG("use setVgm() (uncapitalized 'm') instead") void setVgM(Scalar m) - { setVgm(m); } + { + setVgm(m); + } /*! * \brief Return the \f$n\f$ shape parameter of van Genuchten's * curve. */ Scalar vgn() const - { return vgn_; } + { + return vgn_; + } DUNE_DEPRECATED_MSG("use vgn() (uncapitalized 'n') instead") Scalar vgN() const - { return vgn(); } + { + return vgn(); + } /*! * \brief Set the \f$n\f$ shape parameter of van Genuchten's @@ -355,23 +525,15 @@ public: * The \f$n\f$ shape parameter is set to \f$m = 1 - \frac{1}{n}\f$ */ void setVgn(Scalar n) - { vgn_ = n; vgm_ = 1 - 1/vgn_; } - - DUNE_DEPRECATED_MSG("use setVgn() (uncapitalized 'n') instead") - void setVgN(Scalar n) - { setVgn(n); } - - - /* void setFirstTimeStepindex(bool FirstTimeStepindex) { - FirstTimeStepindex_ = FirstTimeStepindex; + vgn_ = n; vgm_ = 1 - 1/vgn_; } - bool FirstTimeStepindex() const + DUNE_DEPRECATED_MSG("use setVgn() (uncapitalized 'n') instead") + void setVgN(Scalar n) { - return FirstTimeStepindex_; + setVgn(n); } -*/ /*! * \brief Return the residual saturation. @@ -390,6 +552,7 @@ public: return sgr_; break; } + DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx); } @@ -408,162 +571,230 @@ public: * \brief Return the residual wetting saturation. */ Scalar swr() const - { return swr_; } + { + return swr_; + } DUNE_DEPRECATED_MSG("use swr() (uncapitalized 's') instead") Scalar Swr() const - { return swr(); } + { + return swr(); + } /*! * \brief Set the residual wetting saturation. */ void setSwr(Scalar input) - { swr_ = input; } + { + swr_ = input; + } /*! * \brief Return the residual non-wetting saturation. */ Scalar snr() const - { return snr_; } + { + return snr_; + } DUNE_DEPRECATED_MSG("use snr() (uncapitalized 's') instead") Scalar Snr() const - { return snr(); } + { + return snr(); + } /*! * \brief Set the residual non-wetting saturation. */ void setSnr(Scalar input) - { snr_ = input; } + { + snr_ = input; + } /*! * \brief Return the residual gas saturation. */ Scalar sgr() const - { return sgr_; } + { + return sgr_; + } DUNE_DEPRECATED_MSG("use sgr() (uncapitalized 's') instead") Scalar Sgr() const - { return sgr(); } + { + return sgr(); + } /*! * \brief Set the residual gas saturation. */ void setSgr(Scalar input) - { sgr_ = input; } + { + sgr_ = input; + } Scalar swrx() const - { return swrx_; } + { + return swrx_; + } DUNE_DEPRECATED_MSG("use swrx() (uncapitalized 's') instead") Scalar Swrx() const - { return swrx(); } + { + return swrx(); + } /*! * \brief Set the residual gas saturation. */ void setSwrx(Scalar input) - { swrx_ = input; } + { + swrx_ = input; + } /*! * \brief defines the scaling parameters of capillary pressure between the phases (=1 for Gas-Water) */ void setBetaNw(Scalar input) - { betaNw_ = input; } + { + betaNw_ = input; + } DUNE_DEPRECATED_MSG("use setBetaNw() (uncapitalized 'w') instead") void setBetaNW(Scalar input) - { setBetaNw(input); } + { + setBetaNw(input); + } void setBetaGn(Scalar input) - { betaGn_ = input; } + { + betaGn_ = input; + } DUNE_DEPRECATED_MSG("use setBetaGn() (uncapitalized 'n') instead") void setBetaGN(Scalar input) - { setBetaGn(input); } + { + setBetaGn(input); + } void setBetaGw(Scalar input) - { betaGw_ = input; } + { + betaGw_ = input; + } DUNE_DEPRECATED_MSG("use setBetaGw() (uncapitalized 'w') instead") void setBetaGW(Scalar input) - { setBetaGw(input); } + { + setBetaGw(input); + } /*! * \brief Return the values for the beta scaling parameters of capillary pressure between the phases */ Scalar betaNw() const - { return betaNw_; } + { + return betaNw_; + } DUNE_DEPRECATED_MSG("use betaNw() (uncapitalized 'w') instead") Scalar betaNW() const - { return betaNw(); } + { + return betaNw(); + } Scalar betaGn() const - { return betaGn_; } + { + return betaGn_; + } DUNE_DEPRECATED_MSG("use betaGn() (uncapitalized 'n') instead") Scalar betaGN() const - { return betaGn(); } + { + return betaGn(); + } Scalar betaGw() const - { return betaGw_; } + { + return betaGw_; + } DUNE_DEPRECATED_MSG("use betaGw() (uncapitalized 'w') instead") Scalar betaGW() const - { return betaGw(); } + { + return betaGw(); + } /*! * \brief defines if residual n-phase saturation should be regarded in its relative permeability. */ void setKrRegardsSnr(bool input) - { krRegardsSnr_ = input; } + { + krRegardsSnr_ = input; + } DUNE_DEPRECATED_MSG("use setKrRegardsSnr() (capitalized 'K') instead") void setkrRegardsSnr(bool input) - { setKrRegardsSnr(input); } + { + setKrRegardsSnr(input); + } /*! * \brief Calls if residual n-phase saturation should be regarded in its relative permeability. */ bool krRegardsSnr() const - { return krRegardsSnr_; } + { + return krRegardsSnr_; + } //---------------------------------------- void setFirstTimeStepindex(bool input) - { firstTimeStepindex_ = input; } + { + firstTimeStepindex_ = input; + } DUNE_DEPRECATED_MSG("use setFirstTimeStepindex() (capitalized 'F') instead") void setfirstTimeStepindex(bool input) - { setFirstTimeStepindex(input); } + { + setFirstTimeStepindex(input); + } bool firstTimeStepindex() const - { return firstTimeStepindex_; } + { + return firstTimeStepindex_; + } //---------------------------------------- /*! * \brief Return the bulk density of the porous medium */ Scalar rhoBulk() const - { return rhoBulk_; } + { + return rhoBulk_; + } /*! * \brief Set the bulk density of the porous medium */ void setRhoBulk(Scalar input) - { rhoBulk_ = input; } + { + rhoBulk_ = input; + } /*! * \brief Return the adsorption coefficient */ Scalar KdNAPL() const - { return KdNAPL_; } + { + return KdNAPL_; + } /*! * \brief Set the adsorption coefficient */ void setKdNAPL(Scalar input) - { KdNAPL_ = input; } + { + KdNAPL_ = input; + } private: @@ -626,6 +857,7 @@ private: Scalar Sgc_; }; -} // namespace Dumux -#endif +} // end namespace Dumux + +#endif // DUMUX_RELATIVEPERMHYST_PARAMS_3P_HH diff --git a/lecture/mm/heavyoil/sagd/problem.hh b/lecture/mm/heavyoil/sagd/problem.hh index 1836d78..d8dd54a 100644 --- a/lecture/mm/heavyoil/sagd/problem.hh +++ b/lecture/mm/heavyoil/sagd/problem.hh @@ -49,14 +49,16 @@ template class SagdProblem; namespace Properties { + NEW_TYPE_TAG(SagdTypeTag, INHERITS_FROM(ThreePWaterOilNI)); + NEW_TYPE_TAG(ThreePWaterOilSagdBoxTypeTag, INHERITS_FROM(BoxModel, SagdTypeTag)); // Set the grid type SET_TYPE_PROP(SagdTypeTag, Grid, Dune::YaspGrid<2>); // Set the problem property -SET_TYPE_PROP(SagdTypeTag, Problem, Dumux::SagdProblem); +SET_TYPE_PROP(SagdTypeTag, Problem, SagdTypeTag); // Set the spatial parameters SET_TYPE_PROP(SagdTypeTag, SpatialParams, SagdSpatialParams); @@ -77,8 +79,8 @@ SET_PROP(SagdTypeTag, SolidSystem) using InertComponent = Components::Constant<1, Scalar>; using type = SolidSystems::InertSolidPhase; }; -} // end namespace Properties +} // end namespace Properties /*! * \ingroup ThreePWaterOilBoxModel @@ -97,26 +99,19 @@ class SagdProblem : public PorousMediumFlowProblem using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; - enum { - pressureIdx = Indices::pressureIdx, - switch1Idx = Indices::switch1Idx, - switch2Idx = Indices::switch2Idx, - - contiWEqIdx = Indices::conti0EqIdx + FluidSystem::wCompIdx, - contiNEqIdx = Indices::conti0EqIdx + FluidSystem::nCompIdx, - energyEqIdx = Indices::energyEqIdx, - - // phase indices - wPhaseIdx = FluidSystem::wPhaseIdx, - nPhaseIdx = FluidSystem::nPhaseIdx, - - // phase state - wnPhaseOnly = Indices::wnPhaseOnly, - - // world dimension - dimWorld = GridView::dimensionworld - }; - + static constexpr int pressureIdx = Indices::pressureIdx; + static constexpr int switch1Idx = Indices::switch1Idx; + static constexpr int switch2Idx = Indices::switch2Idx; + static constexpr int contiWEqIdx = Indices::conti0EqIdx + FluidSystem::wCompIdx; + static constexpr int contiNEqIdx = Indices::conti0EqIdx + FluidSystem::nCompIdx; + static constexpr int energyEqIdx = Indices::energyEqIdx; + // phase indices + static constexpr int wPhaseIdx = FluidSystem::wPhaseIdx; + static constexpr int nPhaseIdx = FluidSystem::nPhaseIdx; + // phase state + static constexpr int wnPhaseOnly = Indices::wnPhaseOnly; + // world dimension + static constexpr int dimWorld = GridView::dimensionworld; using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector); using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView; @@ -127,7 +122,6 @@ class SagdProblem : public PorousMediumFlowProblem using GlobalPosition = typename SubControlVolumeFace::GlobalPosition; public: - SagdProblem(std::shared_ptr fvGridGeometry) : ParentType(fvGridGeometry), pOut_(4e6) { @@ -208,24 +202,25 @@ public: values[contiWEqIdx] = -0.193;//*0.5; // (55.5 mol*12.5)/3600 mol/s m = 0.193 values[energyEqIdx] = -9132;//*0.5; // J/sec m 9132 } - else if (globalPos[1] > 2.5 - eps_ && globalPos[1] < 3.5 + eps_) // production well - { - const Scalar elemPressW = elemVolVars[scvf.insideScvIdx()].pressure(wPhaseIdx); //Pressures + // production well + else if (globalPos[1] > 2.5 - eps_ && globalPos[1] < 3.5 + eps_) + { + //Pressures + const Scalar elemPressW = elemVolVars[scvf.insideScvIdx()].pressure(wPhaseIdx); const Scalar elemPressN = elemVolVars[scvf.insideScvIdx()].pressure(nPhaseIdx); - - const Scalar densityW = elemVolVars[scvf.insideScvIdx()].fluidState().density(wPhaseIdx); //Densities + //Densities + const Scalar densityW = elemVolVars[scvf.insideScvIdx()].fluidState().density(wPhaseIdx); const Scalar densityN = elemVolVars[scvf.insideScvIdx()].fluidState().density(nPhaseIdx); - - const Scalar elemMobW = elemVolVars[scvf.insideScvIdx()].mobility(wPhaseIdx); //Mobilities + //Mobilities + const Scalar elemMobW = elemVolVars[scvf.insideScvIdx()].mobility(wPhaseIdx); const Scalar elemMobN = elemVolVars[scvf.insideScvIdx()].mobility(nPhaseIdx); - - const Scalar enthW = elemVolVars[scvf.insideScvIdx()].enthalpy(wPhaseIdx); //Enthalpies + //Enthalpies + const Scalar enthW = elemVolVars[scvf.insideScvIdx()].enthalpy(wPhaseIdx); const Scalar enthN = elemVolVars[scvf.insideScvIdx()].enthalpy(nPhaseIdx); const Scalar wellRadius = 0.50 * 0.3048; // 0.50 ft as specified by SPE9 - const Scalar gridHeight_ = 0.5; const Scalar effectiveRadius_ = 0.208 * gridHeight_; //Peaceman's Well Model @@ -243,14 +238,17 @@ public: //with cooling: see Diplomarbeit Stefan Roll, Sept. 2015 Scalar wT = elemVolVars[scvf.insideScvIdx()].temperature(); // well temperature + if ( wT > 495. ) { qE = qW*0.018*enthW + qN*enthN*0.350 + (wT-495.)*5000.; // ~3x injected enthalpy std::cout<< "Cooling now! Extracted enthalpy: " << qE << std::endl; - } else { - qE = qW*0.018*enthW + qN*enthN*0.350; - } + } + else + { + qE = qW*0.018*enthW + qN*enthN*0.350; + } values[contiWEqIdx] = qW; values[contiNEqIdx] = qN; @@ -258,6 +256,7 @@ public: massProducedOil_ = qN; massProducedWater_ = qW; } + return values; } @@ -307,6 +306,7 @@ private: std::ofstream massBalance; }; -} //end namespace -#endif +} //end namespace Dumux + +#endif // DUMUX_SAGDPROBLEM_HH diff --git a/lecture/mm/heavyoil/sagd/sagd.cc b/lecture/mm/heavyoil/sagd/sagd.cc index c969809..63447a3 100644 --- a/lecture/mm/heavyoil/sagd/sagd.cc +++ b/lecture/mm/heavyoil/sagd/sagd.cc @@ -76,7 +76,6 @@ void usage(const char *progName, const std::string &errorMsg) int main(int argc, char** argv) try { - using namespace Dumux; // define the type tag for this problem @@ -154,8 +153,7 @@ int main(int argc, char** argv) try auto linearSolver = std::make_shared(leafGridView, fvGridGeometry->dofMapper()); // the non-linear solver - using NewtonSolver = PriVarSwitchNewtonSolver; + using NewtonSolver = PriVarSwitchNewtonSolver; NewtonSolver nonLinearSolver(assembler, linearSolver); // time loop @@ -198,9 +196,8 @@ int main(int argc, char** argv) try DumuxMessage::print(/*firstCall=*/false); } - return 0; - } + catch (Dumux::ParameterException &e) { std::cerr << std::endl << e << " ---> Abort!" << std::endl; diff --git a/lecture/mm/heavyoil/sagd/spatialparams.hh b/lecture/mm/heavyoil/sagd/spatialparams.hh index 1e17928..4b6657f 100644 --- a/lecture/mm/heavyoil/sagd/spatialparams.hh +++ b/lecture/mm/heavyoil/sagd/spatialparams.hh @@ -38,6 +38,16 @@ namespace Dumux { +namespace Properties { + + // The spatial parameters TypeTag +NEW_TYPE_TAG(SagdSpatialParamsTypeTag); + +// Set the spatial parameters +SET_TYPE_PROP(SagdSpatialParamsTypeTag, SpatialParams, Dumux::SagdSpatialParams); + +} // end namespace Properties + /*! * \ingroup ThreePThreeCNIModel * @@ -53,15 +63,11 @@ class SagdSpatialParams: public FVSpatialParams::Entity; using ElementSolution = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView; using ParentType = FVSpatialParams>; - using EffectiveLaw = RegularizedParkerVanGen3P; public: @@ -78,22 +84,17 @@ public: : ParentType(fvGridGeometry), eps_(1e-6) { layerBottom_ = 35.0; - // intrinsic permeabilities fineK_ = 1e-16; coarseK_ = 4e-14; - // porosities finePorosity_ = 0.10; coarsePorosity_ = 0.1; - - // heat conductivity of granite + // heat conductivity of granite lambdaSolid_ = 2.8; - // specific heat capacities fineHeatCap_ = 850.; coarseHeatCap_ = 850; - // residual saturations fineMaterialParams_.setSwr(0.1); fineMaterialParams_.setSwrx(0.12); //Total liquid Residual Saturation @@ -103,13 +104,11 @@ public: coarseMaterialParams_.setSwrx(0.12); coarseMaterialParams_.setSnr(0.09); coarseMaterialParams_.setSgr(0.01); - // parameters for the 3phase van Genuchten law fineMaterialParams_.setVgn(4.0); coarseMaterialParams_.setVgn(4.0); fineMaterialParams_.setVgAlpha(0.0005); coarseMaterialParams_.setVgAlpha(0.0015); - coarseMaterialParams_.setKrRegardsSnr(false); fineMaterialParams_.setKrRegardsSnr(false); } @@ -127,7 +126,9 @@ public: PermeabilityType permeability(const Element& element, const SubControlVolume& scv, const ElementSolution& elemSol) const - { return permeabilityAtPos(scv.dofPosition());} + { + return permeabilityAtPos(scv.dofPosition()); + } /*! * \brief Returns the intrinsic permeability tensor \f$[m^2]\f$ @@ -138,6 +139,7 @@ public: { if (isFineMaterial_(globalPos)) return fineK_; + return coarseK_; } @@ -150,6 +152,7 @@ public: { if (isFineMaterial_(globalPos)) return finePorosity_; + else return coarsePorosity_; } @@ -180,9 +183,11 @@ public: { if (isFineMaterial_(globalPos)) return fineMaterialParams_; + else return coarseMaterialParams_; } + Scalar solidHeatCapacity(const Element &element, const SubControlVolume& scv, const ElementSolution& elemSol) const @@ -190,15 +195,18 @@ public: // const GlobalPosition &pos = fvGeometry.subContVol[scvIdx].global; if (isFineMaterial_( element.geometry().center() )) return fineHeatCap_; + else return coarseHeatCap_; } + Scalar solidDensity(const Element &element, const SubControlVolume& scv, const ElementSolution& elemSol) const { return 2650; // density of sand [kg/m^3] } + Scalar solidThermalConductivity(const Element &element, const SubControlVolume& scv, const ElementSolution& elemSol) const @@ -210,7 +218,7 @@ private: bool isFineMaterial_(const GlobalPosition &pos) const { return pos[dimWorld-1] > layerBottom_ - eps_; - }; + } Scalar layerBottom_; Scalar lambdaSolid_; @@ -230,6 +238,6 @@ private: Scalar eps_; }; -} // End Namespace Dumux +} // end namespace Dumux #endif diff --git a/lecture/mm/heavyoil/sagdcyclic/problem.hh b/lecture/mm/heavyoil/sagdcyclic/problem.hh index 741cbbb..ff8ab18 100644 --- a/lecture/mm/heavyoil/sagdcyclic/problem.hh +++ b/lecture/mm/heavyoil/sagdcyclic/problem.hh @@ -26,52 +26,39 @@ #ifndef DUMUX_SAGDCYCLICPROBLEM_HH #define DUMUX_SAGDCYCLICPROBLEM_HH -#include - +#include +#include +#include +#include #include -#include +#include #include "spatialparams.hh" #define ISOTHERMAL 0 -namespace Dumux -{ +namespace Dumux { + template class SagdCyclicProblem; -namespace Properties -{ -NEW_TYPE_TAG(SagdCyclicProblem, INHERITS_FROM(ThreePWaterOilNI, SagdCyclicSpatialParams)); +namespace Properties { -NEW_TYPE_TAG(SagdCyclicBoxProblem, INHERITS_FROM(BoxModel, SagdCyclicProblem)); +NEW_TYPE_TAG(SagdCyclicProblemTypeTag, INHERITS_FROM(ThreePWaterOilNI, SagdCyclicSpatialParamsTypeTag)); -NEW_TYPE_TAG(SagdCyclicCCProblem, INHERITS_FROM(CCModel, SagdCyclicProblem)); +NEW_TYPE_TAG(SagdCyclicBoxProblemTypeTag, INHERITS_FROM(BoxModel, SagdCyclicProblemTypeTag)); // Set the grid type -SET_TYPE_PROP(SagdCyclicProblem, Grid, Dune::YaspGrid<2>); +SET_TYPE_PROP(SagdCyclicProblemTypeTag, Grid, Dune::YaspGrid<2>); // Set the problem property -SET_TYPE_PROP(SagdCyclicProblem, Problem, Dumux::SagdCyclicProblem); +SET_TYPE_PROP(SagdCyclicProblemTypeTag, Problem, Dumux::SagdCyclicProblem); // Set the fluid system -SET_TYPE_PROP(SagdCyclicProblem, +SET_TYPE_PROP(SagdCyclicProblemTypeTag, FluidSystem, Dumux::FluidSystems::H2OHeavyOil); -// Enable gravity -SET_BOOL_PROP(SagdCyclicProblem, ProblemEnableGravity, true); - -// Use forward differences instead of central differences -SET_INT_PROP(SagdCyclicProblem, ImplicitNumericDifferenceMethod, +1); - -// Write newton convergence -SET_BOOL_PROP(SagdCyclicProblem, NewtonWriteConvergence, false); - -SET_BOOL_PROP(SagdCyclicProblem, UseSimpleModel, true); - -// Set the maximum time step -//SET_SCALAR_PROP(SagdCyclicProblem, TimeManagerMaxTimeStepvectorSize, 4.); -} +} // end namespace Properties /*! * \ingroup ThreePWaterOilBoxModel @@ -87,8 +74,8 @@ class SagdCyclicProblem : public PorousMediumFlowProblem using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); using GridView = typename GET_PROP_TYPE(TypeTag, GridView); using Grid = typename GridView::Grid; - - using ParentType = ImplicitPorousMediaProblem; + using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); + using ParentType = PorousMediumFlowProblem; // copy some indices for convenience using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; @@ -100,11 +87,11 @@ class SagdCyclicProblem : public PorousMediumFlowProblem static constexpr int energyEqIdx = Indices::energyEqIdx; // phase and component indices - static constexpr int wPhaseIdx = Indices::Phase0Idx; - static constexpr int PhaseIdx = Indices::Phase1Idx; - static constexpr int gPhaseIdx = Indices::Phase2Idx; - static constexpr int wCompIdx = Indices::Comp0Idx; - static constexpr int nCompIdx = Indices::Comp1Idx; + static constexpr int wPhaseIdx = Indices::wPhaseIdx; + static constexpr int nPhaseIdx = Indices::nPhaseIdx; + static constexpr int gPhaseIdx = Indices::gPhaseIdx; + static constexpr int wCompIdx = Indices::wCompIdx; + static constexpr int nCompIdx = Indices::nCompIdx; // Phase State static constexpr int wPhaseOnly = Indices::wPhaseOnly; @@ -112,26 +99,27 @@ class SagdCyclicProblem : public PorousMediumFlowProblem static constexpr int wgPhaseOnly = Indices::wgPhaseOnly; static constexpr int threePhases = Indices::threePhases; - //contiWEqIdx = Indices::contiWEqIdx, - //contiNEqIdx = Indices::contiNEqIdx, + static constexpr int contiWEqIdx = Indices::contiWEqIdx; + static constexpr int contiNEqIdx = Indices::contiNEqIdx; // Grid and world dimension static constexpr int dim = GridView::dimension; static constexpr int dimWorld = GridView::dimensionworld; + + using Element = typename GridView::template Codim<0>::Entity; using GlobalPosition = typename Element::Geometry::GlobalCoordinate; using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); - using Element = typename GridView::template Codim<0>::Entity; - // typename GridView::template Codim::Entity Vertex; - // typedef typename GridView::Intersection Intersection; + using Vertex = typename GridView::template Codim::Entity; + using Intersection = typename GridView::Intersection; - using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); - using FluidSystem 0 typename GET_PROP_TYPE(TypeTag, FluidSystem); - using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables); + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; + using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); + using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView; - enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) }; + static constexpr int isBox = GET_PROP_TYPE(TypeTag, FVGridGeometry)::discMethod == DiscretizationMethod::box; public: /*! @@ -140,7 +128,7 @@ public: * \param timeManager The time manager * \param gridView The grid view */ - SagdCyclicProblem(std::shared_ptr fvGridGeom : ParentType(fvGridGeom) + SagdCyclicProblem(std::shared_ptr fvGridGeometry) : ParentType(fvGridGeometry) { maxDepth_ = 400.0; // [m] FluidSystem::init(); @@ -152,58 +140,14 @@ public: name_ = getParam("Problem.Name"); } -/* bool shouldWriteRestartFile() const - { - return - this->timeLoop().timeStepIndex() == 0 || - this->timeLoop().timeStepIndex() % 10000 == 0 || - this->timeLoop().episodeWillBeFinished() || - this->timeLoop().willBeFinished(); - } -*/ -/* bool shouldWriteOutput() const - { - return - this->timeLoop().timeStepIndex() == 0 || - this->timeLoop().timeStepIndex() % 10000 == 0 || - this->timeLoop().episodeWillBeFinished() || - this->timeLoop().willBeFinished(); - } - -*/ -/* void postTimeStep() - { - Scalar time = this->timeLoop().time(); - Scalar dt = this->timeLoop().timeStepSize(); - - // Calculate storage terms - PrimaryVariables storage; - this->model().globalStorage(storage); - - // Write mass balance information for rank 0 - if (this->gridView().comm().rank() == 0) - { - std::cout<<"Storage: " << storage << " Time: " << time + dt << std::endl; - massBalance.open ("massBalanceCyclic.txt", std::ios::out | std::ios::app ); - massBalance << " Storage " << storage - << " Time " << time+dt - << std::endl; - massBalance.close(); - - } -*/ //mass of Oil Scalar newMassProducedOil_ = massProducedOil_; - //std::cout<<" newMassProducedOil_ : "<< newMassProducedOil_ << " Time: " << time+dt << std::endl; totalMassProducedOil_ += newMassProducedOil_; - //std::cout<<" totalMassProducedOil_ : "<< totalMassProducedOil_ << " Time: " << time+dt << std::endl; //mass of Water Scalar newMassProducedWater_ = massProducedWater_; - //std::cout<<" newMassProducedWater_ : "<< newMassProducedWater_ << " Time: " << time+dt << std::endl; totalMassProducedWater_ += newMassProducedWater_; - //std::cout<<" totalMassProducedWater_ : "<< totalMassProducedWater_ << " Time: " << time+dt << std::endl; const int timeStepIndex = this->timeLoop().timeStepIndex(); if (timeStepIndex == 0 || timeStepIndex % 100 == 0 @@ -211,14 +155,9 @@ public: || this->timeLoop().willBeFinished()) { - //std::cout<<" newMassProducedOil_ : "<< newMassProducedOil_ << " Time: " << time+dt << std::endl; std::cout<<" totalMassProducedOil_ : "<< totalMassProducedOil_ << " Time: " << time+dt << std::endl; - //std::cout<<" newMassProducedWater_ : "<< newMassProducedWater_ << " Time: " << time+dt << std::endl; std::cout<<" totalMassProducedWater_ : "<< totalMassProducedWater_ << " Time: " << time+dt << std::endl; } - - //this->spatialParams().getMaxSaturation(*this); - //this->spatialParams().trappedSat(*this); } void episodeEnd() @@ -249,10 +188,9 @@ public: { return name_; } - void sourceAtPos(PrimaryVariables &values, - const GlobalPosition &globalPos) const + PrimaryVariables sourceAtPos( const GlobalPosition &globalPos) const { - values = 0.0; + return PrimaryVariables(0.0); } // \} @@ -269,9 +207,9 @@ public: * \param values The boundary types for the conservation equations * \param globalPos The position for which the bc type should be evaluated */ - void boundaryTypesAtPos(BoundaryTypes &bcTypes, - const GlobalPosition &globalPos) const + BoundaryTypes boundaryTypesAtPos( const GlobalPosition &globalPos) const { + BoundaryTypes bcTypes; if (globalPos[1] < eps_) // on bottom { bcTypes.setAllNeumann(); @@ -299,9 +237,11 @@ public: * * For this method, the \a values parameter stores primary variables. */ - void dirichletAtPos(PrimaryVariables &values, const GlobalPosition &globalPos) const + PrimaryVariables dirichletAtPos(const GlobalPosition &globalPos) const { + PrimaryVariables values; initial_(values, globalPos); // Everywhere else + return values; } /*! @@ -318,15 +258,15 @@ public: * For this method, the \a values parameter stores the mass flux * in normal direction of each phase. Negative values mean influx. */ - void solDependentNeumann(PrimaryVariables &values, - const Element &element, + PrimaryVariables solDependentNeumann(const Element &element, const FVElementGeometry &fvGeometry, const Intersection &is, const int scvIdx, const int boundaryFaceIdx, const ElementVolumeVariables &elemVolVars) const { - values = 0.0; + PrimaryVariables values(0.0); + int indexEpisode = this->timeLoop().episodeIndex(); GlobalPosition globalPos; @@ -355,36 +295,17 @@ public: else if (globalPos[1] > 2.5 + eps_ && globalPos[1] < 3.5 - eps_) // production well { - //Scalar satWBound = 1.0; - // const Scalar satW = elemVolVars[scvIdx].saturation(wPhaseIdx); // Saturations - // const Scalar satG = elemVolVars[scvIdx].saturation(gPhaseIdx); - // const Scalar satN = elemVolVars[scvIdx].saturation(nPhaseIdx); + const Scalar elemPressW = elemVolVars[scvIdx].pressure(wPhaseIdx); //Pressures - // const Scalar elemPressG = elemVolVars[scvIdx].pressure(gPhaseIdx); + const Scalar elemPressN = elemVolVars[scvIdx].pressure(nPhaseIdx); const Scalar densityW = elemVolVars[scvIdx].fluidState().density(wPhaseIdx); //Densities const Scalar densityN = elemVolVars[scvIdx].fluidState().density(nPhaseIdx); - - // const Scalar moDensityW = elemVolVars[scvIdx].fluidState().molarDensity(wPhaseIdx); //Molar Densities - // const Scalar moDensityG = elemVolVars[scvIdx].fluidState().molarDensity(gPhaseIdx); - // const Scalar moDensityN = elemVolVars[scvIdx].fluidState().molarDensity(nPhaseIdx); - - // const Scalar maDensityW = elemVolVars[scvIdx].fluidState().density(wPhaseIdx); //Molar Densities - // const Scalar maDensityG = elemVolVars[scvIdx].fluidState().density(gPhaseIdx); - // const Scalar maDensityN = elemVolVars[scvIdx].fluidState().density(nPhaseIdx); const Scalar elemMobW = elemVolVars[scvIdx].mobility(wPhaseIdx); //Mobilities // const Scalar elemMobG = elemVolVars[scvIdx].mobility(gPhaseIdx); const Scalar elemMobN = elemVolVars[scvIdx].mobility(nPhaseIdx); - - // const Scalar molFracWinW = elemVolVars[scvIdx].fluidState().moleFraction(wPhaseIdx, wCompIdx); - // const Scalar molFracWinN = elemVolVars[scvIdx].fluidState().moleFraction(nPhaseIdx, wCompIdx); - // const Scalar molFracWinG = elemVolVars[scvIdx].fluidState().moleFraction(gPhaseIdx, wCompIdx); - // const Scalar molFracNinW = elemVolVars[scvIdx].fluidState().moleFraction(wPhaseIdx, nCompIdx); - // const Scalar molFracNinN = elemVolVars[scvIdx].fluidState().moleFraction(nPhaseIdx, nCompIdx); - // const Scalar molFracNinG = elemVolVars[scvIdx].fluidState().moleFraction(gPhaseIdx, nCompIdx); - const Scalar enthW = elemVolVars[scvIdx].enthalpy(wPhaseIdx); //Mobilities // const Scalar enthG = elemVolVars[scvIdx].enthalpy(gPhaseIdx); const Scalar enthN = elemVolVars[scvIdx].enthalpy(nPhaseIdx); @@ -412,11 +333,11 @@ public: { qE = qW*0.018*enthW + qN*enthN*0.350 + (wT-495.)*5000.; // ~3x injected enthalpy std::cout<< "Cooling now! Extracted enthalpy: " << qE << std::endl; - } else { + } + else + { qE = qW*0.018*enthW + qN*enthN*0.350; - } - - + } values[Indices::contiWEqIdx] = qW; values[Indices::contiNEqIdx] = qN; values[Indices::energyEqIdx] = qE; @@ -424,6 +345,8 @@ public: massProducedOil_ = qN; massProducedWater_ = qW; } + + return values; } // \} @@ -442,9 +365,11 @@ public: * For this method, the \a values parameter stores primary * variables. */ - void initialAtPos(PrimaryVariables &values, const GlobalPosition &globalPos) const + PrimaryVarialbes initialAtPos(const GlobalPosition &globalPos) const { + PrimaryVariables values; initial_(values, globalPos); + return values; } /*! @@ -485,12 +410,9 @@ private: Scalar episodeLength_; int indexEpisode_; std::string name_; - // std::string name_; - // std::ifstream inputFile; //Input file stream object - // std::vector hours; std::ofstream massBalance; }; -} //end namespace +} //end namespace Dumux -#endif +#endif // DUMUX_SAGDCYCLICPROBLEM_HH diff --git a/lecture/mm/heavyoil/sagdcyclic/sagd_cyclic.cc b/lecture/mm/heavyoil/sagdcyclic/sagd_cyclic.cc index 75ede1b..6918bbd 100644 --- a/lecture/mm/heavyoil/sagdcyclic/sagd_cyclic.cc +++ b/lecture/mm/heavyoil/sagdcyclic/sagd_cyclic.cc @@ -21,10 +21,33 @@ * * \brief test for the 3p3cni box model */ -#include "config.h" -#include "problem.hh" -#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include + +#include "problem.hh" /*! * \brief Provides an interface for customizing error messages associated with @@ -46,7 +69,6 @@ void usage(const char *progName, const std::string &errorMsg) "\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"; } @@ -57,12 +79,10 @@ void usage(const char *progName, const std::string &errorMsg) //////////////////////// int main(int argc, char** argv) try { - // typedef TTAG(LensOnePTwoCProblem) TypeTag; - // return Dumux::start(argc, argv, usage); using namespace Dumux; // define the type tag for this problem - using TypeTag = TTAG(SagdCyclicBoxProblem); + using TypeTag = TTAG(SagdCyclicBoxProblemTypeTag); // initialize MPI, finalize is done automatically on exit const auto& mpiHelper = Dune::MPIHelper::instance(argc, argv); @@ -75,16 +95,16 @@ int main(int argc, char** argv) try 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(); + GridManager gridManager; + gridManager.init(); //////////////////////////////////////////////////////////// // run instationary non-linear problem on this grid //////////////////////////////////////////////////////////// // we compute on the leaf grid view - const auto& leafGridView = GridCreator::grid().leafGridView(); + const auto& leafGridView = gridManager.grid().leafGridView(); + // create the finite volume grid geometry using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); @@ -179,8 +199,6 @@ int main(int argc, char** argv) try DumuxMessage::print(/*firstCall=*/false); } - - } catch (Dumux::ParameterException &e) diff --git a/lecture/mm/heavyoil/sagdcyclic/spatialparams.hh b/lecture/mm/heavyoil/sagdcyclic/spatialparams.hh index 3466aeb..09412c1 100644 --- a/lecture/mm/heavyoil/sagdcyclic/spatialparams.hh +++ b/lecture/mm/heavyoil/sagdcyclic/spatialparams.hh @@ -25,36 +25,29 @@ #ifndef DUMUX_SAGDCYCLIC_SPATIAL_PARAMS_HH #define DUMUX_SAGDCYCLIC_SPATIAL_PARAMS_HH -#include +#include +#include #include +#include #include "../3p/parkervangenuchtenzero.hh" #include "../3p/parkervangenuchtenzeroparams.hh" -namespace Dumux -{ +namespace Dumux { //forward declaration template class SagdCyclicSpatialParams; -namespace Properties -{ +namespace Properties { + // The spatial parameters TypeTag -NEW_TYPE_TAG(SagdCyclicSpatialParams); +NEW_TYPE_TAG(SagdCyclicSpatialParamsTypeTag); // Set the spatial parameters -SET_TYPE_PROP(SagdCyclicSpatialParams, SpatialParams, Dumux::SagdCyclicSpatialParams); +SET_TYPE_PROP(SagdCyclicSpatialParamsTypeTag, SpatialParams, Dumux::SagdCyclicSpatialParams); -// Set the material Law -SET_PROP(SagdCyclicSpatialParams, MaterialLaw) -{ -private: - using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); -public: - using type = ParkerVanGenZero3P; -}; -} +} // end namespace Properties /*! * \ingroup ThreePThreeCNIModel @@ -62,7 +55,9 @@ public: * \brief Definition of the spatial parameters for the SAGD problem */ template -class SagdCyclicSpatialParams : public FVSpatialParams > +class SagdCyclicSpatialParams : public FVSpatialParams > { using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); @@ -71,43 +66,31 @@ class SagdCyclicSpatialParams : public FVSpatialParams::Entity; using GlobalPosition = typename Element::Geometry::GlobalCoordiante; - using DimVetor = Dune::FieldVector; - - + using DimVector = Dune::FieldVector; using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector); - using FluxVariables = typename GET_PROP_TYPE(TypeTag, FluxVariables); - using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables); - - using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); - - - + using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView; + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; using ElementIterator = typename GridView::template Codim<0>::Iterator; using VertexIterator = typename GridView::template Codim::Iterator; using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables); - - enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) }; - enum { dofCodim = isBox ? dim : 0 }; - + static constexpr auto isBox = FVGridGeometry::discMethod == DiscretizationMethod::box; + static constexpr auto dofCodim = isBox ? dim : 0; public: - using MaterialLaw = typename SpatialParams::MaterialLaw; + using EffectiveLaw = ParkerVanGenZero3P; + using MaterialLaw = EffToAbsLaw; using MaterialLawParams = typename MaterialLaw::Params; /*! @@ -115,7 +98,8 @@ public: * * \param gridView The grid view */ - SagdCyclicSpatialParams(std::shared_ptr fvGridGeometry) : ParentType(fvGridGeometry) + SagdCyclicSpatialParams(std::shared_ptr fvGridGeometry) + : ParentType(fvGridGeometry) { land_ = 5.0; layerBottom_ = 35.0; @@ -153,12 +137,6 @@ public: coarseMaterialParams_.setKrRegardsSnr(false); fineMaterialParams_.setKrRegardsSnr(false); - - /* // parameters for adsorption - coarseMaterialParams_.setKdNAPL(0.); - coarseMaterialParams_.setRhoBulk(0); - fineMaterialParams_.setKdNAPL(0.); - fineMaterialParams_.setRhoBulk(0); */ } /*! @@ -176,6 +154,7 @@ public: const GlobalPosition &pos = fvElemGeom.subContVol[scvIdx].global; if (isFineMaterial_(pos)) return fineK_; + return coarseK_; } @@ -194,11 +173,11 @@ public: const GlobalPosition &pos = fvGeometry.subContVol[scvIdx].global; if (isFineMaterial_(pos)) return finePorosity_; + else return coarsePorosity_; } - /*! * \brief return the parameter object for the Brooks-Corey material law which depends on the position * @@ -213,6 +192,7 @@ public: const GlobalPosition &pos = fvGeometry.subContVol[scvIdx].global; if (isFineMaterial_(pos)) return fineMaterialParams_; + else return coarseMaterialParams_; } @@ -233,6 +213,7 @@ public: const GlobalPosition &pos = fvGeometry.subContVol[scvIdx].global; if (isFineMaterial_(pos)) return fineHeatCap_; + else return coarseHeatCap_; } @@ -283,8 +264,7 @@ public: void getMaxSaturation(Problem &problem) { - - using ScalarField = typedef Dune::BlockVector >; + using ScalarField = typename Dune::BlockVector >; // get the number of degrees of freedom FVElementGeometry fvGeometry; @@ -380,6 +360,6 @@ private: static constexpr Scalar eps_ = 1.5e-7; }; -} // end namespace dumux +} // end namespace Dumux #endif diff --git a/lecture/mm/heavyoil/sagdcyclichyst/problem.hh b/lecture/mm/heavyoil/sagdcyclichyst/problem.hh index e3611a5..c8de471 100644 --- a/lecture/mm/heavyoil/sagdcyclichyst/problem.hh +++ b/lecture/mm/heavyoil/sagdcyclichyst/problem.hh @@ -26,51 +26,53 @@ #define DUMUX_SAGDCYCLICHYSTPROBLEM_HH #include - -#include - +#include +#include +#include #include -#include +#include #include "spatialparams.hh" #define ISOTHERMAL 0 -namespace Dumux -{ +namespace Dumux { + template class SagdCyclicHystProblem; -namespace Properties -{ -NEW_TYPE_TAG(SagdCyclicHystProblem, INHERITS_FROM(ThreePWaterOilNI, SagdCyclicHystSpatialParams)); -NEW_TYPE_TAG(SagdCyclicHystBoxProblem, INHERITS_FROM(BoxModel, SagdCyclicHystProblem)); -NEW_TYPE_TAG(SagdCyclicHystCCProblem, INHERITS_FROM(CCModel, SagdCyclicHystProblem)); +namespace Properties { + +NEW_TYPE_TAG(SagdCyclicHystProblemTypeTag, INHERITS_FROM(ThreePWaterOilNI, SagdCyclicHystSpatialParamsTypeTag)); + +NEW_TYPE_TAG(SagdCyclicHystBoxProblem, INHERITS_FROM(BoxModel, SagdCyclicHystProblemTypeTag)); + +NEW_TYPE_TAG(SagdCyclicHystCCProblem, INHERITS_FROM(CCModel, SagdCyclicHystProblemTypeTag)); // Set the grid type -SET_TYPE_PROP(SagdCyclicHystProblem, Grid, Dune::YaspGrid<2>); +SET_TYPE_PROP(SagdCyclicHystProblemTypeTag, Grid, Dune::YaspGrid<2>); // Set the problem property -SET_TYPE_PROP(SagdCyclicHystProblem, Problem, Dumux::SagdCyclicHystProblem); +SET_TYPE_PROP(SagdCyclicHystProblemTypeTag, Problem, Dumux::SagdCyclicHystProblem); // Set the fluid system -SET_TYPE_PROP(SagdCyclicHystProblem, +SET_TYPE_PROP(SagdCyclicHystProblemTypeTag, FluidSystem, Dumux::FluidSystems::H2OHeavyOil); // Enable gravity -SET_BOOL_PROP(SagdCyclicHystProblem, ProblemEnableGravity, true); +SET_BOOL_PROP(SagdCyclicHystProblemTypeTag, ProblemEnableGravity, true); // Use forward differences instead of central differences -SET_INT_PROP(SagdCyclicHystProblem, ImplicitNumericDifferenceMethod, +1); +SET_INT_PROP(SagdCyclicHystProblemTypeTag, ImplicitNumericDifferenceMethod, +1); // Write newton convergence -SET_BOOL_PROP(SagdCyclicHystProblem, NewtonWriteConvergence, false); +SET_BOOL_PROP(SagdCyclicHystProblemTypeTag, NewtonWriteConvergence, false); -SET_BOOL_PROP(SagdCyclicHystProblem, UseSimpleModel, true); +SET_BOOL_PROP(SagdCyclicHystProblemTypeTag, UseSimpleModel, true); -SET_BOOL_PROP(SagdCyclicHystProblem, UseMoles, true); -} +SET_BOOL_PROP(SagdCyclicHystProblemTypeTag, UseMoles, true); +} // end namespace Properties /*! * \ingroup ThreePWaterOilBoxModel @@ -86,63 +88,45 @@ class SagdCyclicHystProblem : public PorousMediumFlowProblem using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar) using GridView = typename GET_PROP_TYPE(TypeTag, GridView); using Grid = typename GridView::Grid; - - typedef PorousMediumFlowProblem ParentType; - + using ParentType = PorousMediumFlowProblem; // copy some indices for convenience using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; - static constexpr int numPhases = GET_PROP_VALUE(TypeTag, NumPhases); static constexpr int numComponents = GET_PROP_VALUE(TypeTag, NumComponents); - static constexpr int pressureIdx = Indices::pressureIdx; static constexpr int switch1Idx = Indices::switch1Idx; static constexpr int switch2Idx = Indices::switch2Idx; - static constexpr int energyEqIdx = Indices::energyEqIdx; - // phase and component indices static constexpr int wPhaseIdx = Indices::Phase0Idx; static constexpr int nPhaseIdx = Indices::Phase1Idx; static constexpr int gPhaseIdx = Indices::Phase2Idx; static constexpr int wCompIdx = Indices::Comp0Idx; static constexpr int nCompIdx = Indices::Comp1Idx; - // Phase State static constexpr int wPhaseOnly = Indices::wPhaseOnly; static constexpr int wnPhaseOnly = Indices::wnPhaseOnly; static constexpr int wgPhaseOnly = Indices::wgPhaseOnly; static constexpr int threePhases = Indices::threePhases; - - //contiWEqIdx = Indices::contiWEqIdx, - //contiNEqIdx = Indices::contiNEqIdx, // Grid and world dimension static constexpr int dim = GridView::dimension; static constexpr int dimWorld = GridView::dimensionworld; - - using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables); - using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); - using Element = typename GridView::template Codim<0>::Entity; using Vertex = typename GridView::template Codim::Entity; using Intersection = typename GridView::Intersection; - - using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; using FluidSystem = typedef typename GET_PROP_TYPE(TypeTag, FluidSystem); - using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables); - - + using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView; using ElementIterator = typename GridView::template Codim<0>::Iterator; using VertexIterator = typename GridView::template Codim::Iterator; - using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + static constexpr bool isBox = FVGridGeometry::discMethod == DiscretizationMethod::box; + static constexpr int dofCodim = isBox ? dim : 0; + static const bool useMoles = GET_PROP_VALUE(TypeTag, UseMoles); - enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) }; - enum { dofCodim = isBox ? dim : 0 }; - static const bool useMoles = GET_PROP_VALUE(TypeTag, UseMoles); public: /*! * \brief The constructor @@ -153,7 +137,7 @@ public: SagdCyclicHystProblem(Tstd::shared_ptr fvGridGeometry) : ParentType(fvGridGeometry), pOut_(4.0e6) { - name_ = GET_RUNTIME_PARAM(TypeTag, std::string, Problem.Name); + name_ = getParam("Problem.Name"); maxDepth_ = 400.0; // [m] FluidSystem::init(); totalMassProducedOil_ =0; @@ -161,10 +145,10 @@ public: this->timeLoop().startNextEpisode(3600*12.); - //stateing in the console whether mole or mass fractions are used - if(!useMoles) + if (!useMoles) std::cout<<"Problem uses mass-fractions."<model().globalStorage(storage); + // Write mass balance information for rank 0 if (this->gridView().comm().rank() == 0) { @@ -229,18 +214,17 @@ public: std::cout<<" totalMassProducedOil_ : "<< totalMassProducedOil_ << " Time: " << time+dt << std::endl; std::cout<<" totalMassProducedWater_ : "<< totalMassProducedWater_ << " Time: " << time+dt << std::endl; } - - - } void episodeEnd() { int indexEpisode = this->timeLoop().episodeIndex(); this->timeLoop().startNextEpisode(3600*12); //episode length sent to 12 hours - std::cout<<"Episode index is set to: "<timeLoop().episodeIndex(); - GlobalPosition globalPos; if (isBox) globalPos = element.geometry().corner(scvIdx); + else globalPos = is.geometry().center(); - if (globalPos[1] > 8.5 + eps_ && globalPos[1] < 9.5 - eps_ ) { + if (indexEpisode % 2 == 0) // if episodeIndex is even >> noInjection Phase { values[Indices::contiNEqIdx] = 0.0; values[Indices::contiWEqIdx] = 0.0; values[Indices::energyEqIdx] = 0.0; } + else {// if episodeIndex is odd >> Injection Phase values[Indices::contiNEqIdx] = -0.0; @@ -355,15 +347,8 @@ public: } } - else if (globalPos[1] > 2.5 + eps_ && globalPos[1] < 3.5 - eps_) // production well { - - //Scalar satWBound = 1.0; - // const Scalar satW = elemVolVars[scvIdx].saturation(wPhaseIdx); // Saturations - // const Scalar satG = elemVolVars[scvIdx].saturation(gPhaseIdx); - // const Scalar satN = elemVolVars[scvIdx].saturation(nPhaseIdx); - const Scalar elemPressW = elemVolVars[scvIdx].pressure(wPhaseIdx); //Pressures // const Scalar elemPressG = elemVolVars[scvIdx].pressure(gPhaseIdx); const Scalar elemPressN = elemVolVars[scvIdx].pressure(nPhaseIdx); @@ -372,24 +357,10 @@ public: // const Scalar densityG = elemVolVars[scvIdx].fluidState().density(gPhaseIdx); const Scalar densityN = elemVolVars[scvIdx].fluidState().density(nPhaseIdx); - // const Scalar moDensityW = elemVolVars[scvIdx].fluidState().molarDensity(wPhaseIdx); //Molar Densities - // const Scalar moDensityG = elemVolVars[scvIdx].fluidState().molarDensity(gPhaseIdx); - // const Scalar moDensityN = elemVolVars[scvIdx].fluidState().molarDensity(nPhaseIdx); - - // const Scalar maDensityW = elemVolVars[scvIdx].fluidState().density(wPhaseIdx); //Molar Densities - // const Scalar maDensityG = elemVolVars[scvIdx].fluidState().density(gPhaseIdx); - // const Scalar maDensityN = elemVolVars[scvIdx].fluidState().density(nPhaseIdx); const Scalar elemMobW = elemVolVars[scvIdx].mobility(wPhaseIdx); //Mobilities // const Scalar elemMobG = elemVolVars[scvIdx].mobility(gPhaseIdx); const Scalar elemMobN = elemVolVars[scvIdx].mobility(nPhaseIdx); - // const Scalar molFracWinW = elemVolVars[scvIdx].fluidState().moleFraction(wPhaseIdx, wCompIdx); - // const Scalar molFracWinN = elemVolVars[scvIdx].fluidState().moleFraction(nPhaseIdx, wCompIdx); - // const Scalar molFracWinG = elemVolVars[scvIdx].fluidState().moleFraction(gPhaseIdx, wCompIdx); - // const Scalar molFracNinW = elemVolVars[scvIdx].fluidState().moleFraction(wPhaseIdx, nCompIdx); - // const Scalar molFracNinN = elemVolVars[scvIdx].fluidState().moleFraction(nPhaseIdx, nCompIdx); - // const Scalar molFracNinG = elemVolVars[scvIdx].fluidState().moleFraction(gPhaseIdx, nCompIdx); - const Scalar enthW = elemVolVars[scvIdx].enthalpy(wPhaseIdx); //Mobilities // const Scalar enthG = elemVolVars[scvIdx].enthalpy(gPhaseIdx); const Scalar enthN = elemVolVars[scvIdx].enthalpy(nPhaseIdx); @@ -397,7 +368,6 @@ public: const Scalar wellRadius = 0.50 * 0.3048; // 0.50 ft as specified by SPE9 // const Scalar wellArea = M_PI*std::pow(wellRadius,2); // [m^2] - const Scalar gridHeight_ = 0.5; const Scalar effectiveRadius_ = 0.208 * gridHeight_; //Peaceman's Well Model @@ -417,11 +387,12 @@ public: { qE = qW*0.018*enthW + qN*enthN*0.350 + (wT-495.)*5000.; // ~3x injected enthalpy std::cout<< "Cooling now! Extracted enthalpy: " << qE << std::endl; - } else { - qE = qW*0.018*enthW + qN*enthN*0.350; - } - + } + else + { + qE = qW*0.018*enthW + qN*enthN*0.350; + } values[Indices::contiWEqIdx] = qW; values[Indices::contiNEqIdx] = qN; @@ -461,14 +432,11 @@ public: int initialPhasePresenceAtPos(const GlobalPosition &globalPos) const { return wnPhaseOnly; - //return threePhases; } private: - // internal method for the initial condition (reused for the - // dirichlet conditions!) - void initial_(PrimaryVariables &values, - const GlobalPosition &globalPos) const + // internal method for the initial condition (reused for the dirichlet conditions!) + void initial_(PrimaryVariables &values, const GlobalPosition &globalPos) const { Scalar densityW = 1000.0; values[pressureIdx] = 101300. + (maxDepth_ - globalPos[1])*densityW*9.81; @@ -490,13 +458,10 @@ private: // TODO very evil hack mutable Scalar massProducedOil_; mutable Scalar massProducedWater_; - // std::string name_; - //std::ifstream inputFile; //Input file stream object - //std::vector hours; std::ofstream massBalance; - //std::vector maxSats_; + }; -} //end namespace +} //end namespace Dumux -#endif +#endif // DUMUX_SAGDCYCLICHYSTPROBLEM_HH diff --git a/lecture/mm/heavyoil/sagdcyclichyst/sagd_cyclic_hyst.cc b/lecture/mm/heavyoil/sagdcyclichyst/sagd_cyclic_hyst.cc index 1f60ad1..4cccd86 100644 --- a/lecture/mm/heavyoil/sagdcyclichyst/sagd_cyclic_hyst.cc +++ b/lecture/mm/heavyoil/sagdcyclichyst/sagd_cyclic_hyst.cc @@ -21,9 +21,34 @@ * * \brief test for the 3p3cni box model */ -#include "config.h" +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include + +#include +#include + #include "problem.hh" -#include /*! @@ -57,12 +82,10 @@ void usage(const char *progName, const std::string &errorMsg) //////////////////////// int main(int argc, char** argv) try { - // typedef TTAG(LensOnePTwoCProblem) TypeTag; - // return Dumux::start(argc, argv, usage); using namespace Dumux; // define the type tag for this problem - using TypeTag = TTAG(SagdCyclicHystBoxProblem); + using TypeTag = TTAG(SagdCyclicHystBoxProblemTypeTag); // initialize MPI, finalize is done automatically on exit const auto& mpiHelper = Dune::MPIHelper::instance(argc, argv); @@ -75,16 +98,15 @@ int main(int argc, char** argv) try 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(); + GridManager gridManager; + gridManager.init(); //////////////////////////////////////////////////////////// // run instationary non-linear problem on this grid //////////////////////////////////////////////////////////// // we compute on the leaf grid view - const auto& leafGridView = GridCreator::grid().leafGridView(); + const auto& leafGridView = gridManager.grid().leafGridView(); // create the finite volume grid geometry using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); diff --git a/lecture/mm/heavyoil/sagdcyclichyst/spatialparams.hh b/lecture/mm/heavyoil/sagdcyclichyst/spatialparams.hh index 8e748f9..f3d99d8 100644 --- a/lecture/mm/heavyoil/sagdcyclichyst/spatialparams.hh +++ b/lecture/mm/heavyoil/sagdcyclichyst/spatialparams.hh @@ -24,84 +24,70 @@ #ifndef DUMUX_SAGDCYCLICHYST_SPATIAL_PARAMS_HH #define DUMUX_SAGDCYCLICHYST_SPATIAL_PARAMS_HH -#include +#include #include +#include #include "../3p/parkervangenuchtenzerohysteresis.hh" #include "../3p/parkervangenuchtenzerohysteresisparams.hh" -namespace Dumux -{ +namespace Dumux { + //forward declaration template class SagdCyclicHystSpatialParams; -namespace Properties -{ + +namespace Properties { + // The spatial parameters TypeTag -NEW_TYPE_TAG(SagdCyclicHystSpatialParams); +NEW_TYPE_TAG(SagdCyclicHystSpatialParamsTypeTag); + // Set the spatial parameters -SET_TYPE_PROP(SagdCyclicHystSpatialParams, SpatialParams, Dumux::SagdCyclicHystSpatialParams); -// Set the material Law -SET_PROP(SagdCyclicHystSpatialParams, MaterialLaw) -{ - private: - typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; - public: - typedef ParkerVanGenZeroHyst3P type; -}; -} +SET_TYPE_PROP(SagdCyclicHystSpatialParamsTypeTag, SpatialParams, Dumux::SagdCyclicHystSpatialParams); + +} // end namespace Properties + /*! * \ingroup ThreePThreeCNIModel * * \brief Definition of the spatial parameters for the SAGD problem */ template -class SagdCyclicHystSpatialParams : public FVSpatialParams > +class SagdCyclicHystSpatialParams : public FVSpatialParams> { using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - using ParentType = FVSpatialParams > - + using ParentType = FVSpatialParams >; using Problem = typename GET_PROP_TYPE(TypeTag, Problem); using Grid = typename GET_PROP_TYPE(TypeTag, Grid); using GridView = typename GET_PROP_TYPE(TypeTag, GridView); using CoordScalar = typename Grid::ctype; - static constexpr int dim = GridView::dimension; static constexpr int dimWorld=GridView::dimensionworld; - using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; - - static constexpr int numPhases = GET_PROP_VALUE(TypeTag, NumPhases); - static constexpr int numComponents = GET_PROP_VALUE(TypeTag, NumComponents); - + using ModelTraits = typename GET_PROP_TYPE(TypeTag, ModelTraits); + static constexpr int numPhases = ModelTraits::numPhases; + static constexpr int numComponents = ModelTraits::NumComponents; static constexpr int wPhaseIdx = Indices::Phase0Idx; static constexpr int nPhaseIdx = Indices::Phase1Idx; static constexpr int gPhaseIdx = Indices::Phase2Idx; - using Element = typename GridView::template Codim<0>::Entity; using GlobalPosition = typename Element::Geometry::GlobalCoordiante; +// TODO: What is this used for? Is this correct? using DimVetor = Dune::FieldVector; - - - using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector); - using FluxVariables = typename GET_PROP_TYPE(TypeTag, FluxVariables); - using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables); - - using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); - + using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, GridVolumeVariables)::LocalView; + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; using ElementIterator = typename GridView::template Codim<0>::Iterator; using VertexIterator = typename GridView::template Codim::Iterator; using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables); - - enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) }; - enum { dofCodim = isBox ? dim : 0 }; - + static constexpr auto isBox = (FVGridGeometry::discMethod == DiscretizationMethod::box); + static constexpr auto dofCodim = isBox ? dim : 0; public: - using MaterialLaw = typename SpatialParams::MaterialLaw; + using EffectiveLaw = ParkerVanGenZeroHyst3P; + using MaterialLaw = EffToAbsLaw; using MaterialLawParams = typename MaterialLaw::Params; using MaterialLawHystParamsVector = std::vector; @@ -141,7 +127,6 @@ public: coarseMaterialParams_.setVgAlpha(0.0015); coarseMaterialParams_.setKrRegardsSnr(false); fineMaterialParams_.setKrRegardsSnr(false); - } /*! @@ -159,6 +144,7 @@ public: const GlobalPosition &pos = fvElemGeom.subContVol[scvIdx].global; if (isFineMaterial_(pos)) return fineK_; + return coarseK_; } @@ -177,11 +163,11 @@ public: const GlobalPosition &pos = fvGeometry.subContVol[scvIdx].global; if (isFineMaterial_(pos)) return finePorosity_; + else return coarsePorosity_; } - /*! * \brief return the parameter object for the Brooks-Corey material law which depends on the position * @@ -196,10 +182,9 @@ public: const GlobalPosition &pos = fvGeometry.subContVol[scvIdx].global; if (isFineMaterial_(pos)) return fineMaterialParams_; + else return coarseMaterialParams_; - - } /*! @@ -218,6 +203,7 @@ public: const GlobalPosition &pos = fvGeometry.subContVol[scvIdx].global; if (isFineMaterial_(pos)) return fineHeatCap_; + else return coarseHeatCap_; } @@ -361,4 +347,4 @@ private: } // end namespace Dumux -#endif +#endif // DUMUX_SAGDCYCLIC_SPATIAL_PARAMS_HH diff --git a/lecture/mm/henryproblem/henry1p2c/henry1p2c.cc b/lecture/mm/henryproblem/henry1p2c/henry1p2c.cc index 90198da..9a1696d 100644 --- a/lecture/mm/henryproblem/henry1p2c/henry1p2c.cc +++ b/lecture/mm/henryproblem/henry1p2c/henry1p2c.cc @@ -46,8 +46,6 @@ #include #include - - void usage(const char *progName, const std::string &errorMsg) { if (errorMsg.size() > 0) { @@ -79,7 +77,7 @@ int main(int argc, char** argv) try using namespace Dumux; // define the type tag for this problem - using TypeTag = TTAG(Henry1p2cProblem); + using TypeTag = TTAG(Henry1p2cProblemTypeTag); //////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// diff --git a/lecture/mm/henryproblem/henry1p2c/henry1p2cproblem.hh b/lecture/mm/henryproblem/henry1p2c/henry1p2cproblem.hh index 367337c..db29520 100644 --- a/lecture/mm/henryproblem/henry1p2c/henry1p2cproblem.hh +++ b/lecture/mm/henryproblem/henry1p2c/henry1p2cproblem.hh @@ -31,40 +31,35 @@ #include "watersaltfluidsystem.hh" #include "henry1p2cspatialparameters.hh" -namespace Dumux -{ +namespace Dumux { template class Henry1p2cProblem; -namespace Properties -{ -NEW_TYPE_TAG(Henry1p2cProblem, INHERITS_FROM(OnePNC, BoxModel)); +namespace Properties { +NEW_TYPE_TAG(Henry1p2cProblemTypeTag, INHERITS_FROM(OnePNC, BoxModel)); // Set the grid type -SET_TYPE_PROP(Henry1p2cProblem, Grid, Dune::YaspGrid<2>); +SET_TYPE_PROP(Henry1p2cProblemTypeTag, Grid, Dune::YaspGrid<2>); // Set the problem property -SET_TYPE_PROP(Henry1p2cProblem, Problem, Henry1p2cProblem); +SET_TYPE_PROP(Henry1p2cProblemTypeTag, Problem, Henry1p2cProblem); -SET_TYPE_PROP(Henry1p2cProblem, FluidSystem, WaterSaltFluidSystem); +SET_TYPE_PROP(Henry1p2cProblemTypeTag, FluidSystem, WaterSaltFluidSystem); // Set the spatial parameters -SET_TYPE_PROP(Henry1p2cProblem, +SET_TYPE_PROP(Henry1p2cProblemTypeTag, SpatialParams, Henry1p2cSpatialParams); //Define whether mole(true) or mass (false) fractions are used -SET_BOOL_PROP(Henry1p2cProblem, UseMoles, true); - -} +SET_BOOL_PROP(Henry1p2cProblemTypeTag, UseMoles, true); +} // end namespace Properties template class Henry1p2cProblem : public PorousMediumFlowProblem { - - using GridView = typename GET_PROP_TYPE(TypeTag, GridView); using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); @@ -78,37 +73,28 @@ class Henry1p2cProblem : public PorousMediumFlowProblem // copy some indices for convenience using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; using ParentType = PorousMediumFlowProblem; - // Grid and world dimension static constexpr int dim = GridView::dimension; static constexpr int dimWorld = GridView::dimensionworld; - // indices of the equations static constexpr int conti0EqIdx = Indices::conti0EqIdx; static constexpr int transportEqIdx = Indices::transportEqIdx; - using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - using Vertex = typename GridView::template Codim::Entity; using Intersection = typename GridView::Intersection; public: Henry1p2cProblem(std::shared_ptr fvGridGeometry) : ParentType(fvGridGeometry) - { - -// FVElementGeometry fvGeom; -// ElementIterator elemIt = gridView.template begin<0>(); -// const ElementIterator endIt = gridView.template end<0>(); - - freshWaterFluxRate_= getParam("Problem.freshWaterFluxRate"); - } + { + freshWaterFluxRate_= getParam("Problem.freshWaterFluxRate"); + } bool shouldWriteRestartFile() const - { - return false; - } + { + return false; + } /*! * \name Problem parameters @@ -121,7 +107,9 @@ public: * This problem assumes a temperature of 36 degrees Celsius. */ Scalar temperature() const - { return 273.15 + 20; }; // in [K] + { + return 273.15 + 20; // in [K] + }; // \} @@ -140,7 +128,7 @@ public: values.setAllDirichlet(); - if(globalPos[0]1-eps_) + if (globalPos[0]1-eps_) { values.setAllNeumann(); } @@ -159,7 +147,7 @@ public: PrimaryVariables values; initial_(values, globalPos); - if(globalPos[0]>2-eps_ && globalPos[1]<0.8+eps_) + if (globalPos[0]>2-eps_ && globalPos[1]<0.8+eps_) { values[FluidSystem::SaltIdx] = 0.03922; } @@ -179,7 +167,7 @@ public: { PrimaryVariables values(0.0); - if(globalPos[0] #include -namespace Dumux -{ +namespace Dumux { /*! * \ingroup OnePTwoCBoxModel @@ -49,7 +48,6 @@ class Henry1p2cSpatialParams : public FVSpatialParams >; using Grid = typename GET_PROP_TYPE(TypeTag, Grid); using GridView = typename GET_PROP_TYPE(TypeTag, GridView); - using CoordScalar = typename Grid::ctype; using Vector = Dune::FieldVector; using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; @@ -69,16 +67,13 @@ public: perm_ = 1.019368e-9; porosity_ = 0.35; - dispersivity_[0]= getParam("SpatialParams.dispersivityL"); dispersivity_[1]= getParam("SpatialParams.dispersivityT"); - } ~Henry1p2cSpatialParams() {} - /*! * \brief Update the spatial parameters with the flow solution * after a timestep. @@ -87,7 +82,7 @@ public: */ void update(const SolutionVector &globalSolution) { - }; + } /*! * \brief Define the intrinsic permeability \f$\mathrm{[m^2]}\f$. @@ -117,8 +112,8 @@ public: * \param scvIdx The local index of the sub-control volume where */ const Vector dispersivity(const Element &element, - const FVElementGeometry &fvElemGeom, - int scvIdx) const + const FVElementGeometry &fvElemGeom, + int scvIdx) const { return dispersivity_; } @@ -131,8 +126,6 @@ public: } private: - - Scalar perm_; Scalar porosity_; Scalar tortuosityTumor_; @@ -141,6 +134,6 @@ private: Dune::FieldVector dispersivity_; }; -} +} // end namespace Dumux -#endif +#endif // DUMUX_HENRY1P2C_SPATIAL_PARAMETERS_HH diff --git a/lecture/mm/henryproblem/henry1p2c/watersaltfluidsystem.hh b/lecture/mm/henryproblem/henry1p2c/watersaltfluidsystem.hh index c70d81e..e9c2987 100644 --- a/lecture/mm/henryproblem/henry1p2c/watersaltfluidsystem.hh +++ b/lecture/mm/henryproblem/henry1p2c/watersaltfluidsystem.hh @@ -30,19 +30,14 @@ #include - #include #include #include -// #ifdef DUMUX_PROPERTIES_HH -// #include -// #endif -namespace Dumux -{ -namespace FluidSystems -{ +namespace Dumux { + +namespace FluidSystems { /*! * \ingroup Fluidsystems @@ -56,8 +51,7 @@ namespace FluidSystems * used in conjunction the 1p2c model. */ template -class WaterSalt -: public BaseFluidSystem > +class WaterSalt : public BaseFluidSystem > { using ThisType = WaterSalt; using Base = BaseFluidSystem; @@ -81,10 +75,10 @@ public: */ static std::string phaseName(int phaseIdx) { - static const std::string name[] = { + static const std::string name[] = + { std::string("l") }; - assert(0 <= phaseIdx && phaseIdx < numPhases); return name[phaseIdx]; } @@ -144,7 +138,6 @@ public: //! Number of components in the fluid system static constexpr int numComponents = 2; - //! Index of component representing the interstitial fluid static constexpr int WaterIdx = 0; //! Index of component representing TRAIL @@ -161,7 +154,6 @@ public: std::string("Water"), std::string("Salt") }; - assert(0 <= compIdx && compIdx < numComponents); return name[compIdx]; } @@ -195,7 +187,6 @@ public: static void init() {} - using Base::molarDensity; /*! * \brief The molar density \f$\rho_{mol,\alpha}\f$ @@ -230,15 +221,14 @@ public: */ using Base::density; template - static Scalar density(const FluidState &fluidState, - int phaseIdx) + static Scalar density(const FluidState &fluidState, int phaseIdx) { assert(0 <= phaseIdx && phaseIdx < numPhases); Scalar temperature = fluidState.temperature(phaseIdx); Scalar pressure = fluidState.pressure(phaseIdx); - return liquidDensity1_(temperature, + return liquidDensity1_(temperature, pressure, fluidState.massFraction(phaseIdx, SaltIdx)); } @@ -276,16 +266,9 @@ public: */ using Base::viscosity; template - static Scalar viscosity(const FluidState &fluidState, - int phaseIdx) + static Scalar viscosity(const FluidState &fluidState, int phaseIdx) { assert(0 <= phaseIdx && phaseIdx < numPhases); - // Scalar temperature = fluidState.temperature(phaseIdx); - // Scalar pressure = fluidState.pressure(phaseIdx); - -// return liquidViscosity_(temperature, -// pressure, -// fluidState.massFraction(phaseIdx, SaltIdx)); return 0.001; // [Pa*s] } @@ -322,7 +305,6 @@ public: DUNE_THROW(Dune::NotImplemented, "Diffusion coefficients"); } - /*! * \brief Given a phase's composition, temperature and pressure, * return the binary diffusion coefficient for components @@ -339,15 +321,10 @@ public: int phaseIdx, int compIIdx, int compJIdx) - { assert(0 <= phaseIdx && phaseIdx < numPhases); assert(0 <= compIIdx && compIIdx < numComponents); assert(0 <= compJIdx && compJIdx < numComponents); -// Scalar diffusionCoefficient_; -// diffusionCoefficient_ = GET_RUNTIME_PARAM(TypeTag, Scalar, FluidSystem.diffusionCoefficient); - // 3.7378e-12 - // Scalar diffusionCoefficient_ = problem().diffusionCoefficient(element, fvGeometry, scvIdx); return 1.2e-9;//6.6e-6; // in [m^2/s] from Mufte modell } @@ -360,8 +337,7 @@ public: */ using Base::enthalpy; template - static Scalar enthalpy(const FluidState &fluidState, - int phaseIdx) + static Scalar enthalpy(const FluidState &fluidState, int phaseIdx) { assert(0 <= phaseIdx && phaseIdx < numPhases); @@ -376,8 +352,7 @@ public: */ using Base::thermalConductivity; template - static Scalar thermalConductivity(const FluidState &fluidState, - int phaseIdx) + static Scalar thermalConductivity(const FluidState &fluidState, int phaseIdx) { assert(0 <= phaseIdx && phaseIdx < numPhases); @@ -404,56 +379,52 @@ public: private: /***********************************************************************/ - /* */ - /* water density with dissolved salt */ - /* rho_{b} = rho_w + contribution(salt) */ - /* */ + /* water density with dissolved salt + /* rho_{b} = rho_w + contribution(salt) /***********************************************************************/ - static Scalar liquidDensity1_(Scalar T, - Scalar pl, - Scalar Xsalt) + static Scalar liquidDensity1_(Scalar T, Scalar pl, Scalar Xsalt) { Valgrind::CheckDefined(T); Valgrind::CheckDefined(pl); Valgrind::CheckDefined(Xsalt); - - if(T < 273.15) { + if (T < 273.15) + { DUNE_THROW(NumericalProblem, "Liquid density for Brine and CO2 is only " "defined above 273.15K (is" << T << ")"); } - if(pl >= 2.5e8) { + + if (pl >= 2.5e8) + { DUNE_THROW(NumericalProblem, "Liquid density for Brine and CO2 is only " "defined below 250MPa (is" << pl << ")"); } - Scalar salinity=Xsalt; - Scalar TempC = T - 273.15; - Scalar pMPa = pl/1.0E6; - - Scalar rhow = H2O::liquidDensity(T, pl);//1000; - Scalar rho_brine= - rhow + - 1000*salinity*( - 0.668 + - 0.44*salinity + - 1.0E-6*( - 300*pMPa - - 2400*pMPa*salinity + - TempC*( - 80.0 - - 3*TempC - - 3300*salinity - - 13*pMPa + - 47*pMPa*salinity))); - + Scalar salinity=Xsalt; + Scalar TempC = T - 273.15; + Scalar pMPa = pl/1.0E6; + + Scalar rhow = H2O::liquidDensity(T, pl);//1000; + Scalar rho_brine= + rhow + + 1000*salinity*( + 0.668 + + 0.44*salinity + + 1.0E-6*( + 300*pMPa - + 2400*pMPa*salinity + + TempC*( + 80.0 - + 3*TempC - + 3300*salinity - + 13*pMPa + + 47*pMPa*salinity))); return rho_brine; } - /*! * \brief The dynamic viscosity \f$\mathrm{[Pa*s]}\f$ of pure brine. * @@ -464,35 +435,27 @@ private: * - cited by: Bachu & Adams (2002) * "Equations of State for basin geofluids" */ - static Scalar liquidViscosity_(Scalar temperature, Scalar pressure, Scalar Xsalt) - { - if(temperature <= 275.) // regularisation - { temperature = 275; } - Scalar T_C = temperature - 273.15; - Scalar salinity=Xsalt; - Scalar A = (0.42*pow((pow(salinity, 0.8)-0.17), 2) + 0.045)*pow(T_C, 0.8); - Scalar mu_brine = 0.1 + 0.333*salinity + (1.65+91.9*salinity*salinity*salinity)*exp(-A); - - return mu_brine/1000.0; /* unit: Pa s */ - } - + static Scalar liquidViscosity_(Scalar temperature, Scalar pressure, Scalar Xsalt) + { + // regularisation + if (temperature <= 275.) + { + temperature = 275; + } - }; + Scalar T_C = temperature - 273.15; + Scalar salinity=Xsalt; + Scalar A = (0.42*pow((pow(salinity, 0.8)-0.17), 2) + 0.045)*pow(T_C, 0.8); + Scalar mu_brine = 0.1 + 0.333*salinity + (1.65+91.9*salinity*salinity*salinity)*exp(-A); -} // end namepace + return mu_brine/1000.0; /* unit: Pa s */ + } +}; +} // end namepace FluidSystems #ifdef DUMUX_PROPERTIES_HH -// forward defintions of the property tags -//namespace Properties -//{ -//NEW_PROP_TAG(Scalar); -//// Set Co2 tables -//SET_TYPE_PROP(NumericModel, CO2Table, Dumux::CO2Tables); -//// Set salinity defaults -//SET_SCALAR_PROP(NumericModel, Salinity, 1e-3); -//}; /*! * \brief A pure single-phase fluid system. @@ -505,17 +468,11 @@ template class WaterSaltFluidSystem : public FluidSystems::WaterSalt { - using Scalar = typename GET_PROP_TYPE(TypeTag, PTAG(Scalar)); - using ThisType = WaterSaltFluidSystem; - // typedef typename FluidSystems::WaterSalt WaterSalt1; - // typedef BaseFluidSystem Base; - -public: using ParameterCache = Dumux::NullParameterCache; - - // typedef BaseFluidSystem Base; + using Scalar = typename GET_PROP_TYPE(TypeTag, PTAG(Scalar)); + using ThisType = WaterSaltFluidSystem; +public: + using ParameterCache = Dumux::NullParameterCache; /* * \brief Given a phase's composition, temperature and pressure, @@ -527,28 +484,22 @@ public: using ParameterCache = Dumux::NullParameterCache; * \param compIIdx The index of the first component to consider * \param compJIdx The index of the second component to consider */ +template + static Scalar binaryDiffusionCoefficient(const FluidState &fluidState, + const ParameterCache ¶mCache, + int phaseIdx, + int compIIdx, + int compJIdx) + { + Scalar diffusionCoefficient_; + diffusionCoefficient_ = getParam("Problem.diffusionCoefficient"); - - // using Base::binaryDiffusionCoefficient; - template - static Scalar binaryDiffusionCoefficient(const FluidState &fluidState, - const ParameterCache ¶mCache, - int phaseIdx, - int compIIdx, - int compJIdx) - - { -// assert(0 <= phaseIdx && phaseIdx < numPhases); -// assert(0 <= compIIdx && compIIdx < numComponents); -// assert(0 <= compJIdx && compJIdx < numComponents); - Scalar diffusionCoefficient_; - diffusionCoefficient_ = getParam("Problem.diffusionCoefficient"); - - return diffusionCoefficient_;//1.2e-9;//6.6e-6; // in [m^2/s] from Mufte modell - } + return diffusionCoefficient_;//1.2e-9;//6.6e-6; // in [m^2/s] from Mufte modell + } }; -#endif -} // end namepace -#endif +#endif // DUMUX_PROPERTIES_HH +} // end namespace Dumux + +#endif // DUMUX_WATER_SALT_FLUID_SYSTEM_HH diff --git a/lecture/mm/henryproblem/henry2p/henry2p.cc b/lecture/mm/henryproblem/henry2p/henry2p.cc index 1d98beb..fa408ed 100644 --- a/lecture/mm/henryproblem/henry2p/henry2p.cc +++ b/lecture/mm/henryproblem/henry2p/henry2p.cc @@ -83,11 +83,10 @@ void usage(const char *progName, const std::string &errorMsg) //////////////////////// int main(int argc, char** argv) try { - using namespace Dumux; // define the type tag for this problem - using TypeTag = TTAG(Henry2pProblem); + using TypeTag = TTAG(Henry2pProblemTypeTag); // initialize MPI, finalize is done automatically on exit const auto& mpiHelper = Dune::MPIHelper::instance(argc, argv); @@ -202,9 +201,6 @@ int main(int argc, char** argv) try Parameters::print(); DumuxMessage::print(/*firstCall=*/false); } - - - } catch (Dumux::ParameterException &e) diff --git a/lecture/mm/henryproblem/henry2p/henry2p.input b/lecture/mm/henryproblem/henry2p/henry2p.input index 4cdb58b..6ae6974 100644 --- a/lecture/mm/henryproblem/henry2p/henry2p.input +++ b/lecture/mm/henryproblem/henry2p/henry2p.input @@ -1,5 +1,3 @@ - - [TimeLoop] DtInitial = 2.5 # [s] TEnd =1e12 # [s] diff --git a/lecture/mm/henryproblem/henry2p/henry2pproblem.hh b/lecture/mm/henryproblem/henry2p/henry2pproblem.hh index 7f23bbd..da7a843 100644 --- a/lecture/mm/henryproblem/henry2p/henry2pproblem.hh +++ b/lecture/mm/henryproblem/henry2p/henry2pproblem.hh @@ -42,8 +42,7 @@ #include "henry2pspatialparams.hh" -namespace Dumux -{ +namespace Dumux { template class Henry2pProblem; @@ -51,42 +50,29 @@ class Henry2pProblem; ////////// // Specify the properties for the Henry2p problem ////////// -namespace Properties -{ -NEW_TYPE_TAG(Henry2pProblem, INHERITS_FROM(TwoP, BoxModel)); +namespace Properties { + +NEW_TYPE_TAG(Henry2pProblemTypeTag, INHERITS_FROM(TwoP, BoxModel)); // Set the grid type -SET_TYPE_PROP(Henry2pProblem, Grid, Dune::YaspGrid<2>); +SET_TYPE_PROP(Henry2pProblemTypeTag, Grid, Dune::YaspGrid<2>); // Set the problem property -SET_TYPE_PROP(Henry2pProblem, Problem, Henry2pProblem); +SET_TYPE_PROP(Henry2pProblemTypeTag, Problem, Henry2pProblem); // Set the spatial parameters -SET_TYPE_PROP(Henry2pProblem, SpatialParams, Dumux::Henry2pSpatialParams); +SET_TYPE_PROP(Henry2pProblemTypeTag, SpatialParams, Dumux::Henry2pSpatialParams); -// TODO: remove this macro switch -#if 1 // Set the fluid system -SET_PROP(Henry2pProblem, FluidSystem) +SET_PROP(Henry2pProblemTypeTag, FluidSystem) { using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); using WettingPhase = FluidSystems::OnePLiquid >; using NonwettingPhase = FluidSystems::OnePLiquid >; using type = FluidSystems::TwoPImmiscible; }; -#else -// OR: set the fluid system -SET_TYPE_PROP(Henry2pProblem, FluidSystem, H2ON2FluidSystem); -#endif -// Write the solutions of individual newton iterations? -// SET_BOOL_PROP(Henry2pProblem, NewtonWriteConvergence, false); - -// Use forward differences instead of central differences -// SET_INT_PROP(Henry2pProblem, ImplicitNumericDifferenceMethod, +1); -// SET_SCALAR_PROP(Henry2pProblem, ImplicitMassUpwindWeight, 0.5); - -} +} // end namespace Properties template class Henry2pProblem : public PorousMediumFlowProblem @@ -98,30 +84,21 @@ class Henry2pProblem : public PorousMediumFlowProblem using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector); using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); - //using WettingPhase = typename GET_PROP_TYPE(TypeTag, WettingPhase); - //using NonwettingPhase = typename GET_PROP_TYPE(TypeTag, NonwettingPhase); - // primary variable indices static constexpr int pressureIdx = Indices::pressureIdx; static constexpr int saturationIdx = Indices::saturationIdx; - // equation indices static constexpr int conti0EqIdx = Indices::conti0EqIdx; - // phase indices static constexpr int wPhaseIdx = Indices::Phase0Idx; static constexpr int nPhaseIdx = Indices::Phase1Idx; - // Grid and world dimension static constexpr int dim = GridView::dimension; static constexpr int dimWorld = GridView::dimensionworld; - - - using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); - - typedef Dune::FieldVector GlobalPosition; // TODO: New Version for this? + using Element = typename GridView::template Codim<0>::Entity; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; public: /*! @@ -153,19 +130,21 @@ public: this->model().globalStorage(storage); // Write mass balance information for rank 0 - if (this->gridView().comm().rank() == 0) { + if (this->gridView().comm().rank() == 0) + { std::cout<<"Storage: " << storage << std::endl; } } - /*! * \brief Returns the temperature within the domain. * * This problem assumes a uniform temperature of 10 degrees Celsius. */ Scalar temperature() const - { return temperature_; }; + { + return temperature_; + } NumEqVector sourceAtPos( const GlobalPosition &globalPos) const @@ -195,6 +174,7 @@ public: { values.setAllDirichlet(); } + else { values.setAllNeumann(); @@ -214,31 +194,27 @@ public: */ PrimaryVariables dirichletAtPos(const GlobalPosition &globalPos) const { - PrimaryVariables values; if (globalPos[0]>2-eps_)// if(onRightBoundary_(globalPos)) - { - - if(globalPos[1]<0.8+eps_) - { - Scalar densityB = 1025; - values[pressureIdx] = 1.0133e5+(depthBOR_-globalPos[1]-0.2)*densityB*9.81+1000*9.81*0.2; - values[saturationIdx] = 1.0; - } - else { -// Scalar densityW = 1000; -// // hydrostatic pressure -// values[pressureIdx] = 1.0133e5+(depthBOR_-globalPos[1])*densityW*9.81; -// values[saturationIdx] = 0.0; - Scalar densityB = 1025; - values[pressureIdx] = 1.0133e5+(depthBOR_-globalPos[1]-0.2)*densityB*9.81+1000*9.81*0.2; - values[saturationIdx] = 0.0; - } - } + { - return values; + if(globalPos[1]<0.8+eps_) + { + Scalar densityB = 1025; + values[pressureIdx] = 1.0133e5+(depthBOR_-globalPos[1]-0.2)*densityB*9.81+1000*9.81*0.2; + values[saturationIdx] = 1.0; + } + + else + { + Scalar densityB = 1025; + values[pressureIdx] = 1.0133e5+(depthBOR_-globalPos[1]-0.2)*densityB*9.81+1000*9.81*0.2; + values[saturationIdx] = 0.0; + } + } + return values; } /*! @@ -256,7 +232,8 @@ public: PrimaryVariables values; values = 0.0; - if (onLeftBoundary_(globalPos)) { + if (onLeftBoundary_(globalPos)) + { values[conti0EqIdx] = -freshWaterFluxRate_;//-6.6E-2;// kg / (m * s) } @@ -269,7 +246,6 @@ public: */ // \{ - /*! * \brief Evaluate the initial value for a control volume. * @@ -289,6 +265,7 @@ public: values[pressureIdx] = 1.0133e5+(depthBOR_-globalPos[1]-0.2)*densityB*9.81+1000*9.81*0.2; values[saturationIdx] = 0.0; } + else { Scalar densityW = 1000; @@ -297,7 +274,6 @@ public: } return values; - } // \} @@ -328,6 +304,7 @@ private: Scalar eps_; Scalar freshWaterFluxRate_; }; -} //end namespace -#endif +} //end namespace Dumux + +#endif // DUMUX_HENRY2PPROBLEM_HH diff --git a/lecture/mm/henryproblem/henry2p/henry2pspatialparams.hh b/lecture/mm/henryproblem/henry2p/henry2pspatialparams.hh index 5e7156d..b8069c2 100644 --- a/lecture/mm/henryproblem/henry2p/henry2pspatialparams.hh +++ b/lecture/mm/henryproblem/henry2p/henry2pspatialparams.hh @@ -32,8 +32,7 @@ #include -namespace Dumux -{ +namespace Dumux { /*! * \ingroup TwoPBoxModel @@ -50,7 +49,6 @@ class Henry2pSpatialParams : public FVSpatialParams; using Grid = typename GET_PROP_TYPE(TypeTag, Grid); using GridView = typename GET_PROP_TYPE(TypeTag, GridView); - using CoordScalar = typename Grid::ctype; using Element = typename GridView::template Codim<0>::Entity; using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; @@ -60,8 +58,6 @@ class Henry2pSpatialParams : public FVSpatialParams; using MaterialLaw = EffToAbsLaw; @@ -141,13 +137,11 @@ public: } private: - Scalar K_; Scalar porosity_; MaterialLawParams materialParams_; }; -} // end namespace -#endif - +} // end namespace Dumux +#endif // DUMUX_LENS_SPATIAL_PARAMS_HH diff --git a/lecture/mm/henryproblem/henry2p/simplesaltwater.hh b/lecture/mm/henryproblem/henry2p/simplesaltwater.hh index 088bc3f..7e13df0 100644 --- a/lecture/mm/henryproblem/henry2p/simplesaltwater.hh +++ b/lecture/mm/henryproblem/henry2p/simplesaltwater.hh @@ -26,13 +26,10 @@ #define DUMUX_SIMPLE_SALTWATER_HH #include - #include - #include -namespace Dumux -{ +namespace Dumux { /*! * \ingroup Components * @@ -46,7 +43,7 @@ class SimpleSaltwater : public Dumux::Components::Base > , public Components::Gas > { - typedef Dumux::IdealGas IdealGas; + using IdealGas = Dumux::IdealGas; static const Scalar R; // specific gas constant of water @@ -55,37 +52,49 @@ public: * \brief A human readable name for the water. */ static std::string name() - { return "H2O"; } + { + return "H2O"; + } /*! * \brief The molar mass in \f$\mathrm{[kg/mol]}\f$ of water. */ static Scalar molarMass() - { return 18e-3; } + { + return 18e-3; + } /*! * \brief Returns the critical temperature \f$\mathrm{[K]}\f$ of water. */ static Scalar criticalTemperature() - { return 647.096; /* [K] */ } + { + return 647.096; /* [K] */ + } /*! * \brief Returns the critical pressure \f$\mathrm{[Pa]}\f$ of water. */ static Scalar criticalPressure() - { return 22.064e6; /* [N/m^2] */ } + { + return 22.064e6; /* [N/m^2] */ + } /*! * \brief Returns the temperature \f$\mathrm{[K]}\f$ at water's triple point. */ static Scalar tripleTemperature() - { return 273.16; /* [K] */ } + { + return 273.16; /* [K] */ + } /*! * \brief Returns the pressure \f$\mathrm{[Pa]}\f$ at water's triple point. */ static Scalar triplePressure() - { return 611.657; /* [N/m^2] */ } + { + return 611.657; /* [N/m^2] */ + } /*! * \brief The vapor pressure in \f$\mathrm{[Pa]}\f$ of pure water @@ -103,10 +112,12 @@ public: { if (T > criticalTemperature()) return criticalPressure(); + if (T < tripleTemperature()) return 0; // water is solid: We don't take sublimation into account - static const Scalar n[10] = { + static const Scalar n[10] = + { 0.11670521452767e4, -0.72421316703206e6, -0.17073846940092e2, 0.12020824702470e5, -0.32325550322333e7, 0.14915108613530e2, -0.48232657361591e4, 0.40511340542057e6, -0.23855557567849, @@ -114,7 +125,6 @@ public: }; Scalar sigma = T + n[8]/(T - n[9]); - Scalar A = (sigma + n[0])*sigma + n[1]; Scalar B = (n[2]*sigma + n[3])*sigma + n[4]; Scalar C = (n[5]*sigma + n[6])*sigma + n[7]; @@ -132,9 +142,10 @@ public: * \param temperature temperature of component in \f$\mathrm{[K]}\f$ * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$ */ - static const Scalar gasEnthalpy(Scalar temperature, - Scalar pressure) - { return 1976*(temperature - 293.15) + 2.45e6; } + static const Scalar gasEnthalpy(Scalar temperature, Scalar pressure) + { + return 1976*(temperature - 293.15) + 2.45e6; + } /*! * \brief Specific enthalpy of liquid water \f$\mathrm{[J/kg]}\f$. @@ -142,8 +153,7 @@ public: * \param temperature temperature of component in \f$\mathrm{[K]}\f$ * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$ */ - static const Scalar liquidEnthalpy(Scalar temperature, - Scalar pressure) + static const Scalar liquidEnthalpy(Scalar temperature, Scalar pressure) { return 4180*(temperature - 293.15); } @@ -161,8 +171,7 @@ public: * \param temperature temperature of component in \f$\mathrm{[K]}\f$ * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$ */ - static const Scalar gasInternalEnergy(Scalar temperature, - Scalar pressure) + static const Scalar gasInternalEnergy(Scalar temperature, Scalar pressure) { return gasEnthalpy(temperature, pressure) - @@ -176,9 +185,9 @@ public: * \param temperature temperature of component in \f$\mathrm{[K]}\f$ * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$ */ - static const Scalar liquidInternalEnergy(Scalar temperature, - Scalar pressure) - { return + static const Scalar liquidInternalEnergy(Scalar temperature, Scalar pressure) + { + return liquidEnthalpy(temperature, pressure) - pressure/liquidDensity(temperature, pressure); } @@ -187,13 +196,17 @@ public: * \brief Returns true iff the gas phase is assumed to be compressible */ static bool gasIsCompressible() - { return true; } + { + return true; + } /*! * \brief Returns true iff the liquid phase is assumed to be compressible */ static bool liquidIsCompressible() - { return false; } + { + return false; + } /*! * \brief The density \f$\mathrm{[kg/m^3]}\f$ of steam at a given pressure and temperature. @@ -211,7 +224,9 @@ public: * \brief Returns true iff the gas phase is assumed to be ideal */ static bool gasIsIdeal() - { return true; } + { + return true; + } /*! * \brief The pressure of steam in \f$\mathrm{[Pa]}\f$ at a given density and temperature. @@ -232,9 +247,14 @@ public: * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$ */ static Scalar liquidDensity(Scalar temperature, Scalar pressure) - { return 1025.; } + { + return 1025.; + } + static Scalar liquidMolarDensity(Scalar temperature, Scalar pressure) - { return liquidDensity(temperature, pressure)/molarMass(); } + { + return liquidDensity(temperature, pressure)/molarMass(); + } /*! * \brief The pressure of water in \f$\mathrm{[Pa]}\f$ at a given density and temperature. @@ -255,7 +275,7 @@ public: * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$ * \param regularize defines, if the functions is regularized or not, set to true by default */ - static Scalar gasViscosity(Scalar temperature, Scalar pressure, bool regularize=true) + static Scalar gasViscosity(Scalar temperature, Scalar pressure, bool regularize = true) { return 1e-05; } @@ -288,6 +308,6 @@ public: template const Scalar SimpleSaltwater::R = Dumux::Constants::R / 18e-3; -} // end namepace +} // end namespace Dumux #endif // DUMUX_SIMPLE_SALTWATER_HH diff --git a/lecture/mm/mcwhorter/mcwhorteranalyticsolution.hh b/lecture/mm/mcwhorter/mcwhorteranalyticsolution.hh index ea8f168..15b8dc2 100644 --- a/lecture/mm/mcwhorter/mcwhorteranalyticsolution.hh +++ b/lecture/mm/mcwhorter/mcwhorteranalyticsolution.hh @@ -28,8 +28,7 @@ #include -namespace Dumux -{ +namespace Dumux { /** * @brief Analytic solution of * the McWhorter problem @@ -43,44 +42,27 @@ template class McWhorterAnalytic { using Problem = typename GET_PROP_TYPE(TypeTag, Problem); -// typedef typename GET_PROP_TYPE(TypeTag, Grid) Grid; using GridView = typename GET_PROP_TYPE(TypeTag, GridView); using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - using SpatialParams = typename GET_PROP_TYPE(TypeTag, SpatialParams); - - typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem; - typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState; - - typedef typename GET_PROP(TypeTag, SolutionTypes)::PrimaryVariables PrimaryVariables; - - typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices; - - enum - { - dimworld = GridView::dimensionworld //dim = GridView::dimension, - }; - enum - { - wPhaseIdx = Indices::wPhaseIdx, - nPhaseIdx = Indices::nPhaseIdx, -// pressureIdx = Indices::pressureIdx, - saturationIdx = Indices::saturationIdx//, -// pressEqIdx = Indices::pressEqIdx, -// satEqIdx = Indices::satEqIdx - }; + using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); + using FluidState = typename GET_PROP_TYPE(TypeTag, FluidState); + using PrimaryVariables = typename GET_PROP(TypeTag, SolutionTypes)::PrimaryVariables; + using Indices = typename GET_PROP_TYPE(TypeTag, Indices); + static constexpr int dimworld = GridView::dimensionworld; + static constexpr int wPhaseIdx = Indices::wPhaseIdx; + static constexpr int nPhaseIdx = Indices::nPhaseIdx; + static constexpr int saturationIdx = Indices::saturationIdx; using GlobalPosition = Dune::FieldVector; - using BlockVector = Dune::BlockVector >; using Element = typename GridView::Traits::template Codim<0>::Entity; using ElementIterator = typename GridView::template Codim<0>::Iterator; public: - using MaterialLaw = typename SpatialParams::MaterialLaw; using MaterialLawParams = typename MaterialLaw::Params; - // functions needed for analytical solution + // functions needed for analytical solution void initializeAnalytic() { analyticSolution_.resize(size_); @@ -89,8 +71,6 @@ public: error_=0; elementVolume_.resize(size_); elementVolume_=0; - - return; } void calcSatError() @@ -106,38 +86,17 @@ public: const Element& element = *eIt; int index = problem_.variables().index(*eIt); elementVolume_[index]= element.geometry().volume(); - // std::cout<<"elementVolume_ = "< satVec_; Dune::FieldVector fractionalW_; Dune::FieldVector dpcdsw_; @@ -430,5 +347,7 @@ private: Dune::FieldVector fp_; }; -} -#endif + +} // end namespace Dumux + +#endif // DUMUX_MCWHORTER_ANALYTIC_HH diff --git a/lecture/mm/mcwhorter/mcwhorterproblem.hh b/lecture/mm/mcwhorter/mcwhorterproblem.hh index 61a74af..2f8adee 100644 --- a/lecture/mm/mcwhorter/mcwhorterproblem.hh +++ b/lecture/mm/mcwhorter/mcwhorterproblem.hh @@ -36,28 +36,28 @@ #include "mcwhorteranalyticsolution.hh" #include -namespace Dumux -{ +namespace Dumux { + template class McWhorterProblem; ////////// // Specify the properties ////////// -namespace Properties -{ -NEW_TYPE_TAG(McWhorterProblem, INHERITS_FROM(FVPressureTwoP, FVTransportTwoP, IMPESTwoP, BuckleyLeverettSpatialParams)); +namespace Properties { + +NEW_TYPE_TAG(McWhorterProblemTypeTag, INHERITS_FROM(FVPressureTwoP, FVTransportTwoP, IMPESTwoP, BuckleyLeverettSpatialParamsTypeTag)); // Set the grid type -SET_TYPE_PROP(McWhorterProblem, Grid, Dune::YaspGrid<2>); +SET_TYPE_PROP(McWhorterProblemTypeTag, Grid, Dune::YaspGrid<2>); // Set the problem property -SET_TYPE_PROP(McWhorterProblem, Problem, McWhorterProblem); +SET_TYPE_PROP(McWhorterProblemTypeTag, Problem, McWhorterProblem); -SET_INT_PROP(McWhorterProblem, Formulation, SequentialTwoPCommonIndices::pnsw); +SET_INT_PROP(McWhorterProblemTypeTag, Formulation, SequentialTwoPCommonIndices::pnsw); // Set the wetting phase -SET_PROP(McWhorterProblem, FluidSystem) +SET_PROP(McWhorterProblemTypeTag, FluidSystem) { using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); using WettingPhase = FluidSystems::OnePLiquid >; @@ -65,47 +65,36 @@ SET_PROP(McWhorterProblem, FluidSystem) using type = FluidSystems::TwoPImmiscible; }; -SET_TYPE_PROP(McWhorterProblem, EvalCflFluxFunction, Dumux::EvalCflFluxCoats); -} +SET_TYPE_PROP(McWhorterProblemTypeTag, EvalCflFluxFunction, Dumux::EvalCflFluxCoats); + +} // end namespace Properties /*! * \ingroup DecoupledProblems * \brief McWhorter diffusion problem */ template -class McWhorterProblem: public IMPESProblem2P // TODO: Which is now the correct ancestor class? +class McWhorterProblem: public IMPESProblem2P { using ParentType = IMPESProblem2P; using GridView = typename GET_PROP_TYPE(TypeTag, GridView); using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); using TimeManager = typename GET_PROP_TYPE(TypeTag, TimeManager); - using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); using FluidState = typename GET_PROP_TYPE(TypeTag, FluidState); - using CellData = typename GET_PROP_TYPE(TypeTag, CellData); - using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); using PrimaryVariables = typename GET_PROP(TypeTag, SolutionTypes)::PrimaryVariables; - using Indices = typename GET_PROP_TYPE(TypeTag, Indices); - - enum - { - dim = GridView::dimension, - dimWorld = GridView::dimensionworld - }; - enum - { - wPhaseIdx = Indices::wPhaseIdx, - nPhaseIdx = Indices::nPhaseIdx, - pnIdx = Indices::pnIdx, - swIdx = Indices::swIdx, - pressEqIdx = Indices::pressureEqIdx, - satEqIdx = Indices::satEqIdx - }; + static constexpr int dim = GridView::dimension; + static constexpr int dimWorld = GridView::dimensionworld; + static constexpr int wPhaseIdx = Indices::wPhaseIdx; + static constexpr int nPhaseIdx = Indices::nPhaseIdx; + static constexpr int pnIdx = Indices::pnIdx; + static constexpr int swIdx = Indices::swIdx; + static constexpr int pressEqIdx = Indices::pressureEqIdx; + static constexpr int satEqIdx = Indices::satEqIdx; using GlobalPosition = Dune::FieldVector; - using Element = typename GridView::Traits::template Codim<0>::Entity; using Intersection = typename GridView::Intersection; @@ -116,8 +105,11 @@ public: * \param gridView DOC ME! */ McWhorterProblem(TimeManager& timeManager, typename GridView::Grid &grid) - : ParentType(timeManager, grid), eps_(1e-8), pLeftBc_ ( 1.0e5 ), - analyticSolution_(*this), viplabOutput_(*this) + : ParentType(timeManager, grid) + , eps_(1e-8) + , pLeftBc_ ( 1.0e5 ) + , analyticSolution_(*this) + , viplabOutput_(*this) { this->setOutputInterval( getParam("Output.Interval") ); @@ -145,10 +137,14 @@ public: * This is used as a prefix for files generated by the simulation. */ const std::string name() const - { return "McWhorter"; } + { + return "McWhorter"; + } bool shouldWriteRestartFile() const - { return false; } + { + return false; + } void postTimeStep() { @@ -182,7 +178,8 @@ public: * \param values DOC ME! * \param globalPos DOC ME! */ - void sourceAtPos(PrimaryVariables &values,const GlobalPosition& globalPos) const + void sourceAtPos(PrimaryVariables &values, + const GlobalPosition& globalPos) const { values = 0; } @@ -191,9 +188,11 @@ public: * \param bcTypes DOC ME! * \param globalPos DOC ME! */ - void boundaryTypesAtPos(BoundaryTypes &bcTypes, const GlobalPosition& globalPos) const + void boundaryTypesAtPos(BoundaryTypes &bcTypes, + const GlobalPosition& globalPos) const { - if (globalPos[0] < eps_) //west + //west + if (globalPos[0] < eps_) bcTypes.setAllDirichlet(); // the other boundary (east) @@ -205,7 +204,8 @@ public: * \param values DOC ME! * \param globalPos DOC ME! */ - void dirichletAtPos(PrimaryVariables &values, const GlobalPosition& globalPos) const + void dirichletAtPos(PrimaryVariables &values, + const GlobalPosition& globalPos) const { values[pnIdx] = pLeftBc_; values[swIdx] = 1.0 - snr_; @@ -215,7 +215,8 @@ public: * \param values DOC ME! * \param globalPos DOC ME! */ - void neumannAtPos(PrimaryVariables &values, const GlobalPosition& globalPos) const + void neumannAtPos(PrimaryVariables &values, + const GlobalPosition& globalPos) const { values = 0; //homogeneous Neumann } @@ -225,7 +226,7 @@ public: * \param globalPos DOC ME! */ void initialAtPos(PrimaryVariables &values, - const GlobalPosition &globalPos) const + const GlobalPosition &globalPos) const { values[pnIdx] = pLeftBc_; values[swIdx] = swr_; @@ -236,6 +237,7 @@ public: { if (paraviewOutput_) ParentType::writeOutput(false); + else { std::size_t numElements = this->gridView().size(0); @@ -262,7 +264,9 @@ private: McWhorterAnalytic analyticSolution_; ViplabOutput viplabOutput_; bool paraviewOutput_; - }; -} -#endif +}; + +} // end namespace Dumux + +#endif // DUMUX_MCWHORTERPROBLEM_HH -- GitLab From 090083c8d1abc0368749fad51361fbab8a9f1ad9 Mon Sep 17 00:00:00 2001 From: Matthias Schnebele Date: Thu, 27 Sep 2018 13:39:28 +0200 Subject: [PATCH 08/60] co2plume should be working but the Boundary-Conditions have to be reviewed convetivemixing compiles but the results aren't convincing --- .../mm/co2plume/co2plumeshapeexercise.input | 3 +- lecture/mm/co2plume/co2plumeshapeproblem.hh | 88 +++-- .../co2plumeshapespatialparameters.hh | 28 ++ .../mm/convectivemixing/convmixexercise.cc | 122 ++++--- .../mm/convectivemixing/convmixexercise.input | 36 +- lecture/mm/convectivemixing/convmixproblem.hh | 342 +++++++++++------- .../convectivemixing/convmixspatialparams.hh | 121 +++++-- 7 files changed, 498 insertions(+), 242 deletions(-) diff --git a/lecture/mm/co2plume/co2plumeshapeexercise.input b/lecture/mm/co2plume/co2plumeshapeexercise.input index 8b15c69..fde332b 100644 --- a/lecture/mm/co2plume/co2plumeshapeexercise.input +++ b/lecture/mm/co2plume/co2plumeshapeexercise.input @@ -13,11 +13,12 @@ PressureLow = 1e5# [Pa] low end for tabularization of fluid properties PressureHigh = 3e7# [Pa] high end for tabularization of fluid properties TemperatureLow = 283.15 # [Pa] low end for tabularization of fluid properties TemperatureHigh = 320.15 # [Pa] high end for tabularization of fluid properties +Salinity = 0.1 [SpatialParams] Permeability = 1e-13 # [m^2] intrinsic permeability DipAngle = 0.0 # [deg] dip angle for the domain -Porosity = 0.3 # porosity +Porosity = 0.35 # porosity [MaterialLaw] Swr = 0.2 # [-] residual wetting phase sat. diff --git a/lecture/mm/co2plume/co2plumeshapeproblem.hh b/lecture/mm/co2plume/co2plumeshapeproblem.hh index 5b60255..1012164 100644 --- a/lecture/mm/co2plume/co2plumeshapeproblem.hh +++ b/lecture/mm/co2plume/co2plumeshapeproblem.hh @@ -43,8 +43,11 @@ namespace Dumux { template class PlumeShapeProblem; -namespace Properties { -NEW_TYPE_TAG(PlumeShapeTypeTag, INHERITS_FROM(BoxModel, TwoPTwoCCO2, PlumeShapeSpatialParamsTypeTag)); + +namespace Properties +{ +NEW_TYPE_TAG(PlumeShapeTypeTag, INHERITS_FROM(BoxModel, TwoPTwoCCO2NI, PlumeShapeSpatialParams)); + // Set grid to a two-dimensional structured quadrilateral grid SET_TYPE_PROP(PlumeShapeTypeTag, Grid, Dune::YaspGrid<2>); @@ -72,16 +75,28 @@ class PlumeShapeProblem : public PorousMediumFlowProblem using Indices = typename GET_PROP_TYPE(TypeTag, Indices); static constexpr int dimWorld = GridView::dimensionworld; // copy some indices for convenience - static constexpr int pressureIdx = Indices::pressureIdx; - static constexpr int switchIdx = Indices::switchIdx; - static constexpr int wPhaseIdx = Indices::wPhaseIdx; - static constexpr int nPhaseIdx = Indices::nPhaseIdx; - static constexpr int wPhaseOnly = Indices::wPhaseOnly; - static constexpr int nCompIdx = FluidSystem::nCompIdx; - static constexpr int BrineIdx = FluidSystem::BrineIdx; - static constexpr int CO2Idx = FluidSystem::CO2Idx; - static constexpr int conti0EqIdx = Indices::conti0EqIdx; - static constexpr int contiCO2EqIdx = conti0EqIdx + CO2Idx; + + enum { + pressureIdx = Indices::pressureIdx, + switchIdx = Indices::switchIdx, + + wPhaseIdx = Indices::wPhaseIdx, + nPhaseIdx = Indices::nPhaseIdx, + + wPhaseOnly = Indices::wPhaseOnly, + + nCompIdx = FluidSystem::nCompIdx, + BrineIdx = FluidSystem::BrineIdx, + CO2Idx = FluidSystem::CO2Idx, +#if !ISOTHERMAL + temperatureIdx = Indices::temperatureIdx, + energyEqIdx = Indices::energyEqIdx, +#endif + conti0EqIdx = Indices::conti0EqIdx, + contiCO2EqIdx = conti0EqIdx + CO2Idx + }; + + using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector); using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); @@ -93,7 +108,10 @@ class PlumeShapeProblem : public PorousMediumFlowProblem using GlobalPosition = Dune::FieldVector; using CO2 = Dumux::CO2; //! property that defines whether mole or mass fractions are used - static constexpr bool useMoles = GET_PROP_VALUE(TypeTag, UseMoles); + //static constexpr bool useMoles = GET_PROP_VALUE(TypeTag, UseMoles); + static constexpr bool useMoles = true; + + // the discretization method we are using static constexpr auto discMethod = GET_PROP_TYPE(TypeTag, FVGridGeometry)::discMethod; @@ -110,6 +128,7 @@ public: pressureHigh_ = getParam("FluidSystem.PressureHigh"); temperatureLow_ = getParam("FluidSystem.TemperatureLow"); temperatureHigh_ = getParam("FluidSystem.TemperatureHigh"); + salinity_ = getParam("FluidSystem.Salinity"); name_ = getParam("Problem.Name"); pressure_ = getParam("InitialConditions.Pressure"); // hydrodynamic pressure at top layer temperature_ = getParam("InitialConditions.Temperature"); @@ -123,12 +142,13 @@ public: gravity_[0] = -9.81 * sin(dipAngleRadians_); // initialize the tables of the fluid system - FluidSystem::init(/*Tmin=*/temperatureLow_, - /*Tmax=*/temperatureHigh_, - /*nT=*/nTemperature_, - /*pmin=*/pressureLow_, - /*pmax=*/pressureHigh_, - /*np=*/nPressure_); + FluidSystem::init(/*Tmin*/temperatureLow_, + /*Tmax*/temperatureHigh_, + /*nT*/nTemperature_, + /*pmin*/pressureLow_, + /*pmax*/pressureHigh_, + /*np*/nPressure_, + /*salinity*/ salinity_); } /*! @@ -181,7 +201,15 @@ public: { values.setAllDirichlet(); } - +/* TEST + // set part of West boundaries to Dirichlet & Neumann values + else if ( globalPos[1] < 30.0 + eps_ && globalPos[0] < eps_) + { +#if !ISOTHERMAL + values.setDirichlet(temperatureIdx, energyEqIdx); +#endif + } +*/ return values; } @@ -194,8 +222,17 @@ public: * \param globalPos The global position */ PrimaryVariables dirichletAtPos(const GlobalPosition &globalPos) const - { - return initial_(globalPos); + { PrimaryVariables values; + values = initial_(globalPos); +/* +#if !ISOTHERMAL + if (globalPos[1] < 30.0 + eps_ && globalPos[0] < eps_) + { + values[temperatureIdx] = injectionTemperature_; //in K + } +#endif +*/ + return values; } /*! @@ -224,11 +261,13 @@ public: { NumEqVector fluxes(0.0); // kg/(m^2*s) or mole/(m^2*s) depending on useMoles + const Scalar pressure = elemVolvars[scvf.insideScvIdx()].pressure(nPhaseIdx); auto globalPos = scvf.ipGlobal(); if ( globalPos[1] < 30.0 + eps_ && globalPos[0] < eps_ ) { Scalar massFlux = injectionRate_ /30.0; // [kg/(s*m^2)] fluxes[contiCO2EqIdx] = -massFlux; // kg/(s*m^2) + fluxes[energyEqIdx] = -massFlux*CO2::gasEnthalpy(injectionTemperature_, pressure); } return fluxes; @@ -289,7 +328,9 @@ private: densityW * 9.81 * distanceTopBoundaryToSurface_; values[Indices::switchIdx] = massFracLiquidCO2; - +#if !ISOTHERMAL + values[temperatureIdx] = temperature_;//290.0 + (depthBOR_ - globalPos[1])*0.03; +#endif return values; } @@ -308,6 +349,7 @@ private: Scalar pressureLow_, pressureHigh_, pressure_; Scalar temperatureLow_, temperatureHigh_; + Scalar salinity_; }; } //end namespace Dumux diff --git a/lecture/mm/co2plume/co2plumeshapespatialparameters.hh b/lecture/mm/co2plume/co2plumeshapespatialparameters.hh index 1bb3700..2215ebd 100644 --- a/lecture/mm/co2plume/co2plumeshapespatialparameters.hh +++ b/lecture/mm/co2plume/co2plumeshapespatialparameters.hh @@ -140,6 +140,34 @@ public: return materialParams_; } + /*! + * \brief Returns the heat capacity \f$[J / (kg K)]\f$ of the rock matrix. + * + * This is only required for non-isothermal models. + * + * \param globalPos The global positio + */ + Scalar solidHeatCapacityAtPos(const GlobalPosition& globalPos) const + { return 790; /*specific heat capacity of granite [J / (kg K)]*/ } + + /*! + * \brief Returns the mass density \f$[kg / m^3]\f$ of the rock matrix. + * + * This is only required for non-isothermal models. + * + * \param globalPos The global position + */ + Scalar solidDensityAtPos(const GlobalPosition& globalPos) const + { return 2700; /*density of granite [kg/m^3]*/ } + + /*! + * \brief Returns the thermal conductivity \f$\mathrm{[W/(m K)]}\f$ of the porous material. + * + * \param globalPos The global position + */ + Scalar solidThermalConductivityAtPos(const GlobalPosition& globalPos) const + { return 2.8; } + private: Scalar permeability_; Scalar porosity_; diff --git a/lecture/mm/convectivemixing/convmixexercise.cc b/lecture/mm/convectivemixing/convmixexercise.cc index 4adeda3..52a65f3 100644 --- a/lecture/mm/convectivemixing/convmixexercise.cc +++ b/lecture/mm/convectivemixing/convmixexercise.cc @@ -16,8 +16,12 @@ * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * *****************************************************************************/ -#include "config.h" -#include "convmixproblem.hh" +/*! + * \file + * + * \brief Test for the two-phase two-component CC model. + */ +#include #include #include @@ -27,52 +31,33 @@ #include #include -#include - #include #include +#include #include #include -#include -#include +#include +#include +#include #include +#include + +#include #include -#include +// the problem definitions +#include "convmixproblem.hh" -//! Prints a usage/help message if something goes wrong or the user asks for help -void usage(const char *progName, const std::string &errorMsg) /*@\label{tutorial-coupled:usage-function}@*/ -{ - std::cout << "\nUsage: " << progName << " [options]\n"; - if (errorMsg.size() > 0) - std::cout << errorMsg << "\n"; - std::cout << "\n" - << "The list of mandatory arguments for this program is:\n" - << "\t-TEnd The end of the simulation [s]\n" - << "\t-DtInitial The initial timestep size [s]\n" - << "\t-Grid.UpperRightX The x-coordinate value of the upper-right corner of the grid\n" - << "\t-Grid.UpperRightY The y-coordinate value of the upper-right corner of the grid\n" - << "\t-Grid.NumberOfCellsX The grid's x-resolution\n" - << "\t-Grid.NumberOfCellsY The grid's y-resolution\n" - << "\t-Problem.Name The name of the output files\n" - << "\t-Problem.DepthBOR The depth of the bottom of reservoir\n" - << "\t-Problem.Salinity The salinity of the brine phase [kg/kg]\n" - << "\t-SpatialParams.Permeability The intrinsic permeability\n" - << "\n"; -} -//////////////////////// -// the main function -//////////////////////// int main(int argc, char** argv) try { using namespace Dumux; // define the type tag for this problem - using TypeTag = TTAG(ConvectiveMixingProblemTypeTag); + using TypeTag = TTAG(ConvectiveMixingTypeTag); // initialize MPI, finalize is done automatically on exit const auto& mpiHelper = Dune::MPIHelper::instance(argc, argv); @@ -82,18 +67,19 @@ int main(int argc, char** argv) try DumuxMessage::print(/*firstCall=*/true); // parse command line arguments and input file - Parameters::init(argc, argv, usage); + Parameters::init(argc, argv); // try to create a grid (from the given grid file or the input file) - GridManager gridManager; - gridManager.init(); + 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 = gridManager.grid().leafGridView(); + const auto& leafGridView = GridCreator::grid().leafGridView(); // create the finite volume grid geometry using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); @@ -117,13 +103,14 @@ int main(int argc, char** argv) try // get some time loop parameters using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - const auto tEnd = getParam("TimeLoop.TEnd"); + const Scalar tEnd = getParam("TimeManager.TEnd"); + const auto maxDivisions = getParam("TimeLoop.MaxTimeStepDivisions"); const auto maxDt = getParam("TimeLoop.MaxTimeStepSize"); - auto dt = getParam("TimeLoop.DtInitial"); + auto dt = getParam("TimeManager.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")) // Fehlt ebenso + if (Parameters::getTree().hasKey("Restart") || Parameters::getTree().hasKey("TimeLoop.Restart")) restartTime = getParam("TimeLoop.Restart"); // intialize the vtk output module @@ -133,8 +120,10 @@ int main(int argc, char** argv) try vtkWriter.write(0.0); // instantiate time loop - auto timeLoop = std::make_shared>(restartTime, dt, tEnd); + auto timeLoop = std::make_shared>(restartTime, dt, tEnd); timeLoop->setMaxTimeStepSize(maxDt); + timeLoop->setPeriodicCheckPoint(getParam("TimeLoop.EpisodeLength", std::numeric_limits::max())); + // the assembler with time loop for instationary problem using Assembler = FVAssembler; @@ -145,8 +134,11 @@ int main(int argc, char** argv) try auto linearSolver = std::make_shared(leafGridView, fvGridGeometry->dofMapper()); // the non-linear solver - using NewtonSolver = Dumux::NewtonSolver; - NewtonSolver nonLinearSolver(assembler, linearSolver); + + using NewtonController = PriVarSwitchNewtonController; + using NewtonMethod = Dumux::NewtonMethod; + auto newtonController = std::make_shared(timeLoop); + NewtonMethod nonLinearSolver(newtonController, assembler, linearSolver); // time loop timeLoop->start(); do @@ -154,8 +146,26 @@ int main(int argc, char** argv) try // set previous solution for storage evaluations assembler->setPreviousSolution(xOld); - // solve the non-linear system with time step control - nonLinearSolver.solve(x, *timeLoop); + + // 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; @@ -164,14 +174,17 @@ int main(int argc, char** argv) try // 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 the Newton solver - timeLoop->setTimeStepSize(nonLinearSolver.suggestTimeStepSize(timeLoop->timeStepSize())); + // set new dt as suggested by newton controller + timeLoop->setTimeStepSize(newtonController->suggestTimeStepSize(timeLoop->timeStepSize())); + + // write vtk output + // if episode length was specificied output only at the end of episodes + if (!haveParam("TimeLoop.EpisodeLength") || timeLoop->isCheckPoint() || timeLoop->finished() || timeLoop->timeStepIndex() == 1) + vtkWriter.write(timeLoop->time()); + } while (!timeLoop->finished()); @@ -189,7 +202,8 @@ int main(int argc, char** argv) try } return 0; -} + +} // end main catch (Dumux::ParameterException &e) { @@ -199,10 +213,12 @@ catch (Dumux::ParameterException &e) 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; + + "). 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) diff --git a/lecture/mm/convectivemixing/convmixexercise.input b/lecture/mm/convectivemixing/convmixexercise.input index 0f6966a..9bd089e 100644 --- a/lecture/mm/convectivemixing/convmixexercise.input +++ b/lecture/mm/convectivemixing/convmixexercise.input @@ -1,18 +1,44 @@ -tau = 0.706 -[TimeLoop] -TEnd = 1.e9 # duration of the simulation [s] +[TimeManager] +TEnd = 1.e10 # duration of the simulation [s] + DtInitial = 10 # initial time step size [s] -EpisodeLength = 1.e7 +EpisodeLength = 1.e8 [Grid] UpperRight = 5 5 # upper right corner of the grid [m] -Cells = 10 10 # number of cells in (x, y) direction [-] +Cells = 70 70 # number of cells in (x, y) direction [-] + +[FluidSystem] +NTemperature = 3# [-] number of tabularization entries +NPressure = 200# [-] number of tabularization entries +PressureLow = 1e5# [Pa] low end for tabularization of fluid properties +PressureHigh = 3e7# [Pa] high end for tabularization of fluid properties +TemperatureLow = 283.15 # [Pa] low end for tabularization of fluid properties +TemperatureHigh = 320.15 # [Pa] high end for tabularization of fluid properties [Problem] Name = convmix # [-] the name of the output files DepthBOR = 1400 # [m] depth below ground surface Salinity = 0.05 # [kg/kg] brine salinity + + +[MaterialLaw] +Swr = 0.2 # [-] residual wetting phase sat. +Snr = 0.2 # [-] residual non-wetting phase sat. +Pe = 5e3 # [Pa] capillary entry pressure +Lambda = 2 # [-] Brooks Corey parameter + +[InitialConditions] +Temperature = 283.15 # [K] initial temperature of injected CO2 +Pressure = 1.5e7 # [Pa] initial pressure + + [SpatialParams] Permeability = 3e-13 # [m^2] reservoir permeability +DipAngle = 0.0 # [deg] dip angle for the domain +Porosity = 0.2 # porosity + + +tau = 0.706 diff --git a/lecture/mm/convectivemixing/convmixproblem.hh b/lecture/mm/convectivemixing/convmixproblem.hh index 81d5b00..ff9dbbd 100644 --- a/lecture/mm/convectivemixing/convmixproblem.hh +++ b/lecture/mm/convectivemixing/convmixproblem.hh @@ -16,59 +16,69 @@ * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * *****************************************************************************/ +/*! + * \file + * \ingroup CO2Tests + * \brief Definition of a problem, where CO2 is injected in a reservoir. + */ #ifndef DUMUX_CONVECTIVE_MIXING_PROBLEM_HH #define DUMUX_CONVECTIVE_MIXING_PROBLEM_HH -#include -#include -#include + #include -#include +#include +#include + +#include #include #include +#include #include - #include "convmixspatialparams.hh" -namespace Dumux { + +namespace Dumux +{ + template class ConvectiveMixingProblem; -namespace Properties { -NEW_TYPE_TAG(ConvectiveMixingProblemTypeTag, INHERITS_FROM(BoxModel, ConvMixSpatialParamsTypeTag)); +namespace Properties +{ +NEW_TYPE_TAG(ConvectiveMixingTypeTag, INHERITS_FROM(BoxModel, TwoPTwoCCO2, ConvMixSpatialParams)); -// Set the grid type -SET_TYPE_PROP(ConvectiveMixingProblemTypeTag, Grid, Dune::YaspGrid<2>); +// Set grid to a two-dimensional structured quadrilateral grid +SET_TYPE_PROP(ConvectiveMixingTypeTag, Grid, Dune::YaspGrid<2>); // Set the problem property -SET_TYPE_PROP(ConvectiveMixingProblemTypeTag, Problem, ConvectiveMixingProblemTypeTag); +SET_TYPE_PROP(ConvectiveMixingTypeTag, Problem, ConvectiveMixingProblem); // Set fluid configuration -SET_TYPE_PROP(ConvectiveMixingProblemTypeTag, FluidSystem, BrineCO2); +SET_TYPE_PROP(ConvectiveMixingTypeTag, FluidSystem, FluidSystems::BrineCO2); -//! The constant tau function is used for the effective diffusivity -SET_PROP(ConvectiveMixingProblemTypeTag, EffectiveDiffusivityModel) -{ -private: - using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); -public: - using type = DiffusivityConstantTortuosity; -}; +// Use Moles +SET_BOOL_PROP(ConvectiveMixingTypeTag, UseMoles, false); -// Set the CO2 table to be used; in this case not the the default table -SET_TYPE_PROP(ConvectiveMixingProblemTypeTag, CO2Table, CO2TablesBenchmarkThree::CO2Tables); -//Define whether mole(true) or mass (false) fractions are used -SET_BOOL_PROP(ConvectiveMixingProblemTypeTag, UseMoles, false); +} -} // end namespace Properties +// The constant tau function is used for the effective diffusivity +// SET_TYPE_PROP(ConvectiveMixingTypeTag, EffectiveDiffusivityModel) +// { +// private: +// using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); +// public: +// using type = DiffusivityConstantTau; +// }; + + +template -template class ConvectiveMixingProblem : public PorousMediumFlowProblem { using ParentType = PorousMediumFlowProblem; @@ -76,40 +86,87 @@ class ConvectiveMixingProblem : public PorousMediumFlowProblem using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables); + + using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables); + using Indices = typename GET_PROP_TYPE(TypeTag, Indices); + + enum { dimWorld = GridView::dimensionworld }; + + // copy some indices for convenience + enum { + pressureIdx = Indices::pressureIdx, + switchIdx = Indices::switchIdx, + + wPhaseIdx = Indices::wPhaseIdx, + nPhaseIdx = Indices::nPhaseIdx, + + wPhaseOnly = Indices::wPhaseOnly, + bothPhases = Indices::bothPhases, + + nCompIdx = FluidSystem::nCompIdx, + BrineIdx = FluidSystem::BrineIdx, + CO2Idx = FluidSystem::CO2Idx, + }; + enum { + conti0EqIdx = Indices::conti0EqIdx, + contiCO2EqIdx = conti0EqIdx + CO2Idx, + contiWEqIdx = Indices::contiWEqIdx, + }; + using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); + using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector); using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); - // copy some indices for convenience - using ModelTraits = typename GET_PROP_TYPE(TypeTag, ModelTraits); - using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; - // Grid and world dimension - static constexpr int dim = GridView::dimension; - static constexpr int dimWorld = GridView::dimensionworld; - // indices of the primary variables - static constexpr int pressureIdx = Indices::pressureIdx; // index for the pressure primary variable - static constexpr int massFracIdx = Indices::massOrMoleFracIdx; // index for the CO2 massfraction primary variable - // indices of the equations - static constexpr int conti0EqIdx = Indices::conti0EqIdx; // index for the continuity equation - static constexpr int transportEqIdx = Indices::transportEqIdx; // index for the transport equation using Element = typename GridView::template Codim<0>::Entity; - using ElementIterator = typename GridView::template Codim<0>::Iterator; - using Vertex = typename GridView::template Codim::Entity; - using Intersection = typename GridView::Intersection; - using FVGridGeometry = typename GET_PROP_TYPE(TypeTag,FVGridGeometry); + using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; - using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - using CO2Table = typename GET_PROP_TYPE(TypeTag, PTAG(CO2Table)); - using CO2 = Dumux::CO2; - using Brine_CO2 = Dumux::BinaryCoeff::Brine_CO2; + using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace; + using SubControlVolume = typename FVElementGeometry::SubControlVolume; + using GlobalPosition = Dune::FieldVector; + using CO2 = Dumux::CO2; + //using Brine_CO2 = Dumux::BinaryCoeff::Brine_CO2; + using Brine_CO2 = Dumux::BinaryCoeff::Brine_CO2; + + //! property that defines whether mole or mass fractions are used + static constexpr bool useMoles = GET_PROP_VALUE(TypeTag, UseMoles); + + // the discretization method we are using + static constexpr auto discMethod = GET_PROP_TYPE(TypeTag, FVGridGeometry)::discMethod; public: - ConvectiveMixingProblem(std::shared_ptr fvGridGeometry ) : ParentType(fvGridGeometry) + /*! + * \brief The constructor + * + * \param timeManager The time manager + * \param gridView The grid view + */ + ConvectiveMixingProblem(std::shared_ptr fvGridGeometry) + : ParentType(fvGridGeometry), eps_(1e-6) { - depthBOR_ = getParam("Problem.DepthBOR"); - name_ =getParam("Problem.Name"); + depthBOR_ = getParam("Problem.DepthBOR"); + nTemperature_ = getParam("FluidSystem.NTemperature"); + nPressure_ = getParam("FluidSystem.NPressure"); + pressureLow_ = getParam("FluidSystem.PressureLow"); + pressureHigh_ = getParam("FluidSystem.PressureHigh"); + temperatureLow_ = getParam("FluidSystem.TemperatureLow"); + temperatureHigh_ = getParam("FluidSystem.TemperatureHigh"); + name_ = getParam("Problem.Name"); + pressure_ = getParam("InitialConditions.Pressure"); // hydrodynamic pressure at top layer + temperature_ = getParam("InitialConditions.Temperature"); + dipAngle_ = getParam("SpatialParams.DipAngle"); // [deg] + + dipAngleRadians_ = (dipAngle_ * M_PI)/180.0; // [rad] + // rotate the coordinate system / gravity: + gravity_[1] = -9.81 * cos(dipAngleRadians_); + gravity_[0] = -9.81 * sin(dipAngleRadians_); + + // initialize the tables of the fluid system + FluidSystem::init(/*Tmin=*/temperatureLow_, + /*Tmax=*/temperatureHigh_, + /*nT=*/nTemperature_, + /*pmin=*/pressureLow_, + /*pmax=*/pressureHigh_, + /*np=*/nPressure_); - FluidSystem::init(); - episodeLength_ = getParam("TimeLoop.EpisodeLength"); - this->timeLoop().startNextEpisode(episodeLength_); } /*! @@ -122,17 +179,17 @@ public: * * This is used as a prefix for files generated by the simulation. */ - const std::string name() const - { - return name_; - } + + const std::string& name() const + { return name_; } + /*! * \brief Returns the temperature within the domain. * * This problem assumes a geothermal temperature gradient. */ - Scalar temperatureAtPos(const GlobalPosition &globalPos) const + Scalar temperatureAtPos(const GlobalPosition& globalPos) const { return (283.15 + (depthBOR_ - globalPos[1])*0.032); // geothermal temperatur in [K] // assuming 10°C at surface and a @@ -149,59 +206,79 @@ public: /*! * \brief Specifies which kind of boundary condition should be * used for which equation on a given boundary segment. + * + * \param element The finite element + * \param scvf The sub control volume face */ - BoundaryTypes boundaryTypes(const Vertex &vertex) const + + BoundaryTypes boundaryTypesAtPos(const GlobalPosition& globalPos) const { BoundaryTypes values; - const GlobalPosition globalPos = vertex.geometry().center(); values.setAllNeumann(); - if (globalPos[1] > this->bBoxMax()[1] - eps_) + if(globalPos[1] > this->fvGridGeometry().bBoxMax()[1] - eps_) { - values.setDirichlet(massFracIdx, transportEqIdx); // set top boundary to Dirichlet for transport equation + values.setAllDirichlet(); // set top boundary to Dirichlet for transport equation } - if (globalPos[1] < eps_) - { - values.setAllDirichlet(); // set bottom boundary to Dirichlet for continuity and transport equation - } return values; } /*! - * \brief Evaluate the boundary conditions for a dirichlet - * boundary segment. + * \brief Evaluates the boundary conditions for a Dirichlet + * boundary segment * - * For this method, the \a values parameter stores primary variables. - */ //! return Neumann conditions (flux, [kg/(m^2 s)]) - PrimaryVariables dirichlet( const Vertex &vertex) const + * \param returns the Dirichlet values for the conservation equations in + * \f$ [ \textnormal{unit of primary variable} ] \f$ + * \param globalPos The global position + */ + PrimaryVariables dirichletAtPos(const GlobalPosition &globalPos) const { - PrimaryVariables values; - const GlobalPosition& globalPos = vertex.geometry().center(); + PrimaryVariables values(0.0); - initial_(values, globalPos); + // set initial pressure and pressure Dirichlet conditions: + const Scalar distanceToTopBoundary_ = ( this->fvGridGeometry().bBoxMax()[1] - this->fvGridGeometry().bBoxMin()[1] ) - globalPos[1]; // distance without rotation + const Scalar distanceToTopBoundaryRotated_ = distanceToTopBoundary_ / std::cos(dipAngleRadians_); + + const Scalar distanceTopBoundaryToSurface_ = std::sin(dipAngleRadians_) * (this->fvGridGeometry().bBoxMax()[0] - globalPos[0]); + + values[Indices::pressureIdx] = pressure_; + values[Indices::switchIdx] = 0.05; + return values; } - return values; - } /*! * \brief Evaluate the boundary conditions for a neumann * boundary segment. * - * For this method, the \a values parameter stores the mass flux - * in normal direction of each component. Negative values mean - * influx. + * This is the method for the case where the Neumann condition is + * potentially solution dependent and requires some quantities that + * are specific to the fully-implicit method. + * + * \param values The neumann values for the conservation equations in units of + * \f$ [ \textnormal{unit of conserved quantity} / (m^2 \cdot s )] \f$ + * \param element The finite element + * \param fvGeometry The finite-volume geometry + * \param elemVolVars All volume variables for the element + * \param scvf The sub control volume face + * + * For this method, the \a values parameter stores the flux + * in normal direction of each phase. Negative values mean influx. + * E.g. for the mass balance that would the mass flux in \f$ [ kg / (m^2 \cdot s)] \f$. */ - using ParentType::neumann; - PrimaryVariables neumann(const Element &element, - const FVElementGeometry &fvElemGeom, - const Intersection &is, - int scvIdx, - int boundaryFaceIdx) const + + NumEqVector neumann(const Element& element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolvars, + const SubControlVolumeFace& scvf) const { - return PrimaryVariables(0.0); + NumEqVector fluxes(0.0); + // kg/(m^2*s) or mole/(m^2*s) depending on useMoles + auto globalPos = scvf.ipGlobal(); + return fluxes; + } // \} @@ -212,77 +289,100 @@ public: // \{ /*! - * \brief Evaluate the source term for all phases within a given - * sub-control-volume. + + * \brief Evaluates the initial values at a position * - * For this method, the \a values parameter stores the rate mass - * of a component is generated or annihilate per volume - * unit. Positive values mean that mass is created, negative ones - * mean that it vanishes. + * \returns the initial values for the conservation equations in + * \f$ [ \textnormal{unit of primary variables} ] \f$ + * \param globalPos The global position */ - PrimaryVariables sourceAtPos(const GlobalPosition &globalPos) const + + PrimaryVariables initialAtPos(const GlobalPosition &globalPos) const { - return PrimaryVariables(0.0); + return initial_(globalPos); } + // \} + +private: /*! - * \brief Evaluate the initial value for a control volume. + * \brief Evaluates the initial values for a control volume + * + * The internal method for the initial condition * - * For this method, the \a values parameter stores primary - * variables. + * \param values Stores the initial values for the conservation equations in + * \f$ [ \textnormal{unit of primary variables} ] \f$ + * \param globalPos The global position */ - PrimaryVariables initial( const Element &element, - const FVElementGeometry &fvElemGeom, - int scvIdx) const - { - PrimaryVariables values; - const GlobalPosition &globalPos - = element.geometry().corner(scvIdx); - - return(initial_(globalPos)); - } - -private: - // the internal method for the initial condition and dirichlet boundary conditions - // returns the values for the two primary variables pressure and CO2 massfraction PrimaryVariables initial_(const GlobalPosition &globalPos) const { - PrimaryVariables values; + PrimaryVariables values(0.0); + values.setState(wPhaseOnly); + values[Indices::pressureIdx] = 1.013e5 + (depthBOR_ - globalPos[1]) * 1100 * 9.81; // hydrostatic pressure distribution + values[Indices::switchIdx] = 0; // initial condition for the co2 mass fraction const Scalar temp = temperatureAtPos(globalPos); + const Scalar densityW = FluidSystem::Brine::liquidDensity(temperature_, 1e5); const Scalar salinity = getParam("Problem.Salinity"); - values[pressureIdx] = 1.013e5 + (depthBOR_ - globalPos[1]) * 1100 * 9.81; // hydrostatic pressure distribution - values[massFracIdx] = 0; // initial condition for the co2 mass fraction + const Scalar moleFracLiquidCO2 = 0.00; + const Scalar moleFracLiquidBrine = 1.0 - moleFracLiquidCO2; + + const Scalar meanM = FluidSystem::molarMass(BrineIdx)*moleFracLiquidBrine + + FluidSystem::molarMass(CO2Idx)*moleFracLiquidCO2; + + const Scalar massFracLiquidCO2 = moleFracLiquidCO2*FluidSystem::molarMass(CO2Idx)/meanM; Scalar moleFracCO2, xgH2O; Brine_CO2::calculateMoleFractions(temp, - values[pressureIdx], + values[Indices::pressureIdx], salinity, /*knownPhaseIdx=*/-1, moleFracCO2, xgH2O); - const Scalar M1 = FluidSystem::molarMass(0); const Scalar M2 = FluidSystem::molarMass(1); const Scalar avgMolarMass = moleFracCO2 * M2 + (1-moleFracCO2) * M1; const Scalar massFracCO2 = moleFracCO2 * FluidSystem::molarMass(1)/avgMolarMass; - if (globalPos[1] > this->bBoxMax()[1] - eps_) + + // set initial pressure and pressure Dirichlet conditions: + const Scalar distanceToTopBoundary_ = ( this->fvGridGeometry().bBoxMax()[1] - this->fvGridGeometry().bBoxMin()[1] ) - globalPos[1]; // distance without rotation + const Scalar distanceToTopBoundaryRotated_ = distanceToTopBoundary_ / std::cos(dipAngleRadians_); + + + const Scalar distanceTopBoundaryToSurface_ = std::sin(dipAngleRadians_) * (this->fvGridGeometry().bBoxMax()[0] - globalPos[0]); + values[Indices::pressureIdx] = pressure_ + densityW * 9.81 * distanceToTopBoundaryRotated_ + + densityW * 9.81 * distanceTopBoundaryToSurface_; + + values[Indices::switchIdx] = massFracLiquidCO2; + + if(globalPos[1] > this->fvGridGeometry().bBoxMax()[1] - eps_) + { - values[massFracIdx] = massFracCO2; // CO2 massfraction at top boundary [-] + values.setState(bothPhases); + values[Indices::switchIdx] = 0.05; // CO2 saturation at top boundary [-] } return values; } - static constexpr Scalar eps_ = 1e-6; - Scalar episodeLength_; + Scalar temperature_; Scalar depthBOR_; // bottom of reservoir [m] + Scalar eps_; + Scalar dipAngleRadians_, dipAngle_; + + GlobalPosition gravity_; + + int nTemperature_; + int nPressure_; + std::string name_ ; + Scalar pressureLow_, pressureHigh_, pressure_; + Scalar temperatureLow_, temperatureHigh_; }; -} // end namespace Dumux +} //end namespace Dumux -#endif // DUMUX_CONVECTIVE_MIXING_PROBLEM_HH +#endif diff --git a/lecture/mm/convectivemixing/convmixspatialparams.hh b/lecture/mm/convectivemixing/convmixspatialparams.hh index a64ade3..d294c8d 100644 --- a/lecture/mm/convectivemixing/convmixspatialparams.hh +++ b/lecture/mm/convectivemixing/convmixspatialparams.hh @@ -23,6 +23,8 @@ #include #include #include +#include + namespace Dumux { @@ -36,81 +38,122 @@ namespace Properties { NEW_TYPE_TAG(ConvMixSpatialParamsTypeTag); // Set the spatial parameters -SET_TYPE_PROP(ConvMixSpatialParamsTypeTag, SpatialParams, Dumux::ConvMixSpatialParamsTypeTag); -} // end namespace Properties +SET_TYPE_PROP(ConvMixSpatialParams, SpatialParams, ConvMixSpatialParams); + +// Set the material Law +SET_PROP(ConvMixSpatialParams, MaterialLaw) +{ +private: + // define the material law which is parameterized by effective + // saturations + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); +public: + // define the material law parameterized by absolute saturations + using type = EffToAbsLaw>; +}; +} -/*! - * \ingroup OnePTwoCBoxModel - * - * \brief Definition of the spatial parameters for the - * convective mixing problem - */ template -class ConvMixSpatialParams : public FVSpatialParams> +class ConvMixSpatialParams : public FVSpatialParams { - using ParentType = PorousMediumFlowProblem; - using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using ParentType = FVSpatialParams; + using GridCreator = typename GET_PROP_TYPE(TypeTag, GridCreator); + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; + using SubControlVolume = typename FVElementGeometry::SubControlVolume; + + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); using Element = typename GridView::template Codim<0>::Entity; + enum { dimWorld = GridView::dimensionworld }; + using GlobalPosition = Dune::FieldVector; public: - ConvMixSpatialParams(std::shared_ptr fvGridGeometry) - : ParentType(fvGridGeometry) + using MaterialLaw = typename GET_PROP_TYPE(TypeTag, MaterialLaw); + using MaterialLawParams = typename MaterialLaw::Params; + using PermeabilityType = Scalar; + + /*! + * \brief The constructor + * + * \param gridView The grid view + */ + ConvMixSpatialParams(const Problem& problem) + : ParentType(problem) { - // intrinsic permeability [m^2] + // intrinsic permeability permeability_ = getParam("SpatialParams.Permeability"); - } - ~ConvMixSpatialParams() - {} + // porosity + //porosity_ = getParam("SpatialParams.Porosity"); + + // residual saturations + materialParams_.setSwr(getParam("MaterialLaw.Swr")); + materialParams_.setSnr(getParam("MaterialLaw.Snr")); + + // parameters for the Brooks-Corey law + materialParams_.setPe(getParam("MaterialLaw.Pe")); + materialParams_.setLambda(getParam("MaterialLaw.Lambda")); + } /*! - * \brief Define the intrinsic permeability \f$[m^2]\f$. + * \brief Function for defining the (intrinsic) permeability \f$[m^2]\f$ + * \note It is possibly solution dependent. * - * \param element The current finite element - * \param fvElemGeom The current finite volume geometry of the element - * \param scvIdx The index of the sub-control volume + * \param element The current element + * \param scv The sub-control volume inside the element. + * \param elemSol The solution at the dofs connected to the element. + * \return instrinsic permeability */ - const Scalar intrinsicPermeability(const Element &element, - const FVElementGeometry &fvElemGeom, - int scvIdx) const + template + PermeabilityType permeability(const Element& element, + const SubControlVolume& scv, + const ElementSolution& elemSol) const { return permeability_; } /*! - * \brief Define the porosity \f$[-]\f$. + * \brief Returns the porosity \f$[-]\f$ * - * \param element The finite element - * \param fvElemGeom The finite volume geometry - * \param scvIdx The local index of the sub-control volume where + * \param element The current element + * \param scv The sub-control volume inside the element. + * \param elemSol The solution at the dofs connected to the element + * \return porosity */ - const Scalar porosity(const Element &element, - const FVElementGeometry &fvElemGeom, - int scvIdx) const + template + Scalar porosity(const Element& element, + const SubControlVolume& scv, + const ElementSolution& elemSol) const { return 0.2; } /*! - * \brief Define the dispersivity \f$[?]\f$. + * \brief Function for defining the parameters needed by constitutive relationships (kr-sw, pc-sw, etc.). * - * \param element The finite element - * \param fvElemGeom The finite volume geometry - * \param scvIdx The local index of the sub-control volume where + * \return the material parameters object + * \param globalPos The position of the center of the element */ - const Scalar dispersivity(const Element &element, - const FVElementGeometry &fvElemGeom, - int scvIdx) const + + const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const + { + return materialParams_; + } + + template + const Scalar dispersivity(const Element& element, + const SubControlVolume& scv, + const ElementSolution& elemSol) const { return 0.0; } private: - Scalar permeability_; + MaterialLawParams materialParams_; }; } // end namespace Dumux -- GitLab From 9dfc051c2143ae55fcf0c836487523b9350d2e00 Mon Sep 17 00:00:00 2001 From: Giuliano Lombardo Date: Thu, 27 Sep 2018 13:29:15 +0200 Subject: [PATCH 09/60] remediationsscenarios compiles, but during the execution a numerical problem appears (the temperature is getting to high) heatpipe does not compile because of a pTag-error Signed-off-by: Giuliano Lombardo --- lecture/mm/heatpipe/heatpipe.cc | 191 +++++++++++++- lecture/mm/heatpipe/heatpipeproblem.hh | 113 +++++---- lecture/mm/heatpipe/heatpipespatialparams.hh | 131 +++++----- lecture/mm/heatpipe/krpcheatpipe.hh | 2 +- .../mm/remediationscenarios/CMakeLists.txt | 2 +- .../remediationscenariosexercise.cc | 111 ++++---- .../remediationscenariosexercise.input | 15 +- .../remediationscenariosproblem.hh | 239 ++++++++++-------- .../remediationscenariosspatialparams.hh | 235 ++++++----------- 9 files changed, 590 insertions(+), 449 deletions(-) diff --git a/lecture/mm/heatpipe/heatpipe.cc b/lecture/mm/heatpipe/heatpipe.cc index 6201e57..6891313 100644 --- a/lecture/mm/heatpipe/heatpipe.cc +++ b/lecture/mm/heatpipe/heatpipe.cc @@ -22,8 +22,11 @@ * \brief test for the 2p2cni box model */ #include "config.h" -#include "heatpipeproblem.hh" -#include +#include +#include + + +//#include /*! * \brief Provides an interface for customizing error messages associated with @@ -33,6 +36,189 @@ * \param errorMsg The error message that was issued by the start function. * Comprises the thing that went wrong and a general help message. */ + + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include "heatpipeproblem.hh" + +int main(int argc, char** argv) try +{ + using namespace Dumux; + + // define the type tag for this problem + using TypeTag = TTAG(HeatpipeBoxTypeTag); + + //////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////// + + // 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); + + // initialize parameter tree + Parameters::init(argc, argv); + + ////////////////////////////////////////////////////////////////////// + // try to create a grid (from the given grid file or the input file) + ///////////////////////////////////////////////////////////////////// + + GridManager gridManager; + gridManager.init(); + + //////////////////////////////////////////////////////////// + // run instationary non-linear problem on this grid + //////////////////////////////////////////////////////////// + + // we compute on the leaf grid view + const auto& leafGridView = gridManager.grid().leafGridView(); + + // create the finite volume grid geometry + using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); + auto fvGridGeometry = std::make_shared(leafGridView); + fvGridGeometry->update(); + + // the problem (initial and boundary conditions) + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); + auto problem = std::make_shared(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(problem, fvGridGeometry); + gridVariables->init(x, xOld); + + // get some time loop parameters + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + auto tEnd = getParam("TimeLoop.TEnd"); + auto dt = getParam("TimeLoop.DtInitial"); + auto maxDt = getParam("TimeLoop.MaxTimeStepSize"); + + // intialize the vtk output module + VtkOutputModule vtkWriter(*problem, *fvGridGeometry, *gridVariables, x, problem->name()); + using VtkOutputFields = typename GET_PROP_TYPE(TypeTag, VtkOutputFields); + VtkOutputFields::init(vtkWriter); //!< Add model specific output fields + vtkWriter.write(0.0); + + // instantiate time loop + auto timeLoop = std::make_shared>(0.0, dt, tEnd); + timeLoop->setMaxTimeStepSize(maxDt); + + // the assembler with time loop for instationary problem + using Assembler = FVAssembler; + auto assembler = std::make_shared(problem, fvGridGeometry, gridVariables, timeLoop); + + // the linear solver + using LinearSolver = ILU0BiCGSTABBackend; + auto linearSolver = std::make_shared(); + + // the non-linear solver + NewtonSolver nonLinearSolver(assembler, linearSolver); + + // time loop + timeLoop->start(); do + { + // set previous solution for storage evaluations + assembler->setPreviousSolution(xOld); + + // solve the non-linear system with time step control + nonLinearSolver.solve(x, *timeLoop); + + // 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 the newton solver + timeLoop->setTimeStepSize(nonLinearSolver.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) + DumuxMessage::print(/*firstCall=*/false); + + return 0; +} + +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; + + + + + + + + + + + +/* void usage(const char *progName, const std::string &errorMsg) { if (errorMsg.size() > 0) { @@ -223,3 +409,4 @@ catch (...) std::cerr << "Unknown exception thrown! ---> Abort!" << std::endl; return 4; } +*/ diff --git a/lecture/mm/heatpipe/heatpipeproblem.hh b/lecture/mm/heatpipe/heatpipeproblem.hh index 7d0e5f9..6e247dd 100644 --- a/lecture/mm/heatpipe/heatpipeproblem.hh +++ b/lecture/mm/heatpipe/heatpipeproblem.hh @@ -25,10 +25,17 @@ #ifndef DUMUX_HEATPIPE_PROBLEM_HH #define DUMUX_HEATPIPE_PROBLEM_HH +#include +//TODO Which headers? +#include +#include +#include + + #include -#include -#include +#include +#include #include "heatpipespatialparams.hh" @@ -40,33 +47,40 @@ class HeatpipeProblem; namespace Properties { -NEW_TYPE_TAG(HeatpipeProblem, INHERITS_FROM(BoxTwoPTwoCNI, HeatpipeSpatialParams)); +NEW_TYPE_TAG(HeatpipeTypeTag, INHERITS_FROM(TwoPTwoCNI)); +NEW_TYPE_TAG(HeatpipeBoxTypeTag, INHERITS_FROM(BoxModel, HeatpipeTypeTag)); +NEW_TYPE_TAG(HeatpipeCCTpfaTypeTag, INHERITS_FROM(CCTpfaModel, HeatpipeTypeTag)); +NEW_TYPE_TAG(HeatpipeCCMpfaTypeTag, INHERITS_FROM(CCMpfaModel, HeatpipeTypeTag)); // Set the grid type -SET_TYPE_PROP(HeatpipeProblem, Grid, Dune::YaspGrid<2>); +SET_TYPE_PROP(HeatpipeTypeTag, Grid, Dune::YaspGrid<2>); // Set the problem property -SET_TYPE_PROP(HeatpipeProblem, Problem, HeatpipeProblem); +SET_TYPE_PROP(HeatpipeTypeTag, Problem, HeatpipeProblem); // Set the fluid system -SET_TYPE_PROP(HeatpipeProblem, FluidSystem, FluidSystems::H2OAir); +SET_TYPE_PROP(HeatpipeTypeTag, FluidSystem, FluidSystems::H2OAir); - /* This problem uses the \ref TwoPTwoCNIModel model. +// Set the spatial parameters +SET_TYPE_PROP(HeatpipeTypeTag, SpatialParams, HeatpipeSpatialParams); +} + +/* This problem uses the \ref TwoPTwoCNIModel model. * * To run the simulation execute the following line in shell: * ./heatpipe -ParameterFile heatpipe.input * */ template -class HeatpipeProblem : public PorouMediumFlowProblem +class HeatpipeProblem : public PorousMediumFlowProblem { - using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - using GridView = typename GET_PROP_TYPE(TypeTag, GridView); - using Grid = typename GridView::Grid; - using ParentType = ImplicitPorousMediaProblem; + using ParentType = PorousMediumFlowProblem; - // copy some indices for convenience - using Indices = typename GET_PROP_TYPE(TypeTag, Indices); + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using FluidSystem =typename GET_PROP_TYPE(TypeTag, FluidSystem); + using ModelTraits = typename GET_PROP_TYPE(TypeTag, ModelTraits); + using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; enum { @@ -78,26 +92,38 @@ class HeatpipeProblem : public PorouMediumFlowProblem // Phase State bothPhases = Indices::bothPhases, - // Grid and world dimension + // Grid and world dimension dim = GridView::dimension, dimWorld = GridView::dimensionworld, conti0EqIdx = Indices::conti0EqIdx, - contiNEqIdx = conti0EqIdx + Indices::nCompIdx +// contiNEqIdx = conti0EqIdx + FluidSystem::nCompIdx + conti1EqIdx = conti0EqIdx + FluidSystem::comp1Idx }; using GlobalPosition = Dune::FieldVector; - using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); - using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); + using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); + using FVElementGeometry = typename FVGridGeometry::LocalView; + using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace; + using SubControlVolume = typename FVElementGeometry::SubControlVolume; + +// static constexpr int dim = GridView::dimension; +// static constexpr int dimWorld = GridView::dimensionworld; - using Element = typename GridView::template Codim<0>::Entity; + using Element= typename GridView::template Codim<0>::Entity; using Vertex = typename GridView::template Codim::Entity; using Intersection = typename GridView::Intersection; + // copy some indices for convenience - using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); - using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); + using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); + using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector); + using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); + // using Timeloop = typename GET_PROP_TYPE(TypeTag, Timeloop); + + using GlobalPosition = Dune::FieldVector; + public: /*! * \brief The constructor @@ -105,14 +131,11 @@ public: * \param timeManager The time manager * \param gridView The grid view */ - HeatpipeProblem(std::shared_ptr(const FVElementGeometry) fvElementGeometry) - : ParentType(fvElementGeometry) + HeatpipeProblem(std::shared_ptr fVGridGeometry):ParentType(fVGridGeometry) { eps_ = 1e-6; FluidSystem::init(); - episodeLength_ = getParam("TimeLoop.EpisodeLength"); - this->timeManager().startNextEpisode(episodeLength_); } /*! @@ -128,9 +151,9 @@ public: std::string name() const { return "heatpipe"; } - numEqVector sourceAtPos(const GlobalPosition &globalPos) const + NumEqVector sourceAtPos(const GlobalPosition &globalPos) const { - return numEqVector(0.0); + return NumEqVector(0.0); } // \} @@ -147,12 +170,10 @@ public: * \param values The boundary types for the conservation equations * \param vertex The vertex for which the boundary type is set */ - BoundaryTypes boundaryTypes(const Vertex &vertex) const + BoundaryTypes boundaryTypesAtPos(const GlobalPosition &globalPos) const { BoundaryTypes values; - const GlobalPosition globalPos = vertex.geometry().center(); - if(globalPos[0] < eps_) values.setAllDirichlet(); else @@ -170,9 +191,9 @@ public: * * For this method, the \a values parameter stores primary variables. */ - PrimaryVariables dirichlet(const Vertex &vertex) const + PrimaryVariables dirichletAtPos(const GlobalPosition &globalPos) const { - PrimaryVariables values; + PrimaryVariables values(0.0); values[pressureIdx] = 1.013e5; values[switchIdx] = 0.01; @@ -192,14 +213,14 @@ public: * For this method, the \a values parameter stores the mass flux * in normal direction of each phase. Negative values mean influx. */ - PrimaryVariables neumannAtPos( const GlobalPosition &globalPos) const + NumEqVector neumannAtPos( const GlobalPosition &globalPos) const { - PrimaryVariables values(0.0); + NumEqVector values(0.0); // negative values for injection - if (globalPos[0] > (this->bBoxMax()[0] - eps_)) + if (globalPos[0] > (this->fvGridGeometry().bBoxMax()[0] - eps_)) { - values[energyEqIdx] = GET_RUNTIME_PARAM(TypeTag, Scalar, heatFlux); + values[energyEqIdx] = getParam("Problem.heatFlux"); } return values; @@ -223,16 +244,9 @@ public: * For this method, the \a values parameter stores primary * variables. */ - PrimaryVariables initial(const Element &element, - const FVElementGeometry &fvGeometry, - int scvIdx) const + PrimaryVariables initialAtPos(const GlobalPosition &globalPos) const { - PrimaryVariables values; - const GlobalPosition &globalPos = element.geometry().corner(scvIdx); - - initial_(values, globalPos); - - return values; + return initial_(globalPos); } /*! @@ -245,11 +259,6 @@ public: return bothPhases; } - bool shouldWriteRestartFile() const - { - return 0; - } - private: // internal method for the initial condition (reused for the // dirichlet conditions!) @@ -264,8 +273,8 @@ private: return values; } - Scalar eps_; - Scalar episodeLength_; + static constexpr Scalar eps_ = 1e-2; + }; } //end namespace diff --git a/lecture/mm/heatpipe/heatpipespatialparams.hh b/lecture/mm/heatpipe/heatpipespatialparams.hh index 5e385a3..ea90027 100644 --- a/lecture/mm/heatpipe/heatpipespatialparams.hh +++ b/lecture/mm/heatpipe/heatpipespatialparams.hh @@ -24,78 +24,75 @@ #ifndef DUMUX_HEATPIPE_SPATIAL_PARAMS_HH #define DUMUX_HEATPIPE_SPATIAL_PARAMS_HH -#include -#include -//#include -//#include -//#include +#include +#include +#include +#include +#include + #include "krpcheatpipe.hh" namespace Dumux { //forward declaration -template +/*template class HeatpipeSpatialParams; namespace Properties -{ -// The spatial parameters TypeTag -NEW_TYPE_TAG(HeatpipeSpatialParams); - -// Set the spatial parameters -SET_TYPE_PROP(HeatpipeSpatialParams, SpatialParams, Dumux::HeatpipeSpatialParams); - // Set the material Law SET_PROP(HeatpipeSpatialParams, MaterialLaw) { private: using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); public: - using type = KrPcHeatpipe; -}; -} + + + using type = typedef KrPcHeatpipe; +}; //TODO Do we need this +}*/ /*! * \ingroup TwoPTwoCNIModel * \ingroup BoxTestProblems * \brief Definition of the spatial parameters for the water-air problem */ -template -class HeatpipeSpatialParams : public FVSpatialParams > -{ - using ParentType = ImplicitSpatialParams; - using ParentType = FVSpatialParams; - using Element = typename GridView::template Codim<0>::Entity; +template +class HeatpipeSpatialParams +: public FVSpatialParams> - // using Grid = typename GET_PROP_TYPE(TypeTag, Grid); - using GridView = typename GET_PROP_TYPE(TypeTag, GridView); +{ using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - using CoordScalar = typename Grid::ctype; + using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); - static constexpr auto dim=GridView::dimension; - static constexpr auto dimWorld=GridView::dimensionworld; - using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + using ParentType = FVSpatialParams>; - using ModelTraits = typename GET_PROP_TYPE(TypeTag, ModelTraits); - using Indices = typename ModelTraits::Indices; - -/* enum { - wPhaseIdx = Indices::wPhaseIdx - };*/ - static constexpr wPhaseIdx = Indices::wPhaseIdx; + using GridView = typename FVGridGeometry::GridView; + using FVElementGeometry = typename FVGridGeometry::LocalView; + using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace; + using SubControlVolume = typename FVElementGeometry::SubControlVolume; + using Element= typename GridView::template Codim<0>::Entity; - using DimVector = Dune::FieldVector; // TODO: Implementation is Up-to date? + static constexpr int dimWorld = GridView::dimensionworld; - using FluxVariables = typename GET_PROP_TYPE(TypeTag, FluxVariables); - using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables); + using ModelTraits = typename GET_PROP_TYPE(TypeTag, ModelTraits); + using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; - using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); + static constexpr int wPhaseIdx = Indices::wPhaseIdx; + using GlobalPosition = Dune::FieldVector; + //TODO What to do here ? + //using DimVector = Dune::FieldVector; + using DimVector = Dune::FieldVector; + using FluxVariables = typename GET_PROP_TYPE(TypeTag, FluxVariables); + // using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables); TODO + using EffectiveLaw = RegularizedBrooksCorey; public: - using MaterialLaw = typename GET_PROP_TYPE(TypeTag, MaterialLaw); + + using PermeabilityType = Scalar; + using MaterialLaw = EffToAbsLaw; using MaterialLawParams = typename MaterialLaw::Params; /*! @@ -106,18 +103,20 @@ public: HeatpipeSpatialParams(std::shared_ptr fvGridGeometry) : ParentType(fvGridGeometry) { - // intrinsic permeabilities - K_ = getParam("permeability"); // param in a no-name branch: Should this be changed? + + permeability_ = getParam("Problem.Permeability"); // porosities Porosity_ = 0.4; + + multiplierHeatCond_ = getParam("Problem.multiplierHeatCond"); // residual saturations MaterialParams_.setSwr(0.15); MaterialParams_.setSnr(0.0); // parameters for the Brooks-Corey law - MaterialParams_.setP0(std::pow((Porosity_/K_),0.5)); + MaterialParams_.setP0(std::pow((Porosity_/permeability_),0.5)); } ~HeatpipeSpatialParams() @@ -131,11 +130,11 @@ public: * \param fvGeometry The current finite volume geometry of the element * \param scvIdx The index of the sub-control volume */ - const Scalar intrinsicPermeability(const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx) const + Scalar permeability(const Element& element, + const FVElementGeometry &fvElemGeom, + int scvIdx) const { - return K_; + return permeability_; } /*! @@ -146,9 +145,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 int scvIdx) const + double porosity(const Element& element, + const FVElementGeometry &fvElemGeom, + int scvIdx) const { return Porosity_; } @@ -160,10 +159,11 @@ public: * \param element The current finite element * \param fvGeometry The current finite volume geometry of the element * \param scvIdx The index of the sub-control volume - */ - const MaterialLawParams& materialLawParams(const Element &element, + */ // + /*const MaterialLawParams& materialLawParams(const Element &element, const FVElementGeometry &fvGeometry, - const int scvIdx) const + const int scvIdx) const*/ + const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos ) const { return MaterialParams_; } @@ -177,9 +177,9 @@ public: * \param fvGeometry The finite volume geometry * \param scvIdx The local index of the sub-control volume */ - Scalar solidHeatCapacity(const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx) const + Scalar solidHeatCapacity(const Element& element, + const FVElementGeometry &fvElemGeom, + int scvIdx) const { return 700; // specific heat capacity [J / (kg K)] } @@ -193,9 +193,9 @@ public: * \param fvGeometry The finite volume geometry * \param scvIdx The local index of the sub-control volume */ - Scalar solidDensity(const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx) const + Scalar solidDensity(const Element& element, + const FVElementGeometry &fvElemGeom, + int scvIdx) const { return 2600; // density [kg/m^3] } @@ -208,18 +208,19 @@ public: * \param scvIdx The local index of the sub-control volume where * the heat capacity needs to be defined */ - Scalar solidThermalConductivity(const Element &element, - const FVElementGeometry &fvGeometry, - const int scvIdx) const + Scalar solidThermalConductivity(const Element& element, + const FVElementGeometry &fvElemGeom, + int scvIdx) const { - return 2.8*getParam("multiplierHeatCond"); + + return 2.8*multiplierHeatCond_; } private: - Scalar K_; - + Scalar permeability_; + Scalar multiplierHeatCond_; Scalar Porosity_; MaterialLawParams MaterialParams_; diff --git a/lecture/mm/heatpipe/krpcheatpipe.hh b/lecture/mm/heatpipe/krpcheatpipe.hh index 57d5ab6..c78fadb 100644 --- a/lecture/mm/heatpipe/krpcheatpipe.hh +++ b/lecture/mm/heatpipe/krpcheatpipe.hh @@ -70,7 +70,7 @@ public: value = a*std::pow(sw,4)+c; } - Scalar MODIFY_ME_CAPILLARY_PRESSURE = GET_RUNTIME_PARAM(TypeTag, Scalar, multiplierPC); + Scalar MODIFY_ME_CAPILLARY_PRESSURE = getParam("multiplierPC"); return(value * MODIFY_ME_CAPILLARY_PRESSURE); } diff --git a/lecture/mm/remediationscenarios/CMakeLists.txt b/lecture/mm/remediationscenarios/CMakeLists.txt index e3cd194..0ebca9d 100644 --- a/lecture/mm/remediationscenarios/CMakeLists.txt +++ b/lecture/mm/remediationscenarios/CMakeLists.txt @@ -1,4 +1,4 @@ -add_input_file_links() +add_input_file_links(remediationscenariosexercise.input) add_dumux_test(remediationscenariosexercise remediationscenariosexercise remediationscenariosexercise.cc python ${dumux_INCLUDE_DIRS}/bin/testing/runtest.py diff --git a/lecture/mm/remediationscenarios/remediationscenariosexercise.cc b/lecture/mm/remediationscenarios/remediationscenariosexercise.cc index 13bacbf..ca5b722 100644 --- a/lecture/mm/remediationscenarios/remediationscenariosexercise.cc +++ b/lecture/mm/remediationscenarios/remediationscenariosexercise.cc @@ -19,9 +19,34 @@ /*! * \file * - * \brief test for the 3p3cni box model + * \brief Test for the three-phase three-component box model */ -#include "config.h" +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include + +#include +#include + #include "remediationscenariosproblem.hh" #include @@ -73,22 +98,17 @@ void usage(const char *progName, const std::string &errorMsg) } } -/* int main(int argc, char** argv) -{ - typedef TTAG(KuevetteProblem) ProblemTypeTag; - return Dumux::start(argc, argv, usage); -}*/ -//////////////////////// -// the main function -//////////////////////// + int main(int argc, char** argv) try { - // typedef TTAG(LensOnePTwoCProblem) TypeTag; - // return Dumux::start(argc, argv, usage); + using namespace Dumux; // define the type tag for this problem - using TypeTag = TTAG(KuevetteProblem); + using TypeTag = TTAG(KuevetteBoxTypeTag); + + //////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////// // initialize MPI, finalize is done automatically on exit const auto& mpiHelper = Dune::MPIHelper::instance(argc, argv); @@ -101,16 +121,15 @@ int main(int argc, char** argv) try 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(); + GridManager gridManager; + gridManager.init(); //////////////////////////////////////////////////////////// // run instationary non-linear problem on this grid //////////////////////////////////////////////////////////// // we compute on the leaf grid view - const auto& leafGridView = GridCreator::grid().leafGridView(); + const auto& leafGridView = gridManager.grid().leafGridView(); // create the finite volume grid geometry using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); @@ -135,61 +154,49 @@ int main(int argc, char** argv) try // get some time loop parameters using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); const auto tEnd = getParam("TimeLoop.TEnd"); - const auto maxDivisions = getParam("TimeLoop.MaxTimeStepDivisions"); // Q: What is this? Do we need this here? const auto maxDt = getParam("TimeLoop.MaxTimeStepSize"); auto dt = getParam("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")) // Fehlt ebenso + if (Parameters::getTree().hasKey("Restart") || Parameters::getTree().hasKey("TimeLoop.Restart")) restartTime = getParam("TimeLoop.Restart"); // intialize the vtk output module using VtkOutputFields = typename GET_PROP_TYPE(TypeTag, VtkOutputFields); - VtkOutputModule vtkWriter(*problem, *fvGridGeometry, *gridVariables, x, problem->name()); + VtkOutputModule vtkWriter(*gridVariables, x, problem->name()); + using VelocityOutput = typename GET_PROP_TYPE(TypeTag, VelocityOutput); + vtkWriter.addVelocityOutput(std::make_shared(*gridVariables)); VtkOutputFields::init(vtkWriter); //!< Add model specific output fields vtkWriter.write(0.0); // instantiate time loop - auto timeLoop = std::make_shared>(restartTime, dt, tEnd); + auto timeLoop = std::make_shared>(restartTime, dt, tEnd); timeLoop->setMaxTimeStepSize(maxDt); + timeLoop->setPeriodicCheckPoint(getParam("TimeLoop.EpisodeLength", std::numeric_limits::max())); // the assembler with time loop for instationary problem using Assembler = FVAssembler; auto assembler = std::make_shared(problem, fvGridGeometry, gridVariables, timeLoop); // the linear solver - using LinearSolver = AMGBackend; + using LinearSolver = Dumux::AMGBackend; auto linearSolver = std::make_shared(leafGridView, fvGridGeometry->dofMapper()); // the non-linear solver - using NewtonSolver = Dumux::NewtonSolver; + using NewtonSolver = PriVarSwitchNewtonSolver; NewtonSolver nonLinearSolver(assembler, linearSolver); // time loop - timeLoop->start(); do + timeLoop->start(); + while (!timeLoop->finished()) { // 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."); - } + // solve the non-linear system with time step control + nonLinearSolver.solve(x, *timeLoop); // make the new solution the old solution xOld = x; @@ -199,15 +206,16 @@ int main(int argc, char** argv) try timeLoop->advanceTimeStep(); // write vtk output - vtkWriter.write(timeLoop->time()); + // if episode length was specificied output only at the end of episodes + if (!hasParam("TimeLoop.EpisodeLength") || timeLoop->isCheckPoint() || timeLoop->finished() || timeLoop->timeStepIndex() == 1) + vtkWriter.write(timeLoop->time()); // report statistics of this time step timeLoop->reportTimeStep(); - // set new dt as suggested by the Newton solver + // set new dt as suggested by the newton solver timeLoop->setTimeStepSize(nonLinearSolver.suggestTimeStepSize(timeLoop->timeStepSize())); - - } while (!timeLoop->finished()); + } timeLoop->finalize(leafGridView.comm()); @@ -222,8 +230,9 @@ int main(int argc, char** argv) try DumuxMessage::print(/*firstCall=*/false); } -} + return 0; +} catch (Dumux::ParameterException &e) { std::cerr << std::endl << e << " ---> Abort!" << std::endl; @@ -232,10 +241,10 @@ catch (Dumux::ParameterException &e) 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; + "). 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) diff --git a/lecture/mm/remediationscenarios/remediationscenariosexercise.input b/lecture/mm/remediationscenarios/remediationscenariosexercise.input index f683976..4733668 100644 --- a/lecture/mm/remediationscenarios/remediationscenariosexercise.input +++ b/lecture/mm/remediationscenarios/remediationscenariosexercise.input @@ -1,7 +1,8 @@ [TimeLoop] DtInitial = 1 # [s] TEnd = 25920000 # [s] : maybe shorter for some scenarios, can be adapted -OutputInterval = 25 +#OutputInterval = 25 we do not need this +EpisodeLength = 1000 # [s] # Recommended MaxTimeStepSize # for steam injection 5 [s] @@ -13,10 +14,12 @@ MaxTimeStepSize = 5 # [s] UpperRight = 1.5 0.74 Cells = 37 19 -[Implicit] -NumericDifferenceMethod = 1 +#[Implicit] +#NumericDifferenceMethod = 1 [Problem] + +Name = remediation # scenario selection: choose one of the following, # all zero means you can use the "free" scenario parameters SteamScenario = 1 # should be default @@ -46,3 +49,9 @@ WaterFlux = -0.3325 AirFlux = -0.02 ContaminantFlux = -0.0000001 HeatFlux = -5555.0 + +[Newton] +MaxRelativeShift = 1e-5 + +[Assembly] +NumericDifferenceMethod = 0 # use central differences (backward -1, forward +1) diff --git a/lecture/mm/remediationscenarios/remediationscenariosproblem.hh b/lecture/mm/remediationscenarios/remediationscenariosproblem.hh index f940220..2c7d4ec 100644 --- a/lecture/mm/remediationscenarios/remediationscenariosproblem.hh +++ b/lecture/mm/remediationscenarios/remediationscenariosproblem.hh @@ -18,7 +18,7 @@ *****************************************************************************/ /*! * \file - * + * \ingroup ThreePThreeCTests * \brief Non-isothermal gas injection problem where a gas (e.g. steam/air) * is injected into a unsaturated porous medium with a residually * trapped NAPL contamination. @@ -26,11 +26,16 @@ #ifndef DUMUX_REMEDIATIONSCENARIOS_PROBLEM_HH #define DUMUX_REMEDIATIONSCENARIOS_PROBLEM_HH -#include +#include +#include #include #include +#include +#include +#include + #include #include @@ -38,25 +43,34 @@ #define ISOTHERMAL 0 -namespace Dumux -{ +namespace Dumux { +// +/*! + * \ingroup ThreePThreeCTests + * \brief Non-isothermal gas injection problem where a gas (e.g. steam/air) + * is injected into a unsaturated porous medium with a residually + * trapped NAPL contamination. + */ template class KuevetteProblem; -namespace Properties -{ -NEW_TYPE_TAG(KuevetteProblem, INHERITS_FROM(BoxThreePThreeCNI, KuevetteSpatialParams)); +namespace Properties { +NEW_TYPE_TAG(KuevetteTypeTag, INHERITS_FROM(ThreePThreeCNI)); +NEW_TYPE_TAG(KuevetteBoxTypeTag, INHERITS_FROM(BoxModel, KuevetteTypeTag)); +NEW_TYPE_TAG(KuevetteCCTpfaTypeTag, INHERITS_FROM(CCTpfaModel, KuevetteTypeTag)); // Set the grid type -SET_TYPE_PROP(KuevetteProblem, Grid, Dune::YaspGrid<2>); +SET_TYPE_PROP(KuevetteTypeTag, Grid, Dune::YaspGrid<2>); // Set the problem property -SET_TYPE_PROP(KuevetteProblem, Problem,KuevetteProblem); +SET_TYPE_PROP(KuevetteTypeTag, Problem, KuevetteProblem); + +// Set the spatial parameters +SET_TYPE_PROP(KuevetteTypeTag, SpatialParams, KuevetteSpatialParams); // Set the fluid system -SET_TYPE_PROP(KuevetteProblem, - FluidSystem, - FluidSystems::H2OAirMesitylene); +SET_TYPE_PROP(KuevetteTypeTag, + FluidSystem,FluidSystems::H2OAirMesitylene); // Enable gravity // SET_BOOL_PROP(KuevetteProblem, ProblemEnableGravity, true); @@ -75,12 +89,12 @@ SET_TYPE_PROP(KuevetteProblem, // Set the linear solver //SET_TYPE_PROP(KuevetteProblem, LinearSolver, ILU0BiCGSTABBackend); -} +} // end namespace Properties /*! - * \ingroup ThreePThreeCNIBoxModel - * \ingroup BoxTestProblems + * \ingroup ThreePThreeCModel + * \ingroup ImplicitTestProblems * \brief Non-isothermal gas injection problem where a gas (e.g. steam/air) * is injected into a unsaturated porous medium with a residually * trapped NAPL contamination. @@ -100,72 +114,75 @@ SET_TYPE_PROP(KuevetteProblem, * NAPL-kontaminierten por"osen Medien, Dissertation, Eigenverlag des Instituts * f"ur Wasserbau * - * This problem uses the \ref ThreePThreeCNIModel + * This problem uses the \ref ThreePThreeCModel and \ref NIModel model. * * To see the basic effect and the differences to scenarios with pure steam or * pure air injection, it is sufficient to simulated for about 2-3 hours (10000 s). * Complete remediation of the domain requires much longer (about 10 days simulated time). - * To adjust the simulation time it is necessary to edit the file test_3p3cni.input + * To adjust the simulation time it is necessary to edit the input file. * * To run the simulation execute: - * - * ./test_3p3cni -parameterFile test_3p3cni.input - * */ + * ./test_box3p3cnikuevette test_box3p3cnikuevette.input or + * ./test_cc3p3cnikuevette test_cc3p3cnikuevette.input + */ template class KuevetteProblem : public PorousMediumFlowProblem { using ParentType = PorousMediumFlowProblem; using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - using Indices = typename GET_PROP_TYPE(TypeTag, Indices); - using GridView = typename GET_PROP_TYPE(TypeTag, GridView); - using Grid = typename GridView::Grid; - - using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); - using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); - using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); + // copy some indices for convenience + using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); - - using Element = typename GridView::template Codim<0>::Entity; - using Vertex = typename GridView::template Codim::Entity; - using Intersection = typename GridView::Intersection; - enum { pressureIdx = Indices::pressureIdx, switch1Idx = Indices::switch1Idx, switch2Idx = Indices::switch2Idx, temperatureIdx = Indices::temperatureIdx, + contiWEqIdx = Indices::conti0EqIdx + FluidSystem::wCompIdx, + contiGEqIdx = Indices::conti0EqIdx + FluidSystem::gCompIdx, + contiNEqIdx = Indices::conti0EqIdx + FluidSystem::nCompIdx, energyEqIdx = Indices::energyEqIdx, - // Phase State + // phase states threePhases = Indices::threePhases, wgPhaseOnly = Indices::wgPhaseOnly, - // Grid and world dimension - dim = GridView::dimension, + // world dimension dimWorld = GridView::dimensionworld };