AdaptInstationary.cc 10.8 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
#include "AdaptInstationary.h"
#include "Parameters.h"
#include "Estimator.h"
#include "TecPlotWriter.h"
#include "ProblemIterationInterface.h"
#include "ProblemTimeInterface.h"
#include "Serializer.h"

namespace AMDiS {

Thomas Witkowski's avatar
Thomas Witkowski committed
11
  AdaptInstationary::AdaptInstationary(std::string name,
12
				       ProblemIterationInterface *problemStat,  
13
14
15
16
				       AdaptInfo *info,
				       ProblemTimeInterface *problemInstat,
				       AdaptInfo *initialInfo,
				       time_t initialTimestamp)
17
    : AdaptBase(name, problemStat, info, problemInstat, initialInfo),
18
19
      breakWhenStable(0),
      dbgMode(false)
20
21
22
  {
    FUNCNAME("AdaptInstationary::AdaptInstationary()");

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
//     MSG("You make use of the obsolete constructor AdaptInstationary::AdaptInstationary(...)!\n");
//     MSG("Please use the constructor that uses references instead of pointers!\n");

    initConstructor(problemStat, info, initialInfo, initialTimestamp);
  }

  AdaptInstationary::AdaptInstationary(std::string name,
				       ProblemIterationInterface &problemStat,  
				       AdaptInfo &info,
				       ProblemTimeInterface &problemInstat,
				       AdaptInfo &initialInfo,
				       time_t initialTimestamp)
    : AdaptBase(name, &problemStat, &info, &problemInstat, &initialInfo),
      breakWhenStable(0),
      dbgMode(false)
  {
    FUNCNAME("AdaptInstationary::AdaptInstationary()");

    initConstructor(&problemStat, &info, &initialInfo, initialTimestamp);
  }

  void AdaptInstationary::initConstructor(ProblemIterationInterface *problemStat,  
					  AdaptInfo *info,
					  AdaptInfo *initialInfo,
					  time_t initialTimestamp)
  {
Thomas Witkowski's avatar
Thomas Witkowski committed
49
    initialize(name);
50
51
52

    fixedTimestep_ = (info->getMinTimestep() == info->getMaxTimestep());

53
    if (initialTimestamp == 0)
54
      initialTimestamp_ = time(NULL);
55
    else
56
      initialTimestamp_ = initialTimestamp;
57
    
58
    // Check if the problem should be deserialized because of the -rs parameter.
Thomas Witkowski's avatar
Thomas Witkowski committed
59
    std::string serializationFilename = "";
60
61
62
63
64
65
66
    GET_PARAMETER(0, "argv->rs", &serializationFilename);

    if (serializationFilename.compare("")) {
      // The value of the -rs argument is ignored, because we want to use the 
      // serialization file mentioned in the used init file.
      MSG("Deserialization from file: %s\n", queueSerializationFilename_.c_str());

Thomas Witkowski's avatar
Thomas Witkowski committed
67
      std::ifstream in(queueSerializationFilename_.c_str());
68
69
70
      deserialize(in);
      in.close();

71
72
      info->setIsDeserialized(true);
      initialInfo->setIsDeserialized(true);
73
74
75
76
77
78
79
80
81
82
    } else {
      int readSerialization = 0;
      int readSerializationWithAdaptInfo = 0;

      GET_PARAMETER(0, (*problemStat).getName() + "->input->read serialization", "%d", 
		    &readSerialization);
      GET_PARAMETER(0, (*problemStat).getName() + "->input->serialization with adaptinfo", "%d",
		    &readSerializationWithAdaptInfo);

      if (readSerialization && readSerializationWithAdaptInfo) {
Thomas Witkowski's avatar
Thomas Witkowski committed
83
	std::string serializationFilename = "";
84
85
86
87
88
89

	GET_PARAMETER(0, (*problemStat).getName() + "->input->serialization filename", 
		      &serializationFilename);
	TEST_EXIT(serializationFilename != "")("no serialization file\n");

	MSG("Deserialization with AdaptInfo from file: %s\n", serializationFilename.c_str());
Thomas Witkowski's avatar
Thomas Witkowski committed
90
	std::ifstream in(serializationFilename.c_str());
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
	deserialize(in);
	in.close();
      }
    }
  }

  AdaptInstationary::~AdaptInstationary()
  {
  }

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

    // estimate before first adaption
Thomas Witkowski's avatar
Thomas Witkowski committed
106
    if (adaptInfo->getTime() <= adaptInfo->getStartTime())
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
107
      problemIteration_->oneIteration(adaptInfo, ESTIMATE);
Thomas Witkowski's avatar
Thomas Witkowski committed
108
109


110
    // increment time
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
111
    adaptInfo->setTime(adaptInfo->getTime() + adaptInfo->getTimestep());
112

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
113
    problemTime_->setTime(adaptInfo);
114
115

    INFO(info_,6)("time = %e, timestep = %e\n",
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
116
		  adaptInfo->getTime(), adaptInfo->getTimestep());
117

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
118
    adaptInfo->setSpaceIteration(0);
119
120
  
