ncpnewtonmethod.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) 2010-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_NCP_NEWTON_METHOD_HH
27 #define EWOMS_NCP_NEWTON_METHOD_HH
28 
29 #include "ncpproperties.hh"
30 
31 #include <algorithm>
32 
33 namespace Ewoms {
34 
40 template <class TypeTag>
41 class NcpNewtonMethod : public GET_PROP_TYPE(TypeTag, DiscNewtonMethod)
42 {
43  typedef typename GET_PROP_TYPE(TypeTag, DiscNewtonMethod) ParentType;
44 
45  typedef typename GET_PROP_TYPE(TypeTag, EqVector) EqVector;
46  typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
47  typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
48  typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
49  typedef typename GET_PROP_TYPE(TypeTag, Simulator) Simulator;
50 
51  enum { numEq = GET_PROP_VALUE(TypeTag, NumEq) };
52  enum { numPhases = GET_PROP_VALUE(TypeTag, NumPhases) };
53  enum { numComponents = GET_PROP_VALUE(TypeTag, NumComponents) };
54  enum { fugacity0Idx = Indices::fugacity0Idx };
55  enum { saturation0Idx = Indices::saturation0Idx };
56  enum { pressure0Idx = Indices::pressure0Idx };
57 
58 public:
62  NcpNewtonMethod(Simulator &simulator) : ParentType(simulator)
63  {
64  choppedIterations_ = EWOMS_GET_PARAM(TypeTag, int, NcpNewtonNumChoppedIterations);
65  Dune::FMatrixPrecision<Scalar>::set_singular_limit(1e-35);
66  }
67 
71  static void registerParameters()
72  {
73  ParentType::registerParameters();
74 
75  EWOMS_REGISTER_PARAM(TypeTag, int, NcpNewtonNumChoppedIterations,
76  "The number of Newton iterations for which the "
77  "update gets limited");
78  }
79 
80  // HACK: this is necessary since GCC 4.4 does not support
81  // befriending typedefs...
82 /*
83 private:
84  friend class NewtonMethod<TypeTag>;
85  friend class ParentType;
86 */
90  void updatePrimaryVariables_(int globalDofIdx,
91  PrimaryVariables& nextValue,
92  const PrimaryVariables& currentValue,
93  const EqVector& update,
94  const EqVector& currentResidual)
95  {
96  // normal Newton-Raphson update
97  nextValue = currentValue;
98  nextValue -= update;
99 
100  // put crash barriers along the update path at the
101  // beginning...
102  if (this->numIterations_ < choppedIterations_) {
103  for (unsigned phaseIdx = 0; phaseIdx < numPhases - 1; ++phaseIdx)
104  saturationChop_(nextValue[saturation0Idx + phaseIdx],
105  currentValue[saturation0Idx + phaseIdx]);
106  pressureChop_(nextValue[pressure0Idx],
107  currentValue[pressure0Idx]);
108 
109  // fugacities
110  for (int compIdx = 0; compIdx < numComponents; ++compIdx) {
111  Scalar &val = nextValue[fugacity0Idx + compIdx];
112  Scalar oldVal = currentValue[fugacity0Idx + compIdx];
113 
114  // allow the mole fraction of the component to change
115  // at most 70% (assuming composition independent
116  // fugacity coefficients)
117  Scalar minPhi = this->problem().model().minActivityCoeff(globalDofIdx, compIdx);
118  Scalar maxDelta = 0.7 * minPhi;
119 
120  clampValue_(val, oldVal - maxDelta, oldVal + maxDelta);
121 
122  // do not allow mole fractions lager than 101% or
123  // smaller than -1%
124  val = std::max(-0.01 * minPhi, val);
125  val = std::min(1.01 * minPhi, val);
126  }
127  }
128  }
129 
130 private:
131  void clampValue_(Scalar &val, Scalar minVal, Scalar maxVal) const
132  { val = std::max(minVal, std::min(val, maxVal)); }
133 
134  void pressureChop_(Scalar &val, Scalar oldVal) const
135  {
136  // limit pressure updates to 20% per iteration
137  clampValue_(val, oldVal * 0.8, oldVal * 1.2);
138  }
139 
140  void saturationChop_(Scalar &val, Scalar oldVal) const
141  {
142  // limit saturation updates to 20% per iteration
143  const Scalar maxDelta = 0.20;
144  clampValue_(val, oldVal - maxDelta, oldVal + maxDelta);
145  }
146 
147  int choppedIterations_;
148 };
149 } // namespace Ewoms
150 
151 #endif
#define GET_PROP_VALUE(TypeTag, PropTagName)
Access the value attribute of a property for a type tag.
Definition: propertysystem.hh:468
A Newton solver specific to the NCP model.
Definition: ncpnewtonmethod.hh:41
#define GET_PROP_TYPE(TypeTag, PropTagName)
Access the type attribute of a property for a type tag.
Definition: propertysystem.hh:485
Manages the initializing and running of time dependent problems.
Definition: simulator.hh:73
NcpNewtonMethod(Simulator &simulator)
Definition: ncpnewtonmethod.hh:62
Definition: baseauxiliarymodule.hh:35
static void registerParameters()
Register all run-time parameters for the Newton method.
Definition: ncpnewtonmethod.hh:71
#define EWOMS_REGISTER_PARAM(TypeTag, ParamType, ParamName, Description)
Register a run-time parameter.
Definition: parametersystem.hh:64
Declares the properties required for the NCP compositional multi-phase model.
void updatePrimaryVariables_(int globalDofIdx, PrimaryVariables &nextValue, const PrimaryVariables &currentValue, const EqVector &update, const EqVector &currentResidual)
Update a single primary variables object.
Definition: ncpnewtonmethod.hh:90
#define EWOMS_GET_PARAM(TypeTag, ParamType, ParamName)
Retrieve a runtime parameter.
Definition: parametersystem.hh:95