3.1-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
misciblemultiphasecomposition.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3/*****************************************************************************
4 * See the file COPYING for full copying permissions. *
5 * *
6 * This program is free software: you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation, either version 3 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 *****************************************************************************/
26#ifndef DUMUX_MISCIBLE_MULTIPHASE_COMPOSITION_HH
27#define DUMUX_MISCIBLE_MULTIPHASE_COMPOSITION_HH
28
29#include <dune/common/fvector.hh>
30#include <dune/common/fmatrix.hh>
31
34
35namespace Dumux {
58template <class Scalar, class FluidSystem>
60{
61 static constexpr int numPhases = FluidSystem::numPhases;
62 static constexpr int numComponents = FluidSystem::numComponents;
63 static const int numMajorComponents = FluidSystem::numPhases;
64
65public:
81 template <class FluidState, class ParameterCache>
82 static void solve(FluidState &fluidState,
83 ParameterCache &paramCache,
84 int knownPhaseIdx = 0)
85 {
86#ifndef NDEBUG
87 // currently this solver can only handle fluid systems which
88 // assume ideal mixtures of all fluids. TODO: relax this
89 // (requires solving a non-linear system of equations, i.e. using
90 // Newton method.)
91 for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
92 assert(FluidSystem::isIdealMixture(phaseIdx));
93
94 }
95#endif
96
97 //get the known mole fractions from the fluidState
98 //in a 2pnc system the n>2 mole fractions are primary variables and are already set in the fluidstate
99 Dune::FieldVector<Scalar, numComponents-numMajorComponents> xKnown(0.0);
100 for (int knownCompIdx = 0; knownCompIdx < numComponents-numMajorComponents; ++knownCompIdx)
101 {
102 xKnown[knownCompIdx] = fluidState.moleFraction(knownPhaseIdx, knownCompIdx + numMajorComponents);
103 }
104
105 // compute all fugacity coefficients
106 for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
107 paramCache.updatePhase(fluidState, phaseIdx);
108
109 // since we assume ideal mixtures, the fugacity
110 // coefficients of the components cannot depend on
111 // composition, i.e. the parameters in the cache are valid
112 for (int compIdx = 0; compIdx < numComponents; ++compIdx) {
113 Scalar fugCoeff = FluidSystem::fugacityCoefficient(fluidState, paramCache, phaseIdx, compIdx);
114 fluidState.setFugacityCoefficient(phaseIdx, compIdx, fugCoeff);
115 }
116 }
117
118
119 // create the linear system of equations which defines the
120 // mole fractions
121 Dune::FieldMatrix<Scalar, numComponents*numPhases, numComponents*numPhases> M(0.0);
122 Dune::FieldVector<Scalar, numComponents*numPhases> x(0.0);
123 Dune::FieldVector<Scalar, numComponents*numPhases> b(0.0);
124
125 // assemble the equations expressing the assumption that the
126 // sum of all mole fractions in each phase must be 1
127 for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
128 int rowIdx = numComponents*(numPhases - 1) + phaseIdx;
129 b[rowIdx] = 1.0;
130
131 for (int compIdx = 0; compIdx < numComponents; ++compIdx) {
132 int colIdx = phaseIdx*numComponents + compIdx;
133
134 M[rowIdx][colIdx] = 1.0;
135 }
136 }
137
138 // set the additional equations for the numComponents-numMajorComponents
139 // this is only relevant if numphases != numcomponents e.g. in a 2pnc system
140 // Components, of which the mole fractions are known, set to molefraction(knownCompIdx)=xKnown
141 for(int knownCompIdx = 0; knownCompIdx < numComponents-numMajorComponents; ++knownCompIdx)
142 {
143 int rowIdx = numComponents + numPhases + knownCompIdx;
144 int colIdx = knownPhaseIdx*numComponents + knownCompIdx + numMajorComponents;
145 M[rowIdx][colIdx] = 1.0;
146 b[rowIdx] = xKnown[knownCompIdx];
147 }
148
149 // assemble the equations expressing the fact that the
150 // fugacities of each component are equal in all phases
151 for (int compIdx = 0; compIdx < numComponents; ++compIdx)
152 {
153 int col1Idx = compIdx;
154 const auto entryPhase0 = fluidState.fugacityCoefficient(0, compIdx)*fluidState.pressure(0);
155
156 for (unsigned int phaseIdx = 1; phaseIdx < numPhases; ++phaseIdx)
157 {
158 int rowIdx = (phaseIdx - 1)*numComponents + compIdx;
159 int col2Idx = phaseIdx*numComponents + compIdx;
160 M[rowIdx][col1Idx] = entryPhase0;
161 M[rowIdx][col2Idx] = -fluidState.fugacityCoefficient(phaseIdx, compIdx)*fluidState.pressure(phaseIdx);
162 }
163 }
164
165 // preconditioning of M to reduce condition number
166 for (int compIdx = 0; compIdx < numComponents; compIdx++)
167 {
168 // Multiply row of main component (Raoult's Law) with 10e-5 (order of magn. of pressure)
169 if (compIdx < numMajorComponents)
170 M[compIdx] *= 10e-5;
171
172 // Multiply row of sec. components (Henry's Law) with 10e-9 (order of magn. of Henry constant)
173 else
174 M[compIdx] *= 10e-9;
175 }
176
177 // solve for all mole fractions
178 try { M.solve(x, b); }
179 catch (Dune::FMatrixError & e) {
180 DUNE_THROW(NumericalProblem,
181 "Matrix for composition of phases could not be solved. \n"
182 "Throwing NumericalProblem for trying with smaller timestep.");
183 }
184 catch (...) {
185 std::cerr << "Unknown exception thrown!\n";
186 exit(1);
187 }
188
189 // set all mole fractions and the the additional quantities in
190 // the fluid state
191 for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
192 for (int compIdx = 0; compIdx < numComponents; ++compIdx) {
193 int rowIdx = phaseIdx*numComponents + compIdx;
194 fluidState.setMoleFraction(phaseIdx, compIdx, x[rowIdx]);
195 }
196 paramCache.updateComposition(fluidState, phaseIdx);
197
198 Scalar value = FluidSystem::density(fluidState, paramCache, phaseIdx);
199 fluidState.setDensity(phaseIdx, value);
200
201 value = FluidSystem::molarDensity(fluidState, paramCache, phaseIdx);
202 fluidState.setMolarDensity(phaseIdx, value);
203 }
204 }
205};
206
207} // end namespace Dumux
208
209#endif
Some exceptions thrown in DuMux
Some templates to wrap the valgrind macros.
make the local view function available whenever we use the grid geometry
Definition: adapt.hh:29
std::string molarDensity(int phaseIdx) noexcept
I/O name of molar density for multiphase systems.
Definition: name.hh:83
std::string density(int phaseIdx) noexcept
I/O name of density for multiphase systems.
Definition: name.hh:65
Exception thrown if a fixable numerical problem occurs.
Definition: exceptions.hh:39
Computes the composition of all phases of a N-phase, N-component fluid system assuming that all N pha...
Definition: misciblemultiphasecomposition.hh:60
static void solve(FluidState &fluidState, ParameterCache &paramCache, int knownPhaseIdx=0)
Computes the composition of all phases of a N-phase, N-component fluid system assuming that all N pha...
Definition: misciblemultiphasecomposition.hh:82