-
Naumann, Andreas authored
implicit problem read arh file instead of dat files memory error warning in dofvector
Naumann, Andreas authoredimplicit problem read arh file instead of dat files memory error warning in dofvector
AdaptInstationary.cc 12.94 KiB
//
// 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.
#include "AdaptInstationary.h"
#include "Initfile.h"
#include "Estimator.h"
#include "ProblemIterationInterface.h"
#include "ProblemTimeInterface.h"
#include "Serializer.h"
#if HAVE_PARALLEL_DOMAIN_AMDIS
#include "parallel/MeshDistributor.h"
#ifndef HAVE_PARALLEL_MTL4
#include <petsc.h>
#endif
#endif
namespace AMDiS {
AdaptInstationary::AdaptInstationary(std::string name,
ProblemIterationInterface *problemStat,
AdaptInfo *info,
ProblemTimeInterface *problemInstat,
AdaptInfo *initialInfo,
time_t initialTimestampSet)
: AdaptBase(name, problemStat, info, problemInstat, initialInfo),
breakWhenStable(0),
dbgMode(false)
{
FUNCNAME("AdaptInstationary::AdaptInstationary()");
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, initialTimestampSet);
}
AdaptInstationary::AdaptInstationary(std::string name,
ProblemIterationInterface &problemStat,
AdaptInfo &info,
ProblemTimeInterface &problemInstat,
AdaptInfo &initialInfo,
time_t initialTimestampSet)
: AdaptBase(name, &problemStat, &info, &problemInstat, &initialInfo),
breakWhenStable(0),
dbgMode(false)
{
FUNCNAME("AdaptInstationary::AdaptInstationary()");
initConstructor(&problemStat, &info, &initialInfo, initialTimestampSet);
}
void AdaptInstationary::initConstructor(ProblemIterationInterface *problemStat,
AdaptInfo *info,
AdaptInfo *initialInfo,
time_t initialTimestampSet)
{
initialize(name);
fixedTimestep = (info->getMinTimestep() == info->getMaxTimestep());
if (initialTimestampSet == 0)
initialTimestamp = time(NULL);
else
initialTimestamp = initialTimestampSet;
// Check if the problem should be deserialized because of the -rs parameter.
std::string serializationFilename = "";
Parameters::get("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());
std::ifstream in(queueSerializationFilename.c_str() , ios::in);
deserialize(in);
in.close();
info->setIsDeserialized(true);
initialInfo->setIsDeserialized(true);
} else {
int readSerialization = 0;
int readSerializationWithAdaptInfo = 0;
Parameters::get((*problemStat).getName() + "->input->read serialization",
readSerialization);
Parameters::get((*problemStat).getName() + "->input->serialization with adaptinfo",
readSerializationWithAdaptInfo);
if (readSerialization && readSerializationWithAdaptInfo) {
std::string serializationFilename = "";
Parameters::get((*problemStat).getName() + "->input->serialization filename",
serializationFilename);
TEST_EXIT(serializationFilename != "")("no serialization file\n");
MSG("Deserialization with AdaptInfo from file: %s\n", serializationFilename.c_str());
std::ifstream in(serializationFilename.c_str());
deserialize(in);
in.close();
}
}
}
void AdaptInstationary::explicitTimeStrategy()
{
FUNCNAME("AdaptInstationary::explicitTimeStrategy()");
// estimate before first adaption
if (adaptInfo->getTime() <= adaptInfo->getStartTime())
problemIteration->oneIteration(adaptInfo, ESTIMATE);
// increment time
adaptInfo->setTime(adaptInfo->getTime() + adaptInfo->getTimestep());
problemTime->setTime(adaptInfo);
INFO(info, 6)("time = %e, timestep = %e\n",
adaptInfo->getTime(), adaptInfo->getTimestep());
adaptInfo->setSpaceIteration(0);
// do the iteration
problemIteration->beginIteration(adaptInfo);
problemIteration->oneIteration(adaptInfo, FULL_ITERATION);
problemIteration->endIteration(adaptInfo);
adaptInfo->setLastProcessedTimestep(adaptInfo->getTimestep());
}
void AdaptInstationary::implicitTimeStrategy()
{
FUNCNAME("AdaptInstationary::implicitTimeStrategy()");
do {
adaptInfo->setTime(adaptInfo->getTime() + adaptInfo->getTimestep());
problemTime->setTime(adaptInfo);
INFO(info,6)("time = %e, try timestep = %e\n",
adaptInfo->getTime(), adaptInfo->getTimestep());
problemIteration->oneIteration(adaptInfo, NO_ADAPTION);
adaptInfo->incTimestepIteration();
if (!fixedTimestep &&
!adaptInfo->timeToleranceReached() &&
adaptInfo->getTimestepIteration() <= adaptInfo->getMaxTimestepIteration() &&
!(adaptInfo->getTimestep() <= adaptInfo->getMinTimestep())) {
adaptInfo->setTime(adaptInfo->getTime() - adaptInfo->getTimestep());
adaptInfo->setTimestep(adaptInfo->getTimestep() * timeDelta1);
continue;
}
adaptInfo->setSpaceIteration(0);
// === Do only space iterations only if the maximum is higher than 0. ===
if (adaptInfo->getMaxSpaceIteration() > 0) {
// === Space iterations. ===
do {
problemIteration->beginIteration(adaptInfo);
if (problemIteration->oneIteration(adaptInfo, FULL_ITERATION)) {
if (!fixedTimestep &&
!adaptInfo->timeToleranceReached() &&
!(adaptInfo->getTimestep() <= adaptInfo->getMinTimestep())) {
adaptInfo->setTime(adaptInfo->getTime() - adaptInfo->getTimestep());
adaptInfo->setTimestep(adaptInfo->getTimestep() * timeDelta2);
problemIteration->endIteration(adaptInfo);
adaptInfo->incSpaceIteration();
break;
}
}
adaptInfo->incSpaceIteration();
problemIteration->endIteration(adaptInfo);
} while (!adaptInfo->spaceToleranceReached() &&
adaptInfo->getSpaceIteration() <= adaptInfo->getMaxSpaceIteration());
} else {
problemIteration->endIteration(adaptInfo);
}
} while(!adaptInfo->timeToleranceReached() &&
!(adaptInfo->getTimestep() <= adaptInfo->getMinTimestep()) &&
adaptInfo->getTimestepIteration() <= adaptInfo->getMaxTimestepIteration());
adaptInfo->setLastProcessedTimestep(adaptInfo->getTimestep());
// After successful iteration/timestep the timestep will be changed according
// adaption rules for next timestep.
// First, check for increase of timestep
if (!fixedTimestep && adaptInfo->timeErrorLow()) {
adaptInfo->setTimestep(adaptInfo->getTimestep() * timeDelta2);
if (dbgMode) {
// print information about timestep increase
}
} else {
if (dbgMode) {
std::cout << "=== ADAPT INFO DEBUG MODE ===\n";
std::cout << " Do not increase timestep: \n";
if (fixedTimestep)
std::cout << " fixedTimestep = true\n";
if (!adaptInfo->timeErrorLow())
adaptInfo->printTimeErrorLowInfo();
}
}
// Second, check for decrease of timestep
if (!fixedTimestep &&
!adaptInfo->timeToleranceReached() &&
!(adaptInfo->getTimestep() <= adaptInfo->getMinTimestep()))
adaptInfo->setTimestep(adaptInfo->getTimestep() * timeDelta1);
}
void AdaptInstationary::simpleAdaptiveTimeStrategy()
{
FUNCNAME("AdaptInstationary::simpleAdaptiveTimeStrategy()");
// 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());
if (dbgMode) {
std::cout << "=== ADAPT INFO DEBUG MODE ===\n";
std::cout << "=== in simpleAdaptiveTimeStrategy() ===\n";
adaptInfo->printTimeErrorLowInfo();
}
// 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);
}
void AdaptInstationary::oneTimestep()
{
FUNCNAME("AdaptInstationary::oneTimestep()");
adaptInfo->setTimestepIteration(0);
switch (strategy) {
case 0:
explicitTimeStrategy();
break;
case 1:
implicitTimeStrategy();
break;
case 2:
simpleAdaptiveTimeStrategy();
break;
default:
ERROR_EXIT("Unknown strategy = %d!\n", strategy);
}
adaptInfo->incTimestepNumber();
}
int AdaptInstationary::adapt()
{
FUNCNAME("AdaptInstationary::adapt()");
int errorCode = 0;
TEST_EXIT(adaptInfo->getTimestep() >= adaptInfo->getMinTimestep())
("timestep < min timestep\n");
TEST_EXIT(adaptInfo->getTimestep() <= adaptInfo->getMaxTimestep())
("timestep > max timestep\n");
TEST_EXIT(adaptInfo->getTimestep() > 0)("timestep <= 0!\n");
#if HAVE_PARALLEL_DOMAIN_AMDIS
MeshDistributor::globalMeshDistributor->initParallelization();
#endif
if (adaptInfo->getTimestepNumber() == 0) {
adaptInfo->setTime(adaptInfo->getStartTime());
initialAdaptInfo->setStartTime(adaptInfo->getStartTime());
initialAdaptInfo->setTime(adaptInfo->getStartTime());
problemTime->setTime(adaptInfo);
// initial adaption
problemTime->solveInitialProblem(initialAdaptInfo);
problemTime->transferInitialSolution(adaptInfo);
}
while (!adaptInfo->reachedEndTime()) {
iterationTimestamp = time(NULL);
problemTime->initTimestep(adaptInfo);
oneTimestep();
problemTime->closeTimestep(adaptInfo);
if (breakWhenStable && (adaptInfo->getSolverIterations() == 0))
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;
}
void AdaptInstationary::initialize(std::string aName)
{
FUNCNAME("AdaptInstationary::initialize()");
strategy = 0;
timeDelta1 = 0.7071;
timeDelta2 = 1.4142;
queueRuntime = -1;
queueSerializationFilename = "__serialized_problem.ser";
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 + "->time adaptivity debug mode", dbgMode);
Parameters::get(aName + "->queue->runtime", queueRuntime);
Parameters::get(aName + "->queue->serialization filename",
queueSerializationFilename);
}
void AdaptInstationary::serialize(std::ostream &out)
{
FUNCNAME("AdaptInstationary::serialize()");
SerUtil::serialize(out, amdisRevisionNumber);
problemIteration->serialize(out);
adaptInfo->serialize(out);
if (problemTime)
problemTime->serialize(out);
}
void AdaptInstationary::deserialize(std::istream &in)
{
FUNCNAME("AdaptInstationary::deserialize()");
if(in.fail())
ERROR_EXIT("File not found for deserialization \n");
problemIteration->deserialize(in);
adaptInfo->deserialize(in);
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.
lastIterationsDuration.push(currentTimestamp - iterationTimestamp);
// The list should not contain more than 5 elements. If so, delete the oldest one.
if (lastIterationsDuration.size() > 5)
lastIterationsDuration.pop();
// Calculate the avarage of the last iterations.
std::queue<int> tmpQueue = lastIterationsDuration;
int avrgLastIterations = 0;
while (!tmpQueue.empty()) {
avrgLastIterations += tmpQueue.front();
tmpQueue.pop();
}
avrgLastIterations /= lastIterationsDuration.size();
// Check if there is enough time for a further iteration.
if (initialTimestamp + queueRuntime - currentTimestamp < avrgLastIterations * 2) {
std::ofstream out(queueSerializationFilename.c_str());
serialize(out);
out.close();
return true;
}
return false;
}
}