31#include <boost/regex.hpp>
40 Element(size, name, help), itsSize(size) {
42 (
"TYPE",
"The element design type.",
56 (
"L",
"The element length in m");
59 (
"ELEMEDGE",
"The position of the element in path length (in m)");
62 (
"APERTURE",
"The element aperture");
65 (
"WAKEF",
"Defines the wake function");
68 (
"PARTICLEMATTERINTERACTION",
"Defines the particle mater interaction handler");
71 (
"ORIGIN",
"The location of the element");
74 (
"ORIENTATION",
"The Tait-Bryan angles for the orientation of the element");
77 (
"X",
"The x-coordinate of the location of the element", 0);
80 (
"Y",
"The y-coordinate of the location of the element", 0);
83 (
"Z",
"The z-coordinate of the location of the element", 0);
86 (
"THETA",
"The rotation about the y-axis of the element", 0);
89 (
"PHI",
"The rotation about the x-axis of the element", 0);
92 (
"PSI",
"The rotation about the z-axis of the element", 0);
95 (
"DX",
"Misalignment in x direction",0.0);
98 (
"DY",
"Misalignment in y direction",0.0);
101 (
"DZ",
"Misalignment in z direction",0.0);
104 (
"DTHETA",
"Misalignment in theta (Tait-Bryan angles)",0.0);
107 (
"DPHI",
"Misalignment in theta (Tait-Bryan angles)",0.0);
110 (
"DPSI",
"Misalignment in theta (Tait-Bryan angles)",0.0);
113 (
"OUTFN",
"Output filename");
116 (
"DELETEONTRANSVERSEEXIT",
"Flag controlling if particles should be deleted if they exit "
117 "the element transversally",
true);
120 for (
unsigned int i = 0; i <
end; ++ i) {
127 Element(name, parent), itsSize(parent->itsSize)
138 std::vector<double>({0.5, 0.5, 1.0}));
143 boost::regex square(
"square *\\((.*)\\)", boost::regex::icase);
144 boost::regex rectangle(
"rectangle *\\((.*)\\)", boost::regex::icase);
145 boost::regex circle(
"circle *\\((.*)\\)", boost::regex::icase);
146 boost::regex ellipse(
"ellipse *\\((.*)\\)", boost::regex::icase);
148 boost::regex twoArguments(
"([^,]*),([^,]*)");
149 boost::regex threeArguments(
"([^,]*),([^,]*),([^,]*)");
153 const double width2HalfWidth = 0.5;
155 if (boost::regex_search(aperture, match, square)) {
156 std::string arguments = match[1];
157 if (!boost::regex_search(arguments, match, twoArguments)) {
161 retvalue.second[0] = width2HalfWidth * std::stod(arguments);
162 retvalue.second[1] = retvalue.second[0];
163 }
catch (
const std::exception &ex) {
165 "could not convert '" + arguments +
"' to double");
172 retvalue.second[0] = width2HalfWidth * std::stod(match[1]);
173 retvalue.second[1] = retvalue.second[0];
174 retvalue.second[2] = std::stod(match[2]);
175 }
catch (
const std::exception &ex) {
177 "could not convert '" + arguments +
"' to doubles");
184 if (boost::regex_search(aperture, match, rectangle)) {
185 std::string arguments = match[1];
187 if (!boost::regex_search(arguments, match, threeArguments)) {
193 retvalue.second[0] = width2HalfWidth * std::stod(arguments, &sz);
194 sz = arguments.find_first_of(
",", sz) + 1;
195 retvalue.second[1] = width2HalfWidth * std::stod(arguments.substr(sz));
197 }
catch (
const std::exception &ex) {
199 "could not convert '" + arguments +
"' to doubles");
206 retvalue.second[0] = width2HalfWidth * std::stod(match[1]);
207 retvalue.second[1] = width2HalfWidth * std::stod(match[2]);
208 retvalue.second[2] = std::stod(match[3]);
209 }
catch (
const std::exception &ex) {
211 "could not convert '" + arguments +
"' to doubles");
218 if (boost::regex_search(aperture, match, circle)) {
219 std::string arguments = match[1];
220 if (!boost::regex_search(arguments, match, twoArguments)) {
224 retvalue.second[0] = width2HalfWidth * std::stod(arguments);
225 retvalue.second[1] = retvalue.second[0];
226 }
catch (
const std::exception &ex) {
228 "could not convert '" + arguments +
"' to double");
235 retvalue.second[0] = width2HalfWidth * std::stod(match[1]);
236 retvalue.second[1] = retvalue.second[0];
237 retvalue.second[2] = std::stod(match[2]);
238 }
catch (
const std::exception &ex) {
240 "could not convert '" + arguments +
"' to doubles");
247 if (boost::regex_search(aperture, match, ellipse)) {
248 std::string arguments = match[1];
250 if (!boost::regex_search(arguments, match, threeArguments)) {
256 retvalue.second[0] = width2HalfWidth * std::stod(arguments, &sz);
257 sz = arguments.find_first_of(
",", sz) + 1;
258 retvalue.second[1] = width2HalfWidth * std::stod(arguments.substr(sz));
260 }
catch (
const std::exception &ex) {
262 "could not convert '" + arguments +
"' to doubles");
269 retvalue.second[0] = width2HalfWidth * std::stod(match[1]);
270 retvalue.second[1] = width2HalfWidth * std::stod(match[2]);
271 retvalue.second[2] = std::stod(match[3]);
272 }
catch (
const std::exception &ex) {
274 "could not convert '" + arguments +
"' to doubles");
281 if (!aperture.empty()) {
283 "Unknown aperture type '" + aperture +
"'.");
319 "unknown attribute \"" + name +
"\"");
332 "Delimiter \"=\" or \":=\" expected.");
336 attr->
parse(stat,
true);
338 attr->
parse(stat,
false);
351 if (parent != 0 && ! parent->
getOpalName().empty()) {
364 const std::string& sName,
365 const std::string& tName,
388 int div = 2 * (order + 1);
400 std::string normImage = sNorm.
getImage();
402 normImage =
"(" + normImage +
")*(" + length.
getImage() +
")";
412 std::string skewImage = sSkew.
getImage();
414 skewImage =
"(" + skewImage +
")*(" + length.
getImage() +
")";
427 double strength = std::sqrt(sn * sn + ss * ss);
429 std::ostringstream ts;
431 std::string image = ts.str();
433 image =
"(" + image +
")*(" + length.
getImage() +
")";
436 double tilt = - std::atan2(ss, sn) / double(
div);
447 std::string normImage = sNorm.
getImage();
448 std::string skewImage = sSkew.
getImage();
450 "SQRT((" + normImage +
")^2+(" + skewImage +
")^2)";
453 image =
"(" + image +
")*(" + length.
getImage() +
")";
461 divisor[0] +=
div / 10;
462 divisor[1] +=
div % 10;
464 image =
"-ATAN2(" + skewImage +
',' + normImage +
")/" + divisor;
483 if (dir.size() == 3) {
484 Quaternion rotTheta(std::cos(0.5 * dir[0]), 0, std::sin(0.5 * dir[0]), 0);
485 Quaternion rotPhi(std::cos(0.5 * dir[1]), std::sin(0.5 * dir[1]), 0, 0);
486 Quaternion rotPsi(std::cos(0.5 * dir[2]), 0, 0, std::sin(0.5 * dir[2]));
487 rotation = rotTheta * (rotPhi * rotPsi);
491 "Parameter orientation is array of 3 values (theta, phi, psi);\n" +
492 std::to_string(dir.size()) +
" values provided");
496 if (ori.size() == 3) {
501 "Parameter origin is array of 3 values (x, y, z);\n" +
502 std::to_string(ori.size()) +
" values provided");
518 }
else if (!
itsAttr[
X].defaultUsed() ||
532 Quaternion rotTheta(std::cos(0.5 * theta), 0, std::sin(0.5 * theta), 0);
533 Quaternion rotPhi(std::cos(0.5 * phi), std::sin(0.5 * phi), 0, 0);
534 Quaternion rotPsi(std::cos(0.5 * psi), 0, 0, std::sin(0.5 * psi));
535 Quaternion rotation = rotTheta * (rotPhi * rotPsi);
550 Quaternion rotationY(std::cos(0.5 * dtheta), 0, std::sin(0.5 * dtheta), 0);
551 Quaternion rotationX(std::cos(0.5 * dphi), std::sin(0.5 * dphi), 0, 0);
552 Quaternion rotationZ(std::cos(0.5 * dpsi), 0, 0, std::sin(0.5 * dpsi));
553 Quaternion misalignmentRotation = rotationY * rotationX * rotationZ;
575 const std::string& image,
int& len) {
576 len += name.length() + image.length() + 2;
579 len = name.length() + image.length() + 3;
583 os << name <<
'=' << image;
587(std::ostream &os,
const std::string &name,
double value,
int &len) {
588 std::ostringstream ss;
589 ss << value << std::ends;
599 for (
unsigned int i =
COMMON; i <
end; ++ i) {
PartBunch< T, Dim >::ConstIterator end(PartBunch< T, Dim > const &bunch)
ippl::detail::size_type size_type
Inform & endl(Inform &inf)
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.
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.
constexpr double pi
The value of.
detail::meta_div< Field > div(Field &u)
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)
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.
virtual bool isExpression() const
Test for expression.
static void addAttributeOwner(const std::string &owner, const OwnerType &type, const std::string &name)
ElementBase * getElement() const
Return the embedded CLASSIC 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.
Quaternion conjugate() const
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 OPAL) attributes to CLASSIC.
@ 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 CLASSIC element.
void registerOwnership() const
Interface for statements.
bool delimiter(char c)
Test for delimiter.
The base class for all OPAL exceptions.