00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef __coilgen_hpp__
00022 #define __coilgen_hpp__
00023
00024 #include "ephi.hpp"
00025
00026 #define COILGEN_HEADER_SIZE 128
00027 #define COILGEN_MAGIC "cGe1"
00028 #define COILGEN_BUFFER 4
00029 #define COILGEN_QMOD 1e-6
00030
00031 class CoilGen
00032 {
00033 public:
00034 CoilGen ();
00035
00036 prec_t radius;
00037 prec_t wr;
00038 prec_t dbl;
00039 enum { ROUND, SQUARE } shape;
00040 size_t memory_usage;
00041 size_t coil_matrix_n;
00042 bool do_efield;
00043 bool do_cubic;
00044 size_t force_grid;
00045
00046 prec_t geom_radial;
00047 prec_t geom_axial;
00048
00049 void set_space (prec_t space)
00050 {
00051 dbl = 2 * (radius + (wr * 2 + space)/PREC_SQRT2);
00052 }
00053
00054 void generate (const char *path, bool print_info = false, bool show_progress = false);
00055 };
00056
00057 struct coilgen_header
00058 {
00059 char magic[4];
00060 unsigned int flags;
00061 enum eflags {
00062 IS_HALF = 0x00000001,
00063 IS_COILPAIR = 0x00000002,
00064 IS_OPPOSING_COILPAIR = 0x00000004,
00065 IS_MIRROR = 0x00000008
00066 };
00067
00068 unsigned int coilprec_size;
00069 unsigned int _filler;
00070
00071 double coil_radius;
00072 double coil_wr;
00073 double coilpair_distance;
00074
00075 unsigned int radial_samples;
00076 unsigned int axial_samples;
00077 double geom_radial;
00078 double geom_axial;
00079 double geom_axial_add;
00080 };
00081
00082 struct coilgen_blob_header
00083 {
00084 enum eblobtype {
00085 IS_BLOB_BMAP = 1,
00086 IS_BLOB_BMAPEMAP,
00087 IS_BLOB_CONTACTMAP,
00088 IS_BLOB_CUBIC_BMAP,
00089 IS_BLOB_CUBIC_BMAPEMAP,
00090 };
00091 unsigned int blob_type;
00092 unsigned int blob_len_high;
00093 unsigned int blob_len_low;
00094
00095 void set_len (size_t len)
00096 {
00097 if ( sizeof(size_t) == 4 )
00098 {
00099 blob_len_high = 0;
00100 blob_len_low = len;
00101 }
00102 #ifndef LONG_IS_32BIT
00103 else
00104 {
00105 blob_len_low = len & 0xffffffff;
00106 blob_len_high = (len >> 32) & 0xffffffff;
00107 }
00108 #endif
00109 }
00110 bool can_read () const { return sizeof(size_t) >= 8 || !blob_len_high; }
00111 size_t get_len () const
00112 {
00113 return (size_t)blob_len_low
00114 #ifndef LONG_IS_32BIT
00115 | ((size_t)blob_len_high << 32)
00116 #endif
00117 ;
00118 }
00119 };
00120
00121
00122 typedef float coilprec_t;
00123 #if !defined(PREC_FLOAT) && !defined(PREC_DOUBLE)
00124 #define prec2coilprec(v) prec2double(v)
00125 #else
00126 #define prec2coilprec(v) (v)
00127 #endif
00128
00129 struct coilgen_bmap
00130 {
00131 coilprec_t rb;
00132 coilprec_t ab;
00133 };
00134
00135 struct coilgen_bmapemap
00136 {
00137 coilprec_t rb;
00138 coilprec_t ab;
00139 coilprec_t re;
00140 coilprec_t ae;
00141 };
00142
00143 struct coilgen_cubic_bmap
00144 {
00145 typedef coilprec_t matrix_t[4][4];
00146 matrix_t rb;
00147 matrix_t ab;
00148 };
00149
00150 struct coilgen_cubic_bmapemap
00151 {
00152 typedef coilprec_t matrix_t[4][4];
00153 matrix_t rb;
00154 matrix_t ab;
00155 matrix_t re;
00156 matrix_t ae;
00157 };
00158
00159 class CoilData
00160 {
00161 public:
00162 CoilData ();
00163 ~CoilData ();
00164
00165 void cleanup();
00166
00167 bool load (const char *path);
00168
00169 coilgen_bmap *bmap;
00170 coilgen_bmapemap *bmapemap;
00171 unsigned char *cmap;
00172 coilgen_cubic_bmap *cubic_bmap;
00173 coilgen_cubic_bmapemap *cubic_bmapemap;
00174
00175 unsigned int flags;
00176
00177 prec_t coil_radius;
00178 prec_t coil_wr;
00179
00180 prec_t coilpair_distance;
00181
00182 size_t radial_samples;
00183 size_t axial_samples;
00184 prec_t geom_radial;
00185 prec_t geom_axial;
00186 prec_t geom_axial_add;
00187
00188 bool has_axial_add;
00189 bool mirror;
00190
00191 prec_t cr, ca;
00192 prec_t rec_cr, rec_ca;
00193 };
00194
00195 #include "polywell_conf.hpp"
00196 #include "ephi.hpp"
00197
00198 template <class IC>
00199 class CoilDataFactory : public CoilFactory
00200 {
00201 public:
00202 CoilDataFactory (const CoilData& cd) : cd(cd) {}
00203 virtual ~CoilDataFactory() { }
00204
00205 bool make (Statics& statics, const vect3d& pos, const vect3d& normal,
00206 prec_t radius, prec_t wr, prec_t I, prec_t q_per_m) const;
00207
00208 bool make_coilpair (Statics& statics, const vect3d& pos, const vect3d& normal,
00209 prec_t distance, prec_t radius, prec_t wr, prec_t I, prec_t q_per_m) const;
00210
00211 private:
00212 const CoilData& cd;
00213 };
00214
00215 template <class IC>
00216 bool CoilDataFactory<IC>::make (Statics& statics, const vect3d& pos,
00217 const vect3d& normal, prec_t radius, prec_t wr, prec_t I, prec_t q_per_m) const
00218 {
00219 if ( cd.coilpair_distance != 0 )
00220 {
00221 Ephi::debug (Ephi::DEBUG_CRITICAL, "CoilDataFactory::make: coildata is for a coilpair\n");
00222 return false;
00223 }
00224
00225 if ( cd.coil_radius != radius || cd.coil_wr != wr )
00226 {
00227 Ephi::debug (Ephi::DEBUG_CRITICAL, "CoilDataFactory::make: coil radiuses do not match\n");
00228 return false;
00229 }
00230
00231 statics.addStaticElement (new IC(cd, pos, normal, I, q_per_m));
00232 return true;
00233 }
00234
00235 template <class IC>
00236 bool CoilDataFactory<IC>::make_coilpair (Statics& statics, const vect3d& pos, const vect3d& normal,
00237 prec_t distance, prec_t radius, prec_t wr, prec_t I, prec_t q_per_m) const
00238 {
00239 if ( cd.coilpair_distance == 0 )
00240 return CoilFactory::make_coilpair (statics, pos, normal, distance, radius, wr, I, q_per_m);
00241
00242 if ( cd.coil_radius != radius || cd.coil_wr != wr )
00243 {
00244 Ephi::debug (Ephi::DEBUG_CRITICAL, "CoilDataFactory::make_coilpair: coil radiuses do not match\n");
00245 return false;
00246 }
00247
00248 if ( !cd.mirror )
00249 {
00250 Ephi::debug (Ephi::DEBUG_CRITICAL, "CoilDataFactory::make_coilpair: not an opposing coilpair dataset\n");
00251 return false;
00252 }
00253
00254 if ( fabs(cd.coilpair_distance - distance)/distance > 0.000001 )
00255 {
00256 Ephi::debug (Ephi::DEBUG_CRITICAL, "CoilDataFactory::make_coilpair: coil distance not matching: %g vs %g\n",
00257 prec2double(cd.coilpair_distance), prec2double(distance));
00258 return false;
00259 }
00260
00261 statics.addStaticElement (new IC(cd, pos, normal, I, q_per_m));
00262 Ephi::debug (Ephi::DEBUG_INFO, "CoilDataFactory::make_coilpair: coilpair created\n");
00263 return true;
00264 }
00265
00266 #endif // __coilgen_hpp__
00267