ncpmodel.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  Copyright (C) 2012 by Philipp Nuske
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_NCP_MODEL_HH
28 #define EWOMS_NCP_MODEL_HH
29 
30 #include <opm/material/localad/Math.hpp>
31 
32 #include "ncpproperties.hh"
33 #include "ncplocalresidual.hh"
35 #include "ncpprimaryvariables.hh"
36 #include "ncpboundaryratevector.hh"
37 #include "ncpratevector.hh"
39 #include "ncpnewtonmethod.hh"
40 #include "ncpindices.hh"
41 
48 
49 #include <opm/common/ErrorMacros.hpp>
50 #include <opm/common/Exceptions.hpp>
51 
52 #include <dune/common/fvector.hh>
53 #include <dune/common/unused.hh>
54 
55 #include <sstream>
56 #include <string>
57 #include <vector>
58 #include <array>
59 
60 namespace Ewoms {
61 template <class TypeTag>
62 class NcpModel;
63 }
64 
65 namespace Ewoms {
66 namespace Properties {
71  VtkComposition,
72  VtkEnergy,
73  VtkDiffusion));
74 
77  LocalResidual,
79 
82 
85 
88 
90 SET_BOOL_PROP(NcpModel, EnableEnergy, false);
91 
93 SET_BOOL_PROP(NcpModel, EnableDiffusion, false);
94 
97 
100 
103 
106 
109 
111 SET_INT_PROP(NcpModel, NcpNewtonNumChoppedIterations, 3);
112 
115 
117 SET_SCALAR_PROP(NcpModel, NcpPressureBaseWeight, 1.0);
119 SET_SCALAR_PROP(NcpModel, NcpSaturationsBaseWeight, 1.0);
121 SET_SCALAR_PROP(NcpModel, NcpFugacitiesBaseWeight, 1.0);
122 
123 } // namespace Properties
124 
198 template <class TypeTag>
199 class NcpModel
200  : public MultiPhaseBaseModel<TypeTag>
201 {
202  typedef MultiPhaseBaseModel<TypeTag> ParentType;
203 
204  typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
205  typedef typename GET_PROP_TYPE(TypeTag, Evaluation) Evaluation;
206  typedef typename GET_PROP_TYPE(TypeTag, Simulator) Simulator;
207  typedef typename GET_PROP_TYPE(TypeTag, ElementContext) ElementContext;
208  typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
209  typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
210 
211  enum { numPhases = FluidSystem::numPhases };
212  enum { numComponents = FluidSystem::numComponents };
213  enum { fugacity0Idx = Indices::fugacity0Idx };
214  enum { pressure0Idx = Indices::pressure0Idx };
215  enum { saturation0Idx = Indices::saturation0Idx };
216  enum { conti0EqIdx = Indices::conti0EqIdx };
217  enum { ncp0EqIdx = Indices::ncp0EqIdx };
218  enum { enableDiffusion = GET_PROP_VALUE(TypeTag, EnableDiffusion) };
219  enum { enableEnergy = GET_PROP_VALUE(TypeTag, EnableEnergy) };
220 
221  typedef Dune::FieldVector<Scalar, numComponents> ComponentVector;
222 
223  typedef Opm::MathToolbox<Evaluation> Toolbox;
224 
225  typedef Ewoms::EnergyModule<TypeTag, enableEnergy> EnergyModule;
226  typedef Ewoms::DiffusionModule<TypeTag, enableDiffusion> DiffusionModule;
227 
228 public:
229  NcpModel(Simulator &simulator)
230  : ParentType(simulator)
231  {}
232 
236  static void registerParameters()
237  {
239 
240  DiffusionModule::registerParameters();
241  EnergyModule::registerParameters();
242 
243  // register runtime parameters of the VTK output modules
245 
246  if (enableDiffusion)
248 
249  if (enableEnergy)
251  }
252 
256  void finishInit()
257  {
259 
260  minActivityCoeff_.resize(this->numGridDof());
261  std::fill(minActivityCoeff_.begin(), minActivityCoeff_.end(), 1.0);
262  }
263 
267  static std::string name()
268  { return "ncp"; }
269 
273  std::string primaryVarName(int pvIdx) const
274  {
275  std::string s;
276  if (!(s = EnergyModule::primaryVarName(pvIdx)).empty())
277  return s;
278 
279  std::ostringstream oss;
280  if (pvIdx == pressure0Idx)
281  oss << "pressure_" << FluidSystem::phaseName(/*phaseIdx=*/0);
282  else if (saturation0Idx <= pvIdx && pvIdx < saturation0Idx + (numPhases - 1))
283  oss << "saturation_" << FluidSystem::phaseName(/*phaseIdx=*/pvIdx - saturation0Idx);
284  else if (fugacity0Idx <= pvIdx && pvIdx < fugacity0Idx + numComponents)
285  oss << "fugacity^" << FluidSystem::componentName(pvIdx - fugacity0Idx);
286  else
287  assert(false);
288 
289  return oss.str();
290  }
291 
295  std::string eqName(int eqIdx) const
296  {
297  std::string s;
298  if (!(s = EnergyModule::eqName(eqIdx)).empty())
299  return s;
300 
301  std::ostringstream oss;
302  if (conti0EqIdx <= eqIdx && eqIdx < conti0EqIdx + numComponents)
303  oss << "continuity^" << FluidSystem::componentName(eqIdx - conti0EqIdx);
304  else if (ncp0EqIdx <= eqIdx && eqIdx < ncp0EqIdx + numPhases)
305  oss << "ncp_" << FluidSystem::phaseName(/*phaseIdx=*/eqIdx - ncp0EqIdx);
306  else
307  assert(false);
308 
309  return oss.str();
310  }
311 
315  void updateBegin()
316  {
317  ParentType::updateBegin();
318 
319  // find the a reference pressure. The first degree of freedom
320  // might correspond to non-interior entities which would lead
321  // to an undefined value, so we have to iterate...
322  for (size_t dofIdx = 0; dofIdx < this->numGridDof(); ++ dofIdx) {
323  if (this->isLocalDof(dofIdx)) {
325  this->solution(/*timeIdx=*/0)[dofIdx][/*pvIdx=*/Indices::pressure0Idx];
326  break;
327  }
328  }
329  }
330 
334  void updatePVWeights(const ElementContext &elemCtx) const
335  {
336  for (int dofIdx = 0; dofIdx < elemCtx.numDof(/*timeIdx=*/0); ++dofIdx) {
337  int globalIdx = elemCtx.globalSpaceIndex(dofIdx, /*timeIdx=*/0);
338 
339  for (int compIdx = 0; compIdx < numComponents; ++compIdx) {
340  minActivityCoeff_[globalIdx][compIdx] = 1e100;
341  for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
342  const auto &fs = elemCtx.intensiveQuantities(dofIdx, /*timeIdx=*/0).fluidState();
343 
344  minActivityCoeff_[globalIdx][compIdx] =
345  std::min(minActivityCoeff_[globalIdx][compIdx],
346  Toolbox::value(fs.fugacityCoefficient(phaseIdx, compIdx))
347  * Toolbox::value(fs.pressure(phaseIdx)));
348  Valgrind::CheckDefined(minActivityCoeff_[globalIdx][compIdx]);
349  }
350  if (minActivityCoeff_[globalIdx][compIdx] <= 0)
351  OPM_THROW(Opm::NumericalProblem,
352  "The minumum activity coefficient for component " << compIdx
353  << " on DOF " << globalIdx << " is negative or zero!");
354  }
355  }
356  }
357 
361  Scalar primaryVarWeight(int globalDofIdx, int pvIdx) const
362  {
363  Scalar tmp = EnergyModule::primaryVarWeight(*this, globalDofIdx, pvIdx);
364  Scalar result;
365  if (tmp > 0)
366  // energy related quantity
367  result = tmp;
368  else if (fugacity0Idx <= pvIdx && pvIdx < fugacity0Idx + numComponents) {
369  // component fugacity
370  int compIdx = pvIdx - fugacity0Idx;
371  assert(0 <= compIdx && compIdx <= numComponents);
372 
373  Valgrind::CheckDefined(minActivityCoeff_[globalDofIdx][compIdx]);
374  static const Scalar fugacityBaseWeight =
375  GET_PROP_VALUE(TypeTag, NcpFugacitiesBaseWeight);
376  result = fugacityBaseWeight / minActivityCoeff_[globalDofIdx][compIdx];
377  }
378  else if (Indices::pressure0Idx == pvIdx) {
379  static const Scalar pressureBaseWeight = GET_PROP_VALUE(TypeTag, NcpPressureBaseWeight);
380  result = pressureBaseWeight / referencePressure_;
381  }
382  else {
383 #ifndef NDEBUG
384  int phaseIdx = pvIdx - saturation0Idx;
385  assert(0 <= phaseIdx && phaseIdx < numPhases - 1);
386 #endif
387 
388  // saturation
389  static const Scalar saturationsBaseWeight =
390  GET_PROP_VALUE(TypeTag, NcpSaturationsBaseWeight);
391  result = saturationsBaseWeight;
392  }
393 
394  assert(std::isfinite(result));
395  assert(result > 0);
396 
397  return result;
398  }
399 
403  Scalar eqWeight(int globalDofIdx, int eqIdx) const
404  {
405  Scalar tmp = EnergyModule::eqWeight(*this, globalDofIdx, eqIdx);
406  if (tmp > 0)
407  // energy related equation
408  return tmp;
409  // an NCP
410  else if (ncp0EqIdx <= eqIdx && eqIdx < Indices::ncp0EqIdx + numPhases)
411  return 1.0;
412 
413  // mass conservation equation
414  int compIdx = eqIdx - Indices::conti0EqIdx;
415  assert(0 <= compIdx && compIdx <= numComponents);
416 
417  // make all kg equal
418  return FluidSystem::molarMass(compIdx);
419  }
420 
428  Scalar minActivityCoeff(int globalDofIdx, int compIdx) const
429  { return minActivityCoeff_[globalDofIdx][compIdx]; }
430 
435  {
437 
438  this->addOutputModule(new Ewoms::VtkCompositionModule<TypeTag>(this->simulator_));
439  if (enableDiffusion)
440  this->addOutputModule(new Ewoms::VtkDiffusionModule<TypeTag>(this->simulator_));
441  if (enableEnergy)
442  this->addOutputModule(new Ewoms::VtkEnergyModule<TypeTag>(this->simulator_));
443  }
444 
445  mutable Scalar referencePressure_;
446  mutable std::vector<ComponentVector> minActivityCoeff_;
447 };
448 
449 } // namespace Ewoms
450 
451 #endif
Implements a vector representing mass, molar or volumetric rates.
void registerOutputModules_()
Definition: multiphasebasemodel.hh:244
VTK output module for quantities which make sense for models which assume thermal equilibrium...
Scalar minActivityCoeff(int globalDofIdx, int compIdx) const
Returns the smallest activity coefficient of a component for the most current solution at a vertex...
Definition: ncpmodel.hh:428
Classes required for molecular diffusion.
Provides the auxiliary methods required for consideration of the diffusion equation.
Definition: diffusionmodule.hh:46
Scalar primaryVarWeight(int globalDofIdx, int pvIdx) const
Returns the relative weight of a primary variable for calculating relative errors.
Definition: ncpmodel.hh:361
SET_SCALAR_PROP(NumericModel, EndTime,-1e100)
The default value for the simulation's end time.
Details needed to calculate the local residual in the compositional multi-phase NCP-model ...
std::string eqName(int eqIdx) const
Given an equation index, return a human readable name.
Definition: ncpmodel.hh:295
The multi-dimensional Newton method.
Definition: newtonmethod.hh:54
This template class represents the extensive quantities of the compositional NCP model.
VTK output module for quantities which make sense for models which assume thermal equilibrium...
Definition: vtkenergymodule.hh:70
#define GET_PROP_VALUE(TypeTag, PropTagName)
Access the value attribute of a property for a type tag.
Definition: propertysystem.hh:468
void finishInit()
Apply the initial conditions to the model.
Definition: ncpmodel.hh:256
A base class for fully-implicit multi-phase porous-media flow models which assume multiple fluid phas...
Definition: multiphasebasemodel.hh:45
A Newton solver specific to the NCP model.
Definition: ncpnewtonmethod.hh:41
Represents the primary variables used by the compositional multi-phase NCP model. ...
Scalar eqWeight(int globalDofIdx, int eqIdx) const
Returns the relative weight of an equation.
Definition: ncpmodel.hh:403
Contains the quantities which are are constant within a finite volume in the compositional multi-phas...
NcpModel(Simulator &simulator)
Definition: ncpmodel.hh:229
static void registerParameters()
Register all run-time parameters for the immiscible model.
Definition: ncpmodel.hh:236
SET_INT_PROP(NumericModel, GridGlobalRefinements, 0)
static std::string name()
Definition: ncpmodel.hh:267
static void registerParameters()
Register all run-time parameters for the Vtk output module.
Definition: vtkdiffusionmodule.hh:93
Contains the quantities which are are constant within a finite volume in the compositional multi-phas...
Definition: ncpintensivequantities.hh:50
SET_TYPE_PROP(NumericModel, Scalar, double)
Set the default type of scalar values to double.
Implements a vector representing mass, molar or volumetric rates.
Definition: ncpratevector.hh:46
The primary variable and equation indices for the compositional multi-phase NCP model.
Definition: ncpindices.hh:41
Provides the auxiliary methods required for consideration of the energy equation. ...
Definition: energymodule.hh:54
The primary variable and equation indices for the compositional multi-phase NCP model.
Manages the initializing and running of time dependent problems.
Definition: simulator.hh:73
void registerOutputModules_()
Definition: ncpmodel.hh:434
Definition: baseauxiliarymodule.hh:35
void finishInit()
Apply the initial conditions to the model.
Definition: multiphasebasemodel.hh:157
VTK output module for the fluid composition.
VTK output module for quantities which make sense for models which incorperate molecular diffusion...
std::string primaryVarName(int pvIdx) const
Given an primary variable index, return a human readable name.
Definition: ncpmodel.hh:273
static void registerParameters()
Register all run-time parameters for the immiscible model.
Definition: multiphasebasemodel.hh:145
Scalar referencePressure_
Definition: ncpmodel.hh:445
static void registerParameters()
Register all run-time parameters for the Vtk output module.
Definition: vtkcompositionmodule.hh:102
A compositional multi-phase model based on non-linear complementarity functions.
Definition: ncpmodel.hh:62
void updatePVWeights(const ElementContext &elemCtx) const
Update the weights of all primary variables within an element given the complete set of intensive qua...
Definition: ncpmodel.hh:334
A base class for fully-implicit multi-phase porous-media flow models which assume multiple fluid phas...
The base class for the problems of ECFV discretizations which deal with a multi-phase flow through a ...
Definition: multiphasebaseproblem.hh:55
void updateBegin()
Called by the update() method before it tries to apply the newton method. This is primary a hook whic...
Definition: ncpmodel.hh:315
This template class represents the extensive quantities of the compositional NCP model.
Definition: ncpextensivequantities.hh:45
Details needed to calculate the local residual in the compositional multi-phase NCP-model ...
Definition: ncplocalresidual.hh:43
A Newton solver specific to the NCP model.
Implements a boundary vector for the fully implicit compositional multi-phase NCP model...
Declares the properties required for the NCP compositional multi-phase model.
Represents the primary variables used by the compositional multi-phase NCP model. ...
Definition: ncpprimaryvariables.hh:51
NEW_TYPE_TAG(AuxModule)
std::vector< ComponentVector > minActivityCoeff_
Definition: ncpmodel.hh:446
SET_BOOL_PROP(FvBaseDiscretization, EnableVtkOutput, true)
Enable the VTK output by default.
VTK output module for quantities which make sense for models which incorperate molecular diffusion...
Definition: vtkdiffusionmodule.hh:67
#define INHERITS_FROM(...)
Syntactic sugar for NEW_TYPE_TAG.
Definition: propertysystem.hh:229
static void registerParameters()
Register all run-time parameters for the Vtk output module.
Definition: vtkenergymodule.hh:98
Implements a boundary vector for the fully implicit compositional multi-phase NCP model...
Definition: ncpboundaryratevector.hh:43
Contains the classes required to consider energy as a conservation quantity in a multi-phase module...
VTK output module for the fluid composition.
Definition: vtkcompositionmodule.hh:74