From 54b0c351be61201bc86dde4d1e6376dcf1aba9ba Mon Sep 17 00:00:00 2001 From: Benjamin Faigle <benjamin.faigle@posteo.de> Date: Thu, 24 May 2012 15:19:28 +0000 Subject: [PATCH] -Naming conventions in transport module -Reformatted output of pressure module -overhauled upwinding: Fully Upwind and central implemented, fix for the case potential = 0. -Prepared stable modules for merge of multiphyiscs and adaptive model: -Total Concentration (P.V.) is now in cellData and not in FluidState -MuPhys: FluidState that is present locally conceptually decoupled from subdomain. Reviewed by Bernd git-svn-id: svn://svn.iws.uni-stuttgart.de/DUMUX/dumux/trunk@8383 2fb0f335-1f38-0410-981e-8018bf24f1b0 --- dumux/decoupled/2p2c/cellData2p2c.hh | 68 ++++-- .../2p2c/cellData2p2cmultiphysics.hh | 67 +++--- dumux/decoupled/2p2c/dec2p2cfluidstate.hh | 56 +---- dumux/decoupled/2p2c/fluxData2p2c.hh | 62 ++--- dumux/decoupled/2p2c/fvpressure2p2c.hh | 137 +++++++---- .../2p2c/fvpressure2p2cmultiphysics.hh | 199 +++++++++------- .../decoupled/2p2c/fvpressurecompositional.hh | 92 ++++---- dumux/decoupled/2p2c/fvtransport2p2c.hh | 221 ++++++++++-------- dumux/decoupled/2p2c/pseudo1p2cfluidstate.hh | 33 +-- 9 files changed, 496 insertions(+), 439 deletions(-) diff --git a/dumux/decoupled/2p2c/cellData2p2c.hh b/dumux/decoupled/2p2c/cellData2p2c.hh index 21b66478c8..fb3aab44e2 100644 --- a/dumux/decoupled/2p2c/cellData2p2c.hh +++ b/dumux/decoupled/2p2c/cellData2p2c.hh @@ -72,6 +72,9 @@ private: numComponents = GET_PROP_VALUE(TypeTag, NumComponents) }; protected: + // primary variable (phase pressure has to be stored in fluidstate) + Scalar massConcentration_[numComponents]; + Scalar mobility_[numPhases]; //numerical quantities @@ -104,12 +107,12 @@ public: globalIdx_ = 0; perimeter_ = 0.; } - + //! Acess to flux data, representing information living on the intersections FluxData& fluxData() { return fluxData_; } - + //! Constant acess to flux data, representing information living on the intersections const FluxData& fluxData() const { return fluxData_; @@ -134,33 +137,59 @@ public: } /*! Modify the phase pressure * @param phaseIdx index of the Phase - * @param value Value to be srored + * @param value Value to be stored */ void setPressure(int phaseIdx, Scalar value) { manipulateFluidState().setPressure(phaseIdx, value); } - //! \copydoc Dumux::DecoupledTwoPTwoCFluidState::massConcentration() + /*! + * \brief Returns the total mass concentration of a component \f$\mathrm{[kg/m^3]}\f$. + * + * This is equivalent to the sum of the component concentrations for all + * phases multiplied with the phase density. + * + * \param compIdx the index of the component + */ const Scalar totalConcentration(int compIdx) const { - return fluidState_->massConcentration(compIdx); + return massConcentration_[compIdx]; } - //! \copydoc Dumux::DecoupledTwoPTwoCFluidState::massConcentration() + //! \copydoc Dumux::CellData2P2C::totalConcentration() const Scalar massConcentration(int compIdx) const { - return fluidState_->massConcentration(compIdx); + return massConcentration_[compIdx]; } - //! \copydoc Dumux::DecoupledTwoPTwoCFluidState::setMassConcentration() + /*! + * \brief Sets the total mass concentration of a component \f$\mathrm{[kg/m^3]}\f$. + * + * @param compIdx index of the Component + * @param value Value to be stored + */ void setTotalConcentration(int compIdx, Scalar value) { - manipulateFluidState().setMassConcentration(compIdx, value); + massConcentration_[compIdx] = value; } - //! \copydoc Dumux::DecoupledTwoPTwoCFluidState::setMassConcentration() + //! \copydoc Dumux::CellData2P2C::setTotalConcentration() void setMassConcentration(int compIdx, Scalar value) { - manipulateFluidState().setMassConcentration(compIdx, value); + massConcentration_[compIdx] = value; + } + /*! + * \brief Calculate the total mass concentration of a component \f$\mathrm{[kg/m^3]}\f$ + * for a given porosity (within the initialization procedure). + * @param porosity Porosity + */ + void calculateMassConcentration(Scalar porosity) + { + massConcentration_[wCompIdx] = + porosity * (massFraction(wPhaseIdx,wCompIdx) * saturation(wPhaseIdx) * density(wPhaseIdx) + + massFraction(nPhaseIdx,wCompIdx) * saturation(nPhaseIdx) * density(nPhaseIdx)); + massConcentration_[nCompIdx] = + porosity * (massFraction(wPhaseIdx,nCompIdx) * saturation(wPhaseIdx) * density(wPhaseIdx) + + massFraction(nPhaseIdx,nCompIdx) * saturation(nPhaseIdx) * density(nPhaseIdx)); } //@} @@ -282,7 +311,9 @@ public: return fluidState_->viscosity(phaseIdx); } - //! \copydoc Dumux::DecoupledTwoPTwoCFluidState::capillaryPressure() + /*! + * \brief Returns the capillary pressure \f$\mathrm{[Pa]}\f$ + */ const Scalar capillaryPressure() const { return fluidState_->pressure(nPhaseIdx) - fluidState_->pressure(wPhaseIdx); @@ -319,12 +350,12 @@ public: } //@} - -// void setFluidState(FluidState& fluidState) -// DUNE_DEPRECATED -// { -// fluidState_ = &fluidState; -// } + //! Deprecated set function, use manipulateFluidState() instead + void setFluidState(FluidState& fluidState) + DUNE_DEPRECATED + { + fluidState_ = &fluidState; + } //! Returns a reference to the cells fluid state const FluidState& fluidState() const @@ -342,6 +373,7 @@ public: fluidState_ = new FluidState; return *fluidState_; } + //! stores this cell datas index, only for debugging purposes!! int& globalIdx() { return globalIdx_;} diff --git a/dumux/decoupled/2p2c/cellData2p2cmultiphysics.hh b/dumux/decoupled/2p2c/cellData2p2cmultiphysics.hh index 0ed1e5d62c..6ac0395369 100644 --- a/dumux/decoupled/2p2c/cellData2p2cmultiphysics.hh +++ b/dumux/decoupled/2p2c/cellData2p2cmultiphysics.hh @@ -113,30 +113,13 @@ public: else return this->fluidState_->pressure(phaseIdx); } - - //! \copydoc Dumux::DecoupledTwoPTwoCFluidState::massConcentration() - const Scalar totalConcentration(int compIdx) const + //! \copydoc Dumux::CellData2P2C::setPressure() + void setPressure(int phaseIdx, Scalar value) { if(fluidStateType_ == simple) - return simpleFluidState_->massConcentration(compIdx); + manipulateSimpleFluidState().setPressure(phaseIdx, value); else - return this->fluidState_->massConcentration(compIdx); - } - //! \copydoc Dumux::DecoupledTwoPTwoCFluidState::massConcentration() - const Scalar massConcentration(int compIdx) const - { - if(fluidStateType_ == simple) - return simpleFluidState_->massConcentration(compIdx); - else - return this->fluidState_->massConcentration(compIdx); - } - //! \copydoc Dumux::DecoupledTwoPTwoCFluidState::setMassConcentration() - void setTotalConcentration(int compIdx, Scalar value) - { - if(fluidStateType_ == simple) - return simpleFluidState_->setMassConcentration(compIdx, value); - else - return this->fluidState_->setMassConcentration(compIdx, value); + manipulateFluidState().setPressure(phaseIdx, value); } //@} @@ -159,14 +142,30 @@ public: { return subdomain_; } + //! Specify subdomain information and fluidStateType + /** This function is only called if + */ + void setSubdomainAndFluidStateType(int index) + { + subdomain_ = index; + if(index == 2) + fluidStateType_ = complex; + else + fluidStateType_ = simple; + } /*! \name Acess to secondary variables */ //@{ //! \copydoc Dumux::DecoupledTwoPTwoCFluidState::setSaturation() void setSaturation(int phaseIdx, Scalar value) { - assert(this->subdomain() == 2); - this->fluidState_->setSaturation(phaseIdx, value); + if(fluidStateType_ == simple) + { + // saturation is triggered by presentPhaseIdx + manipulateSimpleFluidState().setPresentPhaseIdx((value==0.) ? nPhaseIdx : wPhaseIdx); + } + else + manipulateFluidState().setSaturation(phaseIdx, value); } //! \copydoc Dumux::DecoupledTwoPTwoCFluidState::saturation() const Scalar saturation(int phaseIdx) const @@ -185,10 +184,10 @@ public: if(fluidStateType_ == simple) { assert(phaseIdx == simpleFluidState_->presentPhaseIdx()); - simpleFluidState_->setViscosity(phaseIdx, value); + manipulateSimpleFluidState().setViscosity(phaseIdx, value); } else - this->fluidState_->setViscosity(phaseIdx, value); + manipulateFluidState().setViscosity(phaseIdx, value); } //! \copydoc Dumux::DecoupledTwoPTwoCFluidState::viscosity() const Scalar viscosity(int phaseIdx) const @@ -297,8 +296,13 @@ public: //! Manipulates a simple fluidstate for a cell in the simple domain SimpleFluidState& manipulateSimpleFluidState() { - assert (this->subdomain() != 2); fluidStateType_ = simple; + if(this->fluidState_) + { + delete this->fluidState_; + this->fluidState_ = NULL; + } + if(!simpleFluidState_) simpleFluidState_ = new SimpleFluidState; return *simpleFluidState_; @@ -310,13 +314,22 @@ public: */ FluidState& manipulateFluidState() { - assert(this->subdomain() == 2); fluidStateType_ = complex; + if(simpleFluidState_) + { + delete simpleFluidState_; + simpleFluidState_ = NULL; + } + if(!this->fluidState_) this->fluidState_ = new FluidState; return *this->fluidState_; } + //! Returns the type of the fluidState + const bool fluidStateType() const + { return fluidStateType_;} + }; } #endif diff --git a/dumux/decoupled/2p2c/dec2p2cfluidstate.hh b/dumux/decoupled/2p2c/dec2p2cfluidstate.hh index 46ef932ed1..a183381782 100644 --- a/dumux/decoupled/2p2c/dec2p2cfluidstate.hh +++ b/dumux/decoupled/2p2c/dec2p2cfluidstate.hh @@ -119,7 +119,8 @@ public: // check if there is enough of component 1 to form a phase if (Z1 > massFraction_[nPhaseIdx][wCompIdx] && Z1 < massFraction_[wPhaseIdx][wCompIdx]) - nu_[nPhaseIdx] = -((equilRatio_[nPhaseIdx][wCompIdx]-1)*Z1 + (equilRatio_[nPhaseIdx][nCompIdx]-1)*(1-Z1)) / (equilRatio_[nPhaseIdx][wCompIdx]-1) / (equilRatio_[nPhaseIdx][nCompIdx] -1); + nu_[nPhaseIdx] = -((equilRatio_[nPhaseIdx][wCompIdx]-1)*Z1 + (equilRatio_[nPhaseIdx][nCompIdx]-1)*(1-Z1)) + / (equilRatio_[nPhaseIdx][wCompIdx]-1) / (equilRatio_[nPhaseIdx][nCompIdx] -1); else if (Z1 <= massFraction_[nPhaseIdx][wCompIdx]) // too little wComp to form a phase { nu_[nPhaseIdx] = 1; // only nPhase @@ -130,9 +131,7 @@ public: moleFraction_[nPhaseIdx][wCompIdx] /= ( massFraction_[nPhaseIdx][wCompIdx] / FluidSystem::molarMass(wCompIdx) + massFraction_[nPhaseIdx][nCompIdx] / FluidSystem::molarMass(nCompIdx) ); // /= total moles in phase - // corresponding phase - massFraction_[wPhaseIdx][wCompIdx] = 1.; - moleFraction_[wPhaseIdx][wCompIdx] = 1.; + // w phase is already set to equilibrium mass fraction } else // (Z1 >= Xw1) => no nPhase { @@ -144,8 +143,7 @@ public: moleFraction_[wPhaseIdx][wCompIdx] /= ( massFraction_[wPhaseIdx][wCompIdx] / FluidSystem::molarMass(wCompIdx) + massFraction_[wPhaseIdx][nCompIdx] / FluidSystem::molarMass(nCompIdx) ); // /= total moles in phase - massFraction_[nPhaseIdx][wCompIdx] = 0.; - moleFraction_[nPhaseIdx][wCompIdx] = 0.; + // n phase is already set to equilibrium mass fraction } // complete array of mass fractions @@ -225,13 +223,6 @@ public: // get densities with correct composition density_[wPhaseIdx] = FluidSystem::density(*this, wPhaseIdx); density_[nPhaseIdx] = FluidSystem::density(*this, nPhaseIdx); - - massConcentration_[wCompIdx] = - poro * (massFraction_[wPhaseIdx][wCompIdx] * Sw_ * density_[wPhaseIdx] - + massFraction_[nPhaseIdx][wCompIdx] * (1.-Sw_) * density_[nPhaseIdx]); - massConcentration_[nCompIdx] = - poro * (massFraction_[wPhaseIdx][nCompIdx] * Sw_ * density_[wPhaseIdx] - + massFraction_[nPhaseIdx][nCompIdx] * (1-Sw_) * density_[nPhaseIdx]); } //@} /*! @@ -273,43 +264,6 @@ public: return moleFraction_[phaseIdx][compIdx]; } - /*! - * \brief Returns the total mass concentration of a component \f$\mathrm{[kg/m^3]}\f$. - * - * This is equivalent to the sum of the component concentrations for all - * phases multiplied with the phase density. - * - * \param compIdx the index of the component - */ - Scalar massConcentration(int compIdx) const - { - return massConcentration_[compIdx]; - }; - /*! - * \brief Sets the total mass concentration of a component \f$\mathrm{[kg/m^3]}\f$. - * - * @param compIdx index of the Component - * @param value Value to be stored - */ - void setMassConcentration(int compIdx, Scalar value) - { - massConcentration_[compIdx] = value; - }; - /*! - * \brief Calculate the total mass concentration of a component \f$\mathrm{[kg/m^3]}\f$ - * for a given porosity (within the initialization procedure). - * @param porosity Porosity - */ - void calculateMassConcentration(Scalar porosity) - { - massConcentration_[wCompIdx] = - porosity * (massFraction_[wPhaseIdx][wCompIdx] * Sw_ * density_[wPhaseIdx] - + massFraction_[nPhaseIdx][wCompIdx] * (1.-Sw_) * density_[nPhaseIdx]); - massConcentration_[nCompIdx] = - porosity * (massFraction_[wPhaseIdx][nCompIdx] * Sw_ * density_[wPhaseIdx] - + massFraction_[nPhaseIdx][nCompIdx] * (1-Sw_) * density_[nPhaseIdx]); - } - /*! * \brief Returns the density of a phase \f$\mathrm{[kg/m^3]}\f$. * @@ -495,7 +449,7 @@ public: DecoupledTwoPTwoCFluidState() { Valgrind::SetUndefined(*this); } private: - Scalar massConcentration_[numComponents]; +// Scalar massConcentration_[numComponents]; Scalar phasePressure_[numPhases]; Scalar temperature_; diff --git a/dumux/decoupled/2p2c/fluxData2p2c.hh b/dumux/decoupled/2p2c/fluxData2p2c.hh index 49fcdf339d..e36450b8c5 100644 --- a/dumux/decoupled/2p2c/fluxData2p2c.hh +++ b/dumux/decoupled/2p2c/fluxData2p2c.hh @@ -81,67 +81,35 @@ public: isUpwindCell_[i] = false; } } + //! resizes the upwind vector for the case of hanging nodes void resize(int size) { isUpwindCell_.resize(size); } //! functions returning upwind information + /* @param indexInInside The local inside index of the intersection + * @param equationIdx The equation index + */ const bool& isUpwindCell(int indexInInside, int equationIdx) const { return isUpwindCell_[indexInInside][equationIdx]; } - + //! Sets the upwind information + /* @param indexInInside The local inside index of the intersection + * @param equationIdx The equation index + * @value value set true or false + */ void setUpwindCell(int indexInInside, int equationIdx, bool value) { isUpwindCell_[indexInInside][equationIdx] = value; } + //! Console output for the FluxData + void outputFluxData() + { + for(int banana=0; banana<isUpwindCell_.size(); banana++) + printvector(std::cout, isUpwindCell_, "upwindInformation", "row", 3); + } }; } #endif - - -/*** in transport module: - * // upwind mobility - double lambdaW, lambdaNW; - if (potentialW >= 0.) - { - lambdaW = cellDataI.mobility(wPhaseIdx); - cellDataI.setUpwindCell(intersection.indexInInside(), contiWEqIdx, true); - cellDataJ.setUpwindCell(intersection.indexInOutside(), contiWEqIdx, false); - } - else - { - lambdaW = cellDataJ.mobility(wPhaseIdx); - cellDataJ.setUpwindCell(intersection.indexInOutside(), contiWEqIdx, true); - cellDataI.setUpwindCell(intersection.indexInInside(), contiWEqIdx, false); - } - - if (potentialNW >= 0.) - { - lambdaNW = cellDataI.mobility(nPhaseIdx); - cellDataI.setUpwindCell(intersection.indexInInside(), contiNEqIdx, true); - cellDataJ.setUpwindCell(intersection.indexInOutside(), contiNEqIdx, false); - } - else - { - lambdaW = cellDataJ.mobility(nPhaseIdx); - cellDataJ.setUpwindCell(intersection.indexInOutside(), contiNEqIdx, true); - cellDataI.setUpwindCell(intersection.indexInInside(), contiNEqIdx, false); - } - - - in cellData: - - //! Acess to flux data - bool& isUpwindCell(int indexInInside, int equationIdx) const - { - return fluxData_.isUpwindCell(indexInInside, equationIdx); - } - - void setUpwindCell(int indexInInside, int equationIdx, bool value) - { - fluxData_.setUpwindCell(indexInInside, equationIdx, value); - } - */ - diff --git a/dumux/decoupled/2p2c/fvpressure2p2c.hh b/dumux/decoupled/2p2c/fvpressure2p2c.hh index 1a331aebda..5612c0de8f 100644 --- a/dumux/decoupled/2p2c/fvpressure2p2c.hh +++ b/dumux/decoupled/2p2c/fvpressure2p2c.hh @@ -129,8 +129,8 @@ template<class TypeTag> class FVPressure2P2C // convenience shortcuts for Vectors/Matrices typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition; - typedef Dune::FieldMatrix<Scalar, dim, dim> FieldMatrix; - typedef Dune::FieldVector<Scalar, 2> PhaseVector; + typedef Dune::FieldMatrix<Scalar, dim, dim> DimMatrix; + typedef Dune::FieldVector<Scalar, GET_PROP_VALUE(TypeTag, NumPhases)> PhaseVector; typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; // the typenames used for the stiffness matrix and solution vector @@ -212,9 +212,9 @@ private: */ template<class TypeTag> void FVPressure2P2C<TypeTag>::getSource(Dune::FieldVector<Scalar, 2>& sourceEntry, - const Element& elementI, - const CellData& cellDataI, - const bool first) + const Element& elementI, + const CellData& cellDataI, + const bool first) { sourceEntry=0.; // cell volume & perimeter, assume linear map here @@ -259,8 +259,8 @@ void FVPressure2P2C<TypeTag>::getSource(Dune::FieldVector<Scalar, 2>& sourceEntr */ template<class TypeTag> void FVPressure2P2C<TypeTag>::getStorage(Dune::FieldVector<Scalar, 2>& storageEntry, - const Element& elementI, - const CellData& cellDataI, + const Element& elementI, + const CellData& cellDataI, const bool first) { storageEntry = 0.; @@ -366,7 +366,7 @@ void FVPressure2P2C<TypeTag>::getFlux(Dune::FieldVector<Scalar, 2>& entries, const GlobalPosition& gravity_ = problem().gravity(); // get absolute permeability - FieldMatrix permeabilityI(problem().spatialParams().intrinsicPermeability(*elementPtrI)); + DimMatrix permeabilityI(problem().spatialParams().intrinsicPermeability(*elementPtrI)); // get mobilities and fractional flow factors Scalar fractionalWI=0, fractionalNWI=0; @@ -401,11 +401,11 @@ void FVPressure2P2C<TypeTag>::getFlux(Dune::FieldVector<Scalar, 2>& entries, GlobalPosition unitDistVec(distVec); unitDistVec /= dist; - FieldMatrix permeabilityJ + DimMatrix permeabilityJ = problem().spatialParams().intrinsicPermeability(*neighborPtr); // compute vectorized permeabilities - FieldMatrix meanPermeability(0); + DimMatrix meanPermeability(0); Dumux::harmonicMeanMatrix(meanPermeability, permeabilityI, permeabilityJ); Dune::FieldVector<Scalar, dim> permeability(0); @@ -479,47 +479,102 @@ void FVPressure2P2C<TypeTag>::getFlux(Dune::FieldVector<Scalar, 2>& entries, //do the upwinding of the mobility depending on the phase potentials - if (potentialW >= 0.) + const CellData* upwindWCellData(0); + const CellData* upwindNCellData(0); + if (potentialW > 0.) + upwindWCellData = &cellDataI; + else if (potentialW < 0.) + upwindWCellData = &cellDataJ; + else { - dV_w = (dv_dC1 * cellDataI.massFraction(wPhaseIdx, wCompIdx) - + dv_dC2 * cellDataI.massFraction(wPhaseIdx, nCompIdx)); - lambdaW = cellDataI.mobility(wPhaseIdx); - gV_w = (graddv_dC1 * cellDataI.massFraction(wPhaseIdx, wCompIdx) - + graddv_dC2 * cellDataI.massFraction(wPhaseIdx, nCompIdx)); - dV_w *= cellDataI.density(wPhaseIdx); - gV_w *= cellDataI.density(wPhaseIdx); + if(cellDataI.isUpwindCell(intersection.indexInInside(), contiWEqIdx)) + upwindWCellData = &cellDataI; + else if(cellDataJ.isUpwindCell(intersection.indexInOutside(), contiWEqIdx)) + upwindWCellData = &cellDataJ; + //else + // upwinding is not done! } + + if (potentialNW > 0.) + upwindNCellData = &cellDataI; + else if (potentialNW < 0.) + upwindNCellData = &cellDataJ; else { - dV_w = (dv_dC1 * cellDataJ.massFraction(wPhaseIdx, wCompIdx) + if(cellDataI.isUpwindCell(intersection.indexInInside(), contiNEqIdx)) + upwindNCellData = &cellDataI; + else if(cellDataJ.isUpwindCell(intersection.indexInOutside(), contiNEqIdx)) + upwindNCellData = &cellDataJ; + //else + // upwinding is not done! + } + + //perform upwinding if desired + if(!upwindWCellData) + { + // compute values for both cells + Scalar dV_wI = (dv_dC1 * cellDataI.massFraction(wPhaseIdx, wCompIdx) + + dv_dC2 * cellDataI.massFraction(wPhaseIdx, nCompIdx)); + Scalar gV_wI = (graddv_dC1 * cellDataI.massFraction(wPhaseIdx, wCompIdx) + + graddv_dC2 * cellDataI.massFraction(wPhaseIdx, nCompIdx)); + dV_wI *= cellDataI.density(wPhaseIdx); + gV_wI *= cellDataI.density(wPhaseIdx); + Scalar dV_wJ = (dv_dC1 * cellDataJ.massFraction(wPhaseIdx, wCompIdx) + dv_dC2 * cellDataJ.massFraction(wPhaseIdx, nCompIdx)); - lambdaW = cellDataJ.mobility(wPhaseIdx); - gV_w = (graddv_dC1 * cellDataJ.massFraction(wPhaseIdx, wCompIdx) + Scalar gV_wJ = (graddv_dC1 * cellDataJ.massFraction(wPhaseIdx, wCompIdx) + graddv_dC2 * cellDataJ.massFraction(wPhaseIdx, nCompIdx)); - dV_w *= cellDataJ.density(wPhaseIdx); - gV_w *= cellDataJ.density(wPhaseIdx); + dV_wJ *= cellDataJ.density(wPhaseIdx); + gV_wJ *= cellDataJ.density(wPhaseIdx); + + //compute means + dV_w = harmonicMean(dV_wI, dV_wJ); + gV_w = harmonicMean(gV_wI, gV_wJ); + lambdaW = harmonicMean(cellDataI.mobility(wPhaseIdx), cellDataJ.mobility(wPhaseIdx)); } - if (potentialNW >= 0.) + else + { + dV_w = (dv_dC1 * upwindWCellData->massFraction(wPhaseIdx, wCompIdx) + + dv_dC2 * upwindWCellData->massFraction(wPhaseIdx, nCompIdx)); + lambdaW = upwindWCellData->mobility(wPhaseIdx); + gV_w = (graddv_dC1 * upwindWCellData->massFraction(wPhaseIdx, wCompIdx) + + graddv_dC2 * upwindWCellData->massFraction(wPhaseIdx, nCompIdx)); + dV_w *= upwindWCellData->density(wPhaseIdx); + gV_w *= upwindWCellData->density(wPhaseIdx); + } + + if(!upwindNCellData) { - dV_n = (dv_dC1 * cellDataI.massFraction(nPhaseIdx, wCompIdx) + Scalar dV_nI = (dv_dC1 * cellDataI.massFraction(nPhaseIdx, wCompIdx) + dv_dC2 * cellDataI.massFraction(nPhaseIdx, nCompIdx)); - lambdaN = cellDataI.mobility(nPhaseIdx); - gV_n = (graddv_dC1 * cellDataI.massFraction(nPhaseIdx, wCompIdx) + Scalar gV_nI = (graddv_dC1 * cellDataI.massFraction(nPhaseIdx, wCompIdx) + graddv_dC2 * cellDataI.massFraction(nPhaseIdx, nCompIdx)); - dV_n *= cellDataI.density(nPhaseIdx); - gV_n *= cellDataI.density(nPhaseIdx); + dV_nI *= cellDataI.density(nPhaseIdx); + gV_nI *= cellDataI.density(nPhaseIdx); + Scalar dV_nJ = (dv_dC1 * cellDataJ.massFraction(nPhaseIdx, wCompIdx) + + dv_dC2 * cellDataJ.massFraction(nPhaseIdx, nCompIdx)); + Scalar gV_nJ = (graddv_dC1 * cellDataJ.massFraction(nPhaseIdx, wCompIdx) + + graddv_dC2 * cellDataJ.massFraction(nPhaseIdx, nCompIdx)); + dV_nJ *= cellDataJ.density(nPhaseIdx); + gV_nJ *= cellDataJ.density(nPhaseIdx); + + //compute means + dV_n = harmonicMean(dV_nI, dV_nJ); + gV_n = harmonicMean(gV_nI, gV_nJ); + lambdaN = harmonicMean(cellDataI.mobility(nPhaseIdx), cellDataJ.mobility(nPhaseIdx)); } else { - dV_n = (dv_dC1 * cellDataJ.massFraction(nPhaseIdx, wCompIdx) - + dv_dC2 * cellDataJ.massFraction(nPhaseIdx, nCompIdx)); - lambdaN = cellDataJ.mobility(nPhaseIdx); - gV_n = (graddv_dC1 * cellDataJ.massFraction(nPhaseIdx, wCompIdx) - + graddv_dC2 * cellDataJ.massFraction(nPhaseIdx, nCompIdx)); - dV_n *= cellDataJ.density(nPhaseIdx); - gV_n *= cellDataJ.density(nPhaseIdx); + dV_n = (dv_dC1 * upwindNCellData->massFraction(nPhaseIdx, wCompIdx) + + dv_dC2 * upwindNCellData->massFraction(nPhaseIdx, nCompIdx)); + lambdaN = upwindNCellData->mobility(nPhaseIdx); + gV_n = (graddv_dC1 * upwindNCellData->massFraction(nPhaseIdx, wCompIdx) + + graddv_dC2 * upwindNCellData->massFraction(nPhaseIdx, nCompIdx)); + dV_n *= upwindNCellData->density(nPhaseIdx); + gV_n *= upwindNCellData->density(nPhaseIdx); } + + //calculate current matrix entry entries[matrix] = faceArea * (lambdaW * dV_w + lambdaN * dV_n)* (unitOuterNormal * unitDistVec); if(enableVolumeIntegral) @@ -613,7 +668,7 @@ void FVPressure2P2C<TypeTag>::getFluxOnBoundary(Dune::FieldVector<Scalar, 2>& en if (bcType.isDirichlet(Indices::pressureEqIdx)) { // get absolute permeability - FieldMatrix permeabilityI(problem().spatialParams().intrinsicPermeability(*elementPtrI)); + DimMatrix permeabilityI(problem().spatialParams().intrinsicPermeability(*elementPtrI)); const GlobalPosition& gravity_ = problem().gravity(); //permeability vector at boundary @@ -837,7 +892,7 @@ void FVPressure2P2C<TypeTag>::updateMaterialLaws() CellData& cellData = problem().variables().cellData(globalIdx); - asImp_().updateMaterialLawsInElement(*eIt); + problem().pressureModel().updateMaterialLawsInElement(*eIt); maxError = std::max(maxError, fabs(cellData.volumeError())); } @@ -872,9 +927,9 @@ void FVPressure2P2C<TypeTag>::updateMaterialLawsInElement(const Element& element // fluidState.setMassConcentration(nCompIdx, // problem().transportModel().totalConcentration(nCompIdx,globalIdx)); // get the overall mass of component 1 Z1 = C^k / (C^1+C^2) [-] - Scalar Z1 = fluidState.massConcentration(wCompIdx) - / (fluidState.massConcentration(wCompIdx) - + fluidState.massConcentration(nCompIdx)); + Scalar Z1 = cellData.massConcentration(wCompIdx) + / (cellData.massConcentration(wCompIdx) + + cellData.massConcentration(nCompIdx)); // make shure only physical quantities enter flash calculation #if DUNE_MINIMAL_DEBUG_LEVEL <= 3 diff --git a/dumux/decoupled/2p2c/fvpressure2p2cmultiphysics.hh b/dumux/decoupled/2p2c/fvpressure2p2cmultiphysics.hh index e58691c1f7..74d80196a4 100644 --- a/dumux/decoupled/2p2c/fvpressure2p2cmultiphysics.hh +++ b/dumux/decoupled/2p2c/fvpressure2p2cmultiphysics.hh @@ -118,7 +118,7 @@ class FVPressure2P2CMultiPhysics : public FVPressure2P2C<TypeTag> // convenience shortcuts for Vectors/Matrices typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition; typedef Dune::FieldMatrix<Scalar, dim, dim> DimMatrix; - typedef Dune::FieldVector<Scalar, 2> PhaseVector; + typedef Dune::FieldVector<Scalar, GET_PROP_VALUE(TypeTag, NumPhases)> PhaseVector; typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; @@ -157,6 +157,8 @@ public: //constitutive functions are initialized and stored in the variables object void updateMaterialLaws(); + //updates singlephase secondary variables for one cell and stores in the variables object + void update1pMaterialLawsInElement(const Element&, CellData&); //! \brief Write data files /* \param name file name */ @@ -186,11 +188,9 @@ public: gravity_(problem.gravity()), timer_(false) {} -private: +protected: // subdomain map Dune::BlockVector<Dune::FieldVector<int,1> > nextSubdomain; //! vector holding next subdomain - -protected: const GlobalPosition& gravity_; //!< vector including the gravity constant static constexpr int pressureType = GET_PROP_VALUE(TypeTag, PressureFormulation); //!< gives kind of pressure used (\f$ 0 = p_w \f$, \f$ 1 = p_n \f$, \f$ 2 = p_{global} \f$) Dune::Timer timer_; @@ -662,7 +662,6 @@ template<class TypeTag> void FVPressure2P2CMultiPhysics<TypeTag>::updateMaterialLaws() { //get timestep for error term - Scalar dt = problem().timeManager().timeStepSize(); Scalar maxError = 0.; // next subdomain map @@ -671,14 +670,12 @@ void FVPressure2P2CMultiPhysics<TypeTag>::updateMaterialLaws() else nextSubdomain = -1; // reduce complexity after first TS - // iterate through leaf grid an evaluate c0 at cell center + // Loop A) through leaf grid ElementIterator eItEnd = problem().gridView().template end<0> (); for (ElementIterator eIt = problem().gridView().template begin<0> (); eIt != eItEnd; ++eIt) { - const typename ElementIterator::Entity::Geometry &geo = eIt->geometry(); - // get global coordinate of cell center - GlobalPosition globalPos = geo.center(); + GlobalPosition globalPos = eIt->geometry().center(); int globalIdx = problem().variables().index(*eIt); CellData& cellData = problem().variables().cellData(globalIdx); @@ -715,96 +712,130 @@ void FVPressure2P2CMultiPhysics<TypeTag>::updateMaterialLaws() } timer_.stop(); // end subdomain check - } - else // simple - { - timer_.start(); - // determine which phase should be present - int presentPhaseIdx = cellData.subdomain(); - // check if it is not yet assigned to next complex subdomain - if(nextSubdomain[globalIdx] !=2) - nextSubdomain[globalIdx] = presentPhaseIdx; // assign correct index - - // acess the simple fluid state and prepare for manipulation - PseudoOnePTwoCFluidState<TypeTag>& pseudoFluidState - = cellData.manipulateSimpleFluidState(); - - // prepare phase pressure for fluid state - // both phase pressures are necessary for the case 1p domain is assigned for - // the next 2p subdomain - PhaseVector pressure(0.); - Scalar pc = MaterialLaw::pC(problem().spatialParams().materialLawParams(*eIt), - ((presentPhaseIdx == wPhaseIdx) ? 1. : 0.)); // assign Sw = 1 if wPhase present, else 0 - if(pressureType == wPhaseIdx) - { - pressure[wPhaseIdx] = this->pressure(globalIdx); - pressure[nPhaseIdx] = this->pressure(globalIdx)+pc; - } - else - { - pressure[wPhaseIdx] = this->pressure(globalIdx)-pc; - pressure[nPhaseIdx] = this->pressure(globalIdx); - } - - // make shure total concentrations from solution vector are exact in fluidstate - pseudoFluidState.setMassConcentration(wCompIdx, - problem().transportModel().totalConcentration(wCompIdx,globalIdx)); - pseudoFluidState.setMassConcentration(nCompIdx, - problem().transportModel().totalConcentration(nCompIdx,globalIdx)); - - // get the overall mass of component 1: Z1 = C^k / (C^1+C^2) [-] - Scalar sumConc = pseudoFluidState.massConcentration(wCompIdx) - + pseudoFluidState.massConcentration(nCompIdx); - Scalar Z1 = pseudoFluidState.massConcentration(wCompIdx)/ sumConc; + }// end complex domain + else if (nextSubdomain[globalIdx] != 2) //check if cell remains in simple subdomain + nextSubdomain[globalIdx] = cellData.subdomain(); - pseudoFluidState.update(Z1, pressure, cellData.subdomain(), problem().temperatureAtPos(globalPos)); + } //end define complex area of next subdomain - // write stuff in fluidstate - assert(presentPhaseIdx == pseudoFluidState.presentPhaseIdx()); + timer_.start(); + // Loop B) thorugh leaf grid + // investigate cells that were "simple" in current TS + for (ElementIterator eIt = problem().gridView().template begin<0> (); eIt != eItEnd; ++eIt) + { + int globalIdx = problem().variables().index(*eIt); + CellData& cellData = problem().variables().cellData(globalIdx); - cellData.setSimpleFluidState(pseudoFluidState); + // store old subdomain information and assign new info + int oldSubdomainI = cellData.subdomain(); + cellData.subdomain() = nextSubdomain[globalIdx]; + //first check if simple will become complicated + if(oldSubdomainI != 2 + && nextSubdomain[globalIdx] == 2) + { + // assure correct PV if subdomain used to be simple + if(cellData.fluidStateType() != 0); // i.e. it was simple timer_.stop(); - // initialize viscosities - cellData.setViscosity(presentPhaseIdx, FluidSystem::viscosity(pseudoFluidState, presentPhaseIdx)); - - // initialize mobilities - if(presentPhaseIdx == wPhaseIdx) - cellData.setMobility(wPhaseIdx, - MaterialLaw::krw(problem().spatialParams().materialLawParams(*eIt), pseudoFluidState.saturation(wPhaseIdx)) - / cellData.viscosity(wPhaseIdx)); - else - cellData.setMobility(nPhaseIdx, - MaterialLaw::krn(problem().spatialParams().materialLawParams(*eIt), pseudoFluidState.saturation(wPhaseIdx)) - / cellData.viscosity(nPhaseIdx)); - - // error term handling - Scalar vol(0.); - vol = sumConc / pseudoFluidState.density(presentPhaseIdx); - - if (dt != 0) - cellData.volumeError() = (vol - problem().spatialParams().porosity(*eIt)); - + this->updateMaterialLawsInElement(*eIt); + timer_.start(); + } + else if(oldSubdomainI != 2 + && nextSubdomain[globalIdx] != 2) // will be simple and was simple + { + // get global coordinate of cell center + GlobalPosition globalPos = eIt->geometry().center(); +// // determine which phase should be present +// int presentPhaseIdx = cellData.subdomain(); // this is already =nextSubomainIdx + // perform simple update + this->update1pMaterialLawsInElement(*eIt, cellData); + timer_.stop(); } + //else + // a) will remain complex -> everything already done in loop A + // b) will be simple and was complex: complex FS available, so next TS + // will use comlex FS, next update will transform to simple + maxError = std::max(maxError, fabs(cellData.volumeError())); }// end grid traversal this->maxError_ = maxError/problem().timeManager().timeStepSize(); - // update subdomain information - timer_.start(); - // iterate through leaf grid an copy subdomain information - if(problem().timeManager().time() != 0.) - { - for (unsigned int i= 0; i < nextSubdomain.size(); i++) - { - problem().variables().cellData(i).subdomain() = nextSubdomain[i]; - } - } + timer_.stop(); Dune::dinfo << "Subdomain routines took " << timer_.elapsed() << " seconds" << std::endl; return; } +template<class TypeTag> +void FVPressure2P2CMultiPhysics<TypeTag>::update1pMaterialLawsInElement(const Element& elementI, CellData& cellData) +{ + // get global coordinate of cell center + GlobalPosition globalPos = elementI.geometry().center(); + int globalIdx = problem().variables().index(elementI); + + // determine which phase should be present + int presentPhaseIdx = cellData.subdomain(); // this is already =nextSubomainIdx + + // acess the simple fluid state and prepare for manipulation + PseudoOnePTwoCFluidState<TypeTag>& pseudoFluidState + = cellData.manipulateSimpleFluidState(); + + // prepare phase pressure for fluid state + // both phase pressures are necessary for the case 1p domain is assigned for + // the next 2p subdomain + PhaseVector pressure(0.); + Scalar pc = MaterialLaw::pC(problem().spatialParams().materialLawParams(elementI), + ((presentPhaseIdx == wPhaseIdx) ? 1. : 0.)); // assign Sw = 1 if wPhase present, else 0 + if(pressureType == wPhaseIdx) + { + pressure[wPhaseIdx] = this->pressure(globalIdx); + pressure[nPhaseIdx] = this->pressure(globalIdx)+pc; + } + else + { + pressure[wPhaseIdx] = this->pressure(globalIdx)-pc; + pressure[nPhaseIdx] = this->pressure(globalIdx); + } + +// // make shure total concentrations from solution vector are exact in fluidstate +// pseudoFluidState.setMassConcentration(wCompIdx, +// problem().transportModel().totalConcentration(wCompIdx,globalIdx)); +// pseudoFluidState.setMassConcentration(nCompIdx, +// problem().transportModel().totalConcentration(nCompIdx,globalIdx)); + + // get the overall mass of component 1: Z1 = C^k / (C^1+C^2) [-] + Scalar sumConc = cellData.massConcentration(wCompIdx) + + cellData.massConcentration(nCompIdx); + Scalar Z1 = cellData.massConcentration(wCompIdx)/ sumConc; + + pseudoFluidState.update(Z1, pressure, presentPhaseIdx, problem().temperatureAtPos(globalPos)); + + // write stuff in fluidstate + assert(presentPhaseIdx == pseudoFluidState.presentPhaseIdx()); + + cellData.setSimpleFluidState(pseudoFluidState); + + // initialize viscosities + cellData.setViscosity(presentPhaseIdx, FluidSystem::viscosity(pseudoFluidState, presentPhaseIdx)); + + // initialize mobilities + if(presentPhaseIdx == wPhaseIdx) + cellData.setMobility(wPhaseIdx, + MaterialLaw::krw(problem().spatialParams().materialLawParams(elementI), pseudoFluidState.saturation(wPhaseIdx)) + / cellData.viscosity(wPhaseIdx)); + else + cellData.setMobility(nPhaseIdx, + MaterialLaw::krn(problem().spatialParams().materialLawParams(elementI), pseudoFluidState.saturation(wPhaseIdx)) + / cellData.viscosity(nPhaseIdx)); + + // error term handling + Scalar vol(0.); + vol = sumConc / pseudoFluidState.density(presentPhaseIdx); + + if (problem().timeManager().timeStepSize() != 0) + cellData.volumeError() = (vol - problem().spatialParams().porosity(elementI)); + return; +} }//end namespace Dumux #endif diff --git a/dumux/decoupled/2p2c/fvpressurecompositional.hh b/dumux/decoupled/2p2c/fvpressurecompositional.hh index c951b0ca7f..b1bd9a5f20 100644 --- a/dumux/decoupled/2p2c/fvpressurecompositional.hh +++ b/dumux/decoupled/2p2c/fvpressurecompositional.hh @@ -163,20 +163,25 @@ public: ScalarSolutionType *pressureN = writer.allocateManagedBuffer(size); ScalarSolutionType *pC = writer.allocateManagedBuffer(size); ScalarSolutionType *saturationW = writer.allocateManagedBuffer(size); - ScalarSolutionType *densityWetting = writer.allocateManagedBuffer(size); ScalarSolutionType *densityNonwetting = writer.allocateManagedBuffer(size); - ScalarSolutionType *viscosityWetting = writer.allocateManagedBuffer(size); - ScalarSolutionType *viscosityNonwetting = writer.allocateManagedBuffer(size); ScalarSolutionType *mobilityW = writer.allocateManagedBuffer (size); ScalarSolutionType *mobilityNW = writer.allocateManagedBuffer (size); - ScalarSolutionType *massfraction1W = writer.allocateManagedBuffer (size); ScalarSolutionType *massfraction1NW = writer.allocateManagedBuffer (size); - // numerical stuff ScalarSolutionType *volErr = writer.allocateManagedBuffer (size); + #if DUNE_MINIMAL_DEBUG_LEVEL <= 3 + // add debug stuff + ScalarSolutionType *errorCorrPtr = writer.allocateManagedBuffer (size); + ScalarSolutionType *dv_dpPtr = writer.allocateManagedBuffer (size); + ScalarSolutionType *dV_dC1Ptr = writer.allocateManagedBuffer (size); + ScalarSolutionType *dV_dC2Ptr = writer.allocateManagedBuffer (size); + ScalarSolutionType *updEstimate1 = writer.allocateManagedBuffer (size); + ScalarSolutionType *updEstimate2 = writer.allocateManagedBuffer (size); + #endif + for (int i = 0; i < size; i++) { CellData& cellData = problem_.variables().cellData(i); @@ -186,24 +191,27 @@ public: (*saturationW)[i] = cellData.saturation(wPhaseIdx); (*densityWetting)[i] = cellData.density(wPhaseIdx); (*densityNonwetting)[i] = cellData.density(nPhaseIdx); - (*viscosityWetting)[i] = cellData.viscosity(wPhaseIdx); - (*viscosityNonwetting)[i] = cellData.viscosity(nPhaseIdx); (*mobilityW)[i] = cellData.mobility(wPhaseIdx); (*mobilityNW)[i] = cellData.mobility(nPhaseIdx); (*massfraction1W)[i] = cellData.massFraction(wPhaseIdx,wCompIdx); (*massfraction1NW)[i] = cellData.massFraction(nPhaseIdx,wCompIdx); - (*volErr)[i] = cellData.volumeError(); + + #if DUNE_MINIMAL_DEBUG_LEVEL <= 3 + (*errorCorrPtr)[i] = cellData.errorCorrection(); + (*dv_dpPtr)[i] = cellData.dv_dp(); + (*dV_dC1Ptr)[i] = cellData.dv(wCompIdx); + (*dV_dC2Ptr)[i] = cellData.dv(nCompIdx); + (*updEstimate1)[i] = updateEstimate_[0][i]; + (*updEstimate2)[i] = updateEstimate_[1][i]; + #endif } writer.attachCellData(*pressureW, "wetting pressure"); writer.attachCellData(*pressureN, "nonwetting pressure"); writer.attachCellData(*pC, "capillary pressure"); writer.attachCellData(*saturationW, "wetting saturation"); - writer.attachCellData(*densityWetting, "wetting density"); writer.attachCellData(*densityNonwetting, "nonwetting density"); - writer.attachCellData(*viscosityWetting, "wetting viscosity"); - writer.attachCellData(*viscosityNonwetting, "nonwetting viscosity"); writer.attachCellData(*mobilityW, "mobility w_phase"); writer.attachCellData(*mobilityNW, "mobility nw_phase"); std::ostringstream oss1, oss2; @@ -212,44 +220,35 @@ public: oss2 << "mass fraction " << FluidSystem::componentName(0) << " in " << FluidSystem::phaseName(1) << "-phase"; writer.attachCellData(*massfraction1NW, oss2.str()); writer.attachCellData(*volErr, "volume Error"); + #if DUNE_MINIMAL_DEBUG_LEVEL <= 3 + writer.attachCellData(*errorCorrPtr, "Error Correction"); + writer.attachCellData(*dv_dpPtr, "dv_dp"); + writer.attachCellData(*dV_dC1Ptr, "dV_dC1"); + writer.attachCellData(*dV_dC2Ptr, "dV_dC2"); + writer.attachCellData(*updEstimate1, "updEstimate comp 1"); + writer.attachCellData(*updEstimate2, "updEstimate comp 2"); + #endif #if DUNE_MINIMAL_DEBUG_LEVEL <= 2 ScalarSolutionType *pressurePV = writer.allocateManagedBuffer(size); ScalarSolutionType *totalConcentration1 = writer.allocateManagedBuffer (size); ScalarSolutionType *totalConcentration2 = writer.allocateManagedBuffer (size); - - // add debug stuff - ScalarSolutionType *errorCorrPtr = writer.allocateManagedBuffer (size); - ScalarSolutionType *dv_dpPtr = writer.allocateManagedBuffer (size); - ScalarSolutionType *dV_dC1Ptr = writer.allocateManagedBuffer (size); - ScalarSolutionType *dV_dC2Ptr = writer.allocateManagedBuffer (size); - ScalarSolutionType *updEstimate1 = writer.allocateManagedBuffer (size); - ScalarSolutionType *updEstimate2 = writer.allocateManagedBuffer (size); - + ScalarSolutionType *viscosityWetting = writer.allocateManagedBuffer(size); + ScalarSolutionType *viscosityNonwetting = writer.allocateManagedBuffer(size); for (int i = 0; i < size; i++) { CellData& cellData = problem_.variables().cellData(i); (*totalConcentration1)[i] = cellData.massConcentration(wCompIdx); (*totalConcentration2)[i] = cellData.massConcentration(nCompIdx); - - (*errorCorrPtr)[i] = cellData.errorCorrection(); - (*dv_dpPtr)[i] = cellData.dv_dp(); - (*dV_dC1Ptr)[i] = cellData.dv(wCompIdx); - (*dV_dC2Ptr)[i] = cellData.dv(nCompIdx); - (*updEstimate1)[i] = updateEstimate_[0][i]; - (*updEstimate2)[i] = updateEstimate_[1][i]; + (*viscosityWetting)[i] = cellData.viscosity(wPhaseIdx); + (*viscosityNonwetting)[i] = cellData.viscosity(nPhaseIdx); } *pressurePV = this->pressure(); writer.attachCellData(*pressurePV, "pressure (Primary Variable"); writer.attachCellData(*totalConcentration1, "C^w from cellData"); writer.attachCellData(*totalConcentration2, "C^n from cellData"); - - writer.attachCellData(*errorCorrPtr, "Error Correction"); - writer.attachCellData(*dv_dpPtr, "dv_dp"); - writer.attachCellData(*dV_dC1Ptr, "dV_dC1"); - writer.attachCellData(*dV_dC2Ptr, "dV_dC2"); - writer.attachCellData(*updEstimate1, "updEstimate comp 1"); - writer.attachCellData(*updEstimate2, "updEstimate comp 2"); + writer.attachCellData(*viscosityWetting, "wetting viscosity"); + writer.attachCellData(*viscosityNonwetting, "nonwetting viscosity"); #endif return; } @@ -323,13 +322,13 @@ protected: Scalar ErrorTermUpperBound_; //!< Handling of error term: upper bound for error dampening static constexpr int pressureType = GET_PROP_VALUE(TypeTag, PressureFormulation); //!< gives kind of pressure used (\f$ 0 = p_w \f$, \f$ 1 = p_n \f$, \f$ 2 = p_{global} \f$) private: - //! Returns the implementation of the problem (i.e. static polymorphism) - Implementation &asImp_() - { return *static_cast<Implementation *>(this);} - - //! \copydoc Dumux::IMPETProblem::asImp_() - const Implementation &asImp_() const - { return *static_cast<const Implementation *>(this);} +// //! Returns the implementation of the problem (i.e. static polymorphism) +// Implementation &asImp_() +// { return *static_cast<Implementation *>(this);} +// +// //! \copydoc Dumux::IMPETProblem::asImp_() +// const Implementation &asImp_() const +// { return *static_cast<const Implementation *>(this);} }; @@ -568,13 +567,12 @@ void FVPressureCompositional<TypeTag>::initialMaterialLaws(bool compositional) = this->pressure()[globalIdx]; fluidState.update(Z1_0, pressure, problem_.spatialParams().porosity(*eIt), temperature_); } - - fluidState.calculateMassConcentration(problem_.spatialParams().porosity(*eIt)); - } //end conc initial condition + cellData.calculateMassConcentration(problem_.spatialParams().porosity(*eIt)); + } //end compositional - problem_.transportModel().totalConcentration(wCompIdx,globalIdx) = fluidState.massConcentration(wCompIdx); - problem_.transportModel().totalConcentration(nCompIdx,globalIdx) = fluidState.massConcentration(nCompIdx); + problem_.transportModel().totalConcentration(wCompIdx,globalIdx) = cellData.massConcentration(wCompIdx); + problem_.transportModel().totalConcentration(nCompIdx,globalIdx) = cellData.massConcentration(nCompIdx); // initialize phase properties not stored in fluidstate cellData.setViscosity(wPhaseIdx, FluidSystem::viscosity(fluidState, wPhaseIdx)); @@ -728,7 +726,7 @@ void FVPressureCompositional<TypeTag>::volumeDerivatives(const GlobalPosition& g DUNE_THROW(Dune::MathError, "NAN/inf of dV_dm. If that happens in first timestep, try smaller firstDt!"); } } - cellData.confirmVolumeDerivatives(); + cellData.volumeDerivativesAvailable(true); } }//end namespace Dumux diff --git a/dumux/decoupled/2p2c/fvtransport2p2c.hh b/dumux/decoupled/2p2c/fvtransport2p2c.hh index 81ed17369e..9280795e03 100644 --- a/dumux/decoupled/2p2c/fvtransport2p2c.hh +++ b/dumux/decoupled/2p2c/fvtransport2p2c.hh @@ -98,7 +98,7 @@ class FVTransport2P2C typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition; typedef Dune::FieldMatrix<Scalar,dim,dim> DimMatrix; - typedef Dune::FieldVector<Scalar, 2> PhaseVector; + typedef Dune::FieldVector<Scalar, GET_PROP_VALUE(TypeTag, NumPhases)> PhaseVector; typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; //! Acess function for the current problem @@ -321,7 +321,7 @@ void FVTransport2P2C<TypeTag>::updateTransportedQuantity(TransportSolutionType& for(int compIdx = 0; compIdx < GET_PROP_VALUE(TypeTag, NumComponents); compIdx++) { totalConcentration_[compIdx][i] += (updateVector[compIdx][i]*=dt); - cellDataI.setTotalConcentration(compIdx, totalConcentration_[compIdx][i]); + cellDataI.setMassConcentration(compIdx, totalConcentration_[compIdx][i]); } } } @@ -329,7 +329,7 @@ void FVTransport2P2C<TypeTag>::updateTransportedQuantity(TransportSolutionType& //! Get flux at an interface between two cells /** The flux thorugh \f$ \gamma{ij} \f$ is calculated according to the underlying pressure field, * calculated by the pressure model. - * \f[ - A_{\gamma_{ij}} \cdot \mathbf{K} \cdot \mathbf{u} \cdot (\mathbf{n}_{\gamma_{ij}} \cdot \mathbf{u}) + * \f[ - A_{\gamma_{ij}} \cdot \mathbf{u} \cdot (\mathbf{n}_{\gamma_{ij}} \cdot \mathbf{u})\cdot \mathbf{K} \sum_{\alpha} \varrho_{\alpha} \lambda_{\alpha} \sum_{\kappa} X^{\kappa}_{\alpha} \left( \frac{p_{\alpha,j}^t - p^{t}_{\alpha,i}}{\Delta x} + \varrho_{\alpha} \mathbf{g}\right) \f] * Here, \f$ \mathbf{u} \f$ is the normalized vector connecting the cell centers, and \f$ \mathbf{n}_{\gamma_{ij}} \f$ @@ -384,7 +384,7 @@ void FVTransport2P2C<TypeTag>::getFlux(Dune::FieldVector<Scalar, 2>& fluxEntries Dune::FieldVector<Scalar, 2> factor (0.); Dune::FieldVector<Scalar, 2> updFactor (0.); - Scalar potentialW(0.), potentialNW(0.); + PhaseVector potential(0.); // access neighbor ElementPointer neighborPtr = intersection.outside(); @@ -427,132 +427,151 @@ void FVTransport2P2C<TypeTag>::getFlux(Dune::FieldVector<Scalar, 2>& fluxEntries { case pw: { - potentialW = (K * unitOuterNormal) * (pressI - pressJ) / (dist); - potentialNW = (K * unitOuterNormal) * (pressI - pressJ + pcI - pcJ) / (dist); + potential[wPhaseIdx] = (K * unitOuterNormal) * (pressI - pressJ) / (dist); + potential[nPhaseIdx] = (K * unitOuterNormal) * (pressI - pressJ + pcI - pcJ) / (dist); break; } case pn: { - potentialW = (K * unitOuterNormal) * (pressI - pressJ - pcI + pcJ) / (dist); - potentialNW = (K * unitOuterNormal) * (pressI - pressJ) / (dist); + potential[wPhaseIdx] = (K * unitOuterNormal) * (pressI - pressJ - pcI + pcJ) / (dist); + potential[nPhaseIdx] = (K * unitOuterNormal) * (pressI - pressJ) / (dist); break; } } // add gravity term - potentialNW += (K * gravity_) * (unitOuterNormal * unitDistVec) * densityNW_mean; - potentialW += (K * gravity_) * (unitOuterNormal * unitDistVec) * densityW_mean; + potential[nPhaseIdx] += (K * gravity_) * (unitOuterNormal * unitDistVec) * densityNW_mean; + potential[wPhaseIdx] += (K * gravity_) * (unitOuterNormal * unitDistVec) * densityW_mean; - // upwind mobility - double lambdaW(0.), lambdaNW(0.); + // determine upwinding direction, perform upwinding if possible + Dune::FieldVector<bool, GET_PROP_VALUE(TypeTag, NumPhases)> doUpwinding(true); + PhaseVector lambda(0.); if(!impet_ or !restrictFluxInTransport_) // perform a simple uwpind scheme { - if (potentialW >= 0.) + if (potential[wPhaseIdx] > 0.) { - lambdaW = cellDataI.mobility(wPhaseIdx); + lambda[wPhaseIdx] = cellDataI.mobility(wPhaseIdx); cellDataI.setUpwindCell(intersection.indexInInside(), contiWEqIdx, true); } + else if(potential[wPhaseIdx] < 0.) + { + lambda[wPhaseIdx] = cellDataJ.mobility(wPhaseIdx); + cellDataI.setUpwindCell(intersection.indexInInside(), contiWEqIdx, false); + } else { - lambdaW = cellDataJ.mobility(wPhaseIdx); + doUpwinding[wPhaseIdx] = false; cellDataI.setUpwindCell(intersection.indexInInside(), contiWEqIdx, false); + cellDataJ.setUpwindCell(intersection.indexInOutside(), contiWEqIdx, false); } - if (potentialNW >= 0.) + if (potential[nPhaseIdx] > 0.) { - lambdaNW = cellDataI.mobility(nPhaseIdx); + lambda[nPhaseIdx] = cellDataI.mobility(nPhaseIdx); cellDataI.setUpwindCell(intersection.indexInInside(), contiNEqIdx, true); } + else if (potential[nPhaseIdx] < 0.) + { + lambda[nPhaseIdx] = cellDataJ.mobility(nPhaseIdx); + cellDataI.setUpwindCell(intersection.indexInInside(), contiNEqIdx, false); + } else { - lambdaNW = cellDataJ.mobility(nPhaseIdx); + doUpwinding[nPhaseIdx] = false; cellDataI.setUpwindCell(intersection.indexInInside(), contiNEqIdx, false); + cellDataJ.setUpwindCell(intersection.indexInOutside(), contiNEqIdx, false); } } else // if new potentials indicate same flow direction as in P.E., perform upwind { - if (potentialW >= 0. && cellDataI.isUpwindCell(intersection.indexInInside(), contiWEqIdx)) - lambdaW = cellDataI.mobility(wPhaseIdx); - else if (potentialW < 0. && !cellDataI.isUpwindCell(intersection.indexInInside(), contiWEqIdx)) - lambdaW = cellDataJ.mobility(wPhaseIdx); + if (potential[wPhaseIdx] >= 0. && cellDataI.isUpwindCell(intersection.indexInInside(), contiWEqIdx)) + lambda[wPhaseIdx] = cellDataI.mobility(wPhaseIdx); + else if (potential[wPhaseIdx] < 0. && !cellDataI.isUpwindCell(intersection.indexInInside(), contiWEqIdx)) + lambda[wPhaseIdx] = cellDataJ.mobility(wPhaseIdx); else // potential of w-phase does not coincide with that of P.E. { bool isUpwindCell = cellDataI.isUpwindCell(intersection.indexInInside(), contiWEqIdx); //check if harmonic weithing is necessary if (!isUpwindCell && !(cellDataI.mobility(wPhaseIdx) != 0. && cellDataJ.mobility(wPhaseIdx) == 0.)) // check if outflow induce neglected phase flux - lambdaW = cellDataI.mobility(wPhaseIdx); + lambda[wPhaseIdx] = cellDataI.mobility(wPhaseIdx); else if (isUpwindCell && !(cellDataJ.mobility(wPhaseIdx) != 0. && cellDataI.mobility(wPhaseIdx) == 0.)) // check if inflow induce neglected phase flux - lambdaW = cellDataJ.mobility(wPhaseIdx); + lambda[wPhaseIdx] = cellDataJ.mobility(wPhaseIdx); else - { - //a) perform harmonic averageing - fluxEntries[wCompIdx] -= potentialW * faceArea / volume - * harmonicMean(cellDataI.massFraction(wPhaseIdx, wCompIdx) * cellDataI.mobility(wPhaseIdx) * cellDataI.density(wPhaseIdx), - cellDataJ.massFraction(wPhaseIdx, wCompIdx) * cellDataJ.mobility(wPhaseIdx) * cellDataJ.density(wPhaseIdx)); - fluxEntries[nCompIdx] -= potentialW * faceArea / volume - * harmonicMean(cellDataI.massFraction(wPhaseIdx, nCompIdx) * cellDataI.mobility(wPhaseIdx) * cellDataI.density(wPhaseIdx), - cellDataJ.massFraction(wPhaseIdx, nCompIdx) * cellDataJ.mobility(wPhaseIdx) * cellDataJ.density(wPhaseIdx)); - // b) timestep control - // for timestep control : influx - timestepFlux[0] += std::max(0., - - potentialW * faceArea / volume * harmonicMean(cellDataI.density(wPhaseIdx),cellDataJ.density(wPhaseIdx))); - // outflux - timestepFlux[1] += std::max(0., - potentialW * faceArea / volume * harmonicMean(cellDataI.density(wPhaseIdx),cellDataJ.density(wPhaseIdx))); - - //c) stop further standard calculations - potentialW = 0; - - //d) output (only for one side) - if(potentialW >= 0.) - Dune::dinfo << "harmonicMean flux of phase w used from cell" << globalIdxI<< " into " << globalIdxJ <<"\n"; - } + doUpwinding[wPhaseIdx] = false; } - if (potentialNW >= 0. && cellDataI.isUpwindCell(intersection.indexInInside(), contiNEqIdx)) - lambdaNW = cellDataI.mobility(nPhaseIdx); - else if (potentialNW < 0. && !cellDataI.isUpwindCell(intersection.indexInInside(), contiNEqIdx)) - lambdaNW = cellDataJ.mobility(nPhaseIdx); + if (potential[nPhaseIdx] >= 0. && cellDataI.isUpwindCell(intersection.indexInInside(), contiNEqIdx)) + lambda[nPhaseIdx] = cellDataI.mobility(nPhaseIdx); + else if (potential[nPhaseIdx] < 0. && !cellDataI.isUpwindCell(intersection.indexInInside(), contiNEqIdx)) + lambda[nPhaseIdx] = cellDataJ.mobility(nPhaseIdx); else // potential of n-phase does not coincide with that of P.E. { bool isUpwindCell = cellDataI.isUpwindCell(intersection.indexInInside(), contiNEqIdx); //check if harmonic weithing is necessary if (!isUpwindCell && !(cellDataI.mobility(nPhaseIdx) != 0. && cellDataJ.mobility(nPhaseIdx) == 0.)) // check if outflow induce neglected phase flux - lambdaNW = cellDataI.mobility(nPhaseIdx); + lambda[nPhaseIdx] = cellDataI.mobility(nPhaseIdx); else if (isUpwindCell && !(cellDataJ.mobility(nPhaseIdx) != 0. && cellDataI.mobility(nPhaseIdx) == 0.)) // check if inflow induce neglected phase flux - lambdaNW = cellDataJ.mobility(nPhaseIdx); + lambda[nPhaseIdx] = cellDataJ.mobility(nPhaseIdx); else - { - //a) perform harmonic averageing - fluxEntries[wCompIdx] -= potentialNW * faceArea / volume - * harmonicMean(cellDataI.massFraction(nPhaseIdx, wCompIdx) * cellDataI.mobility(nPhaseIdx) * cellDataI.density(nPhaseIdx), - cellDataJ.massFraction(nPhaseIdx, wCompIdx) * cellDataJ.mobility(nPhaseIdx) * cellDataJ.density(nPhaseIdx)); - fluxEntries[nCompIdx] -= potentialNW * faceArea / volume - * harmonicMean(cellDataI.massFraction(nPhaseIdx, nCompIdx) * cellDataI.mobility(nPhaseIdx) * cellDataI.density(nPhaseIdx), - cellDataJ.massFraction(nPhaseIdx, nCompIdx) * cellDataJ.mobility(nPhaseIdx) * cellDataJ.density(nPhaseIdx)); - // b) timestep control - // for timestep control : influx - timestepFlux[0] += std::max(0., - - potentialNW * faceArea / volume * harmonicMean(cellDataI.density(nPhaseIdx),cellDataJ.density(nPhaseIdx))); - // outflux - timestepFlux[1] += std::max(0., - potentialNW * faceArea / volume * harmonicMean(cellDataI.density(nPhaseIdx),cellDataJ.density(nPhaseIdx))); - - //c) stop further standard calculations - potentialNW = 0; - - //d) output (only for one side) - if(potentialNW >= 0.) - Dune::dinfo << "harmonicMean flux of phase n used from cell" << globalIdxI<< " into " << globalIdxJ <<"\n"; - } + doUpwinding[nPhaseIdx] = false; } } + // do not perform upwinding if so desired + if(!doUpwinding[wPhaseIdx]) + { + //a) perform harmonic averageing + fluxEntries[wCompIdx] -= potential[wPhaseIdx] * faceArea / volume + * harmonicMean(cellDataI.massFraction(wPhaseIdx, wCompIdx) * cellDataI.mobility(wPhaseIdx) * cellDataI.density(wPhaseIdx), + cellDataJ.massFraction(wPhaseIdx, wCompIdx) * cellDataJ.mobility(wPhaseIdx) * cellDataJ.density(wPhaseIdx)); + fluxEntries[nCompIdx] -= potential[wPhaseIdx] * faceArea / volume + * harmonicMean(cellDataI.massFraction(wPhaseIdx, nCompIdx) * cellDataI.mobility(wPhaseIdx) * cellDataI.density(wPhaseIdx), + cellDataJ.massFraction(wPhaseIdx, nCompIdx) * cellDataJ.mobility(wPhaseIdx) * cellDataJ.density(wPhaseIdx)); + // b) timestep control + // for timestep control : influx + timestepFlux[0] += std::max(0., + - potential[wPhaseIdx] * faceArea / volume * harmonicMean(cellDataI.density(wPhaseIdx),cellDataJ.density(wPhaseIdx))); + // outflux + timestepFlux[1] += std::max(0., + potential[wPhaseIdx] * faceArea / volume * harmonicMean(cellDataI.density(wPhaseIdx),cellDataJ.density(wPhaseIdx))); + + //c) stop further standard calculations + potential[wPhaseIdx] = 0; + + //d) output (only for one side) + if(potential[wPhaseIdx] >= 0.) + Dune::dinfo << "harmonicMean flux of phase w used from cell" << globalIdxI<< " into " << globalIdxJ <<"\n"; + } + if(!doUpwinding[nPhaseIdx]) + { + //a) perform harmonic averageing + fluxEntries[wCompIdx] -= potential[nPhaseIdx] * faceArea / volume + * harmonicMean(cellDataI.massFraction(nPhaseIdx, wCompIdx) * cellDataI.mobility(nPhaseIdx) * cellDataI.density(nPhaseIdx), + cellDataJ.massFraction(nPhaseIdx, wCompIdx) * cellDataJ.mobility(nPhaseIdx) * cellDataJ.density(nPhaseIdx)); + fluxEntries[nCompIdx] -= potential[nPhaseIdx] * faceArea / volume + * harmonicMean(cellDataI.massFraction(nPhaseIdx, nCompIdx) * cellDataI.mobility(nPhaseIdx) * cellDataI.density(nPhaseIdx), + cellDataJ.massFraction(nPhaseIdx, nCompIdx) * cellDataJ.mobility(nPhaseIdx) * cellDataJ.density(nPhaseIdx)); + // b) timestep control + // for timestep control : influx + timestepFlux[0] += std::max(0., + - potential[nPhaseIdx] * faceArea / volume * harmonicMean(cellDataI.density(nPhaseIdx),cellDataJ.density(nPhaseIdx))); + // outflux + timestepFlux[1] += std::max(0., + potential[nPhaseIdx] * faceArea / volume * harmonicMean(cellDataI.density(nPhaseIdx),cellDataJ.density(nPhaseIdx))); + + //c) stop further standard calculations + potential[nPhaseIdx] = 0; + + //d) output (only for one side) + if(potential[nPhaseIdx] >= 0.) + Dune::dinfo << "harmonicMean flux of phase n used from cell" << globalIdxI<< " into " << globalIdxJ <<"\n"; + } + // calculate and standardized velocity - double velocityJIw = std::max((-lambdaW * potentialW) * faceArea / volume, 0.0); - double velocityIJw = std::max(( lambdaW * potentialW) * faceArea / volume, 0.0); - double velocityJIn = std::max((-lambdaNW * potentialNW) * faceArea / volume, 0.0); - double velocityIJn = std::max(( lambdaNW * potentialNW) * faceArea / volume, 0.0); + double velocityJIw = std::max((-lambda[wPhaseIdx] * potential[wPhaseIdx]) * faceArea / volume, 0.0); + double velocityIJw = std::max(( lambda[wPhaseIdx] * potential[wPhaseIdx]) * faceArea / volume, 0.0); + double velocityJIn = std::max((-lambda[nPhaseIdx] * potential[nPhaseIdx]) * faceArea / volume, 0.0); + double velocityIJn = std::max(( lambda[nPhaseIdx] * potential[nPhaseIdx]) * faceArea / volume, 0.0); // for timestep control : influx timestepFlux[0] += velocityJIw + velocityJIn; @@ -579,7 +598,7 @@ void FVTransport2P2C<TypeTag>::getFlux(Dune::FieldVector<Scalar, 2>& fluxEntries //! Get flux on Boundary /** The flux thorugh \f$ \gamma{ij} \f$ is calculated according to the underlying pressure field, * calculated by the pressure model. - * \f[ - A_{\gamma_{ij}} \cdot \mathbf{K} \cdot \mathbf{u} \cdot (\mathbf{n}_{\gamma_{ij}} \cdot \mathbf{u}) + * \f[ - A_{\gamma_{ij}} \cdot \mathbf{u} \cdot (\mathbf{n}_{\gamma_{ij}} \cdot \mathbf{u})\cdot \mathbf{K} \sum_{\alpha} \varrho_{\alpha} \lambda_{\alpha} \sum_{\kappa} X^{\kappa}_{\alpha} \left( \frac{p_{\alpha,j}^t - p^{t}_{\alpha,i}}{\Delta x} + \varrho_{\alpha} \mathbf{g}\right) \f] * Here, \f$ \mathbf{u} \f$ is the normalized vector connecting the cell centers, and \f$ \mathbf{n}_{\gamma_{ij}} \f$ @@ -631,7 +650,7 @@ void FVTransport2P2C<TypeTag>::getFluxOnBoundary(Dune::FieldVector<Scalar, 2>& f Dune::FieldVector<Scalar, 2> factor (0.); Dune::FieldVector<Scalar, 2> updFactor (0.); - Scalar potentialW(0.), potentialNW(0.); + PhaseVector potential(0.); // center of face in global coordinates const GlobalPosition& globalPosFace = intersection.geometry().center(); @@ -683,55 +702,55 @@ void FVTransport2P2C<TypeTag>::getFluxOnBoundary(Dune::FieldVector<Scalar, 2>& f { case pw: { - potentialW = (K * unitOuterNormal) * + potential[wPhaseIdx] = (K * unitOuterNormal) * (pressI - pressBound[wPhaseIdx]) / dist; - potentialNW = (K * unitOuterNormal) * + potential[nPhaseIdx] = (K * unitOuterNormal) * (pressI + pcI - pressBound[wPhaseIdx] - pcBound) / dist; break; } case pn: { - potentialW = (K * unitOuterNormal) * + potential[wPhaseIdx] = (K * unitOuterNormal) * (pressI - pcI - pressBound[nPhaseIdx] + pcBound) / dist; - potentialNW = (K * unitOuterNormal) * + potential[nPhaseIdx] = (K * unitOuterNormal) * (pressI - pressBound[nPhaseIdx]) / dist; break; } } - potentialW += (K * gravity_) * (unitOuterNormal * unitDistVec) * densityW_mean;; - potentialNW += (K * gravity_) * (unitOuterNormal * unitDistVec) * densityNW_mean;; + potential[wPhaseIdx] += (K * gravity_) * (unitOuterNormal * unitDistVec) * densityW_mean;; + potential[nPhaseIdx] += (K * gravity_) * (unitOuterNormal * unitDistVec) * densityNW_mean;; // do upwinding for lambdas - double lambdaW, lambdaNW; - if (potentialW >= 0.) - lambdaW = cellDataI.mobility(wPhaseIdx); + PhaseVector lambda(0.); + if (potential[wPhaseIdx] >= 0.) + lambda[wPhaseIdx] = cellDataI.mobility(wPhaseIdx); else { if(GET_PROP_VALUE(TypeTag, BoundaryMobility)==Indices::satDependent) - lambdaW = BCfluidState.saturation(wPhaseIdx) / viscosityWBound; + lambda[wPhaseIdx] = BCfluidState.saturation(wPhaseIdx) / viscosityWBound; else - lambdaW = MaterialLaw::krw( + lambda[wPhaseIdx] = MaterialLaw::krw( problem().spatialParams().materialLawParams(*elementPtrI), BCfluidState.saturation(wPhaseIdx)) / viscosityWBound; } - if (potentialNW >= 0.) - lambdaNW = cellDataI.mobility(nPhaseIdx); + if (potential[nPhaseIdx] >= 0.) + lambda[nPhaseIdx] = cellDataI.mobility(nPhaseIdx); else { if(GET_PROP_VALUE(TypeTag, BoundaryMobility)==Indices::satDependent) - lambdaNW = BCfluidState.saturation(nPhaseIdx) / viscosityNWBound; + lambda[nPhaseIdx] = BCfluidState.saturation(nPhaseIdx) / viscosityNWBound; else - lambdaNW = MaterialLaw::krn( + lambda[nPhaseIdx] = MaterialLaw::krn( problem().spatialParams().materialLawParams(*elementPtrI), BCfluidState.saturation(wPhaseIdx)) / viscosityNWBound; } // calculate and standardized velocity - double velocityJIw = std::max((-lambdaW * potentialW) * faceArea / volume, 0.0); - double velocityIJw = std::max(( lambdaW * potentialW) * faceArea / volume, 0.0); - double velocityJIn = std::max((-lambdaNW * potentialNW) * faceArea / volume, 0.0); - double velocityIJn = std::max(( lambdaNW * potentialNW) * faceArea / volume, 0.0); + double velocityJIw = std::max((-lambda[wPhaseIdx] * potential[wPhaseIdx]) * faceArea / volume, 0.0); + double velocityIJw = std::max(( lambda[wPhaseIdx] * potential[wPhaseIdx]) * faceArea / volume, 0.0); + double velocityJIn = std::max((-lambda[nPhaseIdx] * potential[nPhaseIdx]) * faceArea / volume, 0.0); + double velocityIJn = std::max(( lambda[nPhaseIdx] * potential[nPhaseIdx]) * faceArea / volume, 0.0); // for timestep control timestepFlux[0] = velocityJIw + velocityJIn; diff --git a/dumux/decoupled/2p2c/pseudo1p2cfluidstate.hh b/dumux/decoupled/2p2c/pseudo1p2cfluidstate.hh index abf7852cfb..8d050b2c8d 100644 --- a/dumux/decoupled/2p2c/pseudo1p2cfluidstate.hh +++ b/dumux/decoupled/2p2c/pseudo1p2cfluidstate.hh @@ -82,7 +82,6 @@ public: if (presentPhaseIdx == wPhaseIdx) { - Sw_ = 1.; massFractionWater_[wPhaseIdx] = Z1; massFractionWater_[nPhaseIdx] = 0.; @@ -95,7 +94,6 @@ public: } else if (presentPhaseIdx == nPhaseIdx) { - Sw_ = 0.; massFractionWater_[wPhaseIdx] = 0.; massFractionWater_[nPhaseIdx] = Z1; @@ -126,16 +124,20 @@ public: */ Scalar saturation(int phaseIdx) const { - if (phaseIdx == wPhaseIdx) - return Sw_; + if (phaseIdx == presentPhaseIdx_) + return 1.; else - return Scalar(1.0) - Sw_; + return 0.; }; int presentPhaseIdx() const { return presentPhaseIdx_; } + void setPresentPhaseIdx(int index) + { + presentPhaseIdx_ = index; + }; /*! \brief Returns the pressure of a fluid phase \f$\mathrm{[Pa]}\f$. * \param phaseIdx Index of the phase @@ -197,8 +199,6 @@ public: Scalar averageMolarMass(int phaseIdx) const { return aveMoMass_; -// return moleFractionWater_[phaseIdx]*FluidSystem::molarMass(wCompIdx) -// + (1.-moleFractionWater_[phaseIdx])*FluidSystem::molarMass(nCompIdx); } /*! @@ -211,23 +211,11 @@ public: { return temperature_; }; /*! - * \brief Returns the total mass concentration of a component \f$\mathrm{[kg/m^3]}\f$. - * - * This is equivalent to the sum of the component concentrations for all - * phases multiplied with the phase density. - * - * \param compIdx the index of the component - */ - Scalar massConcentration(int compIdx) const - { - return massConcentration_[compIdx]; - }; - /*! - * \brief Sets the total mass concentration of a component \f$\mathrm{[kg/m^3]}\f$. + * \brief Sets the phase pressure \f$\mathrm{[Pa]}\f$. */ - void setMassConcentration(int compIdx, Scalar value) + void setPressure(int phaseIdx, Scalar value) { - massConcentration_[compIdx] = value; + pressure_[phaseIdx] = value; }; //@} @@ -237,7 +225,6 @@ public: Scalar massFractionWater_[numPhases]; Scalar moleFractionWater_[numPhases]; Scalar pressure_[numPhases]; - Scalar Sw_; Scalar density_; Scalar viscosity_; Scalar temperature_; -- GitLab