1#ifndef __DUNE_ACFEM_ALGORITHMS_TRANSIENT_ADAPTIVE_ALGORITHM_HH__
2#define __DUNE_ACFEM_ALGORITHMS_TRANSIENT_ADAPTIVE_ALGORITHM_HH__
4#include <dune/fem/solver/timeprovider.hh>
5#include "../algorithms/femschemeinterface.hh"
42 template<
class TimeProv
ider>
45 TimeProvider& timeProvider,
47 const std::string& prefix_ =
"")
49 std::string prefix = prefix_ == std::string(
"") ? prefix_ : prefix_ +
".";
51 const bool verbose = Dune::Fem::Parameter::getValue<int>(
"fem.verboserank", -1) != -1;
53 bool restart = Dune::Fem::Parameter::getValue<bool>(prefix +
"restart",
false);
56 double timeStep = timeProvider.deltaT();
61 const double tolerance = Dune::Fem::Parameter::getValue<double>(prefix +
"adaptation.tolerance", 1e-2);
62 const double initialTolerance =
63 tolerance * Dune::Fem::Parameter::getValue<double>(prefix +
"adaptation.initialToleranceFraction", 0.2);
64 const double spaceTolerance =
65 tolerance * Dune::Fem::Parameter::getValue<double>(prefix +
"adaptation.spaceToleranceFraction", 0.4);
66 const double timeTolerance =
67 tolerance * Dune::Fem::Parameter::getValue<double>(prefix +
"adaptation.timeToleranceFraction", 0.4);
68 const double minDeltaT =
69 Dune::Fem::Parameter::getValue<double>(prefix +
"adaptation.time.minimalStep", -1);
70 const double maxDeltaT =
71 Dune::Fem::Parameter::getValue<double>(prefix +
"adaptation.time.maximalStep", -1);
73 const int maximumIterations =
74 Dune::Fem::Parameter::getValue<int>(prefix +
"adaptation.maximumIterations", 10);
75 const int spaceMaximumIterations =
76 Dune::Fem::Parameter::getValue<int>(prefix +
"adaptation.space.maximumIterations", 10);
77 const int initialMaximumIterations =
78 Dune::Fem::Parameter::getValue<int>(prefix +
"adaptation.initial.maximumIterations", 10);
80 const std::string timeStrategyNames[] = {
"explicit",
"implicit" };
81 enum { explicitTimeStrategy, implicitTimeStrategy };
82 const int timeStrategy = Dune::Fem::Parameter::getEnum(prefix +
"adaptation.time.strategy", timeStrategyNames, explicitTimeStrategy);
83 const double timeNarrowFactor = Dune::Fem::Parameter::getValue<double>(prefix +
"adaptation.time.narrowFactor", M_SQRT1_2);
84 const double timeRelaxFactor = Dune::Fem::Parameter::getValue<double>(prefix +
"adaptation.time.relaxFactor", M_SQRT2);
85 const double timeRelaxTolerance =
86 timeTolerance * Dune::Fem::Parameter::getValue<double>(prefix +
"adaptation.time.relaxToleranceFraction", 0.3);
90 std::string dataPath = Dune::Fem::Parameter::commonOutputPath() +
"/";
91 dataPath += Dune::Fem::Parameter::getValue<std::string>(
"fem.io.path",
"./") +
"/";
109 Dune::Fem::persistenceManager << maxError;
110 Dune::Fem::persistenceManager << maxEstimate;
118 estimate = scheme.initialEstimate();
121 while (estimate > initialTolerance && ++cnt < initialMaximumIterations) {
124 scheme.initialMarking(initialTolerance);
132 estimate = scheme.initialEstimate();
134 assert(cnt < initialMaximumIterations);
142 if (timeStrategy == explicitTimeStrategy) {
151 while (timeProvider.time() < endTime) {
153 if (Dune::Fem::Parameter::verbose()) {
154 std::cout <<
"**** Starting time-step " << timeProvider.timeStep() <<
"@" << timeProvider.time() << std::endl;
157 if ( timeProvider.timeStep() > 0 ) {
159 scheme.mark(spaceTolerance);
169 estimate = scheme.estimate();
173 while (estimate > spaceTolerance && cnt < spaceMaximumIterations ) {
175 scheme.mark(spaceTolerance);
184 estimate = scheme.estimate();
192 timeProvider.next(timeStep);
195 double error = scheme.error();
197 if (Dune::Fem::Parameter::verbose()) {
198 std::cout <<
"Error: " << error << std::endl;
199 std::cout <<
"Estimate: " << estimate << std::endl;
202 maxError =
std::max(error, maxError);
203 maxEstimate =
std::max(estimate + scheme.timeEstimate(), maxEstimate);
206 if ((writeCount = scheme.output()) >= 0) {
208 std::string name = Dune::Fem::generateFilename(dataPath + prefix_ +
"-errorlog", writeCount);
210 f.open(name, std::ios::out|std::ios::trunc);
212 f << std::scientific << std::setprecision( 18 );
220 f << std::setw(10) << std::left << timeProvider.timeStep() - 1
221 << std::setw(30) << timeProvider.time()
222 << std::setw(30) << timeStep
223 << std::setw(30) << estimate
224 << std::setw(30) << error
225 << std::setw(30) << scheme.size()
237 while (timeProvider.time() < endTime) {
239 double spaceEstimate;
242 if (Dune::Fem::Parameter::verbose()) {
243 std::cout <<
"**** Starting time-step " << timeProvider.timeStep() <<
"@" << timeProvider.time() << std::endl;
249 if (Dune::Fem::Parameter::verbose()) {
250 std::cout <<
"Solving with step-size " << timeStep << std::endl;
257 spaceEstimate = scheme.estimate();
258 timeEstimate = scheme.timeEstimate();
260 if (Dune::Fem::Parameter::verbose()) {
261 std::cout <<
"spaceEstimate " << spaceEstimate <<
" (tolerance: " << spaceTolerance <<
")" << std::endl
262 <<
"timeEstimate " << timeEstimate <<
" (tolerance: " << timeTolerance <<
")" << std::endl;
265 if (++cnt > maximumIterations) {
271 if (timeEstimate > timeTolerance && timeStep > minDeltaT) {
272 timeStep *= timeNarrowFactor;
273 timeStep =
std::max(minDeltaT, timeStep);
274 timeProvider.init(timeStep);
282 if (scheme.mark(spaceTolerance)) {
285 spaceEstimate = scheme.estimate();
286 timeEstimate = scheme.timeEstimate();
287 if (timeEstimate > timeTolerance && timeStep > minDeltaT) {
288 if (Dune::Fem::Parameter::verbose()) {
289 std::cout <<
"Estimate: " << timeEstimate
290 <<
" (tolerance: " << timeTolerance <<
")"
292 std::cout <<
"timeEstimate > timeTolerance, restart"
295 timeStep *= timeNarrowFactor;
296 timeStep =
std::max(minDeltaT, timeStep);
297 timeProvider.init(timeStep);
301 if (++spaceCnt > spaceMaximumIterations) {
304 }
while (spaceEstimate > spaceTolerance);
305 }
while (timeEstimate > timeTolerance);
307 if (timeEstimate <= timeRelaxTolerance) {
308 timeStep *= timeRelaxFactor;
310 timeStep = std::min(maxDeltaT, timeStep);
320 double oldDeltaT = timeProvider.deltaT();
321 timeProvider.next(timeStep);
324 double error = scheme.error();
327 size_t size = scheme.size();
328 if (Dune::Fem::Parameter::verbose()) {
329 std::cout <<
"Error : " << error << std::endl;
330 std::cout <<
"Space Estimate: " << spaceEstimate << std::endl;
331 std::cout <<
"Time Estimate : " << timeEstimate << std::endl;
332 std::cout <<
"#DoFs : " << size << std::endl;
336 maxError =
std::max(error, maxError);
337 maxEstimate =
std::max(spaceEstimate + timeEstimate, maxEstimate);
340 if ((writeCount = scheme.output()) >= 0) {
342 std::string name = Dune::Fem::generateFilename(dataPath + prefix_ +
"-errorlog", writeCount);
344 f.open(name, std::ios::out|std::ios::trunc);
346 f << std::scientific << std::setprecision( 18 );
356 f << std::setw(10) << std::left << timeProvider.timeStep() - 1
357 << std::setw(30) << timeProvider.time()
358 << std::setw(30) << oldDeltaT
359 << std::setw(30) << spaceEstimate
360 << std::setw(30) << timeEstimate
361 << std::setw(30) << spaceEstimate + timeEstimate
362 << std::setw(30) << error
363 << std::setw(30) << scheme.size()
static std::pair< double, double > adaptiveAlgorithm(AdaptiveFemScheme &scheme, const std::string &prefix_="")
Stationary adaptive algorithm like adapt_method_stat() from poor old ALBERTA.
Definition: stationaryadaptivealgorithm.hh:39
LocalFunctionWrapper< LocalMaxAdapter< GridFunction1, GridFunction2 >, typename GridFunction1::GridPartType > max(const Fem::Function< typename GridFunction1::FunctionSpaceType, GridFunction1 > &f1, const Fem::Function< typename GridFunction2::FunctionSpaceType, GridFunction2 > &f2, const std::string &name="")
Pointwise maximum of two given functions.
Definition: maxfunction.hh:121