From a78975bb738947b41cdf1f035cee61582330b425 Mon Sep 17 00:00:00 2001 From: Bernd Flemisch <bernd@iws.uni-stuttgart.de> Date: Fri, 28 Nov 2014 10:06:10 +0000 Subject: [PATCH] [cell-centered implicit] fix a bug in the handling of mixed boundary conditions Mixed boundary conditions here means that a part of the equations/primary variables gets Dirichlet conditions, while the rest gets Neumann conditions. While in the cell-centered method pure Dirichlet conditions for all equations are handled by calculating the resulting fluxes and adding them to the cell residual, such a flux cannot be (easily?) calculated for an equation that gets a Dirichlet condition as part of mixed conditions. Therefore, such a Dirichlet condition is implemented in a strong way by _replacing_ the corresponding cell residual. It is important that this replacement is done at the very end of the residual calculation. However, for corner cells this has not been guaranteed so far. Therefore, fluxed resulting from the other boundary parts of a corner cell could have been added to the replaced residual, obviously leading to a wrong boundary condition treatment. This patch resolves the issue by guaranteeing that the residual replacement is done at the end of the residual calculation. Brought to attention and reviewed by Thomas. Thanks. git-svn-id: svn://svn.iws.uni-stuttgart.de/DUMUX/dumux/trunk@13823 2fb0f335-1f38-0410-981e-8018bf24f1b0 --- .../implicit/cellcentered/cclocalresidual.hh | 101 ++++++++++++------ .../implicit/common/implicitlocalresidual.hh | 4 + 2 files changed, 70 insertions(+), 35 deletions(-) diff --git a/dumux/implicit/cellcentered/cclocalresidual.hh b/dumux/implicit/cellcentered/cclocalresidual.hh index 242a7a7493..aa5d3048dd 100644 --- a/dumux/implicit/cellcentered/cclocalresidual.hh +++ b/dumux/implicit/cellcentered/cclocalresidual.hh @@ -68,8 +68,8 @@ public: protected: /*! - * \brief Add all Neumann and outflow boundary conditions to the local - * residual. + * \brief Add all fluxes resulting from Neumann, outflow and pure Dirichlet + * boundary conditions to the local residual. */ void evalBoundaryFluxes_() { @@ -92,9 +92,31 @@ protected: if (bcTypes.hasOutflow()) this->asImp_().evalOutflowSegment_(isIt, bcTypes); - // evaluate the Dirichlet conditions at the boundary face - if (bcTypes.hasDirichlet()) - this->asImp_().evalDirichletSegment_(isIt, bcTypes); + // evaluate the pure Dirichlet conditions at the boundary face + if (bcTypes.hasDirichlet() && !bcTypes.hasNeumann()) + this->asImp_().evalDirichletSegmentPure_(isIt, bcTypes); + } + } + + /*! + * \brief Evaluate Dirichlet conditions on faces that have mixed + * Dirichlet/Neumann boundary conditions. + */ + void evalDirichlet_() + { + IntersectionIterator isIt = this->gridView_().ibegin(this->element_()); + const IntersectionIterator &isEndIt = this->gridView_().iend(this->element_()); + for (; isIt != isEndIt; ++isIt) + { + // handle only faces on the boundary + if (!isIt->boundary()) + continue; + + BoundaryTypes bcTypes; + this->problem_().boundaryTypes(bcTypes, *isIt); + + if (bcTypes.hasDirichlet() && bcTypes.hasNeumann()) + this->asImp_().evalDirichletSegmentMixed_(isIt, bcTypes); } } @@ -151,7 +173,7 @@ protected: // manipulate the corresponding subcontrolvolume face SCVFace& boundaryFace = fvGeometry.boundaryFace[bfIdx]; - + // set the second flux approximation index for the boundary face for (int nIdx = 0; nIdx < fvGeometry.numNeighbors-1; nIdx++) { @@ -186,45 +208,54 @@ protected: } /*! - * \brief Add Dirichlet boundary conditions for a single intersection + * \brief Treat Dirichlet boundary conditions in a weak sense for a single + * intersection that only has Dirichlet boundary conditions */ - void evalDirichletSegment_(const IntersectionIterator &isIt, - const BoundaryTypes &bcTypes) + void evalDirichletSegmentPure_(const IntersectionIterator &isIt, + const BoundaryTypes &bcTypes) { // temporary vector to store the Dirichlet boundary fluxes PrimaryVariables values; Valgrind::SetUndefined(values); unsigned bfIdx = isIt->indexInInside(); - - // check for mixed Dirichlet/Neumann conditions - if (bcTypes.hasNeumann()) + + this->asImp_().computeFlux(values, bfIdx, true); + values *= this->curVolVars_(0).extrusionFactor(); + + // add fluxes to the residual + Valgrind::CheckDefined(values); + for (int eqIdx = 0; eqIdx < numEq; ++eqIdx) { - this->problem_().dirichlet(values, *isIt); - Valgrind::CheckDefined(values); - - // set Dirichlet conditions in a strong sense - for (int eqIdx = 0; eqIdx < numEq; ++eqIdx) - { - if (bcTypes.isDirichlet(eqIdx)) - { - int pvIdx = bcTypes.eqToDirichletIndex(eqIdx); - this->residual_[0][eqIdx] - = this->curPriVar_(0, pvIdx) - values[pvIdx]; - } - } + if (bcTypes.isDirichlet(eqIdx)) + this->residual_[0][eqIdx] += values[eqIdx]; } - else // pure Dirichlet conditions - { - this->asImp_().computeFlux(values, bfIdx, true); - values *= this->curVolVars_(0).extrusionFactor(); + } - // add fluxes to the residual - Valgrind::CheckDefined(values); - for (int eqIdx = 0; eqIdx < numEq; ++eqIdx) + /*! + * \brief Treat Dirichlet boundary conditions in a strong sense for a + * single intersection that has mixed D/N boundary conditions + */ + void evalDirichletSegmentMixed_(const IntersectionIterator &isIt, + const BoundaryTypes &bcTypes) + { + // temporary vector to store the Dirichlet boundary fluxes + PrimaryVariables values; + Valgrind::SetUndefined(values); + + unsigned bfIdx = isIt->indexInInside(); + + this->problem_().dirichlet(values, *isIt); + Valgrind::CheckDefined(values); + + // set Dirichlet conditions in a strong sense + for (int eqIdx = 0; eqIdx < numEq; ++eqIdx) + { + if (bcTypes.isDirichlet(eqIdx)) { - if (bcTypes.isDirichlet(eqIdx)) - this->residual_[0][eqIdx] += values[eqIdx]; + int pvIdx = bcTypes.eqToDirichletIndex(eqIdx); + this->residual_[0][eqIdx] + = this->curPriVar_(0, pvIdx) - values[pvIdx]; } } } @@ -244,7 +275,7 @@ protected: continue; fIdx++; - PrimaryVariables flux; + PrimaryVariables flux; Valgrind::SetUndefined(flux); this->asImp_().computeFlux(flux, fIdx); diff --git a/dumux/implicit/common/implicitlocalresidual.hh b/dumux/implicit/common/implicitlocalresidual.hh index 5f50c79825..cb77d3eda9 100644 --- a/dumux/implicit/common/implicitlocalresidual.hh +++ b/dumux/implicit/common/implicitlocalresidual.hh @@ -311,6 +311,10 @@ protected: else { asImp_().evalBoundaryFluxes_(); + + // additionally treat mixed D/N conditions in a strong sense + if (bcTypes_().hasDirichlet()) + asImp_().evalDirichlet_(); } #if !defined NDEBUG && HAVE_VALGRIND -- GitLab