AdaptInstationary.cpp 7.13 KB
Newer Older
Praetorius, Simon's avatar
Praetorius, Simon committed
1
#include <config.h>
2

3
4
5
#include "AdaptInstationary.hpp"

// AMDiS includes
6
7
8
9
10
11
#include <amdis/AdaptInfo.hpp>
#include <amdis/Flag.hpp>
#include <amdis/Initfile.hpp>
#include <amdis/Output.hpp>
#include <amdis/ProblemIterationInterface.hpp>
#include <amdis/ProblemTimeInterface.hpp>
12
13
14

namespace AMDiS
{
15
  AdaptInstationary::AdaptInstationary(std::string const& name,
16
                                       ProblemIterationInterface& problemIteration,
17
                                       AdaptInfo& adaptInfo,
18
19
                                       ProblemTimeInterface& problemTime,
                                       AdaptInfo& initialAdaptInfo)
20
    : AdaptBase(name, &problemIteration, adaptInfo, &problemTime, &initialAdaptInfo)
21
  {
22
23
24
25
    Parameters::get(name_ + "->strategy", strategy_);
    Parameters::get(name_ + "->time delta 1", timeDelta1_);
    Parameters::get(name_ + "->time delta 2", timeDelta2_);
    Parameters::get(name_ + "->break when stable", breakWhenStable_);
26

Praetorius, Simon's avatar
Praetorius, Simon committed
27
    fixedTimestep_ = (adaptInfo_.minTimestep() == adaptInfo_.maxTimestep());
28
29
30
31
32
33
34
35
  }


  void AdaptInstationary::explicitTimeStrategy()
  {
    AMDIS_FUNCNAME("AdaptInstationary::explicitTimeStrategy()");

    // estimate before first adaption
Praetorius, Simon's avatar
Praetorius, Simon committed
36
    if (adaptInfo_.time() <= adaptInfo_.startTime())
37
      problemIteration_->oneIteration(adaptInfo_, ESTIMATE);
38
39
40


    // increment time
Praetorius, Simon's avatar
Praetorius, Simon committed
41
    adaptInfo_.setTime(adaptInfo_.time() + adaptInfo_.timestep());
42

43
    problemTime_->setTime(adaptInfo_);
44

Praetorius, Simon's avatar
Praetorius, Simon committed
45
    msg("time = {}, timestep = {}", adaptInfo_.time(), adaptInfo_.timestep());
46

47
    adaptInfo_.setSpaceIteration(0);
48
49

    // do the iteration
50
51
52
    problemIteration_->beginIteration(adaptInfo_);
    problemIteration_->oneIteration(adaptInfo_, FULL_ITERATION);
    problemIteration_->endIteration(adaptInfo_);
Praetorius, Simon's avatar
Praetorius, Simon committed
53
    adaptInfo_.setLastProcessedTimestep(adaptInfo_.timestep());
54
55
56
57
58
59
60
61
62
  }


