OPALX (Object Oriented Parallel Accelerator Library for Exascal) master (dc2a29eed580)
OPALX
Loading...
Searching...
No Matches
MultipoleT.cpp
Go to the documentation of this file.
1//
2// Cubic Spline Interpolation to replace GSL spline
3//
4// Copyright (c) 2023, Paul Scherrer Institute, Villigen PSI, Switzerland
5// All rights reserved
6//
7// This file is part of OPAL.
8//
9// OPAL is free software: you can redistribute it and/or modify
10// it under the terms of the GNU General Public License as published by
11// the Free Software Foundation, either version 3 of the License, or
12// (at your option) any later version.
13//
14// You should have received a copy of the GNU General License
15// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
16//
17
18#include "MultipoleT.h"
19#include "BeamlineVisitor.h"
21#include "MultipoleTStraight.h"
22
23MultipoleT::MultipoleT(const std::string& name) : Component(name) { chooseImplementation(); }
24
26 : Component(right),
27 config_m(right.config_m),
28 scalingName_m(right.scalingName_m),
29 scalingTD_m(right.scalingTD_m) {
32}
33
34ElementBase* MultipoleT::clone() const { return new MultipoleT(*this); }
35
36void MultipoleT::accept(BeamlineVisitor& visitor) const {
38 visitor.visitMultipoleT(*this);
39}
40
41double MultipoleT::getScaling(const double t) const {
42 double scaling = 1.0;
43 if (scalingTD_m) {
44 scaling = scalingTD_m->getValue(t);
45 }
46 return scaling;
47}
48
49bool MultipoleT::apply(const std::shared_ptr<ParticleContainer_t>& pc) {
51 implementation_->getField(
52 pc->R.getView(), pc->E.getView(), pc->B.getView(), getScaling(RefPartBunch_m->getT()),
53 pc->getLocalNum());
54 return false;
55}
56
58 const Vector_t<double, 3>& R, const Vector_t<double, 3>& /*P*/, const double& t,
61 return implementation_->getField(R, E, B, getScaling(t));
62}
63
65 const size_t& i, const double& t, Vector_t<double, 3>& E, Vector_t<double, 3>& B) {
67 if (RefPartBunch_m == nullptr) {
68 throw OpalException("MultipoleT::apply", "Element is not initialised with a bunch");
69 }
70 if (RefPartBunch_m->getNumParticleContainers() != 1) {
71 throw OpalException(
72 "MultipoleT::apply",
73 "apply(i, t, E, B) is ambiguous for multi-container bunches; "
74 "use apply(pc) from the container loop instead");
75 }
76 const auto pc = RefPartBunch_m->getParticleContainer(0);
77 if (i >= pc->getLocalNum()) {
78 throw OpalException("MultipoleT::apply", "Particle index is out of local bounds");
79 }
81 Kokkos::deep_copy(
82 Kokkos::View<Vector_t<double, 3>, Kokkos::HostSpace>(&R),
83 Kokkos::subview(pc->R.getView(), i));
84 Kokkos::fence();
85 return implementation_->getField(R, E, B, getScaling(t));
86}
87
89 const double& s0, const double& lambda_left, const double& lambda_right) {
91 config_m.fringeLambdaLeft_m = lambda_left;
92 config_m.fringeLambdaRight_m = lambda_right;
93 implementation_->initialise();
94}
95
96std::tuple<double, double, double> MultipoleT::getFringeField() const {
98}
99
101
102void MultipoleT::setElementLength(const double length) {
103 // Base class first
105 // Then me
106 config_m.length_m = length;
107 implementation_->initialise();
108}
109
110void MultipoleT::setBendAngle(const double angle, const bool variableRadius) {
111 // Record information
112 config_m.bendAngle_m = angle;
113 config_m.variableRadius_m = variableRadius;
115}
116
118 if (config_m.bendAngle_m == 0.0) {
119 implementation_ = std::make_unique<MultipoleTStraight>(this);
120 // This is where the variable radius code is to be patched in.
121 //} else if (config_m.variableRadius_m) {
122 // implementation_ = std::make_unique<MultipoleTCurvedVarRadius>(this);
123 } else {
124 implementation_ = std::make_unique<MultipoleTCurvedConstRadius>(this);
125 }
126 implementation_->initialise();
127}
128
129void MultipoleT::setAperture(const double& vertAp, const double& horizAp) {
132}
133
134void MultipoleT::setBoundingBoxLength(const double boundingBoxLength) {
135 config_m.boundingBoxLength_m = boundingBoxLength;
136}
137
138void MultipoleT::setTransProfile(const std::vector<double>& profile) {
140 for (unsigned int i = 0; i < MultipoleTConfig::NumPoles; ++i) {
141 if (i < profile.size() && profile[i] != 0.0) {
142 config_m.transverseProfile_m[i] = profile[i];
145 } else {
147 }
148 }
149}
150
151void MultipoleT::setMaxOrder(const size_t orderZ, const size_t orderX) {
152 config_m.maxFOrder_m = orderZ;
153 config_m.maxXOrder_m = orderX;
154 implementation_->initialise();
155}
156
157void MultipoleT::setRotation(const double rot) { config_m.rotation_m = rot; }
158
159void MultipoleT::setEntranceAngle(const double entranceAngle) {
160 config_m.entranceAngle_m = entranceAngle;
161}
162
163void MultipoleT::setEntryOffset(const double offset) { config_m.entryOffset_m = offset; }
164
165bool MultipoleT::bends() const { return config_m.bendAngle_m != 0.0; }
166
167void MultipoleT::initialise(PartBunch_t* bunch, double& /*startField*/, double& /*endField*/) {
168 RefPartBunch_m = bunch;
169 implementation_->initialise();
170}
171
172void MultipoleT::setScalingName(const std::string& name) {
173 // Element names are stored in upper case
174 scalingName_m = name;
175 std::ranges::transform(scalingName_m, scalingName_m.begin(), [](const unsigned char c) {
176 return static_cast<char>(std::toupper(c));
177 });
178}
179
186
188
189const BGeometryBase& MultipoleT::getGeometry() const { return *implementation_->getGeometry(); }
190
193 throw OpalException(
194 "MultipoleT::validateConfiguration",
195 "Max F order too large for this implementation");
196 }
197}
ippl::Vector< T, Dim > Vector_t
static std::shared_ptr< AbstractTimeDependence > getTimeDependence(const std::string &name)
Abstract base class for accelerator geometry classes.
Definition Geometry.h:42
virtual void visitMultipoleT(const MultipoleT &)=0
Apply the algorithm to an arbitrary multipole.
PartBunch_t * RefPartBunch_m
Definition Component.h:225
virtual void setElementLength(double length)
Set design length.
static constexpr unsigned int MaxDerivatives
void setRotation(double rot)
void setScalingName(const std::string &name)
void setBendAngle(double angle, bool variableRadius)
void setElementLength(double length) override
void initialise(PartBunch_t *bunch, double &startField, double &endField) override
void setEntranceAngle(double entranceAngle)
ElementBase * clone() const override
std::string scalingName_m
Definition MultipoleT.h:243
void accept(BeamlineVisitor &visitor) const override
MultipoleTConfig config_m
Definition MultipoleT.h:233
void setAperture(const double &vertAp, const double &horizAp)
void setMaxOrder(size_t orderZ, size_t orderX)
void initialiseTimeDependencies() const
double getScaling(double t) const
void finalise() override
BGeometryBase & getGeometry() override
bool bends() const override
std::shared_ptr< AbstractTimeDependence > scalingTD_m
Definition MultipoleT.h:244
void chooseImplementation()
MultipoleT(const std::string &name)
void setFringeField(const double &s0, const double &lambda_left, const double &lambda_right)
bool apply(const std::shared_ptr< ParticleContainer_t > &pc) override
std::tuple< double, double, double > getFringeField() const
void setEntryOffset(double offset)
void validateConfiguration() const
void setBoundingBoxLength(double boundingBoxLength)
void setTransProfile(const std::vector< double > &profile)
std::unique_ptr< MultipoleTBase > implementation_
Definition MultipoleT.h:247
double getT() const
Get the current simulation time.
Definition PartBunch.h:651
static constexpr unsigned int NumPoles
unsigned int maxXOrder_m
unsigned int maxFOrder_m
unsigned int transverseProfileMaxOrder_m
Kokkos::Array< double, NumPoles > transverseProfile_m