blackoillocalresidualtpfa.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_TPFA_RESIDUAL_HH
29#define EWOMS_BLACK_OIL_LOCAL_TPFA_RESIDUAL_HH
30
31#include <opm/input/eclipse/EclipseState/Grid/FaceDir.hpp>
32#include <opm/input/eclipse/Schedule/BCProp.hpp>
33
34#include <opm/material/common/ConditionalStorage.hpp>
35#include <opm/material/common/MathToolbox.hpp>
36#include <opm/material/fluidstates/BlackOilFluidState.hpp>
37
42
44
45#include <opm/common/ErrorMacros.hpp>
46#include <opm/common/utility/gpuDecorators.hpp>
47#include <opm/common/utility/gpuistl_if_available.hpp>
48
49#include <array>
50#include <cassert>
51#include <limits>
52#include <stdexcept>
53#include <string>
54
55#include <opm/common/utility/gpuistl_if_available.hpp>
56
57namespace Opm
58{
65template <class TypeTag>
66class BlackOilLocalResidualTPFA : public GetPropType<TypeTag, Properties::DiscLocalResidual>
67{
78 using FluidState = typename IntensiveQuantities::FluidState;
79
80 enum { conti0EqIdx = Indices::conti0EqIdx };
81 enum { numEq = getPropValue<TypeTag, Properties::NumEq>() };
82 enum { numPhases = getPropValue<TypeTag, Properties::NumPhases>() };
83 enum { numComponents = getPropValue<TypeTag, Properties::NumComponents>() };
84
85 enum { dimWorld = GridView::dimensionworld };
86 enum { gasPhaseIdx = FluidSystem::gasPhaseIdx };
87 enum { oilPhaseIdx = FluidSystem::oilPhaseIdx };
88 enum { waterPhaseIdx = FluidSystem::waterPhaseIdx };
89
90 enum { gasCompIdx = FluidSystem::gasCompIdx };
91 enum { oilCompIdx = FluidSystem::oilCompIdx };
92 enum { waterCompIdx = FluidSystem::waterCompIdx };
93 static constexpr unsigned compositionSwitchIdx = Indices::compositionSwitchIdx;
94
95 static constexpr bool waterEnabled = Indices::waterEnabled;
96 static constexpr bool gasEnabled = Indices::gasEnabled;
97 static constexpr bool oilEnabled = Indices::oilEnabled;
98 static constexpr bool compositionSwitchEnabled =
99 compositionSwitchIdx != std::numeric_limits<unsigned>::max();
100
101 static constexpr bool blackoilConserveSurfaceVolume
102 = getPropValue<TypeTag, Properties::BlackoilConserveSurfaceVolume>();
103
104 static constexpr bool enableSolvent = getPropValue<TypeTag, Properties::EnableSolvent>();
105 static constexpr bool enableExtbo = getPropValue<TypeTag, Properties::EnableExtbo>();
106 static constexpr bool enablePolymer = getPropValue<TypeTag, Properties::EnablePolymer>();
107 static constexpr EnergyModules energyModuleType =
108 getPropValue<TypeTag, Properties::EnergyModuleType>();
109 static constexpr bool enableFullyImplicitThermal =
110 energyModuleType == EnergyModules::FullyImplicitThermal;
111 static constexpr bool enableFoam = getPropValue<TypeTag, Properties::EnableFoam>();
112 static constexpr bool enableBrine = getPropValue<TypeTag, Properties::EnableBrine>();
113 static constexpr bool enableDiffusion = getPropValue<TypeTag, Properties::EnableDiffusion>();
114 static constexpr bool enableDispersion = getPropValue<TypeTag, Properties::EnableDispersion>();
115 static constexpr bool enableConvectiveMixing
116 = getPropValue<TypeTag, Properties::EnableConvectiveMixing>();
117 static constexpr bool enableBioeffects = getPropValue<TypeTag, Properties::EnableBioeffects>();
118 static constexpr bool enableSaltPrecipitation
119 = getPropValue<TypeTag, Properties::EnableSaltPrecipitation>();
120 static constexpr bool enableMICP = Indices::enableMICP;
121 static constexpr bool runAssemblyOnGpu = getPropValue<TypeTag, Properties::RunAssemblyOnGpu>();
122
123 using BioeffectsModule = BlackOilBioeffectsModule<TypeTag, enableBioeffects>;
124 using BrineModule = BlackOilBrineModule<TypeTag, enableBrine>;
125 using ConvectiveMixingModule = BlackOilConvectiveMixingModule<TypeTag, enableConvectiveMixing>;
129 using ExtboModule = BlackOilExtboModule<TypeTag, enableExtbo>;
131 using SolventModule = BlackOilSolventModule<TypeTag, enableSolvent>;
132 using PolymerModule = BlackOilPolymerModule<TypeTag, enablePolymer>;
133
135 using Toolbox = MathToolbox<Evaluation>;
136
137public:
139 double trans;
140 double faceArea;
143 double dZg;
144 FaceDir::DirEnum faceDir;
145 double Vin;
146 double Vex;
147 ConditionalStorage<enableFullyImplicitThermal, double> inAlpha;
148 ConditionalStorage<enableFullyImplicitThermal, double> outAlpha;
149 ConditionalStorage<enableDiffusion, double> diffusivity;
150 ConditionalStorage<enableDispersion, double> dispersivity;
151 };
152
156 template <class LhsEval>
157 void computeStorage(Dune::FieldVector<LhsEval, numEq>& storage,
158 const ElementContext& elemCtx,
159 unsigned dofIdx,
160 unsigned timeIdx) const
161 {
162 const IntensiveQuantities& intQuants = elemCtx.intensiveQuantities(dofIdx, timeIdx);
163 computeStorage<LhsEval>(storage, intQuants);
164 }
165
166 template <class LhsEval, class StorageType, class IntensiveQuantitiesType = IntensiveQuantities>
167 OPM_HOST_DEVICE static void computeStorage(StorageType& storage,
168 const IntensiveQuantitiesType& intQuants)
169 {
170 OPM_TIMEBLOCK_LOCAL(computeStorage, Subsystem::Assembly);
171 // retrieve the intensive quantities for the SCV at the specified point in time
172 const auto& fs = intQuants.fluidState();
173 storage = 0.0;
174
175 const FluidSystem& fsys = intQuants.getFluidSystem();
176
177 for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
178 if (!fsys.phaseIsActive(phaseIdx)) {
179 continue;
180 }
181 unsigned activeCompIdx
182 = fsys.canonicalToActiveCompIdx(fsys.solventComponentIndex(phaseIdx));
183 LhsEval surfaceVolume = Toolbox::template decay<LhsEval>(fs.saturation(phaseIdx))
184 * Toolbox::template decay<LhsEval>(fs.invB(phaseIdx))
185 * Toolbox::template decay<LhsEval>(intQuants.porosity());
186
187 storage[conti0EqIdx + activeCompIdx] += surfaceVolume;
188
189 // account for dissolved gas
190 if (phaseIdx == oilPhaseIdx && fsys.enableDissolvedGas()) {
191 unsigned activeGasCompIdx = fsys.canonicalToActiveCompIdx(gasCompIdx);
192 storage[conti0EqIdx + activeGasCompIdx]
193 += Toolbox::template decay<LhsEval>(intQuants.fluidState().Rs())
194 * surfaceVolume;
195 }
196
197 // account for dissolved gas in water
198 if (phaseIdx == waterPhaseIdx && fsys.enableDissolvedGasInWater()) {
199 unsigned activeGasCompIdx = fsys.canonicalToActiveCompIdx(gasCompIdx);
200 storage[conti0EqIdx + activeGasCompIdx]
201 += Toolbox::template decay<LhsEval>(intQuants.fluidState().Rsw())
202 * surfaceVolume;
203 }
204
205 // account for vaporized oil
206 if (phaseIdx == gasPhaseIdx && fsys.enableVaporizedOil()) {
207 unsigned activeOilCompIdx = fsys.canonicalToActiveCompIdx(oilCompIdx);
208 storage[conti0EqIdx + activeOilCompIdx]
209 += Toolbox::template decay<LhsEval>(intQuants.fluidState().Rv())
210 * surfaceVolume;
211 }
212
213 // account for vaporized water
214 if (phaseIdx == gasPhaseIdx && fsys.enableVaporizedWater()) {
215 unsigned activeWaterCompIdx = fsys.canonicalToActiveCompIdx(waterCompIdx);
216 storage[conti0EqIdx + activeWaterCompIdx]
217 += Toolbox::template decay<LhsEval>(intQuants.fluidState().Rvw())
218 * surfaceVolume;
219 }
220 }
221
222 adaptMassConservationQuantities_(storage, intQuants.pvtRegionIndex(), fsys);
223
224 // deal with solvents (if present)
225 if constexpr (enableSolvent) {
226 SolventModule::addStorage(storage, intQuants);
227 }
228
229 // deal with zFracton (if present)
230 if constexpr (enableExtbo) {
231 ExtboModule::addStorage(storage, intQuants);
232 }
233
234 // deal with polymer (if present)
235 if constexpr (enablePolymer) {
236 PolymerModule::addStorage(storage, intQuants);
237 }
238
239 // deal with energy (if present)
240 if constexpr (enableFullyImplicitThermal) {
241 EnergyModule::addStorage(storage, intQuants);
242 }
243
244 // deal with foam (if present)
245 if constexpr (enableFoam) {
246 FoamModule::addStorage(storage, intQuants);
247 }
248
249 // deal with salt (if present)
250 if constexpr (enableBrine) {
251 BrineModule::addStorage(storage, intQuants);
252 }
253
254 // deal with bioeffects (if present)
255 if constexpr (enableBioeffects) {
256 BioeffectsModule::addStorage(storage, intQuants);
257 }
258 }
259
265 template <class ModuleParamsT,
266 class RateVectorT,
267 class IntensiveQuantitiesT,
268 class ResidualNBInfoT>
269 OPM_HOST_DEVICE static void computeFlux(RateVectorT& flux,
270 RateVectorT& darcy,
271 const unsigned globalIndexIn,
272 const unsigned globalIndexEx,
273 const IntensiveQuantitiesT& intQuantsIn,
274 const IntensiveQuantitiesT& intQuantsEx,
275 const ResidualNBInfoT& nbInfo,
276 const ModuleParamsT& moduleParams)
277 {
278 OPM_TIMEBLOCK_LOCAL(computeFlux, Subsystem::Assembly);
279 flux = 0.0;
280 darcy = 0.0;
281
282 calculateFluxes_(flux,
283 darcy,
284 intQuantsIn,
285 intQuantsEx,
286 globalIndexIn,
287 globalIndexEx,
288 nbInfo,
289 moduleParams);
290 }
291
292 // This function demonstrates compatibility with the ElementContext-based interface.
293 // Actually using it will lead to double work since the element context already contains
294 // fluxes through its stored ExtensiveQuantities.
295 static void
296 computeFlux(RateVector& flux, const ElementContext& elemCtx, unsigned scvfIdx, unsigned timeIdx)
297 {
298 OPM_TIMEBLOCK_LOCAL(computeFlux, Subsystem::Assembly);
299 assert(timeIdx == 0);
300
301 flux = 0.0;
302 RateVector darcy = 0.0;
303 // need for dary flux calculation
304 const auto& problem = elemCtx.problem();
305 const auto& stencil = elemCtx.stencil(timeIdx);
306 const auto& scvf = stencil.interiorFace(scvfIdx);
307
308 unsigned interiorDofIdx = scvf.interiorIndex();
309 unsigned exteriorDofIdx = scvf.exteriorIndex();
310 assert(interiorDofIdx != exteriorDofIdx);
311
312 // unsigned I = stencil.globalSpaceIndex(interiorDofIdx);
313 // unsigned J = stencil.globalSpaceIndex(exteriorDofIdx);
314 Scalar Vin = elemCtx.dofVolume(interiorDofIdx, /*timeIdx=*/0);
315 Scalar Vex = elemCtx.dofVolume(exteriorDofIdx, /*timeIdx=*/0);
316 const auto& globalIndexIn = stencil.globalSpaceIndex(interiorDofIdx);
317 const auto& globalIndexEx = stencil.globalSpaceIndex(exteriorDofIdx);
318 Scalar trans = problem.transmissibility(elemCtx, interiorDofIdx, exteriorDofIdx);
319 Scalar faceArea = scvf.area();
320 const auto faceDir = faceDirFromDirId(scvf.dirId());
321 Scalar thpresInToEx = problem.thresholdPressure(globalIndexIn, globalIndexEx);
322 Scalar thpresExToIn = problem.thresholdPressure(globalIndexEx, globalIndexIn);
323
324 // estimate the gravity correction: for performance reasons we use a simplified
325 // approach for this flux module that assumes that gravity is constant and always
326 // acts into the downwards direction. (i.e., no centrifuge experiments, sorry.)
327 const Scalar g = problem.gravity()[dimWorld - 1];
328 const auto& intQuantsIn = elemCtx.intensiveQuantities(interiorDofIdx, timeIdx);
329 const auto& intQuantsEx = elemCtx.intensiveQuantities(exteriorDofIdx, timeIdx);
330
331 // this is quite hacky because the dune grid interface does not provide a
332 // cellCenterDepth() method (so we ask the problem to provide it). The "good"
333 // solution would be to take the Z coordinate of the element centroids, but since
334 // ECL seems to like to be inconsistent on that front, it needs to be done like
335 // here...
336 const Scalar zIn = problem.dofCenterDepth(elemCtx, interiorDofIdx, timeIdx);
337 const Scalar zEx = problem.dofCenterDepth(elemCtx, exteriorDofIdx, timeIdx);
338 // the distances from the DOF's depths. (i.e., the additional depth of the
339 // exterior DOF)
340 const Scalar distZ = zIn - zEx;
341 // for thermal harmonic mean of half trans
342 const Scalar inAlpha = problem.thermalHalfTransmissibility(globalIndexIn, globalIndexEx);
343 const Scalar outAlpha = problem.thermalHalfTransmissibility(globalIndexEx, globalIndexIn);
344 const Scalar diffusivity = problem.diffusivity(globalIndexEx, globalIndexIn);
345 const Scalar dispersivity = problem.dispersivity(globalIndexEx, globalIndexIn);
346
347 const ResidualNBInfo res_nbinfo {trans,
348 faceArea,
349 thpresInToEx,
350 thpresExToIn,
351 distZ * g,
352 faceDir,
353 Vin,
354 Vex,
355 inAlpha,
356 outAlpha,
357 diffusivity,
358 dispersivity};
359
360 calculateFluxes_(flux,
361 darcy,
362 intQuantsIn,
363 intQuantsEx,
364 globalIndexIn,
365 globalIndexEx,
366 res_nbinfo,
367 problem.moduleParams());
368 }
369
370 template <class RateVectorT,
371 class IntensiveQuantitiesT,
372 class ResidualNBInfoT,
373 class ModuleParamsT>
374 OPM_HOST_DEVICE static void calculateFluxes_(RateVectorT& flux,
375 RateVectorT& darcy,
376 const IntensiveQuantitiesT& intQuantsIn,
377 const IntensiveQuantitiesT& intQuantsEx,
378 const unsigned& globalIndexIn,
379 const unsigned& globalIndexEx,
380 const ResidualNBInfoT& nbInfo,
381 const ModuleParamsT& moduleParams)
382 {
383 OPM_TIMEBLOCK_LOCAL(calculateFluxes, Subsystem::Assembly);
384 const Scalar Vin = nbInfo.Vin;
385 const Scalar Vex = nbInfo.Vex;
386 const Scalar distZg = nbInfo.dZg;
387 const Scalar thpresInToEx = nbInfo.thpresInToEx;
388 const Scalar thpresExToIn = nbInfo.thpresExToIn;
389 const Scalar trans = nbInfo.trans;
390 const Scalar faceArea = nbInfo.faceArea;
391 FaceDir::DirEnum facedir = nbInfo.faceDir;
392
393 const FluidSystem& fsys = intQuantsIn.getFluidSystem();
394
395 for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
396 if (!fsys.phaseIsActive(phaseIdx)) {
397 continue;
398 }
399 // darcy flux calculation
400 short dnIdx;
401 //
402 short upIdx;
403 // fake intices should only be used to get upwind anc compatibility with old functions
404 short interiorDofIdx = 0; // NB
405 short exteriorDofIdx = 1; // NB
406 Evaluation pressureDifference;
407 ExtensiveQuantities::calculatePhasePressureDiff_(upIdx,
408 dnIdx,
409 pressureDifference,
410 intQuantsIn,
411 intQuantsEx,
412 phaseIdx, // input
413 interiorDofIdx, // input
414 exteriorDofIdx, // input
415 Vin,
416 Vex,
417 globalIndexIn,
418 globalIndexEx,
419 distZg,
420 thpresInToEx,
421 thpresExToIn,
422 moduleParams);
423
424 const IntensiveQuantities& up = (upIdx == interiorDofIdx) ? intQuantsIn : intQuantsEx;
425 unsigned globalUpIndex = (upIdx == interiorDofIdx) ? globalIndexIn : globalIndexEx;
426 // Use arithmetic average (more accurate with harmonic, but that requires recomputing
427 // the transmissbility)
428 Evaluation transMult = (intQuantsIn.rockCompTransMultiplier()
429 + Toolbox::value(intQuantsEx.rockCompTransMultiplier()))
430 / 2;
431 if constexpr (enableBioeffects || enableSaltPrecipitation) {
432 transMult
433 *= (intQuantsIn.permFactor() + Toolbox::value(intQuantsEx.permFactor())) / 2;
434 }
435
436 Evaluation darcyFlux;
437 if (globalUpIndex == globalIndexIn) {
438 darcyFlux = pressureDifference * up.mobility(phaseIdx, facedir) * transMult
439 * (-trans / faceArea);
440 } else {
441 darcyFlux = pressureDifference
442 * (Toolbox::value(up.mobility(phaseIdx, facedir)) * transMult
443 * (-trans / faceArea));
444 }
445
446 unsigned activeCompIdx
447 = fsys.canonicalToActiveCompIdx(fsys.solventComponentIndex(phaseIdx));
448 // NB! For the FLORES fluxes without derivatives
449 darcy[conti0EqIdx + activeCompIdx] = darcyFlux.value() * faceArea;
450
451 unsigned pvtRegionIdx = up.pvtRegionIndex();
452 // if (upIdx == globalFocusDofIdx){
453 if (globalUpIndex == globalIndexIn) {
454 const auto& invB = getInvB_<FluidSystem, FluidState, Evaluation>(
455 up.fluidState(), phaseIdx, pvtRegionIdx, fsys);
456 const auto& surfaceVolumeFlux = invB * darcyFlux;
457
458 evalPhaseFluxes_<Evaluation>(
459 flux, phaseIdx, pvtRegionIdx, surfaceVolumeFlux, up.fluidState());
460 if constexpr (enableFullyImplicitThermal) {
461 EnergyModule::template addPhaseEnthalpyFluxes_<Evaluation>(
462 flux, phaseIdx, darcyFlux, up.fluidState());
463 }
464 if constexpr (enableBioeffects) {
465 BioeffectsModule::template addBioeffectsFluxes_<Evaluation>(
466 flux, phaseIdx, darcyFlux, up);
467 }
468 if constexpr (enableBrine) {
469 BrineModule::template addBrineFluxes_<Evaluation, FluidState>(
470 flux, phaseIdx, darcyFlux, up.fluidState());
471 }
472 } else {
473 const auto& invB = getInvB_<FluidSystem, FluidState, Scalar>(
474 up.fluidState(), phaseIdx, pvtRegionIdx, fsys);
475 const auto& surfaceVolumeFlux = invB * darcyFlux;
476 evalPhaseFluxes_<Scalar>(
477 flux, phaseIdx, pvtRegionIdx, surfaceVolumeFlux, up.fluidState());
478 if constexpr (enableFullyImplicitThermal) {
479 EnergyModule::template addPhaseEnthalpyFluxes_<Scalar>(
480 flux, phaseIdx, darcyFlux, up.fluidState());
481 }
482 if constexpr (enableBioeffects) {
483 BioeffectsModule::template addBioeffectsFluxes_<Scalar>(
484 flux, phaseIdx, darcyFlux, up);
485 }
486 if constexpr (enableBrine) {
487 BrineModule::template addBrineFluxes_<Scalar, FluidState>(
488 flux, phaseIdx, darcyFlux, up.fluidState());
489 }
490 }
491 }
492
493 // deal with solvents (if present)
494 static_assert(
495 !enableSolvent,
496 "Relevant computeFlux() method must be implemented for this module before enabling.");
497 // SolventModule::computeFlux(flux, elemCtx, scvfIdx, timeIdx);
498
499 // deal with zFracton (if present)
500 static_assert(
501 !enableExtbo,
502 "Relevant computeFlux() method must be implemented for this module before enabling.");
503 // ExtboModule::computeFlux(flux, elemCtx, scvfIdx, timeIdx);
504
505 // deal with polymer (if present)
506 static_assert(
507 !enablePolymer,
508 "Relevant computeFlux() method must be implemented for this module before enabling.");
509 // PolymerModule::computeFlux(flux, elemCtx, scvfIdx, timeIdx);
510
511 // deal with convective mixing
512 if constexpr (enableConvectiveMixing) {
513 ConvectiveMixingModule::addConvectiveMixingFlux(
514 flux,
515 intQuantsIn,
516 intQuantsEx,
517 globalIndexIn,
518 globalIndexEx,
519 nbInfo.dZg,
520 nbInfo.trans,
521 nbInfo.faceArea,
522 moduleParams.convectiveMixingModuleParam);
523 }
524
525 // deal with energy (if present)
526 if constexpr (enableFullyImplicitThermal) {
527 const Scalar inAlpha = nbInfo.inAlpha;
528 const Scalar outAlpha = nbInfo.outAlpha;
529 Evaluation heatFlux;
530
531 short interiorDofIdx = 0; // NB
532 short exteriorDofIdx = 1; // NB
533
534 EnergyModule::ExtensiveQuantities::updateEnergy(heatFlux,
535 interiorDofIdx, // focusDofIndex,
536 interiorDofIdx,
537 exteriorDofIdx,
538 intQuantsIn,
539 intQuantsEx,
540 intQuantsIn.fluidState(),
541 intQuantsEx.fluidState(),
542 inAlpha,
543 outAlpha,
544 faceArea);
545 EnergyModule::addHeatFlux(flux, heatFlux);
546 }
547 // NB need to be tha last energy call since it does scaling
548 // EnergyModule::computeFlux(flux, elemCtx, scvfIdx, timeIdx);
549
550 // deal with foam (if present)
551 static_assert(
552 !enableFoam,
553 "Relevant computeFlux() method must be implemented for this module before enabling.");
554 // FoamModule::computeFlux(flux, elemCtx, scvfIdx, timeIdx);
555
556 // deal with diffusion (if present). opm-models expects per area flux (added in the
557 // tmpdiffusivity).
558 if constexpr (enableDiffusion) {
559 typename DiffusionModule::ExtensiveQuantities::EvaluationArray
560 effectiveDiffusionCoefficient;
561 DiffusionModule::ExtensiveQuantities::update(
562 effectiveDiffusionCoefficient, intQuantsIn, intQuantsEx);
563 const Scalar diffusivity = nbInfo.diffusivity;
564 const Scalar tmpdiffusivity = diffusivity / faceArea;
565 DiffusionModule::addDiffusiveFlux(
566 flux, intQuantsIn, intQuantsEx, tmpdiffusivity, effectiveDiffusionCoefficient);
567 }
568
569 // deal with dispersion (if present). opm-models expects per area flux (added in the
570 // tmpdispersivity).
571 if constexpr (enableDispersion) {
572 typename DispersionModule::ExtensiveQuantities::ScalarArray normVelocityAvg;
573 DispersionModule::ExtensiveQuantities::update(
574 normVelocityAvg, intQuantsIn, intQuantsEx);
575 const Scalar dispersivity = nbInfo.dispersivity;
576 const Scalar tmpdispersivity = dispersivity / faceArea;
577 DispersionModule::addDispersiveFlux(
578 flux, intQuantsIn, intQuantsEx, tmpdispersivity, normVelocityAvg);
579 }
580
581 // apply the scaling for the urea equation in MICP
582 if constexpr (enableMICP) {
583 BioeffectsModule::applyScaling(flux);
584 }
585 }
586
587 template <class BoundaryConditionData>
588 static void computeBoundaryFluxRate(RateVector& bdyFlux, const BoundaryConditionData& bdyInfo)
589 {
590 bdyFlux.setMassRate(bdyInfo.massRate, bdyInfo.pvtRegionIdx);
591 }
592
593 template <class BoundaryConditionData>
594 static void computeBoundaryFluxFree(const Problem& problem,
595 RateVector& bdyFlux,
596 const BoundaryConditionData& bdyInfo,
597 const IntensiveQuantities& insideIntQuants,
598 unsigned globalSpaceIdx)
599 {
600 OPM_TIMEBLOCK_LOCAL(computeBoundaryFluxFree, Subsystem::Assembly);
601 std::array<short, numPhases> upIdx;
602 std::array<short, numPhases> dnIdx;
603 std::array<Evaluation, numPhases> volumeFlux;
604 std::array<Evaluation, numPhases> pressureDifference;
605
606 ExtensiveQuantities::calculateBoundaryGradients_(problem,
607 globalSpaceIdx,
608 insideIntQuants,
609 bdyInfo.boundaryFaceIndex,
610 bdyInfo.faceArea,
611 bdyInfo.faceZCoord,
612 bdyInfo.exFluidState,
613 upIdx,
614 dnIdx,
615 volumeFlux,
616 pressureDifference);
617
619 // advective fluxes of all components in all phases
621 bdyFlux = 0.0;
622 for (unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
623 if (!FluidSystem::phaseIsActive(phaseIdx)) {
624 continue;
625 }
626 const auto& pBoundary = bdyInfo.exFluidState.pressure(phaseIdx);
627 const Evaluation& pInside = insideIntQuants.fluidState().pressure(phaseIdx);
628 const unsigned pvtRegionIdx = insideIntQuants.pvtRegionIndex();
629
630 RateVector tmp(0.0);
631 const auto& darcyFlux = volumeFlux[phaseIdx];
632 // mass conservation
633 if (pBoundary < pInside) {
634 // outflux
635 const auto& invB = getInvB_<FluidSystem, FluidState, Evaluation>(
636 insideIntQuants.fluidState(), phaseIdx, pvtRegionIdx);
637 Evaluation surfaceVolumeFlux = invB * darcyFlux;
638 evalPhaseFluxes_<Evaluation>(tmp,
639 phaseIdx,
640 insideIntQuants.pvtRegionIndex(),
641 surfaceVolumeFlux,
642 insideIntQuants.fluidState());
643 if constexpr (enableFullyImplicitThermal) {
644 EnergyModule::template addPhaseEnthalpyFluxes_<Evaluation>(
645 tmp, phaseIdx, darcyFlux, insideIntQuants.fluidState());
646 }
647 } else if (pBoundary > pInside) {
648 // influx
649 using ScalarFluidState = decltype(bdyInfo.exFluidState);
650 const auto& invB = getInvB_<FluidSystem, ScalarFluidState, Scalar>(
651 bdyInfo.exFluidState, phaseIdx, pvtRegionIdx);
652 Evaluation surfaceVolumeFlux = invB * darcyFlux;
653 evalPhaseFluxes_<Scalar>(tmp,
654 phaseIdx,
655 insideIntQuants.pvtRegionIndex(),
656 surfaceVolumeFlux,
657 bdyInfo.exFluidState);
658 if constexpr (enableFullyImplicitThermal) {
659 EnergyModule::template addPhaseEnthalpyFluxes_<Scalar>(
660 tmp, phaseIdx, darcyFlux, bdyInfo.exFluidState);
661 }
662 }
663
664 for (unsigned i = 0; i < tmp.size(); ++i) {
665 bdyFlux[i] += tmp[i];
666 }
667 }
668
669 // conductive heat flux from boundary
670 if constexpr (enableFullyImplicitThermal) {
671 Evaluation heatFlux;
672 // avoid overload of functions with same number of elements in eclproblem
673 Scalar alpha = problem.eclTransmissibilities().thermalHalfTransBoundary(
674 globalSpaceIdx, bdyInfo.boundaryFaceIndex);
675 unsigned inIdx = 0; // dummy
676 // always calculated with derivatives of this cell
677 EnergyModule::ExtensiveQuantities::updateEnergyBoundary(heatFlux,
678 insideIntQuants,
679 /*focusDofIndex*/ inIdx,
680 inIdx,
681 alpha,
682 bdyInfo.exFluidState);
683 EnergyModule::addHeatFlux(bdyFlux, heatFlux);
684 }
685
686 static_assert(
687 !enableSolvent,
688 "Relevant treatment of boundary conditions must be implemented before enabling.");
689 static_assert(
690 !enablePolymer,
691 "Relevant treatment of boundary conditions must be implemented before enabling.");
692
693 const FluidSystem& fsys = insideIntQuants.getFluidSystem();
694
695 // make sure that the right mass conservation quantities are used
696 adaptMassConservationQuantities_(bdyFlux, insideIntQuants.pvtRegionIndex(), fsys);
697
698#ifndef NDEBUG
699 for (unsigned i = 0; i < numEq; ++i) {
700 Valgrind::CheckDefined(bdyFlux[i]);
701 }
702 Valgrind::CheckDefined(bdyFlux);
703#endif
704 }
705
706 template <class ProblemLocal, class BoundaryConditionData, class RateVectorLocal>
707 OPM_HOST_DEVICE static void computeBoundaryThermal(const ProblemLocal& problem,
708 RateVectorLocal& bdyFlux,
709 const BoundaryConditionData& bdyInfo,
710 const IntensiveQuantities& insideIntQuants,
711 [[maybe_unused]] unsigned globalSpaceIdx)
712 {
713 OPM_TIMEBLOCK_LOCAL(computeBoundaryThermal, Subsystem::Assembly);
714 // only heat is allowed to flow through this boundary
715 bdyFlux = 0.0;
716
717 // conductive heat flux from boundary
718 if constexpr (enableFullyImplicitThermal) {
719 Evaluation heatFlux;
720 // avoid overload of functions with same numeber of elements in eclproblem
721 Scalar alpha;
722 if constexpr (!std::is_empty_v<GetPropType<TypeTag, Properties::FluidSystem>>) {
723 alpha = problem.getAlpha(globalSpaceIdx, bdyInfo.boundaryFaceIndex);
724 } else {
725 alpha = problem.eclTransmissibilities().thermalHalfTransBoundary(globalSpaceIdx, bdyInfo.boundaryFaceIndex);
726 }
727 unsigned inIdx = 0; // dummy
728 // always calculated with derivatives of this cell
729 EnergyModule::ExtensiveQuantities::updateEnergyBoundary(heatFlux,
730 insideIntQuants,
731 /*focusDofIndex*/ inIdx,
732 inIdx,
733 alpha,
734 bdyInfo.exFluidState);
735 EnergyModule::addHeatFlux(bdyFlux, heatFlux);
736 }
737
738#ifndef NDEBUG
739 for (unsigned i = 0; i < numEq; ++i) {
740 Valgrind::CheckDefined(bdyFlux[i]);
741 }
742 Valgrind::CheckDefined(bdyFlux);
743#endif
744 }
745
746 template <class BoundaryConditionData, class RateVectorLocal, class LocalProblem>
747 OPM_HOST_DEVICE static void computeBoundaryFlux(RateVectorLocal& bdyFlux,
748 const LocalProblem& problem,
749 const BoundaryConditionData& bdyInfo,
750 const IntensiveQuantities& insideIntQuants,
751 unsigned globalSpaceIdx)
752 {
753 if constexpr (std::is_empty_v<GetPropType<TypeTag, Properties::FluidSystem>>) {
754 switch (bdyInfo.type) {
755 case BCType::NONE:
756 bdyFlux = 0.0;
757 break;
758 case BCType::RATE:
759 computeBoundaryFluxRate(bdyFlux, bdyInfo);
760 break;
761 case BCType::FREE:
762 case BCType::DIRICHLET:
763 computeBoundaryFluxFree(problem, bdyFlux, bdyInfo, insideIntQuants, globalSpaceIdx);
764 break;
765 case BCType::THERMAL:
766 computeBoundaryThermal(problem, bdyFlux, bdyInfo, insideIntQuants, globalSpaceIdx);
767 break;
768 default:
769 OPM_THROW(std::logic_error, "Unknown boundary condition type "
770 + std::to_string(static_cast<int>(bdyInfo.type))
771 + " in computeBoundaryFlux().");
772 }
773 } else { // Non-static fluid system used in GPU assembly
774 switch (bdyInfo.type) {
775 case BCType::NONE:
776 bdyFlux = 0.0;
777 break;
778 case BCType::THERMAL:
779 computeBoundaryThermal(problem, bdyFlux, bdyInfo, insideIntQuants, globalSpaceIdx);
780 break;
781 default:
782 OPM_THROW(std::logic_error,
783 "Boundary condition type " + std::to_string(static_cast<int>(bdyInfo.type))
784 + " is not supported for GPU fluid systems in computeBoundaryFlux().");
785 }
786 }
787 }
788
789 static void computeSource(RateVector& source,
790 const Problem& problem,
791 const IntensiveQuantities& insideIntQuants,
792 unsigned globalSpaceIdex,
793 unsigned timeIdx)
794 {
795 OPM_TIMEBLOCK_LOCAL(computeSource, Subsystem::Assembly);
796 // retrieve the source term intrinsic to the problem
797 problem.source(source, globalSpaceIdex, timeIdx);
798
799 // deal with bioeffects (if present)
800 if constexpr (enableBioeffects) {
801 BioeffectsModule::addSource(source, problem, insideIntQuants, globalSpaceIdex);
802 }
803
804 // scale the source term of the energy equation
805 if constexpr (enableFullyImplicitThermal) {
806 source[Indices::contiEnergyEqIdx]
807 *= getPropValue<TypeTag, Properties::BlackOilEnergyScalingFactor>();
808 }
809 }
810
811 static void computeSourceDense(RateVector& source,
812 const Problem& problem,
813 const IntensiveQuantities& insideIntQuants,
814 unsigned globalSpaceIdex,
815 unsigned timeIdx)
816 {
817 source = 0.0;
818 problem.addToSourceDense(source, globalSpaceIdex, timeIdx);
819
820 // deal with bioeffects (if present)
821 if constexpr (enableBioeffects) {
822 BioeffectsModule::addSource(source, problem, insideIntQuants, globalSpaceIdex);
823 }
824
825 // scale the source term of the energy equation
826 if constexpr (enableFullyImplicitThermal) {
827 source[Indices::contiEnergyEqIdx]
828 *= getPropValue<TypeTag, Properties::BlackOilEnergyScalingFactor>();
829 }
830 }
831
835 void computeSource(RateVector& source,
836 const ElementContext& elemCtx,
837 unsigned dofIdx,
838 unsigned timeIdx) const
839 {
840 OPM_TIMEBLOCK_LOCAL(computeSource, Subsystem::Assembly);
841 // retrieve the source term intrinsic to the problem
842 elemCtx.problem().source(source, elemCtx, dofIdx, timeIdx);
843
844 // deal with bioeffects (if present)
845 if constexpr (enableBioeffects) {
846 BioeffectsModule::addSource(source, elemCtx, dofIdx, timeIdx);
847 }
848
849 // scale the source term of the energy equation
850 if constexpr (enableFullyImplicitThermal) {
851 source[Indices::contiEnergyEqIdx]
852 *= getPropValue<TypeTag, Properties::BlackOilEnergyScalingFactor>();
853 }
854 }
855
856 template <class UpEval, class FluidState>
857 static void evalPhaseFluxes_(RateVector& flux,
858 unsigned phaseIdx,
859 unsigned pvtRegionIdx,
860 const ExtensiveQuantities& extQuants,
861 const FluidState& upFs)
862 {
863 const auto& invB = getInvB_<FluidSystem, FluidState, UpEval>(upFs, phaseIdx, pvtRegionIdx);
864 const auto& surfaceVolumeFlux = invB * extQuants.volumeFlux(phaseIdx);
865 evalPhaseFluxes_<UpEval>(flux, phaseIdx, pvtRegionIdx, surfaceVolumeFlux, upFs);
866 }
867
872 template <class UpEval, class Eval, class FluidState, class RateVectorT = RateVector>
873 OPM_HOST_DEVICE static void evalPhaseFluxes_(RateVectorT& flux,
874 unsigned phaseIdx,
875 unsigned pvtRegionIdx,
876 const Eval& surfaceVolumeFlux,
877 const FluidState& upFs)
878 {
879 const FluidSystem& fsys = upFs.fluidSystem();
880
881 unsigned activeCompIdx
882 = fsys.canonicalToActiveCompIdx(fsys.solventComponentIndex(phaseIdx));
883
884 if constexpr (blackoilConserveSurfaceVolume) {
885 flux[conti0EqIdx + activeCompIdx] += surfaceVolumeFlux;
886 } else {
887 flux[conti0EqIdx + activeCompIdx]
888 += surfaceVolumeFlux * fsys.referenceDensity(phaseIdx, pvtRegionIdx);
889 }
890
891 if (phaseIdx == oilPhaseIdx) {
892 // dissolved gas (in the oil phase).
893 if (fsys.enableDissolvedGas()) {
894 const auto& Rs
895 = BlackOil::getRs_<FluidSystem, FluidState, UpEval>(upFs, pvtRegionIdx);
896
897 const unsigned activeGasCompIdx = fsys.canonicalToActiveCompIdx(gasCompIdx);
898 if constexpr (blackoilConserveSurfaceVolume) {
899 flux[conti0EqIdx + activeGasCompIdx] += Rs * surfaceVolumeFlux;
900 } else {
901 flux[conti0EqIdx + activeGasCompIdx] += Rs * surfaceVolumeFlux
902 * fsys.referenceDensity(gasPhaseIdx, pvtRegionIdx);
903 }
904 }
905 } else if (phaseIdx == waterPhaseIdx) {
906 // dissolved gas (in the water phase).
907 if (fsys.enableDissolvedGasInWater()) {
908 const auto& Rsw
909 = BlackOil::getRsw_<FluidSystem, FluidState, UpEval>(upFs, pvtRegionIdx);
910
911 const unsigned activeGasCompIdx = fsys.canonicalToActiveCompIdx(gasCompIdx);
912 if constexpr (blackoilConserveSurfaceVolume) {
913 flux[conti0EqIdx + activeGasCompIdx] += Rsw * surfaceVolumeFlux;
914 } else {
915 flux[conti0EqIdx + activeGasCompIdx] += Rsw * surfaceVolumeFlux
916 * fsys.referenceDensity(gasPhaseIdx, pvtRegionIdx);
917 }
918 }
919 } else if (phaseIdx == gasPhaseIdx) {
920 // vaporized oil (in the gas phase).
921 if (fsys.enableVaporizedOil()) {
922 const auto& Rv
923 = BlackOil::getRv_<FluidSystem, FluidState, UpEval>(upFs, pvtRegionIdx);
924
925 const unsigned activeOilCompIdx = fsys.canonicalToActiveCompIdx(oilCompIdx);
926 if constexpr (blackoilConserveSurfaceVolume) {
927 flux[conti0EqIdx + activeOilCompIdx] += Rv * surfaceVolumeFlux;
928 } else {
929 flux[conti0EqIdx + activeOilCompIdx] += Rv * surfaceVolumeFlux
930 * fsys.referenceDensity(oilPhaseIdx, pvtRegionIdx);
931 }
932 }
933 // vaporized water (in the gas phase).
934 if (fsys.enableVaporizedWater()) {
935 const auto& Rvw
936 = BlackOil::getRvw_<FluidSystem, FluidState, UpEval>(upFs, pvtRegionIdx);
937
938 const unsigned activeWaterCompIdx = fsys.canonicalToActiveCompIdx(waterCompIdx);
939 if constexpr (blackoilConserveSurfaceVolume) {
940 flux[conti0EqIdx + activeWaterCompIdx] += Rvw * surfaceVolumeFlux;
941 } else {
942 flux[conti0EqIdx + activeWaterCompIdx] += Rvw * surfaceVolumeFlux
943 * fsys.referenceDensity(waterPhaseIdx, pvtRegionIdx);
944 }
945 }
946 }
947 }
948
952 template <class ScalarVector>
953 OPM_HOST_DEVICE static void adaptMassConservationQuantities_(ScalarVector& container,
954 unsigned pvtRegionIdx)
955 {
956 // Delegate to the generic overload using a default-constructed static FluidSystem
957 // instance. Valid because the static FluidSystem is stateless (std::is_empty_v).
958 adaptMassConservationQuantities_(container, pvtRegionIdx, FluidSystem{});
959 }
960
975 template <class ScalarVector, class FsysType>
976 OPM_HOST_DEVICE static void adaptMassConservationQuantities_(ScalarVector& container,
977 unsigned pvtRegionIdx,
978 const FsysType& fsys)
979 {
980 if constexpr (!blackoilConserveSurfaceVolume) {
981 // convert "surface volume" to mass. this is complicated a bit by the fact that
982 // not all phases are necessarily enabled. (we here assume that if a fluid phase
983 // is disabled, its respective "main" component is not considered as well.)
984
985 if constexpr (waterEnabled) {
986 const unsigned activeWaterCompIdx = fsys.canonicalToActiveCompIdx(waterCompIdx);
987 container[conti0EqIdx + activeWaterCompIdx]
988 *= fsys.referenceDensity(waterPhaseIdx, pvtRegionIdx);
989 }
990
991 if constexpr (gasEnabled) {
992 const unsigned activeGasCompIdx = fsys.canonicalToActiveCompIdx(gasCompIdx);
993 container[conti0EqIdx + activeGasCompIdx]
994 *= fsys.referenceDensity(gasPhaseIdx, pvtRegionIdx);
995 }
996
997 if constexpr (oilEnabled) {
998 const unsigned activeOilCompIdx = fsys.canonicalToActiveCompIdx(oilCompIdx);
999 container[conti0EqIdx + activeOilCompIdx]
1000 *= fsys.referenceDensity(oilPhaseIdx, pvtRegionIdx);
1001 }
1002 }
1003 }
1004
1005 // NNC does not have a direction
1006 static FaceDir::DirEnum faceDirFromDirId(const int dirId)
1007 {
1008 return dirId < 0 ? FaceDir::DirEnum::Unknown : FaceDir::FromIntersectionIndex(dirId);
1009 }
1010};
1011
1012} // namespace Opm
1013
1014#endif
Classes required for dynamic convective mixing.
Contains classes extending the black-oil model. \detail This file holds dummy definitions,...
Declares the properties required by the black oil model.
Provides the auxiliary methods required for consideration of the diffusion equation.
Provides the auxiliary methods required for consideration of the dispersion equation.
Definition: blackoilmodules.hpp:63
Definition: blackoilfoammodules.hh:57
Calculates the local residual of the black oil model.
Definition: blackoillocalresidualtpfa.hh:67
void computeSource(RateVector &source, const ElementContext &elemCtx, unsigned dofIdx, unsigned timeIdx) const
Calculate the source term of the equation.
Definition: blackoillocalresidualtpfa.hh:835
static OPM_HOST_DEVICE void adaptMassConservationQuantities_(ScalarVector &container, unsigned pvtRegionIdx)
Definition: blackoillocalresidualtpfa.hh:953
static void computeBoundaryFluxFree(const Problem &problem, RateVector &bdyFlux, const BoundaryConditionData &bdyInfo, const IntensiveQuantities &insideIntQuants, unsigned globalSpaceIdx)
Definition: blackoillocalresidualtpfa.hh:594
static OPM_HOST_DEVICE void computeStorage(StorageType &storage, const IntensiveQuantitiesType &intQuants)
Definition: blackoillocalresidualtpfa.hh:167
static void computeBoundaryFluxRate(RateVector &bdyFlux, const BoundaryConditionData &bdyInfo)
Definition: blackoillocalresidualtpfa.hh:588
static FaceDir::DirEnum faceDirFromDirId(const int dirId)
Definition: blackoillocalresidualtpfa.hh:1006
static OPM_HOST_DEVICE void computeBoundaryThermal(const ProblemLocal &problem, RateVectorLocal &bdyFlux, const BoundaryConditionData &bdyInfo, const IntensiveQuantities &insideIntQuants, unsigned globalSpaceIdx)
Definition: blackoillocalresidualtpfa.hh:707
static OPM_HOST_DEVICE void calculateFluxes_(RateVectorT &flux, RateVectorT &darcy, const IntensiveQuantitiesT &intQuantsIn, const IntensiveQuantitiesT &intQuantsEx, const unsigned &globalIndexIn, const unsigned &globalIndexEx, const ResidualNBInfoT &nbInfo, const ModuleParamsT &moduleParams)
Definition: blackoillocalresidualtpfa.hh:374
static void evalPhaseFluxes_(RateVector &flux, unsigned phaseIdx, unsigned pvtRegionIdx, const ExtensiveQuantities &extQuants, const FluidState &upFs)
Definition: blackoillocalresidualtpfa.hh:857
static void computeFlux(RateVector &flux, const ElementContext &elemCtx, unsigned scvfIdx, unsigned timeIdx)
Definition: blackoillocalresidualtpfa.hh:296
static OPM_HOST_DEVICE void evalPhaseFluxes_(RateVectorT &flux, unsigned phaseIdx, unsigned pvtRegionIdx, const Eval &surfaceVolumeFlux, const FluidState &upFs)
Helper function to calculate the flux of mass in terms of conservation quantities via specific fluid ...
Definition: blackoillocalresidualtpfa.hh:873
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: blackoillocalresidualtpfa.hh:157
static OPM_HOST_DEVICE void computeFlux(RateVectorT &flux, RateVectorT &darcy, const unsigned globalIndexIn, const unsigned globalIndexEx, const IntensiveQuantitiesT &intQuantsIn, const IntensiveQuantitiesT &intQuantsEx, const ResidualNBInfoT &nbInfo, const ModuleParamsT &moduleParams)
Definition: blackoillocalresidualtpfa.hh:269
static OPM_HOST_DEVICE void computeBoundaryFlux(RateVectorLocal &bdyFlux, const LocalProblem &problem, const BoundaryConditionData &bdyInfo, const IntensiveQuantities &insideIntQuants, unsigned globalSpaceIdx)
Definition: blackoillocalresidualtpfa.hh:747
static void computeSource(RateVector &source, const Problem &problem, const IntensiveQuantities &insideIntQuants, unsigned globalSpaceIdex, unsigned timeIdx)
Definition: blackoillocalresidualtpfa.hh:789
static void computeSourceDense(RateVector &source, const Problem &problem, const IntensiveQuantities &insideIntQuants, unsigned globalSpaceIdex, unsigned timeIdx)
Definition: blackoillocalresidualtpfa.hh:811
static OPM_HOST_DEVICE void adaptMassConservationQuantities_(ScalarVector &container, unsigned pvtRegionIdx, const FsysType &fsys)
Helper function to convert the mass-related parts of a vector that stores conservation quantities in ...
Definition: blackoillocalresidualtpfa.hh:976
Declare the properties used by the infrastructure code of the finite volume discretizations.
@ NONE
Definition: DeferredLogger.hpp:46
Definition: blackoilbioeffectsmodules.hh:45
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
std::string to_string(const ConvergenceReport::ReservoirFailure::Type t)
Definition: blackoillocalresidualtpfa.hh:138
FaceDir::DirEnum faceDir
Definition: blackoillocalresidualtpfa.hh:144
double faceArea
Definition: blackoillocalresidualtpfa.hh:140
double thpresInToEx
Definition: blackoillocalresidualtpfa.hh:141
ConditionalStorage< enableFullyImplicitThermal, double > outAlpha
Definition: blackoillocalresidualtpfa.hh:148
ConditionalStorage< enableFullyImplicitThermal, double > inAlpha
Definition: blackoillocalresidualtpfa.hh:147
ConditionalStorage< enableDiffusion, double > diffusivity
Definition: blackoillocalresidualtpfa.hh:149
double thpresExToIn
Definition: blackoillocalresidualtpfa.hh:142
double dZg
Definition: blackoillocalresidualtpfa.hh:143
double Vin
Definition: blackoillocalresidualtpfa.hh:145
ConditionalStorage< enableDispersion, double > dispersivity
Definition: blackoillocalresidualtpfa.hh:150
double trans
Definition: blackoillocalresidualtpfa.hh:139
double Vex
Definition: blackoillocalresidualtpfa.hh:146
Definition: tpfalinearizerstructs.hh:89
double faceArea
Definition: tpfalinearizerstructs.hh:94
VectorBlock massRate
Definition: tpfalinearizerstructs.hh:91
BCType type
Definition: tpfalinearizerstructs.hh:90
unsigned boundaryFaceIndex
Definition: tpfalinearizerstructs.hh:93
double faceZCoord
Definition: tpfalinearizerstructs.hh:95
ScalarFluidState exFluidState
Definition: tpfalinearizerstructs.hh:96
unsigned pvtRegionIdx
Definition: tpfalinearizerstructs.hh:92