fvbasediscretization.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3/*
4 This file is part of the Open Porous Media project (OPM).
5
6 OPM is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 2 of the License, or
9 (at your option) any later version.
10
11 OPM is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with OPM. If not, see <http://www.gnu.org/licenses/>.
18
19 Consult the COPYING file in the top-level source directory of this
20 module for the precise wording of the license and the list of
21 copyright holders.
22*/
28#ifndef EWOMS_FV_BASE_DISCRETIZATION_HH
29#define EWOMS_FV_BASE_DISCRETIZATION_HH
30
31#include <opm/material/densead/Math.hpp>
32
33#include "fvbaseproperties.hh"
34#include "fvbaselinearizer.hh"
41#include "fvbaseconstraints.hh"
43#include "fvbasenewtonmethod.hh"
48
57
58#include <opm/material/common/MathToolbox.hpp>
59#include <opm/material/common/Valgrind.hpp>
60
61#include <dune/common/version.hh>
62#include <dune/common/fvector.hh>
63#include <dune/common/fmatrix.hh>
64#include <dune/istl/bvector.hh>
65
66
67#include <algorithm>
68#include <cstddef>
69#include <limits>
70#include <list>
71#include <stdexcept>
72#include <sstream>
73#include <string>
74#include <type_traits>
75#include <vector>
76
77namespace Opm {
78template<class TypeTag>
79class FvBaseDiscretizationNoAdapt;
80template<class TypeTag>
81class FvBaseDiscretization;
82
83} // namespace Opm
84
85namespace Opm::Properties {
86
88template<class TypeTag>
90
92template<class TypeTag>
93struct VertexMapper<TypeTag, TTag::FvBaseDiscretization>
94{ using type = Dune::MultipleCodimMultipleGeomTypeMapper<GetPropType<TypeTag, Properties::GridView>>; };
95
97template<class TypeTag>
98struct ElementMapper<TypeTag, TTag::FvBaseDiscretization>
99{ using type = Dune::MultipleCodimMultipleGeomTypeMapper<GetPropType<TypeTag, Properties::GridView>>; };
100
102template<class TypeTag>
104{
107public:
109};
110
111template<class TypeTag>
113
114template<class TypeTag>
116template<class TypeTag>
118
120template<class TypeTag>
122
125template<class TypeTag>
126struct MaxTimeStepDivisions<TypeTag, TTag::FvBaseDiscretization> { static constexpr unsigned value = 10; };
127
128
132template<class TypeTag>
133struct ContinueOnConvergenceError<TypeTag, TTag::FvBaseDiscretization> { static constexpr bool value = false; };
134
138template<class TypeTag>
139struct EqVector<TypeTag, TTag::FvBaseDiscretization>
140{ using type = Dune::FieldVector<GetPropType<TypeTag, Properties::Scalar>,
141 getPropValue<TypeTag, Properties::NumEq>()>; };
142
148template<class TypeTag>
149struct RateVector<TypeTag, TTag::FvBaseDiscretization>
151
155template<class TypeTag>
158
162template<class TypeTag>
164
168template<class TypeTag>
170{ using type = Dune::BlockVector<GetPropType<TypeTag, Properties::EqVector>>; };
171
175template<class TypeTag>
177{ using type = Dune::BlockVector<GetPropType<TypeTag, Properties::EqVector>>; };
178
182template<class TypeTag>
184
188template<class TypeTag>
190{ using type = Dune::BlockVector<GetPropType<TypeTag, Properties::PrimaryVariables>>; };
191
197template<class TypeTag>
199
203template<class TypeTag>
205template<class TypeTag>
207template<class TypeTag>
209
213template<class TypeTag>
215template<class TypeTag>
216struct ThreadsPerProcess<TypeTag, TTag::FvBaseDiscretization> { static constexpr int value = 1; };
217template<class TypeTag>
218struct UseLinearizationLock<TypeTag, TTag::FvBaseDiscretization> { static constexpr bool value = true; };
219
223template<class TypeTag>
225
227template<class TypeTag>
229{
231 static constexpr type value = std::numeric_limits<type>::infinity();
232};
233
235template<class TypeTag>
237{
239 static constexpr type value = 0.0;
240};
241
243template<class TypeTag>
244struct EnableGridAdaptation<TypeTag, TTag::FvBaseDiscretization> { static constexpr bool value = false; };
245
247template<class TypeTag>
248struct OutputDir<TypeTag, TTag::FvBaseDiscretization> { static constexpr auto value = "."; };
249
251template<class TypeTag>
252struct EnableVtkOutput<TypeTag, TTag::FvBaseDiscretization> { static constexpr bool value = true; };
253
257template<class TypeTag>
258struct EnableAsyncVtkOutput<TypeTag, TTag::FvBaseDiscretization> { static constexpr bool value = true; };
259
261template<class TypeTag>
262struct VtkOutputFormat<TypeTag, TTag::FvBaseDiscretization> { static constexpr int value = Dune::VTK::ascii; };
263
264// disable caching the storage term by default
265template<class TypeTag>
266struct EnableStorageCache<TypeTag, TTag::FvBaseDiscretization> { static constexpr bool value = false; };
267
268// disable constraints by default
269template<class TypeTag>
270struct EnableConstraints<TypeTag, TTag::FvBaseDiscretization> { static constexpr bool value = false; };
271
272// by default, disable the intensive quantity cache. If the intensive quantities are
273// relatively cheap to calculate, the cache basically does not yield any performance
274// impact because of the intensive quantity cache will cause additional pressure on the
275// CPU caches...
276template<class TypeTag>
277struct EnableIntensiveQuantityCache<TypeTag, TTag::FvBaseDiscretization> { static constexpr bool value = false; };
278
279// do not use thermodynamic hints by default. If you enable this, make sure to also
280// enable the intensive quantity cache above to avoid getting an exception...
281template<class TypeTag>
282struct EnableThermodynamicHints<TypeTag, TTag::FvBaseDiscretization> { static constexpr bool value = false; };
283
284// if the deflection of the newton method is large, we do not need to solve the linear
285// approximation accurately. Assuming that the value for the current solution is quite
286// close to the final value, a reduction of 3 orders of magnitude in the defect should be
287// sufficient...
288template<class TypeTag>
290{
292 static constexpr type value = 1e-3;
293};
294
295// use default initialization based on rule-of-thumb of Newton tolerance
296template<class TypeTag>
298{
300 static constexpr type value = -1.;
301};
302
304template<class TypeTag>
305struct TimeDiscHistorySize<TypeTag, TTag::FvBaseDiscretization> { static constexpr int value = 2; };
306
309template<class TypeTag>
310struct ExtensiveStorageTerm<TypeTag, TTag::FvBaseDiscretization> { static constexpr bool value = false; };
311
312// use volumetric residuals is default
313template<class TypeTag>
314struct UseVolumetricResidual<TypeTag, TTag::FvBaseDiscretization> { static constexpr bool value = true; };
315
318template<class TypeTag>
319struct EnableExperiments<TypeTag, TTag::FvBaseDiscretization> { static constexpr bool value = true; };
320
321template <class TypeTag, class MyTypeTag>
324};
325
326#if !HAVE_DUNE_FEM
327template<class TypeTag>
330};
331template<class TypeTag>
335};
336#endif
337
338} // namespace Opm::Properties
339
340namespace Opm {
341
347template<class TypeTag>
349{
350 using Implementation = GetPropType<TypeTag, Properties::Model>;
377
380
381 enum {
382 numEq = getPropValue<TypeTag, Properties::NumEq>(),
383 historySize = getPropValue<TypeTag, Properties::TimeDiscHistorySize>(),
384 };
385
386 using IntensiveQuantitiesVector = std::vector<IntensiveQuantities, aligned_allocator<IntensiveQuantities, alignof(IntensiveQuantities)> >;
387
388 using Element = typename GridView::template Codim<0>::Entity;
389 using ElementIterator = typename GridView::template Codim<0>::Iterator;
390
391 using Toolbox = MathToolbox<Evaluation>;
392 using VectorBlock = Dune::FieldVector<Evaluation, numEq>;
393 using EvalEqVector = Dune::FieldVector<Evaluation, numEq>;
394
395 using LocalEvalBlockVector = typename LocalResidual::LocalEvalBlockVector;
396
397public:
399 {
400 protected:
401 SolutionVector blockVector_;
402 public:
403 BlockVectorWrapper(const std::string&, const size_t size)
404 : blockVector_(size)
405 {}
406
408
410 {
411 BlockVectorWrapper result("dummy", 3);
412 result.blockVector_[0] = 1.0;
413 result.blockVector_[1] = 2.0;
414 result.blockVector_[2] = 3.0;
415
416 return result;
417 }
418
419 SolutionVector& blockVector()
420 { return blockVector_; }
421 const SolutionVector& blockVector() const
422 { return blockVector_; }
423
424 bool operator==(const BlockVectorWrapper& wrapper) const
425 {
426 return std::equal(this->blockVector_.begin(), this->blockVector_.end(),
427 wrapper.blockVector_.begin(), wrapper.blockVector_.end());
428 }
429
430 template<class Serializer>
431 void serializeOp(Serializer& serializer)
432 {
433 serializer(blockVector_);
434 }
435 };
436
437private:
440
441 // copying a discretization object is not a good idea
443
444public:
445 // this constructor required to be explicitly specified because
446 // we've defined a constructor above which deletes all implicitly
447 // generated constructors in C++.
448 FvBaseDiscretization(Simulator& simulator)
449 : simulator_(simulator)
450 , gridView_(simulator.gridView())
451 , elementMapper_(gridView_, Dune::mcmgElementLayout())
452 , vertexMapper_(gridView_, Dune::mcmgVertexLayout())
453 , newtonMethod_(simulator)
454 , localLinearizer_(ThreadManager::maxThreads())
455 , linearizer_(new Linearizer())
456 , enableGridAdaptation_(Parameters::get<TypeTag, Properties::EnableGridAdaptation>() )
457 , enableIntensiveQuantityCache_(Parameters::get<TypeTag, Properties::EnableIntensiveQuantityCache>())
458 , enableStorageCache_(Parameters::get<TypeTag, Properties::EnableStorageCache>())
459 , enableThermodynamicHints_(Parameters::get<TypeTag, Properties::EnableThermodynamicHints>())
460 {
461 bool isEcfv = std::is_same<Discretization, EcfvDiscretization<TypeTag> >::value;
462 if (enableGridAdaptation_ && !isEcfv)
463 throw std::invalid_argument("Grid adaptation currently only works for the "
464 "element-centered finite volume discretization (is: "
465 +Dune::className<Discretization>()+")");
466
467 enableStorageCache_ = Parameters::get<TypeTag, Properties::EnableStorageCache>();
468
469 PrimaryVariables::init();
470 size_t numDof = asImp_().numGridDof();
471 for (unsigned timeIdx = 0; timeIdx < historySize; ++timeIdx) {
473 intensiveQuantityCache_[timeIdx].resize(numDof);
474 intensiveQuantityCacheUpToDate_[timeIdx].resize(numDof, /*value=*/false);
475 }
476
478 storageCache_[timeIdx].resize(numDof);
479 }
480
482 asImp_().registerOutputModules_();
483 }
484
486 {
487 // delete all output modules
488 auto modIt = outputModules_.begin();
489 const auto& modEndIt = outputModules_.end();
490 for (; modIt != modEndIt; ++modIt)
491 delete *modIt;
492
493 delete linearizer_;
494 }
495
499 static void registerParameters()
500 {
501 Linearizer::registerParameters();
502 LocalLinearizer::registerParameters();
503 LocalResidual::registerParameters();
504 GradientCalculator::registerParameters();
505 IntensiveQuantities::registerParameters();
506 ExtensiveQuantities::registerParameters();
508 Linearizer::registerParameters();
509 PrimaryVariables::registerParameters();
510 // register runtime parameters of the output modules
512
513 Parameters::registerParam<TypeTag, Properties::EnableGridAdaptation>
514 ("Enable adaptive grid refinement/coarsening");
515 Parameters::registerParam<TypeTag, Properties::EnableVtkOutput>
516 ("Global switch for turning on writing VTK files");
517 Parameters::registerParam<TypeTag, Properties::EnableThermodynamicHints>
518 ("Enable thermodynamic hints");
519 Parameters::registerParam<TypeTag, Properties::EnableIntensiveQuantityCache>
520 ("Turn on caching of intensive quantities");
521 Parameters::registerParam<TypeTag, Properties::EnableStorageCache>
522 ("Store previous storage terms and avoid re-calculating them.");
523 Parameters::registerParam<TypeTag, Properties::OutputDir>
524 ("The directory to which result files are written");
525 }
526
531 {
532 // initialize the volume of the finite volumes to zero
533 size_t numDof = asImp_().numGridDof();
534 dofTotalVolume_.resize(numDof);
535 std::fill(dofTotalVolume_.begin(), dofTotalVolume_.end(), 0.0);
536
537 ElementContext elemCtx(simulator_);
538 gridTotalVolume_ = 0.0;
539
540 // iterate through the grid and evaluate the initial condition
541 for (const auto& elem : elements(gridView_)) {
542 const bool isInteriorElement = elem.partitionType() == Dune::InteriorEntity;
543 // ignore everything which is not in the interior if the
544 // current process' piece of the grid
545 if (!isInteriorElement)
546 continue;
547
548 // deal with the current element
549 elemCtx.updateStencil(elem);
550 const auto& stencil = elemCtx.stencil(/*timeIdx=*/0);
551
552 // loop over all element vertices, i.e. sub control volumes
553 for (unsigned dofIdx = 0; dofIdx < elemCtx.numPrimaryDof(/*timeIdx=*/0); dofIdx++) {
554 // map the local degree of freedom index to the global one
555 unsigned globalIdx = elemCtx.globalSpaceIndex(dofIdx, /*timeIdx=*/0);
556
557 Scalar dofVolume = stencil.subControlVolume(dofIdx).volume();
558 dofTotalVolume_[globalIdx] += dofVolume;
559 if (isInteriorElement)
560 gridTotalVolume_ += dofVolume;
561 }
562 }
563
564 // determine which DOFs should be considered to lie fully in the interior of the
565 // local process grid partition: those which do not have a non-zero volume
566 // before taking the peer processes into account...
567 isLocalDof_.resize(numDof);
568 for (unsigned dofIdx = 0; dofIdx < numDof; ++dofIdx)
569 isLocalDof_[dofIdx] = (dofTotalVolume_[dofIdx] != 0.0);
570
571 // add the volumes of the DOFs on the process boundaries
572 const auto sumHandle =
573 GridCommHandleFactory::template sumHandle<Scalar>(dofTotalVolume_,
574 asImp_().dofMapper());
575 gridView_.communicate(*sumHandle,
576 Dune::InteriorBorder_All_Interface,
577 Dune::ForwardCommunication);
578
579 // sum up the volumes of the grid partitions
581
582 linearizer_->init(simulator_);
583 for (unsigned threadId = 0; threadId < ThreadManager::maxThreads(); ++threadId)
584 localLinearizer_[threadId].init(simulator_);
585
588 // invalidate all cached intensive quantities
589 for (unsigned timeIdx = 0; timeIdx < historySize; ++ timeIdx)
591 }
592
593 newtonMethod_.finishInit();
594 }
595
600 { return enableGridAdaptation_; }
601
607 {
608 // first set the whole domain to zero
609 SolutionVector& uCur = asImp_().solution(/*timeIdx=*/0);
610 uCur = Scalar(0.0);
611
612 ElementContext elemCtx(simulator_);
613
614 // iterate through the grid and evaluate the initial condition
615 for (const auto& elem : elements(gridView_)) {
616 // ignore everything which is not in the interior if the
617 // current process' piece of the grid
618 if (elem.partitionType() != Dune::InteriorEntity)
619 continue;
620
621 // deal with the current element
622 elemCtx.updateStencil(elem);
623
624 // loop over all element vertices, i.e. sub control volumes
625 for (unsigned dofIdx = 0; dofIdx < elemCtx.numPrimaryDof(/*timeIdx=*/0); dofIdx++)
626 {
627 // map the local degree of freedom index to the global one
628 unsigned globalIdx = elemCtx.globalSpaceIndex(dofIdx, /*timeIdx=*/0);
629
630 // let the problem do the dirty work of nailing down
631 // the initial solution.
632 simulator_.problem().initial(uCur[globalIdx], elemCtx, dofIdx, /*timeIdx=*/0);
633 asImp_().supplementInitialSolution_(uCur[globalIdx], elemCtx, dofIdx, /*timeIdx=*/0);
634 uCur[globalIdx].checkDefined();
635 }
636 }
637
638 // synchronize the ghost DOFs (if necessary)
639 asImp_().syncOverlap();
640
641 // also set the solutions of the "previous" time steps to the initial solution.
642 for (unsigned timeIdx = 1; timeIdx < historySize; ++timeIdx)
643 solution(timeIdx) = solution(/*timeIdx=*/0);
644
645 simulator_.problem().initialSolutionApplied();
646
647#ifndef NDEBUG
648 for (unsigned timeIdx = 0; timeIdx < historySize; ++timeIdx) {
649 const auto& sol = solution(timeIdx);
650 for (unsigned dofIdx = 0; dofIdx < sol.size(); ++dofIdx)
651 sol[dofIdx].checkDefined();
652 }
653#endif // NDEBUG
654 }
655
660 void prefetch(const Element&) const
661 {
662 // do nothing by default
663 }
664
668 NewtonMethod& newtonMethod()
669 { return newtonMethod_; }
670
674 const NewtonMethod& newtonMethod() const
675 { return newtonMethod_; }
676
692 const IntensiveQuantities* thermodynamicHint(unsigned globalIdx, unsigned timeIdx) const
693 {
695 return 0;
696
697 // the intensive quantities cache doubles as thermodynamic hint
698 return cachedIntensiveQuantities(globalIdx, timeIdx);
699 }
700
712 const IntensiveQuantities* cachedIntensiveQuantities(unsigned globalIdx, unsigned timeIdx) const
713 {
715 return nullptr;
716 }
717
718 // With the storage cache enabled, usually only the
719 // intensive quantities for the most recent time step are
720 // cached. However, this may be false for some Problem
721 // variants, so we should check if the cache exists for
722 // the timeIdx in question.
723 if (timeIdx > 0 && enableStorageCache_ && intensiveQuantityCache_[timeIdx].empty()) {
724 return nullptr;
725 }
726
727 return &intensiveQuantityCache_[timeIdx][globalIdx];
728 }
729
738 void updateCachedIntensiveQuantities(const IntensiveQuantities& intQuants,
739 unsigned globalIdx,
740 unsigned timeIdx) const
741 {
743 return;
744
745 intensiveQuantityCache_[timeIdx][globalIdx] = intQuants;
746 intensiveQuantityCacheUpToDate_[timeIdx][globalIdx] = 1;
747 }
748
757 unsigned timeIdx,
758 bool newValue) const
759 {
761 return;
762
763 intensiveQuantityCacheUpToDate_[timeIdx][globalIdx] = newValue ? 1 : 0;
764 }
765
771 void invalidateIntensiveQuantitiesCache(unsigned timeIdx) const
772 {
774 std::fill(intensiveQuantityCacheUpToDate_[timeIdx].begin(),
775 intensiveQuantityCacheUpToDate_[timeIdx].end(),
776 /*value=*/0);
777 }
778 }
779
780 void invalidateAndUpdateIntensiveQuantities(unsigned timeIdx) const
781 {
783
784 // loop over all elements...
785 ThreadedEntityIterator<GridView, /*codim=*/0> threadedElemIt(gridView_);
786#ifdef _OPENMP
787#pragma omp parallel
788#endif
789 {
790 ElementContext elemCtx(simulator_);
791 ElementIterator elemIt = threadedElemIt.beginParallel();
792 for (; !threadedElemIt.isFinished(elemIt); elemIt = threadedElemIt.increment()) {
793 const Element& elem = *elemIt;
794 elemCtx.updatePrimaryStencil(elem);
795 elemCtx.updatePrimaryIntensiveQuantities(timeIdx);
796 }
797 }
798 }
799
800 template <class GridViewType>
801 void invalidateAndUpdateIntensiveQuantities(unsigned timeIdx, const GridViewType& gridView) const
802 {
803 // loop over all elements...
804 ThreadedEntityIterator<GridViewType, /*codim=*/0> threadedElemIt(gridView);
805#ifdef _OPENMP
806#pragma omp parallel
807#endif
808 {
809
810 ElementContext elemCtx(simulator_);
811 auto elemIt = threadedElemIt.beginParallel();
812 for (; !threadedElemIt.isFinished(elemIt); elemIt = threadedElemIt.increment()) {
813 if (elemIt->partitionType() != Dune::InteriorEntity) {
814 continue;
815 }
816 const Element& elem = *elemIt;
817 elemCtx.updatePrimaryStencil(elem);
818 // Mark cache for this element as invalid.
819 const std::size_t numPrimaryDof = elemCtx.numPrimaryDof(timeIdx);
820 for (unsigned dofIdx = 0; dofIdx < numPrimaryDof; ++dofIdx) {
821 const unsigned globalIndex = elemCtx.globalSpaceIndex(dofIdx, timeIdx);
822 setIntensiveQuantitiesCacheEntryValidity(globalIndex, timeIdx, false);
823 }
824 // Update for this element.
825 elemCtx.updatePrimaryIntensiveQuantities(/*timeIdx=*/0);
826 }
827 }
828 }
829
838 void shiftIntensiveQuantityCache(unsigned numSlots = 1)
839 {
841 return;
842
843 if (enableStorageCache() && simulator_.problem().recycleFirstIterationStorage()) {
844 // If the storage term is cached, the intensive quantities of the previous
845 // time steps do not need to be accessed, and we can thus spare ourselves to
846 // copy the objects for the intensive quantities.
847 // However, if the storage term at the start of the timestep cannot be deduced
848 // from the primary variables, we must calculate it from the old intensive
849 // quantities, and need to shift them.
850 return;
851 }
852
853 assert(numSlots > 0);
854
855 for (unsigned timeIdx = 0; timeIdx < historySize - numSlots; ++ timeIdx) {
856 intensiveQuantityCache_[timeIdx + numSlots] = intensiveQuantityCache_[timeIdx];
858 }
859
860 // the cache for the most recent time indices do not need to be invalidated
861 // because the solution for them did not change (TODO: that assumes that there is
862 // no post-processing of the solution after a time step! fix it?)
863 }
864
872 { return enableStorageCache_; }
873
882
893 const EqVector& cachedStorage(unsigned globalIdx, unsigned timeIdx) const
894 {
895 assert(enableStorageCache_);
896 return storageCache_[timeIdx][globalIdx];
897 }
898
910 void updateCachedStorage(unsigned globalIdx, unsigned timeIdx, const EqVector& value) const
911 {
912 assert(enableStorageCache_);
913 storageCache_[timeIdx][globalIdx] = value;
914 }
915
923 Scalar globalResidual(GlobalEqVector& dest,
924 const SolutionVector& u) const
925 {
926 SolutionVector tmp(asImp_().solution(/*timeIdx=*/0));
927 mutableSolution(/*timeIdx=*/0) = u;
928 Scalar res = asImp_().globalResidual(dest);
929 mutableSolution(/*timeIdx=*/0) = tmp;
930 return res;
931 }
932
939 Scalar globalResidual(GlobalEqVector& dest) const
940 {
941 dest = 0;
942
943 std::mutex mutex;
944 ThreadedEntityIterator<GridView, /*codim=*/0> threadedElemIt(gridView_);
945#ifdef _OPENMP
946#pragma omp parallel
947#endif
948 {
949 // Attention: the variables below are thread specific and thus cannot be
950 // moved in front of the #pragma!
951 unsigned threadId = ThreadManager::threadId();
952 ElementContext elemCtx(simulator_);
953 ElementIterator elemIt = threadedElemIt.beginParallel();
954 LocalEvalBlockVector residual, storageTerm;
955
956 for (; !threadedElemIt.isFinished(elemIt); elemIt = threadedElemIt.increment()) {
957 const Element& elem = *elemIt;
958 if (elem.partitionType() != Dune::InteriorEntity)
959 continue;
960
961 elemCtx.updateAll(elem);
962 residual.resize(elemCtx.numDof(/*timeIdx=*/0));
963 storageTerm.resize(elemCtx.numPrimaryDof(/*timeIdx=*/0));
964 asImp_().localResidual(threadId).eval(residual, elemCtx);
965
966 size_t numPrimaryDof = elemCtx.numPrimaryDof(/*timeIdx=*/0);
967 mutex.lock();
968 for (unsigned dofIdx = 0; dofIdx < numPrimaryDof; ++dofIdx) {
969 unsigned globalI = elemCtx.globalSpaceIndex(dofIdx, /*timeIdx=*/0);
970 for (unsigned eqIdx = 0; eqIdx < numEq; ++ eqIdx)
971 dest[globalI][eqIdx] += Toolbox::value(residual[dofIdx][eqIdx]);
972 }
973 mutex.unlock();
974 }
975 }
976
977 // add up the residuals on the process borders
978 const auto sumHandle =
979 GridCommHandleFactory::template sumHandle<EqVector>(dest, asImp_().dofMapper());
980 gridView_.communicate(*sumHandle,
981 Dune::InteriorBorder_InteriorBorder_Interface,
982 Dune::ForwardCommunication);
983
984 // calculate the square norm of the residual. this is not
985 // entirely correct, since the residual for the finite volumes
986 // which are on the boundary are counted once for every
987 // process. As often in life: shit happens (, we don't care)...
988 Scalar result2 = dest.two_norm2();
989 result2 = asImp_().gridView().comm().sum(result2);
990
991 return std::sqrt(result2);
992 }
993
1000 void globalStorage(EqVector& storage, unsigned timeIdx = 0) const
1001 {
1002 storage = 0;
1003
1004 std::mutex mutex;
1005 ThreadedEntityIterator<GridView, /*codim=*/0> threadedElemIt(gridView());
1006#ifdef _OPENMP
1007#pragma omp parallel
1008#endif
1009 {
1010 // Attention: the variables below are thread specific and thus cannot be
1011 // moved in front of the #pragma!
1012 unsigned threadId = ThreadManager::threadId();
1013 ElementContext elemCtx(simulator_);
1014 ElementIterator elemIt = threadedElemIt.beginParallel();
1015 LocalEvalBlockVector elemStorage;
1016
1017 // in this method, we need to disable the storage cache because we want to
1018 // evaluate the storage term for other time indices than the most recent one
1019 elemCtx.setEnableStorageCache(false);
1020
1021 for (; !threadedElemIt.isFinished(elemIt); elemIt = threadedElemIt.increment()) {
1022 const Element& elem = *elemIt;
1023 if (elem.partitionType() != Dune::InteriorEntity)
1024 continue; // ignore ghost and overlap elements
1025
1026 elemCtx.updateStencil(elem);
1027 elemCtx.updatePrimaryIntensiveQuantities(timeIdx);
1028
1029 size_t numPrimaryDof = elemCtx.numPrimaryDof(timeIdx);
1030 elemStorage.resize(numPrimaryDof);
1031
1032 localResidual(threadId).evalStorage(elemStorage, elemCtx, timeIdx);
1033
1034 mutex.lock();
1035 for (unsigned dofIdx = 0; dofIdx < numPrimaryDof; ++dofIdx)
1036 for (unsigned eqIdx = 0; eqIdx < numEq; ++eqIdx)
1037 storage[eqIdx] += Toolbox::value(elemStorage[dofIdx][eqIdx]);
1038 mutex.unlock();
1039 }
1040 }
1041
1042 storage = gridView_.comm().sum(storage);
1043 }
1044
1052 void checkConservativeness([[maybe_unused]] Scalar tolerance = -1,
1053 [[maybe_unused]] bool verbose=false) const
1054 {
1055#ifndef NDEBUG
1056 Scalar totalBoundaryArea(0.0);
1057 Scalar totalVolume(0.0);
1058 EvalEqVector totalRate(0.0);
1059
1060 // take the newton tolerance times the total volume of the grid if we're not
1061 // given an explicit tolerance...
1062 if (tolerance <= 0) {
1063 tolerance =
1064 simulator_.model().newtonMethod().tolerance()
1065 * simulator_.model().gridTotalVolume()
1066 * 1000;
1067 }
1068
1069 // we assume the implicit Euler time discretization for now...
1070 assert(historySize == 2);
1071
1072 EqVector storageBeginTimeStep(0.0);
1073 globalStorage(storageBeginTimeStep, /*timeIdx=*/1);
1074
1075 EqVector storageEndTimeStep(0.0);
1076 globalStorage(storageEndTimeStep, /*timeIdx=*/0);
1077
1078 // calculate the rate at the boundary and the source rate
1079 ElementContext elemCtx(simulator_);
1080 elemCtx.setEnableStorageCache(false);
1081 auto eIt = simulator_.gridView().template begin</*codim=*/0>();
1082 const auto& elemEndIt = simulator_.gridView().template end</*codim=*/0>();
1083 for (; eIt != elemEndIt; ++eIt) {
1084 if (eIt->partitionType() != Dune::InteriorEntity)
1085 continue; // ignore ghost and overlap elements
1086
1087 elemCtx.updateAll(*eIt);
1088
1089 // handle the boundary terms
1090 if (elemCtx.onBoundary()) {
1091 BoundaryContext boundaryCtx(elemCtx);
1092
1093 for (unsigned faceIdx = 0; faceIdx < boundaryCtx.numBoundaryFaces(/*timeIdx=*/0); ++faceIdx) {
1094 BoundaryRateVector values;
1095 simulator_.problem().boundary(values,
1096 boundaryCtx,
1097 faceIdx,
1098 /*timeIdx=*/0);
1099 Valgrind::CheckDefined(values);
1100
1101 unsigned dofIdx = boundaryCtx.interiorScvIndex(faceIdx, /*timeIdx=*/0);
1102 const auto& insideIntQuants = elemCtx.intensiveQuantities(dofIdx, /*timeIdx=*/0);
1103
1104 Scalar bfArea =
1105 boundaryCtx.boundarySegmentArea(faceIdx, /*timeIdx=*/0)
1106 * insideIntQuants.extrusionFactor();
1107
1108 for (unsigned i = 0; i < values.size(); ++i)
1109 values[i] *= bfArea;
1110
1111 totalBoundaryArea += bfArea;
1112 for (unsigned eqIdx = 0; eqIdx < numEq; ++eqIdx)
1113 totalRate[eqIdx] += values[eqIdx];
1114 }
1115 }
1116
1117 // deal with the source terms
1118 for (unsigned dofIdx = 0; dofIdx < elemCtx.numPrimaryDof(/*timeIdx=*/0); ++ dofIdx) {
1119 RateVector values;
1120 simulator_.problem().source(values,
1121 elemCtx,
1122 dofIdx,
1123 /*timeIdx=*/0);
1124 Valgrind::CheckDefined(values);
1125
1126 const auto& intQuants = elemCtx.intensiveQuantities(dofIdx, /*timeIdx=*/0);
1127 Scalar dofVolume =
1128 elemCtx.dofVolume(dofIdx, /*timeIdx=*/0)
1129 * intQuants.extrusionFactor();
1130 for (unsigned eqIdx = 0; eqIdx < numEq; ++ eqIdx)
1131 totalRate[eqIdx] += -dofVolume*Toolbox::value(values[eqIdx]);
1132 totalVolume += dofVolume;
1133 }
1134 }
1135
1136 // summarize everything over all processes
1137 const auto& comm = simulator_.gridView().comm();
1138 totalRate = comm.sum(totalRate);
1139 totalBoundaryArea = comm.sum(totalBoundaryArea);
1140 totalVolume = comm.sum(totalVolume);
1141
1142 if (comm.rank() == 0) {
1143 EqVector storageRate = storageBeginTimeStep;
1144 storageRate -= storageEndTimeStep;
1145 storageRate /= simulator_.timeStepSize();
1146 if (verbose) {
1147 std::cout << "storage at beginning of time step: " << storageBeginTimeStep << "\n";
1148 std::cout << "storage at end of time step: " << storageEndTimeStep << "\n";
1149 std::cout << "rate based on storage terms: " << storageRate << "\n";
1150 std::cout << "rate based on source and boundary terms: " << totalRate << "\n";
1151 std::cout << "difference in rates: ";
1152 for (unsigned eqIdx = 0; eqIdx < EqVector::dimension; ++eqIdx)
1153 std::cout << (storageRate[eqIdx] - Toolbox::value(totalRate[eqIdx])) << " ";
1154 std::cout << "\n";
1155 }
1156 for (unsigned eqIdx = 0; eqIdx < EqVector::dimension; ++eqIdx) {
1157 Scalar eps =
1158 (std::abs(storageRate[eqIdx]) + Toolbox::value(totalRate[eqIdx]))*tolerance;
1159 eps = std::max(tolerance, eps);
1160 assert(std::abs(storageRate[eqIdx] - Toolbox::value(totalRate[eqIdx])) <= eps);
1161 }
1162 }
1163#endif // NDEBUG
1164 }
1165
1171 Scalar dofTotalVolume(unsigned globalIdx) const
1172 { return dofTotalVolume_[globalIdx]; }
1173
1179 bool isLocalDof(unsigned globalIdx) const
1180 { return isLocalDof_[globalIdx]; }
1181
1186 Scalar gridTotalVolume() const
1187 { return gridTotalVolume_; }
1188
1194 const SolutionVector& solution(unsigned timeIdx) const
1195 { return solution_[timeIdx]->blockVector(); }
1196
1200 SolutionVector& solution(unsigned timeIdx)
1201 { return solution_[timeIdx]->blockVector(); }
1202
1203 protected:
1207 SolutionVector& mutableSolution(unsigned timeIdx) const
1208 { return solution_[timeIdx]->blockVector(); }
1209
1210 public:
1215 const Linearizer& linearizer() const
1216 { return *linearizer_; }
1217
1222 Linearizer& linearizer()
1223 { return *linearizer_; }
1224
1233 const LocalLinearizer& localLinearizer(unsigned openMpThreadId) const
1234 { return localLinearizer_[openMpThreadId]; }
1238 LocalLinearizer& localLinearizer(unsigned openMpThreadId)
1239 { return localLinearizer_[openMpThreadId]; }
1240
1244 const LocalResidual& localResidual(unsigned openMpThreadId) const
1245 { return asImp_().localLinearizer(openMpThreadId).localResidual(); }
1249 LocalResidual& localResidual(unsigned openMpThreadId)
1250 { return asImp_().localLinearizer(openMpThreadId).localResidual(); }
1251
1259 Scalar primaryVarWeight(unsigned globalDofIdx, unsigned pvIdx) const
1260 {
1261 Scalar absPv = std::abs(asImp_().solution(/*timeIdx=*/1)[globalDofIdx][pvIdx]);
1262 return 1.0/std::max(absPv, 1.0);
1263 }
1264
1271 Scalar eqWeight(unsigned, unsigned) const
1272 { return 1.0; }
1273
1283 Scalar relativeDofError(unsigned vertexIdx,
1284 const PrimaryVariables& pv1,
1285 const PrimaryVariables& pv2) const
1286 {
1287 Scalar result = 0.0;
1288 for (unsigned j = 0; j < numEq; ++j) {
1289 Scalar weight = asImp_().primaryVarWeight(vertexIdx, j);
1290 Scalar eqErr = std::abs((pv1[j] - pv2[j])*weight);
1291 //Scalar eqErr = std::abs(pv1[j] - pv2[j]);
1292 //eqErr *= std::max<Scalar>(1.0, std::abs(pv1[j] + pv2[j])/2);
1293
1294 result = std::max(result, eqErr);
1295 }
1296 return result;
1297 }
1298
1304 bool update()
1305 {
1306 TimerGuard prePostProcessGuard(prePostProcessTimer_);
1307
1308#ifndef NDEBUG
1309 for (unsigned timeIdx = 0; timeIdx < historySize; ++timeIdx) {
1310 // Make sure that the primary variables are defined. Note that because of padding
1311 // bytes, we can't just simply ask valgrind to check the whole solution vectors
1312 // for definedness...
1313 for (size_t i = 0; i < asImp_().solution(/*timeIdx=*/0).size(); ++i) {
1314 asImp_().solution(timeIdx)[i].checkDefined();
1315 }
1316 }
1317#endif // NDEBUG
1318
1319 // make sure all timers are prestine
1322 solveTimer_.halt();
1324
1326 asImp_().updateBegin();
1328
1329 bool converged = false;
1330
1331 try {
1332 converged = newtonMethod_.apply();
1333 }
1334 catch(...) {
1335 prePostProcessTimer_ += newtonMethod_.prePostProcessTimer();
1336 linearizeTimer_ += newtonMethod_.linearizeTimer();
1337 solveTimer_ += newtonMethod_.solveTimer();
1338 updateTimer_ += newtonMethod_.updateTimer();
1339
1340 throw;
1341 }
1342
1343#ifndef NDEBUG
1344 for (unsigned timeIdx = 0; timeIdx < historySize; ++timeIdx) {
1345 // Make sure that the primary variables are defined. Note that because of padding
1346 // bytes, we can't just simply ask valgrind to check the whole solution vectors
1347 // for definedness...
1348 for (size_t i = 0; i < asImp_().solution(/*timeIdx=*/0).size(); ++i) {
1349 asImp_().solution(timeIdx)[i].checkDefined();
1350 }
1351 }
1352#endif // NDEBUG
1353
1354 prePostProcessTimer_ += newtonMethod_.prePostProcessTimer();
1355 linearizeTimer_ += newtonMethod_.linearizeTimer();
1356 solveTimer_ += newtonMethod_.solveTimer();
1357 updateTimer_ += newtonMethod_.updateTimer();
1358
1360 if (converged)
1361 asImp_().updateSuccessful();
1362 else
1363 asImp_().updateFailed();
1365
1366#ifndef NDEBUG
1367 for (unsigned timeIdx = 0; timeIdx < historySize; ++timeIdx) {
1368 // Make sure that the primary variables are defined. Note that because of padding
1369 // bytes, we can't just simply ask valgrind to check the whole solution vectors
1370 // for definedness...
1371 for (size_t i = 0; i < asImp_().solution(/*timeIdx=*/0).size(); ++i) {
1372 asImp_().solution(timeIdx)[i].checkDefined();
1373 }
1374 }
1375#endif // NDEBUG
1376
1377 return converged;
1378 }
1379
1388 { }
1389
1396 { }
1397
1403 { }
1404
1409 {
1410 throw std::invalid_argument("Grid adaptation need to be implemented for "
1411 "specific settings of grid and function spaces");
1412 }
1413
1420 {
1421 // Reset the current solution to the one of the
1422 // previous time step so that we can start the next
1423 // update at a physically meaningful solution.
1424 solution(/*timeIdx=*/0) = solution(/*timeIdx=*/1);
1426
1427#ifndef NDEBUG
1428 for (unsigned timeIdx = 0; timeIdx < historySize; ++timeIdx) {
1429 // Make sure that the primary variables are defined. Note that because of padding
1430 // bytes, we can't just simply ask valgrind to check the whole solution vectors
1431 // for definedness...
1432 for (size_t i = 0; i < asImp_().solution(/*timeIdx=*/0).size(); ++i)
1433 asImp_().solution(timeIdx)[i].checkDefined();
1434 }
1435#endif // NDEBUG
1436 }
1437
1446 {
1447 // at this point we can adapt the grid
1448 if (this->enableGridAdaptation_) {
1449 asImp_().adaptGrid();
1450 }
1451
1452 // make the current solution the previous one.
1453 solution(/*timeIdx=*/1) = solution(/*timeIdx=*/0);
1454
1455 // shift the intensive quantities cache by one position in the
1456 // history
1457 asImp_().shiftIntensiveQuantityCache(/*numSlots=*/1);
1458 }
1459
1467 template <class Restarter>
1468 void serialize(Restarter&)
1469 {
1470 throw std::runtime_error("Not implemented: The discretization chosen for this problem "
1471 "does not support restart files. (serialize() method unimplemented)");
1472 }
1473
1481 template <class Restarter>
1482 void deserialize(Restarter&)
1483 {
1484 throw std::runtime_error("Not implemented: The discretization chosen for this problem "
1485 "does not support restart files. (deserialize() method unimplemented)");
1486 }
1487
1496 template <class DofEntity>
1497 void serializeEntity(std::ostream& outstream,
1498 const DofEntity& dof)
1499 {
1500 unsigned dofIdx = static_cast<unsigned>(asImp_().dofMapper().index(dof));
1501
1502 // write phase state
1503 if (!outstream.good()) {
1504 throw std::runtime_error("Could not serialize degree of freedom "
1505 +std::to_string(dofIdx));
1506 }
1507
1508 for (unsigned eqIdx = 0; eqIdx < numEq; ++eqIdx) {
1509 outstream << solution(/*timeIdx=*/0)[dofIdx][eqIdx] << " ";
1510 }
1511 }
1512
1521 template <class DofEntity>
1522 void deserializeEntity(std::istream& instream,
1523 const DofEntity& dof)
1524 {
1525 unsigned dofIdx = static_cast<unsigned>(asImp_().dofMapper().index(dof));
1526
1527 for (unsigned eqIdx = 0; eqIdx < numEq; ++eqIdx) {
1528 if (!instream.good())
1529 throw std::runtime_error("Could not deserialize degree of freedom "
1530 +std::to_string(dofIdx));
1531 instream >> solution(/*timeIdx=*/0)[dofIdx][eqIdx];
1532 }
1533 }
1534
1538 size_t numGridDof() const
1539 { throw std::logic_error("The discretization class must implement the numGridDof() method!"); }
1540
1544 size_t numAuxiliaryDof() const
1545 {
1546 size_t result = 0;
1547 auto auxModIt = auxEqModules_.begin();
1548 const auto& auxModEndIt = auxEqModules_.end();
1549 for (; auxModIt != auxModEndIt; ++auxModIt)
1550 result += (*auxModIt)->numDofs();
1551
1552 return result;
1553 }
1554
1558 size_t numTotalDof() const
1559 { return asImp_().numGridDof() + numAuxiliaryDof(); }
1560
1565 const DofMapper& dofMapper() const
1566 { throw std::logic_error("The discretization class must implement the dofMapper() method!"); }
1567
1571 const VertexMapper& vertexMapper() const
1572 { return vertexMapper_; }
1573
1577 const ElementMapper& elementMapper() const
1578 { return elementMapper_; }
1579
1585 {
1586 delete linearizer_;
1587 linearizer_ = new Linearizer;
1588 linearizer_->init(simulator_);
1589 }
1590
1594 static std::string discretizationName()
1595 { return ""; }
1596
1602 std::string primaryVarName(unsigned pvIdx) const
1603 {
1604 std::ostringstream oss;
1605 oss << "primary variable_" << pvIdx;
1606 return oss.str();
1607 }
1608
1614 std::string eqName(unsigned eqIdx) const
1615 {
1616 std::ostringstream oss;
1617 oss << "equation_" << eqIdx;
1618 return oss.str();
1619 }
1620
1627 void updatePVWeights(const ElementContext&) const
1628 { }
1629
1634 { outputModules_.push_back(newModule); }
1635
1644 template <class VtkMultiWriter>
1646 const SolutionVector& u,
1647 const GlobalEqVector& deltaU) const
1648 {
1649 using ScalarBuffer = std::vector<double>;
1650
1651 GlobalEqVector globalResid(u.size());
1652 asImp_().globalResidual(globalResid, u);
1653
1654 // create the required scalar fields
1655 size_t numGridDof = asImp_().numGridDof();
1656
1657 // global defect of the two auxiliary equations
1658 ScalarBuffer* def[numEq];
1659 ScalarBuffer* delta[numEq];
1660 ScalarBuffer* priVars[numEq];
1661 ScalarBuffer* priVarWeight[numEq];
1662 ScalarBuffer* relError = writer.allocateManagedScalarBuffer(numGridDof);
1663 ScalarBuffer* normalizedRelError = writer.allocateManagedScalarBuffer(numGridDof);
1664 for (unsigned pvIdx = 0; pvIdx < numEq; ++pvIdx) {
1665 priVars[pvIdx] = writer.allocateManagedScalarBuffer(numGridDof);
1666 priVarWeight[pvIdx] = writer.allocateManagedScalarBuffer(numGridDof);
1667 delta[pvIdx] = writer.allocateManagedScalarBuffer(numGridDof);
1668 def[pvIdx] = writer.allocateManagedScalarBuffer(numGridDof);
1669 }
1670
1671 Scalar minRelErr = 1e30;
1672 Scalar maxRelErr = -1e30;
1673 for (unsigned globalIdx = 0; globalIdx < numGridDof; ++ globalIdx) {
1674 for (unsigned pvIdx = 0; pvIdx < numEq; ++pvIdx) {
1675 (*priVars[pvIdx])[globalIdx] = u[globalIdx][pvIdx];
1676 (*priVarWeight[pvIdx])[globalIdx] = asImp_().primaryVarWeight(globalIdx, pvIdx);
1677 (*delta[pvIdx])[globalIdx] = - deltaU[globalIdx][pvIdx];
1678 (*def[pvIdx])[globalIdx] = globalResid[globalIdx][pvIdx];
1679 }
1680
1681 PrimaryVariables uOld(u[globalIdx]);
1682 PrimaryVariables uNew(uOld);
1683 uNew -= deltaU[globalIdx];
1684
1685 Scalar err = asImp_().relativeDofError(globalIdx, uOld, uNew);
1686 (*relError)[globalIdx] = err;
1687 (*normalizedRelError)[globalIdx] = err;
1688 minRelErr = std::min(err, minRelErr);
1689 maxRelErr = std::max(err, maxRelErr);
1690 }
1691
1692 // do the normalization of the relative error
1693 Scalar alpha = std::max(1e-20,
1694 std::max(std::abs(maxRelErr),
1695 std::abs(minRelErr)));
1696 for (unsigned globalIdx = 0; globalIdx < numGridDof; ++ globalIdx)
1697 (*normalizedRelError)[globalIdx] /= alpha;
1698
1699 DiscBaseOutputModule::attachScalarDofData_(writer, *relError, "relative error");
1700 DiscBaseOutputModule::attachScalarDofData_(writer, *normalizedRelError, "normalized relative error");
1701
1702 for (unsigned i = 0; i < numEq; ++i) {
1703 std::ostringstream oss;
1704 oss.str(""); oss << "priVar_" << asImp_().primaryVarName(i);
1705 DiscBaseOutputModule::attachScalarDofData_(writer,
1706 *priVars[i],
1707 oss.str());
1708
1709 oss.str(""); oss << "delta_" << asImp_().primaryVarName(i);
1710 DiscBaseOutputModule::attachScalarDofData_(writer,
1711 *delta[i],
1712 oss.str());
1713
1714 oss.str(""); oss << "weight_" << asImp_().primaryVarName(i);
1715 DiscBaseOutputModule::attachScalarDofData_(writer,
1716 *priVarWeight[i],
1717 oss.str());
1718
1719 oss.str(""); oss << "defect_" << asImp_().eqName(i);
1720 DiscBaseOutputModule::attachScalarDofData_(writer,
1721 *def[i],
1722 oss.str());
1723 }
1724
1725 asImp_().prepareOutputFields();
1726 asImp_().appendOutputFields(writer);
1727 }
1728
1734 {
1735 bool needFullContextUpdate = false;
1736 auto modIt = outputModules_.begin();
1737 const auto& modEndIt = outputModules_.end();
1738 for (; modIt != modEndIt; ++modIt) {
1739 (*modIt)->allocBuffers();
1740 needFullContextUpdate = needFullContextUpdate || (*modIt)->needExtensiveQuantities();
1741 }
1742
1743 // iterate over grid
1744 ThreadedEntityIterator<GridView, /*codim=*/0> threadedElemIt(gridView());
1745#ifdef _OPENMP
1746#pragma omp parallel
1747#endif
1748 {
1749 ElementContext elemCtx(simulator_);
1750 ElementIterator elemIt = threadedElemIt.beginParallel();
1751 for (; !threadedElemIt.isFinished(elemIt); elemIt = threadedElemIt.increment()) {
1752 const auto& elem = *elemIt;
1753 if (elem.partitionType() != Dune::InteriorEntity)
1754 // ignore non-interior entities
1755 continue;
1756
1757 if (needFullContextUpdate)
1758 elemCtx.updateAll(elem);
1759 else {
1760 elemCtx.updatePrimaryStencil(elem);
1761 elemCtx.updatePrimaryIntensiveQuantities(/*timeIdx=*/0);
1762 }
1763
1764 // we cannot reuse the "modIt" variable here because the code here might
1765 // be threaded and "modIt" is is the same for all threads, i.e., if a
1766 // given thread modifies it, the changes affect all threads.
1767 auto modIt2 = outputModules_.begin();
1768 for (; modIt2 != modEndIt; ++modIt2)
1769 (*modIt2)->processElement(elemCtx);
1770 }
1771 }
1772 }
1773
1779 {
1780 auto modIt = outputModules_.begin();
1781 const auto& modEndIt = outputModules_.end();
1782 for (; modIt != modEndIt; ++modIt)
1783 (*modIt)->commitBuffers(writer);
1784 }
1785
1789 const GridView& gridView() const
1790 { return gridView_; }
1791
1804 {
1805 auxMod->setDofOffset(numTotalDof());
1806 auxEqModules_.push_back(auxMod);
1807
1808 // resize the solutions
1810 && !std::is_same<DiscreteFunction, BlockVectorWrapper>::value)
1811 {
1812 throw std::invalid_argument("Problems which require auxiliary modules cannot be used in"
1813 " conjunction with dune-fem");
1814 }
1815
1816 size_t numDof = numTotalDof();
1817 for (unsigned timeIdx = 0; timeIdx < historySize; ++timeIdx)
1818 solution(timeIdx).resize(numDof);
1819
1820 auxMod->applyInitial();
1821 }
1822
1829 {
1830 auxEqModules_.clear();
1831 linearizer_->eraseMatrix();
1832 newtonMethod_.eraseMatrix();
1833 }
1834
1838 size_t numAuxiliaryModules() const
1839 { return auxEqModules_.size(); }
1840
1845 { return auxEqModules_[auxEqModIdx]; }
1846
1850 const BaseAuxiliaryModule<TypeTag>* auxiliaryModule(unsigned auxEqModIdx) const
1851 { return auxEqModules_[auxEqModIdx]; }
1852
1858
1860 { return prePostProcessTimer_; }
1861
1862 const Timer& linearizeTimer() const
1863 { return linearizeTimer_; }
1864
1865 const Timer& solveTimer() const
1866 { return solveTimer_; }
1867
1868 const Timer& updateTimer() const
1869 { return updateTimer_; }
1870
1871 template<class Serializer>
1872 void serializeOp(Serializer& serializer)
1873 {
1875 using Helper = typename BaseDiscretization::template SerializeHelper<Serializer>;
1876 Helper::serializeOp(serializer, solution_);
1877 }
1878
1879 bool operator==(const FvBaseDiscretization& rhs) const
1880 {
1881 return std::equal(this->solution_.begin(), this->solution_.end(),
1882 rhs.solution_.begin(), rhs.solution_.end(),
1883 [](const auto& x, const auto& y)
1884 {
1885 return *x == *y;
1886 });
1887 }
1888
1889protected:
1891 {
1892 // allocate the storage cache
1893 if (enableStorageCache()) {
1894 size_t numDof = asImp_().numGridDof();
1895 for (unsigned timeIdx = 0; timeIdx < historySize; ++timeIdx) {
1896 storageCache_[timeIdx].resize(numDof);
1897 }
1898 }
1899
1900 // allocate the intensive quantities cache
1902 size_t numDof = asImp_().numGridDof();
1903 for(unsigned timeIdx=0; timeIdx<historySize; ++timeIdx) {
1904 intensiveQuantityCache_[timeIdx].resize(numDof);
1905 intensiveQuantityCacheUpToDate_[timeIdx].resize(numDof);
1907 }
1908 }
1909 }
1910 template <class Context>
1911 void supplementInitialSolution_(PrimaryVariables&,
1912 const Context&,
1913 unsigned,
1914 unsigned)
1915 { }
1916
1925 {
1926 // add the output modules available on all model
1928 this->outputModules_.push_back(mod);
1929 }
1930
1934 LocalResidual& localResidual_()
1935 { return localLinearizer_.localResidual(); }
1936
1940 bool verbose_() const
1941 { return gridView_.comm().rank() == 0; }
1942
1943 Implementation& asImp_()
1944 { return *static_cast<Implementation*>(this); }
1945 const Implementation& asImp_() const
1946 { return *static_cast<const Implementation*>(this); }
1947
1948 // the problem we want to solve. defines the constitutive
1949 // relations, matxerial laws, etc.
1950 Simulator& simulator_;
1951
1952 // the representation of the spatial domain of the problem
1953 GridView gridView_;
1954
1955 // the mappers for element and vertex entities to global indices
1956 ElementMapper elementMapper_;
1957 VertexMapper vertexMapper_;
1958
1959 // a vector with all auxiliary equations to be considered
1960 std::vector<BaseAuxiliaryModule<TypeTag>*> auxEqModules_;
1961
1962 NewtonMethod newtonMethod_;
1963
1968
1969 // calculates the local jacobian matrix for a given element
1970 std::vector<LocalLinearizer> localLinearizer_;
1971 // Linearizes the problem at the current time step using the
1972 // local jacobian
1973 Linearizer *linearizer_;
1974
1975 // cur is the current iterative solution, prev the converged
1976 // solution of the previous time step
1977 mutable IntensiveQuantitiesVector intensiveQuantityCache_[historySize];
1978 // while these are logically bools, concurrent writes to vector<bool> are not thread safe.
1979 mutable std::vector<unsigned char> intensiveQuantityCacheUpToDate_[historySize];
1980
1981 mutable std::array< std::unique_ptr< DiscreteFunction >, historySize > solution_;
1982
1983 std::list<BaseOutputModule<TypeTag>*> outputModules_;
1984
1986 std::vector<Scalar> dofTotalVolume_;
1987 std::vector<bool> isLocalDof_;
1988
1989 mutable GlobalEqVector storageCache_[historySize];
1990
1995};
1996
2002template<class TypeTag>
2004{
2008
2009 static constexpr unsigned historySize = getPropValue<TypeTag, Properties::TimeDiscHistorySize>();
2010
2011public:
2012 template<class Serializer>
2014 template<class SolutionType>
2015 static void serializeOp(Serializer& serializer,
2016 SolutionType& solution)
2017 {
2018 for (auto& sol : solution) {
2019 serializer(*sol);
2020 }
2021 }
2022 };
2023
2024 FvBaseDiscretizationNoAdapt(Simulator& simulator)
2025 : ParentType(simulator)
2026 {
2027 if (this->enableGridAdaptation_) {
2028 throw std::invalid_argument("Grid adaptation need to use"
2029 " BaseDiscretization = FvBaseDiscretizationFemAdapt"
2030 " which currently requires the presence of the"
2031 " dune-fem module");
2032 }
2033 size_t numDof = this->asImp_().numGridDof();
2034 for (unsigned timeIdx = 0; timeIdx < historySize; ++timeIdx) {
2035 this->solution_[timeIdx] = std::make_unique<DiscreteFunction>("solution", numDof);
2036 }
2037 }
2038};
2039
2040} // namespace Opm
2041
2042#endif // EWOMS_FV_BASE_DISCRETIZATION_HH
This is a stand-alone version of boost::alignment::aligned_allocator from Boost 1....
Base class for specifying auxiliary equations.
Definition: baseauxiliarymodule.hh:56
virtual void applyInitial()=0
Set the initial condition of the auxiliary module in the solution vector.
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:79
The base class for writer modules.
Definition: baseoutputmodule.hh:73
The base class for all output writers.
Definition: baseoutputwriter.hh:44
Represents all quantities which available on boundary segments.
Definition: fvbaseboundarycontext.hh:44
Represents all quantities which available for calculating constraints.
Definition: fvbaseconstraintscontext.hh:44
Class to specify constraints for a finite volume spatial discretization.
Definition: fvbaseconstraints.hh:46
Definition: fvbasediscretization.hh:399
const SolutionVector & blockVector() const
Definition: fvbasediscretization.hh:421
SolutionVector blockVector_
Definition: fvbasediscretization.hh:401
BlockVectorWrapper(const std::string &, const size_t size)
Definition: fvbasediscretization.hh:403
void serializeOp(Serializer &serializer)
Definition: fvbasediscretization.hh:431
static BlockVectorWrapper serializationTestObject()
Definition: fvbasediscretization.hh:409
SolutionVector & blockVector()
Definition: fvbasediscretization.hh:419
bool operator==(const BlockVectorWrapper &wrapper) const
Definition: fvbasediscretization.hh:424
The base class for the finite volume discretization schemes without adaptation.
Definition: fvbasediscretization.hh:2004
FvBaseDiscretizationNoAdapt(Simulator &simulator)
Definition: fvbasediscretization.hh:2024
The base class for the finite volume discretization schemes.
Definition: fvbasediscretization.hh:349
Timer linearizeTimer_
Definition: fvbasediscretization.hh:1965
LocalLinearizer & localLinearizer(unsigned openMpThreadId)
Definition: fvbasediscretization.hh:1238
size_t numAuxiliaryDof() const
Returns the number of degrees of freedom (DOFs) of the auxiliary equations.
Definition: fvbasediscretization.hh:1544
void prepareOutputFields() const
Prepare the quantities relevant for the current solution to be appended to the output writers.
Definition: fvbasediscretization.hh:1733
void shiftIntensiveQuantityCache(unsigned numSlots=1)
Move the intensive quantities for a given time index to the back.
Definition: fvbasediscretization.hh:838
void invalidateAndUpdateIntensiveQuantities(unsigned timeIdx) const
Definition: fvbasediscretization.hh:780
void adaptGrid()
Called by the update() method when the grid should be refined.
Definition: fvbasediscretization.hh:1408
std::vector< BaseAuxiliaryModule< TypeTag > * > auxEqModules_
Definition: fvbasediscretization.hh:1960
~FvBaseDiscretization()
Definition: fvbasediscretization.hh:485
const Implementation & asImp_() const
Definition: fvbasediscretization.hh:1945
void addAuxiliaryModule(BaseAuxiliaryModule< TypeTag > *auxMod)
Add a module for an auxiliary equation.
Definition: fvbasediscretization.hh:1803
void setIntensiveQuantitiesCacheEntryValidity(unsigned globalIdx, unsigned timeIdx, bool newValue) const
Invalidate the cache for a given intensive quantities object.
Definition: fvbasediscretization.hh:756
void finishInit()
Apply the initial conditions to the model.
Definition: fvbasediscretization.hh:530
void prefetch(const Element &) const
Allows to improve the performance by prefetching all data which is associated with a given element.
Definition: fvbasediscretization.hh:660
bool enableStorageCache_
Definition: fvbasediscretization.hh:1993
void resizeAndResetIntensiveQuantitiesCache_()
Definition: fvbasediscretization.hh:1890
std::vector< Scalar > dofTotalVolume_
Definition: fvbasediscretization.hh:1986
void updateSuccessful()
Called by the update() method if it was successful.
Definition: fvbasediscretization.hh:1402
static std::string discretizationName()
Returns a string of discretization's human-readable name.
Definition: fvbasediscretization.hh:1594
BaseAuxiliaryModule< TypeTag > * auxiliaryModule(unsigned auxEqModIdx)
Returns a given module for auxiliary equations.
Definition: fvbasediscretization.hh:1844
bool isLocalDof(unsigned globalIdx) const
Returns if the overlap of the volume ofa degree of freedom is non-zero.
Definition: fvbasediscretization.hh:1179
bool operator==(const FvBaseDiscretization &rhs) const
Definition: fvbasediscretization.hh:1879
void serializeOp(Serializer &serializer)
Definition: fvbasediscretization.hh:1872
std::vector< bool > isLocalDof_
Definition: fvbasediscretization.hh:1987
LocalResidual & localResidual_()
Reference to the local residal object.
Definition: fvbasediscretization.hh:1934
void registerOutputModules_()
Register all output modules which make sense for the model.
Definition: fvbasediscretization.hh:1924
bool enableGridAdaptation() const
Returns whether the grid ought to be adapted to the solution during the simulation.
Definition: fvbasediscretization.hh:599
const NewtonMethod & newtonMethod() const
Returns the newton method object.
Definition: fvbasediscretization.hh:674
SolutionVector & mutableSolution(unsigned timeIdx) const
Definition: fvbasediscretization.hh:1207
void advanceTimeLevel()
Called by the problem if a time integration was successful, post processing of the solution is done a...
Definition: fvbasediscretization.hh:1445
NewtonMethod & newtonMethod()
Returns the newton method object.
Definition: fvbasediscretization.hh:668
const VertexMapper & vertexMapper() const
Returns the mapper for vertices to indices.
Definition: fvbasediscretization.hh:1571
const EqVector & cachedStorage(unsigned globalIdx, unsigned timeIdx) const
Retrieve an entry of the cache for the storage term.
Definition: fvbasediscretization.hh:893
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:1627
const Timer & solveTimer() const
Definition: fvbasediscretization.hh:1865
void updateFailed()
Called by the update() method if it was unsuccessful. This is primary a hook which the actual model c...
Definition: fvbasediscretization.hh:1419
void updateBegin()
Called by the update() method before it tries to apply the newton method. This is primary a hook whic...
Definition: fvbasediscretization.hh:1395
Scalar globalResidual(GlobalEqVector &dest) const
Compute the global residual for the current solution vector.
Definition: fvbasediscretization.hh:939
LocalResidual & localResidual(unsigned openMpThreadId)
Definition: fvbasediscretization.hh:1249
void serializeEntity(std::ostream &outstream, const DofEntity &dof)
Write the current solution for a degree of freedom to a restart file.
Definition: fvbasediscretization.hh:1497
void setEnableStorageCache(bool enableStorageCache)
Set the value of enable storage cache.
Definition: fvbasediscretization.hh:880
std::string eqName(unsigned eqIdx) const
Given an equation index, return a human readable name.
Definition: fvbasediscretization.hh:1614
std::list< BaseOutputModule< TypeTag > * > outputModules_
Definition: fvbasediscretization.hh:1983
Scalar eqWeight(unsigned, unsigned) const
Returns the relative weight of an equation.
Definition: fvbasediscretization.hh:1271
const Timer & prePostProcessTimer() const
Definition: fvbasediscretization.hh:1859
Scalar primaryVarWeight(unsigned globalDofIdx, unsigned pvIdx) const
Returns the relative weight of a primary variable for calculating relative errors.
Definition: fvbasediscretization.hh:1259
void deserialize(Restarter &)
Deserializes the state of the model.
Definition: fvbasediscretization.hh:1482
void checkConservativeness(Scalar tolerance=-1, 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:1052
std::array< std::unique_ptr< DiscreteFunction >, historySize > solution_
Definition: fvbasediscretization.hh:1981
Scalar gridTotalVolume() const
Returns the volume of the whole grid which represents the spatial domain.
Definition: fvbasediscretization.hh:1186
Timer updateTimer_
Definition: fvbasediscretization.hh:1967
FvBaseDiscretization(Simulator &simulator)
Definition: fvbasediscretization.hh:448
const IntensiveQuantities * thermodynamicHint(unsigned globalIdx, unsigned timeIdx) const
Return the thermodynamic hint for a entity on the grid at given time.
Definition: fvbasediscretization.hh:692
const Timer & updateTimer() const
Definition: fvbasediscretization.hh:1868
const Linearizer & linearizer() const
Returns the operator linearizer for the global jacobian of the problem.
Definition: fvbasediscretization.hh:1215
void updateCachedStorage(unsigned globalIdx, unsigned timeIdx, const EqVector &value) const
Set an entry of the cache for the storage term.
Definition: fvbasediscretization.hh:910
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:1645
Scalar relativeDofError(unsigned vertexIdx, const PrimaryVariables &pv1, const PrimaryVariables &pv2) const
Returns the relative error between two vectors of primary variables.
Definition: fvbasediscretization.hh:1283
bool enableGridAdaptation_
Definition: fvbasediscretization.hh:1991
Scalar globalResidual(GlobalEqVector &dest, const SolutionVector &u) const
Compute the global residual for an arbitrary solution vector.
Definition: fvbasediscretization.hh:923
SolutionVector & solution(unsigned timeIdx)
Definition: fvbasediscretization.hh:1200
void addOutputModule(BaseOutputModule< TypeTag > *newModule)
Add an module for writing visualization output after a timestep.
Definition: fvbasediscretization.hh:1633
Timer prePostProcessTimer_
Definition: fvbasediscretization.hh:1964
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:1522
Timer solveTimer_
Definition: fvbasediscretization.hh:1966
void supplementInitialSolution_(PrimaryVariables &, const Context &, unsigned, unsigned)
Definition: fvbasediscretization.hh:1911
const LocalLinearizer & localLinearizer(unsigned openMpThreadId) const
Returns the local jacobian which calculates the local stiffness matrix for an arbitrary element.
Definition: fvbasediscretization.hh:1233
const Timer & linearizeTimer() const
Definition: fvbasediscretization.hh:1862
void invalidateAndUpdateIntensiveQuantities(unsigned timeIdx, const GridViewType &gridView) const
Definition: fvbasediscretization.hh:801
bool update()
Try to progress the model to the next timestep.
Definition: fvbasediscretization.hh:1304
void clearAuxiliaryModules()
Causes the list of auxiliary equations to be cleared.
Definition: fvbasediscretization.hh:1828
bool enableIntensiveQuantityCache_
Definition: fvbasediscretization.hh:1992
std::vector< unsigned char > intensiveQuantityCacheUpToDate_[historySize]
Definition: fvbasediscretization.hh:1979
const ElementMapper & elementMapper() const
Returns the mapper for elements to indices.
Definition: fvbasediscretization.hh:1577
size_t numGridDof() const
Returns the number of degrees of freedom (DOFs) for the computational grid.
Definition: fvbasediscretization.hh:1538
void syncOverlap()
Syncronize the values of the primary variables on the degrees of freedom that overlap with the neighb...
Definition: fvbasediscretization.hh:1387
void appendOutputFields(BaseOutputWriter &writer) const
Append the quantities relevant for the current solution to an output writer.
Definition: fvbasediscretization.hh:1778
ElementMapper elementMapper_
Definition: fvbasediscretization.hh:1956
NewtonMethod newtonMethod_
Definition: fvbasediscretization.hh:1962
void applyInitialSolution()
Applies the initial solution for all degrees of freedom to which the model applies.
Definition: fvbasediscretization.hh:606
Implementation & asImp_()
Definition: fvbasediscretization.hh:1943
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:738
std::string primaryVarName(unsigned pvIdx) const
Given an primary variable index, return a human readable name.
Definition: fvbasediscretization.hh:1602
GlobalEqVector storageCache_[historySize]
Definition: fvbasediscretization.hh:1989
void invalidateIntensiveQuantitiesCache(unsigned timeIdx) const
Invalidate the whole intensive quantity cache for time index.
Definition: fvbasediscretization.hh:771
Linearizer & linearizer()
Returns the object which linearizes the global system of equations at the current solution.
Definition: fvbasediscretization.hh:1222
const BaseAuxiliaryModule< TypeTag > * auxiliaryModule(unsigned auxEqModIdx) const
Returns a given module for auxiliary equations.
Definition: fvbasediscretization.hh:1850
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:1000
Linearizer * linearizer_
Definition: fvbasediscretization.hh:1973
GridView gridView_
Definition: fvbasediscretization.hh:1953
Scalar dofTotalVolume(unsigned globalIdx) const
Returns the volume of a given control volume.
Definition: fvbasediscretization.hh:1171
static void registerParameters()
Register all run-time parameters for the model.
Definition: fvbasediscretization.hh:499
const SolutionVector & solution(unsigned timeIdx) const
Reference to the solution at a given history index as a block vector.
Definition: fvbasediscretization.hh:1194
bool verbose_() const
Returns whether messages should be printed.
Definition: fvbasediscretization.hh:1940
Simulator & simulator_
Definition: fvbasediscretization.hh:1950
const LocalResidual & localResidual(unsigned openMpThreadId) const
Returns the object to calculate the local residual function.
Definition: fvbasediscretization.hh:1244
Scalar gridTotalVolume_
Definition: fvbasediscretization.hh:1985
const DofMapper & dofMapper() const
Mapper to convert the Dune entities of the discretization's degrees of freedoms are to indices.
Definition: fvbasediscretization.hh:1565
bool storeIntensiveQuantities() const
Returns true if the cache for intensive quantities is enabled.
Definition: fvbasediscretization.hh:1856
std::vector< LocalLinearizer > localLinearizer_
Definition: fvbasediscretization.hh:1970
void serialize(Restarter &)
Serializes the current state of the model.
Definition: fvbasediscretization.hh:1468
IntensiveQuantitiesVector intensiveQuantityCache_[historySize]
Definition: fvbasediscretization.hh:1977
bool enableThermodynamicHints_
Definition: fvbasediscretization.hh:1994
size_t numTotalDof() const
Returns the total number of degrees of freedom (i.e., grid plux auxiliary DOFs)
Definition: fvbasediscretization.hh:1558
VertexMapper vertexMapper_
Definition: fvbasediscretization.hh:1957
void resetLinearizer()
Resets the Jacobian matrix linearizer, so that the boundary types can be altered.
Definition: fvbasediscretization.hh:1584
bool enableStorageCache() const
Returns true iff the storage term is cached.
Definition: fvbasediscretization.hh:871
size_t numAuxiliaryModules() const
Returns the number of modules for auxiliary equations.
Definition: fvbasediscretization.hh:1838
const GridView & gridView() const
Reference to the grid view of the spatial domain.
Definition: fvbasediscretization.hh:1789
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:712
This class stores an array of IntensiveQuantities objects, one intensive quantities object for each o...
Definition: fvbaseelementcontext.hh:50
Provide the properties at a face which make sense indepentently of the conserved quantities.
Definition: fvbaseextensivequantities.hh:46
This class calculates gradients of arbitrary quantities at flux integration points using the two-poin...
Definition: fvbasegradientcalculator.hh:47
Base class for the model specific class which provides access to all intensive (i....
Definition: fvbaseintensivequantities.hh:45
The common code for the linearizers of non-linear systems of equations.
Definition: fvbaselinearizer.hh:71
Element-wise caculation of the residual matrix for models based on a finite volume spatial discretiza...
Definition: fvbaselocalresidual.hh:58
Represents the primary variables used by the a model.
Definition: fvbaseprimaryvariables.hh:52
This is a grid manager which does not create any border list.
Definition: nullborderlistmanager.hh:44
static void registerParameters()
Register all run-time parameters for the Newton method.
Definition: newtonmethod.hh:150
Manages the initializing and running of time dependent problems.
Definition: simulator.hh:102
Simplifies multi-threaded capabilities.
Definition: threadmanager.hh:47
static unsigned maxThreads()
Return the maximum number of threads of the current process.
Definition: threadmanager.hh:118
static unsigned threadId()
Return the index of the current OpenMP thread.
Definition: threadmanager.hh:124
Provides an STL-iterator like interface to iterate over the enties of a GridView in OpenMP threaded a...
Definition: threadedentityiterator.hh:43
bool isFinished(const EntityIterator &it) const
Definition: threadedentityiterator.hh:67
EntityIterator increment()
Definition: threadedentityiterator.hh:80
EntityIterator beginParallel()
Definition: threadedentityiterator.hh:55
A simple class which makes sure that a timer gets stopped if an exception is thrown.
Definition: timerguard.hh:41
Provides an encapsulation to measure the system time.
Definition: timer.hh:49
void start()
Start counting the time resources used by the simulation.
Definition: timer.hh:62
void halt()
Stop the measurement reset all timing values.
Definition: timer.hh:99
double stop()
Stop counting the time resources.
Definition: timer.hh:73
Simplifies writing multi-file VTK datasets.
Definition: vtkmultiwriter.hh:66
ScalarBuffer * allocateManagedScalarBuffer(size_t numEntities)
Allocate a managed buffer for a scalar field.
Definition: vtkmultiwriter.hh:203
VTK output module for the fluid composition.
Definition: vtkprimaryvarsmodule.hh:71
static void registerParameters()
Register all run-time parameters for the Vtk output module.
Definition: vtkprimaryvarsmodule.hh:94
Definition: alignedallocator.hh:114
Declare the properties used by the infrastructure code of the finite volume discretizations.
Provides data handles for parallel communication which operate on DOFs.
auto get(bool errorIfNotRegistered=true)
Retrieve a runtime parameter.
Definition: parametersystem.hh:835
Definition: fvbaseprimaryvariables.hh:141
Definition: blackoilmodel.hh:72
Definition: blackoilboundaryratevector.hh:37
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:242
Definition: fvbasediscretization.hh:2013
static void serializeOp(Serializer &serializer, SolutionType &solution)
Definition: fvbasediscretization.hh:2015
Definition: fvbasediscretization.hh:322
GetPropType< TypeTag, Properties::GridView > GridView
Definition: fvbasediscretization.hh:106
GetPropType< TypeTag, Properties::DofMapper > DofMapper
Definition: fvbasediscretization.hh:105
The class which marks the border indices associated with the degrees of freedom on a process boundary...
Definition: basicproperties.hh:182
The secondary variables of a boundary segment.
Definition: fvbaseproperties.hh:160
GetPropType< TypeTag, Properties::RateVector > type
Definition: fvbasediscretization.hh:157
Type of object for specifying boundary conditions.
Definition: fvbaseproperties.hh:136
The secondary variables of a constraint degree of freedom.
Definition: fvbaseproperties.hh:163
The class which represents a constraint degree of freedom.
Definition: fvbaseproperties.hh:139
Continue with a non-converged solution instead of giving up if we encounter a time step size smaller ...
Definition: fvbaseproperties.hh:285
The part of the extensive quantities which is specific to the spatial discretization.
Definition: fvbaseproperties.hh:177
The discretization specific part of the intensive quantities.
Definition: fvbaseproperties.hh:153
The discretization specific part of the local residual.
Definition: fvbaseproperties.hh:108
typename BaseDiscretization::BlockVectorWrapper type
Definition: fvbasediscretization.hh:334
Definition: fvbaseproperties.hh:94
The secondary variables of all degrees of freedom in an element's stencil.
Definition: fvbaseproperties.hh:157
Dune::BlockVector< GetPropType< TypeTag, Properties::EqVector > > type
Definition: fvbasediscretization.hh:170
A vector of holding a quantity for each equation for each DOF of an element.
Definition: fvbaseproperties.hh:129
Dune::MultipleCodimMultipleGeomTypeMapper< GetPropType< TypeTag, Properties::GridView > > type
Definition: fvbasediscretization.hh:99
The mapper to find the global index of an element.
Definition: fvbaseproperties.hh:331
Determines if the VTK output is written to disk asynchronously.
Definition: fvbaseproperties.hh:238
Specify whether the some degrees of fredom can be constraint.
Definition: fvbaseproperties.hh:254
Specify if experimental features should be enabled or not.
Definition: fvbaseproperties.hh:360
Switch to enable or disable grid adaptation.
Definition: fvbaseproperties.hh:211
Specify whether all intensive quantities for the grid should be cached in the discretization.
Definition: fvbaseproperties.hh:297
Specify whether the storage terms for previous solutions should be cached.
Definition: fvbaseproperties.hh:306
Specify whether to use the already calculated solutions as starting values of the intensive quantitie...
Definition: fvbaseproperties.hh:317
Global switch to enable or disable the writing of VTK output files.
Definition: fvbaseproperties.hh:226
Dune::FieldVector< GetPropType< TypeTag, Properties::Scalar >, getPropValue< TypeTag, Properties::NumEq >()> type
Definition: fvbasediscretization.hh:141
A vector of holding a quantity for each equation (usually at a given spatial location)
Definition: fvbaseproperties.hh:126
Specify whether the storage terms use extensive quantities or not.
Definition: fvbaseproperties.hh:351
Dune::BlockVector< GetPropType< TypeTag, Properties::EqVector > > type
Definition: fvbasediscretization.hh:177
Vector containing a quantity of for equation for each DOF of the whole grid.
Definition: linalgproperties.hh:103
Calculates gradients of arbitrary quantities at flux integration points.
Definition: fvbaseproperties.hh:169
The secondary variables within a sub-control volume.
Definition: fvbaseproperties.hh:150
GetPropType< TypeTag, Scalar > type
Definition: fvbasediscretization.hh:299
Maximum accepted error of the norm of the residual.
Definition: linalgproperties.hh:69
GetPropType< TypeTag, Scalar > type
Definition: fvbasediscretization.hh:291
Maximum accepted error of the solution of the linear solver.
Definition: linalgproperties.hh:63
The class which linearizes the non-linear system of equations.
Definition: newtonmethodproperties.hh:36
The maximum allowed number of timestep divisions for the Newton solver.
Definition: fvbaseproperties.hh:277
GetPropType< TypeTag, Scalar > type
Definition: fvbasediscretization.hh:230
Specify the maximum size of a time integration [s].
Definition: fvbaseproperties.hh:262
GetPropType< TypeTag, Scalar > type
Definition: fvbasediscretization.hh:238
Specify the minimal size of a time integration [s].
Definition: fvbaseproperties.hh:270
The directory to which simulation output ought to be written to.
Definition: fvbaseproperties.hh:217
A vector of primary variables within a sub-control volume.
Definition: fvbaseproperties.hh:147
GetPropType< TypeTag, Properties::EqVector > type
Definition: fvbasediscretization.hh:150
Vector containing volumetric or areal rates of quantities.
Definition: fvbaseproperties.hh:133
Manages the simulation time.
Definition: basicproperties.hh:173
Dune::BlockVector< GetPropType< TypeTag, Properties::PrimaryVariables > > type
Definition: fvbasediscretization.hh:190
Vector containing all primary variables of the grid.
Definition: fvbaseproperties.hh:143
The OpenMP threads manager.
Definition: fvbaseproperties.hh:191
Definition: fvbaseproperties.hh:193
The history size required by the time discretization.
Definition: fvbaseproperties.hh:343
a tag to mark properties as undefined
Definition: propertysystem.hh:40
Definition: fvbaseproperties.hh:200
Specify whether to use volumetric residuals or not.
Definition: fvbaseproperties.hh:355
Dune::MultipleCodimMultipleGeomTypeMapper< GetPropType< TypeTag, Properties::GridView > > type
Definition: fvbasediscretization.hh:94
The mapper to find the global index of a vertex.
Definition: fvbaseproperties.hh:325
Specify the format the VTK output is written to disk.
Definition: fvbaseproperties.hh:250