43namespace fs = std::filesystem;
45#define REGISTER_PARSE_TYPE(X) template <> struct _Fieldmap::TypeParseTraits<X> \
46 { static const char* name; } ; const char* _Fieldmap::TypeParseTraits<X>::name = #X
49 std::map<std::string, FieldmapDescription>::iterator position =
FieldmapDictionary.find(Filename);
51 (*position).second.RefCounter++;
52 return (*position).second.Map;
55 std::pair<std::map<std::string, FieldmapDescription>::iterator,
bool> position;
72 return (*position.first).second.Map;
89 return (*position.first).second.Map;
106 return (*position.first).second.Map;
123 return (*position.first).second.Map;
140 return (*position.first).second.Map;
157 return (*position.first).second.Map;
166 return (*position.first).second.Map;
175 return (*position.first).second.Map;
184 return (*position.first).second.Map;
193 return (*position.first).second.Map;
202 return (*position.first).second.Map;
211 return (*position.first).second.Map;
219 return (*position.first).second.Map;
227 return (*position.first).second.Map;
235 return (*position.first).second.Map;
252 return (*position.first).second.Map;
257 "Couldn't determine type of fieldmap in file \"" + Filename +
"\"");
263 std::vector<std::string> name_list;
265 name_list.push_back((*it).first);
277 it->second.Map.reset();
283 char magicnumber[5] =
" ";
288 if (Filename ==
"1DPROFILE1-DEFAULT")
291 if (Filename.empty())
293 "No field map file specified");
295 if (!fs::exists(Filename))
297 "File '" + Filename +
"' doesn't exist");
299 std::ifstream File(Filename.c_str());
301 std::cerr <<
"could not open file " << Filename << std::endl;
306 std::istringstream interpreter(buffer, std::istringstream::in);
308 interpreter.read(magicnumber, 4);
310 if (std::strcmp(magicnumber,
"3DDy") == 0)
313 if (std::strcmp(magicnumber,
"3DMa") == 0) {
314 char tmpString[21] =
" ";
315 interpreter.read(tmpString, 20);
317 if (std::strcmp(tmpString,
"gnetoStatic_Extended") == 0)
323 if (std::strcmp(magicnumber,
"3DEl") == 0)
326 if (std::strcmp(magicnumber,
"2DDy") == 0) {
332 if (std::strcmp(magicnumber,
"2DMa") == 0) {
338 if (std::strcmp(magicnumber,
"2DEl") == 0) {
344 if (std::strcmp(magicnumber,
"1DDy") == 0)
347 if (std::strcmp(magicnumber,
"1DMa") == 0)
350 if (std::strcmp(magicnumber,
"1DPr") == 0) {
359 if (std::strcmp(magicnumber,
"1DEl") == 0)
362 if (std::strcmp(magicnumber,
"\211HDF") == 0) {
369 h5_size_t len_name =
sizeof(
name);
370 h5_prop_t props = H5CreateFileProp ();
372 h5err = H5SetPropFileMPIOCollective (props, &comm);
374 h5_file_t file = H5OpenFile (Filename.c_str(), H5_O_RDONLY, props);
375 PAssert (file != (h5_file_t)H5_ERR);
378 h5err = H5SetStep(file, 0);
381 h5_int64_t num_fields = H5BlockGetNumFields(file);
382 PAssert (num_fields != H5_ERR);
385 for (h5_ssize_t i = 0; i < num_fields; ++ i) {
386 h5err = H5BlockGetFieldInfo(
387 file, (h5_size_t)i,
name, len_name,
nullptr,
nullptr,
nullptr,
nullptr);
390 if (std::strcmp(
name,
"Bfield") == 0) {
393 }
else if (std::strcmp(
name,
"Hfield") == 0) {
398 h5err = H5CloseFile(file);
404 if (std::strcmp(magicnumber,
"Astr") == 0) {
405 char tmpString[3] =
" ";
406 interpreter.read(tmpString, 2);
407 if (std::strcmp(tmpString,
"aE") == 0) {
410 if (std::strcmp(tmpString,
"aM") == 0) {
413 if (std::strcmp(tmpString,
"aD") == 0) {
423 std::map<std::string, FieldmapDescription>::iterator position =
FieldmapDictionary.find(Filename);
425 if (!(*position).second.read) {
426 (*position).second.Map->readMap();
427 (*position).second.read =
true;
432 std::map<std::string, FieldmapDescription>::iterator position =
FieldmapDictionary.find(Filename);
437 if ((*position).second.RefCounter > 0) {
438 (*position).second.RefCounter--;
441 if ((*position).second.RefCounter == 0) {
442 (*position).second.Map.reset();
449 std::pair<double, double> fieldDimensions,
451 const std::vector<double> &fourierCoefficients,
452 gsl_spline *splineCoefficients,
453 gsl_interp_accel *splineAccelerator) {
454 double length = fieldDimensions.second - fieldDimensions.first;
455 unsigned int sizeSampling = std::round(length / deltaZ);
456 std::vector<double> zSampling(sizeSampling);
457 zSampling[0] = fieldDimensions.first;
458 for (
unsigned int i = 1; i < sizeSampling; ++ i) {
459 zSampling[i] = zSampling[i-1] + deltaZ;
461 checkMap(accuracy, length, zSampling, fourierCoefficients, splineCoefficients, splineAccelerator);
466 const std::vector<double> &zSampling,
467 const std::vector<double> &fourierCoefficients,
468 gsl_spline *splineCoefficients,
469 gsl_interp_accel *splineAccelerator) {
471 double maxDiff = 0.0;
473 double ezSquare = 0.0;
474 size_t lastDot =
Filename_m.find_last_of(
".");
475 size_t lastSlash =
Filename_m.find_last_of(
"/");
476 lastSlash = (lastSlash == std::string::npos)? 0: lastSlash + 1;
482 opal->getAuxiliaryOutputDirectory(),
483 Filename_m.substr(lastSlash, lastDot) +
".check"
486 out <<
"# z original reproduced\n";
488 auto it = zSampling.begin();
489 auto end = zSampling.end();
490 for (; it !=
end; ++ it) {
492 double onAxisFieldCheck = fourierCoefficients[0];
494 for (
unsigned int l = 1; l < accuracy; ++l, n += 2) {
495 double coskzl = std::cos(kz * l);
496 double sinkzl = std::sin(kz * l);
498 onAxisFieldCheck += (fourierCoefficients[n] * coskzl - fourierCoefficients[n + 1] * sinkzl);
500 double ez = gsl_spline_eval(splineCoefficients, *it, splineAccelerator);
501 double difference = std::abs(ez - onAxisFieldCheck);
502 maxDiff = difference > maxDiff? difference: maxDiff;
503 ezMax = std::abs(ez) > ezMax? std::abs(ez): ezMax;
504 error += std::pow(difference, 2.0);
505 ezSquare += std::pow(ez, 2.0);
508 out << std::setw(16) << std::setprecision(8) << *it
509 << std::setw(16) << std::setprecision(8) << ez
510 << std::setw(16) << std::setprecision(8) << onAxisFieldCheck
516 if (std::sqrt(error / ezSquare) > 1e-1 || maxDiff > 1e-1 * ezMax) {
520 "Field map can't be reproduced properly with the given number of fourier components");
522 if (std::sqrt(error / ezSquare) > 1e-2 || maxDiff > 1e-2 * ezMax) {
543 size_t comment = buffer.find(
"#");
544 buffer = buffer.substr(0, comment);
548 }
while(!in.eof() && lastof == std::string::npos);
550 if (firstof != std::string::npos) {
551 buffer = buffer.substr(firstof, lastof - firstof + 1);
560 size_t comment = buffer.find_first_of(
"#");
561 buffer = buffer.substr(0, comment);
563 if (lasto != std::string::npos) {
572 const bool &read_all,
573 const std::string &expecting,
574 const std::string &found) {
575 std::stringstream errormsg;
576 errormsg <<
"THERE SEEMS TO BE SOMETHING WRONG WITH YOUR FIELD MAP '" <<
Filename_m <<
"'.\n";
578 errormsg <<
"Didn't find enough values!" << std::endl;
579 }
else if (state & std::ios_base::eofbit) {
580 errormsg <<
"Found more values than expected!" << std::endl;
581 }
else if (state & std::ios_base::failbit) {
582 errormsg <<
"Found wrong type of values!" <<
"\n"
583 <<
"expecting: '" << expecting <<
"' on line " <<
lines_read_m <<
",\n"
584 <<
"instead found: '" << found <<
"'." << std::endl;
591 std::stringstream errormsg;
592 errormsg <<
"THERE SEEMS TO BE SOMETHING WRONG WITH YOUR FIELD MAP '" <<
Filename_m <<
"'.\n"
593 <<
"There are only " <<
lines_read_m - 1 <<
" lines in the file, expecting more.\n"
594 <<
"Please check the section about field maps in the user manual.";
601 std::stringstream errormsg;
602 errormsg <<
"THERE SEEMS TO BE SOMETHING WRONG WITH YOUR FIELD MAP '" <<
Filename_m <<
"'.\n"
603 <<
"There are too many lines in the file, expecting only " <<
lines_read_m <<
" lines.\n"
604 <<
"Please check the section about field maps in the user manual.";
611 std::stringstream errormsg;
612 errormsg <<
"DISABLING FIELD MAP '" +
Filename_m +
"' DUE TO PARSING ERRORS." ;
619 std::stringstream errormsg;
620 errormsg <<
"DISABLING FIELD MAP '" <<
Filename_m <<
"' SINCE FILE COULDN'T BE FOUND!";
627 std::stringstream errormsg;
628 errormsg <<
"IT SEEMS THAT YOU USE TOO FEW FOURIER COMPONENTS TO SUFFICIENTLY WELL\n"
629 <<
"RESOLVE THE FIELD MAP '" <<
Filename_m <<
"'.\n"
630 <<
"PLEASE INCREASE THE NUMBER OF FOURIER COMPONENTS!\n"
631 <<
"The ratio (e_i - E_i)^2 / E_i^2 is " << std::to_string(squareError) <<
" and\n"
632 <<
"the ratio (max_i(|e_i - E_i|) / max_i(|E_i|) is " << std::to_string(maxError) <<
".\n"
633 <<
"Here E_i is the field as in the field map and e_i is the reconstructed field.\n"
634 <<
"The lower limit for the two ratios is 1e-2\n"
635 <<
"Have a look into the directory "
637 <<
" for a reconstruction of the field map.\n";
638 std::string errormsg_str =
typeset_msg(errormsg.str(),
"warning");
643 std::ofstream omsg(
"errormsg.txt", std::ios_base::app);
644 omsg << errormsg.str() << std::endl;
650 static std::string frame(
"* ******************************************************************************\n");
651 static unsigned int frame_width = frame.length() - 5;
652 static std::string closure(
" *\n");
654 std::string return_string(
"\n" + frame);
656 int remaining_length = msg.length();
657 unsigned int current_position = 0;
660 for (; ii < title.length(); ++ ii) {
663 return_string.replace(15 + 2 * ii, 1,
" ");
664 return_string.replace(16 + 2 * ii, 1, &
c, 1);
666 return_string.replace(15 + 2 * ii, 1,
" ");
668 while(remaining_length > 0) {
669 size_t eol = msg.find(
"\n", current_position);
670 std::string next_to_process;
671 if (eol != std::string::npos) {
672 next_to_process = msg.substr(current_position, eol - current_position);
674 next_to_process = msg.substr(current_position);
678 if (eol - current_position < frame_width) {
679 return_string +=
"* " + next_to_process + closure.substr(eol - current_position + 2);
681 unsigned int last_space = next_to_process.rfind(
" ", frame_width);
682 if (last_space > 0) {
683 if (last_space < frame_width) {
684 return_string +=
"* " + next_to_process.substr(0, last_space) + closure.substr(last_space + 2);
686 return_string +=
"* " + next_to_process.substr(0, last_space) +
" *\n";
688 if (next_to_process.length() - last_space + 1 < frame_width) {
689 return_string +=
"* " + next_to_process.substr(last_space + 1) + closure.substr(next_to_process.length() - last_space + 1);
691 return_string +=
"* " + next_to_process.substr(last_space + 1) +
" *\n";
694 return_string +=
"* " + next_to_process +
" *\n";
698 current_position = eol + 1;
699 remaining_length = msg.length() - current_position;
701 return_string += frame;
703 return return_string;
710 std::vector<double> &) {
737 const std::pair<double, double> &xrange,
738 const std::pair<double, double> &yrange,
739 const std::pair<double, double> &zrange,
740 const std::vector<Vector_t> &ef,
741 const std::vector<Vector_t> &bf) {
742 const size_t numpoints = nx * ny * nz;
744 (ef.size() != numpoints && bf.size() != numpoints))
return;
749 p.stem().string() +
".vtk"
756 const double hx = (xrange.second - xrange.first) / (nx - 1);
757 const double hy = (yrange.second - yrange.first) / (ny - 1);
758 const double hz = (zrange.second - zrange.first) / (nz - 1);
760 of <<
"# vtk DataFile Version 2.0" << std::endl;
761 of <<
"generated by 3D fieldmaps" << std::endl;
762 of <<
"ASCII" << std::endl << std::endl;
763 of <<
"DATASET RECTILINEAR_GRID" << std::endl;
764 of <<
"DIMENSIONS " << nx <<
" " << ny <<
" " << nz << std::endl;
766 of <<
"X_COORDINATES " << nx <<
" float" << std::endl;
768 for (
unsigned int i = 1; i < nx - 1; ++ i) {
769 of <<
" " << xrange.first + i * hx;
771 of <<
" " << xrange.second << std::endl;
773 of <<
"Y_COORDINATES " << ny <<
" float" << std::endl;
775 for (
unsigned int i = 1; i < ny - 1; ++ i) {
776 of <<
" " << yrange.first + i * hy;
778 of <<
" " << yrange.second << std::endl;
780 of <<
"Z_COORDINATES " << nz <<
" float" << std::endl;
782 for (
unsigned int i = 1; i < nz - 1; ++ i) {
783 of <<
" " << zrange.first + i * hz;
785 of <<
" " << zrange.second << std::endl;
787 of <<
"POINT_DATA " << numpoints << std::endl;
789 if (ef.size() == numpoints) {
790 of <<
"VECTORS EField float" << std::endl;
792 for (
size_t i = 0; i < numpoints; ++ i) {
793 of << ef[i](0) <<
" " << ef[i](1) <<
" " << ef[i](2) << std::endl;
798 if (bf.size() == numpoints) {
799 of <<
"VECTORS BField float" << std::endl;
801 for (
size_t i = 0; i < numpoints; ++ i) {
802 of << bf[i](0) <<
" " << bf[i](1) <<
" " << bf[i](2) << std::endl;
814std::map<std::string, _Fieldmap::FieldmapDescription>
_Fieldmap::FieldmapDictionary = std::map<std::string, _Fieldmap::FieldmapDescription>();
PartBunchBase< T, Dim >::ConstIterator end(PartBunchBase< T, Dim > const &bunch)
#define REGISTER_PARSE_TYPE(X)
std::shared_ptr< _Fieldmap > Fieldmap
#define READ_BUFFER_LENGTH
@ T3DMagnetoStatic_Extended
@ T3DMagnetoStaticH5Block
constexpr double c
The velocity of light in m/s.
Inform & endl(Inform &inf)
constexpr double two_pi
The value of.
std::string combineFilePath(std::initializer_list< std::string > ilist)
static OpalData * getInstance()
std::string getAuxiliaryOutputDirectory() const
get the name of the the additional data directory
static Astra1DDynamic create(const std::string &filename)
static Astra1DDynamic_fast create(const std::string &filename)
static Astra1DElectroStatic create(const std::string &filename)
static Astra1DElectroStatic_fast create(const std::string &filename)
static Astra1DMagnetoStatic create(const std::string &filename)
static Astra1DMagnetoStatic_fast create(const std::string &filename)
virtual double getFieldGap()
bool interpreteEOF(std::ifstream &in)
static std::string typeset_msg(const std::string &msg, const std::string &title)
void disableFieldmapWarning()
virtual void get1DProfile1EngeCoeffs(std::vector< double > &engeCoeffsEntry, std::vector< double > &engeCoeffsExit)
void missingValuesWarning()
virtual void getOnaxisEz(std::vector< std::pair< double, double > > &onaxis)
virtual void get1DProfile1EntranceParam(double &entranceParameter1, double &entranceParameter2, double &entranceParameter3)
static void clearDictionary()
void getLine(std::ifstream &in, std::string &buffer)
void exceedingValuesWarning()
static void deleteFieldmap(std::string Filename)
virtual void setFieldGap(double gap)
virtual void setFieldLength(const double &)
void write3DField(unsigned int nx, unsigned int ny, unsigned int nz, const std::pair< double, double > &xrange, const std::pair< double, double > &yrange, const std::pair< double, double > &zrange, const std::vector< Vector_t > &ef, const std::vector< Vector_t > &bf)
static std::vector< std::string > getListFieldmapNames()
static std::map< std::string, FieldmapDescription > FieldmapDictionary
virtual void get1DProfile1ExitParam(double &exitParameter1, double &exitParameter2, double &exitParameter3)
static Fieldmap getFieldmap(std::string Filename, bool fast=false)
void interpretWarning(const std::ios_base::iostate &state, const bool &read_all, const std::string &error_msg, const std::string &found)
static std::string alpha_numeric
static MapType readHeader(std::string Filename)
void checkMap(unsigned int accuracy, std::pair< double, double > fieldDimensions, double deltaZ, const std::vector< double > &fourierCoefficients, gsl_spline *splineCoefficients, gsl_interp_accel *splineAccelerator)
void lowResolutionWarning(double squareError, double maxError)
static char buffer_m[256]
virtual void setEdgeConstants(const double &bendAngle, const double &entranceAngle, const double &exitAngle)
static FM1DDynamic create(const std::string &filename)
static FM1DDynamic_fast create(const std::string &filename)
static FM1DElectroStatic create(const std::string &filename)
static FM1DElectroStatic_fast create(const std::string &filename)
static FM1DMagnetoStatic create(const std::string &filename)
static FM1DMagnetoStatic_fast create(const std::string &filename)
static FM1DProfile1 create(const std::string &filename)
static FM1DProfile2 create(const std::string &filename)
static FM2DDynamic create(const std::string &filename)
static FM2DElectroStatic create(const std::string &filename)
static FM2DMagnetoStatic create(const std::string &filename)
static FM3DDynamic create(const std::string &filename)
static FM3DH5Block create(const std::string &filename)
static FM3DH5Block_nonscale create(const std::string &filename)
static FM3DMagnetoStatic create(const std::string &filename)
static FM3DMagnetoStaticExtended create(const std::string &filename)
static FM3DMagnetoStaticH5Block create(const std::string &filename)
static MPI_Comm getComm()