diffusionmodule.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) 2011-2013 by Andreas Lauser
5 
6  This file is part of the Open Porous Media project (OPM).
7 
8  OPM is free software: you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation, either version 2 of the License, or
11  (at your option) any later version.
12 
13  OPM is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with OPM. If not, see <http://www.gnu.org/licenses/>.
20 */
26 #ifndef EWOMS_DIFFUSION_MODULE_HH
27 #define EWOMS_DIFFUSION_MODULE_HH
28 
31 
32 #include <dune/common/fvector.hh>
33 
34 namespace Ewoms {
35 namespace Properties {
36 NEW_PROP_TAG(Indices);
37 }
38 
45 template <class TypeTag, bool enableDiffusion>
47 
51 template <class TypeTag>
52 class DiffusionModule<TypeTag, /*enableDiffusion=*/false>
53 {
54  typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
55  typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
56  typedef typename GET_PROP_TYPE(TypeTag, RateVector) RateVector;
57  typedef typename FluidSystem::ParameterCache ParameterCache;
58 
59 public:
63  static void registerParameters()
64  {}
65 
70  template <class Context>
71  static void addDiffusiveFlux(RateVector &flux, const Context &context,
72  int spaceIdx, int timeIdx)
73  {}
74 };
75 
79 template <class TypeTag>
80 class DiffusionModule<TypeTag, /*enableDiffusion=*/true>
81 {
82  typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
83  typedef typename GET_PROP_TYPE(TypeTag, Evaluation) Evaluation;
84  typedef typename GET_PROP_TYPE(TypeTag, RateVector) RateVector;
85  typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
86  typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
87 
88  enum { numPhases = FluidSystem::numPhases };
89  enum { numComponents = FluidSystem::numComponents };
90  enum { conti0EqIdx = Indices::conti0EqIdx };
91 
92  typedef Opm::MathToolbox<Evaluation> Toolbox;
93 
94 public:
98  static void registerParameters()
99  {}
100 
105  template <class Context>
106  static void addDiffusiveFlux(RateVector &flux, const Context &context,
107  int spaceIdx, int timeIdx)
108  {
109  const auto &extQuants = context.extensiveQuantities(spaceIdx, timeIdx);
110 
111  const auto &fluidStateI = context.intensiveQuantities(extQuants.interiorIndex(), timeIdx).fluidState();
112  const auto &fluidStateJ = context.intensiveQuantities(extQuants.exteriorIndex(), timeIdx).fluidState();
113 
114  for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
115  // arithmetic mean of the phase's molar density
116  Evaluation rhoMolar = fluidStateI.molarDensity(phaseIdx);
117  rhoMolar += Toolbox::value(fluidStateJ.molarDensity(phaseIdx));
118  rhoMolar /= 2;
119 
120  for (int compIdx = 0; compIdx < numComponents; ++compIdx)
121  // mass flux due to molecular diffusion
122  flux[conti0EqIdx + compIdx] +=
123  -rhoMolar
124  * extQuants.moleFractionGradientNormal(phaseIdx, compIdx)
125  * extQuants.effectiveDiffusionCoefficient(phaseIdx, compIdx);
126  }
127  }
128 };
129 
137 template <class TypeTag, bool enableDiffusion>
139 
143 template <class TypeTag>
144 class DiffusionIntensiveQuantities<TypeTag, /*enableDiffusion=*/false>
145 {
146  typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
147  typedef typename GET_PROP_TYPE(TypeTag, ElementContext) ElementContext;
148  typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
149 
150  typedef typename FluidSystem::ParameterCache ParameterCache;
151 
152 public:
157  Scalar tortuosity(int phaseIdx) const
158  {
159  OPM_THROW(std::logic_error, "Method tortuosity() does not make sense "
160  "if diffusion is disabled");
161  }
162 
167  Scalar diffusionCoefficient(int phaseIdx, int compIdx) const
168  {
169  OPM_THROW(std::logic_error, "Method diffusionCoefficient() does not "
170  "make sense if diffusion is disabled");
171  }
172 
177  Scalar effectiveDiffusionCoefficient(int phaseIdx, int compIdx) const
178  {
179  OPM_THROW(std::logic_error, "Method effectiveDiffusionCoefficient() "
180  "does not make sense if diffusion is "
181  "disabled");
182  }
183 
184 protected:
189  template <class FluidState>
190  void update_(FluidState &fs,
191  ParameterCache &paramCache,
192  const ElementContext &elemCtx,
193  int dofIdx,
194  int timeIdx)
195  { }
196 };
197 
201 template <class TypeTag>
202 class DiffusionIntensiveQuantities<TypeTag, /*enableDiffusion=*/true>
203 {
204  typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
205  typedef typename GET_PROP_TYPE(TypeTag, ElementContext) ElementContext;
206  typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
207 
208  typedef typename FluidSystem::ParameterCache ParameterCache;
209 
210  enum { numPhases = FluidSystem::numPhases };
211  enum { numComponents = FluidSystem::numComponents };
212 
213 public:
218  Scalar diffusionCoefficient(int phaseIdx, int compIdx) const
219  { return diffusionCoefficient_[phaseIdx][compIdx]; }
220 
225  Scalar tortuosity(int phaseIdx) const
226  { return tortuosity_[phaseIdx]; }
227 
232  Scalar effectiveDiffusionCoefficient(int phaseIdx, int compIdx) const
233  { return tortuosity_[phaseIdx] * diffusionCoefficient_[phaseIdx][compIdx]; }
234 
235 protected:
240  template <class FluidState>
241  void update_(FluidState &fluidState,
242  ParameterCache &paramCache,
243  const ElementContext &elemCtx,
244  int dofIdx,
245  int timeIdx)
246  {
247  const auto &intQuants = elemCtx.intensiveQuantities(dofIdx, timeIdx);
248 
249  for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
250  if (!elemCtx.model().phaseIsConsidered(phaseIdx))
251  continue;
252 
253  // TODO: let the problem do this (this is a constitutive
254  // relation of which the model should be free of from the
255  // abstraction POV!)
256  tortuosity_[phaseIdx] =
257  1.0 / (intQuants.porosity() * intQuants.porosity())
258  * std::pow(std::max(0.0001,
259  intQuants.porosity()
260  * intQuants.fluidState().saturation(phaseIdx)),
261  7.0 / 3);
262 
263  for (int compIdx = 0; compIdx < numComponents; ++compIdx) {
264  diffusionCoefficient_[phaseIdx][compIdx] =
265  FluidSystem::diffusionCoefficient(fluidState,
266  paramCache,
267  phaseIdx,
268  compIdx);
269  }
270  }
271  }
272 
273 private:
274  Scalar tortuosity_[numPhases];
275  Scalar diffusionCoefficient_[numPhases][numComponents];
276 };
277 
284 template <class TypeTag, bool enableDiffusion>
286 
290 template <class TypeTag>
291 class DiffusionExtensiveQuantities<TypeTag, /*enableDiffusion=*/false>
292 {
293  typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
294  typedef typename GET_PROP_TYPE(TypeTag, ElementContext) ElementContext;
295 
296 protected:
301  void update_(const ElementContext &elemCtx, int faceIdx, int timeIdx)
302  {}
303 
304  template <class Context, class FluidState>
305  void updateBoundary_(const Context &context, int bfIdx, int timeIdx,
306  const FluidState &fluidState)
307  {}
308 
309 public:
316  Scalar moleFractionGradientNormal(int phaseIdx, int compIdx) const
317  {
318  OPM_THROW(std::logic_error, "Method moleFractionGradient() does not "
319  "make sense if diffusion is disabled.");
320  }
321 
329  Scalar effectiveDiffusionCoefficient(int phaseIdx, int compIdx) const
330  {
331  OPM_THROW(std::logic_error, "Method effectiveDiffusionCoefficient() "
332  "does not make sense if diffusion is "
333  "disabled.");
334  }
335 };
336 
340 template <class TypeTag>
341 class DiffusionExtensiveQuantities<TypeTag, /*enableDiffusion=*/true>
342 {
343  typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
344  typedef typename GET_PROP_TYPE(TypeTag, ElementContext) ElementContext;
345  typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
346 
347  enum { dimWorld = GridView::dimensionworld };
348  enum { numPhases = GET_PROP_VALUE(TypeTag, NumPhases) };
349  enum { numComponents = GET_PROP_VALUE(TypeTag, NumComponents) };
350 
351  typedef Dune::FieldVector<Scalar, dimWorld> DimVector;
352 
353 protected:
358  void update_(const ElementContext &elemCtx, int faceIdx, int timeIdx)
359  {
360  const auto& gradCalc = elemCtx.gradientCalculator();
361  Ewoms::MoleFractionCallback<TypeTag> moleFractionCallback(elemCtx);
362 
363  DimVector temperatureGrad;
364 
365  const auto &face = elemCtx.stencil(timeIdx).interiorFace(faceIdx);
366  const auto &extQuants = elemCtx.extensiveQuantities(faceIdx, timeIdx);
367 
368  const auto &intQuantsInside = elemCtx.intensiveQuantities(extQuants.interiorIndex(), timeIdx);
369  const auto &intQuantsOutside = elemCtx.intensiveQuantities(extQuants.exteriorIndex(), timeIdx);
370 
371  for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
372  if (!elemCtx.model().phaseIsConsidered(phaseIdx))
373  continue;
374 
375  moleFractionCallback.setPhaseIndex(phaseIdx);
376  for (int compIdx = 0; compIdx < numComponents; ++compIdx) {
377  moleFractionCallback.setComponentIndex(compIdx);
378 
379  DimVector moleFractionGradient(0.0);
380  gradCalc.calculateGradient(moleFractionGradient,
381  elemCtx,
382  faceIdx,
383  moleFractionCallback);
384 
385  moleFractionGradientNormal_[phaseIdx][compIdx] =
386  face.normal()*moleFractionGradient;
387  Valgrind::CheckDefined(moleFractionGradientNormal_[phaseIdx][compIdx]);
388 
389  // use the arithmetic average for the effective
390  // diffusion coefficients.
391  effectiveDiffusionCoefficient_[phaseIdx][compIdx] =
392  (intQuantsInside.effectiveDiffusionCoefficient(phaseIdx, compIdx)
393  +
394  intQuantsOutside.effectiveDiffusionCoefficient(phaseIdx, compIdx))
395  / 2;
396 
397  Valgrind::CheckDefined(effectiveDiffusionCoefficient_[phaseIdx][compIdx]);
398  }
399  }
400  }
401 
402  template <class Context, class FluidState>
403  void updateBoundary_(const Context &context, int bfIdx, int timeIdx,
404  const FluidState &fluidState)
405  {
406  const auto &stencil = context.stencil(timeIdx);
407  const auto &face = stencil.boundaryFace(bfIdx);
408 
409  const auto &elemCtx = context.elementContext();
410  int insideScvIdx = face.interiorIndex();
411  const auto &insideScv = stencil.subControlVolume(insideScvIdx);
412 
413  const auto &intQuantsInside = elemCtx.intensiveQuantities(insideScvIdx, timeIdx);
414  const auto &fluidStateInside = intQuantsInside.fluidState();
415 
416  // distance between the center of the SCV and center of the boundary face
417  DimVector distVec = face.integrationPos();
418  distVec -= context.element().geometry().global(insideScv.localGeometry().center());
419 
420  Scalar dist = distVec * face.normal();
421 
422  // if the following assertation triggers, the center of the
423  // center of the interior SCV was not inside the element!
424  assert(dist > 0);
425 
426  for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
427  if (!elemCtx.model().phaseIsConsidered(phaseIdx))
428  continue;
429 
430  for (int compIdx = 0; compIdx < numComponents; ++compIdx) {
431  DimVector moleFractionGradient(0.0);
432 
433  // calculate mole fraction gradient using two-point
434  // gradients
435  moleFractionGradientNormal_[phaseIdx][compIdx] =
436  (fluidState.moleFraction(phaseIdx, compIdx)
437  -
438  fluidStateInside.moleFraction(phaseIdx, compIdx))
439  / dist;
440  Valgrind::CheckDefined(moleFractionGradientNormal_[phaseIdx][compIdx]);
441 
442  // use effective diffusion coefficients of the interior finite
443  // volume.
444  effectiveDiffusionCoefficient_[phaseIdx][compIdx] =
445  intQuantsInside.effectiveDiffusionCoefficient(phaseIdx, compIdx);
446 
447  Valgrind::CheckDefined(effectiveDiffusionCoefficient_[phaseIdx][compIdx]);
448  }
449  }
450  }
451 
452 public:
459  Scalar moleFractionGradientNormal(int phaseIdx, int compIdx) const
460  { return moleFractionGradientNormal_[phaseIdx][compIdx]; }
461 
469  Scalar effectiveDiffusionCoefficient(int phaseIdx, int compIdx) const
470  { return effectiveDiffusionCoefficient_[phaseIdx][compIdx]; }
471 
472 private:
473  Scalar moleFractionGradientNormal_[numPhases][numComponents];
474  Scalar effectiveDiffusionCoefficient_[numPhases][numComponents];
475 };
476 
477 } // namespace Ewoms
478 
479 #endif
static void registerParameters()
Register all run-time parameters for the diffusion module.
Definition: diffusionmodule.hh:98
Provides the auxiliary methods required for consideration of the diffusion equation.
Definition: diffusionmodule.hh:46
Scalar diffusionCoefficient(int phaseIdx, int compIdx) const
Returns the molecular diffusion coefficient for a component in a phase.
Definition: diffusionmodule.hh:167
Declare the properties used by the infrastructure code of the finite volume discretizations.
#define GET_PROP_VALUE(TypeTag, PropTagName)
Access the value attribute of a property for a type tag.
Definition: propertysystem.hh:468
Scalar effectiveDiffusionCoefficient(int phaseIdx, int compIdx) const
The effective diffusion coeffcient of a component in a fluid phase at the face's integration point...
Definition: diffusionmodule.hh:469
void update_(const ElementContext &elemCtx, int faceIdx, int timeIdx)
Update the quantities required to calculate the diffusive mass fluxes.
Definition: diffusionmodule.hh:358
#define GET_PROP_TYPE(TypeTag, PropTagName)
Access the type attribute of a property for a type tag.
Definition: propertysystem.hh:485
void update_(const ElementContext &elemCtx, int faceIdx, int timeIdx)
Update the quantities required to calculate the diffusive mass fluxes.
Definition: diffusionmodule.hh:301
void setPhaseIndex(short phaseIdx)
Set the index of the fluid phase for which a mole fraction should be returned.
Definition: quantitycallbacks.hh:429
static void addDiffusiveFlux(RateVector &flux, const Context &context, int spaceIdx, int timeIdx)
Adds the diffusive mass flux flux to the flux vector over a flux integration point.
Definition: diffusionmodule.hh:71
void updateBoundary_(const Context &context, int bfIdx, int timeIdx, const FluidState &fluidState)
Definition: diffusionmodule.hh:305
Scalar moleFractionGradientNormal(int phaseIdx, int compIdx) const
The the gradient of the mole fraction times the face normal.
Definition: diffusionmodule.hh:316
Callback class for a mole fraction of a component in a phase.
Definition: quantitycallbacks.hh:402
Scalar moleFractionGradientNormal(int phaseIdx, int compIdx) const
The the gradient of the mole fraction times the face normal.
Definition: diffusionmodule.hh:459
void updateBoundary_(const Context &context, int bfIdx, int timeIdx, const FluidState &fluidState)
Definition: diffusionmodule.hh:403
NEW_PROP_TAG(Grid)
The type of the DUNE grid.
Scalar effectiveDiffusionCoefficient(int phaseIdx, int compIdx) const
Returns the effective molecular diffusion coefficient of the porous medium for a component in a phase...
Definition: diffusionmodule.hh:177
void update_(FluidState &fs, ParameterCache &paramCache, const ElementContext &elemCtx, int dofIdx, int timeIdx)
Update the quantities required to calculate diffusive mass fluxes.
Definition: diffusionmodule.hh:190
Scalar tortuosity(int phaseIdx) const
Returns the tortuousity of the sub-domain of a fluid phase in the porous medium.
Definition: diffusionmodule.hh:157
Definition: baseauxiliarymodule.hh:35
void update_(FluidState &fluidState, ParameterCache &paramCache, const ElementContext &elemCtx, int dofIdx, int timeIdx)
Update the quantities required to calculate diffusive mass fluxes.
Definition: diffusionmodule.hh:241
Provides the quantities required to calculate diffusive mass fluxes.
Definition: diffusionmodule.hh:285
This method contains all callback classes for quantities that are required by some extensive quantiti...
static void registerParameters()
Register all run-time parameters for the diffusion module.
Definition: diffusionmodule.hh:63
Provides the volumetric quantities required for the calculation of molecular diffusive fluxes...
Definition: diffusionmodule.hh:138
Scalar effectiveDiffusionCoefficient(int phaseIdx, int compIdx) const
Returns the effective molecular diffusion coefficient of the porous medium for a component in a phase...
Definition: diffusionmodule.hh:232
Scalar tortuosity(int phaseIdx) const
Returns the tortuousity of the sub-domain of a fluid phase in the porous medium.
Definition: diffusionmodule.hh:225
Scalar effectiveDiffusionCoefficient(int phaseIdx, int compIdx) const
The effective diffusion coeffcient of a component in a fluid phase at the face's integration point...
Definition: diffusionmodule.hh:329
Scalar diffusionCoefficient(int phaseIdx, int compIdx) const
Returns the molecular diffusion coefficient for a component in a phase.
Definition: diffusionmodule.hh:218
static void addDiffusiveFlux(RateVector &flux, const Context &context, int spaceIdx, int timeIdx)
Adds the mass flux due to molecular diffusion to the flux vector over the flux integration point...
Definition: diffusionmodule.hh:106
void setComponentIndex(short compIdx)
Set the index of the component for which the mole fraction should be returned.
Definition: quantitycallbacks.hh:436