Commit 4848122f authored by kraus's avatar kraus

Merge branch...

Merge branch '509-orbitthreader-computemaximalimplicitdrift-not-yielding-correct-results' into 'master'

Resolve "OrbitThreader::computeMaximalImplicitDrift not yielding correct results"

Closes #509

See merge request OPAL/src!336
parents 4d45fbc5 895e02a8
//
// Class CavityAutophaser
//
// This class determines the phase of an RF cavity for which the reference particle
// is accelerated to the highest energy.
//
// Copyright (c) 2016, Christof Metzger-Kraus, Helmholtz-Zentrum Berlin, Germany
// 2017 - 2020 Christof Metzger-Kraus
//
// All rights reserved
//
// This file is part of OPAL.
//
// OPAL 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.
//
// You should have received a copy of the GNU General Public License
// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
//
#include "Algorithms/CavityAutophaser.h"
#include "Algorithms/Vektor.h"
#include "AbsBeamline/RFCavity.h"
......
//
// Class CavityAutophaser
//
// This class determines the phase of an RF cavity for which the reference particle
// is accelerated to the highest energy.
//
// Copyright (c) 2016, Christof Metzger-Kraus, Helmholtz-Zentrum Berlin, Germany
// 2017 - 2020 Christof Metzger-Kraus
//
// All rights reserved
//
// This file is part of OPAL.
//
// OPAL 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.
//
// You should have received a copy of the GNU General Public License
// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
//
#ifndef CAVITYAUTOPHASER
#define CAVITYAUTOPHASER
......
//
// Class OrbitThreader
//
// This class determines the design path by tracking the reference particle through
// the 3D lattice.
//
// Copyright (c) 2016, Christof Metzger-Kraus, Helmholtz-Zentrum Berlin, Germany
// 2017 - 2020 Christof Metzger-Kraus
//
// All rights reserved
//
// This file is part of OPAL.
//
// OPAL 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.
//
// You should have received a copy of the GNU General Public License
// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
//
#include "Algorithms/OrbitThreader.h"
#include "Algorithms/CavityAutophaser.h"
......@@ -31,7 +53,6 @@ OrbitThreader::OrbitThreader(const PartData &ref,
double maxDiffZBunch,
double t,
double dt,
size_t maxIntegSteps,
double zstop,
OpalBeamline &bl) :
r_m(r),
......@@ -39,7 +60,6 @@ OrbitThreader::OrbitThreader(const PartData &ref,
pathLength_m(s),
time_m(t),
dt_m(dt),
maxIntegSteps_m(maxIntegSteps),
zstop_m(zstop),
itsOpalBeamline_m(bl),
errorFlag_m(0),
......@@ -82,16 +102,16 @@ OrbitThreader::OrbitThreader(const PartData &ref,
}
distTrackBack_m = std::min(pathLength_m, std::max(0.0, maxDiffZBunch));
computeBoundingBox();
}
void OrbitThreader::execute() {
double initialPathLength = pathLength_m;
double maxDistance = computeMaximalImplicitDrift();
auto allElements = itsOpalBeamline_m.getElementByType(ElementBase::ANY);
std::set<std::string> visitedElements;
trackBack(2 * maxDistance);
trackBack();
Vector_t nextR = r_m / (Physics::c * dt_m);
integrator_m.push(nextR, p_m, dt_m);
......@@ -109,7 +129,8 @@ void OrbitThreader::execute() {
double initialS = pathLength_m;
Vector_t initialR = r_m;
Vector_t initialP = p_m;
integrate(elementSet, maxIntegSteps_m, 2 * maxDistance);
double maxDistance = computeDriftLengthToBoundingBox(elementSet, r_m, p_m);
integrate(elementSet, maxDistance);
registerElement(elementSet, initialS, initialR, initialP);
......@@ -146,7 +167,7 @@ void OrbitThreader::execute() {
processElementRegister();
}
void OrbitThreader::integrate(const IndexMap::value_t &activeSet, size_t /*maxSteps*/, double maxDrift) {
void OrbitThreader::integrate(const IndexMap::value_t &activeSet, double maxDrift) {
static size_t step = 0;
CoordinateSystemTrafo labToBeamline = itsOpalBeamline_m.getCSTrafoLab2Local();
const double oldPathLength = pathLength_m;
......@@ -281,7 +302,7 @@ double OrbitThreader::getMaxDesignEnergy(const IndexMap::value_t &elementSet) co
return designEnergy;
}
void OrbitThreader::trackBack(double maxDrift) {
void OrbitThreader::trackBack() {
dt_m *= -1;
double initialPathLength = pathLength_m;
......@@ -289,11 +310,12 @@ void OrbitThreader::trackBack(double maxDrift) {
integrator_m.push(nextR, p_m, dt_m);
nextR *= Physics::c * dt_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);
double maxDrift = computeDriftLengthToBoundingBox(elementSet, r_m, -p_m);
maxDrift = std::min(maxDrift, distTrackBack_m);
integrate(elementSet, maxDrift);
nextR = r_m / (Physics::c * dt_m);
integrator_m.push(nextR, p_m, dt_m);
......@@ -388,75 +410,30 @@ void OrbitThreader::setDesignEnergy(FieldList &allElements, const std::set<std::
}
}
double OrbitThreader::computeMaximalImplicitDrift() {
void OrbitThreader::computeBoundingBox() {
FieldList allElements = itsOpalBeamline_m.getElementByType(ElementBase::ANY);
double maxDrift = 0.0;
MarkerRep start("#S");
CoordinateSystemTrafo toEdge(r_m, getQuaternion(p_m, Vector_t(0, 0, 1)));
start.setElementLength(0.0);
start.setCSTrafoGlobal2Local(toEdge);
std::shared_ptr<Component> startPtr(static_cast<Marker*>(start.clone()));
allElements.push_front(ClassicField(startPtr, 0.0, 0.0));
FieldList::iterator it = allElements.begin();
const FieldList::iterator end = allElements.end();
globalBoundingBox_m.lowerLeftCorner = Vector_t(std::numeric_limits<double>::max());
globalBoundingBox_m.upperRightCorner = Vector_t(-std::numeric_limits<double>::max());
for (; it != end; ++ it) {
auto element1 = it->getElement();
const auto &toEdge = element1->getCSTrafoGlobal2Local();
auto toEnd = element1->getEdgeToEnd() * toEdge;
Vector_t end1 = toEnd.transformFrom(Vector_t(0, 0, 0));
Vector_t directionEnd = toEnd.rotateFrom(Vector_t(0, 0, 1));
if (element1->getType() == ElementBase::RBEND ||
element1->getType() == ElementBase::SBEND ||
element1->getType() == ElementBase::RBEND3D ) {
auto toBegin = element1->getEdgeToBegin() * toEdge;
BendBase *bend = static_cast<BendBase*>(element1.get());
double angleRelativeToFace = bend->getEntranceAngle() - bend->getBendAngle();
directionEnd = toBegin.rotateFrom(Vector_t(sin(angleRelativeToFace), 0, cos(angleRelativeToFace)));
}
double minDistanceLocal = std::numeric_limits<double>::max();
FieldList::iterator it2 = allElements.begin();
for (; it2 != end; ++ it2) {
if (it == it2) continue;
auto element2 = it2->getElement();
const auto &toEdge = element2->getCSTrafoGlobal2Local();
auto toBegin = element2->getEdgeToBegin() * toEdge;
auto toEnd = element2->getEdgeToEnd() * toEdge;
Vector_t begin2 = toBegin.transformFrom(Vector_t(0, 0, 0));
Vector_t end2 = toEnd.transformFrom(Vector_t(0, 0, 0));
Vector_t directionBegin = toBegin.rotateFrom(Vector_t(0, 0, 1));
if (element2->getType() == ElementBase::RBEND ||
element2->getType() == ElementBase::SBEND ||
element2->getType() == ElementBase::RBEND3D ) {
BendBase *bend = static_cast<BendBase*>(element2.get());
double E1 = bend->getEntranceAngle();
directionBegin = toBegin.rotateFrom(Vector_t(sin(E1), 0, cos(E1)));
}
double distance = euclidean_norm(begin2 - end1);
double directionProjection = dot(directionEnd, directionBegin);
bool overlapping = dot(begin2 - end1, directionBegin) < 0.0? true: false;
if (!overlapping &&
directionProjection > 0.999 &&
minDistanceLocal > distance) {
minDistanceLocal = distance;
}
}
if (maxDrift < minDistanceLocal &&
minDistanceLocal != std::numeric_limits<double>::max()) {
maxDrift = minDistanceLocal;
if (it->getElement()->getType() == ElementBase::MARKER) {
continue;
}
ElementBase::BoundingBox other = it->getBoundingBoxInLabCoords();
globalBoundingBox_m.getCombinedBoundingBox(other);
}
}
maxDrift = std::min(maxIntegSteps_m * std::abs(dt_m) * Physics::c, maxDrift);
double OrbitThreader::computeDriftLengthToBoundingBox(const std::set<std::shared_ptr<Component>> & elements,
const Vector_t & position,
const Vector_t & direction) const {
if (elements.empty() ||
(elements.size() == 1 && (*elements.begin())->getType() == ElementBase::ElementType::DRIFT)) {
boost::optional<Vector_t> intersectionPoint = globalBoundingBox_m.getPointOfIntersection(position, direction);
return intersectionPoint ? euclidean_norm(intersectionPoint.get() - position): 10.0;
}
return maxDrift;
}
return std::numeric_limits<double>::max();
}
\ No newline at end of file
//
// Class OrbitThreader
//
// This class determines the design path by tracking the reference particle through
// the 3D lattice.
//
// Copyright (c) 2016, Christof Metzger-Kraus, Helmholtz-Zentrum Berlin, Germany
// 2017 - 2020 Christof Metzger-Kraus
//
// All rights reserved
//
// This file is part of OPAL.
//
// OPAL 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.
//
// You should have received a copy of the GNU General Public License
// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
//
#ifndef OPAL_ORBITTHREADER_H
#define OPAL_ORBITTHREADER_H
......@@ -20,7 +41,6 @@ public:
double maxDiffZBunch,
double t,
double dT,
size_t maxIntegSteps,
double zstop,
OpalBeamline &bl);
......@@ -48,8 +68,6 @@ private:
/// 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;
......@@ -64,6 +82,8 @@ private:
std::ofstream logger_m;
size_t loggingFrequency_m;
ElementBase::BoundingBox globalBoundingBox_m;
struct elementPosition {
double startField_m;
double endField_m;
......@@ -78,8 +98,8 @@ private:
std::multimap<std::string, elementPosition> elementRegistry_m;
void trackBack(double maxDrift);
void integrate(const IndexMap::value_t &activeSet, size_t maxSteps, double maxDrift = 10.0);
void trackBack();
void integrate(const IndexMap::value_t &activeSet, double maxDrift = 10.0);
bool containsCavity(const IndexMap::value_t &activeSet);
void autophaseCavities(const IndexMap::value_t &activeSet, const std::set<std::string> &visitedElements);
double getMaxDesignEnergy(const IndexMap::value_t &elementSet) const;
......@@ -87,7 +107,11 @@ private:
void registerElement(const IndexMap::value_t &elementSet, double, const Vector_t &r, const Vector_t &p);
void processElementRegister();
void setDesignEnergy(FieldList &allElements, const std::set<std::string> &visitedElements);
double computeMaximalImplicitDrift();
void computeBoundingBox();
// double computeMaximalImplicitDrift();
double computeDriftLengthToBoundingBox(const std::set<std::shared_ptr<Component>> & elements,
const Vector_t & position,
const Vector_t & direction) const;
};
inline
......
......@@ -4,7 +4,9 @@
// The visitor class for tracking particles with time as independent
// variable.
//
// Copyright (c) 200x - 2020, Paul Scherrer Institut, Villigen PSI, Switzerland
// Copyright (c) 200x - 2014, Christof Kraus, Paul Scherrer Institut, Villigen PSI, Switzerland
// 2015 - 2016, Christof Metzger-Kraus, Helmholtz-Zentrum Berlin, Germany
// 2017 - 2020, Christof Metzger-Kraus
// All rights reserved
//
// This file is part of OPAL.
......@@ -191,7 +193,6 @@ void ParallelTTracker::execute() {
prepareSections();
double minTimeStep = stepSizes_m.getMinTimeStep();
unsigned long long totalNumSteps = stepSizes_m.getNumStepsFinestResolution();
itsOpalBeamline_m.activateElements();
......@@ -246,7 +247,6 @@ void ParallelTTracker::execute() {
-rmin(2),
itsBunch_m->getT(),
(back_track? -minTimeStep: minTimeStep),
totalNumSteps,
stepSizes_m.getFinalZStop() + 2 * rmax(2),
itsOpalBeamline_m);
......
......@@ -4,7 +4,9 @@
// The visitor class for tracking particles with time as independent
// variable.
//
// Copyright (c) 200x - 2020, Paul Scherrer Institut, Villigen PSI, Switzerland
// Copyright (c) 200x - 2014, Christof Kraus, Paul Scherrer Institut, Villigen PSI, Switzerland
// 2015 - 2016, Christof Metzger-Kraus, Helmholtz-Zentrum Berlin, Germany
// 2017 - 2020, Christof Metzger-Kraus
// All rights reserved
//
// This file is part of OPAL.
......
......@@ -1680,4 +1680,32 @@ std::array<double,2> Bend2D::getExitFringeFieldLength() const {
extFFL[1] = ( exitParameter2_m-exitParameter1_m ); //before edge
return extFFL;
}
ElementBase::BoundingBox Bend2D::getBoundingBoxInLabCoords() const {
CoordinateSystemTrafo toBegin = getEdgeToBegin() * csTrafoGlobal2Local_m;
CoordinateSystemTrafo toEnd = getEdgeToEnd() * csTrafoGlobal2Local_m;
std::vector<Vector_t> outline = getOutline();
BoundingBox bb;
bb.lowerLeftCorner = std::numeric_limits<double>::max();
bb.upperRightCorner = std::numeric_limits<double>::lowest();
Vector_t dY(0, 0.5 * getFullGap(), 0);
for (int i : {-1, 1}) {
for (const Vector_t & vec: outline) {
Vector_t vecInLabCoords = csTrafoGlobal2Local_m.transformFrom(vec + i * dY);
for (unsigned int d = 0; d < 3; ++ d) {
if (vecInLabCoords(d) < bb.lowerLeftCorner(d)) {
bb.lowerLeftCorner(d) = vecInLabCoords(d);
}
if (vecInLabCoords(d) > bb.upperRightCorner(d)) {
bb.upperRightCorner(d) = vecInLabCoords(d);
}
}
}
}
return bb;
}
\ No newline at end of file
......@@ -129,6 +129,7 @@ public:
// Used to create fringe fields in ThickTracker, (before edge[m], after edge[m])
std::array<double,2> getExitFringeFieldLength() const;
BoundingBox getBoundingBoxInLabCoords() const override;
protected:
void setMessageHeader(const std::string & header);
double getStartField() const;
......@@ -375,5 +376,4 @@ Vector_t Bend2D::transformToExitRegion(const Vector_t &R) const {
return toExitRegion_m.transformTo(R);
}
#endif // CLASSIC_BEND_H
#endif // CLASSIC_BEND_H
\ No newline at end of file
......@@ -37,7 +37,6 @@ public:
void setFieldMapFN(std::string fileName);
std::string getFieldMapFN() const;
protected:
/// Calculate design radius from design energy and field amplitude
double calcDesignRadius(double fieldAmplitude) const;
......
......@@ -304,4 +304,115 @@ void ElementBase::setCurrentSCoordinate(double s) {
elementEdge_m = actionRange_m.front().first;
}
}
}
bool ElementBase::isInsideTransverse(const Vector_t &r) const
{
const double &xLimit = aperture_m.second[0];
const double &yLimit = aperture_m.second[1];
double factor = 1.0;
if (aperture_m.first == CONIC_RECTANGULAR ||
aperture_m.first == CONIC_ELLIPTICAL) {
Vector_t rRelativeToBegin = getEdgeToBegin().transformTo(r);
double fractionLength = rRelativeToBegin(2) / getElementLength();
factor = fractionLength * aperture_m.second[2];
}
switch(aperture_m.first) {
case RECTANGULAR:
return (std::abs(r[0]) < xLimit && std::abs(r[1]) < yLimit);
case ELLIPTICAL:
return (std::pow(r[0] / xLimit, 2) + std::pow(r[1] / yLimit, 2) < 1.0);
case CONIC_RECTANGULAR:
return (std::abs(r[0]) < factor * xLimit && std::abs(r[1]) < factor * yLimit);
case CONIC_ELLIPTICAL:
return (std::pow(r[0] / (factor * xLimit), 2) + std::pow(r[1] / (factor * yLimit), 2) < 1.0);
default:
return false;
}
}
bool ElementBase::BoundingBox::isInside(const Vector_t & position) const {
Vector_t relativePosition = position - lowerLeftCorner;
Vector_t diagonal = upperRightCorner - lowerLeftCorner;
for (unsigned int d = 0; d < 3; ++ d) {
if (relativePosition[d] < 0.0 ||
relativePosition[d] > diagonal[d]) {
return false;
}
}
return true;
}
boost::optional<Vector_t>
ElementBase::BoundingBox::getPointOfIntersection(const Vector_t & position,
const Vector_t & direction) const {
Vector_t relativePosition = lowerLeftCorner - position;
Vector_t diagonal = upperRightCorner - lowerLeftCorner;
Vector_t normalizedDirection = direction / euclidean_norm(direction);
for (int i : {-1, 1}) {
for (unsigned int d = 0; d < 3; ++ d) {
double projectedDirection = normalizedDirection[d];
if (std::abs(projectedDirection) < 1e-10) {
continue;
}
double distanceNearestPoint = relativePosition[d];
double tau = distanceNearestPoint / projectedDirection;
if (tau < 0) {
continue;
}
Vector_t delta = tau * normalizedDirection;
Vector_t relativeIntersectionPoint = i * (relativePosition - delta);
if (relativeIntersectionPoint[(d + 1) % 3] < 0.0 ||
relativeIntersectionPoint[(d + 1) % 3] > diagonal[(d + 1) % 3] ||
relativeIntersectionPoint[(d + 2) % 3] < 0.0 ||
relativeIntersectionPoint[(d + 2) % 3] > diagonal[(d + 2) % 3]) {
continue;
}
return position + delta;
}
relativePosition = upperRightCorner - position;
}
return boost::none;
}
ElementBase::BoundingBox ElementBase::getBoundingBoxInLabCoords() const {
CoordinateSystemTrafo toBegin = getEdgeToBegin() * csTrafoGlobal2Local_m;
CoordinateSystemTrafo toEnd = getEdgeToEnd() * csTrafoGlobal2Local_m;
const double &x = aperture_m.second[0];
const double &y = aperture_m.second[1];
const double &f = aperture_m.second[2];
std::vector<Vector_t> corners(8);
for (int i = -1; i < 2; i += 2) {
for (int j = -1; j < 2; j += 2) {
unsigned int idx = (i + 1)/2 + (j + 1);
corners[idx] = toBegin.transformFrom(Vector_t(i * x, j * y, 0.0));
corners[idx + 4] = toEnd.transformFrom(Vector_t(i * f * x, j * f * y, 0.0));
}
}
BoundingBox bb;
bb.lowerLeftCorner = bb.upperRightCorner = corners[0];
for (unsigned int i = 1; i < 8u; ++ i) {
for (unsigned int d = 0; d < 3u; ++ d) {
if (bb.lowerLeftCorner(d) > corners[i](d)) {
bb.lowerLeftCorner(d) = corners[i](d);
}
if (bb.upperRightCorner(d) < corners[i](d)) {
bb.upperRightCorner(d) = corners[i](d);
}
}
}
return bb;
}
\ No newline at end of file
......@@ -71,6 +71,8 @@
#include "Algorithms/CoordinateSystemTrafo.h"
#include "Utilities/GeneralClassicException.h"
#include <boost/optional.hpp>
#include <string>
#include <queue>
......@@ -79,6 +81,7 @@ class BoundaryGeometry;
class Channel;
class ConstChannel;
class ElementImage;
class ParticleMatterInteractionHandler;
class WakeFunction;
......@@ -353,8 +356,35 @@ public:
void setRotationAboutZ(double rotation);
double getRotationAboutZ() const;
struct BoundingBox {
Vector_t lowerLeftCorner;
Vector_t upperRightCorner;
void getCombinedBoundingBox(const BoundingBox & other) {
for (unsigned int d = 0; d < 3; ++ d) {
lowerLeftCorner[d] = std::min(lowerLeftCorner[d], other.lowerLeftCorner[d]);
upperRightCorner[d] = std::max(upperRightCorner[d], other.upperRightCorner[d]);
}
}
bool isInside(const Vector_t &) const;
/*! Computes the intersection point between a bounding box and the ray which
* has the direction 'direction' and starts at the position 'position'. If
* the position is inside the box then the algorithm should find an inter-
* section point.
*
* @param position the position where the ray starts
* @param direction the direction of the ray
*/
boost::optional<Vector_t> getPointOfIntersection(const Vector_t & position,
const Vector_t & direction) const;
};
virtual BoundingBox getBoundingBoxInLabCoords() const;
protected:
bool isInsideTransverse(const Vector_t &r, double f = 1) const;
bool isInsideTransverse(const Vector_t &r) const;
// Sharable flag.
// If this flag is true, the element is always shared.
......@@ -525,24 +555,7 @@ inline
bool ElementBase::isInside(const Vector_t &r) const
{
const double length = getElementLength();
return isInsideTransverse(r, r(2) / length * aperture_m.second[2]) && r(2) >= 0.0 && r(2) < length;
}
inline
bool ElementBase::isInsideTransverse(const Vector_t &r, double f) const
{
switch(aperture_m.first) {
case RECTANGULAR:
return (std::abs(r[0]) < aperture_m.second[0] && std::abs(r[1]) < aperture_m.second[1]);
case ELLIPTICAL:
return (std::pow(r[0] / aperture_m.second[0], 2) + std::pow(r[1] / aperture_m.second[1], 2) < 1.0);
case CONIC_RECTANGULAR:
return (std::abs(r[0]) < f * aperture_m.second[0] && std::abs(r[1]) < f * aperture_m.second[1]);
case CONIC_ELLIPTICAL:
return (std::pow(r[0] / (f * aperture_m.second[0]), 2) + std::pow(r[1] / (f * aperture_m.second[1]), 2) < 1.0);
default:
return false;
}
return r(2) >= 0.0 && r(2) < length && isInsideTransverse(r);
}
inline
......@@ -611,5 +624,4 @@ inline
bool ElementBase::isElementPositionSet() const
{ return elemedgeSet_m; }
#endif // CLASSIC_ElementBase_HH
\ No newline at end of file
#endif // CLASSIC_ElementBase_HH
......@@ -63,6 +63,7 @@ RFCavity::RFCavity(const RFCavity &right):
fieldmap_m(right.fieldmap_m),
length_m(right.length_m),
startField_m(right.startField_m),
endField_m(right.endField_m),
type_m(right.type_m),
rmin_m(right.rmin_m),
rmax_m(right.rmax_m),
......@@ -96,6 +97,7 @@ RFCavity::RFCavity(const std::string &name):
fieldmap_m(nullptr),
length_m(0.0),
startField_m(0.0),
endField_m(0.0),
type_m(SW),
rmin_m(0.0),
rmax_m(0.0),
......@@ -164,10 +166,10 @@ bool RFCavity::applyToReferenceParticle(const Vector_t &R,
void RFCavity::initialise(PartBunchBase<double, 3> *bunch, double &startField, double &endField) {
startField_m = 0.0;
startField_m = endField_m = 0.0;
if (bunch == NULL) {
startField = startField_m;
endField = startField_m;
endField = endField_m;
return;
}
......@@ -483,7 +485,7 @@ double RFCavity::spline(double z, double *za) {
void RFCavity::getDimensions(double &zBegin, double &zEnd) const {
zBegin = startField_m;
zEnd = startField_m + length_m;
zEnd = endField_m;
}
......@@ -740,4 +742,4 @@ void RFCavity::getElementDimensions(double &begin,
// c-basic-offset: 4
// indent-tabs-mode: nil
// require-final-newline: nil
// End:
// End:
\ No newline at end of file
......@@ -230,6 +230,8 @@ protected:
double startField_m; /**< starting point of field(m)*/
private:
double endField_m;
CavityType type_m;
double rmin_m;
......@@ -513,4 +515,4 @@ Coordina