From 1a2de93bdad8906296b4ba5e8c98fb0e21ef9af9 Mon Sep 17 00:00:00 2001 From: Martin Schneider <martin.schneider@iws.uni-stuttgart.de> Date: Thu, 3 Oct 2024 20:30:00 +0200 Subject: [PATCH] [test][stokes] Add volume averaging to determine permeability Co-authored-by: Timo Koch <timokoch@uio.no> --- .../permeabilityupscaling/main.cc | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/test/freeflow/navierstokes/permeabilityupscaling/main.cc b/test/freeflow/navierstokes/permeabilityupscaling/main.cc index bfe6c84c21..b80a3c7e97 100644 --- a/test/freeflow/navierstokes/permeabilityupscaling/main.cc +++ b/test/freeflow/navierstokes/permeabilityupscaling/main.cc @@ -37,8 +37,33 @@ #include <dumux/freeflow/navierstokes/velocityoutput.hh> #include <dumux/freeflow/navierstokes/fluxoveraxisalignedsurface.hh> +#include <dumux/geometry/intersectionentityset.hh> + #include "properties.hh" +template<class Position> +std::vector<Position> corners(const Position& c, const Position& l) +{ + const Position lowerLeft = c - 0.5*l; + return { + lowerLeft , lowerLeft + Position({l[0], 0.0, 0.0}), + lowerLeft + Position({0.0, l[1], 0.0}) , lowerLeft + Position({l[0], l[1], 0.0}), + lowerLeft + Position({0.0, 0.0, l[2]}) , lowerLeft + Position({l[0], 0.0, l[2]}), + lowerLeft + Position({0.0, l[1], l[2]}), lowerLeft + Position({l[0], l[1], l[2]}) + }; +} + + +// helper function to generate an REV geometry +template<class ctype, int dim> +auto makeAveragingVolume(const Dune::FieldVector<ctype, dim>& center, + const Dune::FieldVector<ctype, dim>& l) +{ + return Dune::MultiLinearGeometry<ctype, dim, dim>{ + Dune::GeometryTypes::cube(dim), corners(center, l) + }; +} + int main(int argc, char** argv) { using namespace Dumux; @@ -185,6 +210,59 @@ int main(int argc, char** argv) if (Dune::FloatCmp::ne(phi, phiRef, 1e-5)) DUNE_THROW(Dune::Exception, "Porosity " << phi << " doesn't match reference " << phiRef << " by " << phi-phiRef); + //////////////////////////////////////////////////////////// + // do the same calculations by using volume averaging + //////////////////////////////////////////////////////////// + + // Calculate element velocities + std::vector<GlobalPosition> velocity(leafGridView.size(0)); + auto fvGeometry = localView(*massGridGeometry); + for (const auto& element : elements(leafGridView)) + { + const auto eIdx = massGridGeometry->elementMapper().index(element); + fvGeometry.bind(element); + const auto getFaceVelocity = [&](const auto&, const auto& scvf) + { return massProblem->faceVelocity(element, fvGeometry, scvf); }; + + velocity[eIdx] = StaggeredVelocityReconstruction::cellCenterVelocity(getFaceVelocity, fvGeometry); + } + + const auto size = massGridGeometry->bBoxMax() - massGridGeometry->bBoxMin(); + const auto center = 0.5*(massGridGeometry->bBoxMax() + massGridGeometry->bBoxMin()); + const auto geo = makeAveragingVolume(center, size); + + using GES = GridViewGeometricEntitySet<GridView>; + using AES = SingleGeometryEntitySet<std::decay_t<decltype(geo)>>; + using IntersectionSet = IntersectionEntitySet<GES, AES>; + const auto gridEntitySet = std::make_shared<GES>(leafGridView); + const auto averagingEntitySet = std::make_shared<AES>(geo); + IntersectionSet iset; + iset.build(gridEntitySet, averagingEntitySet); + + Scalar phiAvg(0.0); + GlobalPosition vAvg(0.0); + for(const auto& is : intersections(iset)) + { + const auto geo = is.geometry(); + const auto volume = geo.volume(); + const auto eIdx = gridEntitySet->index(is.domainEntity()); + + phiAvg += volume; + // Here we apply a piecewise-constant interpolation (because of staggered scheme) + vAvg += velocity[eIdx]*volume; + } + phiAvg /= geo.volume(); + vAvg /= geo.volume(); + + Scalar KAvg = vAvg[0]*1e-12; + std::cout << "Permeability by volume averaging is: " << KAvg << " m^2" << std::endl; + std::cout << "Porosity by volume averaging is: " << phiAvg << std::endl; + + if (Dune::FloatCmp::ne(KAvg, KRef, 1e-5)) + DUNE_THROW(Dune::Exception, "Permeability (by volume averaging) " << KAvg << " doesn't match reference " << KRef << " by " << KAvg-KRef); + if (Dune::FloatCmp::ne(phiAvg, phiRef, 1e-5)) + DUNE_THROW(Dune::Exception, "Porosity (by volume averaging)" << phiAvg << " doesn't match reference " << phiRef << " by " << phiAvg-phiRef); + //////////////////////////////////////////////////////////// // finalize, print dumux message to say goodbye //////////////////////////////////////////////////////////// -- GitLab