OPAL (Object Oriented Parallel Accelerator Library) 2024.2
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"
26static_assert (sizeof(double) == sizeof (h5_float64_t),
27 "double and h5_float64_t are not the same type" );
28static_assert (sizeof(long long) == sizeof (h5_int64_t),
29 "long long and h5_int64_t are not the same type" );
30
31class _FM3DH5BlockBase: virtual public _Fieldmap {
32
33public:
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
87protected:
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
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
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 */
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)),
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)),
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)),
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;
247
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;
260
261 unsigned int num_gridpx_m;
262 unsigned int num_gridpy_m;
263 unsigned int num_gridpz_m;
264
266
267 bool swap_m;
268 friend class _Fieldmap;
269};
270
271using FM3DH5BlockBase = std::shared_ptr<_FM3DH5BlockBase>;
272
273#endif
std::shared_ptr< _FM3DH5BlockBase > FM3DH5BlockBase
DiffDirection
Definition Fieldmap.h:55
#define X(arg)
Definition fftpack.cpp:106
const std::string name
std::vector< double > FieldstrengthEz_m
virtual bool isInside(const Vector_t &r) const
virtual double getFrequency() const
friend class _Fieldmap
void setStep(const long long)
virtual bool getFieldstrength(const Vector_t &, Vector_t &, Vector_t &) const =0
Vector_t interpolateTrilinearly(const std::vector< double > &, const std::vector< double > &, const std::vector< double > &, const Vector_t &X) const
void getResonanceFrequency(void)
virtual bool getFieldDerivative(const Vector_t &, Vector_t &, Vector_t &, const DiffDirection &) const
virtual void getInfo(Inform *msg)
IndexTriplet getIndex(const Vector_t &X) const
unsigned int num_gridpx_m
virtual ~_FM3DH5BlockBase()
unsigned long getIndex(unsigned int i, unsigned int j, unsigned int k) const
virtual void setFrequency(double freq)
virtual void swap()
void getFieldInfo(const char *)
virtual void getOnaxisEz(std::vector< std::pair< double, double > > &F)
virtual void readMap()
void readField(const char *name, double *x, double *y, double *z)
void openFileMPIOCollective(const std::string &filename)
virtual void freeMap()
double getWeightedData(const std::vector< double > &data, const IndexTriplet &idx, unsigned short corner) const
long long getNumSteps(void)
unsigned int num_gridpz_m
unsigned int num_gridpy_m
std::vector< double > FieldstrengthEy_m
std::vector< double > FieldstrengthEx_m
virtual void getFieldDimensions(double &xIni, double &xFinal, double &yIni, double &yFinal, double &zIni, double &zFinal) const
virtual void getFieldDimensions(double &zBegin, double &zEnd) const
Vektor< double, 3 > Vector_t