Commit b0812f57 authored by ext-calvo_p's avatar ext-calvo_p
Browse files

Merge branch '651-printing-info-of-dumpfields-and-dumpemfields' into 'master'

Resolve "Printing info of DumpFields and DumpEMFields"

Closes #651

See merge request !492
parents 66ea7642 58229c68
......@@ -50,7 +50,7 @@ IndexMap::IndexMap():
void IndexMap::print(std::ostream &out) const {
if (mapRange2Element_m.size() == 0) return;
out << "Size of map " << mapRange2Element_m.size() << " sections " << std::endl;
out << "* Size of map " << mapRange2Element_m.size() << " sections " << std::endl;
out << std::fixed << std::setprecision(6);
auto mapIti = mapRange2Element_m.begin();
auto mapItf = mapRange2Element_m.end();
......@@ -61,14 +61,14 @@ void IndexMap::print(std::ostream &out) const {
for (; mapIti != mapItf; mapIti++) {
const key_t key = (*mapIti).first;
const value_t val = (*mapIti).second;
out << "Key: ("
out << "* Key: ("
<< std::setw(numDigits + 7) << std::right << key.begin
<< " - "
<< std::setw(numDigits + 7) << std::right << key.end
<< ") number of overlapping elements " << val.size() << "\n";
for (auto element: val) {
out << std::setw(25 + 2 * numDigits) << " " << element->getName() << "\n";
out << "* " << std::setw(25 + 2 * numDigits) << " " << element->getName() << "\n";
}
}
}
......
This diff is collapsed.
......@@ -30,30 +30,28 @@
#include <sstream>
#include <string>
#include "AbsBeamline/Monitor.h"
#include "AbstractObjects/OpalData.h"
#include "Algorithms/OrbitThreader.h"
#include "Algorithms/CavityAutophaser.h"
#include "BasicActions/Option.h"
#ifdef ENABLE_OPAL_FEL
#include "BeamlineCore/UndulatorRep.h"
#endif
#include "Beamlines/Beamline.h"
#include "Beamlines/FlaggedBeamline.h"
#include "Distribution/Distribution.h"
#include "Elements/OpalBeamline.h"
#include "Solvers/CSRWakeFunction.h"
#include "AbstractObjects/OpalData.h"
#include "BasicActions/Option.h"
#include "Solvers/ParticleMatterInteractionHandler.h"
#include "Structure/BoundaryGeometry.h"
#include "Utilities/OpalException.h"
#include "Utilities/Options.h"
#include "Utilities/Timer.h"
#include "Utilities/Util.h"
#include "Distribution/Distribution.h"
#include "ValueDefinitions/RealVariable.h"
#include "Utilities/Timer.h"
#include "Utilities/OpalException.h"
#include "Solvers/ParticleMatterInteractionHandler.h"
#include "Structure/BoundaryGeometry.h"
#include "AbsBeamline/Monitor.h"
#ifdef ENABLE_OPAL_FEL
#include "BeamlineCore/UndulatorRep.h"
#endif
extern Inform* gmsg;
class PartData;
......@@ -268,15 +266,16 @@ void ParallelTTracker::execute() {
unsigned long long step = itsBunch_m->getGlobalTrackStep();
OPALTimer::Timer myt1;
*gmsg << "Track start at: " << myt1.time() << ", t= " << Util::getTimeString(time) << "; "
*gmsg << "* Track start at: " << myt1.time() << ", t= " << Util::getTimeString(time) << "; "
<< "zstart at: " << Util::getLengthString(pathLength_m)
<< endl;
prepareEmission();
*gmsg << level1
<< "Executing ParallelTTracker, initial dt= " << Util::getTimeString(itsBunch_m->getdT()) << ";\n"
<< "max integration steps " << stepSizes_m.getMaxSteps() << ", next step= " << step << endl;
*gmsg << "* Executing ParallelTTracker\n"
<< "* Initial dt = " << Util::getTimeString(itsBunch_m->getdT()) << "\n"
<< "* Max integration steps = " << stepSizes_m.getMaxSteps()
<< ", next step = " << step << endl << endl;
setOptionalVariables();
......@@ -359,7 +358,8 @@ void ParallelTTracker::execute() {
itsOpalBeamline_m.switchElementsOff();
OPALTimer::Timer myt3;
*gmsg << "done executing ParallelTTracker at " << myt3.time() << endl;
*gmsg << endl << "* Done executing ParallelTTracker at "
<< myt3.time() << endl << endl;
Monitor::writeStatistics();
......
......@@ -27,6 +27,7 @@
#include <iostream>
extern Inform* gmsg;
Call::Call():
Action(1, "CALL",
......@@ -57,14 +58,11 @@ void Call::execute() {
std::string file = Attributes::getString(itsAttr[0]);
if (Options::info && Ippl::myNode() == 0) {
std::cerr << "Start reading input stream \"" << file << "\"." << std::endl;
*gmsg << "* Reading input stream \"" << file
<< "\" from CALL command.\n" << endl;
}
OpalParser().run(new FileStream(file));
if (Options::info && Ippl::myNode() == 0) {
std::cerr << "End reading input stream \"" << file << "\"." << std::endl;
}
}
......
/*
* Copyright (c) 2016, Chris Rogers
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STFC nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
//
// Class DumpEMFields
// DumpEMFields dumps the dynamically changing fields of a Ring in a user-
// defined grid.
//
// Copyright (c) 2017, Chris Rogers
// All rights reserved
//
// This file is part of OPAL.
//
// OPAL is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// You should have received a copy of the GNU General Public License
// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
//
#include "BasicActions/DumpEMFields.h"
#include "AbsBeamline/Component.h"
#include "AbstractObjects/OpalData.h"
#include "Attributes/Attributes.h"
#include "Fields/Interpolation/NDGrid.h"
#include "Physics/Physics.h"
#include "Utilities/OpalException.h"
#include "Utilities/Util.h"
#include <fstream>
#include <cmath>
#include "Fields/Interpolation/NDGrid.h" // classic
#include "AbsBeamline/Component.h" // classic
#include "Utilities/OpalException.h"
#include "Attributes/Attributes.h"
#include "BasicActions/DumpEMFields.h"
// extern Inform *gmsg;
extern Inform* gmsg;
std::unordered_set<DumpEMFields*> DumpEMFields::dumpsSet_m;
std::string DumpEMFields::dumpemfields_docstring =
std::string("The \"DUMPEMFIELDS\" statement dumps a field map to a user-defined")+
std::string(" field file, for checking that fields are generated correctly.")+
std::string(" The fields are written out on a grid in space and time.");
DumpEMFields::DumpEMFields() :
Action(20, "DUMPEMFIELDS", dumpemfields_docstring.c_str()),
grid_m(NULL), filename_m("") {
Action(SIZE, "DUMPEMFIELDS",
"The \"DUMPEMFIELDS\" statement dumps a field map to a user-defined "
"field file, for checking that fields are generated correctly. "
"The fields are written out on a grid in space and time."),
grid_m(NULL),
filename_m(""),
coordinates_m(CoordinateSystem::CARTESIAN) {
// would be nice if "steps" could be integer
itsAttr[0] = Attributes::makeReal
itsAttr[FILE_NAME] = Attributes::makeString
("FILE_NAME", "Name of the file to which field data is dumped");
itsAttr[COORDINATE_SYSTEM] = Attributes::makeUpperCaseString
("COORDINATE_SYSTEM", "Choose to use CARTESIAN (default) or CYLINDRICAL coordinates", "CARTESIAN");
itsAttr[X_START] = Attributes::makeReal
("X_START", "(Cartesian) Start point in the grid in x [m]");
itsAttr[1] = Attributes::makeReal
itsAttr[DX] = Attributes::makeReal
("DX", "(Cartesian) Grid step size in x [m]");
itsAttr[2] = Attributes::makeReal
itsAttr[X_STEPS] = Attributes::makeReal
("X_STEPS", "(Cartesian) Number of steps in x");
itsAttr[3] = Attributes::makeReal
itsAttr[Y_START] = Attributes::makeReal
("Y_START", "(Cartesian) Start point in the grid in y [m]");
itsAttr[4] = Attributes::makeReal
itsAttr[DY] = Attributes::makeReal
("DY", "(Cartesian) Grid step size in y [m]");
itsAttr[5] = Attributes::makeReal
itsAttr[Y_STEPS] = Attributes::makeReal
("Y_STEPS", "(Cartesian) Number of steps in y");
itsAttr[6] = Attributes::makeReal
itsAttr[Z_START] = Attributes::makeReal
("Z_START", "Start point in the grid in z [m]");
itsAttr[7] = Attributes::makeReal
itsAttr[DZ] = Attributes::makeReal
("DZ", "Grid step size in z [m]");
itsAttr[8] = Attributes::makeReal
itsAttr[Z_STEPS] = Attributes::makeReal
("Z_STEPS", "Number of steps in z");
itsAttr[9] = Attributes::makeReal
itsAttr[T_START] = Attributes::makeReal
("T_START", "Start point in the grid in time [ns]");
itsAttr[10] = Attributes::makeReal
itsAttr[DT] = Attributes::makeReal
("DT", "Grid step size in time [ns]");
itsAttr[11] = Attributes::makeReal
itsAttr[T_STEPS] = Attributes::makeReal
("T_STEPS", "Number of steps in time");
itsAttr[12] = Attributes::makeString
("FILE_NAME", "Name of the file to which field data is dumped");
itsAttr[13] = Attributes::makeString("COORDINATE_SYSTEM",
"Choose to use 'Cartesian' or 'Cylindrical' coordinates");
itsAttr[14] = Attributes::makeReal
itsAttr[R_START] = Attributes::makeReal
("R_START", "(Cylindrical) Start point in the grid in radius [m]");
itsAttr[15] = Attributes::makeReal
itsAttr[DR] = Attributes::makeReal
("DR", "(Cylindrical) Grid step size in radius [m]");
itsAttr[16] = Attributes::makeReal
itsAttr[R_STEPS] = Attributes::makeReal
("R_STEPS", "(Cylindrical) Number of steps in radius");
itsAttr[17] = Attributes::makeReal
itsAttr[PHI_START] = Attributes::makeReal
("PHI_START", "(Cylindrical) Start point in the grid in phi [rad]");
itsAttr[18] = Attributes::makeReal
itsAttr[DPHI] = Attributes::makeReal
("DPHI", "(Cylindrical) Grid step size in phi [rad]");
itsAttr[19] = Attributes::makeReal
itsAttr[PHI_STEPS] = Attributes::makeReal
("PHI_STEPS", "(Cylindrical) Number of steps in phi");
registerOwnership(AttributeHandler::STATEMENT);
}
DumpEMFields::DumpEMFields(const std::string& name, DumpEMFields* parent):
Action(name, parent)
{}
DumpEMFields::~DumpEMFields() {
delete grid_m;
dumpsSet_m.erase(this);
}
DumpEMFields* DumpEMFields::clone(const std::string &/*name*/) {
DumpEMFields* dumper = new DumpEMFields();
DumpEMFields* DumpEMFields::clone(const std::string& name) {
DumpEMFields* dumper = new DumpEMFields(name, this);
if (grid_m != NULL) {
dumper->grid_m = grid_m->clone();
}
......@@ -108,22 +129,16 @@ DumpEMFields* DumpEMFields::clone(const std::string &/*name*/) {
}
void DumpEMFields::parseCoordinateSystem() {
if (!itsAttr[13]) {
coordinates_m = CARTESIAN;
return;
}
std::string coordStr = Attributes::getString(itsAttr[13]);
for (size_t i = 0; i < coordStr.size(); ++i) {
coordStr[i] = std::tolower(coordStr[i]);
}
if (coordStr == "cylindrical") {
coordinates_m = CYLINDRICAL;
} else if (coordStr == "cartesian") {
coordinates_m = CARTESIAN;
std::string coordStr = Attributes::getString(itsAttr[COORDINATE_SYSTEM]);
if (coordStr == "CYLINDRICAL") {
coordinates_m = CoordinateSystem::CYLINDRICAL;
} else if (coordStr == "CARTESIAN") {
coordinates_m = CoordinateSystem::CARTESIAN;
} else {
throw OpalException("DumpEMFields::parseCoordinateSystem",
std::string("Failed to parse '")+Attributes::getString(itsAttr[13])+
std::string("'. OPAL expected either 'cylindrical' or 'cartesian'."));
"Failed to parse '" + coordStr +
"'. OPAL expected either CYLINDRICAL or CARTESIAN.");
}
}
......@@ -142,40 +157,40 @@ void DumpEMFields::buildGrid() {
std::vector<int> gridSize(4);
parseCoordinateSystem();
if (coordinates_m == CYLINDRICAL) {
origin[0] = Attributes::getReal(itsAttr[14]);
spacing[0] = Attributes::getReal(itsAttr[15]);
double nr = Attributes::getReal(itsAttr[16]);
if (coordinates_m == CoordinateSystem::CYLINDRICAL) {
origin[0] = Attributes::getReal(itsAttr[R_START]);
spacing[0] = Attributes::getReal(itsAttr[DR]);
double nr = Attributes::getReal(itsAttr[R_STEPS]);
checkInt(nr, "R_STEPS");
gridSize[0] = nr;
origin[1] = Attributes::getReal(itsAttr[17]);
spacing[1] = Attributes::getReal(itsAttr[18]);
double nphi = Attributes::getReal(itsAttr[19]);
origin[1] = Attributes::getReal(itsAttr[PHI_START]);
spacing[1] = Attributes::getReal(itsAttr[DPHI]);
double nphi = Attributes::getReal(itsAttr[PHI_STEPS]);
checkInt(nphi, "PHI_STEPS");
gridSize[1] = nphi;
} else {
origin[0] = Attributes::getReal(itsAttr[0]);
spacing[0] = Attributes::getReal(itsAttr[1]);
double nx = Attributes::getReal(itsAttr[2]);
origin[0] = Attributes::getReal(itsAttr[X_START]);
spacing[0] = Attributes::getReal(itsAttr[DX]);
double nx = Attributes::getReal(itsAttr[X_STEPS]);
checkInt(nx, "X_STEPS");
gridSize[0] = nx;
origin[1] = Attributes::getReal(itsAttr[3]);
spacing[1] = Attributes::getReal(itsAttr[4]);
double ny = Attributes::getReal(itsAttr[5]);
origin[1] = Attributes::getReal(itsAttr[Y_START]);
spacing[1] = Attributes::getReal(itsAttr[DY]);
double ny = Attributes::getReal(itsAttr[Y_STEPS]);
checkInt(ny, "Y_STEPS");
gridSize[1] = ny;
}
origin[2] = Attributes::getReal(itsAttr[6]);
spacing[2] = Attributes::getReal(itsAttr[7]);
double nz = Attributes::getReal(itsAttr[8]);
origin[2] = Attributes::getReal(itsAttr[Z_START]);
spacing[2] = Attributes::getReal(itsAttr[DZ]);
double nz = Attributes::getReal(itsAttr[Z_STEPS]);
checkInt(nz, "Z_STEPS");
gridSize[2] = nz;
origin[3] = Attributes::getReal(itsAttr[9]);
spacing[3] = Attributes::getReal(itsAttr[10]);
double nt = Attributes::getReal(itsAttr[11]);
origin[3] = Attributes::getReal(itsAttr[T_START]);
spacing[3] = Attributes::getReal(itsAttr[DT]);
double nt = Attributes::getReal(itsAttr[T_STEPS]);
checkInt(nt, "T_STEPS");
gridSize[3] = nt;
......@@ -185,7 +200,7 @@ void DumpEMFields::buildGrid() {
grid_m = new interpolation::NDGrid(4, &gridSize[0], &spacing[0], &origin[0]);
filename_m = Attributes::getString(itsAttr[12]);
filename_m = Attributes::getString(itsAttr[FILE_NAME]);
}
void DumpEMFields::writeFields(Component* field) {
......@@ -210,7 +225,7 @@ void DumpEMFields::checkInt(double real, std::string name, double tolerance) {
void DumpEMFields::writeHeader(std::ofstream& fout) const {
fout << grid_m->end().toInteger() << "\n";
if (coordinates_m == CYLINDRICAL) {
if (coordinates_m == CoordinateSystem::CYLINDRICAL) {
fout << 1 << " r [mm]\n";
fout << 2 << " phi [degree]\n";
} else {
......@@ -219,7 +234,7 @@ void DumpEMFields::writeHeader(std::ofstream& fout) const {
}
fout << 3 << " z [mm]\n";
fout << 4 << " t [ns]\n";
if (coordinates_m == CYLINDRICAL) {
if (coordinates_m == CoordinateSystem::CYLINDRICAL) {
fout << 5 << " Br [kGauss]\n";
fout << 6 << " Bphi [kGauss]\n";
fout << 7 << " Bz [kGauss]\n";
......@@ -245,7 +260,7 @@ void DumpEMFields::writeFieldLine(Component* field,
Vector_t E(0., 0., 0.);
Vector_t B(0., 0., 0.);
Vector_t point = pointIn;
if (coordinates_m == CYLINDRICAL) {
if (coordinates_m == CoordinateSystem::CYLINDRICAL) {
// pointIn is r, phi, z
point[0] = std::cos(pointIn[1])*pointIn[0];
point[1] = std::sin(pointIn[1])*pointIn[0];
......@@ -254,13 +269,13 @@ void DumpEMFields::writeFieldLine(Component* field,
field->apply(point, centroid, time, E, B);
Vector_t Bout = B;
Vector_t Eout = E;
if (coordinates_m == CYLINDRICAL) {
if (coordinates_m == CoordinateSystem::CYLINDRICAL) {
// pointIn is r, phi, z
Bout[0] = B[0]*std::cos(pointIn[1])+B[1]*std::sin(pointIn[1]);
Bout[1] = -B[0]*std::sin(pointIn[1])+B[1]*std::cos(pointIn[1]);
Eout[0] = E[0]*std::cos(pointIn[1])+E[1]*std::sin(pointIn[1]);
Eout[1] = -E[0]*std::sin(pointIn[1])+E[1]*std::cos(pointIn[1]);
fout << pointIn[0] << " " << pointIn[1]*DEGREE << " " << pointIn[2] << " " << time << " ";
fout << pointIn[0] << " " << pointIn[1]*Physics::rad2deg << " " << pointIn[2] << " " << time << " ";
} else {
fout << pointIn[0] << " " << pointIn[1] << " " << pointIn[2] << " " << time << " ";
}
......@@ -274,11 +289,17 @@ void DumpEMFields::writeFieldThis(Component* field) {
throw OpalException("DumpEMFields::writeFieldThis",
"The grid was NULL; there was a problem with the DumpEMFields initialisation.");
}
if (field == NULL) {
throw OpalException("DumpEMFields::writeFieldThis",
"The field to be written was NULL.");
}
*gmsg << *this << endl;
std::string fname = Util::combineFilePath({
OpalData::getInstance()->getAuxiliaryOutputDirectory(),
filename_m
});
std::vector<double> point_std(4);
Vector_t point(0., 0., 0.);
std::ofstream fout;
......@@ -310,3 +331,32 @@ void DumpEMFields::writeFieldThis(Component* field) {
}
fout.close();
}
void DumpEMFields::print(std::ostream& os) const {
os << "* ************* D U M P E M F I E L D S ****************************************** " << std::endl;
os << "* File name: " << filename_m << '\n';
if (coordinates_m == CoordinateSystem::CARTESIAN) {
os << "* Coordinate system: " << "Cartesian" << '\n'
<< "* X_START = " << Attributes::getReal(itsAttr[X_START]) << " [m]\n"
<< "* DX = " << Attributes::getReal(itsAttr[DX]) << " [m]\n"
<< "* X_STEPS = " << Attributes::getReal(itsAttr[X_STEPS]) << '\n'
<< "* Y_START = " << Attributes::getReal(itsAttr[Y_START]) << " [m]\n"
<< "* DY = " << Attributes::getReal(itsAttr[DY]) << " [m]\n"
<< "* Y_STEPS = " << Attributes::getReal(itsAttr[Y_STEPS]) << '\n';
} else if (coordinates_m == CoordinateSystem::CYLINDRICAL) {
os << "* Coordinate system: " << "Cylindrical" << '\n'
<< "* R_START = " << Attributes::getReal(itsAttr[R_START]) << " [m]\n"
<< "* DR = " << Attributes::getReal(itsAttr[DR]) << " [m]\n"
<< "* R_STEPS = " << Attributes::getReal(itsAttr[R_STEPS]) << '\n'
<< "* PHI_START = " << Attributes::getReal(itsAttr[PHI_START]) << " [rad]\n"
<< "* DPHI = " << Attributes::getReal(itsAttr[DPHI]) << " [rad]\n"
<< "* PHI_STEPS = " << Attributes::getReal(itsAttr[PHI_STEPS]) << '\n';
}
os << "* Z_START = " << Attributes::getReal(itsAttr[Z_START]) << " [m]\n"
<< "* DZ = " << Attributes::getReal(itsAttr[DZ]) << " [m]\n"
<< "* Z_STEPS = " << Attributes::getReal(itsAttr[Z_STEPS]) << '\n'
<< "* T_START = " << Attributes::getReal(itsAttr[T_START]) << " [ns]\n"
<< "* DT = " << Attributes::getReal(itsAttr[DT]) << " [ns]\n"
<< "* T_STEPS = " << Attributes::getReal(itsAttr[T_STEPS]) << '\n';
os << "* ********************************************************************************** " << std::endl;
}
/*
* Copyright (c) 2017, Chris Rogers
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STFC nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
//
// Class DumpEMFields
// DumpEMFields dumps the dynamically changing fields of a Ring in a user-
// defined grid.
//
// Copyright (c) 2017, Chris Rogers
// All rights reserved
//
// This file is part of OPAL.
//
// OPAL is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// You should have received a copy of the GNU General Public License
// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
//
#ifndef OPAL_BASICACTIONS_DUMPEMFIELDS_HH
#define OPAL_BASICACTIONS_DUMPEMFIELDS_HH
#include <unordered_set>
#include <string>
#include "AbsBeamline/Component.h"
#include "AbstractObjects/Action.h"
#include <string>
#include <unordered_set>
#include <vector>
namespace interpolation {
class NDGrid;
}
class Component;
/** DumpEMFields dumps the dynamically changing fields of a Ring in a user-
* defined grid.
*
* The idea is to print out the field map across a 4D grid in space-time for
* debugging purposes. The problem is to manage the DumpEMFields object through
* three phases of program execution; initial construction, parsing and then
* actual field map writing (where we need to somehow let DumpFields know what
* the field maps are). So for each DumpFields object created, we store in a
* set. When the execute() method is called, DumpFields builds a grid using
* the parsed information.
* debugging purposes. The problem is to manage the DumpEMFields object
* through three phases of program execution; initial construction, parsing
* and then actual field map writing (where we need to somehow let DumpFields
* know what the field maps are). So for each DumpEMFields object created, we
* store in a set. When the execute() method is called, DumpEMFields builds a
* grid using the parsed information.
*
* When the ParallelCyclotronTracker is about to start tracking, it calls
* writeFields method which loops over the static set of DumpFields and writes
* each one. It is not the cleanest implementation, but I can't see a better
* way.
* writeFields method which loops over the static set of DumpEMFields and
* writes each one. It is not the cleanest implementation, but I can't see a
* better way.
*
* The DumpEMFields themselves operate by iterating over a NDGrid object
* and looking up the field/writing it out on each grid point.
*
*/
class DumpEMFields : public Action {