From c4e37299bf70a5b2afa523df73cd8bfaa6c92d2c Mon Sep 17 00:00:00 2001 From: Timo Koch <timo.koch@iws.uni-stuttgart.de> Date: Wed, 14 Dec 2016 23:17:40 +0100 Subject: [PATCH] [test][1p] Add 1d3d network test cc. TODO fix box. --- .../1p/implicit/CMakeLists.txt | 23 +- .../1p/implicit/test_box1p1d3d.cc | 69 ---- .../1p/implicit/test_box1p1d3d.input | 19 - .../1p/implicit/test_box1pnetwork1d3d.cc | 38 ++ .../1p/implicit/test_box1pnetwork1d3d.input | 11 + .../1p/implicit/test_cc1p1d3d.cc | 68 ---- .../1p/implicit/test_cc1p1d3d.input | 19 - .../1p/implicit/test_cc1pnetwork1d3d.cc | 38 ++ .../1p/implicit/test_cc1pnetwork1d3d.input | 11 + .../1p/implicit/tubesconvergencetest.py | 62 ++++ .../1p/implicit/tubesproblem.hh | 324 ++++++++++++++++++ .../1p/implicit/tubesspatialparams.hh | 104 ++++++ 12 files changed, 600 insertions(+), 186 deletions(-) delete mode 100644 test/porousmediumflow/1p/implicit/test_box1p1d3d.cc delete mode 100644 test/porousmediumflow/1p/implicit/test_box1p1d3d.input create mode 100644 test/porousmediumflow/1p/implicit/test_box1pnetwork1d3d.cc create mode 100644 test/porousmediumflow/1p/implicit/test_box1pnetwork1d3d.input delete mode 100644 test/porousmediumflow/1p/implicit/test_cc1p1d3d.cc delete mode 100644 test/porousmediumflow/1p/implicit/test_cc1p1d3d.input create mode 100644 test/porousmediumflow/1p/implicit/test_cc1pnetwork1d3d.cc create mode 100644 test/porousmediumflow/1p/implicit/test_cc1pnetwork1d3d.input create mode 100755 test/porousmediumflow/1p/implicit/tubesconvergencetest.py create mode 100644 test/porousmediumflow/1p/implicit/tubesproblem.hh create mode 100644 test/porousmediumflow/1p/implicit/tubesspatialparams.hh diff --git a/test/porousmediumflow/1p/implicit/CMakeLists.txt b/test/porousmediumflow/1p/implicit/CMakeLists.txt index 2fdc06850d..93b23efd35 100644 --- a/test/porousmediumflow/1p/implicit/CMakeLists.txt +++ b/test/porousmediumflow/1p/implicit/CMakeLists.txt @@ -3,7 +3,11 @@ add_subdirectory(pointsources) add_input_file_links() add_gstat_file_links() -add_executable(test_mpfa1p test_mpfa1p.cc) +dune_symlink_to_source_files(FILES "tubesconvergencetest.py") + +set(CMAKE_BUILD_TYPE Debug) + +add_executable(test_mpfa1p EXCLUDE_FROM_ALL test_mpfa1p.cc) # isothermal tests add_dumux_test(test_box1p test_box1p test_box1p.cc @@ -70,12 +74,12 @@ add_dumux_test(test_cc1pniconvection test_cc1pniconvection test_cc1pniconvection --command "${CMAKE_CURRENT_BINARY_DIR}/test_cc1pniconvection") # dim < dimWorld tests with foamgrid -add_dumux_test(test_box1p1d3d test_box1p1d3d test_box1p1d3d.cc +add_dumux_test(test_box1pnetwork1d3d test_box1pnetwork1d3d test_box1pnetwork1d3d.cc python ${CMAKE_SOURCE_DIR}/bin/testing/runtest.py --script fuzzy - --files ${CMAKE_SOURCE_DIR}/test/references/1ptestbox1d3d-reference.vtp - ${CMAKE_CURRENT_BINARY_DIR}/1ptestbox1d3d-00001.vtp - --command "${CMAKE_CURRENT_BINARY_DIR}/test_box1p1d3d") + --files ${CMAKE_SOURCE_DIR}/test/references/1pboxnetwork1d3d-reference.vtp + ${CMAKE_CURRENT_BINARY_DIR}/1pboxnetwork1d3d-00001.vtp + --command "${CMAKE_CURRENT_BINARY_DIR}/test_box1pnetwork1d3d") add_dumux_test(test_box1pfracture2d3d test_box1pfracture2d3d test_box1pfracture2d3d.cc python ${CMAKE_SOURCE_DIR}/bin/testing/runtest.py @@ -84,12 +88,9 @@ add_dumux_test(test_box1pfracture2d3d test_box1pfracture2d3d test_box1pfracture2 ${CMAKE_CURRENT_BINARY_DIR}/1pboxfracture2d3d-00001.vtu --command "${CMAKE_CURRENT_BINARY_DIR}/test_box1pfracture2d3d") -add_dumux_test(test_cc1p1d3d test_cc1p1d3d test_cc1p1d3d.cc - python ${CMAKE_SOURCE_DIR}/bin/testing/runtest.py - --script fuzzy - --files ${CMAKE_SOURCE_DIR}/test/references/1ptestcc1d3d-reference.vtp - ${CMAKE_CURRENT_BINARY_DIR}/1ptestcc1d3d-00001.vtp - --command "${CMAKE_CURRENT_BINARY_DIR}/test_cc1p1d3d") +dune_add_test(SOURCES test_cc1pnetwork1d3d.cc + NAME test_cc1pnetwork1d3d + COMMAND ./tubesconvergencetest.py test_cc1pnetwork1d3d) add_dumux_test(test_cc1pfracture2d3d test_cc1pfracture2d3d test_cc1pfracture2d3d.cc python ${CMAKE_SOURCE_DIR}/bin/testing/runtest.py diff --git a/test/porousmediumflow/1p/implicit/test_box1p1d3d.cc b/test/porousmediumflow/1p/implicit/test_box1p1d3d.cc deleted file mode 100644 index 9afff531b9..0000000000 --- a/test/porousmediumflow/1p/implicit/test_box1p1d3d.cc +++ /dev/null @@ -1,69 +0,0 @@ -// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- -// vi: set et ts=4 sw=4 sts=4: -/***************************************************************************** - * See the file COPYING for full copying permissions. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *****************************************************************************/ -/*! - * \file - * - * \brief test for the one-phase CC model - */ -#include <config.h> -#include "1ptestproblem.hh" -#include <dumux/common/start.hh> - -/*! - * \brief Provides an interface for customizing error messages associated with - * reading in parameters. - * - * \param progName The name of the program, that was tried to be started. - * \param errorMsg The error message that was issued by the start function. - * Comprises the thing that went wrong and a general help message. - */ -void usage(const char *progName, const std::string &errorMsg) -{ - if (errorMsg.size() > 0) { - std::string errorMessageOut = "\nUsage: "; - errorMessageOut += progName; - errorMessageOut += " [options]\n"; - errorMessageOut += errorMsg; - errorMessageOut += "\n\nThe list of mandatory arguments for this program is:\n" - "\t-TimeManager.TEnd End of the simulation [s] \n" - "\t-TimeManager.DtInitial Initial timestep size [s] \n" - "\t-Grid.LowerLeft Lower left corner coordinates\n" - "\t-Grid.UpperRight Upper right corner coordinates\n" - "\t-Grid.Cells Number of cells in respective coordinate directions\n" - "\t-SpatialParams.LensLowerLeft coordinates of the lower left corner of the lens [m] \n" - "\t-SpatialParams.LensUpperRight coordinates of the upper right corner of the lens [m] \n" - "\t-SpatialParams.Permeability Permeability of the domain [m^2] \n" - "\t-SpatialParams.PermeabilityLens Permeability of the lens [m^2] \n"; - - std::cout << errorMessageOut - << "\n"; - } -} - -int main(int argc, char** argv) -{ -#if HAVE_DUNE_FOAMGRID - typedef TTAG(OnePOneDThreeDTestBoxProblem) ProblemTypeTag; - return Dumux::start<ProblemTypeTag>(argc, argv, usage); -#else -#warning External grid module dune-foamgrid needed to run this example. - std::cerr << "Test skipped, it needs dune-foamgrid!" << std::endl; - return 77; -#endif -} diff --git a/test/porousmediumflow/1p/implicit/test_box1p1d3d.input b/test/porousmediumflow/1p/implicit/test_box1p1d3d.input deleted file mode 100644 index 8c972d99f6..0000000000 --- a/test/porousmediumflow/1p/implicit/test_box1p1d3d.input +++ /dev/null @@ -1,19 +0,0 @@ -[TimeManager] -DtInitial = 1 # [s] -TEnd = 1 # [s] - -[Grid] -LowerLeft = 0 0 0 -UpperRight = 1 1 1 -Cells = 4 - -[Problem] -Name = 1ptestbox1d3d # name passed to the output routines - -[SpatialParams] -LensLowerLeft = 0.2 0.2 0.2 -LensUpperRight = 0.8 0.8 0.8 - -Permeability = 1e-10 # [m^2] -PermeabilityLens = 1e-12 # [m^2] - diff --git a/test/porousmediumflow/1p/implicit/test_box1pnetwork1d3d.cc b/test/porousmediumflow/1p/implicit/test_box1pnetwork1d3d.cc new file mode 100644 index 0000000000..0d698cbb6c --- /dev/null +++ b/test/porousmediumflow/1p/implicit/test_box1pnetwork1d3d.cc @@ -0,0 +1,38 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + *****************************************************************************/ +/*! + * \file + * + * \brief test for the one-phase CC model + */ +#include <config.h> +#include "tubesproblem.hh" +#include <dumux/common/start.hh> + +int main(int argc, char** argv) +{ +#if HAVE_DUNE_FOAMGRID + typedef TTAG(TubesTestBoxProblem) ProblemTypeTag; + return Dumux::start<ProblemTypeTag>(argc, argv, [](const char *, const std::string &){}); +#else +#warning External grid module dune-foamgrid needed to run this example. + std::cerr << "Test skipped, it needs dune-foamgrid!" << std::endl; + return 77; +#endif +} diff --git a/test/porousmediumflow/1p/implicit/test_box1pnetwork1d3d.input b/test/porousmediumflow/1p/implicit/test_box1pnetwork1d3d.input new file mode 100644 index 0000000000..3fc22439d7 --- /dev/null +++ b/test/porousmediumflow/1p/implicit/test_box1pnetwork1d3d.input @@ -0,0 +1,11 @@ +[TimeManager] +DtInitial = 1 # [s] +TEnd = 1 # [s] + +[Grid] +File = ./grids/network1d3d.msh + +[Problem] +Name = 1pccnetwork1d3d +LiquidDensity = 1050 # blood density +LiquidKinematicViscosity = 4.0e-3 # blood viscosity diff --git a/test/porousmediumflow/1p/implicit/test_cc1p1d3d.cc b/test/porousmediumflow/1p/implicit/test_cc1p1d3d.cc deleted file mode 100644 index fd20762ad8..0000000000 --- a/test/porousmediumflow/1p/implicit/test_cc1p1d3d.cc +++ /dev/null @@ -1,68 +0,0 @@ -// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- -// vi: set et ts=4 sw=4 sts=4: -/***************************************************************************** - * See the file COPYING for full copying permissions. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - *****************************************************************************/ -/*! - * \file - * - * \brief test for the one-phase CC model - */ -#include <config.h> -#include "1ptestproblem.hh" -#include <dumux/common/start.hh> - -/*! - * \brief Provides an interface for customizing error messages associated with - * reading in parameters. - * - * \param progName The name of the program, that was tried to be started. - * \param errorMsg The error message that was issued by the start function. - * Comprises the thing that went wrong and a general help message. - */ -void usage(const char *progName, const std::string &errorMsg) -{ - if (errorMsg.size() > 0) { - std::string errorMessageOut = "\nUsage: "; - errorMessageOut += progName; - errorMessageOut += " [options]\n"; - errorMessageOut += errorMsg; - errorMessageOut += "\n\nThe list of mandatory arguments for this program is:\n" - "\t-TimeManager.TEnd End of the simulation [s] \n" - "\t-TimeManager.DtInitial Initial timestep size [s] \n" - "\t-Grid.File Name of the file containing the grid \n" - "\t definition in DGF format\n" - "\t-SpatialParams.LensLowerLeftX coordinates of the lower left corner of the lens [m] \n" - "\t-SpatialParams.LensUpperRight coordinates of the upper right corner of the lens [m] \n" - "\t-SpatialParams.Permeability Permeability of the domain [m^2] \n" - "\t-SpatialParams.PermeabilityLens Permeability of the lens [m^2] \n"; - - std::cout << errorMessageOut - << "\n"; - } -} - -int main(int argc, char** argv) -{ -#if HAVE_DUNE_FOAMGRID - typedef TTAG(OnePOneDThreeDTestCCProblem) ProblemTypeTag; - return Dumux::start<ProblemTypeTag>(argc, argv, usage); -#else -#warning External grid module dune-foamgrid needed to run this example. - std::cerr << "Test skipped, it needs dune-foamgrid!" << std::endl; - return 77; -#endif -} diff --git a/test/porousmediumflow/1p/implicit/test_cc1p1d3d.input b/test/porousmediumflow/1p/implicit/test_cc1p1d3d.input deleted file mode 100644 index cb05c034f6..0000000000 --- a/test/porousmediumflow/1p/implicit/test_cc1p1d3d.input +++ /dev/null @@ -1,19 +0,0 @@ -[TimeManager] -DtInitial = 1 # [s] -TEnd = 1 # [s] - -[Grid] -LowerLeft = 0 0 0 -UpperRight = 1 1 1 -Cells = 4 - -[Problem] -Name = 1ptestcc1d3d # name passed to the output routines - -[SpatialParams] -LensLowerLeft = 0.2 0.2 0.2 -LensUpperRight = 0.8 0.8 0.8 - -Permeability = 1e-10 # [m^2] -PermeabilityLens = 1e-12 # [m^2] - diff --git a/test/porousmediumflow/1p/implicit/test_cc1pnetwork1d3d.cc b/test/porousmediumflow/1p/implicit/test_cc1pnetwork1d3d.cc new file mode 100644 index 0000000000..21253b0753 --- /dev/null +++ b/test/porousmediumflow/1p/implicit/test_cc1pnetwork1d3d.cc @@ -0,0 +1,38 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + *****************************************************************************/ +/*! + * \file + * + * \brief test for the one-phase CC model + */ +#include <config.h> +#include "tubesproblem.hh" +#include <dumux/common/start.hh> + +int main(int argc, char** argv) +{ +#if HAVE_DUNE_FOAMGRID + typedef TTAG(TubesTestCCTpfaProblem) ProblemTypeTag; + return Dumux::start<ProblemTypeTag>(argc, argv, [](const char *, const std::string &){}); +#else +#warning External grid module dune-foamgrid needed to run this example. + std::cerr << "Test skipped, it needs dune-foamgrid!" << std::endl; + return 77; +#endif +} diff --git a/test/porousmediumflow/1p/implicit/test_cc1pnetwork1d3d.input b/test/porousmediumflow/1p/implicit/test_cc1pnetwork1d3d.input new file mode 100644 index 0000000000..3fc22439d7 --- /dev/null +++ b/test/porousmediumflow/1p/implicit/test_cc1pnetwork1d3d.input @@ -0,0 +1,11 @@ +[TimeManager] +DtInitial = 1 # [s] +TEnd = 1 # [s] + +[Grid] +File = ./grids/network1d3d.msh + +[Problem] +Name = 1pccnetwork1d3d +LiquidDensity = 1050 # blood density +LiquidKinematicViscosity = 4.0e-3 # blood viscosity diff --git a/test/porousmediumflow/1p/implicit/tubesconvergencetest.py b/test/porousmediumflow/1p/implicit/tubesconvergencetest.py new file mode 100755 index 0000000000..8a2723208a --- /dev/null +++ b/test/porousmediumflow/1p/implicit/tubesconvergencetest.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python + +from math import * +import subprocess +import sys + +if len(sys.argv) != 2: + sys.stderr.write('Please provide a single argument <testname> to the script\n') + sys.exit(1) + +testname = str(sys.argv[1]) + +# remove the old log file +subprocess.call(['rm', testname + '.log']) +print("Removed old log file ({})!".format(testname + '.log')) + +# do the runs with different refinement +for i in [0, 1, 2, 3, 4, 5]: + subprocess.call(['./' + testname, '-Grid.Refinement', str(i), + '-Problem.Name', testname]) + +# check the rates and append them to the log file +logfile = open(testname + '.log', "r+") + +error = [] +hmax = [] +for line in logfile: + line = line.strip("\n") + line = line.strip("\[ConvergenceTest\]") + line = line.split() + error.append(float(line[2])) + hmax.append(float(line[5])) + +results = [] +logfile.truncate(0) +logfile.write("n\thmax\t\terror\t\trate\n") +logfile.write("-"*50 + "\n") +for i in range(len(error)-1): + if isnan(error[i]) or isinf(error[i]): + continue + if not (error[i] < 1e-12 or error[i] < 1e-12): + rate = (log(error[i])-log(error[i+1]))/(log(hmax[i])-log(hmax[i+1])) + message = "{}\t{:0.4e}\t{:0.4e}\t{:0.4e}\n".format(i, hmax[i], error[i], rate) + logfile.write(message) + results.append(rate) + else: + logfile.write("error: exact solution!?") +i = len(error)-1 +message = "{}\t{:0.4e}\t{:0.4e}\n\n\n".format(i, hmax[i], error[i]) +logfile.write(message) + +logfile.close() +print("\nComputed the following convergence rates for {}:\n".format(testname)) +subprocess.call(['cat', testname + '.log']) + +# check the rates, we expect rates around 2 +for r in results: + if int(round(r)) is not 2: + sys.stderr.write("*"*70 + "\n", "The convergence rates were not close enough to 2! Test failed.\n", "*"*70 + "\n") + sys.exit(1) + +sys.exit(0) diff --git a/test/porousmediumflow/1p/implicit/tubesproblem.hh b/test/porousmediumflow/1p/implicit/tubesproblem.hh new file mode 100644 index 0000000000..be741ac146 --- /dev/null +++ b/test/porousmediumflow/1p/implicit/tubesproblem.hh @@ -0,0 +1,324 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + *****************************************************************************/ +/*! + * \file + * + * \brief A test problem for the 1p model. A pipe system with circular cross-section + * and a branching point embedded in a three-dimensional world + */ +#ifndef DUMUX_ONEP_TUBES_TEST_PROBLEM_HH +#define DUMUX_ONEP_TUBES_TEST_PROBLEM_HH + +#include <dune/localfunctions/lagrange/pqkfactory.hh> +#include <dune/geometry/quadraturerules.hh> + +#include <dumux/implicit/cellcentered/tpfa/properties.hh> +#include <dumux/porousmediumflow/1p/implicit/model.hh> +#include <dumux/porousmediumflow/implicit/problem.hh> +#include <dumux/material/components/constant.hh> + +#include "tubesspatialparams.hh" + +namespace Dumux +{ +template <class TypeTag> +class TubesTestProblem; + +namespace Properties +{ +NEW_TYPE_TAG(TubesTestProblem, INHERITS_FROM(OneP)); +NEW_TYPE_TAG(TubesTestCCTpfaProblem, INHERITS_FROM(CCTpfaModel, TubesTestProblem)); +NEW_TYPE_TAG(TubesTestBoxProblem, INHERITS_FROM(BoxModel, TubesTestProblem)); + +// Set the grid type +SET_TYPE_PROP(TubesTestProblem, Grid, Dune::FoamGrid<1, 3>); + +// Set the problem property +SET_TYPE_PROP(TubesTestProblem, Problem, TubesTestProblem<TypeTag>); + +// Set the spatial parameters +SET_TYPE_PROP(TubesTestProblem, SpatialParams, TubesTestSpatialParams<TypeTag>); + +// Set the spatial parameters +SET_TYPE_PROP(TubesTestProblem, LinearSolver, UMFPackBackend<TypeTag>); + +// the fluid +SET_PROP(TubesTestProblem, Fluid) +{ +private: + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); +public: + using type = FluidSystems::LiquidPhase<Scalar, Constant<TypeTag, Scalar>>; +}; +} + +/*! + * \ingroup OnePModel + * \ingroup ImplicitTestProblems + * + * \brief A test problem for the 1p model. A pipe system with circular cross-section + * and a branching point embedded in a three-dimensional world + */ +template <class TypeTag> +class TubesTestProblem : public ImplicitPorousMediaProblem<TypeTag> +{ + using ParentType = ImplicitPorousMediaProblem<TypeTag>; + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables); + + // Grid and world dimension + static const int dim = GridView::dimension; + static const int dimWorld = GridView::dimensionworld; + + using Indices = typename GET_PROP_TYPE(TypeTag, Indices); + enum { + // indices of the primary variables + conti0EqIdx = Indices::conti0EqIdx, + pressureIdx = Indices::pressureIdx + }; + + using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); + using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); + using TimeManager = typename GET_PROP_TYPE(TypeTag, TimeManager); + using Element = typename GridView::template Codim<0>::Entity; + using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry); + using SubControlVolume = typename GET_PROP_TYPE(TypeTag, SubControlVolume); + using GlobalPosition = Dune::FieldVector<Scalar, dimWorld>; + + enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) }; + +public: + TubesTestProblem(TimeManager &timeManager, const GridView &gridView) + : ParentType(timeManager, gridView) + { + name_ = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, std::string, Problem, Name); + + //get hMax_ of the grid + hMax_ = 0.0; + for (const auto& element : elements(this->gridView())) + hMax_ = std::max(element.geometry().volume(), hMax_); + } + + /*! + * \name Problem parameters + */ + // \{ + + /*! + * \brief The problem name. + * + * This is used as a prefix for files generated by the simulation. + */ + const std::string& name() const + { + return name_; + } + + /*! + * \brief Return the temperature within the domain in [K]. + * + */ + Scalar temperature() const + { return 273.15 + 37.0; } // Body temperature + + /*! + * \brief Return how much the domain is extruded at a given sub-control volume. + * + * This means the factor by which a lower-dimensional (1D or 2D) + * entity needs to be expanded to get a full dimensional cell. The + * default is 1.0 which means that 1D problems are actually + * thought as pipes with a cross section of 1 m^2 and 2D problems + * are assumed to extend 1 m to the back. + */ + Scalar boxExtrusionFactor(const Element &element, + const SubControlVolume &scv) const + { + const auto radius = this->spatialParams().radius(scv); + return M_PI*radius*radius; + } + + // \} + /*! + * \name Boundary conditions + */ + // \{ + + /*! + * \brief Specifies which kind of boundary condition should be + * used for which equation on a given boundary control volume. + * + * \param globalPos The position of the center of the finite volume + */ + BoundaryTypes boundaryTypesAtPos(const GlobalPosition &globalPos) const + { + BoundaryTypes bcTypes; + bcTypes.setAllDirichlet(); + return bcTypes; + } + + /*! + * \brief Evaluate the boundary conditions for a dirichlet + * control volume. + * + * \param globalPos The center of the finite volume which ought to be set. + * + * For this method, the \a values parameter stores primary variables. + */ + PrimaryVariables dirichletAtPos(const GlobalPosition &globalPos) const + { + return PrimaryVariables(0.0); + } + + /*! + * \brief Evaluate the boundary conditions for a neumann + * boundary segment. + * + * For this method, the \a priVars parameter stores the mass flux + * in normal direction of each component. Negative values mean + * influx. + */ + PrimaryVariables neumannAtPos(const GlobalPosition& globalPos) const + { + return PrimaryVariables(0.0); + } + + // \} + + /*! + * \name Volume terms + */ + // \{ + + /*! + * \brief Evaluate the source term for all phases within a given + * sub-control-volume. + * + * This is the method for the case where the source term is + * potentially solution dependent and requires some quantities that + * are specific to the fully-implicit method. + * + * \param element The finite element + * \param fvGeometry The finite-volume geometry + * \param elemVolVars All volume variables for the element + * \param scv The sub control volume + * + * 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$. + */ + PrimaryVariables source(const Element &element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars, + const SubControlVolume &scv) const + { + PrimaryVariables source(0.0); + + const auto& globalPos = scv.center(); + const auto& volVars = elemVolVars[scv]; + const auto K = this->spatialParams().intrinsicPermeability(scv, elemVolVars[scv]); + + using std::sin; + if (globalPos[2] > 0.5 - eps_) + source[conti0EqIdx] = K/volVars.viscosity()*volVars.density() + *4.0*4.0*M_PI*M_PI*sin(4.0*M_PI*globalPos[2]); + else + // the "/3.0" stems from the coordindate transformations on the lower branches + source[conti0EqIdx] = K/volVars.viscosity()*volVars.density() + *4.0*4.0*M_PI*M_PI*sin(4.0*M_PI*globalPos[2])/3.0; + + return source; + } + + /*! + * \brief Evaluate the initial value for a control volume. + * + * For this method, the \a priVars parameter stores primary + * variables. + */ + PrimaryVariables initial(const SubControlVolume& scv) const + { + return PrimaryVariables(0.0); + } + + // \} + + void postTimeStep() + { + const auto& solution = this->model().curSol(); + + // calculate the discrete L2-Norm + Scalar LTwoNorm = 0.0; + + // get the Gaussian quadrature rule for intervals + const auto& quad = Dune::QuadratureRules<Scalar, dim>::rule(Dune::GeometryType(1), 1); + + for (const auto& element : elements(this->gridView())) + { + const unsigned int eIdx = this->elementMapper().index(element); + const auto geometry = element.geometry(); + for(auto&& qp : quad) + { + const auto globalPos = geometry.global(qp.position()); + const Scalar pe = exactPressure_(globalPos); + const Scalar integrationElement = geometry.integrationElement(qp.position()); + Scalar p = 0.0; + if (!isBox) + p = solution[eIdx][pressureIdx]; + else + { + // do interpolation with ansatz functions + std::vector<Dune::FieldVector<Scalar, 1> > shapeValues; + const auto& localFiniteElement = feCache_.get(geometry.type()); + localFiniteElement.localBasis().evaluateFunction(qp.position(), shapeValues); + for (unsigned int i = 0; i < shapeValues.size(); ++i) + p += shapeValues[i]*solution[this->model().dofMapper().subIndex(element, i, dim)][pressureIdx]; + } + LTwoNorm += (p - pe)*(p - pe)*qp.weight()*integrationElement; + } + } + LTwoNorm = std::sqrt(LTwoNorm); + + // write the norm into a log file + logFile_.open(this->name() + ".log", std::ios::app); + logFile_ << "[ConvergenceTest] L2-norm(pressure) = " << LTwoNorm << " hMax = " << hMax_ << std::endl; + logFile_.close(); + } + +private: + + Scalar exactPressure_(const GlobalPosition& globalPos) + { + using std::sin; + return sin(4.0*M_PI*globalPos[2]); + } + + static constexpr Scalar eps_ = 1e-8; + std::string name_; + + Scalar hMax_; + + std::ofstream logFile_; + typename Dune::PQkLocalFiniteElementCache<Scalar, Scalar, dim, 1> feCache_; +}; + +} //end namespace Dumux + +#endif diff --git a/test/porousmediumflow/1p/implicit/tubesspatialparams.hh b/test/porousmediumflow/1p/implicit/tubesspatialparams.hh new file mode 100644 index 0000000000..c7ab856603 --- /dev/null +++ b/test/porousmediumflow/1p/implicit/tubesspatialparams.hh @@ -0,0 +1,104 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + *****************************************************************************/ +/*! + * \file + * + * \brief A test problem for the 1p model. A pipe system with circular cross-section + * and a branching point embedded in a three-dimensional world + */ +#ifndef DUMUX_ONEP_TUBES_TEST_SPATIALPARAMS_HH +#define DUMUX_ONEP_TUBES_TEST_SPATIALPARAMS_HH + +#include <dumux/material/spatialparams/implicit1p.hh> + +namespace Dumux +{ + +/*! + * \ingroup OnePModel + * \ingroup ImplicitTestProblems + * + * \brief A test problem for the 1p model. A pipe system with circular cross-section + * and a branching point embedded in a three-dimensional world + */ +template<class TypeTag> +class TubesTestSpatialParams : public ImplicitSpatialParamsOneP<TypeTag> +{ + using ParentType = ImplicitSpatialParamsOneP<TypeTag>; + using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); + using GridView = typename GET_PROP_TYPE(TypeTag, GridView); + using Problem = typename GET_PROP_TYPE(TypeTag, Problem); + using SubControlVolume = typename GET_PROP_TYPE(TypeTag, SubControlVolume); + using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables); + +public: + TubesTestSpatialParams(const Problem& problem, const GridView& gridView) + : ParentType(problem, gridView) + { + radius_ = 1.0; + + using std::sqrt; + radiusMain_ = sqrt(sqrt(4.0/sqrt(3.0))); + } + + /*! + * \brief Return the radius of the circular pipe for the current sub-control volume in [m]. + * + * \param scv The sub control volume + */ + Scalar radius(const SubControlVolume &scv) const + { + if(scv.center()[2] > 0.5 - eps_) + return radiusMain_; + else + return radius_; + } + + /*! + * \brief Function for defining the intrinsic (absolute) permeability. + * + * \param scv The sub control volume + * \param volVars The volume variables in the sub control volumes + * \return the intrinsic permeability + */ + Scalar intrinsicPermeability (const SubControlVolume& scv, + const VolumeVariables& volVars) const + { + const Scalar radius = this->radius(scv); + const Scalar gamma = 2; // quadratic velocity profile (Poiseuille flow) + return radius*radius/(2*(2+gamma)); + } + + /*! + * \brief Returns the porosity \f$[-]\f$ + * + * \param scv The sub control volume + * \return the porosity + */ + Scalar porosity(const SubControlVolume &scv) const + { return 1.0; } + +private: + Scalar radius_, radiusMain_; + static constexpr Scalar eps_ = 1e-8; +}; + +} // end namespace Dumux + +#endif -- GitLab