35 :
Element(size, name, help), itsSize(size) {
37 "TYPE",
"The element design type.",
38 {
"RING",
"CARBONCYCL",
"CYCIAE",
"AVFEQ",
"FFA",
"BANDRF",
"SYNCHROCYCLOTRON",
39 "SINGLEGAP",
"STANDING",
"TEMPORAL",
"SPATIAL"});
51 "PARTICLEMATTERINTERACTION",
"Defines the particle mater interaction handler");
56 "ORIENTATION",
"The Tait-Bryan angles for the orientation of the element");
87 "DELETEONTRANSVERSEEXIT",
88 "Flag controlling if particles should be deleted if they exit "
89 "the element transversally",
92 const unsigned int end =
COMMON;
93 for (
unsigned int i = 0; i < end; ++i) {
99 :
Element(name, parent), itsSize(parent->itsSize) {}
104 std::pair<ApertureType, std::vector<double>> retvalue(
112 std::regex square(
"square *\\((.*)\\)", std::regex::icase);
113 std::regex rectangle(
"rectangle *\\((.*)\\)", std::regex::icase);
114 std::regex circle(
"circle *\\((.*)\\)", std::regex::icase);
115 std::regex ellipse(
"ellipse *\\((.*)\\)", std::regex::icase);
117 std::regex twoArguments(
"^\\s*([^,]+)\\s*,\\s*([^,]+)\\s*$");
118 std::regex threeArguments(
"^\\s*([^,]+)\\s*,\\s*([^,]+)\\s*,\\s*([^,]+)\\s*$");
122 const double width2HalfWidth = 0.5;
124 auto validateConicScale = [&](
double scale,
const std::string& arguments) {
125 if (!(scale > 0.0)) {
127 "OpalElement::getApert()",
"invalid conic aperture scale in '" + arguments
128 +
"': expected positive real value");
132 if (std::regex_search(aperture, match, square)) {
133 std::string arguments = match[1];
134 if (!std::regex_search(arguments, match, twoArguments)) {
138 retvalue.second[0] = width2HalfWidth * std::stod(arguments);
139 retvalue.second[1] = retvalue.second[0];
140 }
catch (
const std::exception& ex) {
142 "OpalElement::getApert()",
143 "could not convert '" + arguments +
"' to double");
150 retvalue.second[0] = width2HalfWidth * std::stod(match[1]);
151 retvalue.second[1] = retvalue.second[0];
152 retvalue.second[2] = std::stod(match[2]);
153 }
catch (
const std::exception& ex) {
155 "OpalElement::getApert()",
156 "could not convert '" + arguments +
"' to doubles");
158 validateConicScale(retvalue.second[2], arguments);
164 if (std::regex_search(aperture, match, rectangle)) {
165 std::string arguments = match[1];
167 if (!std::regex_search(arguments, match, threeArguments)) {
173 retvalue.second[0] = width2HalfWidth * std::stod(arguments, &sz);
174 sz = arguments.find_first_of(
",", sz) + 1;
175 retvalue.second[1] = width2HalfWidth * std::stod(arguments.substr(sz));
177 }
catch (
const std::exception& ex) {
179 "OpalElement::getApert()",
180 "could not convert '" + arguments +
"' to doubles");
187 retvalue.second[0] = width2HalfWidth * std::stod(match[1]);
188 retvalue.second[1] = width2HalfWidth * std::stod(match[2]);
189 retvalue.second[2] = std::stod(match[3]);
190 }
catch (
const std::exception& ex) {
192 "OpalElement::getApert()",
193 "could not convert '" + arguments +
"' to doubles");
195 validateConicScale(retvalue.second[2], arguments);
201 if (std::regex_search(aperture, match, circle)) {
202 std::string arguments = match[1];
203 if (!std::regex_search(arguments, match, twoArguments)) {
207 retvalue.second[0] = width2HalfWidth * std::stod(arguments);
208 retvalue.second[1] = retvalue.second[0];
209 }
catch (
const std::exception& ex) {
211 "OpalElement::getApert()",
212 "could not convert '" + arguments +
"' to double");
219 retvalue.second[0] = width2HalfWidth * std::stod(match[1]);
220 retvalue.second[1] = retvalue.second[0];
221 retvalue.second[2] = std::stod(match[2]);
222 }
catch (
const std::exception& ex) {
224 "OpalElement::getApert()",
225 "could not convert '" + arguments +
"' to doubles");
227 validateConicScale(retvalue.second[2], arguments);
233 if (std::regex_search(aperture, match, ellipse)) {
234 std::string arguments = match[1];
236 if (!std::regex_search(arguments, match, threeArguments)) {
242 retvalue.second[0] = width2HalfWidth * std::stod(arguments, &sz);
243 sz = arguments.find_first_of(
",", sz) + 1;
244 retvalue.second[1] = width2HalfWidth * std::stod(arguments.substr(sz));
246 }
catch (
const std::exception& ex) {
248 "OpalElement::getApert()",
249 "could not convert '" + arguments +
"' to doubles");
256 retvalue.second[0] = width2HalfWidth * std::stod(match[1]);
257 retvalue.second[1] = width2HalfWidth * std::stod(match[2]);
258 retvalue.second[2] = std::stod(match[3]);
259 }
catch (
const std::exception& ex) {
261 "OpalElement::getApert()",
262 "could not convert '" + arguments +
"' to doubles");
264 validateConicScale(retvalue.second[2], arguments);
270 if (!aperture.empty()) {
271 throw OpalException(
"OpalElement::getApert()",
"Unknown aperture type '" + aperture +
"'.");
303 throw OpalException(
"OpalElement::parse",
"unknown attribute \"" + name +
"\"");
315 throw ParseError(
"OpalElement::parse()",
"Delimiter \"=\" or \":=\" expected.");
319 attr->
parse(stat,
true);
321 attr->
parse(stat,
false);
333 if (parent != 0 && !parent->
getOpalName().empty()) {
344 std::ostream& os,
int order,
int& len,
const std::string& sName,
const std::string& tName,
364 int div = 2 * (order + 1);
375 std::string normImage = sNorm.
getImage();
377 normImage =
"(" + normImage +
")*(" + length.
getImage() +
")";
387 std::string skewImage = sSkew.
getImage();
389 skewImage =
"(" + skewImage +
")*(" + length.
getImage() +
")";
402 double strength = std::sqrt(sn * sn + ss * ss);
404 std::ostringstream ts;
406 std::string image = ts.str();
408 image =
"(" + image +
")*(" + length.
getImage() +
")";
411 double tilt = -std::atan2(ss, sn) / double(div);
422 std::string normImage = sNorm.
getImage();
423 std::string skewImage = sSkew.
getImage();
424 std::string image =
"SQRT((" + normImage +
")^2+(" + skewImage +
")^2)";
427 image =
"(" + image +
")*(" + length.
getImage() +
")";
435 divisor[0] += div / 10;
436 divisor[1] += div % 10;
438 image =
"-ATAN2(" + skewImage +
',' + normImage +
")/" + divisor;
457 if (dir.size() == 3) {
458 Quaternion rotTheta(std::cos(0.5 * dir[0]), 0, std::sin(0.5 * dir[0]), 0);
459 Quaternion rotPhi(std::cos(0.5 * dir[1]), std::sin(0.5 * dir[1]), 0, 0);
460 Quaternion rotPsi(std::cos(0.5 * dir[2]), 0, 0, std::sin(0.5 * dir[2]));
461 rotation = rotTheta * (rotPhi * rotPsi);
465 "OpalElement::update",
466 "Parameter orientation is array of 3 values (theta, phi, psi);\n"
467 + std::to_string(dir.size()) +
" values provided");
471 if (ori.size() == 3) {
476 "OpalElement::update",
"Parameter origin is array of 3 values (x, y, z);\n"
477 + std::to_string(ori.size())
478 +
" values provided");
503 Quaternion rotTheta(std::cos(0.5 * theta), 0, std::sin(0.5 * theta), 0);
504 Quaternion rotPhi(std::cos(0.5 * phi), std::sin(0.5 * phi), 0, 0);
505 Quaternion rotPsi(std::cos(0.5 * psi), 0, 0, std::sin(0.5 * psi));
506 Quaternion rotation = rotTheta * (rotPhi * rotPsi);
520 Quaternion rotationY(std::cos(0.5 * dtheta), 0, std::sin(0.5 * dtheta), 0);
521 Quaternion rotationX(std::cos(0.5 * dphi), std::sin(0.5 * dphi), 0, 0);
522 Quaternion rotationZ(std::cos(0.5 * dpsi), 0, 0, std::sin(0.5 * dpsi));
523 Quaternion misalignmentRotation = rotationY * rotationX * rotationZ;
534 for (std::vector<Attribute>::size_type i =
itsSize; i <
itsAttr.size(); ++i) {
541 std::ostream& os,
const std::string& name,
const std::string& image,
int& len) {
542 len += name.length() + image.length() + 2;
545 len = name.length() + image.length() + 3;
549 os << name <<
'=' << image;
553 std::ostream& os,
const std::string& name,
double value,
int& len) {
554 std::ostringstream ss;
555 ss << value << std::ends;
562 const unsigned int end =
itsSize;
564 for (
unsigned int i =
COMMON; i < end; ++i) {
ippl::Vector< T, Dim > Vector_t
virtual bool isExpression() const
Test for expression.
static void addAttributeOwner(const std::string &owner, const OwnerType &type, const std::string &name)
A representation of an Object attribute.
AttributeBase & getBase() const
Return reference to polymorphic value.
const std::string & getName() const
Return the attribute name.
void setDefault()
Assign default value.
void parse(Statement &stat, bool eval)
Parse attribute.
void parseComponent(Statement &stat, bool eval, int index)
Parse array component.
std::string getImage() const
Return printable representation.
Rigid spatial transform between a parent frame and a local frame.
void setElementPosition(double elemedge)
Access to ELEMEDGE attribute.
void setAperture(const ApertureType &type, const std::vector< double > &args)
void setMisalignment(const CoordinateSystemTrafo &cst)
virtual void setAttribute(const std::string &aKey, double val)
Set value of an attribute.
void setFlagDeleteOnTransverseExit(bool=true)
void setRotationAboutZ(double rotation)
Set rotation about z axis in bend frame.
void setCSTrafoGlobal2Local(const CoordinateSystemTrafo &ori)
ElementBase * getElement() const
Return the embedded OPALX element.
The base class for all OPAL objects.
Object * getParent() const
Return parent pointer.
const std::string & getOpalName() const
Return object name.
virtual Attribute * findAttribute(const std::string &name)
Find an attribute by name.
std::vector< Attribute > itsAttr
The object attributes.
std::pair< ApertureType, std::vector< double > > getApert() const
static void printMultipoleStrength(std::ostream &os, int order, int &len, const std::string &sName, const std::string &tName, const Attribute &length, const Attribute &vNorm, const Attribute &vSkew)
Print multipole components in OPAL-8 format.
virtual double getLength() const
Return element length.
static void printAttribute(std::ostream &os, const std::string &name, const std::string &image, int &len)
Print an attribute with a OPAL-8 name (as an expression).
virtual void parse(Statement &)
Parse the element.
const std::string getParticleMatterInteraction() const
const std::string getWakeF() const
Return the element's type name.
virtual void updateUnknown(ElementBase *)
Transmit the `‘unknown’' (not known to OPALX) attributes to OPALX.
@ PARTICLEMATTERINTERACTION
const std::string getTypeName() const
Return the element's type name.
virtual void print(std::ostream &) const
Print the object.
virtual void update()
Update the embedded OPALX element.
void registerOwnership() const
Quaternion storage and rotation algebra used by OPALX geometry code.
Quaternion conjugate() const
Return the quaternion conjugate .
Interface for statements.
bool delimiter(char c)
Test for delimiter.
Attribute makeBool(const std::string &name, const std::string &help)
Make logical attribute.
double getReal(const Attribute &attr)
Return real value.
Attribute makePredefinedString(const std::string &name, const std::string &help, const std::initializer_list< std::string > &predefinedStrings)
Make predefined string attribute.
Attribute makeReal(const std::string &name, const std::string &help)
Make real attribute.
bool getBool(const Attribute &attr)
Return logical value.
Attribute makeRealArray(const std::string &name, const std::string &help)
Create real array attribute.
std::vector< double > getRealArray(const Attribute &attr)
Get array value.
std::string getString(const Attribute &attr)
Get string value.
Attribute makeString(const std::string &name, const std::string &help)
Make string attribute.
std::string parseString(Statement &, const char msg[])
Parse string value.
void parseDelimiter(Statement &stat, char delim)
Test for one-character delimiter.
double parseRealConst(Statement &)
Parse real constant.
constexpr double pi
The value of.