28 #ifndef EWOMS_FV_BASE_DISCRETIZATION_HH 29 #define EWOMS_FV_BASE_DISCRETIZATION_HH 31 #include <dune/common/fmatrix.hh> 32 #include <dune/common/fvector.hh> 33 #include <dune/common/version.hh> 34 #include <dune/istl/bvector.hh> 36 #include <opm/material/common/MathToolbox.hpp> 37 #include <opm/material/common/Valgrind.hpp> 38 #include <opm/material/densead/Math.hpp> 77 #include <type_traits> 83 template<
class TypeTag>
86 template<
class TypeTag>
94 template<
class TypeTag>
99 template<
class TypeTag>
101 {
using type = Dune::MultipleCodimMultipleGeomTypeMapper<GetPropType<TypeTag, Properties::GridView>>; };
104 template<
class TypeTag>
106 {
using type = Dune::MultipleCodimMultipleGeomTypeMapper<GetPropType<TypeTag, Properties::GridView>>; };
109 template<
class TypeTag>
119 template<
class TypeTag>
123 template<
class TypeTag>
127 template<
class TypeTag>
132 template<
class TypeTag>
139 template<
class TypeTag>
142 using type = Dune::FieldVector<GetPropType<TypeTag, Properties::Scalar>,
143 getPropValue<TypeTag, Properties::NumEq>()>;
151 template<
class TypeTag>
158 template<
class TypeTag>
165 template<
class TypeTag>
172 template<
class TypeTag>
174 {
using type = Dune::BlockVector<GetPropType<TypeTag, Properties::EqVector>>; };
179 template<
class TypeTag>
181 {
using type = Dune::BlockVector<GetPropType<TypeTag, Properties::EqVector>>; };
186 template<
class TypeTag>
193 template<
class TypeTag>
195 {
using type = Dune::BlockVector<GetPropType<TypeTag, Properties::PrimaryVariables>>; };
202 template<
class TypeTag>
209 template<
class TypeTag>
213 template<
class TypeTag>
217 template<
class TypeTag>
224 template<
class TypeTag>
228 template<
class TypeTag>
230 {
static constexpr
bool value =
true; };
235 template<
class TypeTag>
240 template<
class TypeTag>
242 {
static constexpr
auto value = Dune::VTK::ascii; };
245 template<
class TypeTag>
247 {
static constexpr
bool value =
false; };
250 template<
class TypeTag>
252 {
static constexpr
int value = 2; };
256 template<
class TypeTag>
258 {
static constexpr
bool value =
false; };
261 template<
class TypeTag>
263 {
static constexpr
bool value =
true; };
267 template<
class TypeTag>
269 {
static constexpr
bool value =
true; };
271 template <
class TypeTag,
class MyTypeTag>
275 template<
class TypeTag>
279 template<
class TypeTag>
296 template<
class TypeTag>
331 numEq = getPropValue<TypeTag, Properties::NumEq>(),
332 historySize = getPropValue<TypeTag, Properties::TimeDiscHistorySize>(),
335 using IntensiveQuantitiesVector = std::vector<IntensiveQuantities,
336 aligned_allocator<IntensiveQuantities,
337 alignof(IntensiveQuantities)>>;
339 using Element =
typename GridView::template Codim<0>::Entity;
340 using ElementIterator =
typename GridView::template Codim<0>::Iterator;
342 using Toolbox = MathToolbox<Evaluation>;
343 using VectorBlock = Dune::FieldVector<Evaluation, numEq>;
344 using EvalEqVector = Dune::FieldVector<Evaluation, numEq>;
346 using LocalEvalBlockVector =
typename LocalResidual::LocalEvalBlockVector;
352 SolutionVector blockVector_;
363 result.blockVector_[0] = 1.0;
364 result.blockVector_[1] = 2.0;
365 result.blockVector_[2] = 3.0;
370 SolutionVector& blockVector()
371 {
return blockVector_; }
373 const SolutionVector& blockVector()
const 374 {
return blockVector_; }
378 return std::ranges::equal(this->blockVector_, wrapper.blockVector_);
381 template<
class Serializer>
382 void serializeOp(Serializer& serializer)
384 serializer(blockVector_);
394 : simulator_(simulator)
396 , elementMapper_(gridView_,
Dune::mcmgElementLayout())
397 , vertexMapper_(gridView_,
Dune::mcmgVertexLayout())
398 , newtonMethod_(simulator)
399 , localLinearizer_(ThreadManager::maxThreads())
400 , linearizer_(std::make_unique<Linearizer>())
401 , enableGridAdaptation_(Parameters::Get<Parameters::EnableGridAdaptation>() )
402 , enableIntensiveQuantityCache_(Parameters::Get<Parameters::EnableIntensiveQuantityCache>())
403 , enableStorageCache_(Parameters::Get<Parameters::EnableStorageCache>())
404 , enableThermodynamicHints_(Parameters::Get<Parameters::EnableThermodynamicHints>())
405 , cachedIntensiveQuantityHistorySize_(static_cast<unsigned>(-1))
407 const bool isEcfv = std::is_same_v<Discretization, EcfvDiscretization<TypeTag>>;
408 if (enableGridAdaptation_ && !isEcfv) {
409 throw std::invalid_argument(
"Grid adaptation currently only works for the " 410 "element-centered finite volume discretization (is: " +
411 Dune::className<Discretization>() +
")");
414 PrimaryVariables::init();
417 asImp_().registerOutputModules_();
421 FvBaseDiscretization(
const FvBaseDiscretization&) =
delete;
428 Linearizer::registerParameters();
429 LocalLinearizer::registerParameters();
430 LocalResidual::registerParameters();
431 GradientCalculator::registerParameters();
432 IntensiveQuantities::registerParameters();
433 ExtensiveQuantities::registerParameters();
435 Linearizer::registerParameters();
436 PrimaryVariables::registerParameters();
440 Parameters::Register<Parameters::EnableGridAdaptation>
441 (
"Enable adaptive grid refinement/coarsening");
442 Parameters::Register<Parameters::EnableVtkOutput>
443 (
"Global switch for turning on writing VTK files");
444 Parameters::Register<Parameters::EnableThermodynamicHints>
445 (
"Enable thermodynamic hints");
446 Parameters::Register<Parameters::EnableIntensiveQuantityCache>
447 (
"Turn on caching of intensive quantities");
448 Parameters::Register<Parameters::EnableStorageCache>
449 (
"Store previous storage terms and avoid re-calculating them.");
450 Parameters::Register<Parameters::OutputDir>
451 (
"The directory to which result files are written");
460 const std::size_t numDof = asImp_().numGridDof();
461 dofTotalVolume_.resize(numDof);
462 std::ranges::fill(dofTotalVolume_, 0.0);
464 ElementContext elemCtx(simulator_);
465 gridTotalVolume_ = 0.0;
468 for (
const auto& elem : elements(gridView_)) {
471 if (elem.partitionType() != Dune::InteriorEntity) {
476 elemCtx.updateStencil(elem);
477 const auto& stencil = elemCtx.stencil(0);
480 for (
unsigned dofIdx = 0; dofIdx < elemCtx.numPrimaryDof(0); dofIdx++) {
482 const unsigned globalIdx = elemCtx.globalSpaceIndex(dofIdx, 0);
484 const Scalar dofVolume = stencil.subControlVolume(dofIdx).volume();
485 dofTotalVolume_[globalIdx] += dofVolume;
486 gridTotalVolume_ += dofVolume;
493 isLocalDof_.resize(numDof);
494 for (
unsigned dofIdx = 0; dofIdx < numDof; ++dofIdx) {
495 isLocalDof_[dofIdx] = (dofTotalVolume_[dofIdx] != 0.0);
499 const auto sumHandle =
500 GridCommHandleFactory::template sumHandle<Scalar>(dofTotalVolume_,
501 asImp_().dofMapper());
502 gridView_.communicate(*sumHandle,
503 Dune::InteriorBorder_All_Interface,
504 Dune::ForwardCommunication);
507 gridTotalVolume_ = gridView_.comm().sum(gridTotalVolume_);
509 linearizer_->init(simulator_);
511 localLinearizer_[threadId].init(simulator_);
514 resizeAndResetIntensiveQuantitiesCache_();
516 newtonMethod_.finishInit();
523 {
return enableGridAdaptation_; }
532 SolutionVector& uCur = asImp_().solution(0);
535 ElementContext elemCtx(simulator_);
538 for (
const auto& elem : elements(gridView_)) {
541 if (elem.partitionType() != Dune::InteriorEntity) {
546 elemCtx.updateStencil(elem);
549 for (
unsigned dofIdx = 0; dofIdx < elemCtx.numPrimaryDof(0); ++dofIdx) {
551 const unsigned globalIdx = elemCtx.globalSpaceIndex(dofIdx, 0);
555 simulator_.problem().initial(uCur[globalIdx], elemCtx, dofIdx, 0);
556 asImp_().supplementInitialSolution_(uCur[globalIdx], elemCtx, dofIdx, 0);
557 uCur[globalIdx].checkDefined();
562 asImp_().syncOverlap();
565 for (
unsigned timeIdx = 1; timeIdx < historySize; ++timeIdx) {
572 resizeAndResetIntensiveQuantitiesCache_();
574 simulator_.problem().initialSolutionApplied();
577 for (
unsigned timeIdx = 0; timeIdx < historySize; ++timeIdx) {
578 const auto& sol =
solution(timeIdx);
579 for (
unsigned dofIdx = 0; dofIdx < sol.size(); ++dofIdx) {
580 sol[dofIdx].checkDefined();
599 {
return newtonMethod_; }
605 {
return newtonMethod_; }
624 if (!enableThermodynamicHints_) {
645 if (!enableIntensiveQuantityCache_ ||
646 timeIdx >= cachedIntensiveQuantityHistorySize_ ||
647 !intensiveQuantityCacheUpToDate_[timeIdx][globalIdx]) {
656 if (timeIdx > 0 && enableStorageCache_ && intensiveQuantityCache_[timeIdx].empty()) {
660 return &intensiveQuantityCache_[timeIdx][globalIdx];
663 const auto& intensiveQuantityCache()
const 664 {
return intensiveQuantityCache_; }
676 unsigned timeIdx)
const 682 intensiveQuantityCache_[timeIdx][globalIdx] = intQuants;
683 intensiveQuantityCacheUpToDate_[timeIdx][globalIdx] =
true;
702 intensiveQuantityCacheUpToDate_[timeIdx][globalIdx] = newValue ? 1 : 0;
709 {
return cachedIntensiveQuantityHistorySize_; }
718 if (timeIdx >= cachedIntensiveQuantityHistorySize_) {
723 std::ranges::fill(intensiveQuantityCacheUpToDate_[timeIdx], 0);
727 void invalidateAndUpdateIntensiveQuantities(
unsigned timeIdx)
const 737 ElementContext elemCtx(simulator_);
738 ElementIterator elemIt = threadedElemIt.beginParallel();
739 for (; !threadedElemIt.isFinished(elemIt); elemIt = threadedElemIt.increment()) {
740 const Element& elem = *elemIt;
741 elemCtx.updatePrimaryStencil(elem);
742 elemCtx.updatePrimaryIntensiveQuantities(timeIdx);
747 template <
class Gr
idViewType>
748 void invalidateAndUpdateIntensiveQuantities(
unsigned timeIdx,
const GridViewType&
gridView)
const 751 ThreadedEntityIterator<GridViewType, 0> threadedElemIt(
gridView);
757 ElementContext elemCtx(simulator_);
758 auto elemIt = threadedElemIt.beginParallel();
759 for (; !threadedElemIt.isFinished(elemIt); elemIt = threadedElemIt.increment()) {
760 if (elemIt->partitionType() != Dune::InteriorEntity) {
763 const Element& elem = *elemIt;
764 elemCtx.updatePrimaryStencil(elem);
766 const std::size_t numPrimaryDof = elemCtx.numPrimaryDof(timeIdx);
767 for (
unsigned dofIdx = 0; dofIdx < numPrimaryDof; ++dofIdx) {
768 const unsigned globalIndex = elemCtx.globalSpaceIndex(dofIdx, timeIdx);
772 elemCtx.updatePrimaryIntensiveQuantities(timeIdx);
801 const unsigned intensiveHistorySize = cachedIntensiveQuantityHistorySize_;
802 for (
unsigned timeIdx = 0; timeIdx < intensiveHistorySize - numSlots; ++timeIdx) {
803 intensiveQuantityCache_[timeIdx + numSlots] = intensiveQuantityCache_[timeIdx];
804 intensiveQuantityCacheUpToDate_[timeIdx + numSlots] = intensiveQuantityCacheUpToDate_[timeIdx];
819 {
return enableStorageCache_; }
845 if (!enableStorageCache_ ||
846 timeIdx >= historySize ||
847 !storageCacheUpToDate_[timeIdx][globalIdx]) {
848 throw std::logic_error(
"Cached storage is not available or up to date for the requested " 849 "global index and time index. Make sure storage cache is enabled " 850 "and the entry is valid before calling this method.");
853 return storageCache_[timeIdx][globalIdx];
869 if (!enableStorageCache_ || timeIdx >= historySize) {
873 storageCache_[timeIdx][globalIdx] = value;
874 storageCacheUpToDate_[timeIdx][globalIdx] = 1;
885 if (!enableStorageCache_ || timeIdx >= historySize) {
888 return storageCacheUpToDate_[timeIdx][globalIdx] != 0;
899 if (enableStorageCache_ && timeIdx < historySize) {
900 storageCacheUpToDate_[timeIdx][globalIdx] = 0;
911 if (enableStorageCache_ && timeIdx < historySize) {
912 std::ranges::fill(storageCacheUpToDate_[timeIdx], 0);
930 if (enableStorageCache_ && !simulator_.problem().recycleFirstIterationStorage()) {
931 for (
unsigned timeIdx = 0; timeIdx < historySize - numSlots; ++timeIdx) {
932 storageCache_[timeIdx + numSlots] = storageCache_[timeIdx];
933 storageCacheUpToDate_[timeIdx + numSlots] = storageCacheUpToDate_[timeIdx];
948 const SolutionVector& u)
const 951 const Scalar res = asImp_().globalResidual(dest);
975 ElementContext elemCtx(simulator_);
976 ElementIterator elemIt = threadedElemIt.beginParallel();
977 LocalEvalBlockVector residual, storageTerm;
979 for (; !threadedElemIt.isFinished(elemIt); elemIt = threadedElemIt.increment()) {
980 const Element& elem = *elemIt;
981 if (elem.partitionType() != Dune::InteriorEntity) {
985 elemCtx.updateAll(elem);
986 residual.resize(elemCtx.numDof(0));
987 storageTerm.resize(elemCtx.numPrimaryDof(0));
988 asImp_().localResidual(threadId).eval(residual, elemCtx);
990 const std::size_t numPrimaryDof = elemCtx.numPrimaryDof(0);
992 for (
unsigned dofIdx = 0; dofIdx < numPrimaryDof; ++dofIdx) {
993 const unsigned globalI = elemCtx.globalSpaceIndex(dofIdx, 0);
994 for (
unsigned eqIdx = 0; eqIdx < numEq; ++ eqIdx) {
995 dest[globalI][eqIdx] += Toolbox::value(residual[dofIdx][eqIdx]);
1003 const auto sumHandle =
1004 GridCommHandleFactory::template sumHandle<EqVector>(dest, asImp_().dofMapper());
1005 gridView_.communicate(*sumHandle,
1006 Dune::InteriorBorder_InteriorBorder_Interface,
1007 Dune::ForwardCommunication);
1013 return std::sqrt(asImp_().
gridView().comm().sum(dest.two_norm2()));
1029 #pragma omp parallel 1035 ElementContext elemCtx(simulator_);
1036 ElementIterator elemIt = threadedElemIt.beginParallel();
1037 LocalEvalBlockVector elemStorage;
1041 elemCtx.setEnableStorageCache(
false);
1043 for (; !threadedElemIt.isFinished(elemIt); elemIt = threadedElemIt.increment()) {
1044 const Element& elem = *elemIt;
1045 if (elem.partitionType() != Dune::InteriorEntity) {
1049 elemCtx.updateStencil(elem);
1050 elemCtx.updatePrimaryIntensiveQuantities(timeIdx);
1052 const std::size_t numPrimaryDof = elemCtx.numPrimaryDof(timeIdx);
1053 elemStorage.resize(numPrimaryDof);
1055 localResidual(threadId).evalStorage(elemStorage, elemCtx, timeIdx);
1058 for (
unsigned dofIdx = 0; dofIdx < numPrimaryDof; ++dofIdx) {
1059 for (
unsigned eqIdx = 0; eqIdx < numEq; ++eqIdx) {
1060 storage[eqIdx] += Toolbox::value(elemStorage[dofIdx][eqIdx]);
1067 storage = gridView_.comm().sum(storage);
1078 [[maybe_unused]]
bool verbose =
false)
const 1081 Scalar totalBoundaryArea(0.0);
1082 Scalar totalVolume(0.0);
1083 EvalEqVector totalRate(0.0);
1087 if (tolerance <= 0) {
1089 simulator_.model().newtonMethod().tolerance() *
1090 simulator_.model().gridTotalVolume() *
1095 assert(historySize == 2);
1097 EqVector storageBeginTimeStep(0.0);
1100 EqVector storageEndTimeStep(0.0);
1104 ElementContext elemCtx(simulator_);
1105 elemCtx.setEnableStorageCache(
false);
1106 for (
const auto& elem : elements(simulator_.gridView())) {
1107 if (elem.partitionType() != Dune::InteriorEntity) {
1111 elemCtx.updateAll(elem);
1114 if (elemCtx.onBoundary()) {
1115 BoundaryContext boundaryCtx(elemCtx);
1117 for (
unsigned faceIdx = 0; faceIdx < boundaryCtx.numBoundaryFaces(0); ++faceIdx) {
1118 BoundaryRateVector values;
1119 simulator_.problem().boundary(values,
1123 Valgrind::CheckDefined(values);
1125 const unsigned dofIdx = boundaryCtx.interiorScvIndex(faceIdx, 0);
1126 const auto& insideIntQuants = elemCtx.intensiveQuantities(dofIdx, 0);
1128 const Scalar bfArea =
1129 boundaryCtx.boundarySegmentArea(faceIdx, 0) *
1130 insideIntQuants.extrusionFactor();
1132 for (
unsigned i = 0; i < values.size(); ++i) {
1133 values[i] *= bfArea;
1136 totalBoundaryArea += bfArea;
1137 for (
unsigned eqIdx = 0; eqIdx < numEq; ++eqIdx) {
1138 totalRate[eqIdx] += values[eqIdx];
1144 for (
unsigned dofIdx = 0; dofIdx < elemCtx.numPrimaryDof(0); ++dofIdx) {
1146 simulator_.problem().source(values,
1150 Valgrind::CheckDefined(values);
1152 const auto& intQuants = elemCtx.intensiveQuantities(dofIdx, 0);
1154 elemCtx.dofVolume(dofIdx, 0) *
1155 intQuants.extrusionFactor();
1156 for (
unsigned eqIdx = 0; eqIdx < numEq; ++eqIdx) {
1157 totalRate[eqIdx] += -dofVolume*Toolbox::value(values[eqIdx]);
1159 totalVolume += dofVolume;
1164 const auto& comm = simulator_.gridView().comm();
1165 totalRate = comm.sum(totalRate);
1166 totalBoundaryArea = comm.sum(totalBoundaryArea);
1167 totalVolume = comm.sum(totalVolume);
1169 if (comm.rank() == 0) {
1170 EqVector storageRate = storageBeginTimeStep;
1171 storageRate -= storageEndTimeStep;
1172 storageRate /= simulator_.timeStepSize();
1174 std::cout <<
"storage at beginning of time step: " << storageBeginTimeStep <<
"\n";
1175 std::cout <<
"storage at end of time step: " << storageEndTimeStep <<
"\n";
1176 std::cout <<
"rate based on storage terms: " << storageRate <<
"\n";
1177 std::cout <<
"rate based on source and boundary terms: " << totalRate <<
"\n";
1178 std::cout <<
"difference in rates: ";
1179 for (
unsigned eqIdx = 0; eqIdx < EqVector::dimension; ++eqIdx) {
1180 std::cout << (storageRate[eqIdx] - Toolbox::value(totalRate[eqIdx])) <<
" ";
1184 for (
unsigned eqIdx = 0; eqIdx < EqVector::dimension; ++eqIdx) {
1186 (std::abs(storageRate[eqIdx]) + Toolbox::value(totalRate[eqIdx])) * tolerance;
1187 eps = std::max(tolerance, eps);
1188 assert(std::abs(storageRate[eqIdx] - Toolbox::value(totalRate[eqIdx])) <= eps);
1200 {
return dofTotalVolume_[globalIdx]; }
1208 {
return isLocalDof_[globalIdx]; }
1210 size_t numDof()
const 1211 {
return asImp_().numGridDof(); }
1218 {
return gridTotalVolume_; }
1226 {
return solution_[timeIdx]->blockVector(); }
1232 {
return solution_[timeIdx]->blockVector(); }
1239 {
return solution_[timeIdx]->blockVector(); }
1247 {
return *linearizer_; }
1254 {
return *linearizer_; }
1265 {
return localLinearizer_[openMpThreadId]; }
1271 {
return localLinearizer_[openMpThreadId]; }
1277 {
return asImp_().localLinearizer(openMpThreadId).localResidual(); }
1283 {
return asImp_().localLinearizer(openMpThreadId).localResidual(); }
1294 const Scalar absPv = std::abs(asImp_().
solution(1)[globalDofIdx][pvIdx]);
1295 return 1.0 / std::max(absPv, 1.0);
1317 const PrimaryVariables& pv1,
1318 const PrimaryVariables& pv2)
const 1320 Scalar result = 0.0;
1321 for (
unsigned j = 0; j < numEq; ++j) {
1322 const Scalar weight = asImp_().primaryVarWeight(vertexIdx, j);
1323 const Scalar eqErr = std::abs((pv1[j] - pv2[j])*weight);
1327 result = std::max(result, eqErr);
1339 const TimerGuard prePostProcessGuard(prePostProcessTimer_);
1342 for (
unsigned timeIdx = 0; timeIdx < historySize; ++timeIdx) {
1346 for (std::size_t i = 0; i < asImp_().solution(0).size(); ++i) {
1347 asImp_().solution(timeIdx)[i].checkDefined();
1353 prePostProcessTimer_.
halt();
1354 linearizeTimer_.
halt();
1356 updateTimer_.
halt();
1358 prePostProcessTimer_.
start();
1359 asImp_().updateBegin();
1360 prePostProcessTimer_.
stop();
1362 bool converged =
false;
1365 converged = newtonMethod_.apply();
1368 prePostProcessTimer_ += newtonMethod_.prePostProcessTimer();
1369 linearizeTimer_ += newtonMethod_.linearizeTimer();
1370 solveTimer_ += newtonMethod_.solveTimer();
1371 updateTimer_ += newtonMethod_.updateTimer();
1377 for (
unsigned timeIdx = 0; timeIdx < historySize; ++timeIdx) {
1381 for (std::size_t i = 0; i < asImp_().solution(0).size(); ++i) {
1382 asImp_().solution(timeIdx)[i].checkDefined();
1387 prePostProcessTimer_ += newtonMethod_.prePostProcessTimer();
1388 linearizeTimer_ += newtonMethod_.linearizeTimer();
1389 solveTimer_ += newtonMethod_.solveTimer();
1390 updateTimer_ += newtonMethod_.updateTimer();
1392 prePostProcessTimer_.
start();
1394 asImp_().updateSuccessful();
1397 asImp_().updateFailed();
1399 prePostProcessTimer_.
stop();
1402 for (
unsigned timeIdx = 0; timeIdx < historySize; ++timeIdx) {
1406 for (std::size_t i = 0; i < asImp_().solution(0).size(); ++i) {
1407 asImp_().solution(timeIdx)[i].checkDefined();
1445 throw std::invalid_argument(
"Grid adaptation need to be implemented for " 1446 "specific settings of grid and function spaces");
1460 invalidateAndUpdateIntensiveQuantities(0);
1463 for (
unsigned timeIdx = 0; timeIdx < historySize; ++timeIdx) {
1467 for (std::size_t i = 0; i < asImp_().solution(0).size(); ++i) {
1468 asImp_().solution(timeIdx)[i].checkDefined();
1484 if (this->enableGridAdaptation_) {
1485 asImp_().adaptGrid();
1492 asImp_().shiftStorageCache(1);
1496 asImp_().shiftIntensiveQuantityCache(1);
1506 template <
class Restarter>
1509 throw std::runtime_error(
"Not implemented: The discretization chosen for this problem " 1510 "does not support restart files. (serialize() method unimplemented)");
1520 template <
class Restarter>
1523 throw std::runtime_error(
"Not implemented: The discretization chosen for this problem " 1524 "does not support restart files. (deserialize() method unimplemented)");
1535 template <
class DofEntity>
1537 const DofEntity& dof)
1539 const unsigned dofIdx =
static_cast<unsigned>(asImp_().dofMapper().index(dof));
1542 if (!outstream.good()) {
1543 throw std::runtime_error(
"Could not serialize degree of freedom " +
1544 std::to_string(dofIdx));
1547 for (
unsigned eqIdx = 0; eqIdx < numEq; ++eqIdx) {
1548 outstream <<
solution(0)[dofIdx][eqIdx] <<
" ";
1560 template <
class DofEntity>
1562 const DofEntity& dof)
1564 const unsigned dofIdx =
static_cast<unsigned>(asImp_().dofMapper().index(dof));
1566 for (
unsigned eqIdx = 0; eqIdx < numEq; ++eqIdx) {
1567 if (!instream.good()) {
1568 throw std::runtime_error(
"Could not deserialize degree of freedom " +
1569 std::to_string(dofIdx));
1571 instream >>
solution(0)[dofIdx][eqIdx];
1579 {
throw std::logic_error(
"The discretization class must implement the numGridDof() method!"); }
1586 return std::accumulate(auxEqModules_.begin(), auxEqModules_.end(),
1588 [](
const auto acc,
const auto& mod)
1589 {
return acc + mod->numDofs(); });
1603 {
throw std::logic_error(
"The discretization class must implement the dofMapper() method!"); }
1609 {
return vertexMapper_; }
1615 {
return elementMapper_; }
1623 linearizer_ = std::make_unique<Linearizer>();
1624 linearizer_->init(simulator_);
1640 std::ostringstream oss;
1641 oss <<
"primary variable_" << pvIdx;
1652 std::ostringstream oss;
1653 oss <<
"equation_" << eqIdx;
1670 { outputModules_.push_back(std::move(newModule)); }
1680 template <
class VtkMultiWriter>
1682 const SolutionVector& u,
1683 const GlobalEqVector& deltaU)
const 1685 using ScalarBuffer = std::vector<double>;
1687 GlobalEqVector globalResid(u.size());
1688 asImp_().globalResidual(globalResid, u);
1691 const std::size_t numDof = asImp_().numGridDof();
1694 std::array<ScalarBuffer*, numEq> def;
1695 std::array<ScalarBuffer*, numEq> delta;
1696 std::array<ScalarBuffer*, numEq> priVars;
1697 std::array<ScalarBuffer*, numEq> priVarWeight;
1700 for (
unsigned pvIdx = 0; pvIdx < numEq; ++pvIdx) {
1707 Scalar minRelErr = 1e30;
1708 Scalar maxRelErr = -1e30;
1709 for (
unsigned globalIdx = 0; globalIdx < numDof; ++ globalIdx) {
1710 for (
unsigned pvIdx = 0; pvIdx < numEq; ++pvIdx) {
1711 (*priVars[pvIdx])[globalIdx] = u[globalIdx][pvIdx];
1712 (*priVarWeight[pvIdx])[globalIdx] = asImp_().primaryVarWeight(globalIdx, pvIdx);
1713 (*delta[pvIdx])[globalIdx] = - deltaU[globalIdx][pvIdx];
1714 (*def[pvIdx])[globalIdx] = globalResid[globalIdx][pvIdx];
1717 PrimaryVariables uOld(u[globalIdx]);
1718 PrimaryVariables uNew(uOld);
1719 uNew -= deltaU[globalIdx];
1721 const Scalar err = asImp_().relativeDofError(globalIdx, uOld, uNew);
1722 (*relError)[globalIdx] = err;
1723 (*normalizedRelError)[globalIdx] = err;
1724 minRelErr = std::min(err, minRelErr);
1725 maxRelErr = std::max(err, maxRelErr);
1729 const Scalar alpha = std::max(Scalar{1e-20},
1730 std::max(std::abs(maxRelErr),
1731 std::abs(minRelErr)));
1732 for (
unsigned globalIdx = 0; globalIdx < numDof; ++globalIdx) {
1733 (*normalizedRelError)[globalIdx] /= alpha;
1736 DiscBaseOutputModule::attachScalarDofData_(writer, *relError,
"relative error");
1737 DiscBaseOutputModule::attachScalarDofData_(writer, *normalizedRelError,
"normalized relative error");
1739 for (
unsigned i = 0; i < numEq; ++i) {
1740 std::ostringstream oss;
1741 oss.str(
""); oss <<
"priVar_" << asImp_().primaryVarName(i);
1742 DiscBaseOutputModule::attachScalarDofData_(writer,
1746 oss.str(
""); oss <<
"delta_" << asImp_().primaryVarName(i);
1747 DiscBaseOutputModule::attachScalarDofData_(writer,
1751 oss.str(
""); oss <<
"weight_" << asImp_().primaryVarName(i);
1752 DiscBaseOutputModule::attachScalarDofData_(writer,
1756 oss.str(
""); oss <<
"defect_" << asImp_().eqName(i);
1757 DiscBaseOutputModule::attachScalarDofData_(writer,
1762 asImp_().prepareOutputFields();
1763 asImp_().appendOutputFields(writer);
1772 const bool needFullContextUpdate =
1773 std::ranges::any_of(outputModules_,
1775 {
return mod->needExtensiveQuantities(); });
1776 std::ranges::for_each(outputModules_,
1777 [](
auto& mod) { mod->allocBuffers(); });
1782 #pragma omp parallel 1785 ElementContext elemCtx(simulator_);
1786 ElementIterator elemIt = threadedElemIt.beginParallel();
1787 for (; !threadedElemIt.isFinished(elemIt); elemIt = threadedElemIt.increment()) {
1788 const auto& elem = *elemIt;
1789 if (elem.partitionType() != Dune::InteriorEntity) {
1794 if (needFullContextUpdate) {
1795 elemCtx.updateAll(elem);
1798 elemCtx.updatePrimaryStencil(elem);
1799 elemCtx.updatePrimaryIntensiveQuantities(0);
1802 std::ranges::for_each(outputModules_,
1803 [&elemCtx](
auto& mod) { mod->processElement(elemCtx); });
1814 std::ranges::for_each(outputModules_,
1815 [&writer](
auto& mod) { mod->commitBuffers(writer); });
1822 {
return gridView_; }
1838 auxEqModules_.push_back(auxMod);
1841 if (enableGridAdaptation_ && !std::is_same_v<DiscreteFunction, BlockVectorWrapper>) {
1842 throw std::invalid_argument(
"Problems which require auxiliary modules cannot be used in" 1843 " conjunction with dune-fem");
1847 for (
unsigned timeIdx = 0; timeIdx < historySize; ++timeIdx) {
1861 auxEqModules_.clear();
1862 linearizer_->eraseMatrix();
1863 newtonMethod_.eraseMatrix();
1870 {
return auxEqModules_.size(); }
1876 {
return auxEqModules_[auxEqModIdx]; }
1882 {
return auxEqModules_[auxEqModIdx]; }
1888 {
return enableIntensiveQuantityCache_ || enableThermodynamicHints_; }
1890 const Timer& prePostProcessTimer()
const 1891 {
return prePostProcessTimer_; }
1893 const Timer& linearizeTimer()
const 1894 {
return linearizeTimer_; }
1896 const Timer& solveTimer()
const 1897 {
return solveTimer_; }
1899 const Timer& updateTimer()
const 1900 {
return updateTimer_; }
1902 template<
class Serializer>
1903 void serializeOp(Serializer& serializer)
1905 using BaseDiscretization = GetPropType<TypeTag, Properties::BaseDiscretizationType>;
1906 using Helper =
typename BaseDiscretization::template SerializeHelper<Serializer>;
1907 Helper::serializeOp(serializer, solution_);
1910 bool operator==(
const FvBaseDiscretization& rhs)
const 1912 return std::ranges::equal(this->solution_, rhs.solution_,
1913 [](
const auto& x,
const auto& y)
1914 { return *x == *y; });
1918 void resizeAndResetIntensiveQuantitiesCache_()
1922 const std::size_t numDof = asImp_().numGridDof();
1923 for (
unsigned timeIdx = 0; timeIdx < historySize; ++timeIdx) {
1924 storageCache_[timeIdx].resize(numDof);
1925 storageCacheUpToDate_[timeIdx].resize(numDof, 0);
1931 const std::size_t numDof = asImp_().numGridDof();
1932 cachedIntensiveQuantityHistorySize_ = simulator_.problem().intensiveQuantityHistorySize();
1933 const unsigned intensiveHistorySize = cachedIntensiveQuantityHistorySize_;
1936 intensiveQuantityCache_.resize(intensiveHistorySize);
1937 intensiveQuantityCacheUpToDate_.resize(intensiveHistorySize);
1939 for(
unsigned timeIdx = 0; timeIdx < intensiveHistorySize; ++timeIdx) {
1940 intensiveQuantityCache_[timeIdx].resize(numDof);
1941 intensiveQuantityCacheUpToDate_[timeIdx].resize(numDof);
1947 template <
class Context>
1948 void supplementInitialSolution_(PrimaryVariables&,
1971 {
return localLinearizer_.localResidual(); }
1977 {
return gridView_.comm().rank() == 0; }
1979 Implementation& asImp_()
1980 {
return *
static_cast<Implementation*
>(
this); }
1982 const Implementation& asImp_()
const 1983 {
return *
static_cast<const Implementation*
>(
this); }
1987 Simulator& simulator_;
1993 ElementMapper elementMapper_;
1994 VertexMapper vertexMapper_;
1997 std::vector<BaseAuxiliaryModule<TypeTag>*> auxEqModules_;
1999 NewtonMethod newtonMethod_;
2001 Timer prePostProcessTimer_;
2002 Timer linearizeTimer_;
2007 std::vector<LocalLinearizer> localLinearizer_;
2010 std::unique_ptr<Linearizer> linearizer_;
2014 mutable std::vector<IntensiveQuantitiesVector> intensiveQuantityCache_;
2017 mutable std::vector<std::vector<unsigned char>> intensiveQuantityCacheUpToDate_;
2019 std::array<std::unique_ptr<DiscreteFunction>, historySize> solution_;
2021 std::list<std::unique_ptr<BaseOutputModule<TypeTag>>> outputModules_;
2023 Scalar gridTotalVolume_;
2024 std::vector<Scalar> dofTotalVolume_;
2025 std::vector<bool> isLocalDof_;
2027 mutable std::array<GlobalEqVector, historySize> storageCache_;
2030 mutable std::array<std::vector<unsigned char>, historySize> storageCacheUpToDate_;
2032 bool enableGridAdaptation_;
2033 bool enableIntensiveQuantityCache_;
2034 bool enableStorageCache_;
2035 bool enableThermodynamicHints_;
2037 mutable unsigned cachedIntensiveQuantityHistorySize_;
2045 template<
class TypeTag>
2046 class FvBaseDiscretizationNoAdapt :
public FvBaseDiscretization<TypeTag>
2048 using ParentType = FvBaseDiscretization<TypeTag>;
2049 using Simulator = GetPropType<TypeTag, Properties::Simulator>;
2050 using DiscreteFunction = GetPropType<TypeTag, Properties::DiscreteFunction>;
2052 static constexpr
unsigned historySize = getPropValue<TypeTag, Properties::TimeDiscHistorySize>();
2055 template<
class Serializer>
2058 template<
class SolutionType>
2059 static void serializeOp(Serializer& serializer,
2071 if (this->enableGridAdaptation_) {
2072 throw std::invalid_argument(
"Grid adaptation need to use" 2073 " BaseDiscretization = FvBaseDiscretizationFemAdapt" 2074 " which currently requires the presence of the" 2075 " dune-fem module");
2077 const std::size_t numDof = this->asImp_().numGridDof();
2078 for (
unsigned timeIdx = 0; timeIdx < historySize; ++timeIdx) {
2079 this->solution_[timeIdx] = std::make_unique<DiscreteFunction>(
"solution", numDof);
2086 #endif // EWOMS_FV_BASE_DISCRETIZATION_HH Definition: fvbasediscretization.hh:2056
void registerOutputModules_()
Register all output modules which make sense for the model.
Definition: fvbasediscretization.hh:1961
Simplifies multi-threaded capabilities.
Definition: threadmanager.hpp:35
std::string eqName(unsigned eqIdx) const
Given an equation index, return a human readable name.
Definition: fvbasediscretization.hh:1650
This is a stand-alone version of boost::alignment::aligned_allocator from Boost 1...
void setIntensiveQuantitiesCacheEntryValidity(unsigned globalIdx, unsigned timeIdx, bool newValue) const
Invalidate the cache for a given intensive quantities object.
Definition: fvbasediscretization.hh:694
Calculates gradients of arbitrary quantities at flux integration points.
Definition: fvbaseproperties.hh:167
Definition: fvbasediscretization.hh:349
Manages the initializing and running of time dependent problems.
The multi-dimensional Newton method.
Definition: newtonmethod.hh:64
void finishInit()
Apply the initial conditions to the model.
Definition: fvbasediscretization.hh:457
static void registerParameters()
Register all run-time parameters for the Newton method.
Definition: newtonmethod.hh:135
Provide the properties at a face which make sense independently of the conserved quantities.
Definition: fvbaseextensivequantities.hh:47
const IntensiveQuantities * thermodynamicHint(unsigned globalIdx, unsigned timeIdx) const
Return the thermodynamic hint for a entity on the grid at given time.
Definition: fvbasediscretization.hh:622
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
void setEnableStorageCache(bool enableStorageCache)
Set the value of enable storage cache.
Definition: fvbasediscretization.hh:827
static unsigned maxThreads()
Return the maximum number of threads of the current process.
Definition: threadmanager.hpp:66
void shiftIntensiveQuantityCache(unsigned numSlots=1)
Move the intensive quantities for a given time index to the back.
Definition: fvbasediscretization.hh:785
Element-wise caculation of the residual matrix for models based on a finite volume spatial discretiza...
Definition: fvbaselocalresidual.hh:62
const BaseAuxiliaryModule< TypeTag > * auxiliaryModule(unsigned auxEqModIdx) const
Returns a given module for auxiliary equations.
Definition: fvbasediscretization.hh:1881
The base class for the finite volume discretization schemes.
Definition: fvbasediscretization.hh:87
const LocalLinearizer & localLinearizer(unsigned openMpThreadId) const
Returns the local jacobian which calculates the local stiffness matrix for an arbitrary element...
Definition: fvbasediscretization.hh:1264
This class stores an array of IntensiveQuantities objects, one intensive quantities object for each o...
void addAuxiliaryModule(BaseAuxiliaryModule< TypeTag > *auxMod)
Add a module for an auxiliary equation.
Definition: fvbasediscretization.hh:1835
The mapper to find the global index of an element.
Definition: fvbaseproperties.hh:228
This class calculates gradients of arbitrary quantities at flux integration points using the two-poin...
Definition: fvbasegradientcalculator.hh:51
void adaptGrid()
Called by the update() method when the grid should be refined.
Definition: fvbasediscretization.hh:1443
Scalar globalResidual(GlobalEqVector &dest, const SolutionVector &u) const
Compute the global residual for an arbitrary solution vector.
Definition: fvbasediscretization.hh:947
virtual void applyInitial()=0
Set the initial condition of the auxiliary module in the solution vector.
Base class for specifying auxiliary equations.
NewtonMethod & newtonMethod()
Returns the newton method object.
Definition: fvbasediscretization.hh:598
static void registerParameters()
Register all run-time parameters for the Vtk output module.
Definition: vtkprimaryvarsmodule.hpp:74
void start()
Start counting the time resources used by the simulation.
Definition: timer.cpp:46
Definition: fvbaseprimaryvariables.hh:161
void shiftStorageCache(unsigned numSlots=1) const
Shift storage cache by a given number of time step slots.
Definition: fvbasediscretization.hh:927
void invalidateIntensiveQuantitiesCache(unsigned timeIdx) const
Invalidate the whole intensive quantity cache for time index.
Definition: fvbasediscretization.hh:716
void updateBegin()
Called by the update() method before it tries to apply the newton method.
Definition: fvbasediscretization.hh:1430
The base class for writer modules.
Definition: baseoutputmodule.hh:67
const SolutionVector & solution(unsigned timeIdx) const
Reference to the solution at a given history index as a block vector.
Definition: fvbasediscretization.hh:1225
const GridView & gridView() const
Reference to the grid view of the spatial domain.
Definition: fvbasediscretization.hh:1821
The discretization specific part of the local residual.
Definition: fvbaseproperties.hh:97
This is a grid manager which does not create any border list.
Scalar primaryVarWeight(unsigned globalDofIdx, unsigned pvIdx) const
Returns the relative weight of a primary variable for calculating relative errors.
Definition: fvbasediscretization.hh:1292
bool enableStorageCache() const
Returns true iff the storage term is cached.
Definition: fvbasediscretization.hh:818
void invalidateStorageCacheEntry(unsigned globalIdx, unsigned timeIdx) const
Invalidate the storage cache for a given DOF and time index.
Definition: fvbasediscretization.hh:897
use locking to prevent race conditions when linearizing the global system of equations in multi-threa...
Definition: fvbaseproperties.hh:196
Specify whether the storage terms use extensive quantities or not.
Definition: fvbaseproperties.hh:248
Base class for the model specific class which provides access to all intensive (i.e., volume averaged) quantities.
Definition: fvbaseintensivequantities.hh:44
The mapper to find the global index of a vertex.
Definition: fvbaseproperties.hh:222
void serializeEntity(std::ostream &outstream, const DofEntity &dof)
Write the current solution for a degree of freedom to a restart file.
Definition: fvbasediscretization.hh:1536
bool storageCacheIsUpToDate(unsigned globalIdx, unsigned timeIdx) const
Returns true if the storage cache entry for a given DOF and time index is up to date.
Definition: fvbasediscretization.hh:883
Represents all quantities which available for calculating constraints.
a tag to mark properties as undefined
Definition: propertysystem.hh:38
The OpenMP threads manager.
Definition: fvbaseproperties.hh:189
bool storeIntensiveQuantities() const
Returns true if the cache for intensive quantities is enabled.
Definition: fvbasediscretization.hh:1887
std::string primaryVarName(unsigned pvIdx) const
Given an primary variable index, return a human readable name.
Definition: fvbasediscretization.hh:1638
A vector of holding a quantity for each equation (usually at a given spatial location) ...
Definition: fvbaseproperties.hh:115
Specify whether the some degrees of fredom can be constraint.
Definition: fvbaseproperties.hh:214
Simplifies writing multi-file VTK datasets.
Definition: vtkmultiwriter.hh:64
The base class for the finite volume discretization schemes without adaptation.
Definition: fvbasediscretization.hh:84
Structs needed for tpfalinearizer and its gpuparams struct extracted to be defined in one place that ...
Definition: blackoilbioeffectsmodules.hh:45
The base class for all output writers.
Definition: baseoutputwriter.hh:45
BaseAuxiliaryModule< TypeTag > * auxiliaryModule(unsigned auxEqModIdx)
Returns a given module for auxiliary equations.
Definition: fvbasediscretization.hh:1875
A Newton method for models using a finite volume discretization.
This class stores an array of IntensiveQuantities objects, one intensive quantities object for each o...
Definition: fvbaseelementcontext.hh:54
void clearAuxiliaryModules()
Causes the list of auxiliary equations to be cleared.
Definition: fvbasediscretization.hh:1859
SolutionVector & solution(unsigned timeIdx)
Definition: fvbasediscretization.hh:1231
const Linearizer & linearizer() const
Returns the operator linearizer for the global jacobian of the problem.
Definition: fvbasediscretization.hh:1246
void syncOverlap()
Syncronize the values of the primary variables on the degrees of freedom that overlap with the neighb...
Definition: fvbasediscretization.hh:1422
void addOutputModule(std::unique_ptr< BaseOutputModule< TypeTag >> newModule)
Add an module for writing visualization output after a timestep.
Definition: fvbasediscretization.hh:1669
The class which marks the border indices associated with the degrees of freedom on a process boundary...
Definition: basicproperties.hh:129
Vector containing volumetric or areal rates of quantities.
Definition: fvbaseproperties.hh:122
Type of object for specifying boundary conditions.
Definition: fvbaseproperties.hh:125
void addConvergenceVtkFields(VtkMultiWriter &writer, const SolutionVector &u, const GlobalEqVector &deltaU) const
Add the vector fields for analysing the convergence of the newton method to the a VTK writer...
Definition: fvbasediscretization.hh:1681
Base class for the model specific class which provides access to all intensive (i.e., volume averaged) quantities.
Declare the properties used by the infrastructure code of the finite volume discretizations.
Provides data handles for parallel communication which operate on DOFs.
This class calculates gradients of arbitrary quantities at flux integration points using the two-poin...
void globalStorage(EqVector &storage, unsigned timeIdx=0) const
Compute the integral over the domain of the storage terms of all conservation quantities.
Definition: fvbasediscretization.hh:1022
std::size_t numGridDof() const
Returns the number of degrees of freedom (DOFs) for the computational grid.
Definition: fvbasediscretization.hh:1578
void advanceTimeLevel()
Called by the problem if a time integration was successful, post processing of the solution is done a...
Definition: fvbasediscretization.hh:1481
Represents all quantities which available for calculating constraints.
Definition: fvbaseconstraintscontext.hh:43
const EqVector & cachedStorage(unsigned globalIdx, unsigned timeIdx) const
Retrieve an entry of the cache for the storage term.
Definition: fvbasediscretization.hh:843
const DofMapper & dofMapper() const
Mapper to convert the Dune entities of the discretization's degrees of freedoms are to indices...
Definition: fvbasediscretization.hh:1602
static unsigned threadId()
Return the index of the current OpenMP thread.
Definition: threadmanager.cpp:84
VTK output module for the fluid composition.
Definition: vtkprimaryvarsmodule.hpp:47
void deserializeEntity(std::istream &instream, const DofEntity &dof)
Reads the current solution variables for a degree of freedom from a restart file. ...
Definition: fvbasediscretization.hh:1561
Represents all quantities which available on boundary segments.
Scalar eqWeight(unsigned, unsigned) const
Returns the relative weight of an equation.
Definition: fvbasediscretization.hh:1304
bool verbose_() const
Returns whether messages should be printed.
Definition: fvbasediscretization.hh:1976
The secondary variables of all degrees of freedom in an element's stencil.
Definition: fvbaseproperties.hh:155
void serialize(Restarter &)
Serializes the current state of the model.
Definition: fvbasediscretization.hh:1507
SolutionVector & mutableSolution(unsigned timeIdx) const
Definition: fvbasediscretization.hh:1238
const ElementMapper & elementMapper() const
Returns the mapper for elements to indices.
Definition: fvbasediscretization.hh:1614
void updateCachedIntensiveQuantities(const IntensiveQuantities &intQuants, unsigned globalIdx, unsigned timeIdx) const
Update the intensive quantity cache for a entity on the grid at given time.
Definition: fvbasediscretization.hh:674
Definition: fvbaseproperties.hh:151
void invalidateStorageCache(unsigned timeIdx) const
Invalidate the whole storage cache for a given time index.
Definition: fvbasediscretization.hh:909
Provides an STL-iterator like interface to iterate over the enties of a GridView in OpenMP threaded a...
Definition: threadedentityiterator.hh:41
bool isLocalDof(unsigned globalIdx) const
Returns if the overlap of the volume ofa degree of freedom is non-zero.
Definition: fvbasediscretization.hh:1207
LocalResidual & localResidual_()
Reference to the local residal object.
Definition: fvbasediscretization.hh:1970
Calculates the Jacobian of the local residual for finite volume spatial discretizations using a finit...
The secondary variables of a constraint degree of freedom.
Definition: fvbaseproperties.hh:161
void resetLinearizer()
Resets the Jacobian matrix linearizer, so that the boundary types can be altered. ...
Definition: fvbasediscretization.hh:1621
Represents all quantities which available on boundary segments.
Definition: fvbaseboundarycontext.hh:45
The class which represents a constraint degree of freedom.
Definition: fvbaseproperties.hh:128
Calculates the local residual and its Jacobian for a single element of the grid.
A simple class which makes sure that a timer gets stopped if an exception is thrown.
Definition: timerguard.hh:41
void appendOutputFields(BaseOutputWriter &writer) const
Append the quantities relevant for the current solution to an output writer.
Definition: fvbasediscretization.hh:1812
void deserialize(Restarter &)
Deserializes the state of the model.
Definition: fvbasediscretization.hh:1521
The secondary variables within a sub-control volume.
Definition: fvbaseproperties.hh:139
The common code for the linearizers of non-linear systems of equations.
Provides an encapsulation to measure the system time.
Definition: timer.hpp:45
void updateSuccessful()
Called by the update() method if it was successful.
Definition: fvbasediscretization.hh:1437
LocalLinearizer & localLinearizer(unsigned openMpThreadId)
Definition: fvbasediscretization.hh:1270
unsigned cachedIntensiveQuantityHistorySize() const
Get the cached intensive quantity history size.
Definition: fvbasediscretization.hh:708
Class to specify constraints for a finite volume spatial discretization.
Definition: fvbaseconstraints.hh:47
Declares the parameters for the black oil model.
void checkConservativeness([[maybe_unused]] Scalar tolerance=-1, [[maybe_unused]] bool verbose=false) const
Ensure that the difference between the storage terms of the last and of the current time step is cons...
Definition: fvbasediscretization.hh:1077
void applyInitialSolution()
Applies the initial solution for all degrees of freedom to which the model applies.
Definition: fvbasediscretization.hh:529
const VertexMapper & vertexMapper() const
Returns the mapper for vertices to indices.
Definition: fvbasediscretization.hh:1608
const IntensiveQuantities * cachedIntensiveQuantities(unsigned globalIdx, unsigned timeIdx) const
Return the cached intensive quantities for a entity on the grid at given time.
Definition: fvbasediscretization.hh:643
The part of the extensive quantities which is specific to the spatial discretization.
Definition: fvbaseproperties.hh:175
Specify if experimental features should be enabled or not.
Definition: fvbaseproperties.hh:256
Provides an encapsulation to measure the system time.
Class to specify constraints for a finite volume spatial discretization.
bool enableGridAdaptation() const
Returns whether the grid ought to be adapted to the solution during the simulation.
Definition: fvbasediscretization.hh:522
Scalar gridTotalVolume() const
Returns the volume of the whole grid which represents the spatial domain.
Definition: fvbasediscretization.hh:1217
Scalar globalResidual(GlobalEqVector &dest) const
Compute the global residual for the current solution vector.
Definition: fvbasediscretization.hh:962
bool update()
Try to progress the model to the next timestep.
Definition: fvbasediscretization.hh:1337
Vector containing a quantity of for equation for each DOF of the whole grid.
Definition: linalgproperties.hh:54
Simplifies multi-threaded capabilities.
This is a grid manager which does not create any border list.
Definition: nullborderlistmanager.hh:43
The class which linearizes the non-linear system of equations.
Definition: newtonmethodproperties.hh:36
Scalar dofTotalVolume(unsigned globalIdx) const
Returns the volume of a given control volume.
Definition: fvbasediscretization.hh:1199
Represents the primary variables used by the a model.
Element-wise caculation of the residual matrix for models based on a finite volume spatial discretiza...
Scalar relativeDofError(unsigned vertexIdx, const PrimaryVariables &pv1, const PrimaryVariables &pv2) const
Returns the relative error between two vectors of primary variables.
Definition: fvbasediscretization.hh:1316
A simple class which makes sure that a timer gets stopped if an exception is thrown.
Provide the properties at a face which make sense independently of the conserved quantities.
std::size_t numTotalDof() const
Returns the total number of degrees of freedom (i.e., grid plux auxiliary DOFs)
Definition: fvbasediscretization.hh:1595
A vector of holding a quantity for each equation for each DOF of an element.
Definition: fvbaseproperties.hh:118
void setDofOffset(int value)
Set the offset in the global system of equations for the first degree of freedom of this auxiliary mo...
Definition: baseauxiliarymodule.hh:78
void prepareOutputFields() const
Prepare the quantities relevant for the current solution to be appended to the output writers...
Definition: fvbasediscretization.hh:1770
Definition: fvbasediscretization.hh:272
Manages the simulation time.
Definition: basicproperties.hh:120
The history size required by the time discretization.
Definition: fvbaseproperties.hh:240
ScalarBuffer * allocateManagedScalarBuffer(std::size_t numEntities)
Allocate a managed buffer for a scalar field.
Definition: vtkmultiwriter.hh:192
std::size_t numAuxiliaryModules() const
Returns the number of modules for auxiliary equations.
Definition: fvbasediscretization.hh:1869
void prefetch(const Element &) const
Allows to improve the performance by prefetching all data which is associated with a given element...
Definition: fvbasediscretization.hh:590
Vector containing all primary variables of the grid.
Definition: fvbaseproperties.hh:132
void halt()
Stop the measurement reset all timing values.
Definition: timer.cpp:75
Base class for specifying auxiliary equations.
Definition: baseauxiliarymodule.hh:55
std::size_t numAuxiliaryDof() const
Returns the number of degrees of freedom (DOFs) of the auxiliary equations.
Definition: fvbasediscretization.hh:1584
static void registerParameters()
Register all run-time parameters for the model.
Definition: fvbasediscretization.hh:426
void updatePVWeights(const ElementContext &) const
Update the weights of all primary variables within an element given the complete set of intensive qua...
Definition: fvbasediscretization.hh:1663
Manages the initializing and running of time dependent problems.
Definition: simulator.hh:83
double stop()
Stop counting the time resources.
Definition: timer.cpp:52
Definition: blackoilmodel.hh:75
const LocalResidual & localResidual(unsigned openMpThreadId) const
Returns the object to calculate the local residual function.
Definition: fvbasediscretization.hh:1276
The secondary variables of a boundary segment.
Definition: fvbaseproperties.hh:158
void updateFailed()
Called by the update() method if it was unsuccessful.
Definition: fvbasediscretization.hh:1454
A vector of primary variables within a sub-control volume.
Definition: fvbaseproperties.hh:136
void updateCachedStorage(unsigned globalIdx, unsigned timeIdx, const EqVector &value) const
Set an entry of the cache for the storage term.
Definition: fvbasediscretization.hh:867
static std::string discretizationName()
Returns a string of discretization's human-readable name.
Definition: fvbasediscretization.hh:1630
The common code for the linearizers of non-linear systems of equations.
Definition: fvbaselinearizer.hh:77
VTK output module for the fluid composition.
Definition: fvbaseproperties.hh:83
LocalResidual & localResidual(unsigned openMpThreadId)
Definition: fvbasediscretization.hh:1282
Specify whether to use volumetric residuals or not.
Definition: fvbaseproperties.hh:252
Linearizer & linearizer()
Returns the object which linearizes the global system of equations at the current solution...
Definition: fvbasediscretization.hh:1253
const NewtonMethod & newtonMethod() const
Returns the newton method object.
Definition: fvbasediscretization.hh:604