3.2-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
impet.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 * See the file COPYING for full copying permissions. *
5 * *
6 * This program is free software: you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation, either version 3 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 *****************************************************************************/
19#ifndef DUMUX_IMPET_HH
20#define DUMUX_IMPET_HH
21
27#include "impetproperties.hh"
28
29namespace Dumux
30{
48template<class TypeTag> class IMPET
49{
52
54 using ElementMapper = typename SolutionTypes::ElementMapper;
56
57 enum IterationType
58 {
59 noIter,
60 iterToNumIter,
61 iterToConverged,
62 };
63
64public:
65 using SolutionType = typename SolutionTypes::ScalarSolution;
66
69 {
70 //initial values of transported quantity
71 problem_.transportModel().initialize();
72 //call function with true to get a first initialisation of the pressure field
73 problem_.pressureModel().initialize();
74
75 //update constitutive functions
76 problem_.pressureModel().updateMaterialLaws();
77
78 Dune::dinfo << "IMPET: initialization done." << std::endl;
79
80 return;
81 }
82
84
92 void update(const Scalar t, Scalar& dt, TransportSolutionType& updateVec)
93 {
94 if (iterFlag_ == noIter)
95 {
96 //update pressure
97 problem_.pressureModel().update();
98
99 //calculate defect of transported quantity
100 problem_.transportModel().update(t, dt, updateVec, true);
101
102 dt *= cFLFactor_;
103 }
104 else if (iterFlag_ == iterToNumIter || iterFlag_ == iterToConverged)
105 {
106 bool converg = false;
107 int iter = 0;
108 int iterTot = 0;
109
110 // the method is valid for any transported quantity.
111 TransportSolutionType transValueOldIter;
112 problem_.transportModel().getTransportedQuantity(transValueOldIter);
113 TransportSolutionType updateOldIter(transValueOldIter);
114 updateOldIter = 0;
115 TransportSolutionType transportedQuantity(transValueOldIter);
116 TransportSolutionType updateHelp(transValueOldIter);
117 TransportSolutionType updateDiff(transValueOldIter);
118
119 while (!converg)
120 {
121 iter++;
122 iterTot++;
123
124 problem_.pressureModel().update();
125
126 //calculate defect of transported quantity
127 problem_.transportModel().update(t, dt, updateVec, true);
128
129 updateHelp = updateVec;
130 problem_.transportModel().getTransportedQuantity(transportedQuantity);
131 transportedQuantity += (updateHelp *= (dt * cFLFactor_));
132 transportedQuantity *= omega_;
133 transValueOldIter *= (1 - omega_);
134 transportedQuantity += transValueOldIter;
135 updateDiff = updateVec;
136 updateDiff -= updateOldIter;
137 transValueOldIter = transportedQuantity;
138 updateOldIter = updateVec;
139 Dune::dinfo << " defect = " << dt * updateDiff.two_norm() / transportedQuantity.two_norm();
140 // break criteria for iteration loop
141 if (iterFlag_ == iterToConverged && dt * updateDiff.two_norm() / transportedQuantity.two_norm() <= maxDefect_)
142 {
143 converg = true;
144 }
145 else if (iterFlag_ == iterToNumIter && iter > nIter_)
146 {
147 converg = true;
148 }
149
150 if (iterFlag_ == iterToConverged && transportedQuantity.infinity_norm() > (1 + maxDefect_))
151 {
152 converg = false;
153 }
154 if (!converg && iter > nIter_)
155 {
156 converg = true;
157 std::cout << "Nonlinear loop in IMPET.update exceeded nIter = " << nIter_ << " iterations."
158 << std::endl;
159 std::cout << transportedQuantity.infinity_norm() << std::endl;
160 }
161 }
162 // outputs
163 if (iterFlag_ == iterToConverged)
164 std::cout << "Iteration steps: " << iterTot << std::endl;
165 std::cout.setf(std::ios::scientific, std::ios::floatfield);
166
167 dt *= cFLFactor_;
168 }
169 else
170 {
171 DUNE_THROW(Dune::NotImplemented,"IMPET: Iterationtype not implemented!");
172 }
173
174 }
175
176 void updateTransport(const Scalar t, Scalar& dt, TransportSolutionType& updateVec)
177 {
178 problem_.pressureModel().updateVelocity();
179
180 problem_.transportModel().update(t, dt, updateVec, true);
181 }
182
184
188 template<class MultiWriter>
189 void addOutputVtkFields(MultiWriter &writer)
190 {
191 problem_.pressureModel().addOutputVtkFields(writer);
192 problem_.transportModel().addOutputVtkFields(writer);
193
194 return;
195 }
196
200 const ElementMapper &dofMapper() const
201 {
202 return problem_.elementMapper();
203 }
204
206
209 IMPET(Problem& problem) :
210 problem_(problem)
211 {
212 cFLFactor_ = getParam<Scalar>("Impet.CFLFactor");
213 iterFlag_ = getParam<int>("Impet.IterationFlag", 0);
214 nIter_ = getParam<int>("Impet.IterationNumber", 2);
215 maxDefect_ = getParam<Scalar>("Impet.MaximumDefect", 1e-5);
216 omega_ = getParam<Scalar>("Impet.RelaxationFactor", 1.0);
217 }
218
219private:
220 Problem& problem_;
221 Scalar cFLFactor_;
222 int iterFlag_;
223 int nIter_;
224 Scalar maxDefect_;
225 Scalar omega_;
226};
227}
228#endif
Base file for properties related to sequential IMPET algorithms.
Definition: adapt.hh:29
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type GetProp
get the type of a property (equivalent to old macro GET_PROP(...))
Definition: propertysystem.hh:140
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(....
Definition: propertysystem.hh:149
IMplicit Pressure Explicit Transport (IMPET) scheme for the solution of weakly coupled diffusion-tran...
Definition: impet.hh:49
void update(const Scalar t, Scalar &dt, TransportSolutionType &updateVec)
Calculate the update.
Definition: impet.hh:92
typename SolutionTypes::ScalarSolution SolutionType
Definition: impet.hh:65
void initialize()
Set initial solution and initialize parameters.
Definition: impet.hh:68
void updateTransport(const Scalar t, Scalar &dt, TransportSolutionType &updateVec)
Definition: impet.hh:176
const ElementMapper & dofMapper() const
Mapper for the entities where degrees of freedoms are defined.
Definition: impet.hh:200
void addOutputVtkFields(MultiWriter &writer)
Write data files.
Definition: impet.hh:189
IMPET(Problem &problem)
Constructs an IMPET object.
Definition: impet.hh:209