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  Copyright (C) 2008-2014 by Andreas Lauser
5  Copyright (C) 2009-2011 by Bernd Flemisch
6 
7  This file is part of the Open Porous Media project (OPM).
8 
9  OPM is free software: you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 2 of the License, or
12  (at your option) any later version.
13 
14  OPM is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with OPM. If not, see <http://www.gnu.org/licenses/>.
21 */
27 #ifndef EWOMS_FV_BASE_DISCRETIZATION_HH
28 #define EWOMS_FV_BASE_DISCRETIZATION_HH
29 
30 #include <opm/material/localad/Math.hpp>
31 
32 #include "fvbaseproperties.hh"
33 #include "fvbaselinearizer.hh"
36 #include "fvbaselocalresidual.hh"
37 #include "fvbaseelementcontext.hh"
38 #include "fvbaseboundarycontext.hh"
40 #include "fvbaseconstraints.hh"
41 #include "fvbasediscretization.hh"
43 #include "fvbasenewtonmethod.hh"
47 
53 
54 #include <opm/material/common/MathToolbox.hpp>
55 
56 #include <dune/common/fvector.hh>
57 #include <dune/common/fmatrix.hh>
58 #include <dune/istl/bvector.hh>
59 
60 #include <limits>
61 #include <list>
62 #include <sstream>
63 #include <string>
64 #include <vector>
65 
66 namespace Ewoms {
67 template<class TypeTag>
69 
70 namespace Properties {
73 
76  Dune::MultipleCodimMultipleGeomTypeMapper<typename GET_PROP_TYPE(TypeTag, GridView),
77  Dune::MCMGVertexLayout>);
78 
80 SET_TYPE_PROP(FvBaseDiscretization, ElementMapper,
81  Dune::MultipleCodimMultipleGeomTypeMapper<typename GET_PROP_TYPE(TypeTag, GridView),
82  Dune::MCMGElementLayout>);
83 
85 SET_PROP(FvBaseDiscretization, BorderListCreator)
86 {
87  typedef typename GET_PROP_TYPE(TypeTag, DofMapper) DofMapper;
88  typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
89 public:
91 };
92 
94 
97 
100 
103 {
104 private:
105  typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
106  enum { numEq = GET_PROP_VALUE(TypeTag, NumEq) };
107  typedef typename Dune::FieldMatrix<Scalar, numEq, numEq> MatrixBlock;
108 public:
109  typedef typename Dune::BCRSMatrix<MatrixBlock> type;
110 };
111 
114 SET_INT_PROP(FvBaseDiscretization, MaxTimeStepDivisions, 10);
115 
120  Dune::FieldVector<typename GET_PROP_TYPE(TypeTag, Scalar),
121  GET_PROP_VALUE(TypeTag, NumEq)>);
122 
129  typename GET_PROP_TYPE(TypeTag, EqVector));
130 
134 SET_TYPE_PROP(FvBaseDiscretization, BoundaryRateVector,
135  typename GET_PROP_TYPE(TypeTag, RateVector));
136 
141 
145 SET_TYPE_PROP(FvBaseDiscretization, ElementEqVector,
146  Dune::BlockVector<typename GET_PROP_TYPE(TypeTag, EqVector)>);
147 
151 SET_TYPE_PROP(FvBaseDiscretization, GlobalEqVector,
152  Dune::BlockVector<typename GET_PROP_TYPE(TypeTag, EqVector)>);
153 
158 
162 SET_TYPE_PROP(FvBaseDiscretization, SolutionVector,
163  Dune::BlockVector<typename GET_PROP_TYPE(TypeTag, PrimaryVariables)>);
164 
171 
178 
183 SET_INT_PROP(FvBaseDiscretization, ThreadsPerProcess, 1);
184 
189 
191 #if 0
192 // requires GCC 4.6 or later to be able call the constexpr function here
193 SET_SCALAR_PROP(FvBaseDiscretization, MaxTimeStepSize, std::numeric_limits<Scalar>::infinity());
194 #else
195 SET_SCALAR_PROP(FvBaseDiscretization, MaxTimeStepSize, 1e100);
196 #endif
197 SET_SCALAR_PROP(FvBaseDiscretization, MinTimeStepSize, 0.0);
199 
201 SET_BOOL_PROP(FvBaseDiscretization, EnableVtkOutput, true);
202 
204 SET_INT_PROP(FvBaseDiscretization, VtkOutputFormat, Dune::VTK::ascii);
205 
206 // disable linearization recycling by default
207 SET_BOOL_PROP(FvBaseDiscretization, EnableLinearizationRecycling, false);
208 
209 // disable partial relinearization by default
210 SET_BOOL_PROP(FvBaseDiscretization, EnablePartialRelinearization, false);
211 
212 // disable constraints by default
213 SET_BOOL_PROP(FvBaseDiscretization, EnableConstraints, false);
214 
215 // by default, disable the intensive quantity cache. If the intensive quantities are
216 // relatively cheap to calculate, the cache basically does not yield any performance
217 // impact because of the intensive quantity cache will cause additional pressure on the
218 // CPU caches...
219 SET_BOOL_PROP(FvBaseDiscretization, EnableIntensiveQuantityCache, false);
220 
221 // do not use thermodynamic hints by default. If you enable this, make sure to also
222 // enable the intensive quantity cache above to avoid getting an exception...
223 SET_BOOL_PROP(FvBaseDiscretization, EnableThermodynamicHints, false);
224 
225 // if the deflection of the newton method is large, we do not need to solve the linear
226 // approximation accurately. Assuming that the value for the current solution is quite
227 // close to the final value, a reduction of 3 orders of magnitude in the defect should be
228 // sufficient...
229 SET_SCALAR_PROP(FvBaseDiscretization, LinearSolverTolerance, 1e-3);
230 
232 SET_INT_PROP(FvBaseDiscretization, TimeDiscHistorySize, 2);
233 
236 SET_BOOL_PROP(FvBaseDiscretization, RequireScvCenterGradients, false);
237 } // namespace Properties
238 
244 template<class TypeTag>
245 class FvBaseDiscretization
246 {
247  typedef typename GET_PROP_TYPE(TypeTag, Model) Implementation;
248  typedef typename GET_PROP_TYPE(TypeTag, Simulator) Simulator;
249  typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
250  typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
251  typedef typename GET_PROP_TYPE(TypeTag, Evaluation) Evaluation;
252  typedef typename GET_PROP_TYPE(TypeTag, ElementMapper) ElementMapper;
253  typedef typename GET_PROP_TYPE(TypeTag, VertexMapper) VertexMapper;
254  typedef typename GET_PROP_TYPE(TypeTag, DofMapper) DofMapper;
255  typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector;
256  typedef typename GET_PROP_TYPE(TypeTag, GlobalEqVector) GlobalEqVector;
257  typedef typename GET_PROP_TYPE(TypeTag, EqVector) EqVector;
258  typedef typename GET_PROP_TYPE(TypeTag, RateVector) RateVector;
259  typedef typename GET_PROP_TYPE(TypeTag, BoundaryRateVector) BoundaryRateVector;
260  typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
261  typedef typename GET_PROP_TYPE(TypeTag, Linearizer) Linearizer;
262  typedef typename GET_PROP_TYPE(TypeTag, ElementContext) ElementContext;
263  typedef typename GET_PROP_TYPE(TypeTag, BoundaryContext) BoundaryContext;
264  typedef typename GET_PROP_TYPE(TypeTag, IntensiveQuantities) IntensiveQuantities;
265  typedef typename GET_PROP_TYPE(TypeTag, ExtensiveQuantities) ExtensiveQuantities;
266  typedef typename GET_PROP_TYPE(TypeTag, GradientCalculator) GradientCalculator;
267  typedef typename GET_PROP_TYPE(TypeTag, Stencil) Stencil;
268  typedef typename GET_PROP_TYPE(TypeTag, DiscBaseOutputModule) DiscBaseOutputModule;
269  typedef typename GET_PROP_TYPE(TypeTag, GridCommHandleFactory) GridCommHandleFactory;
270  typedef typename GET_PROP_TYPE(TypeTag, NewtonMethod) NewtonMethod;
271  typedef typename GET_PROP_TYPE(TypeTag, ThreadManager) ThreadManager;
272 
273  typedef typename GET_PROP_TYPE(TypeTag, LocalLinearizer) LocalLinearizer;
274  typedef typename GET_PROP_TYPE(TypeTag, LocalResidual) LocalResidual;
275 
276  enum {
277  numEq = GET_PROP_VALUE(TypeTag, NumEq),
278  historySize = GET_PROP_VALUE(TypeTag, TimeDiscHistorySize),
279  };
280 
281  typedef std::vector<IntensiveQuantities> IntensiveQuantitiesVector;
282 
283  typedef typename GridView::template Codim<0>::Entity Element;
284  typedef typename GridView::template Codim<0>::Iterator ElementIterator;
285 
286  typedef Opm::MathToolbox<Evaluation> Toolbox;
287  typedef Dune::FieldVector<Evaluation, numEq> VectorBlock;
288  typedef Dune::FieldVector<Evaluation, numEq> EvalEqVector;
289  typedef Dune::BlockVector<VectorBlock> LocalBlockVector;
290 
291  // copying a discretization object is not a good idea
292  FvBaseDiscretization(const FvBaseDiscretization &);
293 
294 public:
295  // this constructor required to be explicitly specified because
296  // we've defined a constructor above which deletes all implicitly
297  // generated constructors in C++.
299  : simulator_(simulator)
300  , gridView_(simulator.gridView())
301  , newtonMethod_(simulator)
302  , localLinearizer_(ThreadManager::maxThreads())
303  , linearizer_(new Linearizer())
304  {
305  asImp_().updateBoundary_();
306 
307  int nDofs = asImp_().numGridDof();
308  for (int timeIdx = 0; timeIdx < historySize; ++timeIdx) {
309  solution_[timeIdx].resize(nDofs);
310 
312  intensiveQuantityCache_[timeIdx].resize(nDofs);
313  intensiveQuantityCacheUpToDate_[timeIdx].resize(nDofs, /*value=*/false);
314  }
315  }
316 
317  asImp_().registerOutputModules_();
318  }
319 
321  {
322  // delete all output modules
323  auto modIt = outputModules_.begin();
324  const auto &modEndIt = outputModules_.end();
325  for (; modIt != modEndIt; ++modIt)
326  delete *modIt;
327 
328  delete linearizer_;
329  }
330 
334  static void registerParameters()
335  {
336  Linearizer::registerParameters();
337  LocalLinearizer::registerParameters();
338  LocalResidual::registerParameters();
339  GradientCalculator::registerParameters();
340  IntensiveQuantities::registerParameters();
341  ExtensiveQuantities::registerParameters();
343 
344  // register runtime parameters of the output modules
346 
347  EWOMS_REGISTER_PARAM(TypeTag, bool, EnableVtkOutput, "Global switch for turing on writing VTK files");
348  EWOMS_REGISTER_PARAM(TypeTag, bool, EnableThermodynamicHints, "Enable thermodynamic hints");
349  EWOMS_REGISTER_PARAM(TypeTag, bool, EnableIntensiveQuantityCache, "Turn on caching of intensive quantities");
350  }
351 
355  void finishInit()
356  {
357  // initialize the volume of the finite volumes to zero
358  int nDofs = asImp_().numGridDof();
359  dofTotalVolume_.resize(nDofs);
360  std::fill(dofTotalVolume_.begin(), dofTotalVolume_.end(), 0.0);
361 
362  ElementContext elemCtx(simulator_);
363  gridTotalVolume_ = 0.0;
364 
365  // iterate through the grid and evaluate the initial condition
366  ElementIterator elemIt = gridView_.template begin</*codim=*/0>();
367  const ElementIterator &elemEndIt = gridView_.template end</*codim=*/0>();
368  for (; elemIt != elemEndIt; ++elemIt) {
369  const Element& elem = *elemIt;
370  const bool isInteriorElement = elem.partitionType() == Dune::InteriorEntity;
371  // ignore everything which is not in the interior if the
372  // current process' piece of the grid
373  if (!isInteriorElement)
374  continue;
375 
376  // deal with the current element
377  elemCtx.updateStencil(elem);
378  const auto &stencil = elemCtx.stencil(/*timeIdx=*/0);
379 
380  // loop over all element vertices, i.e. sub control volumes
381  for (int dofIdx = 0; dofIdx < elemCtx.numPrimaryDof(/*timeIdx=*/0); dofIdx++) {
382  // map the local degree of freedom index to the global one
383  unsigned globalIdx = elemCtx.globalSpaceIndex(dofIdx, /*timeIdx=*/0);
384 
385  Scalar dofVolume = stencil.subControlVolume(dofIdx).volume();
386  dofTotalVolume_[globalIdx] += dofVolume;
387  if (isInteriorElement)
388  gridTotalVolume_ += dofVolume;
389  }
390  }
391 
392  // determine which DOFs should be considered to lie fully in the interior of the
393  // local process grid partition: those which do not have a non-zero volume
394  // before taking the peer processes into account...
395  isLocalDof_.resize(nDofs);
396  for (int dofIdx = 0; dofIdx < nDofs; ++dofIdx)
397  isLocalDof_[dofIdx] = (dofTotalVolume_[dofIdx] != 0.0);
398 
399  // add the volumes of the DOFs on the process boundaries
400  const auto sumHandle =
401  GridCommHandleFactory::template sumHandle<Scalar>(dofTotalVolume_,
402  asImp_().dofMapper());
403  gridView_.communicate(*sumHandle,
404  Dune::InteriorBorder_All_Interface,
405  Dune::BackwardCommunication);
406 
407  // sum up the volumes of the grid partitions
409 
410  linearizer_->init(simulator_);
411  for (int threadId = 0; threadId < ThreadManager::maxThreads(); ++threadId)
412  localLinearizer_[threadId].init(simulator_);
413 
415  // invalidate all cached intensive quantities
416  for (int timeIdx = 0; timeIdx < historySize; ++ timeIdx) {
417  std::fill(intensiveQuantityCacheUpToDate_[timeIdx].begin(),
418  intensiveQuantityCacheUpToDate_[timeIdx].end(),
419  false);
420  }
421  }
422  }
423 
429  {
430  // first set the whole domain to zero
431  SolutionVector &uCur = asImp_().solution(/*timeIdx=*/0);
432  uCur = Scalar(0.0);
433 
434  ElementContext elemCtx(simulator_);
435 
436  // iterate through the grid and evaluate the initial condition
437  ElementIterator elemIt = gridView_.template begin</*codim=*/0>();
438  const ElementIterator &elemEndIt = gridView_.template end</*codim=*/0>();
439  for (; elemIt != elemEndIt; ++elemIt) {
440  const Element& elem = *elemIt;
441  // ignore everything which is not in the interior if the
442  // current process' piece of the grid
443  if (elem.partitionType() != Dune::InteriorEntity)
444  continue;
445 
446  // deal with the current element
447  elemCtx.updateStencil(elem);
448 
449  // loop over all element vertices, i.e. sub control volumes
450  for (int dofIdx = 0; dofIdx < elemCtx.numPrimaryDof(/*timeIdx=*/0); dofIdx++)
451  {
452  // map the local degree of freedom index to the global one
453  unsigned globalIdx = elemCtx.globalSpaceIndex(dofIdx, /*timeIdx=*/0);
454 
455  // let the problem do the dirty work of nailing down
456  // the initial solution.
457  simulator_.problem().initial(uCur[globalIdx], elemCtx, dofIdx, /*timeIdx=*/0);
458  asImp_().supplementInitialSolution_(uCur[globalIdx], elemCtx, dofIdx, /*timeIdx=*/0);
459  uCur[globalIdx].checkDefined();
460  }
461  }
462 
463  // synchronize the ghost DOFs (if necessary)
464  asImp_().syncOverlap();
465 
466  // also set the solution of the "previous" time steps to the
467  // initial solution.
468  for (int timeIdx = 1; timeIdx < historySize; ++timeIdx)
469  solution_[timeIdx] = solution_[/*timeIdx=*/0];
470 
471  simulator_.problem().initialSolutionApplied();
472  }
473 
478  { return newtonMethod_; }
479 
483  const NewtonMethod &newtonMethod() const
484  { return newtonMethod_; }
485 
501  const IntensiveQuantities *thermodynamicHint(int globalIdx, int timeIdx) const
502  {
504  return 0;
505 
506  if (intensiveQuantityCacheUpToDate_[timeIdx][globalIdx])
507  return &intensiveQuantityCache_[timeIdx][globalIdx];
508 
509  // use the intensive quantities for the first up-to-date time index as hint
510  for (int timeIdx2 = 0; timeIdx2 < historySize; ++timeIdx2)
511  if (intensiveQuantityCacheUpToDate_[timeIdx2][globalIdx])
512  return &intensiveQuantityCache_[timeIdx2][globalIdx];
513 
514  // no suitable up-to-date intensive quantities...
515  return 0;
516  }
517 
529  const IntensiveQuantities *cachedIntensiveQuantities(int globalIdx, int timeIdx) const
530  {
532  !intensiveQuantityCacheUpToDate_[timeIdx][globalIdx])
533  return 0;
534 
535  return &intensiveQuantityCache_[timeIdx][globalIdx];
536  }
537 
546  void updateCachedIntensiveQuantities(const IntensiveQuantities &intQuants,
547  int globalIdx,
548  int timeIdx) const
549  {
551  return;
552 
553  intensiveQuantityCache_[timeIdx][globalIdx] = intQuants;
554  intensiveQuantityCacheUpToDate_[timeIdx][globalIdx] = true;
555  }
556 
565  int timeIdx,
566  bool newValue) const
567  {
569  return;
570 
571  intensiveQuantityCacheUpToDate_[timeIdx][globalIdx] = newValue;
572  }
573 
582  void shiftIntensiveQuantityCache(int numSlots = 1)
583  {
585  return;
586 
587  for (int timeIdx = 0; timeIdx < historySize - numSlots; ++ timeIdx) {
588  intensiveQuantityCache_[timeIdx + numSlots] = intensiveQuantityCache_[timeIdx];
590  }
591 
592  // invalidate the cache for the most recent time index
593  std::fill(intensiveQuantityCacheUpToDate_[/*timeIdx=*/0].begin(),
594  intensiveQuantityCacheUpToDate_[/*timeIdx=*/0].end(),
595  false);
596  }
597 
605  Scalar globalResidual(GlobalEqVector &dest,
606  const SolutionVector &u) const
607  {
608  SolutionVector tmp(asImp_().solution(/*timeIdx=*/0));
609  solution_[/*timeIdx=*/0] = u;
610  Scalar res = asImp_().globalResidual(dest);
611  solution_[/*timeIdx=*/0] = tmp;
612  return res;
613  }
614 
621  Scalar globalResidual(GlobalEqVector &dest) const
622  {
623  dest = 0;
624 
625  OmpMutex mutex;
626  ThreadedEntityIterator<GridView, /*codim=*/0> threadedElemIt(gridView());
627 #ifdef _OPENMP
628 #pragma omp parallel
629 #endif
630  {
631  // Attention: the variables below are thread specific and thus cannot be
632  // moved in front of the #pragma!
633  int threadId = ThreadManager::threadId();
634  ElementContext elemCtx(simulator_);
635  ElementIterator elemIt = gridView().template begin</*codim=*/0>();
636  LocalBlockVector residual, storageTerm;
637 
638  for (threadedElemIt.beginParallel(elemIt);
639  !threadedElemIt.isFinished(elemIt);
640  threadedElemIt.increment(elemIt))
641  {
642  const Element& elem = *elemIt;
643  if (elem.partitionType() != Dune::InteriorEntity)
644  continue;
645 
646  elemCtx.updateAll(elem);
647  residual.resize(elemCtx.numDof(/*timeIdx=*/0));
648  storageTerm.resize(elemCtx.numPrimaryDof(/*timeIdx=*/0));
649  asImp_().localResidual(threadId).eval(residual, storageTerm, elemCtx);
650 
651  int numPrimaryDof = elemCtx.numPrimaryDof(/*timeIdx=*/0);
652  ScopedLock addLock(mutex);
653  for (int dofIdx = 0; dofIdx < numPrimaryDof; ++dofIdx) {
654  int globalI = elemCtx.globalSpaceIndex(dofIdx, /*timeIdx=*/0);
655  for (int eqIdx = 0; eqIdx < numEq; ++ eqIdx)
656  dest[globalI][eqIdx] += Toolbox::value(residual[dofIdx][eqIdx]);
657  }
658  addLock.unlock();
659  }
660  }
661 
662  // add up the residuals on the process borders
663  const auto sumHandle =
664  GridCommHandleFactory::template sumHandle<EqVector>(dest, asImp_().dofMapper());
665  gridView_.communicate(*sumHandle,
666  Dune::InteriorBorder_InteriorBorder_Interface,
667  Dune::ForwardCommunication);
668 
669  // calculate the square norm of the residual. this is not
670  // entirely correct, since the residual for the finite volumes
671  // which are on the boundary are counted once for every
672  // process. As often in life: shit happens (, we don't care)...
673  Scalar result2 = dest.two_norm2();
674  result2 = asImp_().gridView().comm().sum(result2);
675 
676  return std::sqrt(result2);
677  }
678 
685  void globalStorage(EqVector &storage, int timeIdx = 0) const
686  {
687  storage = 0;
688 
689  OmpMutex mutex;
690  ThreadedEntityIterator<GridView, /*codim=*/0> threadedElemIt(gridView());
691 #ifdef _OPENMP
692 #pragma omp parallel
693 #endif
694  {
695  // Attention: the variables below are thread specific and thus cannot be
696  // moved in front of the #pragma!
697  int threadId = ThreadManager::threadId();
698  ElementContext elemCtx(simulator_);
699  ElementIterator elemIt = gridView().template begin</*codim=*/0>();
700  LocalBlockVector elemStorage;
701 
702  for (threadedElemIt.beginParallel(elemIt);
703  !threadedElemIt.isFinished(elemIt);
704  threadedElemIt.increment(elemIt))
705  {
706  const Element& elem = *elemIt;
707  if (elem.partitionType() != Dune::InteriorEntity)
708  continue; // ignore ghost and overlap elements
709 
710  elemCtx.updateStencil(elem);
711  elemCtx.updatePrimaryIntensiveQuantities(timeIdx);
712 
713  int numPrimaryDof = elemCtx.numPrimaryDof(timeIdx);
714  elemStorage.resize(numPrimaryDof);
715 
716  localResidual(threadId).evalStorage(elemStorage, elemCtx, timeIdx);
717 
718  ScopedLock addLock(mutex);
719  for (int dofIdx = 0; dofIdx < numPrimaryDof; ++dofIdx)
720  for (int eqIdx = 0; eqIdx < numEq; ++eqIdx)
721  storage[eqIdx] += Toolbox::value(elemStorage[dofIdx][eqIdx]);
722  addLock.unlock();
723  }
724  }
725 
726  storage = gridView_.comm().sum(storage);
727  }
728 
736  void checkConservativeness(Scalar tolerance = -1, bool verbose=false) const
737  {
738 #ifndef NDEBUG
739  EqVector storageBeginTimeStep;
740  EqVector storageEndTimeStep;
741 
742  Scalar totalBoundaryArea(0.0);
743  Scalar totalVolume(0.0);
744  EvalEqVector totalRate(Toolbox::createConstant(0.0));
745 
746  // take the newton tolerance times the total volume of the grid if we're not
747  // given an explicit tolerance...
748  if (tolerance <= 0) {
749  tolerance =
750  simulator_.model().newtonMethod().tolerance()
751  * simulator_.model().gridTotalVolume()
752  * 1000;
753  }
754 
755  // we assume the implicit Euler time discretization for now...
756  assert(historySize == 2);
757 
758  globalStorage(storageBeginTimeStep, /*timeIdx=*/1);
759  globalStorage(storageEndTimeStep, /*timeIdx=*/0);
760 
761  // calculate the rate at the boundary and the source rate
762  ElementContext elemCtx(simulator_);
763  auto eIt = simulator_.gridView().template begin</*codim=*/0>();
764  const auto &elemEndIt = simulator_.gridView().template end</*codim=*/0>();
765  for (; eIt != elemEndIt; ++eIt) {
766  if (eIt->partitionType() != Dune::InteriorEntity)
767  continue; // ignore ghost and overlap elements
768 
769  elemCtx.updateAll(*eIt);
770 
771  // handle the boundary terms
772  if (elemCtx.onBoundary()) {
773  BoundaryContext boundaryCtx(elemCtx);
774 
775  for (int faceIdx = 0; faceIdx < boundaryCtx.numBoundaryFaces(/*timeIdx=*/0); ++faceIdx) {
776  BoundaryRateVector values;
777  simulator_.problem().boundary(values,
778  boundaryCtx,
779  faceIdx,
780  /*timeIdx=*/0);
781  Valgrind::CheckDefined(values);
782 
783  int dofIdx = boundaryCtx.interiorScvIndex(faceIdx, /*timeIdx=*/0);
784  const auto &insideIntQuants = elemCtx.intensiveQuantities(dofIdx, /*timeIdx=*/0);
785 
786  Scalar bfArea =
787  boundaryCtx.boundarySegmentArea(faceIdx, /*timeIdx=*/0)
788  * insideIntQuants.extrusionFactor();
789 
790  for (unsigned i = 0; i < values.size(); ++i)
791  values[i] *= bfArea;
792 
793  totalBoundaryArea += bfArea;
794  totalRate += values;
795  }
796  }
797 
798  // deal with the source terms
799  for (int dofIdx = 0; dofIdx < elemCtx.numPrimaryDof(/*timeIdx=*/0); ++ dofIdx) {
800  RateVector values;
801  simulator_.problem().source(values,
802  elemCtx,
803  dofIdx,
804  /*timeIdx=*/0);
805  Valgrind::CheckDefined(values);
806 
807  const auto &intQuants = elemCtx.intensiveQuantities(dofIdx, /*timeIdx=*/0);
808  Scalar dofVolume =
809  elemCtx.dofVolume(dofIdx, /*timeIdx=*/0)
810  * intQuants.extrusionFactor();
811  for (int eqIdx = 0; eqIdx < numEq; ++ eqIdx)
812  totalRate[eqIdx] += -dofVolume*Toolbox::value(values[eqIdx]);
813  totalVolume += dofVolume;
814  }
815  }
816 
817  // summarize everything over all processes
818  const auto &comm = simulator_.gridView().comm();
819  totalRate = comm.sum(totalRate);
820  totalBoundaryArea = comm.sum(totalBoundaryArea);
821  totalVolume = comm.sum(totalVolume);
822 
823  if (comm.rank() == 0) {
824  EqVector storageRate = storageBeginTimeStep;
825  storageRate -= storageEndTimeStep;
826  storageRate /= simulator_.timeStepSize();
827  if (verbose) {
828  std::cout << "storage at beginning of time step: " << storageBeginTimeStep << "\n";
829  std::cout << "storage at end of time step: " << storageEndTimeStep << "\n";
830  std::cout << "rate based on storage terms: " << storageRate << "\n";
831  std::cout << "rate based on source and boundary terms: " << totalRate << "\n";
832  std::cout << "difference in rates: ";
833  for (int eqIdx = 0; eqIdx < EqVector::dimension; ++eqIdx)
834  std::cout << (storageRate[eqIdx] - Toolbox::value(totalRate[eqIdx])) << " ";
835  std::cout << "\n";
836  }
837  for (int eqIdx = 0; eqIdx < EqVector::dimension; ++eqIdx) {
838  Scalar eps =
839  (std::abs(storageRate[eqIdx]) + Toolbox::value(totalRate[eqIdx]))*tolerance;
840  eps = std::max(tolerance, eps);
841  assert(std::abs(storageRate[eqIdx] - Toolbox::value(totalRate[eqIdx])) <= eps);
842  }
843  }
844 #endif // NDEBUG
845  }
846 
852  Scalar dofTotalVolume(int globalIdx) const
853  { return dofTotalVolume_[globalIdx]; }
854 
860  bool isLocalDof(int globalIdx) const
861  { return isLocalDof_[globalIdx]; }
862 
867  Scalar gridTotalVolume() const
868  { return gridTotalVolume_; }
869 
875  const SolutionVector &solution(int timeIdx) const
876  { return solution_[timeIdx]; }
877 
881  SolutionVector &solution(int timeIdx)
882  { return solution_[timeIdx]; }
883 
888  const Linearizer &linearizer() const
889  { return *linearizer_; }
890 
895  Linearizer &linearizer()
896  { return *linearizer_; }
897 
906  const LocalLinearizer &localLinearizer(int openMpThreadId) const
907  { return localLinearizer_[openMpThreadId]; }
911  LocalLinearizer &localLinearizer(int openMpThreadId)
912  { return localLinearizer_[openMpThreadId]; }
913 
917  const LocalResidual &localResidual(int openMpThreadId) const
918  { return asImp_().localLinearizer(openMpThreadId).localResidual(); }
922  LocalResidual &localResidual(int openMpThreadId)
923  { return asImp_().localLinearizer(openMpThreadId).localResidual(); }
924 
932  Scalar primaryVarWeight(int globalDofIdx, int pvIdx) const
933  {
934  Scalar absPv = std::abs(asImp_().solution(/*timeIdx=*/1)[globalDofIdx][pvIdx]);
935  return 1.0/std::max(absPv, 1.0);
936  }
937 
944  Scalar eqWeight(int globalVertexIdx, int eqIdx) const
945  { return 1.0; }
946 
956  Scalar relativeDofError(int vertexIdx,
957  const PrimaryVariables &pv1,
958  const PrimaryVariables &pv2) const
959  {
960  Scalar result = 0.0;
961  for (int j = 0; j < numEq; ++j) {
962  Scalar weight = asImp_().primaryVarWeight(vertexIdx, j);
963  Scalar eqErr = std::abs((pv1[j] - pv2[j])*weight);
964  //Scalar eqErr = std::abs(pv1[j] - pv2[j]);
965  //eqErr *= std::max<Scalar>(1.0, std::abs(pv1[j] + pv2[j])/2);
966 
967  result = std::max(result, eqErr);
968  }
969  return result;
970  }
971 
977  bool update(NewtonMethod &solver)
978  {
979 #if HAVE_VALGRIND
980  for (size_t i = 0; i < asImp_().solution(/*timeIdx=*/0).size(); ++i)
981  asImp_().solution(/*timeIdx=*/0)[i].checkDefined();
982 #endif // HAVE_VALGRIND
983 
984  Timer prePostProcessTimer;
985  prePostProcessTimer.start();
986  asImp_().updateBegin();
987  prePostProcessTimer.stop();
988  simulator_.addPrePostProcessTime(prePostProcessTimer.realTimeElapsed());
989 
990  bool converged = solver.apply();
991 
992  prePostProcessTimer.start();
993  if (converged)
994  asImp_().updateSuccessful();
995  else
996  asImp_().updateFailed();
997  prePostProcessTimer.stop();
998  simulator_.addPrePostProcessTime(prePostProcessTimer.realTimeElapsed());
999 
1000 #if HAVE_VALGRIND
1001  // make sure that the "non-pseudo" primary variables are defined. Note that
1002  // because of the padding, we can't just simply ask valgrind to check the whole
1003  // solution vectors for definedness...
1004  for (size_t i = 0; i < asImp_().solution(/*timeIdx=*/0).size(); ++i) {
1005  for (size_t eqIdx = 0; eqIdx < numEq; ++eqIdx)
1006  Valgrind::CheckDefined(asImp_().solution(/*timeIdx=*/0)[i][eqIdx]);
1007  }
1008 #endif // HAVE_VALGRIND
1009 
1010  return converged;
1011  }
1012 
1021  { }
1022 
1029  { updateBoundary_(); }
1030 
1031 
1038  { }
1039 
1046  {
1047  // Reset the current solution to the one of the
1048  // previous time step so that we can start the next
1049  // update at a physically meaningful solution.
1050  intensiveQuantityCache_[/*timeIdx=*/0] = intensiveQuantityCache_[/*timeIdx=*/1];
1051  intensiveQuantityCacheUpToDate_[/*timeIdx=*/0] = intensiveQuantityCacheUpToDate_[/*timeIdx=*/1];
1052 
1053  solution_[/*timeIdx=*/0] = solution_[/*timeIdx=*/1];
1054  linearizer_->relinearizeAll();
1055  }
1056 
1065  {
1066  // make the current solution the previous one.
1067  solution_[/*timeIdx=*/1] = solution_[/*timeIdx=*/0];
1068 
1069  // shift the intensive quantities cache by one position in the
1070  // history
1071  asImp_().shiftIntensiveQuantityCache(/*numSlots=*/1);
1072  }
1073 
1081  template <class Restarter>
1082  void serialize(Restarter &res)
1083  {
1084  OPM_THROW(std::runtime_error,
1085  "Not implemented: The discretization chosen for this problem does not support"
1086  " restart files. (serialize() method unimplemented)");
1087  }
1088 
1096  template <class Restarter>
1097  void deserialize(Restarter &res)
1098  {
1099  OPM_THROW(std::runtime_error,
1100  "Not implemented: The discretization chosen for this problem does not support"
1101  " restart files. (deserialize() method unimplemented)");
1102  }
1103 
1112  template <class DofEntity>
1113  void serializeEntity(std::ostream &outstream,
1114  const DofEntity &dof)
1115  {
1116 #if DUNE_VERSION_NEWER(DUNE_COMMON, 2, 4)
1117  int dofIdx = asImp_().dofMapper().index(dof);
1118 #else
1119  int dofIdx = asImp_().dofMapper().map(dof);
1120 #endif
1121 
1122  // write phase state
1123  if (!outstream.good()) {
1124  OPM_THROW(std::runtime_error, "Could not serialize degree of freedom " << dofIdx);
1125  }
1126 
1127  for (int eqIdx = 0; eqIdx < numEq; ++eqIdx) {
1128  outstream << solution_[/*timeIdx=*/0][dofIdx][eqIdx] << " ";
1129  }
1130  }
1131 
1140  template <class DofEntity>
1141  void deserializeEntity(std::istream &instream,
1142  const DofEntity &dof)
1143  {
1144 #if DUNE_VERSION_NEWER(DUNE_COMMON, 2, 4)
1145  int dofIdx = asImp_().dofMapper().index(dof);
1146 #else
1147  int dofIdx = asImp_().dofMapper().map(dof);
1148 #endif
1149 
1150  for (int eqIdx = 0; eqIdx < numEq; ++eqIdx) {
1151  if (!instream.good())
1152  OPM_THROW(std::runtime_error,
1153  "Could not deserialize degree of freedom " << dofIdx);
1154  instream >> solution_[/*timeIdx=*/0][dofIdx][eqIdx];
1155  }
1156  }
1157 
1161  size_t numGridDof() const
1162  { OPM_THROW(std::logic_error,
1163  "The discretization class must implement the numGridDof() method!"); }
1164 
1168  size_t numAuxiliaryDof() const
1169  {
1170  size_t result = 0;
1171  auto auxModIt = auxEqModules_.begin();
1172  const auto& auxModEndIt = auxEqModules_.end();
1173  for (; auxModIt != auxModEndIt; ++auxModIt)
1174  result += (*auxModIt)->numDofs();
1175 
1176  return result;
1177  }
1178 
1182  size_t numTotalDof() const
1183  { return asImp_().numGridDof() + numAuxiliaryDof(); }
1184 
1189  const DofMapper &dofMapper() const
1190  { OPM_THROW(std::logic_error,
1191  "The discretization class must implement the dofMapper() method!"); }
1192 
1196  const VertexMapper &vertexMapper() const
1197  { return simulator_.problem().vertexMapper(); }
1198 
1202  const ElementMapper &elementMapper() const
1203  { return simulator_.problem().elementMapper(); }
1204 
1210  {
1211  delete linearizer_;
1212  linearizer_ = new Linearizer;
1213  linearizer_->init(simulator_);
1214  }
1215 
1222  bool onBoundary(int globalIdx) const
1223  { return onBoundary_[globalIdx]; }
1224 
1228  static std::string discretizationName()
1229  { return ""; }
1230 
1236  std::string primaryVarName(int pvIdx) const
1237  {
1238  std::ostringstream oss;
1239  oss << "primary variable_" << pvIdx;
1240  return oss.str();
1241  }
1242 
1248  std::string eqName(int eqIdx) const
1249  {
1250  std::ostringstream oss;
1251  oss << "equation_" << eqIdx;
1252  return oss.str();
1253  }
1254 
1261  void updatePVWeights(const ElementContext &elemCtx) const
1262  { }
1263 
1268  { outputModules_.push_back(newModule); }
1269 
1278  template <class VtkMultiWriter>
1280  const SolutionVector &u,
1281  const GlobalEqVector &deltaU) const
1282  {
1283  typedef std::vector<double> ScalarBuffer;
1284 
1285  GlobalEqVector globalResid(u.size());
1286  asImp_().globalResidual(globalResid, u);
1287 
1288  // create the required scalar fields
1289  unsigned numGridDof = asImp_().numGridDof();
1290 
1291  // global defect of the two auxiliary equations
1292  ScalarBuffer* def[numEq];
1293  ScalarBuffer* delta[numEq];
1294  ScalarBuffer* priVars[numEq];
1295  ScalarBuffer* priVarWeight[numEq];
1296  ScalarBuffer* relError = writer.allocateManagedScalarBuffer(numGridDof);
1297  ScalarBuffer* dofColor = writer.allocateManagedScalarBuffer(numGridDof);
1298  for (int pvIdx = 0; pvIdx < numEq; ++pvIdx) {
1299  priVars[pvIdx] = writer.allocateManagedScalarBuffer(numGridDof);
1300  priVarWeight[pvIdx] = writer.allocateManagedScalarBuffer(numGridDof);
1301  delta[pvIdx] = writer.allocateManagedScalarBuffer(numGridDof);
1302  def[pvIdx] = writer.allocateManagedScalarBuffer(numGridDof);
1303  }
1304 
1305  for (unsigned globalIdx = 0; globalIdx < numGridDof; ++ globalIdx)
1306  {
1307  for (int pvIdx = 0; pvIdx < numEq; ++pvIdx) {
1308  (*priVars[pvIdx])[globalIdx] = u[globalIdx][pvIdx];
1309  (*priVarWeight[pvIdx])[globalIdx] = asImp_().primaryVarWeight(globalIdx, pvIdx);
1310  (*delta[pvIdx])[globalIdx] = - deltaU[globalIdx][pvIdx];
1311  (*def[pvIdx])[globalIdx] = globalResid[globalIdx][pvIdx];
1312  }
1313 
1314  PrimaryVariables uOld(u[globalIdx]);
1315  PrimaryVariables uNew(uOld);
1316  uNew -= deltaU[globalIdx];
1317  (*relError)[globalIdx] = asImp_().relativeDofError(globalIdx, uOld, uNew);
1318  (*dofColor)[globalIdx] = linearizer().dofColor(globalIdx);
1319  }
1320 
1321  DiscBaseOutputModule::attachScalarDofData_(writer, *relError, "relErr");
1322 
1323  for (int i = 0; i < numEq; ++i) {
1324  std::ostringstream oss;
1325  oss.str(""); oss << "priVar_" << asImp_().primaryVarName(i);
1326  DiscBaseOutputModule::attachScalarDofData_(writer,
1327  *priVars[i],
1328  oss.str());
1329 
1330  oss.str(""); oss << "delta_" << asImp_().primaryVarName(i);
1331  DiscBaseOutputModule::attachScalarDofData_(writer,
1332  *delta[i],
1333  oss.str());
1334 
1335  oss.str(""); oss << "weight_" << asImp_().primaryVarName(i);
1336  DiscBaseOutputModule::attachScalarDofData_(writer,
1337  *priVarWeight[i],
1338  oss.str());
1339 
1340  oss.str(""); oss << "defect_" << asImp_().eqName(i);
1341  DiscBaseOutputModule::attachScalarDofData_(writer,
1342  *def[i],
1343  oss.str());
1344  }
1345 
1346  DiscBaseOutputModule::attachScalarDofData_(writer, *dofColor, "color");
1347 
1348  asImp_().prepareOutputFields();
1349  asImp_().appendOutputFields(writer);
1350  }
1351 
1356  void prepareOutputFields() const
1357  {
1358  auto modIt = outputModules_.begin();
1359  const auto &modEndIt = outputModules_.end();
1360  for (; modIt != modEndIt; ++modIt) {
1361  (*modIt)->allocBuffers();
1362  }
1363 
1364  // iterate over grid
1365  ElementContext elemCtx(simulator_);
1366 
1367  ElementIterator elemIt = this->gridView().template begin<0>();
1368  ElementIterator elemEndIt = this->gridView().template end<0>();
1369  for (; elemIt != elemEndIt; ++elemIt) {
1370  const Element& elem = *elemIt;
1371  if (elem.partitionType() != Dune::InteriorEntity)
1372  continue;
1373 
1374  elemCtx.updateStencil(elem);
1375  elemCtx.updateIntensiveQuantities(/*timeIdx=*/0);
1376  elemCtx.updateExtensiveQuantities(/*timeIdx=*/0);
1377 
1378  modIt = outputModules_.begin();
1379  for (; modIt != modEndIt; ++modIt)
1380  (*modIt)->processElement(elemCtx);
1381  }
1382  }
1383 
1389  {
1390  auto modIt = outputModules_.begin();
1391  const auto &modEndIt = outputModules_.end();
1392  for (; modIt != modEndIt; ++modIt)
1393  (*modIt)->commitBuffers(writer);
1394  }
1395 
1399  const GridView &gridView() const
1400  { return gridView_; }
1401 
1413  void addAuxiliaryModule(std::shared_ptr<BaseAuxiliaryModule<TypeTag> > auxMod)
1414  {
1415  auxMod->setDofOffset(numTotalDof());
1416  auxEqModules_.push_back(auxMod);
1417 
1418  // resize the solutions
1419  int nDof = numTotalDof();
1420  for (int timeIdx = 0; timeIdx < historySize; ++timeIdx) {
1421  solution_[timeIdx].resize(nDof);
1422  }
1423 
1424  auxMod->applyInitial();
1425  }
1426 
1433  { auxEqModules_.clear(); }
1434 
1438  size_t numAuxiliaryModules() const
1439  { return auxEqModules_.size(); }
1440 
1444  std::shared_ptr<BaseAuxiliaryModule<TypeTag> > auxiliaryModule(int auxEqModIdx)
1445  { return auxEqModules_[auxEqModIdx]; }
1446 
1450  std::shared_ptr<const BaseAuxiliaryModule<TypeTag> > auxiliaryModule(int auxEqModIdx) const
1451  { return auxEqModules_[auxEqModIdx]; }
1452 
1453 protected:
1454  template <class Context>
1455  void supplementInitialSolution_(PrimaryVariables &priVars,
1456  const Context &context, int dofIdx, int timeIdx)
1457  { }
1458 
1461 
1463  { return EWOMS_GET_PARAM(TypeTag, bool, EnableIntensiveQuantityCache); }
1464 
1466  { return EWOMS_GET_PARAM(TypeTag, bool, EnableThermodynamicHints); }
1467 
1476  {
1477  // add the output modules available on all model
1479  this->outputModules_.push_back(mod);
1480  }
1481 
1485  LocalResidual &localResidual_()
1486  { return localLinearizer_.localResidual(); }
1487 
1492  {
1493  // resize the vectors and set everything to not being on the boundary
1494  onBoundary_.resize(asImp_().numGridDof());
1495  std::fill(onBoundary_.begin(), onBoundary_.end(), /*value=*/false);
1496 
1497  // loop over all elements of the grid
1498  Stencil stencil(gridView_);
1499  ElementIterator elemIt = gridView_.template begin<0>();
1500  const ElementIterator elemEndIt = gridView_.template end<0>();
1501  for (; elemIt != elemEndIt; ++elemIt) {
1502  stencil.update(*elemIt);
1503 
1504  // do nothing if the element does not have boundary intersections
1505  if (stencil.numBoundaryFaces() == 0)
1506  continue;
1507 
1508  for (int dofIdx = 0; dofIdx < stencil.numPrimaryDof(); ++dofIdx) {
1509  int globalIdx = stencil.globalSpaceIndex(dofIdx);
1510  onBoundary_[globalIdx] = true;
1511  }
1512  }
1513  }
1514 
1518  bool verbose_() const
1519  { return gridView_.comm().rank() == 0; }
1520 
1521  Implementation &asImp_()
1522  { return *static_cast<Implementation*>(this); }
1523  const Implementation &asImp_() const
1524  { return *static_cast<const Implementation*>(this); }
1525 
1526  // the problem we want to solve. defines the constitutive
1527  // relations, matxerial laws, etc.
1529 
1530  // the representation of the spatial domain of the problem
1531  GridView gridView_;
1532 
1533  // a vector with all auxiliary equations to be considered
1534  std::vector<std::shared_ptr<BaseAuxiliaryModule<TypeTag> > > auxEqModules_;
1535 
1537 
1538  // calculates the local jacobian matrix for a given element
1539  std::vector<LocalLinearizer> localLinearizer_;
1540  // Linearizes the problem at the current time step using the
1541  // local jacobian
1542  Linearizer *linearizer_;
1543 
1544  // cur is the current iterative solution, prev the converged
1545  // solution of the previous time step
1546  mutable SolutionVector solution_[historySize];
1547  mutable IntensiveQuantitiesVector intensiveQuantityCache_[historySize];
1548  mutable std::vector<bool> intensiveQuantityCacheUpToDate_[historySize];
1549 
1550  // all the index of the BoundaryTypes object for a vertex
1551  std::vector<bool> onBoundary_;
1552 
1553  std::list<BaseOutputModule<TypeTag>*> outputModules_;
1554 
1556  std::vector<Scalar> dofTotalVolume_;
1557  std::vector<bool> isLocalDof_;
1558 };
1559 } // namespace Ewoms
1560 
1561 #endif
1562 
void shiftIntensiveQuantityCache(int numSlots=1)
Move the intensive quantities for a given time index to the back.
Definition: fvbasediscretization.hh:582
Scalar dofTotalVolume(int globalIdx) const
Returns the volume of a given control volume.
Definition: fvbasediscretization.hh:852
SolutionVector solution_[historySize]
Definition: fvbasediscretization.hh:1546
void updateBegin()
Called by the update() method before it tries to apply the newton method. This is primary a hook whic...
Definition: fvbasediscretization.hh:1028
void applyInitialSolution()
Applies the initial solution for all degrees of freedom to which the model applies.
Definition: fvbasediscretization.hh:428
const VertexMapper & vertexMapper() const
Mapper for vertices to indices.
Definition: fvbasediscretization.hh:1196
Linearizer & linearizer()
Returns the object which linearizes the global system of equations at the current solution...
Definition: fvbasediscretization.hh:895
void updateBoundary_()
Find the degrees of freedoms adjacent to the grid boundary.
Definition: fvbasediscretization.hh:1491
Represents the primary variables used by the a model.
std::list< BaseOutputModule< TypeTag > * > outputModules_
Definition: fvbasediscretization.hh:1553
This is a grid manager which does not create any border list.
void globalStorage(EqVector &storage, int timeIdx=0) const
Compute the integral over the domain of the storage terms of all conservation quantities.
Definition: fvbasediscretization.hh:685
This is a grid manager which does not create any border list.
Definition: nullborderlistmanager.hh:50
Scalar timeStepSize() const
Returns the time step length so that we don't miss the beginning of the next episode or cross the en...
Definition: simulator.hh:296
const GridView & gridView() const
Reference to the grid view of the spatial domain.
Definition: fvbasediscretization.hh:1399
size_t numAuxiliaryModules() const
Returns the number of modules for auxiliary equations.
Definition: fvbasediscretization.hh:1438
This class stores an array of IntensiveQuantities objects, one intensive quantities object for each o...
Definition: fvbaseelementcontext.hh:44
size_t numAuxiliaryDof() const
Returns the number of degrees of freedom (DOFs) of the auxiliary equations.
Definition: fvbasediscretization.hh:1168
void beginParallel(EntityIterator &threadPrivateIt)
Definition: threadedentityiterator.hh:53
SET_SCALAR_PROP(NumericModel, EndTime,-1e100)
The default value for the simulation's end time.
Problem & problem()
Return the object which specifies the pysical setup of the simulation.
Definition: simulator.hh:189
const SolutionVector & solution(int timeIdx) const
Reference to the solution at a given history index as a block vector.
Definition: fvbasediscretization.hh:875
SolutionVector & solution(int timeIdx)
Reference to the solution at a given history index as a block vector.
Definition: fvbasediscretization.hh:881
const IntensiveQuantities * cachedIntensiveQuantities(int globalIdx, int timeIdx) const
Return the cached intensive quantities for a entity on the grid at given time.
Definition: fvbasediscretization.hh:529
void unlock()
Definition: locks.hh:77
Declare the properties used by the infrastructure code of the finite volume discretizations.
GridView gridView_
Definition: fvbasediscretization.hh:1531
The multi-dimensional Newton method.
Definition: newtonmethod.hh:54
LocalLinearizer & localLinearizer(int openMpThreadId)
Definition: fvbasediscretization.hh:911
NewtonMethod newtonMethod_
Definition: fvbasediscretization.hh:1536
void supplementInitialSolution_(PrimaryVariables &priVars, const Context &context, int dofIdx, int timeIdx)
Definition: fvbasediscretization.hh:1455
static void registerParameters()
Register all run-time parameters for the Newton method.
Definition: newtonmethod.hh:198
#define GET_PROP_VALUE(TypeTag, PropTagName)
Access the value attribute of a property for a type tag.
Definition: propertysystem.hh:468
The common code for the linearizers of non-linear systems of equations.
Definition: fvbaselinearizer.hh:60
LocalResidual & localResidual_()
Reference to the local residal object.
Definition: fvbasediscretization.hh:1485
NewtonMethod & newtonMethod()
Returns the newton method object.
Definition: fvbasediscretization.hh:477
static void registerParameters()
Register all run-time parameters for the model.
Definition: fvbasediscretization.hh:334
const ElementMapper & elementMapper() const
Mapper for elements to indices.
Definition: fvbasediscretization.hh:1202
void deserialize(Restarter &res)
Deserializes the state of the model.
Definition: fvbasediscretization.hh:1097
Implementation & asImp_()
Definition: fvbasediscretization.hh:1521
#define GET_PROP_TYPE(TypeTag, PropTagName)
Access the type attribute of a property for a type tag.
Definition: propertysystem.hh:485
The common code for the linearizers of non-linear systems of equations.
~FvBaseDiscretization()
Definition: fvbasediscretization.hh:320
This class implements an exception-safe scoped lock-keeper.
Definition: locks.hh:63
Calculates the local residual and its Jacobian for a single element of the grid.
Represents all quantities which available for calculating constraints.
Definition: fvbaseconstraintscontext.hh:41
void addOutputModule(BaseOutputModule< TypeTag > *newModule)
Add an module for writing visualization output after a timestep.
Definition: fvbasediscretization.hh:1267
void addAuxiliaryModule(std::shared_ptr< BaseAuxiliaryModule< TypeTag > > auxMod)
Add a module for an auxiliary equation.
Definition: fvbasediscretization.hh:1413
static void registerParameters()
Register all run-time parameters for the Vtk output module.
Definition: vtkprimaryvarsmodule.hh:80
bool onBoundary(int globalIdx) const
Return whether a degree of freedom is located on the domain boundary.
Definition: fvbasediscretization.hh:1222
void updateSuccessful()
Called by the update() method if it was successful. This is primary a hook which the actual model can...
Definition: fvbasediscretization.hh:1037
std::shared_ptr< const BaseAuxiliaryModule< TypeTag > > auxiliaryModule(int auxEqModIdx) const
Returns a given module for auxiliary equations.
Definition: fvbasediscretization.hh:1450
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:736
static bool storeIntensiveQuantities_()
Definition: fvbasediscretization.hh:1459
SET_PROP(NumericModel, ParameterTree)
Set the ParameterTree property.
Definition: basicproperties.hh:117
std::vector< LocalLinearizer > localLinearizer_
Definition: fvbasediscretization.hh:1539
bool isLocalDof(int globalIdx) const
Returns if the overlap of the volume ofa degree of freedom is non-zero.
Definition: fvbasediscretization.hh:860
void addPrePostProcessTime(Scalar value)
Definition: simulator.hh:623
Represents all quantities which available for calculating constraints.
SET_INT_PROP(NumericModel, GridGlobalRefinements, 0)
Represents the primary variables used by the a model.
Definition: fvbaseprimaryvariables.hh:41
Calculates the Jacobian of the local residual for finite volume spatial discretizations using a finit...
Simplifies multi-threaded capabilities.
Definition: threadmanager.hh:48
size_t numGridDof() const
Returns the number of degrees of freedom (DOFs) for the computational grid.
Definition: fvbasediscretization.hh:1161
void updateCachedIntensiveQuantities(const IntensiveQuantities &intQuants, int globalIdx, int timeIdx) const
Update the intensive quantity cache for a entity on the grid at given time.
Definition: fvbasediscretization.hh:546
Scalar globalResidual(GlobalEqVector &dest, const SolutionVector &u) const
Compute the global residual for an arbitrary solution vector.
Definition: fvbasediscretization.hh:605
The base class for the finite volume discretization schemes.
FvBaseDiscretization(Simulator &simulator)
Definition: fvbasediscretization.hh:298
const NewtonMethod & newtonMethod() const
Returns the newton method object.
Definition: fvbasediscretization.hh:483
std::vector< bool > isLocalDof_
Definition: fvbasediscretization.hh:1557
std::vector< bool > intensiveQuantityCacheUpToDate_[historySize]
Definition: fvbasediscretization.hh:1548
void finishInit()
Apply the initial conditions to the model.
Definition: fvbasediscretization.hh:355
The base class for all output writers.
Definition: baseoutputwriter.hh:41
SET_TYPE_PROP(NumericModel, Scalar, double)
Set the default type of scalar values to double.
static std::string discretizationName()
Returns a string of discretization's human-readable name.
Definition: fvbasediscretization.hh:1228
const IntensiveQuantities * thermodynamicHint(int globalIdx, int timeIdx) const
Return the thermodynamic hint for a entity on the grid at given time.
Definition: fvbasediscretization.hh:501
bool apply()
Run the Newton method.
Definition: newtonmethod.hh:281
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:1141
Manages the initializing and running of time dependent problems.
Definition: simulator.hh:73
Provide the properties at a face which make sense indepentently of the conserved quantities.
Definition: fvbaseextensivequantities.hh:41
Scalar primaryVarWeight(int globalDofIdx, int pvIdx) const
Returns the relative weight of a primary variable for calculating relative errors.
Definition: fvbasediscretization.hh:932
Definition: baseauxiliarymodule.hh:35
Manages the initializing and running of time dependent problems.
std::vector< Scalar > dofTotalVolume_
Definition: fvbasediscretization.hh:1556
Provide the properties at a face which make sense indepentently of the conserved quantities.
ScalarBuffer * allocateManagedScalarBuffer(int numEntities)
Allocate a managed buffer for a scalar field.
Definition: vtkmultiwriter.hh:147
const DofMapper & dofMapper() const
Mapper to convert the Dune entities of the discretization's degrees of freedoms are to indices...
Definition: fvbasediscretization.hh:1189
void syncOverlap()
Syncronize the values of the primary variables on the degrees of freedom that overlap with the neighb...
Definition: fvbasediscretization.hh:1020
Base class for the model specific class which provides access to all intensive (i.e., volume averaged) quantities.
Definition: fvbaseintensivequantities.hh:42
static bool enableThermodynamicHints_()
Definition: fvbasediscretization.hh:1465
const LocalLinearizer & localLinearizer(int openMpThreadId) const
Returns the local jacobian which calculates the local stiffness matrix for an arbitrary element...
Definition: fvbasediscretization.hh:906
bool update(NewtonMethod &solver)
Try to progress the model to the next timestep.
Definition: fvbasediscretization.hh:977
Provides data handles for parallel communication which operate on DOFs.
static int maxThreads()
Return the maximum number of threads of the current process.
Definition: threadmanager.hh:117
#define EWOMS_REGISTER_PARAM(TypeTag, ParamType, ParamName, Description)
Register a run-time parameter.
Definition: parametersystem.hh:64
This class calculates gradients of arbitrary quantities at flux integration points using the two-poin...
std::shared_ptr< BaseAuxiliaryModule< TypeTag > > auxiliaryModule(int auxEqModIdx)
Returns a given module for auxiliary equations.
Definition: fvbasediscretization.hh:1444
Class to specify constraints for a finite volume spatial discretization.
Provides an STL-iterator like interface to iterate over the enties of a GridView in OpenMP threaded a...
Definition: threadedentityiterator.hh:39
static int threadId()
Return the index of the current OpenMP thread.
Definition: threadmanager.hh:123
void resetLinearizer()
Resets the Jacobian matrix linearizer, so that the boundary types can be altered. ...
Definition: fvbasediscretization.hh:1209
IntensiveQuantitiesVector intensiveQuantityCache_[historySize]
Definition: fvbasediscretization.hh:1547
Base class for the model specific class which provides access to all intensive (i.e., volume averaged) quantities.
void updatePVWeights(const ElementContext &elemCtx) const
Update the weights of all primary variables within an element given the complete set of intensive qua...
Definition: fvbasediscretization.hh:1261
void appendOutputFields(BaseOutputWriter &writer) const
Append the quantities relevant for the current solution to an output writer.
Definition: fvbasediscretization.hh:1388
std::string eqName(int eqIdx) const
Given an equation index, return a human readable name.
Definition: fvbasediscretization.hh:1248
Model & model()
Return the physical model used in the simulation.
Definition: simulator.hh:176
Represents all quantities which available on boundary segments.
const LocalResidual & localResidual(int openMpThreadId) const
Returns the object to calculate the local residual function.
Definition: fvbasediscretization.hh:917
Implements a shallow wrapper around the "raw" locks provided by OpenMP.
Definition: locks.hh:35
A Newton method for models using a finite volume discretization.
Simulator & simulator_
Definition: fvbasediscretization.hh:1528
void advanceTimeLevel()
Called by the problem if a time integration was successful, post processing of the solution is done a...
Definition: fvbasediscretization.hh:1064
This class stores an array of IntensiveQuantities objects, one intensive quantities object for each o...
Represents all quantities which available on boundary segments.
Definition: fvbaseboundarycontext.hh:41
Scalar eqWeight(int globalVertexIdx, int eqIdx) const
Returns the relative weight of an equation.
Definition: fvbasediscretization.hh:944
VTK output module for the fluid composition.
Definition: vtkprimaryvarsmodule.hh:56
Base class for specifying auxiliary equations.
Definition: baseauxiliarymodule.hh:57
void setIntensiveQuantitiesCacheEntryValidity(int globalIdx, int timeIdx, bool newValue) const
Invalidate the cache for a given intensive quantities object.
Definition: fvbasediscretization.hh:564
LocalResidual & localResidual(int openMpThreadId)
Definition: fvbasediscretization.hh:922
void registerOutputModules_()
Register all output modules which make sense for the model.
Definition: fvbasediscretization.hh:1475
GridView & gridView()
Return the grid view for which the simulation is done.
Definition: simulator.hh:164
Element-wise caculation of the residual matrix for models based on a finite volume spatial discretiza...
void clearAuxiliaryModules()
Causes the list of auxiliary equations to be cleared.
Definition: fvbasediscretization.hh:1432
Scalar globalResidual(GlobalEqVector &dest) const
Compute the global residual for the current solution vector.
Definition: fvbasediscretization.hh:621
void serializeEntity(std::ostream &outstream, const DofEntity &dof)
Write the current solution for a degree of freedom to a restart file.
Definition: fvbasediscretization.hh:1113
void increment(EntityIterator &threadPrivateIt)
Definition: threadedentityiterator.hh:68
std::vector< std::shared_ptr< BaseAuxiliaryModule< TypeTag > > > auxEqModules_
Definition: fvbasediscretization.hh:1534
Scalar gridTotalVolume() const
Returns the volume of the whole grid which represents the spatial domain.
Definition: fvbasediscretization.hh:867
size_t numTotalDof() const
Returns the total number of degrees of freedom (i.e., grid plux auxiliary DOFs)
Definition: fvbasediscretization.hh:1182
double realTimeElapsed() const
Return the real time [s] elapsed.
Definition: timer.hh:100
Provides an encapsulation to measure the system time.
Definition: timer.hh:47
Element-wise caculation of the residual matrix for models based on a finite volume spatial discretiza...
Definition: fvbaselocalresidual.hh:52
void updateFailed()
Called by the update() method if it was unsuccessful. This is primary a hook which the actual model c...
Definition: fvbasediscretization.hh:1045
bool verbose_() const
Returns whether messages should be printed.
Definition: fvbasediscretization.hh:1518
bool isFinished(const EntityIterator &threadPrivateIt) const
Definition: threadedentityiterator.hh:63
const Implementation & asImp_() const
Definition: fvbasediscretization.hh:1523
This class calculates gradients of arbitrary quantities at flux integration points using the two-poin...
Definition: fvbasegradientcalculator.hh:44
static bool enableIntensiveQuantitiesCache_()
Definition: fvbasediscretization.hh:1462
The base class for the finite volume discretization schemes.
Definition: fvbasediscretization.hh:68
SET_BOOL_PROP(FvBaseDiscretization, EnableVtkOutput, true)
Enable the VTK output by default.
Linearizer * linearizer_
Definition: fvbasediscretization.hh:1542
void start()
Start counting the time resources used by the simulation.
Definition: timer.hh:68
Base class for specifying auxiliary equations.
Simplifies multi-threaded capabilities.
void serialize(Restarter &res)
Serializes the current state of the model.
Definition: fvbasediscretization.hh:1082
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:1279
std::vector< bool > onBoundary_
Definition: fvbasediscretization.hh:1551
The base class for writer modules.
Definition: baseoutputmodule.hh:71
Scalar gridTotalVolume_
Definition: fvbasediscretization.hh:1555
Scalar relativeDofError(int vertexIdx, const PrimaryVariables &pv1, const PrimaryVariables &pv2) const
Returns the relative error between two vectors of primary variables.
Definition: fvbasediscretization.hh:956
std::string primaryVarName(int pvIdx) const
Given an primary variable index, return a human readable name.
Definition: fvbasediscretization.hh:1236
Simplifies writing multi-file VTK datasets.
Definition: vtkmultiwriter.hh:61
const Linearizer & linearizer() const
Returns the operator linearizer for the global jacobian of the problem.
Definition: fvbasediscretization.hh:888
Class to specify constraints for a finite volume spatial discretization.
Definition: fvbaseconstraints.hh:45
#define EWOMS_GET_PARAM(TypeTag, ParamType, ParamName)
Retrieve a runtime parameter.
Definition: parametersystem.hh:95
void prepareOutputFields() const
Prepare the quantities relevant for the current solution to be appended to the output writers...
Definition: fvbasediscretization.hh:1356
void stop()
Stop counting the time resources used by the simulation.
Definition: timer.hh:77