Commit 47dc27d6 authored by frey_m's avatar frey_m
Browse files

rewind lines in multi-bunch mode

parent 6af246d7
......@@ -210,14 +210,15 @@ void ParallelCyclotronTracker::bgf_main_collision_test() {
// only used for dumping into stat file
void ParallelCyclotronTracker::dumpAngle(const double& theta,
double& prevAzimuth,
double& azimuth)
double& azimuth,
const short& bunchNr)
{
if ( prevAzimuth < 0.0 ) { // only at first occurrence
double plus = 0.0;
if ( OpalData::getInstance()->inRestartRun() ) {
plus = 360.0 * turnnumber_m;
plus = 360.0 * (turnnumber_m - bunchNr);
}
azimuth_m = theta + plus;
azimuth = theta + plus;
} else {
double dtheta = theta - prevAzimuth;
if ( dtheta < 0 ) {
......@@ -2853,6 +2854,8 @@ std::tuple<double, double, double> ParallelCyclotronTracker::initializeTracking_
*gmsg << "* Restart at integration step " << restartStep0_m
<< " at turn " << turnnumber_m << endl;
initPathLength();
}
setup_m.stepsNextCheck = step_m + setup_m.stepsPerTurn; // Steps to next check for transition
......@@ -3508,6 +3511,14 @@ void ParallelCyclotronTracker::updateAzimuthAndRadius() {
binfo.radius = computeRadius(meanR);
double azimuth = calculateAngle(meanR(0), meanR(1)) * Physics::rad2deg;
dumpAngle(azimuth, binfo.prevAzimuth, binfo.azimuth);
dumpAngle(azimuth, binfo.prevAzimuth, binfo.azimuth, b);
}
}
void ParallelCyclotronTracker::initPathLength() {
if ( isMultiBunch() ) {
// we need to reset the path length of each bunch
itsDataSink->setMultiBunchInitialPathLengh(mbHandler_m.get());
}
}
......@@ -279,10 +279,12 @@ private:
* @param theta computed azimuth [deg]
* @param prevAzimuth previous angle [deg]
* @param azimuth to be updated [deg]
* @param bunchNr in restart mode only --> to compute initial azimuth
*/
void dumpAngle(const double& theta,
double& prevAzimuth,
double& azimuth);
double& azimuth,
const short& bunchNr = 0);
double computeRadius(const Vector_t& meanR) const;
......@@ -517,6 +519,9 @@ private:
void updateTime(const double& dt);
void updateAzimuthAndRadius();
// multi-bunch mode: set the path length of each bunch in case of restart mode
void initPathLength();
};
/**
......
......@@ -39,25 +39,40 @@
#include <queue>
#include <sstream>
DataSink::DataSink() {
DataSink::DataSink()
: isMultiBunch_m(false)
{
this->init();
}
DataSink::DataSink(H5PartWrapper *h5wrapper, bool restart)
DataSink::DataSink(H5PartWrapper *h5wrapper, bool restart, short numBunch)
: isMultiBunch_m(numBunch > 1)
{
if (restart && !Options::enableHDF5) {
throw OpalException("DataSink::DataSink()",
"Can not restart when HDF5 is disabled");
}
this->init(restart, h5wrapper);
this->init(restart, h5wrapper, numBunch);
if ( restart )
rewindLines();
}
DataSink::DataSink(H5PartWrapper *h5wrapper)
: DataSink(h5wrapper, false)
DataSink::DataSink(H5PartWrapper *h5wrapper, short numBunch)
: DataSink(h5wrapper, false, numBunch)
{ }
DataSink::DataSink(const DataSink& ds)
: h5Writer_m(ds.h5Writer_m)
, statWriter_m(ds.statWriter_m)
, sddsWriter_m(ds.sddsWriter_m)
, mbWriter_m(ds.mbWriter_m)
, lossWrCounter_m(ds.lossWrCounter_m)
, StatMarkerTimer_m(ds.StatMarkerTimer_m)
, isMultiBunch_m(ds.isMultiBunch_m)
{ }
......@@ -276,21 +291,6 @@ void DataSink::writeMultiBunchStatistics(PartBunchBase<double, 3> *beam,
/// Start timer.
IpplTimings::startTimer(StatMarkerTimer_m);
std::string fn = OpalData::getInstance()->getInputBasename();
bool restart = OpalData::getInstance()->inRestartRun();
// if new bunch in machine --> generate new writer for it
short bunch = mbWriter_m.size();
while ( bunch < mbhandler_p->getNumBunch() ) {
std::stringstream ss;
ss << fn << "-bunch-"
<< std::setw(4) << std::setfill('0') << bunch << ".smb";
mbWriter_m.push_back(
mbWriter_t(new MultiBunchDump(ss.str(), restart))
);
++bunch;
}
for (short b = 0; b < mbhandler_p->getNumBunch(); ++b) {
bool isOk = mbhandler_p->calcBunchBeamParameters(beam, b);
const MultiBunchHandler::beaminfo_t& binfo = mbhandler_p->getBunchInfo(b);
......@@ -307,30 +307,52 @@ void DataSink::writeMultiBunchStatistics(PartBunchBase<double, 3> *beam,
}
void DataSink::setMultiBunchInitialPathLengh(MultiBunchHandler* mbhandler_p) {
for (short b = 0; b < mbhandler_p->getNumBunch(); ++b) {
MultiBunchHandler::beaminfo_t& binfo = mbhandler_p->getBunchInfo(b);
binfo.pathlength = mbWriter_m[b]->getLastValue("s");
}
}
void DataSink::rewindLines() {
unsigned int linesToRewind = 0;
// use stat file to get position
if ( statWriter_m->exists() ) {
double spos = h5Writer_m->getLastPosition();
double spos = h5Writer_m->getLastPosition();
if (isMultiBunch_m) {
/* first check if multi-bunch restart
*
* first element of vector belongs to first
* injected bunch in machine --> rewind lines
* according to that file --> thus rewind in
* reversed order
*/
for (std::vector<mbWriter_t>::reverse_iterator rit = mbWriter_m.rbegin();
rit != mbWriter_m.rend(); ++rit)
{
linesToRewind = (*rit)->rewindToSpos(spos);
(*rit)->replaceVersionString();
}
} else if ( statWriter_m->exists() ) {
// use stat file to get position
linesToRewind = statWriter_m->rewindToSpos(spos);
statWriter_m->replaceVersionString();
h5Writer_m->close();
}
h5Writer_m->close();
// rewind all others
if ( linesToRewind > 0 ) {
for (size_t i = 0; i < sddsWriter_m.size(); ++i)
for (size_t i = 0; i < sddsWriter_m.size(); ++i) {
sddsWriter_m[i]->rewindLines(linesToRewind);
sddsWriter_m[i]->replaceVersionString();
}
}
}
void DataSink::init(bool restart, H5PartWrapper* h5wrapper) {
void DataSink::init(bool restart, H5PartWrapper* h5wrapper, short numBunch) {
std::string fn = OpalData::getInstance()->getInputBasename();
/* Set file write flags to true. These will be set to false after first
* write operation.
*/
lossWrCounter_m = 0;
StatMarkerTimer_m = IpplTimings::getTimer("Write Stat");
......@@ -360,14 +382,34 @@ void DataSink::init(bool restart, H5PartWrapper* h5wrapper) {
#endif
}
if ( isMultiBunch_m ) {
// generate at least file for first bunch (if numBunch = 1)
initMultiBunchDump(numBunch);
}
if ( Options::enableHDF5 ) {
h5Writer_m = h5Writer_t(new H5Writer(h5wrapper, restart));
}
}
void DataSink::initMultiBunchDump(short numBunch) {
bool restart = OpalData::getInstance()->inRestartRun();
std::string fn = OpalData::getInstance()->getInputBasename();
short bunch = mbWriter_m.size();
while (bunch < numBunch) {
std::string fname = fn + std::string("-bunch-") +
convertToString(bunch, 4) + std::string(".smb");
mbWriter_m.push_back(
mbWriter_t(new MultiBunchDump(fname, restart))
);
++bunch;
}
}
// vi: set et ts=4 sw=4 sts=4:
// Local Variables:
// mode:c
// mode:c++
// c-basic-offset: 4
// indent-tabs-mode:nil
// End:
......@@ -36,10 +36,10 @@ class DataSink {
public:
typedef MultiBunchDump::beaminfo_t beaminfo_t;
typedef StatWriter::losses_t losses_t;
typedef std::unique_ptr<StatWriter> statWriter_t;
typedef std::unique_ptr<SDDSWriter> sddsWriter_t;
typedef std::unique_ptr<H5Writer> h5Writer_t;
typedef std::unique_ptr<MultiBunchDump> mbWriter_t;
typedef std::shared_ptr<StatWriter> statWriter_t;
typedef std::shared_ptr<SDDSWriter> sddsWriter_t;
typedef std::shared_ptr<H5Writer> h5Writer_t;
typedef std::shared_ptr<MultiBunchDump> mbWriter_t;
/** \brief Default constructor.
......@@ -48,8 +48,8 @@ public:
* opposed to a calculation restart).
*/
DataSink();
DataSink(H5PartWrapper *h5wrapper, bool restart);
DataSink(H5PartWrapper *h5wrapper);
DataSink(H5PartWrapper *h5wrapper, bool restart, short numBunch);
DataSink(H5PartWrapper *h5wrapper, short numBunch);
void dumpH5(PartBunchBase<double, 3> *beam, Vector_t FDext[]) const;
......@@ -114,19 +114,27 @@ public:
/** no statWriter_m dump
* @param beam
* @param binfo is the beam info
* @param mbhandler is the multi-bunch handler
*/
void writeMultiBunchStatistics(PartBunchBase<double, 3> *beam,
MultiBunchHandler* mbhandler);
/**
* In restart mode we need to set the correct path length
* of each bunch
* @param mbhandler is the multi-bunch handler
*/
void setMultiBunchInitialPathLengh(MultiBunchHandler* mbhandler_p);
private:
DataSink(const DataSink &) { }
DataSink(const DataSink& ds);
DataSink &operator = (const DataSink &) { return *this; }
void rewindLines();
void init(bool restart = false,
H5PartWrapper* h5wrapper = nullptr);
H5PartWrapper* h5wrapper = nullptr,
short numBunch = 1);
h5Writer_t h5Writer_m;
......@@ -134,20 +142,24 @@ private:
std::vector<sddsWriter_t> sddsWriter_m;
std::vector<mbWriter_t> mbWriter_m;
static std::string convertToString(int number);
static std::string convertToString(int number, int setw = 5);
/// needed to create index for vtk file
unsigned int lossWrCounter_m;
/// Timer to track statistics write time.
IpplTimings::TimerRef StatMarkerTimer_m;
const bool isMultiBunch_m;
void initMultiBunchDump(short numBunch);
};
inline
std::string DataSink::convertToString(int number) {
std::string DataSink::convertToString(int number, int setw) {
std::stringstream ss;
ss << std::setw(5) << std::setfill('0') << number;
ss << std::setw(setw) << std::setfill('0') << number;
return ss.str();
}
......@@ -156,7 +168,7 @@ std::string DataSink::convertToString(int number) {
// vi: set et ts=4 sw=4 sts=4:
// Local Variables:
// mode:c
// mode:c++
// c-basic-offset: 4
// indent-tabs-mode:nil
// End:
......@@ -17,8 +17,22 @@ public:
void write(PartBunchBase<double, 3>* beam, const beaminfo_t& binfo);
/** \brief
* delete the last 'numberOfLines' lines of the statistics file
*/
unsigned int rewindToSpos(double maxSpos);
private:
bool isFirst_m;
};
inline
unsigned int MultiBunchDump::rewindToSpos(double maxSPos) {
if (Ippl::myNode() == 0) {
return Util::rewindLinesSDDS(this->fname_m, maxSPos);
}
return 0;
}
#endif
......@@ -100,6 +100,18 @@ void SDDSWriter::replaceVersionString() {
}
double SDDSWriter::getLastValue(const std::string& column) {
if (Ippl::myNode() != 0)
return 0.0;
SDDS::SDDSParser parser(fname_m);
parser.run();
double val = 0.0;
parser.getValue(-1, column, val);
return val;
}
void SDDSWriter::open() {
if ( Ippl::myNode() != 0 || os_m.is_open() )
return;
......
......@@ -50,6 +50,7 @@ public:
void replaceVersionString();
double getLastValue(const std::string& column);
bool exists() const;
......
......@@ -322,13 +322,13 @@ void TrackRun::setupSliceTracker() {
if(!opal->inRestartRun()) {
if(!opal->hasDataSinkAllocated()) {
opal->setDataSink(new DataSink(phaseSpaceSink_m));
opal->setDataSink(new DataSink(phaseSpaceSink_m, false, 1));
} else {
ds = opal->getDataSink();
ds->changeH5Wrapper(phaseSpaceSink_m);
}
} else {
opal->setDataSink(new DataSink(phaseSpaceSink_m, -1));
opal->setDataSink(new DataSink(phaseSpaceSink_m, true, 1));
}
ds = opal->getDataSink();
......@@ -443,13 +443,13 @@ void TrackRun::setupThickTracker()
if(!opal->inRestartRun()) {
if(!opal->hasDataSinkAllocated()) {
opal->setDataSink(new DataSink(phaseSpaceSink_m));
opal->setDataSink(new DataSink(phaseSpaceSink_m, false, 1));
} else {
ds = opal->getDataSink();
ds->changeH5Wrapper(phaseSpaceSink_m);
}
} else {
opal->setDataSink(new DataSink(phaseSpaceSink_m, -1));//opal->getRestartStep()));
opal->setDataSink(new DataSink(phaseSpaceSink_m, true, 1));
}
ds = opal->getDataSink();
......@@ -566,13 +566,13 @@ void TrackRun::setupTTracker(){
if(!opal->inRestartRun()) {
if(!opal->hasDataSinkAllocated()) {
opal->setDataSink(new DataSink(phaseSpaceSink_m));
opal->setDataSink(new DataSink(phaseSpaceSink_m, false, 1));
} else {
ds = opal->getDataSink();
ds->changeH5Wrapper(phaseSpaceSink_m);
}
} else {
opal->setDataSink(new DataSink(phaseSpaceSink_m, -1));//opal->getRestartStep()));
opal->setDataSink(new DataSink(phaseSpaceSink_m, true, 1));
}
ds = opal->getDataSink();
......@@ -739,14 +739,14 @@ void TrackRun::setupCyclotronTracker(){
if(!opal->inRestartRun())
if(!opal->hasDataSinkAllocated()) {
ds = new DataSink(phaseSpaceSink_m);
ds = new DataSink(phaseSpaceSink_m, false, specifiedNumBunch);
opal->setDataSink(ds);
} else {
ds = opal->getDataSink();
ds->changeH5Wrapper(phaseSpaceSink_m);
}
else {
ds = new DataSink(phaseSpaceSink_m, -1);
ds = new DataSink(phaseSpaceSink_m, true, specifiedNumBunch);
opal->setDataSink(ds);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment