src/coildata.hpp

Go to the documentation of this file.
00001 //
00002 // Ephi - simulation of magnetic fields and particles
00003 // Copyright (C) 2007 Indrek Mandre <indrek(at)mare.ee>
00004 // For more information please see http://www.mare.ee/indrek/
00005 //
00006 // This program is free software; you can redistribute it and/or modify
00007 // it under the terms of the GNU General Public License as published by
00008 // the Free Software Foundation; either version 2 of the License, or
00009 // (at your option) any later version.
00010 //
00011 // This program is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU General Public License along
00017 // with this program; if not, write to the Free Software Foundation, Inc.,
00018 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
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; // to get 8 aligned
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 //typedef double coilprec_t;
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 

Generated on Thu Dec 6 20:31:14 2007 for Ephi by  doxygen 1.5.0