// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- // vi: set et ts=4 sw=4 sts=4: // // SPDX-FileCopyrightText: Copyright © DuMux-Course contributors, see AUTHORS.md in root folder // SPDX-License-Identifier: GPL-3.0-or-later // /*! * \file * \brief The main file for the two-phase porousmediumflow problem of exercise-basic */ #include <config.h> #include <iostream> #include <dumux/common/initialize.hh> #include <dumux/common/properties.hh> #include <dumux/common/parameters.hh> #include <dumux/linear/istlsolvers.hh> #include <dumux/linear/linearsolvertraits.hh> #include <dumux/linear/linearalgebratraits.hh> #include <dumux/nonlinear/newtonsolver.hh> #include <dumux/assembly/fvassembler.hh> #include <dumux/assembly/diffmethod.hh> #include <dumux/io/vtkoutputmodule.hh> #include <dumux/io/grid/gridmanager_yasp.hh> /*! * TODO: dumux-course-task 3: * In 2pnimain.cc include the correct properties headerfile */ // The properties file, where the compile time options are defined #include "properties2p.hh" //////////////////////// // the main function //////////////////////// int main(int argc, char** argv) { using namespace Dumux; /*! * TODO: dumux-course-task 3: * In 2pnimain.cc change the type tag for the new injection problem */ // define the type tag for this problem using TypeTag = Properties::TTag::Injection2pCC; /// initialize MPI+X, finalize is done automatically on exit Dumux::initialize(argc, argv); // 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) GridManager<GetPropType<TypeTag, Properties::Grid>> 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 GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; auto gridGeometry = std::make_shared<GridGeometry>(leafGridView); // the problem (initial and boundary conditions) using Problem = GetPropType<TypeTag, Properties::Problem>; auto problem = std::make_shared<Problem>(gridGeometry); // the solution vector using SolutionVector = GetPropType<TypeTag, Properties::SolutionVector>; SolutionVector x; problem->applyInitialSolution(x); auto xOld = x; // the grid variables using GridVariables = GetPropType<TypeTag, Properties::GridVariables>; auto gridVariables = std::make_shared<GridVariables>(problem, gridGeometry); gridVariables->init(x); // initialize the vtk output module using IOFields = GetPropType<TypeTag, Properties::IOFields>; // use non-conforming output for the test with interface solver const auto ncOutput = getParam<bool>("Problem.UseNonConformingOutput", false); VtkOutputModule<GridVariables, SolutionVector> vtkWriter(*gridVariables, x, problem->name(), "", ncOutput ? Dune::VTK::nonconforming : Dune::VTK::conforming); using VelocityOutput = GetPropType<TypeTag, Properties::VelocityOutput>; vtkWriter.addVelocityOutput(std::make_shared<VelocityOutput>(*gridVariables)); IOFields::initOutputModule(vtkWriter); //!< Add model specific output fields vtkWriter.write(0.0); // instantiate time loop using Scalar = GetPropType<TypeTag, Properties::Scalar>; const auto tEnd = getParam<Scalar>("TimeLoop.TEnd"); const auto maxDt = getParam<Scalar>("TimeLoop.MaxTimeStepSize"); const auto dt = getParam<Scalar>("TimeLoop.DtInitial"); auto timeLoop = std::make_shared<TimeLoop<Scalar>>(0.0, dt, tEnd); timeLoop->setMaxTimeStepSize(maxDt); // the assembler with time loop for instationary problem using Assembler = FVAssembler<TypeTag, DiffMethod::numeric>; auto assembler = std::make_shared<Assembler>(problem, gridGeometry, gridVariables, timeLoop, xOld); // the linear solver using LinearSolver = AMGBiCGSTABIstlSolver<LinearSolverTraits<GridGeometry>, LinearAlgebraTraitsFromAssembler<Assembler>>; auto linearSolver = std::make_shared<LinearSolver>(gridGeometry->gridView(), gridGeometry->dofMapper()); // the non-linear solver using NewtonSolver = Dumux::NewtonSolver<Assembler, LinearSolver>; NewtonSolver nonLinearSolver(assembler, linearSolver); // time loop timeLoop->start(); while (!timeLoop->finished()) { //set time in problem (is used in time-dependent Neumann boundary condition) problem->setTime(timeLoop->time()+timeLoop->timeStepSize()); // 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(); // report statistics of this time step timeLoop->reportTimeStep(); // set new dt as suggested by the newton solver timeLoop->setTimeStepSize(nonLinearSolver.suggestTimeStepSize(timeLoop->timeStepSize())); // output to vtk vtkWriter.write(timeLoop->time()); } timeLoop->finalize(leafGridView.comm()); // print parameter report if (leafGridView.comm().rank() == 0) Parameters::print(); return 0; } // end main