fvbasenewtonmethod.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) 2009-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_FV_BASE_NEWTON_METHOD_HH
27 #define EWOMS_FV_BASE_NEWTON_METHOD_HH
28 
30 
33 
34 namespace Ewoms {
35 
36 template <class TypeTag>
38 
39 template <class TypeTag>
41 } // namespace Ewoms
42 
43 namespace Ewoms {
44 namespace Properties {
47 
49 NEW_PROP_TAG(Model);
50 
52 NEW_PROP_TAG(PrimaryVariables);
53 
56 NEW_PROP_TAG(EqVector);
57 
59 NEW_PROP_TAG(NumEq);
60 
62 NEW_PROP_TAG(DiscNewtonMethod);
63 
66 
69 NEW_PROP_TAG(EnablePartialRelinearization);
70 
72 NEW_PROP_TAG(EnableLinearizationRecycling);
73 
80 NEW_PROP_TAG(LinearSolverTolerance);
81 
82 // set default values
83 SET_TYPE_PROP(FvBaseNewtonMethod, DiscNewtonMethod,
86  typename GET_PROP_TYPE(TypeTag, DiscNewtonMethod));
87 SET_TYPE_PROP(FvBaseNewtonMethod, NewtonConvergenceWriter,
89 } // namespace Properties
90 
99 template <class TypeTag>
100 class FvBaseNewtonMethod : public NewtonMethod<TypeTag>
101 {
102  typedef Ewoms::NewtonMethod<TypeTag> ParentType;
103  typedef typename GET_PROP_TYPE(TypeTag, NewtonMethod) Implementation;
104 
105  typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
106  typedef typename GET_PROP_TYPE(TypeTag, Simulator) Simulator;
107  typedef typename GET_PROP_TYPE(TypeTag, Model) Model;
108  typedef typename GET_PROP_TYPE(TypeTag, Linearizer) Linearizer;
109  typedef typename GET_PROP_TYPE(TypeTag, NewtonMethod) NewtonMethod;
110  typedef typename GET_PROP_TYPE(TypeTag, GlobalEqVector) GlobalEqVector;
111  typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector;
112  typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
113  typedef typename GET_PROP_TYPE(TypeTag, EqVector) EqVector;
114 
115 
116 public:
117  FvBaseNewtonMethod(Simulator &simulator)
118  : ParentType(simulator)
119  { }
120 
121 protected:
122  friend class Ewoms::NewtonMethod<TypeTag>;
123 
141  void update_(SolutionVector &nextSolution,
142  const SolutionVector &currentSolution,
143  const GlobalEqVector &solutionUpdate,
144  const GlobalEqVector &currentResidual)
145  {
146  auto& model = this->model();
147  auto& linearizer = model.linearizer();
148 
149  // first, write out the next solution to make convergence
150  // analysis possible
151  this->writeConvergence_(currentSolution, solutionUpdate);
152 
153  // make sure not to swallow non-finite values at this point
154  if (!std::isfinite(solutionUpdate.two_norm2()))
155  OPM_THROW(Opm::NumericalProblem, "Non-finite update!");
156 
157  Scalar relinearizationTol = 0.0;
158 
159  // compute the DOF and element colors for partial relinearization
160  if (enablePartialRelinearization_()) {
161  linearizer.updateRelinearizationErrors(solutionUpdate, currentResidual);
162 
163  // we chose to relinearize all DOFs for which the solution is to be deflected
164  // by more than a thousandth of the maximum deflection.
165  relinearizationTol = 1e-1*linearizer.maxDofError();
166 
167  // decrease the relinearization tolerance until at least 15% of the DOFs are
168  // relinearized. (or by at most 6 orders of magnitude.)
169  for (unsigned i = 0; i < 6; ++i) {
170  unsigned numRelinearized = 0;
171  for (unsigned dofIdx = 0; dofIdx < model.numGridDof(); ++dofIdx) {
172  if (linearizer.dofError(dofIdx) > relinearizationTol)
173  ++numRelinearized;
174  }
175 
176  if (numRelinearized*100 >= model.numGridDof()*15)
177  break;
178 
179  relinearizationTol /= 10;
180  }
181 
182  // tell the linarizer what tolerance it should use
183  linearizer.setRelinearizationTolerance(relinearizationTol);
184  }
185 
186  // update the solution for the grid DOFs
187  for (unsigned dofIdx = 0; dofIdx < model.numGridDof(); ++dofIdx) {
188  asImp_().updatePrimaryVariables_(dofIdx,
189  nextSolution[dofIdx],
190  currentSolution[dofIdx],
191  solutionUpdate[dofIdx],
192  currentResidual[dofIdx]);
193  model.setIntensiveQuantitiesCacheEntryValidity(dofIdx, /*timeIdx=*/0, false);
194  }
195 
196  // update the DOFs of the auxiliary equations
197  int nTotalDof = model.numTotalDof();
198  for (int dofIdx = model.numGridDof(); dofIdx < nTotalDof; ++dofIdx) {
199  nextSolution[dofIdx] = currentSolution[dofIdx];
200  nextSolution[dofIdx] -= solutionUpdate[dofIdx];
201  }
202  }
203 
208  {
209  model_().syncOverlap();
210 
212  }
213 
217  void failed_()
218  {
220 
221  model_().linearizer().relinearizeAll();
222  }
223 
227  void succeeded_()
228  {
230 
231  if (enableLinearizationRecycling_())
232  model_().linearizer().setLinearizationReusable(true);
233  else
234  model_().linearizer().relinearizeAll();
235  }
236 
240  Model &model_()
241  { return ParentType::model(); }
242 
246  const Model &model_() const
247  { return ParentType::model(); }
248 
249 private:
250  Implementation &asImp_()
251  { return *static_cast<Implementation*>(this); }
252 
253  const Implementation &asImp_() const
254  { return *static_cast<const Implementation*>(this); }
255 
260  bool enablePartialRelinearization_() const
261  { return EWOMS_GET_PARAM(TypeTag, bool, EnablePartialRelinearization); }
262 
267  bool enableLinearizationRecycling_() const
268  { return EWOMS_GET_PARAM(TypeTag, bool, EnableLinearizationRecycling); }
269 };
270 } // namespace Ewoms
271 
272 #endif
void writeConvergence_(const SolutionVector &currentSolution, const GlobalEqVector &solutionUpdate)
Write the convergence behaviour of the newton method to disk.
Definition: newtonmethod.hh:667
Model & model_()
Returns a reference to the model.
Definition: fvbasenewtonmethod.hh:240
void failed_()
Called if the Newton method broke down.
Definition: fvbasenewtonmethod.hh:217
void beginIteration_()
Indicates the beginning of a Newton iteration.
Definition: newtonmethod.hh:541
void beginIteration_()
Indicates the beginning of a Newton iteration.
Definition: fvbasenewtonmethod.hh:207
The multi-dimensional Newton method.
Definition: newtonmethod.hh:54
#define GET_PROP_TYPE(TypeTag, PropTagName)
Access the type attribute of a property for a type tag.
Definition: propertysystem.hh:485
void update_(SolutionVector &nextSolution, const SolutionVector &currentSolution, const GlobalEqVector &solutionUpdate, const GlobalEqVector &currentResidual)
Update the current solution with a delta vector.
Definition: fvbasenewtonmethod.hh:141
Model & model()
Returns a reference to the numeric model.
Definition: newtonmethod.hh:245
The multi-dimensional Newton method.
NEW_PROP_TAG(Grid)
The type of the DUNE grid.
SET_TYPE_PROP(NumericModel, Scalar, double)
Set the default type of scalar values to double.
Definition: baseauxiliarymodule.hh:35
void succeeded_()
Called if the Newton method was successful.
Definition: newtonmethod.hh:744
NewtonMethod(Simulator &simulator)
Definition: newtonmethod.hh:183
Writes the intermediate solutions during the Newton scheme for models using a finite volume discretiz...
Definition: fvbasenewtonconvergencewriter.hh:53
void failed_()
Called if the Newton method broke down.
Definition: newtonmethod.hh:736
NEW_TYPE_TAG(AuxModule)
Provides the magic behind the eWoms property system.
Writes the intermediate solutions during the Newton scheme for models using a finite volume discretiz...
const Model & model_() const
Returns a reference to the model.
Definition: fvbasenewtonmethod.hh:246
A Newton method for models using a finite volume discretization.
Definition: fvbasenewtonmethod.hh:37
#define INHERITS_FROM(...)
Syntactic sugar for NEW_TYPE_TAG.
Definition: propertysystem.hh:229
void succeeded_()
Called when the Newton method was successful.
Definition: fvbasenewtonmethod.hh:227
#define EWOMS_GET_PARAM(TypeTag, ParamType, ParamName)
Retrieve a runtime parameter.
Definition: parametersystem.hh:95