diff --git a/dumux/common/properties.hh b/dumux/common/properties.hh index d08dbebf076c75ff58771433f6184cae2fc3ba79..aee63d335e022d3bfee25089bbc6b30891132c7c 100644 --- a/dumux/common/properties.hh +++ b/dumux/common/properties.hh @@ -128,7 +128,7 @@ NEW_PROP_TAG(EvaluatePermeabilityAtScvfIP); // Additional properties used by the 2pnc and 2pncmin models: ////////////////////////////////////////////////////////////// NEW_PROP_TAG(Chemistry); //!< The chemistry class with which solves equlibrium reactions -NEW_PROP_TAG(SetMoleFractionsForWettingPhase); //!< Set the mole fraction in the wetting or non-wetting phase +NEW_PROP_TAG(SetMoleFractionsForFirstPhase); //!< Set the mole fraction in the wetting or non-wetting phase ////////////////////////////////////////////////////////////// // Additional properties used by the richards model diff --git a/dumux/io/plotthermalconductivitymodel.hh b/dumux/io/plotthermalconductivitymodel.hh index a1681d5d1e4b316666f211950418bdec6e8c60cd..f759379a4b95364312dd56d0a2bb8acd084abbb8 100644 --- a/dumux/io/plotthermalconductivitymodel.hh +++ b/dumux/io/plotthermalconductivitymodel.hh @@ -41,9 +41,12 @@ template<class Scalar, class ThermalConductivityModel, class FluidSystem> class PlotThermalConductivityModel { using FluidState = CompositionalFluidState<Scalar, FluidSystem>; - enum { - wPhaseIdx = FluidSystem::wPhaseIdx, - nPhaseIdx = FluidSystem::nPhaseIdx + + // phase indices + enum + { + phase0Idx = FluidSystem::phase0Idx, + phase1Idx = FluidSystem::phase1Idx }; public: @@ -61,10 +64,10 @@ public: { FluidState fluidstate; fluidstate.setTemperature(temperature); - fluidstate.setPressure(wPhaseIdx, pressure); - fluidstate.setPressure(nPhaseIdx, pressure); - lambdaW_ = FluidSystem::thermalConductivity(fluidstate, wPhaseIdx); - lambdaN_ = FluidSystem::thermalConductivity(fluidstate, nPhaseIdx); + fluidstate.setPressure(phase0Idx, pressure); + fluidstate.setPressure(phase1Idx, pressure); + lambdaW_ = FluidSystem::thermalConductivity(fluidstate, phase0Idx); + lambdaN_ = FluidSystem::thermalConductivity(fluidstate, phase1Idx); } /*! diff --git a/dumux/material/chemistry/electrochemistry/electrochemistry.hh b/dumux/material/chemistry/electrochemistry/electrochemistry.hh index 37d09fc5b1cf988420357185bc39629019634c50..26dcca48ed3d9bfb2feed6c68ba362646f35e710 100644 --- a/dumux/material/chemistry/electrochemistry/electrochemistry.hh +++ b/dumux/material/chemistry/electrochemistry/electrochemistry.hh @@ -26,7 +26,6 @@ #include <cmath> -#include <dumux/common/properties.hh> #include <dumux/common/parameters.hh> #include <dumux/common/exceptions.hh> #include <dumux/discretization/methods.hh> @@ -46,37 +45,36 @@ enum ElectroChemistryModel { Ochs, Acosta }; * \brief This class calculates source terms and current densities for fuel cells * with the electrochemical models suggested by Ochs (2008) \cite ochs2008 or Acosta et al. (2006) \cite A3:acosta:2006 * \todo TODO: Scalar type should be extracted from VolumeVariables! + * \todo TODO: This shouldn't depend on grid and discretization!! */ template <class Scalar, class Indices, class FluidSystem, class FVGridGeometry, ElectroChemistryModel electroChemistryModel> class ElectroChemistry { - using FVElementGeometry = typename FVGridGeometry::LocalView; - using GridView = typename FVGridGeometry::GridView; - using Element = typename GridView::template Codim<0>::Entity; using Constant = Dumux::Constants<Scalar>; - enum { - //indices of the components - wCompIdx = FluidSystem::wCompIdx, //major component of the liquid phase - nCompIdx = FluidSystem::nCompIdx, //major component of the gas phase - O2Idx = wCompIdx + 2 - }; - enum { + enum + { //indices of the primary variables - pressureIdx = Indices::pressureIdx, //gas-phase pressure - switchIdx = Indices::switchIdx, //liquid saturation or mole fraction + pressureIdx = Indices::pressureIdx, // gas-phase pressure + switchIdx = Indices::switchIdx, // liquid saturation or mole fraction }; - enum { + enum + { //equation indices - conti0EqIdx = Indices::conti0EqIdx, - contiH2OEqIdx = conti0EqIdx + wCompIdx, - contiO2EqIdx = conti0EqIdx + wCompIdx + 2, + contiH2OEqIdx = Indices::conti0EqIdx + FluidSystem::H2OIdx, + contiO2EqIdx = Indices::conti0EqIdx + FluidSystem::O2Idx, }; - static constexpr bool isBox = FVGridGeometry::discMethod == DiscretizationMethod::box; - enum { dofCodim = isBox ? GridView::dimension : 0 }; + enum + { + // phase indices + liquidPhaseIdx = FluidSystem::liquidPhaseIdx, + gasPhaseIdx = FluidSystem::gasPhaseIdx + }; + using GridView = typename FVGridGeometry::GridView; + static constexpr bool isBox = FVGridGeometry::discMethod == DiscretizationMethod::box; using GlobalPosition = typename Dune::FieldVector<typename GridView::ctype, GridView::dimensionworld>; public: @@ -92,9 +90,9 @@ public: static void reactionSource(SourceValues &values, Scalar currentDensity, const std::string& paramGroup = "") { - //correction to account for actually relevant reaction area - //current density has to be devided by the half length of the box - //\todo Do we have multiply with the electrochemically active surface area (ECSA) here instead? + // correction to account for actually relevant reaction area + // current density has to be devided by the half length of the box + // \todo Do we have multiply with the electrochemically active surface area (ECSA) here instead? static Scalar gridYMax = getParamFromGroup<GlobalPosition>(paramGroup, "Grid.UpperRight")[1]; static Scalar nCellsY = getParamFromGroup<GlobalPosition>(paramGroup, "Grid.Cells")[1]; @@ -143,7 +141,7 @@ public: Scalar activationLossesNext = calculateActivationLosses_(volVars, currentDensity+deltaCurrentDensity); Scalar concentrationLosses = calculateConcentrationLosses_(volVars); Scalar activationLossesDiff = activationLossesNext - activationLosses; - Scalar sw = volVars.saturation(FluidSystem::wPhaseIdx); + Scalar sw = volVars.saturation(liquidPhaseIdx); if(electroChemistryModel == ElectroChemistryModel::Acosta) { @@ -198,11 +196,11 @@ private: static Scalar transferCoefficient = getParam<Scalar>("ElectroChemistry.TransferCoefficient"); //Saturation sw for Acosta calculation - Scalar sw = volVars.saturation(FluidSystem::wPhaseIdx); + Scalar sw = volVars.saturation(liquidPhaseIdx); //Calculate prefactor Scalar preFactor = Constant::R*volVars.fluidState().temperature()/transferCoefficient/Constant::F/numElectrons; //Get partial pressure of O2 in the gas phase - Scalar pO2 = volVars.pressure(FluidSystem::nPhaseIdx) * volVars.fluidState().moleFraction(FluidSystem::nPhaseIdx, O2Idx); + Scalar pO2 = volVars.pressure(gasPhaseIdx) * volVars.fluidState().moleFraction(gasPhaseIdx, FluidSystem::O2Idx); Scalar losses = 0.0; //Calculate activation losses @@ -241,7 +239,7 @@ private: //Calculate preFactor Scalar preFactor = Constant::R*volVars.temperature()/transferCoefficient/Constant::F/numElectrons; //Get partial pressure of O2 in the gas phase - Scalar pO2 = volVars.pressure(FluidSystem::nPhaseIdx) * volVars.fluidState().moleFraction(FluidSystem::nPhaseIdx, O2Idx); + Scalar pO2 = volVars.pressure(gasPhaseIdx) * volVars.fluidState().moleFraction(gasPhaseIdx, FluidSystem::O2Idx); Scalar losses = 0.0; //Calculate concentration losses diff --git a/dumux/material/chemistry/electrochemistry/electrochemistryni.hh b/dumux/material/chemistry/electrochemistry/electrochemistryni.hh index 4b9de9329357a19e47700c875b41c527c468bdde..a1a0eae0f5ad4c31fcc3f9a1b3f5ce94eae53298 100644 --- a/dumux/material/chemistry/electrochemistry/electrochemistryni.hh +++ b/dumux/material/chemistry/electrochemistry/electrochemistryni.hh @@ -24,7 +24,6 @@ #ifndef DUMUX_ELECTROCHEMISTRY_NI_HH #define DUMUX_ELECTROCHEMISTRY_NI_HH -#include <dumux/common/properties.hh> #include <dumux/material/constants.hh> #include <dumux/material/chemistry/electrochemistry/electrochemistry.hh> @@ -36,30 +35,23 @@ namespace Dumux { * with the electrochemical models suggested by Ochs (2008) \cite ochs2008 or Acosta (2006) \cite A3:acosta:2006 * for the non-isothermal case. * \todo TODO: Scalar type should be extracted from VolumeVariables! + * \todo TODO: This shouldn't depend on discretization and grid!! */ template <class Scalar, class Indices, class FVGridGeometry, ElectroChemistryModel electroChemistryModel> class ElectroChemistryNI : public ElectroChemistry<Scalar, Indices, FVGridGeometry, electroChemistryModel> { using ParentType = ElectroChemistry<Scalar, Indices, FVGridGeometry, electroChemistryModel>; - using GridView = typename FVGridGeometry::GridView; using Constant = Constants<Scalar>; enum { - //indices of the components - wCompIdx = Indices::wCompIdx, //major component of the liquid phase - nCompIdx = Indices::nCompIdx, //major component of the gas phase - O2Idx = wCompIdx + 2 - }; - enum { //equation indices - conti0EqIdx = Indices::conti0EqIdx, - contiH2OEqIdx = conti0EqIdx + wCompIdx, - contiO2EqIdx = conti0EqIdx + wCompIdx + 2, - energyEqIdx = Indices::energyEqIdx, //energy equation + //equation indices + contiH2OEqIdx = Indices::conti0EqIdx + FluidSystem::H2OIdx, + contiO2EqIdx = Indices::conti0EqIdx + FluidSystem::O2Idx, + energyEqIdx = Indices::energyEqIdx, //energy equation }; + using GridView = typename FVGridGeometry::GridView; static constexpr bool isBox = FVGridGeometry::discMethod == DiscretizationMethod::box; - enum { dofCodim = isBox ? GridView::dimension : 0 }; - using GlobalPosition = typename Dune::FieldVector<typename GridView::ctype, GridView::dimensionworld>; using CellVector = typename Dune::FieldVector<typename GridView::ctype, GridView::dimension>; diff --git a/dumux/material/constraintsolvers/compositionalflash.hh b/dumux/material/constraintsolvers/compositionalflash.hh index 834ec781fb061d43d7a4791d8147b28c9c7bd482..a49d22970d5bf8fb2d77366daa991716276355a3 100644 --- a/dumux/material/constraintsolvers/compositionalflash.hh +++ b/dumux/material/constraintsolvers/compositionalflash.hh @@ -47,10 +47,10 @@ class CompositionalFlash }; enum{ - wPhaseIdx = FluidSystem::wPhaseIdx, - nPhaseIdx = FluidSystem::nPhaseIdx, - wCompIdx = FluidSystem::wCompIdx, - nCompIdx = FluidSystem::nCompIdx + phase0Idx = FluidSystem::phase0Idx, + phase1Idx = FluidSystem::phase1Idx, + comp0Idx = FluidSystem::comp0Idx, + comp1Idx = FluidSystem::comp1Idx }; public: @@ -82,93 +82,93 @@ public: { // set the temperature, pressure fluidState.setTemperature(temperature); - fluidState.setPressure(wPhaseIdx, phasePressure[wPhaseIdx]); - fluidState.setPressure(nPhaseIdx, phasePressure[nPhaseIdx]); + fluidState.setPressure(phase0Idx, phasePressure[phase0Idx]); + fluidState.setPressure(phase1Idx, phasePressure[phase1Idx]); //mole equilibrium ratios K for in case wPhase is reference phase - double k1 = FluidSystem::fugacityCoefficient(fluidState, wPhaseIdx, wCompIdx); // = p^wComp_vap - double k2 = FluidSystem::fugacityCoefficient(fluidState, wPhaseIdx, nCompIdx); // = H^nComp_w + double k1 = FluidSystem::fugacityCoefficient(fluidState, phase0Idx, comp0Idx); // = p^wComp_vap + double k2 = FluidSystem::fugacityCoefficient(fluidState, phase0Idx, comp1Idx); // = H^nComp_w // get mole fraction from equilibrium konstants - fluidState.setMoleFraction(wPhaseIdx,wCompIdx, ((1. - k2) / (k1 -k2))); - fluidState.setMoleFraction(nPhaseIdx,wCompIdx, (fluidState.moleFraction(wPhaseIdx,wCompIdx) * k1)); + fluidState.setMoleFraction(phase0Idx,comp0Idx, ((1. - k2) / (k1 -k2))); + fluidState.setMoleFraction(phase1Idx,comp0Idx, (fluidState.moleFraction(phase0Idx,comp0Idx) * k1)); // transform mole to mass fractions - fluidState.setMassFraction(wPhaseIdx, wCompIdx, - (fluidState.moleFraction(wPhaseIdx,wCompIdx) * FluidSystem::molarMass(wCompIdx) - / ( fluidState.moleFraction(wPhaseIdx,wCompIdx) * FluidSystem::molarMass(wCompIdx) - + (1.-fluidState.moleFraction(wPhaseIdx,wCompIdx)) * FluidSystem::molarMass(nCompIdx) ))); - fluidState.setMassFraction(nPhaseIdx,wCompIdx, - (fluidState.moleFraction(nPhaseIdx,wCompIdx) * FluidSystem::molarMass(wCompIdx) - / ( fluidState.moleFraction(nPhaseIdx,wCompIdx) * FluidSystem::molarMass(wCompIdx) - + (1.-fluidState.moleFraction(nPhaseIdx,wCompIdx)) * FluidSystem::molarMass(nCompIdx) ))); + fluidState.setMassFraction(phase0Idx, comp0Idx, + (fluidState.moleFraction(phase0Idx,comp0Idx) * FluidSystem::molarMass(comp0Idx) + / ( fluidState.moleFraction(phase0Idx,comp0Idx) * FluidSystem::molarMass(comp0Idx) + + (1.-fluidState.moleFraction(phase0Idx,comp0Idx)) * FluidSystem::molarMass(comp1Idx) ))); + fluidState.setMassFraction(phase1Idx,comp0Idx, + (fluidState.moleFraction(phase1Idx,comp0Idx) * FluidSystem::molarMass(comp0Idx) + / ( fluidState.moleFraction(phase1Idx,comp0Idx) * FluidSystem::molarMass(comp0Idx) + + (1.-fluidState.moleFraction(phase1Idx,comp0Idx)) * FluidSystem::molarMass(comp1Idx) ))); //mass equilibrium ratios Scalar equilRatio_[numPhases][numComponents]; - equilRatio_[nPhaseIdx][wCompIdx] = fluidState.massFraction(nPhaseIdx,wCompIdx) - / fluidState.massFraction(wPhaseIdx, wCompIdx); // = Xn1 / Xw1 = K1 - equilRatio_[nPhaseIdx][nCompIdx] = (1.-fluidState.massFraction(nPhaseIdx, wCompIdx)) - / (1.-fluidState.massFraction(wPhaseIdx, wCompIdx)); // =(1.-Xn1) / (1.-Xw1) = K2 - equilRatio_[wPhaseIdx][nCompIdx] = equilRatio_[wPhaseIdx][wCompIdx] = 1.; + equilRatio_[phase1Idx][comp0Idx] = fluidState.massFraction(phase1Idx,comp0Idx) + / fluidState.massFraction(phase0Idx, comp0Idx); // = Xn1 / Xw1 = K1 + equilRatio_[phase1Idx][comp1Idx] = (1.-fluidState.massFraction(phase1Idx, comp0Idx)) + / (1.-fluidState.massFraction(phase0Idx, comp0Idx)); // =(1.-Xn1) / (1.-Xw1) = K2 + equilRatio_[phase0Idx][comp1Idx] = equilRatio_[phase0Idx][comp0Idx] = 1.; // phase fraction of nPhase [mass/totalmass] - fluidState.setNu(nPhaseIdx, 0.); + fluidState.setNu(phase1Idx, 0.); // check if there is enough of component 1 to form a phase - if (Z1 > fluidState.massFraction(nPhaseIdx,wCompIdx) - && Z1 < fluidState.massFraction(wPhaseIdx,wCompIdx)) - fluidState.setNu(nPhaseIdx, -((equilRatio_[nPhaseIdx][wCompIdx]-1)*Z1 + (equilRatio_[nPhaseIdx][nCompIdx]-1)*(1-Z1)) - / (equilRatio_[nPhaseIdx][wCompIdx]-1) / (equilRatio_[nPhaseIdx][nCompIdx] -1)); - else if (Z1 <= fluidState.massFraction(nPhaseIdx,wCompIdx)) // too little wComp to form a phase + if (Z1 > fluidState.massFraction(phase1Idx,comp0Idx) + && Z1 < fluidState.massFraction(phase0Idx,comp0Idx)) + fluidState.setNu(phase1Idx, -((equilRatio_[phase1Idx][comp0Idx]-1)*Z1 + (equilRatio_[phase1Idx][comp1Idx]-1)*(1-Z1)) + / (equilRatio_[phase1Idx][comp0Idx]-1) / (equilRatio_[phase1Idx][comp1Idx] -1)); + else if (Z1 <= fluidState.massFraction(phase1Idx,comp0Idx)) // too little wComp to form a phase { - fluidState.setNu(nPhaseIdx, 1.); // only nPhase - fluidState.setMassFraction(nPhaseIdx,wCompIdx, Z1); // hence, assign complete mass dissolved into nPhase + fluidState.setNu(phase1Idx, 1.); // only nPhase + fluidState.setMassFraction(phase1Idx,comp0Idx, Z1); // hence, assign complete mass dissolved into nPhase // store as moleFractions - Scalar xw_n = Z1 /*=Xw_n*/ / FluidSystem::molarMass(wCompIdx); // = moles of compIdx - xw_n /= ( Z1 /*=Xw_n*/ / FluidSystem::molarMass(wCompIdx) - +(1- Z1 /*=Xn_n*/) / FluidSystem::molarMass(nCompIdx) ); // /= total moles in phase + Scalar xw_n = Z1 /*=Xw_n*/ / FluidSystem::molarMass(comp0Idx); // = moles of compIdx + xw_n /= ( Z1 /*=Xw_n*/ / FluidSystem::molarMass(comp0Idx) + +(1- Z1 /*=Xn_n*/) / FluidSystem::molarMass(comp1Idx) ); // /= total moles in phase - fluidState.setMoleFraction(nPhaseIdx,wCompIdx, xw_n); + fluidState.setMoleFraction(phase1Idx,comp0Idx, xw_n); // // opposing non-present phase is already set to equilibrium mass fraction -// fluidState.setMassFraction(wPhaseIdx,wCompIdx, 1.); // non present phase is set to be pure -// fluidState.setMoleFraction(wPhaseIdx,wCompIdx, 1.); // non present phase is set to be pure +// fluidState.setMassFraction(phase0Idx,comp0Idx, 1.); // non present phase is set to be pure +// fluidState.setMoleFraction(phase0Idx,comp0Idx, 1.); // non present phase is set to be pure } else // (Z1 >= Xw1) => no nPhase { - fluidState.setNu(nPhaseIdx, 0.); // no second phase - fluidState.setMassFraction(wPhaseIdx, wCompIdx, Z1); + fluidState.setNu(phase1Idx, 0.); // no second phase + fluidState.setMassFraction(phase0Idx, comp0Idx, Z1); // store as moleFractions - Scalar xw_w = Z1 /*=Xw_w*/ / FluidSystem::molarMass(wCompIdx); // = moles of compIdx - xw_w /= ( Z1 /*=Xw_w*/ / FluidSystem::molarMass(wCompIdx) - +(1- Z1 /*=Xn_w*/) / FluidSystem::molarMass(nCompIdx) ); // /= total moles in phase - fluidState.setMoleFraction(wPhaseIdx, wCompIdx, xw_w); + Scalar xw_w = Z1 /*=Xw_w*/ / FluidSystem::molarMass(comp0Idx); // = moles of compIdx + xw_w /= ( Z1 /*=Xw_w*/ / FluidSystem::molarMass(comp0Idx) + +(1- Z1 /*=Xn_w*/) / FluidSystem::molarMass(comp1Idx) ); // /= total moles in phase + fluidState.setMoleFraction(phase0Idx, comp0Idx, xw_w); // // opposing non-present phase is already set to equilibrium mass fraction -// fluidState.setMassFraction(nPhaseIdx,wCompIdx, 0.); // non present phase is set to be pure -// fluidState.setMoleFraction(nPhaseIdx,wCompIdx, 0.); // non present phase is set to be pure +// fluidState.setMassFraction(phase1Idx,comp0Idx, 0.); // non present phase is set to be pure +// fluidState.setMoleFraction(phase1Idx,comp0Idx, 0.); // non present phase is set to be pure } // complete array of mass fractions - fluidState.setMassFraction(wPhaseIdx, nCompIdx, 1. - fluidState.massFraction(wPhaseIdx,wCompIdx)); - fluidState.setMassFraction(nPhaseIdx, nCompIdx, 1. - fluidState.massFraction(nPhaseIdx,wCompIdx)); + fluidState.setMassFraction(phase0Idx, comp1Idx, 1. - fluidState.massFraction(phase0Idx,comp0Idx)); + fluidState.setMassFraction(phase1Idx, comp1Idx, 1. - fluidState.massFraction(phase1Idx,comp0Idx)); // complete array of mole fractions - fluidState.setMoleFraction(wPhaseIdx, nCompIdx, 1. - fluidState.moleFraction(wPhaseIdx,wCompIdx)); - fluidState.setMoleFraction(nPhaseIdx, nCompIdx, 1. - fluidState.moleFraction(nPhaseIdx,wCompIdx)); + fluidState.setMoleFraction(phase0Idx, comp1Idx, 1. - fluidState.moleFraction(phase0Idx,comp0Idx)); + fluidState.setMoleFraction(phase1Idx, comp1Idx, 1. - fluidState.moleFraction(phase1Idx,comp0Idx)); // complete phase mass fractions - fluidState.setNu(wPhaseIdx, 1. - fluidState.phaseMassFraction(nPhaseIdx)); + fluidState.setNu(phase0Idx, 1. - fluidState.phaseMassFraction(phase1Idx)); // get densities with correct composition - fluidState.setDensity(wPhaseIdx, FluidSystem::density(fluidState, wPhaseIdx)); - fluidState.setDensity(nPhaseIdx, FluidSystem::density(fluidState, nPhaseIdx)); + fluidState.setDensity(phase0Idx, FluidSystem::density(fluidState, phase0Idx)); + fluidState.setDensity(phase1Idx, FluidSystem::density(fluidState, phase1Idx)); - Scalar sw = fluidState.phaseMassFraction(wPhaseIdx) / fluidState.density(wPhaseIdx); - sw /= (fluidState.phaseMassFraction(wPhaseIdx)/fluidState.density(wPhaseIdx) - + fluidState.phaseMassFraction(nPhaseIdx)/fluidState.density(nPhaseIdx)); - fluidState.setSaturation(wPhaseIdx, sw); + Scalar sw = fluidState.phaseMassFraction(phase0Idx) / fluidState.density(phase0Idx); + sw /= (fluidState.phaseMassFraction(phase0Idx)/fluidState.density(phase0Idx) + + fluidState.phaseMassFraction(phase1Idx)/fluidState.density(phase1Idx)); + fluidState.setSaturation(phase0Idx, sw); } /*! The simplest possible update routine for 1p2c "flash" calculations @@ -188,51 +188,51 @@ public: { // set the temperature, pressure fluidState.setTemperature(temperature); - fluidState.setPressure(wPhaseIdx, phasePressure[wPhaseIdx]); - fluidState.setPressure(nPhaseIdx, phasePressure[nPhaseIdx]); + fluidState.setPressure(phase0Idx, phasePressure[phase0Idx]); + fluidState.setPressure(phase1Idx, phasePressure[phase1Idx]); fluidState.setPresentPhaseIdx(presentPhaseIdx); - fluidState.setMassFraction(presentPhaseIdx,wCompIdx, Z1); + fluidState.setMassFraction(presentPhaseIdx,comp0Idx, Z1); // calculate mole fraction and average molar mass - Scalar xw_alpha= Z1 / FluidSystem::molarMass(wCompIdx); - xw_alpha /= ( Z1 / FluidSystem::molarMass(wCompIdx) - + (1.-Z1) / FluidSystem::molarMass(nCompIdx)); - fluidState.setMoleFraction(presentPhaseIdx, wCompIdx, xw_alpha); + Scalar xw_alpha= Z1 / FluidSystem::molarMass(comp0Idx); + xw_alpha /= ( Z1 / FluidSystem::molarMass(comp0Idx) + + (1.-Z1) / FluidSystem::molarMass(comp1Idx)); + fluidState.setMoleFraction(presentPhaseIdx, comp0Idx, xw_alpha); -// if (presentPhaseIdx == wPhaseIdx) +// if (presentPhaseIdx == phase0Idx) // { // -//// fluidState.setMassFraction(wPhaseIdx,wCompIdx, 0.; +//// fluidState.setMassFraction(phase0Idx,comp0Idx, 0.; // // // // // -//// fluidState.moleFractionWater_[nPhaseIdx] = 0.; +//// fluidState.moleFractionWater_[phase1Idx] = 0.; // // fluidState.setPresentPhaseIdx(presentPhaseIdx); // } -// else if (presentPhaseIdx == nPhaseIdx) +// else if (presentPhaseIdx == phase1Idx) // { -// fluidState.setMassFraction[wPhaseIdx] = 0.; -// fluidState.setMassFraction[nPhaseIdx] = Z1; +// fluidState.setMassFraction[phase0Idx] = 0.; +// fluidState.setMassFraction[phase1Idx] = Z1; // // // interested in nComp => 1-X1 -// fluidState.moleFractionWater_[nPhaseIdx] = ( Z1 / FluidSystem::molarMass(0) ); // = moles of compIdx -// fluidState.moleFractionWater_[nPhaseIdx] /= (Z1/ FluidSystem::molarMass(0) +// fluidState.moleFractionWater_[phase1Idx] = ( Z1 / FluidSystem::molarMass(0) ); // = moles of compIdx +// fluidState.moleFractionWater_[phase1Idx] /= (Z1/ FluidSystem::molarMass(0) // + (1.-Z1) / FluidSystem::molarMass(1) ); // /= total moles in phase -// fluidState.moleFractionWater_[nPhaseIdx] = 0.; +// fluidState.moleFractionWater_[phase1Idx] = 0.; // -// fluidState.presentPhaseIdx_ = nPhaseIdx; +// fluidState.presentPhaseIdx_ = phase1Idx; // } // else // Dune::dgrave << __FILE__ <<": Twophase conditions in single-phase flash!" // << " Z1 is "<<Z1<< std::endl; fluidState.setAverageMolarMass(presentPhaseIdx, - fluidState.massFraction(presentPhaseIdx, wCompIdx)*FluidSystem::molarMass(wCompIdx) - +fluidState.massFraction(presentPhaseIdx, nCompIdx)*FluidSystem::molarMass(nCompIdx)); + fluidState.massFraction(presentPhaseIdx, comp0Idx)*FluidSystem::molarMass(comp0Idx) + +fluidState.massFraction(presentPhaseIdx, comp1Idx)*FluidSystem::molarMass(comp1Idx)); fluidState.setDensity(presentPhaseIdx, FluidSystem::density(fluidState, presentPhaseIdx)); } @@ -263,44 +263,44 @@ public: { // set the temperature, pressure fluidState.setTemperature(temperature); - fluidState.setPressure(wPhaseIdx, phasePressure[wPhaseIdx]); - fluidState.setPressure(nPhaseIdx, phasePressure[nPhaseIdx]); + fluidState.setPressure(phase0Idx, phasePressure[phase0Idx]); + fluidState.setPressure(phase1Idx, phasePressure[phase1Idx]); //in contrast to the standard update() method, satflash() does not calculate nu. - fluidState.setNu(wPhaseIdx, NAN); - fluidState.setNu(nPhaseIdx, NAN); + fluidState.setNu(phase0Idx, NAN); + fluidState.setNu(phase1Idx, NAN); //mole equilibrium ratios K for in case wPhase is reference phase - double k1 = FluidSystem::fugacityCoefficient(fluidState, wPhaseIdx, wCompIdx); // = p^wComp_vap - double k2 = FluidSystem::fugacityCoefficient(fluidState, wPhaseIdx, nCompIdx); // = H^nComp_w + double k1 = FluidSystem::fugacityCoefficient(fluidState, phase0Idx, comp0Idx); // = p^wComp_vap + double k2 = FluidSystem::fugacityCoefficient(fluidState, phase0Idx, comp1Idx); // = H^nComp_w // get mole fraction from equilibrium konstants - fluidState.setMoleFraction(wPhaseIdx,wCompIdx, ((1. - k2) / (k1 -k2))); - fluidState.setMoleFraction(nPhaseIdx,wCompIdx, (fluidState.moleFraction(wPhaseIdx,wCompIdx) * k1)); + fluidState.setMoleFraction(phase0Idx,comp0Idx, ((1. - k2) / (k1 -k2))); + fluidState.setMoleFraction(phase1Idx,comp0Idx, (fluidState.moleFraction(phase0Idx,comp0Idx) * k1)); // transform mole to mass fractions - fluidState.setMassFraction(wPhaseIdx, wCompIdx, - (fluidState.moleFraction(wPhaseIdx,wCompIdx) * FluidSystem::molarMass(wCompIdx) - / ( fluidState.moleFraction(wPhaseIdx,wCompIdx) * FluidSystem::molarMass(wCompIdx) - + (1.-fluidState.moleFraction(wPhaseIdx,wCompIdx)) * FluidSystem::molarMass(nCompIdx) ))); - fluidState.setMassFraction(nPhaseIdx,wCompIdx, - (fluidState.moleFraction(nPhaseIdx,wCompIdx) * FluidSystem::molarMass(wCompIdx) - / ( fluidState.moleFraction(nPhaseIdx,wCompIdx) * FluidSystem::molarMass(wCompIdx) - + (1.-fluidState.moleFraction(nPhaseIdx,wCompIdx)) * FluidSystem::molarMass(nCompIdx) ))); + fluidState.setMassFraction(phase0Idx, comp0Idx, + (fluidState.moleFraction(phase0Idx,comp0Idx) * FluidSystem::molarMass(comp0Idx) + / ( fluidState.moleFraction(phase0Idx,comp0Idx) * FluidSystem::molarMass(comp0Idx) + + (1.-fluidState.moleFraction(phase0Idx,comp0Idx)) * FluidSystem::molarMass(comp1Idx) ))); + fluidState.setMassFraction(phase1Idx,comp0Idx, + (fluidState.moleFraction(phase1Idx,comp0Idx) * FluidSystem::molarMass(comp0Idx) + / ( fluidState.moleFraction(phase1Idx,comp0Idx) * FluidSystem::molarMass(comp0Idx) + + (1.-fluidState.moleFraction(phase1Idx,comp0Idx)) * FluidSystem::molarMass(comp1Idx) ))); // complete array of mass fractions - fluidState.setMassFraction(wPhaseIdx, nCompIdx, 1. - fluidState.massFraction(wPhaseIdx,wCompIdx)); - fluidState.setMassFraction(nPhaseIdx, nCompIdx, 1. - fluidState.massFraction(nPhaseIdx,wCompIdx)); + fluidState.setMassFraction(phase0Idx, comp1Idx, 1. - fluidState.massFraction(phase0Idx,comp0Idx)); + fluidState.setMassFraction(phase1Idx, comp1Idx, 1. - fluidState.massFraction(phase1Idx,comp0Idx)); // complete array of mole fractions - fluidState.setMoleFraction(wPhaseIdx, nCompIdx, 1. - fluidState.moleFraction(wPhaseIdx,wCompIdx)); - fluidState.setMoleFraction(nPhaseIdx, nCompIdx, 1. - fluidState.moleFraction(nPhaseIdx,wCompIdx)); + fluidState.setMoleFraction(phase0Idx, comp1Idx, 1. - fluidState.moleFraction(phase0Idx,comp0Idx)); + fluidState.setMoleFraction(phase1Idx, comp1Idx, 1. - fluidState.moleFraction(phase1Idx,comp0Idx)); // get densities with correct composition - fluidState.setDensity(wPhaseIdx, FluidSystem::density(fluidState, wPhaseIdx)); - fluidState.setDensity(nPhaseIdx, FluidSystem::density(fluidState, nPhaseIdx)); + fluidState.setDensity(phase0Idx, FluidSystem::density(fluidState, phase0Idx)); + fluidState.setDensity(phase1Idx, FluidSystem::density(fluidState, phase1Idx)); // set saturation - fluidState.setSaturation(wPhaseIdx, saturation); + fluidState.setSaturation(phase0Idx, saturation); } //@} }; diff --git a/dumux/material/constraintsolvers/misciblemultiphasecomposition.hh b/dumux/material/constraintsolvers/misciblemultiphasecomposition.hh index de0c8d64056cf6eac4b79b3e774f55e1428f99f1..a51839547045b147003e7953dee6bb820713f29e 100644 --- a/dumux/material/constraintsolvers/misciblemultiphasecomposition.hh +++ b/dumux/material/constraintsolvers/misciblemultiphasecomposition.hh @@ -57,7 +57,7 @@ namespace Dumux { * - if the setViscosity parameter is true, also dynamic viscosities of *all* phases * - if the setEnthalpy parameter is true, also specific enthalpies of *all* phases */ -template <class Scalar, class FluidSystem, bool useKelvinEquation = false> +template <class Scalar, class FluidSystem> class MiscibleMultiPhaseComposition { static constexpr int numPhases = FluidSystem::numPhases; @@ -140,9 +140,9 @@ public: } } - //set the additional equations for the numComponents-numMajorComponents + // set the additional equations for the numComponents-numMajorComponents // this is only relevant if numphases != numcomponents e.g. in a 2pnc system - //Components, of which the molefractions are known, set to molefraction(knownCompIdx)=xKnown + // Components, of which the molefractions are known, set to molefraction(knownCompIdx)=xKnown for(int knownCompIdx = 0; knownCompIdx < numComponents-numMajorComponents; ++knownCompIdx) { int rowIdx = numComponents + numPhases + knownCompIdx; @@ -156,70 +156,31 @@ public: for (int compIdx = 0; compIdx < numComponents; ++compIdx) { int col1Idx = compIdx; - Scalar entryPhase0 = 0.0; - for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - { - Scalar entry = fluidState.fugacityCoefficient(phaseIdx, compIdx) - * fluidState.pressure(phaseIdx); - - // modify the saturation vapor pressure of the wetting component by the Kelvin equation - if (compIdx == FluidSystem::wCompIdx - && phaseIdx == FluidSystem::wPhaseIdx - && useKelvinEquation) - { - // a new fluidState is needed, because mole fractions are unknown - FluidState purePhaseFluidState; - // assign all phase pressures, needed for capillary pressure - for (unsigned int idx = 0; idx < numPhases; ++idx) - { - purePhaseFluidState.setPressure(idx, fluidState.pressure(idx)); - } - purePhaseFluidState.setTemperature(fluidState.temperature()); - purePhaseFluidState.setMoleFraction(phaseIdx, compIdx, 1.0); - entry = FluidSystem::kelvinVaporPressure(purePhaseFluidState, phaseIdx, compIdx); - } + const auto entryPhase0 = fluidState.fugacityCoefficient(0, compIdx)*fluidState.pressure(0); - if (phaseIdx == 0) - { - entryPhase0 = entry; - } - else - { - int rowIdx = (phaseIdx - 1)*numComponents + compIdx; - int col2Idx = phaseIdx*numComponents + compIdx; - M[rowIdx][col1Idx] = entryPhase0; - M[rowIdx][col2Idx] = -entry; - } + for (unsigned int phaseIdx = 1; phaseIdx < numPhases; ++phaseIdx) + { + int rowIdx = (phaseIdx - 1)*numComponents + compIdx; + int col2Idx = phaseIdx*numComponents + compIdx; + M[rowIdx][col1Idx] = entryPhase0; + M[rowIdx][col2Idx] = -fluidState.fugacityCoefficient(phaseIdx, compIdx)*fluidState.pressure(phaseIdx); } } - - //preconditioning of M to reduce condition number - //prevents matrix meeting dune's singularity criteria + // preconditioning of M to reduce condition number for (int compIdx = 0; compIdx < numComponents; compIdx++) { + // Multiply row of main component (Raoult's Law) with 10e-5 (order of magn. of pressure) if (compIdx < numMajorComponents) - { - for (int colIdx = 0; colIdx < numPhases*numComponents; colIdx++) - { - //Multiply row of main component (Raoult's Law) with 10e-5 (order of magn. of pressure) - M[compIdx][colIdx] *= 10e-5; - } - } else { - for (int colIdx = 0; colIdx < numPhases*numComponents; colIdx++) - { - //Multiply row of sec. components (Henry's Law) with 10e-9 (order of magn. of Henry constant) - M[compIdx][colIdx] *= 10e-9; - } - } - } + M[compIdx] *= 10e-5; + // Multiply row of sec. components (Henry's Law) with 10e-9 (order of magn. of Henry constant) + else + M[compIdx] *= 10e-9; + } // solve for all mole fractions - try - { - M.solve(x, b); - } + try { M.solve(x, b); } catch (Dune::FMatrixError & e) { DUNE_THROW(NumericalProblem, "Matrix for composition of phases could not be solved. \n" diff --git a/dumux/material/fluidmatrixinteractions/2p/thermalconductivitysimplefluidlumping.hh b/dumux/material/fluidmatrixinteractions/2p/thermalconductivitysimplefluidlumping.hh index ff33343b16df2a4a1027175262e4062d105c955b..5f09f7b147b7ccc7d26f4be2bd16ecd323fe57f2 100644 --- a/dumux/material/fluidmatrixinteractions/2p/thermalconductivitysimplefluidlumping.hh +++ b/dumux/material/fluidmatrixinteractions/2p/thermalconductivitysimplefluidlumping.hh @@ -47,7 +47,7 @@ public: * \param element element (to be passed to spatialParams) * \param fvGeometry fvGeometry (to be passed to spatialParams) * \param scv the sub-control volume - * + * \todo TODO: Fix this law for changing wettability * \return effective thermal conductivity \f$\mathrm{[W/(m K)]}\f$ */ template<class VolumeVariables, class SpatialParams, class Element, class FVGeometry, class SubControlVolume> @@ -58,9 +58,9 @@ public: SubControlVolume& scv) { using FluidSystem = typename VolumeVariables::FluidSystem; - Scalar sw = volVars.saturation(FluidSystem::wPhaseIdx); - Scalar lambdaW = volVars.fluidThermalConductivity(FluidSystem::wPhaseIdx); - Scalar lambdaN = volVars.fluidThermalConductivity(FluidSystem::nPhaseIdx); + Scalar sw = volVars.saturation(FluidSystem::phase0Idx); + Scalar lambdaW = volVars.fluidThermalConductivity(FluidSystem::phase0Idx); + Scalar lambdaN = volVars.fluidThermalConductivity(FluidSystem::phase1Idx); Scalar lambdaSolid = volVars.solidThermalConductivity(); Scalar porosity = volVars.porosity(); diff --git a/dumux/material/fluidmatrixinteractions/2p/thermalconductivitysomerton.hh b/dumux/material/fluidmatrixinteractions/2p/thermalconductivitysomerton.hh index 0072d19247d37a1e68314d6c16988bbb6c6efbfb..7fb5c8773119feeb91b0028a0ebb75448bf18847 100644 --- a/dumux/material/fluidmatrixinteractions/2p/thermalconductivitysomerton.hh +++ b/dumux/material/fluidmatrixinteractions/2p/thermalconductivitysomerton.hh @@ -84,31 +84,36 @@ public: const typename FVGeometry::SubControlVolume& scv) { using FluidSystem = typename VolumeVariables::FluidSystem; + static_assert(FluidSystem::numPhases == 2, "ThermalConductivitySomerton only works for two-phase fluid systems!"); + static_assert(!FluidSystem::isLiquid(0) || !FluidSystem::isLiquid(1), "ThermalConductivitySomerton only works if one phase is gaseous and one is liquid!"); - const Scalar sw = volVars.saturation(FluidSystem::wPhaseIdx); - const Scalar lambdaW = volVars.fluidThermalConductivity(FluidSystem::wPhaseIdx); - const Scalar lambdaN = volVars.fluidThermalConductivity(FluidSystem::nPhaseIdx); + constexpr int liquidPhaseIdx = FluidSystem::isLiquid(0) ? 0 : 1; + constexpr int gasPhaseIdx = FluidSystem::isLiquid(0) ? 1 : 0; + + const Scalar satLiquid = volVars.saturation(liquidPhaseIdx); + const Scalar lambdaLiquid = volVars.fluidThermalConductivity(liquidPhaseIdx); + const Scalar lambdaGas = volVars.fluidThermalConductivity(gasPhaseIdx); const Scalar lambdaSolid = volVars.solidThermalConductivity(); const Scalar porosity = volVars.porosity(); - return effectiveThermalConductivity(sw, lambdaW, lambdaN, lambdaSolid, porosity); + return effectiveThermalConductivity(satLiquid, lambdaLiquid, lambdaGas, lambdaSolid, porosity); } /*! * \brief effective thermal conductivity \f$\mathrm{[W/(m K)]}\f$ after Somerton (1974) \cite somerton1974 <BR> * - * \param sw The saturation of the wetting phase - * \param lambdaW The thermal conductivity of the wetting phase in \f$\mathrm{[W/(m K)]}\f$ - * \param lambdaN The thermal conductivity of the non-wetting phase in \f$\mathrm{[W/(m K)]}\f$ + * \param satLiquid The saturation of the liquid phase + * \param lambdaLiquid The thermal conductivity of the liquid phase in \f$\mathrm{[W/(m K)]}\f$ + * \param lambdaGas The thermal conductivity of the gas phase in \f$\mathrm{[W/(m K)]}\f$ * \param lambdaSolid The thermal conductivity of the solid phase in \f$\mathrm{[W/(m K)]}\f$ * \param porosity The porosity * \param rhoSolid The density of solid phase in \f$\mathrm{[kg/m^3]}\f$ * * \return effective thermal conductivity \f$\mathrm{[W/(m K)]}\f$ after Somerton (1974) \cite somerton1974 */ - static Scalar effectiveThermalConductivity(const Scalar sw, - const Scalar lambdaW, - const Scalar lambdaN, + static Scalar effectiveThermalConductivity(const Scalar satLiquid, + const Scalar lambdaLiquid, + const Scalar lambdaGas, const Scalar lambdaSolid, const Scalar porosity, const Scalar rhoSolid = 0.0 /*unused*/) @@ -116,13 +121,15 @@ public: using std::max; using std::pow; using std::sqrt; - const Scalar satW = max<Scalar>(0.0, sw); + const Scalar satLiquidPhysical = max<Scalar>(0.0, satLiquid); // geometric mean, using ls^(1-p)*l^p = ls*(l/ls)^p - const Scalar lSat = lambdaSolid * pow(lambdaW / lambdaSolid, porosity); - const Scalar lDry = lambdaSolid * pow(lambdaN / lambdaSolid, porosity); + const Scalar lSat = lambdaSolid * pow(lambdaLiquid / lambdaSolid, porosity); + const Scalar lDry = lambdaSolid * pow(lambdaGas / lambdaSolid, porosity); - return lDry + sqrt(satW) * (lSat - lDry); + return lDry + sqrt(satLiquidPhysical) * (lSat - lDry); } }; -} + +} // end namespace Dumux + #endif diff --git a/dumux/material/fluidstates/2p2c.hh b/dumux/material/fluidstates/2p2c.hh index f69efa52319bcbbda4bee0ffd73c275644aad265..91d746422ef8cf8636d1c9c5c9a2b916c4768288 100644 --- a/dumux/material/fluidstates/2p2c.hh +++ b/dumux/material/fluidstates/2p2c.hh @@ -40,8 +40,8 @@ class TwoPTwoCFluidState { public: enum { - wPhaseIdx = FluidSystem::wPhaseIdx, - nPhaseIdx = FluidSystem::nPhaseIdx, + phase0Idx = FluidSystem::phase0Idx, + phase1Idx = FluidSystem::phase1Idx, }; enum { numPhases = FluidSystem::numPhases, @@ -49,6 +49,13 @@ public: using PhaseVector = Dune::FieldVector<Scalar, numPhases>; public: + + // comply with new style 2p2c models + int wettingPhase() const + { + return phase0Idx; + } + /*! * \name access functions * \todo doc me! @@ -65,7 +72,7 @@ public: */ Scalar saturation(int phaseIdx) const { - if (phaseIdx == wPhaseIdx) + if (phaseIdx == phase0Idx) { return sw_; } @@ -124,7 +131,7 @@ public: */ Scalar partialPressure(int compIdx) const { - return partialPressure(nPhaseIdx, compIdx); + return partialPressure(phase1Idx, compIdx); } /*! @@ -146,7 +153,7 @@ public: * \brief Returns the capillary pressure \f$\mathrm{[Pa]}\f$ */ Scalar capillaryPressure() const - { return phasePressure_[nPhaseIdx] - phasePressure_[wPhaseIdx]; } + { return phasePressure_[phase1Idx] - phasePressure_[phase0Idx]; } /*! * \brief The temperature within the domain \f$\mathrm{[K]}\f$ @@ -181,8 +188,8 @@ public: using std::isnan; if (isnan(nu_[phaseIdx])) //in contrast to the standard update() method, satflash() does not calculate nu. { - nu_[wPhaseIdx] = sw_ * density_[wPhaseIdx] / (sw_ * density_[wPhaseIdx] + (1. - sw_) * density_[nPhaseIdx]); - nu_[nPhaseIdx] = 1. - nu_[wPhaseIdx]; + nu_[phase0Idx] = sw_ * density_[phase0Idx] / (sw_ * density_[phase0Idx] + (1. - sw_) * density_[phase1Idx]); + nu_[phase1Idx] = 1. - nu_[phase0Idx]; return nu_[phaseIdx]; } return nu_[phaseIdx]; @@ -247,7 +254,7 @@ public: */ void setSaturation(int phaseIdx, Scalar value) { - if (phaseIdx == wPhaseIdx) + if (phaseIdx == phase0Idx) sw_ = value; else sw_ = 1.-value; diff --git a/dumux/material/fluidstates/compositional.hh b/dumux/material/fluidstates/compositional.hh index 79d5198363b3bcfcdaf8e461d01cb0faaf5db213..2e065d34d191425cd8061f9d26d2ed559c3c6458 100644 --- a/dumux/material/fluidstates/compositional.hh +++ b/dumux/material/fluidstates/compositional.hh @@ -73,6 +73,14 @@ public: * Generic access to fluid properties (No assumptions * on thermodynamic equilibrium required) *****************************************************/ + /*! + * \brief Returns the index of the wetting phase in the + * fluid-solid configuration (for porous medium systems). + * + * \param phaseIdx the index of the phase + */ + int wettingPhase() const { return wPhaseIdx_; } + /*! * \brief Returns the saturation \f$S_\alpha\f$ of a fluid phase \f$\alpha\f$ in \f$\mathrm{[-]}\f$. * @@ -293,6 +301,7 @@ public: viscosity_[phaseIdx] = fs.viscosity(phaseIdx); } temperature_ = fs.temperature(0); + wPhaseIdx_ = fs.wettingPhase(); } /*! @@ -427,6 +436,12 @@ public: void setViscosity(int phaseIdx, Scalar value) { viscosity_[phaseIdx] = value; } + /*! + * \brief Set the index of the wetting phase + */ + void setWettingPhase(int phaseIdx) + { wPhaseIdx_ = phaseIdx; } + /*! * \brief Make sure that all attributes are defined. * @@ -467,6 +482,10 @@ protected: Scalar enthalpy_[numPhases]; Scalar viscosity_[numPhases]; Scalar temperature_; + + // For porous medium flow models, here we ... the index of the wetting + // phase (needed for vapor pressure evaluation if kelvin equation is used) + int wPhaseIdx_{0}; }; } // end namespace Dumux diff --git a/dumux/material/fluidstates/pseudo1p2c.hh b/dumux/material/fluidstates/pseudo1p2c.hh index 97f2549fe5c81938310fe32973ffb53a94a469fb..6a6b716867a73378ae5e2dca5b59c1894d1b920a 100644 --- a/dumux/material/fluidstates/pseudo1p2c.hh +++ b/dumux/material/fluidstates/pseudo1p2c.hh @@ -48,11 +48,11 @@ public: numComponents = FluidSystem::numComponents }; enum { - wPhaseIdx = FluidSystem::wPhaseIdx, - nPhaseIdx = FluidSystem::nPhaseIdx, + phase0Idx = FluidSystem::phase0Idx, + phase1Idx = FluidSystem::phase1Idx, - wCompIdx = FluidSystem::wPhaseIdx, - nCompIdx = FluidSystem::nPhaseIdx + comp0Idx = FluidSystem::comp0Idx, + comp1Idx = FluidSystem::comp1Idx }; public: @@ -90,7 +90,7 @@ public: */ Scalar partialPressure(int compIdx) const { - return partialPressure(nPhaseIdx, compIdx); + return partialPressure(phase1Idx, compIdx); } /*! @@ -145,7 +145,7 @@ public: } - if (compIdx == wPhaseIdx) + if (compIdx == phase0Idx) return massFractionWater_; else return 1.-massFractionWater_; @@ -172,7 +172,7 @@ public: return 0.; } - if (compIdx == wPhaseIdx) + if (compIdx == phase0Idx) return moleFractionWater_; else return 1.-moleFractionWater_; @@ -260,7 +260,7 @@ public: */ void setMassFraction(int phaseIdx, int compIdx, Scalar value) { - if (compIdx == wCompIdx) + if (compIdx == comp0Idx) massFractionWater_ = value; else massFractionWater_ = 1- value; @@ -275,7 +275,7 @@ public: */ void setMoleFraction(int phaseIdx, int compIdx, Scalar value) { - if (compIdx == wCompIdx) + if (compIdx == comp0Idx) moleFractionWater_ = value; else moleFractionWater_ = 1-value; diff --git a/dumux/material/fluidsystems/1pgas.hh b/dumux/material/fluidsystems/1pgas.hh index 57425a911109529f4653a1d5cae0bd48182a7cdd..1fec25b2523952da3027207a2ab37e5e73111308 100644 --- a/dumux/material/fluidsystems/1pgas.hh +++ b/dumux/material/fluidsystems/1pgas.hh @@ -32,11 +32,8 @@ #include <dumux/material/fluidsystems/base.hh> #include <dumux/material/components/componenttraits.hh> -namespace Dumux -{ - -namespace FluidSystems -{ +namespace Dumux { +namespace FluidSystems { /*! * \ingroup Fluidsystems @@ -55,11 +52,11 @@ public: using Component = ComponentT; using ParameterCache = NullParameterCache; - /**************************************** - * Fluid phase related static parameters - ****************************************/ - static constexpr int numPhases = 1; - static constexpr int numComponents = 1; + static constexpr int numPhases = 1; //!< Number of phases in the fluid system + static constexpr int numComponents = 1; //!< Number of components in the fluid system + + static constexpr int phase0Idx = 0; //!< index of the only phase + static constexpr int comp0Idx = 0; //!< index of the only component /*! * \brief Initialize the fluid system's static parameters generically @@ -67,6 +64,9 @@ public: static void init() { } + /**************************************** + * Fluid phase related static parameters + ****************************************/ /*! * \brief Return the human readable name of a fluid phase * diff --git a/dumux/material/fluidsystems/1pliquid.hh b/dumux/material/fluidsystems/1pliquid.hh index 96fa18d53ddaaa353246360143bd0b369b17930b..fce0b62962ffed276b308c1236d9b85d75abec07 100644 --- a/dumux/material/fluidsystems/1pliquid.hh +++ b/dumux/material/fluidsystems/1pliquid.hh @@ -32,10 +32,8 @@ #include <dumux/material/fluidsystems/base.hh> #include <dumux/material/components/componenttraits.hh> -namespace Dumux -{ -namespace FluidSystems -{ +namespace Dumux { +namespace FluidSystems { /*! * \ingroup Fluidsystems @@ -54,11 +52,11 @@ public: using Component = ComponentT; using ParameterCache = NullParameterCache; - /**************************************** - * Fluid phase related static parameters - ****************************************/ - static constexpr int numPhases = 1; - static constexpr int numComponents = 1; + static constexpr int numPhases = 1; //!< Number of phases in the fluid system + static constexpr int numComponents = 1; //!< Number of components in the fluid system + + static constexpr int phase0Idx = 0; //!< index of the only phase + static constexpr int comp0Idx = 0; //!< index of the only component /*! * \brief Initialize the fluid system's static parameters generically @@ -66,6 +64,9 @@ public: static void init() { } + /**************************************** + * Fluid phase related static parameters + ****************************************/ /*! * \brief Return the human readable name of a fluid phase * diff --git a/dumux/material/fluidsystems/2p1c.hh b/dumux/material/fluidsystems/2p1c.hh index 2dbda768b069ea59c9599a6799ad804e9a9be3a0..1bdba48a6e4c9a4f7f343efb7b077f64058afda2 100644 --- a/dumux/material/fluidsystems/2p1c.hh +++ b/dumux/material/fluidsystems/2p1c.hh @@ -30,10 +30,6 @@ #include <dune/common/exceptions.hh> -#include <dumux/material/fluidsystems/1pliquid.hh> -#include <dumux/material/fluidsystems/1pgas.hh> -#include <dumux/material/fluidstates/compositional.hh> - #include "base.hh" namespace Dumux { @@ -51,17 +47,19 @@ class TwoPOneC using Component = ComponentType; public: - /**************************************** - * Fluid phase related static parameters - ****************************************/ - - //! Number of phases in the fluid system - static constexpr int numPhases = 2; + static constexpr int numPhases = 2; //!< Number of phases in the fluid system + static constexpr int numComponents = 1; //!< Number of components in the fluid system - static constexpr int wPhaseIdx = 0; // index of the wetting phase - static constexpr int nPhaseIdx = 1; // index of the non-wetting phase + static constexpr int liquidPhaseIdx = 0; //!< index of the liquid phase + static constexpr int gasPhaseIdx = 1; //!< index of the gas phase + static constexpr int phase0Idx = liquidPhaseIdx; //!< index of the first phase + static constexpr int phase1Idx = gasPhaseIdx; //!< index of the second phase + static constexpr int comp0Idx = 0; //!< index of the only component + /**************************************** + * Fluid phase related static parameters + ****************************************/ /*! * \brief Return the human readable name of a fluid phase * @@ -89,10 +87,10 @@ public: * * \param phaseIdx The index of the fluid phase to consider */ - static bool isLiquid(int phaseIdx) + static constexpr bool isLiquid(int phaseIdx) { assert(0 <= phaseIdx && phaseIdx < numPhases); - return phaseIdx == wPhaseIdx; + return phaseIdx == liquidPhaseIdx; } /*! @@ -109,7 +107,7 @@ public: * * \param phaseIdx The index of the fluid phase to consider */ - static bool isIdealMixture(int phaseIdx) + static constexpr bool isIdealMixture(int phaseIdx) { assert(0 <= phaseIdx && phaseIdx < numPhases); // we assume Henry's and Raoult's laws for the water phase and @@ -131,7 +129,7 @@ public: { assert(0 <= phaseIdx && phaseIdx < numPhases); // gases are always compressible - if (phaseIdx == nPhaseIdx) + if (phaseIdx == gasPhaseIdx) return true; // the component decides for the liquid phase... return Component::liquidIsCompressible(); @@ -143,11 +141,11 @@ public: * * \param phaseIdx The index of the fluid phase to consider */ - static bool isIdealGas(int phaseIdx) + static constexpr bool isIdealGas(int phaseIdx) { assert(0 <= phaseIdx && phaseIdx < numPhases); - if (phaseIdx == nPhaseIdx) + if (phaseIdx == gasPhaseIdx) // let the components decide return Component::gasIsIdeal(); return false; // not a gas @@ -157,12 +155,6 @@ public: * Component related static parameters ****************************************/ - //! Number of components in the fluid system - static constexpr int numComponents = 1; - - static constexpr int ComponentIdx = 0; - - /*! * \brief Return the human readable name of a component * @@ -291,10 +283,10 @@ public: Scalar p = fluidState.pressure(phaseIdx); // liquid phase - if (phaseIdx == wPhaseIdx) { + if (phaseIdx == liquidPhaseIdx) { return Component::liquidDensity(T, p); } - else if (phaseIdx == nPhaseIdx)// gas phase + else if (phaseIdx == gasPhaseIdx)// gas phase { return Component::gasDensity(T, p); } @@ -319,10 +311,10 @@ public: Scalar p = fluidState.pressure(phaseIdx); // liquid phase - if (phaseIdx == wPhaseIdx) { + if (phaseIdx == liquidPhaseIdx) { return Component::liquidViscosity(T, p); } - else if (phaseIdx == nPhaseIdx) // gas phase + else if (phaseIdx == gasPhaseIdx) // gas phase { return Component::gasViscosity(T, p) ; } @@ -341,7 +333,7 @@ public: const unsigned int phaseIdx) { assert(0 <= phaseIdx && phaseIdx < numPhases); - Scalar pressure = fluidState.pressure(nPhaseIdx) ; + Scalar pressure = fluidState.pressure(gasPhaseIdx) ; return Component::vaporTemperature(pressure) ; } @@ -386,7 +378,7 @@ public: Scalar p = fluidState.pressure(phaseIdx); // liquid phase - if (phaseIdx == wPhaseIdx) + if (phaseIdx == liquidPhaseIdx) return Component::vaporPressure(T)/p; // for the gas phase, assume an ideal gas when it comes to @@ -449,11 +441,11 @@ public: assert(0 <= phaseIdx && phaseIdx < numPhases); // liquid phase - if (phaseIdx == wPhaseIdx) { + if (phaseIdx == liquidPhaseIdx) { return Component::liquidEnthalpy(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx)); } - else if (phaseIdx == nPhaseIdx) // gas phase + else if (phaseIdx == gasPhaseIdx) // gas phase { return Component::gasEnthalpy(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx)); @@ -477,11 +469,11 @@ public: { assert(0 <= phaseIdx && phaseIdx < numPhases); // liquid phase - if (phaseIdx == wPhaseIdx) { + if (phaseIdx == liquidPhaseIdx) { return Component::liquidThermalConductivity(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx)); //0.68 ; } - else if (phaseIdx == nPhaseIdx) // gas phase + else if (phaseIdx == gasPhaseIdx) // gas phase { return Component::gasThermalConductivity(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx)); //0.0248; @@ -504,11 +496,11 @@ public: { assert(0 <= phaseIdx && phaseIdx < numPhases); // liquid phase - if (phaseIdx == wPhaseIdx) { + if (phaseIdx == liquidPhaseIdx) { return Component::liquidHeatCapacity(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx));//4.217e3 ; } - else if (phaseIdx == nPhaseIdx) // gas phase + else if (phaseIdx == gasPhaseIdx) // gas phase { return Component::gasHeatCapacity(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx));//2.029e3; diff --git a/dumux/material/fluidsystems/2pimmiscible.hh b/dumux/material/fluidsystems/2pimmiscible.hh index 5b66a4eadd86b9576f986671fba0d2551fb38aec..db9c3cf2e7b93b35201b766871689cdf7787ebfd 100644 --- a/dumux/material/fluidsystems/2pimmiscible.hh +++ b/dumux/material/fluidsystems/2pimmiscible.hh @@ -45,38 +45,38 @@ namespace FluidSystems { * * The fluid phases are completely specified by means of their * constituting components. - * The wetting and the non-wetting fluids can be defined individually - * via FluidSystem::OnePLiquid<Scalar, Component> and - * FluidSystem::OnePGas<Scalar, Component>. These fluids consist of one pure - * component. + * The fluids can be defined individually via FluidSystem::OnePLiquid<Scalar, Component> and + * FluidSystem::OnePGas<Scalar, Component>. These fluids consist of one component. * \tparam Scalar the scalar type - * \tparam WettingFluid the wetting phase fluid system (use FluidSystem::OnePLiquid<Scalar, Component> / FluidSystem::OnePGas<Scalar, Component>) - * \tparam NonwettingFluid the wetting phase fluid system (use FluidSystem::OnePLiquid<Scalar, Component> / FluidSystem::OnePGas<Scalar, Component>) + * \tparam Fluid0 a one-phase fluid system (use FluidSystem::OnePLiquid<Scalar, Component> / FluidSystem::OnePGas<Scalar, Component>) + * \tparam Fluid1 a one-phase fluid system (use FluidSystem::OnePLiquid<Scalar, Component> / FluidSystem::OnePGas<Scalar, Component>) */ -template <class Scalar, class WettingFluid, class NonwettingFluid> +template <class Scalar, class Fluid0, class Fluid1> class TwoPImmiscible -: public BaseFluidSystem<Scalar, TwoPImmiscible<Scalar, WettingFluid, NonwettingFluid> > +: public BaseFluidSystem<Scalar, TwoPImmiscible<Scalar, Fluid0, Fluid1> > { - static_assert((WettingFluid::numPhases == 1), "WettingFluid has more than one phase"); - static_assert((NonwettingFluid::numPhases == 1), "NonwettingFluid has more than one phase"); - static_assert((WettingFluid::numComponents == 1), "WettingFluid has more than one component"); - static_assert((NonwettingFluid::numComponents == 1), "NonwettingFluid has more than one component"); - - using ThisType = TwoPImmiscible<Scalar, WettingFluid, NonwettingFluid>; + static_assert((Fluid0::numPhases == 1), "Fluid0 has more than one phase"); + static_assert((Fluid1::numPhases == 1), "Fluid1 has more than one phase"); + static_assert((Fluid0::numComponents == 1), "Fluid0 has more than one component"); + static_assert((Fluid1::numComponents == 1), "Fluid1 has more than one component"); + // two gaseous phases at once do not make sense physically! (but two liquids are fine) + static_assert(Fluid0::isLiquid() || Fluid1::isLiquid(), "One phase has to be a liquid!"); + + using ThisType = TwoPImmiscible<Scalar, Fluid0, Fluid1>; using Base = BaseFluidSystem<Scalar, ThisType>; + public: + static constexpr int numPhases = 2; //!< Number of phases in the fluid system + static constexpr int numComponents = 2; //!< Number of components in the fluid system + + static constexpr int phase0Idx = 0; //!< index of the first phase + static constexpr int phase1Idx = 1; //!< index of the second phase + static constexpr int comp0Idx = 0; //!< index of the frist component + static constexpr int comp1Idx = 1; //!< index of the second component + /**************************************** * Fluid phase related static parameters ****************************************/ - - //! Number of phases in the fluid system - static constexpr int numPhases = 2; - - //! Index of the wetting phase - static constexpr int wPhaseIdx = 0; - //! Index of the non-wetting phase - static constexpr int nPhaseIdx = 1; - /*! * \brief Return the human readable name of a fluid phase * \param phaseIdx The index of the fluid phase to consider @@ -85,11 +85,10 @@ public: { assert(0 <= phaseIdx && phaseIdx < numPhases); - static std::string name[] = { - std::string("w"), - std::string("n") - }; - return name[phaseIdx]; + if (phaseIdx == phase0Idx) + return Fluid0::phaseName(); + else + return Fluid1::phaseName(); } /*! @@ -102,13 +101,13 @@ public: * \brief Return whether a phase is liquid * \param phaseIdx The index of the fluid phase to consider */ - static bool isLiquid(int phaseIdx) + static constexpr bool isLiquid(int phaseIdx) { assert(0 <= phaseIdx && phaseIdx < numPhases); - if (phaseIdx == wPhaseIdx) - return WettingFluid::isLiquid(); - return NonwettingFluid::isLiquid(); + if (phaseIdx == phase0Idx) + return Fluid0::isLiquid(); + return Fluid1::isLiquid(); } /*! @@ -132,6 +131,22 @@ public: return true; } + /*! + * \brief Returns true if and only if a fluid phase is assumed to + * be an ideal gas. + * + * \param phaseIdx The index of the fluid phase to consider + */ + static constexpr bool isIdealGas(int phaseIdx) + { + assert(0 <= phaseIdx && phaseIdx < numPhases); + + // let the fluids decide + if (phaseIdx == phase0Idx) + return Fluid0::isIdealGas(); + return Fluid1::isIdealGas(); + } + /*! * \brief Returns true if and only if a fluid phase is assumed to * be compressible. @@ -146,9 +161,9 @@ public: assert(0 <= phaseIdx && phaseIdx < numPhases); // let the fluids decide - if (phaseIdx == wPhaseIdx) - return WettingFluid::isCompressible(); - return NonwettingFluid::isCompressible(); + if (phaseIdx == phase0Idx) + return Fluid0::isCompressible(); + return Fluid1::isCompressible(); } /*! @@ -161,9 +176,9 @@ public: assert(0 <= phaseIdx && phaseIdx < numPhases); // let the fluids decide - if (phaseIdx == wPhaseIdx) - return WettingFluid::viscosityIsConstant(); - return NonwettingFluid::viscosityIsConstant(); + if (phaseIdx == phase0Idx) + return Fluid0::viscosityIsConstant(); + return Fluid1::viscosityIsConstant(); } /*! @@ -172,28 +187,19 @@ public: * * \param phaseIdx The index of the fluid phase to consider */ - static bool isIdealGas(int phaseIdx) + static bool isIdealFluid1(int phaseIdx) { assert(0 <= phaseIdx && phaseIdx < numPhases); // let the fluids decide - if (phaseIdx == wPhaseIdx) - return WettingFluid::isIdealGas(); - return NonwettingFluid::isIdealGas(); + if (phaseIdx == phase0Idx) + return Fluid0::isIdealFluid1(); + return Fluid1::isIdealFluid1(); } /**************************************** * Component related static parameters ****************************************/ - - //! Number of components in the fluid system - static constexpr int numComponents = 2; - - //! Index of the wetting phase's component - static constexpr int wCompIdx = 0; - //! Index of the non-wetting phase's component - static constexpr int nCompIdx = 1; - /*! * \brief Return the human readable name of a component * @@ -203,9 +209,9 @@ public: { assert(0 <= compIdx && compIdx < numComponents); - if (compIdx == wCompIdx) - return WettingFluid::name(); - return NonwettingFluid::name(); + if (compIdx == comp0Idx) + return Fluid0::name(); + return Fluid1::name(); } /*! @@ -216,9 +222,9 @@ public: { assert(0 <= compIdx && compIdx < numComponents); - if (compIdx == wCompIdx) - return WettingFluid::molarMass(); - return NonwettingFluid::molarMass(); + if (compIdx == comp0Idx) + return Fluid0::molarMass(); + return Fluid1::molarMass(); } /*! @@ -229,9 +235,9 @@ public: { assert(0 <= compIdx && compIdx < numComponents); - if (compIdx == wCompIdx) - return WettingFluid::criticalTemperature(); - return NonwettingFluid::criticalTemperature(); + if (compIdx == comp0Idx) + return Fluid0::criticalTemperature(); + return Fluid1::criticalTemperature(); } /*! @@ -242,9 +248,9 @@ public: { assert(0 <= compIdx && compIdx < numComponents); - if (compIdx == wCompIdx) - return WettingFluid::criticalPressure(); - return NonwettingFluid::criticalPressure(); + if (compIdx == comp0Idx) + return Fluid0::criticalPressure(); + return Fluid1::criticalPressure(); } /*! @@ -255,9 +261,9 @@ public: { assert(0 <= compIdx && compIdx < numComponents); - if (compIdx == wCompIdx) - return WettingFluid::acentricFactor(); - return NonwettingFluid::acentricFactor(); + if (compIdx == comp0Idx) + return Fluid0::acentricFactor(); + return Fluid1::acentricFactor(); } /**************************************** @@ -268,11 +274,7 @@ public: * \brief Initialize the fluid system's static parameters */ static void init() - { - // two gaseous phases at once do not make sense physically! - // (But two liquids are fine) - assert(WettingFluid::isLiquid() || NonwettingFluid::isLiquid()); - } + {} using Base::density; /*! @@ -287,9 +289,9 @@ public: Scalar temperature = fluidState.temperature(phaseIdx); Scalar pressure = fluidState.pressure(phaseIdx); - if (phaseIdx == wPhaseIdx) - return WettingFluid::density(temperature, pressure); - return NonwettingFluid::density(temperature, pressure); + if (phaseIdx == phase0Idx) + return Fluid0::density(temperature, pressure); + return Fluid1::density(temperature, pressure); } using Base::viscosity; @@ -306,9 +308,9 @@ public: Scalar temperature = fluidState.temperature(phaseIdx); Scalar pressure = fluidState.pressure(phaseIdx); - if (phaseIdx == wPhaseIdx) - return WettingFluid::viscosity(temperature, pressure); - return NonwettingFluid::viscosity(temperature, pressure); + if (phaseIdx == phase0Idx) + return Fluid0::viscosity(temperature, pressure); + return Fluid1::viscosity(temperature, pressure); } using Base::fugacityCoefficient; @@ -414,9 +416,9 @@ public: Scalar temperature = fluidState.temperature(phaseIdx); Scalar pressure = fluidState.pressure(phaseIdx); - if (phaseIdx == wPhaseIdx) - return WettingFluid::enthalpy(temperature, pressure); - return NonwettingFluid::enthalpy(temperature, pressure); + if (phaseIdx == phase0Idx) + return Fluid0::enthalpy(temperature, pressure); + return Fluid1::enthalpy(temperature, pressure); } using Base::thermalConductivity; @@ -433,9 +435,9 @@ public: Scalar temperature = fluidState.temperature(phaseIdx); Scalar pressure = fluidState.pressure(phaseIdx); - if (phaseIdx == wPhaseIdx) - return WettingFluid::thermalConductivity(temperature, pressure); - return NonwettingFluid::thermalConductivity(temperature, pressure); + if (phaseIdx == phase0Idx) + return Fluid0::thermalConductivity(temperature, pressure); + return Fluid1::thermalConductivity(temperature, pressure); } using Base::heatCapacity; @@ -458,9 +460,9 @@ public: Scalar temperature = fluidState.temperature(phaseIdx); Scalar pressure = fluidState.pressure(phaseIdx); - if (phaseIdx == wPhaseIdx) - return WettingFluid::heatCapacity(temperature, pressure); - return NonwettingFluid::heatCapacity(temperature, pressure); + if (phaseIdx == phase0Idx) + return Fluid0::heatCapacity(temperature, pressure); + return Fluid1::heatCapacity(temperature, pressure); } }; diff --git a/dumux/material/fluidsystems/brineair.hh b/dumux/material/fluidsystems/brineair.hh index 7597e2ec6c5d9de2ab4700954614c344fd4426bd..ca54b4ba99799ceaff055fb9e6f062a38f5ded47 100644 --- a/dumux/material/fluidsystems/brineair.hh +++ b/dumux/material/fluidsystems/brineair.hh @@ -60,13 +60,12 @@ class BrineAir using IdealGas = Dumux::IdealGas<Scalar>; public: - using H2O = H2Otype; + using Air = Components::Air<Scalar>; + using Brine = Components::Brine<Scalar, H2Otype>; + using NaCl = Components::NaCl<Scalar>; using H2O_Air = BinaryCoeff::H2O_Air; - using Air = Dumux::Components::Air<Scalar>; using Brine_Air = BinaryCoeff::Brine_Air<Scalar, Air>; - using Brine = Dumux::Components::Brine<Scalar,H2Otype>; - using NaCl = Dumux::Components::NaCl<Scalar>; // the type of parameter cache objects. this fluid system does not using ParameterCache = NullParameterCache; @@ -74,19 +73,25 @@ public: /**************************************** * Fluid phase related static parameters ****************************************/ - static const int numPhases = 2; // liquid and gas phases - static const int numSPhases = 1;// precipitated solid phases - static const int lPhaseIdx = 0; // index of the liquid phase - static const int gPhaseIdx = 1; // index of the gas phase - static const int sPhaseIdx = 2; // index of the precipitated salt - static const int wPhaseIdx = lPhaseIdx; // index of the wetting phase - static const int nPhaseIdx = gPhaseIdx; // index of the non-wetting phase + static constexpr int numPhases = 2; // liquid and gas phases + static constexpr int numComponents = 3; // H2O, Air, NaCl + static constexpr int numSPhases = 1;// precipitated solid phases // TODO: remove + + static constexpr int liquidPhaseIdx = 0; // index of the liquid phase + static constexpr int gasPhaseIdx = 1; // index of the gas phase + static constexpr int solidPhaseIdx = 2; // index of the precipitated salt // TODO: remove + + static constexpr int phase0Idx = liquidPhaseIdx; // index of the first phase + static constexpr int phase1Idx = gasPhaseIdx; // index of the second phase // export component indices to indicate the main component // of the corresponding phase at atmospheric pressure 1 bar // and room temperature 20°C: - static const int wCompIdx = wPhaseIdx; - static const int nCompIdx = nPhaseIdx; + static constexpr int H2OIdx = 0; + static constexpr int AirIdx = 1; + static constexpr int comp0Idx = H2OIdx; + static constexpr int comp1Idx = AirIdx; + static constexpr int NaClIdx = 2; // TODO: remove /*! * \brief Return the human readable name of a fluid phase @@ -96,9 +101,9 @@ public: static std::string phaseName(int phaseIdx) { switch (phaseIdx) { - case wPhaseIdx: return "liquid"; - case nPhaseIdx: return "gas"; - case sPhaseIdx: return "NaCl"; + case phase0Idx: return "liquid"; + case phase1Idx: return "gas"; + case solidPhaseIdx: return "NaCl"; } DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx); } @@ -118,7 +123,7 @@ public: { assert(0 <= phaseIdx && phaseIdx < numPhases); - return phaseIdx != nPhaseIdx; + return phaseIdx != phase1Idx; } /*! @@ -158,7 +163,7 @@ public: { assert(0 <= phaseIdx && phaseIdx < numPhases); // ideal gases are always compressible - if (phaseIdx == nPhaseIdx) + if (phaseIdx == phase1Idx) return true; // the water component decides for the liquid phase... return H2O::liquidIsCompressible(); @@ -175,7 +180,7 @@ public: assert(0 <= phaseIdx && phaseIdx < numPhases); // let the fluids decide - if (phaseIdx == nPhaseIdx) + if (phaseIdx == phase1Idx) return H2O::gasIsIdeal() && Air::gasIsIdeal(); return false; // not a gas } @@ -183,12 +188,6 @@ public: /**************************************** * Component related static parameters ****************************************/ - static const int numComponents = 3; // H2O, Air, NaCl - - static const int H2OIdx = wCompIdx;//0 - static const int AirIdx = nCompIdx;//1 - static const int NaClIdx = 2; - /*! * \brief Return the human readable name of a component * @@ -228,8 +227,8 @@ public: */ static Scalar precipitateDensity(int phaseIdx) { - if(phaseIdx != sPhaseIdx) - DUNE_THROW(Dune::InvalidStateException, "Invalid solid phase index " << sPhaseIdx); + if(phaseIdx != solidPhaseIdx) + DUNE_THROW(Dune::InvalidStateException, "Invalid solid phase index " << solidPhaseIdx); return NaCl::density(); } @@ -336,14 +335,14 @@ public: Scalar pressure = fluidState.pressure(phaseIdx); switch (phaseIdx) { - case lPhaseIdx: + case liquidPhaseIdx: return Brine::liquidDensity(temperature, pressure, - fluidState.massFraction(lPhaseIdx, NaClIdx)); - case gPhaseIdx: + fluidState.massFraction(liquidPhaseIdx, NaClIdx)); + case gasPhaseIdx: return gasDensity_(temperature, pressure, - fluidState.moleFraction(gPhaseIdx, H2OIdx)); + fluidState.moleFraction(gasPhaseIdx, H2OIdx)); default: DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx); @@ -372,12 +371,12 @@ public: Scalar pressure = fluidState.pressure(phaseIdx); Scalar result = 0; - if (phaseIdx == lPhaseIdx) + if (phaseIdx == liquidPhaseIdx) { - Scalar XNaCl = fluidState.massFraction(lPhaseIdx, NaClIdx); + Scalar XNaCl = fluidState.massFraction(liquidPhaseIdx, NaClIdx); result = Brine::liquidViscosity(temperature, pressure, XNaCl); } - else if (phaseIdx == gPhaseIdx) + else if (phaseIdx == gasPhaseIdx) { result = Air::gasViscosity(temperature, pressure); } @@ -423,10 +422,10 @@ public: assert(T > 0); assert(p > 0); - if (phaseIdx == gPhaseIdx) + if (phaseIdx == gasPhaseIdx) return 1.0; - else if (phaseIdx == lPhaseIdx) + else if (phaseIdx == liquidPhaseIdx) { if (compIdx == H2OIdx) return Brine::vaporPressure(T)/p; @@ -439,15 +438,6 @@ public: DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx); } - template <class FluidState> - static Scalar kelvinVaporPressure(const FluidState &fluidState, - const int phaseIdx, - const int compIdx) - { - DUNE_THROW(Dune::NotImplemented, "FluidSystems::BrineAir::kelvinVaporPressure()"); - } - - using Base::diffusionCoefficient; template <class FluidState> static Scalar diffusionCoefficient(const FluidState &fluidState, @@ -481,7 +471,7 @@ public: Scalar temperature = fluidState.temperature(phaseIdx); Scalar pressure = fluidState.pressure(phaseIdx); - if (phaseIdx == lPhaseIdx) { + if (phaseIdx == liquidPhaseIdx) { Scalar result = 0.0; if(compJIdx == AirIdx) result = Brine_Air::liquidDiffCoeff(temperature, pressure); @@ -495,7 +485,7 @@ public: return result; } else { - assert(phaseIdx == gPhaseIdx); + assert(phaseIdx == gasPhaseIdx); if (compIIdx != AirIdx) { @@ -546,7 +536,7 @@ public: Scalar T = fluidState.temperature(phaseIdx); Scalar p = fluidState.pressure(phaseIdx); - if (phaseIdx == lPhaseIdx) + if (phaseIdx == liquidPhaseIdx) { Scalar XlNaCl = fluidState.massFraction(phaseIdx, NaClIdx); Scalar result = Brine::liquidEnthalpy(T, p, XlNaCl); @@ -555,8 +545,8 @@ public: } else { - Scalar XAir = fluidState.massFraction(gPhaseIdx, AirIdx); - Scalar XH2O = fluidState.massFraction(gPhaseIdx, H2OIdx); + Scalar XAir = fluidState.massFraction(gasPhaseIdx, AirIdx); + Scalar XH2O = fluidState.massFraction(gasPhaseIdx, H2OIdx); Scalar result = 0; result += XH2O * H2O::gasEnthalpy(T, p); @@ -577,16 +567,16 @@ public: int phaseIdx, int componentIdx) { - Scalar T = fluidState.temperature(nPhaseIdx); - Scalar p = fluidState.pressure(nPhaseIdx); + Scalar T = fluidState.temperature(phase1Idx); + Scalar p = fluidState.pressure(phase1Idx); Valgrind::CheckDefined(T); Valgrind::CheckDefined(p); - if (phaseIdx == wPhaseIdx) + if (phaseIdx == phase0Idx) { DUNE_THROW(Dune::NotImplemented, "The component enthalpies in the liquid phase are not implemented."); } - else if (phaseIdx == nPhaseIdx) + else if (phaseIdx == phase1Idx) { if (componentIdx == H2OIdx) { @@ -616,7 +606,7 @@ public: static Scalar thermalConductivity(const FluidState &fluidState, int phaseIdx) { - if (phaseIdx == lPhaseIdx) + if (phaseIdx == liquidPhaseIdx) return H2O::liquidThermalConductivity(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx)); else // gas phase @@ -641,14 +631,14 @@ public: { const Scalar temperature = fluidState.temperature(phaseIdx); const Scalar pressure = fluidState.pressure(phaseIdx); - if (phaseIdx == wPhaseIdx) + if (phaseIdx == phase0Idx) { return H2O::liquidHeatCapacity(temperature, pressure); } - else if (phaseIdx == nPhaseIdx) + else if (phaseIdx == phase1Idx) { - return Air::gasHeatCapacity(temperature, pressure) * fluidState.moleFraction(nPhaseIdx, AirIdx) - + H2O::gasHeatCapacity(temperature, pressure) * fluidState.moleFraction(nPhaseIdx, H2OIdx); + return Air::gasHeatCapacity(temperature, pressure) * fluidState.moleFraction(phase1Idx, AirIdx) + + H2O::gasHeatCapacity(temperature, pressure) * fluidState.moleFraction(phase1Idx, H2OIdx); } else DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx); diff --git a/dumux/material/fluidsystems/brineco2.hh b/dumux/material/fluidsystems/brineco2.hh index 81d2be0181d109480363b36efa0356a0a8a78270..c63188902bab4ba31a2824efc0e466c1bc534e1b 100644 --- a/dumux/material/fluidsystems/brineco2.hh +++ b/dumux/material/fluidsystems/brineco2.hh @@ -66,17 +66,20 @@ public: using Brine = Brinetype; using CO2 = Dumux::Components::CO2<Scalar, CO2Table>; - static const int numComponents = 2; - static const int numPhases = 2; - - static const int wPhaseIdx = 0; // index of the liquid phase - static const int nPhaseIdx = 1; // index of the gas phase - static const int wCompIdx = 0; - static const int nCompIdx = 1; - static const int lCompIdx = wCompIdx; - static const int gCompIdx = nCompIdx; - static const int BrineIdx = wCompIdx; - static const int CO2Idx = nCompIdx; + static constexpr int numComponents = 2; + static constexpr int numPhases = 2; + + static constexpr int phase0Idx = 0; // index of the first phase + static constexpr int phase1Idx = 1; // index of the second phase + + static constexpr int comp0Idx = 0; + static constexpr int comp1Idx = 1; + + static constexpr int liquidPhaseIdx = phase0Idx; + static constexpr int gasPhaseIdx = phase1Idx; + + static constexpr int BrineIdx = comp0Idx; + static constexpr int CO2Idx = comp1Idx; /*! * \brief Return the human readable name of a fluid phase @@ -105,11 +108,11 @@ public: * * \param phaseIdx The index of the fluid phase to consider */ - static bool isLiquid(int phaseIdx) + static constexpr bool isLiquid(int phaseIdx) { assert(0 <= phaseIdx && phaseIdx < numPhases); - return phaseIdx != nPhaseIdx; + return phaseIdx != phase1Idx; } /*! @@ -262,14 +265,14 @@ public: Scalar temperature = fluidState.temperature(phaseIdx); Scalar pressure = fluidState.pressure(phaseIdx); - if (phaseIdx == wPhaseIdx) { + if (phaseIdx == phase0Idx) { // use normalized composition for to calculate the density // (the relations don't seem to take non-normalized // compositions too well...) using std::min; using std::max; - Scalar xlBrine = min(1.0, max(0.0, fluidState.moleFraction(wPhaseIdx, BrineIdx))); - Scalar xlCO2 = min(1.0, max(0.0, fluidState.moleFraction(wPhaseIdx, CO2Idx))); + Scalar xlBrine = min(1.0, max(0.0, fluidState.moleFraction(phase0Idx, BrineIdx))); + Scalar xlCO2 = min(1.0, max(0.0, fluidState.moleFraction(phase0Idx, CO2Idx))); Scalar sumx = xlBrine + xlCO2; xlBrine /= sumx; xlCO2 /= sumx; @@ -283,15 +286,15 @@ public: return result; } else { - assert(phaseIdx == nPhaseIdx); + assert(phaseIdx == phase1Idx); // use normalized composition for to calculate the density // (the relations don't seem to take non-normalized // compositions too well...) using std::min; using std::max; - Scalar xgBrine = min(1.0, max(0.0, fluidState.moleFraction(nPhaseIdx, BrineIdx))); - Scalar xgCO2 = min(1.0, max(0.0, fluidState.moleFraction(nPhaseIdx, CO2Idx))); + Scalar xgBrine = min(1.0, max(0.0, fluidState.moleFraction(phase1Idx, BrineIdx))); + Scalar xgCO2 = min(1.0, max(0.0, fluidState.moleFraction(phase1Idx, CO2Idx))); Scalar sumx = xgBrine + xgCO2; xgBrine /= sumx; xgCO2 /= sumx; @@ -326,7 +329,7 @@ public: Scalar pressure = fluidState.pressure(phaseIdx); Scalar result = 0; - if (phaseIdx == wPhaseIdx) + if (phaseIdx == phase0Idx) result = Brine::liquidViscosity(temperature, pressure); else result = CO2::gasViscosity(temperature, pressure); @@ -370,7 +373,7 @@ public: assert(0 <= phaseIdx && phaseIdx < numPhases); assert(0 <= compIdx && compIdx < numComponents); - if (phaseIdx == nPhaseIdx) + if (phaseIdx == phase1Idx) // use the fugacity coefficients of an ideal gas. the // actual value of the fugacity is not relevant, as long // as the relative fluid compositions are observed, @@ -388,7 +391,7 @@ public: Brine_CO2::calculateMoleFractions(temperature, pressure, BrineRawComponent::salinity, - /*knownPhaseIdx=*/-1, + /*knowphase1Idx=*/-1, xlCO2, xgH2O); @@ -439,11 +442,11 @@ public: Brine_CO2::calculateMoleFractions(temperature, pressure, BrineRawComponent::constantSalinity, - /*knownPhaseIdx=*/-1, + /*knowphase1Idx=*/-1, xlCO2, xgH2O); - if(phaseIdx == nPhaseIdx) + if(phaseIdx == phase1Idx) { return xgH2O; } @@ -515,7 +518,7 @@ public: Scalar temperature = fluidState.temperature(phaseIdx); Scalar pressure = fluidState.pressure(phaseIdx); - if (phaseIdx == wPhaseIdx) { + if (phaseIdx == phase0Idx) { assert(compIIdx == BrineIdx); assert(compJIdx == CO2Idx); @@ -524,7 +527,7 @@ public: return result; } else { - assert(phaseIdx == nPhaseIdx); + assert(phaseIdx == phase1Idx); assert(compIIdx == BrineIdx); assert(compJIdx == CO2Idx); @@ -550,7 +553,7 @@ public: Scalar temperature = fluidState.temperature(phaseIdx); Scalar pressure = fluidState.pressure(phaseIdx); - if (phaseIdx == wPhaseIdx) { + if (phaseIdx == phase0Idx) { Scalar XlCO2 = fluidState.massFraction(phaseIdx, CO2Idx); Scalar result = liquidEnthalpyBrineCO2_(temperature, @@ -564,10 +567,10 @@ public: Scalar result = 0; result += Brine::gasEnthalpy(temperature, pressure) * - fluidState.massFraction(nPhaseIdx, BrineIdx); + fluidState.massFraction(phase1Idx, BrineIdx); result += CO2::gasEnthalpy(temperature, pressure) * - fluidState.massFraction(nPhaseIdx, CO2Idx); + fluidState.massFraction(phase1Idx, CO2Idx); Valgrind::CheckDefined(result); return result; } @@ -587,7 +590,7 @@ public: static Scalar thermalConductivity(const FluidState &fluidState, int phaseIdx) { - if (phaseIdx == wPhaseIdx) + if (phaseIdx == phase0Idx) { return H2O::liquidThermalConductivity(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx)); @@ -612,7 +615,7 @@ public: static Scalar heatCapacity(const FluidState &fluidState, int phaseIdx) { - if(phaseIdx == wPhaseIdx) + if(phaseIdx == phase0Idx) return H2O::liquidHeatCapacity(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx)); else diff --git a/dumux/material/fluidsystems/h2oair.hh b/dumux/material/fluidsystems/h2oair.hh index 2fad865ceda666fd6395268fa635edd0c126972e..77d5b173610f1fdce75a7088c5720f618540873e 100644 --- a/dumux/material/fluidsystems/h2oair.hh +++ b/dumux/material/fluidsystems/h2oair.hh @@ -54,7 +54,8 @@ namespace FluidSystems { */ template <class Scalar, class H2Otype = Components::TabulatedComponent<Components::H2O<Scalar> >, - bool useComplexRelations = true> + bool useComplexRelations = true, + bool useKelvinVaporPressure = false> class H2OAir : public BaseFluidSystem<Scalar, H2OAir<Scalar, H2Otype, useComplexRelations> > { @@ -66,16 +67,20 @@ public: using H2O = H2Otype; using Air = Dumux::Components::Air<Scalar>; - static constexpr int numPhases = 2; + static constexpr int numPhases = 2; //!< Number of phases in the fluid system + static constexpr int numComponents = 2; //!< Number of components in the fluid system - static constexpr int wPhaseIdx = 0; // index of the water phase - static constexpr int nPhaseIdx = 1; // index of the air phase + static constexpr int liquidPhaseIdx = 0; //!< index of the first phase + static constexpr int gasPhaseIdx = 1; //!< index of the second phase + static constexpr int phase0Idx = liquidPhaseIdx; //!< index of the first phase + static constexpr int phase1Idx = gasPhaseIdx; //!< index of the second phase - // export component indices to indicate the main component - // of the corresponding phase at atmospheric pressure 1 bar - // and room temperature 20°C: - static const int wCompIdx = wPhaseIdx; - static const int nCompIdx = nPhaseIdx; + static constexpr int H2OIdx = 0; //!< index of the frist component + static constexpr int AirIdx = 1; //!< index of the second component + static constexpr int comp0Idx = H2OIdx; //!< index of the frist component + static constexpr int comp1Idx = AirIdx; //!< index of the second component + static constexpr int liquidCompIdx = H2OIdx; //!< index of the liquid component + static constexpr int gasCompIdx = AirIdx; //!< index of the gas component /*! * \brief Return the human readable name of a phase @@ -85,8 +90,8 @@ public: static std::string phaseName(int phaseIdx) { switch (phaseIdx) { - case wPhaseIdx: return "liquid"; - case nPhaseIdx: return "gas"; + case phase0Idx: return "liquid"; + case phase1Idx: return "gas"; } DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx); } @@ -102,10 +107,10 @@ public: * * \param phaseIdx The index of the fluid phase to consider */ - static bool isLiquid(int phaseIdx) + static constexpr bool isLiquid(int phaseIdx) { assert(0 <= phaseIdx && phaseIdx < numPhases); - return phaseIdx != nPhaseIdx; + return phaseIdx != phase1Idx; } /*! @@ -113,10 +118,10 @@ public: * * \param phaseIdx The index of the fluid phase to consider */ - static bool isGas(int phaseIdx) + static constexpr bool isGas(int phaseIdx) { assert(0 <= phaseIdx && phaseIdx < numPhases); - return phaseIdx == nPhaseIdx; + return phaseIdx == phase1Idx; } /*! @@ -133,7 +138,7 @@ public: * * \param phaseIdx The index of the fluid phase to consider */ - static bool isIdealMixture(int phaseIdx) + static constexpr bool isIdealMixture(int phaseIdx) { assert(0 <= phaseIdx && phaseIdx < numPhases); // we assume Henry's and Raoult's laws for the water phase and @@ -155,7 +160,7 @@ public: { assert(0 <= phaseIdx && phaseIdx < numPhases); // ideal gases are always compressible - if (phaseIdx == nPhaseIdx) + if (phaseIdx == phase1Idx) return true; // the water component decides for the liquid phase... return H2O::liquidIsCompressible(); @@ -167,12 +172,12 @@ public: * * \param phaseIdx The index of the fluid phase to consider */ - static bool isIdealGas(int phaseIdx) + static constexpr bool isIdealGas(int phaseIdx) { assert(0 <= phaseIdx && phaseIdx < numPhases); // let the fluids decide - if (phaseIdx == nPhaseIdx) + if (phaseIdx == phase1Idx) return H2O::gasIsIdeal() && Air::gasIsIdeal(); return false; // not a gas } @@ -180,13 +185,6 @@ public: /**************************************** * Component related static parameters ****************************************/ - - //! Number of components in the fluid system - static constexpr int numComponents = 2; - - static constexpr int H2OIdx = wCompIdx; - static constexpr int AirIdx = nCompIdx; - /*! * \brief Return the human readable name of a component * @@ -260,36 +258,25 @@ public: static Scalar vaporPressure(const FluidState &fluidState, int compIdx) { if (compIdx == H2OIdx) - return H2O::vaporPressure(fluidState.temperature()); + { + const auto t = fluidState.temperature(H2OIdx); + if (!useKelvinVaporPressure) + return H2O::vaporPressure(t); + else + { + const auto pc = (fluidState.wettingPhase() == H2OIdx) + ? fluidState.pressure(AirIdx)-fluidState.pressure(H2OIdx) + : fluidState.pressure(H2OIdx)-fluidState.pressure(AirIdx); + return H2O::vaporPressure(t)*exp( -pc * molarMass(H2OIdx) + / density(fluidState, H2OIdx) + / (Dumux::Constants<Scalar>::R*t) ); + } + } else if (compIdx == AirIdx) - return Air::vaporPressure(fluidState.temperature()); + // return Air::vaporPressure(fluidState.temperature(AirIdx)); + DUNE_THROW(Dune::NotImplemented, "Air::vaporPressure(t)"); else - DUNE_THROW(Dune::NotImplemented, "Invalid component index " << compIdx); - } - - /*! - * \brief Vapor pressure including the Kelvin equation in \f$\mathrm{[Pa]}\f$ - * - * Calculate the decreased vapor pressure due to capillarity - * - * \param fluidState An abitrary fluid state - * \param phaseIdx The index of the fluid phase to consider - * \param compIdx The index of the component to consider - */ - template <class FluidState> - static Scalar kelvinVaporPressure(const FluidState &fluidState, - const int phaseIdx, - const int compIdx) - { - assert(compIdx == wCompIdx && phaseIdx == wPhaseIdx); - - using std::exp; - return fugacityCoefficient(fluidState, phaseIdx, compIdx) - * fluidState.pressure(phaseIdx) - * exp(-(fluidState.pressure(nPhaseIdx)-fluidState.pressure(wPhaseIdx)) - / density(fluidState, phaseIdx) - / (Dumux::Constants<Scalar>::R / molarMass(compIdx)) - / fluidState.temperature()); + DUNE_THROW(Dune::NotImplemented, "Invalid component index " << compIdx); } /*! @@ -396,7 +383,7 @@ public: for (int compIdx = 0; compIdx < numComponents; ++compIdx) sumMoleFrac += fluidState.moleFraction(phaseIdx, compIdx); - if (phaseIdx == wPhaseIdx) + if (phaseIdx == phase0Idx) { if (!useComplexRelations) // assume pure water @@ -409,25 +396,25 @@ public: return clH2O - * (H2O::molarMass()*fluidState.moleFraction(wPhaseIdx, H2OIdx) + * (H2O::molarMass()*fluidState.moleFraction(phase0Idx, H2OIdx) + - Air::molarMass()*fluidState.moleFraction(wPhaseIdx, AirIdx)) + Air::molarMass()*fluidState.moleFraction(phase0Idx, AirIdx)) / sumMoleFrac; } } - else if (phaseIdx == nPhaseIdx) + else if (phaseIdx == phase1Idx) { using std::max; if (!useComplexRelations) // for the gas phase assume an ideal gas return IdealGas::molarDensity(T, p) - * fluidState.averageMolarMass(nPhaseIdx) + * fluidState.averageMolarMass(phase1Idx) / max(1e-5, sumMoleFrac); return - H2O::gasDensity(T, fluidState.partialPressure(nPhaseIdx, H2OIdx)) + - Air::gasDensity(T, fluidState.partialPressure(nPhaseIdx, AirIdx)); + H2O::gasDensity(T, fluidState.partialPressure(phase1Idx, H2OIdx)) + + Air::gasDensity(T, fluidState.partialPressure(phase1Idx, AirIdx)); } DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx); } @@ -455,12 +442,12 @@ public: Scalar T = fluidState.temperature(phaseIdx); Scalar p = fluidState.pressure(phaseIdx); - if (phaseIdx == wPhaseIdx) + if (phaseIdx == phase0Idx) { // assume pure water for the liquid phase return H2O::liquidViscosity(T, p); } - else if (phaseIdx == nPhaseIdx) + else if (phaseIdx == phase1Idx) { if(!useComplexRelations){ return Air::gasViscosity(T, p); @@ -530,9 +517,9 @@ public: Scalar T = fluidState.temperature(phaseIdx); Scalar p = fluidState.pressure(phaseIdx); - if (phaseIdx == wPhaseIdx) { + if (phaseIdx == phase0Idx) { if (compIdx == H2OIdx) - return H2O::vaporPressure(T)/p; + return vaporPressure(fluidState, compIdx)/p; return BinaryCoeff::H2O_Air::henry(T)/p; } @@ -550,8 +537,8 @@ public: template <class FluidState> static Scalar relativeHumidity(const FluidState &fluidState) { - return fluidState.partialPressure(nPhaseIdx, wCompIdx) - / H2O::vaporPressure(fluidState.temperature(nPhaseIdx)); + return fluidState.partialPressure(phase1Idx, comp0Idx) + / H2O::vaporPressure(fluidState.temperature(phase1Idx)); } using Base::diffusionCoefficient; @@ -603,7 +590,7 @@ public: switch (phaseIdx) { - case wPhaseIdx: + case phase0Idx: switch (compIIdx) { case H2OIdx: switch (compJIdx) { @@ -616,7 +603,7 @@ public: "Binary diffusion coefficients of trace " "substances in liquid phase is undefined!\n"); } - case nPhaseIdx: + case phase1Idx: switch (compIIdx){ case H2OIdx: switch (compJIdx){ @@ -660,21 +647,21 @@ public: Valgrind::CheckDefined(T); Valgrind::CheckDefined(p); - if (phaseIdx == wPhaseIdx) + if (phaseIdx == phase0Idx) { return H2O::liquidEnthalpy(T, p); } - else if (phaseIdx == nPhaseIdx) + else if (phaseIdx == phase1Idx) { Scalar result = 0.0; result += H2O::gasEnthalpy(T, p) * - fluidState.massFraction(nPhaseIdx, H2OIdx); + fluidState.massFraction(phase1Idx, H2OIdx); result += Air::gasEnthalpy(T, p) * - fluidState.massFraction(nPhaseIdx, AirIdx); + fluidState.massFraction(phase1Idx, AirIdx); return result; } DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx); @@ -697,11 +684,11 @@ public: Valgrind::CheckDefined(T); Valgrind::CheckDefined(p); - if (phaseIdx == wPhaseIdx) + if (phaseIdx == phase0Idx) { DUNE_THROW(Dune::NotImplemented, "The component enthalpies in the liquid phase are not implemented."); } - else if (phaseIdx == nPhaseIdx) + else if (phaseIdx == phase1Idx) { if (componentIdx == H2OIdx) { @@ -734,11 +721,11 @@ public: const Scalar temperature = fluidState.temperature(phaseIdx) ; const Scalar pressure = fluidState.pressure(phaseIdx); - if (phaseIdx == wPhaseIdx) + if (phaseIdx == phase0Idx) { return H2O::liquidThermalConductivity(temperature, pressure); } - else if (phaseIdx == nPhaseIdx) + else if (phaseIdx == phase1Idx) { return Air::gasThermalConductivity(temperature, pressure); } @@ -763,15 +750,15 @@ public: { const Scalar temperature = fluidState.temperature(phaseIdx); const Scalar pressure = fluidState.pressure(phaseIdx); - if (phaseIdx == wPhaseIdx) + if (phaseIdx == phase0Idx) { // influence of air is neglected return H2O::liquidHeatCapacity(temperature, pressure); } - else if (phaseIdx == nPhaseIdx) + else if (phaseIdx == phase1Idx) { - return Air::gasHeatCapacity(temperature, pressure) * fluidState.moleFraction(nPhaseIdx, AirIdx) - + H2O::gasHeatCapacity(temperature, pressure) * fluidState.moleFraction(nPhaseIdx, H2OIdx); + return Air::gasHeatCapacity(temperature, pressure) * fluidState.moleFraction(phase1Idx, AirIdx) + + H2O::gasHeatCapacity(temperature, pressure) * fluidState.moleFraction(phase1Idx, H2OIdx); } else DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx); diff --git a/dumux/material/fluidsystems/h2on2.hh b/dumux/material/fluidsystems/h2on2.hh index 250a4d63b93fb143cfd4ce8d14dfc22648fa1e9d..c84572b622fa49d23a5ea74bc64ba753740a100c 100644 --- a/dumux/material/fluidsystems/h2on2.hh +++ b/dumux/material/fluidsystems/h2on2.hh @@ -38,10 +38,8 @@ #include "base.hh" -namespace Dumux -{ -namespace FluidSystems -{ +namespace Dumux { +namespace FluidSystems { /*! * \ingroup Fluidsystems @@ -62,22 +60,27 @@ class H2ON2 using SimpleN2 = Dumux::Components::N2<Scalar>; public: - /**************************************** - * Fluid phase related static parameters - ****************************************/ + using H2O = TabulatedH2O; //!< The components for pure water + using N2 = SimpleN2; //!< The components for pure nitrogen - //! Number of phases in the fluid system - static constexpr int numPhases = 2; + static constexpr int numPhases = 2; //!< Number of phases in the fluid system + static constexpr int numComponents = 2; //!< Number of components in the fluid system - static constexpr int wPhaseIdx = 0; // index of the wetting phase - static constexpr int nPhaseIdx = 1; // index of the non-wetting phase + static constexpr int liquidPhaseIdx = 0; //!< index of the liquid phase + static constexpr int gasPhaseIdx = 1; //!< index of the gas phase + static constexpr int phase0Idx = liquidPhaseIdx; //!< index of the first phase + static constexpr int phase1Idx = gasPhaseIdx; //!< index of the second phase - // export component indices to indicate the main component - // of the corresponding phase at atmospheric pressure 1 bar - // and room temperature 20°C: - static const int wCompIdx = wPhaseIdx; - static const int nCompIdx = nPhaseIdx; + static constexpr int H2OIdx = 0; + static constexpr int N2Idx = 1; + static constexpr int comp0Idx = H2OIdx; //!< index of the first component + static constexpr int comp1Idx = N2Idx; //!< index of the second component + static constexpr int liquidCompIdx = H2OIdx; //!< index of the liquid component + static constexpr int gasCompIdx = N2Idx; //!< index of the gas component + /**************************************** + * Fluid phase related static parameters + ****************************************/ /*! * \brief Return the human readable name of a fluid phase * @@ -101,10 +104,10 @@ public: * * \param phaseIdx The index of the fluid phase to consider */ - static bool isLiquid(int phaseIdx) + static constexpr bool isLiquid(int phaseIdx) { assert(0 <= phaseIdx && phaseIdx < numPhases); - return phaseIdx != nPhaseIdx; + return phaseIdx != gasPhaseIdx; } /*! @@ -143,7 +146,7 @@ public: { assert(0 <= phaseIdx && phaseIdx < numPhases); // gases are always compressible - if (phaseIdx == nPhaseIdx) + if (phaseIdx == gasPhaseIdx) return true; // the water component decides for the liquid phase... return H2O::liquidIsCompressible(); @@ -159,7 +162,7 @@ public: { assert(0 <= phaseIdx && phaseIdx < numPhases); - if (phaseIdx == nPhaseIdx) + if (phaseIdx == gasPhaseIdx) // let the components decide return H2O::gasIsIdeal() && N2::gasIsIdeal(); return false; // not a gas @@ -168,19 +171,6 @@ public: /**************************************** * Component related static parameters ****************************************/ - - //! Number of components in the fluid system - static constexpr int numComponents = 2; - - static constexpr int H2OIdx = wCompIdx; - static constexpr int N2Idx = nCompIdx; - - //! The components for pure water - using H2O = TabulatedH2O; - - //! The components for pure nitrogen - using N2 = SimpleN2; - /*! * \brief Return the human readable name of a component * @@ -259,12 +249,12 @@ public: const int phaseIdx, const int compIdx) { - assert(compIdx == wCompIdx && phaseIdx == wPhaseIdx); + assert(compIdx == wCompIdx && phaseIdx == liquidPhaseIdx); using std::exp; return fugacityCoefficient(fluidState, phaseIdx, compIdx) * fluidState.pressure(phaseIdx) - * exp(-(fluidState.pressure(nPhaseIdx)-fluidState.pressure(wPhaseIdx)) + * exp(-(fluidState.pressure(gasPhaseIdx)-fluidState.pressure(liquidPhaseIdx)) / density(fluidState, phaseIdx) / (Dumux::Constants<Scalar>::R / molarMass(compIdx)) / fluidState.temperature()); @@ -373,7 +363,7 @@ public: sumMoleFrac += fluidState.moleFraction(phaseIdx, compIdx); // liquid phase - if (phaseIdx == wPhaseIdx) { + if (phaseIdx == liquidPhaseIdx) { if (!useComplexRelations) // assume pure water return H2O::liquidDensity(T, p); @@ -387,9 +377,9 @@ public: // water molecule in the liquid return clH2O - * (H2O::molarMass()*fluidState.moleFraction(wPhaseIdx, H2OIdx) + * (H2O::molarMass()*fluidState.moleFraction(liquidPhaseIdx, H2OIdx) + - N2::molarMass()*fluidState.moleFraction(wPhaseIdx, N2Idx)) + N2::molarMass()*fluidState.moleFraction(liquidPhaseIdx, N2Idx)) / sumMoleFrac; } } @@ -400,12 +390,12 @@ public: // for the gas phase assume an ideal gas return IdealGas::molarDensity(T, p) - * fluidState.averageMolarMass(nPhaseIdx) + * fluidState.averageMolarMass(gasPhaseIdx) / max(1e-5, sumMoleFrac); // assume ideal mixture: steam and nitrogen don't "see" each other - Scalar rho_gH2O = H2O::gasDensity(T, p*fluidState.moleFraction(nPhaseIdx, H2OIdx)); - Scalar rho_gN2 = N2::gasDensity(T, p*fluidState.moleFraction(nPhaseIdx, N2Idx)); + Scalar rho_gH2O = H2O::gasDensity(T, p*fluidState.moleFraction(gasPhaseIdx, H2OIdx)); + Scalar rho_gN2 = N2::gasDensity(T, p*fluidState.moleFraction(gasPhaseIdx, N2Idx)); return (rho_gH2O + rho_gN2) / max(1e-5, sumMoleFrac); } @@ -432,7 +422,7 @@ public: Scalar p = fluidState.pressure(phaseIdx); // liquid phase - if (phaseIdx == wPhaseIdx) { + if (phaseIdx == liquidPhaseIdx) { // assume pure water for the liquid phase return H2O::liquidViscosity(T, p); } @@ -514,7 +504,7 @@ public: Scalar p = fluidState.pressure(phaseIdx); // liquid phase - if (phaseIdx == wPhaseIdx) { + if (phaseIdx == liquidPhaseIdx) { if (compIdx == H2OIdx) return H2O::vaporPressure(T)/p; return BinaryCoeff::H2O_N2::henry(T)/p; @@ -600,7 +590,7 @@ public: Scalar p = fluidState.pressure(phaseIdx); // liquid phase - if (phaseIdx == wPhaseIdx) { + if (phaseIdx == liquidPhaseIdx) { if (compIIdx == H2OIdx && compJIdx == N2Idx) return BinaryCoeff::H2O_N2::liquidDiffCoeff(T, p); return undefined; @@ -635,7 +625,7 @@ public: Valgrind::CheckDefined(p); // liquid phase - if (phaseIdx == wPhaseIdx) { + if (phaseIdx == liquidPhaseIdx) { return H2O::liquidEnthalpy(T, p); } // gas phase @@ -644,10 +634,10 @@ public: // that the total specific enthalpy is the sum of the // "partial specific enthalpies" of the components. Scalar hH2O = - fluidState.massFraction(nPhaseIdx, H2OIdx) + fluidState.massFraction(gasPhaseIdx, H2OIdx) * H2O::gasEnthalpy(T, p); Scalar hN2 = - fluidState.massFraction(nPhaseIdx, N2Idx) + fluidState.massFraction(gasPhaseIdx, N2Idx) * N2::gasEnthalpy(T, p); return hH2O + hN2; } @@ -670,7 +660,7 @@ public: const Scalar temperature = fluidState.temperature(phaseIdx) ; const Scalar pressure = fluidState.pressure(phaseIdx); - if (phaseIdx == wPhaseIdx) + if (phaseIdx == liquidPhaseIdx) { return H2O::liquidThermalConductivity(temperature, pressure); } @@ -703,7 +693,7 @@ public: static Scalar heatCapacity(const FluidState &fluidState, int phaseIdx) { - if (phaseIdx == wPhaseIdx) { + if (phaseIdx == liquidPhaseIdx) { return H2O::liquidHeatCapacity(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx)); } @@ -736,8 +726,8 @@ public: // mangle both components together return - c_pH2O*fluidState.massFraction(nPhaseIdx, H2OIdx) - + c_pN2*fluidState.massFraction(nPhaseIdx, N2Idx); + c_pH2O*fluidState.massFraction(gasPhaseIdx, H2OIdx) + + c_pN2*fluidState.massFraction(gasPhaseIdx, N2Idx); } }; diff --git a/dumux/material/fluidsystems/h2on2kinetic.hh b/dumux/material/fluidsystems/h2on2kinetic.hh index a84dd2100a5679db0b5ed0c2baa0d3582258ffd1..12bff8ba1bf1ad9e7d2449a9fcbaacde4188cf4a 100644 --- a/dumux/material/fluidsystems/h2on2kinetic.hh +++ b/dumux/material/fluidsystems/h2on2kinetic.hh @@ -44,7 +44,7 @@ namespace FluidSystems /*! * \ingroup Fluidsystems * \brief A two-phase fluid system with two components water \f$(\mathrm{H_2O})\f$ - * Nitrogen \f$(\mathrm{N_2})\f$ for non-equilibrium models. + * Nitrogen \f$(\mathrm{N_2})\f$ for non-equilibrium models. TODO: Is this fluid system necessary?? */ template <class Scalar, bool useComplexRelations = true> class H2ON2Kinetic : @@ -85,7 +85,7 @@ public: Valgrind::CheckDefined(T); Valgrind::CheckDefined(p); switch (phaseIdx){ - case ParentType::wPhaseIdx: + case ParentType::liquidPhaseIdx: switch(compIdx){ case ParentType::H2OIdx: return ParentType::H2O::liquidEnthalpy(T, p); @@ -97,7 +97,7 @@ public: break; }// end switch compIdx break; - case ParentType::nPhaseIdx: + case ParentType::gasPhaseIdx: switch(compIdx){ case ParentType::H2OIdx: return ParentType::H2O::gasEnthalpy(T, p); @@ -137,10 +137,10 @@ public: const unsigned int referencePhaseIdx, const unsigned int calcCompIdx) { - const unsigned int nPhaseIdx = ParentType::nPhaseIdx; - const unsigned int wPhaseIdx = ParentType::wPhaseIdx; - const unsigned int nCompIdx = ParentType::nCompIdx; - const unsigned int wCompIdx = ParentType::wCompIdx; + const unsigned int nPhaseIdx = ParentType::gasPhaseIdx; + const unsigned int wPhaseIdx = ParentType::liquidPhaseIdx; + const unsigned int nCompIdx = ParentType::N2Idx; + const unsigned int wCompIdx = ParentType::H2OIdx; assert(0 <= referencePhaseIdx && referencePhaseIdx < ParentType::numPhases); assert(0 <= calcCompIdx && calcCompIdx < ParentType::numComponents); @@ -265,10 +265,10 @@ public: static void calculateEquilibriumMoleFractions(FluidState & fluidState, const ParameterCache & paramCache) { - const unsigned int nPhaseIdx = ParentType::nPhaseIdx; - const unsigned int wPhaseIdx = ParentType::wPhaseIdx; - const unsigned int nCompIdx = ParentType::nCompIdx; - const unsigned int wCompIdx = ParentType::wCompIdx; + const unsigned int nPhaseIdx = ParentType::gasPhaseIdx; + const unsigned int wPhaseIdx = ParentType::liquidPhaseIdx; + const unsigned int nCompIdx = ParentType::N2Idx; + const unsigned int wCompIdx = ParentType::H2OIdx; const unsigned int numPhases = ParentType::numPhases; const unsigned int numComponents= ParentType::numComponents; diff --git a/dumux/material/fluidsystems/h2on2o2.hh b/dumux/material/fluidsystems/h2on2o2.hh index bdbc2d81ef4ba8d215903259f33688ba60082644..24c5ca61643e5ba5ae9c8be5a372f6492e78695f 100644 --- a/dumux/material/fluidsystems/h2on2o2.hh +++ b/dumux/material/fluidsystems/h2on2o2.hh @@ -43,10 +43,8 @@ #include <dumux/material/binarycoefficients/h2o_o2.hh> #include <dumux/material/binarycoefficients/n2_o2.hh> -namespace Dumux -{ -namespace FluidSystems -{ +namespace Dumux { +namespace FluidSystems { /*! * \ingroup Fluidsystems @@ -78,18 +76,30 @@ class H2ON2O2 using N2 = SimpleN2; public: - /**************************************** - * Fluid phase related static parameters - ****************************************/ + static constexpr int numPhases = 2; //!< Number of phases in the fluid system + static constexpr int numComponents = 3; //!< Number of components in the fluid system + static constexpr int numSPhases = 0; // TODO: Remove + + static constexpr int liquidPhaseIdx = 0; //!< index of the liquid phase + static constexpr int gasPhaseIdx = 1; //!< index of the gas phase + static constexpr int phase0Idx = liquidPhaseIdx; //!< index of the first phase + static constexpr int phase1Idx = gasPhaseIdx; //!< index of the second phase + + static constexpr int H2OIdx = 0; + static constexpr int N2Idx = 1; + static constexpr int O2Idx = 2; - //! Number of phases in the fluid system - static constexpr int numPhases = 2; - //! Number of solid phases besides the solid matrix - static constexpr int numSPhases = 0; + static constexpr int comp0Idx = H2OIdx; // first major component + static constexpr int comp1Idx = N2Idx; // second major component + static constexpr int comp2Idx = O2Idx; // secondary component - static constexpr int wPhaseIdx = 0; // index of the wetting phase - static constexpr int nPhaseIdx = 1; // index of the non-wetting phase + // main component at 20°C and 1 bar + static constexpr int liquidPhaseMainCompIdx = H2OIdx; + static constexpr int gasPhaseMainCompIdx = N2Idx; + /**************************************** + * Fluid phase related static parameters + ****************************************/ /*! * \brief Return the human readable name of a fluid phase * @@ -114,7 +124,7 @@ public: static bool isLiquid(int phaseIdx) { assert(0 <= phaseIdx && phaseIdx < numPhases); - return phaseIdx != nPhaseIdx; + return phaseIdx != gasPhaseIdx; } /*! @@ -153,7 +163,7 @@ public: { assert(0 <= phaseIdx && phaseIdx < numPhases); // gases are always compressible - if (phaseIdx == nPhaseIdx) + if (phaseIdx == gasPhaseIdx) return true; // the water component decides for the liquid phase... return H2O::liquidIsCompressible(); @@ -168,7 +178,7 @@ public: static bool isIdealGas(int phaseIdx) { assert(0 <= phaseIdx && phaseIdx < numPhases); - if (phaseIdx == nPhaseIdx) + if (phaseIdx == gasPhaseIdx) // let the components decide return H2O::gasIsIdeal() && N2::gasIsIdeal() && O2::gasIsIdeal(); return false; // not a gas @@ -177,20 +187,6 @@ public: /**************************************** * Component related static parameters ****************************************/ - - //! Number of components in the fluid system - static constexpr int numComponents = 3; - - static constexpr int H2OIdx = 0;//first major component - static constexpr int N2Idx = 1;//second major component - static constexpr int O2Idx = 2;//secondary component - - // export component indices to indicate the main component - // of the corresponding phase at atmospheric pressure 1 bar - // and room temperature 20C: - static const int wCompIdx = wPhaseIdx; //=0 -> H2OIdx - static const int nCompIdx = nPhaseIdx; //=1 -> N2Idx - /*! * \brief Return the human readable name of a component * @@ -304,8 +300,8 @@ public: const int compIdx, const Scalar radius) { - assert(0 <= phaseIdx && phaseIdx == wPhaseIdx); - assert(0 <= compIdx && compIdx == wCompIdx); + assert(0 <= phaseIdx && phaseIdx == liquidPhaseIdx); + assert(0 <= compIdx && compIdx == liquidPhaseMainCompIdx); Scalar T = fluidState.temperature(phaseIdx); @@ -332,12 +328,12 @@ public: const int phaseIdx, const int compIdx) { - assert(compIdx == wCompIdx && phaseIdx == wPhaseIdx); + assert(compIdx == liquidPhaseMainCompIdx && phaseIdx == liquidPhaseIdx); using std::exp; return fugacityCoefficient(fluidState, phaseIdx, compIdx) * fluidState.pressure(phaseIdx) - * exp(-(fluidState.pressure(nPhaseIdx)-fluidState.pressure(wPhaseIdx)) + * exp(-(fluidState.pressure(gasPhaseIdx)-fluidState.pressure(liquidPhaseIdx)) / density(fluidState, phaseIdx) / (Dumux::Constants<Scalar>::R / molarMass(compIdx)) / fluidState.temperature()); @@ -439,7 +435,7 @@ public: sumMoleFrac += fluidState.moleFraction(phaseIdx, compIdx); // liquid phase - if (phaseIdx == wPhaseIdx) { + if (phaseIdx == liquidPhaseIdx) { if (!useComplexRelations) // assume pure water return H2O::liquidDensity(T, p); @@ -453,11 +449,11 @@ public: // water molecule in the liquid return clH2O* - (fluidState.moleFraction(wPhaseIdx, H2OIdx)*H2O::molarMass() + (fluidState.moleFraction(liquidPhaseIdx, H2OIdx)*H2O::molarMass() + - fluidState.moleFraction(wPhaseIdx, N2Idx)*N2::molarMass() + fluidState.moleFraction(liquidPhaseIdx, N2Idx)*N2::molarMass() + - fluidState.moleFraction(wPhaseIdx, O2Idx)*O2::molarMass()) + fluidState.moleFraction(liquidPhaseIdx, O2Idx)*O2::molarMass()) / sumMoleFrac; } } @@ -468,14 +464,14 @@ public: // for the gas phase assume an ideal gas return IdealGas::molarDensity(T, p) - * fluidState.averageMolarMass(nPhaseIdx) + * fluidState.averageMolarMass(gasPhaseIdx) / max(1e-5, sumMoleFrac); // assume ideal mixture: steam, nitrogen and oxygen don't "see" each // other - Scalar rho_gH2O = H2O::gasDensity(T, p*fluidState.moleFraction(nPhaseIdx, H2OIdx)); - Scalar rho_gN2 = N2::gasDensity(T, p*fluidState.moleFraction(nPhaseIdx, N2Idx)); - Scalar rho_gO2 = O2::gasDensity(T, p*fluidState.moleFraction(nPhaseIdx, O2Idx)); + Scalar rho_gH2O = H2O::gasDensity(T, p*fluidState.moleFraction(gasPhaseIdx, H2OIdx)); + Scalar rho_gN2 = N2::gasDensity(T, p*fluidState.moleFraction(gasPhaseIdx, N2Idx)); + Scalar rho_gO2 = O2::gasDensity(T, p*fluidState.moleFraction(gasPhaseIdx, O2Idx)); return (rho_gH2O + rho_gN2 + rho_gO2 ) / max(1e-5, sumMoleFrac); } @@ -502,7 +498,7 @@ public: Scalar p = fluidState.pressure(phaseIdx); // liquid phase - if (phaseIdx == wPhaseIdx) { + if (phaseIdx == liquidPhaseIdx) { // assume pure water for the liquid phase return H2O::liquidViscosity(T, p); } @@ -576,7 +572,7 @@ public: Scalar p = fluidState.pressure(phaseIdx); // liquid phase - if (phaseIdx == wPhaseIdx) + if (phaseIdx == liquidPhaseIdx) { switch(compIdx){ case H2OIdx: return H2O::vaporPressure(T)/p; @@ -662,7 +658,7 @@ public: Scalar p = fluidState.pressure(phaseIdx); // liquid phase - if (phaseIdx == wPhaseIdx) { + if (phaseIdx == liquidPhaseIdx) { if (compIIdx == H2OIdx && compJIdx == N2Idx) return BinaryCoeff::H2O_N2::liquidDiffCoeff(T, p); if (compIIdx == H2OIdx && compJIdx == O2Idx) @@ -673,7 +669,7 @@ public: << " in phase " << phaseIdx << " is undefined!\n"); } // gas phase - if (phaseIdx == nPhaseIdx) { + if (phaseIdx == gasPhaseIdx) { if (compIIdx == H2OIdx && compJIdx == N2Idx) return BinaryCoeff::H2O_N2::gasDiffCoeff(T, p); if (compIIdx == H2OIdx && compJIdx == O2Idx) @@ -715,23 +711,23 @@ public: Valgrind::CheckDefined(p); // liquid phase - if (phaseIdx == wPhaseIdx) { + if (phaseIdx == liquidPhaseIdx) { return H2O::liquidEnthalpy(T, p); } // gas phase - else if (phaseIdx == nPhaseIdx) + else if (phaseIdx == gasPhaseIdx) { // assume ideal mixture: which means // that the total specific enthalpy is the sum of the // "partial specific enthalpies" of the components. Scalar hH2O = - fluidState.massFraction(nPhaseIdx, H2OIdx) + fluidState.massFraction(gasPhaseIdx, H2OIdx) * H2O::gasEnthalpy(T, p); Scalar hN2 = - fluidState.massFraction(nPhaseIdx, N2Idx) + fluidState.massFraction(gasPhaseIdx, N2Idx) * N2::gasEnthalpy(T,p); Scalar hO2 = - fluidState.massFraction(nPhaseIdx, O2Idx) + fluidState.massFraction(gasPhaseIdx, O2Idx) * O2::gasEnthalpy(T,p); return hH2O + hN2 + hO2; } @@ -767,7 +763,7 @@ public: Scalar temperature = fluidState.temperature(phaseIdx) ; Scalar pressure = fluidState.pressure(phaseIdx); - if (phaseIdx == wPhaseIdx) + if (phaseIdx == liquidPhaseIdx) { return H2O::liquidThermalConductivity(temperature, pressure); } @@ -803,7 +799,7 @@ public: static Scalar heatCapacity(const FluidState &fluidState, int phaseIdx) { - if (phaseIdx == wPhaseIdx) { + if (phaseIdx == liquidPhaseIdx) { return H2O::liquidHeatCapacity(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx)); } @@ -844,9 +840,9 @@ public: // mangle all components together return - c_pH2O*fluidState.massFraction(nPhaseIdx, H2OIdx) - + c_pN2*fluidState.massFraction(nPhaseIdx, N2Idx) - + c_pO2*fluidState.massFraction(nPhaseIdx, O2Idx); + c_pH2O*fluidState.massFraction(gasPhaseIdx, H2OIdx) + + c_pN2*fluidState.massFraction(gasPhaseIdx, N2Idx) + + c_pO2*fluidState.massFraction(gasPhaseIdx, O2Idx); } }; diff --git a/dumux/material/fluidsystems/liquidphase2c.hh b/dumux/material/fluidsystems/liquidphase2c.hh index 259dc2c2f48082452501036359add78d877da33b..4cfd409d0c9ccae811aaf8d7461ca0e09a67f9b5 100644 --- a/dumux/material/fluidsystems/liquidphase2c.hh +++ b/dumux/material/fluidsystems/liquidphase2c.hh @@ -31,10 +31,8 @@ #include <dumux/material/fluidsystems/base.hh> #include <dumux/material/binarycoefficients/h2o_constant.hh> -namespace Dumux -{ -namespace FluidSystems -{ +namespace Dumux { +namespace FluidSystems { /*! * \ingroup Fluidsystems @@ -52,21 +50,25 @@ class LiquidPhaseTwoC public: using ParameterCache = NullParameterCache; - /**************************************** - * Fluid phase related static parameters - ****************************************/ - static constexpr int mainCompIdx = 0; - static constexpr int secondCompIdx = 1; - static constexpr int wPhaseIdx = 0; - static constexpr int numPhases = 1; - static constexpr int numComponents = 2; + static constexpr int numPhases = 2; //!< Number of phases in the fluid system + static constexpr int numComponents = 2; //!< Number of components in the fluid system + + static constexpr int phase0Idx = 0; //!< index of the only phase + + static constexpr int comp0Idx = 0; //!< index of the frist component + static constexpr int comp1Idx = 1; //!< index of the second component + static constexpr int mainCompIdx = comp0Idx; //!< index of the main component + static constexpr int secondCompIdx = comp1Idx; //!< index of the secondary component /*! - * \brief Initialize the fluid system's static parameters generically - */ + * \brief Initialize the fluid system's static parameters generically + */ static void init() {} + /**************************************** + * Fluid phase related static parameters + ****************************************/ /*! * \brief Return the human readable name of a fluid phase * @@ -191,8 +193,8 @@ public: const Scalar densityMain = MainComponent::liquidDensity(T, p); const Scalar molarDensity = densityMain/MainComponent::molarMass(); - return molarDensity * (MainComponent::molarMass()*fluidState.moleFraction(wPhaseIdx, mainCompIdx) - + SecondComponent::molarMass()*fluidState.moleFraction(wPhaseIdx, secondCompIdx)); + return molarDensity * (MainComponent::molarMass()*fluidState.moleFraction(phase0Idx, mainCompIdx) + + SecondComponent::molarMass()*fluidState.moleFraction(phase0Idx, secondCompIdx)); } /*! diff --git a/dumux/material/fluidsystems/nullparametercache.hh b/dumux/material/fluidsystems/nullparametercache.hh index a056632b89c0b8420dd9ee85461bf0cb9bfe754a..d140b381c5e9f226a38f4114fd7199eca222e99d 100644 --- a/dumux/material/fluidsystems/nullparametercache.hh +++ b/dumux/material/fluidsystems/nullparametercache.hh @@ -26,18 +26,12 @@ #include "parametercachebase.hh" -namespace Dumux -{ +namespace Dumux { /*! * \ingroup Fluidsystems * \brief The a parameter cache which does nothing */ -class NullParameterCache : public ParameterCacheBase<NullParameterCache> -{ -public: - NullParameterCache() - {}; -}; +class NullParameterCache : public ParameterCacheBase<NullParameterCache> {}; } // end namespace diff --git a/dumux/material/fluidsystems/steamn2cao2h2.hh b/dumux/material/fluidsystems/steamn2cao2h2.hh index d59540ef166ffc8de8e667702fd05bd14677a8e9..ee8f743160df9ac38b96914bd2339aa16949395b 100644 --- a/dumux/material/fluidsystems/steamn2cao2h2.hh +++ b/dumux/material/fluidsystems/steamn2cao2h2.hh @@ -76,21 +76,29 @@ public: // the type of parameter cache objects. this fluid system does not using ParameterCache = Dumux::NullParameterCache; - /**************************************** - * Fluid phase related static parameters - ****************************************/ - //! Number of phases in the fluid system static constexpr int numPhases = 1; //gas phase: N2 and steam - static const int numSPhases = 2;// solid phases CaO and CaO2H2 + static constexpr int numComponents = 2; // H2O, Air + static constexpr int numSPhases = 2;// solid phases CaO and CaO2H2 TODO: Remove + static constexpr int numSComponents = 2;// CaO2H2, CaO TODO: Remove - static constexpr int gPhaseIdx = 0; - static const int nPhaseIdx = gPhaseIdx; // index of the gas phase + static constexpr int gasPhaseIdx = 0; //!< index of the gas phase + static constexpr int phase0Idx = gasPhaseIdx; //!< index of the only phase - static constexpr int cPhaseIdx = 1; // CaO-phaseIdx - static constexpr int hPhaseIdx = 2; // CaO2H2-phaseIdx + static constexpr int cPhaseIdx = 1; // CaO-phaseIdx TODO: Remove + static constexpr int hPhaseIdx = 2; // CaO2H2-phaseIdx TODO: Remove + static constexpr int N2Idx = 0; + static constexpr int H2OIdx = 1; + static constexpr int comp0Idx = N2Idx; + static constexpr int comp1Idx = H2OIdx; + static constexpr int CaOIdx = 2; // CaO-phaseIdx TODO: Remove + static constexpr int CaO2H2Idx = 3; // CaO-phaseIdx TODO: Remove + + /**************************************** + * Fluid phase related static parameters + ****************************************/ /*! * \brief Return the human readable name of a fluid phase * @@ -99,7 +107,7 @@ public: static std::string phaseName(int phaseIdx) { switch (phaseIdx) { - case nPhaseIdx: return "gas"; + case gasPhaseIdx: return "gas"; case cPhaseIdx : return "CaO"; case hPhaseIdx : return "CaOH2"; } @@ -117,10 +125,10 @@ public: * * \param phaseIdx The index of the fluid phase to consider */ - static bool isGas (int phaseIdx) + static constexpr bool isGas (int phaseIdx) { assert(0 <= phaseIdx && phaseIdx < numPhases); - return phaseIdx == nPhaseIdx; + return phaseIdx == gasPhaseIdx; } /*! @@ -137,7 +145,7 @@ public: * * \param phaseIdx The index of the fluid phase to consider */ - static bool isIdealMixture(int phaseIdx) + static constexpr bool isIdealMixture(int phaseIdx) { assert(0 <= phaseIdx && phaseIdx < numPhases); // we assume no interaction between gas molecules of different @@ -154,7 +162,7 @@ public: * * \param phaseIdx The index of the fluid phase to consider */ - static bool isCompressible(int phaseIdx) + static constexpr bool isCompressible(int phaseIdx) { assert(0 <= phaseIdx && phaseIdx < numPhases); @@ -167,7 +175,7 @@ public: * * \param phaseIdx The index of the fluid phase to consider */ - static bool isIdealGas(int phaseIdx) + static constexpr bool isIdealGas(int phaseIdx) { assert(0 <= phaseIdx && phaseIdx < numPhases); @@ -178,17 +186,6 @@ public: /**************************************** * Component related static parameters ****************************************/ - - static const int numComponents = 2; // H2O, Air - static const int numSComponents = 2;// CaO2H2, CaO - - - static const int N2Idx = 0; - static const int H2OIdx = 1; - static const int CaOIdx = 2; - static const int CaO2H2Idx = 3; - - /*! * \brief Return the human readable name of a component * @@ -353,13 +350,13 @@ public: // for the gas phase assume an ideal gas return IdealGas::molarDensity(T, p) - * fluidState.averageMolarMass(nPhaseIdx) + * fluidState.averageMolarMass(gasPhaseIdx) / std::max(1e-5, sumMoleFrac); else { return - (H2O::gasDensity(T, fluidState.partialPressure(nPhaseIdx, H2OIdx)) + - N2::gasDensity(T, fluidState.partialPressure(nPhaseIdx, N2Idx))); + (H2O::gasDensity(T, fluidState.partialPressure(gasPhaseIdx, H2OIdx)) + + N2::gasDensity(T, fluidState.partialPressure(gasPhaseIdx, N2Idx))); } } @@ -438,7 +435,7 @@ public: Scalar temperature = fluidState.temperature(phaseIdx); Scalar pressure = fluidState.pressure(phaseIdx); - assert(phaseIdx == gPhaseIdx); + assert(phaseIdx == gasPhaseIdx); if (compIIdx != N2Idx) std::swap(compIIdx, compJIdx); @@ -474,13 +471,13 @@ public: static Scalar enthalpy(const FluidState &fluidState, int phaseIdx) { - assert(phaseIdx == gPhaseIdx); + assert(phaseIdx == gasPhaseIdx); Scalar T = fluidState.temperature(phaseIdx); Scalar p = fluidState.pressure(phaseIdx); - Scalar XN2 = fluidState.massFraction(gPhaseIdx, N2Idx); - Scalar XH2O = fluidState.massFraction(gPhaseIdx, H2OIdx); + Scalar XN2 = fluidState.massFraction(gasPhaseIdx, N2Idx); + Scalar XH2O = fluidState.massFraction(gasPhaseIdx, H2OIdx); Scalar result = 0; result += XH2O * H2O::gasEnthalpy(T, p); @@ -501,8 +498,8 @@ public: int phaseIdx, int componentIdx) { - Scalar T = fluidState.temperature(nPhaseIdx); - Scalar p = fluidState.pressure(nPhaseIdx); + Scalar T = fluidState.temperature(gasPhaseIdx); + Scalar p = fluidState.pressure(gasPhaseIdx); Valgrind::CheckDefined(T); Valgrind::CheckDefined(p); @@ -523,7 +520,7 @@ public: int componentIdx) { Scalar T = 573.15; - Scalar p = fluidState.pressure(nPhaseIdx); + Scalar p = fluidState.pressure(gasPhaseIdx); Valgrind::CheckDefined(T); Valgrind::CheckDefined(p); @@ -607,7 +604,7 @@ public: fluidState.pressure(phaseIdx) * fluidState.moleFraction(phaseIdx, H2OIdx)); - return c_pH2O*fluidState.moleFraction(nPhaseIdx, H2OIdx) + c_pN2*fluidState.moleFraction(nPhaseIdx, N2Idx); + return c_pH2O*fluidState.moleFraction(gasPhaseIdx, H2OIdx) + c_pN2*fluidState.moleFraction(gasPhaseIdx, N2Idx); } }; diff --git a/dumux/material/spatialparams/fv.hh b/dumux/material/spatialparams/fv.hh index d95952de6b35b6e59880f57e534526a25601394e..2263814954b7e01163789e45ae6702847c691631 100644 --- a/dumux/material/spatialparams/fv.hh +++ b/dumux/material/spatialparams/fv.hh @@ -84,6 +84,36 @@ public: "The spatial parameters do not provide " "a materialLawParamsAtPos() method."); } + + /*! + * \brief Function for defining which phase is to be considered as the wetting phase. + * + * \param element The current element + * \param scv The sub-control volume inside the element. + * \param elemSol The solution at the dofs connected to the element. + * \return the wetting phase index + */ + template<class FluidSystem, class ElementSolution> + int wettingPhase(const Element& element, + const SubControlVolume& scv, + const ElementSolution& elemSol) const + { + return this->asImp_().template wettingPhaseAtPos<FluidSystem>(scv.center()); + } + + /*! + * \brief Function for defining which phase is to be considered as the wetting phase. + * + * \return the wetting phase index + * \param globalPos The global position + */ + template<class FluidSystem> + int wettingPhaseAtPos(const GlobalPosition& globalPos) const + { + DUNE_THROW(Dune::InvalidStateException, + "The spatial parameters do not provide " + "a wettingPhaseAtPos() method."); + } }; } // namespace Dumux diff --git a/dumux/porousmediumflow/1pnc/volumevariables.hh b/dumux/porousmediumflow/1pnc/volumevariables.hh index 4a0f69c79adc050b277e06adc2bc08096dfba45d..c0312d5fea9809e154be2059276ad345b6eb926d 100644 --- a/dumux/porousmediumflow/1pnc/volumevariables.hh +++ b/dumux/porousmediumflow/1pnc/volumevariables.hh @@ -46,15 +46,15 @@ class OnePNCVolumeVariables using Scalar = typename Traits::PrimaryVariables::value_type; using PermeabilityType = typename Traits::PermeabilityType; - using Indices = typename Traits::ModelTraits::Indices; + using Idx = typename Traits::ModelTraits::Indices; static constexpr int numComp = ParentType::numComponents(); enum { - fluidSystemPhaseIdx = Indices::fluidSystemPhaseIdx, + fluidSystemPhaseIdx = Idx::fluidSystemPhaseIdx, // pressure primary variable index - pressureIdx = Indices::pressureIdx, + pressureIdx = Idx::pressureIdx, // main component index mainCompMoleOrMassFracIdx = fluidSystemPhaseIdx @@ -65,6 +65,8 @@ public: using FluidState = typename Traits::FluidState; //! export fluid system type using FluidSystem = typename Traits::FluidSystem; + //! export indices + using Indices = typename Traits::ModelTraits::Indices; /*! * \brief Update all quantities for a given control volume @@ -182,7 +184,6 @@ public: */ Scalar density(int phaseIdx = fluidSystemPhaseIdx) const { - assert(phaseIdx == fluidSystemPhaseIdx); return fluidState_.density(fluidSystemPhaseIdx); } @@ -194,7 +195,6 @@ public: */ Scalar molarDensity(int phaseIdx = fluidSystemPhaseIdx) const { - assert(phaseIdx == fluidSystemPhaseIdx); return fluidState_.molarDensity(fluidSystemPhaseIdx); } @@ -219,7 +219,6 @@ public: Scalar moleFraction(int phaseIdx, int compIdx) const { // make sure this is only called with admissible indices - assert(phaseIdx == fluidSystemPhaseIdx); assert(compIdx < numComp); return fluidState_.moleFraction(fluidSystemPhaseIdx, compIdx); } @@ -236,7 +235,6 @@ public: Scalar massFraction(int phaseIdx, int compIdx) const { // make sure this is only called with admissible indices - assert(phaseIdx == fluidSystemPhaseIdx); assert(compIdx < numComp); return fluidState_.massFraction(fluidSystemPhaseIdx, compIdx); } @@ -252,7 +250,6 @@ public: */ Scalar pressure(int phaseIdx = fluidSystemPhaseIdx) const { - assert(phaseIdx == fluidSystemPhaseIdx); return fluidState_.pressure(fluidSystemPhaseIdx); } @@ -277,7 +274,6 @@ public: */ Scalar mobility(int phaseIdx = fluidSystemPhaseIdx) const { - assert(phaseIdx == fluidSystemPhaseIdx); return 1.0/fluidState_.viscosity(fluidSystemPhaseIdx); } @@ -290,7 +286,6 @@ public: */ Scalar viscosity(int phaseIdx = fluidSystemPhaseIdx) const { - assert(phaseIdx == fluidSystemPhaseIdx); return fluidState_.viscosity(fluidSystemPhaseIdx); } @@ -305,7 +300,6 @@ public: */ Scalar diffusionCoefficient(int phaseIdx, int compIdx) const { - assert(phaseIdx == fluidSystemPhaseIdx); assert(compIdx < numComp); return diffCoeff_[compIdx]; } diff --git a/dumux/porousmediumflow/1pnc/vtkoutputfields.hh b/dumux/porousmediumflow/1pnc/vtkoutputfields.hh index 2b0ce0267ec3c843f830abc57c5aa57fc7bd30c8..94d4d092142e4e0325b8391d750dbb1a4256f11c 100644 --- a/dumux/porousmediumflow/1pnc/vtkoutputfields.hh +++ b/dumux/porousmediumflow/1pnc/vtkoutputfields.hh @@ -38,18 +38,19 @@ public: { using VolumeVariables = typename VtkOutputModule::VolumeVariables; using FluidSystem = typename VolumeVariables::FluidSystem; + using Indices = typename VolumeVariables::Indices; - vtk.addVolumeVariable([](const auto& volVars){ return volVars.pressure(); }, "pressure"); - vtk.addVolumeVariable([](const auto& volVars){ return volVars.density(); }, "rho"); - vtk.addVolumeVariable([](const auto& volVars){ return volVars.viscosity(); }, "mu"); - vtk.addVolumeVariable([](const auto& volVars){ return volVars.pressure() - 1e5; }, "delp"); + vtk.addVolumeVariable([](const auto& volVars){ return volVars.pressure(Indices::fluidSystemPhaseIdx); }, "pressure"); + vtk.addVolumeVariable([](const auto& volVars){ return volVars.density(Indices::fluidSystemPhaseIdx); }, "rho"); + vtk.addVolumeVariable([](const auto& volVars){ return volVars.viscosity(Indices::fluidSystemPhaseIdx); }, "mu"); + vtk.addVolumeVariable([](const auto& volVars){ return volVars.pressure(Indices::fluidSystemPhaseIdx) - 1e5; }, "delp"); for (int i = 0; i < VolumeVariables::numComponents(); ++i) - vtk.addVolumeVariable([i](const auto& volVars){ return volVars.moleFraction(0, i); }, + vtk.addVolumeVariable([i](const auto& volVars){ return volVars.moleFraction(Indices::fluidSystemPhaseIdx, i); }, "x_" + std::string(FluidSystem::componentName(i))); for (int i = 0; i < VolumeVariables::numComponents(); ++i) - vtk.addVolumeVariable([i](const auto& volVars){ return volVars.massFraction(0,i); }, + vtk.addVolumeVariable([i](const auto& volVars){ return volVars.massFraction(Indices::fluidSystemPhaseIdx, i); }, "X_" + std::string(FluidSystem::componentName(i))); } }; diff --git a/dumux/porousmediumflow/1pncmin/model.hh b/dumux/porousmediumflow/1pncmin/model.hh index 602ed456acf92ea43835b19939ea838404e540a9..f484bc3c833b97bc67a9a416cf4c1b578c1ac284 100644 --- a/dumux/porousmediumflow/1pncmin/model.hh +++ b/dumux/porousmediumflow/1pncmin/model.hh @@ -131,7 +131,7 @@ SET_TYPE_PROP(OnePNCMin, VtkOutputFields, MineralizationVtkOutputFields<OnePNCVt ////////////////////////////////////////////////////////////////// //! non-isothermal vtk output -SET_PROP(OnePNCMinNI, VtkOutputFields, EnergyVtkOutputFields<MineralizationVtkOutputFields<OnePNCVtkOutputFields>>); +SET_TYPE_PROP(OnePNCMinNI, VtkOutputFields, EnergyVtkOutputFields<MineralizationVtkOutputFields<OnePNCVtkOutputFields>>); //! The non-isothermal model traits SET_PROP(OnePNCMinNI, ModelTraits) diff --git a/dumux/porousmediumflow/2p/formulation.hh b/dumux/porousmediumflow/2p/formulation.hh index 9ad0e328e2e7e4d401df6bc4f4fe9b78008d1877..681324e06031737157a3d47a6eafeff91f1e87de 100644 --- a/dumux/porousmediumflow/2p/formulation.hh +++ b/dumux/porousmediumflow/2p/formulation.hh @@ -25,16 +25,16 @@ #ifndef DUMUX_2P_FORMULATION_INDICES_HH #define DUMUX_2P_FORMULATION_INDICES_HH -namespace Dumux -{ +namespace Dumux { + /*! * \ingroup TwoPModel * \brief Enumerates the formulations which the two-phase model accepts. */ enum class TwoPFormulation { - pwsn, //!< pw and sn as primary variables - pnsw //!< pn and sw as primary variables + p0s1, //!< first phase pressure and second phase saturation as primary variables + p1s0 //!< first phase saturation and second phase pressure as primary variables }; } // namespace Dumux diff --git a/dumux/porousmediumflow/2p/griddatatransfer.hh b/dumux/porousmediumflow/2p/griddatatransfer.hh index e163baf4c1c36b79c746bc40c92c7cf8c2f83d63..748ffedeb9808c56e6523f13a45ba17bdb27f356 100644 --- a/dumux/porousmediumflow/2p/griddatatransfer.hh +++ b/dumux/porousmediumflow/2p/griddatatransfer.hh @@ -84,24 +84,24 @@ class TwoPGridDataTransfer : public GridDataTransfer // phase indices enum { - wPhaseIdx = FluidSystem::wPhaseIdx, - nPhaseIdx = FluidSystem::nPhaseIdx, + phase0Idx = FluidSystem::phase0Idx, + phase1Idx = FluidSystem::phase1Idx, }; // formulations - static constexpr auto pwsn = TwoPFormulation::pwsn; - static constexpr auto pnsw = TwoPFormulation::pnsw; + static constexpr auto p0s1 = TwoPFormulation::p0s1; + static constexpr auto p1s0 = TwoPFormulation::p1s0; // the formulation that is actually used static constexpr auto formulation = ModelTraits::priVarFormulation(); // This won't work (mass conservative) for compressible fluids - static_assert(!FluidSystem::isCompressible(wPhaseIdx) - && !FluidSystem::isCompressible(nPhaseIdx), + static_assert(!FluidSystem::isCompressible(phase0Idx) + && !FluidSystem::isCompressible(phase1Idx), "This adaption helper is only mass conservative for incompressible fluids!"); // check if the used formulation is implemented here - static_assert(formulation == pwsn || formulation == pnsw, "Chosen formulation not known to the TwoPGridDataTransfer"); + static_assert(formulation == p0s1 || formulation == p1s0, "Chosen formulation not known to the TwoPGridDataTransfer"); public: /*! \brief Constructor @@ -158,8 +158,8 @@ public: volVars.update(adaptedValues.u, *problem_, element, scv); const auto poreVolume = scv.volume()*volVars.porosity(); - adaptedValues.associatedMass[nPhaseIdx] += poreVolume * volVars.density(nPhaseIdx) * volVars.saturation(nPhaseIdx); - adaptedValues.associatedMass[wPhaseIdx] += poreVolume * volVars.density(wPhaseIdx) * volVars.saturation(wPhaseIdx); + adaptedValues.associatedMass[phase1Idx] += poreVolume * volVars.density(phase1Idx) * volVars.saturation(phase1Idx); + adaptedValues.associatedMass[phase0Idx] += poreVolume * volVars.density(phase0Idx) * volVars.saturation(phase0Idx); } // leaf elements always start with count = 1 @@ -243,15 +243,15 @@ public: // only recalculate the saturations if element hasn't been leaf before adaptation if (!adaptedValues.wasLeaf) { - if (formulation == pwsn) + if (formulation == p0s1) { - sol_[dofIdxGlobal][saturationIdx] = adaptedValues.associatedMass[nPhaseIdx]; - sol_[dofIdxGlobal][saturationIdx] /= elementVolume * volVars.density(nPhaseIdx) * volVars.porosity(); + sol_[dofIdxGlobal][saturationIdx] = adaptedValues.associatedMass[phase1Idx]; + sol_[dofIdxGlobal][saturationIdx] /= elementVolume * volVars.density(phase1Idx) * volVars.porosity(); } - else if (formulation == pnsw) + else if (formulation == p1s0) { - sol_[dofIdxGlobal][saturationIdx] = adaptedValues.associatedMass[wPhaseIdx]; - sol_[dofIdxGlobal][saturationIdx] /= elementVolume * volVars.density(wPhaseIdx) * volVars.porosity(); + sol_[dofIdxGlobal][saturationIdx] = adaptedValues.associatedMass[phase0Idx]; + sol_[dofIdxGlobal][saturationIdx] /= elementVolume * volVars.density(phase0Idx) * volVars.porosity(); } } } @@ -260,15 +260,15 @@ public: else { const auto scvVolume = scv.volume(); - if (formulation == pwsn) + if (formulation == p0s1) { - massCoeff[dofIdxGlobal] += scvVolume * volVars.density(nPhaseIdx) * volVars.porosity(); - associatedMass[dofIdxGlobal] += scvVolume / elementVolume * adaptedValues.associatedMass[nPhaseIdx]; + massCoeff[dofIdxGlobal] += scvVolume * volVars.density(phase1Idx) * volVars.porosity(); + associatedMass[dofIdxGlobal] += scvVolume / elementVolume * adaptedValues.associatedMass[phase1Idx]; } - else if (formulation == pnsw) + else if (formulation == p1s0) { - massCoeff[dofIdxGlobal] += scvVolume * volVars.density(wPhaseIdx) * volVars.porosity(); - associatedMass[dofIdxGlobal] += scvVolume / elementVolume * adaptedValues.associatedMass[wPhaseIdx]; + massCoeff[dofIdxGlobal] += scvVolume * volVars.density(phase0Idx) * volVars.porosity(); + associatedMass[dofIdxGlobal] += scvVolume / elementVolume * adaptedValues.associatedMass[phase0Idx]; } } } @@ -289,10 +289,10 @@ public: // obtain the mass contained in father Scalar massFather = 0.0; - if (formulation == pwsn) - massFather = adaptedValuesFather.associatedMass[nPhaseIdx]; - else if (formulation == pnsw) - massFather = adaptedValuesFather.associatedMass[wPhaseIdx]; + if (formulation == p0s1) + massFather = adaptedValuesFather.associatedMass[phase1Idx]; + else if (formulation == p1s0) + massFather = adaptedValuesFather.associatedMass[phase0Idx]; // obtain the element solution through the father auto elemSolSon = adaptedValuesFather.u; @@ -311,10 +311,10 @@ public: // overwrite the saturation by a mass conservative one here Scalar massCoeffSon = 0.0; - if (formulation == pwsn) - massCoeffSon = scv.volume() * volVars.density(nPhaseIdx) * volVars.porosity(); - else if (formulation == pnsw) - massCoeffSon = scv.volume() * volVars.density(wPhaseIdx) * volVars.porosity(); + if (formulation == p0s1) + massCoeffSon = scv.volume() * volVars.density(phase1Idx) * volVars.porosity(); + else if (formulation == p1s0) + massCoeffSon = scv.volume() * volVars.density(phase0Idx) * volVars.porosity(); sol_[scv.dofIndex()][saturationIdx] = (scv.volume() / fatherElement.geometry().volume() * massFather)/massCoeffSon; } } @@ -343,15 +343,15 @@ public: const auto dofIdxGlobal = scv.dofIndex(); const auto scvVolume = scv.volume(); - if (formulation == pwsn) + if (formulation == p0s1) { - massCoeff[dofIdxGlobal] += scvVolume * volVars.density(nPhaseIdx) * volVars.porosity(); - associatedMass[dofIdxGlobal] += scvVolume / fatherElementVolume * adaptedValuesFather.associatedMass[nPhaseIdx]; + massCoeff[dofIdxGlobal] += scvVolume * volVars.density(phase1Idx) * volVars.porosity(); + associatedMass[dofIdxGlobal] += scvVolume / fatherElementVolume * adaptedValuesFather.associatedMass[phase1Idx]; } - else if (formulation == pnsw) + else if (formulation == p1s0) { - massCoeff[dofIdxGlobal] += scvVolume * volVars.density(wPhaseIdx) * volVars.porosity(); - associatedMass[dofIdxGlobal] += scvVolume / fatherElementVolume * adaptedValuesFather.associatedMass[wPhaseIdx]; + massCoeff[dofIdxGlobal] += scvVolume * volVars.density(phase0Idx) * volVars.porosity(); + associatedMass[dofIdxGlobal] += scvVolume / fatherElementVolume * adaptedValuesFather.associatedMass[phase0Idx]; } // store constructed (pressure) values of son in the current solution (saturation comes later) diff --git a/dumux/porousmediumflow/2p/incompressiblelocalresidual.hh b/dumux/porousmediumflow/2p/incompressiblelocalresidual.hh index 23c2480cb7ad9aa12593e6eb60e235427293794e..421b5ce7af25fdc5018db0e6b7f4730f930d9b31 100644 --- a/dumux/porousmediumflow/2p/incompressiblelocalresidual.hh +++ b/dumux/porousmediumflow/2p/incompressiblelocalresidual.hh @@ -99,8 +99,8 @@ public: "2p/incompressiblelocalresidual.hh: Only incompressible fluids are allowed!"); static_assert(ModelTraits::numPhases() == 2, "2p/incompressiblelocalresidual.hh: Only two-phase models are allowed!"); - static_assert(ModelTraits::priVarFormulation() == TwoPFormulation::pwsn, - "2p/incompressiblelocalresidual.hh: Analytic differentiation has to be checked for pn-sw formulation!"); + static_assert(ModelTraits::priVarFormulation() == TwoPFormulation::p0s1, + "2p/incompressiblelocalresidual.hh: Analytic differentiation has to be checked for p1-s0 formulation!"); // we know that these values are constant throughout the simulation const auto poreVolume = scv.volume()*curVolVars.porosity(); @@ -167,8 +167,8 @@ public: "2p/incompressiblelocalresidual.hh: Only fluids with constant viscosities are allowed!"); static_assert(ModelTraits::numPhases() == 2, "2p/incompressiblelocalresidual.hh: Only two-phase models are allowed!"); - static_assert(ModelTraits::priVarFormulation() == TwoPFormulation::pwsn, - "2p/incompressiblelocalresidual.hh: Analytic differentiation has to be checked for pn-sw formulation!"); + static_assert(ModelTraits::priVarFormulation() == TwoPFormulation::p0s1, + "2p/incompressiblelocalresidual.hh: Analytic differentiation has to be checked for p1-s0 formulation!"); using MaterialLaw = typename GET_PROP_TYPE(TypeTag, MaterialLaw); using AdvectionType = typename GET_PROP_TYPE(TypeTag, AdvectionType); @@ -285,8 +285,8 @@ public: "2p/incompressiblelocalresidual.hh: Only fluids with constant viscosities are allowed!"); static_assert(ModelTraits::numPhases() == 2, "2p/incompressiblelocalresidual.hh: Only two-phase models are allowed!"); - static_assert(ModelTraits::priVarFormulation() == TwoPFormulation::pwsn, - "2p/incompressiblelocalresidual.hh: Analytic differentiation has to be checked for pn-sw formulation!"); + static_assert(ModelTraits::priVarFormulation() == TwoPFormulation::p0s1, + "2p/incompressiblelocalresidual.hh: Analytic differentiation has to be checked for p0-s1 formulation!"); using MaterialLaw = typename GET_PROP_TYPE(TypeTag, MaterialLaw); using AdvectionType = typename GET_PROP_TYPE(TypeTag, AdvectionType); diff --git a/dumux/porousmediumflow/2p/indices.hh b/dumux/porousmediumflow/2p/indices.hh index 8eed8d8dc7c6267ffc412e9a3dd4d8b3ace56a88..057dcacc5ef7e7f68f8b9b5c025dd18bfad70fca 100644 --- a/dumux/porousmediumflow/2p/indices.hh +++ b/dumux/porousmediumflow/2p/indices.hh @@ -33,43 +33,14 @@ namespace Dumux { * \ingroup TwoPModel * \brief Defines the indices required for the two-phase fully implicit model. */ -struct TwoPCommonIndices +struct TwoPIndices { // Primary variable indices - static const int pressureIdx = 0; //!< index for wetting/non-wetting phase pressure (depending on formulation) in a solution vector - static const int saturationIdx = 1; //!< index of the saturation of the non-wetting/wetting phase + static constexpr int pressureIdx = 0; //!< index for first/second phase pressure (depending on formulation) in a solution vector + static constexpr int saturationIdx = 1; //!< index of the saturation of the first/second phase // indices of the equations - static const int conti0EqIdx = 0; //!< index of the first continuity equation -}; - -/*! - * \ingroup TwoPModel - * \brief The indices for the \f$p_w-S_n\f$ formulation of the - * isothermal two-phase model. - * - * \tparam formulation The formulation, either pwsn or pnsw - */ -template <TwoPFormulation formulation = TwoPFormulation::pwsn> -struct TwoPIndices : public TwoPCommonIndices -{ - // indices of the primary variables - static constexpr int pwIdx = 0; //!< index of the wetting phase pressure - static constexpr int snIdx = 1; //!< index of the nonwetting phase saturation -}; - -/*! - * \ingroup TwoPModel - * \brief The indices for the \f$p_n-S_w\f$ formulation of the - * isothermal two-phase model. - */ -template <> -struct TwoPIndices<TwoPFormulation::pnsw> -: public TwoPCommonIndices -{ - // indices of the primary variables - static constexpr int pnIdx = 0; //!< index of the nonwetting phase pressure - static constexpr int swIdx = 1; //!< index of the wetting phase saturation + static constexpr int conti0EqIdx = 0; //!< index of the first continuity equation }; } // namespace Dumux diff --git a/dumux/porousmediumflow/2p/model.hh b/dumux/porousmediumflow/2p/model.hh index 139b57000a6ee4c9e0cbabc2c4932baf555e7f44..1aacdb680e02b1c7f0269bbb7d5ca5e21d2d9426 100644 --- a/dumux/porousmediumflow/2p/model.hh +++ b/dumux/porousmediumflow/2p/model.hh @@ -85,7 +85,7 @@ namespace Dumux template<TwoPFormulation formulation> struct TwoPModelTraits { - using Indices = TwoPIndices<formulation>; + using Indices = TwoPIndices; static constexpr TwoPFormulation priVarFormulation() { return formulation; } @@ -139,7 +139,7 @@ NEW_TYPE_TAG(TwoPNI, INHERITS_FROM(TwoP)); /////////////////////////////////////////////////////////////////////////// //!< Set the default formulation to pwsn SET_PROP(TwoP, Formulation) -{ static constexpr auto value = TwoPFormulation::pwsn; }; +{ static constexpr auto value = TwoPFormulation::p0s1; }; SET_TYPE_PROP(TwoP, LocalResidual, ImmiscibleLocalResidual<TypeTag>); //!< Use the immiscible local residual operator for the 2p model SET_TYPE_PROP(TwoP, SpatialParams, FVSpatialParams<TypeTag>); //!< The spatial parameters. Use FVSpatialParams by default. diff --git a/dumux/porousmediumflow/2p/volumevariables.hh b/dumux/porousmediumflow/2p/volumevariables.hh index 4fd91bb01b3491a2319ea7575974a141424dd3dd..2675a44511882cf48f51703e0dfd3ca6cb60987c 100644 --- a/dumux/porousmediumflow/2p/volumevariables.hh +++ b/dumux/porousmediumflow/2p/volumevariables.hh @@ -46,14 +46,15 @@ class TwoPVolumeVariables using Indices = typename ModelTraits::Indices; static constexpr auto formulation = ModelTraits::priVarFormulation(); using Scalar = typename Traits::PrimaryVariables::value_type; + using FS = typename Traits::FluidSystem; enum { pressureIdx = Indices::pressureIdx, saturationIdx = Indices::saturationIdx, - wPhaseIdx = Traits::FluidSystem::wPhaseIdx, - nPhaseIdx = Traits::FluidSystem::nPhaseIdx, - numPhases = ModelTraits::numPhases() + + phase0Idx = FS::phase0Idx, + phase1Idx = FS::phase1Idx }; @@ -82,9 +83,12 @@ public: completeFluidState(elemSol, problem, element, scv, fluidState_); + using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol); - using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; + const int wPhaseIdx = problem.spatialParams().template wettingPhase<FluidSystem>(element, scv, elemSol); + const int nPhaseIdx = 1 - wPhaseIdx; + mobility_[wPhaseIdx] = MaterialLaw::krw(materialParams, fluidState_.saturation(wPhaseIdx)) / fluidState_.viscosity(wPhaseIdx); @@ -111,44 +115,49 @@ public: * Set temperature, saturations, capillary pressures, viscosities, densities and enthalpies. */ template<class ElemSol, class Problem, class Element, class Scv> - static void completeFluidState(const ElemSol& elemSol, - const Problem& problem, - const Element& element, - const Scv& scv, - FluidState& fluidState) + void completeFluidState(const ElemSol& elemSol, + const Problem& problem, + const Element& element, + const Scv& scv, + FluidState& fluidState) { Scalar t = ParentType::temperature(elemSol, problem, element, scv); fluidState.setTemperature(t); + using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol); const auto& priVars = ParentType::extractDofPriVars(elemSol, scv); - using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; - if (formulation == TwoPFormulation::pwsn) { - Scalar sn = priVars[saturationIdx]; - fluidState.setSaturation(nPhaseIdx, sn); - fluidState.setSaturation(wPhaseIdx, 1 - sn); + const int wPhaseIdx = problem.spatialParams().template wettingPhase<FluidSystem>(element, scv, elemSol); + if (formulation == TwoPFormulation::p0s1) + { + fluidState.setSaturation(phase1Idx, priVars[saturationIdx]); + fluidState.setSaturation(phase0Idx, 1 - priVars[saturationIdx]); + } + else if (formulation == TwoPFormulation::p1s0) + { + fluidState.setSaturation(phase0Idx, priVars[saturationIdx]); + fluidState.setSaturation(phase1Idx, 1 - priVars[saturationIdx]); + } - Scalar pw = priVars[pressureIdx]; - fluidState.setPressure(wPhaseIdx, pw); - fluidState.setPressure(nPhaseIdx, - pw + MaterialLaw::pc(materialParams, 1 - sn)); + pc_ = MaterialLaw::pc(materialParams, fluidState.saturation(wPhaseIdx)); + if (formulation == TwoPFormulation::p0s1) + { + fluidState.setPressure(phase0Idx, priVars[pressureIdx]); + fluidState.setPressure(phase1Idx, (wPhaseIdx == phase0Idx) ? priVars[pressureIdx] + pc_ + : priVars[pressureIdx] - pc_); } - else if (formulation == TwoPFormulation::pnsw) { - Scalar sw = priVars[saturationIdx]; - fluidState.setSaturation(wPhaseIdx, sw); - fluidState.setSaturation(nPhaseIdx, 1 - sw); - - Scalar pn = priVars[pressureIdx]; - fluidState.setPressure(nPhaseIdx, pn); - fluidState.setPressure(wPhaseIdx, - pn - MaterialLaw::pc(materialParams, sw)); + else if (formulation == TwoPFormulation::p1s0) + { + fluidState.setPressure(phase1Idx, priVars[pressureIdx]); + fluidState.setPressure(phase0Idx, (wPhaseIdx == phase0Idx) ? priVars[pressureIdx] - pc_ + : priVars[pressureIdx] + pc_); } typename FluidSystem::ParameterCache paramCache; paramCache.updateAll(fluidState); - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { + for (int phaseIdx = 0; phaseIdx < ModelTraits::numPhases(); ++phaseIdx) { // compute and set the viscosity Scalar mu = FluidSystem::viscosity(fluidState, paramCache, phaseIdx); fluidState.setViscosity(phaseIdx, mu); @@ -201,7 +210,7 @@ public: * in \f$[kg/(m*s^2)=N/m^2=Pa]\f$. */ Scalar capillaryPressure() const - { return fluidState_.pressure(nPhaseIdx) - fluidState_.pressure(wPhaseIdx); } + { return pc_; } /*! * \brief Returns temperature inside the sub-control volume @@ -248,9 +257,10 @@ protected: FluidState fluidState_; private: + Scalar pc_; Scalar porosity_; PermeabilityType permeability_; - Scalar mobility_[numPhases]; + Scalar mobility_[ModelTraits::numPhases()]; }; } // end namespace Dumux diff --git a/dumux/porousmediumflow/2p/vtkoutputfields.hh b/dumux/porousmediumflow/2p/vtkoutputfields.hh index e3dc83685a713f797464f1119c31dc55ccfc1f3c..fea024af3354a45691583e913bb70bdaece70b0c 100644 --- a/dumux/porousmediumflow/2p/vtkoutputfields.hh +++ b/dumux/porousmediumflow/2p/vtkoutputfields.hh @@ -37,18 +37,20 @@ public: static void init(VtkOutputModule& vtk) { using VolumeVariables = typename VtkOutputModule::VolumeVariables; - using FluidSystem = typename VolumeVariables::FluidSystem; + using FS = typename VolumeVariables::FluidSystem; - vtk.addVolumeVariable([](const VolumeVariables& v){ return v.saturation(FluidSystem::wPhaseIdx); }, "Sw"); - vtk.addVolumeVariable([](const VolumeVariables& v){ return v.saturation(FluidSystem::nPhaseIdx); }, "Sn"); - vtk.addVolumeVariable([](const VolumeVariables& v){ return v.pressure(FluidSystem::wPhaseIdx); }, "pw"); - vtk.addVolumeVariable([](const VolumeVariables& v){ return v.pressure(FluidSystem::nPhaseIdx); }, "pn"); - vtk.addVolumeVariable([](const VolumeVariables& v){ return v.capillaryPressure(); }, "pc"); - vtk.addVolumeVariable([](const VolumeVariables& v){ return v.density(FluidSystem::wPhaseIdx); }, "rhoW"); - vtk.addVolumeVariable([](const VolumeVariables& v){ return v.density(FluidSystem::nPhaseIdx); }, "rhoN"); - vtk.addVolumeVariable([](const VolumeVariables& v){ return v.mobility(FluidSystem::wPhaseIdx); }, "mobW"); - vtk.addVolumeVariable([](const VolumeVariables& v){ return v.mobility(FluidSystem::nPhaseIdx); }, "mobN"); vtk.addVolumeVariable([](const VolumeVariables& v){ return v.porosity(); }, "porosity"); + vtk.addVolumeVariable([](const VolumeVariables& v){ return v.capillaryPressure(); }, "pc"); + + vtk.addVolumeVariable([](const VolumeVariables& v){ return v.saturation(FS::phase0Idx); }, "Sw"); + vtk.addVolumeVariable([](const VolumeVariables& v){ return v.pressure(FS::phase0Idx); }, "pw"); + vtk.addVolumeVariable([](const VolumeVariables& v){ return v.density(FS::phase0Idx); }, "rhoW"); + vtk.addVolumeVariable([](const VolumeVariables& v){ return v.mobility(FS::phase0Idx); }, "mobW"); + + vtk.addVolumeVariable([](const VolumeVariables& v){ return v.saturation(FS::phase1Idx); }, "Sn"); + vtk.addVolumeVariable([](const VolumeVariables& v){ return v.pressure(FS::phase1Idx); }, "pn"); + vtk.addVolumeVariable([](const VolumeVariables& v){ return v.density(FS::phase1Idx); }, "rhoN"); + vtk.addVolumeVariable([](const VolumeVariables& v){ return v.mobility(FS::phase1Idx); }, "mobN"); } }; diff --git a/dumux/porousmediumflow/2p1c/darcyslaw.hh b/dumux/porousmediumflow/2p1c/darcyslaw.hh index 826e365d197d888c647251a40292dbfb9568c1fc..15ee9a6d56aef8d241cd8ca929d64e06e5f37a51 100644 --- a/dumux/porousmediumflow/2p1c/darcyslaw.hh +++ b/dumux/porousmediumflow/2p1c/darcyslaw.hh @@ -70,8 +70,8 @@ class TwoPOneCDarcysLaw : public DarcysLaw<TypeTag> // copy some indices for convenience enum { // phase indices - wPhaseIdx = FluidSystem::wPhaseIdx, - nPhaseIdx = FluidSystem::nPhaseIdx, + liquidPhaseIdx = FluidSystem::liquidPhaseIdx, + gasPhaseIdx = FluidSystem::gasPhaseIdx, }; using DimWorldMatrix = Dune::FieldMatrix<Scalar, dimWorld, dimWorld>; @@ -91,7 +91,7 @@ public: const Scalar flux = ParentType::flux(problem, element, fvGeometry, elemVolVars, scvf, phaseIdx, elemFluxVarCache); // only block wetting-phase (i.e. liquid water) fluxes - if((!GET_PROP_VALUE(TypeTag, UseBlockingOfSpuriousFlow)) || phaseIdx != wPhaseIdx) + if((!GET_PROP_VALUE(TypeTag, UseBlockingOfSpuriousFlow)) || phaseIdx != liquidPhaseIdx) return flux; const auto& insideVolVars = elemVolVars[scvf.insideScvIdx()]; @@ -118,8 +118,8 @@ private: const Scalar tDn = dn.temperature(); //temperature of the downstream SCV (where the cold water is potentially intruding into a steam zone) const Scalar tUp = up.temperature(); //temperature of the upstream SCV - const Scalar sgDn = dn.saturation(nPhaseIdx); //gas phase saturation of the downstream SCV - const Scalar sgUp = up.saturation(nPhaseIdx); //gas phase saturation of the upstream SCV + const Scalar sgDn = dn.saturation(gasPhaseIdx); //gas phase saturation of the downstream SCV + const Scalar sgUp = up.saturation(gasPhaseIdx); //gas phase saturation of the upstream SCV bool upIsNotSteam = false; bool downIsSteam = false; @@ -131,7 +131,7 @@ private: if(sgDn > 1e-5) downIsSteam = true; - if(upIsNotSteam && downIsSteam && tDn > tUp && phaseIdx == wPhaseIdx) + if(upIsNotSteam && downIsSteam && tDn > tUp && phaseIdx == liquidPhaseIdx) spuriousFlow = true; if(spuriousFlow) diff --git a/dumux/porousmediumflow/2p1c/indices.hh b/dumux/porousmediumflow/2p1c/indices.hh index 3f0d6ed029478ea708e55f3b0519febc49630fc8..15d5959f23e3422a484941ebb5b273e7b5e8840b 100644 --- a/dumux/porousmediumflow/2p1c/indices.hh +++ b/dumux/porousmediumflow/2p1c/indices.hh @@ -35,9 +35,9 @@ class TwoPOneCIndices { public: // Present phases (-> 'pseudo' primary variable) - static const int twoPhases = 1; //!< Both wetting and non-wetting phase are present. - static const int wPhaseOnly = 2; //!< Only the wetting phase is present. - static const int nPhaseOnly = 3; //!< Only non-wetting phase is present. + static const int twoPhases = 1; //!< Both liquid and gas phase are present. + static const int liquidPhaseOnly = 2; //!< Only the liquid phase is present. + static const int gasPhaseOnly = 3; //!< Only gas phase is present. // Primary variable indices static const int pressureIdx = 0; //!< Index for phase pressure in a solution vector. diff --git a/dumux/porousmediumflow/2p1c/model.hh b/dumux/porousmediumflow/2p1c/model.hh index c74930eb90d8567f64d33d0a0fdc50bae532ccc5..281a0a28e7312451995a8a8f760a2ec9eefbef66 100644 --- a/dumux/porousmediumflow/2p1c/model.hh +++ b/dumux/porousmediumflow/2p1c/model.hh @@ -168,7 +168,7 @@ public: }; //! The primary variable switch for the 2p1cni model. -SET_TYPE_PROP(TwoPOneCNI, PrimaryVariableSwitch, TwoPOneCPrimaryVariableSwitch<TypeTag>); +SET_TYPE_PROP(TwoPOneCNI, PrimaryVariableSwitch, TwoPOneCPrimaryVariableSwitch); //! The primary variables vector for the 2p1cni model. SET_PROP(TwoPOneCNI, PrimaryVariables) diff --git a/dumux/porousmediumflow/2p1c/primaryvariableswitch.hh b/dumux/porousmediumflow/2p1c/primaryvariableswitch.hh index 3b37e48a93e13cb340d9fcdd3e1a50f83a3395a4..04034051326c225dba40439307f620531c4131a3 100644 --- a/dumux/porousmediumflow/2p1c/primaryvariableswitch.hh +++ b/dumux/porousmediumflow/2p1c/primaryvariableswitch.hh @@ -24,7 +24,6 @@ #ifndef DUMUX_2P1C_PRIMARY_VARIABLE_SWITCH_HH #define DUMUX_2P1C_PRIMARY_VARIABLE_SWITCH_HH -#include <dumux/common/properties.hh> #include <dumux/porousmediumflow/compositional/primaryvariableswitch.hh> namespace Dumux { @@ -33,36 +32,12 @@ namespace Dumux { * \ingroup TwoPOneCModel * \brief The primary variable switch for the two-phase one-component model */ -template<class TypeTag> class TwoPOneCPrimaryVariableSwitch -: public PrimaryVariableSwitch<TwoPOneCPrimaryVariableSwitch<TypeTag>> +: public PrimaryVariableSwitch<TwoPOneCPrimaryVariableSwitch> { - using ParentType = PrimaryVariableSwitch<TwoPOneCPrimaryVariableSwitch<TypeTag>>; + using ParentType = PrimaryVariableSwitch<TwoPOneCPrimaryVariableSwitch>; friend ParentType; - using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - using GridView = typename GET_PROP_TYPE(TypeTag, GridView); - using IndexType = typename GridView::IndexSet::IndexType; - using GlobalPosition = Dune::FieldVector<Scalar, GridView::dimensionworld>; - - using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); - using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables); - using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; - using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); - - enum { - switchIdx = Indices::switchIdx, - - pressureIdx = Indices::pressureIdx, - - wPhaseIdx = FluidSystem::wPhaseIdx, - nPhaseIdx = FluidSystem::nPhaseIdx, - - twoPhases = Indices::twoPhases, - wPhaseOnly = Indices::wPhaseOnly, - nPhaseOnly = Indices::nPhaseOnly - }; - public: using ParentType::ParentType; @@ -76,48 +51,54 @@ protected: * \param dofIdxGlobal The respective dof index. * \param globalPos The global position of the dof. */ - bool update_(PrimaryVariables& priVars, + template<class VolumeVariables, class GlobalPosition> + bool update_(typename VolumeVariables::PrimaryVariables& priVars, const VolumeVariables& volVars, - IndexType dofIdxGlobal, + std::size_t dofIdxGlobal, const GlobalPosition& globalPos) { + using Scalar = typename VolumeVariables::PrimaryVariables::value_type; + using FluidSystem = typename VolumeVariables::FluidSystem; + using Indices = typename VolumeVariables::Indices; + + // evaluate primary variable switch bool wouldSwitch = false; int phasePresence = priVars.state(); int newPhasePresence = phasePresence; // check if a primary var switch is necessary - if (phasePresence == twoPhases) + if (phasePresence == Indices::twoPhases) { Scalar Smin = 0; if (this->wasSwitched_[dofIdxGlobal]) Smin = -0.01; - if (volVars.saturation(nPhaseIdx) <= Smin) + if (volVars.saturation(FluidSystem::gasPhaseIdx) <= Smin) { wouldSwitch = true; // gas phase disappears std::cout << "Gas phase disappears at vertex " << dofIdxGlobal << ", coordinates: " << globalPos << ", sg: " - << volVars.saturation(nPhaseIdx) << std::endl; - newPhasePresence = wPhaseOnly; + << volVars.saturation(FluidSystem::gasPhaseIdx) << std::endl; + newPhasePresence = Indices::liquidPhaseOnly; - priVars[switchIdx] = volVars.fluidState().temperature(); + priVars[Indices::switchIdx] = volVars.fluidState().temperature(); } - else if (volVars.saturation(wPhaseIdx) <= Smin) + else if (volVars.saturation(FluidSystem::liquidPhaseIdx) <= Smin) { wouldSwitch = true; // water phase disappears - std::cout << "Wetting phase disappears at vertex " << dofIdxGlobal + std::cout << "Liquid phase disappears at vertex " << dofIdxGlobal << ", coordinates: " << globalPos << ", sw: " - << volVars.saturation(wPhaseIdx) << std::endl; - newPhasePresence = nPhaseOnly; + << volVars.saturation(FluidSystem::liquidPhaseIdx) << std::endl; + newPhasePresence = Indices::gasPhaseOnly; - priVars[switchIdx] = volVars.fluidState().temperature(); + priVars[Indices::switchIdx] = volVars.fluidState().temperature(); } } - else if (phasePresence == wPhaseOnly) + else if (phasePresence == Indices::liquidPhaseOnly) { const Scalar temp = volVars.fluidState().temperature(); const Scalar tempVap = volVars.vaporTemperature(); @@ -131,13 +112,13 @@ protected: std::cout << "gas phase appears at vertex " << dofIdxGlobal << ", coordinates: " << globalPos << std::endl; - newPhasePresence = twoPhases; - priVars[switchIdx] = 0.9999; //wetting phase saturation + newPhasePresence = Indices::twoPhases; + priVars[Indices::switchIdx] = 0.9999; // liquid phase saturation } } - else if (phasePresence == nPhaseOnly) + else if (phasePresence == Indices::gasPhaseOnly) { const Scalar temp = volVars.fluidState().temperature(); @@ -146,13 +127,13 @@ protected: if (temp < tempVap) { wouldSwitch = true; - // wetting phase appears - std::cout << "wetting phase appears at vertex " << dofIdxGlobal + // liquid phase appears + std::cout << "Liquid phase appears at vertex " << dofIdxGlobal << ", coordinates: " << globalPos << std::endl; - newPhasePresence = twoPhases; - priVars[switchIdx] = 0.0001; //arbitrary small value + newPhasePresence = Indices::twoPhases; + priVars[Indices::switchIdx] = 0.0001; //arbitrary small value } } priVars.setState(newPhasePresence); diff --git a/dumux/porousmediumflow/2p1c/volumevariables.hh b/dumux/porousmediumflow/2p1c/volumevariables.hh index de6659db9ce059adcd8579f3c41d87014a3fd794..13583f6b3fbd0fac2b802a164fddca72b6529391 100644 --- a/dumux/porousmediumflow/2p1c/volumevariables.hh +++ b/dumux/porousmediumflow/2p1c/volumevariables.hh @@ -40,23 +40,19 @@ class TwoPOneCVolumeVariables using Scalar = typename Traits::PrimaryVariables::value_type; using PermeabilityType = typename Traits::PermeabilityType; using FS = typename Traits::FluidSystem; - using Indices = typename Traits::ModelTraits::Indices; + using Idx = typename Traits::ModelTraits::Indices; enum { numPhases = Traits::ModelTraits::numPhases(), - - wPhaseIdx = FS::wPhaseIdx, - nPhaseIdx = FS::nPhaseIdx, - - switchIdx = Indices::switchIdx, - pressureIdx = Indices::pressureIdx + switchIdx = Idx::switchIdx, + pressureIdx = Idx::pressureIdx }; // present phases enum { - twoPhases = Indices::twoPhases, - wPhaseOnly = Indices::wPhaseOnly, - nPhaseOnly = Indices::nPhaseOnly, + twoPhases = Idx::twoPhases, + liquidPhaseOnly = Idx::liquidPhaseOnly, + gasPhaseOnly = Idx::gasPhaseOnly, }; public: @@ -64,6 +60,13 @@ public: using FluidState = typename Traits::FluidState; //! The type of the fluid system using FluidSystem = typename Traits::FluidSystem; + //! The type of the indices + using Indices = typename Traits::ModelTraits::Indices; + + // set liquid phase as wetting phase: TODO make this more flexible + static constexpr int wPhaseIdx = FluidSystem::liquidPhaseIdx; + // set gas phase as non-wetting phase: TODO make this more flexible + static constexpr int nPhaseIdx = FluidSystem::gasPhaseIdx; /*! * \brief Update all quantities for a given control volume @@ -136,12 +139,12 @@ public: sw = priVars[switchIdx]; sg = 1.0 - sw; } - else if (phasePresence == wPhaseOnly) + else if (phasePresence == liquidPhaseOnly) { sw = 1.0; sg = 0.0; } - else if (phasePresence == nPhaseOnly) + else if (phasePresence == gasPhaseOnly) { sw = 0.0; sg = 1.0; @@ -168,7 +171,7 @@ public: // get temperature Scalar temperature; - if (phasePresence == wPhaseOnly || phasePresence == nPhaseOnly) + if (phasePresence == liquidPhaseOnly || phasePresence == gasPhaseOnly) temperature = priVars[switchIdx]; else if (phasePresence == twoPhases) temperature = FluidSystem::vaporTemperature(fluidState, wPhaseIdx); diff --git a/dumux/porousmediumflow/2p2c/indices.hh b/dumux/porousmediumflow/2p2c/indices.hh index 9f04c8de237e82c2642dd86b57beb91bec911c5c..ae353161751e532ec391b0be43c35f74fdb67278 100644 --- a/dumux/porousmediumflow/2p2c/indices.hh +++ b/dumux/porousmediumflow/2p2c/indices.hh @@ -29,31 +29,20 @@ namespace Dumux { /*! * \brief The indices for the isothermal two-phase two-component model. * \ingroup TwoPTwoCModel - * - * \tparam wCompIdx index of the wetting component - * \tparam nCompIdx index of the non-wetting component */ -template<int wCompIdx, int nCompIdx> struct TwoPTwoCIndices { // present phases (-> 'pseudo' primary variable) - static constexpr int wPhaseOnly = 1; //!< Only the non-wetting phase is present - static constexpr int nPhaseOnly = 2; //!< Only the wetting phase is present - static constexpr int bothPhases = 3; //!< Both phases are present + static constexpr int firstPhaseOnly = 1; //!< Only the first phase (in fluid system) is present + static constexpr int secondPhaseOnly = 2; //!< Only the second phase (in fluid system) is present + static constexpr int bothPhases = 3; //!< Both phases are present // Primary variable indices - //! index for wetting/non-wetting phase pressure (depending on the formulation) in a solution vector - static constexpr int pressureIdx = 0; - //! index of either the saturation or the mass fraction of the non-wetting/wetting phase - static constexpr int switchIdx = 1; + static constexpr int pressureIdx = 0; //! index for first/second phase pressure (depending on formulation) in privar vector + static constexpr int switchIdx = 1; //! index of either the saturation or the mass/mole fraction of the first/second component // equation indices - //! index of the mass conservation equation for the first component - static constexpr int conti0EqIdx = 0; - //! index of the mass conservation equation for the primary component of the wetting phase - static constexpr int contiWEqIdx = conti0EqIdx + wCompIdx; - //! index of the mass conservation equation for the primary component of the non-wetting phase - static constexpr int contiNEqIdx = conti0EqIdx + nCompIdx; + static constexpr int conti0EqIdx = 0; //! index of the conservation equation for the first component }; } // end namespace Dumux diff --git a/dumux/porousmediumflow/2p2c/model.hh b/dumux/porousmediumflow/2p2c/model.hh index 24829936c3397824cf0ad4dadb110d522ebf210e..2bd9e7c2916c96f6356267229cc704b2ea837a97 100644 --- a/dumux/porousmediumflow/2p2c/model.hh +++ b/dumux/porousmediumflow/2p2c/model.hh @@ -106,14 +106,12 @@ namespace Dumux { * \brief Specifies a number properties of two-phase two-component models. * * \tparam f The two-phase formulation used - * \tparam wCompIdx The index of the wetting component - * \tparam nCompIdx The index of the non-wetting component * \tparam useM Boolean to specify if moles or masses are balanced */ -template<TwoPFormulation f, int wCompIdx, int nCompIdx, bool useM> +template<TwoPFormulation f, bool useM> struct TwoPTwoCModelTraits { - using Indices = TwoPTwoCIndices<wCompIdx, nCompIdx>; + using Indices = TwoPTwoCIndices; static constexpr int numEq() { return 2; } static constexpr int numPhases() { return 2; } @@ -176,8 +174,6 @@ private: public: using type = TwoPTwoCModelTraits< GET_PROP_VALUE(TypeTag, Formulation), - FluidSystem::wCompIdx, - FluidSystem::nCompIdx, GET_PROP_VALUE(TypeTag, UseMoles) >; }; @@ -201,10 +197,7 @@ public: //! Set the default formulation to pw-sn SET_PROP(TwoPTwoC, Formulation) -{ -public: - static const TwoPFormulation value = TwoPFormulation::pwsn; -}; +{ static constexpr TwoPFormulation value = TwoPFormulation::p0s1; }; //! Set as default that no component mass balance is replaced by the total mass balance SET_INT_PROP(TwoPTwoC, ReplaceCompEqIdx, GET_PROP_TYPE(TypeTag, ModelTraits)::numComponents()); @@ -280,8 +273,6 @@ private: static_assert(FluidSystem::numComponents == 2, "Only fluid systems with 2 components are supported by the 2p-2c model!"); static_assert(FluidSystem::numPhases == 2, "Only fluid systems with 2 phases are supported by the 2p-2c model!"); using Traits = TwoPTwoCModelTraits< GET_PROP_VALUE(TypeTag, Formulation), - FluidSystem::wCompIdx, - FluidSystem::nCompIdx, GET_PROP_VALUE(TypeTag, UseMoles) >; public: using type = PorousMediumFlowNIModelTraits< Traits >; diff --git a/dumux/porousmediumflow/2p2c/primaryvariableswitch.hh b/dumux/porousmediumflow/2p2c/primaryvariableswitch.hh index eedbec306d2ee96626ef12eded63b16da7980f10..339d15a74fe3868f6eef70be2dd2d14532274d86 100644 --- a/dumux/porousmediumflow/2p2c/primaryvariableswitch.hh +++ b/dumux/porousmediumflow/2p2c/primaryvariableswitch.hh @@ -51,13 +51,15 @@ protected: using Scalar = typename VolumeVariables::PrimaryVariables::value_type; using FluidSystem = typename VolumeVariables::FluidSystem; - static constexpr int wPhaseIdx = FluidSystem::wPhaseIdx; - static constexpr int nPhaseIdx = FluidSystem::nPhaseIdx; - static constexpr int wCompIdx = FluidSystem::wCompIdx; - static constexpr int nCompIdx = FluidSystem::nCompIdx; + static constexpr int phase0Idx = FluidSystem::phase0Idx; + static constexpr int phase1Idx = FluidSystem::phase1Idx; + static constexpr int comp0Idx = FluidSystem::comp0Idx; + static constexpr int comp1Idx = FluidSystem::comp1Idx; static constexpr bool useMoles = VolumeVariables::useMoles(); static constexpr auto formulation = VolumeVariables::priVarFormulation(); + static_assert( (formulation == TwoPFormulation::p0s1 || formulation == TwoPFormulation::p1s0), + "Chosen TwoPFormulation not supported!"); using Indices = typename VolumeVariables::Indices; static constexpr int switchIdx = Indices::switchIdx; @@ -68,11 +70,11 @@ protected: int newPhasePresence = phasePresence; // check if a primary var switch is necessary - if (phasePresence == Indices::nPhaseOnly) + if (phasePresence == Indices::secondPhaseOnly) { - // calculate mole fraction in the hypothetic wetting phase - Scalar xww = volVars.moleFraction(wPhaseIdx, wCompIdx); - Scalar xwn = volVars.moleFraction(wPhaseIdx, nCompIdx); + // calculate mole fraction in the hypothetic first phase + Scalar xww = volVars.moleFraction(phase0Idx, comp0Idx); + Scalar xwn = volVars.moleFraction(phase0Idx, comp1Idx); Scalar xwMax = 1.0; if (xww + xwn > xwMax) @@ -81,26 +83,26 @@ protected: xwMax *= 1.02; // if the sum of the mole fractions is larger than - // 100%, wetting phase appears + // 100%, first phase appears if (xww + xwn > xwMax) { // wetting phase appears - std::cout << "wetting phase appears at vertex " << dofIdxGlobal - << ", coordinates: " << globalPos << ", xww + xwn: " + std::cout << "first phase appears at vertex " << dofIdxGlobal + << ", coordinates: " << globalPos << ", x00 + x01: " << xww + xwn << std::endl; newPhasePresence = Indices::bothPhases; - if (formulation == TwoPFormulation::pnsw) + if (formulation == TwoPFormulation::p1s0) priVars[switchIdx] = 0.0001; - else if (formulation == TwoPFormulation::pwsn) + else priVars[switchIdx] = 0.9999; } } - else if (phasePresence == Indices::wPhaseOnly) + else if (phasePresence == Indices::firstPhaseOnly) { // calculate fractions of the partial pressures in the // hypothetic nonwetting phase - Scalar xnw = volVars.moleFraction(nPhaseIdx, wCompIdx); - Scalar xnn = volVars.moleFraction(nPhaseIdx, nCompIdx); + Scalar xnw = volVars.moleFraction(phase1Idx, comp0Idx); + Scalar xnn = volVars.moleFraction(phase1Idx, comp1Idx); Scalar xgMax = 1.0; if (xnw + xnn > xgMax) @@ -113,13 +115,13 @@ protected: if (xnw + xnn > xgMax) { // nonwetting phase appears - std::cout << "nonwetting phase appears at vertex " << dofIdxGlobal - << ", coordinates: " << globalPos << ", xnw + xnn: " + std::cout << "second phase appears at vertex " << dofIdxGlobal + << ", coordinates: " << globalPos << ", x10 + x11: " << xnw + xnn << std::endl; newPhasePresence = Indices::bothPhases; - if (formulation == TwoPFormulation::pnsw) + if (formulation == TwoPFormulation::p1s0) priVars[switchIdx] = 0.9999; - else if (formulation == TwoPFormulation::pwsn) + else priVars[switchIdx] = 0.0001; } } @@ -129,33 +131,33 @@ protected: if (this->wasSwitched_[dofIdxGlobal]) Smin = -0.01; - if (volVars.saturation(nPhaseIdx) <= Smin) + if (volVars.saturation(phase1Idx) <= Smin) { wouldSwitch = true; // nonwetting phase disappears - std::cout << "Nonwetting phase disappears at vertex " << dofIdxGlobal - << ", coordinates: " << globalPos << ", sn: " - << volVars.saturation(nPhaseIdx) << std::endl; - newPhasePresence = Indices::wPhaseOnly; + std::cout << "second phase disappears at vertex " << dofIdxGlobal + << ", coordinates: " << globalPos << ", s1: " + << volVars.saturation(phase1Idx) << std::endl; + newPhasePresence = Indices::firstPhaseOnly; if(useMoles) // mole-fraction formulation - priVars[switchIdx] = volVars.moleFraction(wPhaseIdx, nCompIdx); + priVars[switchIdx] = volVars.moleFraction(phase0Idx, comp1Idx); else // mass-fraction formulation - priVars[switchIdx] = volVars.massFraction(wPhaseIdx, nCompIdx); + priVars[switchIdx] = volVars.massFraction(phase0Idx, comp1Idx); } - else if (volVars.saturation(wPhaseIdx) <= Smin) + else if (volVars.saturation(phase0Idx) <= Smin) { wouldSwitch = true; // wetting phase disappears - std::cout << "Wetting phase disappears at vertex " << dofIdxGlobal - << ", coordinates: " << globalPos << ", sw: " - << volVars.saturation(wPhaseIdx) << std::endl; - newPhasePresence = Indices::nPhaseOnly; + std::cout << "first phase disappears at vertex " << dofIdxGlobal + << ", coordinates: " << globalPos << ", s0: " + << volVars.saturation(phase0Idx) << std::endl; + newPhasePresence = Indices::secondPhaseOnly; if(useMoles) // mole-fraction formulation - priVars[switchIdx] = volVars.moleFraction(nPhaseIdx, wCompIdx); + priVars[switchIdx] = volVars.moleFraction(phase1Idx, comp0Idx); else // mass-fraction formulation - priVars[switchIdx] = volVars.massFraction(nPhaseIdx, wCompIdx); + priVars[switchIdx] = volVars.massFraction(phase1Idx, comp0Idx); } } diff --git a/dumux/porousmediumflow/2p2c/sequential/properties.hh b/dumux/porousmediumflow/2p2c/sequential/properties.hh index 4d05a5af1aa95af650bc329a0816e8c554f401b5..f6a2cb3c66a38a3c7bee0eeae5c4ce512ab7470b 100644 --- a/dumux/porousmediumflow/2p2c/sequential/properties.hh +++ b/dumux/porousmediumflow/2p2c/sequential/properties.hh @@ -170,8 +170,8 @@ private: public: // Component indices - static const int wPhaseIdx = FluidSystem::wPhaseIdx; - static const int nPhaseIdx = FluidSystem::nPhaseIdx; + static const int wPhaseIdx = FluidSystem::phase0Idx; + static const int nPhaseIdx = FluidSystem::phase1Idx; // Component indices static const int wCompIdx = wPhaseIdx; //!< Component index equals phase index diff --git a/dumux/porousmediumflow/2p2c/volumevariables.hh b/dumux/porousmediumflow/2p2c/volumevariables.hh index 041f54af2b5c0e22083578a3b97d057db3ba5acd..649b6fb68549865fb2fabd11010bac87580028aa 100644 --- a/dumux/porousmediumflow/2p2c/volumevariables.hh +++ b/dumux/porousmediumflow/2p2c/volumevariables.hh @@ -52,17 +52,17 @@ class TwoPTwoCVolumeVariables // component indices enum { - wCompIdx = Traits::FluidSystem::wCompIdx, - nCompIdx = Traits::FluidSystem::nCompIdx, - wPhaseIdx = Traits::FluidSystem::wPhaseIdx, - nPhaseIdx = Traits::FluidSystem::nPhaseIdx + comp0Idx = Traits::FluidSystem::comp0Idx, + comp1Idx = Traits::FluidSystem::comp1Idx, + phase0Idx = Traits::FluidSystem::phase0Idx, + phase1Idx = Traits::FluidSystem::phase1Idx }; // phase presence indices enum { - wPhaseOnly = ModelTraits::Indices::wPhaseOnly, - nPhaseOnly = ModelTraits::Indices::nPhaseOnly, + firstPhaseOnly = ModelTraits::Indices::firstPhaseOnly, + secondPhaseOnly = ModelTraits::Indices::secondPhaseOnly, bothPhases = ModelTraits::Indices::bothPhases }; @@ -75,18 +75,13 @@ class TwoPTwoCVolumeVariables // formulations static constexpr auto formulation = ModelTraits::priVarFormulation(); - static constexpr auto pwsn = TwoPFormulation::pwsn; - static constexpr auto pnsw = TwoPFormulation::pnsw; // further specifications on the variables update - static constexpr bool useKelvinEquation = Traits::useKelvinEquation; static constexpr bool useConstraintSolver = Traits::useConstraintSolver; using PermeabilityType = typename Traits::PermeabilityType; using ComputeFromReferencePhase = Dumux::ComputeFromReferencePhase<Scalar, typename Traits::FluidSystem>; - using MiscibleMultiPhaseComposition = Dumux::MiscibleMultiPhaseComposition< Scalar, - typename Traits::FluidSystem, - useKelvinEquation>; + using MiscibleMultiPhaseComposition = Dumux::MiscibleMultiPhaseComposition< Scalar, typename Traits::FluidSystem >; public: //! The type of the object returned by the fluidState() method using FluidState = typename Traits::FluidState; @@ -102,6 +97,12 @@ public: static_assert(useMoles() || (!useMoles() && useConstraintSolver), "if !UseMoles, UseConstraintSolver has to be set to true"); static_assert(ModelTraits::numPhases() == 2, "NumPhases set in the model is not two!"); static_assert(ModelTraits::numComponents() == 2, "NumComponents set in the model is not two!"); + static_assert((formulation == TwoPFormulation::p0s1 || formulation == TwoPFormulation::p1s0), "Chosen TwoPFormulation not supported!"); + + // The computations in the explicit composition update most probably assume a liquid-gas interface with + // liquid as first phase. TODO: is this really needed? The constraint solver does the job anyway, doesn't it? + static_assert(useConstraintSolver || (FluidSystem::isLiquid(phase0Idx) && !FluidSystem::isLiquid(phase1Idx)), + "Explicit composition calculation has to be re-checked for NON-liquid-gas equilibria"); /*! * \brief Update all quantities for a given control volume @@ -125,14 +126,17 @@ public: using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; const auto& matParams = problem.spatialParams().materialLawParams(element, scv, elemSol); - for (int phaseIdx = 0; phaseIdx < ModelTraits::numPhases(); ++phaseIdx) - { - // relative permeabilities -> require wetting phase saturation as parameter! - relativePermeability_[phaseIdx] = (phaseIdx == wPhaseIdx) ? MaterialLaw::krw(matParams, saturation(wPhaseIdx)) - : MaterialLaw::krn(matParams, saturation(wPhaseIdx)); - // binary diffusion coefficients - diffCoeff_[phaseIdx] = FluidSystem::binaryDiffusionCoefficient(fluidState_, paramCache, phaseIdx, wCompIdx, nCompIdx); - } + + const int wPhaseIdx = problem.spatialParams().template wettingPhase<FluidSystem>(element, scv, elemSol); + const int nPhaseIdx = 1 - wPhaseIdx; + + // relative permeabilities -> require wetting phase saturation as parameter! + relativePermeability_[wPhaseIdx] = MaterialLaw::krw(matParams, saturation(wPhaseIdx)); + relativePermeability_[nPhaseIdx] = MaterialLaw::krn(matParams, saturation(wPhaseIdx)); + + // binary diffusion coefficients + diffCoeff_[phase0Idx] = FluidSystem::binaryDiffusionCoefficient(fluidState_, paramCache, phase0Idx, comp0Idx, comp1Idx); + diffCoeff_[phase1Idx] = FluidSystem::binaryDiffusionCoefficient(fluidState_, paramCache, phase1Idx, comp0Idx, comp1Idx); // porosity & permeabilty porosity_ = problem.spatialParams().porosity(element, scv, elemSol); @@ -151,11 +155,11 @@ public: * Set temperature, saturations, capillary pressures, viscosities, densities and enthalpies. */ template<class ElemSol, class Problem, class Element, class Scv> - static void completeFluidState(const ElemSol& elemSol, - const Problem& problem, - const Element& element, - const Scv& scv, - FluidState& fluidState) + void completeFluidState(const ElemSol& elemSol, + const Problem& problem, + const Element& element, + const Scv& scv, + FluidState& fluidState) { const auto t = ParentType::temperature(elemSol, problem, element, scv); fluidState.setTemperature(t); @@ -163,59 +167,59 @@ public: const auto& priVars = ParentType::extractDofPriVars(elemSol, scv); const auto phasePresence = priVars.state(); + using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; + const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol); + const int wPhaseIdx = problem.spatialParams().template wettingPhase<FluidSystem>(element, scv, elemSol); + fluidState.setWettingPhase(wPhaseIdx); + // set the saturations - Scalar sn; - if (phasePresence == nPhaseOnly) - sn = 1.0; - else if (phasePresence == wPhaseOnly) - sn = 0.0; + if (phasePresence == firstPhaseOnly) + { + fluidState.setSaturation(phase0Idx, 1.0); + fluidState.setSaturation(phase1Idx, 0.0); + } + else if (phasePresence == secondPhaseOnly) + { + fluidState.setSaturation(phase0Idx, 0.0); + fluidState.setSaturation(phase1Idx, 1.0); + } else if (phasePresence == bothPhases) { - if (formulation == pwsn) - sn = priVars[switchIdx]; - else if (formulation == pnsw) - sn = 1.0 - priVars[switchIdx]; + if (formulation == TwoPFormulation::p0s1) + { + fluidState.setSaturation(phase1Idx, priVars[switchIdx]); + fluidState.setSaturation(phase0Idx, 1 - priVars[switchIdx]); + } else - DUNE_THROW(Dune::InvalidStateException, "Chosen TwoPFormulation not supported by the TwoPTwoCVolumeVariables."); + { + fluidState.setSaturation(phase0Idx, priVars[switchIdx]); + fluidState.setSaturation(phase1Idx, 1 - priVars[switchIdx]); + } } else DUNE_THROW(Dune::InvalidStateException, "Invalid phase presence."); - fluidState.setSaturation(wPhaseIdx, 1 - sn); - fluidState.setSaturation(nPhaseIdx, sn); - - // calculate capillary pressure - using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; - const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol); - Scalar pc = MaterialLaw::pc(materialParams, 1 - sn); - // set the pressures of the fluid phases - if (formulation == pwsn) { - fluidState.setPressure(wPhaseIdx, priVars[pressureIdx]); - fluidState.setPressure(nPhaseIdx, priVars[pressureIdx] + pc); + // set pressures of the fluid phases + pc_ = MaterialLaw::pc(materialParams, fluidState.saturation(wPhaseIdx)); + if (formulation == TwoPFormulation::p0s1) + { + fluidState.setPressure(phase0Idx, priVars[pressureIdx]); + fluidState.setPressure(phase1Idx, (wPhaseIdx == phase0Idx) ? priVars[pressureIdx] + pc_ + : priVars[pressureIdx] - pc_); } - else if (formulation == pnsw) { - fluidState.setPressure(nPhaseIdx, priVars[pressureIdx]); - fluidState.setPressure(wPhaseIdx, priVars[pressureIdx] - pc); + else + { + fluidState.setPressure(phase1Idx, priVars[pressureIdx]); + fluidState.setPressure(phase0Idx, (wPhaseIdx == phase0Idx) ? priVars[pressureIdx] - pc_ + : priVars[pressureIdx] + pc_); } - else DUNE_THROW(Dune::InvalidStateException, "Chosen TwoPFormulation not supported by the TwoPTwoCVolumeVariables."); // calculate the phase compositions typename FluidSystem::ParameterCache paramCache; // If constraint solver is not used, get the phase pressures and set the fugacity coefficients here - Scalar pn = 0; - Scalar pw = 0; if(!useConstraintSolver) { - if (formulation == pwsn) { - pw = priVars[pressureIdx]; - pn = pw + pc; - } - else { - pn = priVars[pressureIdx]; - pw = pn - pc; - } - for (int phaseIdx = 0; phaseIdx < ModelTraits::numPhases(); ++ phaseIdx) { assert(FluidSystem::isIdealMixture(phaseIdx)); @@ -227,12 +231,13 @@ public: } // now comes the tricky part: calculate phase compositions + const Scalar p0 = fluidState.pressure(phase0Idx); + const Scalar p1 = fluidState.pressure(phase1Idx); if (phasePresence == bothPhases) { - // both phases are present, phase compositions are a - // result of the nonwetting <-> wetting equilibrium. This is - // the job of the "MiscibleMultiPhaseComposition" - // constraint solver + // both phases are present, phase compositions are a result + // of the equilibrium between the phases. This is the job + // of the "MiscibleMultiPhaseComposition" constraint solver if(useConstraintSolver) MiscibleMultiPhaseComposition::solve(fluidState, paramCache, @@ -241,49 +246,42 @@ public: // ... or calculated explicitly this way ... else { - // get the partial pressure of the main component of the the wetting phase ("H20") within the - // nonwetting (gas) phase == vapor pressure due to equilibrium. Note that in this case the - // fugacityCoefficient * pw is the vapor pressure (see implementation in respective fluidsystem) - Scalar partPressH2O; - if (useKelvinEquation) - partPressH2O = FluidSystem::kelvinVaporPressure(fluidState, wPhaseIdx, wCompIdx); - else - partPressH2O = FluidSystem::fugacityCoefficient(fluidState, wPhaseIdx, wCompIdx)*pw; - - // get the partial pressure of the main component of the the nonwetting (gas) phase ("Air") - Scalar partPressAir = pn - partPressH2O; + // get the partial pressure of the main component of the first phase within the + // second phase == vapor pressure due to equilibrium. Note that in this case the + // fugacityCoefficient * p is the vapor pressure (see implementation in respective fluidsystem) + const Scalar partPressLiquid = FluidSystem::fugacityCoefficient(fluidState, phase0Idx, comp0Idx)*p0; + + // get the partial pressure of the main component of the gas phase + const Scalar partPressGas = p1 - partPressLiquid; // calculate the mole fractions of the components within the nonwetting phase - Scalar xnn = partPressAir/pn; - Scalar xnw = partPressH2O/pn; + const Scalar xnn = partPressGas / p1; + const Scalar xnw = partPressLiquid / p1; // calculate the mole fractions of the components within the wetting phase - // note that in this case the fugacityCoefficient * pw is the Henry Coefficient + // note that in this case the fugacityCoefficient * p is the Henry Coefficient // (see implementation in respective fluidsystem) - Scalar xwn = partPressAir/( FluidSystem::fugacityCoefficient(fluidState, wPhaseIdx, nCompIdx)*pw ); - Scalar xww = 1.0 -xwn; + const Scalar xwn = partPressGas / (FluidSystem::fugacityCoefficient(fluidState, phase0Idx, comp1Idx)*p0); + const Scalar xww = 1.0 - xwn; // set all mole fractions - fluidState.setMoleFraction(wPhaseIdx, wCompIdx, xww); - fluidState.setMoleFraction(wPhaseIdx, nCompIdx, xwn); - fluidState.setMoleFraction(nPhaseIdx, wCompIdx, xnw); - fluidState.setMoleFraction(nPhaseIdx, nCompIdx, xnn); + fluidState.setMoleFraction(phase0Idx, comp0Idx, xww); + fluidState.setMoleFraction(phase0Idx, comp1Idx, xwn); + fluidState.setMoleFraction(phase1Idx, comp0Idx, xnw); + fluidState.setMoleFraction(phase1Idx, comp1Idx, xnn); } } - else if (phasePresence == nPhaseOnly) + else if (phasePresence == secondPhaseOnly) { - // only the nonwetting phase is present, i.e. nonwetting phase - // composition is stored explicitly. + // only the second phase is present, composition is stored explicitly. if( useMoles() ) { - fluidState.setMoleFraction(nPhaseIdx, nCompIdx, 1 - priVars[switchIdx]); - fluidState.setMoleFraction(nPhaseIdx, wCompIdx, priVars[switchIdx]); + fluidState.setMoleFraction(phase1Idx, comp1Idx, 1 - priVars[switchIdx]); + fluidState.setMoleFraction(phase1Idx, comp0Idx, priVars[switchIdx]); } + // setMassFraction() has only to be called 1-numComponents times else - { - // setMassFraction() has only to be called 1-numComponents times - fluidState.setMassFraction(nPhaseIdx, wCompIdx, priVars[switchIdx]); - } + fluidState.setMassFraction(phase1Idx, comp0Idx, priVars[switchIdx]); // calculate the composition of the remaining phases (as // well as the densities of all phases). This is the job @@ -291,7 +289,7 @@ public: if (useConstraintSolver) ComputeFromReferencePhase::solve(fluidState, paramCache, - nPhaseIdx, + phase1Idx, /*setViscosity=*/true, /*setEnthalpy=*/false); // ... or calculated explicitly this way ... @@ -299,8 +297,8 @@ public: { // note that the water phase is actually not existing! // thus, this is used as phase switch criterion - Scalar xnw = priVars[switchIdx]; - Scalar xnn = 1.0 -xnw; + const Scalar xnw = priVars[switchIdx]; + const Scalar xnn = 1.0 - xnw; // first, xww: // xnw * pn = "actual" (hypothetical) vapor pressure @@ -309,33 +307,31 @@ public: // xww is only the ratio of "actual" vapor pressure / "thermodynamic" vapor pressure // If xww > 1 : gas is over-saturated with water vapor, // condensation takes place (see switch criterion in model) - Scalar xww = xnw*pn/( FluidSystem::fugacityCoefficient(fluidState, wPhaseIdx, wCompIdx)*pw ); + const Scalar xww = xnw*p1/( FluidSystem::fugacityCoefficient(fluidState, phase0Idx, comp0Idx)*p0 ); // second, xwn: // partialPressure / xwn = Henry // partialPressure = xnn * pn // xwn = xnn * pn / Henry // Henry = fugacityCoefficient * pw - Scalar xwn = xnn*pn/( FluidSystem::fugacityCoefficient(fluidState, wPhaseIdx, nCompIdx)*pw ); + const Scalar xwn = xnn*p1/( FluidSystem::fugacityCoefficient(fluidState, phase0Idx, comp1Idx)*p0 ); - fluidState.setMoleFraction(wPhaseIdx, wCompIdx, xww); - fluidState.setMoleFraction(wPhaseIdx, nCompIdx, xwn); + fluidState.setMoleFraction(phase0Idx, comp0Idx, xww); + fluidState.setMoleFraction(phase0Idx, comp1Idx, xwn); } } - else if (phasePresence == wPhaseOnly) + else if (phasePresence == firstPhaseOnly) { // only the wetting phase is present, i.e. wetting phase // composition is stored explicitly. if( useMoles() ) // mole-fraction formulation { - fluidState.setMoleFraction(wPhaseIdx, wCompIdx, 1-priVars[switchIdx]); - fluidState.setMoleFraction(wPhaseIdx, nCompIdx, priVars[switchIdx]); + fluidState.setMoleFraction(phase0Idx, comp0Idx, 1-priVars[switchIdx]); + fluidState.setMoleFraction(phase0Idx, comp1Idx, priVars[switchIdx]); } + // setMassFraction() has only to be called 1-numComponents times else // mass-fraction formulation - { - // setMassFraction() has only to be called 1-numComponents times - fluidState.setMassFraction(wPhaseIdx, nCompIdx, priVars[switchIdx]); - } + fluidState.setMassFraction(phase0Idx, comp1Idx, priVars[switchIdx]); // calculate the composition of the remaining phases (as // well as the densities of all phases). This is the job @@ -343,7 +339,7 @@ public: if (useConstraintSolver) ComputeFromReferencePhase::solve(fluidState, paramCache, - wPhaseIdx, + phase0Idx, /*setViscosity=*/true, /*setEnthalpy=*/false); // ... or calculated explicitly this way ... @@ -351,12 +347,12 @@ public: { // note that the gas phase is actually not existing! // thus, this is used as phase switch criterion - Scalar xwn = priVars[switchIdx]; + const Scalar xwn = priVars[switchIdx]; // first, xnw: // psteam = xnw * pn = partial pressure of water in gas phase // psteam = fugacityCoefficient * pw - Scalar xnw = ( FluidSystem::fugacityCoefficient(fluidState, wPhaseIdx, wCompIdx)*pw )/pn; + const Scalar xnw = ( FluidSystem::fugacityCoefficient(fluidState, phase0Idx, comp0Idx)*p0 )/p1; // second, xnn: // xwn = partialPressure / Henry @@ -364,10 +360,10 @@ public: // xwn = pn * xnn / Henry // xnn = xwn * Henry / pn // Henry = fugacityCoefficient * pw - Scalar xnn = xwn*( FluidSystem::fugacityCoefficient(fluidState, wPhaseIdx, nCompIdx)*pw )/pn; + const Scalar xnn = xwn*( FluidSystem::fugacityCoefficient(fluidState, phase0Idx, comp1Idx)*p0 )/p1; - fluidState.setMoleFraction(nPhaseIdx, nCompIdx, xnn); - fluidState.setMoleFraction(nPhaseIdx, wCompIdx, xnw); + fluidState.setMoleFraction(phase1Idx, comp1Idx, xnn); + fluidState.setMoleFraction(phase1Idx, comp0Idx, xnw); } } @@ -493,7 +489,7 @@ public: * in \f$[kg/(m*s^2)=N/m^2=Pa]\f$. */ Scalar capillaryPressure() const - { return fluidState_.pressure(nPhaseIdx) - fluidState_.pressure(wPhaseIdx); } + { return pc_; } /*! * \brief Returns the average porosity within the control volume in \f$[-]\f$. @@ -520,6 +516,7 @@ public: private: FluidState fluidState_; + Scalar pc_; //!< The capillary pressure Scalar porosity_; //!< Effective porosity within the control volume PermeabilityType permeability_; //!< Effective permeability within the control volume diff --git a/dumux/porousmediumflow/2p2c/vtkoutputfields.hh b/dumux/porousmediumflow/2p2c/vtkoutputfields.hh index aa287063b23e6a3a1fd85aa6f631bf40cc26629a..c947f2a3f968d05d10d4b7ef9f7c7cd2d959e9d3 100644 --- a/dumux/porousmediumflow/2p2c/vtkoutputfields.hh +++ b/dumux/porousmediumflow/2p2c/vtkoutputfields.hh @@ -40,15 +40,15 @@ public: using FluidSystem = typename VolumeVariables::FluidSystem; // register standardized vtk output fields - vtk.addVolumeVariable([](const auto& v){ return v.saturation(FluidSystem::nPhaseIdx); }, "Sn"); - vtk.addVolumeVariable([](const auto& v){ return v.saturation(FluidSystem::wPhaseIdx); }, "Sw"); - vtk.addVolumeVariable([](const auto& v){ return v.pressure(FluidSystem::nPhaseIdx); }, "pn"); - vtk.addVolumeVariable([](const auto& v){ return v.pressure(FluidSystem::wPhaseIdx); }, "pw"); + vtk.addVolumeVariable([](const auto& v){ return v.saturation(FluidSystem::phase1Idx); }, "Sn"); + vtk.addVolumeVariable([](const auto& v){ return v.saturation(FluidSystem::phase0Idx); }, "Sw"); + vtk.addVolumeVariable([](const auto& v){ return v.pressure(FluidSystem::phase1Idx); }, "pn"); + vtk.addVolumeVariable([](const auto& v){ return v.pressure(FluidSystem::phase0Idx); }, "pw"); vtk.addVolumeVariable([](const auto& v){ return v.capillaryPressure(); }, "pc"); - vtk.addVolumeVariable([](const auto& v){ return v.density(FluidSystem::wPhaseIdx); }, "rhoW"); - vtk.addVolumeVariable([](const auto& v){ return v.density(FluidSystem::nPhaseIdx); }, "rhoN"); - vtk.addVolumeVariable([](const auto& v){ return v.mobility(FluidSystem::wPhaseIdx); }, "mobW"); - vtk.addVolumeVariable([](const auto& v){ return v.mobility(FluidSystem::nPhaseIdx); }, "mobN"); + vtk.addVolumeVariable([](const auto& v){ return v.density(FluidSystem::phase0Idx); }, "rhoW"); + vtk.addVolumeVariable([](const auto& v){ return v.density(FluidSystem::phase1Idx); }, "rhoN"); + vtk.addVolumeVariable([](const auto& v){ return v.mobility(FluidSystem::phase0Idx); }, "mobW"); + vtk.addVolumeVariable([](const auto& v){ return v.mobility(FluidSystem::phase1Idx); }, "mobN"); for (int i = 0; i < VolumeVariables::numPhases(); ++i) for (int j = 0; j < VolumeVariables::numComponents(); ++j) diff --git a/dumux/porousmediumflow/2pnc/CMakeLists.txt b/dumux/porousmediumflow/2pnc/CMakeLists.txt index 5e3c930c89509e68756c958178cff2e748398917..81352b781a2ad3666225b9df58ad757b10e5e3a1 100644 --- a/dumux/porousmediumflow/2pnc/CMakeLists.txt +++ b/dumux/porousmediumflow/2pnc/CMakeLists.txt @@ -1,7 +1,6 @@ #install headers install(FILES -indices.hh model.hh primaryvariableswitch.hh volumevariables.hh diff --git a/dumux/porousmediumflow/2pnc/indices.hh b/dumux/porousmediumflow/2pnc/indices.hh deleted file mode 100644 index a0c4f9b88af5e24e8a10204b42ade442f5c953d9..0000000000000000000000000000000000000000 --- a/dumux/porousmediumflow/2pnc/indices.hh +++ /dev/null @@ -1,52 +0,0 @@ -// -*- 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 2 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 TwoPNCModel - * \brief Defines the indices required for the two-phase n-component - * fully implicit model. - */ -#ifndef DUMUX_2PNC_INDICES_HH -#define DUMUX_2PNC_INDICES_HH - -namespace Dumux { - -/*! - * \ingroup TwoPNCModel - * \brief The indices for the isothermal two-phase n-component model. - */ -class TwoPNCIndices -{ -public: - // present phases (-> 'pseudo' primary variable) - static const int wPhaseOnly = 1; //!< Only the non-wetting phase is present - static const int nPhaseOnly = 2; //!< Only the wetting phase is present - static const int bothPhases = 3; //!< Both phases are present - - // Primary variable indices - static const int pressureIdx = 0; //!< index for wetting/non-wetting phase pressure (depending on formulation) in a solution vector - static const int switchIdx = 1; //!< index of the either the saturation or the mass fraction of the non-wetting/wetting phase - - // equation indices - static const int conti0EqIdx = 0; //!< Reference index for mass conservation equations. -}; - -} // end namespace Dumux - -#endif diff --git a/dumux/porousmediumflow/2pnc/model.hh b/dumux/porousmediumflow/2pnc/model.hh index d277875f9f66e613943bc2d032f711d8ca82e3f8..88acab3dabd478ed0c622be5dcb691b0fdc091a3 100644 --- a/dumux/porousmediumflow/2pnc/model.hh +++ b/dumux/porousmediumflow/2pnc/model.hh @@ -100,8 +100,8 @@ #include <dumux/porousmediumflow/nonisothermal/indices.hh> #include <dumux/porousmediumflow/nonisothermal/vtkoutputfields.hh> #include <dumux/porousmediumflow/2p/formulation.hh> +#include <dumux/porousmediumflow/2p2c/indices.hh> -#include "indices.hh" #include "volumevariables.hh" #include "primaryvariableswitch.hh" #include "vtkoutputfields.hh" @@ -114,12 +114,12 @@ namespace Dumux { * * \tparam nComp the number of components to be considered. * \tparam useMol whether to use molar or mass balances - * \tparam setMoleFractionForWP whether to set mole fractions for wetting or non-wetting phase + * \tparam setMoleFractionForFP whether to set mole fractions for first or second phase */ -template<int nComp, bool useMol, bool setMoleFractionForWP, TwoPFormulation formulation> +template<int nComp, bool useMol, bool setMoleFractionForFP, TwoPFormulation formulation> struct TwoPNCModelTraits { - using Indices = TwoPNCIndices; + using Indices = TwoPTwoCIndices; static constexpr int numEq() { return nComp; } static constexpr int numPhases() { return 2; } @@ -130,7 +130,7 @@ struct TwoPNCModelTraits static constexpr bool enableEnergyBalance() { return false; } static constexpr bool useMoles() { return useMol; } - static constexpr bool setMoleFractionsForWettingPhase() { return setMoleFractionForWP; } + static constexpr bool setMoleFractionsForFirstPhase() { return setMoleFractionForFP; } static constexpr TwoPFormulation priVarFormulation() { return formulation; } }; @@ -204,7 +204,7 @@ private: public: using type = TwoPNCModelTraits<FluidSystem::numComponents, GET_PROP_VALUE(TypeTag, UseMoles), - GET_PROP_VALUE(TypeTag, SetMoleFractionsForWettingPhase), + GET_PROP_VALUE(TypeTag, SetMoleFractionsForFirstPhase), GET_PROP_VALUE(TypeTag, Formulation)>; }; @@ -217,9 +217,9 @@ SET_INT_PROP(TwoPNC, ReplaceCompEqIdx, GET_PROP_TYPE(TypeTag, FluidSystem)::numC //! Default formulation is pw-Sn, overwrite if necessary SET_PROP(TwoPNC, Formulation) -{ static constexpr auto value = TwoPFormulation::pwsn; }; +{ static constexpr auto value = TwoPFormulation::p0s1; }; -SET_BOOL_PROP(TwoPNC, SetMoleFractionsForWettingPhase, true); //!< Set the primary variables mole fractions for the wetting or non-wetting phase +SET_BOOL_PROP(TwoPNC, SetMoleFractionsForFirstPhase, true); //!< Set the primary variables mole fractions for the wetting or non-wetting phase SET_BOOL_PROP(TwoPNC, UseMoles, true); //!< Use mole fractions in the balance equations by default //! Use the model after Millington (1961) for the effective diffusivity @@ -248,7 +248,7 @@ private: static_assert(FluidSystem::numPhases == 2, "Only fluid systems with 2 fluid phases are supported by the 2p-nc model!"); using IsothermalTraits = TwoPNCModelTraits<FluidSystem::numComponents, GET_PROP_VALUE(TypeTag, UseMoles), - GET_PROP_VALUE(TypeTag, SetMoleFractionsForWettingPhase), + GET_PROP_VALUE(TypeTag, SetMoleFractionsForFirstPhase), GET_PROP_VALUE(TypeTag, Formulation)>; public: using type = PorousMediumFlowNIModelTraits<IsothermalTraits>; diff --git a/dumux/porousmediumflow/2pnc/primaryvariableswitch.hh b/dumux/porousmediumflow/2pnc/primaryvariableswitch.hh index babad58faeab26c3f5107e5ea64a6286a85c33b9..db9ccb342548a21d21c5010ef9a5e73f4dabd39e 100644 --- a/dumux/porousmediumflow/2pnc/primaryvariableswitch.hh +++ b/dumux/porousmediumflow/2pnc/primaryvariableswitch.hh @@ -39,153 +39,139 @@ class TwoPNCPrimaryVariableSwitch { using ParentType = PrimaryVariableSwitch<TwoPNCPrimaryVariableSwitch<TypeTag>>; friend ParentType; - - using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - using GridView = typename GET_PROP_TYPE(TypeTag, GridView); - using IndexType = typename GridView::IndexSet::IndexType; - using GlobalPosition = Dune::FieldVector<Scalar, GridView::dimensionworld>; - - using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); - using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables); - using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); - using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; - - static const int numComponents = GET_PROP_TYPE(TypeTag, ModelTraits)::numComponents(); - static const int numMajorComponents = GET_PROP_TYPE(TypeTag, ModelTraits)::numPhases(); - - enum { - - switchIdx = Indices::switchIdx, - - wPhaseIdx = FluidSystem::wPhaseIdx, - nPhaseIdx = FluidSystem::nPhaseIdx, - - wCompIdx = FluidSystem::wCompIdx, - nCompIdx = FluidSystem::nCompIdx, - - wPhaseOnly = Indices::wPhaseOnly, - nPhaseOnly = Indices::nPhaseOnly, - bothPhases = Indices::bothPhases - }; - - static constexpr auto formulation = GET_PROP_TYPE(TypeTag, ModelTraits)::priVarFormulation(); public: using ParentType::ParentType; protected: // perform variable switch at a degree of freedom location - bool update_(PrimaryVariables& priVars, + template<class VolumeVariables, class IndexType, class GlobalPosition> + bool update_(typename VolumeVariables::PrimaryVariables& priVars, const VolumeVariables& volVars, IndexType dofIdxGlobal, const GlobalPosition& globalPos) { + using Scalar = typename VolumeVariables::PrimaryVariables::value_type; + + using FluidSystem = typename VolumeVariables::FluidSystem; + static constexpr int phase0Idx = FluidSystem::phase0Idx; + static constexpr int phase1Idx = FluidSystem::phase1Idx; + static constexpr int comp0Idx = FluidSystem::comp0Idx; + static constexpr int comp1Idx = FluidSystem::comp1Idx; + + static constexpr auto numComponents = VolumeVariables::numComponents(); + static constexpr auto numMajorComponents = VolumeVariables::numPhases(); + static constexpr auto formulation = VolumeVariables::priVarFormulation(); + static_assert( (formulation == TwoPFormulation::p0s1 || formulation == TwoPFormulation::p1s0), + "Chosen TwoPFormulation not supported!"); + + using Indices = typename VolumeVariables::Indices; + static constexpr int switchIdx = Indices::switchIdx; + // evaluate primary variable switch bool wouldSwitch = false; int phasePresence = priVars.state(); int newPhasePresence = phasePresence; //check if a primary variable switch is necessary - if (phasePresence == bothPhases) + if (phasePresence == Indices::bothPhases) { Scalar Smin = 0; //saturation threshold if (this->wasSwitched_[dofIdxGlobal]) Smin = -0.01; - //if saturation of wetting phase is smaller 0 switch - if (volVars.saturation(wPhaseIdx) <= Smin) + // if saturation of first phase is smaller 0: switch + if (volVars.saturation(phase0Idx) <= Smin) { wouldSwitch = true; - //wetting phase has to disappear - std::cout << "Wetting Phase disappears at vertex " << dofIdxGlobal - << ", coordinated: " << globalPos << ", Sw: " - << volVars.saturation(wPhaseIdx) << std::endl; - newPhasePresence = nPhaseOnly; - - //switch not depending on formulation - //switch "Sw" to "xn20" - priVars[switchIdx] - = volVars.moleFraction(nPhaseIdx, wCompIdx /*H2O*/); - - //switch all secondary components to mole fraction in non-wetting phase - for (int compIdx=numMajorComponents; compIdx<numComponents; ++compIdx) - priVars[compIdx] = volVars.moleFraction(nPhaseIdx,compIdx); + // first phase has to disappear + std::cout << "First Phase disappears at vertex " << dofIdxGlobal + << ", coordinated: " << globalPos << ", s0: " + << volVars.saturation(phase0Idx) << std::endl; + newPhasePresence = Indices::secondPhaseOnly; + + // switch not depending on formulation, switch "S0" to "x10" + priVars[switchIdx] = volVars.moleFraction(phase1Idx, comp0Idx); + + // switch all secondary components to mole fraction in non-wetting phase + for (int compIdx = numMajorComponents; compIdx < numComponents; ++compIdx) + priVars[compIdx] = volVars.moleFraction(phase1Idx, compIdx); } - //if saturation of non-wetting phase is smaller than 0 switch - else if (volVars.saturation(nPhaseIdx) <= Smin) + + // if saturation of second phase is smaller than 0: switch + else if (volVars.saturation(phase1Idx) <= Smin) { wouldSwitch = true; - //non-wetting phase has to disappear - std::cout << "Non-wetting Phase disappears at vertex " << dofIdxGlobal - << ", coordinated: " << globalPos << ", Sn: " - << volVars.saturation(nPhaseIdx) << std::endl; - newPhasePresence = wPhaseOnly; - - //switch "Sn" to "xwN2" - priVars[switchIdx] = volVars.moleFraction(wPhaseIdx, nCompIdx /*N2*/); + // second phase has to disappear + std::cout << "Second Phase disappears at vertex " << dofIdxGlobal + << ", coordinated: " << globalPos << ", s1: " + << volVars.saturation(phase1Idx) << std::endl; + newPhasePresence = Indices::firstPhaseOnly; + + // switch "S1" to "x01" + priVars[switchIdx] = volVars.moleFraction(phase0Idx, comp1Idx); } } - else if (phasePresence == nPhaseOnly) + else if (phasePresence == Indices::secondPhaseOnly) { Scalar xwmax = 1; Scalar sumxw = 0; - //Calculate sum of mole fractions in the hypothetical wetting phase + // Calculate sum of mole fractions in the hypothetical first phase for (int compIdx = 0; compIdx < numComponents; compIdx++) - { - sumxw += volVars.moleFraction(wPhaseIdx, compIdx); - } + sumxw += volVars.moleFraction(phase0Idx, compIdx); + if (sumxw > xwmax) wouldSwitch = true; if (this->wasSwitched_[dofIdxGlobal]) - xwmax *=1.02; - //wetting phase appears if sum is larger than one + xwmax *= 1.02; + + // first phase appears if sum is larger than one if (sumxw/*sum of mole fractions*/ > xwmax/*1*/) { - std::cout << "Wetting Phase appears at vertex " << dofIdxGlobal - << ", coordinated: " << globalPos << ", sumxw: " + std::cout << "First Phase appears at vertex " << dofIdxGlobal + << ", coordinated: " << globalPos << ", sumx0: " << sumxw << std::endl; - newPhasePresence = bothPhases; + newPhasePresence = Indices::bothPhases; - //saturation of the wetting phase set to 0.0001 (if formulation TwoPFormulation::pnsw and vice versa) - if (formulation == TwoPFormulation::pnsw) + // saturation of the first phase set to 0.0001 (if formulation TwoPFormulation::p1s0 and vice versa) + if (formulation == TwoPFormulation::p1s0) priVars[switchIdx] = 0.0001; - else if (formulation == TwoPFormulation::pwsn) + else priVars[switchIdx] = 0.9999; - //switch all secondary components back to wetting mole fraction - for (int compIdx=numMajorComponents; compIdx<numComponents; ++compIdx) - priVars[compIdx] = volVars.moleFraction(wPhaseIdx,compIdx); + // switch all secondary components back to first component mole fraction + for (int compIdx = numMajorComponents; compIdx < numComponents; ++compIdx) + priVars[compIdx] = volVars.moleFraction(phase0Idx,compIdx); } } - else if (phasePresence == wPhaseOnly) + else if (phasePresence == Indices::firstPhaseOnly) { Scalar xnmax = 1; Scalar sumxn = 0; - //Calculate sum of mole fractions in the hypothetical wetting phase + + // Calculate sum of mole fractions in the hypothetical wetting phase for (int compIdx = 0; compIdx < numComponents; compIdx++) - { - sumxn += volVars.moleFraction(nPhaseIdx, compIdx); - } + sumxn += volVars.moleFraction(phase1Idx, compIdx); + if (sumxn > xnmax) wouldSwitch = true; if (this->wasSwitched_[dofIdxGlobal]) - xnmax *=1.02; - //wetting phase appears if sum is larger than one + xnmax *= 1.02; + + // wetting phase appears if sum is larger than one if (sumxn > xnmax) { - std::cout << "Non-wetting Phase appears at vertex " << dofIdxGlobal + std::cout << "Second Phase appears at vertex " << dofIdxGlobal << ", coordinated: " << globalPos << ", sumxn: " << sumxn << std::endl; - newPhasePresence = bothPhases; + newPhasePresence = Indices::bothPhases; //saturation of the wetting phase set to 0.9999 (if formulation TwoPFormulation::pnsw and vice versa) - if (formulation == TwoPFormulation::pnsw) + if (formulation == TwoPFormulation::p1s0) priVars[switchIdx] = 0.9999; - else if (formulation == TwoPFormulation::pwsn) + else priVars[switchIdx] = 0.0001; - } } - priVars.setState(newPhasePresence); this->wasSwitched_[dofIdxGlobal] = wouldSwitch; return phasePresence != newPhasePresence; diff --git a/dumux/porousmediumflow/2pnc/volumevariables.hh b/dumux/porousmediumflow/2pnc/volumevariables.hh index 870553d9e9db7cfbe19ae3f4498f4fa80ea2946a..589067bf5a945369f7d78039457278ba584af30a 100644 --- a/dumux/porousmediumflow/2pnc/volumevariables.hh +++ b/dumux/porousmediumflow/2pnc/volumevariables.hh @@ -54,33 +54,32 @@ class TwoPNCVolumeVariables using Scalar = typename Traits::PrimaryVariables::value_type; using PermeabilityType = typename Traits::PermeabilityType; using FS = typename Traits::FluidSystem; - using Indices = typename Traits::ModelTraits::Indices; + using ModelTraits = typename Traits::ModelTraits; enum { - numPhases = Traits::ModelTraits::numPhases(), - numComponents = Traits::ModelTraits::numComponents(), - numMajorComponents = Traits::ModelTraits::numPhases(), + numMajorComponents = ModelTraits::numPhases(), // phase indices - wPhaseIdx = FS::wPhaseIdx, - nPhaseIdx = FS::nPhaseIdx, + phase0Idx = FS::phase0Idx, + phase1Idx = FS::phase1Idx, // component indices - wCompIdx = FS::wCompIdx, - nCompIdx = FS::nCompIdx, + comp0Idx = FS::comp0Idx, + comp1Idx = FS::comp1Idx, // phase presence enums - nPhaseOnly = Indices::nPhaseOnly, - wPhaseOnly = Indices::wPhaseOnly, - bothPhases = Indices::bothPhases, + secondPhaseOnly = ModelTraits::Indices::secondPhaseOnly, + firstPhaseOnly = ModelTraits::Indices::firstPhaseOnly, + bothPhases = ModelTraits::Indices::bothPhases, // primary variable indices - pressureIdx = Indices::pressureIdx, - switchIdx = Indices::switchIdx, + pressureIdx = ModelTraits::Indices::pressureIdx, + switchIdx = ModelTraits::Indices::switchIdx }; - static constexpr auto formulation = Traits::ModelTraits::priVarFormulation(); + static constexpr auto formulation = ModelTraits::priVarFormulation(); + static constexpr bool setFirstPhaseMoleFractions = ModelTraits::setMoleFractionsForFirstPhase(); using MiscibleMultiPhaseComposition = Dumux::MiscibleMultiPhaseComposition<Scalar, FS>; using ComputeFromReferencePhase = Dumux::ComputeFromReferencePhase<Scalar, FS>; @@ -91,10 +90,15 @@ public: //! export fluid system type using FluidSystem = typename Traits::FluidSystem; - static constexpr bool useMoles() - { return Traits::ModelTraits::useMoles(); } + //! return whether moles or masses are balanced + static constexpr bool useMoles() { return Traits::ModelTraits::useMoles(); } + //! return the two-phase formulation used here + static constexpr TwoPFormulation priVarFormulation() { return formulation; } + // check for permissive specifications static_assert(useMoles(), "use moles has to be set true in the 2pnc model"); + static_assert(ModelTraits::numPhases() == 2, "NumPhases set in the model is not two!"); + static_assert((formulation == TwoPFormulation::p0s1 || formulation == TwoPFormulation::p1s0), "Chosen TwoPFormulation not supported!"); /*! * \brief Update all quantities for a given control volume @@ -112,45 +116,44 @@ public: const Scv& scv) { ParentType::update(elemSol, problem, element, scv); - completeFluidState(elemSol, problem, element, scv, fluidState_); ///////////// // calculate the remaining quantities ///////////// - using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; - const auto &materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol); - // Second instance of a parameter cache. // Could be avoided if diffusion coefficients also // became part of the fluid state. typename FluidSystem::ParameterCache paramCache; paramCache.updateAll(fluidState_); - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) - { - // relative permeabilities - Scalar kr; - if (phaseIdx == wPhaseIdx) - kr = MaterialLaw::krw(materialParams, saturation(wPhaseIdx)); - else // ATTENTION: krn requires the wetting-phase saturation as parameter! - kr = MaterialLaw::krn(materialParams, saturation(wPhaseIdx)); - mobility_[phaseIdx] = kr / fluidState_.viscosity(phaseIdx); + using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; + const auto& matParams = problem.spatialParams().materialLawParams(element, scv, elemSol); - int compIIdx = phaseIdx; - for (unsigned int compJIdx = 0; compJIdx < numComponents; ++compJIdx) - { - // binary diffusion coefficients - if(compIIdx!= compJIdx) - { - setDiffusionCoefficient_(phaseIdx, compJIdx, - FluidSystem::binaryDiffusionCoefficient(fluidState_, - paramCache, - phaseIdx, - compIIdx, - compJIdx)); - } - } + const int wPhaseIdx = problem.spatialParams().template wettingPhase<FluidSystem>(element, scv, elemSol); + const int nPhaseIdx = 1 - wPhaseIdx; + + // mobilities -> require wetting phase saturation as parameter! + mobility_[wPhaseIdx] = MaterialLaw::krw(matParams, saturation(wPhaseIdx))/fluidState_.viscosity(wPhaseIdx); + mobility_[nPhaseIdx] = MaterialLaw::krn(matParams, saturation(wPhaseIdx))/fluidState_.viscosity(nPhaseIdx); + + // binary diffusion coefficients + for (unsigned int compJIdx = 0; compJIdx < ModelTraits::numComponents(); ++compJIdx) + { + if(compJIdx != comp0Idx) + setDiffusionCoefficient_( phase0Idx, compJIdx, + FluidSystem::binaryDiffusionCoefficient(fluidState_, + paramCache, + phase0Idx, + comp0Idx, + compJIdx) ); + if(compJIdx != comp1Idx) + setDiffusionCoefficient_( phase1Idx, compJIdx, + FluidSystem::binaryDiffusionCoefficient(fluidState_, + paramCache, + phase1Idx, + comp1Idx, + compJIdx) ); } // porosity & permeability @@ -170,179 +173,146 @@ public: * Set temperature, saturations, capillary pressures, viscosities, densities and enthalpies. */ template<class ElemSol, class Problem, class Element, class Scv> - static void completeFluidState(const ElemSol& elemSol, - const Problem& problem, - const Element& element, - const Scv& scv, - FluidState& fluidState) + void completeFluidState(const ElemSol& elemSol, + const Problem& problem, + const Element& element, + const Scv& scv, + FluidState& fluidState) { - Scalar t = ParentType::temperature(elemSol, problem, element, scv); + const auto t = ParentType::temperature(elemSol, problem, element, scv); fluidState.setTemperature(t); - auto&& priVars = ParentType::extractDofPriVars(elemSol, scv); + const auto& priVars = ParentType::extractDofPriVars(elemSol, scv); const auto phasePresence = priVars.state(); - ///////////// - // set the saturations - ///////////// + using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; + const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol); + const int wPhaseIdx = problem.spatialParams().template wettingPhase<FluidSystem>(element, scv, elemSol); + fluidState.setWettingPhase(wPhaseIdx); - Scalar Sn; - if (phasePresence == nPhaseOnly) + // set the saturations + if (phasePresence == secondPhaseOnly) { - Sn = 1.0; + fluidState.setSaturation(phase0Idx, 0.0); + fluidState.setSaturation(phase1Idx, 1.0); } - else if (phasePresence == wPhaseOnly) + else if (phasePresence == firstPhaseOnly) { - Sn = 0.0; + fluidState.setSaturation(phase0Idx, 1.0); + fluidState.setSaturation(phase1Idx, 0.0); } else if (phasePresence == bothPhases) { - if (formulation == TwoPFormulation::pwsn) - Sn = priVars[switchIdx]; - else if (formulation == TwoPFormulation::pnsw) - Sn = 1.0 - priVars[switchIdx]; + if (formulation == TwoPFormulation::p0s1) + { + fluidState.setSaturation(phase1Idx, priVars[switchIdx]); + fluidState.setSaturation(phase0Idx, 1 - priVars[switchIdx]); + } else - DUNE_THROW(Dune::InvalidStateException, "Formulation is invalid."); + { + fluidState.setSaturation(phase0Idx, priVars[switchIdx]); + fluidState.setSaturation(phase1Idx, 1 - priVars[switchIdx]); + } } else - { DUNE_THROW(Dune::InvalidStateException, "phasePresence: " << phasePresence << " is invalid."); - } - - fluidState.setSaturation(nPhaseIdx, Sn); - fluidState.setSaturation(wPhaseIdx, 1.0 - Sn); - ///////////// - // set the pressures of the fluid phases - ///////////// - - // calculate capillary pressure - const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol); - using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; - auto pc = MaterialLaw::pc(materialParams, 1 - Sn); - - // extract the pressures - if (formulation == TwoPFormulation::pwsn) + // set pressures of the fluid phases + pc_ = MaterialLaw::pc(materialParams, fluidState.saturation(wPhaseIdx)); + if (formulation == TwoPFormulation::p0s1) { - fluidState.setPressure(wPhaseIdx, priVars[pressureIdx]); - if (priVars[pressureIdx] + pc < 0.0) - DUNE_THROW(NumericalProblem,"Capillary pressure is too low"); - fluidState.setPressure(nPhaseIdx, priVars[pressureIdx] + pc); - } - else if (formulation == TwoPFormulation::pnsw) - { - fluidState.setPressure(nPhaseIdx, priVars[pressureIdx]); - // Here we check for (p_g - pc) in order to ensure that (p_l > 0) - if (priVars[pressureIdx] - pc < 0.0) - { - std::cout<< "p_n: "<< priVars[pressureIdx]<<" Cap_press: "<< pc << std::endl; - DUNE_THROW(NumericalProblem,"Capillary pressure is too high"); - } - fluidState.setPressure(wPhaseIdx, priVars[pressureIdx] - pc); + fluidState.setPressure(phase0Idx, priVars[pressureIdx]); + fluidState.setPressure(phase1Idx, (wPhaseIdx == phase0Idx) ? priVars[pressureIdx] + pc_ + : priVars[pressureIdx] - pc_); } else { - DUNE_THROW(Dune::InvalidStateException, "Formulation is invalid."); + fluidState.setPressure(phase1Idx, priVars[pressureIdx]); + fluidState.setPressure(phase0Idx, (wPhaseIdx == phase0Idx) ? priVars[pressureIdx] - pc_ + : priVars[pressureIdx] + pc_); } - ///////////// // calculate the phase compositions - ///////////// - typename FluidSystem::ParameterCache paramCache; // now comes the tricky part: calculate phase composition if (phasePresence == bothPhases) { // both phases are present, phase composition results from - // the nonwetting <-> wetting equilibrium. This is - // the job of the "MiscibleMultiPhaseComposition" - // constraint solver + // the first <-> second phase equilibrium. This is the job + // of the "MiscibleMultiPhaseComposition" constraint solver // set the known mole fractions in the fluidState so that they // can be used by the MiscibleMultiPhaseComposition constraint solver - unsigned int knownPhaseIdx = nPhaseIdx; - if (Traits::ModelTraits::setMoleFractionsForWettingPhase()) - { - knownPhaseIdx = wPhaseIdx; - } - - for (int compIdx=numMajorComponents; compIdx<numComponents; ++compIdx) - { + const int knownPhaseIdx = setFirstPhaseMoleFractions ? phase0Idx : phase1Idx; + for (int compIdx = numMajorComponents; compIdx < ModelTraits::numComponents(); ++compIdx) fluidState.setMoleFraction(knownPhaseIdx, compIdx, priVars[compIdx]); - } MiscibleMultiPhaseComposition::solve(fluidState, - paramCache, - /*setViscosity=*/true, - /*setEnthalpy=*/false, - knownPhaseIdx); + paramCache, + /*setViscosity=*/true, + /*setEnthalpy=*/false, + knownPhaseIdx); } - else if (phasePresence == nPhaseOnly) + else if (phasePresence == secondPhaseOnly) { - Dune::FieldVector<Scalar, numComponents> moleFrac; + Dune::FieldVector<Scalar, ModelTraits::numComponents()> moleFrac; - moleFrac[wCompIdx] = priVars[switchIdx]; + moleFrac[comp0Idx] = priVars[switchIdx]; + Scalar sumMoleFracOtherComponents = moleFrac[comp0Idx]; - for (int compIdx=numMajorComponents; compIdx<numComponents; ++compIdx) + for (int compIdx = numMajorComponents; compIdx < ModelTraits::numComponents(); ++compIdx) + { moleFrac[compIdx] = priVars[compIdx]; - - Scalar sumMoleFracOtherComponents = 0; - for (int compIdx=numMajorComponents; compIdx<numComponents; ++compIdx) sumMoleFracOtherComponents += moleFrac[compIdx]; + } - sumMoleFracOtherComponents += moleFrac[wCompIdx]; - moleFrac[nCompIdx] = 1 - sumMoleFracOtherComponents; + moleFrac[comp1Idx] = 1 - sumMoleFracOtherComponents; // Set fluid state mole fractions - for (int compIdx=0; compIdx<numComponents; ++compIdx) - fluidState.setMoleFraction(nPhaseIdx, compIdx, moleFrac[compIdx]); + for (int compIdx = 0; compIdx < ModelTraits::numComponents(); ++compIdx) + fluidState.setMoleFraction(phase1Idx, compIdx, moleFrac[compIdx]); // calculate the composition of the remaining phases (as // well as the densities of all phases). this is the job // of the "ComputeFromReferencePhase" constraint solver ComputeFromReferencePhase::solve(fluidState, paramCache, - nPhaseIdx, + phase1Idx, /*setViscosity=*/true, /*setEnthalpy=*/false); } - else if (phasePresence == wPhaseOnly) + else if (phasePresence == firstPhaseOnly) { - // only the wetting phase is present, i.e. wetting phase - // composition is stored explicitly. - // extract _mass_ fractions in the non-wetting phase - Dune::FieldVector<Scalar, numComponents> moleFrac; - - moleFrac[nCompIdx] = priVars[switchIdx]; + // only the first phase is present, i.e. first phase composition + // is stored explicitly. extract _mass_ fractions in the second phase + Dune::FieldVector<Scalar, ModelTraits::numComponents()> moleFrac; - for (int compIdx=numMajorComponents; compIdx<numComponents; ++compIdx) + moleFrac[comp1Idx] = priVars[switchIdx]; + Scalar sumMoleFracOtherComponents = moleFrac[comp1Idx]; + for (int compIdx = numMajorComponents; compIdx < ModelTraits::numComponents(); ++compIdx) + { moleFrac[compIdx] = priVars[compIdx]; - - Scalar sumMoleFracOtherComponents = 0; - for (int compIdx=numMajorComponents; compIdx<numComponents; ++compIdx) sumMoleFracOtherComponents += moleFrac[compIdx]; + } - sumMoleFracOtherComponents += moleFrac[nCompIdx]; - moleFrac[wCompIdx] = 1 - sumMoleFracOtherComponents; + moleFrac[comp0Idx] = 1 - sumMoleFracOtherComponents; // convert mass to mole fractions and set the fluid state - for (int compIdx=0; compIdx<numComponents; ++compIdx) - { - fluidState.setMoleFraction(wPhaseIdx, compIdx, moleFrac[compIdx]); - } + for (int compIdx = 0; compIdx < ModelTraits::numComponents(); ++compIdx) + fluidState.setMoleFraction(phase0Idx, compIdx, moleFrac[compIdx]); // calculate the composition of the remaining phases (as // well as the densities of all phases). this is the job // of the "ComputeFromReferencePhase" constraint solver ComputeFromReferencePhase::solve(fluidState, paramCache, - wPhaseIdx, + phase0Idx, /*setViscosity=*/true, /*setEnthalpy=*/false); } paramCache.updateAll(fluidState); - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) + for (int phaseIdx = 0; phaseIdx < ModelTraits::numPhases(); ++phaseIdx) { Scalar rho = FluidSystem::density(fluidState, paramCache, phaseIdx); Scalar mu = FluidSystem::viscosity(fluidState, paramCache, phaseIdx); @@ -376,12 +346,7 @@ public: * \param phaseIdx The phase index */ Scalar density(int phaseIdx) const - { - if (phaseIdx < numPhases) - return fluidState_.density(phaseIdx); - else - DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx); - } + { return fluidState_.density(phaseIdx); } /*! * \brief Returns the kinematic viscosity of a given phase within the @@ -390,12 +355,7 @@ public: * \param phaseIdx The phase index */ Scalar viscosity(int phaseIdx) const - { - if (phaseIdx < numPhases) - return fluidState_.viscosity(phaseIdx); - else - DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx); - } + { return fluidState_.viscosity(phaseIdx); } /*! * \brief Returns the mass density of a given phase within the @@ -404,12 +364,7 @@ public: * \param phaseIdx The phase index */ Scalar molarDensity(int phaseIdx) const - { - if (phaseIdx < numPhases) - return fluidState_.molarDensity(phaseIdx); - else - DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx); - } + { return fluidState_.molarDensity(phaseIdx); } /*! * \brief Returns the effective pressure of a given phase within @@ -444,7 +399,7 @@ public: * in \f$[kg/(m*s^2)=N/m^2=Pa]\f$. */ Scalar capillaryPressure() const - { return fluidState_.pressure(FluidSystem::nPhaseIdx) - fluidState_.pressure(FluidSystem::wPhaseIdx); } + { return pc_; } /*! * \brief Returns the average porosity within the control volume. @@ -513,10 +468,11 @@ private: DUNE_THROW(Dune::InvalidStateException, "Diffusion coefficient for phaseIdx = compIdx doesn't exist"); } + Scalar pc_; //!< The capillary pressure Scalar porosity_; //!< Effective porosity within the control volume PermeabilityType permeability_; //!> Effective permeability within the control volume - Scalar mobility_[numPhases]; //!< Effective mobility within the control volume - std::array<std::array<Scalar, numComponents-1>, numPhases> diffCoefficient_; + Scalar mobility_[ModelTraits::numPhases()]; //!< Effective mobility within the control volume + std::array<std::array<Scalar, ModelTraits::numComponents()-1>, ModelTraits::numPhases()> diffCoefficient_; }; } // end namespace Dumux diff --git a/dumux/porousmediumflow/2pnc/vtkoutputfields.hh b/dumux/porousmediumflow/2pnc/vtkoutputfields.hh index 13e711bb51cd2c0a10808bf8489d1d1e033d8f04..da45474989d602f3892e4c77d0c9d06435a67cac 100644 --- a/dumux/porousmediumflow/2pnc/vtkoutputfields.hh +++ b/dumux/porousmediumflow/2pnc/vtkoutputfields.hh @@ -53,8 +53,8 @@ public: "x_"+ FluidSystem::phaseName(i) + "^" + FluidSystem::componentName(j)); for (int j = 0; j < VolumeVariables::numComponents(); ++j) - vtk.addVolumeVariable([j](const auto& v){ return v.molarity(FluidSystem::wPhaseIdx,j); }, - "m_"+ FluidSystem::phaseName(FluidSystem::wPhaseIdx) + "^" + FluidSystem::componentName(j)); + vtk.addVolumeVariable([j](const auto& v){ return v.molarity(FluidSystem::phase0Idx,j); }, + "m_"+ FluidSystem::phaseName(FluidSystem::phase1Idx) + "^" + FluidSystem::componentName(j)); vtk.addVolumeVariable([](const auto& v){ return v.priVars().state(); }, "phasePresence"); } diff --git a/dumux/porousmediumflow/2pncmin/model.hh b/dumux/porousmediumflow/2pncmin/model.hh index 2a77226cf3cd8d7d5a25265c344fcdf2ee352c0d..a5ccef76cdb23d4bb0afe6dd16bdb99c66f587ac 100644 --- a/dumux/porousmediumflow/2pncmin/model.hh +++ b/dumux/porousmediumflow/2pncmin/model.hh @@ -146,7 +146,7 @@ private: static_assert(FluidSystem::numPhases == 2, "Only fluid systems with 2 fluid phases are supported by the 2p-nc model!"); using NonMineralizationTraits = TwoPNCModelTraits<FluidSystem::numComponents, GET_PROP_VALUE(TypeTag, UseMoles), - GET_PROP_VALUE(TypeTag, SetMoleFractionsForWettingPhase), + GET_PROP_VALUE(TypeTag, SetMoleFractionsForFirstPhase), GET_PROP_VALUE(TypeTag, Formulation)>; public: using type = MineralizationModelTraits<NonMineralizationTraits, FluidSystem::numSPhases>; @@ -165,7 +165,7 @@ private: static_assert(FluidSystem::numPhases == 2, "Only fluid systems with 2 fluid phases are supported by the 2p-nc model!"); using TwoPNCTraits = TwoPNCModelTraits<FluidSystem::numComponents, GET_PROP_VALUE(TypeTag, UseMoles), - GET_PROP_VALUE(TypeTag, SetMoleFractionsForWettingPhase), + GET_PROP_VALUE(TypeTag, SetMoleFractionsForFirstPhase), GET_PROP_VALUE(TypeTag, Formulation)>; using IsothermalTraits = MineralizationModelTraits<TwoPNCTraits, FluidSystem::numSPhases>; public: @@ -174,7 +174,7 @@ public: }; //! non-isothermal vtkoutput -SET_PROP(TwoPNCMinNI, VtkOutputFields, EnergyVtkOutputFields<MineralizationVtkOutputFields<TwoPNCVtkOutputFields>>); +SET_TYPE_PROP(TwoPNCMinNI, VtkOutputFields, EnergyVtkOutputFields<MineralizationVtkOutputFields<TwoPNCVtkOutputFields>>); } // end namespace Properties } // end namespace Dumux diff --git a/dumux/porousmediumflow/3p3c/volumevariables.hh b/dumux/porousmediumflow/3p3c/volumevariables.hh index b005609995a68d0dd1eab2498c0d7b6be355758b..b89ca04a2005763e61a7968384ac73ae89290677 100644 --- a/dumux/porousmediumflow/3p3c/volumevariables.hh +++ b/dumux/porousmediumflow/3p3c/volumevariables.hh @@ -54,9 +54,6 @@ class ThreePThreeCVolumeVariables using ModelTraits = typename Traits::ModelTraits; using Idx = typename ModelTraits::Indices; enum { - numPhases = ModelTraits::numPhases(), - numComponents = ModelTraits::numComponents(), - wCompIdx = FS::wCompIdx, gCompIdx = FS::gCompIdx, nCompIdx = FS::nCompIdx, @@ -187,10 +184,10 @@ public: // depend on composition! typename FluidSystem::ParameterCache paramCache; // assert(FluidSystem::isIdealGas(gPhaseIdx)); - for (int phaseIdx = 0; phaseIdx < numPhases; ++ phaseIdx) { + for (int phaseIdx = 0; phaseIdx < ModelTraits::numPhases(); ++ phaseIdx) { assert(FluidSystem::isIdealMixture(phaseIdx)); - for (int compIdx = 0; compIdx < numComponents; ++ compIdx) { + for (int compIdx = 0; compIdx < ModelTraits::numComponents(); ++ compIdx) { Scalar phi = FluidSystem::fugacityCoefficient(fluidState_, paramCache, phaseIdx, compIdx); fluidState_.setFugacityCoefficient(phaseIdx, compIdx, phi); } @@ -508,7 +505,7 @@ public: DUNE_THROW(Dune::InvalidStateException, "phasePresence: " << phasePresence << " is invalid."); } - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { + for (int phaseIdx = 0; phaseIdx < ModelTraits::numPhases(); ++phaseIdx) { // Mobilities const Scalar mu = FluidSystem::viscosity(fluidState_, @@ -549,7 +546,7 @@ public: permeability_ = problem.spatialParams().permeability(element, scv, elemSol); // compute and set the enthalpy - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) + for (int phaseIdx = 0; phaseIdx < ModelTraits::numPhases(); ++phaseIdx) { Scalar h = ParentType::enthalpy(fluidState_, paramCache, phaseIdx); fluidState_.setEnthalpy(phaseIdx, h); @@ -682,12 +679,12 @@ protected: private: Scalar sw_, sg_, sn_, pg_, pw_, pn_; - Scalar moleFrac_[numPhases][numComponents]; - Scalar massFrac_[numPhases][numComponents]; + Scalar moleFrac_[ModelTraits::numPhases()][ModelTraits::numComponents()]; + Scalar massFrac_[ModelTraits::numPhases()][ModelTraits::numComponents()]; Scalar porosity_; //!< Effective porosity within the control volume PermeabilityType permeability_; //!< Effective permeability within the control volume - Scalar mobility_[numPhases]; //!< Effective mobility within the control volume + Scalar mobility_[ModelTraits::numPhases()]; //!< Effective mobility within the control volume Scalar bulkDensTimesAdsorpCoeff_; //!< the basis for calculating adsorbed NAPL void setDiffusionCoefficient_(int phaseIdx, int compIdx, Scalar d) @@ -702,7 +699,7 @@ private: DUNE_THROW(Dune::InvalidStateException, "Diffusion coefficient for phaseIdx = compIdx doesn't exist"); } - std::array<std::array<Scalar, numComponents-1>, numPhases> diffCoefficient_; + std::array<std::array<Scalar, ModelTraits::numComponents()-1>, ModelTraits::numPhases()> diffCoefficient_; }; } // end namespace Dumux diff --git a/dumux/porousmediumflow/3pwateroil/volumevariables.hh b/dumux/porousmediumflow/3pwateroil/volumevariables.hh index 4c0ee79aa3d5d4b3d9bbaca522daf243acbcc967..4af2eadc3652b89078d88497d36159a900d5a83f 100644 --- a/dumux/porousmediumflow/3pwateroil/volumevariables.hh +++ b/dumux/porousmediumflow/3pwateroil/volumevariables.hh @@ -54,12 +54,13 @@ class ThreePWaterOilVolumeVariables using ParentType = PorousMediumFlowVolumeVariables<Traits, ThreePWaterOilVolumeVariables<Traits>>; using Scalar = typename Traits::PrimaryVariables::value_type; - using Indices = typename Traits::ModelTraits::Indices; + using ModelTraits = typename Traits::ModelTraits; + using Indices = typename ModelTraits::Indices; using FS = typename Traits::FluidSystem; enum { - numPhases = Traits::ModelTraits::numPhases(), - numComponents = Traits::ModelTraits::numComponents(), + numPs = ParentType::numPhases(), + numComps = ParentType::numComponents(), wCompIdx = FS::wCompIdx, nCompIdx = FS::nCompIdx, @@ -625,7 +626,7 @@ public: else DUNE_THROW(Dune::InvalidStateException, "phasePresence: " << phasePresence << " is invalid."); } - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { + for (int phaseIdx = 0; phaseIdx < numPs; ++phaseIdx) { // Mobilities const Scalar mu = FluidSystem::viscosity(fluidState_, @@ -665,7 +666,7 @@ public: // fluidState_.setTemperature(temp_); // the enthalpies (internal energies are directly calculated in the fluidstate - for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) { + for (int phaseIdx = 0; phaseIdx < numPs; ++phaseIdx) { Scalar h = FluidSystem::enthalpy(fluidState_, phaseIdx); fluidState_.setEnthalpy(phaseIdx, h); @@ -778,7 +779,7 @@ public: * \brief Returns the diffusivity coefficient matrix */ DUNE_DEPRECATED_MSG("diffusionCoefficient() is deprecated. Use diffusionCoefficient(int phaseIdx) instead.") - Dune::FieldVector<Scalar, numPhases> diffusionCoefficient() const + Dune::FieldVector<Scalar, numPs> diffusionCoefficient() const { return diffusionCoefficient_; } @@ -821,17 +822,17 @@ protected: private: Scalar sw_, sg_, sn_, pg_, pw_, pn_, temp_; - Scalar moleFrac_[numPhases][numComponents]; - Scalar massFrac_[numPhases][numComponents]; + Scalar moleFrac_[numPs][numComps]; + Scalar massFrac_[numPs][numComps]; Scalar porosity_; //!< Effective porosity within the control volume Scalar permeability_; //!< Effective porosity within the control volume - Scalar mobility_[numPhases]; //!< Effective mobility within the control volume + Scalar mobility_[numPs]; //!< Effective mobility within the control volume Scalar bulkDensTimesAdsorpCoeff_; //!< the basis for calculating adsorbed NAPL /* We need a tensor here !! */ //!< Binary diffusion coefficients of the 3 components in the phases - Dune::FieldVector<Scalar, numPhases> diffusionCoefficient_; - std::array<std::array<Scalar, numComponents-1>, numPhases> diffCoefficient_; + Dune::FieldVector<Scalar, numPs> diffusionCoefficient_; + std::array<std::array<Scalar, numComps-1>, numPs> diffCoefficient_; }; } // end namespace Dumux diff --git a/dumux/porousmediumflow/co2/primaryvariableswitch.hh b/dumux/porousmediumflow/co2/primaryvariableswitch.hh index 84bf612c4a4ffd2a4b123cfdb85ee633ad33c46f..30307aea246227596220e506a145ea06f7412f14 100644 --- a/dumux/porousmediumflow/co2/primaryvariableswitch.hh +++ b/dumux/porousmediumflow/co2/primaryvariableswitch.hh @@ -56,13 +56,15 @@ protected: using Scalar = typename VolumeVariables::PrimaryVariables::value_type; using FluidSystem = typename VolumeVariables::FluidSystem; - static constexpr int wPhaseIdx = FluidSystem::wPhaseIdx; - static constexpr int nPhaseIdx = FluidSystem::nPhaseIdx; - static constexpr int wCompIdx = FluidSystem::wCompIdx; - static constexpr int nCompIdx = FluidSystem::nCompIdx; + static constexpr int phase0Idx = FluidSystem::phase0Idx; + static constexpr int phase1Idx = FluidSystem::phase1Idx; + static constexpr int comp0Idx = FluidSystem::comp0Idx; + static constexpr int comp1Idx = FluidSystem::comp1Idx; static constexpr bool useMoles = VolumeVariables::useMoles(); static constexpr auto formulation = VolumeVariables::priVarFormulation(); + static_assert( (formulation == TwoPFormulation::p0s1 || formulation == TwoPFormulation::p1s0), + "Chosen TwoPFormulation not supported!"); using Indices = typename VolumeVariables::Indices; static constexpr int switchIdx = Indices::switchIdx; @@ -76,11 +78,11 @@ protected: typename FluidSystem::ParameterCache paramCache; // check if a primary var switch is necessary - if (phasePresence == Indices::nPhaseOnly) + if (phasePresence == Indices::secondPhaseOnly) { - // calculate wetting component mole fraction in the non-wetting phase - Scalar xnw = volVars.moleFraction(nPhaseIdx, wCompIdx); - Scalar xnwMax = FluidSystem::equilibriumMoleFraction(volVars.fluidState(), paramCache, nPhaseIdx); + // calculate wetting component mole fraction in the second phase + Scalar xnw = volVars.moleFraction(phase1Idx, comp0Idx); + Scalar xnwMax = FluidSystem::equilibriumMoleFraction(volVars.fluidState(), paramCache, phase1Idx); // if it is larger than the equilibirum mole fraction switch if(xnw > xnwMax) @@ -89,27 +91,25 @@ protected: if (this->wasSwitched_[dofIdxGlobal]) xnwMax *= 1.02; - // if it is larger than the equilibirum mole fraction switch wetting phase appears + // if it is larger than the equilibirum mole fraction switch: first phase appears if (xnw > xnwMax) { // wetting phase appears - std::cout << "wetting phase appears at vertex " << dofIdxGlobal - << ", coordinates: " << globalPos << ", xnw > xnwMax: " + std::cout << "First phase appears at vertex " << dofIdxGlobal + << ", coordinates: " << globalPos << ", x10 > x10_max: " << xnw << " > " << xnwMax << std::endl; newPhasePresence = Indices::bothPhases; - if (formulation == TwoPFormulation::pnsw) + if (formulation == TwoPFormulation::p1s0) priVars[switchIdx] = 0.0; - else if (formulation == TwoPFormulation::pwsn) - priVars[switchIdx] = 1.0; else - DUNE_THROW(Dune::InvalidStateException, "Chosen TwoPFormulation not supported"); + priVars[switchIdx] = 1.0; } } - else if (phasePresence == Indices::wPhaseOnly) + else if (phasePresence == Indices::firstPhaseOnly) { - // calculate non-wetting component mole fraction in the wetting phase - Scalar xwn = volVars.moleFraction(wPhaseIdx, nCompIdx); - Scalar xwnMax = FluidSystem::equilibriumMoleFraction(volVars.fluidState(), paramCache, wPhaseIdx); + // calculate second component mole fraction in the wetting phase + Scalar xwn = volVars.moleFraction(phase0Idx, comp1Idx); + Scalar xwnMax = FluidSystem::equilibriumMoleFraction(volVars.fluidState(), paramCache, phase0Idx); // if it is larger than the equilibirum mole fraction switch if(xwn > xwnMax) @@ -118,20 +118,18 @@ protected: if (this->wasSwitched_[dofIdxGlobal]) xwnMax *= 1.02; - // if it is larger than the equilibirum mole fraction switch non-wetting phase appears + // if it is larger than the equilibirum mole fraction switch second phase appears if(xwn > xwnMax) { - // nonwetting phase appears - std::cout << "nonwetting phase appears at vertex " << dofIdxGlobal - << ", coordinates: " << globalPos << ", xwn > xwnMax: " + // Second phase appears + std::cout << "Second phase appears at vertex " << dofIdxGlobal + << ", coordinates: " << globalPos << ", x01 > x01_max: " << xwn << " > " << xwnMax << std::endl; newPhasePresence = Indices::bothPhases; - if (formulation == TwoPFormulation::pnsw) + if (formulation == TwoPFormulation::p1s0) priVars[switchIdx] = 0.999; - else if (formulation == TwoPFormulation::pwsn) - priVars[switchIdx] = 0.001; else - DUNE_THROW(Dune::InvalidStateException, "Chosen TwoPFormulation not supported"); + priVars[switchIdx] = 0.001; } } // TODO: this is the same as for the 2p2c model maybe factor out @@ -141,33 +139,33 @@ protected: if (this->wasSwitched_[dofIdxGlobal]) Smin = -0.01; - if (volVars.saturation(nPhaseIdx) <= Smin) + if (volVars.saturation(phase1Idx) <= Smin) { wouldSwitch = true; // nonwetting phase disappears - std::cout << "Nonwetting phase disappears at vertex " << dofIdxGlobal - << ", coordinates: " << globalPos << ", sn: " - << volVars.saturation(nPhaseIdx) << std::endl; - newPhasePresence = Indices::wPhaseOnly; + std::cout << "Second phase disappears at vertex " << dofIdxGlobal + << ", coordinates: " << globalPos << ", s1: " + << volVars.saturation(phase1Idx) << std::endl; + newPhasePresence = Indices::firstPhaseOnly; if(useMoles) // mole-fraction formulation - priVars[switchIdx] = volVars.moleFraction(wPhaseIdx, nCompIdx); + priVars[switchIdx] = volVars.moleFraction(phase0Idx, comp1Idx); else // mass-fraction formulation - priVars[switchIdx] = volVars.massFraction(wPhaseIdx, nCompIdx); + priVars[switchIdx] = volVars.massFraction(phase0Idx, comp1Idx); } - else if (volVars.saturation(wPhaseIdx) <= Smin) + else if (volVars.saturation(phase0Idx) <= Smin) { wouldSwitch = true; // wetting phase disappears - std::cout << "Wetting phase disappears at vertex " << dofIdxGlobal - << ", coordinates: " << globalPos << ", sw: " - << volVars.saturation(wPhaseIdx) << std::endl; - newPhasePresence = Indices::nPhaseOnly; + std::cout << "First phase disappears at vertex " << dofIdxGlobal + << ", coordinates: " << globalPos << ", s0: " + << volVars.saturation(phase0Idx) << std::endl; + newPhasePresence = Indices::secondPhaseOnly; if(useMoles) // mole-fraction formulation - priVars[switchIdx] = volVars.moleFraction(nPhaseIdx, wCompIdx); + priVars[switchIdx] = volVars.moleFraction(phase1Idx, comp0Idx); else // mass-fraction formulation - priVars[switchIdx] = volVars.massFraction(nPhaseIdx, wCompIdx); + priVars[switchIdx] = volVars.massFraction(phase1Idx, comp0Idx); } } diff --git a/dumux/porousmediumflow/co2/volumevariables.hh b/dumux/porousmediumflow/co2/volumevariables.hh index 21480c4678ef127bcd7c9676b2e761e1c1219d45..e53dfe04bc471704d143b7226258174987f60121 100644 --- a/dumux/porousmediumflow/co2/volumevariables.hh +++ b/dumux/porousmediumflow/co2/volumevariables.hh @@ -47,17 +47,17 @@ class TwoPTwoCCO2VolumeVariables // component indices enum { - wCompIdx = Traits::FluidSystem::wCompIdx, - nCompIdx = Traits::FluidSystem::nCompIdx, - wPhaseIdx = Traits::FluidSystem::wPhaseIdx, - nPhaseIdx = Traits::FluidSystem::nPhaseIdx + comp0Idx = Traits::FluidSystem::comp0Idx, + comp1Idx = Traits::FluidSystem::comp1Idx, + phase0Idx = Traits::FluidSystem::phase0Idx, + phase1Idx = Traits::FluidSystem::phase1Idx }; // phase presence indices enum { - wPhaseOnly = ModelTraits::Indices::wPhaseOnly, - nPhaseOnly = ModelTraits::Indices::nPhaseOnly, + firstPhaseOnly = ModelTraits::Indices::firstPhaseOnly, + secondPhaseOnly = ModelTraits::Indices::secondPhaseOnly, bothPhases = ModelTraits::Indices::bothPhases }; @@ -68,11 +68,10 @@ class TwoPTwoCCO2VolumeVariables pressureIdx = ModelTraits::Indices::pressureIdx }; - // formulations + // formulation static constexpr auto formulation = ModelTraits::priVarFormulation(); - static constexpr auto pwsn = TwoPFormulation::pwsn; - static constexpr auto pnsw = TwoPFormulation::pnsw; + // type used for the permeability using PermeabilityType = typename Traits::PermeabilityType; public: //! The type of the object returned by the fluidState() method @@ -88,6 +87,7 @@ public: // check for permissive combinations static_assert(ModelTraits::numPhases() == 2, "NumPhases set in the model is not two!"); static_assert(ModelTraits::numComponents() == 2, "NumComponents set in the model is not two!"); + static_assert((formulation == TwoPFormulation::p0s1 || formulation == TwoPFormulation::p1s0), "Chosen TwoPFormulation not supported!"); /*! * \brief Update all quantities for a given control volume @@ -111,14 +111,17 @@ public: using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; const auto& matParams = problem.spatialParams().materialLawParams(element, scv, elemSol); - for (int phaseIdx = 0; phaseIdx < ModelTraits::numPhases(); ++phaseIdx) - { - // relative permeabilities -> require wetting phase saturation as parameter! - relativePermeability_[phaseIdx] = (phaseIdx == wPhaseIdx) ? MaterialLaw::krw(matParams, saturation(wPhaseIdx)) - : MaterialLaw::krn(matParams, saturation(wPhaseIdx)); - // binary diffusion coefficients - diffCoeff_[phaseIdx] = FluidSystem::binaryDiffusionCoefficient(fluidState_, paramCache, phaseIdx, wCompIdx, nCompIdx); - } + + const int wPhaseIdx = problem.spatialParams().template wettingPhase<FluidSystem>(element, scv, elemSol); + const int nPhaseIdx = 1 - wPhaseIdx; + + // relative permeabilities -> require wetting phase saturation as parameter! + relativePermeability_[wPhaseIdx] = MaterialLaw::krw(matParams, saturation(wPhaseIdx)); + relativePermeability_[nPhaseIdx] = MaterialLaw::krn(matParams, saturation(wPhaseIdx)); + + // binary diffusion coefficients + diffCoeff_[phase0Idx] = FluidSystem::binaryDiffusionCoefficient(fluidState_, paramCache, phase0Idx, comp0Idx, comp1Idx); + diffCoeff_[phase1Idx] = FluidSystem::binaryDiffusionCoefficient(fluidState_, paramCache, phase1Idx, comp0Idx, comp1Idx); // porosity & permeabilty porosity_ = problem.spatialParams().porosity(element, scv, elemSol); @@ -138,57 +141,66 @@ public: * Set temperature, saturations, capillary pressures, viscosities, densities and enthalpies. */ template<class ElemSol, class Problem, class Element, class Scv> - static void completeFluidState(const ElemSol& elemSol, - const Problem& problem, - const Element& element, - const Scv& scv, - FluidState& fluidState) + void completeFluidState(const ElemSol& elemSol, + const Problem& problem, + const Element& element, + const Scv& scv, + FluidState& fluidState) { - - const Scalar t = ParentType::temperature(elemSol, problem, element, scv); + const auto t = ParentType::temperature(elemSol, problem, element, scv); fluidState.setTemperature(t); const auto& priVars = ParentType::extractDofPriVars(elemSol, scv); const auto phasePresence = priVars.state(); + using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; + const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol); + const int wPhaseIdx = problem.spatialParams().template wettingPhase<FluidSystem>(element, scv, elemSol); + fluidState.setWettingPhase(wPhaseIdx); + // set the saturations - Scalar sn; - if (phasePresence == nPhaseOnly) - sn = 1.0; - else if (phasePresence == wPhaseOnly) - sn = 0.0; + if (phasePresence == secondPhaseOnly) + { + fluidState.setSaturation(phase0Idx, 0.0); + fluidState.setSaturation(phase1Idx, 1.0); + } + else if (phasePresence == firstPhaseOnly) + { + fluidState.setSaturation(phase0Idx, 1.0); + fluidState.setSaturation(phase1Idx, 0.0); + } else if (phasePresence == bothPhases) { - if (formulation == pwsn) - sn = priVars[switchIdx]; - else if (formulation == pnsw) - sn = 1.0 - priVars[switchIdx]; + if (formulation == TwoPFormulation::p0s1) + { + fluidState.setSaturation(phase1Idx, priVars[switchIdx]); + fluidState.setSaturation(phase0Idx, 1 - priVars[switchIdx]); + } else - DUNE_THROW(Dune::InvalidStateException, "Chosen TwoPFormulation is invalid."); + { + fluidState.setSaturation(phase0Idx, priVars[switchIdx]); + fluidState.setSaturation(phase1Idx, 1 - priVars[switchIdx]); + } } - else DUNE_THROW(Dune::InvalidStateException, "Invalid phase presence."); - - fluidState.setSaturation(wPhaseIdx, 1 - sn); - fluidState.setSaturation(nPhaseIdx, sn); - - // capillary pressure parameters - using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; - const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol); - Scalar pc = MaterialLaw::pc(materialParams, 1 - sn); + else + DUNE_THROW(Dune::InvalidStateException, "Invalid phase presence."); - if (formulation == pwsn) { - fluidState.setPressure(wPhaseIdx, priVars[pressureIdx]); - fluidState.setPressure(nPhaseIdx, priVars[pressureIdx] + pc); + // set pressures of the fluid phases + pc_ = MaterialLaw::pc(materialParams, fluidState.saturation(wPhaseIdx)); + if (formulation == TwoPFormulation::p0s1) + { + fluidState.setPressure(phase0Idx, priVars[pressureIdx]); + fluidState.setPressure(phase1Idx, (wPhaseIdx == phase0Idx) ? priVars[pressureIdx] + pc_ + : priVars[pressureIdx] - pc_); } - else if (formulation == pnsw) { - fluidState.setPressure(nPhaseIdx, priVars[pressureIdx]); - fluidState.setPressure(wPhaseIdx, priVars[pressureIdx] - pc); + else + { + fluidState.setPressure(phase1Idx, priVars[pressureIdx]); + fluidState.setPressure(phase0Idx, (wPhaseIdx == phase0Idx) ? priVars[pressureIdx] - pc_ + : priVars[pressureIdx] + pc_); } - else DUNE_THROW(Dune::InvalidStateException, "Chosen TwoPFormulation is invalid."); - ///////////// // calculate the phase compositions - ///////////// typename FluidSystem::ParameterCache paramCache; // both phases are present if (phasePresence == bothPhases) @@ -196,67 +208,67 @@ public: //Get the equilibrium mole fractions from the FluidSystem and set them in the fluidState //xCO2 = equilibrium mole fraction of CO2 in the liquid phase //yH2O = equilibrium mole fraction of H2O in the gas phase - const auto xwCO2 = FluidSystem::equilibriumMoleFraction(fluidState, paramCache, wPhaseIdx); - const auto xgH2O = FluidSystem::equilibriumMoleFraction(fluidState, paramCache, nPhaseIdx); + const auto xwCO2 = FluidSystem::equilibriumMoleFraction(fluidState, paramCache, phase0Idx); + const auto xgH2O = FluidSystem::equilibriumMoleFraction(fluidState, paramCache, phase1Idx); const auto xwH2O = 1 - xwCO2; const auto xgCO2 = 1 - xgH2O; - fluidState.setMoleFraction(wPhaseIdx, wCompIdx, xwH2O); - fluidState.setMoleFraction(wPhaseIdx, nCompIdx, xwCO2); - fluidState.setMoleFraction(nPhaseIdx, wCompIdx, xgH2O); - fluidState.setMoleFraction(nPhaseIdx, nCompIdx, xgCO2); + fluidState.setMoleFraction(phase0Idx, comp0Idx, xwH2O); + fluidState.setMoleFraction(phase0Idx, comp1Idx, xwCO2); + fluidState.setMoleFraction(phase1Idx, comp0Idx, xgH2O); + fluidState.setMoleFraction(phase1Idx, comp1Idx, xgCO2); } // only the nonwetting phase is present, i.e. nonwetting phase // composition is stored explicitly. - else if (phasePresence == nPhaseOnly) + else if (phasePresence == secondPhaseOnly) { if( useMoles() ) // mole-fraction formulation { // set the fluid state - fluidState.setMoleFraction(nPhaseIdx, wCompIdx, priVars[switchIdx]); - fluidState.setMoleFraction(nPhaseIdx, nCompIdx, 1-priVars[switchIdx]); + fluidState.setMoleFraction(phase1Idx, comp0Idx, priVars[switchIdx]); + fluidState.setMoleFraction(phase1Idx, comp1Idx, 1-priVars[switchIdx]); // TODO give values for non-existing wetting phase - const auto xwCO2 = FluidSystem::equilibriumMoleFraction(fluidState, paramCache, wPhaseIdx); + const auto xwCO2 = FluidSystem::equilibriumMoleFraction(fluidState, paramCache, phase0Idx); const auto xwH2O = 1 - xwCO2; - fluidState.setMoleFraction(wPhaseIdx, nCompIdx, xwCO2); - fluidState.setMoleFraction(wPhaseIdx, wCompIdx, xwH2O); + fluidState.setMoleFraction(phase0Idx, comp1Idx, xwCO2); + fluidState.setMoleFraction(phase0Idx, comp0Idx, xwH2O); } else // mass-fraction formulation { // setMassFraction() has only to be called 1-numComponents times - fluidState.setMassFraction(nPhaseIdx, wCompIdx, priVars[switchIdx]); + fluidState.setMassFraction(phase1Idx, comp0Idx, priVars[switchIdx]); // TODO give values for non-existing wetting phase - const auto xwCO2 = FluidSystem::equilibriumMoleFraction(fluidState, paramCache, wPhaseIdx); + const auto xwCO2 = FluidSystem::equilibriumMoleFraction(fluidState, paramCache, phase0Idx); const auto xwH2O = 1 - xwCO2; - fluidState.setMoleFraction(wPhaseIdx, nCompIdx, xwCO2); - fluidState.setMoleFraction(wPhaseIdx, wCompIdx, xwH2O); + fluidState.setMoleFraction(phase0Idx, comp1Idx, xwCO2); + fluidState.setMoleFraction(phase0Idx, comp0Idx, xwH2O); } } // only the wetting phase is present, i.e. wetting phase // composition is stored explicitly. - else if (phasePresence == wPhaseOnly) + else if (phasePresence == firstPhaseOnly) { if( useMoles() ) // mole-fraction formulation { // convert mass to mole fractions and set the fluid state - fluidState.setMoleFraction(wPhaseIdx, wCompIdx, 1-priVars[switchIdx]); - fluidState.setMoleFraction(wPhaseIdx, nCompIdx, priVars[switchIdx]); + fluidState.setMoleFraction(phase0Idx, comp0Idx, 1-priVars[switchIdx]); + fluidState.setMoleFraction(phase0Idx, comp1Idx, priVars[switchIdx]); // TODO give values for non-existing nonwetting phase - Scalar xnH2O = FluidSystem::equilibriumMoleFraction(fluidState, paramCache, nPhaseIdx); + Scalar xnH2O = FluidSystem::equilibriumMoleFraction(fluidState, paramCache, phase1Idx); Scalar xnCO2 = 1 - xnH2O; - fluidState.setMoleFraction(nPhaseIdx, nCompIdx, xnCO2); - fluidState.setMoleFraction(nPhaseIdx, wCompIdx, xnH2O); + fluidState.setMoleFraction(phase1Idx, comp1Idx, xnCO2); + fluidState.setMoleFraction(phase1Idx, comp0Idx, xnH2O); } else // mass-fraction formulation { // setMassFraction() has only to be called 1-numComponents times - fluidState.setMassFraction(wPhaseIdx, nCompIdx, priVars[switchIdx]); + fluidState.setMassFraction(phase0Idx, comp1Idx, priVars[switchIdx]); // TODO give values for non-existing nonwetting phase - Scalar xnH2O = FluidSystem::equilibriumMoleFraction(fluidState, paramCache, nPhaseIdx); + Scalar xnH2O = FluidSystem::equilibriumMoleFraction(fluidState, paramCache, phase1Idx); Scalar xnCO2 = 1 - xnH2O; - fluidState.setMoleFraction(nPhaseIdx, nCompIdx, xnCO2); - fluidState.setMoleFraction(nPhaseIdx, wCompIdx, xnH2O); + fluidState.setMoleFraction(phase1Idx, comp1Idx, xnCO2); + fluidState.setMoleFraction(phase1Idx, comp0Idx, xnH2O); } } @@ -379,7 +391,7 @@ public: * in \f$[kg/(m*s^2)=N/m^2=Pa]\f$. */ Scalar capillaryPressure() const - { return fluidState_.pressure(nPhaseIdx) - fluidState_.pressure(wPhaseIdx); } + { return fluidState_.pressure(phase1Idx) - fluidState_.pressure(phase0Idx); } /*! * \brief Returns the average porosity within the control volume in \f$[-]\f$. @@ -406,6 +418,7 @@ public: private: FluidState fluidState_; + Scalar pc_; //!< The capillary pressure Scalar porosity_; //!< Effective porosity within the control volume PermeabilityType permeability_; //!< Effective permeability within the control volume diff --git a/dumux/porousmediumflow/mineralization/volumevariables.hh b/dumux/porousmediumflow/mineralization/volumevariables.hh index 82bc3386c94b30a291364a79922af5a5649930b8..1855d728961dedc0f39e7e9c25dc6c12522adc5a 100644 --- a/dumux/porousmediumflow/mineralization/volumevariables.hh +++ b/dumux/porousmediumflow/mineralization/volumevariables.hh @@ -38,12 +38,6 @@ class MineralizationVolumeVariables : public NonMineralizationVolVars using ParentType = NonMineralizationVolVars; using Scalar = typename Traits::PrimaryVariables::value_type; using ModelTraits = typename Traits::ModelTraits; - enum - { - numPhases = ModelTraits::numPhases(), - numSPhases = ModelTraits::numSPhases(), - numComponents = ModelTraits::numComponents() - }; public: //! export the type of the fluid state @@ -65,9 +59,9 @@ public: auto&& priVars = elemSol[scv.indexInElement()]; sumPrecipitates_ = 0.0; - for(int sPhaseIdx = 0; sPhaseIdx < numSPhases; ++sPhaseIdx) + for(int sPhaseIdx = 0; sPhaseIdx < ModelTraits::numSPhases(); ++sPhaseIdx) { - precipitateVolumeFraction_[sPhaseIdx] = priVars[numComponents + sPhaseIdx]; + precipitateVolumeFraction_[sPhaseIdx] = priVars[ModelTraits::numComponents() + sPhaseIdx]; sumPrecipitates_+= precipitateVolumeFraction_[sPhaseIdx]; } } @@ -79,16 +73,17 @@ public: * \param phaseIdx the index of the solid phase */ Scalar precipitateVolumeFraction(int phaseIdx) const - { return precipitateVolumeFraction_[phaseIdx - numPhases]; } + { return precipitateVolumeFraction_[phaseIdx - ModelTraits::numPhases()]; } /*! * \brief Returns the density of the phase for all fluid and solid phases * * \param phaseIdx the index of the fluid phase + * \todo TODO: This fails for 1pnc if fluidSystemPhaseIdx is not 0 */ Scalar density(int phaseIdx) const { - if (phaseIdx < numPhases) + if (phaseIdx < ModelTraits::numPhases()) return this->fluidState_.density(phaseIdx); else return FluidSystem::precipitateDensity(phaseIdx); @@ -99,10 +94,11 @@ public: * control volume. * * \param phaseIdx The phase index + * \todo TODO: This fails for 1pnc if fluidSystemPhaseIdx is not 0 */ Scalar molarDensity(int phaseIdx) const { - if (phaseIdx < numPhases) + if (phaseIdx < ModelTraits::numPhases()) return this->fluidState_.molarDensity(phaseIdx); else return FluidSystem::precipitateMolarDensity(phaseIdx); @@ -128,7 +124,7 @@ public: } protected: - Scalar precipitateVolumeFraction_[numSPhases]; + Scalar precipitateVolumeFraction_[ModelTraits::numSPhases()]; Scalar sumPrecipitates_; }; } // end namespace Dumux diff --git a/dumux/porousmediumflow/nonequilibrium/localresidual.hh b/dumux/porousmediumflow/nonequilibrium/localresidual.hh index e5a2623501da87765c36561f4bc39520ede6a8d6..5ac069eeec690471443d6922376762e10d351599 100644 --- a/dumux/porousmediumflow/nonequilibrium/localresidual.hh +++ b/dumux/porousmediumflow/nonequilibrium/localresidual.hh @@ -183,10 +183,10 @@ class NonEquilibriumLocalResidualImplementation<TypeTag, true, true>: public GET using ComponentVector = Dune::FieldVector<Scalar, numComponents>; enum { conti0EqIdx = Indices::conti0EqIdx }; - enum { nCompIdx = FluidSystem::nCompIdx } ; - enum { wCompIdx = FluidSystem::wCompIdx } ; - enum { wPhaseIdx = FluidSystem::wPhaseIdx} ; - enum { nPhaseIdx = FluidSystem::nPhaseIdx} ; + enum { comp1Idx = FluidSystem::comp1Idx } ; + enum { comp0Idx = FluidSystem::comp0Idx } ; + enum { phase0Idx = FluidSystem::phase0Idx} ; + enum { phase1Idx = FluidSystem::phase1Idx} ; enum { sPhaseIdx = FluidSystem::sPhaseIdx} ; public: @@ -286,11 +286,11 @@ public: ComponentVector componentIntoPhaseMassTransfer[numPhases]; #define FUNKYMASSTRANSFER 0 #if FUNKYMASSTRANSFER - const Scalar mu_nPhaseNCompEquil = volVars.chemicalPotentialEquil(nPhaseIdx, nCompIdx) ; // very 2p2c - const Scalar mu_wPhaseWCompEquil = volVars.chemicalPotentialEquil(wPhaseIdx, wCompIdx); // very 2p2c + const Scalar mu_nPhaseNCompEquil = volVars.chemicalPotentialEquil(phase1Idx, comp1Idx) ; // very 2p2c + const Scalar mu_wPhaseWCompEquil = volVars.chemicalPotentialEquil(phase0Idx, comp0Idx); // very 2p2c - const Scalar mu_wPhaseNComp = volVars.chemicalPotential(wPhaseIdx, nCompIdx) ; // very 2p2c - const Scalar mu_nPhaseWComp = volVars.chemicalPotential(nPhaseIdx, wCompIdx); // very 2p2c + const Scalar mu_wPhaseNComp = volVars.chemicalPotential(phase0Idx, comp1Idx) ; // very 2p2c + const Scalar mu_nPhaseWComp = volVars.chemicalPotential(phase1Idx, comp0Idx); // very 2p2c Valgrind::CheckDefined(mu_nPhaseNCompEquil); Valgrind::CheckDefined(mu_wPhaseWCompEquil); @@ -298,8 +298,8 @@ public: Valgrind::CheckDefined(mu_nPhaseWComp); const Scalar characteristicLength = volVars.characteristicLength() ; - const Scalar temperature = volVars.temperature(wPhaseIdx); - const Scalar pn = volVars.pressure(nPhaseIdx); + const Scalar temperature = volVars.temperature(phase0Idx); + const Scalar pn = volVars.pressure(phase1Idx); const Scalar henry = FluidSystem::henry(temperature) ; const Scalar gradNinWApprox = ( mu_wPhaseNComp - mu_nPhaseNCompEquil) / characteristicLength; // very 2p2c // 1. / henry * const Scalar gradWinNApprox = ( mu_nPhaseWComp - mu_wPhaseWCompEquil) / characteristicLength; // very 2p2c // 1. / pn * @@ -314,13 +314,13 @@ public: Valgrind::CheckDefined(x); // "equilibrium" values: calculated in volume variables - const Scalar x_wPhaseNCompEquil = volVars.xEquil(wPhaseIdx, nCompIdx) ; // very 2p2c - const Scalar x_nPhaseWCompEquil = volVars.xEquil(nPhaseIdx, wCompIdx); // very 2p2c + const Scalar x_wPhaseNCompEquil = volVars.xEquil(phase0Idx, comp1Idx) ; // very 2p2c + const Scalar x_nPhaseWCompEquil = volVars.xEquil(phase1Idx, comp0Idx); // very 2p2c Valgrind::CheckDefined(x_wPhaseNCompEquil); Valgrind::CheckDefined(x_nPhaseWCompEquil); const Scalar characteristicLength = volVars.characteristicLength() ; - const Scalar gradNinWApprox = (x[wPhaseIdx][nCompIdx] - x_wPhaseNCompEquil) / characteristicLength; // very 2p2c - const Scalar gradWinNApprox = (x[nPhaseIdx][wCompIdx] - x_nPhaseWCompEquil) / characteristicLength; // very 2p2c + const Scalar gradNinWApprox = (x[phase0Idx][comp1Idx] - x_wPhaseNCompEquil) / characteristicLength; // very 2p2c + const Scalar gradWinNApprox = (x[phase1Idx][comp0Idx] - x_nPhaseWCompEquil) / characteristicLength; // very 2p2c #endif Scalar phaseDensity[numPhases]; for(int phaseIdx=0; phaseIdx<numPhases; ++phaseIdx){ @@ -328,31 +328,31 @@ public: } // diffusion coefficients in wetting phase - const Scalar diffCoeffNinW = volVars.diffusionCoefficient(wPhaseIdx, nCompIdx) ; + const Scalar diffCoeffNinW = volVars.diffusionCoefficient(phase0Idx, comp1Idx) ; Valgrind::CheckDefined(diffCoeffNinW); // diffusion coefficients in non-wetting phase - const Scalar diffCoeffWinN = volVars.diffusionCoefficient(nPhaseIdx, wCompIdx) ; + const Scalar diffCoeffWinN = volVars.diffusionCoefficient(phase1Idx, comp0Idx) ; Valgrind::CheckDefined(diffCoeffWinN); const Scalar factorMassTransfer = volVars.factorMassTransfer() ; - const Scalar awn = volVars.interfacialArea(wPhaseIdx, nPhaseIdx); + const Scalar awn = volVars.interfacialArea(phase0Idx, phase1Idx); - const Scalar sherwoodWPhase = volVars.sherwoodNumber(wPhaseIdx); - const Scalar sherwoodNPhase = volVars.sherwoodNumber(nPhaseIdx); + const Scalar sherwoodWPhase = volVars.sherwoodNumber(phase0Idx); + const Scalar sherwoodNPhase = volVars.sherwoodNumber(phase1Idx); // actual diffusion is always calculated for eq's 2,3 // Eq's 1,4 have to be the same with different sign, because no mass is accumulated in the interface // i.e. automatically conserving mass that mvoes across the interface - const Scalar nCompIntoWPhase = - factorMassTransfer * gradNinWApprox * awn * phaseDensity[wPhaseIdx] * diffCoeffNinW * sherwoodWPhase; + const Scalar nCompIntoWPhase = - factorMassTransfer * gradNinWApprox * awn * phaseDensity[phase0Idx] * diffCoeffNinW * sherwoodWPhase; const Scalar nCompIntoNPhase = - nCompIntoWPhase ; - const Scalar wCompIntoNPhase = - factorMassTransfer * gradWinNApprox * awn * phaseDensity[nPhaseIdx] * diffCoeffWinN * sherwoodNPhase; + const Scalar wCompIntoNPhase = - factorMassTransfer * gradWinNApprox * awn * phaseDensity[phase1Idx] * diffCoeffWinN * sherwoodNPhase; const Scalar wCompIntoWPhase = - wCompIntoNPhase ; - componentIntoPhaseMassTransfer[wPhaseIdx][nCompIdx] = nCompIntoWPhase; - componentIntoPhaseMassTransfer[nPhaseIdx][nCompIdx] = nCompIntoNPhase; - componentIntoPhaseMassTransfer[nPhaseIdx][wCompIdx] = wCompIntoNPhase; - componentIntoPhaseMassTransfer[wPhaseIdx][wCompIdx] = wCompIntoWPhase; + componentIntoPhaseMassTransfer[phase0Idx][comp1Idx] = nCompIntoWPhase; + componentIntoPhaseMassTransfer[phase1Idx][comp1Idx] = nCompIntoNPhase; + componentIntoPhaseMassTransfer[phase1Idx][comp0Idx] = wCompIntoNPhase; + componentIntoPhaseMassTransfer[phase0Idx][comp0Idx] = wCompIntoWPhase; Valgrind::CheckDefined(componentIntoPhaseMassTransfer); diff --git a/dumux/porousmediumflow/nonequilibrium/thermal/localresidual.hh b/dumux/porousmediumflow/nonequilibrium/thermal/localresidual.hh index 54e2f429356651d1b026a99e54a833f861a94672..6a4fff355eb393ae46aef8c8bfbd204db3479a40 100644 --- a/dumux/porousmediumflow/nonequilibrium/thermal/localresidual.hh +++ b/dumux/porousmediumflow/nonequilibrium/thermal/localresidual.hh @@ -64,8 +64,8 @@ class EnergyLocalResidualNonEquilibrium<TypeTag, 1/*numEnergyEqFluid*/> enum { energyEqSolidIdx = Indices::energyEqSolidIdx}; enum { numComponents = ModelTraits::numComponents() }; - enum { wPhaseIdx = FluidSystem::wPhaseIdx}; - enum { nPhaseIdx = FluidSystem::nPhaseIdx}; + enum { phase0Idx = FluidSystem::phase0Idx}; + enum { phase1Idx = FluidSystem::phase1Idx}; enum { sPhaseIdx = FluidSystem::sPhaseIdx}; public: @@ -177,17 +177,17 @@ public: const Scalar TFluid = volVars.temperature(0); const Scalar TSolid = volVars.temperatureSolid(); - const Scalar satW = fs.saturation(wPhaseIdx) ; - const Scalar satN = fs.saturation(nPhaseIdx) ; + const Scalar satW = fs.saturation(phase0Idx) ; + const Scalar satN = fs.saturation(phase1Idx) ; const Scalar eps = 1e-6 ; Scalar solidToFluidEnergyExchange ; Scalar fluidConductivity ; if (satW < 1.0 - eps) - fluidConductivity = volVars.fluidThermalConductivity(nPhaseIdx) ; + fluidConductivity = volVars.fluidThermalConductivity(phase1Idx) ; else if (satW >= 1.0 - eps) - fluidConductivity = volVars.fluidThermalConductivity(wPhaseIdx) ; + fluidConductivity = volVars.fluidThermalConductivity(phase0Idx) ; else DUNE_THROW(Dune::NotImplemented, "wrong range"); @@ -199,11 +199,11 @@ public: if (satW < (0 + eps) ) { - solidToFluidEnergyExchange *= volVars.nusseltNumber(nPhaseIdx) ; + solidToFluidEnergyExchange *= volVars.nusseltNumber(phase1Idx) ; } else if ( (satW >= 0 + eps) and (satW < 1.0-eps) ) { - solidToFluidEnergyExchange *= (volVars.nusseltNumber(nPhaseIdx) * satN ); + solidToFluidEnergyExchange *= (volVars.nusseltNumber(phase1Idx) * satN ); Scalar qBoil ; if (satW<=epsRegul) {// regularize @@ -233,7 +233,7 @@ public: } else if (satW >= 1.0-eps) { - solidToFluidEnergyExchange *= volVars.nusseltNumber(wPhaseIdx) ; + solidToFluidEnergyExchange *= volVars.nusseltNumber(phase0Idx) ; } else DUNE_THROW(Dune::NotImplemented, @@ -278,17 +278,17 @@ public: const Scalar characteristicLength = volVars.characteristicLength() ; using std::pow; const Scalar as = 6.0 * (1.0-volVars.porosity()) / characteristicLength ; - const Scalar mul = fs.viscosity(wPhaseIdx) ; - const Scalar deltahv = fs.enthalpy(nPhaseIdx) - fs.enthalpy(wPhaseIdx); - const Scalar deltaRho = fs.density(wPhaseIdx) - fs.density(nPhaseIdx) ; + const Scalar mul = fs.viscosity(phase0Idx) ; + const Scalar deltahv = fs.enthalpy(phase1Idx) - fs.enthalpy(phase0Idx); + const Scalar deltaRho = fs.density(phase0Idx) - fs.density(phase1Idx) ; const Scalar firstBracket = pow(g * deltaRho / gamma, 0.5); - const Scalar cp = FluidSystem::heatCapacity(fs, wPhaseIdx) ; + const Scalar cp = FluidSystem::heatCapacity(fs, phase0Idx) ; // This use of Tsat is only justified if the fluid is always boiling (tsat equals boiling conditions) // If a different state is to be simulated, please use the actual fluid temperature instead. - const Scalar Tsat = FluidSystem::vaporTemperature(fs, nPhaseIdx ) ; + const Scalar Tsat = FluidSystem::vaporTemperature(fs, phase1Idx ) ; const Scalar deltaT = TSolid - Tsat ; const Scalar secondBracket = pow( (cp *deltaT / (0.006 * deltahv) ) , 3.0 ) ; - const Scalar Prl = volVars.prandtlNumber(wPhaseIdx) ; + const Scalar Prl = volVars.prandtlNumber(phase0Idx) ; const Scalar thirdBracket = pow( 1/Prl , (1.7/0.33) ); const Scalar QBoil = satW * as * mul * deltahv * firstBracket * secondBracket * thirdBracket ; return QBoil; @@ -335,8 +335,8 @@ class EnergyLocalResidualNonEquilibrium<TypeTag, 2 /*numEnergyEqFluid*/> enum { conti0EqIdx = Indices::conti0EqIdx }; enum { numComponents = ModelTraits::numComponents() }; - enum { wPhaseIdx = FluidSystem::wPhaseIdx}; - enum { nPhaseIdx = FluidSystem::nPhaseIdx}; + enum { phase0Idx = FluidSystem::phase0Idx}; + enum { phase1Idx = FluidSystem::phase1Idx}; enum { sPhaseIdx = FluidSystem::sPhaseIdx}; static constexpr bool enableChemicalNonEquilibrium = ModelTraits::enableChemicalNonEquilibrium(); @@ -418,16 +418,16 @@ public: const auto &localScvIdx = scv.indexInElement(); const auto &volVars = elemVolVars[localScvIdx]; - const Scalar awn = volVars.interfacialArea(wPhaseIdx, nPhaseIdx); - const Scalar aws = volVars.interfacialArea(wPhaseIdx, sPhaseIdx); - const Scalar ans = volVars.interfacialArea(nPhaseIdx, sPhaseIdx); + const Scalar awn = volVars.interfacialArea(phase0Idx, phase1Idx); + const Scalar aws = volVars.interfacialArea(phase0Idx, sPhaseIdx); + const Scalar ans = volVars.interfacialArea(phase1Idx, sPhaseIdx); - const Scalar Tw = volVars.temperature(wPhaseIdx); - const Scalar Tn = volVars.temperature(nPhaseIdx); + const Scalar Tw = volVars.temperature(phase0Idx); + const Scalar Tn = volVars.temperature(phase1Idx); const Scalar Ts = volVars.temperatureSolid(); - const Scalar lambdaWetting = volVars.fluidThermalConductivity(wPhaseIdx); - const Scalar lambdaNonWetting = volVars.fluidThermalConductivity(nPhaseIdx); + const Scalar lambdaWetting = volVars.fluidThermalConductivity(phase0Idx); + const Scalar lambdaNonWetting = volVars.fluidThermalConductivity(phase1Idx); const Scalar lambdaSolid = volVars.solidThermalConductivity(); const Scalar lambdaWN = harmonicMean(lambdaWetting, lambdaNonWetting); @@ -437,9 +437,9 @@ public: const Scalar characteristicLength = volVars.characteristicLength() ; const Scalar factorEnergyTransfer = volVars.factorEnergyTransfer() ; - const Scalar nusseltWN = harmonicMean(volVars.nusseltNumber(wPhaseIdx), volVars.nusseltNumber(nPhaseIdx)); - const Scalar nusseltWS = volVars.nusseltNumber(wPhaseIdx); - const Scalar nusseltNS = volVars.nusseltNumber(nPhaseIdx); + const Scalar nusseltWN = harmonicMean(volVars.nusseltNumber(phase0Idx), volVars.nusseltNumber(phase1Idx)); + const Scalar nusseltWS = volVars.nusseltNumber(phase0Idx); + const Scalar nusseltNS = volVars.nusseltNumber(phase1Idx); const Scalar wettingToNonWettingEnergyExchange = factorEnergyTransfer * (Tw - Tn) / characteristicLength * awn * lambdaWN * nusseltWN ; const Scalar wettingToSolidEnergyExchange = factorEnergyTransfer * (Tw - Ts) / characteristicLength * aws * lambdaWS * nusseltWS ; @@ -448,10 +448,10 @@ public: for(int phaseIdx =0; phaseIdx<numEnergyEqFluid+numEnergyEqSolid; ++phaseIdx){ switch (phaseIdx) { - case wPhaseIdx: + case phase0Idx: source[energyEq0Idx + phaseIdx] += ( - wettingToNonWettingEnergyExchange - wettingToSolidEnergyExchange); break; - case nPhaseIdx: + case phase1Idx: source[energyEq0Idx + phaseIdx] += (+ wettingToNonWettingEnergyExchange - nonWettingToSolidEnergyExchange); break; case sPhaseIdx: @@ -489,24 +489,24 @@ public: { switch (phaseIdx) { - case wPhaseIdx: + case phase0Idx: //sum up the transfered energy by the components into the wetting phase for(int compIdx =0; compIdx<numComponents; ++compIdx) { const unsigned int eqIdx = conti0EqIdx + compIdx + phaseIdx*numComponents; source[energyEq0Idx + phaseIdx] += (source[eqIdx] * FluidSystem::molarMass(compIdx) - * FluidSystem::componentEnthalpy(fluidState, nPhaseIdx, compIdx) ); + * FluidSystem::componentEnthalpy(fluidState, phase1Idx, compIdx) ); } break; - case nPhaseIdx: + case phase1Idx: //sum up the transfered energy by the components into the nonwetting phase for(int compIdx =0; compIdx<numComponents; ++compIdx) { const unsigned int eqIdx = conti0EqIdx + compIdx + phaseIdx*numComponents; source[energyEq0Idx + phaseIdx] += (source[eqIdx] * FluidSystem::molarMass(compIdx) - *FluidSystem::componentEnthalpy(fluidState, wPhaseIdx, compIdx)); + *FluidSystem::componentEnthalpy(fluidState, phase0Idx, compIdx)); } break; case sPhaseIdx: diff --git a/dumux/porousmediumflow/nonequilibrium/volumevariables.hh b/dumux/porousmediumflow/nonequilibrium/volumevariables.hh index e30d0b14cf79aeac1fddf2cca816849467fd8d73..b1c113862f4c235d72316bcae0adcceebf1b3d4c 100644 --- a/dumux/porousmediumflow/nonequilibrium/volumevariables.hh +++ b/dumux/porousmediumflow/nonequilibrium/volumevariables.hh @@ -248,8 +248,10 @@ class NonEquilibriumVolumeVariablesImplementation< Traits, static constexpr auto numPhases = ModelTraits::numPhases(); static constexpr auto numComponents = ModelTraits::numComponents(); - static constexpr auto wPhaseIdx = FluidSystem::wPhaseIdx; - static constexpr auto nPhaseIdx = FluidSystem::nPhaseIdx; + static constexpr auto phase0Idx = FluidSystem::phase0Idx; + static constexpr auto phase1Idx = FluidSystem::phase1Idx; + static constexpr auto wCompIdx = FluidSystem::comp0Idx; + static constexpr auto nCompIdx = FluidSystem::comp1Idx; using DimLessNum = DimensionlessNumbers<Scalar>; using ConstraintSolver = MiscibleMultiPhaseComposition<Scalar, FluidSystem>; @@ -277,8 +279,8 @@ public: const auto& awnSurfaceParams = problem.spatialParams().aWettingNonWettingSurfaceParams(element, scv, elemSol) ; const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol) ; - const auto Sw = fluidState.saturation(wPhaseIdx) ; - const auto pc = fluidState.pressure(nPhaseIdx) - fluidState.pressure(wPhaseIdx); + const auto Sw = fluidState.saturation(phase0Idx) ; + const auto pc = fluidState.pressure(phase1Idx) - fluidState.pressure(phase0Idx); // so far there is only a model for kinetic mass transfer between fluid phases using AwnSurface = typename Problem::SpatialParams::AwnSurface; @@ -300,8 +302,8 @@ public: const auto diffCoeff = FluidSystem::binaryDiffusionCoefficient(fluidState, paramCache, phaseIdx, - FluidSystem::wCompIdx, - FluidSystem::nCompIdx); + wCompIdx, + nCompIdx); reynoldsNumber_[phaseIdx] = DimLessNum::reynoldsNumber(darcyMagVelocity, characteristicLength_, kinematicViscosity); schmidtNumber_[phaseIdx] = DimLessNum::schmidtNumber(dynamicViscosity, density, diffCoeff); @@ -369,8 +371,8 @@ public: const Scalar interfacialArea(const unsigned int phaseIIdx, const unsigned int phaseJIdx) const { // so far there is only a model for kinetic mass transfer between fluid phases - assert( (phaseIIdx == nPhaseIdx && phaseJIdx == wPhaseIdx) - || (phaseIIdx == wPhaseIdx && phaseJIdx == nPhaseIdx) ); + assert( (phaseIIdx == phase1Idx && phaseJIdx == phase0Idx) + || (phaseIIdx == phase0Idx && phaseJIdx == phase1Idx) ); return interfacialArea_; } @@ -414,9 +416,11 @@ class NonEquilibriumVolumeVariablesImplementation< Traits, static constexpr auto numEnergyEqFluid = ModelTraits::numEnergyEqFluid(); static constexpr auto numEnergyEqSolid = ModelTraits::numEnergyEqSolid(); - static constexpr auto wPhaseIdx = FluidSystem::wPhaseIdx; - static constexpr auto nPhaseIdx = FluidSystem::nPhaseIdx; + static constexpr auto phase0Idx = FluidSystem::phase0Idx; + static constexpr auto phase1Idx = FluidSystem::phase1Idx; static constexpr auto sPhaseIdx = FluidSystem::sPhaseIdx; + static constexpr auto wCompIdx = FluidSystem::comp0Idx; + static constexpr auto nCompIdx = FluidSystem::comp1Idx; using DimLessNum = DimensionlessNumbers<Scalar>; using ConstraintSolver = MiscibleMultiPhaseComposition<Scalar, FluidSystem>; @@ -448,8 +452,8 @@ public: const auto& aWettingNonWettingSurfaceParams = problem.spatialParams().aWettingNonWettingSurfaceParams(element, scv, elemSol); const auto& aNonWettingSolidSurfaceParams = problem.spatialParams().aNonWettingSolidSurfaceParams(element, scv, elemSol); - const Scalar pc = fluidState.pressure(nPhaseIdx) - fluidState.pressure(wPhaseIdx); - const Scalar Sw = fluidState.saturation(wPhaseIdx); + const Scalar pc = fluidState.pressure(phase1Idx) - fluidState.pressure(phase0Idx); + const Scalar Sw = fluidState.saturation(phase0Idx); Scalar awn; @@ -473,9 +477,9 @@ public: using AwnSurface = typename Problem::SpatialParams::AwnSurface; awn = AwnSurface::interfacialArea(aWettingNonWettingSurfaceParams, materialParams, Sw, pc ); - interfacialArea_[wPhaseIdx][nPhaseIdx] = awn; - interfacialArea_[nPhaseIdx][wPhaseIdx] = interfacialArea_[wPhaseIdx][nPhaseIdx]; - interfacialArea_[wPhaseIdx][wPhaseIdx] = 0.; + interfacialArea_[phase0Idx][phase1Idx] = awn; + interfacialArea_[phase1Idx][phase0Idx] = interfacialArea_[phase0Idx][phase1Idx]; + interfacialArea_[phase0Idx][phase0Idx] = 0.; using AnsSurface = typename Problem::SpatialParams::AnsSurface; Scalar ans = AnsSurface::interfacialArea(aNonWettingSolidSurfaceParams, materialParams,Sw, pc); @@ -489,21 +493,21 @@ public: solidSurface_ = AnsSurface::interfacialArea(aNonWettingSolidSurfaceParams, materialParams, /*Sw=*/0., pcMax); const Scalar aws = solidSurface_ - ans; - interfacialArea_[wPhaseIdx][sPhaseIdx] = aws; - interfacialArea_[sPhaseIdx][wPhaseIdx] = interfacialArea_[wPhaseIdx][sPhaseIdx]; + interfacialArea_[phase0Idx][sPhaseIdx] = aws; + interfacialArea_[sPhaseIdx][phase0Idx] = interfacialArea_[phase0Idx][sPhaseIdx]; interfacialArea_[sPhaseIdx][sPhaseIdx] = 0.; #else using AwsSurface = typename Problem::SpatialParams::AwsSurface; const auto& aWettingSolidSurfaceParams = problem.spatialParams().aWettingSolidSurfaceParams(); const auto aws = AwsSurface::interfacialArea(aWettingSolidSurfaceParams,materialParams, Sw, pc ); - interfacialArea_[wPhaseIdx][sPhaseIdx] = aws ; - interfacialArea_[sPhaseIdx][wPhaseIdx] = interfacialArea_[wPhaseIdx][sPhaseIdx]; + interfacialArea_[phase0Idx][sPhaseIdx] = aws ; + interfacialArea_[sPhaseIdx][phase0Idx] = interfacialArea_[phase0Idx][sPhaseIdx]; interfacialArea_[sPhaseIdx][sPhaseIdx] = 0.; #endif - interfacialArea_[nPhaseIdx][sPhaseIdx] = ans; - interfacialArea_[sPhaseIdx][nPhaseIdx] = interfacialArea_[nPhaseIdx][sPhaseIdx]; - interfacialArea_[nPhaseIdx][nPhaseIdx] = 0.; + interfacialArea_[phase1Idx][sPhaseIdx] = ans; + interfacialArea_[sPhaseIdx][phase1Idx] = interfacialArea_[phase1Idx][sPhaseIdx]; + interfacialArea_[phase1Idx][phase1Idx] = 0.; factorMassTransfer_ = problem.spatialParams().factorMassTransfer(element, scv, elemSol); factorEnergyTransfer_ = problem.spatialParams().factorEnergyTransfer(element, scv, elemSol); @@ -524,8 +528,8 @@ public: const auto diffCoeff = FluidSystem::binaryDiffusionCoefficient(fluidState, paramCache, phaseIdx, - FluidSystem::wCompIdx, - FluidSystem::nCompIdx); + wCompIdx, + nCompIdx); reynoldsNumber_[phaseIdx] = DimLessNum::reynoldsNumber(darcyMagVelocity, characteristicLength_, kinematicViscosity); prandtlNumber_[phaseIdx] = DimLessNum::prandtlNumber(dynamicViscosity, heatCapacity, thermalConductivity); diff --git a/dumux/porousmediumflow/richards/indices.hh b/dumux/porousmediumflow/richards/indices.hh index 0bd2cb78ed2412c32f9d2dd0703b566a65e13dc6..fbe3eed8d81ef668dc0e027b184fd16e5cdf9658 100644 --- a/dumux/porousmediumflow/richards/indices.hh +++ b/dumux/porousmediumflow/richards/indices.hh @@ -24,9 +24,7 @@ #ifndef DUMUX_RICHARDS_INDICES_HH #define DUMUX_RICHARDS_INDICES_HH -namespace Dumux -{ -// \{ +namespace Dumux { /*! * \ingroup RichardsModel @@ -35,32 +33,18 @@ namespace Dumux struct RichardsIndices { - ////////// - // primary variable indices - ////////// - //! Primary variable index for the wetting phase pressure static constexpr int pressureIdx = 0; static constexpr int switchIdx = 0; - ////////// - // equation indices - ////////// //! Equation index for the mass conservation of the wetting phase static constexpr int conti0EqIdx = 0; - ////////// - // phase indices - ////////// - static constexpr int wPhaseIdx = 0; //!< Index of the wetting phase; - static constexpr int nPhaseIdx = 1; //!< Index of the non-wetting phase; - // present phases (-> 'pseudo' primary variable) - static constexpr int wPhaseOnly = 1; //!< Only the non-wetting phase is present - static constexpr int nPhaseOnly = 2; //!< Only the wetting phase is present + static constexpr int liquidPhaseOnly = 1; //!< Only the liquid phase is present + static constexpr int gasPhaseOnly = 2; //!< Only the gas phase is present static constexpr int bothPhases = 3; //!< Both phases are present }; -// \} } // end namespace Dumux diff --git a/dumux/porousmediumflow/richards/localresidual.hh b/dumux/porousmediumflow/richards/localresidual.hh index 3294e0991fafe8dbe0a3ba43a0ed70616471938c..3927d4716d7a366525eeb86dd6152eb314e8db5b 100644 --- a/dumux/porousmediumflow/richards/localresidual.hh +++ b/dumux/porousmediumflow/richards/localresidual.hh @@ -60,9 +60,9 @@ class RichardsLocalResidual : public GET_PROP_TYPE(TypeTag, BaseLocalResidual) // phase indices enum { - wPhaseIdx = FluidSystem::wPhaseIdx, - nPhaseIdx = FluidSystem::nPhaseIdx, - wCompIdx = FluidSystem::wCompIdx + liquidPhaseIdx = FluidSystem::liquidPhaseIdx, + gasPhaseIdx = FluidSystem::gasPhaseIdx, + liquidCompIdx = FluidSystem::liquidCompIdx }; static constexpr bool enableWaterDiffusionInAir @@ -88,20 +88,20 @@ public: // partial time derivative of the phase mass NumEqVector storage(0.0); storage[conti0EqIdx] = volVars.porosity() - * volVars.density(wPhaseIdx) - * volVars.saturation(wPhaseIdx); + * volVars.density(liquidPhaseIdx) + * volVars.saturation(liquidPhaseIdx); // for extended Richards we consider water in air if (enableWaterDiffusionInAir) storage[conti0EqIdx] += volVars.porosity() - * volVars.molarDensity(nPhaseIdx) - * volVars.moleFraction(nPhaseIdx, wCompIdx) - * FluidSystem::molarMass(wCompIdx) - * volVars.saturation(nPhaseIdx); + * volVars.molarDensity(gasPhaseIdx) + * volVars.moleFraction(gasPhaseIdx, liquidCompIdx) + * FluidSystem::molarMass(liquidCompIdx) + * volVars.saturation(gasPhaseIdx); //! The energy storage in the water, air and solid phase - EnergyLocalResidual::fluidPhaseStorage(storage, scv, volVars, wPhaseIdx); - EnergyLocalResidual::fluidPhaseStorage(storage, scv, volVars, nPhaseIdx); + EnergyLocalResidual::fluidPhaseStorage(storage, scv, volVars, liquidPhaseIdx); + EnergyLocalResidual::fluidPhaseStorage(storage, scv, volVars, gasPhaseIdx); EnergyLocalResidual::solidPhaseStorage(storage, scv, volVars); return storage; @@ -131,16 +131,16 @@ public: NumEqVector flux(0.0); // the physical quantities for which we perform upwinding auto upwindTerm = [](const auto& volVars) - { return volVars.density(wPhaseIdx)*volVars.mobility(wPhaseIdx); }; + { return volVars.density(liquidPhaseIdx)*volVars.mobility(liquidPhaseIdx); }; - flux[conti0EqIdx] = fluxVars.advectiveFlux(wPhaseIdx, upwindTerm); + flux[conti0EqIdx] = fluxVars.advectiveFlux(liquidPhaseIdx, upwindTerm); // for extended Richards we consider water vapor diffusion in air if (enableWaterDiffusionInAir) - flux[conti0EqIdx] += fluxVars.molecularDiffusionFlux(nPhaseIdx)[wCompIdx]*FluidSystem::molarMass(wCompIdx); + flux[conti0EqIdx] += fluxVars.molecularDiffusionFlux(gasPhaseIdx)[liquidCompIdx]*FluidSystem::molarMass(liquidCompIdx); //! Add advective phase energy fluxes for the water phase only. For isothermal model the contribution is zero. - EnergyLocalResidual::heatConvectionFlux(flux, fluxVars, wPhaseIdx); + EnergyLocalResidual::heatConvectionFlux(flux, fluxVars, liquidPhaseIdx); //! Add diffusive energy fluxes. For isothermal model the contribution is zero. //! The effective lambda is averaged over both fluid phases and the solid phase diff --git a/dumux/porousmediumflow/richards/model.hh b/dumux/porousmediumflow/richards/model.hh index 9c571d00a591af6b7705ca6ead73824e749031bf..d8bed2a2264be6f9d20cab21da7859b2bc60b9a2 100644 --- a/dumux/porousmediumflow/richards/model.hh +++ b/dumux/porousmediumflow/richards/model.hh @@ -233,7 +233,7 @@ public: }; //! The primary variable switch for the richards model -SET_TYPE_PROP(Richards, PrimaryVariableSwitch, ExtendedRichardsPrimaryVariableSwitch<TypeTag>); +SET_TYPE_PROP(Richards, PrimaryVariableSwitch, ExtendedRichardsPrimaryVariableSwitch); //! The primary variable switch for the richards model // SET_BOOL_PROP(Richards, ProblemUsePrimaryVariableSwitch, false); diff --git a/dumux/porousmediumflow/richards/primaryvariableswitch.hh b/dumux/porousmediumflow/richards/primaryvariableswitch.hh index 9546cfcd6560562cb58dcedb56743b52039fa54a..5c07d13a1a428422533b5722b6d8d4f80d14c4dd 100644 --- a/dumux/porousmediumflow/richards/primaryvariableswitch.hh +++ b/dumux/porousmediumflow/richards/primaryvariableswitch.hh @@ -36,81 +36,50 @@ namespace Dumux { * \ingroup RichardsModel * \brief The primary variable switch controlling the phase presence state variable. */ -template<class TypeTag> class ExtendedRichardsPrimaryVariableSwitch -: public PrimaryVariableSwitch<ExtendedRichardsPrimaryVariableSwitch<TypeTag>> +: public PrimaryVariableSwitch<ExtendedRichardsPrimaryVariableSwitch> { - using ParentType = PrimaryVariableSwitch<ExtendedRichardsPrimaryVariableSwitch<TypeTag>>; + using ParentType = PrimaryVariableSwitch<ExtendedRichardsPrimaryVariableSwitch>; friend ParentType; - using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - using GridView = typename GET_PROP_TYPE(TypeTag, GridView); - using IndexType = typename GridView::IndexSet::IndexType; - using GlobalPosition = Dune::FieldVector<Scalar, GridView::dimensionworld>; - - using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); - using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables); - using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); - using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; - - enum { - switchIdx = Indices::switchIdx, - - wPhaseIdx = Indices::wPhaseIdx, - nPhaseIdx = Indices::nPhaseIdx, - - wCompIdx = FluidSystem::wCompIdx, - - wPhaseOnly = Indices::wPhaseOnly, - nPhaseOnly = Indices::nPhaseOnly, - bothPhases = Indices::bothPhases - }; - - static constexpr bool useMoles = GET_PROP_VALUE(TypeTag, UseMoles); - - static constexpr bool enableWaterDiffusionInAir - = GET_PROP_VALUE(TypeTag, EnableWaterDiffusionInAir); - static constexpr bool useKelvinVaporPressure - = GET_PROP_VALUE(TypeTag, UseKelvinEquation); - public: using ParentType::ParentType; protected: // perform variable switch at a degree of freedom location - bool update_(PrimaryVariables& priVars, + template<class VolumeVariables, class GlobalPosition> + bool update_(typename VolumeVariables::PrimaryVariables& priVars, const VolumeVariables& volVars, - IndexType dofIdxGlobal, + std::size_t dofIdxGlobal, const GlobalPosition& globalPos) { - static const bool usePriVarSwitch = getParamFromGroup<bool>(GET_PROP_VALUE(TypeTag, ModelParameterGroup), "Problem.UsePrimaryVariableSwitch"); + using Scalar = typename VolumeVariables::PrimaryVariables::value_type; + using Indices = typename VolumeVariables::Indices; + using FluidSystem = typename VolumeVariables::FluidSystem; + + static const bool usePriVarSwitch = getParam<bool>("Problem.UsePrimaryVariableSwitch"); if (!usePriVarSwitch) return false; - if (!enableWaterDiffusionInAir) + if (!VolumeVariables::enableWaterDiffusionInAir()) DUNE_THROW(Dune::InvalidStateException, "The Richards primary variable switch only works with water diffusion in air enabled!"); + static constexpr int liquidCompIdx = FluidSystem::liquidPhaseIdx; + // evaluate primary variable switch bool wouldSwitch = false; int phasePresence = priVars.state(); int newPhasePresence = phasePresence; // check if a primary var switch is necessary - if (phasePresence == nPhaseOnly) + if (phasePresence == Indices::gasPhaseOnly) { // if the mole fraction of water is larger than the one // predicted by a liquid-vapor equilibrium - Scalar xnw = volVars.moleFraction(nPhaseIdx, wCompIdx); + Scalar xnw = volVars.moleFraction(FluidSystem::gasPhaseIdx, liquidCompIdx); Scalar xnwPredicted = FluidSystem::H2O::vaporPressure(volVars.temperature()) - / volVars.pressure(nPhaseIdx); - if (useKelvinVaporPressure) - { - using std::exp; - xnwPredicted *= exp(-volVars.capillaryPressure() - * FluidSystem::H2O::molarMass() / volVars.density(wPhaseIdx) - / Constants<Scalar>::R / volVars.temperature()); - } + / volVars.pressure(FluidSystem::gasPhaseIdx); Scalar xwMax = 1.0; if (xnw / xnwPredicted > xwMax) @@ -126,31 +95,31 @@ protected: std::cout << "wetting phase appears at vertex " << dofIdxGlobal << ", coordinates: " << globalPos << ", xnw / xnwPredicted * 100: " << xnw / xnwPredicted * 100 << "%" - << ", at x_n^w: " << priVars[switchIdx] << std::endl; - newPhasePresence = bothPhases; - priVars[switchIdx] = 0.0; + << ", at x_n^w: " << priVars[Indices::switchIdx] << std::endl; + newPhasePresence = Indices::bothPhases; + priVars[Indices::switchIdx] = 0.0; } } - else if (phasePresence == bothPhases) + else if (phasePresence == Indices::bothPhases) { Scalar Smin = 0.0; if (this->wasSwitched_[dofIdxGlobal]) Smin = -0.01; - if (volVars.saturation(wPhaseIdx) <= Smin) + if (volVars.saturation(FluidSystem::liquidPhaseIdx) <= Smin) { wouldSwitch = true; // wetting phase disappears - newPhasePresence = nPhaseOnly; - priVars[switchIdx] = volVars.moleFraction(nPhaseIdx, wCompIdx); + newPhasePresence = Indices::gasPhaseOnly; + priVars[Indices::switchIdx] = volVars.moleFraction(FluidSystem::gasPhaseIdx, liquidCompIdx); std::cout << "Wetting phase disappears at vertex " << dofIdxGlobal << ", coordinates: " << globalPos << ", sw: " - << volVars.saturation(wPhaseIdx) - << ", x_n^w: " << priVars[switchIdx] << std::endl; + << volVars.saturation(FluidSystem::liquidPhaseIdx) + << ", x_n^w: " << priVars[Indices::switchIdx] << std::endl; } } - else if (phasePresence == wPhaseOnly) + else if (phasePresence == Indices::liquidPhaseOnly) { DUNE_THROW(Dune::NotImplemented, "Water phase only phase presence!"); } diff --git a/dumux/porousmediumflow/richards/volumevariables.hh b/dumux/porousmediumflow/richards/volumevariables.hh index d1bca0b3038136184adf9e0b6c87a9f78eb300b1..8f2169eefd1cbefb333549f33b04d2ffea986af5 100644 --- a/dumux/porousmediumflow/richards/volumevariables.hh +++ b/dumux/porousmediumflow/richards/volumevariables.hh @@ -49,35 +49,16 @@ class RichardsVolumeVariables using Scalar = typename Traits::PrimaryVariables::value_type; using PermeabilityType = typename Traits::PermeabilityType; using ModelTraits = typename Traits::ModelTraits; - using Indices = typename ModelTraits::Indices; - using FS = typename Traits::FluidSystem; - - enum{ - pressureIdx = Indices::pressureIdx, - switchIdx = Indices::switchIdx, - wPhaseIdx = FS::wPhaseIdx, - nPhaseIdx = FS::nPhaseIdx, - wCompIdx = FS::wCompIdx, - nCompIdx = FS::nCompIdx - }; - - // present phases - enum - { - wPhaseOnly = Indices::wPhaseOnly, - nPhaseOnly = Indices::nPhaseOnly, - bothPhases = Indices::bothPhases - }; - - static constexpr bool enableWaterDiffusionInAir = ModelTraits::enableMolecularDiffusion(); - static constexpr bool useKelvinVaporPressure = ModelTraits::useKelvinVaporPressure(); - static constexpr int numPhases = ModelTraits::numPhases(); public: //! export type of the fluid system using FluidSystem = typename Traits::FluidSystem; //! export type of the fluid state using FluidState = typename Traits::FluidState; + //! export type of the fluid state + using Indices = typename Traits::ModelTraits::Indices; + //! if water diffusion in air is enabled + static constexpr bool enableWaterDiffusionInAir() { return ModelTraits::enableMolecularDiffusion(); }; /*! * \brief Update all quantities for a given control volume @@ -94,7 +75,8 @@ public: const Element &element, const Scv& scv) { - static_assert(!(!enableWaterDiffusionInAir && useKelvinVaporPressure), + // TODO check this is the fluid system now + static_assert(!(!enableWaterDiffusionInAir() && ModelTraits::useKelvinVaporPressure()), "Kevin vapor presssure only makes sense if water in air is considered!"); ParentType::update(elemSol, problem, element, scv); @@ -107,13 +89,13 @@ public: using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; minPc_ = MaterialLaw::endPointPc(materialParams); - if (phasePresence == nPhaseOnly) + if (phasePresence == Indices::gasPhaseOnly) { - moleFraction_[wPhaseIdx] = 1.0; - moleFraction_[nPhaseIdx] = priVars[switchIdx]; + moleFraction_[FluidSystem::liquidPhaseIdx] = 1.0; + moleFraction_[FluidSystem::gasPhaseIdx] = priVars[Indices::switchIdx]; - fluidState_.setSaturation(wPhaseIdx, 0.0); - fluidState_.setSaturation(nPhaseIdx, 1.0); + fluidState_.setSaturation(FluidSystem::liquidPhaseIdx, 0.0); + fluidState_.setSaturation(FluidSystem::gasPhaseIdx, 1.0); Scalar t = ParentType::temperature(elemSol, problem, element, scv); fluidState_.setTemperature(t); @@ -122,51 +104,45 @@ public: const Scalar pc = MaterialLaw::pc(materialParams, 0.0); // set the wetting pressure - fluidState_.setPressure(wPhaseIdx, problem.nonWettingReferencePressure() - pc); - fluidState_.setPressure(nPhaseIdx, problem.nonWettingReferencePressure()); + fluidState_.setPressure(FluidSystem::liquidPhaseIdx, problem.nonWettingReferencePressure() - pc); + fluidState_.setPressure(FluidSystem::gasPhaseIdx, problem.nonWettingReferencePressure()); // set molar densities - molarDensity_[wPhaseIdx] = FluidSystem::H2O::liquidDensity(temperature(), pressure(wPhaseIdx))/FluidSystem::H2O::molarMass(); - molarDensity_[nPhaseIdx] = IdealGas<Scalar>::molarDensity(temperature(), problem.nonWettingReferencePressure()); + molarDensity_[FluidSystem::liquidPhaseIdx] = FluidSystem::H2O::liquidDensity(temperature(), pressure(FluidSystem::liquidPhaseIdx))/FluidSystem::H2O::molarMass(); + molarDensity_[FluidSystem::gasPhaseIdx] = IdealGas<Scalar>::molarDensity(temperature(), problem.nonWettingReferencePressure()); // density and viscosity typename FluidSystem::ParameterCache paramCache; paramCache.updateAll(fluidState_); - fluidState_.setDensity(wPhaseIdx, FluidSystem::density(fluidState_, paramCache, wPhaseIdx)); - fluidState_.setDensity(nPhaseIdx, FluidSystem::density(fluidState_, paramCache, nPhaseIdx)); - fluidState_.setViscosity(wPhaseIdx, FluidSystem::viscosity(fluidState_, paramCache, wPhaseIdx)); + fluidState_.setDensity(FluidSystem::liquidPhaseIdx, FluidSystem::density(fluidState_, paramCache, FluidSystem::liquidPhaseIdx)); + fluidState_.setDensity(FluidSystem::gasPhaseIdx, FluidSystem::density(fluidState_, paramCache, FluidSystem::gasPhaseIdx)); + fluidState_.setViscosity(FluidSystem::liquidPhaseIdx, FluidSystem::viscosity(fluidState_, paramCache, FluidSystem::liquidPhaseIdx)); // compute and set the enthalpy - fluidState_.setEnthalpy(wPhaseIdx, ParentType::enthalpy(fluidState_, paramCache, wPhaseIdx)); - fluidState_.setEnthalpy(nPhaseIdx, ParentType::enthalpy(fluidState_, paramCache, nPhaseIdx)); + fluidState_.setEnthalpy(FluidSystem::liquidPhaseIdx, ParentType::enthalpy(fluidState_, paramCache, FluidSystem::liquidPhaseIdx)); + fluidState_.setEnthalpy(FluidSystem::gasPhaseIdx, ParentType::enthalpy(fluidState_, paramCache, FluidSystem::gasPhaseIdx)); } - else if (phasePresence == bothPhases) + else if (phasePresence == Indices::bothPhases) { completeFluidState(elemSol, problem, element, scv, fluidState_); // if we want to account for diffusion in the air phase // use Raoult to compute the water mole fraction in air - if (enableWaterDiffusionInAir) + if (enableWaterDiffusionInAir()) { - molarDensity_[wPhaseIdx] = FluidSystem::H2O::liquidDensity(temperature(), pressure(wPhaseIdx))/FluidSystem::H2O::molarMass(); - molarDensity_[nPhaseIdx] = IdealGas<Scalar>::molarDensity(temperature(), problem.nonWettingReferencePressure()); - moleFraction_[wPhaseIdx] = 1.0; - - moleFraction_[nPhaseIdx] = FluidSystem::H2O::vaporPressure(temperature()) / problem.nonWettingReferencePressure(); - if (useKelvinVaporPressure) - { - using std::exp; - moleFraction_[nPhaseIdx] *= exp(-capillaryPressure() * FluidSystem::H2O::molarMass()/density(wPhaseIdx) - / Constants<Scalar>::R / temperature()); - } + molarDensity_[FluidSystem::liquidPhaseIdx] = FluidSystem::H2O::liquidDensity(temperature(), pressure(FluidSystem::liquidPhaseIdx))/FluidSystem::H2O::molarMass(); + molarDensity_[FluidSystem::gasPhaseIdx] = IdealGas<Scalar>::molarDensity(temperature(), problem.nonWettingReferencePressure()); + moleFraction_[FluidSystem::liquidPhaseIdx] = 1.0; + + moleFraction_[FluidSystem::gasPhaseIdx] = FluidSystem::H2O::vaporPressure(temperature()) / problem.nonWettingReferencePressure(); // binary diffusion coefficients typename FluidSystem::ParameterCache paramCache; paramCache.updateAll(fluidState_); - diffCoeff_ = FluidSystem::binaryDiffusionCoefficient(fluidState_, paramCache, nPhaseIdx, wCompIdx, nCompIdx); + diffCoeff_ = FluidSystem::binaryDiffusionCoefficient(fluidState_, paramCache, FluidSystem::gasPhaseIdx, FluidSystem::comp0Idx, FluidSystem::comp1Idx); } } - else if (phasePresence == wPhaseOnly) + else if (phasePresence == Indices::liquidPhaseOnly) { completeFluidState(elemSol, problem, element, scv, fluidState_); } @@ -174,7 +150,7 @@ public: ////////// // specify the other parameters ////////// - relativePermeabilityWetting_ = MaterialLaw::krw(materialParams, fluidState_.saturation(wPhaseIdx)); + relativePermeabilityWetting_ = MaterialLaw::krw(materialParams, fluidState_.saturation(FluidSystem::liquidPhaseIdx)); porosity_ = problem.spatialParams().porosity(element, scv, elemSol); permeability_ = problem.spatialParams().permeability(element, scv, elemSol); } @@ -209,29 +185,29 @@ public: using std::max; using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; Scalar minPc = MaterialLaw::pc(materialParams, 1.0); - fluidState.setPressure(wPhaseIdx, priVars[pressureIdx]); - fluidState.setPressure(nPhaseIdx, max(problem.nonWettingReferencePressure(), fluidState.pressure(wPhaseIdx) + minPc)); + fluidState.setPressure(FluidSystem::liquidPhaseIdx, priVars[Indices::pressureIdx]); + fluidState.setPressure(FluidSystem::gasPhaseIdx, max(problem.nonWettingReferencePressure(), fluidState.pressure(FluidSystem::liquidPhaseIdx) + minPc)); // compute the capillary pressure to compute the saturation // make sure that we the capillary pressure is not smaller than the minimum pc // this would possibly return unphysical values from regularized material laws using std::max; const Scalar pc = max(MaterialLaw::endPointPc(materialParams), - problem.nonWettingReferencePressure() - fluidState.pressure(wPhaseIdx)); + problem.nonWettingReferencePressure() - fluidState.pressure(FluidSystem::liquidPhaseIdx)); const Scalar sw = MaterialLaw::sw(materialParams, pc); - fluidState.setSaturation(wPhaseIdx, sw); - fluidState.setSaturation(nPhaseIdx, 1.0-sw); + fluidState.setSaturation(FluidSystem::liquidPhaseIdx, sw); + fluidState.setSaturation(FluidSystem::gasPhaseIdx, 1.0-sw); // density and viscosity typename FluidSystem::ParameterCache paramCache; paramCache.updateAll(fluidState); - fluidState.setDensity(wPhaseIdx, FluidSystem::density(fluidState, paramCache, wPhaseIdx)); - fluidState.setDensity(nPhaseIdx, FluidSystem::density(fluidState, paramCache, nPhaseIdx)); - fluidState.setViscosity(wPhaseIdx, FluidSystem::viscosity(fluidState, paramCache, wPhaseIdx)); + fluidState.setDensity(FluidSystem::liquidPhaseIdx, FluidSystem::density(fluidState, paramCache, FluidSystem::liquidPhaseIdx)); + fluidState.setDensity(FluidSystem::gasPhaseIdx, FluidSystem::density(fluidState, paramCache, FluidSystem::gasPhaseIdx)); + fluidState.setViscosity(FluidSystem::liquidPhaseIdx, FluidSystem::viscosity(fluidState, paramCache, FluidSystem::liquidPhaseIdx)); // compute and set the enthalpy - fluidState.setEnthalpy(wPhaseIdx, ParentType::enthalpy(fluidState, paramCache, wPhaseIdx)); - fluidState.setEnthalpy(nPhaseIdx, ParentType::enthalpy(fluidState, paramCache, nPhaseIdx)); + fluidState.setEnthalpy(FluidSystem::liquidPhaseIdx, ParentType::enthalpy(fluidState, paramCache, FluidSystem::liquidPhaseIdx)); + fluidState.setEnthalpy(FluidSystem::gasPhaseIdx, ParentType::enthalpy(fluidState, paramCache, FluidSystem::gasPhaseIdx)); } /*! @@ -272,7 +248,7 @@ public: * * \param phaseIdx The index of the fluid phase */ - Scalar saturation(const int phaseIdx = wPhaseIdx) const + Scalar saturation(const int phaseIdx = FluidSystem::liquidPhaseIdx) const { return fluidState_.saturation(phaseIdx); } /*! @@ -281,7 +257,7 @@ public: * * \param phaseIdx The index of the fluid phase */ - Scalar density(const int phaseIdx = wPhaseIdx) const + Scalar density(const int phaseIdx = FluidSystem::liquidPhaseIdx) const { return fluidState_.density(phaseIdx); } /*! @@ -295,7 +271,7 @@ public: * * \param phaseIdx The index of the fluid phase */ - Scalar pressure(const int phaseIdx = wPhaseIdx) const + Scalar pressure(const int phaseIdx = FluidSystem::liquidPhaseIdx) const { return fluidState_.pressure(phaseIdx); } /*! @@ -309,7 +285,7 @@ public: * * \param phaseIdx The index of the fluid phase */ - Scalar mobility(const int phaseIdx = wPhaseIdx) const + Scalar mobility(const int phaseIdx = FluidSystem::liquidPhaseIdx) const { return relativePermeability(phaseIdx)/fluidState_.viscosity(phaseIdx); } /*! @@ -319,8 +295,8 @@ public: * \param phaseIdx The index of the fluid phase * \note The non-wetting phase is infinitely mobile */ - Scalar viscosity(const int phaseIdx = wPhaseIdx) const - { return phaseIdx == wPhaseIdx ? fluidState_.viscosity(wPhaseIdx) : 0.0; } + Scalar viscosity(const int phaseIdx = FluidSystem::liquidPhaseIdx) const + { return phaseIdx == FluidSystem::liquidPhaseIdx ? fluidState_.viscosity(FluidSystem::liquidPhaseIdx) : 0.0; } /*! * \brief Returns relative permeability [-] of a given phase within @@ -328,8 +304,8 @@ public: * * \param phaseIdx The index of the fluid phase */ - Scalar relativePermeability(const int phaseIdx = wPhaseIdx) const - { return phaseIdx == wPhaseIdx ? relativePermeabilityWetting_ : 1.0; } + Scalar relativePermeability(const int phaseIdx = FluidSystem::liquidPhaseIdx) const + { return phaseIdx == FluidSystem::liquidPhaseIdx ? relativePermeabilityWetting_ : 1.0; } /*! * \brief Returns the effective capillary pressure \f$\mathrm{[Pa]}\f$ within the @@ -345,7 +321,7 @@ public: Scalar capillaryPressure() const { using std::max; - return max(minPc_, pressure(nPhaseIdx) - pressure(wPhaseIdx)); + return max(minPc_, pressure(FluidSystem::gasPhaseIdx) - pressure(FluidSystem::liquidPhaseIdx)); } /*! @@ -362,8 +338,8 @@ public: * manually do a conversion. It is not correct if the density is not constant * or the gravity different */ - Scalar pressureHead(const int phaseIdx = wPhaseIdx) const - { return 100.0 *(pressure(phaseIdx) - pressure(nPhaseIdx))/density(phaseIdx)/9.81; } + Scalar pressureHead(const int phaseIdx = FluidSystem::liquidPhaseIdx) const + { return 100.0 *(pressure(phaseIdx) - pressure(FluidSystem::gasPhaseIdx))/density(phaseIdx)/9.81; } /*! * \brief Returns the water content @@ -376,7 +352,7 @@ public: * \note this function is here as a convenience to the user to not have to * manually do a conversion. */ - Scalar waterContent(const int phaseIdx = wPhaseIdx) const + Scalar waterContent(const int phaseIdx = FluidSystem::liquidPhaseIdx) const { return saturation(phaseIdx) * porosity_; } /*! @@ -388,8 +364,8 @@ public: */ Scalar moleFraction(const int phaseIdx, const int compIdx) const { - assert(enableWaterDiffusionInAir); - if (compIdx != wCompIdx) + assert(enableWaterDiffusionInAir()); + if (compIdx != FluidSystem::comp0Idx) DUNE_THROW(Dune::InvalidStateException, "There is only one component for Richards!"); return moleFraction_[phaseIdx]; } @@ -402,7 +378,7 @@ public: */ Scalar molarDensity(const int phaseIdx) const { - assert(enableWaterDiffusionInAir); + assert(enableWaterDiffusionInAir()); return molarDensity_[phaseIdx]; } @@ -414,7 +390,7 @@ public: */ Scalar diffusionCoefficient(int phaseIdx, int compIdx) const { - assert(enableWaterDiffusionInAir && phaseIdx == nPhaseIdx && compIdx == wCompIdx); + assert(enableWaterDiffusionInAir() && phaseIdx == FluidSystem::gasPhaseIdx && compIdx == FluidSystem::comp0Idx); return diffCoeff_; } @@ -424,8 +400,8 @@ protected: Scalar porosity_; //!< the porosity PermeabilityType permeability_; //!< the instrinsic permeability Scalar minPc_; //!< the minimum capillary pressure (entry pressure) - Scalar moleFraction_[numPhases]; //!< The water mole fractions in water and air - Scalar molarDensity_[numPhases]; //!< The molar density of water and air + Scalar moleFraction_[ParentType::numPhases()]; //!< The water mole fractions in water and air + Scalar molarDensity_[ParentType::numPhases()]; //!< The molar density of water and air Scalar diffCoeff_; //!< The binary diffusion coefficient of water in air }; diff --git a/dumux/porousmediumflow/richards/vtkoutputfields.hh b/dumux/porousmediumflow/richards/vtkoutputfields.hh index e1da0d0b8e68dffeabc8a86438ae6243450ebfa8..baf1139d791672d174141a6ab3f14a535097c88f 100644 --- a/dumux/porousmediumflow/richards/vtkoutputfields.hh +++ b/dumux/porousmediumflow/richards/vtkoutputfields.hh @@ -41,23 +41,23 @@ public: { using FluidSystem = typename VtkOutputModule::VolumeVariables::FluidSystem; - vtk.addVolumeVariable([](const auto& v){ return v.saturation(FluidSystem::wPhaseIdx); }, "Sw"); - vtk.addVolumeVariable([](const auto& v){ return v.saturation(FluidSystem::nPhaseIdx); }, "Sn"); - vtk.addVolumeVariable([](const auto& v){ return v.pressure(FluidSystem::wPhaseIdx); }, "pw"); - vtk.addVolumeVariable([](const auto& v){ return v.pressure(FluidSystem::nPhaseIdx); }, "pn"); + vtk.addVolumeVariable([](const auto& v){ return v.saturation(FluidSystem::liquidPhaseIdx); }, "Sw"); + vtk.addVolumeVariable([](const auto& v){ return v.saturation(FluidSystem::gasPhaseIdx); }, "Sn"); + vtk.addVolumeVariable([](const auto& v){ return v.pressure(FluidSystem::liquidPhaseIdx); }, "pw"); + vtk.addVolumeVariable([](const auto& v){ return v.pressure(FluidSystem::gasPhaseIdx); }, "pn"); vtk.addVolumeVariable([](const auto& v){ return v.capillaryPressure(); }, "pc"); - vtk.addVolumeVariable([](const auto& v){ return v.density(FluidSystem::wPhaseIdx); }, "density"); - vtk.addVolumeVariable([](const auto& v){ return v.mobility(FluidSystem::wPhaseIdx); }, "mobility"); - vtk.addVolumeVariable([](const auto& v){ return v.relativePermeability(FluidSystem::wPhaseIdx); }, "kr"); + vtk.addVolumeVariable([](const auto& v){ return v.density(FluidSystem::liquidPhaseIdx); }, "density"); + vtk.addVolumeVariable([](const auto& v){ return v.mobility(FluidSystem::liquidPhaseIdx); }, "mobility"); + vtk.addVolumeVariable([](const auto& v){ return v.relativePermeability(FluidSystem::liquidPhaseIdx); }, "kr"); vtk.addVolumeVariable([](const auto& v){ return v.porosity(); }, "porosity"); static const bool gravity = getParamFromGroup<bool>(vtk.paramGroup(), "Problem.EnableGravity"); if(gravity) - vtk.addVolumeVariable([](const auto& v){ return v.pressureHead(FluidSystem::wPhaseIdx); }, "pressure head"); + vtk.addVolumeVariable([](const auto& v){ return v.pressureHead(FluidSystem::liquidPhaseIdx); }, "pressure head"); if (enableWaterDiffusionInAir) vtk.addVolumeVariable([](const auto& v){ return v.moleFraction(1, 0); }, "x^w_air"); - vtk.addVolumeVariable([](const auto& v){ return v.waterContent(FluidSystem::wPhaseIdx); },"water content"); + vtk.addVolumeVariable([](const auto& v){ return v.waterContent(FluidSystem::liquidPhaseIdx); },"water content"); vtk.addVolumeVariable([](const auto& v){ return v.priVars().state(); }, "phasePresence"); } diff --git a/dumux/porousmediumflow/richardsnc/indices.hh b/dumux/porousmediumflow/richardsnc/indices.hh index 81ca17fb237a494db9f07ed02b3fa22ff8ffa21d..2cf18ab8cd88bb2aaaa90d577a8e8d4cb6a947d3 100644 --- a/dumux/porousmediumflow/richardsnc/indices.hh +++ b/dumux/porousmediumflow/richardsnc/indices.hh @@ -31,20 +31,25 @@ namespace Dumux { /*! * \ingroup RichardsNCModel * \brief The indices for the isothermal Richards, n-component model. + * \tparam fluidSystemPhaseIdx The index of the fluid phase in the fluid system */ +template<int phaseIdx> struct RichardsNCIndices { //! Component indices - static const int compMainIdx = 0; //!< main component index + static constexpr int compMainIdx = 0; //!< main component index //! primary variable indices - static const int pressureIdx = 0; //!< pressure + static constexpr int pressureIdx = 0; //!< pressure + + //! the index of the fluid phase in the fluid system + static constexpr int fluidSystemPhaseIdx = phaseIdx; //! \note These indices make sense if the first balance is replaced by the //! total mass balance. //! Equation indices - static const int conti0EqIdx = 0; //!< continuity equation index + static constexpr int conti0EqIdx = 0; //!< continuity equation index }; } // end namespace Dumux diff --git a/dumux/porousmediumflow/richardsnc/model.hh b/dumux/porousmediumflow/richardsnc/model.hh index d2e6e0ca41f1a4301b6376f31eef82e12514c0e4..9b0074b149adfffd29c9b33d6e2a15486ac27520 100644 --- a/dumux/porousmediumflow/richardsnc/model.hh +++ b/dumux/porousmediumflow/richardsnc/model.hh @@ -98,11 +98,12 @@ namespace Dumux { * * \tparam nComp the number of components to be considered. * \tparam useMol whether to use mass or mole balances + * \tparam fluidSystemPhaseIdx The index of the fluid phase in the fluid system */ -template<int nComp, bool useMol> +template<int nComp, bool useMol, int fluidSystemPhaseIdx> struct RichardsNCModelTraits { - using Indices = RichardsNCIndices; + using Indices = RichardsNCIndices<fluidSystemPhaseIdx>; static constexpr int numEq() { return nComp; } static constexpr int numPhases() { return 1; } @@ -137,9 +138,12 @@ SET_PROP(RichardsNC, ModelTraits) private: using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); public: - using type = RichardsNCModelTraits<FluidSystem::numComponents, GET_PROP_VALUE(TypeTag, UseMoles)>; + using type = RichardsNCModelTraits<FluidSystem::numComponents, GET_PROP_VALUE(TypeTag, UseMoles), GET_PROP_VALUE(TypeTag, PhaseIdx)>; }; + //! The default phase index to access the fluid system +SET_INT_PROP(RichardsNC, PhaseIdx, 0); + //! Define that per default mole fractions are used in the balance equations SET_BOOL_PROP(RichardsNC, UseMoles, true); @@ -215,7 +219,7 @@ SET_PROP(RichardsNCNI, ModelTraits) { private: using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); - using IsothermalTraits = RichardsNCModelTraits<FluidSystem::numComponents, GET_PROP_VALUE(TypeTag, UseMoles)>; + using IsothermalTraits = RichardsNCModelTraits<FluidSystem::numComponents, GET_PROP_VALUE(TypeTag, UseMoles), GET_PROP_VALUE(TypeTag, PhaseIdx)>; public: using type = PorousMediumFlowNIModelTraits<IsothermalTraits>; }; diff --git a/dumux/porousmediumflow/richardsnc/volumevariables.hh b/dumux/porousmediumflow/richardsnc/volumevariables.hh index 2a388adefdbc13ff8bdc74163c06db62a042a38c..e3c05f0ce28f44a2456c7f129d0f8112f3ee3b45 100644 --- a/dumux/porousmediumflow/richardsnc/volumevariables.hh +++ b/dumux/porousmediumflow/richardsnc/volumevariables.hh @@ -41,22 +41,21 @@ class RichardsNCVolumeVariables using ParentType = PorousMediumFlowVolumeVariables<Traits, RichardsNCVolumeVariables<Traits>>; using Scalar = typename Traits::PrimaryVariables::value_type; using PermeabilityType = typename Traits::PermeabilityType; - using Indices = typename Traits::ModelTraits::Indices; - enum { pressureIdx = Indices::pressureIdx }; + using Idx = typename Traits::ModelTraits::Indices; + static constexpr int fluidSystemPhaseIdx = Idx::fluidSystemPhaseIdx; static constexpr bool useMoles = Traits::ModelTraits::useMoles(); - static constexpr int numComponents = Traits::ModelTraits::numComponents(); public: //! export type of the fluid system using FluidSystem = typename Traits::FluidSystem; //! export type of the fluid state using FluidState = typename Traits::FluidState; - //! export phase access - enum { - wPhaseIdx = FluidSystem::wPhaseIdx, - nPhaseIdx = 1 - FluidSystem::wPhaseIdx - }; + //! export indices + using Indices = typename Traits::ModelTraits::Indices; + //! export phase acess indices + static constexpr int liquidPhaseIdx = fluidSystemPhaseIdx; + static constexpr int gasPhaseIdx = 1 - liquidPhaseIdx; /*! * \brief Update all quantities for a given control volume @@ -81,7 +80,7 @@ public: ////////// using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol); - relativePermeabilityWetting_ = MaterialLaw::krw(materialParams, fluidState_.saturation(FluidSystem::wPhaseIdx)); + relativePermeabilityWetting_ = MaterialLaw::krw(materialParams, fluidState_.saturation(fluidSystemPhaseIdx)); // precompute the minimum capillary pressure (entry pressure) // needed to make sure we don't compute unphysical capillary pressures and thus saturations @@ -94,15 +93,15 @@ public: // Could be avoided if diffusion coefficients also // became part of the fluid state. typename FluidSystem::ParameterCache paramCache; - paramCache.updatePhase(fluidState_, FluidSystem::wPhaseIdx); + paramCache.updatePhase(fluidState_, fluidSystemPhaseIdx); - const int compIIdx = FluidSystem::wPhaseIdx; - for (unsigned int compJIdx = 0; compJIdx < numComponents; ++compJIdx) + const int compIIdx = fluidSystemPhaseIdx; + for (unsigned int compJIdx = 0; compJIdx < ParentType::numComponents(); ++compJIdx) if(compIIdx != compJIdx) setDiffusionCoefficient_(compJIdx, FluidSystem::binaryDiffusionCoefficient(fluidState_, paramCache, - FluidSystem::wPhaseIdx, + fluidSystemPhaseIdx, compIIdx, compJIdx)); } @@ -134,7 +133,7 @@ public: const auto& priVars = ParentType::extractDofPriVars(elemSol, scv); // set the wetting pressure - fluidState.setPressure(FluidSystem::wPhaseIdx, priVars[pressureIdx]); + fluidState.setPressure(fluidSystemPhaseIdx, priVars[Indices::pressureIdx]); // compute the capillary pressure to compute the saturation // make sure that we the capillary pressure is not smaller than the minimum pc @@ -142,35 +141,35 @@ public: using std::max; using MaterialLaw = typename Problem::SpatialParams::MaterialLaw; const Scalar pc = max(MaterialLaw::endPointPc(materialParams), - problem.nonWettingReferencePressure() - fluidState.pressure(FluidSystem::wPhaseIdx)); + problem.nonWettingReferencePressure() - fluidState.pressure(fluidSystemPhaseIdx)); const Scalar sw = MaterialLaw::sw(materialParams, pc); - fluidState.setSaturation(FluidSystem::wPhaseIdx, sw); + fluidState.setSaturation(fluidSystemPhaseIdx, sw); // set the mole/mass fractions if(useMoles) { Scalar sumSecondaryFractions = 0.0; - for (int compIdx = 1; compIdx < numComponents; ++compIdx) + for (int compIdx = 1; compIdx < ParentType::numComponents(); ++compIdx) { - fluidState.setMoleFraction(FluidSystem::wPhaseIdx, compIdx, priVars[compIdx]); + fluidState.setMoleFraction(fluidSystemPhaseIdx, compIdx, priVars[compIdx]); sumSecondaryFractions += priVars[compIdx]; } - fluidState.setMoleFraction(FluidSystem::wPhaseIdx, 0, 1.0 - sumSecondaryFractions); + fluidState.setMoleFraction(fluidSystemPhaseIdx, 0, 1.0 - sumSecondaryFractions); } else { - for (int compIdx = 1; compIdx < numComponents; ++compIdx) - fluidState.setMassFraction(FluidSystem::wPhaseIdx, compIdx, priVars[compIdx]); + for (int compIdx = 1; compIdx < ParentType::numComponents(); ++compIdx) + fluidState.setMassFraction(fluidSystemPhaseIdx, compIdx, priVars[compIdx]); } // density and viscosity typename FluidSystem::ParameterCache paramCache; paramCache.updateAll(fluidState); - fluidState.setDensity(FluidSystem::wPhaseIdx, FluidSystem::density(fluidState, paramCache, FluidSystem::wPhaseIdx)); - fluidState.setViscosity(FluidSystem::wPhaseIdx, FluidSystem::viscosity(fluidState, paramCache, FluidSystem::wPhaseIdx)); + fluidState.setDensity(fluidSystemPhaseIdx, FluidSystem::density(fluidState, paramCache, fluidSystemPhaseIdx)); + fluidState.setViscosity(fluidSystemPhaseIdx, FluidSystem::viscosity(fluidState, paramCache, fluidSystemPhaseIdx)); // compute and set the enthalpy - fluidState.setEnthalpy(FluidSystem::wPhaseIdx, ParentType::enthalpy(fluidState, paramCache, FluidSystem::wPhaseIdx)); + fluidState.setEnthalpy(fluidSystemPhaseIdx, ParentType::enthalpy(fluidState, paramCache, fluidSystemPhaseIdx)); } /*! @@ -211,8 +210,8 @@ public: * * \param phaseIdx The index of the fluid phase */ - Scalar saturation(const int phaseIdx = FluidSystem::wPhaseIdx) const - { return phaseIdx == FluidSystem::wPhaseIdx ? fluidState_.saturation(FluidSystem::wPhaseIdx) : 1.0-fluidState_.saturation(FluidSystem::wPhaseIdx); } + Scalar saturation(const int phaseIdx = fluidSystemPhaseIdx) const + { return phaseIdx == fluidSystemPhaseIdx ? fluidState_.saturation(fluidSystemPhaseIdx) : 1.0-fluidState_.saturation(fluidSystemPhaseIdx); } /*! * \brief Returns the average mass density \f$\mathrm{[kg/m^3]}\f$ of a given @@ -220,8 +219,8 @@ public: * * \param phaseIdx The index of the fluid phase */ - Scalar density(const int phaseIdx = FluidSystem::wPhaseIdx) const - { return phaseIdx == FluidSystem::wPhaseIdx ? fluidState_.density(phaseIdx) : 0.0; } + Scalar density(const int phaseIdx = fluidSystemPhaseIdx) const + { return phaseIdx == fluidSystemPhaseIdx ? fluidState_.density(phaseIdx) : 0.0; } /*! * \brief Returns the effective pressure \f$\mathrm{[Pa]}\f$ of a given phase within @@ -234,8 +233,8 @@ public: * * \param phaseIdx The index of the fluid phase */ - Scalar pressure(const int phaseIdx = FluidSystem::wPhaseIdx) const - { return phaseIdx == FluidSystem::wPhaseIdx ? fluidState_.pressure(phaseIdx) : pn_; } + Scalar pressure(const int phaseIdx = fluidSystemPhaseIdx) const + { return phaseIdx == fluidSystemPhaseIdx ? fluidState_.pressure(phaseIdx) : pn_; } /*! * \brief Returns the effective mobility \f$\mathrm{[1/(Pa*s)]}\f$ of a given phase within @@ -248,7 +247,7 @@ public: * * \param phaseIdx The index of the fluid phase */ - Scalar mobility(const int phaseIdx = FluidSystem::wPhaseIdx) const + Scalar mobility(const int phaseIdx = fluidSystemPhaseIdx) const { return relativePermeability(phaseIdx)/fluidState_.viscosity(phaseIdx); } /*! @@ -258,8 +257,8 @@ public: * \param phaseIdx The index of the fluid phase * \note The non-wetting phase is infinitely mobile */ - Scalar viscosity(const int phaseIdx = FluidSystem::wPhaseIdx) const - { return phaseIdx == FluidSystem::wPhaseIdx ? fluidState_.viscosity(FluidSystem::wPhaseIdx) : 0.0; } + Scalar viscosity(const int phaseIdx = fluidSystemPhaseIdx) const + { return phaseIdx == fluidSystemPhaseIdx ? fluidState_.viscosity(fluidSystemPhaseIdx) : 0.0; } /*! * \brief Returns relative permeability [-] of a given phase within @@ -267,8 +266,8 @@ public: * * \param phaseIdx The index of the fluid phase */ - Scalar relativePermeability(const int phaseIdx = FluidSystem::wPhaseIdx) const - { return phaseIdx == FluidSystem::wPhaseIdx ? relativePermeabilityWetting_ : 1.0; } + Scalar relativePermeability(const int phaseIdx = fluidSystemPhaseIdx) const + { return phaseIdx == fluidSystemPhaseIdx ? relativePermeabilityWetting_ : 1.0; } /*! * \brief Returns the effective capillary pressure \f$\mathrm{[Pa]}\f$ within the @@ -284,7 +283,7 @@ public: Scalar capillaryPressure() const { using std::max; - return max(minPc_, pn_ - fluidState_.pressure(FluidSystem::wPhaseIdx)); + return max(minPc_, pn_ - fluidState_.pressure(fluidSystemPhaseIdx)); } /*! @@ -301,7 +300,7 @@ public: * manually do a conversion. It is not correct if the density is not constant * or the gravity different */ - Scalar pressureHead(const int phaseIdx = FluidSystem::wPhaseIdx) const + Scalar pressureHead(const int phaseIdx = fluidSystemPhaseIdx) const { return 100.0 *(pressure(phaseIdx) - pn_)/density(phaseIdx)/9.81; } /*! @@ -315,7 +314,7 @@ public: * \note this function is here as a convenience to the user to not have to * manually do a conversion. */ - Scalar waterContent(const int phaseIdx = FluidSystem::wPhaseIdx) const + Scalar waterContent(const int phaseIdx = fluidSystemPhaseIdx) const { return saturation(phaseIdx) * porosity_; } /*! @@ -323,8 +322,8 @@ public: * * We always forward to the fluid state with the phaseIdx property (see class description). */ - Scalar molarDensity(const int phaseIdx = FluidSystem::wPhaseIdx) const - { return phaseIdx == FluidSystem::wPhaseIdx ? this->fluidState_.molarDensity(phaseIdx) : 0.0; } + Scalar molarDensity(const int phaseIdx = fluidSystemPhaseIdx) const + { return phaseIdx == fluidSystemPhaseIdx ? this->fluidState_.molarDensity(phaseIdx) : 0.0; } /*! * \brief Return mole fraction \f$\mathrm{[mol/mol]}\f$ of a component in the phase. @@ -335,7 +334,7 @@ public: * We always forward to the fluid state with the phaseIdx property (see class description). */ Scalar moleFraction(const int phaseIdx, const int compIdx) const - { return phaseIdx == FluidSystem::wPhaseIdx ? this->fluidState_.moleFraction(phaseIdx, compIdx) : 0.0; } + { return phaseIdx == fluidSystemPhaseIdx ? this->fluidState_.moleFraction(phaseIdx, compIdx) : 0.0; } /*! * \brief Return mass fraction \f$\mathrm{[kg/kg]}\f$ of a component in the phase. @@ -346,7 +345,7 @@ public: * We always forward to the fluid state with the phaseIdx property (see class description). */ Scalar massFraction(const int phaseIdx, const int compIdx) const - { return phaseIdx == FluidSystem::wPhaseIdx ? this->fluidState_.massFraction(phaseIdx, compIdx) : 0.0; } + { return phaseIdx == fluidSystemPhaseIdx ? this->fluidState_.massFraction(phaseIdx, compIdx) : 0.0; } /*! * \brief Return concentration \f$\mathrm{[mol/m^3]}\f$ of a component in the phase. @@ -357,7 +356,7 @@ public: * We always forward to the fluid state with the phaseIdx property (see class description). */ Scalar molarity(const int phaseIdx, const int compIdx) const - { return phaseIdx == FluidSystem::wPhaseIdx ? this->fluidState_.molarity(phaseIdx, compIdx) : 0.0; } + { return phaseIdx == fluidSystemPhaseIdx ? this->fluidState_.molarity(phaseIdx, compIdx) : 0.0; } /*! * \brief Return the binary diffusion coefficient \f$\mathrm{[m^2/s]}\f$ in the fluid. @@ -366,11 +365,7 @@ public: * \param compIdx The index of the component */ Scalar diffusionCoefficient(const int phaseIdx, const int compIdx) const - { - assert(phaseIdx == FluidSystem::wPhaseIdx); - assert(compIdx > FluidSystem::wPhaseIdx); - return diffCoefficient_[compIdx-1]; - } + { return diffCoefficient_[compIdx-1]; } protected: FluidState fluidState_; //!< the fluid state @@ -383,12 +378,9 @@ private: * \param compIdx The index of the component */ void setDiffusionCoefficient_(int compIdx, Scalar d) - { - assert(compIdx > FluidSystem::wPhaseIdx); - diffCoefficient_[compIdx-1] = d; - } + { diffCoefficient_[compIdx-1] = d; } - std::array<Scalar, numComponents-1> diffCoefficient_; + std::array<Scalar, ParentType::numComponents()-1> diffCoefficient_; Scalar relativePermeabilityWetting_; //!< the relative permeability of the wetting phase Scalar porosity_; //!< the porosity @@ -397,203 +389,6 @@ private: Scalar minPc_; //!< the minimum capillary pressure (entry pressure) }; -// /*! -// * \ingroup RichardsNCModel -// * \brief Contains the quantities which are constant within a -// * finite volume in the Richards, n-component model. -// */ -// template <class TypeTag> -// class RichardsNCVolumeVariables : public RichardsBaseVolumeVariables<TypeTag> -// { -// using ParentType = RichardsBaseVolumeVariables<TypeTag>; -// -// using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); -// using Problem = typename GET_PROP_TYPE(TypeTag, Problem); -// using GridView = typename GET_PROP_TYPE(TypeTag, GridView); -// using Implementation = typename GET_PROP_TYPE(TypeTag, VolumeVariables); -// using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; -// using SubControlVolume = typename FVElementGeometry::SubControlVolume; -// using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); -// using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); -// using Indices = typename GET_PROP_TYPE(TypeTag, Indices); -// -// static_assert(!GET_PROP_VALUE(TypeTag, EnableWaterDiffusionInAir), "Water diffusion in air is not implement for RichardsNC"); -// -// enum -// { -// wPhaseIdx = Indices::wPhaseIdx, -// pressureIdx = Indices::pressureIdx -// }; -// -// static constexpr bool useMoles = GET_PROP_VALUE(TypeTag, UseMoles); -// static const int dimWorld = GridView::dimensionworld; -// static const int numComponents = GET_PROP_TYPE(TypeTag, ModelTraits)::numComponents(); -// -// using GlobalPosition = Dune::FieldVector<Scalar, dimWorld>; -// using Element = typename GridView::template Codim<0>::Entity; -// -// public: -// -// using FluidState = typename GET_PROP_TYPE(TypeTag, FluidState); -// -// /*! -// * \brief Update all quantities for a given control volume -// * -// * \param elemSol A vector containing all primary variables connected to the element -// * \param problem The object specifying the problem which ought to -// * be simulated -// * \param element An element which contains part of the control volume -// * \param scv The sub-control volume -// */ -// template<class ElementSolution> -// void update(const ElementSolution &elemSol, -// const Problem &problem, -// const Element &element, -// const SubControlVolume &scv) -// { -// ParentType::update(elemSol, problem, element, scv); -// -// //calculate all secondary variables from the primary variables and store results in fluidstate -// Implementation::completeFluidState(elemSol, problem, element, scv, this->fluidState_); -// -// // Second instance of a parameter cache. -// // Could be avoided if diffusion coefficients also -// // became part of the fluid state. -// typename FluidSystem::ParameterCache paramCache; -// paramCache.updatePhase(this->fluidState_, wPhaseIdx); -// -// const int compIIdx = wPhaseIdx; -// for (unsigned int compJIdx = 0; compJIdx < numComponents; ++compJIdx) -// if(compIIdx != compJIdx) -// setDiffusionCoefficient_(compJIdx, -// FluidSystem::binaryDiffusionCoefficient(this->fluidState_, -// paramCache, -// wPhaseIdx, -// compIIdx, -// compJIdx)); -// } -// -// /*! -// * \brief Fill the fluid state according to the primary variables. -// * -// * Taking the information from the primary variables, -// * the fluid state is filled with every information that is -// * necessary to evaluate the model's local residual. -// * -// * \param elemSol A vector containing all primary variables connected to the element. -// * \param problem The problem at hand. -// * \param element The current element. -// * \param scv The subcontrol volume. -// * \param fluidState The fluid state to fill. -// */ -// template<class ElementSolution> -// static void completeFluidState(const ElementSolution &elemSol, -// const Problem& problem, -// const Element& element, -// const SubControlVolume &scv, -// FluidState& fluidState) -// { -// ParentType::completeFluidState(elemSol, problem, element, scv, fluidState); -// -// const auto& priVars = ParentType::extractDofPriVars(elemSol, scv); -// -// // set the mole/mass fractions -// if(useMoles) -// { -// Scalar sumSecondaryFractions = 0.0; -// for (int compIdx = 1; compIdx < numComponents; ++compIdx) -// { -// fluidState.setMoleFraction(wPhaseIdx, compIdx, priVars[compIdx]); -// sumSecondaryFractions += priVars[compIdx]; -// } -// fluidState.setMoleFraction(wPhaseIdx, 0, 1.0 - sumSecondaryFractions); -// } -// else -// { -// for (int compIdx = 1; compIdx < numComponents; ++compIdx) -// fluidState.setMassFraction(wPhaseIdx, compIdx, priVars[compIdx]); -// } -// } -// -// /*! -// * \brief Return molar density \f$\mathrm{[mol/m^3]}\f$ the of the fluid phase. -// * -// * We always forward to the fluid state with the phaseIdx property (see class description). -// */ -// Scalar molarDensity(const int phaseIdx = FluidSystem::wPhaseIdx) const -// { return phaseIdx == FluidSystem::wPhaseIdx ? this->fluidState_.molarDensity(phaseIdx) : 0.0; } -// -// /*! -// * \brief Return mole fraction \f$\mathrm{[mol/mol]}\f$ of a component in the phase. -// * -// * \param phaseIdx The index of the phase. -// * \param compIdx The index of the component. -// * -// * We always forward to the fluid state with the phaseIdx property (see class description). -// */ -// Scalar moleFraction(const int phaseIdx, const int compIdx) const -// { return phaseIdx == FluidSystem::wPhaseIdx ? this->fluidState_.moleFraction(phaseIdx, compIdx) : 0.0; } -// -// /*! -// * \brief Return mass fraction \f$\mathrm{[kg/kg]}\f$ of a component in the phase. -// * -// * \param phaseIdx The index of the phase. -// * \param compIdx The index of the component -// * -// * We always forward to the fluid state with the phaseIdx property (see class description). -// */ -// Scalar massFraction(const int phaseIdx, const int compIdx) const -// { return phaseIdx == FluidSystem::wPhaseIdx ? this->fluidState_.massFraction(phaseIdx, compIdx) : 0.0; } -// -// /*! -// * \brief Return concentration \f$\mathrm{[mol/m^3]}\f$ of a component in the phase. -// * -// * \param phaseIdx The index of the phase. -// * \param compIdx The index of the component -// * -// * We always forward to the fluid state with the phaseIdx property (see class description). -// */ -// Scalar molarity(const int phaseIdx, const int compIdx) const -// { return phaseIdx == FluidSystem::wPhaseIdx ? this->fluidState_.molarity(phaseIdx, compIdx) : 0.0; } -// -// /*! -// * \brief Return the binary diffusion coefficient \f$\mathrm{[m^2/s]}\f$ in the fluid. -// * -// * \param phaseIdx The index of the phase. -// * \param compIdx The index of the component -// */ -// Scalar diffusionCoefficient(const int phaseIdx, const int compIdx) const -// { -// assert(phaseIdx == FluidSystem::wPhaseIdx); -// assert(compIdx > FluidSystem::wPhaseIdx); -// return diffCoefficient_[compIdx-1]; -// } -// -// protected: -// FluidState fluidState_; //!< the fluid state -// -// private: -// /*! -// * \brief TODO docme! -// * -// * \param d TODO docme! -// * \param compIdx The index of the component -// */ -// void setDiffusionCoefficient_(int compIdx, Scalar d) -// { -// assert(compIdx > FluidSystem::wPhaseIdx); -// diffCoefficient_[compIdx-1] = d; -// } -// -// std::array<Scalar, numComponents-1> diffCoefficient_; -// -// Scalar relativePermeabilityWetting_; //!< the relative permeability of the wetting phase -// Scalar porosity_; //!< the porosity -// PermeabilityType permeability_; //!< the instrinsic permeability -// Scalar pn_; //!< the reference non-wetting pressure -// Scalar minPc_; //!< the minimum capillary pressure (entry pressure) -// }; - } // end namespace Dumux #endif diff --git a/dumux/porousmediumflow/richardsnc/vtkoutputfields.hh b/dumux/porousmediumflow/richardsnc/vtkoutputfields.hh index 40b172046a194d8fae1977fcacf5e58a7214f498..8d760dfa8ec7e71f2e70f767f5afb56c495ccff3 100644 --- a/dumux/porousmediumflow/richardsnc/vtkoutputfields.hh +++ b/dumux/porousmediumflow/richardsnc/vtkoutputfields.hh @@ -39,25 +39,25 @@ public: using VolumeVariables = typename VtkOutputModule::VolumeVariables; using FluidSystem = typename VolumeVariables::FluidSystem; - vtk.addVolumeVariable([](const auto& v){ return v.saturation(VolumeVariables::wPhaseIdx); }, "Sw"); - vtk.addVolumeVariable([](const auto& v){ return v.saturation(VolumeVariables::nPhaseIdx); }, "Sn"); - vtk.addVolumeVariable([](const auto& v){ return v.pressure(VolumeVariables::wPhaseIdx); }, "pw"); - vtk.addVolumeVariable([](const auto& v){ return v.pressure(VolumeVariables::nPhaseIdx); }, "pn"); + vtk.addVolumeVariable([](const auto& v){ return v.saturation(VolumeVariables::liquidPhaseIdx); }, "Sw"); + vtk.addVolumeVariable([](const auto& v){ return v.saturation(VolumeVariables::gasPhaseIdx); }, "Sn"); + vtk.addVolumeVariable([](const auto& v){ return v.pressure(VolumeVariables::liquidPhaseIdx); }, "pw"); + vtk.addVolumeVariable([](const auto& v){ return v.pressure(VolumeVariables::gasPhaseIdx); }, "pn"); vtk.addVolumeVariable([](const auto& v){ return v.capillaryPressure(); }, "pc"); - vtk.addVolumeVariable([](const auto& v){ return v.density(VolumeVariables::wPhaseIdx); }, "density"); - vtk.addVolumeVariable([](const auto& v){ return v.mobility(VolumeVariables::wPhaseIdx); }, "mobility"); - vtk.addVolumeVariable([](const auto& v){ return v.relativePermeability(VolumeVariables::wPhaseIdx); }, "kr"); + vtk.addVolumeVariable([](const auto& v){ return v.density(VolumeVariables::liquidPhaseIdx); }, "density"); + vtk.addVolumeVariable([](const auto& v){ return v.mobility(VolumeVariables::liquidPhaseIdx); }, "mobility"); + vtk.addVolumeVariable([](const auto& v){ return v.relativePermeability(VolumeVariables::liquidPhaseIdx); }, "kr"); vtk.addVolumeVariable([](const auto& v){ return v.porosity(); }, "porosity"); vtk.addVolumeVariable([](const auto& v){ return v.temperature(); }, "temperature"); static const bool gravity = getParamFromGroup<bool>(vtk.paramGroup(), "Problem.EnableGravity"); if(gravity) - vtk.addVolumeVariable([](const auto& v){ return v.pressureHead(VolumeVariables::wPhaseIdx); }, "pressure head"); - vtk.addVolumeVariable([](const auto& v){ return v.waterContent(VolumeVariables::wPhaseIdx); },"water content"); + vtk.addVolumeVariable([](const auto& v){ return v.pressureHead(VolumeVariables::liquidPhaseIdx); }, "pressure head"); + vtk.addVolumeVariable([](const auto& v){ return v.waterContent(VolumeVariables::liquidPhaseIdx); },"water content"); for (int compIdx = 0; compIdx < VolumeVariables::numComponents(); ++compIdx) - vtk.addVolumeVariable([compIdx](const auto& v){ return v.moleFraction(VolumeVariables::wPhaseIdx, compIdx); }, - "x^" + FluidSystem::phaseName(FluidSystem::wPhaseIdx) + "_" + FluidSystem::componentName(compIdx)); + vtk.addVolumeVariable([compIdx](const auto& v){ return v.moleFraction(VolumeVariables::liquidPhaseIdx, compIdx); }, + "x^" + FluidSystem::phaseName(VolumeVariables::liquidPhaseIdx) + "_" + FluidSystem::componentName(compIdx)); } }; diff --git a/dumux/porousmediumflow/tracer/volumevariables.hh b/dumux/porousmediumflow/tracer/volumevariables.hh index 2b85aa0b6dbf023671387248ea509f4da1bde4fd..12e9d1641beed83e52c30ae8a2b4d6283f251d46 100644 --- a/dumux/porousmediumflow/tracer/volumevariables.hh +++ b/dumux/porousmediumflow/tracer/volumevariables.hh @@ -41,7 +41,6 @@ class TracerVolumeVariables using Scalar = typename Traits::PrimaryVariables::value_type; static constexpr bool useMoles = Traits::ModelTraits::useMoles(); - static constexpr int numComponents = Traits::ModelTraits::numComponents(); public: //! export fluid system type @@ -72,7 +71,7 @@ public: fluidDensity_ = problem.spatialParams().fluidDensity(element, scv); fluidMolarMass_ = problem.spatialParams().fluidMolarMass(element, scv); - for (int compIdx = 0; compIdx < numComponents; ++compIdx) + for (int compIdx = 0; compIdx < ParentType::numComponents(); ++compIdx) { moleOrMassFraction_[compIdx] = this->priVars()[compIdx]; diffCoeff_[compIdx] = FluidSystem::binaryDiffusionCoefficient(compIdx, problem, element, scv); @@ -172,8 +171,8 @@ protected: Scalar porosity_; // Effective porosity within the control volume Scalar fluidDensity_, fluidMolarMass_; // DispersivityType dispersivity_; - std::array<Scalar, numComponents> diffCoeff_; - std::array<Scalar, numComponents> moleOrMassFraction_; + std::array<Scalar, ParentType::numComponents()> diffCoeff_; + std::array<Scalar, ParentType::numComponents()> moleOrMassFraction_; }; } // end namespace Dumux diff --git a/test/freeflow/navierstokesnc/channeltestproblem.hh b/test/freeflow/navierstokesnc/channeltestproblem.hh index 87fe301e8f274f781e4efc4f938ab83ed98d4b22..f72f82451ecb8e691b651a182deefa2f2fb13c30 100644 --- a/test/freeflow/navierstokesnc/channeltestproblem.hh +++ b/test/freeflow/navierstokesnc/channeltestproblem.hh @@ -53,7 +53,7 @@ SET_TYPE_PROP(ChannelNCTestTypeTag, FluidSystem, FluidSystems::H2OAir<typename GET_PROP_TYPE(TypeTag, Scalar)/*, SimpleH2O<typename GET_PROP_TYPE(TypeTag, Scalar)>, true*/>); SET_INT_PROP(ChannelNCTestTypeTag, PhaseIdx, - GET_PROP_TYPE(TypeTag, FluidSystem)::wPhaseIdx); + GET_PROP_TYPE(TypeTag, FluidSystem)::phase0Idx); SET_INT_PROP(ChannelNCTestTypeTag, ReplaceCompEqIdx, GET_PROP_VALUE(TypeTag, PhaseIdx)); diff --git a/test/freeflow/navierstokesnc/densityflowproblem.hh b/test/freeflow/navierstokesnc/densityflowproblem.hh index 5c9661b2d1f010493f56f5d9297c5af54bf82c60..2e0bfcd0e20c770c14eb56b9ff5852fbe410029e 100644 --- a/test/freeflow/navierstokesnc/densityflowproblem.hh +++ b/test/freeflow/navierstokesnc/densityflowproblem.hh @@ -48,7 +48,7 @@ SET_TYPE_PROP(DensityDrivenFlowTypeTag, FluidSystem, FluidSystems::H2OAir<typename GET_PROP_TYPE(TypeTag, Scalar)/*, SimpleH2O<typename GET_PROP_TYPE(TypeTag, Scalar)>, false*/>); SET_INT_PROP(DensityDrivenFlowTypeTag, PhaseIdx, - GET_PROP_TYPE(TypeTag, FluidSystem)::wPhaseIdx); + GET_PROP_TYPE(TypeTag, FluidSystem)::phase0Idx); SET_INT_PROP(DensityDrivenFlowTypeTag, ReplaceCompEqIdx, GET_PROP_VALUE(TypeTag, PhaseIdx)); diff --git a/test/freeflow/ransnc/channeltestproblem.hh b/test/freeflow/ransnc/channeltestproblem.hh index e5d3a6da51e968e41ad703cfdaf7b8c5cd562c82..3ad9efdad39df8c6ab409b01ff599c2f78cbfc44 100644 --- a/test/freeflow/ransnc/channeltestproblem.hh +++ b/test/freeflow/ransnc/channeltestproblem.hh @@ -52,7 +52,7 @@ SET_TYPE_PROP(ChannelNCTestTypeTag, FluidSystem, FluidSystems::H2OAir<typename GET_PROP_TYPE(TypeTag, Scalar)>); SET_INT_PROP(ChannelNCTestTypeTag, PhaseIdx, - GET_PROP_TYPE(TypeTag, FluidSystem)::nPhaseIdx); + GET_PROP_TYPE(TypeTag, FluidSystem)::phase1Idx); SET_INT_PROP(ChannelNCTestTypeTag, ReplaceCompEqIdx, GET_PROP_VALUE(TypeTag, PhaseIdx)); @@ -70,7 +70,7 @@ SET_BOOL_PROP(ChannelNCTestTypeTag, EnableGridVolumeVariablesCache, true); // Enable gravity SET_BOOL_PROP(ChannelNCTestTypeTag, UseMoles, true); -} +} // end namespace Properties /*! * \ingroup RANSNCTests diff --git a/test/material/fluidsystems/checkfluidsystem.hh b/test/material/fluidsystems/checkfluidsystem.hh index 2914a7b75e46de3f06189f38d5cdc130bfaecd12..88f1e2e021a2598045136ee25506177754dc5a22 100644 --- a/test/material/fluidsystems/checkfluidsystem.hh +++ b/test/material/fluidsystems/checkfluidsystem.hh @@ -136,6 +136,12 @@ public: return BaseFluidState::temperature(phaseIdx); } + Scalar wettingPhase() const + { + assert(allowComposition_); + return BaseFluidState::wettingPhase(); + } + Scalar partialPressure(int phaseIdx, int compIdx) const { assert(allowComposition_); diff --git a/test/material/immiscibleflash/test_immiscibleflash.cc b/test/material/immiscibleflash/test_immiscibleflash.cc index a89a85e7d78c1196ec6201008dd60e97a8ea1c1e..958980b9371a676068f2f0aa6b992d382aa0e150 100644 --- a/test/material/immiscibleflash/test_immiscibleflash.cc +++ b/test/material/immiscibleflash/test_immiscibleflash.cc @@ -155,12 +155,12 @@ int main() enum { numPhases = FluidSystem::numPhases }; enum { numComponents = FluidSystem::numComponents }; - enum { wPhaseIdx = FluidSystem::wPhaseIdx }; - enum { nPhaseIdx = FluidSystem::nPhaseIdx }; + enum { liquidPhaseIdx = FluidSystem::liquidPhaseIdx }; + enum { gasPhaseIdx = FluidSystem::gasPhaseIdx }; using EffMaterialLaw = Dumux::RegularizedBrooksCorey<Scalar>; using TwoPMaterialLaw = Dumux::EffToAbsLaw<EffMaterialLaw>; - using MaterialLaw = Dumux::TwoPAdapter<wPhaseIdx, TwoPMaterialLaw>; + using MaterialLaw = Dumux::TwoPAdapter<liquidPhaseIdx, TwoPMaterialLaw>; using MaterialLawParams = MaterialLaw::Params; Scalar T = 273.15 + 25; @@ -196,11 +196,11 @@ int main() std::cout << "testing single-phase liquid\n"; // set liquid saturation and pressure - fsRef.setSaturation(wPhaseIdx, 1.0); - fsRef.setPressure(wPhaseIdx, 1e6); + fsRef.setSaturation(liquidPhaseIdx, 1.0); + fsRef.setPressure(liquidPhaseIdx, 1e6); // set the remaining parameters of the reference fluid state - completeReferenceFluidState<Scalar, FluidSystem, MaterialLaw>(fsRef, matParams, wPhaseIdx); + completeReferenceFluidState<Scalar, FluidSystem, MaterialLaw>(fsRef, matParams, liquidPhaseIdx); // check the flash calculation checkImmiscibleFlash<Scalar, FluidSystem, MaterialLaw>(fsRef, matParams); @@ -211,11 +211,11 @@ int main() std::cout << "testing single-phase gas\n"; // set gas saturation and pressure - fsRef.setSaturation(nPhaseIdx, 1.0); - fsRef.setPressure(nPhaseIdx, 1e6); + fsRef.setSaturation(gasPhaseIdx, 1.0); + fsRef.setPressure(gasPhaseIdx, 1e6); // set the remaining parameters of the reference fluid state - completeReferenceFluidState<Scalar, FluidSystem, MaterialLaw>(fsRef, matParams, nPhaseIdx); + completeReferenceFluidState<Scalar, FluidSystem, MaterialLaw>(fsRef, matParams, gasPhaseIdx); // check the flash calculation checkImmiscibleFlash<Scalar, FluidSystem, MaterialLaw>(fsRef, matParams); @@ -226,11 +226,11 @@ int main() std::cout << "testing two-phase\n"; // set liquid saturation and pressure - fsRef.setSaturation(wPhaseIdx, 0.5); - fsRef.setPressure(wPhaseIdx, 1e6); + fsRef.setSaturation(liquidPhaseIdx, 0.5); + fsRef.setPressure(liquidPhaseIdx, 1e6); // set the remaining parameters of the reference fluid state - completeReferenceFluidState<Scalar, FluidSystem, MaterialLaw>(fsRef, matParams, wPhaseIdx); + completeReferenceFluidState<Scalar, FluidSystem, MaterialLaw>(fsRef, matParams, liquidPhaseIdx); // check the flash calculation checkImmiscibleFlash<Scalar, FluidSystem, MaterialLaw>(fsRef, matParams); @@ -247,13 +247,13 @@ int main() matParams2.setLambda(2.0); // set liquid saturation - fsRef.setSaturation(wPhaseIdx, 0.5); + fsRef.setSaturation(liquidPhaseIdx, 0.5); // set pressure of the liquid phase - fsRef.setPressure(wPhaseIdx, 1e6); + fsRef.setPressure(liquidPhaseIdx, 1e6); // set the remaining parameters of the reference fluid state - completeReferenceFluidState<Scalar, FluidSystem, MaterialLaw>(fsRef, matParams2, wPhaseIdx); + completeReferenceFluidState<Scalar, FluidSystem, MaterialLaw>(fsRef, matParams2, liquidPhaseIdx); // check the flash calculation checkImmiscibleFlash<Scalar, FluidSystem, MaterialLaw>(fsRef, matParams2); diff --git a/test/material/ncpflash/test_ncpflash.cc b/test/material/ncpflash/test_ncpflash.cc index 20dbca2a2425206265296437e4d78739d65620a5..ff562c94ca857c8dd15f247d9bf7bc80a7920076 100644 --- a/test/material/ncpflash/test_ncpflash.cc +++ b/test/material/ncpflash/test_ncpflash.cc @@ -157,15 +157,15 @@ int main() enum { numPhases = FluidSystem::numPhases }; enum { numComponents = FluidSystem::numComponents }; - enum { wPhaseIdx = FluidSystem::wPhaseIdx }; - enum { nPhaseIdx = FluidSystem::nPhaseIdx }; + enum { liquidPhaseIdx = FluidSystem::liquidPhaseIdx }; + enum { gasPhaseIdx = FluidSystem::gasPhaseIdx }; enum { H2OIdx = FluidSystem::H2OIdx }; enum { N2Idx = FluidSystem::N2Idx }; using EffMaterialLaw = Dumux::RegularizedBrooksCorey<Scalar>; using TwoPMaterialLaw = Dumux::EffToAbsLaw<EffMaterialLaw>; - using MaterialLaw = Dumux::TwoPAdapter<wPhaseIdx, TwoPMaterialLaw>; + using MaterialLaw = Dumux::TwoPAdapter<liquidPhaseIdx, TwoPMaterialLaw>; using MaterialLawParams = MaterialLaw::Params; Scalar T = 273.15 + 25; @@ -201,17 +201,17 @@ int main() std::cout << "testing single-phase liquid\n"; // set liquid saturation - fsRef.setSaturation(wPhaseIdx, 1.0); + fsRef.setSaturation(liquidPhaseIdx, 1.0); // set pressure of the liquid phase - fsRef.setPressure(wPhaseIdx, 2e5); + fsRef.setPressure(liquidPhaseIdx, 2e5); // set the liquid composition to pure water - fsRef.setMoleFraction(wPhaseIdx, N2Idx, 0.0); - fsRef.setMoleFraction(wPhaseIdx, H2OIdx, 1.0); + fsRef.setMoleFraction(liquidPhaseIdx, N2Idx, 0.0); + fsRef.setMoleFraction(liquidPhaseIdx, H2OIdx, 1.0); // "complete" the fluid state - completeReferenceFluidState<Scalar, FluidSystem, MaterialLaw>(fsRef, matParams, wPhaseIdx); + completeReferenceFluidState<Scalar, FluidSystem, MaterialLaw>(fsRef, matParams, liquidPhaseIdx); // check the flash calculation checkNcpFlash<Scalar, FluidSystem, MaterialLaw>(fsRef, matParams); @@ -221,17 +221,17 @@ int main() //////////////// std::cout << "testing single-phase gas\n"; // set gas saturation - fsRef.setSaturation(nPhaseIdx, 1.0); + fsRef.setSaturation(gasPhaseIdx, 1.0); // set pressure of the gas phase - fsRef.setPressure(nPhaseIdx, 1e6); + fsRef.setPressure(gasPhaseIdx, 1e6); // set the gas composition to 99.9% nitrogen and 0.1% water - fsRef.setMoleFraction(nPhaseIdx, N2Idx, 0.999); - fsRef.setMoleFraction(nPhaseIdx, H2OIdx, 0.001); + fsRef.setMoleFraction(gasPhaseIdx, N2Idx, 0.999); + fsRef.setMoleFraction(gasPhaseIdx, H2OIdx, 0.001); // "complete" the fluid state - completeReferenceFluidState<Scalar, FluidSystem, MaterialLaw>(fsRef, matParams, nPhaseIdx); + completeReferenceFluidState<Scalar, FluidSystem, MaterialLaw>(fsRef, matParams, gasPhaseIdx); // check the flash calculation checkNcpFlash<Scalar, FluidSystem, MaterialLaw>(fsRef, matParams); @@ -242,12 +242,12 @@ int main() std::cout << "testing two-phase\n"; // set saturations - fsRef.setSaturation(wPhaseIdx, 0.5); - fsRef.setSaturation(nPhaseIdx, 0.5); + fsRef.setSaturation(liquidPhaseIdx, 0.5); + fsRef.setSaturation(gasPhaseIdx, 0.5); // set pressures - fsRef.setPressure(wPhaseIdx, 1e6); - fsRef.setPressure(nPhaseIdx, 1e6); + fsRef.setPressure(liquidPhaseIdx, 1e6); + fsRef.setPressure(gasPhaseIdx, 1e6); FluidSystem::ParameterCache paramCache; using MiscibleMultiPhaseComposition = Dumux::MiscibleMultiPhaseComposition<Scalar, FluidSystem>; @@ -269,19 +269,19 @@ int main() matParams2.setLambda(2.0); // set gas saturation - fsRef.setSaturation(nPhaseIdx, 0.5); - fsRef.setSaturation(wPhaseIdx, 0.5); + fsRef.setSaturation(gasPhaseIdx, 0.5); + fsRef.setSaturation(liquidPhaseIdx, 0.5); // set pressure of the liquid phase - fsRef.setPressure(wPhaseIdx, 1e6); + fsRef.setPressure(liquidPhaseIdx, 1e6); // calulate the capillary pressure using PhaseVector = Dune::FieldVector<Scalar, numPhases>; PhaseVector pc; MaterialLaw::capillaryPressures(pc, matParams2, fsRef); - fsRef.setPressure(nPhaseIdx, - fsRef.pressure(wPhaseIdx) - + (pc[nPhaseIdx] - pc[wPhaseIdx])); + fsRef.setPressure(gasPhaseIdx, + fsRef.pressure(liquidPhaseIdx) + + (pc[gasPhaseIdx] - pc[liquidPhaseIdx])); using MiscibleMultiPhaseComposition = Dumux::MiscibleMultiPhaseComposition<Scalar, FluidSystem>; MiscibleMultiPhaseComposition::solve(fsRef, paramCache, diff --git a/test/porousmediumflow/1pncmin/implicit/modifiedsteamn2cao2h2.hh b/test/porousmediumflow/1pncmin/implicit/modifiedsteamn2cao2h2.hh index e6d6ac40391c2c8a2bee27a56cb0b68db3d4163b..1753dd0c0e9fa5b1d545e783acf18846bfa36e6a 100644 --- a/test/porousmediumflow/1pncmin/implicit/modifiedsteamn2cao2h2.hh +++ b/test/porousmediumflow/1pncmin/implicit/modifiedsteamn2cao2h2.hh @@ -79,20 +79,27 @@ public: // the type of parameter cache objects. this fluid system does not using ParameterCache = Dumux::NullParameterCache; - /**************************************** - * Fluid phase related static parameters - ****************************************/ - //! Number of phases in the fluid system static constexpr int numPhases = 1; //gas phase: N2 and steam - static const int numSPhases = 2;// solid phases CaO and CaO2H2 - - static constexpr int gPhaseIdx = 0; - static const int nPhaseIdx = gPhaseIdx; // index of the gas phase - - static constexpr int cPhaseIdx = 1; // CaO-phaseIdx - static constexpr int hPhaseIdx = 2; // CaO2H2-phaseIdx + static constexpr int numComponents = 2; // H2O, Air + static constexpr int numSPhases = 2;// solid phases CaO and CaO2H2 TODO: Remove + static constexpr int numSComponents = 2;// CaO2H2, CaO TODO: Remove + + static constexpr int gasPhaseIdx = 0; //!< index of the gas phase + static constexpr int phase0Idx = gasPhaseIdx; //!< index of the only phase + static constexpr int cPhaseIdx = 1; // CaO-phaseIdx TODO: Remove + static constexpr int hPhaseIdx = 2; // CaO2H2-phaseIdx TODO: Remove + + static constexpr int N2Idx = 0; + static constexpr int H2OIdx = 1; + static constexpr int comp0Idx = N2Idx; + static constexpr int comp1Idx = H2OIdx; + static constexpr int CaOIdx = 2; // CaO-phaseIdx TODO: Remove + static constexpr int CaO2H2Idx = 3; // CaO-phaseIdx TODO: Remove + /**************************************** + * Fluid phase related static parameters + ****************************************/ /*! * \brief Return the human readable name of a fluid phase @@ -102,7 +109,7 @@ public: static std::string phaseName(int phaseIdx) { switch (phaseIdx) { - case nPhaseIdx: return "gas"; + case gasPhaseIdx: return "gas"; case cPhaseIdx : return "CaO"; case hPhaseIdx : return "CaOH2"; } @@ -117,7 +124,7 @@ public: static bool isGas (int phaseIdx) { assert(0 <= phaseIdx && phaseIdx < numPhases); - return phaseIdx == nPhaseIdx; + return phaseIdx == gasPhaseIdx; } /*! @@ -175,17 +182,6 @@ public: /**************************************** * Component related static parameters ****************************************/ - - static const int numComponents = 2; // H2O, Air - static const int numSComponents = 2;// CaO2H2, CaO - - - static const int N2Idx = 0; - static const int H2OIdx = 1; - static const int CaOIdx = 2; - static const int CaO2H2Idx = 3; - - /*! * \brief Return the human readable name of a component * @@ -350,13 +346,13 @@ public: // for the gas phase assume an ideal gas return IdealGas::molarDensity(T, p) - * fluidState.averageMolarMass(nPhaseIdx) + * fluidState.averageMolarMass(gasPhaseIdx) / std::max(1e-5, sumMoleFrac); else { return - (H2O::gasDensity(T, fluidState.partialPressure(nPhaseIdx, H2OIdx)) + - N2::gasDensity(T, fluidState.partialPressure(nPhaseIdx, N2Idx))); + (H2O::gasDensity(T, fluidState.partialPressure(gasPhaseIdx, H2OIdx)) + + N2::gasDensity(T, fluidState.partialPressure(gasPhaseIdx, N2Idx))); } } @@ -435,7 +431,7 @@ public: Scalar temperature = fluidState.temperature(phaseIdx); Scalar pressure = fluidState.pressure(phaseIdx); - assert(phaseIdx == gPhaseIdx); + assert(phaseIdx == gasPhaseIdx); if (compIIdx != N2Idx) std::swap(compIIdx, compJIdx); @@ -471,13 +467,13 @@ public: static Scalar enthalpy(const FluidState &fluidState, int phaseIdx) { - assert(phaseIdx == gPhaseIdx); + assert(phaseIdx == gasPhaseIdx); Scalar T = fluidState.temperature(phaseIdx); Scalar p = fluidState.pressure(phaseIdx); - Scalar XN2 = fluidState.massFraction(gPhaseIdx, N2Idx); - Scalar XH2O = fluidState.massFraction(gPhaseIdx, H2OIdx); + Scalar XN2 = fluidState.massFraction(gasPhaseIdx, N2Idx); + Scalar XH2O = fluidState.massFraction(gasPhaseIdx, H2OIdx); Scalar result = 0; result += XH2O * H2O::gasEnthalpy(T, p); @@ -498,8 +494,8 @@ public: int phaseIdx, int componentIdx) { - Scalar T = fluidState.temperature(nPhaseIdx); - Scalar p = fluidState.pressure(nPhaseIdx); + Scalar T = fluidState.temperature(gasPhaseIdx); + Scalar p = fluidState.pressure(gasPhaseIdx); Valgrind::CheckDefined(T); Valgrind::CheckDefined(p); @@ -520,7 +516,7 @@ public: int componentIdx) { Scalar T = 573.15; - Scalar p = fluidState.pressure(nPhaseIdx); + Scalar p = fluidState.pressure(gasPhaseIdx); Valgrind::CheckDefined(T); Valgrind::CheckDefined(p); @@ -604,7 +600,7 @@ public: fluidState.pressure(phaseIdx) * fluidState.moleFraction(phaseIdx, H2OIdx)); - return c_pH2O*fluidState.moleFraction(nPhaseIdx, H2OIdx) + c_pN2*fluidState.moleFraction(nPhaseIdx, N2Idx); + return c_pH2O*fluidState.moleFraction(gasPhaseIdx, H2OIdx) + c_pN2*fluidState.moleFraction(gasPhaseIdx, N2Idx); } }; diff --git a/test/porousmediumflow/1pncmin/implicit/thermochemproblem.hh b/test/porousmediumflow/1pncmin/implicit/thermochemproblem.hh index 8701b8a69fd734ee9f1720f280ce7f7c6403cf2c..dda4373600c342e74d67b0f8e52c7e0cc5c6194b 100644 --- a/test/porousmediumflow/1pncmin/implicit/thermochemproblem.hh +++ b/test/porousmediumflow/1pncmin/implicit/thermochemproblem.hh @@ -100,7 +100,7 @@ class ThermoChemProblem : public PorousMediumFlowProblem<TypeTag> using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector); using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector); - using ReactionRate =ThermoChemReaction<TypeTag>; + using ReactionRate = ThermoChemReaction; enum { dim = GridView::dimension }; enum { dimWorld = GridView::dimensionworld }; @@ -109,7 +109,7 @@ class ThermoChemProblem : public PorousMediumFlowProblem<TypeTag> { // Indices of the primary variables pressureIdx = Indices::pressureIdx, //gas-phase pressure - firstMoleFracIdx = Indices::firstMoleFracIdx, // mole fraction water + H2OIdx = FluidSystem::H2OIdx, // mole fraction water CaOIdx = FluidSystem::numComponents, CaO2H2Idx = FluidSystem::numComponents+1, @@ -180,7 +180,7 @@ public: // we don't set any BCs for the solid phases values.setDirichlet(pressureIdx); - values.setDirichlet(firstMoleFracIdx); + values.setDirichlet(H2OIdx); values.setDirichlet(temperatureIdx); return values; @@ -197,7 +197,7 @@ public: PrimaryVariables priVars(0.0); priVars[pressureIdx] = boundaryPressure_; - priVars[firstMoleFracIdx] = boundaryVaporMoleFrac_; + priVars[H2OIdx] = boundaryVaporMoleFrac_; priVars[temperatureIdx] = boundaryTemperature_; priVars[CaO2H2Idx] = 0.0; priVars[CaOIdx] = 0.2; @@ -250,7 +250,7 @@ public: CaO2H2Init = getParam<Scalar>("Problem.CaO2H2Initial"); priVars[pressureIdx] = pInit; - priVars[firstMoleFracIdx] = h2oInit; + priVars[H2OIdx] = h2oInit; priVars[temperatureIdx] = tInit; // these values are not used, as we didn't set BCs @@ -292,7 +292,7 @@ public: Scalar qMass = rrate_.thermoChemReaction(volVars); const auto elemSol = elementSolution(element, elemVolVars, fvGeometry); - Scalar qMole = qMass/FluidSystem::molarMass(firstMoleFracIdx)*(1-this->spatialParams().porosity(element, scv, elemSol)); + Scalar qMole = qMass/FluidSystem::molarMass(H2OIdx)*(1-this->spatialParams().porosity(element, scv, elemSol)); // make sure not more solid reacts than present // In this test, we only consider discharge. Therefore, we use the cPhaseIdx for CaO. @@ -303,7 +303,7 @@ public: source[conti0EqIdx+CaO2H2Idx] = qMole; source[conti0EqIdx+CaOIdx] = - qMole; - source[conti0EqIdx+firstMoleFracIdx] = - qMole; + source[conti0EqIdx+H2OIdx] = - qMole; Scalar deltaH = 108e3; // J/mol source[energyEqIdx] = qMole * deltaH; diff --git a/test/porousmediumflow/1pncmin/implicit/thermochemreaction.hh b/test/porousmediumflow/1pncmin/implicit/thermochemreaction.hh index d332cca02669ed72ac5b4a652b210692bdc1f284..2881de870d9dac35183f0ead7da08994b5a78e78 100644 --- a/test/porousmediumflow/1pncmin/implicit/thermochemreaction.hh +++ b/test/porousmediumflow/1pncmin/implicit/thermochemreaction.hh @@ -26,11 +26,7 @@ #ifndef DUMUX_THERMOCHEM_REACTION_HH #define DUMUX_THERMOCHEM_REACTION_HH -#include <dumux/common/properties.hh> - -namespace Dumux -{ - +namespace Dumux { /*! * \ingroup OnePNCMinTests @@ -38,67 +34,50 @@ namespace Dumux * * It contains simple and advanced reaction kinetics according to Nagel et al. (2014). */ -template<class TypeTag> class ThermoChemReaction { - using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables); - using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; - using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); - - static const int numComponents = GET_PROP_TYPE(TypeTag, ModelTraits)::numComponents(); - static const int numSolidPhases = GET_PROP_TYPE(TypeTag, ModelTraits)::numSPhases(); - - enum{ - // Indices of the primary variables - pressureIdx = Indices::pressureIdx, //gas-phase pressure - firstMoleFracIdx = Indices::firstMoleFracIdx, // mole fraction water - - // Phase Indices - phaseIdx = FluidSystem::gPhaseIdx, - cPhaseIdx = FluidSystem::cPhaseIdx, - hPhaseIdx = FluidSystem::hPhaseIdx - }; - public: - - /*! * \brief evaluates the reaction kinetics (see Nagel et al. 2014) */ - Scalar thermoChemReaction(const VolumeVariables &volVars) const + template<class VolumeVariables> + typename VolumeVariables::PrimaryVariables::value_type + thermoChemReaction(const VolumeVariables &volVars) const { + using FluidSystem = typename VolumeVariables::FluidSystem; + using Scalar = typename VolumeVariables::PrimaryVariables::value_type; + // calculate the equilibrium temperature Teq Scalar T= volVars.temperature(); Scalar Teq = 0; Scalar moleFractionVapor = 1e-3; - if(volVars.moleFraction(phaseIdx, firstMoleFracIdx) > 1e-3) - moleFractionVapor = volVars.moleFraction(phaseIdx, firstMoleFracIdx); + if(volVars.moleFraction(FluidSystem::gasPhaseIdx, FluidSystem::H2OIdx) > 1e-3) + moleFractionVapor = volVars.moleFraction(FluidSystem::gasPhaseIdx, FluidSystem::H2OIdx); - if(volVars.moleFraction(phaseIdx, firstMoleFracIdx) >= 1.0) moleFractionVapor = 1; + if(volVars.moleFraction(FluidSystem::gasPhaseIdx, FluidSystem::H2OIdx) >= 1.0) moleFractionVapor = 1; - Scalar pV = volVars.pressure(phaseIdx) *moleFractionVapor; + Scalar pV = volVars.pressure(FluidSystem::gasPhaseIdx) *moleFractionVapor; Scalar vaporPressure = pV*1.0e-5; Scalar pFactor = log(vaporPressure); Teq = -12845; Teq /= (pFactor - 16.508); //the equilibrium temperature - Scalar realSolidDensityAverage = (volVars.precipitateVolumeFraction(hPhaseIdx)*volVars.density(hPhaseIdx) - + volVars.precipitateVolumeFraction(cPhaseIdx)*volVars.density(cPhaseIdx)) - / (volVars.precipitateVolumeFraction(hPhaseIdx) - + volVars.precipitateVolumeFraction(cPhaseIdx)); + Scalar realSolidDensityAverage = (volVars.precipitateVolumeFraction(FluidSystem::hPhaseIdx)*volVars.density(FluidSystem::hPhaseIdx) + + volVars.precipitateVolumeFraction(FluidSystem::cPhaseIdx)*volVars.density(FluidSystem::cPhaseIdx)) + / (volVars.precipitateVolumeFraction(FluidSystem::hPhaseIdx) + + volVars.precipitateVolumeFraction(FluidSystem::cPhaseIdx)); - if(realSolidDensityAverage <= volVars.density(cPhaseIdx)) + if(realSolidDensityAverage <= volVars.density(FluidSystem::cPhaseIdx)) { - realSolidDensityAverage = volVars.density(cPhaseIdx); + realSolidDensityAverage = volVars.density(FluidSystem::cPhaseIdx); } - if(realSolidDensityAverage >= volVars.density(hPhaseIdx)) + if(realSolidDensityAverage >= volVars.density(FluidSystem::hPhaseIdx)) { - realSolidDensityAverage = volVars.density(hPhaseIdx); + realSolidDensityAverage = volVars.density(FluidSystem::hPhaseIdx); } Scalar qMass = 0.0; @@ -108,7 +87,7 @@ public: Scalar dXH_dt1 = 0.0; Scalar dXH_dt2 = 0.0; - Scalar xH = (realSolidDensityAverage-volVars.density(cPhaseIdx))/(volVars.density(hPhaseIdx)- volVars.density(cPhaseIdx)); + Scalar xH = (realSolidDensityAverage-volVars.density(FluidSystem::cPhaseIdx))/(volVars.density(FluidSystem::hPhaseIdx)- volVars.density(FluidSystem::cPhaseIdx)); if(xH < 1.0e-5) {xH = 1.0e-5; } if(xH >=1 ) {xH = 1 - 1e-5; } @@ -164,7 +143,7 @@ public: // no reaction at equilibrium if(Teq -T <= 0) dXH_dt = 0; - Scalar deltaRhoS = volVars.density(hPhaseIdx) - volVars.density(cPhaseIdx); + Scalar deltaRhoS = volVars.density(FluidSystem::hPhaseIdx) - volVars.density(FluidSystem::cPhaseIdx); qMass = dXH_dt*deltaRhoS; } @@ -175,49 +154,54 @@ public: /*! * \brief evaluates the simple chemical reaction kinetics (see Nagel et al. 2014) */ - Scalar thermoChemReactionSimple(const VolumeVariables &volVars) const + template<class VolumeVariables> + typename VolumeVariables::PrimaryVariables::value_type + thermoChemReactionSimple(const VolumeVariables &volVars) const { + using FluidSystem = typename VolumeVariables::FluidSystem; + using Scalar = typename VolumeVariables::PrimaryVariables::value_type; + // calculate the equilibrium temperature Teq Scalar T= volVars.temperature(); Scalar Teq = 0; Scalar moleFractionVapor = 1e-3; - if(volVars.moleFraction(phaseIdx, firstMoleFracIdx) > 1e-3) - moleFractionVapor = volVars.moleFraction(phaseIdx, firstMoleFracIdx); + if(volVars.moleFraction(FluidSystem::gasPhaseIdx, FluidSystem::H2OIdx) > 1e-3) + moleFractionVapor = volVars.moleFraction(FluidSystem::gasPhaseIdx, FluidSystem::H2OIdx); - if(volVars.moleFraction(phaseIdx, firstMoleFracIdx) >= 1.0) moleFractionVapor = 1; + if(volVars.moleFraction(FluidSystem::gasPhaseIdx, FluidSystem::H2OIdx) >= 1.0) moleFractionVapor = 1; - Scalar pV = volVars.pressure(phaseIdx) *moleFractionVapor; + Scalar pV = volVars.pressure(FluidSystem::gasPhaseIdx) *moleFractionVapor; Scalar vaporPressure = pV*1.0e-5; Scalar pFactor = log(vaporPressure); Teq = -12845; Teq /= (pFactor - 16.508); //the equilibrium temperature - Scalar realSolidDensityAverage = (volVars.precipitateVolumeFraction(hPhaseIdx)*volVars.density(hPhaseIdx) - + volVars.precipitateVolumeFraction(cPhaseIdx)*volVars.density(cPhaseIdx)) - / (volVars.precipitateVolumeFraction(hPhaseIdx) - + volVars.precipitateVolumeFraction(cPhaseIdx)); + Scalar realSolidDensityAverage = (volVars.precipitateVolumeFraction(FluidSystem::hPhaseIdx)*volVars.density(FluidSystem::hPhaseIdx) + + volVars.precipitateVolumeFraction(FluidSystem::cPhaseIdx)*volVars.density(FluidSystem::cPhaseIdx)) + / (volVars.precipitateVolumeFraction(FluidSystem::hPhaseIdx) + + volVars.precipitateVolumeFraction(FluidSystem::cPhaseIdx)); - if(realSolidDensityAverage <= volVars.density(cPhaseIdx)) + if(realSolidDensityAverage <= volVars.density(FluidSystem::cPhaseIdx)) { - realSolidDensityAverage = volVars.density(cPhaseIdx); + realSolidDensityAverage = volVars.density(FluidSystem::cPhaseIdx); } - if(realSolidDensityAverage >= volVars.density(hPhaseIdx)) + if(realSolidDensityAverage >= volVars.density(FluidSystem::hPhaseIdx)) { - realSolidDensityAverage = volVars.density(hPhaseIdx); + realSolidDensityAverage = volVars.density(FluidSystem::hPhaseIdx); } Scalar qMass = 0.0; //discharge or hydration if (T < Teq){ - Scalar massFracH2O_fPhase = volVars.massFraction(phaseIdx, firstMoleFracIdx); + Scalar massFracH2O_fPhase = volVars.massFraction(FluidSystem::gasPhaseIdx, FluidSystem::H2OIdx); Scalar krh = 0.2; - Scalar rHydration = - massFracH2O_fPhase* (volVars.density(hPhaseIdx)- realSolidDensityAverage) + Scalar rHydration = - massFracH2O_fPhase* (volVars.density(FluidSystem::hPhaseIdx)- realSolidDensityAverage) * krh * (T-Teq)/ Teq; Scalar qMass = rHydration; @@ -228,7 +212,7 @@ public: Scalar krd = 0.05; - Scalar rDehydration = -(volVars.density(cPhaseIdx)- realSolidDensityAverage) + Scalar rDehydration = -(volVars.density(FluidSystem::cPhaseIdx)- realSolidDensityAverage) * krd * (Teq-T)/ Teq; qMass = rDehydration; diff --git a/test/porousmediumflow/2p/implicit/fracture/problem.hh b/test/porousmediumflow/2p/implicit/fracture/problem.hh index eb7b950c7e10389a02ccf0686d7911003d912115..4d9f46f896d75212166f7d400edab002518ee220 100644 --- a/test/porousmediumflow/2p/implicit/fracture/problem.hh +++ b/test/porousmediumflow/2p/implicit/fracture/problem.hh @@ -74,7 +74,7 @@ SET_BOOL_PROP(FractureTypeTag, EnableGridFluxVariablesCache, true); // permeablility is solution-independent SET_BOOL_PROP(FractureTypeTag, SolutionDependentAdvection, false); -} +} // end namespace Properties /*! * \ingroup TwoPTests @@ -93,14 +93,14 @@ class FractureProblem : public PorousMediumFlowProblem<TypeTag> using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector); - enum { - + enum + { // primary variable indices - pwIdx = Indices::pwIdx, - snIdx = Indices::snIdx, + pressureIdx = Indices::pressureIdx, + saturationIdx = Indices::saturationIdx, // equation indices - contiNEqIdx = Indices::conti0EqIdx + FluidSystem::nPhaseIdx, + contiTCEEqIdx = Indices::conti0EqIdx + FluidSystem::comp1Idx, // world dimension dimWorld = GridView::dimensionworld @@ -194,8 +194,8 @@ public: const auto g = this->gravityAtPos(globalPos)[dimWorld-1]; PrimaryVariables values; - values[pwIdx] = 1e5 + 1000*g*depth; - values[snIdx] = 0.0; + values[pressureIdx] = 1e5 + 1000*g*depth; + values[saturationIdx] = 0.0; return values; } @@ -214,7 +214,7 @@ public: { NumEqVector values(0.0); if (onInlet_(globalPos)) { - values[contiNEqIdx] = -0.04; // kg / (m * s) + values[contiTCEEqIdx] = -0.04; // kg / (m * s) } return values; } diff --git a/test/porousmediumflow/2p/implicit/fracture/spatialparams.hh b/test/porousmediumflow/2p/implicit/fracture/spatialparams.hh index 6d5807dba411e148ec3da6defa598d3407edc503..b562d853be036fdcfa51dbcbba9bb8d2fd3607bd 100644 --- a/test/porousmediumflow/2p/implicit/fracture/spatialparams.hh +++ b/test/porousmediumflow/2p/implicit/fracture/spatialparams.hh @@ -120,6 +120,16 @@ public: const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const { return materialParams_; } + /*! + * \brief Function for defining which phase is to be considered as the wetting phase. + * + * \return the wetting phase index + * \param globalPos The global position + */ + template<class FluidSystem> + int wettingPhaseAtPos(const GlobalPosition& globalPos) const + { return FluidSystem::phase0Idx; } + private: MaterialLawParams materialParams_; }; diff --git a/test/porousmediumflow/2p/implicit/incompressible/problem.hh b/test/porousmediumflow/2p/implicit/incompressible/problem.hh index 655ea8d7e91dfdc3a1b2de4b283a06f5cb6d7dfb..26e44a4e4db8bc22b6e655d7bffab1b417e1eab6 100644 --- a/test/porousmediumflow/2p/implicit/incompressible/problem.hh +++ b/test/porousmediumflow/2p/implicit/incompressible/problem.hh @@ -93,9 +93,11 @@ class TwoPTestProblem : public PorousMediumFlowProblem<TypeTag> using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector); using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; enum { - pwIdx = Indices::pwIdx, - snIdx = Indices::snIdx, - contiNEqIdx = Indices::conti0EqIdx + FluidSystem::nPhaseIdx + pressureH2OIdx = Indices::pressureIdx, + saturationDNAPLIdx = Indices::saturationIdx, + contiDNAPLEqIdx = Indices::conti0EqIdx + FluidSystem::comp1Idx, + waterPhaseIdx = FluidSystem::phase0Idx, + dnaplPhaseIdx = FluidSystem::phase1Idx }; public: @@ -132,10 +134,10 @@ public: PrimaryVariables values; typename GET_PROP_TYPE(TypeTag, FluidState) fluidState; fluidState.setTemperature(temperature()); - fluidState.setPressure(FluidSystem::wPhaseIdx, /*pressure=*/1e5); - fluidState.setPressure(FluidSystem::nPhaseIdx, /*pressure=*/1e5); + fluidState.setPressure(waterPhaseIdx, /*pressure=*/1e5); + fluidState.setPressure(dnaplPhaseIdx, /*pressure=*/1e5); - Scalar densityW = FluidSystem::density(fluidState, FluidSystem::wPhaseIdx); + Scalar densityW = FluidSystem::density(fluidState, waterPhaseIdx); Scalar height = this->fvGridGeometry().bBoxMax()[1] - this->fvGridGeometry().bBoxMin()[1]; Scalar depth = this->fvGridGeometry().bBoxMax()[1] - globalPos[1]; @@ -144,8 +146,8 @@ public: Scalar factor = (width*alpha + (1.0 - alpha)*globalPos[0])/width; // hydrostatic pressure scaled by alpha - values[pwIdx] = 1e5 - factor*densityW*this->gravity()[1]*depth; - values[snIdx] = 0.0; + values[pressureH2OIdx] = 1e5 - factor*densityW*this->gravity()[1]*depth; + values[saturationDNAPLIdx] = 0.0; return values; } @@ -165,7 +167,7 @@ public: { NumEqVector values(0.0); if (onInlet_(globalPos)) - values[contiNEqIdx] = -0.04; // kg / (m * s) + values[contiDNAPLEqIdx] = -0.04; // kg / (m * s) return values; } @@ -181,16 +183,16 @@ public: PrimaryVariables values; typename GET_PROP_TYPE(TypeTag, FluidState) fluidState; fluidState.setTemperature(temperature()); - fluidState.setPressure(FluidSystem::wPhaseIdx, /*pressure=*/1e5); - fluidState.setPressure(FluidSystem::nPhaseIdx, /*pressure=*/1e5); + fluidState.setPressure(waterPhaseIdx, /*pressure=*/1e5); + fluidState.setPressure(dnaplPhaseIdx, /*pressure=*/1e5); - Scalar densityW = FluidSystem::density(fluidState, FluidSystem::wPhaseIdx); + Scalar densityW = FluidSystem::density(fluidState, waterPhaseIdx); Scalar depth = this->fvGridGeometry().bBoxMax()[1] - globalPos[1]; // hydrostatic pressure - values[pwIdx] = 1e5 - densityW*this->gravity()[1]*depth; - values[snIdx] = 0.0; + values[pressureH2OIdx] = 1e5 - densityW*this->gravity()[1]*depth; + values[saturationDNAPLIdx] = 0; return values; } diff --git a/test/porousmediumflow/2p/implicit/incompressible/spatialparams.hh b/test/porousmediumflow/2p/implicit/incompressible/spatialparams.hh index e89f0f8fa3c89ba23afea40591e6d8b76e8b5655..d13ad5538855c8e0596a6b643bb28fa65483db4f 100644 --- a/test/porousmediumflow/2p/implicit/incompressible/spatialparams.hh +++ b/test/porousmediumflow/2p/implicit/incompressible/spatialparams.hh @@ -148,6 +148,16 @@ public: return outerMaterialParams_; } + /*! + * \brief Function for defining which phase is to be considered as the wetting phase. + * + * \return the wetting phase index + * \param globalPos The global position + */ + template<class FluidSystem> + int wettingPhaseAtPos(const GlobalPosition& globalPos) const + { return FluidSystem::phase0Idx; } + private: bool isInLens_(const GlobalPosition &globalPos) const { diff --git a/test/porousmediumflow/2p1c/implicit/steaminjectionproblem.hh b/test/porousmediumflow/2p1c/implicit/steaminjectionproblem.hh index af3f92bbfb94b14a647a9e0ff350b456a891c54b..e0944b388cb757f8a47516b09dc307540fa3d290 100644 --- a/test/porousmediumflow/2p1c/implicit/steaminjectionproblem.hh +++ b/test/porousmediumflow/2p1c/implicit/steaminjectionproblem.hh @@ -37,13 +37,11 @@ #include "steaminjectionspatialparams.hh" -namespace Dumux -{ +namespace Dumux { template <class TypeTag> class InjectionProblem; -namespace Properties -{ +namespace Properties { NEW_TYPE_TAG(InjectionProblemTypeTag, INHERITS_FROM(TwoPOneCNI, InjectionProblemSpatialParams)); NEW_TYPE_TAG(TwoPOneCNIBoxTypeTag, INHERITS_FROM(BoxModel, InjectionProblemTypeTag)); NEW_TYPE_TAG(TwoPOneCNICCTpfaTypeTag, INHERITS_FROM(CCTpfaModel, InjectionProblemTypeTag)); @@ -67,7 +65,7 @@ public: //Define whether spurious cold-water flow into the steam is blocked SET_BOOL_PROP(InjectionProblemTypeTag, UseBlockingOfSpuriousFlow, true); -} +} // end namespace Properties /*! * \ingroup TwoPOneCTests @@ -104,7 +102,7 @@ class InjectionProblem : public PorousMediumFlowProblem<TypeTag> energyEqIdx = Indices::energyEqIdx, // phase state - wPhaseOnly = Indices::wPhaseOnly + liquidPhaseOnly = Indices::liquidPhaseOnly }; static constexpr int dimWorld = GridView::dimensionworld; @@ -231,7 +229,7 @@ public: values[pressureIdx] = 101300.0 + (this->fvGridGeometry().bBoxMax()[1] - globalPos[1])*densityW*9.81; // hydrostatic pressure values[switchIdx] = 283.13; - values.setState(wPhaseOnly); + values.setState(liquidPhaseOnly); return values; } diff --git a/test/porousmediumflow/2p2c/implicit/injectionproblem.hh b/test/porousmediumflow/2p2c/implicit/injectionproblem.hh index 0b64b8bbc5fdc8efa7383b3cbeaa6b5a87e1611f..f2ca76aaf945cb23028d162cfe00c0856453b0ba 100644 --- a/test/porousmediumflow/2p2c/implicit/injectionproblem.hh +++ b/test/porousmediumflow/2p2c/implicit/injectionproblem.hh @@ -34,8 +34,7 @@ #include "injectionspatialparams.hh" -namespace Dumux -{ +namespace Dumux { #ifndef ENABLECACHING #define ENABLECACHING 0 @@ -44,8 +43,7 @@ namespace Dumux template <class TypeTag> class InjectionProblem; -namespace Properties -{ +namespace Properties { NEW_TYPE_TAG(InjectionTypeTag, INHERITS_FROM(TwoPTwoC, InjectionSpatialParams)); NEW_TYPE_TAG(InjectionBoxTypeTag, INHERITS_FROM(BoxModel, InjectionTypeTag)); NEW_TYPE_TAG(InjectionCCTpfaTypeTag, INHERITS_FROM(CCTpfaModel, InjectionTypeTag)); @@ -69,8 +67,7 @@ SET_BOOL_PROP(InjectionTypeTag, UseMoles, true); SET_BOOL_PROP(InjectionTypeTag, EnableFVGridGeometryCache, ENABLECACHING); SET_BOOL_PROP(InjectionTypeTag, EnableGridVolumeVariablesCache, ENABLECACHING); SET_BOOL_PROP(InjectionTypeTag, EnableGridFluxVariablesCache, ENABLECACHING); -} - +} // end namespace Properties /*! * \ingroup TwoPTwoCTests @@ -114,21 +111,21 @@ class InjectionProblem : public PorousMediumFlowProblem<TypeTag> }; // phase presence - enum { wPhaseOnly = Indices::wPhaseOnly }; + enum { wPhaseOnly = Indices::firstPhaseOnly }; // equation indices enum { - contiH2OEqIdx = Indices::contiWEqIdx, - contiN2EqIdx = Indices::contiNEqIdx + contiH2OEqIdx = Indices::conti0EqIdx + FluidSystem::H2OIdx, + contiN2EqIdx = Indices::conti0EqIdx + FluidSystem::N2Idx, }; // phase indices enum { - nPhaseIdx = FluidSystem::nPhaseIdx, - wCompIdx = FluidSystem::wCompIdx, - nCompIdx = FluidSystem::nCompIdx + gasPhaseIdx = FluidSystem::N2Idx, + H2OIdx = FluidSystem::H2OIdx, + N2Idx = FluidSystem::N2Idx }; using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); @@ -262,11 +259,11 @@ public: const auto& globalPos = scvf.ipGlobal(); Scalar injectedPhaseMass = 1e-3; - Scalar moleFracW = elemVolVars[scvf.insideScvIdx()].moleFraction(nPhaseIdx, wCompIdx); + Scalar moleFracW = elemVolVars[scvf.insideScvIdx()].moleFraction(gasPhaseIdx, H2OIdx); if (globalPos[1] < 14 - eps_ && globalPos[1] > 6.5 - eps_) { - values[contiN2EqIdx] = -(1-moleFracW)*injectedPhaseMass/FluidSystem::molarMass(nCompIdx); //mole/(m^2*s) -> kg/(s*m^2) - values[contiH2OEqIdx] = -moleFracW*injectedPhaseMass/FluidSystem::molarMass(wCompIdx); //mole/(m^2*s) -> kg/(s*m^2) + values[contiN2EqIdx] = -(1-moleFracW)*injectedPhaseMass/FluidSystem::molarMass(N2Idx); //mole/(m^2*s) -> kg/(s*m^2) + values[contiH2OEqIdx] = -moleFracW*injectedPhaseMass/FluidSystem::molarMass(H2OIdx); //mole/(m^2*s) -> kg/(s*m^2) } return values; } @@ -312,8 +309,8 @@ private: Scalar moleFracLiquidH2O = 1.0 - moleFracLiquidN2; Scalar meanM = - FluidSystem::molarMass(wCompIdx)*moleFracLiquidH2O + - FluidSystem::molarMass(nCompIdx)*moleFracLiquidN2; + FluidSystem::molarMass(H2OIdx)*moleFracLiquidH2O + + FluidSystem::molarMass(N2Idx)*moleFracLiquidN2; if(useMoles) { //mole-fraction formulation @@ -322,7 +319,7 @@ private: else { //mass fraction formulation - Scalar massFracLiquidN2 = moleFracLiquidN2*FluidSystem::molarMass(nCompIdx)/meanM; + Scalar massFracLiquidN2 = moleFracLiquidN2*FluidSystem::molarMass(N2Idx)/meanM; priVars[switchIdx] = massFracLiquidN2; } priVars[pressureIdx] = pl; diff --git a/test/porousmediumflow/2p2c/implicit/injectionspatialparams.hh b/test/porousmediumflow/2p2c/implicit/injectionspatialparams.hh index c3f5d7082d71c342bad074de65e788eaa4a1ee5c..8e7a4e44efb6b3a0b2b88a242a51755bacb73ad5 100644 --- a/test/porousmediumflow/2p2c/implicit/injectionspatialparams.hh +++ b/test/porousmediumflow/2p2c/implicit/injectionspatialparams.hh @@ -180,6 +180,16 @@ public: Scalar solidThermalConductivityAtPos(const GlobalPosition& globalPos) const { return lambdaSolid_; } + /*! + * \brief Function for defining which phase is to be considered as the wetting phase. + * + * \return the wetting phase index + * \param globalPos The position of the center of the element + */ + template<class FluidSystem> + int wettingPhaseAtPos(const GlobalPosition& globalPos) const + { return FluidSystem::H2OIdx; } + private: bool isFineMaterial_(const GlobalPosition &globalPos) const { return globalPos[dimWorld-1] > layerBottom_; } diff --git a/test/porousmediumflow/2p2c/implicit/mpnccomparison/2p2c_comparison_problem.hh b/test/porousmediumflow/2p2c/implicit/mpnccomparison/2p2c_comparison_problem.hh index be0c835ec25961334e76687af69dfbae757b39b3..04dc86ba0ca3ce3ea57621640219c50b203cca69 100644 --- a/test/porousmediumflow/2p2c/implicit/mpnccomparison/2p2c_comparison_problem.hh +++ b/test/porousmediumflow/2p2c/implicit/mpnccomparison/2p2c_comparison_problem.hh @@ -71,7 +71,7 @@ SET_TYPE_PROP(TwoPTwoCComparisonTypeTag, Scalar, double); SET_PROP(TwoPTwoCComparisonTypeTag, Formulation) { public: - static const TwoPFormulation value = TwoPFormulation::pnsw; + static const TwoPFormulation value = TwoPFormulation::p1s0; }; SET_BOOL_PROP(TwoPTwoCComparisonTypeTag, UseMoles, true); @@ -105,23 +105,6 @@ class TwoPTwoCComparisonProblem : public PorousMediumFlowProblem<TypeTag> using ModelTraits = typename GET_PROP_TYPE(TypeTag, ModelTraits); using Indices = typename ModelTraits::Indices; - // world dimension - enum {numPhases = ModelTraits::numPhases()}; - enum {numComponents = ModelTraits::numComponents()}; - enum {nPhaseIdx = FluidSystem::nPhaseIdx}; - enum {wPhaseIdx = FluidSystem::wPhaseIdx}; - enum {wCompIdx = FluidSystem::wCompIdx}; - enum {nCompIdx = FluidSystem::nCompIdx}; - enum - { - pressureIdx = Indices::pressureIdx, - switchIdx = Indices::switchIdx, - contiH2OEqIdx = Indices::contiWEqIdx, - contiN2EqIdx = Indices::contiNEqIdx - }; - - static constexpr bool isBox = GET_PROP_TYPE(TypeTag, FVGridGeometry)::discMethod == DiscretizationMethod::box; - public: /*! * \brief The constructor @@ -218,11 +201,9 @@ public: NeumannFluxes values(0.0); const auto& globalPos = scvf.ipGlobal(); Scalar injectedAirMass = -1e-3; - Scalar injectedAirMolarMass = injectedAirMass/FluidSystem::molarMass(nCompIdx); + Scalar injectedAirMolarMass = injectedAirMass/FluidSystem::molarMass(FluidSystem::N2Idx); if (onInlet_(globalPos)) - { - values[Indices::conti0EqIdx+1] = injectedAirMolarMass; - } + values[Indices::conti0EqIdx + FluidSystem::N2Idx] = injectedAirMolarMass; return values; } @@ -249,8 +230,8 @@ private: PrimaryVariables initial_(const GlobalPosition &globalPos) const { PrimaryVariables values(0.0); - values[pressureIdx] = 1e5; - values[switchIdx] = 0.8; + values[Indices::pressureIdx] = 1e5; // air pressure + values[Indices::switchIdx] = 0.8; // water saturation values.setState(Indices::bothPhases); return values; diff --git a/test/porousmediumflow/2p2c/implicit/mpnccomparison/2p2c_comparison_spatialparams.hh b/test/porousmediumflow/2p2c/implicit/mpnccomparison/2p2c_comparison_spatialparams.hh index 9573b1ac77f473072fb34175360b1ee20da92cd0..9800b5a6b210b7547b9da36bb07a0252b9d484df 100644 --- a/test/porousmediumflow/2p2c/implicit/mpnccomparison/2p2c_comparison_spatialparams.hh +++ b/test/porousmediumflow/2p2c/implicit/mpnccomparison/2p2c_comparison_spatialparams.hh @@ -154,6 +154,16 @@ public: return coarseMaterialParams_; } + /*! + * \brief Function for defining which phase is to be considered as the wetting phase. + * + * \return the wetting phase index + * \param globalPos The position of the center of the element + */ + template<class FluidSystem> + int wettingPhaseAtPos(const GlobalPosition& globalPos) const + { return FluidSystem::H2OIdx; } + private: /*! * \brief Returns whether a given global position is in the diff --git a/test/porousmediumflow/2p2c/implicit/mpnccomparison/vtkoutputfields.hh b/test/porousmediumflow/2p2c/implicit/mpnccomparison/vtkoutputfields.hh index 697a8ed7f8f1a0e9495ebffabae91a81d24a192e..038c4b4a814f47291f9b84850da206a32b85ae16 100644 --- a/test/porousmediumflow/2p2c/implicit/mpnccomparison/vtkoutputfields.hh +++ b/test/porousmediumflow/2p2c/implicit/mpnccomparison/vtkoutputfields.hh @@ -24,10 +24,7 @@ #ifndef DUMUX_TWOPTWOC_MPNC_VTK_OUTPUT_FIELDS_HH #define DUMUX_TWOPTWOC_MPNC_VTK_OUTPUT_FIELDS_HH -#include <dumux/common/properties.hh> - -namespace Dumux -{ +namespace Dumux { /*! * \ingroup TwoPTwoCModel @@ -44,15 +41,15 @@ public: // register standardized vtk output fields vtk.addVolumeVariable([](const auto& v){ return v.porosity(); }, "porosity"); - vtk.addVolumeVariable([](const auto& v){ return v.saturation(FluidSystem::nPhaseIdx); }, "Sn"); - vtk.addVolumeVariable([](const auto& v){ return v.saturation(FluidSystem::wPhaseIdx); }, "Sw"); - vtk.addVolumeVariable([](const auto& v){ return v.pressure(FluidSystem::nPhaseIdx); }, "pn"); - vtk.addVolumeVariable([](const auto& v){ return v.pressure(FluidSystem::wPhaseIdx); }, "pw"); + vtk.addVolumeVariable([](const auto& v){ return v.saturation(FluidSystem::phase1Idx); }, "Sn"); + vtk.addVolumeVariable([](const auto& v){ return v.saturation(FluidSystem::phase0Idx); }, "Sw"); + vtk.addVolumeVariable([](const auto& v){ return v.pressure(FluidSystem::phase1Idx); }, "pn"); + vtk.addVolumeVariable([](const auto& v){ return v.pressure(FluidSystem::phase0Idx); }, "pw"); - vtk.addVolumeVariable([](const auto& v){ return v.density(FluidSystem::wPhaseIdx); }, "rhoW"); - vtk.addVolumeVariable([](const auto& v){ return v.density(FluidSystem::nPhaseIdx); }, "rhoN"); - vtk.addVolumeVariable([](const auto& v){ return v.mobility(FluidSystem::wPhaseIdx); }, "mobW"); - vtk.addVolumeVariable([](const auto& v){ return v.mobility(FluidSystem::nPhaseIdx); }, "mobN"); + vtk.addVolumeVariable([](const auto& v){ return v.density(FluidSystem::phase0Idx); }, "rhoW"); + vtk.addVolumeVariable([](const auto& v){ return v.density(FluidSystem::phase1Idx); }, "rhoN"); + vtk.addVolumeVariable([](const auto& v){ return v.mobility(FluidSystem::phase0Idx); }, "mobW"); + vtk.addVolumeVariable([](const auto& v){ return v.mobility(FluidSystem::phase1Idx); }, "mobN"); for (int i = 0; i < VolumeVariables::numPhases(); ++i) for (int j = 0; j < VolumeVariables::numComponents(); ++j) diff --git a/test/porousmediumflow/2p2c/implicit/waterairproblem.hh b/test/porousmediumflow/2p2c/implicit/waterairproblem.hh index b46df02fc42d82dc6a4f4a554c86fcd3307ea1d6..983fcd2e1a54faf2dc4c53fc3bd4d78fcdf9cd85 100644 --- a/test/porousmediumflow/2p2c/implicit/waterairproblem.hh +++ b/test/porousmediumflow/2p2c/implicit/waterairproblem.hh @@ -36,8 +36,7 @@ #include "waterairspatialparams.hh" -namespace Dumux -{ +namespace Dumux { /*! * \ingroup TwoPTwoCTests * \brief Non-isothermal gas injection problem where a gas (e.g. air) @@ -46,8 +45,7 @@ namespace Dumux template <class TypeTag> class WaterAirProblem; -namespace Properties -{ +namespace Properties { NEW_TYPE_TAG(WaterAirTypeTag, INHERITS_FROM(TwoPTwoCNI, WaterAirSpatialParams)); NEW_TYPE_TAG(WaterAirBoxTypeTag, INHERITS_FROM(BoxModel, WaterAirTypeTag)); NEW_TYPE_TAG(WaterAirCCTpfaTypeTag, INHERITS_FROM(CCTpfaModel, WaterAirTypeTag)); @@ -63,8 +61,7 @@ SET_TYPE_PROP(WaterAirTypeTag, FluidSystem, FluidSystems::H2ON2<typename GET_PRO // Define whether mole(true) or mass (false) fractions are used SET_BOOL_PROP(WaterAirTypeTag, UseMoles, true); -} - +} // end namespace Dumux /*! * \ingroup TwoPTwoCModel @@ -123,14 +120,14 @@ class WaterAirProblem : public PorousMediumFlowProblem<TypeTag> // equation indices enum { - conti0EqIdx = Indices::conti0EqIdx, - contiNEqIdx = Indices::contiNEqIdx + contiH2OEqIdx = Indices::conti0EqIdx + FluidSystem::H2OIdx, + contiN2EqIdx = Indices::conti0EqIdx + FluidSystem::N2Idx }; // phase presence - enum { wPhaseOnly = Indices::wPhaseOnly }; + enum { wPhaseOnly = Indices::firstPhaseOnly }; // component index - enum { nCompIdx = FluidSystem::nCompIdx }; + enum { N2Idx = FluidSystem::N2Idx }; using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector); @@ -234,7 +231,7 @@ public: // we inject pure gasious nitrogen at the initial condition temperature and pressure from the bottom (negative values mean injection) if (globalPos[0] > 14.8 - eps_ && globalPos[0] < 25.2 + eps_ && globalPos[1] < eps_) { - values[contiNEqIdx] = useMoles ? -1e-3/FluidSystem::molarMass(nCompIdx) : -1e-3; // kg/(m^2*s) or mole/(m^2*s) + values[contiN2EqIdx] = useMoles ? -1e-3/FluidSystem::molarMass(N2Idx) : -1e-3; // kg/(m^2*s) or mole/(m^2*s) const auto initialValues = initial_(globalPos); const auto& mParams = this->spatialParams().materialLawParamsAtPos(globalPos); diff --git a/test/porousmediumflow/2p2c/implicit/waterairspatialparams.hh b/test/porousmediumflow/2p2c/implicit/waterairspatialparams.hh index 5f4057f04e7e33fb253a929dd6e9cf1222595b5c..cce22dd6d78ecb1550e810d99d9222fd38f7ef65 100644 --- a/test/porousmediumflow/2p2c/implicit/waterairspatialparams.hh +++ b/test/porousmediumflow/2p2c/implicit/waterairspatialparams.hh @@ -222,6 +222,16 @@ public: Scalar solidThermalConductivityAtPos(const GlobalPosition& globalPos) const { return lambdaSolid_; } + /*! + * \brief Function for defining which phase is to be considered as the wetting phase. + * + * \return the wetting phase index + * \param globalPos The position of the center of the element + */ + template<class FluidSystem> + int wettingPhaseAtPos(const GlobalPosition& globalPos) const + { return FluidSystem::H2OIdx; } + private: bool isFineMaterial_(const GlobalPosition &globalPos) const { return globalPos[dimWorld-1] > layerBottom_; } diff --git a/test/porousmediumflow/2pnc/implicit/2pncdiffusionproblem.hh b/test/porousmediumflow/2pnc/implicit/2pncdiffusionproblem.hh index b5aeee0c8a93d24334544448a607c8fbb2824a15..aaf0a9653ea7b2ae97bf84019699874e0c6499f5 100644 --- a/test/porousmediumflow/2pnc/implicit/2pncdiffusionproblem.hh +++ b/test/porousmediumflow/2pnc/implicit/2pncdiffusionproblem.hh @@ -67,7 +67,7 @@ SET_TYPE_PROP(TwoPNCDiffusionTypeTag, MolecularDiffusionType, DIFFUSIONTYPE); //! Set the default formulation to pw-Sn: This can be over written in the problem. SET_PROP(TwoPNCDiffusionTypeTag, Formulation) -{ static constexpr auto value = TwoPFormulation::pwsn; }; +{ static constexpr auto value = TwoPFormulation::p0s1; }; } // end namespace Properties @@ -90,24 +90,7 @@ class TwoPNCDiffusionProblem : public PorousMediumFlowProblem<TypeTag> dimWorld = GridView::dimensionworld }; - // copy some indices for convenience using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; - enum { - pressureIdx = Indices::pressureIdx, - switchIdx = Indices::switchIdx, - - wPhaseIdx = FluidSystem::wPhaseIdx, - nPhaseIdx = FluidSystem::nPhaseIdx, - - wCompIdx = FluidSystem::wCompIdx, - nCompIdx = FluidSystem::nCompIdx, - - wPhaseOnly = Indices::wPhaseOnly, - - contiH2OEqIdx = Indices::conti0EqIdx + wCompIdx, - contiN2EqIdx = Indices::conti0EqIdx + nCompIdx - }; - using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector); using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); @@ -194,12 +177,12 @@ public: PrimaryVariables dirichletAtPos(const GlobalPosition &globalPos) const { PrimaryVariables priVars; - priVars.setState(wPhaseOnly); - priVars[pressureIdx] = 1e5; - priVars[switchIdx] = 1e-5 ; + priVars.setState(Indices::firstPhaseOnly); + priVars[Indices::pressureIdx] = 1e5; + priVars[Indices::switchIdx] = 1e-5 ; if (globalPos[0] < this->fvGridGeometry().bBoxMin()[0] + eps_) - priVars[switchIdx] = 1e-3; + priVars[Indices::switchIdx] = 1e-3; return priVars; } @@ -254,11 +237,11 @@ private: PrimaryVariables initial_(const GlobalPosition &globalPos) const { PrimaryVariables priVars(0.0); - priVars.setState(wPhaseOnly); + priVars.setState(Indices::firstPhaseOnly); //mole-fraction formulation - priVars[switchIdx] = 1e-5; - priVars[pressureIdx] = 1e5; + priVars[Indices::switchIdx] = 1e-5; + priVars[Indices::pressureIdx] = 1e5; return priVars; } diff --git a/test/porousmediumflow/2pnc/implicit/2pncdiffusionspatialparams.hh b/test/porousmediumflow/2pnc/implicit/2pncdiffusionspatialparams.hh index 554dcfd07f795867d87bd361279d11b787ab345b..eb7a7abb6b2b8c26a2c3ec021ce817e59f716170 100644 --- a/test/porousmediumflow/2pnc/implicit/2pncdiffusionspatialparams.hh +++ b/test/porousmediumflow/2pnc/implicit/2pncdiffusionspatialparams.hh @@ -136,6 +136,16 @@ public: const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const { return materialParams_; } + /*! + * \brief Function for defining which phase is to be considered as the wetting phase. + * + * \return the wetting phase index + * \param globalPos The position of the center of the element + */ + template<class FluidSystem> + int wettingPhaseAtPos(const GlobalPosition& globalPos) const + { return FluidSystem::H2OIdx; } + private: DimWorldMatrix K_; Scalar porosity_; diff --git a/test/porousmediumflow/2pnc/implicit/fuelcellproblem.hh b/test/porousmediumflow/2pnc/implicit/fuelcellproblem.hh index 4457ae325ef688e90843d30b8f49afe2d5d413a9..62d710d797b99781ff8bb85d5c4b1a77afd15580 100644 --- a/test/porousmediumflow/2pnc/implicit/fuelcellproblem.hh +++ b/test/porousmediumflow/2pnc/implicit/fuelcellproblem.hh @@ -55,7 +55,7 @@ SET_TYPE_PROP(FuelCellTypeTag, Grid, Dune::YaspGrid<2>); SET_TYPE_PROP(FuelCellTypeTag, Problem, FuelCellProblem<TypeTag>); // Set the primary variable combination for the 2pnc model SET_PROP(FuelCellTypeTag, Formulation) -{ static constexpr auto value = TwoPFormulation::pnsw; }; +{ static constexpr auto value = TwoPFormulation::p1s0; }; // Set fluid configuration SET_PROP(FuelCellTypeTag, FluidSystem) @@ -98,19 +98,6 @@ class FuelCellProblem : public PorousMediumFlowProblem<TypeTag> // Select the electrochemistry method using ElectroChemistry = typename Dumux::ElectroChemistry<Scalar, Indices, FluidSystem, FVGridGeometry, ElectroChemistryModel::Ochs>; - enum { numComponents = FluidSystem::numComponents }; - - enum { wPhaseIdx = FluidSystem::wPhaseIdx }; - - enum { bothPhases = Indices::bothPhases }; - - // privar indices - enum - { - pressureIdx = Indices::pressureIdx, //gas-phase pressure - switchIdx = Indices::switchIdx //liquid saturation or mole fraction - }; - static constexpr int dim = GridView::dimension; static constexpr int dimWorld = GridView::dimensionworld; static constexpr bool isBox = FVGridGeometry::discMethod == DiscretizationMethod::box; @@ -223,9 +210,9 @@ public: if(onUpperBoundary_(globalPos)) { Scalar pn = 1.0e5; - priVars[pressureIdx] = pn; - priVars[switchIdx] = 0.3;//Sw for bothPhases - priVars[switchIdx+1] = pO2Inlet_/4.315e9; //moleFraction xlO2 for bothPhases + priVars[Indices::pressureIdx] = pn; + priVars[Indices::switchIdx] = 0.3;//Sw for bothPhases + priVars[Indices::switchIdx+1] = pO2Inlet_/4.315e9; //moleFraction xlO2 for bothPhases } return priVars; @@ -288,8 +275,8 @@ public: auto i = ElectroChemistry::calculateCurrentDensity(volVars); ElectroChemistry::reactionSource(source, i); - reactionSourceH2O_[dofIdxGlobal] = source[wPhaseIdx]; - reactionSourceO2_[dofIdxGlobal] = source[numComponents-1]; + reactionSourceH2O_[dofIdxGlobal] = source[Indices::conti0EqIdx + FluidSystem::H2OIdx]; + reactionSourceO2_[dofIdxGlobal] = source[Indices::conti0EqIdx + FluidSystem::O2Idx]; //Current Output in A/cm^2 currentDensity_[dofIdxGlobal] = i/10000; @@ -311,12 +298,12 @@ private: PrimaryVariables initial_(const GlobalPosition &globalPos) const { PrimaryVariables priVars(0.0); - priVars.setState(bothPhases); + priVars.setState(Indices::bothPhases); Scalar pn = 1.0e5; - priVars[pressureIdx] = pn; - priVars[switchIdx] = 0.3;//Sw for bothPhases - priVars[switchIdx+1] = pO2Inlet_/4.315e9; //moleFraction xlO2 for bothPhases + priVars[Indices::pressureIdx] = pn; + priVars[Indices::switchIdx] = 0.3;//Sw for bothPhases + priVars[Indices::switchIdx+1] = pO2Inlet_/4.315e9; //moleFraction xlO2 for bothPhases return priVars; } diff --git a/test/porousmediumflow/2pnc/implicit/fuelcellspatialparams.hh b/test/porousmediumflow/2pnc/implicit/fuelcellspatialparams.hh index 0651205102aaef5e321a27d0a27894e66fd82083..f12a2dddadd264c1235b350c4ecefdbe08640005 100644 --- a/test/porousmediumflow/2pnc/implicit/fuelcellspatialparams.hh +++ b/test/porousmediumflow/2pnc/implicit/fuelcellspatialparams.hh @@ -147,6 +147,16 @@ public: const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const { return materialParams_; } + /*! + * \brief Function for defining which phase is to be considered as the wetting phase. + * + * \return the wetting phase index + * \param globalPos The position of the center of the element + */ + template<class FluidSystem> + int wettingPhaseAtPos(const GlobalPosition& globalPos) const + { return FluidSystem::H2OIdx; } + private: DimWorldMatrix K_; Scalar porosity_; diff --git a/test/porousmediumflow/2pncmin/implicit/dissolutionproblem.hh b/test/porousmediumflow/2pncmin/implicit/dissolutionproblem.hh index c27c4da772002c78f0f27487e6b2a9ace8bd1483..076d17a322a07b4b5df63e98bd883e70ef752dca 100644 --- a/test/porousmediumflow/2pncmin/implicit/dissolutionproblem.hh +++ b/test/porousmediumflow/2pncmin/implicit/dissolutionproblem.hh @@ -68,7 +68,7 @@ SET_TYPE_PROP(DissolutionTypeTag, SpatialParams, DissolutionSpatialparams<TypeTa //Set properties here to override the default property settings SET_INT_PROP(DissolutionTypeTag, ReplaceCompEqIdx, 1); //!< Replace gas balance by total mass balance SET_PROP(DissolutionTypeTag, Formulation) -{ static constexpr auto value = TwoPFormulation::pnsw; }; +{ static constexpr auto value = TwoPFormulation::p1s0; }; } // end namespace Properties @@ -100,22 +100,30 @@ class DissolutionProblem : public PorousMediumFlowProblem<TypeTag> using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables); using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; - enum { + enum + { + // primary variable indices pressureIdx = Indices::pressureIdx, - switchIdx = Indices::switchIdx, //Saturation + switchIdx = Indices::switchIdx, + + // component indices + // TODO: using xwNaClIdx as privaridx works here, but + // looks like magic. Can this be done differently?? xwNaClIdx = FluidSystem::NaClIdx, precipNaClIdx = FluidSystem::numComponents, - //Indices of the components - wCompIdx = FluidSystem::H2OIdx, + // Indices of the components + H2OIdx = FluidSystem::H2OIdx, NaClIdx = FluidSystem::NaClIdx, - //Indices of the phases - wPhaseIdx = FluidSystem::wPhaseIdx, - nPhaseIdx = FluidSystem::nPhaseIdx, - sPhaseIdx = FluidSystem::sPhaseIdx, + // Indices of the phases + liquidPhaseIdx = FluidSystem::liquidPhaseIdx, + gasPhaseIdx = FluidSystem::gasPhaseIdx, + + // TODO: this shouldn't be in the fluid system + sPhaseIdx = FluidSystem::solidPhaseIdx, - //Index of the primary component of G and L phase + // Index of the primary component of G and L phase conti0EqIdx = Indices::conti0EqIdx, precipNaClEqIdx = Indices::conti0EqIdx + FluidSystem::numComponents, @@ -325,25 +333,25 @@ public: const auto& volVars = elemVolVars[scv]; - Scalar moleFracNaCl_wPhase = volVars.moleFraction(wPhaseIdx, NaClIdx); - Scalar moleFracNaCl_nPhase = volVars.moleFraction(nPhaseIdx, NaClIdx); + Scalar moleFracNaCl_wPhase = volVars.moleFraction(liquidPhaseIdx, NaClIdx); + Scalar moleFracNaCl_nPhase = volVars.moleFraction(gasPhaseIdx, NaClIdx); Scalar massFracNaCl_Max_wPhase = this->spatialParams().solubilityLimit(); Scalar moleFracNaCl_Max_wPhase = massToMoleFrac_(massFracNaCl_Max_wPhase); - Scalar moleFracNaCl_Max_nPhase = moleFracNaCl_Max_wPhase / volVars.pressure(nPhaseIdx); + Scalar moleFracNaCl_Max_nPhase = moleFracNaCl_Max_wPhase / volVars.pressure(gasPhaseIdx); Scalar saltPorosity = this->spatialParams().minPorosity(element, scv); // liquid phase using std::abs; - Scalar precipSalt = volVars.porosity() * volVars.molarDensity(wPhaseIdx) - * volVars.saturation(wPhaseIdx) + Scalar precipSalt = volVars.porosity() * volVars.molarDensity(liquidPhaseIdx) + * volVars.saturation(liquidPhaseIdx) * abs(moleFracNaCl_wPhase - moleFracNaCl_Max_wPhase); if (moleFracNaCl_wPhase < moleFracNaCl_Max_wPhase) precipSalt *= -1; // gas phase - precipSalt += volVars.porosity() * volVars.molarDensity(nPhaseIdx) - * volVars.saturation(nPhaseIdx) + precipSalt += volVars.porosity() * volVars.molarDensity(gasPhaseIdx) + * volVars.saturation(gasPhaseIdx) * abs(moleFracNaCl_nPhase - moleFracNaCl_Max_nPhase); // make sure we don't dissolve more salt than previously precipitated @@ -396,7 +404,7 @@ private: */ static Scalar massToMoleFrac_(Scalar XwNaCl) { - const Scalar Mw = 18.015e-3; //FluidSystem::molarMass(wCompIdx); /* molecular weight of water [kg/mol] */ //TODO use correct link to FluidSyswem later + const Scalar Mw = 18.015e-3; //FluidSystem::molarMass(H2OIdx); /* molecular weight of water [kg/mol] */ //TODO use correct link to FluidSyswem later const Scalar Ms = 58.44e-3; //FluidSystem::molarMass(NaClIdx); /* molecular weight of NaCl [kg/mol] */ const Scalar X_NaCl = XwNaCl; diff --git a/test/porousmediumflow/2pncmin/implicit/dissolutionspatialparams.hh b/test/porousmediumflow/2pncmin/implicit/dissolutionspatialparams.hh index 0cd4526dcddbc812e43cd09a43a57be926628907..4af312062de70898fcf77306de814c33930f9a21 100644 --- a/test/porousmediumflow/2pncmin/implicit/dissolutionspatialparams.hh +++ b/test/porousmediumflow/2pncmin/implicit/dissolutionspatialparams.hh @@ -170,6 +170,11 @@ public: const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const { return materialParams_; } + // define which phase is to be considered as the wetting phase + template<class FluidSystem> + int wettingPhaseAtPos(const GlobalPosition& globalPos) const + { return FluidSystem::H2OIdx; } + private: MaterialLawParams materialParams_; diff --git a/test/porousmediumflow/co2/implicit/heterogeneousproblem.hh b/test/porousmediumflow/co2/implicit/heterogeneousproblem.hh index 2aa4e97a3125708aa97d997ac3b8a737b0c2b430..d37a1ed53d3f7b5462e416b14bccfa495b3ba75e 100644 --- a/test/porousmediumflow/co2/implicit/heterogeneousproblem.hh +++ b/test/porousmediumflow/co2/implicit/heterogeneousproblem.hh @@ -136,14 +136,9 @@ class HeterogeneousProblem : public PorousMediumFlowProblem<TypeTag> switchIdx = Indices::switchIdx, // phase presence index - wPhaseOnly = Indices::wPhaseOnly, - - // phase indices - wPhaseIdx = FluidSystem::wPhaseIdx, - nPhaseIdx = FluidSystem::nPhaseIdx, + firstPhaseOnly = Indices::firstPhaseOnly, // component indices - nCompIdx = FluidSystem::nCompIdx, BrineIdx = FluidSystem::BrineIdx, CO2Idx = FluidSystem::CO2Idx, @@ -250,8 +245,8 @@ public: vtk.addField(vtkBoxVolume_, "boxVolume"); #if !ISOTHERMAL - vtk.addVolumeVariable([](const VolumeVariables& v){ return v.enthalpy(wPhaseIdx); }, "enthalpyW"); - vtk.addVolumeVariable([](const VolumeVariables& v){ return v.enthalpy(nPhaseIdx); }, "enthalpyN"); + vtk.addVolumeVariable([](const VolumeVariables& v){ return v.enthalpy(BrineIdx); }, "enthalpyW"); + vtk.addVolumeVariable([](const VolumeVariables& v){ return v.enthalpy(CO2Idx); }, "enthalpyN"); #else vtkTemperature_.resize(numDofs, 0.0); vtk.addField(vtkTemperature_, "temperature"); @@ -385,7 +380,7 @@ public: // kg/(m^2*s) or mole/(m^2*s) depending on useMoles if (boundaryId == injectionBottom_) { - fluxes[contiCO2EqIdx] = useMoles ? -injectionRate_/FluidSystem::molarMass(nCompIdx) : -injectionRate_; + fluxes[contiCO2EqIdx] = useMoles ? -injectionRate_/FluidSystem::molarMass(CO2Idx) : -injectionRate_; #if !ISOTHERMAL // energy fluxes are always mass specific fluxes[energyEqIdx] = -injectionRate_/*kg/(m^2 s)*/*CO2::gasEnthalpy( @@ -430,7 +425,7 @@ private: PrimaryVariables initial_(const GlobalPosition &globalPos) const { PrimaryVariables values(0.0); - values.setState(wPhaseOnly); + values.setState(firstPhaseOnly); const Scalar temp = initialTemperatureField_(globalPos); const Scalar densityW = FluidSystem::Brine::liquidDensity(temp, 1e7); diff --git a/test/porousmediumflow/co2/implicit/heterogeneousspatialparameters.hh b/test/porousmediumflow/co2/implicit/heterogeneousspatialparameters.hh index 891d092475c63fd32723cd9621e377ff6a662815..17dc8457f139dd3a20b09cdd182a2d3d870660cd 100644 --- a/test/porousmediumflow/co2/implicit/heterogeneousspatialparameters.hh +++ b/test/porousmediumflow/co2/implicit/heterogeneousspatialparameters.hh @@ -219,6 +219,16 @@ public: return materialParams_; } + /*! + * \brief Function for defining which phase is to be considered as the wetting phase. + * + * \return the wetting phase index + * \param globalPos The position of the center of the element + */ + template<class FluidSystem> + int wettingPhaseAtPos(const GlobalPosition& globalPos) const + { return FluidSystem::BrineIdx; } + /*! * \brief Returns the heat capacity \f$[J / (kg K)]\f$ of the rock matrix. * diff --git a/test/porousmediumflow/mpnc/implicit/2p2ccomparison/mpnc_comparison_problem.hh b/test/porousmediumflow/mpnc/implicit/2p2ccomparison/mpnc_comparison_problem.hh index 13853dda38b0166c49bdf8c89fecac81fba73a5b..b7af9bb6c4f58f4c4ab8c2738449e233c272113c 100644 --- a/test/porousmediumflow/mpnc/implicit/2p2ccomparison/mpnc_comparison_problem.hh +++ b/test/porousmediumflow/mpnc/implicit/2p2ccomparison/mpnc_comparison_problem.hh @@ -104,10 +104,10 @@ class MPNCComparisonProblem enum {dimWorld = GridView::dimensionworld}; enum {numPhases = GET_PROP_TYPE(TypeTag, ModelTraits)::numPhases()}; enum {numComponents = GET_PROP_TYPE(TypeTag, ModelTraits)::numComponents()}; - enum {nPhaseIdx = FluidSystem::nPhaseIdx}; - enum {wPhaseIdx = FluidSystem::wPhaseIdx}; - enum {wCompIdx = FluidSystem::wCompIdx}; - enum {nCompIdx = FluidSystem::nCompIdx}; + enum {gasPhaseIdx = FluidSystem::gasPhaseIdx}; + enum {liquidPhaseIdx = FluidSystem::liquidPhaseIdx}; + enum {wCompIdx = FluidSystem::H2OIdx}; + enum {nCompIdx = FluidSystem::N2Idx}; enum {fug0Idx = Indices::fug0Idx}; enum {s0Idx = Indices::s0Idx}; enum {p0Idx = Indices::p0Idx}; @@ -258,21 +258,21 @@ private: fs.setTemperature(this->temperatureAtPos(globalPos)); // set water saturation - fs.setSaturation(wPhaseIdx, 0.8); - fs.setSaturation(nPhaseIdx, 1.0 - fs.saturation(wPhaseIdx)); + fs.setSaturation(liquidPhaseIdx, 0.8); + fs.setSaturation(gasPhaseIdx, 1.0 - fs.saturation(liquidPhaseIdx)); // set pressure of the gas phase - fs.setPressure(nPhaseIdx, 1e5); + fs.setPressure(gasPhaseIdx, 1e5); // calulate the capillary pressure const auto& matParams = this->spatialParams().materialLawParamsAtPos(globalPos); PhaseVector pc; MaterialLaw::capillaryPressures(pc, matParams, fs); - fs.setPressure(wPhaseIdx, - fs.pressure(nPhaseIdx) + pc[wPhaseIdx] - pc[nPhaseIdx]); + fs.setPressure(liquidPhaseIdx, + fs.pressure(gasPhaseIdx) + pc[liquidPhaseIdx] - pc[gasPhaseIdx]); // make the fluid state consistent with local thermodynamic // equilibrium - using MiscibleMultiPhaseComposition = Dumux::MiscibleMultiPhaseComposition<Scalar, FluidSystem, /*useKelvinEquation*/false>; + using MiscibleMultiPhaseComposition = Dumux::MiscibleMultiPhaseComposition<Scalar, FluidSystem>; ParameterCache paramCache; MiscibleMultiPhaseComposition::solve(fs, @@ -285,7 +285,7 @@ private: // all N component fugacities for (int compIdx = 0; compIdx < numComponents; ++compIdx) - values[fug0Idx + compIdx] = fs.fugacity(nPhaseIdx, compIdx); + values[fug0Idx + compIdx] = fs.fugacity(gasPhaseIdx, compIdx); // first M - 1 saturations for (int phaseIdx = 0; phaseIdx < numPhases - 1; ++phaseIdx) diff --git a/test/porousmediumflow/mpnc/implicit/2p2ccomparison/mpnc_comparison_spatialparams.hh b/test/porousmediumflow/mpnc/implicit/2p2ccomparison/mpnc_comparison_spatialparams.hh index 1312f86a1fb903b0f4a6caec6e6e711cc66f3408..01c7045e9ac87c995a19ca39d461d78484e57fde 100644 --- a/test/porousmediumflow/mpnc/implicit/2p2ccomparison/mpnc_comparison_spatialparams.hh +++ b/test/porousmediumflow/mpnc/implicit/2p2ccomparison/mpnc_comparison_spatialparams.hh @@ -56,15 +56,15 @@ SET_PROP(MPNCComparisonSpatialParams, MaterialLaw) { private: using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); - enum {wPhaseIdx = FluidSystem::wPhaseIdx}; + enum {liquidPhaseIdx = FluidSystem::liquidPhaseIdx}; // define the material law using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); using EffMaterialLaw = RegularizedBrooksCorey<Scalar>; using TwoPMaterialLaw = EffToAbsLaw<EffMaterialLaw>; public: - using type = TwoPAdapter<wPhaseIdx, TwoPMaterialLaw>; + using type = TwoPAdapter<liquidPhaseIdx, TwoPMaterialLaw>; }; -} +} // end namespace Properties /** * \ingroup MPNCModel diff --git a/test/porousmediumflow/mpnc/implicit/combustionfluidsystem.hh b/test/porousmediumflow/mpnc/implicit/combustionfluidsystem.hh index 0688a0e8580b1302dfebfd1f33740d688a84ef72..3fa8ba66b22d9bed9a61c21a52c55f8a56c22655 100644 --- a/test/porousmediumflow/mpnc/implicit/combustionfluidsystem.hh +++ b/test/porousmediumflow/mpnc/implicit/combustionfluidsystem.hh @@ -67,13 +67,17 @@ public: static constexpr int wPhaseIdx = 0; // index of the wetting phase static constexpr int nPhaseIdx = 1; // index of the non-wetting phase + static constexpr int phase0Idx = 0; // index of the wetting phase + static constexpr int phase1Idx = 1; // index of the non-wetting phase static constexpr int sPhaseIdx = 2; // index of the solid phase // export component indices to indicate the main component // of the corresponding phase at atmospheric pressure 1 bar // and room temperature 20°C: - static const int wCompIdx = wPhaseIdx; - static const int nCompIdx = nPhaseIdx; + static constexpr int wCompIdx = wPhaseIdx; + static constexpr int nCompIdx = nPhaseIdx; + static constexpr int comp0Idx = 0; // index of the wetting phase + static constexpr int comp1Idx = 1; // index of the non-wetting phase /*! * \brief Return the human readable name of a fluid phase diff --git a/test/porousmediumflow/mpnc/implicit/evaporationatmosphereproblem.hh b/test/porousmediumflow/mpnc/implicit/evaporationatmosphereproblem.hh index 65b64db4bfd0cc45a795a3be0cb2cd5404ddac08..27892ae7002744c56770a933381c12552054b04e 100644 --- a/test/porousmediumflow/mpnc/implicit/evaporationatmosphereproblem.hh +++ b/test/porousmediumflow/mpnc/implicit/evaporationatmosphereproblem.hh @@ -131,8 +131,8 @@ class EvaporationAtmosphereProblem: public PorousMediumFlowProblem<TypeTag> enum { p0Idx = Indices::p0Idx }; enum { conti00EqIdx = Indices::conti0EqIdx }; enum { energyEq0Idx = Indices::energyEqIdx }; - enum { wPhaseIdx = FluidSystem::wPhaseIdx }; - enum { nPhaseIdx = FluidSystem::nPhaseIdx }; + enum { liquidPhaseIdx = FluidSystem::liquidPhaseIdx }; + enum { gasPhaseIdx = FluidSystem::gasPhaseIdx }; enum { wCompIdx = FluidSystem::H2OIdx }; enum { nCompIdx = FluidSystem::N2Idx }; enum { numEnergyEqFluid = ModelTraits::numEnergyEqFluid() }; @@ -268,8 +268,8 @@ public: fluidState.setPressure(phaseIdx, pnInitial_); } - fluidState.setTemperature(nPhaseIdx, TInject_ ); - fluidState.setTemperature(wPhaseIdx, TInitial_ ); // this value is a good one, TInject does not work + fluidState.setTemperature(gasPhaseIdx, TInject_ ); + fluidState.setTemperature(liquidPhaseIdx, TInitial_ ); // this value is a good one, TInject does not work // This solves the system of equations defining x=x(p,T) ConstraintSolver::solve(fluidState, @@ -278,14 +278,14 @@ public: /*setEnthalpy=*/false) ; // Now let's make the air phase less than fully saturated with water - fluidState.setMoleFraction(nPhaseIdx, wCompIdx, fluidState.moleFraction(nPhaseIdx, wCompIdx)*percentOfEquil_ ) ; - fluidState.setMoleFraction(nPhaseIdx, nCompIdx, 1.-fluidState.moleFraction(nPhaseIdx, wCompIdx) ) ; + fluidState.setMoleFraction(gasPhaseIdx, wCompIdx, fluidState.moleFraction(gasPhaseIdx, wCompIdx)*percentOfEquil_ ) ; + fluidState.setMoleFraction(gasPhaseIdx, nCompIdx, 1.-fluidState.moleFraction(gasPhaseIdx, wCompIdx) ) ; // compute density of injection phase const Scalar density = FluidSystem::density(fluidState, dummyCache, - nPhaseIdx); - fluidState.setDensity(nPhaseIdx, density); + gasPhaseIdx); + fluidState.setDensity(gasPhaseIdx, density); for(int phaseIdx=0; phaseIdx<numPhases; phaseIdx++) { @@ -295,18 +295,18 @@ public: fluidState.setEnthalpy(phaseIdx, h); } - const Scalar molarFlux = massFluxInjectedPhase / fluidState.averageMolarMass(nPhaseIdx); + const Scalar molarFlux = massFluxInjectedPhase / fluidState.averageMolarMass(gasPhaseIdx); // actually setting the fluxes if (onLeftBoundary_(globalPos) && this->spatialParams().inFF_(globalPos)) { - values[conti00EqIdx + nPhaseIdx * numComponents + wCompIdx] - = -molarFlux * fluidState.moleFraction(nPhaseIdx, wCompIdx); - values[conti00EqIdx + nPhaseIdx * numComponents + nCompIdx] - = -molarFlux * fluidState.moleFraction(nPhaseIdx, nCompIdx); + values[conti00EqIdx + gasPhaseIdx * numComponents + wCompIdx] + = -molarFlux * fluidState.moleFraction(gasPhaseIdx, wCompIdx); + values[conti00EqIdx + gasPhaseIdx * numComponents + nCompIdx] + = -molarFlux * fluidState.moleFraction(gasPhaseIdx, nCompIdx); // energy equations are specified mass specifically - values[energyEq0Idx + nPhaseIdx] = - massFluxInjectedPhase - * fluidState.enthalpy(nPhaseIdx) ; + values[energyEq0Idx + gasPhaseIdx] = - massFluxInjectedPhase + * fluidState.enthalpy(gasPhaseIdx) ; } return values; } @@ -359,12 +359,12 @@ private: Scalar S[numPhases]; if (this->spatialParams().inPM_(globalPos)){ - S[wPhaseIdx] = SwPMInitial_; - S[nPhaseIdx] = 1. - S[wPhaseIdx] ; + S[liquidPhaseIdx] = SwPMInitial_; + S[gasPhaseIdx] = 1. - S[liquidPhaseIdx] ; } else if (this->spatialParams().inFF_(globalPos)){ - S[wPhaseIdx] = SwFFInitial_; - S[nPhaseIdx] = 1. - S[wPhaseIdx] ; + S[liquidPhaseIdx] = SwFFInitial_; + S[gasPhaseIdx] = 1. - S[liquidPhaseIdx] ; } else DUNE_THROW(Dune::InvalidStateException, @@ -394,12 +394,12 @@ private: if (this->spatialParams().inPM_(globalPos)){ // Use homogenous pressure in the domain and let the newton find the pressure distribution using std::abs; - p[wPhaseIdx] = pnInitial_ - abs(capPress[wPhaseIdx]); - p[nPhaseIdx] = p[wPhaseIdx] + abs(capPress[wPhaseIdx]); + p[liquidPhaseIdx] = pnInitial_ - abs(capPress[liquidPhaseIdx]); + p[gasPhaseIdx] = p[liquidPhaseIdx] + abs(capPress[liquidPhaseIdx]); } else if (this->spatialParams().inFF_(globalPos)){ - p[nPhaseIdx] = pnInitial_ ; - p[wPhaseIdx] = pnInitial_ ; + p[gasPhaseIdx] = pnInitial_ ; + p[liquidPhaseIdx] = pnInitial_ ; } else DUNE_THROW(Dune::InvalidStateException, "You should not be here: x=" << globalPos[0] << " y= "<< globalPos[dimWorld-1]); @@ -407,12 +407,12 @@ private: if(pressureFormulation == mostWettingFirst){ // This means that the pressures are sorted from the most wetting to the least wetting-1 in the primary variables vector. // For two phases this means that there is one pressure as primary variable: pw - priVars[p0Idx] = p[wPhaseIdx]; + priVars[p0Idx] = p[liquidPhaseIdx]; } else if(pressureFormulation == leastWettingFirst){ // This means that the pressures are sorted from the least wetting to the most wetting-1 in the primary variables vector. // For two phases this means that there is one pressure as primary variable: pn - priVars[p0Idx] = p[nPhaseIdx]; + priVars[p0Idx] = p[gasPhaseIdx]; } else DUNE_THROW(Dune::InvalidStateException, "EvaporationAtmosphereProblem does not support the chosen pressure formulation."); @@ -431,8 +431,8 @@ private: FluidState dryFluidState(equilibriumFluidState); // Now let's make the air phase less than fully saturated with vapor - dryFluidState.setMoleFraction(nPhaseIdx, wCompIdx, dryFluidState.moleFraction(nPhaseIdx, wCompIdx) * percentOfEquil_ ) ; - dryFluidState.setMoleFraction(nPhaseIdx, nCompIdx, 1.0-dryFluidState.moleFraction(nPhaseIdx, wCompIdx) ) ; + dryFluidState.setMoleFraction(gasPhaseIdx, wCompIdx, dryFluidState.moleFraction(gasPhaseIdx, wCompIdx) * percentOfEquil_ ) ; + dryFluidState.setMoleFraction(gasPhaseIdx, nCompIdx, 1.0-dryFluidState.moleFraction(gasPhaseIdx, wCompIdx) ) ; /* Difference between kinetic and MPNC: * number of component related primVar and how they are calculated (mole fraction, fugacities, resp.) @@ -458,7 +458,7 @@ private: { // in the case I am using the "standard" mpnc model, the variables to be set are the "fugacities" const Scalar fugH2O = FluidSystem::H2O::vaporPressure(T) ; - const Scalar fugN2 = p[nPhaseIdx] - fugH2O ; + const Scalar fugN2 = p[gasPhaseIdx] - fugH2O ; priVars[conti00EqIdx + FluidSystem::N2Idx] = fugN2 ; priVars[conti00EqIdx + FluidSystem::H2OIdx] = fugH2O ; @@ -468,8 +468,8 @@ private: const Scalar Henry = BinaryCoeff::H2O_N2::henry(TInitial_); const Scalar satVapPressure = FluidSystem::H2O::vaporPressure(TInitial_); - xl[FluidSystem::H2OIdx] = x_[wPhaseIdx][wCompIdx]; - xl[FluidSystem::N2Idx] = x_[wPhaseIdx][nCompIdx]; + xl[FluidSystem::H2OIdx] = x_[liquidPhaseIdx][wCompIdx]; + xl[FluidSystem::N2Idx] = x_[liquidPhaseIdx][nCompIdx]; beta[FluidSystem::H2OIdx] = satVapPressure ; beta[FluidSystem::N2Idx] = Henry ; diff --git a/test/porousmediumflow/mpnc/implicit/evaporationatmospherespatialparams.hh b/test/porousmediumflow/mpnc/implicit/evaporationatmospherespatialparams.hh index ee2e2392b820f22f6929b013255eb0af9014364e..39700dcf967ba903fb29d12e677739eac1cf884f 100644 --- a/test/porousmediumflow/mpnc/implicit/evaporationatmospherespatialparams.hh +++ b/test/porousmediumflow/mpnc/implicit/evaporationatmospherespatialparams.hh @@ -67,7 +67,7 @@ SET_TYPE_PROP(EvaporationAtmosphereSpatialParams, SpatialParams, EvaporationAtmo SET_PROP(EvaporationAtmosphereSpatialParams, MaterialLaw) { using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); - enum {wPhaseIdx = FluidSystem::wPhaseIdx}; + enum {liquidPhaseIdx = FluidSystem::liquidPhaseIdx}; private: // define the material law which is parameterized by effective @@ -103,7 +103,7 @@ private: using TwoPMaterialLaw = EffToAbsLaw<EffectiveLaw>; public: - using type = TwoPAdapter<wPhaseIdx, TwoPMaterialLaw>; + using type = TwoPAdapter<liquidPhaseIdx, TwoPMaterialLaw>; }; diff --git a/test/porousmediumflow/mpnc/implicit/obstacleproblem.hh b/test/porousmediumflow/mpnc/implicit/obstacleproblem.hh index 7071f92ad51988b896fc92ca5143a5b5de2dbc03..b235977db2b0a0f4f3ddff51a474490006aff3cd 100644 --- a/test/porousmediumflow/mpnc/implicit/obstacleproblem.hh +++ b/test/porousmediumflow/mpnc/implicit/obstacleproblem.hh @@ -127,16 +127,16 @@ class ObstacleProblem using ModelTraits = typename GET_PROP_TYPE(TypeTag, ModelTraits); using Indices = typename ModelTraits::Indices; - enum {dimWorld = GridView::dimensionworld}; - enum {numPhases = ModelTraits::numPhases()}; - enum {numComponents = ModelTraits::numComponents()}; - enum {nPhaseIdx = FluidSystem::nPhaseIdx}; - enum {wPhaseIdx = FluidSystem::wPhaseIdx}; - enum {wCompIdx = FluidSystem::wCompIdx}; - enum {nCompIdx = FluidSystem::nCompIdx}; - enum {fug0Idx = Indices::fug0Idx}; - enum {s0Idx = Indices::s0Idx}; - enum {p0Idx = Indices::p0Idx}; + enum { dimWorld = GridView::dimensionworld }; + enum { numPhases = ModelTraits::numPhases() }; + enum { numComponents = ModelTraits::numComponents() }; + enum { gasPhaseIdx = FluidSystem::gasPhaseIdx }; + enum { liquidPhaseIdx = FluidSystem::liquidPhaseIdx }; + enum { H2OIdx = FluidSystem::H2OIdx }; + enum { N2Idx = FluidSystem::N2Idx }; + enum { fug0Idx = Indices::fug0Idx }; + enum { s0Idx = Indices::s0Idx }; + enum { p0Idx = Indices::p0Idx }; using GlobalPosition = Dune::FieldVector<Scalar, dimWorld>; using PhaseVector = Dune::FieldVector<Scalar, numPhases>; @@ -310,33 +310,33 @@ private: if (onInlet_(globalPos)) { // only liquid on inlet - refPhaseIdx = wPhaseIdx; - otherPhaseIdx = nPhaseIdx; + refPhaseIdx = liquidPhaseIdx; + otherPhaseIdx = gasPhaseIdx; // set liquid saturation - fs.setSaturation(wPhaseIdx, 1.0); + fs.setSaturation(liquidPhaseIdx, 1.0); // set pressure of the liquid phase - fs.setPressure(wPhaseIdx, 2e5); + fs.setPressure(liquidPhaseIdx, 2e5); // set the liquid composition to pure water - fs.setMoleFraction(wPhaseIdx, nCompIdx, 0.0); - fs.setMoleFraction(wPhaseIdx, wCompIdx, 1.0); + fs.setMoleFraction(liquidPhaseIdx, N2Idx, 0.0); + fs.setMoleFraction(liquidPhaseIdx, H2OIdx, 1.0); } else { // elsewhere, only gas - refPhaseIdx = nPhaseIdx; - otherPhaseIdx = wPhaseIdx; + refPhaseIdx = gasPhaseIdx; + otherPhaseIdx = liquidPhaseIdx; // set gas saturation - fs.setSaturation(nPhaseIdx, 1.0); + fs.setSaturation(gasPhaseIdx, 1.0); // set pressure of the gas phase - fs.setPressure(nPhaseIdx, 1e5); + fs.setPressure(gasPhaseIdx, 1e5); // set the gas composition to 99% nitrogen and 1% steam - fs.setMoleFraction(nPhaseIdx, nCompIdx, 0.99); - fs.setMoleFraction(nPhaseIdx, wCompIdx, 0.01); + fs.setMoleFraction(gasPhaseIdx, N2Idx, 0.99); + fs.setMoleFraction(gasPhaseIdx, H2OIdx, 0.01); } // set the other saturation diff --git a/test/porousmediumflow/mpnc/implicit/obstaclespatialparams.hh b/test/porousmediumflow/mpnc/implicit/obstaclespatialparams.hh index 2a363654ae42a7d660661e3ed439d8140b3b53be..f628bd11b9dee3387f731c5147efca0cb4f0e8bd 100644 --- a/test/porousmediumflow/mpnc/implicit/obstaclespatialparams.hh +++ b/test/porousmediumflow/mpnc/implicit/obstaclespatialparams.hh @@ -55,13 +55,13 @@ SET_PROP(ObstacleSpatialParams, MaterialLaw) { private: using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); - enum {wPhaseIdx = FluidSystem::wPhaseIdx}; + enum { liquidPhaseIdx = FluidSystem::liquidPhaseIdx }; // define the material law using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); using EffMaterialLaw = RegularizedLinearMaterial<Scalar>; using TwoPMaterialLaw = EffToAbsLaw<EffMaterialLaw>; public: - using type = TwoPAdapter<wPhaseIdx, TwoPMaterialLaw>; + using type = TwoPAdapter<liquidPhaseIdx, TwoPMaterialLaw>; }; } diff --git a/test/porousmediumflow/richards/implicit/richardsniconductionproblem.hh b/test/porousmediumflow/richards/implicit/richardsniconductionproblem.hh index 9d8471f2a4f32f0d52429a249fbaa2f544645e9c..b4c032237583cb55866e271ed79709e46a5d6302 100644 --- a/test/porousmediumflow/richards/implicit/richardsniconductionproblem.hh +++ b/test/porousmediumflow/richards/implicit/richardsniconductionproblem.hh @@ -113,8 +113,8 @@ class RichardsNIConductionProblem :public PorousMediumFlowProblem<TypeTag> enum { pressureIdx = Indices::pressureIdx, - wPhaseOnly = Indices::wPhaseOnly, - wPhaseIdx = Indices::wPhaseIdx, + liquidPhaseOnly = Indices::liquidPhaseOnly, + liquidPhaseIdx = FluidSystem::liquidPhaseIdx, temperatureIdx = Indices::temperatureIdx }; @@ -161,7 +161,7 @@ public: volVars.update(someElemSol, *this, someElement, someScv); const auto porosity = this->spatialParams().porosity(someElement, someScv, someElemSol); - const auto densityW = volVars.density(wPhaseIdx); + const auto densityW = volVars.density(liquidPhaseIdx); const auto heatCapacityW = IapwsH2O::liquidHeatCapacity(someInitSol[temperatureIdx], someInitSol[pressureIdx]); const auto densityS = this->spatialParams().solidDensity(someElement, someScv, someElemSol); const auto heatCapacityS = this->spatialParams().solidHeatCapacity(someElement, someScv, someElemSol); @@ -305,7 +305,7 @@ private: PrimaryVariables initial_(const GlobalPosition &globalPos) const { PrimaryVariables priVars(0.0); - priVars.setState(wPhaseOnly); + priVars.setState(liquidPhaseOnly); priVars[pressureIdx] = 1e5; // initial condition for the pressure priVars[temperatureIdx] = 290.; diff --git a/test/porousmediumflow/richards/implicit/richardsniconvectionproblem.hh b/test/porousmediumflow/richards/implicit/richardsniconvectionproblem.hh index 5a36d9b1966179e23a4439b5dc97d140833df695..7721e0ad3086b63c40f451f247e2475a55aced1c 100644 --- a/test/porousmediumflow/richards/implicit/richardsniconvectionproblem.hh +++ b/test/porousmediumflow/richards/implicit/richardsniconvectionproblem.hh @@ -122,8 +122,8 @@ class RichardsNIConvectionProblem : public PorousMediumFlowProblem<TypeTag> enum { pressureIdx = Indices::pressureIdx, - wPhaseOnly = Indices::wPhaseOnly, - wPhaseIdx = Indices::wPhaseIdx, + liquidPhaseOnly = Indices::liquidPhaseOnly, + liquidPhaseIdx = FluidSystem::liquidPhaseIdx, temperatureIdx = Indices::temperatureIdx }; @@ -175,7 +175,7 @@ public: volVars.update(someElemSol, *this, someElement, someScv); const auto porosity = this->spatialParams().porosity(someElement, someScv, someElemSol); - const auto densityW = volVars.density(wPhaseIdx); + const auto densityW = volVars.density(liquidPhaseIdx); const auto heatCapacityW = IapwsH2O::liquidHeatCapacity(someInitSol[temperatureIdx], someInitSol[pressureIdx]); const auto densityS = this->spatialParams().solidDensity(someElement, someScv, someElemSol); const auto heatCapacityS = this->spatialParams().solidHeatCapacity(someElement, someScv, someElemSol); @@ -277,9 +277,9 @@ public: if(globalPos[0] < eps_) { - values[pressureIdx] = -darcyVelocity_*elemVolVars[scvf.insideScvIdx()].density(wPhaseIdx); - values[temperatureIdx] = -darcyVelocity_*elemVolVars[scvf.insideScvIdx()].density(wPhaseIdx) - *IapwsH2O::liquidEnthalpy(temperatureHigh_, elemVolVars[scvf.insideScvIdx()].pressure(wPhaseIdx)); + values[pressureIdx] = -darcyVelocity_*elemVolVars[scvf.insideScvIdx()].density(liquidPhaseIdx); + values[temperatureIdx] = -darcyVelocity_*elemVolVars[scvf.insideScvIdx()].density(liquidPhaseIdx) + *IapwsH2O::liquidEnthalpy(temperatureHigh_, elemVolVars[scvf.insideScvIdx()].pressure(liquidPhaseIdx)); } return values; } @@ -327,7 +327,7 @@ private: PrimaryVariables initial_(const GlobalPosition &globalPos) const { PrimaryVariables priVars(0.0); - priVars.setState(wPhaseOnly); + priVars.setState(liquidPhaseOnly); priVars[pressureIdx] = pressureLow_; // initial condition for the pressure priVars[temperatureIdx] = temperatureLow_; return priVars; diff --git a/test/porousmediumflow/richards/implicit/richardsnievaporationproblem.hh b/test/porousmediumflow/richards/implicit/richardsnievaporationproblem.hh index 1d20119e5023b5f485f0427fdebf6ecd6faa7bda..fff94fdd65b1a26fc7f73d264c1a70d35f636e02 100644 --- a/test/porousmediumflow/richards/implicit/richardsnievaporationproblem.hh +++ b/test/porousmediumflow/richards/implicit/richardsnievaporationproblem.hh @@ -208,8 +208,8 @@ public: if(globalPos[1] > this->fvGridGeometry().bBoxMax()[1] - eps_) { values[conti0EqIdx] = 1e-3; - values[energyEqIdx] = FluidSystem::enthalpy( volVars.fluidState(),Indices::nPhaseIdx) * values[conti0EqIdx]; - values[energyEqIdx] += FluidSystem::thermalConductivity(volVars.fluidState(), Indices::nPhaseIdx) + values[energyEqIdx] = FluidSystem::enthalpy( volVars.fluidState(), FluidSystem::gasPhaseIdx) * values[conti0EqIdx]; + values[energyEqIdx] += FluidSystem::thermalConductivity(volVars.fluidState(), FluidSystem::gasPhaseIdx) * (volVars.temperature() - temperatureInitial_)/boundaryLayerThickness; } return values; diff --git a/test/porousmediumflow/richardsnc/implicit/richardswelltracerproblem.hh b/test/porousmediumflow/richardsnc/implicit/richardswelltracerproblem.hh index 406a6cb7ec6c1db1bf9eefa516c5cb349f312129..cfdddf7494aca241d751ae0ae413b1c4e6342ddf 100644 --- a/test/porousmediumflow/richardsnc/implicit/richardswelltracerproblem.hh +++ b/test/porousmediumflow/richardsnc/implicit/richardswelltracerproblem.hh @@ -112,7 +112,7 @@ class RichardsWellTracerProblem : public PorousMediumFlowProblem<TypeTag> enum { pressureIdx = Indices::pressureIdx, compIdx = Indices::compMainIdx + 1, - wPhaseIdx = FluidSystem::wPhaseIdx, + liquidPhaseIdx = FluidSystem::phase0Idx, dimWorld = GridView::dimensionworld }; @@ -161,8 +161,8 @@ public: for (auto&& scv : scvs(fvGeometry)) { const auto& volVars = elemVolVars[scv]; - tracerMass += volVars.massFraction(wPhaseIdx, compIdx)*volVars.density(wPhaseIdx) - * scv.volume() * volVars.saturation(wPhaseIdx) * volVars.porosity() * volVars.extrusionFactor(); + tracerMass += volVars.massFraction(liquidPhaseIdx, compIdx)*volVars.density(liquidPhaseIdx) + * scv.volume() * volVars.saturation(liquidPhaseIdx) * volVars.porosity() * volVars.extrusionFactor(); accumulatedSource_ += this->scvPointSources(element, fvGeometry, elemVolVars, scv)[compIdx] * scv.volume() * volVars.extrusionFactor() @@ -287,8 +287,8 @@ public: const auto& volVars = elemVolVars[scv]; //! convert pump rate from kg/s to mol/s //! We assume we can't keep up the pump rate if the saturation sinks - const Scalar value = pumpRate_*volVars.molarDensity(wPhaseIdx)/volVars.density(wPhaseIdx)*volVars.saturation(wPhaseIdx); - return PrimaryVariables({-value, -value*volVars.moleFraction(wPhaseIdx, compIdx)}); + const Scalar value = pumpRate_*volVars.molarDensity(liquidPhaseIdx)/volVars.density(liquidPhaseIdx)*volVars.saturation(liquidPhaseIdx); + return PrimaryVariables({-value, -value*volVars.moleFraction(liquidPhaseIdx, compIdx)}); }); } diff --git a/tutorial/ex1/injection2p2cproblem.hh b/tutorial/ex1/injection2p2cproblem.hh index 603af566a59f8d1541c2cee8cd7568171d89ba50..a9331eb5e4ffedbdda739b2f80ca32b842484675 100644 --- a/tutorial/ex1/injection2p2cproblem.hh +++ b/tutorial/ex1/injection2p2cproblem.hh @@ -200,8 +200,8 @@ public: // inject nitrogen. negative values mean injection // convert from units kg/(s*m^2) to mole/(s*m^2) - values[Indices::contiNEqIdx] = -1e-4/FluidSystem::molarMass(FluidSystem::nCompIdx); - values[Indices::contiWEqIdx] = 0.0; + values[Indices::conti0EqIdx + FluidSystem::N2Idx] = -1e-4/FluidSystem::molarMass(FluidSystem::N2Idx); + values[Indices::conti0EqIdx + FluidSystem::H2OIdx] = 0.0; } return values; @@ -226,7 +226,7 @@ public: PrimaryVariables initialAtPos(const GlobalPosition &globalPos) const { PrimaryVariables values(0.0); - values.setState(Indices::wPhaseOnly); + values.setState(Indices::firstPhaseOnly); // get the water density at atmospheric conditions const Scalar densityW = FluidSystem::H2O::liquidDensity(temperature(), 1.0e5); diff --git a/tutorial/ex1/injection2pproblem.hh b/tutorial/ex1/injection2pproblem.hh index 4374492f1f0b1014a96a53e8e2ca025f1d5e7a54..5e0b2980d6095617d5d85e2c267c19d4fb75dc18 100644 --- a/tutorial/ex1/injection2pproblem.hh +++ b/tutorial/ex1/injection2pproblem.hh @@ -196,8 +196,8 @@ public: { // inject nitrogen. negative values mean injection // units kg/(s*m^2) - values[Indices::contiNEqIdx] = -1e-4; - values[Indices::contiWEqIdx] = 0.0; + values[Indices::conti0EqIdx + FluidSystem::N2Idx] = -1e-4; + values[Indices::conti0EqIdx + FluidSystem::H2OIdx] = 0.0; } return values; diff --git a/tutorial/ex1/injection2pspatialparams.hh b/tutorial/ex1/injection2pspatialparams.hh index 8449b258539d80b5506ff5295ffd88ef1115d27b..411f22bd73a8d6537554a16518e4ca75591aae0d 100644 --- a/tutorial/ex1/injection2pspatialparams.hh +++ b/tutorial/ex1/injection2pspatialparams.hh @@ -153,6 +153,16 @@ public: return aquiferMaterialParams_; } + /*! + * \brief Function for defining which phase is to be considered as the wetting phase. + * + * \return the wetting phase index + * \param globalPos The position of the center of the element + */ + template<class FluidSystem> + int wettingPhaseAtPos(const GlobalPosition& globalPos) const + { return FluidSystem::H2OIdx; } + /*! * These parameters are only needed for nonisothermal models. Comment them in if you want to implement the 2pni model. */ diff --git a/tutorial/ex2/injection2p2cproblem.hh b/tutorial/ex2/injection2p2cproblem.hh index 8a280cd3b01cd566e48be249e2ecbc6aa066ecc0..159466e91bb015a30185a1e1e90c3048aa568fc3 100644 --- a/tutorial/ex2/injection2p2cproblem.hh +++ b/tutorial/ex2/injection2p2cproblem.hh @@ -207,8 +207,8 @@ public: { // set the Neumann values for the Nitrogen component balance // convert from units kg/(s*m^2) to mole/(s*m^2) - values[Indices::contiNEqIdx] = -totalAreaSpecificInflow_/FluidSystem::molarMass(FluidSystem::nCompIdx); - values[Indices::contiWEqIdx] = 0.0; + values[Indices::conti0EqIdx + FluidSystem::H2OIdx] = -totalAreaSpecificInflow_/FluidSystem::molarMass(FluidSystem::N2Idx); + values[Indices::conti0EqIdx + FluidSystem::N2Idx] = 0.0; } return values; @@ -232,7 +232,7 @@ public: PrimaryVariables initialAtPos(const GlobalPosition &globalPos) const { PrimaryVariables values(0.0); - values.setState(Indices::wPhaseOnly); + values.setState(Indices::firstPhaseOnly); // get the water density at atmospheric conditions const Scalar densityW = FluidSystem::H2O::liquidDensity(temperature(), 1.0e5); diff --git a/tutorial/ex2/injection2p2cspatialparams.hh b/tutorial/ex2/injection2p2cspatialparams.hh index 1467c696beb4e974421e302c40a32a55b4ceed5a..0c0eb3137599faf72b90e44e871f05a7b2865a3c 100644 --- a/tutorial/ex2/injection2p2cspatialparams.hh +++ b/tutorial/ex2/injection2p2cspatialparams.hh @@ -162,13 +162,23 @@ public: * * \return the material parameters object */ - const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const + const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const { if (isInAquitard_(globalPos)) return aquitardMaterialParams_; return aquiferMaterialParams_; } + /*! + * \brief Function for defining which phase is to be considered as the wetting phase. + * + * \return the wetting phase index + * \param globalPos The position of the center of the element + */ + template<class FluidSystem> + int wettingPhaseAtPos(const GlobalPosition& globalPos) const + { return FluidSystem::H2OIdx; } + /*! * \brief Creates a gnuplot output of the pc-Sw curve */ diff --git a/tutorial/ex3/2p2cproblem.hh b/tutorial/ex3/2p2cproblem.hh index ec08570f9a8e9e00e72542b3e33401a59ffd184d..a6225799182aacdb44a00457a44cd57cfefa2dae 100644 --- a/tutorial/ex3/2p2cproblem.hh +++ b/tutorial/ex3/2p2cproblem.hh @@ -107,11 +107,11 @@ public: std::cout << "If you want to use simplices instead of cubes, install and use dune-ALUGrid or UGGrid." << std::endl; #endif // !(HAVE_DUNE_ALUGRID || HAVE_UG) - // initialize the fluid system - FluidSystem::init(); + // initialize the fluid system + FluidSystem::init(); - // set the depth of the bottom of the reservoir - depthBOR_ = this->fvGridGeometry().bBoxMax()[dimWorld-1]; + // set the depth of the bottom of the reservoir + depthBOR_ = this->fvGridGeometry().bBoxMax()[dimWorld-1]; // name of the problem and output file name_ = getParam<std::string>("Problem.Name"); @@ -170,7 +170,7 @@ public: PrimaryVariables dirichletAtPos(const GlobalPosition &globalPos) const { PrimaryVariables priVars; - priVars.setState(Indices::wPhaseOnly); + priVars.setState(Indices::firstPhaseOnly); priVars[Indices::pressureIdx] = 200.0e3 + 9.81*1000*(depthBOR_ - globalPos[dimWorld-1]); priVars[Indices::switchIdx] = 0.0; // 0 % oil saturation on left boundary return priVars; @@ -196,12 +196,12 @@ public: if (globalPos[dimWorld-1] > up - eps_ && globalPos[0] > 20 && globalPos[0] < 40) { // oil outflux of 30 g/(m * s) on the right boundary. // we solve for the mole balance, so we have to divide by the molar mass - values[Indices::contiWEqIdx] = 0; - values[Indices::contiNEqIdx] = -3e-2/FluidSystem::MyCompressibleComponent::molarMass(); + values[Indices::conti0EqIdx + FluidSystem::H2OIdx] = 0; + values[Indices::conti0EqIdx + FluidSystem::NAPLIdx] = -3e-2/FluidSystem::MyCompressibleComponent::molarMass(); } else { // no-flow on the remaining Neumann-boundaries. - values[Indices::contiWEqIdx] = 0; - values[Indices::contiNEqIdx] = 0; + values[Indices::conti0EqIdx + FluidSystem::H2OIdx] = 0; + values[Indices::conti0EqIdx + FluidSystem::NAPLIdx] = 0; } return values; @@ -226,7 +226,7 @@ public: { PrimaryVariables values(0.0); - values.setState(Indices::wPhaseOnly); + values.setState(Indices::firstPhaseOnly); values[Indices::pressureIdx] = 200.0e3 + 9.81*1000*(depthBOR_ - globalPos[dimWorld-1]); // 200 kPa = 2 bar values[Indices::switchIdx] = 0.0; diff --git a/tutorial/ex3/2pproblem.hh b/tutorial/ex3/2pproblem.hh index 5e9cba0b0cdd192db812a15ecf4d2c1d46aa1dc5..0d79a848bfc5a2a15f04f479c8055e77e5761287 100644 --- a/tutorial/ex3/2pproblem.hh +++ b/tutorial/ex3/2pproblem.hh @@ -117,6 +117,13 @@ class ExerciseThreeProblemTwoP : public PorousMediumFlowProblem<TypeTag> using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry)::LocalView; using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); + enum { + waterPressureIdx = Indices::pressureIdx, + naplSaturationIdx = Indices::saturationIdx, + contiWEqIdx = Indices::conti0EqIdx + FluidSystem::comp0Idx, // water transport equation index + contiNEqIdx = Indices::conti0EqIdx + FluidSystem::comp1Idx // napl transport equation index + }; + public: ExerciseThreeProblemTwoP(std::shared_ptr<const FVGridGeometry> fvGridGeometry) : ParentType(fvGridGeometry) @@ -196,8 +203,8 @@ public: { PrimaryVariables priVars; - priVars[Indices::pwIdx] = 200.0e3 + 9.81*1000*(depthBOR_ - globalPos[dimWorld-1]); // 200 kPa = 2 bar - priVars[Indices::snIdx] = 0.0; // 0 % oil saturation on left boundary + priVars[waterPressureIdx] = 200.0e3 + 9.81*1000*(depthBOR_ - globalPos[dimWorld-1]); // 200 kPa = 2 bar + priVars[naplSaturationIdx] = 0.0; // 0 % oil saturation on left boundary return priVars; } @@ -221,12 +228,12 @@ public: // extraction of oil on the right boundary for approx. 1.e6 seconds if (globalPos[dimWorld-1] > up - eps_ && globalPos[0] > 20 && globalPos[0] < 40) { // oil outflux of 30 g/(m * s) on the right boundary. - values[Indices::contiWEqIdx] = 0; - values[Indices::contiNEqIdx] = -3e-2; + values[contiWEqIdx] = 0; + values[contiNEqIdx] = -3e-2; } else { // no-flow on the remaining Neumann-boundaries. - values[Indices::contiWEqIdx] = 0; - values[Indices::contiNEqIdx] = 0; + values[contiWEqIdx] = 0; + values[contiNEqIdx] = 0; } return values; @@ -252,8 +259,8 @@ public: { PrimaryVariables values(0.0); - values[Indices::pwIdx] = 200.0e3 + 9.81*1000*(depthBOR_ - globalPos[dimWorld-1]); // 200 kPa = 2 bar - values[Indices::snIdx] = 0.0; + values[waterPressureIdx] = 200.0e3 + 9.81*1000*(depthBOR_ - globalPos[dimWorld-1]); // 200 kPa = 2 bar (pw) + values[naplSaturationIdx] = 0.0; // (sn) return values; } diff --git a/tutorial/ex3/fluidsystems/h2omycompressiblecomponent.hh b/tutorial/ex3/fluidsystems/h2omycompressiblecomponent.hh index 43c84c8a0e6813ad1ae7df110253bcc27248c4a6..e98c1a011f39db1f15f39084de77035e5e975612 100644 --- a/tutorial/ex3/fluidsystems/h2omycompressiblecomponent.hh +++ b/tutorial/ex3/fluidsystems/h2omycompressiblecomponent.hh @@ -58,20 +58,19 @@ public: typedef Dumux::MyCompressibleComponent<Scalar> MyCompressibleComponent; typedef H2OType H2O; - static const int numPhases = 2; - static const int numComponents = 2; + static constexpr int numPhases = 2; + static constexpr int numComponents = 2; - static const int wPhaseIdx = 0; // index of the water phase - static const int nPhaseIdx = 1; // index of the NAPL phase - - static const int H2OIdx = 0; - static const int NAPLIdx = 1; + static constexpr int phase0Idx = 0; // index of the first phase + static constexpr int phase1Idx = 1; // index of the second phase + static constexpr int H2OIdx = 0; + static constexpr int NAPLIdx = 1; // export component indices to indicate the main component // of the corresponding phase at atmospheric pressure 1 bar // and room temperature 20°C: - static const int wCompIdx = H2OIdx; - static const int nCompIdx = NAPLIdx; + static constexpr int comp0Idx = H2OIdx; + static constexpr int comp1Idx = NAPLIdx; /*! * \brief Initialize the fluid system's static parameters generically @@ -119,13 +118,13 @@ public: * * \param phaseIdx The index of the fluid phase to consider */ - static bool isLiquid(int phaseIdx) + static constexpr bool isLiquid(int phaseIdx) { assert(0 <= phaseIdx && phaseIdx < numPhases); return true; } - static bool isIdealGas(int phaseIdx) + static constexpr bool isIdealGas(int phaseIdx) { return H2O::gasIsIdeal() && MyCompressibleComponent::gasIsIdeal(); } /*! @@ -142,7 +141,7 @@ public: * * \param phaseIdx The index of the fluid phase to consider */ - static bool isIdealMixture(int phaseIdx) + static constexpr bool isIdealMixture(int phaseIdx) { assert(0 <= phaseIdx && phaseIdx < numPhases); return true; @@ -157,10 +156,10 @@ public: * * \param phaseIdx The index of the fluid phase to consider */ - static bool isCompressible(int phaseIdx) + static constexpr bool isCompressible(int phaseIdx) { assert(0 <= phaseIdx && phaseIdx < numPhases); - if (phaseIdx == wPhaseIdx) + if (phaseIdx == phase0Idx) // the water component decides for the water phase... return H2O::liquidIsCompressible(); @@ -174,8 +173,8 @@ public: static std::string phaseName(int phaseIdx) { switch (phaseIdx) { - case wPhaseIdx: return "w"; - case nPhaseIdx: return "n"; + case phase0Idx: return "w"; + case phase1Idx: return "n"; }; DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx); } @@ -213,15 +212,15 @@ public: static Scalar density(const FluidState &fluidState, int phaseIdx) { assert(0 <= phaseIdx && phaseIdx < numPhases); - if (phaseIdx == wPhaseIdx) { + if (phaseIdx == phase0Idx) { // See: doctoral thesis of Steffen Ochs 2007 // Steam injection into saturated porous media : process analysis including experimental and numerical investigations // http://elib.uni-stuttgart.de/bitstream/11682/271/1/Diss_Ochs_OPUS.pdf // Scalar rholH2O = H2O::liquidDensity(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx)); // Scalar clH2O = rholH2O/H2O::molarMass(); - // Scalar x_H2O = fluidState.moleFraction(wPhaseIdx, H2OIdx); - // Scalar x_myComp = fluidState.moleFraction(wPhaseIdx, NAPLIdx); + // Scalar x_H2O = fluidState.moleFraction phase0Idx, H2OIdx); + // Scalar x_myComp = fluidState.moleFraction phase0Idx, NAPLIdx); /*! * TODO: implement the composition-dependent water density from the exercise sheet. @@ -244,7 +243,7 @@ public: int phaseIdx) { assert(0 <= phaseIdx && phaseIdx < numPhases); - if (phaseIdx == wPhaseIdx) { + if (phaseIdx == phase0Idx) { // assume pure water viscosity return H2O::liquidViscosity(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx)); @@ -303,10 +302,10 @@ public: const Scalar T = fluidState.temperature(phaseIdx); const Scalar p = fluidState.pressure(phaseIdx); - if (compIdx == NAPLIdx && phaseIdx == wPhaseIdx) + if (compIdx == NAPLIdx && phaseIdx == phase0Idx) return Dumux::BinaryCoeff::H2O_MyCompressibleComponent::henryMyCompressibleComponentInWater(T)/p; - else if (phaseIdx == nPhaseIdx && compIdx == H2OIdx) + else if (phaseIdx == phase1Idx && compIdx == H2OIdx) return Dumux::BinaryCoeff::H2O_MyCompressibleComponent::henryWaterInMyCompressibleComponent(T)/p; else @@ -339,7 +338,7 @@ public: Scalar T = fluidState.temperature(phaseIdx); Scalar p = fluidState.pressure(phaseIdx); - if (phaseIdx == wPhaseIdx) { + if (phaseIdx == phase0Idx) { if (compIdx == H2OIdx) return H2O::vaporPressure(T)/p; else if (compIdx == NAPLIdx) @@ -432,7 +431,7 @@ public: const Scalar temperature = fluidState.temperature(phaseIdx) ; const Scalar pressure = fluidState.pressure(phaseIdx); - if (phaseIdx == wPhaseIdx) + if (phaseIdx == phase0Idx) { return H2O::liquidThermalConductivity(temperature, pressure); } diff --git a/tutorial/ex3/spatialparams.hh b/tutorial/ex3/spatialparams.hh index 954385ae1a5daa9bdaf7b7e4b0e8dedbc337d65d..1bec0b8356e52e137cd8159a737b63bc59784a10 100644 --- a/tutorial/ex3/spatialparams.hh +++ b/tutorial/ex3/spatialparams.hh @@ -118,13 +118,23 @@ public: * * \return the material parameters object */ - const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const + const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const { if (isInLens(globalPos)) return materialParamsLens_; return materialParams_; } + /*! + * \brief Function for defining which phase is to be considered as the wetting phase. + * + * \return the wetting phase index + * \param globalPos The position of the center of the element + */ + template<class FluidSystem> + int wettingPhaseAtPos(const GlobalPosition& globalPos) const + { return FluidSystem::phase0Idx; } + /*! * \brief The constructor * diff --git a/tutorial/solution/ex1/CMakeLists.txt b/tutorial/solution/ex1/CMakeLists.txt index 7e261939f9faf0795264e54dd70cb2401a9d88bc..1b245486c92a54041492238657595282b0f6f351 100644 --- a/tutorial/solution/ex1/CMakeLists.txt +++ b/tutorial/solution/ex1/CMakeLists.txt @@ -15,7 +15,7 @@ dune_add_test(NAME exercise1_2pni_solution # add tutorial to the common target -add_dependencies(build_tutorials exercise1_2pni_solution) +add_dependencies(build_tutorials exercise1_2p2c_solution exercise1_2pni_solution) # add a symlink for the input file dune_symlink_to_source_files(FILES "exercise1.input") diff --git a/tutorial/solution/ex1/injection2p2cproblem.hh b/tutorial/solution/ex1/injection2p2cproblem.hh index fe91d9352c135b7f978f1ce6168c071c9bcbcb4b..fad1fdf151ed88f4ed2bbf74d7d9a39658b21f2d 100644 --- a/tutorial/solution/ex1/injection2p2cproblem.hh +++ b/tutorial/solution/ex1/injection2p2cproblem.hh @@ -92,6 +92,11 @@ class Injection2p2cProblem : public PorousMediumFlowProblem<TypeTag> enum { dimWorld = GridView::dimensionworld }; using GlobalPosition = Dune::FieldVector<Scalar, GridView::dimension>; + enum { + contiWEqIdx = Indices::conti0EqIdx + FluidSystem::H2OIdx, // water transport equation index + contiNEqIdx = Indices::conti0EqIdx + FluidSystem::N2Idx, // nitrogen transport equation index + }; + public: Injection2p2cProblem(std::shared_ptr<const FVGridGeometry> fvGridGeometry) : ParentType(fvGridGeometry) @@ -195,8 +200,8 @@ public: // inject nitrogen. negative values mean injection // convert from units kg/(s*m^2) to mole/(s*m^2) - values[Indices::contiNEqIdx] = totalAreaSpecificInflow_/FluidSystem::molarMass(FluidSystem::nCompIdx); - values[Indices::contiWEqIdx] = 0.0; + values[contiNEqIdx] = totalAreaSpecificInflow_/FluidSystem::molarMass(FluidSystem::N2Idx); + values[contiWEqIdx] = 0.0; } return values; @@ -221,7 +226,7 @@ public: PrimaryVariables initialAtPos(const GlobalPosition &globalPos) const { PrimaryVariables values(0.0); - values.setState(Indices::wPhaseOnly); + values.setState(Indices::firstPhaseOnly); // get the water density at atmospheric conditions const Scalar densityW = FluidSystem::H2O::liquidDensity(temperature(), 1.0e5); diff --git a/tutorial/solution/ex1/injection2pniproblem.hh b/tutorial/solution/ex1/injection2pniproblem.hh index 90812e9925608a4d572e3bd1ca4ae5a166f0f81f..20fda3e097452508581184fb22f191af71393d45 100644 --- a/tutorial/solution/ex1/injection2pniproblem.hh +++ b/tutorial/solution/ex1/injection2pniproblem.hh @@ -90,6 +90,12 @@ class InjectionProblem2PNI : public PorousMediumFlowProblem<TypeTag> enum { dimWorld = GridView::dimensionworld }; using GlobalPosition = Dune::FieldVector<Scalar, GridView::dimension>; + enum { + contiWEqIdx = Indices::conti0EqIdx + FluidSystem::H2OIdx, // water transport equation index + contiNEqIdx = Indices::conti0EqIdx + FluidSystem::N2Idx, // nitrogen transport equation index + energyEqIdx = Indices::energyEqIdx, + }; + public: InjectionProblem2PNI(std::shared_ptr<const FVGridGeometry> fvGridGeometry) : ParentType(fvGridGeometry) @@ -181,9 +187,9 @@ public: { // inject nitrogen. negative values mean injection // units kg/(s*m^2) - values[Indices::contiNEqIdx] = -1e-4; - values[Indices::contiWEqIdx] = 0.0; - values[Indices::energyEqIdx] = 0.0; + values[contiNEqIdx] = -1e-4; + values[contiWEqIdx] = 0.0; + values[energyEqIdx] = 0.0; } return values; diff --git a/tutorial/solution/ex1/injection2pspatialparams.hh b/tutorial/solution/ex1/injection2pspatialparams.hh index 0741103053f0600a77e156125b59d2ef3e47face..3b087bafff89ec9655d51e8e4afa259385759f6b 100644 --- a/tutorial/solution/ex1/injection2pspatialparams.hh +++ b/tutorial/solution/ex1/injection2pspatialparams.hh @@ -144,13 +144,23 @@ public: * * \return the material parameters object */ - const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const + const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const { if (isInAquitard_(globalPos)) return aquitardMaterialParams_; return aquiferMaterialParams_; } + /*! + * \brief Function for defining which phase is to be considered as the wetting phase. + * + * \return the wetting phase index + * \param globalPos The position of the center of the element + */ + template<class FluidSystem> + int wettingPhaseAtPos(const GlobalPosition& globalPos) const + { return FluidSystem::H2OIdx; } + /*! * These parameters are only needed for nonisothermal models. Comment them in if you want to implement the 2pni model. */ diff --git a/tutorial/solution/ex2/injection2p2cproblem.hh b/tutorial/solution/ex2/injection2p2cproblem.hh index ea8c5b1b170762b5b1eed9bceae22e959019a539..7ab57db74602f95f0001c8900d726f465b174fb1 100644 --- a/tutorial/solution/ex2/injection2p2cproblem.hh +++ b/tutorial/solution/ex2/injection2p2cproblem.hh @@ -95,6 +95,7 @@ class Injection2p2cProblem : public PorousMediumFlowProblem<TypeTag> using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); using Indices = typename GET_PROP_TYPE(TypeTag, ModelTraits)::Indices; + using NumEqVector = typename GET_PROP_TYPE(TypeTag, NumEqVector); using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables); using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes); using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry); @@ -194,10 +195,10 @@ public: * For this method, the \a values parameter stores the mass flux * in normal direction of each phase. Negative values mean influx. */ - PrimaryVariables neumannAtPos(const GlobalPosition &globalPos) const + NumEqVector neumannAtPos(const GlobalPosition &globalPos) const { // initialize values to zero, i.e. no-flow Neumann boundary conditions - PrimaryVariables values(0.0); + NumEqVector values(0.0); //if we are inside the injection zone set inflow Neumann boundary conditions if (time_ < injectionDuration_ @@ -205,8 +206,7 @@ public: { // set the Neumann values for the Nitrogen component balance // convert from units kg/(s*m^2) to mole/(s*m^2) - values[Indices::contiNEqIdx] = -totalAreaSpecificInflow_/FluidSystem::molarMass(FluidSystem::nCompIdx); - values[Indices::contiWEqIdx] = 0.0; + values[Indices::conti0EqIdx + FluidSystem::N2Idx] = -totalAreaSpecificInflow_/FluidSystem::molarMass(FluidSystem::N2Idx); } return values; @@ -230,7 +230,7 @@ public: PrimaryVariables initialAtPos(const GlobalPosition &globalPos) const { PrimaryVariables values(0.0); - values.setState(Indices::wPhaseOnly); + values.setState(Indices::firstPhaseOnly); // get the water density at atmospheric conditions const Scalar densityW = FluidSystem::H2O::liquidDensity(temperature(), 1.0e5); diff --git a/tutorial/solution/ex2/injection2p2cspatialparams.hh b/tutorial/solution/ex2/injection2p2cspatialparams.hh index 3c4d63d8ac54cc0501df2167b53b2be5fbb2f8a0..561d42ae42cbd1ae5df36c653d314fa66643d1f9 100644 --- a/tutorial/solution/ex2/injection2p2cspatialparams.hh +++ b/tutorial/solution/ex2/injection2p2cspatialparams.hh @@ -167,6 +167,16 @@ public: return aquiferMaterialParams_; } + /*! + * \brief Function for defining which phase is to be considered as the wetting phase. + * + * \return the wetting phase index + * \param globalPos The position of the center of the element + */ + template<class FluidSystem> + int wettingPhaseAtPos(const GlobalPosition& globalPos) const + { return FluidSystem::H2OIdx; } + /*! * \brief Creates a gnuplot output of the pc-Sw curve */ diff --git a/tutorial/solution/ex3/h2omycompressiblecomponent.hh b/tutorial/solution/ex3/h2omycompressiblecomponent.hh index e9ce1ed89bc80e3117beab375fb70acd53fbb499..80995530eba36be1ebe54ea3047eb731ad14b8f4 100644 --- a/tutorial/solution/ex3/h2omycompressiblecomponent.hh +++ b/tutorial/solution/ex3/h2omycompressiblecomponent.hh @@ -58,20 +58,19 @@ public: typedef Dumux::MyCompressibleComponent<Scalar> MyCompressibleComponent; typedef H2OType H2O; - static const int numPhases = 2; - static const int numComponents = 2; + static constexpr int numPhases = 2; + static constexpr int numComponents = 2; - static const int wPhaseIdx = 0; // index of the water phase - static const int nPhaseIdx = 1; // index of the NAPL phase - - static const int H2OIdx = 0; - static const int NAPLIdx = 1; + static constexpr int phase0Idx = 0; // index of the first phase + static constexpr int phase1Idx = 1; // index of the second phase + static constexpr int H2OIdx = 0; + static constexpr int NAPLIdx = 1; // export component indices to indicate the main component // of the corresponding phase at atmospheric pressure 1 bar // and room temperature 20°C: - static const int wCompIdx = H2OIdx; - static const int nCompIdx = NAPLIdx; + static constexpr int comp0Idx = H2OIdx; + static constexpr int comp1Idx = NAPLIdx; /*! * \brief Initialize the fluid system's static parameters generically @@ -119,13 +118,13 @@ public: * * \param phaseIdx The index of the fluid phase to consider */ - static bool isLiquid(int phaseIdx) + static constexpr bool isLiquid(int phaseIdx) { assert(0 <= phaseIdx && phaseIdx < numPhases); return true; } - static bool isIdealGas(int phaseIdx) + static constexpr bool isIdealGas(int phaseIdx) { return H2O::gasIsIdeal() && MyCompressibleComponent::gasIsIdeal(); } /*! @@ -142,7 +141,7 @@ public: * * \param phaseIdx The index of the fluid phase to consider */ - static bool isIdealMixture(int phaseIdx) + static constexpr bool isIdealMixture(int phaseIdx) { assert(0 <= phaseIdx && phaseIdx < numPhases); return true; @@ -157,10 +156,10 @@ public: * * \param phaseIdx The index of the fluid phase to consider */ - static bool isCompressible(int phaseIdx) + static constexpr bool isCompressible(int phaseIdx) { assert(0 <= phaseIdx && phaseIdx < numPhases); - if (phaseIdx == wPhaseIdx) + if (phaseIdx == phase0Idx) // the water component decides for the water phase... return H2O::liquidIsCompressible(); @@ -174,8 +173,8 @@ public: static std::string phaseName(int phaseIdx) { switch (phaseIdx) { - case wPhaseIdx: return "w"; - case nPhaseIdx: return "n"; + case phase0Idx: return "w"; + case phase1Idx: return "n"; }; DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx); } @@ -213,14 +212,14 @@ public: static Scalar density(const FluidState &fluidState, int phaseIdx) { assert(0 <= phaseIdx && phaseIdx < numPhases); - if (phaseIdx == wPhaseIdx) { + if (phaseIdx == phase0Idx) { // See: doctoral thesis of Steffen Ochs 2007 // Steam injection into saturated porous media : process analysis including experimental and numerical investigations // http://elib.uni-stuttgart.de/bitstream/11682/271/1/Diss_Ochs_OPUS.pdf Scalar rholH2O = H2O::liquidDensity(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx)); Scalar clH2O = rholH2O/H2O::molarMass(); - Scalar x_H2O = fluidState.moleFraction(wPhaseIdx, H2OIdx); - Scalar x_myComp = fluidState.moleFraction(wPhaseIdx, NAPLIdx); + Scalar x_H2O = fluidState.moleFraction(phase0Idx, H2OIdx); + Scalar x_myComp = fluidState.moleFraction(phase0Idx, NAPLIdx); // return composition-dependent water phase density return clH2O*(H2O::molarMass()*x_H2O + MyCompressibleComponent::molarMass()*x_myComp); @@ -241,7 +240,7 @@ public: int phaseIdx) { assert(0 <= phaseIdx && phaseIdx < numPhases); - if (phaseIdx == wPhaseIdx) { + if (phaseIdx == phase0Idx) { // assume pure water viscosity return H2O::liquidViscosity(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx)); @@ -300,10 +299,10 @@ public: const Scalar T = fluidState.temperature(phaseIdx); const Scalar p = fluidState.pressure(phaseIdx); - if (compIdx == NAPLIdx && phaseIdx == wPhaseIdx) + if (compIdx == NAPLIdx && phaseIdx == phase0Idx) return Dumux::BinaryCoeff::H2O_MyCompressibleComponent::henryMyCompressibleComponentInWater(T)/p; - else if (phaseIdx == nPhaseIdx && compIdx == H2OIdx) + else if (phaseIdx == phase1Idx && compIdx == H2OIdx) return Dumux::BinaryCoeff::H2O_MyCompressibleComponent::henryWaterInMyCompressibleComponent(T)/p; else @@ -336,7 +335,7 @@ public: Scalar T = fluidState.temperature(phaseIdx); Scalar p = fluidState.pressure(phaseIdx); - if (phaseIdx == wPhaseIdx) { + if (phaseIdx == phase0Idx) { if (compIdx == H2OIdx) return H2O::vaporPressure(T)/p; else if (compIdx == NAPLIdx) @@ -410,7 +409,7 @@ public: int phaseIdx) { assert(0 <= phaseIdx && phaseIdx < numPhases); - if (phaseIdx == wPhaseIdx) { + if (phaseIdx == phase0Idx) { return H2O::liquidEnthalpy(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx)); } else { @@ -436,7 +435,7 @@ public: const Scalar temperature = fluidState.temperature(phaseIdx) ; const Scalar pressure = fluidState.pressure(phaseIdx); - if (phaseIdx == wPhaseIdx) + if (phaseIdx == phase0Idx) { return H2O::liquidThermalConductivity(temperature, pressure); }