57 using GridView =
typename GridGeometry::GridView;
58 using FVElementGeometry =
typename GridGeometry::LocalView;
59 using SubControlVolume =
typename GridGeometry::SubControlVolume;
60 using SubControlVolumeFace =
typename GridGeometry::SubControlVolumeFace;
63 using Element =
typename GridView::template Codim<0>::Entity;
65 static constexpr bool advectionEnabled = ModelTraits::enableAdvection();
66 static constexpr bool diffusionEnabled = ModelTraits::enableMolecularDiffusion();
67 static constexpr bool heatConductionEnabled = ModelTraits::enableEnergyBalance();
75 static constexpr bool isSolDependent = (advectionEnabled && advectionIsSolDependent) ||
76 (diffusionEnabled && diffusionIsSolDependent) ||
77 (heatConductionEnabled && heatConductionIsSolDependent);
81 : problemPtr_(&problem) {}
94 template<
class FluxVariablesCacheContainer,
class FluxVariablesCache>
95 void fill(FluxVariablesCacheContainer& fluxVarsCacheContainer,
96 FluxVariablesCache& scvfFluxVarsCache,
97 const Element& element,
98 const FVElementGeometry& fvGeometry,
99 const ElementVolumeVariables& elemVolVars,
100 const SubControlVolumeFace& scvf,
101 bool forceUpdateAll =
false)
106 if constexpr (advectionEnabled)
107 fillAdvection_(scvfFluxVarsCache, element, fvGeometry, elemVolVars, scvf);
108 if constexpr (diffusionEnabled)
109 fillDiffusion_(scvfFluxVarsCache, element, fvGeometry, elemVolVars, scvf);
110 if constexpr (heatConductionEnabled)
111 fillHeatConduction_(scvfFluxVarsCache, element, fvGeometry, elemVolVars, scvf);
115 if constexpr (advectionEnabled && advectionIsSolDependent)
116 fillAdvection_(scvfFluxVarsCache, element, fvGeometry, elemVolVars, scvf);
117 if constexpr (diffusionEnabled && diffusionIsSolDependent)
118 fillDiffusion_(scvfFluxVarsCache, element, fvGeometry, elemVolVars, scvf);
119 if constexpr (heatConductionEnabled && heatConductionIsSolDependent)
120 fillHeatConduction_(scvfFluxVarsCache, element, fvGeometry, elemVolVars, scvf);
126 const Problem& problem()
const
127 {
return *problemPtr_; }
130 template<
class FluxVariablesCache>
131 void fillAdvection_(FluxVariablesCache& scvfFluxVarsCache,
132 const Element& element,
133 const FVElementGeometry& fvGeometry,
134 const ElementVolumeVariables& elemVolVars,
135 const SubControlVolumeFace& scvf)
137 using AdvectionType = GetPropType<TypeTag, Properties::AdvectionType>;
138 using AdvectionFiller =
typename AdvectionType::Cache::Filler;
141 AdvectionFiller::fill(scvfFluxVarsCache, problem(), element, fvGeometry, elemVolVars, scvf, *
this);
145 template<
class FluxVariablesCache>
146 void fillDiffusion_(FluxVariablesCache& scvfFluxVarsCache,
147 const Element& element,
148 const FVElementGeometry& fvGeometry,
149 const ElementVolumeVariables& elemVolVars,
150 const SubControlVolumeFace& scvf)
153 using DiffusionFiller =
typename DiffusionType::Cache::Filler;
156 static constexpr int numPhases = ModelTraits::numFluidPhases();
157 static constexpr int numComponents = ModelTraits::numFluidComponents();
160 if constexpr (FluidSystem::isTracerFluidSystem())
161 for (
unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
162 for (
unsigned int compIdx = 0; compIdx < numComponents; ++compIdx)
163 DiffusionFiller::fill(scvfFluxVarsCache, phaseIdx, compIdx, problem(), element, fvGeometry, elemVolVars, scvf, *
this);
165 for (
unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
166 for (
unsigned int compIdx = 0; compIdx < numComponents; ++compIdx)
167 if (compIdx != FluidSystem::getMainComponent(phaseIdx))
168 DiffusionFiller::fill(scvfFluxVarsCache, phaseIdx, compIdx, problem(), element, fvGeometry, elemVolVars, scvf, *
this);
172 template<
class FluxVariablesCache>
173 void fillHeatConduction_(FluxVariablesCache& scvfFluxVarsCache,
174 const Element& element,
175 const FVElementGeometry& fvGeometry,
176 const ElementVolumeVariables& elemVolVars,
177 const SubControlVolumeFace& scvf)
180 using HeatConductionFiller =
typename HeatConductionType::Cache::Filler;
183 HeatConductionFiller::fill(scvfFluxVarsCache, problem(), element, fvGeometry, elemVolVars, scvf, *
this);
186 const Problem* problemPtr_;
196 using Element =
typename GridView::template Codim<0>::Entity;
199 using FVElementGeometry =
typename GridGeometry::LocalView;
200 using MpfaHelper =
typename GridGeometry::MpfaHelper;
201 using SubControlVolumeFace =
typename GridGeometry::SubControlVolumeFace;
207 using PrimaryDataHandle =
typename ElementFluxVariablesCache::PrimaryIvDataHandle;
208 using PrimaryLocalFaceData =
typename PrimaryInteractionVolume::Traits::LocalFaceData;
210 using SecondaryDataHandle =
typename ElementFluxVariablesCache::SecondaryIvDataHandle;
211 using SecondaryLocalFaceData =
typename SecondaryInteractionVolume::Traits::LocalFaceData;
213 static constexpr int dim = GridView::dimension;
214 static constexpr int dimWorld = GridView::dimensionworld;
216 static constexpr bool advectionEnabled = ModelTraits::enableAdvection();
217 static constexpr bool diffusionEnabled = ModelTraits::enableMolecularDiffusion();
218 static constexpr bool heatConductionEnabled = ModelTraits::enableEnergyBalance();
232 : problemPtr_(&problem) {}
246 template<
class FluxVarsCacheStorage,
class FluxVariablesCache,
class IVDataStorage>
247 void fill(FluxVarsCacheStorage& fluxVarsCacheStorage,
248 FluxVariablesCache& scvfFluxVarsCache,
249 IVDataStorage& ivDataStorage,
250 const Element& element,
251 const FVElementGeometry& fvGeometry,
252 const ElementVolumeVariables& elemVolVars,
253 const SubControlVolumeFace& scvf,
254 bool forceUpdateAll =
false)
257 elementPtr_ = &element;
258 fvGeometryPtr_ = &fvGeometry;
259 elemVolVarsPtr_ = &elemVolVars;
260 const auto& gridGeometry = fvGeometry.gridGeometry();
265 if (gridGeometry.vertexUsesSecondaryInteractionVolume(scvf.vertexIndex()))
270 const auto ivIndexInContainer = ivDataStorage.secondaryInteractionVolumes.size();
271 const auto& indexSet = gridGeometry.gridInteractionVolumeIndexSets().secondaryIndexSet(scvf);
272 ivDataStorage.secondaryInteractionVolumes.emplace_back();
273 secondaryIv_ = &ivDataStorage.secondaryInteractionVolumes.back();
274 secondaryIv_->bind(indexSet, problem(), fvGeometry);
277 ivDataStorage.secondaryDataHandles.emplace_back();
278 secondaryIvDataHandle_ = &ivDataStorage.secondaryDataHandles.back();
279 prepareDataHandle_(*secondaryIv_, *secondaryIvDataHandle_, forceUpdateAll);
282 fillCachesInInteractionVolume_<FluxVariablesCache>(fluxVarsCacheStorage, *secondaryIv_, ivIndexInContainer);
287 const auto ivIndexInContainer = scvfFluxVarsCache.ivIndexInContainer();
288 secondaryIv_ = &ivDataStorage.secondaryInteractionVolumes[ivIndexInContainer];
289 secondaryIvDataHandle_ = &ivDataStorage.secondaryDataHandles[ivIndexInContainer];
290 prepareDataHandle_(*secondaryIv_, *secondaryIvDataHandle_, forceUpdateAll);
293 fillCachesInInteractionVolume_<FluxVariablesCache>(fluxVarsCacheStorage, *secondaryIv_, ivIndexInContainer);
303 const auto ivIndexInContainer = ivDataStorage.primaryInteractionVolumes.size();
304 const auto& indexSet = gridGeometry.gridInteractionVolumeIndexSets().primaryIndexSet(scvf);
305 ivDataStorage.primaryInteractionVolumes.emplace_back();
306 primaryIv_ = &ivDataStorage.primaryInteractionVolumes.back();
307 primaryIv_->bind(indexSet, problem(), fvGeometry);
310 ivDataStorage.primaryDataHandles.emplace_back();
311 primaryIvDataHandle_ = &ivDataStorage.primaryDataHandles.back();
312 prepareDataHandle_(*primaryIv_, *primaryIvDataHandle_, forceUpdateAll);
315 fillCachesInInteractionVolume_<FluxVariablesCache>(fluxVarsCacheStorage, *primaryIv_, ivIndexInContainer);
320 const auto ivIndexInContainer = scvfFluxVarsCache.ivIndexInContainer();
321 primaryIv_ = &ivDataStorage.primaryInteractionVolumes[ivIndexInContainer];
322 primaryIvDataHandle_ = &ivDataStorage.primaryDataHandles[ivIndexInContainer];
323 prepareDataHandle_(*primaryIv_, *primaryIvDataHandle_, forceUpdateAll);
326 fillCachesInInteractionVolume_<FluxVariablesCache>(fluxVarsCacheStorage, *primaryIv_, ivIndexInContainer);
333 {
return *primaryIv_; }
337 {
return *secondaryIv_; }
341 {
return *primaryIvDataHandle_; }
345 {
return *secondaryIvDataHandle_; }
349 {
return *primaryLocalFaceData_; }
353 {
return *secondaryLocalFaceData_; }
357 const Problem& problem()
const {
return *problemPtr_; }
358 const Element& element()
const {
return *elementPtr_; }
359 const FVElementGeometry& fvGeometry()
const {
return *fvGeometryPtr_; }
360 const ElementVolumeVariables& elemVolVars()
const {
return *elemVolVarsPtr_; }
363 template<
class FluxVariablesCache,
class FluxVarsCacheStorage,
class InteractionVolume>
364 void fillCachesInInteractionVolume_(FluxVarsCacheStorage& fluxVarsCacheStorage,
365 InteractionVolume& iv,
366 unsigned int ivIndexInContainer)
369 static constexpr bool isSecondary = MpfaHelper::considerSecondaryIVs()
370 && std::is_same_v<InteractionVolume, SecondaryInteractionVolume>;
375 const auto numGlobalScvfs = iv.localFaceData().size();
376 std::vector<const SubControlVolumeFace*> ivScvfs(numGlobalScvfs);
377 std::vector<FluxVariablesCache*> ivFluxVarCaches(numGlobalScvfs);
380 for (
const auto& d : iv.localFaceData())
383 const auto& scvfJ = fvGeometry().scvf(d.gridScvfIndex());
385 ivFluxVarCaches[i] = &fluxVarsCacheStorage[scvfJ];
386 ivFluxVarCaches[i]->setIvIndexInContainer(ivIndexInContainer);
387 ivFluxVarCaches[i]->setUpdateStatus(
true);
388 ivFluxVarCaches[i]->setSecondaryIvUsage(isSecondary);
389 ivFluxVarCaches[i]->setIvLocalFaceIndex(d.ivLocalScvfIndex());
391 if (d.isOutsideFace())
392 ivFluxVarCaches[i]->setIndexInOutsideFaces(d.scvfLocalOutsideScvfIndex());
396 if constexpr (advectionEnabled)
397 fillAdvection_(iv, ivScvfs, ivFluxVarCaches);
398 if constexpr (diffusionEnabled)
399 fillDiffusion_(iv, ivScvfs, ivFluxVarCaches);
400 if constexpr (heatConductionEnabled)
401 fillHeatConduction_(iv, ivScvfs, ivFluxVarCaches);
405 template<
class InteractionVolume,
class FluxVariablesCache>
406 void fillAdvection_(InteractionVolume& iv,
407 const std::vector<const SubControlVolumeFace*>& ivScvfs,
408 const std::vector<FluxVariablesCache*>& ivFluxVarCaches)
411 using AdvectionFiller =
typename AdvectionType::Cache::Filler;
414 for (
unsigned int i = 0; i < iv.localFaceData().size(); ++i)
418 if (std::is_same_v<PrimaryInteractionVolume, SecondaryInteractionVolume>)
421 primaryLocalFaceData_ = &(iv.localFaceData()[i]);
422 secondaryLocalFaceData_ = &(iv.localFaceData()[i]);
424 else if (std::is_same_v<InteractionVolume, PrimaryInteractionVolume>)
425 primaryLocalFaceData_ = &(iv.localFaceData()[i]);
427 secondaryLocalFaceData_ = &(iv.localFaceData()[i]);
430 AdvectionFiller::fill(*ivFluxVarCaches[i],
432 iv.element(iv.localFaceData()[i].ivLocalInsideScvIndex()),
441 template<
class InteractionVolume,
class FluxVariablesCache>
442 void fillDiffusion_(InteractionVolume& iv,
443 const std::vector<const SubControlVolumeFace*>& ivScvfs,
444 const std::vector<FluxVariablesCache*>& ivFluxVarCaches)
447 using DiffusionFiller =
typename DiffusionType::Cache::Filler;
449 static constexpr int numPhases = ModelTraits::numFluidPhases();
450 static constexpr int numComponents = ModelTraits::numFluidComponents();
452 for (
unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
454 for (
unsigned int compIdx = 0; compIdx < numComponents; ++compIdx)
457 if constexpr (!FluidSystem::isTracerFluidSystem())
458 if (compIdx == FluidSystem::getMainComponent(phaseIdx))
462 for (
unsigned int i = 0; i < iv.localFaceData().size(); ++i)
466 if constexpr (std::is_same_v<PrimaryInteractionVolume, SecondaryInteractionVolume>)
469 primaryLocalFaceData_ = &(iv.localFaceData()[i]);
470 secondaryLocalFaceData_ = &(iv.localFaceData()[i]);
472 else if constexpr (std::is_same_v<InteractionVolume, PrimaryInteractionVolume>)
473 primaryLocalFaceData_ = &(iv.localFaceData()[i]);
475 secondaryLocalFaceData_ = &(iv.localFaceData()[i]);
478 DiffusionFiller::fill(*ivFluxVarCaches[i],
482 iv.element(iv.localFaceData()[i].ivLocalInsideScvIndex()),
493 template<
class InteractionVolume,
class FluxVariablesCache>
494 void fillHeatConduction_(InteractionVolume& iv,
495 const std::vector<const SubControlVolumeFace*>& ivScvfs,
496 const std::vector<FluxVariablesCache*>& ivFluxVarCaches)
499 using HeatConductionFiller =
typename HeatConductionType::Cache::Filler;
502 for (
unsigned int i = 0; i < iv.localFaceData().size(); ++i)
506 if constexpr (std::is_same_v<PrimaryInteractionVolume, SecondaryInteractionVolume>)
509 primaryLocalFaceData_ = &(iv.localFaceData()[i]);
510 secondaryLocalFaceData_ = &(iv.localFaceData()[i]);
512 else if constexpr (std::is_same_v<InteractionVolume, PrimaryInteractionVolume>)
513 primaryLocalFaceData_ = &(iv.localFaceData()[i]);
515 secondaryLocalFaceData_ = &(iv.localFaceData()[i]);
518 HeatConductionFiller::fill(*ivFluxVarCaches[i],
520 iv.element(iv.localFaceData()[i].ivLocalInsideScvIndex()),
529 template<
class InteractionVolume,
class DataHandle>
530 void prepareDataHandle_([[maybe_unused]] InteractionVolume& iv, [[maybe_unused]] DataHandle& handle, [[maybe_unused]]
bool forceUpdate)
533 if constexpr (advectionEnabled)
537 prepareAdvectionHandle_(iv, handle, forceUpdate);
541 if constexpr (diffusionEnabled)
545 prepareDiffusionHandles_(iv, handle, forceUpdate);
549 if constexpr (heatConductionEnabled)
553 prepareHeatConductionHandle_(iv, handle, forceUpdate);
558 template<
class InteractionVolume,
class DataHandle>
559 void prepareAdvectionHandle_(InteractionVolume& iv, DataHandle& handle,
bool forceUpdateAll)
562 using Traits =
typename InteractionVolume::Traits;
563 using IvLocalAssembler =
typename Traits::template LocalAssembler<Problem, FVElementGeometry, ElementVolumeVariables>;
564 IvLocalAssembler localAssembler(problem(), fvGeometry(), elemVolVars());
567 auto getK = [] (
const auto& volVars) {
return volVars.permeability(); };
570 if (forceUpdateAll || advectionIsSolDependent)
571 localAssembler.assembleMatrices(handle.advectionHandle(), iv, getK);
574 for (
unsigned int pIdx = 0; pIdx < ModelTraits::numFluidPhases(); ++pIdx)
577 handle.advectionHandle().setPhaseIndex(pIdx);
580 auto getRho = [pIdx] (
const auto& volVars) {
return volVars.density(pIdx); };
583 localAssembler.assembleGravity(handle.advectionHandle(), iv, getRho);
586 auto getPressure = [pIdx] (
const auto& volVars) {
return volVars.pressure(pIdx); };
587 localAssembler.assembleU(handle.advectionHandle(), iv, getPressure);
592 template<
class InteractionVolume,
class DataHandle>
593 void prepareDiffusionHandles_(InteractionVolume& iv,
597 for (
unsigned int phaseIdx = 0; phaseIdx < ModelTraits::numFluidPhases(); ++phaseIdx)
599 for (
unsigned int compIdx = 0; compIdx < ModelTraits::numFluidComponents(); ++compIdx)
603 if constexpr (!FluidSystem::isTracerFluidSystem())
604 if (compIdx == FluidSystem::getMainComponent(phaseIdx))
608 handle.diffusionHandle().setPhaseIndex(phaseIdx);
609 handle.diffusionHandle().setComponentIndex(compIdx);
614 using Traits =
typename InteractionVolume::Traits;
615 using IvLocalAssembler =
typename Traits::template LocalAssembler<Problem, FVElementGeometry, ElementVolumeVariables>;
616 IvLocalAssembler localAssembler(problem(), fvGeometry(), elemVolVars());
619 if (forceUpdateAll || diffusionIsSolDependent)
622 const auto getD = [&](
const auto& volVars)
624 if constexpr (FluidSystem::isTracerFluidSystem())
625 return volVars.effectiveDiffusionCoefficient(0, 0, compIdx);
627 return volVars.effectiveDiffusionCoefficient(phaseIdx, FluidSystem::getMainComponent(phaseIdx), compIdx);
632 const auto& scv = *scvs(fvGeometry()).begin();
633 const auto& scvf = *scvfs(fvGeometry()).begin();
634 const auto& vv = elemVolVars()[scv];
635 const auto D = [&] ()
639 if constexpr (!FluidSystem::isTracerFluidSystem())
640 return max(1e-20, vv.diffusionCoefficient(phaseIdx, FluidSystem::getMainComponent(phaseIdx), compIdx));
642 return max(1e-20, vv.diffusionCoefficient(0, 0, compIdx));
646 localAssembler.assembleMatrices(handle.diffusionHandle(), iv, getD, eps);
650 auto getMassOrMoleFraction = [phaseIdx, compIdx] (
const auto& volVars)
653 volVars.moleFraction(phaseIdx, compIdx);
656 localAssembler.assembleU(handle.diffusionHandle(), iv, getMassOrMoleFraction);
662 template<
class InteractionVolume,
class DataHandle>
663 void prepareHeatConductionHandle_(InteractionVolume& iv, DataHandle& handle,
bool forceUpdateAll)
666 using Traits =
typename InteractionVolume::Traits;
667 using IvLocalAssembler =
typename Traits::template LocalAssembler<Problem, FVElementGeometry, ElementVolumeVariables>;
668 IvLocalAssembler localAssembler(problem(), fvGeometry(), elemVolVars());
671 auto getLambda = [] (
const auto& volVars) {
return volVars.effectiveThermalConductivity(); };
674 if (forceUpdateAll || heatConductionIsSolDependent)
675 localAssembler.assembleMatrices(handle.heatConductionHandle(), iv, getLambda);
678 auto getTemperature = [] (
const auto& volVars) {
return volVars.temperature(); };
679 localAssembler.assembleU(handle.heatConductionHandle(), iv, getTemperature);
682 const Problem* problemPtr_;
683 const Element* elementPtr_;
684 const FVElementGeometry* fvGeometryPtr_;
685 const ElementVolumeVariables* elemVolVarsPtr_;
690 PrimaryInteractionVolume* primaryIv_;
691 SecondaryInteractionVolume* secondaryIv_;
694 PrimaryDataHandle* primaryIvDataHandle_;
695 SecondaryDataHandle* secondaryIvDataHandle_;
701 const PrimaryLocalFaceData* primaryLocalFaceData_;
702 const SecondaryLocalFaceData* secondaryLocalFaceData_;