  void AdaptInstationary::implicitTimeStrategy()
  {
    AMDIS_FUNCNAME("AdaptInstationary::implicitTimeStrategy()");

    do
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
63
      adaptInfo_.setTime(adaptInfo_.time() + adaptInfo_.timestep());
64
      problemTime_->setTime(adaptInfo_);
65

Praetorius, Simon's avatar
Praetorius, Simon committed
66
      msg("time = {}, timestep = {}", adaptInfo_.time(), adaptInfo_.timestep());
67

68
      problemIteration_->oneIteration(adaptInfo_, NO_ADAPTION);
69

70
      adaptInfo_.incTimestepIteration();
71

72
73
      if (!fixedTimestep_ &&
          !adaptInfo_.timeToleranceReached() &&
Praetorius, Simon's avatar
Praetorius, Simon committed
74
75
          adaptInfo_.timestepIteration() <= adaptInfo_.maxTimestepIteration() &&
          !(adaptInfo_.timestep() <= adaptInfo_.minTimestep()))
76
      {
Praetorius, Simon's avatar
Praetorius, Simon committed
77
78
        adaptInfo_.setTime(adaptInfo_.time() - adaptInfo_.timestep());
        adaptInfo_.setTimestep(adaptInfo_.timestep() * timeDelta1_);
79
80
81
82
        continue;
      }


83
      adaptInfo_.setSpaceIteration(0);
84
85
86
87


      // === Do space iterations only if the maximum is higher than 0. ===

Praetorius, Simon's avatar
Praetorius, Simon committed
88
      if (adaptInfo_.maxSpaceIteration() > 0)
89
90
91
92
93
      {

        // === Space iterations. ===
        do
        {
94
          problemIteration_->beginIteration(adaptInfo_);
95

96
          Flag adapted = problemIteration_->oneIteration(adaptInfo_, FULL_ITERATION);
97
98
          if (adapted == Flag{0})
          {
99
100
            if (!fixedTimestep_ &&
                !adaptInfo_.timeToleranceReached() &&
Praetorius, Simon's avatar
Praetorius, Simon committed
101
                !(adaptInfo_.timestep() <= adaptInfo_.minTimestep()))
102
            {
Praetorius, Simon's avatar
Praetorius, Simon committed
103
104
              adaptInfo_.setTime(adaptInfo_.time() - adaptInfo_.timestep());
              adaptInfo_.setTimestep(adaptInfo_.timestep() * timeDelta2_);
105
106
              problemIteration_->endIteration(adaptInfo_);
              adaptInfo_.incSpaceIteration();
107
108
109
110
              break;
            }
          }

111
112
          adaptInfo_.incSpaceIteration();
          problemIteration_->endIteration(adaptInfo_);
113
114

        }
115
        while (!adaptInfo_.spaceToleranceReached() &&
Praetorius, Simon's avatar
Praetorius, Simon committed
116
               adaptInfo_.spaceIteration() <= adaptInfo_.maxSpaceIteration());
117
118
119
120

      }
      else
      {
121
        problemIteration_->endIteration(adaptInfo_);
122
123
124
125
      }


    }
126
    while(!adaptInfo_.timeToleranceReached() &&
Praetorius, Simon's avatar
Praetorius, Simon committed
127
128
          !(adaptInfo_.timestep() <= adaptInfo_.minTimestep()) &&
          adaptInfo_.timestepIteration() <= adaptInfo_.maxTimestepIteration());
129

Praetorius, Simon's avatar
Praetorius, Simon committed
130
    adaptInfo_.setLastProcessedTimestep(adaptInfo_.timestep());
131
132
133
134

    // After successful iteration/timestep the timestep will be changed according
    // adaption rules for next timestep.
    // First, check for increase of timestep
135
    if (!fixedTimestep_ && adaptInfo_.timeErrorLow())
Praetorius, Simon's avatar
Praetorius, Simon committed
136
      adaptInfo_.setTimestep(adaptInfo_.timestep() * timeDelta2_);
137
138

