OPALX (Object Oriented Parallel Accelerator Library for Exascal) master (dc2a29eed580)
OPALX
Loading...
Searching...
No Matches
FM2DDynamic.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
12FM2DDynamic::FM2DDynamic(const std::string& filename) : Fieldmap(filename) {
13 std::ifstream file;
14 std::string tmpString;
15 double tmpDouble;
16
17 Type = T2DDynamic; // I can put ut also as Type(T2DDynamic) in the header file.
18
19 // open field map, parse it and disable element on error
20 file.open(Filename_m.c_str());
21 if (file.good()) {
22 bool parsing_passed = true;
23 try {
24 parsing_passed = interpretLine<std::string, std::string>(file, tmpString, tmpString);
25 } catch (GeneralOpalException& e) {
26 parsing_passed = interpretLine<std::string, std::string, std::string>(
27 file, tmpString, tmpString, tmpString);
28
29 tmpString = Util::toUpper(tmpString);
30 if (tmpString != "TRUE" && tmpString != "FALSE")
32 "FM2DDynamic::FM2DDynamic",
33 "The third string on the first line of 2D field "
34 "maps has to be either TRUE or FALSE");
35
36 normalize_m = (tmpString == "TRUE");
37 }
38
39 if (tmpString == "ZX") {
40 swap_m = true;
42 parsing_passed =
43 parsing_passed
44 && interpretLine<double, double, int>(file, rbegin_m, rend_m, num_gridpr_m);
46 parsing_passed = parsing_passed && interpretLine<double>(file, frequency_m);
48 parsing_passed =
49 parsing_passed
50 && interpretLine<double, double, int>(file, zbegin_m, zend_m, num_gridpz_m);
51 } else if (tmpString == "XZ") {
52 swap_m = false;
54 parsing_passed =
55 parsing_passed
56 && interpretLine<double, double, int>(file, zbegin_m, zend_m, num_gridpz_m);
58 parsing_passed = parsing_passed && interpretLine<double>(file, frequency_m);
60 parsing_passed =
61 parsing_passed
62 && interpretLine<double, double, int>(file, rbegin_m, rend_m, num_gridpr_m);
63 } else {
64 std::cerr << "unknown orientation of 2D dynamic fieldmap" << std::endl;
65 parsing_passed = false;
66 zbegin_m = 0.0;
67 zend_m = -1e-3;
68 }
69
70 for (long i = 0; (i < (num_gridpz_m + 1) * (num_gridpr_m + 1)) && parsing_passed; ++i) {
71 parsing_passed = parsing_passed
72 && interpretLine<double, double, double, double>(
73 file, tmpDouble, tmpDouble, tmpDouble, tmpDouble);
74 }
75
76 parsing_passed = parsing_passed && interpreteEOF(file);
77
78 file.close();
79 lines_read_m = 0;
80
81 if (!parsing_passed) {
83 zend_m = zbegin_m - 1e-3;
85 "FM2DDynamic::FM2DDynamic",
86 "An error occured when reading the fieldmap '" + Filename_m + "'");
87 } else {
88 // convert MHz to Hz and frequency to angular frequency
90
91 // convert cm to m
96
99
100 // num spacings -> num grid points
101 num_gridpr_m++;
102 num_gridpz_m++;
103 }
104 } else {
106 zbegin_m = 0.0;
107 zend_m = -1e-3;
108 }
109}
110
112
114 if (FieldstrengthEz_m.extent(0) == 0) {
115 // declare variables and allocate memory
116 std::ifstream in;
117 std::string tmpString;
118 double tmpDouble, Ezmax = 0.0;
119
120 const size_t size = num_gridpz_m * num_gridpr_m;
121 FieldstrengthEz_m = Kokkos::DualView<double*>("FieldstrengthEz", size);
122 FieldstrengthEr_m = Kokkos::DualView<double*>("FieldstrengthEr", size);
123 FieldstrengthBt_m = Kokkos::DualView<double*>("FieldstrengthBt", size);
124
125 auto Ez = FieldstrengthEz_m.view_host();
126 auto Er = FieldstrengthEr_m.view_host();
127 auto Bt = FieldstrengthBt_m.view_host();
128
129 // read in field map and parse it
130 in.open(Filename_m.c_str());
131 getLine(in, tmpString);
132 getLine(in, tmpString);
133 getLine(in, tmpString);
134 getLine(in, tmpString);
135
136 if (swap_m) {
137 for (int i = 0; i < num_gridpz_m; i++) {
138 for (int j = 0; j < num_gridpr_m; j++) {
139 interpretLine<double, double, double, double>(
140 in, Er(j * num_gridpz_m + i), Ez(j * num_gridpz_m + i),
141 Bt(j * num_gridpz_m + i), tmpDouble);
142 }
143 }
144 } else {
145 for (int j = 0; j < num_gridpr_m; j++) {
146 for (int i = 0; i < num_gridpz_m; i++) {
147 interpretLine<double, double, double, double>(
148 in, Ez(j * num_gridpz_m + i), Er(j * num_gridpz_m + i), tmpDouble,
149 Bt(j * num_gridpz_m + i));
150 }
151 }
152 }
153 in.close();
154
155 if (normalize_m) {
156 // find maximum field
157 // Is (i < num_gridpz_m) enough or should it be (i < size)?
158 for (size_t i = 0; i < size; ++i) {
159 if (std::abs(Ez(i)) > Ezmax) {
160 Ezmax = std::abs(Ez(i));
161 }
162 }
163 } else {
164 Ezmax = 1.0;
165 }
166
167 // Precompute scaling factor once
168 double const scaleE = 1.e6 / Ezmax; // MV/m -> V/m conversion
169 double const scaleB = Physics::mu_0 / Ezmax; // H -> B conversion
170
171 for (size_t i = 0; i < size; i++) {
172 Ez(i) *= scaleE;
173 Er(i) *= scaleE;
174 Bt(i) *= scaleB;
175 }
176
177 FieldstrengthEz_m.modify<Kokkos::HostSpace>();
178 FieldstrengthEz_m.sync<Kokkos::DefaultExecutionSpace>();
179
180 FieldstrengthEr_m.modify<Kokkos::HostSpace>();
181 FieldstrengthEr_m.sync<Kokkos::DefaultExecutionSpace>();
182
183 FieldstrengthBt_m.modify<Kokkos::HostSpace>();
184 FieldstrengthBt_m.sync<Kokkos::DefaultExecutionSpace>();
185
186 Inform m("FM2DDynamic::readMap");
187 m << level3 << "Read in fieldmap '" << Filename_m << "'" << endl;
188 }
189}
190
192 if (FieldstrengthEz_m.extent(0) != 0) {
193 FieldstrengthEz_m = Kokkos::DualView<double*>();
194 FieldstrengthEr_m = Kokkos::DualView<double*>();
195 FieldstrengthBt_m = Kokkos::DualView<double*>();
196
197 Inform m("FM2DDynamic::freeMap");
198 m << level3 << "Freed fieldmap '" << Filename_m << "'" << endl;
199 }
200}
201
208void FM2DDynamic::applyField(std::shared_ptr<ParticleContainer_t> pc, double) {
209 // Local copies of member variables for use in the lambda function
210 double zbegin = zbegin_m;
211 double zend = zend_m;
212 double rend = rend_m;
213 double hr = hr_m;
214 double hz = hz_m;
215 int num_gridpr = num_gridpr_m;
216 int num_gridpz = num_gridpz_m;
217
218 // Device accessible views
219 auto Ez_device = FieldstrengthEz_m.view_device();
220 auto Er_device = FieldstrengthEr_m.view_device();
221 auto Bt_device = FieldstrengthBt_m.view_device();
222
223 auto Rview = pc->R.getView();
224 auto Eview = pc->E.getView();
225 auto Bview = pc->B.getView();
226
227 const size_t nLocal = pc->getLocalNum();
228
229 Kokkos::parallel_for(
230 "FM2DDynamic::applyField", nLocal, KOKKOS_LAMBDA(const size_t i) {
231 if (Rview(i)(2) >= zbegin && Rview(i)(2) < zend
232 && sqrt(Rview(i)(0) * Rview(i)(0) + Rview(i)(1) * Rview(i)(1)) < rend) {
234 Rview(i), Eview(i), Bview(i), Ez_device, Er_device, Bt_device, hr, hz,
235 zbegin, num_gridpr, num_gridpz);
236 }
237 });
238}
239
241 std::shared_ptr<ParticleContainer_t> pc, double electricScale, double magneticScale,
242 double startField, double endField) {
243 double zbegin = zbegin_m;
244 double zend = zend_m;
245 double rend = rend_m;
246 double hr = hr_m;
247 double hz = hz_m;
248 int num_gridpr = num_gridpr_m;
249 int num_gridpz = num_gridpz_m;
250
251 auto Ez_device = FieldstrengthEz_m.view_device();
252 auto Er_device = FieldstrengthEr_m.view_device();
253 auto Bt_device = FieldstrengthBt_m.view_device();
254
255 auto Rview = pc->R.getView();
256 auto Eview = pc->E.getView();
257 auto Bview = pc->B.getView();
258
259 const size_t nLocal = pc->getLocalNum();
260
261 Kokkos::parallel_for(
262 "FM2DDynamic::applyRFField", nLocal, KOKKOS_LAMBDA(const size_t i) {
263 const auto& R = Rview(i);
264
265 if (R(2) >= startField && R(2) < endField && R(2) >= zbegin && R(2) < zend
266 && sqrt(R(0) * R(0) + R(1) * R(1)) < rend) {
267 Vector_t<double, 3> tmpE(0.0), tmpB(0.0);
268
270 R, tmpE, tmpB, Ez_device, Er_device, Bt_device, hr, hz, zbegin,
271 num_gridpr, num_gridpz);
272
273 Eview(i) += electricScale * tmpE;
274 Bview(i) += magneticScale * tmpB;
275 }
276 });
277}
278
290 if (isInside(R)) {
292 R, E, B, FieldstrengthEz_m.view_host(), FieldstrengthEr_m.view_host(),
294
295 return false;
296 } else {
297 return true;
298 }
299}
300
313 const DiffDirection& /*dir*/) const {
314 throw GeneralOpalException("FM2DDynamic::getFieldDerivative", "not implemented");
315}
316
317void FM2DDynamic::getFieldDimensions(double& zBegin, double& zEnd) const {
318 zBegin = zbegin_m;
319 zEnd = zend_m;
320}
321
323 double& /*xIni*/, double& /*xFinal*/, double& /*yIni*/, double& /*yFinal*/,
324 double& /*zIni*/, double& /*zFinal*/) const {
325 throw GeneralOpalException("FM2DDynamic::getFieldDimensions", "not implemented");
326}
327
329
330void FM2DDynamic::getInfo(Inform* msg) {
331 (*msg) << Filename_m << " (2D dynamic); zini= " << zbegin_m << " m; zfinal= " << zend_m << " m;"
332 << endl;
333}
334
335double FM2DDynamic::getFrequency() const { return frequency_m; }
336
337void FM2DDynamic::setFrequency(double freq) { frequency_m = freq; }
338
339void FM2DDynamic::getOnaxisEz(std::vector<std::pair<double, double>>& F) {
340 double dz = (zend_m - zbegin_m) / (num_gridpz_m - 1);
341 F.resize(num_gridpz_m);
342
343 auto Ez = FieldstrengthEz_m.view_host(); // Access host view
344
345 for (int i = 0; i < num_gridpz_m; ++i) {
346 F[i].first = dz * i;
347 F[i].second = Ez(i) / 1e6; // Convert V/m -> MV/m
348 }
349}
ippl::Vector< T, Dim > Vector_t
@ T2DDynamic
Definition Fieldmap.h:24
DiffDirection
Definition Fieldmap.h:54
Template PIC bunch: IPPL PicManager, shared field mesh/solver, and multiple particle containers.
bool isInside(const Vector_t< double, 3 > &r) const override
Checks if the given coordinate is inside the volume covered by the fieldmap.
Definition FM2DDynamic.h:88
double frequency_m
FM2DDynamic(const std::string &filename)
Kokkos::DualView< double * > FieldstrengthEr_m
Kokkos::DualView< double * > FieldstrengthEz_m
Fieldstrengths.
double rbegin_m
Radius Bounds.
Kokkos::DualView< double * > FieldstrengthBt_m
virtual void swap() override
Swap coordinates.
void applyRFField(std::shared_ptr< ParticleContainer_t > pc, double electricScale, double magneticScale, double startField, double endField)
Apply the RF-scaled dynamic field map to all particles.
void freeMap() override
Pure virtual method to free the map data.
double rend_m
double hz_m
Grid.
double zbegin_m
Z Bounds relative to element edge.
virtual double getFrequency() const override
Get the frequency.
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 getInfo(Inform *msg) override
Print info about the field map.
void readMap() override
Pure virtual method to read the map data. Called by the public static readMap().
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) override
Apply the FM to all the particles.
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.
double zend_m
virtual void getOnaxisEz(std::vector< std::pair< double, double > > &F) override
virtual void setFrequency(double freq) override
Set the frequency.
static KOKKOS_INLINE_FUNCTION void computeField(const Vector_t< double, 3 > &R, Vector_t< double, 3 > &E, Vector_t< double, 3 > &B, const ViewType &Ez, const ViewType &Er, const ViewType &Bt, double hr_m, double hz_m, double zbegin_m, int num_gridpr_m, int num_gridpz_m)
Definition FM2DDynamic.h:93
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
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 two_pi
The value of.
Definition Physics.h:40
constexpr double mu_0
The permeability of vacuum in Vs/Am.
Definition Physics.h:63
constexpr double MHz2Hz
Definition Units.h:113
constexpr double cm2m
Definition Units.h:35
std::string toUpper(const std::string &str)
Definition Util.cpp:141