From baa40c7e829d385046cc806694f181baba243763 Mon Sep 17 00:00:00 2001 From: "Dennis.Glaeser" <dennis.glaeser@iws.uni-stuttgart.de> Date: Tue, 17 Mar 2020 10:50:37 +0100 Subject: [PATCH] [facet][box] implement fouriers law --- dumux/multidomain/facet/box/CMakeLists.txt | 1 + dumux/multidomain/facet/box/fourierslaw.hh | 173 +++++++++++++++++++++ dumux/multidomain/facet/box/properties.hh | 8 + 3 files changed, 182 insertions(+) create mode 100644 dumux/multidomain/facet/box/fourierslaw.hh diff --git a/dumux/multidomain/facet/box/CMakeLists.txt b/dumux/multidomain/facet/box/CMakeLists.txt index a9641d813d..b73b0185d5 100644 --- a/dumux/multidomain/facet/box/CMakeLists.txt +++ b/dumux/multidomain/facet/box/CMakeLists.txt @@ -4,6 +4,7 @@ couplingmapper.hh darcyslaw.hh elementboundarytypes.hh fickslaw.hh +fourierslaw.hh fvelementgeometry.hh fvgridgeometry.hh localresidual.hh diff --git a/dumux/multidomain/facet/box/fourierslaw.hh b/dumux/multidomain/facet/box/fourierslaw.hh new file mode 100644 index 0000000000..43e4edeed6 --- /dev/null +++ b/dumux/multidomain/facet/box/fourierslaw.hh @@ -0,0 +1,173 @@ +// -*- 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 FacetCoupling + * \copydoc Dumux::BoxFacetCouplingFouriersLaw + */ +#ifndef DUMUX_DISCRETIZATION_BOX_FACET_COUPLING_FOURIERS_LAW_HH +#define DUMUX_DISCRETIZATION_BOX_FACET_COUPLING_FOURIERS_LAW_HH + +#include <cmath> +#include <vector> + +#include <dune/common/exceptions.hh> +#include <dune/common/fvector.hh> +#include <dune/common/float_cmp.hh> + +#include <dumux/common/math.hh> +#include <dumux/common/parameters.hh> +#include <dumux/common/properties.hh> + +#include <dumux/flux/referencesystemformulation.hh> +#include <dumux/flux/box/fourierslaw.hh> +#include <dumux/discretization/method.hh> + +namespace Dumux { + +/*! + * \ingroup FacetCoupling + * \brief Fourier's law for the box scheme in the context of coupled models + * where coupling occurs across the facets of the bulk domain elements + * with a lower-dimensional domain living on these facets. + */ +template<class TypeTag> +class BoxFacetCouplingFouriersLaw +: public FouriersLawImplementation<TypeTag, DiscretizationMethod::box> +{ + using ParentType = FouriersLawImplementation<TypeTag, DiscretizationMethod::box>; + + using Scalar = GetPropType<TypeTag, Properties::Scalar>; + using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; + using FVElementGeometry = typename GridGeometry::LocalView; + using SubControlVolume = typename FVElementGeometry::SubControlVolume; + using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace; + using GridView = typename GridGeometry::GridView; + using Element = typename GridView::template Codim<0>::Entity; + using CoordScalar = typename GridView::ctype; + using GlobalPosition = typename Element::Geometry::GlobalCoordinate; + + static constexpr int dim = GridView::dimension; + static constexpr int dimWorld = GridView::dimensionworld; + +public: + + /*! + * \brief Compute the conductive heat flux across a sub-control volume face. + */ + template<class Problem, class ElementVolumeVariables, class ElementFluxVarsCache> + static Scalar flux(const Problem& problem, + const Element& element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars, + const SubControlVolumeFace& scvf, + const ElementFluxVarsCache& elemFluxVarCache) + { + // if this scvf is not on an interior boundary, use the standard law + if (!scvf.interiorBoundary()) + return ParentType::flux(problem, element, fvGeometry, elemVolVars, scvf, elemFluxVarCache); + + static const Scalar xi = getParamFromGroup<Scalar>(problem.paramGroup(), "FacetCoupling.Xi", 1.0); + if ( !Dune::FloatCmp::eq(xi, 1.0, 1e-6) ) + DUNE_THROW(Dune::NotImplemented, "Xi != 1.0 cannot be used with the Box-Facet-Coupling scheme"); + + // get some references for convenience + const auto& fluxVarCache = elemFluxVarCache[scvf]; + const auto& shapeValues = fluxVarCache.shapeValues(); + const auto& insideScv = fvGeometry.scv(scvf.insideScvIdx()); + const auto& insideVolVars = elemVolVars[insideScv]; + + // on interior Neumann boundaries, evaluate the flux using the facet thermal conductivity + const auto bcTypes = problem.interiorBoundaryTypes(element, scvf); + if (bcTypes.hasOnlyNeumann()) + { + // compute tpfa flux from integration point to facet centerline + const auto& facetVolVars = problem.couplingManager().getLowDimVolVars(element, scvf); + + // interpolate temperature to scvf integration point + Scalar T = 0.0; + for (const auto& scv : scvs(fvGeometry)) + T += elemVolVars[scv].temperature()*shapeValues[scv.indexInElement()][0]; + + using std::sqrt; + // If this is a surface grid, use the square root of the facet extrusion factor + // as an approximate average distance from scvf ip to facet center + using std::sqrt; + const auto a = facetVolVars.extrusionFactor(); + auto gradT = scvf.unitOuterNormal(); + gradT *= dim == dimWorld ? 0.5*a : 0.5*sqrt(a); + gradT /= gradT.two_norm2(); + gradT *= (facetVolVars.temperature() - T); + + return -1.0*scvf.area() + *insideVolVars.extrusionFactor() + *vtmv(scvf.unitOuterNormal(), + facetVolVars.effectiveThermalConductivity(), + gradT); + } + + // on interior Dirichlet boundaries use the facet temperature and evaluate flux + else if (bcTypes.hasOnlyDirichlet()) + { + // create vector with nodal temperatures + std::vector<Scalar> temperatures(element.subEntities(dim)); + for (const auto& scv : scvs(fvGeometry)) + temperatures[scv.localDofIndex()] = elemVolVars[scv].temperature(); + + // substitute with facet temperatures for those scvs touching this facet + for (const auto& scvfJ : scvfs(fvGeometry)) + if (scvfJ.interiorBoundary() && scvfJ.facetIndexInElement() == scvf.facetIndexInElement()) + temperatures[ fvGeometry.scv(scvfJ.insideScvIdx()).localDofIndex() ] + = problem.couplingManager().getLowDimVolVars(element, scvfJ).temperature(); + + // evaluate gradT at integration point + Dune::FieldVector<Scalar, dimWorld> gradT(0.0); + for (const auto& scv : scvs(fvGeometry)) + gradT.axpy(temperatures[scv.localDofIndex()], fluxVarCache.gradN(scv.indexInElement())); + + // apply matrix thermal conductivity and return the flux + return -1.0*scvf.area() + *insideVolVars.extrusionFactor() + *vtmv(scvf.unitOuterNormal(), + insideVolVars.effectiveThermalConductivity(), + gradT); + } + + // mixed boundary types are not supported + else + DUNE_THROW(Dune::NotImplemented, "Mixed boundary types are not supported"); + } + + // compute transmissibilities ti for analytical jacobians + template<class Problem, class ElementVolumeVariables, class FluxVarCache> + static std::vector<Scalar> calculateTransmissibilities(const Problem& problem, + const Element& element, + const FVElementGeometry& fvGeometry, + const ElementVolumeVariables& elemVolVars, + const SubControlVolumeFace& scvf, + const FluxVarCache& fluxVarCache, + unsigned int phaseIdx) + { + DUNE_THROW(Dune::NotImplemented, "transmissibilty computation for BoxFacetCouplingFouriersLaw"); + } +}; + +} // end namespace Dumux + +#endif diff --git a/dumux/multidomain/facet/box/properties.hh b/dumux/multidomain/facet/box/properties.hh index 7d2ac65efe..07a0efe428 100644 --- a/dumux/multidomain/facet/box/properties.hh +++ b/dumux/multidomain/facet/box/properties.hh @@ -36,6 +36,7 @@ #include <dumux/multidomain/facet/box/darcyslaw.hh> #include <dumux/multidomain/facet/box/fickslaw.hh> +#include <dumux/multidomain/facet/box/fourierslaw.hh> #include <dumux/multidomain/facet/box/elementboundarytypes.hh> #include <dumux/multidomain/facet/box/fvgridgeometry.hh> #include <dumux/multidomain/facet/box/localresidual.hh> @@ -73,6 +74,13 @@ struct MolecularDiffusionType<TypeTag, TTag::BoxFacetCouplingModel> using type = BoxFacetCouplingFicksLaw< TypeTag >; }; +//! Use the box facet coupling-specific Fourier's law +template<class TypeTag> +struct HeatConductionType<TypeTag, TTag::BoxFacetCouplingModel> +{ + using type = BoxFacetCouplingFouriersLaw< TypeTag >; +}; + //! Per default, use the porous medium flow flux variables with the modified upwind scheme template<class TypeTag> struct FluxVariables<TypeTag, TTag::BoxFacetCouplingModel> -- GitLab