OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
OPAL
FM3DH5BlockBase.cpp
Go to the documentation of this file.
1 //
2 // Class FM3DH5BlockBase
3 // Base class for 3D field-maps in stored in H5hut files.
4 //
5 // Copyright (c) 2020, Achim Gsell, Paul Scherrer Institut, Villigen PSI, Switzerland
6 // All rights reserved.
7 //
8 // This file is part of OPAL.
9 //
10 // OPAL is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with OPAL. If not, see <https://www.gnu.org/licenses/>.
17 //
18 
19 #include "Fields/FM3DH5BlockBase.h"
20 #include "Fields/Fieldmap.hpp"
21 #include "Physics/Physics.h"
23 
25  const std::string aFilename
26  ) {
27  h5_prop_t props = H5CreateFileProp ();
28  MPI_Comm comm = Ippl::getComm();
29  if (H5SetPropFileMPIOCollective (props, &comm) == H5_ERR) {
31  "FM3DH5BlockBase::openFileMPIOCollective () ",
32  "Cannot set MPIO collective!");
33  }
34  file_m = H5OpenFile (aFilename.c_str(), H5_O_RDONLY, props);
35  if (file_m == (h5_file_t)H5_ERR) {
37  "FM3DH5BlockBase::openFileMPIOCollective () ",
38  "Cannot open file '" + aFilename + "'!");
39  }
40  H5CloseProp (props);
41 }
42 
43 long long FM3DH5BlockBase::getNumSteps (void) {
44  long long num_steps = H5GetNumSteps(file_m);
45  if (num_steps <= 0) {
46  if (num_steps == 0) {
48  "FM3DH5BlockBase::getNumSteps () ",
49  "Number of time-steps in file '" + Filename_m + "' is zero!");
50  } else {
52  "FM3DH5BlockBase::getNumSteps () ",
53  "Query number of time-steps in file '" + Filename_m + "' failed!");
54  }
55  }
56  return num_steps;
57 }
58 
59 void FM3DH5BlockBase::setStep (long long step) {
60  if (H5SetStep(file_m, step) == H5_ERR) {
62  "FM3DH5BlockBase::setStep () ",
63  "Cannot set time-step to " + std::to_string (step) +
64  " in file '" + Filename_m + "'!");
65  }
66 }
67 
68 void FM3DH5BlockBase::getFieldInfo (const char* name) {
69  long long last_step = getNumSteps () - 1;
70  setStep (last_step);
71  h5_size_t grid_rank;
72  h5_size_t grid_dims[3];
73  h5_size_t field_dims;
74  h5_int64_t ftype;
75  if (H5BlockGetFieldInfoByName (
76  file_m, name,
77  &grid_rank, grid_dims, &field_dims, &ftype
78  ) == H5_ERR) {
80  "FM3DH5BlockBase::GetFieldInfo () ",
81  "Query of field info for " + std::string (name) +
82  " in time-step " + std::to_string (last_step) +
83  " in file '" + Filename_m + "' failed!");
84  }
85  num_gridpx_m = grid_dims[0];
86  num_gridpy_m = grid_dims[1];
87  num_gridpz_m = grid_dims[2];
88 
89  if (H5Block3dGetFieldSpacing (
90  file_m, "Efield", &hx_m, &hy_m, &hz_m
91  ) == H5_ERR) {
93  "FM3DH5BlockBase::GetFieldInfo () ",
94  "Query of field spacing"
95  " in time-step " + std::to_string (last_step) +
96  " in file '" + Filename_m + "' failed!");
97  }
98 
99  if (H5Block3dGetFieldOrigin(
100  file_m, "Efield", &xbegin_m, &ybegin_m, &zbegin_m) == H5_ERR) {
102  "FM3DH5BlockBase::GetFieldInfo () ",
103  "Query of field origin"
104  " in time-step " + std::to_string (last_step) +
105  " in file '" + Filename_m + "' failed!");
106  }
107  xend_m = xbegin_m + (num_gridpx_m - 1) * hx_m;
108  yend_m = ybegin_m + (num_gridpy_m - 1) * hy_m;
109  zend_m = zbegin_m + (num_gridpz_m - 1) * hz_m;
110 }
111 
113  if (H5ReadFileAttribFloat64 (
114  file_m, "Resonance Frequency(Hz)", &frequency_m
115  ) == H5_ERR) {
117  "FM3DH5BlockBase::GetResonanceFrequency () ",
118  "Cannot read file attribute 'Resonance Frequency(Hz)'"
119  " in file '" + Filename_m + "'!");
120  }
122 }
123 
125  const char* name,
126  double* x,
127  double* y,
128  double* z
129  ) {
130  if (H5Block3dSetView(file_m,
131  0, num_gridpx_m - 1,
132  0, num_gridpy_m - 1,
133  0, num_gridpz_m - 1) == H5_ERR) {
135  "FM3DH5BlockBase::ReadField () ",
136  "Cannot set view "
137  "0, " + std::to_string (num_gridpx_m) +
138  "0, " + std::to_string (num_gridpy_m) +
139  "0, " + std::to_string (num_gridpz_m) +
140  " in file '" + Filename_m + "'!");
141  }
142  if (H5Block3dReadVector3dFieldFloat64 (
143  file_m,
144  name,
145  x, y, z) == H5_ERR) {
147  "FM3DH5BlockBase::ReadField () ",
148  "Cannot read field " + std::string (name) +
149  " in file '" + Filename_m + "'!");
150  }
151 }
152 
154  if (H5CloseFile (file_m) == H5_ERR) {
156  "FM3DH5BlockBase::closeFile () ",
157  "Error closing file '" + Filename_m + "'!");
158  }
159 }
160 
162  const std::vector<double>& data,
163  const IndexTriplet& idx,
164  unsigned short corner
165  ) const {
166  unsigned short switchX = ((corner & HX) >> 2);
167  unsigned short switchY = ((corner & HY) >> 1);
168  unsigned short switchZ = (corner & HZ);
169  double factorX = 0.5 + (1 - 2 * switchX) * (0.5 - idx.weight(0));
170  double factorY = 0.5 + (1 - 2 * switchY) * (0.5 - idx.weight(1));
171  double factorZ = 0.5 + (1 - 2 * switchZ) * (0.5 - idx.weight(2));
172 
173  unsigned long i = idx.i + switchX, j = idx.j + switchY, k = idx.k + switchZ;
174 
175  return factorX * factorY * factorZ * data[getIndex(i, j, k)];
176 }
177 
179  const std::vector<double>& field_strength_x,
180  const std::vector<double>& field_strength_y,
181  const std::vector<double>& field_strength_z,
182  const Vector_t& X
183  ) const {
184  IndexTriplet idx = getIndex (X);
185  Vector_t result{0.0};
186 
187  result[0] = (getWeightedData(field_strength_x, idx, LX|LY|LZ) +
188  getWeightedData(field_strength_x, idx, LX|LY|HZ) +
189  getWeightedData(field_strength_x, idx, LX|HY|LZ) +
190  getWeightedData(field_strength_x, idx, LX|HY|HZ) +
191  getWeightedData(field_strength_x, idx, HX|LY|LZ) +
192  getWeightedData(field_strength_x, idx, HX|LY|HZ) +
193  getWeightedData(field_strength_x, idx, HX|HY|LZ) +
194  getWeightedData(field_strength_x, idx, HX|HY|HZ));
195 
196  result[1] = (getWeightedData(field_strength_y, idx, LX|LY|LZ) +
197  getWeightedData(field_strength_y, idx, LX|LY|HZ) +
198  getWeightedData(field_strength_y, idx, LX|HY|LZ) +
199  getWeightedData(field_strength_y, idx, LX|HY|HZ) +
200  getWeightedData(field_strength_y, idx, HX|LY|LZ) +
201  getWeightedData(field_strength_y, idx, HX|LY|HZ) +
202  getWeightedData(field_strength_y, idx, HX|HY|LZ) +
203  getWeightedData(field_strength_y, idx, HX|HY|HZ));
204 
205  result[2] = (getWeightedData(field_strength_z, idx, LX|LY|LZ) +
206  getWeightedData(field_strength_z, idx, LX|LY|HZ) +
207  getWeightedData(field_strength_z, idx, LX|HY|LZ) +
208  getWeightedData(field_strength_z, idx, LX|HY|HZ) +
209  getWeightedData(field_strength_z, idx, HX|LY|LZ) +
210  getWeightedData(field_strength_z, idx, HX|LY|HZ) +
211  getWeightedData(field_strength_z, idx, HX|HY|LZ) +
212  getWeightedData(field_strength_z, idx, HX|HY|HZ));
213 
214  return result;
215 }
216 
218  (*msg) << Filename_m << " (3D dynamic) "
219  << " xini= " << xbegin_m << " xfinal= " << xend_m
220  << " yini= " << ybegin_m << " yfinal= " << yend_m
221  << " zini= " << zbegin_m << " zfinal= " << zend_m << " [mm] " << endl;
222  (*msg) << " hx= " << hx_m <<" hy= " << hy_m <<" hz= " << hz_m << " [mm] " <<endl;
223 }
224 
226  return frequency_m;
227 }
228 
229 void FM3DH5BlockBase::setFrequency (double freq) {
230  frequency_m = freq;
231 }
232 
234  std::vector<std::pair<double, double>>& F
235  ) {
236  F.resize(num_gridpz_m);
237 
238  double Ez_max = 0.0;
239  const double dz = (zend_m - zbegin_m) / (num_gridpz_m - 1);
240  const int index_x = -static_cast<int>(std::floor(xbegin_m / hx_m));
241  const double lever_x = -xbegin_m / hx_m - index_x;
242 
243  const int index_y = -static_cast<int>(std::floor(ybegin_m / hy_m));
244  const double lever_y = -ybegin_m / hy_m - index_y;
245  long idx = index_x + index_y*num_gridpx_m + num_gridpx_m*num_gridpy_m;
246  for (int i = 0;
247  i < num_gridpz_m;
248  i++, idx += num_gridpy_m * num_gridpx_m
249  ) {
250  F[i].first = dz * i;
251  F[i].second =
252  (1.0 - lever_x) * (1.0 - lever_y) * FieldstrengthEz_m[idx]
253  + lever_x * (1.0 - lever_y) * FieldstrengthEz_m[idx + 1]
254  + (1.0 - lever_x) * lever_y * FieldstrengthEz_m[idx + num_gridpx_m]
255  + lever_x * lever_y * FieldstrengthEz_m[idx + num_gridpx_m + 1];
256 
257  if(std::abs(F[i].second) > Ez_max) {
258  Ez_max = std::abs(F[i].second);
259  }
260  F[i].second /= Ez_max;
261  }
262 }
#define X(arg)
Definition: fftpack.cpp:112
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
PETE_TUTree< FnFloor, typename T::PETE_Expr_t > floor(const PETE_Expr< T > &l)
Definition: PETE.h:733
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
const std::string name
constexpr double two_pi
The value of.
Definition: Physics.h:33
std::string Filename_m
Definition: Fieldmap.h:117
virtual void setFrequency(double freq)
void getFieldInfo(const char *)
long long getNumSteps(void)
void openFileMPIOCollective(const std::string aFilename)
unsigned long getIndex(unsigned int i, unsigned int j, unsigned int k) const
std::vector< double > FieldstrengthEz_m
virtual double getFrequency() const
void setStep(const long long)
virtual void getOnaxisEz(std::vector< std::pair< double, double > > &F)
Vector_t interpolateTrilinearly(const std::vector< double > &, const std::vector< double > &, const std::vector< double > &, const Vector_t &X) const
double getWeightedData(const std::vector< double > &data, const IndexTriplet &idx, unsigned short corner) const
void getResonanceFrequency(void)
void readField(const char *name, double *x, double *y, double *z)
virtual void getInfo(Inform *msg)
Definition: Inform.h:42
static MPI_Comm getComm()
Definition: IpplInfo.h:152