43 namespace 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
51 (*position).second.RefCounter++;
52 return (*position).second.Map;
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;
305 getLine(File, lines_read_m, buffer);
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) {
425 if (!(*position).second.read) {
426 (*position).second.Map->readMap();
427 (*position).second.read =
true;
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();
492 double onAxisFieldCheck = fourierCoefficients[0];
494 for (
unsigned int l = 1; l < accuracy; ++l, n += 2) {
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;
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) > 1
e-1 || maxDiff > 1
e-1 * ezMax) {
520 "Field map can't be reproduced properly with the given number of fourier components");
522 if (
std::sqrt(error / ezSquare) > 1
e-2 || maxDiff > 1
e-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);
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;
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;
773 of <<
"Y_COORDINATES " << ny <<
" float" <<
std::endl;
775 for (
unsigned int i = 1; i < ny - 1; ++ i) {
776 of <<
" " << yrange.first + i * hy;
780 of <<
"Z_COORDINATES " << nz <<
" float" <<
std::endl;
782 for (
unsigned int i = 1; i < nz - 1; ++ i) {
783 of <<
" " << zrange.first + i * hz;
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;
814 std::map<std::string, _Fieldmap::FieldmapDescription>
_Fieldmap::FieldmapDictionary = std::map<std::string, _Fieldmap::FieldmapDescription>();
static Astra1DElectroStatic create(const std::string &filename)
static OpalData * getInstance()
Tps< T > sqrt(const Tps< T > &x)
Square root.
constexpr double c
The velocity of light in m/s.
static void clearDictionary()
static Astra1DDynamic_fast create(const std::string &filename)
and that you know you can do these things To protect your we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights These restrictions translate to certain responsibilities for you if you distribute copies of the or if you modify it For if you distribute copies of such a whether gratis or for a you must give the recipients all the rights that you have You must make sure that receive or can get the source code And you must show them these terms so they know their rights We protect your rights with two distribute and or modify the software for each author s protection and we want to make certain that everyone understands that there is no warranty for this free software If the software is modified by someone else and passed we want its recipients to know that what they have is not the so that any problems introduced by others will not reflect on the original authors reputations any free program is threatened constantly by software patents We wish to avoid the danger that redistributors of a free program will individually obtain patent in effect making the program proprietary To prevent we have made it clear that any patent must be licensed for everyone s free use or not licensed at all The precise terms and conditions for distribution and modification follow GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR DISTRIBUTION AND MODIFICATION This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License The refers to any such program or and a work based on the Program means either the Program or any derivative work under copyright a work containing the Program or a portion of it
virtual void setFieldLength(const double &)
constexpr double two_pi
The value of .
static FM2DElectroStatic create(const std::string &filename)
static Astra1DElectroStatic_fast create(const std::string &filename)
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
static void deleteFieldmap(std::string Filename)
virtual void setEdgeConstants(const double &bendAngle, const double &entranceAngle, const double &exitAngle)
static MPI_Comm getComm()
static FM1DDynamic create(const std::string &filename)
static FM1DDynamic_fast create(const std::string &filename)
virtual void get1DProfile1ExitParam(double &exitParameter1, double &exitParameter2, double &exitParameter3)
static FM2DDynamic create(const std::string &filename)
virtual void get1DProfile1EntranceParam(double &entranceParameter1, double &entranceParameter2, double &entranceParameter3)
void interpretWarning(const std::ios_base::iostate &state, const bool &read_all, const std::string &error_msg, const std::string &found)
static std::string typeset_msg(const std::string &msg, const std::string &title)
virtual double getFieldGap()
static std::map< std::string, FieldmapDescription > FieldmapDictionary
c Accompany it with the information you received as to the offer to distribute corresponding source complete source code means all the source code for all modules it plus any associated interface definition plus the scripts used to control compilation and installation of the executable as a special the source code distributed need not include anything that is normally and so on of the operating system on which the executable unless that component itself accompanies the executable If distribution of executable or object code is made by offering access to copy from a designated then offering equivalent access to copy the source code from the same place counts as distribution of the source even though third parties are not compelled to copy the source along with the object code You may not or distribute the Program except as expressly provided under this License Any attempt otherwise to sublicense or distribute the Program is void
Inform & endl(Inform &inf)
static MapType readHeader(std::string Filename)
#define REGISTER_PARSE_TYPE(X)
bool interpreteEOF(std::ifstream &in)
static Astra1DMagnetoStatic create(const std::string &filename)
static char buffer_m[256]
#define READ_BUFFER_LENGTH
static FM3DH5Block create(const std::string &filename)
std::shared_ptr< _Fieldmap > Fieldmap
std::string::iterator iterator
static FM1DProfile2 create(const std::string &filename)
static FM3DMagnetoStaticH5Block create(const std::string &filename)
virtual void get1DProfile1EngeCoeffs(std::vector< double > &engeCoeffsEntry, std::vector< double > &engeCoeffsExit)
virtual void setFieldGap(double gap)
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 Astra1DDynamic create(const std::string &filename)
std::string getAuxiliaryOutputDirectory() const
get the name of the the additional data directory
static FM1DElectroStatic_fast create(const std::string &filename)
void exceedingValuesWarning()
static FM1DElectroStatic create(const std::string &filename)
static Astra1DMagnetoStatic_fast create(const std::string &filename)
static std::string alpha_numeric
static FM2DMagnetoStatic create(const std::string &filename)
void disableFieldmapWarning()
static FM3DDynamic create(const std::string &filename)
Tps< T > cos(const Tps< T > &x)
Cosine.
static FM3DMagnetoStatic create(const std::string &filename)
std::string combineFilePath(std::initializer_list< std::string > ilist)
void getLine(std::ifstream &in, std::string &buffer)
static FM1DProfile1 create(const std::string &filename)
constexpr double e
The value of .
static FM1DMagnetoStatic_fast create(const std::string &filename)
virtual void getOnaxisEz(std::vector< std::pair< double, double > > &onaxis)
static std::vector< std::string > getListFieldmapNames()
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
void missingValuesWarning()
Tps< T > sin(const Tps< T > &x)
Sine.
static FM3DMagnetoStaticExtended create(const std::string &filename)
void lowResolutionWarning(double squareError, double maxError)
void checkMap(unsigned int accuracy, std::pair< double, double > fieldDimensions, double deltaZ, const std::vector< double > &fourierCoefficients, gsl_spline *splineCoefficients, gsl_interp_accel *splineAccelerator)
static Fieldmap getFieldmap(std::string Filename, bool fast=false)
static FM3DH5Block_nonscale create(const std::string &filename)
static FM1DMagnetoStatic create(const std::string &filename)