version 3.8
porousmediumflow/nonequilibrium/volumevariables.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// SPDX-FileCopyrightInfo: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
18#ifndef DUMUX_NONEQUILIBRIUM_VOLUME_VARIABLES_HH
19#define DUMUX_NONEQUILIBRIUM_VOLUME_VARIABLES_HH
20
21#include <cassert>
22#include <array>
23
26
27namespace Dumux {
28
35template<class Traits, class EquilibriumVolumeVariables, bool enableChemicalNonEquilibrium,
36 bool enableThermalNonEquilibrium, int numEnergyEqFluid>
38
39template<class Traits, class EquilibriumVolumeVariables>
42 EquilibriumVolumeVariables,
43 Traits::ModelTraits::enableChemicalNonEquilibrium(),
44 Traits::ModelTraits::enableThermalNonEquilibrium(),
45 Traits::ModelTraits::numEnergyEqFluid()>;
46
48// specialization for the case of NO kinetic mass but kinetic energy transfer of two fluids and a solid
50template<class Traits, class EquilibriumVolumeVariables>
52 EquilibriumVolumeVariables,
53 false/*chemicalNonEquilibrium?*/,
54 true/*thermalNonEquilibrium?*/,
55 2>
56: public EquilibriumVolumeVariables
57{
58 using ParentType = EquilibriumVolumeVariables;
59 using ParameterCache = typename Traits::FluidSystem::ParameterCache;
60 using Scalar = typename Traits::PrimaryVariables::value_type;
61
62 using ModelTraits = typename Traits::ModelTraits;
63
64 using FS = typename Traits::FluidSystem;
65 static constexpr auto numEnergyEqFluid = ModelTraits::numEnergyEqFluid();
66 static constexpr auto numEnergyEqSolid = ModelTraits::numEnergyEqSolid();
67
68 static constexpr auto phase0Idx = FS::phase0Idx;
69 static constexpr auto phase1Idx = FS::phase1Idx;
70 static constexpr auto sPhaseIdx = FS::numPhases;
71
73
74 using NumFluidPhasesArray = std::array<Scalar, ModelTraits::numFluidPhases()>;
75 using InterfacialAreasArray = std::array<std::array<Scalar, ModelTraits::numFluidPhases()+numEnergyEqSolid>,
76 ModelTraits::numFluidPhases()+numEnergyEqSolid>;
77
78public:
79 using FluidState = typename Traits::FluidState;
80 using Indices = typename ModelTraits::Indices;
89 template<class ElemSol, class Problem, class Element, class Scv>
90 void update(const ElemSol &elemSol,
91 const Problem &problem,
92 const Element &element,
93 const Scv& scv)
94 {
95 // Update parent type (also completes the fluid state)
96 ParentType::update(elemSol, problem, element, scv);
97
98 ParameterCache paramCache;
99 paramCache.updateAll(this->fluidState());
100 updateDimLessNumbers(elemSol, this->fluidState(), paramCache, problem, element, scv);
101 updateInterfacialArea(elemSol, this->fluidState(), paramCache, problem, element, scv);
102 }
103
114 template<class ElemSol, class Problem, class Element, class Scv>
115 void updateDimLessNumbers(const ElemSol& elemSol,
116 const FluidState& fluidState,
117 const ParameterCache& paramCache,
118 const Problem& problem,
119 const Element& element,
120 const Scv& scv)
121 {
122 const auto& spatialParams = problem.spatialParams();
123 factorEnergyTransfer_ = spatialParams.factorEnergyTransfer(element, scv, elemSol);
124 characteristicLength_ = spatialParams.characteristicLength(element, scv, elemSol);
125
126 // set the dimensionless numbers and obtain respective quantities
127 const unsigned int vIdxGlobal = scv.dofIndex();
128 for (int phaseIdx = 0; phaseIdx < ModelTraits::numFluidPhases(); ++phaseIdx)
129 {
130 const auto darcyMagVelocity = problem.gridVariables().volumeDarcyMagVelocity(phaseIdx, vIdxGlobal);
131 const auto dynamicViscosity = fluidState.viscosity(phaseIdx);
132 const auto density = fluidState.density(phaseIdx);
133 const auto kinematicViscosity = dynamicViscosity/density;
134
135 using FluidSystem = typename Traits::FluidSystem;
136 const auto heatCapacity = FluidSystem::heatCapacity(fluidState, paramCache, phaseIdx);
137 const auto thermalConductivity = FluidSystem::thermalConductivity(fluidState, paramCache, phaseIdx);
138 const auto porosity = this->porosity();
139
140 reynoldsNumber_[phaseIdx] = DimLessNum::reynoldsNumber(darcyMagVelocity, characteristicLength_,kinematicViscosity);
141 prandtlNumber_[phaseIdx] = DimLessNum::prandtlNumber(dynamicViscosity, heatCapacity, thermalConductivity);
142 nusseltNumber_[phaseIdx] = DimLessNum::nusseltNumberForced(reynoldsNumber_[phaseIdx],
143 prandtlNumber_[phaseIdx],
144 porosity,
145 ModelTraits::nusseltFormulation());
146
147 }
148 }
149
160 template<class ElemSol, class Problem, class Element, class Scv>
161 void updateInterfacialArea(const ElemSol& elemSol,
162 const FluidState& fluidState,
163 const ParameterCache& paramCache,
164 const Problem& problem,
165 const Element& element,
166 const Scv& scv)
167 {
168 const Scalar pc = fluidState.pressure(phase1Idx) - fluidState.pressure(phase0Idx);
169 const Scalar Sw = fluidState.saturation(phase0Idx);
170
171 const auto fluidMatrixInteraction = problem.spatialParams().fluidMatrixInteraction(element, scv, elemSol);
172 const auto areaWN = fluidMatrixInteraction.wettingNonwettingInterface().area(Sw, pc);
173 const auto areaNS = fluidMatrixInteraction.nonwettingSolidInterface().area(Sw, pc);
174 interfacialArea_[phase0Idx][phase1Idx] = areaWN;
175 interfacialArea_[phase1Idx][phase0Idx] = interfacialArea_[phase0Idx][phase1Idx];
176 interfacialArea_[phase0Idx][phase0Idx] = 0.0;
177
178 // Switch for using a a_{wn} relations that has some "maximum capillary pressure" as parameter
179 // That value is obtained by regularization of the pc(Sw) function.
180 static const bool computeAwsFromAnsAndPcMax = getParam<bool>("SpatialParams.ComputeAwsFromAnsAndPcMax", true);
181 if (computeAwsFromAnsAndPcMax)
182 {
183 // I know the solid surface from the pore network. But it is more consistent to use the fit value.
184 const Scalar pcMax = fluidMatrixInteraction.wettingNonwettingInterface().basicParams().pcMax();
185 const auto solidSurface = fluidMatrixInteraction.nonwettingSolidInterface().area(/*Sw=*/0., pcMax);
186 interfacialArea_[phase0Idx][sPhaseIdx] = solidSurface - areaNS;
187 }
188 else
189 interfacialArea_[phase0Idx][sPhaseIdx] = fluidMatrixInteraction.wettingSolidInterface().area(Sw, pc);
190
191 interfacialArea_[sPhaseIdx][phase0Idx] = interfacialArea_[phase0Idx][sPhaseIdx];
192 interfacialArea_[sPhaseIdx][sPhaseIdx] = 0.0;
193
194 interfacialArea_[phase1Idx][sPhaseIdx] = areaNS;
195 interfacialArea_[sPhaseIdx][phase1Idx] = interfacialArea_[phase1Idx][sPhaseIdx];
196 interfacialArea_[phase1Idx][phase1Idx] = 0.0;
197 }
198
203 const Scalar interfacialArea(const unsigned int phaseIIdx, const unsigned int phaseJIdx) const
204 {
205 // there is no interfacial area between a phase and itself
206 assert(phaseIIdx not_eq phaseJIdx);
207 return interfacialArea_[phaseIIdx][phaseJIdx];
208 }
209
211 const Scalar reynoldsNumber(const unsigned int phaseIdx) const
212 { return reynoldsNumber_[phaseIdx]; }
213
215 const Scalar prandtlNumber(const unsigned int phaseIdx) const
216 { return prandtlNumber_[phaseIdx]; }
217
219 const Scalar nusseltNumber(const unsigned int phaseIdx) const
220 { return nusseltNumber_[phaseIdx]; }
221
223 const Scalar characteristicLength() const
224 { return characteristicLength_; }
225
227 const Scalar factorEnergyTransfer() const
228 { return factorEnergyTransfer_; }
229
230private:
232 NumFluidPhasesArray reynoldsNumber_;
233 NumFluidPhasesArray prandtlNumber_;
234 NumFluidPhasesArray nusseltNumber_;
235
236 Scalar characteristicLength_;
237 Scalar factorEnergyTransfer_;
238 InterfacialAreasArray interfacialArea_;
239};
240
242// specialization for the case of NO kinetic mass but kinetic energy transfer of a fluid mixture and a solid
244template<class Traits, class EquilibriumVolumeVariables>
246 EquilibriumVolumeVariables,
247 false/*chemicalNonEquilibrium?*/,
248 true/*thermalNonEquilibrium?*/,
249 1>
250: public EquilibriumVolumeVariables
251{
252 using ParentType = EquilibriumVolumeVariables;
253 using ParameterCache = typename Traits::FluidSystem::ParameterCache;
254 using Scalar = typename Traits::PrimaryVariables::value_type;
255
256 using ModelTraits = typename Traits::ModelTraits;
257 using FS = typename Traits::FluidSystem;
258 static constexpr auto numEnergyEqFluid = ModelTraits::numEnergyEqFluid();
259 static constexpr auto numEnergyEqSolid = ModelTraits::numEnergyEqSolid();
260
262
263 using NumFluidPhasesArray = std::array<Scalar, ModelTraits::numFluidPhases()>;
264
265public:
266 using Indices = typename ModelTraits::Indices;
267 using FluidState = typename Traits::FluidState;
268
278 template<class ElemSol, class Problem, class Element, class Scv>
279 void update(const ElemSol &elemSol,
280 const Problem &problem,
281 const Element &element,
282 const Scv& scv)
283 {
284 // Update parent type (also completes the fluid state)
285 ParentType::update(elemSol, problem, element, scv);
286
287 ParameterCache paramCache;
288 paramCache.updateAll(this->fluidState());
289 //only update of DimLessNumbers is necessary here, as interfacial area
290 // is easy due to only one fluid with a solid and is directly computed in localresidual
291 updateDimLessNumbers(elemSol, this->fluidState(), paramCache, problem, element, scv);
292 updateInterfacialArea(elemSol, this->fluidState(), paramCache, problem, element, scv);
293 }
294
305 template<class ElemSol, class Problem, class Element, class Scv>
306 void updateDimLessNumbers(const ElemSol& elemSol,
307 const FluidState& fluidState,
308 const ParameterCache& paramCache,
309 const Problem& problem,
310 const Element& element,
311 const Scv& scv)
312 {
313 const auto& spatialParams = problem.spatialParams();
314 factorEnergyTransfer_ = spatialParams.factorEnergyTransfer(element, scv, elemSol);
315 characteristicLength_ = spatialParams.characteristicLength(element, scv, elemSol);
316
317 // set the dimensionless numbers and obtain respective quantities
318 const unsigned int vIdxGlobal = scv.dofIndex();
319 for (int phaseIdx = 0; phaseIdx < ModelTraits::numFluidPhases(); ++phaseIdx)
320 {
321 const auto darcyMagVelocity = problem.gridVariables().volumeDarcyMagVelocity(phaseIdx, vIdxGlobal);
322 const auto dynamicViscosity = fluidState.viscosity(phaseIdx);
323 const auto density = fluidState.density(phaseIdx);
324 const auto kinematicViscosity = dynamicViscosity/density;
325
326 using FluidSystem = typename Traits::FluidSystem;
327 const auto heatCapacity = FluidSystem::heatCapacity(fluidState, paramCache, phaseIdx);
328 const auto thermalConductivity = FluidSystem::thermalConductivity(fluidState, paramCache, phaseIdx);
329 const auto porosity = this->porosity();
330
331 reynoldsNumber_[phaseIdx] = DimLessNum::reynoldsNumber(darcyMagVelocity, characteristicLength_,kinematicViscosity);
332 prandtlNumber_[phaseIdx] = DimLessNum::prandtlNumber(dynamicViscosity, heatCapacity, thermalConductivity);
333 nusseltNumber_[phaseIdx] = DimLessNum::nusseltNumberForced(reynoldsNumber_[phaseIdx],
334 prandtlNumber_[phaseIdx],
335 porosity,
336 ModelTraits::nusseltFormulation());
337 }
338 }
339
340
351 template<class ElemSol, class Problem, class Element, class Scv>
352 void updateInterfacialArea(const ElemSol& elemSol,
353 const FluidState& fluidState,
354 const ParameterCache& paramCache,
355 const Problem& problem,
356 const Element& element,
357 const Scv& scv)
358 {
359 using FluidSolidInterfacialAreaFormulation = typename Problem::SpatialParams::FluidSolidInterfacialAreaFormulation;
360 interfacialArea_ = FluidSolidInterfacialAreaFormulation::fluidSolidInterfacialArea(this->porosity(), characteristicLength());
361 }
362
364 const Scalar reynoldsNumber(const unsigned int phaseIdx) const
365 { return reynoldsNumber_[phaseIdx]; }
366
368 const Scalar prandtlNumber(const unsigned int phaseIdx) const
369 { return prandtlNumber_[phaseIdx]; }
370
372 const Scalar nusseltNumber(const unsigned int phaseIdx) const
373 { return nusseltNumber_[phaseIdx]; }
374
376 const Scalar characteristicLength() const
377 { return characteristicLength_; }
378
380 const Scalar factorEnergyTransfer() const
381 { return factorEnergyTransfer_; }
382
383 const Scalar fluidSolidInterfacialArea() const
384 {return interfacialArea_;}
385
386private:
388 NumFluidPhasesArray reynoldsNumber_;
389 NumFluidPhasesArray prandtlNumber_;
390 NumFluidPhasesArray nusseltNumber_;
391
392 Scalar characteristicLength_;
393 Scalar factorEnergyTransfer_;
394 Scalar interfacialArea_ ;
395};
396
398// specialization for the case of (only) kinetic mass transfer. Be careful, we do not test this!
400template<class Traits, class EquilibriumVolumeVariables>
402 EquilibriumVolumeVariables,
403 true/*chemicalNonEquilibrium?*/,
404 false/*thermalNonEquilibrium?*/,
405 0>
406: public EquilibriumVolumeVariables
407{
408 using ParentType = EquilibriumVolumeVariables;
409 using FluidState = typename Traits::FluidState;
410 using FS = typename Traits::FluidSystem;
411 using ParameterCache = typename Traits::FluidSystem::ParameterCache;
412 using Scalar = typename Traits::PrimaryVariables::value_type;
413
414 using ModelTraits = typename Traits::ModelTraits;
415
416 static constexpr auto phase0Idx = FS::phase0Idx;
417 static constexpr auto phase1Idx = FS::phase1Idx;
418 static constexpr auto wCompIdx = FS::comp0Idx;
419 static constexpr auto nCompIdx = FS::comp1Idx;
420
422
423 using NumFluidPhasesArray = std::array<Scalar, ModelTraits::numFluidPhases()>;
424
425public:
426 using Indices = typename ModelTraits::Indices;
436 template<class ElemSol, class Problem, class Element, class Scv>
437 void update(const ElemSol &elemSol,
438 const Problem &problem,
439 const Element &element,
440 const Scv& scv)
441 {
442 // Update parent type (also completes the fluid state)
443 ParentType::update(elemSol, problem, element, scv);
444
445 ParameterCache paramCache;
446 paramCache.updateAll(this->fluidState());
447 updateDimLessNumbers(elemSol, this->fluidState(), paramCache, problem, element, scv);
448 updateInterfacialArea(elemSol, this->fluidState(), paramCache, problem, element, scv);
449 }
450
461 template<class ElemSol, class Problem, class Element, class Scv>
462 void updateDimLessNumbers(const ElemSol& elemSol,
463 const FluidState& fluidState,
464 const ParameterCache& paramCache,
465 const Problem& problem,
466 const Element& element,
467 const Scv& scv)
468 {
469 const auto& spatialParams = problem.spatialParams();
470 factorMassTransfer_ = spatialParams.factorMassTransfer(element, scv, elemSol);
471 characteristicLength_ = spatialParams.characteristicLength(element, scv, elemSol);
472
473 // set the dimensionless numbers and obtain respective quantities.
474 const unsigned int vIdxGlobal = scv.dofIndex();
475 for (int phaseIdx = 0; phaseIdx < ModelTraits::numFluidPhases(); ++phaseIdx)
476 {
477 const auto darcyMagVelocity = problem.gridVariables().volumeDarcyMagVelocity(phaseIdx, vIdxGlobal);
478 const auto dynamicViscosity = fluidState.viscosity(phaseIdx);
479 const auto density = fluidState.density(phaseIdx);
480 const auto kinematicViscosity = dynamicViscosity/density;
481
482 // diffusion coefficient of nonwetting component in wetting phase
483 using FluidSystem = typename Traits::FluidSystem;
484 const auto diffCoeff = FluidSystem::binaryDiffusionCoefficient(fluidState,
485 paramCache,
486 phaseIdx,
487 wCompIdx,
488 nCompIdx);
489
490 reynoldsNumber_[phaseIdx] = DimLessNum::reynoldsNumber(darcyMagVelocity, characteristicLength_, kinematicViscosity);
491 schmidtNumber_[phaseIdx] = DimLessNum::schmidtNumber(dynamicViscosity, density, diffCoeff);
492 sherwoodNumber_[phaseIdx] = DimLessNum::sherwoodNumber(reynoldsNumber_[phaseIdx],
493 schmidtNumber_[phaseIdx],
494 ModelTraits::sherwoodFormulation());
495 }
496 }
497
508 template<class ElemSol, class Problem, class Element, class Scv>
509 void updateInterfacialArea(const ElemSol& elemSol,
510 const FluidState& fluidState,
511 const ParameterCache& paramCache,
512 const Problem& problem,
513 const Element& element,
514 const Scv& scv)
515 {
516 const auto Sw = fluidState.saturation(phase0Idx) ;
517 const auto pc = fluidState.pressure(phase1Idx) - fluidState.pressure(phase0Idx);
518
519 // when we only consider chemical non-equilibrium there is only mass transfer between
520 // the fluid phases, so in 2p only interfacial area between wetting and non-wetting
521 const auto fluidMatrixInteraction = problem.spatialParams().fluidMatrixInteraction(element, scv, elemSol);
522 interfacialArea_ = fluidMatrixInteraction.wettingNonwettingInterface().area(Sw, pc);
523 }
524
528 const Scalar interfacialArea(const unsigned int phaseIIdx, const unsigned int phaseJIdx) const
529 {
530 // so far there is only a model for kinetic mass transfer between fluid phases
531 assert( (phaseIIdx == phase1Idx && phaseJIdx == phase0Idx)
532 || (phaseIIdx == phase0Idx && phaseJIdx == phase1Idx) );
533 return interfacialArea_;
534 }
535
537 const Scalar reynoldsNumber(const unsigned int phaseIdx) const
538 { return reynoldsNumber_[phaseIdx]; }
539
541 const Scalar schmidtNumber(const unsigned int phaseIdx) const
542 { return schmidtNumber_[phaseIdx]; }
543
545 const Scalar sherwoodNumber(const unsigned int phaseIdx) const
546 { return sherwoodNumber_[phaseIdx]; }
547
549 const Scalar characteristicLength() const
550 { return characteristicLength_; }
551
553 const Scalar factorMassTransfer() const
554 { return factorMassTransfer_; }
555
556private:
557 Scalar characteristicLength_;
558 Scalar factorMassTransfer_;
559 Scalar interfacialArea_ ;
560 NumFluidPhasesArray sherwoodNumber_;
561 NumFluidPhasesArray schmidtNumber_;
562 NumFluidPhasesArray reynoldsNumber_;
563};
564
565// Specialization where everything is in non-equilibrium.
566template<class Traits, class EquilibriumVolumeVariables>
568 EquilibriumVolumeVariables,
569 true/*chemicalNonEquilibrium?*/,
570 true/*thermalNonEquilibrium?*/,
571 2>
572: public EquilibriumVolumeVariables
573{
574 using ParentType = EquilibriumVolumeVariables;
575 using FluidState = typename Traits::FluidState;
576 using FS = typename Traits::FluidSystem;
577 using ParameterCache = typename Traits::FluidSystem::ParameterCache;
578 using Scalar = typename Traits::PrimaryVariables::value_type;
579
580 using ModelTraits = typename Traits::ModelTraits;
581 static constexpr auto numEnergyEqFluid = ModelTraits::numEnergyEqFluid();
582 static constexpr auto numEnergyEqSolid = ModelTraits::numEnergyEqSolid();
583
584 static constexpr auto phase0Idx = FS::phase0Idx;
585 static constexpr auto phase1Idx = FS::phase1Idx;
586 static constexpr auto sPhaseIdx = FS::numPhases;
587 static constexpr auto wCompIdx = FS::comp0Idx;
588 static constexpr auto nCompIdx = FS::comp1Idx;
589
591 static_assert((numEnergyEqFluid > 1), "This model only deals with energy transfer between two fluids and one solid phase");
592
593 using NumFluidPhasesArray = std::array<Scalar, ModelTraits::numFluidPhases()>;
594 using InterfacialAreasArray = std::array<std::array<Scalar, ModelTraits::numFluidPhases()+numEnergyEqSolid>,
595 ModelTraits::numFluidPhases()+numEnergyEqSolid>;
596
597public:
598 using Indices = typename ModelTraits::Indices;
599
609 template<class ElemSol, class Problem, class Element, class Scv>
610 void update(const ElemSol &elemSol,
611 const Problem &problem,
612 const Element &element,
613 const Scv& scv)
614 {
615 // Update parent type (also completes the fluid state)
616 ParentType::update(elemSol, problem, element, scv);
617
618 ParameterCache paramCache;
619 paramCache.updateAll(this->fluidState());
620 updateDimLessNumbers(elemSol, this->fluidState(), paramCache, problem, element, scv);
621 updateInterfacialArea(elemSol, this->fluidState(), paramCache, problem, element, scv);
622 }
623
634 template<class ElemSol, class Problem, class Element, class Scv>
635 void updateDimLessNumbers(const ElemSol& elemSol,
636 const FluidState& fluidState,
637 const ParameterCache& paramCache,
638 const Problem& problem,
639 const Element& element,
640 const Scv& scv)
641 {
642 const auto& spatialParams = problem.spatialParams();
643 factorMassTransfer_ = spatialParams.factorMassTransfer(element, scv, elemSol);
644 factorEnergyTransfer_ = spatialParams.factorEnergyTransfer(element, scv, elemSol);
645 characteristicLength_ = spatialParams.characteristicLength(element, scv, elemSol);
646
647 const auto vIdxGlobal = scv.dofIndex();
648 using FluidSystem = typename Traits::FluidSystem;
649 for (int phaseIdx = 0; phaseIdx < ModelTraits::numFluidPhases(); ++phaseIdx)
650 {
651 const auto darcyMagVelocity = problem.gridVariables().volumeDarcyMagVelocity(phaseIdx, vIdxGlobal);
652 const auto dynamicViscosity = fluidState.viscosity(phaseIdx);
653 const auto density = fluidState.density(phaseIdx);
654 const auto kinematicViscosity = dynamicViscosity/density;
655 const auto heatCapacity = FluidSystem::heatCapacity(fluidState, paramCache, phaseIdx);
656 const auto thermalConductivity = FluidSystem::thermalConductivity(fluidState, paramCache, phaseIdx);
657
658 // diffusion coefficient of nonwetting component in wetting phase
659 const auto porosity = this->porosity();
660 const auto diffCoeff = FluidSystem::binaryDiffusionCoefficient(fluidState,
661 paramCache,
662 phaseIdx,
663 wCompIdx,
664 nCompIdx);
665
666 reynoldsNumber_[phaseIdx] = DimLessNum::reynoldsNumber(darcyMagVelocity, characteristicLength_, kinematicViscosity);
667 prandtlNumber_[phaseIdx] = DimLessNum::prandtlNumber(dynamicViscosity, heatCapacity, thermalConductivity);
668 schmidtNumber_[phaseIdx] = DimLessNum::schmidtNumber(dynamicViscosity, density, diffCoeff);
669 nusseltNumber_[phaseIdx] = DimLessNum::nusseltNumberForced(reynoldsNumber_[phaseIdx],
670 prandtlNumber_[phaseIdx],
671 porosity,
672 ModelTraits::nusseltFormulation());
673 // If Diffusion is not enabled, Sherwood is divided by zero
674 sherwoodNumber_[phaseIdx] = DimLessNum::sherwoodNumber(reynoldsNumber_[phaseIdx],
675 schmidtNumber_[phaseIdx],
676 ModelTraits::sherwoodFormulation());
677 }
678 }
679
690 template<class ElemSol, class Problem, class Element, class Scv>
691 void updateInterfacialArea(const ElemSol& elemSol,
692 const FluidState& fluidState,
693 const ParameterCache& paramCache,
694 const Problem& problem,
695 const Element& element,
696 const Scv& scv)
697 {
698 const Scalar pc = fluidState.pressure(phase1Idx) - fluidState.pressure(phase0Idx);
699 const Scalar Sw = fluidState.saturation(phase0Idx);
700
701 const auto fluidMatrixInteraction = problem.spatialParams().fluidMatrixInteraction(element, scv, elemSol);
702
703 const auto awn = fluidMatrixInteraction.wettingNonwettingInterface().area(Sw, pc);
704 interfacialArea_[phase0Idx][phase1Idx] = awn;
705 interfacialArea_[phase1Idx][phase0Idx] = interfacialArea_[phase0Idx][phase1Idx];
706 interfacialArea_[phase0Idx][phase0Idx] = 0.;
707
708 const auto areaNS = fluidMatrixInteraction.nonwettingSolidInterface().area(Sw, pc);
709
710 // Switch for using a a_{wn} relations that has some "maximum capillary pressure" as parameter.
711 // That value is obtained by regularization of the pc(Sw) function.
712 static const bool computeAwsFromAnsAndPcMax = getParam<bool>("SpatialParams.ComputeAwsFromAnsAndPcMax", true);
713 if (computeAwsFromAnsAndPcMax)
714 {
715 // I know the solid surface from the pore network. But it is more consistent to use the fit value.
716 const Scalar pcMax = fluidMatrixInteraction.wettingNonwettingInterface().basicParams().pcMax();
717 const auto solidSurface = fluidMatrixInteraction.nonwettingSolidInterface().area(/*Sw=*/0., pcMax);
718 interfacialArea_[phase0Idx][sPhaseIdx] = solidSurface - areaNS;
719 }
720 else
721 interfacialArea_[phase0Idx][sPhaseIdx] = fluidMatrixInteraction.wettingSolidInterface().area(Sw, pc);
722
723 interfacialArea_[sPhaseIdx][phase0Idx] = interfacialArea_[phase0Idx][sPhaseIdx];
724 interfacialArea_[sPhaseIdx][sPhaseIdx] = 0.;
725
726 interfacialArea_[phase1Idx][sPhaseIdx] = areaNS;
727 interfacialArea_[sPhaseIdx][phase1Idx] = interfacialArea_[phase1Idx][sPhaseIdx];
728 interfacialArea_[phase1Idx][phase1Idx] = 0.;
729 }
730
735 const Scalar interfacialArea(const unsigned int phaseIIdx, const unsigned int phaseJIdx) const
736 {
737 // there is no interfacial area between a phase and itself
738 assert(phaseIIdx not_eq phaseJIdx);
739 return interfacialArea_[phaseIIdx][phaseJIdx];
740 }
741
743 const Scalar reynoldsNumber(const unsigned int phaseIdx) const
744 { return reynoldsNumber_[phaseIdx]; }
745
747 const Scalar prandtlNumber(const unsigned int phaseIdx) const
748 { return prandtlNumber_[phaseIdx]; }
749
751 const Scalar nusseltNumber(const unsigned int phaseIdx) const
752 { return nusseltNumber_[phaseIdx]; }
753
755 const Scalar schmidtNumber(const unsigned int phaseIdx) const
756 { return schmidtNumber_[phaseIdx]; }
757
759 const Scalar sherwoodNumber(const unsigned int phaseIdx) const
760 { return sherwoodNumber_[phaseIdx]; }
761
763 const Scalar characteristicLength() const
764 { return characteristicLength_; }
765
767 const Scalar factorEnergyTransfer() const
768 { return factorEnergyTransfer_; }
769
771 const Scalar factorMassTransfer() const
772 { return factorMassTransfer_; }
773
774private:
776 NumFluidPhasesArray reynoldsNumber_;
777 NumFluidPhasesArray prandtlNumber_;
778 NumFluidPhasesArray nusseltNumber_;
779 NumFluidPhasesArray schmidtNumber_;
780 NumFluidPhasesArray sherwoodNumber_;
781 Scalar characteristicLength_;
782 Scalar factorEnergyTransfer_;
783 Scalar factorMassTransfer_;
784 InterfacialAreasArray interfacialArea_;
785};
786
787} // namespace Dumux
788
789#endif
Collection of functions which calculate dimensionless numbers. Each number has it's own function....
Definition: dimensionlessnumbers.hh:53
void updateInterfacialArea(const ElemSol &elemSol, const FluidState &fluidState, const ParameterCache &paramCache, const Problem &problem, const Element &element, const Scv &scv)
Updates the volume specific interfacial area [m^2 / m^3] between the phases.
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:161
const Scalar factorEnergyTransfer() const
access function pre factor energy transfer
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:227
const Scalar prandtlNumber(const unsigned int phaseIdx) const
access function Prandtl Number
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:215
const Scalar interfacialArea(const unsigned int phaseIIdx, const unsigned int phaseJIdx) const
The specific interfacial area between two fluid phases [m^2 / m^3].
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:203
typename ModelTraits::Indices Indices
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:80
void update(const ElemSol &elemSol, const Problem &problem, const Element &element, const Scv &scv)
Update all quantities for a given control volume.
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:90
const Scalar reynoldsNumber(const unsigned int phaseIdx) const
access function Reynolds Number
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:211
void updateDimLessNumbers(const ElemSol &elemSol, const FluidState &fluidState, const ParameterCache &paramCache, const Problem &problem, const Element &element, const Scv &scv)
Updates dimensionless numbers.
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:115
const Scalar nusseltNumber(const unsigned int phaseIdx) const
access function Nusselt Number
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:219
const Scalar characteristicLength() const
access function characteristic length
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:223
typename Traits::FluidState FluidState
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:79
const Scalar characteristicLength() const
access function characteristic length
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:763
const Scalar sherwoodNumber(const unsigned int phaseIdx) const
access function Sherwood Number
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:759
typename ModelTraits::Indices Indices
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:598
void update(const ElemSol &elemSol, const Problem &problem, const Element &element, const Scv &scv)
Update all quantities for a given control volume.
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:610
const Scalar factorMassTransfer() const
access function pre factor mass transfer
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:771
const Scalar factorEnergyTransfer() const
access function pre factor energy transfer
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:767
const Scalar schmidtNumber(const unsigned int phaseIdx) const
access function Schmidt Number
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:755
const Scalar nusseltNumber(const unsigned int phaseIdx) const
access function Nusselt Number
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:751
const Scalar interfacialArea(const unsigned int phaseIIdx, const unsigned int phaseJIdx) const
The specific interfacial area between two fluid phases [m^2 / m^3].
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:735
const Scalar prandtlNumber(const unsigned int phaseIdx) const
access function Prandtl Number
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:747
void updateDimLessNumbers(const ElemSol &elemSol, const FluidState &fluidState, const ParameterCache &paramCache, const Problem &problem, const Element &element, const Scv &scv)
Updates the volume specific interfacial area [m^2 / m^3] between the phases.
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:635
const Scalar reynoldsNumber(const unsigned int phaseIdx) const
access function Reynolds Number
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:743
void updateInterfacialArea(const ElemSol &elemSol, const FluidState &fluidState, const ParameterCache &paramCache, const Problem &problem, const Element &element, const Scv &scv)
Updates the volume specific interfacial area [m^2 / m^3] between the phases.
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:691
void update(const ElemSol &elemSol, const Problem &problem, const Element &element, const Scv &scv)
Update all quantities for a given control volume.
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:437
const Scalar reynoldsNumber(const unsigned int phaseIdx) const
access function Reynolds Number
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:537
void updateDimLessNumbers(const ElemSol &elemSol, const FluidState &fluidState, const ParameterCache &paramCache, const Problem &problem, const Element &element, const Scv &scv)
Updates the volume specific interfacial area [m^2 / m^3] between the phases.
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:462
typename ModelTraits::Indices Indices
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:426
const Scalar characteristicLength() const
access function characteristic length
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:549
const Scalar sherwoodNumber(const unsigned int phaseIdx) const
access function Sherwood Number
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:545
const Scalar factorMassTransfer() const
access function pre factor mass transfer
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:553
const Scalar interfacialArea(const unsigned int phaseIIdx, const unsigned int phaseJIdx) const
The specific interfacial area between two fluid phases [m^2 / m^3].
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:528
void updateInterfacialArea(const ElemSol &elemSol, const FluidState &fluidState, const ParameterCache &paramCache, const Problem &problem, const Element &element, const Scv &scv)
Updates the volume specific interfacial area [m^2 / m^3] between the phases.
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:509
const Scalar schmidtNumber(const unsigned int phaseIdx) const
access function Schmidt Number
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:541
typename ModelTraits::Indices Indices
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:266
const Scalar fluidSolidInterfacialArea() const
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:383
const Scalar characteristicLength() const
access function characteristic length
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:376
const Scalar reynoldsNumber(const unsigned int phaseIdx) const
access function Reynolds Number
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:364
void updateDimLessNumbers(const ElemSol &elemSol, const FluidState &fluidState, const ParameterCache &paramCache, const Problem &problem, const Element &element, const Scv &scv)
Updates dimensionless numbers.
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:306
void updateInterfacialArea(const ElemSol &elemSol, const FluidState &fluidState, const ParameterCache &paramCache, const Problem &problem, const Element &element, const Scv &scv)
Updates the volume specific interfacial area [m^2 / m^3] between the solid and the fluid phase.
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:352
const Scalar nusseltNumber(const unsigned int phaseIdx) const
access function Nusselt Number
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:372
const Scalar prandtlNumber(const unsigned int phaseIdx) const
access function Prandtl Number
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:368
typename Traits::FluidState FluidState
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:267
const Scalar factorEnergyTransfer() const
access function pre factor energy transfer
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:380
void update(const ElemSol &elemSol, const Problem &problem, const Element &element, const Scv &scv)
Update all quantities for a given control volume.
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:279
This class contains the volume variables required for the modules which require the specific interfac...
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:37
Collection of functions, calculating dimensionless numbers.
std::string density(int phaseIdx) noexcept
I/O name of density for multiphase systems.
Definition: name.hh:53
std::string porosity() noexcept
I/O name of porosity.
Definition: name.hh:127
Definition: adapt.hh:17
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.