blackoillocalresidual.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 This file is part of the Open Porous Media project (OPM).
5
6 OPM 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 2 of the License, or
9 (at your option) any later version.
10
11 OPM 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 OPM. If not, see <http://www.gnu.org/licenses/>.
18
19 Consult the COPYING file in the top-level source directory of this
20 module for the precise wording of the license and the list of
21 copyright holders.
22*/
28#ifndef EWOMS_BLACK_OIL_LOCAL_RESIDUAL_HH
29#define EWOMS_BLACK_OIL_LOCAL_RESIDUAL_HH
30
31#include <opm/material/common/MathToolbox.hpp>
32#include <opm/material/fluidstates/BlackOilFluidState.hpp>
33
44
45#include <cassert>
46
47namespace Opm {
48
54template <class TypeTag>
55class BlackOilLocalResidual : public GetPropType<TypeTag, Properties::DiscLocalResidual>
56{
65
66 enum { conti0EqIdx = Indices::conti0EqIdx };
67 enum { numEq = getPropValue<TypeTag, Properties::NumEq>() };
68 enum { numPhases = getPropValue<TypeTag, Properties::NumPhases>() };
69 enum { numComponents = getPropValue<TypeTag, Properties::NumComponents>() };
70
71 enum { gasPhaseIdx = FluidSystem::gasPhaseIdx };
72 enum { oilPhaseIdx = FluidSystem::oilPhaseIdx };
73 enum { waterPhaseIdx = FluidSystem::waterPhaseIdx };
74
75 enum { gasCompIdx = FluidSystem::gasCompIdx };
76 enum { oilCompIdx = FluidSystem::oilCompIdx };
77 enum { waterCompIdx = FluidSystem::waterCompIdx };
78 enum { compositionSwitchIdx = Indices::compositionSwitchIdx };
79
80 static constexpr bool waterEnabled = Indices::waterEnabled;
81 static constexpr bool gasEnabled = Indices::gasEnabled;
82 static constexpr bool oilEnabled = Indices::oilEnabled;
83 static constexpr bool compositionSwitchEnabled = (compositionSwitchIdx >= 0);
84
85 static constexpr bool blackoilConserveSurfaceVolume = getPropValue<TypeTag, Properties::BlackoilConserveSurfaceVolume>();
86 static constexpr bool enableEnergy = getPropValue<TypeTag, Properties::EnableEnergy>();
87 static constexpr bool enableDiffusion = getPropValue<TypeTag, Properties::EnableDiffusion>();
88 static constexpr bool enableConvectiveMixing = getPropValue<TypeTag, Properties::EnableConvectiveMixing>();
89
90 using Toolbox = MathToolbox<Evaluation>;
100
101public:
105 template <class LhsEval>
106 void computeStorage(Dune::FieldVector<LhsEval, numEq>& storage,
107 const ElementContext& elemCtx,
108 unsigned dofIdx,
109 unsigned timeIdx) const
110 {
111 // retrieve the intensive quantities for the SCV at the specified point in time
112 const IntensiveQuantities& intQuants = elemCtx.intensiveQuantities(dofIdx, timeIdx);
113 const auto& fs = intQuants.fluidState();
114
115 storage = 0.0;
116
117 for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
118 if (!FluidSystem::phaseIsActive(phaseIdx)) {
119 if (Indices::numPhases == 3) { // add trivial equation for the pseudo phase
120 const unsigned activeCompIdx =
121 FluidSystem::canonicalToActiveCompIdx(FluidSystem::solventComponentIndex(phaseIdx));
122 if (timeIdx == 0) {
123 storage[conti0EqIdx + activeCompIdx] = variable<LhsEval>(0.0, conti0EqIdx + activeCompIdx);
124 }
125 else {
126 storage[conti0EqIdx + activeCompIdx] = 0.0;
127 }
128 }
129 continue;
130 }
131
132 const unsigned activeCompIdx =
133 FluidSystem::canonicalToActiveCompIdx(FluidSystem::solventComponentIndex(phaseIdx));
134 const LhsEval surfaceVolume =
135 Toolbox::template decay<LhsEval>(fs.saturation(phaseIdx)) *
136 Toolbox::template decay<LhsEval>(fs.invB(phaseIdx)) *
137 Toolbox::template decay<LhsEval>(intQuants.porosity());
138
139 storage[conti0EqIdx + activeCompIdx] += surfaceVolume;
140
141 // account for dissolved gas
142 if (phaseIdx == oilPhaseIdx && FluidSystem::enableDissolvedGas()) {
143 const unsigned activeGasCompIdx = FluidSystem::canonicalToActiveCompIdx(gasCompIdx);
144 storage[conti0EqIdx + activeGasCompIdx] +=
145 Toolbox::template decay<LhsEval>(intQuants.fluidState().Rs()) *
146 surfaceVolume;
147 }
148
149 // account for dissolved gas in water phase
150 if (phaseIdx == waterPhaseIdx && FluidSystem::enableDissolvedGasInWater()) {
151 const unsigned activeGasCompIdx = FluidSystem::canonicalToActiveCompIdx(gasCompIdx);
152 storage[conti0EqIdx + activeGasCompIdx] +=
153 Toolbox::template decay<LhsEval>(intQuants.fluidState().Rsw()) *
154 surfaceVolume;
155 }
156
157 // account for vaporized oil
158 if (phaseIdx == gasPhaseIdx && FluidSystem::enableVaporizedOil()) {
159 const unsigned activeOilCompIdx = FluidSystem::canonicalToActiveCompIdx(oilCompIdx);
160 storage[conti0EqIdx + activeOilCompIdx] +=
161 Toolbox::template decay<LhsEval>(intQuants.fluidState().Rv()) *
162 surfaceVolume;
163 }
164
165 // account for vaporized water
166 if (phaseIdx == gasPhaseIdx && FluidSystem::enableVaporizedWater()) {
167 const unsigned activeWaterCompIdx = FluidSystem::canonicalToActiveCompIdx(waterCompIdx);
168 storage[conti0EqIdx + activeWaterCompIdx] +=
169 Toolbox::template decay<LhsEval>(intQuants.fluidState().Rvw()) *
170 surfaceVolume;
171 }
172 }
173
174 adaptMassConservationQuantities_(storage, intQuants.pvtRegionIndex());
175
176 // deal with solvents (if present)
177 SolventModule::addStorage(storage, intQuants);
178
179 // deal with zFracton (if present)
180 ExtboModule::addStorage(storage, intQuants);
181
182 // deal with polymer (if present)
183 PolymerModule::addStorage(storage, intQuants);
184
185 // deal with energy (if present)
186 EnergyModule::addStorage(storage, intQuants);
187
188 // deal with foam (if present)
189 FoamModule::addStorage(storage, intQuants);
190
191 // deal with salt (if present)
192 BrineModule::addStorage(storage, intQuants);
193
194 // deal with bioeffects (if present)
195 BioeffectsModule::addStorage(storage, intQuants);
196 }
197
201 void computeFlux(RateVector& flux,
202 const ElementContext& elemCtx,
203 unsigned scvfIdx,
204 unsigned timeIdx) const
205 {
206 assert(timeIdx == 0);
207
208 flux = 0.0;
209
210 const ExtensiveQuantities& extQuants = elemCtx.extensiveQuantities(scvfIdx, timeIdx);
211 unsigned focusDofIdx = elemCtx.focusDofIndex();
212 for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
213 if (!FluidSystem::phaseIsActive(phaseIdx)) {
214 continue;
215 }
216
217 const unsigned upIdx = static_cast<unsigned>(extQuants.upstreamIndex(phaseIdx));
218 const IntensiveQuantities& up = elemCtx.intensiveQuantities(upIdx, timeIdx);
219 const unsigned pvtRegionIdx = up.pvtRegionIndex();
220 if (upIdx == focusDofIdx) {
221 evalPhaseFluxes_<Evaluation>(flux, phaseIdx, pvtRegionIdx, extQuants, up.fluidState());
222 }
223 else {
224 evalPhaseFluxes_<Scalar>(flux, phaseIdx, pvtRegionIdx, extQuants, up.fluidState());
225 }
226 }
227 // deal with solvents (if present)
228 SolventModule::computeFlux(flux, elemCtx, scvfIdx, timeIdx);
229
230 // deal with zFracton (if present)
231 ExtboModule::computeFlux(flux, elemCtx, scvfIdx, timeIdx);
232
233 // deal with polymer (if present)
234 PolymerModule::computeFlux(flux, elemCtx, scvfIdx, timeIdx);
235
236 // deal with energy (if present)
237 EnergyModule::computeFlux(flux, elemCtx, scvfIdx, timeIdx);
238
239 // deal with foam (if present)
240 FoamModule::computeFlux(flux, elemCtx, scvfIdx, timeIdx);
241
242 // deal with salt (if present)
243 BrineModule::computeFlux(flux, elemCtx, scvfIdx, timeIdx);
244
245 // deal with bioeffects (if present)
246 BioeffectsModule::computeFlux(flux, elemCtx, scvfIdx, timeIdx);
247
248 // deal with diffusion (if present)
249 DiffusionModule::addDiffusiveFlux(flux, elemCtx, scvfIdx, timeIdx);
250
251 // deal with convective mixing (if enabled)
252 ConvectiveMixingModule::addConvectiveMixingFlux(flux, elemCtx, scvfIdx, timeIdx);
253 }
254
258 void computeSource(RateVector& source,
259 const ElementContext& elemCtx,
260 unsigned dofIdx,
261 unsigned timeIdx) const
262 {
263 // retrieve the source term intrinsic to the problem
264 elemCtx.problem().source(source, elemCtx, dofIdx, timeIdx);
265
266 // deal with MICP (if present)
267 BioeffectsModule::addSource(source, elemCtx, dofIdx, timeIdx);
268
269 // scale the source term of the energy equation
270 if constexpr (enableEnergy) {
271 source[Indices::contiEnergyEqIdx] *=
272 getPropValue<TypeTag, Properties::BlackOilEnergyScalingFactor>();
273 }
274 }
275
280 template <class UpEval, class FluidState>
281 static void evalPhaseFluxes_(RateVector& flux,
282 unsigned phaseIdx,
283 unsigned pvtRegionIdx,
284 const ExtensiveQuantities& extQuants,
285 const FluidState& upFs)
286 {
287 const auto& invB = getInvB_<FluidSystem, FluidState, UpEval>(upFs, phaseIdx, pvtRegionIdx);
288 const auto& surfaceVolumeFlux = invB*extQuants.volumeFlux(phaseIdx);
289 const unsigned activeCompIdx =
290 FluidSystem::canonicalToActiveCompIdx(FluidSystem::solventComponentIndex(phaseIdx));
291
292 if constexpr (blackoilConserveSurfaceVolume) {
293 flux[conti0EqIdx + activeCompIdx] += surfaceVolumeFlux;
294 }
295 else {
296 flux[conti0EqIdx + activeCompIdx] += surfaceVolumeFlux *
297 FluidSystem::referenceDensity(phaseIdx, pvtRegionIdx);
298 }
299
300 if (phaseIdx == oilPhaseIdx) {
301 // dissolved gas (in the oil phase).
302 if (FluidSystem::enableDissolvedGas()) {
303 const auto& Rs = BlackOil::getRs_<FluidSystem, FluidState, UpEval>(upFs, pvtRegionIdx);
304
305 const unsigned activeGasCompIdx = FluidSystem::canonicalToActiveCompIdx(gasCompIdx);
306 if constexpr (blackoilConserveSurfaceVolume) {
307 flux[conti0EqIdx + activeGasCompIdx] += Rs * surfaceVolumeFlux;
308 }
309 else {
310 flux[conti0EqIdx + activeGasCompIdx] +=
311 Rs * surfaceVolumeFlux *
312 FluidSystem::referenceDensity(gasPhaseIdx, pvtRegionIdx);
313 }
314 }
315 } else if (phaseIdx == waterPhaseIdx) {
316 // dissolved gas (in the water phase).
317 if (FluidSystem::enableDissolvedGasInWater()) {
318 const auto& Rsw = BlackOil::getRsw_<FluidSystem, FluidState, UpEval>(upFs, pvtRegionIdx);
319
320 const unsigned activeGasCompIdx = FluidSystem::canonicalToActiveCompIdx(gasCompIdx);
321 if constexpr (blackoilConserveSurfaceVolume) {
322 flux[conti0EqIdx + activeGasCompIdx] += Rsw * surfaceVolumeFlux;
323 }
324 else {
325 flux[conti0EqIdx + activeGasCompIdx] +=
326 Rsw * surfaceVolumeFlux *
327 FluidSystem::referenceDensity(gasPhaseIdx, pvtRegionIdx);
328 }
329 }
330 }
331 else if (phaseIdx == gasPhaseIdx) {
332 // vaporized oil (in the gas phase).
333 if (FluidSystem::enableVaporizedOil()) {
334 const auto& Rv = BlackOil::getRv_<FluidSystem, FluidState, UpEval>(upFs, pvtRegionIdx);
335
336 const unsigned activeOilCompIdx = FluidSystem::canonicalToActiveCompIdx(oilCompIdx);
337 if constexpr (blackoilConserveSurfaceVolume) {
338 flux[conti0EqIdx + activeOilCompIdx] += Rv * surfaceVolumeFlux;
339 }
340 else {
341 flux[conti0EqIdx + activeOilCompIdx] +=
342 Rv * surfaceVolumeFlux *
343 FluidSystem::referenceDensity(oilPhaseIdx, pvtRegionIdx);
344 }
345 }
346 // vaporized water (in the gas phase).
347 if (FluidSystem::enableVaporizedWater()) {
348 const auto& Rvw = BlackOil::getRvw_<FluidSystem, FluidState, UpEval>(upFs, pvtRegionIdx);
349
350 const unsigned activeWaterCompIdx = FluidSystem::canonicalToActiveCompIdx(waterCompIdx);
351 if constexpr (blackoilConserveSurfaceVolume) {
352 flux[conti0EqIdx + activeWaterCompIdx] += Rvw * surfaceVolumeFlux;
353 }
354 else {
355 flux[conti0EqIdx + activeWaterCompIdx] +=
356 Rvw * surfaceVolumeFlux *
357 FluidSystem::referenceDensity(waterPhaseIdx, pvtRegionIdx);
358 }
359 }
360 }
361 }
362
374 template <class Scalar>
375 static void adaptMassConservationQuantities_(Dune::FieldVector<Scalar, numEq>& container,
376 unsigned pvtRegionIdx)
377 {
378 if constexpr (!blackoilConserveSurfaceVolume) {
379 // convert "surface volume" to mass. this is complicated a bit by the fact that
380 // not all phases are necessarily enabled. (we here assume that if a fluid phase
381 // is disabled, its respective "main" component is not considered as well.)
382
383 if constexpr (waterEnabled) {
384 const unsigned activeWaterCompIdx = FluidSystem::canonicalToActiveCompIdx(waterCompIdx);
385 container[conti0EqIdx + activeWaterCompIdx] *=
386 FluidSystem::referenceDensity(waterPhaseIdx, pvtRegionIdx);
387 }
388
389 if constexpr (gasEnabled) {
390 const unsigned activeGasCompIdx = FluidSystem::canonicalToActiveCompIdx(gasCompIdx);
391 container[conti0EqIdx + activeGasCompIdx] *=
392 FluidSystem::referenceDensity(gasPhaseIdx, pvtRegionIdx);
393 }
394
395 if constexpr (oilEnabled) {
396 const unsigned activeOilCompIdx = FluidSystem::canonicalToActiveCompIdx(oilCompIdx);
397 container[conti0EqIdx + activeOilCompIdx] *=
398 FluidSystem::referenceDensity(oilPhaseIdx, pvtRegionIdx);
399 }
400 }
401 }
402};
403
404} // namespace Opm
405
406#endif
Contains the classes required to extend the black-oil model by bioeffects.
Contains the classes required to extend the black-oil model by brine.
Classes required for dynamic convective mixing.
Classes required for molecular diffusion.
Contains the classes required to extend the black-oil model by energy.
Contains the classes required to extend the black-oil model by solvent component. For details,...
Contains the classes required to extend the black-oil model to include the effects of foam.
Contains the classes required to extend the black-oil model by polymer.
Declares the properties required by the black oil model.
Contains the classes required to extend the black-oil model by solvents.
Contains the high level supplements required to extend the black oil model by bioeffects.
Definition: blackoilbioeffectsmodules.hh:93
static void addStorage(Dune::FieldVector< LhsEval, numEq > &storage, const IntensiveQuantities &intQuants)
Definition: blackoilbioeffectsmodules.hh:177
static void addSource(RateVector &source, const Problem &problem, const IntensiveQuantities &intQuants, unsigned globalSpaceIdex)
Definition: blackoilbioeffectsmodules.hh:276
static void computeFlux(RateVector &flux, const ElementContext &elemCtx, unsigned scvfIdx, unsigned timeIdx)
Definition: blackoilbioeffectsmodules.hh:242
Contains the high level supplements required to extend the black oil model by brine.
Definition: blackoilbrinemodules.hh:56
static void computeFlux(RateVector &flux, const ElementContext &elemCtx, unsigned scvfIdx, unsigned timeIdx)
Definition: blackoilbrinemodules.hh:196
static void addStorage(Dune::FieldVector< LhsEval, numEq > &storage, const IntensiveQuantities &intQuants)
Definition: blackoilbrinemodules.hh:163
Definition: blackoilconvectivemixingmodule.hh:64
Provides the auxiliary methods required for consideration of the diffusion equation.
Definition: blackoildiffusionmodule.hh:50
Contains the high level supplements required to extend the black oil model by energy.
Definition: blackoilenergymodules.hh:58
static void computeFlux(RateVector &flux, const ElementContext &elemCtx, unsigned scvfIdx, unsigned timeIdx)
Definition: blackoilenergymodules.hh:181
static void addStorage(Dune::FieldVector< LhsEval, numEq > &storage, const IntensiveQuantities &intQuants)
Definition: blackoilenergymodules.hh:153
Contains the high level supplements required to extend the black oil model.
Definition: blackoilextbomodules.hh:62
static void addStorage(Dune::FieldVector< LhsEval, numEq > &storage, const IntensiveQuantities &intQuants)
Definition: blackoilextbomodules.hh:156
static void computeFlux(RateVector &flux, const ElementContext &elemCtx, unsigned scvfIdx, unsigned timeIdx)
Definition: blackoilextbomodules.hh:191
Contains the high level supplements required to extend the black oil model to include the effects of ...
Definition: blackoilfoammodules.hh:58
static void addStorage(Dune::FieldVector< LhsEval, numEq > &storage, const IntensiveQuantities &intQuants)
Definition: blackoilfoammodules.hh:164
static void computeFlux(RateVector &flux, const ElementContext &elemCtx, unsigned scvfIdx, unsigned timeIdx)
Definition: blackoilfoammodules.hh:204
Calculates the local residual of the black oil model.
Definition: blackoillocalresidual.hh:56
void computeFlux(RateVector &flux, const ElementContext &elemCtx, unsigned scvfIdx, unsigned timeIdx) const
Evaluates the total mass flux of all conservation quantities over a face of a sub-control volume.
Definition: blackoillocalresidual.hh:201
void computeSource(RateVector &source, const ElementContext &elemCtx, unsigned dofIdx, unsigned timeIdx) const
Calculate the source term of the equation.
Definition: blackoillocalresidual.hh:258
static void evalPhaseFluxes_(RateVector &flux, unsigned phaseIdx, unsigned pvtRegionIdx, const ExtensiveQuantities &extQuants, const FluidState &upFs)
Helper function to calculate the flux of mass in terms of conservation quantities via specific fluid ...
Definition: blackoillocalresidual.hh:281
static void adaptMassConservationQuantities_(Dune::FieldVector< Scalar, numEq > &container, unsigned pvtRegionIdx)
Helper function to convert the mass-related parts of a Dune::FieldVector that stores conservation qua...
Definition: blackoillocalresidual.hh:375
void computeStorage(Dune::FieldVector< LhsEval, numEq > &storage, const ElementContext &elemCtx, unsigned dofIdx, unsigned timeIdx) const
Evaluate the amount all conservation quantities (e.g. phase mass) within a finite sub-control volume.
Definition: blackoillocalresidual.hh:106
Contains the high level supplements required to extend the black oil model by polymer.
Definition: blackoilpolymermodules.hh:64
static void addStorage(Dune::FieldVector< LhsEval, numEq > &storage, const IntensiveQuantities &intQuants)
Definition: blackoilpolymermodules.hh:236
static void computeFlux(RateVector &flux, const ElementContext &elemCtx, unsigned scvfIdx, unsigned timeIdx)
Definition: blackoilpolymermodules.hh:275
Contains the high level supplements required to extend the black oil model by solvents.
Definition: blackoilsolventmodules.hh:68
static void addStorage(Dune::FieldVector< LhsEval, numEq > &storage, const IntensiveQuantities &intQuants)
Definition: blackoilsolventmodules.hh:183
static void computeFlux(RateVector &flux, const ElementContext &elemCtx, unsigned scvfIdx, unsigned timeIdx)
Definition: blackoilsolventmodules.hh:216
Definition: blackoilbioeffectsmodules.hh:43
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(....
Definition: propertysystem.hh:233