Commit f5edc17e authored by kraus's avatar kraus
Browse files

Implements tracking bunch back in time; replace queues for time step size, num...

Implements tracking bunch back in time; replace queues for time step size, num time steps and zstop with class that stores all these informations in a list; let the SOURCE element absorbe all particles in case of back tracking; disables automatic centering of FROMFILE distributions;
parent e1d32631
......@@ -10,9 +10,10 @@ set (_SRCS
MPSplitIntegrator.cpp
MultiBunchHandler.cpp
OrbitThreader.cpp
ParallelTTracker.cpp
ParallelCyclotronTracker.cpp
ParallelSliceTracker.cpp
ParallelTTracker.cpp
StepSizeConfig.cpp
ThickMapper.cpp
ThickTracker.cpp
TransportMapper.cpp
......@@ -51,6 +52,7 @@ set (HDRS
ParallelCyclotronTracker.h
ParallelSliceTracker.h
ParallelTTracker.h
StepSizeConfig.h
ThickMapper.h
ThickTracker.h
TransportMapper.h
......@@ -68,4 +70,4 @@ set (HDRS
bet/math/svdfit.h
)
install (FILES ${HDRS} DESTINATION "${CMAKE_INSTALL_PREFIX}/include/Algorithms")
install (FILES ${HDRS} DESTINATION "${CMAKE_INSTALL_PREFIX}/include/Algorithms")
\ No newline at end of file
......@@ -51,7 +51,7 @@ void IndexMap::print(std::ostream &out) const {
}
IndexMap::value_t IndexMap::query(key_t::first_type s, key_t::second_type ds) {
const double lowerLimit = (ds < s? s - ds: 0);
const double lowerLimit = s - ds;//(ds < s? s - ds: 0);
const double upperLimit = std::min(totalPathLength_m, s + ds);
value_t elementSet;
......@@ -88,7 +88,11 @@ IndexMap::value_t IndexMap::query(key_t::first_type s, key_t::second_type ds) {
}
void IndexMap::add(key_t::first_type initialS, key_t::second_type finalS, const value_t &val) {
if (initialS > finalS) {
std::swap(initialS, finalS);
}
key_t key(initialS, finalS * oneMinusEpsilon_m);
mapRange2Element_m.insert(std::pair<key_t, value_t>(key, val));
totalPathLength_m = (*mapRange2Element_m.rbegin()).first.second;
......
......@@ -72,12 +72,12 @@ OrbitThreader::OrbitThreader(const PartData &ref,
logger_m.open(fileName, std::ios_base::app);
}
loggingFrequency_m = std::max(1.0, floor(1e-11 / dt_m + 0.5));
loggingFrequency_m = std::max(1.0, floor(1e-11 / std::abs(dt_m) + 0.5));
} else {
loggingFrequency_m = std::numeric_limits<size_t>::max();
}
dZ_m = std::min(pathLength_m, std::max(0.0, maxDiffZBunch));
distTrackBack_m = std::min(pathLength_m, std::max(0.0, maxDiffZBunch));
}
void OrbitThreader::execute() {
......@@ -110,7 +110,9 @@ void OrbitThreader::execute() {
registerElement(elementSet, initialS, initialR, initialP);
if (errorFlag_m == HITMATERIAL) {
pathLength_m += 1.0;
// Shouldn't be reached because reference particle
// isn't stopped by collimators
pathLength_m += std::copysign(1.0, dt_m);
}
imap_m.add(initialS, pathLength_m, elementSet);
......@@ -144,7 +146,6 @@ void OrbitThreader::integrate(const IndexMap::value_t &activeSet, size_t maxStep
static size_t step = 0;
CoordinateSystemTrafo labToBeamline = itsOpalBeamline_m.getCSTrafoLab2Local();
const double oldPathLength = pathLength_m;
double stepLength;
Vector_t nextR;
do {
errorFlag_m = EVERYTHINGFINE;
......@@ -211,15 +212,13 @@ void OrbitThreader::integrate(const IndexMap::value_t &activeSet, size_t maxStep
nextR *= Physics::c * dt_m;
if ((activeSet.size() == 0 && std::abs(pathLength_m - oldPathLength) > maxDrift) ||
(activeSet.size() > 0 && pathLength_m > zstop_m)) {
(activeSet.size() > 0 && dt_m * pathLength_m > dt_m * zstop_m) ||
(pathLength_m < 0.0 && dt_m < 0.0)) {
errorFlag_m = EOL;
return;
}
stepLength = std::abs(dt_m) * euclidean_norm(p_m) / sqrt(dot(p_m, p_m) + 1) * Physics::c;
} while ((dt_m > 0.0 ||
euclidean_norm(labToBeamline.transformTo(r_m)) > stepLength) &&
(activeSet == itsOpalBeamline_m.getElements(nextR)));
} while (activeSet == itsOpalBeamline_m.getElements(nextR));
}
bool OrbitThreader::containsCavity(const IndexMap::value_t &activeSet) {
......@@ -286,8 +285,8 @@ void OrbitThreader::trackBack(double maxDrift) {
integrator_m.push(nextR, p_m, dt_m);
nextR *= Physics::c * dt_m;
maxDrift = std::min(maxDrift, dZ_m);
while (initialPathLength - pathLength_m < dZ_m) {
maxDrift = std::min(maxDrift, distTrackBack_m);
while (std::abs(initialPathLength - pathLength_m) < distTrackBack_m) {
auto elementSet = itsOpalBeamline_m.getElements(nextR);
integrate(elementSet, 1000, maxDrift);
......@@ -453,7 +452,7 @@ double OrbitThreader::computeMaximalImplicitDrift() {
}
}
maxDrift = std::min(maxIntegSteps_m * dt_m * Physics::c, maxDrift);
maxDrift = std::min(maxIntegSteps_m * std::abs(dt_m) * Physics::c, maxDrift);
return maxDrift;
}
\ No newline at end of file
......@@ -34,13 +34,23 @@ public:
IndexMap::value_t getTouchingElements(const std::pair<double, double> &range);
private:
/// position of reference particle in lab coordinates
Vector_t r_m;
/// momentum of reference particle
Vector_t p_m;
/// position of reference particle in path length
double pathLength_m;
double dZ_m;
/// distance to track back before tracking forward
/// (length of bunch but not beyond cathode)
double distTrackBack_m;
/// the simulated time
double time_m;
/// the time step
double dt_m;
/// the number of time steps to track
const size_t maxIntegSteps_m;
/// final position in path length
const double zstop_m;
OpalBeamline &itsOpalBeamline_m;
......
......@@ -64,10 +64,7 @@ ParallelTTracker::ParallelTTracker(const Beamline &beamline,
wakeFunction_m(NULL),
pathLength_m(0.0),
zstart_m(0.0),
zStop_m(),
dtCurrentTrack_m(0.0),
dtAllTracks_m(),
localTrackSteps_m(),
minStepforReBin_m(-1),
minBinEmitted_m(std::numeric_limits<size_t>::max()),
repartFreq_m(-1),
......@@ -120,16 +117,13 @@ ParallelTTracker::ParallelTTracker(const Beamline &beamline,
particleMatterStatus_m(false),
totalParticlesInSimulation_m(0)
{
for (std::vector<unsigned long long>::const_iterator it = maxSteps.begin(); it != maxSteps.end(); ++ it) {
localTrackSteps_m.push(*it);
}
for (std::vector<double>::const_iterator it = dt.begin(); it != dt.end(); ++ it) {
dtAllTracks_m.push(*it);
}
for (std::vector<double>::const_iterator it = zstop.begin(); it != zstop.end(); ++ it) {
zStop_m.push(*it);
for (unsigned int i = 0; i < zstop.size(); ++ i) {
stepSizes_m.push_back(dt[i], zstop[i], maxSteps[i]);
}
stepSizes_m.sortAscendingZStop();
stepSizes_m.resetIterator();
#ifdef OPAL_DKS
if (IpplInfo::DKSEnabled)
setupDKS();
......@@ -202,6 +196,8 @@ void ParallelTTracker::execute() {
const double globalTimeShift = itsBunch_m->weHaveEnergyBins()? OpalData::getInstance()->getGlobalPhaseShift(): 0.0;
OpalData::getInstance()->setGlobalPhaseShift(0.0);
// the time step needs to be positive in the setup
itsBunch_m->setdT(std::abs(itsBunch_m->getdT()));
dtCurrentTrack_m = itsBunch_m->getdT();
evenlyDistributeParticles();
......@@ -212,20 +208,8 @@ void ParallelTTracker::execute() {
prepareSections();
std::queue<double> timeStepSizes(dtAllTracks_m);
std::queue<unsigned long long> numSteps(localTrackSteps_m);
double minTimeStep = timeStepSizes.front();
unsigned long long totalNumSteps = 0;
while (timeStepSizes.size() > 0) {
if (minTimeStep > timeStepSizes.front()) {
totalNumSteps = std::ceil(totalNumSteps * minTimeStep / timeStepSizes.front());
minTimeStep = timeStepSizes.front();
}
totalNumSteps += std::ceil(numSteps.front() * timeStepSizes.front() / minTimeStep);
numSteps.pop();
timeStepSizes.pop();
}
double minTimeStep = stepSizes_m.getMinTimeStep();
unsigned long long totalNumSteps = stepSizes_m.getNumStepsFinestResolution();
itsOpalBeamline_m.activateElements();
......@@ -259,19 +243,29 @@ void ParallelTTracker::execute() {
}
}
stepSizes_m.advanceToPos(zstart_m);
if (back_track) {
itsBunch_m->setdT(-std::abs(itsBunch_m->getdT()));
stepSizes_m.reverseDirection();
if (pathLength_m < stepSizes_m.getZStop()) {
++ stepSizes_m;
}
}
Vector_t rmin(0.0), rmax(0.0);
if (itsBunch_m->getTotalNum() > 0) {
itsBunch_m->get_bounds(rmin, rmax);
}
OrbitThreader oth(itsReference,
itsBunch_m->RefPartR_m,
itsBunch_m->RefPartP_m,
pathLength_m,
-rmin(2),
itsBunch_m->getT(),
minTimeStep,
(back_track? -minTimeStep: minTimeStep),
totalNumSteps,
zStop_m.back() + 2 * rmax(2),
stepSizes_m.getFinalZStop() + 2 * rmax(2),
itsOpalBeamline_m);
oth.execute();
......@@ -298,7 +292,7 @@ void ParallelTTracker::execute() {
*gmsg << level1
<< "Executing ParallelTTracker, initial dt= " << Util::getTimeString(itsBunch_m->getdT()) << ";\n"
<< "max integration steps " << getMaxSteps(localTrackSteps_m) << ", next step= " << step << endl;
<< "max integration steps " << stepSizes_m.getMaxSteps() << ", next step= " << step << endl;
setOptionalVariables();
......@@ -307,17 +301,20 @@ void ParallelTTracker::execute() {
allocateDeviceMemory();
#endif
// loggingFrequency_m = floor(1e-11/itsBunch_m->getdT() + 0.5);
globalEOL_m = false;
wakeStatus_m = false;
deletedParticles_m = false;
OpalData::getInstance()->setInPrepState(false);
while (localTrackSteps_m.size() > 0) {
localTrackSteps_m.front() += step;
dtCurrentTrack_m = dtAllTracks_m.front();
changeDT();
for (; step < localTrackSteps_m.front(); ++step) {
while (!stepSizes_m.reachedEnd()) {
unsigned long long trackSteps = stepSizes_m.getNumSteps() + step;
dtCurrentTrack_m = stepSizes_m.getdT();
changeDT(back_track);
for (; step < trackSteps; ++ step) {
Vector_t rmin(0.0), rmax(0.0);
if (itsBunch_m->getTotalNum() > 0) {
itsBunch_m->get_bounds(rmin, rmax);
}
timeIntegration1(pusher);
......@@ -326,9 +323,9 @@ void ParallelTTracker::execute() {
computeSpaceChargeFields(step);
selectDT();
selectDT(back_track);
emitParticles(step);
selectDT();
selectDT(back_track);
computeExternalFields(oth);
......@@ -336,7 +333,8 @@ void ParallelTTracker::execute() {
itsBunch_m->incrementT();
if (itsBunch_m->getT() > 0.0) {
if (itsBunch_m->getT() > 0.0 ||
itsBunch_m->getdT() < 0.0) {
updateReference(pusher);
}
......@@ -344,7 +342,6 @@ void ParallelTTracker::execute() {
evenlyDistributeParticles();
deletedParticles_m = false;
}
itsBunch_m->set_sPos(pathLength_m);
if (hasEndOfLineReached()) break;
......@@ -356,17 +353,16 @@ void ParallelTTracker::execute() {
itsBunch_m->incTrackSteps();
double beta = euclidean_norm(itsBunch_m->RefPartP_m / Util::getGamma(itsBunch_m->RefPartP_m));
double driftPerTimeStep = itsBunch_m->getdT() * Physics::c * beta;
if (std::abs(zStop_m.front() - pathLength_m) < 0.5 * driftPerTimeStep)
localTrackSteps_m.front() = step;
double driftPerTimeStep = std::abs(itsBunch_m->getdT()) * Physics::c * beta;
if (std::abs(stepSizes_m.getZStop() - pathLength_m) < 0.5 * driftPerTimeStep) {
break;
}
}
if (globalEOL_m)
break;
dtAllTracks_m.pop();
localTrackSteps_m.pop();
zStop_m.pop();
++ stepSizes_m;
}
itsBunch_m->set_sPos(pathLength_m);
......@@ -465,7 +461,7 @@ void ParallelTTracker::timeIntegration2(BorisPusher & pusher) {
IpplTimings::stopTimer(timeIntegrationTimer2_m);
}
void ParallelTTracker::selectDT() {
void ParallelTTracker::selectDT(bool backTrack) {
if (itsBunch_m->getIfBeamEmitting()) {
double dt = itsBunch_m->getEmissionDeltaT();
......@@ -474,10 +470,13 @@ void ParallelTTracker::selectDT() {
double dt = dtCurrentTrack_m;
itsBunch_m->setdT(dt);
}
if (backTrack) {
itsBunch_m->setdT(-std::abs(itsBunch_m->getdT()));
}
}
void ParallelTTracker::changeDT() {
selectDT();
void ParallelTTracker::changeDT(bool backTrack) {
selectDT(backTrack);
const unsigned int localNum = itsBunch_m->getLocalNum();
for (unsigned int i = 0; i < localNum; ++ i) {
itsBunch_m->dt[i] = itsBunch_m->getdT();
......@@ -645,7 +644,7 @@ void ParallelTTracker::computeExternalFields(OrbitThreader &oth) {
if (ne > 0) {
msg << level1 << "* Deleted " << ne << " particles, "
<< "remaining " << itsBunch_m->getTotalNum() << " particles" << endl;
<< "remaining " << totalParticlesInSimulation_m << " particles" << endl;
}
}
......@@ -1054,7 +1053,7 @@ void ParallelTTracker::writePhaseSpace(const long long step, bool psDump, bool s
if (psDump && (itsBunch_m->getTotalNum() > 0)) {
// Write fields to .h5 file.
const size_t localNum = itsBunch_m->getLocalNum();
double distToLastStop = zStop_m.back() - pathLength_m;
double distToLastStop = stepSizes_m.getFinalZStop() - pathLength_m;
Vector_t beta = itsBunch_m->RefPartP_m / Util::getGamma(itsBunch_m->RefPartP_m);
Vector_t driftPerTimeStep = itsBunch_m->getdT() * Physics::c * itsBunch_m->toLabTrafo_m.rotateFrom(beta);
bool driftToCorrectPosition = std::abs(distToLastStop) < 0.5 * euclidean_norm(driftPerTimeStep);
......@@ -1080,7 +1079,7 @@ void ParallelTTracker::writePhaseSpace(const long long step, bool psDump, bool s
Quaternion(1.0, 0.0, 0.0, 0.0));
itsBunch_m->toLabTrafo_m = itsBunch_m->toLabTrafo_m * update.inverted();
itsBunch_m->set_sPos(zStop_m.back());
itsBunch_m->set_sPos(stepSizes_m.getFinalZStop());
itsBunch_m->calcBeamParameters();
}
......@@ -1111,7 +1110,9 @@ void ParallelTTracker::updateReference(const BorisPusher &pusher) {
}
void ParallelTTracker::updateReferenceParticle(const BorisPusher &pusher) {
const double dt = std::min(itsBunch_m->getT(), itsBunch_m->getdT());
const double direction = back_track? -1: 1;
const double dt = direction * std::min(itsBunch_m->getT(),
direction * itsBunch_m->getdT());
const double scaleFactor = Physics::c * dt;
Vector_t Ef(0.0), Bf(0.0);
......@@ -1162,10 +1163,9 @@ void ParallelTTracker::transformBunch(const CoordinateSystemTrafo &trafo) {
void ParallelTTracker::updateRefToLabCSTrafo() {
Vector_t R = itsBunch_m->toLabTrafo_m.transformFrom(itsBunch_m->RefPartR_m);
Vector_t P = itsBunch_m->toLabTrafo_m.rotateFrom(itsBunch_m->RefPartP_m);
pathLength_m += euclidean_norm(R);
pathLength_m += std::copysign(1, itsBunch_m->getdT()) * euclidean_norm(R);
CoordinateSystemTrafo update(R, getQuaternion(P, Vector_t(0, 0, 1)));
......@@ -1174,15 +1174,40 @@ void ParallelTTracker::updateRefToLabCSTrafo() {
itsBunch_m->toLabTrafo_m = itsBunch_m->toLabTrafo_m * update.inverted();
}
void ParallelTTracker::applyFractionalStep(const BorisPusher &pusher, double tau) {
double t = itsBunch_m->getT();
t += tau;
itsBunch_m->setT(t);
// the push method below pushes for half a time step. Hence the ref particle
// should be pushed for 2 * tau
itsBunch_m->RefPartR_m /= (Physics::c * 2 * tau);
pusher.push(itsBunch_m->RefPartR_m, itsBunch_m->RefPartP_m, tau);
itsBunch_m->RefPartR_m *= (Physics::c * 2 * tau);
pathLength_m = zstart_m;
Vector_t R = itsBunch_m->toLabTrafo_m.transformFrom(itsBunch_m->RefPartR_m);
Vector_t P = itsBunch_m->toLabTrafo_m.rotateFrom(itsBunch_m->RefPartP_m);
CoordinateSystemTrafo update(R, getQuaternion(P, Vector_t(0, 0, 1)));
itsBunch_m->toLabTrafo_m = itsBunch_m->toLabTrafo_m * update.inverted();
}
void ParallelTTracker::findStartPosition(const BorisPusher &pusher) {
StepSizeConfig stepSizesCopy(stepSizes_m);
if (back_track) {
stepSizesCopy.shiftZStopLeft(zstart_m);
}
double t = 0.0;
itsBunch_m->setT(t);
dtCurrentTrack_m = dtAllTracks_m.front();
changeDT();
dtCurrentTrack_m = stepSizesCopy.getdT();
selectDT();
if (Util::getEnergy(itsBunch_m->RefPartP_m, itsBunch_m->getM()) < 1e-3) {
if ((back_track && itsOpalBeamline_m.containsSource()) ||
Util::getEnergy(itsBunch_m->RefPartP_m, itsBunch_m->getM()) < 1e-3) {
double gamma = 0.1 / itsBunch_m->getM() + 1.0;
double beta = sqrt(1.0 - 1.0 / std::pow(gamma, 2));
itsBunch_m->RefPartP_m = itsBunch_m->toLabTrafo_m.rotateTo(beta * gamma * Vector_t(0, 0, 1));
......@@ -1198,37 +1223,32 @@ void ParallelTTracker::findStartPosition(const BorisPusher &pusher) {
updateReferenceParticle(pusher);
pathLength_m += euclidean_norm(itsBunch_m->RefPartR_m - oldR);
if (pathLength_m > zStop_m.front()) {
if (localTrackSteps_m.size() == 0) return;
dtAllTracks_m.pop();
localTrackSteps_m.pop();
zStop_m.pop();
changeDT();
}
double speed = euclidean_norm(itsBunch_m->RefPartP_m * Physics::c / Util::getGamma(itsBunch_m->RefPartP_m));
if (std::abs(pathLength_m - zstart_m) <= 0.5 * itsBunch_m->getdT() * speed) {
double tau = (pathLength_m - zstart_m) / speed;
t += tau;
itsBunch_m->setT(t);
if (pathLength_m > stepSizesCopy.getZStop()) {
++ stepSizesCopy;
itsBunch_m->RefPartR_m /= (Physics::c * tau);
pusher.push(itsBunch_m->RefPartR_m, itsBunch_m->RefPartP_m, tau);
itsBunch_m->RefPartR_m *= (Physics::c * tau);
if (stepSizesCopy.reachedEnd()) {
-- stepSizesCopy;
double tau = (stepSizesCopy.getZStop() - pathLength_m) / speed;
applyFractionalStep(pusher, tau);
pathLength_m = zstart_m;
break;
}
Vector_t R = itsBunch_m->toLabTrafo_m.transformFrom(itsBunch_m->RefPartR_m);
Vector_t P = itsBunch_m->toLabTrafo_m.rotateFrom(itsBunch_m->RefPartP_m);
CoordinateSystemTrafo update(R, getQuaternion(P, Vector_t(0, 0, 1)));
itsBunch_m->toLabTrafo_m = itsBunch_m->toLabTrafo_m * update.inverted();
dtCurrentTrack_m = stepSizesCopy.getdT();
selectDT();
}
return;
if (std::abs(pathLength_m - zstart_m) <= 0.5 * itsBunch_m->getdT() * speed) {
double tau = (zstart_m - pathLength_m) / speed;
applyFractionalStep(pusher, tau);
break;
}
}
changeDT();
}
void ParallelTTracker::autophaseCavities(const BorisPusher &pusher) {
......
......@@ -21,6 +21,7 @@
#include "Algorithms/Tracker.h"
#include "Steppers/BorisPusher.h"
#include "Structure/DataSink.h"
#include "Algorithms/StepSizeConfig.h"
#include "BasicActions/Option.h"
#include "Utilities/Options.h"
......@@ -62,9 +63,7 @@
#include <list>
#include <vector>
#include <queue>
class BorisPusher;
class ParticleMatterInteractionHandler;
class ParallelTTracker: public Tracker {
......@@ -214,14 +213,13 @@ private:
/// where to start
double zstart_m;
/// where to stop
std::queue<double> zStop_m;
/// stores informations where to change the time step and
/// where to stop the simulation,
/// the time step sizes and
/// the number of time steps with each configuration
StepSizeConfig stepSizes_m;
double dtCurrentTrack_m;
std::queue<double> dtAllTracks_m;
/// The maximal number of steps the system is integrated per TRACK
std::queue<unsigned long long> localTrackSteps_m;
// This variable controls the minimal number of steps of emission (using bins)
// before we can merge the bins
......@@ -292,8 +290,8 @@ private:
void timeIntegration1(BorisPusher & pusher);
void timeIntegration2(BorisPusher & pusher);
void selectDT();
void changeDT();
void selectDT(bool backTrack = false);
void changeDT(bool backTrack = false);
void emitParticles(long long step);
void computeExternalFields(OrbitThreader &oth);
void computeWakefield(IndexMap::value_t &elements);
......@@ -312,12 +310,11 @@ private:
void updateReference(const BorisPusher &pusher);
void updateRefToLabCSTrafo();
void applyFractionalStep(const BorisPusher &pusher, double tau);
void findStartPosition(const BorisPusher &pusher);
void autophaseCavities(const BorisPusher &pusher);
void evenlyDistributeParticles();
static unsigned long long getMaxSteps(std::queue<unsigned long long> numSteps);
};
inline void ParallelTTracker::visitAlignWrapper(const AlignWrapper &wrap) {
......@@ -455,18 +452,6 @@ inline void ParallelTTracker::pushParticles(const BorisPusher &pusher) {
itsBunch_m->switchOffUnitlessPositions(true);
}
inline
unsigned long long ParallelTTracker::getMaxSteps(std::queue<unsigned long long> numSteps) {
unsigned long long totalNumSteps = 0;
while (numSteps.size() > 0) {
totalNumSteps += numSteps.front();
numSteps.pop();
}
return totalNumSteps;
}
#ifdef OPAL_DKS
inline void ParallelTTracker::setupDKS() {
dksbase = new DKSOPAL;
......
#include "Algorithms/StepSizeConfig.h"
#include "Utilities/OpalException.h"
#include <algorithm>
#include <numeric>
#include <iterator>
#include <cmath>
void StepSizeConfig::sortAscendingZStop() {
configurations_m.sort([] (const entry_t &a,
const entry_t &b) -> bool
{
return std::get<1>(a) < std::get<1>(b);
});
}
void StepSizeConfig::reverseDirection() {
unsigned int posIterator = std::distance(it_m, configurations_m.end()) - 1;
configurations_m.reverse();
it_m = configurations_m.begin();
std::advance(it_m, posIterator);
}
StepSizeConfig& StepSizeConfig::advanceToPos(double spos) {
while (getZStop() < spos && std::next(it_m) != configurations_m.end()) {