3.3.0
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
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 * See the file COPYING for full copying permissions. *
5 * *
6 * This program is free software: you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation, either version 3 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 *****************************************************************************/
30#ifndef DUMUX_NONEQUILIBRIUM_VOLUME_VARIABLES_HH
31#define DUMUX_NONEQUILIBRIUM_VOLUME_VARIABLES_HH
32
33#include <cassert>
34#include <array>
35
38
40
41namespace Dumux {
42
49template<class Traits, class EquilibriumVolumeVariables, bool enableChemicalNonEquilibrium,
50 bool enableThermalNonEquilibrium, int numEnergyEqFluid>
52
53template<class Traits, class EquilibriumVolumeVariables>
56 EquilibriumVolumeVariables,
57 Traits::ModelTraits::enableChemicalNonEquilibrium(),
58 Traits::ModelTraits::enableThermalNonEquilibrium(),
59 Traits::ModelTraits::numEnergyEqFluid()>;
60
62// specialization for the case of NO kinetic mass but kinetic energy transfer of two fluids and a solid
64template<class Traits, class EquilibriumVolumeVariables>
66 EquilibriumVolumeVariables,
67 false/*chemicalNonEquilibrium?*/,
68 true/*thermalNonEquilibrium?*/,
69 2>
70: public EquilibriumVolumeVariables
71{
72 using ParentType = EquilibriumVolumeVariables;
73 using ParameterCache = typename Traits::FluidSystem::ParameterCache;
74 using Scalar = typename Traits::PrimaryVariables::value_type;
75
76 using ModelTraits = typename Traits::ModelTraits;
77
78 using FS = typename Traits::FluidSystem;
79 static constexpr auto numEnergyEqFluid = ModelTraits::numEnergyEqFluid();
80 static constexpr auto numEnergyEqSolid = ModelTraits::numEnergyEqSolid();
81
82 static constexpr auto phase0Idx = FS::phase0Idx;
83 static constexpr auto phase1Idx = FS::phase1Idx;
84 static constexpr auto sPhaseIdx = FS::numPhases;
85
87
88 using NumFluidPhasesArray = std::array<Scalar, ModelTraits::numFluidPhases()>;
89 using InterfacialAreasArray = std::array<std::array<Scalar, ModelTraits::numFluidPhases()+numEnergyEqSolid>,
90 ModelTraits::numFluidPhases()+numEnergyEqSolid>;
91
92public:
93 using FluidState = typename Traits::FluidState;
94 using Indices = typename ModelTraits::Indices;
103 template<class ElemSol, class Problem, class Element, class Scv>
104 void update(const ElemSol &elemSol,
105 const Problem &problem,
106 const Element &element,
107 const Scv& scv)
108 {
109 // Update parent type (also completes the fluid state)
110 ParentType::update(elemSol, problem, element, scv);
111
112 ParameterCache paramCache;
113 paramCache.updateAll(this->fluidState());
114 updateDimLessNumbers(elemSol, this->fluidState(), paramCache, problem, element, scv);
115 updateInterfacialArea(elemSol, this->fluidState(), paramCache, problem, element, scv);
116 }
117
128 template<class ElemSol, class Problem, class Element, class Scv>
129 void updateDimLessNumbers(const ElemSol& elemSol,
130 const FluidState& fluidState,
131 const ParameterCache& paramCache,
132 const Problem& problem,
133 const Element& element,
134 const Scv& scv)
135 {
136 factorEnergyTransfer_ = problem.spatialParams().factorEnergyTransfer(element, scv, elemSol);
137 characteristicLength_ = problem.spatialParams().characteristicLength(element, scv, elemSol);
138
139 // set the dimensionless numbers and obtain respective quantities
140 const unsigned int vIdxGlobal = scv.dofIndex();
141 for (int phaseIdx = 0; phaseIdx < ModelTraits::numFluidPhases(); ++phaseIdx)
142 {
143 const auto darcyMagVelocity = problem.gridVariables().volumeDarcyMagVelocity(phaseIdx, vIdxGlobal);
144 const auto dynamicViscosity = fluidState.viscosity(phaseIdx);
145 const auto density = fluidState.density(phaseIdx);
146 const auto kinematicViscosity = dynamicViscosity/density;
147
148 using FluidSystem = typename Traits::FluidSystem;
149 const auto heatCapacity = FluidSystem::heatCapacity(fluidState, paramCache, phaseIdx);
150 const auto thermalConductivity = FluidSystem::thermalConductivity(fluidState, paramCache, phaseIdx);
151 const auto porosity = this->porosity();
152
153 reynoldsNumber_[phaseIdx] = DimLessNum::reynoldsNumber(darcyMagVelocity, characteristicLength_,kinematicViscosity);
154 prandtlNumber_[phaseIdx] = DimLessNum::prandtlNumber(dynamicViscosity, heatCapacity, thermalConductivity);
155 nusseltNumber_[phaseIdx] = DimLessNum::nusseltNumberForced(reynoldsNumber_[phaseIdx],
156 prandtlNumber_[phaseIdx],
157 porosity,
158 ModelTraits::nusseltFormulation());
159
160 }
161 }
162
173 template<class ElemSol, class Problem, class Element, class Scv>
174 void updateInterfacialArea(const ElemSol& elemSol,
175 const FluidState& fluidState,
176 const ParameterCache& paramCache,
177 const Problem& problem,
178 const Element& element,
179 const Scv& scv)
180 {
181 const Scalar pc = fluidState.pressure(phase1Idx) - fluidState.pressure(phase0Idx);
182 const Scalar Sw = fluidState.saturation(phase0Idx);
183
184 // old material law interface is deprecated: Replace this by
185 // const auto& wettingNonwettingInterfacialArea = spatialParams.wettingNonwettingInterfacialArea(element, scv, elemSol);
186 // after the release of 3.3, when the deprecated interface is no longer supported
187 const auto fluidMatrixInteraction = Deprecated::makeInterfacialArea(Scalar{}, problem.spatialParams(), element, scv, elemSol);
188
189 const auto awn = fluidMatrixInteraction.wettingNonwettingInterface().area(Sw, pc);
190 interfacialArea_[phase0Idx][phase1Idx] = awn;
191 interfacialArea_[phase1Idx][phase0Idx] = interfacialArea_[phase0Idx][phase1Idx];
192 interfacialArea_[phase0Idx][phase0Idx] = 0.;
193
194 // old material law interface is deprecated: Replace this by
195 // const auto& nonwettingSolidInterfacialArea = spatialParams.nonwettingSolidInterfacialArea(element, scv, elemSol);
196 // after the release of 3.3, when the deprecated interface is no longer supported
197 const auto ans = fluidMatrixInteraction.nonwettingSolidInterface().area(Sw, pc);
198
199 // Switch for using a a_{wn} relations that has some "maximum capillary pressure" as parameter
200 // That value is obtained by regularization of the pc(Sw) function.
201 static const bool computeAwsFromAnsAndPcMax = getParam<bool>("SpatialParams.ComputeAwsFromAnsAndPcMax", true);
202 if (computeAwsFromAnsAndPcMax)
203 {
204 // I know the solid surface from the pore network. But it is more consistent to use the fit value.
205 const Scalar pcMax = fluidMatrixInteraction.wettingNonwettingInterface().basicParams().pcMax();
206 const auto solidSurface = fluidMatrixInteraction.nonwettingSolidInterface().area(/*Sw=*/0., pcMax);
207 interfacialArea_[phase0Idx][sPhaseIdx] = solidSurface - ans;
208 }
209 else
210 {
211 // old material law interface is deprecated: Replace this by
212 // const auto& wettingSolidInterfacialArea = spatialParams.wettingSolidInterfacialArea(element, scv, elemSol);
213 // after the release of 3.3, when the deprecated interface is no longer supported
214 const auto fluidMatrixInteraction = Deprecated::makeInterfacialArea(Scalar{}, problem.spatialParams(), element, scv, elemSol);
215 interfacialArea_[phase0Idx][sPhaseIdx] = fluidMatrixInteraction.wettingSolidInterface().area(Sw, pc);
216 }
217
218 interfacialArea_[sPhaseIdx][phase0Idx] = interfacialArea_[phase0Idx][sPhaseIdx];
219 interfacialArea_[sPhaseIdx][sPhaseIdx] = 0.;
220
221 interfacialArea_[phase1Idx][sPhaseIdx] = ans;
222 interfacialArea_[sPhaseIdx][phase1Idx] = interfacialArea_[phase1Idx][sPhaseIdx];
223 interfacialArea_[phase1Idx][phase1Idx] = 0.;
224 }
225
230 const Scalar interfacialArea(const unsigned int phaseIIdx, const unsigned int phaseJIdx) const
231 {
232 // there is no interfacial area between a phase and itself
233 assert(phaseIIdx not_eq phaseJIdx);
234 return interfacialArea_[phaseIIdx][phaseJIdx];
235 }
236
238 const Scalar reynoldsNumber(const unsigned int phaseIdx) const
239 { return reynoldsNumber_[phaseIdx]; }
240
242 const Scalar prandtlNumber(const unsigned int phaseIdx) const
243 { return prandtlNumber_[phaseIdx]; }
244
246 const Scalar nusseltNumber(const unsigned int phaseIdx) const
247 { return nusseltNumber_[phaseIdx]; }
248
250 const Scalar characteristicLength() const
251 { return characteristicLength_; }
252
254 const Scalar factorEnergyTransfer() const
255 { return factorEnergyTransfer_; }
256
257private:
259 NumFluidPhasesArray reynoldsNumber_;
260 NumFluidPhasesArray prandtlNumber_;
261 NumFluidPhasesArray nusseltNumber_;
262
263 Scalar characteristicLength_;
264 Scalar factorEnergyTransfer_;
265 InterfacialAreasArray interfacialArea_;
266};
267
269// specialization for the case of NO kinetic mass but kinetic energy transfer of a fluid mixture and a solid
271template<class Traits, class EquilibriumVolumeVariables>
273 EquilibriumVolumeVariables,
274 false/*chemicalNonEquilibrium?*/,
275 true/*thermalNonEquilibrium?*/,
276 1>
277: public EquilibriumVolumeVariables
278{
279 using ParentType = EquilibriumVolumeVariables;
280 using ParameterCache = typename Traits::FluidSystem::ParameterCache;
281 using Scalar = typename Traits::PrimaryVariables::value_type;
282
283 using ModelTraits = typename Traits::ModelTraits;
284 using FS = typename Traits::FluidSystem;
285 static constexpr auto numEnergyEqFluid = ModelTraits::numEnergyEqFluid();
286 static constexpr auto numEnergyEqSolid = ModelTraits::numEnergyEqSolid();
287
289
290 using NumFluidPhasesArray = std::array<Scalar, ModelTraits::numFluidPhases()>;
291
292public:
293 using Indices = typename ModelTraits::Indices;
294 using FluidState = typename Traits::FluidState;
295
305 template<class ElemSol, class Problem, class Element, class Scv>
306 void update(const ElemSol &elemSol,
307 const Problem &problem,
308 const Element &element,
309 const Scv& scv)
310 {
311 // Update parent type (also completes the fluid state)
312 ParentType::update(elemSol, problem, element, scv);
313
314 ParameterCache paramCache;
315 paramCache.updateAll(this->fluidState());
316 //only update of DimLessNumbers is necessary here, as interfacial area
317 // is easy due to only one fluid with a solid and is directly computed in localresidual
318 updateDimLessNumbers(elemSol, this->fluidState(), paramCache, problem, element, scv);
319 updateInterfacialArea(elemSol, this->fluidState(), paramCache, problem, element, scv);
320 }
321
332 template<class ElemSol, class Problem, class Element, class Scv>
333 void updateDimLessNumbers(const ElemSol& elemSol,
334 const FluidState& fluidState,
335 const ParameterCache& paramCache,
336 const Problem& problem,
337 const Element& element,
338 const Scv& scv)
339 {
340 factorEnergyTransfer_ = problem.spatialParams().factorEnergyTransfer(element, scv, elemSol);
341 characteristicLength_ = problem.spatialParams().characteristicLength(element, scv, elemSol);
342
343 // set the dimensionless numbers and obtain respective quantities
344 const unsigned int vIdxGlobal = scv.dofIndex();
345 for (int phaseIdx = 0; phaseIdx < ModelTraits::numFluidPhases(); ++phaseIdx)
346 {
347 const auto darcyMagVelocity = problem.gridVariables().volumeDarcyMagVelocity(phaseIdx, vIdxGlobal);
348 const auto dynamicViscosity = fluidState.viscosity(phaseIdx);
349 const auto density = fluidState.density(phaseIdx);
350 const auto kinematicViscosity = dynamicViscosity/density;
351
352 using FluidSystem = typename Traits::FluidSystem;
353 const auto heatCapacity = FluidSystem::heatCapacity(fluidState, paramCache, phaseIdx);
354 const auto thermalConductivity = FluidSystem::thermalConductivity(fluidState, paramCache, phaseIdx);
355 const auto porosity = this->porosity();
356
357 reynoldsNumber_[phaseIdx] = DimLessNum::reynoldsNumber(darcyMagVelocity, characteristicLength_,kinematicViscosity);
358 prandtlNumber_[phaseIdx] = DimLessNum::prandtlNumber(dynamicViscosity, heatCapacity, thermalConductivity);
359 nusseltNumber_[phaseIdx] = DimLessNum::nusseltNumberForced(reynoldsNumber_[phaseIdx],
360 prandtlNumber_[phaseIdx],
361 porosity,
362 ModelTraits::nusseltFormulation());
363 }
364 }
365
366
377 template<class ElemSol, class Problem, class Element, class Scv>
378 void updateInterfacialArea(const ElemSol& elemSol,
379 const FluidState& fluidState,
380 const ParameterCache& paramCache,
381 const Problem& problem,
382 const Element& element,
383 const Scv& scv)
384 {
385 using FluidSolidInterfacialAreaFormulation = typename Problem::SpatialParams::FluidSolidInterfacialAreaFormulation;
386 interfacialArea_ = FluidSolidInterfacialAreaFormulation::fluidSolidInterfacialArea(this->porosity(), characteristicLength());
387 }
388
390 const Scalar reynoldsNumber(const unsigned int phaseIdx) const
391 { return reynoldsNumber_[phaseIdx]; }
392
394 const Scalar prandtlNumber(const unsigned int phaseIdx) const
395 { return prandtlNumber_[phaseIdx]; }
396
398 const Scalar nusseltNumber(const unsigned int phaseIdx) const
399 { return nusseltNumber_[phaseIdx]; }
400
402 const Scalar characteristicLength() const
403 { return characteristicLength_; }
404
406 const Scalar factorEnergyTransfer() const
407 { return factorEnergyTransfer_; }
408
409 const Scalar fluidSolidInterfacialArea() const
410 {return interfacialArea_;}
411
412private:
414 NumFluidPhasesArray reynoldsNumber_;
415 NumFluidPhasesArray prandtlNumber_;
416 NumFluidPhasesArray nusseltNumber_;
417
418 Scalar characteristicLength_;
419 Scalar factorEnergyTransfer_;
420 Scalar interfacialArea_ ;
421};
422
424// specialization for the case of (only) kinetic mass transfer. Be careful, we do not test this!
426template<class Traits, class EquilibriumVolumeVariables>
428 EquilibriumVolumeVariables,
429 true/*chemicalNonEquilibrium?*/,
430 false/*thermalNonEquilibrium?*/,
431 0>
432: public EquilibriumVolumeVariables
433{
434 using ParentType = EquilibriumVolumeVariables;
435 using FluidState = typename Traits::FluidState;
436 using FS = typename Traits::FluidSystem;
437 using ParameterCache = typename Traits::FluidSystem::ParameterCache;
438 using Scalar = typename Traits::PrimaryVariables::value_type;
439
440 using ModelTraits = typename Traits::ModelTraits;
441
442 static constexpr auto phase0Idx = FS::phase0Idx;
443 static constexpr auto phase1Idx = FS::phase1Idx;
444 static constexpr auto wCompIdx = FS::comp0Idx;
445 static constexpr auto nCompIdx = FS::comp1Idx;
446
448
449 using NumFluidPhasesArray = std::array<Scalar, ModelTraits::numFluidPhases()>;
450
451public:
452 using Indices = typename ModelTraits::Indices;
462 template<class ElemSol, class Problem, class Element, class Scv>
463 void update(const ElemSol &elemSol,
464 const Problem &problem,
465 const Element &element,
466 const Scv& scv)
467 {
468 // Update parent type (also completes the fluid state)
469 ParentType::update(elemSol, problem, element, scv);
470
471 ParameterCache paramCache;
472 paramCache.updateAll(this->fluidState());
473 updateDimLessNumbers(elemSol, this->fluidState(), paramCache, problem, element, scv);
474 updateInterfacialArea(elemSol, this->fluidState(), paramCache, problem, element, scv);
475 }
476
487 template<class ElemSol, class Problem, class Element, class Scv>
488 void updateDimLessNumbers(const ElemSol& elemSol,
489 const FluidState& fluidState,
490 const ParameterCache& paramCache,
491 const Problem& problem,
492 const Element& element,
493 const Scv& scv)
494 {
495 factorMassTransfer_ = problem.spatialParams().factorMassTransfer(element, scv, elemSol);
496 characteristicLength_ = problem.spatialParams().characteristicLength(element, scv, elemSol);
497
498 // set the dimensionless numbers and obtain respective quantities.
499 const unsigned int vIdxGlobal = scv.dofIndex();
500 for (int phaseIdx = 0; phaseIdx < ModelTraits::numFluidPhases(); ++phaseIdx)
501 {
502 const auto darcyMagVelocity = problem.gridVariables().volumeDarcyMagVelocity(phaseIdx, vIdxGlobal);
503 const auto dynamicViscosity = fluidState.viscosity(phaseIdx);
504 const auto density = fluidState.density(phaseIdx);
505 const auto kinematicViscosity = dynamicViscosity/density;
506
507 // diffusion coefficient of nonwetting component in wetting phase
508 using FluidSystem = typename Traits::FluidSystem;
509 const auto diffCoeff = FluidSystem::binaryDiffusionCoefficient(fluidState,
510 paramCache,
511 phaseIdx,
512 wCompIdx,
513 nCompIdx);
514
515 reynoldsNumber_[phaseIdx] = DimLessNum::reynoldsNumber(darcyMagVelocity, characteristicLength_, kinematicViscosity);
516 schmidtNumber_[phaseIdx] = DimLessNum::schmidtNumber(dynamicViscosity, density, diffCoeff);
517 sherwoodNumber_[phaseIdx] = DimLessNum::sherwoodNumber(reynoldsNumber_[phaseIdx],
518 schmidtNumber_[phaseIdx],
519 ModelTraits::sherwoodFormulation());
520 }
521 }
522
533 template<class ElemSol, class Problem, class Element, class Scv>
534 void updateInterfacialArea(const ElemSol& elemSol,
535 const FluidState& fluidState,
536 const ParameterCache& paramCache,
537 const Problem& problem,
538 const Element& element,
539 const Scv& scv)
540 {
541 // obtain parameters for awnsurface and material law
542 // old material law interface is deprecated: Replace this by
543 // const auto fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol);
544 // after the release of 3.3, when the deprecated interface is no longer supported
545 const auto fluidMatrixInteraction = Deprecated::makeInterfacialArea(Scalar{}, problem.spatialParams(), element, scv, elemSol);
546
547 const auto Sw = fluidState.saturation(phase0Idx) ;
548 const auto pc = fluidState.pressure(phase1Idx) - fluidState.pressure(phase0Idx);
549
550 // when we only consider chemical non-equilibrium there is only mass transfer between
551 // the fluid phases, so in 2p only interfacial area between wetting and non-wetting
552 interfacialArea_ = fluidMatrixInteraction.wettingNonwettingInterface().area(Sw, pc);
553 }
554
558 const Scalar interfacialArea(const unsigned int phaseIIdx, const unsigned int phaseJIdx) const
559 {
560 // so far there is only a model for kinetic mass transfer between fluid phases
561 assert( (phaseIIdx == phase1Idx && phaseJIdx == phase0Idx)
562 || (phaseIIdx == phase0Idx && phaseJIdx == phase1Idx) );
563 return interfacialArea_;
564 }
565
567 const Scalar reynoldsNumber(const unsigned int phaseIdx) const
568 { return reynoldsNumber_[phaseIdx]; }
569
571 const Scalar schmidtNumber(const unsigned int phaseIdx) const
572 { return schmidtNumber_[phaseIdx]; }
573
575 const Scalar sherwoodNumber(const unsigned int phaseIdx) const
576 { return sherwoodNumber_[phaseIdx]; }
577
579 const Scalar characteristicLength() const
580 { return characteristicLength_; }
581
583 const Scalar factorMassTransfer() const
584 { return factorMassTransfer_; }
585
586private:
587 Scalar characteristicLength_;
588 Scalar factorMassTransfer_;
589 Scalar interfacialArea_ ;
590 NumFluidPhasesArray sherwoodNumber_;
591 NumFluidPhasesArray schmidtNumber_;
592 NumFluidPhasesArray reynoldsNumber_;
593};
594
595// Specialization where everything is in non-equilibrium.
596template<class Traits, class EquilibriumVolumeVariables>
598 EquilibriumVolumeVariables,
599 true/*chemicalNonEquilibrium?*/,
600 true/*thermalNonEquilibrium?*/,
601 2>
602: public EquilibriumVolumeVariables
603{
604 using ParentType = EquilibriumVolumeVariables;
605 using FluidState = typename Traits::FluidState;
606 using FS = typename Traits::FluidSystem;
607 using ParameterCache = typename Traits::FluidSystem::ParameterCache;
608 using Scalar = typename Traits::PrimaryVariables::value_type;
609
610 using ModelTraits = typename Traits::ModelTraits;
611 static constexpr auto numEnergyEqFluid = ModelTraits::numEnergyEqFluid();
612 static constexpr auto numEnergyEqSolid = ModelTraits::numEnergyEqSolid();
613
614 static constexpr auto phase0Idx = FS::phase0Idx;
615 static constexpr auto phase1Idx = FS::phase1Idx;
616 static constexpr auto sPhaseIdx = FS::numPhases;
617 static constexpr auto wCompIdx = FS::comp0Idx;
618 static constexpr auto nCompIdx = FS::comp1Idx;
619
621 static_assert((numEnergyEqFluid > 1), "This model only deals with energy transfer between two fluids and one solid phase");
622
623 using NumFluidPhasesArray = std::array<Scalar, ModelTraits::numFluidPhases()>;
624 using InterfacialAreasArray = std::array<std::array<Scalar, ModelTraits::numFluidPhases()+numEnergyEqSolid>,
625 ModelTraits::numFluidPhases()+numEnergyEqSolid>;
626
627public:
628 using Indices = typename ModelTraits::Indices;
629
639 template<class ElemSol, class Problem, class Element, class Scv>
640 void update(const ElemSol &elemSol,
641 const Problem &problem,
642 const Element &element,
643 const Scv& scv)
644 {
645 // Update parent type (also completes the fluid state)
646 ParentType::update(elemSol, problem, element, scv);
647
648 ParameterCache paramCache;
649 paramCache.updateAll(this->fluidState());
650 updateDimLessNumbers(elemSol, this->fluidState(), paramCache, problem, element, scv);
651 updateInterfacialArea(elemSol, this->fluidState(), paramCache, problem, element, scv);
652 }
653
664 template<class ElemSol, class Problem, class Element, class Scv>
665 void updateDimLessNumbers(const ElemSol& elemSol,
666 const FluidState& fluidState,
667 const ParameterCache& paramCache,
668 const Problem& problem,
669 const Element& element,
670 const Scv& scv)
671 {
672 factorMassTransfer_ = problem.spatialParams().factorMassTransfer(element, scv, elemSol);
673 factorEnergyTransfer_ = problem.spatialParams().factorEnergyTransfer(element, scv, elemSol);
674 characteristicLength_ = problem.spatialParams().characteristicLength(element, scv, elemSol);
675
676 const auto vIdxGlobal = scv.dofIndex();
677 using FluidSystem = typename Traits::FluidSystem;
678 for (int phaseIdx = 0; phaseIdx < ModelTraits::numFluidPhases(); ++phaseIdx)
679 {
680 const auto darcyMagVelocity = problem.gridVariables().volumeDarcyMagVelocity(phaseIdx, vIdxGlobal);
681 const auto dynamicViscosity = fluidState.viscosity(phaseIdx);
682 const auto density = fluidState.density(phaseIdx);
683 const auto kinematicViscosity = dynamicViscosity/density;
684 const auto heatCapacity = FluidSystem::heatCapacity(fluidState, paramCache, phaseIdx);
685 const auto thermalConductivity = FluidSystem::thermalConductivity(fluidState, paramCache, phaseIdx);
686
687 // diffusion coefficient of nonwetting component in wetting phase
688 const auto porosity = this->porosity();
689 const auto diffCoeff = FluidSystem::binaryDiffusionCoefficient(fluidState,
690 paramCache,
691 phaseIdx,
692 wCompIdx,
693 nCompIdx);
694
695 reynoldsNumber_[phaseIdx] = DimLessNum::reynoldsNumber(darcyMagVelocity, characteristicLength_, kinematicViscosity);
696 prandtlNumber_[phaseIdx] = DimLessNum::prandtlNumber(dynamicViscosity, heatCapacity, thermalConductivity);
697 schmidtNumber_[phaseIdx] = DimLessNum::schmidtNumber(dynamicViscosity, density, diffCoeff);
698 nusseltNumber_[phaseIdx] = DimLessNum::nusseltNumberForced(reynoldsNumber_[phaseIdx],
699 prandtlNumber_[phaseIdx],
700 porosity,
701 ModelTraits::nusseltFormulation());
702 // If Diffusion is not enabled, Sherwood is divided by zero
703 sherwoodNumber_[phaseIdx] = DimLessNum::sherwoodNumber(reynoldsNumber_[phaseIdx],
704 schmidtNumber_[phaseIdx],
705 ModelTraits::sherwoodFormulation());
706 }
707 }
708
719 template<class ElemSol, class Problem, class Element, class Scv>
720 void updateInterfacialArea(const ElemSol& elemSol,
721 const FluidState& fluidState,
722 const ParameterCache& paramCache,
723 const Problem& problem,
724 const Element& element,
725 const Scv& scv)
726 {
727 const Scalar pc = fluidState.pressure(phase1Idx) - fluidState.pressure(phase0Idx);
728 const Scalar Sw = fluidState.saturation(phase0Idx);
729
730 // old material law interface is deprecated: Replace this by
731 // const auto fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol);
732 // after the release of 3.3, when the deprecated interface is no longer supported
733 const auto fluidMatrixInteraction = Deprecated::makeInterfacialArea(Scalar{}, problem.spatialParams(), element, scv, elemSol);
734
735 const auto awn = fluidMatrixInteraction.wettingNonwettingInterface().area(Sw, pc);
736 interfacialArea_[phase0Idx][phase1Idx] = awn;
737 interfacialArea_[phase1Idx][phase0Idx] = interfacialArea_[phase0Idx][phase1Idx];
738 interfacialArea_[phase0Idx][phase0Idx] = 0.;
739
740 const auto ans = fluidMatrixInteraction.nonwettingSolidInterface().area(Sw, pc);
741
742 // Switch for using a a_{wn} relations that has some "maximum capillary pressure" as parameter.
743 // That value is obtained by regularization of the pc(Sw) function.
744 static const bool computeAwsFromAnsAndPcMax = getParam<bool>("SpatialParams.ComputeAwsFromAnsAndPcMax", true);
745 if (computeAwsFromAnsAndPcMax)
746 {
747 // I know the solid surface from the pore network. But it is more consistent to use the fit value.
748 const Scalar pcMax = fluidMatrixInteraction.wettingNonwettingInterface().basicParams().pcMax();
749 const auto solidSurface = fluidMatrixInteraction.nonwettingSolidInterface().area(/*Sw=*/0., pcMax);
750 interfacialArea_[phase0Idx][sPhaseIdx] = solidSurface - ans;
751 }
752 else
753 interfacialArea_[phase0Idx][sPhaseIdx] = fluidMatrixInteraction.wettingSolidInterface().area(Sw, pc);
754
755 interfacialArea_[sPhaseIdx][phase0Idx] = interfacialArea_[phase0Idx][sPhaseIdx];
756 interfacialArea_[sPhaseIdx][sPhaseIdx] = 0.;
757
758 interfacialArea_[phase1Idx][sPhaseIdx] = ans;
759 interfacialArea_[sPhaseIdx][phase1Idx] = interfacialArea_[phase1Idx][sPhaseIdx];
760 interfacialArea_[phase1Idx][phase1Idx] = 0.;
761 }
762
767 const Scalar interfacialArea(const unsigned int phaseIIdx, const unsigned int phaseJIdx) const
768 {
769 // there is no interfacial area between a phase and itself
770 assert(phaseIIdx not_eq phaseJIdx);
771 return interfacialArea_[phaseIIdx][phaseJIdx];
772 }
773
775 const Scalar reynoldsNumber(const unsigned int phaseIdx) const
776 { return reynoldsNumber_[phaseIdx]; }
777
779 const Scalar prandtlNumber(const unsigned int phaseIdx) const
780 { return prandtlNumber_[phaseIdx]; }
781
783 const Scalar nusseltNumber(const unsigned int phaseIdx) const
784 { return nusseltNumber_[phaseIdx]; }
785
787 const Scalar schmidtNumber(const unsigned int phaseIdx) const
788 { return schmidtNumber_[phaseIdx]; }
789
791 const Scalar sherwoodNumber(const unsigned int phaseIdx) const
792 { return sherwoodNumber_[phaseIdx]; }
793
795 const Scalar characteristicLength() const
796 { return characteristicLength_; }
797
799 const Scalar factorEnergyTransfer() const
800 { return factorEnergyTransfer_; }
801
803 const Scalar factorMassTransfer() const
804 { return factorMassTransfer_; }
805
806private:
808 NumFluidPhasesArray reynoldsNumber_;
809 NumFluidPhasesArray prandtlNumber_;
810 NumFluidPhasesArray nusseltNumber_;
811 NumFluidPhasesArray schmidtNumber_;
812 NumFluidPhasesArray sherwoodNumber_;
813 Scalar characteristicLength_;
814 Scalar factorEnergyTransfer_;
815 Scalar factorMassTransfer_;
816 InterfacialAreasArray interfacialArea_;
817};
818
819} // namespace Dumux
820
821#endif
Helpers for deprecation.
Collection of functions, calculating dimensionless numbers.
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
Definition: adapt.hh:29
std::string density(int phaseIdx) noexcept
I/O name of density for multiphase systems.
Definition: name.hh:65
std::string porosity() noexcept
I/O name of porosity.
Definition: name.hh:139
Collection of functions which calculate dimensionless numbers. Each number has it's own function....
Definition: dimensionlessnumbers.hh:65
This class contains the volume variables required for the modules which require the specific interfac...
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:51
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:174
const Scalar factorEnergyTransfer() const
access function pre factor energy transfer
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:254
const Scalar prandtlNumber(const unsigned int phaseIdx) const
access function Prandtl Number
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:242
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:230
typename ModelTraits::Indices Indices
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:94
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:104
const Scalar reynoldsNumber(const unsigned int phaseIdx) const
access function Reynolds Number
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:238
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:129
const Scalar nusseltNumber(const unsigned int phaseIdx) const
access function Nusselt Number
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:246
const Scalar characteristicLength() const
access function characteristic length
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:250
typename Traits::FluidState FluidState
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:93
typename ModelTraits::Indices Indices
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:293
const Scalar fluidSolidInterfacialArea() const
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:409
const Scalar characteristicLength() const
access function characteristic length
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:402
const Scalar reynoldsNumber(const unsigned int phaseIdx) const
access function Reynolds Number
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:390
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:333
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:378
const Scalar nusseltNumber(const unsigned int phaseIdx) const
access function Nusselt Number
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:398
const Scalar prandtlNumber(const unsigned int phaseIdx) const
access function Prandtl Number
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:394
typename Traits::FluidState FluidState
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:294
const Scalar factorEnergyTransfer() const
access function pre factor energy transfer
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:406
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:306
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:463
const Scalar reynoldsNumber(const unsigned int phaseIdx) const
access function Reynolds Number
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:567
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:488
typename ModelTraits::Indices Indices
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:452
const Scalar characteristicLength() const
access function characteristic length
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:579
const Scalar sherwoodNumber(const unsigned int phaseIdx) const
access function Sherwood Number
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:575
const Scalar factorMassTransfer() const
access function pre factor mass transfer
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:583
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:558
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:534
const Scalar schmidtNumber(const unsigned int phaseIdx) const
access function Schmidt Number
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:571
const Scalar characteristicLength() const
access function characteristic length
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:795
const Scalar sherwoodNumber(const unsigned int phaseIdx) const
access function Sherwood Number
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:791
typename ModelTraits::Indices Indices
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:628
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:640
const Scalar factorMassTransfer() const
access function pre factor mass transfer
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:803
const Scalar factorEnergyTransfer() const
access function pre factor energy transfer
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:799
const Scalar schmidtNumber(const unsigned int phaseIdx) const
access function Schmidt Number
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:787
const Scalar nusseltNumber(const unsigned int phaseIdx) const
access function Nusselt Number
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:783
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:767
const Scalar prandtlNumber(const unsigned int phaseIdx) const
access function Prandtl Number
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:779
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:665
const Scalar reynoldsNumber(const unsigned int phaseIdx) const
access function Reynolds Number
Definition: porousmediumflow/nonequilibrium/volumevariables.hh:775
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:720