From aa167dd4f123c0478495a464c12a64fcba32cf94 Mon Sep 17 00:00:00 2001 From: Melanie Lipp <melanie.lipp@iws.uni-stuttgart.de> Date: Fri, 10 Sep 2021 10:49:40 +0200 Subject: [PATCH 01/69] [appl][donea] Update to newer version. --- appl/freeflow/navierstokes/donea/main.cc | 90 +++--- appl/freeflow/navierstokes/donea/params.input | 3 +- appl/freeflow/navierstokes/donea/problem.hh | 263 ++++++------------ 3 files changed, 134 insertions(+), 222 deletions(-) diff --git a/appl/freeflow/navierstokes/donea/main.cc b/appl/freeflow/navierstokes/donea/main.cc index 8f6369f..29bb8b6 100644 --- a/appl/freeflow/navierstokes/donea/main.cc +++ b/appl/freeflow/navierstokes/donea/main.cc @@ -25,6 +25,8 @@ #pragma GCC diagnostic ignored "-Wdeprecated-declarations" #pragma GCC diagnostic ignored "-Wdeprecated-copy" +bool doFirstOrderLocalTruncErrorGlobalRefinement = false; + bool writeOut = false; #include <config.h> @@ -55,8 +57,10 @@ bool writeOut = false; #include <dumux/io/mystaggeredvtkoutputmodule.hh> #include <dumux/io/grid/gridmanager.hh> +#include <dumux/io/grid/controlvolumegrids.hh> #include <dumux/freeflow/navierstokes/staggered/cvdresidualCalc.hh> +#include <dumux/io/outputFacility.hh> #include "problem.hh" @@ -131,15 +135,17 @@ int main(int argc, char** argv) try // we compute on the leaf grid view const auto& leafGridViewVar = hostGrid.leafGridView(); + bool adapt = getParam<bool>("Adaptivity.Adapt"); + using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; using GridView = typename GridGeometry::GridView; using Element = typename GridView::template Codim<0>::Entity; using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - if (getParam<bool>("Adaptivity.Adapt", false)) + if (adapt) { hostGridManager.grid().preAdapt(); - for (const auto &element : elements(leafGridViewVar)) + for (const auto& element : elements(leafGridViewVar)) { GlobalPosition pos = element.geometry().center(); @@ -174,7 +180,6 @@ int main(int argc, char** argv) try // create the finite volume grid geometry using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; auto gridGeometry = std::make_shared<GridGeometry>(leafGridView); - gridGeometry->update(); // the problem (boundary conditions) using Problem = GetPropType<TypeTag, Properties::Problem>; @@ -203,6 +208,11 @@ int main(int argc, char** argv) try vtkWriter.addFaceField(problem->getAnalyticalVelocitySolutionOnFace(), "faceVelocityExact"); vtkWriter.write(0.0); + using CellCenterSolutionVector = GetPropType<TypeTag, Properties::CellCenterSolutionVector>; + CellCenterSolutionVector numericalCCResidualWithAnalytical; + numericalCCResidualWithAnalytical.resize(numDofsCellCenter); + vtkWriter.addField(numericalCCResidualWithAnalytical, "continuityResidual"); + // use the staggered FV assembler using Assembler = CVDStaggeredRefinedFVAssembler<TypeTag, DiffMethod::numeric>; auto assembler = std::make_shared<Assembler>(problem, gridGeometry, gridVariables); @@ -215,55 +225,59 @@ int main(int argc, char** argv) try using NewtonSolver = Dumux::NewtonSolver<Assembler, LinearSolver>; NewtonSolver nonLinearSolver(assembler, linearSolver); - // get residuals for analytical solution - nonLinearSolver.assembleLinearSystem(x); - const auto faceResidualWithAnalyticalSol = (*assembler).residual()[Dune::index_constant<0>()]; - const auto ccResidualWithAnalyticalSol = (*assembler).residual()[Dune::index_constant<1>()]; + using HostGrid = Dune::ALUGrid<2,2,Dune::cube,Dune::nonconforming >; + using HostGridManager = GridManager<HostGrid>; + + std::array<std::string, 4> paramGroups = {"finexCVs", "fineyCVs", "coarsexCVs", "coarseyCVs"}; //xfine... + std::array<HostGridManager, 4> cvGridManagers = {}; + std::array<std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>>,4> cvCenterScvfIndicesMaps; + CVOutputFacility<TypeTag> cvOutputFacility(problem); + cvOutputFacility.iniCVGridManagers(cvGridManagers, cvCenterScvfIndicesMaps, paramGroups); + using Scalar = GetPropType<TypeTag, Properties::Scalar>; + std::vector<std::pair<unsigned int, Scalar>> pvdFileInfos; // linearize & solve Dune::Timer timer; nonLinearSolver.solve(x); - problem->printL2Error(x); - // write shifted control volumes vtk output + //output + if (getParam<bool>("Problem.PrintErrors")) + problem->printErrors(x); + using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; - std::vector<FaceSolutionVector> outputVecs; - std::vector<std::string> outputVecNames; + FaceSolutionVector numericalFaceResidualWithAnalytical; - const FaceSolutionVector& vel = x[GridGeometry::faceIdx()]; - outputVecs.push_back(vel); - outputVecNames.push_back("velocity"); + std::optional<std::array<std::vector<Scalar>, 4>> optionalPerfectInterpolationFaceResiduals; + std::array<std::vector<Scalar>, 4> perfectInterpolationFaceResiduals; + optionalPerfectInterpolationFaceResiduals.emplace(perfectInterpolationFaceResiduals); - const FaceSolutionVector& anaVel = problem->getAnalyticalFaceSolutionVector(); - outputVecs.push_back(anaVel); - outputVecNames.push_back("analyticalVelocity"); + ResidualCalc<TypeTag> residualCalc(problem); + residualCalc.calcResidualsStationary(gridGeometry, cvGridManagers, cvCenterScvfIndicesMaps, numericalCCResidualWithAnalytical, numericalFaceResidualWithAnalytical, optionalPerfectInterpolationFaceResiduals); - FaceSolutionVector absVelocityError; - absVelocityError.resize(numDofsFace); - for (unsigned int i = 0; i < vel.size(); ++i) + bool readDofBasedValues = getParam<bool>("Problem.ReadDofBasedValues", false); + if (readDofBasedValues) { - absVelocityError[i] = std::abs(vel[i] - anaVel[i]); + CellCenterSolutionVector readInPres; + readInPres.resize(gridGeometry->numCellCenterDofs()); + ReadDofBasedResult<TypeTag> reader(problem); + reader.readDofBasedResult(readInPres, "pressure"); + vtkWriter.addField(readInPres, "readInPres"); } - outputVecs.push_back(absVelocityError); - outputVecNames.push_back("absVelocityError"); - - bool startWithAnalytical = getParam<bool>("Problem.StartWithAnalytical", false); - auto resPres = ccResidualWithAnalyticalSol; - if (startWithAnalytical) - { - std::cout << "velocity residual norm = " << faceResidualWithAnalyticalSol.two_norm()/*velocity*/ << ", presssure residual norm = " << ccResidualWithAnalyticalSol.two_norm()/*pressure*/ << std::endl; - Dune::printvector(std::cout, faceResidualWithAnalyticalSol, "Residual velocities", ""); - Dune::printvector(std::cout, ccResidualWithAnalyticalSol, "Residual pressures", ""); + vtkWriter.write(1.); - outputCVResiduals<TypeTag>((*gridGeometry), faceResidualWithAnalyticalSol, *problem, outputVecs, outputVecNames); + cvOutputFacility.onCVsOutputResidualsAndPrimVars( + gridGeometry, + cvGridManagers, + paramGroups, + x, + 0, + numericalFaceResidualWithAnalytical, + optionalPerfectInterpolationFaceResiduals, + readDofBasedValues); - // write grid cells vtk output - for (const auto& element : elements((*gridGeometry).gridView())) - resPres[(*gridGeometry).gridView().indexSet().index(element)] /= element.geometry().volume(); - vtkWriter.addField(resPres, "continuityResidual"); - } - vtkWriter.write(1.0); + pvdFileInfos.push_back(std::make_pair(0, 0)); + cvOutputFacility.printPvdFiles(paramGroups, pvdFileInfos); timer.stop(); diff --git a/appl/freeflow/navierstokes/donea/params.input b/appl/freeflow/navierstokes/donea/params.input index f085f0e..19c98eb 100644 --- a/appl/freeflow/navierstokes/donea/params.input +++ b/appl/freeflow/navierstokes/donea/params.input @@ -24,10 +24,9 @@ File = grid.dgf [Problem] Name = donea # name passed to the output routines EnableGravity = false -PrintL2Error = true +PrintErrors = true EnableInertiaTerms = false StartWithAnalytical = true -AveragedAnalyticalSolution = false [ Newton ] MaxSteps = 100 diff --git a/appl/freeflow/navierstokes/donea/problem.hh b/appl/freeflow/navierstokes/donea/problem.hh index 32772fa..611eb55 100644 --- a/appl/freeflow/navierstokes/donea/problem.hh +++ b/appl/freeflow/navierstokes/donea/problem.hh @@ -30,6 +30,8 @@ #include <dumux/assembly/cvdstaggeredrefinedlocalresidual.hh> +#include <dumux/common/numeqvector.hh> + #include <dumux/material/fluidsystems/1pliquid.hh> #include <dumux/material/components/constant.hh> @@ -39,6 +41,7 @@ #include <dumux/freeflow/navierstokes/cvdfluxvariableswrapper.hh> #include <dumux/freeflow/navierstokes/myvolumevariables.hh> #include <dumux/freeflow/navierstokes/myiofields.hh> +#include <dumux/freeflow/navierstokes/model.hh> #include <dumux/discretization/method.hh> #include <dumux/discretization/staggered/myfacesolution.hh> @@ -49,7 +52,6 @@ #include <dumux/discretization/staggered/cvdfvgridgeometry.hh> #include <dumux/discretization/staggered/freeflow/cvdfvgridgeometrytraits.hh> #include <dumux/discretization/staggered/freeflow/properties.hh> -#include <dumux/freeflow/navierstokes/model.hh> #include <dumux/discretization/staggered/freeflow/myfacevariables.hh> #include <dumux/discretization/staggered/freeflow/elementvolumevariables1.hh> @@ -57,8 +59,6 @@ #include <dumux/discretization/staggered/freeflow/mygridvolumevariables.hh> #include <dumux/discretization/staggered/mygridfluxvariablescache.hh> -#include <appl/freeflow/navierstokes/l2error.hh> - namespace Dumux { template <class TypeTag> @@ -330,7 +330,7 @@ class DoneaTestProblem : public MyNavierStokesProblem<TypeTag> using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; - using NumEqVector = GetPropType<TypeTag, Properties::NumEqVector>; + using NumEqVector = Dumux::NumEqVector<GetPropType<TypeTag, Properties::PrimaryVariables>>; using ModelTraits = GetPropType<TypeTag, Properties::ModelTraits>; using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>; using Scalar = GetPropType<TypeTag, Properties::Scalar>; @@ -343,13 +343,13 @@ class DoneaTestProblem : public MyNavierStokesProblem<TypeTag> using VelocityVector = Dune::FieldVector<Scalar, dimWorld>; using FVElementGeometry = typename GridGeometry::LocalView; using SubControlVolume = typename GridGeometry::SubControlVolume; + using SubControlVolumeFace = typename GetPropType<TypeTag, Properties::GridGeometry>::SubControlVolumeFace; public: DoneaTestProblem(std::shared_ptr<const GridGeometry> gridGeometry) : ParentType(gridGeometry), eps_(1e-6) { - printL2Error_ = getParam<bool>("Problem.PrintL2Error"); - createAnalyticalSolution_(); + ParentType::createAnalyticalSolution(); mu_ = getParam<Scalar>("Component.LiquidKinematicViscosity", 1.0); } @@ -363,23 +363,7 @@ public: return false; } - void printL2Error(const SolutionVector& curSol) const - { - if(printL2Error_) - { - using L2Error = NavierStokesTestL2Error<Scalar, ModelTraits, PrimaryVariables>; - const auto l2error = L2Error::calculateL2Error(*this, curSol); - const int numCellCenterDofs = this->gridGeometry().numCellCenterDofs(); - const int numFaceDofs = this->gridGeometry().numFaceDofs(); - std::cout << std::setprecision(8) << "** L2 error (abs/rel) for " - << std::setw(6) << numCellCenterDofs << " cc dofs and " << numFaceDofs << " face dofs (total: " << numCellCenterDofs + numFaceDofs << "): " - << std::scientific - << "L2(p) = " << l2error.first[Indices::pressureIdx] << " / " << l2error.second[Indices::pressureIdx] - << " , L2(vx) = " << l2error.first[Indices::velocityXIdx] << " / " << l2error.second[Indices::velocityXIdx] - << " , L2(vy) = " << l2error.first[Indices::velocityYIdx] << " / " << l2error.second[Indices::velocityYIdx] - << std::endl; - } - } + /*! * \brief Return the temperature within the domain in [K]. @@ -452,15 +436,39 @@ public: return (isBoundary(fvGeometry) && pvIdx == Indices::pressureIdx); } - /*! - * \brief Return dirichlet boundary values at a given position + /*! + * \brief Evaluate the boundary conditions for a dirichlet + * control volume face (velocities) * - * \param globalPos The global position + * \param element The finite element + * \param scvf the sub control volume face + * + * Concerning the usage of averaged velocity, see the explanation of the initial function. The average of the nondirection velocity along an scvf is required in the context of dirichlet boundary conditions for the functions getParallelVelocityFromBoundary_ and getParallelVelocityFromOtherBoundary_ within myfluxvariables.hh. There dirichlet is called for ghost faces built from the normalFace but the value then is taken in the the direction scvf.directionIndex, which is along that normalFace. + */ + PrimaryVariables dirichlet(const Element& element, const SubControlVolumeFace& scvf) const + { + PrimaryVariables priVars(0.0); + + unsigned int dirIdx = scvf.directionIndex(); + priVars[Indices::velocity(dirIdx)] = this->analyticalVelocitySolutionAtPos(scvf); + unsigned int nonDirIdx = (dirIdx == 0)?1:0; + priVars[Indices::velocity(nonDirIdx)] = this->analyticalNonDirVelocitySolutionAtPos(scvf); + + return priVars; + } + + /*! + * \brief Evaluate the boundary conditions for a dirichlet + * control volume face (pressure) + * + * \param element The finite element + * \param scv the sub control volume */ - PrimaryVariables dirichletAtPos(const GlobalPosition& globalPos) const + PrimaryVariables dirichlet(const Element& element, const SubControlVolume& scv) const { - // use the values of the analytical solution - return this->analyticalSolution(globalPos); + PrimaryVariables priVars(0.0); + priVars[Indices::pressureIdx] = this->analyticalPressureSolutionAtPos(scv); + return priVars; } /*! @@ -470,81 +478,16 @@ public: */ PrimaryVariables analyticalSolutionAtPos(const GlobalPosition& globalPos) const { - PrimaryVariables values; - Scalar x = globalPos[0]; Scalar y = globalPos[1]; - for (unsigned int i = 0; i < values.size(); ++i) - { - values[i] = xFactorAnalyticalSolutionAtPos(x)[0][i]*yFactorAnalyticalSolutionAtPos(y)[0][i]; - } - - return values; - } - - std::array<PrimaryVariables, 2> xFactorAnalyticalSolutionAtPos(Scalar x) const - { PrimaryVariables values = {}; - values[Indices::pressureIdx] = f1_(x); - values[Indices::velocityXIdx] = f2_(x); - values[Indices::velocityYIdx] = -df2_(x); - - PrimaryVariables zero = {}; - - std::array<PrimaryVariables, 2> retPair; - retPair[0] = values; - retPair[1] = zero; - - return retPair; - } - - std::array<PrimaryVariables, 2> yFactorAnalyticalSolutionAtPos(Scalar y) const - { - PrimaryVariables values; - values[Indices::pressureIdx] = 1.; - values[Indices::velocityXIdx] = df2_(y); - values[Indices::velocityYIdx] = f2_(y); - - PrimaryVariables zero = {}; - - std::array<PrimaryVariables, 2> retPair; - retPair[0] = values; - retPair[1] = zero; - - return retPair; - } - - std::array<PrimaryVariables, 2> xFactorAnalyticalSolutionAntiderivativeAtPos(Scalar x) const - { - PrimaryVariables values; - values[Indices::pressureIdx] = intf1_(x); - values[Indices::velocityXIdx] = intf2_(x); - values[Indices::velocityYIdx] = -f2_(x); - - PrimaryVariables zero = {}; - - std::array<PrimaryVariables, 2> retPair; - retPair[0] = values; - retPair[1] = zero; - - return retPair; - } - - std::array<PrimaryVariables, 2> yFactorAnalyticalSolutionAntiderivativeAtPos(Scalar y) const - { - PrimaryVariables values; - values[Indices::pressureIdx] = y; - values[Indices::velocityXIdx] = f2_(y); - values[Indices::velocityYIdx] = intf2_(y); - PrimaryVariables zero = {}; - - std::array<PrimaryVariables, 2> retPair; - retPair[0] = values; - retPair[1] = zero; + values[Indices::pressureIdx] = f1_(x); + values[Indices::velocityXIdx] = f2_(x)*df2_(y); + values[Indices::velocityYIdx] = -df2_(x)*f2_(y); - return retPair; + return values; } // \} @@ -554,71 +497,71 @@ public: */ // \{ - /*! - * \brief Evaluate the initial value for a control volume. + /*! + * \brief Evaluates the initial value for a sub control volume face (velocities) * - * \param globalPos The global position + * Simply assigning the value of the analytical solution at the face center + * gives a discrete solution that is not divergence-free. For small initial + * time steps, this has a negative impact on the pressure solution + * after the first time step. The flag UseVelocityAveraging triggers the + * function averagedVelocity_ which uses a higher order quadrature formula to + * bring the discrete solution sufficiently close to being divergence-free. */ - PrimaryVariables initialAtPos(const GlobalPosition& globalPos) const + PrimaryVariables initial(const SubControlVolumeFace& scvf) const { bool startWithAnalytical = getParam<bool>("Problem.StartWithAnalytical", false); if (startWithAnalytical) - return this->analyticalSolution(globalPos); - - PrimaryVariables values; - values[Indices::pressureIdx] = 0.0; - values[Indices::velocityXIdx] = 0.0; - values[Indices::velocityYIdx] = 0.0; - - return values; - } + { + PrimaryVariables priVars(0.0); + priVars[Indices::velocity(scvf.directionIndex())] = this->analyticalVelocitySolutionAtPos(scvf); + return priVars; + } + else + { + PrimaryVariables values; + values[Indices::pressureIdx] = 0.0; + values[Indices::velocityXIdx] = 0.0; + values[Indices::velocityYIdx] = 0.0; - /*! - * \brief Returns the analytical solution for the pressure - */ - auto& getAnalyticalPressureSolution() const - { - return analyticalPressure_; + return values; + } } - /*! - * \brief Returns the analytical solution for the velocity + /*! + * \brief Evaluates the initial value for a control volume (pressure) */ - auto& getAnalyticalVelocitySolution() const + PrimaryVariables initial(const SubControlVolume& scv) const { - return analyticalVelocity_; - } + bool startWithAnalytical = getParam<bool>("Problem.StartWithAnalytical", false); - /*! - * \brief Returns the analytical solution for the velocity at the faces - */ - auto& getAnalyticalVelocitySolutionOnFace() const - { - return analyticalVelocityOnFace_; - } + if (startWithAnalytical) + { + PrimaryVariables priVars(0.0); + priVars[Indices::pressureIdx] = this->analyticalPressureSolutionAtPos(scv); + return priVars; + } + else + { + PrimaryVariables values; + values[Indices::pressureIdx] = 0.0; + values[Indices::velocityXIdx] = 0.0; + values[Indices::velocityYIdx] = 0.0; - auto& getAnalyticalFaceSolutionVector() const - { - return analyticalFaceSolutionVector_; + return values; + } } private: Scalar f1_(Scalar x) const { return x*(1.0-x); /*x - x^2*/ } - Scalar intf1_(Scalar x) const - { return .5*x*x - 1./3*x*x*x; } - Scalar df1_(Scalar x) const { return 1.0 - 2.0*x; } Scalar f2_(Scalar x) const { return f1_(x)*f1_(x); /*=x^2*(1-2x+x^2)=x^2-2x^3+x^4*/ } - Scalar intf2_(Scalar x) const - { return .2*x*x*x*x*x - .5*x*x*x*x + 1./3*x*x*x; } - Scalar df2_(Scalar x) const { return 2.0*x - 6.0*x*x + 4.0*x*x*x; } @@ -658,51 +601,7 @@ private: Scalar dxxV_ (Scalar x, Scalar y) const { return -f2_(y)*dddf2_(x); } - /*! - * \brief Adds additional VTK output data to the VTKWriter. Function is called by the output module on every write. - */ - void createAnalyticalSolution_() - { - analyticalPressure_.resize(this->gridGeometry().numCellCenterDofs()); - analyticalVelocity_.resize(this->gridGeometry().numCellCenterDofs()); - analyticalVelocityOnFace_.resize(this->gridGeometry().numFaceDofs()); - analyticalFaceSolutionVector_.resize(this->gridGeometry().numFaceDofs()); - - for (const auto& element : elements(this->gridGeometry().gridView())) - { - auto fvGeometry = localView(this->gridGeometry()); - fvGeometry.bindElement(element); - for (auto&& scv : scvs(fvGeometry)) - { - auto ccDofIdx = scv.dofIndex(); - auto ccDofPosition = scv.dofPosition(); - auto analyticalSolutionAtCc = this->analyticalSolution(ccDofPosition); - - // velocities on faces - for (auto&& scvf : scvfs(fvGeometry)) - { - const auto faceDofIdx = scvf.dofIndex(); - const auto faceDofPosition = scvf.center(); - const auto dirIdx = scvf.directionIndex(); - const auto analyticalSolutionAtFace = this->analyticalSolution(faceDofPosition); - analyticalVelocityOnFace_[faceDofIdx][dirIdx] = analyticalSolutionAtFace[Indices::velocity(dirIdx)]; - analyticalFaceSolutionVector_[faceDofIdx] = analyticalSolutionAtFace[Indices::velocity(dirIdx)]; - } - - analyticalPressure_[ccDofIdx] = analyticalSolutionAtCc[Indices::pressureIdx]; - - for(int dirIdx = 0; dirIdx < ModelTraits::dim(); ++dirIdx) - analyticalVelocity_[ccDofIdx][dirIdx] = analyticalSolutionAtCc[Indices::velocity(dirIdx)]; - } - } - } - Scalar eps_; - bool printL2Error_; - std::vector<Scalar> analyticalPressure_; - std::vector<VelocityVector> analyticalVelocity_; - std::vector<VelocityVector> analyticalVelocityOnFace_; - FaceSolutionVector analyticalFaceSolutionVector_; Scalar mu_; }; } //end namespace -- GitLab From fe2a78501f7e478a9d4cf1a90117700d66644955 Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Fri, 10 Sep 2021 11:54:04 +0300 Subject: [PATCH 02/69] Residual calc --- .../navierstokes/staggered/cvdResidualCalc.hh | 938 ++++++++++++++++++ ...dresidualCalc.hh => cvdresidualCalcOld.hh} | 0 2 files changed, 938 insertions(+) create mode 100644 dumux/freeflow/navierstokes/staggered/cvdResidualCalc.hh rename dumux/freeflow/navierstokes/staggered/{cvdresidualCalc.hh => cvdresidualCalcOld.hh} (100%) diff --git a/dumux/freeflow/navierstokes/staggered/cvdResidualCalc.hh b/dumux/freeflow/navierstokes/staggered/cvdResidualCalc.hh new file mode 100644 index 0000000..58e4553 --- /dev/null +++ b/dumux/freeflow/navierstokes/staggered/cvdResidualCalc.hh @@ -0,0 +1,938 @@ +// -*- 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 3 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 + * \ingroup NavierStokesModel + */ + +#ifndef DUMUX_NAVIERSTOKES_STAGGERED_RESIDUALCALC_HH +#define DUMUX_NAVIERSTOKES_STAGGERED_RESIDUALCALC_HH + +#include <dumux/common/timeloop.hh> +#include <dune/grid/io/file/vtk/vtkwriter.hh> +#include <dumux/io/grid/cvdcontrolvolumegrids.hh> +#include <dumux/discretization/staggered/freeflow/geometryhelper/cvdstaggeredgeometryhelper.hh> +#include <dumux/discretization/staggered/freeflow/cvdffsubcontrolvolumeface.hh> +#include <dumux/freeflow/navierstokes/analyticalSolutionIntegration.hh> + +namespace Dumux{ + namespace Properties { + template<class TypeTag, class MyTypeTag> + struct CVGridGeometry { using type = UndefinedProperty; }; + } + +template<class TypeTag> +class ResidualCalc +{ + using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; + using SubControlVolumeFace = typename GridGeometry::SubControlVolumeFace; + using GridView = typename GridGeometry::GridView; + using Scalar = GetPropType<TypeTag, Properties::Scalar>; + using MLGTraits = typename MyFreeFlowStaggeredDefaultScvfGeometryTraits<GridView>::template ScvfMLGTraits<Scalar> ; + + using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; + using Element = typename GridGeometry::GridView::template Codim<0>::Entity; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + using Problem = GetPropType<TypeTag, Properties::Problem>; + + using HostGrid = Dune::ALUGrid<2,2,Dune::cube,Dune::nonconforming >; + using HostGridManager = GridManager<HostGrid>; + using CVGridGeometry = GetPropType<TypeTag, Properties::CVGridGeometry>; + + using SolutionVector = GetPropType<TypeTag, Properties::SolutionVector>; + using CellCenterSolutionVector = GetPropType<TypeTag, Properties::CellCenterSolutionVector>; + using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; + + using GridVariables = GetPropType<TypeTag, Properties::GridVariables>; + using Assembler = StaggeredRefinedFVAssembler<TypeTag, DiffMethod::numeric>; + +public: + /*! + * \brief The Constructor + */ + ResidualCalc(std::shared_ptr<const Problem> problem) + : problem_(problem) + {} + + void calcResidualsStationary(std::shared_ptr<const GridGeometry> gridGeometry, + std::array<HostGridManager, 4>& cvGridManagers, + const std::array<std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>>,4>& cvCenterScvfIndicesMaps, + CellCenterSolutionVector& cellCenterResidualWithAnalyticalSol, + FaceSolutionVector& faceResidualWithAnalyticalSol, + std::optional<std::array<std::vector<Scalar>, 4>>& perfectInterpolationFaceResiduals) const + { + if (perfectInterpolationFaceResiduals) + *perfectInterpolationFaceResiduals = calcPerfectInterpolationFaceResidual_( + [&] (const GlobalPosition& globalPos, Scalar time) { return problem_->analyticalSolutionAtPos (globalPos); }, + [&] (const GlobalPosition& globalPos, Scalar time) { return problem_->sourceAtPos (globalPos); }, + true, + 0., + 0., + cvGridManagers, + cvCenterScvfIndicesMaps); + + SolutionVector numericalResidual = calcNumericalResidualStationary_(gridGeometry); + + FaceSolutionVector areaWeightedFaceResidualWithAnalyticalSol = numericalResidual[GridGeometry::faceIdx()]; + std::cout << "velocity residual norm = " << areaWeightedFaceResidualWithAnalyticalSol.two_norm() << std::endl; + faceResidualWithAnalyticalSol = areaWeightedToNonAreaWeightedFaceVec_(areaWeightedFaceResidualWithAnalyticalSol); + + CellCenterSolutionVector areaWeightedCCResidualWithAnalyticalSol = numericalResidual[GridGeometry::cellCenterIdx()]; + std::cout << "presssure residual norm = " << areaWeightedCCResidualWithAnalyticalSol.two_norm() << std::endl; + cellCenterResidualWithAnalyticalSol = areaWeightedToNonAreaWeightedCCVec_(areaWeightedCCResidualWithAnalyticalSol); + } + + void calcResidualsInstationary(std::shared_ptr<const TimeLoop<Scalar>> timeLoop, + std::shared_ptr<const GridGeometry> gridGeometry, + std::array<HostGridManager, 4>& cvGridManagers, + const std::array<std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>>,4>& cvCenterScvfIndicesMaps, + CellCenterSolutionVector& cellCenterResidualWithAnalyticalSol, + FaceSolutionVector& faceResidualWithAnalyticalSol, + std::optional<std::array<std::vector<Scalar>, 4>>& perfectInterpolationFaceResiduals) const + { + Scalar t = timeLoop->time()+timeLoop->timeStepSize(); + Scalar tOld = timeLoop->time(); + + if (perfectInterpolationFaceResiduals) + *perfectInterpolationFaceResiduals = calcPerfectInterpolationFaceResidual_( + [&] (const GlobalPosition& globalPos, Scalar time) { return problem_->instationaryAnalyticalSolutionAtPos (globalPos, time); }, + [&] (const GlobalPosition& globalPos, Scalar time) { return problem_->instationarySourceAtPos (globalPos, time); }, + false, + t, + tOld, + cvGridManagers, + cvCenterScvfIndicesMaps); + + SolutionVector numericalResidual = calcNumericalResidualInstationary_(gridGeometry, timeLoop, t, tOld); + + FaceSolutionVector areaWeightedFaceResidualWithAnalyticalSol = numericalResidual[GridGeometry::faceIdx()]; + std::cout << "velocity residual norm = " << areaWeightedFaceResidualWithAnalyticalSol.two_norm() << std::endl; + faceResidualWithAnalyticalSol = areaWeightedToNonAreaWeightedFaceVec_(areaWeightedFaceResidualWithAnalyticalSol); + + CellCenterSolutionVector areaWeightedCCResidualWithAnalyticalSol = numericalResidual[GridGeometry::cellCenterIdx()]; + std::cout << "presssure residual norm = " << areaWeightedCCResidualWithAnalyticalSol.two_norm() << std::endl; + cellCenterResidualWithAnalyticalSol = areaWeightedToNonAreaWeightedCCVec_(areaWeightedCCResidualWithAnalyticalSol); + } + +private: + template <class Vec> + auto areaWeightedToNonAreaWeightedFaceVec_(const Vec& areaWeightedVec) const + { + Dune::BlockVector<Dune::FieldVector<Scalar, 1>, std::allocator<Dune::FieldVector<Scalar, 1> > > resVel; + resVel = areaWeightedVec; + + auto cvAreas = resVel; + cvAreas = 0.; + + for (const auto& element : elements((*problem_).gridGeometry().gridView())) + { + auto fvGeometry = localView((*problem_).gridGeometry()); + fvGeometry.bindElement(element); + for (const auto& scvf : scvfs(fvGeometry)) + { + cvAreas[scvf.dofIndex()] += (scvf.area() * 0.5 * scvf.selfToOppositeDistance()); + } + } + + for (int i = 0; i < resVel.size(); ++i) + { + resVel[i] /= cvAreas[i]; + } + + return resVel; + } + + template <class Vec> + auto areaWeightedToNonAreaWeightedCCVec_(const Vec& areaWeightedVec) const + { + CellCenterSolutionVector resVec; + resVec = areaWeightedVec; + + for (const auto& element : elements((*problem_).gridGeometry().gridView())) + resVec[(*problem_).gridGeometry().gridView().indexSet().index(element)] /= element.geometry().volume(); + + return resVec; + } + + template<class LambdaA, class LambdaB> + std::array<std::vector<Scalar>,4> calcPerfectInterpolationFaceResidual_( + const LambdaA& possiblyInstationaryAnalyticalSolution, + const LambdaB& possiblyInstationarySourceAtPos, + bool isStationary, + Scalar t, + Scalar tOld, + std::array<HostGridManager, 4>& gridManagers, + const std::array<std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>>,4>& cvCenterScvfIndicesMaps) const + { + std::array<std::vector<Scalar>,4> retArray; + + fillResidual_(possiblyInstationaryAnalyticalSolution, possiblyInstationarySourceAtPos, isStationary, t, tOld, retArray[0], gridManagers[0].grid().leafGridView(), cvCenterScvfIndicesMaps[0], 0, false); + fillResidual_(possiblyInstationaryAnalyticalSolution, possiblyInstationarySourceAtPos, isStationary, t, tOld, retArray[1], gridManagers[1].grid().leafGridView(), cvCenterScvfIndicesMaps[1], 1, false); + fillResidual_(possiblyInstationaryAnalyticalSolution, possiblyInstationarySourceAtPos, isStationary, t, tOld, retArray[2], gridManagers[2].grid().leafGridView(), cvCenterScvfIndicesMaps[2], 0, true); + fillResidual_(possiblyInstationaryAnalyticalSolution, possiblyInstationarySourceAtPos, isStationary, t, tOld, retArray[3], gridManagers[3].grid().leafGridView(), cvCenterScvfIndicesMaps[3], 1, true); + + return retArray; + } + + SolutionVector calcNumericalResidualInstationary_(std::shared_ptr<const GridGeometry> gridGeometry, std::shared_ptr<const TimeLoop<Scalar>> timeLoop, Scalar t, Scalar tOld) const + { + const auto analyticalTPlusDeltaTTuple = problem_->getAnalyticalSolution(t); + const auto analyticalTTuple = problem_->getAnalyticalSolution(tOld); + + SolutionVector analyticalTPlusDeltaT; + analyticalTPlusDeltaT[GridGeometry::faceIdx()] = std::get<3>(analyticalTPlusDeltaTTuple); + analyticalTPlusDeltaT[GridGeometry::cellCenterIdx()] = std::get<0>(analyticalTPlusDeltaTTuple); + + SolutionVector analyticalT; + analyticalT[GridGeometry::faceIdx()] = std::get<3>(analyticalTTuple); + analyticalT[GridGeometry::cellCenterIdx()] = std::get<0>(analyticalTTuple); + + auto localGridVariables = std::make_shared<GridVariables>(problem_, gridGeometry); + localGridVariables->init(analyticalT); + localGridVariables->update(analyticalTPlusDeltaT); + + const auto numDofsCellCenter = gridGeometry->numCellCenterDofs(); + const auto numDofsFace = gridGeometry->numIntersections(); + + SolutionVector residual; + residual[GridGeometry::cellCenterIdx()].resize(numDofsCellCenter); + residual[GridGeometry::faceIdx()].resize(numDofsFace); + + Assembler localAssemblerObject(problem_, gridGeometry, localGridVariables, timeLoop, analyticalT); + localAssemblerObject.assembleResidual(residual, analyticalTPlusDeltaT); + + return residual; + } + + SolutionVector calcNumericalResidualStationary_(std::shared_ptr<const GridGeometry> gridGeometry) const + { + const auto analyticalTuple = problem_->getAnalyticalSolution(); + + SolutionVector analytical; + analytical[GridGeometry::faceIdx()] = std::get<3>(analyticalTuple); + analytical[GridGeometry::cellCenterIdx()] = std::get<0>(analyticalTuple); + + auto localGridVariables = std::make_shared<GridVariables>(problem_, gridGeometry); + localGridVariables->init(analytical); + + const auto numDofsCellCenter = gridGeometry->numCellCenterDofs(); + const auto numDofsFace = gridGeometry->numIntersections(); + + SolutionVector residual; + residual[GridGeometry::cellCenterIdx()].resize(numDofsCellCenter); + residual[GridGeometry::faceIdx()].resize(numDofsFace); + + Assembler localAssemblerObject(problem_, gridGeometry, localGridVariables); + localAssemblerObject.assembleResidual(residual, analytical); + + return residual; + } + + Scalar residual_(bool isStationary, Scalar velSelfOld, Scalar deltaT, Scalar leftOrDownOppoDelta, Scalar rightOrUpOppoDelta, Scalar rightOrUpLateralDelta, Scalar scvfDelta, Scalar leftOrDownLateralDelta, Scalar q, Scalar velSelf, Scalar velParallelRightOrUp, Scalar velParallelLeftOrDown, Scalar velOppoRightOrUp, Scalar velOppoLeftOrDown, Scalar velNormalUpRightOrRightUp, Scalar velNormalUpLeftOrRightDown, Scalar velNormalDownRightOrLeftUp, Scalar velNormalDownLeftOrLeftDown, Scalar presLeftOrDown, Scalar presRightOrUp, bool navierStokes, Scalar viscosity) const + { + Scalar opposDelta = .5 * (leftOrDownOppoDelta + rightOrUpOppoDelta); + Scalar density = 1.; //can only deal with constant viscosity here + + Scalar res = -q*opposDelta * scvfDelta + + ( 2*opposDelta/(rightOrUpLateralDelta+scvfDelta) + 2*opposDelta/(leftOrDownLateralDelta+scvfDelta) + 2*scvfDelta/leftOrDownOppoDelta + 2*scvfDelta/rightOrUpOppoDelta ) * viscosity * velSelf + + ( -2*opposDelta/(rightOrUpLateralDelta+scvfDelta)) * viscosity * velParallelRightOrUp + + ( -2*opposDelta/(leftOrDownLateralDelta+scvfDelta) ) * viscosity * velParallelLeftOrDown + + ( -2*scvfDelta/leftOrDownOppoDelta ) * viscosity * velOppoLeftOrDown + + ( -2*scvfDelta/rightOrUpOppoDelta ) * viscosity * velOppoRightOrUp + - velNormalUpRightOrRightUp * viscosity + + velNormalUpLeftOrRightDown * viscosity + + velNormalDownRightOrLeftUp * viscosity + - velNormalDownLeftOrLeftDown * viscosity + - scvfDelta* presLeftOrDown + + scvfDelta * presRightOrUp; + + // std::cout << "source " << -q*opposDelta * scvfDelta; + // std::cout << ", self " << ( 2*opposDelta/(rightOrUpLateralDelta+scvfDelta) + 2*opposDelta/(leftOrDownLateralDelta+scvfDelta) + 2*scvfDelta/leftOrDownOppoDelta + 2*scvfDelta/rightOrUpOppoDelta ) * viscosity * velSelf; + // std::cout << ", parallel a " << ( -2*opposDelta/(rightOrUpLateralDelta+scvfDelta)) * viscosity * velParallelRightOrUp; + // std::cout << ", prallel b " << ( -2*opposDelta/(leftOrDownLateralDelta+scvfDelta) ) * viscosity * velParallelLeftOrDown; + // std::cout << ", oppo a " << ( -2*scvfDelta/leftOrDownOppoDelta ) * viscosity * velOppoLeftOrDown; + // std::cout << ", oppo b " << ( -2*scvfDelta/rightOrUpOppoDelta ) * viscosity * velOppoRightOrUp; + // std::cout << ", normal a " << - velNormalUpRightOrRightUp * viscosity; + // std::cout << ", normal b " << velNormalUpLeftOrRightDown * viscosity; + // std::cout << ", normal c " << velNormalDownRightOrLeftUp * viscosity; + // std::cout << ", normal d " << - velNormalDownLeftOrLeftDown * viscosity; + // std::cout << ", pressure a " << - scvfDelta* presLeftOrDown; + // std::cout << ", pressure b " << scvfDelta * presRightOrUp; + // std::cout << std::endl; + + // std::cout << "res = " << res << std::endl; + // + // std::cout << "opposDelta * scvfDelta = " << opposDelta * scvfDelta << std::endl; + // + // std::cout << "d_y u term: " << + // ((2/(rightOrUpLateralDelta+scvfDelta) + 2/(leftOrDownLateralDelta+scvfDelta))/(scvfDelta)* velSelf + // + ( -2/(rightOrUpLateralDelta+scvfDelta))/(scvfDelta) * velParallelRightOrUp + // + ( -2/(leftOrDownLateralDelta+scvfDelta))/(scvfDelta) * velParallelLeftOrDown) << std::endl; + + // Scalar selfCoefficient = ((leftOrDownLateralDelta+scvfDelta)/(2.*scvfDelta)+(rightOrUpLateralDelta+scvfDelta)/(2.*scvfDelta))/(((rightOrUpLateralDelta+scvfDelta)/2.)*((leftOrDownLateralDelta+scvfDelta)/2.))*scvfDelta*scvfDelta; + // Scalar upCoefficient = (leftOrDownLateralDelta+scvfDelta)/(2.*scvfDelta)/(((rightOrUpLateralDelta+scvfDelta)/2.)*((leftOrDownLateralDelta+scvfDelta)/2.))*scvfDelta*scvfDelta; + // Scalar downCoefficient = (rightOrUpLateralDelta+scvfDelta)/(2.*scvfDelta)/(((rightOrUpLateralDelta+scvfDelta)/2.)*((leftOrDownLateralDelta+scvfDelta)/2.))*scvfDelta*scvfDelta; + + // std::cout << "selfCoefficient " << selfCoefficient << ", upCoefficient = " << upCoefficient << ", downCoefficient = " << downCoefficient << std::endl; + + // std::cout << "var d_y u term: " << + // (selfCoefficient*velSelf + // -upCoefficient*velParallelRightOrUp + // -downCoefficient*velParallelLeftOrDown) + // /(scvfDelta*scvfDelta) + // << std::endl; + // + // std::cout << "pressure term: " << (- scvfDelta* presLeftOrDown + scvfDelta * presRightOrUp)/(opposDelta * scvfDelta) << std::endl; + + if (navierStokes) + { + auto mixedVelocity = [&](Scalar upwindVelocity, Scalar downwindVelocity) + { + Scalar upwindWeight = Dumux::getParam<Scalar>("Flux.UpwindWeight", 1.); + return upwindWeight * upwindVelocity + (1. - upwindWeight) * downwindVelocity; + }; + + //x:left, y: down + Scalar transportingVelocity = (velSelf + velOppoLeftOrDown) * 0.5; + Scalar upwindVelocity = (Dumux::sign(transportingVelocity) == +1) ? velOppoLeftOrDown : velSelf; + Scalar downwindVelocity = (Dumux::sign(transportingVelocity) == +1) ? velSelf : velOppoLeftOrDown; + + res -= scvfDelta * density * transportingVelocity * mixedVelocity(upwindVelocity,downwindVelocity); + + //x:right, y: up + transportingVelocity = (velSelf + velOppoRightOrUp) * 0.5; + upwindVelocity = (Dumux::sign(transportingVelocity) == +1) ? velSelf : velOppoRightOrUp; + downwindVelocity = (Dumux::sign(transportingVelocity) == +1) ? velOppoRightOrUp : velSelf; + + res += scvfDelta * density * transportingVelocity * mixedVelocity(upwindVelocity,downwindVelocity); + + //x:upright, y: rightup + if (rightOrUpLateralDelta == 0.) + { + upwindVelocity = velParallelRightOrUp; + downwindVelocity = velParallelRightOrUp; + } + else + { + upwindVelocity = (Dumux::sign(velNormalUpRightOrRightUp)==+1) ? velSelf : velParallelRightOrUp; + downwindVelocity = (Dumux::sign(velNormalUpRightOrRightUp)==+1) ? velParallelRightOrUp : velSelf; + } + + res += .25 * (leftOrDownOppoDelta+rightOrUpOppoDelta) * density * mixedVelocity(upwindVelocity,downwindVelocity) * velNormalUpRightOrRightUp; + + //x: downright, y: leftup + if (leftOrDownLateralDelta == 0.) + { + upwindVelocity = velParallelLeftOrDown; + downwindVelocity = velParallelLeftOrDown; + } + else + { + upwindVelocity = (Dumux::sign(velNormalDownRightOrLeftUp)==+1) ? velParallelLeftOrDown : velSelf; + downwindVelocity = (Dumux::sign(velNormalDownRightOrLeftUp)==+1) ? velSelf : velParallelLeftOrDown; + } + + res -= .25 * (leftOrDownOppoDelta+rightOrUpOppoDelta) * density * mixedVelocity(upwindVelocity,downwindVelocity) * velNormalDownRightOrLeftUp; + + //x:upleft, y: rightdown + if (rightOrUpLateralDelta == 0.) + { + downwindVelocity = velParallelRightOrUp; + upwindVelocity = velParallelRightOrUp; + } + else + { + downwindVelocity = (Dumux::sign(velNormalUpLeftOrRightDown)==+1) ? velParallelRightOrUp : velSelf; + upwindVelocity = (Dumux::sign(velNormalUpLeftOrRightDown)==+1) ? velSelf : velParallelRightOrUp; + } + + res += .25 * (leftOrDownOppoDelta+rightOrUpOppoDelta)* density * mixedVelocity(upwindVelocity,downwindVelocity) * velNormalUpLeftOrRightDown; + + //x:downleft, y: leftdown + if (leftOrDownLateralDelta == 0.) + { + upwindVelocity = velParallelLeftOrDown; + downwindVelocity = velParallelLeftOrDown; + } + else + { + upwindVelocity = (Dumux::sign(velNormalDownLeftOrLeftDown)==+1) ? velParallelLeftOrDown : velSelf; + downwindVelocity = (Dumux::sign(velNormalDownLeftOrLeftDown)==+1) ? velSelf : velParallelLeftOrDown; + } + + res -= .25 * (leftOrDownOppoDelta+rightOrUpOppoDelta) * density * mixedVelocity(upwindVelocity,downwindVelocity) * velNormalDownLeftOrLeftDown; + } + + if (!isStationary) + { + res += (velSelf - velSelfOld) / deltaT * opposDelta * scvfDelta; + } + + // std::cout << "final res = " << res/(opposDelta * scvfDelta) << std::endl; + + return res/(opposDelta * scvfDelta); //that should be the one relevant for grid convergence + } + + template <class LambdaA> + Scalar possiblyInstationaryPossiblyMeanAnalyticalVelocityySolutionAtPos_(const LambdaA& possiblyInstationaryAnalyticalSolution, const std::array<GlobalPosition, 2>& corners, unsigned int dirIdx, Scalar t) const + { + if ((*problem_).useScvfLineAveraging() ) + { + AnalyticalSolutionIntegration<TypeTag, MLGTraits> analyticalSolInt((*problem_).quadOrder()); + auto lineGeo = analyticalSolInt.getLineGeometry(corners); + return analyticalSolInt.lineIntegral(lineGeo, [&](const GlobalPosition& globalPos) { return possiblyInstationaryAnalyticalSolution(globalPos,t)[Indices::velocity(dirIdx)]; }); + } + else if ((*problem_).useScvfCVAveraging() ) + { + DUNE_THROW(Dune::InvalidStateException, "Residual calc can only do line averaging for scvf."); + } + else + { + GlobalPosition center = corners[0]+corners[1]; + center *= 0.5; + return possiblyInstationaryAnalyticalSolution(center,t)[Indices::velocity(dirIdx)]; + } + } + + template <class LambdaA> + Scalar analyticalXVelocityBetweenCorners_ (const LambdaA& possiblyInstationaryAnalyticalSolution, const std::array<GlobalPosition, 2>& corners, Scalar time) const + { + return possiblyInstationaryPossiblyMeanAnalyticalVelocityySolutionAtPos_(possiblyInstationaryAnalyticalSolution, corners, 0, time); + } + + template <class LambdaA> + Scalar analyticalYVelocityBetweenCorners_ (const LambdaA& possiblyInstationaryAnalyticalSolution, const std::array<GlobalPosition, 2>& corners, Scalar time) const + { + return possiblyInstationaryPossiblyMeanAnalyticalVelocityySolutionAtPos_(possiblyInstationaryAnalyticalSolution, corners, 1, time); + } + + template <class LambdaA> + Scalar possiblyInstationaryAnalyticalPressureAtPos_ (const LambdaA& possiblyInstationaryAnalyticalSolution, const GlobalPosition& globalPos, Scalar time) const + { + if ((*problem_).useScvVolumeAveraging()) + DUNE_THROW(Dune::InvalidStateException, "Residual calc can only do no averaging for scv."); + + return possiblyInstationaryAnalyticalSolution(globalPos,time)[Indices::pressureIdx]; + } + + template <class LambdaA, class LambdaB> + Scalar momentumXResidual_(const LambdaA& possiblyInstationaryAnalyticalSolution, const LambdaB& possiblyInstationarySourceAtPos, bool isStationary, Scalar t, Scalar tOld, Scalar x, Scalar y, Scalar leftOppoDelta, Scalar rightOppoDelta, Scalar upLateralDelta, Scalar scvfDelta, Scalar downLateralDelta) const + { + // std::cout << "x= " << x << ", y = " << y << ", leftOppoDelta = " << leftOppoDelta << ", rightOppoDelta = " << rightOppoDelta << ", upLateralDelta = " << upLateralDelta << ", scvfDelta = " << scvfDelta << ", downLateralDelta = " << downLateralDelta << std::endl; + std::array<GlobalPosition, 2> selfCorners, parallelUpCorners, parallelDownCorners, oppoRightCorners, oppoLeftCorners, normalUpRightCorners, normalUpLeftCorners, normalDownRightCorners, normalDownLeftCorners; + + selfCorners[0] = {x,y-0.5*scvfDelta}; + selfCorners[1] = {x,y+0.5*scvfDelta}; + + parallelUpCorners [0] = {x, y+.5*scvfDelta}; + parallelUpCorners [1] = {x, y+.5*scvfDelta+upLateralDelta}; + parallelDownCorners [0] = {x, y-.5*scvfDelta-downLateralDelta}; + parallelDownCorners [1] = {x, y-.5*scvfDelta}; + oppoRightCorners [0] = {x+rightOppoDelta, y-0.5*scvfDelta}; + oppoRightCorners [1] = {x+rightOppoDelta, y+0.5*scvfDelta}; + oppoLeftCorners [0] = {x-leftOppoDelta, y-0.5*scvfDelta}; + oppoLeftCorners [1] = {x-leftOppoDelta, y+0.5*scvfDelta}; + + normalUpRightCorners[0] = {x, y+.5*scvfDelta}; + normalUpRightCorners[1] = {x+rightOppoDelta, y+.5*scvfDelta}; + normalUpLeftCorners[0] = {x-leftOppoDelta, y+.5*scvfDelta}; + normalUpLeftCorners[1] = {x, y+.5*scvfDelta}; + normalDownRightCorners[0] = {x, y-.5*scvfDelta}; + normalDownRightCorners[1] = {x+rightOppoDelta, y-.5*scvfDelta}; + normalDownLeftCorners [0] = {x-leftOppoDelta, y-.5*scvfDelta}; + normalDownLeftCorners [1] = {x, y-.5*scvfDelta}; + + Scalar deltaT = t-tOld; + Scalar q = possiblyInstationarySourceAtPos({x,y},t)[Indices::momentumXBalanceIdx]; + + Scalar velSelfOld = isStationary? 0. : analyticalXVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, selfCorners, tOld); + Scalar velSelf = analyticalXVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, selfCorners, t); + + Scalar velParallelRightOrUp = analyticalXVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, parallelUpCorners, t); + Scalar velParallelLeftOrDown = analyticalXVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, parallelDownCorners, t); + Scalar velOppoRightOrUp = analyticalXVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, oppoRightCorners, t); + Scalar velOppoLeftOrDown = analyticalXVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, oppoLeftCorners, t); + + Scalar velNormalUpRightOrRightUp = analyticalYVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, normalUpRightCorners, t); + Scalar velNormalUpLeftOrRightDown = analyticalYVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, normalUpLeftCorners, t); + Scalar velNormalDownRightOrLeftUp = analyticalYVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, normalDownRightCorners, t); + Scalar velNormalDownLeftOrLeftDown = analyticalYVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, normalDownLeftCorners, t); + + Scalar presLeftOrDown = possiblyInstationaryAnalyticalPressureAtPos_(possiblyInstationaryAnalyticalSolution, {x-0.5*leftOppoDelta,y},t); + Scalar presRightOrUp = possiblyInstationaryAnalyticalPressureAtPos_(possiblyInstationaryAnalyticalSolution, {x+0.5*rightOppoDelta,y},t); + + bool navierStokes = getParam<bool>("Problem.EnableInertiaTerms"); + Scalar viscosity = getParam<Scalar>("Component.LiquidKinematicViscosity"); + + return residual_(isStationary, + velSelfOld, + deltaT, + leftOppoDelta, + rightOppoDelta, + upLateralDelta, + scvfDelta, + downLateralDelta, + q, + velSelf, + velParallelRightOrUp, + velParallelLeftOrDown, + velOppoRightOrUp, + velOppoLeftOrDown, + velNormalUpRightOrRightUp, + velNormalUpLeftOrRightDown, + velNormalDownRightOrLeftUp, + velNormalDownLeftOrLeftDown, + presLeftOrDown, + presRightOrUp, + navierStokes, + viscosity); + } + + template <class LambdaA, class LambdaB> + Scalar momentumYResidual_(const LambdaA& possiblyInstationaryAnalyticalSolution, const LambdaB& possiblyInstationarySourceAtPos, bool isStationary, Scalar t, Scalar tOld, Scalar x, Scalar y, Scalar downOppoDelta, Scalar upOppoDelta, Scalar rightLateralDelta, Scalar scvfDelta, Scalar leftLateralDelta) const + { + std::array<GlobalPosition, 2> selfCorners, parallelRightCorners, parallelLeftCorners, oppoUpCorners, oppoDownCorners, normalRightUpCorners, normalRightDownCorners, normalLeftUpCorners, normalLeftDownCorners; + + selfCorners[0] = {x-0.5*scvfDelta,y}; + selfCorners[1] = {x+0.5*scvfDelta,y}; + + parallelRightCorners[0] = {x+.5*scvfDelta, y}; + parallelRightCorners[1] = {x+.5*scvfDelta+rightLateralDelta, y}; + parallelLeftCorners [0] = {x-.5*scvfDelta-leftLateralDelta, y}; + parallelLeftCorners [1] = {x-.5*scvfDelta, y}; + oppoUpCorners [0] = {x-0.5*scvfDelta, y+upOppoDelta}; + oppoUpCorners [1] = {x+0.5*scvfDelta, y+upOppoDelta}; + oppoDownCorners [0] = {x-0.5*scvfDelta, y-downOppoDelta}; + oppoDownCorners [1] = {x+0.5*scvfDelta, y-downOppoDelta}; + + normalRightUpCorners [0] = {x+.5*scvfDelta, y}; + normalRightUpCorners [1] = {x+.5*scvfDelta, y+upOppoDelta}; + normalRightDownCorners[0] = {x+.5*scvfDelta, y-downOppoDelta}; + normalRightDownCorners[1] = {x+.5*scvfDelta, y}; + normalLeftUpCorners [0] = {x-.5*scvfDelta, y}; + normalLeftUpCorners [1] = {x-.5*scvfDelta, y+upOppoDelta}; + normalLeftDownCorners [0] = {x-.5*scvfDelta, y-downOppoDelta}; + normalLeftDownCorners [1] = {x-.5*scvfDelta, y}; + + Scalar deltaT = t-tOld; + Scalar q = possiblyInstationarySourceAtPos({x,y},t)[Indices::momentumYBalanceIdx]; + + Scalar velSelfOld = isStationary? 0. : analyticalYVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, selfCorners, tOld); + Scalar velSelf = analyticalYVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, selfCorners, t); + + Scalar velParallelRightOrUp = analyticalYVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, parallelRightCorners, t); + Scalar velParallelLeftOrDown = analyticalYVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, parallelLeftCorners, t); + Scalar velOppoRightOrUp = analyticalYVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, oppoUpCorners, t); + Scalar velOppoLeftOrDown = analyticalYVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, oppoDownCorners, t); + + Scalar velNormalUpRightOrRightUp = analyticalXVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, normalRightUpCorners, t); + Scalar velNormalUpLeftOrRightDown = analyticalXVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, normalRightDownCorners, t); + Scalar velNormalDownRightOrLeftUp = analyticalXVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, normalLeftUpCorners, t); + Scalar velNormalDownLeftOrLeftDown = analyticalXVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, normalLeftDownCorners, t); + + Scalar presLeftOrDown = possiblyInstationaryAnalyticalPressureAtPos_(possiblyInstationaryAnalyticalSolution, {x,y-.5*downOppoDelta}, t); + Scalar presRightOrUp = possiblyInstationaryAnalyticalPressureAtPos_(possiblyInstationaryAnalyticalSolution, {x,y+.5*upOppoDelta}, t); + + bool navierStokes = getParam<bool>("Problem.EnableInertiaTerms"); + Scalar viscosity = getParam<Scalar>("Component.LiquidKinematicViscosity"); + + return residual_(isStationary, + velSelfOld, + deltaT, + downOppoDelta, + upOppoDelta, + rightLateralDelta, + scvfDelta, + leftLateralDelta, + q, + velSelf, + velParallelRightOrUp, + velParallelLeftOrDown, + velOppoRightOrUp, + velOppoLeftOrDown, + velNormalUpRightOrRightUp, + velNormalUpLeftOrRightDown, + velNormalDownRightOrLeftUp, + velNormalDownLeftOrLeftDown, + presLeftOrDown, + presRightOrUp, + navierStokes, + viscosity); + } + + // output the residuals that we would get for perfect interpolation. + template<class LambdaA, class LambdaB, class CVLeafGridView> + void fillResidual_(const LambdaA& possiblyInstationaryAnalyticalSolution, + const LambdaB& possiblyInstationarySourceAtPos, + bool isStationary, + Scalar t, + Scalar tOld, + std::vector<Scalar>& outputResMom, + const CVLeafGridView& cvLeafGridView, + const std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>>& cvCenterScvfIndicesMap, + unsigned int dirIdx, + bool vanDerPlas ) const + { + outputResMom.resize(cvLeafGridView.size(0)); + + for (const auto& controlVolume : elements(cvLeafGridView)) + { + std::vector<unsigned int> scvfIndices;//size 1 value at boundary, 2 usually, 3 for vanDerPlas transition face + auto it = cvCenterScvfIndicesMap.find(controlVolume.geometry().center()); + + bool transitionCV = false; + SubControlVolumeFace scvf; + SubControlVolumeFace otherFace; + + if (it == cvCenterScvfIndicesMap.end()) + { + std::cout << "looking for " << controlVolume.geometry().center() << std::endl; + + for ( const auto& entry : cvCenterScvfIndicesMap ) + { + std::cout << "map entry cv center = " << entry.first; + for ( const auto& val : entry.second) + std::cout << " " << val; + std::cout << std::endl; + } + + DUNE_THROW(Dune::InvalidStateException, ""); + } + else + { + scvfIndices = (*it).second; + + if (scvfIndices.size() == 1 /*boundary*/ || scvfIndices.size() == 2 /*inner,non-transition face*/) + { + scvf = (*problem_).gridGeometry().scvf(scvfIndices[0]); + } + else if (vanDerPlas && scvfIndices.size() == 4)/*transition face*/ + { + transitionCV = true; + + const auto& scvf0 = (*problem_).gridGeometry().scvf(scvfIndices[0]); + const auto& scvf1 = (*problem_).gridGeometry().scvf(scvfIndices[1]); + const auto& scvf2 = (*problem_).gridGeometry().scvf(scvfIndices[2]); + + scvf = scvf0; + + if (!containerCmp(scvf1.center(), scvf0.center())) + otherFace = scvf1; + else + otherFace = scvf2; + } + else + { + for (const auto& scvfIndex : scvfIndices) + { + const auto& scvf = (*problem_).gridGeometry().scvf(scvfIndex); + std::cout << "scvf at " << scvf.center() << std::endl; + } + + DUNE_THROW(Dune::InvalidStateException, "size = " << scvfIndices.size() << " at " << controlVolume.geometry().center()); + } + } + + if (dirIdx != scvf.directionIndex()) + DUNE_THROW(Dune::InvalidStateException, "dirIdx = " << dirIdx << ", scvf.directionIndex() = " << scvf.directionIndex() << ", scvf center = " << scvf.center()); + + int nondirIdx = (dirIdx == 0)?1:0; + + unsigned int index = cvLeafGridView.indexSet().index(controlVolume); + + Scalar dirCenter = scvf.center()[dirIdx]; + Scalar nonDirCenter = transitionCV?(.5*(scvf.center()[nondirIdx]+otherFace.center()[nondirIdx])):scvf.center()[nondirIdx]; + + Scalar x = (dirIdx == 0)?dirCenter:nonDirCenter; + Scalar y = (dirIdx == 1)?dirCenter:nonDirCenter; + + std::vector<Scalar> dirValues; + std::vector<Scalar> nonDirValues; + + for (unsigned int i=0; i < controlVolume.geometry().corners(); ++i) + { + const auto& corner = controlVolume.geometry().corner(i); + + dirValues.push_back(corner[dirIdx]); + nonDirValues.push_back(corner[nondirIdx]); + } + + std::sort(dirValues.begin(),dirValues.end()); + std::sort(nonDirValues.begin(),nonDirValues.end()); + + Scalar lowerDirValue = dirValues[0]; + Scalar higherDirValue = dirValues[3]; + + Scalar oppoDeltaLower = 2*(dirCenter-lowerDirValue); + Scalar oppoDeltaHigher = 2*(higherDirValue - dirCenter); + + int upOrRightSubFaceIdx; + int downOrLeftSubFaceIdx; + + const auto& normalFluxCorrectionFace = (*problem_).gridGeometry().scvf(scvf.insideScvIdx(), scvf.pairData(0).localNormalFluxCorrectionIndex); + if (normalFluxCorrectionFace.unitOuterNormal()[1]==1) + { + upOrRightSubFaceIdx = 0; + downOrLeftSubFaceIdx = 1; + } + else + { + upOrRightSubFaceIdx = 1; + downOrLeftSubFaceIdx = 0; + } + + Scalar higherLateralDelta; + if (!transitionCV || (scvf.center()[nondirIdx]>otherFace.center()[nondirIdx])) + { + higherLateralDelta = scvf.pairData(upOrRightSubFaceIdx).parallelDistances[1]; + } + else + { + higherLateralDelta = otherFace.pairData(upOrRightSubFaceIdx).parallelDistances[1]; + } + + Scalar lowerLateralDelta; + if (!transitionCV || (scvf.center()[nondirIdx]<otherFace.center()[nondirIdx])) + { + lowerLateralDelta = scvf.pairData(downOrLeftSubFaceIdx).parallelDistances[1]; + } + else + { + lowerLateralDelta = otherFace.pairData(downOrLeftSubFaceIdx).parallelDistances[1]; + } + + Scalar midLateralDelta = transitionCV?2.*scvf.area():scvf.area(); + + if (scvf.boundary()) + { + using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; + + auto bcTypes = (*problem_).boundaryTypesAtPos(scvf.center()); + if (!bcTypes.isDirichlet(Indices::velocity(scvf.directionIndex()))) + DUNE_THROW(Dune::InvalidStateException, "Do not use the residual calculation with outflow BCs. Not prepared so far."); + + outputResMom[index] = 0.; + continue; + } + + outputResMom[index] = + (dirIdx==0)? momentumXResidual_(possiblyInstationaryAnalyticalSolution, possiblyInstationarySourceAtPos, isStationary, t, tOld, x, y, oppoDeltaLower, oppoDeltaHigher, higherLateralDelta, midLateralDelta, lowerLateralDelta) + :momentumYResidual_(possiblyInstationaryAnalyticalSolution, possiblyInstationarySourceAtPos, isStationary, t, tOld, x, y, oppoDeltaLower, oppoDeltaHigher, higherLateralDelta, midLateralDelta, lowerLateralDelta); + + } + } + + /* + void printResidualsOfGeometry_ (Scalar coarseDeltaX, Scalar coarseDeltaY, Scalar centralX, Scalar centralY) const + { + ////// + std::cout << "coarse: " << std::endl; + //x + // ------------------------------------- + // | | | | + // | | | | + // | + + | + // | | | | + // | | | | + // ------+lllllllllll+rrrrrrrrrrr+------ + // | l | * | r | + // | l | * | r | + // + o + o + o + + // | l | * | r | + // | l | * | r | + // ------+lllllllllll+rrrrrrrrrrr+------ + // | | | | + // | | | | + // | + + | + // | | | | + // | | | | + // ------------------------------------- + // l: control volume named left + // r: control volume named right + // *: overlap of mid/right control volume boundary + // +: relevant velocity dof positions + // o: relevant pressure dof positions + Scalar right = momentumXResidual_(centralX+.5*coarseDeltaX, centralY, coarseDeltaX, coarseDeltaX, coarseDeltaY, coarseDeltaY, coarseDeltaY); + Scalar left = momentumXResidual_(centralX-.5*coarseDeltaX, centralY, coarseDeltaX, coarseDeltaX, coarseDeltaY, coarseDeltaY, coarseDeltaY); + std::cout << "momentum x: right " << right << ", left " << left << std::endl; + + //y + Scalar up = momentumYResidual_(centralX, centralY+.5*coarseDeltaY, coarseDeltaY, coarseDeltaY, coarseDeltaX, coarseDeltaX, coarseDeltaX); + Scalar down = momentumYResidual_(centralX, centralY-.5*coarseDeltaY, coarseDeltaY, coarseDeltaY, coarseDeltaX, coarseDeltaX, coarseDeltaX); + std::cout << "momentum y: up " << up << ", down " << down << std::endl; + + ///// + std::cout << "perfect interpolation " << std::endl; + //x + // ------------------------------------- + // | | | | + // | | | | + // | | | | + // | | | | + // | | | | + // | + + + | + // | | | | + // ------+lulululu+mumum+rurururu+------ + // | l | * | * | r | + // + o + o + o + o + + // | u | * | * | u | + // | +********+*****+********+ | + // | l | * | * | r | + // + o + o + o + o + + // | d | * | * | d | + // ------+ldldldld+mdmdm+rdrdrdrd+------ + // | | | | + // | + + + | + // | | | | + // | | | | + // | | | | + // | | | | + // | | | | + // ------------------------------------- + // lu: control volume named left up + // ru: control volume named right up + // ld: control volume named left down + // rd: control volume named right down + // ... + // *: overlap of mid/left or mid/right control volume boundary + // +: relevant velocity dof positions + // o: relevant pressure dof positions + Scalar rightUp = momentumXResidual_( centralX+.5*coarseDeltaX, centralY+0.25*coarseDeltaY, .5*coarseDeltaX, coarseDeltaX, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaY); + Scalar rightDown = momentumXResidual_(centralX+.5*coarseDeltaX, centralY-0.25*coarseDeltaY, .5*coarseDeltaX, coarseDeltaX, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaY); + Scalar leftUp = momentumXResidual_( centralX-.5*coarseDeltaX, centralY+0.25*coarseDeltaY, coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaY); + Scalar leftDown = momentumXResidual_( centralX-.5*coarseDeltaX, centralY-0.25*coarseDeltaY, coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaY); + Scalar midUp = momentumXResidual_( centralX, centralY+0.25*coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaY); + Scalar midDown = momentumXResidual_( centralX, centralY-0.25*coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaY); + + std::cout << "momentum x: right up " << rightUp << ", right down = " << rightDown << ", left up " << leftUp << ", left down = " << leftDown << ", mid up " << midUp << ", mid down = " << midDown << std::endl; + //y-component of the momentum balance + Scalar upRight = momentumYResidual_( centralX+.25*coarseDeltaX, centralY+.5*coarseDeltaY, .5*coarseDeltaY, coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX); + Scalar upLeft = momentumYResidual_( centralX-.25*coarseDeltaX, centralY+.5*coarseDeltaY, .5*coarseDeltaY, coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX); + Scalar midRight = momentumYResidual_( centralX+.25*coarseDeltaX, centralY, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX); + Scalar midLeft = momentumYResidual_( centralX-.25*coarseDeltaX, centralY, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX); + Scalar downRight = momentumYResidual_(centralX+.25*coarseDeltaX, centralY-.5*coarseDeltaY, coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX); + Scalar downLeft = momentumYResidual_( centralX-.25*coarseDeltaX, centralY-.5*coarseDeltaY, coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX); + + std::cout << "momentum y: up right " << upRight << ", up left = " << upLeft << ", mid right " << midRight << ", mid left " << midLeft << ", downRight " << downRight << ", downLeft " << downLeft << std::endl; + + ///// + std::cout << "grading in x momentumXResiduals: "; + //x + // ------------------------------------- + // | | | | | + // | | | | | + // | + + + | + // | | | | | + // | | | | | + // ------+llllllll+mmmmm+rrrrrrrr+------ + // | l | * | * | r | + // | l | * | * | r | + // + o + o + o + o + + // | l | * | * | r | + // | l | * | * | r | + // ------+llllllll+mmmmm+rrrrrrrr+------ + // | | | | | + // | | | | | + // | + + + | + // | | | | | + // | | | | | + // ------------------------------------- + // l: control volume named left grading + // r: control volume named right grading + // m: control volume named mid grading + // *: overlap of mid/left or mid/right control volume boundary + // +: relevant velocity dof positions + // o: relevant pressure dof positions + Scalar rightGrading = momentumXResidual_(centralX+.5*coarseDeltaX, centralY, .5*coarseDeltaX, coarseDeltaX, coarseDeltaY, coarseDeltaY, coarseDeltaY); + Scalar leftGrading = momentumXResidual_(centralX-.5*coarseDeltaX, centralY, coarseDeltaX, .5*coarseDeltaX, coarseDeltaY, coarseDeltaY, coarseDeltaY); + Scalar midGrading = momentumXResidual_(centralX, centralY, .5*coarseDeltaX, .5*coarseDeltaX, coarseDeltaY, coarseDeltaY, coarseDeltaY); + + std::cout << "momentum x: right " << rightGrading << ", left " << leftGrading << ", mid " << midGrading << std::endl; + + //y + // ------------------------------------- + // | | | | | + // | | | | | + // | +luolu+ruoru+ | + // | l * r | + // | u * u | + // ------------l-----*-----r------------ + // | u * u | + // | l * r | + // + +*****+*****+ + + // | l * r | + // | d * d | + // ------------l-----*-----r------------ + // | d * d | + // | l * r | + // | +ldold+rdord+ | + // | | | | | + // | | | | | + // ------------------------------------- + // lu: control volume named left up grading + // ru: control volume named right up grading + // ld: control volume named left down grading + // rd: control volume named right down grading + // *: overlap of mid/left or mid/right control volume boundary + // +: relevant velocity dof positions + // o: relevant pressure dof positions + Scalar rightUpGrading = momentumYResidual_(centralX+.25*coarseDeltaX, centralY+.5*coarseDeltaY, coarseDeltaY, coarseDeltaY, coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX); + Scalar leftUpGrading = momentumYResidual_(centralX-.25*coarseDeltaX, centralY+.5*coarseDeltaY, coarseDeltaY, coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, coarseDeltaX); + Scalar rightDownGrading = momentumYResidual_(centralX+.25*coarseDeltaX, centralY-.5*coarseDeltaY, coarseDeltaY, coarseDeltaY, coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX); + Scalar leftDownGrading = momentumYResidual_(centralX-.25*coarseDeltaX, centralY-.5*coarseDeltaY, coarseDeltaY, coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, coarseDeltaX); + + std::cout << "momentum y: right up " << rightUpGrading << ", left up " << leftUpGrading << ", right down " << rightDownGrading << ", left down " << leftDownGrading << std::endl; + + ///// + std::cout << "grading in neighbor in y momentumXResiduals: "; + //x + Scalar rightNeighborGrading = momentumXResidual_(centralX+.5*coarseDeltaX, centralY, coarseDeltaX, coarseDeltaX, 2.*coarseDeltaY, coarseDeltaY, coarseDeltaY); + Scalar leftNeighborGrading = momentumXResidual_(centralX-.5*coarseDeltaX, centralY, coarseDeltaX, coarseDeltaX, 2.*coarseDeltaY, coarseDeltaY, coarseDeltaY); + + std::cout << "momentum y: rightNeighborGrading " << rightNeighborGrading << ", leftNeighborGrading " << leftNeighborGrading << std::endl; + ///// + std::cout << "perfect interpolation, everything central and symmetric:"; + //x + Scalar rightUpPerfectIterpSymm = momentumXResidual_( centralX + 5./8*coarseDeltaX, centralY+0.25*coarseDeltaY, 0.75*coarseDeltaX, 0.75*coarseDeltaX, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaY); + Scalar rightDownPerfectIterpSymm = momentumXResidual_( centralX + 5./8*coarseDeltaX, centralY-0.25*coarseDeltaY, 0.75*coarseDeltaX, 0.75*coarseDeltaX, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaY); + Scalar leftUpPerfectIterpSymm = momentumXResidual_( centralX - 5./8*coarseDeltaX, centralY+0.25*coarseDeltaY, 0.75*coarseDeltaX, 0.75*coarseDeltaX, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaY); + Scalar leftDownPerfectIterpSymm = momentumXResidual_( centralX - 5./8*coarseDeltaX, centralY-0.25*coarseDeltaY, 0.75*coarseDeltaX, 0.75*coarseDeltaX, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaY); + Scalar midUpPerfectIterpSymm = momentumXResidual_( centralX, centralY+0.25*coarseDeltaY, 0.5*coarseDeltaX, 0.5*coarseDeltaX, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaY); + Scalar midDownPerfectIterpSymm = momentumXResidual_( centralX, centralY-0.25*coarseDeltaY, 0.5*coarseDeltaX, 0.5*coarseDeltaX, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaY); + + std::cout << "momentum x: right up " << rightUpPerfectIterpSymm << ", right down = " << rightDownPerfectIterpSymm << ", left up " << leftUpPerfectIterpSymm << ", left down = " << leftDownPerfectIterpSymm << ", mid up " << midUpPerfectIterpSymm << ", mid down = " << midDownPerfectIterpSymm << std::endl; + + //y + Scalar upRightPerfectIterpSymm = momentumYResidual_( centralX+.25*coarseDeltaX, centralY+5./8*coarseDeltaY, 0.75*coarseDeltaY, 0.75*coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX); + Scalar upLeftPerfectIterpSymm = momentumYResidual_( centralX-.25*coarseDeltaX, centralY+5./8*coarseDeltaY, 0.75*coarseDeltaY, 0.75*coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX); + Scalar midRightPerfectIterpSymm = momentumYResidual_( centralX+.25*coarseDeltaX, centralY, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX); + Scalar midLeftPerfectIterpSymm = momentumYResidual_( centralX-.25*coarseDeltaX, centralY, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX); + Scalar downRightPerfectIterpSymm = momentumYResidual_(centralX+.25*coarseDeltaX, centralY-5./8*coarseDeltaY, 0.75*coarseDeltaY, 0.75*coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX); + Scalar downLeftPerfectIterpSymm = momentumYResidual_( centralX-.25*coarseDeltaX, centralY-5./8*coarseDeltaY, 0.75*coarseDeltaY, 0.75*coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX); + + std::cout << "momentum y: up right " << upRightPerfectIterpSymm << ", up left = " << upLeftPerfectIterpSymm << ", mid right " << midRightPerfectIterpSymm << ", mid left " << midLeftPerfectIterpSymm << ", downRight " << downRightPerfectIterpSymm << ", downLeft " << downLeftPerfectIterpSymm << std::endl; + + return; + }*/ + + std::shared_ptr<const Problem> problem_; +}; +} // end namespace Dumux + +#endif diff --git a/dumux/freeflow/navierstokes/staggered/cvdresidualCalc.hh b/dumux/freeflow/navierstokes/staggered/cvdresidualCalcOld.hh similarity index 100% rename from dumux/freeflow/navierstokes/staggered/cvdresidualCalc.hh rename to dumux/freeflow/navierstokes/staggered/cvdresidualCalcOld.hh -- GitLab From dad40fecf45522a5b7a15ed4ba0f6fc7bd8c094c Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Fri, 10 Sep 2021 12:05:09 +0300 Subject: [PATCH 03/69] renamed residual calc --- .../staggered/{cvdResidualCalc.hh => cvdresidualCalc.hh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename dumux/freeflow/navierstokes/staggered/{cvdResidualCalc.hh => cvdresidualCalc.hh} (100%) diff --git a/dumux/freeflow/navierstokes/staggered/cvdResidualCalc.hh b/dumux/freeflow/navierstokes/staggered/cvdresidualCalc.hh similarity index 100% rename from dumux/freeflow/navierstokes/staggered/cvdResidualCalc.hh rename to dumux/freeflow/navierstokes/staggered/cvdresidualCalc.hh -- GitLab From faf09056cba617e25a0554462f98c2dc2ebda778 Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Fri, 10 Sep 2021 12:29:21 +0300 Subject: [PATCH 04/69] cvdcontrolvolumegrids update --- .../navierstokes/staggered/cvdresidualCalc.hh | 4 +- dumux/io/grid/cvdcontrolvolumegrids.hh | 176 +++---- dumux/io/grid/cvdcontrolvolumegrids_old.hh | 428 ++++++++++++++++++ 3 files changed, 499 insertions(+), 109 deletions(-) create mode 100644 dumux/io/grid/cvdcontrolvolumegrids_old.hh diff --git a/dumux/freeflow/navierstokes/staggered/cvdresidualCalc.hh b/dumux/freeflow/navierstokes/staggered/cvdresidualCalc.hh index 58e4553..323a1d3 100644 --- a/dumux/freeflow/navierstokes/staggered/cvdresidualCalc.hh +++ b/dumux/freeflow/navierstokes/staggered/cvdresidualCalc.hh @@ -21,8 +21,8 @@ * \ingroup NavierStokesModel */ -#ifndef DUMUX_NAVIERSTOKES_STAGGERED_RESIDUALCALC_HH -#define DUMUX_NAVIERSTOKES_STAGGERED_RESIDUALCALC_HH +#ifndef DUMUX_CVD_NAVIERSTOKES_STAGGERED_RESIDUALCALC_HH +#define DUMUX_CVD_NAVIERSTOKES_STAGGERED_RESIDUALCALC_HH #include <dumux/common/timeloop.hh> #include <dune/grid/io/file/vtk/vtkwriter.hh> diff --git a/dumux/io/grid/cvdcontrolvolumegrids.hh b/dumux/io/grid/cvdcontrolvolumegrids.hh index 1bb1d3b..9e2d3e0 100644 --- a/dumux/io/grid/cvdcontrolvolumegrids.hh +++ b/dumux/io/grid/cvdcontrolvolumegrids.hh @@ -20,8 +20,8 @@ * \file * \brief Provides a grid creator builds a pore network grid from a host grid */ -#ifndef DUMUX_CONTROL_VOLUME_GRID_HH -#define DUMUX_CONTROL_VOLUME_GRID_HH +#ifndef DUMUX_CVD_CONTROL_VOLUME_GRID_HH +#define DUMUX_CVD_CONTROL_VOLUME_GRID_HH #include <iostream> #include <fstream> @@ -30,10 +30,19 @@ #include <dumux/discretization/staggered/freeflow/geometryhelper/cvdstaggeredgeometryhelper.hh> namespace Dumux { -template<class SubControlVolumeFace, class GridGeometry> +template<class GlobalPosition> +struct ContainerCmpClass { + bool operator() (const GlobalPosition& lhs, const GlobalPosition& rhs) const + { + double epsilon = 1e-6; + auto scalarLess = [&] (double left, double right) { return (std::abs(left - right) > epsilon) && (left < right); }; -//Finds the two coordinates at "corners" of the subcontrolvolume face. If face is horizontal + return (scalarLess(lhs[0], rhs[0]) || ((scalarCmp(lhs[0],rhs[0],epsilon)) && (scalarLess(lhs[1], rhs[1])))); + } +}; + +template<class SubControlVolumeFace, class GridGeometry> void fillNonDirCoord_(const SubControlVolumeFace& scvf, const GridGeometry& gridGeometry, double& nonDirCoord0, @@ -55,10 +64,10 @@ void fillNonDirCoord_(const SubControlVolumeFace& scvf, for (auto&& myscvf : scvfs(outsideFvGeometry)) { - auto minusNormal = scvf.centerUnitOuterNormal(); + auto minusNormal = scvf.unitOuterNormal(); minusNormal *= -1.; - if (containerCmp(myscvf.centerUnitOuterNormal(),minusNormal)) + if (containerCmp(myscvf.unitOuterNormal(),minusNormal)) { if (containerCmp(myscvf.center(),scvf.center())) { @@ -69,10 +78,10 @@ void fillNonDirCoord_(const SubControlVolumeFace& scvf, } unsigned int nonDirIdx = (scvf.directionIndex() == 0) ? 1 : 0; - const SubControlVolumeFace& normalFace0 = gridGeometry.scvf(coarseSideScvf.insideScvIdx(), coarseSideScvf.pairData(0).localNormalFluxCorrectionIndex); + const SubControlVolumeFace& normalFace0 = gridGeometry.scvf(coarseSideScvf.insideScvIdx(), coarseSideScvf.localNormalFaceBuildingIdx(0)); nonDirCoord0 = normalFace0.center()[nonDirIdx]; - const SubControlVolumeFace& normalFace1 = gridGeometry.scvf(coarseSideScvf.insideScvIdx(), coarseSideScvf.pairData(1).localNormalFluxCorrectionIndex); + const SubControlVolumeFace& normalFace1 = gridGeometry.scvf(coarseSideScvf.insideScvIdx(), coarseSideScvf.localNormalFaceBuildingIdx(1)); nonDirCoord1 = normalFace1.center()[nonDirIdx]; } else @@ -136,8 +145,33 @@ std::array<GlobalPosition,4> localCVVertices(const SubControlVolumeFace& scvf, c return localVertices; } + +template<class GlobalPosition, class SubControlVolumeFace> +GlobalPosition localCVCenter(const SubControlVolumeFace& scvf, bool hangingNodesAreCVCenters) +{ + unsigned int dirIdx = scvf.directionIndex(); + unsigned int nonDirIdx = (dirIdx == 0) ? 1 : 0; + + GlobalPosition center; + double insideCoord = scvf.inside().geometry().center()[dirIdx]; + double outsideCoord = scvf.boundary()?scvf.center()[dirIdx]:scvf.outside().geometry().center()[dirIdx]; + center[dirIdx] = (insideCoord + outsideCoord)*0.5; + + if (hangingNodesAreCVCenters && !scvf.boundary() && (scvf.inside().level() != scvf.outside().level())) + { + if (scvf.inside().level() < scvf.outside().level()) + center[nonDirIdx] = scvf.inside().geometry().center()[nonDirIdx]; + else + center[nonDirIdx] = scvf.outside().geometry().center()[nonDirIdx]; + } + else + center[nonDirIdx] = scvf.center()[nonDirIdx]; + + return center; +} + template<class GridGeometry, class GlobalPosition> -void fillCVsGridInfo(bool hangingNodesAreCVCenters, +auto fillCVsGridInfo(bool hangingNodesAreCVCenters, const GridGeometry& gridGeometry, int dirIdx, std::map<int, GlobalPosition>& vertices, @@ -146,6 +180,7 @@ void fillCVsGridInfo(bool hangingNodesAreCVCenters, { using namespace Dumux; unsigned int vertexNumber = 0; + std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>> cvCenterScvfIndicesMap; std::vector<unsigned int> visitedScvfDofs; @@ -156,8 +191,16 @@ void fillCVsGridInfo(bool hangingNodesAreCVCenters, for (auto&& scvf : scvfs(fvGeometry)) { + GlobalPosition cvCenter = localCVCenter<GlobalPosition>(scvf,hangingNodesAreCVCenters); + if ( std::find(visitedScvfDofs.begin(), visitedScvfDofs.end(), scvf.dofIndex()) != visitedScvfDofs.end()) + { + auto it = cvCenterScvfIndicesMap.find(cvCenter); + if (it != cvCenterScvfIndicesMap.end()) + (*it).second.push_back(scvf.index()); + continue; + } bool transitionFace = hangingNodesAreCVCenters && !scvf.boundary() && (scvf.inside().level() != scvf.outside().level()); @@ -171,7 +214,7 @@ void fillCVsGridInfo(bool hangingNodesAreCVCenters, { for (auto&& myscvf : scvfs(fvGeometry)) { - if (containerCmp(myscvf.centerUnitOuterNormal(),scvf.centerUnitOuterNormal()) && !containerCmp(myscvf.center(),scvf.center())) + if (containerCmp(myscvf.unitOuterNormal(),scvf.unitOuterNormal()) && !containerCmp(myscvf.center(),scvf.center())) { otherFace = myscvf; } @@ -184,10 +227,10 @@ void fillCVsGridInfo(bool hangingNodesAreCVCenters, for (auto&& myscvf : scvfs(outsideFvGeometry)) { - auto minusNormal = scvf.centerUnitOuterNormal(); + auto minusNormal = scvf.unitOuterNormal(); minusNormal *= -1.; - if (containerCmp(myscvf.centerUnitOuterNormal(),minusNormal)) + if (containerCmp(myscvf.unitOuterNormal(),minusNormal)) { if (!containerCmp(myscvf.center(),scvf.center())) { @@ -201,6 +244,11 @@ void fillCVsGridInfo(bool hangingNodesAreCVCenters, if (std::find(visitedScvfDofs.begin(), visitedScvfDofs.end(), otherFace.dofIndex()) != visitedScvfDofs.end()) { visitedScvfDofs.push_back(scvf.dofIndex()); + + auto it = cvCenterScvfIndicesMap.find(cvCenter); + if (it != cvCenterScvfIndicesMap.end()) + (*it).second.push_back(scvf.index()); + continue; } } @@ -211,6 +259,11 @@ void fillCVsGridInfo(bool hangingNodesAreCVCenters, { std::array<GlobalPosition,4> localVertices = localCVVertices<GlobalPosition>(scvf, gridGeometry, hangingNodesAreCVCenters); + std::vector<unsigned int> scvfIndices; + scvfIndices.push_back(scvf.index()); + + cvCenterScvfIndicesMap.insert(std::pair<GlobalPosition, std::vector<unsigned int>>(cvCenter,scvfIndices)); + std::array<int,4> localCube; std::array<int,2> parallelLocalBoundarySegment; @@ -279,90 +332,8 @@ void fillCVsGridInfo(bool hangingNodesAreCVCenters, } } } -} - - -//Goal is to construct visualisation from actual previously constructed scvf's, instead of finding them here based on scvf normals -template <class GridGeometry, class GlobalPosition> -void fillCoarseVelocityCVsGridInfo(const GridGeometry& gridGeometry, - int dirIdx, - std::map<int, GlobalPosition>& vertices, - std::vector<std::array<int, 4>>& cubes, - std::vector<std::array<int, 2>>& boundarySegments) { - using namespace Dumux; - unsigned int vertexNumber = 0; - - std::vector<unsigned int> visitedScvfDofs; - - for (const auto& element : elements(gridGeometry.gridView())) { - auto fvGeometry = localView(gridGeometry); - fvGeometry.bindElement(element); - - for (auto&& scvf : scvfs(fvGeometry)) { - if (std::find(visitedScvfDofs.begin(), visitedScvfDofs.end(), scvf.dofIndex()) != visitedScvfDofs.end()) - continue; - - visitedScvfDofs.push_back(scvf.dofIndex()); - if (scvf.directionIndex() == dirIdx) { - std::array<GlobalPosition, 4> localVertices = localCVVertices<GlobalPosition>(scvf, gridGeometry, true); - - std::array<int, 4> localCube; - - std::array<int, 2> parallelLocalBoundarySegment; - std::array<int, 2> perpendicularLocalBoundarySegment; - - for (unsigned int i = 0; i < 4; ++i) { - const GlobalPosition& vertex = localVertices[i]; - - int alreadyThereVertexNumber = -1; - for (auto it = vertices.begin(); it != vertices.end(); ++it) { - if (containerCmp(it->second, vertex)) { - alreadyThereVertexNumber = it->first; - } - } - - if (!(alreadyThereVertexNumber < 0)) { - localCube[i] = alreadyThereVertexNumber; - } else { - localCube[i] = vertexNumber; - vertices.insert(std::pair<unsigned int, GlobalPosition>(vertexNumber, vertex)); - ++vertexNumber; - } - } - - for (unsigned int someIndex = 0; someIndex < 2; ++someIndex) { - unsigned int otherIdx = (someIndex == 0) ? 1 : 0; - - if (!scvf.hasParallelNeighbor(someIndex, 0)) { - if (containerCmp(scvf.pairData(someIndex).virtualFirstParallelFaceDofPos, scvf.corner(someIndex))) { - if (someIndex == 0) - perpendicularLocalBoundarySegment = {localCube[0], localCube[2]}; - else if (someIndex == 1) - perpendicularLocalBoundarySegment = {localCube[1], localCube[3]}; - } else if (containerCmp(scvf.pairData(someIndex).virtualFirstParallelFaceDofPos, scvf.corner(otherIdx))) { - if (otherIdx == 0) - perpendicularLocalBoundarySegment = {localCube[0], localCube[2]}; - else if (otherIdx == 1) - perpendicularLocalBoundarySegment = {localCube[1], localCube[3]}; - } else - DUNE_THROW(Dune::InvalidStateException, ""); - } - } - - if (scvf.boundary()) - parallelLocalBoundarySegment = {localCube[2], localCube[3]}; - - cubes.push_back(localCube); - - if (scvf.boundary()) - boundarySegments.push_back(parallelLocalBoundarySegment); - - if (!scvf.hasParallelNeighbor(0, 0) || !scvf.hasParallelNeighbor(1, 0)) - boundarySegments.push_back(perpendicularLocalBoundarySegment); - } - } - } + return cvCenterScvfIndicesMap; } template<class GlobalPosition> @@ -403,26 +374,17 @@ void printCVsGridInfo(const std::string& name, } template<class GridGeometry, class GlobalPosition> -void generateCVsDGFfile(const std::string& paramGroup, const GridGeometry& gridGeometry, int dirIdx, bool hangingNodesAreCVCenters) +auto generateCVsDGFfile(const std::string& paramGroup, const GridGeometry& gridGeometry, int dirIdx, bool hangingNodesAreCVCenters) { std::map<int, GlobalPosition> vertices; std::vector<std::array<int,4>> cubes; std::vector<std::array<int,2>> boundarySegments; - fillCVsGridInfo<GridGeometry, GlobalPosition>(hangingNodesAreCVCenters, gridGeometry,dirIdx, vertices, cubes, boundarySegments); + std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>> cvCenterScvfIndicesMap = fillCVsGridInfo<GridGeometry, GlobalPosition>(hangingNodesAreCVCenters, gridGeometry,dirIdx, vertices, cubes, boundarySegments); printCVsGridInfo<GlobalPosition>(paramGroup, vertices, cubes, boundarySegments); -} - -template<class GridGeometry, class GlobalPosition> -void createCoarseVelocityCVsDGFfile(const std::string& paramGroup, const GridGeometry& gridGeometry, int dirIdx){ - std::map<int, GlobalPosition> vertices; - std::vector<std::array<int,4>> cubes; - std::vector<std::array<int,2>> boundarySegments; - fillCoarseVelocityCVsGridInfo<GridGeometry, GlobalPosition>(gridGeometry, dirIdx, vertices, cubes, boundarySegments); - printCVsGridInfo<GlobalPosition>(paramGroup, vertices, cubes, boundarySegments); + return cvCenterScvfIndicesMap; } - } #endif diff --git a/dumux/io/grid/cvdcontrolvolumegrids_old.hh b/dumux/io/grid/cvdcontrolvolumegrids_old.hh new file mode 100644 index 0000000..1bb1d3b --- /dev/null +++ b/dumux/io/grid/cvdcontrolvolumegrids_old.hh @@ -0,0 +1,428 @@ +// -*- 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 Provides a grid creator builds a pore network grid from a host grid + */ +#ifndef DUMUX_CONTROL_VOLUME_GRID_HH +#define DUMUX_CONTROL_VOLUME_GRID_HH + +#include <iostream> +#include <fstream> +#include <iomanip> + +#include <dumux/discretization/staggered/freeflow/geometryhelper/cvdstaggeredgeometryhelper.hh> + +namespace Dumux { +template<class SubControlVolumeFace, class GridGeometry> + + +//Finds the two coordinates at "corners" of the subcontrolvolume face. If face is horizontal +void fillNonDirCoord_(const SubControlVolumeFace& scvf, + const GridGeometry& gridGeometry, + double& nonDirCoord0, + double& nonDirCoord1, + bool hangingNodesAreCVCenters) +{ + if (hangingNodesAreCVCenters && !scvf.boundary() && (scvf.inside().level() != scvf.outside().level())) + { + SubControlVolumeFace coarseSideScvf; + + if (!scvf.boundary() && (scvf.inside().level() < scvf.outside().level())) + { + coarseSideScvf = scvf; + } + else if (!scvf.boundary() && (scvf.inside().level() > scvf.outside().level())) + { + auto outsideFvGeometry = localView(gridGeometry); + outsideFvGeometry.bindElement(scvf.outside()); + + for (auto&& myscvf : scvfs(outsideFvGeometry)) + { + auto minusNormal = scvf.centerUnitOuterNormal(); + minusNormal *= -1.; + + if (containerCmp(myscvf.centerUnitOuterNormal(),minusNormal)) + { + if (containerCmp(myscvf.center(),scvf.center())) + { + coarseSideScvf = myscvf; + } + } + } + } + + unsigned int nonDirIdx = (scvf.directionIndex() == 0) ? 1 : 0; + const SubControlVolumeFace& normalFace0 = gridGeometry.scvf(coarseSideScvf.insideScvIdx(), coarseSideScvf.pairData(0).localNormalFluxCorrectionIndex); + nonDirCoord0 = normalFace0.center()[nonDirIdx]; + + const SubControlVolumeFace& normalFace1 = gridGeometry.scvf(coarseSideScvf.insideScvIdx(), coarseSideScvf.pairData(1).localNormalFluxCorrectionIndex); + nonDirCoord1 = normalFace1.center()[nonDirIdx]; + } + else + { + unsigned int dirIdx = scvf.directionIndex(); + unsigned int nonDirIdx = (dirIdx == 0) ? 1 : 0; + + nonDirCoord0 = scvf.corner(0)[nonDirIdx]; + nonDirCoord1 = scvf.corner(1)[nonDirIdx]; + } +} + +template<class GlobalPosition, class SubControlVolumeFace, class GridGeometry> +std::array<GlobalPosition,4> localCVVertices(const SubControlVolumeFace& scvf, const GridGeometry& gridGeometry, bool hangingNodesAreCVCenters) +{ + double nonDirCoord0; + double nonDirCoord1; + + fillNonDirCoord_(scvf, gridGeometry, nonDirCoord0, nonDirCoord1, hangingNodesAreCVCenters); + + unsigned int dirIdx = scvf.directionIndex(); + unsigned int nonDirIdx = (dirIdx == 0) ? 1 : 0; + + std::array<GlobalPosition,4> localVertices; + + //fill local vertices inside + GlobalPosition innerNormalCenter0; + innerNormalCenter0[dirIdx] = scvf.inside().geometry().center()[dirIdx]; + innerNormalCenter0[nonDirIdx] = nonDirCoord0; + + GlobalPosition innerNormalCenter1; + innerNormalCenter1[dirIdx] = scvf.inside().geometry().center()[dirIdx]; + innerNormalCenter1[nonDirIdx] = nonDirCoord1; + + localVertices[0] = innerNormalCenter0; + localVertices[1] = innerNormalCenter1; + + //fill local vertices outside + if (scvf.boundary()) + { + GlobalPosition scvfCorner0 = scvf.corner(0); + GlobalPosition scvfCorner1 = scvf.corner(1); + + localVertices[2] = scvfCorner0; + localVertices[3] = scvfCorner1; + } + else + { + GlobalPosition outerNormalCenter0; + outerNormalCenter0[dirIdx] = scvf.outside().geometry().center()[dirIdx]; + outerNormalCenter0[nonDirIdx] = nonDirCoord0; + + GlobalPosition outerNormalCenter1; + outerNormalCenter1[dirIdx] = scvf.outside().geometry().center()[dirIdx]; + outerNormalCenter1[nonDirIdx] = nonDirCoord1; + + localVertices[2] = outerNormalCenter0; + localVertices[3] = outerNormalCenter1; + } + + return localVertices; +} + +template<class GridGeometry, class GlobalPosition> +void fillCVsGridInfo(bool hangingNodesAreCVCenters, + const GridGeometry& gridGeometry, + int dirIdx, + std::map<int, GlobalPosition>& vertices, + std::vector<std::array<int,4>>& cubes, + std::vector<std::array<int,2>>& boundarySegments) +{ + using namespace Dumux; + unsigned int vertexNumber = 0; + + std::vector<unsigned int> visitedScvfDofs; + + for (const auto& element : elements(gridGeometry.gridView())) + { + auto fvGeometry = localView(gridGeometry); + fvGeometry.bindElement(element); + + for (auto&& scvf : scvfs(fvGeometry)) + { + if ( std::find(visitedScvfDofs.begin(), visitedScvfDofs.end(), scvf.dofIndex()) != visitedScvfDofs.end()) + continue; + + bool transitionFace = hangingNodesAreCVCenters && !scvf.boundary() && (scvf.inside().level() != scvf.outside().level()); + + if (transitionFace) + { + //fill visited dof + using SubControlVolumeFace = std::decay_t<decltype(scvf)>; + SubControlVolumeFace otherFace; + //fill other face + if (!scvf.boundary() && (scvf.inside().level() < scvf.outside().level())) + { + for (auto&& myscvf : scvfs(fvGeometry)) + { + if (containerCmp(myscvf.centerUnitOuterNormal(),scvf.centerUnitOuterNormal()) && !containerCmp(myscvf.center(),scvf.center())) + { + otherFace = myscvf; + } + } + } + else if (!scvf.boundary() && (scvf.inside().level() > scvf.outside().level())) + { + auto outsideFvGeometry = localView(gridGeometry); + outsideFvGeometry.bindElement(scvf.outside()); + + for (auto&& myscvf : scvfs(outsideFvGeometry)) + { + auto minusNormal = scvf.centerUnitOuterNormal(); + minusNormal *= -1.; + + if (containerCmp(myscvf.centerUnitOuterNormal(),minusNormal)) + { + if (!containerCmp(myscvf.center(),scvf.center())) + { + otherFace = myscvf; + } + } + } + } + + //fill visitedDof + if (std::find(visitedScvfDofs.begin(), visitedScvfDofs.end(), otherFace.dofIndex()) != visitedScvfDofs.end()) + { + visitedScvfDofs.push_back(scvf.dofIndex()); + continue; + } + } + + visitedScvfDofs.push_back(scvf.dofIndex()); + + if (scvf.directionIndex() == dirIdx) + { + std::array<GlobalPosition,4> localVertices = localCVVertices<GlobalPosition>(scvf, gridGeometry, hangingNodesAreCVCenters); + + std::array<int,4> localCube; + + std::array<int,2> parallelLocalBoundarySegment; + std::array<int,2> perpendicularLocalBoundarySegment; + + for (unsigned int i = 0; i < 4; ++i) + { + const GlobalPosition& vertex = localVertices[i]; + + int alreadyThereVertexNumber = -1; + for (auto it = vertices.begin(); it != vertices.end(); ++it) + { + if (containerCmp(it->second, vertex)) + { + alreadyThereVertexNumber = it->first; + } + } + + if (!(alreadyThereVertexNumber < 0)) + { + localCube[i] = alreadyThereVertexNumber; + } + else + { + localCube[i] = vertexNumber; + vertices.insert(std::pair<unsigned int, GlobalPosition>(vertexNumber, vertex)); + ++vertexNumber; + } + } + + for (unsigned int someIndex = 0; someIndex < 2; ++someIndex) + { + unsigned int otherIdx = (someIndex==0)?1:0; + + if (!scvf.hasParallelNeighbor(someIndex,0)) + { + if (containerCmp(scvf.pairData(someIndex).virtualFirstParallelFaceDofPos, scvf.corner(someIndex))) + { + if (someIndex==0) + perpendicularLocalBoundarySegment = {localCube[0],localCube[2]}; + else if (someIndex==1) + perpendicularLocalBoundarySegment = {localCube[1],localCube[3]}; + } + else if (containerCmp(scvf.pairData(someIndex).virtualFirstParallelFaceDofPos, scvf.corner(otherIdx))) + { + if (otherIdx==0) + perpendicularLocalBoundarySegment = {localCube[0],localCube[2]}; + else if (otherIdx==1) + perpendicularLocalBoundarySegment = {localCube[1],localCube[3]}; + } + else + DUNE_THROW(Dune::InvalidStateException, ""); + } + } + + if (scvf.boundary()) + parallelLocalBoundarySegment = {localCube[2],localCube[3]}; + + cubes.push_back(localCube); + + if (scvf.boundary()) + boundarySegments.push_back(parallelLocalBoundarySegment); + + if (!scvf.hasParallelNeighbor(0,0) || !scvf.hasParallelNeighbor(1,0)) + boundarySegments.push_back(perpendicularLocalBoundarySegment); + } + } + } +} + + +//Goal is to construct visualisation from actual previously constructed scvf's, instead of finding them here based on scvf normals +template <class GridGeometry, class GlobalPosition> +void fillCoarseVelocityCVsGridInfo(const GridGeometry& gridGeometry, + int dirIdx, + std::map<int, GlobalPosition>& vertices, + std::vector<std::array<int, 4>>& cubes, + std::vector<std::array<int, 2>>& boundarySegments) { + using namespace Dumux; + unsigned int vertexNumber = 0; + + std::vector<unsigned int> visitedScvfDofs; + + for (const auto& element : elements(gridGeometry.gridView())) { + auto fvGeometry = localView(gridGeometry); + fvGeometry.bindElement(element); + + for (auto&& scvf : scvfs(fvGeometry)) { + if (std::find(visitedScvfDofs.begin(), visitedScvfDofs.end(), scvf.dofIndex()) != visitedScvfDofs.end()) + continue; + + visitedScvfDofs.push_back(scvf.dofIndex()); + + if (scvf.directionIndex() == dirIdx) { + std::array<GlobalPosition, 4> localVertices = localCVVertices<GlobalPosition>(scvf, gridGeometry, true); + + std::array<int, 4> localCube; + + std::array<int, 2> parallelLocalBoundarySegment; + std::array<int, 2> perpendicularLocalBoundarySegment; + + for (unsigned int i = 0; i < 4; ++i) { + const GlobalPosition& vertex = localVertices[i]; + + int alreadyThereVertexNumber = -1; + for (auto it = vertices.begin(); it != vertices.end(); ++it) { + if (containerCmp(it->second, vertex)) { + alreadyThereVertexNumber = it->first; + } + } + + if (!(alreadyThereVertexNumber < 0)) { + localCube[i] = alreadyThereVertexNumber; + } else { + localCube[i] = vertexNumber; + vertices.insert(std::pair<unsigned int, GlobalPosition>(vertexNumber, vertex)); + ++vertexNumber; + } + } + + for (unsigned int someIndex = 0; someIndex < 2; ++someIndex) { + unsigned int otherIdx = (someIndex == 0) ? 1 : 0; + + if (!scvf.hasParallelNeighbor(someIndex, 0)) { + if (containerCmp(scvf.pairData(someIndex).virtualFirstParallelFaceDofPos, scvf.corner(someIndex))) { + if (someIndex == 0) + perpendicularLocalBoundarySegment = {localCube[0], localCube[2]}; + else if (someIndex == 1) + perpendicularLocalBoundarySegment = {localCube[1], localCube[3]}; + } else if (containerCmp(scvf.pairData(someIndex).virtualFirstParallelFaceDofPos, scvf.corner(otherIdx))) { + if (otherIdx == 0) + perpendicularLocalBoundarySegment = {localCube[0], localCube[2]}; + else if (otherIdx == 1) + perpendicularLocalBoundarySegment = {localCube[1], localCube[3]}; + } else + DUNE_THROW(Dune::InvalidStateException, ""); + } + } + + if (scvf.boundary()) + parallelLocalBoundarySegment = {localCube[2], localCube[3]}; + + cubes.push_back(localCube); + + if (scvf.boundary()) + boundarySegments.push_back(parallelLocalBoundarySegment); + + if (!scvf.hasParallelNeighbor(0, 0) || !scvf.hasParallelNeighbor(1, 0)) + boundarySegments.push_back(perpendicularLocalBoundarySegment); + } + } + } +} + +template<class GlobalPosition> +void printCVsGridInfo(const std::string& name, + const std::map<int, GlobalPosition>& vertices, + const std::vector<std::array<int,4>>& cubes, + const std::vector<std::array<int,2>>& boundarySegments) +{ + std::ofstream dgfFile; + dgfFile.open(name + ".dgf"); + dgfFile << "DGF" << std::endl; + dgfFile << "% Elements = " << cubes.size() << " | Vertices = " << vertices.size() << std::endl; + dgfFile << std::endl; + dgfFile << "VERTEX" << std::endl; + auto i = vertices.begin(); + while (i != vertices.end()) + { + dgfFile << (i->second)[0] << " " << (i->second)[1] << std::endl; + ++i; + } + dgfFile << "#" << std::endl; + dgfFile << std::endl; + dgfFile << "CUBE" << std::endl; + for (const auto& cube : cubes) + dgfFile << cube[0] << " " << cube[1] << " " << cube[2] << " " << cube[3] << std::endl; + dgfFile << "#" << std::endl; + dgfFile << std::endl; + dgfFile << "BOUNDARYSEGMENTS" << std::endl; + for (const auto& boundarySegment : boundarySegments) + dgfFile << "1 " << boundarySegment[0] << " " << boundarySegment[1] << std::endl; + dgfFile << "#" << std::endl; + dgfFile << std::endl; + dgfFile << "#" << std::endl; + dgfFile << "BOUNDARYDOMAIN" << std::endl; + dgfFile << "default 1 % all other boundary segments have id 1" << std::endl; //I had to add this as for some reason it seems that the hanging node stuff (faces at hanging nodes from both sides) is also treated as boundary, if I not set anything the boundary there has id 0 which is not allowed + dgfFile << "#" << std::endl; + dgfFile.close(); +} + +template<class GridGeometry, class GlobalPosition> +void generateCVsDGFfile(const std::string& paramGroup, const GridGeometry& gridGeometry, int dirIdx, bool hangingNodesAreCVCenters) +{ + std::map<int, GlobalPosition> vertices; + std::vector<std::array<int,4>> cubes; + std::vector<std::array<int,2>> boundarySegments; + + fillCVsGridInfo<GridGeometry, GlobalPosition>(hangingNodesAreCVCenters, gridGeometry,dirIdx, vertices, cubes, boundarySegments); + printCVsGridInfo<GlobalPosition>(paramGroup, vertices, cubes, boundarySegments); +} + +template<class GridGeometry, class GlobalPosition> +void createCoarseVelocityCVsDGFfile(const std::string& paramGroup, const GridGeometry& gridGeometry, int dirIdx){ + std::map<int, GlobalPosition> vertices; + std::vector<std::array<int,4>> cubes; + std::vector<std::array<int,2>> boundarySegments; + + fillCoarseVelocityCVsGridInfo<GridGeometry, GlobalPosition>(gridGeometry, dirIdx, vertices, cubes, boundarySegments); + printCVsGridInfo<GlobalPosition>(paramGroup, vertices, cubes, boundarySegments); +} + +} + +#endif -- GitLab From cca31e7c18b45a7c134a0548db0ca89ac46c94f7 Mon Sep 17 00:00:00 2001 From: Melanie Lipp <melanie.lipp@iws.uni-stuttgart.de> Date: Fri, 10 Sep 2021 11:31:11 +0200 Subject: [PATCH 05/69] [appl][donea] Correct include of controlvolumegrids. --- appl/freeflow/navierstokes/donea/main.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appl/freeflow/navierstokes/donea/main.cc b/appl/freeflow/navierstokes/donea/main.cc index 29bb8b6..43590d9 100644 --- a/appl/freeflow/navierstokes/donea/main.cc +++ b/appl/freeflow/navierstokes/donea/main.cc @@ -57,7 +57,7 @@ bool writeOut = false; #include <dumux/io/mystaggeredvtkoutputmodule.hh> #include <dumux/io/grid/gridmanager.hh> -#include <dumux/io/grid/controlvolumegrids.hh> +#include <dumux/io/grid/cvdcontrolvolumegrids.hh> #include <dumux/freeflow/navierstokes/staggered/cvdresidualCalc.hh> #include <dumux/io/outputFacility.hh> @@ -323,4 +323,4 @@ catch (...) std::cerr << "Unknown exception thrown! ---> Abort!" << std::endl; return 4; } -#pragma GCC diagnostic pop \ No newline at end of file +#pragma GCC diagnostic pop -- GitLab From 6d2c6e99ae1cc3261f2dd9ba9c6e9727886206f1 Mon Sep 17 00:00:00 2001 From: Melanie Lipp <melanie.lipp@iws.uni-stuttgart.de> Date: Fri, 10 Sep 2021 11:45:11 +0200 Subject: [PATCH 06/69] [residualcalc] Add missing CVD prefixes. --- dumux/freeflow/navierstokes/staggered/cvdresidualCalc.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dumux/freeflow/navierstokes/staggered/cvdresidualCalc.hh b/dumux/freeflow/navierstokes/staggered/cvdresidualCalc.hh index 323a1d3..e946500 100644 --- a/dumux/freeflow/navierstokes/staggered/cvdresidualCalc.hh +++ b/dumux/freeflow/navierstokes/staggered/cvdresidualCalc.hh @@ -44,7 +44,7 @@ class ResidualCalc using SubControlVolumeFace = typename GridGeometry::SubControlVolumeFace; using GridView = typename GridGeometry::GridView; using Scalar = GetPropType<TypeTag, Properties::Scalar>; - using MLGTraits = typename MyFreeFlowStaggeredDefaultScvfGeometryTraits<GridView>::template ScvfMLGTraits<Scalar> ; + using MLGTraits = typename CVDFreeFlowStaggeredDefaultScvfGeometryTraits<GridView>::template ScvfMLGTraits<Scalar> ; using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; using Element = typename GridGeometry::GridView::template Codim<0>::Entity; @@ -60,7 +60,7 @@ class ResidualCalc using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; using GridVariables = GetPropType<TypeTag, Properties::GridVariables>; - using Assembler = StaggeredRefinedFVAssembler<TypeTag, DiffMethod::numeric>; + using Assembler = CVDStaggeredRefinedFVAssembler<TypeTag, DiffMethod::numeric>; public: /*! -- GitLab From 3c4d3ebffee05a47ce0cb6f26f95cc36c169335c Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Fri, 10 Sep 2021 12:47:36 +0300 Subject: [PATCH 07/69] delete old versions of outputfacility and readdofbasedresults --- dumux/io/outputFacility.hh | 271 --------------------------------- dumux/io/readdofbasedresult.hh | 82 ---------- 2 files changed, 353 deletions(-) delete mode 100755 dumux/io/outputFacility.hh delete mode 100755 dumux/io/readdofbasedresult.hh diff --git a/dumux/io/outputFacility.hh b/dumux/io/outputFacility.hh deleted file mode 100755 index ec1941e..0000000 --- a/dumux/io/outputFacility.hh +++ /dev/null @@ -1,271 +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 3 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 - * \ingroup NavierStokesModel - */ - -#ifndef DUMUX_IO_OUTPUTFACILITY_HH -#define DUMUX_IO_OUTPUTFACILITY_HH - -#include <dumux/common/timeloop.hh> -#include <dune/grid/io/file/vtk/vtkwriter.hh> -#include <dumux/io/grid/cvdcontrolvolumegrids.hh> -#include <dumux/discretization/staggered/freeflow/geometryhelper/cvdstaggeredgeometryhelper.hh> -#include <dumux/discretization/staggered/freeflow/cvdffsubcontrolvolumeface.hh> -#include <dumux/freeflow/navierstokes/analyticalSolutionIntegration.hh> -#include <dumux/io/readdofbasedresult.hh> - -namespace Dumux{ -template<class TypeTag> -class CVOutputFacility -{ - using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; - using GridView = typename GridGeometry::GridView; - using Scalar = GetPropType<TypeTag, Properties::Scalar>; - using SolutionVector = GetPropType<TypeTag, Properties::SolutionVector>; - using CellCenterSolutionVector = GetPropType<TypeTag, Properties::CellCenterSolutionVector>; - using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; - // using MLGTraits = typename CVDFreeFlowStaggeredDefaultScvfGeometryTraits<GridView>::template ScvfMLGTraits<Scalar> ; - - using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; - using Element = typename GridGeometry::GridView::template Codim<0>::Entity; - using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - using Problem = GetPropType<TypeTag, Properties::Problem>; - - using HostGrid = Dune::ALUGrid<2,2,Dune::cube,Dune::nonconforming >; - using HostGridManager = GridManager<HostGrid>; - using CVGridGeometry = GetPropType<TypeTag, Properties::CVGridGeometry>; - - using GridVariables = GetPropType<TypeTag, Properties::GridVariables>; - using Assembler = CVDStaggeredRefinedFVAssembler<TypeTag, DiffMethod::numeric>; - -public: - /*! - * \brief The Constructor - */ - CVOutputFacility(std::shared_ptr<const Problem> problem) - : problem_(problem) - {} - - void iniCVGridManagers(std::array<HostGridManager, 4>& gridManagers, - std::array<std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>>,4>& cvCenterScvfIndicesMaps, - const std::array<std::string, 4>& paramGroups) const - { - // generate dgf files, initialize grid managers - cvCenterScvfIndicesMaps[0] = generateCVsDGFfile<GridGeometry, GlobalPosition>(paramGroups[0], (*problem_).gridGeometry(), 0, false); - cvCenterScvfIndicesMaps[1] = generateCVsDGFfile<GridGeometry, GlobalPosition>(paramGroups[1], (*problem_).gridGeometry(), 1, false); - cvCenterScvfIndicesMaps[2] = generateCVsDGFfile<GridGeometry, GlobalPosition>(paramGroups[2], (*problem_).gridGeometry(), 0, true); - cvCenterScvfIndicesMaps[3] = generateCVsDGFfile<GridGeometry, GlobalPosition>(paramGroups[3], (*problem_).gridGeometry(), 1, true); - - std::string testString = getParam<std::string>("finexCVs.Grid.File", ""); - if (testString == "") - DUNE_THROW(Dune::InvalidStateException, "Please set finexCVs.Grid.File."); - - for (unsigned int i = 0; i < 4; ++i) - gridManagers[i].init(paramGroups[i]); - } - - void onCVsOutputResidualsAndPrimVars(std::shared_ptr<const GridGeometry> gridGeometry, std::array<HostGridManager, 4>& cvGridManagers, const std::array<std::string, 4>& paramGroups, const SolutionVector& sol, unsigned int timeIndex, const FaceSolutionVector& faceResidualWithAnalyticalSol, const std::optional<std::array<std::vector<Scalar>, 4>>& perfectInterpolationFaceResiduals, bool readDofBasedValues) const - { - std::array<std::vector<std::vector<Scalar>>,4> dualIndexedOutputVecsArray = {}; - std::vector<std::string> fineOutputVecNames; - std::vector<std::string> coarseOutputVecNames; - - // - { - std::vector<FaceSolutionVector> finePrimalIndexOutputVecs; - - const FaceSolutionVector& vel = sol[GridGeometry::faceIdx()]; - finePrimalIndexOutputVecs.push_back(vel); - fineOutputVecNames.push_back("velocity"); - - const FaceSolutionVector& anaVel = problem_->getAnalyticalFaceSolutionVector(); - finePrimalIndexOutputVecs.push_back(anaVel); - fineOutputVecNames.push_back("analyticalVelocity"); - - FaceSolutionVector absVelocityError; - absVelocityError.resize((*problem_).gridGeometry().numIntersections()); - for (unsigned int i = 0; i < vel.size(); ++i) - { - absVelocityError[i] = std::abs(vel[i] - anaVel[i]); - } - finePrimalIndexOutputVecs.push_back(absVelocityError); - fineOutputVecNames.push_back("absVelocityError"); - - if (readDofBasedValues) - { - FaceSolutionVector IBAMRvel; - IBAMRvel.resize((*problem_).gridGeometry().numFaceDofs()); - - ReadDofBasedResult<TypeTag> reader(problem_); - reader.readDofBasedResult(IBAMRvel, "velocity"); - finePrimalIndexOutputVecs.push_back(IBAMRvel); - fineOutputVecNames.push_back("IBAMRvel"); - } - - finePrimalIndexOutputVecs.push_back(faceResidualWithAnalyticalSol); - fineOutputVecNames.push_back("numericalMomResAnalytical"); - - std::array<std::vector<std::vector<Scalar>>,2> fineDualIndexOutputVec = onePrimalIndexedVectorToTwoDualIndexedVectors_(finePrimalIndexOutputVecs, cvGridManagers); - for (unsigned int i = 0; i < 2; ++i) - for (unsigned int j = 0; j < fineDualIndexOutputVec[i].size(); ++j) - dualIndexedOutputVecsArray[i].push_back(fineDualIndexOutputVec[i][j]); - } - - if (perfectInterpolationFaceResiduals) - { - for (unsigned int i = 0; i < 4; ++i) - dualIndexedOutputVecsArray[i].push_back((*perfectInterpolationFaceResiduals)[i]); - fineOutputVecNames.push_back("perfectInterpMomResWithAnalytical"); - coarseOutputVecNames.push_back("perfectInterpMomResWithAnalytical"); - } - - std::array<std::vector<std::string>, 4> outputVecNames; - for (unsigned int i = 0; i < fineOutputVecNames.size(); ++i) - { - outputVecNames[0].push_back(fineOutputVecNames[i]+"_x"); - outputVecNames[1].push_back(fineOutputVecNames[i]+"_y"); - } - for (unsigned int i = 0; i < coarseOutputVecNames.size(); ++i) - { - outputVecNames[2].push_back(coarseOutputVecNames[i]+"_x"); - outputVecNames[3].push_back(coarseOutputVecNames[i]+"_y"); - } - - for (unsigned int i = 0; i < 4; ++i) - { - using CVsGridView = std::decay_t<decltype(cvGridManagers[i].grid().leafGridView())>; - Dune::VTKWriter<CVsGridView> writer (cvGridManagers[i].grid().leafGridView()); - for (unsigned int j = 0; j < dualIndexedOutputVecsArray[i].size(); ++j) - writer.addCellData(dualIndexedOutputVecsArray[i][j], outputVecNames[i][j]); - - std::string timeIndexString = std::to_string(timeIndex); - writer.write(paramGroups[i]+"-0000"+timeIndexString); - } - } - - void printPvdFiles(const std::array<std::string, 4>& paramGroups, const std::vector<std::pair<unsigned int, Scalar>> pvdFileInfos) - { - for (unsigned int i = 0; i < 4; ++i) - { - std::string name = paramGroups[i]; - - std::ofstream dgfFile; - dgfFile.open(name + ".pvd"); - dgfFile << "<?xml version=\"1.0\"?>" << std::endl; - dgfFile << "<VTKFile type=\"Collection\" version=\"0.1\" byte_order=\"LittleEndian\">" << std::endl; - dgfFile << "<Collection>" << std::endl; - - for (const auto& pvdFileInfo : pvdFileInfos) - dgfFile << "<DataSet timestep=\"" << pvdFileInfo.second << "\" group=\"\" part=\"0\" name=\"\" file=\""<< name << "-0000" << pvdFileInfo.first << ".vtu\"/>" << std::endl; - dgfFile << "</Collection>" << std::endl; - dgfFile << "</VTKFile>" << std::endl; - dgfFile.close(); - } - } - -private: - template<class OutputVecs> - std::array<std::vector<std::vector<Scalar>>,2> onePrimalIndexedVectorToTwoDualIndexedVectors_(OutputVecs& finePrimalIndexOutputVecs, std::array<HostGridManager, 4>& gridManagers) const - { - const auto& xFineCVsLeafGridView = (gridManagers[0]).grid().leafGridView(); - const HostGrid::LeafGridView& yFineCVsLeafGridView = gridManagers[1].grid().leafGridView(); - - std::array<std::vector<std::vector<Scalar>>,2> retArray; - - std::vector<std::vector<Scalar>> modifiedfinePrimalIndexOutputVecsX; - std::vector<Scalar> dummyVecX; - dummyVecX.resize(xFineCVsLeafGridView.size(0)); - for (unsigned int i = 0; i < finePrimalIndexOutputVecs.size(); ++i) - modifiedfinePrimalIndexOutputVecsX.push_back(dummyVecX); - - std::vector<std::vector<Scalar>> modifiedfinePrimalIndexOutputVecsY; - std::vector<Scalar> dummyVecY; - dummyVecY.resize(yFineCVsLeafGridView.size(0)); - for (unsigned int i = 0; i < finePrimalIndexOutputVecs.size(); ++i) - modifiedfinePrimalIndexOutputVecsY.push_back(dummyVecY); - - for (const auto& element : elements((*problem_).gridGeometry().gridView())) - { - auto fvGeometry = localView((*problem_).gridGeometry()); - fvGeometry.bindElement(element); - - for (auto&& scvf : scvfs(fvGeometry)) - { - bool isX = scvf.directionIndex() == 0; - - unsigned int index = 0; - for (const auto& cv : elements(isX ? xFineCVsLeafGridView : yFineCVsLeafGridView)) - { - std::vector<Scalar> xValues; - std::vector<Scalar> yValues; - - for (unsigned int i=0; i < cv.geometry().corners(); ++i) - { - const auto& corner = cv.geometry().corner(i); - - xValues.push_back(corner[0]); - yValues.push_back(corner[1]); - } - - std::sort(xValues.begin(),xValues.end()); - std::sort(yValues.begin(),yValues.end()); - - Scalar left = xValues[0]; - Scalar right = xValues[3]; - Scalar down = yValues[0]; - Scalar up = yValues[3]; - - if ((left < scvf.center()[0] || scalarCmp(left, scvf.center()[0])) && - (scvf.center()[0] < right || scalarCmp(right, scvf.center()[0])) && - (down < scvf.center()[1] || scalarCmp(down, scvf.center()[1])) && - (scvf.center()[1] < up || scalarCmp(up, scvf.center()[1]))) - { - index = (isX ? xFineCVsLeafGridView : yFineCVsLeafGridView).indexSet().index(cv); - } - } - - if (isX) - { - for (unsigned int i = 0; i < finePrimalIndexOutputVecs.size(); ++i) - modifiedfinePrimalIndexOutputVecsX[i][index] = finePrimalIndexOutputVecs[i][scvf.dofIndex()]; - } - else if (scvf.directionIndex() == 1) - { - for (unsigned int i = 0; i < finePrimalIndexOutputVecs.size(); ++i) - modifiedfinePrimalIndexOutputVecsY[i][index] = finePrimalIndexOutputVecs[i][scvf.dofIndex()]; - } - else - { - DUNE_THROW(Dune::InvalidStateException, "wrong"); - } - } - } - - retArray = {modifiedfinePrimalIndexOutputVecsX, modifiedfinePrimalIndexOutputVecsY}; - - return retArray; - } - - std::shared_ptr<const Problem> problem_; -}; -} // end namespace Dumux - -#endif diff --git a/dumux/io/readdofbasedresult.hh b/dumux/io/readdofbasedresult.hh deleted file mode 100755 index 500f983..0000000 --- a/dumux/io/readdofbasedresult.hh +++ /dev/null @@ -1,82 +0,0 @@ - -#include<dumux/discretization/staggered/freeflow/geometryhelper/cvdstaggeredgeometryhelper.hh> - -std::vector<double> read_single_column (std::string inputfile_name, int max_readin_linenumber){ - std::ifstream stream(inputfile_name.c_str());//inputfilestream (ofstrem = outputfilestrem) - if(!stream) - { - std::cout << "ERROR: inputfile could not be opened" << std::endl; - exit(1); - } - std::vector<double> Values; - double d; - std::string s; - - //for max_readin_linenumber - int i=1; - - while (stream >> d) {//seems to go through everything which is separated by endl; http://stackoverflow.com/questions/7443787/using-c-ifstream-extraction-operator-to-read-formatted-data-from-a-file - Values.push_back(d); - i++; - if (i>max_readin_linenumber){break;} - }//for my rhoValues it's fine if it's only considering positive values - - stream.close(); - - return Values; -} - -template <class SomeType, class Vector> -void setValue(const SomeType& range, Vector retVector, const std::vector<double>& xPositions, const std::vector<double>& yPositions, const std::vector<double>& values, bool& setSomething, unsigned int i) -{ - using namespace Dumux; - - for (auto&& entity : range) - { - if(scalarCmp(entity.center()[0],xPositions[i]) && scalarCmp(entity.center()[1], yPositions[i])) - { - retVector[entity.dofIndex()] = values[i]; - setSomething = true; - } - } -} - -template<class Vector, class GridGeometry> -void readDofBasedResult(Vector retVector, const GridGeometry& gridGeometry, const std::string& quantity) -{ - using namespace Dumux; - - std::string paramGroup = (quantity == "pressure") ? "PressureReadIn" : "VelocityReadIn"; - - std::string xFileName = getParamFromGroup<std::string>(paramGroup, "XFileName"); - std::string yFileName = getParamFromGroup<std::string>(paramGroup, "YFileName"); - std::string valueFileName = getParamFromGroup<std::string>(paramGroup, "ValueFileName"); - unsigned int numFileEntries = getParamFromGroup<bool>(paramGroup, "NumFileEntries"); - - std::vector<double> xPositions = read_single_column(xFileName, numFileEntries); - std::vector<double> yPositions = read_single_column(yFileName, numFileEntries); - std::vector<double> values = read_single_column(valueFileName, numFileEntries); - - for (unsigned int i = 0; i < numFileEntries; ++i) - { - bool setSomething = false; - - for (const auto& element : elements((*gridGeometry).gridView())) - { - auto fvGeometry = localView(*gridGeometry); - fvGeometry.bindElement(element); - - if (quantity == "pressure") - { - const auto& range = scvs(fvGeometry); - setValue(range, retVector, xPositions, yPositions, values, setSomething, i); - } - else - { - const auto& range = scvfs(fvGeometry); - setValue(range, retVector, xPositions, yPositions, values, setSomething, i); - } - } - } - -} -- GitLab From 46c0d11f233403b2c99eade9d4839b33ed8d2f30 Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Fri, 10 Sep 2021 12:50:02 +0300 Subject: [PATCH 08/69] Copy of outputfacility and readdofbasedresult --- dumux/io/outputFacility.hh | 271 +++++++++++++++++++++++++++++++++ dumux/io/readdofbasedresult.hh | 120 +++++++++++++++ 2 files changed, 391 insertions(+) create mode 100644 dumux/io/outputFacility.hh create mode 100644 dumux/io/readdofbasedresult.hh diff --git a/dumux/io/outputFacility.hh b/dumux/io/outputFacility.hh new file mode 100644 index 0000000..ad44629 --- /dev/null +++ b/dumux/io/outputFacility.hh @@ -0,0 +1,271 @@ +// -*- 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 3 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 + * \ingroup NavierStokesModel + */ + +#ifndef DUMUX_CVD_IO_OUTPUTFACILITY_HH +#define DUMUX_CVD_IO_OUTPUTFACILITY_HH + +#include <dumux/common/timeloop.hh> +#include <dune/grid/io/file/vtk/vtkwriter.hh> +#include <dumux/io/grid/controlvolumegrids.hh> +#include <dumux/discretization/staggered/freeflow/geometryhelper/cvdstaggeredgeometryhelper.hh> +#include <dumux/discretization/staggered/freeflow/cvdffsubcontrolvolumeface.hh> +#include <dumux/freeflow/navierstokes/analyticalSolutionIntegration.hh> +#include <dumux/io/readdofbasedresult.hh> + +namespace Dumux{ +template<class TypeTag> +class CVOutputFacility +{ + using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; + using GridView = typename GridGeometry::GridView; + using Scalar = GetPropType<TypeTag, Properties::Scalar>; + using SolutionVector = GetPropType<TypeTag, Properties::SolutionVector>; + using CellCenterSolutionVector = GetPropType<TypeTag, Properties::CellCenterSolutionVector>; + using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; + using MLGTraits = typename CVDFreeFlowStaggeredDefaultScvfGeometryTraits<GridView>::template ScvfMLGTraits<Scalar> ; + + using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; + using Element = typename GridGeometry::GridView::template Codim<0>::Entity; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + using Problem = GetPropType<TypeTag, Properties::Problem>; + + using HostGrid = Dune::ALUGrid<2,2,Dune::cube,Dune::nonconforming >; + using HostGridManager = GridManager<HostGrid>; + using CVGridGeometry = GetPropType<TypeTag, Properties::CVGridGeometry>; + + using GridVariables = GetPropType<TypeTag, Properties::GridVariables>; + using Assembler = CVDStaggeredRefinedFVAssembler<TypeTag, DiffMethod::numeric>; + +public: + /*! + * \brief The Constructor + */ + CVOutputFacility(std::shared_ptr<const Problem> problem) + : problem_(problem) + {} + + void iniCVGridManagers(std::array<HostGridManager, 4>& gridManagers, + std::array<std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>>,4>& cvCenterScvfIndicesMaps, + const std::array<std::string, 4>& paramGroups) const + { + // generate dgf files, initialize grid managers + cvCenterScvfIndicesMaps[0] = generateCVsDGFfile<GridGeometry, GlobalPosition>(paramGroups[0], (*problem_).gridGeometry(), 0, false); + cvCenterScvfIndicesMaps[1] = generateCVsDGFfile<GridGeometry, GlobalPosition>(paramGroups[1], (*problem_).gridGeometry(), 1, false); + cvCenterScvfIndicesMaps[2] = generateCVsDGFfile<GridGeometry, GlobalPosition>(paramGroups[2], (*problem_).gridGeometry(), 0, true); + cvCenterScvfIndicesMaps[3] = generateCVsDGFfile<GridGeometry, GlobalPosition>(paramGroups[3], (*problem_).gridGeometry(), 1, true); + + std::string testString = getParam<std::string>("finexCVs.Grid.File", ""); + if (testString == "") + DUNE_THROW(Dune::InvalidStateException, "Please set finexCVs.Grid.File."); + + for (unsigned int i = 0; i < 4; ++i) + gridManagers[i].init(paramGroups[i]); + } + + void onCVsOutputResidualsAndPrimVars(std::shared_ptr<const GridGeometry> gridGeometry, std::array<HostGridManager, 4>& cvGridManagers, const std::array<std::string, 4>& paramGroups, const SolutionVector& sol, unsigned int timeIndex, const FaceSolutionVector& faceResidualWithAnalyticalSol, const std::optional<std::array<std::vector<Scalar>, 4>>& perfectInterpolationFaceResiduals, bool readDofBasedValues) const + { + std::array<std::vector<std::vector<Scalar>>,4> dualIndexedOutputVecsArray = {}; + std::vector<std::string> fineOutputVecNames; + std::vector<std::string> coarseOutputVecNames; + + // + { + std::vector<FaceSolutionVector> finePrimalIndexOutputVecs; + + const FaceSolutionVector& vel = sol[GridGeometry::faceIdx()]; + finePrimalIndexOutputVecs.push_back(vel); + fineOutputVecNames.push_back("velocity"); + + const FaceSolutionVector& anaVel = problem_->getAnalyticalFaceSolutionVector(); + finePrimalIndexOutputVecs.push_back(anaVel); + fineOutputVecNames.push_back("analyticalVelocity"); + + FaceSolutionVector absVelocityError; + absVelocityError.resize((*problem_).gridGeometry().numIntersections()); + for (unsigned int i = 0; i < vel.size(); ++i) + { + absVelocityError[i] = std::abs(vel[i] - anaVel[i]); + } + finePrimalIndexOutputVecs.push_back(absVelocityError); + fineOutputVecNames.push_back("absVelocityError"); + + if (readDofBasedValues) + { + FaceSolutionVector IBAMRvel; + IBAMRvel.resize((*problem_).gridGeometry().numFaceDofs()); + + ReadDofBasedResult<TypeTag> reader(problem_); + reader.readDofBasedResult(IBAMRvel, "velocity"); + finePrimalIndexOutputVecs.push_back(IBAMRvel); + fineOutputVecNames.push_back("IBAMRvel"); + } + + finePrimalIndexOutputVecs.push_back(faceResidualWithAnalyticalSol); + fineOutputVecNames.push_back("numericalMomResAnalytical"); + + std::array<std::vector<std::vector<Scalar>>,2> fineDualIndexOutputVec = onePrimalIndexedVectorToTwoDualIndexedVectors_(finePrimalIndexOutputVecs, cvGridManagers); + for (unsigned int i = 0; i < 2; ++i) + for (unsigned int j = 0; j < fineDualIndexOutputVec[i].size(); ++j) + dualIndexedOutputVecsArray[i].push_back(fineDualIndexOutputVec[i][j]); + } + + if (perfectInterpolationFaceResiduals) + { + for (unsigned int i = 0; i < 4; ++i) + dualIndexedOutputVecsArray[i].push_back((*perfectInterpolationFaceResiduals)[i]); + fineOutputVecNames.push_back("perfectInterpMomResWithAnalytical"); + coarseOutputVecNames.push_back("perfectInterpMomResWithAnalytical"); + } + + std::array<std::vector<std::string>, 4> outputVecNames; + for (unsigned int i = 0; i < fineOutputVecNames.size(); ++i) + { + outputVecNames[0].push_back(fineOutputVecNames[i]+"_x"); + outputVecNames[1].push_back(fineOutputVecNames[i]+"_y"); + } + for (unsigned int i = 0; i < coarseOutputVecNames.size(); ++i) + { + outputVecNames[2].push_back(coarseOutputVecNames[i]+"_x"); + outputVecNames[3].push_back(coarseOutputVecNames[i]+"_y"); + } + + for (unsigned int i = 0; i < 4; ++i) + { + using CVsGridView = std::decay_t<decltype(cvGridManagers[i].grid().leafGridView())>; + Dune::VTKWriter<CVsGridView> writer (cvGridManagers[i].grid().leafGridView()); + for (unsigned int j = 0; j < dualIndexedOutputVecsArray[i].size(); ++j) + writer.addCellData(dualIndexedOutputVecsArray[i][j], outputVecNames[i][j]); + + std::string timeIndexString = std::to_string(timeIndex); + writer.write(paramGroups[i]+"-0000"+timeIndexString); + } + } + + void printPvdFiles(const std::array<std::string, 4>& paramGroups, const std::vector<std::pair<unsigned int, Scalar>> pvdFileInfos) + { + for (unsigned int i = 0; i < 4; ++i) + { + std::string name = paramGroups[i]; + + std::ofstream dgfFile; + dgfFile.open(name + ".pvd"); + dgfFile << "<?xml version=\"1.0\"?>" << std::endl; + dgfFile << "<VTKFile type=\"Collection\" version=\"0.1\" byte_order=\"LittleEndian\">" << std::endl; + dgfFile << "<Collection>" << std::endl; + + for (const auto& pvdFileInfo : pvdFileInfos) + dgfFile << "<DataSet timestep=\"" << pvdFileInfo.second << "\" group=\"\" part=\"0\" name=\"\" file=\""<< name << "-0000" << pvdFileInfo.first << ".vtu\"/>" << std::endl; + dgfFile << "</Collection>" << std::endl; + dgfFile << "</VTKFile>" << std::endl; + dgfFile.close(); + } + } + +private: + template<class OutputVecs> + std::array<std::vector<std::vector<Scalar>>,2> onePrimalIndexedVectorToTwoDualIndexedVectors_(OutputVecs& finePrimalIndexOutputVecs, std::array<HostGridManager, 4>& gridManagers) const + { + const auto& xFineCVsLeafGridView = (gridManagers[0]).grid().leafGridView(); + const HostGrid::LeafGridView& yFineCVsLeafGridView = gridManagers[1].grid().leafGridView(); + + std::array<std::vector<std::vector<Scalar>>,2> retArray; + + std::vector<std::vector<Scalar>> modifiedfinePrimalIndexOutputVecsX; + std::vector<Scalar> dummyVecX; + dummyVecX.resize(xFineCVsLeafGridView.size(0)); + for (unsigned int i = 0; i < finePrimalIndexOutputVecs.size(); ++i) + modifiedfinePrimalIndexOutputVecsX.push_back(dummyVecX); + + std::vector<std::vector<Scalar>> modifiedfinePrimalIndexOutputVecsY; + std::vector<Scalar> dummyVecY; + dummyVecY.resize(yFineCVsLeafGridView.size(0)); + for (unsigned int i = 0; i < finePrimalIndexOutputVecs.size(); ++i) + modifiedfinePrimalIndexOutputVecsY.push_back(dummyVecY); + + for (const auto& element : elements((*problem_).gridGeometry().gridView())) + { + auto fvGeometry = localView((*problem_).gridGeometry()); + fvGeometry.bindElement(element); + + for (auto&& scvf : scvfs(fvGeometry)) + { + bool isX = scvf.directionIndex() == 0; + + unsigned int index = 0; + for (const auto& cv : elements(isX ? xFineCVsLeafGridView : yFineCVsLeafGridView)) + { + std::vector<Scalar> xValues; + std::vector<Scalar> yValues; + + for (unsigned int i=0; i < cv.geometry().corners(); ++i) + { + const auto& corner = cv.geometry().corner(i); + + xValues.push_back(corner[0]); + yValues.push_back(corner[1]); + } + + std::sort(xValues.begin(),xValues.end()); + std::sort(yValues.begin(),yValues.end()); + + Scalar left = xValues[0]; + Scalar right = xValues[3]; + Scalar down = yValues[0]; + Scalar up = yValues[3]; + + if ((left < scvf.center()[0] || scalarCmp(left, scvf.center()[0])) && + (scvf.center()[0] < right || scalarCmp(right, scvf.center()[0])) && + (down < scvf.center()[1] || scalarCmp(down, scvf.center()[1])) && + (scvf.center()[1] < up || scalarCmp(up, scvf.center()[1]))) + { + index = (isX ? xFineCVsLeafGridView : yFineCVsLeafGridView).indexSet().index(cv); + } + } + + if (isX) + { + for (unsigned int i = 0; i < finePrimalIndexOutputVecs.size(); ++i) + modifiedfinePrimalIndexOutputVecsX[i][index] = finePrimalIndexOutputVecs[i][scvf.dofIndex()]; + } + else if (scvf.directionIndex() == 1) + { + for (unsigned int i = 0; i < finePrimalIndexOutputVecs.size(); ++i) + modifiedfinePrimalIndexOutputVecsY[i][index] = finePrimalIndexOutputVecs[i][scvf.dofIndex()]; + } + else + { + DUNE_THROW(Dune::InvalidStateException, "wrong"); + } + } + } + + retArray = {modifiedfinePrimalIndexOutputVecsX, modifiedfinePrimalIndexOutputVecsY}; + + return retArray; + } + + std::shared_ptr<const Problem> problem_; +}; +} // end namespace Dumux + +#endif diff --git a/dumux/io/readdofbasedresult.hh b/dumux/io/readdofbasedresult.hh new file mode 100644 index 0000000..f204045 --- /dev/null +++ b/dumux/io/readdofbasedresult.hh @@ -0,0 +1,120 @@ +// -*- 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 3 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 + * \ingroup NavierStokesModel + */ + +#ifndef DUMUX_CVD_IO_READDOFBASEDRESULT_HH +#define DUMUX_CVD_IO_READDOFBASEDRESULT_HH + +#include<dumux/discretization/staggered/freeflow/geometryhelper/cvdstaggeredgeometryhelper.hh> + +namespace Dumux{ +template<class TypeTag> +class ReadDofBasedResult +{ + using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; + using GridView = typename GridGeometry::GridView; + using Scalar = GetPropType<TypeTag, Properties::Scalar>; + using Problem = GetPropType<TypeTag, Properties::Problem>; + +public: + /*! + * \brief The Constructor + */ + ReadDofBasedResult(std::shared_ptr<const Problem> problem) + : problem_(problem) + {} + +template<class Vector> +void readDofBasedResult(Vector& retVector, const std::string& quantity) const +{ + std::string paramGroup = (quantity == "pressure") ? "PressureReadIn" : "VelocityReadIn"; + + std::string xFileName = getParamFromGroup<std::string>(paramGroup, "XFileName"); + std::string yFileName = getParamFromGroup<std::string>(paramGroup, "YFileName"); + std::string valueFileName = getParamFromGroup<std::string>(paramGroup, "ValueFileName"); + unsigned int numFileEntries = getParamFromGroup<unsigned int>(paramGroup, "NumFileEntries"); + + std::vector<double> xPositions = read_single_column_(xFileName, numFileEntries); + std::vector<double> yPositions = read_single_column_(yFileName, numFileEntries); + std::vector<double> values = read_single_column_(valueFileName, numFileEntries); + + for (unsigned int i = 0; i < numFileEntries; ++i) + { + for (const auto& element : elements((*problem_).gridGeometry().gridView())) + { + auto fvGeometry = localView((*problem_).gridGeometry()); + fvGeometry.bindElement(element); + + if (quantity == "pressure") + { + const auto& range = scvs(fvGeometry); + setValue_(range, retVector, xPositions, yPositions, values, i); + } + else + { + const auto& range = scvfs(fvGeometry); + setValue_(range, retVector, xPositions, yPositions, values, i); + } + } + } +} + +private: + template <class SomeType, class Vector> + void setValue_(const SomeType& range, Vector& retVector, const std::vector<double>& xPositions, const std::vector<double>& yPositions, const std::vector<double>& values, unsigned int i) const + { + for (auto&& entity : range) + if(scalarCmp(entity.center()[0],xPositions[i]) && scalarCmp(entity.center()[1], yPositions[i])) + retVector[entity.dofIndex()] = values[i]; + } + + std::vector<double> read_single_column_ (std::string inputfile_name, int max_readin_linenumber) const + { + std::ifstream stream(inputfile_name.c_str());//inputfilestream (ofstrem = outputfilestrem) + if(!stream) + { + std::cout << "ERROR: inputfile could not be opened" << std::endl; + exit(1); + } + std::vector<double> Values; + double d; + std::string s; + + //for max_readin_linenumber + int i=1; + + while (stream >> d) {//seems to go through everything which is separated by endl; http://stackoverflow.com/questions/7443787/using-c-ifstream-extraction-operator-to-read-formatted-data-from-a-file + Values.push_back(d); + i++; + if (i>max_readin_linenumber){break;} + }//for my rhoValues it's fine if it's only considering positive values + + stream.close(); + + return Values; + } + + std::shared_ptr<const Problem> problem_; +}; +} // end namespace Dumux + +#endif -- GitLab From 70dced548d4ffd614f11a985ff2e92351ac81c08 Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Fri, 10 Sep 2021 14:02:53 +0300 Subject: [PATCH 09/69] cvdproblem update --- dumux/freeflow/navierstokes/cvdproblem.hh | 630 +++++++++++++--------- 1 file changed, 380 insertions(+), 250 deletions(-) diff --git a/dumux/freeflow/navierstokes/cvdproblem.hh b/dumux/freeflow/navierstokes/cvdproblem.hh index 92aa0e7..e82f771 100644 --- a/dumux/freeflow/navierstokes/cvdproblem.hh +++ b/dumux/freeflow/navierstokes/cvdproblem.hh @@ -21,8 +21,8 @@ * \ingroup NavierStokesModel * \copydoc Dumux::MyNavierStokesProblem */ -#ifndef DUMUX_NAVIERSTOKES_MY_PROBLEM_HH -#define DUMUX_NAVIERSTOKES_MY_PROBLEM_HH +#ifndef DUMUX_NAVIERSTOKES_CVD_PROBLEM_HH +#define DUMUX_NAVIERSTOKES_CVD_PROBLEM_HH #include <dune/common/exceptions.hh> #include <dune/common/typetraits.hh> @@ -30,8 +30,12 @@ #include <dumux/common/staggeredfvproblem.hh> #include <dumux/discretization/method.hh> #include <dumux/freeflow/mystaggeredupwindmethods.hh> -#include <dumux/io/grid/controlvolumegrids.hh> +#include <dumux/io/grid/cvdcontrolvolumegrids.hh> #include <dumux/discretization/staggered/freeflow/geometryhelper/cvdstaggeredgeometryhelper.hh> +#include <dumux/discretization/staggered/freeflow/cvdffsubcontrolvolumeface.hh> + +#include <dumux/freeflow/navierstokes/errors.hh> +#include <dumux/freeflow/navierstokes/analyticalSolutionIntegration.hh> namespace Dumux { @@ -68,6 +72,7 @@ class MyNavierStokesProblem : public MyNavierStokesParentProblem<TypeTag> using GridView = typename GridGeometry::GridView; using Element = typename GridView::template Codim<0>::Entity; + using ModelTraits = GetPropType<TypeTag, Properties::ModelTraits>; using GridVariables = GetPropType<TypeTag, Properties::GridVariables>; using GridFaceVariables = typename GridVariables::GridFaceVariables; using ElementFaceVariables = typename GridFaceVariables::LocalView; @@ -83,9 +88,12 @@ class MyNavierStokesProblem : public MyNavierStokesParentProblem<TypeTag> using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; using SolutionVector = GetPropType<TypeTag, Properties::SolutionVector>; + using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; + using CellCenterSolutionVector = GetPropType<TypeTag, Properties::CellCenterSolutionVector>; using FacePrimaryVariables = GetPropType<TypeTag, Properties::FacePrimaryVariables>; using CellCenterPrimaryVariables = GetPropType<TypeTag, Properties::CellCenterPrimaryVariables>; static constexpr int upwindSchemeOrder = getPropValue<TypeTag, Properties::UpwindSchemeOrder>(); + using NumEqVector = Dumux::NumEqVector<GetPropType<TypeTag, Properties::PrimaryVariables>>; enum { dim = GridView::dimension, @@ -96,6 +104,8 @@ class MyNavierStokesProblem : public MyNavierStokesParentProblem<TypeTag> using VelocityVector = Dune::FieldVector<Scalar, dimWorld>; using GravityVector = Dune::FieldVector<Scalar, dimWorld>; + using MLGTraits = typename MyFreeFlowStaggeredDefaultScvfGeometryTraits<GridView>::template ScvfMLGTraits<Scalar> ; + public: /*! * \brief The constructor @@ -111,6 +121,82 @@ public: gravity_[dim-1] = -9.81; enableInertiaTerms_ = getParamFromGroup<bool>(paramGroup, "Problem.EnableInertiaTerms"); + useScvfLineAveraging_ = getParam<bool>("Problem.UseScvfLineAveraging", false); + useScvfCVAveraging_ = getParam<bool>("Problem.UseScvfCVAveraging", false); + useScvVolumeAveraging_ = getParam<bool>("Problem.UseScvVolumeAveraging", false); + useContiSourceAveraging_ = getParam<bool>("Problem.UseContiSourceAveraging", false); + quadOrder_ = getParam<unsigned int>("Problem.QuadratureOrder", 3); + + //prepare headlines in the error file + std::ofstream logFile; + logFile.open(this->name() + "_error.csv"); + logFile << ",,,,,abs L2,,,rel L2,,,Linf,,,"<< std::endl; + logFile << "time/refinement step,corresponding paraview files,cc dofs, face dofs, all dofs, p,u,v,p,u,v,p,u,v" << std::endl; + logFile.close(); + } + + bool useScvfLineAveraging() const + { + return useScvfLineAveraging_; + } + + bool useScvfCVAveraging() const + { + return useScvfCVAveraging_; + } + + bool useScvVolumeAveraging() const + { + return useScvVolumeAveraging_; + } + + bool useContiSourceAveraging() const + { + return useContiSourceAveraging_; + } + + unsigned int quadOrder() const + { + return quadOrder_; + } + + /*! + * \brief Evaluate the source term for all phases within a given + * sub-control-volume (-face). + * + * 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 elementFaceVars All face variables for the element + * \param e The geometrical entity on which the source shall be applied (scv or scvf) + * + * For this method, the return 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. + */ + template<class ElementVolumeVariables, class ElementFaceVariables, class Entity> + NumEqVector source(const Element &element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars, + const ElementFaceVariables& elementFaceVars, + const Entity &e) const + { + // forward to solution independent, fully-implicit specific interface + NumEqVector source = asImp_().sourceAtPos(e.center()); + + if (useContiSourceAveraging_) + { + AnalyticalSolutionIntegration<TypeTag, MLGTraits> analyticalSolInt(quadOrder_); + auto rectangleGeo = analyticalSolInt.getRectangleGeometry(e, this->gridGeometry()); + Scalar meanContiSource = analyticalSolInt.rectangleIntegral(rectangleGeo, [&](const GlobalPosition& globalPos) { return asImp_().sourceAtPos(globalPos)[Indices::conti0EqIdx]; }); + source[Indices::conti0EqIdx] = meanContiSource; + } + + return source; } /*! @@ -124,10 +210,38 @@ public: Scalar temperatureAtPos(const GlobalPosition &globalPos) const { return asImp_().temperature(); } - //needed for residualcalc - auto instationaryAnalyticalSolutionAtPos(const GlobalPosition& globalPos, Scalar t) const + /*! + * \brief Return the analytical solution of the problem at a given position + * + * \param globalPos The global position + */ + Scalar instationaryAnalyticalPressureSolutionAtPos(const SubControlVolume& scv, const Scalar time) const { - return asImp_().analyticalSolutionAtPos(globalPos); + AnalyticalSolutionIntegration<TypeTag, MLGTraits> analyticalSolInt(quadOrder_); + auto rectangleGeo = analyticalSolInt.getRectangleGeometry(scv, this->gridGeometry()); + + if (useScvVolumeAveraging_) + return analyticalSolInt.rectangleIntegral(rectangleGeo, [&](const GlobalPosition& globalPos) { return asImp_().instationaryAnalyticalSolutionAtPos(globalPos, time)[Indices::pressureIdx]; }); + else + return asImp_().instationaryAnalyticalSolutionAtPos(scv.dofPosition(), time)[Indices::pressureIdx]; + } + + /*! + * \brief Return the analytical solution of the problem at a scvf + */ + Scalar instationaryAnalyticalVelocitySolutionAtPos(const SubControlVolumeFace& scvf, const Scalar time) const + { + unsigned int dirIdx = scvf.directionIndex(); + return instationaryAnalyticalVelocitySolutionAtPos_(scvf, time, dirIdx); + } + + /*! + * \brief Return the analytical solution of the problem at a scvf + */ + Scalar instationaryAnalyticalNonDirVelocitySolutionAtPos(const SubControlVolumeFace& scvf, const Scalar time) const + { + unsigned int nonDirIdx = (scvf.directionIndex() == 0)?1:0; + return instationaryAnalyticalVelocitySolutionAtPos_(scvf, time, nonDirIdx); } /*! @@ -135,15 +249,14 @@ public: * * \param globalPos The global position */ - PrimaryVariables analyticalSolution(const GlobalPosition& globalPos) const + Scalar analyticalPressureSolutionAtPos(const SubControlVolume& scv) const { - if (!getParam<bool>("Problem.AveragedAnalyticalSolution", true)) - return asImp_().analyticalSolutionAtPos(globalPos); - - return meanAnalyticalSolution(globalPos, [&](Scalar x) { return asImp_().xFactorAnalyticalSolutionAntiderivativeAtPos(x); }, - [&](Scalar y) { return asImp_().yFactorAnalyticalSolutionAntiderivativeAtPos(y); }, - [&](Scalar x) { return asImp_().xFactorAnalyticalSolutionAtPos(x); }, - [&](Scalar y) { return asImp_().yFactorAnalyticalSolutionAtPos(y); }); + AnalyticalSolutionIntegration<TypeTag, MLGTraits> analyticalSolInt(quadOrder_); + auto rectangleGeo = analyticalSolInt.getRectangleGeometry(scv, this->gridGeometry()); + if (useScvVolumeAveraging_) + return analyticalSolInt.rectangleIntegral(rectangleGeo, [&](const GlobalPosition& globalPos) { return asImp_().analyticalSolutionAtPos(globalPos)[Indices::pressureIdx]; }); + else + return asImp_().analyticalSolutionAtPos(scv.dofPosition())[Indices::pressureIdx]; } /*! @@ -151,16 +264,10 @@ public: * * \param globalPos The global position */ - PrimaryVariables instationaryAnalyticalSolution(const GlobalPosition& globalPos, Scalar t) const + Scalar analyticalVelocitySolutionAtPos(const SubControlVolumeFace& scvf) const { - if (!getParam<bool>("Problem.AveragedAnalyticalSolution", true)) - return asImp_().instationaryAnalyticalSolutionAtPos(globalPos,t); - - return meanAnalyticalSolution(globalPos, - [&](Scalar x) { return asImp_().xFactorAnalyticalSolutionAntiderivativeAtPos(x,t); }, - [&](Scalar y) { return asImp_().yFactorAnalyticalSolutionAntiderivativeAtPos(y,t); }, - [&](Scalar x) { return asImp_().xFactorAnalyticalSolutionAtPos(x,t); }, - [&](Scalar y) { return asImp_().yFactorAnalyticalSolutionAtPos(y,t); }); + unsigned int dirIdx = scvf.directionIndex(); + return analyticalVelocitySolutionAtPos_(scvf, dirIdx); } /*! @@ -168,90 +275,79 @@ public: * * \param globalPos The global position */ - template <class LambdaA, class LambdaB, class LambdaC, class LambdaD> - PrimaryVariables meanAnalyticalSolution(const GlobalPosition& globalPos, - const LambdaA& xFactorAnalyticalSolutionAntiderivativeAtPosLambdaFunction, - const LambdaB& yFactorAnalyticalSolutionAntiderivativeAtPosLambdaFunction, - const LambdaC& xFactorAnalyticalSolutionAtPosLambdaFunction, - const LambdaD& yFactorAnalyticalSolutionAtPosLambdaFunction) const + Scalar analyticalNonDirVelocitySolutionAtPos(const SubControlVolumeFace& scvf) const { - Scalar xIntegralLeft = 0.; - Scalar xIntegralRight = 0.; - Scalar yIntegralDown = 0.; - Scalar yIntegralUp = 0.; - - bool integrateX = false; - bool integrateY = false; - - setIntegralRanges_(globalPos, integrateX, integrateY, xIntegralLeft, xIntegralRight, yIntegralDown, yIntegralUp); - - std::array<PrimaryVariables,2> xMean; - std::array<PrimaryVariables,2> yMean; - - for (unsigned int j=0; j < 2; ++j) //up to two summands in the analytical solution - { - for (unsigned int i = 0; i < xMean[j].size(); ++i) - { - xMean[j][i] = (xFactorAnalyticalSolutionAntiderivativeAtPosLambdaFunction(xIntegralRight)[j][i] - xFactorAnalyticalSolutionAntiderivativeAtPosLambdaFunction(xIntegralLeft)[j][i])/(xIntegralRight - xIntegralLeft); - yMean[j][i] = (yFactorAnalyticalSolutionAntiderivativeAtPosLambdaFunction(yIntegralUp)[j][i] - yFactorAnalyticalSolutionAntiderivativeAtPosLambdaFunction(yIntegralDown)[j][i])/(yIntegralUp - yIntegralDown); - } - } - - const std::array<PrimaryVariables,2> xPointValue = xFactorAnalyticalSolutionAtPosLambdaFunction(globalPos[0]); - const std::array<PrimaryVariables,2> yPointValue = yFactorAnalyticalSolutionAtPosLambdaFunction(globalPos[1]); - - if (integrateX && !integrateY) - { - PrimaryVariables values; - - for (unsigned int j=0; j < 2; ++j) - { - for (unsigned int i = 0; i < values.size(); ++i) - { - values[i] += xMean[j][i] * yPointValue[j][i]; - } - } - - return values; - } - - if (!integrateX && integrateY) - { - PrimaryVariables values; - - for (unsigned int j=0; j < 2; ++j) - { - for (unsigned int i = 0; i < values.size(); ++i) - { - values[i] += xPointValue[j][i] * yMean[j][i]; - } - } - - return values; - } - - if (integrateX && integrateY) - { - PrimaryVariables values; + unsigned int nonDirIdx = (scvf.directionIndex() == 0)?1:0; + return analyticalVelocitySolutionAtPos_(scvf, nonDirIdx); + } - for (unsigned int j=0; j < 2; ++j) - { - for (unsigned int i = 0; i < values.size(); ++i) - { - values[i] += xMean[j][i] * yMean[j][i]; - } - } + void printErrors(const SolutionVector& curSol) const + { + PrimaryVariables l2NormAbs(0.0); + PrimaryVariables l2NormRel(0.0); + PrimaryVariables lInfinityNorm(0.0); + + std::ofstream logFile; + logFile.open(this->name() + "_error.csv", std::ios::app); + logFile << ", 00001.vtu ,"; + logFile.close(); + + NavierStokesTestErrors<TypeTag>::calculateErrors( + l2NormAbs, + l2NormRel, + lInfinityNorm, + *this, + curSol, + [&](const SubControlVolume& scv) { return analyticalPressureSolutionAtPos(scv); }, + [&](const SubControlVolumeFace& scvf) { return analyticalVelocitySolutionAtPos(scvf);}); + + NavierStokesTestErrors<TypeTag>::printErrors(l2NormAbs, l2NormRel, lInfinityNorm, *this); + } - return values; - } - PrimaryVariables values; - return values;//warning bypass + void printErrors(const SolutionVector& curSol, Scalar time, unsigned int timeIndex) const + { + PrimaryVariables l2NormAbs(0.0); + PrimaryVariables l2NormRel(0.0); + PrimaryVariables lInfinityNorm(0.0); + + std::ofstream logFile; + logFile.open(this->name() + "_error.csv", std::ios::app); + logFile << time << " , 0000" << timeIndex+1 << ".vtu, "; + logFile.close(); + + NavierStokesTestErrors<TypeTag>::calculateErrors( + l2NormAbs, + l2NormRel, + lInfinityNorm, + *this, + curSol, + [&](const SubControlVolume& scv) { return instationaryAnalyticalPressureSolutionAtPos(scv, time); }, + [&](const SubControlVolumeFace& scvf) { return instationaryAnalyticalVelocitySolutionAtPos(scvf, time);}); + + NavierStokesTestErrors<TypeTag>::printErrors(l2NormAbs, l2NormRel, lInfinityNorm, *this); } - //needed for residualcalc - auto instationarySourceAtPos(const GlobalPosition &globalPos, Scalar t) const + void printErrors(const SolutionVector& curSol, unsigned int refinementStep) const { - return asImp_().sourceAtPos(globalPos); + PrimaryVariables l2NormAbs(0.0); + PrimaryVariables l2NormRel(0.0); + PrimaryVariables lInfinityNorm(0.0); + + std::ofstream logFile; + logFile.open(this->name() + "_error.csv", std::ios::app); + logFile << refinementStep << " , 0000" << refinementStep+1 << ".vtu , "; + logFile.close(); + + NavierStokesTestErrors<TypeTag>::calculateErrors( + l2NormAbs, + l2NormRel, + lInfinityNorm, + *this, + curSol, + [&](const SubControlVolume& scv) { return analyticalPressureSolutionAtPos(scv); }, + [&](const SubControlVolumeFace& scvf) { return analyticalVelocitySolutionAtPos(scvf);}); + + NavierStokesTestErrors<TypeTag>::printErrors(l2NormAbs, l2NormRel, lInfinityNorm, *this); } /*! @@ -425,181 +521,204 @@ public: const SubControlVolumeFace& scvf) const { return CellCenterPrimaryVariables(0.0); } + void createAnalyticalSolution(Scalar time) + { + auto instationaryAnalyticalVelocitySolutionAtPosLambdaFunction = [&](const SubControlVolumeFace& scvf) { return asImp_().instationaryAnalyticalVelocitySolutionAtPos(scvf, time); }; + createAnalyticalSolution_( + [&](const SubControlVolume& scv) { return asImp_().instationaryAnalyticalPressureSolutionAtPos(scv, time); }, + instationaryAnalyticalVelocitySolutionAtPosLambdaFunction, + [&](const FVElementGeometry& fvGeometry) { return possiblyInstationaryAnalyticalVectorialVelocitySolutionAtGridCellCenterLambdaFunction_(fvGeometry, instationaryAnalyticalVelocitySolutionAtPosLambdaFunction); }); + } + + void createAnalyticalSolution() + { + auto analyticalVelocitySolutionAtPosLambdaFunction = [&](const SubControlVolumeFace& scvf) { return asImp_().analyticalVelocitySolutionAtPos(scvf); }; + createAnalyticalSolution_( + [&](const SubControlVolume& scv) { return asImp_().analyticalPressureSolutionAtPos(scv); }, + analyticalVelocitySolutionAtPosLambdaFunction, + [&](const FVElementGeometry& fvGeometry) { return possiblyInstationaryAnalyticalVectorialVelocitySolutionAtGridCellCenterLambdaFunction_(fvGeometry, analyticalVelocitySolutionAtPosLambdaFunction); }); + } + + auto getAnalyticalSolution(Scalar time) const + { + auto instationaryAnalyticalVelocitySolutionAtPosLambdaFunction = [&](const SubControlVolumeFace& scvf) { return asImp_().instationaryAnalyticalVelocitySolutionAtPos(scvf, time); }; + return getAnalyticalSolution_( + [&](const SubControlVolume& scv) { return asImp_().instationaryAnalyticalPressureSolutionAtPos(scv, time); }, + instationaryAnalyticalVelocitySolutionAtPosLambdaFunction, + [&](const FVElementGeometry& fvGeometry) { return possiblyInstationaryAnalyticalVectorialVelocitySolutionAtGridCellCenterLambdaFunction_(fvGeometry, instationaryAnalyticalVelocitySolutionAtPosLambdaFunction); }); + } + + auto getAnalyticalSolution() const + { + auto analyticalVelocitySolutionAtPosLambdaFunction = [&](const SubControlVolumeFace& scvf) { return asImp_().analyticalVelocitySolutionAtPos(scvf); }; + return getAnalyticalSolution_( + [&](const SubControlVolume& scv) { return asImp_().analyticalPressureSolutionAtPos(scv); }, + analyticalVelocitySolutionAtPosLambdaFunction, + [&](const FVElementGeometry& fvGeometry) { return possiblyInstationaryAnalyticalVectorialVelocitySolutionAtGridCellCenterLambdaFunction_(fvGeometry, analyticalVelocitySolutionAtPosLambdaFunction); }); + } + + /*! + * \brief Returns the analytical solution for the pressure + */ + auto& getAnalyticalPressureSolution() const + { + return analyticalPressure_; + } + + /*! + * \brief Returns the analytical solution for the velocity + */ + auto& getAnalyticalVelocitySolution() const + { + return analyticalVelocity_; + } + + /*! + * \brief Returns the analytical solution for the velocity at the faces + */ + auto& getAnalyticalVelocitySolutionOnFace() const + { + return analyticalVelocityOnFace_; + } + + auto& getAnalyticalFaceSolutionVector() const + { + return analyticalFaceSolutionVector_; + } + private: - void setVolumeOrLineForAveragingCorners_(const GlobalPosition& globalPos, std::array<GlobalPosition,4>& volumeForAveragingCorners, std::array<GlobalPosition,2>& lineForAveragingCorners, bool& setVolumeForAveragingCorners, bool& setLineForAveragingCorners) const + template <class Lambda> + VelocityVector possiblyInstationaryAnalyticalVectorialVelocitySolutionAtGridCellCenterLambdaFunction_(const FVElementGeometry& fvGeometry, const Lambda& possiblyInstationaryAnalyticalVelocitySolutionAtPosLambdaFunction) const { - for (const auto& element : elements(this->gridGeometry().gridView())) + VelocityVector analyticalVelocitySolAtCC; + VelocityVector scvfAreas; + + // velocities on faces + for (auto&& scvf : scvfs(fvGeometry)) { - auto fvGeometry = localView(this->gridGeometry()); - fvGeometry.bindElement(element); - for (auto&& scv : scvs(fvGeometry)) - { - if (containerCmp(globalPos,scv.center())) - { - if(scv.geometry().corners()!=4) - { - DUNE_THROW(Dune::InvalidStateException, ""); - } + analyticalVelocitySolAtCC[Indices::velocity(scvf.directionIndex())] += possiblyInstationaryAnalyticalVelocitySolutionAtPosLambdaFunction(scvf)*scvf.area(); + scvfAreas[Indices::velocity(scvf.directionIndex())] += scvf.area(); + } - for (unsigned int i = 0; i < scv.geometry().corners(); ++i) - { - volumeForAveragingCorners[i] = scv.geometry().corner(i); - } + for(int dirIdx = 0; dirIdx < dimWorld; ++dirIdx) + analyticalVelocitySolAtCC[dirIdx] /= scvfAreas[dirIdx]; - setVolumeForAveragingCorners = true; - } + return analyticalVelocitySolAtCC; + } - for (auto&& scvf : scvfs(fvGeometry)) - { - if (!scvf.boundary()) - { - if (containerCmp(globalPos,scvf.center())) - { - volumeForAveragingCorners = localCVVertices<GlobalPosition>(scvf, this->gridGeometry(), true/*hangingNodesAreCVCenters*/); - setVolumeForAveragingCorners = true; - } - } - else - { - if (containerCmp(globalPos,scvf.center())) - { - lineForAveragingCorners[0] = scvf.corner(0); - lineForAveragingCorners[1] = scvf.corner(1); - setLineForAveragingCorners = true; - } - - auto treatVirtualParallelFaceDofPos = [&](const GlobalPosition& thisCorner) - { - if (containerCmp(globalPos, thisCorner)) - { - unsigned int dirIdx = scvf.directionIndex(); - unsigned int nonDirIdx = (dirIdx == 0) ? 1 : 0; - - SubControlVolumeFace normalFaceThisCorner = scvf; - - const SubControlVolumeFace& normalFacePair0 = this->gridGeometry().scvf(scvf.insideScvIdx(), scvf.pairData(0).localNormalFluxCorrectionIndex); - const SubControlVolumeFace& normalFacePair1 = this->gridGeometry().scvf(scvf.insideScvIdx(), scvf.pairData(1).localNormalFluxCorrectionIndex); - - if (scalarCmp(thisCorner[nonDirIdx], normalFacePair0.center()[nonDirIdx])) - { - normalFaceThisCorner = normalFacePair0; - } - else if (scalarCmp(thisCorner[nonDirIdx], normalFacePair1.center()[nonDirIdx])) - { - normalFaceThisCorner = normalFacePair1; - } - else - { - DUNE_THROW(Dune::InvalidStateException, ""); - } - - std::array<GlobalPosition,4> boundaryFullCVCorners = localCVVertices<GlobalPosition>(normalFaceThisCorner, this->gridGeometry(), false/*hangingNodesAreCVCenters*/); - - bool alreadySetFirstLineForAveragingCornersEntry = false; - for (const auto& corner : boundaryFullCVCorners) - { - if (scalarCmp(corner[dirIdx],scvf.center()[dirIdx])) - { - if (!alreadySetFirstLineForAveragingCornersEntry) - { - lineForAveragingCorners[0]=corner; - alreadySetFirstLineForAveragingCornersEntry = true; - } - else - { - lineForAveragingCorners[1]=corner; - } - setLineForAveragingCorners = true; - } - } - } - }; - - treatVirtualParallelFaceDofPos(scvf.corner(0)); - treatVirtualParallelFaceDofPos(scvf.corner(1)); - } - } - } + /*! + * \brief Return the analytical solution of the problem at a given position + * + * \param globalPos The global position + */ + Scalar analyticalVelocitySolutionAtPos_(const SubControlVolumeFace& scvf, unsigned int dirIdx) const + { + AnalyticalSolutionIntegration<TypeTag, MLGTraits> analyticalSolInt(quadOrder_); + if (useScvfLineAveraging_ || (useScvfCVAveraging_ && scvf.boundary())) + { + auto lineGeo = analyticalSolInt.getLineGeometry(scvf, this->gridGeometry()); + return analyticalSolInt.lineIntegral(lineGeo, [&](const GlobalPosition& globalPos) { return asImp_().analyticalSolutionAtPos(globalPos)[Indices::velocity(dirIdx)]; }); } - - if (setLineForAveragingCorners == setVolumeForAveragingCorners) + else if (useScvfCVAveraging_ && !scvf.boundary()) { - DUNE_THROW(Dune::InvalidStateException, "either they both stayed false or they were both set to true, none of which should happen"); + auto rectangleGeo = analyticalSolInt.getRectangleGeometry(scvf, this->gridGeometry()); + return analyticalSolInt.rectangleIntegral(rectangleGeo, [&](const GlobalPosition& globalPos) { return asImp_().analyticalSolutionAtPos(globalPos)[Indices::velocity(dirIdx)]; }); } + else + return asImp_().analyticalSolutionAtPos(scvf.center())[Indices::velocity(dirIdx)]; } - void setIntegralRanges_ (const GlobalPosition& globalPos, bool& integrateX, bool& integrateY, Scalar& xIntegralLeft, Scalar& xIntegralRight, Scalar& yIntegralDown, Scalar& yIntegralUp) const + Scalar instationaryAnalyticalVelocitySolutionAtPos_(const SubControlVolumeFace& scvf, const Scalar time, unsigned int dirIdx) const { - std::array<GlobalPosition,4> volumeForAveragingCorners = {}; - std::array<GlobalPosition,2> lineForAveragingCorners = {}; - - bool setVolumeForAveragingCorners = false; - bool setLineForAveragingCorners = false; + AnalyticalSolutionIntegration<TypeTag, MLGTraits> analyticalSolInt(quadOrder_); + if (useScvfLineAveraging_ || (useScvfCVAveraging_ && scvf.boundary())) + { + auto lineGeo = analyticalSolInt.getLineGeometry(scvf, this->gridGeometry()); + return analyticalSolInt.lineIntegral(lineGeo, [&](const GlobalPosition& globalPos) { return asImp_().instationaryAnalyticalSolutionAtPos(globalPos, time)[Indices::velocity(dirIdx)]; }); + } + else if (useScvfCVAveraging_ && !scvf.boundary()) + { + auto rectangleGeo = analyticalSolInt.getRectangleGeometry(scvf, this->gridGeometry()); + return analyticalSolInt.rectangleIntegral(rectangleGeo, [&](const GlobalPosition& globalPos) { return asImp_().instationaryAnalyticalSolutionAtPos(globalPos, time)[Indices::velocity(dirIdx)]; }); + } + else + return asImp_().instationaryAnalyticalSolutionAtPos(scvf.center(), time)[Indices::velocity(dirIdx)]; + } - setVolumeOrLineForAveragingCorners_(globalPos, volumeForAveragingCorners, lineForAveragingCorners, setVolumeForAveragingCorners, setLineForAveragingCorners); + /*! + * \brief Adds additional VTK output data to the VTKWriter. Function is called by the output module on every write. + */ + template <class LambdaA, class LambdaB, class LambdaC> + void createAnalyticalSolution_(const LambdaA& instationaryAnalyticalPressureSolutionAtPosLambdaFunction, + const LambdaB& instationaryAnalyticalVelocitySolutionAtPosLambdaFunction, + const LambdaC& instationaryAnalyticalVectorialVelocitySolutionAtGridCellCenterLambdaFunction) + { + analyticalPressure_.resize(this->gridGeometry().numCellCenterDofs()); + analyticalVelocity_.resize(this->gridGeometry().numCellCenterDofs()); + analyticalVelocityOnFace_.resize(this->gridGeometry().numFaceDofs()); + analyticalFaceSolutionVector_.resize(this->gridGeometry().numFaceDofs()); - if (setLineForAveragingCorners) + for (const auto& element : elements(this->gridGeometry().gridView())) { - if (scalarCmp(lineForAveragingCorners[0][1], lineForAveragingCorners[1][1])) + auto fvGeometry = localView(this->gridGeometry()); + fvGeometry.bindElement(element); + for (auto&& scv : scvs(fvGeometry)) { - integrateX = true; - if (lineForAveragingCorners[0][0] < lineForAveragingCorners[1][0]) - { - xIntegralLeft = lineForAveragingCorners[0][0]; - xIntegralRight = lineForAveragingCorners[1][0]; - } - else if (lineForAveragingCorners[0][0] > lineForAveragingCorners[1][0]) - { - xIntegralLeft = lineForAveragingCorners[1][0]; - xIntegralRight = lineForAveragingCorners[0][0]; - } - else + // velocities on faces + for (auto&& scvf : scvfs(fvGeometry)) { - DUNE_THROW(Dune::InvalidStateException, ""); + const auto analyticalSolutionAtFace = instationaryAnalyticalVelocitySolutionAtPosLambdaFunction(scvf); + analyticalVelocityOnFace_[scvf.dofIndex()][scvf.directionIndex()] = analyticalSolutionAtFace; + analyticalFaceSolutionVector_[scvf.dofIndex()] = analyticalSolutionAtFace; } + + analyticalPressure_[scv.dofIndex()] = instationaryAnalyticalPressureSolutionAtPosLambdaFunction(scv); + + analyticalVelocity_[scv.dofIndex()] = instationaryAnalyticalVectorialVelocitySolutionAtGridCellCenterLambdaFunction(fvGeometry); } - else if (scalarCmp(lineForAveragingCorners[0][0], lineForAveragingCorners[1][0])) + } + } + + /*! + * \brief Adds additional VTK output data to the VTKWriter. Function is called by the output module on every write. + */ + template <class LambdaA, class LambdaB, class LambdaC> + auto getAnalyticalSolution_(const LambdaA& instationaryAnalyticalPressureSolutionAtPosLambdaFunction, + const LambdaB& instationaryAnalyticalVelocitySolutionAtPosLambdaFunction, + const LambdaC& instationaryAnalyticalVectorialVelocitySolutionAtGridCellCenterLambdaFunction) const + { + CellCenterSolutionVector analyticalPressure; + std::vector<VelocityVector> analyticalVelocity; + std::vector<VelocityVector> analyticalVelocityOnFace; + FaceSolutionVector analyticalFaceSolutionVector; + + analyticalPressure.resize(this->gridGeometry().numCellCenterDofs()); + analyticalVelocity.resize(this->gridGeometry().numCellCenterDofs()); + analyticalVelocityOnFace.resize(this->gridGeometry().numFaceDofs()); + analyticalFaceSolutionVector.resize(this->gridGeometry().numFaceDofs()); + + for (const auto& element : elements(this->gridGeometry().gridView())) + { + auto fvGeometry = localView(this->gridGeometry()); + fvGeometry.bindElement(element); + for (auto&& scv : scvs(fvGeometry)) { - integrateY = true; - if (lineForAveragingCorners[0][1] < lineForAveragingCorners[1][1]) - { - yIntegralDown = lineForAveragingCorners[0][1]; - yIntegralUp = lineForAveragingCorners[1][1]; - } - else if (lineForAveragingCorners[0][1] > lineForAveragingCorners[1][1]) - { - yIntegralDown = lineForAveragingCorners[1][1]; - yIntegralUp = lineForAveragingCorners[0][1]; - } - else + // velocities on faces + for (auto&& scvf : scvfs(fvGeometry)) { - DUNE_THROW(Dune::InvalidStateException, ""); + const auto analyticalSolutionAtFace = instationaryAnalyticalVelocitySolutionAtPosLambdaFunction(scvf); + analyticalVelocityOnFace[scvf.dofIndex()][scvf.directionIndex()] = analyticalSolutionAtFace; + analyticalFaceSolutionVector[scvf.dofIndex()] = analyticalSolutionAtFace; } - } - else - { - DUNE_THROW(Dune::InvalidStateException, ""); - } - } - else //setVolumeForAveragingCorners - { - integrateX = true; - integrateY = true; - xIntegralLeft = std::numeric_limits<Scalar>::max(); - xIntegralRight = std::numeric_limits<Scalar>::min(); - yIntegralDown = std::numeric_limits<Scalar>::max(); - yIntegralUp = std::numeric_limits<Scalar>::min(); + analyticalPressure[scv.dofIndex()] = instationaryAnalyticalPressureSolutionAtPosLambdaFunction(scv); - for (unsigned int i = 0; i < volumeForAveragingCorners.size(); ++i) - { - xIntegralLeft = std::min(xIntegralLeft, volumeForAveragingCorners[i][0]); - xIntegralRight = std::max(xIntegralRight, volumeForAveragingCorners[i][0]); - yIntegralDown = std::min(yIntegralDown, volumeForAveragingCorners[i][1]); - yIntegralUp = std::max(yIntegralUp, volumeForAveragingCorners[i][1]); + analyticalVelocity[scv.dofIndex()] = instationaryAnalyticalVectorialVelocitySolutionAtGridCellCenterLambdaFunction(fvGeometry); } } - } + + return std::make_tuple(analyticalPressure, analyticalVelocity, analyticalVelocityOnFace, analyticalFaceSolutionVector); + } //! Returns a scalar permeability value at the coupling interface Scalar interfacePermeability_(const Element& element, const SubControlVolumeFace& scvf, const GlobalPosition& tangentialVector) const @@ -624,6 +743,17 @@ private: GravityVector gravity_; bool enableInertiaTerms_; MyStaggeredUpwindMethods<Scalar, upwindSchemeOrder> staggeredUpwindMethods_; + + CellCenterSolutionVector analyticalPressure_; + std::vector<VelocityVector> analyticalVelocity_; + std::vector<VelocityVector> analyticalVelocityOnFace_; + FaceSolutionVector analyticalFaceSolutionVector_; + + bool useScvfLineAveraging_; + bool useScvfCVAveraging_; + bool useScvVolumeAveraging_; + bool useContiSourceAveraging_; + unsigned int quadOrder_; }; } // end namespace Dumux -- GitLab From 613fc4fd4adf8182de4534fa4393c9bd51812fc8 Mon Sep 17 00:00:00 2001 From: Melanie Lipp <melanie.lipp@iws.uni-stuttgart.de> Date: Fri, 10 Sep 2021 13:05:44 +0200 Subject: [PATCH 10/69] Rename outputFacility and readdofbasedresult to have different names than in dumux-adaptivestaggered. --- appl/freeflow/navierstokes/donea/main.cc | 2 +- dumux/io/{outputFacility.hh => cvdoutputFacility.hh} | 4 ++-- dumux/io/{readdofbasedresult.hh => cvdreaddofbasedresult.hh} | 0 3 files changed, 3 insertions(+), 3 deletions(-) rename dumux/io/{outputFacility.hh => cvdoutputFacility.hh} (99%) rename dumux/io/{readdofbasedresult.hh => cvdreaddofbasedresult.hh} (100%) diff --git a/appl/freeflow/navierstokes/donea/main.cc b/appl/freeflow/navierstokes/donea/main.cc index 43590d9..a479d84 100644 --- a/appl/freeflow/navierstokes/donea/main.cc +++ b/appl/freeflow/navierstokes/donea/main.cc @@ -60,7 +60,7 @@ bool writeOut = false; #include <dumux/io/grid/cvdcontrolvolumegrids.hh> #include <dumux/freeflow/navierstokes/staggered/cvdresidualCalc.hh> -#include <dumux/io/outputFacility.hh> +#include <dumux/io/cvdoutputFacility.hh> #include "problem.hh" diff --git a/dumux/io/outputFacility.hh b/dumux/io/cvdoutputFacility.hh similarity index 99% rename from dumux/io/outputFacility.hh rename to dumux/io/cvdoutputFacility.hh index ad44629..7735f82 100644 --- a/dumux/io/outputFacility.hh +++ b/dumux/io/cvdoutputFacility.hh @@ -26,11 +26,11 @@ #include <dumux/common/timeloop.hh> #include <dune/grid/io/file/vtk/vtkwriter.hh> -#include <dumux/io/grid/controlvolumegrids.hh> +#include <dumux/io/grid/cvdcontrolvolumegrids.hh> #include <dumux/discretization/staggered/freeflow/geometryhelper/cvdstaggeredgeometryhelper.hh> #include <dumux/discretization/staggered/freeflow/cvdffsubcontrolvolumeface.hh> #include <dumux/freeflow/navierstokes/analyticalSolutionIntegration.hh> -#include <dumux/io/readdofbasedresult.hh> +#include <dumux/io/cvdreaddofbasedresult.hh> namespace Dumux{ template<class TypeTag> diff --git a/dumux/io/readdofbasedresult.hh b/dumux/io/cvdreaddofbasedresult.hh similarity index 100% rename from dumux/io/readdofbasedresult.hh rename to dumux/io/cvdreaddofbasedresult.hh -- GitLab From 5df8e898ee38633f48dde7e54d82043a7b6a98d3 Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Fri, 10 Sep 2021 14:07:02 +0300 Subject: [PATCH 11/69] CVD prefix for mlgtraits --- dumux/freeflow/navierstokes/cvdproblem.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dumux/freeflow/navierstokes/cvdproblem.hh b/dumux/freeflow/navierstokes/cvdproblem.hh index e82f771..e502462 100644 --- a/dumux/freeflow/navierstokes/cvdproblem.hh +++ b/dumux/freeflow/navierstokes/cvdproblem.hh @@ -104,7 +104,7 @@ class MyNavierStokesProblem : public MyNavierStokesParentProblem<TypeTag> using VelocityVector = Dune::FieldVector<Scalar, dimWorld>; using GravityVector = Dune::FieldVector<Scalar, dimWorld>; - using MLGTraits = typename MyFreeFlowStaggeredDefaultScvfGeometryTraits<GridView>::template ScvfMLGTraits<Scalar> ; + using MLGTraits = typename CVDFreeFlowStaggeredDefaultScvfGeometryTraits<GridView>::template ScvfMLGTraits<Scalar> ; public: /*! -- GitLab From 19917d835beac87c96c366890091bcc6b18897f4 Mon Sep 17 00:00:00 2001 From: Melanie Lipp <melanie.lipp@iws.uni-stuttgart.de> Date: Fri, 10 Sep 2021 13:10:11 +0200 Subject: [PATCH 12/69] [subcontrolvolumeface] Add function localNormalFaceBuildingIdx. --- .../staggered/freeflow/cvdffsubcontrolvolumeface.hh | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/dumux/discretization/staggered/freeflow/cvdffsubcontrolvolumeface.hh b/dumux/discretization/staggered/freeflow/cvdffsubcontrolvolumeface.hh index 47df1d9..c2bd2e9 100644 --- a/dumux/discretization/staggered/freeflow/cvdffsubcontrolvolumeface.hh +++ b/dumux/discretization/staggered/freeflow/cvdffsubcontrolvolumeface.hh @@ -309,6 +309,11 @@ public: return pairData_; } + GridIndexType localNormalFaceBuildingIdx (const int idx) const + { + return pairData_[idx].localNormalFluxCorrectionIndex; + } + //! Return an array of all pair data const auto& axisData() const { @@ -510,19 +515,19 @@ public: private: CVDIntersectionBase<GV, Intersection>* intersection_; Dune::GeometryType geomType_; - Scalar area_; + Scalar area_; GlobalPosition center_; GlobalPosition unitOuterNormal_; GridIndexType scvfIndex_; - std::vector<GridIndexType> scvIndices_; + std::vector<GridIndexType> scvIndices_; bool boundary_; - std::vector<GlobalPosition> corners_; + std::vector<GlobalPosition> corners_; int dofIdx_; Scalar selfToOppositeDistance_; std::vector<int> localIndicesOpposingFace_; MyAxisData<Scalar> axisData_; - std::array<MyPairData<Scalar, GlobalPosition>, numPairs> pairData_; + std::array<MyPairData<Scalar, GlobalPosition>, numPairs> pairData_; MyVolVarsData<Scalar, numPairs> volVarsData_; std::vector<MyLocalFaceVelocityData<Scalar>> localVelVarsData_; -- GitLab From a307b17ae5f1ed110d45bc5a8d48e58502b07344 Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Fri, 10 Sep 2021 14:12:41 +0300 Subject: [PATCH 13/69] added cvdAnalyticalSolutionIntegration.hh --- ...tionIntegration.hh => cvdAnalyticalSolutionIntegration.hh} | 4 ++-- dumux/freeflow/navierstokes/cvdproblem.hh | 2 +- dumux/freeflow/navierstokes/staggered/cvdresidualCalc.hh | 2 +- dumux/io/cvdoutputFacility.hh | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) rename dumux/freeflow/navierstokes/{analyticalSolutionIntegration.hh => cvdAnalyticalSolutionIntegration.hh} (98%) mode change 100755 => 100644 diff --git a/dumux/freeflow/navierstokes/analyticalSolutionIntegration.hh b/dumux/freeflow/navierstokes/cvdAnalyticalSolutionIntegration.hh old mode 100755 new mode 100644 similarity index 98% rename from dumux/freeflow/navierstokes/analyticalSolutionIntegration.hh rename to dumux/freeflow/navierstokes/cvdAnalyticalSolutionIntegration.hh index 57f19e9..83ee0c8 --- a/dumux/freeflow/navierstokes/analyticalSolutionIntegration.hh +++ b/dumux/freeflow/navierstokes/cvdAnalyticalSolutionIntegration.hh @@ -20,8 +20,8 @@ * \file * \ingroup NavierStokesModel */ -#ifndef DUMUX_NAVIERSTOKES_ANALYTICAL_SOLUTION_INTEGRATION_HH -#define DUMUX_NAVIERSTOKES_ANALYTICAL_SOLUTION_INTEGRATION_HH +#ifndef DUMUX_CVD_NAVIERSTOKES_ANALYTICAL_SOLUTION_INTEGRATION_HH +#define DUMUX_CVD_NAVIERSTOKES_ANALYTICAL_SOLUTION_INTEGRATION_HH #include <dune/geometry/quadraturerules.hh> #include <dumux/io/grid/cvdcontrolvolumegrids.hh> diff --git a/dumux/freeflow/navierstokes/cvdproblem.hh b/dumux/freeflow/navierstokes/cvdproblem.hh index e502462..fb1f924 100644 --- a/dumux/freeflow/navierstokes/cvdproblem.hh +++ b/dumux/freeflow/navierstokes/cvdproblem.hh @@ -35,7 +35,7 @@ #include <dumux/discretization/staggered/freeflow/cvdffsubcontrolvolumeface.hh> #include <dumux/freeflow/navierstokes/errors.hh> -#include <dumux/freeflow/navierstokes/analyticalSolutionIntegration.hh> +#include <dumux/freeflow/navierstokes/cvdAnalyticalSolutionIntegration.hh> namespace Dumux { diff --git a/dumux/freeflow/navierstokes/staggered/cvdresidualCalc.hh b/dumux/freeflow/navierstokes/staggered/cvdresidualCalc.hh index e946500..144b337 100644 --- a/dumux/freeflow/navierstokes/staggered/cvdresidualCalc.hh +++ b/dumux/freeflow/navierstokes/staggered/cvdresidualCalc.hh @@ -29,7 +29,7 @@ #include <dumux/io/grid/cvdcontrolvolumegrids.hh> #include <dumux/discretization/staggered/freeflow/geometryhelper/cvdstaggeredgeometryhelper.hh> #include <dumux/discretization/staggered/freeflow/cvdffsubcontrolvolumeface.hh> -#include <dumux/freeflow/navierstokes/analyticalSolutionIntegration.hh> +#include <dumux/freeflow/navierstokes/cvdAnalyticalSolutionIntegration.hh> namespace Dumux{ namespace Properties { diff --git a/dumux/io/cvdoutputFacility.hh b/dumux/io/cvdoutputFacility.hh index 7735f82..e53bbda 100644 --- a/dumux/io/cvdoutputFacility.hh +++ b/dumux/io/cvdoutputFacility.hh @@ -29,7 +29,7 @@ #include <dumux/io/grid/cvdcontrolvolumegrids.hh> #include <dumux/discretization/staggered/freeflow/geometryhelper/cvdstaggeredgeometryhelper.hh> #include <dumux/discretization/staggered/freeflow/cvdffsubcontrolvolumeface.hh> -#include <dumux/freeflow/navierstokes/analyticalSolutionIntegration.hh> +#include <dumux/freeflow/navierstokes/cvdAnalyticalSolutionIntegration.hh> #include <dumux/io/cvdreaddofbasedresult.hh> namespace Dumux{ -- GitLab From 704c872af2a72f2f254913662d21379205f15bb5 Mon Sep 17 00:00:00 2001 From: Melanie Lipp <melanie.lipp@iws.uni-stuttgart.de> Date: Fri, 10 Sep 2021 13:20:52 +0200 Subject: [PATCH 14/69] [subcontrolvolumeface] Apply changes related to CornerStorage from commit f97f99c1 of dumux-adaptivestaggered plus changes from e59be871 that are still relevant. --- .../freeflow/cvdffsubcontrolvolumeface.hh | 46 +++++++++++++++++-- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/dumux/discretization/staggered/freeflow/cvdffsubcontrolvolumeface.hh b/dumux/discretization/staggered/freeflow/cvdffsubcontrolvolumeface.hh index c2bd2e9..b82f94b 100644 --- a/dumux/discretization/staggered/freeflow/cvdffsubcontrolvolumeface.hh +++ b/dumux/discretization/staggered/freeflow/cvdffsubcontrolvolumeface.hh @@ -24,9 +24,13 @@ #ifndef DUMUX_DISCRETIZATION_STAGGERED_FREE_FLOW_CVD_SUBCONTROLVOLUMEFACE_HH #define DUMUX_DISCRETIZATION_STAGGERED_FREE_FLOW_CVD_SUBCONTROLVOLUMEFACE_HH +#include <array> #include <utility> #include <dune/common/fvector.hh> +#include <dune/geometry/type.hh> +#include <dune/geometry/multilineargeometry.hh> +#include <dumux/common/typetraits/isvalid.hh> #include <dumux/discretization/refinedsubcontrolvolumefacebase.hh> #include <dumux/discretization/staggered/cvdsubcontrolvolumeface.hh> #include <dumux/discretization/staggered/freeflow/geometryhelper/cvdstaggeredgeometryhelper.hh> @@ -35,6 +39,19 @@ #include <typeinfo> namespace Dumux { +#ifndef DOXYGEN +namespace Detail { +// helper struct detecting if the container class storing the scvf's corners has a resize function +// for g++ > 5.3, this can be replaced by a lambda +struct hasResize +{ + template<class Container> + auto operator()(Container&& c) + -> decltype(c.resize(1)) + {} +}; +} // end namespace Detail +#endif /*! * \ingroup StaggeredDiscretization @@ -80,7 +97,7 @@ struct CVDFreeFlowStaggeredDefaultScvfGeometryTraits * of a sub control volume we compute fluxes on. This is a specialization for free flow models. */ template<class GV, - class T = CVDStaggeredDefaultScvfGeometryTraits<GV> > + class T = CVDFreeFlowStaggeredDefaultScvfGeometryTraits<GV> > class CVDFreeFlowStaggeredSubControlVolumeFace : public RefinedSubControlVolumeFaceBase<CVDFreeFlowStaggeredSubControlVolumeFace<GV, T>, T> { @@ -89,6 +106,7 @@ class CVDFreeFlowStaggeredSubControlVolumeFace using Geometry = typename T::Geometry; using GridIndexType = typename T::GridIndexType; using Intersection = typename T::Intersection; + using CornerStorage = typename T::CornerStorage; using Scalar = typename T::Scalar; static const int dim = Geometry::mydimension; @@ -120,7 +138,6 @@ public: scvfIndex_(scvfIndex), scvIndices_(scvIndices), boundary_(is->boundary()), - corners_(is->cornersvec()), localIndicesOpposingFace_(geometryHelper.localIndicesOpposingFace()), axisData_(geometryHelper.axisData()), @@ -131,6 +148,12 @@ public: dirIdx_(geometryHelper.directionIndex()), outerNormalSign_(sign(unitOuterNormal_[directionIndex()])), isGhostFace_(false) { + + using HasResize = decltype(isValid(Detail::hasResize())(corners_)); + maybeResizeCornerStorage_(HasResize{}, intersection_->corners()); + for (int i = 0; i < intersection_->corners(); ++i) + corners_[i] = intersection_->corner(i); + dofIdx_ = axisData_.selfDof; } @@ -511,8 +534,25 @@ public: return boundaryFace; } + //! set the center to a different position + void setCenter(const GlobalPosition& center) + { center_ = center; } + + //! set the boundary flag + void setBoundary(bool boundaryFlag) + { boundary_ = boundaryFlag; } + + //! set the ghost face flag + void setIsGhostFace(bool isGhostFaceFlag) + { isGhostFace_ = isGhostFaceFlag; } private: + void maybeResizeCornerStorage_(std::true_type /*hasResize*/, std::size_t size) + { corners_.resize(size); } + + void maybeResizeCornerStorage_(std::false_type /*hasResize*/, std::size_t size) + {} + CVDIntersectionBase<GV, Intersection>* intersection_; Dune::GeometryType geomType_; Scalar area_; @@ -521,7 +561,7 @@ private: GridIndexType scvfIndex_; std::vector<GridIndexType> scvIndices_; bool boundary_; - std::vector<GlobalPosition> corners_; + CornerStorage corners_; int dofIdx_; Scalar selfToOppositeDistance_; -- GitLab From 170066574336175e8b4189f3d3702647e5e5050f Mon Sep 17 00:00:00 2001 From: Melanie Lipp <melanie.lipp@iws.uni-stuttgart.de> Date: Fri, 10 Sep 2021 13:38:03 +0200 Subject: [PATCH 15/69] [geometryhelper][genericmethods] Add methods scalarCmp and containerCmp versions with variable epsilon. --- .../cvdgeometryhelpergenericmethods.hh | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/dumux/discretization/staggered/freeflow/geometryhelper/cvdgeometryhelpergenericmethods.hh b/dumux/discretization/staggered/freeflow/geometryhelper/cvdgeometryhelpergenericmethods.hh index 9a6cd33..6f560a1 100644 --- a/dumux/discretization/staggered/freeflow/geometryhelper/cvdgeometryhelpergenericmethods.hh +++ b/dumux/discretization/staggered/freeflow/geometryhelper/cvdgeometryhelpergenericmethods.hh @@ -28,6 +28,23 @@ #include <type_traits> namespace Dumux { +template <class SomeType> +bool containerCmp(const SomeType& a, const SomeType& b, double eps) { + if (a.size() != b.size()) { + std::cout << "containerCmp with different sizes" << std::endl; + return false; + } else { + bool retVal = true; + for (unsigned int i = 0; i < a.size(); ++i) { + if (!((a[i] > b[i] - eps) && (a[i] < b[i] + eps))) { + retVal = false; + break; + } + } + + return retVal; + } +} template <class SomeType> bool containerCmp(const SomeType& a, const SomeType& b) { @@ -56,6 +73,11 @@ bool scalarCmp(const SomeType& a, const SomeType& b) { return a > b - eps && a < b + eps; } +template <class SomeType> +bool scalarCmp(const SomeType& a, const SomeType& b, double eps) { + return a > b - eps && a < b + eps; +} + template <class SomeType> bool areInPlane(const SomeType& a, const SomeType& b, int directionIdx) { for(int i = 0; i<a.size(); i++) @@ -162,4 +184,4 @@ constexpr InputIt scalarFind_(InputIt first, InputIt last, const T& value) { } } // namespace Dumux -#endif \ No newline at end of file +#endif -- GitLab From a21fc3eaf04edf13f0bbb19bba659cb6299449e9 Mon Sep 17 00:00:00 2001 From: Melanie Lipp <melanie.lipp@iws.uni-stuttgart.de> Date: Fri, 10 Sep 2021 14:01:11 +0200 Subject: [PATCH 16/69] Change const like in cc1faf21. --- dumux/discretization/staggered/cvdgridvariables.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dumux/discretization/staggered/cvdgridvariables.hh b/dumux/discretization/staggered/cvdgridvariables.hh index 065092a..d29ae4f 100644 --- a/dumux/discretization/staggered/cvdgridvariables.hh +++ b/dumux/discretization/staggered/cvdgridvariables.hh @@ -240,7 +240,7 @@ public: //! Constructor template<class Problem> CVDStaggeredGridVariables(std::shared_ptr<Problem> problem, - std::shared_ptr<GridGeometry> gridGeometry) + std::shared_ptr<const GridGeometry> gridGeometry) : ParentType(problem, gridGeometry) , curGridFaceVariables_(*problem) , prevGridFaceVariables_(*problem) -- GitLab From f75612eed4e7b46e0ea75e0d5b4227e1583ab8d2 Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Fri, 10 Sep 2021 15:08:51 +0300 Subject: [PATCH 17/69] [intersectionmapper][geometryhelper] Update to new version according to dumux-adaptivestaggered commits 0f21c9de, aa3b80ca and 0e7cc00a. --- dumux/common/cvdintersectionmapper.hh | 60 ++++++++++++------- .../staggered/cvdfvgridgeometry.hh | 32 +++++++--- 2 files changed, 62 insertions(+), 30 deletions(-) diff --git a/dumux/common/cvdintersectionmapper.hh b/dumux/common/cvdintersectionmapper.hh index 86a97b9..c2267e0 100644 --- a/dumux/common/cvdintersectionmapper.hh +++ b/dumux/common/cvdintersectionmapper.hh @@ -58,8 +58,9 @@ class CVDNonConformingGridIntersectionMapper public: CVDNonConformingGridIntersectionMapper(const GridView& gridview) : gridView_(gridview), - numIntersections_(gridView_.size(1)), - intersectionMapGlobal_(gridView_.size(0)) + indexSet_(&gridView_.indexSet()), + numIntersections_(gridView_.size(1)), + intersectionMapGlobal_(gridView_.size(0)) { } @@ -78,7 +79,7 @@ public: std::cout << "should not be after for loop in cvdisIndexInInside in intersectionmapper!" << std::endl; return 0;//just to avoid compiler warning } - + GridIndexType isIndexInInside(const Intersection& myIs) const { int localMyIsIdx = 0; @@ -158,13 +159,13 @@ public: GridIndexType globalIntersectionIdx = 0; for (const auto& element : elements(gridView_)) { - int eIdx = index(element); + int eIdx = index(element); int fIdx = 0; // run through all intersections with neighbors for (const auto& intersection : intersections(gridView_, element)) { - + if (intersection.neighbor()) { auto neighbor = intersection.outside(); int eIdxN = index(neighbor); @@ -175,13 +176,13 @@ public: intersectionMapGlobal_[eIdxN][fIdxN] = globalIntersectionIdx; setVelocityPositions(intersection, globalIntersectionIdx, intersection.geometry().center()); - + globalIntersectionIdx++; } elementIntersections_[eIdx].push_back(cvdIntersection); } else { CVDSimpleIntersection<GridView, Intersection>* cvdIntersection = new CVDSimpleIntersection<GridView, Intersection>(intersection); - + intersectionMapGlobal_[eIdx][fIdx] = globalIntersectionIdx; setVelocityPositions(intersection, globalIntersectionIdx, intersection.geometry().center()); @@ -192,11 +193,25 @@ public: fIdx++; } - } + } numIntersections_ = globalIntersectionIdx; } - void update() + void update (const GridView& gridView) + { + gridView_ = gridView; + indexSet_ = &gridView_.indexSet(); + update_(); + } + + void update (GridView&& gridView) + { + gridView_ = std::move(gridView); + indexSet_ = &gridView_.indexSet(); + update_(); + } + + void update_() { intersectionMapGlobal_.clear(); intersectionMapGlobal_.resize(gridView_.size(0)); @@ -220,7 +235,7 @@ public: // array of vectors for each direction(2 for x, 2 for y) std::vector <Intersection> elementIntersections[4]; for (const auto& intersection : intersections(gridView_, element)) - { + { //map of outernormal indices with corresposing intersections unsigned int outerNormalIdx = outerNormalIndex(intersection); elementIntersections[outerNormalIdx].push_back(intersection); @@ -229,8 +244,8 @@ public: auto interCount = intersectionList.size(); if (interCount == 1) { const auto& intersection = intersectionList.at(0); - - + + CVDSimpleIntersection<GridView, Intersection>* cvdIntersection = new CVDSimpleIntersection<GridView, Intersection>(globalIntersectionIdx, intersection); CVDSimpleIntersection<GridView, Intersection>* nbIntersection = nullptr; //Must create a cvdintersection for neighbor with the same globalIntersectionIndex! @@ -239,13 +254,13 @@ public: const auto& outerIntersection = outerIs(intersection); nbIntersection = new CVDSimpleIntersection<GridView, Intersection>(globalIntersectionIdx, outerIntersection); } - + //Set the global intersection indices setIndicesForIntersectionAndItsNeighbour(intersection, element, eIdx, fIdx, globalIntersectionIdx); fIdx++; //Push local cvdintersection regardless if a new global dof is set or not - //TODO: Ignore if it is part of a shared-dof for refined-to-coarse interface + //TODO: Ignore if it is part of a shared-dof for refined-to-coarse interface if(!cvdIntersection->isInsideFiner() && (cvdIntersection->boundary() || eIdx < index(intersection.outside()))) { @@ -254,10 +269,10 @@ public: { int eIdxN = index(intersection.outside()); elementIntersections_[eIdxN].push_back(nbIntersection); - } + } } else - { + { //Is an intersection that belongs to a doublecvdintersection. Handled below. } } else if (interCount == 2) { @@ -269,12 +284,12 @@ public: //Also create a double cvdIntersection for the two outside() elements. const auto& outsideIsOne = outerIs(intersectionOne); const auto& outsideIsTwo = outerIs(intersectionTwo); - + CVDDoubleIntersection<GridView, Intersection>* fineSideIsOne = new CVDDoubleIntersection<GridView, Intersection>(globalIntersectionIdx, outsideIsOne, outsideIsTwo); CVDDoubleIntersection<GridView, Intersection>* fineSideIsTwo = new CVDDoubleIntersection<GridView, Intersection>(globalIntersectionIdx, outsideIsTwo, outsideIsOne); //Set indices for intersection and its neighbour - setIndicesForDoubleIntersectionAndItsNeighbour(cvdIntersection, element, eIdx, fIdx, globalIntersectionIdx); + setIndicesForDoubleIntersectionAndItsNeighbour(cvdIntersection, element, eIdx, fIdx, globalIntersectionIdx); fIdx+=2; //Push local cvdintersection regardless if a new global dof is set or not @@ -284,7 +299,7 @@ public: } else if(interCount != 0) { DUNE_THROW(Dune::InvalidStateException, "Refinement ratio between cells is higher than 2!"); - } + } } // elementIntersections_[eIdx] = cvdIntersections; } @@ -318,7 +333,7 @@ public: private: GridIndexType index(const Element& element) const { - return gridView_.indexSet().index(element); + return indexSet_->index(element); } void pushElementIntersection(const Element& element, CVDDoubleIntersection<GridView, Intersection>* is) @@ -337,7 +352,7 @@ private: } DUNE_THROW(Dune::InvalidStateException, "Should not be outside of loop in outerIs_!"); return is; - } + } void setIndicesForDoubleIntersectionAndItsNeighbour(CVDDoubleIntersection<GridView, Intersection>* intersection, const Element& element, @@ -447,7 +462,8 @@ private: return 0;//compiler warning ignore } - const GridView gridView_; + GridView gridView_; + const typename GridView::IndexSet* indexSet_; unsigned int numIntersections_; std::vector<std::unordered_map<int, int> > intersectionMapGlobal_; std::vector<std::pair<GridIndexType, GlobalPosition>> velocityXPositions_; diff --git a/dumux/discretization/staggered/cvdfvgridgeometry.hh b/dumux/discretization/staggered/cvdfvgridgeometry.hh index 7b27a8d..21d2a21 100644 --- a/dumux/discretization/staggered/cvdfvgridgeometry.hh +++ b/dumux/discretization/staggered/cvdfvgridgeometry.hh @@ -24,6 +24,8 @@ #ifndef DUMUX_COARSE_VEL_DISC_STAGGERED_FV_GRID_GEOMETRY #define DUMUX_COARSE_VEL_DISC_STAGGERED_FV_GRID_GEOMETRY +#include <utility> + #include <dumux/discretization/basegridgeometry.hh> #include <dumux/discretization/checkoverlapsize.hh> #include <dumux/discretization/method.hh> @@ -235,6 +237,8 @@ public: << " Set the parameter \"Grid.Overlap\" in the input file."); if (hasParamInGroup("Discretization", "TvdApproach")) GeometryHelper::setOrder(2); + + update_(); } //! The total number of sub control volumes @@ -271,18 +275,30 @@ public: std::size_t numFaceDofs() const { return numIntersections(); } - //! update all fvElementGeometries (do this again after grid adaption) - void update() + //! update all fvElementGeometries (call this after grid adaption) + void update(const GridView& gridView) { - ParentType::update(); + ParentType::update(gridView); + update_(); + } + //! update all fvElementGeometries (call this after grid adaption) + void update(GridView&& gridView) + { + ParentType::update(std::move(gridView)); + update_(); + } + + //! update all fvElementGeometries (do this again after grid adaption) + void update_() + { // clear containers (necessary after grid refinement) scvs_.clear(); scvfs_.clear(); scvfIndicesOfScv_.clear(); - + auto intersectionMapper_ = std::make_shared<IntersectionMapper>(this->gridView()); - intersectionMapper_->update(); + intersectionMapper_->update(this->gridView()); numIntersections_ = intersectionMapper_->numIntersections(); @@ -331,7 +347,7 @@ public: //At this point the intersection iteration should be my generic CVDIntersectionBase for (auto& intersection : intersectionMapper_->elementIntersections(element)) { - //TODO: Check if the global dof has been updated for element or not + //TODO: Check if the global dof has been updated for element or not // (for the fine side where two elements have one cvdintersection) // also mark the element face which has the same global dof geometryHelper.updateLocalFace(intersection); @@ -361,7 +377,7 @@ public: scvfs_.emplace_back(intersection, scvfIdx, std::vector<IndexType>({eIdx, nIdx}), - geometryHelper); + geometryHelper); if(intersection->isInsideFiner()) { @@ -378,7 +394,7 @@ public: { localToGlobalScvfIndices_[eIdx][localFaceIndex] = scvfIdx; scvfIndicesOfScv_[eIdx].push_back(scvfIdx++); - } + } } if (intersection->inside().level() != intersection->outside().level()) -- GitLab From 2e97acddc7955d1e1ef12e1219f5c9dd975425d9 Mon Sep 17 00:00:00 2001 From: Melanie Lipp <melanie.lipp@iws.uni-stuttgart.de> Date: Fri, 10 Sep 2021 15:10:23 +0200 Subject: [PATCH 18/69] [fluxvariables] Update to newest version from dumux-adaptivestaggered. --- .../staggered/cvdfluxvariables.hh | 255 +++++++++--------- 1 file changed, 133 insertions(+), 122 deletions(-) diff --git a/dumux/freeflow/navierstokes/staggered/cvdfluxvariables.hh b/dumux/freeflow/navierstokes/staggered/cvdfluxvariables.hh index 422713a..4840dd5 100644 --- a/dumux/freeflow/navierstokes/staggered/cvdfluxvariables.hh +++ b/dumux/freeflow/navierstokes/staggered/cvdfluxvariables.hh @@ -21,8 +21,8 @@ * \ingroup NavierStokesModel * \copydoc Dumux::CVDNavierStokesFluxVariablesImpl */ -#ifndef DUMUX_NAVIERSTOKES_STAGGERED_MY_FLUXVARIABLES_HH -#define DUMUX_NAVIERSTOKES_STAGGERED_MY_FLUXVARIABLES_HH +#ifndef DUMUX_NAVIERSTOKES_STAGGERED_CVD_FLUXVARIABLES_HH +#define DUMUX_NAVIERSTOKES_STAGGERED_CVD_FLUXVARIABLES_HH #include <array> #include <type_traits> @@ -114,14 +114,8 @@ public: UpwindTerm upwindTerm, const FVElementGeometry& fvGeometry, bool writeOut = false) - { + { const Scalar velocity = elemLocalFaceVars[cellCenterIdx].velocity(scvf.outerNormalIndex()); - if(writeOut) - { - auto normal = scvf.unitOuterNormal(); - std::cout<<"Velocity for normal X: "<<normal[0]<<" Y: "<<normal[1]<<" V: "<<velocity<<std::endl; - } - const bool insideIsUpstream = scvf.directionSign() == sign(velocity); static const Scalar upWindWeight = getParamFromGroup<Scalar>(problem.paramGroup(), "Flux.UpwindWeight"); @@ -141,6 +135,7 @@ public: * velocity * scvf.area() * scvf.directionSign(); if (!scvf.isSimple() && scvf.isInsideFiner()) flux *= 0.5; + return flux * harmonicMean(extrusionFactorInsideVolVars.extrusionFactor(), extrusionFactorOutsideVolVars.extrusionFactor()); } @@ -195,7 +190,7 @@ public: FacePrimaryVariables retVal(0.0); FacePrimaryVariables added(0.0); - + const auto eIdx = scvf.insideScvIdx(); const auto sampleOpposingFace = fvGeometry.scvf(eIdx, scvf.localIndicesOpposingFace()[0]);//any one of the possibly two opposing faces is fine -> sample face @@ -218,22 +213,18 @@ public: } else { - added += computeFrontalMomentumFlux(problem, element, scvf, scvf, fvGeometry, elemVolVars, elemFaceVars, writeOut); + added += computeFrontalMomentumFlux(problem, element, scvf, scvf, fvGeometry, elemVolVars, elemFaceVars); } // if (writeOut) // { -// std::cout << "frontal flux contains, " << added << ", for eIdx, " << eIdx << ", and normal ," << scvf.centerUnitOuterNormal()[0] << "," << scvf.centerUnitOuterNormal()[1] << ", 0, 0, 0, 0" << std::endl; +// std::cout << "frontal flux contains, " << added << ", for eIdx, " << eIdx << ", and normal ," << scvf.unitOuterNormal()[0] << "," << scvf.unitOuterNormal()[1] << ", 0, 0, 0, 0" << std::endl; // } retVal += added; retVal += computeLateralMomentumFlux(problem, element, scvf, fvGeometry, elemVolVars, elemFaceVars, curSol, writeOut); - if (writeOut) - { - std::cout<< std::endl << " === Total momentum flux: " << retVal << std::endl; - } return retVal; } @@ -273,12 +264,6 @@ public: // because the fluxes are calculated over the staggered face at the center of the element. const auto& insideVolVars = elemVolVars[scvf].inside; - if(writeOut) - { - std::cout<<std::endl<<" = Frontal momentum flux = "<<std::endl; - // std::cout<<"Self velocity: "<<velocitySelf<<std::endl; - // std::cout<<"Opposite velocity: "<<velocityOpposite<<std::endl; - } // Advective flux. if(problem.enableInertiaTerms()) { @@ -347,10 +332,6 @@ public: // Account for the orientation of the staggered face's normal outer normal vector // (pointing in opposite direction of the scvf's one). - if(writeOut) - { - std::cout << "Advective flux: " << transportingVelocity * momentum * -1.0 * scvf.directionSign() * scvf.area() << std::endl; - } frontalFlux += transportingVelocity * momentum * -1.0 * scvf.directionSign(); } @@ -364,10 +345,6 @@ public: const Scalar factor = enableUnsymmetrizedVelocityGradient ? 1.0 : 2.0; frontalFlux -= factor * insideVolVars.effectiveViscosity() * gradV; - if(writeOut) - { - std::cout << "Diffusive flux: " << -factor * insideVolVars.effectiveViscosity() * gradV * scvf.area() << std::endl; - } // The pressure term. // If specified, the pressure can be normalized using the initial value on the scfv of interest. @@ -381,10 +358,6 @@ public: // (pointing in opposite direction of the scvf's one). frontalFlux += pressure * -1.0 * scvf.directionSign(); - if(writeOut) - { - std::cout << "Pressure term: " << pressure * -1.0 * scvf.directionSign() * scvf.area() << std::endl; - } // Handle inflow or outflow conditions. // Treat the staggered half-volume adjacent to the boundary as if it was on the opposite side of the boundary. @@ -397,10 +370,6 @@ public: // Account for the staggered face's area. For rectangular elements, this equals the area of the scvf // our velocity dof of interest lives on. - if(writeOut) - { - std::cout<<"Total frontal flux: "<< frontalFlux * scvf.area() * extrusionFactorInsideVolVars.extrusionFactor() <<std::endl; - } return frontalFlux * scvf.area() * extrusionFactorInsideVolVars.extrusionFactor(); } @@ -434,11 +403,6 @@ public: auto& faceVars = elemFaceVars[scvf]; const int numSubFaces = scvf.pairData().size(); - if(writeOut) - { - std::cout<< std::endl <<" = Lateral momentum flux = "<<std::endl; - } - // Account for all sub faces. for(int localSubFaceIdx = 0; localSubFaceIdx < numSubFaces; ++localSubFaceIdx) { @@ -472,10 +436,9 @@ public: // Construct a temporary scvf which corresponds to the staggered sub face, featuring the location // the sub faces's center. - localSubFaceCenter = scvf.pairData(localSubFaceIdx).virtualFirstParallelFaceDofPos - normalFace.center(); + localSubFaceCenter = scvf.pairData(localSubFaceIdx).virtualFirstParallelFaceDofPos + normalFace.center(); localSubFaceCenter *= 0.5; - localSubFaceCenter += normalFace.center(); - localSubFace = makeGhostFace_(normalFace, localSubFaceCenter); + localSubFace = makeStaggeredBoundaryFace(normalFace, localSubFaceCenter); // Retrieve the boundary types that correspond to the sub face. const auto bcTypes = problem.boundaryTypes(element, localSubFace); @@ -534,11 +497,11 @@ public: for (const auto& outerScvf : scvfs(fvNormalGeometry)) { - const auto& scvfNormal = scvf.centerUnitOuterNormal(); + const auto& scvfNormal = scvf.unitOuterNormal(); auto minusScvfNormal = scvfNormal; minusScvfNormal *= -1.; - const auto& normalFaceNormal = normalFace.centerUnitOuterNormal(); + const auto& normalFaceNormal = normalFace.unitOuterNormal(); auto minusNormalFaceNormal = normalFaceNormal; minusNormalFaceNormal *= -1.; @@ -546,12 +509,12 @@ public: int outerNormalLocalSubFaceIdx = 0; for (const auto& normalOuterScvf : scvfs(fvNormalGeometry)) { - if (containerCmp(normalOuterScvf.centerUnitOuterNormal(), minusNormalFaceNormal)) + if (containerCmp(normalOuterScvf.unitOuterNormal(), minusNormalFaceNormal)) { outerNormalScvf = normalOuterScvf; break; } - else if (containerCmp(normalOuterScvf.centerUnitOuterNormal(), normalFaceNormal)) + else if (containerCmp(normalOuterScvf.unitOuterNormal(), normalFaceNormal)) { if (ModelTraits::dim() != 2) { @@ -587,7 +550,7 @@ public: ElementFaceVariables outerElemFaceVars(gridFaceVars); outerElemFaceVars.bind(normalFace.outside(), fvNormalGeometry, curSol); - if (containerCmp(outerScvf.centerUnitOuterNormal(), scvfNormal)) + if (containerCmp(outerScvf.unitOuterNormal(), scvfNormal)) { // If there is no symmetry or Neumann boundary condition for the given sub face, proceed to calculate the tangential momentum flux. if(problem.enableInertiaTerms()) @@ -595,7 +558,7 @@ public: normalFluxSubFace -= computeDiffusivePartOfLateralMomentumFlux_(problem, fvGeometry, normalFace.outside(), outerScvf, outerNormalScvf, outerElemVolVars, outerElemFaceVars[outerScvf], outerNormalLocalSubFaceIdx, isDirichletPressure, isBJS, writeOut); } - else if (containerCmp(outerScvf.centerUnitOuterNormal(), minusScvfNormal)) + else if (containerCmp(outerScvf.unitOuterNormal(), minusScvfNormal)) { // If there is no symmetry or Neumann boundary condition for the given sub face, proceed to calculate the tangential momentum flux. if(problem.enableInertiaTerms()) @@ -609,51 +572,19 @@ public: { // If there is no symmetry or Neumann boundary condition for the given sub face, proceed to calculate the tangential momentum flux. if(problem.enableInertiaTerms()) - { - if(writeOut) - { - std::cout<<std::endl; - } - auto advective = computeAdvectivePartOfLateralMomentumFlux_(problem, fvGeometry, element, scvf, normalFace, elemVolVars, faceVars, localSubFaceIdx, isDirichletPressure, isBJS); - if (writeOut) - { - std::cout << "Advective part "<< localSubFaceIdx<< ":" << advective << std::endl; - } - normalFluxSubFace += advective; - } - if(writeOut) - { - std::cout<<std::endl; - } - auto diffusive = computeDiffusivePartOfLateralMomentumFlux_(problem, fvGeometry, element, scvf, normalFace, elemVolVars, faceVars, localSubFaceIdx, isDirichletPressure, isBJS, writeOut); - normalFluxSubFace += diffusive; - if (writeOut) - { - std::cout << "Diffusive part " << localSubFaceIdx << ":" << diffusive << std::endl; - } + normalFluxSubFace += computeAdvectivePartOfLateralMomentumFlux_(problem, fvGeometry, element, scvf, normalFace, elemVolVars, faceVars, localSubFaceIdx, isDirichletPressure, isBJS); + + normalFluxSubFace += computeDiffusivePartOfLateralMomentumFlux_(problem, fvGeometry, element, scvf, normalFace, elemVolVars, faceVars, localSubFaceIdx, isDirichletPressure, isBJS, writeOut); } normalFlux += normalFluxSubFace; - // if(writeOut) - // { - // auto area = normalFace.area(); - // area *= 0.5; - // if (normalFace.isInsideFiner() && !normalFace.isSimple()) - // { - // area *= 0.5; - // } - // std::cout << "Area of normal face " << localSubFaceIdx << ": " << area << std::endl; - // } // if (writeOut) // { -// std::cout << "lateral flux contains, " << normalFluxSubFace << ", for normal idx, " << normalFace.dofIndex() << ", scvf idx, " << scvf.dofIndex() << ", and normal , " << normalFace.centerUnitOuterNormal()[0] << "," << normalFace.centerUnitOuterNormal()[1] << ", eIdx , " << eIdx << std::endl; +// std::cout << "lateral flux contains, " << normalFluxSubFace << ", for normal idx, " << normalFace.dofIndex() << ", scvf idx, " << scvf.dofIndex() << ", and normal , " << normalFace.unitOuterNormal()[0] << "," << normalFace.unitOuterNormal()[1] << ", eIdx , " << eIdx << std::endl; // } } - if (writeOut) - { - std::cout << "Total lateral part :" << normalFlux << std::endl; - } + return normalFlux; } @@ -807,15 +738,15 @@ private: // Account for the orientation of the staggered normal face's outer normal vector // and its area (0.5 of the coinciding scfv). Scalar retVal = transportingVelocity * momentum * normalFace.directionSign() * normalFace.area() * harmonicMean(extrusionFactorInsideVolVars.extrusionFactor(), extrusionFactorOutsideVolVars.extrusionFactor()); - - // static const bool useConservation = getParamFromGroup<bool>(problem.paramGroup(), "Adaptivity.Conservation"); - // if (useConservation || !normalFace.neighbor() || normalFace.inside().level() >= normalFace.outside().level()) - // { + static const bool useConservation = getParamFromGroup<bool>(problem.paramGroup(), "Adaptivity.Conservation"); + +// if (useConservation || !normalFace.neighbor() || normalFace.inside().level() >= normalFace.outside().level()) +// { retVal *= 0.5; - // } +// } - if(normalFace.isInsideFiner() && !normalFace.isSimple()) + if(normalFace.isInsideFiner() && !normalFace.isSimple()) { //In case outside is coarser retVal *= 0.5; @@ -924,13 +855,103 @@ private: * than by velocity(b)/distance(a,b). */ + unsigned int otherSubFaceIdx = (localSubFaceIdx == 0)?1:0; //TODO generalize to 3D + + Scalar deltaParallel1 = scvf.pairData(localSubFaceIdx).parallelDistances[1]; + Scalar deltaParallel0 = scvf.pairData(localSubFaceIdx).parallelDistances[0]; + Scalar deltaOtherParallel0 = scvf.pairData(otherSubFaceIdx).parallelDistances[0]; + Scalar deltaSelf = scvf.area(); + + Scalar deltaParallelOtherParallel0ToInterpolatedVelocityInner = -0.75*deltaSelf - 0.5*deltaOtherParallel0 + 0.25 * deltaParallel0; + Scalar deltaParallel0ToInterpolatedVelocityInner = 0.75*deltaParallel0 + 0.25*deltaSelf; + Scalar deltaSelfToInterpolatedVelocityInner = 0.25*deltaParallel0-0.25*deltaSelf; + + Scalar deltaParallel1ToInterpolatedVelocityOuter = 0.5*deltaParallel1 + 0.75* deltaParallel0 - 0.25* deltaSelf; + Scalar deltaParallel0ToInterpolatedVelocityOuter = 0.25 * (deltaParallel0 - deltaSelf); + Scalar deltaSelfToInterpolatedVelocityOuter = - deltaSelf - 0.25*(deltaParallel0 - deltaSelf); + + const auto parallelVelocity = [&](std::array<Scalar,3> deltas, std::array<Scalar,3> velocities) + { + const auto scalarCmp = [&](const Scalar& a, const Scalar& b) + { + double eps = 1e-10; + + return a > b - eps + && a < b + eps; + }; + + if (!scvf.hasParallelNeighbor(localSubFaceIdx,0) || !scvf.hasParallelNeighbor(otherSubFaceIdx,0) || !scvf.hasParallelNeighbor(localSubFaceIdx,1) ||(scalarCmp(deltaParallel0, deltaOtherParallel0) && scalarCmp(deltaParallel0, scvf.area()))) + { + return velocities[0]; + } + else + { + Dune::FieldMatrix<Scalar,3,3> threeCrossThreeMatrix; + + for (unsigned int i = 0; i<3; ++i) + { + threeCrossThreeMatrix[i][0] = deltas[i]*deltas[i]; + threeCrossThreeMatrix[i][1] = deltas[i]; + threeCrossThreeMatrix[i][2] = 1.; + } + + threeCrossThreeMatrix.invert(); + + std::array<Scalar,3> interpFactors = {threeCrossThreeMatrix[2][0], threeCrossThreeMatrix[2][1], threeCrossThreeMatrix[2][2]}; + + if (!scalarCmp(interpFactors[0]+interpFactors[1]+interpFactors[2],1.)) + { + DUNE_THROW(Dune::InvalidStateException, ""); + } + + Scalar outerParaVel = 0.; + for (unsigned int i = 0; i<3; ++i) + { + outerParaVel += interpFactors[i] * velocities[i]; + } + + return outerParaVel; + } + }; + // For the parallel derivative, get the velocities at the current (own) scvf // and at the parallel one at the neighboring scvf. - const Scalar innerParallelVelocity = faceVars.velocitySelf(); + + Scalar outerParallelVelocity = 0.; + if (!::doFirstOrderLocalTruncErrorGlobalRefinement) + { + if (scvf.hasParallelNeighbor(localSubFaceIdx,0)) + outerParallelVelocity = faceVars.velocityParallel(localSubFaceIdx,0); + } + else + { + std::array<Scalar,3> deltasOuter = {deltaParallel0ToInterpolatedVelocityOuter, deltaSelfToInterpolatedVelocityOuter, deltaParallel1ToInterpolatedVelocityOuter }; + std::array<Scalar,3> velocitiesOuter = {scvf.hasParallelNeighbor(localSubFaceIdx,0)?faceVars.velocityParallel(localSubFaceIdx, 0):faceVars.velocitySelf(), + faceVars.velocitySelf(), + scvf.hasParallelNeighbor(localSubFaceIdx,1)?faceVars.velocityParallel(localSubFaceIdx, 1):(scvf.hasParallelNeighbor(localSubFaceIdx,0)?faceVars.velocityParallel(localSubFaceIdx, 0):faceVars.velocitySelf())}; + + outerParallelVelocity = parallelVelocity(deltasOuter, velocitiesOuter); + } + + Scalar innerParallelVelocity; + if (!::doFirstOrderLocalTruncErrorGlobalRefinement) + { + innerParallelVelocity = faceVars.velocitySelf(); + } + else + { + std::array<Scalar,3> deltasInner = {deltaSelfToInterpolatedVelocityInner, deltaParallel0ToInterpolatedVelocityInner, deltaParallelOtherParallel0ToInterpolatedVelocityInner }; + std::array<Scalar,3> velocitiesInner = {faceVars.velocitySelf(), + scvf.hasParallelNeighbor(localSubFaceIdx,0)?faceVars.velocityParallel(localSubFaceIdx, 0):faceVars.velocityParallel(otherSubFaceIdx, 0), + scvf.hasParallelNeighbor(otherSubFaceIdx,0)?faceVars.velocityParallel(otherSubFaceIdx, 0):faceVars.velocityParallel(localSubFaceIdx, 0)}; + + innerParallelVelocity = parallelVelocity(deltasInner, velocitiesInner); + } + const Scalar deltaParallelVelocities = !::doFirstOrderLocalTruncErrorGlobalRefinement ? scvf.cellCenteredParallelDistance(localSubFaceIdx,0) : (0.5*(deltaParallel0+deltaSelf)); const Scalar velocityFirstParallel = scvf.hasParallelNeighbor(localSubFaceIdx,0) - ? faceVars.velocityParallel(localSubFaceIdx,0) - : getParallelVelocityFromBoundary_(problem, fvGeometry, scvf, normalFace, innerParallelVelocity, localSubFaceIdx, element, false, isBJS); + ? outerParallelVelocity + : getParallelVelocityFromBoundary_(problem, fvGeometry, scvf, normalFace, faceVars.velocitySelf(), localSubFaceIdx, element, false, isBJS); int localOppositeSubFaceIdx = (localSubFaceIdx % 2) ? (localSubFaceIdx - 1) : (localSubFaceIdx + 1); @@ -945,7 +966,8 @@ private: // The velocity gradient already accounts for the orientation // of the staggered face's outer normal vector. const Scalar parallelGradient = factor * (velocityFirstParallel - innerParallelVelocity) - / scvf.cellCenteredParallelDistance(localSubFaceIdx,0); + / deltaParallelVelocities ; + normalDiffusiveFlux -= muAvg * parallelGradient; } @@ -957,13 +979,13 @@ private: Scalar retVal = normalDiffusiveFlux * normalFace.area() * harmonicMean(extrusionFactorInsideVolVars.extrusionFactor(), extrusionFactorOutsideVolVars.extrusionFactor()); - // static const bool useConservation = getParamFromGroup<bool>(problem.paramGroup(), "Adaptivity.Conservation"); + static const bool useConservation = getParamFromGroup<bool>(problem.paramGroup(), "Adaptivity.Conservation"); - // Also have to multiply by 0.5for case normalFace.inside().level()<normalFace.outside().level() (?) - // if (useConservation || !normalFace.neighbor() || normalFace.inside().level() >= normalFace.outside().level()) - // { +// if (useConservation || !normalFace.neighbor() || normalFace.inside().level() >= normalFace.outside().level()) +// { retVal *= 0.5; - // } +// } + if(normalFace.isInsideFiner() && !normalFace.isSimple()) { //In case outside is coarser - meaning it should be 0.25 of normalFace area @@ -1022,19 +1044,6 @@ private: } private: - - //! helper function to conveniently create a ghost face used to retrieve boundary values from the problem - SubControlVolumeFace makeGhostFace_(const SubControlVolumeFace& ownScvf, const GlobalPosition& pos) const - { - return SubControlVolumeFace(pos, std::vector<unsigned int>{ownScvf.insideScvIdx(), ownScvf.outsideScvIdx()}, ownScvf.directionIndex(), ownScvf.dofIndex(), ownScvf.index()); - }; - - //! helper function to conveniently create a ghost face which is outside the domain, parallel to the scvf of interest - SubControlVolumeFace makeParallelGhostFace_(const SubControlVolumeFace& ownScvf, const int localSubFaceIdx) const - { - return makeGhostFace_(ownScvf, ownScvf.pairData(localSubFaceIdx).virtualFirstParallelFaceDofPos); - }; - /*! * \brief Check if a second order approximation for the frontal part of the advective term can be used * @@ -1215,7 +1224,6 @@ private: if (isDirichletPressure) return velocitySelf; - const auto ghostFace = makeParallelGhostFace_(scvf, localSubFaceIdx); if (isBJS) { const auto tangentialVelocityGradient = [&]() @@ -1234,6 +1242,9 @@ private: return problem.beaversJosephVelocity(element, fvGeometry.scv(scvf.insideScvIdx()), scvf, normalFace, velocitySelf, tangentialVelocityGradient); } + + const auto ghostFace = makeStaggeredBoundaryFace(normalFace, scvf.pairData(localSubFaceIdx).virtualFirstParallelFaceDofPos); + return problem.dirichlet(element, ghostFace)[Indices::velocity(scvf.directionIndex())]; }; @@ -1260,7 +1271,7 @@ private: const SubControlVolumeFace& boundaryNormalFace = problem.gridGeometry().scvf(scvf.insideScvIdx(), scvf.pairData(localIdx).localNormalFluxCorrectionIndex); GlobalPosition boundarySubFaceCenter = scvf.pairData(localIdx).virtualFirstParallelFaceDofPos + boundaryNormalFace.center(); boundarySubFaceCenter *= 0.5; - const SubControlVolumeFace boundarySubFace = makeGhostFace_(boundaryNormalFace, boundarySubFaceCenter); + const SubControlVolumeFace boundarySubFace = makeStaggeredBoundaryFace(boundaryNormalFace, boundarySubFaceCenter); // The boundary condition is checked, in case of symmetry or Dirichlet for the pressure // a gradient of zero is assumed in the direction normal to the bounadry, while if there is @@ -1269,14 +1280,14 @@ private: if (bcTypes.isDirichlet(Indices::velocity(scvf.directionIndex()))) { - const SubControlVolumeFace ghostFace = makeParallelGhostFace_(scvf, localIdx); + const SubControlVolumeFace ghostFace = makeStaggeredBoundaryFace(boundaryNormalFace, scvf.pairData(localIdx).virtualFirstParallelFaceDofPos); + return problem.dirichlet(boundaryElement, ghostFace)[Indices::velocity(scvf.directionIndex())]; } else if (bcTypes.isSymmetry() || bcTypes.isDirichlet(Indices::pressureIdx)) return parallelVelocity; else if (bcTypes.isBeaversJoseph(Indices::velocity(scvf.directionIndex()))) { - const SubControlVolumeFace ghostFace = makeParallelGhostFace_(scvf, localIdx); const auto tangentialVelocityGradient = [&]() { // If the current scvf is on a boundary and if a Dirichlet BC for the pressure or a BJ condition for @@ -1362,7 +1373,7 @@ private: const SubControlVolumeFace& normalFace = problem.gridGeometry().scvf(scvf.insideScvIdx(), scvf.pairData(localSubFaceIdx).localNormalFluxCorrectionIndex); - const auto ghostFace = makeGhostFace_(boundaryScvf, getCommonCorner_(scvf, normalFace)); + const auto ghostFace = makeStaggeredBoundaryFace(boundaryScvf, getCommonCorner_(scvf, normalFace)); return problem.dirichlet(boundaryElement, ghostFace)[Indices::velocity(scvf.directionIndex())]; } -- GitLab From 2ee1436b5ac9f9469c165535a5cabeb5afe194d5 Mon Sep 17 00:00:00 2001 From: Melanie Lipp <melanie.lipp@iws.uni-stuttgart.de> Date: Fri, 10 Sep 2021 15:14:04 +0200 Subject: [PATCH 19/69] [fluxvariables] Also comment useConservation to compile free of compiler warnings. --- dumux/freeflow/navierstokes/staggered/cvdfluxvariables.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dumux/freeflow/navierstokes/staggered/cvdfluxvariables.hh b/dumux/freeflow/navierstokes/staggered/cvdfluxvariables.hh index 4840dd5..6c2bc24 100644 --- a/dumux/freeflow/navierstokes/staggered/cvdfluxvariables.hh +++ b/dumux/freeflow/navierstokes/staggered/cvdfluxvariables.hh @@ -739,7 +739,7 @@ private: // and its area (0.5 of the coinciding scfv). Scalar retVal = transportingVelocity * momentum * normalFace.directionSign() * normalFace.area() * harmonicMean(extrusionFactorInsideVolVars.extrusionFactor(), extrusionFactorOutsideVolVars.extrusionFactor()); - static const bool useConservation = getParamFromGroup<bool>(problem.paramGroup(), "Adaptivity.Conservation"); +// static const bool useConservation = getParamFromGroup<bool>(problem.paramGroup(), "Adaptivity.Conservation"); // if (useConservation || !normalFace.neighbor() || normalFace.inside().level() >= normalFace.outside().level()) // { @@ -979,7 +979,7 @@ private: Scalar retVal = normalDiffusiveFlux * normalFace.area() * harmonicMean(extrusionFactorInsideVolVars.extrusionFactor(), extrusionFactorOutsideVolVars.extrusionFactor()); - static const bool useConservation = getParamFromGroup<bool>(problem.paramGroup(), "Adaptivity.Conservation"); +// static const bool useConservation = getParamFromGroup<bool>(problem.paramGroup(), "Adaptivity.Conservation"); // if (useConservation || !normalFace.neighbor() || normalFace.inside().level() >= normalFace.outside().level()) // { -- GitLab From 2359179e32565008dc5847f3df02f595850fcac5 Mon Sep 17 00:00:00 2001 From: Melanie Lipp <melanie.lipp@iws.uni-stuttgart.de> Date: Mon, 13 Sep 2021 09:02:27 +0200 Subject: [PATCH 20/69] [subcontrolvolume] Remove unused constructor. This was also done in dumux-adaptivestaggered. --- .../freeflow/cvdffsubcontrolvolumeface.hh | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/dumux/discretization/staggered/freeflow/cvdffsubcontrolvolumeface.hh b/dumux/discretization/staggered/freeflow/cvdffsubcontrolvolumeface.hh index b82f94b..493d608 100644 --- a/dumux/discretization/staggered/freeflow/cvdffsubcontrolvolumeface.hh +++ b/dumux/discretization/staggered/freeflow/cvdffsubcontrolvolumeface.hh @@ -157,21 +157,6 @@ public: dofIdx_ = axisData_.selfDof; } - //! Constructor for a ghost face outside of the domain. Only needed to retrieve the center and scvIndices - CVDFreeFlowStaggeredSubControlVolumeFace(const GlobalPosition& dofPosition, - const std::vector<GridIndexType>& scvIndices, - const unsigned int dirIdx, - const int dofIdx, - const int scvfIndex) - : center_(dofPosition), - scvfIndex_(scvfIndex), - scvIndices_(scvIndices), - dofIdx_(dofIdx), - selfToOppositeDistance_(0.0), - dirIdx_(dirIdx), - isGhostFace_(true) - {} - //! The center of the sub control volume face const GlobalPosition& center() const { -- GitLab From 3ef773693b2e4302785a549fe8577569b048d7e9 Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Mon, 13 Sep 2021 10:48:44 +0300 Subject: [PATCH 21/69] Fix for corners in doubleIntersection --- .../intersection/cvddoubleintersection.hh | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/dumux/discretization/staggered/intersection/cvddoubleintersection.hh b/dumux/discretization/staggered/intersection/cvddoubleintersection.hh index 82c93e1..f391b61 100644 --- a/dumux/discretization/staggered/intersection/cvddoubleintersection.hh +++ b/dumux/discretization/staggered/intersection/cvddoubleintersection.hh @@ -26,6 +26,7 @@ #include <dumux/discretization/staggered/cvdsubcontrolvolumeface.hh> #include <dumux/discretization/staggered/intersection/cvdintersectionbase.hh> +#include <dumux/discretization/staggered/freeflow/geometryhelper/cvdgeometryhelpergenericmethods.hh> namespace Dumux { @@ -102,12 +103,23 @@ class CVDDoubleIntersection : public CVDIntersectionBase<GV, Intersection> { std::vector<GlobalPosition> cornersvec() { std::vector<GlobalPosition> corners_; - corners_.resize(corners()); + GlobalPosition center = this->center(); + corners_.clear(); int corners1 = intersectionLevelOne_.geometry().corners(); for (int i = 0; i < corners1; ++i) - corners_[i] = intersectionLevelOne_.geometry().corner(i); + { + auto corner = intersectionLevelOne_.geometry().corner(i); + if(!containerCmp(center, corner)){ + corners_.push_back(corner); + } + } for (int i = 0; i < intersectionLevelTwo_.geometry().corners(); ++i) - corners_[i+corners1] = intersectionLevelTwo_.geometry().corner(i); + { + auto corner = intersectionLevelTwo_.geometry().corner(i); + if(!containerCmp(center, corner)){ + corners_.push_back(corner); + } + } return corners_; } @@ -116,7 +128,7 @@ class CVDDoubleIntersection : public CVDIntersectionBase<GV, Intersection> { } unsigned int corners(){ - return (intersectionLevelOne_.geometry().corners() + intersectionLevelTwo_.geometry().corners()); + return 2;//(intersectionLevelOne_.geometry().corners() + intersectionLevelTwo_.geometry().corners()); } Intersection first(){ -- GitLab From 47cba69ebfe7d0400b74bd59c85ebb8f7f87566a Mon Sep 17 00:00:00 2001 From: Melanie Lipp <melanie.lipp@iws.uni-stuttgart.de> Date: Mon, 13 Sep 2021 12:48:22 +0200 Subject: [PATCH 22/69] Freshly copy outputFacility from dumux-adaptivestaggered. --- dumux/io/cvdoutputFacility.hh | 153 ++++++++++++++++------------------ 1 file changed, 72 insertions(+), 81 deletions(-) diff --git a/dumux/io/cvdoutputFacility.hh b/dumux/io/cvdoutputFacility.hh index e53bbda..f8da191 100644 --- a/dumux/io/cvdoutputFacility.hh +++ b/dumux/io/cvdoutputFacility.hh @@ -21,16 +21,16 @@ * \ingroup NavierStokesModel */ -#ifndef DUMUX_CVD_IO_OUTPUTFACILITY_HH -#define DUMUX_CVD_IO_OUTPUTFACILITY_HH +#ifndef DUMUX_IO_OUTPUTFACILITY_HH +#define DUMUX_IO_OUTPUTFACILITY_HH #include <dumux/common/timeloop.hh> #include <dune/grid/io/file/vtk/vtkwriter.hh> -#include <dumux/io/grid/cvdcontrolvolumegrids.hh> -#include <dumux/discretization/staggered/freeflow/geometryhelper/cvdstaggeredgeometryhelper.hh> -#include <dumux/discretization/staggered/freeflow/cvdffsubcontrolvolumeface.hh> -#include <dumux/freeflow/navierstokes/cvdAnalyticalSolutionIntegration.hh> -#include <dumux/io/cvdreaddofbasedresult.hh> +#include <dumux/io/grid/controlvolumegrids.hh> +#include <dumux/discretization/staggered/freeflow/mystaggeredgeometryhelper.hh> +#include <dumux/discretization/staggered/freeflow/mysubcontrolvolumeface.hh> +#include <dumux/freeflow/navierstokes/analyticalSolutionIntegration.hh> +#include <dumux/io/readdofbasedresult.hh> namespace Dumux{ template<class TypeTag> @@ -42,7 +42,7 @@ class CVOutputFacility using SolutionVector = GetPropType<TypeTag, Properties::SolutionVector>; using CellCenterSolutionVector = GetPropType<TypeTag, Properties::CellCenterSolutionVector>; using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; - using MLGTraits = typename CVDFreeFlowStaggeredDefaultScvfGeometryTraits<GridView>::template ScvfMLGTraits<Scalar> ; + using MLGTraits = typename MyFreeFlowStaggeredDefaultScvfGeometryTraits<GridView>::template ScvfMLGTraits<Scalar> ; using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; using Element = typename GridGeometry::GridView::template Codim<0>::Entity; @@ -52,9 +52,11 @@ class CVOutputFacility using HostGrid = Dune::ALUGrid<2,2,Dune::cube,Dune::nonconforming >; using HostGridManager = GridManager<HostGrid>; using CVGridGeometry = GetPropType<TypeTag, Properties::CVGridGeometry>; + using CVElement = typename CVGridGeometry::GridView::template Codim<0>::Entity; + using SubControlVolumeFace = typename GridGeometry::SubControlVolumeFace; using GridVariables = GetPropType<TypeTag, Properties::GridVariables>; - using Assembler = CVDStaggeredRefinedFVAssembler<TypeTag, DiffMethod::numeric>; + using Assembler = StaggeredRefinedFVAssembler<TypeTag, DiffMethod::numeric>; public: /*! @@ -82,7 +84,15 @@ public: gridManagers[i].init(paramGroups[i]); } - void onCVsOutputResidualsAndPrimVars(std::shared_ptr<const GridGeometry> gridGeometry, std::array<HostGridManager, 4>& cvGridManagers, const std::array<std::string, 4>& paramGroups, const SolutionVector& sol, unsigned int timeIndex, const FaceSolutionVector& faceResidualWithAnalyticalSol, const std::optional<std::array<std::vector<Scalar>, 4>>& perfectInterpolationFaceResiduals, bool readDofBasedValues) const + void onCVsOutputResidualsAndPrimVars(std::shared_ptr<const GridGeometry> gridGeometry, + std::array<HostGridManager, 4>& cvGridManagers, + const std::array<std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>>,4>& cvCenterScvfIndicesMaps, + const std::array<std::string, 4>& paramGroups, + const SolutionVector& sol, + unsigned int timeIndex, + const FaceSolutionVector& faceResidualWithAnalyticalSol, + const std::optional<std::array<std::vector<Scalar>, 4>>& perfectInterpolationFaceResiduals, + bool readDofBasedValues) const { std::array<std::vector<std::vector<Scalar>>,4> dualIndexedOutputVecsArray = {}; std::vector<std::string> fineOutputVecNames; @@ -123,7 +133,7 @@ public: finePrimalIndexOutputVecs.push_back(faceResidualWithAnalyticalSol); fineOutputVecNames.push_back("numericalMomResAnalytical"); - std::array<std::vector<std::vector<Scalar>>,2> fineDualIndexOutputVec = onePrimalIndexedVectorToTwoDualIndexedVectors_(finePrimalIndexOutputVecs, cvGridManagers); + std::array<std::vector<std::vector<Scalar>>,2> fineDualIndexOutputVec = onePrimalIndexedVectorToTwoDualIndexedVectors_(finePrimalIndexOutputVecs, cvGridManagers, cvCenterScvfIndicesMaps); for (unsigned int i = 0; i < 2; ++i) for (unsigned int j = 0; j < fineDualIndexOutputVec[i].size(); ++j) dualIndexedOutputVecsArray[i].push_back(fineDualIndexOutputVec[i][j]); @@ -161,7 +171,8 @@ public: } } - void printPvdFiles(const std::array<std::string, 4>& paramGroups, const std::vector<std::pair<unsigned int, Scalar>> pvdFileInfos) + void printPvdFiles(const std::array<std::string, 4>& paramGroups, + const std::vector<std::pair<unsigned int, Scalar>> pvdFileInfos) { for (unsigned int i = 0; i < 4; ++i) { @@ -182,84 +193,64 @@ public: } private: - template<class OutputVecs> - std::array<std::vector<std::vector<Scalar>>,2> onePrimalIndexedVectorToTwoDualIndexedVectors_(OutputVecs& finePrimalIndexOutputVecs, std::array<HostGridManager, 4>& gridManagers) const + /*! + * \brief scvfDofIndex from control volume + * + * \param cv The control volume + */ + unsigned int scvfDofIndexFromCv_(const CVElement& cv, + const std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>>& cvCenterScvfIndicesMap) const { - const auto& xFineCVsLeafGridView = (gridManagers[0]).grid().leafGridView(); - const HostGrid::LeafGridView& yFineCVsLeafGridView = gridManagers[1].grid().leafGridView(); + auto it = cvCenterScvfIndicesMap.find(cv.geometry().center()); + std::vector<unsigned int> scvfIndices = (*it).second; + SubControlVolumeFace scvf = (*problem_).gridGeometry().scvf(scvfIndices[0]); - std::array<std::vector<std::vector<Scalar>>,2> retArray; + return scvf.dofIndex(); + } - std::vector<std::vector<Scalar>> modifiedfinePrimalIndexOutputVecsX; - std::vector<Scalar> dummyVecX; - dummyVecX.resize(xFineCVsLeafGridView.size(0)); - for (unsigned int i = 0; i < finePrimalIndexOutputVecs.size(); ++i) - modifiedfinePrimalIndexOutputVecsX.push_back(dummyVecX); + /*! + * \brief control volume index from control volume + * + * \param cv The control volume + */ + unsigned int cvIndexFromCv_(const CVElement& cv, + const HostGrid::LeafGridView& cvLeafGridView) const + { + return cvLeafGridView.indexSet().index(cv); + } + + template<class OutputVecs> + std::vector<std::vector<Scalar>> onePrimalIndexedVectorToOneDualIndexedVectorInOneDirection_(unsigned int dirIdx, + OutputVecs& finePrimalIndexOutputVecs, + std::array<HostGridManager, 4>& gridManagers, + const std::array<std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>>,4>& cvCenterScvfIndicesMaps) const + { + const HostGrid::LeafGridView& cVsLeafGridView = (gridManagers[dirIdx]).grid().leafGridView(); - std::vector<std::vector<Scalar>> modifiedfinePrimalIndexOutputVecsY; - std::vector<Scalar> dummyVecY; - dummyVecY.resize(yFineCVsLeafGridView.size(0)); + std::vector<std::vector<Scalar>> modifiedfinePrimalIndexOutputVecs; + std::vector<Scalar> dummyVec; + dummyVec.resize(cVsLeafGridView.size(0)); for (unsigned int i = 0; i < finePrimalIndexOutputVecs.size(); ++i) - modifiedfinePrimalIndexOutputVecsY.push_back(dummyVecY); + modifiedfinePrimalIndexOutputVecs.push_back(dummyVec); - for (const auto& element : elements((*problem_).gridGeometry().gridView())) + for (const auto& cv : elements(cVsLeafGridView)) { - auto fvGeometry = localView((*problem_).gridGeometry()); - fvGeometry.bindElement(element); - - for (auto&& scvf : scvfs(fvGeometry)) - { - bool isX = scvf.directionIndex() == 0; - - unsigned int index = 0; - for (const auto& cv : elements(isX ? xFineCVsLeafGridView : yFineCVsLeafGridView)) - { - std::vector<Scalar> xValues; - std::vector<Scalar> yValues; - - for (unsigned int i=0; i < cv.geometry().corners(); ++i) - { - const auto& corner = cv.geometry().corner(i); - - xValues.push_back(corner[0]); - yValues.push_back(corner[1]); - } - - std::sort(xValues.begin(),xValues.end()); - std::sort(yValues.begin(),yValues.end()); - - Scalar left = xValues[0]; - Scalar right = xValues[3]; - Scalar down = yValues[0]; - Scalar up = yValues[3]; - - if ((left < scvf.center()[0] || scalarCmp(left, scvf.center()[0])) && - (scvf.center()[0] < right || scalarCmp(right, scvf.center()[0])) && - (down < scvf.center()[1] || scalarCmp(down, scvf.center()[1])) && - (scvf.center()[1] < up || scalarCmp(up, scvf.center()[1]))) - { - index = (isX ? xFineCVsLeafGridView : yFineCVsLeafGridView).indexSet().index(cv); - } - } - - if (isX) - { - for (unsigned int i = 0; i < finePrimalIndexOutputVecs.size(); ++i) - modifiedfinePrimalIndexOutputVecsX[i][index] = finePrimalIndexOutputVecs[i][scvf.dofIndex()]; - } - else if (scvf.directionIndex() == 1) - { - for (unsigned int i = 0; i < finePrimalIndexOutputVecs.size(); ++i) - modifiedfinePrimalIndexOutputVecsY[i][index] = finePrimalIndexOutputVecs[i][scvf.dofIndex()]; - } - else - { - DUNE_THROW(Dune::InvalidStateException, "wrong"); - } - } + for (unsigned int i = 0; i < finePrimalIndexOutputVecs.size(); ++i) + modifiedfinePrimalIndexOutputVecs[i][cvIndexFromCv_(cv, cVsLeafGridView)] = finePrimalIndexOutputVecs[i][scvfDofIndexFromCv_(cv, cvCenterScvfIndicesMaps[dirIdx])]; } - retArray = {modifiedfinePrimalIndexOutputVecsX, modifiedfinePrimalIndexOutputVecsY}; + return modifiedfinePrimalIndexOutputVecs; + } + + template<class OutputVecs> + std::array<std::vector<std::vector<Scalar>>,2> onePrimalIndexedVectorToTwoDualIndexedVectors_(OutputVecs& finePrimalIndexOutputVecs, + std::array<HostGridManager, 4>& gridManagers, + const std::array<std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>>,4>& cvCenterScvfIndicesMaps) const + { + std::vector<std::vector<Scalar>> modifiedfinePrimalIndexOutputVecsX = onePrimalIndexedVectorToOneDualIndexedVectorInOneDirection_(0, finePrimalIndexOutputVecs, gridManagers, cvCenterScvfIndicesMaps); + std::vector<std::vector<Scalar>> modifiedfinePrimalIndexOutputVecsY = onePrimalIndexedVectorToOneDualIndexedVectorInOneDirection_(1, finePrimalIndexOutputVecs, gridManagers, cvCenterScvfIndicesMaps); + + std::array<std::vector<std::vector<Scalar>>,2> retArray = {modifiedfinePrimalIndexOutputVecsX, modifiedfinePrimalIndexOutputVecsY}; return retArray; } -- GitLab From ff480dcd01cb52b7b4edc26f0e90e563b3cc3d95 Mon Sep 17 00:00:00 2001 From: Melanie Lipp <melanie.lipp@iws.uni-stuttgart.de> Date: Mon, 13 Sep 2021 12:54:12 +0200 Subject: [PATCH 23/69] [outputfacility] Adapt includes, headerguard and class name. --- appl/freeflow/navierstokes/donea/main.cc | 2 +- dumux/io/cvdoutputFacility.hh | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/appl/freeflow/navierstokes/donea/main.cc b/appl/freeflow/navierstokes/donea/main.cc index a479d84..9066a6b 100644 --- a/appl/freeflow/navierstokes/donea/main.cc +++ b/appl/freeflow/navierstokes/donea/main.cc @@ -231,7 +231,7 @@ int main(int argc, char** argv) try std::array<std::string, 4> paramGroups = {"finexCVs", "fineyCVs", "coarsexCVs", "coarseyCVs"}; //xfine... std::array<HostGridManager, 4> cvGridManagers = {}; std::array<std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>>,4> cvCenterScvfIndicesMaps; - CVOutputFacility<TypeTag> cvOutputFacility(problem); + CVDCVOutputFacility<TypeTag> cvOutputFacility(problem); cvOutputFacility.iniCVGridManagers(cvGridManagers, cvCenterScvfIndicesMaps, paramGroups); using Scalar = GetPropType<TypeTag, Properties::Scalar>; std::vector<std::pair<unsigned int, Scalar>> pvdFileInfos; diff --git a/dumux/io/cvdoutputFacility.hh b/dumux/io/cvdoutputFacility.hh index f8da191..b4cdf4c 100644 --- a/dumux/io/cvdoutputFacility.hh +++ b/dumux/io/cvdoutputFacility.hh @@ -21,20 +21,20 @@ * \ingroup NavierStokesModel */ -#ifndef DUMUX_IO_OUTPUTFACILITY_HH -#define DUMUX_IO_OUTPUTFACILITY_HH +#ifndef DUMUX_CVD_IO_OUTPUTFACILITY_HH +#define DUMUX_CVD_IO_OUTPUTFACILITY_HH #include <dumux/common/timeloop.hh> #include <dune/grid/io/file/vtk/vtkwriter.hh> -#include <dumux/io/grid/controlvolumegrids.hh> -#include <dumux/discretization/staggered/freeflow/mystaggeredgeometryhelper.hh> -#include <dumux/discretization/staggered/freeflow/mysubcontrolvolumeface.hh> -#include <dumux/freeflow/navierstokes/analyticalSolutionIntegration.hh> -#include <dumux/io/readdofbasedresult.hh> +#include <dumux/io/grid/cvdcontrolvolumegrids.hh> +#include <dumux/discretization/staggered/freeflow/geometryhelper/cvdstaggeredgeometryhelper.hh> +#include <dumux/discretization/staggered/freeflow/cvdffsubcontrolvolumeface.hh> +#include <dumux/freeflow/navierstokes/cvdAnalyticalSolutionIntegration.hh> +#include <dumux/io/cvdreaddofbasedresult.hh> namespace Dumux{ template<class TypeTag> -class CVOutputFacility +class CVDCVOutputFacility { using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; using GridView = typename GridGeometry::GridView; @@ -42,7 +42,7 @@ class CVOutputFacility using SolutionVector = GetPropType<TypeTag, Properties::SolutionVector>; using CellCenterSolutionVector = GetPropType<TypeTag, Properties::CellCenterSolutionVector>; using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; - using MLGTraits = typename MyFreeFlowStaggeredDefaultScvfGeometryTraits<GridView>::template ScvfMLGTraits<Scalar> ; + using MLGTraits = typename CVDFreeFlowStaggeredDefaultScvfGeometryTraits<GridView>::template ScvfMLGTraits<Scalar> ; using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; using Element = typename GridGeometry::GridView::template Codim<0>::Entity; @@ -56,13 +56,13 @@ class CVOutputFacility using SubControlVolumeFace = typename GridGeometry::SubControlVolumeFace; using GridVariables = GetPropType<TypeTag, Properties::GridVariables>; - using Assembler = StaggeredRefinedFVAssembler<TypeTag, DiffMethod::numeric>; + using Assembler = CVDStaggeredRefinedFVAssembler<TypeTag, DiffMethod::numeric>; public: /*! * \brief The Constructor */ - CVOutputFacility(std::shared_ptr<const Problem> problem) + CVDCVOutputFacility(std::shared_ptr<const Problem> problem) : problem_(problem) {} -- GitLab From 16a359f39458305a617a75cc2c810eae28330fe0 Mon Sep 17 00:00:00 2001 From: Melanie Lipp <melanie.lipp@iws.uni-stuttgart.de> Date: Mon, 13 Sep 2021 14:34:35 +0200 Subject: [PATCH 24/69] [output] Adapt output functionality to be actually meaningful in the coarse-velocity-discretization context. Output of perfect residuals is dropped. That way, we also only need coarse cv grids. --- appl/freeflow/navierstokes/donea/main.cc | 13 +- .../cvdAnalyticalSolutionIntegration.hh | 4 +- .../navierstokes/staggered/cvdresidualCalc.hh | 743 +----------------- dumux/io/cvdoutputFacility.hh | 103 ++- dumux/io/grid/cvdcontrolvolumegrids.hh | 124 +-- 5 files changed, 89 insertions(+), 898 deletions(-) diff --git a/appl/freeflow/navierstokes/donea/main.cc b/appl/freeflow/navierstokes/donea/main.cc index 9066a6b..2aaa047 100644 --- a/appl/freeflow/navierstokes/donea/main.cc +++ b/appl/freeflow/navierstokes/donea/main.cc @@ -228,9 +228,9 @@ int main(int argc, char** argv) try using HostGrid = Dune::ALUGrid<2,2,Dune::cube,Dune::nonconforming >; using HostGridManager = GridManager<HostGrid>; - std::array<std::string, 4> paramGroups = {"finexCVs", "fineyCVs", "coarsexCVs", "coarseyCVs"}; //xfine... - std::array<HostGridManager, 4> cvGridManagers = {}; - std::array<std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>>,4> cvCenterScvfIndicesMaps; + std::array<std::string, 2> paramGroups = {"coarsexCVs", "coarseyCVs"}; + std::array<HostGridManager, 2> cvGridManagers = {}; + std::array<std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>>,2> cvCenterScvfIndicesMaps; CVDCVOutputFacility<TypeTag> cvOutputFacility(problem); cvOutputFacility.iniCVGridManagers(cvGridManagers, cvCenterScvfIndicesMaps, paramGroups); using Scalar = GetPropType<TypeTag, Properties::Scalar>; @@ -247,12 +247,10 @@ int main(int argc, char** argv) try using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; FaceSolutionVector numericalFaceResidualWithAnalytical; - std::optional<std::array<std::vector<Scalar>, 4>> optionalPerfectInterpolationFaceResiduals; - std::array<std::vector<Scalar>, 4> perfectInterpolationFaceResiduals; - optionalPerfectInterpolationFaceResiduals.emplace(perfectInterpolationFaceResiduals); + std::optional<std::array<std::vector<Scalar>, 2>> optionalPerfectInterpolationFaceResiduals; ResidualCalc<TypeTag> residualCalc(problem); - residualCalc.calcResidualsStationary(gridGeometry, cvGridManagers, cvCenterScvfIndicesMaps, numericalCCResidualWithAnalytical, numericalFaceResidualWithAnalytical, optionalPerfectInterpolationFaceResiduals); + residualCalc.calcResidualsStationary(gridGeometry, numericalCCResidualWithAnalytical, numericalFaceResidualWithAnalytical); bool readDofBasedValues = getParam<bool>("Problem.ReadDofBasedValues", false); if (readDofBasedValues) @@ -269,6 +267,7 @@ int main(int argc, char** argv) try cvOutputFacility.onCVsOutputResidualsAndPrimVars( gridGeometry, cvGridManagers, + cvCenterScvfIndicesMaps, paramGroups, x, 0, diff --git a/dumux/freeflow/navierstokes/cvdAnalyticalSolutionIntegration.hh b/dumux/freeflow/navierstokes/cvdAnalyticalSolutionIntegration.hh index 83ee0c8..569198a 100644 --- a/dumux/freeflow/navierstokes/cvdAnalyticalSolutionIntegration.hh +++ b/dumux/freeflow/navierstokes/cvdAnalyticalSolutionIntegration.hh @@ -94,7 +94,7 @@ public: auto getRectangleGeometry(const SubControlVolumeFace& scvf, const GridGeometry& gridGeometry) const { - const auto& averagingVolumeCorners = localCVVertices<GlobalPosition>(scvf, gridGeometry, false/*hangingNodesAreCVCenters*/); + const auto& averagingVolumeCorners = localCVVertices<GlobalPosition>(scvf, gridGeometry); using RectangleCorners = typename MLGTraits::template CornerStorage<2/*rectangle dimension*/, dimWorld/*coordinate dimension*/>::Type; @@ -158,7 +158,7 @@ private: DUNE_THROW(Dune::InvalidStateException, ""); } - std::array<GlobalPosition,4> boundaryFullCVCorners = localCVVertices<GlobalPosition>(normalFaceThisCorner, gridGeometry, false/*hangingNodesAreCVCenters*/); + std::array<GlobalPosition,4> boundaryFullCVCorners = localCVVertices<GlobalPosition>(normalFaceThisCorner, gridGeometry); using LineCorners = typename MLGTraits::template CornerStorage<1/*line dimension*/, dimWorld/*coordinate dimension*/>::Type; diff --git a/dumux/freeflow/navierstokes/staggered/cvdresidualCalc.hh b/dumux/freeflow/navierstokes/staggered/cvdresidualCalc.hh index 144b337..79db31a 100644 --- a/dumux/freeflow/navierstokes/staggered/cvdresidualCalc.hh +++ b/dumux/freeflow/navierstokes/staggered/cvdresidualCalc.hh @@ -71,22 +71,9 @@ public: {} void calcResidualsStationary(std::shared_ptr<const GridGeometry> gridGeometry, - std::array<HostGridManager, 4>& cvGridManagers, - const std::array<std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>>,4>& cvCenterScvfIndicesMaps, CellCenterSolutionVector& cellCenterResidualWithAnalyticalSol, - FaceSolutionVector& faceResidualWithAnalyticalSol, - std::optional<std::array<std::vector<Scalar>, 4>>& perfectInterpolationFaceResiduals) const + FaceSolutionVector& faceResidualWithAnalyticalSol) const { - if (perfectInterpolationFaceResiduals) - *perfectInterpolationFaceResiduals = calcPerfectInterpolationFaceResidual_( - [&] (const GlobalPosition& globalPos, Scalar time) { return problem_->analyticalSolutionAtPos (globalPos); }, - [&] (const GlobalPosition& globalPos, Scalar time) { return problem_->sourceAtPos (globalPos); }, - true, - 0., - 0., - cvGridManagers, - cvCenterScvfIndicesMaps); - SolutionVector numericalResidual = calcNumericalResidualStationary_(gridGeometry); FaceSolutionVector areaWeightedFaceResidualWithAnalyticalSol = numericalResidual[GridGeometry::faceIdx()]; @@ -100,25 +87,12 @@ public: void calcResidualsInstationary(std::shared_ptr<const TimeLoop<Scalar>> timeLoop, std::shared_ptr<const GridGeometry> gridGeometry, - std::array<HostGridManager, 4>& cvGridManagers, - const std::array<std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>>,4>& cvCenterScvfIndicesMaps, CellCenterSolutionVector& cellCenterResidualWithAnalyticalSol, - FaceSolutionVector& faceResidualWithAnalyticalSol, - std::optional<std::array<std::vector<Scalar>, 4>>& perfectInterpolationFaceResiduals) const + FaceSolutionVector& faceResidualWithAnalyticalSol) const { Scalar t = timeLoop->time()+timeLoop->timeStepSize(); Scalar tOld = timeLoop->time(); - if (perfectInterpolationFaceResiduals) - *perfectInterpolationFaceResiduals = calcPerfectInterpolationFaceResidual_( - [&] (const GlobalPosition& globalPos, Scalar time) { return problem_->instationaryAnalyticalSolutionAtPos (globalPos, time); }, - [&] (const GlobalPosition& globalPos, Scalar time) { return problem_->instationarySourceAtPos (globalPos, time); }, - false, - t, - tOld, - cvGridManagers, - cvCenterScvfIndicesMaps); - SolutionVector numericalResidual = calcNumericalResidualInstationary_(gridGeometry, timeLoop, t, tOld); FaceSolutionVector areaWeightedFaceResidualWithAnalyticalSol = numericalResidual[GridGeometry::faceIdx()]; @@ -146,7 +120,11 @@ private: fvGeometry.bindElement(element); for (const auto& scvf : scvfs(fvGeometry)) { - cvAreas[scvf.dofIndex()] += (scvf.area() * 0.5 * scvf.selfToOppositeDistance()); + Scalar addToCVArea = (scvf.area() * 0.5 * scvf.selfToOppositeDistance()); + if (scvf.isInsideFiner()) + addToCVArea *= 0.5; + + cvAreas[scvf.dofIndex()] += addToCVArea; } } @@ -170,26 +148,6 @@ private: return resVec; } - template<class LambdaA, class LambdaB> - std::array<std::vector<Scalar>,4> calcPerfectInterpolationFaceResidual_( - const LambdaA& possiblyInstationaryAnalyticalSolution, - const LambdaB& possiblyInstationarySourceAtPos, - bool isStationary, - Scalar t, - Scalar tOld, - std::array<HostGridManager, 4>& gridManagers, - const std::array<std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>>,4>& cvCenterScvfIndicesMaps) const - { - std::array<std::vector<Scalar>,4> retArray; - - fillResidual_(possiblyInstationaryAnalyticalSolution, possiblyInstationarySourceAtPos, isStationary, t, tOld, retArray[0], gridManagers[0].grid().leafGridView(), cvCenterScvfIndicesMaps[0], 0, false); - fillResidual_(possiblyInstationaryAnalyticalSolution, possiblyInstationarySourceAtPos, isStationary, t, tOld, retArray[1], gridManagers[1].grid().leafGridView(), cvCenterScvfIndicesMaps[1], 1, false); - fillResidual_(possiblyInstationaryAnalyticalSolution, possiblyInstationarySourceAtPos, isStationary, t, tOld, retArray[2], gridManagers[2].grid().leafGridView(), cvCenterScvfIndicesMaps[2], 0, true); - fillResidual_(possiblyInstationaryAnalyticalSolution, possiblyInstationarySourceAtPos, isStationary, t, tOld, retArray[3], gridManagers[3].grid().leafGridView(), cvCenterScvfIndicesMaps[3], 1, true); - - return retArray; - } - SolutionVector calcNumericalResidualInstationary_(std::shared_ptr<const GridGeometry> gridGeometry, std::shared_ptr<const TimeLoop<Scalar>> timeLoop, Scalar t, Scalar tOld) const { const auto analyticalTPlusDeltaTTuple = problem_->getAnalyticalSolution(t); @@ -244,693 +202,6 @@ private: return residual; } - Scalar residual_(bool isStationary, Scalar velSelfOld, Scalar deltaT, Scalar leftOrDownOppoDelta, Scalar rightOrUpOppoDelta, Scalar rightOrUpLateralDelta, Scalar scvfDelta, Scalar leftOrDownLateralDelta, Scalar q, Scalar velSelf, Scalar velParallelRightOrUp, Scalar velParallelLeftOrDown, Scalar velOppoRightOrUp, Scalar velOppoLeftOrDown, Scalar velNormalUpRightOrRightUp, Scalar velNormalUpLeftOrRightDown, Scalar velNormalDownRightOrLeftUp, Scalar velNormalDownLeftOrLeftDown, Scalar presLeftOrDown, Scalar presRightOrUp, bool navierStokes, Scalar viscosity) const - { - Scalar opposDelta = .5 * (leftOrDownOppoDelta + rightOrUpOppoDelta); - Scalar density = 1.; //can only deal with constant viscosity here - - Scalar res = -q*opposDelta * scvfDelta - + ( 2*opposDelta/(rightOrUpLateralDelta+scvfDelta) + 2*opposDelta/(leftOrDownLateralDelta+scvfDelta) + 2*scvfDelta/leftOrDownOppoDelta + 2*scvfDelta/rightOrUpOppoDelta ) * viscosity * velSelf - + ( -2*opposDelta/(rightOrUpLateralDelta+scvfDelta)) * viscosity * velParallelRightOrUp - + ( -2*opposDelta/(leftOrDownLateralDelta+scvfDelta) ) * viscosity * velParallelLeftOrDown - + ( -2*scvfDelta/leftOrDownOppoDelta ) * viscosity * velOppoLeftOrDown - + ( -2*scvfDelta/rightOrUpOppoDelta ) * viscosity * velOppoRightOrUp - - velNormalUpRightOrRightUp * viscosity - + velNormalUpLeftOrRightDown * viscosity - + velNormalDownRightOrLeftUp * viscosity - - velNormalDownLeftOrLeftDown * viscosity - - scvfDelta* presLeftOrDown - + scvfDelta * presRightOrUp; - - // std::cout << "source " << -q*opposDelta * scvfDelta; - // std::cout << ", self " << ( 2*opposDelta/(rightOrUpLateralDelta+scvfDelta) + 2*opposDelta/(leftOrDownLateralDelta+scvfDelta) + 2*scvfDelta/leftOrDownOppoDelta + 2*scvfDelta/rightOrUpOppoDelta ) * viscosity * velSelf; - // std::cout << ", parallel a " << ( -2*opposDelta/(rightOrUpLateralDelta+scvfDelta)) * viscosity * velParallelRightOrUp; - // std::cout << ", prallel b " << ( -2*opposDelta/(leftOrDownLateralDelta+scvfDelta) ) * viscosity * velParallelLeftOrDown; - // std::cout << ", oppo a " << ( -2*scvfDelta/leftOrDownOppoDelta ) * viscosity * velOppoLeftOrDown; - // std::cout << ", oppo b " << ( -2*scvfDelta/rightOrUpOppoDelta ) * viscosity * velOppoRightOrUp; - // std::cout << ", normal a " << - velNormalUpRightOrRightUp * viscosity; - // std::cout << ", normal b " << velNormalUpLeftOrRightDown * viscosity; - // std::cout << ", normal c " << velNormalDownRightOrLeftUp * viscosity; - // std::cout << ", normal d " << - velNormalDownLeftOrLeftDown * viscosity; - // std::cout << ", pressure a " << - scvfDelta* presLeftOrDown; - // std::cout << ", pressure b " << scvfDelta * presRightOrUp; - // std::cout << std::endl; - - // std::cout << "res = " << res << std::endl; - // - // std::cout << "opposDelta * scvfDelta = " << opposDelta * scvfDelta << std::endl; - // - // std::cout << "d_y u term: " << - // ((2/(rightOrUpLateralDelta+scvfDelta) + 2/(leftOrDownLateralDelta+scvfDelta))/(scvfDelta)* velSelf - // + ( -2/(rightOrUpLateralDelta+scvfDelta))/(scvfDelta) * velParallelRightOrUp - // + ( -2/(leftOrDownLateralDelta+scvfDelta))/(scvfDelta) * velParallelLeftOrDown) << std::endl; - - // Scalar selfCoefficient = ((leftOrDownLateralDelta+scvfDelta)/(2.*scvfDelta)+(rightOrUpLateralDelta+scvfDelta)/(2.*scvfDelta))/(((rightOrUpLateralDelta+scvfDelta)/2.)*((leftOrDownLateralDelta+scvfDelta)/2.))*scvfDelta*scvfDelta; - // Scalar upCoefficient = (leftOrDownLateralDelta+scvfDelta)/(2.*scvfDelta)/(((rightOrUpLateralDelta+scvfDelta)/2.)*((leftOrDownLateralDelta+scvfDelta)/2.))*scvfDelta*scvfDelta; - // Scalar downCoefficient = (rightOrUpLateralDelta+scvfDelta)/(2.*scvfDelta)/(((rightOrUpLateralDelta+scvfDelta)/2.)*((leftOrDownLateralDelta+scvfDelta)/2.))*scvfDelta*scvfDelta; - - // std::cout << "selfCoefficient " << selfCoefficient << ", upCoefficient = " << upCoefficient << ", downCoefficient = " << downCoefficient << std::endl; - - // std::cout << "var d_y u term: " << - // (selfCoefficient*velSelf - // -upCoefficient*velParallelRightOrUp - // -downCoefficient*velParallelLeftOrDown) - // /(scvfDelta*scvfDelta) - // << std::endl; - // - // std::cout << "pressure term: " << (- scvfDelta* presLeftOrDown + scvfDelta * presRightOrUp)/(opposDelta * scvfDelta) << std::endl; - - if (navierStokes) - { - auto mixedVelocity = [&](Scalar upwindVelocity, Scalar downwindVelocity) - { - Scalar upwindWeight = Dumux::getParam<Scalar>("Flux.UpwindWeight", 1.); - return upwindWeight * upwindVelocity + (1. - upwindWeight) * downwindVelocity; - }; - - //x:left, y: down - Scalar transportingVelocity = (velSelf + velOppoLeftOrDown) * 0.5; - Scalar upwindVelocity = (Dumux::sign(transportingVelocity) == +1) ? velOppoLeftOrDown : velSelf; - Scalar downwindVelocity = (Dumux::sign(transportingVelocity) == +1) ? velSelf : velOppoLeftOrDown; - - res -= scvfDelta * density * transportingVelocity * mixedVelocity(upwindVelocity,downwindVelocity); - - //x:right, y: up - transportingVelocity = (velSelf + velOppoRightOrUp) * 0.5; - upwindVelocity = (Dumux::sign(transportingVelocity) == +1) ? velSelf : velOppoRightOrUp; - downwindVelocity = (Dumux::sign(transportingVelocity) == +1) ? velOppoRightOrUp : velSelf; - - res += scvfDelta * density * transportingVelocity * mixedVelocity(upwindVelocity,downwindVelocity); - - //x:upright, y: rightup - if (rightOrUpLateralDelta == 0.) - { - upwindVelocity = velParallelRightOrUp; - downwindVelocity = velParallelRightOrUp; - } - else - { - upwindVelocity = (Dumux::sign(velNormalUpRightOrRightUp)==+1) ? velSelf : velParallelRightOrUp; - downwindVelocity = (Dumux::sign(velNormalUpRightOrRightUp)==+1) ? velParallelRightOrUp : velSelf; - } - - res += .25 * (leftOrDownOppoDelta+rightOrUpOppoDelta) * density * mixedVelocity(upwindVelocity,downwindVelocity) * velNormalUpRightOrRightUp; - - //x: downright, y: leftup - if (leftOrDownLateralDelta == 0.) - { - upwindVelocity = velParallelLeftOrDown; - downwindVelocity = velParallelLeftOrDown; - } - else - { - upwindVelocity = (Dumux::sign(velNormalDownRightOrLeftUp)==+1) ? velParallelLeftOrDown : velSelf; - downwindVelocity = (Dumux::sign(velNormalDownRightOrLeftUp)==+1) ? velSelf : velParallelLeftOrDown; - } - - res -= .25 * (leftOrDownOppoDelta+rightOrUpOppoDelta) * density * mixedVelocity(upwindVelocity,downwindVelocity) * velNormalDownRightOrLeftUp; - - //x:upleft, y: rightdown - if (rightOrUpLateralDelta == 0.) - { - downwindVelocity = velParallelRightOrUp; - upwindVelocity = velParallelRightOrUp; - } - else - { - downwindVelocity = (Dumux::sign(velNormalUpLeftOrRightDown)==+1) ? velParallelRightOrUp : velSelf; - upwindVelocity = (Dumux::sign(velNormalUpLeftOrRightDown)==+1) ? velSelf : velParallelRightOrUp; - } - - res += .25 * (leftOrDownOppoDelta+rightOrUpOppoDelta)* density * mixedVelocity(upwindVelocity,downwindVelocity) * velNormalUpLeftOrRightDown; - - //x:downleft, y: leftdown - if (leftOrDownLateralDelta == 0.) - { - upwindVelocity = velParallelLeftOrDown; - downwindVelocity = velParallelLeftOrDown; - } - else - { - upwindVelocity = (Dumux::sign(velNormalDownLeftOrLeftDown)==+1) ? velParallelLeftOrDown : velSelf; - downwindVelocity = (Dumux::sign(velNormalDownLeftOrLeftDown)==+1) ? velSelf : velParallelLeftOrDown; - } - - res -= .25 * (leftOrDownOppoDelta+rightOrUpOppoDelta) * density * mixedVelocity(upwindVelocity,downwindVelocity) * velNormalDownLeftOrLeftDown; - } - - if (!isStationary) - { - res += (velSelf - velSelfOld) / deltaT * opposDelta * scvfDelta; - } - - // std::cout << "final res = " << res/(opposDelta * scvfDelta) << std::endl; - - return res/(opposDelta * scvfDelta); //that should be the one relevant for grid convergence - } - - template <class LambdaA> - Scalar possiblyInstationaryPossiblyMeanAnalyticalVelocityySolutionAtPos_(const LambdaA& possiblyInstationaryAnalyticalSolution, const std::array<GlobalPosition, 2>& corners, unsigned int dirIdx, Scalar t) const - { - if ((*problem_).useScvfLineAveraging() ) - { - AnalyticalSolutionIntegration<TypeTag, MLGTraits> analyticalSolInt((*problem_).quadOrder()); - auto lineGeo = analyticalSolInt.getLineGeometry(corners); - return analyticalSolInt.lineIntegral(lineGeo, [&](const GlobalPosition& globalPos) { return possiblyInstationaryAnalyticalSolution(globalPos,t)[Indices::velocity(dirIdx)]; }); - } - else if ((*problem_).useScvfCVAveraging() ) - { - DUNE_THROW(Dune::InvalidStateException, "Residual calc can only do line averaging for scvf."); - } - else - { - GlobalPosition center = corners[0]+corners[1]; - center *= 0.5; - return possiblyInstationaryAnalyticalSolution(center,t)[Indices::velocity(dirIdx)]; - } - } - - template <class LambdaA> - Scalar analyticalXVelocityBetweenCorners_ (const LambdaA& possiblyInstationaryAnalyticalSolution, const std::array<GlobalPosition, 2>& corners, Scalar time) const - { - return possiblyInstationaryPossiblyMeanAnalyticalVelocityySolutionAtPos_(possiblyInstationaryAnalyticalSolution, corners, 0, time); - } - - template <class LambdaA> - Scalar analyticalYVelocityBetweenCorners_ (const LambdaA& possiblyInstationaryAnalyticalSolution, const std::array<GlobalPosition, 2>& corners, Scalar time) const - { - return possiblyInstationaryPossiblyMeanAnalyticalVelocityySolutionAtPos_(possiblyInstationaryAnalyticalSolution, corners, 1, time); - } - - template <class LambdaA> - Scalar possiblyInstationaryAnalyticalPressureAtPos_ (const LambdaA& possiblyInstationaryAnalyticalSolution, const GlobalPosition& globalPos, Scalar time) const - { - if ((*problem_).useScvVolumeAveraging()) - DUNE_THROW(Dune::InvalidStateException, "Residual calc can only do no averaging for scv."); - - return possiblyInstationaryAnalyticalSolution(globalPos,time)[Indices::pressureIdx]; - } - - template <class LambdaA, class LambdaB> - Scalar momentumXResidual_(const LambdaA& possiblyInstationaryAnalyticalSolution, const LambdaB& possiblyInstationarySourceAtPos, bool isStationary, Scalar t, Scalar tOld, Scalar x, Scalar y, Scalar leftOppoDelta, Scalar rightOppoDelta, Scalar upLateralDelta, Scalar scvfDelta, Scalar downLateralDelta) const - { - // std::cout << "x= " << x << ", y = " << y << ", leftOppoDelta = " << leftOppoDelta << ", rightOppoDelta = " << rightOppoDelta << ", upLateralDelta = " << upLateralDelta << ", scvfDelta = " << scvfDelta << ", downLateralDelta = " << downLateralDelta << std::endl; - std::array<GlobalPosition, 2> selfCorners, parallelUpCorners, parallelDownCorners, oppoRightCorners, oppoLeftCorners, normalUpRightCorners, normalUpLeftCorners, normalDownRightCorners, normalDownLeftCorners; - - selfCorners[0] = {x,y-0.5*scvfDelta}; - selfCorners[1] = {x,y+0.5*scvfDelta}; - - parallelUpCorners [0] = {x, y+.5*scvfDelta}; - parallelUpCorners [1] = {x, y+.5*scvfDelta+upLateralDelta}; - parallelDownCorners [0] = {x, y-.5*scvfDelta-downLateralDelta}; - parallelDownCorners [1] = {x, y-.5*scvfDelta}; - oppoRightCorners [0] = {x+rightOppoDelta, y-0.5*scvfDelta}; - oppoRightCorners [1] = {x+rightOppoDelta, y+0.5*scvfDelta}; - oppoLeftCorners [0] = {x-leftOppoDelta, y-0.5*scvfDelta}; - oppoLeftCorners [1] = {x-leftOppoDelta, y+0.5*scvfDelta}; - - normalUpRightCorners[0] = {x, y+.5*scvfDelta}; - normalUpRightCorners[1] = {x+rightOppoDelta, y+.5*scvfDelta}; - normalUpLeftCorners[0] = {x-leftOppoDelta, y+.5*scvfDelta}; - normalUpLeftCorners[1] = {x, y+.5*scvfDelta}; - normalDownRightCorners[0] = {x, y-.5*scvfDelta}; - normalDownRightCorners[1] = {x+rightOppoDelta, y-.5*scvfDelta}; - normalDownLeftCorners [0] = {x-leftOppoDelta, y-.5*scvfDelta}; - normalDownLeftCorners [1] = {x, y-.5*scvfDelta}; - - Scalar deltaT = t-tOld; - Scalar q = possiblyInstationarySourceAtPos({x,y},t)[Indices::momentumXBalanceIdx]; - - Scalar velSelfOld = isStationary? 0. : analyticalXVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, selfCorners, tOld); - Scalar velSelf = analyticalXVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, selfCorners, t); - - Scalar velParallelRightOrUp = analyticalXVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, parallelUpCorners, t); - Scalar velParallelLeftOrDown = analyticalXVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, parallelDownCorners, t); - Scalar velOppoRightOrUp = analyticalXVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, oppoRightCorners, t); - Scalar velOppoLeftOrDown = analyticalXVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, oppoLeftCorners, t); - - Scalar velNormalUpRightOrRightUp = analyticalYVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, normalUpRightCorners, t); - Scalar velNormalUpLeftOrRightDown = analyticalYVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, normalUpLeftCorners, t); - Scalar velNormalDownRightOrLeftUp = analyticalYVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, normalDownRightCorners, t); - Scalar velNormalDownLeftOrLeftDown = analyticalYVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, normalDownLeftCorners, t); - - Scalar presLeftOrDown = possiblyInstationaryAnalyticalPressureAtPos_(possiblyInstationaryAnalyticalSolution, {x-0.5*leftOppoDelta,y},t); - Scalar presRightOrUp = possiblyInstationaryAnalyticalPressureAtPos_(possiblyInstationaryAnalyticalSolution, {x+0.5*rightOppoDelta,y},t); - - bool navierStokes = getParam<bool>("Problem.EnableInertiaTerms"); - Scalar viscosity = getParam<Scalar>("Component.LiquidKinematicViscosity"); - - return residual_(isStationary, - velSelfOld, - deltaT, - leftOppoDelta, - rightOppoDelta, - upLateralDelta, - scvfDelta, - downLateralDelta, - q, - velSelf, - velParallelRightOrUp, - velParallelLeftOrDown, - velOppoRightOrUp, - velOppoLeftOrDown, - velNormalUpRightOrRightUp, - velNormalUpLeftOrRightDown, - velNormalDownRightOrLeftUp, - velNormalDownLeftOrLeftDown, - presLeftOrDown, - presRightOrUp, - navierStokes, - viscosity); - } - - template <class LambdaA, class LambdaB> - Scalar momentumYResidual_(const LambdaA& possiblyInstationaryAnalyticalSolution, const LambdaB& possiblyInstationarySourceAtPos, bool isStationary, Scalar t, Scalar tOld, Scalar x, Scalar y, Scalar downOppoDelta, Scalar upOppoDelta, Scalar rightLateralDelta, Scalar scvfDelta, Scalar leftLateralDelta) const - { - std::array<GlobalPosition, 2> selfCorners, parallelRightCorners, parallelLeftCorners, oppoUpCorners, oppoDownCorners, normalRightUpCorners, normalRightDownCorners, normalLeftUpCorners, normalLeftDownCorners; - - selfCorners[0] = {x-0.5*scvfDelta,y}; - selfCorners[1] = {x+0.5*scvfDelta,y}; - - parallelRightCorners[0] = {x+.5*scvfDelta, y}; - parallelRightCorners[1] = {x+.5*scvfDelta+rightLateralDelta, y}; - parallelLeftCorners [0] = {x-.5*scvfDelta-leftLateralDelta, y}; - parallelLeftCorners [1] = {x-.5*scvfDelta, y}; - oppoUpCorners [0] = {x-0.5*scvfDelta, y+upOppoDelta}; - oppoUpCorners [1] = {x+0.5*scvfDelta, y+upOppoDelta}; - oppoDownCorners [0] = {x-0.5*scvfDelta, y-downOppoDelta}; - oppoDownCorners [1] = {x+0.5*scvfDelta, y-downOppoDelta}; - - normalRightUpCorners [0] = {x+.5*scvfDelta, y}; - normalRightUpCorners [1] = {x+.5*scvfDelta, y+upOppoDelta}; - normalRightDownCorners[0] = {x+.5*scvfDelta, y-downOppoDelta}; - normalRightDownCorners[1] = {x+.5*scvfDelta, y}; - normalLeftUpCorners [0] = {x-.5*scvfDelta, y}; - normalLeftUpCorners [1] = {x-.5*scvfDelta, y+upOppoDelta}; - normalLeftDownCorners [0] = {x-.5*scvfDelta, y-downOppoDelta}; - normalLeftDownCorners [1] = {x-.5*scvfDelta, y}; - - Scalar deltaT = t-tOld; - Scalar q = possiblyInstationarySourceAtPos({x,y},t)[Indices::momentumYBalanceIdx]; - - Scalar velSelfOld = isStationary? 0. : analyticalYVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, selfCorners, tOld); - Scalar velSelf = analyticalYVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, selfCorners, t); - - Scalar velParallelRightOrUp = analyticalYVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, parallelRightCorners, t); - Scalar velParallelLeftOrDown = analyticalYVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, parallelLeftCorners, t); - Scalar velOppoRightOrUp = analyticalYVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, oppoUpCorners, t); - Scalar velOppoLeftOrDown = analyticalYVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, oppoDownCorners, t); - - Scalar velNormalUpRightOrRightUp = analyticalXVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, normalRightUpCorners, t); - Scalar velNormalUpLeftOrRightDown = analyticalXVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, normalRightDownCorners, t); - Scalar velNormalDownRightOrLeftUp = analyticalXVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, normalLeftUpCorners, t); - Scalar velNormalDownLeftOrLeftDown = analyticalXVelocityBetweenCorners_ (possiblyInstationaryAnalyticalSolution, normalLeftDownCorners, t); - - Scalar presLeftOrDown = possiblyInstationaryAnalyticalPressureAtPos_(possiblyInstationaryAnalyticalSolution, {x,y-.5*downOppoDelta}, t); - Scalar presRightOrUp = possiblyInstationaryAnalyticalPressureAtPos_(possiblyInstationaryAnalyticalSolution, {x,y+.5*upOppoDelta}, t); - - bool navierStokes = getParam<bool>("Problem.EnableInertiaTerms"); - Scalar viscosity = getParam<Scalar>("Component.LiquidKinematicViscosity"); - - return residual_(isStationary, - velSelfOld, - deltaT, - downOppoDelta, - upOppoDelta, - rightLateralDelta, - scvfDelta, - leftLateralDelta, - q, - velSelf, - velParallelRightOrUp, - velParallelLeftOrDown, - velOppoRightOrUp, - velOppoLeftOrDown, - velNormalUpRightOrRightUp, - velNormalUpLeftOrRightDown, - velNormalDownRightOrLeftUp, - velNormalDownLeftOrLeftDown, - presLeftOrDown, - presRightOrUp, - navierStokes, - viscosity); - } - - // output the residuals that we would get for perfect interpolation. - template<class LambdaA, class LambdaB, class CVLeafGridView> - void fillResidual_(const LambdaA& possiblyInstationaryAnalyticalSolution, - const LambdaB& possiblyInstationarySourceAtPos, - bool isStationary, - Scalar t, - Scalar tOld, - std::vector<Scalar>& outputResMom, - const CVLeafGridView& cvLeafGridView, - const std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>>& cvCenterScvfIndicesMap, - unsigned int dirIdx, - bool vanDerPlas ) const - { - outputResMom.resize(cvLeafGridView.size(0)); - - for (const auto& controlVolume : elements(cvLeafGridView)) - { - std::vector<unsigned int> scvfIndices;//size 1 value at boundary, 2 usually, 3 for vanDerPlas transition face - auto it = cvCenterScvfIndicesMap.find(controlVolume.geometry().center()); - - bool transitionCV = false; - SubControlVolumeFace scvf; - SubControlVolumeFace otherFace; - - if (it == cvCenterScvfIndicesMap.end()) - { - std::cout << "looking for " << controlVolume.geometry().center() << std::endl; - - for ( const auto& entry : cvCenterScvfIndicesMap ) - { - std::cout << "map entry cv center = " << entry.first; - for ( const auto& val : entry.second) - std::cout << " " << val; - std::cout << std::endl; - } - - DUNE_THROW(Dune::InvalidStateException, ""); - } - else - { - scvfIndices = (*it).second; - - if (scvfIndices.size() == 1 /*boundary*/ || scvfIndices.size() == 2 /*inner,non-transition face*/) - { - scvf = (*problem_).gridGeometry().scvf(scvfIndices[0]); - } - else if (vanDerPlas && scvfIndices.size() == 4)/*transition face*/ - { - transitionCV = true; - - const auto& scvf0 = (*problem_).gridGeometry().scvf(scvfIndices[0]); - const auto& scvf1 = (*problem_).gridGeometry().scvf(scvfIndices[1]); - const auto& scvf2 = (*problem_).gridGeometry().scvf(scvfIndices[2]); - - scvf = scvf0; - - if (!containerCmp(scvf1.center(), scvf0.center())) - otherFace = scvf1; - else - otherFace = scvf2; - } - else - { - for (const auto& scvfIndex : scvfIndices) - { - const auto& scvf = (*problem_).gridGeometry().scvf(scvfIndex); - std::cout << "scvf at " << scvf.center() << std::endl; - } - - DUNE_THROW(Dune::InvalidStateException, "size = " << scvfIndices.size() << " at " << controlVolume.geometry().center()); - } - } - - if (dirIdx != scvf.directionIndex()) - DUNE_THROW(Dune::InvalidStateException, "dirIdx = " << dirIdx << ", scvf.directionIndex() = " << scvf.directionIndex() << ", scvf center = " << scvf.center()); - - int nondirIdx = (dirIdx == 0)?1:0; - - unsigned int index = cvLeafGridView.indexSet().index(controlVolume); - - Scalar dirCenter = scvf.center()[dirIdx]; - Scalar nonDirCenter = transitionCV?(.5*(scvf.center()[nondirIdx]+otherFace.center()[nondirIdx])):scvf.center()[nondirIdx]; - - Scalar x = (dirIdx == 0)?dirCenter:nonDirCenter; - Scalar y = (dirIdx == 1)?dirCenter:nonDirCenter; - - std::vector<Scalar> dirValues; - std::vector<Scalar> nonDirValues; - - for (unsigned int i=0; i < controlVolume.geometry().corners(); ++i) - { - const auto& corner = controlVolume.geometry().corner(i); - - dirValues.push_back(corner[dirIdx]); - nonDirValues.push_back(corner[nondirIdx]); - } - - std::sort(dirValues.begin(),dirValues.end()); - std::sort(nonDirValues.begin(),nonDirValues.end()); - - Scalar lowerDirValue = dirValues[0]; - Scalar higherDirValue = dirValues[3]; - - Scalar oppoDeltaLower = 2*(dirCenter-lowerDirValue); - Scalar oppoDeltaHigher = 2*(higherDirValue - dirCenter); - - int upOrRightSubFaceIdx; - int downOrLeftSubFaceIdx; - - const auto& normalFluxCorrectionFace = (*problem_).gridGeometry().scvf(scvf.insideScvIdx(), scvf.pairData(0).localNormalFluxCorrectionIndex); - if (normalFluxCorrectionFace.unitOuterNormal()[1]==1) - { - upOrRightSubFaceIdx = 0; - downOrLeftSubFaceIdx = 1; - } - else - { - upOrRightSubFaceIdx = 1; - downOrLeftSubFaceIdx = 0; - } - - Scalar higherLateralDelta; - if (!transitionCV || (scvf.center()[nondirIdx]>otherFace.center()[nondirIdx])) - { - higherLateralDelta = scvf.pairData(upOrRightSubFaceIdx).parallelDistances[1]; - } - else - { - higherLateralDelta = otherFace.pairData(upOrRightSubFaceIdx).parallelDistances[1]; - } - - Scalar lowerLateralDelta; - if (!transitionCV || (scvf.center()[nondirIdx]<otherFace.center()[nondirIdx])) - { - lowerLateralDelta = scvf.pairData(downOrLeftSubFaceIdx).parallelDistances[1]; - } - else - { - lowerLateralDelta = otherFace.pairData(downOrLeftSubFaceIdx).parallelDistances[1]; - } - - Scalar midLateralDelta = transitionCV?2.*scvf.area():scvf.area(); - - if (scvf.boundary()) - { - using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; - - auto bcTypes = (*problem_).boundaryTypesAtPos(scvf.center()); - if (!bcTypes.isDirichlet(Indices::velocity(scvf.directionIndex()))) - DUNE_THROW(Dune::InvalidStateException, "Do not use the residual calculation with outflow BCs. Not prepared so far."); - - outputResMom[index] = 0.; - continue; - } - - outputResMom[index] = - (dirIdx==0)? momentumXResidual_(possiblyInstationaryAnalyticalSolution, possiblyInstationarySourceAtPos, isStationary, t, tOld, x, y, oppoDeltaLower, oppoDeltaHigher, higherLateralDelta, midLateralDelta, lowerLateralDelta) - :momentumYResidual_(possiblyInstationaryAnalyticalSolution, possiblyInstationarySourceAtPos, isStationary, t, tOld, x, y, oppoDeltaLower, oppoDeltaHigher, higherLateralDelta, midLateralDelta, lowerLateralDelta); - - } - } - - /* - void printResidualsOfGeometry_ (Scalar coarseDeltaX, Scalar coarseDeltaY, Scalar centralX, Scalar centralY) const - { - ////// - std::cout << "coarse: " << std::endl; - //x - // ------------------------------------- - // | | | | - // | | | | - // | + + | - // | | | | - // | | | | - // ------+lllllllllll+rrrrrrrrrrr+------ - // | l | * | r | - // | l | * | r | - // + o + o + o + - // | l | * | r | - // | l | * | r | - // ------+lllllllllll+rrrrrrrrrrr+------ - // | | | | - // | | | | - // | + + | - // | | | | - // | | | | - // ------------------------------------- - // l: control volume named left - // r: control volume named right - // *: overlap of mid/right control volume boundary - // +: relevant velocity dof positions - // o: relevant pressure dof positions - Scalar right = momentumXResidual_(centralX+.5*coarseDeltaX, centralY, coarseDeltaX, coarseDeltaX, coarseDeltaY, coarseDeltaY, coarseDeltaY); - Scalar left = momentumXResidual_(centralX-.5*coarseDeltaX, centralY, coarseDeltaX, coarseDeltaX, coarseDeltaY, coarseDeltaY, coarseDeltaY); - std::cout << "momentum x: right " << right << ", left " << left << std::endl; - - //y - Scalar up = momentumYResidual_(centralX, centralY+.5*coarseDeltaY, coarseDeltaY, coarseDeltaY, coarseDeltaX, coarseDeltaX, coarseDeltaX); - Scalar down = momentumYResidual_(centralX, centralY-.5*coarseDeltaY, coarseDeltaY, coarseDeltaY, coarseDeltaX, coarseDeltaX, coarseDeltaX); - std::cout << "momentum y: up " << up << ", down " << down << std::endl; - - ///// - std::cout << "perfect interpolation " << std::endl; - //x - // ------------------------------------- - // | | | | - // | | | | - // | | | | - // | | | | - // | | | | - // | + + + | - // | | | | - // ------+lulululu+mumum+rurururu+------ - // | l | * | * | r | - // + o + o + o + o + - // | u | * | * | u | - // | +********+*****+********+ | - // | l | * | * | r | - // + o + o + o + o + - // | d | * | * | d | - // ------+ldldldld+mdmdm+rdrdrdrd+------ - // | | | | - // | + + + | - // | | | | - // | | | | - // | | | | - // | | | | - // | | | | - // ------------------------------------- - // lu: control volume named left up - // ru: control volume named right up - // ld: control volume named left down - // rd: control volume named right down - // ... - // *: overlap of mid/left or mid/right control volume boundary - // +: relevant velocity dof positions - // o: relevant pressure dof positions - Scalar rightUp = momentumXResidual_( centralX+.5*coarseDeltaX, centralY+0.25*coarseDeltaY, .5*coarseDeltaX, coarseDeltaX, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaY); - Scalar rightDown = momentumXResidual_(centralX+.5*coarseDeltaX, centralY-0.25*coarseDeltaY, .5*coarseDeltaX, coarseDeltaX, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaY); - Scalar leftUp = momentumXResidual_( centralX-.5*coarseDeltaX, centralY+0.25*coarseDeltaY, coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaY); - Scalar leftDown = momentumXResidual_( centralX-.5*coarseDeltaX, centralY-0.25*coarseDeltaY, coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaY); - Scalar midUp = momentumXResidual_( centralX, centralY+0.25*coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaY); - Scalar midDown = momentumXResidual_( centralX, centralY-0.25*coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaY); - - std::cout << "momentum x: right up " << rightUp << ", right down = " << rightDown << ", left up " << leftUp << ", left down = " << leftDown << ", mid up " << midUp << ", mid down = " << midDown << std::endl; - //y-component of the momentum balance - Scalar upRight = momentumYResidual_( centralX+.25*coarseDeltaX, centralY+.5*coarseDeltaY, .5*coarseDeltaY, coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX); - Scalar upLeft = momentumYResidual_( centralX-.25*coarseDeltaX, centralY+.5*coarseDeltaY, .5*coarseDeltaY, coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX); - Scalar midRight = momentumYResidual_( centralX+.25*coarseDeltaX, centralY, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX); - Scalar midLeft = momentumYResidual_( centralX-.25*coarseDeltaX, centralY, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX); - Scalar downRight = momentumYResidual_(centralX+.25*coarseDeltaX, centralY-.5*coarseDeltaY, coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX); - Scalar downLeft = momentumYResidual_( centralX-.25*coarseDeltaX, centralY-.5*coarseDeltaY, coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX); - - std::cout << "momentum y: up right " << upRight << ", up left = " << upLeft << ", mid right " << midRight << ", mid left " << midLeft << ", downRight " << downRight << ", downLeft " << downLeft << std::endl; - - ///// - std::cout << "grading in x momentumXResiduals: "; - //x - // ------------------------------------- - // | | | | | - // | | | | | - // | + + + | - // | | | | | - // | | | | | - // ------+llllllll+mmmmm+rrrrrrrr+------ - // | l | * | * | r | - // | l | * | * | r | - // + o + o + o + o + - // | l | * | * | r | - // | l | * | * | r | - // ------+llllllll+mmmmm+rrrrrrrr+------ - // | | | | | - // | | | | | - // | + + + | - // | | | | | - // | | | | | - // ------------------------------------- - // l: control volume named left grading - // r: control volume named right grading - // m: control volume named mid grading - // *: overlap of mid/left or mid/right control volume boundary - // +: relevant velocity dof positions - // o: relevant pressure dof positions - Scalar rightGrading = momentumXResidual_(centralX+.5*coarseDeltaX, centralY, .5*coarseDeltaX, coarseDeltaX, coarseDeltaY, coarseDeltaY, coarseDeltaY); - Scalar leftGrading = momentumXResidual_(centralX-.5*coarseDeltaX, centralY, coarseDeltaX, .5*coarseDeltaX, coarseDeltaY, coarseDeltaY, coarseDeltaY); - Scalar midGrading = momentumXResidual_(centralX, centralY, .5*coarseDeltaX, .5*coarseDeltaX, coarseDeltaY, coarseDeltaY, coarseDeltaY); - - std::cout << "momentum x: right " << rightGrading << ", left " << leftGrading << ", mid " << midGrading << std::endl; - - //y - // ------------------------------------- - // | | | | | - // | | | | | - // | +luolu+ruoru+ | - // | l * r | - // | u * u | - // ------------l-----*-----r------------ - // | u * u | - // | l * r | - // + +*****+*****+ + - // | l * r | - // | d * d | - // ------------l-----*-----r------------ - // | d * d | - // | l * r | - // | +ldold+rdord+ | - // | | | | | - // | | | | | - // ------------------------------------- - // lu: control volume named left up grading - // ru: control volume named right up grading - // ld: control volume named left down grading - // rd: control volume named right down grading - // *: overlap of mid/left or mid/right control volume boundary - // +: relevant velocity dof positions - // o: relevant pressure dof positions - Scalar rightUpGrading = momentumYResidual_(centralX+.25*coarseDeltaX, centralY+.5*coarseDeltaY, coarseDeltaY, coarseDeltaY, coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX); - Scalar leftUpGrading = momentumYResidual_(centralX-.25*coarseDeltaX, centralY+.5*coarseDeltaY, coarseDeltaY, coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, coarseDeltaX); - Scalar rightDownGrading = momentumYResidual_(centralX+.25*coarseDeltaX, centralY-.5*coarseDeltaY, coarseDeltaY, coarseDeltaY, coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX); - Scalar leftDownGrading = momentumYResidual_(centralX-.25*coarseDeltaX, centralY-.5*coarseDeltaY, coarseDeltaY, coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, coarseDeltaX); - - std::cout << "momentum y: right up " << rightUpGrading << ", left up " << leftUpGrading << ", right down " << rightDownGrading << ", left down " << leftDownGrading << std::endl; - - ///// - std::cout << "grading in neighbor in y momentumXResiduals: "; - //x - Scalar rightNeighborGrading = momentumXResidual_(centralX+.5*coarseDeltaX, centralY, coarseDeltaX, coarseDeltaX, 2.*coarseDeltaY, coarseDeltaY, coarseDeltaY); - Scalar leftNeighborGrading = momentumXResidual_(centralX-.5*coarseDeltaX, centralY, coarseDeltaX, coarseDeltaX, 2.*coarseDeltaY, coarseDeltaY, coarseDeltaY); - - std::cout << "momentum y: rightNeighborGrading " << rightNeighborGrading << ", leftNeighborGrading " << leftNeighborGrading << std::endl; - ///// - std::cout << "perfect interpolation, everything central and symmetric:"; - //x - Scalar rightUpPerfectIterpSymm = momentumXResidual_( centralX + 5./8*coarseDeltaX, centralY+0.25*coarseDeltaY, 0.75*coarseDeltaX, 0.75*coarseDeltaX, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaY); - Scalar rightDownPerfectIterpSymm = momentumXResidual_( centralX + 5./8*coarseDeltaX, centralY-0.25*coarseDeltaY, 0.75*coarseDeltaX, 0.75*coarseDeltaX, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaY); - Scalar leftUpPerfectIterpSymm = momentumXResidual_( centralX - 5./8*coarseDeltaX, centralY+0.25*coarseDeltaY, 0.75*coarseDeltaX, 0.75*coarseDeltaX, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaY); - Scalar leftDownPerfectIterpSymm = momentumXResidual_( centralX - 5./8*coarseDeltaX, centralY-0.25*coarseDeltaY, 0.75*coarseDeltaX, 0.75*coarseDeltaX, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaY); - Scalar midUpPerfectIterpSymm = momentumXResidual_( centralX, centralY+0.25*coarseDeltaY, 0.5*coarseDeltaX, 0.5*coarseDeltaX, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaY); - Scalar midDownPerfectIterpSymm = momentumXResidual_( centralX, centralY-0.25*coarseDeltaY, 0.5*coarseDeltaX, 0.5*coarseDeltaX, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaY); - - std::cout << "momentum x: right up " << rightUpPerfectIterpSymm << ", right down = " << rightDownPerfectIterpSymm << ", left up " << leftUpPerfectIterpSymm << ", left down = " << leftDownPerfectIterpSymm << ", mid up " << midUpPerfectIterpSymm << ", mid down = " << midDownPerfectIterpSymm << std::endl; - - //y - Scalar upRightPerfectIterpSymm = momentumYResidual_( centralX+.25*coarseDeltaX, centralY+5./8*coarseDeltaY, 0.75*coarseDeltaY, 0.75*coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX); - Scalar upLeftPerfectIterpSymm = momentumYResidual_( centralX-.25*coarseDeltaX, centralY+5./8*coarseDeltaY, 0.75*coarseDeltaY, 0.75*coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX); - Scalar midRightPerfectIterpSymm = momentumYResidual_( centralX+.25*coarseDeltaX, centralY, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX); - Scalar midLeftPerfectIterpSymm = momentumYResidual_( centralX-.25*coarseDeltaX, centralY, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX); - Scalar downRightPerfectIterpSymm = momentumYResidual_(centralX+.25*coarseDeltaX, centralY-5./8*coarseDeltaY, 0.75*coarseDeltaY, 0.75*coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX); - Scalar downLeftPerfectIterpSymm = momentumYResidual_( centralX-.25*coarseDeltaX, centralY-5./8*coarseDeltaY, 0.75*coarseDeltaY, 0.75*coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX); - - std::cout << "momentum y: up right " << upRightPerfectIterpSymm << ", up left = " << upLeftPerfectIterpSymm << ", mid right " << midRightPerfectIterpSymm << ", mid left " << midLeftPerfectIterpSymm << ", downRight " << downRightPerfectIterpSymm << ", downLeft " << downLeftPerfectIterpSymm << std::endl; - - return; - }*/ - std::shared_ptr<const Problem> problem_; }; } // end namespace Dumux diff --git a/dumux/io/cvdoutputFacility.hh b/dumux/io/cvdoutputFacility.hh index b4cdf4c..360b0e0 100644 --- a/dumux/io/cvdoutputFacility.hh +++ b/dumux/io/cvdoutputFacility.hh @@ -66,49 +66,46 @@ public: : problem_(problem) {} - void iniCVGridManagers(std::array<HostGridManager, 4>& gridManagers, - std::array<std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>>,4>& cvCenterScvfIndicesMaps, - const std::array<std::string, 4>& paramGroups) const + void iniCVGridManagers(std::array<HostGridManager, 2>& gridManagers, + std::array<std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>>, 2>& cvCenterScvfIndicesMaps, + const std::array<std::string, 2>& paramGroups) const { // generate dgf files, initialize grid managers - cvCenterScvfIndicesMaps[0] = generateCVsDGFfile<GridGeometry, GlobalPosition>(paramGroups[0], (*problem_).gridGeometry(), 0, false); - cvCenterScvfIndicesMaps[1] = generateCVsDGFfile<GridGeometry, GlobalPosition>(paramGroups[1], (*problem_).gridGeometry(), 1, false); - cvCenterScvfIndicesMaps[2] = generateCVsDGFfile<GridGeometry, GlobalPosition>(paramGroups[2], (*problem_).gridGeometry(), 0, true); - cvCenterScvfIndicesMaps[3] = generateCVsDGFfile<GridGeometry, GlobalPosition>(paramGroups[3], (*problem_).gridGeometry(), 1, true); + cvCenterScvfIndicesMaps[0] = generateCVsDGFfile<GridGeometry, GlobalPosition>(paramGroups[0], (*problem_).gridGeometry(), 0); + cvCenterScvfIndicesMaps[1] = generateCVsDGFfile<GridGeometry, GlobalPosition>(paramGroups[1], (*problem_).gridGeometry(), 1); std::string testString = getParam<std::string>("finexCVs.Grid.File", ""); if (testString == "") DUNE_THROW(Dune::InvalidStateException, "Please set finexCVs.Grid.File."); - for (unsigned int i = 0; i < 4; ++i) + for (unsigned int i = 0; i < 2; ++i) gridManagers[i].init(paramGroups[i]); } void onCVsOutputResidualsAndPrimVars(std::shared_ptr<const GridGeometry> gridGeometry, - std::array<HostGridManager, 4>& cvGridManagers, - const std::array<std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>>,4>& cvCenterScvfIndicesMaps, - const std::array<std::string, 4>& paramGroups, + std::array<HostGridManager, 2>& cvGridManagers, + const std::array<std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>>, 2>& cvCenterScvfIndicesMaps, + const std::array<std::string, 2>& paramGroups, const SolutionVector& sol, unsigned int timeIndex, const FaceSolutionVector& faceResidualWithAnalyticalSol, - const std::optional<std::array<std::vector<Scalar>, 4>>& perfectInterpolationFaceResiduals, + const std::optional<std::array<std::vector<Scalar>, 2>>& perfectInterpolationFaceResiduals, bool readDofBasedValues) const { - std::array<std::vector<std::vector<Scalar>>,4> dualIndexedOutputVecsArray = {}; - std::vector<std::string> fineOutputVecNames; + std::array<std::vector<std::vector<Scalar>>, 2> dualIndexedOutputVecsArray = {}; std::vector<std::string> coarseOutputVecNames; // { - std::vector<FaceSolutionVector> finePrimalIndexOutputVecs; + std::vector<FaceSolutionVector> primalIndexOutputVecs; const FaceSolutionVector& vel = sol[GridGeometry::faceIdx()]; - finePrimalIndexOutputVecs.push_back(vel); - fineOutputVecNames.push_back("velocity"); + primalIndexOutputVecs.push_back(vel); + coarseOutputVecNames.push_back("velocity"); const FaceSolutionVector& anaVel = problem_->getAnalyticalFaceSolutionVector(); - finePrimalIndexOutputVecs.push_back(anaVel); - fineOutputVecNames.push_back("analyticalVelocity"); + primalIndexOutputVecs.push_back(anaVel); + coarseOutputVecNames.push_back("analyticalVelocity"); FaceSolutionVector absVelocityError; absVelocityError.resize((*problem_).gridGeometry().numIntersections()); @@ -116,8 +113,8 @@ public: { absVelocityError[i] = std::abs(vel[i] - anaVel[i]); } - finePrimalIndexOutputVecs.push_back(absVelocityError); - fineOutputVecNames.push_back("absVelocityError"); + primalIndexOutputVecs.push_back(absVelocityError); + coarseOutputVecNames.push_back("absVelocityError"); if (readDofBasedValues) { @@ -126,40 +123,34 @@ public: ReadDofBasedResult<TypeTag> reader(problem_); reader.readDofBasedResult(IBAMRvel, "velocity"); - finePrimalIndexOutputVecs.push_back(IBAMRvel); - fineOutputVecNames.push_back("IBAMRvel"); + primalIndexOutputVecs.push_back(IBAMRvel); + coarseOutputVecNames.push_back("IBAMRvel"); } - finePrimalIndexOutputVecs.push_back(faceResidualWithAnalyticalSol); - fineOutputVecNames.push_back("numericalMomResAnalytical"); + primalIndexOutputVecs.push_back(faceResidualWithAnalyticalSol); + coarseOutputVecNames.push_back("numericalMomResAnalytical"); - std::array<std::vector<std::vector<Scalar>>,2> fineDualIndexOutputVec = onePrimalIndexedVectorToTwoDualIndexedVectors_(finePrimalIndexOutputVecs, cvGridManagers, cvCenterScvfIndicesMaps); + std::array<std::vector<std::vector<Scalar>>,2> dualIndexOutputVec = onePrimalIndexedVectorToTwoDualIndexedVectors_(primalIndexOutputVecs, cvGridManagers, cvCenterScvfIndicesMaps); for (unsigned int i = 0; i < 2; ++i) - for (unsigned int j = 0; j < fineDualIndexOutputVec[i].size(); ++j) - dualIndexedOutputVecsArray[i].push_back(fineDualIndexOutputVec[i][j]); + for (unsigned int j = 0; j < dualIndexOutputVec[i].size(); ++j) + dualIndexedOutputVecsArray[i].push_back(dualIndexOutputVec[i][j]); } if (perfectInterpolationFaceResiduals) { - for (unsigned int i = 0; i < 4; ++i) + for (unsigned int i = 0; i < 2; ++i) dualIndexedOutputVecsArray[i].push_back((*perfectInterpolationFaceResiduals)[i]); - fineOutputVecNames.push_back("perfectInterpMomResWithAnalytical"); coarseOutputVecNames.push_back("perfectInterpMomResWithAnalytical"); } - std::array<std::vector<std::string>, 4> outputVecNames; - for (unsigned int i = 0; i < fineOutputVecNames.size(); ++i) - { - outputVecNames[0].push_back(fineOutputVecNames[i]+"_x"); - outputVecNames[1].push_back(fineOutputVecNames[i]+"_y"); - } + std::array<std::vector<std::string>, 2> outputVecNames; for (unsigned int i = 0; i < coarseOutputVecNames.size(); ++i) { - outputVecNames[2].push_back(coarseOutputVecNames[i]+"_x"); - outputVecNames[3].push_back(coarseOutputVecNames[i]+"_y"); + outputVecNames[0].push_back(coarseOutputVecNames[i]+"_x"); + outputVecNames[1].push_back(coarseOutputVecNames[i]+"_y"); } - for (unsigned int i = 0; i < 4; ++i) + for (unsigned int i = 0; i < 2; ++i) { using CVsGridView = std::decay_t<decltype(cvGridManagers[i].grid().leafGridView())>; Dune::VTKWriter<CVsGridView> writer (cvGridManagers[i].grid().leafGridView()); @@ -171,10 +162,10 @@ public: } } - void printPvdFiles(const std::array<std::string, 4>& paramGroups, + void printPvdFiles(const std::array<std::string, 2>& paramGroups, const std::vector<std::pair<unsigned int, Scalar>> pvdFileInfos) { - for (unsigned int i = 0; i < 4; ++i) + for (unsigned int i = 0; i < 2; ++i) { std::string name = paramGroups[i]; @@ -221,36 +212,36 @@ private: template<class OutputVecs> std::vector<std::vector<Scalar>> onePrimalIndexedVectorToOneDualIndexedVectorInOneDirection_(unsigned int dirIdx, - OutputVecs& finePrimalIndexOutputVecs, - std::array<HostGridManager, 4>& gridManagers, - const std::array<std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>>,4>& cvCenterScvfIndicesMaps) const + OutputVecs& primalIndexOutputVecs, + std::array<HostGridManager, 2>& gridManagers, + const std::array<std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>>, 2>& cvCenterScvfIndicesMaps) const { const HostGrid::LeafGridView& cVsLeafGridView = (gridManagers[dirIdx]).grid().leafGridView(); - std::vector<std::vector<Scalar>> modifiedfinePrimalIndexOutputVecs; + std::vector<std::vector<Scalar>> modifiedprimalIndexOutputVecs; std::vector<Scalar> dummyVec; dummyVec.resize(cVsLeafGridView.size(0)); - for (unsigned int i = 0; i < finePrimalIndexOutputVecs.size(); ++i) - modifiedfinePrimalIndexOutputVecs.push_back(dummyVec); + for (unsigned int i = 0; i < primalIndexOutputVecs.size(); ++i) + modifiedprimalIndexOutputVecs.push_back(dummyVec); for (const auto& cv : elements(cVsLeafGridView)) { - for (unsigned int i = 0; i < finePrimalIndexOutputVecs.size(); ++i) - modifiedfinePrimalIndexOutputVecs[i][cvIndexFromCv_(cv, cVsLeafGridView)] = finePrimalIndexOutputVecs[i][scvfDofIndexFromCv_(cv, cvCenterScvfIndicesMaps[dirIdx])]; + for (unsigned int i = 0; i < primalIndexOutputVecs.size(); ++i) + modifiedprimalIndexOutputVecs[i][cvIndexFromCv_(cv, cVsLeafGridView)] = primalIndexOutputVecs[i][scvfDofIndexFromCv_(cv, cvCenterScvfIndicesMaps[dirIdx])]; } - return modifiedfinePrimalIndexOutputVecs; + return modifiedprimalIndexOutputVecs; } template<class OutputVecs> - std::array<std::vector<std::vector<Scalar>>,2> onePrimalIndexedVectorToTwoDualIndexedVectors_(OutputVecs& finePrimalIndexOutputVecs, - std::array<HostGridManager, 4>& gridManagers, - const std::array<std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>>,4>& cvCenterScvfIndicesMaps) const + std::array<std::vector<std::vector<Scalar>>,2> onePrimalIndexedVectorToTwoDualIndexedVectors_(OutputVecs& primalIndexOutputVecs, + std::array<HostGridManager, 2>& gridManagers, + const std::array<std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>>, 2>& cvCenterScvfIndicesMaps) const { - std::vector<std::vector<Scalar>> modifiedfinePrimalIndexOutputVecsX = onePrimalIndexedVectorToOneDualIndexedVectorInOneDirection_(0, finePrimalIndexOutputVecs, gridManagers, cvCenterScvfIndicesMaps); - std::vector<std::vector<Scalar>> modifiedfinePrimalIndexOutputVecsY = onePrimalIndexedVectorToOneDualIndexedVectorInOneDirection_(1, finePrimalIndexOutputVecs, gridManagers, cvCenterScvfIndicesMaps); + std::vector<std::vector<Scalar>> modifiedprimalIndexOutputVecsX = onePrimalIndexedVectorToOneDualIndexedVectorInOneDirection_(0, primalIndexOutputVecs, gridManagers, cvCenterScvfIndicesMaps); + std::vector<std::vector<Scalar>> modifiedprimalIndexOutputVecsY = onePrimalIndexedVectorToOneDualIndexedVectorInOneDirection_(1, primalIndexOutputVecs, gridManagers, cvCenterScvfIndicesMaps); - std::array<std::vector<std::vector<Scalar>>,2> retArray = {modifiedfinePrimalIndexOutputVecsX, modifiedfinePrimalIndexOutputVecsY}; + std::array<std::vector<std::vector<Scalar>>,2> retArray = {modifiedprimalIndexOutputVecsX, modifiedprimalIndexOutputVecsY}; return retArray; } diff --git a/dumux/io/grid/cvdcontrolvolumegrids.hh b/dumux/io/grid/cvdcontrolvolumegrids.hh index 9e2d3e0..e7294ad 100644 --- a/dumux/io/grid/cvdcontrolvolumegrids.hh +++ b/dumux/io/grid/cvdcontrolvolumegrids.hh @@ -46,61 +46,43 @@ template<class SubControlVolumeFace, class GridGeometry> void fillNonDirCoord_(const SubControlVolumeFace& scvf, const GridGeometry& gridGeometry, double& nonDirCoord0, - double& nonDirCoord1, - bool hangingNodesAreCVCenters) + double& nonDirCoord1) { - if (hangingNodesAreCVCenters && !scvf.boundary() && (scvf.inside().level() != scvf.outside().level())) + SubControlVolumeFace scvfOrCoarseSideScvf; + + if (!scvf.boundary() && (scvf.inside().level() > scvf.outside().level())) { - SubControlVolumeFace coarseSideScvf; + auto outsideFvGeometry = localView(gridGeometry); + outsideFvGeometry.bindElement(scvf.outside()); - if (!scvf.boundary() && (scvf.inside().level() < scvf.outside().level())) - { - coarseSideScvf = scvf; - } - else if (!scvf.boundary() && (scvf.inside().level() > scvf.outside().level())) + for (auto&& myscvf : scvfs(outsideFvGeometry)) { - auto outsideFvGeometry = localView(gridGeometry); - outsideFvGeometry.bindElement(scvf.outside()); - - for (auto&& myscvf : scvfs(outsideFvGeometry)) - { - auto minusNormal = scvf.unitOuterNormal(); - minusNormal *= -1.; + auto minusNormal = scvf.unitOuterNormal(); + minusNormal *= -1.; - if (containerCmp(myscvf.unitOuterNormal(),minusNormal)) - { - if (containerCmp(myscvf.center(),scvf.center())) - { - coarseSideScvf = myscvf; - } - } - } + if (containerCmp(myscvf.unitOuterNormal(),minusNormal)) + scvfOrCoarseSideScvf = myscvf; } - - unsigned int nonDirIdx = (scvf.directionIndex() == 0) ? 1 : 0; - const SubControlVolumeFace& normalFace0 = gridGeometry.scvf(coarseSideScvf.insideScvIdx(), coarseSideScvf.localNormalFaceBuildingIdx(0)); - nonDirCoord0 = normalFace0.center()[nonDirIdx]; - - const SubControlVolumeFace& normalFace1 = gridGeometry.scvf(coarseSideScvf.insideScvIdx(), coarseSideScvf.localNormalFaceBuildingIdx(1)); - nonDirCoord1 = normalFace1.center()[nonDirIdx]; } else { - unsigned int dirIdx = scvf.directionIndex(); - unsigned int nonDirIdx = (dirIdx == 0) ? 1 : 0; - - nonDirCoord0 = scvf.corner(0)[nonDirIdx]; - nonDirCoord1 = scvf.corner(1)[nonDirIdx]; + scvfOrCoarseSideScvf = scvf; } + + unsigned int dirIdx = scvf.directionIndex(); + unsigned int nonDirIdx = (dirIdx == 0) ? 1 : 0; + + nonDirCoord0 = scvfOrCoarseSideScvf.corner(0)[nonDirIdx]; + nonDirCoord1 = scvfOrCoarseSideScvf.corner(1)[nonDirIdx]; } template<class GlobalPosition, class SubControlVolumeFace, class GridGeometry> -std::array<GlobalPosition,4> localCVVertices(const SubControlVolumeFace& scvf, const GridGeometry& gridGeometry, bool hangingNodesAreCVCenters) +std::array<GlobalPosition,4> localCVVertices(const SubControlVolumeFace& scvf, const GridGeometry& gridGeometry) { double nonDirCoord0; double nonDirCoord1; - fillNonDirCoord_(scvf, gridGeometry, nonDirCoord0, nonDirCoord1, hangingNodesAreCVCenters); + fillNonDirCoord_(scvf, gridGeometry, nonDirCoord0, nonDirCoord1); unsigned int dirIdx = scvf.directionIndex(); unsigned int nonDirIdx = (dirIdx == 0) ? 1 : 0; @@ -147,7 +129,7 @@ std::array<GlobalPosition,4> localCVVertices(const SubControlVolumeFace& scvf, c template<class GlobalPosition, class SubControlVolumeFace> -GlobalPosition localCVCenter(const SubControlVolumeFace& scvf, bool hangingNodesAreCVCenters) +GlobalPosition localCVCenter(const SubControlVolumeFace& scvf) { unsigned int dirIdx = scvf.directionIndex(); unsigned int nonDirIdx = (dirIdx == 0) ? 1 : 0; @@ -157,7 +139,7 @@ GlobalPosition localCVCenter(const SubControlVolumeFace& scvf, bool hangingNodes double outsideCoord = scvf.boundary()?scvf.center()[dirIdx]:scvf.outside().geometry().center()[dirIdx]; center[dirIdx] = (insideCoord + outsideCoord)*0.5; - if (hangingNodesAreCVCenters && !scvf.boundary() && (scvf.inside().level() != scvf.outside().level())) + if (!scvf.boundary() && (scvf.inside().level() != scvf.outside().level())) { if (scvf.inside().level() < scvf.outside().level()) center[nonDirIdx] = scvf.inside().geometry().center()[nonDirIdx]; @@ -171,8 +153,7 @@ GlobalPosition localCVCenter(const SubControlVolumeFace& scvf, bool hangingNodes } template<class GridGeometry, class GlobalPosition> -auto fillCVsGridInfo(bool hangingNodesAreCVCenters, - const GridGeometry& gridGeometry, +auto fillCVsGridInfo(const GridGeometry& gridGeometry, int dirIdx, std::map<int, GlobalPosition>& vertices, std::vector<std::array<int,4>>& cubes, @@ -191,7 +172,7 @@ auto fillCVsGridInfo(bool hangingNodesAreCVCenters, for (auto&& scvf : scvfs(fvGeometry)) { - GlobalPosition cvCenter = localCVCenter<GlobalPosition>(scvf,hangingNodesAreCVCenters); + GlobalPosition cvCenter = localCVCenter<GlobalPosition>(scvf); if ( std::find(visitedScvfDofs.begin(), visitedScvfDofs.end(), scvf.dofIndex()) != visitedScvfDofs.end()) { @@ -202,62 +183,11 @@ auto fillCVsGridInfo(bool hangingNodesAreCVCenters, continue; } - bool transitionFace = hangingNodesAreCVCenters && !scvf.boundary() && (scvf.inside().level() != scvf.outside().level()); - - if (transitionFace) - { - //fill visited dof - using SubControlVolumeFace = std::decay_t<decltype(scvf)>; - SubControlVolumeFace otherFace; - //fill other face - if (!scvf.boundary() && (scvf.inside().level() < scvf.outside().level())) - { - for (auto&& myscvf : scvfs(fvGeometry)) - { - if (containerCmp(myscvf.unitOuterNormal(),scvf.unitOuterNormal()) && !containerCmp(myscvf.center(),scvf.center())) - { - otherFace = myscvf; - } - } - } - else if (!scvf.boundary() && (scvf.inside().level() > scvf.outside().level())) - { - auto outsideFvGeometry = localView(gridGeometry); - outsideFvGeometry.bindElement(scvf.outside()); - - for (auto&& myscvf : scvfs(outsideFvGeometry)) - { - auto minusNormal = scvf.unitOuterNormal(); - minusNormal *= -1.; - - if (containerCmp(myscvf.unitOuterNormal(),minusNormal)) - { - if (!containerCmp(myscvf.center(),scvf.center())) - { - otherFace = myscvf; - } - } - } - } - - //fill visitedDof - if (std::find(visitedScvfDofs.begin(), visitedScvfDofs.end(), otherFace.dofIndex()) != visitedScvfDofs.end()) - { - visitedScvfDofs.push_back(scvf.dofIndex()); - - auto it = cvCenterScvfIndicesMap.find(cvCenter); - if (it != cvCenterScvfIndicesMap.end()) - (*it).second.push_back(scvf.index()); - - continue; - } - } - visitedScvfDofs.push_back(scvf.dofIndex()); if (scvf.directionIndex() == dirIdx) { - std::array<GlobalPosition,4> localVertices = localCVVertices<GlobalPosition>(scvf, gridGeometry, hangingNodesAreCVCenters); + std::array<GlobalPosition,4> localVertices = localCVVertices<GlobalPosition>(scvf, gridGeometry); std::vector<unsigned int> scvfIndices; scvfIndices.push_back(scvf.index()); @@ -374,13 +304,13 @@ void printCVsGridInfo(const std::string& name, } template<class GridGeometry, class GlobalPosition> -auto generateCVsDGFfile(const std::string& paramGroup, const GridGeometry& gridGeometry, int dirIdx, bool hangingNodesAreCVCenters) +auto generateCVsDGFfile(const std::string& paramGroup, const GridGeometry& gridGeometry, int dirIdx) { std::map<int, GlobalPosition> vertices; std::vector<std::array<int,4>> cubes; std::vector<std::array<int,2>> boundarySegments; - std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>> cvCenterScvfIndicesMap = fillCVsGridInfo<GridGeometry, GlobalPosition>(hangingNodesAreCVCenters, gridGeometry,dirIdx, vertices, cubes, boundarySegments); + std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>> cvCenterScvfIndicesMap = fillCVsGridInfo<GridGeometry, GlobalPosition>(gridGeometry,dirIdx, vertices, cubes, boundarySegments); printCVsGridInfo<GlobalPosition>(paramGroup, vertices, cubes, boundarySegments); return cvCenterScvfIndicesMap; -- GitLab From 66e10bd4e67ebee95f96dab1c45b4bf16c17bbe9 Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Tue, 14 Sep 2021 09:44:33 +0300 Subject: [PATCH 25/69] Deleted files with _old suffix --- .../staggered/cvdresidualCalcOld.hh | 854 ------------------ dumux/io/grid/cvdcontrolvolumegrids_old.hh | 428 --------- 2 files changed, 1282 deletions(-) delete mode 100644 dumux/freeflow/navierstokes/staggered/cvdresidualCalcOld.hh delete mode 100644 dumux/io/grid/cvdcontrolvolumegrids_old.hh diff --git a/dumux/freeflow/navierstokes/staggered/cvdresidualCalcOld.hh b/dumux/freeflow/navierstokes/staggered/cvdresidualCalcOld.hh deleted file mode 100644 index 7072b38..0000000 --- a/dumux/freeflow/navierstokes/staggered/cvdresidualCalcOld.hh +++ /dev/null @@ -1,854 +0,0 @@ -#include <dune/grid/io/file/vtk/vtkwriter.hh> -#include <dumux/io/grid/cvdcontrolvolumegrids.hh> -#include <dumux/discretization/staggered/freeflow/geometryhelper/cvdstaggeredgeometryhelper.hh> - -namespace Dumux{ - namespace Properties { - template<class TypeTag, class MyTypeTag> - struct CVGridGeometry { using type = UndefinedProperty; }; - } -} - - -double residual (bool isStationary, double velSelfOld, double deltaT, double leftOrDownOppoDelta, double rightOrUpOppoDelta, double rightOrUpLateralDelta, double scvfDelta, double leftOrDownLateralDelta, double q, double velSelf, double velParallelRightOrUp, double velParallelLeftOrDown, double velOppoRightOrUp, double velOppoLeftOrDown, double velNormalUpRightOrRightUp, double velNormalUpLeftOrRightDown, double velNormalDownRightOrLeftUp, double velNormalDownLeftOrLeftDown, double presLeftOrDown, double presRightOrUp, bool navierStokes, double viscosity) -{ - double opposDelta = .5 * (leftOrDownOppoDelta + rightOrUpOppoDelta); - double density = 1.; //can only deal with constant viscosity here - - double res = -q*opposDelta * scvfDelta - + ( 2*opposDelta/(rightOrUpLateralDelta+scvfDelta) + 2*opposDelta/(leftOrDownLateralDelta+scvfDelta) + 2*scvfDelta/leftOrDownOppoDelta + 2*scvfDelta/rightOrUpOppoDelta ) * viscosity * velSelf - + ( -2*opposDelta/(rightOrUpLateralDelta+scvfDelta)) * viscosity * velParallelRightOrUp - + ( -2*opposDelta/(leftOrDownLateralDelta+scvfDelta) ) * viscosity * velParallelLeftOrDown - + ( -2*scvfDelta/leftOrDownOppoDelta ) * viscosity * velOppoLeftOrDown - + ( -2*scvfDelta/rightOrUpOppoDelta ) * viscosity * velOppoRightOrUp - - velNormalUpRightOrRightUp * viscosity - + velNormalUpLeftOrRightDown * viscosity - + velNormalDownRightOrLeftUp * viscosity - - velNormalDownLeftOrLeftDown * viscosity - - scvfDelta* presLeftOrDown - + scvfDelta * presRightOrUp; - -// std::cout << "source " << -q*opposDelta * scvfDelta; -// std::cout << ", self " << ( 2*opposDelta/(rightOrUpLateralDelta+scvfDelta) + 2*opposDelta/(leftOrDownLateralDelta+scvfDelta) + 2*scvfDelta/leftOrDownOppoDelta + 2*scvfDelta/rightOrUpOppoDelta ) * viscosity * velSelf; -// std::cout << ", parallel a " << ( -2*opposDelta/(rightOrUpLateralDelta+scvfDelta)) * viscosity * velParallelRightOrUp; -// std::cout << ", prallel b " << ( -2*opposDelta/(leftOrDownLateralDelta+scvfDelta) ) * viscosity * velParallelLeftOrDown; -// std::cout << ", oppo a " << ( -2*scvfDelta/leftOrDownOppoDelta ) * viscosity * velOppoLeftOrDown; -// std::cout << ", oppo b " << ( -2*scvfDelta/rightOrUpOppoDelta ) * viscosity * velOppoRightOrUp; -// std::cout << ", normal a " << - velNormalUpRightOrRightUp * viscosity; -// std::cout << ", normal b " << velNormalUpLeftOrRightDown * viscosity; -// std::cout << ", normal c " << velNormalDownRightOrLeftUp * viscosity; -// std::cout << ", normal d " << - velNormalDownLeftOrLeftDown * viscosity; -// std::cout << ", pressure a " << - scvfDelta* presLeftOrDown; -// std::cout << ", pressure b " << scvfDelta * presRightOrUp; -// std::cout << std::endl; - -// std::cout << "res = " << res << std::endl; -// -// std::cout << "opposDelta * scvfDelta = " << opposDelta * scvfDelta << std::endl; -// -// std::cout << "d_y u term: " << -// ((2/(rightOrUpLateralDelta+scvfDelta) + 2/(leftOrDownLateralDelta+scvfDelta))/(scvfDelta)* velSelf -// + ( -2/(rightOrUpLateralDelta+scvfDelta))/(scvfDelta) * velParallelRightOrUp -// + ( -2/(leftOrDownLateralDelta+scvfDelta))/(scvfDelta) * velParallelLeftOrDown) << std::endl; - -// double selfCoefficient = ((leftOrDownLateralDelta+scvfDelta)/(2.*scvfDelta)+(rightOrUpLateralDelta+scvfDelta)/(2.*scvfDelta))/(((rightOrUpLateralDelta+scvfDelta)/2.)*((leftOrDownLateralDelta+scvfDelta)/2.))*scvfDelta*scvfDelta; -// double upCoefficient = (leftOrDownLateralDelta+scvfDelta)/(2.*scvfDelta)/(((rightOrUpLateralDelta+scvfDelta)/2.)*((leftOrDownLateralDelta+scvfDelta)/2.))*scvfDelta*scvfDelta; -// double downCoefficient = (rightOrUpLateralDelta+scvfDelta)/(2.*scvfDelta)/(((rightOrUpLateralDelta+scvfDelta)/2.)*((leftOrDownLateralDelta+scvfDelta)/2.))*scvfDelta*scvfDelta; - -// std::cout << "selfCoefficient " << selfCoefficient << ", upCoefficient = " << upCoefficient << ", downCoefficient = " << downCoefficient << std::endl; - -// std::cout << "var d_y u term: " << -// (selfCoefficient*velSelf -// -upCoefficient*velParallelRightOrUp -// -downCoefficient*velParallelLeftOrDown) -// /(scvfDelta*scvfDelta) -// << std::endl; -// -// std::cout << "pressure term: " << (- scvfDelta* presLeftOrDown + scvfDelta * presRightOrUp)/(opposDelta * scvfDelta) << std::endl; - - if (navierStokes) - { - auto mixedVelocity = [&](double upwindVelocity, double downwindVelocity) - { - double upwindWeight = Dumux::getParam<double>("Flux.UpwindWeight", 1.); - return upwindWeight * upwindVelocity + (1. - upwindWeight) * downwindVelocity; - }; - - //x:left, y: down - double transportingVelocity = (velSelf + velOppoLeftOrDown) * 0.5; - double upwindVelocity = (Dumux::sign(transportingVelocity) == +1) ? velOppoLeftOrDown : velSelf; - double downwindVelocity = (Dumux::sign(transportingVelocity) == +1) ? velSelf : velOppoLeftOrDown; - - res -= scvfDelta * density * transportingVelocity * mixedVelocity(upwindVelocity,downwindVelocity); - - //x:right, y: up - transportingVelocity = (velSelf + velOppoRightOrUp) * 0.5; - upwindVelocity = (Dumux::sign(transportingVelocity) == +1) ? velSelf : velOppoRightOrUp; - downwindVelocity = (Dumux::sign(transportingVelocity) == +1) ? velOppoRightOrUp : velSelf; - - res += scvfDelta * density * transportingVelocity * mixedVelocity(upwindVelocity,downwindVelocity); - - //x:upright, y: rightup - if (rightOrUpLateralDelta == 0.) - { - upwindVelocity = velParallelRightOrUp; - downwindVelocity = velParallelRightOrUp; - } - else - { - upwindVelocity = (Dumux::sign(velNormalUpRightOrRightUp)==+1) ? velSelf : velParallelRightOrUp; - downwindVelocity = (Dumux::sign(velNormalUpRightOrRightUp)==+1) ? velParallelRightOrUp : velSelf; - } - - res += .25 * (leftOrDownOppoDelta+rightOrUpOppoDelta) * density * mixedVelocity(upwindVelocity,downwindVelocity) * velNormalUpRightOrRightUp; - - //x: downright, y: leftup - if (leftOrDownLateralDelta == 0.) - { - upwindVelocity = velParallelLeftOrDown; - downwindVelocity = velParallelLeftOrDown; - } - else - { - upwindVelocity = (Dumux::sign(velNormalDownRightOrLeftUp)==+1) ? velParallelLeftOrDown : velSelf; - downwindVelocity = (Dumux::sign(velNormalDownRightOrLeftUp)==+1) ? velSelf : velParallelLeftOrDown; - } - - res -= .25 * (leftOrDownOppoDelta+rightOrUpOppoDelta) * density * mixedVelocity(upwindVelocity,downwindVelocity) * velNormalDownRightOrLeftUp; - - //x:upleft, y: rightdown - if (rightOrUpLateralDelta == 0.) - { - downwindVelocity = velParallelRightOrUp; - upwindVelocity = velParallelRightOrUp; - } - else - { - downwindVelocity = (Dumux::sign(velNormalUpLeftOrRightDown)==+1) ? velParallelRightOrUp : velSelf; - upwindVelocity = (Dumux::sign(velNormalUpLeftOrRightDown)==+1) ? velSelf : velParallelRightOrUp; - } - - res += .25 * (leftOrDownOppoDelta+rightOrUpOppoDelta)* density * mixedVelocity(upwindVelocity,downwindVelocity) * velNormalUpLeftOrRightDown; - - //x:downleft, y: leftdown - if (leftOrDownLateralDelta == 0.) - { - upwindVelocity = velParallelLeftOrDown; - downwindVelocity = velParallelLeftOrDown; - } - else - { - upwindVelocity = (Dumux::sign(velNormalDownLeftOrLeftDown)==+1) ? velParallelLeftOrDown : velSelf; - downwindVelocity = (Dumux::sign(velNormalDownLeftOrLeftDown)==+1) ? velSelf : velParallelLeftOrDown; - } - - res -= .25 * (leftOrDownOppoDelta+rightOrUpOppoDelta) * density * mixedVelocity(upwindVelocity,downwindVelocity) * velNormalDownLeftOrLeftDown; - } - - if (!isStationary) - { - res += (velSelf - velSelfOld) / deltaT * opposDelta * scvfDelta; - } - -// std::cout << "final res = " << res/(opposDelta * scvfDelta) << std::endl; - - return res/(opposDelta * scvfDelta); //that should be the one relevant for grid convergence -} - -template <class TypeTag, class Problem> -double momentumXResidual (bool isStationary, double t, double tOld, double x, double y, double leftOppoDelta, double rightOppoDelta, double upLateralDelta, double scvfDelta, double downLateralDelta, const Problem& problem) -{ -// std::cout << "x= " << x << ", y = " << y << ", leftOppoDelta = " << leftOppoDelta << ", rightOppoDelta = " << rightOppoDelta << ", upLateralDelta = " << upLateralDelta << ", scvfDelta = " << scvfDelta << ", downLateralDelta = " << downLateralDelta << std::endl; - - using namespace Dumux; - using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; - using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; - using Element = typename GridGeometry::GridView::template Codim<0>::Entity; - using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - - auto myAnalyticalSolution = [&] (const GlobalPosition& globalPos) - { - if (isStationary) - { - return problem.analyticalSolutionAtPos(globalPos); - } - else - return problem.instationaryAnalyticalSolutionAtPos(globalPos,t); - }; - - double velSelfOld = isStationary? 0. : problem.instationaryAnalyticalSolutionAtPos({x,y},tOld)[Indices::velocityXIdx]; - double deltaT = t-tOld; - double q = isStationary ? problem.sourceAtPos({x,y})[Indices::momentumXBalanceIdx] : - problem.instationarySourceAtPos({x,y},t)[Indices::momentumXBalanceIdx]; - double velSelf = myAnalyticalSolution({x,y})[Indices::velocityXIdx]; - double velParallelRightOrUp =myAnalyticalSolution({x,y+0.5*scvfDelta+0.5*upLateralDelta})[Indices::velocityXIdx]; - double velParallelLeftOrDown =myAnalyticalSolution({x,y-0.5*scvfDelta-0.5*downLateralDelta})[Indices::velocityXIdx]; - double velOppoRightOrUp = myAnalyticalSolution({x+rightOppoDelta,y})[Indices::velocityXIdx]; - double velOppoLeftOrDown = myAnalyticalSolution({x-leftOppoDelta,y})[Indices::velocityXIdx]; - double velNormalUpRightOrRightUp = myAnalyticalSolution({x+0.5*rightOppoDelta,y+0.5*scvfDelta})[Indices::velocityYIdx]; - double velNormalUpLeftOrRightDown = myAnalyticalSolution({x-0.5*leftOppoDelta,y+0.5*scvfDelta})[Indices::velocityYIdx]; - double velNormalDownRightOrLeftUp = myAnalyticalSolution({x+0.5*rightOppoDelta,y-0.5*scvfDelta})[Indices::velocityYIdx]; - double velNormalDownLeftOrLeftDown = myAnalyticalSolution({x-0.5*leftOppoDelta,y-0.5*scvfDelta})[Indices::velocityYIdx]; - double presLeftOrDown = myAnalyticalSolution({x-0.5*leftOppoDelta,y})[Indices::pressureIdx]; - double presRightOrUp = myAnalyticalSolution({x+0.5*rightOppoDelta,y})[Indices::pressureIdx]; - bool navierStokes = getParam<bool>("Problem.EnableInertiaTerms"); - double viscosity = getParam<double>("Component.LiquidKinematicViscosity"); - - return residual(isStationary, - velSelfOld, - deltaT, - leftOppoDelta, - rightOppoDelta, - upLateralDelta, - scvfDelta, - downLateralDelta, - q, - velSelf, - velParallelRightOrUp, - velParallelLeftOrDown, - velOppoRightOrUp, - velOppoLeftOrDown, - velNormalUpRightOrRightUp, - velNormalUpLeftOrRightDown, - velNormalDownRightOrLeftUp, - velNormalDownLeftOrLeftDown, - presLeftOrDown, - presRightOrUp, - navierStokes, - viscosity); -} - -template <class TypeTag, class Problem> -double momentumYResidual (bool isStationary, double t, double tOld, double x, double y, double downOppoDelta, double upOppoDelta, double rightLateralDelta, double scvfDelta, double leftLateralDelta, const Problem& problem) -{ - using namespace Dumux; - using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; - using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; - using Element = typename GridGeometry::GridView::template Codim<0>::Entity; - using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - - auto myAnalyticalSolution = [&] (const GlobalPosition& globalPos) - { - if (isStationary) - { - return problem.analyticalSolutionAtPos(globalPos); - } - else - return problem.instationaryAnalyticalSolutionAtPos(globalPos,t); - }; - - double velSelfOld = isStationary? 0. : problem.instationaryAnalyticalSolutionAtPos({x,y},tOld)[Indices::velocityYIdx]; - double deltaT = t-tOld; - double q = isStationary ? problem.sourceAtPos({x,y})[Indices::momentumYBalanceIdx] - : problem.instationarySourceAtPos({x,y},t)[Indices::momentumYBalanceIdx]; - double velSelf = myAnalyticalSolution({x,y})[Indices::velocityYIdx]; - double velParallelRightOrUp =myAnalyticalSolution({x+.5*scvfDelta+.5*rightLateralDelta,y})[Indices::velocityYIdx]; - double velParallelLeftOrDown =myAnalyticalSolution({x-.5*scvfDelta-.5*leftLateralDelta,y})[Indices::velocityYIdx]; - double velOppoRightOrUp = myAnalyticalSolution({x, y+upOppoDelta})[Indices::velocityYIdx]; - double velOppoLeftOrDown = myAnalyticalSolution({x, y-downOppoDelta})[Indices::velocityYIdx]; - double velNormalUpRightOrRightUp = myAnalyticalSolution({x+.5*scvfDelta, y+.5*upOppoDelta})[Indices::velocityXIdx]; - double velNormalUpLeftOrRightDown = myAnalyticalSolution({x+.5*scvfDelta, y-.5*downOppoDelta})[Indices::velocityXIdx]; - double velNormalDownRightOrLeftUp = myAnalyticalSolution({x-.5*scvfDelta, y+.5*upOppoDelta})[Indices::velocityXIdx]; - double velNormalDownLeftOrLeftDown = myAnalyticalSolution({x-.5*scvfDelta, y-.5*downOppoDelta})[Indices::velocityXIdx]; - double presLeftOrDown = myAnalyticalSolution({x,y-.5*downOppoDelta})[Indices::pressureIdx]; - double presRightOrUp = myAnalyticalSolution({x,y+.5*upOppoDelta})[Indices::pressureIdx]; - bool navierStokes = getParam<bool>("Problem.EnableInertiaTerms"); - double viscosity = getParam<double>("Component.LiquidKinematicViscosity"); - - return residual(isStationary, - velSelfOld, - deltaT, - downOppoDelta, - upOppoDelta, - rightLateralDelta, - scvfDelta, - leftLateralDelta, - q, - velSelf, - velParallelRightOrUp, - velParallelLeftOrDown, - velOppoRightOrUp, - velOppoLeftOrDown, - velNormalUpRightOrRightUp, - velNormalUpLeftOrRightDown, - velNormalDownRightOrLeftUp, - velNormalDownLeftOrLeftDown, - presLeftOrDown, - presRightOrUp, - navierStokes, - viscosity); -} - -// output the residuals that we would get for perfect interpolation. -template<class TypeTag, class SubControlVolumeFace, class CVGridGeometry, class GridGeometry, class Problem> -void fillResidual(bool isStationary, double t, double tOld, std::vector<double>& outputResMom, const SubControlVolumeFace& scvf, const CVGridGeometry& cvGridGeometry, const GridGeometry& gridGeometry, const Problem& problem, bool vanDerPlas ) -{ - using namespace Dumux; - - SubControlVolumeFace otherFace; - SubControlVolumeFace coarseSideScvf; - bool transitionFace = false; - if (vanDerPlas) - { - if (!scvf.boundary() && (scvf.inside().level() < scvf.outside().level())) - { - transitionFace = true; - coarseSideScvf = scvf; - - auto fvGeometry = localView(gridGeometry); - fvGeometry.bindElement(scvf.inside()); - for (auto&& myscvf : scvfs(fvGeometry)) - { - if (containerCmp(myscvf.centerUnitOuterNormal(),scvf.centerUnitOuterNormal()) && !containerCmp(myscvf.center(),scvf.center())) - { - otherFace = myscvf; - } - } - } - else if (!scvf.boundary() && (scvf.inside().level() > scvf.outside().level())) - { - transitionFace = true; - auto outsideFvGeometry = localView(gridGeometry); - outsideFvGeometry.bindElement(scvf.outside()); - - for (auto&& myscvf : scvfs(outsideFvGeometry)) - { - auto minusNormal = scvf.centerUnitOuterNormal(); - minusNormal *= -1.; - - if (containerCmp(myscvf.centerUnitOuterNormal(),minusNormal)) - { - if (containerCmp(myscvf.center(),scvf.center())) - { - coarseSideScvf = myscvf; - } - else - { - otherFace = myscvf; - } - } - } - } - } - - int dirIdx = scvf.directionIndex(); - int nondirIdx = (dirIdx == 0)?1:0; - - const auto& cvLeafGridView = (*cvGridGeometry).gridView(); - - using Element = Dune::Entity<0, 2, const Dune::ALU3dGrid<2, 2, (Dune::ALU3dGridElementType)7, Dune::ALUGridMPIComm>, Dune::ALU3dGridEntity>; - Element controlVolume; - bool controlVolumeIsSet = false; - - for (const auto& cv : elements(cvLeafGridView)) - { - std::vector<double> xValues; - std::vector<double> yValues; - - for (unsigned int i=0; i < cv.geometry().corners(); ++i) - { - const auto& corner = cv.geometry().corner(i); - - xValues.push_back(corner[0]); - yValues.push_back(corner[1]); - } - - std::sort(xValues.begin(),xValues.end()); - std::sort(yValues.begin(),yValues.end()); - - double left = xValues[0]; - double right = xValues[3]; - double down = yValues[0]; - double up = yValues[3]; - - //in the following the scalarCmp is to take care of boundary scvfs - if ((left < scvf.center()[0] || scalarCmp(left, scvf.center()[0])) && - (scvf.center()[0] < right || scalarCmp(right, scvf.center()[0])) && - (down < scvf.center()[1] || scalarCmp(down, scvf.center()[1])) && - (scvf.center()[1] < up || scalarCmp(up, scvf.center()[1]))) - { - controlVolume = cv; - controlVolumeIsSet = true; - } - } - - if (!controlVolumeIsSet) - DUNE_THROW(Dune::InvalidStateException, "Control volume was not set."); - - unsigned int index = cvLeafGridView.indexSet().index(controlVolume); - - double dirCenter = scvf.center()[dirIdx]; - double nonDirCenter = transitionFace?(.5*(scvf.center()[nondirIdx]+otherFace.center()[nondirIdx])):scvf.center()[nondirIdx]; - - double x = (dirIdx == 0)?dirCenter:nonDirCenter; - double y = (dirIdx == 1)?dirCenter:nonDirCenter; - - std::vector<double> dirValues; - std::vector<double> nonDirValues; - - for (unsigned int i=0; i < controlVolume.geometry().corners(); ++i) - { - const auto& corner = controlVolume.geometry().corner(i); - - dirValues.push_back(corner[dirIdx]); - nonDirValues.push_back(corner[nondirIdx]); - } - - std::sort(dirValues.begin(),dirValues.end()); - std::sort(nonDirValues.begin(),nonDirValues.end()); - - double lowerDirValue = dirValues[0]; - double higherDirValue = dirValues[3]; - - double oppoDeltaLower = 2*(dirCenter-lowerDirValue); - double oppoDeltaHigher = 2*(higherDirValue - dirCenter); - - int upOrRightSubFaceIdx; - int downOrLeftSubFaceIdx; - - const auto& normalFluxCorrectionFace = gridGeometry.scvf(scvf.insideScvIdx(), scvf.pairData(0).localNormalFluxCorrectionIndex); - if (normalFluxCorrectionFace.unitOuterNormal()[1]==1) - { - upOrRightSubFaceIdx = 0; - downOrLeftSubFaceIdx = 1; - } - else - { - upOrRightSubFaceIdx = 1; - downOrLeftSubFaceIdx = 0; - } - - double higherLateralDelta; - // if (!transitionFace || (scvf.center()[nondirIdx]>otherFace.center()[nondirIdx])) - // { - higherLateralDelta = scvf.pairData(upOrRightSubFaceIdx).parallelDistances[1]; - // } - // else - // { - // higherLateralDelta = otherFace.pairData(upOrRightSubFaceIdx).parallelDistances[1]; - // } - - double lowerLateralDelta; - // if (!transitionFace || (scvf.center()[nondirIdx]<otherFace.center()[nondirIdx])) - // { - lowerLateralDelta = scvf.pairData(downOrLeftSubFaceIdx).parallelDistances[1]; - // } - // else - // { - // lowerLateralDelta = otherFace.pairData(downOrLeftSubFaceIdx).parallelDistances[1]; - // } - - double midLateralDelta = transitionFace?2.*scvf.area():scvf.area(); - - if (scvf.boundary()) - { - using namespace Dumux; - using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; - - auto bcTypes = problem.boundaryTypesAtPos(scvf.center()); - if (!bcTypes.isDirichlet(Indices::velocity(scvf.directionIndex()))) - DUNE_THROW(Dune::InvalidStateException, "Do not use the residual calculation with outflow BCs. Not prepared so far."); - - outputResMom[index] = 0.; - return; - } - - outputResMom[index] = - (dirIdx==0)? momentumXResidual<TypeTag, Problem>(isStationary, t, tOld, x, y, oppoDeltaLower, oppoDeltaHigher, higherLateralDelta, midLateralDelta, lowerLateralDelta, problem) - :momentumYResidual<TypeTag, Problem>(isStationary, t, tOld, x, y, oppoDeltaLower, oppoDeltaHigher, higherLateralDelta, midLateralDelta, lowerLateralDelta, problem); -} - -//general version -template<class TypeTag, class GridGeometry, class FaceRes, class Problem, class OutputVecs> -void outputCVResidualsInstationary(bool isStationary, double t, double tOld, const GridGeometry& gridGeometry, const FaceRes& areaWeightedFaceResidual, const Problem& problem, const OutputVecs& outputVecs, const std::vector<std::string>& outputVecNames) -{ - using namespace Dumux; - - std::string testString = getParam<std::string>("finexCVs.Grid.File", ""); - if (testString == "") - DUNE_THROW(Dune::InvalidStateException, "Please set finexCVs.Grid.File."); - - using GridView = typename GridGeometry::GridView; - using Element = typename GridView::template Codim<0>::Entity; - using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - - using HostGrid = Dune::ALUGrid<2,2,Dune::cube,Dune::nonconforming >; - using HostGridManager = GridManager<HostGrid>; - using Scalar = GetPropType<TypeTag, Properties::Scalar>; - using CVGridGeometry = GetPropType<TypeTag, Properties::CVGridGeometry>; - using SubControlVolumeFace = typename GetPropType<TypeTag, Properties::GridGeometry>::SubControlVolumeFace; - - Dune::BlockVector<Dune::FieldVector<double, 1>, std::allocator<Dune::FieldVector<double, 1> > > resVel; - resVel = areaWeightedFaceResidual; - - auto cvAreas = resVel; - cvAreas = 0.; - - for (const auto& element : elements(gridGeometry.gridView())) - { - auto fvGeometry = localView(gridGeometry); - fvGeometry.bindElement(element); - for (const auto& scvf : scvfs(fvGeometry)) - { - cvAreas[scvf.dofIndex()] += (scvf.area() * 0.5 * scvf.selfToOppositeDistance()); - } - } - - for (int i = 0; i < resVel.size(); ++i) - { - resVel[i] /= cvAreas[i]; - } - - // create control volume grids and vtk output (fine version) - std::string xFineParamGroup = "finexCVs"; - std::string yFineParamGroup = "fineyCVs"; - - generateCVsDGFfile<GridGeometry, GlobalPosition>(xFineParamGroup, gridGeometry,0, false); - generateCVsDGFfile<GridGeometry, GlobalPosition>(yFineParamGroup, gridGeometry,1, false); - - HostGridManager xFineCVsGridManager; - xFineCVsGridManager.init(xFineParamGroup); - const auto& xFineCVsLeafGridView = xFineCVsGridManager.grid().leafGridView(); - - HostGridManager yFineCVsGridManager; - yFineCVsGridManager.init(yFineParamGroup); - const auto& yFineCVsLeafGridView = yFineCVsGridManager.grid().leafGridView(); - - std::vector<Scalar> finePerfectInterpMomXRes; - finePerfectInterpMomXRes.resize(xFineCVsLeafGridView.size(0)); - std::vector<Scalar> fromAssemblyMomXRes; - fromAssemblyMomXRes.resize(xFineCVsLeafGridView.size(0)); - std::vector<std::vector<Scalar>> modifiedOutputVecsX; - std::vector<Scalar> dummyVecX; - dummyVecX.resize(xFineCVsLeafGridView.size(0)); - for (unsigned int i = 0; i < outputVecs.size(); ++i) - modifiedOutputVecsX.push_back(dummyVecX); - - - std::vector<Scalar> finePerfectInterpMomYRes; - finePerfectInterpMomYRes.resize(yFineCVsLeafGridView.size(0)); - std::vector<Scalar> fromAssemblyMomYRes; - fromAssemblyMomYRes.resize(yFineCVsLeafGridView.size(0)); - std::vector<std::vector<Scalar>> modifiedOutputVecsY; - std::vector<Scalar> dummyVecY; - dummyVecY.resize(yFineCVsLeafGridView.size(0)); - for (unsigned int i = 0; i < outputVecs.size(); ++i) - modifiedOutputVecsY.push_back(dummyVecY); - - auto xFineGridGeometry = std::make_shared<CVGridGeometry>(xFineCVsLeafGridView); - xFineGridGeometry->update(); - auto yFineGridGeometry = std::make_shared<CVGridGeometry>(yFineCVsLeafGridView); - yFineGridGeometry->update(); - - // create control volume grids and vtk output (coarse version) - std::string xCoarseParamGroup = "coarsexCVs"; - std::string yCoarseParamGroup = "coarseyCVs"; - - generateCVsDGFfile<GridGeometry, GlobalPosition>(xCoarseParamGroup, gridGeometry,0, true); - generateCVsDGFfile<GridGeometry, GlobalPosition>(yCoarseParamGroup, gridGeometry,1, true); - - HostGridManager xCoarseCVsGridManager; - xCoarseCVsGridManager.init(xCoarseParamGroup); - const auto& xCoarseCVsLeafGridView = xCoarseCVsGridManager.grid().leafGridView(); - - HostGridManager yCoarseCVsGridManager; - yCoarseCVsGridManager.init(yCoarseParamGroup); - const auto& yCoarseCVsLeafGridView = yCoarseCVsGridManager.grid().leafGridView(); - - std::vector<Scalar> coarsePerfectInterpMomXRes; - coarsePerfectInterpMomXRes.resize(xCoarseCVsLeafGridView.size(0)); - std::vector<Scalar> coarsePerfectInterpMomYRes; - coarsePerfectInterpMomYRes.resize(yCoarseCVsLeafGridView.size(0)); - - using CVsGridView = std::decay_t<decltype(xCoarseCVsLeafGridView)>; - Dune::VTKWriter<CVsGridView> coarseXWriter (xCoarseCVsLeafGridView); - coarseXWriter.addCellData(coarsePerfectInterpMomXRes, "coarsePerfectInterpMomXResWithAnalyticalAtPos"); - Dune::VTKWriter<CVsGridView> coarseYWriter (yCoarseCVsLeafGridView); - coarseYWriter.addCellData(coarsePerfectInterpMomYRes, "coarsePerfectInterpMomYResWithAnalyticalAtPos"); - - auto xCoarseGridGeometry = std::make_shared<CVGridGeometry>(xCoarseCVsLeafGridView); - xCoarseGridGeometry->update(); - auto yCoarseGridGeometry = std::make_shared<CVGridGeometry>(yCoarseCVsLeafGridView); - yCoarseGridGeometry->update(); - - for (const auto& element : elements(gridGeometry.gridView())) - { - auto fvGeometry = localView(gridGeometry); - fvGeometry.bindElement(element); - - for (auto&& scvf : scvfs(fvGeometry)) - { - bool isX = scvf.directionIndex() == 0; - - fillResidual<TypeTag, SubControlVolumeFace, std::shared_ptr<CVGridGeometry>, GridGeometry, Problem>(isStationary, t, tOld, isX ? finePerfectInterpMomXRes : finePerfectInterpMomYRes, scvf, isX ? xFineGridGeometry : yFineGridGeometry, gridGeometry, problem, false ); - fillResidual<TypeTag, SubControlVolumeFace, std::shared_ptr<CVGridGeometry>, GridGeometry, Problem>(isStationary, t, tOld, isX ? coarsePerfectInterpMomXRes : coarsePerfectInterpMomYRes, scvf, isX ? xCoarseGridGeometry : yCoarseGridGeometry, gridGeometry, problem, true ); - - unsigned int index = 0; - for (const auto& cv : elements(isX ? xFineCVsLeafGridView : yFineCVsLeafGridView)) - { - std::vector<double> xValues; - std::vector<double> yValues; - - for (unsigned int i=0; i < cv.geometry().corners(); ++i) - { - const auto& corner = cv.geometry().corner(i); - - xValues.push_back(corner[0]); - yValues.push_back(corner[1]); - } - - std::sort(xValues.begin(),xValues.end()); - std::sort(yValues.begin(),yValues.end()); - - double left = xValues[0]; - double right = xValues[3]; - double down = yValues[0]; - double up = yValues[3]; - - if ((left < scvf.center()[0] || scalarCmp(left, scvf.center()[0])) && - (scvf.center()[0] < right || scalarCmp(right, scvf.center()[0])) && - (down < scvf.center()[1] || scalarCmp(down, scvf.center()[1])) && - (scvf.center()[1] < up || scalarCmp(up, scvf.center()[1]))) - { - index = (isX ? xFineCVsLeafGridView : yFineCVsLeafGridView).indexSet().index(cv); - } - } - - if (isX) - { - fromAssemblyMomXRes[index] = resVel[scvf.dofIndex()]; - for (unsigned int i = 0; i < outputVecs.size(); ++i) - modifiedOutputVecsX[i][index] = outputVecs[i][scvf.dofIndex()]; - } - else if (scvf.directionIndex() == 1) - { - fromAssemblyMomYRes[index] = resVel[scvf.dofIndex()]; - for (unsigned int i = 0; i < outputVecs.size(); ++i) - modifiedOutputVecsY[i][index] = outputVecs[i][scvf.dofIndex()]; - } - else - { - DUNE_THROW(Dune::InvalidStateException, "wrong"); - } - } - } - - using CVsGridView = std::decay_t<decltype(xFineCVsLeafGridView)>; - Dune::VTKWriter<CVsGridView> fineXWriter (xFineCVsLeafGridView); - fineXWriter.addCellData(fromAssemblyMomXRes, "fromAssemblyMomXRes"); - fineXWriter.addCellData(finePerfectInterpMomXRes, "finePerfectInterpMomXResWithAnalyticalAtPos"); - for (unsigned int i = 0; i < outputVecs.size(); ++i) - fineXWriter.addCellData(modifiedOutputVecsX[i], outputVecNames[i]+"_x"); - - Dune::VTKWriter<CVsGridView> fineYWriter (yFineCVsLeafGridView); - fineYWriter.addCellData(fromAssemblyMomYRes, "fromAssemblyMomYRes"); - fineYWriter.addCellData(finePerfectInterpMomYRes, "finePerfectInterpMomYResWithAnalyticalAtPos"); - for (unsigned int i = 0; i < outputVecs.size(); ++i) - fineYWriter.addCellData(modifiedOutputVecsY[i], outputVecNames[i]+"_y"); - - fineXWriter.write("finexCVs"); - fineYWriter.write("fineyCVs"); - coarseXWriter.write("coarsexCVs"); - coarseYWriter.write("coarseyCVs"); -} - -//stationary version -template<class TypeTag, class GridGeometry, class FaceRes, class Problem, class OutputVecs> -void outputCVResiduals(const GridGeometry& gridGeometry, const FaceRes& areaWeightedFaceResidual, const Problem& problem, const OutputVecs& outputVecs, const std::vector<std::string>& outputVecNames) -{ - outputCVResidualsInstationary<TypeTag>(true, 0., 0., gridGeometry, areaWeightedFaceResidual, problem, outputVecs, outputVecNames); -} - -/* -template <class Problem> -void printResidualsOfGeometry (double coarseDeltaX, double coarseDeltaY, double centralX, double centralY, const Problem& problem) -{ -////// - std::cout << "coarse: " << std::endl; -//x -// ------------------------------------- -// | | | | -// | | | | -// | + + | -// | | | | -// | | | | -// ------+lllllllllll+rrrrrrrrrrr+------ -// | l | * | r | -// | l | * | r | -// + o + o + o + -// | l | * | r | -// | l | * | r | -// ------+lllllllllll+rrrrrrrrrrr+------ -// | | | | -// | | | | -// | + + | -// | | | | -// | | | | -// ------------------------------------- -// l: control volume named left -// r: control volume named right -// *: overlap of mid/right control volume boundary -// +: relevant velocity dof positions -// o: relevant pressure dof positions - double right = momentumXResidual<TypeTag, Problem, Problem>(centralX+.5*coarseDeltaX, centralY, coarseDeltaX, coarseDeltaX, coarseDeltaY, coarseDeltaY, coarseDeltaY, problem); - double left = momentumXResidual<TypeTag, Problem, Problem>(centralX-.5*coarseDeltaX, centralY, coarseDeltaX, coarseDeltaX, coarseDeltaY, coarseDeltaY, coarseDeltaY, problem); - std::cout << "momentum x: right " << right << ", left " << left << std::endl; - -//y - double up = momentumYResidual<TypeTag, Problem, Problem>(centralX, centralY+.5*coarseDeltaY, coarseDeltaY, coarseDeltaY, coarseDeltaX, coarseDeltaX, coarseDeltaX, problem); - double down = momentumYResidual<TypeTag, Problem, Problem>(centralX, centralY-.5*coarseDeltaY, coarseDeltaY, coarseDeltaY, coarseDeltaX, coarseDeltaX, coarseDeltaX, problem); - std::cout << "momentum y: up " << up << ", down " << down << std::endl; - -///// - std::cout << "perfect interpolation " << std::endl; -//x -// ------------------------------------- -// | | | | -// | | | | -// | | | | -// | | | | -// | | | | -// | + + + | -// | | | | -// ------+lulululu+mumum+rurururu+------ -// | l | * | * | r | -// + o + o + o + o + -// | u | * | * | u | -// | +********+*****+********+ | -// | l | * | * | r | -// + o + o + o + o + -// | d | * | * | d | -// ------+ldldldld+mdmdm+rdrdrdrd+------ -// | | | | -// | + + + | -// | | | | -// | | | | -// | | | | -// | | | | -// | | | | -// ------------------------------------- -// lu: control volume named left up -// ru: control volume named right up -// ld: control volume named left down -// rd: control volume named right down -// ... -// *: overlap of mid/left or mid/right control volume boundary -// +: relevant velocity dof positions -// o: relevant pressure dof positions - double rightUp = momentumXResidual<TypeTag, Problem, Problem>( centralX+.5*coarseDeltaX, centralY+0.25*coarseDeltaY, .5*coarseDeltaX, coarseDeltaX, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaY, problem); - double rightDown = momentumXResidual<TypeTag, Problem, Problem>(centralX+.5*coarseDeltaX, centralY-0.25*coarseDeltaY, .5*coarseDeltaX, coarseDeltaX, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaY, problem); - double leftUp = momentumXResidual<TypeTag, Problem, Problem>( centralX-.5*coarseDeltaX, centralY+0.25*coarseDeltaY, coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaY, problem); - double leftDown = momentumXResidual<TypeTag, Problem, Problem>( centralX-.5*coarseDeltaX, centralY-0.25*coarseDeltaY, coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaY, problem); - double midUp = momentumXResidual<TypeTag, Problem, Problem>( centralX, centralY+0.25*coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaY, problem); - double midDown = momentumXResidual<TypeTag, Problem, Problem>( centralX, centralY-0.25*coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaY, problem); - - std::cout << "momentum x: right up " << rightUp << ", right down = " << rightDown << ", left up " << leftUp << ", left down = " << leftDown << ", mid up " << midUp << ", mid down = " << midDown << std::endl; -//y-component of the momentum balance - double upRight = momentumYResidual<TypeTag, Problem, Problem>( centralX+.25*coarseDeltaX, centralY+.5*coarseDeltaY, .5*coarseDeltaY, coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX, problem); - double upLeft = momentumYResidual<TypeTag, Problem, Problem>( centralX-.25*coarseDeltaX, centralY+.5*coarseDeltaY, .5*coarseDeltaY, coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX, problem); - double midRight = momentumYResidual<TypeTag, Problem, Problem>( centralX+.25*coarseDeltaX, centralY, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX, problem); - double midLeft = momentumYResidual<TypeTag, Problem, Problem>( centralX-.25*coarseDeltaX, centralY, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX, problem); - double downRight = momentumYResidual<TypeTag, Problem, Problem>(centralX+.25*coarseDeltaX, centralY-.5*coarseDeltaY, coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX, problem); - double downLeft = momentumYResidual<TypeTag, Problem, Problem>( centralX-.25*coarseDeltaX, centralY-.5*coarseDeltaY, coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX, problem); - - std::cout << "momentum y: up right " << upRight << ", up left = " << upLeft << ", mid right " << midRight << ", mid left " << midLeft << ", downRight " << downRight << ", downLeft " << downLeft << std::endl; - -///// - std::cout << "grading in x momentumXResiduals: "; -//x -// ------------------------------------- -// | | | | | -// | | | | | -// | + + + | -// | | | | | -// | | | | | -// ------+llllllll+mmmmm+rrrrrrrr+------ -// | l | * | * | r | -// | l | * | * | r | -// + o + o + o + o + -// | l | * | * | r | -// | l | * | * | r | -// ------+llllllll+mmmmm+rrrrrrrr+------ -// | | | | | -// | | | | | -// | + + + | -// | | | | | -// | | | | | -// ------------------------------------- -// l: control volume named left grading -// r: control volume named right grading -// m: control volume named mid grading -// *: overlap of mid/left or mid/right control volume boundary -// +: relevant velocity dof positions -// o: relevant pressure dof positions - double rightGrading = momentumXResidual<TypeTag, Problem, Problem>(centralX+.5*coarseDeltaX, centralY, .5*coarseDeltaX, coarseDeltaX, coarseDeltaY, coarseDeltaY, coarseDeltaY, problem); - double leftGrading = momentumXResidual<TypeTag, Problem, Problem>(centralX-.5*coarseDeltaX, centralY, coarseDeltaX, .5*coarseDeltaX, coarseDeltaY, coarseDeltaY, coarseDeltaY, problem); - double midGrading = momentumXResidual<TypeTag, Problem, Problem>(centralX, centralY, .5*coarseDeltaX, .5*coarseDeltaX, coarseDeltaY, coarseDeltaY, coarseDeltaY, problem); - - std::cout << "momentum x: right " << rightGrading << ", left " << leftGrading << ", mid " << midGrading << std::endl; - -//y -// ------------------------------------- -// | | | | | -// | | | | | -// | +luolu+ruoru+ | -// | l * r | -// | u * u | -// ------------l-----*-----r------------ -// | u * u | -// | l * r | -// + +*****+*****+ + -// | l * r | -// | d * d | -// ------------l-----*-----r------------ -// | d * d | -// | l * r | -// | +ldold+rdord+ | -// | | | | | -// | | | | | -// ------------------------------------- -// lu: control volume named left up grading -// ru: control volume named right up grading -// ld: control volume named left down grading -// rd: control volume named right down grading -// *: overlap of mid/left or mid/right control volume boundary -// +: relevant velocity dof positions -// o: relevant pressure dof positions - double rightUpGrading = momentumYResidual<TypeTag, Problem, Problem>(centralX+.25*coarseDeltaX, centralY+.5*coarseDeltaY, coarseDeltaY, coarseDeltaY, coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX, problem); - double leftUpGrading = momentumYResidual<TypeTag, Problem, Problem>(centralX-.25*coarseDeltaX, centralY+.5*coarseDeltaY, coarseDeltaY, coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, coarseDeltaX, problem); - double rightDownGrading = momentumYResidual<TypeTag, Problem, Problem>(centralX+.25*coarseDeltaX, centralY-.5*coarseDeltaY, coarseDeltaY, coarseDeltaY, coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX, problem); - double leftDownGrading = momentumYResidual<TypeTag, Problem, Problem>(centralX-.25*coarseDeltaX, centralY-.5*coarseDeltaY, coarseDeltaY, coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, coarseDeltaX, problem); - - std::cout << "momentum y: right up " << rightUpGrading << ", left up " << leftUpGrading << ", right down " << rightDownGrading << ", left down " << leftDownGrading << std::endl; - -///// - std::cout << "grading in neighbor in y momentumXResiduals: "; -//x - double rightNeighborGrading = momentumXResidual<TypeTag, Problem, Problem>(centralX+.5*coarseDeltaX, centralY, coarseDeltaX, coarseDeltaX, 2.*coarseDeltaY, coarseDeltaY, coarseDeltaY, problem); - double leftNeighborGrading = momentumXResidual<TypeTag, Problem, Problem>(centralX-.5*coarseDeltaX, centralY, coarseDeltaX, coarseDeltaX, 2.*coarseDeltaY, coarseDeltaY, coarseDeltaY, problem); - - std::cout << "momentum y: rightNeighborGrading " << rightNeighborGrading << ", leftNeighborGrading " << leftNeighborGrading << std::endl; -///// - std::cout << "perfect interpolation, everything central and symmetric:"; -//x - double rightUpPerfectIterpSymm = momentumXResidual<TypeTag, Problem, Problem>( centralX + 5./8*coarseDeltaX, centralY+0.25*coarseDeltaY, 0.75*coarseDeltaX, 0.75*coarseDeltaX, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaY, problem); - double rightDownPerfectIterpSymm = momentumXResidual<TypeTag, Problem, Problem>( centralX + 5./8*coarseDeltaX, centralY-0.25*coarseDeltaY, 0.75*coarseDeltaX, 0.75*coarseDeltaX, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaY, problem); - double leftUpPerfectIterpSymm = momentumXResidual<TypeTag, Problem, Problem>( centralX - 5./8*coarseDeltaX, centralY+0.25*coarseDeltaY, 0.75*coarseDeltaX, 0.75*coarseDeltaX, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaY, problem); - double leftDownPerfectIterpSymm = momentumXResidual<TypeTag, Problem, Problem>( centralX - 5./8*coarseDeltaX, centralY-0.25*coarseDeltaY, 0.75*coarseDeltaX, 0.75*coarseDeltaX, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaY, problem); - double midUpPerfectIterpSymm = momentumXResidual<TypeTag, Problem, Problem>( centralX, centralY+0.25*coarseDeltaY, 0.5*coarseDeltaX, 0.5*coarseDeltaX, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaY, problem); - double midDownPerfectIterpSymm = momentumXResidual<TypeTag, Problem, Problem>( centralX, centralY-0.25*coarseDeltaY, 0.5*coarseDeltaX, 0.5*coarseDeltaX, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaY, problem); - - std::cout << "momentum x: right up " << rightUpPerfectIterpSymm << ", right down = " << rightDownPerfectIterpSymm << ", left up " << leftUpPerfectIterpSymm << ", left down = " << leftDownPerfectIterpSymm << ", mid up " << midUpPerfectIterpSymm << ", mid down = " << midDownPerfectIterpSymm << std::endl; - -//y - double upRightPerfectIterpSymm = momentumYResidual<TypeTag, Problem, Problem>( centralX+.25*coarseDeltaX, centralY+5./8*coarseDeltaY, 0.75*coarseDeltaY, 0.75*coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX, problem); - double upLeftPerfectIterpSymm = momentumYResidual<TypeTag, Problem, Problem>( centralX-.25*coarseDeltaX, centralY+5./8*coarseDeltaY, 0.75*coarseDeltaY, 0.75*coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX, problem); - double midRightPerfectIterpSymm = momentumYResidual<TypeTag, Problem, Problem>( centralX+.25*coarseDeltaX, centralY, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX, problem); - double midLeftPerfectIterpSymm = momentumYResidual<TypeTag, Problem, Problem>( centralX-.25*coarseDeltaX, centralY, .5*coarseDeltaY, .5*coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX, problem); - double downRightPerfectIterpSymm = momentumYResidual<TypeTag, Problem, Problem>(centralX+.25*coarseDeltaX, centralY-5./8*coarseDeltaY, 0.75*coarseDeltaY, 0.75*coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX, problem); - double downLeftPerfectIterpSymm = momentumYResidual<TypeTag, Problem, Problem>( centralX-.25*coarseDeltaX, centralY-5./8*coarseDeltaY, 0.75*coarseDeltaY, 0.75*coarseDeltaY, .5*coarseDeltaX, .5*coarseDeltaX, .5*coarseDeltaX, problem); - - std::cout << "momentum y: up right " << upRightPerfectIterpSymm << ", up left = " << upLeftPerfectIterpSymm << ", mid right " << midRightPerfectIterpSymm << ", mid left " << midLeftPerfectIterpSymm << ", downRight " << downRightPerfectIterpSymm << ", downLeft " << downLeftPerfectIterpSymm << std::endl; - - return; -}*/ diff --git a/dumux/io/grid/cvdcontrolvolumegrids_old.hh b/dumux/io/grid/cvdcontrolvolumegrids_old.hh deleted file mode 100644 index 1bb1d3b..0000000 --- a/dumux/io/grid/cvdcontrolvolumegrids_old.hh +++ /dev/null @@ -1,428 +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 Provides a grid creator builds a pore network grid from a host grid - */ -#ifndef DUMUX_CONTROL_VOLUME_GRID_HH -#define DUMUX_CONTROL_VOLUME_GRID_HH - -#include <iostream> -#include <fstream> -#include <iomanip> - -#include <dumux/discretization/staggered/freeflow/geometryhelper/cvdstaggeredgeometryhelper.hh> - -namespace Dumux { -template<class SubControlVolumeFace, class GridGeometry> - - -//Finds the two coordinates at "corners" of the subcontrolvolume face. If face is horizontal -void fillNonDirCoord_(const SubControlVolumeFace& scvf, - const GridGeometry& gridGeometry, - double& nonDirCoord0, - double& nonDirCoord1, - bool hangingNodesAreCVCenters) -{ - if (hangingNodesAreCVCenters && !scvf.boundary() && (scvf.inside().level() != scvf.outside().level())) - { - SubControlVolumeFace coarseSideScvf; - - if (!scvf.boundary() && (scvf.inside().level() < scvf.outside().level())) - { - coarseSideScvf = scvf; - } - else if (!scvf.boundary() && (scvf.inside().level() > scvf.outside().level())) - { - auto outsideFvGeometry = localView(gridGeometry); - outsideFvGeometry.bindElement(scvf.outside()); - - for (auto&& myscvf : scvfs(outsideFvGeometry)) - { - auto minusNormal = scvf.centerUnitOuterNormal(); - minusNormal *= -1.; - - if (containerCmp(myscvf.centerUnitOuterNormal(),minusNormal)) - { - if (containerCmp(myscvf.center(),scvf.center())) - { - coarseSideScvf = myscvf; - } - } - } - } - - unsigned int nonDirIdx = (scvf.directionIndex() == 0) ? 1 : 0; - const SubControlVolumeFace& normalFace0 = gridGeometry.scvf(coarseSideScvf.insideScvIdx(), coarseSideScvf.pairData(0).localNormalFluxCorrectionIndex); - nonDirCoord0 = normalFace0.center()[nonDirIdx]; - - const SubControlVolumeFace& normalFace1 = gridGeometry.scvf(coarseSideScvf.insideScvIdx(), coarseSideScvf.pairData(1).localNormalFluxCorrectionIndex); - nonDirCoord1 = normalFace1.center()[nonDirIdx]; - } - else - { - unsigned int dirIdx = scvf.directionIndex(); - unsigned int nonDirIdx = (dirIdx == 0) ? 1 : 0; - - nonDirCoord0 = scvf.corner(0)[nonDirIdx]; - nonDirCoord1 = scvf.corner(1)[nonDirIdx]; - } -} - -template<class GlobalPosition, class SubControlVolumeFace, class GridGeometry> -std::array<GlobalPosition,4> localCVVertices(const SubControlVolumeFace& scvf, const GridGeometry& gridGeometry, bool hangingNodesAreCVCenters) -{ - double nonDirCoord0; - double nonDirCoord1; - - fillNonDirCoord_(scvf, gridGeometry, nonDirCoord0, nonDirCoord1, hangingNodesAreCVCenters); - - unsigned int dirIdx = scvf.directionIndex(); - unsigned int nonDirIdx = (dirIdx == 0) ? 1 : 0; - - std::array<GlobalPosition,4> localVertices; - - //fill local vertices inside - GlobalPosition innerNormalCenter0; - innerNormalCenter0[dirIdx] = scvf.inside().geometry().center()[dirIdx]; - innerNormalCenter0[nonDirIdx] = nonDirCoord0; - - GlobalPosition innerNormalCenter1; - innerNormalCenter1[dirIdx] = scvf.inside().geometry().center()[dirIdx]; - innerNormalCenter1[nonDirIdx] = nonDirCoord1; - - localVertices[0] = innerNormalCenter0; - localVertices[1] = innerNormalCenter1; - - //fill local vertices outside - if (scvf.boundary()) - { - GlobalPosition scvfCorner0 = scvf.corner(0); - GlobalPosition scvfCorner1 = scvf.corner(1); - - localVertices[2] = scvfCorner0; - localVertices[3] = scvfCorner1; - } - else - { - GlobalPosition outerNormalCenter0; - outerNormalCenter0[dirIdx] = scvf.outside().geometry().center()[dirIdx]; - outerNormalCenter0[nonDirIdx] = nonDirCoord0; - - GlobalPosition outerNormalCenter1; - outerNormalCenter1[dirIdx] = scvf.outside().geometry().center()[dirIdx]; - outerNormalCenter1[nonDirIdx] = nonDirCoord1; - - localVertices[2] = outerNormalCenter0; - localVertices[3] = outerNormalCenter1; - } - - return localVertices; -} - -template<class GridGeometry, class GlobalPosition> -void fillCVsGridInfo(bool hangingNodesAreCVCenters, - const GridGeometry& gridGeometry, - int dirIdx, - std::map<int, GlobalPosition>& vertices, - std::vector<std::array<int,4>>& cubes, - std::vector<std::array<int,2>>& boundarySegments) -{ - using namespace Dumux; - unsigned int vertexNumber = 0; - - std::vector<unsigned int> visitedScvfDofs; - - for (const auto& element : elements(gridGeometry.gridView())) - { - auto fvGeometry = localView(gridGeometry); - fvGeometry.bindElement(element); - - for (auto&& scvf : scvfs(fvGeometry)) - { - if ( std::find(visitedScvfDofs.begin(), visitedScvfDofs.end(), scvf.dofIndex()) != visitedScvfDofs.end()) - continue; - - bool transitionFace = hangingNodesAreCVCenters && !scvf.boundary() && (scvf.inside().level() != scvf.outside().level()); - - if (transitionFace) - { - //fill visited dof - using SubControlVolumeFace = std::decay_t<decltype(scvf)>; - SubControlVolumeFace otherFace; - //fill other face - if (!scvf.boundary() && (scvf.inside().level() < scvf.outside().level())) - { - for (auto&& myscvf : scvfs(fvGeometry)) - { - if (containerCmp(myscvf.centerUnitOuterNormal(),scvf.centerUnitOuterNormal()) && !containerCmp(myscvf.center(),scvf.center())) - { - otherFace = myscvf; - } - } - } - else if (!scvf.boundary() && (scvf.inside().level() > scvf.outside().level())) - { - auto outsideFvGeometry = localView(gridGeometry); - outsideFvGeometry.bindElement(scvf.outside()); - - for (auto&& myscvf : scvfs(outsideFvGeometry)) - { - auto minusNormal = scvf.centerUnitOuterNormal(); - minusNormal *= -1.; - - if (containerCmp(myscvf.centerUnitOuterNormal(),minusNormal)) - { - if (!containerCmp(myscvf.center(),scvf.center())) - { - otherFace = myscvf; - } - } - } - } - - //fill visitedDof - if (std::find(visitedScvfDofs.begin(), visitedScvfDofs.end(), otherFace.dofIndex()) != visitedScvfDofs.end()) - { - visitedScvfDofs.push_back(scvf.dofIndex()); - continue; - } - } - - visitedScvfDofs.push_back(scvf.dofIndex()); - - if (scvf.directionIndex() == dirIdx) - { - std::array<GlobalPosition,4> localVertices = localCVVertices<GlobalPosition>(scvf, gridGeometry, hangingNodesAreCVCenters); - - std::array<int,4> localCube; - - std::array<int,2> parallelLocalBoundarySegment; - std::array<int,2> perpendicularLocalBoundarySegment; - - for (unsigned int i = 0; i < 4; ++i) - { - const GlobalPosition& vertex = localVertices[i]; - - int alreadyThereVertexNumber = -1; - for (auto it = vertices.begin(); it != vertices.end(); ++it) - { - if (containerCmp(it->second, vertex)) - { - alreadyThereVertexNumber = it->first; - } - } - - if (!(alreadyThereVertexNumber < 0)) - { - localCube[i] = alreadyThereVertexNumber; - } - else - { - localCube[i] = vertexNumber; - vertices.insert(std::pair<unsigned int, GlobalPosition>(vertexNumber, vertex)); - ++vertexNumber; - } - } - - for (unsigned int someIndex = 0; someIndex < 2; ++someIndex) - { - unsigned int otherIdx = (someIndex==0)?1:0; - - if (!scvf.hasParallelNeighbor(someIndex,0)) - { - if (containerCmp(scvf.pairData(someIndex).virtualFirstParallelFaceDofPos, scvf.corner(someIndex))) - { - if (someIndex==0) - perpendicularLocalBoundarySegment = {localCube[0],localCube[2]}; - else if (someIndex==1) - perpendicularLocalBoundarySegment = {localCube[1],localCube[3]}; - } - else if (containerCmp(scvf.pairData(someIndex).virtualFirstParallelFaceDofPos, scvf.corner(otherIdx))) - { - if (otherIdx==0) - perpendicularLocalBoundarySegment = {localCube[0],localCube[2]}; - else if (otherIdx==1) - perpendicularLocalBoundarySegment = {localCube[1],localCube[3]}; - } - else - DUNE_THROW(Dune::InvalidStateException, ""); - } - } - - if (scvf.boundary()) - parallelLocalBoundarySegment = {localCube[2],localCube[3]}; - - cubes.push_back(localCube); - - if (scvf.boundary()) - boundarySegments.push_back(parallelLocalBoundarySegment); - - if (!scvf.hasParallelNeighbor(0,0) || !scvf.hasParallelNeighbor(1,0)) - boundarySegments.push_back(perpendicularLocalBoundarySegment); - } - } - } -} - - -//Goal is to construct visualisation from actual previously constructed scvf's, instead of finding them here based on scvf normals -template <class GridGeometry, class GlobalPosition> -void fillCoarseVelocityCVsGridInfo(const GridGeometry& gridGeometry, - int dirIdx, - std::map<int, GlobalPosition>& vertices, - std::vector<std::array<int, 4>>& cubes, - std::vector<std::array<int, 2>>& boundarySegments) { - using namespace Dumux; - unsigned int vertexNumber = 0; - - std::vector<unsigned int> visitedScvfDofs; - - for (const auto& element : elements(gridGeometry.gridView())) { - auto fvGeometry = localView(gridGeometry); - fvGeometry.bindElement(element); - - for (auto&& scvf : scvfs(fvGeometry)) { - if (std::find(visitedScvfDofs.begin(), visitedScvfDofs.end(), scvf.dofIndex()) != visitedScvfDofs.end()) - continue; - - visitedScvfDofs.push_back(scvf.dofIndex()); - - if (scvf.directionIndex() == dirIdx) { - std::array<GlobalPosition, 4> localVertices = localCVVertices<GlobalPosition>(scvf, gridGeometry, true); - - std::array<int, 4> localCube; - - std::array<int, 2> parallelLocalBoundarySegment; - std::array<int, 2> perpendicularLocalBoundarySegment; - - for (unsigned int i = 0; i < 4; ++i) { - const GlobalPosition& vertex = localVertices[i]; - - int alreadyThereVertexNumber = -1; - for (auto it = vertices.begin(); it != vertices.end(); ++it) { - if (containerCmp(it->second, vertex)) { - alreadyThereVertexNumber = it->first; - } - } - - if (!(alreadyThereVertexNumber < 0)) { - localCube[i] = alreadyThereVertexNumber; - } else { - localCube[i] = vertexNumber; - vertices.insert(std::pair<unsigned int, GlobalPosition>(vertexNumber, vertex)); - ++vertexNumber; - } - } - - for (unsigned int someIndex = 0; someIndex < 2; ++someIndex) { - unsigned int otherIdx = (someIndex == 0) ? 1 : 0; - - if (!scvf.hasParallelNeighbor(someIndex, 0)) { - if (containerCmp(scvf.pairData(someIndex).virtualFirstParallelFaceDofPos, scvf.corner(someIndex))) { - if (someIndex == 0) - perpendicularLocalBoundarySegment = {localCube[0], localCube[2]}; - else if (someIndex == 1) - perpendicularLocalBoundarySegment = {localCube[1], localCube[3]}; - } else if (containerCmp(scvf.pairData(someIndex).virtualFirstParallelFaceDofPos, scvf.corner(otherIdx))) { - if (otherIdx == 0) - perpendicularLocalBoundarySegment = {localCube[0], localCube[2]}; - else if (otherIdx == 1) - perpendicularLocalBoundarySegment = {localCube[1], localCube[3]}; - } else - DUNE_THROW(Dune::InvalidStateException, ""); - } - } - - if (scvf.boundary()) - parallelLocalBoundarySegment = {localCube[2], localCube[3]}; - - cubes.push_back(localCube); - - if (scvf.boundary()) - boundarySegments.push_back(parallelLocalBoundarySegment); - - if (!scvf.hasParallelNeighbor(0, 0) || !scvf.hasParallelNeighbor(1, 0)) - boundarySegments.push_back(perpendicularLocalBoundarySegment); - } - } - } -} - -template<class GlobalPosition> -void printCVsGridInfo(const std::string& name, - const std::map<int, GlobalPosition>& vertices, - const std::vector<std::array<int,4>>& cubes, - const std::vector<std::array<int,2>>& boundarySegments) -{ - std::ofstream dgfFile; - dgfFile.open(name + ".dgf"); - dgfFile << "DGF" << std::endl; - dgfFile << "% Elements = " << cubes.size() << " | Vertices = " << vertices.size() << std::endl; - dgfFile << std::endl; - dgfFile << "VERTEX" << std::endl; - auto i = vertices.begin(); - while (i != vertices.end()) - { - dgfFile << (i->second)[0] << " " << (i->second)[1] << std::endl; - ++i; - } - dgfFile << "#" << std::endl; - dgfFile << std::endl; - dgfFile << "CUBE" << std::endl; - for (const auto& cube : cubes) - dgfFile << cube[0] << " " << cube[1] << " " << cube[2] << " " << cube[3] << std::endl; - dgfFile << "#" << std::endl; - dgfFile << std::endl; - dgfFile << "BOUNDARYSEGMENTS" << std::endl; - for (const auto& boundarySegment : boundarySegments) - dgfFile << "1 " << boundarySegment[0] << " " << boundarySegment[1] << std::endl; - dgfFile << "#" << std::endl; - dgfFile << std::endl; - dgfFile << "#" << std::endl; - dgfFile << "BOUNDARYDOMAIN" << std::endl; - dgfFile << "default 1 % all other boundary segments have id 1" << std::endl; //I had to add this as for some reason it seems that the hanging node stuff (faces at hanging nodes from both sides) is also treated as boundary, if I not set anything the boundary there has id 0 which is not allowed - dgfFile << "#" << std::endl; - dgfFile.close(); -} - -template<class GridGeometry, class GlobalPosition> -void generateCVsDGFfile(const std::string& paramGroup, const GridGeometry& gridGeometry, int dirIdx, bool hangingNodesAreCVCenters) -{ - std::map<int, GlobalPosition> vertices; - std::vector<std::array<int,4>> cubes; - std::vector<std::array<int,2>> boundarySegments; - - fillCVsGridInfo<GridGeometry, GlobalPosition>(hangingNodesAreCVCenters, gridGeometry,dirIdx, vertices, cubes, boundarySegments); - printCVsGridInfo<GlobalPosition>(paramGroup, vertices, cubes, boundarySegments); -} - -template<class GridGeometry, class GlobalPosition> -void createCoarseVelocityCVsDGFfile(const std::string& paramGroup, const GridGeometry& gridGeometry, int dirIdx){ - std::map<int, GlobalPosition> vertices; - std::vector<std::array<int,4>> cubes; - std::vector<std::array<int,2>> boundarySegments; - - fillCoarseVelocityCVsGridInfo<GridGeometry, GlobalPosition>(gridGeometry, dirIdx, vertices, cubes, boundarySegments); - printCVsGridInfo<GlobalPosition>(paramGroup, vertices, cubes, boundarySegments); -} - -} - -#endif -- GitLab From 152e4484061bb8ddf4348bb4af97a4220bf0922c Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Tue, 14 Sep 2021 12:20:42 +0300 Subject: [PATCH 26/69] channel copy --- .../channel_copy/2d/CMakeLists.txt | 64 ++ .../navierstokes/channel_copy/2d/main.cc | 535 ++++++++++++++++ .../channel_copy/2d/params_conduction.input | 50 ++ .../channel_copy/2d/params_convection.input | 50 ++ .../channel_copy/2d/params_graded.input | 69 ++ .../2d/params_grading_add_dof_good.input | 57 ++ .../channel_copy/2d/params_navierstokes.input | 43 ++ .../2d/params_navierstokes_stationary.input | 72 +++ .../channel_copy/2d/params_stokes.input | 65 ++ .../2d/params_stokes_stationary.input | 70 +++ .../params_stokes_stationary_fvcaGrid.input | 71 +++ .../channel_copy/2d/params_uniform.input | 57 ++ .../navierstokes/channel_copy/2d/problem.hh | 588 ++++++++++++++++++ .../navierstokes/channel_copy/CMakeLists.txt | 1 + 14 files changed, 1792 insertions(+) create mode 100644 appl/freeflow/navierstokes/channel_copy/2d/CMakeLists.txt create mode 100644 appl/freeflow/navierstokes/channel_copy/2d/main.cc create mode 100644 appl/freeflow/navierstokes/channel_copy/2d/params_conduction.input create mode 100644 appl/freeflow/navierstokes/channel_copy/2d/params_convection.input create mode 100644 appl/freeflow/navierstokes/channel_copy/2d/params_graded.input create mode 100644 appl/freeflow/navierstokes/channel_copy/2d/params_grading_add_dof_good.input create mode 100644 appl/freeflow/navierstokes/channel_copy/2d/params_navierstokes.input create mode 100644 appl/freeflow/navierstokes/channel_copy/2d/params_navierstokes_stationary.input create mode 100644 appl/freeflow/navierstokes/channel_copy/2d/params_stokes.input create mode 100644 appl/freeflow/navierstokes/channel_copy/2d/params_stokes_stationary.input create mode 100644 appl/freeflow/navierstokes/channel_copy/2d/params_stokes_stationary_fvcaGrid.input create mode 100644 appl/freeflow/navierstokes/channel_copy/2d/params_uniform.input create mode 100644 appl/freeflow/navierstokes/channel_copy/2d/problem.hh create mode 100644 appl/freeflow/navierstokes/channel_copy/CMakeLists.txt diff --git a/appl/freeflow/navierstokes/channel_copy/2d/CMakeLists.txt b/appl/freeflow/navierstokes/channel_copy/2d/CMakeLists.txt new file mode 100644 index 0000000..a4c7227 --- /dev/null +++ b/appl/freeflow/navierstokes/channel_copy/2d/CMakeLists.txt @@ -0,0 +1,64 @@ +add_input_file_links() + +set(CMAKE_BUILD_TYPE Debug) + +add_executable(test_ff_channel EXCLUDE_FROM_ALL main.cc) + +dune_add_test(NAME test_ff_stokes_channel + TARGET test_ff_channel + CMAKE_GUARD HAVE_UMFPACK + COMMAND ${CMAKE_SOURCE_DIR}/../dumux/bin/testing/runtest.py + CMD_ARGS --script fuzzy + --files ${CMAKE_SOURCE_DIR}/../dumux/test/references/channel-stokes.vtu + ${CMAKE_CURRENT_BINARY_DIR}/test_ff_stokes_channel-00002.vtu + --command "${CMAKE_CURRENT_BINARY_DIR}/test_ff_channel params_stokes.input") + +dune_add_test(NAME test_ff_navierstokes_channel + TARGET test_ff_channel + CMAKE_GUARD HAVE_UMFPACK + COMMAND ${CMAKE_SOURCE_DIR}/../dumux/bin/testing/runtest.py + CMD_ARGS --script fuzzy + --files ${CMAKE_SOURCE_DIR}/../dumux/test/references/channel-navierstokes-reference.vtu + ${CMAKE_CURRENT_BINARY_DIR}/test_ff_navierstokes_channel-00002.vtu + --command "${CMAKE_CURRENT_BINARY_DIR}/test_ff_channel params_navierstokes.input") + +dune_add_test(NAME test_ff_channel_stokes_stationary + TARGET test_ff_channel + CMAKE_GUARD HAVE_UMFPACK + COMMAND ${CMAKE_SOURCE_DIR}/../dumux/bin/testing/runtest.py + CMD_ARGS --script fuzzy + --files ${CMAKE_SOURCE_DIR}/../dumux/test/references/channel-stokes-stationary.vtu + ${CMAKE_CURRENT_BINARY_DIR}/test_channel_stokes_stationary-00002.vtu + --command "${CMAKE_CURRENT_BINARY_DIR}/test_ff_channel params_stokes_stationary.input") + +dune_add_test(NAME test_ff_channel_navierstokes_stationary + TARGET test_ff_channel + CMAKE_GUARD HAVE_UMFPACK + COMMAND ${CMAKE_SOURCE_DIR}/../dumux/bin/testing/runtest.py + CMD_ARGS --script fuzzy + --files ${CMAKE_SOURCE_DIR}/../dumux/test/references/channel-navierstokes-stationary.vtu + ${CMAKE_CURRENT_BINARY_DIR}/test_channel_navierstokes_stationary-00002.vtu + --command "${CMAKE_CURRENT_BINARY_DIR}/test_ff_channel params_navierstokes_stationary.input") + + +add_executable(test_ff_stokesni_channel EXCLUDE_FROM_ALL main.cc) +target_compile_definitions(test_ff_stokesni_channel PUBLIC "NONISOTHERMAL=1") + +dune_add_test(NAME test_ff_channel_stokesni_convection + TARGET test_ff_stokesni_channel + CMAKE_GUARD HAVE_UMFPACK + COMMAND ${CMAKE_SOURCE_DIR}/../dumux/bin/testing/runtest.py + CMD_ARGS --script fuzzy + --files ${CMAKE_SOURCE_DIR}/../dumux/test/references/stokesni-convection-reference.vtu + ${CMAKE_CURRENT_BINARY_DIR}/test_channel_stokesni_convection-00006.vtu + --command "${CMAKE_CURRENT_BINARY_DIR}/test_ff_stokesni_channel params_convection.input") + +dune_add_test(NAME test_ff_channel_stokesni_conduction + TARGET test_ff_stokesni_channel + CMAKE_GUARD HAVE_UMFPACK + COMMAND ${CMAKE_SOURCE_DIR}/../dumux/bin/testing/runtest.py + CMD_ARGS --script fuzzy + --files ${CMAKE_SOURCE_DIR}/../dumux/test/references/stokesni-conduction-reference.vtu + ${CMAKE_CURRENT_BINARY_DIR}/test_channel_stokesni_conduction-00004.vtu + --command "${CMAKE_CURRENT_BINARY_DIR}/test_ff_stokesni_channel params_conduction.input" + --zeroThreshold {"velocity_H2O \(m/s\)":1e-20}) diff --git a/appl/freeflow/navierstokes/channel_copy/2d/main.cc b/appl/freeflow/navierstokes/channel_copy/2d/main.cc new file mode 100644 index 0000000..a6cd218 --- /dev/null +++ b/appl/freeflow/navierstokes/channel_copy/2d/main.cc @@ -0,0 +1,535 @@ +// -*- 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 Channel flow test for the staggered grid (Navier-)Stokes model + */ + +bool doFirstOrderLocalTruncErrorGlobalRefinement = false; + + #include <config.h> + + #include <ctime> + #include <iostream> + + #include <dune/common/parallel/mpihelper.hh> + #include <dune/common/timer.hh> + #include <dune/grid/io/file/dgfparser/dgfwriter.hh> + #include <dune/grid/io/file/dgfparser/dgfexception.hh> + #include <dune/grid/io/file/vtk.hh> + #include <dune/istl/io.hh> + +#include <dumux/common/properties.hh> +#include <dumux/common/coursevelocityproperties.hh> +#include <dumux/common/parameters.hh> +#include <dumux/common/dumuxmessage.hh> +#include <dumux/common/defaultusagemessage.hh> + +#include <dumux/linear/seqsolverbackend.hh> +#include <dumux/nonlinear/newtonsolver.hh> + +#include <dumux/assembly/cvdstaggeredrefinedfvassembler.hh> +#include <dumux/assembly/diffmethod.hh> + +#include <dumux/discretization/method.hh> + +#include <dumux/io/mystaggeredvtkoutputmodule.hh> +#include <dumux/io/grid/gridmanager.hh> + +#include <dumux/freeflow/navierstokes/staggered/cvdfluxoversurface.hh> + +#include <dumux/adaptive/adapt.hh> +#include <dumux/adaptive/markelements.hh> + +#include <dumux/freeflow/cvdgridadaptindicator.hh> +#include <dumux/freeflow/navierstokes/staggered/griddatatransfer.hh> + +#include <dumux/discretization/staggered/cvdfvgridgeometry.hh> +#include <dumux/discretization/staggered/freeflow/cvdfvgridgeometrytraits.hh> + +#include <dumux/freeflow/navierstokes/staggered/cvdresidualCalc.hh> +#include <dumux/io/cvdoutputFacility.hh> + +#include "problem.hh" + +int main(int argc, char** argv) try +{ + using namespace Dumux; + + // define the type tag for this problem + using TypeTag = Properties::TTag::ChannelTestTypeTag; + + // 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); + + bool doFirstOrderLocalTruncError = getParam<bool>("Numerics.DoFirstOrderLocalTruncError", false); + bool adapt = getParam<bool>("Adaptivity.Adapt", false); + //when adapt is true refinement is local, not only global + doFirstOrderLocalTruncErrorGlobalRefinement = !adapt && doFirstOrderLocalTruncError; + + using HelpingGridManager = Dumux::GridManager<GetPropType<TypeTag, Properties::HelpingGrid>>; + HelpingGridManager helpingGridManager; + helpingGridManager.init("Helper"); + const auto& helpingGridView = helpingGridManager.grid().leafGridView(); + Dune::DGFWriter dgfWriter(helpingGridView); + std::string inputFileName = getParam<std::string>("Grid.File"); + dgfWriter.write(inputFileName); + + // The hostgrid + using GridView = typename GetPropType<TypeTag, Properties::GridGeometry>::GridView; + using HostGrid = Dune::ALUGrid<2,2,Dune::cube,Dune::nonconforming >;/* typename GetPropType<TypeTag, Properties::Grid>::HostGrid;*/ + using HostGridManager = GridManager<HostGrid>; + HostGridManager hostGridManager; + hostGridManager.init(); + auto& hostGrid = hostGridManager.grid(); + + // we compute on the leaf grid view + const auto& leafGridViewVar = hostGrid.leafGridView(); + + bool roughChannel = getParam<bool>("Adaptivity.RoughChannel", false); + using Scalar = GetPropType<TypeTag, Properties::Scalar>; + + bool FVCAgrid = getParam<bool>("Grid.FVCAGrid", false); + if (FVCAgrid) + { + adapt = false; + + hostGrid.preAdapt(); + for (const auto& element : elements(leafGridViewVar)) + { + using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; + using GridView = typename GridGeometry::GridView; + using Element = typename GridView::template Codim<0>::Entity; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + + GlobalPosition pos = element.geometry().center(); + + auto x = pos[0]; + auto y = pos[1]; + + if(x > .5 && y < .5) + { + hostGrid.mark( 1, element); + } + } + hostGrid.adapt(); + hostGrid.postAdapt(); + + hostGrid.preAdapt(); + for (const auto& element : elements(leafGridViewVar)) + { + using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; + using GridView = typename GridGeometry::GridView; + using Element = typename GridView::template Codim<0>::Entity; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + + GlobalPosition pos = element.geometry().center(); + + auto x = pos[0]; + auto y = pos[1]; + + if(x > .75 && y < .25) + { + hostGrid.mark( 1, element); + } + } + hostGrid.adapt(); + hostGrid.postAdapt(); + } + + if (adapt) + { + Scalar leftX = getParam<Scalar>("Adaptivity.LeftX"); + Scalar rightX = getParam<Scalar>("Adaptivity.RightX"); + Scalar lowerY = getParam<Scalar>("Adaptivity.LowerY"); + Scalar upperY = getParam<Scalar>("Adaptivity.UpperY"); + + hostGrid.preAdapt(); + for (const auto& element : elements(leafGridViewVar)) + { + using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; + using GridView = typename GridGeometry::GridView; + using Element = typename GridView::template Codim<0>::Entity; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + + GlobalPosition pos = element.geometry().center(); + + auto x = pos[0]; + auto y = pos[1]; + + if((leftX < x) && (x < rightX) && (y > lowerY) && (y < upperY)) + { + hostGrid.mark( 1, element); + } + } + hostGrid.adapt(); + hostGrid.postAdapt(); + + if (roughChannel) + { + hostGrid.preAdapt(); + for (const auto& element : elements(leafGridViewVar)) + { + using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; + using GridView = typename GridGeometry::GridView; + using Element = typename GridView::template Codim<0>::Entity; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + GlobalPosition pos = element.geometry().center(); + + auto x = pos[0]; + auto y = pos[1]; + + auto inCircle = [&](Scalar xCenter, Scalar yCenter, Scalar radius) + { + return (x-xCenter)*(x-xCenter) + (y-yCenter)*(y-yCenter) < radius*radius; + }; + + Scalar myRadius = .25; + + if(inCircle(2, .2, myRadius) || inCircle(3, .2, myRadius) ||inCircle(5, .2, myRadius) ||inCircle(6, .2, myRadius) ||inCircle(8, .2, myRadius) ||inCircle(9, .2, myRadius) ) + { + hostGrid.mark( 1, element); + } + } + hostGrid.adapt(); + hostGrid.postAdapt(); + + + hostGrid.preAdapt(); + for (const auto& element : elements(leafGridViewVar)) + { + using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; + using GridView = typename GridGeometry::GridView; + using Element = typename GridView::template Codim<0>::Entity; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + GlobalPosition pos = element.geometry().center(); + + auto x = pos[0]; + auto y = pos[1]; + + auto inCircle = [&](Scalar xCenter, Scalar yCenter, Scalar radius) + { + return (x-xCenter)*(x-xCenter) + (y-yCenter)*(y-yCenter) < radius*radius; + }; + + Scalar myRadius = .15; + + if(inCircle(2, .2, myRadius) || inCircle(3, .2, myRadius) ||inCircle(5, .2, myRadius) ||inCircle(6, .2, myRadius) ||inCircle(8, .2, myRadius) ||inCircle(9, .2, myRadius) ) + { + hostGrid.mark( 1, element); + } + } + hostGrid.adapt(); + hostGrid.postAdapt(); + } + } + + // create a grid + using Grid = GetPropType<TypeTag, Properties::Grid>; + Dumux::GridManager<Grid> gridManager; + + // cut out elements within the stair-case region + auto selector = [&](const auto& element) + { + if (!roughChannel) + return true; + + const auto globalPos = element.geometry().center(); + const auto x = globalPos[0]; + const auto y = globalPos[1]; + + return y > 0.2 || + (x > 2 && x < 3) || + (x > 5 && x < 6) || + (x > 8 && x < 9); + }; + + gridManager.init(hostGrid, selector); + + //////////////////////////////////////////////////////////// + // 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); + + // get some time loop parameters + const auto tEnd = getParam<Scalar>("TimeLoop.TEnd", 0.); + const auto maxDt = getParam<Scalar>("TimeLoop.MaxTimeStepSize"); + auto dt = getParam<Scalar>("TimeLoop.DtInitial", 0.); + + // check if we are about to restart a previously interrupted simulation + Scalar restartTime = 0; + if (Parameters::getTree().hasKey("Restart") || Parameters::getTree().hasKey("TimeLoop.Restart")) + restartTime = getParam<Scalar>("TimeLoop.Restart"); + + // instantiate time loop + auto timeLoop = std::make_shared<CheckPointTimeLoop<Scalar>>(restartTime, dt, tEnd); + timeLoop->setMaxTimeStepSize(maxDt); + problem->setTimeLoop(timeLoop); + + // the solution vector + using SolutionVector = GetPropType<TypeTag, Properties::SolutionVector>; + const auto numDofsCellCenter = leafGridView.size(0); + const auto numDofsFace = (*gridGeometry).numIntersections(); + SolutionVector x; + x[GridGeometry::cellCenterIdx()].resize(numDofsCellCenter); + x[GridGeometry::faceIdx()].resize(numDofsFace); + 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>; + MyStaggeredVtkOutputModule<GridVariables, SolutionVector> vtkWriter(*gridVariables, x, problem->name()); + IOFields::initOutputModule(vtkWriter); //!< Add model specific output fields + problem->createAnalyticalSolution(); + + const bool isStationary = getParam<bool>("Problem.IsStationary"); + + if(isStationary) + { + vtkWriter.addField(problem->getAnalyticalPressureSolution(), "pressureExact"); + vtkWriter.addField(problem->getAnalyticalVelocitySolution(), "velocityExact"); + vtkWriter.addFaceField(problem->getAnalyticalVelocitySolutionOnFace(), "faceVelocityExact"); + } + vtkWriter.write(0.0); + + using CellCenterSolutionVector = GetPropType<TypeTag, Properties::CellCenterSolutionVector>; + CellCenterSolutionVector numericalCCResidualWithAnalytical; + numericalCCResidualWithAnalytical.resize(numDofsCellCenter); + vtkWriter.addField(numericalCCResidualWithAnalytical, "continuityResidual"); + + // the assembler with time loop for instationary problem + using Assembler = CVDStaggeredRefinedFVAssembler<TypeTag, DiffMethod::numeric>; + auto assembler = isStationary ? std::make_shared<Assembler>(problem, gridGeometry, gridVariables) + : std::make_shared<Assembler>(problem, gridGeometry, gridVariables, timeLoop, xOld); + + // the linear solver + using LinearSolver = Dumux::UMFPackBackend; + auto linearSolver = std::make_shared<LinearSolver>(); + + // the non-linear solver + using NewtonSolver = Dumux::NewtonSolver<Assembler, LinearSolver>; + NewtonSolver nonLinearSolver(assembler, linearSolver); + + // set up two surfaces over which fluxes are calculated + MyFluxOverSurface<GridVariables, + SolutionVector, + GetPropType<TypeTag, Properties::ModelTraits>, + GetPropType<TypeTag, Properties::LocalResidual>> flux(*gridVariables, x); + using GridView = typename GetPropType<TypeTag, Properties::GridGeometry>::GridView; + using Element = typename GridView::template Codim<0>::Entity; + + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + + const Scalar xMin = gridGeometry->bBoxMin()[0]; + const Scalar xMax = gridGeometry->bBoxMax()[0]; + const Scalar yMin = gridGeometry->bBoxMin()[1]; + const Scalar yMax = gridGeometry->bBoxMax()[1]; + + // The first surface shall be placed at the middle of the channel. + // If we have an odd number of cells in x-direction, there would not be any cell faces + // at the position of the surface (which is required for the flux calculation). + // In this case, we add half a cell-width to the x-position in order to make sure that + // the cell faces lie on the surface. This assumes a regular cartesian grid. + const Scalar planePosMiddleX = xMin + 0.5*(xMax - xMin); + + using CellVector = std::vector<unsigned int>; + const auto numCellsXVec = getParam<CellVector>("Helper.Grid.Cells0"); + const unsigned int numCellsX = std::accumulate(numCellsXVec.begin(), numCellsXVec.end(), 0); + + const Scalar offsetX = (numCellsX % 2 == 0) ? 0.0 : 0.5*((xMax - xMin) / numCellsX); + + const auto p0middle = GlobalPosition{planePosMiddleX + offsetX, yMin}; + const auto p1middle = GlobalPosition{planePosMiddleX + offsetX, yMax}; + flux.addSurface("middle", p0middle, p1middle); + + // The second surface is placed at the outlet of the channel. + const auto p0outlet = GlobalPosition{xMax, yMin}; + const auto p1outlet = GlobalPosition{xMax, yMax}; + flux.addSurface("outlet", p0outlet, p1outlet); + + if (isStationary) + { + using HostGrid = Dune::ALUGrid<2,2,Dune::cube,Dune::nonconforming >; + using HostGridManager = GridManager<HostGrid>; + + std::array<std::string, 2> paramGroups = {"coarsexCVs", "coarseyCVs"}; //xfine... + std::array<HostGridManager, 2> cvGridManagers = {}; + std::array<std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>>,2> cvCenterScvfIndicesMaps; + CVDCVOutputFacility<TypeTag> cvOutputFacility(problem); + cvOutputFacility.iniCVGridManagers(cvGridManagers, cvCenterScvfIndicesMaps, paramGroups); + using Scalar = GetPropType<TypeTag, Properties::Scalar>; + std::vector<std::pair<unsigned int, Scalar>> pvdFileInfos; + + // linearize & solve + Dune::Timer timer; + nonLinearSolver.solve(x); + + //output + if (getParam<bool>("Problem.PrintErrors", true)) + problem->printErrors(x); + + using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; + FaceSolutionVector numericalFaceResidualWithAnalytical; + + std::optional<std::array<std::vector<Scalar>, 2>> optionalPerfectInterpolationFaceResiduals; + //TODO when reintroducing outflow BC make this empty with outflow BC + // std::array<std::vector<Scalar>, 4> perfectInterpolationFaceResiduals; + // optionalPerfectInterpolationFaceResiduals.emplace(perfectInterpolationFaceResiduals); + + ResidualCalc<TypeTag> residualCalc(problem); + residualCalc.calcResidualsStationary(gridGeometry, numericalCCResidualWithAnalytical, numericalFaceResidualWithAnalytical); + + bool readDofBasedValues = getParam<bool>("Problem.ReadDofBasedValues", false); + if (readDofBasedValues) + { + CellCenterSolutionVector readInPres; + readInPres.resize(gridGeometry->numCellCenterDofs()); + ReadDofBasedResult<TypeTag> reader(problem); + reader.readDofBasedResult(readInPres, "pressure"); + vtkWriter.addField(readInPres, "readInPres"); + } + + vtkWriter.write(1.); + + cvOutputFacility.onCVsOutputResidualsAndPrimVars( + gridGeometry, + cvGridManagers, + cvCenterScvfIndicesMaps, + paramGroups, + x, + 0, + numericalFaceResidualWithAnalytical, + optionalPerfectInterpolationFaceResiduals, + readDofBasedValues); + + pvdFileInfos.push_back(std::make_pair(0, 0)); + cvOutputFacility.printPvdFiles(paramGroups, pvdFileInfos); + + timer.stop(); + } + else + { + // 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()); + + // calculate and print mass fluxes over the planes + flux.calculateMassOrMoleFluxes(); + if(GetPropType<TypeTag, Properties::ModelTraits>::enableEnergyBalance()) + { + std::cout << "mass / energy flux at middle is: " << flux.netFlux("middle") << std::endl; + std::cout << "mass / energy flux at outlet is: " << flux.netFlux("outlet") << std::endl; + } + else + { + std::cout << "mass flux at middle is: " << flux.netFlux("middle") << std::endl; + std::cout << "mass flux at outlet is: " << flux.netFlux("outlet") << std::endl; + } + + // calculate and print volume fluxes over the planes + flux.calculateVolumeFluxes(); + std::cout << "volume flux at middle is: " << flux.netFlux("middle")[0] << std::endl; + std::cout << "volume flux at outlet is: " << flux.netFlux("outlet")[0] << std::endl; + + // report statistics of this time step + timeLoop->reportTimeStep(); + + // set new dt as suggested by 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/appl/freeflow/navierstokes/channel_copy/2d/params_conduction.input b/appl/freeflow/navierstokes/channel_copy/2d/params_conduction.input new file mode 100644 index 0000000..e2d46c3 --- /dev/null +++ b/appl/freeflow/navierstokes/channel_copy/2d/params_conduction.input @@ -0,0 +1,50 @@ +[TimeLoop] +DtInitial = 1e7 # [s] +TEnd = 1e8 # [s] + +[Helper.Grid] +Positions0 = 0 10 +Positions1 = 0 1 +Cells0 = 10 +Cells1 = 5 +Grading0 = 1.0 +Grading1 = 1.0 + +[Grid] +File = grid.dgf + +[Problem] +Name = test_channel_stokesni_conduction # name passed to the output routines +InletVelocity = 0 +EnableGravity = false +EnableInertiaTerms = false +PrintErrors = true +IsStationary = false + +[Component] +MolarMass = 1.0 +LiquidDensity = 1 +LiquidKinematicViscosity = 1 + +[ Newton ] +MaxSteps = 10 +MaxRelativeShift = 1e-8 + +[Vtk] +WriteFaceData = false + +[Adaptivity] +Conservation = true +Adapt = true +LeftX = 2 +RightX = 8 +LowerY = 0.2 +UpperY = 0.8 + +[Adaptive] +RefineAtDirichletBC = 0 +RefineAtFluxBC = 1 +MinLevel = 0 +MaxLevel = 0 +CoarsenTolerance = 1e-4 +RefineTolerance = 2e-1 diff --git a/appl/freeflow/navierstokes/channel_copy/2d/params_convection.input b/appl/freeflow/navierstokes/channel_copy/2d/params_convection.input new file mode 100644 index 0000000..aeacc54 --- /dev/null +++ b/appl/freeflow/navierstokes/channel_copy/2d/params_convection.input @@ -0,0 +1,50 @@ +[TimeLoop] +DtInitial = 50 # [s] +TEnd = 250 # [s] + +[Helper.Grid] +Positions0 = 0 0.5 +Positions1 = 0 0.025 +Cells0 = 10 +Cells1 = 5 +Grading0 = 1.0 +Grading1 = 1.0 + +[Grid] +File = grid.dgf + +[Problem] +Name = test_channel_stokesni_convection # name passed to the output routines +InletVelocity = 1e-2 +EnableGravity = false +EnableInertiaTerms = false +PrintErrors = true +IsStationary = false + +[Component] +MolarMass = 1.0 +LiquidDensity = 1 +LiquidKinematicViscosity = 1 + +[ Newton ] +MaxSteps = 10 +MaxRelativeShift = 1e-8 + +[Vtk] +WriteFaceData = false + +[Adaptivity] +Conservation = true +Adapt = true +LeftX = 2 +RightX = 8 +LowerY = 0.2 +UpperY = 0.8 + +[Adaptive] +RefineAtDirichletBC = 0 +RefineAtFluxBC = 1 +MinLevel = 0 +MaxLevel = 0 +CoarsenTolerance = 1e-4 +RefineTolerance = 2e-1 diff --git a/appl/freeflow/navierstokes/channel_copy/2d/params_graded.input b/appl/freeflow/navierstokes/channel_copy/2d/params_graded.input new file mode 100644 index 0000000..0d15b9f --- /dev/null +++ b/appl/freeflow/navierstokes/channel_copy/2d/params_graded.input @@ -0,0 +1,69 @@ +[TimeLoop] +DtInitial = 1 # [s] +TEnd = 2 # [s] + +[Helper.Grid] +UpperRight = 10 1 +Cells = 100 50 +Positions0 = 0 10 +Positions1 = 0 0.1 0.3 0.4 0.6 0.7 0.9 1 +Cells0 = 20 +Cells1 = 2 2 2 2 2 2 2 +Grading0 = 1 +Grading1 = 1 1 1 1 1 1 1 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = graded # name passed to the output routines +InletVelocity = 1 +EnableGravity = false +EnableInertiaTerms = false +OutletCondition = Outflow +UseVelocityProfile = true +PrintErrors = true +IsStationary = true + +[Component] +MolarMass = 1.0 +LiquidDensity = 1.0 +LiquidKinematicViscosity = 1.0 + +[ Newton ] +MaxSteps = 10 +MaxRelativeShift = 1e-8 + +[FreeFlow] +EnableVelocityGradientFactor = false + +[Vtk] +WriteFaceData = true +Precision = Float64 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-3 + +# This test does actually not require setting the primary variable magnitues. +# This rather serves as a demonstration of how to use the feature. +# [CellCenter.Assembly] +# NumericDifference.PriVarMagnitude = 1e5 # pressure is in the order of 1e5 + +[Face.Assembly] +# NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 + +[Adaptivity] +Conservation = false +Adapt = false diff --git a/appl/freeflow/navierstokes/channel_copy/2d/params_grading_add_dof_good.input b/appl/freeflow/navierstokes/channel_copy/2d/params_grading_add_dof_good.input new file mode 100644 index 0000000..ce697b1 --- /dev/null +++ b/appl/freeflow/navierstokes/channel_copy/2d/params_grading_add_dof_good.input @@ -0,0 +1,57 @@ +[TimeLoop] +DtInitial = 1 # [s] +TEnd = 2 # [s] + +[Helper.Grid] +UpperRight = 10 1 +Cells = 100 50 +Positions0 = 0 10 +Positions1 = 0 0.1 0.9 1 +Cells0 = 20 +Cells1 = 3 16 2 +Grading0 = 1 +Grading1 = 1 1 1 + +[Grid] +File = grid.dgf + +[Problem] +Name = graded # name passed to the output routines +InletVelocity = 1 +EnableGravity = false +EnableInertiaTerms = false +OutletCondition = Outflow +UseVelocityProfile = true +PrintErrors = true +IsStationary = true + +[Component] +MolarMass = 1. +LiquidDensity = 1.0 +LiquidKinematicViscosity = 1.0 + +[ Newton ] +MaxSteps = 10 +MaxRelativeShift = 1e-8 + +[FreeFlow] +EnableVelocityGradientFactor = false + +[Vtk] +WriteFaceData = false# +Precision = Float64 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-3 + +# This test does actually not require setting the primary variable magnitues. +# This rather serves as a demonstration of how to use the feature. +# [CellCenter.Assembly] +# NumericDifference.PriVarMagnitude = 1e5 # pressure is in the order of 1e5 + +[Face.Assembly] +# NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 + +[Adaptivity] +Conservation = false +Adapt = false diff --git a/appl/freeflow/navierstokes/channel_copy/2d/params_navierstokes.input b/appl/freeflow/navierstokes/channel_copy/2d/params_navierstokes.input new file mode 100644 index 0000000..ab06b01 --- /dev/null +++ b/appl/freeflow/navierstokes/channel_copy/2d/params_navierstokes.input @@ -0,0 +1,43 @@ +[TimeLoop] +DtInitial = 1 # [s] +TEnd = 2 # [s] + +[Helper.Grid] +Positions0 = 0 10 +Positions1 = 0 1 +Cells0 = 10 +Cells1 = 5 +Grading0 = 1.0 +Grading1 = 1.0 + +[Grid] +File = grid.dgf + +[Problem] +Name = test_channel_navierstokes # name passed to the output routines +InletVelocity = 1000 +EnableGravity = false +PrintErrors = true +IsStationary = false + +[Component] +LiquidDensity = 1.0 +LiquidKinematicViscosity = 1.0 +MolarMass = 1.0 + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-5 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true + +[Vtk] +WriteFaceData = false + +[Adaptivity] +Conservation = false +Adapt = true +LeftX = 2 +RightX = 8 +LowerY = 0.2 +UpperY = 0.8 diff --git a/appl/freeflow/navierstokes/channel_copy/2d/params_navierstokes_stationary.input b/appl/freeflow/navierstokes/channel_copy/2d/params_navierstokes_stationary.input new file mode 100644 index 0000000..968f8d2 --- /dev/null +++ b/appl/freeflow/navierstokes/channel_copy/2d/params_navierstokes_stationary.input @@ -0,0 +1,72 @@ +[Helper.Grid] +Positions0 = 0 10 +Positions1 = 0 1 +Cells0 = 15 +Cells1 = 6 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_channel_navierstokes_stationary # name passed to the output routines +InletVelocity = 100 +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +AveragedAnalyticalSolution = false + +[Component] +MolarMass = 1.0 +LiquidDensity = 1 +LiquidKinematicViscosity = 1 + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-4 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true + +[Vtk] +WriteFaceData = false + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +# This test does actually not require setting the primary variable magnitues. +# This rather serves as a demonstration of how to use the feature. +[CellCenter.Assembly] +NumericDifference.PriVarMagnitude = 1e5 # pressure is in the order of 1e5 + +[Face.Assembly] +NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 + +[Adaptivity] +Conservation = false +Adapt = true +LeftX = 2 +RightX = 8 +LowerY = 0.2 +UpperY = 0.8 + +[Adaptive] +RefineAtDirichletBC = 0 +RefineAtFluxBC = 1 +MinLevel = 0 +MaxLevel = 0 +CoarsenTolerance = 1e-4 +RefineTolerance = 2e-1 diff --git a/appl/freeflow/navierstokes/channel_copy/2d/params_stokes.input b/appl/freeflow/navierstokes/channel_copy/2d/params_stokes.input new file mode 100644 index 0000000..9101022 --- /dev/null +++ b/appl/freeflow/navierstokes/channel_copy/2d/params_stokes.input @@ -0,0 +1,65 @@ +[TimeLoop] +DtInitial = 1 # [s] +TEnd = 2 # [s] + +[Helper.Grid] +Positions0 = 0 10 +Positions1 = 0 1 +Cells0 = 10 +Cells1 = 5 +Grading0 = 1.0 +Grading1 = 1.0 + +[Grid] +File = grid.dgf + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Problem] +Name = test_channel_stokes # name passed to the output routines +InletVelocity = 1 +EnableGravity = false +EnableInertiaTerms = false +PrintErrors = true +IsStationary = false + +[Component] +MolarMass = 1.0 +LiquidDensity = 1 +LiquidKinematicViscosity = 1 + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-8 + +[Vtk] +WriteFaceData = false + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +# This test does actually not require setting the primary variable magnitues. +# This rather serves as a demonstration of how to use the feature. +[CellCenter.Assembly] +NumericDifference.PriVarMagnitude = 1e5 # pressure is in the order of 1e5 + +[Face.Assembly] +NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 + +[Adaptivity] +Conservation = true +Adapt = true +LeftX = 3 +RightX = 5 +LowerY = 0.2 +UpperY = 0.6 diff --git a/appl/freeflow/navierstokes/channel_copy/2d/params_stokes_stationary.input b/appl/freeflow/navierstokes/channel_copy/2d/params_stokes_stationary.input new file mode 100644 index 0000000..de8baa2 --- /dev/null +++ b/appl/freeflow/navierstokes/channel_copy/2d/params_stokes_stationary.input @@ -0,0 +1,70 @@ +[Helper.Grid] +Positions0 = 0 10 +Positions1 = 0 1 +Cells0 = 5 +Cells1 = 5 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_channel_stokes_stationary # name passed to the output routines +InletVelocity = 1 +EnableGravity = false +EnableInertiaTerms = false +PrintErrors = true +IsStationary = true + +[Component] +MolarMass = 1.0 +LiquidDensity = 1 +LiquidKinematicViscosity = 1 + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-15 + +[Vtk] +WriteFaceData = false + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +# This test does actually not require setting the primary variable magnitues. +# This rather serves as a demonstration of how to use the feature. +[CellCenter.Assembly] +NumericDifference.PriVarMagnitude = 1e5 # pressure is in the order of 1e5 + +[Face.Assembly] +NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 + +[Adaptivity] +Conservation = false +Adapt = true +LeftX = 4 +RightX = 6 +LowerY = .4 +UpperY = .6 + + +[Adaptive] +RefineAtDirichletBC = 0 +RefineAtFluxBC = 1 +MinLevel = 0 +MaxLevel = 0 +CoarsenTolerance = 1e-4 +RefineTolerance = 2e-1 diff --git a/appl/freeflow/navierstokes/channel_copy/2d/params_stokes_stationary_fvcaGrid.input b/appl/freeflow/navierstokes/channel_copy/2d/params_stokes_stationary_fvcaGrid.input new file mode 100644 index 0000000..13efb63 --- /dev/null +++ b/appl/freeflow/navierstokes/channel_copy/2d/params_stokes_stationary_fvcaGrid.input @@ -0,0 +1,71 @@ +[Helper.Grid] +Positions0 = 0 1 +Positions1 = 0 1 +Cells0 = 4 +Cells1 = 4 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf +FVCAGrid = true + +[Problem] +Name = test_channel_fvca # name passed to the output routines +InletVelocity = 1 +EnableGravity = false +EnableInertiaTerms = false +PrintErrors = true +IsStationary = true + +[Component] +MolarMass = 1.0 +LiquidDensity = 1 +LiquidKinematicViscosity = 1 + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-15 + +[Vtk] +WriteFaceData = false + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +# This test does actually not require setting the primary variable magnitues. +# This rather serves as a demonstration of how to use the feature. +[CellCenter.Assembly] +NumericDifference.PriVarMagnitude = 1e5 # pressure is in the order of 1e5 + +[Face.Assembly] +NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 + +[Adaptivity] +Conservation = true +Adapt = true +LeftX = 4 +RightX = 6 +LowerY = .4 +UpperY = .6 + + +[Adaptive] +RefineAtDirichletBC = 0 +RefineAtFluxBC = 1 +MinLevel = 0 +MaxLevel = 0 +CoarsenTolerance = 1e-4 +RefineTolerance = 2e-1 diff --git a/appl/freeflow/navierstokes/channel_copy/2d/params_uniform.input b/appl/freeflow/navierstokes/channel_copy/2d/params_uniform.input new file mode 100644 index 0000000..978b64b --- /dev/null +++ b/appl/freeflow/navierstokes/channel_copy/2d/params_uniform.input @@ -0,0 +1,57 @@ +[TimeLoop] +DtInitial = 1 # [s] +TEnd = 2 # [s] + +[Helper.Grid] +UpperRight = 10 1 +Cells = 100 50 +Positions0 = 0 10 +Positions1 = 0 1 +Cells0 = 20 +Cells1 = 20 +Grading0 = 1 +Grading1 = 1 + +[Grid] +File = grid.dgf + +[Problem] +Name = uniform # name passed to the output routines +InletVelocity = 1 +EnableGravity = false +EnableInertiaTerms = false +OutletCondition = Outflow +UseVelocityProfile = true +PrintErrors = true +IsStationary = true + +[Component] +MolarMass = 1.0 +LiquidDensity = 1.0 +LiquidKinematicViscosity = 1.0 + +[ Newton ] +MaxSteps = 10 +MaxRelativeShift = 1e-8 + +[FreeFlow] +EnableVelocityGradientFactor = false + +[Vtk] +WriteFaceData = false +Precision = Float64 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-3 + +# This test does actually not require setting the primary variable magnitues. +# This rather serves as a demonstration of how to use the feature. +# [CellCenter.Assembly] +# NumericDifference.PriVarMagnitude = 1e5 # pressure is in the order of 1e5 + +[Face.Assembly] +# NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 + +[Adaptivity] +Conservation = false +Adapt = false diff --git a/appl/freeflow/navierstokes/channel_copy/2d/problem.hh b/appl/freeflow/navierstokes/channel_copy/2d/problem.hh new file mode 100644 index 0000000..726b595 --- /dev/null +++ b/appl/freeflow/navierstokes/channel_copy/2d/problem.hh @@ -0,0 +1,588 @@ +// -*- 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 + * \ingroup NavierStokesTests + * \brief Channel flow test for the staggered grid (Navier-)Stokes model + */ +#ifndef DUMUX_CHANNEL_TEST_PROBLEM_HH +#define DUMUX_CHANNEL_TEST_PROBLEM_HH + +#include <dune/alugrid/grid.hh> +#include <dune/grid/yaspgrid.hh> +#include <dune/subgrid/subgrid.hh> + +#include <dumux/assembly/cvdstaggeredrefinedlocalresidual.hh> + +#include <dumux/common/numeqvector.hh> + +#include <dumux/material/fluidsystems/1pliquid.hh> +#include <dumux/material/components/simpleh2o.hh> +#include <dumux/material/components/constant.hh> + +#include <dumux/freeflow/navierstokes/boundarytypes.hh> +#include <dumux/freeflow/navierstokes/cvdproblem.hh> +#include <dumux/freeflow/navierstokes/model.hh> +#include <dumux/freeflow/navierstokes/cvdlocalresidual.hh> +#include <dumux/freeflow/navierstokes/cvdfluxvariableswrapper.hh> +#include <dumux/freeflow/navierstokes/myvolumevariables.hh> +#include <dumux/freeflow/navierstokes/myiofields.hh> + +#include <dumux/discretization/staggered/freeflow/properties.hh> +#include <dumux/discretization/staggered/freeflow/myfacevariables.hh> +#include <dumux/discretization/staggered/freeflow/cvdlocalfacevariables.hh> +#include <dumux/discretization/staggered/cvdlocalgridfacevariables.hh> +#include <dumux/discretization/staggered/freeflow/myvelocityoutput.hh> +#include <dumux/discretization/staggered/freeflow/mygridvolumevariables.hh> +#include <dumux/discretization/staggered/freeflow/elementvolumevariables1.hh> +#include <dumux/discretization/staggered/mygridfluxvariablescache.hh> +#include <dumux/discretization/staggered/myfacesolution.hh> +#include <dumux/discretization/staggered/cvdelementfacesolution.hh> +#include <dumux/discretization/staggered/cvdgridvariables.hh> +#include <dumux/discretization/staggered/cvdfvgridgeometry.hh> +#include <dumux/discretization/staggered/freeflow/cvdfvgridgeometrytraits.hh> + +namespace Dumux +{ +template <class TypeTag> +class ChannelTestProblem; + +namespace Properties +{ +namespace TTag { +#if !NONISOTHERMAL +// Create new type tags +struct ChannelTestTypeTag { using InheritsFrom = std::tuple<NavierStokes, StaggeredFreeFlowModel>; }; +} // end namespace TTag +#else +struct ChannelTestTypeTag { using InheritsFrom = std::tuple<NavierStokesNI, StaggeredFreeFlowModel>; }; +} // end namespace TTag +#endif + +// the fluid system +template<class TypeTag> +struct FluidSystem<TypeTag, TTag::ChannelTestTypeTag> +{ + using Scalar = GetPropType<TypeTag, Properties::Scalar>; +#if NONISOTHERMAL + using type = FluidSystems::OnePLiquid<Scalar, Components::SimpleH2O<Scalar> >; +#else + using type = FluidSystems::OnePLiquid<Scalar, Components::Constant<1, Scalar> >; +#endif +}; + +// Set the grid type +template<class TypeTag> +struct Grid<TypeTag, TTag::ChannelTestTypeTag> +{ + using HostGrid = Dune::ALUGrid<2,2,Dune::cube,Dune::nonconforming >; + using type = Dune::SubGrid<HostGrid::dimension, HostGrid>; +}; + +template<class TypeTag, class MyTypeTag> +struct HelpingGrid { using type = UndefinedProperty; }; + +// Set the grid type +template<class TypeTag> +struct HelpingGrid<TypeTag, TTag::ChannelTestTypeTag> +{ + using type = Dune::YaspGrid<2,Dune::TensorProductCoordinates<double, 2>>; +}; + +// Set the problem property +template<class TypeTag> +struct Problem<TypeTag, TTag::ChannelTestTypeTag> { using type = Dumux::ChannelTestProblem<TypeTag> ; }; + +template<class TypeTag> +struct EnableGridGeometryCache<TypeTag, TTag::ChannelTestTypeTag> { static constexpr bool value = true; }; + +template<class TypeTag> +struct EnableGridFluxVariablesCache<TypeTag, TTag::ChannelTestTypeTag> { static constexpr bool value = true; }; +template<class TypeTag> +struct EnableGridVolumeVariablesCache<TypeTag, TTag::ChannelTestTypeTag> { static constexpr bool value = true; }; + +//! The variables living on the faces +template<class TypeTag> +struct FaceVariables<TypeTag, TTag::ChannelTestTypeTag> +{ +private: + using FacePrimaryVariables = GetPropType<TypeTag, Properties::FacePrimaryVariables>; + using GridView = typename GetPropType<TypeTag, Properties::GridGeometry>::GridView; + static constexpr auto upwindSchemeOrder = getPropValue<TypeTag, Properties::UpwindSchemeOrder>(); + using ModelTraits = GetPropType<TypeTag, Properties::ModelTraits>; +public: + using type = MyStaggeredFaceVariables<ModelTraits, FacePrimaryVariables, GridView::dimension, upwindSchemeOrder>; +}; + +template<class TypeTag> +struct LocalFaceVariables<TypeTag, TTag::ChannelTestTypeTag> +{ +private: + using FacePrimaryVariables = GetPropType<TypeTag, Properties::FacePrimaryVariables>; +public: + using type = CVDStaggeredLocalFaceVariables<FacePrimaryVariables>; +}; + +//! The velocity output +template<class TypeTag> +struct VelocityOutput<TypeTag, TTag::ChannelTestTypeTag> +{ + using type = MyStaggeredFreeFlowVelocityOutput<GetPropType<TypeTag, Properties::GridVariables>, + GetPropType<TypeTag, Properties::SolutionVector>>; +}; + +//! Set the volume variables property +template<class TypeTag> +struct DualCVsVolVars<TypeTag, TTag::ChannelTestTypeTag> +{ +private: + using VV = GetPropType<TypeTag, Properties::VolumeVariables>; + using GridView = typename GetPropType<TypeTag, Properties::GridGeometry>::GridView; + static constexpr auto dimWorld = GridView::dimensionworld; + static constexpr int numPairs = 2 * (dimWorld - 1); + +public: + using type = NavierStokesDualCVsVolVars<VV, numPairs>; +}; + +//! Set the volume variables property +template<class TypeTag> +struct PrimalCVsVolVars<TypeTag, TTag::ChannelTestTypeTag> +{ +public: + using VolumeVariables = GetPropType<TypeTag, Properties::VolumeVariables>; + using type = std::array<NaviesStokesPrimalScvfPair<VolumeVariables>,8>;//TODO make work for dim != 2 +}; + +//! Set the default global volume variables cache vector class +template<class TypeTag> +struct GridVolumeVariables<TypeTag, TTag::ChannelTestTypeTag> +{ +private: + using Problem = GetPropType<TypeTag, Properties::Problem>; + using VolumeVariables = GetPropType<TypeTag, Properties::VolumeVariables>; + using DualCVsVolVars = GetPropType<TypeTag, Properties::DualCVsVolVars>; + using PrimalCVsVolVars = GetPropType<TypeTag, Properties::PrimalCVsVolVars>; + using GridView = typename GetPropType<TypeTag, Properties::GridGeometry>::GridView; + using SubControlVolume = typename GetPropType<TypeTag, Properties::GridGeometry>::SubControlVolume; + using SubControlVolumeFace = typename GetPropType<TypeTag, Properties::GridGeometry>::SubControlVolumeFace; + static constexpr auto enableCache = getPropValue<TypeTag, Properties::EnableGridVolumeVariablesCache>(); + using Traits = MyStaggeredGridDefaultGridVolumeVariablesTraits<Problem, PrimalCVsVolVars, DualCVsVolVars, VolumeVariables, GridView, SubControlVolume, SubControlVolumeFace>; +public: + using type = MyStaggeredGridVolumeVariables<Traits, enableCache>; +}; + +//! Set the BaseLocalResidual to StaggeredLocalResidual +template<class TypeTag> +struct BaseLocalResidual<TypeTag, TTag::ChannelTestTypeTag> { using type = StaggeredRefinedLocalResidual<TypeTag>; }; + +//! Set the face solution type +template<class TypeTag> +struct StaggeredFaceSolution<TypeTag, TTag::ChannelTestTypeTag> +{ +private: + using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; +public: + using type = Dumux::MyStaggeredFaceSolution<FaceSolutionVector>; +}; + +template<class TypeTag> +struct ElementFaceSolution<TypeTag, TTag::ChannelTestTypeTag> +{ +private: + using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; +public: + using type = Dumux::CVDElementFaceSolution<FaceSolutionVector>; +}; + +//! Set the GridLocalFaceVariables +template<class TypeTag> +struct GridLocalFaceVariables<TypeTag, TTag::ChannelTestTypeTag> +{ + private: + using Problem = GetPropType<TypeTag, Properties::Problem>; + using LocalFaceVariables = GetPropType<TypeTag, Properties::LocalFaceVariables>; + static constexpr auto enableCache = getPropValue<TypeTag, Properties::EnableGridFaceVariablesCache>(); + public: + using type = CVDStaggeredLocalGridFaceVariables<Problem, LocalFaceVariables, enableCache>; +}; + +//! Set the grid variables (volume, flux and face variables) +template<class TypeTag> +struct GridVariables<TypeTag, TTag::ChannelTestTypeTag> +{ +private: + using GG = GetPropType<TypeTag, Properties::GridGeometry>; + using GVV = GetPropType<TypeTag, Properties::GridVolumeVariables>; + using GFVC = GetPropType<TypeTag, Properties::GridFluxVariablesCache>; + using GFV = GetPropType<TypeTag, Properties::GridFaceVariables>; + using GLFV = GetPropType<TypeTag, Properties::GridLocalFaceVariables>; +public: + using type = CVDStaggeredGridVariables<GG, GVV, GFVC, GFV, GLFV>; +}; + +//! The default fv grid geometry +template<class TypeTag> +struct GridGeometry<TypeTag, TTag::ChannelTestTypeTag> +{ +private: + static constexpr auto upwindSchemeOrder = getPropValue<TypeTag, Properties::UpwindSchemeOrder>(); + static constexpr bool enableCache = getPropValue<TypeTag, Properties::EnableGridGeometryCache>(); + using GridView = typename GetPropType<TypeTag, Properties::Grid>::LeafGridView; + using Traits = CVDStaggeredFreeFlowDefaultGridGeometryTraits<GridView, upwindSchemeOrder>; +public: + using type = CVDStaggeredGridGeometry<GridView, enableCache, Traits>; +}; + +template<class TypeTag> +struct CVGridGeometry<TypeTag, TTag::ChannelTestTypeTag> +{ +private: + static constexpr auto upwindSchemeOrder = getPropValue<TypeTag, Properties::UpwindSchemeOrder>(); + static constexpr bool enableCache = getPropValue<TypeTag, Properties::EnableGridGeometryCache>(); + using GridView = typename Dune::ALUGrid<2,2,Dune::cube,Dune::nonconforming >::LeafGridView; + using Traits = CVDStaggeredFreeFlowDefaultGridGeometryTraits<GridView, upwindSchemeOrder>; +public: + using type = CVDStaggeredGridGeometry<GridView, enableCache, Traits>; +}; + +//! Set the volume variables property +template<class TypeTag> +struct VolumeVariables<TypeTag, TTag::ChannelTestTypeTag> +{ +private: + using PV = GetPropType<TypeTag, Properties::PrimaryVariables>; + using FSY = GetPropType<TypeTag, Properties::FluidSystem>; + using FST = GetPropType<TypeTag, Properties::FluidState>; + using MT = GetPropType<TypeTag, Properties::ModelTraits>; + + static_assert(FSY::numPhases == MT::numFluidPhases(), "Number of phases mismatch between model and fluid system"); + static_assert(FST::numPhases == MT::numFluidPhases(), "Number of phases mismatch between model and fluid state"); + static_assert(!FSY::isMiscible(), "The Navier-Stokes model only works with immiscible fluid systems."); + + using Traits = NavierStokesVolumeVariablesTraits<PV, FSY, FST, MT>; +public: + using type = MyNavierStokesVolumeVariables<Traits>; +}; + +//! The local residual +template<class TypeTag> +struct LocalResidual<TypeTag, TTag::ChannelTestTypeTag> { using type = RefinedNavierStokesResidual<TypeTag>; }; + +//! The flux variables +template<class TypeTag> +struct FluxVariables<TypeTag, TTag::ChannelTestTypeTag> { using type = RefinedNavierStokesFluxVariables<TypeTag>; }; + +//! The specific I/O fields +template<class TypeTag> +struct IOFields<TypeTag, TTag::ChannelTestTypeTag> { +#if NONISOTHERMAL + using type = FreeflowNonIsothermalIOFields<MyNavierStokesIOFields>; +#else + using type = MyNavierStokesIOFields; +#endif +}; + +//! Set the global flux variables cache vector class +template<class TypeTag> +struct GridFluxVariablesCache<TypeTag, TTag::ChannelTestTypeTag> +{ +private: + using Problem = GetPropType<TypeTag, Properties::Problem>; + using FluxVariablesCache = GetPropType<TypeTag, Properties::FluxVariablesCache>; + using FluxVariablesCacheFiller = GetPropType<TypeTag, Properties::FluxVariablesCacheFiller>; + static constexpr auto enableCache = getPropValue<TypeTag, Properties::EnableGridFluxVariablesCache>(); + static constexpr auto upwindSchemeOrder = getPropValue<TypeTag, Properties::UpwindSchemeOrder>(); +public: + using type = MyStaggeredGridFluxVariablesCache<Problem, FluxVariablesCache, FluxVariablesCacheFiller, enableCache, upwindSchemeOrder>; +}; +} + +/*! + * \ingroup NavierStokesTests + * \brief Test problem for the one-phase (Navier-) Stokes problem in a channel. + * \todo doc me! + */ +template <class TypeTag> +class ChannelTestProblem : public MyNavierStokesProblem<TypeTag> +{ + using ParentType = MyNavierStokesProblem<TypeTag>; + + using BoundaryTypes = Dumux::NavierStokesBoundaryTypes<GetPropType<TypeTag, Properties::ModelTraits>::numEq()>; + using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; + using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; + using ModelTraits = GetPropType<TypeTag, Properties::ModelTraits>; + using NumEqVector = Dumux::NumEqVector<GetPropType<TypeTag, Properties::PrimaryVariables>>; + using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>; + using Scalar = GetPropType<TypeTag, Properties::Scalar>; + using SolutionVector = GetPropType<TypeTag, Properties::SolutionVector>; + using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; + using FVElementGeometry = typename GridGeometry::LocalView; + using SubControlVolume = typename GridGeometry::SubControlVolume; + using SubControlVolumeFace = typename GetPropType<TypeTag, Properties::GridGeometry>::SubControlVolumeFace; + + static constexpr auto dimWorld = GetPropType<TypeTag, Properties::GridGeometry>::GridView::dimensionworld; + + using Element = typename GridGeometry::GridView::template Codim<0>::Entity; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + using VelocityVector = Dune::FieldVector<Scalar, dimWorld>; + + using TimeLoopPtr = std::shared_ptr<CheckPointTimeLoop<Scalar>>; + +public: + ChannelTestProblem(std::shared_ptr<const GridGeometry> gridGeometry) + : ParentType(gridGeometry), eps_(1e-6) + { + dynamicViscosity_ = getParam<Scalar>("Component.LiquidKinematicViscosity", 1.0) * getParam<Scalar>("Component.LiquidDensity", 1.0); + inletVelocity_ = getParam<Scalar>("Problem.InletVelocity"); + + const Scalar xMin = this->gridGeometry().bBoxMin()[0]; + const Scalar xMax = this->gridGeometry().bBoxMax()[0]; + const Scalar yMin = this->gridGeometry().bBoxMin()[1]; + const Scalar yMax = this->gridGeometry().bBoxMax()[1]; + + velocityQuadraticCoefficient_ = - inletVelocity_ / (0.25*(yMax - yMin)*(yMax - yMin)); + velocityLinearCoefficient_ = velocityQuadraticCoefficient_ * (-yMax - yMin); + velocityConstant_ = velocityQuadraticCoefficient_ * yMin * yMax; + pressureLinearCoefficient_ = 2. * velocityQuadraticCoefficient_ * dynamicViscosity_; + pressureConstant_ = -pressureLinearCoefficient_ *.5 * (xMax - xMin); + } + + /*! + * \name Problem parameters + */ + // \{ + + + bool shouldWriteRestartFile() const + { + return false; + } + + /*! + * \brief Return the temperature within the domain in [K]. + * + * This problem assumes a temperature of 10 degrees Celsius. + */ + Scalar temperature() const + { return 273.15 + 10; } // 10C + + /*! + * \brief Return the sources within the domain. + * + * \param globalPos The global position + */ + NumEqVector sourceAtPos(const GlobalPosition &globalPos) const + { + return NumEqVector(0.0); + } + // \} + /*! + * \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 values; + + values.setDirichlet(Indices::velocityXIdx); + values.setDirichlet(Indices::velocityYIdx); + + return values; + } + + bool isDirichletCell(const Element& element, + const FVElementGeometry& fvGeometry, + const SubControlVolume& scv, + int pvIdx) const + { + // set fixed pressure in one cell + return (scv.dofIndex() == 0) && pvIdx == Indices::pressureIdx; + } + + /*! + * \brief Evaluate the boundary conditions for a dirichlet + * control volume face (velocities) + * + * \param element The finite element + * \param scvf the sub control volume face + * + * Concerning the usage of averaged velocity, see the explanation of the initial function. The average of the nondirection velocity along an scvf is required in the context of dirichlet boundary conditions for the functions getParallelVelocityFromBoundary_ and getParallelVelocityFromOtherBoundary_ within myfluxvariables.hh. There dirichlet is called for ghost faces built from the normalFace but the value then is taken in the the direction scvf.directionIndex, which is along that normalFace. + */ + PrimaryVariables dirichlet(const Element& element, const SubControlVolumeFace& scvf) const + { + PrimaryVariables priVars(0.0); + + unsigned int dirIdx = scvf.directionIndex(); + priVars[Indices::velocity(dirIdx)] = this->analyticalVelocitySolutionAtPos(scvf); + unsigned int nonDirIdx = (dirIdx == 0)?1:0; + priVars[Indices::velocity(nonDirIdx)] = this->analyticalNonDirVelocitySolutionAtPos(scvf); + + return priVars; + } + + /*! + * \brief Evaluate the boundary conditions for a dirichlet + * control volume face (pressure) + * + * \param element The finite element + * \param scv the sub control volume + */ + PrimaryVariables dirichlet(const Element& element, const SubControlVolume& scv) const + { + PrimaryVariables priVars(0.0); + priVars[Indices::pressureIdx] = this->analyticalPressureSolutionAtPos(scv); + return priVars; + } + + /*! + * \brief Return the analytical solution of the problem at a given position + * + * \param globalPos The global position + */ + PrimaryVariables analyticalSolutionAtPos(const GlobalPosition& globalPos) const + { + PrimaryVariables values; + + Scalar x = globalPos[0]; + Scalar y = globalPos[1]; + + values[Indices::pressureIdx] = f1_(x); + values[Indices::velocityXIdx] = f2_(y); + values[Indices::velocityYIdx] = 0.; + + return values; + } + + /*! + * \name Volume terms + */ + // \{ + + /*! + * \brief Evaluates the initial value for a sub control volume face (velocities) + * + * Simply assigning the value of the analytical solution at the face center + * gives a discrete solution that is not divergence-free. For small initial + * time steps, this has a negative impact on the pressure solution + * after the first time step. The flag UseVelocityAveraging triggers the + * function averagedVelocity_ which uses a higher order quadrature formula to + * bring the discrete solution sufficiently close to being divergence-free. + */ + PrimaryVariables initial(const SubControlVolumeFace& scvf) const + { + bool startWithAnalytical = getParam<bool>("Problem.StartWithAnalytical", false); + + if (startWithAnalytical) + { + PrimaryVariables priVars(0.0); + priVars[Indices::velocity(scvf.directionIndex())] = this->analyticalVelocitySolutionAtPos(scvf); + return priVars; + } + else + { + PrimaryVariables values; + values[Indices::pressureIdx] = 0.0; + values[Indices::velocityXIdx] = 0.0; + values[Indices::velocityYIdx] = 0.0; + + return values; + } + } + + /*! + * \brief Evaluates the initial value for a control volume (pressure) + */ + PrimaryVariables initial(const SubControlVolume& scv) const + { + bool startWithAnalytical = getParam<bool>("Problem.StartWithAnalytical", false); + + if (startWithAnalytical) + { + PrimaryVariables priVars(0.0); + priVars[Indices::pressureIdx] = this->analyticalPressureSolutionAtPos(scv); + return priVars; + } + else + { + PrimaryVariables values; + values[Indices::pressureIdx] = 0.0; + values[Indices::velocityXIdx] = 0.0; + values[Indices::velocityYIdx] = 0.0; + + return values; + } + } + + // \} + void setTimeLoop(TimeLoopPtr timeLoop) + { + timeLoop_ = timeLoop; + if(inletVelocity_ > eps_) + timeLoop_->setCheckPoint({200.0, 210.0}); + } + + Scalar time() const + { + return timeLoop_->time(); + } + +private: + bool isInlet(const GlobalPosition& globalPos) const + { + return globalPos[0] < eps_; + } + + bool isOutlet(const GlobalPosition& globalPos) const + { + return globalPos[0] > this->gridGeometry().bBoxMax()[0] - eps_; + } + + bool isWall(const GlobalPosition& globalPos) const + { + return globalPos[0] > eps_ || globalPos[0] < this->gridGeometry().bBoxMax()[0] - eps_; + } + + Scalar f1_(Scalar x) const + { return pressureLinearCoefficient_ * x + pressureConstant_; } + + Scalar f2_(Scalar y) const + { return velocityQuadraticCoefficient_ * y * y + velocityLinearCoefficient_ * y + velocityConstant_; } + + Scalar eps_; + Scalar dynamicViscosity_; + Scalar inletVelocity_; + TimeLoopPtr timeLoop_; + + Scalar velocityQuadraticCoefficient_; + Scalar velocityLinearCoefficient_; + Scalar velocityConstant_; + Scalar pressureLinearCoefficient_; + Scalar pressureConstant_; +}; +} //end namespace + +#endif diff --git a/appl/freeflow/navierstokes/channel_copy/CMakeLists.txt b/appl/freeflow/navierstokes/channel_copy/CMakeLists.txt new file mode 100644 index 0000000..5c4cec9 --- /dev/null +++ b/appl/freeflow/navierstokes/channel_copy/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(2d) -- GitLab From 337242536cab1f7fff6e484faf50a0d1a212a32e Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Tue, 14 Sep 2021 12:23:25 +0300 Subject: [PATCH 27/69] [channel] channel_copy instead of channel --- appl/freeflow/navierstokes/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appl/freeflow/navierstokes/CMakeLists.txt b/appl/freeflow/navierstokes/CMakeLists.txt index 718c8c5..d6d5dc3 100644 --- a/appl/freeflow/navierstokes/CMakeLists.txt +++ b/appl/freeflow/navierstokes/CMakeLists.txt @@ -1,4 +1,4 @@ add_subdirectory(donea) -add_subdirectory(channel) +add_subdirectory(channel_copy) add_subdirectory(sincos) add_subdirectory(angeli) -- GitLab From f09d734e86bd4d390b7328b9fbfb51969fb79288 Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Tue, 14 Sep 2021 13:08:24 +0300 Subject: [PATCH 28/69] Fix for coordinate cmp --- dumux/io/grid/cvdcontrolvolumegrids.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dumux/io/grid/cvdcontrolvolumegrids.hh b/dumux/io/grid/cvdcontrolvolumegrids.hh index e7294ad..d77cc40 100644 --- a/dumux/io/grid/cvdcontrolvolumegrids.hh +++ b/dumux/io/grid/cvdcontrolvolumegrids.hh @@ -34,7 +34,7 @@ template<class GlobalPosition> struct ContainerCmpClass { bool operator() (const GlobalPosition& lhs, const GlobalPosition& rhs) const { - double epsilon = 1e-6; + double epsilon = 1e-5; auto scalarLess = [&] (double left, double right) { return (std::abs(left - right) > epsilon) && (left < right); }; -- GitLab From 3697d00a9e1e1b5cb030e45f1214e676cfd4d27c Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Tue, 14 Sep 2021 13:08:54 +0300 Subject: [PATCH 29/69] [channel] params changes --- appl/freeflow/navierstokes/channel_copy/2d/main.cc | 10 +++++----- .../navierstokes/channel_copy/2d/params_stokes.input | 4 +++- .../channel_copy/2d/params_stokes_stationary.input | 2 ++ 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/appl/freeflow/navierstokes/channel_copy/2d/main.cc b/appl/freeflow/navierstokes/channel_copy/2d/main.cc index a6cd218..c1d0996 100644 --- a/appl/freeflow/navierstokes/channel_copy/2d/main.cc +++ b/appl/freeflow/navierstokes/channel_copy/2d/main.cc @@ -528,8 +528,8 @@ 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; -// } +catch (...) +{ + std::cerr << "Unknown exception thrown! ---> Abort!" << std::endl; + return 4; +} diff --git a/appl/freeflow/navierstokes/channel_copy/2d/params_stokes.input b/appl/freeflow/navierstokes/channel_copy/2d/params_stokes.input index 9101022..9197ce7 100644 --- a/appl/freeflow/navierstokes/channel_copy/2d/params_stokes.input +++ b/appl/freeflow/navierstokes/channel_copy/2d/params_stokes.input @@ -41,6 +41,8 @@ LiquidKinematicViscosity = 1 [ Newton ] MaxSteps = 100 MaxRelativeShift = 1e-8 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true [Vtk] WriteFaceData = false @@ -57,7 +59,7 @@ NumericDifference.PriVarMagnitude = 1e5 # pressure is in the order of 1e5 NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 [Adaptivity] -Conservation = true +Conservation = false Adapt = true LeftX = 3 RightX = 5 diff --git a/appl/freeflow/navierstokes/channel_copy/2d/params_stokes_stationary.input b/appl/freeflow/navierstokes/channel_copy/2d/params_stokes_stationary.input index de8baa2..09ef667 100644 --- a/appl/freeflow/navierstokes/channel_copy/2d/params_stokes_stationary.input +++ b/appl/freeflow/navierstokes/channel_copy/2d/params_stokes_stationary.input @@ -37,6 +37,8 @@ LiquidKinematicViscosity = 1 [ Newton ] MaxSteps = 100 MaxRelativeShift = 1e-15 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true [Vtk] WriteFaceData = false -- GitLab From 930c8e91b79b0e037df2e5aae5ff49f18ef196e4 Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Tue, 14 Sep 2021 14:11:53 +0300 Subject: [PATCH 30/69] [warning elimination] numeqvector warning --- appl/freeflow/navierstokes/donea/main.cc | 4 ---- dumux/multidomain/cvdsubdomainstaggeredlocalassembler.hh | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/appl/freeflow/navierstokes/donea/main.cc b/appl/freeflow/navierstokes/donea/main.cc index 2aaa047..fa0b419 100644 --- a/appl/freeflow/navierstokes/donea/main.cc +++ b/appl/freeflow/navierstokes/donea/main.cc @@ -21,9 +21,6 @@ * * \brief Test for the staggered grid Navier-Stokes model (Kovasznay 1947) */ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#pragma GCC diagnostic ignored "-Wdeprecated-copy" bool doFirstOrderLocalTruncErrorGlobalRefinement = false; @@ -322,4 +319,3 @@ catch (...) std::cerr << "Unknown exception thrown! ---> Abort!" << std::endl; return 4; } -#pragma GCC diagnostic pop diff --git a/dumux/multidomain/cvdsubdomainstaggeredlocalassembler.hh b/dumux/multidomain/cvdsubdomainstaggeredlocalassembler.hh index 6c78c43..23d576b 100644 --- a/dumux/multidomain/cvdsubdomainstaggeredlocalassembler.hh +++ b/dumux/multidomain/cvdsubdomainstaggeredlocalassembler.hh @@ -69,7 +69,7 @@ class CVDSubDomainStaggeredLocalAssemblerBase : public FVLocalAssemblerBase<Type using ParentType = FVLocalAssemblerBase<TypeTag, Assembler,Implementation, isImplicit>; using Problem = GetPropType<TypeTag, Properties::Problem>; - using LocalResidualValues = GetPropType<TypeTag, Properties::NumEqVector>; + // using LocalResidualValues = GetPropType<TypeTag, Properties::NumEqVector>; using LocalResidual = GetPropType<TypeTag, Properties::LocalResidual>; using ElementResidualVector = typename LocalResidual::ElementResidualVector; using JacobianMatrix = GetPropType<TypeTag, Properties::JacobianMatrix>; -- GitLab From 3a5ef027090968c409e475900ff71e7667e2dff0 Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Tue, 14 Sep 2021 14:28:32 +0300 Subject: [PATCH 31/69] [channel] Rename channel_copy to channel --- appl/freeflow/navierstokes/CMakeLists.txt | 2 +- .../navierstokes/channel/2d/CMakeLists.txt | 4 +- appl/freeflow/navierstokes/channel/2d/main.cc | 115 ++-- .../channel/2d/params_conduction.input | 3 +- .../channel/2d/params_convection.input | 3 +- .../channel/2d/params_graded.input | 2 +- .../2d/params_grading_add_dof_good.input | 2 +- .../channel/2d/params_navierstokes.input | 22 +- .../2d/params_navierstokes_stationary.input | 10 +- .../channel/2d/params_stokes.input | 7 +- .../channel/2d/params_stokes_stationary.input | 5 +- .../params_stokes_stationary_fvcaGrid.input | 4 +- .../channel/2d/params_uniform.input | 2 +- .../navierstokes/channel/2d/problem.hh | 322 +++------- .../navierstokes/channel/channell2error.hh | 206 ------ .../channel_copy/2d/CMakeLists.txt | 64 -- .../navierstokes/channel_copy/2d/main.cc | 535 ---------------- .../channel_copy/2d/params_conduction.input | 50 -- .../channel_copy/2d/params_convection.input | 50 -- .../channel_copy/2d/params_graded.input | 69 -- .../2d/params_grading_add_dof_good.input | 57 -- .../channel_copy/2d/params_navierstokes.input | 43 -- .../2d/params_navierstokes_stationary.input | 72 --- .../channel_copy/2d/params_stokes.input | 67 -- .../2d/params_stokes_stationary.input | 72 --- .../params_stokes_stationary_fvcaGrid.input | 71 --- .../channel_copy/2d/params_uniform.input | 57 -- .../navierstokes/channel_copy/2d/problem.hh | 588 ------------------ .../navierstokes/channel_copy/CMakeLists.txt | 1 - 29 files changed, 169 insertions(+), 2336 deletions(-) delete mode 100644 appl/freeflow/navierstokes/channel/channell2error.hh delete mode 100644 appl/freeflow/navierstokes/channel_copy/2d/CMakeLists.txt delete mode 100644 appl/freeflow/navierstokes/channel_copy/2d/main.cc delete mode 100644 appl/freeflow/navierstokes/channel_copy/2d/params_conduction.input delete mode 100644 appl/freeflow/navierstokes/channel_copy/2d/params_convection.input delete mode 100644 appl/freeflow/navierstokes/channel_copy/2d/params_graded.input delete mode 100644 appl/freeflow/navierstokes/channel_copy/2d/params_grading_add_dof_good.input delete mode 100644 appl/freeflow/navierstokes/channel_copy/2d/params_navierstokes.input delete mode 100644 appl/freeflow/navierstokes/channel_copy/2d/params_navierstokes_stationary.input delete mode 100644 appl/freeflow/navierstokes/channel_copy/2d/params_stokes.input delete mode 100644 appl/freeflow/navierstokes/channel_copy/2d/params_stokes_stationary.input delete mode 100644 appl/freeflow/navierstokes/channel_copy/2d/params_stokes_stationary_fvcaGrid.input delete mode 100644 appl/freeflow/navierstokes/channel_copy/2d/params_uniform.input delete mode 100644 appl/freeflow/navierstokes/channel_copy/2d/problem.hh delete mode 100644 appl/freeflow/navierstokes/channel_copy/CMakeLists.txt diff --git a/appl/freeflow/navierstokes/CMakeLists.txt b/appl/freeflow/navierstokes/CMakeLists.txt index d6d5dc3..718c8c5 100644 --- a/appl/freeflow/navierstokes/CMakeLists.txt +++ b/appl/freeflow/navierstokes/CMakeLists.txt @@ -1,4 +1,4 @@ add_subdirectory(donea) -add_subdirectory(channel_copy) +add_subdirectory(channel) add_subdirectory(sincos) add_subdirectory(angeli) diff --git a/appl/freeflow/navierstokes/channel/2d/CMakeLists.txt b/appl/freeflow/navierstokes/channel/2d/CMakeLists.txt index 532ef02..a4c7227 100644 --- a/appl/freeflow/navierstokes/channel/2d/CMakeLists.txt +++ b/appl/freeflow/navierstokes/channel/2d/CMakeLists.txt @@ -1,7 +1,7 @@ -set(CMAKE_BUILD_TYPE Debug) - add_input_file_links() +set(CMAKE_BUILD_TYPE Debug) + add_executable(test_ff_channel EXCLUDE_FROM_ALL main.cc) dune_add_test(NAME test_ff_stokes_channel diff --git a/appl/freeflow/navierstokes/channel/2d/main.cc b/appl/freeflow/navierstokes/channel/2d/main.cc index 6db0ba6..c1d0996 100644 --- a/appl/freeflow/navierstokes/channel/2d/main.cc +++ b/appl/freeflow/navierstokes/channel/2d/main.cc @@ -21,9 +21,8 @@ * * \brief Channel flow test for the staggered grid (Navier-)Stokes model */ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#pragma GCC diagnostic ignored "-Wdeprecated-copy" + +bool doFirstOrderLocalTruncErrorGlobalRefinement = false; #include <config.h> @@ -66,6 +65,7 @@ #include <dumux/discretization/staggered/freeflow/cvdfvgridgeometrytraits.hh> #include <dumux/freeflow/navierstokes/staggered/cvdresidualCalc.hh> +#include <dumux/io/cvdoutputFacility.hh> #include "problem.hh" @@ -86,6 +86,11 @@ int main(int argc, char** argv) try // parse command line arguments and input file Parameters::init(argc, argv); + bool doFirstOrderLocalTruncError = getParam<bool>("Numerics.DoFirstOrderLocalTruncError", false); + bool adapt = getParam<bool>("Adaptivity.Adapt", false); + //when adapt is true refinement is local, not only global + doFirstOrderLocalTruncErrorGlobalRefinement = !adapt && doFirstOrderLocalTruncError; + using HelpingGridManager = Dumux::GridManager<GetPropType<TypeTag, Properties::HelpingGrid>>; HelpingGridManager helpingGridManager; helpingGridManager.init("Helper"); @@ -106,7 +111,6 @@ int main(int argc, char** argv) try const auto& leafGridViewVar = hostGrid.leafGridView(); bool roughChannel = getParam<bool>("Adaptivity.RoughChannel", false); - bool adapt = getParam<bool>("Adaptivity.Adapt", false); using Scalar = GetPropType<TypeTag, Properties::Scalar>; bool FVCAgrid = getParam<bool>("Grid.FVCAGrid", false); @@ -276,7 +280,6 @@ int main(int argc, char** argv) try // create the finite volume grid geometry using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; auto gridGeometry = std::make_shared<GridGeometry>(leafGridView); - gridGeometry->update(); // the problem (initial and boundary conditions) using Problem = GetPropType<TypeTag, Properties::Problem>; @@ -328,6 +331,11 @@ int main(int argc, char** argv) try } vtkWriter.write(0.0); + using CellCenterSolutionVector = GetPropType<TypeTag, Properties::CellCenterSolutionVector>; + CellCenterSolutionVector numericalCCResidualWithAnalytical; + numericalCCResidualWithAnalytical.resize(numDofsCellCenter); + vtkWriter.addField(numericalCCResidualWithAnalytical, "continuityResidual"); + // the assembler with time loop for instationary problem using Assembler = CVDStaggeredRefinedFVAssembler<TypeTag, DiffMethod::numeric>; auto assembler = isStationary ? std::make_shared<Assembler>(problem, gridGeometry, gridVariables) @@ -380,73 +388,63 @@ int main(int argc, char** argv) try if (isStationary) { - // get residuals for analytical solution - nonLinearSolver.assembleLinearSystem(x); + using HostGrid = Dune::ALUGrid<2,2,Dune::cube,Dune::nonconforming >; + using HostGridManager = GridManager<HostGrid>; - // get residuals for analytical solution - nonLinearSolver.assembleLinearSystem(x); - const auto faceResidualWithAnalyticalSol = (*assembler).residual()[Dune::index_constant<0>()]; - const auto ccResidualWithAnalyticalSol = (*assembler).residual()[Dune::index_constant<1>()]; + std::array<std::string, 2> paramGroups = {"coarsexCVs", "coarseyCVs"}; //xfine... + std::array<HostGridManager, 2> cvGridManagers = {}; + std::array<std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>>,2> cvCenterScvfIndicesMaps; + CVDCVOutputFacility<TypeTag> cvOutputFacility(problem); + cvOutputFacility.iniCVGridManagers(cvGridManagers, cvCenterScvfIndicesMaps, paramGroups); + using Scalar = GetPropType<TypeTag, Properties::Scalar>; + std::vector<std::pair<unsigned int, Scalar>> pvdFileInfos; // linearize & solve Dune::Timer timer; nonLinearSolver.solve(x); - problem->printErrors(x); - // write shifted control volumes vtk output + //output + if (getParam<bool>("Problem.PrintErrors", true)) + problem->printErrors(x); + using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; - std::vector<FaceSolutionVector> outputVecs; - std::vector<std::string> outputVecNames; + FaceSolutionVector numericalFaceResidualWithAnalytical; - const FaceSolutionVector& vel = x[GridGeometry::faceIdx()]; - outputVecs.push_back(vel); - outputVecNames.push_back("velocity"); + std::optional<std::array<std::vector<Scalar>, 2>> optionalPerfectInterpolationFaceResiduals; + //TODO when reintroducing outflow BC make this empty with outflow BC + // std::array<std::vector<Scalar>, 4> perfectInterpolationFaceResiduals; + // optionalPerfectInterpolationFaceResiduals.emplace(perfectInterpolationFaceResiduals); - const FaceSolutionVector& anaVel = problem->getAnalyticalFaceSolutionVector(); - outputVecs.push_back(anaVel); - outputVecNames.push_back("analyticalVelocity"); + ResidualCalc<TypeTag> residualCalc(problem); + residualCalc.calcResidualsStationary(gridGeometry, numericalCCResidualWithAnalytical, numericalFaceResidualWithAnalytical); - FaceSolutionVector absVelocityError; - absVelocityError.resize(numDofsFace); - for (unsigned int i = 0; i < vel.size(); ++i) + bool readDofBasedValues = getParam<bool>("Problem.ReadDofBasedValues", false); + if (readDofBasedValues) { - absVelocityError[i] = std::abs(vel[i] - anaVel[i]); + CellCenterSolutionVector readInPres; + readInPres.resize(gridGeometry->numCellCenterDofs()); + ReadDofBasedResult<TypeTag> reader(problem); + reader.readDofBasedResult(readInPres, "pressure"); + vtkWriter.addField(readInPres, "readInPres"); } - outputVecs.push_back(absVelocityError); - outputVecNames.push_back("absVelocityError"); - - std::cout << "velocity residual norm = " << faceResidualWithAnalyticalSol.two_norm()/*velocity*/ << ", presssure residual norm = " << ccResidualWithAnalyticalSol.two_norm()/*pressure*/ << std::endl; - - outputCVResiduals<TypeTag>((*gridGeometry), faceResidualWithAnalyticalSol, *problem, outputVecs, outputVecNames); - - // write grid cells vtk output - auto resPres = ccResidualWithAnalyticalSol; - for (const auto& element : elements((*gridGeometry).gridView())) - resPres[(*gridGeometry).gridView().indexSet().index(element)] /= element.geometry().volume(); - vtkWriter.addField(resPres, "continuityResidual"); - -// for (const auto& element : elements(gridGeometry->gridView())) -// { -// auto fvGeometry = localView(*gridGeometry); -// fvGeometry.bindElement(element); -// for (const auto& scvf : scvfs(fvGeometry)) -// { -// std::cout << "at " << scvf.center() << " sol " << x[GridGeometry::faceIdx()][scvf.dofIndex()] << " analytical sol " << xOld[GridGeometry::faceIdx()][scvf.dofIndex()] << " diff " << x[GridGeometry::faceIdx()][scvf.dofIndex()]-xOld[GridGeometry::faceIdx()][scvf.dofIndex()] << std::endl; -// } -// } -// -// for (const auto& element : elements(gridGeometry->gridView())) -// { -// auto fvGeometry = localView(*gridGeometry); -// fvGeometry.bindElement(element); -// for (const auto& scv : scvs(fvGeometry)) -// { -// std::cout << "at " << scv.center() << " sol " << x[GridGeometry::faceIdx()][scv.dofIndex()] << " analytical sol " << xOld[GridGeometry::faceIdx()][scv.dofIndex()] << " diff " << x[GridGeometry::faceIdx()][scv.dofIndex()]-xOld[GridGeometry::faceIdx()][scv.dofIndex()] << std::endl; -// } -// } - // write vtk output vtkWriter.write(1.); + + cvOutputFacility.onCVsOutputResidualsAndPrimVars( + gridGeometry, + cvGridManagers, + cvCenterScvfIndicesMaps, + paramGroups, + x, + 0, + numericalFaceResidualWithAnalytical, + optionalPerfectInterpolationFaceResiduals, + readDofBasedValues); + + pvdFileInfos.push_back(std::make_pair(0, 0)); + cvOutputFacility.printPvdFiles(paramGroups, pvdFileInfos); + + timer.stop(); } else { @@ -535,4 +533,3 @@ catch (...) std::cerr << "Unknown exception thrown! ---> Abort!" << std::endl; return 4; } -#pragma GCC diagnostic pop \ No newline at end of file diff --git a/appl/freeflow/navierstokes/channel/2d/params_conduction.input b/appl/freeflow/navierstokes/channel/2d/params_conduction.input index 5e8e77a..e2d46c3 100644 --- a/appl/freeflow/navierstokes/channel/2d/params_conduction.input +++ b/appl/freeflow/navierstokes/channel/2d/params_conduction.input @@ -18,8 +18,7 @@ Name = test_channel_stokesni_conduction # name passed to the output routines InletVelocity = 0 EnableGravity = false EnableInertiaTerms = false -PrintL2Error = false -PrintLInfinityError = false +PrintErrors = true IsStationary = false [Component] diff --git a/appl/freeflow/navierstokes/channel/2d/params_convection.input b/appl/freeflow/navierstokes/channel/2d/params_convection.input index 7e81730..aeacc54 100644 --- a/appl/freeflow/navierstokes/channel/2d/params_convection.input +++ b/appl/freeflow/navierstokes/channel/2d/params_convection.input @@ -18,8 +18,7 @@ Name = test_channel_stokesni_convection # name passed to the output routines InletVelocity = 1e-2 EnableGravity = false EnableInertiaTerms = false -PrintL2Error = false -PrintLInfinityError = false +PrintErrors = true IsStationary = false [Component] diff --git a/appl/freeflow/navierstokes/channel/2d/params_graded.input b/appl/freeflow/navierstokes/channel/2d/params_graded.input index 11777b3..0d15b9f 100644 --- a/appl/freeflow/navierstokes/channel/2d/params_graded.input +++ b/appl/freeflow/navierstokes/channel/2d/params_graded.input @@ -34,7 +34,7 @@ EnableGravity = false EnableInertiaTerms = false OutletCondition = Outflow UseVelocityProfile = true -PrintL2Error = true +PrintErrors = true IsStationary = true [Component] diff --git a/appl/freeflow/navierstokes/channel/2d/params_grading_add_dof_good.input b/appl/freeflow/navierstokes/channel/2d/params_grading_add_dof_good.input index f27e42e..ce697b1 100644 --- a/appl/freeflow/navierstokes/channel/2d/params_grading_add_dof_good.input +++ b/appl/freeflow/navierstokes/channel/2d/params_grading_add_dof_good.input @@ -22,7 +22,7 @@ EnableGravity = false EnableInertiaTerms = false OutletCondition = Outflow UseVelocityProfile = true -PrintL2Error = true +PrintErrors = true IsStationary = true [Component] diff --git a/appl/freeflow/navierstokes/channel/2d/params_navierstokes.input b/appl/freeflow/navierstokes/channel/2d/params_navierstokes.input index d43244c..ab06b01 100644 --- a/appl/freeflow/navierstokes/channel/2d/params_navierstokes.input +++ b/appl/freeflow/navierstokes/channel/2d/params_navierstokes.input @@ -5,7 +5,7 @@ TEnd = 2 # [s] [Helper.Grid] Positions0 = 0 10 Positions1 = 0 1 -Cells0 = 5 +Cells0 = 10 Cells1 = 5 Grading0 = 1.0 Grading1 = 1.0 @@ -15,13 +15,10 @@ File = grid.dgf [Problem] Name = test_channel_navierstokes # name passed to the output routines -InletVelocity = 1 +InletVelocity = 1000 EnableGravity = false -EnableInertiaTerms = false -PrintL2Error = false -PrintLInfinityError = false +PrintErrors = true IsStationary = false -AveragedAnalyticalSolution = false [Component] LiquidDensity = 1.0 @@ -31,8 +28,8 @@ MolarMass = 1.0 [ Newton ] MaxSteps = 100 MaxRelativeShift = 1e-5 -ExitAfterFirstIteration = true -OutputMatrices = true +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true [Vtk] WriteFaceData = false @@ -40,8 +37,7 @@ WriteFaceData = false [Adaptivity] Conservation = false Adapt = true -LinearInterpolation = true #false: quadratic -LeftX = 4 -RightX = 6 -LowerY = 0.4 -UpperY = 0.6 +LeftX = 2 +RightX = 8 +LowerY = 0.2 +UpperY = 0.8 diff --git a/appl/freeflow/navierstokes/channel/2d/params_navierstokes_stationary.input b/appl/freeflow/navierstokes/channel/2d/params_navierstokes_stationary.input index f4cfc0e..968f8d2 100644 --- a/appl/freeflow/navierstokes/channel/2d/params_navierstokes_stationary.input +++ b/appl/freeflow/navierstokes/channel/2d/params_navierstokes_stationary.input @@ -25,10 +25,10 @@ File = grid.dgf Name = test_channel_navierstokes_stationary # name passed to the output routines InletVelocity = 100 EnableGravity = false -PrintL2Error = true -PrintLInfinityError = true +PrintErrors = true EnableInertiaTerms = true IsStationary = true +AveragedAnalyticalSolution = false [Component] MolarMass = 1.0 @@ -37,7 +37,9 @@ LiquidKinematicViscosity = 1 [ Newton ] MaxSteps = 100 -MaxRelativeShift = 1e-8 +MaxRelativeShift = 1e-4 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true [Vtk] WriteFaceData = false @@ -54,7 +56,7 @@ NumericDifference.PriVarMagnitude = 1e5 # pressure is in the order of 1e5 NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 [Adaptivity] -Conservation = true +Conservation = false Adapt = true LeftX = 2 RightX = 8 diff --git a/appl/freeflow/navierstokes/channel/2d/params_stokes.input b/appl/freeflow/navierstokes/channel/2d/params_stokes.input index 7b2226f..9197ce7 100644 --- a/appl/freeflow/navierstokes/channel/2d/params_stokes.input +++ b/appl/freeflow/navierstokes/channel/2d/params_stokes.input @@ -30,8 +30,7 @@ Name = test_channel_stokes # name passed to the output routines InletVelocity = 1 EnableGravity = false EnableInertiaTerms = false -PrintL2Error = false -PrintLInfinityError = false +PrintErrors = true IsStationary = false [Component] @@ -42,6 +41,8 @@ LiquidKinematicViscosity = 1 [ Newton ] MaxSteps = 100 MaxRelativeShift = 1e-8 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true [Vtk] WriteFaceData = false @@ -58,7 +59,7 @@ NumericDifference.PriVarMagnitude = 1e5 # pressure is in the order of 1e5 NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 [Adaptivity] -Conservation = true +Conservation = false Adapt = true LeftX = 3 RightX = 5 diff --git a/appl/freeflow/navierstokes/channel/2d/params_stokes_stationary.input b/appl/freeflow/navierstokes/channel/2d/params_stokes_stationary.input index e63b163..09ef667 100644 --- a/appl/freeflow/navierstokes/channel/2d/params_stokes_stationary.input +++ b/appl/freeflow/navierstokes/channel/2d/params_stokes_stationary.input @@ -26,8 +26,7 @@ Name = test_channel_stokes_stationary # name passed to the output routines InletVelocity = 1 EnableGravity = false EnableInertiaTerms = false -PrintL2Error = true -PrintLInfinityError = true +PrintErrors = true IsStationary = true [Component] @@ -38,6 +37,8 @@ LiquidKinematicViscosity = 1 [ Newton ] MaxSteps = 100 MaxRelativeShift = 1e-15 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true [Vtk] WriteFaceData = false diff --git a/appl/freeflow/navierstokes/channel/2d/params_stokes_stationary_fvcaGrid.input b/appl/freeflow/navierstokes/channel/2d/params_stokes_stationary_fvcaGrid.input index 56f0a1f..13efb63 100644 --- a/appl/freeflow/navierstokes/channel/2d/params_stokes_stationary_fvcaGrid.input +++ b/appl/freeflow/navierstokes/channel/2d/params_stokes_stationary_fvcaGrid.input @@ -27,10 +27,8 @@ Name = test_channel_fvca # name passed to the output routines InletVelocity = 1 EnableGravity = false EnableInertiaTerms = false -PrintL2Error = true -PrintLInfinityError = true +PrintErrors = true IsStationary = true -AveragedAnalyticalSolution = false [Component] MolarMass = 1.0 diff --git a/appl/freeflow/navierstokes/channel/2d/params_uniform.input b/appl/freeflow/navierstokes/channel/2d/params_uniform.input index 4ff1274..978b64b 100644 --- a/appl/freeflow/navierstokes/channel/2d/params_uniform.input +++ b/appl/freeflow/navierstokes/channel/2d/params_uniform.input @@ -22,7 +22,7 @@ EnableGravity = false EnableInertiaTerms = false OutletCondition = Outflow UseVelocityProfile = true -PrintL2Error = true +PrintErrors = true IsStationary = true [Component] diff --git a/appl/freeflow/navierstokes/channel/2d/problem.hh b/appl/freeflow/navierstokes/channel/2d/problem.hh index 8338b3c..726b595 100644 --- a/appl/freeflow/navierstokes/channel/2d/problem.hh +++ b/appl/freeflow/navierstokes/channel/2d/problem.hh @@ -21,8 +21,8 @@ * \ingroup NavierStokesTests * \brief Channel flow test for the staggered grid (Navier-)Stokes model */ -#ifndef DUMUX_CVD_CHANNEL_TEST_PROBLEM_HH -#define DUMUX_CVD_CHANNEL_TEST_PROBLEM_HH +#ifndef DUMUX_CHANNEL_TEST_PROBLEM_HH +#define DUMUX_CHANNEL_TEST_PROBLEM_HH #include <dune/alugrid/grid.hh> #include <dune/grid/yaspgrid.hh> @@ -30,6 +30,8 @@ #include <dumux/assembly/cvdstaggeredrefinedlocalresidual.hh> +#include <dumux/common/numeqvector.hh> + #include <dumux/material/fluidsystems/1pliquid.hh> #include <dumux/material/components/simpleh2o.hh> #include <dumux/material/components/constant.hh> @@ -45,6 +47,7 @@ #include <dumux/discretization/staggered/freeflow/properties.hh> #include <dumux/discretization/staggered/freeflow/myfacevariables.hh> #include <dumux/discretization/staggered/freeflow/cvdlocalfacevariables.hh> +#include <dumux/discretization/staggered/cvdlocalgridfacevariables.hh> #include <dumux/discretization/staggered/freeflow/myvelocityoutput.hh> #include <dumux/discretization/staggered/freeflow/mygridvolumevariables.hh> #include <dumux/discretization/staggered/freeflow/elementvolumevariables1.hh> @@ -52,14 +55,9 @@ #include <dumux/discretization/staggered/myfacesolution.hh> #include <dumux/discretization/staggered/cvdelementfacesolution.hh> #include <dumux/discretization/staggered/cvdgridvariables.hh> -#include <dumux/discretization/staggered/cvdlocalgridfacevariables.hh> #include <dumux/discretization/staggered/cvdfvgridgeometry.hh> #include <dumux/discretization/staggered/freeflow/cvdfvgridgeometrytraits.hh> -#include <appl/freeflow/navierstokes/channel/channell2error.hh> -#include <appl/freeflow/navierstokes/l2error.hh> -#include <appl/freeflow/navierstokes/linfinityerror.hh> - namespace Dumux { template <class TypeTag> @@ -330,13 +328,14 @@ class ChannelTestProblem : public MyNavierStokesProblem<TypeTag> using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; using ModelTraits = GetPropType<TypeTag, Properties::ModelTraits>; - using NumEqVector = GetPropType<TypeTag, Properties::NumEqVector>; + using NumEqVector = Dumux::NumEqVector<GetPropType<TypeTag, Properties::PrimaryVariables>>; using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>; using Scalar = GetPropType<TypeTag, Properties::Scalar>; using SolutionVector = GetPropType<TypeTag, Properties::SolutionVector>; using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; using FVElementGeometry = typename GridGeometry::LocalView; using SubControlVolume = typename GridGeometry::SubControlVolume; + using SubControlVolumeFace = typename GetPropType<TypeTag, Properties::GridGeometry>::SubControlVolumeFace; static constexpr auto dimWorld = GetPropType<TypeTag, Properties::GridGeometry>::GridView::dimensionworld; @@ -350,8 +349,6 @@ public: ChannelTestProblem(std::shared_ptr<const GridGeometry> gridGeometry) : ParentType(gridGeometry), eps_(1e-6) { - printL2Error_ = getParam<bool>("Problem.PrintL2Error", true); - printLInfinityError_ = getParam<bool>("Problem.PrintLInfinityError", true); dynamicViscosity_ = getParam<Scalar>("Component.LiquidKinematicViscosity", 1.0) * getParam<Scalar>("Component.LiquidDensity", 1.0); inletVelocity_ = getParam<Scalar>("Problem.InletVelocity"); @@ -378,42 +375,6 @@ public: return false; } - void printErrors(const SolutionVector& curSol) const - { - if(printL2Error_) - { - bool integratedError = getParam<bool>("Problem.IntegratedError", false); - - using IntegratedL2Error = ChannelTestL2Error<Scalar, ModelTraits, PrimaryVariables>; - using L2Error = NavierStokesTestL2Error<Scalar, ModelTraits, PrimaryVariables>; - const auto l2error = integratedError?IntegratedL2Error::calculateL2Error(*this, curSol):L2Error::calculateL2Error(*this, curSol); - const int numCellCenterDofs = this->gridGeometry().numCellCenterDofs(); - const int numFaceDofs = this->gridGeometry().numFaceDofs(); - std::cout << std::setprecision(8) << "** L2 error (abs/rel) for " - << std::setw(6) << numCellCenterDofs << " cc dofs and " << numFaceDofs << " face dofs (total: " << numCellCenterDofs + numFaceDofs << "): " - << std::scientific - << "L2(p) = " << l2error.first[Indices::pressureIdx] << " / " << l2error.second[Indices::pressureIdx] - << " , L2(vx) = " << l2error.first[Indices::velocityXIdx] << " / " << l2error.second[Indices::velocityXIdx] - << " , L2(vy) = " << l2error.first[Indices::velocityYIdx] << " / " << l2error.second[Indices::velocityYIdx] - << std::endl; - } - - if(printLInfinityError_) - { - using LInfinityError = NavierStokesTestLInfinityError<Scalar, ModelTraits, PrimaryVariables>; - const auto lInfinityError = LInfinityError::calculateLInfinityError(*this, curSol); - const int numCellCenterDofs = this->gridGeometry().numCellCenterDofs(); - const int numFaceDofs = this->gridGeometry().numFaceDofs(); - std::cout << std::setprecision(8) << "** LInfinity error (abs/rel) for " - << std::setw(6) << numCellCenterDofs << " cc dofs and " << numFaceDofs << " face dofs (total: " << numCellCenterDofs + numFaceDofs << "): " - << std::scientific - << "LInfinity(p) = " << lInfinityError[Indices::pressureIdx] - << " , LInfinity(vx) = " << lInfinityError[Indices::velocityXIdx] - << " , LInfinity(vy) = " << lInfinityError[Indices::velocityYIdx] - << std::endl; - } - } - /*! * \brief Return the temperature within the domain in [K]. * @@ -458,28 +419,43 @@ public: const SubControlVolume& scv, int pvIdx) const { - // set fixed pressure in one cell - return (scv.dofIndex() == 0) && pvIdx == Indices::pressureIdx; + // set fixed pressure in one cell + return (scv.dofIndex() == 0) && pvIdx == Indices::pressureIdx; } - /*! + /*! * \brief Evaluate the boundary conditions for a dirichlet - * control volume. + * control volume face (velocities) * - * \param globalPos The center of the finite volume which ought to be set. - */ - PrimaryVariables dirichletAtPos(const GlobalPosition &globalPos) const + * \param element The finite element + * \param scvf the sub control volume face + * + * Concerning the usage of averaged velocity, see the explanation of the initial function. The average of the nondirection velocity along an scvf is required in the context of dirichlet boundary conditions for the functions getParallelVelocityFromBoundary_ and getParallelVelocityFromOtherBoundary_ within myfluxvariables.hh. There dirichlet is called for ghost faces built from the normalFace but the value then is taken in the the direction scvf.directionIndex, which is along that normalFace. + */ + PrimaryVariables dirichlet(const Element& element, const SubControlVolumeFace& scvf) const { - PrimaryVariables values = initialAtPos(globalPos); + PrimaryVariables priVars(0.0); - if(isInlet(globalPos) || isOutlet(globalPos)) - { - Scalar y = globalPos[1]; + unsigned int dirIdx = scvf.directionIndex(); + priVars[Indices::velocity(dirIdx)] = this->analyticalVelocitySolutionAtPos(scvf); + unsigned int nonDirIdx = (dirIdx == 0)?1:0; + priVars[Indices::velocity(nonDirIdx)] = this->analyticalNonDirVelocitySolutionAtPos(scvf); - values[Indices::velocityXIdx] = velocityQuadraticCoefficient_ * y * y + velocityLinearCoefficient_ * y + velocityConstant_; - } + return priVars; + } - return values; + /*! + * \brief Evaluate the boundary conditions for a dirichlet + * control volume face (pressure) + * + * \param element The finite element + * \param scv the sub control volume + */ + PrimaryVariables dirichlet(const Element& element, const SubControlVolume& scv) const + { + PrimaryVariables priVars(0.0); + priVars[Indices::pressureIdx] = this->analyticalPressureSolutionAtPos(scv); + return priVars; } /*! @@ -494,125 +470,71 @@ public: Scalar x = globalPos[0]; Scalar y = globalPos[1]; - for (unsigned int i = 0; i < values.size(); ++i) - { - values[i] = xFactorAnalyticalSolutionAtPos(x)[0][i]*yFactorAnalyticalSolutionAtPos(y)[0][i]; - } - - return values; - } - - std::array<PrimaryVariables, 2> xFactorAnalyticalSolutionAtPos(Scalar x) const - { - PrimaryVariables values = {}; values[Indices::pressureIdx] = f1_(x); - values[Indices::velocityXIdx] = 1.; - values[Indices::velocityYIdx] = 0.; - - PrimaryVariables zero = {}; - - std::array<PrimaryVariables, 2> retPair; - retPair[0] = values; - retPair[1] = zero; - - return retPair; - } - - std::array<PrimaryVariables, 2> yFactorAnalyticalSolutionAtPos(Scalar y) const - { - PrimaryVariables values = {}; - values[Indices::pressureIdx] = 1.; values[Indices::velocityXIdx] = f2_(y); values[Indices::velocityYIdx] = 0.; - PrimaryVariables zero = {}; - - std::array<PrimaryVariables, 2> retPair; - retPair[0] = values; - retPair[1] = zero; - - return retPair; - } - - std::array<PrimaryVariables, 2> xFactorAnalyticalSolutionAntiderivativeAtPos(Scalar x) const - { - PrimaryVariables values = {}; - values[Indices::pressureIdx] = intf1_(x); - values[Indices::velocityXIdx] = x; - values[Indices::velocityYIdx] = 0.; - - PrimaryVariables zero = {}; - - std::array<PrimaryVariables, 2> retPair; - retPair[0] = values; - retPair[1] = zero; - - return retPair; + return values; } - std::array<PrimaryVariables, 2> yFactorAnalyticalSolutionAntiderivativeAtPos(Scalar y) const - { - PrimaryVariables values = {}; - values[Indices::pressureIdx] = y; - values[Indices::velocityXIdx] = intf2_(y); - values[Indices::velocityYIdx] = 0.; - - PrimaryVariables zero = {}; - - std::array<PrimaryVariables, 2> retPair; - retPair[0] = values; - retPair[1] = zero; - - return retPair; - } + /*! + * \name Volume terms + */ + // \{ /*! - * \brief Return the mean analytical solution of the problem at a given position, (int_V analyticalSolution dV)/V + * \brief Evaluates the initial value for a sub control volume face (velocities) * - * \param globalPos The global position + * Simply assigning the value of the analytical solution at the face center + * gives a discrete solution that is not divergence-free. For small initial + * time steps, this has a negative impact on the pressure solution + * after the first time step. The flag UseVelocityAveraging triggers the + * function averagedVelocity_ which uses a higher order quadrature formula to + * bring the discrete solution sufficiently close to being divergence-free. */ - PrimaryVariables meanAnalyticalSolution(const GlobalPosition& globalPos, Scalar deltaAdd, Scalar deltaSubtract) const + PrimaryVariables initial(const SubControlVolumeFace& scvf) const { - if (deltaAdd < 0 || deltaSubtract < 0 || deltaAdd + deltaSubtract == 0) - { - DUNE_THROW(Dune::InvalidStateException, "Expected nonnegative deltas as well as one delta neq 0."); - } - - Scalar x = globalPos[0]; - Scalar y = globalPos[1]; + bool startWithAnalytical = getParam<bool>("Problem.StartWithAnalytical", false); - auto pressureAntiderivative = [&](Scalar x) + if (startWithAnalytical) { - return 0.5 * pressureLinearCoefficient_ * x * x + pressureConstant_ * x; - }; - - auto velocityXAntiderivative = [&](Scalar y) + PrimaryVariables priVars(0.0); + priVars[Indices::velocity(scvf.directionIndex())] = this->analyticalVelocitySolutionAtPos(scvf); + return priVars; + } + else { - return velocityQuadraticCoefficient_ * y * y * y / 3. + velocityLinearCoefficient_ * y * y / 2. + velocityConstant_ * y; - }; - - PrimaryVariables values; - values[Indices::pressureIdx] = (pressureAntiderivative(x + deltaAdd) - pressureAntiderivative(x - deltaSubtract))/(deltaAdd + deltaSubtract); - values[Indices::velocityXIdx] = (velocityXAntiderivative(y + deltaAdd) - velocityXAntiderivative(y - deltaSubtract))/(deltaAdd + deltaSubtract); - values[Indices::velocityYIdx] = 0; + PrimaryVariables values; + values[Indices::pressureIdx] = 0.0; + values[Indices::velocityXIdx] = 0.0; + values[Indices::velocityYIdx] = 0.0; - return values; + return values; + } } - /*! - * \name Volume terms - */ - // \{ - - /*! - * \brief Evaluate the initial value for a control volume. - * - * \param globalPos The global position + /*! + * \brief Evaluates the initial value for a control volume (pressure) */ - PrimaryVariables initialAtPos(const GlobalPosition &globalPos) const + PrimaryVariables initial(const SubControlVolume& scv) const { - // if I change this, I have to make outputCVResiduals conditional on startWithAnalytical - return this->analyticalSolution(globalPos); + bool startWithAnalytical = getParam<bool>("Problem.StartWithAnalytical", false); + + if (startWithAnalytical) + { + PrimaryVariables priVars(0.0); + priVars[Indices::pressureIdx] = this->analyticalPressureSolutionAtPos(scv); + return priVars; + } + else + { + PrimaryVariables values; + values[Indices::pressureIdx] = 0.0; + values[Indices::velocityXIdx] = 0.0; + values[Indices::velocityYIdx] = 0.0; + + return values; + } } // \} @@ -628,74 +550,6 @@ public: return timeLoop_->time(); } - /*! - * \brief Returns the analytical solution for the pressure - */ - auto& getAnalyticalPressureSolution() const - { - return analyticalPressure_; - } - - /*! - * \brief Returns the analytical solution for the velocity - */ - auto& getAnalyticalVelocitySolution() const - { - return analyticalVelocity_; - } - - /*! - * \brief Returns the analytical solution for the velocity at the faces - */ - auto& getAnalyticalVelocitySolutionOnFace() const - { - return analyticalVelocityOnFace_; - } - - auto& getAnalyticalFaceSolutionVector() const - { - return analyticalFaceSolutionVector_; - } - - /*! - * \brief Adds additional VTK output data to the VTKWriter. Function is called by the output module on every write. - */ - void createAnalyticalSolution() - { - analyticalPressure_.resize(this->gridGeometry().numCellCenterDofs()); - analyticalVelocity_.resize(this->gridGeometry().numCellCenterDofs()); - analyticalVelocityOnFace_.resize(this->gridGeometry().numFaceDofs()); - analyticalFaceSolutionVector_.resize(this->gridGeometry().numFaceDofs()); - - for (const auto& element : elements(this->gridGeometry().gridView())) - { - auto fvGeometry = localView(this->gridGeometry()); - fvGeometry.bindElement(element); - for (auto&& scv : scvs(fvGeometry)) - { - auto ccDofIdx = scv.dofIndex(); - auto ccDofPosition = scv.dofPosition(); - auto analyticalSolutionAtCc = this->analyticalSolution(ccDofPosition); - - // velocities on faces - for (auto&& scvf : scvfs(fvGeometry)) - { - const auto faceDofIdx = scvf.dofIndex(); - const auto faceDofPosition = scvf.center(); - const auto dirIdx = scvf.directionIndex(); - const auto analyticalSolutionAtFace = this->analyticalSolution(faceDofPosition); - analyticalVelocityOnFace_[faceDofIdx][dirIdx] = analyticalSolutionAtFace[Indices::velocity(dirIdx)]; - analyticalFaceSolutionVector_[faceDofIdx] = analyticalSolutionAtFace[Indices::velocity(dirIdx)]; - } - - analyticalPressure_[ccDofIdx] = analyticalSolutionAtCc[Indices::pressureIdx]; - - for(int dirIdx = 0; dirIdx < ModelTraits::dim(); ++dirIdx) - analyticalVelocity_[ccDofIdx][dirIdx] = analyticalSolutionAtCc[Indices::velocity(dirIdx)]; - } - } - } - private: bool isInlet(const GlobalPosition& globalPos) const { @@ -715,25 +569,13 @@ private: Scalar f1_(Scalar x) const { return pressureLinearCoefficient_ * x + pressureConstant_; } - Scalar intf1_(Scalar x) const - { return 0.5*pressureLinearCoefficient_ * x * x + pressureConstant_*x; } - Scalar f2_(Scalar y) const { return velocityQuadraticCoefficient_ * y * y + velocityLinearCoefficient_ * y + velocityConstant_; } - Scalar intf2_(Scalar y) const - { return 1./3*velocityQuadraticCoefficient_ * y * y * y + .5 * velocityLinearCoefficient_ * y * y + velocityConstant_ * y; } - Scalar eps_; - bool printL2Error_; - bool printLInfinityError_; Scalar dynamicViscosity_; Scalar inletVelocity_; TimeLoopPtr timeLoop_; - std::vector<Scalar> analyticalPressure_; - std::vector<VelocityVector> analyticalVelocity_; - std::vector<VelocityVector> analyticalVelocityOnFace_; - FaceSolutionVector analyticalFaceSolutionVector_; Scalar velocityQuadraticCoefficient_; Scalar velocityLinearCoefficient_; diff --git a/appl/freeflow/navierstokes/channel/channell2error.hh b/appl/freeflow/navierstokes/channel/channell2error.hh deleted file mode 100644 index 0f6e26f..0000000 --- a/appl/freeflow/navierstokes/channel/channell2error.hh +++ /dev/null @@ -1,206 +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 - * \ingroup NavierStokesTests - * \copydoc Dumux::NavierStokesTestL2Error - */ -#ifndef DUMUX_APPL_CHANNEL_L2_ERROR_HH -#define DUMUX_APPL_CHANNEL_L2_ERROR_HH - -#include <vector> -#include <cmath> - -namespace Dumux -{ - -/*! - * \ingroup NavierStokesTests - * \brief Routines to calculate the discrete L2 error - */ -template<class Scalar, class ModelTraits, class PrimaryVariables> -class ChannelTestL2Error -{ - using Indices = typename ModelTraits::Indices; - -public: - - /*! - * \brief Calculate the L2 error between the analytical solution and the numerical approximation. - * - * \param curSol Vector containing the current solution - */ - template<class Problem, class SolutionVector> - static auto calculateL2Error(const Problem& problem, const SolutionVector& curSol) - { - using GridGeometry = std::decay_t<decltype(problem.gridGeometry())>; - PrimaryVariables sumError(0.0), sumReference(0.0), l2NormAbs(0.0), l2NormRel(0.0); - - const int numFaceDofs = problem.gridGeometry().numFaceDofs(); - - std::vector<Scalar> staggeredVolume(numFaceDofs); - std::vector<Scalar> errorVelocity(numFaceDofs); - std::vector<Scalar> velocityReference(numFaceDofs); - std::vector<int> directionIndex(numFaceDofs); - - Scalar totalVolume = 0.0; - - for (const auto& element : elements(problem.gridGeometry().gridView())) - { - auto fvGeometry = localView(problem.gridGeometry()); - fvGeometry.bindElement(element); - - for (auto&& scv : scvs(fvGeometry)) - { - // treat cell-center dofs - const auto dofIdxCellCenter = scv.dofIndex(); - const auto& posCellCenter = scv.dofPosition(); - - const Scalar deltaX = [&]() - { - Scalar x1 = element.geometry().corner(0)[0]; - for (unsigned int i = 1; i < element.geometry().corners(); ++i) - { - Scalar x2 = element.geometry().corner(i)[0]; - - if (!scalarCmp(x1,x2)) - { - return fabs(x1 - x2); - } - } - - DUNE_THROW(Dune::InvalidStateException, "Should never get here"); - }(); - - const auto analyticalSolutionCellCenter = problem.meanAnalyticalSolution(posCellCenter, 0.5 * deltaX, 0.5 * deltaX)[Indices::pressureIdx]; - const auto numericalSolutionCellCenter = curSol[GridGeometry::cellCenterIdx()][dofIdxCellCenter][Indices::pressureIdx - ModelTraits::dim()]; - sumError[Indices::pressureIdx] += squaredDiff_(analyticalSolutionCellCenter, numericalSolutionCellCenter) * scv.volume(); - sumReference[Indices::pressureIdx] += analyticalSolutionCellCenter * analyticalSolutionCellCenter * scv.volume(); - totalVolume += scv.volume(); - - // treat face dofs, Dirichlet boundary values are considered but will not contribute to the error - for (auto&& scvf : scvfs(fvGeometry)) - { - const int dofIdxFace = scvf.dofIndex(); - const int dirIdx = scvf.directionIndex(); - - Scalar deltaYUp; - Scalar deltaYDown; - - if (scvf.directionSign() < 0)//inside is up, outside is down - { - deltaYUp = scv.volume()/scvf.area(); - - if (scvf.neighbor()) - { - deltaYDown = scvf.outside().geometry().volume()/scvf.area(); - - if (scvf.inside().level() < scvf.outside().level()) - { - deltaYUp *= 0.5; - } - else if (scvf.inside().level() > scvf.outside().level()) - { - deltaYDown *= 0.5; - } - } - else - { - deltaYDown = 0.; - } - } - else if (scvf.directionSign() > 0)//outside is up, inside is down - { - deltaYDown = scv.volume()/scvf.area(); - - if (scvf.neighbor()) - { - deltaYUp = scvf.outside().geometry().volume()/scvf.area(); - - if (scvf.inside().level() < scvf.outside().level()) - { - deltaYDown *= 0.5; - } - else if (scvf.inside().level() > scvf.outside().level()) - { - deltaYUp *= 0.5; - } - } - else - { - deltaYUp = 0.; - } - } - else - { - DUNE_THROW(Dune::InvalidStateException, "Invalid state."); - } - - const auto analyticalSolutionFace = problem.meanAnalyticalSolution(scvf.center(), 0.5 * deltaYUp, 0.5 * deltaYDown)[Indices::velocity(dirIdx)]; - const auto numericalSolutionFace = curSol[GridGeometry::faceIdx()][dofIdxFace][0]; - directionIndex[dofIdxFace] = dirIdx; - errorVelocity[dofIdxFace] = squaredDiff_(analyticalSolutionFace, numericalSolutionFace); - velocityReference[dofIdxFace] = squaredDiff_(analyticalSolutionFace, 0.0); - Scalar staggeredHalfVolume = 0.5 * scv.volume(); - - if (scvf.neighbor() && scvf.inside().level() < scvf.outside().level()) - { - staggeredHalfVolume *= 0.5; - } - - staggeredVolume[dofIdxFace] = staggeredVolume[dofIdxFace] + staggeredHalfVolume; - } - } - } - - // get the absolute and relative discrete L2-error for cell-center dofs - l2NormAbs[Indices::pressureIdx] = std::sqrt(sumError[Indices::pressureIdx] / totalVolume); - l2NormRel[Indices::pressureIdx] = std::sqrt(sumError[Indices::pressureIdx] / sumReference[Indices::pressureIdx]); - - // get the absolute and relative discrete L2-error for face dofs - for(int i = 0; i < numFaceDofs; ++i) - { - const int dirIdx = directionIndex[i]; - const auto error = errorVelocity[i]; - const auto ref = velocityReference[i]; - const auto volume = staggeredVolume[i]; - sumError[Indices::velocity(dirIdx)] += error * volume; - sumReference[Indices::velocity(dirIdx)] += ref * volume; - } - - for(int dirIdx = 0; dirIdx < ModelTraits::dim(); ++dirIdx) - { - l2NormAbs[Indices::velocity(dirIdx)] = std::sqrt(sumError[Indices::velocity(dirIdx)] / totalVolume); - l2NormRel[Indices::velocity(dirIdx)] = std::sqrt(sumError[Indices::velocity(dirIdx)] / sumReference[Indices::velocity(dirIdx)]); - } - return std::make_pair(l2NormAbs, l2NormRel); - } - -private: - - template<class T> - static T squaredDiff_(const T& a, const T& b) - { - return (a-b)*(a-b); - } - -}; -} //end namespace DUMUX_APPL_CHANNEL_L2_ERROR_HH - -#endif diff --git a/appl/freeflow/navierstokes/channel_copy/2d/CMakeLists.txt b/appl/freeflow/navierstokes/channel_copy/2d/CMakeLists.txt deleted file mode 100644 index a4c7227..0000000 --- a/appl/freeflow/navierstokes/channel_copy/2d/CMakeLists.txt +++ /dev/null @@ -1,64 +0,0 @@ -add_input_file_links() - -set(CMAKE_BUILD_TYPE Debug) - -add_executable(test_ff_channel EXCLUDE_FROM_ALL main.cc) - -dune_add_test(NAME test_ff_stokes_channel - TARGET test_ff_channel - CMAKE_GUARD HAVE_UMFPACK - COMMAND ${CMAKE_SOURCE_DIR}/../dumux/bin/testing/runtest.py - CMD_ARGS --script fuzzy - --files ${CMAKE_SOURCE_DIR}/../dumux/test/references/channel-stokes.vtu - ${CMAKE_CURRENT_BINARY_DIR}/test_ff_stokes_channel-00002.vtu - --command "${CMAKE_CURRENT_BINARY_DIR}/test_ff_channel params_stokes.input") - -dune_add_test(NAME test_ff_navierstokes_channel - TARGET test_ff_channel - CMAKE_GUARD HAVE_UMFPACK - COMMAND ${CMAKE_SOURCE_DIR}/../dumux/bin/testing/runtest.py - CMD_ARGS --script fuzzy - --files ${CMAKE_SOURCE_DIR}/../dumux/test/references/channel-navierstokes-reference.vtu - ${CMAKE_CURRENT_BINARY_DIR}/test_ff_navierstokes_channel-00002.vtu - --command "${CMAKE_CURRENT_BINARY_DIR}/test_ff_channel params_navierstokes.input") - -dune_add_test(NAME test_ff_channel_stokes_stationary - TARGET test_ff_channel - CMAKE_GUARD HAVE_UMFPACK - COMMAND ${CMAKE_SOURCE_DIR}/../dumux/bin/testing/runtest.py - CMD_ARGS --script fuzzy - --files ${CMAKE_SOURCE_DIR}/../dumux/test/references/channel-stokes-stationary.vtu - ${CMAKE_CURRENT_BINARY_DIR}/test_channel_stokes_stationary-00002.vtu - --command "${CMAKE_CURRENT_BINARY_DIR}/test_ff_channel params_stokes_stationary.input") - -dune_add_test(NAME test_ff_channel_navierstokes_stationary - TARGET test_ff_channel - CMAKE_GUARD HAVE_UMFPACK - COMMAND ${CMAKE_SOURCE_DIR}/../dumux/bin/testing/runtest.py - CMD_ARGS --script fuzzy - --files ${CMAKE_SOURCE_DIR}/../dumux/test/references/channel-navierstokes-stationary.vtu - ${CMAKE_CURRENT_BINARY_DIR}/test_channel_navierstokes_stationary-00002.vtu - --command "${CMAKE_CURRENT_BINARY_DIR}/test_ff_channel params_navierstokes_stationary.input") - - -add_executable(test_ff_stokesni_channel EXCLUDE_FROM_ALL main.cc) -target_compile_definitions(test_ff_stokesni_channel PUBLIC "NONISOTHERMAL=1") - -dune_add_test(NAME test_ff_channel_stokesni_convection - TARGET test_ff_stokesni_channel - CMAKE_GUARD HAVE_UMFPACK - COMMAND ${CMAKE_SOURCE_DIR}/../dumux/bin/testing/runtest.py - CMD_ARGS --script fuzzy - --files ${CMAKE_SOURCE_DIR}/../dumux/test/references/stokesni-convection-reference.vtu - ${CMAKE_CURRENT_BINARY_DIR}/test_channel_stokesni_convection-00006.vtu - --command "${CMAKE_CURRENT_BINARY_DIR}/test_ff_stokesni_channel params_convection.input") - -dune_add_test(NAME test_ff_channel_stokesni_conduction - TARGET test_ff_stokesni_channel - CMAKE_GUARD HAVE_UMFPACK - COMMAND ${CMAKE_SOURCE_DIR}/../dumux/bin/testing/runtest.py - CMD_ARGS --script fuzzy - --files ${CMAKE_SOURCE_DIR}/../dumux/test/references/stokesni-conduction-reference.vtu - ${CMAKE_CURRENT_BINARY_DIR}/test_channel_stokesni_conduction-00004.vtu - --command "${CMAKE_CURRENT_BINARY_DIR}/test_ff_stokesni_channel params_conduction.input" - --zeroThreshold {"velocity_H2O \(m/s\)":1e-20}) diff --git a/appl/freeflow/navierstokes/channel_copy/2d/main.cc b/appl/freeflow/navierstokes/channel_copy/2d/main.cc deleted file mode 100644 index c1d0996..0000000 --- a/appl/freeflow/navierstokes/channel_copy/2d/main.cc +++ /dev/null @@ -1,535 +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 Channel flow test for the staggered grid (Navier-)Stokes model - */ - -bool doFirstOrderLocalTruncErrorGlobalRefinement = false; - - #include <config.h> - - #include <ctime> - #include <iostream> - - #include <dune/common/parallel/mpihelper.hh> - #include <dune/common/timer.hh> - #include <dune/grid/io/file/dgfparser/dgfwriter.hh> - #include <dune/grid/io/file/dgfparser/dgfexception.hh> - #include <dune/grid/io/file/vtk.hh> - #include <dune/istl/io.hh> - -#include <dumux/common/properties.hh> -#include <dumux/common/coursevelocityproperties.hh> -#include <dumux/common/parameters.hh> -#include <dumux/common/dumuxmessage.hh> -#include <dumux/common/defaultusagemessage.hh> - -#include <dumux/linear/seqsolverbackend.hh> -#include <dumux/nonlinear/newtonsolver.hh> - -#include <dumux/assembly/cvdstaggeredrefinedfvassembler.hh> -#include <dumux/assembly/diffmethod.hh> - -#include <dumux/discretization/method.hh> - -#include <dumux/io/mystaggeredvtkoutputmodule.hh> -#include <dumux/io/grid/gridmanager.hh> - -#include <dumux/freeflow/navierstokes/staggered/cvdfluxoversurface.hh> - -#include <dumux/adaptive/adapt.hh> -#include <dumux/adaptive/markelements.hh> - -#include <dumux/freeflow/cvdgridadaptindicator.hh> -#include <dumux/freeflow/navierstokes/staggered/griddatatransfer.hh> - -#include <dumux/discretization/staggered/cvdfvgridgeometry.hh> -#include <dumux/discretization/staggered/freeflow/cvdfvgridgeometrytraits.hh> - -#include <dumux/freeflow/navierstokes/staggered/cvdresidualCalc.hh> -#include <dumux/io/cvdoutputFacility.hh> - -#include "problem.hh" - -int main(int argc, char** argv) try -{ - using namespace Dumux; - - // define the type tag for this problem - using TypeTag = Properties::TTag::ChannelTestTypeTag; - - // 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); - - bool doFirstOrderLocalTruncError = getParam<bool>("Numerics.DoFirstOrderLocalTruncError", false); - bool adapt = getParam<bool>("Adaptivity.Adapt", false); - //when adapt is true refinement is local, not only global - doFirstOrderLocalTruncErrorGlobalRefinement = !adapt && doFirstOrderLocalTruncError; - - using HelpingGridManager = Dumux::GridManager<GetPropType<TypeTag, Properties::HelpingGrid>>; - HelpingGridManager helpingGridManager; - helpingGridManager.init("Helper"); - const auto& helpingGridView = helpingGridManager.grid().leafGridView(); - Dune::DGFWriter dgfWriter(helpingGridView); - std::string inputFileName = getParam<std::string>("Grid.File"); - dgfWriter.write(inputFileName); - - // The hostgrid - using GridView = typename GetPropType<TypeTag, Properties::GridGeometry>::GridView; - using HostGrid = Dune::ALUGrid<2,2,Dune::cube,Dune::nonconforming >;/* typename GetPropType<TypeTag, Properties::Grid>::HostGrid;*/ - using HostGridManager = GridManager<HostGrid>; - HostGridManager hostGridManager; - hostGridManager.init(); - auto& hostGrid = hostGridManager.grid(); - - // we compute on the leaf grid view - const auto& leafGridViewVar = hostGrid.leafGridView(); - - bool roughChannel = getParam<bool>("Adaptivity.RoughChannel", false); - using Scalar = GetPropType<TypeTag, Properties::Scalar>; - - bool FVCAgrid = getParam<bool>("Grid.FVCAGrid", false); - if (FVCAgrid) - { - adapt = false; - - hostGrid.preAdapt(); - for (const auto& element : elements(leafGridViewVar)) - { - using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; - using GridView = typename GridGeometry::GridView; - using Element = typename GridView::template Codim<0>::Entity; - using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - - GlobalPosition pos = element.geometry().center(); - - auto x = pos[0]; - auto y = pos[1]; - - if(x > .5 && y < .5) - { - hostGrid.mark( 1, element); - } - } - hostGrid.adapt(); - hostGrid.postAdapt(); - - hostGrid.preAdapt(); - for (const auto& element : elements(leafGridViewVar)) - { - using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; - using GridView = typename GridGeometry::GridView; - using Element = typename GridView::template Codim<0>::Entity; - using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - - GlobalPosition pos = element.geometry().center(); - - auto x = pos[0]; - auto y = pos[1]; - - if(x > .75 && y < .25) - { - hostGrid.mark( 1, element); - } - } - hostGrid.adapt(); - hostGrid.postAdapt(); - } - - if (adapt) - { - Scalar leftX = getParam<Scalar>("Adaptivity.LeftX"); - Scalar rightX = getParam<Scalar>("Adaptivity.RightX"); - Scalar lowerY = getParam<Scalar>("Adaptivity.LowerY"); - Scalar upperY = getParam<Scalar>("Adaptivity.UpperY"); - - hostGrid.preAdapt(); - for (const auto& element : elements(leafGridViewVar)) - { - using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; - using GridView = typename GridGeometry::GridView; - using Element = typename GridView::template Codim<0>::Entity; - using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - - GlobalPosition pos = element.geometry().center(); - - auto x = pos[0]; - auto y = pos[1]; - - if((leftX < x) && (x < rightX) && (y > lowerY) && (y < upperY)) - { - hostGrid.mark( 1, element); - } - } - hostGrid.adapt(); - hostGrid.postAdapt(); - - if (roughChannel) - { - hostGrid.preAdapt(); - for (const auto& element : elements(leafGridViewVar)) - { - using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; - using GridView = typename GridGeometry::GridView; - using Element = typename GridView::template Codim<0>::Entity; - using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - GlobalPosition pos = element.geometry().center(); - - auto x = pos[0]; - auto y = pos[1]; - - auto inCircle = [&](Scalar xCenter, Scalar yCenter, Scalar radius) - { - return (x-xCenter)*(x-xCenter) + (y-yCenter)*(y-yCenter) < radius*radius; - }; - - Scalar myRadius = .25; - - if(inCircle(2, .2, myRadius) || inCircle(3, .2, myRadius) ||inCircle(5, .2, myRadius) ||inCircle(6, .2, myRadius) ||inCircle(8, .2, myRadius) ||inCircle(9, .2, myRadius) ) - { - hostGrid.mark( 1, element); - } - } - hostGrid.adapt(); - hostGrid.postAdapt(); - - - hostGrid.preAdapt(); - for (const auto& element : elements(leafGridViewVar)) - { - using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; - using GridView = typename GridGeometry::GridView; - using Element = typename GridView::template Codim<0>::Entity; - using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - GlobalPosition pos = element.geometry().center(); - - auto x = pos[0]; - auto y = pos[1]; - - auto inCircle = [&](Scalar xCenter, Scalar yCenter, Scalar radius) - { - return (x-xCenter)*(x-xCenter) + (y-yCenter)*(y-yCenter) < radius*radius; - }; - - Scalar myRadius = .15; - - if(inCircle(2, .2, myRadius) || inCircle(3, .2, myRadius) ||inCircle(5, .2, myRadius) ||inCircle(6, .2, myRadius) ||inCircle(8, .2, myRadius) ||inCircle(9, .2, myRadius) ) - { - hostGrid.mark( 1, element); - } - } - hostGrid.adapt(); - hostGrid.postAdapt(); - } - } - - // create a grid - using Grid = GetPropType<TypeTag, Properties::Grid>; - Dumux::GridManager<Grid> gridManager; - - // cut out elements within the stair-case region - auto selector = [&](const auto& element) - { - if (!roughChannel) - return true; - - const auto globalPos = element.geometry().center(); - const auto x = globalPos[0]; - const auto y = globalPos[1]; - - return y > 0.2 || - (x > 2 && x < 3) || - (x > 5 && x < 6) || - (x > 8 && x < 9); - }; - - gridManager.init(hostGrid, selector); - - //////////////////////////////////////////////////////////// - // 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); - - // get some time loop parameters - const auto tEnd = getParam<Scalar>("TimeLoop.TEnd", 0.); - const auto maxDt = getParam<Scalar>("TimeLoop.MaxTimeStepSize"); - auto dt = getParam<Scalar>("TimeLoop.DtInitial", 0.); - - // check if we are about to restart a previously interrupted simulation - Scalar restartTime = 0; - if (Parameters::getTree().hasKey("Restart") || Parameters::getTree().hasKey("TimeLoop.Restart")) - restartTime = getParam<Scalar>("TimeLoop.Restart"); - - // instantiate time loop - auto timeLoop = std::make_shared<CheckPointTimeLoop<Scalar>>(restartTime, dt, tEnd); - timeLoop->setMaxTimeStepSize(maxDt); - problem->setTimeLoop(timeLoop); - - // the solution vector - using SolutionVector = GetPropType<TypeTag, Properties::SolutionVector>; - const auto numDofsCellCenter = leafGridView.size(0); - const auto numDofsFace = (*gridGeometry).numIntersections(); - SolutionVector x; - x[GridGeometry::cellCenterIdx()].resize(numDofsCellCenter); - x[GridGeometry::faceIdx()].resize(numDofsFace); - 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>; - MyStaggeredVtkOutputModule<GridVariables, SolutionVector> vtkWriter(*gridVariables, x, problem->name()); - IOFields::initOutputModule(vtkWriter); //!< Add model specific output fields - problem->createAnalyticalSolution(); - - const bool isStationary = getParam<bool>("Problem.IsStationary"); - - if(isStationary) - { - vtkWriter.addField(problem->getAnalyticalPressureSolution(), "pressureExact"); - vtkWriter.addField(problem->getAnalyticalVelocitySolution(), "velocityExact"); - vtkWriter.addFaceField(problem->getAnalyticalVelocitySolutionOnFace(), "faceVelocityExact"); - } - vtkWriter.write(0.0); - - using CellCenterSolutionVector = GetPropType<TypeTag, Properties::CellCenterSolutionVector>; - CellCenterSolutionVector numericalCCResidualWithAnalytical; - numericalCCResidualWithAnalytical.resize(numDofsCellCenter); - vtkWriter.addField(numericalCCResidualWithAnalytical, "continuityResidual"); - - // the assembler with time loop for instationary problem - using Assembler = CVDStaggeredRefinedFVAssembler<TypeTag, DiffMethod::numeric>; - auto assembler = isStationary ? std::make_shared<Assembler>(problem, gridGeometry, gridVariables) - : std::make_shared<Assembler>(problem, gridGeometry, gridVariables, timeLoop, xOld); - - // the linear solver - using LinearSolver = Dumux::UMFPackBackend; - auto linearSolver = std::make_shared<LinearSolver>(); - - // the non-linear solver - using NewtonSolver = Dumux::NewtonSolver<Assembler, LinearSolver>; - NewtonSolver nonLinearSolver(assembler, linearSolver); - - // set up two surfaces over which fluxes are calculated - MyFluxOverSurface<GridVariables, - SolutionVector, - GetPropType<TypeTag, Properties::ModelTraits>, - GetPropType<TypeTag, Properties::LocalResidual>> flux(*gridVariables, x); - using GridView = typename GetPropType<TypeTag, Properties::GridGeometry>::GridView; - using Element = typename GridView::template Codim<0>::Entity; - - using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - - const Scalar xMin = gridGeometry->bBoxMin()[0]; - const Scalar xMax = gridGeometry->bBoxMax()[0]; - const Scalar yMin = gridGeometry->bBoxMin()[1]; - const Scalar yMax = gridGeometry->bBoxMax()[1]; - - // The first surface shall be placed at the middle of the channel. - // If we have an odd number of cells in x-direction, there would not be any cell faces - // at the position of the surface (which is required for the flux calculation). - // In this case, we add half a cell-width to the x-position in order to make sure that - // the cell faces lie on the surface. This assumes a regular cartesian grid. - const Scalar planePosMiddleX = xMin + 0.5*(xMax - xMin); - - using CellVector = std::vector<unsigned int>; - const auto numCellsXVec = getParam<CellVector>("Helper.Grid.Cells0"); - const unsigned int numCellsX = std::accumulate(numCellsXVec.begin(), numCellsXVec.end(), 0); - - const Scalar offsetX = (numCellsX % 2 == 0) ? 0.0 : 0.5*((xMax - xMin) / numCellsX); - - const auto p0middle = GlobalPosition{planePosMiddleX + offsetX, yMin}; - const auto p1middle = GlobalPosition{planePosMiddleX + offsetX, yMax}; - flux.addSurface("middle", p0middle, p1middle); - - // The second surface is placed at the outlet of the channel. - const auto p0outlet = GlobalPosition{xMax, yMin}; - const auto p1outlet = GlobalPosition{xMax, yMax}; - flux.addSurface("outlet", p0outlet, p1outlet); - - if (isStationary) - { - using HostGrid = Dune::ALUGrid<2,2,Dune::cube,Dune::nonconforming >; - using HostGridManager = GridManager<HostGrid>; - - std::array<std::string, 2> paramGroups = {"coarsexCVs", "coarseyCVs"}; //xfine... - std::array<HostGridManager, 2> cvGridManagers = {}; - std::array<std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>>,2> cvCenterScvfIndicesMaps; - CVDCVOutputFacility<TypeTag> cvOutputFacility(problem); - cvOutputFacility.iniCVGridManagers(cvGridManagers, cvCenterScvfIndicesMaps, paramGroups); - using Scalar = GetPropType<TypeTag, Properties::Scalar>; - std::vector<std::pair<unsigned int, Scalar>> pvdFileInfos; - - // linearize & solve - Dune::Timer timer; - nonLinearSolver.solve(x); - - //output - if (getParam<bool>("Problem.PrintErrors", true)) - problem->printErrors(x); - - using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; - FaceSolutionVector numericalFaceResidualWithAnalytical; - - std::optional<std::array<std::vector<Scalar>, 2>> optionalPerfectInterpolationFaceResiduals; - //TODO when reintroducing outflow BC make this empty with outflow BC - // std::array<std::vector<Scalar>, 4> perfectInterpolationFaceResiduals; - // optionalPerfectInterpolationFaceResiduals.emplace(perfectInterpolationFaceResiduals); - - ResidualCalc<TypeTag> residualCalc(problem); - residualCalc.calcResidualsStationary(gridGeometry, numericalCCResidualWithAnalytical, numericalFaceResidualWithAnalytical); - - bool readDofBasedValues = getParam<bool>("Problem.ReadDofBasedValues", false); - if (readDofBasedValues) - { - CellCenterSolutionVector readInPres; - readInPres.resize(gridGeometry->numCellCenterDofs()); - ReadDofBasedResult<TypeTag> reader(problem); - reader.readDofBasedResult(readInPres, "pressure"); - vtkWriter.addField(readInPres, "readInPres"); - } - - vtkWriter.write(1.); - - cvOutputFacility.onCVsOutputResidualsAndPrimVars( - gridGeometry, - cvGridManagers, - cvCenterScvfIndicesMaps, - paramGroups, - x, - 0, - numericalFaceResidualWithAnalytical, - optionalPerfectInterpolationFaceResiduals, - readDofBasedValues); - - pvdFileInfos.push_back(std::make_pair(0, 0)); - cvOutputFacility.printPvdFiles(paramGroups, pvdFileInfos); - - timer.stop(); - } - else - { - // 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()); - - // calculate and print mass fluxes over the planes - flux.calculateMassOrMoleFluxes(); - if(GetPropType<TypeTag, Properties::ModelTraits>::enableEnergyBalance()) - { - std::cout << "mass / energy flux at middle is: " << flux.netFlux("middle") << std::endl; - std::cout << "mass / energy flux at outlet is: " << flux.netFlux("outlet") << std::endl; - } - else - { - std::cout << "mass flux at middle is: " << flux.netFlux("middle") << std::endl; - std::cout << "mass flux at outlet is: " << flux.netFlux("outlet") << std::endl; - } - - // calculate and print volume fluxes over the planes - flux.calculateVolumeFluxes(); - std::cout << "volume flux at middle is: " << flux.netFlux("middle")[0] << std::endl; - std::cout << "volume flux at outlet is: " << flux.netFlux("outlet")[0] << std::endl; - - // report statistics of this time step - timeLoop->reportTimeStep(); - - // set new dt as suggested by 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/appl/freeflow/navierstokes/channel_copy/2d/params_conduction.input b/appl/freeflow/navierstokes/channel_copy/2d/params_conduction.input deleted file mode 100644 index e2d46c3..0000000 --- a/appl/freeflow/navierstokes/channel_copy/2d/params_conduction.input +++ /dev/null @@ -1,50 +0,0 @@ -[TimeLoop] -DtInitial = 1e7 # [s] -TEnd = 1e8 # [s] - -[Helper.Grid] -Positions0 = 0 10 -Positions1 = 0 1 -Cells0 = 10 -Cells1 = 5 -Grading0 = 1.0 -Grading1 = 1.0 - -[Grid] -File = grid.dgf - -[Problem] -Name = test_channel_stokesni_conduction # name passed to the output routines -InletVelocity = 0 -EnableGravity = false -EnableInertiaTerms = false -PrintErrors = true -IsStationary = false - -[Component] -MolarMass = 1.0 -LiquidDensity = 1 -LiquidKinematicViscosity = 1 - -[ Newton ] -MaxSteps = 10 -MaxRelativeShift = 1e-8 - -[Vtk] -WriteFaceData = false - -[Adaptivity] -Conservation = true -Adapt = true -LeftX = 2 -RightX = 8 -LowerY = 0.2 -UpperY = 0.8 - -[Adaptive] -RefineAtDirichletBC = 0 -RefineAtFluxBC = 1 -MinLevel = 0 -MaxLevel = 0 -CoarsenTolerance = 1e-4 -RefineTolerance = 2e-1 diff --git a/appl/freeflow/navierstokes/channel_copy/2d/params_convection.input b/appl/freeflow/navierstokes/channel_copy/2d/params_convection.input deleted file mode 100644 index aeacc54..0000000 --- a/appl/freeflow/navierstokes/channel_copy/2d/params_convection.input +++ /dev/null @@ -1,50 +0,0 @@ -[TimeLoop] -DtInitial = 50 # [s] -TEnd = 250 # [s] - -[Helper.Grid] -Positions0 = 0 0.5 -Positions1 = 0 0.025 -Cells0 = 10 -Cells1 = 5 -Grading0 = 1.0 -Grading1 = 1.0 - -[Grid] -File = grid.dgf - -[Problem] -Name = test_channel_stokesni_convection # name passed to the output routines -InletVelocity = 1e-2 -EnableGravity = false -EnableInertiaTerms = false -PrintErrors = true -IsStationary = false - -[Component] -MolarMass = 1.0 -LiquidDensity = 1 -LiquidKinematicViscosity = 1 - -[ Newton ] -MaxSteps = 10 -MaxRelativeShift = 1e-8 - -[Vtk] -WriteFaceData = false - -[Adaptivity] -Conservation = true -Adapt = true -LeftX = 2 -RightX = 8 -LowerY = 0.2 -UpperY = 0.8 - -[Adaptive] -RefineAtDirichletBC = 0 -RefineAtFluxBC = 1 -MinLevel = 0 -MaxLevel = 0 -CoarsenTolerance = 1e-4 -RefineTolerance = 2e-1 diff --git a/appl/freeflow/navierstokes/channel_copy/2d/params_graded.input b/appl/freeflow/navierstokes/channel_copy/2d/params_graded.input deleted file mode 100644 index 0d15b9f..0000000 --- a/appl/freeflow/navierstokes/channel_copy/2d/params_graded.input +++ /dev/null @@ -1,69 +0,0 @@ -[TimeLoop] -DtInitial = 1 # [s] -TEnd = 2 # [s] - -[Helper.Grid] -UpperRight = 10 1 -Cells = 100 50 -Positions0 = 0 10 -Positions1 = 0 0.1 0.3 0.4 0.6 0.7 0.9 1 -Cells0 = 20 -Cells1 = 2 2 2 2 2 2 2 -Grading0 = 1 -Grading1 = 1 1 1 1 1 1 1 - -[finexCVs.Grid] -File = finexCVs.dgf - -[fineyCVs.Grid] -File = fineyCVs.dgf - -[coarsexCVs.Grid] -File = coarsexCVs.dgf - -[coarseyCVs.Grid] -File = coarseyCVs.dgf - -[Grid] -File = grid.dgf - -[Problem] -Name = graded # name passed to the output routines -InletVelocity = 1 -EnableGravity = false -EnableInertiaTerms = false -OutletCondition = Outflow -UseVelocityProfile = true -PrintErrors = true -IsStationary = true - -[Component] -MolarMass = 1.0 -LiquidDensity = 1.0 -LiquidKinematicViscosity = 1.0 - -[ Newton ] -MaxSteps = 10 -MaxRelativeShift = 1e-8 - -[FreeFlow] -EnableVelocityGradientFactor = false - -[Vtk] -WriteFaceData = true -Precision = Float64 - -[Assembly] -NumericDifference.BaseEpsilon = 1e-3 - -# This test does actually not require setting the primary variable magnitues. -# This rather serves as a demonstration of how to use the feature. -# [CellCenter.Assembly] -# NumericDifference.PriVarMagnitude = 1e5 # pressure is in the order of 1e5 - -[Face.Assembly] -# NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 - -[Adaptivity] -Conservation = false -Adapt = false diff --git a/appl/freeflow/navierstokes/channel_copy/2d/params_grading_add_dof_good.input b/appl/freeflow/navierstokes/channel_copy/2d/params_grading_add_dof_good.input deleted file mode 100644 index ce697b1..0000000 --- a/appl/freeflow/navierstokes/channel_copy/2d/params_grading_add_dof_good.input +++ /dev/null @@ -1,57 +0,0 @@ -[TimeLoop] -DtInitial = 1 # [s] -TEnd = 2 # [s] - -[Helper.Grid] -UpperRight = 10 1 -Cells = 100 50 -Positions0 = 0 10 -Positions1 = 0 0.1 0.9 1 -Cells0 = 20 -Cells1 = 3 16 2 -Grading0 = 1 -Grading1 = 1 1 1 - -[Grid] -File = grid.dgf - -[Problem] -Name = graded # name passed to the output routines -InletVelocity = 1 -EnableGravity = false -EnableInertiaTerms = false -OutletCondition = Outflow -UseVelocityProfile = true -PrintErrors = true -IsStationary = true - -[Component] -MolarMass = 1. -LiquidDensity = 1.0 -LiquidKinematicViscosity = 1.0 - -[ Newton ] -MaxSteps = 10 -MaxRelativeShift = 1e-8 - -[FreeFlow] -EnableVelocityGradientFactor = false - -[Vtk] -WriteFaceData = false# -Precision = Float64 - -[Assembly] -NumericDifference.BaseEpsilon = 1e-3 - -# This test does actually not require setting the primary variable magnitues. -# This rather serves as a demonstration of how to use the feature. -# [CellCenter.Assembly] -# NumericDifference.PriVarMagnitude = 1e5 # pressure is in the order of 1e5 - -[Face.Assembly] -# NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 - -[Adaptivity] -Conservation = false -Adapt = false diff --git a/appl/freeflow/navierstokes/channel_copy/2d/params_navierstokes.input b/appl/freeflow/navierstokes/channel_copy/2d/params_navierstokes.input deleted file mode 100644 index ab06b01..0000000 --- a/appl/freeflow/navierstokes/channel_copy/2d/params_navierstokes.input +++ /dev/null @@ -1,43 +0,0 @@ -[TimeLoop] -DtInitial = 1 # [s] -TEnd = 2 # [s] - -[Helper.Grid] -Positions0 = 0 10 -Positions1 = 0 1 -Cells0 = 10 -Cells1 = 5 -Grading0 = 1.0 -Grading1 = 1.0 - -[Grid] -File = grid.dgf - -[Problem] -Name = test_channel_navierstokes # name passed to the output routines -InletVelocity = 1000 -EnableGravity = false -PrintErrors = true -IsStationary = false - -[Component] -LiquidDensity = 1.0 -LiquidKinematicViscosity = 1.0 -MolarMass = 1.0 - -[ Newton ] -MaxSteps = 100 -MaxRelativeShift = 1e-5 -SatisfyResidualAndShiftCriterion = true -EnableAbsoluteResidualCriterion = true - -[Vtk] -WriteFaceData = false - -[Adaptivity] -Conservation = false -Adapt = true -LeftX = 2 -RightX = 8 -LowerY = 0.2 -UpperY = 0.8 diff --git a/appl/freeflow/navierstokes/channel_copy/2d/params_navierstokes_stationary.input b/appl/freeflow/navierstokes/channel_copy/2d/params_navierstokes_stationary.input deleted file mode 100644 index 968f8d2..0000000 --- a/appl/freeflow/navierstokes/channel_copy/2d/params_navierstokes_stationary.input +++ /dev/null @@ -1,72 +0,0 @@ -[Helper.Grid] -Positions0 = 0 10 -Positions1 = 0 1 -Cells0 = 15 -Cells1 = 6 -Grading0 = 1.0 -Grading1 = 1.0 - -[finexCVs.Grid] -File = finexCVs.dgf - -[fineyCVs.Grid] -File = fineyCVs.dgf - -[coarsexCVs.Grid] -File = coarsexCVs.dgf - -[coarseyCVs.Grid] -File = coarseyCVs.dgf - -[Grid] -File = grid.dgf - -[Problem] -Name = test_channel_navierstokes_stationary # name passed to the output routines -InletVelocity = 100 -EnableGravity = false -PrintErrors = true -EnableInertiaTerms = true -IsStationary = true -AveragedAnalyticalSolution = false - -[Component] -MolarMass = 1.0 -LiquidDensity = 1 -LiquidKinematicViscosity = 1 - -[ Newton ] -MaxSteps = 100 -MaxRelativeShift = 1e-4 -SatisfyResidualAndShiftCriterion = true -EnableAbsoluteResidualCriterion = true - -[Vtk] -WriteFaceData = false - -[Assembly] -NumericDifference.BaseEpsilon = 1e-8 - -# This test does actually not require setting the primary variable magnitues. -# This rather serves as a demonstration of how to use the feature. -[CellCenter.Assembly] -NumericDifference.PriVarMagnitude = 1e5 # pressure is in the order of 1e5 - -[Face.Assembly] -NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 - -[Adaptivity] -Conservation = false -Adapt = true -LeftX = 2 -RightX = 8 -LowerY = 0.2 -UpperY = 0.8 - -[Adaptive] -RefineAtDirichletBC = 0 -RefineAtFluxBC = 1 -MinLevel = 0 -MaxLevel = 0 -CoarsenTolerance = 1e-4 -RefineTolerance = 2e-1 diff --git a/appl/freeflow/navierstokes/channel_copy/2d/params_stokes.input b/appl/freeflow/navierstokes/channel_copy/2d/params_stokes.input deleted file mode 100644 index 9197ce7..0000000 --- a/appl/freeflow/navierstokes/channel_copy/2d/params_stokes.input +++ /dev/null @@ -1,67 +0,0 @@ -[TimeLoop] -DtInitial = 1 # [s] -TEnd = 2 # [s] - -[Helper.Grid] -Positions0 = 0 10 -Positions1 = 0 1 -Cells0 = 10 -Cells1 = 5 -Grading0 = 1.0 -Grading1 = 1.0 - -[Grid] -File = grid.dgf - -[finexCVs.Grid] -File = finexCVs.dgf - -[fineyCVs.Grid] -File = fineyCVs.dgf - -[coarsexCVs.Grid] -File = coarsexCVs.dgf - -[coarseyCVs.Grid] -File = coarseyCVs.dgf - -[Problem] -Name = test_channel_stokes # name passed to the output routines -InletVelocity = 1 -EnableGravity = false -EnableInertiaTerms = false -PrintErrors = true -IsStationary = false - -[Component] -MolarMass = 1.0 -LiquidDensity = 1 -LiquidKinematicViscosity = 1 - -[ Newton ] -MaxSteps = 100 -MaxRelativeShift = 1e-8 -SatisfyResidualAndShiftCriterion = true -EnableAbsoluteResidualCriterion = true - -[Vtk] -WriteFaceData = false - -[Assembly] -NumericDifference.BaseEpsilon = 1e-8 - -# This test does actually not require setting the primary variable magnitues. -# This rather serves as a demonstration of how to use the feature. -[CellCenter.Assembly] -NumericDifference.PriVarMagnitude = 1e5 # pressure is in the order of 1e5 - -[Face.Assembly] -NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 - -[Adaptivity] -Conservation = false -Adapt = true -LeftX = 3 -RightX = 5 -LowerY = 0.2 -UpperY = 0.6 diff --git a/appl/freeflow/navierstokes/channel_copy/2d/params_stokes_stationary.input b/appl/freeflow/navierstokes/channel_copy/2d/params_stokes_stationary.input deleted file mode 100644 index 09ef667..0000000 --- a/appl/freeflow/navierstokes/channel_copy/2d/params_stokes_stationary.input +++ /dev/null @@ -1,72 +0,0 @@ -[Helper.Grid] -Positions0 = 0 10 -Positions1 = 0 1 -Cells0 = 5 -Cells1 = 5 -Grading0 = 1.0 -Grading1 = 1.0 - -[finexCVs.Grid] -File = finexCVs.dgf - -[fineyCVs.Grid] -File = fineyCVs.dgf - -[coarsexCVs.Grid] -File = coarsexCVs.dgf - -[coarseyCVs.Grid] -File = coarseyCVs.dgf - -[Grid] -File = grid.dgf - -[Problem] -Name = test_channel_stokes_stationary # name passed to the output routines -InletVelocity = 1 -EnableGravity = false -EnableInertiaTerms = false -PrintErrors = true -IsStationary = true - -[Component] -MolarMass = 1.0 -LiquidDensity = 1 -LiquidKinematicViscosity = 1 - -[ Newton ] -MaxSteps = 100 -MaxRelativeShift = 1e-15 -SatisfyResidualAndShiftCriterion = true -EnableAbsoluteResidualCriterion = true - -[Vtk] -WriteFaceData = false - -[Assembly] -NumericDifference.BaseEpsilon = 1e-8 - -# This test does actually not require setting the primary variable magnitues. -# This rather serves as a demonstration of how to use the feature. -[CellCenter.Assembly] -NumericDifference.PriVarMagnitude = 1e5 # pressure is in the order of 1e5 - -[Face.Assembly] -NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 - -[Adaptivity] -Conservation = false -Adapt = true -LeftX = 4 -RightX = 6 -LowerY = .4 -UpperY = .6 - - -[Adaptive] -RefineAtDirichletBC = 0 -RefineAtFluxBC = 1 -MinLevel = 0 -MaxLevel = 0 -CoarsenTolerance = 1e-4 -RefineTolerance = 2e-1 diff --git a/appl/freeflow/navierstokes/channel_copy/2d/params_stokes_stationary_fvcaGrid.input b/appl/freeflow/navierstokes/channel_copy/2d/params_stokes_stationary_fvcaGrid.input deleted file mode 100644 index 13efb63..0000000 --- a/appl/freeflow/navierstokes/channel_copy/2d/params_stokes_stationary_fvcaGrid.input +++ /dev/null @@ -1,71 +0,0 @@ -[Helper.Grid] -Positions0 = 0 1 -Positions1 = 0 1 -Cells0 = 4 -Cells1 = 4 -Grading0 = 1.0 -Grading1 = 1.0 - -[finexCVs.Grid] -File = finexCVs.dgf - -[fineyCVs.Grid] -File = fineyCVs.dgf - -[coarsexCVs.Grid] -File = coarsexCVs.dgf - -[coarseyCVs.Grid] -File = coarseyCVs.dgf - -[Grid] -File = grid.dgf -FVCAGrid = true - -[Problem] -Name = test_channel_fvca # name passed to the output routines -InletVelocity = 1 -EnableGravity = false -EnableInertiaTerms = false -PrintErrors = true -IsStationary = true - -[Component] -MolarMass = 1.0 -LiquidDensity = 1 -LiquidKinematicViscosity = 1 - -[ Newton ] -MaxSteps = 100 -MaxRelativeShift = 1e-15 - -[Vtk] -WriteFaceData = false - -[Assembly] -NumericDifference.BaseEpsilon = 1e-8 - -# This test does actually not require setting the primary variable magnitues. -# This rather serves as a demonstration of how to use the feature. -[CellCenter.Assembly] -NumericDifference.PriVarMagnitude = 1e5 # pressure is in the order of 1e5 - -[Face.Assembly] -NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 - -[Adaptivity] -Conservation = true -Adapt = true -LeftX = 4 -RightX = 6 -LowerY = .4 -UpperY = .6 - - -[Adaptive] -RefineAtDirichletBC = 0 -RefineAtFluxBC = 1 -MinLevel = 0 -MaxLevel = 0 -CoarsenTolerance = 1e-4 -RefineTolerance = 2e-1 diff --git a/appl/freeflow/navierstokes/channel_copy/2d/params_uniform.input b/appl/freeflow/navierstokes/channel_copy/2d/params_uniform.input deleted file mode 100644 index 978b64b..0000000 --- a/appl/freeflow/navierstokes/channel_copy/2d/params_uniform.input +++ /dev/null @@ -1,57 +0,0 @@ -[TimeLoop] -DtInitial = 1 # [s] -TEnd = 2 # [s] - -[Helper.Grid] -UpperRight = 10 1 -Cells = 100 50 -Positions0 = 0 10 -Positions1 = 0 1 -Cells0 = 20 -Cells1 = 20 -Grading0 = 1 -Grading1 = 1 - -[Grid] -File = grid.dgf - -[Problem] -Name = uniform # name passed to the output routines -InletVelocity = 1 -EnableGravity = false -EnableInertiaTerms = false -OutletCondition = Outflow -UseVelocityProfile = true -PrintErrors = true -IsStationary = true - -[Component] -MolarMass = 1.0 -LiquidDensity = 1.0 -LiquidKinematicViscosity = 1.0 - -[ Newton ] -MaxSteps = 10 -MaxRelativeShift = 1e-8 - -[FreeFlow] -EnableVelocityGradientFactor = false - -[Vtk] -WriteFaceData = false -Precision = Float64 - -[Assembly] -NumericDifference.BaseEpsilon = 1e-3 - -# This test does actually not require setting the primary variable magnitues. -# This rather serves as a demonstration of how to use the feature. -# [CellCenter.Assembly] -# NumericDifference.PriVarMagnitude = 1e5 # pressure is in the order of 1e5 - -[Face.Assembly] -# NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 - -[Adaptivity] -Conservation = false -Adapt = false diff --git a/appl/freeflow/navierstokes/channel_copy/2d/problem.hh b/appl/freeflow/navierstokes/channel_copy/2d/problem.hh deleted file mode 100644 index 726b595..0000000 --- a/appl/freeflow/navierstokes/channel_copy/2d/problem.hh +++ /dev/null @@ -1,588 +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 - * \ingroup NavierStokesTests - * \brief Channel flow test for the staggered grid (Navier-)Stokes model - */ -#ifndef DUMUX_CHANNEL_TEST_PROBLEM_HH -#define DUMUX_CHANNEL_TEST_PROBLEM_HH - -#include <dune/alugrid/grid.hh> -#include <dune/grid/yaspgrid.hh> -#include <dune/subgrid/subgrid.hh> - -#include <dumux/assembly/cvdstaggeredrefinedlocalresidual.hh> - -#include <dumux/common/numeqvector.hh> - -#include <dumux/material/fluidsystems/1pliquid.hh> -#include <dumux/material/components/simpleh2o.hh> -#include <dumux/material/components/constant.hh> - -#include <dumux/freeflow/navierstokes/boundarytypes.hh> -#include <dumux/freeflow/navierstokes/cvdproblem.hh> -#include <dumux/freeflow/navierstokes/model.hh> -#include <dumux/freeflow/navierstokes/cvdlocalresidual.hh> -#include <dumux/freeflow/navierstokes/cvdfluxvariableswrapper.hh> -#include <dumux/freeflow/navierstokes/myvolumevariables.hh> -#include <dumux/freeflow/navierstokes/myiofields.hh> - -#include <dumux/discretization/staggered/freeflow/properties.hh> -#include <dumux/discretization/staggered/freeflow/myfacevariables.hh> -#include <dumux/discretization/staggered/freeflow/cvdlocalfacevariables.hh> -#include <dumux/discretization/staggered/cvdlocalgridfacevariables.hh> -#include <dumux/discretization/staggered/freeflow/myvelocityoutput.hh> -#include <dumux/discretization/staggered/freeflow/mygridvolumevariables.hh> -#include <dumux/discretization/staggered/freeflow/elementvolumevariables1.hh> -#include <dumux/discretization/staggered/mygridfluxvariablescache.hh> -#include <dumux/discretization/staggered/myfacesolution.hh> -#include <dumux/discretization/staggered/cvdelementfacesolution.hh> -#include <dumux/discretization/staggered/cvdgridvariables.hh> -#include <dumux/discretization/staggered/cvdfvgridgeometry.hh> -#include <dumux/discretization/staggered/freeflow/cvdfvgridgeometrytraits.hh> - -namespace Dumux -{ -template <class TypeTag> -class ChannelTestProblem; - -namespace Properties -{ -namespace TTag { -#if !NONISOTHERMAL -// Create new type tags -struct ChannelTestTypeTag { using InheritsFrom = std::tuple<NavierStokes, StaggeredFreeFlowModel>; }; -} // end namespace TTag -#else -struct ChannelTestTypeTag { using InheritsFrom = std::tuple<NavierStokesNI, StaggeredFreeFlowModel>; }; -} // end namespace TTag -#endif - -// the fluid system -template<class TypeTag> -struct FluidSystem<TypeTag, TTag::ChannelTestTypeTag> -{ - using Scalar = GetPropType<TypeTag, Properties::Scalar>; -#if NONISOTHERMAL - using type = FluidSystems::OnePLiquid<Scalar, Components::SimpleH2O<Scalar> >; -#else - using type = FluidSystems::OnePLiquid<Scalar, Components::Constant<1, Scalar> >; -#endif -}; - -// Set the grid type -template<class TypeTag> -struct Grid<TypeTag, TTag::ChannelTestTypeTag> -{ - using HostGrid = Dune::ALUGrid<2,2,Dune::cube,Dune::nonconforming >; - using type = Dune::SubGrid<HostGrid::dimension, HostGrid>; -}; - -template<class TypeTag, class MyTypeTag> -struct HelpingGrid { using type = UndefinedProperty; }; - -// Set the grid type -template<class TypeTag> -struct HelpingGrid<TypeTag, TTag::ChannelTestTypeTag> -{ - using type = Dune::YaspGrid<2,Dune::TensorProductCoordinates<double, 2>>; -}; - -// Set the problem property -template<class TypeTag> -struct Problem<TypeTag, TTag::ChannelTestTypeTag> { using type = Dumux::ChannelTestProblem<TypeTag> ; }; - -template<class TypeTag> -struct EnableGridGeometryCache<TypeTag, TTag::ChannelTestTypeTag> { static constexpr bool value = true; }; - -template<class TypeTag> -struct EnableGridFluxVariablesCache<TypeTag, TTag::ChannelTestTypeTag> { static constexpr bool value = true; }; -template<class TypeTag> -struct EnableGridVolumeVariablesCache<TypeTag, TTag::ChannelTestTypeTag> { static constexpr bool value = true; }; - -//! The variables living on the faces -template<class TypeTag> -struct FaceVariables<TypeTag, TTag::ChannelTestTypeTag> -{ -private: - using FacePrimaryVariables = GetPropType<TypeTag, Properties::FacePrimaryVariables>; - using GridView = typename GetPropType<TypeTag, Properties::GridGeometry>::GridView; - static constexpr auto upwindSchemeOrder = getPropValue<TypeTag, Properties::UpwindSchemeOrder>(); - using ModelTraits = GetPropType<TypeTag, Properties::ModelTraits>; -public: - using type = MyStaggeredFaceVariables<ModelTraits, FacePrimaryVariables, GridView::dimension, upwindSchemeOrder>; -}; - -template<class TypeTag> -struct LocalFaceVariables<TypeTag, TTag::ChannelTestTypeTag> -{ -private: - using FacePrimaryVariables = GetPropType<TypeTag, Properties::FacePrimaryVariables>; -public: - using type = CVDStaggeredLocalFaceVariables<FacePrimaryVariables>; -}; - -//! The velocity output -template<class TypeTag> -struct VelocityOutput<TypeTag, TTag::ChannelTestTypeTag> -{ - using type = MyStaggeredFreeFlowVelocityOutput<GetPropType<TypeTag, Properties::GridVariables>, - GetPropType<TypeTag, Properties::SolutionVector>>; -}; - -//! Set the volume variables property -template<class TypeTag> -struct DualCVsVolVars<TypeTag, TTag::ChannelTestTypeTag> -{ -private: - using VV = GetPropType<TypeTag, Properties::VolumeVariables>; - using GridView = typename GetPropType<TypeTag, Properties::GridGeometry>::GridView; - static constexpr auto dimWorld = GridView::dimensionworld; - static constexpr int numPairs = 2 * (dimWorld - 1); - -public: - using type = NavierStokesDualCVsVolVars<VV, numPairs>; -}; - -//! Set the volume variables property -template<class TypeTag> -struct PrimalCVsVolVars<TypeTag, TTag::ChannelTestTypeTag> -{ -public: - using VolumeVariables = GetPropType<TypeTag, Properties::VolumeVariables>; - using type = std::array<NaviesStokesPrimalScvfPair<VolumeVariables>,8>;//TODO make work for dim != 2 -}; - -//! Set the default global volume variables cache vector class -template<class TypeTag> -struct GridVolumeVariables<TypeTag, TTag::ChannelTestTypeTag> -{ -private: - using Problem = GetPropType<TypeTag, Properties::Problem>; - using VolumeVariables = GetPropType<TypeTag, Properties::VolumeVariables>; - using DualCVsVolVars = GetPropType<TypeTag, Properties::DualCVsVolVars>; - using PrimalCVsVolVars = GetPropType<TypeTag, Properties::PrimalCVsVolVars>; - using GridView = typename GetPropType<TypeTag, Properties::GridGeometry>::GridView; - using SubControlVolume = typename GetPropType<TypeTag, Properties::GridGeometry>::SubControlVolume; - using SubControlVolumeFace = typename GetPropType<TypeTag, Properties::GridGeometry>::SubControlVolumeFace; - static constexpr auto enableCache = getPropValue<TypeTag, Properties::EnableGridVolumeVariablesCache>(); - using Traits = MyStaggeredGridDefaultGridVolumeVariablesTraits<Problem, PrimalCVsVolVars, DualCVsVolVars, VolumeVariables, GridView, SubControlVolume, SubControlVolumeFace>; -public: - using type = MyStaggeredGridVolumeVariables<Traits, enableCache>; -}; - -//! Set the BaseLocalResidual to StaggeredLocalResidual -template<class TypeTag> -struct BaseLocalResidual<TypeTag, TTag::ChannelTestTypeTag> { using type = StaggeredRefinedLocalResidual<TypeTag>; }; - -//! Set the face solution type -template<class TypeTag> -struct StaggeredFaceSolution<TypeTag, TTag::ChannelTestTypeTag> -{ -private: - using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; -public: - using type = Dumux::MyStaggeredFaceSolution<FaceSolutionVector>; -}; - -template<class TypeTag> -struct ElementFaceSolution<TypeTag, TTag::ChannelTestTypeTag> -{ -private: - using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; -public: - using type = Dumux::CVDElementFaceSolution<FaceSolutionVector>; -}; - -//! Set the GridLocalFaceVariables -template<class TypeTag> -struct GridLocalFaceVariables<TypeTag, TTag::ChannelTestTypeTag> -{ - private: - using Problem = GetPropType<TypeTag, Properties::Problem>; - using LocalFaceVariables = GetPropType<TypeTag, Properties::LocalFaceVariables>; - static constexpr auto enableCache = getPropValue<TypeTag, Properties::EnableGridFaceVariablesCache>(); - public: - using type = CVDStaggeredLocalGridFaceVariables<Problem, LocalFaceVariables, enableCache>; -}; - -//! Set the grid variables (volume, flux and face variables) -template<class TypeTag> -struct GridVariables<TypeTag, TTag::ChannelTestTypeTag> -{ -private: - using GG = GetPropType<TypeTag, Properties::GridGeometry>; - using GVV = GetPropType<TypeTag, Properties::GridVolumeVariables>; - using GFVC = GetPropType<TypeTag, Properties::GridFluxVariablesCache>; - using GFV = GetPropType<TypeTag, Properties::GridFaceVariables>; - using GLFV = GetPropType<TypeTag, Properties::GridLocalFaceVariables>; -public: - using type = CVDStaggeredGridVariables<GG, GVV, GFVC, GFV, GLFV>; -}; - -//! The default fv grid geometry -template<class TypeTag> -struct GridGeometry<TypeTag, TTag::ChannelTestTypeTag> -{ -private: - static constexpr auto upwindSchemeOrder = getPropValue<TypeTag, Properties::UpwindSchemeOrder>(); - static constexpr bool enableCache = getPropValue<TypeTag, Properties::EnableGridGeometryCache>(); - using GridView = typename GetPropType<TypeTag, Properties::Grid>::LeafGridView; - using Traits = CVDStaggeredFreeFlowDefaultGridGeometryTraits<GridView, upwindSchemeOrder>; -public: - using type = CVDStaggeredGridGeometry<GridView, enableCache, Traits>; -}; - -template<class TypeTag> -struct CVGridGeometry<TypeTag, TTag::ChannelTestTypeTag> -{ -private: - static constexpr auto upwindSchemeOrder = getPropValue<TypeTag, Properties::UpwindSchemeOrder>(); - static constexpr bool enableCache = getPropValue<TypeTag, Properties::EnableGridGeometryCache>(); - using GridView = typename Dune::ALUGrid<2,2,Dune::cube,Dune::nonconforming >::LeafGridView; - using Traits = CVDStaggeredFreeFlowDefaultGridGeometryTraits<GridView, upwindSchemeOrder>; -public: - using type = CVDStaggeredGridGeometry<GridView, enableCache, Traits>; -}; - -//! Set the volume variables property -template<class TypeTag> -struct VolumeVariables<TypeTag, TTag::ChannelTestTypeTag> -{ -private: - using PV = GetPropType<TypeTag, Properties::PrimaryVariables>; - using FSY = GetPropType<TypeTag, Properties::FluidSystem>; - using FST = GetPropType<TypeTag, Properties::FluidState>; - using MT = GetPropType<TypeTag, Properties::ModelTraits>; - - static_assert(FSY::numPhases == MT::numFluidPhases(), "Number of phases mismatch between model and fluid system"); - static_assert(FST::numPhases == MT::numFluidPhases(), "Number of phases mismatch between model and fluid state"); - static_assert(!FSY::isMiscible(), "The Navier-Stokes model only works with immiscible fluid systems."); - - using Traits = NavierStokesVolumeVariablesTraits<PV, FSY, FST, MT>; -public: - using type = MyNavierStokesVolumeVariables<Traits>; -}; - -//! The local residual -template<class TypeTag> -struct LocalResidual<TypeTag, TTag::ChannelTestTypeTag> { using type = RefinedNavierStokesResidual<TypeTag>; }; - -//! The flux variables -template<class TypeTag> -struct FluxVariables<TypeTag, TTag::ChannelTestTypeTag> { using type = RefinedNavierStokesFluxVariables<TypeTag>; }; - -//! The specific I/O fields -template<class TypeTag> -struct IOFields<TypeTag, TTag::ChannelTestTypeTag> { -#if NONISOTHERMAL - using type = FreeflowNonIsothermalIOFields<MyNavierStokesIOFields>; -#else - using type = MyNavierStokesIOFields; -#endif -}; - -//! Set the global flux variables cache vector class -template<class TypeTag> -struct GridFluxVariablesCache<TypeTag, TTag::ChannelTestTypeTag> -{ -private: - using Problem = GetPropType<TypeTag, Properties::Problem>; - using FluxVariablesCache = GetPropType<TypeTag, Properties::FluxVariablesCache>; - using FluxVariablesCacheFiller = GetPropType<TypeTag, Properties::FluxVariablesCacheFiller>; - static constexpr auto enableCache = getPropValue<TypeTag, Properties::EnableGridFluxVariablesCache>(); - static constexpr auto upwindSchemeOrder = getPropValue<TypeTag, Properties::UpwindSchemeOrder>(); -public: - using type = MyStaggeredGridFluxVariablesCache<Problem, FluxVariablesCache, FluxVariablesCacheFiller, enableCache, upwindSchemeOrder>; -}; -} - -/*! - * \ingroup NavierStokesTests - * \brief Test problem for the one-phase (Navier-) Stokes problem in a channel. - * \todo doc me! - */ -template <class TypeTag> -class ChannelTestProblem : public MyNavierStokesProblem<TypeTag> -{ - using ParentType = MyNavierStokesProblem<TypeTag>; - - using BoundaryTypes = Dumux::NavierStokesBoundaryTypes<GetPropType<TypeTag, Properties::ModelTraits>::numEq()>; - using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; - using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; - using ModelTraits = GetPropType<TypeTag, Properties::ModelTraits>; - using NumEqVector = Dumux::NumEqVector<GetPropType<TypeTag, Properties::PrimaryVariables>>; - using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>; - using Scalar = GetPropType<TypeTag, Properties::Scalar>; - using SolutionVector = GetPropType<TypeTag, Properties::SolutionVector>; - using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; - using FVElementGeometry = typename GridGeometry::LocalView; - using SubControlVolume = typename GridGeometry::SubControlVolume; - using SubControlVolumeFace = typename GetPropType<TypeTag, Properties::GridGeometry>::SubControlVolumeFace; - - static constexpr auto dimWorld = GetPropType<TypeTag, Properties::GridGeometry>::GridView::dimensionworld; - - using Element = typename GridGeometry::GridView::template Codim<0>::Entity; - using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - using VelocityVector = Dune::FieldVector<Scalar, dimWorld>; - - using TimeLoopPtr = std::shared_ptr<CheckPointTimeLoop<Scalar>>; - -public: - ChannelTestProblem(std::shared_ptr<const GridGeometry> gridGeometry) - : ParentType(gridGeometry), eps_(1e-6) - { - dynamicViscosity_ = getParam<Scalar>("Component.LiquidKinematicViscosity", 1.0) * getParam<Scalar>("Component.LiquidDensity", 1.0); - inletVelocity_ = getParam<Scalar>("Problem.InletVelocity"); - - const Scalar xMin = this->gridGeometry().bBoxMin()[0]; - const Scalar xMax = this->gridGeometry().bBoxMax()[0]; - const Scalar yMin = this->gridGeometry().bBoxMin()[1]; - const Scalar yMax = this->gridGeometry().bBoxMax()[1]; - - velocityQuadraticCoefficient_ = - inletVelocity_ / (0.25*(yMax - yMin)*(yMax - yMin)); - velocityLinearCoefficient_ = velocityQuadraticCoefficient_ * (-yMax - yMin); - velocityConstant_ = velocityQuadraticCoefficient_ * yMin * yMax; - pressureLinearCoefficient_ = 2. * velocityQuadraticCoefficient_ * dynamicViscosity_; - pressureConstant_ = -pressureLinearCoefficient_ *.5 * (xMax - xMin); - } - - /*! - * \name Problem parameters - */ - // \{ - - - bool shouldWriteRestartFile() const - { - return false; - } - - /*! - * \brief Return the temperature within the domain in [K]. - * - * This problem assumes a temperature of 10 degrees Celsius. - */ - Scalar temperature() const - { return 273.15 + 10; } // 10C - - /*! - * \brief Return the sources within the domain. - * - * \param globalPos The global position - */ - NumEqVector sourceAtPos(const GlobalPosition &globalPos) const - { - return NumEqVector(0.0); - } - // \} - /*! - * \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 values; - - values.setDirichlet(Indices::velocityXIdx); - values.setDirichlet(Indices::velocityYIdx); - - return values; - } - - bool isDirichletCell(const Element& element, - const FVElementGeometry& fvGeometry, - const SubControlVolume& scv, - int pvIdx) const - { - // set fixed pressure in one cell - return (scv.dofIndex() == 0) && pvIdx == Indices::pressureIdx; - } - - /*! - * \brief Evaluate the boundary conditions for a dirichlet - * control volume face (velocities) - * - * \param element The finite element - * \param scvf the sub control volume face - * - * Concerning the usage of averaged velocity, see the explanation of the initial function. The average of the nondirection velocity along an scvf is required in the context of dirichlet boundary conditions for the functions getParallelVelocityFromBoundary_ and getParallelVelocityFromOtherBoundary_ within myfluxvariables.hh. There dirichlet is called for ghost faces built from the normalFace but the value then is taken in the the direction scvf.directionIndex, which is along that normalFace. - */ - PrimaryVariables dirichlet(const Element& element, const SubControlVolumeFace& scvf) const - { - PrimaryVariables priVars(0.0); - - unsigned int dirIdx = scvf.directionIndex(); - priVars[Indices::velocity(dirIdx)] = this->analyticalVelocitySolutionAtPos(scvf); - unsigned int nonDirIdx = (dirIdx == 0)?1:0; - priVars[Indices::velocity(nonDirIdx)] = this->analyticalNonDirVelocitySolutionAtPos(scvf); - - return priVars; - } - - /*! - * \brief Evaluate the boundary conditions for a dirichlet - * control volume face (pressure) - * - * \param element The finite element - * \param scv the sub control volume - */ - PrimaryVariables dirichlet(const Element& element, const SubControlVolume& scv) const - { - PrimaryVariables priVars(0.0); - priVars[Indices::pressureIdx] = this->analyticalPressureSolutionAtPos(scv); - return priVars; - } - - /*! - * \brief Return the analytical solution of the problem at a given position - * - * \param globalPos The global position - */ - PrimaryVariables analyticalSolutionAtPos(const GlobalPosition& globalPos) const - { - PrimaryVariables values; - - Scalar x = globalPos[0]; - Scalar y = globalPos[1]; - - values[Indices::pressureIdx] = f1_(x); - values[Indices::velocityXIdx] = f2_(y); - values[Indices::velocityYIdx] = 0.; - - return values; - } - - /*! - * \name Volume terms - */ - // \{ - - /*! - * \brief Evaluates the initial value for a sub control volume face (velocities) - * - * Simply assigning the value of the analytical solution at the face center - * gives a discrete solution that is not divergence-free. For small initial - * time steps, this has a negative impact on the pressure solution - * after the first time step. The flag UseVelocityAveraging triggers the - * function averagedVelocity_ which uses a higher order quadrature formula to - * bring the discrete solution sufficiently close to being divergence-free. - */ - PrimaryVariables initial(const SubControlVolumeFace& scvf) const - { - bool startWithAnalytical = getParam<bool>("Problem.StartWithAnalytical", false); - - if (startWithAnalytical) - { - PrimaryVariables priVars(0.0); - priVars[Indices::velocity(scvf.directionIndex())] = this->analyticalVelocitySolutionAtPos(scvf); - return priVars; - } - else - { - PrimaryVariables values; - values[Indices::pressureIdx] = 0.0; - values[Indices::velocityXIdx] = 0.0; - values[Indices::velocityYIdx] = 0.0; - - return values; - } - } - - /*! - * \brief Evaluates the initial value for a control volume (pressure) - */ - PrimaryVariables initial(const SubControlVolume& scv) const - { - bool startWithAnalytical = getParam<bool>("Problem.StartWithAnalytical", false); - - if (startWithAnalytical) - { - PrimaryVariables priVars(0.0); - priVars[Indices::pressureIdx] = this->analyticalPressureSolutionAtPos(scv); - return priVars; - } - else - { - PrimaryVariables values; - values[Indices::pressureIdx] = 0.0; - values[Indices::velocityXIdx] = 0.0; - values[Indices::velocityYIdx] = 0.0; - - return values; - } - } - - // \} - void setTimeLoop(TimeLoopPtr timeLoop) - { - timeLoop_ = timeLoop; - if(inletVelocity_ > eps_) - timeLoop_->setCheckPoint({200.0, 210.0}); - } - - Scalar time() const - { - return timeLoop_->time(); - } - -private: - bool isInlet(const GlobalPosition& globalPos) const - { - return globalPos[0] < eps_; - } - - bool isOutlet(const GlobalPosition& globalPos) const - { - return globalPos[0] > this->gridGeometry().bBoxMax()[0] - eps_; - } - - bool isWall(const GlobalPosition& globalPos) const - { - return globalPos[0] > eps_ || globalPos[0] < this->gridGeometry().bBoxMax()[0] - eps_; - } - - Scalar f1_(Scalar x) const - { return pressureLinearCoefficient_ * x + pressureConstant_; } - - Scalar f2_(Scalar y) const - { return velocityQuadraticCoefficient_ * y * y + velocityLinearCoefficient_ * y + velocityConstant_; } - - Scalar eps_; - Scalar dynamicViscosity_; - Scalar inletVelocity_; - TimeLoopPtr timeLoop_; - - Scalar velocityQuadraticCoefficient_; - Scalar velocityLinearCoefficient_; - Scalar velocityConstant_; - Scalar pressureLinearCoefficient_; - Scalar pressureConstant_; -}; -} //end namespace - -#endif diff --git a/appl/freeflow/navierstokes/channel_copy/CMakeLists.txt b/appl/freeflow/navierstokes/channel_copy/CMakeLists.txt deleted file mode 100644 index 5c4cec9..0000000 --- a/appl/freeflow/navierstokes/channel_copy/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -add_subdirectory(2d) -- GitLab From cb8c2e1b496f7a8e4fb4e7bfa816656e8067d952 Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Tue, 14 Sep 2021 15:07:56 +0300 Subject: [PATCH 32/69] Added sincos_copy --- appl/freeflow/navierstokes/CMakeLists.txt | 2 +- .../navierstokes/sincos_copy/CMakeLists.txt | 31 + .../freeflow/navierstokes/sincos_copy/main.cc | 431 +++++++++++ .../navierstokes/sincos_copy/params.input | 79 ++ .../sincos_copy/paramsVanDerPlas.input | 59 ++ .../sincos_copy/params_grading.input | 65 ++ .../params_grading_add_dof_bad.input | 65 ++ .../sincos_copy/params_uniform.input | 65 ++ .../sincos_copy/params_vdP_full.input | 79 ++ .../sincos_copy/params_vdP_full_vdP.input | 63 ++ .../sincos_copy/params_vdP_lin.input | 62 ++ .../sincos_copy/params_vdP_unrefined.input | 62 ++ .../navierstokes/sincos_copy/problem.hh | 720 ++++++++++++++++++ 13 files changed, 1782 insertions(+), 1 deletion(-) create mode 100644 appl/freeflow/navierstokes/sincos_copy/CMakeLists.txt create mode 100644 appl/freeflow/navierstokes/sincos_copy/main.cc create mode 100644 appl/freeflow/navierstokes/sincos_copy/params.input create mode 100644 appl/freeflow/navierstokes/sincos_copy/paramsVanDerPlas.input create mode 100644 appl/freeflow/navierstokes/sincos_copy/params_grading.input create mode 100644 appl/freeflow/navierstokes/sincos_copy/params_grading_add_dof_bad.input create mode 100644 appl/freeflow/navierstokes/sincos_copy/params_uniform.input create mode 100644 appl/freeflow/navierstokes/sincos_copy/params_vdP_full.input create mode 100644 appl/freeflow/navierstokes/sincos_copy/params_vdP_full_vdP.input create mode 100644 appl/freeflow/navierstokes/sincos_copy/params_vdP_lin.input create mode 100644 appl/freeflow/navierstokes/sincos_copy/params_vdP_unrefined.input create mode 100644 appl/freeflow/navierstokes/sincos_copy/problem.hh diff --git a/appl/freeflow/navierstokes/CMakeLists.txt b/appl/freeflow/navierstokes/CMakeLists.txt index 718c8c5..f74e1ad 100644 --- a/appl/freeflow/navierstokes/CMakeLists.txt +++ b/appl/freeflow/navierstokes/CMakeLists.txt @@ -1,4 +1,4 @@ add_subdirectory(donea) add_subdirectory(channel) -add_subdirectory(sincos) +add_subdirectory(sincos_copy) add_subdirectory(angeli) diff --git a/appl/freeflow/navierstokes/sincos_copy/CMakeLists.txt b/appl/freeflow/navierstokes/sincos_copy/CMakeLists.txt new file mode 100644 index 0000000..98ad3fb --- /dev/null +++ b/appl/freeflow/navierstokes/sincos_copy/CMakeLists.txt @@ -0,0 +1,31 @@ +set(CMAKE_BUILD_TYPE Debug) + +add_input_file_links() + +dune_add_test(NAME test_ff_sincos + SOURCES main.cc + LABELS freeflow + TIMEOUT 1000 + CMAKE_GUARD HAVE_UMFPACK + COMMAND ./convergencetest.py + CMD_ARGS test_ff_navierstokes_sincos params.input + -Grid.UpperRight "6.28 6.28" + -Grid.Cells "150 150" + -Problem.Name test_ff_navierstokes_sincos_stationary_convergence + -Problem.IsStationary true + -Component.LiquidKinematicViscosity 0.001) + +dune_add_test(NAME test_ff_navierstokes_sincos_instationary + TARGET test_ff_sincos + LABELS freeflow + CMAKE_GUARD HAVE_UMFPACK + COMMAND ${CMAKE_SOURCE_DIR}/bin/testing/runtest.py + CMD_ARGS --script fuzzy + --files ${CMAKE_SOURCE_DIR}/../dumux/test/references/test_ff_navierstokes_sincos_instationary-reference.vtu + ${CMAKE_CURRENT_BINARY_DIR}/test_ff_navierstokes_sincos_instationary-00017.vtu + --command "${CMAKE_CURRENT_BINARY_DIR}/test_ff_navierstokes_sincos params.input + -Grid.UpperRight '1 1' + -Grid.Cells '50 50' + -Problem.Name test_ff_navierstokes_sincos_instationary + -Problem.IsStationary false + -Component.LiquidKinematicViscosity 0.1") diff --git a/appl/freeflow/navierstokes/sincos_copy/main.cc b/appl/freeflow/navierstokes/sincos_copy/main.cc new file mode 100644 index 0000000..aa1e94b --- /dev/null +++ b/appl/freeflow/navierstokes/sincos_copy/main.cc @@ -0,0 +1,431 @@ +// -*- 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 3 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 + * \ingroup NavierStokesTests + * \brief Test for the instationary staggered grid Navier-Stokes model + * with analytical solution. + */ + +bool doFirstOrderLocalTruncErrorGlobalRefinement = false; + +#include <config.h> + +#include <ctime> +#include <iostream> +#include <type_traits> +#include <tuple> + +#include <dumux/common/dumuxmessage.hh> +#include <dumux/common/parameters.hh> +#include <dumux/common/properties.hh> + +#include <dune/common/parallel/mpihelper.hh> +#include <dune/common/timer.hh> +#include <dune/grid/io/file/vtk/vtkwriter.hh> +#include <dune/grid/io/file/dgfparser/dgfwriter.hh> +#include <dune/grid/io/file/dgfparser/dgfexception.hh> +#include <dune/grid/io/file/vtk.hh> + +namespace Dumux { +namespace Properties { +template<class TypeTag, class MyTypeTag> +struct FaceVolumeVariables { using type = UndefinedProperty; }; //!< The secondary variables within a sub-control volume +} +} + +#include <dumux/assembly/cvdstaggeredrefinedfvassembler.hh> +#include <dumux/assembly/diffmethod.hh> + +#include <dumux/io/grid/gridmanager.hh> +#include <dumux/io/grid/cvdcontrolvolumegrids.hh> +#include <dumux/io/mystaggeredvtkoutputmodule.hh> +#include <dumux/linear/seqsolverbackend.hh> +#include <dumux/nonlinear/newtonsolver.hh> + +#include <dumux/adaptive/adapt.hh> +#include <dumux/adaptive/markelements.hh> + +#include <dumux/freeflow/cvdgridadaptindicator.hh> +#include <dumux/freeflow/navierstokes/staggered/griddatatransfer.hh> + +#include <dumux/discretization/staggered/cvdfvgridgeometry.hh> +#include <dumux/discretization/staggered/freeflow/cvdfvgridgeometrytraits.hh> + +#include <dumux/freeflow/navierstokes/staggered/cvdresidualCalc.hh> +#include <dumux/io/cvdoutputFacility.hh> + +#include "problem.hh" + +template<class Problem> +auto createSource(const Problem& problem) +{ + using Scalar = double; + using Indices = typename Problem::Indices; + + const auto& gridGeometry = problem.gridGeometry(); + std::array<std::vector<Scalar>, Problem::ModelTraits::numEq()> source; + + for (auto& component : source) + { + component.resize(gridGeometry.numCellCenterDofs()); + } + + for (const auto& element : elements(gridGeometry.gridView())) + { + auto fvGeometry = localView(gridGeometry); + fvGeometry.bindElement(element); + for (auto&& scv : scvs(fvGeometry)) + { + auto ccDofIdx = scv.dofIndex(); + auto ccDofPosition = scv.dofPosition(); + + auto sourceAtPosVal = problem.sourceAtPos(ccDofPosition); + + source[Indices::momentumXBalanceIdx][ccDofIdx] = sourceAtPosVal[Indices::momentumXBalanceIdx]; + source[Indices::momentumYBalanceIdx][ccDofIdx] = sourceAtPosVal[Indices::momentumYBalanceIdx]; + } + } + + return source; +} + +int main(int argc, char** argv) try +{ + using namespace Dumux; + + // define the type tag for this problem + using TypeTag = Properties::TTag::SincosTest; + + // 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); + + bool adapt = getParam<bool>("Adaptivity.Adapt", false); + bool doFirstOrderLocalTruncError = getParam<bool>("Numerics.DoFirstOrderLocalTruncError", false); + //when adapt is true refinement is local, not only global + doFirstOrderLocalTruncErrorGlobalRefinement = !adapt && doFirstOrderLocalTruncError; + + using HelpingGridManager = Dumux::GridManager<GetPropType<TypeTag, Properties::HelpingGrid>>; + HelpingGridManager helpingGridManager; + helpingGridManager.init("Helper"); + const auto& helpingGridView = helpingGridManager.grid().leafGridView(); + Dune::DGFWriter dgfWriter(helpingGridView); + std::string inputFileName = getParam<std::string>("Grid.File"); + dgfWriter.write(inputFileName); + + // 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(); + + using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; + using GridView = typename GridGeometry::GridView; + using Element = typename GridView::template Codim<0>::Entity; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + + if (adapt) + { + using Scalar = GetPropType<TypeTag, Properties::Scalar>; + + Scalar leftX = getParam<Scalar>("Adaptivity.LeftX"); + Scalar rightX = getParam<Scalar>("Adaptivity.RightX"); + Scalar lowerY = getParam<Scalar>("Adaptivity.LowerY"); + Scalar upperY = getParam<Scalar>("Adaptivity.UpperY"); + + gridManager.grid().preAdapt(); + + for (const auto& element : elements(leafGridView)) + { + GlobalPosition pos = element.geometry().center(); + + auto x = pos[0]; + auto y = pos[1]; + + if((leftX < x) && (x < rightX) && (y > lowerY) && (y < upperY)) + { + gridManager.grid().mark( 1, element); + } + } + gridManager.grid().adapt(); + gridManager.grid().postAdapt(); + } + + // create the finite volume grid geometry + using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; + auto gridGeometry = std::make_shared<GridGeometry>(leafGridView); + + // get some time loop parameters + using Scalar = GetPropType<TypeTag, Properties::Scalar>; + const auto tEnd = getParam<Scalar>("TimeLoop.TEnd"); + const auto maxDt = getParam<Scalar>("TimeLoop.MaxTimeStepSize"); + auto dt = getParam<Scalar>("TimeLoop.DtInitial"); + + // instantiate time loop + auto timeLoop = std::make_shared<TimeLoop<Scalar>>(0.0, dt, tEnd); + timeLoop->setMaxTimeStepSize(maxDt); + + // the problem (initial and boundary conditions) + using Problem = GetPropType<TypeTag, Properties::Problem>; + auto problem = std::make_shared<Problem>(gridGeometry); + problem->updateTimeStepSize(timeLoop->timeStepSize()); + + // the solution vector + using SolutionVector = GetPropType<TypeTag, Properties::SolutionVector>; + SolutionVector x; + x[GridGeometry::cellCenterIdx()].resize(gridGeometry->numCellCenterDofs()); + x[GridGeometry::faceIdx()].resize(gridGeometry->numFaceDofs()); + 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 + MyStaggeredVtkOutputModule<GridVariables, SolutionVector> vtkWriter(*gridVariables, x, problem->name()); + using IOFields = GetPropType<TypeTag, Properties::IOFields>; + IOFields::initOutputModule(vtkWriter); // Add model specific output fields + + auto source = createSource(*problem); + auto sourceX = source[Problem::Indices::momentumXBalanceIdx]; + auto sourceY = source[Problem::Indices::momentumYBalanceIdx]; + vtkWriter.addField(sourceX, "sourceX"); + vtkWriter.addField(sourceY, "sourceY"); + + problem->createAnalyticalSolution(timeLoop->timeStepSize()); + vtkWriter.addField(problem->getAnalyticalPressureSolution(), "pressureExact"); + vtkWriter.addField(problem->getAnalyticalVelocitySolution(), "velocityExact"); + vtkWriter.addFaceField(problem->getAnalyticalVelocitySolutionOnFace(), "faceVelocityExact"); + vtkWriter.write(0.0); + + using CellCenterSolutionVector = GetPropType<TypeTag, Properties::CellCenterSolutionVector>; + CellCenterSolutionVector numericalCCResidualWithAnalytical; + const auto numDofsCellCenter = leafGridView.size(0); + numericalCCResidualWithAnalytical.resize(numDofsCellCenter); + vtkWriter.addField(numericalCCResidualWithAnalytical, "continuityResidual"); + + const bool isStationary = getParam<bool>("Problem.IsStationary"); + + // the assembler with time loop for instationary problem + using Assembler = CVDStaggeredRefinedFVAssembler<TypeTag, DiffMethod::numeric>; + auto assembler = isStationary ? std::make_shared<Assembler>(problem, gridGeometry, gridVariables) + : std::make_shared<Assembler>(problem, gridGeometry, gridVariables, timeLoop, xOld); + + // the linear solver + using LinearSolver = Dumux::UMFPackBackend; + auto linearSolver = std::make_shared<LinearSolver>(); + + // the non-linear solver + using NewtonSolver = Dumux::NewtonSolver<Assembler, LinearSolver>; + NewtonSolver nonLinearSolver(assembler, linearSolver); + + using HostGrid = Dune::ALUGrid<2,2,Dune::cube,Dune::nonconforming >; + using HostGridManager = GridManager<HostGrid>; + + std::array<std::string, 2> paramGroups = {"coarsexCVs", "coarseyCVs"}; //xfine... + std::array<HostGridManager, 2> cvGridManagers = {}; + std::array<std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>>,2> cvCenterScvfIndicesMaps; + CVDCVOutputFacility<TypeTag> cvOutputFacility(problem); + cvOutputFacility.iniCVGridManagers(cvGridManagers, cvCenterScvfIndicesMaps, paramGroups); + std::vector<std::pair<unsigned int, Scalar>> pvdFileInfos; + + gridVariables->update(x); + + const bool shouldPrintErrors = getParam<bool>("Problem.PrintErrors"); + + unsigned int timeIndex = 0; + if (isStationary) + { + // linearize & solve + Dune::Timer timer; + nonLinearSolver.solve(x); + + //output + if (shouldPrintErrors) + problem->printErrors(x); + + using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; + FaceSolutionVector numericalFaceResidualWithAnalytical; + + std::optional<std::array<std::vector<Scalar>, 2>> optionalPerfectInterpolationFaceResiduals; + // std::array<std::vector<Scalar>, 4> perfectInterpolationFaceResiduals; + // optionalPerfectInterpolationFaceResiduals.emplace(perfectInterpolationFaceResiduals); + + ResidualCalc<TypeTag> residualCalc(problem); + residualCalc.calcResidualsStationary(gridGeometry, numericalCCResidualWithAnalytical, numericalFaceResidualWithAnalytical); + + bool readDofBasedValues = getParam<bool>("Problem.ReadDofBasedValues", false); + if (readDofBasedValues) + { + CellCenterSolutionVector readInPres; + readInPres.resize(gridGeometry->numCellCenterDofs()); + ReadDofBasedResult<TypeTag> reader(problem); + reader.readDofBasedResult(readInPres, "pressure"); + vtkWriter.addField(readInPres, "readInPres"); + } + + vtkWriter.write(1.); + + cvOutputFacility.onCVsOutputResidualsAndPrimVars( + gridGeometry, + cvGridManagers, + cvCenterScvfIndicesMaps, + paramGroups, + x, + 0, + numericalFaceResidualWithAnalytical, + optionalPerfectInterpolationFaceResiduals, + readDofBasedValues); + + pvdFileInfos.push_back(std::make_pair(0, 0)); + cvOutputFacility.printPvdFiles(paramGroups, pvdFileInfos); + + timer.stop(); + + const auto& comm = Dune::MPIHelper::getCollectiveCommunication(); + std::cout << "Simulation took " << timer.elapsed() << " seconds on " + << comm.size() << " processes.\n" + << "The cumulative CPU time was " << timer.elapsed()*comm.size() << " seconds.\n"; + } + else + { + // time loop + timeLoop->start(); do + { + Scalar actualCurrentTime = timeLoop->time()+timeLoop->timeStepSize(); + + // set previous solution for storage evaluations + assembler->setPreviousSolution(xOld); + + // solve the non-linear system with time step control + nonLinearSolver.solve(x, *timeLoop); + + //output + if (shouldPrintErrors) + { + problem->printErrors(x, actualCurrentTime, timeIndex); + } + + using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; + FaceSolutionVector numericalFaceResidualWithAnalytical; + + std::optional<std::array<std::vector<Scalar>, 2>> optionalPerfectInterpolationFaceResiduals; + std::array<std::vector<Scalar>, 2> perfectInterpolationFaceResiduals; + optionalPerfectInterpolationFaceResiduals.emplace(perfectInterpolationFaceResiduals); + + ResidualCalc<TypeTag> residualCalc(problem); + // residualCalc.calcResidualsInstationary(timeLoop, gridGeometry, cvGridManagers, cvCenterScvfIndicesMaps, numericalCCResidualWithAnalytical, numericalFaceResidualWithAnalytical, optionalPerfectInterpolationFaceResiduals); + + bool readDofBasedValues = getParam<bool>("Problem.ReadDofBasedValues", false) && scalarCmp(getParam<Scalar>("Problem.TimeDofBasedValues"), actualCurrentTime); + if (readDofBasedValues) + { + CellCenterSolutionVector IBAMRpres; + IBAMRpres.resize(gridGeometry->numCellCenterDofs()); + ReadDofBasedResult<TypeTag> reader(problem); + reader.readDofBasedResult(IBAMRpres, "pressure"); + vtkWriter.addField(IBAMRpres, "IBAMRpres"); + } + + problem->createAnalyticalSolution(actualCurrentTime); + vtkWriter.write(actualCurrentTime); + + if (readDofBasedValues) + vtkWriter.removeField(); + + cvOutputFacility.onCVsOutputResidualsAndPrimVars( + gridGeometry, + cvGridManagers, + cvCenterScvfIndicesMaps, + paramGroups, + x, + timeIndex,/*0 for stationary*/ + numericalFaceResidualWithAnalytical, + optionalPerfectInterpolationFaceResiduals, + readDofBasedValues); + + pvdFileInfos.push_back(std::make_pair(timeIndex, actualCurrentTime)); + + // prepare next time step + xOld = x; + gridVariables->advanceTimeStep(); + timeLoop->advanceTimeStep(); + problem->updateTime(timeLoop->time()); + timeLoop->reportTimeStep(); + timeLoop->setTimeStepSize(nonLinearSolver.suggestTimeStepSize(timeLoop->timeStepSize())); + problem->updateTimeStepSize(timeLoop->timeStepSize()); + + ++timeIndex; + } while (!timeLoop->finished()); + + cvOutputFacility.printPvdFiles(paramGroups, pvdFileInfos); + + 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/appl/freeflow/navierstokes/sincos_copy/params.input b/appl/freeflow/navierstokes/sincos_copy/params.input new file mode 100644 index 0000000..7fad359 --- /dev/null +++ b/appl/freeflow/navierstokes/sincos_copy/params.input @@ -0,0 +1,79 @@ +[TimeLoop] +DtInitial = 0.01 # [s] +TEnd = 1.0 # [s] + +[Helper.Grid] +Positions0 = 0 .1 +Positions1 = 0 .1 +Cells0 = 10 +Cells1 = 10 +Grading0 = 1.0 +Grading1 = 1.0 + +[Grid] +File = grid.dgf + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Problem] +Name = test_ff_sincos +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +ReadDofBasedPressure = false +ReadDofBasedVelocity = false + +[Component] +LiquidDensity = 1.0 +LiquidKinematicViscosity = 0.001 +MolarMass = 1.0 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +[Newton] +MaxSteps = 10 +TargetSteps = 4 +MaxRelativeShift = 1e-5 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true +MaxAbsoluteResidual = 1e-5 + +[Vtk] +WriteFaceData = false +AddProcessRank = false + +[Flux] +UpwindWeight = 0.5 + +[Adaptivity] +Conservation = true +Adapt = true +LeftX = 3 +RightX = 5 +LowerY = .2 +UpperY = .6 + +[VelocityReadIn] +NumFileEntries = 260 +XFileName = "/home/melanie/Desktop/daten_IBAMR/AngeliAMR/velocitiesXPositions.txt" +YFileName = "/home/melanie/Desktop/daten_IBAMR/AngeliAMR/velocitiesYPositions.txt" +ValueFileName = "/home/melanie/Desktop/daten_IBAMR/AngeliAMR/velocities.txt" + +[PressureReadIn] +NumFileEntries = 116; +XFileName = "/home/melanie/Desktop/daten_IBAMR/AngeliAMR/pressuresXPositions.txt" +YFileName = "/home/melanie/Desktop/daten_IBAMR/AngeliAMR/pressuresYPositions.txt" +ValuesFileName = "/home/melanie/Desktop/daten_IBAMR/AngeliAMR/pressures.txt" + diff --git a/appl/freeflow/navierstokes/sincos_copy/paramsVanDerPlas.input b/appl/freeflow/navierstokes/sincos_copy/paramsVanDerPlas.input new file mode 100644 index 0000000..498cfa6 --- /dev/null +++ b/appl/freeflow/navierstokes/sincos_copy/paramsVanDerPlas.input @@ -0,0 +1,59 @@ +[TimeLoop] +DtInitial = 0.01 # [s] +TEnd = 1.0 # [s] + +[Helper.Grid] +Positions0 = 0.25 0.75 +Positions1 = 0.25 0.75 #we don't have symmetry BCs +Cells0 = 30 +Cells1 = 30 +Grading0 = 1.0 +Grading1 = 1.0 + +[xCVs.Grid] +File = xCVs.dgf + +[yCVs.Grid] +File = yCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_ff_sincos +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +VanDerPlasVersion = true + +[Component] +LiquidDensity = 1.0 +LiquidKinematicViscosity = 0.05 +MolarMass = 1.0 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +[Newton] +MaxSteps = 10 +TargetSteps = 4 +MaxRelativeShift = 1e-5 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true +MaxAbsoluteResidual = 1e-5 + +[Vtk] +WriteFaceData = false +AddProcessRank = false + +[Flux] +UpwindWeight = 0.5 + +[Adaptivity] +Conservation = true +Adapt = true +LeftX = .4 +RightX = .6 +LowerY = .4 +UpperY = .6 diff --git a/appl/freeflow/navierstokes/sincos_copy/params_grading.input b/appl/freeflow/navierstokes/sincos_copy/params_grading.input new file mode 100644 index 0000000..9436bfc --- /dev/null +++ b/appl/freeflow/navierstokes/sincos_copy/params_grading.input @@ -0,0 +1,65 @@ +[TimeLoop] +DtInitial = 0.01 # [s] +TEnd = 1.0 # [s] + +[Helper.Grid] +LowerLeft = 0 0 +UpperRight = 6.28 6.28 +Cells = 62 62 +Positions0 = 0 1.57 2.512 4.082 5.024 6.28 +Positions1 = 0 1.57 2.512 4.082 5.024 6.28 +Cells0 = 3 5 4 5 3 +Cells1 = 3 5 4 5 3 +Grading0 = 1 1 1 1 1 +Grading1 = 1 1 1 1 1 + +[Grid] +File = grid.dgf + +[Problem] +Name = grading +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true + +[Component] +MolarMass = 1.0 +LiquidDensity = 1.0 +LiquidKinematicViscosity = 0.1 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +[Newton] +MaxSteps = 10 +TargetSteps = 4 +MaxRelativeShift = 1e-5 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true +MaxAbsoluteResidual = 1e-10 + +[Vtk] +WriteFaceData = false +AddProcessRank = false +Precision = Float64 + +[Flux] +UpwindWeight = 0.5 + +[LinearSolver] +Type = restartedflexiblegmressolver +Verbosity = 1 +GMResRestart = 50 + +[LinearSolver.Preconditioner] +Type = uzawa +Verbosity = 1 +Iterations = 5 + +[FreeFlow] +EnableVelocityGradientFactor = false + +[Adaptivity] +Conservation = false +Adapt = false diff --git a/appl/freeflow/navierstokes/sincos_copy/params_grading_add_dof_bad.input b/appl/freeflow/navierstokes/sincos_copy/params_grading_add_dof_bad.input new file mode 100644 index 0000000..1874482 --- /dev/null +++ b/appl/freeflow/navierstokes/sincos_copy/params_grading_add_dof_bad.input @@ -0,0 +1,65 @@ +[TimeLoop] +DtInitial = 0.01 # [s] +TEnd = 1.0 # [s] + +[Helper.Grid] +LowerLeft = 0 0 +UpperRight = 6.28 6.28 +Cells = 62 62 +Positions0 = 0 1.57 2.512 4.082 5.024 6.28 +Positions1 = 0 1.57 2.512 4.082 5.024 6.28 +Cells0 = 4 5 4 5 4 +Cells1 = 4 5 4 5 4 +Grading0 = 1 1 1 1 1 +Grading1 = 1 1 1 1 1 + +[Grid] +File = grid.dgf + +[Problem] +Name = grading +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true + +[Component] +MolarMass = 1.0 +LiquidDensity = 1.0 +LiquidKinematicViscosity = 0.1 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +[Newton] +MaxSteps = 10 +TargetSteps = 4 +MaxRelativeShift = 1e-5 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true +MaxAbsoluteResidual = 1e-10 + +[Vtk] +WriteFaceData = false +AddProcessRank = false +Precision = Float64 + +[Flux] +UpwindWeight = 0.5 + +[LinearSolver] +Type = restartedflexiblegmressolver +Verbosity = 1 +GMResRestart = 50 + +[LinearSolver.Preconditioner] +Type = uzawa +Verbosity = 1 +Iterations = 5 + +[FreeFlow] +EnableVelocityGradientFactor = false + +[Adaptivity] +Conservation = false +Adapt = false diff --git a/appl/freeflow/navierstokes/sincos_copy/params_uniform.input b/appl/freeflow/navierstokes/sincos_copy/params_uniform.input new file mode 100644 index 0000000..b9a55e5 --- /dev/null +++ b/appl/freeflow/navierstokes/sincos_copy/params_uniform.input @@ -0,0 +1,65 @@ +[TimeLoop] +DtInitial = 0.01 # [s] +TEnd = 1.0 # [s] + +[Helper.Grid] +LowerLeft = 0 0 +UpperRight = 6.28 6.28 +Cells = 62 62 +Positions0 = 0 6.28 +Positions1 = 0 6.28 +Cells0 = 20 +Cells1 = 20 +Grading0 = 1 +Grading1 = 1 + +[Grid] +File = grid.dgf + +[Problem] +Name = uniform +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true + +[Component] +MolarMass = 1.0 +LiquidDensity = 1.0 +LiquidKinematicViscosity = 0.1 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +[Newton] +MaxSteps = 10 +TargetSteps = 4 +MaxRelativeShift = 1e-5 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true +MaxAbsoluteResidual = 1e-10 + +[Vtk] +WriteFaceData = false +AddProcessRank = false +Precision = Float64 + +[Flux] +UpwindWeight = 0.5 + +[LinearSolver] +Type = restartedflexiblegmressolver +Verbosity = 1 +GMResRestart = 50 + +[LinearSolver.Preconditioner] +Type = uzawa +Verbosity = 1 +Iterations = 5 + +[FreeFlow] +EnableVelocityGradientFactor = false + +[Adaptivity] +Conservation = false +Adapt = false diff --git a/appl/freeflow/navierstokes/sincos_copy/params_vdP_full.input b/appl/freeflow/navierstokes/sincos_copy/params_vdP_full.input new file mode 100644 index 0000000..7b2b8d1 --- /dev/null +++ b/appl/freeflow/navierstokes/sincos_copy/params_vdP_full.input @@ -0,0 +1,79 @@ +[TimeLoop] +DtInitial = 0.01 # [s] +TEnd = 1.0 # [s] + +[Helper.Grid] +Positions0 = 0.25 0.75 +Positions1 = 0.25 0.75 #we don't have symmetry BCs +Cells0 = 10 +Cells1 = 10 +Grading0 = 1.0 +Grading1 = 1.0 + +[xCVs.Grid] +File = xCVs.dgf + +[yCVs.Grid] +File = yCVs.dgf + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_ff_sincos_vdP_full_42_bigresidual +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +VanDerPlasVersion = true +StartWithAnalytical = false +AveragedAnalyticalSolution = false + +[Component] +LiquidDensity = 1.0 +LiquidKinematicViscosity = 0.05 +MolarMass = 1.0 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +[Newton] +MaxSteps = 10 +TargetSteps = 4 +MaxRelativeShift = 1e-5 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true +MaxAbsoluteResidual = 1e-5 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = false +AddProcessRank = false + +[Flux] +UpwindWeight = 0.5 + +[Adaptivity] +NewParallelAlgo = false +UseOwn4PointCoefficients = false +Conservation = false +LinearInterpolation = false +DebugDof = -1 +Adapt = true +LeftX = .4 +RightX = .6 +LowerY = .4 +UpperY = .6 diff --git a/appl/freeflow/navierstokes/sincos_copy/params_vdP_full_vdP.input b/appl/freeflow/navierstokes/sincos_copy/params_vdP_full_vdP.input new file mode 100644 index 0000000..2f5ea17 --- /dev/null +++ b/appl/freeflow/navierstokes/sincos_copy/params_vdP_full_vdP.input @@ -0,0 +1,63 @@ +[TimeLoop] +DtInitial = 0.01 # [s] +TEnd = 1.0 # [s] + +[Helper.Grid] +Positions0 = 0.25 0.75 +Positions1 = 0.25 0.75 #we don't have symmetry BCs +Cells0 = 5 +Cells1 = 5 +Grading0 = 1.0 +Grading1 = 1.0 + +[xCVs.Grid] +File = xCVs.dgf + +[yCVs.Grid] +File = yCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_ff_sincos +EnableGravity = false +PrintL2Error = true +EnableInertiaTerms = true +IsStationary = true +VanDerPlasVersion = true + +[Component] +LiquidDensity = 1.0 +LiquidKinematicViscosity = 0.05 +MolarMass = 1.0 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +[Newton] +MaxSteps = 10 +TargetSteps = 4 +MaxRelativeShift = 1e-5 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true +MaxAbsoluteResidual = 1e-5 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = false +AddProcessRank = false + +[Flux] +UpwindWeight = 0.5 + +[Adaptivity] +Conservation = false +LinearInterpolation = true +UseOwn4PointCoefficients = false +Adapt = true +LeftX = .4 +RightX = .6 +LowerY = .4 +UpperY = .6 diff --git a/appl/freeflow/navierstokes/sincos_copy/params_vdP_lin.input b/appl/freeflow/navierstokes/sincos_copy/params_vdP_lin.input new file mode 100644 index 0000000..769fbcc --- /dev/null +++ b/appl/freeflow/navierstokes/sincos_copy/params_vdP_lin.input @@ -0,0 +1,62 @@ +[TimeLoop] +DtInitial = 0.01 # [s] +TEnd = 1.0 # [s] + +[Helper.Grid] +Positions0 = 0.25 0.75 +Positions1 = 0.25 0.75 #we don't have symmetry BCs +Cells0 = 5 +Cells1 = 5 +Grading0 = 1.0 +Grading1 = 1.0 + +[xCVs.Grid] +File = xCVs.dgf + +[yCVs.Grid] +File = yCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_ff_sincos +EnableGravity = false +PrintL2Error = true +EnableInertiaTerms = true +IsStationary = true +VanDerPlasVersion = true + +[Component] +LiquidDensity = 1.0 +LiquidKinematicViscosity = 0.05 +MolarMass = 1.0 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +[Newton] +MaxSteps = 10 +TargetSteps = 4 +MaxRelativeShift = 1e-5 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true +MaxAbsoluteResidual = 1e-5 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = false +AddProcessRank = false + +[Flux] +UpwindWeight = 0.5 + +[Adaptivity] +Conservation = false +LinearInterpolation = true +Adapt = true +LeftX = .4 +RightX = .6 +LowerY = .4 +UpperY = .6 diff --git a/appl/freeflow/navierstokes/sincos_copy/params_vdP_unrefined.input b/appl/freeflow/navierstokes/sincos_copy/params_vdP_unrefined.input new file mode 100644 index 0000000..0106de6 --- /dev/null +++ b/appl/freeflow/navierstokes/sincos_copy/params_vdP_unrefined.input @@ -0,0 +1,62 @@ +[TimeLoop] +DtInitial = 0.01 # [s] +TEnd = 1.0 # [s] + +[Helper.Grid] +Positions0 = 0.25 0.75 +Positions1 = 0.25 0.75 #we don't have symmetry BCs +Cells0 = 5 +Cells1 = 5 +Grading0 = 1.0 +Grading1 = 1.0 + +[xCVs.Grid] +File = xCVs.dgf + +[yCVs.Grid] +File = yCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_ff_sincos +EnableGravity = false +PrintL2Error = true +EnableInertiaTerms = true +IsStationary = true +VanDerPlasVersion = true + +[Component] +LiquidDensity = 1.0 +LiquidKinematicViscosity = 0.05 +MolarMass = 1.0 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +[Newton] +MaxSteps = 10 +TargetSteps = 4 +MaxRelativeShift = 1e-5 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true +MaxAbsoluteResidual = 1e-5 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = false +AddProcessRank = false + +[Flux] +UpwindWeight = 0.5 + +[Adaptivity] +Conservation = false +LinearInterpolation = false +Adapt = false +LeftX = .4 +RightX = .6 +LowerY = .4 +UpperY = .6 diff --git a/appl/freeflow/navierstokes/sincos_copy/problem.hh b/appl/freeflow/navierstokes/sincos_copy/problem.hh new file mode 100644 index 0000000..3b7f603 --- /dev/null +++ b/appl/freeflow/navierstokes/sincos_copy/problem.hh @@ -0,0 +1,720 @@ +// -*- 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 3 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 + * \ingroup NavierStokesTests + * \brief Test for the staggered grid Navier-Stokes model + * with analytical solution. + */ +#ifndef DUMUX_SINCOS_TEST_PROBLEM_HH +#define DUMUX_SINCOS_TEST_PROBLEM_HH + +#include <dune/alugrid/grid.hh> +#include <dune/grid/yaspgrid.hh> + +#include <dumux/assembly/cvdstaggeredrefinedlocalresidual.hh> + +#include <dumux/common/numeqvector.hh> + +#include <dumux/material/fluidsystems/1pliquid.hh> +#include <dumux/material/components/constant.hh> + +#include <dumux/freeflow/navierstokes/cvdproblem.hh> +#include <dumux/freeflow/navierstokes/model.hh> + +#include <dumux/freeflow/navierstokes/boundarytypes.hh> +#include <dumux/freeflow/navierstokes/cvdlocalresidual.hh> +#include <dumux/freeflow/navierstokes/cvdfluxvariableswrapper.hh> +#include <dumux/freeflow/navierstokes/myvolumevariables.hh> +#include <dumux/freeflow/navierstokes/myiofields.hh> + +#include <dumux/discretization/staggered/freeflow/properties.hh> +#include <dumux/discretization/staggered/freeflow/myfacevariables.hh> +#include <dumux/discretization/staggered/freeflow/cvdlocalfacevariables.hh> +#include <dumux/discretization/staggered/freeflow/myvelocityoutput.hh> +#include <dumux/discretization/staggered/freeflow/mygridvolumevariables.hh> +#include <dumux/discretization/staggered/freeflow/elementvolumevariables1.hh> +#include <dumux/discretization/staggered/mygridfluxvariablescache.hh> +#include <dumux/discretization/staggered/myfacesolution.hh> +#include <dumux/discretization/staggered/cvdelementfacesolution.hh> +#include <dumux/discretization/staggered/cvdgridvariables.hh> +#include <dumux/discretization/staggered/cvdlocalgridfacevariables.hh> +#include <dumux/discretization/staggered/cvdfvgridgeometry.hh> +#include <dumux/discretization/staggered/freeflow/cvdfvgridgeometrytraits.hh> + +namespace Dumux { +template <class TypeTag> +class SincosTestProblem; + +namespace Properties { +// Create new type tags +namespace TTag { +struct SincosTest { using InheritsFrom = std::tuple<StaggeredFreeFlowModel, NavierStokes>; }; +} // end namespace TTag + +// the fluid system +template<class TypeTag> +struct FluidSystem<TypeTag, TTag::SincosTest> +{ +private: + using Scalar = GetPropType<TypeTag, Properties::Scalar>; +public: + using type = FluidSystems::OnePLiquid<Scalar, Components::Constant<1, Scalar> >; +}; + +// Set the grid type +template<class TypeTag> +struct Grid<TypeTag, TTag::SincosTest> { using type = Dune::ALUGrid<2,2,Dune::cube,Dune::nonconforming>; }; + +template<class TypeTag, class MyTypeTag> +struct HelpingGrid { using type = UndefinedProperty; }; + +// Set the grid type +template<class TypeTag> +struct HelpingGrid<TypeTag, TTag::SincosTest> +{ + using type = Dune::YaspGrid<2,Dune::TensorProductCoordinates<double, 2>>; +}; + +// Set the problem property +template<class TypeTag> +struct Problem<TypeTag, TTag::SincosTest> { using type = Dumux::SincosTestProblem<TypeTag> ; }; + +template<class TypeTag> +struct EnableGridGeometryCache<TypeTag, TTag::SincosTest> { static constexpr bool value = true; }; +template<class TypeTag> +struct EnableGridFluxVariablesCache<TypeTag, TTag::SincosTest> { static constexpr bool value = true; }; +template<class TypeTag> +struct EnableGridVolumeVariablesCache<TypeTag, TTag::SincosTest> { static constexpr bool value = true; }; + +//! The variables living on the faces +template<class TypeTag> +struct FaceVariables<TypeTag, TTag::SincosTest> +{ +private: + using FacePrimaryVariables = GetPropType<TypeTag, Properties::FacePrimaryVariables>; + using GridView = typename GetPropType<TypeTag, Properties::GridGeometry>::GridView; + static constexpr auto upwindSchemeOrder = getPropValue<TypeTag, Properties::UpwindSchemeOrder>(); + using ModelTraits = GetPropType<TypeTag, Properties::ModelTraits>; +public: + using type = MyStaggeredFaceVariables<ModelTraits, FacePrimaryVariables, GridView::dimension, upwindSchemeOrder>; +}; + +template<class TypeTag> +struct LocalFaceVariables<TypeTag, TTag::SincosTest> +{ +private: + using FacePrimaryVariables = GetPropType<TypeTag, Properties::FacePrimaryVariables>; +public: + using type = CVDStaggeredLocalFaceVariables<FacePrimaryVariables>; +}; + +//! The velocity output +template<class TypeTag> +struct VelocityOutput<TypeTag, TTag::SincosTest> +{ + using type = MyStaggeredFreeFlowVelocityOutput<GetPropType<TypeTag, Properties::GridVariables>, + GetPropType<TypeTag, Properties::SolutionVector>>; +}; + +//! Set the volume variables property +template<class TypeTag> +struct DualCVsVolVars<TypeTag, TTag::SincosTest> +{ +private: + using VV = GetPropType<TypeTag, Properties::VolumeVariables>; + using GridView = typename GetPropType<TypeTag, Properties::GridGeometry>::GridView; + static constexpr auto dimWorld = GridView::dimensionworld; + static constexpr int numPairs = 2 * (dimWorld - 1); + +public: + using type = NavierStokesDualCVsVolVars<VV, numPairs>; +}; + +//! Set the volume variables property +template<class TypeTag> +struct PrimalCVsVolVars<TypeTag, TTag::SincosTest> +{ +private: + using VV = GetPropType<TypeTag, Properties::VolumeVariables>; +public: + using type = std::array<NaviesStokesPrimalScvfPair<VV>,8>;//TODO make work for dim != 2 +}; + +//! Set the default global volume variables cache vector class +template<class TypeTag> +struct GridVolumeVariables<TypeTag, TTag::SincosTest> +{ +private: + using Problem = GetPropType<TypeTag, Properties::Problem>; + using VolumeVariables = GetPropType<TypeTag, Properties::VolumeVariables>; + using DualCVsVolVars = GetPropType<TypeTag, Properties::DualCVsVolVars>; + using PrimalCVsVolVars = GetPropType<TypeTag, Properties::PrimalCVsVolVars>; + using GridView = typename GetPropType<TypeTag, Properties::GridGeometry>::GridView; + using SubControlVolume = typename GetPropType<TypeTag, Properties::GridGeometry>::SubControlVolume; + using SubControlVolumeFace = typename GetPropType<TypeTag, Properties::GridGeometry>::SubControlVolumeFace; + static constexpr auto enableCache = getPropValue<TypeTag, Properties::EnableGridVolumeVariablesCache>(); + using Traits = MyStaggeredGridDefaultGridVolumeVariablesTraits<Problem, PrimalCVsVolVars, DualCVsVolVars, VolumeVariables, GridView, SubControlVolume, SubControlVolumeFace>; +public: + using type = MyStaggeredGridVolumeVariables<Traits, enableCache>; +}; + +//! Set the BaseLocalResidual to StaggeredLocalResidual +template<class TypeTag> +struct BaseLocalResidual<TypeTag, TTag::SincosTest> { using type = StaggeredRefinedLocalResidual<TypeTag>; }; + +//! Set the face solution type +template<class TypeTag> +struct StaggeredFaceSolution<TypeTag, TTag::SincosTest> +{ +private: + using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; +public: + using type = Dumux::MyStaggeredFaceSolution<FaceSolutionVector>; +}; + +template<class TypeTag> +struct ElementFaceSolution<TypeTag, TTag::SincosTest> +{ +private: + using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; +public: + using type = Dumux::CVDElementFaceSolution<FaceSolutionVector>; +}; + +//! Set the GridLocalFaceVariables +template<class TypeTag> +struct GridLocalFaceVariables<TypeTag, TTag::SincosTest> +{ + private: + using Problem = GetPropType<TypeTag, Properties::Problem>; + using LocalFaceVariables = GetPropType<TypeTag, Properties::LocalFaceVariables>; + static constexpr auto enableCache = getPropValue<TypeTag, Properties::EnableGridFaceVariablesCache>(); + public: + using type = CVDStaggeredLocalGridFaceVariables<Problem, LocalFaceVariables, enableCache>; +}; + +//! Set the grid variables (volume, flux and face variables) +template<class TypeTag> +struct GridVariables<TypeTag, TTag::SincosTest> +{ +private: + using GG = GetPropType<TypeTag, Properties::GridGeometry>; + using GVV = GetPropType<TypeTag, Properties::GridVolumeVariables>; + using GFVC = GetPropType<TypeTag, Properties::GridFluxVariablesCache>; + using GFV = GetPropType<TypeTag, Properties::GridFaceVariables>; + using GLFV = GetPropType<TypeTag, Properties::GridLocalFaceVariables>; +public: + using type = CVDStaggeredGridVariables<GG, GVV, GFVC, GFV, GLFV>; +}; + +//! The default fv grid geometry +template<class TypeTag> +struct GridGeometry<TypeTag, TTag::SincosTest> +{ +private: + static constexpr auto upwindSchemeOrder = getPropValue<TypeTag, Properties::UpwindSchemeOrder>(); + static constexpr bool enableCache = getPropValue<TypeTag, Properties::EnableGridGeometryCache>(); + using GridView = typename GetPropType<TypeTag, Properties::Grid>::LeafGridView; + using Traits = CVDStaggeredFreeFlowDefaultGridGeometryTraits<GridView, upwindSchemeOrder>; +public: + using type = CVDStaggeredGridGeometry<GridView, enableCache, Traits>; +}; + +//! Set the volume variables property +template<class TypeTag> +struct VolumeVariables<TypeTag, TTag::SincosTest> +{ +private: + using PV = GetPropType<TypeTag, Properties::PrimaryVariables>; + using FSY = GetPropType<TypeTag, Properties::FluidSystem>; + using FST = GetPropType<TypeTag, Properties::FluidState>; + using MT = GetPropType<TypeTag, Properties::ModelTraits>; + + static_assert(FSY::numPhases == MT::numFluidPhases(), "Number of phases mismatch between model and fluid system"); + static_assert(FST::numPhases == MT::numFluidPhases(), "Number of phases mismatch between model and fluid state"); + static_assert(!FSY::isMiscible(), "The Navier-Stokes model only works with immiscible fluid systems."); + + using Traits = NavierStokesVolumeVariablesTraits<PV, FSY, FST, MT>; +public: + using type = MyNavierStokesVolumeVariables<Traits>; +}; + +//! The local residual +template<class TypeTag> +struct LocalResidual<TypeTag, TTag::SincosTest> { using type = RefinedNavierStokesResidual<TypeTag>; }; + +//! The flux variables +template<class TypeTag> +struct FluxVariables<TypeTag, TTag::SincosTest> { using type = RefinedNavierStokesFluxVariables<TypeTag>; }; + +//! The specific I/O fields +template<class TypeTag> +struct IOFields<TypeTag, TTag::SincosTest> { using type = MyNavierStokesIOFields; }; + +//! Set the global flux variables cache vector class +template<class TypeTag> +struct GridFluxVariablesCache<TypeTag, TTag::SincosTest> +{ +private: + using Problem = GetPropType<TypeTag, Properties::Problem>; + using FluxVariablesCache = GetPropType<TypeTag, Properties::FluxVariablesCache>; + using FluxVariablesCacheFiller = GetPropType<TypeTag, Properties::FluxVariablesCacheFiller>; + static constexpr auto enableCache = getPropValue<TypeTag, Properties::EnableGridFluxVariablesCache>(); + static constexpr auto upwindSchemeOrder = getPropValue<TypeTag, Properties::UpwindSchemeOrder>(); +public: + using type = MyStaggeredGridFluxVariablesCache<Problem, FluxVariablesCache, FluxVariablesCacheFiller, enableCache, upwindSchemeOrder>; +}; + +template<class TypeTag> +struct CVGridGeometry<TypeTag, TTag::SincosTest> +{ +private: + static constexpr auto upwindSchemeOrder = getPropValue<TypeTag, Properties::UpwindSchemeOrder>(); + static constexpr bool enableCache = getPropValue<TypeTag, Properties::EnableGridGeometryCache>(); + using GridView = typename Dune::ALUGrid<2,2,Dune::cube,Dune::nonconforming >::LeafGridView; + using Traits = CVDStaggeredFreeFlowDefaultGridGeometryTraits<GridView, upwindSchemeOrder>; +public: + using type = CVDStaggeredGridGeometry<GridView, enableCache, Traits>; +}; +} // end namespace Properties + +/*! + * \ingroup NavierStokesTests + * \brief Test problem for the staggered grid. + * + * The 2D, incompressible Navier-Stokes equations for zero gravity and a Newtonian + * flow is solved and compared to an analytical solution (sums/products of trigonometric functions). + * For the instationary case, the velocities and pressures are periodical in time. The Dirichlet boundary conditions are + * consistent with the analytical solution and in the instationary case time-dependent. + */ +template <class TypeTag> +class SincosTestProblem : public MyNavierStokesProblem<TypeTag> +{ + using ParentType = MyNavierStokesProblem<TypeTag>; + + using BoundaryTypes = Dumux::NavierStokesBoundaryTypes<GetPropType<TypeTag, Properties::ModelTraits>::numEq()>; + using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; + using NumEqVector = Dumux::NumEqVector<GetPropType<TypeTag, Properties::PrimaryVariables>>; + using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>; + using Scalar = GetPropType<TypeTag, Properties::Scalar>; + using SolutionVector = GetPropType<TypeTag, Properties::SolutionVector>; + using TimeLoopPtr = std::shared_ptr<TimeLoop<Scalar>>; + using SubControlVolume = typename GridGeometry::SubControlVolume; + using SubControlVolumeFace = typename GridGeometry::SubControlVolumeFace; + using FVElementGeometry = typename GridGeometry::LocalView; + + static constexpr auto dimWorld = GetPropType<TypeTag, Properties::GridGeometry>::GridView::dimensionworld; + using Element = typename GridGeometry::GridView::template Codim<0>::Entity; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + using VelocityVector = Dune::FieldVector<Scalar, dimWorld>; + +public: + using ModelTraits = GetPropType<TypeTag, Properties::ModelTraits>; + using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; + + SincosTestProblem(std::shared_ptr<const GridGeometry> gridGeometry) + : ParentType(gridGeometry), time_(0.0), timeStepSize_(0.0) + { + isStationary_ = getParam<bool>("Problem.IsStationary"); + vanDerPlasVersion_ = getParam<bool>("Problem.VanDerPlasVersion", false); + + if (vanDerPlasVersion_) + isStationary_=true; + + enableInertiaTerms_ = getParam<bool>("Problem.EnableInertiaTerms"); + rho_ = getParam<Scalar>("Component.LiquidDensity"); + //kinematic + Scalar nu = getParam<Scalar>("Component.LiquidKinematicViscosity", 1.0); + //dynamic + mu_ = rho_*nu; + } + + /*! + * \brief Returns the temperature within the domain in [K]. + * + * This problem assumes a temperature of 10 degrees Celsius. + */ + Scalar temperature() const + { return 298.0; } + + /*! + * \brief Return the sources within the domain. + * + * \param globalPos The global position + */ + NumEqVector instationarySourceAtPos(const GlobalPosition &globalPos, Scalar t) const + { + NumEqVector source(0.0); + const Scalar x = globalPos[0]; + const Scalar y = globalPos[1]; + + source[Indices::momentumXBalanceIdx] = rho_*dtU_(x,y,t) - 2.*mu_*dxxU_(x,y,t) - mu_*dyyU_(x,y,t) - mu_*dxyV_(x,y,t) + dxP_(x,y,t); + source[Indices::momentumYBalanceIdx] = rho_*dtV_(x,y,t) - 2.*mu_*dyyV_(x,y,t) - mu_*dxyU_(x,y,t) - mu_*dxxV_(x,y,t) + dyP_(x,y,t); + + if (enableInertiaTerms_) + { + source[Indices::momentumXBalanceIdx] += rho_*dxUU_(x,y,t) + rho_*dyUV_(x,y,t); + source[Indices::momentumYBalanceIdx] += rho_*dxUV_(x,y,t) + rho_*dyVV_(x,y,t); + } + + return source; + } + + + NumEqVector sourceAtPos(const GlobalPosition &globalPos) const + { + const Scalar t = time_ + timeStepSize_; + return instationarySourceAtPos(globalPos,t); + } + + // \} + /*! + * \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 values; + + // set Dirichlet values for the velocity everywhere + values.setDirichlet(Indices::velocityXIdx); + values.setDirichlet(Indices::velocityYIdx); + + return values; + } + + /*! + * \brief Returns whether a fixed Dirichlet value shall be used at a given cell. + * + * \param element The finite element + * \param fvGeometry The finite-volume geometry + * \param scv The sub control volume + * \param pvIdx The primary variable index in the solution vector + */ + bool isDirichletCell(const Element& element, + const FVElementGeometry& fvGeometry, + const SubControlVolume& scv, + int pvIdx) const + { + // set fixed pressure in one cell + return (scv.dofIndex() == 0) && pvIdx == Indices::pressureIdx; + } + + /*! + * \brief Evaluate the boundary conditions for a dirichlet + * control volume face (velocities) + * + * \param element The finite element + * \param scvf the sub control volume face + * + * Concerning the usage of averaged velocity, see the explanation of the initial function. The average of the nondirection velocity along an scvf is required in the context of dirichlet boundary conditions for the functions getParallelVelocityFromBoundary_ and getParallelVelocityFromOtherBoundary_ within myfluxvariables.hh. There dirichlet is called for ghost faces built from the normalFace but the value then is taken in the the direction scvf.directionIndex, which is along that normalFace. + */ + PrimaryVariables dirichlet(const Element& element, const SubControlVolumeFace& scvf) const + { + Scalar time = time_+timeStepSize_; + + PrimaryVariables priVars(0.0); + + unsigned int dirIdx = scvf.directionIndex(); + priVars[Indices::velocity(dirIdx)] = this->instationaryAnalyticalVelocitySolutionAtPos(scvf, time); + unsigned int nonDirIdx = (dirIdx == 0)?1:0; + priVars[Indices::velocity(nonDirIdx)] = this->instationaryAnalyticalNonDirVelocitySolutionAtPos(scvf, time); + + return priVars; + } + + /*! + * \brief Evaluate the boundary conditions for a dirichlet + * control volume face (pressure) + * + * \param element The finite element + * \param scv the sub control volume + */ + PrimaryVariables dirichlet(const Element& element, const SubControlVolume& scv) const + { + Scalar time = time_+timeStepSize_; + + PrimaryVariables priVars(0.0); + priVars[Indices::pressureIdx] = this->instationaryAnalyticalPressureSolutionAtPos(scv, time); + return priVars; + } + + /*! + * \brief Returns the analytical solution of the problem at a given time and position. + * + * \param globalPos The global position + * \param time The current simulation time + */ + PrimaryVariables instationaryAnalyticalSolutionAtPos(const GlobalPosition& globalPos, const Scalar t) const + { + const Scalar x = globalPos[0]; + const Scalar y = globalPos[1]; + + PrimaryVariables values = {}; + + values[Indices::pressureIdx] = (f1_(x) + f1_(y)) * f_(t) * f_(t) ; + values[Indices::velocityXIdx] = f2_(x) * df2_(y) * f_(t); + values[Indices::velocityYIdx] = - df2_(x) * f2_(y) * f_(t); + + return values; + } + + /*! + * \brief Returns the analytical solution of the problem at a given position. + * + * \param globalPos The global position + */ + PrimaryVariables analyticalSolutionAtPos(const GlobalPosition& globalPos) const + { + if(!isStationary_) + DUNE_THROW(Dune::InvalidStateException, "analyticalSolutionAtPos was supposed to be used only be the stationary problem."); + + return this->instationaryAnalyticalSolutionAtPos(globalPos, time_+timeStepSize_); + } + + // \} + + /*! + * \name Volume terms + */ + // \{ + + /*! + * \brief Evaluates the initial value for a sub control volume face (velocities) + * + * Simply assigning the value of the analytical solution at the face center + * gives a discrete solution that is not divergence-free. For small initial + * time steps, this has a negative impact on the pressure solution + * after the first time step. The flag UseVelocityAveraging triggers the + * function averagedVelocity_ which uses a higher order quadrature formula to + * bring the discrete solution sufficiently close to being divergence-free. + */ + PrimaryVariables initial(const SubControlVolumeFace& scvf) const + { + bool startWithAnalytical = getParam<bool>("Problem.StartWithAnalytical", false); + + if (startWithAnalytical || !isStationary_) + { + PrimaryVariables priVars(0.0); + priVars[Indices::velocity(scvf.directionIndex())] = this->instationaryAnalyticalVelocitySolutionAtPos(scvf, 0.); + return priVars; + } + else + { + PrimaryVariables values; + values[Indices::pressureIdx] = 0.0; + values[Indices::velocityXIdx] = 0.0; + values[Indices::velocityYIdx] = 0.0; + + return values; + } + } + + /*! + * \brief Evaluates the initial value for a control volume (pressure) + */ + PrimaryVariables initial(const SubControlVolume& scv) const + { + bool startWithAnalytical = getParam<bool>("Problem.StartWithAnalytical", false); + + if (startWithAnalytical || !isStationary_) + { + PrimaryVariables priVars(0.0); + priVars[Indices::pressureIdx] = this->instationaryAnalyticalPressureSolutionAtPos(scv, 0.); + return priVars; + } + else + { + PrimaryVariables values; + values[Indices::pressureIdx] = 0.0; + values[Indices::velocityXIdx] = 0.0; + values[Indices::velocityYIdx] = 0.0; + + return values; + } + } + + /*! + * \brief Updates the time + */ + void updateTime(const Scalar time) + { + time_ = time; + } + + /*! + * \brief Updates the time step size + */ + void updateTimeStepSize(const Scalar timeStepSize) + { + timeStepSize_ = timeStepSize; + } + +private: + Scalar f_(Scalar t) const + { + if (isStationary_) + return 1.0; + else + return std::sin(2.0 * t); + } + + Scalar df_(Scalar t) const + { + if (isStationary_) + return 0.0; + else + return 2.0 * std::cos(2.0 * t); + } + + Scalar f1_(Scalar x) const + { + if (vanDerPlasVersion_)//p. 136 + return std::cos(2.*M_PI*x); + else + return -0.25 * std::cos(2.0 * x); + } + + Scalar df1_(Scalar x) const + { + if (vanDerPlasVersion_) + return -2.*M_PI*std::sin(2.*M_PI*x); + else + return 0.5 * std::sin(2.0 * x); + } + + Scalar f2_(Scalar x) const + { + if (vanDerPlasVersion_) + return -std::cos(2.*M_PI*x)/std::sqrt(2.*M_PI);//p. 136 + else + return -std::cos(x); + } + + Scalar df2_(Scalar x) const + { + if (vanDerPlasVersion_) + return std::sqrt(2.*M_PI)*std::sin(2.*M_PI*x); + else + return std::sin(x); + } + + Scalar ddf2_(Scalar x) const + { + if (vanDerPlasVersion_) + return std::sqrt(2.*M_PI)*(2.*M_PI)*std::cos(2*M_PI*x); + else + return std::cos(x); + } + + Scalar dddf2_(Scalar x) const + { + if (vanDerPlasVersion_) + return -std::sqrt(2.*M_PI)*(4.*M_PI*M_PI)*std::sin(2*M_PI*x); + else + return -std::sin(x); + } + + Scalar p_(Scalar x, Scalar y, Scalar t) const + { return (f1_(x) + f1_(y)) * f_(t) * f_(t); } + + Scalar dxP_ (Scalar x, Scalar y, Scalar t) const + { return df1_(x) * f_(t) * f_(t); } + + Scalar dyP_ (Scalar x, Scalar y, Scalar t) const + { return df1_(y) * f_(t) * f_(t); } + + Scalar u_(Scalar x, Scalar y, Scalar t) const + { return f2_(x)*df2_(y) * f_(t); } + + Scalar dtU_ (Scalar x, Scalar y, Scalar t) const + { return f2_(x)*df2_(y) * df_(t); } + + Scalar dxU_ (Scalar x, Scalar y, Scalar t) const + { return df2_(x)*df2_(y) * f_(t); } + + Scalar dyU_ (Scalar x, Scalar y, Scalar t) const + { return f2_(x)*ddf2_(y) * f_(t); } + + Scalar dxxU_ (Scalar x, Scalar y, Scalar t) const + { return ddf2_(x)*df2_(y) * f_(t); } + + Scalar dxyU_ (Scalar x, Scalar y, Scalar t) const + { return df2_(x)*ddf2_(y) * f_(t); } + + Scalar dyyU_ (Scalar x, Scalar y, Scalar t) const + { return f2_(x)*dddf2_(y) * f_(t); } + + Scalar v_(Scalar x, Scalar y, Scalar t) const + { return -f2_(y)*df2_(x) * f_(t); } + + Scalar dtV_ (Scalar x, Scalar y, Scalar t) const + { return -f2_(y)*df2_(x) * df_(t); } + + Scalar dxV_ (Scalar x, Scalar y, Scalar t) const + { return -f2_(y)*ddf2_(x) * f_(t); } + + Scalar dyV_ (Scalar x, Scalar y, Scalar t) const + { return -df2_(y)*df2_(x) * f_(t); } + + Scalar dyyV_ (Scalar x, Scalar y, Scalar t) const + { return -ddf2_(y)*df2_(x) * f_(t); } + + Scalar dxyV_ (Scalar x, Scalar y, Scalar t) const + { return -df2_(y)*ddf2_(x) * f_(t); } + + Scalar dxxV_ (Scalar x, Scalar y, Scalar t) const + { return -f2_(y)*dddf2_(x) * f_(t); } + + Scalar dxUU_ (Scalar x, Scalar y, Scalar t) const + { return 2.*u_(x,y,t)*dxU_(x,y,t); } + + Scalar dyVV_ (Scalar x, Scalar y, Scalar t) const + { return 2.*v_(x,y,t)*dyV_(x,y,t); } + + Scalar dxUV_ (Scalar x, Scalar y, Scalar t) const + { return v_(x,y,t)*dxU_(x,y,t) + u_(x,y,t)*dxV_(x,y,t); } + + Scalar dyUV_ (Scalar x, Scalar y, Scalar t) const + { return v_(x,y,t)*dyU_(x,y,t) + u_(x,y,t)*dyV_(x,y,t); } + + Scalar rho_; + Scalar mu_; + + static constexpr Scalar eps_ = 1e-6; + + Scalar time_; + Scalar timeStepSize_; + + bool isStationary_; + bool vanDerPlasVersion_; + bool enableInertiaTerms_; +}; + +} // end namespace Dumux + +#endif // DUMUX_SINCOS_TEST_PROBLEM_HH -- GitLab From 3d3982f8ae5143e60c2182620a9f149eaf993916 Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Tue, 14 Sep 2021 15:08:26 +0300 Subject: [PATCH 33/69] [sincos] remove old sincos --- .../navierstokes/sincos/CMakeLists.txt | 31 - appl/freeflow/navierstokes/sincos/main.cc | 561 ------------- .../freeflow/navierstokes/sincos/params.input | 80 -- .../sincos/paramsVanDerPlas.input | 62 -- .../navierstokes/sincos/params_grading.input | 65 -- .../sincos/params_grading_add_dof_bad.input | 65 -- .../navierstokes/sincos/params_uniform.input | 65 -- .../navierstokes/sincos/params_vdP_full.input | 79 -- .../sincos/params_vdP_full_vdP.input | 63 -- .../navierstokes/sincos/params_vdP_lin.input | 62 -- .../sincos/params_vdP_unrefined.input | 62 -- appl/freeflow/navierstokes/sincos/problem.hh | 758 ------------------ 12 files changed, 1953 deletions(-) delete mode 100644 appl/freeflow/navierstokes/sincos/CMakeLists.txt delete mode 100644 appl/freeflow/navierstokes/sincos/main.cc delete mode 100644 appl/freeflow/navierstokes/sincos/params.input delete mode 100644 appl/freeflow/navierstokes/sincos/paramsVanDerPlas.input delete mode 100644 appl/freeflow/navierstokes/sincos/params_grading.input delete mode 100644 appl/freeflow/navierstokes/sincos/params_grading_add_dof_bad.input delete mode 100644 appl/freeflow/navierstokes/sincos/params_uniform.input delete mode 100644 appl/freeflow/navierstokes/sincos/params_vdP_full.input delete mode 100644 appl/freeflow/navierstokes/sincos/params_vdP_full_vdP.input delete mode 100644 appl/freeflow/navierstokes/sincos/params_vdP_lin.input delete mode 100644 appl/freeflow/navierstokes/sincos/params_vdP_unrefined.input delete mode 100644 appl/freeflow/navierstokes/sincos/problem.hh diff --git a/appl/freeflow/navierstokes/sincos/CMakeLists.txt b/appl/freeflow/navierstokes/sincos/CMakeLists.txt deleted file mode 100644 index 98ad3fb..0000000 --- a/appl/freeflow/navierstokes/sincos/CMakeLists.txt +++ /dev/null @@ -1,31 +0,0 @@ -set(CMAKE_BUILD_TYPE Debug) - -add_input_file_links() - -dune_add_test(NAME test_ff_sincos - SOURCES main.cc - LABELS freeflow - TIMEOUT 1000 - CMAKE_GUARD HAVE_UMFPACK - COMMAND ./convergencetest.py - CMD_ARGS test_ff_navierstokes_sincos params.input - -Grid.UpperRight "6.28 6.28" - -Grid.Cells "150 150" - -Problem.Name test_ff_navierstokes_sincos_stationary_convergence - -Problem.IsStationary true - -Component.LiquidKinematicViscosity 0.001) - -dune_add_test(NAME test_ff_navierstokes_sincos_instationary - TARGET test_ff_sincos - LABELS freeflow - CMAKE_GUARD HAVE_UMFPACK - COMMAND ${CMAKE_SOURCE_DIR}/bin/testing/runtest.py - CMD_ARGS --script fuzzy - --files ${CMAKE_SOURCE_DIR}/../dumux/test/references/test_ff_navierstokes_sincos_instationary-reference.vtu - ${CMAKE_CURRENT_BINARY_DIR}/test_ff_navierstokes_sincos_instationary-00017.vtu - --command "${CMAKE_CURRENT_BINARY_DIR}/test_ff_navierstokes_sincos params.input - -Grid.UpperRight '1 1' - -Grid.Cells '50 50' - -Problem.Name test_ff_navierstokes_sincos_instationary - -Problem.IsStationary false - -Component.LiquidKinematicViscosity 0.1") diff --git a/appl/freeflow/navierstokes/sincos/main.cc b/appl/freeflow/navierstokes/sincos/main.cc deleted file mode 100644 index 7192a0e..0000000 --- a/appl/freeflow/navierstokes/sincos/main.cc +++ /dev/null @@ -1,561 +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 3 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 - * \ingroup NavierStokesTests - * \brief Test for the instationary staggered grid Navier-Stokes model - * with analytical solution. - */ - -bool doFirstOrderLocalTruncErrorGlobalRefinement = true; - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#pragma GCC diagnostic ignored "-Wdeprecated-copy" - -#include <config.h> - -#include <ctime> -#include <iostream> -#include <type_traits> -#include <tuple> - -#include <dumux/common/dumuxmessage.hh> -#include <dumux/common/parameters.hh> -#include <dumux/common/properties.hh> - -#include <dune/common/parallel/mpihelper.hh> -#include <dune/common/timer.hh> -#include <dune/grid/io/file/vtk/vtkwriter.hh> -#include <dune/grid/io/file/dgfparser/dgfwriter.hh> -#include <dune/grid/io/file/dgfparser/dgfexception.hh> -#include <dune/grid/io/file/vtk.hh> - -namespace Dumux { -namespace Properties { -template<class TypeTag, class MyTypeTag> -struct FaceVolumeVariables { using type = UndefinedProperty; }; //!< The secondary variables within a sub-control volume -} -} - -#include <dumux/assembly/cvdstaggeredrefinedfvassembler.hh> -#include <dumux/assembly/diffmethod.hh> - -#include <dumux/io/grid/gridmanager.hh> -#include <dumux/io/grid/cvdcontrolvolumegrids.hh> -#include <dumux/io/mystaggeredvtkoutputmodule.hh> -#include <dumux/io/readdofbasedresult.hh> -#include <dumux/linear/seqsolverbackend.hh> -#include <dumux/nonlinear/newtonsolver.hh> - -#include <dumux/adaptive/adapt.hh> -#include <dumux/adaptive/markelements.hh> - -#include <dumux/freeflow/cvdgridadaptindicator.hh> -#include <dumux/freeflow/navierstokes/staggered/griddatatransfer.hh> - -#include <dumux/discretization/staggered/cvdfvgridgeometry.hh> -#include <dumux/discretization/staggered/freeflow/cvdfvgridgeometrytraits.hh> - -#include <dumux/freeflow/navierstokes/staggered/cvdresidualCalc.hh> - -#include "problem.hh" - -/*! -* \brief Creates analytical solution. -* Returns a tuple of the analytical solution for the pressure, the velocity and the velocity at the faces -* \param time the time at which to evaluate the analytical solution -* \param problem the problem for which to evaluate the analytical solution -*/ -template<class TypeTag, class Scalar, class Problem> -auto createAnalyticalSolution(const Scalar time, const Problem& problem) -{ - using FaceSolutionVector = Dumux::GetPropType<TypeTag, Dumux::Properties::FaceSolutionVector>; - using CellCenterSolutionVector = Dumux::GetPropType<TypeTag, Dumux::Properties::CellCenterSolutionVector>; - - const auto& gridGeometry = problem.gridGeometry(); - using GridView = typename std::decay_t<decltype(gridGeometry)>::GridView; - - static constexpr auto dim = GridView::dimension; - static constexpr auto dimWorld = GridView::dimensionworld; - - using VelocityVector = Dune::FieldVector<Scalar, dimWorld>; - - CellCenterSolutionVector analyticalPressure; - std::vector<VelocityVector> analyticalVelocity; - std::vector<VelocityVector> analyticalVelocityOnFace; - FaceSolutionVector analyticalFaceSolutionVector; - - analyticalPressure.resize(gridGeometry.numCellCenterDofs()); - analyticalVelocity.resize(gridGeometry.numCellCenterDofs()); - analyticalVelocityOnFace.resize(gridGeometry.numFaceDofs()); - analyticalFaceSolutionVector.resize(gridGeometry.numFaceDofs()); - - using Indices = typename Problem::Indices; - for (const auto& element : elements(gridGeometry.gridView())) - { - auto fvGeometry = localView(gridGeometry); - fvGeometry.bindElement(element); - for (auto&& scv : scvs(fvGeometry)) - { - auto ccDofIdx = scv.dofIndex(); - auto ccDofPosition = scv.dofPosition(); - auto analyticalSolutionAtCc = problem.instationaryAnalyticalSolution(ccDofPosition, time); - - // velocities on faces - for (auto&& scvf : scvfs(fvGeometry)) - { - const auto faceDofIdx = scvf.dofIndex(); - const auto faceDofPosition = scvf.center(); - const auto dirIdx = scvf.directionIndex(); - const auto analyticalSolutionAtFace = problem.instationaryAnalyticalSolution(faceDofPosition, time); - analyticalVelocityOnFace[faceDofIdx][dirIdx] = analyticalSolutionAtFace[Indices::velocity(dirIdx)]; - analyticalFaceSolutionVector[faceDofIdx] = analyticalSolutionAtFace[Indices::velocity(dirIdx)]; - } - - analyticalPressure[ccDofIdx] = analyticalSolutionAtCc[Indices::pressureIdx]; - - for(int dirIdx = 0; dirIdx < dim; ++dirIdx) - analyticalVelocity[ccDofIdx][dirIdx] = analyticalSolutionAtCc[Indices::velocity(dirIdx)]; - } - } - - return std::make_tuple(analyticalPressure, analyticalVelocity, analyticalVelocityOnFace, analyticalFaceSolutionVector); -} - -template<class Problem> -auto createSource(const Problem& problem) -{ - using Scalar = double; - using Indices = typename Problem::Indices; - - const auto& gridGeometry = problem.gridGeometry(); - std::array<std::vector<Scalar>, Problem::ModelTraits::numEq()> source; - - for (auto& component : source) - { - component.resize(gridGeometry.numCellCenterDofs()); - } - - for (const auto& element : elements(gridGeometry.gridView())) - { - auto fvGeometry = localView(gridGeometry); - fvGeometry.bindElement(element); - for (auto&& scv : scvs(fvGeometry)) - { - auto ccDofIdx = scv.dofIndex(); - auto ccDofPosition = scv.dofPosition(); - - auto sourceAtPosVal = problem.sourceAtPos(ccDofPosition); - - source[Indices::momentumXBalanceIdx][ccDofIdx] = sourceAtPosVal[Indices::momentumXBalanceIdx]; - source[Indices::momentumYBalanceIdx][ccDofIdx] = sourceAtPosVal[Indices::momentumYBalanceIdx]; - } - } - - return source; -} - -template<class Problem, class SolutionVector, class GridGeometry> -void printL2Error(const Problem& problem, const SolutionVector& x, const GridGeometry& gridGeometry) -{ - using namespace Dumux; - using Scalar = double; - using TypeTag = Properties::TTag::SincosTest; - using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; - using ModelTraits = GetPropType<TypeTag, Properties::ModelTraits>; - using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>; - - using L2Error = NavierStokesTestL2Error<Scalar, ModelTraits, PrimaryVariables>; - const auto l2error = L2Error::calculateL2Error(*problem, x); - const int numCellCenterDofs = gridGeometry->numCellCenterDofs(); - const int numFaceDofs = gridGeometry->numFaceDofs(); - std::cout << std::setprecision(8) << "** L2 error (abs/rel) for " - << std::setw(6) << numCellCenterDofs << " cc dofs and " << numFaceDofs << " face dofs (total: " << numCellCenterDofs + numFaceDofs << "): " - << std::scientific - << "L2(p) = " << l2error.first[Indices::pressureIdx] << " / " << l2error.second[Indices::pressureIdx] - << " , L2(vx) = " << l2error.first[Indices::velocityXIdx] << " / " << l2error.second[Indices::velocityXIdx] - << " , L2(vy) = " << l2error.first[Indices::velocityYIdx] << " / " << l2error.second[Indices::velocityYIdx] - << std::endl; - - // write the norm into a log file - std::ofstream logFile; - logFile.open(problem->name() + ".log", std::ios::app); - logFile << "[ConvergenceTest] L2(p) = " << l2error.first[Indices::pressureIdx] << " L2(vx) = " << l2error.first[Indices::velocityXIdx] << " L2(vy) = " << l2error.first[Indices::velocityYIdx] << std::endl; - logFile.close(); -} - -int main(int argc, char** argv) try -{ - using namespace Dumux; - - // define the type tag for this problem - using TypeTag = Properties::TTag::SincosTest; - - // 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); - - using HelpingGridManager = Dumux::GridManager<GetPropType<TypeTag, Properties::HelpingGrid>>; - HelpingGridManager helpingGridManager; - helpingGridManager.init("Helper"); - const auto& helpingGridView = helpingGridManager.grid().leafGridView(); - Dune::DGFWriter dgfWriter(helpingGridView); - std::string inputFileName = getParam<std::string>("Grid.File"); - dgfWriter.write(inputFileName); - - // 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(); - bool adapt = getParam<bool>("Adaptivity.Adapt", false); - - using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; - using GridView = typename GridGeometry::GridView; - using Element = typename GridView::template Codim<0>::Entity; - using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - - if (adapt) - { - using Scalar = GetPropType<TypeTag, Properties::Scalar>; - - Scalar leftX = getParam<Scalar>("Adaptivity.LeftX"); - Scalar rightX = getParam<Scalar>("Adaptivity.RightX"); - Scalar lowerY = getParam<Scalar>("Adaptivity.LowerY"); - Scalar upperY = getParam<Scalar>("Adaptivity.UpperY"); - - gridManager.grid().preAdapt(); - - for (const auto& element : elements(leafGridView)) - { - GlobalPosition pos = element.geometry().center(); - - auto x = pos[0]; - auto y = pos[1]; - - if((leftX < x) && (x < rightX) && (y > lowerY) && (y < upperY)) - { - gridManager.grid().mark( 1, element); - } - } - gridManager.grid().adapt(); - gridManager.grid().postAdapt(); - } - - // create the finite volume grid geometry - using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; - auto gridGeometry = std::make_shared<GridGeometry>(leafGridView); - gridGeometry->update(); - - // get some time loop parameters - using Scalar = GetPropType<TypeTag, Properties::Scalar>; - const auto tEnd = getParam<Scalar>("TimeLoop.TEnd"); - const auto maxDt = getParam<Scalar>("TimeLoop.MaxTimeStepSize"); - auto dt = getParam<Scalar>("TimeLoop.DtInitial"); - - // instantiate time loop - auto timeLoop = std::make_shared<TimeLoop<Scalar>>(0.0, dt, tEnd); - timeLoop->setMaxTimeStepSize(maxDt); - - // the problem (initial and boundary conditions) - using Problem = GetPropType<TypeTag, Properties::Problem>; - auto problem = std::make_shared<Problem>(gridGeometry); - problem->updateTimeStepSize(timeLoop->timeStepSize()); - - // the solution vector - using SolutionVector = GetPropType<TypeTag, Properties::SolutionVector>; - SolutionVector x; - x[GridGeometry::cellCenterIdx()].resize(gridGeometry->numCellCenterDofs()); - x[GridGeometry::faceIdx()].resize(gridGeometry->numFaceDofs()); - 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 - MyStaggeredVtkOutputModule<GridVariables, SolutionVector> vtkWriter(*gridVariables, x, problem->name()); - using IOFields = GetPropType<TypeTag, Properties::IOFields>; - IOFields::initOutputModule(vtkWriter); // Add model specific output fields - - auto source = createSource(*problem); - auto sourceX = source[Problem::Indices::momentumXBalanceIdx]; - auto sourceY = source[Problem::Indices::momentumYBalanceIdx]; - vtkWriter.addField(sourceX, "sourceX"); - vtkWriter.addField(sourceY, "sourceY"); - - auto analyticalSolution = createAnalyticalSolution<TypeTag>(timeLoop->time(), *problem); - vtkWriter.addField(std::get<0>(analyticalSolution), "pressureExact"); - vtkWriter.addField(std::get<1>(analyticalSolution), "velocityExact"); - vtkWriter.addFaceField(std::get<2>(analyticalSolution), "faceVelocityExact"); - - if (getParam<bool>("Problem.ReadDofBasedPressure", false)) - { - using CellCenterSolutionVector = GetPropType<TypeTag, Properties::CellCenterSolutionVector>; - CellCenterSolutionVector IBAMRpres; - IBAMRpres.resize(gridGeometry->numCellCenterDofs()); - readDofBasedResult(IBAMRpres, gridGeometry, "pressure"); - vtkWriter.addField(IBAMRpres, "IBAMRpres"); - } - - vtkWriter.write(0.0); - - const bool isStationary = getParam<bool>("Problem.IsStationary"); - - // the assembler with time loop for instationary problem - using Assembler = CVDStaggeredRefinedFVAssembler<TypeTag, DiffMethod::numeric>; - auto assembler = isStationary ? std::make_shared<Assembler>(problem, gridGeometry, gridVariables) - : std::make_shared<Assembler>(problem, gridGeometry, gridVariables, timeLoop, xOld); - - // the linear solver - using LinearSolver = Dumux::UMFPackBackend; - auto linearSolver = std::make_shared<LinearSolver>(); - - // the non-linear solver - using NewtonSolver = Dumux::NewtonSolver<Assembler, LinearSolver>; - NewtonSolver nonLinearSolver(assembler, linearSolver); - - if (timeLoop->time() != 0) - DUNE_THROW(Dune::InvalidStateException, "Was expecting to start with time zero."); - - //here, the temporal starting value is for t=0, the iteration starting value is the analytical solution for t=deltaT - analyticalSolution = createAnalyticalSolution<TypeTag>(timeLoop->timeStepSize(), *problem); - SolutionVector analyticalFirstTimeStep; - analyticalFirstTimeStep[GridGeometry::faceIdx()] = std::get<3>(analyticalSolution); - analyticalFirstTimeStep[GridGeometry::cellCenterIdx()] = std::get<0>(analyticalSolution); - std::string filenamevars0 = "analyticalsol0"; - std::ofstream s; - s.open(filenamevars0 + ".csv"); - writeVectorToCSV(s, analyticalFirstTimeStep[Dune::index_constant<0>()]); - s.close(); - std::string filenamevars1 = "analyticalsol1"; - s.open(filenamevars1 + ".csv"); - writeVectorToCSV(s, analyticalFirstTimeStep[Dune::index_constant<1>()]); - s.close(); - gridVariables->update(analyticalFirstTimeStep); - nonLinearSolver.assembleLinearSystem(analyticalFirstTimeStep); - const auto faceResidualWithAnalyticalSol = (*assembler).residual()[Dune::index_constant<0>()]; - const auto ccResidualWithAnalyticalSol = (*assembler).residual()[Dune::index_constant<1>()]; - gridVariables->update(x); - - const bool shouldPrintL2Error = getParam<bool>("Problem.PrintL2Error"); - - int timeIndex = 0; - if (isStationary) - { - // get residuals for analytical solution - nonLinearSolver.assembleLinearSystem(x); - - const auto faceResidualWithAnalyticalSol = (*assembler).residual()[Dune::index_constant<0>()]; - const auto ccResidualWithAnalyticalSol = (*assembler).residual()[Dune::index_constant<1>()]; - - // linearize & solve - Dune::Timer timer; - nonLinearSolver.solve(x); - if (shouldPrintL2Error) - printL2Error(problem, x, gridGeometry); - - // write shifted control volumes vtk output - using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; - std::vector<FaceSolutionVector> outputVecs; - std::vector<std::string> outputVecNames; - - const FaceSolutionVector& vel = x[GridGeometry::faceIdx()]; - outputVecs.push_back(vel); - outputVecNames.push_back("velocity"); - - const FaceSolutionVector& anaVel = std::get<3>(analyticalSolution); - outputVecs.push_back(anaVel); - outputVecNames.push_back("analyticalVelocity"); - - FaceSolutionVector absVelocityError; - absVelocityError.resize((*gridGeometry).numIntersections()); - for (unsigned int i = 0; i < vel.size(); ++i) - { - absVelocityError[i] = std::abs(vel[i] - anaVel[i]); - } - outputVecs.push_back(absVelocityError); - outputVecNames.push_back("absVelocityError"); - - bool startWithAnalytical = getParam<bool>("Problem.StartWithAnalytical", false); - - auto resPres = ccResidualWithAnalyticalSol; - if (startWithAnalytical) - { - std::cout << "velocity residual norm = " << faceResidualWithAnalyticalSol.two_norm()/*velocity*/ << ", presssure residual norm = " << ccResidualWithAnalyticalSol.two_norm()/*pressure*/ << std::endl; - - outputCVResiduals<TypeTag>((*gridGeometry), faceResidualWithAnalyticalSol, *problem, outputVecs, outputVecNames); - - // write grid cells vtk output - for (const auto& element : elements((*gridGeometry).gridView())) - resPres[(*gridGeometry).gridView().indexSet().index(element)] /= element.geometry().volume(); - vtkWriter.addField(resPres, "continuityResidual"); - } - analyticalSolution = createAnalyticalSolution<TypeTag>(timeLoop->time(), *problem); - vtkWriter.write(1.0); - - timer.stop(); - - const auto& comm = Dune::MPIHelper::getCollectiveCommunication(); - std::cout << "Simulation took " << timer.elapsed() << " seconds on " - << comm.size() << " processes.\n" - << "The cumulative CPU time was " << timer.elapsed()*comm.size() << " seconds.\n"; - } - else - { - // 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(); - - if (shouldPrintL2Error) - { - printL2Error(problem, x, gridGeometry); - } - - // advance to the time loop to the next step - timeLoop->advanceTimeStep(); - problem->updateTime(timeLoop->time()); - analyticalSolution = createAnalyticalSolution<TypeTag>(timeLoop->time(), *problem); - - // write vtk output - if (timeIndex == 0) - { - // write shifted control volumes vtk output - using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; - std::vector<FaceSolutionVector> outputVecs; - std::vector<std::string> outputVecNames; - - const FaceSolutionVector& vel = x[GridGeometry::faceIdx()]; - outputVecs.push_back(vel); - outputVecNames.push_back("velocity"); - - const FaceSolutionVector& anaVel = std::get<3>(analyticalSolution); - outputVecs.push_back(anaVel); - outputVecNames.push_back("analyticalVelocity"); - - if (getParam<bool>("Problem.ReadDofBasedVelocity", false)) - { - using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; - FaceSolutionVector IBAMRvel; - IBAMRvel.resize(gridGeometry->numFaceDofs()); - - readDofBasedResult(IBAMRvel, gridGeometry, "velocity"); - outputVecs.push_back(IBAMRvel); - outputVecNames.push_back("IBAMRvel"); - } - - FaceSolutionVector absVelocityError; - absVelocityError.resize(gridGeometry->numFaceDofs()); - for (unsigned int i = 0; i < vel.size(); ++i) - { - absVelocityError[i] = std::abs(vel[i] - anaVel[i]); - } - outputVecs.push_back(absVelocityError); - outputVecNames.push_back("absVelocityError"); - - auto resPres = ccResidualWithAnalyticalSol; - std::cout << "velocity residual norm = " << faceResidualWithAnalyticalSol.two_norm()/*velocity*/ << ", presssure residual norm = " << ccResidualWithAnalyticalSol.two_norm()/*pressure*/ << std::endl; - - outputCVResidualsInstationary<TypeTag>(false, dt, 0., (*gridGeometry), faceResidualWithAnalyticalSol, *problem, outputVecs, outputVecNames); - - // write grid cells vtk output - for (const auto& element : elements((*gridGeometry).gridView())) - resPres[(*gridGeometry).gridView().indexSet().index(element)] /= element.geometry().volume(); - vtkWriter.addField(resPres, "continuityResidual"); // this then will be there in the 00001.vtu file - vtkWriter.write(timeLoop->time()); - } - else - { - vtkWriter.write(timeLoop->time()); - } - - // report statistics of this time step - timeLoop->reportTimeStep(); - - // set new dt as suggested by newton solver - timeLoop->setTimeStepSize(nonLinearSolver.suggestTimeStepSize(timeLoop->timeStepSize())); - problem->updateTimeStepSize(timeLoop->timeStepSize()); - - ++timeIndex; - } 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; -} -#pragma GCC diagnostic pop \ No newline at end of file diff --git a/appl/freeflow/navierstokes/sincos/params.input b/appl/freeflow/navierstokes/sincos/params.input deleted file mode 100644 index 90db6d3..0000000 --- a/appl/freeflow/navierstokes/sincos/params.input +++ /dev/null @@ -1,80 +0,0 @@ -[TimeLoop] -DtInitial = 0.01 # [s] -TEnd = 1.0 # [s] - -[Helper.Grid] -Positions0 = 0 1 -Positions1 = 0 1 -Cells0 = 20 -Cells1 = 20 -Grading0 = 1.0 -Grading1 = 1.0 - -[Grid] -File = grid.dgf - -[finexCVs.Grid] -File = finexCVs.dgf - -[fineyCVs.Grid] -File = fineyCVs.dgf - -[coarsexCVs.Grid] -File = coarsexCVs.dgf - -[coarseyCVs.Grid] -File = coarseyCVs.dgf - -[Problem] -Name = test_ff_sincos -EnableGravity = false -PrintL2Error = true -EnableInertiaTerms = true -IsStationary = true -ReadDofBasedVelocity = true -StartWithAnalytical = true - -[Component] -LiquidDensity = 1.0 -LiquidKinematicViscosity = 0.001 -MolarMass = 1.0 - -[Assembly] -NumericDifference.BaseEpsilon = 1e-8 - -[Newton] -MaxSteps = 10 -TargetSteps = 4 -MaxRelativeShift = 1e-5 -SatisfyResidualAndShiftCriterion = true -EnableAbsoluteResidualCriterion = true -MaxAbsoluteResidual = 1e-5 -OutputMatrices = false - -[Vtk] -WriteFaceData = false -AddProcessRank = false - -[Flux] -UpwindWeight = 0.5 - -[Adaptivity] -Conservation = false -Adapt = true -LeftX = 3 -RightX = 5 -LowerY = .2 -UpperY = .6 - -[VelocityReadIn] -NumFileEntries = 260 -XFileName = "/home/melanie/Desktop/daten_IBAMR/AngeliAMR/velocitiesXPositions.txt" -YFileName = "/home/melanie/Desktop/daten_IBAMR/AngeliAMR/velocitiesYPositions.txt" -ValueFileName = "/home/melanie/Desktop/daten_IBAMR/AngeliAMR/velocities.txt" - -[PressureReadIn] -NumFileEntries = 116; -XFileName = "/home/melanie/Desktop/daten_IBAMR/AngeliAMR/pressuresXPositions.txt" -YFileName = "/home/melanie/Desktop/daten_IBAMR/AngeliAMR/pressuresYPositions.txt" -ValuesFileName = "/home/melanie/Desktop/daten_IBAMR/AngeliAMR/pressures.txt" - diff --git a/appl/freeflow/navierstokes/sincos/paramsVanDerPlas.input b/appl/freeflow/navierstokes/sincos/paramsVanDerPlas.input deleted file mode 100644 index 769fbcc..0000000 --- a/appl/freeflow/navierstokes/sincos/paramsVanDerPlas.input +++ /dev/null @@ -1,62 +0,0 @@ -[TimeLoop] -DtInitial = 0.01 # [s] -TEnd = 1.0 # [s] - -[Helper.Grid] -Positions0 = 0.25 0.75 -Positions1 = 0.25 0.75 #we don't have symmetry BCs -Cells0 = 5 -Cells1 = 5 -Grading0 = 1.0 -Grading1 = 1.0 - -[xCVs.Grid] -File = xCVs.dgf - -[yCVs.Grid] -File = yCVs.dgf - -[Grid] -File = grid.dgf - -[Problem] -Name = test_ff_sincos -EnableGravity = false -PrintL2Error = true -EnableInertiaTerms = true -IsStationary = true -VanDerPlasVersion = true - -[Component] -LiquidDensity = 1.0 -LiquidKinematicViscosity = 0.05 -MolarMass = 1.0 - -[Assembly] -NumericDifference.BaseEpsilon = 1e-8 - -[Newton] -MaxSteps = 10 -TargetSteps = 4 -MaxRelativeShift = 1e-5 -SatisfyResidualAndShiftCriterion = true -EnableAbsoluteResidualCriterion = true -MaxAbsoluteResidual = 1e-5 -ExitAfterFirstIteration = false -OutputMatrices = false - -[Vtk] -WriteFaceData = false -AddProcessRank = false - -[Flux] -UpwindWeight = 0.5 - -[Adaptivity] -Conservation = false -LinearInterpolation = true -Adapt = true -LeftX = .4 -RightX = .6 -LowerY = .4 -UpperY = .6 diff --git a/appl/freeflow/navierstokes/sincos/params_grading.input b/appl/freeflow/navierstokes/sincos/params_grading.input deleted file mode 100644 index 72f5946..0000000 --- a/appl/freeflow/navierstokes/sincos/params_grading.input +++ /dev/null @@ -1,65 +0,0 @@ -[TimeLoop] -DtInitial = 0.01 # [s] -TEnd = 1.0 # [s] - -[Helper.Grid] -LowerLeft = 0 0 -UpperRight = 6.28 6.28 -Cells = 62 62 -Positions0 = 0 1.57 2.512 4.082 5.024 6.28 -Positions1 = 0 1.57 2.512 4.082 5.024 6.28 -Cells0 = 3 5 4 5 3 -Cells1 = 3 5 4 5 3 -Grading0 = 1 1 1 1 1 -Grading1 = 1 1 1 1 1 - -[Grid] -File = grid.dgf - -[Problem] -Name = grading -EnableGravity = false -PrintL2Error = true -EnableInertiaTerms = true -IsStationary = true - -[Component] -MolarMass = 1.0 -LiquidDensity = 1.0 -LiquidKinematicViscosity = 0.1 - -[Assembly] -NumericDifference.BaseEpsilon = 1e-8 - -[Newton] -MaxSteps = 10 -TargetSteps = 4 -MaxRelativeShift = 1e-5 -SatisfyResidualAndShiftCriterion = true -EnableAbsoluteResidualCriterion = true -MaxAbsoluteResidual = 1e-10 - -[Vtk] -WriteFaceData = false -AddProcessRank = false -Precision = Float64 - -[Flux] -UpwindWeight = 0.5 - -[LinearSolver] -Type = restartedflexiblegmressolver -Verbosity = 1 -GMResRestart = 50 - -[LinearSolver.Preconditioner] -Type = uzawa -Verbosity = 1 -Iterations = 5 - -[FreeFlow] -EnableVelocityGradientFactor = false - -[Adaptivity] -Conservation = false -Adapt = false diff --git a/appl/freeflow/navierstokes/sincos/params_grading_add_dof_bad.input b/appl/freeflow/navierstokes/sincos/params_grading_add_dof_bad.input deleted file mode 100644 index 07af795..0000000 --- a/appl/freeflow/navierstokes/sincos/params_grading_add_dof_bad.input +++ /dev/null @@ -1,65 +0,0 @@ -[TimeLoop] -DtInitial = 0.01 # [s] -TEnd = 1.0 # [s] - -[Helper.Grid] -LowerLeft = 0 0 -UpperRight = 6.28 6.28 -Cells = 62 62 -Positions0 = 0 1.57 2.512 4.082 5.024 6.28 -Positions1 = 0 1.57 2.512 4.082 5.024 6.28 -Cells0 = 4 5 4 5 4 -Cells1 = 4 5 4 5 4 -Grading0 = 1 1 1 1 1 -Grading1 = 1 1 1 1 1 - -[Grid] -File = grid.dgf - -[Problem] -Name = grading -EnableGravity = false -PrintL2Error = true -EnableInertiaTerms = true -IsStationary = true - -[Component] -MolarMass = 1.0 -LiquidDensity = 1.0 -LiquidKinematicViscosity = 0.1 - -[Assembly] -NumericDifference.BaseEpsilon = 1e-8 - -[Newton] -MaxSteps = 10 -TargetSteps = 4 -MaxRelativeShift = 1e-5 -SatisfyResidualAndShiftCriterion = true -EnableAbsoluteResidualCriterion = true -MaxAbsoluteResidual = 1e-10 - -[Vtk] -WriteFaceData = false -AddProcessRank = false -Precision = Float64 - -[Flux] -UpwindWeight = 0.5 - -[LinearSolver] -Type = restartedflexiblegmressolver -Verbosity = 1 -GMResRestart = 50 - -[LinearSolver.Preconditioner] -Type = uzawa -Verbosity = 1 -Iterations = 5 - -[FreeFlow] -EnableVelocityGradientFactor = false - -[Adaptivity] -Conservation = false -Adapt = false diff --git a/appl/freeflow/navierstokes/sincos/params_uniform.input b/appl/freeflow/navierstokes/sincos/params_uniform.input deleted file mode 100644 index 333a2b2..0000000 --- a/appl/freeflow/navierstokes/sincos/params_uniform.input +++ /dev/null @@ -1,65 +0,0 @@ -[TimeLoop] -DtInitial = 0.01 # [s] -TEnd = 1.0 # [s] - -[Helper.Grid] -LowerLeft = 0 0 -UpperRight = 6.28 6.28 -Cells = 62 62 -Positions0 = 0 6.28 -Positions1 = 0 6.28 -Cells0 = 20 -Cells1 = 20 -Grading0 = 1 -Grading1 = 1 - -[Grid] -File = grid.dgf - -[Problem] -Name = uniform -EnableGravity = false -PrintL2Error = true -EnableInertiaTerms = true -IsStationary = true - -[Component] -MolarMass = 1.0 -LiquidDensity = 1.0 -LiquidKinematicViscosity = 0.1 - -[Assembly] -NumericDifference.BaseEpsilon = 1e-8 - -[Newton] -MaxSteps = 10 -TargetSteps = 4 -MaxRelativeShift = 1e-5 -SatisfyResidualAndShiftCriterion = true -EnableAbsoluteResidualCriterion = true -MaxAbsoluteResidual = 1e-10 - -[Vtk] -WriteFaceData = false -AddProcessRank = false -Precision = Float64 - -[Flux] -UpwindWeight = 0.5 - -[LinearSolver] -Type = restartedflexiblegmressolver -Verbosity = 1 -GMResRestart = 50 - -[LinearSolver.Preconditioner] -Type = uzawa -Verbosity = 1 -Iterations = 5 - -[FreeFlow] -EnableVelocityGradientFactor = false - -[Adaptivity] -Conservation = false -Adapt = false diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_full.input b/appl/freeflow/navierstokes/sincos/params_vdP_full.input deleted file mode 100644 index 7d2b14a..0000000 --- a/appl/freeflow/navierstokes/sincos/params_vdP_full.input +++ /dev/null @@ -1,79 +0,0 @@ -[TimeLoop] -DtInitial = 0.01 # [s] -TEnd = 1.0 # [s] - -[Helper.Grid] -Positions0 = 0.25 0.75 -Positions1 = 0.25 0.75 #we don't have symmetry BCs -Cells0 = 10 -Cells1 = 10 -Grading0 = 1.0 -Grading1 = 1.0 - -[xCVs.Grid] -File = xCVs.dgf - -[yCVs.Grid] -File = yCVs.dgf - -[finexCVs.Grid] -File = finexCVs.dgf - -[fineyCVs.Grid] -File = fineyCVs.dgf - -[coarsexCVs.Grid] -File = coarsexCVs.dgf - -[coarseyCVs.Grid] -File = coarseyCVs.dgf - -[Grid] -File = grid.dgf - -[Problem] -Name = test_ff_sincos_vdP_full_42_bigresidual -EnableGravity = false -PrintL2Error = true -EnableInertiaTerms = true -IsStationary = true -VanDerPlasVersion = true -StartWithAnalytical = false -AveragedAnalyticalSolution = false - -[Component] -LiquidDensity = 1.0 -LiquidKinematicViscosity = 0.05 -MolarMass = 1.0 - -[Assembly] -NumericDifference.BaseEpsilon = 1e-8 - -[Newton] -MaxSteps = 10 -TargetSteps = 4 -MaxRelativeShift = 1e-5 -SatisfyResidualAndShiftCriterion = true -EnableAbsoluteResidualCriterion = true -MaxAbsoluteResidual = 1e-5 -ExitAfterFirstIteration = false -OutputMatrices = false - -[Vtk] -WriteFaceData = false -AddProcessRank = false - -[Flux] -UpwindWeight = 0.5 - -[Adaptivity] -NewParallelAlgo = false -UseOwn4PointCoefficients = false -Conservation = false -LinearInterpolation = false -DebugDof = -1 -Adapt = true -LeftX = .4 -RightX = .6 -LowerY = .4 -UpperY = .6 diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_full_vdP.input b/appl/freeflow/navierstokes/sincos/params_vdP_full_vdP.input deleted file mode 100644 index 2f5ea17..0000000 --- a/appl/freeflow/navierstokes/sincos/params_vdP_full_vdP.input +++ /dev/null @@ -1,63 +0,0 @@ -[TimeLoop] -DtInitial = 0.01 # [s] -TEnd = 1.0 # [s] - -[Helper.Grid] -Positions0 = 0.25 0.75 -Positions1 = 0.25 0.75 #we don't have symmetry BCs -Cells0 = 5 -Cells1 = 5 -Grading0 = 1.0 -Grading1 = 1.0 - -[xCVs.Grid] -File = xCVs.dgf - -[yCVs.Grid] -File = yCVs.dgf - -[Grid] -File = grid.dgf - -[Problem] -Name = test_ff_sincos -EnableGravity = false -PrintL2Error = true -EnableInertiaTerms = true -IsStationary = true -VanDerPlasVersion = true - -[Component] -LiquidDensity = 1.0 -LiquidKinematicViscosity = 0.05 -MolarMass = 1.0 - -[Assembly] -NumericDifference.BaseEpsilon = 1e-8 - -[Newton] -MaxSteps = 10 -TargetSteps = 4 -MaxRelativeShift = 1e-5 -SatisfyResidualAndShiftCriterion = true -EnableAbsoluteResidualCriterion = true -MaxAbsoluteResidual = 1e-5 -ExitAfterFirstIteration = false -OutputMatrices = false - -[Vtk] -WriteFaceData = false -AddProcessRank = false - -[Flux] -UpwindWeight = 0.5 - -[Adaptivity] -Conservation = false -LinearInterpolation = true -UseOwn4PointCoefficients = false -Adapt = true -LeftX = .4 -RightX = .6 -LowerY = .4 -UpperY = .6 diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_lin.input b/appl/freeflow/navierstokes/sincos/params_vdP_lin.input deleted file mode 100644 index 769fbcc..0000000 --- a/appl/freeflow/navierstokes/sincos/params_vdP_lin.input +++ /dev/null @@ -1,62 +0,0 @@ -[TimeLoop] -DtInitial = 0.01 # [s] -TEnd = 1.0 # [s] - -[Helper.Grid] -Positions0 = 0.25 0.75 -Positions1 = 0.25 0.75 #we don't have symmetry BCs -Cells0 = 5 -Cells1 = 5 -Grading0 = 1.0 -Grading1 = 1.0 - -[xCVs.Grid] -File = xCVs.dgf - -[yCVs.Grid] -File = yCVs.dgf - -[Grid] -File = grid.dgf - -[Problem] -Name = test_ff_sincos -EnableGravity = false -PrintL2Error = true -EnableInertiaTerms = true -IsStationary = true -VanDerPlasVersion = true - -[Component] -LiquidDensity = 1.0 -LiquidKinematicViscosity = 0.05 -MolarMass = 1.0 - -[Assembly] -NumericDifference.BaseEpsilon = 1e-8 - -[Newton] -MaxSteps = 10 -TargetSteps = 4 -MaxRelativeShift = 1e-5 -SatisfyResidualAndShiftCriterion = true -EnableAbsoluteResidualCriterion = true -MaxAbsoluteResidual = 1e-5 -ExitAfterFirstIteration = false -OutputMatrices = false - -[Vtk] -WriteFaceData = false -AddProcessRank = false - -[Flux] -UpwindWeight = 0.5 - -[Adaptivity] -Conservation = false -LinearInterpolation = true -Adapt = true -LeftX = .4 -RightX = .6 -LowerY = .4 -UpperY = .6 diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_unrefined.input b/appl/freeflow/navierstokes/sincos/params_vdP_unrefined.input deleted file mode 100644 index 0106de6..0000000 --- a/appl/freeflow/navierstokes/sincos/params_vdP_unrefined.input +++ /dev/null @@ -1,62 +0,0 @@ -[TimeLoop] -DtInitial = 0.01 # [s] -TEnd = 1.0 # [s] - -[Helper.Grid] -Positions0 = 0.25 0.75 -Positions1 = 0.25 0.75 #we don't have symmetry BCs -Cells0 = 5 -Cells1 = 5 -Grading0 = 1.0 -Grading1 = 1.0 - -[xCVs.Grid] -File = xCVs.dgf - -[yCVs.Grid] -File = yCVs.dgf - -[Grid] -File = grid.dgf - -[Problem] -Name = test_ff_sincos -EnableGravity = false -PrintL2Error = true -EnableInertiaTerms = true -IsStationary = true -VanDerPlasVersion = true - -[Component] -LiquidDensity = 1.0 -LiquidKinematicViscosity = 0.05 -MolarMass = 1.0 - -[Assembly] -NumericDifference.BaseEpsilon = 1e-8 - -[Newton] -MaxSteps = 10 -TargetSteps = 4 -MaxRelativeShift = 1e-5 -SatisfyResidualAndShiftCriterion = true -EnableAbsoluteResidualCriterion = true -MaxAbsoluteResidual = 1e-5 -ExitAfterFirstIteration = false -OutputMatrices = false - -[Vtk] -WriteFaceData = false -AddProcessRank = false - -[Flux] -UpwindWeight = 0.5 - -[Adaptivity] -Conservation = false -LinearInterpolation = false -Adapt = false -LeftX = .4 -RightX = .6 -LowerY = .4 -UpperY = .6 diff --git a/appl/freeflow/navierstokes/sincos/problem.hh b/appl/freeflow/navierstokes/sincos/problem.hh deleted file mode 100644 index c6232c6..0000000 --- a/appl/freeflow/navierstokes/sincos/problem.hh +++ /dev/null @@ -1,758 +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 3 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 - * \ingroup NavierStokesTests - * \brief Test for the staggered grid Navier-Stokes model - * with analytical solution. - */ -#ifndef DUMUX_CVD_SINCOS_TEST_PROBLEM_HH -#define DUMUX_CVD_SINCOS_TEST_PROBLEM_HH - -#include <dune/alugrid/grid.hh> -#include <dune/grid/yaspgrid.hh> - -#include <dumux/assembly/cvdstaggeredrefinedlocalresidual.hh> - -#include <dumux/material/fluidsystems/1pliquid.hh> -#include <dumux/material/components/constant.hh> - -#include <dumux/freeflow/navierstokes/cvdproblem.hh> -#include <dumux/freeflow/navierstokes/model.hh> - -#include <dumux/freeflow/navierstokes/boundarytypes.hh> -#include <dumux/freeflow/navierstokes/cvdlocalresidual.hh> -#include <dumux/freeflow/navierstokes/cvdfluxvariableswrapper.hh> -#include <dumux/freeflow/navierstokes/myvolumevariables.hh> -#include <dumux/freeflow/navierstokes/myiofields.hh> - -#include <dumux/discretization/staggered/freeflow/properties.hh> -#include <dumux/discretization/staggered/freeflow/myfacevariables.hh> -#include <dumux/discretization/staggered/freeflow/cvdlocalfacevariables.hh> -#include <dumux/discretization/staggered/freeflow/myvelocityoutput.hh> -#include <dumux/discretization/staggered/freeflow/mygridvolumevariables.hh> -#include <dumux/discretization/staggered/freeflow/elementvolumevariables1.hh> -#include <dumux/discretization/staggered/mygridfluxvariablescache.hh> -#include <dumux/discretization/staggered/myfacesolution.hh> -#include <dumux/discretization/staggered/cvdelementfacesolution.hh> -#include <dumux/discretization/staggered/cvdgridvariables.hh> -#include <dumux/discretization/staggered/cvdlocalgridfacevariables.hh> -#include <dumux/discretization/staggered/cvdfvgridgeometry.hh> -#include <dumux/discretization/staggered/freeflow/cvdfvgridgeometrytraits.hh> - -#include <appl/freeflow/navierstokes/l2error.hh> - -namespace Dumux { -template <class TypeTag> -class SincosTestProblem; - -namespace Properties { -// Create new type tags -namespace TTag { -struct SincosTest { using InheritsFrom = std::tuple<StaggeredFreeFlowModel, NavierStokes>; }; -} // end namespace TTag - -// the fluid system -template<class TypeTag> -struct FluidSystem<TypeTag, TTag::SincosTest> -{ -private: - using Scalar = GetPropType<TypeTag, Properties::Scalar>; -public: - using type = FluidSystems::OnePLiquid<Scalar, Components::Constant<1, Scalar> >; -}; - -// Set the grid type -template<class TypeTag> -struct Grid<TypeTag, TTag::SincosTest> { using type = Dune::ALUGrid<2,2,Dune::cube,Dune::nonconforming>; }; - -template<class TypeTag, class MyTypeTag> -struct HelpingGrid { using type = UndefinedProperty; }; - -// Set the grid type -template<class TypeTag> -struct HelpingGrid<TypeTag, TTag::SincosTest> -{ - using type = Dune::YaspGrid<2,Dune::TensorProductCoordinates<double, 2>>; -}; - -// Set the problem property -template<class TypeTag> -struct Problem<TypeTag, TTag::SincosTest> { using type = Dumux::SincosTestProblem<TypeTag> ; }; - -template<class TypeTag> -struct EnableGridGeometryCache<TypeTag, TTag::SincosTest> { static constexpr bool value = true; }; -template<class TypeTag> -struct EnableGridFluxVariablesCache<TypeTag, TTag::SincosTest> { static constexpr bool value = true; }; -template<class TypeTag> -struct EnableGridVolumeVariablesCache<TypeTag, TTag::SincosTest> { static constexpr bool value = true; }; - -//! The variables living on the faces -template<class TypeTag> -struct FaceVariables<TypeTag, TTag::SincosTest> -{ -private: - using FacePrimaryVariables = GetPropType<TypeTag, Properties::FacePrimaryVariables>; - using GridView = typename GetPropType<TypeTag, Properties::GridGeometry>::GridView; - static constexpr auto upwindSchemeOrder = getPropValue<TypeTag, Properties::UpwindSchemeOrder>(); - using ModelTraits = GetPropType<TypeTag, Properties::ModelTraits>; -public: - using type = MyStaggeredFaceVariables<ModelTraits, FacePrimaryVariables, GridView::dimension, upwindSchemeOrder>; -}; - -template<class TypeTag> -struct LocalFaceVariables<TypeTag, TTag::SincosTest> -{ -private: - using FacePrimaryVariables = GetPropType<TypeTag, Properties::FacePrimaryVariables>; -public: - using type = CVDStaggeredLocalFaceVariables<FacePrimaryVariables>; -}; - -//! The velocity output -template<class TypeTag> -struct VelocityOutput<TypeTag, TTag::SincosTest> -{ - using type = MyStaggeredFreeFlowVelocityOutput<GetPropType<TypeTag, Properties::GridVariables>, - GetPropType<TypeTag, Properties::SolutionVector>>; -}; - -//! Set the volume variables property -template<class TypeTag> -struct DualCVsVolVars<TypeTag, TTag::SincosTest> -{ -private: - using VV = GetPropType<TypeTag, Properties::VolumeVariables>; - using GridView = typename GetPropType<TypeTag, Properties::GridGeometry>::GridView; - static constexpr auto dimWorld = GridView::dimensionworld; - static constexpr int numPairs = 2 * (dimWorld - 1); - -public: - using type = NavierStokesDualCVsVolVars<VV, numPairs>; -}; - -//! Set the volume variables property -template<class TypeTag> -struct PrimalCVsVolVars<TypeTag, TTag::SincosTest> -{ -private: - using VV = GetPropType<TypeTag, Properties::VolumeVariables>; -public: - using type = std::array<NaviesStokesPrimalScvfPair<VV>,8>;//TODO make work for dim != 2 -}; - -//! Set the default global volume variables cache vector class -template<class TypeTag> -struct GridVolumeVariables<TypeTag, TTag::SincosTest> -{ -private: - using Problem = GetPropType<TypeTag, Properties::Problem>; - using VolumeVariables = GetPropType<TypeTag, Properties::VolumeVariables>; - using DualCVsVolVars = GetPropType<TypeTag, Properties::DualCVsVolVars>; - using PrimalCVsVolVars = GetPropType<TypeTag, Properties::PrimalCVsVolVars>; - using GridView = typename GetPropType<TypeTag, Properties::GridGeometry>::GridView; - using SubControlVolume = typename GetPropType<TypeTag, Properties::GridGeometry>::SubControlVolume; - using SubControlVolumeFace = typename GetPropType<TypeTag, Properties::GridGeometry>::SubControlVolumeFace; - static constexpr auto enableCache = getPropValue<TypeTag, Properties::EnableGridVolumeVariablesCache>(); - using Traits = MyStaggeredGridDefaultGridVolumeVariablesTraits<Problem, PrimalCVsVolVars, DualCVsVolVars, VolumeVariables, GridView, SubControlVolume, SubControlVolumeFace>; -public: - using type = MyStaggeredGridVolumeVariables<Traits, enableCache>; -}; - -//! Set the BaseLocalResidual to StaggeredLocalResidual -template<class TypeTag> -struct BaseLocalResidual<TypeTag, TTag::SincosTest> { using type = StaggeredRefinedLocalResidual<TypeTag>; }; - -//! Set the face solution type -template<class TypeTag> -struct StaggeredFaceSolution<TypeTag, TTag::SincosTest> -{ -private: - using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; -public: - using type = Dumux::MyStaggeredFaceSolution<FaceSolutionVector>; -}; - -template<class TypeTag> -struct ElementFaceSolution<TypeTag, TTag::SincosTest> -{ -private: - using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; -public: - using type = Dumux::CVDElementFaceSolution<FaceSolutionVector>; -}; - -//! Set the GridLocalFaceVariables -template<class TypeTag> -struct GridLocalFaceVariables<TypeTag, TTag::SincosTest> -{ - private: - using Problem = GetPropType<TypeTag, Properties::Problem>; - using LocalFaceVariables = GetPropType<TypeTag, Properties::LocalFaceVariables>; - static constexpr auto enableCache = getPropValue<TypeTag, Properties::EnableGridFaceVariablesCache>(); - public: - using type = CVDStaggeredLocalGridFaceVariables<Problem, LocalFaceVariables, enableCache>; -}; - -//! Set the grid variables (volume, flux and face variables) -template<class TypeTag> -struct GridVariables<TypeTag, TTag::SincosTest> -{ -private: - using GG = GetPropType<TypeTag, Properties::GridGeometry>; - using GVV = GetPropType<TypeTag, Properties::GridVolumeVariables>; - using GFVC = GetPropType<TypeTag, Properties::GridFluxVariablesCache>; - using GFV = GetPropType<TypeTag, Properties::GridFaceVariables>; - using GLFV = GetPropType<TypeTag, Properties::GridLocalFaceVariables>; -public: - using type = CVDStaggeredGridVariables<GG, GVV, GFVC, GFV, GLFV>; -}; - -//! The default fv grid geometry -template<class TypeTag> -struct GridGeometry<TypeTag, TTag::SincosTest> -{ -private: - static constexpr auto upwindSchemeOrder = getPropValue<TypeTag, Properties::UpwindSchemeOrder>(); - static constexpr bool enableCache = getPropValue<TypeTag, Properties::EnableGridGeometryCache>(); - using GridView = typename GetPropType<TypeTag, Properties::Grid>::LeafGridView; - using Traits = CVDStaggeredFreeFlowDefaultGridGeometryTraits<GridView, upwindSchemeOrder>; -public: - using type = CVDStaggeredGridGeometry<GridView, enableCache, Traits>; -}; - -//! Set the volume variables property -template<class TypeTag> -struct VolumeVariables<TypeTag, TTag::SincosTest> -{ -private: - using PV = GetPropType<TypeTag, Properties::PrimaryVariables>; - using FSY = GetPropType<TypeTag, Properties::FluidSystem>; - using FST = GetPropType<TypeTag, Properties::FluidState>; - using MT = GetPropType<TypeTag, Properties::ModelTraits>; - - static_assert(FSY::numPhases == MT::numFluidPhases(), "Number of phases mismatch between model and fluid system"); - static_assert(FST::numPhases == MT::numFluidPhases(), "Number of phases mismatch between model and fluid state"); - static_assert(!FSY::isMiscible(), "The Navier-Stokes model only works with immiscible fluid systems."); - - using Traits = NavierStokesVolumeVariablesTraits<PV, FSY, FST, MT>; -public: - using type = MyNavierStokesVolumeVariables<Traits>; -}; - -//! The local residual -template<class TypeTag> -struct LocalResidual<TypeTag, TTag::SincosTest> { using type = RefinedNavierStokesResidual<TypeTag>; }; - -//! The flux variables -template<class TypeTag> -struct FluxVariables<TypeTag, TTag::SincosTest> { using type = RefinedNavierStokesFluxVariables<TypeTag>; }; - -//! The specific I/O fields -template<class TypeTag> -struct IOFields<TypeTag, TTag::SincosTest> { using type = MyNavierStokesIOFields; }; - -//! Set the global flux variables cache vector class -template<class TypeTag> -struct GridFluxVariablesCache<TypeTag, TTag::SincosTest> -{ -private: - using Problem = GetPropType<TypeTag, Properties::Problem>; - using FluxVariablesCache = GetPropType<TypeTag, Properties::FluxVariablesCache>; - using FluxVariablesCacheFiller = GetPropType<TypeTag, Properties::FluxVariablesCacheFiller>; - static constexpr auto enableCache = getPropValue<TypeTag, Properties::EnableGridFluxVariablesCache>(); - static constexpr auto upwindSchemeOrder = getPropValue<TypeTag, Properties::UpwindSchemeOrder>(); -public: - using type = MyStaggeredGridFluxVariablesCache<Problem, FluxVariablesCache, FluxVariablesCacheFiller, enableCache, upwindSchemeOrder>; -}; - -template<class TypeTag> -struct CVGridGeometry<TypeTag, TTag::SincosTest> -{ -private: - static constexpr auto upwindSchemeOrder = getPropValue<TypeTag, Properties::UpwindSchemeOrder>(); - static constexpr bool enableCache = getPropValue<TypeTag, Properties::EnableGridGeometryCache>(); - using GridView = typename Dune::ALUGrid<2,2,Dune::cube,Dune::nonconforming >::LeafGridView; - using Traits = CVDStaggeredFreeFlowDefaultGridGeometryTraits<GridView, upwindSchemeOrder>; -public: - using type = CVDStaggeredGridGeometry<GridView, enableCache, Traits>; -}; -} // end namespace Properties - -/*! - * \ingroup NavierStokesTests - * \brief Test problem for the staggered grid. - * - * The 2D, incompressible Navier-Stokes equations for zero gravity and a Newtonian - * flow is solved and compared to an analytical solution (sums/products of trigonometric functions). - * For the instationary case, the velocities and pressures are periodical in time. The Dirichlet boundary conditions are - * consistent with the analytical solution and in the instationary case time-dependent. - */ -template <class TypeTag> -class SincosTestProblem : public MyNavierStokesProblem<TypeTag> -{ - using ParentType = MyNavierStokesProblem<TypeTag>; - - using BoundaryTypes = Dumux::NavierStokesBoundaryTypes<GetPropType<TypeTag, Properties::ModelTraits>::numEq()>; - using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; - using NumEqVector = GetPropType<TypeTag, Properties::NumEqVector>; - using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>; - using Scalar = GetPropType<TypeTag, Properties::Scalar>; - using SolutionVector = GetPropType<TypeTag, Properties::SolutionVector>; - using TimeLoopPtr = std::shared_ptr<TimeLoop<Scalar>>; - using SubControlVolume = typename GridGeometry::SubControlVolume; - using FVElementGeometry = typename GridGeometry::LocalView; - - static constexpr auto dimWorld = GetPropType<TypeTag, Properties::GridGeometry>::GridView::dimensionworld; - using Element = typename GridGeometry::GridView::template Codim<0>::Entity; - using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - using VelocityVector = Dune::FieldVector<Scalar, dimWorld>; - -public: - using ModelTraits = GetPropType<TypeTag, Properties::ModelTraits>; - using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; - - SincosTestProblem(std::shared_ptr<const GridGeometry> gridGeometry) - : ParentType(gridGeometry), time_(0.0), timeStepSize_(0.0) - { - isStationary_ = getParam<bool>("Problem.IsStationary"); - vanDerPlasVersion_ = getParam<bool>("Problem.VanDerPlasVersion", false); - - if (vanDerPlasVersion_) - isStationary_=true; - - enableInertiaTerms_ = getParam<bool>("Problem.EnableInertiaTerms"); - rho_ = getParam<Scalar>("Component.LiquidDensity"); - //kinematic - Scalar nu = getParam<Scalar>("Component.LiquidKinematicViscosity", 1.0); - //dynamic - mu_ = rho_*nu; - } - - /*! - * \brief Returns the temperature within the domain in [K]. - * - * This problem assumes a temperature of 10 degrees Celsius. - */ - Scalar temperature() const - { return 298.0; } - - /*! - * \brief Return the sources within the domain. - * - * \param globalPos The global position - */ - NumEqVector instationarySourceAtPos(const GlobalPosition &globalPos, Scalar t) const - { - NumEqVector source(0.0); - const Scalar x = globalPos[0]; - const Scalar y = globalPos[1]; - - source[Indices::momentumXBalanceIdx] = rho_*dtU_(x,y,t) - 2.*mu_*dxxU_(x,y,t) - mu_*dyyU_(x,y,t) - mu_*dxyV_(x,y,t) + dxP_(x,y,t); - source[Indices::momentumYBalanceIdx] = rho_*dtV_(x,y,t) - 2.*mu_*dyyV_(x,y,t) - mu_*dxyU_(x,y,t) - mu_*dxxV_(x,y,t) + dyP_(x,y,t); - - if (enableInertiaTerms_) - { - source[Indices::momentumXBalanceIdx] += rho_*dxUU_(x,y,t) + rho_*dyUV_(x,y,t); - source[Indices::momentumYBalanceIdx] += rho_*dxUV_(x,y,t) + rho_*dyVV_(x,y,t); - } - - return source; - } - - - NumEqVector sourceAtPos(const GlobalPosition &globalPos) const - { - const Scalar t = time_ + timeStepSize_; - return instationarySourceAtPos(globalPos,t); - } - - // \} - /*! - * \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 values; - - // set Dirichlet values for the velocity everywhere - values.setDirichlet(Indices::velocityXIdx); - values.setDirichlet(Indices::velocityYIdx); - - return values; - } - - /*! - * \brief Returns whether a fixed Dirichlet value shall be used at a given cell. - * - * \param element The finite element - * \param fvGeometry The finite-volume geometry - * \param scv The sub control volume - * \param pvIdx The primary variable index in the solution vector - */ - bool isDirichletCell(const Element& element, - const FVElementGeometry& fvGeometry, - const SubControlVolume& scv, - int pvIdx) const - { - // set fixed pressure in one cell - return (scv.dofIndex() == 0) && pvIdx == Indices::pressureIdx; - } - - /*! - * \brief Returns Dirichlet boundary values at a given position. - * - * \param globalPos The global position - */ - PrimaryVariables dirichletAtPos(const GlobalPosition & globalPos) const - { - // use the values of the analytical solution - return this->instationaryAnalyticalSolution(globalPos, time_+timeStepSize_); - } - - /*! - * \brief Returns the analytical solution of the problem at a given time and position. - * - * \param globalPos The global position - * \param time The current simulation time - */ - PrimaryVariables instationaryAnalyticalSolutionAtPos(const GlobalPosition& globalPos, const Scalar t) const - { - const Scalar x = globalPos[0]; - const Scalar y = globalPos[1]; - - PrimaryVariables values = {}; - - for (unsigned int j = 0; j < 2; ++j) - { - for (unsigned int i = 0; i < values.size(); ++i) - { - values[i] += xFactorAnalyticalSolutionAtPos(x,t)[j][i]*yFactorAnalyticalSolutionAtPos(y,t)[j][i]; - } - } - - return values; - } - - /*! - * \brief Returns the analytical solution of the problem at a given position. - * - * \param globalPos The global position - */ - PrimaryVariables analyticalSolution(const GlobalPosition& globalPos) const - { - return this->instationaryAnalyticalSolution(globalPos, time_+timeStepSize_); - } - - /*! - * \brief Returns the analytical solution of the problem at a given position. - * - * \param globalPos The global position - */ - PrimaryVariables analyticalSolutionAtPos(const GlobalPosition& globalPos) const - { - return this->instationaryAnalyticalSolutionAtPos(globalPos, time_+timeStepSize_); - } - - std::array<PrimaryVariables, 2> xFactorAnalyticalSolutionAtPos(Scalar x, Scalar t) const - { - PrimaryVariables values1; - values1[Indices::pressureIdx] = f1_(x) * f_(t) * f_(t); - values1[Indices::velocityXIdx] = f2_(x) * f_(t); - values1[Indices::velocityYIdx] = - df2_(x) * f_(t); - - PrimaryVariables values2 = {}; - values2[Indices::pressureIdx] = 1.; - - std::array<PrimaryVariables, 2> retPair; - retPair[0] = values1; - retPair[1] = values2; - - return retPair; - } - - std::array<PrimaryVariables, 2> yFactorAnalyticalSolutionAtPos(Scalar y, Scalar t) const - { - PrimaryVariables values1; - values1[Indices::pressureIdx] = 1.; - values1[Indices::velocityXIdx] = df2_(y); - values1[Indices::velocityYIdx] = f2_(y); - - PrimaryVariables values2 = {}; - values2[Indices::pressureIdx] = f1_(y)* f_(t) * f_(t); - - std::array<PrimaryVariables, 2> retPair; - retPair[0] = values1; - retPair[1] = values2; - - return retPair; - } - - std::array<PrimaryVariables, 2> xFactorAnalyticalSolutionAntiderivativeAtPos(Scalar x, Scalar t) const - { - PrimaryVariables values1; - values1[Indices::pressureIdx] = intf1_(x) * f_(t) * f_(t); - values1[Indices::velocityXIdx] = intf2_(x) * f_(t); - values1[Indices::velocityYIdx] = - f2_(x) * f_(t); - - PrimaryVariables values2 = {}; - values2[Indices::pressureIdx] = x; - - std::array<PrimaryVariables, 2> retPair; - retPair[0] = values1; - retPair[1] = values2; - - return retPair; - } - - std::array<PrimaryVariables, 2> yFactorAnalyticalSolutionAntiderivativeAtPos(Scalar y, Scalar t) const - { - PrimaryVariables values1; - values1[Indices::pressureIdx] = y; - values1[Indices::velocityXIdx] = f2_(y); - values1[Indices::velocityYIdx] = intf2_(y); - - PrimaryVariables values2 = {}; - values2[Indices::pressureIdx] = intf1_(y)* f_(t) * f_(t); - - std::array<PrimaryVariables, 2> retPair; - retPair[0] = values1; - retPair[1] = values2; - - return retPair; - } - - // \} - - /*! - * \name Volume terms - */ - // \{ - - /*! - * \brief Evaluates the initial value for a control volume. - * - * \param globalPos The global position - */ - PrimaryVariables initialAtPos(const GlobalPosition &globalPos) const - { - bool startWithAnalytical = getParam<bool>("Problem.StartWithAnalytical", false); - - if (startWithAnalytical) - return this->instationaryAnalyticalSolution(globalPos,0.); - - if (isStationary_) - { - PrimaryVariables values; - values[Indices::pressureIdx] = 0.0; - values[Indices::velocityXIdx] = 0.0; - values[Indices::velocityYIdx] = 0.0; - - return values; - } - else - { - return this->instationaryAnalyticalSolution(globalPos, 0.0); - } - } - - /*! - * \brief Updates the time - */ - void updateTime(const Scalar time) - { - time_ = time; - } - - /*! - * \brief Updates the time step size - */ - void updateTimeStepSize(const Scalar timeStepSize) - { - timeStepSize_ = timeStepSize; - } - -private: - Scalar f_(Scalar t) const - { - if (isStationary_) - return 1.0; - else - return std::sin(2.0 * t); - } - - Scalar df_(Scalar t) const - { - if (isStationary_) - return 0.0; - else - return 2.0 * std::cos(2.0 * t); - } - - Scalar intf1_(Scalar x) const - { - if (vanDerPlasVersion_)//p. 136 - return std::sin(2.*M_PI*x)/(2.*M_PI); - else - return -0.125 * std::sin(2.0 * x); - } - - Scalar f1_(Scalar x) const - { - if (vanDerPlasVersion_)//p. 136 - return std::cos(2.*M_PI*x); - else - return -0.25 * std::cos(2.0 * x); - } - - Scalar df1_(Scalar x) const - { - if (vanDerPlasVersion_) - return -2.*M_PI*std::sin(2.*M_PI*x); - else - return 0.5 * std::sin(2.0 * x); - } - - Scalar intf2_(Scalar x) const - { - if (vanDerPlasVersion_) - return -std::sin(2.*M_PI*x)/(2.*M_PI*std::sqrt(2.*M_PI));//p. 136 - else - return -std::sin(x); - } - - Scalar f2_(Scalar x) const - { - if (vanDerPlasVersion_) - return -std::cos(2.*M_PI*x)/std::sqrt(2.*M_PI);//p. 136 - else - return -std::cos(x); - } - - Scalar df2_(Scalar x) const - { - if (vanDerPlasVersion_) - return std::sqrt(2.*M_PI)*std::sin(2.*M_PI*x); - else - return std::sin(x); - } - - Scalar ddf2_(Scalar x) const - { - if (vanDerPlasVersion_) - return std::sqrt(2.*M_PI)*(2.*M_PI)*std::cos(2*M_PI*x); - else - return std::cos(x); - } - - Scalar dddf2_(Scalar x) const - { - if (vanDerPlasVersion_) - return -std::sqrt(2.*M_PI)*(4.*M_PI*M_PI)*std::sin(2*M_PI*x); - else - return -std::sin(x); - } - - Scalar p_(Scalar x, Scalar y, Scalar t) const - { return (f1_(x) + f1_(y)) * f_(t) * f_(t); } - - Scalar dxP_ (Scalar x, Scalar y, Scalar t) const - { return df1_(x) * f_(t) * f_(t); } - - Scalar dyP_ (Scalar x, Scalar y, Scalar t) const - { return df1_(y) * f_(t) * f_(t); } - - Scalar u_(Scalar x, Scalar y, Scalar t) const - { return f2_(x)*df2_(y) * f_(t); } - - Scalar dtU_ (Scalar x, Scalar y, Scalar t) const - { return f2_(x)*df2_(y) * df_(t); } - - Scalar dxU_ (Scalar x, Scalar y, Scalar t) const - { return df2_(x)*df2_(y) * f_(t); } - - Scalar dyU_ (Scalar x, Scalar y, Scalar t) const - { return f2_(x)*ddf2_(y) * f_(t); } - - Scalar dxxU_ (Scalar x, Scalar y, Scalar t) const - { return ddf2_(x)*df2_(y) * f_(t); } - - Scalar dxyU_ (Scalar x, Scalar y, Scalar t) const - { return df2_(x)*ddf2_(y) * f_(t); } - - Scalar dyyU_ (Scalar x, Scalar y, Scalar t) const - { return f2_(x)*dddf2_(y) * f_(t); } - - Scalar v_(Scalar x, Scalar y, Scalar t) const - { return -f2_(y)*df2_(x) * f_(t); } - - Scalar dtV_ (Scalar x, Scalar y, Scalar t) const - { return -f2_(y)*df2_(x) * df_(t); } - - Scalar dxV_ (Scalar x, Scalar y, Scalar t) const - { return -f2_(y)*ddf2_(x) * f_(t); } - - Scalar dyV_ (Scalar x, Scalar y, Scalar t) const - { return -df2_(y)*df2_(x) * f_(t); } - - Scalar dyyV_ (Scalar x, Scalar y, Scalar t) const - { return -ddf2_(y)*df2_(x) * f_(t); } - - Scalar dxyV_ (Scalar x, Scalar y, Scalar t) const - { return -df2_(y)*ddf2_(x) * f_(t); } - - Scalar dxxV_ (Scalar x, Scalar y, Scalar t) const - { return -f2_(y)*dddf2_(x) * f_(t); } - - Scalar dxUU_ (Scalar x, Scalar y, Scalar t) const - { return 2.*u_(x,y,t)*dxU_(x,y,t); } - - Scalar dyVV_ (Scalar x, Scalar y, Scalar t) const - { return 2.*v_(x,y,t)*dyV_(x,y,t); } - - Scalar dxUV_ (Scalar x, Scalar y, Scalar t) const - { return v_(x,y,t)*dxU_(x,y,t) + u_(x,y,t)*dxV_(x,y,t); } - - Scalar dyUV_ (Scalar x, Scalar y, Scalar t) const - { return v_(x,y,t)*dyU_(x,y,t) + u_(x,y,t)*dyV_(x,y,t); } - - Scalar rho_; - Scalar mu_; - - static constexpr Scalar eps_ = 1e-6; - - Scalar time_; - Scalar timeStepSize_; - - bool isStationary_; - bool vanDerPlasVersion_; - bool enableInertiaTerms_; -}; - -} // end namespace Dumux - -#endif // DUMUX_SINCOS_TEST_PROBLEM_HH -- GitLab From 22eb9e573db4e9b25479bb1b8c5a6cd22551452d Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Tue, 14 Sep 2021 15:08:55 +0300 Subject: [PATCH 34/69] [sincos] rename sincos_copy to sincos --- appl/freeflow/navierstokes/CMakeLists.txt | 2 +- .../navierstokes/{sincos_copy => sincos}/CMakeLists.txt | 0 appl/freeflow/navierstokes/{sincos_copy => sincos}/main.cc | 0 appl/freeflow/navierstokes/{sincos_copy => sincos}/params.input | 0 .../navierstokes/{sincos_copy => sincos}/paramsVanDerPlas.input | 0 .../navierstokes/{sincos_copy => sincos}/params_grading.input | 0 .../{sincos_copy => sincos}/params_grading_add_dof_bad.input | 0 .../navierstokes/{sincos_copy => sincos}/params_uniform.input | 0 .../navierstokes/{sincos_copy => sincos}/params_vdP_full.input | 0 .../{sincos_copy => sincos}/params_vdP_full_vdP.input | 0 .../navierstokes/{sincos_copy => sincos}/params_vdP_lin.input | 0 .../{sincos_copy => sincos}/params_vdP_unrefined.input | 0 appl/freeflow/navierstokes/{sincos_copy => sincos}/problem.hh | 0 13 files changed, 1 insertion(+), 1 deletion(-) rename appl/freeflow/navierstokes/{sincos_copy => sincos}/CMakeLists.txt (100%) rename appl/freeflow/navierstokes/{sincos_copy => sincos}/main.cc (100%) rename appl/freeflow/navierstokes/{sincos_copy => sincos}/params.input (100%) rename appl/freeflow/navierstokes/{sincos_copy => sincos}/paramsVanDerPlas.input (100%) rename appl/freeflow/navierstokes/{sincos_copy => sincos}/params_grading.input (100%) rename appl/freeflow/navierstokes/{sincos_copy => sincos}/params_grading_add_dof_bad.input (100%) rename appl/freeflow/navierstokes/{sincos_copy => sincos}/params_uniform.input (100%) rename appl/freeflow/navierstokes/{sincos_copy => sincos}/params_vdP_full.input (100%) rename appl/freeflow/navierstokes/{sincos_copy => sincos}/params_vdP_full_vdP.input (100%) rename appl/freeflow/navierstokes/{sincos_copy => sincos}/params_vdP_lin.input (100%) rename appl/freeflow/navierstokes/{sincos_copy => sincos}/params_vdP_unrefined.input (100%) rename appl/freeflow/navierstokes/{sincos_copy => sincos}/problem.hh (100%) diff --git a/appl/freeflow/navierstokes/CMakeLists.txt b/appl/freeflow/navierstokes/CMakeLists.txt index f74e1ad..718c8c5 100644 --- a/appl/freeflow/navierstokes/CMakeLists.txt +++ b/appl/freeflow/navierstokes/CMakeLists.txt @@ -1,4 +1,4 @@ add_subdirectory(donea) add_subdirectory(channel) -add_subdirectory(sincos_copy) +add_subdirectory(sincos) add_subdirectory(angeli) diff --git a/appl/freeflow/navierstokes/sincos_copy/CMakeLists.txt b/appl/freeflow/navierstokes/sincos/CMakeLists.txt similarity index 100% rename from appl/freeflow/navierstokes/sincos_copy/CMakeLists.txt rename to appl/freeflow/navierstokes/sincos/CMakeLists.txt diff --git a/appl/freeflow/navierstokes/sincos_copy/main.cc b/appl/freeflow/navierstokes/sincos/main.cc similarity index 100% rename from appl/freeflow/navierstokes/sincos_copy/main.cc rename to appl/freeflow/navierstokes/sincos/main.cc diff --git a/appl/freeflow/navierstokes/sincos_copy/params.input b/appl/freeflow/navierstokes/sincos/params.input similarity index 100% rename from appl/freeflow/navierstokes/sincos_copy/params.input rename to appl/freeflow/navierstokes/sincos/params.input diff --git a/appl/freeflow/navierstokes/sincos_copy/paramsVanDerPlas.input b/appl/freeflow/navierstokes/sincos/paramsVanDerPlas.input similarity index 100% rename from appl/freeflow/navierstokes/sincos_copy/paramsVanDerPlas.input rename to appl/freeflow/navierstokes/sincos/paramsVanDerPlas.input diff --git a/appl/freeflow/navierstokes/sincos_copy/params_grading.input b/appl/freeflow/navierstokes/sincos/params_grading.input similarity index 100% rename from appl/freeflow/navierstokes/sincos_copy/params_grading.input rename to appl/freeflow/navierstokes/sincos/params_grading.input diff --git a/appl/freeflow/navierstokes/sincos_copy/params_grading_add_dof_bad.input b/appl/freeflow/navierstokes/sincos/params_grading_add_dof_bad.input similarity index 100% rename from appl/freeflow/navierstokes/sincos_copy/params_grading_add_dof_bad.input rename to appl/freeflow/navierstokes/sincos/params_grading_add_dof_bad.input diff --git a/appl/freeflow/navierstokes/sincos_copy/params_uniform.input b/appl/freeflow/navierstokes/sincos/params_uniform.input similarity index 100% rename from appl/freeflow/navierstokes/sincos_copy/params_uniform.input rename to appl/freeflow/navierstokes/sincos/params_uniform.input diff --git a/appl/freeflow/navierstokes/sincos_copy/params_vdP_full.input b/appl/freeflow/navierstokes/sincos/params_vdP_full.input similarity index 100% rename from appl/freeflow/navierstokes/sincos_copy/params_vdP_full.input rename to appl/freeflow/navierstokes/sincos/params_vdP_full.input diff --git a/appl/freeflow/navierstokes/sincos_copy/params_vdP_full_vdP.input b/appl/freeflow/navierstokes/sincos/params_vdP_full_vdP.input similarity index 100% rename from appl/freeflow/navierstokes/sincos_copy/params_vdP_full_vdP.input rename to appl/freeflow/navierstokes/sincos/params_vdP_full_vdP.input diff --git a/appl/freeflow/navierstokes/sincos_copy/params_vdP_lin.input b/appl/freeflow/navierstokes/sincos/params_vdP_lin.input similarity index 100% rename from appl/freeflow/navierstokes/sincos_copy/params_vdP_lin.input rename to appl/freeflow/navierstokes/sincos/params_vdP_lin.input diff --git a/appl/freeflow/navierstokes/sincos_copy/params_vdP_unrefined.input b/appl/freeflow/navierstokes/sincos/params_vdP_unrefined.input similarity index 100% rename from appl/freeflow/navierstokes/sincos_copy/params_vdP_unrefined.input rename to appl/freeflow/navierstokes/sincos/params_vdP_unrefined.input diff --git a/appl/freeflow/navierstokes/sincos_copy/problem.hh b/appl/freeflow/navierstokes/sincos/problem.hh similarity index 100% rename from appl/freeflow/navierstokes/sincos_copy/problem.hh rename to appl/freeflow/navierstokes/sincos/problem.hh -- GitLab From db0672c203b4e9062e1d462026738fa6516aa9c5 Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Tue, 14 Sep 2021 15:30:41 +0300 Subject: [PATCH 35/69] [gauss_local] added gauss local test --- appl/freeflow/navierstokes/CMakeLists.txt | 1 + .../navierstokes/gaussLocal/CMakeLists.txt | 7 + appl/freeflow/navierstokes/gaussLocal/main.cc | 470 +++++++++++++ .../navierstokes/gaussLocal/params.input | 75 ++ .../navierstokes/gaussLocal/problem.hh | 657 ++++++++++++++++++ appl/freeflow/navierstokes/sincos/main.cc | 2 +- 6 files changed, 1211 insertions(+), 1 deletion(-) create mode 100644 appl/freeflow/navierstokes/gaussLocal/CMakeLists.txt create mode 100644 appl/freeflow/navierstokes/gaussLocal/main.cc create mode 100644 appl/freeflow/navierstokes/gaussLocal/params.input create mode 100644 appl/freeflow/navierstokes/gaussLocal/problem.hh diff --git a/appl/freeflow/navierstokes/CMakeLists.txt b/appl/freeflow/navierstokes/CMakeLists.txt index 718c8c5..646ac09 100644 --- a/appl/freeflow/navierstokes/CMakeLists.txt +++ b/appl/freeflow/navierstokes/CMakeLists.txt @@ -2,3 +2,4 @@ add_subdirectory(donea) add_subdirectory(channel) add_subdirectory(sincos) add_subdirectory(angeli) +add_subdirectory(gaussLocal) diff --git a/appl/freeflow/navierstokes/gaussLocal/CMakeLists.txt b/appl/freeflow/navierstokes/gaussLocal/CMakeLists.txt new file mode 100644 index 0000000..8406575 --- /dev/null +++ b/appl/freeflow/navierstokes/gaussLocal/CMakeLists.txt @@ -0,0 +1,7 @@ +add_input_file_links() + +dune_add_test(NAME test_ff_gauss_local + SOURCES main.cc + CMAKE_GUARD HAVE_UMFPACK + COMMAND ${CMAKE_SOURCE_DIR}/../dumux/bin/testing/runtest.py + CMD_ARGS --command "${CMAKE_CURRENT_BINARY_DIR}/test_ff_gauss_local params.input") diff --git a/appl/freeflow/navierstokes/gaussLocal/main.cc b/appl/freeflow/navierstokes/gaussLocal/main.cc new file mode 100644 index 0000000..3b5ce0f --- /dev/null +++ b/appl/freeflow/navierstokes/gaussLocal/main.cc @@ -0,0 +1,470 @@ +// -*- 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 staggered grid Navier-Stokes model (Kovasznay 1947) + */ + +bool doFirstOrderLocalTruncErrorGlobalRefinement = false; + +#include <config.h> + +#include <ctime> +#include <iostream> + +#include <dune/common/parallel/mpihelper.hh> +#include <dune/common/timer.hh> +#include <dune/grid/io/file/dgfparser/dgfwriter.hh> +#include <dune/grid/io/file/dgfparser/dgfexception.hh> +#include <dune/grid/io/file/vtk.hh> +#include <dune/istl/io.hh> + +#include <dumux/common/properties.hh> +#include <dumux/common/parameters.hh> +#include <dumux/common/dumuxmessage.hh> +#include <dumux/common/defaultusagemessage.hh> + +#include <dumux/linear/seqsolverbackend.hh> +#include <dumux/nonlinear/newtonsolver.hh> + +#include <dumux/assembly/cvdstaggeredrefinedfvassembler.hh> +#include <dumux/assembly/diffmethod.hh> + +#include <dumux/discretization/method.hh> + +#include <dumux/io/mystaggeredvtkoutputmodule.hh> +#include <dumux/io/grid/gridmanager.hh> + +#include <dumux/adaptive/adapt.hh> +#include <dumux/adaptive/markelements.hh> +#include <dumux/freeflow/cvdgridadaptindicator.hh> +#include <dumux/freeflow/navierstokes/staggered/griddatatransfer.hh> + +#include <dumux/freeflow/navierstokes/staggered/cvdresidualCalc.hh> +#include <dumux/io/cvdoutputFacility.hh> + +#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. + * \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 x-coordinate of the lower left corner of the lens [m] \n" + "\t-SpatialParams.LensLowerLeftY y-coordinate of the lower left corner of the lens [m] \n" + "\t-SpatialParams.LensUpperRightX x-coordinate of the upper right corner of the lens [m] \n" + "\t-SpatialParams.LensUpperRightY y-coordinate of the upper right corner of the lens [m] \n" + "\t-SpatialParams.Permeability Permeability of the domain [m^2] \n" + "\t-SpatialParams.PermeabilityLens Permeability of the lens [m^2] \n"; + + std::cout << errorMessageOut + << "\n"; + } +} + +int main(int argc, char** argv) try +{ + using namespace Dumux; + + // define the type tag for this problem + using TypeTag = Properties::TTag::GaussLocalTestTypeTag; + using Scalar = GetPropType<TypeTag, Properties::Scalar>; + + // 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); + + using HelpingGridManager = Dumux::GridManager<GetPropType<TypeTag, Properties::HelpingGrid>>; + HelpingGridManager helpingGridManager; + helpingGridManager.init("Helper"); + const auto& helpingGridView = helpingGridManager.grid().leafGridView(); + Dune::DGFWriter dgfWriter(helpingGridView); + std::string inputFileName = getParam<std::string>("Grid.File"); + dgfWriter.write(inputFileName); + + // try to create a grid (from the given grid file or the input file) + using GridManager = Dumux::GridManager<GetPropType<TypeTag, Properties::Grid>>; + 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(); + + using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; + using GridView = typename GridGeometry::GridView; + using Element = typename GridView::template Codim<0>::Entity; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + + const bool isStationary = getParam<bool>("Problem.IsStationary"); + const bool doAdapt = getParam<bool>("Adaptivity.Adapt"); + if (!isStationary && doAdapt) + { + const unsigned int numRefinementSteps = getParam<double>("Adaptive.MaxLevel"); + for (unsigned int i=1; i < numRefinementSteps; ++i) + { + gridManager.grid().preAdapt(); + for (const auto& element : elements(leafGridView)) + { + GlobalPosition pos = element.geometry().center(); + + auto x = pos[0]; + auto y = pos[1]; + + Scalar innerCircle = getParam<Scalar>("Adaptivity.InnerCircle"); + Scalar outerCircle = getParam<Scalar>("Adaptivity.OuterCircle"); + if ((x*x+y*y) > innerCircle*innerCircle && (x*x+y*y < outerCircle*outerCircle)) + { + gridManager.grid().mark( 1, element); + } + } + gridManager.grid().adapt(); + gridManager.grid().postAdapt(); + } + } + +// Dune::VTKWriter<GridView> vtkwriter(this->gridView()); +// vtkwriter.write("latestgrid", Dune::VTK::appenddraw); + + // create the finite volume grid geometry + using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; + auto gridGeometry = std::make_shared<GridGeometry>(leafGridView); + + // get some time loop parameters + const auto tEnd = getParam<Scalar>("TimeLoop.TEnd"); + const auto maxDt = getParam<Scalar>("TimeLoop.MaxTimeStepSize"); + auto dt = getParam<Scalar>("TimeLoop.DtInitial"); + + // instantiate time loop + auto timeLoop = std::make_shared<TimeLoop<Scalar>>(0.0, dt, tEnd); + timeLoop->setMaxTimeStepSize(maxDt); + + // the problem (boundary conditions) + using Problem = GetPropType<TypeTag, Properties::Problem>; + auto problem = std::make_shared<Problem>(gridGeometry); + problem->updateTimeStepSize(timeLoop->timeStepSize()); + + // the solution vector + using SolutionVector = GetPropType<TypeTag, Properties::SolutionVector>; + const auto numDofsCellCenter = leafGridView.size(0); + const auto numDofsFace = (*gridGeometry).numIntersections(); + SolutionVector x; + x[GridGeometry::cellCenterIdx()].resize(numDofsCellCenter); + x[GridGeometry::faceIdx()].resize(numDofsFace); + 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); + + // use the staggered FV assembler + using Assembler = CVDStaggeredRefinedFVAssembler<TypeTag, DiffMethod::numeric>; + auto assembler = isStationary ? std::make_shared<Assembler>(problem, gridGeometry, gridVariables) + : std::make_shared<Assembler>(problem, gridGeometry, gridVariables, timeLoop, xOld); + + // the linear solver + using LinearSolver = Dumux::UMFPackBackend; + auto linearSolver = std::make_shared<LinearSolver>(); + + // the non-linear solver + using NewtonSolver = Dumux::NewtonSolver<Assembler, LinearSolver>; + NewtonSolver nonLinearSolver(assembler, linearSolver); + + using HostGrid = Dune::ALUGrid<2,2,Dune::cube,Dune::nonconforming >; + using HostGridManager = Dumux::GridManager<HostGrid>; + + std::array<std::string, 2> paramGroups = {"coarsexCVs", "coarseyCVs"}; //xfine... + CVDCVOutputFacility<TypeTag> cvOutputFacility(problem); + std::vector<std::pair<unsigned int, Scalar>> pvdFileInfos; + + gridVariables->update(x); + + const double refineTol = getParam<double>("Adaptive.RefineTolerance"); + const double coarsenTol = getParam<double>("Adaptive.CoarsenTolerance"); + MyFreeflowGridAdaptIndicator<TypeTag> indicator(problem); + const unsigned int numRefinementSteps = getParam<double>("Adaptive.MaxLevel"); + + FreeFlowGridDataTransfer<TypeTag, SolutionVector> freeflowDataTransfer(problem, gridGeometry, gridVariables, x); + + unsigned int timeIndex = 0; + if (isStationary) + { + // intialize the vtk output module + using IOFields = GetPropType<TypeTag, Properties::IOFields>; + problem->createAnalyticalSolution(); + MyStaggeredVtkOutputModule<GridVariables, SolutionVector> vtkWriter(*gridVariables, x, problem->name()); + IOFields::initOutputModule(vtkWriter); //!< Add model specific output fields + vtkWriter.addField(problem->getAnalyticalPressureSolution(), "pressureExact"); + vtkWriter.addField(problem->getAnalyticalVelocitySolution(), "velocityExact"); + vtkWriter.addFaceField(problem->getAnalyticalVelocitySolutionOnFace(), "faceVelocityExact"); + vtkWriter.write(0.0); + + using CellCenterSolutionVector = GetPropType<TypeTag, Properties::CellCenterSolutionVector>; + CellCenterSolutionVector numericalCCResidualWithAnalytical; + numericalCCResidualWithAnalytical.resize(numDofsCellCenter); + vtkWriter.addField(numericalCCResidualWithAnalytical, "continuityResidual"); + + Dune::Timer timer; + + for (unsigned int i=0; i < numRefinementSteps; ++i) + { + if (i>0) + { + // compute refinement indicator + indicator.prepareCenterRefine(refineTol, coarsenTol); + + // mark elements and maybe adapt grid + bool wasAdapted = false; + if (markElements(gridManager.grid(), indicator)) + wasAdapted = adapt(gridManager.grid(), freeflowDataTransfer); + + if (wasAdapted) + { + gridGeometry->update(leafGridView); + + x[GridGeometry::cellCenterIdx()] = 0.; + x[GridGeometry::cellCenterIdx()].resize(leafGridView.size(0)); + x[GridGeometry::faceIdx()] = 0.; + x[GridGeometry::faceIdx()].resize((*gridGeometry).numIntersections()); + problem->applyInitialSolution(x); +// xOld = x;//needed when time-dependent + + gridVariables->updateAfterGridAdaption(x); +// gridVariables->advanceTimeStep();//needed when time-dependent + + assembler->reSetJacobianSize(); // has to be after nonlinear solver + assembler->reSetJacobianPattern(); //!< Tell the assembler to resize the matrix and set pattern + assembler->reSetResidualSize(); //!< Tell the assembler to resize the residual + } + } + + // linearize & solve + nonLinearSolver.solve(x); + + // write vtk output + problem->createAnalyticalSolution(); + if (getParam<bool>("Problem.PrintErrors")) + problem->printErrors(x, i); + + using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; + FaceSolutionVector numericalFaceResidualWithAnalytical; + + std::optional<std::array<std::vector<Scalar>, 2>> optionalPerfectInterpolationFaceResiduals; + // std::array<std::vector<Scalar>, 2> perfectInterpolationFaceResiduals; + // optionalPerfectInterpolationFaceResiduals.emplace(perfectInterpolationFaceResiduals); + + std::array<HostGridManager, 2> cvGridManagers = {}; + std::array<std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>>,2> cvCenterScvfIndicesMaps; + cvOutputFacility.iniCVGridManagers(cvGridManagers, cvCenterScvfIndicesMaps, paramGroups); + + ResidualCalc<TypeTag> residualCalc(problem); + residualCalc.calcResidualsStationary(gridGeometry, numericalCCResidualWithAnalytical, numericalFaceResidualWithAnalytical); + + bool readDofBasedValues = getParam<bool>("Problem.ReadDofBasedValues", false); + if (readDofBasedValues) + { + CellCenterSolutionVector readInPres; + readInPres.resize(gridGeometry->numCellCenterDofs()); + ReadDofBasedResult<TypeTag> reader(problem); + reader.readDofBasedResult(readInPres, "pressure"); + vtkWriter.addField(readInPres, "readInPres"); + } + + vtkWriter.write(i+1.); + + cvOutputFacility.onCVsOutputResidualsAndPrimVars( + gridGeometry, + cvGridManagers, + cvCenterScvfIndicesMaps, + paramGroups, + x, + i+1, + numericalFaceResidualWithAnalytical, + optionalPerfectInterpolationFaceResiduals, + readDofBasedValues); + + pvdFileInfos.push_back(std::make_pair(i+1, i+1)); + + timer.stop(); + } + cvOutputFacility.printPvdFiles(paramGroups, pvdFileInfos); + + const auto& comm = Dune::MPIHelper::getCollectiveCommunication(); + std::cout << "Simulation took " << timer.elapsed() << " seconds on " + << comm.size() << " processes.\n" + << "The cumulative CPU time was " << timer.elapsed()*comm.size() << " seconds.\n"; + } + else + { + // intialize the vtk output module + using IOFields = GetPropType<TypeTag, Properties::IOFields>; + problem->createAnalyticalSolution(timeLoop->timeStepSize()); + MyStaggeredVtkOutputModule<GridVariables, SolutionVector> vtkWriter(*gridVariables, x, problem->name()); + IOFields::initOutputModule(vtkWriter); //!< Add model specific output fields + vtkWriter.addField(problem->getAnalyticalPressureSolution(), "pressureExact"); + vtkWriter.addField(problem->getAnalyticalVelocitySolution(), "velocityExact"); + vtkWriter.addFaceField(problem->getAnalyticalVelocitySolutionOnFace(), "faceVelocityExact"); + vtkWriter.write(0.0); + + using CellCenterSolutionVector = GetPropType<TypeTag, Properties::CellCenterSolutionVector>; + CellCenterSolutionVector numericalCCResidualWithAnalytical; + numericalCCResidualWithAnalytical.resize(leafGridView.size(0)); + vtkWriter.addField(numericalCCResidualWithAnalytical, "continuityResidual"); + + // time loop + timeLoop->start(); do + { + Scalar actualCurrentTime = timeLoop->time()+timeLoop->timeStepSize(); + + // set previous solution for storage evaluations + assembler->setPreviousSolution(xOld); + + // solve the non-linear system with time step control + nonLinearSolver.solve(x, *timeLoop); + + //output + if (getParam<bool>("Problem.PrintErrors")) + { + problem->printErrors(x, actualCurrentTime, timeIndex); + } + + using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; + FaceSolutionVector numericalFaceResidualWithAnalytical; + + std::optional<std::array<std::vector<Scalar>, 2>> optionalPerfectInterpolationFaceResiduals; + std::array<std::vector<Scalar>, 2> perfectInterpolationFaceResiduals; + optionalPerfectInterpolationFaceResiduals.emplace(perfectInterpolationFaceResiduals); + + std::array<HostGridManager, 2> cvGridManagers = {}; + std::array<std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>>,2> cvCenterScvfIndicesMaps; + cvOutputFacility.iniCVGridManagers(cvGridManagers, cvCenterScvfIndicesMaps, paramGroups); + + ResidualCalc<TypeTag> residualCalc(problem); + residualCalc.calcResidualsInstationary(timeLoop, gridGeometry, numericalCCResidualWithAnalytical, numericalFaceResidualWithAnalytical); + + bool readDofBasedValues = getParam<bool>("Problem.ReadDofBasedValues", false) && scalarCmp(getParam<Scalar>("Problem.TimeDofBasedValues"), actualCurrentTime); + if (readDofBasedValues) + { + CellCenterSolutionVector IBAMRpres; + IBAMRpres.resize(gridGeometry->numCellCenterDofs()); + ReadDofBasedResult<TypeTag> reader(problem); + reader.readDofBasedResult(IBAMRpres, "pressure"); + vtkWriter.addField(IBAMRpres, "IBAMRpres"); + } + + problem->createAnalyticalSolution(actualCurrentTime); + vtkWriter.write(actualCurrentTime); + + if (readDofBasedValues) + vtkWriter.removeField(); + + cvOutputFacility.onCVsOutputResidualsAndPrimVars( + gridGeometry, + cvGridManagers, + cvCenterScvfIndicesMaps, + paramGroups, + x, + timeIndex,/*0 for stationary*/ + numericalFaceResidualWithAnalytical, + optionalPerfectInterpolationFaceResiduals, + readDofBasedValues); + + pvdFileInfos.push_back(std::make_pair(timeIndex, actualCurrentTime)); + + // prepare next time step + xOld = x; + gridVariables->advanceTimeStep(); + timeLoop->advanceTimeStep(); + problem->updateTime(timeLoop->time()); + timeLoop->reportTimeStep(); + timeLoop->setTimeStepSize(nonLinearSolver.suggestTimeStepSize(timeLoop->timeStepSize())); + problem->updateTimeStepSize(timeLoop->timeStepSize()); + + ++timeIndex; + } while (!timeLoop->finished()); + + cvOutputFacility.printPvdFiles(paramGroups, pvdFileInfos); + + 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/appl/freeflow/navierstokes/gaussLocal/params.input b/appl/freeflow/navierstokes/gaussLocal/params.input new file mode 100644 index 0000000..0c3e2b5 --- /dev/null +++ b/appl/freeflow/navierstokes/gaussLocal/params.input @@ -0,0 +1,75 @@ +[TimeLoop] +DtInitial = 0.05 # [s] #choose this small enough, when I chose DtInitial=1, I got problems with the spacial convergence +TEnd = 0.05 # [s] + +[Helper.Grid] +Positions0 = -5 5 +Positions1 = -5 5 +Cells0 = 20 +Cells1 = 20 +Grading0 = 1.0 +Grading1 = 1.0 + +[Grid] +File = grid.dgf + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Problem] +Name = test_gauss_local +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +GaussWidthFactor = 4. +GaussPowerFactor = 5. +Chooser = 1 #0:pressureGauss, 1:velocityGauss +#UseScvfLineAveraging = true +#UseContiSourceAveraging = true +#QuadratureOrder = 10 #among others for continuity-residual to become closer to zero + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-10 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true + +[Vtk] +WriteFaceData = false + +[LinearSolver] +Verbosity = 0 + +[Adaptivity] +LinearInterpolation = false #false: quadratic +Conservation = false +InnerCircle = .6 +OuterCircle = 2.8 +Adapt = true + +[Component] +MolarMass = 1.0 +LiquidDensity = 1.0 +LiquidKinematicViscosity = 1.0 + +[FreeFlow] +EnableUnsymmetrizedVelocityGradientForBeaversJoseph = true + +[Adaptive] +HigherOrderInterpolation = false +RefineAtDirichletBC = 0 +RefineAtFluxBC = 1 +MinLevel = 0 +MaxLevel = 4 +CoarsenTolerance = 0 +RefineTolerance = 1e-1 diff --git a/appl/freeflow/navierstokes/gaussLocal/problem.hh b/appl/freeflow/navierstokes/gaussLocal/problem.hh new file mode 100644 index 0000000..58f5f4c --- /dev/null +++ b/appl/freeflow/navierstokes/gaussLocal/problem.hh @@ -0,0 +1,657 @@ +// -*- 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 + * \ingroup NavierStokesTests + * \brief Test for the staggered grid (Navier-)Stokes model with analytical solution + */ +#ifndef DUMUX_DONEA_TEST_PROBLEM_HH +#define DUMUX_DONEA_TEST_PROBLEM_HH + +#include <dune/alugrid/grid.hh> +#include <dune/grid/yaspgrid.hh> + +#include <dumux/assembly/cvdstaggeredrefinedlocalresidual.hh> + +#include <dumux/common/numeqvector.hh> + +#include <dumux/material/fluidsystems/1pliquid.hh> +#include <dumux/material/components/constant.hh> + +#include <dumux/freeflow/navierstokes/boundarytypes.hh> +#include <dumux/freeflow/navierstokes/cvdproblem.hh> +#include <dumux/freeflow/navierstokes/cvdlocalresidual.hh> +#include <dumux/freeflow/navierstokes/cvdfluxvariableswrapper.hh> +#include <dumux/freeflow/navierstokes/myvolumevariables.hh> +#include <dumux/freeflow/navierstokes/myiofields.hh> + +#include <dumux/discretization/method.hh> +#include <dumux/discretization/staggered/myfacesolution.hh> +#include <dumux/discretization/staggered/freeflow/properties.hh> +#include <dumux/freeflow/navierstokes/model.hh> + +#include <dumux/discretization/staggered/freeflow/myfacevariables.hh> +#include <dumux/discretization/staggered/freeflow/cvdlocalfacevariables.hh> +#include <dumux/discretization/staggered/freeflow/elementvolumevariables1.hh> +#include <dumux/discretization/staggered/freeflow/myvelocityoutput.hh> +#include <dumux/discretization/staggered/freeflow/mygridvolumevariables.hh> +#include <dumux/discretization/staggered/mygridfluxvariablescache.hh> +#include <dumux/discretization/staggered/cvdelementfacesolution.hh> +#include <dumux/discretization/staggered/cvdgridvariables.hh> +#include <dumux/discretization/staggered/cvdlocalgridfacevariables.hh> +#include <dumux/discretization/staggered/cvdfvgridgeometry.hh> +#include <dumux/discretization/staggered/freeflow/cvdfvgridgeometrytraits.hh> + +namespace Dumux +{ +template <class TypeTag> +class GaussLocalTestProblem; + +namespace Properties +{ +// Create new type tags +namespace TTag { +struct GaussLocalTestTypeTag { using InheritsFrom = std::tuple<NavierStokes, StaggeredFreeFlowModel>; }; +} // end namespace TTag + +// the fluid system +template<class TypeTag> +struct FluidSystem<TypeTag, TTag::GaussLocalTestTypeTag> +{ + using Scalar = GetPropType<TypeTag, Properties::Scalar>; + using type = FluidSystems::OnePLiquid<Scalar, Components::Constant<1, Scalar> >; +}; + +template<class TypeTag, class MyTypeTag> +struct HelpingGrid { using type = UndefinedProperty; }; + +// Set the grid type +template<class TypeTag> +struct HelpingGrid<TypeTag, TTag::GaussLocalTestTypeTag> +{ + using type = Dune::YaspGrid<2,Dune::TensorProductCoordinates<double, 2>>; +}; + +// Set the grid type +template<class TypeTag> +struct Grid<TypeTag, TTag::GaussLocalTestTypeTag> { using type = Dune::ALUGrid<2,2,Dune::cube,Dune::nonconforming>; }; + +// Set the problem property +template<class TypeTag> +struct Problem<TypeTag, TTag::GaussLocalTestTypeTag> { using type = Dumux::GaussLocalTestProblem<TypeTag> ; }; + +template<class TypeTag> +struct EnableGridGeometryCache<TypeTag, TTag::GaussLocalTestTypeTag> { static constexpr bool value = true; }; + +template<class TypeTag> +struct EnableGridFluxVariablesCache<TypeTag, TTag::GaussLocalTestTypeTag> { static constexpr bool value = true; }; +template<class TypeTag> +struct EnableGridVolumeVariablesCache<TypeTag, TTag::GaussLocalTestTypeTag> { static constexpr bool value = true; }; + +//! The variables living on the faces +template<class TypeTag> +struct FaceVariables<TypeTag, TTag::GaussLocalTestTypeTag> +{ +private: + using FacePrimaryVariables = GetPropType<TypeTag, Properties::FacePrimaryVariables>; + using GridView = typename GetPropType<TypeTag, Properties::GridGeometry>::GridView; + static constexpr auto upwindSchemeOrder = getPropValue<TypeTag, Properties::UpwindSchemeOrder>(); + using ModelTraits = GetPropType<TypeTag, Properties::ModelTraits>; +public: + using type = MyStaggeredFaceVariables<ModelTraits, FacePrimaryVariables, GridView::dimension, upwindSchemeOrder>; +}; + +template<class TypeTag> +struct LocalFaceVariables<TypeTag, TTag::GaussLocalTestTypeTag> +{ +private: + using FacePrimaryVariables = GetPropType<TypeTag, Properties::FacePrimaryVariables>; +public: + using type = CVDStaggeredLocalFaceVariables<FacePrimaryVariables>; +}; + +//! The velocity output +template<class TypeTag> +struct VelocityOutput<TypeTag, TTag::GaussLocalTestTypeTag> +{ + using type = MyStaggeredFreeFlowVelocityOutput<GetPropType<TypeTag, Properties::GridVariables>, + GetPropType<TypeTag, Properties::SolutionVector>>; +}; + +//! Set the volume variables property +template<class TypeTag> +struct DualCVsVolVars<TypeTag, TTag::GaussLocalTestTypeTag> +{ +private: + using VV = GetPropType<TypeTag, Properties::VolumeVariables>; + using GridView = typename GetPropType<TypeTag, Properties::GridGeometry>::GridView; + static constexpr auto dimWorld = GridView::dimensionworld; + static constexpr int numPairs = 2 * (dimWorld - 1); + +public: + using type = NavierStokesDualCVsVolVars<VV, numPairs>; +}; + +//! Set the volume variables property +template<class TypeTag> +struct PrimalCVsVolVars<TypeTag, TTag::GaussLocalTestTypeTag> +{ +public: + using VolumeVariables = GetPropType<TypeTag, Properties::VolumeVariables>; + using type = std::array<NaviesStokesPrimalScvfPair<VolumeVariables>,8>;//TODO make work for dim != 2 +}; + +template<class TypeTag> +struct GridVolumeVariables<TypeTag, TTag::GaussLocalTestTypeTag> +{ +private: + using Problem = GetPropType<TypeTag, Properties::Problem>; + using VolumeVariables = GetPropType<TypeTag, Properties::VolumeVariables>; + using DualCVsVolVars = GetPropType<TypeTag, Properties::DualCVsVolVars>; + using PrimalCVsVolVars = GetPropType<TypeTag, Properties::PrimalCVsVolVars>; + using GridView = typename GetPropType<TypeTag, Properties::GridGeometry>::GridView; + using SubControlVolume = typename GetPropType<TypeTag, Properties::GridGeometry>::SubControlVolume; + using SubControlVolumeFace = typename GetPropType<TypeTag, Properties::GridGeometry>::SubControlVolumeFace; + static constexpr auto enableCache = getPropValue<TypeTag, Properties::EnableGridVolumeVariablesCache>(); + using Traits = MyStaggeredGridDefaultGridVolumeVariablesTraits<Problem, PrimalCVsVolVars, DualCVsVolVars, VolumeVariables, GridView, SubControlVolume, SubControlVolumeFace>; +public: + using type = MyStaggeredGridVolumeVariables<Traits, enableCache>; +}; + +//! Set the BaseLocalResidual to StaggeredLocalResidual +template<class TypeTag> +struct BaseLocalResidual<TypeTag, TTag::GaussLocalTestTypeTag> { using type = StaggeredRefinedLocalResidual<TypeTag>; }; + +//! Set the face solution type +template<class TypeTag> +struct StaggeredFaceSolution<TypeTag, TTag::GaussLocalTestTypeTag> +{ +private: + using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; +public: + using type = Dumux::MyStaggeredFaceSolution<FaceSolutionVector>; +}; + +template<class TypeTag> +struct ElementFaceSolution<TypeTag, TTag::GaussLocalTestTypeTag> +{ +private: + using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; +public: + using type = Dumux::CVDElementFaceSolution<FaceSolutionVector>; +}; + +//! Set the GridLocalFaceVariables +template<class TypeTag> +struct GridLocalFaceVariables<TypeTag, TTag::GaussLocalTestTypeTag> +{ + private: + using Problem = GetPropType<TypeTag, Properties::Problem>; + using LocalFaceVariables = GetPropType<TypeTag, Properties::LocalFaceVariables>; + static constexpr auto enableCache = getPropValue<TypeTag, Properties::EnableGridFaceVariablesCache>(); + public: + using type = CVDStaggeredLocalGridFaceVariables<Problem, LocalFaceVariables, enableCache>; +}; + +//! Set the grid variables (volume, flux and face variables) +template<class TypeTag> +struct GridVariables<TypeTag, TTag::GaussLocalTestTypeTag> +{ +private: + using GG = GetPropType<TypeTag, Properties::GridGeometry>; + using GVV = GetPropType<TypeTag, Properties::GridVolumeVariables>; + using GFVC = GetPropType<TypeTag, Properties::GridFluxVariablesCache>; + using GFV = GetPropType<TypeTag, Properties::GridFaceVariables>; + using GLFV = GetPropType<TypeTag, Properties::GridLocalFaceVariables>; +public: + using type = CVDStaggeredGridVariables<GG, GVV, GFVC, GFV, GLFV>; +}; + +//! The default fv grid geometry +template<class TypeTag> +struct GridGeometry<TypeTag, TTag::GaussLocalTestTypeTag> +{ +private: + static constexpr auto upwindSchemeOrder = getPropValue<TypeTag, Properties::UpwindSchemeOrder>(); + static constexpr bool enableCache = getPropValue<TypeTag, Properties::EnableGridGeometryCache>(); + using GridView = typename GetPropType<TypeTag, Properties::Grid>::LeafGridView; + using Traits = CVDStaggeredFreeFlowDefaultGridGeometryTraits<GridView, upwindSchemeOrder>; +public: + using type = CVDStaggeredGridGeometry<GridView, enableCache, Traits>; +}; + +//! Set the volume variables property +template<class TypeTag> +struct VolumeVariables<TypeTag, TTag::GaussLocalTestTypeTag> +{ +private: + using PV = GetPropType<TypeTag, Properties::PrimaryVariables>; + using FSY = GetPropType<TypeTag, Properties::FluidSystem>; + using FST = GetPropType<TypeTag, Properties::FluidState>; + using MT = GetPropType<TypeTag, Properties::ModelTraits>; + + static_assert(FSY::numPhases == MT::numFluidPhases(), "Number of phases mismatch between model and fluid system"); + static_assert(FST::numPhases == MT::numFluidPhases(), "Number of phases mismatch between model and fluid state"); + static_assert(!FSY::isMiscible(), "The Navier-Stokes model only works with immiscible fluid systems."); + + using Traits = NavierStokesVolumeVariablesTraits<PV, FSY, FST, MT>; +public: + using type = MyNavierStokesVolumeVariables<Traits>; +}; + +//! The local residual +template<class TypeTag> +struct LocalResidual<TypeTag, TTag::GaussLocalTestTypeTag> { using type = RefinedNavierStokesResidual<TypeTag>; }; + +//! The flux variables +template<class TypeTag> +struct FluxVariables<TypeTag, TTag::GaussLocalTestTypeTag> { using type = RefinedNavierStokesFluxVariables<TypeTag>; }; + +//! The specific I/O fields +template<class TypeTag> +struct IOFields<TypeTag, TTag::GaussLocalTestTypeTag> { +#if NONISOTHERMAL + using type = FreeflowNonIsothermalIOFields<MyNavierStokesIOFields>; +#else + using type = MyNavierStokesIOFields; +#endif +}; + +//! Set the global flux variables cache vector class +template<class TypeTag> +struct GridFluxVariablesCache<TypeTag, TTag::GaussLocalTestTypeTag> +{ +private: + using Problem = GetPropType<TypeTag, Properties::Problem>; + using FluxVariablesCache = GetPropType<TypeTag, Properties::FluxVariablesCache>; + using FluxVariablesCacheFiller = GetPropType<TypeTag, Properties::FluxVariablesCacheFiller>; + static constexpr auto enableCache = getPropValue<TypeTag, Properties::EnableGridFluxVariablesCache>(); + static constexpr auto upwindSchemeOrder = getPropValue<TypeTag, Properties::UpwindSchemeOrder>(); +public: + using type = MyStaggeredGridFluxVariablesCache<Problem, FluxVariablesCache, FluxVariablesCacheFiller, enableCache, upwindSchemeOrder>; +}; + +template<class TypeTag> +struct CVGridGeometry<TypeTag, TTag::GaussLocalTestTypeTag> +{ +private: + static constexpr auto upwindSchemeOrder = getPropValue<TypeTag, Properties::UpwindSchemeOrder>(); + static constexpr bool enableCache = getPropValue<TypeTag, Properties::EnableGridGeometryCache>(); + using GridView = typename Dune::ALUGrid<2,2,Dune::cube,Dune::nonconforming >::LeafGridView; + using Traits = CVDStaggeredFreeFlowDefaultGridGeometryTraits<GridView, upwindSchemeOrder>; +public: + using type = CVDStaggeredGridGeometry<GridView, enableCache, Traits>; +}; +} + +/*! + * \ingroup NavierStokesTests + * \brief Test problem for the staggered grid (Bla et al., 2003) + * \todo doc me! + */ +template <class TypeTag> +class GaussLocalTestProblem : public MyNavierStokesProblem<TypeTag> +{ + using ParentType = MyNavierStokesProblem<TypeTag>; + + using BoundaryTypes = Dumux::NavierStokesBoundaryTypes<GetPropType<TypeTag, Properties::ModelTraits>::numEq()>; + + using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; + using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; + using NumEqVector = Dumux::NumEqVector<GetPropType<TypeTag, Properties::PrimaryVariables>>; + using ModelTraits = GetPropType<TypeTag, Properties::ModelTraits>; + using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>; + using Scalar = GetPropType<TypeTag, Properties::Scalar>; + using SolutionVector = GetPropType<TypeTag, Properties::SolutionVector>; + + static constexpr auto dimWorld = GetPropType<TypeTag, Properties::GridGeometry>::GridView::dimensionworld; + using Element = typename GridGeometry::GridView::template Codim<0>::Entity; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + using VelocityVector = Dune::FieldVector<Scalar, dimWorld>; + using FVElementGeometry = typename GridGeometry::LocalView; + using SubControlVolume = typename GridGeometry::SubControlVolume; + using SubControlVolumeFace = typename GridGeometry::SubControlVolumeFace; + +public: + GaussLocalTestProblem(std::shared_ptr<const GridGeometry> gridGeometry) + : ParentType(gridGeometry), eps_(1e-6), time_(0.0), timeStepSize_(0.0) + { + isStationary_ = getParam<bool>("Problem.IsStationary"); + } + + /*! + * \name Problem parameters + */ + // \{ + + bool shouldWriteRestartFile() const + { + return false; + } + + /*! + * \brief Returns the temperature within the domain in [K]. + * + * This problem assumes a temperature of 10 degrees Celsius. + */ + Scalar temperature() const + { return 273.15 + 10; } // 10°C + + // see Schneider et al., 2019: "Coupling staggered-grid and MPFA finite volume methods for + // free flow/porous-medium flow problems" + NumEqVector instationarySourceAtPos(const GlobalPosition& globalPos, Scalar t) const + { + NumEqVector source(0.0); + + const Scalar x = globalPos[0]; + const Scalar y = globalPos[1]; + + Scalar a = getParam<Scalar>("Problem.GaussWidthFactor"); + Scalar b = getParam<Scalar>("Problem.GaussPowerFactor"); + int chooser = getParam<int>("Problem.Chooser"); + + //super Gaussian function (https://en.wikipedia.org/wiki/Gaussian_function) + + if (chooser == 0) + { + auto dxp = [&](Scalar x, Scalar y) + { return - b * std::pow((x*x+y*y)/a,b-1) * 2./a * x * std::exp(-std::pow((x*x+y*y)/a,b)); }; + auto dyp = [&](Scalar x, Scalar y) + { return - b * std::pow((x*x+y*y)/a,b-1) * 2./a * y * std::exp(-std::pow((x*x+y*y)/a,b)); }; + + source[Indices::conti0EqIdx] = 0.; + source[Indices::momentumXBalanceIdx] = dxp(x,y); + source[Indices::momentumYBalanceIdx] = dyp(x,y); + } + else if (chooser == 1) + { + auto dtu = [&](Scalar x, Scalar y, Scalar t) + { return df_(t) * std::exp(-std::pow((x*x+y*y)/a,b)); }; + auto dtv = [&](Scalar x, Scalar y, Scalar t) + { return df_(t) * std::exp(-std::pow((x*x+y*y)/a,b)); }; + auto dxu = [&](Scalar x, Scalar y, Scalar t) + { return - f_(t) * b * std::pow(((x*x+y*y)/a),b-1)*2./a* std::exp(-std::pow(((x*x+y*y)/a),b))*x; }; + auto dyu = [&](Scalar x, Scalar y, Scalar t) + { return - f_(t) * b * std::pow(((x*x+y*y)/a),b-1)*2./a* std::exp(-std::pow(((x*x+y*y)/a),b))*y; }; + auto dxuu = [&](Scalar x, Scalar y, Scalar t) + { return - f_(t) * f_(t) * 2.*b * std::pow(((x*x+y*y)/a),b-1)*2./a* std::exp(-2.*std::pow(((x*x+y*y)/a),b))*x; }; + auto dyuu = [&](Scalar x, Scalar y, Scalar t) + { return - f_(t) * f_(t) * 2.*b * std::pow(((x*x+y*y)/a),b-1)*2./a* std::exp(-2.*std::pow(((x*x+y*y)/a),b))*y; }; + auto dxxu = [&](Scalar x, Scalar y, Scalar t) + { return - f_(t) * 2*b/a * std::exp(-std::pow(((x*x+y*y)/a),b))*(std::pow(((x*x+y*y)/a),b-1)+2./a*(b-1.)*x*x*std::pow(((x*x+y*y)/a),b-2) - 2.*b/a*x*x*std::pow(((x*x+y*y)/a),2*(b-1))); }; + auto dxyu = [&](Scalar x, Scalar y, Scalar t) + { return - f_(t) * 2*b/a * std::exp(-std::pow(((x*x+y*y)/a),b))*(2./a*(b-1.)*x*y*std::pow(((x*x+y*y)/a),b-2) - 2.*b/a*x*y*std::pow(((x*x+y*y)/a),2*(b-1))); }; + auto dyyu = [&](Scalar x, Scalar y, Scalar t) + { return - f_(t) * 2*b/a * std::exp(-std::pow(((x*x+y*y)/a),b))*(std::pow(((x*x+y*y)/a),b-1)+2./a*(b-1.)*y*y*std::pow(((x*x+y*y)/a),b-2) - 2.*b/a*y*y*std::pow(((x*x+y*y)/a),2*(b-1))); }; + + + source[Indices::conti0EqIdx] = dxu(x,y,t) + dyu(x,y,t); + source[Indices::momentumXBalanceIdx] = dtu(x,y,t) + dxuu(x,y,t) + dyuu(x,y,t) - 2.*dxxu(x,y,t) -dyyu(x,y,t) - dxyu(x,y,t); + source[Indices::momentumYBalanceIdx] = dtv(x,y,t) + dxuu(x,y,t) + dyuu(x,y,t) - 2.*dyyu(x,y,t) - dxxu(x,y,t) - dxyu(x,y,t); + } + else + { + DUNE_THROW(Dune::InvalidStateException, "not meaningful"); + } + + return source; + } + + NumEqVector sourceAtPos(const GlobalPosition &globalPos) const + { + const Scalar t = time_ + timeStepSize_; + return instationarySourceAtPos(globalPos,t); + } + + // \} + /*! + * \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 values; + + // set Dirichlet values for the velocity and pressure everywhere + values.setDirichlet(Indices::velocityXIdx); + values.setDirichlet(Indices::velocityYIdx); + return values; + } + + /*! + * \brief Returns whether a fixed Dirichlet value shall be used at a given cell. + * + * \param element The finite element + * \param fvGeometry The finite-volume geometry + * \param scv The sub control volume + * \param pvIdx The primary variable index in the solution vector + */ + bool isDirichletCell(const Element& element, + const FVElementGeometry& fvGeometry, + const SubControlVolume& scv, + int pvIdx) const + { + // set fixed pressure in all cells at the left boundary + auto isBoundary = [&](const FVElementGeometry& fvGeometry) + { + if (fvGeometry.hasBoundaryScvf()) + { + return true; + } + return false; + }; + return (isBoundary(fvGeometry) && pvIdx == Indices::pressureIdx); + } + + /*! + * \brief Evaluate the boundary conditions for a dirichlet + * control volume face (velocities) + * + * \param element The finite element + * \param scvf the sub control volume face + * + * Concerning the usage of averaged velocity, see the explanation of the initial function. The average of the nondirection velocity along an scvf is required in the context of dirichlet boundary conditions for the functions getParallelVelocityFromBoundary_ and getParallelVelocityFromOtherBoundary_ within myfluxvariables.hh. There dirichlet is called for ghost faces built from the normalFace but the value then is taken in the the direction scvf.directionIndex, which is along that normalFace. + */ + PrimaryVariables dirichlet(const Element& element, const SubControlVolumeFace& scvf) const + { + Scalar time = time_+timeStepSize_; + + PrimaryVariables priVars(0.0); + + unsigned int dirIdx = scvf.directionIndex(); + priVars[Indices::velocity(dirIdx)] = this->instationaryAnalyticalVelocitySolutionAtPos(scvf, time); + unsigned int nonDirIdx = (dirIdx == 0)?1:0; + priVars[Indices::velocity(nonDirIdx)] = this->instationaryAnalyticalNonDirVelocitySolutionAtPos(scvf, time); + + return priVars; + } + + /*! + * \brief Evaluate the boundary conditions for a dirichlet + * control volume face (pressure) + * + * \param element The finite element + * \param scv the sub control volume + */ + PrimaryVariables dirichlet(const Element& element, const SubControlVolume& scv) const + { + Scalar time = time_+timeStepSize_; + + PrimaryVariables priVars(0.0); + priVars[Indices::pressureIdx] = this->instationaryAnalyticalPressureSolutionAtPos(scv, time); + return priVars; + } + + // see Schneider et al., 2019: "Coupling staggered-grid and MPFA finite volume methods for + // free flow/porous-medium flow problems" + PrimaryVariables instationaryAnalyticalSolutionAtPos(const GlobalPosition& globalPos, Scalar t) const + { + PrimaryVariables sol(0.0); + const Scalar x = globalPos[0]; + const Scalar y = globalPos[1]; + + Scalar a = getParam<Scalar>("Problem.GaussWidthFactor"); + Scalar b = getParam<Scalar>("Problem.GaussPowerFactor"); + int chooser = getParam<int>("Problem.Chooser"); + + if (chooser == 0) + { + sol[Indices::velocityXIdx] = 0.; + sol[Indices::velocityYIdx] = 0.; + sol[Indices::pressureIdx] = std::exp(-std::pow((x*x+y*y)/a,b)); + } + else if (chooser == 1) + { + sol[Indices::velocityXIdx] = f_(t) * std::exp(-std::pow((x*x+y*y)/a,b)); + sol[Indices::velocityYIdx] = f_(t) * std::exp(-std::pow((x*x+y*y)/a,b)); + sol[Indices::pressureIdx] = 0.; + } + else + { + DUNE_THROW(Dune::InvalidStateException, "not meaningful"); + } + + return sol; + } + + /*! + * \brief Returns the analytical solution of the problem at a given position. + * + * \param globalPos The global position + */ + PrimaryVariables analyticalSolutionAtPos(const GlobalPosition& globalPos) const + { + if(!isStationary_) + DUNE_THROW(Dune::InvalidStateException, "analyticalSolutionAtPos was supposed to be used only be the stationary problem."); + + return this->instationaryAnalyticalSolutionAtPos(globalPos, time_+timeStepSize_); + } + + // \} + + /*! + * \name Volume terms + */ + // \{ + +/*! + * \brief Evaluates the initial value for a sub control volume face (velocities) + * + * Simply assigning the value of the analytical solution at the face center + * gives a discrete solution that is not divergence-free. For small initial + * time steps, this has a negative impact on the pressure solution + * after the first time step. The flag UseVelocityAveraging triggers the + * function averagedVelocity_ which uses a higher order quadrature formula to + * bring the discrete solution sufficiently close to being divergence-free. + */ + PrimaryVariables initial(const SubControlVolumeFace& scvf) const + { + bool startWithAnalytical = getParam<bool>("Problem.StartWithAnalytical", false); + + if (startWithAnalytical || !isStationary_) + { + PrimaryVariables priVars(0.0); + priVars[Indices::velocity(scvf.directionIndex())] = this->instationaryAnalyticalVelocitySolutionAtPos(scvf, 0.); + return priVars; + } + else + { + PrimaryVariables values; + values[Indices::pressureIdx] = 0.0; + values[Indices::velocityXIdx] = 0.0; + values[Indices::velocityYIdx] = 0.0; + + return values; + } + } + + /*! + * \brief Evaluates the initial value for a control volume (pressure) + */ + PrimaryVariables initial(const SubControlVolume& scv) const + { + bool startWithAnalytical = getParam<bool>("Problem.StartWithAnalytical", false); + + if (startWithAnalytical || !isStationary_) + { + PrimaryVariables priVars(0.0); + priVars[Indices::pressureIdx] = this->instationaryAnalyticalPressureSolutionAtPos(scv, 0.); + return priVars; + } + else + { + PrimaryVariables values; + values[Indices::pressureIdx] = 0.0; + values[Indices::velocityXIdx] = 0.0; + values[Indices::velocityYIdx] = 0.0; + + return values; + } + } + + /*! + * \brief Updates the time + */ + void updateTime(const Scalar time) + { + time_ = time; + } + + /*! + * \brief Updates the time step size + */ + void updateTimeStepSize(const Scalar timeStepSize) + { + timeStepSize_ = timeStepSize; + } + +private: + Scalar f_(Scalar t) const + { + if (isStationary_) + return 1.0; + else + return std::exp(-t); + } + + Scalar df_(Scalar t) const + { + if (isStationary_) + return 0.0; + else + return -f_(t); + } + + Scalar eps_; + + Scalar time_; + Scalar timeStepSize_; + + bool isStationary_; +}; +} //end namespace + +#endif diff --git a/appl/freeflow/navierstokes/sincos/main.cc b/appl/freeflow/navierstokes/sincos/main.cc index aa1e94b..028f87c 100644 --- a/appl/freeflow/navierstokes/sincos/main.cc +++ b/appl/freeflow/navierstokes/sincos/main.cc @@ -344,7 +344,7 @@ int main(int argc, char** argv) try optionalPerfectInterpolationFaceResiduals.emplace(perfectInterpolationFaceResiduals); ResidualCalc<TypeTag> residualCalc(problem); - // residualCalc.calcResidualsInstationary(timeLoop, gridGeometry, cvGridManagers, cvCenterScvfIndicesMaps, numericalCCResidualWithAnalytical, numericalFaceResidualWithAnalytical, optionalPerfectInterpolationFaceResiduals); + residualCalc.calcResidualsInstationary(timeLoop, gridGeometry, numericalCCResidualWithAnalytical, numericalFaceResidualWithAnalytical); bool readDofBasedValues = getParam<bool>("Problem.ReadDofBasedValues", false) && scalarCmp(getParam<Scalar>("Problem.TimeDofBasedValues"), actualCurrentTime); if (readDofBasedValues) -- GitLab From 1349e159aae0902ab0a809a17badbbc5a862b46f Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Tue, 14 Sep 2021 15:35:42 +0300 Subject: [PATCH 36/69] [gauss_local] made bigger maxrelshift for output analysis --- appl/freeflow/navierstokes/gaussLocal/params.input | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appl/freeflow/navierstokes/gaussLocal/params.input b/appl/freeflow/navierstokes/gaussLocal/params.input index 0c3e2b5..f5a7781 100644 --- a/appl/freeflow/navierstokes/gaussLocal/params.input +++ b/appl/freeflow/navierstokes/gaussLocal/params.input @@ -40,7 +40,7 @@ Chooser = 1 #0:pressureGauss, 1:velocityGauss [ Newton ] MaxSteps = 100 -MaxRelativeShift = 1e-10 +MaxRelativeShift = 1e-5 SatisfyResidualAndShiftCriterion = true EnableAbsoluteResidualCriterion = true -- GitLab From 3eb1eeb1269bdc153a4b781b7664e7ccd80c8784 Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Tue, 14 Sep 2021 15:49:14 +0300 Subject: [PATCH 37/69] [sincos] updated params throw error for instationary --- appl/freeflow/navierstokes/sincos/params_vdP_full.input | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_full.input b/appl/freeflow/navierstokes/sincos/params_vdP_full.input index 7b2b8d1..88fa496 100644 --- a/appl/freeflow/navierstokes/sincos/params_vdP_full.input +++ b/appl/freeflow/navierstokes/sincos/params_vdP_full.input @@ -36,7 +36,7 @@ Name = test_ff_sincos_vdP_full_42_bigresidual EnableGravity = false PrintErrors = true EnableInertiaTerms = true -IsStationary = true +IsStationary = false VanDerPlasVersion = true StartWithAnalytical = false AveragedAnalyticalSolution = false -- GitLab From 51df49bcec23f03486caa7eeb242842e779cfa5d Mon Sep 17 00:00:00 2001 From: Melanie Lipp <melanie.lipp@iws.uni-stuttgart.de> Date: Thu, 16 Sep 2021 09:49:30 +0200 Subject: [PATCH 38/69] Use errors.hh from module dumux-adaptivestaggered. Adapt to recent version. --- appl/freeflow/navierstokes/channel/2d/main.cc | 8 +- .../navierstokes/channel/2d/problem.hh | 3 +- appl/freeflow/navierstokes/donea/main.cc | 9 +- appl/freeflow/navierstokes/donea/problem.hh | 3 +- appl/freeflow/navierstokes/gaussLocal/main.cc | 26 ++- .../navierstokes/gaussLocal/problem.hh | 3 +- appl/freeflow/navierstokes/sincos/main.cc | 19 +- dumux/freeflow/navierstokes/cvdproblem.hh | 77 -------- dumux/freeflow/navierstokes/errors.hh | 179 ------------------ 9 files changed, 55 insertions(+), 272 deletions(-) delete mode 100755 dumux/freeflow/navierstokes/errors.hh diff --git a/appl/freeflow/navierstokes/channel/2d/main.cc b/appl/freeflow/navierstokes/channel/2d/main.cc index c1d0996..982a8f7 100644 --- a/appl/freeflow/navierstokes/channel/2d/main.cc +++ b/appl/freeflow/navierstokes/channel/2d/main.cc @@ -65,6 +65,8 @@ bool doFirstOrderLocalTruncErrorGlobalRefinement = false; #include <dumux/discretization/staggered/freeflow/cvdfvgridgeometrytraits.hh> #include <dumux/freeflow/navierstokes/staggered/cvdresidualCalc.hh> +#include <dumux/freeflow/navierstokes/errors.hh> + #include <dumux/io/cvdoutputFacility.hh> #include "problem.hh" @@ -405,7 +407,11 @@ int main(int argc, char** argv) try //output if (getParam<bool>("Problem.PrintErrors", true)) - problem->printErrors(x); + { + NavierStokesRefinedErrors errors(problem, x); + errors.setCoarseVelocityDiscretization(true); + NavierStokesRefinedErrorCSVWriter(problem).printErrors(errors); + } using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; FaceSolutionVector numericalFaceResidualWithAnalytical; diff --git a/appl/freeflow/navierstokes/channel/2d/problem.hh b/appl/freeflow/navierstokes/channel/2d/problem.hh index 726b595..85235aa 100644 --- a/appl/freeflow/navierstokes/channel/2d/problem.hh +++ b/appl/freeflow/navierstokes/channel/2d/problem.hh @@ -326,7 +326,6 @@ class ChannelTestProblem : public MyNavierStokesProblem<TypeTag> using BoundaryTypes = Dumux::NavierStokesBoundaryTypes<GetPropType<TypeTag, Properties::ModelTraits>::numEq()>; using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; - using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; using ModelTraits = GetPropType<TypeTag, Properties::ModelTraits>; using NumEqVector = Dumux::NumEqVector<GetPropType<TypeTag, Properties::PrimaryVariables>>; using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>; @@ -346,6 +345,8 @@ class ChannelTestProblem : public MyNavierStokesProblem<TypeTag> using TimeLoopPtr = std::shared_ptr<CheckPointTimeLoop<Scalar>>; public: + using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; + ChannelTestProblem(std::shared_ptr<const GridGeometry> gridGeometry) : ParentType(gridGeometry), eps_(1e-6) { diff --git a/appl/freeflow/navierstokes/donea/main.cc b/appl/freeflow/navierstokes/donea/main.cc index fa0b419..6303567 100644 --- a/appl/freeflow/navierstokes/donea/main.cc +++ b/appl/freeflow/navierstokes/donea/main.cc @@ -57,6 +57,7 @@ bool writeOut = false; #include <dumux/io/grid/cvdcontrolvolumegrids.hh> #include <dumux/freeflow/navierstokes/staggered/cvdresidualCalc.hh> +#include <dumux/freeflow/navierstokes/errors.hh> #include <dumux/io/cvdoutputFacility.hh> #include "problem.hh" @@ -238,8 +239,12 @@ int main(int argc, char** argv) try nonLinearSolver.solve(x); //output - if (getParam<bool>("Problem.PrintErrors")) - problem->printErrors(x); + if (getParam<bool>("Problem.PrintErrors", true)) + { + NavierStokesRefinedErrors errors(problem, x); + errors.setCoarseVelocityDiscretization(true); + NavierStokesRefinedErrorCSVWriter(problem).printErrors(errors); + } using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; FaceSolutionVector numericalFaceResidualWithAnalytical; diff --git a/appl/freeflow/navierstokes/donea/problem.hh b/appl/freeflow/navierstokes/donea/problem.hh index 611eb55..147e427 100644 --- a/appl/freeflow/navierstokes/donea/problem.hh +++ b/appl/freeflow/navierstokes/donea/problem.hh @@ -329,7 +329,6 @@ class DoneaTestProblem : public MyNavierStokesProblem<TypeTag> using BoundaryTypes = Dumux::NavierStokesBoundaryTypes<GetPropType<TypeTag, Properties::ModelTraits>::numEq()>; using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; - using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; using NumEqVector = Dumux::NumEqVector<GetPropType<TypeTag, Properties::PrimaryVariables>>; using ModelTraits = GetPropType<TypeTag, Properties::ModelTraits>; using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>; @@ -346,6 +345,8 @@ class DoneaTestProblem : public MyNavierStokesProblem<TypeTag> using SubControlVolumeFace = typename GetPropType<TypeTag, Properties::GridGeometry>::SubControlVolumeFace; public: + using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; + DoneaTestProblem(std::shared_ptr<const GridGeometry> gridGeometry) : ParentType(gridGeometry), eps_(1e-6) { diff --git a/appl/freeflow/navierstokes/gaussLocal/main.cc b/appl/freeflow/navierstokes/gaussLocal/main.cc index 3b5ce0f..ded3c9b 100644 --- a/appl/freeflow/navierstokes/gaussLocal/main.cc +++ b/appl/freeflow/navierstokes/gaussLocal/main.cc @@ -54,10 +54,12 @@ bool doFirstOrderLocalTruncErrorGlobalRefinement = false; #include <dumux/adaptive/adapt.hh> #include <dumux/adaptive/markelements.hh> + #include <dumux/freeflow/cvdgridadaptindicator.hh> #include <dumux/freeflow/navierstokes/staggered/griddatatransfer.hh> - +#include <dumux/freeflow/navierstokes/errors.hh> #include <dumux/freeflow/navierstokes/staggered/cvdresidualCalc.hh> + #include <dumux/io/cvdoutputFacility.hh> #include "problem.hh" @@ -229,7 +231,6 @@ int main(int argc, char** argv) try FreeFlowGridDataTransfer<TypeTag, SolutionVector> freeflowDataTransfer(problem, gridGeometry, gridVariables, x); - unsigned int timeIndex = 0; if (isStationary) { // intialize the vtk output module @@ -249,6 +250,10 @@ int main(int argc, char** argv) try Dune::Timer timer; + NavierStokesRefinedErrors errors(problem, x, 0); + errors.setCoarseVelocityDiscretization(true); + NavierStokesRefinedErrorCSVWriter errorCSVWriter(problem); + for (unsigned int i=0; i < numRefinementSteps; ++i) { if (i>0) @@ -286,8 +291,11 @@ int main(int argc, char** argv) try // write vtk output problem->createAnalyticalSolution(); - if (getParam<bool>("Problem.PrintErrors")) - problem->printErrors(x, i); + if (getParam<bool>("Problem.PrintErrors", true)) + { + errors.update(x, i); + errorCSVWriter.printErrors(errors); + } using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; FaceSolutionVector numericalFaceResidualWithAnalytical; @@ -354,6 +362,11 @@ int main(int argc, char** argv) try numericalCCResidualWithAnalytical.resize(leafGridView.size(0)); vtkWriter.addField(numericalCCResidualWithAnalytical, "continuityResidual"); + unsigned int timeIndex = 0; + NavierStokesRefinedErrors errors(problem, x, 0.0, 0); + errors.setCoarseVelocityDiscretization(true); + NavierStokesRefinedErrorCSVWriter errorCSVWriter(problem); + // time loop timeLoop->start(); do { @@ -366,9 +379,10 @@ int main(int argc, char** argv) try nonLinearSolver.solve(x, *timeLoop); //output - if (getParam<bool>("Problem.PrintErrors")) + if (getParam<bool>("Problem.PrintErrors", true)) { - problem->printErrors(x, actualCurrentTime, timeIndex); + errors.update(x, actualCurrentTime, timeIndex); + errorCSVWriter.printErrors(errors); } using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; diff --git a/appl/freeflow/navierstokes/gaussLocal/problem.hh b/appl/freeflow/navierstokes/gaussLocal/problem.hh index 58f5f4c..d5633b8 100644 --- a/appl/freeflow/navierstokes/gaussLocal/problem.hh +++ b/appl/freeflow/navierstokes/gaussLocal/problem.hh @@ -313,7 +313,6 @@ class GaussLocalTestProblem : public MyNavierStokesProblem<TypeTag> using BoundaryTypes = Dumux::NavierStokesBoundaryTypes<GetPropType<TypeTag, Properties::ModelTraits>::numEq()>; using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; - using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; using NumEqVector = Dumux::NumEqVector<GetPropType<TypeTag, Properties::PrimaryVariables>>; using ModelTraits = GetPropType<TypeTag, Properties::ModelTraits>; using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>; @@ -329,6 +328,8 @@ class GaussLocalTestProblem : public MyNavierStokesProblem<TypeTag> using SubControlVolumeFace = typename GridGeometry::SubControlVolumeFace; public: + using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; + GaussLocalTestProblem(std::shared_ptr<const GridGeometry> gridGeometry) : ParentType(gridGeometry), eps_(1e-6), time_(0.0), timeStepSize_(0.0) { diff --git a/appl/freeflow/navierstokes/sincos/main.cc b/appl/freeflow/navierstokes/sincos/main.cc index 028f87c..9dd100b 100644 --- a/appl/freeflow/navierstokes/sincos/main.cc +++ b/appl/freeflow/navierstokes/sincos/main.cc @@ -69,6 +69,8 @@ struct FaceVolumeVariables { using type = UndefinedProperty; }; #include <dumux/discretization/staggered/freeflow/cvdfvgridgeometrytraits.hh> #include <dumux/freeflow/navierstokes/staggered/cvdresidualCalc.hh> +#include <dumux/freeflow/navierstokes/errors.hh> + #include <dumux/io/cvdoutputFacility.hh> #include "problem.hh" @@ -261,9 +263,8 @@ int main(int argc, char** argv) try gridVariables->update(x); - const bool shouldPrintErrors = getParam<bool>("Problem.PrintErrors"); + const bool shouldPrintErrors = getParam<bool>("Problem.PrintErrors", true); - unsigned int timeIndex = 0; if (isStationary) { // linearize & solve @@ -272,7 +273,11 @@ int main(int argc, char** argv) try //output if (shouldPrintErrors) - problem->printErrors(x); + { + NavierStokesRefinedErrors errors(problem, x); + errors.setCoarseVelocityDiscretization(true); + NavierStokesRefinedErrorCSVWriter(problem).printErrors(errors); + } using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; FaceSolutionVector numericalFaceResidualWithAnalytical; @@ -319,6 +324,11 @@ int main(int argc, char** argv) try } else { + NavierStokesRefinedErrors errors(problem, x, 0.0, 0); + errors.setCoarseVelocityDiscretization(true); + NavierStokesRefinedErrorCSVWriter errorCSVWriter(problem); + unsigned int timeIndex = 0; + // time loop timeLoop->start(); do { @@ -333,7 +343,8 @@ int main(int argc, char** argv) try //output if (shouldPrintErrors) { - problem->printErrors(x, actualCurrentTime, timeIndex); + errors.update(x, actualCurrentTime, timeIndex); + errorCSVWriter.printErrors(errors); } using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; diff --git a/dumux/freeflow/navierstokes/cvdproblem.hh b/dumux/freeflow/navierstokes/cvdproblem.hh index fb1f924..db3771e 100644 --- a/dumux/freeflow/navierstokes/cvdproblem.hh +++ b/dumux/freeflow/navierstokes/cvdproblem.hh @@ -34,7 +34,6 @@ #include <dumux/discretization/staggered/freeflow/geometryhelper/cvdstaggeredgeometryhelper.hh> #include <dumux/discretization/staggered/freeflow/cvdffsubcontrolvolumeface.hh> -#include <dumux/freeflow/navierstokes/errors.hh> #include <dumux/freeflow/navierstokes/cvdAnalyticalSolutionIntegration.hh> namespace Dumux { @@ -126,13 +125,6 @@ public: useScvVolumeAveraging_ = getParam<bool>("Problem.UseScvVolumeAveraging", false); useContiSourceAveraging_ = getParam<bool>("Problem.UseContiSourceAveraging", false); quadOrder_ = getParam<unsigned int>("Problem.QuadratureOrder", 3); - - //prepare headlines in the error file - std::ofstream logFile; - logFile.open(this->name() + "_error.csv"); - logFile << ",,,,,abs L2,,,rel L2,,,Linf,,,"<< std::endl; - logFile << "time/refinement step,corresponding paraview files,cc dofs, face dofs, all dofs, p,u,v,p,u,v,p,u,v" << std::endl; - logFile.close(); } bool useScvfLineAveraging() const @@ -281,75 +273,6 @@ public: return analyticalVelocitySolutionAtPos_(scvf, nonDirIdx); } - void printErrors(const SolutionVector& curSol) const - { - PrimaryVariables l2NormAbs(0.0); - PrimaryVariables l2NormRel(0.0); - PrimaryVariables lInfinityNorm(0.0); - - std::ofstream logFile; - logFile.open(this->name() + "_error.csv", std::ios::app); - logFile << ", 00001.vtu ,"; - logFile.close(); - - NavierStokesTestErrors<TypeTag>::calculateErrors( - l2NormAbs, - l2NormRel, - lInfinityNorm, - *this, - curSol, - [&](const SubControlVolume& scv) { return analyticalPressureSolutionAtPos(scv); }, - [&](const SubControlVolumeFace& scvf) { return analyticalVelocitySolutionAtPos(scvf);}); - - NavierStokesTestErrors<TypeTag>::printErrors(l2NormAbs, l2NormRel, lInfinityNorm, *this); - } - - void printErrors(const SolutionVector& curSol, Scalar time, unsigned int timeIndex) const - { - PrimaryVariables l2NormAbs(0.0); - PrimaryVariables l2NormRel(0.0); - PrimaryVariables lInfinityNorm(0.0); - - std::ofstream logFile; - logFile.open(this->name() + "_error.csv", std::ios::app); - logFile << time << " , 0000" << timeIndex+1 << ".vtu, "; - logFile.close(); - - NavierStokesTestErrors<TypeTag>::calculateErrors( - l2NormAbs, - l2NormRel, - lInfinityNorm, - *this, - curSol, - [&](const SubControlVolume& scv) { return instationaryAnalyticalPressureSolutionAtPos(scv, time); }, - [&](const SubControlVolumeFace& scvf) { return instationaryAnalyticalVelocitySolutionAtPos(scvf, time);}); - - NavierStokesTestErrors<TypeTag>::printErrors(l2NormAbs, l2NormRel, lInfinityNorm, *this); - } - - void printErrors(const SolutionVector& curSol, unsigned int refinementStep) const - { - PrimaryVariables l2NormAbs(0.0); - PrimaryVariables l2NormRel(0.0); - PrimaryVariables lInfinityNorm(0.0); - - std::ofstream logFile; - logFile.open(this->name() + "_error.csv", std::ios::app); - logFile << refinementStep << " , 0000" << refinementStep+1 << ".vtu , "; - logFile.close(); - - NavierStokesTestErrors<TypeTag>::calculateErrors( - l2NormAbs, - l2NormRel, - lInfinityNorm, - *this, - curSol, - [&](const SubControlVolume& scv) { return analyticalPressureSolutionAtPos(scv); }, - [&](const SubControlVolumeFace& scvf) { return analyticalVelocitySolutionAtPos(scvf);}); - - NavierStokesTestErrors<TypeTag>::printErrors(l2NormAbs, l2NormRel, lInfinityNorm, *this); - } - /*! * \brief Returns the temperature within the domain. * diff --git a/dumux/freeflow/navierstokes/errors.hh b/dumux/freeflow/navierstokes/errors.hh deleted file mode 100755 index b972f6f..0000000 --- a/dumux/freeflow/navierstokes/errors.hh +++ /dev/null @@ -1,179 +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 3 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 - * \ingroup NavierStokesTests - * \copydoc Dumux::NavierStokesTestErrors - */ -#ifndef DUMUX_APPL_ERROR_HH -#define DUMUX_APPL_ERROR_HH - -#include <vector> -#include <cmath> - -namespace Dumux { -/*! - * \ingroup NavierStokesTests - * \brief Routines to calculate the discrete L2 error - */ -template<class TypeTag> -class NavierStokesTestErrors -{ - using Scalar = GetPropType<TypeTag, Properties::Scalar>; - using ModelTraits = GetPropType<TypeTag, Properties::ModelTraits>; - using Indices = typename ModelTraits::Indices; - using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>; - using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; - using SubControlVolume = typename GridGeometry::SubControlVolume; - using SubControlVolumeFace = typename GridGeometry::SubControlVolumeFace; - -public: - /*! - * \brief Calculates the L2 error between the analytical solution and the numerical approximation. - * - * \param problem The object specifying the problem which ought to be simulated - * \param curSol Vector containing the current solution - */ - template<class Problem, class SolutionVector, class LambdaA, class LambdaB> - static void calculateErrors(PrimaryVariables& l2NormAbs, - PrimaryVariables& l2NormRel, - PrimaryVariables& lInfinityNorm, - const Problem& problem, - const SolutionVector& curSol, - const LambdaA& instationaryAnalyticalPressureSolutionAtPosLambdaFunction, - const LambdaB& instationaryAnalyticalVelocitySolutionAtPosLambdaFunction) - { -/////////////////////////// calculate helping variables - Scalar totalVolume = 0.; - - Scalar sumPReference = 0.; - Scalar sumPError = 0.; - Scalar maxPError = 0.; - - Scalar sumUReference = 0.; - Scalar sumUError = 0.; - Scalar maxUError = 0.; - - Scalar sumVReference = 0.; - Scalar sumVError = 0.; - Scalar maxVError = 0.; - - for (const auto& element : elements(problem.gridGeometry().gridView())) - { - auto fvGeometry = localView(problem.gridGeometry()); - fvGeometry.bindElement(element); - - for (auto&& scv : scvs(fvGeometry)) - { - totalVolume += scv.volume(); - - processPressure_(curSol, instationaryAnalyticalPressureSolutionAtPosLambdaFunction, scv, sumPReference, sumPError, maxPError); - - // treat face dofs - for (auto&& scvf : scvfs(fvGeometry)) - { - if (scvf.directionIndex() == 0) - processVelocity_(curSol, instationaryAnalyticalVelocitySolutionAtPosLambdaFunction, scvf, sumUReference, sumUError, maxUError); - else if (scvf.directionIndex() == 1) - processVelocity_(curSol, instationaryAnalyticalVelocitySolutionAtPosLambdaFunction, scvf, sumVReference, sumVError, maxVError); - } - } - } - -/////////////////////////// calculate errors -// absolute L2 error - l2NormAbs[Indices::pressureIdx] = std::sqrt(sumPError / totalVolume); - l2NormAbs[Indices::velocityXIdx] = std::sqrt(sumUError / totalVolume); - l2NormAbs[Indices::velocityYIdx] = std::sqrt(sumVError / totalVolume); - -// relative L2 error - l2NormRel[Indices::pressureIdx] = std::sqrt(sumPError / sumPReference); - l2NormRel[Indices::velocityXIdx] = std::sqrt(sumUError / sumUReference); - l2NormRel[Indices::velocityYIdx] = std::sqrt(sumVError / sumVReference); - -// L infinity error - lInfinityNorm[Indices::pressureIdx] = maxPError; - lInfinityNorm[Indices::velocityXIdx] = maxUError; - lInfinityNorm[Indices::velocityYIdx] = maxVError; - } - - template<class Problem> - static void printErrors(const PrimaryVariables& l2NormAbs, - const PrimaryVariables& l2NormRel, - const PrimaryVariables& lInfinityNorm, - const Problem& problem) - { - const int numCCDofs = problem.gridGeometry().numCellCenterDofs(); - const int numFaceDofs = problem.gridGeometry().numFaceDofs(); - - std::ofstream logFile; - logFile.open(problem.name() + "_error.csv", std::ios::app); - - logFile << std::setprecision(8) << numCCDofs << " , " << numFaceDofs << " , " << numCCDofs + numFaceDofs << " , "; - logFile << std::scientific << l2NormAbs[Indices::pressureIdx] << " , " << l2NormAbs[Indices::velocityXIdx] << " , " << l2NormAbs[Indices::velocityYIdx] << ", "; - logFile << std::scientific << l2NormRel[Indices::pressureIdx] << " , " << l2NormRel[Indices::velocityXIdx] << " , " << l2NormRel[Indices::velocityYIdx] << ", "; - logFile << std::scientific << lInfinityNorm[Indices::pressureIdx] << " , " << lInfinityNorm[Indices::velocityXIdx] << " , " << lInfinityNorm[Indices::velocityYIdx] << std::endl; - - logFile.close(); - } - -private: - template<class T> - static T absDiff_(const T& a, const T& b) - { - return std::abs(a-b); - } - - template<class SolutionVector, class LambdaA> - static void processPressure_(const SolutionVector& curSol, const LambdaA& instationaryAnalyticalPressureSolutionAtPosLambdaFunction, const SubControlVolume& scv, Scalar& sumPReference, Scalar& sumPError, Scalar& maxPError) - { - const auto analyticalSolutionCellCenter = instationaryAnalyticalPressureSolutionAtPosLambdaFunction(scv); - const auto numericalSolutionCellCenter = curSol[GridGeometry::cellCenterIdx()][scv.dofIndex()][Indices::pressureIdx - ModelTraits::dim()]; - - const Scalar pError = absDiff_(analyticalSolutionCellCenter, numericalSolutionCellCenter); - const Scalar pReference = absDiff_(analyticalSolutionCellCenter, 0.0) * absDiff_(analyticalSolutionCellCenter, 0.0); - - maxPError = std::max(maxPError, pError); - sumPError += pError * pError * scv.volume(); - sumPReference += pReference * scv.volume(); - } - - template<class SolutionVector, class LambdaB> - static void processVelocity_(const SolutionVector& curSol, const LambdaB& instationaryAnalyticalVelocitySolutionAtPosLambdaFunction, const SubControlVolumeFace& scvf, Scalar& sumVelReference, Scalar& sumVelError, Scalar& maxVelError) - { - Scalar staggeredHalfVolume = 0.5 * scvf.inside().geometry().volume(); - if (scvf.neighbor() && scvf.inside().level() < scvf.outside().level()) - { - staggeredHalfVolume *= 0.5; - } - - const auto analyticalSolutionFace = instationaryAnalyticalVelocitySolutionAtPosLambdaFunction(scvf); - const auto numericalSolutionFace = curSol[GridGeometry::faceIdx()][scvf.dofIndex()][0]; - - const Scalar velError = absDiff_(analyticalSolutionFace, numericalSolutionFace); - const Scalar velReference = absDiff_(analyticalSolutionFace, 0.0)*absDiff_(analyticalSolutionFace, 0.0); - - maxVelError = std::max(maxVelError, velError); - sumVelError += velError * velError * staggeredHalfVolume; - sumVelReference += velReference * staggeredHalfVolume; - } -}; -} // end namespace Dumux - -#endif -- GitLab From 5158927de621c23f1f77d8fb1fd54b78ac6c1ca5 Mon Sep 17 00:00:00 2001 From: Melanie Lipp <melanie.lipp@iws.uni-stuttgart.de> Date: Thu, 16 Sep 2021 13:29:56 +0200 Subject: [PATCH 39/69] Throw error when trying to average velocities over cvs. --- dumux/freeflow/navierstokes/cvdproblem.hh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dumux/freeflow/navierstokes/cvdproblem.hh b/dumux/freeflow/navierstokes/cvdproblem.hh index db3771e..8684be5 100644 --- a/dumux/freeflow/navierstokes/cvdproblem.hh +++ b/dumux/freeflow/navierstokes/cvdproblem.hh @@ -122,6 +122,10 @@ public: enableInertiaTerms_ = getParamFromGroup<bool>(paramGroup, "Problem.EnableInertiaTerms"); useScvfLineAveraging_ = getParam<bool>("Problem.UseScvfLineAveraging", false); useScvfCVAveraging_ = getParam<bool>("Problem.UseScvfCVAveraging", false); + + if (useScvfCVAveraging_) + DUNE_THROW(Dune::InvalidStateException, "Rectangle averaging not checked for cvd implementation."); + useScvVolumeAveraging_ = getParam<bool>("Problem.UseScvVolumeAveraging", false); useContiSourceAveraging_ = getParam<bool>("Problem.UseContiSourceAveraging", false); quadOrder_ = getParam<unsigned int>("Problem.QuadratureOrder", 3); -- GitLab From 62ff7c8194369cb17934f3112de4ecd0b0f79387 Mon Sep 17 00:00:00 2001 From: Melanie Lipp <melanie.lipp@iws.uni-stuttgart.de> Date: Thu, 16 Sep 2021 15:45:57 +0200 Subject: [PATCH 40/69] [appl][angeli] Fresh copy from dumux-adaptivestaggered. --- appl/freeflow/navierstokes/angeli/main.cc | 189 ++++++----- .../freeflow/navierstokes/angeli/params.input | 23 +- appl/freeflow/navierstokes/angeli/problem.hh | 311 +++++------------- 3 files changed, 189 insertions(+), 334 deletions(-) diff --git a/appl/freeflow/navierstokes/angeli/main.cc b/appl/freeflow/navierstokes/angeli/main.cc index 7714809..cfc9c13 100644 --- a/appl/freeflow/navierstokes/angeli/main.cc +++ b/appl/freeflow/navierstokes/angeli/main.cc @@ -22,11 +22,7 @@ * \brief Test for the instationary staggered grid Navier-Stokes model with analytical solution (Angeli et al., 2017) */ -bool doFirstOrderLocalTruncErrorGlobalRefinement = true; - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#pragma GCC diagnostic ignored "-Wdeprecated-copy" +bool doFirstOrderLocalTruncErrorGlobalRefinement = false; #include <config.h> @@ -48,16 +44,18 @@ bool doFirstOrderLocalTruncErrorGlobalRefinement = true; #include <dumux/linear/seqsolverbackend.hh> #include <dumux/nonlinear/newtonsolver.hh> -#include <dumux/assembly/cvdstaggeredrefinedfvassembler.hh> +#include <dumux/assembly/staggeredrefinedfvassembler.hh> #include <dumux/assembly/diffmethod.hh> #include <dumux/discretization/method.hh> #include <dumux/io/mystaggeredvtkoutputmodule.hh> #include <dumux/io/grid/gridmanager.hh> -#include <dumux/io/readdofbasedresult.hh> -#include <dumux/freeflow/navierstokes/staggered/cvdresidualCalc.hh> +#include <dumux/freeflow/navierstokes/staggered/residualCalc.hh> +#include <dumux/freeflow/navierstokes/errors.hh> + +#include <dumux/io/outputFacility.hh> #include "problem.hh" @@ -110,6 +108,11 @@ int main(int argc, char** argv) try // parse command line arguments and input file Parameters::init(argc, argv, usage); + bool adapt = getParam<bool>("Adaptivity.Adapt", false); + bool doFirstOrderLocalTruncError = getParam<bool>("Numerics.DoFirstOrderLocalTruncError", false); + //when adapt is true refinement is local, not only global + doFirstOrderLocalTruncErrorGlobalRefinement = !adapt && doFirstOrderLocalTruncError; + using HelpingGridManager = Dumux::GridManager<GetPropType<TypeTag, Properties::HelpingGrid>>; HelpingGridManager helpingGridManager; helpingGridManager.init("Helper"); @@ -129,35 +132,41 @@ int main(int argc, char** argv) try // we compute on the leaf grid view const auto& leafGridView = gridManager.grid().leafGridView(); - bool adapt = getParam<bool>("Adaptivity.Adapt", false); + using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; + using GridView = typename GridGeometry::GridView; + using Element = typename GridView::template Codim<0>::Entity; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + if (adapt) { - gridManager.grid().preAdapt(); + using Scalar = GetPropType<TypeTag, Properties::Scalar>; - for (const auto& element : elements(leafGridView)) - { - using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; - using GridView = typename GridGeometry::GridView; - using Element = typename GridView::template Codim<0>::Entity; - using GlobalPosition = typename Element::Geometry::GlobalCoordinate; - GlobalPosition pos = element.geometry().center(); + Scalar leftX = getParam<Scalar>("Adaptivity.LeftX"); + Scalar rightX = getParam<Scalar>("Adaptivity.RightX"); + Scalar lowerY = getParam<Scalar>("Adaptivity.LowerY"); + Scalar upperY = getParam<Scalar>("Adaptivity.UpperY"); - auto x = pos[0]; - auto y = pos[1]; + gridManager.grid().preAdapt(); - if((x > 0.4 && x < 0.6) && (y > 0.4 && y < 0.6)) + for (const auto& element : elements(leafGridView)) { - gridManager.grid().mark( 1, element); + GlobalPosition pos = element.geometry().center(); + + auto x = pos[0]; + auto y = pos[1]; + + if((leftX < x) && (x < rightX) && (y > lowerY) && (y < upperY)) + { + gridManager.grid().mark( 1, element); + } } - } - gridManager.grid().adapt(); - gridManager.grid().postAdapt(); + gridManager.grid().adapt(); + gridManager.grid().postAdapt(); } // create the finite volume grid geometry using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; auto gridGeometry = std::make_shared<GridGeometry>(leafGridView); - gridGeometry->update(); // get some time loop parameters using Scalar = GetPropType<TypeTag, Properties::Scalar>; @@ -203,20 +212,15 @@ int main(int argc, char** argv) try vtkWriter.addField(problem->getAnalyticalPressureSolution(), "pressureExact"); vtkWriter.addField(problem->getAnalyticalVelocitySolution(), "velocityExact"); vtkWriter.addFaceField(problem->getAnalyticalVelocitySolutionOnFace(), "faceVelocityExact"); - - if (getParam<bool>("Problem.ReadDofBasedPressure", false)) - { - using CellCenterSolutionVector = GetPropType<TypeTag, Properties::CellCenterSolutionVector>; - CellCenterSolutionVector IBAMRpres; - IBAMRpres.resize(gridGeometry->numCellCenterDofs()); - readDofBasedResult(IBAMRpres, gridGeometry, "pressure"); - vtkWriter.addField(IBAMRpres, "IBAMRpres"); - } - vtkWriter.write(0.0); + using CellCenterSolutionVector = GetPropType<TypeTag, Properties::CellCenterSolutionVector>; + CellCenterSolutionVector numericalCCResidualWithAnalytical; + numericalCCResidualWithAnalytical.resize(numDofsCellCenter); + vtkWriter.addField(numericalCCResidualWithAnalytical, "continuityResidual"); + // the assembler with time loop for instationary problem - using Assembler = CVDStaggeredRefinedFVAssembler<TypeTag, DiffMethod::numeric>; + using Assembler = StaggeredRefinedFVAssembler<TypeTag, DiffMethod::numeric>; auto assembler = std::make_shared<Assembler>(problem, gridGeometry, gridVariables, timeLoop, xOld); // the linear solver @@ -227,83 +231,91 @@ int main(int argc, char** argv) try using NewtonSolver = Dumux::NewtonSolver<Assembler, LinearSolver>; NewtonSolver nonLinearSolver(assembler, linearSolver); - if (timeLoop->time() != 0) - DUNE_THROW(Dune::InvalidStateException, "Was expecting to start with time zero."); - - //here, the temporal starting value is for t=0, the iteration starting value is the analytical solution for t=deltaT - problem->createAnalyticalSolution(timeLoop->timeStepSize()); - SolutionVector analyticalFirstTimeStep; - analyticalFirstTimeStep[GridGeometry::faceIdx()] = problem->getAnalyticalFaceSolutionVector(); - analyticalFirstTimeStep[GridGeometry::cellCenterIdx()] = problem->getAnalyticalPressureSolution(); - gridVariables->update(analyticalFirstTimeStep); - nonLinearSolver.assembleLinearSystem(analyticalFirstTimeStep); - const auto faceResidualWithAnalyticalSol = (*assembler).residual()[Dune::index_constant<0>()]; - const auto ccResidualWithAnalyticalSol = (*assembler).residual()[Dune::index_constant<1>()]; -// std::string filenamevars0 = "analyticalsol0"; -// std::ofstream s; -// s.open(filenamevars0 + ".csv"); -// writeVectorToCSV(s, analyticalFirstTimeStep[Dune::index_constant<0>()]); -// s.close(); -// std::string filenamevars1 = "analyticalsol1"; -// s.open(filenamevars1 + ".csv"); -// writeVectorToCSV(s, analyticalFirstTimeStep[Dune::index_constant<1>()]); -// s.close(); - gridVariables->update(x); + using HostGrid = Dune::ALUGrid<2,2,Dune::cube,Dune::nonconforming >; + using HostGridManager = GridManager<HostGrid>; + + std::array<std::string, 4> paramGroups = {"finexCVs", "fineyCVs", "coarsexCVs", "coarseyCVs"}; //xfine... + std::array<HostGridManager, 4> cvGridManagers = {}; + std::array<std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>>,4> cvCenterScvfIndicesMaps; + CVOutputFacility<TypeTag> cvOutputFacility(problem); + cvOutputFacility.iniCVGridManagers(cvGridManagers, cvCenterScvfIndicesMaps, paramGroups); + std::vector<std::pair<unsigned int, Scalar>> pvdFileInfos; + + NavierStokesRefinedErrors errors(problem, x, 0.0, 0); + NavierStokesRefinedErrorCSVWriter errorCSVWriter(problem); + unsigned int timeIndex = 0; // time loop - const bool printL2Error = getParam<bool>("Problem.PrintL2Error"); - int timeIndex = 0; timeLoop->start(); do { + Scalar actualCurrentTime = timeLoop->time()+timeLoop->timeStepSize(); + // 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(); + //output + if (getParam<bool>("Problem.PrintErrors", true)) + { + errors.update(x, actualCurrentTime, timeIndex); + errorCSVWriter.printErrors(errors); + } + + using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; + FaceSolutionVector numericalFaceResidualWithAnalytical; + + std::optional<std::array<std::vector<Scalar>, 4>> optionalPerfectInterpolationFaceResiduals; + std::array<std::vector<Scalar>, 4> perfectInterpolationFaceResiduals; + optionalPerfectInterpolationFaceResiduals.emplace(perfectInterpolationFaceResiduals); + + ResidualCalc<TypeTag> residualCalc(problem); + residualCalc.calcResidualsInstationary(timeLoop, gridGeometry, cvGridManagers, cvCenterScvfIndicesMaps, numericalCCResidualWithAnalytical, numericalFaceResidualWithAnalytical, optionalPerfectInterpolationFaceResiduals); - if(printL2Error) + bool readDofBasedValues = getParam<bool>("Problem.ReadDofBasedValues", false) && scalarCmp(getParam<Scalar>("Problem.TimeDofBasedValues"), actualCurrentTime); + if (readDofBasedValues) { - using ModelTraits = GetPropType<TypeTag, Properties::ModelTraits>; - using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>; - using L2Error = NavierStokesTestL2Error<Scalar, ModelTraits, PrimaryVariables>; - using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; - - const auto l2error = L2Error::calculateL2Error(*problem, x); - const int numCellCenterDofs = (*gridGeometry).numCellCenterDofs(); - const int numFaceDofs = (*gridGeometry).numFaceDofs(); - std::cout << std::setprecision(8) << "** L2 error (abs/rel) for " - << std::setw(6) << numCellCenterDofs << " cc dofs and " << numFaceDofs << " face dofs (total: " << numCellCenterDofs + numFaceDofs << "): " - << std::scientific - << "L2(p) = " << l2error.first[Indices::pressureIdx] << " / " << l2error.second[Indices::pressureIdx] - << ", L2(vx) = " << l2error.first[Indices::velocityXIdx] << " / " << l2error.second[Indices::velocityXIdx] - << ", L2(vy) = " << l2error.first[Indices::velocityYIdx] << " / " << l2error.second[Indices::velocityYIdx] - << std::endl; + CellCenterSolutionVector IBAMRpres; + IBAMRpres.resize(gridGeometry->numCellCenterDofs()); + ReadDofBasedResult<TypeTag> reader(problem); + reader.readDofBasedResult(IBAMRpres, "pressure"); + vtkWriter.addField(IBAMRpres, "IBAMRpres"); } - // advance to the time loop to the next step - timeLoop->advanceTimeStep(); - problem->updateTime(timeLoop->time()); + problem->createAnalyticalSolution(actualCurrentTime); + vtkWriter.write(actualCurrentTime); - problem->createAnalyticalSolution(timeLoop->time()); + if (readDofBasedValues) + vtkWriter.removeField(); - // write vtk output + cvOutputFacility.onCVsOutputResidualsAndPrimVars( + gridGeometry, + cvGridManagers, + cvCenterScvfIndicesMaps, + paramGroups, + x, + timeIndex,/*0 for stationary*/ + numericalFaceResidualWithAnalytical, + optionalPerfectInterpolationFaceResiduals, + readDofBasedValues); - vtkWriter.write(timeLoop->time()); + pvdFileInfos.push_back(std::make_pair(timeIndex, actualCurrentTime)); - // report statistics of this time step + // prepare next time step + xOld = x; + gridVariables->advanceTimeStep(); + timeLoop->advanceTimeStep(); + problem->updateTime(timeLoop->time()); timeLoop->reportTimeStep(); - - // set new dt as suggested by newton solver timeLoop->setTimeStepSize(nonLinearSolver.suggestTimeStepSize(timeLoop->timeStepSize())); problem->updateTimeStepSize(timeLoop->timeStepSize()); ++timeIndex; } while (!timeLoop->finished()); + cvOutputFacility.printPvdFiles(paramGroups, pvdFileInfos); + timeLoop->finalize(leafGridView.comm()); //////////////////////////////////////////////////////////// @@ -343,4 +355,3 @@ catch (...) std::cerr << "Unknown exception thrown! ---> Abort!" << std::endl; return 4; } -#pragma GCC diagnostic pop diff --git a/appl/freeflow/navierstokes/angeli/params.input b/appl/freeflow/navierstokes/angeli/params.input index f7e7dce..f2099f4 100644 --- a/appl/freeflow/navierstokes/angeli/params.input +++ b/appl/freeflow/navierstokes/angeli/params.input @@ -28,10 +28,13 @@ File = grid.dgf [Problem] Name = test_angeli # name passed to the output routines EnableGravity = false -PrintL2Error = false +PrintErrors = true EnableInertiaTerms = true -AveragedAnalyticalSolution = false +ReadDofBasedPressure = false ReadDofBasedVelocity = false +UseScvfLineAveraging = true +UseContiSourceAveraging = true +QuadratureOrder = 6 #among others for continuity-residual to become closer to zero [Component] LiquidDensity = 1 @@ -43,19 +46,21 @@ NumericDifference.BaseEpsilon = 1e-8 [Newton] MaxSteps = 20 -TargetSteps = 20 MaxRelativeShift = 1e-5 -ExitAfterFirstIteration = false -OutputMatrices = false [Vtk] WriteFaceData = false +[Numerics] +DoFirstOrderLocalTruncError = false + [Adaptivity] -Adapt = false -Conservation = false -LinearInterpolation = false -DebugDof = -1 +Conservation = true +Adapt = true +LeftX = .4 +RightX = .6 +LowerY = .4 +UpperY = .6 [VelocityReadIn] NumFileEntries = 260 diff --git a/appl/freeflow/navierstokes/angeli/problem.hh b/appl/freeflow/navierstokes/angeli/problem.hh index 2ee3874..77037c1 100644 --- a/appl/freeflow/navierstokes/angeli/problem.hh +++ b/appl/freeflow/navierstokes/angeli/problem.hh @@ -21,44 +21,39 @@ * \ingroup NavierStokesTests * \brief Test for the instationary staggered grid Navier-Stokes model with analytical solution (Angeli et al., 2017) */ -#ifndef DUMUX_CVD_ANGELI_TEST_PROBLEM_HH -#define DUMUX_CVD_ANGELI_TEST_PROBLEM_HH +#ifndef DUMUX_ANGELI_TEST_PROBLEM_HH +#define DUMUX_ANGELI_TEST_PROBLEM_HH #include <dune/alugrid/grid.hh> #include <dune/grid/yaspgrid.hh> -#include <dumux/assembly/cvdstaggeredrefinedlocalresidual.hh> +#include <dumux/assembly/staggeredrefinedlocalresidual.hh> + +#include <dumux/common/numeqvector.hh> #include <dumux/material/fluidsystems/1pliquid.hh> #include <dumux/material/components/constant.hh> #include <dumux/freeflow/navierstokes/boundarytypes.hh> #include <dumux/freeflow/navierstokes/model.hh> -#include <dumux/freeflow/navierstokes/cvdproblem.hh> -#include <dumux/freeflow/navierstokes/cvdlocalresidual.hh> -#include <dumux/freeflow/navierstokes/cvdfluxvariableswrapper.hh> +#include <dumux/freeflow/navierstokes/myproblem.hh> +#include <dumux/freeflow/navierstokes/mylocalresidual.hh> +#include <dumux/freeflow/navierstokes/myfluxvariables.hh> #include <dumux/freeflow/navierstokes/myvolumevariables.hh> #include <dumux/freeflow/navierstokes/myiofields.hh> #include <dumux/discretization/method.hh> #include <dumux/discretization/staggered/myfacesolution.hh> +#include <dumux/discretization/staggered/mygridvariables.hh> +#include <dumux/discretization/staggered/myfvgridgeometry.hh> #include <dumux/discretization/staggered/mygridfluxvariablescache.hh> +#include <dumux/discretization/staggered/freeflow/fvgridgeometrytraits1.hh> #include <dumux/discretization/staggered/freeflow/properties.hh> #include <dumux/discretization/staggered/freeflow/myfacevariables.hh> -#include <dumux/discretization/staggered/freeflow/cvdlocalfacevariables.hh> #include <dumux/discretization/staggered/freeflow/elementvolumevariables1.hh> #include <dumux/discretization/staggered/freeflow/myvelocityoutput.hh> #include <dumux/discretization/staggered/freeflow/mygridvolumevariables.hh> -#include <dumux/discretization/staggered/cvdelementfacesolution.hh> -#include <dumux/discretization/staggered/cvdgridvariables.hh> -#include <dumux/discretization/staggered/cvdlocalgridfacevariables.hh> -#include <dumux/discretization/staggered/cvdfvgridgeometry.hh> -#include <dumux/discretization/staggered/freeflow/cvdfvgridgeometrytraits.hh> - - -#include <appl/freeflow/navierstokes/l2error.hh> - namespace Dumux { template <class TypeTag> @@ -120,15 +115,6 @@ public: using type = MyStaggeredFaceVariables<ModelTraits, FacePrimaryVariables, GridView::dimension, upwindSchemeOrder>; }; -template<class TypeTag> -struct LocalFaceVariables<TypeTag, TTag::AngeliTestTypeTag> -{ -private: - using FacePrimaryVariables = GetPropType<TypeTag, Properties::FacePrimaryVariables>; -public: - using type = CVDStaggeredLocalFaceVariables<FacePrimaryVariables>; -}; - //! The velocity output template<class TypeTag> struct VelocityOutput<TypeTag, TTag::AngeliTestTypeTag> @@ -192,28 +178,6 @@ public: using type = Dumux::MyStaggeredFaceSolution<FaceSolutionVector>; }; - -template<class TypeTag> -struct ElementFaceSolution<TypeTag, TTag::AngeliTestTypeTag> -{ -private: - using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; -public: - using type = Dumux::CVDElementFaceSolution<FaceSolutionVector>; -}; - -//! Set the GridLocalFaceVariables -template<class TypeTag> -struct GridLocalFaceVariables<TypeTag, TTag::AngeliTestTypeTag> -{ - private: - using Problem = GetPropType<TypeTag, Properties::Problem>; - using LocalFaceVariables = GetPropType<TypeTag, Properties::LocalFaceVariables>; - static constexpr auto enableCache = getPropValue<TypeTag, Properties::EnableGridFaceVariablesCache>(); - public: - using type = CVDStaggeredLocalGridFaceVariables<Problem, LocalFaceVariables, enableCache>; -}; - //! Set the grid variables (volume, flux and face variables) template<class TypeTag> struct GridVariables<TypeTag, TTag::AngeliTestTypeTag> @@ -223,9 +187,8 @@ private: using GVV = GetPropType<TypeTag, Properties::GridVolumeVariables>; using GFVC = GetPropType<TypeTag, Properties::GridFluxVariablesCache>; using GFV = GetPropType<TypeTag, Properties::GridFaceVariables>; - using GLFV = GetPropType<TypeTag, Properties::GridLocalFaceVariables>; public: - using type = CVDStaggeredGridVariables<GG, GVV, GFVC, GFV, GLFV>; + using type = MyStaggeredGridVariables<GG, GVV, GFVC, GFV>; }; //! The default fv grid geometry @@ -236,9 +199,9 @@ private: static constexpr auto upwindSchemeOrder = getPropValue<TypeTag, Properties::UpwindSchemeOrder>(); static constexpr bool enableCache = getPropValue<TypeTag, Properties::EnableGridGeometryCache>(); using GridView = typename GetPropType<TypeTag, Properties::Grid>::LeafGridView; - using Traits = CVDStaggeredFreeFlowDefaultGridGeometryTraits<GridView, upwindSchemeOrder>; + using Traits = MyStaggeredFreeFlowDefaultGridGeometryTraits<GridView, upwindSchemeOrder>; public: - using type = CVDStaggeredGridGeometry<GridView, enableCache, Traits>; + using type = MyStaggeredGridGeometry<GridView, enableCache, Traits>; }; //! Set the volume variables property @@ -299,9 +262,9 @@ private: static constexpr auto upwindSchemeOrder = getPropValue<TypeTag, Properties::UpwindSchemeOrder>(); static constexpr bool enableCache = getPropValue<TypeTag, Properties::EnableGridGeometryCache>(); using GridView = typename Dune::ALUGrid<2,2,Dune::cube,Dune::nonconforming >::LeafGridView; - using Traits = CVDStaggeredFreeFlowDefaultGridGeometryTraits<GridView, upwindSchemeOrder>; + using Traits = MyStaggeredFreeFlowDefaultGridGeometryTraits<GridView, upwindSchemeOrder>; public: - using type = CVDStaggeredGridGeometry<GridView, enableCache, Traits>; + using type = MyStaggeredGridGeometry<GridView, enableCache, Traits>; }; } @@ -319,9 +282,8 @@ class AngeliTestProblem : public MyNavierStokesProblem<TypeTag> using BoundaryTypes = Dumux::NavierStokesBoundaryTypes<GetPropType<TypeTag, Properties::ModelTraits>::numEq()>; using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; - using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; using ModelTraits = GetPropType<TypeTag, Properties::ModelTraits>; - using NumEqVector = GetPropType<TypeTag, Properties::NumEqVector>; + using NumEqVector = Dumux::NumEqVector<GetPropType<TypeTag, Properties::PrimaryVariables>>; using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>; using Scalar = GetPropType<TypeTag, Properties::Scalar>; using SolutionVector = GetPropType<TypeTag, Properties::SolutionVector>; @@ -332,8 +294,12 @@ class AngeliTestProblem : public MyNavierStokesProblem<TypeTag> using Element = typename GridGeometry::GridView::template Codim<0>::Entity; using GlobalPosition = typename Element::Geometry::GlobalCoordinate; using VelocityVector = Dune::FieldVector<Scalar, dimWorld>; + using SubControlVolume = typename GridGeometry::SubControlVolume; + using SubControlVolumeFace = typename GetPropType<TypeTag, Properties::GridGeometry>::SubControlVolumeFace; public: + using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; + AngeliTestProblem(std::shared_ptr<const GridGeometry> gridGeometry) : ParentType(gridGeometry), eps_(1e-6) { @@ -433,127 +399,62 @@ public: /*! - * \brief Return dirichlet boundary values at a given position + * \brief Evaluate the boundary conditions for a dirichlet + * control volume face (velocities) * - * \param globalPos The global position - */ - PrimaryVariables dirichletAtPos(const GlobalPosition & globalPos) const - { - // use the values of the analytical solution - return this->instationaryAnalyticalSolution(globalPos, time_+timeStepSize_); - } - - /*! - * \brief Return the analytical solution of the problem at a given position + * \param element The finite element + * \param scvf the sub control volume face * - * \param globalPos The global position + * Concerning the usage of averaged velocity, see the explanation of the initial function. The average of the nondirection velocity along an scvf is required in the context of dirichlet boundary conditions for the functions getParallelVelocityFromBoundary_ and getParallelVelocityFromOtherBoundary_ within myfluxvariables.hh. There dirichlet is called for ghost faces built from the normalFace but the value then is taken in the the direction scvf.directionIndex, which is along that normalFace. */ - PrimaryVariables instationaryAnalyticalSolutionAtPos(const GlobalPosition& globalPos, const Scalar time) const + PrimaryVariables dirichlet(const Element& element, const SubControlVolumeFace& scvf) const { - const Scalar x = globalPos[0]; - const Scalar y = globalPos[1]; - const Scalar t = time; + Scalar time = time_+timeStepSize_; - PrimaryVariables values = {}; + PrimaryVariables priVars(0.0); - for (unsigned int j = 0; j < 2; ++j) - { - for (unsigned int i = 0; i < values.size(); ++i) - { - values[i] += xFactorAnalyticalSolutionAtPos(x,t)[j][i]*yFactorAnalyticalSolutionAtPos(y,t)[j][i]; - } - } + unsigned int dirIdx = scvf.directionIndex(); + priVars[Indices::velocity(dirIdx)] = this->instationaryAnalyticalVelocitySolutionAtPos(scvf, time); + unsigned int nonDirIdx = (dirIdx == 0)?1:0; + priVars[Indices::velocity(nonDirIdx)] = this->instationaryAnalyticalNonDirVelocitySolutionAtPos(scvf, time); - return values; + return priVars; } /*! - * \brief Returns the analytical solution of the problem at a given position. + * \brief Evaluate the boundary conditions for a dirichlet + * control volume face (pressure) * - * \param globalPos The global position + * \param element The finite element + * \param scv the sub control volume */ - PrimaryVariables analyticalSolution(const GlobalPosition& globalPos) const + PrimaryVariables dirichlet(const Element& element, const SubControlVolume& scv) const { - return this->instationaryAnalyticalSolution(globalPos, time()+timeStepSize_); + Scalar time = time_+timeStepSize_; + + PrimaryVariables priVars(0.0); + priVars[Indices::pressureIdx] = this->instationaryAnalyticalPressureSolutionAtPos(scv, time); + return priVars; } /*! - * \brief Returns the analytical solution of the problem at a given position. + * \brief Return the analytical solution of the problem at a given position * * \param globalPos The global position */ - PrimaryVariables analyticalSolutionAtPos(const GlobalPosition& globalPos) const - { - return this->instationaryAnalyticalSolutionAtPos(globalPos, time()+timeStepSize_); - } - - - std::array<PrimaryVariables, 2> xFactorAnalyticalSolutionAtPos(Scalar x, Scalar t) const - { - PrimaryVariables values1; - values1[Indices::pressureIdx] = - 0.25 * f_(t) * f_(t) * 4.0 * M_PI * M_PI * std::cos(2.0 * M_PI * x)*rho_; - values1[Indices::velocityXIdx] = f_(t) * f2_(x) ; - values1[Indices::velocityYIdx] = - f_(t) * df2_(x); - - PrimaryVariables values2 = {}; - values2[Indices::pressureIdx] = 1.; - - std::array<PrimaryVariables, 2> retPair; - retPair[0] = values1; - retPair[1] = values2; - - return retPair; - } - - std::array<PrimaryVariables, 2> yFactorAnalyticalSolutionAtPos(Scalar y, Scalar t) const - { - PrimaryVariables values1; - values1[Indices::pressureIdx] = 1.; - values1[Indices::velocityXIdx] = df3_(y); - values1[Indices::velocityYIdx] = f3_(y); - - PrimaryVariables values2 = {}; - values2[Indices::pressureIdx] = - 0.25 * f_(t) * f_(t) * M_PI * M_PI * std::cos(4.0 * M_PI * y)*rho_; - - std::array<PrimaryVariables, 2> retPair; - retPair[0] = values1; - retPair[1] = values2; - - return retPair; - } - - std::array<PrimaryVariables, 2> xFactorAnalyticalSolutionAntiderivativeAtPos(Scalar x, Scalar t) const - { - PrimaryVariables values1; - values1[Indices::pressureIdx] = - 0.25 * f_(t) * f_(t) * 2.0 * M_PI * std::sin(2.0 * M_PI * x)*rho_; - values1[Indices::velocityXIdx] = f_(t) * intf2_(x) ; - values1[Indices::velocityYIdx] = - f_(t) * f2_(x); - - PrimaryVariables values2 = {}; - values2[Indices::pressureIdx] = x; - - std::array<PrimaryVariables, 2> retPair; - retPair[0] = values1; - retPair[1] = values2; - - return retPair; - } - - std::array<PrimaryVariables, 2> yFactorAnalyticalSolutionAntiderivativeAtPos(Scalar y, Scalar t) const + PrimaryVariables instationaryAnalyticalSolutionAtPos(const GlobalPosition& globalPos, const Scalar time) const { - PrimaryVariables values1; - values1[Indices::pressureIdx] = y; - values1[Indices::velocityXIdx] = f3_(y); - values1[Indices::velocityYIdx] = intf3_(y); + const Scalar x = globalPos[0]; + const Scalar y = globalPos[1]; + const Scalar t = time; - PrimaryVariables values2 = {}; - values2[Indices::pressureIdx] = - 1./16 * f_(t) * f_(t) * M_PI * std::sin(4.0 * M_PI * y)*rho_; + PrimaryVariables values = {}; - std::array<PrimaryVariables, 2> retPair; - retPair[0] = values1; - retPair[1] = values2; + values[Indices::pressureIdx] = - 0.25 * f_(t) * f_(t) * M_PI * M_PI *rho_ * (4.0 * std::cos(2.0 * M_PI * x) - std::cos(4.0 * M_PI * y)); + values[Indices::velocityXIdx] = f_(t) * f2_(x)*df3_(y); + values[Indices::velocityYIdx] = - f_(t) * df2_(x)* f3_(y); - return retPair; + return values; } // \} @@ -563,16 +464,32 @@ public: */ // \{ - /*! - * \brief Evaluate the initial value for a control volume. + /*! + * \brief Evaluates the initial value for a sub control volume face (velocities) * - * \param globalPos The global position + * Simply assigning the value of the analytical solution at the face center + * gives a discrete solution that is not divergence-free. For small initial + * time steps, this has a negative impact on the pressure solution + * after the first time step. The flag UseVelocityAveraging triggers the + * function averagedVelocity_ which uses a higher order quadrature formula to + * bring the discrete solution sufficiently close to being divergence-free. */ - PrimaryVariables initialAtPos(const GlobalPosition &globalPos) const + PrimaryVariables initial(const SubControlVolumeFace& scvf) const { - return this->instationaryAnalyticalSolution(globalPos, 0); + PrimaryVariables priVars(0.0); + priVars[Indices::velocity(scvf.directionIndex())] = this->instationaryAnalyticalVelocitySolutionAtPos(scvf, 0.); + return priVars; } + /*! + * \brief Evaluates the initial value for a control volume (pressure) + */ + PrimaryVariables initial(const SubControlVolume& scv) const + { + PrimaryVariables priVars(0.0); + priVars[Indices::pressureIdx] = this->instationaryAnalyticalPressureSolutionAtPos(scv, 0.); + return priVars; + } /*! * \brief Updates the time */ @@ -589,79 +506,11 @@ public: timeStepSize_ = timeStepSize; } - /*! - * \brief Returns the analytical solution for the pressure - */ - auto& getAnalyticalPressureSolution() const - { - return analyticalPressure_; - } - - /*! - * \brief Returns the analytical solution for the velocity - */ - auto& getAnalyticalVelocitySolution() const - { - return analyticalVelocity_; - } - - auto& getAnalyticalFaceSolutionVector() const - { - return analyticalFaceSolutionVector_; - } - - /*! - * \brief Returns the analytical solution for the velocity at the faces - */ - auto& getAnalyticalVelocitySolutionOnFace() const - { - return analyticalVelocityOnFace_; - } - Scalar time() const { return time_; } - /*! - * \brief Adds additional VTK output data to the VTKWriter. Function is called by the output module on every write. - */ - void createAnalyticalSolution(Scalar t) - { - analyticalPressure_.resize(this->gridGeometry().numCellCenterDofs()); - analyticalVelocity_.resize(this->gridGeometry().numCellCenterDofs()); - analyticalVelocityOnFace_.resize(this->gridGeometry().numFaceDofs()); - analyticalFaceSolutionVector_.resize(this->gridGeometry().numFaceDofs()); - - for (const auto& element : elements(this->gridGeometry().gridView())) - { - auto fvGeometry = localView(this->gridGeometry()); - fvGeometry.bindElement(element); - for (auto&& scv : scvs(fvGeometry)) - { - auto ccDofIdx = scv.dofIndex(); - auto ccDofPosition = scv.dofPosition(); - auto analyticalSolutionAtCc = this->instationaryAnalyticalSolution(ccDofPosition, t); - - // velocities on faces - for (auto&& scvf : scvfs(fvGeometry)) - { - const auto faceDofIdx = scvf.dofIndex(); - const auto faceDofPosition = scvf.center(); - const auto dirIdx = scvf.directionIndex(); - const auto analyticalSolutionAtFace = this->instationaryAnalyticalSolution(faceDofPosition, t); - analyticalVelocityOnFace_[faceDofIdx][dirIdx] = analyticalSolutionAtFace[Indices::velocity(dirIdx)]; - analyticalFaceSolutionVector_[faceDofIdx] = analyticalSolutionAtFace[Indices::velocity(dirIdx)]; - } - - analyticalPressure_[ccDofIdx] = analyticalSolutionAtCc[Indices::pressureIdx]; - - for(int dirIdx = 0; dirIdx < ModelTraits::dim(); ++dirIdx) - analyticalVelocity_[ccDofIdx][dirIdx] = analyticalSolutionAtCc[Indices::velocity(dirIdx)]; - } - } - } - private: Scalar f_(Scalar t) const { return std::exp(- 5.0 * kinematicViscosity_ * M_PI * M_PI * t); } @@ -669,18 +518,12 @@ private: Scalar df_(Scalar t) const { return - 5.0 * kinematicViscosity_ * M_PI * M_PI * f_(t); } - Scalar intf2_ (Scalar x) const - { return std::sin(M_PI * x)/M_PI; } - Scalar f2_ (Scalar x) const { return std::cos(M_PI * x); } Scalar df2_ (Scalar x) const { return -M_PI * std::sin(M_PI * x); } - Scalar intf3_ ( Scalar x) const - { return std::sin(2.0 * M_PI * x)/(2.0 * M_PI); } - Scalar f3_ ( Scalar x) const { return std::cos(2.0 * M_PI * x); } @@ -697,10 +540,6 @@ private: Scalar kinematicViscosity_; Scalar rho_; - CellCenterSolutionVector analyticalPressure_; - std::vector<VelocityVector> analyticalVelocity_; - std::vector<VelocityVector> analyticalVelocityOnFace_; - FaceSolutionVector analyticalFaceSolutionVector_; Scalar time_ = 0; Scalar timeStepSize_ = 0; -- GitLab From 27b72b25f4887b5fd14dea34323deaa63db8315f Mon Sep 17 00:00:00 2001 From: Melanie Lipp <melanie.lipp@iws.uni-stuttgart.de> Date: Thu, 16 Sep 2021 16:26:34 +0200 Subject: [PATCH 41/69] [appl][angeli] Adapt to the needs of the cvd refinement. --- appl/freeflow/navierstokes/angeli/main.cc | 30 +++++---- .../freeflow/navierstokes/angeli/params.input | 7 +- appl/freeflow/navierstokes/angeli/problem.hh | 64 +++++++++++++++---- 3 files changed, 74 insertions(+), 27 deletions(-) diff --git a/appl/freeflow/navierstokes/angeli/main.cc b/appl/freeflow/navierstokes/angeli/main.cc index cfc9c13..443fabf 100644 --- a/appl/freeflow/navierstokes/angeli/main.cc +++ b/appl/freeflow/navierstokes/angeli/main.cc @@ -24,6 +24,10 @@ bool doFirstOrderLocalTruncErrorGlobalRefinement = false; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#pragma GCC diagnostic ignored "-Wdeprecated-copy" + #include <config.h> #include <ctime> @@ -37,6 +41,7 @@ bool doFirstOrderLocalTruncErrorGlobalRefinement = false; #include <dune/istl/io.hh> #include <dumux/common/properties.hh> +#include <dumux/common/coursevelocityproperties.hh> #include <dumux/common/parameters.hh> #include <dumux/common/dumuxmessage.hh> #include <dumux/common/defaultusagemessage.hh> @@ -44,18 +49,19 @@ bool doFirstOrderLocalTruncErrorGlobalRefinement = false; #include <dumux/linear/seqsolverbackend.hh> #include <dumux/nonlinear/newtonsolver.hh> -#include <dumux/assembly/staggeredrefinedfvassembler.hh> +#include <dumux/assembly/cvdstaggeredrefinedfvassembler.hh> #include <dumux/assembly/diffmethod.hh> #include <dumux/discretization/method.hh> #include <dumux/io/mystaggeredvtkoutputmodule.hh> #include <dumux/io/grid/gridmanager.hh> +#include <dumux/io/grid/cvdcontrolvolumegrids.hh> -#include <dumux/freeflow/navierstokes/staggered/residualCalc.hh> +#include <dumux/freeflow/navierstokes/staggered/cvdresidualCalc.hh> #include <dumux/freeflow/navierstokes/errors.hh> -#include <dumux/io/outputFacility.hh> +#include <dumux/io/cvdoutputFacility.hh> #include "problem.hh" @@ -220,7 +226,7 @@ int main(int argc, char** argv) try vtkWriter.addField(numericalCCResidualWithAnalytical, "continuityResidual"); // the assembler with time loop for instationary problem - using Assembler = StaggeredRefinedFVAssembler<TypeTag, DiffMethod::numeric>; + using Assembler = CVDStaggeredRefinedFVAssembler<TypeTag, DiffMethod::numeric>; auto assembler = std::make_shared<Assembler>(problem, gridGeometry, gridVariables, timeLoop, xOld); // the linear solver @@ -234,14 +240,15 @@ int main(int argc, char** argv) try using HostGrid = Dune::ALUGrid<2,2,Dune::cube,Dune::nonconforming >; using HostGridManager = GridManager<HostGrid>; - std::array<std::string, 4> paramGroups = {"finexCVs", "fineyCVs", "coarsexCVs", "coarseyCVs"}; //xfine... - std::array<HostGridManager, 4> cvGridManagers = {}; - std::array<std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>>,4> cvCenterScvfIndicesMaps; - CVOutputFacility<TypeTag> cvOutputFacility(problem); + std::array<std::string, 2> paramGroups = {"coarsexCVs", "coarseyCVs"}; + std::array<HostGridManager, 2> cvGridManagers = {}; + std::array<std::map<GlobalPosition, std::vector<unsigned int>, ContainerCmpClass<GlobalPosition>>,2> cvCenterScvfIndicesMaps; + CVDCVOutputFacility<TypeTag> cvOutputFacility(problem); cvOutputFacility.iniCVGridManagers(cvGridManagers, cvCenterScvfIndicesMaps, paramGroups); std::vector<std::pair<unsigned int, Scalar>> pvdFileInfos; NavierStokesRefinedErrors errors(problem, x, 0.0, 0); + errors.setCoarseVelocityDiscretization(true); NavierStokesRefinedErrorCSVWriter errorCSVWriter(problem); unsigned int timeIndex = 0; @@ -266,12 +273,10 @@ int main(int argc, char** argv) try using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; FaceSolutionVector numericalFaceResidualWithAnalytical; - std::optional<std::array<std::vector<Scalar>, 4>> optionalPerfectInterpolationFaceResiduals; - std::array<std::vector<Scalar>, 4> perfectInterpolationFaceResiduals; - optionalPerfectInterpolationFaceResiduals.emplace(perfectInterpolationFaceResiduals); + std::optional<std::array<std::vector<Scalar>, 2>> optionalPerfectInterpolationFaceResiduals; ResidualCalc<TypeTag> residualCalc(problem); - residualCalc.calcResidualsInstationary(timeLoop, gridGeometry, cvGridManagers, cvCenterScvfIndicesMaps, numericalCCResidualWithAnalytical, numericalFaceResidualWithAnalytical, optionalPerfectInterpolationFaceResiduals); + residualCalc.calcResidualsInstationary(timeLoop, gridGeometry, numericalCCResidualWithAnalytical, numericalFaceResidualWithAnalytical); bool readDofBasedValues = getParam<bool>("Problem.ReadDofBasedValues", false) && scalarCmp(getParam<Scalar>("Problem.TimeDofBasedValues"), actualCurrentTime); if (readDofBasedValues) @@ -355,3 +360,4 @@ catch (...) std::cerr << "Unknown exception thrown! ---> Abort!" << std::endl; return 4; } +#pragma GCC diagnostic pop diff --git a/appl/freeflow/navierstokes/angeli/params.input b/appl/freeflow/navierstokes/angeli/params.input index f2099f4..b0c3753 100644 --- a/appl/freeflow/navierstokes/angeli/params.input +++ b/appl/freeflow/navierstokes/angeli/params.input @@ -46,7 +46,10 @@ NumericDifference.BaseEpsilon = 1e-8 [Newton] MaxSteps = 20 +TargetSteps = 20 MaxRelativeShift = 1e-5 +ExitAfterFirstIteration = false +OutputMatrices = false [Vtk] WriteFaceData = false @@ -55,12 +58,14 @@ WriteFaceData = false DoFirstOrderLocalTruncError = false [Adaptivity] -Conservation = true +Conservation = false Adapt = true LeftX = .4 RightX = .6 LowerY = .4 UpperY = .6 +LinearInterpolation = false +DebugDof = -1 [VelocityReadIn] NumFileEntries = 260 diff --git a/appl/freeflow/navierstokes/angeli/problem.hh b/appl/freeflow/navierstokes/angeli/problem.hh index 77037c1..5f05e7c 100644 --- a/appl/freeflow/navierstokes/angeli/problem.hh +++ b/appl/freeflow/navierstokes/angeli/problem.hh @@ -21,13 +21,13 @@ * \ingroup NavierStokesTests * \brief Test for the instationary staggered grid Navier-Stokes model with analytical solution (Angeli et al., 2017) */ -#ifndef DUMUX_ANGELI_TEST_PROBLEM_HH -#define DUMUX_ANGELI_TEST_PROBLEM_HH +#ifndef DUMUX_CVD_ANGELI_TEST_PROBLEM_HH +#define DUMUX_CVD_ANGELI_TEST_PROBLEM_HH #include <dune/alugrid/grid.hh> #include <dune/grid/yaspgrid.hh> -#include <dumux/assembly/staggeredrefinedlocalresidual.hh> +#include <dumux/assembly/cvdstaggeredrefinedlocalresidual.hh> #include <dumux/common/numeqvector.hh> @@ -36,24 +36,28 @@ #include <dumux/freeflow/navierstokes/boundarytypes.hh> #include <dumux/freeflow/navierstokes/model.hh> -#include <dumux/freeflow/navierstokes/myproblem.hh> -#include <dumux/freeflow/navierstokes/mylocalresidual.hh> -#include <dumux/freeflow/navierstokes/myfluxvariables.hh> +#include <dumux/freeflow/navierstokes/cvdproblem.hh> +#include <dumux/freeflow/navierstokes/cvdlocalresidual.hh> +#include <dumux/freeflow/navierstokes/cvdfluxvariableswrapper.hh> #include <dumux/freeflow/navierstokes/myvolumevariables.hh> #include <dumux/freeflow/navierstokes/myiofields.hh> #include <dumux/discretization/method.hh> #include <dumux/discretization/staggered/myfacesolution.hh> -#include <dumux/discretization/staggered/mygridvariables.hh> -#include <dumux/discretization/staggered/myfvgridgeometry.hh> #include <dumux/discretization/staggered/mygridfluxvariablescache.hh> -#include <dumux/discretization/staggered/freeflow/fvgridgeometrytraits1.hh> #include <dumux/discretization/staggered/freeflow/properties.hh> #include <dumux/discretization/staggered/freeflow/myfacevariables.hh> +#include <dumux/discretization/staggered/freeflow/cvdlocalfacevariables.hh> #include <dumux/discretization/staggered/freeflow/elementvolumevariables1.hh> #include <dumux/discretization/staggered/freeflow/myvelocityoutput.hh> #include <dumux/discretization/staggered/freeflow/mygridvolumevariables.hh> +#include <dumux/discretization/staggered/cvdelementfacesolution.hh> +#include <dumux/discretization/staggered/cvdgridvariables.hh> +#include <dumux/discretization/staggered/cvdlocalgridfacevariables.hh> +#include <dumux/discretization/staggered/cvdfvgridgeometry.hh> +#include <dumux/discretization/staggered/freeflow/cvdfvgridgeometrytraits.hh> + namespace Dumux { template <class TypeTag> @@ -115,6 +119,15 @@ public: using type = MyStaggeredFaceVariables<ModelTraits, FacePrimaryVariables, GridView::dimension, upwindSchemeOrder>; }; +template<class TypeTag> +struct LocalFaceVariables<TypeTag, TTag::AngeliTestTypeTag> +{ +private: + using FacePrimaryVariables = GetPropType<TypeTag, Properties::FacePrimaryVariables>; +public: + using type = CVDStaggeredLocalFaceVariables<FacePrimaryVariables>; +}; + //! The velocity output template<class TypeTag> struct VelocityOutput<TypeTag, TTag::AngeliTestTypeTag> @@ -178,6 +191,28 @@ public: using type = Dumux::MyStaggeredFaceSolution<FaceSolutionVector>; }; + +template<class TypeTag> +struct ElementFaceSolution<TypeTag, TTag::AngeliTestTypeTag> +{ +private: + using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; +public: + using type = Dumux::CVDElementFaceSolution<FaceSolutionVector>; +}; + +//! Set the GridLocalFaceVariables +template<class TypeTag> +struct GridLocalFaceVariables<TypeTag, TTag::AngeliTestTypeTag> +{ + private: + using Problem = GetPropType<TypeTag, Properties::Problem>; + using LocalFaceVariables = GetPropType<TypeTag, Properties::LocalFaceVariables>; + static constexpr auto enableCache = getPropValue<TypeTag, Properties::EnableGridFaceVariablesCache>(); + public: + using type = CVDStaggeredLocalGridFaceVariables<Problem, LocalFaceVariables, enableCache>; +}; + //! Set the grid variables (volume, flux and face variables) template<class TypeTag> struct GridVariables<TypeTag, TTag::AngeliTestTypeTag> @@ -187,8 +222,9 @@ private: using GVV = GetPropType<TypeTag, Properties::GridVolumeVariables>; using GFVC = GetPropType<TypeTag, Properties::GridFluxVariablesCache>; using GFV = GetPropType<TypeTag, Properties::GridFaceVariables>; + using GLFV = GetPropType<TypeTag, Properties::GridLocalFaceVariables>; public: - using type = MyStaggeredGridVariables<GG, GVV, GFVC, GFV>; + using type = CVDStaggeredGridVariables<GG, GVV, GFVC, GFV, GLFV>; }; //! The default fv grid geometry @@ -199,9 +235,9 @@ private: static constexpr auto upwindSchemeOrder = getPropValue<TypeTag, Properties::UpwindSchemeOrder>(); static constexpr bool enableCache = getPropValue<TypeTag, Properties::EnableGridGeometryCache>(); using GridView = typename GetPropType<TypeTag, Properties::Grid>::LeafGridView; - using Traits = MyStaggeredFreeFlowDefaultGridGeometryTraits<GridView, upwindSchemeOrder>; + using Traits = CVDStaggeredFreeFlowDefaultGridGeometryTraits<GridView, upwindSchemeOrder>; public: - using type = MyStaggeredGridGeometry<GridView, enableCache, Traits>; + using type = CVDStaggeredGridGeometry<GridView, enableCache, Traits>; }; //! Set the volume variables property @@ -262,9 +298,9 @@ private: static constexpr auto upwindSchemeOrder = getPropValue<TypeTag, Properties::UpwindSchemeOrder>(); static constexpr bool enableCache = getPropValue<TypeTag, Properties::EnableGridGeometryCache>(); using GridView = typename Dune::ALUGrid<2,2,Dune::cube,Dune::nonconforming >::LeafGridView; - using Traits = MyStaggeredFreeFlowDefaultGridGeometryTraits<GridView, upwindSchemeOrder>; + using Traits = CVDStaggeredFreeFlowDefaultGridGeometryTraits<GridView, upwindSchemeOrder>; public: - using type = MyStaggeredGridGeometry<GridView, enableCache, Traits>; + using type = CVDStaggeredGridGeometry<GridView, enableCache, Traits>; }; } -- GitLab From c728ef3b032939dc289d45ef5fcbd24e87366052 Mon Sep 17 00:00:00 2001 From: Melanie Lipp <melanie.lipp@iws.uni-stuttgart.de> Date: Thu, 16 Sep 2021 18:07:40 +0200 Subject: [PATCH 42/69] [appl][angeli] Correct sign. This is a bug that was introduced by commit 32e0daac. With this fix I also finally retrieve the L2 errors that I gave to Caroline. --- appl/freeflow/navierstokes/angeli/problem.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appl/freeflow/navierstokes/angeli/problem.hh b/appl/freeflow/navierstokes/angeli/problem.hh index 5f05e7c..066486a 100644 --- a/appl/freeflow/navierstokes/angeli/problem.hh +++ b/appl/freeflow/navierstokes/angeli/problem.hh @@ -486,7 +486,7 @@ public: PrimaryVariables values = {}; - values[Indices::pressureIdx] = - 0.25 * f_(t) * f_(t) * M_PI * M_PI *rho_ * (4.0 * std::cos(2.0 * M_PI * x) - std::cos(4.0 * M_PI * y)); + values[Indices::pressureIdx] = - 0.25 * f_(t) * f_(t) * M_PI * M_PI *rho_ * (4.0 * std::cos(2.0 * M_PI * x) + std::cos(4.0 * M_PI * y)); values[Indices::velocityXIdx] = f_(t) * f2_(x)*df3_(y); values[Indices::velocityYIdx] = - f_(t) * df2_(x)* f3_(y); -- GitLab From ddd099c29e652f9b835c73431caf132f0493eee9 Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Sun, 19 Sep 2021 18:34:22 +0300 Subject: [PATCH 43/69] [1p_1p] adapted the test for ff-porous, compiles --- appl/CMakeLists.txt | 1 + .../navierstokes/sincos/params_vdP_full.input | 3 +- appl/multidomain/CMakeLists.txt | 1 + appl/multidomain/boundary/CMakeLists.txt | 1 + .../boundary/stokesdarcy/1p_1p/CMakeLists.txt | 1 + .../1p_1p/convergencetest/CMakeLists.txt | 25 + .../1p_1p/convergencetest/convergencetest.py | 132 ++++ .../stokesdarcy/1p_1p/convergencetest/main.cc | 445 ++++++++++++ .../convergencetest/manufactured_solution.py | 81 +++ .../1p_1p/convergencetest/params.input | 66 ++ .../paramsGloballyRefined.input | 65 ++ .../paramsLocallyRefined.input | 66 ++ .../1p_1p/convergencetest/paramsUniform.input | 66 ++ .../1p_1p/convergencetest/problem_darcy.hh | 402 +++++++++++ .../1p_1p/convergencetest/problem_stokes.hh | 663 ++++++++++++++++++ .../1p_1p/convergencetest/spatialparams.hh | 131 ++++ .../1p_1p/convergencetest/testcase.hh | 37 + .../boundary/stokesdarcy/CMakeLists.txt | 1 + .../cvdsubdomainstaggeredlocalassembler.hh | 10 + 19 files changed, 2196 insertions(+), 1 deletion(-) create mode 100644 appl/multidomain/CMakeLists.txt create mode 100644 appl/multidomain/boundary/CMakeLists.txt create mode 100644 appl/multidomain/boundary/stokesdarcy/1p_1p/CMakeLists.txt create mode 100644 appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/CMakeLists.txt create mode 100755 appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/convergencetest.py create mode 100644 appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/main.cc create mode 100644 appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/manufactured_solution.py create mode 100644 appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/params.input create mode 100644 appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/paramsGloballyRefined.input create mode 100644 appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/paramsLocallyRefined.input create mode 100644 appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/paramsUniform.input create mode 100644 appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/problem_darcy.hh create mode 100644 appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/problem_stokes.hh create mode 100644 appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/spatialparams.hh create mode 100644 appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/testcase.hh create mode 100644 appl/multidomain/boundary/stokesdarcy/CMakeLists.txt diff --git a/appl/CMakeLists.txt b/appl/CMakeLists.txt index 8bc9977..f5fe7bd 100644 --- a/appl/CMakeLists.txt +++ b/appl/CMakeLists.txt @@ -1 +1,2 @@ add_subdirectory(freeflow) +add_subdirectory(multidomain) \ No newline at end of file diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_full.input b/appl/freeflow/navierstokes/sincos/params_vdP_full.input index 88fa496..783e870 100644 --- a/appl/freeflow/navierstokes/sincos/params_vdP_full.input +++ b/appl/freeflow/navierstokes/sincos/params_vdP_full.input @@ -39,7 +39,8 @@ EnableInertiaTerms = true IsStationary = false VanDerPlasVersion = true StartWithAnalytical = false -AveragedAnalyticalSolution = false +AveragedAnalyticalSolution = true +UseScvfLineAveraging = true [Component] LiquidDensity = 1.0 diff --git a/appl/multidomain/CMakeLists.txt b/appl/multidomain/CMakeLists.txt new file mode 100644 index 0000000..f85a389 --- /dev/null +++ b/appl/multidomain/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(boundary) diff --git a/appl/multidomain/boundary/CMakeLists.txt b/appl/multidomain/boundary/CMakeLists.txt new file mode 100644 index 0000000..bbaa72a --- /dev/null +++ b/appl/multidomain/boundary/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(stokesdarcy) diff --git a/appl/multidomain/boundary/stokesdarcy/1p_1p/CMakeLists.txt b/appl/multidomain/boundary/stokesdarcy/1p_1p/CMakeLists.txt new file mode 100644 index 0000000..40c0225 --- /dev/null +++ b/appl/multidomain/boundary/stokesdarcy/1p_1p/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(convergencetest) \ No newline at end of file diff --git a/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/CMakeLists.txt b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/CMakeLists.txt new file mode 100644 index 0000000..cace090 --- /dev/null +++ b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/CMakeLists.txt @@ -0,0 +1,25 @@ +add_input_file_links() +dune_symlink_to_source_files(FILES "convergencetest.py") + +add_executable(test_md_boundary_darcy1p_freeflow1p_convtest EXCLUDE_FROM_ALL main.cc) + +dune_add_test(NAME test_md_boundary_darcy1p_stokes1p_convtest + TARGET test_md_boundary_darcy1p_freeflow1p_convtest + LABELS multidomain multidomain_boundary stokesdarcy + TIMEOUT 1000 + CMAKE_GUARD HAVE_UMFPACK + COMMAND ./convergencetest.py + CMD_ARGS test_md_boundary_darcy1p_freeflow1p_convtest params.input + -Problem.TestCase ShiueExampleTwo + -Darcy.SpatialParams.Permeability 1.0) + +dune_add_test(NAME test_md_boundary_darcy1p_navierstokes1p_convtest + TARGET test_md_boundary_darcy1p_freeflow1p_convtest + LABELS multidomain multidomain_boundary stokesdarcy + TIMEOUT 1000 + CMAKE_GUARD HAVE_UMFPACK + COMMAND ./convergencetest.py + CMD_ARGS test_md_boundary_darcy1p_freeflow1p_convtest params.input + -Problem.TestCase Schneider + -FreeFlow.Problem.EnableInertiaTerms true + -FreeFlow.EnableUnsymmetrizedVelocityGradientForBeaversJoseph true) diff --git a/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/convergencetest.py b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/convergencetest.py new file mode 100755 index 0000000..80b3fe1 --- /dev/null +++ b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/convergencetest.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python3 + +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) + +executableName = str(sys.argv[1]) +testargs = [str(i) for i in sys.argv][2:] +testname = testargs[testargs.index('-Problem.TestCase')+1] + +# remove the old log files +subprocess.call(['rm', testname + '_freeFlow.log']) +print("Removed old log file ({})!".format(testname + '_freeFlow.log')) +subprocess.call(['rm', testname + '_darcy.log']) +print("Removed old log file ({})!".format(testname + '_darcy.log')) + +# do the runs with different refinement +for i in [0, 1, 2]: + subprocess.call(['./' + executableName] + testargs + ['-Grid.Refinement', str(i)]) + +def checkRatesFreeFlow(): + # check the rates and append them to the log file + logfile = open(testname + '_freeFlow.log', "r+") + + errorP = [] + errorVx = [] + errorVy = [] + for line in logfile: + line = line.strip("\n") + line = line.strip("\[ConvergenceTest\]") + line = line.split() + errorP.append(float(line[2])) + errorVx.append(float(line[5])) + errorVy.append(float(line[8])) + + resultsP = [] + resultsVx = [] + resultsVy = [] + logfile.truncate(0) + logfile.write("n\terrorP\t\trateP\t\terrorVx\t\trateVx\t\terrorVy\t\trateVy\n") + logfile.write("-"*50 + "\n") + for i in range(len(errorP)-1): + if isnan(errorP[i]) or isinf(errorP[i]): + continue + if not ((errorP[i] < 1e-12 or errorP[i+1] < 1e-12) and (errorVx[i] < 1e-12 or errorVx[i+1] < 1e-12) and (errorVy[i] < 1e-12 or errorVy[i+1] < 1e-12)): + rateP = (log(errorP[i])-log(errorP[i+1]))/log(2) + rateVx = (log(errorVx[i])-log(errorVx[i+1]))/log(2) + rateVy = (log(errorVy[i])-log(errorVy[i+1]))/log(2) + message = "{}\t{:0.4e}\t{:0.4e}\t{:0.4e}\t{:0.4e}\t{:0.4e}\t{:0.4e}\n".format(i, errorP[i], rateP, errorVx[i], rateVx, errorVy[i], rateVy) + logfile.write(message) + resultsP.append(rateP) + resultsVx.append(rateVx) + resultsVy.append(rateVy) + else: + logfile.write("error: exact solution!?") + i = len(errorP)-1 + message = "{}\t{:0.4e}\t\t{}\t{:0.4e}\t\t{}\t{:0.4e}\t\t{}\n".format(i, errorP[i], "", errorVx[i], "", errorVy[i], "") + logfile.write(message) + + logfile.close() + print("\nComputed the following convergence rates for {}:\n".format(testname)) + + subprocess.call(['cat', testname + '_freeFlow.log']) + + return {"p" : resultsP, "v_x" : resultsVx, "v_y" : resultsVy} + +def checkRatesDarcy(): + # check the rates and append them to the log file + logfile = open(testname + '_darcy.log', "r+") + + errorP = [] + for line in logfile: + line = line.strip("\n") + line = line.strip("\[ConvergenceTest\]") + line = line.split() + errorP.append(float(line[2])) + + resultsP = [] + logfile.truncate(0) + logfile.write("n\terrorP\t\trateP\n") + logfile.write("-"*50 + "\n") + for i in range(len(errorP)-1): + if isnan(errorP[i]) or isinf(errorP[i]): + continue + if not ((errorP[i] < 1e-12 or errorP[i+1] < 1e-12)): + rateP = (log(errorP[i])-log(errorP[i+1]))/log(2) + message = "{}\t{:0.4e}\t{:0.4e}\n".format(i, errorP[i], rateP) + logfile.write(message) + resultsP.append(rateP) + else: + logfile.write("error: exact solution!?") + i = len(errorP)-1 + message = "{}\t{:0.4e}\n".format(i, errorP[i], "") + logfile.write(message) + + logfile.close() + print("\nComputed the following convergence rates for {}:\n".format(testname)) + + subprocess.call(['cat', testname + '_darcy.log']) + + return {"p" : resultsP} + +def checkRatesFreeFlowAndDarcy(): + resultsFreeFlow = checkRatesFreeFlow() + resultsDarcy = checkRatesDarcy() + + def mean(numbers): + return float(sum(numbers)) / len(numbers) + + # check the rates, we expect rates around 2 + if mean(resultsFreeFlow["p"]) < 2.05 and mean(resultsFreeFlow["p"]) < 1.84: + sys.stderr.write("*"*70 + "\n" + "The convergence rates for pressure were not close enough to 2! Test failed.\n" + "*"*70 + "\n") + sys.exit(1) + + if mean(resultsFreeFlow["v_x"]) < 2.05 and mean(resultsFreeFlow["v_x"]) < 1.95: + sys.stderr.write("*"*70 + "\n" + "The convergence rates for x-velocity were not close enough to 2! Test failed.\n" + "*"*70 + "\n") + sys.exit(1) + + if mean(resultsFreeFlow["v_y"]) < 2.05 and mean(resultsFreeFlow["v_y"]) < 1.95: + sys.stderr.write("*"*70 + "\n" + "The convergence rates for y-velocity were not close enough to 2! Test failed.\n" + "*"*70 + "\n") + sys.exit(1) + + if mean(resultsDarcy["p"]) < 2.05 and mean(resultsDarcy["p"]) < 1.95: + sys.stderr.write("*"*70 + "\n" + "The convergence rates for pressure were not close enough to 2! Test failed.\n" + "*"*70 + "\n") + sys.exit(1) + + +checkRatesFreeFlowAndDarcy() diff --git a/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/main.cc b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/main.cc new file mode 100644 index 0000000..ee54666 --- /dev/null +++ b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/main.cc @@ -0,0 +1,445 @@ +// -*- 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 3 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 + * \ingroup BoundaryTests + * \brief A test problem for the coupled FreeFlow/Darcy problem (1p). + */ + +bool doFirstOrderLocalTruncErrorGlobalRefinement = false; + +#include <config.h> + +#include <ctime> +#include <iostream> + +#include <dumux/assembly/cvdstaggeredrefinedfvassembler.hh> + +#include <dune/common/parallel/mpihelper.hh> +#include <dune/common/timer.hh> +#include <dune/grid/io/file/dgfparser/dgfwriter.hh> + +#include <dumux/common/properties.hh> +#include <dumux/common/parameters.hh> +#include <dumux/common/partial.hh> +#include <dumux/common/dumuxmessage.hh> +#include <dumux/linear/seqsolverbackend.hh> +#include <dumux/assembly/fvassembler.hh> +#include <dumux/assembly/diffmethod.hh> +#include <dumux/discretization/method.hh> +#include <dumux/io/vtkoutputmodule.hh> +#include <dumux/io/mystaggeredvtkoutputmodule.hh> +#include <dumux/io/grid/gridmanager.hh> + +#include <dumux/multidomain/staggeredtraits.hh> +#include <dumux/multidomain/cvdfvassembler.hh> +#include <dumux/multidomain/newtonsolver.hh> + +#include <dumux/adaptive/adapt.hh> +#include <dumux/adaptive/markelements.hh> +#include <dumux/freeflow/cvdgridadaptindicator.hh> +#include <dumux/freeflow/navierstokes/staggered/griddatatransfer.hh> +#include <dumux/freeflow/navierstokes/errors.hh> + +#include <dumux/multidomain/boundary/stokesdarcy/mycouplingmanager.hh> + +#include <dumux/discretization/staggered/cvdfvgridgeometry.hh> +#include <dumux/discretization/staggered/freeflow/cvdfvgridgeometrytraits.hh> + +#include "testcase.hh" +#include "problem_darcy.hh" +#include "problem_stokes.hh" + +namespace Dumux { +namespace Properties { + +template<class TypeTag> +struct CouplingManager<TypeTag, TTag::FreeFlowOneP> +{ + using Traits = StaggeredMultiDomainTraits<TypeTag, TypeTag, Properties::TTag::DarcyOneP>; + using type = Dumux::MyStokesDarcyCouplingManager<Traits>; +}; + +template<class TypeTag> +struct CouplingManager<TypeTag, TTag::DarcyOneP> +{ + using Traits = StaggeredMultiDomainTraits<Properties::TTag::FreeFlowOneP, Properties::TTag::FreeFlowOneP, TypeTag>; + using type = Dumux::MyStokesDarcyCouplingManager<Traits>; +}; + +} // end namespace Properties +} // end namespace Dumux + +/*! +* \brief Creates analytical solution. +* Returns a tuple of the analytical solution for the pressure, the velocity and the velocity at the faces +* \param problem the problem for which to evaluate the analytical solution +*/ +template<class Scalar, class Problem> +auto createFreeFlowAnalyticalSolution(const Problem& problem) +{ + const auto& gridGeometry = problem.gridGeometry(); + using GridView = typename std::decay_t<decltype(gridGeometry)>::GridView; + + static constexpr auto dim = GridView::dimension; + static constexpr auto dimWorld = GridView::dimensionworld; + + using VelocityVector = Dune::FieldVector<Scalar, dimWorld>; + + std::vector<Scalar> analyticalPressure; + std::vector<VelocityVector> analyticalVelocity; + std::vector<Scalar> analyticalVelocityOnFace; + + analyticalPressure.resize(gridGeometry.numCellCenterDofs()); + analyticalVelocity.resize(gridGeometry.numCellCenterDofs()); + analyticalVelocityOnFace.resize(gridGeometry.numFaceDofs()); + + using Indices = typename Problem::Indices; + for (const auto& element : elements(gridGeometry.gridView())) + { + auto fvGeometry = localView(gridGeometry); + fvGeometry.bindElement(element); + for (auto&& scv : scvs(fvGeometry)) + { + auto ccDofIdx = scv.dofIndex(); + auto ccDofPosition = scv.dofPosition(); + auto analyticalSolutionAtCc = problem.analyticalSolutionAtPos(ccDofPosition); + + // velocities on faces + for (auto&& scvf : scvfs(fvGeometry)) + { + const auto faceDofIdx = scvf.dofIndex(); + const auto faceDofPosition = scvf.center(); + const auto dirIdx = scvf.directionIndex(); + const auto analyticalSolutionAtFace = problem.analyticalSolutionAtPos(faceDofPosition); + analyticalVelocityOnFace[faceDofIdx] = analyticalSolutionAtFace[Indices::velocity(dirIdx)]; + } + + analyticalPressure[ccDofIdx] = analyticalSolutionAtCc[Indices::pressureIdx]; + + for (int dirIdx = 0; dirIdx < dim; ++dirIdx) + analyticalVelocity[ccDofIdx][dirIdx] = analyticalSolutionAtCc[Indices::velocity(dirIdx)]; + } + } + + return std::make_tuple(analyticalPressure, analyticalVelocity, analyticalVelocityOnFace); +} + +/*! +* \brief Creates analytical solution. +* Returns a tuple of the analytical solution for the pressure, the velocity and the velocity at the faces +* \param problem the problem for which to evaluate the analytical solution +*/ +template<class Scalar, class Problem> +auto createDarcyAnalyticalSolution(const Problem& problem) +{ + const auto& gridGeometry = problem.gridGeometry(); + using GridView = typename std::decay_t<decltype(gridGeometry)>::GridView; + + static constexpr auto dim = GridView::dimension; + static constexpr auto dimWorld = GridView::dimensionworld; + + using VelocityVector = Dune::FieldVector<Scalar, dimWorld>; + + std::vector<Scalar> analyticalPressure; + std::vector<VelocityVector> analyticalVelocity; + + analyticalPressure.resize(gridGeometry.numDofs()); + analyticalVelocity.resize(gridGeometry.numDofs()); + + for (const auto& element : elements(gridGeometry.gridView())) + { + auto fvGeometry = localView(gridGeometry); + fvGeometry.bindElement(element); + for (auto&& scv : scvs(fvGeometry)) + { + const auto ccDofIdx = scv.dofIndex(); + const auto ccDofPosition = scv.dofPosition(); + const auto analyticalSolutionAtCc = problem.analyticalSolution(ccDofPosition); + analyticalPressure[ccDofIdx] = analyticalSolutionAtCc[dim]; +/* + if (isinf(analyticalSolutionAtCc[dim])) + std::cout << "pressure " << std::endl;*/ + + for (int dirIdx = 0; dirIdx < dim; ++dirIdx) + { + analyticalVelocity[ccDofIdx][dirIdx] = analyticalSolutionAtCc[dirIdx]; + +// if (isinf (analyticalSolutionAtCc[dirIdx])) +// std::cout << "velocity " << std::endl; + } + } + } + + return std::make_tuple(analyticalPressure, analyticalVelocity); +} + +template<class Problem, class SolutionVector> +void printDarcyL2Error(const Problem& problem, const SolutionVector& x) +{ + using namespace Dumux; + using Scalar = double; + + Scalar l2error = 0.0; + + for (const auto& element : elements(problem.gridGeometry().gridView())) + { + auto fvGeometry = localView(problem.gridGeometry()); + fvGeometry.bindElement(element); + + for (auto&& scv : scvs(fvGeometry)) + { + const auto dofIdx = scv.dofIndex(); + const Scalar delta = x[dofIdx] - problem.analyticalSolution(scv.center())[2/*pressureIdx*/]; + l2error += scv.volume()*(delta*delta); + } + } + using std::sqrt; + l2error = sqrt(l2error); + + const auto numDofs = problem.gridGeometry().numDofs(); + std::ostream tmp(std::cout.rdbuf()); + tmp << std::setprecision(8) << "** L2 error (abs) for " + << std::setw(6) << numDofs << " cc dofs " + << std::scientific + << "L2 error = " << l2error + << std::endl; + + // write the norm into a log file + std::ofstream logFile; + logFile.open(problem.name() + ".log", std::ios::app); + logFile << "[ConvergenceTest] L2(p) = " << l2error << std::endl; + logFile.close(); +} + +int main(int argc, char** argv) +{ + using namespace Dumux; + + // 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); + + // Define the sub problem type tags + using FreeFlowTypeTag = Properties::TTag::FreeFlowOneP; + using DarcyTypeTag = Properties::TTag::DarcyOneP; + + using FreeFlowHelpingGridManager = Dumux::GridManager<GetPropType<FreeFlowTypeTag, Properties::HelpingGrid>>; + FreeFlowHelpingGridManager freeFlowHelpingGridManager; + freeFlowHelpingGridManager.init("FreeFlowHelper"); + const auto& freeFlowHelpingGridView = freeFlowHelpingGridManager.grid().leafGridView(); + Dune::DGFWriter dgfWriter(freeFlowHelpingGridView); + std::string inputFileName = getParam<std::string>("FreeFlow.Grid.File"); + dgfWriter.write(inputFileName); + + // try to create a grid (from the given grid file or the input file) + // for both sub-domains + using DarcyGridManager = Dumux::GridManager<GetPropType<DarcyTypeTag, Properties::Grid>>; + DarcyGridManager darcyGridManager; + darcyGridManager.init("Darcy"); + + using FreeFlowGridManager = Dumux::GridManager<GetPropType<FreeFlowTypeTag, Properties::Grid>>; + FreeFlowGridManager freeFlowGridManager; + freeFlowGridManager.init("FreeFlow"); + + // we compute on the leaf grid view + const auto& darcyGridView = darcyGridManager.grid().leafGridView(); + const auto& freeFlowGridView = freeFlowGridManager.grid().leafGridView(); + + // create the finite volume grid geometry + using FreeFlowGridGeometry = GetPropType<FreeFlowTypeTag, Properties::GridGeometry>; + auto freeFlowGridGeometry = std::make_shared<FreeFlowGridGeometry>(freeFlowGridView); + using DarcyGridGeometry = GetPropType<DarcyTypeTag, Properties::GridGeometry>; + auto darcyGridGeometry = std::make_shared<DarcyGridGeometry>(darcyGridView); + + using Traits = StaggeredMultiDomainTraits<FreeFlowTypeTag, FreeFlowTypeTag, DarcyTypeTag>; + + // the coupling manager + using CouplingManager = MyStokesDarcyCouplingManager<Traits>; + auto couplingManager = std::make_shared<CouplingManager>(freeFlowGridGeometry, darcyGridGeometry); + + // the indices + constexpr auto freeFlowCellCenterIdx = CouplingManager::stokesCellCenterIdx; + constexpr auto freeFlowFaceIdx = CouplingManager::stokesFaceIdx; + constexpr auto darcyIdx = CouplingManager::darcyIdx; + + // the problem (initial and boundary conditions) + const auto testCaseName = getParam<std::string>("Problem.TestCase"); + const auto testCase = [&testCaseName]() + { + if (testCaseName == "ShiueExampleOne") + return TestCase::ShiueExampleOne; + else if (testCaseName == "ShiueExampleTwo") + return TestCase::ShiueExampleTwo; + else if (testCaseName == "Rybak") + return TestCase::Rybak; + else if (testCaseName == "Schneider") + return TestCase::Schneider; + else + DUNE_THROW(Dune::InvalidStateException, testCaseName + " is not a valid test case"); + }(); + + using FreeFlowProblem = GetPropType<FreeFlowTypeTag, Properties::Problem>; + auto freeFlowProblem = std::make_shared<FreeFlowProblem>(freeFlowGridGeometry, couplingManager, testCase, testCaseName); + using DarcyProblem = GetPropType<DarcyTypeTag, Properties::Problem>; + auto spatialParams = std::make_shared<typename DarcyProblem::SpatialParams>(darcyGridGeometry, testCase); + auto darcyProblem = std::make_shared<DarcyProblem>(darcyGridGeometry, couplingManager, spatialParams, testCase, testCaseName); + + const auto freeFlowNumCellCenterDofs = freeFlowGridView.size(0); + const auto freeFlowNumFaceDofs = (*freeFlowGridGeometry).numIntersections(); + // the solution vector + Traits::SolutionVector sol; + sol[freeFlowCellCenterIdx].resize(freeFlowNumCellCenterDofs); + sol[freeFlowFaceIdx].resize(freeFlowNumFaceDofs); + sol[darcyIdx].resize(darcyGridGeometry->numDofs()); + + // get a solution vector storing references to the two FreeFlow solution vectors + auto freeFlowSol = partial(sol, freeFlowFaceIdx, freeFlowCellCenterIdx); + using FreeFlowSolutionVector = std::decay_t<decltype(freeFlowSol)>; + + couplingManager->init(freeFlowProblem, darcyProblem, sol); + + // the grid variables + using FreeFlowGridVariables = GetPropType<FreeFlowTypeTag, Properties::GridVariables>; + auto freeFlowGridVariables = std::make_shared<FreeFlowGridVariables>(freeFlowProblem, freeFlowGridGeometry); + freeFlowGridVariables->init(freeFlowSol); + using DarcyGridVariables = GetPropType<DarcyTypeTag, Properties::GridVariables>; + auto darcyGridVariables = std::make_shared<DarcyGridVariables>(darcyProblem, darcyGridGeometry); + darcyGridVariables->init(sol[darcyIdx]); + + // intialize the vtk output module + using Scalar = typename Traits::Scalar; + MyStaggeredVtkOutputModule<FreeFlowGridVariables, decltype(freeFlowSol)> freeFlowVtkWriter(*freeFlowGridVariables, freeFlowSol, freeFlowProblem->name()); + GetPropType<FreeFlowTypeTag, Properties::IOFields>::initOutputModule(freeFlowVtkWriter); + auto freeFlowAnalyticalSolution = createFreeFlowAnalyticalSolution<Scalar>(*freeFlowProblem); + freeFlowVtkWriter.addField(std::get<0>(freeFlowAnalyticalSolution), "pressureExact"); + freeFlowVtkWriter.addField(std::get<1>(freeFlowAnalyticalSolution), "velocityExact"); + freeFlowVtkWriter.addFaceField(std::get<2>(freeFlowAnalyticalSolution), "faceVelocityExact"); + freeFlowVtkWriter.write(0.0); + + VtkOutputModule<DarcyGridVariables, GetPropType<DarcyTypeTag, Properties::SolutionVector>> darcyVtkWriter(*darcyGridVariables, sol[darcyIdx], darcyProblem->name()); + using DarcyVelocityOutput = GetPropType<DarcyTypeTag, Properties::VelocityOutput>; + darcyVtkWriter.addVelocityOutput(std::make_shared<DarcyVelocityOutput>(*darcyGridVariables)); + GetPropType<DarcyTypeTag, Properties::IOFields>::initOutputModule(darcyVtkWriter); + auto darcyAnalyticalSolution = createDarcyAnalyticalSolution<Scalar>(*darcyProblem); + darcyVtkWriter.addField(std::get<0>(darcyAnalyticalSolution), "pressureExact"); + darcyVtkWriter.addField(std::get<1>(darcyAnalyticalSolution), "velocityExact"); + darcyVtkWriter.write(0.0); + + // the assembler for a stationary problem + using Assembler = RefinedMultiDomainFVAssembler<Traits, CouplingManager, DiffMethod::numeric>; + auto assembler = std::make_shared<Assembler>(std::make_tuple(freeFlowProblem, freeFlowProblem, darcyProblem), + std::make_tuple(freeFlowGridGeometry->faceGridGeometryPtr(), + freeFlowGridGeometry->cellCenterGridGeometryPtr(), + darcyGridGeometry), + std::make_tuple(freeFlowGridVariables->faceGridVariablesPtr(), + freeFlowGridVariables->cellCenterGridVariablesPtr(), + darcyGridVariables), + couplingManager); + + // the linear solver + using LinearSolver = UMFPackBackend; + auto linearSolver = std::make_shared<LinearSolver>(); + + // the non-linear solver + using NewtonSolver = MultiDomainNewtonSolver<Assembler, LinearSolver, CouplingManager>; + NewtonSolver nonLinearSolver(assembler, linearSolver, couplingManager); + + printDarcyL2Error(*darcyProblem, sol[darcyIdx]); + + const Scalar refineTol = getParam<Scalar>("Adaptive.RefineTolerance"); + const Scalar coarsenTol = getParam<Scalar>("Adaptive.CoarsenTolerance"); + MyFreeflowGridAdaptIndicator<FreeFlowTypeTag> indicator(freeFlowProblem); + const unsigned int numRefinementSteps = getParam<Scalar>("Adaptive.MaxLevel"); + + FreeFlowGridDataTransfer<FreeFlowTypeTag, FreeFlowSolutionVector> freeflowDataTransfer(freeFlowProblem, freeFlowGridGeometry, freeFlowGridVariables, freeFlowSol); + + NavierStokesRefinedErrors freeFlowErrors(freeFlowProblem, freeFlowSol, 0); + NavierStokesRefinedErrorCSVWriter freeFlowErrorCSVWriter(freeFlowProblem); + + for (unsigned int i=0; i < numRefinementSteps; ++i) + { + if (i>0) + { + // compute refinement indicator + indicator.calculateVelocityError(freeFlowSol, std::get<1>(freeFlowAnalyticalSolution), refineTol, coarsenTol); + + // mark elements and maybe adapt grid + bool wasAdapted = false; + if (markElements(freeFlowGridManager.grid(), indicator)) + wasAdapted = adapt(freeFlowGridManager.grid(), freeflowDataTransfer); + + if (wasAdapted) + { + darcyGridManager.grid().globalRefine(1); + + freeFlowGridGeometry->update(freeFlowGridView); + darcyGridGeometry->update(darcyGridView); + + freeFlowSol[FreeFlowGridGeometry::cellCenterIdx()] = 0.; + freeFlowSol[FreeFlowGridGeometry::cellCenterIdx()].resize(freeFlowGridView.size(0)); + freeFlowSol[FreeFlowGridGeometry::faceIdx()] = 0.; + freeFlowSol[FreeFlowGridGeometry::faceIdx()].resize((*freeFlowGridGeometry).numIntersections()); + sol[darcyIdx]= 0.; + sol[darcyIdx].resize(darcyGridGeometry->numDofs()); + + freeFlowGridVariables->updateAfterGridAdaption(freeFlowSol); //!< Initialize the secondary variables to the new (and "new old") solution + darcyGridVariables->updateAfterGridAdaption(sol[darcyIdx]); + + couplingManager->update(sol); + + assembler->reSetJacobianSize(); // has to be after nonlinear solver + assembler->reSetJacobianPattern(); //!< Tell the assembler to resize the matrix and set pattern + assembler->reSetResidualSize(); //!< Tell the assembler to resize the residual + } + } + + nonLinearSolver.solve(sol); + + // write vtk output + freeFlowAnalyticalSolution = createFreeFlowAnalyticalSolution<Scalar>(*freeFlowProblem); + darcyAnalyticalSolution = createDarcyAnalyticalSolution<Scalar>(*darcyProblem); + freeFlowVtkWriter.write(i+1.0); + darcyVtkWriter.write(i+1.0); + + freeFlowErrors.update(freeFlowSol, i); + freeFlowErrorCSVWriter.printErrors(freeFlowErrors); + + printDarcyL2Error(*darcyProblem, sol[darcyIdx]); + } + + //////////////////////////////////////////////////////////// + // 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 diff --git a/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/manufactured_solution.py b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/manufactured_solution.py new file mode 100644 index 0000000..b783c5c --- /dev/null +++ b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/manufactured_solution.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python3 + +""" +This script determines the source terms needed for analytical solutions for coupled Stokes/Darcy problems. +Given an analytical solution, it evaluates the momentum and mass balance equations and outputs source terms +such that the balance equations are fulfilled. It furthermore calculates the Darcy velocity from a given pressure solution. +""" + +import sympy as sp +import numpy as np +from sympy import * + +# case = "Rybak" +# case = "Shiue_1" +case = "Shiue_2" + +# divergence of a matrix +def div(M): + return np.array([sp.diff(M[0,0],x) + sp.diff(M[0,1],y) , sp.diff(M[1,0],x) + sp.diff(M[1,1],y) ]) + +# gradient of a vector +def grad(v): + return np.array([[sp.diff(v[0],x), sp.diff(v[0],y)], [sp.diff(v[1],x), sp.diff(v[1],y)]]) + +# coordinates +x, y = sp.symbols("x y") + +# analytical solutions for v and p in free-flow domain (see reference given in problems) +def analyticalSolutionStokes(case): + if case == "Rybak": + vFF = np.array([-sp.cos(sp.pi*x)*sp.sin(sp.pi*y), sp.sin(sp.pi*x)*sp.cos(sp.pi*y)]) + pFF = 0.5*y*sp.sin(sp.pi*x) + elif case == "Shiue_1": + vFF = np.array([-1.0/sp.pi * sp.exp(y) * sp.sin(sp.pi*x), (sp.exp(y) - sp.exp(1)) * sp.cos(sp.pi*x)]) + pFF = 2.0*sp.exp(y) * sp.cos(sp.pi*x) + else: # Shiue_2 + vFF = np.array([(y-1.0)*(y-1.0) + x*(y-1.0) + 3.0*x - 1.0, x*(x-1.0) - 0.5*(y-1.0)*(y-1.0) - 3.0*y + 1.0]) + pFF = 2.0*x + y - 1.0 + return [vFF, pFF] + +vFF, pFF = analyticalSolutionStokes(case) + +# individual terms of the Navier-Stokes eq. +vvT = np.outer(vFF, vFF) +gradV = grad(vFF) +gradVT = grad(vFF).T +pI = np.array([[pFF, 0], [0, pFF]]) + +# complete momentum flux and its divergence +#momentumFlux = vvT - (gradV + gradVT) +pI +momentumFlux = - (gradV + gradVT) +pI # only Stokes +divMomentumFlux = div(momentumFlux) + +print("Source terms for case", case) + +# solution for source term +print(" \nStokes:") +print("Source term mass:", sp.diff(vFF[0],x) + sp.diff(vFF[1], y)) +print("Source term momentum x:", divMomentumFlux[0]) +print("Source term momentum y:", divMomentumFlux[1]) + +# analytical solutions for p in Darcy domain (see reference given in problems) +def analyticalSolutionDarcy(case): + if case == "Rybak": + pD = 0.5*y*y*sp.sin(sp.pi*x) + elif case == "Shiue_1": + pD = (sp.exp(y) - y*sp.exp(1)) * sp.cos(sp.pi*x) + else: # Shiue_2 + pD = x*(1.0-x)*(y-1.0) + pow(y-1.0, 3)/3.0 + 2.0*x + 2.0*y + 4.0 + return pD + +pD = analyticalSolutionDarcy(case) + +gradPdK = np.array([sp.diff(pD,x), sp.diff(pD,y)]) +vD = -gradPdK +divVd = sp.diff(vD[0],x) + sp.diff(vD[1],y) + +print("\nDarcy:") +print("Source term mass:", simplify(divVd)) +print("v x:", simplify(vD[0])) +print("v_y", simplify(vD[1])) diff --git a/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/params.input b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/params.input new file mode 100644 index 0000000..59cf609 --- /dev/null +++ b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/params.input @@ -0,0 +1,66 @@ +[Darcy.Grid] +Positions0 = 0 1 +Positions1 = 0 1 +Cells0 = 10 +Cells1 = 10 +Grading0 = 1. +Grading1 = 1. + +[FreeFlowHelper.Grid] +Positions0 = 0 1 +Positions1 = 1 2 +Cells0 = 10 +Cells1 = 12 +Grading0 = 1.0 +Grading1 = 1.0 + +[FreeFlow.Grid] +File = grid.dgf + +[FreeFlow.Problem] +Name = freeFlow +EnableInertiaTerms = true + +[Darcy.Problem] +Name = darcy + +[Darcy.SpatialParams] +AlphaBeaversJoseph = 1.0 + +[Problem] +EnableGravity = false + +[Vtk] +AddVelocity = 1 + +[Component] +LiquidDensity = 1.0 +LiquidKinematicViscosity = 1.0 +MolarMass = 1.0 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-4 + +[FreeFlow.Flux] +UpwindWeight = 0.5 + +[FreeFlow] +EnableUnsymmetrizedVelocityGradientForBeaversJoseph = true + +[Adaptivity] +Conservation = true + +[Adaptive] +HigherOrderInterpolation = false +RefineAtDirichletBC = 0 +RefineAtFluxBC = 1 +MinLevel = 0 +MaxLevel = 2 +CoarsenTolerance = 0 +RefineTolerance = 1e-6 + +[ Newton ] +MaxSteps = 100 + +[Problem] +TestCase = Schneider diff --git a/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/paramsGloballyRefined.input b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/paramsGloballyRefined.input new file mode 100644 index 0000000..75ed820 --- /dev/null +++ b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/paramsGloballyRefined.input @@ -0,0 +1,65 @@ +[Darcy.Grid] +Positions0 = 0 1 +Positions1 = 0 1 +Cells0 = 10 +Cells1 = 10 +Grading0 = 1. +Grading1 = 1. + +[FreeFlowHelper.Grid] +Positions0 = 0 1 +Positions1 = 1 2 +Cells0 = 10 +Cells1 = 12 +Grading0 = 1.0 +Grading1 = 1.05 +[FreeFlow.Grid] +File = grid.dgf + +[FreeFlow.Problem] +Name = freeFlow +EnableInertiaTerms = true + +[Darcy.Problem] +Name = darcy + +[Darcy.SpatialParams] +AlphaBeaversJoseph = 1.0 + +[Problem] +EnableGravity = false + +[Vtk] +AddVelocity = 1 + +[Component] +LiquidDensity = 1.0 +LiquidKinematicViscosity = 1.0 +MolarMass = 1.0 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-4 + +[FreeFlow.Flux] +UpwindWeight = 0.5 + +[FreeFlow] +EnableUnsymmetrizedVelocityGradientForBeaversJoseph = true + +[Adaptivity] +Conservation = true + +[Adaptive] +HigherOrderInterpolation = false +RefineAtDirichletBC = 0 +RefineAtFluxBC = 1 +MinLevel = 0 +MaxLevel = 1 +CoarsenTolerance = 0 +RefineTolerance = 1e-6 + +[ Newton ] +MaxSteps = 100 + +[Problem] +TestCase = Schneider diff --git a/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/paramsLocallyRefined.input b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/paramsLocallyRefined.input new file mode 100644 index 0000000..3bfc8ee --- /dev/null +++ b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/paramsLocallyRefined.input @@ -0,0 +1,66 @@ +[Darcy.Grid] +Positions0 = 0 1 +Positions1 = 0 1 +Cells0 = 10 +Cells1 = 10 +Grading0 = 1. +Grading1 = 1. + +[FreeFlowHelper.Grid] +Positions0 = 0 1 +Positions1 = 1 1.159 2 +Cells0 = 10 +Cells1 = 1 8 +Grading0 = 1.0 +Grading1 = 1.0 1.05 + +[FreeFlow.Grid] +File = grid.dgf + +[FreeFlow.Problem] +Name = freeFlow +EnableInertiaTerms = true + +[Darcy.Problem] +Name = darcy + +[Darcy.SpatialParams] +AlphaBeaversJoseph = 1.0 + +[Problem] +EnableGravity = false + +[Vtk] +AddVelocity = 1 + +[Component] +LiquidDensity = 1.0 +LiquidKinematicViscosity = 1.0 +MolarMass = 1.0 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-4 + +[FreeFlow.Flux] +UpwindWeight = 0.5 + +[FreeFlow] +EnableUnsymmetrizedVelocityGradientForBeaversJoseph = true + +[Adaptivity] +Conservation = true + +[Adaptive] +HigherOrderInterpolation = false +RefineAtDirichletBC = 0 +RefineAtFluxBC = 1 +MinLevel = 0 +MaxLevel = 2 +CoarsenTolerance = 0 +RefineTolerance = 1e-6 + +[ Newton ] +MaxSteps = 100 + +[Problem] +TestCase = Schneider diff --git a/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/paramsUniform.input b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/paramsUniform.input new file mode 100644 index 0000000..168b6d8 --- /dev/null +++ b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/paramsUniform.input @@ -0,0 +1,66 @@ +[Darcy.Grid] +Positions0 = 0 1 +Positions1 = 0 1 +Cells0 = 10 +Cells1 = 10 +Grading0 = 1. +Grading1 = 1. + +[FreeFlowHelper.Grid] +Positions0 = 0 1 +Positions1 = 1 2 +Cells0 = 10 +Cells1 = 12 +Grading0 = 1.0 +Grading1 = 1.0 + +[FreeFlow.Grid] +File = grid.dgf + +[FreeFlow.Problem] +Name = freeFlow +EnableInertiaTerms = true + +[Darcy.Problem] +Name = darcy + +[Darcy.SpatialParams] +AlphaBeaversJoseph = 1.0 + +[Problem] +EnableGravity = false + +[Vtk] +AddVelocity = 1 + +[Component] +LiquidDensity = 1.0 +LiquidKinematicViscosity = 1.0 +MolarMass = 1.0 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-4 + +[FreeFlow.Flux] +UpwindWeight = 0.5 + +[FreeFlow] +EnableUnsymmetrizedVelocityGradientForBeaversJoseph = true + +[Adaptivity] +Conservation = true + +[Adaptive] +HigherOrderInterpolation = false +RefineAtDirichletBC = 0 +RefineAtFluxBC = 1 +MinLevel = 0 +MaxLevel = 1 +CoarsenTolerance = 0 +RefineTolerance = 1e-6 + +[ Newton ] +MaxSteps = 100 + +[Problem] +TestCase = Schneider diff --git a/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/problem_darcy.hh b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/problem_darcy.hh new file mode 100644 index 0000000..2d9c1d5 --- /dev/null +++ b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/problem_darcy.hh @@ -0,0 +1,402 @@ +// -*- 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 3 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 + * \ingroup BoundaryTests + * \brief The Darcy sub-problem of coupled Stokes-Darcy convergence test + */ + +#ifndef DUMUX_DARCY_SUBPROBLEM_HH +#define DUMUX_DARCY_SUBPROBLEM_HH + +#include <dune/common/fvector.hh> +#include <dumux/common/numeqvector.hh> + +#include <dune/grid/yaspgrid.hh> + +#include <dumux/discretization/cctpfa.hh> + +#include <dumux/common/boundarytypes.hh> + +#include <dumux/material/components/constant.hh> +#include <dumux/material/fluidsystems/1pliquid.hh> + +#include <dumux/porousmediumflow/1p/model.hh> +#include <dumux/porousmediumflow/problem.hh> + +#include "spatialparams.hh" +#include "testcase.hh" + +namespace Dumux { +template <class TypeTag> +class DarcySubProblem; + +namespace Properties { +// Create new type tags +namespace TTag { +struct DarcyOneP { using InheritsFrom = std::tuple<OneP, CCTpfaModel>; }; +} // end namespace TTag + +// Set the problem property +template<class TypeTag> +struct Problem<TypeTag, TTag::DarcyOneP> { using type = Dumux::DarcySubProblem<TypeTag>; }; + +// the fluid system +template<class TypeTag> +struct FluidSystem<TypeTag, TTag::DarcyOneP> +{ + using Scalar = GetPropType<TypeTag, Properties::Scalar>; + using type = FluidSystems::OnePLiquid<Scalar, Dumux::Components::Constant<1, Scalar> > ; +}; + +// Set the grid type +template<class TypeTag> +struct Grid<TypeTag, TTag::DarcyOneP> +{ + using type = Dune::YaspGrid<2,Dune::TensorProductCoordinates<double, 2>>; +}; + +template<class TypeTag> +struct SpatialParams<TypeTag, TTag::DarcyOneP> +{ + using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; + using Scalar = GetPropType<TypeTag, Properties::Scalar>; + using type = ConvergenceTestSpatialParams<GridGeometry, Scalar>; +}; +} // end namespace Properties + +/*! + * \ingroup BoundaryTests + * \brief The Darcy sub-problem of coupled Stokes-Darcy convergence test + */ +template <class TypeTag> +class DarcySubProblem : public PorousMediumFlowProblem<TypeTag> +{ + using ParentType = PorousMediumFlowProblem<TypeTag>; + using GridView = typename GetPropType<TypeTag, Properties::GridGeometry>::GridView; + using Scalar = GetPropType<TypeTag, Properties::Scalar>; + using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>; + using NumEqVector = Dumux::NumEqVector<GetPropType<TypeTag, Properties::PrimaryVariables>>; + using BoundaryTypes = Dumux::BoundaryTypes<GetPropType<TypeTag, Properties::ModelTraits>::numEq()>; + using VolumeVariables = GetPropType<TypeTag, Properties::VolumeVariables>; + using FVElementGeometry = typename GetPropType<TypeTag, Properties::GridGeometry>::LocalView; + using SubControlVolume = typename FVElementGeometry::SubControlVolume; + using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace; + using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; + using Element = typename GridView::template Codim<0>::Entity; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + + using CouplingManager = GetPropType<TypeTag, Properties::CouplingManager>; + + static constexpr auto velocityXIdx = 0; + static constexpr auto velocityYIdx = 1; + static constexpr auto pressureIdx = 2; + +public: + //! export the Indices + using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; + + DarcySubProblem(std::shared_ptr<const GridGeometry> gridGeometry, + std::shared_ptr<CouplingManager> couplingManager, + std::shared_ptr<typename ParentType::SpatialParams> spatialParams, + const TestCase testCase, + const std::string& name) + : ParentType(gridGeometry, spatialParams, "Darcy") + , couplingManager_(couplingManager) + , testCase_(testCase) + { + problemName_ = name + "_" + getParamFromGroup<std::string>(this->paramGroup(), "Problem.Name"); + } + + /*! + * \brief The problem name. + */ + const std::string& name() const + { + return problemName_; + } + + /*! + * \name Problem parameters + */ + // \{ + + /*! + * \brief Returns the temperature within the domain in [K]. + * + */ + Scalar temperature() const + { return 273.15 + 10; } // 10°C + // \} + + /*! + * \name Boundary conditions + */ + // \{ + + /*! + * \brief Specifies which kind of boundary condition should be + * used for which equation on a given boundary control volume. + * + * \param element The element + * \param scvf The boundary sub control volume face + */ + BoundaryTypes boundaryTypes(const Element &element, const SubControlVolumeFace &scvf) const + { + BoundaryTypes values; + + if (couplingManager().isCoupledEntity(CouplingManager::darcyIdx, scvf)) + values.setAllCouplingNeumann(); + else + values.setAllDirichlet(); + + return values; + } + + /*! + * \brief Evaluates the boundary conditions for a Dirichlet control volume. + * + * \param element The element for which the Dirichlet boundary condition is set + * \param scvf The boundary subcontrolvolumeface + * + * For this method, the \a values parameter stores primary variables. + */ + PrimaryVariables dirichlet(const Element &element, const SubControlVolumeFace &scvf) const + { + const auto p = analyticalSolution(scvf.center())[pressureIdx]; + return PrimaryVariables(p); + } + + /*! + * \brief Evaluates the boundary conditions for a Neumann control volume. + * + * \param element The element for which the Neumann boundary condition is set + * \param fvGeometry The fvGeometry + * \param elemVolVars The element volume variables + * \param elemFluxVarsCache Flux variables caches for all faces in stencil + * \param scvf The boundary sub control volume face + * + * For this method, the \a values variable stores primary variables. + */ + template<class ElementVolumeVariables, class ElementFluxVarsCache> + NumEqVector neumann(const Element& element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars, + const ElementFluxVarsCache& elemFluxVarsCache, + const SubControlVolumeFace& scvf) const + { + NumEqVector values(0.0); + + if (couplingManager().isCoupledEntity(CouplingManager::darcyIdx, scvf)) + values[Indices::conti0EqIdx] = couplingManager().couplingData().massCouplingCondition(element, fvGeometry, elemVolVars, scvf); + + return values; + } + + // \} + + /*! + * \name Volume terms + */ + // \{ + /*! + * \brief Evaluates the source term for all phases within a given + * sub control volume. + * + * \param globalPos The global position + */ + NumEqVector sourceAtPos(const GlobalPosition& globalPos) const + { + switch (testCase_) + { + case TestCase::ShiueExampleOne: + return rhsShiueEtAlExampleOne_(globalPos); + case TestCase::ShiueExampleTwo: + return rhsShiueEtAlExampleTwo_(globalPos); + case TestCase::Rybak: + return rhsRybak_(globalPos); + case TestCase::Schneider: + return rhsSchneiderEtAl_(globalPos); + default: + DUNE_THROW(Dune::InvalidStateException, "Invalid test case"); + } + } + + // \} + + /*! + * \brief Evaluates the initial value for a control volume. + * + * \param element The element + * + * For this method, the \a priVars parameter stores primary + * variables. + */ + PrimaryVariables initial(const Element &element) const + { + return PrimaryVariables(0.0); + } + + /*! + * \brief Returns the analytical solution of the problem at a given position. + * + * \param globalPos The global position + */ + auto analyticalSolution(const GlobalPosition& globalPos) const + { + switch (testCase_) + { + case TestCase::ShiueExampleOne: + return analyticalSolutionShiueEtAlExampleOne_(globalPos); + case TestCase::ShiueExampleTwo: + return analyticalSolutionShiueEtAlExampleTwo_(globalPos); + case TestCase::Rybak: + return analyticalSolutionRybak_(globalPos); + case TestCase::Schneider: + return analyticalSolutionSchneiderEtAl_(globalPos); + default: + DUNE_THROW(Dune::InvalidStateException, "Invalid test case"); + } + } + + // \} + + //! Get the coupling manager + const CouplingManager& couplingManager() const + { return *couplingManager_; } + +private: + + // see Rybak et al., 2015: "Multirate time integration for coupled saturated/unsaturated porous medium and free flow systems" + Dune::FieldVector<Scalar, 3> analyticalSolutionRybak_(const GlobalPosition& globalPos) const + { + Dune::FieldVector<Scalar, 3> sol(0.0); + const Scalar x = globalPos[0]; + const Scalar y = globalPos[1]; + + using std::exp; using std::sin; using std::cos; + sol[velocityXIdx] = -0.5*M_PI*y*y*cos(M_PI*x); + sol[velocityYIdx] = -1.0*y*sin(M_PI*x); + sol[pressureIdx] = 0.5*y*y*sin(M_PI*x); + return sol; + } + + // see Rybak et al., 2015: "Multirate time integration for coupled saturated/unsaturated porous medium and free flow systems" + NumEqVector rhsRybak_(const GlobalPosition& globalPos) const + { + const Scalar x = globalPos[0]; + const Scalar y = globalPos[1]; + using std::sin; + return NumEqVector((0.5*M_PI*y*M_PI*y - 1)*sin(M_PI*x)); + } + + // see Shiue et al., 2018: "Convergence of the MAC Scheme for the Stokes/Darcy Coupling Problem" + Dune::FieldVector<Scalar, 3> analyticalSolutionShiueEtAlExampleOne_(const GlobalPosition& globalPos) const + { + Dune::FieldVector<Scalar, 3> sol(0.0); + const Scalar x = globalPos[0]; + const Scalar y = globalPos[1]; + + using std::exp; using std::sin; using std::cos; + sol[pressureIdx] = (exp(y) - y*exp(1)) * cos(M_PI*x); + sol[velocityXIdx] = M_PI*(-exp(1)*y + exp(y))*sin(M_PI*x); + sol[velocityYIdx] = (exp(1) - exp(y))*cos(M_PI*x); + + return sol; + } + + // see Shiue et al., 2018: "Convergence of the MAC Scheme for the Stokes/Darcy Coupling Problem" + NumEqVector rhsShiueEtAlExampleOne_(const GlobalPosition& globalPos) const + { + const Scalar x = globalPos[0]; + const Scalar y = globalPos[1]; + using std::exp; using std::sin; using std::cos; + return NumEqVector(cos(M_PI*x) * (M_PI*M_PI*(exp(y) - y*exp(1)) - exp(y))); + } + + // see Shiue et al., 2018: "Convergence of the MAC Scheme for the Stokes/Darcy Coupling Problem" + Dune::FieldVector<Scalar, 3> analyticalSolutionShiueEtAlExampleTwo_(const GlobalPosition& globalPos) const + { + Dune::FieldVector<Scalar, 3> sol(0.0); + const Scalar x = globalPos[0]; + const Scalar y = globalPos[1]; + + sol[pressureIdx] = x*(1.0-x)*(y-1.0) + (y-1.0)*(y-1.0)*(y-1.0)/3.0 + 2.0*x + 2.0*y + 4.0; + sol[velocityXIdx] = x*(y - 1.0) + (x - 1.0)*(y - 1.0) - 2.0; + sol[velocityYIdx] = x*(x - 1.0) - 1.0*(y - 1.0)*(y - 1.0) - 2.0; + + return sol; + } + + // see Shiue et al., 2018: "Convergence of the MAC Scheme for the Stokes/Darcy Coupling Problem" + NumEqVector rhsShiueEtAlExampleTwo_(const GlobalPosition& globalPos) const + { return NumEqVector(0.0); } + + // see Schneider et al., 2019: "Coupling staggered-grid and MPFA finite volume methods for + // free flow/porous-medium flow problems" + Dune::FieldVector<Scalar, 3> analyticalSolutionSchneiderEtAl_(const GlobalPosition& globalPos) const + { + Dune::FieldVector<Scalar, 3> sol(0.0); + const Scalar x = globalPos[0]; + const Scalar y = globalPos[1]; + static constexpr Scalar omega = M_PI; + static constexpr Scalar c = 0.0; + using std::exp; using std::sin; using std::cos; + const Scalar sinOmegaX = sin(omega*x); + const Scalar cosOmegaX = cos(omega*x); + static const Scalar expTwo = exp(2); + const Scalar expYPlusOne = exp(y+1); + + sol[pressureIdx] = (expYPlusOne + 2 - expTwo)*sinOmegaX; + sol[velocityXIdx] = c/(2*omega)*expYPlusOne*sinOmegaX*sinOmegaX + -omega*(expYPlusOne + 2 - expTwo)*cosOmegaX; + sol[velocityYIdx] = (0.5*c*(expYPlusOne + 2 - expTwo)*cosOmegaX + -(c*cosOmegaX + 1)*exp(y-1))*sinOmegaX; + + return sol; + } + + // see Schneider et al., 2019: "Coupling staggered-grid and MPFA finite volume methods for + // free flow/porous-medium flow problems (with c = 0)" + NumEqVector rhsSchneiderEtAl_(const GlobalPosition& globalPos) const + { + const Scalar x = globalPos[0]; + const Scalar y = globalPos[1]; + using std::exp; using std::sin; using std::cos; + static constexpr Scalar omega = M_PI; + static constexpr Scalar c = 0.0; + const Scalar cosOmegaX = cos(omega*x); + static const Scalar expTwo = exp(2); + const Scalar expYPlusOne = exp(y+1); + + const Scalar result = (-(c*cosOmegaX + 1)*exp(y - 1) + + 1.5*c*expYPlusOne*cosOmegaX + + omega*omega*(expYPlusOne - expTwo + 2)) + *sin(omega*x); + return NumEqVector(result); + } + + static constexpr Scalar eps_ = 1e-7; + std::shared_ptr<CouplingManager> couplingManager_; + std::string problemName_; + TestCase testCase_; +}; +} // end namespace Dumux + +#endif diff --git a/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/problem_stokes.hh b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/problem_stokes.hh new file mode 100644 index 0000000..7f18fb8 --- /dev/null +++ b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/problem_stokes.hh @@ -0,0 +1,663 @@ +// -*- 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 3 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 + * \ingroup BoundaryTests + * \brief The free-flow sub-problem of coupled FreeFlow/Darcy convergence test + */ + +#ifndef DUMUX_FREEFLOW_SUBPROBLEM_HH +#define DUMUX_FREEFLOW_SUBPROBLEM_HH + +#include <dune/common/fvector.hh> +#include <dumux/common/numeqvector.hh> + +#include <dune/alugrid/grid.hh> +#include <dune/grid/yaspgrid.hh> + +#include <dumux/discretization/staggered/freeflow/properties.hh> + +#include <dumux/freeflow/navierstokes/boundarytypes.hh> +#include <dumux/freeflow/navierstokes/model.hh> + +#include <dumux/material/fluidsystems/1pliquid.hh> +#include <dumux/material/components/constant.hh> + +#include <dumux/assembly/cvdstaggeredrefinedlocalresidual.hh> +#include <dumux/discretization/staggered/mygridfluxvariablescache.hh> +#include <dumux/discretization/staggered/freeflow/myfacevariables.hh> +#include <dumux/discretization/staggered/freeflow/cvdlocalfacevariables.hh> +#include <dumux/discretization/staggered/freeflow/myvelocityoutput.hh> +#include <dumux/discretization/staggered/freeflow/mygridvolumevariables.hh> +#include <dumux/discretization/staggered/freeflow/elementvolumevariables1.hh> +#include <dumux/discretization/staggered/myfacesolution.hh> +#include <dumux/freeflow/navierstokes/cvdproblem.hh> +#include <dumux/freeflow/navierstokes/cvdlocalresidual.hh> +#include <dumux/freeflow/navierstokes/cvdfluxvariableswrapper.hh> +#include <dumux/freeflow/navierstokes/myvolumevariables.hh> +#include <dumux/freeflow/navierstokes/myiofields.hh> + +#include <dumux/discretization/staggered/cvdelementfacesolution.hh> +#include <dumux/discretization/staggered/cvdgridvariables.hh> +#include <dumux/discretization/staggered/cvdlocalgridfacevariables.hh> +#include <dumux/discretization/staggered/cvdfvgridgeometry.hh> +#include <dumux/discretization/staggered/freeflow/cvdfvgridgeometrytraits.hh> + +#include "testcase.hh" + +namespace Dumux { +template <class TypeTag> +class FreeFlowSubProblem; + +namespace Properties { +// Create new type tags +namespace TTag { +struct FreeFlowOneP { using InheritsFrom = std::tuple<NavierStokes, StaggeredFreeFlowModel>; }; +} // end namespace TTag + +// the fluid system +template<class TypeTag> +struct FluidSystem<TypeTag, TTag::FreeFlowOneP> +{ + using Scalar = GetPropType<TypeTag, Properties::Scalar>; + using type = FluidSystems::OnePLiquid<Scalar, Dumux::Components::Constant<1, Scalar> > ; +}; + +template<class TypeTag, class MyTypeTag> +struct HelpingGrid { using type = UndefinedProperty; }; + +// Set the grid type +template<class TypeTag> +struct HelpingGrid<TypeTag, TTag::FreeFlowOneP> +{ + using type = Dune::YaspGrid<2,Dune::TensorProductCoordinates<double, 2>>; +}; + +// Set the grid type +template<class TypeTag> +struct Grid<TypeTag, TTag::FreeFlowOneP> +{ + using type = Dune::ALUGrid<2,2,Dune::cube,Dune::nonconforming >; +}; + +// Set the problem property +template<class TypeTag> +struct Problem<TypeTag, TTag::FreeFlowOneP> { using type = Dumux::FreeFlowSubProblem<TypeTag> ; }; + +template<class TypeTag> +struct EnableGridGeometryCache<TypeTag, TTag::FreeFlowOneP> { static constexpr bool value = true; }; +template<class TypeTag> +struct EnableGridFluxVariablesCache<TypeTag, TTag::FreeFlowOneP> { static constexpr bool value = true; }; +template<class TypeTag> +struct EnableGridVolumeVariablesCache<TypeTag, TTag::FreeFlowOneP> { static constexpr bool value = true; }; + +//! The variables living on the faces +template<class TypeTag> +struct FaceVariables<TypeTag, TTag::FreeFlowOneP> +{ +private: + using FacePrimaryVariables = GetPropType<TypeTag, Properties::FacePrimaryVariables>; + using GridView = typename GetPropType<TypeTag, Properties::GridGeometry>::GridView; + static constexpr auto upwindSchemeOrder = getPropValue<TypeTag, Properties::UpwindSchemeOrder>(); + using ModelTraits = GetPropType<TypeTag, Properties::ModelTraits>; +public: + using type = MyStaggeredFaceVariables<ModelTraits, FacePrimaryVariables, GridView::dimension, upwindSchemeOrder>; +}; + +template<class TypeTag> +struct LocalFaceVariables<TypeTag, TTag::FreeFlowOneP> +{ +private: + using FacePrimaryVariables = GetPropType<TypeTag, Properties::FacePrimaryVariables>; +public: + using type = CVDStaggeredLocalFaceVariables<FacePrimaryVariables>; +}; + +//! The velocity output +template<class TypeTag> +struct VelocityOutput<TypeTag, TTag::FreeFlowOneP> +{ + using type = MyStaggeredFreeFlowVelocityOutput<GetPropType<TypeTag, Properties::GridVariables>, + GetPropType<TypeTag, Properties::SolutionVector>>; +}; + +//! Set the volume variables property +template<class TypeTag> +struct DualCVsVolVars<TypeTag, TTag::FreeFlowOneP> +{ +private: + using VV = GetPropType<TypeTag, Properties::VolumeVariables>; + using GridView = typename GetPropType<TypeTag, Properties::GridGeometry>::GridView; + static constexpr auto dimWorld = GridView::dimensionworld; + static constexpr int numPairs = 2 * (dimWorld - 1); + +public: + using type = NavierStokesDualCVsVolVars<VV, numPairs>; +}; + +//! Set the volume variables property +template<class TypeTag> +struct PrimalCVsVolVars<TypeTag, TTag::FreeFlowOneP> +{ +public: + using VolumeVariables = GetPropType<TypeTag, Properties::VolumeVariables>; + using type = std::array<NaviesStokesPrimalScvfPair<VolumeVariables>,8>;//TODO make work for dim != 2 +}; + +//! Set the default global volume variables cache vector class +template<class TypeTag> +struct GridVolumeVariables<TypeTag, TTag::FreeFlowOneP> +{ +private: + using Problem = GetPropType<TypeTag, Properties::Problem>; + using VolumeVariables = GetPropType<TypeTag, Properties::VolumeVariables>; + using DualCVsVolVars = GetPropType<TypeTag, Properties::DualCVsVolVars>; + using PrimalCVsVolVars = GetPropType<TypeTag, Properties::PrimalCVsVolVars>; + using GridView = typename GetPropType<TypeTag, Properties::GridGeometry>::GridView; + using SubControlVolume = typename GetPropType<TypeTag, Properties::GridGeometry>::SubControlVolume; + using SubControlVolumeFace = typename GetPropType<TypeTag, Properties::GridGeometry>::SubControlVolumeFace; + static constexpr auto enableCache = getPropValue<TypeTag, Properties::EnableGridVolumeVariablesCache>(); + using Traits = MyStaggeredGridDefaultGridVolumeVariablesTraits<Problem, PrimalCVsVolVars, DualCVsVolVars, VolumeVariables, GridView, SubControlVolume, SubControlVolumeFace>; +public: + using type = MyStaggeredGridVolumeVariables<Traits, enableCache>; +}; + +//! Set the BaseLocalResidual to StaggeredLocalResidual +template<class TypeTag> +struct BaseLocalResidual<TypeTag, TTag::FreeFlowOneP> { using type = StaggeredRefinedLocalResidual<TypeTag>; }; + +//! Set the face solution type +template<class TypeTag> +struct StaggeredFaceSolution<TypeTag, TTag::FreeFlowOneP> +{ +private: + using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; +public: + using type = Dumux::MyStaggeredFaceSolution<FaceSolutionVector>; +}; + +template<class TypeTag> +struct ElementFaceSolution<TypeTag, TTag::FreeFlowOneP> +{ +private: + using FaceSolutionVector = GetPropType<TypeTag, Properties::FaceSolutionVector>; +public: + using type = Dumux::CVDElementFaceSolution<FaceSolutionVector>; +}; + +//! Set the GridLocalFaceVariables +template<class TypeTag> +struct GridLocalFaceVariables<TypeTag, TTag::FreeFlowOneP> +{ + private: + using Problem = GetPropType<TypeTag, Properties::Problem>; + using LocalFaceVariables = GetPropType<TypeTag, Properties::LocalFaceVariables>; + static constexpr auto enableCache = getPropValue<TypeTag, Properties::EnableGridFaceVariablesCache>(); + public: + using type = CVDStaggeredLocalGridFaceVariables<Problem, LocalFaceVariables, enableCache>; +}; + +//! Set the grid variables (volume, flux and face variables) +template<class TypeTag> +struct GridVariables<TypeTag, TTag::FreeFlowOneP> +{ +private: + using GG = GetPropType<TypeTag, Properties::GridGeometry>; + using GVV = GetPropType<TypeTag, Properties::GridVolumeVariables>; + using GFVC = GetPropType<TypeTag, Properties::GridFluxVariablesCache>; + using GFV = GetPropType<TypeTag, Properties::GridFaceVariables>; + using GLFV = GetPropType<TypeTag, Properties::GridLocalFaceVariables>; +public: + using type = CVDStaggeredGridVariables<GG, GVV, GFVC, GFV, GLFV>; +}; + +//! The default fv grid geometry +template<class TypeTag> +struct GridGeometry<TypeTag, TTag::FreeFlowOneP> +{ +private: + static constexpr auto upwindSchemeOrder = getPropValue<TypeTag, Properties::UpwindSchemeOrder>(); + static constexpr bool enableCache = getPropValue<TypeTag, Properties::EnableGridGeometryCache>(); + using GridView = typename GetPropType<TypeTag, Properties::Grid>::LeafGridView; + using Traits = CVDStaggeredFreeFlowDefaultGridGeometryTraits<GridView, upwindSchemeOrder>; +public: + using type = CVDStaggeredGridGeometry<GridView, enableCache, Traits>; +}; + +//! Set the volume variables property +template<class TypeTag> +struct VolumeVariables<TypeTag, TTag::FreeFlowOneP> +{ +private: + using PV = GetPropType<TypeTag, Properties::PrimaryVariables>; + using FSY = GetPropType<TypeTag, Properties::FluidSystem>; + using FST = GetPropType<TypeTag, Properties::FluidState>; + using MT = GetPropType<TypeTag, Properties::ModelTraits>; + + static_assert(FSY::numPhases == MT::numFluidPhases(), "Number of phases mismatch between model and fluid system"); + static_assert(FST::numPhases == MT::numFluidPhases(), "Number of phases mismatch between model and fluid state"); + static_assert(!FSY::isMiscible(), "The Navier-Stokes model only works with immiscible fluid systems."); + + using Traits = NavierStokesVolumeVariablesTraits<PV, FSY, FST, MT>; +public: + using type = MyNavierStokesVolumeVariables<Traits>; +}; + +//! The local residual +template<class TypeTag> +struct LocalResidual<TypeTag, TTag::FreeFlowOneP> { using type = RefinedNavierStokesResidual<TypeTag>; }; + +//! The flux variables +template<class TypeTag> +struct FluxVariables<TypeTag, TTag::FreeFlowOneP> { using type = RefinedNavierStokesFluxVariables<TypeTag>; }; + +//! The specific I/O fields +template<class TypeTag> +struct IOFields<TypeTag, TTag::FreeFlowOneP> { +#if NONISOTHERMAL + using type = FreeflowNonIsothermalIOFields<MyNavierStokesIOFields>; +#else + using type = MyNavierStokesIOFields; +#endif +}; + +//! Set the global flux variables cache vector class +template<class TypeTag> +struct GridFluxVariablesCache<TypeTag, TTag::FreeFlowOneP> +{ +private: + using Problem = GetPropType<TypeTag, Properties::Problem>; + using FluxVariablesCache = GetPropType<TypeTag, Properties::FluxVariablesCache>; + using FluxVariablesCacheFiller = GetPropType<TypeTag, Properties::FluxVariablesCacheFiller>; + static constexpr auto enableCache = getPropValue<TypeTag, Properties::EnableGridFluxVariablesCache>(); + static constexpr auto upwindSchemeOrder = getPropValue<TypeTag, Properties::UpwindSchemeOrder>(); +public: + using type = MyStaggeredGridFluxVariablesCache<Problem, FluxVariablesCache, FluxVariablesCacheFiller, enableCache, upwindSchemeOrder>; +}; +} // end namespace Properties + +/*! + * \ingroup BoundaryTests + * \brief The Stokes sub-problem of coupled Stokes-Darcy convergence test + */ +template <class TypeTag> +class FreeFlowSubProblem : public MyNavierStokesProblem<TypeTag> +{ + using ParentType = MyNavierStokesProblem<TypeTag>; + using Scalar = GetPropType<TypeTag, Properties::Scalar>; + using BoundaryTypes = Dumux::NavierStokesBoundaryTypes<GetPropType<TypeTag, Properties::ModelTraits>::numEq()>; + using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; + using GridView = typename GridGeometry::GridView; + using FVElementGeometry = typename GridGeometry::LocalView; + using SubControlVolume = typename FVElementGeometry::SubControlVolume; + using SubControlVolumeFace = typename GridGeometry::SubControlVolumeFace; + using Element = typename GridView::template Codim<0>::Entity; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>; + using NumEqVector = Dumux::NumEqVector<GetPropType<TypeTag, Properties::PrimaryVariables>>; + using ModelTraits = GetPropType<TypeTag, Properties::ModelTraits>; + + using CouplingManager = GetPropType<TypeTag, Properties::CouplingManager>; + +public: + //! export the Indices + using Indices = typename ModelTraits::Indices; + + FreeFlowSubProblem(std::shared_ptr<const GridGeometry> gridGeometry, + std::shared_ptr<CouplingManager> couplingManager, + const TestCase testCase, + const std::string& name) + : ParentType(gridGeometry, "FreeFlow") + , couplingManager_(couplingManager) + , testCase_(testCase) + { + problemName_ = name + "_" + getParamFromGroup<std::string>(this->paramGroup(), "Problem.Name"); + } + + /*! + * \brief The problem name. + */ + const std::string& name() const + { + return problemName_; + } + + /*! + * \name Problem parameters + */ + // \{ + + /*! + * \brief Returns the temperature within the domain in [K]. + * + * This problem assumes a temperature of 10 degrees Celsius. + */ + Scalar temperature() const + { return 273.15 + 10; } // 10°C + + /*! + * \brief Returns the sources within the domain. + * + * \param globalPos The global position + */ + NumEqVector sourceAtPos(const GlobalPosition &globalPos) const + { + switch (testCase_) + { + case TestCase::ShiueExampleOne: + return rhsShiueEtAlExampleOne_(globalPos); + case TestCase::ShiueExampleTwo: + return rhsShiueEtAlExampleTwo_(globalPos); + case TestCase::Rybak: + return rhsRybak_(globalPos); + case TestCase::Schneider: + return rhsSchneiderEtAl_(globalPos); + default: + DUNE_THROW(Dune::InvalidStateException, "Invalid test case"); + } + } + + // \} + + /*! + * \name Boundary conditions + */ + // \{ + + /*! + * \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 Element& element, + const SubControlVolumeFace& scvf) const + { + BoundaryTypes values; + + values.setDirichlet(Indices::velocityXIdx); + values.setDirichlet(Indices::velocityYIdx); + + if (couplingManager().isCoupledEntity(CouplingManager::stokesIdx, scvf)) + { + values.setCouplingNeumann(Indices::conti0EqIdx); + values.setCouplingNeumann(Indices::momentumYBalanceIdx); + values.setBeaversJoseph(Indices::momentumXBalanceIdx); + } + + return values; + } + + /*! + * \brief Evaluate the boundary conditions for a dirichlet + * control volume face (velocities) + * + * \param element The finite element + * \param scvf the sub control volume face + * + * Concerning the usage of averaged velocity, see the explanation of the initial function. The average of the nondirection velocity along an scvf is required in the context of dirichlet boundary conditions for the functions getParallelVelocityFromBoundary_ and getParallelVelocityFromOtherBoundary_ within myfluxvariables.hh. There dirichlet is called for ghost faces built from the normalFace but the value then is taken in the the direction scvf.directionIndex, which is along that normalFace. + */ + PrimaryVariables dirichlet(const Element& element, const SubControlVolumeFace& scvf) const + { + PrimaryVariables priVars(0.0); + + unsigned int dirIdx = scvf.directionIndex(); + priVars[Indices::velocity(dirIdx)] = this->analyticalVelocitySolutionAtPos(scvf); + unsigned int nonDirIdx = (dirIdx == 0)?1:0; + priVars[Indices::velocity(nonDirIdx)] = this->analyticalNonDirVelocitySolutionAtPos(scvf); + + return priVars; + } + + /*! + * \brief Evaluate the boundary conditions for a dirichlet + * control volume face (pressure) + * + * \param element The finite element + * \param scv the sub control volume + */ + PrimaryVariables dirichlet(const Element& element, const SubControlVolume& scv) const + { + PrimaryVariables priVars(0.0); + priVars[Indices::pressureIdx] = this->analyticalPressureSolutionAtPos(scv); + return priVars; + } + + /*! + * \brief Evaluates the boundary conditions for a Neumann control volume. + * + * \param element The element for which the Neumann boundary condition is set + * \param fvGeometry The fvGeometry + * \param elemVolVars The element volume variables + * \param elemFaceVars The element face variables + * \param scvf The boundary sub control volume face + */ + template<class ElementVolumeVariables, class ElementFaceVariables> + NumEqVector neumann(const Element& element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars, + const ElementFaceVariables& elemFaceVars, + const SubControlVolumeFace& scvf) const + { + NumEqVector values(0.0); + + if(couplingManager().isCoupledEntity(CouplingManager::stokesIdx, scvf)) + { + values[Indices::conti0EqIdx] = couplingManager().couplingData().massCouplingCondition(element, fvGeometry, elemVolVars, elemFaceVars, scvf); + values[Indices::momentumYBalanceIdx] = couplingManager().couplingData().momentumCouplingCondition(element, fvGeometry, elemVolVars, elemFaceVars, scvf); + } + return values; + } + + // \} + + //! Get the coupling manager + const CouplingManager& couplingManager() const + { return *couplingManager_; } + + /*! + * \name Volume terms + */ + // \{ + + /*! + * \brief Evaluates the initial value for a sub control volume face (velocities) + * + * Simply assigning the value of the analytical solution at the face center + * gives a discrete solution that is not divergence-free. For small initial + * time steps, this has a negative impact on the pressure solution + * after the first time step. The flag UseVelocityAveraging triggers the + * function averagedVelocity_ which uses a higher order quadrature formula to + * bring the discrete solution sufficiently close to being divergence-free. + */ + PrimaryVariables initial(const SubControlVolumeFace& scvf) const + { + PrimaryVariables priVars(0.0); + priVars[Indices::velocity(scvf.directionIndex())] = this->analyticalVelocitySolutionAtPos(scvf); + return priVars; + } + + /*! + * \brief Evaluates the initial value for a control volume (pressure) + */ + PrimaryVariables initial(const SubControlVolume& scv) const + { + PrimaryVariables priVars(0.0); + priVars[Indices::pressureIdx] = this->analyticalPressureSolutionAtPos(scv); + return priVars; + } + + /*! + * \brief Returns the intrinsic permeability of required as input parameter + for the Beavers-Joseph-Saffman boundary condition + */ + auto permeability(const Element& element, const SubControlVolumeFace& scvf) const + { + return couplingManager().couplingData().darcyPermeability(element, scvf); + } + + /*! + * \brief Returns the alpha value required as input parameter for the + Beavers-Joseph-Saffman boundary condition. + */ + Scalar alphaBJ(const SubControlVolumeFace& scvf) const + { + return couplingManager().problem(CouplingManager::darcyIdx).spatialParams().beaversJosephCoeffAtPos(scvf.center()); + } + + /*! + * \brief Returns the analytical solution of the problem at a given position. + * + * \param globalPos The global position + */ + PrimaryVariables analyticalSolutionAtPos(const GlobalPosition& globalPos) const + { + switch (testCase_) + { + case TestCase::ShiueExampleOne: + return analyticalSolutionShiueEtAlExampleOne_(globalPos); + case TestCase::ShiueExampleTwo: + return analyticalSolutionShiueEtAlExampleTwo_(globalPos); + case TestCase::Rybak: + return analyticalSolutionRybak_(globalPos); + case TestCase::Schneider: + return analyticalSolutionSchneiderEtAl_(globalPos); + default: + DUNE_THROW(Dune::InvalidStateException, "Invalid test case"); + } + } + + // \} + +private: + + // see Rybak et al., 2015: "Multirate time integration for coupled saturated/unsaturated porous medium and free flow systems" + PrimaryVariables analyticalSolutionRybak_(const GlobalPosition& globalPos) const + { + PrimaryVariables sol(0.0); + const Scalar x = globalPos[0]; + const Scalar y = globalPos[1]; + + using std::sin; using std::cos; + sol[Indices::velocityXIdx] = -cos(M_PI*x)*sin(M_PI*y); + sol[Indices::velocityYIdx] = sin(M_PI*x)*cos(M_PI*y); + sol[Indices::pressureIdx] = 0.5*y*sin(M_PI*x); + return sol; + } + + // see Rybak et al., 2015: "Multirate time integration for coupled saturated/unsaturated porous medium and free flow systems" + NumEqVector rhsRybak_(const GlobalPosition& globalPos) const + { + const Scalar x = globalPos[0]; + const Scalar y = globalPos[1]; + NumEqVector source(0.0); + using std::sin; using std::cos; + source[Indices::momentumXBalanceIdx] = 0.5*M_PI*y*cos(M_PI*x) - 2*M_PI*M_PI*cos(M_PI*x)*sin(M_PI*y); + source[Indices::momentumYBalanceIdx] = 0.5*sin(M_PI*x) + 2*M_PI*M_PI*sin(M_PI*x)*cos(M_PI*y); + return source; + } + + // see Shiue et al., 2018: "Convergence of the MAC Scheme for the Stokes/Darcy Coupling Problem" + PrimaryVariables analyticalSolutionShiueEtAlExampleOne_(const GlobalPosition& globalPos) const + { + PrimaryVariables sol(0.0); + const Scalar x = globalPos[0]; + const Scalar y = globalPos[1]; + + using std::exp; using std::sin; using std::cos; + sol[Indices::velocityXIdx] = -1/M_PI * exp(y) * sin(M_PI*x); + sol[Indices::velocityYIdx] = (exp(y) - exp(1)) * cos(M_PI*x); + sol[Indices::pressureIdx] = 2*exp(y) * cos(M_PI*x); + return sol; + } + + // see Shiue et al., 2018: "Convergence of the MAC Scheme for the Stokes/Darcy Coupling Problem" + NumEqVector rhsShiueEtAlExampleOne_(const GlobalPosition& globalPos) const + { + const Scalar x = globalPos[0]; + const Scalar y = globalPos[1]; + using std::exp; using std::sin; using std::cos; + NumEqVector source(0.0); + source[Indices::momentumXBalanceIdx] = exp(y)*sin(M_PI*x) * (1/M_PI -3*M_PI); + source[Indices::momentumYBalanceIdx] = cos(M_PI*x) * (M_PI*M_PI*(exp(y)- exp(1)) + exp(y)); + return source; + } + + // see Shiue et al., 2018: "Convergence of the MAC Scheme for the Stokes/Darcy Coupling Problem" + PrimaryVariables analyticalSolutionShiueEtAlExampleTwo_(const GlobalPosition& globalPos) const + { + PrimaryVariables sol(0.0); + const Scalar x = globalPos[0]; + const Scalar y = globalPos[1]; + + sol[Indices::velocityXIdx] = (y-1.0)*(y-1.0) + x*(y-1.0) + 3.0*x - 1.0; + sol[Indices::velocityYIdx] = x*(x-1.0) - 0.5*(y-1.0)*(y-1.0) - 3.0*y + 1.0; + sol[Indices::pressureIdx] = 2.0*x + y - 1.0; + return sol; + } + + // see Shiue et al., 2018: "Convergence of the MAC Scheme for the Stokes/Darcy Coupling Problem" + NumEqVector rhsShiueEtAlExampleTwo_(const GlobalPosition& globalPos) const + { return NumEqVector(0.0); } + + // see Schneider et al., 2019: "Coupling staggered-grid and MPFA finite volume methods for + // free flow/porous-medium flow problems" + PrimaryVariables analyticalSolutionSchneiderEtAl_(const GlobalPosition& globalPos) const + { + PrimaryVariables sol(0.0); + const Scalar x = globalPos[0]; + const Scalar y = globalPos[1]; + using std::sin; + static constexpr Scalar omega = M_PI; + const Scalar sinOmegaX = sin(omega*x); + + sol[Indices::velocityXIdx] = y; + sol[Indices::velocityYIdx] = -y*sinOmegaX; + sol[Indices::pressureIdx] = -y*y*sinOmegaX*sinOmegaX; + return sol; + } + + // see Schneider et al., 2019: "Coupling staggered-grid and MPFA finite volume methods for + // free flow/porous-medium flow problems" + NumEqVector rhsSchneiderEtAl_(const GlobalPosition& globalPos) const + { + const Scalar x = globalPos[0]; + const Scalar y = globalPos[1]; + using std::exp; using std::sin; using std::cos; + static constexpr Scalar omega = M_PI; + const Scalar sinOmegaX = sin(omega*x); + const Scalar cosOmegaX = cos(omega*x); + + NumEqVector source(0.0); + source[Indices::conti0EqIdx] = -sinOmegaX; + source[Indices::momentumXBalanceIdx] = -2*omega*y*y*sinOmegaX*cosOmegaX + -2*y*sinOmegaX + omega*cosOmegaX; + source[Indices::momentumYBalanceIdx] = -omega*y*y*cosOmegaX - omega*omega*y*sinOmegaX; + return source; + } + + static constexpr Scalar eps_ = 1e-7; + std::string problemName_; + std::shared_ptr<CouplingManager> couplingManager_; + TestCase testCase_; +}; +} // end namespace Dumux + +#endif diff --git a/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/spatialparams.hh b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/spatialparams.hh new file mode 100644 index 0000000..0f0c9f2 --- /dev/null +++ b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/spatialparams.hh @@ -0,0 +1,131 @@ +// -*- 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 3 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 + * \ingroup BoundaryTests + * \brief The spatial parameters class for the test problem using the 1p cc model. + */ + +#ifndef DUMUX_CONVERGENCE_TEST_SPATIALPARAMS_HH +#define DUMUX_CONVERGENCE_TEST_SPATIALPARAMS_HH + +#include <cmath> +#include <dumux/common/math.hh> +#include <dumux/common/parameters.hh> +#include <dune/common/fmatrix.hh> +#include <dumux/material/spatialparams/fv1p.hh> +#include "testcase.hh" + +namespace Dumux { + +/*! + * \ingroup BoundaryTests + * \brief The spatial parameters class for the test problem using the + * 1p cc model. + */ +template<class GridGeometry, class Scalar> +class ConvergenceTestSpatialParams +: public FVSpatialParamsOneP<GridGeometry, Scalar, + ConvergenceTestSpatialParams<GridGeometry, Scalar>> +{ + using GridView = typename GridGeometry::GridView; + using ParentType = FVSpatialParamsOneP<GridGeometry, Scalar, + ConvergenceTestSpatialParams<GridGeometry, Scalar>>; + + using Element = typename GridView::template Codim<0>::Entity; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + + static constexpr int dimWorld = GridView::dimensionworld; + using DimWorldMatrix = Dune::FieldMatrix<Scalar, dimWorld, dimWorld>; + + +public: + // export permeability type + using PermeabilityType = DimWorldMatrix; + + ConvergenceTestSpatialParams(std::shared_ptr<const GridGeometry> gridGeometry, const TestCase testCase) + : ParentType(gridGeometry) + , testCase_(testCase) + { + alphaBJ_ = getParam<Scalar>("Darcy.SpatialParams.AlphaBeaversJoseph"); + } + + /*! + * \brief Function for defining the (intrinsic) permeability \f$[m^2]\f$. + * + * \param element The element + * \param scv The sub control volume + * \param elemSol The element solution vector + * \return the intrinsic permeability + */ + template<class SubControlVolume, class ElementSolution> + PermeabilityType permeability(const Element& element, + const SubControlVolume& scv, + const ElementSolution& elemSol) const + { + PermeabilityType K(0.0); + + if (testCase_ == TestCase::Schneider) + { + using std::cos; + using std::sin; + using std::exp; + + static constexpr Scalar c = 0.0; + static constexpr Scalar omega = M_PI; + + const Scalar x = scv.center()[0]; + K[0][0] = 1.0; + K[0][1] = -c/(2*omega) * sin(omega*x); + K[1][0] = K[0][1]; + K[1][1] = exp(-2)*(1 + c*cos(omega*x)); + } + else + { + const static Scalar permeability = getParam<Scalar>("Darcy.SpatialParams.Permeability"); + K[0][0] = permeability; + K[1][1] = permeability; + } + + return K; + } + + /*! \brief Defines the porosity in [-]. + * + * \param globalPos The global position + */ + Scalar porosityAtPos(const GlobalPosition& globalPos) const + { return 0.4; } + + /*! \brief Defines the Beavers-Joseph coefficient in [-]. + * + * \param globalPos The global position + */ + Scalar beaversJosephCoeffAtPos(const GlobalPosition& globalPos) const + { return alphaBJ_; } + +private: + TestCase testCase_; + Scalar permeability_; + Scalar alphaBJ_; +}; + +} // end namespace Dumux + +#endif diff --git a/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/testcase.hh b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/testcase.hh new file mode 100644 index 0000000..39aaaf7 --- /dev/null +++ b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/testcase.hh @@ -0,0 +1,37 @@ +// -*- 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 3 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 + * \ingroup BoundaryTests + * \brief The different test cases + */ + +#ifndef DUMUX_CONVERGENCE_TEST_TESTCASE_HH +#define DUMUX_CONVERGENCE_TEST_TESTCASE_HH + +namespace Dumux { + +enum class TestCase +{ + ShiueExampleOne, ShiueExampleTwo, Rybak, Schneider +}; + +} // end namespace Dumux + +#endif diff --git a/appl/multidomain/boundary/stokesdarcy/CMakeLists.txt b/appl/multidomain/boundary/stokesdarcy/CMakeLists.txt new file mode 100644 index 0000000..f62f49d --- /dev/null +++ b/appl/multidomain/boundary/stokesdarcy/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(1p_1p) diff --git a/dumux/multidomain/cvdsubdomainstaggeredlocalassembler.hh b/dumux/multidomain/cvdsubdomainstaggeredlocalassembler.hh index 23d576b..65af17f 100644 --- a/dumux/multidomain/cvdsubdomainstaggeredlocalassembler.hh +++ b/dumux/multidomain/cvdsubdomainstaggeredlocalassembler.hh @@ -153,6 +153,16 @@ public: assembleResidualImpl_(domainId, res); } + /*! + * \brief Convenience function to evaluate the complete local residual for the current element. Automatically chooses the the appropriate + * element volume variables. Automatically takes cellCenterIdx from this->element() (afterthought for porous-medium test) + */ + CellCenterResidualValue evalLocalResidualForCellCenter() const + { + const auto cellCenterGlobalI = problem().gridGeometry().elementMapper().index(this->element()); + return evalLocalResidualForCellCenter(cellCenterGlobalI); + } + /*! * \brief Convenience function to evaluate the complete local residual for the current element. Automatically chooses the the appropriate * element volume variables. -- GitLab From dd0600a6bae405c9390900b10767b3c8fc46038b Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Mon, 20 Sep 2021 13:26:27 +0300 Subject: [PATCH 44/69] Created a newtonsolver for debugging the program --- appl/freeflow/navierstokes/channel/2d/main.cc | 2 +- dumux/nonlinear/newtonsolverdebug.hh | 1480 +++++++++++++++++ 2 files changed, 1481 insertions(+), 1 deletion(-) create mode 100644 dumux/nonlinear/newtonsolverdebug.hh diff --git a/appl/freeflow/navierstokes/channel/2d/main.cc b/appl/freeflow/navierstokes/channel/2d/main.cc index 982a8f7..9af2b60 100644 --- a/appl/freeflow/navierstokes/channel/2d/main.cc +++ b/appl/freeflow/navierstokes/channel/2d/main.cc @@ -43,7 +43,7 @@ bool doFirstOrderLocalTruncErrorGlobalRefinement = false; #include <dumux/common/defaultusagemessage.hh> #include <dumux/linear/seqsolverbackend.hh> -#include <dumux/nonlinear/newtonsolver.hh> +#include <dumux/nonlinear/newtonsolverdebug.hh> #include <dumux/assembly/cvdstaggeredrefinedfvassembler.hh> #include <dumux/assembly/diffmethod.hh> diff --git a/dumux/nonlinear/newtonsolverdebug.hh b/dumux/nonlinear/newtonsolverdebug.hh new file mode 100644 index 0000000..33c3d58 --- /dev/null +++ b/dumux/nonlinear/newtonsolverdebug.hh @@ -0,0 +1,1480 @@ +// -*- 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 3 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 + * \ingroup Nonlinear + * \brief Reference implementation of a Newton solver. + */ +#ifndef DUMUX_NEWTON_SOLVER_DEBUG_HH +#define DUMUX_NEWTON_SOLVER_DEBUG_HH + +#include <cmath> +#include <memory> +#include <iostream> +#include <type_traits> +#include <algorithm> +#include <numeric> +#include <filesystem> + +#include <dune/common/timer.hh> +#include <dune/common/exceptions.hh> +#include <dune/common/parallel/mpicommunication.hh> +#include <dune/common/parallel/mpihelper.hh> +#include <dune/common/std/type_traits.hh> +#include <dune/common/indices.hh> +#include <dune/common/hybridutilities.hh> + +#include <dune/istl/bvector.hh> +#include <dune/istl/multitypeblockvector.hh> + +#include <dumux/common/parameters.hh> +#include <dumux/common/exceptions.hh> +#include <dumux/common/typetraits/vector.hh> +#include <dumux/common/typetraits/isvalid.hh> +#include <dumux/common/timeloop.hh> +#include <dumux/common/pdesolver.hh> +#include <dumux/common/variablesbackend.hh> + +#include <dumux/io/format.hh> +#include <dumux/linear/linearsolveracceptsmultitypematrix.hh> +#include <dumux/linear/matrixconverter.hh> +#include <dumux/assembly/partialreassembler.hh> + +#include <dumux/io/cvdio.hh> + +#include <dumux/nonlinear/newtonconvergencewriter.hh> +#include <dumux/nonlinear/primaryvariableswitchadapter.hh> + +namespace Dumux { +namespace Detail { + +// Helper boolean that states if the assembler exports grid variables +template<class Assembler> using AssemblerGridVariablesType = typename Assembler::GridVariables; +template<class Assembler> +inline constexpr bool assemblerExportsGridVariables + = Dune::Std::is_detected_v<AssemblerGridVariablesType, Assembler>; + +// helper struct to define the variables on which the privarswitch should operate +template<class Assembler, bool exportsGridVars = assemblerExportsGridVariables<Assembler>> +struct PriVarSwitchVariablesType { using Type = typename Assembler::GridVariables; }; + +// if assembler does not export them, use an empty class. These situations either mean +// that there is no privarswitch, or, it is handled by a derived implementation. +template<class Assembler> +struct PriVarSwitchVariablesType<Assembler, false> +{ using Type = struct EmptyGridVariables {}; }; + +// Helper alias to deduce the variables types used in the privarswitch adapter +template<class Assembler> +using PriVarSwitchVariables + = typename PriVarSwitchVariablesType<Assembler, assemblerExportsGridVariables<Assembler>>::Type; + +//! helper struct detecting if an assembler supports partial reassembly +struct supportsPartialReassembly +{ + template<class Assembler> + auto operator()(Assembler&& a) + -> decltype(a.assembleJacobianAndResidual(std::declval<const typename Assembler::ResidualType&>(), + std::declval<const PartialReassembler<Assembler>*>())) + {} +}; + +// helper struct and function detecting if the linear solver features a norm() function +template <class LinearSolver, class Residual> +using NormDetector = decltype(std::declval<LinearSolver>().norm(std::declval<Residual>())); + +template<class LinearSolver, class Residual> +static constexpr bool hasNorm() +{ return Dune::Std::is_detected<NormDetector, LinearSolver, Residual>::value; } + +// helpers to implement max relative shift +template<class C> using dynamicIndexAccess = decltype(std::declval<C>()[0]); +template<class C> using staticIndexAccess = decltype(std::declval<C>()[Dune::Indices::_0]); +template<class C> static constexpr auto hasDynamicIndexAccess = Dune::Std::is_detected<dynamicIndexAccess, C>{}; +template<class C> static constexpr auto hasStaticIndexAccess = Dune::Std::is_detected<staticIndexAccess, C>{}; + +template<class V, class Scalar, class Reduce, class Transform> +auto hybridInnerProduct(const V& v1, const V& v2, Scalar init, Reduce&& r, Transform&& t) +-> std::enable_if_t<hasDynamicIndexAccess<V>(), Scalar> +{ + return std::inner_product(v1.begin(), v1.end(), v2.begin(), init, std::forward<Reduce>(r), std::forward<Transform>(t)); +} + +template<class V, class Scalar, class Reduce, class Transform> +auto hybridInnerProduct(const V& v1, const V& v2, Scalar init, Reduce&& r, Transform&& t) +-> std::enable_if_t<hasStaticIndexAccess<V>() && !hasDynamicIndexAccess<V>(), Scalar> +{ + using namespace Dune::Hybrid; + forEach(std::make_index_sequence<V::N()>{}, [&](auto i){ + init = r(init, hybridInnerProduct(v1[Dune::index_constant<i>{}], v2[Dune::index_constant<i>{}], init, std::forward<Reduce>(r), std::forward<Transform>(t))); + }); + return init; +} + +// Maximum relative shift at a degree of freedom. +// For (primary variables) values below 1.0 we use +// an absolute shift. +template<class Scalar, class V> +auto maxRelativeShift(const V& v1, const V& v2) +-> std::enable_if_t<Dune::IsNumber<V>::value, Scalar> +{ + using std::abs; using std::max; + return abs(v1 - v2)/max<Scalar>(1.0, abs(v1 + v2)*0.5); +} + +// Maximum relative shift for generic vector types. +// Recursively calls maxRelativeShift until Dune::IsNumber is true. +template<class Scalar, class V> +auto maxRelativeShift(const V& v1, const V& v2) +-> std::enable_if_t<!Dune::IsNumber<V>::value, Scalar> +{ + return hybridInnerProduct(v1, v2, Scalar(0.0), + [](const auto& a, const auto& b){ using std::max; return max(a, b); }, + [](const auto& a, const auto& b){ return maxRelativeShift<Scalar>(a, b); } + ); +} + +template<class To, class From> +void assign(To& to, const From& from) +{ + if constexpr (std::is_assignable<To&, From>::value) + to = from; + + else if constexpr (hasStaticIndexAccess<To>() && hasStaticIndexAccess<To>() && !hasDynamicIndexAccess<From>() && !hasDynamicIndexAccess<From>()) + { + using namespace Dune::Hybrid; + forEach(std::make_index_sequence<To::N()>{}, [&](auto i){ + assign(to[Dune::index_constant<i>{}], from[Dune::index_constant<i>{}]); + }); + } + + else if constexpr (hasDynamicIndexAccess<To>() && hasDynamicIndexAccess<From>()) + for (decltype(to.size()) i = 0; i < to.size(); ++i) + assign(to[i], from[i]); + + else if constexpr (hasDynamicIndexAccess<To>() && Dune::IsNumber<From>::value) + { + assert(to.size() == 1); + assign(to[0], from); + } + + else if constexpr (Dune::IsNumber<To>::value && hasDynamicIndexAccess<From>()) + { + assert(from.size() == 1); + assign(to, from[0]); + } + + else + DUNE_THROW(Dune::Exception, "Values are not assignable to each other!"); +} + +template<class T, std::enable_if_t<Dune::IsNumber<std::decay_t<T>>::value, int> = 0> +constexpr std::size_t blockSize() { return 1; } + +template<class T, std::enable_if_t<!Dune::IsNumber<std::decay_t<T>>::value, int> = 0> +constexpr std::size_t blockSize() { return std::decay_t<T>::size(); } + +template<class S, bool isScalar = false> +struct BlockTypeHelper +{ using type = std::decay_t<decltype(std::declval<S>()[0])>; }; +template<class S> +struct BlockTypeHelper<S, true> +{ using type = S; }; + +template<class SolutionVector> +using BlockType = typename BlockTypeHelper<SolutionVector, Dune::IsNumber<SolutionVector>::value>::type; + +} // end namespace Detail + +/*! + * \ingroup Nonlinear + * \brief An implementation of a Newton solver + * \tparam Assembler the assembler + * \tparam LinearSolver the linear solver + * \tparam Comm the communication object used to communicate with all processes + * \note If you want to specialize only some methods but are happy with the + * defaults of the reference solver, derive your solver from + * this class and simply overload the required methods. + */ +template <class Assembler, class LinearSolver, + class Reassembler = PartialReassembler<Assembler>, + class Comm = Dune::CollectiveCommunication<Dune::MPIHelper::MPICommunicator> > +class NewtonSolver : public PDESolver<Assembler, LinearSolver> +{ + using ParentType = PDESolver<Assembler, LinearSolver>; + +protected: + using Backend = VariablesBackend<typename ParentType::Variables>; + using SolutionVector = typename Backend::DofVector; + +private: + using Scalar = typename Assembler::Scalar; + using JacobianMatrix = typename Assembler::JacobianMatrix; + using ConvergenceWriter = ConvergenceWriterInterface<SolutionVector>; + using TimeLoop = TimeLoopBase<Scalar>; + + // enable models with primary variable switch + // TODO: Always use ParentType::Variables once we require assemblers to export variables + static constexpr bool assemblerExportsVariables = Detail::exportsVariables<Assembler>; + using PriVarSwitchVariables + = std::conditional_t<assemblerExportsVariables, + typename ParentType::Variables, + Detail::PriVarSwitchVariables<Assembler>>; + using PrimaryVariableSwitchAdapter = Dumux::PrimaryVariableSwitchAdapter<PriVarSwitchVariables>; + +public: + using typename ParentType::Variables; + using Communication = Comm; + + /*! + * \brief The Constructor + */ + NewtonSolver(std::shared_ptr<Assembler> assembler, + std::shared_ptr<LinearSolver> linearSolver, + const Communication& comm = Dune::MPIHelper::getCollectiveCommunication(), + const std::string& paramGroup = "") + : ParentType(assembler, linearSolver) + , endIterMsgStream_(std::ostringstream::out) + , comm_(comm) + , paramGroup_(paramGroup) + , priVarSwitchAdapter_(std::make_unique<PrimaryVariableSwitchAdapter>(paramGroup)) + { + initParams_(paramGroup); + + // set the linear system (matrix & residual) in the assembler + this->assembler().setLinearSystem(); + + // set a different default for the linear solver residual reduction + // within the Newton the linear solver doesn't need to solve too exact + this->linearSolver().setResidualReduction(getParamFromGroup<Scalar>(paramGroup, "LinearSolver.ResidualReduction", 1e-6)); + + // initialize the partial reassembler + if (enablePartialReassembly_) + partialReassembler_ = std::make_unique<Reassembler>(this->assembler()); + } + + //! the communicator for parallel runs + const Communication& comm() const + { return comm_; } + + /*! + * \brief Set the maximum acceptable difference of any primary variable + * between two iterations for declaring convergence. + * + * \param tolerance The maximum relative shift between two Newton + * iterations at which the scheme is considered finished + */ + void setMaxRelativeShift(Scalar tolerance) + { shiftTolerance_ = tolerance; } + + /*! + * \brief Set the maximum acceptable absolute residual for declaring convergence. + * + * \param tolerance The maximum absolute residual at which + * the scheme is considered finished + */ + void setMaxAbsoluteResidual(Scalar tolerance) + { residualTolerance_ = tolerance; } + + /*! + * \brief Set the maximum acceptable residual norm reduction. + * + * \param tolerance The maximum reduction of the residual norm + * at which the scheme is considered finished + */ + void setResidualReduction(Scalar tolerance) + { reductionTolerance_ = tolerance; } + + /*! + * \brief Set the number of iterations at which the Newton method + * should aim at. + * + * This is used to control the time-step size. The heuristic used + * is to scale the last time-step size by the deviation of the + * number of iterations used from the target steps. + * + * \param targetSteps Number of iterations which are considered "optimal" + */ + void setTargetSteps(int targetSteps) + { targetSteps_ = targetSteps; } + + /*! + * \brief Set the number of minimum iterations for the Newton + * method. + * + * \param minSteps Minimum number of iterations + */ + void setMinSteps(int minSteps) + { minSteps_ = minSteps; } + + /*! + * \brief Set the number of iterations after which the Newton + * method gives up. + * + * \param maxSteps Number of iterations after we give up + */ + void setMaxSteps(int maxSteps) + { maxSteps_ = maxSteps; } + + /*! + * \brief Run the Newton method to solve a non-linear system. + * Does time step control when the Newton fails to converge + * \param vars The variables object representing the current state of the + * numerical solution (primary and possibly secondary variables). + * \param timeLoop The time loop. + */ + void solve(Variables& vars, TimeLoop& timeLoop) override + { + if constexpr (!assemblerExportsVariables) + { + if (this->assembler().isStationaryProblem()) + DUNE_THROW(Dune::InvalidStateException, "Using time step control with stationary problem makes no sense!"); + } + + // try solving the non-linear system + for (std::size_t i = 0; i <= maxTimeStepDivisions_; ++i) + { + // linearize & solve + const bool converged = solve_(vars); + + if (converged) + return; + + else if (!converged && i < maxTimeStepDivisions_) + { + if constexpr (assemblerExportsVariables) + DUNE_THROW(Dune::NotImplemented, "Time step reset for new assembly methods"); + else + { + // set solution to previous solution & reset time step + Backend::update(vars, this->assembler().prevSol()); + this->assembler().resetTimeStep(Backend::dofs(vars)); + + if (verbosity_ >= 1) + { + const auto dt = timeLoop.timeStepSize(); + std::cout << Fmt::format("Newton solver did not converge with dt = {} seconds. ", dt) + << Fmt::format("Retrying with time step of dt = {} seconds.\n", dt*retryTimeStepReductionFactor_); + } + + // try again with dt = dt * retryTimeStepReductionFactor_ + timeLoop.setTimeStepSize(timeLoop.timeStepSize() * retryTimeStepReductionFactor_); + } + } + + else + { + DUNE_THROW(NumericalProblem, + Fmt::format("Newton solver didn't converge after {} time-step divisions; dt = {}.\n", + maxTimeStepDivisions_, timeLoop.timeStepSize())); + } + } + } + + /*! + * \brief Run the Newton method to solve a non-linear system. + * The solver is responsible for all the strategic decisions. + * \param vars The variables object representing the current state of the + * numerical solution (primary and possibly secondary variables). + */ + void solve(Variables& vars) override + { + const bool converged = solve_(vars); + if (!converged) + DUNE_THROW(NumericalProblem, + Fmt::format("Newton solver didn't converge after {} iterations.\n", numSteps_)); + } + + /*! + * \brief Called before the Newton method is applied to an + * non-linear system of equations. + * + * \param initVars The variables representing the initial solution + */ + virtual void newtonBegin(Variables& initVars) + { + numSteps_ = 0; + + if constexpr (hasPriVarsSwitch<PriVarSwitchVariables>) + { + if constexpr (assemblerExportsVariables) + priVarSwitchAdapter_->initialize(Backend::dofs(initVars), initVars); + else // this assumes assembly with solution (i.e. Variables=SolutionVector) + priVarSwitchAdapter_->initialize(initVars, this->assembler().gridVariables()); + } + + const auto& initSol = Backend::dofs(initVars); + + // write the initial residual if a convergence writer was set + if (convergenceWriter_) + { + this->assembler().assembleResidual(initVars); + + // dummy vector, there is no delta before solving the linear system + auto delta = Backend::zeros(Backend::size(initSol)); + convergenceWriter_->write(initSol, delta, this->assembler().residual()); + } + + if (enablePartialReassembly_) + { + partialReassembler_->resetColors(); + resizeDistanceFromLastLinearization_(initSol, distanceFromLastLinearization_); + } + } + + /*! + * \brief Returns true if another iteration should be done. + * + * \param varsCurrentIter The variables of the current Newton iteration + * \param converged if the Newton method's convergence criterion was met in this step + */ + virtual bool newtonProceed(const Variables &varsCurrentIter, bool converged) + { + if (numSteps_ < minSteps_) + return true; + else if (converged) + return false; // we are below the desired tolerance + else if (numSteps_ >= maxSteps_) + { + // We have exceeded the allowed number of steps. If the + // maximum relative shift was reduced by a factor of at least 4, + // we proceed even if we are above the maximum number of steps. + if (enableShiftCriterion_) + return shift_*4.0 < lastShift_; + else + return reduction_*4.0 < lastReduction_; + } + + return true; + } + + /*! + * \brief Indicates the beginning of a Newton iteration. + */ + virtual void newtonBeginStep(const Variables& vars) + { + lastShift_ = shift_; + if (numSteps_ == 0) + { + lastReduction_ = 1.0; + } + else + { + lastReduction_ = reduction_; + } + } + + /*! + * \brief Assemble the linear system of equations \f$\mathbf{A}x - b = 0\f$. + * + * \param vars The current iteration's variables + */ + virtual void assembleLinearSystem(const Variables& vars) + { + assembleLinearSystem_(this->assembler(), vars); + + if (enablePartialReassembly_) + partialReassembler_->report(comm_, endIterMsgStream_); + } + + /*! + * \brief Solve the linear system of equations \f$\mathbf{A}x - b = 0\f$. + * + * Throws Dumux::NumericalProblem if the linear solver didn't + * converge. + * + * If the linear solver doesn't accept multitype matrices we copy the matrix + * into a 1x1 block BCRS matrix for solving. + * + * \param deltaU The difference between the current and the next solution + */ + void solveLinearSystem(SolutionVector& deltaU) + { + auto& b = this->assembler().residual(); + + try + { + if (numSteps_ == 0) + { + if constexpr (Detail::hasNorm<LinearSolver, SolutionVector>()) + initialResidual_ = this->linearSolver().norm(b); + + else + { + Scalar norm2 = b.two_norm2(); + if (comm_.size() > 1) + norm2 = comm_.sum(norm2); + + using std::sqrt; + initialResidual_ = sqrt(norm2); + } + } + + // solve by calling the appropriate implementation depending on whether the linear solver + // is capable of handling MultiType matrices or not + bool converged = solveLinearSystem_(deltaU); + + // make sure all processes converged + int convergedRemote = converged; + if (comm_.size() > 1) + convergedRemote = comm_.min(converged); + + if (!converged) { + DUNE_THROW(NumericalProblem, "Linear solver did not converge"); + ++numLinearSolverBreakdowns_; + } + else if (!convergedRemote) { + DUNE_THROW(NumericalProblem, "Linear solver did not converge on a remote process"); + ++numLinearSolverBreakdowns_; // we keep correct count for process 0 + } + } + catch (const Dune::Exception &e) { + // make sure all processes converged + int converged = 0; + if (comm_.size() > 1) + converged = comm_.min(converged); + + NumericalProblem p; + p.message(e.what()); + throw p; + } + } + + /*! + * \brief Update the current solution with a delta vector. + * + * The error estimates required for the newtonConverged() and + * newtonProceed() methods should be updated inside this method. + * + * Different update strategies, such as line search and chopped + * updates can be implemented. The default behavior is just to + * subtract deltaU from uLastIter, i.e. + * \f[ u^{k+1} = u^k - \Delta u^k \f] + * + * \param vars The variables after the current iteration + * \param uLastIter The solution vector after the last iteration + * \param deltaU The delta as calculated from solving the linear + * system of equations. This parameter also stores + * the updated solution. + */ + void newtonUpdate(Variables& vars, + const SolutionVector& uLastIter, + const SolutionVector& deltaU) + { + if (enableShiftCriterion_ || enablePartialReassembly_) + newtonUpdateShift_(uLastIter, deltaU); + + if (enablePartialReassembly_) { + // Determine the threshold 'eps' that is used for the partial reassembly. + // Every entity where the primary variables exhibit a relative shift + // summed up since the last linearization above 'eps' will be colored + // red yielding a reassembly. + // The user can provide three parameters to influence the threshold: + // 'minEps' by 'Newton.ReassemblyMinThreshold' (1e-1*shiftTolerance_ default) + // 'maxEps' by 'Newton.ReassemblyMaxThreshold' (1e2*shiftTolerance_ default) + // 'omega' by 'Newton.ReassemblyShiftWeight' (1e-3 default) + // The threshold is calculated from the currently achieved maximum + // relative shift according to the formula + // eps = max( minEps, min(maxEps, omega*shift) ). + // Increasing/decreasing 'minEps' leads to less/more reassembly if + // 'omega*shift' is small, i.e., for the last Newton iterations. + // Increasing/decreasing 'maxEps' leads to less/more reassembly if + // 'omega*shift' is large, i.e., for the first Newton iterations. + // Increasing/decreasing 'omega' leads to more/less first and last + // iterations in this sense. + using std::max; + using std::min; + auto reassemblyThreshold = max(reassemblyMinThreshold_, + min(reassemblyMaxThreshold_, + shift_*reassemblyShiftWeight_)); + + updateDistanceFromLastLinearization_(uLastIter, deltaU); + partialReassembler_->computeColors(this->assembler(), + distanceFromLastLinearization_, + reassemblyThreshold); + + // set the discrepancy of the red entities to zero + for (unsigned int i = 0; i < distanceFromLastLinearization_.size(); i++) + if (partialReassembler_->dofColor(i) == EntityColor::red) + distanceFromLastLinearization_[i] = 0; + } + + if (useLineSearch_) + lineSearchUpdate_(vars, uLastIter, deltaU); + + else if (useChop_) + choppedUpdate_(vars, uLastIter, deltaU); + + else + { + auto uCurrentIter = uLastIter; + uCurrentIter -= deltaU; + solutionChanged_(vars, uCurrentIter); + + if (enableResidualCriterion_) + computeResidualReduction_(vars); + } + } + + /*! + * \brief Indicates that one Newton iteration was finished. + * + * \param vars The variables after the current Newton iteration + * \param uLastIter The solution at the beginning of the current Newton iteration + */ + virtual void newtonEndStep(Variables &vars, + const SolutionVector &uLastIter) + { + if constexpr (hasPriVarsSwitch<PriVarSwitchVariables>) + { + if constexpr (assemblerExportsVariables) + priVarSwitchAdapter_->invoke(Backend::dofs(vars), vars); + else // this assumes assembly with solution (i.e. Variables=SolutionVector) + priVarSwitchAdapter_->invoke(vars, this->assembler().gridVariables()); + } + + ++numSteps_; + + if (verbosity_ >= 1) + { + if (enableDynamicOutput_) + std::cout << '\r'; // move cursor to beginning of line + + const auto width = Fmt::formatted_size("{}", maxSteps_); + std::cout << Fmt::format("Newton iteration {:{}} done", numSteps_, width); + + if (enableShiftCriterion_) + std::cout << Fmt::format(", maximum relative shift = {:.4e}", shift_); + if (enableResidualCriterion_ && enableAbsoluteResidualCriterion_) + std::cout << Fmt::format(", residual = {:.4e}", residualNorm_); + else if (enableResidualCriterion_) + std::cout << Fmt::format(", residual reduction = {:.4e}", reduction_); + + std::cout << endIterMsgStream_.str() << "\n"; + } + endIterMsgStream_.str(""); + + // When the Newton iterations are done: ask the model to check whether it makes sense + // TODO: how do we realize this? -> do this here in the Newton solver + // model_().checkPlausibility(); + } + + /*! + * \brief Called if the Newton method ended + * (not known yet if we failed or succeeded) + */ + virtual void newtonEnd() {} + + /*! + * \brief Returns true if the error of the solution is below the + * tolerance. + */ + virtual bool newtonConverged() const + { + // in case the model has a priVar switch and some some primary variables + // actually switched their state in the last iteration, enforce another iteration + if (priVarSwitchAdapter_->switched()) + return false; + + if (enableShiftCriterion_ && !enableResidualCriterion_) + { + return shift_ <= shiftTolerance_; + } + else if (!enableShiftCriterion_ && enableResidualCriterion_) + { + if(enableAbsoluteResidualCriterion_) + return residualNorm_ <= residualTolerance_; + else + return reduction_ <= reductionTolerance_; + } + else if (satisfyResidualAndShiftCriterion_) + { + if(enableAbsoluteResidualCriterion_) + return shift_ <= shiftTolerance_ + && residualNorm_ <= residualTolerance_; + else + return shift_ <= shiftTolerance_ + && reduction_ <= reductionTolerance_; + } + else if(enableShiftCriterion_ && enableResidualCriterion_) + { + if(enableAbsoluteResidualCriterion_) + return shift_ <= shiftTolerance_ + || residualNorm_ <= residualTolerance_; + else + return shift_ <= shiftTolerance_ + || reduction_ <= reductionTolerance_; + } + else + { + return shift_ <= shiftTolerance_ + || reduction_ <= reductionTolerance_ + || residualNorm_ <= residualTolerance_; + } + + return false; + } + + /*! + * \brief Called if the Newton method broke down. + * This method is called _after_ newtonEnd() + */ + virtual void newtonFail(Variables& u) {} + + /*! + * \brief Called if the Newton method ended successfully + * This method is called _after_ newtonEnd() + */ + virtual void newtonSucceed() {} + + /*! + * \brief output statistics / report + */ + void report(std::ostream& sout = std::cout) const + { + sout << '\n' + << "Newton statistics\n" + << "----------------------------------------------\n" + << "-- Total Newton iterations: " << totalWastedIter_ + totalSucceededIter_ << '\n' + << "-- Total wasted Newton iterations: " << totalWastedIter_ << '\n' + << "-- Total succeeded Newton iterations: " << totalSucceededIter_ << '\n' + << "-- Average iterations per solve: " << std::setprecision(3) << double(totalSucceededIter_) / double(numConverged_) << '\n' + << "-- Number of linear solver breakdowns: " << numLinearSolverBreakdowns_ << '\n' + << std::endl; + } + + /*! + * \brief reset the statistics + */ + void resetReport() + { + totalWastedIter_ = 0; + totalSucceededIter_ = 0; + numConverged_ = 0; + numLinearSolverBreakdowns_ = 0; + } + + /*! + * \brief Report the options and parameters this Newton is configured with + */ + void reportParams(std::ostream& sout = std::cout) const + { + sout << "\nNewton solver configured with the following options and parameters:\n"; + // options + if (useLineSearch_) sout << " -- Newton.UseLineSearch = true\n"; + if (useChop_) sout << " -- Newton.EnableChop = true\n"; + if (enablePartialReassembly_) sout << " -- Newton.EnablePartialReassembly = true\n"; + if (enableAbsoluteResidualCriterion_) sout << " -- Newton.EnableAbsoluteResidualCriterion = true\n"; + if (enableShiftCriterion_) sout << " -- Newton.EnableShiftCriterion = true (relative shift convergence criterion)\n"; + if (enableResidualCriterion_) sout << " -- Newton.EnableResidualCriterion = true\n"; + if (satisfyResidualAndShiftCriterion_) sout << " -- Newton.SatisfyResidualAndShiftCriterion = true\n"; + // parameters + if (enableShiftCriterion_) sout << " -- Newton.MaxRelativeShift = " << shiftTolerance_ << '\n'; + if (enableAbsoluteResidualCriterion_) sout << " -- Newton.MaxAbsoluteResidual = " << residualTolerance_ << '\n'; + if (enableResidualCriterion_) sout << " -- Newton.ResidualReduction = " << reductionTolerance_ << '\n'; + sout << " -- Newton.MinSteps = " << minSteps_ << '\n'; + sout << " -- Newton.MaxSteps = " << maxSteps_ << '\n'; + sout << " -- Newton.TargetSteps = " << targetSteps_ << '\n'; + if (enablePartialReassembly_) + { + sout << " -- Newton.ReassemblyMinThreshold = " << reassemblyMinThreshold_ << '\n'; + sout << " -- Newton.ReassemblyMaxThreshold = " << reassemblyMaxThreshold_ << '\n'; + sout << " -- Newton.ReassemblyShiftWeight = " << reassemblyShiftWeight_ << '\n'; + } + sout << " -- Newton.RetryTimeStepReductionFactor = " << retryTimeStepReductionFactor_ << '\n'; + sout << " -- Newton.MaxTimeStepDivisions = " << maxTimeStepDivisions_ << '\n'; + sout << std::endl; + } + + /*! + * \brief Suggest a new time-step size based on the old time-step + * size. + * + * The default behavior is to suggest the old time-step size + * scaled by the ratio between the target iterations and the + * iterations required to actually solve the last time-step. + */ + Scalar suggestTimeStepSize(Scalar oldTimeStep) const + { + // be aggressive reducing the time-step size but + // conservative when increasing it. the rationale is + // that we want to avoid failing in the next Newton + // iteration which would require another linearization + // of the problem. + if (numSteps_ > targetSteps_) { + Scalar percent = Scalar(numSteps_ - targetSteps_)/targetSteps_; + return oldTimeStep/(1.0 + percent); + } + + Scalar percent = Scalar(targetSteps_ - numSteps_)/targetSteps_; + return oldTimeStep*(1.0 + percent/1.2); + } + + /*! + * \brief Specifies the verbosity level + */ + void setVerbosity(int val) + { verbosity_ = val; } + + /*! + * \brief Return the verbosity level + */ + int verbosity() const + { return verbosity_ ; } + + /*! + * \brief Returns the parameter group + */ + const std::string& paramGroup() const + { return paramGroup_; } + + /*! + * \brief Attach a convergence writer to write out intermediate results after each iteration + */ + void attachConvergenceWriter(std::shared_ptr<ConvergenceWriter> convWriter) + { convergenceWriter_ = convWriter; } + + /*! + * \brief Detach the convergence writer to stop the output + */ + void detachConvergenceWriter() + { convergenceWriter_ = nullptr; } + + /*! + * \brief Return the factor for reducing the time step after a Newton iteration has failed + */ + Scalar retryTimeStepReductionFactor() const + { return retryTimeStepReductionFactor_; } + + /*! + * \brief Set the factor for reducing the time step after a Newton iteration has failed + */ + void setRetryTimeStepReductionFactor(const Scalar factor) + { retryTimeStepReductionFactor_ = factor; } + +protected: + + /*! + * \brief Update solution-dependent quantities like grid variables after the solution has changed. + * \todo TODO: In case we stop support for old-style grid variables / assemblers at one point, + * this would become obsolete as only the update call to the backend would remain. + */ + virtual void solutionChanged_(Variables& vars, const SolutionVector& uCurrentIter) + { + Backend::update(vars, uCurrentIter); + + if constexpr (!assemblerExportsVariables) + this->assembler().updateGridVariables(Backend::dofs(vars)); + } + + void computeResidualReduction_(const Variables& vars) + { + // we assume that the assembler works on solution vectors + // if it doesn't export the variables type + if constexpr (Detail::hasNorm<LinearSolver, SolutionVector>()) + { + if constexpr (!assemblerExportsVariables) + this->assembler().assembleResidual(Backend::dofs(vars)); + else + this->assembler().assembleResidual(vars); + residualNorm_ = this->linearSolver().norm(this->assembler().residual()); + } + else + { + if constexpr (!assemblerExportsVariables) + residualNorm_ = this->assembler().residualNorm(Backend::dofs(vars)); + else + residualNorm_ = this->assembler().residualNorm(vars); + } + + reduction_ = residualNorm_; + reduction_ /= initialResidual_; + } + + bool enableResidualCriterion() const + { return enableResidualCriterion_; } + + //! optimal number of iterations we want to achieve + int targetSteps_; + //! minimum number of iterations we do + int minSteps_; + //! maximum number of iterations we do before giving up + int maxSteps_; + //! actual number of steps done so far + int numSteps_; + + // residual criterion variables + Scalar reduction_; + Scalar residualNorm_; + Scalar lastReduction_; + Scalar initialResidual_; + + // shift criterion variables + Scalar shift_; + Scalar lastShift_; + + //! message stream to be displayed at the end of iterations + std::ostringstream endIterMsgStream_; + + +private: + + /*! + * \brief Run the Newton method to solve a non-linear system. + * The solver is responsible for all the strategic decisions. + */ + bool solve_(Variables& vars) + { + try + { + // newtonBegin may manipulate the solution + newtonBegin(vars); + + // the given solution is the initial guess + auto uLastIter = Backend::dofs(vars); + auto deltaU = Backend::dofs(vars); + + // setup timers + Dune::Timer assembleTimer(false); + Dune::Timer solveTimer(false); + Dune::Timer updateTimer(false); + + // execute the method as long as the solver thinks + // that we should do another iteration + bool converged = false; + while (newtonProceed(vars, converged)) + { + // notify the solver that we're about to start + // a new iteration + newtonBeginStep(vars); + + // make the current solution to the old one + if (numSteps_ > 0) + uLastIter = Backend::dofs(vars); + + if (verbosity_ >= 1 && enableDynamicOutput_) + std::cout << "Assemble: r(x^k) = dS/dt + div F - q; M = grad r" + << std::flush; + + /////////////// + // assemble + /////////////// + + // linearize the problem at the current solution + assembleTimer.start(); + assembleLinearSystem(vars); + assembleTimer.stop(); + + bool outputMatrices = getParam<bool>("Newton.OutputMatrices", false); + if (outputMatrices) + { + std::string filename0_0 = "jacobian_0_0"; + std::string filename0_1 = "jacobian_0_1"; + std::string filename1_0 = "jacobian_1_0"; + std::string filename1_1 = "jacobian_1_1"; + std::string folderName = getParam<std::string>("Problem.Name",""); + if(!folderName.empty()) + { + folderName+="/"; + } + std::filesystem::create_directory(folderName); + std::ofstream s; + s.open(folderName+filename0_0 + ".csv"); + writeSparseMatrixToCSV(s, (this->assembler()).jacobian()[Dune::index_constant<0>()][Dune::index_constant<0>()]); + s.close(); + s.open(folderName+filename0_1 + ".csv"); + writeSparseMatrixToCSV(s, (this->assembler()).jacobian()[Dune::index_constant<0>()][Dune::index_constant<1>()]); + s.close(); + s.open(folderName+filename1_0 + ".csv"); + writeSparseMatrixToCSV(s, (this->assembler()).jacobian()[Dune::index_constant<1>()][Dune::index_constant<0>()]); + s.close(); + s.open(folderName+filename1_1 + ".csv"); + writeSparseMatrixToCSV(s, (this->assembler()).jacobian()[Dune::index_constant<1>()][Dune::index_constant<1>()]); + s.close(); + + // Dune::printSparseMatrix(myfile, (this->assembler()).jacobian()[Dune::index_constant<0>()][Dune::index_constant<0>()], "", ""); + // Dune::printSparseMatrix(myfile, (this->assembler()).jacobian()[Dune::index_constant<0>()][Dune::index_constant<1>()], "", ""); + // Dune::printSparseMatrix(myfile, (this->assembler()).jacobian()[Dune::index_constant<1>()][Dune::index_constant<0>()], "", ""); + // Dune::printSparseMatrix(myfile, (this->assembler()).jacobian()[Dune::index_constant<1>()][Dune::index_constant<1>()], "", ""); + std::string filename0 = "residual_0"; + std::string filename1 = "residual_1"; + s.open(folderName+filename0 + ".csv"); + writeVectorToCSV(s, (this->assembler()).residual()[Dune::index_constant<0>()]); + s.close(); + s.open(folderName+filename1 + ".csv"); + writeVectorToCSV(s, (this->assembler()).residual()[Dune::index_constant<1>()]); + s.close(); + + std::string filenamevars0 = "initialsol_0"; + s.open(folderName+filenamevars0 + ".csv"); + writeVectorToCSV(s, vars[Dune::index_constant<0>()], 6); + s.close(); + std::string filenamevars1 = "initialsol_1"; + s.open(folderName+filenamevars1 + ".csv"); + writeVectorToCSV(s, vars[Dune::index_constant<1>()], 6); + s.close(); + // Dune::printvector(std::cout, (this->assembler()).residual()[Dune::index_constant<0>()], "Residual velocities", ""); + // Dune::printvector(std::cout, (this->assembler()).residual()[Dune::index_constant<1>()], "Residual pressures", ""); + // Dune::printvector(std::cout, vars[Dune::index_constant<0>()], "X velocities", ""); + // Dune::printvector(std::cout, vars[Dune::index_constant<1>()], "X pressures", ""); + } + + /////////////// + // linear solve + /////////////// + + // Clear the current line using an ansi escape + // sequence. for an explanation see + // http://en.wikipedia.org/wiki/ANSI_escape_code + const char clearRemainingLine[] = { 0x1b, '[', 'K', 0 }; + + if (verbosity_ >= 1 && enableDynamicOutput_) + std::cout << "\rSolve: M deltax^k = r" + << clearRemainingLine << std::flush; + + // solve the resulting linear equation system + solveTimer.start(); + + // set the delta vector to zero before solving the linear system! + deltaU = 0; + + solveLinearSystem(deltaU); + solveTimer.stop(); + + /////////////// + // update + /////////////// + if (verbosity_ >= 1 && enableDynamicOutput_) + std::cout << "\rUpdate: x^(k+1) = x^k - deltax^k" + << clearRemainingLine << std::flush; + + updateTimer.start(); + // update the current solution (i.e. uOld) with the delta + // (i.e. u). The result is stored in u + newtonUpdate(vars, uLastIter, deltaU); + updateTimer.stop(); + + // tell the solver that we're done with this iteration + newtonEndStep(vars, uLastIter); + + // if a convergence writer was specified compute residual and write output + if (convergenceWriter_) + { + this->assembler().assembleResidual(vars); + convergenceWriter_->write(Backend::dofs(vars), deltaU, this->assembler().residual()); + } + + bool exitNewtonAfterFirst = getParam<bool>("Newton.ExitAfterFirstIteration", false); + bool exitNewtonAfterSecond = getParam<int>("Newton.ExitAfterIteration", -1) == numSteps_; + if(exitNewtonAfterFirst || exitNewtonAfterSecond) + { + std::ofstream s; + std::string filename0 = "updatedresidual_0"; + std::string filename1 = "updatedresidual_1"; + std::string folderName = getParam<std::string>("Problem.Name",""); + if(!folderName.empty()) + { + folderName+="/"; + } + s.open(folderName+filename0 + ".csv"); + writeVectorToCSV(s, (this->assembler()).residual()[Dune::index_constant<0>()]); + s.close(); + s.open(folderName+filename1 + ".csv"); + writeVectorToCSV(s, (this->assembler()).residual()[Dune::index_constant<1>()]); + s.close(); + + std::string filenamevars0 = "initialsol_updated_0"; + s.open(folderName+filenamevars0 + ".csv"); + writeVectorToCSV(s, vars[Dune::index_constant<0>()], 6); + s.close(); + std::string filenamevars1 = "initialsol_updated_1"; + s.open(folderName+filenamevars1 + ".csv"); + writeVectorToCSV(s, vars[Dune::index_constant<1>()], 6); + s.close(); + + exit(0); + } + + // detect if the method has converged + converged = newtonConverged(); + } + + // tell solver we are done + newtonEnd(); + + // reset state if Newton failed + if (!newtonConverged()) + { + totalWastedIter_ += numSteps_; + newtonFail(vars); + return false; + } + + totalSucceededIter_ += numSteps_; + numConverged_++; + + // tell solver we converged successfully + newtonSucceed(); + + if (verbosity_ >= 1) { + const auto elapsedTot = assembleTimer.elapsed() + solveTimer.elapsed() + updateTimer.elapsed(); + std::cout << Fmt::format("Assemble/solve/update time: {:.2g}({:.2f}%)/{:.2g}({:.2f}%)/{:.2g}({:.2f}%)\n", + assembleTimer.elapsed(), 100*assembleTimer.elapsed()/elapsedTot, + solveTimer.elapsed(), 100*solveTimer.elapsed()/elapsedTot, + updateTimer.elapsed(), 100*updateTimer.elapsed()/elapsedTot); + } + return true; + + } + catch (const NumericalProblem &e) + { + if (verbosity_ >= 1) + std::cout << "Newton: Caught exception: \"" << e.what() << "\"\n"; + + totalWastedIter_ += numSteps_; + + newtonFail(vars); + return false; + } + } + + //! assembleLinearSystem_ for assemblers that support partial reassembly + template<class A> + auto assembleLinearSystem_(const A& assembler, const Variables& vars) + -> typename std::enable_if_t<decltype(isValid(Detail::supportsPartialReassembly())(assembler))::value, void> + { + this->assembler().assembleJacobianAndResidual(vars, partialReassembler_.get()); + } + + //! assembleLinearSystem_ for assemblers that don't support partial reassembly + template<class A> + auto assembleLinearSystem_(const A& assembler, const Variables& vars) + -> typename std::enable_if_t<!decltype(isValid(Detail::supportsPartialReassembly())(assembler))::value, void> + { + this->assembler().assembleJacobianAndResidual(vars); + } + + /*! + * \brief Update the maximum relative shift of the solution compared to + * the previous iteration. Overload for "normal" solution vectors. + * + * \param uLastIter The current iterative solution + * \param deltaU The difference between the current and the next solution + */ + virtual void newtonUpdateShift_(const SolutionVector &uLastIter, + const SolutionVector &deltaU) + { + auto uNew = uLastIter; + uNew -= deltaU; + shift_ = Detail::maxRelativeShift<Scalar>(uLastIter, uNew); + + if (comm_.size() > 1) + shift_ = comm_.max(shift_); + } + + virtual void lineSearchUpdate_(Variables &vars, + const SolutionVector &uLastIter, + const SolutionVector &deltaU) + { + Scalar lambda = 1.0; + auto uCurrentIter = uLastIter; + + while (true) + { + Backend::axpy(-lambda, deltaU, uCurrentIter); + solutionChanged_(vars, uCurrentIter); + + computeResidualReduction_(vars); + + if (reduction_ < lastReduction_ || lambda <= lineSearchMinRelaxationFactor_) + { + endIterMsgStream_ << Fmt::format(", residual reduction {:.4e}->{:.4e}@lambda={:.4f}", lastReduction_, reduction_, lambda); + return; + } + + // try with a smaller update and reset solution + lambda *= 0.5; + uCurrentIter = uLastIter; + } + } + + //! \note method must update the gridVariables, too! + virtual void choppedUpdate_(Variables& vars, + const SolutionVector& uLastIter, + const SolutionVector& deltaU) + { + DUNE_THROW(Dune::NotImplemented, + "Chopped Newton update strategy not implemented."); + } + + virtual bool solveLinearSystem_(SolutionVector& deltaU) + { + return solveLinearSystemImpl_(this->linearSolver(), + this->assembler().jacobian(), + deltaU, + this->assembler().residual()); + } + + /*! + * \brief Solve the linear system of equations \f$\mathbf{A}x - b = 0\f$. + * + * Throws Dumux::NumericalProblem if the linear solver didn't + * converge. + * + * Specialization for regular vector types (not MultiTypeBlockVector) + * + */ + template<class V = SolutionVector> + typename std::enable_if_t<!isMultiTypeBlockVector<V>(), bool> + solveLinearSystemImpl_(LinearSolver& ls, + JacobianMatrix& A, + SolutionVector& x, + SolutionVector& b) + { + //! Copy into a standard block vector. + //! This is necessary for all model _not_ using a FieldVector<Scalar, blockSize> as + //! primary variables vector in combination with UMFPack or SuperLU as their interfaces are hard coded + //! to this field vector type in Dune ISTL + //! Could be avoided for vectors that already have the right type using SFINAE + //! but it shouldn't impact performance too much + using OriginalBlockType = Detail::BlockType<SolutionVector>; + constexpr auto blockSize = Detail::blockSize<OriginalBlockType>(); + + using BlockType = Dune::FieldVector<Scalar, blockSize>; + Dune::BlockVector<BlockType> xTmp; xTmp.resize(Backend::size(b)); + Dune::BlockVector<BlockType> bTmp(xTmp); + + Detail::assign(bTmp, b); + const int converged = ls.solve(A, xTmp, bTmp); + Detail::assign(x, xTmp); + + return converged; + } + + + /*! + * \brief Solve the linear system of equations \f$\mathbf{A}x - b = 0\f$. + * + * Throws Dumux::NumericalProblem if the linear solver didn't + * converge. + * + * Specialization for linear solvers that can handle MultiType matrices. + * + */ + template<class LS = LinearSolver, class V = SolutionVector> + typename std::enable_if_t<linearSolverAcceptsMultiTypeMatrix<LS>() && + isMultiTypeBlockVector<V>(), bool> + solveLinearSystemImpl_(LinearSolver& ls, + JacobianMatrix& A, + SolutionVector& x, + SolutionVector& b) + { + assert(this->checkSizesOfSubMatrices(A) && "Sub-blocks of MultiTypeBlockMatrix have wrong sizes!"); + return ls.solve(A, x, b); + } + + /*! + * \brief Solve the linear system of equations \f$\mathbf{A}x - b = 0\f$. + * + * Throws Dumux::NumericalProblem if the linear solver didn't + * converge. + * + * Specialization for linear solvers that cannot handle MultiType matrices. + * We copy the matrix into a 1x1 block BCRS matrix before solving. + * + */ + template<class LS = LinearSolver, class V = SolutionVector> + typename std::enable_if_t<!linearSolverAcceptsMultiTypeMatrix<LS>() && + isMultiTypeBlockVector<V>(), bool> + solveLinearSystemImpl_(LinearSolver& ls, + JacobianMatrix& A, + SolutionVector& x, + SolutionVector& b) + { + assert(this->checkSizesOfSubMatrices(A) && "Sub-blocks of MultiTypeBlockMatrix have wrong sizes!"); + + // create the bcrs matrix the IterativeSolver backend can handle + const auto M = MatrixConverter<JacobianMatrix>::multiTypeToBCRSMatrix(A); + + // get the new matrix sizes + const std::size_t numRows = M.N(); + assert(numRows == M.M()); + + // create the vector the IterativeSolver backend can handle + const auto bTmp = VectorConverter<SolutionVector>::multiTypeToBlockVector(b); + assert(bTmp.size() == numRows); + + // create a blockvector to which the linear solver writes the solution + using VectorBlock = typename Dune::FieldVector<Scalar, 1>; + using BlockVector = typename Dune::BlockVector<VectorBlock>; + BlockVector y(numRows); + + // solve + const bool converged = ls.solve(M, y, bTmp); + + // copy back the result y into x + if(converged) + VectorConverter<SolutionVector>::retrieveValues(x, y); + + return converged; + } + + //! initialize the parameters by reading from the parameter tree + void initParams_(const std::string& group = "") + { + useLineSearch_ = getParamFromGroup<bool>(group, "Newton.UseLineSearch", false); + lineSearchMinRelaxationFactor_ = getParamFromGroup<Scalar>(group, "Newton.LineSearchMinRelaxationFactor", 0.125); + useChop_ = getParamFromGroup<bool>(group, "Newton.EnableChop", false); + if(useLineSearch_ && useChop_) + DUNE_THROW(Dune::InvalidStateException, "Use either linesearch OR chop!"); + + enableAbsoluteResidualCriterion_ = getParamFromGroup<bool>(group, "Newton.EnableAbsoluteResidualCriterion", false); + enableShiftCriterion_ = getParamFromGroup<bool>(group, "Newton.EnableShiftCriterion", true); + enableResidualCriterion_ = getParamFromGroup<bool>(group, "Newton.EnableResidualCriterion", false) || enableAbsoluteResidualCriterion_; + satisfyResidualAndShiftCriterion_ = getParamFromGroup<bool>(group, "Newton.SatisfyResidualAndShiftCriterion", false); + enableDynamicOutput_ = getParamFromGroup<bool>(group, "Newton.EnableDynamicOutput", true); + + if (!enableShiftCriterion_ && !enableResidualCriterion_) + { + DUNE_THROW(Dune::NotImplemented, + "at least one of NewtonEnableShiftCriterion or " + << "NewtonEnableResidualCriterion has to be set to true"); + } + + setMaxRelativeShift(getParamFromGroup<Scalar>(group, "Newton.MaxRelativeShift", 1e-8)); + setMaxAbsoluteResidual(getParamFromGroup<Scalar>(group, "Newton.MaxAbsoluteResidual", 1e-5)); + setResidualReduction(getParamFromGroup<Scalar>(group, "Newton.ResidualReduction", 1e-5)); + setTargetSteps(getParamFromGroup<int>(group, "Newton.TargetSteps", 10)); + setMinSteps(getParamFromGroup<int>(group, "Newton.MinSteps", 2)); + setMaxSteps(getParamFromGroup<int>(group, "Newton.MaxSteps", 18)); + + enablePartialReassembly_ = getParamFromGroup<bool>(group, "Newton.EnablePartialReassembly", false); + reassemblyMinThreshold_ = getParamFromGroup<Scalar>(group, "Newton.ReassemblyMinThreshold", 1e-1*shiftTolerance_); + reassemblyMaxThreshold_ = getParamFromGroup<Scalar>(group, "Newton.ReassemblyMaxThreshold", 1e2*shiftTolerance_); + reassemblyShiftWeight_ = getParamFromGroup<Scalar>(group, "Newton.ReassemblyShiftWeight", 1e-3); + + maxTimeStepDivisions_ = getParamFromGroup<std::size_t>(group, "Newton.MaxTimeStepDivisions", 10); + retryTimeStepReductionFactor_ = getParamFromGroup<Scalar>(group, "Newton.RetryTimeStepReductionFactor", 0.5); + + verbosity_ = comm_.rank() == 0 ? getParamFromGroup<int>(group, "Newton.Verbosity", 2) : 0; + numSteps_ = 0; + + // output a parameter report + if (verbosity_ >= 2) + reportParams(); + } + + template<class Sol> + void updateDistanceFromLastLinearization_(const Sol& u, const Sol& uDelta) + { + if constexpr (Dune::IsNumber<Sol>::value) + { + auto nextPriVars = u; + nextPriVars -= uDelta; + + // add the current relative shift for this degree of freedom + auto shift = Detail::maxRelativeShift<Scalar>(u, nextPriVars); + distanceFromLastLinearization_[0] += shift; + } + else + { + for (std::size_t i = 0; i < u.size(); ++i) + { + const auto& currentPriVars(u[i]); + auto nextPriVars(currentPriVars); + nextPriVars -= uDelta[i]; + + // add the current relative shift for this degree of freedom + auto shift = Detail::maxRelativeShift<Scalar>(currentPriVars, nextPriVars); + distanceFromLastLinearization_[i] += shift; + } + } + } + + template<class ...Args> + void updateDistanceFromLastLinearization_(const Dune::MultiTypeBlockVector<Args...>& uLastIter, + const Dune::MultiTypeBlockVector<Args...>& deltaU) + { + DUNE_THROW(Dune::NotImplemented, "Reassembly for MultiTypeBlockVector"); + } + + template<class Sol> + void resizeDistanceFromLastLinearization_(const Sol& u, std::vector<Scalar>& dist) + { + dist.assign(Backend::size(u), 0.0); + } + + template<class ...Args> + void resizeDistanceFromLastLinearization_(const Dune::MultiTypeBlockVector<Args...>& u, + std::vector<Scalar>& dist) + { + DUNE_THROW(Dune::NotImplemented, "Reassembly for MultiTypeBlockVector"); + } + + //! The communication object + Communication comm_; + + //! the verbosity level + int verbosity_; + + Scalar shiftTolerance_; + Scalar reductionTolerance_; + Scalar residualTolerance_; + + // time step control + std::size_t maxTimeStepDivisions_; + Scalar retryTimeStepReductionFactor_; + + // further parameters + bool useLineSearch_; + Scalar lineSearchMinRelaxationFactor_; + bool useChop_; + bool enableAbsoluteResidualCriterion_; + bool enableShiftCriterion_; + bool enableResidualCriterion_; + bool satisfyResidualAndShiftCriterion_; + bool enableDynamicOutput_; + + //! the parameter group for getting parameters from the parameter tree + std::string paramGroup_; + + // infrastructure for partial reassembly + bool enablePartialReassembly_; + std::unique_ptr<Reassembler> partialReassembler_; + std::vector<Scalar> distanceFromLastLinearization_; + Scalar reassemblyMinThreshold_; + Scalar reassemblyMaxThreshold_; + Scalar reassemblyShiftWeight_; + + // statistics for the optional report + std::size_t totalWastedIter_ = 0; //! Newton steps in solves that didn't converge + std::size_t totalSucceededIter_ = 0; //! Newton steps in solves that converged + std::size_t numConverged_ = 0; //! total number of converged solves + std::size_t numLinearSolverBreakdowns_ = 0; //! total number of linear solves that failed + + //! the class handling the primary variable switch + std::unique_ptr<PrimaryVariableSwitchAdapter> priVarSwitchAdapter_; + + //! convergence writer + std::shared_ptr<ConvergenceWriter> convergenceWriter_ = nullptr; +}; + +} // end namespace Dumux + +#endif -- GitLab From add61a8f2d0f4b14a28eeed242dbcf8f86d3c87f Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Mon, 20 Sep 2021 13:27:34 +0300 Subject: [PATCH 45/69] [convergence] cell center coupling fix illogical factors were introduced by me for some reason removed some output for cell center residual --- dumux/assembly/cvdstaggeredrefinedlocalresidual.hh | 14 +------------- .../cvdsubdomainstaggeredlocalassembler.hh | 2 +- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/dumux/assembly/cvdstaggeredrefinedlocalresidual.hh b/dumux/assembly/cvdstaggeredrefinedlocalresidual.hh index 386d94e..8227b48 100644 --- a/dumux/assembly/cvdstaggeredrefinedlocalresidual.hh +++ b/dumux/assembly/cvdstaggeredrefinedlocalresidual.hh @@ -87,24 +87,12 @@ public: for (auto&& scv : scvs(fvGeometry)) asImp().evalSourceForCellCenter(residual, this->problem(), element, fvGeometry, elemVolVars, elemFaceVars, scv); - auto ctr = element.geometry().center(); - bool writeOut = false;//(ctr[0] > 0.35 && ctr[0] < 0.45 && ctr[1] > 0.45 && ctr[1] < 0.55); - if (writeOut) - { - std::cout << "Printing mass residual for volume X: " << ctr[0] << " Y: " << ctr[1] << std::endl; - } // evaluate the flux term for (auto&& scvf : scvfs(fvGeometry)) { - asImp().evalFluxForCellCenter(residual, this->problem(), element, fvGeometry, cellCenterIdx, elemVolVars, elemFaceVars, elemLocalFaceVars, bcTypes, elemFluxVarsCache, scvf, writeOut); - if(writeOut) - { - auto normal = scvf.unitOuterNormal(); - std::cout<<"Coarse volume residual for normal X: "<<normal[0]<<" Y: "<< normal[1]<< " R: "<<residual<<std::endl; - } + asImp().evalFluxForCellCenter(residual, this->problem(), element, fvGeometry, cellCenterIdx, elemVolVars, elemFaceVars, elemLocalFaceVars, bcTypes, elemFluxVarsCache, scvf); } - return residual; } diff --git a/dumux/multidomain/cvdsubdomainstaggeredlocalassembler.hh b/dumux/multidomain/cvdsubdomainstaggeredlocalassembler.hh index 65af17f..94e9f8d 100644 --- a/dumux/multidomain/cvdsubdomainstaggeredlocalassembler.hh +++ b/dumux/multidomain/cvdsubdomainstaggeredlocalassembler.hh @@ -866,7 +866,7 @@ public: epsCoupl(faceSolution[globalJ][pvIdx], pvIdx), numDiffMethod); //multiply with factor if it is a transition from fine to coarse - partialDeriv *= origFaceSolution.factor(globalJ); + // partialDeriv *= origFaceSolution.factor(globalJ); // update the global jacobian matrix with the current partial derivatives updateGlobalJacobian_(A, cellCenterGlobalI, globalJ, pvIdx, partialDeriv); -- GitLab From 168a7776933f134939f8a8ac1ef6e7d9f902ac38 Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Tue, 21 Sep 2021 10:10:32 +0300 Subject: [PATCH 46/69] Some param changes --- .../channel/2d/params_navierstokes_stationary.input | 2 +- appl/freeflow/navierstokes/sincos/params_vdP_full.input | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/appl/freeflow/navierstokes/channel/2d/params_navierstokes_stationary.input b/appl/freeflow/navierstokes/channel/2d/params_navierstokes_stationary.input index 968f8d2..3824dfa 100644 --- a/appl/freeflow/navierstokes/channel/2d/params_navierstokes_stationary.input +++ b/appl/freeflow/navierstokes/channel/2d/params_navierstokes_stationary.input @@ -37,7 +37,7 @@ LiquidKinematicViscosity = 1 [ Newton ] MaxSteps = 100 -MaxRelativeShift = 1e-4 +MaxRelativeShift = 1e-8 SatisfyResidualAndShiftCriterion = true EnableAbsoluteResidualCriterion = true diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_full.input b/appl/freeflow/navierstokes/sincos/params_vdP_full.input index 783e870..4aacaa1 100644 --- a/appl/freeflow/navierstokes/sincos/params_vdP_full.input +++ b/appl/freeflow/navierstokes/sincos/params_vdP_full.input @@ -32,11 +32,11 @@ File = coarseyCVs.dgf File = grid.dgf [Problem] -Name = test_ff_sincos_vdP_full_42_bigresidual +Name = test_ff_sincos_vdP_full EnableGravity = false PrintErrors = true EnableInertiaTerms = true -IsStationary = false +IsStationary = true VanDerPlasVersion = true StartWithAnalytical = false AveragedAnalyticalSolution = true @@ -71,8 +71,6 @@ UpwindWeight = 0.5 NewParallelAlgo = false UseOwn4PointCoefficients = false Conservation = false -LinearInterpolation = false -DebugDof = -1 Adapt = true LeftX = .4 RightX = .6 -- GitLab From aa86acc4a1a70cc5e756392d02058925948f5cf0 Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Tue, 21 Sep 2021 10:22:11 +0300 Subject: [PATCH 47/69] Preparations for sincos convergence --- .../navierstokes/sincos/CMakeLists.txt | 2 - .../sincos/params_vdP_full_c120.input | 78 +++++++++++++++++++ .../sincos/params_vdP_full_c20.input | 78 +++++++++++++++++++ .../sincos/params_vdP_full_c40.input | 78 +++++++++++++++++++ .../sincos/params_vdP_full_c80.input | 78 +++++++++++++++++++ 5 files changed, 312 insertions(+), 2 deletions(-) create mode 100644 appl/freeflow/navierstokes/sincos/params_vdP_full_c120.input create mode 100644 appl/freeflow/navierstokes/sincos/params_vdP_full_c20.input create mode 100644 appl/freeflow/navierstokes/sincos/params_vdP_full_c40.input create mode 100644 appl/freeflow/navierstokes/sincos/params_vdP_full_c80.input diff --git a/appl/freeflow/navierstokes/sincos/CMakeLists.txt b/appl/freeflow/navierstokes/sincos/CMakeLists.txt index 98ad3fb..2aafdb5 100644 --- a/appl/freeflow/navierstokes/sincos/CMakeLists.txt +++ b/appl/freeflow/navierstokes/sincos/CMakeLists.txt @@ -1,5 +1,3 @@ -set(CMAKE_BUILD_TYPE Debug) - add_input_file_links() dune_add_test(NAME test_ff_sincos diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_full_c120.input b/appl/freeflow/navierstokes/sincos/params_vdP_full_c120.input new file mode 100644 index 0000000..a8674fb --- /dev/null +++ b/appl/freeflow/navierstokes/sincos/params_vdP_full_c120.input @@ -0,0 +1,78 @@ +[TimeLoop] +DtInitial = 0.01 # [s] +TEnd = 1.0 # [s] + +[Helper.Grid] +Positions0 = 0.25 0.75 +Positions1 = 0.25 0.75 #we don't have symmetry BCs +Cells0 = 120 +Cells1 = 120 +Grading0 = 1.0 +Grading1 = 1.0 + +[xCVs.Grid] +File = xCVs.dgf + +[yCVs.Grid] +File = yCVs.dgf + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_ff_sincos_vdP_full_c120 +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +VanDerPlasVersion = true +StartWithAnalytical = false +AveragedAnalyticalSolution = true +UseScvfLineAveraging = true + +[Component] +LiquidDensity = 1.0 +LiquidKinematicViscosity = 0.05 +MolarMass = 1.0 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +[Newton] +MaxSteps = 10 +TargetSteps = 4 +MaxRelativeShift = 1e-5 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true +MaxAbsoluteResidual = 1e-5 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = false +AddProcessRank = false + +[Flux] +UpwindWeight = 0.5 + +[Adaptivity] +NewParallelAlgo = false +UseOwn4PointCoefficients = false +Conservation = false +Adapt = true +LeftX = .4 +RightX = .6 +LowerY = .4 +UpperY = .6 diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_full_c20.input b/appl/freeflow/navierstokes/sincos/params_vdP_full_c20.input new file mode 100644 index 0000000..d6cd26e --- /dev/null +++ b/appl/freeflow/navierstokes/sincos/params_vdP_full_c20.input @@ -0,0 +1,78 @@ +[TimeLoop] +DtInitial = 0.01 # [s] +TEnd = 1.0 # [s] + +[Helper.Grid] +Positions0 = 0.25 0.75 +Positions1 = 0.25 0.75 #we don't have symmetry BCs +Cells0 = 20 +Cells1 = 20 +Grading0 = 1.0 +Grading1 = 1.0 + +[xCVs.Grid] +File = xCVs.dgf + +[yCVs.Grid] +File = yCVs.dgf + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_ff_sincos_vdP_full_c20 +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +VanDerPlasVersion = true +StartWithAnalytical = false +AveragedAnalyticalSolution = true +UseScvfLineAveraging = true + +[Component] +LiquidDensity = 1.0 +LiquidKinematicViscosity = 0.05 +MolarMass = 1.0 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +[Newton] +MaxSteps = 10 +TargetSteps = 4 +MaxRelativeShift = 1e-5 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true +MaxAbsoluteResidual = 1e-5 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = false +AddProcessRank = false + +[Flux] +UpwindWeight = 0.5 + +[Adaptivity] +NewParallelAlgo = false +UseOwn4PointCoefficients = false +Conservation = false +Adapt = true +LeftX = .4 +RightX = .6 +LowerY = .4 +UpperY = .6 diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_full_c40.input b/appl/freeflow/navierstokes/sincos/params_vdP_full_c40.input new file mode 100644 index 0000000..47de437 --- /dev/null +++ b/appl/freeflow/navierstokes/sincos/params_vdP_full_c40.input @@ -0,0 +1,78 @@ +[TimeLoop] +DtInitial = 0.01 # [s] +TEnd = 1.0 # [s] + +[Helper.Grid] +Positions0 = 0.25 0.75 +Positions1 = 0.25 0.75 #we don't have symmetry BCs +Cells0 = 40 +Cells1 = 40 +Grading0 = 1.0 +Grading1 = 1.0 + +[xCVs.Grid] +File = xCVs.dgf + +[yCVs.Grid] +File = yCVs.dgf + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_ff_sincos_vdP_full_c40 +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +VanDerPlasVersion = true +StartWithAnalytical = false +AveragedAnalyticalSolution = true +UseScvfLineAveraging = true + +[Component] +LiquidDensity = 1.0 +LiquidKinematicViscosity = 0.05 +MolarMass = 1.0 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +[Newton] +MaxSteps = 10 +TargetSteps = 4 +MaxRelativeShift = 1e-5 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true +MaxAbsoluteResidual = 1e-5 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = false +AddProcessRank = false + +[Flux] +UpwindWeight = 0.5 + +[Adaptivity] +NewParallelAlgo = false +UseOwn4PointCoefficients = false +Conservation = false +Adapt = true +LeftX = .4 +RightX = .6 +LowerY = .4 +UpperY = .6 diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_full_c80.input b/appl/freeflow/navierstokes/sincos/params_vdP_full_c80.input new file mode 100644 index 0000000..9bfca19 --- /dev/null +++ b/appl/freeflow/navierstokes/sincos/params_vdP_full_c80.input @@ -0,0 +1,78 @@ +[TimeLoop] +DtInitial = 0.01 # [s] +TEnd = 1.0 # [s] + +[Helper.Grid] +Positions0 = 0.25 0.75 +Positions1 = 0.25 0.75 #we don't have symmetry BCs +Cells0 = 80 +Cells1 = 80 +Grading0 = 1.0 +Grading1 = 1.0 + +[xCVs.Grid] +File = xCVs.dgf + +[yCVs.Grid] +File = yCVs.dgf + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_ff_sincos_vdP_full_c80 +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +VanDerPlasVersion = true +StartWithAnalytical = false +AveragedAnalyticalSolution = true +UseScvfLineAveraging = true + +[Component] +LiquidDensity = 1.0 +LiquidKinematicViscosity = 0.05 +MolarMass = 1.0 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +[Newton] +MaxSteps = 10 +TargetSteps = 4 +MaxRelativeShift = 1e-5 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true +MaxAbsoluteResidual = 1e-5 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = false +AddProcessRank = false + +[Flux] +UpwindWeight = 0.5 + +[Adaptivity] +NewParallelAlgo = false +UseOwn4PointCoefficients = false +Conservation = false +Adapt = true +LeftX = .4 +RightX = .6 +LowerY = .4 +UpperY = .6 -- GitLab From 4c8167d4aa7ea8c61d0742e3cf1611be921e780c Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Tue, 21 Sep 2021 13:14:59 +0300 Subject: [PATCH 48/69] Decreased limiting error measures for sincos tests --- .../navierstokes/sincos/params_vdP_full.input | 4 +- .../sincos/params_vdP_full_c120.input | 4 +- .../sincos/params_vdP_full_c160.input | 78 +++++++++++++++++++ .../sincos/params_vdP_full_c20.input | 4 +- .../sincos/params_vdP_full_c240.input | 78 +++++++++++++++++++ .../sincos/params_vdP_full_c40.input | 4 +- .../sincos/params_vdP_full_c80.input | 4 +- 7 files changed, 166 insertions(+), 10 deletions(-) create mode 100644 appl/freeflow/navierstokes/sincos/params_vdP_full_c160.input create mode 100644 appl/freeflow/navierstokes/sincos/params_vdP_full_c240.input diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_full.input b/appl/freeflow/navierstokes/sincos/params_vdP_full.input index 4aacaa1..68e419c 100644 --- a/appl/freeflow/navierstokes/sincos/params_vdP_full.input +++ b/appl/freeflow/navierstokes/sincos/params_vdP_full.input @@ -53,10 +53,10 @@ NumericDifference.BaseEpsilon = 1e-8 [Newton] MaxSteps = 10 TargetSteps = 4 -MaxRelativeShift = 1e-5 +MaxRelativeShift = 1e-10 SatisfyResidualAndShiftCriterion = true EnableAbsoluteResidualCriterion = true -MaxAbsoluteResidual = 1e-5 +MaxAbsoluteResidual = 1e-10 ExitAfterFirstIteration = false OutputMatrices = false diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_full_c120.input b/appl/freeflow/navierstokes/sincos/params_vdP_full_c120.input index a8674fb..7632900 100644 --- a/appl/freeflow/navierstokes/sincos/params_vdP_full_c120.input +++ b/appl/freeflow/navierstokes/sincos/params_vdP_full_c120.input @@ -53,10 +53,10 @@ NumericDifference.BaseEpsilon = 1e-8 [Newton] MaxSteps = 10 TargetSteps = 4 -MaxRelativeShift = 1e-5 +MaxRelativeShift = 1e-10 SatisfyResidualAndShiftCriterion = true EnableAbsoluteResidualCriterion = true -MaxAbsoluteResidual = 1e-5 +MaxAbsoluteResidual = 1e-10 ExitAfterFirstIteration = false OutputMatrices = false diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_full_c160.input b/appl/freeflow/navierstokes/sincos/params_vdP_full_c160.input new file mode 100644 index 0000000..62d5795 --- /dev/null +++ b/appl/freeflow/navierstokes/sincos/params_vdP_full_c160.input @@ -0,0 +1,78 @@ +[TimeLoop] +DtInitial = 0.01 # [s] +TEnd = 1.0 # [s] + +[Helper.Grid] +Positions0 = 0.25 0.75 +Positions1 = 0.25 0.75 #we don't have symmetry BCs +Cells0 = 160 +Cells1 = 160 +Grading0 = 1.0 +Grading1 = 1.0 + +[xCVs.Grid] +File = xCVs.dgf + +[yCVs.Grid] +File = yCVs.dgf + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_ff_sincos_vdP_full_c160 +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +VanDerPlasVersion = true +StartWithAnalytical = false +AveragedAnalyticalSolution = true +UseScvfLineAveraging = true + +[Component] +LiquidDensity = 1.0 +LiquidKinematicViscosity = 0.05 +MolarMass = 1.0 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +[Newton] +MaxSteps = 10 +TargetSteps = 4 +MaxRelativeShift = 1e-10 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true +MaxAbsoluteResidual = 1e-10 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = false +AddProcessRank = false + +[Flux] +UpwindWeight = 0.5 + +[Adaptivity] +NewParallelAlgo = false +UseOwn4PointCoefficients = false +Conservation = false +Adapt = true +LeftX = .4 +RightX = .6 +LowerY = .4 +UpperY = .6 diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_full_c20.input b/appl/freeflow/navierstokes/sincos/params_vdP_full_c20.input index d6cd26e..0aebdfb 100644 --- a/appl/freeflow/navierstokes/sincos/params_vdP_full_c20.input +++ b/appl/freeflow/navierstokes/sincos/params_vdP_full_c20.input @@ -53,10 +53,10 @@ NumericDifference.BaseEpsilon = 1e-8 [Newton] MaxSteps = 10 TargetSteps = 4 -MaxRelativeShift = 1e-5 +MaxRelativeShift = 1e-10 SatisfyResidualAndShiftCriterion = true EnableAbsoluteResidualCriterion = true -MaxAbsoluteResidual = 1e-5 +MaxAbsoluteResidual = 1e-10 ExitAfterFirstIteration = false OutputMatrices = false diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_full_c240.input b/appl/freeflow/navierstokes/sincos/params_vdP_full_c240.input new file mode 100644 index 0000000..436e5d8 --- /dev/null +++ b/appl/freeflow/navierstokes/sincos/params_vdP_full_c240.input @@ -0,0 +1,78 @@ +[TimeLoop] +DtInitial = 0.01 # [s] +TEnd = 1.0 # [s] + +[Helper.Grid] +Positions0 = 0.25 0.75 +Positions1 = 0.25 0.75 #we don't have symmetry BCs +Cells0 = 240 +Cells1 = 240 +Grading0 = 1.0 +Grading1 = 1.0 + +[xCVs.Grid] +File = xCVs.dgf + +[yCVs.Grid] +File = yCVs.dgf + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_ff_sincos_vdP_full_c240 +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +VanDerPlasVersion = true +StartWithAnalytical = false +AveragedAnalyticalSolution = true +UseScvfLineAveraging = true + +[Component] +LiquidDensity = 1.0 +LiquidKinematicViscosity = 0.05 +MolarMass = 1.0 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +[Newton] +MaxSteps = 10 +TargetSteps = 4 +MaxRelativeShift = 1e-10 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true +MaxAbsoluteResidual = 1e-10 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = false +AddProcessRank = false + +[Flux] +UpwindWeight = 0.5 + +[Adaptivity] +NewParallelAlgo = false +UseOwn4PointCoefficients = false +Conservation = false +Adapt = true +LeftX = .4 +RightX = .6 +LowerY = .4 +UpperY = .6 diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_full_c40.input b/appl/freeflow/navierstokes/sincos/params_vdP_full_c40.input index 47de437..bc91d4b 100644 --- a/appl/freeflow/navierstokes/sincos/params_vdP_full_c40.input +++ b/appl/freeflow/navierstokes/sincos/params_vdP_full_c40.input @@ -53,10 +53,10 @@ NumericDifference.BaseEpsilon = 1e-8 [Newton] MaxSteps = 10 TargetSteps = 4 -MaxRelativeShift = 1e-5 +MaxRelativeShift = 1e-10 SatisfyResidualAndShiftCriterion = true EnableAbsoluteResidualCriterion = true -MaxAbsoluteResidual = 1e-5 +MaxAbsoluteResidual = 1e-10 ExitAfterFirstIteration = false OutputMatrices = false diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_full_c80.input b/appl/freeflow/navierstokes/sincos/params_vdP_full_c80.input index 9bfca19..81c2fe1 100644 --- a/appl/freeflow/navierstokes/sincos/params_vdP_full_c80.input +++ b/appl/freeflow/navierstokes/sincos/params_vdP_full_c80.input @@ -53,10 +53,10 @@ NumericDifference.BaseEpsilon = 1e-8 [Newton] MaxSteps = 10 TargetSteps = 4 -MaxRelativeShift = 1e-5 +MaxRelativeShift = 1e-10 SatisfyResidualAndShiftCriterion = true EnableAbsoluteResidualCriterion = true -MaxAbsoluteResidual = 1e-5 +MaxAbsoluteResidual = 1e-10 ExitAfterFirstIteration = false OutputMatrices = false -- GitLab From 0f27934782e43930d97486956bd18f0bf9008517 Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Wed, 22 Sep 2021 12:30:54 +0300 Subject: [PATCH 49/69] donea convergence test files --- .../navierstokes/donea/CMakeLists.txt | 2 - appl/freeflow/navierstokes/donea/main.cc | 2 +- .../navierstokes/donea/params_full_c120.input | 50 +++++++++++++++++++ .../navierstokes/donea/params_full_c160.input | 50 +++++++++++++++++++ .../navierstokes/donea/params_full_c20.input | 50 +++++++++++++++++++ .../navierstokes/donea/params_full_c40.input | 50 +++++++++++++++++++ .../navierstokes/donea/params_full_c80.input | 50 +++++++++++++++++++ 7 files changed, 251 insertions(+), 3 deletions(-) create mode 100644 appl/freeflow/navierstokes/donea/params_full_c120.input create mode 100644 appl/freeflow/navierstokes/donea/params_full_c160.input create mode 100644 appl/freeflow/navierstokes/donea/params_full_c20.input create mode 100644 appl/freeflow/navierstokes/donea/params_full_c40.input create mode 100644 appl/freeflow/navierstokes/donea/params_full_c80.input diff --git a/appl/freeflow/navierstokes/donea/CMakeLists.txt b/appl/freeflow/navierstokes/donea/CMakeLists.txt index 700e929..474689b 100644 --- a/appl/freeflow/navierstokes/donea/CMakeLists.txt +++ b/appl/freeflow/navierstokes/donea/CMakeLists.txt @@ -1,5 +1,3 @@ -set(CMAKE_BUILD_TYPE Debug) - add_input_file_links() dune_add_test(NAME test_ff_donea diff --git a/appl/freeflow/navierstokes/donea/main.cc b/appl/freeflow/navierstokes/donea/main.cc index 6303567..da789ca 100644 --- a/appl/freeflow/navierstokes/donea/main.cc +++ b/appl/freeflow/navierstokes/donea/main.cc @@ -150,7 +150,7 @@ int main(int argc, char** argv) try auto x = pos[0]; auto y = pos[1]; - if ((x > 0.4 && x < 0.6) && (y > 0.4 && y < 0.6)) + if ((x > 0.2 && x < 0.8) && (y > 0.2 && y < 0.8)) { hostGridManager.grid().mark(1, element); } diff --git a/appl/freeflow/navierstokes/donea/params_full_c120.input b/appl/freeflow/navierstokes/donea/params_full_c120.input new file mode 100644 index 0000000..94d74e4 --- /dev/null +++ b/appl/freeflow/navierstokes/donea/params_full_c120.input @@ -0,0 +1,50 @@ +[Helper.Grid] +Positions0 = 0 1 +Positions1 = 0 1 +Cells0 = 120 +Cells1 = 120 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = donea_full_c120 # name passed to the output routines +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = false +StartWithAnalytical = false +AveragedAnalyticalSolution = false +UseScvfLineAveraging = true + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-5 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = true + +[Adaptivity] +Adapt = true +LinearInterpolation = false #false: quadratic +Conservation = false + +[Component] +MolarMass = 1.0 +LiquidDensity = 1.0 +LiquidKinematicViscosity = 1.0 diff --git a/appl/freeflow/navierstokes/donea/params_full_c160.input b/appl/freeflow/navierstokes/donea/params_full_c160.input new file mode 100644 index 0000000..2372133 --- /dev/null +++ b/appl/freeflow/navierstokes/donea/params_full_c160.input @@ -0,0 +1,50 @@ +[Helper.Grid] +Positions0 = 0 1 +Positions1 = 0 1 +Cells0 = 160 +Cells1 = 160 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = donea_full_c160 # name passed to the output routines +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = false +StartWithAnalytical = false +AveragedAnalyticalSolution = false +UseScvfLineAveraging = true + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-5 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = true + +[Adaptivity] +Adapt = true +LinearInterpolation = false #false: quadratic +Conservation = false + +[Component] +MolarMass = 1.0 +LiquidDensity = 1.0 +LiquidKinematicViscosity = 1.0 diff --git a/appl/freeflow/navierstokes/donea/params_full_c20.input b/appl/freeflow/navierstokes/donea/params_full_c20.input new file mode 100644 index 0000000..2600d37 --- /dev/null +++ b/appl/freeflow/navierstokes/donea/params_full_c20.input @@ -0,0 +1,50 @@ +[Helper.Grid] +Positions0 = 0 1 +Positions1 = 0 1 +Cells0 = 20 +Cells1 = 20 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = donea_full_c20 # name passed to the output routines +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = false +StartWithAnalytical = false +AveragedAnalyticalSolution = false +UseScvfLineAveraging = true + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-5 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = true + +[Adaptivity] +Adapt = true +LinearInterpolation = false #false: quadratic +Conservation = false + +[Component] +MolarMass = 1.0 +LiquidDensity = 1.0 +LiquidKinematicViscosity = 1.0 diff --git a/appl/freeflow/navierstokes/donea/params_full_c40.input b/appl/freeflow/navierstokes/donea/params_full_c40.input new file mode 100644 index 0000000..8390845 --- /dev/null +++ b/appl/freeflow/navierstokes/donea/params_full_c40.input @@ -0,0 +1,50 @@ +[Helper.Grid] +Positions0 = 0 1 +Positions1 = 0 1 +Cells0 = 40 +Cells1 = 40 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = donea_full_c40 # name passed to the output routines +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = false +StartWithAnalytical = false +AveragedAnalyticalSolution = false +UseScvfLineAveraging = true + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-5 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = true + +[Adaptivity] +Adapt = true +LinearInterpolation = false #false: quadratic +Conservation = false + +[Component] +MolarMass = 1.0 +LiquidDensity = 1.0 +LiquidKinematicViscosity = 1.0 diff --git a/appl/freeflow/navierstokes/donea/params_full_c80.input b/appl/freeflow/navierstokes/donea/params_full_c80.input new file mode 100644 index 0000000..5aa8915 --- /dev/null +++ b/appl/freeflow/navierstokes/donea/params_full_c80.input @@ -0,0 +1,50 @@ +[Helper.Grid] +Positions0 = 0 1 +Positions1 = 0 1 +Cells0 = 80 +Cells1 = 80 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = donea_full_c80 # name passed to the output routines +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = false +StartWithAnalytical = false +AveragedAnalyticalSolution = false +UseScvfLineAveraging = true + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-5 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = true + +[Adaptivity] +Adapt = true +LinearInterpolation = false #false: quadratic +Conservation = false + +[Component] +MolarMass = 1.0 +LiquidDensity = 1.0 +LiquidKinematicViscosity = 1.0 -- GitLab From 99b34ee7feeaf11a4a9e8f30f2a2cfbede75efc8 Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Wed, 22 Sep 2021 14:05:33 +0300 Subject: [PATCH 50/69] Added channel convergence tests --- .../navierstokes/channel/2d/CMakeLists.txt | 3 - .../channel/2d/params_ns_stat_c120.input | 73 +++++++++++++++++++ .../channel/2d/params_ns_stat_c160.input | 73 +++++++++++++++++++ .../channel/2d/params_ns_stat_c20.input | 73 +++++++++++++++++++ .../channel/2d/params_ns_stat_c40.input | 73 +++++++++++++++++++ .../channel/2d/params_ns_stat_c80.input | 73 +++++++++++++++++++ .../channel/2d/params_s_stat_c120.input | 73 +++++++++++++++++++ .../channel/2d/params_s_stat_c160.input | 73 +++++++++++++++++++ .../channel/2d/params_s_stat_c20.input | 73 +++++++++++++++++++ .../channel/2d/params_s_stat_c40.input | 73 +++++++++++++++++++ .../channel/2d/params_s_stat_c80.input | 73 +++++++++++++++++++ 11 files changed, 730 insertions(+), 3 deletions(-) create mode 100644 appl/freeflow/navierstokes/channel/2d/params_ns_stat_c120.input create mode 100644 appl/freeflow/navierstokes/channel/2d/params_ns_stat_c160.input create mode 100644 appl/freeflow/navierstokes/channel/2d/params_ns_stat_c20.input create mode 100644 appl/freeflow/navierstokes/channel/2d/params_ns_stat_c40.input create mode 100644 appl/freeflow/navierstokes/channel/2d/params_ns_stat_c80.input create mode 100644 appl/freeflow/navierstokes/channel/2d/params_s_stat_c120.input create mode 100644 appl/freeflow/navierstokes/channel/2d/params_s_stat_c160.input create mode 100644 appl/freeflow/navierstokes/channel/2d/params_s_stat_c20.input create mode 100644 appl/freeflow/navierstokes/channel/2d/params_s_stat_c40.input create mode 100644 appl/freeflow/navierstokes/channel/2d/params_s_stat_c80.input diff --git a/appl/freeflow/navierstokes/channel/2d/CMakeLists.txt b/appl/freeflow/navierstokes/channel/2d/CMakeLists.txt index a4c7227..3e82f96 100644 --- a/appl/freeflow/navierstokes/channel/2d/CMakeLists.txt +++ b/appl/freeflow/navierstokes/channel/2d/CMakeLists.txt @@ -1,7 +1,4 @@ add_input_file_links() - -set(CMAKE_BUILD_TYPE Debug) - add_executable(test_ff_channel EXCLUDE_FROM_ALL main.cc) dune_add_test(NAME test_ff_stokes_channel diff --git a/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c120.input b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c120.input new file mode 100644 index 0000000..5b16505 --- /dev/null +++ b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c120.input @@ -0,0 +1,73 @@ +[Helper.Grid] +Positions0 = 0 10 +Positions1 = 0 1 +Cells0 = 120 +Cells1 = 90 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_channel_ns_stat_c120 # name passed to the output routines +InletVelocity = 100 +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +AveragedAnalyticalSolution = false +UseScvfLineAveraging = true + +[Component] +MolarMass = 1.0 +LiquidDensity = 1 +LiquidKinematicViscosity = 1 + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-8 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true + +[Vtk] +WriteFaceData = false + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +# This test does actually not require setting the primary variable magnitues. +# This rather serves as a demonstration of how to use the feature. +[CellCenter.Assembly] +NumericDifference.PriVarMagnitude = 1e5 # pressure is in the order of 1e5 + +[Face.Assembly] +NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 + +[Adaptivity] +Conservation = false +Adapt = true +LeftX = 2 +RightX = 8 +LowerY = 0.2 +UpperY = 0.8 + +[Adaptive] +RefineAtDirichletBC = 0 +RefineAtFluxBC = 1 +MinLevel = 0 +MaxLevel = 0 +CoarsenTolerance = 1e-4 +RefineTolerance = 2e-1 diff --git a/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c160.input b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c160.input new file mode 100644 index 0000000..662cd59 --- /dev/null +++ b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c160.input @@ -0,0 +1,73 @@ +[Helper.Grid] +Positions0 = 0 10 +Positions1 = 0 1 +Cells0 = 160 +Cells1 = 120 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_channel_ns_stat_c160 # name passed to the output routines +InletVelocity = 100 +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +AveragedAnalyticalSolution = false +UseScvfLineAveraging = true + +[Component] +MolarMass = 1.0 +LiquidDensity = 1 +LiquidKinematicViscosity = 1 + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-8 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true + +[Vtk] +WriteFaceData = false + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +# This test does actually not require setting the primary variable magnitues. +# This rather serves as a demonstration of how to use the feature. +[CellCenter.Assembly] +NumericDifference.PriVarMagnitude = 1e5 # pressure is in the order of 1e5 + +[Face.Assembly] +NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 + +[Adaptivity] +Conservation = false +Adapt = true +LeftX = 2 +RightX = 8 +LowerY = 0.2 +UpperY = 0.8 + +[Adaptive] +RefineAtDirichletBC = 0 +RefineAtFluxBC = 1 +MinLevel = 0 +MaxLevel = 0 +CoarsenTolerance = 1e-4 +RefineTolerance = 2e-1 diff --git a/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c20.input b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c20.input new file mode 100644 index 0000000..d678d14 --- /dev/null +++ b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c20.input @@ -0,0 +1,73 @@ +[Helper.Grid] +Positions0 = 0 10 +Positions1 = 0 1 +Cells0 = 20 +Cells1 = 15 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_channel_ns_stat_c20 # name passed to the output routines +InletVelocity = 100 +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +AveragedAnalyticalSolution = false +UseScvfLineAveraging = true + +[Component] +MolarMass = 1.0 +LiquidDensity = 1 +LiquidKinematicViscosity = 1 + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-8 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true + +[Vtk] +WriteFaceData = false + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +# This test does actually not require setting the primary variable magnitues. +# This rather serves as a demonstration of how to use the feature. +[CellCenter.Assembly] +NumericDifference.PriVarMagnitude = 1e5 # pressure is in the order of 1e5 + +[Face.Assembly] +NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 + +[Adaptivity] +Conservation = false +Adapt = true +LeftX = 2 +RightX = 8 +LowerY = 0.2 +UpperY = 0.8 + +[Adaptive] +RefineAtDirichletBC = 0 +RefineAtFluxBC = 1 +MinLevel = 0 +MaxLevel = 0 +CoarsenTolerance = 1e-4 +RefineTolerance = 2e-1 diff --git a/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c40.input b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c40.input new file mode 100644 index 0000000..31d16c1 --- /dev/null +++ b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c40.input @@ -0,0 +1,73 @@ +[Helper.Grid] +Positions0 = 0 10 +Positions1 = 0 1 +Cells0 = 40 +Cells1 = 30 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_channel_ns_stat_c40 # name passed to the output routines +InletVelocity = 100 +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +AveragedAnalyticalSolution = false +UseScvfLineAveraging = true + +[Component] +MolarMass = 1.0 +LiquidDensity = 1 +LiquidKinematicViscosity = 1 + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-8 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true + +[Vtk] +WriteFaceData = false + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +# This test does actually not require setting the primary variable magnitues. +# This rather serves as a demonstration of how to use the feature. +[CellCenter.Assembly] +NumericDifference.PriVarMagnitude = 1e5 # pressure is in the order of 1e5 + +[Face.Assembly] +NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 + +[Adaptivity] +Conservation = false +Adapt = true +LeftX = 2 +RightX = 8 +LowerY = 0.2 +UpperY = 0.8 + +[Adaptive] +RefineAtDirichletBC = 0 +RefineAtFluxBC = 1 +MinLevel = 0 +MaxLevel = 0 +CoarsenTolerance = 1e-4 +RefineTolerance = 2e-1 diff --git a/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c80.input b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c80.input new file mode 100644 index 0000000..0c4475e --- /dev/null +++ b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c80.input @@ -0,0 +1,73 @@ +[Helper.Grid] +Positions0 = 0 10 +Positions1 = 0 1 +Cells0 = 80 +Cells1 = 60 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_channel_ns_stat_c80 # name passed to the output routines +InletVelocity = 100 +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +AveragedAnalyticalSolution = false +UseScvfLineAveraging = true + +[Component] +MolarMass = 1.0 +LiquidDensity = 1 +LiquidKinematicViscosity = 1 + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-8 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true + +[Vtk] +WriteFaceData = false + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +# This test does actually not require setting the primary variable magnitues. +# This rather serves as a demonstration of how to use the feature. +[CellCenter.Assembly] +NumericDifference.PriVarMagnitude = 1e5 # pressure is in the order of 1e5 + +[Face.Assembly] +NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 + +[Adaptivity] +Conservation = false +Adapt = true +LeftX = 2 +RightX = 8 +LowerY = 0.2 +UpperY = 0.8 + +[Adaptive] +RefineAtDirichletBC = 0 +RefineAtFluxBC = 1 +MinLevel = 0 +MaxLevel = 0 +CoarsenTolerance = 1e-4 +RefineTolerance = 2e-1 diff --git a/appl/freeflow/navierstokes/channel/2d/params_s_stat_c120.input b/appl/freeflow/navierstokes/channel/2d/params_s_stat_c120.input new file mode 100644 index 0000000..d289d64 --- /dev/null +++ b/appl/freeflow/navierstokes/channel/2d/params_s_stat_c120.input @@ -0,0 +1,73 @@ +[Helper.Grid] +Positions0 = 0 10 +Positions1 = 0 1 +Cells0 = 120 +Cells1 = 90 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_channel_s_stat_c120 # name passed to the output routines +InletVelocity = 1 +EnableGravity = false +EnableInertiaTerms = false +PrintErrors = true +IsStationary = true +UseScvfLineAveraging = true + +[Component] +MolarMass = 1.0 +LiquidDensity = 1 +LiquidKinematicViscosity = 1 + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-10 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true + +[Vtk] +WriteFaceData = false + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +# This test does actually not require setting the primary variable magnitues. +# This rather serves as a demonstration of how to use the feature. +[CellCenter.Assembly] +NumericDifference.PriVarMagnitude = 1e5 # pressure is in the order of 1e5 + +[Face.Assembly] +NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 + +[Adaptivity] +Conservation = false +Adapt = true +LeftX = 2 +RightX = 8 +LowerY = 0.2 +UpperY = 0.8 + + +[Adaptive] +RefineAtDirichletBC = 0 +RefineAtFluxBC = 1 +MinLevel = 0 +MaxLevel = 0 +CoarsenTolerance = 1e-4 +RefineTolerance = 2e-1 diff --git a/appl/freeflow/navierstokes/channel/2d/params_s_stat_c160.input b/appl/freeflow/navierstokes/channel/2d/params_s_stat_c160.input new file mode 100644 index 0000000..4e5fdb7 --- /dev/null +++ b/appl/freeflow/navierstokes/channel/2d/params_s_stat_c160.input @@ -0,0 +1,73 @@ +[Helper.Grid] +Positions0 = 0 10 +Positions1 = 0 1 +Cells0 = 160 +Cells1 = 120 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_channel_s_stat_c160 # name passed to the output routines +InletVelocity = 1 +EnableGravity = false +EnableInertiaTerms = false +PrintErrors = true +IsStationary = true +UseScvfLineAveraging = true + +[Component] +MolarMass = 1.0 +LiquidDensity = 1 +LiquidKinematicViscosity = 1 + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-10 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true + +[Vtk] +WriteFaceData = false + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +# This test does actually not require setting the primary variable magnitues. +# This rather serves as a demonstration of how to use the feature. +[CellCenter.Assembly] +NumericDifference.PriVarMagnitude = 1e5 # pressure is in the order of 1e5 + +[Face.Assembly] +NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 + +[Adaptivity] +Conservation = false +Adapt = true +LeftX = 2 +RightX = 8 +LowerY = 0.2 +UpperY = 0.8 + + +[Adaptive] +RefineAtDirichletBC = 0 +RefineAtFluxBC = 1 +MinLevel = 0 +MaxLevel = 0 +CoarsenTolerance = 1e-4 +RefineTolerance = 2e-1 diff --git a/appl/freeflow/navierstokes/channel/2d/params_s_stat_c20.input b/appl/freeflow/navierstokes/channel/2d/params_s_stat_c20.input new file mode 100644 index 0000000..e18424c --- /dev/null +++ b/appl/freeflow/navierstokes/channel/2d/params_s_stat_c20.input @@ -0,0 +1,73 @@ +[Helper.Grid] +Positions0 = 0 10 +Positions1 = 0 1 +Cells0 = 20 +Cells1 = 15 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_channel_s_stat_c20 # name passed to the output routines +InletVelocity = 1 +EnableGravity = false +EnableInertiaTerms = false +PrintErrors = true +IsStationary = true +UseScvfLineAveraging = true + +[Component] +MolarMass = 1.0 +LiquidDensity = 1 +LiquidKinematicViscosity = 1 + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-10 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true + +[Vtk] +WriteFaceData = false + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +# This test does actually not require setting the primary variable magnitues. +# This rather serves as a demonstration of how to use the feature. +[CellCenter.Assembly] +NumericDifference.PriVarMagnitude = 1e5 # pressure is in the order of 1e5 + +[Face.Assembly] +NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 + +[Adaptivity] +Conservation = false +Adapt = true +LeftX = 2 +RightX = 8 +LowerY = 0.2 +UpperY = 0.8 + + +[Adaptive] +RefineAtDirichletBC = 0 +RefineAtFluxBC = 1 +MinLevel = 0 +MaxLevel = 0 +CoarsenTolerance = 1e-4 +RefineTolerance = 2e-1 diff --git a/appl/freeflow/navierstokes/channel/2d/params_s_stat_c40.input b/appl/freeflow/navierstokes/channel/2d/params_s_stat_c40.input new file mode 100644 index 0000000..b29c60f --- /dev/null +++ b/appl/freeflow/navierstokes/channel/2d/params_s_stat_c40.input @@ -0,0 +1,73 @@ +[Helper.Grid] +Positions0 = 0 10 +Positions1 = 0 1 +Cells0 = 40 +Cells1 = 30 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_channel_s_stat_c40 # name passed to the output routines +InletVelocity = 1 +EnableGravity = false +EnableInertiaTerms = false +PrintErrors = true +IsStationary = true +UseScvfLineAveraging = true + +[Component] +MolarMass = 1.0 +LiquidDensity = 1 +LiquidKinematicViscosity = 1 + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-10 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true + +[Vtk] +WriteFaceData = false + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +# This test does actually not require setting the primary variable magnitues. +# This rather serves as a demonstration of how to use the feature. +[CellCenter.Assembly] +NumericDifference.PriVarMagnitude = 1e5 # pressure is in the order of 1e5 + +[Face.Assembly] +NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 + +[Adaptivity] +Conservation = false +Adapt = true +LeftX = 2 +RightX = 8 +LowerY = 0.2 +UpperY = 0.8 + + +[Adaptive] +RefineAtDirichletBC = 0 +RefineAtFluxBC = 1 +MinLevel = 0 +MaxLevel = 0 +CoarsenTolerance = 1e-4 +RefineTolerance = 2e-1 diff --git a/appl/freeflow/navierstokes/channel/2d/params_s_stat_c80.input b/appl/freeflow/navierstokes/channel/2d/params_s_stat_c80.input new file mode 100644 index 0000000..8445ca7 --- /dev/null +++ b/appl/freeflow/navierstokes/channel/2d/params_s_stat_c80.input @@ -0,0 +1,73 @@ +[Helper.Grid] +Positions0 = 0 10 +Positions1 = 0 1 +Cells0 = 80 +Cells1 = 60 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_channel_s_stat_c80 # name passed to the output routines +InletVelocity = 1 +EnableGravity = false +EnableInertiaTerms = false +PrintErrors = true +IsStationary = true +UseScvfLineAveraging = true + +[Component] +MolarMass = 1.0 +LiquidDensity = 1 +LiquidKinematicViscosity = 1 + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-10 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true + +[Vtk] +WriteFaceData = false + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +# This test does actually not require setting the primary variable magnitues. +# This rather serves as a demonstration of how to use the feature. +[CellCenter.Assembly] +NumericDifference.PriVarMagnitude = 1e5 # pressure is in the order of 1e5 + +[Face.Assembly] +NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 + +[Adaptivity] +Conservation = false +Adapt = true +LeftX = 2 +RightX = 8 +LowerY = 0.2 +UpperY = 0.8 + + +[Adaptive] +RefineAtDirichletBC = 0 +RefineAtFluxBC = 1 +MinLevel = 0 +MaxLevel = 0 +CoarsenTolerance = 1e-4 +RefineTolerance = 2e-1 -- GitLab From c36c054b796b9396daa7080244a31b576f6459e7 Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Wed, 22 Sep 2021 15:13:17 +0300 Subject: [PATCH 51/69] Sincos conv. param files --- .../sincos/params_vdP_full_c120.input | 2 +- .../sincos/params_vdP_full_c160.input | 2 +- .../sincos/params_vdP_full_c20.input | 2 +- .../sincos/params_vdP_full_c240.input | 2 +- .../sincos/params_vdP_full_c40.input | 2 +- .../sincos/params_vdP_full_c80.input | 2 +- .../sincos/params_vdP_vdPC_full_c120.input | 78 +++++++++++++++++++ .../sincos/params_vdP_vdPC_full_c160.input | 78 +++++++++++++++++++ .../sincos/params_vdP_vdPC_full_c20.input | 78 +++++++++++++++++++ .../sincos/params_vdP_vdPC_full_c240.input | 78 +++++++++++++++++++ .../sincos/params_vdP_vdPC_full_c40.input | 78 +++++++++++++++++++ .../sincos/params_vdP_vdPC_full_c80.input | 78 +++++++++++++++++++ 12 files changed, 474 insertions(+), 6 deletions(-) create mode 100644 appl/freeflow/navierstokes/sincos/params_vdP_vdPC_full_c120.input create mode 100644 appl/freeflow/navierstokes/sincos/params_vdP_vdPC_full_c160.input create mode 100644 appl/freeflow/navierstokes/sincos/params_vdP_vdPC_full_c20.input create mode 100644 appl/freeflow/navierstokes/sincos/params_vdP_vdPC_full_c240.input create mode 100644 appl/freeflow/navierstokes/sincos/params_vdP_vdPC_full_c40.input create mode 100644 appl/freeflow/navierstokes/sincos/params_vdP_vdPC_full_c80.input diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_full_c120.input b/appl/freeflow/navierstokes/sincos/params_vdP_full_c120.input index 7632900..85059f9 100644 --- a/appl/freeflow/navierstokes/sincos/params_vdP_full_c120.input +++ b/appl/freeflow/navierstokes/sincos/params_vdP_full_c120.input @@ -69,7 +69,7 @@ UpwindWeight = 0.5 [Adaptivity] NewParallelAlgo = false -UseOwn4PointCoefficients = false +UseOwn4PointCoefficients = true Conservation = false Adapt = true LeftX = .4 diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_full_c160.input b/appl/freeflow/navierstokes/sincos/params_vdP_full_c160.input index 62d5795..69aca6d 100644 --- a/appl/freeflow/navierstokes/sincos/params_vdP_full_c160.input +++ b/appl/freeflow/navierstokes/sincos/params_vdP_full_c160.input @@ -69,7 +69,7 @@ UpwindWeight = 0.5 [Adaptivity] NewParallelAlgo = false -UseOwn4PointCoefficients = false +UseOwn4PointCoefficients = true Conservation = false Adapt = true LeftX = .4 diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_full_c20.input b/appl/freeflow/navierstokes/sincos/params_vdP_full_c20.input index 0aebdfb..0b9dcc8 100644 --- a/appl/freeflow/navierstokes/sincos/params_vdP_full_c20.input +++ b/appl/freeflow/navierstokes/sincos/params_vdP_full_c20.input @@ -69,7 +69,7 @@ UpwindWeight = 0.5 [Adaptivity] NewParallelAlgo = false -UseOwn4PointCoefficients = false +UseOwn4PointCoefficients = true Conservation = false Adapt = true LeftX = .4 diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_full_c240.input b/appl/freeflow/navierstokes/sincos/params_vdP_full_c240.input index 436e5d8..b57abaf 100644 --- a/appl/freeflow/navierstokes/sincos/params_vdP_full_c240.input +++ b/appl/freeflow/navierstokes/sincos/params_vdP_full_c240.input @@ -69,7 +69,7 @@ UpwindWeight = 0.5 [Adaptivity] NewParallelAlgo = false -UseOwn4PointCoefficients = false +UseOwn4PointCoefficients = true Conservation = false Adapt = true LeftX = .4 diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_full_c40.input b/appl/freeflow/navierstokes/sincos/params_vdP_full_c40.input index bc91d4b..2016f1b 100644 --- a/appl/freeflow/navierstokes/sincos/params_vdP_full_c40.input +++ b/appl/freeflow/navierstokes/sincos/params_vdP_full_c40.input @@ -69,7 +69,7 @@ UpwindWeight = 0.5 [Adaptivity] NewParallelAlgo = false -UseOwn4PointCoefficients = false +UseOwn4PointCoefficients = true Conservation = false Adapt = true LeftX = .4 diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_full_c80.input b/appl/freeflow/navierstokes/sincos/params_vdP_full_c80.input index 81c2fe1..97de356 100644 --- a/appl/freeflow/navierstokes/sincos/params_vdP_full_c80.input +++ b/appl/freeflow/navierstokes/sincos/params_vdP_full_c80.input @@ -69,7 +69,7 @@ UpwindWeight = 0.5 [Adaptivity] NewParallelAlgo = false -UseOwn4PointCoefficients = false +UseOwn4PointCoefficients = true Conservation = false Adapt = true LeftX = .4 diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_vdPC_full_c120.input b/appl/freeflow/navierstokes/sincos/params_vdP_vdPC_full_c120.input new file mode 100644 index 0000000..7632900 --- /dev/null +++ b/appl/freeflow/navierstokes/sincos/params_vdP_vdPC_full_c120.input @@ -0,0 +1,78 @@ +[TimeLoop] +DtInitial = 0.01 # [s] +TEnd = 1.0 # [s] + +[Helper.Grid] +Positions0 = 0.25 0.75 +Positions1 = 0.25 0.75 #we don't have symmetry BCs +Cells0 = 120 +Cells1 = 120 +Grading0 = 1.0 +Grading1 = 1.0 + +[xCVs.Grid] +File = xCVs.dgf + +[yCVs.Grid] +File = yCVs.dgf + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_ff_sincos_vdP_full_c120 +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +VanDerPlasVersion = true +StartWithAnalytical = false +AveragedAnalyticalSolution = true +UseScvfLineAveraging = true + +[Component] +LiquidDensity = 1.0 +LiquidKinematicViscosity = 0.05 +MolarMass = 1.0 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +[Newton] +MaxSteps = 10 +TargetSteps = 4 +MaxRelativeShift = 1e-10 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true +MaxAbsoluteResidual = 1e-10 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = false +AddProcessRank = false + +[Flux] +UpwindWeight = 0.5 + +[Adaptivity] +NewParallelAlgo = false +UseOwn4PointCoefficients = false +Conservation = false +Adapt = true +LeftX = .4 +RightX = .6 +LowerY = .4 +UpperY = .6 diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_vdPC_full_c160.input b/appl/freeflow/navierstokes/sincos/params_vdP_vdPC_full_c160.input new file mode 100644 index 0000000..62d5795 --- /dev/null +++ b/appl/freeflow/navierstokes/sincos/params_vdP_vdPC_full_c160.input @@ -0,0 +1,78 @@ +[TimeLoop] +DtInitial = 0.01 # [s] +TEnd = 1.0 # [s] + +[Helper.Grid] +Positions0 = 0.25 0.75 +Positions1 = 0.25 0.75 #we don't have symmetry BCs +Cells0 = 160 +Cells1 = 160 +Grading0 = 1.0 +Grading1 = 1.0 + +[xCVs.Grid] +File = xCVs.dgf + +[yCVs.Grid] +File = yCVs.dgf + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_ff_sincos_vdP_full_c160 +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +VanDerPlasVersion = true +StartWithAnalytical = false +AveragedAnalyticalSolution = true +UseScvfLineAveraging = true + +[Component] +LiquidDensity = 1.0 +LiquidKinematicViscosity = 0.05 +MolarMass = 1.0 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +[Newton] +MaxSteps = 10 +TargetSteps = 4 +MaxRelativeShift = 1e-10 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true +MaxAbsoluteResidual = 1e-10 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = false +AddProcessRank = false + +[Flux] +UpwindWeight = 0.5 + +[Adaptivity] +NewParallelAlgo = false +UseOwn4PointCoefficients = false +Conservation = false +Adapt = true +LeftX = .4 +RightX = .6 +LowerY = .4 +UpperY = .6 diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_vdPC_full_c20.input b/appl/freeflow/navierstokes/sincos/params_vdP_vdPC_full_c20.input new file mode 100644 index 0000000..0aebdfb --- /dev/null +++ b/appl/freeflow/navierstokes/sincos/params_vdP_vdPC_full_c20.input @@ -0,0 +1,78 @@ +[TimeLoop] +DtInitial = 0.01 # [s] +TEnd = 1.0 # [s] + +[Helper.Grid] +Positions0 = 0.25 0.75 +Positions1 = 0.25 0.75 #we don't have symmetry BCs +Cells0 = 20 +Cells1 = 20 +Grading0 = 1.0 +Grading1 = 1.0 + +[xCVs.Grid] +File = xCVs.dgf + +[yCVs.Grid] +File = yCVs.dgf + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_ff_sincos_vdP_full_c20 +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +VanDerPlasVersion = true +StartWithAnalytical = false +AveragedAnalyticalSolution = true +UseScvfLineAveraging = true + +[Component] +LiquidDensity = 1.0 +LiquidKinematicViscosity = 0.05 +MolarMass = 1.0 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +[Newton] +MaxSteps = 10 +TargetSteps = 4 +MaxRelativeShift = 1e-10 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true +MaxAbsoluteResidual = 1e-10 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = false +AddProcessRank = false + +[Flux] +UpwindWeight = 0.5 + +[Adaptivity] +NewParallelAlgo = false +UseOwn4PointCoefficients = false +Conservation = false +Adapt = true +LeftX = .4 +RightX = .6 +LowerY = .4 +UpperY = .6 diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_vdPC_full_c240.input b/appl/freeflow/navierstokes/sincos/params_vdP_vdPC_full_c240.input new file mode 100644 index 0000000..436e5d8 --- /dev/null +++ b/appl/freeflow/navierstokes/sincos/params_vdP_vdPC_full_c240.input @@ -0,0 +1,78 @@ +[TimeLoop] +DtInitial = 0.01 # [s] +TEnd = 1.0 # [s] + +[Helper.Grid] +Positions0 = 0.25 0.75 +Positions1 = 0.25 0.75 #we don't have symmetry BCs +Cells0 = 240 +Cells1 = 240 +Grading0 = 1.0 +Grading1 = 1.0 + +[xCVs.Grid] +File = xCVs.dgf + +[yCVs.Grid] +File = yCVs.dgf + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_ff_sincos_vdP_full_c240 +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +VanDerPlasVersion = true +StartWithAnalytical = false +AveragedAnalyticalSolution = true +UseScvfLineAveraging = true + +[Component] +LiquidDensity = 1.0 +LiquidKinematicViscosity = 0.05 +MolarMass = 1.0 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +[Newton] +MaxSteps = 10 +TargetSteps = 4 +MaxRelativeShift = 1e-10 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true +MaxAbsoluteResidual = 1e-10 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = false +AddProcessRank = false + +[Flux] +UpwindWeight = 0.5 + +[Adaptivity] +NewParallelAlgo = false +UseOwn4PointCoefficients = false +Conservation = false +Adapt = true +LeftX = .4 +RightX = .6 +LowerY = .4 +UpperY = .6 diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_vdPC_full_c40.input b/appl/freeflow/navierstokes/sincos/params_vdP_vdPC_full_c40.input new file mode 100644 index 0000000..bc91d4b --- /dev/null +++ b/appl/freeflow/navierstokes/sincos/params_vdP_vdPC_full_c40.input @@ -0,0 +1,78 @@ +[TimeLoop] +DtInitial = 0.01 # [s] +TEnd = 1.0 # [s] + +[Helper.Grid] +Positions0 = 0.25 0.75 +Positions1 = 0.25 0.75 #we don't have symmetry BCs +Cells0 = 40 +Cells1 = 40 +Grading0 = 1.0 +Grading1 = 1.0 + +[xCVs.Grid] +File = xCVs.dgf + +[yCVs.Grid] +File = yCVs.dgf + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_ff_sincos_vdP_full_c40 +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +VanDerPlasVersion = true +StartWithAnalytical = false +AveragedAnalyticalSolution = true +UseScvfLineAveraging = true + +[Component] +LiquidDensity = 1.0 +LiquidKinematicViscosity = 0.05 +MolarMass = 1.0 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +[Newton] +MaxSteps = 10 +TargetSteps = 4 +MaxRelativeShift = 1e-10 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true +MaxAbsoluteResidual = 1e-10 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = false +AddProcessRank = false + +[Flux] +UpwindWeight = 0.5 + +[Adaptivity] +NewParallelAlgo = false +UseOwn4PointCoefficients = false +Conservation = false +Adapt = true +LeftX = .4 +RightX = .6 +LowerY = .4 +UpperY = .6 diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_vdPC_full_c80.input b/appl/freeflow/navierstokes/sincos/params_vdP_vdPC_full_c80.input new file mode 100644 index 0000000..81c2fe1 --- /dev/null +++ b/appl/freeflow/navierstokes/sincos/params_vdP_vdPC_full_c80.input @@ -0,0 +1,78 @@ +[TimeLoop] +DtInitial = 0.01 # [s] +TEnd = 1.0 # [s] + +[Helper.Grid] +Positions0 = 0.25 0.75 +Positions1 = 0.25 0.75 #we don't have symmetry BCs +Cells0 = 80 +Cells1 = 80 +Grading0 = 1.0 +Grading1 = 1.0 + +[xCVs.Grid] +File = xCVs.dgf + +[yCVs.Grid] +File = yCVs.dgf + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_ff_sincos_vdP_full_c80 +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +VanDerPlasVersion = true +StartWithAnalytical = false +AveragedAnalyticalSolution = true +UseScvfLineAveraging = true + +[Component] +LiquidDensity = 1.0 +LiquidKinematicViscosity = 0.05 +MolarMass = 1.0 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +[Newton] +MaxSteps = 10 +TargetSteps = 4 +MaxRelativeShift = 1e-10 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true +MaxAbsoluteResidual = 1e-10 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = false +AddProcessRank = false + +[Flux] +UpwindWeight = 0.5 + +[Adaptivity] +NewParallelAlgo = false +UseOwn4PointCoefficients = false +Conservation = false +Adapt = true +LeftX = .4 +RightX = .6 +LowerY = .4 +UpperY = .6 -- GitLab From 8ec11dd108242d535e6da7c3468ab7240b45d103 Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Fri, 24 Sep 2021 16:08:46 +0300 Subject: [PATCH 52/69] donea, channel, sincos fvd params --- .../channel/2d/params_ns_stat_fvd_c20.input | 74 ++++++++++++++++++ .../channel/2d/params_ns_stat_fvd_c40.input | 74 ++++++++++++++++++ .../channel/2d/params_ns_stat_fvd_c80.input | 74 ++++++++++++++++++ .../navierstokes/donea/params_fvd_c20.input | 50 ++++++++++++ .../navierstokes/donea/params_fvd_c40.input | 50 ++++++++++++ .../navierstokes/donea/params_fvd_c80.input | 50 ++++++++++++ .../sincos/params_vdP_fvd_c20.input | 77 +++++++++++++++++++ .../sincos/params_vdP_fvd_c40.input | 77 +++++++++++++++++++ .../sincos/params_vdP_fvd_c80.input | 77 +++++++++++++++++++ 9 files changed, 603 insertions(+) create mode 100644 appl/freeflow/navierstokes/channel/2d/params_ns_stat_fvd_c20.input create mode 100644 appl/freeflow/navierstokes/channel/2d/params_ns_stat_fvd_c40.input create mode 100644 appl/freeflow/navierstokes/channel/2d/params_ns_stat_fvd_c80.input create mode 100644 appl/freeflow/navierstokes/donea/params_fvd_c20.input create mode 100644 appl/freeflow/navierstokes/donea/params_fvd_c40.input create mode 100644 appl/freeflow/navierstokes/donea/params_fvd_c80.input create mode 100644 appl/freeflow/navierstokes/sincos/params_vdP_fvd_c20.input create mode 100644 appl/freeflow/navierstokes/sincos/params_vdP_fvd_c40.input create mode 100644 appl/freeflow/navierstokes/sincos/params_vdP_fvd_c80.input diff --git a/appl/freeflow/navierstokes/channel/2d/params_ns_stat_fvd_c20.input b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_fvd_c20.input new file mode 100644 index 0000000..ed42d99 --- /dev/null +++ b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_fvd_c20.input @@ -0,0 +1,74 @@ +[Helper.Grid] +Positions0 = 0 10 +Positions1 = 0 1 +Cells0 = 20 +Cells1 = 15 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_channel_ns_stat_c20 # name passed to the output routines +InletVelocity = 100 +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +AveragedAnalyticalSolution = false +UseScvfLineAveraging = true + +[Component] +MolarMass = 1.0 +LiquidDensity = 1 +LiquidKinematicViscosity = 1 + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-8 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true + +[Vtk] +WriteFaceData = false + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +# This test does actually not require setting the primary variable magnitues. +# This rather serves as a demonstration of how to use the feature. +[CellCenter.Assembly] +NumericDifference.PriVarMagnitude = 1e5 # pressure is in the order of 1e5 + +[Face.Assembly] +NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 + +[Adaptivity] +LinearInterpolation = true +Conservation = true +Adapt = true +LeftX = 2 +RightX = 8 +LowerY = 0.2 +UpperY = 0.8 + +[Adaptive] +RefineAtDirichletBC = 0 +RefineAtFluxBC = 1 +MinLevel = 0 +MaxLevel = 0 +CoarsenTolerance = 1e-4 +RefineTolerance = 2e-1 diff --git a/appl/freeflow/navierstokes/channel/2d/params_ns_stat_fvd_c40.input b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_fvd_c40.input new file mode 100644 index 0000000..2688a1b --- /dev/null +++ b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_fvd_c40.input @@ -0,0 +1,74 @@ +[Helper.Grid] +Positions0 = 0 10 +Positions1 = 0 1 +Cells0 = 40 +Cells1 = 30 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_channel_ns_stat_c40 # name passed to the output routines +InletVelocity = 100 +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +AveragedAnalyticalSolution = false +UseScvfLineAveraging = true + +[Component] +MolarMass = 1.0 +LiquidDensity = 1 +LiquidKinematicViscosity = 1 + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-8 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true + +[Vtk] +WriteFaceData = false + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +# This test does actually not require setting the primary variable magnitues. +# This rather serves as a demonstration of how to use the feature. +[CellCenter.Assembly] +NumericDifference.PriVarMagnitude = 1e5 # pressure is in the order of 1e5 + +[Face.Assembly] +NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 + +[Adaptivity] +LinearInterpolation = true +Conservation = true +Adapt = true +LeftX = 2 +RightX = 8 +LowerY = 0.2 +UpperY = 0.8 + +[Adaptive] +RefineAtDirichletBC = 0 +RefineAtFluxBC = 1 +MinLevel = 0 +MaxLevel = 0 +CoarsenTolerance = 1e-4 +RefineTolerance = 2e-1 diff --git a/appl/freeflow/navierstokes/channel/2d/params_ns_stat_fvd_c80.input b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_fvd_c80.input new file mode 100644 index 0000000..aabd06e --- /dev/null +++ b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_fvd_c80.input @@ -0,0 +1,74 @@ +[Helper.Grid] +Positions0 = 0 10 +Positions1 = 0 1 +Cells0 = 80 +Cells1 = 60 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_channel_ns_stat_c80 # name passed to the output routines +InletVelocity = 100 +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +AveragedAnalyticalSolution = false +UseScvfLineAveraging = true + +[Component] +MolarMass = 1.0 +LiquidDensity = 1 +LiquidKinematicViscosity = 1 + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-8 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true + +[Vtk] +WriteFaceData = false + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +# This test does actually not require setting the primary variable magnitues. +# This rather serves as a demonstration of how to use the feature. +[CellCenter.Assembly] +NumericDifference.PriVarMagnitude = 1e5 # pressure is in the order of 1e5 + +[Face.Assembly] +NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 + +[Adaptivity] +LinearInterpolation = true +Conservation = true +Adapt = true +LeftX = 2 +RightX = 8 +LowerY = 0.2 +UpperY = 0.8 + +[Adaptive] +RefineAtDirichletBC = 0 +RefineAtFluxBC = 1 +MinLevel = 0 +MaxLevel = 0 +CoarsenTolerance = 1e-4 +RefineTolerance = 2e-1 diff --git a/appl/freeflow/navierstokes/donea/params_fvd_c20.input b/appl/freeflow/navierstokes/donea/params_fvd_c20.input new file mode 100644 index 0000000..4b598dc --- /dev/null +++ b/appl/freeflow/navierstokes/donea/params_fvd_c20.input @@ -0,0 +1,50 @@ +[Helper.Grid] +Positions0 = 0 1 +Positions1 = 0 1 +Cells0 = 20 +Cells1 = 20 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = donea_full_c20 # name passed to the output routines +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = false +StartWithAnalytical = false +AveragedAnalyticalSolution = false +UseScvfLineAveraging = true + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-5 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = true + +[Adaptivity] +Adapt = true +LinearInterpolation = true #false: quadratic +Conservation = true + +[Component] +MolarMass = 1.0 +LiquidDensity = 1.0 +LiquidKinematicViscosity = 1.0 diff --git a/appl/freeflow/navierstokes/donea/params_fvd_c40.input b/appl/freeflow/navierstokes/donea/params_fvd_c40.input new file mode 100644 index 0000000..508aed4 --- /dev/null +++ b/appl/freeflow/navierstokes/donea/params_fvd_c40.input @@ -0,0 +1,50 @@ +[Helper.Grid] +Positions0 = 0 1 +Positions1 = 0 1 +Cells0 = 40 +Cells1 = 40 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = donea_full_c40 # name passed to the output routines +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = false +StartWithAnalytical = false +AveragedAnalyticalSolution = false +UseScvfLineAveraging = true + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-5 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = true + +[Adaptivity] +Adapt = true +LinearInterpolation = true #false: quadratic +Conservation = true + +[Component] +MolarMass = 1.0 +LiquidDensity = 1.0 +LiquidKinematicViscosity = 1.0 diff --git a/appl/freeflow/navierstokes/donea/params_fvd_c80.input b/appl/freeflow/navierstokes/donea/params_fvd_c80.input new file mode 100644 index 0000000..3f47b7c --- /dev/null +++ b/appl/freeflow/navierstokes/donea/params_fvd_c80.input @@ -0,0 +1,50 @@ +[Helper.Grid] +Positions0 = 0 1 +Positions1 = 0 1 +Cells0 = 80 +Cells1 = 80 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = donea_full_c80 # name passed to the output routines +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = false +StartWithAnalytical = false +AveragedAnalyticalSolution = false +UseScvfLineAveraging = true + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-5 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = true + +[Adaptivity] +Adapt = true +LinearInterpolation = true #false: quadratic +Conservation = true + +[Component] +MolarMass = 1.0 +LiquidDensity = 1.0 +LiquidKinematicViscosity = 1.0 diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_fvd_c20.input b/appl/freeflow/navierstokes/sincos/params_vdP_fvd_c20.input new file mode 100644 index 0000000..6413bd3 --- /dev/null +++ b/appl/freeflow/navierstokes/sincos/params_vdP_fvd_c20.input @@ -0,0 +1,77 @@ +[TimeLoop] +DtInitial = 0.01 # [s] +TEnd = 1.0 # [s] + +[Helper.Grid] +Positions0 = 0.25 0.75 +Positions1 = 0.25 0.75 #we don't have symmetry BCs +Cells0 = 20 +Cells1 = 20 +Grading0 = 1.0 +Grading1 = 1.0 + +[xCVs.Grid] +File = xCVs.dgf + +[yCVs.Grid] +File = yCVs.dgf + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_ff_sincos_vdP_full_c20 +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +VanDerPlasVersion = true +StartWithAnalytical = false +AveragedAnalyticalSolution = true +UseScvfLineAveraging = true + +[Component] +LiquidDensity = 1.0 +LiquidKinematicViscosity = 0.05 +MolarMass = 1.0 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +[Newton] +MaxSteps = 10 +TargetSteps = 4 +MaxRelativeShift = 1e-10 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true +MaxAbsoluteResidual = 1e-10 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = false +AddProcessRank = false + +[Flux] +UpwindWeight = 0.5 + +[Adaptivity] +LinearInterpolation = true +Conservation = true +Adapt = true +LeftX = .4 +RightX = .6 +LowerY = .4 +UpperY = .6 diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_fvd_c40.input b/appl/freeflow/navierstokes/sincos/params_vdP_fvd_c40.input new file mode 100644 index 0000000..018ceb5 --- /dev/null +++ b/appl/freeflow/navierstokes/sincos/params_vdP_fvd_c40.input @@ -0,0 +1,77 @@ +[TimeLoop] +DtInitial = 0.01 # [s] +TEnd = 1.0 # [s] + +[Helper.Grid] +Positions0 = 0.25 0.75 +Positions1 = 0.25 0.75 #we don't have symmetry BCs +Cells0 = 40 +Cells1 = 40 +Grading0 = 1.0 +Grading1 = 1.0 + +[xCVs.Grid] +File = xCVs.dgf + +[yCVs.Grid] +File = yCVs.dgf + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_ff_sincos_vdP_full_c40 +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +VanDerPlasVersion = true +StartWithAnalytical = false +AveragedAnalyticalSolution = true +UseScvfLineAveraging = true + +[Component] +LiquidDensity = 1.0 +LiquidKinematicViscosity = 0.05 +MolarMass = 1.0 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +[Newton] +MaxSteps = 10 +TargetSteps = 4 +MaxRelativeShift = 1e-10 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true +MaxAbsoluteResidual = 1e-10 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = false +AddProcessRank = false + +[Flux] +UpwindWeight = 0.5 + +[Adaptivity] +LinearInterpolation = true +Conservation = true +Adapt = true +LeftX = .4 +RightX = .6 +LowerY = .4 +UpperY = .6 diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_fvd_c80.input b/appl/freeflow/navierstokes/sincos/params_vdP_fvd_c80.input new file mode 100644 index 0000000..808cf01 --- /dev/null +++ b/appl/freeflow/navierstokes/sincos/params_vdP_fvd_c80.input @@ -0,0 +1,77 @@ +[TimeLoop] +DtInitial = 0.01 # [s] +TEnd = 1.0 # [s] + +[Helper.Grid] +Positions0 = 0.25 0.75 +Positions1 = 0.25 0.75 #we don't have symmetry BCs +Cells0 = 80 +Cells1 = 80 +Grading0 = 1.0 +Grading1 = 1.0 + +[xCVs.Grid] +File = xCVs.dgf + +[yCVs.Grid] +File = yCVs.dgf + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_ff_sincos_vdP_full_c80 +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +VanDerPlasVersion = true +StartWithAnalytical = false +AveragedAnalyticalSolution = true +UseScvfLineAveraging = true + +[Component] +LiquidDensity = 1.0 +LiquidKinematicViscosity = 0.05 +MolarMass = 1.0 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +[Newton] +MaxSteps = 10 +TargetSteps = 4 +MaxRelativeShift = 1e-10 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true +MaxAbsoluteResidual = 1e-10 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = false +AddProcessRank = false + +[Flux] +UpwindWeight = 0.5 + +[Adaptivity] +LinearInterpolation = true +Conservation = true +Adapt = true +LeftX = .4 +RightX = .6 +LowerY = .4 +UpperY = .6 -- GitLab From cf6d9fe45d7c752de8aa50e967c189faede5df03 Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Wed, 29 Sep 2021 12:20:46 +0300 Subject: [PATCH 53/69] Some test params changes --- .../freeflow/navierstokes/angeli/params.input | 8 +- .../sincos/params_vdP_fvd_c120.input | 77 +++++++++++++++++++ .../1p_1p/convergencetest/CMakeLists.txt | 1 + 3 files changed, 82 insertions(+), 4 deletions(-) create mode 100644 appl/freeflow/navierstokes/sincos/params_vdP_fvd_c120.input diff --git a/appl/freeflow/navierstokes/angeli/params.input b/appl/freeflow/navierstokes/angeli/params.input index b0c3753..4eff65a 100644 --- a/appl/freeflow/navierstokes/angeli/params.input +++ b/appl/freeflow/navierstokes/angeli/params.input @@ -60,10 +60,10 @@ DoFirstOrderLocalTruncError = false [Adaptivity] Conservation = false Adapt = true -LeftX = .4 -RightX = .6 -LowerY = .4 -UpperY = .6 +LeftX = .2 +RightX = .8 +LowerY = .2 +UpperY = .8 LinearInterpolation = false DebugDof = -1 diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_fvd_c120.input b/appl/freeflow/navierstokes/sincos/params_vdP_fvd_c120.input new file mode 100644 index 0000000..db3460d --- /dev/null +++ b/appl/freeflow/navierstokes/sincos/params_vdP_fvd_c120.input @@ -0,0 +1,77 @@ +[TimeLoop] +DtInitial = 0.01 # [s] +TEnd = 1.0 # [s] + +[Helper.Grid] +Positions0 = 0.25 0.75 +Positions1 = 0.25 0.75 #we don't have symmetry BCs +Cells0 = 120 +Cells1 = 120 +Grading0 = 1.0 +Grading1 = 1.0 + +[xCVs.Grid] +File = xCVs.dgf + +[yCVs.Grid] +File = yCVs.dgf + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_ff_sincos_vdP_full_c120 +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +VanDerPlasVersion = true +StartWithAnalytical = false +AveragedAnalyticalSolution = true +UseScvfLineAveraging = true + +[Component] +LiquidDensity = 1.0 +LiquidKinematicViscosity = 0.05 +MolarMass = 1.0 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +[Newton] +MaxSteps = 10 +TargetSteps = 4 +MaxRelativeShift = 1e-10 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true +MaxAbsoluteResidual = 1e-10 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = false +AddProcessRank = false + +[Flux] +UpwindWeight = 0.5 + +[Adaptivity] +LinearInterpolation = true +Conservation = true +Adapt = true +LeftX = .4 +RightX = .6 +LowerY = .4 +UpperY = .6 diff --git a/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/CMakeLists.txt b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/CMakeLists.txt index cace090..29cd1ae 100644 --- a/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/CMakeLists.txt +++ b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/CMakeLists.txt @@ -1,4 +1,5 @@ add_input_file_links() +set(CMAKE_BUILD_TYPE Debug) dune_symlink_to_source_files(FILES "convergencetest.py") add_executable(test_md_boundary_darcy1p_freeflow1p_convtest EXCLUDE_FROM_ALL main.cc) -- GitLab From c3a6eba6cf7b6092d8532eac18bcfd739b702990 Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Fri, 1 Oct 2021 14:28:28 +0300 Subject: [PATCH 54/69] donea vdP coeffs version --- .../navierstokes/donea/params_vdP_c20.input | 51 +++++++++++++++++++ .../navierstokes/donea/params_vdP_c40.input | 51 +++++++++++++++++++ .../navierstokes/donea/params_vdP_c80.input | 51 +++++++++++++++++++ 3 files changed, 153 insertions(+) create mode 100644 appl/freeflow/navierstokes/donea/params_vdP_c20.input create mode 100644 appl/freeflow/navierstokes/donea/params_vdP_c40.input create mode 100644 appl/freeflow/navierstokes/donea/params_vdP_c80.input diff --git a/appl/freeflow/navierstokes/donea/params_vdP_c20.input b/appl/freeflow/navierstokes/donea/params_vdP_c20.input new file mode 100644 index 0000000..86312b2 --- /dev/null +++ b/appl/freeflow/navierstokes/donea/params_vdP_c20.input @@ -0,0 +1,51 @@ +[Helper.Grid] +Positions0 = 0 1 +Positions1 = 0 1 +Cells0 = 20 +Cells1 = 20 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = donea_full_vdP_c20 # name passed to the output routines +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = false +StartWithAnalytical = false +AveragedAnalyticalSolution = false +UseScvfLineAveraging = true + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-5 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = true + +[Adaptivity] +UseOwn4PointCoefficients = false +Adapt = true +LinearInterpolation = false #false: quadratic +Conservation = false + +[Component] +MolarMass = 1.0 +LiquidDensity = 1.0 +LiquidKinematicViscosity = 1.0 diff --git a/appl/freeflow/navierstokes/donea/params_vdP_c40.input b/appl/freeflow/navierstokes/donea/params_vdP_c40.input new file mode 100644 index 0000000..6fcabc5 --- /dev/null +++ b/appl/freeflow/navierstokes/donea/params_vdP_c40.input @@ -0,0 +1,51 @@ +[Helper.Grid] +Positions0 = 0 1 +Positions1 = 0 1 +Cells0 = 40 +Cells1 = 40 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = donea_full_vdP_c40 # name passed to the output routines +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = false +StartWithAnalytical = false +AveragedAnalyticalSolution = false +UseScvfLineAveraging = true + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-5 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = true + +[Adaptivity] +UseOwn4PointCoefficients = false +Adapt = true +LinearInterpolation = false #false: quadratic +Conservation = false + +[Component] +MolarMass = 1.0 +LiquidDensity = 1.0 +LiquidKinematicViscosity = 1.0 diff --git a/appl/freeflow/navierstokes/donea/params_vdP_c80.input b/appl/freeflow/navierstokes/donea/params_vdP_c80.input new file mode 100644 index 0000000..c4e738d --- /dev/null +++ b/appl/freeflow/navierstokes/donea/params_vdP_c80.input @@ -0,0 +1,51 @@ +[Helper.Grid] +Positions0 = 0 1 +Positions1 = 0 1 +Cells0 = 80 +Cells1 = 80 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = donea_full_vdP_c80 # name passed to the output routines +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = false +StartWithAnalytical = false +AveragedAnalyticalSolution = false +UseScvfLineAveraging = true + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-5 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = true + +[Adaptivity] +UseOwn4PointCoefficients = false +Adapt = true +LinearInterpolation = false #false: quadratic +Conservation = false + +[Component] +MolarMass = 1.0 +LiquidDensity = 1.0 +LiquidKinematicViscosity = 1.0 -- GitLab From 6574de87f710e9f5d1b286b812931c250c3e8f49 Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Fri, 1 Oct 2021 20:31:57 +0300 Subject: [PATCH 55/69] Some late night unrefined comparison tests --- .../navierstokes/donea/params_c80.input | 50 ++++++++++++ .../navierstokes/sincos/params_c10.input | 77 ++++++++++++++++++ .../navierstokes/sincos/params_c10_cvd.input | 78 +++++++++++++++++++ .../navierstokes/sincos/params_c10_vdP.input | 78 +++++++++++++++++++ .../navierstokes/sincos/params_c120.input | 77 ++++++++++++++++++ 5 files changed, 360 insertions(+) create mode 100644 appl/freeflow/navierstokes/donea/params_c80.input create mode 100644 appl/freeflow/navierstokes/sincos/params_c10.input create mode 100644 appl/freeflow/navierstokes/sincos/params_c10_cvd.input create mode 100644 appl/freeflow/navierstokes/sincos/params_c10_vdP.input create mode 100644 appl/freeflow/navierstokes/sincos/params_c120.input diff --git a/appl/freeflow/navierstokes/donea/params_c80.input b/appl/freeflow/navierstokes/donea/params_c80.input new file mode 100644 index 0000000..5b1684d --- /dev/null +++ b/appl/freeflow/navierstokes/donea/params_c80.input @@ -0,0 +1,50 @@ +[Helper.Grid] +Positions0 = 0 1 +Positions1 = 0 1 +Cells0 = 80 +Cells1 = 80 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = donea_c80 # name passed to the output routines +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = false +StartWithAnalytical = false +AveragedAnalyticalSolution = false +UseScvfLineAveraging = true + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-5 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = true + +[Adaptivity] +Adapt = false +LinearInterpolation = true #false: quadratic +Conservation = true + +[Component] +MolarMass = 1.0 +LiquidDensity = 1.0 +LiquidKinematicViscosity = 1.0 diff --git a/appl/freeflow/navierstokes/sincos/params_c10.input b/appl/freeflow/navierstokes/sincos/params_c10.input new file mode 100644 index 0000000..db46681 --- /dev/null +++ b/appl/freeflow/navierstokes/sincos/params_c10.input @@ -0,0 +1,77 @@ +[TimeLoop] +DtInitial = 0.01 # [s] +TEnd = 1.0 # [s] + +[Helper.Grid] +Positions0 = 0.25 0.75 +Positions1 = 0.25 0.75 #we don't have symmetry BCs +Cells0 = 10 +Cells1 = 10 +Grading0 = 1.0 +Grading1 = 1.0 + +[xCVs.Grid] +File = xCVs.dgf + +[yCVs.Grid] +File = yCVs.dgf + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_ff_sincos_c10 +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +VanDerPlasVersion = true +StartWithAnalytical = false +AveragedAnalyticalSolution = true +UseScvfLineAveraging = true + +[Component] +LiquidDensity = 1.0 +LiquidKinematicViscosity = 0.05 +MolarMass = 1.0 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +[Newton] +MaxSteps = 10 +TargetSteps = 4 +MaxRelativeShift = 1e-10 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true +MaxAbsoluteResidual = 1e-10 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = false +AddProcessRank = false + +[Flux] +UpwindWeight = 0.5 + +[Adaptivity] +LinearInterpolation = true +Conservation = true +Adapt = false +LeftX = .4 +RightX = .6 +LowerY = .4 +UpperY = .6 diff --git a/appl/freeflow/navierstokes/sincos/params_c10_cvd.input b/appl/freeflow/navierstokes/sincos/params_c10_cvd.input new file mode 100644 index 0000000..36cf936 --- /dev/null +++ b/appl/freeflow/navierstokes/sincos/params_c10_cvd.input @@ -0,0 +1,78 @@ +[TimeLoop] +DtInitial = 0.01 # [s] +TEnd = 1.0 # [s] + +[Helper.Grid] +Positions0 = 0.25 0.75 +Positions1 = 0.25 0.75 #we don't have symmetry BCs +Cells0 = 10 +Cells1 = 10 +Grading0 = 1.0 +Grading1 = 1.0 + +[xCVs.Grid] +File = xCVs.dgf + +[yCVs.Grid] +File = yCVs.dgf + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_ff_sincos_c10_cvd +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +VanDerPlasVersion = true +StartWithAnalytical = false +AveragedAnalyticalSolution = true +UseScvfLineAveraging = true + +[Component] +LiquidDensity = 1.0 +LiquidKinematicViscosity = 0.05 +MolarMass = 1.0 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +[Newton] +MaxSteps = 10 +TargetSteps = 4 +MaxRelativeShift = 1e-10 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true +MaxAbsoluteResidual = 1e-10 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = false +AddProcessRank = false + +[Flux] +UpwindWeight = 0.5 + +[Adaptivity] +UseOwn4PointCoefficients = true +LinearInterpolation = false +Conservation = false +Adapt = true +LeftX = .4 +RightX = .6 +LowerY = .4 +UpperY = .6 diff --git a/appl/freeflow/navierstokes/sincos/params_c10_vdP.input b/appl/freeflow/navierstokes/sincos/params_c10_vdP.input new file mode 100644 index 0000000..cec60d6 --- /dev/null +++ b/appl/freeflow/navierstokes/sincos/params_c10_vdP.input @@ -0,0 +1,78 @@ +[TimeLoop] +DtInitial = 0.01 # [s] +TEnd = 1.0 # [s] + +[Helper.Grid] +Positions0 = 0.25 0.75 +Positions1 = 0.25 0.75 #we don't have symmetry BCs +Cells0 = 10 +Cells1 = 10 +Grading0 = 1.0 +Grading1 = 1.0 + +[xCVs.Grid] +File = xCVs.dgf + +[yCVs.Grid] +File = yCVs.dgf + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_ff_sincos_c10_vdP +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +VanDerPlasVersion = true +StartWithAnalytical = false +AveragedAnalyticalSolution = true +UseScvfLineAveraging = true + +[Component] +LiquidDensity = 1.0 +LiquidKinematicViscosity = 0.05 +MolarMass = 1.0 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +[Newton] +MaxSteps = 10 +TargetSteps = 4 +MaxRelativeShift = 1e-10 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true +MaxAbsoluteResidual = 1e-10 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = false +AddProcessRank = false + +[Flux] +UpwindWeight = 0.5 + +[Adaptivity] +UseOwn4PointCoefficients = false +LinearInterpolation = false +Conservation = false +Adapt = true +LeftX = .4 +RightX = .6 +LowerY = .4 +UpperY = .6 diff --git a/appl/freeflow/navierstokes/sincos/params_c120.input b/appl/freeflow/navierstokes/sincos/params_c120.input new file mode 100644 index 0000000..a87370c --- /dev/null +++ b/appl/freeflow/navierstokes/sincos/params_c120.input @@ -0,0 +1,77 @@ +[TimeLoop] +DtInitial = 0.01 # [s] +TEnd = 1.0 # [s] + +[Helper.Grid] +Positions0 = 0.25 0.75 +Positions1 = 0.25 0.75 #we don't have symmetry BCs +Cells0 = 120 +Cells1 = 120 +Grading0 = 1.0 +Grading1 = 1.0 + +[xCVs.Grid] +File = xCVs.dgf + +[yCVs.Grid] +File = yCVs.dgf + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_ff_sincos_c120 +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +VanDerPlasVersion = true +StartWithAnalytical = false +AveragedAnalyticalSolution = true +UseScvfLineAveraging = true + +[Component] +LiquidDensity = 1.0 +LiquidKinematicViscosity = 0.05 +MolarMass = 1.0 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +[Newton] +MaxSteps = 10 +TargetSteps = 4 +MaxRelativeShift = 1e-10 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true +MaxAbsoluteResidual = 1e-10 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = false +AddProcessRank = false + +[Flux] +UpwindWeight = 0.5 + +[Adaptivity] +LinearInterpolation = true +Conservation = true +Adapt = false +LeftX = .4 +RightX = .6 +LowerY = .4 +UpperY = .6 -- GitLab From b8ccbf2aaa48f34260c002a8de57c16cfdecfa44 Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Sat, 2 Oct 2021 09:54:32 +0300 Subject: [PATCH 56/69] donea comparison to unrefined --- .../navierstokes/donea/params_c10_cvd.input | 50 ++++++++++++++++++ .../donea/params_c10_cvd_vdP.input | 51 +++++++++++++++++++ .../navierstokes/donea/params_c10_fvd.input | 50 ++++++++++++++++++ .../navierstokes/donea/params_c10_unref.input | 50 ++++++++++++++++++ 4 files changed, 201 insertions(+) create mode 100644 appl/freeflow/navierstokes/donea/params_c10_cvd.input create mode 100644 appl/freeflow/navierstokes/donea/params_c10_cvd_vdP.input create mode 100644 appl/freeflow/navierstokes/donea/params_c10_fvd.input create mode 100644 appl/freeflow/navierstokes/donea/params_c10_unref.input diff --git a/appl/freeflow/navierstokes/donea/params_c10_cvd.input b/appl/freeflow/navierstokes/donea/params_c10_cvd.input new file mode 100644 index 0000000..6f78185 --- /dev/null +++ b/appl/freeflow/navierstokes/donea/params_c10_cvd.input @@ -0,0 +1,50 @@ +[Helper.Grid] +Positions0 = 0 1 +Positions1 = 0 1 +Cells0 = 10 +Cells1 = 10 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = donea_c10_cvd # name passed to the output routines +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = false +StartWithAnalytical = false +AveragedAnalyticalSolution = false +UseScvfLineAveraging = true + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-5 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = true + +[Adaptivity] +Adapt = true +LinearInterpolation = false #false: quadratic +Conservation = false + +[Component] +MolarMass = 1.0 +LiquidDensity = 1.0 +LiquidKinematicViscosity = 1.0 diff --git a/appl/freeflow/navierstokes/donea/params_c10_cvd_vdP.input b/appl/freeflow/navierstokes/donea/params_c10_cvd_vdP.input new file mode 100644 index 0000000..fcadd76 --- /dev/null +++ b/appl/freeflow/navierstokes/donea/params_c10_cvd_vdP.input @@ -0,0 +1,51 @@ +[Helper.Grid] +Positions0 = 0 1 +Positions1 = 0 1 +Cells0 = 10 +Cells1 = 10 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = donea_c10_cvd_vdP # name passed to the output routines +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = false +StartWithAnalytical = false +AveragedAnalyticalSolution = false +UseScvfLineAveraging = true + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-5 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = true + +[Adaptivity] +UseOwn4PointCoefficients = false +Adapt = true +LinearInterpolation = false #false: quadratic +Conservation = false + +[Component] +MolarMass = 1.0 +LiquidDensity = 1.0 +LiquidKinematicViscosity = 1.0 diff --git a/appl/freeflow/navierstokes/donea/params_c10_fvd.input b/appl/freeflow/navierstokes/donea/params_c10_fvd.input new file mode 100644 index 0000000..c308381 --- /dev/null +++ b/appl/freeflow/navierstokes/donea/params_c10_fvd.input @@ -0,0 +1,50 @@ +[Helper.Grid] +Positions0 = 0 1 +Positions1 = 0 1 +Cells0 = 10 +Cells1 = 10 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = donea_c10_fvd # name passed to the output routines +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = false +StartWithAnalytical = false +AveragedAnalyticalSolution = false +UseScvfLineAveraging = true + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-5 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = true + +[Adaptivity] +Adapt = true +LinearInterpolation = true #false: quadratic +Conservation = false + +[Component] +MolarMass = 1.0 +LiquidDensity = 1.0 +LiquidKinematicViscosity = 1.0 diff --git a/appl/freeflow/navierstokes/donea/params_c10_unref.input b/appl/freeflow/navierstokes/donea/params_c10_unref.input new file mode 100644 index 0000000..c0f0982 --- /dev/null +++ b/appl/freeflow/navierstokes/donea/params_c10_unref.input @@ -0,0 +1,50 @@ +[Helper.Grid] +Positions0 = 0 1 +Positions1 = 0 1 +Cells0 = 10 +Cells1 = 10 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = donea_c10_unref # name passed to the output routines +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = false +StartWithAnalytical = false +AveragedAnalyticalSolution = false +UseScvfLineAveraging = true + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-5 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = true + +[Adaptivity] +Adapt = false +LinearInterpolation = true #false: quadratic +Conservation = false + +[Component] +MolarMass = 1.0 +LiquidDensity = 1.0 +LiquidKinematicViscosity = 1.0 -- GitLab From f2604d65b1be28d5de0ddcbc3b365b6323ffcf44 Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Sat, 2 Oct 2021 10:59:00 +0300 Subject: [PATCH 57/69] angeli unrefined 10 cell comparison --- .../navierstokes/angeli/params_c10_cvd.input | 80 ++++++++++++++++++ .../angeli/params_c10_cvd_vdP.input | 81 +++++++++++++++++++ .../navierstokes/angeli/params_c10_fvd.input | 80 ++++++++++++++++++ .../angeli/params_c10_unref.input | 78 ++++++++++++++++++ 4 files changed, 319 insertions(+) create mode 100644 appl/freeflow/navierstokes/angeli/params_c10_cvd.input create mode 100644 appl/freeflow/navierstokes/angeli/params_c10_cvd_vdP.input create mode 100644 appl/freeflow/navierstokes/angeli/params_c10_fvd.input create mode 100644 appl/freeflow/navierstokes/angeli/params_c10_unref.input diff --git a/appl/freeflow/navierstokes/angeli/params_c10_cvd.input b/appl/freeflow/navierstokes/angeli/params_c10_cvd.input new file mode 100644 index 0000000..82e1099 --- /dev/null +++ b/appl/freeflow/navierstokes/angeli/params_c10_cvd.input @@ -0,0 +1,80 @@ +[TimeLoop] +DtInitial = 1e-4 # [s] +TEnd = 1e-2 # [s] + +[Helper.Grid] +Positions0 = 0 1 +Positions1 = 0 1 +Cells0 = 10 +Cells1 = 10 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_angeli_c10_cvd # name passed to the output routines +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +ReadDofBasedPressure = false +ReadDofBasedVelocity = false +UseScvfLineAveraging = true +UseContiSourceAveraging = true +QuadratureOrder = 6 #among others for continuity-residual to become closer to zero + +[Component] +LiquidDensity = 1 +LiquidKinematicViscosity = 0.1 +MolarMass = 1. + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +[Newton] +MaxSteps = 20 +TargetSteps = 20 +MaxRelativeShift = 1e-5 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = false + +[Numerics] +DoFirstOrderLocalTruncError = false + +[Adaptivity] +Conservation = false +Adapt = true +LeftX = .2 +RightX = .8 +LowerY = .2 +UpperY = .8 +LinearInterpolation = false +DebugDof = -1 + +[VelocityReadIn] +NumFileEntries = 260 +XFileName = "/home/melanie/Desktop/daten_IBAMR/SinusCosinus/velocitiesXPositions.txt" +YFileName = "/home/melanie/Desktop/daten_IBAMR/SinusCosinus/velocitiesYPositions.txt" +ValueFileName = "/home/melanie/Desktop/daten_IBAMR/SinusCosinus/velocities.txt" + +[PressureReadIn] +NumFileEntries = 116; +XFileName = "/home/melanie/Desktop/daten_IBAMR/SinusCosinus/pressuresXPositions.txt" +YFileName = "/home/melanie/Desktop/daten_IBAMR/SinusCosinus/pressuresYPositions.txt" +ValuesFileName = "/home/melanie/Desktop/daten_IBAMR/SinusCosinus/pressures.txt" diff --git a/appl/freeflow/navierstokes/angeli/params_c10_cvd_vdP.input b/appl/freeflow/navierstokes/angeli/params_c10_cvd_vdP.input new file mode 100644 index 0000000..622189d --- /dev/null +++ b/appl/freeflow/navierstokes/angeli/params_c10_cvd_vdP.input @@ -0,0 +1,81 @@ +[TimeLoop] +DtInitial = 1e-4 # [s] +TEnd = 1e-2 # [s] + +[Helper.Grid] +Positions0 = 0 1 +Positions1 = 0 1 +Cells0 = 10 +Cells1 = 10 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_angeli_c10_cvd_vdP # name passed to the output routines +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +ReadDofBasedPressure = false +ReadDofBasedVelocity = false +UseScvfLineAveraging = true +UseContiSourceAveraging = true +QuadratureOrder = 6 #among others for continuity-residual to become closer to zero + +[Component] +LiquidDensity = 1 +LiquidKinematicViscosity = 0.1 +MolarMass = 1. + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +[Newton] +MaxSteps = 20 +TargetSteps = 20 +MaxRelativeShift = 1e-5 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = false + +[Numerics] +DoFirstOrderLocalTruncError = false + +[Adaptivity] +UseOwn4PointCoefficients = false +Conservation = false +Adapt = true +LeftX = .2 +RightX = .8 +LowerY = .2 +UpperY = .8 +LinearInterpolation = false +DebugDof = -1 + +[VelocityReadIn] +NumFileEntries = 260 +XFileName = "/home/melanie/Desktop/daten_IBAMR/SinusCosinus/velocitiesXPositions.txt" +YFileName = "/home/melanie/Desktop/daten_IBAMR/SinusCosinus/velocitiesYPositions.txt" +ValueFileName = "/home/melanie/Desktop/daten_IBAMR/SinusCosinus/velocities.txt" + +[PressureReadIn] +NumFileEntries = 116; +XFileName = "/home/melanie/Desktop/daten_IBAMR/SinusCosinus/pressuresXPositions.txt" +YFileName = "/home/melanie/Desktop/daten_IBAMR/SinusCosinus/pressuresYPositions.txt" +ValuesFileName = "/home/melanie/Desktop/daten_IBAMR/SinusCosinus/pressures.txt" diff --git a/appl/freeflow/navierstokes/angeli/params_c10_fvd.input b/appl/freeflow/navierstokes/angeli/params_c10_fvd.input new file mode 100644 index 0000000..07eae0c --- /dev/null +++ b/appl/freeflow/navierstokes/angeli/params_c10_fvd.input @@ -0,0 +1,80 @@ +[TimeLoop] +DtInitial = 1e-4 # [s] +TEnd = 1e-2 # [s] + +[Helper.Grid] +Positions0 = 0 1 +Positions1 = 0 1 +Cells0 = 10 +Cells1 = 10 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_angeli_c10_fvd # name passed to the output routines +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +ReadDofBasedPressure = false +ReadDofBasedVelocity = false +UseScvfLineAveraging = true +UseContiSourceAveraging = true +QuadratureOrder = 6 #among others for continuity-residual to become closer to zero + +[Component] +LiquidDensity = 1 +LiquidKinematicViscosity = 0.1 +MolarMass = 1. + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +[Newton] +MaxSteps = 20 +TargetSteps = 20 +MaxRelativeShift = 1e-5 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = false + +[Numerics] +DoFirstOrderLocalTruncError = false + +[Adaptivity] +Conservation = false +Adapt = true +LeftX = .2 +RightX = .8 +LowerY = .2 +UpperY = .8 +LinearInterpolation = true +DebugDof = -1 + +[VelocityReadIn] +NumFileEntries = 260 +XFileName = "/home/melanie/Desktop/daten_IBAMR/SinusCosinus/velocitiesXPositions.txt" +YFileName = "/home/melanie/Desktop/daten_IBAMR/SinusCosinus/velocitiesYPositions.txt" +ValueFileName = "/home/melanie/Desktop/daten_IBAMR/SinusCosinus/velocities.txt" + +[PressureReadIn] +NumFileEntries = 116; +XFileName = "/home/melanie/Desktop/daten_IBAMR/SinusCosinus/pressuresXPositions.txt" +YFileName = "/home/melanie/Desktop/daten_IBAMR/SinusCosinus/pressuresYPositions.txt" +ValuesFileName = "/home/melanie/Desktop/daten_IBAMR/SinusCosinus/pressures.txt" diff --git a/appl/freeflow/navierstokes/angeli/params_c10_unref.input b/appl/freeflow/navierstokes/angeli/params_c10_unref.input new file mode 100644 index 0000000..7b21052 --- /dev/null +++ b/appl/freeflow/navierstokes/angeli/params_c10_unref.input @@ -0,0 +1,78 @@ +[TimeLoop] +DtInitial = 1e-4 # [s] +TEnd = 1e-2 # [s] + +[Helper.Grid] +Positions0 = 0 1 +Positions1 = 0 1 +Cells0 = 10 +Cells1 = 10 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_angeli_c10_unref # name passed to the output routines +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +ReadDofBasedPressure = false +ReadDofBasedVelocity = false +UseScvfLineAveraging = true +UseContiSourceAveraging = true +QuadratureOrder = 6 #among others for continuity-residual to become closer to zero + +[Component] +LiquidDensity = 1 +LiquidKinematicViscosity = 0.1 +MolarMass = 1. + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +[Newton] +MaxSteps = 20 +TargetSteps = 20 +MaxRelativeShift = 1e-5 + +[Vtk] +WriteFaceData = false + +[Numerics] +DoFirstOrderLocalTruncError = false + +[Adaptivity] +Conservation = false +Adapt = false +LeftX = .2 +RightX = .8 +LowerY = .2 +UpperY = .8 +LinearInterpolation = false +DebugDof = -1 + +[VelocityReadIn] +NumFileEntries = 260 +XFileName = "/home/melanie/Desktop/daten_IBAMR/SinusCosinus/velocitiesXPositions.txt" +YFileName = "/home/melanie/Desktop/daten_IBAMR/SinusCosinus/velocitiesYPositions.txt" +ValueFileName = "/home/melanie/Desktop/daten_IBAMR/SinusCosinus/velocities.txt" + +[PressureReadIn] +NumFileEntries = 116; +XFileName = "/home/melanie/Desktop/daten_IBAMR/SinusCosinus/pressuresXPositions.txt" +YFileName = "/home/melanie/Desktop/daten_IBAMR/SinusCosinus/pressuresYPositions.txt" +ValuesFileName = "/home/melanie/Desktop/daten_IBAMR/SinusCosinus/pressures.txt" -- GitLab From c5d37e29c586def5861cd2184e0c3793f2706496 Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Sat, 2 Oct 2021 11:18:35 +0300 Subject: [PATCH 58/69] channel 10 cell unrefined comparison --- .../channel/2d/params_ns_stat_c10_cvd.input | 73 ++++++++++++++++++ .../2d/params_ns_stat_c10_cvd_vdP.input | 74 +++++++++++++++++++ .../channel/2d/params_ns_stat_c10_fvd.input | 73 ++++++++++++++++++ .../channel/2d/params_ns_stat_c10_unref.input | 73 ++++++++++++++++++ 4 files changed, 293 insertions(+) create mode 100644 appl/freeflow/navierstokes/channel/2d/params_ns_stat_c10_cvd.input create mode 100644 appl/freeflow/navierstokes/channel/2d/params_ns_stat_c10_cvd_vdP.input create mode 100644 appl/freeflow/navierstokes/channel/2d/params_ns_stat_c10_fvd.input create mode 100644 appl/freeflow/navierstokes/channel/2d/params_ns_stat_c10_unref.input diff --git a/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c10_cvd.input b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c10_cvd.input new file mode 100644 index 0000000..01edb11 --- /dev/null +++ b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c10_cvd.input @@ -0,0 +1,73 @@ +[Helper.Grid] +Positions0 = 0 10 +Positions1 = 0 1 +Cells0 = 10 +Cells1 = 6 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_channel_ns_stat_c10_cvd # name passed to the output routines +InletVelocity = 100 +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +AveragedAnalyticalSolution = false +UseScvfLineAveraging = true + +[Component] +MolarMass = 1.0 +LiquidDensity = 1 +LiquidKinematicViscosity = 1 + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-8 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true + +[Vtk] +WriteFaceData = false + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +# This test does actually not require setting the primary variable magnitues. +# This rather serves as a demonstration of how to use the feature. +[CellCenter.Assembly] +NumericDifference.PriVarMagnitude = 1e5 # pressure is in the order of 1e5 + +[Face.Assembly] +NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 + +[Adaptivity] +Conservation = false +Adapt = true +LeftX = 2 +RightX = 8 +LowerY = 0.2 +UpperY = 0.8 + +[Adaptive] +RefineAtDirichletBC = 0 +RefineAtFluxBC = 1 +MinLevel = 0 +MaxLevel = 0 +CoarsenTolerance = 1e-4 +RefineTolerance = 2e-1 diff --git a/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c10_cvd_vdP.input b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c10_cvd_vdP.input new file mode 100644 index 0000000..8b93955 --- /dev/null +++ b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c10_cvd_vdP.input @@ -0,0 +1,74 @@ +[Helper.Grid] +Positions0 = 0 10 +Positions1 = 0 1 +Cells0 = 10 +Cells1 = 6 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_channel_ns_stat_c10_cvd_vdP # name passed to the output routines +InletVelocity = 100 +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +AveragedAnalyticalSolution = false +UseScvfLineAveraging = true + +[Component] +MolarMass = 1.0 +LiquidDensity = 1 +LiquidKinematicViscosity = 1 + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-8 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true + +[Vtk] +WriteFaceData = false + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +# This test does actually not require setting the primary variable magnitues. +# This rather serves as a demonstration of how to use the feature. +[CellCenter.Assembly] +NumericDifference.PriVarMagnitude = 1e5 # pressure is in the order of 1e5 + +[Face.Assembly] +NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 + +[Adaptivity] +UseOwn4PointCoefficients = false +Conservation = false +Adapt = true +LeftX = 2 +RightX = 8 +LowerY = 0.2 +UpperY = 0.8 + +[Adaptive] +RefineAtDirichletBC = 0 +RefineAtFluxBC = 1 +MinLevel = 0 +MaxLevel = 0 +CoarsenTolerance = 1e-4 +RefineTolerance = 2e-1 diff --git a/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c10_fvd.input b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c10_fvd.input new file mode 100644 index 0000000..d883c40 --- /dev/null +++ b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c10_fvd.input @@ -0,0 +1,73 @@ +[Helper.Grid] +Positions0 = 0 10 +Positions1 = 0 1 +Cells0 = 10 +Cells1 = 6 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_channel_ns_stat_c10_fvd # name passed to the output routines +InletVelocity = 100 +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +AveragedAnalyticalSolution = false +UseScvfLineAveraging = true + +[Component] +MolarMass = 1.0 +LiquidDensity = 1 +LiquidKinematicViscosity = 1 + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-8 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true + +[Vtk] +WriteFaceData = false + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +# This test does actually not require setting the primary variable magnitues. +# This rather serves as a demonstration of how to use the feature. +[CellCenter.Assembly] +NumericDifference.PriVarMagnitude = 1e5 # pressure is in the order of 1e5 + +[Face.Assembly] +NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 + +[Adaptivity] +Conservation = false +Adapt = true +LeftX = 2 +RightX = 8 +LowerY = 0.2 +UpperY = 0.8 + +[Adaptive] +RefineAtDirichletBC = 0 +RefineAtFluxBC = 1 +MinLevel = 0 +MaxLevel = 0 +CoarsenTolerance = 1e-4 +RefineTolerance = 2e-1 diff --git a/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c10_unref.input b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c10_unref.input new file mode 100644 index 0000000..3e29444 --- /dev/null +++ b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c10_unref.input @@ -0,0 +1,73 @@ +[Helper.Grid] +Positions0 = 0 10 +Positions1 = 0 1 +Cells0 = 10 +Cells1 = 6 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_channel_ns_stat_c10_unref # name passed to the output routines +InletVelocity = 100 +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +AveragedAnalyticalSolution = false +UseScvfLineAveraging = true + +[Component] +MolarMass = 1.0 +LiquidDensity = 1 +LiquidKinematicViscosity = 1 + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-8 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true + +[Vtk] +WriteFaceData = false + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +# This test does actually not require setting the primary variable magnitues. +# This rather serves as a demonstration of how to use the feature. +[CellCenter.Assembly] +NumericDifference.PriVarMagnitude = 1e5 # pressure is in the order of 1e5 + +[Face.Assembly] +NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 + +[Adaptivity] +Conservation = false +Adapt = false +LeftX = 2 +RightX = 8 +LowerY = 0.2 +UpperY = 0.8 + +[Adaptive] +RefineAtDirichletBC = 0 +RefineAtFluxBC = 1 +MinLevel = 0 +MaxLevel = 0 +CoarsenTolerance = 1e-4 +RefineTolerance = 2e-1 -- GitLab From 12ab2d2e3013977b4e52ac6cf5ee196c37a48d8f Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Sat, 2 Oct 2021 11:53:05 +0300 Subject: [PATCH 59/69] sincos 10 cell unrefined comparison --- .../navierstokes/sincos/params_c10_fvd.input | 77 +++++++++++++++++++ ...arams_c10.input => params_c10_unref.input} | 3 +- .../navierstokes/sincos/params_c10_vdP.input | 2 +- 3 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 appl/freeflow/navierstokes/sincos/params_c10_fvd.input rename appl/freeflow/navierstokes/sincos/{params_c10.input => params_c10_unref.input} (95%) diff --git a/appl/freeflow/navierstokes/sincos/params_c10_fvd.input b/appl/freeflow/navierstokes/sincos/params_c10_fvd.input new file mode 100644 index 0000000..f3c1bb7 --- /dev/null +++ b/appl/freeflow/navierstokes/sincos/params_c10_fvd.input @@ -0,0 +1,77 @@ +[TimeLoop] +DtInitial = 0.01 # [s] +TEnd = 1.0 # [s] + +[Helper.Grid] +Positions0 = 0.25 0.75 +Positions1 = 0.25 0.75 #we don't have symmetry BCs +Cells0 = 10 +Cells1 = 10 +Grading0 = 1.0 +Grading1 = 1.0 + +[xCVs.Grid] +File = xCVs.dgf + +[yCVs.Grid] +File = yCVs.dgf + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_ff_sincos_c10_fvd +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +VanDerPlasVersion = true +StartWithAnalytical = false +AveragedAnalyticalSolution = true +UseScvfLineAveraging = true + +[Component] +LiquidDensity = 1.0 +LiquidKinematicViscosity = 0.05 +MolarMass = 1.0 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +[Newton] +MaxSteps = 10 +TargetSteps = 4 +MaxRelativeShift = 1e-10 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true +MaxAbsoluteResidual = 1e-10 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = false +AddProcessRank = false + +[Flux] +UpwindWeight = 0.5 + +[Adaptivity] +LinearInterpolation = true +Conservation = false +Adapt = true +LeftX = .4 +RightX = .6 +LowerY = .4 +UpperY = .6 diff --git a/appl/freeflow/navierstokes/sincos/params_c10.input b/appl/freeflow/navierstokes/sincos/params_c10_unref.input similarity index 95% rename from appl/freeflow/navierstokes/sincos/params_c10.input rename to appl/freeflow/navierstokes/sincos/params_c10_unref.input index db46681..0960318 100644 --- a/appl/freeflow/navierstokes/sincos/params_c10.input +++ b/appl/freeflow/navierstokes/sincos/params_c10_unref.input @@ -32,7 +32,7 @@ File = coarseyCVs.dgf File = grid.dgf [Problem] -Name = test_ff_sincos_c10 +Name = test_ff_sincos_c10_unref EnableGravity = false PrintErrors = true EnableInertiaTerms = true @@ -68,7 +68,6 @@ AddProcessRank = false UpwindWeight = 0.5 [Adaptivity] -LinearInterpolation = true Conservation = true Adapt = false LeftX = .4 diff --git a/appl/freeflow/navierstokes/sincos/params_c10_vdP.input b/appl/freeflow/navierstokes/sincos/params_c10_vdP.input index cec60d6..0c19ef8 100644 --- a/appl/freeflow/navierstokes/sincos/params_c10_vdP.input +++ b/appl/freeflow/navierstokes/sincos/params_c10_vdP.input @@ -32,7 +32,7 @@ File = coarseyCVs.dgf File = grid.dgf [Problem] -Name = test_ff_sincos_c10_vdP +Name = test_ff_sincos_c10_cvd_vdP EnableGravity = false PrintErrors = true EnableInertiaTerms = true -- GitLab From 23c76d3bc4b44feeb81c2094d0169fb68c5fb983 Mon Sep 17 00:00:00 2001 From: Melanie Lipp <melanie.lipp@iws.uni-stuttgart.de> Date: Mon, 4 Oct 2021 17:26:53 +0200 Subject: [PATCH 60/69] Copy mycouplingdata and mycouplingmanager from dumux-adaptivestaggered. --- .../boundary/stokesdarcy/mycouplingdata.hh | 1000 +++++++++++++++++ .../boundary/stokesdarcy/mycouplingmanager.hh | 562 +++++++++ 2 files changed, 1562 insertions(+) create mode 100644 dumux/multidomain/boundary/stokesdarcy/mycouplingdata.hh create mode 100644 dumux/multidomain/boundary/stokesdarcy/mycouplingmanager.hh diff --git a/dumux/multidomain/boundary/stokesdarcy/mycouplingdata.hh b/dumux/multidomain/boundary/stokesdarcy/mycouplingdata.hh new file mode 100644 index 0000000..db0488d --- /dev/null +++ b/dumux/multidomain/boundary/stokesdarcy/mycouplingdata.hh @@ -0,0 +1,1000 @@ +// -*- 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 3 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 + * \ingroup StokesDarcyCoupling + * \copydoc Dumux::StokesDarcyCouplingData + */ + +#ifndef DUMUX_STOKES_DARCY_MY_COUPLINGDATA_HH +#define DUMUX_STOKES_DARCY_MY_COUPLINGDATA_HH + +#include <numeric> + +#include <dumux/common/properties.hh> +#include <dumux/common/math.hh> +#include <dumux/discretization/method.hh> +#include <dumux/discretization/cellcentered/tpfa/computetransmissibility.hh> +#include <dumux/flux/referencesystemformulation.hh> +#include <dumux/flux/refinedfickslaw.hh> +#include <dumux/multidomain/couplingmanager.hh> +#include <dumux/multidomain/boundary/stokesdarcy/couplingdata.hh> + +namespace Dumux { +// forward declaration +template <class TypeTag, DiscretizationMethod discMethod, ReferenceSystemFormulation referenceSystem> +class RefinedFicksLawImplementation; + +/*! + * \ingroup StokesDarcyCoupling + * \brief This structs indicates that Fick's law is not used for diffusion. + * \tparam DiffLaw The diffusion law. + */ +template<class DiffLaw> +struct RefinedIsFicksLaw : public std::false_type {}; + +/*! + * \ingroup StokesDarcyCoupling + * \brief This structs indicates that Fick's law is used for diffusion. + * \tparam DiffLaw The diffusion law. + */ +template<class T, DiscretizationMethod discMethod, ReferenceSystemFormulation referenceSystem> +struct RefinedIsFicksLaw<RefinedFicksLawImplementation<T, discMethod, referenceSystem>> : public std::true_type {}; + +template<class MDTraits, class CouplingManager, bool enableEnergyBalance, bool isCompositional> +class MyStokesDarcyCouplingDataImplementation; + +/*! +* \ingroup BoundaryCoupling +* \brief Data for the coupling of a Darcy model (cell-centered finite volume) +* with a (Navier-)Stokes model (staggerd grid). +*/ +template<class MDTraits, class CouplingManager> +using MyStokesDarcyCouplingData = MyStokesDarcyCouplingDataImplementation<MDTraits, CouplingManager, + GetPropType<typename MDTraits::template SubDomain<0>::TypeTag, Properties::ModelTraits>::enableEnergyBalance(), + (GetPropType<typename MDTraits::template SubDomain<0>::TypeTag, Properties::ModelTraits>::numFluidComponents() > 1)>; + +/*! + * \ingroup StokesDarcyCoupling + * \brief A base class which provides some common methods used for Stokes-Darcy coupling. + */ +template<class MDTraits, class CouplingManager> +class MyStokesDarcyCouplingDataImplementationBase +{ + using Scalar = typename MDTraits::Scalar; + + template<std::size_t id> using SubDomainTypeTag = typename MDTraits::template SubDomain<id>::TypeTag; + template<std::size_t id> using GridGeometry = GetPropType<SubDomainTypeTag<id>, Properties::GridGeometry>; + template<std::size_t id> using Element = typename GridGeometry<id>::GridView::template Codim<0>::Entity; + template<std::size_t id> using FVElementGeometry = typename GridGeometry<id>::LocalView; + template<std::size_t id> using SubControlVolumeFace = typename GridGeometry<id>::LocalView::SubControlVolumeFace; + template<std::size_t id> using SubControlVolume = typename GridGeometry<id>::LocalView::SubControlVolume; + template<std::size_t id> using Indices = typename GetPropType<SubDomainTypeTag<id>, Properties::ModelTraits>::Indices; + template<std::size_t id> using ElementVolumeVariables = typename GetPropType<SubDomainTypeTag<id>, Properties::GridVolumeVariables>::LocalView; + template<std::size_t id> using VolumeVariables = typename GetPropType<SubDomainTypeTag<id>, Properties::GridVolumeVariables>::VolumeVariables; + template<std::size_t id> using Problem = GetPropType<SubDomainTypeTag<id>, Properties::Problem>; + template<std::size_t id> using FluidSystem = GetPropType<SubDomainTypeTag<id>, Properties::FluidSystem>; + template<std::size_t id> using ModelTraits = GetPropType<SubDomainTypeTag<id>, Properties::ModelTraits>; + template<std::size_t id> using GlobalPosition = typename Element<id>::Geometry::GlobalCoordinate; + static constexpr auto stokesIdx = CouplingManager::stokesIdx; + static constexpr auto darcyIdx = CouplingManager::darcyIdx; + + using AdvectionType = GetPropType<SubDomainTypeTag<darcyIdx>, Properties::AdvectionType>; + using DarcysLaw = DarcysLawImplementation<SubDomainTypeTag<darcyIdx>, GridGeometry<darcyIdx>::discMethod>; + using ForchheimersLaw = ForchheimersLawImplementation<SubDomainTypeTag<darcyIdx>, GridGeometry<darcyIdx>::discMethod>; + + static constexpr bool adapterUsed = ModelTraits<darcyIdx>::numFluidPhases() > 1; + using IndexHelper = Dumux::IndexHelper<stokesIdx, darcyIdx, FluidSystem<stokesIdx>, adapterUsed>; + + static constexpr int enableEnergyBalance = GetPropType<SubDomainTypeTag<stokesIdx>, Properties::ModelTraits>::enableEnergyBalance(); + static_assert(GetPropType<SubDomainTypeTag<darcyIdx>, Properties::ModelTraits>::enableEnergyBalance() == enableEnergyBalance, + "All submodels must both be either isothermal or non-isothermal"); + + static_assert(IsSameFluidSystem<FluidSystem<stokesIdx>, + FluidSystem<darcyIdx>>::value, + "All submodels must use the same fluid system"); + + using DiffusionCoefficientAveragingType = typename StokesDarcyCouplingOptions::DiffusionCoefficientAveragingType; + +public: + MyStokesDarcyCouplingDataImplementationBase(const CouplingManager& couplingmanager): couplingManager_(couplingmanager) {} + + /*! + * \brief Returns the corresponding phase index needed for coupling. + */ + template<std::size_t i> + static constexpr auto couplingPhaseIdx(Dune::index_constant<i> id, int coupledPhaseIdx = 0) + { return IndexHelper::couplingPhaseIdx(id, coupledPhaseIdx); } + + /*! + * \brief Returns the corresponding component index needed for coupling. + */ + template<std::size_t i> + static constexpr auto couplingCompIdx(Dune::index_constant<i> id, int coupledCompdIdx) + { return IndexHelper::couplingCompIdx(id, coupledCompdIdx); } + + /*! + * \brief Returns a reference to the coupling manager. + */ + const CouplingManager& couplingManager() const + { return couplingManager_; } + + /*! + * \brief Returns the intrinsic permeability of the coupled Darcy element. + */ + auto darcyPermeability(const Element<stokesIdx>& element, const SubControlVolumeFace<stokesIdx>& scvf) const + { + const auto& stokesContext = couplingManager().stokesCouplingContext(element, scvf); + return stokesContext.volVars.permeability(); + } + + /*! + * \brief Returns the momentum flux across the coupling boundary. + * + * For the normal momentum coupling, the porous medium side of the coupling condition + * is evaluated, i.e. -[p n]^pm. + * + */ + template<class ElementFaceVariables> + Scalar momentumCouplingCondition(const Element<stokesIdx>& element, + const FVElementGeometry<stokesIdx>& fvGeometry, + const ElementVolumeVariables<stokesIdx>& stokesElemVolVars, + const ElementFaceVariables& stokesElemFaceVars, + const SubControlVolumeFace<stokesIdx>& scvf) const + { + static constexpr auto numPhasesDarcy = GetPropType<SubDomainTypeTag<darcyIdx>, Properties::ModelTraits>::numFluidPhases(); + + Scalar momentumFlux(0.0); + const auto& stokesContext = couplingManager_.stokesCouplingContext(element, scvf); + const auto darcyPhaseIdx = couplingPhaseIdx(darcyIdx); + + // - p_pm * n_pm = p_pm * n_ff + const Scalar darcyPressure = stokesContext.volVars.pressure(darcyPhaseIdx); + + if(numPhasesDarcy > 1) + momentumFlux = darcyPressure; + else // use pressure reconstruction for single phase models + momentumFlux = pressureAtInterface_(element, scvf, stokesElemFaceVars, stokesContext); + // TODO: generalize for permeability tensors + + // normalize pressure + if(getPropValue<SubDomainTypeTag<stokesIdx>, Properties::NormalizePressure>()) + momentumFlux -= couplingManager_.problem(stokesIdx).initial(scvf)[Indices<stokesIdx>::pressureIdx]; + + momentumFlux *= scvf.directionSign(); + + return momentumFlux; + } + + /*! + * \brief Evaluate an advective flux across the interface and consider upwinding. + */ + Scalar advectiveFlux(const Scalar insideQuantity, const Scalar outsideQuantity, const Scalar volumeFlow, bool insideIsUpstream) const + { + const Scalar upwindWeight = 1.0; //TODO use Flux.UpwindWeight or something like Coupling.UpwindWeight? + + if(insideIsUpstream) + return (upwindWeight * insideQuantity + (1.0 - upwindWeight) * outsideQuantity) * volumeFlow; + else + return (upwindWeight * outsideQuantity + (1.0 - upwindWeight) * insideQuantity) * volumeFlow; + } + +protected: + + /*! + * \brief Returns the transmissibility used for either molecular diffusion or thermal conductivity. + */ + template<std::size_t i, std::size_t j> + Scalar transmissibility_(Dune::index_constant<i> domainI, + Dune::index_constant<j> domainJ, + const Scalar insideDistance, + const Scalar outsideDistance, + const Scalar avgQuantityI, + const Scalar avgQuantityJ, + const DiffusionCoefficientAveragingType diffCoeffAvgType) const + { + const Scalar totalDistance = insideDistance + outsideDistance; + if(diffCoeffAvgType == DiffusionCoefficientAveragingType::harmonic) + { + return harmonicMean(avgQuantityI, avgQuantityJ, insideDistance, outsideDistance) + / totalDistance; + } + else if(diffCoeffAvgType == DiffusionCoefficientAveragingType::arithmethic) + { + return arithmeticMean(avgQuantityI, avgQuantityJ, insideDistance, outsideDistance) + / totalDistance; + } + else if(diffCoeffAvgType == DiffusionCoefficientAveragingType::ffOnly) + return domainI == stokesIdx + ? avgQuantityI / totalDistance + : avgQuantityJ / totalDistance; + + else // diffCoeffAvgType == DiffusionCoefficientAveragingType::pmOnly) + return domainI == darcyIdx + ? avgQuantityI / totalDistance + : avgQuantityJ / totalDistance; + } + + /*! + * \brief Returns the distance between an scvf and the corresponding scv center. + */ + template<class Scv, class Scvf> + Scalar getDistance_(const Scv& scv, const Scvf& scvf) const + { + return (scv.dofPosition() - scvf.ipGlobal()).two_norm(); + } + + /*! + * \brief Returns the conductive energy flux acorss the interface. + */ + template<std::size_t i, std::size_t j, bool isNI = enableEnergyBalance, typename std::enable_if_t<isNI, int> = 0> + Scalar conductiveEnergyFlux_(Dune::index_constant<i> domainI, + Dune::index_constant<j> domainJ, + const FVElementGeometry<i>& fvGeometryI, + const FVElementGeometry<j>& fvGeometryJ, + const SubControlVolumeFace<i>& scvfI, + const SubControlVolume<i>& scvI, + const SubControlVolume<j>& scvJ, + const VolumeVariables<i>& volVarsI, + const VolumeVariables<j>& volVarsJ, + const DiffusionCoefficientAveragingType diffCoeffAvgType) const + { + const Scalar insideDistance = getDistance_(scvI, scvfI); + const Scalar outsideDistance = getDistance_(scvJ, scvfI); + + const Scalar deltaT = volVarsJ.temperature() - volVarsI.temperature(); + const Scalar tij = transmissibility_(domainI, + domainJ, + insideDistance, + outsideDistance, + volVarsI.effectiveThermalConductivity(), + volVarsJ.effectiveThermalConductivity(), + diffCoeffAvgType); + + return -tij * deltaT; + } + + /*! + * \brief Returns the pressure at the interface + */ + template<class ElementFaceVariables, class CouplingContext> + Scalar pressureAtInterface_(const Element<stokesIdx>& element, + const SubControlVolumeFace<stokesIdx>& scvf, + const ElementFaceVariables& elemFaceVars, + const CouplingContext& context) const + { + GlobalPosition<stokesIdx> velocity(0.0); + velocity[scvf.directionIndex()] = elemFaceVars[scvf].velocitySelf(); + const auto& darcyScvf = context.fvGeometry.scvf(context.darcyScvfIdx); + return computeCouplingPhasePressureAtInterface_(context.element, context.fvGeometry, darcyScvf, context.volVars, velocity, AdvectionType()); + } + + /*! + * \brief Returns the pressure at the interface using Forchheimers's law for reconstruction + */ + Scalar computeCouplingPhasePressureAtInterface_(const Element<darcyIdx>& element, + const FVElementGeometry<darcyIdx>& fvGeometry, + const SubControlVolumeFace<darcyIdx>& scvf, + const VolumeVariables<darcyIdx>& volVars, + const typename Element<stokesIdx>::Geometry::GlobalCoordinate& couplingPhaseVelocity, + ForchheimersLaw) const + { + const auto darcyPhaseIdx = couplingPhaseIdx(darcyIdx); + const Scalar cellCenterPressure = volVars.pressure(darcyPhaseIdx); + using std::sqrt; + + // v + (cF*sqrt(K)*rho/mu*|v|) * v = - K/mu grad(p - rho g) + // multiplying with n and using a tpfa for the right-hand side yields + // v*n + (cF*sqrt(K)*rho/mu*|v|) * (v*n) = 1/mu * (ti*(p_center - p_interface) + rho*n^TKg) + // --> p_interface = (-mu*v*n + (cF*sqrt(K)*rho*|v|) * (-v*n) + rho*n^TKg)/ti + p_center + const auto velocity = couplingPhaseVelocity; + const Scalar mu = volVars.viscosity(darcyPhaseIdx); + const Scalar rho = volVars.density(darcyPhaseIdx); + const auto K = volVars.permeability(); + const auto alpha = vtmv(scvf.unitOuterNormal(), K, couplingManager_.problem(darcyIdx).spatialParams().gravity(scvf.center())); + + const auto& insideScv = fvGeometry.scv(scvf.insideScvIdx()); + const auto ti = computeTpfaTransmissibility(scvf, insideScv, K, 1.0); + + // get the Forchheimer coefficient + Scalar cF = couplingManager_.problem(darcyIdx).spatialParams().forchCoeff(scvf); + + const Scalar interfacePressure = ((-mu*(scvf.unitOuterNormal() * velocity)) + + (-(scvf.unitOuterNormal() * velocity) * velocity.two_norm() * rho * sqrt(darcyPermeability(element, scvf)) * cF) + + rho * alpha)/ti + cellCenterPressure; + return interfacePressure; + } + + /*! + * \brief Returns the pressure at the interface using Darcy's law for reconstruction + */ + Scalar computeCouplingPhasePressureAtInterface_(const Element<darcyIdx>& element, + const FVElementGeometry<darcyIdx>& fvGeometry, + const SubControlVolumeFace<darcyIdx>& scvf, + const VolumeVariables<darcyIdx>& volVars, + const typename Element<stokesIdx>::Geometry::GlobalCoordinate& couplingPhaseVelocity, + DarcysLaw) const + { + const auto darcyPhaseIdx = couplingPhaseIdx(darcyIdx); + const Scalar couplingPhaseCellCenterPressure = volVars.pressure(darcyPhaseIdx); + const Scalar couplingPhaseMobility = volVars.mobility(darcyPhaseIdx); + const Scalar couplingPhaseDensity = volVars.density(darcyPhaseIdx); + const auto K = volVars.permeability(); + + // A tpfa approximation yields (works if mobility != 0) + // v*n = -kr/mu*K * (gradP - rho*g)*n = mobility*(ti*(p_center - p_interface) + rho*n^TKg) + // -> p_interface = (1/mobility * (-v*n) + rho*n^TKg)/ti + p_center + // where v is the free-flow velocity (couplingPhaseVelocity) + const auto alpha = vtmv(scvf.unitOuterNormal(), K, couplingManager_.problem(darcyIdx).spatialParams().gravity(scvf.center())); + + const auto& insideScv = fvGeometry.scv(scvf.insideScvIdx()); + const auto ti = computeTpfaTransmissibility(scvf, insideScv, K, 1.0); + + return (-1/couplingPhaseMobility * (scvf.unitOuterNormal() * couplingPhaseVelocity) + couplingPhaseDensity * alpha)/ti + + couplingPhaseCellCenterPressure; + } + + +private: + const CouplingManager& couplingManager_; + +}; + +/*! + * \ingroup StokesDarcyCoupling + * \brief Coupling data specialization for non-compositional models. + */ +template<class MDTraits, class CouplingManager, bool enableEnergyBalance> +class MyStokesDarcyCouplingDataImplementation<MDTraits, CouplingManager, enableEnergyBalance, false> +: public MyStokesDarcyCouplingDataImplementationBase<MDTraits, CouplingManager> +{ + using ParentType = MyStokesDarcyCouplingDataImplementationBase<MDTraits, CouplingManager>; + using Scalar = typename MDTraits::Scalar; + static constexpr auto stokesIdx = CouplingManager::stokesIdx; + static constexpr auto darcyIdx = CouplingManager::darcyIdx; + static constexpr auto stokesFaceIdx = CouplingManager::stokesFaceIdx; + static constexpr auto stokesCellCenterIdx = CouplingManager::stokesCellCenterIdx; + + // the sub domain type tags + template<std::size_t id> + using SubDomainTypeTag = typename MDTraits::template SubDomain<id>::TypeTag; + + template<std::size_t id> using GridGeometry = GetPropType<SubDomainTypeTag<id>, Properties::GridGeometry>; + template<std::size_t id> using Element = typename GridGeometry<id>::GridView::template Codim<0>::Entity; + template<std::size_t id> using FVElementGeometry = typename GridGeometry<id>::LocalView; + template<std::size_t id> using SubControlVolumeFace = typename GridGeometry<id>::LocalView::SubControlVolumeFace; + template<std::size_t id> using SubControlVolume = typename GridGeometry<id>::LocalView::SubControlVolume; + template<std::size_t id> using Indices = typename GetPropType<SubDomainTypeTag<id>, Properties::ModelTraits>::Indices; + template<std::size_t id> using ElementVolumeVariables = typename GetPropType<SubDomainTypeTag<id>, Properties::GridVolumeVariables>::LocalView; + template<std::size_t id> using ElementFaceVariables = typename GetPropType<SubDomainTypeTag<id>, Properties::GridFaceVariables>::LocalView; + template<std::size_t id> using VolumeVariables = typename GetPropType<SubDomainTypeTag<id>, Properties::GridVolumeVariables>::VolumeVariables; + + static_assert(GetPropType<SubDomainTypeTag<darcyIdx>, Properties::ModelTraits>::numFluidComponents() == GetPropType<SubDomainTypeTag<darcyIdx>, Properties::ModelTraits>::numFluidPhases(), + "Darcy Model must not be compositional"); + + using DiffusionCoefficientAveragingType = typename StokesDarcyCouplingOptions::DiffusionCoefficientAveragingType; + +public: + using ParentType::ParentType; + using ParentType::couplingPhaseIdx; + + /*! + * \brief Returns the mass flux across the coupling boundary as seen from the Darcy domain. + */ + Scalar massCouplingCondition(const Element<darcyIdx>& element, + const FVElementGeometry<darcyIdx>& fvGeometry, + const ElementVolumeVariables<darcyIdx>& darcyElemVolVars, + const SubControlVolumeFace<darcyIdx>& scvf) const + { + const auto& darcyContext = this->couplingManager().darcyCouplingContext(element, scvf); + const Scalar velocity = darcyContext.velocity * scvf.unitOuterNormal(); + const Scalar darcyDensity = darcyElemVolVars[scvf.insideScvIdx()].density(couplingPhaseIdx(darcyIdx)); + const Scalar stokesDensity = darcyContext.volVars.density(); + const bool insideIsUpstream = velocity > 0.0; + + return massFlux_(velocity, darcyDensity, stokesDensity, insideIsUpstream); + } + + /*! + * \brief Returns the mass flux across the coupling boundary as seen from the free-flow domain. + */ + Scalar massCouplingCondition(const Element<stokesIdx>& element, + const FVElementGeometry<stokesIdx>& fvGeometry, + const ElementVolumeVariables<stokesIdx>& stokesElemVolVars, + const ElementFaceVariables<stokesIdx>& stokesElemFaceVars, + const SubControlVolumeFace<stokesIdx>& scvf) const + { + const auto& stokesContext = this->couplingManager().stokesCouplingContext(element, scvf); + const Scalar velocity = stokesElemFaceVars[scvf].velocitySelf(); + const Scalar stokesDensity = stokesElemVolVars[scvf.insideScvIdx()][scvf.localFaceIdx()].inside.density(); + const Scalar darcyDensity = stokesContext.volVars.density(couplingPhaseIdx(darcyIdx)); + const bool insideIsUpstream = sign(velocity) == scvf.directionSign(); + + return massFlux_(velocity * scvf.directionSign(), stokesDensity, darcyDensity, insideIsUpstream); + } + + /*! + * \brief Returns the energy flux across the coupling boundary as seen from the Darcy domain. + */ + template<bool isNI = enableEnergyBalance, typename std::enable_if_t<isNI, int> = 0> + Scalar energyCouplingCondition(const Element<darcyIdx>& element, + const FVElementGeometry<darcyIdx>& fvGeometry, + const ElementVolumeVariables<darcyIdx>& darcyElemVolVars, + const SubControlVolumeFace<darcyIdx>& scvf, + const DiffusionCoefficientAveragingType diffCoeffAvgType = DiffusionCoefficientAveragingType::ffOnly) const + { + const auto& darcyContext = this->couplingManager().darcyCouplingContext(element, scvf); + const auto& darcyVolVars = darcyElemVolVars[scvf.insideScvIdx()]; + const auto& stokesVolVars = darcyContext.volVars; + + const Scalar velocity = darcyContext.velocity * scvf.unitOuterNormal(); + const bool insideIsUpstream = velocity > 0.0; + + return energyFlux_(darcyIdx, stokesIdx, fvGeometry, darcyContext.fvGeometry, scvf, + darcyVolVars, stokesVolVars, velocity, insideIsUpstream, diffCoeffAvgType); + } + + /*! + * \brief Returns the energy flux across the coupling boundary as seen from the free-flow domain. + */ + template<bool isNI = enableEnergyBalance, typename std::enable_if_t<isNI, int> = 0> + Scalar energyCouplingCondition(const Element<stokesIdx>& element, + const FVElementGeometry<stokesIdx>& fvGeometry, + const ElementVolumeVariables<stokesIdx>& stokesElemVolVars, + const ElementFaceVariables<stokesIdx>& stokesElemFaceVars, + const SubControlVolumeFace<stokesIdx>& scvf, + const DiffusionCoefficientAveragingType diffCoeffAvgType = DiffusionCoefficientAveragingType::ffOnly) const + { + const auto& stokesContext = this->couplingManager().stokesCouplingContext(element, scvf); + const auto& stokesVolVars = stokesElemVolVars[scvf.insideScvIdx()][scvf.localFaceIdx()].inside; + const auto& darcyVolVars = stokesContext.volVars; + + const Scalar velocity = stokesElemFaceVars[scvf].velocitySelf(); + const bool insideIsUpstream = sign(velocity) == scvf.directionSign(); + + return energyFlux_(stokesIdx, darcyIdx, fvGeometry, stokesContext.fvGeometry, scvf, + stokesVolVars, darcyVolVars, velocity * scvf.directionSign(), insideIsUpstream, diffCoeffAvgType); + } + +private: + + /*! + * \brief Evaluate the mole/mass flux across the interface. + */ + Scalar massFlux_(const Scalar velocity, + const Scalar insideDensity, + const Scalar outSideDensity, + bool insideIsUpstream) const + { + return this->advectiveFlux(insideDensity, outSideDensity, velocity, insideIsUpstream); + } + + /*! + * \brief Evaluate the energy flux across the interface. + */ + template<std::size_t i, std::size_t j, bool isNI = enableEnergyBalance, typename std::enable_if_t<isNI, int> = 0> + Scalar energyFlux_(Dune::index_constant<i> domainI, + Dune::index_constant<j> domainJ, + const FVElementGeometry<i>& insideFvGeometry, + const FVElementGeometry<j>& outsideFvGeometry, + const SubControlVolumeFace<i>& scvf, + const VolumeVariables<i>& insideVolVars, + const VolumeVariables<j>& outsideVolVars, + const Scalar velocity, + const bool insideIsUpstream, + const DiffusionCoefficientAveragingType diffCoeffAvgType) const + { + Scalar flux(0.0); + + const auto& insideScv = (*scvs(insideFvGeometry).begin()); + const auto& outsideScv = (*scvs(outsideFvGeometry).begin()); + + // convective fluxes + const Scalar insideTerm = insideVolVars.density(couplingPhaseIdx(domainI)) * insideVolVars.enthalpy(couplingPhaseIdx(domainI)); + const Scalar outsideTerm = outsideVolVars.density(couplingPhaseIdx(domainJ)) * outsideVolVars.enthalpy(couplingPhaseIdx(domainJ)); + + flux += this->advectiveFlux(insideTerm, outsideTerm, velocity, insideIsUpstream); + + flux += this->conductiveEnergyFlux_(domainI, domainJ, insideFvGeometry, outsideFvGeometry, scvf, insideScv, outsideScv, insideVolVars, outsideVolVars, diffCoeffAvgType); + + return flux; + } + +}; + +/*! + * \ingroup StokesDarcyCoupling + * \brief Coupling data specialization for compositional models. + */ +template<class MDTraits, class CouplingManager, bool enableEnergyBalance> +class MyStokesDarcyCouplingDataImplementation<MDTraits, CouplingManager, enableEnergyBalance, true> +: public MyStokesDarcyCouplingDataImplementationBase<MDTraits, CouplingManager> +{ + using ParentType = MyStokesDarcyCouplingDataImplementationBase<MDTraits, CouplingManager>; + using Scalar = typename MDTraits::Scalar; + static constexpr auto stokesIdx = CouplingManager::stokesIdx; + static constexpr auto darcyIdx = CouplingManager::darcyIdx; + static constexpr auto stokesFaceIdx = CouplingManager::stokesFaceIdx; + static constexpr auto stokesCellCenterIdx = CouplingManager::stokesCellCenterIdx; + + // the sub domain type tags + template<std::size_t id> + using SubDomainTypeTag = typename MDTraits::template SubDomain<id>::TypeTag; + + template<std::size_t id> using GridGeometry = GetPropType<SubDomainTypeTag<id>, Properties::GridGeometry>; + template<std::size_t id> using Element = typename GridGeometry<id>::GridView::template Codim<0>::Entity; + template<std::size_t id> using FVElementGeometry = typename GridGeometry<id>::LocalView; + template<std::size_t id> using SubControlVolumeFace = typename FVElementGeometry<id>::SubControlVolumeFace; + template<std::size_t id> using SubControlVolume = typename GridGeometry<id>::LocalView::SubControlVolume; + template<std::size_t id> using Indices = typename GetPropType<SubDomainTypeTag<id>, Properties::ModelTraits>::Indices; + template<std::size_t id> using ElementVolumeVariables = typename GetPropType<SubDomainTypeTag<id>, Properties::GridVolumeVariables>::LocalView; + template<std::size_t id> using ElementFaceVariables = typename GetPropType<SubDomainTypeTag<id>, Properties::GridFaceVariables>::LocalView; + template<std::size_t id> using VolumeVariables = typename GetPropType<SubDomainTypeTag<id>, Properties::GridVolumeVariables>::VolumeVariables; + template<std::size_t id> using FluidSystem = GetPropType<SubDomainTypeTag<id>, Properties::FluidSystem>; + + static constexpr auto numComponents = GetPropType<SubDomainTypeTag<stokesIdx>, Properties::ModelTraits>::numFluidComponents(); + static constexpr auto replaceCompEqIdx = GetPropType<SubDomainTypeTag<stokesIdx>, Properties::ModelTraits>::replaceCompEqIdx(); + static constexpr bool useMoles = GetPropType<SubDomainTypeTag<stokesIdx>, Properties::ModelTraits>::useMoles(); + static constexpr auto referenceSystemFormulation = GetPropType<SubDomainTypeTag<stokesIdx>, Properties::MolecularDiffusionType>::referenceSystemFormulation(); + + static_assert(GetPropType<SubDomainTypeTag<darcyIdx>, Properties::ModelTraits>::numFluidComponents() == numComponents, "Both submodels must use the same number of components"); + static_assert(getPropValue<SubDomainTypeTag<darcyIdx>, Properties::UseMoles>() == useMoles, "Both submodels must either use moles or not"); + static_assert(getPropValue<SubDomainTypeTag<darcyIdx>, Properties::ReplaceCompEqIdx>() == replaceCompEqIdx, "Both submodels must use the same replaceCompEqIdx"); + static_assert(GetPropType<SubDomainTypeTag<darcyIdx>, Properties::MolecularDiffusionType>::referenceSystemFormulation() == referenceSystemFormulation, + "Both submodels must use the same reference system formulation for diffusion"); + + using NumEqVector = Dune::FieldVector<Scalar, numComponents>; + + using DiffusionCoefficientAveragingType = typename StokesDarcyCouplingOptions::DiffusionCoefficientAveragingType; + + static constexpr bool isFicksLaw = RefinedIsFicksLaw<GetPropType<SubDomainTypeTag<stokesIdx>, Properties::MolecularDiffusionType>>(); + + static_assert(isFicksLaw == IsFicksLaw<GetPropType<SubDomainTypeTag<darcyIdx>, Properties::MolecularDiffusionType>>(), + "Both submodels must use the same diffusion law."); + + using ReducedComponentVector = Dune::FieldVector<Scalar, numComponents-1>; + using ReducedComponentMatrix = Dune::FieldMatrix<Scalar, numComponents-1, numComponents-1>; + + using MolecularDiffusionType = GetPropType<SubDomainTypeTag<stokesIdx>, Properties::MolecularDiffusionType>; +public: + using ParentType::ParentType; + using ParentType::couplingPhaseIdx; + using ParentType::couplingCompIdx; + + /*! + * \brief Returns the mass flux across the coupling boundary as seen from the Darcy domain. + */ + NumEqVector massCouplingCondition(const Element<darcyIdx>& element, + const FVElementGeometry<darcyIdx>& fvGeometry, + const ElementVolumeVariables<darcyIdx>& darcyElemVolVars, + const SubControlVolumeFace<darcyIdx>& scvf, + const DiffusionCoefficientAveragingType diffCoeffAvgType = DiffusionCoefficientAveragingType::ffOnly) const + { + NumEqVector flux(0.0); + const auto& darcyContext = this->couplingManager().darcyCouplingContext(element, scvf); + const auto& darcyVolVars = darcyElemVolVars[scvf.insideScvIdx()]; + const auto& stokesVolVars = darcyContext.volVars; + const auto& outsideScv = (*scvs(darcyContext.fvGeometry).begin()); + + const Scalar velocity = darcyContext.velocity * scvf.unitOuterNormal(); + const bool insideIsUpstream = velocity > 0.0; + + return massFlux_(darcyIdx, stokesIdx, fvGeometry, + scvf, darcyVolVars, stokesVolVars, + outsideScv, velocity, insideIsUpstream, + diffCoeffAvgType); + } + + /*! + * \brief Returns the mass flux across the coupling boundary as seen from the free-flow domain. + */ + NumEqVector massCouplingCondition(const Element<stokesIdx>& element, + const FVElementGeometry<stokesIdx>& fvGeometry, + const ElementVolumeVariables<stokesIdx>& stokesElemVolVars, + const ElementFaceVariables<stokesIdx>& stokesElemFaceVars, + const SubControlVolumeFace<stokesIdx>& scvf, + const DiffusionCoefficientAveragingType diffCoeffAvgType = DiffusionCoefficientAveragingType::ffOnly) const + { + NumEqVector flux(0.0); + const auto& stokesContext = this->couplingManager().stokesCouplingContext(element, scvf); + const auto& stokesVolVars = stokesElemVolVars[scvf.insideScvIdx()][scvf.localFaceIdx()].inside; + const auto& darcyVolVars = stokesContext.volVars; + const auto& outsideScv = (*scvs(stokesContext.fvGeometry).begin()); + + const Scalar velocity = stokesElemFaceVars[scvf].velocitySelf(); + const bool insideIsUpstream = sign(velocity) == scvf.directionSign(); + + return massFlux_(stokesIdx, darcyIdx, fvGeometry, + scvf, stokesVolVars, darcyVolVars, + outsideScv, velocity * scvf.directionSign(), + insideIsUpstream, diffCoeffAvgType); + } + + /*! + * \brief Returns the energy flux across the coupling boundary as seen from the Darcy domain. + */ + template<bool isNI = enableEnergyBalance, typename std::enable_if_t<isNI, int> = 0> + Scalar energyCouplingCondition(const Element<darcyIdx>& element, + const FVElementGeometry<darcyIdx>& fvGeometry, + const ElementVolumeVariables<darcyIdx>& darcyElemVolVars, + const SubControlVolumeFace<darcyIdx>& scvf, + const DiffusionCoefficientAveragingType diffCoeffAvgType = DiffusionCoefficientAveragingType::ffOnly) const + { + const auto& darcyContext = this->couplingManager().darcyCouplingContext(element, scvf); + const auto& darcyVolVars = darcyElemVolVars[scvf.insideScvIdx()]; + const auto& stokesVolVars = darcyContext.volVars; + + const Scalar velocity = darcyContext.velocity * scvf.unitOuterNormal(); + const bool insideIsUpstream = velocity > 0.0; + + return energyFlux_(darcyIdx, stokesIdx, fvGeometry, darcyContext.fvGeometry, scvf, + darcyVolVars, stokesVolVars, velocity, insideIsUpstream, diffCoeffAvgType); + } + + /*! + * \brief Returns the energy flux across the coupling boundary as seen from the free-flow domain. + */ + template<bool isNI = enableEnergyBalance, typename std::enable_if_t<isNI, int> = 0> + Scalar energyCouplingCondition(const Element<stokesIdx>& element, + const FVElementGeometry<stokesIdx>& fvGeometry, + const ElementVolumeVariables<stokesIdx>& stokesElemVolVars, + const ElementFaceVariables<stokesIdx>& stokesElemFaceVars, + const SubControlVolumeFace<stokesIdx>& scvf, + const DiffusionCoefficientAveragingType diffCoeffAvgType = DiffusionCoefficientAveragingType::ffOnly) const + { + const auto& stokesContext = this->couplingManager().stokesCouplingContext(element, scvf); + const auto& stokesVolVars = stokesElemVolVars[scvf.insideScvIdx()][scvf.localFaceIdx()].inside; + const auto& darcyVolVars = stokesContext.volVars; + + const Scalar velocity = stokesElemFaceVars[scvf].velocitySelf(); + const bool insideIsUpstream = sign(velocity) == scvf.directionSign(); + + return energyFlux_(stokesIdx, darcyIdx, fvGeometry, stokesContext.fvGeometry, scvf, + stokesVolVars, darcyVolVars, velocity * scvf.directionSign(), insideIsUpstream, diffCoeffAvgType); + } + +protected: + + /*! + * \brief Evaluate the compositional mole/mass flux across the interface. + */ + template<std::size_t i, std::size_t j> + NumEqVector massFlux_(Dune::index_constant<i> domainI, + Dune::index_constant<j> domainJ, + const FVElementGeometry<i>& insideFvGeometry, + const SubControlVolumeFace<i>& scvf, + const VolumeVariables<i>& insideVolVars, + const VolumeVariables<j>& outsideVolVars, + const SubControlVolume<j>& outsideScv, + const Scalar velocity, + const bool insideIsUpstream, + const DiffusionCoefficientAveragingType diffCoeffAvgType) const + { + NumEqVector flux(0.0); + NumEqVector diffusiveFlux(0.0); + + auto moleOrMassFraction = [&](const auto& volVars, int phaseIdx, int compIdx) + { return useMoles ? volVars.moleFraction(phaseIdx, compIdx) : volVars.massFraction(phaseIdx, compIdx); }; + + auto moleOrMassDensity = [&](const auto& volVars, int phaseIdx) + { return useMoles ? volVars.molarDensity(phaseIdx) : volVars.density(phaseIdx); }; + + // treat the advective fluxes + auto insideTerm = [&](int compIdx) + { return moleOrMassFraction(insideVolVars, couplingPhaseIdx(domainI), compIdx) * moleOrMassDensity(insideVolVars, couplingPhaseIdx(domainI)); }; + + auto outsideTerm = [&](int compIdx) + { return moleOrMassFraction(outsideVolVars, couplingPhaseIdx(domainJ), compIdx) * moleOrMassDensity(outsideVolVars, couplingPhaseIdx(domainJ)); }; + + + for (int compIdx = 0; compIdx < numComponents; ++compIdx) + { + const int domainICompIdx = couplingCompIdx(domainI, compIdx); + const int domainJCompIdx = couplingCompIdx(domainJ, compIdx); + flux[domainICompIdx] += this->advectiveFlux(insideTerm(domainICompIdx), outsideTerm(domainJCompIdx), velocity, insideIsUpstream); + } + + // treat the diffusive fluxes + const auto& insideScv = insideFvGeometry.scv(scvf.insideScvIdx()); + + if (isFicksLaw) + diffusiveFlux += diffusiveMolecularFluxFicksLaw_(domainI, domainJ, scvf, insideScv, outsideScv, insideVolVars, outsideVolVars, diffCoeffAvgType); + else //maxwell stefan + diffusiveFlux += diffusiveMolecularFluxMaxwellStefan_(domainI, domainJ, scvf, insideScv, outsideScv, insideVolVars, outsideVolVars); + + //convert to correct units if necessary + if (referenceSystemFormulation == ReferenceSystemFormulation::massAveraged && useMoles) + { + for (int compIdx = 0; compIdx < numComponents; ++compIdx) + { + const int domainICompIdx = couplingCompIdx(domainI, compIdx); + diffusiveFlux[domainICompIdx] *= 1/FluidSystem<i>::molarMass(domainICompIdx); + } + } + if (referenceSystemFormulation == ReferenceSystemFormulation::molarAveraged && !useMoles) + { + for (int compIdx = 0; compIdx < numComponents; ++compIdx) + { + const int domainICompIdx = couplingCompIdx(domainI, compIdx); + diffusiveFlux[domainICompIdx] *= FluidSystem<i>::molarMass(domainICompIdx); + } + } + + flux += diffusiveFlux; + // convert to total mass/mole balance, if set be user + if (replaceCompEqIdx < numComponents) + flux[replaceCompEqIdx] = std::accumulate(flux.begin(), flux.end(), 0.0); + + return flux; + } + + Scalar getComponentEnthalpy(const VolumeVariables<stokesIdx>& volVars, int phaseIdx, int compIdx) const + { + return FluidSystem<stokesIdx>::componentEnthalpy(volVars.fluidState(), 0, compIdx); + } + + Scalar getComponentEnthalpy(const VolumeVariables<darcyIdx>& volVars, int phaseIdx, int compIdx) const + { + return FluidSystem<darcyIdx>::componentEnthalpy(volVars.fluidState(), phaseIdx, compIdx); + } + + /*! + * \brief Evaluate the diffusive mole/mass flux across the interface. + */ + template<std::size_t i, std::size_t j> + NumEqVector diffusiveMolecularFluxMaxwellStefan_(Dune::index_constant<i> domainI, + Dune::index_constant<j> domainJ, + const SubControlVolumeFace<i>& scvfI, + const SubControlVolume<i>& scvI, + const SubControlVolume<j>& scvJ, + const VolumeVariables<i>& volVarsI, + const VolumeVariables<j>& volVarsJ) const + { + NumEqVector diffusiveFlux(0.0); + + const Scalar insideDistance = this->getDistance_(scvI, scvfI); + const Scalar outsideDistance = this->getDistance_(scvJ, scvfI); + + ReducedComponentVector moleFracInside(0.0); + ReducedComponentVector moleFracOutside(0.0); + ReducedComponentVector reducedFlux(0.0); + ReducedComponentMatrix reducedDiffusionMatrixInside(0.0); + ReducedComponentMatrix reducedDiffusionMatrixOutside(0.0); + + //calculate the mole fraction vectors + for (int compIdx = 0; compIdx < numComponents-1; compIdx++) + { + const int domainICompIdx = couplingCompIdx(domainI, compIdx); + const int domainJCompIdx = couplingCompIdx(domainJ, compIdx); + + assert(FluidSystem<i>::componentName(domainICompIdx) == FluidSystem<j>::componentName(domainJCompIdx)); + + //calculate x_inside + const Scalar xInside = volVarsI.moleFraction(couplingPhaseIdx(domainI), domainICompIdx); + //calculate outside molefraction with the respective transmissibility + const Scalar xOutside = volVarsJ.moleFraction(couplingPhaseIdx(domainJ), domainJCompIdx); + moleFracInside[domainICompIdx] = xInside; + moleFracOutside[domainICompIdx] = xOutside; + } + + //now we have to do the tpfa: J_i = -J_j which leads to: J_i = -rho_i Bi^-1 omegai(x*-xi) with x* = (omegai rho_i Bi^-1 + omegaj rho_j Bj^-1)^-1 (xi omegai rho_i Bi^-1 + xj omegaj rho_j Bj^-1) with i inside and j outside. + + //first set up the matrices containing the binary diffusion coefficients and mole fractions + + //inside matrix. KIdx and LIdx are the indices for the k and l-th component, N for the n-th component + for (int compKIdx = 0; compKIdx < numComponents-1; compKIdx++) + { + const int domainICompKIdx = couplingCompIdx(domainI, compKIdx); + const Scalar xk = volVarsI.moleFraction(couplingPhaseIdx(domainI), domainICompKIdx); + const Scalar avgMolarMass = volVarsI.averageMolarMass(couplingPhaseIdx(domainI)); + const Scalar Mn = FluidSystem<i>::molarMass(numComponents-1); + const Scalar tkn = volVarsI.effectiveDiffusionCoefficient(couplingPhaseIdx(domainI), domainICompKIdx, couplingCompIdx(domainI, numComponents-1)); + + // set the entries of the diffusion matrix of the diagonal + reducedDiffusionMatrixInside[domainICompKIdx][domainICompKIdx] += xk*avgMolarMass/(tkn*Mn); + + for (int compLIdx = 0; compLIdx < numComponents; compLIdx++) + { + const int domainICompLIdx = couplingCompIdx(domainI, compLIdx); + + // we don't want to calculate e.g. water in water diffusion + if (domainICompKIdx == domainICompLIdx) + continue; + + const Scalar xl = volVarsI.moleFraction(couplingPhaseIdx(domainI), domainICompLIdx); + const Scalar Mk = FluidSystem<i>::molarMass(domainICompKIdx); + const Scalar Ml = FluidSystem<i>::molarMass(domainICompLIdx); + const Scalar tkl = volVarsI.effectiveDiffusionCoefficient(couplingPhaseIdx(domainI), domainICompKIdx, domainICompLIdx); + reducedDiffusionMatrixInside[domainICompKIdx][domainICompKIdx] += xl*avgMolarMass/(tkl*Mk); + reducedDiffusionMatrixInside[domainICompKIdx][domainICompLIdx] += xk*(avgMolarMass/(tkn*Mn) - avgMolarMass/(tkl*Ml)); + } + } + //outside matrix + for (int compKIdx = 0; compKIdx < numComponents-1; compKIdx++) + { + const int domainJCompKIdx = couplingCompIdx(domainJ, compKIdx); + const int domainICompKIdx = couplingCompIdx(domainI, compKIdx); + + const Scalar xk = volVarsJ.moleFraction(couplingPhaseIdx(domainJ), domainJCompKIdx); + const Scalar avgMolarMass = volVarsJ.averageMolarMass(couplingPhaseIdx(domainJ)); + const Scalar Mn = FluidSystem<j>::molarMass(numComponents-1); + const Scalar tkn = volVarsJ.effectiveDiffusionCoefficient(couplingPhaseIdx(domainJ), domainJCompKIdx, couplingCompIdx(domainJ, numComponents-1)); + + // set the entries of the diffusion matrix of the diagonal + reducedDiffusionMatrixOutside[domainICompKIdx][domainICompKIdx] += xk*avgMolarMass/(tkn*Mn); + + for (int compLIdx = 0; compLIdx < numComponents; compLIdx++) + { + const int domainJCompLIdx = couplingCompIdx(domainJ, compLIdx); + const int domainICompLIdx = couplingCompIdx(domainI, compLIdx); + + // we don't want to calculate e.g. water in water diffusion + if (domainJCompLIdx == domainJCompKIdx) + continue; + + const Scalar xl = volVarsJ.moleFraction(couplingPhaseIdx(domainJ), domainJCompLIdx); + const Scalar Mk = FluidSystem<j>::molarMass(domainJCompKIdx); + const Scalar Ml = FluidSystem<j>::molarMass(domainJCompLIdx); + const Scalar tkl = volVarsJ.effectiveDiffusionCoefficient(couplingPhaseIdx(domainJ), domainJCompKIdx, domainJCompLIdx); + reducedDiffusionMatrixOutside[domainICompKIdx][domainICompKIdx] += xl*avgMolarMass/(tkl*Mk); + reducedDiffusionMatrixOutside[domainICompKIdx][domainICompLIdx] += xk*(avgMolarMass/(tkn*Mn) - avgMolarMass/(tkl*Ml)); + } + } + + const Scalar omegai = 1/insideDistance; + const Scalar omegaj = 1/outsideDistance; + + reducedDiffusionMatrixInside.invert(); + reducedDiffusionMatrixInside *= omegai*volVarsI.density(couplingPhaseIdx(domainI)); + reducedDiffusionMatrixOutside.invert(); + reducedDiffusionMatrixOutside *= omegaj*volVarsJ.density(couplingPhaseIdx(domainJ)); + + //in the helpervector we store the values for x* + ReducedComponentVector helperVector(0.0); + ReducedComponentVector gradientVectori(0.0); + ReducedComponentVector gradientVectorj(0.0); + + reducedDiffusionMatrixInside.mv(moleFracInside, gradientVectori); + reducedDiffusionMatrixOutside.mv(moleFracOutside, gradientVectorj); + + auto gradientVectorij = (gradientVectori + gradientVectorj); + + //add the two matrixes to each other + reducedDiffusionMatrixOutside += reducedDiffusionMatrixInside; + + reducedDiffusionMatrixOutside.solve(helperVector, gradientVectorij); + + //Bi^-1 omegai rho_i (x*-xi). As we previously multiplied rho_i and omega_i wit the insidematrix, this does not need to be done again + helperVector -=moleFracInside; + reducedDiffusionMatrixInside.mv(helperVector, reducedFlux); + + reducedFlux *= -1; + + for (int compIdx = 0; compIdx < numComponents-1; compIdx++) + { + const int domainICompIdx = couplingCompIdx(domainI, compIdx); + diffusiveFlux[domainICompIdx] = reducedFlux[domainICompIdx]; + diffusiveFlux[couplingCompIdx(domainI, numComponents-1)] -= reducedFlux[domainICompIdx]; + } + return diffusiveFlux; + } + + template<std::size_t i, std::size_t j> + NumEqVector diffusiveMolecularFluxFicksLaw_(Dune::index_constant<i> domainI, + Dune::index_constant<j> domainJ, + const SubControlVolumeFace<i>& scvfI, + const SubControlVolume<i>& scvI, + const SubControlVolume<j>& scvJ, + const VolumeVariables<i>& volVarsI, + const VolumeVariables<j>& volVarsJ, + const DiffusionCoefficientAveragingType diffCoeffAvgType) const + { + NumEqVector diffusiveFlux(0.0); + + const Scalar rhoInside = massOrMolarDensity(volVarsI, referenceSystemFormulation, couplingPhaseIdx(domainI)); + const Scalar rhoOutside = massOrMolarDensity(volVarsJ, referenceSystemFormulation, couplingPhaseIdx(domainJ)); + const Scalar avgDensity = 0.5 * rhoInside + 0.5 * rhoOutside; + + const Scalar insideDistance = this->getDistance_(scvI, scvfI); + const Scalar outsideDistance = this->getDistance_(scvJ, scvfI); + + for (int compIdx = 1; compIdx < numComponents; ++compIdx) + { + const int domainIMainCompIdx = couplingPhaseIdx(domainI); + const int domainJMainCompIdx = couplingPhaseIdx(domainJ); + const int domainICompIdx = couplingCompIdx(domainI, compIdx); + const int domainJCompIdx = couplingCompIdx(domainJ, compIdx); + + assert(FluidSystem<i>::componentName(domainICompIdx) == FluidSystem<j>::componentName(domainJCompIdx)); + + const Scalar massOrMoleFractionInside = massOrMoleFraction(volVarsI, referenceSystemFormulation, couplingPhaseIdx(domainI), domainICompIdx); + const Scalar massOrMoleFractionOutside = massOrMoleFraction(volVarsJ, referenceSystemFormulation, couplingPhaseIdx(domainJ), domainJCompIdx); + + const Scalar deltaMassOrMoleFrac = massOrMoleFractionOutside - massOrMoleFractionInside; + const Scalar tij = this->transmissibility_(domainI, + domainJ, + insideDistance, + outsideDistance, + volVarsI.effectiveDiffusionCoefficient(couplingPhaseIdx(domainI), domainIMainCompIdx, domainICompIdx), + volVarsJ.effectiveDiffusionCoefficient(couplingPhaseIdx(domainJ), domainJMainCompIdx, domainJCompIdx), + diffCoeffAvgType); + diffusiveFlux[domainICompIdx] += -avgDensity * tij * deltaMassOrMoleFrac; + } + + const Scalar cumulativeFlux = std::accumulate(diffusiveFlux.begin(), diffusiveFlux.end(), 0.0); + diffusiveFlux[couplingCompIdx(domainI, 0)] = -cumulativeFlux; + + return diffusiveFlux; + } + + /*! + * \brief Evaluate the energy flux across the interface. + */ + template<std::size_t i, std::size_t j, bool isNI = enableEnergyBalance, typename std::enable_if_t<isNI, int> = 0> + Scalar energyFlux_(Dune::index_constant<i> domainI, + Dune::index_constant<j> domainJ, + const FVElementGeometry<i>& insideFvGeometry, + const FVElementGeometry<j>& outsideFvGeometry, + const SubControlVolumeFace<i>& scvf, + const VolumeVariables<i>& insideVolVars, + const VolumeVariables<j>& outsideVolVars, + const Scalar velocity, + const bool insideIsUpstream, + const DiffusionCoefficientAveragingType diffCoeffAvgType) const + { + Scalar flux(0.0); + + const auto& insideScv = (*scvs(insideFvGeometry).begin()); + const auto& outsideScv = (*scvs(outsideFvGeometry).begin()); + + // convective fluxes + const Scalar insideTerm = insideVolVars.density(couplingPhaseIdx(domainI)) * insideVolVars.enthalpy(couplingPhaseIdx(domainI)); + const Scalar outsideTerm = outsideVolVars.density(couplingPhaseIdx(domainJ)) * outsideVolVars.enthalpy(couplingPhaseIdx(domainJ)); + + flux += this->advectiveFlux(insideTerm, outsideTerm, velocity, insideIsUpstream); + + flux += this->conductiveEnergyFlux_(domainI, domainJ, insideFvGeometry, outsideFvGeometry, scvf, insideScv, outsideScv, insideVolVars, outsideVolVars, diffCoeffAvgType); + + auto diffusiveFlux = isFicksLaw ? diffusiveMolecularFluxFicksLaw_(domainI, domainJ, scvf, insideScv, outsideScv, insideVolVars, outsideVolVars, diffCoeffAvgType) + : diffusiveMolecularFluxMaxwellStefan_(domainI, domainJ, scvf, insideScv, outsideScv, insideVolVars, outsideVolVars); + + + for (int compIdx = 0; compIdx < diffusiveFlux.size(); ++compIdx) + { + const int domainICompIdx = couplingCompIdx(domainI, compIdx); + const int domainJCompIdx = couplingCompIdx(domainJ, compIdx); + + const bool insideDiffFluxIsUpstream = diffusiveFlux[domainICompIdx] > 0; + const Scalar componentEnthalpy = insideDiffFluxIsUpstream ? + getComponentEnthalpy(insideVolVars, couplingPhaseIdx(domainI), domainICompIdx) + : getComponentEnthalpy(outsideVolVars, couplingPhaseIdx(domainJ), domainJCompIdx); + + if (referenceSystemFormulation == ReferenceSystemFormulation::massAveraged) + flux += diffusiveFlux[domainICompIdx] * componentEnthalpy; + else + flux += diffusiveFlux[domainICompIdx] * FluidSystem<i>::molarMass(domainICompIdx) * componentEnthalpy; + } + + return flux; + } +}; + +} // end namespace Dumux + +#endif // DUMUX_STOKES_DARCY_COUPLINGDATA_HH diff --git a/dumux/multidomain/boundary/stokesdarcy/mycouplingmanager.hh b/dumux/multidomain/boundary/stokesdarcy/mycouplingmanager.hh new file mode 100644 index 0000000..8246f8c --- /dev/null +++ b/dumux/multidomain/boundary/stokesdarcy/mycouplingmanager.hh @@ -0,0 +1,562 @@ +// -*- 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 3 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 + * \ingroup StokesDarcyCoupling + * \copydoc Dumux::MyStokesDarcyCouplingManager + */ + +#ifndef DUMUX_STOKES_DARCY_MY_COUPLINGMANAGER_HH +#define DUMUX_STOKES_DARCY_MY_COUPLINGMANAGER_HH + +#include <utility> +#include <memory> + +#include <dune/common/float_cmp.hh> +#include <dune/common/exceptions.hh> +#include <dumux/common/properties.hh> +#include <dumux/common/numeqvector.hh> + +#include <dumux/multidomain/staggeredcouplingmanager.hh> +#include <dumux/discretization/staggered/elementsolution.hh> + +#include "mycouplingdata.hh" +#include "mycouplingmapper.hh" + +namespace Dumux { + +/*! + * \ingroup StokesDarcyCoupling + * \brief Coupling manager for Stokes and Darcy domains with equal dimension. + */ +template<class MDTraits> +class MyStokesDarcyCouplingManager +: public StaggeredCouplingManager<MDTraits> +{ + using Scalar = typename MDTraits::Scalar; + using ParentType = StaggeredCouplingManager<MDTraits>; + +public: + static constexpr auto stokesFaceIdx = typename MDTraits::template SubDomain<0>::Index(); + static constexpr auto stokesCellCenterIdx = typename MDTraits::template SubDomain<1>::Index(); + static constexpr auto stokesIdx = stokesFaceIdx; + static constexpr auto darcyIdx = typename MDTraits::template SubDomain<2>::Index(); + +private: + + using SolutionVector = typename MDTraits::SolutionVector; + + // obtain the type tags of the sub problems + using StokesTypeTag = typename MDTraits::template SubDomain<0>::TypeTag; + using DarcyTypeTag = typename MDTraits::template SubDomain<2>::TypeTag; + + using CouplingStencils = std::unordered_map<std::size_t, std::vector<std::size_t> >; + using CouplingStencil = CouplingStencils::mapped_type; + + // the sub domain type tags + template<std::size_t id> + using SubDomainTypeTag = typename MDTraits::template SubDomain<id>::TypeTag; + + static constexpr bool isCompositional = GetPropType<SubDomainTypeTag<0>, Properties::ModelTraits>::numFluidComponents()> 1; + + template<std::size_t id> using GridView = typename GetPropType<SubDomainTypeTag<id>, Properties::GridGeometry>::GridView; + template<std::size_t id> using Problem = GetPropType<SubDomainTypeTag<id>, Properties::Problem>; + template<std::size_t id> using PrimaryVariables = typename MDTraits::template SubDomain<id>::PrimaryVariables; + template<std::size_t id> using NumEqVector = Dumux::NumEqVector<PrimaryVariables<id>>; + template<std::size_t id> using ElementVolumeVariables = typename GetPropType<SubDomainTypeTag<id>, Properties::GridVolumeVariables>::LocalView; + template<std::size_t id> using GridVolumeVariables = GetPropType<SubDomainTypeTag<id>, Properties::GridVolumeVariables>; + template<std::size_t id> using VolumeVariables = typename GetPropType<SubDomainTypeTag<id>, Properties::GridVolumeVariables>::VolumeVariables; + template<std::size_t id> using GridGeometry = GetPropType<SubDomainTypeTag<id>, Properties::GridGeometry>; + template<std::size_t id> using FVElementGeometry = typename GridGeometry<id>::LocalView; + template<std::size_t id> using ElementBoundaryTypes = GetPropType<SubDomainTypeTag<id>, Properties::ElementBoundaryTypes>; + template<std::size_t id> using ElementFluxVariablesCache = typename GetPropType<SubDomainTypeTag<id>, Properties::GridFluxVariablesCache>::LocalView; + template<std::size_t id> using GridVariables = GetPropType<SubDomainTypeTag<id>, Properties::GridVariables>; + template<std::size_t id> using Element = typename GridView<id>::template Codim<0>::Entity; + template<std::size_t id> using SubControlVolumeFace = typename FVElementGeometry<id>::SubControlVolumeFace; + + using CellCenterSolutionVector = GetPropType<StokesTypeTag, Properties::CellCenterSolutionVector>; + + using VelocityVector = typename Element<stokesIdx>::Geometry::GlobalCoordinate; + + using CouplingMapper = MyStokesDarcyCouplingMapper; + + struct StationaryStokesCouplingContext + { + Element<darcyIdx> element; + FVElementGeometry<darcyIdx> fvGeometry; + std::size_t darcyScvfIdx; + std::size_t stokesScvfIdx; + VolumeVariables<darcyIdx> volVars; + }; + + struct StationaryDarcyCouplingContext + { + Element<stokesIdx> element; + FVElementGeometry<stokesIdx> fvGeometry; + std::size_t stokesScvfIdx; + std::size_t darcyScvfIdx; + VelocityVector velocity; + VolumeVariables<stokesIdx> volVars; + }; +public: + + using ParentType::couplingStencil; + using ParentType::updateCouplingContext; + using CouplingData = MyStokesDarcyCouplingData<MDTraits, MyStokesDarcyCouplingManager<MDTraits>>; + + //! Constructor + MyStokesDarcyCouplingManager(std::shared_ptr<const GridGeometry<stokesIdx>> stokesFvGridGeometry, + std::shared_ptr<const GridGeometry<darcyIdx>> darcyFvGridGeometry) + { } + + /*! + * \brief Methods to be accessed by main + */ + // \{ + + //! Initialize the coupling manager + void init(std::shared_ptr<const Problem<stokesIdx>> stokesProblem, + std::shared_ptr<const Problem<darcyIdx>> darcyProblem, + const SolutionVector& curSol) + { + if (Dune::FloatCmp::ne(stokesProblem->gravity(), darcyProblem->spatialParams().gravity({}))) + DUNE_THROW(Dune::InvalidStateException, "Both models must use the same gravity vector"); + + this->setSubProblems(std::make_tuple(stokesProblem, stokesProblem, darcyProblem)); + this->updateSolution(curSol); + couplingData_ = std::make_shared<CouplingData>(*this); + computeStencils(); + } + + //! Update after the grid has changed + void update(const SolutionVector& curSol) + { + this->updateSolution(curSol); + computeStencils(); + } + + // \} + + //! Prepare the coupling stencils + void computeStencils() + { + couplingMapper_.computeCouplingMapsAndStencils(*this, + darcyToStokesCellCenterCouplingStencils_, + darcyToStokesFaceCouplingStencils_, + stokesCellCenterCouplingStencils_, + stokesFaceCouplingStencils_); + + for(auto&& stencil : darcyToStokesCellCenterCouplingStencils_) + removeDuplicates_(stencil.second); + for(auto&& stencil : darcyToStokesFaceCouplingStencils_) + removeDuplicates_(stencil.second); + for(auto&& stencil : stokesCellCenterCouplingStencils_) + removeDuplicates_(stencil.second); + for(auto&& stencil : stokesFaceCouplingStencils_) + removeDuplicates_(stencil.second); + } + + /*! + * \brief Methods to be accessed by the assembly + */ + // \{ + + using ParentType::evalCouplingResidual; + + /*! + * \brief prepares all data and variables that are necessary to evaluate the residual of an Darcy element (i.e. Darcy information) + */ + template<std::size_t i, class Assembler, std::enable_if_t<(i == stokesCellCenterIdx || i == stokesFaceIdx), int> = 0> + void bindCouplingContext(Dune::index_constant<i> domainI, const Element<stokesCellCenterIdx>& element, const Assembler& assembler) const + { bindCouplingContext(domainI, element); } + + /*! + * \brief prepares all data and variables that are necessary to evaluate the residual of an Darcy element (i.e. Darcy information) + */ + template<std::size_t i, std::enable_if_t<(i == stokesCellCenterIdx || i == stokesFaceIdx), int> = 0> + void bindCouplingContext(Dune::index_constant<i> domainI, const Element<stokesCellCenterIdx>& element) const + { + stokesCouplingContext_.clear(); + + const auto stokesElementIdx = this->problem(stokesIdx).gridGeometry().elementMapper().index(element); + boundStokesElemIdx_ = stokesElementIdx; + + // do nothing if the element is not coupled to the other domain + if(!couplingMapper_.stokesElementToDarcyElementMap().count(stokesElementIdx)) + return; + + // prepare the coupling context + const auto& darcyIndices = couplingMapper_.stokesElementToDarcyElementMap().at(stokesElementIdx); + auto darcyFvGeometry = localView(this->problem(darcyIdx).gridGeometry()); + + for(auto&& indices : darcyIndices) + { + const auto& darcyElement = this->problem(darcyIdx).gridGeometry().boundingBoxTree().entitySet().entity(indices.eIdx); + darcyFvGeometry.bindElement(darcyElement); + const auto& scv = (*scvs(darcyFvGeometry).begin()); + + const auto darcyElemSol = elementSolution(darcyElement, this->curSol(darcyIdx), this->problem(darcyIdx).gridGeometry()); + VolumeVariables<darcyIdx> darcyVolVars; + darcyVolVars.update(darcyElemSol, this->problem(darcyIdx), darcyElement, scv); + + // add the context + stokesCouplingContext_.push_back({darcyElement, darcyFvGeometry, indices.scvfIdx, indices.flipScvfIdx, darcyVolVars}); + } + } + + /*! + * \brief prepares all data and variables that are necessary to evaluate the residual of an Darcy element (i.e. Stokes information) + */ + template<class Assembler> + void bindCouplingContext(Dune::index_constant<darcyIdx> domainI, const Element<darcyIdx>& element, const Assembler& assembler) const + { bindCouplingContext(domainI, element); } + + /*! + * \brief prepares all data and variables that are necessary to evaluate the residual of an Darcy element (i.e. Stokes information) + */ + void bindCouplingContext(Dune::index_constant<darcyIdx> domainI, const Element<darcyIdx>& element) const + { + darcyCouplingContext_.clear(); + + const auto darcyElementIdx = this->problem(darcyIdx).gridGeometry().elementMapper().index(element); + boundDarcyElemIdx_ = darcyElementIdx; + + // do nothing if the element is not coupled to the other domain + if(!couplingMapper_.darcyElementToStokesElementMap().count(darcyElementIdx)) + return; + + // prepare the coupling context + const auto& stokesElementIndices = couplingMapper_.darcyElementToStokesElementMap().at(darcyElementIdx); + auto stokesFvGeometry = localView(this->problem(stokesIdx).gridGeometry()); + + for(auto&& indices : stokesElementIndices) + { + const auto& stokesElement = this->problem(stokesIdx).gridGeometry().boundingBoxTree().entitySet().entity(indices.eIdx); + stokesFvGeometry.bindElement(stokesElement); + + VelocityVector faceVelocity(0.0); + + for(const auto& scvf : scvfs(stokesFvGeometry)) + { + if(scvf.index() == indices.scvfIdx) + faceVelocity[scvf.directionIndex()] = this->curSol(stokesFaceIdx)[scvf.dofIndex()]; + } + + using PriVarsType = typename VolumeVariables<stokesCellCenterIdx>::PrimaryVariables; + const auto& cellCenterPriVars = this->curSol(stokesCellCenterIdx)[indices.eIdx]; + const auto elemSol = makeElementSolutionFromCellCenterPrivars<PriVarsType>(cellCenterPriVars); + + VolumeVariables<stokesIdx> stokesVolVars; + for(const auto& scv : scvs(stokesFvGeometry)) + stokesVolVars.update(elemSol, this->problem(stokesIdx), stokesElement, scv); + + // add the context + darcyCouplingContext_.push_back({stokesElement, stokesFvGeometry, indices.scvfIdx, indices.flipScvfIdx, faceVelocity, stokesVolVars}); + } + } + + /*! + * \brief Update the coupling context for the Darcy residual w.r.t. Darcy DOFs + */ + template<class LocalAssemblerI> + void updateCouplingContext(Dune::index_constant<darcyIdx> domainI, + const LocalAssemblerI& localAssemblerI, + Dune::index_constant<darcyIdx> domainJ, + std::size_t dofIdxGlobalJ, + const PrimaryVariables<darcyIdx>& priVarsJ, + int pvIdxJ) + { + this->curSol(domainJ)[dofIdxGlobalJ][pvIdxJ] = priVarsJ[pvIdxJ]; + } + + /*! + * \brief Update the coupling context for the Darcy residual w.r.t. the Stokes cell-center DOFs (DarcyToCC) + */ + template<class LocalAssemblerI> + void updateCouplingContext(Dune::index_constant<darcyIdx> domainI, + const LocalAssemblerI& localAssemblerI, + Dune::index_constant<stokesCellCenterIdx> domainJ, + const std::size_t dofIdxGlobalJ, + const PrimaryVariables<stokesCellCenterIdx>& priVars, + int pvIdxJ) + { + this->curSol(domainJ)[dofIdxGlobalJ] = priVars; + + for (auto& data : darcyCouplingContext_) + { + const auto stokesElemIdx = this->problem(stokesIdx).gridGeometry().elementMapper().index(data.element); + + if(stokesElemIdx != dofIdxGlobalJ) + continue; + + using PriVarsType = typename VolumeVariables<stokesCellCenterIdx>::PrimaryVariables; + const auto elemSol = makeElementSolutionFromCellCenterPrivars<PriVarsType>(priVars); + + for(const auto& scv : scvs(data.fvGeometry)) + data.volVars.update(elemSol, this->problem(stokesIdx), data.element, scv); + } + } + + /*! + * \brief Update the coupling context for the Darcy residual w.r.t. the Stokes face DOFs (DarcyToFace) + */ + template<class LocalAssemblerI> + void updateCouplingContext(Dune::index_constant<darcyIdx> domainI, + const LocalAssemblerI& localAssemblerI, + Dune::index_constant<stokesFaceIdx> domainJ, + const std::size_t dofIdxGlobalJ, + const PrimaryVariables<stokesFaceIdx>& priVars, + int pvIdxJ) + { + this->curSol(domainJ)[dofIdxGlobalJ] = priVars; + + for (auto& data : darcyCouplingContext_) + { + for(const auto& scvf : scvfs(data.fvGeometry)) + { + if(scvf.dofIndex() == dofIdxGlobalJ) + data.velocity[scvf.directionIndex()] = priVars; + } + } + } + + /*! + * \brief Update the coupling context for the Stokes cc residual w.r.t. the Darcy DOFs (FaceToDarcy) + */ + template<std::size_t i, class LocalAssemblerI, std::enable_if_t<(i == stokesCellCenterIdx || i == stokesFaceIdx), int> = 0> + void updateCouplingContext(Dune::index_constant<i> domainI, + const LocalAssemblerI& localAssemblerI, + Dune::index_constant<darcyIdx> domainJ, + const std::size_t dofIdxGlobalJ, + const PrimaryVariables<darcyIdx>& priVars, + int pvIdxJ) + { + this->curSol(domainJ)[dofIdxGlobalJ] = priVars; + + for (auto& data : stokesCouplingContext_) + { + const auto darcyElemIdx = this->problem(darcyIdx).gridGeometry().elementMapper().index(data.element); + + if(darcyElemIdx != dofIdxGlobalJ) + continue; + + const auto darcyElemSol = elementSolution(data.element, this->curSol(darcyIdx), this->problem(darcyIdx).gridGeometry()); + + for(const auto& scv : scvs(data.fvGeometry)) + data.volVars.update(darcyElemSol, this->problem(darcyIdx), data.element, scv); + } + } + + // \} + + /*! + * \brief Access the coupling data + */ + const auto& couplingData() const + { + return *couplingData_; + } + + /*! + * \brief Access the coupling context needed for the Stokes domain + */ + const auto& stokesCouplingContext(const Element<stokesIdx>& element, const SubControlVolumeFace<stokesIdx>& scvf) const + { + if (stokesCouplingContext_.empty() || boundStokesElemIdx_ != scvf.insideScvIdx()) + bindCouplingContext(stokesIdx, element); + + for(const auto& context : stokesCouplingContext_) + { + if(scvf.index() == context.stokesScvfIdx) + return context; + } + + DUNE_THROW(Dune::InvalidStateException, "No coupling context found at scvf " << scvf.center() << ". This may occur if there is too extensive grading and cell sizes are too small."); + } + + /*! + * \brief Access the coupling context needed for the Darcy domain + */ + const auto& darcyCouplingContext(const Element<darcyIdx>& element, const SubControlVolumeFace<darcyIdx>& scvf) const + { + if (darcyCouplingContext_.empty() || boundDarcyElemIdx_ != scvf.insideScvIdx()) + bindCouplingContext(darcyIdx, element); + + for(const auto& context : darcyCouplingContext_) + { + if(scvf.index() == context.darcyScvfIdx) + return context; + } + + DUNE_THROW(Dune::InvalidStateException, "No coupling context found at scvf " << scvf.center()); + } + + /*! + * \brief The coupling stencils + */ + // \{ + + /*! + * \brief The Stokes cell center coupling stencil w.r.t. Darcy DOFs + */ + const CouplingStencil& couplingStencil(Dune::index_constant<stokesCellCenterIdx> domainI, + const Element<stokesIdx>& element, + Dune::index_constant<darcyIdx> domainJ) const + { + const auto eIdx = this->problem(domainI).gridGeometry().elementMapper().index(element); + if(stokesCellCenterCouplingStencils_.count(eIdx)) + return stokesCellCenterCouplingStencils_.at(eIdx); + else + return emptyStencil_; + } + + /*! + * \brief The coupling stencil of domain I, i.e. which domain J DOFs + * the given domain I element's residual depends on. + */ + template<std::size_t i, std::size_t j> + const CouplingStencil& couplingStencil(Dune::index_constant<i> domainI, + const Element<i>& element, + Dune::index_constant<j> domainJ) const + { return emptyStencil_; } + + /*! + * \brief The coupling stencil of domain I, i.e. which domain J dofs + * the given domain I element's residual depends on. + */ + const CouplingStencil& couplingStencil(Dune::index_constant<darcyIdx> domainI, + const Element<darcyIdx>& element, + Dune::index_constant<stokesCellCenterIdx> domainJ) const + { + const auto eIdx = this->problem(domainI).gridGeometry().elementMapper().index(element); + if(darcyToStokesCellCenterCouplingStencils_.count(eIdx)) + return darcyToStokesCellCenterCouplingStencils_.at(eIdx); + else + return emptyStencil_; + } + + /*! + * \brief The coupling stencil of domain I, i.e. which domain J dofs + * the given domain I element's residual depends on. + */ + const CouplingStencil& couplingStencil(Dune::index_constant<darcyIdx> domainI, + const Element<darcyIdx>& element, + Dune::index_constant<stokesFaceIdx> domainJ) const + { + const auto eIdx = this->problem(domainI).gridGeometry().elementMapper().index(element); + if (darcyToStokesFaceCouplingStencils_.count(eIdx)) + return darcyToStokesFaceCouplingStencils_.at(eIdx); + else + return emptyStencil_; + } + + /*! + * \brief The coupling stencil of domain I, i.e. which domain J DOFs + * the given domain I element's residual depends on. + */ + template<std::size_t i, std::size_t j> + const CouplingStencil& couplingStencil(Dune::index_constant<i> domainI, + const SubControlVolumeFace<stokesIdx>& scvf, + Dune::index_constant<j> domainJ) const + { return emptyStencil_; } + + /*! + * \brief The coupling stencil of a Stokes face w.r.t. Darcy DOFs + */ + const CouplingStencil& couplingStencil(Dune::index_constant<stokesFaceIdx> domainI, + const SubControlVolumeFace<stokesIdx>& scvf, + Dune::index_constant<darcyIdx> domainJ) const + { + const auto faceDofIdx = scvf.dofIndex(); + if(stokesFaceCouplingStencils_.count(faceDofIdx)) + return stokesFaceCouplingStencils_.at(faceDofIdx); + else + return emptyStencil_; + } + + // \} + + /*! + * \brief There are no additional dof dependencies + */ + template<class IdType> + const std::vector<std::size_t>& getAdditionalDofDependencies(IdType id, std::size_t stokesElementIdx) const + { return emptyStencil_; } + + /*! + * \brief There are no additional dof dependencies + */ + template<class IdType> + const std::vector<std::size_t>& getAdditionalDofDependenciesInverse(IdType id, std::size_t darcyElementIdx) const + { return emptyStencil_; } + + /*! + * \brief Returns whether a given free flow scvf is coupled to the other domain + */ + bool isCoupledEntity(Dune::index_constant<stokesIdx>, const SubControlVolumeFace<stokesFaceIdx>& scvf) const + { + return stokesFaceCouplingStencils_.count(scvf.dofIndex()); + } + + /*! + * \brief Returns whether a given free flow scvf is coupled to the other domain + */ + bool isCoupledEntity(Dune::index_constant<darcyIdx>, const SubControlVolumeFace<darcyIdx>& scvf) const + { + return couplingMapper_.isCoupledDarcyScvf(scvf.index()); + } + +protected: + + //! Return a reference to an empty stencil + std::vector<std::size_t>& emptyStencil() + { return emptyStencil_; } + + void removeDuplicates_(std::vector<std::size_t>& stencil) + { + std::sort(stencil.begin(), stencil.end()); + stencil.erase(std::unique(stencil.begin(), stencil.end()), stencil.end()); + } + +private: + + std::vector<bool> isCoupledDarcyDof_; + std::shared_ptr<CouplingData> couplingData_; + + std::unordered_map<std::size_t, std::vector<std::size_t> > stokesCellCenterCouplingStencils_; + std::unordered_map<std::size_t, std::vector<std::size_t> > stokesFaceCouplingStencils_; + std::unordered_map<std::size_t, std::vector<std::size_t> > darcyToStokesCellCenterCouplingStencils_; + std::unordered_map<std::size_t, std::vector<std::size_t> > darcyToStokesFaceCouplingStencils_; + std::vector<std::size_t> emptyStencil_; + + //////////////////////////////////////////////////////////////////////////// + //! The coupling context + //////////////////////////////////////////////////////////////////////////// + mutable std::vector<StationaryStokesCouplingContext> stokesCouplingContext_; + mutable std::vector<StationaryDarcyCouplingContext> darcyCouplingContext_; + + mutable std::size_t boundStokesElemIdx_; + mutable std::size_t boundDarcyElemIdx_; + + CouplingMapper couplingMapper_; +}; + +} // end namespace Dumux + +#endif -- GitLab From 6fa9a2c3a2337fa9128b98b34dc1b159ad444035 Mon Sep 17 00:00:00 2001 From: Melanie Lipp <melanie.lipp@iws.uni-stuttgart.de> Date: Mon, 4 Oct 2021 17:37:27 +0200 Subject: [PATCH 61/69] Make copies of couplingdata and couplingmanager used. --- .../stokesdarcy/1p_1p/convergencetest/main.cc | 8 +++---- .../{mycouplingdata.hh => cvdcouplingdata.hh} | 24 +++++++++---------- ...uplingmanager.hh => cvdcouplingmanager.hh} | 16 ++++++------- 3 files changed, 24 insertions(+), 24 deletions(-) rename dumux/multidomain/boundary/stokesdarcy/{mycouplingdata.hh => cvdcouplingdata.hh} (98%) rename dumux/multidomain/boundary/stokesdarcy/{mycouplingmanager.hh => cvdcouplingmanager.hh} (97%) diff --git a/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/main.cc b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/main.cc index ee54666..45a8484 100644 --- a/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/main.cc +++ b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/main.cc @@ -57,7 +57,7 @@ bool doFirstOrderLocalTruncErrorGlobalRefinement = false; #include <dumux/freeflow/navierstokes/staggered/griddatatransfer.hh> #include <dumux/freeflow/navierstokes/errors.hh> -#include <dumux/multidomain/boundary/stokesdarcy/mycouplingmanager.hh> +#include <dumux/multidomain/boundary/stokesdarcy/cvdcouplingmanager.hh> #include <dumux/discretization/staggered/cvdfvgridgeometry.hh> #include <dumux/discretization/staggered/freeflow/cvdfvgridgeometrytraits.hh> @@ -73,14 +73,14 @@ template<class TypeTag> struct CouplingManager<TypeTag, TTag::FreeFlowOneP> { using Traits = StaggeredMultiDomainTraits<TypeTag, TypeTag, Properties::TTag::DarcyOneP>; - using type = Dumux::MyStokesDarcyCouplingManager<Traits>; + using type = Dumux::CVDStokesDarcyCouplingManager<Traits>; }; template<class TypeTag> struct CouplingManager<TypeTag, TTag::DarcyOneP> { using Traits = StaggeredMultiDomainTraits<Properties::TTag::FreeFlowOneP, Properties::TTag::FreeFlowOneP, TypeTag>; - using type = Dumux::MyStokesDarcyCouplingManager<Traits>; + using type = Dumux::CVDStokesDarcyCouplingManager<Traits>; }; } // end namespace Properties @@ -277,7 +277,7 @@ int main(int argc, char** argv) using Traits = StaggeredMultiDomainTraits<FreeFlowTypeTag, FreeFlowTypeTag, DarcyTypeTag>; // the coupling manager - using CouplingManager = MyStokesDarcyCouplingManager<Traits>; + using CouplingManager = CVDStokesDarcyCouplingManager<Traits>; auto couplingManager = std::make_shared<CouplingManager>(freeFlowGridGeometry, darcyGridGeometry); // the indices diff --git a/dumux/multidomain/boundary/stokesdarcy/mycouplingdata.hh b/dumux/multidomain/boundary/stokesdarcy/cvdcouplingdata.hh similarity index 98% rename from dumux/multidomain/boundary/stokesdarcy/mycouplingdata.hh rename to dumux/multidomain/boundary/stokesdarcy/cvdcouplingdata.hh index db0488d..7b4e2fe 100644 --- a/dumux/multidomain/boundary/stokesdarcy/mycouplingdata.hh +++ b/dumux/multidomain/boundary/stokesdarcy/cvdcouplingdata.hh @@ -22,8 +22,8 @@ * \copydoc Dumux::StokesDarcyCouplingData */ -#ifndef DUMUX_STOKES_DARCY_MY_COUPLINGDATA_HH -#define DUMUX_STOKES_DARCY_MY_COUPLINGDATA_HH +#ifndef DUMUX_STOKES_DARCY_CVD_COUPLINGDATA_HH +#define DUMUX_STOKES_DARCY_CVD_COUPLINGDATA_HH #include <numeric> @@ -58,7 +58,7 @@ template<class T, DiscretizationMethod discMethod, ReferenceSystemFormulation re struct RefinedIsFicksLaw<RefinedFicksLawImplementation<T, discMethod, referenceSystem>> : public std::true_type {}; template<class MDTraits, class CouplingManager, bool enableEnergyBalance, bool isCompositional> -class MyStokesDarcyCouplingDataImplementation; +class CVDStokesDarcyCouplingDataImplementation; /*! * \ingroup BoundaryCoupling @@ -66,7 +66,7 @@ class MyStokesDarcyCouplingDataImplementation; * with a (Navier-)Stokes model (staggerd grid). */ template<class MDTraits, class CouplingManager> -using MyStokesDarcyCouplingData = MyStokesDarcyCouplingDataImplementation<MDTraits, CouplingManager, +using CVDStokesDarcyCouplingData = CVDStokesDarcyCouplingDataImplementation<MDTraits, CouplingManager, GetPropType<typename MDTraits::template SubDomain<0>::TypeTag, Properties::ModelTraits>::enableEnergyBalance(), (GetPropType<typename MDTraits::template SubDomain<0>::TypeTag, Properties::ModelTraits>::numFluidComponents() > 1)>; @@ -75,7 +75,7 @@ using MyStokesDarcyCouplingData = MyStokesDarcyCouplingDataImplementation<MDTrai * \brief A base class which provides some common methods used for Stokes-Darcy coupling. */ template<class MDTraits, class CouplingManager> -class MyStokesDarcyCouplingDataImplementationBase +class CVDStokesDarcyCouplingDataImplementationBase { using Scalar = typename MDTraits::Scalar; @@ -113,7 +113,7 @@ class MyStokesDarcyCouplingDataImplementationBase using DiffusionCoefficientAveragingType = typename StokesDarcyCouplingOptions::DiffusionCoefficientAveragingType; public: - MyStokesDarcyCouplingDataImplementationBase(const CouplingManager& couplingmanager): couplingManager_(couplingmanager) {} + CVDStokesDarcyCouplingDataImplementationBase(const CouplingManager& couplingmanager): couplingManager_(couplingmanager) {} /*! * \brief Returns the corresponding phase index needed for coupling. @@ -361,10 +361,10 @@ private: * \brief Coupling data specialization for non-compositional models. */ template<class MDTraits, class CouplingManager, bool enableEnergyBalance> -class MyStokesDarcyCouplingDataImplementation<MDTraits, CouplingManager, enableEnergyBalance, false> -: public MyStokesDarcyCouplingDataImplementationBase<MDTraits, CouplingManager> +class CVDStokesDarcyCouplingDataImplementation<MDTraits, CouplingManager, enableEnergyBalance, false> +: public CVDStokesDarcyCouplingDataImplementationBase<MDTraits, CouplingManager> { - using ParentType = MyStokesDarcyCouplingDataImplementationBase<MDTraits, CouplingManager>; + using ParentType = CVDStokesDarcyCouplingDataImplementationBase<MDTraits, CouplingManager>; using Scalar = typename MDTraits::Scalar; static constexpr auto stokesIdx = CouplingManager::stokesIdx; static constexpr auto darcyIdx = CouplingManager::darcyIdx; @@ -523,10 +523,10 @@ private: * \brief Coupling data specialization for compositional models. */ template<class MDTraits, class CouplingManager, bool enableEnergyBalance> -class MyStokesDarcyCouplingDataImplementation<MDTraits, CouplingManager, enableEnergyBalance, true> -: public MyStokesDarcyCouplingDataImplementationBase<MDTraits, CouplingManager> +class CVDStokesDarcyCouplingDataImplementation<MDTraits, CouplingManager, enableEnergyBalance, true> +: public CVDStokesDarcyCouplingDataImplementationBase<MDTraits, CouplingManager> { - using ParentType = MyStokesDarcyCouplingDataImplementationBase<MDTraits, CouplingManager>; + using ParentType = CVDStokesDarcyCouplingDataImplementationBase<MDTraits, CouplingManager>; using Scalar = typename MDTraits::Scalar; static constexpr auto stokesIdx = CouplingManager::stokesIdx; static constexpr auto darcyIdx = CouplingManager::darcyIdx; diff --git a/dumux/multidomain/boundary/stokesdarcy/mycouplingmanager.hh b/dumux/multidomain/boundary/stokesdarcy/cvdcouplingmanager.hh similarity index 97% rename from dumux/multidomain/boundary/stokesdarcy/mycouplingmanager.hh rename to dumux/multidomain/boundary/stokesdarcy/cvdcouplingmanager.hh index 8246f8c..b5a1d85 100644 --- a/dumux/multidomain/boundary/stokesdarcy/mycouplingmanager.hh +++ b/dumux/multidomain/boundary/stokesdarcy/cvdcouplingmanager.hh @@ -19,11 +19,11 @@ /*! * \file * \ingroup StokesDarcyCoupling - * \copydoc Dumux::MyStokesDarcyCouplingManager + * \copydoc Dumux::CVDStokesDarcyCouplingManager */ -#ifndef DUMUX_STOKES_DARCY_MY_COUPLINGMANAGER_HH -#define DUMUX_STOKES_DARCY_MY_COUPLINGMANAGER_HH +#ifndef DUMUX_STOKES_DARCY_CVD_COUPLINGMANAGER_HH +#define DUMUX_STOKES_DARCY_CVD_COUPLINGMANAGER_HH #include <utility> #include <memory> @@ -36,8 +36,8 @@ #include <dumux/multidomain/staggeredcouplingmanager.hh> #include <dumux/discretization/staggered/elementsolution.hh> -#include "mycouplingdata.hh" -#include "mycouplingmapper.hh" +#include "cvdcouplingdata.hh" +#include <dumux/multidomain/boundary/stokesdarcy/mycouplingmapper.hh> namespace Dumux { @@ -46,7 +46,7 @@ namespace Dumux { * \brief Coupling manager for Stokes and Darcy domains with equal dimension. */ template<class MDTraits> -class MyStokesDarcyCouplingManager +class CVDStokesDarcyCouplingManager : public StaggeredCouplingManager<MDTraits> { using Scalar = typename MDTraits::Scalar; @@ -118,10 +118,10 @@ public: using ParentType::couplingStencil; using ParentType::updateCouplingContext; - using CouplingData = MyStokesDarcyCouplingData<MDTraits, MyStokesDarcyCouplingManager<MDTraits>>; + using CouplingData = CVDStokesDarcyCouplingData<MDTraits, CVDStokesDarcyCouplingManager<MDTraits>>; //! Constructor - MyStokesDarcyCouplingManager(std::shared_ptr<const GridGeometry<stokesIdx>> stokesFvGridGeometry, + CVDStokesDarcyCouplingManager(std::shared_ptr<const GridGeometry<stokesIdx>> stokesFvGridGeometry, std::shared_ptr<const GridGeometry<darcyIdx>> darcyFvGridGeometry) { } -- GitLab From af17234117a27ad24290d3abfa0d769ffaf16ef6 Mon Sep 17 00:00:00 2001 From: Melanie Lipp <melanie.lipp@iws.uni-stuttgart.de> Date: Mon, 4 Oct 2021 17:43:05 +0200 Subject: [PATCH 62/69] Fix multidomain. Use elemLocalFaceVars in neumann. --- .../1p_1p/convergencetest/problem_stokes.hh | 48 ++++++++++++++++++- .../staggered/cvdfluxvariables.hh | 2 +- .../staggered/cvdlocalresidual.hh | 4 +- .../boundary/stokesdarcy/cvdcouplingdata.hh | 9 ++-- 4 files changed, 56 insertions(+), 7 deletions(-) diff --git a/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/problem_stokes.hh b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/problem_stokes.hh index 7f18fb8..6125e5a 100644 --- a/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/problem_stokes.hh +++ b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/problem_stokes.hh @@ -455,17 +455,63 @@ public: const ElementVolumeVariables& elemVolVars, const ElementFaceVariables& elemFaceVars, const SubControlVolumeFace& scvf) const + { + //this is to make sure momentumNeumann or contiNeumann are distinguished and not called uncontrolled + DUNE_THROW(Dune::InvalidStateException, ""); + } + + /*! + * \brief Evaluates the boundary conditions for a Neumann control volume. + * + * \param element The element for which the Neumann boundary condition is set + * \param fvGeometry The fvGeometry + * \param elemVolVars The element volume variables + * \param elemFaceVars The element face variables + * \param scvf The boundary sub control volume face + */ + template<class ElementVolumeVariables, class ElementFaceVariables> + NumEqVector momentumNeumann(const Element& element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars, + const ElementFaceVariables& elemFaceVars, + const SubControlVolumeFace& scvf) const { NumEqVector values(0.0); if(couplingManager().isCoupledEntity(CouplingManager::stokesIdx, scvf)) { - values[Indices::conti0EqIdx] = couplingManager().couplingData().massCouplingCondition(element, fvGeometry, elemVolVars, elemFaceVars, scvf); values[Indices::momentumYBalanceIdx] = couplingManager().couplingData().momentumCouplingCondition(element, fvGeometry, elemVolVars, elemFaceVars, scvf); } return values; } + + /*! + * \brief Evaluates the boundary conditions for a Neumann control volume. + * + * \param element The element for which the Neumann boundary condition is set + * \param fvGeometry The fvGeometry + * \param elemVolVars The element volume variables + * \param elemFaceVars The element face variables + * \param scvf The boundary sub control volume face + */ + template<class ElementVolumeVariables, class ElementFaceVariables, class ElementLocalFaceVariables> + NumEqVector contiNeumann(const Element& element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars, + const ElementFaceVariables& elemFaceVars, + const ElementLocalFaceVariables& elemLocalFaceVars, + const SubControlVolumeFace& scvf) const + { + NumEqVector values(0.0); + + if(couplingManager().isCoupledEntity(CouplingManager::stokesIdx, scvf)) + { + values[Indices::conti0EqIdx] = couplingManager().couplingData().massCouplingCondition(element, fvGeometry, elemVolVars, elemFaceVars, elemLocalFaceVars, scvf); + } + return values; + } + // \} //! Get the coupling manager diff --git a/dumux/freeflow/navierstokes/staggered/cvdfluxvariables.hh b/dumux/freeflow/navierstokes/staggered/cvdfluxvariables.hh index 6c2bc24..09f55b7 100644 --- a/dumux/freeflow/navierstokes/staggered/cvdfluxvariables.hh +++ b/dumux/freeflow/navierstokes/staggered/cvdfluxvariables.hh @@ -454,7 +454,7 @@ public: // Handle Neumann boundary conditions. No further calculations are then required for the given sub face. if(bcTypes.isNeumann(Indices::velocity(scvf.directionIndex()))) { - Scalar addedVal = problem.neumann(element, fvGeometry, elemVolVars, elemFaceVars, localSubFace)[Indices::velocity(scvf.directionIndex())] * extrusionFactorInsideVolVars.extrusionFactor() * normalFace.area(); + Scalar addedVal = problem.momentumNeumann(element, fvGeometry, elemVolVars, elemFaceVars, localSubFace)[Indices::velocity(scvf.directionIndex())] * extrusionFactorInsideVolVars.extrusionFactor() * normalFace.area(); if (useConservation || !normalFace.neighbor() || normalFace.inside().level() >= normalFace.outside().level()) { diff --git a/dumux/freeflow/navierstokes/staggered/cvdlocalresidual.hh b/dumux/freeflow/navierstokes/staggered/cvdlocalresidual.hh index 2c00a31..e8aca1f 100644 --- a/dumux/freeflow/navierstokes/staggered/cvdlocalresidual.hh +++ b/dumux/freeflow/navierstokes/staggered/cvdlocalresidual.hh @@ -253,7 +253,7 @@ protected: { if(bcTypes.isNeumann(eqIdx + cellCenterOffset)) { - boundaryFlux[eqIdx] = problem.neumann(element, fvGeometry, elemVolVars, elemFaceVars, scvf)[eqIdx + cellCenterOffset] + boundaryFlux[eqIdx] = problem.contiNeumann(element, fvGeometry, elemVolVars, elemFaceVars, elemLocalFaceVars, scvf)[eqIdx + cellCenterOffset] * extrusionFactor * scvf.area(); } } @@ -311,7 +311,7 @@ protected: // set a given Neumann flux for the face on the boundary itself const auto extrusionFactor = extrusionFactorInsideVolVars.extrusionFactor(); - residual = problem.neumann(element, fvGeometry, elemVolVars, elemFaceVars, scvf)[Indices::velocity(scvf.directionIndex())] + residual = problem.momentumNeumann(element, fvGeometry, elemVolVars, elemFaceVars, scvf)[Indices::velocity(scvf.directionIndex())] * extrusionFactor * scvf.area(); // treat the remaining (frontal and lateral) faces of the staggered control volume diff --git a/dumux/multidomain/boundary/stokesdarcy/cvdcouplingdata.hh b/dumux/multidomain/boundary/stokesdarcy/cvdcouplingdata.hh index 7b4e2fe..cb228a7 100644 --- a/dumux/multidomain/boundary/stokesdarcy/cvdcouplingdata.hh +++ b/dumux/multidomain/boundary/stokesdarcy/cvdcouplingdata.hh @@ -414,14 +414,16 @@ public: /*! * \brief Returns the mass flux across the coupling boundary as seen from the free-flow domain. */ + template<class ElementLocalFaceVariables> Scalar massCouplingCondition(const Element<stokesIdx>& element, const FVElementGeometry<stokesIdx>& fvGeometry, const ElementVolumeVariables<stokesIdx>& stokesElemVolVars, const ElementFaceVariables<stokesIdx>& stokesElemFaceVars, + const ElementLocalFaceVariables& stokesElemLocalFaceVars, const SubControlVolumeFace<stokesIdx>& scvf) const { const auto& stokesContext = this->couplingManager().stokesCouplingContext(element, scvf); - const Scalar velocity = stokesElemFaceVars[scvf].velocitySelf(); + const Scalar velocity = stokesElemLocalFaceVars[scvf.insideScvIdx()].velocity(scvf.outerNormalIndex()); const Scalar stokesDensity = stokesElemVolVars[scvf.insideScvIdx()][scvf.localFaceIdx()].inside.density(); const Scalar darcyDensity = stokesContext.volVars.density(couplingPhaseIdx(darcyIdx)); const bool insideIsUpstream = sign(velocity) == scvf.directionSign(); @@ -604,10 +606,11 @@ public: /*! * \brief Returns the mass flux across the coupling boundary as seen from the free-flow domain. */ + template<class ElementLocalFaceVariables> NumEqVector massCouplingCondition(const Element<stokesIdx>& element, const FVElementGeometry<stokesIdx>& fvGeometry, const ElementVolumeVariables<stokesIdx>& stokesElemVolVars, - const ElementFaceVariables<stokesIdx>& stokesElemFaceVars, + const ElementFaceVariables<stokesIdx>& stokesElemFaceVars, const ElementLocalFaceVariables& stokesElemLocalFaceVars, const SubControlVolumeFace<stokesIdx>& scvf, const DiffusionCoefficientAveragingType diffCoeffAvgType = DiffusionCoefficientAveragingType::ffOnly) const { @@ -617,7 +620,7 @@ public: const auto& darcyVolVars = stokesContext.volVars; const auto& outsideScv = (*scvs(stokesContext.fvGeometry).begin()); - const Scalar velocity = stokesElemFaceVars[scvf].velocitySelf(); + const Scalar velocity = stokesElemLocalFaceVars[scvf.insideScvIdx()].velocity(scvf.outerNormalIndex()); const bool insideIsUpstream = sign(velocity) == scvf.directionSign(); return massFlux_(stokesIdx, darcyIdx, fvGeometry, -- GitLab From fec4e0021553e1e920c8b0fa8b07416c0e52851f Mon Sep 17 00:00:00 2001 From: Melanie Lipp <melanie.lipp@iws.uni-stuttgart.de> Date: Wed, 6 Oct 2021 09:51:05 +0200 Subject: [PATCH 63/69] [appl][multidomain convergencetest] Change grid such that it is working. Switch the conservation off (not implemented for cvd. --- .../stokesdarcy/1p_1p/convergencetest/main.cc | 60 +++++++------------ .../1p_1p/convergencetest/params.input | 4 +- 2 files changed, 24 insertions(+), 40 deletions(-) diff --git a/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/main.cc b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/main.cc index 45a8484..fa99f3a 100644 --- a/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/main.cc +++ b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/main.cc @@ -268,6 +268,27 @@ int main(int argc, char** argv) const auto& darcyGridView = darcyGridManager.grid().leafGridView(); const auto& freeFlowGridView = freeFlowGridManager.grid().leafGridView(); + using GridGeometry = GetPropType<FreeFlowTypeTag, Properties::GridGeometry>; + using GridView = typename GridGeometry::GridView; + using Element = typename GridView::template Codim<0>::Entity; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + + freeFlowGridManager.grid().preAdapt(); + for (const auto& element : elements(freeFlowGridView)) + { + GlobalPosition pos = element.geometry().center(); + + auto x = pos[0]; + auto y = pos[1]; + + if (x < 0.6 && x > 0.4 && y < 1.6 && y > 1.4) + { + freeFlowGridManager.grid().mark(1, element); + } + } + freeFlowGridManager.grid().adapt(); + freeFlowGridManager.grid().postAdapt(); + // create the finite volume grid geometry using FreeFlowGridGeometry = GetPropType<FreeFlowTypeTag, Properties::GridGeometry>; auto freeFlowGridGeometry = std::make_shared<FreeFlowGridGeometry>(freeFlowGridView); @@ -379,46 +400,10 @@ int main(int argc, char** argv) NavierStokesRefinedErrors freeFlowErrors(freeFlowProblem, freeFlowSol, 0); NavierStokesRefinedErrorCSVWriter freeFlowErrorCSVWriter(freeFlowProblem); - for (unsigned int i=0; i < numRefinementSteps; ++i) - { - if (i>0) - { - // compute refinement indicator - indicator.calculateVelocityError(freeFlowSol, std::get<1>(freeFlowAnalyticalSolution), refineTol, coarsenTol); - - // mark elements and maybe adapt grid - bool wasAdapted = false; - if (markElements(freeFlowGridManager.grid(), indicator)) - wasAdapted = adapt(freeFlowGridManager.grid(), freeflowDataTransfer); - - if (wasAdapted) - { - darcyGridManager.grid().globalRefine(1); - - freeFlowGridGeometry->update(freeFlowGridView); - darcyGridGeometry->update(darcyGridView); - - freeFlowSol[FreeFlowGridGeometry::cellCenterIdx()] = 0.; - freeFlowSol[FreeFlowGridGeometry::cellCenterIdx()].resize(freeFlowGridView.size(0)); - freeFlowSol[FreeFlowGridGeometry::faceIdx()] = 0.; - freeFlowSol[FreeFlowGridGeometry::faceIdx()].resize((*freeFlowGridGeometry).numIntersections()); - sol[darcyIdx]= 0.; - sol[darcyIdx].resize(darcyGridGeometry->numDofs()); - - freeFlowGridVariables->updateAfterGridAdaption(freeFlowSol); //!< Initialize the secondary variables to the new (and "new old") solution - darcyGridVariables->updateAfterGridAdaption(sol[darcyIdx]); - - couplingManager->update(sol); - - assembler->reSetJacobianSize(); // has to be after nonlinear solver - assembler->reSetJacobianPattern(); //!< Tell the assembler to resize the matrix and set pattern - assembler->reSetResidualSize(); //!< Tell the assembler to resize the residual - } - } - nonLinearSolver.solve(sol); // write vtk output + int i = 0; freeFlowAnalyticalSolution = createFreeFlowAnalyticalSolution<Scalar>(*freeFlowProblem); darcyAnalyticalSolution = createDarcyAnalyticalSolution<Scalar>(*darcyProblem); freeFlowVtkWriter.write(i+1.0); @@ -428,7 +413,6 @@ int main(int argc, char** argv) freeFlowErrorCSVWriter.printErrors(freeFlowErrors); printDarcyL2Error(*darcyProblem, sol[darcyIdx]); - } //////////////////////////////////////////////////////////// // finalize, print dumux message to say goodbye diff --git a/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/params.input b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/params.input index 59cf609..a1b5ce4 100644 --- a/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/params.input +++ b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/params.input @@ -10,7 +10,7 @@ Grading1 = 1. Positions0 = 0 1 Positions1 = 1 2 Cells0 = 10 -Cells1 = 12 +Cells1 = 10 Grading0 = 1.0 Grading1 = 1.0 @@ -48,7 +48,7 @@ UpwindWeight = 0.5 EnableUnsymmetrizedVelocityGradientForBeaversJoseph = true [Adaptivity] -Conservation = true +Conservation = false [Adaptive] HigherOrderInterpolation = false -- GitLab From bc80805060b3aa9e2e75eb412d2e7859570e9411 Mon Sep 17 00:00:00 2001 From: Melanie Lipp <melanie.lipp@iws.uni-stuttgart.de> Date: Wed, 6 Oct 2021 10:17:00 +0200 Subject: [PATCH 64/69] [appl][multidomain convergencetest] Fix indentation. --- .../stokesdarcy/1p_1p/convergencetest/main.cc | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/main.cc b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/main.cc index fa99f3a..75e2389 100644 --- a/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/main.cc +++ b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/main.cc @@ -400,19 +400,19 @@ int main(int argc, char** argv) NavierStokesRefinedErrors freeFlowErrors(freeFlowProblem, freeFlowSol, 0); NavierStokesRefinedErrorCSVWriter freeFlowErrorCSVWriter(freeFlowProblem); - nonLinearSolver.solve(sol); + nonLinearSolver.solve(sol); - // write vtk output - int i = 0; - freeFlowAnalyticalSolution = createFreeFlowAnalyticalSolution<Scalar>(*freeFlowProblem); - darcyAnalyticalSolution = createDarcyAnalyticalSolution<Scalar>(*darcyProblem); - freeFlowVtkWriter.write(i+1.0); - darcyVtkWriter.write(i+1.0); + // write vtk output + int i = 0; + freeFlowAnalyticalSolution = createFreeFlowAnalyticalSolution<Scalar>(*freeFlowProblem); + darcyAnalyticalSolution = createDarcyAnalyticalSolution<Scalar>(*darcyProblem); + freeFlowVtkWriter.write(i+1.0); + darcyVtkWriter.write(i+1.0); - freeFlowErrors.update(freeFlowSol, i); - freeFlowErrorCSVWriter.printErrors(freeFlowErrors); + freeFlowErrors.update(freeFlowSol, i); + freeFlowErrorCSVWriter.printErrors(freeFlowErrors); - printDarcyL2Error(*darcyProblem, sol[darcyIdx]); + printDarcyL2Error(*darcyProblem, sol[darcyIdx]); //////////////////////////////////////////////////////////// // finalize, print dumux message to say goodbye -- GitLab From 0ab64bf74010cb3474733d52a72239d356c47778 Mon Sep 17 00:00:00 2001 From: Melanie Lipp <melanie.lipp@iws.uni-stuttgart.de> Date: Thu, 7 Oct 2021 10:23:51 +0200 Subject: [PATCH 65/69] Make sure non-multidomain tests resume working. --- dumux/freeflow/navierstokes/cvdproblem.hh | 40 +++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/dumux/freeflow/navierstokes/cvdproblem.hh b/dumux/freeflow/navierstokes/cvdproblem.hh index 8684be5..749f54f 100644 --- a/dumux/freeflow/navierstokes/cvdproblem.hh +++ b/dumux/freeflow/navierstokes/cvdproblem.hh @@ -513,6 +513,46 @@ public: return analyticalFaceSolutionVector_; } + /*! + * \brief Evaluates the boundary conditions for a Neumann control volume. + * + * \param element The element for which the Neumann boundary condition is set + * \param fvGeometry The fvGeometry + * \param elemVolVars The element volume variables + * \param elemFaceVars The element face variables + * \param scvf The boundary sub control volume face + */ + template<class ElementVolumeVariables, class ElementFaceVariables> + NumEqVector momentumNeumann(const Element& element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars, + const ElementFaceVariables& elemFaceVars, + const SubControlVolumeFace& scvf) const + { + return asImp_().neumannAtPos(scvf.ipGlobal()); + } + + + /*! + * \brief Evaluates the boundary conditions for a Neumann control volume. + * + * \param element The element for which the Neumann boundary condition is set + * \param fvGeometry The fvGeometry + * \param elemVolVars The element volume variables + * \param elemFaceVars The element face variables + * \param scvf The boundary sub control volume face + */ + template<class ElementVolumeVariables, class ElementFaceVariables, class ElementLocalFaceVariables> + NumEqVector contiNeumann(const Element& element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars, + const ElementFaceVariables& elemFaceVars, + const ElementLocalFaceVariables& elemLocalFaceVars, + const SubControlVolumeFace& scvf) const + { + return asImp_().neumannAtPos(scvf.ipGlobal()); + } + private: template <class Lambda> VelocityVector possiblyInstationaryAnalyticalVectorialVelocitySolutionAtGridCellCenterLambdaFunction_(const FVElementGeometry& fvGeometry, const Lambda& possiblyInstationaryAnalyticalVelocitySolutionAtPosLambdaFunction) const -- GitLab From e0b3e6260427fd746512bb5dd02da4d9f19287d7 Mon Sep 17 00:00:00 2001 From: Melanie Lipp <melanie.lipp@iws.uni-stuttgart.de> Date: Thu, 7 Oct 2021 10:34:28 +0200 Subject: [PATCH 66/69] [appl][channel] Remove non-isothermal tests from CMakeLists. Non-isothermal is not implemented for CVD. --- .../navierstokes/channel/2d/CMakeLists.txt | 23 ------------------- 1 file changed, 23 deletions(-) diff --git a/appl/freeflow/navierstokes/channel/2d/CMakeLists.txt b/appl/freeflow/navierstokes/channel/2d/CMakeLists.txt index 3e82f96..c3e9d49 100644 --- a/appl/freeflow/navierstokes/channel/2d/CMakeLists.txt +++ b/appl/freeflow/navierstokes/channel/2d/CMakeLists.txt @@ -36,26 +36,3 @@ dune_add_test(NAME test_ff_channel_navierstokes_stationary --files ${CMAKE_SOURCE_DIR}/../dumux/test/references/channel-navierstokes-stationary.vtu ${CMAKE_CURRENT_BINARY_DIR}/test_channel_navierstokes_stationary-00002.vtu --command "${CMAKE_CURRENT_BINARY_DIR}/test_ff_channel params_navierstokes_stationary.input") - - -add_executable(test_ff_stokesni_channel EXCLUDE_FROM_ALL main.cc) -target_compile_definitions(test_ff_stokesni_channel PUBLIC "NONISOTHERMAL=1") - -dune_add_test(NAME test_ff_channel_stokesni_convection - TARGET test_ff_stokesni_channel - CMAKE_GUARD HAVE_UMFPACK - COMMAND ${CMAKE_SOURCE_DIR}/../dumux/bin/testing/runtest.py - CMD_ARGS --script fuzzy - --files ${CMAKE_SOURCE_DIR}/../dumux/test/references/stokesni-convection-reference.vtu - ${CMAKE_CURRENT_BINARY_DIR}/test_channel_stokesni_convection-00006.vtu - --command "${CMAKE_CURRENT_BINARY_DIR}/test_ff_stokesni_channel params_convection.input") - -dune_add_test(NAME test_ff_channel_stokesni_conduction - TARGET test_ff_stokesni_channel - CMAKE_GUARD HAVE_UMFPACK - COMMAND ${CMAKE_SOURCE_DIR}/../dumux/bin/testing/runtest.py - CMD_ARGS --script fuzzy - --files ${CMAKE_SOURCE_DIR}/../dumux/test/references/stokesni-conduction-reference.vtu - ${CMAKE_CURRENT_BINARY_DIR}/test_channel_stokesni_conduction-00004.vtu - --command "${CMAKE_CURRENT_BINARY_DIR}/test_ff_stokesni_channel params_conduction.input" - --zeroThreshold {"velocity_H2O \(m/s\)":1e-20}) -- GitLab From 59d8f1cfe72bf4ad8c71f3815e3b486c86050733 Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Fri, 8 Oct 2021 14:31:51 +0300 Subject: [PATCH 67/69] modified and edited fine-velocity params files --- .../channel/2d/params_ns_stat_c120.input | 1 + .../channel/2d/params_ns_stat_c160.input | 1 + .../channel/2d/params_ns_stat_c20.input | 1 + .../channel/2d/params_ns_stat_c40.input | 1 + .../channel/2d/params_ns_stat_c80.input | 1 + .../channel/2d/params_ns_stat_fvd_c120.input | 74 ++++++++++++++++++ .../channel/2d/params_ns_stat_fvd_c160.input | 74 ++++++++++++++++++ .../channel/2d/params_ns_stat_fvd_c20.input | 2 +- .../channel/2d/params_ns_stat_fvd_c40.input | 2 +- .../channel/2d/params_ns_stat_fvd_c80.input | 2 +- .../navierstokes/donea/params_fvd_c120.input | 50 ++++++++++++ .../navierstokes/donea/params_fvd_c160.input | 50 ++++++++++++ .../navierstokes/donea/params_fvd_c20.input | 2 +- .../navierstokes/donea/params_fvd_c40.input | 2 +- .../navierstokes/donea/params_fvd_c80.input | 2 +- .../navierstokes/donea/params_vdP_c120.input | 51 ++++++++++++ .../navierstokes/donea/params_vdP_c160.input | 51 ++++++++++++ .../sincos/params_vdP_fvd_c120.input | 8 +- .../sincos/params_vdP_fvd_c160.input | 77 +++++++++++++++++++ .../sincos/params_vdP_fvd_c20.input | 8 +- .../sincos/params_vdP_fvd_c40.input | 8 +- .../sincos/params_vdP_fvd_c80.input | 8 +- 22 files changed, 454 insertions(+), 22 deletions(-) create mode 100644 appl/freeflow/navierstokes/channel/2d/params_ns_stat_fvd_c120.input create mode 100644 appl/freeflow/navierstokes/channel/2d/params_ns_stat_fvd_c160.input create mode 100644 appl/freeflow/navierstokes/donea/params_fvd_c120.input create mode 100644 appl/freeflow/navierstokes/donea/params_fvd_c160.input create mode 100644 appl/freeflow/navierstokes/donea/params_vdP_c120.input create mode 100644 appl/freeflow/navierstokes/donea/params_vdP_c160.input create mode 100644 appl/freeflow/navierstokes/sincos/params_vdP_fvd_c160.input diff --git a/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c120.input b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c120.input index 5b16505..6650028 100644 --- a/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c120.input +++ b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c120.input @@ -58,6 +58,7 @@ NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 [Adaptivity] Conservation = false +UseOwn4PointCoefficients = false Adapt = true LeftX = 2 RightX = 8 diff --git a/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c160.input b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c160.input index 662cd59..040d8f1 100644 --- a/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c160.input +++ b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c160.input @@ -58,6 +58,7 @@ NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 [Adaptivity] Conservation = false +UseOwn4PointCoefficients = false Adapt = true LeftX = 2 RightX = 8 diff --git a/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c20.input b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c20.input index d678d14..e6613ee 100644 --- a/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c20.input +++ b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c20.input @@ -58,6 +58,7 @@ NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 [Adaptivity] Conservation = false +UseOwn4PointCoefficients = false Adapt = true LeftX = 2 RightX = 8 diff --git a/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c40.input b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c40.input index 31d16c1..2a0bc95 100644 --- a/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c40.input +++ b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c40.input @@ -58,6 +58,7 @@ NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 [Adaptivity] Conservation = false +UseOwn4PointCoefficients = false Adapt = true LeftX = 2 RightX = 8 diff --git a/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c80.input b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c80.input index 0c4475e..b8715a2 100644 --- a/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c80.input +++ b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_c80.input @@ -58,6 +58,7 @@ NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 [Adaptivity] Conservation = false +UseOwn4PointCoefficients = false Adapt = true LeftX = 2 RightX = 8 diff --git a/appl/freeflow/navierstokes/channel/2d/params_ns_stat_fvd_c120.input b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_fvd_c120.input new file mode 100644 index 0000000..aaac24e --- /dev/null +++ b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_fvd_c120.input @@ -0,0 +1,74 @@ +[Helper.Grid] +Positions0 = 0 10 +Positions1 = 0 1 +Cells0 = 120 +Cells1 = 90 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_channel_ns_stat_c120 # name passed to the output routines +InletVelocity = 100 +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +AveragedAnalyticalSolution = false +UseScvfLineAveraging = true + +[Component] +MolarMass = 1.0 +LiquidDensity = 1 +LiquidKinematicViscosity = 1 + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-8 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true + +[Vtk] +WriteFaceData = false + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +# This test does actually not require setting the primary variable magnitues. +# This rather serves as a demonstration of how to use the feature. +[CellCenter.Assembly] +NumericDifference.PriVarMagnitude = 1e5 # pressure is in the order of 1e5 + +[Face.Assembly] +NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 + +[Adaptivity] +LinearInterpolation = true +Conservation = false +Adapt = true +LeftX = 2 +RightX = 8 +LowerY = 0.2 +UpperY = 0.8 + +[Adaptive] +RefineAtDirichletBC = 0 +RefineAtFluxBC = 1 +MinLevel = 0 +MaxLevel = 0 +CoarsenTolerance = 1e-4 +RefineTolerance = 2e-1 diff --git a/appl/freeflow/navierstokes/channel/2d/params_ns_stat_fvd_c160.input b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_fvd_c160.input new file mode 100644 index 0000000..d89818f --- /dev/null +++ b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_fvd_c160.input @@ -0,0 +1,74 @@ +[Helper.Grid] +Positions0 = 0 10 +Positions1 = 0 1 +Cells0 = 160 +Cells1 = 120 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_channel_ns_stat_c160 # name passed to the output routines +InletVelocity = 100 +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +AveragedAnalyticalSolution = false +UseScvfLineAveraging = true + +[Component] +MolarMass = 1.0 +LiquidDensity = 1 +LiquidKinematicViscosity = 1 + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-8 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true + +[Vtk] +WriteFaceData = false + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +# This test does actually not require setting the primary variable magnitues. +# This rather serves as a demonstration of how to use the feature. +[CellCenter.Assembly] +NumericDifference.PriVarMagnitude = 1e5 # pressure is in the order of 1e5 + +[Face.Assembly] +NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 + +[Adaptivity] +LinearInterpolation = true +Conservation = false +Adapt = true +LeftX = 2 +RightX = 8 +LowerY = 0.2 +UpperY = 0.8 + +[Adaptive] +RefineAtDirichletBC = 0 +RefineAtFluxBC = 1 +MinLevel = 0 +MaxLevel = 0 +CoarsenTolerance = 1e-4 +RefineTolerance = 2e-1 diff --git a/appl/freeflow/navierstokes/channel/2d/params_ns_stat_fvd_c20.input b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_fvd_c20.input index ed42d99..b548d3b 100644 --- a/appl/freeflow/navierstokes/channel/2d/params_ns_stat_fvd_c20.input +++ b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_fvd_c20.input @@ -58,7 +58,7 @@ NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 [Adaptivity] LinearInterpolation = true -Conservation = true +Conservation = false Adapt = true LeftX = 2 RightX = 8 diff --git a/appl/freeflow/navierstokes/channel/2d/params_ns_stat_fvd_c40.input b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_fvd_c40.input index 2688a1b..a873699 100644 --- a/appl/freeflow/navierstokes/channel/2d/params_ns_stat_fvd_c40.input +++ b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_fvd_c40.input @@ -58,7 +58,7 @@ NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 [Adaptivity] LinearInterpolation = true -Conservation = true +Conservation = false Adapt = true LeftX = 2 RightX = 8 diff --git a/appl/freeflow/navierstokes/channel/2d/params_ns_stat_fvd_c80.input b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_fvd_c80.input index aabd06e..01417e0 100644 --- a/appl/freeflow/navierstokes/channel/2d/params_ns_stat_fvd_c80.input +++ b/appl/freeflow/navierstokes/channel/2d/params_ns_stat_fvd_c80.input @@ -58,7 +58,7 @@ NumericDifference.PriVarMagnitude = 1 # velocity is in the order of 1 [Adaptivity] LinearInterpolation = true -Conservation = true +Conservation = false Adapt = true LeftX = 2 RightX = 8 diff --git a/appl/freeflow/navierstokes/donea/params_fvd_c120.input b/appl/freeflow/navierstokes/donea/params_fvd_c120.input new file mode 100644 index 0000000..5fb0784 --- /dev/null +++ b/appl/freeflow/navierstokes/donea/params_fvd_c120.input @@ -0,0 +1,50 @@ +[Helper.Grid] +Positions0 = 0 1 +Positions1 = 0 1 +Cells0 = 120 +Cells1 = 120 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = donea_full_c120 # name passed to the output routines +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = false +StartWithAnalytical = false +AveragedAnalyticalSolution = false +UseScvfLineAveraging = true + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-5 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = true + +[Adaptivity] +Adapt = true +LinearInterpolation = true #false: quadratic +Conservation = false + +[Component] +MolarMass = 1.0 +LiquidDensity = 1.0 +LiquidKinematicViscosity = 1.0 diff --git a/appl/freeflow/navierstokes/donea/params_fvd_c160.input b/appl/freeflow/navierstokes/donea/params_fvd_c160.input new file mode 100644 index 0000000..3b92df3 --- /dev/null +++ b/appl/freeflow/navierstokes/donea/params_fvd_c160.input @@ -0,0 +1,50 @@ +[Helper.Grid] +Positions0 = 0 1 +Positions1 = 0 1 +Cells0 = 160 +Cells1 = 160 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = donea_full_c160 # name passed to the output routines +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = false +StartWithAnalytical = false +AveragedAnalyticalSolution = false +UseScvfLineAveraging = true + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-5 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = true + +[Adaptivity] +Adapt = true +LinearInterpolation = true #false: quadratic +Conservation = false + +[Component] +MolarMass = 1.0 +LiquidDensity = 1.0 +LiquidKinematicViscosity = 1.0 diff --git a/appl/freeflow/navierstokes/donea/params_fvd_c20.input b/appl/freeflow/navierstokes/donea/params_fvd_c20.input index 4b598dc..8f55e4c 100644 --- a/appl/freeflow/navierstokes/donea/params_fvd_c20.input +++ b/appl/freeflow/navierstokes/donea/params_fvd_c20.input @@ -42,7 +42,7 @@ WriteFaceData = true [Adaptivity] Adapt = true LinearInterpolation = true #false: quadratic -Conservation = true +Conservation = false [Component] MolarMass = 1.0 diff --git a/appl/freeflow/navierstokes/donea/params_fvd_c40.input b/appl/freeflow/navierstokes/donea/params_fvd_c40.input index 508aed4..9bc0c65 100644 --- a/appl/freeflow/navierstokes/donea/params_fvd_c40.input +++ b/appl/freeflow/navierstokes/donea/params_fvd_c40.input @@ -42,7 +42,7 @@ WriteFaceData = true [Adaptivity] Adapt = true LinearInterpolation = true #false: quadratic -Conservation = true +Conservation = false [Component] MolarMass = 1.0 diff --git a/appl/freeflow/navierstokes/donea/params_fvd_c80.input b/appl/freeflow/navierstokes/donea/params_fvd_c80.input index 3f47b7c..3652041 100644 --- a/appl/freeflow/navierstokes/donea/params_fvd_c80.input +++ b/appl/freeflow/navierstokes/donea/params_fvd_c80.input @@ -42,7 +42,7 @@ WriteFaceData = true [Adaptivity] Adapt = true LinearInterpolation = true #false: quadratic -Conservation = true +Conservation = false [Component] MolarMass = 1.0 diff --git a/appl/freeflow/navierstokes/donea/params_vdP_c120.input b/appl/freeflow/navierstokes/donea/params_vdP_c120.input new file mode 100644 index 0000000..24abc09 --- /dev/null +++ b/appl/freeflow/navierstokes/donea/params_vdP_c120.input @@ -0,0 +1,51 @@ +[Helper.Grid] +Positions0 = 0 1 +Positions1 = 0 1 +Cells0 = 120 +Cells1 = 120 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = donea_full_vdP_c120 # name passed to the output routines +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = false +StartWithAnalytical = false +AveragedAnalyticalSolution = false +UseScvfLineAveraging = true + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-5 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = true + +[Adaptivity] +UseOwn4PointCoefficients = false +Adapt = true +LinearInterpolation = false #false: quadratic +Conservation = false + +[Component] +MolarMass = 1.0 +LiquidDensity = 1.0 +LiquidKinematicViscosity = 1.0 diff --git a/appl/freeflow/navierstokes/donea/params_vdP_c160.input b/appl/freeflow/navierstokes/donea/params_vdP_c160.input new file mode 100644 index 0000000..668803d --- /dev/null +++ b/appl/freeflow/navierstokes/donea/params_vdP_c160.input @@ -0,0 +1,51 @@ +[Helper.Grid] +Positions0 = 0 1 +Positions1 = 0 1 +Cells0 = 160 +Cells1 = 160 +Grading0 = 1.0 +Grading1 = 1.0 + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = donea_full_vdP_c160 # name passed to the output routines +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = false +StartWithAnalytical = false +AveragedAnalyticalSolution = false +UseScvfLineAveraging = true + +[ Newton ] +MaxSteps = 100 +MaxRelativeShift = 1e-5 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = true + +[Adaptivity] +UseOwn4PointCoefficients = false +Adapt = true +LinearInterpolation = false #false: quadratic +Conservation = false + +[Component] +MolarMass = 1.0 +LiquidDensity = 1.0 +LiquidKinematicViscosity = 1.0 diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_fvd_c120.input b/appl/freeflow/navierstokes/sincos/params_vdP_fvd_c120.input index db3460d..8204fcb 100644 --- a/appl/freeflow/navierstokes/sincos/params_vdP_fvd_c120.input +++ b/appl/freeflow/navierstokes/sincos/params_vdP_fvd_c120.input @@ -32,7 +32,7 @@ File = coarseyCVs.dgf File = grid.dgf [Problem] -Name = test_ff_sincos_vdP_full_c120 +Name = test_ff_sincos_fvd_c120 EnableGravity = false PrintErrors = true EnableInertiaTerms = true @@ -53,10 +53,10 @@ NumericDifference.BaseEpsilon = 1e-8 [Newton] MaxSteps = 10 TargetSteps = 4 -MaxRelativeShift = 1e-10 +MaxRelativeShift = 1e-8 SatisfyResidualAndShiftCriterion = true EnableAbsoluteResidualCriterion = true -MaxAbsoluteResidual = 1e-10 +MaxAbsoluteResidual = 1e-8 ExitAfterFirstIteration = false OutputMatrices = false @@ -69,7 +69,7 @@ UpwindWeight = 0.5 [Adaptivity] LinearInterpolation = true -Conservation = true +Conservation = false Adapt = true LeftX = .4 RightX = .6 diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_fvd_c160.input b/appl/freeflow/navierstokes/sincos/params_vdP_fvd_c160.input new file mode 100644 index 0000000..3aa08c0 --- /dev/null +++ b/appl/freeflow/navierstokes/sincos/params_vdP_fvd_c160.input @@ -0,0 +1,77 @@ +[TimeLoop] +DtInitial = 0.01 # [s] +TEnd = 1.0 # [s] + +[Helper.Grid] +Positions0 = 0.25 0.75 +Positions1 = 0.25 0.75 #we don't have symmetry BCs +Cells0 = 160 +Cells1 = 160 +Grading0 = 1.0 +Grading1 = 1.0 + +[xCVs.Grid] +File = xCVs.dgf + +[yCVs.Grid] +File = yCVs.dgf + +[finexCVs.Grid] +File = finexCVs.dgf + +[fineyCVs.Grid] +File = fineyCVs.dgf + +[coarsexCVs.Grid] +File = coarsexCVs.dgf + +[coarseyCVs.Grid] +File = coarseyCVs.dgf + +[Grid] +File = grid.dgf + +[Problem] +Name = test_ff_sincos_fvd_c160 +EnableGravity = false +PrintErrors = true +EnableInertiaTerms = true +IsStationary = true +VanDerPlasVersion = true +StartWithAnalytical = false +AveragedAnalyticalSolution = true +UseScvfLineAveraging = true + +[Component] +LiquidDensity = 1.0 +LiquidKinematicViscosity = 0.05 +MolarMass = 1.0 + +[Assembly] +NumericDifference.BaseEpsilon = 1e-8 + +[Newton] +MaxSteps = 10 +TargetSteps = 4 +MaxRelativeShift = 1e-8 +SatisfyResidualAndShiftCriterion = true +EnableAbsoluteResidualCriterion = true +MaxAbsoluteResidual = 1e-8 +ExitAfterFirstIteration = false +OutputMatrices = false + +[Vtk] +WriteFaceData = false +AddProcessRank = false + +[Flux] +UpwindWeight = 0.5 + +[Adaptivity] +LinearInterpolation = true +Conservation = false +Adapt = true +LeftX = .4 +RightX = .6 +LowerY = .4 +UpperY = .6 diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_fvd_c20.input b/appl/freeflow/navierstokes/sincos/params_vdP_fvd_c20.input index 6413bd3..6a329ae 100644 --- a/appl/freeflow/navierstokes/sincos/params_vdP_fvd_c20.input +++ b/appl/freeflow/navierstokes/sincos/params_vdP_fvd_c20.input @@ -32,7 +32,7 @@ File = coarseyCVs.dgf File = grid.dgf [Problem] -Name = test_ff_sincos_vdP_full_c20 +Name = test_ff_sincos_fvd_c20 EnableGravity = false PrintErrors = true EnableInertiaTerms = true @@ -53,10 +53,10 @@ NumericDifference.BaseEpsilon = 1e-8 [Newton] MaxSteps = 10 TargetSteps = 4 -MaxRelativeShift = 1e-10 +MaxRelativeShift = 1e-8 SatisfyResidualAndShiftCriterion = true EnableAbsoluteResidualCriterion = true -MaxAbsoluteResidual = 1e-10 +MaxAbsoluteResidual = 1e-8 ExitAfterFirstIteration = false OutputMatrices = false @@ -69,7 +69,7 @@ UpwindWeight = 0.5 [Adaptivity] LinearInterpolation = true -Conservation = true +Conservation = false Adapt = true LeftX = .4 RightX = .6 diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_fvd_c40.input b/appl/freeflow/navierstokes/sincos/params_vdP_fvd_c40.input index 018ceb5..ae586f4 100644 --- a/appl/freeflow/navierstokes/sincos/params_vdP_fvd_c40.input +++ b/appl/freeflow/navierstokes/sincos/params_vdP_fvd_c40.input @@ -32,7 +32,7 @@ File = coarseyCVs.dgf File = grid.dgf [Problem] -Name = test_ff_sincos_vdP_full_c40 +Name = test_ff_sincos_fvd_c40 EnableGravity = false PrintErrors = true EnableInertiaTerms = true @@ -53,10 +53,10 @@ NumericDifference.BaseEpsilon = 1e-8 [Newton] MaxSteps = 10 TargetSteps = 4 -MaxRelativeShift = 1e-10 +MaxRelativeShift = 1e-8 SatisfyResidualAndShiftCriterion = true EnableAbsoluteResidualCriterion = true -MaxAbsoluteResidual = 1e-10 +MaxAbsoluteResidual = 1e-8 ExitAfterFirstIteration = false OutputMatrices = false @@ -69,7 +69,7 @@ UpwindWeight = 0.5 [Adaptivity] LinearInterpolation = true -Conservation = true +Conservation = false Adapt = true LeftX = .4 RightX = .6 diff --git a/appl/freeflow/navierstokes/sincos/params_vdP_fvd_c80.input b/appl/freeflow/navierstokes/sincos/params_vdP_fvd_c80.input index 808cf01..72896a7 100644 --- a/appl/freeflow/navierstokes/sincos/params_vdP_fvd_c80.input +++ b/appl/freeflow/navierstokes/sincos/params_vdP_fvd_c80.input @@ -32,7 +32,7 @@ File = coarseyCVs.dgf File = grid.dgf [Problem] -Name = test_ff_sincos_vdP_full_c80 +Name = test_ff_sincos_fvd_c80 EnableGravity = false PrintErrors = true EnableInertiaTerms = true @@ -53,10 +53,10 @@ NumericDifference.BaseEpsilon = 1e-8 [Newton] MaxSteps = 10 TargetSteps = 4 -MaxRelativeShift = 1e-10 +MaxRelativeShift = 1e-8 SatisfyResidualAndShiftCriterion = true EnableAbsoluteResidualCriterion = true -MaxAbsoluteResidual = 1e-10 +MaxAbsoluteResidual = 1e-8 ExitAfterFirstIteration = false OutputMatrices = false @@ -69,7 +69,7 @@ UpwindWeight = 0.5 [Adaptivity] LinearInterpolation = true -Conservation = true +Conservation = false Adapt = true LeftX = .4 RightX = .6 -- GitLab From 75fc78a952e37f341451d3ea684e9408815f1c80 Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Sat, 9 Oct 2021 15:13:47 +0300 Subject: [PATCH 68/69] Removed conservation for params files --- .../1p_1p/convergencetest/paramsLocallyRefined.input | 2 +- .../stokesdarcy/1p_1p/convergencetest/paramsUniform.input | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/paramsLocallyRefined.input b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/paramsLocallyRefined.input index 3bfc8ee..af08211 100644 --- a/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/paramsLocallyRefined.input +++ b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/paramsLocallyRefined.input @@ -48,7 +48,7 @@ UpwindWeight = 0.5 EnableUnsymmetrizedVelocityGradientForBeaversJoseph = true [Adaptivity] -Conservation = true +Conservation = false [Adaptive] HigherOrderInterpolation = false diff --git a/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/paramsUniform.input b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/paramsUniform.input index 168b6d8..d6327f2 100644 --- a/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/paramsUniform.input +++ b/appl/multidomain/boundary/stokesdarcy/1p_1p/convergencetest/paramsUniform.input @@ -48,7 +48,7 @@ UpwindWeight = 0.5 EnableUnsymmetrizedVelocityGradientForBeaversJoseph = true [Adaptivity] -Conservation = true +Conservation = false [Adaptive] HigherOrderInterpolation = false -- GitLab From 04c4d6b38545cf79ebcf943c7596cac68efe83e9 Mon Sep 17 00:00:00 2001 From: Arunas Rimkus <st169459@stud.uni-stuttgart.de> Date: Sat, 9 Oct 2021 15:14:02 +0300 Subject: [PATCH 69/69] Bandaid fix for multidomain scv indices --- .../staggered/cvdfvgridgeometry.hh | 16 ++++++---- .../freeflow/cvdffsubcontrolvolumeface.hh | 29 ++++++++++++++++++- .../boundary/stokesdarcy/cvdcouplingdata.hh | 4 +-- 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/dumux/discretization/staggered/cvdfvgridgeometry.hh b/dumux/discretization/staggered/cvdfvgridgeometry.hh index 21d2a21..c7f9a39 100644 --- a/dumux/discretization/staggered/cvdfvgridgeometry.hh +++ b/dumux/discretization/staggered/cvdfvgridgeometry.hh @@ -373,16 +373,16 @@ public: //If hasn't been handled, create subcontrolvolumeface if (allowSCVFCreation) { - auto nIdx = this->elementMapper().index(intersection->outside()); - scvfs_.emplace_back(intersection, - scvfIdx, - std::vector<IndexType>({eIdx, nIdx}), - geometryHelper); - + auto nIdx = this->elementMapper().index(intersection->outside()); if(intersection->isInsideFiner()) { + //TODO: Make a unique SCVF for each small grid cell (with correct scv index - currently not done like this) auto e1Idx = this->elementMapper().index(intersection->intersections()[0].inside()); auto e2Idx = this->elementMapper().index(intersection->intersections()[1].inside()); + scvfs_.emplace_back(intersection, + scvfIdx, + std::vector<IndexType>({e1Idx, e2Idx, nIdx}), + geometryHelper); localToGlobalScvfIndices_[e1Idx].resize(numLocalFaces); localToGlobalScvfIndices_[e2Idx].resize(numLocalFaces); localToGlobalScvfIndices_[e1Idx][localFaceIndex] = scvfIdx; @@ -392,6 +392,10 @@ public: } else { + scvfs_.emplace_back(intersection, + scvfIdx, + std::vector<IndexType>({eIdx, nIdx}), + geometryHelper); localToGlobalScvfIndices_[eIdx][localFaceIndex] = scvfIdx; scvfIndicesOfScv_[eIdx].push_back(scvfIdx++); } diff --git a/dumux/discretization/staggered/freeflow/cvdffsubcontrolvolumeface.hh b/dumux/discretization/staggered/freeflow/cvdffsubcontrolvolumeface.hh index 493d608..a3c230a 100644 --- a/dumux/discretization/staggered/freeflow/cvdffsubcontrolvolumeface.hh +++ b/dumux/discretization/staggered/freeflow/cvdffsubcontrolvolumeface.hh @@ -194,6 +194,25 @@ public: return unitOuterNormal_; } + //! Index of actual inside sub control volume for spatial param evaluation (used as a bypass for badly implemented inside scv indices for double scvfs) + template<class Element> + GridIndexType insideScvIdx(const Element& ele_) const + { + int i = 0; + if (scvIndices_.size() > 2) + { + for (auto is : intersection_->intersections()) + { + if (is.inside() == ele_) + { + return scvIndices_[i]; + } + i++; + } + } + return scvIndices_[0]; + } + //! Index of the inside sub control volume for spatial param evaluation GridIndexType insideScvIdx() const { @@ -226,7 +245,15 @@ public: // This results in undefined behaviour if boundary is true GridIndexType outsideScvIdx() const { - return scvIndices_[1]; + if (scvIndices_.size() > 2) + { + //If inside is finer and we have two inside scv's + return scvIndices_[2]; + } + else + { + return scvIndices_[1]; + } } bool isSimple() const diff --git a/dumux/multidomain/boundary/stokesdarcy/cvdcouplingdata.hh b/dumux/multidomain/boundary/stokesdarcy/cvdcouplingdata.hh index cb228a7..8132290 100644 --- a/dumux/multidomain/boundary/stokesdarcy/cvdcouplingdata.hh +++ b/dumux/multidomain/boundary/stokesdarcy/cvdcouplingdata.hh @@ -423,7 +423,7 @@ public: const SubControlVolumeFace<stokesIdx>& scvf) const { const auto& stokesContext = this->couplingManager().stokesCouplingContext(element, scvf); - const Scalar velocity = stokesElemLocalFaceVars[scvf.insideScvIdx()].velocity(scvf.outerNormalIndex()); + const Scalar velocity = stokesElemLocalFaceVars[scvf.insideScvIdx(element)].velocity(scvf.outerNormalIndex()); const Scalar stokesDensity = stokesElemVolVars[scvf.insideScvIdx()][scvf.localFaceIdx()].inside.density(); const Scalar darcyDensity = stokesContext.volVars.density(couplingPhaseIdx(darcyIdx)); const bool insideIsUpstream = sign(velocity) == scvf.directionSign(); @@ -620,7 +620,7 @@ public: const auto& darcyVolVars = stokesContext.volVars; const auto& outsideScv = (*scvs(stokesContext.fvGeometry).begin()); - const Scalar velocity = stokesElemLocalFaceVars[scvf.insideScvIdx()].velocity(scvf.outerNormalIndex()); + const Scalar velocity = stokesElemLocalFaceVars[scvf.insideScvIdx(element)].velocity(scvf.outerNormalIndex()); const bool insideIsUpstream = sign(velocity) == scvf.directionSign(); return massFlux_(stokesIdx, darcyIdx, fvGeometry, -- GitLab