44#include <gtest/gtest.h>
75 std::string writeAstra1DFieldmap(
76 const std::string& path,
const std::vector<double>& z_m,
77 const std::vector<double>& ez_MVpm,
int accuracy = 8,
double freq_MHz = 100.0,
78 bool normalize =
true) {
79 EXPECT_EQ(z_m.size(), ez_MVpm.size());
81 std::ofstream f(path);
82 f <<
"AstraDynamic " << accuracy <<
" " << (normalize ?
"TRUE" :
"FALSE") <<
"\n";
83 f << freq_MHz <<
"\n";
85 for (
size_t i = 0; i < z_m.size(); ++i) {
86 f << z_m[i] <<
" " << ez_MVpm[i] <<
"\n";
95 std::string writeConstantAstra1DFieldmap(
96 const std::string& path,
double zbegin_m,
double zend_m,
int nz,
double ez_MVpm,
97 int accuracy = 8,
double freq_MHz = 100.0,
bool normalize =
true) {
98 std::vector<double> z(nz);
99 std::vector<double> ez(nz, ez_MVpm);
101 const double dz = (zend_m - zbegin_m) / (nz - 1);
102 for (
int i = 0; i < nz; ++i) {
103 z[i] = zbegin_m + i * dz;
106 return writeAstra1DFieldmap(path, z, ez, accuracy, freq_MHz, normalize);
118 char** argv =
nullptr;
119 ippl::initialize(argc, argv);
123 Fieldmap::clearDictionary();
128 tmpDir_ = std::filesystem::temp_directory_path() /
"opalx_astra1d_test";
129 std::filesystem::create_directories(
tmpDir_);
133 Fieldmap::clearDictionary();
134 std::filesystem::remove_all(
tmpDir_);
137 std::string
tmpFile(
const std::string& name)
const {
return (
tmpDir_ / name).string(); }
146 const double zb = 0.0;
147 const double ze = 0.10;
148 const double freq = 100.0;
152 writeConstantAstra1DFieldmap(tmpFile(
"parse.map"), zb, ze, nz, 1.0, 8, freq,
true);
154 Fieldmap* fm = Fieldmap::getFieldmap(fname);
155 ASSERT_NE(fm,
nullptr);
158 Fieldmap::readMap(fname);
160 double zBegin = 0.0, zEnd = 0.0;
163 EXPECT_NEAR(zBegin, zb, 1e-12);
164 EXPECT_NEAR(zEnd, ze, 1e-12);
171 const double freq = 100.0;
174 writeConstantAstra1DFieldmap(tmpFile(
"freq.map"), 0.0, 0.10, 5, 1.0, 8, freq,
true);
176 auto* fm =
dynamic_cast<Astra1DDynamic*
>(Fieldmap::getFieldmap(fname));
177 ASSERT_NE(fm,
nullptr);
179 Fieldmap::readMap(fname);
182 EXPECT_NEAR(fm->getFrequency(), expected, 1e-6);
190 writeConstantAstra1DFieldmap(tmpFile(
"inside.map"), 0.0, 0.10, 5, 1.0, 8, 100.0,
true);
192 auto* fm =
dynamic_cast<Astra1DDynamic*
>(Fieldmap::getFieldmap(fname));
193 ASSERT_NE(fm,
nullptr);
195 EXPECT_TRUE(fm->isInside({0.0, 0.0, 0.00}));
196 EXPECT_TRUE(fm->isInside({0.0, 0.0, 0.05}));
197 EXPECT_FALSE(fm->isInside({0.0, 0.0, 0.10}));
198 EXPECT_FALSE(fm->isInside({0.0, 0.0, -0.01}));
212 std::string fname = writeConstantAstra1DFieldmap(
213 tmpFile(
"uniform.map"), 0.0, 0.10, nz, 3.0, 8, 100.0,
true);
215 Fieldmap* fm = Fieldmap::getFieldmap(fname);
216 ASSERT_NE(fm,
nullptr);
218 Fieldmap::readMap(fname);
226 EXPECT_FALSE(outside);
228 EXPECT_NEAR(E[0], 0.0, 1e-10);
229 EXPECT_NEAR(E[1], 0.0, 1e-10);
232 EXPECT_NEAR(E[2], 1.0e6, 1e-4);
235 EXPECT_NEAR(B[0], 0.0, 1e-10);
236 EXPECT_NEAR(B[1], 0.0, 1e-10);
237 EXPECT_NEAR(B[2], 0.0, 1e-10);
246 std::string fname = writeConstantAstra1DFieldmap(
247 tmpFile(
"nonorm.map"), 0.0, 0.10, nz, 3.0, 8, 100.0,
false);
249 Fieldmap* fm = Fieldmap::getFieldmap(fname);
250 ASSERT_NE(fm,
nullptr);
252 Fieldmap::readMap(fname);
260 EXPECT_FALSE(outside);
263 EXPECT_NEAR(E[2], 3.0e6, 1e-3);
271 writeConstantAstra1DFieldmap(tmpFile(
"outside.map"), 0.0, 0.10, 9, 1.0, 8, 100.0,
true);
273 Fieldmap* fm = Fieldmap::getFieldmap(fname);
274 ASSERT_NE(fm,
nullptr);
276 Fieldmap::readMap(fname);
285 EXPECT_TRUE(outside);
286 EXPECT_NEAR(E[0], 1.0, 1e-15);
287 EXPECT_NEAR(E[1], 2.0, 1e-15);
288 EXPECT_NEAR(E[2], 3.0, 1e-15);
289 EXPECT_NEAR(B[0], 4.0, 1e-15);
290 EXPECT_NEAR(B[1], 5.0, 1e-15);
291 EXPECT_NEAR(B[2], 6.0, 1e-15);
301 EXPECT_TRUE(outside);
302 EXPECT_NEAR(E[0], 1.0, 1e-15);
303 EXPECT_NEAR(E[1], 2.0, 1e-15);
304 EXPECT_NEAR(E[2], 3.0, 1e-15);
305 EXPECT_NEAR(B[0], 4.0, 1e-15);
306 EXPECT_NEAR(B[1], 5.0, 1e-15);
307 EXPECT_NEAR(B[2], 6.0, 1e-15);
318 writeConstantAstra1DFieldmap(tmpFile(
"accum.map"), 0.0, 0.10, nz, 1.0, 8, 100.0,
true);
320 Fieldmap* fm = Fieldmap::getFieldmap(fname);
321 ASSERT_NE(fm,
nullptr);
323 Fieldmap::readMap(fname);
331 EXPECT_NEAR(E[0], 1.0, 1e-10);
332 EXPECT_NEAR(E[1], 2.0, 1e-10);
335 EXPECT_NEAR(E[2], 3.0 + 1.0e6, 1e-4);
338 EXPECT_NEAR(B[0], 4.0, 1e-10);
339 EXPECT_NEAR(B[1], 5.0, 1e-10);
340 EXPECT_NEAR(B[2], 6.0, 1e-10);
348 writeConstantAstra1DFieldmap(tmpFile(
"deriv.map"), 0.0, 0.10, 9, 2.0, 8, 100.0,
true);
350 auto* fm =
dynamic_cast<Astra1DDynamic*
>(Fieldmap::getFieldmap(fname));
351 ASSERT_NE(fm,
nullptr);
353 Fieldmap::readMap(fname);
359 bool outside = fm->getFieldDerivative(R, E, B,
DZ);
361 EXPECT_FALSE(outside);
362 EXPECT_NEAR(E[2], 0.0, 1e-6);
371 const std::string fname = tmpFile(
"onaxis_legacy.map");
374 std::ofstream out(fname);
375 ASSERT_TRUE(out.good());
380 out <<
"AstraDynamic 8\n";
383 for (
int i = 0; i < nz; ++i) {
384 const double z = 0.10 * double(i) / double(nz - 1);
385 out << std::setprecision(16) << z <<
" " << 3.0 <<
"\n";
389 auto* fm =
dynamic_cast<Astra1DDynamic*
>(Fieldmap::getFieldmap(fname));
390 ASSERT_NE(fm,
nullptr);
392 ASSERT_NO_THROW(Fieldmap::readMap(fname));
394 std::vector<std::pair<double, double>> F;
395 ASSERT_NO_THROW(fm->getOnaxisEz(F));
397 ASSERT_EQ(F.size(), nz);
399 EXPECT_NEAR(F.front().first, 0.0, 1e-12);
400 EXPECT_NEAR(F.back().first, 0.10, 1e-12);
402 for (
int i = 0; i < nz; ++i) {
403 EXPECT_NEAR(F[i].second, 1.0, 1e-12);
413 Kokkos::View<double*, Kokkos::HostSpace> coefs(
"coefs", 3);
422 Astra1DDynamic::computeField(
430 EXPECT_NEAR(E[0], 0.0, 1e-12);
431 EXPECT_NEAR(E[1], 0.0, 1e-12);
432 EXPECT_NEAR(E[2], 1.0, 1e-12);
434 EXPECT_NEAR(B[0], 0.0, 1e-12);
435 EXPECT_NEAR(B[1], 0.0, 1e-12);
443 writeConstantAstra1DFieldmap(tmpFile(
"swap.map"), 0.0, 0.10, 5, 1.0, 8, 100.0,
true);
445 auto* fm =
dynamic_cast<Astra1DDynamic*
>(Fieldmap::getFieldmap(fname));
446 ASSERT_NE(fm,
nullptr);
448 EXPECT_NO_THROW(fm->swap());
456 writeConstantAstra1DFieldmap(tmpFile(
"info.map"), 0.0, 0.10, 5, 1.0, 8, 100.0,
true);
458 Fieldmap* fm = Fieldmap::getFieldmap(fname);
459 ASSERT_NE(fm,
nullptr);
462 EXPECT_NO_THROW(fm->
getInfo(&msg));
469 std::string fname = tmpFile(
"nonexistent.map");
478 writeConstantAstra1DFieldmap(tmpFile(
"cache.map"), 0.0, 0.10, 5, 1.0, 8, 100.0,
true);
480 Fieldmap* fm1 = Fieldmap::getFieldmap(fname);
481 Fieldmap* fm2 = Fieldmap::getFieldmap(fname);
491 writeConstantAstra1DFieldmap(tmpFile(
"cycle.map"), 0.0, 0.10, 9, 1.0, 8, 100.0,
true);
493 Fieldmap* fm = Fieldmap::getFieldmap(fname);
494 ASSERT_NE(fm,
nullptr);
503 EXPECT_NE(E[2], 0.0);
512 EXPECT_NE(E[2], 0.0);
519 Kokkos::View<double*, Kokkos::HostSpace> coefs(
"coefs", 3);
528 Astra1DDynamic::computeTravelingWaveField(
547 EXPECT_NEAR(E[2], 2.0, 1e-12);
554 Kokkos::View<double*, Kokkos::HostSpace> coefs(
"coefs", 3);
564 const double periodLength = 0.05;
565 const double startCoreField = 0.025;
566 const double cellLength = 0.05;
567 const double startExitField = 0.125;
568 const double mappedStartExit = 0.05;
569 const double elementLength = 0.175;
571 Astra1DDynamic::computeTravelingWaveField(
582 startCoreField, startExitField, mappedStartExit, periodLength, cellLength,
586 EXPECT_NEAR(E[2], 4.0, 1e-12);
593 Kokkos::View<double*, Kokkos::HostSpace> coefs(
"coefs", 3);
603 const double periodLength = 0.05;
604 const double startCoreField = 0.025;
605 const double cellLength = 0.05;
606 const double startExitField = 0.125;
607 const double mappedStartExit = 0.05;
608 const double elementLength = 0.175;
610 Astra1DDynamic::computeTravelingWaveField(
621 startCoreField, startExitField, mappedStartExit, periodLength, cellLength,
624 EXPECT_NEAR(E[2], 3.0, 1e-12);
631 Kokkos::View<double*, Kokkos::HostSpace> coefs(
"coefs", 3);
640 Astra1DDynamic::computeTravelingWaveField(
641 R, E, B, coefs, 0.0, 0.10, 0.20, 1.0, 2, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.05,
642 0.20, 0.0, 0.10, 0.05, 0.30);
644 EXPECT_NEAR(E[0], 1.0, 1e-12);
645 EXPECT_NEAR(E[1], 2.0, 1e-12);
646 EXPECT_NEAR(E[2], 3.0, 1e-12);
647 EXPECT_NEAR(B[0], 4.0, 1e-12);
648 EXPECT_NEAR(B[1], 5.0, 1e-12);
649 EXPECT_NEAR(B[2], 6.0, 1e-12);
656 Kokkos::View<double*, Kokkos::HostSpace> coefs(
"coefs", 3);
665 Astra1DDynamic::computeRFField(
678 EXPECT_NEAR(E[0], 0.0, 1e-12);
679 EXPECT_NEAR(E[1], 0.0, 1e-12);
680 EXPECT_NEAR(E[2], 2.0, 1e-12);
682 EXPECT_NEAR(B[0], 0.0, 1e-12);
683 EXPECT_NEAR(B[1], 0.0, 1e-12);
684 EXPECT_NEAR(B[2], 0.0, 1e-12);
691 Kokkos::View<double*, Kokkos::HostSpace> coefs(
"coefs", 3);
700 Astra1DDynamic::computeRFField(
713 EXPECT_NEAR(E[0], 1.0, 1e-12);
714 EXPECT_NEAR(E[1], 2.0, 1e-12);
715 EXPECT_NEAR(E[2], 3.0, 1e-12);
717 EXPECT_NEAR(B[0], 4.0, 1e-12);
718 EXPECT_NEAR(B[1], 5.0, 1e-12);
719 EXPECT_NEAR(B[2], 6.0, 1e-12);
726 Kokkos::View<double*, Kokkos::HostSpace> coefs(
"coefs", 3);
735 Astra1DDynamic::computeRFField(
748 EXPECT_NEAR(E[0], 1.0, 1e-12);
749 EXPECT_NEAR(E[1], 2.0, 1e-12);
750 EXPECT_NEAR(E[2], 3.0, 1e-12);
752 EXPECT_NEAR(B[0], 4.0, 1e-12);
753 EXPECT_NEAR(B[1], 5.0, 1e-12);
754 EXPECT_NEAR(B[2], 6.0, 1e-12);
ippl::Vector< T, Dim > Vector_t
Template PIC bunch: IPPL PicManager, shared field mesh/solver, and multiple particle containers.
TEST_F(Astra1DDynamicTest, ParseAndDimensions)
std::string tmpFile(const std::string &name) const
static void SetUpTestSuite()
static void TearDownTestSuite()
std::filesystem::path tmpDir_
Abstract base class for all field maps. It acts as a factory for creating specific field map types ba...
virtual bool getFieldstrength(const Vector_t< double, 3 > &R, Vector_t< double, 3 > &E, Vector_t< double, 3 > &B) const =0
Get the field strength at a given point.
virtual void getInfo(Inform *msg)=0
Print info about the field map.
virtual void getFieldDimensions(double &zBegin, double &zEnd) const =0
Get the longitudinal dimensions of the field.
static void freeMap(std::string Filename)
Decrease reference count or delete field map if unused.
static void readMap(std::string Filename)
Trigger the actual reading of the field map data.
constexpr double two_pi
The value of.