OPAL (Object Oriented Parallel Accelerator Library)  2024.1
OPAL
FM3DH5BlockBase.h
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 #ifndef CLASSIC_FIELDMAP3DH5BLOCKBASE_H
20 #define CLASSIC_FIELDMAP3DH5BLOCKBASE_H
21 
22 #include "Fields/Fieldmap.h"
23 #include <vector>
24 
25 #include "H5hut.h"
26 static_assert (sizeof(double) == sizeof (h5_float64_t),
27  "double and h5_float64_t are not the same type" );
28 static_assert (sizeof(long long) == sizeof (h5_int64_t),
29  "long long and h5_int64_t are not the same type" );
30 
31 class _FM3DH5BlockBase: virtual public _Fieldmap {
32 
33 public:
34  virtual void readMap (
35  ) {};
36 
37  virtual void freeMap (
38  ) {};
39 
40  virtual bool getFieldstrength (
41  const Vector_t& /*R*/, Vector_t& /*E*/, Vector_t& /*B*/) const = 0;
42 
43  virtual void getFieldDimensions (
44  double &zBegin, double &zEnd
45  ) const {
46  zBegin = zbegin_m;
47  zEnd = zend_m;
48  }
49 
50  virtual void getFieldDimensions (
51  double &xIni, double &xFinal,
52  double &yIni, double &yFinal,
53  double &zIni, double &zFinal
54  ) const {
55  xIni = xbegin_m;
56  xFinal = xend_m;
57  yIni = ybegin_m;
58  yFinal = yend_m;
59  zIni = zbegin_m;
60  zFinal = zend_m;
61  }
62 
63  virtual bool getFieldDerivative (
64  const Vector_t &/*R*/,
65  Vector_t &/*E*/,
66  Vector_t &/*B*/,
67  const DiffDirection &/*dir*/
68  ) const {
69  return false;
70  }
71 
72  virtual void swap(
73  ) {};
74 
75  virtual void getInfo (
76  Inform *msg);
77 
78  virtual double getFrequency (
79  ) const;
80 
81  virtual void setFrequency (
82  double freq);
83 
84  virtual void getOnaxisEz (
85  std::vector<std::pair<double, double> >& F);
86 
87 protected:
89  ) {};
90 
92  ) {};
93 
95  const std::string& filename);
96 
97  long long getNumSteps (
98  void);
99 
100  void setStep (
101  const long long);
102 
103  void getFieldInfo (
104  const char*);
105 
106  void getResonanceFrequency (
107  void);
108 
109  void readField (
110  const char* name,
111  double* x,
112  double* y,
113  double* z
114  );
115 
116  void closeFile (
117  void);
118 
119  virtual bool isInside (
120  const Vector_t &r
121  ) const {
122  return ((r(0) >= xbegin_m && r(0) < xend_m) &&
123  (r(1) >= ybegin_m && r(1) < yend_m) &&
124  (r(2) >= zbegin_m && r(2) < zend_m));
125  }
126 
127  struct IndexTriplet {
128  unsigned int i;
129  unsigned int j;
130  unsigned int k;
133  i(0),
134  j(0),
135  k(0),
136  weight(0.0)
137  {}
138  };
139 
140  /*
141  The 3-dimensional fieldmaps are stored in a 1-dimensional arrays.
142  Please note that the FORTRAN indexing scheme is used in H5hut!
143 
144  This functions maps the 3-dimensional index (i, j, k) to the
145  corresponding index in the 1-dimensional array.
146  */
147  unsigned long getIndex (
148  unsigned int i,
149  unsigned int j,
150  unsigned int k
151  ) const {
152  unsigned long result = j + k * num_gridpy_m;
153  result = i + result * num_gridpx_m;
154 
155  return result;
156  }
157 
158  /*
159  Compute grid indices for a point X.
160 
161  Before calling this function a Isinside(X) test must
162  to be performed!
163 
164  2-dim example with num_gridpx_m = 5, num_gridpy_m = 4
165 
166  3 +----+----+----+----+
167  | | | | |
168  2 +----+----+----+----+
169  | | | | X|
170  1 +----+----+----+----+
171  | | | | |
172  0 +----+----+----+----+
173  0 1 2 3 4
174 
175  idx.x = 3
176  idx.y = 1
177 
178  Notes:
179  In above example: max for idx.x is num_gridpx_m - 2 which is 3.
180 
181  If X is close to a cell border, it can happen that the computation
182  of the index is wrong due to rounding errors. In the example above
183  idx.i == 4 instead of 3. To mitigate this issue we use __float128.
184  To avoid out-of-bound errors we set the index to the max allowed
185  value, if it is out of bound.
186 
187  std::fmod() doesn't support __float128 types! Best we can use is
188  long double.
189  */
190  IndexTriplet getIndex(const Vector_t &X) const {
191  IndexTriplet idx;
192  long double difference = (long double)(X(0)) - (long double)(xbegin_m);
193  idx.i = std::min(
194  (unsigned int)((difference) / (long double)(hx_m)),
195  num_gridpx_m-2
196  );
197  idx.weight(0) = std::fmod(
198  (long double)difference,
199  (long double)hx_m
200  );
201 
202  difference = (long double)(X(1)) - (long double)(ybegin_m);
203  idx.j = std::min(
204  (unsigned int)((difference) / (long double)(hy_m)),
205  num_gridpy_m-2
206  );
207  idx.weight(1) = std::fmod(
208  (long double)difference,
209  (long double)hy_m
210  );
211 
212  difference = (long double)(X(2)) - (long double)(zbegin_m);
213  idx.k = std::min(
214  (unsigned int)((difference) / (long double)(hz_m)),
215  num_gridpz_m-2
216  );
217  idx.weight(2) = std::fmod(
218  (long double)difference,
219  (long double)hz_m
220  );
221  return idx;
222  }
223 
224  double getWeightedData (
225  const std::vector<double>& data,
226  const IndexTriplet& idx,
227  unsigned short corner) const;
228 
230  const std::vector<double>&,
231  const std::vector<double>&,
232  const std::vector<double>&,
233  const Vector_t& X) const;
234 
235  enum : unsigned short {
236  LX = 0, // low X
237  LY = 0, // low Y
238  LZ = 0, // low Z
239  HX = 4, // high X
240  HY = 2, // high Y
241  HZ = 1}; // high Z
242 
243  h5_file_t file_m;
244  std::vector<double> FieldstrengthEz_m;
245  std::vector<double> FieldstrengthEx_m;
246  std::vector<double> FieldstrengthEy_m;
248  double xbegin_m;
249  double xend_m;
250 
251  double ybegin_m;
252  double yend_m;
253 
254  double zbegin_m;
255  double zend_m;
256 
257  double hx_m;
258  double hy_m;
259  double hz_m;
261  unsigned int num_gridpx_m;
262  unsigned int num_gridpy_m;
263  unsigned int num_gridpz_m;
265  double frequency_m;
266 
267  bool swap_m;
268  friend class _Fieldmap;
269 };
270 
271 using FM3DH5BlockBase = std::shared_ptr<_FM3DH5BlockBase>;
272 
273 #endif
virtual void getFieldDimensions(double &zBegin, double &zEnd) const
IndexTriplet getIndex(const Vector_t &X) const
virtual void swap()
virtual ~_FM3DH5BlockBase()
virtual bool getFieldstrength(const Vector_t &, Vector_t &, Vector_t &) const =0
DiffDirection
Definition: Fieldmap.h:55
std::shared_ptr< _FM3DH5BlockBase > FM3DH5BlockBase
virtual bool isInside(const Vector_t &r) const
virtual void freeMap()
unsigned long getIndex(unsigned int i, unsigned int j, unsigned int k) const
void getFieldInfo(const char *)
unsigned int num_gridpz_m
Definition: TSVMeta.h:24
void getResonanceFrequency(void)
void readField(const char *name, double *x, double *y, double *z)
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:76
long long getNumSteps(void)
unsigned int num_gridpy_m
void openFileMPIOCollective(const std::string &filename)
Definition: Inform.h:42
void setStep(const long long)
#define X(arg)
Definition: fftpack.cpp:112
std::vector< double > FieldstrengthEy_m
double getWeightedData(const std::vector< double > &data, const IndexTriplet &idx, unsigned short corner) const
virtual void getOnaxisEz(std::vector< std::pair< double, double > > &F)
virtual void setFrequency(double freq)
float result
Definition: test.py:2
virtual void getFieldDimensions(double &xIni, double &xFinal, double &yIni, double &yFinal, double &zIni, double &zFinal) const
PETE_TBTree< FnFmod, PETE_Scalar< Vektor< T1, Dim > >, typename T2::PETE_Expr_t > fmod(const Vektor< T1, Dim > &l, const PETE_Expr< T2 > &r)
const std::string name
virtual double getFrequency() const
unsigned int num_gridpx_m
virtual bool getFieldDerivative(const Vector_t &, Vector_t &, Vector_t &, const DiffDirection &) const
virtual void getInfo(Inform *msg)
virtual void readMap()
Vector_t interpolateTrilinearly(const std::vector< double > &, const std::vector< double > &, const std::vector< double > &, const Vector_t &X) const
std::vector< double > FieldstrengthEx_m
std::vector< double > FieldstrengthEz_m