    // do the iteration
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
121
122
123
    problemIteration_->beginIteration(adaptInfo);
    problemIteration_->oneIteration(adaptInfo, FULL_ITERATION);
    problemIteration_->endIteration(adaptInfo);
124
    adaptInfo->setLastProcessedTimestep(adaptInfo->getTimestep()); 
125
126
127
128
129
130
131
  }

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

    do {
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
132
133
      adaptInfo->setTime(adaptInfo->getTime() + adaptInfo->getTimestep());
      problemTime_->setTime(adaptInfo);
134
135

      INFO(info_,6)("time = %e, try timestep = %e\n",
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
136
		    adaptInfo->getTime(), adaptInfo->getTimestep());
137

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
138
      problemIteration_->oneIteration(adaptInfo, NO_ADAPTION);
139

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
140
      adaptInfo->incTimestepIteration();
141

142
      if (!fixedTimestep_ && 
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
143
	  !adaptInfo->timeToleranceReached() &&
Thomas Witkowski's avatar
Thomas Witkowski committed
144
	  !(adaptInfo->getTimestep() <= adaptInfo->getMinTimestep())) {
145

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
146
147
	adaptInfo->setTime(adaptInfo->getTime() - adaptInfo->getTimestep());
	adaptInfo->setTimestep(adaptInfo->getTimestep() * time_delta_1);
148
149
	continue;
      }
150

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
151
      adaptInfo->setSpaceIteration(0);
152
153
154
155


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

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
156
      if (adaptInfo->getMaxSpaceIteration() > 0) {
157
    
158
159
	/* === Space iterations === */
	do {
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
160
	  problemIteration_->beginIteration(adaptInfo);
161
	  
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
162
	  if (problemIteration_->oneIteration(adaptInfo, FULL_ITERATION)) {
163
	    if (!fixedTimestep_ && 
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
164
		!adaptInfo->timeToleranceReached() &&
Thomas Witkowski's avatar
Thomas Witkowski committed
165
166
167
168
169
170
171
		!(adaptInfo->getTimestep() <= adaptInfo->getMinTimestep())) {
	      adaptInfo->setTime(adaptInfo->getTime() - adaptInfo->getTimestep());
	      adaptInfo->setTimestep(adaptInfo->getTimestep() * time_delta_1);
	      problemIteration_->endIteration(adaptInfo);
	      adaptInfo->incSpaceIteration();
	      break;
	    }	
172
173
	  }

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
174
175
	  adaptInfo->incSpaceIteration();
	  problemIteration_->endIteration(adaptInfo);
176
	  
Thomas Witkowski's avatar
Thomas Witkowski committed
177
178
	} while (!adaptInfo->spaceToleranceReached() && 
		 adaptInfo->getSpaceIteration() <= adaptInfo->getMaxSpaceIteration());
179
180

      } else {
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
181
	problemIteration_->endIteration(adaptInfo);
182
183
      }

184

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
185
    } while(!adaptInfo->timeToleranceReached() &&
Thomas Witkowski's avatar
Thomas Witkowski committed
186
	    !(adaptInfo->getTimestep() <= adaptInfo->getMinTimestep()) && 
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
187
	    adaptInfo->getTimestepIteration() <= adaptInfo->getMaxTimestepIteration());  
