stokeslocalresidual.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) 2012-2013 by Andreas Lauser
5  Copyright (C) 2012 by Christoph Grueninger
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_STOKES_LOCAL_RESIDUAL_HH
28 #define EWOMS_STOKES_LOCAL_RESIDUAL_HH
29 
32 #include "stokesproperties.hh"
33 
34 #include <opm/material/common/Valgrind.hpp>
35 
36 #include <dune/grid/common/grid.hh>
37 #include <dune/common/fvector.hh>
38 
39 namespace Ewoms {
40 
46 template<class TypeTag>
48  : public GET_PROP_TYPE(TypeTag, DiscLocalResidual)
49 {
50  typedef typename GET_PROP_TYPE(TypeTag, DiscLocalResidual) ParentType;
51  typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
52  typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
53  typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
54  typedef typename GET_PROP_TYPE(TypeTag, EqVector) EqVector;
55  typedef typename GET_PROP_TYPE(TypeTag, RateVector) RateVector;
56  typedef typename GET_PROP_TYPE(TypeTag, IntensiveQuantities) IntensiveQuantities;
57  typedef typename GET_PROP_TYPE(TypeTag, ExtensiveQuantities) ExtensiveQuantities;
58  typedef typename GET_PROP_TYPE(TypeTag, ElementContext) ElementContext;
59  typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
60 
61  enum { dimWorld = GridView::dimensionworld };
62  enum { phaseIdx = GET_PROP_VALUE(TypeTag, StokesPhaseIndex) };
63  enum { numComponents = FluidSystem::numComponents };
64  enum { conti0EqIdx = Indices::conti0EqIdx };
65  enum { momentum0EqIdx = Indices::momentum0EqIdx };
66  enum { enableEnergy = GET_PROP_VALUE(TypeTag, EnableEnergy) };
67 
69  typedef Dune::FieldVector<Scalar, dimWorld> DimVector;
70 
71 public:
75  static void registerParameters()
76  {
77  ParentType::registerParameters();
78 
79  EWOMS_REGISTER_PARAM(TypeTag, bool, EnableNavierTerm,
80  "Enable the Navier term (convective flux term).");
81  }
82 
86  void computeStorage(EqVector &storage,
87  const ElementContext &elemCtx,
88  int dofIdx,
89  int timeIdx) const
90  {
91  const auto &intQuants = elemCtx.intensiveQuantities(dofIdx, timeIdx);
92  const auto &fs = intQuants.fluidState();
93 
94  // mass storage
95  for (int compIdx = 0; compIdx < numComponents; ++compIdx) {
96  storage[conti0EqIdx + compIdx] = fs.molarity(phaseIdx, compIdx);
97  }
98  Valgrind::CheckDefined(storage);
99 
100  // momentum balance
101  for (int axisIdx = 0; axisIdx < dimWorld; ++ axisIdx) {
102  storage[momentum0EqIdx + axisIdx] =
103  fs.density(phaseIdx) * intQuants.velocity()[axisIdx];
104  }
105  Valgrind::CheckDefined(storage);
106 
107  EnergyModule::addPhaseStorage(storage, elemCtx.intensiveQuantities(dofIdx, timeIdx), phaseIdx);
108  Valgrind::CheckDefined(storage);
109  }
110 
114  void computeFlux(RateVector &flux, const ElementContext &elemCtx,
115  int scvfIdx, int timeIdx) const
116  {
117  flux = 0.0;
118  addAdvectiveFlux(flux, elemCtx, scvfIdx, timeIdx);
119  Valgrind::CheckDefined(flux);
120  addDiffusiveFlux(flux, elemCtx, scvfIdx, timeIdx);
121  Valgrind::CheckDefined(flux);
122  }
123 
127  void addAdvectiveFlux(RateVector &flux, const ElementContext &elemCtx,
128  int scvfIdx, int timeIdx) const
129  {
130  const ExtensiveQuantities &extQuants = elemCtx.extensiveQuantities(scvfIdx, timeIdx);
131 
132  // data attached to upstream DOF
133  const IntensiveQuantities &up =
134  elemCtx.intensiveQuantities(extQuants.upstreamIndex(phaseIdx), timeIdx);
135 
136  auto normal = extQuants.normal();
137 
138  // mass fluxes
139  Scalar vTimesN = extQuants.velocity() * normal;
140  for (int compIdx = 0; compIdx < numComponents; ++compIdx)
141  flux[conti0EqIdx + compIdx] = up.fluidState().molarity(phaseIdx, compIdx) * vTimesN;
142 
143  // momentum flux
144  Scalar mu =
145  up.fluidState().viscosity(phaseIdx)
146  + extQuants.eddyViscosity();
147  for (int axisIdx = 0; axisIdx < dimWorld; ++axisIdx) {
148  // deal with the surface forces, i.e. the $\div[ \mu
149  // (\grad[v] + \grad[v^T])]$ term on the right hand side
150  // of the equation
151  DimVector tmp;
152  for (int j = 0; j < dimWorld; ++j) {
153  tmp[j] = extQuants.velocityGrad(/*velocityComp=*/axisIdx)[j];
154  tmp[j] += extQuants.velocityGrad(/*velocityComp=*/j)[axisIdx];
155  }
156 
157  flux[momentum0EqIdx + axisIdx] = -mu * (tmp * normal);
158 
159  // this adds the convective momentum flux term $rho v
160  // div[v]$ to the Stokes equation, transforming it to
161  // Navier-Stokes.
162  if (enableNavierTerm_()) {
163  flux[momentum0EqIdx + axisIdx] +=
164  up.velocity()[axisIdx] * (up.velocity() * normal);
165  }
166  }
167 
168  EnergyModule::addAdvectiveFlux(flux, elemCtx, scvfIdx, timeIdx);
169  }
170 
174  void addDiffusiveFlux(RateVector &flux, const ElementContext &elemCtx,
175  int scvfIdx, int timeIdx) const
176  {
177  // heat conduction
178  EnergyModule::addDiffusiveFlux(flux, elemCtx, scvfIdx, timeIdx);
179  }
180 
184  void computeSource(RateVector &source,
185  const ElementContext &elemCtx,
186  int dofIdx,
187  int timeIdx) const
188  {
189  assert(timeIdx == 0);
190  const auto &intQuants = elemCtx.intensiveQuantities(dofIdx, timeIdx);
191 
192  // retrieve the source term intrinsic to the problem
193  Valgrind::SetUndefined(source);
194  elemCtx.problem().source(source, elemCtx, dofIdx, timeIdx);
195  Valgrind::CheckDefined(source);
196 
197  const auto &gravity = intQuants.gravity();
198  const auto &gradp = intQuants.pressureGradient();
199  Scalar density = intQuants.fluidState().density(phaseIdx);
200 
201  assert(std::isfinite(gradp.two_norm()));
202  assert(std::isfinite(density));
203  assert(std::isfinite(source.two_norm()));
204 
205  Valgrind::CheckDefined(gravity);
206  Valgrind::CheckDefined(gradp);
207  Valgrind::CheckDefined(density);
208 
209  // deal with the pressure and volumetric terms
210  for (int axisIdx = 0; axisIdx < dimWorld; ++axisIdx)
211  source[momentum0EqIdx + axisIdx] +=
212  gradp[axisIdx] - density * gravity[axisIdx];
213  }
214 
215 private:
216  static bool enableNavierTerm_()
217  { return EWOMS_GET_PARAM(TypeTag, bool, EnableNavierTerm); }
218 };
219 
220 } // namespace Ewoms
221 
222 #endif
Declares the properties required by the Stokes model.
#define GET_PROP_VALUE(TypeTag, PropTagName)
Access the value attribute of a property for a type tag.
Definition: propertysystem.hh:468
The local residual function for problems using the Stokes model.
Definition: stokeslocalresidual.hh:47
void computeStorage(EqVector &storage, const ElementContext &elemCtx, int dofIdx, int timeIdx) const
Evaluate the amount all conservation quantities (e.g. phase mass) within a finite sub-control volume...
Definition: stokeslocalresidual.hh:86
#define GET_PROP_TYPE(TypeTag, PropTagName)
Access the type attribute of a property for a type tag.
Definition: propertysystem.hh:485
void computeFlux(RateVector &flux, const ElementContext &elemCtx, int scvfIdx, int timeIdx) const
Evaluates the total mass flux of all conservation quantities over a face of a sub-control volume...
Definition: stokeslocalresidual.hh:114
static void registerParameters()
Register all run-time parameters for the local residual.
Definition: stokeslocalresidual.hh:75
Provides the auxiliary methods required for consideration of the energy equation. ...
Definition: energymodule.hh:54
Definition: baseauxiliarymodule.hh:35
#define EWOMS_REGISTER_PARAM(TypeTag, ParamType, ParamName, Description)
Register a run-time parameter.
Definition: parametersystem.hh:64
Contains the intensive quantities of the Stokes model.
Contains the data which is required to calculate the mass and momentum fluxes over the face of a sub-...
void addAdvectiveFlux(RateVector &flux, const ElementContext &elemCtx, int scvfIdx, int timeIdx) const
Add the advective mass flux at a given flux integration point.
Definition: stokeslocalresidual.hh:127
void addDiffusiveFlux(RateVector &flux, const ElementContext &elemCtx, int scvfIdx, int timeIdx) const
Adds the diffusive flux at a given flux integration point.
Definition: stokeslocalresidual.hh:174
void computeSource(RateVector &source, const ElementContext &elemCtx, int dofIdx, int timeIdx) const
Calculate the source term of the equation.
Definition: stokeslocalresidual.hh:184
#define EWOMS_GET_PARAM(TypeTag, ParamType, ParamName)
Retrieve a runtime parameter.
Definition: parametersystem.hh:95