OPAL (Object Oriented Parallel Accelerator Library)  2024.1
OPAL
FieldWriter.hpp
Go to the documentation of this file.
1 //
2 // Class FieldWriter
3 // This class writes the bunch internal fields on the grid to
4 // file. It supports single core execution only.
5 //
6 // Copyright (c) 2020, Paul Scherrer Institut, Villigen PSI, Switzerland
7 // All rights reserved
8 //
9 // This file is part of OPAL.
10 //
11 // OPAL is free software: you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation, either version 3 of the License, or
14 // (at your option) any later version.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with OPAL. If not, see <https://www.gnu.org/licenses/>.
18 //
19 #include <iomanip>
20 #include <fstream>
21 
22 #include <boost/format.hpp>
23 
24 #include "Utilities/Util.h"
26 #include "Algorithms/PBunchDefs.h"
27 
28 template<typename FieldType>
29 void FieldWriter::dumpField(FieldType& field, std::string name,
30  std::string unit, long long step,
31  FieldType* image)
32 {
33  if (Ippl::getNodes() > 1) {
34  return;
35  }
36 
37  constexpr bool isVectorField = std::is_same<VField_t, FieldType>::value;
38  std::string type = (isVectorField) ? "field" : "scalar";
39 
40  INFOMSG("*** START DUMPING " + Util::toUpper(name) + " FIELD ***" << endl);
41 
42  /* Save the files in the output directory of the simulation. The file
43  * name of vector fields is
44  *
45  * 'basename'-'name'_field-'******'.dat
46  *
47  * and of scalar fields
48  *
49  * 'basename'-'name'_scalar-'******'.dat
50  *
51  * with
52  * 'basename': OPAL input file name (*.in)
53  * 'name': field name (input argument of function)
54  * '******': step padded with zeros to 6 digits
55  */
56  std::string dirname = OpalData::getInstance()->getAuxiliaryOutputDirectory();
57  std::filesystem::path file(dirname);
58  std::format filename("%1%-%2%-%|3$06|.dat");
59  std::string basename = OpalData::getInstance()->getInputBasename();
60  filename % basename % (name + std::string("_") + type) % step;
61  file /= filename.str();
62 
63  std::ofstream fout(file.string(), std::ios::out);
64  fout.precision(9);
65 
66  fout << "# " << name << " " << type << " data on grid" << std::endl
67  << "#"
68  << std::setw(4) << "i"
69  << std::setw(5) << "j"
70  << std::setw(5) << "k"
71  << std::setw(17) << "x [m]"
72  << std::setw(17) << "y [m]"
73  << std::setw(17) << "z [m]";
74  if (isVectorField) {
75  fout << std::setw(10) << name << "x [" << unit << "]"
76  << std::setw(10) << name << "y [" << unit << "]"
77  << std::setw(10) << name << "z [" << unit << "]";
78  } else {
79  fout << std::setw(13) << name << " [" << unit << "]";
80  }
81 
82  if (image) {
83  fout << std::setw(13) << name << " image [" << unit << "]";
84  }
85 
86  fout << std::endl;
87 
88  Vector_t origin = field.get_mesh().get_origin();
89  Vector_t spacing(field.get_mesh().get_meshSpacing(0),
90  field.get_mesh().get_meshSpacing(1),
91  field.get_mesh().get_meshSpacing(2));
92 
93  NDIndex<3> localIdx = field.getLayout().getLocalNDIndex();
94  for (int x = localIdx[0].first(); x <= localIdx[0].last(); x++) {
95  for (int y = localIdx[1].first(); y <= localIdx[1].last(); y++) {
96  for (int z = localIdx[2].first(); z <= localIdx[2].last(); z++) {
97  NDIndex<3> idx(Index(x, x), Index(y, y), Index(z, z));
98  fout << std::setw(5) << x + 1
99  << std::setw(5) << y + 1
100  << std::setw(5) << z + 1
101  << std::setw(17) << origin(0) + x * spacing(0)
102  << std::setw(17) << origin(1) + y * spacing(1)
103  << std::setw(17) << origin(2) + z * spacing(2);
104  if (isVectorField) {
105  Vector_t vfield = field.localElement(idx);
106  fout << std::setw(17) << vfield[0]
107  << std::setw(17) << vfield[1]
108  << std::setw(17) << vfield[2];
109  } else {
110  fout << std::setw(17) << field.localElement(idx);
111  }
112 
113  if (image) {
114  fout << std::setw(17) << image->localElement(idx);
115  }
116  fout << std::endl;
117  }
118  }
119  }
120  fout.close();
121  INFOMSG("*** FINISHED DUMPING " + Util::toUpper(name) + " FIELD ***" << endl);
122 }
static OpalData * getInstance()
Definition: OpalData.cpp:196
Definition: Index.h:236
std::string toUpper(const std::string &str)
Definition: Util.cpp:147
#define INFOMSG(msg)
Definition: IpplInfo.h:348
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
static int getNodes()
Definition: IpplInfo.cpp:670
void dumpField(FieldType &field, std::string name, std::string unit, long long step, FieldType *image=nullptr)
Dump a scalar or vector field to a file.
Definition: FieldWriter.hpp:29
std::string getAuxiliaryOutputDirectory() const
get the name of the the additional data directory
Definition: OpalData.cpp:666
const std::string name
std::string getInputBasename()
get input file name without extension
Definition: OpalData.cpp:674
SDDS1 &description type
Definition: test.stat:4