188
    adaptInfo->setLastProcessedTimestep(adaptInfo->getTimestep()); 
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
189
    if (!fixedTimestep_ && adaptInfo->timeErrorLow()) {
Thomas Witkowski's avatar
Thomas Witkowski committed
190
      adaptInfo->setTimestep(adaptInfo->getTimestep() * time_delta_2);
191
192
193
194
195
196
197
      if (dbgMode) {
	// print information about timestep increase
      }
    } else {
      if (dbgMode) {
	std::cout << "=== ADAPT INFO DEBUG MODE ===\n";
	std::cout << " Do not increase timestep: \n";
Thomas Witkowski's avatar
Thomas Witkowski committed
198
	if (fixedTimestep_)
199
	  std::cout << "   fixedTimestep = true\n";	
Thomas Witkowski's avatar
Thomas Witkowski committed
200
	if (!adaptInfo->timeErrorLow())
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
201
	  adaptInfo->printTimeErrorLowInfo();
202
      }
203
204
205
206
207
    }
  }

  void AdaptInstationary::oneTimestep()
  {
208
    FUNCNAME("AdaptInstationary::oneTimestep()");
209

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
210
    adaptInfo->setTimestepIteration(0);
211

212
213
214
215
216
217
218
219
220
221
222
    switch (strategy) {
    case 0:
      explicitTimeStrategy();
      break;
    case 1:
      implicitTimeStrategy();
      break;
    default:
      MSG("unknown strategy = %d; use explicit strategy\n", strategy);
      explicitTimeStrategy();
    }
223

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
224
    adaptInfo->incTimestepNumber();
225
226
227
228
229
230
231
232
  }

  int AdaptInstationary::adapt()
  {
    FUNCNAME("AdaptInstationary::adapt()");

    int errorCode = 0;

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
233
    TEST_EXIT(adaptInfo->getTimestep() >= adaptInfo->getMinTimestep())
234
      ("timestep < min timestep\n");
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
235
    TEST_EXIT(adaptInfo->getTimestep() <= adaptInfo->getMaxTimestep())
236
237
      ("timestep > max timestep\n");

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
238
    TEST_EXIT(adaptInfo->getTimestep() > 0)("timestep <= 0!\n");
239

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
240
241
242
243
    if (adaptInfo->getTimestepNumber() == 0) {
      adaptInfo->setTime(adaptInfo->getStartTime());
      initialAdaptInfo_->setStartTime(adaptInfo->getStartTime());
      initialAdaptInfo_->setTime(adaptInfo->getStartTime());
244

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
245
      problemTime_->setTime(adaptInfo);
246
247
248

      // initial adaption
      problemTime_->solveInitialProblem(initialAdaptInfo_);
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
249
      problemTime_->transferInitialSolution(adaptInfo);
250
251
    }

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
252
    while (!adaptInfo->reachedEndTime()) {
253
254
      iterationTimestamp_ = time(NULL);

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
255
      problemTime_->initTimestep(adaptInfo);
256
      oneTimestep();
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
257
      problemTime_->closeTimestep(adaptInfo);
Thomas Witkowski's avatar
Thomas Witkowski committed
258

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
259
      if (breakWhenStable && (adaptInfo->getSolverIterations() == 0)) {
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
	break;
      }

      // Check if there is a runtime limitation. If there is a runtime limitation
      // and there is no more time for a next adaption loop, than return the error
      // code for rescheduling the problem and break the adaption loop.
      if (checkQueueRuntime()) {
	errorCode = RescheduleErrorCode;
	break;
      }
    }

    return errorCode;
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
275
  void AdaptInstationary::initialize(std::string aName)
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
  {
    FUNCNAME("AdaptInstationary::initialize()");

    strategy = 0;
    time_delta_1 = 0.7071;
    time_delta_2 = 1.4142;
    queueRuntime_ = -1;
    queueSerializationFilename_ = "__serialized_problem.ser";

    GET_PARAMETER(0, aName + "->strategy", "%d", &strategy);
    GET_PARAMETER(0, aName + "->time delta 1", "%f", &time_delta_1);
    GET_PARAMETER(0, aName + "->time delta 2", "%f", &time_delta_2);
    GET_PARAMETER(0, aName + "->info", "%d", &info_);
    GET_PARAMETER(0, aName + "->break when stable", "%d", &breakWhenStable);
    GET_PARAMETER(0, aName + "->queue->runtime", "%d", &queueRuntime_);
Thomas Witkowski's avatar
Thomas Witkowski committed
291
292
    GET_PARAMETER(0, aName + "->queue->serialization filename", 
		  &queueSerializationFilename_);
293
294
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
295
  void AdaptInstationary::serialize(std::ostream &out)
296
297
298
299
  {
    FUNCNAME("AdaptInstationary::serialize()");

    problemIteration_->serialize(out);
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
300
    adaptInfo->serialize(out);
301
302
303
304
305
    if (problemTime_) {
      problemTime_->serialize(out);
    }
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
306
  void AdaptInstationary::deserialize(std::istream &in)
307
308
309
310
  {
    FUNCNAME("AdaptInstationary::deserialize()");

    problemIteration_->deserialize(in);
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
311
    adaptInfo->deserialize(in);
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
    if (problemTime_) {
      problemTime_->deserialize(in);
    }
  }


  bool AdaptInstationary::checkQueueRuntime()
  {
    // If there is no time limited runtime queue, there is also nothing to check.
    if (queueRuntime_ == -1) {
      return false;
    }

    // Get the current time.
    time_t currentTimestamp = time(NULL);

    // Update list with the last iteration runtimes.
329
    lastIterationsDuration_.push(currentTimestamp - iterationTimestamp_);
330
    // The list should not contain more than 5 elements. If so, delete the oldest one.
331
332
    if (lastIterationsDuration_.size() > 5) {
      lastIterationsDuration_.pop();
333
334
335
    }

    // Calculate the avarage of the last iterations.
Thomas Witkowski's avatar
Thomas Witkowski committed
336
    std::queue<int> tmpQueue = lastIterationsDuration_;
337
338
339
340
341
    int avrgLastIterations = 0;
    while (!tmpQueue.empty()) {
      avrgLastIterations += tmpQueue.front();
      tmpQueue.pop();
    } 
342
    avrgLastIterations /= lastIterationsDuration_.size();
343
344
345
    
    // Check if there is enough time for a further iteration.
    if (initialTimestamp_ + queueRuntime_ - currentTimestamp < avrgLastIterations * 2) {
Thomas Witkowski's avatar
Thomas Witkowski committed
346
      std::ofstream out(queueSerializationFilename_.c_str());
347
348
349
350
351
352
353
354
355
356
      serialize(out);
      out.close();

      return true;
    }

    return false;
  }

}