OPALX (Object Oriented Parallel Accelerator Library for Exascal) master (dc2a29eed580)
OPALX
Loading...
Searching...
No Matches
FM2DMagnetoStatic.cpp
Go to the documentation of this file.
2#include "Fields/Fieldmap.hpp"
4#include "Physics/Units.h"
6#include "Utilities/Util.h"
7
8#include <cmath>
9#include <fstream>
10#include <ios>
11
21FM2DMagnetoStatic::FM2DMagnetoStatic(std::string aFilename) : Fieldmap(aFilename) {
22 std::ifstream file;
23 std::string tmpString;
24 double tmpDouble;
25
27
28 // open field map, parse it and disable element on error
29 file.open(Filename_m.c_str());
30 if (file.good()) {
31 bool parsing_passed = true;
32 try {
33 parsing_passed = interpretLine<std::string, std::string>(file, tmpString, tmpString);
34 } catch (GeneralOpalException& e) {
35 parsing_passed = interpretLine<std::string, std::string, std::string>(
36 file, tmpString, tmpString, tmpString);
37
38 tmpString = Util::toUpper(tmpString);
39 if (tmpString != "TRUE" && tmpString != "FALSE")
41 "FM2DMagnetoStatic::FM2DMagnetoStatic",
42 "The third string on the first line of 2D field "
43 "maps has to be either TRUE or FALSE");
44
45 normalize_m = (tmpString == "TRUE");
46 }
47
48 if (tmpString == "ZX") {
49 swap_m = true;
51 parsing_passed =
52 parsing_passed
53 && interpretLine<double, double, int>(file, rbegin_m, rend_m, num_gridpr_m);
55 parsing_passed =
56 parsing_passed
57 && interpretLine<double, double, int>(file, zbegin_m, zend_m, num_gridpz_m);
58 } else if (tmpString == "XZ") {
59 swap_m = false;
61 parsing_passed =
62 parsing_passed
63 && interpretLine<double, double, int>(file, zbegin_m, zend_m, num_gridpz_m);
65 parsing_passed =
66 parsing_passed
67 && interpretLine<double, double, int>(file, rbegin_m, rend_m, num_gridpr_m);
68 } else {
69 std::cerr << "unknown orientation of 2D magnetostatic fieldmap" << std::endl;
70 parsing_passed = false;
71 }
72
73 for (long i = 0; (i < (num_gridpz_m + 1) * (num_gridpr_m + 1)) && parsing_passed; ++i) {
74 parsing_passed =
75 parsing_passed && interpretLine<double, double>(file, tmpDouble, tmpDouble);
76 }
77
78 parsing_passed = parsing_passed && interpreteEOF(file);
79
80 file.close();
81 lines_read_m = 0;
82
83 if (!parsing_passed) {
85 zend_m = zbegin_m - 1e-3;
87 "FM2DMagnetoStatic::FM2DMagnetoStatic",
88 "An error occured when reading the fieldmap '" + Filename_m + "'");
89 } else {
90 // conversion from cm to m
95
98
99 // num spacings -> num grid points
100 num_gridpr_m++;
101 num_gridpz_m++;
102 }
103 } else {
105 zbegin_m = 0.0;
106 zend_m = -1e-3;
107 }
108}
109
111
113 if (FieldstrengthBz_m.extent(0) == 0) {
114 // declare variables and allocate memory
115 std::ifstream in;
116 std::string tmpString;
117
118 const size_t size = num_gridpz_m * num_gridpr_m;
119 FieldstrengthBz_m = Kokkos::DualView<double*>("FieldstrengthBz", size);
120 FieldstrengthBr_m = Kokkos::DualView<double*>("FieldstrengthBr", size);
121
122 auto Bz = FieldstrengthBz_m.view_host();
123 auto Br = FieldstrengthBr_m.view_host();
124
125 // read in and parse field map
126 in.open(Filename_m.c_str());
127 getLine(in, tmpString);
128 getLine(in, tmpString);
129 getLine(in, tmpString);
130
131 if (swap_m) {
132 for (int i = 0; i < num_gridpz_m; i++) {
133 for (int j = 0; j < num_gridpr_m; j++) {
134 interpretLine<double, double>(
135 in, // input stream
136 Br(j * num_gridpz_m + i), // radial component
137 Bz(j * num_gridpz_m + i) // longitudinal component
138 );
139 }
140 }
141 } else {
142 for (int j = 0; j < num_gridpr_m; j++) {
143 for (int i = 0; i < num_gridpz_m; i++) {
144 interpretLine<double, double>(
145 in, // input stream
146 Bz(j * num_gridpz_m + i), // longitudinal component
147 Br(j * num_gridpz_m + i) // radial component
148 );
149 }
150 }
151 }
152 in.close();
153
154 if (normalize_m) {
155 double Bzmax = 0.0;
156 // find maximum field
157 for (int i = 0; i < num_gridpz_m; ++i) {
158 if (std::abs(Bz(i)) > Bzmax) {
159 Bzmax = std::abs(Bz(i));
160 }
161 }
162
163 // normalize field
164 for (size_t i = 0; i < size; ++i) {
165 Bz(i) /= Bzmax;
166 Br(i) /= Bzmax;
167 }
168 }
169
170 FieldstrengthBz_m.modify<Kokkos::HostSpace>();
171 FieldstrengthBz_m.sync<Kokkos::DefaultExecutionSpace>();
172 FieldstrengthBr_m.modify<Kokkos::HostSpace>();
173 FieldstrengthBr_m.sync<Kokkos::DefaultExecutionSpace>();
174
175 *ippl::Info << level3 << typeset_msg("read in fieldmap '" + Filename_m + "'", "info")
176 << endl;
177 }
178}
179
181 if (FieldstrengthBz_m.extent(0) != 0) {
182 FieldstrengthBz_m = Kokkos::DualView<double*>();
183 FieldstrengthBr_m = Kokkos::DualView<double*>();
184
185 *ippl::Info << level3 << typeset_msg("freed fieldmap '" + Filename_m + "'", "info") << endl;
186 }
187}
188
194void FM2DMagnetoStatic::applyField(std::shared_ptr<ParticleContainer_t> pc, double scale) {
195 // Local copies of member variables for use in the lambda function
196 double zbegin = zbegin_m;
197 double zend = zend_m;
198 double rend = rend_m;
199 double hr = hr_m;
200 double hz = hz_m;
201 int num_gridpr = num_gridpr_m;
202 int num_gridpz = num_gridpz_m;
203
204 // Device accessible views
205 auto Bz_device = FieldstrengthBz_m.view_device();
206 auto Br_device = FieldstrengthBr_m.view_device();
207 auto Rview = pc->R.getView();
208 auto Bview = pc->B.getView();
209 const size_t nLocal = pc->getLocalNum();
210
211 Kokkos::parallel_for(
212 "FM2DMagnetoStatic::applyField", nLocal, KOKKOS_LAMBDA(const size_t i) {
213 // Check bounds
214 if (Rview(i)(2) >= zbegin && Rview(i)(2) < zend
215 && sqrt(Rview(i)(0) * Rview(i)(0) + Rview(i)(1) * Rview(i)(1)) < rend) {
216 Vector_t<double, 3> tmpB = 0.0;
218 Rview(i), tmpB, Bz_device, Br_device, hr, hz, zbegin, num_gridpr,
219 num_gridpz);
220 Bview(i) += scale * tmpB;
221 }
222 });
223
224 return;
225}
226
238 if (isInside(R)) {
240 R, B, FieldstrengthBz_m.view_host(), FieldstrengthBr_m.view_host(), hr_m, hz_m,
242 return false;
243 } else {
244 return true;
245 }
246}
247
260 const DiffDirection& /*dir*/) const {
261 throw GeneralOpalException("FM2DMagnetoStatic::getFieldDerivative", "not implemented");
262}
263
264void FM2DMagnetoStatic::getFieldDimensions(double& zBegin, double& zEnd) const {
265 zBegin = zbegin_m;
266 zEnd = zend_m;
267}
268
270 double& xIni, double& xFinal, double& yIni, double& yFinal, double& zIni,
271 double& zFinal) const {
272 const double radius = std::max(std::abs(rbegin_m), std::abs(rend_m));
273 xIni = -radius;
274 xFinal = radius;
275 yIni = -radius;
276 yFinal = radius;
277 zIni = zbegin_m;
278 zFinal = zend_m;
279}
280
282 if (swap_m)
283 swap_m = false;
284 else
285 swap_m = true;
286}
287
288void FM2DMagnetoStatic::getInfo(Inform* msg) {
289 (*msg) << Filename_m << " (2D magnetostatic); zini= " << zbegin_m << " m; zfinal= " << zend_m
290 << " m;" << endl;
291}
292
294 throw GeneralOpalException("FM2DMagnetoStatic::getFrequency", "not implemented");
295 return 0.0;
296}
297
298void FM2DMagnetoStatic::setFrequency(double /*freq*/) {
299 throw GeneralOpalException("FM2DMagnetoStatic::setFrequency", "not implemented");
300 return;
301}
ippl::Vector< T, Dim > Vector_t
@ T2DMagnetoStatic
Definition Fieldmap.h:28
DiffDirection
Definition Fieldmap.h:54
Template PIC bunch: IPPL PicManager, shared field mesh/solver, and multiple particle containers.
virtual void swap() override
Swap coordinates.
virtual bool getFieldstrength(const Vector_t< double, 3 > &R, Vector_t< double, 3 > &E, Vector_t< double, 3 > &B) const override
Get the field strength at a given point.
virtual double getFrequency() const override
Get the frequency.
virtual void getFieldDimensions(double &zBegin, double &zEnd) const override
Get the longitudinal dimensions of the field.
void applyField(std::shared_ptr< ParticleContainer_t > pc, double scale=1.0) override
Apply the FM to all the particles.
virtual void getInfo(Inform *msg) override
Print info about the field map.
void freeMap() override
Pure virtual method to free the map data.
void readMap() override
Pure virtual method to read the map data. Called by the public static readMap().
Kokkos::DualView< double * > FieldstrengthBz_m
Fieldstrengths.
static KOKKOS_INLINE_FUNCTION void computeField(const Vector_t< double, 3 > &R, Vector_t< double, 3 > &B, const ViewType &Bz, const ViewType &Br, double hr, double hz, double zbegin, int num_gridpr, int num_gridpz)
Computes the magnetic field B at the position R by interpolating from the fieldmap specified by Bz,...
FM2DMagnetoStatic(std::string aFilename)
Constructor for 2D magnetostatic field map. Parses the file header to read grid parameters:
virtual bool getFieldDerivative(const Vector_t< double, 3 > &R, Vector_t< double, 3 > &E, Vector_t< double, 3 > &B, const DiffDirection &dir) const override
Get the field derivative with respect to a direction.
virtual void setFrequency(double freq) override
Set the frequency.
bool isInside(const Vector_t< double, 3 > &r) const override
Checks if the given coordinate is inside the volume covered by the fieldmap.
double zbegin_m
Z Bounds relative to element edge.
double rbegin_m
Radius Bounds.
Kokkos::DualView< double * > FieldstrengthBr_m
Abstract base class for all field maps. It acts as a factory for creating specific field map types ba...
Definition Fieldmap.h:62
MapType Type
Definition Fieldmap.h:231
bool interpreteEOF(std::ifstream &in)
Definition Fieldmap.cpp:436
void disableFieldmapWarning()
Definition Fieldmap.cpp:489
bool normalize_m
Definition Fieldmap.h:236
int lines_read_m
Definition Fieldmap.h:234
static std::string typeset_msg(const std::string &msg, const std::string &title)
Definition Fieldmap.cpp:527
std::string Filename_m
Definition Fieldmap.h:233
void getLine(std::ifstream &in, std::string &buffer)
Definition Fieldmap.h:237
void noFieldmapWarning()
Definition Fieldmap.cpp:496
constexpr double cm2m
Definition Units.h:35
std::string toUpper(const std::string &str)
Definition Util.cpp:141