ENH: Time: secondary write controls, signal handling

This commit is contained in:
mattijs
2011-10-05 17:31:12 +01:00
parent 2088364c43
commit 99c860d2e2
10 changed files with 664 additions and 13 deletions

View File

@ -2,6 +2,8 @@ signals/sigFpe.C
signals/sigSegv.C
signals/sigInt.C
signals/sigQuit.C
signals/sigStopAtWriteNow.C
signals/sigWriteNow.C
regExp.C
timer.C
fileStat.C

View File

@ -0,0 +1,140 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "sigStopAtWriteNow.H"
#include "error.H"
#include "JobInfo.H"
#include "IOstreams.H"
#include "Time.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
// Signal number to catch
int Foam::sigStopAtWriteNow::signal_
(
debug::optimisationSwitch("stopAtWriteNowSignal", -1)
);
static Foam::Time const* runTimePtr_ = NULL;
struct sigaction Foam::sigStopAtWriteNow::oldAction_;
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::sigStopAtWriteNow::sigHandler(int)
{
// Reset old handling
if (sigaction(signal_, &oldAction_, NULL) < 0)
{
FatalErrorIn
(
"Foam::sigStopAtWriteNow::sigHandler(int)"
) << "Cannot reset " << signal_ << " trapping"
<< abort(FatalError);
}
// Update jobInfo file
jobInfo.signalEnd();
Info<< "sigStopAtWriteNow :"
<< " setting up write and stop at end of the next iteration"
<< nl << endl;
runTimePtr_->stopAt(Time::saWriteNow);
//// Throw signal (to old handler)
//raise(signal_);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::sigStopAtWriteNow::sigStopAtWriteNow(){}
Foam::sigStopAtWriteNow::sigStopAtWriteNow
(
const bool verbose,
const Time& runTime
)
{
if (signal_ > 0)
{
// Store runTime
runTimePtr_ = &runTime;
struct sigaction newAction;
newAction.sa_handler = sigHandler;
newAction.sa_flags = SA_NODEFER;
sigemptyset(&newAction.sa_mask);
if (sigaction(signal_, &newAction, &oldAction_) < 0)
{
FatalErrorIn
(
"Foam::sigStopAtWriteNow::sigStopAtWriteNow"
"(const bool, const Time&)"
) << "Cannot set " << signal_ << " trapping"
<< abort(FatalError);
}
if (verbose)
{
Info<< "sigStopAtWriteNow :"
<< " Enabling writing and stopping upon signal " << signal_
<< endl;
}
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::sigStopAtWriteNow::~sigStopAtWriteNow()
{
// Reset old handling
if (signal_ > 0)
{
if (sigaction(signal_, &oldAction_, NULL) < 0)
{
FatalErrorIn
(
"Foam::sigStopAtWriteNow::~sigStopAtWriteNow()"
) << "Cannot reset " << signal_ << " trapping"
<< abort(FatalError);
}
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::sigStopAtWriteNow::active() const
{
return signal_ > 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,99 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::sigStopAtWriteNow
Description
Signal handler for interupt defined by
OptimisationSwitches::stopAtWriteNowSignal
Write and stop the job.
SourceFiles
sigStopAtWriteNow.C
\*---------------------------------------------------------------------------*/
#ifndef sigStopAtWriteNow_H
#define sigStopAtWriteNow_H
#include <signal.h>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class Time;
/*---------------------------------------------------------------------------*\
Class sigStopAtWriteNow Declaration
\*---------------------------------------------------------------------------*/
class sigStopAtWriteNow
{
// Private data
//- number of signal to use
static int signal_;
//- Saved old signal trapping setting
static struct sigaction oldAction_;
// Private Member Functions
static void sigHandler(int);
public:
// Constructors
//- Construct null
sigStopAtWriteNow();
//- Construct from components
sigStopAtWriteNow(const bool verbose, const Time& runTime);
//- Destructor
~sigStopAtWriteNow();
// Member functions
//- Is active?
bool active() const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,122 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "sigWriteNow.H"
#include "error.H"
#include "JobInfo.H"
#include "IOstreams.H"
#include "Time.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
// Signal number to catch
int Foam::sigWriteNow::signal_
(
debug::optimisationSwitch("writeNowSignal", -1)
);
static Foam::Time* runTimePtr_ = NULL;
struct sigaction Foam::sigWriteNow::oldAction_;
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::sigWriteNow::sigHandler(int)
{
Info<< "sigWriteNow :"
<< " setting up write at end of the next iteration" << nl << endl;
runTimePtr_->writeOnce();
//// Throw signal (to old handler)
//raise(signal_);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::sigWriteNow::sigWriteNow()
{}
Foam::sigWriteNow::sigWriteNow(const bool verbose, Time& runTime)
{
if (signal_ >= 0)
{
// Store runTime
runTimePtr_ = &runTime;
struct sigaction newAction;
newAction.sa_handler = sigHandler;
newAction.sa_flags = SA_NODEFER;
sigemptyset(&newAction.sa_mask);
if (sigaction(signal_, &newAction, &oldAction_) < 0)
{
FatalErrorIn
(
"Foam::sigWriteNow::sigWriteNow(const bool, const Time&)"
) << "Cannot set " << signal_ << " trapping"
<< abort(FatalError);
}
if (verbose)
{
Info<< "sigWriteNow :"
<< " Enabling writing upon signal " << signal_
<< endl;
}
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::sigWriteNow::~sigWriteNow()
{
// Reset old handling
if (signal_ > 0)
{
if (sigaction(signal_, &oldAction_, NULL) < 0)
{
FatalErrorIn
(
"Foam::sigWriteNow::~sigWriteNow()"
) << "Cannot reset " << signal_ << " trapping"
<< abort(FatalError);
}
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::sigWriteNow::active() const
{
return signal_ > 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,99 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::sigWriteNow
Description
Signal handler for interupt defined by OptimisationSwitches::writeNowSignal
Write once and continue.
SourceFiles
sigWriteNow.C
\*---------------------------------------------------------------------------*/
#ifndef sigWriteNow_H
#define sigWriteNow_H
#include <signal.h>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class Time;
/*---------------------------------------------------------------------------*\
Class sigWriteNow Declaration
\*---------------------------------------------------------------------------*/
class sigWriteNow
{
// Private data
//- number of signal to use
static int signal_;
//- Saved old signal trapping setting
static struct sigaction oldAction_;
// Private Member Functions
static void sigHandler(int);
public:
// Constructors
//- Construct null
sigWriteNow();
//- Construct from components
sigWriteNow(const bool verbose, Time& runTime);
//- Destructor
~sigWriteNow();
// Member functions
//- Is active?
bool active() const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -81,10 +81,17 @@ void Foam::Time::adjustDeltaT()
{
if (writeControl_ == wcAdjustableRunTime)
{
scalar interval = writeInterval_;
if (secondaryWriteControl_ == wcAdjustableRunTime)
{
interval = min(interval, secondaryWriteInterval_);
}
scalar timeToNextWrite = max
(
0.0,
(outputTimeIndex_ + 1)*writeInterval_ - (value() - startTime_)
(outputTimeIndex_ + 1)*interval - (value() - startTime_)
);
scalar nSteps = timeToNextWrite/deltaT_ - SMALL;
@ -252,8 +259,13 @@ Foam::Time::Time
stopAt_(saEndTime),
writeControl_(wcTimeStep),
writeInterval_(GREAT),
secondaryWriteControl_(wcTimeStep),
secondaryWriteInterval_(labelMax),
purgeWrite_(0),
writeOnce_(false),
subCycling_(false),
sigWriteNow_(true, *this),
sigStopAtWriteNow_(true, *this),
writeFormat_(IOstream::ASCII),
writeVersion_(IOstream::currentVersion),
@ -339,8 +351,13 @@ Foam::Time::Time
stopAt_(saEndTime),
writeControl_(wcTimeStep),
writeInterval_(GREAT),
secondaryWriteControl_(wcTimeStep),
secondaryWriteInterval_(labelMax),
purgeWrite_(0),
writeOnce_(false),
subCycling_(false),
sigWriteNow_(true, *this),
sigStopAtWriteNow_(true, *this),
writeFormat_(IOstream::ASCII),
writeVersion_(IOstream::currentVersion),
@ -429,8 +446,13 @@ Foam::Time::Time
stopAt_(saEndTime),
writeControl_(wcTimeStep),
writeInterval_(GREAT),
secondaryWriteControl_(wcTimeStep),
secondaryWriteInterval_(labelMax),
purgeWrite_(0),
writeOnce_(false),
subCycling_(false),
sigWriteNow_(true, *this),
sigStopAtWriteNow_(true, *this),
writeFormat_(IOstream::ASCII),
writeVersion_(IOstream::currentVersion),
@ -521,7 +543,10 @@ Foam::Time::Time
stopAt_(saEndTime),
writeControl_(wcTimeStep),
writeInterval_(GREAT),
secondaryWriteControl_(wcTimeStep),
secondaryWriteInterval_(labelMax),
purgeWrite_(0),
writeOnce_(false),
subCycling_(false),
writeFormat_(IOstream::ASCII),
@ -944,6 +969,35 @@ Foam::Time& Foam::Time::operator++()
if (!subCycling_)
{
if (sigStopAtWriteNow_.active() || sigWriteNow_.active())
{
// A signal might have been sent on one processor only
// Reduce so all decide the same.
label flag = 0;
if (sigStopAtWriteNow_.active() && stopAt_ == saWriteNow)
{
flag += 1;
}
if (sigWriteNow_.active() && writeOnce_)
{
flag += 2;
}
reduce(flag, maxOp<label>());
if (flag & 1)
{
stopAt_ = saWriteNow;
}
if (flag & 2)
{
writeOnce_ = true;
}
}
outputTime_ = false;
switch (writeControl_)
{
case wcTimeStep:
@ -964,10 +1018,6 @@ Foam::Time& Foam::Time::operator++()
outputTime_ = true;
outputTimeIndex_ = outputIndex;
}
else
{
outputTime_ = false;
}
}
break;
@ -983,10 +1033,6 @@ Foam::Time& Foam::Time::operator++()
outputTime_ = true;
outputTimeIndex_ = outputIndex;
}
else
{
outputTime_ = false;
}
}
break;
@ -1002,14 +1048,69 @@ Foam::Time& Foam::Time::operator++()
outputTime_ = true;
outputTimeIndex_ = outputIndex;
}
else
}
break;
}
// Adapt for secondaryWrite controls
switch (secondaryWriteControl_)
{
case wcTimeStep:
outputTime_ =
outputTime_
|| !(timeIndex_ % label(secondaryWriteInterval_));
break;
case wcRunTime:
case wcAdjustableRunTime:
{
label outputIndex = label
(
((value() - startTime_) + 0.5*deltaT_)
/ secondaryWriteInterval_
);
if (outputIndex > outputTimeIndex_)
{
outputTime_ = false;
outputTime_ = true;
outputTimeIndex_ = outputIndex;
}
}
break;
case wcCpuTime:
{
label outputIndex = label
(
returnReduce(elapsedCpuTime(), maxOp<double>())
/ secondaryWriteInterval_
);
if (outputIndex > outputTimeIndex_)
{
outputTime_ = true;
outputTimeIndex_ = outputIndex;
}
}
break;
case wcClockTime:
{
label outputIndex = label
(
returnReduce(label(elapsedClockTime()), maxOp<label>())
/ secondaryWriteInterval_
);
if (outputIndex > outputTimeIndex_)
{
outputTime_ = true;
outputTimeIndex_ = outputIndex;
}
}
break;
}
// see if endTime needs adjustment to stop at the next run()/end() check
if (!end())
{
@ -1027,6 +1128,14 @@ Foam::Time& Foam::Time::operator++()
endTime_ = value();
}
}
// Override outputTime if one-shot writing
if (writeOnce_)
{
outputTime_ = true;
writeOnce_ = false;
}
}
return *this;

View File

@ -52,6 +52,8 @@ SourceFiles
#include "dlLibraryTable.H"
#include "functionObjectList.H"
#include "fileMonitor.H"
#include "sigWriteNow.H"
#include "sigStopAtWriteNow.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -130,15 +132,35 @@ protected:
scalar writeInterval_;
// Additional writing
writeControls secondaryWriteControl_;
scalar secondaryWriteInterval_;
label purgeWrite_;
mutable FIFOStack<word> previousOutputTimes_;
// One-shot writing
bool writeOnce_;
//- Is the time currently being sub-cycled?
bool subCycling_;
//- If time is being sub-cycled this is the previous TimeState
autoPtr<TimeState> prevTimeState_;
// Signal handlers for secondary writing
//- Enable one-shot writing upon signal
sigWriteNow sigWriteNow_;
//- Enable write and clean exit upon signal
sigStopAtWriteNow sigStopAtWriteNow_;
//- Time directory name format
static fmtflags format_;
@ -357,12 +379,16 @@ public:
IOstream::compressionType
) const;
//- Write the objects now and continue the run
//- Write the objects now (not at end of iteration) and continue
// the run
bool writeNow();
//- Write the objects now and end the run
//- Write the objects now (not at end of iteration) and end the run
bool writeAndEnd();
//- Write the objects once (one shot) and continue the run
void writeOnce();
// Access

View File

@ -58,6 +58,45 @@ void Foam::Time::readDict()
controlDict_.lookup("writeFrequency") >> writeInterval_;
}
// Additional writing
if (controlDict_.found("secondaryWriteControl"))
{
secondaryWriteControl_ = writeControlNames_.read
(
controlDict_.lookup("secondaryWriteControl")
);
if
(
controlDict_.readIfPresent
(
"secondaryWriteInterval",
secondaryWriteInterval_
)
)
{
if
(
secondaryWriteControl_
== wcTimeStep && label(secondaryWriteInterval_) < 1
)
{
FatalIOErrorIn("Time::readDict()", controlDict_)
<< "secondaryWriteInterval < 1"
<< " for secondaryWriteControl timeStep"
<< exit(FatalIOError);
}
}
else
{
controlDict_.lookup("secondaryWriteFrequency")
>> secondaryWriteInterval_;
}
}
if (oldWriteInterval != writeInterval_)
{
switch (writeControl_)
@ -310,4 +349,10 @@ bool Foam::Time::writeAndEnd()
}
void Foam::Time::writeOnce()
{
writeOnce_ = true;
}
// ************************************************************************* //