AdaptInstationary.cc 12.2 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
//     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);
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
29

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
  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);
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
45

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

Thomas Witkowski's avatar
Thomas Witkowski committed
53
    fixedTimestep = (info->getMinTimestep() == info->getMaxTimestep());
54

55
    if (initialTimestamp == 0)
Thomas Witkowski's avatar
Thomas Witkowski committed
56
      initialTimestamp = time(NULL);
57
    else
Thomas Witkowski's avatar
Thomas Witkowski committed
58
      initialTimestamp = initialTimestamp;
59
    
60
    // Check if the problem should be deserialized because of the -rs parameter.
Thomas Witkowski's avatar
Thomas Witkowski committed
61
    std::string serializationFilename = "";
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.
Thomas Witkowski's avatar
Thomas Witkowski committed
67
      MSG("Deserialization from file: %s\n", queueSerializationFilename.c_str());
68

Thomas Witkowski's avatar
Thomas Witkowski committed
69
      std::ifstream in(queueSerializationFilename.c_str());
70
71
72
      deserialize(in);
      in.close();

73
74
      info->setIsDeserialized(true);
      initialInfo->setIsDeserialized(true);
75
76
77
78
79
80
81
82
83
84
    } 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
85
	std::string serializationFilename = "";
86
87
88
89
90
91

	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
92
	std::ifstream in(serializationFilename.c_str());
93
94
95
96
97
98
	deserialize(in);
	in.close();
      }
    }
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
99

