AdaptInstationary.cc 12.4 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
//
// Software License for AMDiS
//
// Copyright (c) 2010 Dresden University of Technology 
// All rights reserved.
// Authors: Simon Vey, Thomas Witkowski et al.
//
// This file is part of AMDiS
//
// See also license.opensource.txt in the distribution.


13
14
15
16
17
18
19
20
21
#include "AdaptInstationary.h"
#include "Parameters.h"
#include "Estimator.h"
#include "ProblemIterationInterface.h"
#include "ProblemTimeInterface.h"
#include "Serializer.h"

namespace AMDiS {

Thomas Witkowski's avatar
Thomas Witkowski committed
22
  AdaptInstationary::AdaptInstationary(std::string name,
23
				       ProblemIterationInterface *problemStat,  
24
25
26
				       AdaptInfo *info,
				       ProblemTimeInterface *problemInstat,
				       AdaptInfo *initialInfo,
27
				       time_t initialTimestampSet)
28
    : AdaptBase(name, problemStat, info, problemInstat, initialInfo),
29
30
      breakWhenStable(0),
      dbgMode(false)
31
32
33
  {
    FUNCNAME("AdaptInstationary::AdaptInstationary()");

34
35
36
//     MSG("You make use of the obsolete constructor AdaptInstationary::AdaptInstationary(...)!\n");
//     MSG("Please use the constructor that uses references instead of pointers!\n");

37
38
    initConstructor(problemStat, info, initialInfo, initialTimestampSet);
 }
39

Thomas Witkowski's avatar
Thomas Witkowski committed
40

41
42
43
44
45
  AdaptInstationary::AdaptInstationary(std::string name,
				       ProblemIterationInterface &problemStat,  
				       AdaptInfo &info,
				       ProblemTimeInterface &problemInstat,
				       AdaptInfo &initialInfo,
46
				       time_t initialTimestampSet)
47
48
49
50
51
52
    : AdaptBase(name, &problemStat, &info, &problemInstat, &initialInfo),
      breakWhenStable(0),
      dbgMode(false)
  {
    FUNCNAME("AdaptInstationary::AdaptInstationary()");

53
    initConstructor(&problemStat, &info, &initialInfo, initialTimestampSet);
54
55
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
56

57
58
59
  void AdaptInstationary::initConstructor(ProblemIterationInterface *problemStat,  
					  AdaptInfo *info,
					  AdaptInfo *initialInfo,
60
					  time_t initialTimestampSet)
61
  {
Thomas Witkowski's avatar
Thomas Witkowski committed
62
    initialize(name);
63

Thomas Witkowski's avatar
Thomas Witkowski committed
64
    fixedTimestep = (info->getMinTimestep() == info->getMaxTimestep());
65
66
 
    if (initialTimestampSet == 0)
Thomas Witkowski's avatar
Thomas Witkowski committed
67
      initialTimestamp = time(NULL);
68
    else
69
70
      initialTimestamp = initialTimestampSet;

71
    // Check if the problem should be deserialized because of the -rs parameter.
Thomas Witkowski's avatar
Thomas Witkowski committed
72
    std::string serializationFilename = "";
73
    Parameters::get("argv->rs", serializationFilename);
74
75
76
77

    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
78
      MSG("Deserialization from file: %s\n", queueSerializationFilename.c_str());
79

Thomas Witkowski's avatar
Thomas Witkowski committed
80
      std::ifstream in(queueSerializationFilename.c_str());
81
82
83
      deserialize(in);
      in.close();

84
85
      info->setIsDeserialized(true);
      initialInfo->setIsDeserialized(true);
86
87
88
89
    } else {
      int readSerialization = 0;
      int readSerializationWithAdaptInfo = 0;

90
91
92
93
      Parameters::get((*problemStat).getName() + "->input->read serialization",
		      readSerialization);
      Parameters::get((*problemStat).getName() + "->input->serialization with adaptinfo",
		      readSerializationWithAdaptInfo);
94
95

      if (readSerialization && readSerializationWithAdaptInfo) {
Thomas Witkowski's avatar
Thomas Witkowski committed
96
	std::string serializationFilename = "";
97

98
99
	Parameters::get((*problemStat).getName() + "->input->serialization filename", 
			serializationFilename);
100
101
102
	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
103
	std::ifstream in(serializationFilename.c_str());
104
105
106
107
108
109
	deserialize(in);
	in.close();
      }
    }
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
110

111
112
113
114
115
  void AdaptInstationary::explicitTimeStrategy()
  {
    FUNCNAME("AdaptInstationary::explicitTimeStrategy()");

    // estimate before first adaption
Thomas Witkowski's avatar
Thomas Witkowski committed
116
    if (adaptInfo->getTime() <= adaptInfo->getStartTime())
Thomas Witkowski's avatar
Thomas Witkowski committed
117
      problemIteration->oneIteration(adaptInfo, ESTIMATE);
Thomas Witkowski's avatar
Thomas Witkowski committed
118
119


120
    // increment time
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
121
    adaptInfo->setTime(adaptInfo->getTime() + adaptInfo->getTimestep());
122

Thomas Witkowski's avatar
Thomas Witkowski committed
123
    problemTime->setTime(adaptInfo);
124

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

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
128
    adaptInfo->setSpaceIteration(0);
129
130
  
    // do the iteration
Thomas Witkowski's avatar
Thomas Witkowski committed
131
132
133
    problemIteration->beginIteration(adaptInfo);
    problemIteration->oneIteration(adaptInfo, FULL_ITERATION);
    problemIteration->endIteration(adaptInfo);
134
    adaptInfo->setLastProcessedTimestep(adaptInfo->getTimestep()); 
135
136
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
137

138
139
140
141
142
  void AdaptInstationary::implicitTimeStrategy()
  {
    FUNCNAME("AdaptInstationary::implicitTimeStrategy()");

    do {
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
143
      adaptInfo->setTime(adaptInfo->getTime() + adaptInfo->getTimestep());
Thomas Witkowski's avatar
Thomas Witkowski committed
144
      problemTime->setTime(adaptInfo);
145

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

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

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
151
      adaptInfo->incTimestepIteration();
152

Thomas Witkowski's avatar
Thomas Witkowski committed
153
      if (!fixedTimestep && 
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
154
	  !adaptInfo->timeToleranceReached() &&
155
	  adaptInfo->getTimestepIteration() <= adaptInfo->getMaxTimestepIteration() &&
Thomas Witkowski's avatar
Thomas Witkowski committed
156
	  !(adaptInfo->getTimestep() <= adaptInfo->getMinTimestep())) {
157
158
159
160
  
	adaptInfo->setTime(adaptInfo->getTime() - adaptInfo->getTimestep());
	adaptInfo->setTimestep(adaptInfo->getTimestep() * timeDelta1);
	continue;
161
      }
162

163

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
164
      adaptInfo->setSpaceIteration(0);
165
166


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

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

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
187
	  adaptInfo->incSpaceIteration();
Thomas Witkowski's avatar
Thomas Witkowski committed
188
	  problemIteration->endIteration(adaptInfo);
189
	  
Thomas Witkowski's avatar
Thomas Witkowski committed
190
191
	} while (!adaptInfo->spaceToleranceReached() && 
		 adaptInfo->getSpaceIteration() <= adaptInfo->getMaxSpaceIteration());
192
193

      } else {
Thomas Witkowski's avatar
Thomas Witkowski committed
194
	problemIteration->endIteration(adaptInfo);
195
196
      }

197

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
198
    } while(!adaptInfo->timeToleranceReached() &&
Thomas Witkowski's avatar
Thomas Witkowski committed
199
	    !(adaptInfo->getTimestep() <= adaptInfo->getMinTimestep()) && 
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
200
	    adaptInfo->getTimestepIteration() <= adaptInfo->getMaxTimestepIteration());  
201

202
    adaptInfo->setLastProcessedTimestep(adaptInfo->getTimestep()); 
203
204
205
206

    // 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
207
208
    if (!fixedTimestep && adaptInfo->timeErrorLow()) {
      adaptInfo->setTimestep(adaptInfo->getTimestep() * timeDelta2);
209
210
211
212
213
214
215
      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
216
	if (fixedTimestep)
217
	  std::cout << "   fixedTimestep = true\n";	
Thomas Witkowski's avatar
Thomas Witkowski committed
218
	if (!adaptInfo->timeErrorLow())
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
219
	  adaptInfo->printTimeErrorLowInfo();
220
      }
221
    }
Thomas Witkowski's avatar
Thomas Witkowski committed
222

223
    // Second, check for decrease of timestep
Thomas Witkowski's avatar
Thomas Witkowski committed
224
    if (!fixedTimestep &&
225
	!adaptInfo->timeToleranceReached() &&
Thomas Witkowski's avatar
Thomas Witkowski committed
226
227
	!(adaptInfo->getTimestep() <= adaptInfo->getMinTimestep()))
	adaptInfo->setTimestep(adaptInfo->getTimestep() * timeDelta1);    
228
229
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
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
255
256
257
258
259
260

  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);    
  }


