AdaptInstationary.cpp 7.16 KB
Newer Older
1
2
3
4
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

5
6
7
#include "AdaptInstationary.hpp"

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

namespace AMDiS
{
17
  AdaptInstationary::AdaptInstationary(std::string const& name,
18
                                       ProblemIterationInterface& problemIteration,
19
                                       AdaptInfo& adaptInfo,
20
21
                                       ProblemTimeInterface& problemTime,
                                       AdaptInfo& initialAdaptInfo)
22
    : AdaptBase(name, &problemIteration, adaptInfo, &problemTime, &initialAdaptInfo)
23
  {
24
25
26
27
    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_);
28

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


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

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


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

45
    problemTime_->setTime(adaptInfo_);
46

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

49
    adaptInfo_.setSpaceIteration(0);
50
51

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


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

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

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

70
      problemIteration_->oneIteration(adaptInfo_, NO_ADAPTION);
71

72
      adaptInfo_.incTimestepIteration();
73

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


85
      adaptInfo_.setSpaceIteration(0);
86
87
88
89


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

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

        // === Space iterations. ===
        do
        {
96
          problemIteration_->beginIteration(adaptInfo_);
97

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

113
114
          adaptInfo_.incSpaceIteration();
          problemIteration_->endIteration(adaptInfo_);
115
116

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

      }
      else
      {
123
        problemIteration_->endIteration(adaptInfo_);
124
125
126
127
      }


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

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

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

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


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

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

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

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

161
    problemIteration_->oneIteration(adaptInfo_, FULL_ITERATION);
162

Praetorius, Simon's avatar
Praetorius, Simon committed
163
    adaptInfo_.setLastProcessedTimestep(adaptInfo_.timestep());
164
165

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

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


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

181
    adaptInfo_.setTimestepIteration(0);
182

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

198
    adaptInfo_.incTimestepNumber();
199
200
201
202
203
204
205
206
  }


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

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

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

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

220
      problemTime_->setTime(adaptInfo_);
221
222

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

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

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

    return errorCode;
  }

} // end namespace AMDiS