    // Second, check for decrease of timestep
139
140
    if (!fixedTimestep_ &&
        !adaptInfo_.timeToleranceReached() &&
Praetorius, Simon's avatar
Praetorius, Simon committed
141
142
        !(adaptInfo_.timestep() <= adaptInfo_.minTimestep()))
      adaptInfo_.setTimestep(adaptInfo_.timestep() * timeDelta1_);
143
144
145
146
147
148
149
150
  }


  void AdaptInstationary::simpleAdaptiveTimeStrategy()
  {
    AMDIS_FUNCNAME("AdaptInstationary::simpleAdaptiveTimeStrategy()");

    // estimate before first adaption
Praetorius, Simon's avatar
Praetorius, Simon committed
151
    if (adaptInfo_.time() <= adaptInfo_.startTime())
152
      problemIteration_->oneIteration(adaptInfo_, ESTIMATE);
153

Praetorius, Simon's avatar
Praetorius, Simon committed
154
    adaptInfo_.setTime(adaptInfo_.time() + adaptInfo_.timestep());
155
    problemTime_->setTime(adaptInfo_);
156

Praetorius, Simon's avatar
Praetorius, Simon committed
157
    msg("time = {}, timestep = {}", adaptInfo_.time(), adaptInfo_.timestep());
158

159
    problemIteration_->oneIteration(adaptInfo_, FULL_ITERATION);
160

Praetorius, Simon's avatar
Praetorius, Simon committed
161
    adaptInfo_.setLastProcessedTimestep(adaptInfo_.timestep());
162
163

    // First, check for increase of timestep
164
    if (!fixedTimestep_ && adaptInfo_.timeErrorLow())
Praetorius, Simon's avatar
Praetorius, Simon committed
165
      adaptInfo_.setTimestep(adaptInfo_.timestep() * timeDelta2_);
166
167

    // Second, check for decrease of timestep
168
169
    if (!fixedTimestep_ &&
        !adaptInfo_.timeToleranceReached() &&
Praetorius, Simon's avatar
Praetorius, Simon committed
170
171
        !(adaptInfo_.timestep() <= adaptInfo_.minTimestep()))
      adaptInfo_.setTimestep(adaptInfo_.timestep() * timeDelta1_);
172
173
174
175
176
177
178
  }


  void AdaptInstationary::oneTimestep()
  {
    AMDIS_FUNCNAME("AdaptInstationary::oneTimestep()");

179
    adaptInfo_.setTimestepIteration(0);
180

181
    switch (strategy_)
182
183
184
185
186
187
188
189
190
191
192
    {
    case 0:
      explicitTimeStrategy();
      break;
    case 1:
      implicitTimeStrategy();
      break;
    case 2:
      simpleAdaptiveTimeStrategy();
      break;
    default:
193
      error_exit("Unknown strategy = {}", strategy_);
194
195
    }

196
    adaptInfo_.incTimestepNumber();
197
198
199
200
201
202
203
204
  }


  int AdaptInstationary::adapt()
  {
    AMDIS_FUNCNAME("AdaptInstationary::adapt()");
    int errorCode = 0;

Praetorius, Simon's avatar
Praetorius, Simon committed
205
    test_exit(adaptInfo_.timestep() >= adaptInfo_.minTimestep(),
206
              "timestep < min timestep");
Praetorius, Simon's avatar
Praetorius, Simon committed
207
    test_exit(adaptInfo_.timestep() <= adaptInfo_.maxTimestep(),
208
              "timestep > max timestep");
209

Praetorius, Simon's avatar
Praetorius, Simon committed
210
    test_exit(adaptInfo_.timestep() > 0, "timestep <= 0!");
211

Praetorius, Simon's avatar
Praetorius, Simon committed
212
    if (adaptInfo_.timestepNumber() == 0)
213
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
214
215
216
      adaptInfo_.setTime(adaptInfo_.startTime());
      initialAdaptInfo_->setStartTime(adaptInfo_.startTime());
      initialAdaptInfo_->setTime(adaptInfo_.startTime());
217

218
      problemTime_->setTime(adaptInfo_);
219
220

      // initial adaption
221
222
      problemTime_->solveInitialProblem(*initialAdaptInfo_);
      problemTime_->transferInitialSolution(adaptInfo_);
223
224
    }

225
    while (!adaptInfo_.reachedEndTime())
226
    {
227
      problemTime_->initTimestep(adaptInfo_);
228
      oneTimestep();
229
      problemTime_->closeTimestep(adaptInfo_);
230

Praetorius, Simon's avatar
Praetorius, Simon committed
231
      if (breakWhenStable_ && (adaptInfo_.solverIterations() == 0))
232
233
234
235
236
237
238
        break;
    }

    return errorCode;
  }

} // end namespace AMDiS