261
262
  void AdaptInstationary::oneTimestep()
  {
263
    FUNCNAME("AdaptInstationary::oneTimestep()");
264

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

267
268
269
270
271
272
273
    switch (strategy) {
    case 0:
      explicitTimeStrategy();
      break;
    case 1:
      implicitTimeStrategy();
      break;
Thomas Witkowski's avatar
Thomas Witkowski committed
274
275
276
    case 2:
      simpleAdaptiveTimeStrategy();
      break;
277
    default:
Thomas Witkowski's avatar
Thomas Witkowski committed
278
      ERROR_EXIT("Unknown strategy = %d!\n", strategy);
279
    }
280

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
281
    adaptInfo->incTimestepNumber();
282
283
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
284

285
286
287
288
289
  int AdaptInstationary::adapt()
  {
    FUNCNAME("AdaptInstationary::adapt()");
    int errorCode = 0;

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
290
    TEST_EXIT(adaptInfo->getTimestep() >= adaptInfo->getMinTimestep())
291
      ("timestep < min timestep\n");
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
292
    TEST_EXIT(adaptInfo->getTimestep() <= adaptInfo->getMaxTimestep())
293
294
      ("timestep > max timestep\n");

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

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
297
298
    if (adaptInfo->getTimestepNumber() == 0) {
      adaptInfo->setTime(adaptInfo->getStartTime());
Thomas Witkowski's avatar
Thomas Witkowski committed
299
300
      initialAdaptInfo->setStartTime(adaptInfo->getStartTime());
      initialAdaptInfo->setTime(adaptInfo->getStartTime());
301

Thomas Witkowski's avatar
Thomas Witkowski committed
302
      problemTime->setTime(adaptInfo);
303
304

      // initial adaption
Thomas Witkowski's avatar
Thomas Witkowski committed
305
306
      problemTime->solveInitialProblem(initialAdaptInfo);
      problemTime->transferInitialSolution(adaptInfo);
307
308
    }

Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
309
    while (!adaptInfo->reachedEndTime()) {
Thomas Witkowski's avatar
Thomas Witkowski committed
310
      iterationTimestamp = time(NULL);
311

Thomas Witkowski's avatar
Thomas Witkowski committed
312
      problemTime->initTimestep(adaptInfo);
313
      oneTimestep();
Thomas Witkowski's avatar
Thomas Witkowski committed
314
      problemTime->closeTimestep(adaptInfo);
Thomas Witkowski's avatar
Thomas Witkowski committed
315

316
      if (breakWhenStable && (adaptInfo->getSolverIterations() == 0)) 
317
	break;
318
319
320
321
      /*     
      if (adaptInfo->forceBreak) 
	  break;
      */
322
323
324
325
326
327
328
329
330
331
332
333
      // 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
334

Thomas Witkowski's avatar
Thomas Witkowski committed
335
  void AdaptInstationary::initialize(std::string aName)
336
337
338
339
  {
    FUNCNAME("AdaptInstationary::initialize()");

    strategy = 0;
Thomas Witkowski's avatar
Thomas Witkowski committed
340
341
342
343
    timeDelta1 = 0.7071;
    timeDelta2 = 1.4142;
    queueRuntime = -1;
    queueSerializationFilename = "__serialized_problem.ser";
344

345
346
347
348
349
350
351
352
    Parameters::get(aName + "->strategy", strategy);
    Parameters::get(aName + "->time delta 1", timeDelta1);
    Parameters::get(aName + "->time delta 2", timeDelta2);
    Parameters::get(aName + "->info", info);
    Parameters::get(aName + "->break when stable", breakWhenStable);
    Parameters::get(aName + "->queue->runtime", queueRuntime);
    Parameters::get(aName + "->queue->serialization filename", 
		    queueSerializationFilename);
353
354
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
355

Thomas Witkowski's avatar
Thomas Witkowski committed
356
  void AdaptInstationary::serialize(std::ostream &out)
357
358
359
  {
    FUNCNAME("AdaptInstationary::serialize()");

360
    SerUtil::serialize(out, amdisRevisionNumber);
Thomas Witkowski's avatar
Thomas Witkowski committed
361
    problemIteration->serialize(out);
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
362
    adaptInfo->serialize(out);
Thomas Witkowski's avatar
Thomas Witkowski committed
363
364
    if (problemTime)
      problemTime->serialize(out);    
365
366
  }

Thomas Witkowski's avatar
Thomas Witkowski committed
367

Thomas Witkowski's avatar
Thomas Witkowski committed
368
  void AdaptInstationary::deserialize(std::istream &in)
369
370
371
  {
    FUNCNAME("AdaptInstationary::deserialize()");

Thomas Witkowski's avatar
Thomas Witkowski committed
372
    problemIteration->deserialize(in);
Thomas Witkowski's avatar
* Bla    
Thomas Witkowski committed
373
    adaptInfo->deserialize(in);
Thomas Witkowski's avatar
Thomas Witkowski committed
374
375
    if (problemTime)
      problemTime->deserialize(in);    
376
377
378
379
380
381
  }


  bool AdaptInstationary::checkQueueRuntime()
  {
    // If there is no time limited runtime queue, there is also nothing to check.
Thomas Witkowski's avatar
Thomas Witkowski committed
382
    if (queueRuntime == -1) {
383
384
385
386
387
388
      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
389
    lastIterationsDuration.push(currentTimestamp - iterationTimestamp);
390
    // The list should not contain more than 5 elements. If so, delete the oldest one.
Thomas Witkowski's avatar
Thomas Witkowski committed
391
392
    if (lastIterationsDuration.size() > 5)
      lastIterationsDuration.pop();    
393
394

    // Calculate the avarage of the last iterations.
Thomas Witkowski's avatar
Thomas Witkowski committed
395
    std::queue<int> tmpQueue = lastIterationsDuration;
396
397
    int avrgLastIterations = 0;
    while (!tmpQueue.empty()) {
398
399
	avrgLastIterations += tmpQueue.front();
	tmpQueue.pop();
400
    } 
Thomas Witkowski's avatar
Thomas Witkowski committed
401
    avrgLastIterations /= lastIterationsDuration.size();
402

403
    // Check if there is enough time for a further iteration.
Thomas Witkowski's avatar
Thomas Witkowski committed
404
405
    if (initialTimestamp + queueRuntime - currentTimestamp < avrgLastIterations * 2) {
      std::ofstream out(queueSerializationFilename.c_str());
406
407
408
409
410
411
412
413
414
415
      serialize(out);
      out.close();

      return true;
    }

    return false;
  }

}