00001
00007 #ifndef GRIDFORCEGRID_H
00008 #define GRIDFORCEGRID_H
00009
00010 #include <set>
00011
00012 #include "Vector.h"
00013 #include "Tensor.h"
00014 #include "SimParameters.h"
00015 #include "NamdTypes.h"
00016 #include "MStream.h"
00017 #include "charm++.h"
00018
00019
00020 #include "MGridforceParams.h"
00021
00022
00023 class GridforceFullMainGrid;
00024 class GridforceFullSubGrid;
00025
00026
00027
00028 class GridforceGrid {
00029 public:
00030 static GridforceGrid * new_grid(int gridnum, char *potfilename, SimParameters *simParams, MGridforceParams *mgridParams);
00031
00032 virtual void initialize(char *potfilename, SimParameters *simParams, MGridforceParams *mgridParams) = 0;
00033 virtual void reinitialize(SimParameters *simParams, MGridforceParams *mgridParams) = 0;
00034
00035 virtual Position get_center(void) const = 0;
00036 virtual Position get_origin(void) const = 0;
00037 virtual Tensor get_e (void) const = 0;
00038 virtual Tensor get_inv(void) const = 0;
00039 virtual Vector get_scale(void) const = 0;
00040 virtual int get_k0(void) const = 0;
00041 virtual int get_k1(void) const = 0;
00042 virtual int get_k2(void) const = 0;
00043 virtual int get_total_grids(void) const = 0;
00044
00045 virtual int get_all_gridvals(float** all_gridvals) const = 0;
00046 virtual void set_all_gridvals(float* all_gridvals, int sz) = 0;
00047
00048 Position wrap_position(const Position &pos, const Lattice &lattice);
00049 bool fits_lattice(const Lattice &lattice);
00050
00051 inline int compute_VdV(Position pos, float &V, Vector &dV) const { return -1; }
00052
00053 static void pack_grid(GridforceGrid *grid, MOStream *msg);
00054 static GridforceGrid * unpack_grid(int gridnum, MIStream *msg);
00055
00056 typedef enum {
00057 GridforceGridTypeUndefined = 0,
00058 GridforceGridTypeFull,
00059 GridforceGridTypeLite
00060 } GridforceGridType;
00061
00062 inline GridforceGridType get_grid_type(void) { return type; }
00063
00064 protected:
00065 virtual void pack(MOStream *msg) const = 0;
00066 virtual void unpack(MIStream *msg) = 0;
00067
00068 Position get_corner(int idx);
00069
00070 GridforceGridType type;
00071 int mygridnum;
00072
00073 private:
00074 Vector corners[8];
00075 };
00076
00077
00078 class GridforceFullBaseGrid {
00079 friend class GridforceFullMainGrid;
00080 friend class GridforceFullSubGrid;
00081
00082 public:
00083 GridforceFullBaseGrid(void);
00084 virtual ~GridforceFullBaseGrid();
00085
00086
00087
00088
00089 inline Position get_center(void) const { return center; }
00090 inline Position get_origin(void) const { return origin; }
00091 inline Tensor get_e (void) const { return e; }
00092 inline Tensor get_inv(void) const { return inv; }
00093 inline Vector get_scale(void) const { return scale; }
00094 virtual int get_border(void) const = 0;
00095
00096 inline float get_grid(int i0, int i1, int i2) const {
00097 return grid[grid_index(i0, i1, i2)];
00098 }
00099 inline double get_grid_d(int i0, int i1, int i2) const {
00100 return double(get_grid(i0, i1, i2));
00101 }
00102 inline void set_grid(int i0, int i1, int i2, float V) {
00103 grid[grid_index(i0, i1, i2)] = V;
00104 }
00105
00106 int compute_VdV(Position pos, float &V, Vector &dV) const;
00107
00108 inline int get_k0(void) const { return k[0]; }
00109 inline int get_k1(void) const { return k[1]; }
00110 inline int get_k2(void) const { return k[2]; }
00111
00112 protected:
00113 virtual void pack(MOStream *msg) const;
00114 virtual void unpack(MIStream *msg);
00115
00116 struct GridIndices {
00117 int inds2;
00118 int dk_hi;
00119 int dk_lo;
00120 Bool zero_derivs;
00121 };
00122
00123
00124 void readHeader(SimParameters *simParams, MGridforceParams *mgridParams);
00125
00126 inline int grid_index(int i0, int i1, int i2) const {
00127 register int inds[3] = {i0, i1, i2};
00128 #ifdef DEBUGM
00129 if (i0 < 0 || i0 >= k[0] || i1 < 0 || i1 >= k[1] || i2 < 0 || i2 >= k[2]) {
00130 char buffer[256];
00131 sprintf(buffer, "Bad grid index! (%d %d %d)", i0, i1, i2);
00132 NAMD_bug(buffer);
00133 }
00134 #endif
00135 return inds[0]*dk[0] + inds[1]*dk[1] + inds[2]*dk[2];
00136 }
00137
00138
00139 int get_inds(Position pos, int *inds, Vector &dg, Vector &gapscale) const;
00140 void compute_a(float *a, float *b) const;
00141 virtual void compute_b(float *b, int *inds, Vector gapscale) const = 0;
00142 float compute_V(float *a, float *x, float *y, float *z) const;
00143 Vector compute_dV(float *a, float *x, float *y, float *z) const;
00144 Vector compute_d2V(float *a, float *x, float *y, float *z) const;
00145 float compute_d3V(float *a, float *x, float *y, float *z) const;
00146
00147 void readSubgridHierarchy(FILE *poten, int &totalGrids);
00148
00149 FILE *poten_fp;
00150 float *grid;
00151
00152 GridforceFullSubGrid **subgrids;
00153 int numSubgrids;
00154 int generation;
00155
00156
00157 int k[3];
00158 int k_nopad[3];
00159 int size;
00160 int size_nopad;
00161 int dk[3];
00162 int dk_nopad[3];
00163 float factor;
00164
00165 Position origin;
00166 Position center;
00167 Tensor e;
00168 Tensor inv;
00169
00170 float p_sum[3];
00171 float n_sum[3];
00172 float pad_p[3];
00173 float pad_n[3];
00174 Bool cont[3];
00175 float offset[3];
00176 float gap[3];
00177 float gapinv[3];
00178
00179 Vector scale;
00180 };
00181
00182
00183 class GridforceFullMainGrid : public GridforceGrid, public GridforceFullBaseGrid {
00184 friend class GridforceFullBaseGrid;
00185 friend class GridforceFullSubGrid;
00186
00187 public:
00188 explicit GridforceFullMainGrid(int gridnum);
00189 virtual ~GridforceFullMainGrid();
00190
00191 void initialize(char *potfilename, SimParameters *simParams, MGridforceParams *mgridParams, int border);
00192 inline void initialize(char *potfilename, SimParameters *simParams, MGridforceParams *mgridParams) {
00193 initialize(potfilename, simParams, mgridParams, default_border);
00194 }
00195 void reinitialize(SimParameters *simParams, MGridforceParams *mgridParams);
00196
00197 inline Position get_center(void) const { return GridforceFullBaseGrid::get_center(); };
00198 inline Position get_origin(void) const { return GridforceFullBaseGrid::get_origin(); };
00199 inline Tensor get_e (void) const { return GridforceFullBaseGrid::get_e(); };
00200 inline Tensor get_inv(void) const { return GridforceFullBaseGrid::get_inv(); };
00201 inline Vector get_scale(void) const { return GridforceFullBaseGrid::get_scale(); };
00202 inline int get_k0(void) const { return GridforceFullBaseGrid::get_k0(); };
00203 inline int get_k1(void) const { return GridforceFullBaseGrid::get_k1(); };
00204 inline int get_k2(void) const { return GridforceFullBaseGrid::get_k2(); };
00205 inline int get_border(void) const { return border; }
00206
00207 inline int compute_VdV(Position pos, float &V, Vector &dV) const { return GridforceFullBaseGrid::compute_VdV(pos, V, dV); };
00208
00209 inline int get_total_grids(void) const { return totalGrids; }
00210
00211 protected:
00212 void pack(MOStream *msg) const;
00213 void unpack(MIStream *msg);
00214
00215 int get_all_gridvals(float **all_gridvals) const;
00216 void set_all_gridvals(float *all_gridvals, int sz);
00217
00218
00219 void compute_b(float *b, int *inds, Vector gapscale) const;
00220 void buildSubgridsFlat(void);
00221
00222 char filename[129];
00223 int totalGrids;
00224 GridforceFullSubGrid **subgrids_flat;
00225
00226
00227 static const int default_border = 1;
00228 int border;
00229 };
00230
00231
00232 class GridforceFullSubGrid : public GridforceFullBaseGrid {
00233 friend class GridforceFullBaseGrid;
00234 friend class GridforceFullMainGrid;
00235
00236 public:
00237 GridforceFullSubGrid(GridforceFullBaseGrid *parent_in);
00238
00239 void initialize(SimParameters *simParams, MGridforceParams *mgridParams);
00240
00241 inline int get_border(void) const { return 0; }
00242
00243 inline Tensor tensorMult (const Tensor &t1, const Tensor &t2) {
00244 Tensor tmp;
00245 tmp.xx = t1.xx * t2.xx + t1.xy * t2.yx + t1.xz * t2.zx;
00246 tmp.xy = t1.xx * t2.xy + t1.xy * t2.yy + t1.xz * t2.zy;
00247 tmp.xz = t1.xx * t2.xz + t1.xy * t2.yz + t1.xz * t2.zz;
00248 tmp.yx = t1.yx * t2.xx + t1.yy * t2.yx + t1.yz * t2.zx;
00249 tmp.yy = t1.yx * t2.xy + t1.yy * t2.yy + t1.yz * t2.zy;
00250 tmp.yz = t1.yx * t2.xz + t1.yy * t2.yz + t1.yz * t2.zz;
00251 tmp.zx = t1.zx * t2.xx + t1.zy * t2.yx + t1.zz * t2.zx;
00252 tmp.zy = t1.zx * t2.xy + t1.zy * t2.yy + t1.zz * t2.zy;
00253 tmp.zz = t1.zx * t2.xz + t1.zy * t2.yz + t1.zz * t2.zz;
00254 return tmp;
00255 }
00256
00257 protected:
00258 void pack(MOStream *msg) const;
00259 void unpack(MIStream *msg);
00260
00261
00262 void compute_b(float *b, int *inds, Vector gapscale) const;
00263 void addToSubgridsFlat(void);
00264
00265
00266 Tensor scale_dV;
00267 Tensor scale_d2V;
00268 float scale_d3V;
00269
00270 GridforceFullBaseGrid *parent;
00271 int pmin[3], pmax[3];
00272 GridforceFullMainGrid *maingrid;
00273 int subgridIdx;
00274 };
00275
00276
00277 class GridforceLiteGrid : public GridforceGrid {
00278 public:
00279 explicit GridforceLiteGrid(int gridnum);
00280 virtual ~GridforceLiteGrid();
00281
00282 void initialize(char *potfilename, SimParameters *simParams, MGridforceParams *mgridParams);
00283 void reinitialize(SimParameters *simParams, MGridforceParams *mgridParams);
00284
00285 inline Position get_center(void) const { return center; }
00286 inline Position get_origin(void) const { return origin; }
00287 inline Tensor get_e (void) const { return e; }
00288 inline Tensor get_inv(void) const { return inv; }
00289 inline Vector get_scale(void) const { return scale; }
00290 inline int get_k0(void) const { return k[0]; }
00291 inline int get_k1(void) const { return k[1]; }
00292 inline int get_k2(void) const { return k[2]; }
00293 inline int get_total_grids(void) const { return 1; }
00294
00295 inline float get_grid(int i0, int i1, int i2, int i3) const {
00296 return grid[grid_index(i0, i1, i2, i3)];
00297 }
00298 inline double get_grid_d(int i0, int i1, int i2, int i3) const {
00299 return double(grid[grid_index(i0, i1, i2, i3)]);
00300 }
00301 inline void set_grid(int i0, int i1, int i2, int i3, float V) {
00302 grid[grid_index(i0, i1, i2, i3)] = V;
00303 }
00304
00305 int get_all_gridvals(float** all_gridvals) const;
00306 void set_all_gridvals(float* all_gridvals, int sz);
00307
00308 int compute_VdV(Position pos, float &V, Vector &dV) const;
00309
00310 protected:
00311 void compute_derivative_grids(void);
00312 void compute_wts(float *wts, const Vector &dg) const;
00313 int get_inds(Position pos, int *inds, Vector &dg) const;
00314 float linear_interpolate(int i0, int i1, int i2, int i3, const float *wts) const;
00315
00316 void pack(MOStream *msg) const;
00317 void unpack(MIStream *msg);
00318
00319 inline int grid_index(int i0, int i1, int i2, int i3) const {
00320
00321 register int inds[4] = {i0, i1, i2, i3};
00322 return inds[0]*dk[0] + inds[1]*dk[1] + inds[2]*dk[2] + inds[3]*dk[3];
00323 }
00324
00325 float *grid;
00326
00327 int k[4];
00328 int size;
00329 int dk[4];
00330
00331 Position origin;
00332 Position center;
00333 Tensor e;
00334 Tensor inv;
00335
00336 Vector scale;
00337
00338 char filename[129];
00339 };
00340
00341 #endif