100
101
102
103
  AdaptInstationary::~AdaptInstationary()
  {
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
104

105
106
107
108
109
  void AdaptInstationary::explicitTimeStrategy()
  {
    FUNCNAME("AdaptInstationary::explicitTimeStrategy()");

    // estimate before first adaption
Thomas Witkowski's avatar
Thomas Witkowski committed
110
    if (adaptInfo->getTime() <= adaptInfo->getStartTime())
Thomas Witkowski's avatar
Thomas Witkowski committed
111
      problemIteration->oneIteration(adaptInfo, ESTIMATE);
Thomas Witkowski's avatar
Thomas Witkowski committed
112
113


114
    // increment time
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
115
    adaptInfo->setTime(adaptInfo->getTime() + adaptInfo->getTimestep());
116

Thomas Witkowski's avatar
Thomas Witkowski committed
117
    problemTime->setTime(adaptInfo);
118

Thomas Witkowski's avatar
Thomas Witkowski committed
119
    INFO(info,6)("time = %e, timestep = %e\n",
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
120
		  adaptInfo->getTime(), adaptInfo->getTimestep());
121

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

Thomas Witkowski's avatar
Thomas Witkowski committed
131

132
133
134
135
136
  void AdaptInstationary::implicitTimeStrategy()
  {
    FUNCNAME("AdaptInstationary::implicitTimeStrategy()");

    do {
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
137
      adaptInfo->setTime(adaptInfo->getTime() + adaptInfo->getTimestep());
Thomas Witkowski's avatar
Thomas Witkowski committed
138
      problemTime->setTime(adaptInfo);
139

Thomas Witkowski's avatar
Thomas Witkowski committed
140
141
      INFO(info,6)("time = %e, try timestep = %e\n",
		   adaptInfo->getTime(), adaptInfo->getTimestep());
142

Thomas Witkowski's avatar
Thomas Witkowski committed
143
      problemIteration->oneIteration(adaptInfo, NO_ADAPTION);
144

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
145
      adaptInfo->incTimestepIteration();
146
   
Thomas Witkowski's avatar
Thomas Witkowski committed
147
      if (!fixedTimestep && 
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
148
	  !adaptInfo->timeToleranceReached() &&
149
	  adaptInfo->getTimestepIteration() <= adaptInfo->getMaxTimestepIteration() &&
Thomas Witkowski's avatar
Thomas Witkowski committed
150
	  !(adaptInfo->getTimestep() <= adaptInfo->getMinTimestep())) {
151
152
	  
	  adaptInfo->setTime(adaptInfo->getTime() - adaptInfo->getTimestep());
Thomas Witkowski's avatar
Thomas Witkowski committed
153
	  adaptInfo->setTimestep(adaptInfo->getTimestep() * timeDelta1);
154
	  continue;
155
      }
156

157

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
158
      adaptInfo->setSpaceIteration(0);
159
160
161
162


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

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
163
      if (adaptInfo->getMaxSpaceIteration() > 0) {
164
    
165
166
	/* === Space iterations === */
	do {
Thomas Witkowski's avatar
Thomas Witkowski committed
167
	  problemIteration->beginIteration(adaptInfo);
168
	  
Thomas Witkowski's avatar
Thomas Witkowski committed
169
170
	  if (problemIteration->oneIteration(adaptInfo, FULL_ITERATION)) {
	    if (!fixedTimestep && 
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
171
		!adaptInfo->timeToleranceReached() &&
Thomas Witkowski's avatar
Thomas Witkowski committed
172
173
		!(adaptInfo->getTimestep() <= adaptInfo->getMinTimestep())) {
	      adaptInfo->setTime(adaptInfo->getTime() - adaptInfo->getTimestep());
Thomas Witkowski's avatar
Thomas Witkowski committed
174
175
	      adaptInfo->setTimestep(adaptInfo->getTimestep() * timeDelta2);
	      problemIteration->endIteration(adaptInfo);
Thomas Witkowski's avatar
Thomas Witkowski committed
176
177
178
	      adaptInfo->incSpaceIteration();
	      break;
	    }	
179
180
	  }

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
181
	  adaptInfo->incSpaceIteration();
Thomas Witkowski's avatar
Thomas Witkowski committed
182
	  problemIteration->endIteration(adaptInfo);
183
	  
Thomas Witkowski's avatar
Thomas Witkowski committed
184
185
	} while (!adaptInfo->spaceToleranceReached() && 
		 adaptInfo->getSpaceIteration() <= adaptInfo->getMaxSpaceIteration());
186
187

      } else {
Thomas Witkowski's avatar
Thomas Witkowski committed
188
	problemIteration->endIteration(adaptInfo);
189
190
      }

191

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
192
    } while(!adaptInfo->timeToleranceReached() &&
Thomas Witkowski's avatar
Thomas Witkowski committed
193
	    !(adaptInfo->getTimestep() <= adaptInfo->getMinTimestep()) && 
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
194
	    adaptInfo->getTimestepIteration() <= adaptInfo->getMaxTimestepIteration());  
195

196
    adaptInfo->setLastProcessedTimestep(adaptInfo->getTimestep()); 
197
198
199
200

    // After successful iteration/timestep the timestep will be changed according 
    // adaption rules for next timestep. 
    // First, check for increase of timestep
Thomas Witkowski's avatar
Thomas Witkowski committed
201
202
    if (!fixedTimestep && adaptInfo->timeErrorLow()) {
      adaptInfo->setTimestep(adaptInfo->getTimestep() * timeDelta2);
203
204
205
206
207
208
209
      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
210
	if (fixedTimestep)
211
	  std::cout << "   fixedTimestep = true\n";	
Thomas Witkowski's avatar
Thomas Witkowski committed
212
	if (!adaptInfo->timeErrorLow())
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
213
	  adaptInfo->printTimeErrorLowInfo();
214
      }
215
    }
Thomas Witkowski's avatar
Thomas Witkowski committed
216

217
    // Second, check for decrease of timestep
Thomas Witkowski's avatar
Thomas Witkowski committed
218
    if (!fixedTimestep &&
219
	!adaptInfo->timeToleranceReached() &&
Thomas Witkowski's avatar
Thomas Witkowski committed
220
221
	!(adaptInfo->getTimestep() <= adaptInfo->getMinTimestep()))
	adaptInfo->setTimestep(adaptInfo->getTimestep() * timeDelta1);    
222
223
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254

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

    // estimate before first adaption
    if (adaptInfo->getTime() <= adaptInfo->getStartTime())
      problemIteration->oneIteration(adaptInfo, ESTIMATE);

    adaptInfo->setTime(adaptInfo->getTime() + adaptInfo->getTimestep());
    problemTime->setTime(adaptInfo);
    
    INFO(info,6)("time = %e, timestep = %e\n",
		 adaptInfo->getTime(), adaptInfo->getTimestep());
    
    problemIteration->oneIteration(adaptInfo, FULL_ITERATION);

    adaptInfo->setLastProcessedTimestep(adaptInfo->getTimestep());        
    
    // First, check for increase of timestep
    if (!fixedTimestep && adaptInfo->timeErrorLow())
      adaptInfo->setTimestep(adaptInfo->getTimestep() * timeDelta2);
    
    // Second, check for decrease of timestep
    if (!fixedTimestep &&
	!adaptInfo->timeToleranceReached() &&
	!(adaptInfo->getTimestep() <= adaptInfo->getMinTimestep()))
      adaptInfo->setTimestep(adaptInfo->getTimestep() * timeDelta1);    
  }


255
256
  void AdaptInstationary::oneTimestep()
  {
257
    FUNCNAME("AdaptInstationary::oneTimestep()");
258

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

261
262
263
264
265
266
267
    switch (strategy) {
    case 0:
      explicitTimeStrategy();
      break;
    case 1:
      implicitTimeStrategy();
      break;
Thomas Witkowski's avatar
Thomas Witkowski committed
268
269
270
    case 2:
      simpleAdaptiveTimeStrategy();
      break;
271
    default:
Thomas Witkowski's avatar
Thomas Witkowski committed
272
      ERROR_EXIT("Unknown strategy = %d!\n", strategy);
273
    }
274

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
275
    adaptInfo->incTimestepNumber();
276
277
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
278

279
280
281
282
283
284
  int AdaptInstationary::adapt()
  {
    FUNCNAME("AdaptInstationary::adapt()");

    int errorCode = 0;

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
285
    TEST_EXIT(adaptInfo->getTimestep() >= adaptInfo->getMinTimestep())
286
      ("timestep < min timestep\n");
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
287
    TEST_EXIT(adaptInfo->getTimestep() <= adaptInfo->getMaxTimestep())
288
289
      ("timestep > max timestep\n");

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

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
292
293
    if (adaptInfo->getTimestepNumber() == 0) {
      adaptInfo->setTime(adaptInfo->getStartTime());
Thomas Witkowski's avatar
Thomas Witkowski committed
294
295
      initialAdaptInfo->setStartTime(adaptInfo->getStartTime());
      initialAdaptInfo->setTime(adaptInfo->getStartTime());
296

Thomas Witkowski's avatar
Thomas Witkowski committed
297
      problemTime->setTime(adaptInfo);
298
299

      // initial adaption
Thomas Witkowski's avatar
Thomas Witkowski committed
300
301
      problemTime->solveInitialProblem(initialAdaptInfo);
      problemTime->transferInitialSolution(adaptInfo);
302
303
    }

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
304
    while (!adaptInfo->reachedEndTime()) {
Thomas Witkowski's avatar
Thomas Witkowski committed
305
      iterationTimestamp = time(NULL);
306

Thomas Witkowski's avatar
Thomas Witkowski committed
307
      problemTime->initTimestep(adaptInfo);
308
      oneTimestep();
Thomas Witkowski's avatar
Thomas Witkowski committed
309
      problemTime->closeTimestep(adaptInfo);
Thomas Witkowski's avatar
Thomas Witkowski committed
310

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
311
      if (breakWhenStable && (adaptInfo->getSolverIterations() == 0)) {
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
	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
327

Thomas Witkowski's avatar
Thomas Witkowski committed
328
  void AdaptInstationary::initialize(std::string aName)
329
330
331
332
  {
    FUNCNAME("AdaptInstationary::initialize()");

    strategy = 0;
Thomas Witkowski's avatar
Thomas Witkowski committed
333
334
335
336
    timeDelta1 = 0.7071;
    timeDelta2 = 1.4142;
    queueRuntime = -1;
    queueSerializationFilename = "__serialized_problem.ser";
337
338

    GET_PARAMETER(0, aName + "->strategy", "%d", &strategy);
Thomas Witkowski's avatar
Thomas Witkowski committed
339
340
341
    GET_PARAMETER(0, aName + "->time delta 1", "%f", &timeDelta1);
    GET_PARAMETER(0, aName + "->time delta 2", "%f", &timeDelta2);
    GET_PARAMETER(0, aName + "->info", "%d", &info);
342
    GET_PARAMETER(0, aName + "->break when stable", "%d", &breakWhenStable);
Thomas Witkowski's avatar
Thomas Witkowski committed
343
    GET_PARAMETER(0, aName + "->queue->runtime", "%d", &queueRuntime);
Thomas Witkowski's avatar
Thomas Witkowski committed
344
    GET_PARAMETER(0, aName + "->queue->serialization filename", 
Thomas Witkowski's avatar
Thomas Witkowski committed
345
		  &queueSerializationFilename);
346
347
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
348

Thomas Witkowski's avatar
Thomas Witkowski committed
349
  void AdaptInstationary::serialize(std::ostream &out)
350
351
352
  {
    FUNCNAME("AdaptInstationary::serialize()");

Thomas Witkowski's avatar
Thomas Witkowski committed
353
    problemIteration->serialize(out);
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
354
    adaptInfo->serialize(out);
Thomas Witkowski's avatar
Thomas Witkowski committed
355
356
    if (problemTime)
      problemTime->serialize(out);    
357
358
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
359

Thomas Witkowski's avatar
Thomas Witkowski committed
360
  void AdaptInstationary::deserialize(std::istream &in)
361
362
363
  {
    FUNCNAME("AdaptInstationary::deserialize()");

Thomas Witkowski's avatar
Thomas Witkowski committed
364
    problemIteration->deserialize(in);
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
365
    adaptInfo->deserialize(in);
Thomas Witkowski's avatar
Thomas Witkowski committed
366
367
    if (problemTime)
      problemTime->deserialize(in);    
368
369
370
371
372
373
  }


  bool AdaptInstationary::checkQueueRuntime()
  {
    // If there is no time limited runtime queue, there is also nothing to check.
Thomas Witkowski's avatar
Thomas Witkowski committed
374
    if (queueRuntime == -1) {
375
376
377
378
379
380
381
      return false;
    }

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

    // Update list with the last iteration runtimes.
Thomas Witkowski's avatar
Thomas Witkowski committed
382
    lastIterationsDuration.push(currentTimestamp - iterationTimestamp);
383
    // The list should not contain more than 5 elements. If so, delete the oldest one.
Thomas Witkowski's avatar
Thomas Witkowski committed
384
385
    if (lastIterationsDuration.size() > 5)
      lastIterationsDuration.pop();    
386
387

    // Calculate the avarage of the last iterations.
Thomas Witkowski's avatar
Thomas Witkowski committed
388
    std::queue<int> tmpQueue = lastIterationsDuration;
389
390
391
392
393
    int avrgLastIterations = 0;
    while (!tmpQueue.empty()) {
      avrgLastIterations += tmpQueue.front();
      tmpQueue.pop();
    } 
Thomas Witkowski's avatar
Thomas Witkowski committed
394
    avrgLastIterations /= lastIterationsDuration.size();
395
396
    
    // Check if there is enough time for a further iteration.
Thomas Witkowski's avatar
Thomas Witkowski committed
397
398
    if (initialTimestamp + queueRuntime - currentTimestamp < avrgLastIterations * 2) {
      std::ofstream out(queueSerializationFilename.c_str());
399
400
401
402
403
404
405
406
407
408
      serialize(out);
      out.close();

      return true;
    }

    return false;
  }

}