From cb836d2bf03bf0069ec8cf75b9b005b2b1bc1b3c Mon Sep 17 00:00:00 2001 From: Klaus Mosthaf <klmos@env.dtu.dk> Date: Fri, 13 Jan 2012 15:32:08 +0000 Subject: [PATCH] Enabled outflow conditions (beta version) for the 2p2cni model. boxspatialparameters: additional empty matrixHeatFlux() method, which uses the face as argument and can handle both, boundary faces and sub-control-volume faces; this is used for the calculation of outflow fluxes only so far and has to be specified in the spatial parameters, if required. 2p2cnifluxvariables: additional call to matrixHeatFlux(), if we are on a boundary face; changed temperature gradient to a private object with a return function to make it accessible from outside. boxlocalresidual: removed some superfluous asImp()s. 2p2cnilocalresidual: added computeOutflowValues() method for the evaluation of outflow conditions. regularizedvangenuchten: corrected typo. git-svn-id: svn://svn.iws.uni-stuttgart.de/DUMUX/dumux/trunk@7368 2fb0f335-1f38-0410-981e-8018bf24f1b0 --- dumux/boxmodels/2p2cni/2p2cnifluxvariables.hh | 35 ++++++++++----- dumux/boxmodels/2p2cni/2p2cnilocalresidual.hh | 43 ++++++++++++++++++- dumux/boxmodels/common/boxlocalresidual.hh | 28 ++++++------ .../2p/regularizedvangenuchten.hh | 2 +- .../spatialparameters/boxspatialparameters.hh | 28 ++++++++++++ 5 files changed, 109 insertions(+), 27 deletions(-) diff --git a/dumux/boxmodels/2p2cni/2p2cnifluxvariables.hh b/dumux/boxmodels/2p2cni/2p2cnifluxvariables.hh index 52d09ba663..00e62b05dc 100644 --- a/dumux/boxmodels/2p2cni/2p2cnifluxvariables.hh +++ b/dumux/boxmodels/2p2cni/2p2cnifluxvariables.hh @@ -99,6 +99,9 @@ public: Scalar normalMatrixHeatFlux() const { return normalMatrixHeatFlux_; } + Vector temperatureGradient() const + { return temperatureGrad_; } + protected: template<class FaceType> void calculateValues_(const Problem &problem, @@ -112,29 +115,39 @@ protected: // calculate temperature gradient using finite element // gradients - Vector temperatureGrad(0); + temperatureGrad_ = 0; Vector tmp(0.0); for (int vertIdx = 0; vertIdx < this->fvGeom_.numVertices; vertIdx++) { - tmp = this->fvGeom_.subContVolFace[scvfIdx_].grad[vertIdx]; + tmp = face.grad[vertIdx]; tmp *= elemVolVars[vertIdx].temperature(); - temperatureGrad += tmp; + temperatureGrad_ += tmp; } // The spatial parameters calculates the actual heat flux vector - problem.spatialParameters().matrixHeatFlux(tmp, - *this, - elemVolVars, - temperatureGrad, - element, - this->fvGeom_, - scvfIdx_); + if (!onBoundary) + problem.spatialParameters().matrixHeatFlux(tmp, + *this, + elemVolVars, + temperatureGrad_, + element, + this->fvGeom_, + scvfIdx_); + else + problem.spatialParameters().matrixHeatFlux(tmp, + *this, + elemVolVars, + face, + element, + this->fvGeom_); + // project the heat flux vector on the face's normal vector - normalMatrixHeatFlux_ = tmp*this->fvGeom_.subContVolFace[scvfIdx_].normal; + normalMatrixHeatFlux_ = tmp*face.normal; } private: Scalar normalMatrixHeatFlux_; + Vector temperatureGrad_; int scvfIdx_; }; diff --git a/dumux/boxmodels/2p2cni/2p2cnilocalresidual.hh b/dumux/boxmodels/2p2cni/2p2cnilocalresidual.hh index f7a22d5cfc..c4a3450fe0 100644 --- a/dumux/boxmodels/2p2cni/2p2cnilocalresidual.hh +++ b/dumux/boxmodels/2p2cni/2p2cnilocalresidual.hh @@ -52,10 +52,12 @@ class TwoPTwoCNILocalResidual : public TwoPTwoCLocalResidual<TypeTag> typedef TwoPTwoCLocalResidual<TypeTag> ParentType; typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar; + typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; - typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; + typedef typename GET_PROP_TYPE(TypeTag, BoundaryVariables) BoundaryVariables; + typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes; typedef typename GET_PROP_TYPE(TypeTag, TwoPTwoCIndices) Indices; enum { @@ -174,6 +176,45 @@ public: fluxData.normalMatrixHeatFlux(); } + /*! + * \brief Compute the fluxes at outflow boundaries. This does essentially the same + * as computeFluxes, but the fluxes are evaluated at the integration point + * of the boundary face. Therefore, still some variables are evaluated + * at the vertex (usually the ones which are upwinded). + * + * \param flux A temporary vector, where the outflow boundary fluxes are written into + * \param boundaryVars The boundary variables object + * \param scvIdx The index of the SCV containing the outflow boundary face + * \param boundaryFaceIdx The index of the boundary face + */ + void computeOutflowValues(PrimaryVariables &flux, + const BoundaryVariables &boundaryVars, + const int scvIdx, + const int boundaryFaceIdx) + { + ParentType::computeOutflowValues(flux, boundaryVars, scvIdx, boundaryFaceIdx); + + const BoundaryTypes &bcTypes = this->bcTypes_(scvIdx); + const VolumeVariables &vertVars = this->curVolVars_()[scvIdx]; + + if (bcTypes.isOutflow(energyEqIdx)) + { + // advective heat flux in all phases + flux[energyEqIdx] = 0; + for (int phase = 0; phase < numPhases; ++phase) { + flux[energyEqIdx] += + boundaryVars.KmvpNormal(phase) * + vertVars.density(phase) * + vertVars.mobility(phase) * + vertVars.enthalpy(phase); + } + + // add conductive heat flux in all phases + flux[energyEqIdx] += + boundaryVars.normalMatrixHeatFlux(); + } + } + private: Scalar massUpwindWeight_; diff --git a/dumux/boxmodels/common/boxlocalresidual.hh b/dumux/boxmodels/common/boxlocalresidual.hh index ff718f3aea..eaf68a38a3 100644 --- a/dumux/boxmodels/common/boxlocalresidual.hh +++ b/dumux/boxmodels/common/boxlocalresidual.hh @@ -363,10 +363,10 @@ protected: assert(0 <= pvIdx && pvIdx < numEq); Valgrind::CheckDefined(tmp[pvIdx]); - this->residual_[i][eqIdx] = - curPrimaryVar_(i, pvIdx) - tmp[pvIdx]; + residual_[i][eqIdx] = + curPrimaryVar_(i, pvIdx) - tmp[pvIdx]; - this->storageTerm_[i][eqIdx] = 0.0; + storageTerm_[i][eqIdx] = 0.0; }; }; } @@ -406,15 +406,15 @@ protected: // add the residual of all vertices of the boundary // segment - evalNeumannSegment_(isIt, - elemVertIdx, - boundaryFaceIdx); + asImp_().evalNeumannSegment_(isIt, + elemVertIdx, + boundaryFaceIdx); // evaluate the outflow conditions at the boundary face // ATTENTION: This is so far a beta version that is only for the 2p2c and 2p2cni model // available and not thoroughly tested. - this->asImp_().evalOutflowSegment(isIt, - elemVertIdx, - boundaryFaceIdx); + asImp_().evalOutflowSegment(isIt, + elemVertIdx, + boundaryFaceIdx); } } } @@ -471,7 +471,7 @@ protected: PrimaryVariables flux; Valgrind::SetUndefined(flux); - this->asImp_().computeFlux(flux, k); + asImp_().computeFlux(flux, k); Valgrind::CheckDefined(flux); Scalar extrusionFactor = @@ -512,7 +512,7 @@ protected: // all sub control volumes for (int i=0; i < fvElemGeom_().numVertices; i++) { Valgrind::SetUndefined(storageTerm_[i]); - this->asImp_().computeStorage(storageTerm_[i], i, /*isOldSol=*/false); + asImp_().computeStorage(storageTerm_[i], i, /*isOldSol=*/false); storageTerm_[i] *= fvElemGeom_().subContVol[i].volume * curVolVars_(i).extrusionFactor(); @@ -543,8 +543,8 @@ protected: // doing the time discretization... Valgrind::SetUndefined(storageTerm_[i]); Valgrind::SetUndefined(tmp); - this->asImp_().computeStorage(storageTerm_[i], i, false); - this->asImp_().computeStorage(tmp, i, true); + asImp_().computeStorage(storageTerm_[i], i, false); + asImp_().computeStorage(tmp, i, true); Valgrind::CheckDefined(storageTerm_[i]); Valgrind::CheckDefined(tmp); @@ -557,7 +557,7 @@ protected: // subtract the source term from the local rate Valgrind::SetUndefined(tmp); - this->asImp_().computeSource(tmp, i); + asImp_().computeSource(tmp, i); Valgrind::CheckDefined(tmp); tmp *= fvElemGeom_().subContVol[i].volume * extrusionFactor; residual_[i] -= tmp; diff --git a/dumux/material/fluidmatrixinteractions/2p/regularizedvangenuchten.hh b/dumux/material/fluidmatrixinteractions/2p/regularizedvangenuchten.hh index 0563fd9982..68ad0a23b5 100644 --- a/dumux/material/fluidmatrixinteractions/2p/regularizedvangenuchten.hh +++ b/dumux/material/fluidmatrixinteractions/2p/regularizedvangenuchten.hh @@ -116,7 +116,7 @@ public: // use spline between threshold Swe and 1.0 Scalar mTh = VanGenuchten::dpC_dSw(params, SwThHigh); Spline<Scalar> sp(SwThHigh, 1.0, // x0, x1 - yTh, 0, // m0, m1 + yTh, 0, // y0, y1 mTh, m1); // m0, m1 return sp.eval(Swe); } diff --git a/dumux/material/spatialparameters/boxspatialparameters.hh b/dumux/material/spatialparameters/boxspatialparameters.hh index 0573e80cc0..e1e9d44cbf 100644 --- a/dumux/material/spatialparameters/boxspatialparameters.hh +++ b/dumux/material/spatialparameters/boxspatialparameters.hh @@ -99,6 +99,34 @@ public: "a materialLawParamsAtPos() method."); } + /*! + * \brief Calculate the heat flux \f$[W/m^2]\f$ through the + * rock matrix based on the temperature gradient \f$[K / m]\f$ + * + * This is only required for non-isothermal models that use outflow + * boundary conditions. + * + * \param heatFlux The resulting heat flux vector + * \param fluxDat The flux variables + * \param vDat The volume variables + * \param face The boundary or SCV face + * \param element The current finite element + * \param fvElemGeom The finite volume geometry of the current element + * \tparam FaceType The type of the face (boundary face / SCV face) + */ + template <class FaceType> + void matrixHeatFlux(Vector &heatFlux, + const FluxVariables &fluxDat, + const ElementVolumeVariables &vDat, + const FaceType &face, + const Element &element, + const FVElementGeometry &fvElemGeom) const + { + DUNE_THROW(Dune::InvalidStateException, + "The spatial parameters do not provide " + "a matrixHeatFlux() method."); + } + private: Implementation &asImp_() { return *static_cast<Implementation*>(this); } -- GitLab