NAMD
ComputeGridForce.C
Go to the documentation of this file.
1 
7 #include "ComputeGridForce.h"
8 #include "GridForceGrid.h"
9 #include "Node.h"
10 
11 #define MIN_DEBUG_LEVEL 3
12 //#define DEBUGM
13 #include "Debug.h"
14 #include "GridForceGrid.inl"
15 #include "MGridforceParams.h"
16 
17 //#define GF_FORCE_OUTPUT
18 //#define GF_FORCE_OUTPUT_FREQ 100
19 #define GF_OVERLAPCHECK_FREQ 1000
20 
21 
23  : ComputeHomePatch(c,pid)
24 {
25 
27  idxChecked=false;
28 }
29 /* END OF FUNCTION ComputeGridForce */
30 
31 
33 {
34  delete reduction;
35 }
36 /* END OF FUNCTION ~ComputeGridForce */
37 
38 
41 {
42  // Loop through and check each atom
43  int numGridForcedAtoms=0;
44  Molecule *mol = Node::Object()->molecule;
45  int numGrids = mol->numGridforceGrids;
48  for (int gridnum = 0; gridnum < numGrids; gridnum++) {
49  for (int i = 0; i < numAtoms; i++)
50  if (mol->is_atom_gridforced(a[i].id, gridnum)){
51  numGridForcedAtoms++;
52  }
53  }
54  return numGridForcedAtoms;
55 }
56 
57 void ComputeGridForce::createGridForcedIdxList(int numGridForcedAtoms)
58 {
59  // Loop through and check each atom
60  Molecule *mol = Node::Object()->molecule;
61  int numGrids = mol->numGridforceGrids;
63  if(gridForcedAtomIdxList.size()>0)
64  {
65  //empty everything
66  for (int gridnum = 0; gridnum < gridForcedAtomIdxList.size(); gridnum++) {
67  gridForcedAtomIdxList[gridnum].clear();
68  }
69  gridForcedAtomIdxList.clear();
70  }
71  else
72  {
73  gridForcedAtomIdxList.reserve(numGrids);
74  }
76 
77  for (int gridnum = 0; gridnum < numGrids; gridnum++) {
78  std::vector <int> thisGrid;
79  thisGrid.reserve(numGridForcedAtoms);
80  for (int i = 0; i < numAtoms; i++)
81  if (mol->is_atom_gridforced(a[i].id, gridnum)){
82  thisGrid.push_back(i);
83  }
84  gridForcedAtomIdxList.push_back(thisGrid);
85  }
86 }
87 
88 
89 template <class T> void ComputeGridForce::do_calc(T *grid, int gridnum, FullAtom *p, int numAtoms, Molecule *mol, Force *forces, BigReal &energy, Force &extForce, Tensor &extVirial)
90 {
91  Real scale; // Scaling factor
92  Charge charge; // Charge
93  Vector dV;
94  float V;
95 
96  Vector gfScale = grid->get_scale();
97  DebugM(3, "doCalc()\n" << endi);
98 #ifdef DEBUGM
99  int gridForcedCount=0;
100 #endif
101  if(useIndexList)
102  {
103  // loop through the atoms we know need gridforce
104  DebugM(3, "doCalc() using index \n" << endi);
105  std::vector<int> &thisGrid=gridForcedAtomIdxList[gridnum];
106  for (int idx = 0; idx < thisGrid.size(); idx++)
107  {
108  int i=thisGrid[idx];
109 #ifdef DEBUGM
110  gridForcedCount++;
111 #endif
112  DebugM(1, "Atom " << p[i].id << " is gridforced\n" << endi);
113 
114  mol->get_gridfrc_params(scale, charge, p[i].id, gridnum);
115 
116  // Wrap coordinates using grid center
117  Position pos = grid->wrap_position(p[i].position, homePatch->lattice);
118  DebugM(1, "pos = " << pos << "\n" << endi);
119 
120  // Here's where the action happens
121  int err = grid->compute_VdV(pos, V, dV);
122 
123  if (err) {
124  DebugM(2, "V = 0\n" << endi);
125  DebugM(2, "dV = 0 0 0\n" << endi);
126  continue; // This means the current atom is outside the potential
127  }
128 
129  //Force force = scale * Tensor::diagonal(gfScale) * (-charge * dV);
130  Force force = -charge * scale * Vector(gfScale.x * dV.x, gfScale.y * dV.y, gfScale.z * dV.z);
131 
132 #ifdef DEBUGM
133  DebugM(2, "scale = " << scale << " gfScale = " << gfScale << " charge = " << charge << "\n" << endi);
134 
135  DebugM(2, "V = " << V << "\n" << endi);
136  DebugM(2, "dV = " << dV << "\n" << endi);
137  DebugM(2, "grid = " << gridnum << " force = " << force << " pos = " << pos << " V = " << V << " dV = " << dV << " step = " << homePatch->flags.step << " index = " << p[i].id << "\n" << endi);
138 
139  DebugM(1, "transform = " << (int)p[i].transform.i << " "
140  << (int)p[i].transform.j << " " << (int)p[i].transform.k << "\n" << endi);
141 
142  if (V != V) {
143  iout << iWARN << "V is NaN!\natomid = " << p[i].id << " loc = " << p[i].position << " V = " << V << "\n" << endi;
144  }
145 #endif
146 
147  forces[i] += force;
148  extForce += force;
149  Position vpos = homePatch->lattice.reverse_transform(p[i].position, p[i].transform);
150 
151  //energy -= force * (vpos - homePatch->lattice.origin());
152  if (gfScale.x == gfScale.y && gfScale.x == gfScale.z)
153  {
154  // only makes sense when scaling is isotropic
155  energy += scale * gfScale.x * (charge * V);
156 
157  // add something when we're off the grid? I'm thinking no
158  }
159  extVirial += outer(force,vpos);
160  }
161  }
162  else
163  {
164  // Loop through and check each atom
165  for (int i = 0; i < numAtoms; i++) {
166  if (mol->is_atom_gridforced(p[i].id, gridnum))
167  {
168  DebugM(1, "Atom " << p[i].id << " is gridforced\n" << endi);
169 #ifdef DEBUGM
170  gridForcedCount++;
171 #endif
172  mol->get_gridfrc_params(scale, charge, p[i].id, gridnum);
173 
174  // Wrap coordinates using grid center
175  Position pos = grid->wrap_position(p[i].position, homePatch->lattice);
176  DebugM(1, "pos = " << pos << "\n" << endi);
177 
178  // Here's where the action happens
179  int err = grid->compute_VdV(pos, V, dV);
180 
181  if (err) {
182  DebugM(2, "V = 0\n" << endi);
183  DebugM(2, "dV = 0 0 0\n" << endi);
184  continue; // This means the current atom is outside the potential
185  }
186 
187  //Force force = scale * Tensor::diagonal(gfScale) * (-charge * dV);
188  Force force = -charge * scale * Vector(gfScale.x * dV.x, gfScale.y * dV.y, gfScale.z * dV.z);
189 
190 #ifdef DEBUGM
191  DebugM(2, "scale = " << scale << " gfScale = " << gfScale << " charge = " << charge << "\n" << endi);
192 
193  DebugM(2, "V = " << V << "\n" << endi);
194  DebugM(2, "dV = " << dV << "\n" << endi);
195  DebugM(2, "grid = " << gridnum << " force = " << force << " pos = " << pos << " V = " << V << " dV = " << dV << " step = " << homePatch->flags.step << " index = " << p[i].id << "\n" << endi);
196 
197  DebugM(1, "transform = " << (int)p[i].transform.i << " "
198  << (int)p[i].transform.j << " " << (int)p[i].transform.k << "\n" << endi);
199 
200  if (V != V) {
201  iout << iWARN << "V is NaN!\natomid = " << p[i].id << " loc = " << p[i].position << " V = " << V << "\n" << endi;
202  }
203 #endif
204 
205  forces[i] += force;
206  extForce += force;
207  Position vpos = homePatch->lattice.reverse_transform(p[i].position, p[i].transform);
208 
209  //energy -= force * (vpos - homePatch->lattice.origin());
210  if (gfScale.x == gfScale.y && gfScale.x == gfScale.z)
211  {
212  // only makes sense when scaling is isotropic
213  energy += scale * gfScale.x * (charge * V);
214 
215  // add something when we're off the grid? I'm thinking no
216  }
217  extVirial += outer(force,vpos);
218  }
219  }
220  }
221  DebugM(3, "doCalc() patch "<<homePatch->getPatchID()<<" computed "<< gridForcedCount<<" of "<< numAtoms <<"\n" << endi);
222  DebugM(3, "doCalc() done\n" << endi);
223 }
224 
226 {
228  Molecule *mol = Node::Object()->molecule;
229 
230  Force *forces = r->f[Results::normal];
231  BigReal energy = 0;
232  Force extForce = 0.;
233  Tensor extVirial;
234 
235  int numAtoms = homePatch->getNumAtoms();
236 
237  if ( mol->numGridforceGrids < 1 ) NAMD_bug("No grids loaded in ComputeGridForce::doForce()");
238 
239  DebugM(3, "doForce()\n" << endi);
241  DebugM(3, "doForce() patch " << homePatch->getPatchID()<<" checking grid \n" << endi);
242  int numGridForcedAtoms= checkGridForceRatio();
243  int numAtoms = homePatch->getNumAtoms();
244  useIndexList=(float)numGridForcedAtoms/(float)numAtoms<0.5;
245  if(useIndexList)
246  {
247  createGridForcedIdxList(numGridForcedAtoms);
248  }
250  }
251 
252  for (int gridnum = 0; gridnum < mol->numGridforceGrids; gridnum++) {
253  GridforceGrid *grid = mol->get_gridfrc_grid(gridnum);
254 
255  const Vector gfScale = grid->get_scale();
256  if ((gfScale.x == 0.0) && (gfScale.y == 0.0) && (gfScale.z == 0.0)) {
257  DebugM(3, "Skipping grid index " << gridnum << "\n" << endi);
258  continue;
259  }
260 
262  // only check on node 0 and every GF_OVERLAPCHECK_FREQ steps
263  if (simParams->langevinPistonOn || simParams->berendsenPressureOn) {
264  // check for grid overlap if pressure control is on
265  // not needed without pressure control, since the check is also performed on startup
266  if (!grid->fits_lattice(homePatch->lattice)) {
267  char errmsg[512];
268  if (grid->get_checksize()) {
269  sprintf(errmsg, "Warning: Periodic cell basis too small for Gridforce grid %d. Set gridforcechecksize off in configuration file to ignore.\n", gridnum);
270  NAMD_die(errmsg);
271  }
272  }
273  }
274  }
275 
276  if (homePatch->flags.step % 100 == 1) {
277  Position center = grid->get_center();
278  DebugM(3, "center = " << center << "\n" << endi);
279  DebugM(3, "e = " << grid->get_e() << "\n" << endi);
280  }
281 
284  do_calc(g, gridnum, p, numAtoms, mol, forces, energy, extForce, extVirial);
285  } else if (grid->get_grid_type() == GridforceGrid::GridforceGridTypeLite) {
287  do_calc(g, gridnum, p, numAtoms, mol, forces, energy, extForce, extVirial);
288  }
289  }
291  ADD_VECTOR_OBJECT(reduction,REDUCTION_EXT_FORCE_NORMAL,extForce);
292  ADD_TENSOR_OBJECT(reduction,REDUCTION_VIRIAL_NORMAL,extVirial);
293  reduction->submit();
294  DebugM(3, "doForce() done\n" << endi);
295 }
296 /* END OF FUNCTION force */
static Node * Object()
Definition: Node.h:86
int getNumAtoms() const
Definition: Patch.h:105
GridforceGrid * get_gridfrc_grid(int gridnum) const
Definition: Molecule.h:1363
NAMD_HOST_DEVICE Position reverse_transform(Position data, const Transform &t) const
Definition: Lattice.h:143
int32 ComputeID
Definition: NamdTypes.h:278
Lattice & lattice
Definition: Patch.h:127
NAMD_HOST_DEVICE Tensor outer(const Vector &v1, const Vector &v2)
Definition: Tensor.h:241
Definition: Vector.h:72
#define ADD_TENSOR_OBJECT(R, RL, D)
Definition: ReductionMgr.h:44
SimParameters * simParameters
Definition: Node.h:181
ComputeGridForce(ComputeID c, PatchID pid)
float Real
Definition: common.h:118
BigReal & item(int i)
Definition: ReductionMgr.h:313
#define DebugM(x, y)
Definition: Debug.h:75
std::ostream & endi(std::ostream &s)
Definition: InfoStream.C:54
BigReal z
Definition: Vector.h:74
Position position
Definition: NamdTypes.h:77
#define GF_OVERLAPCHECK_FREQ
int numGridforceGrids
Definition: Molecule.h:624
std::ostream & iWARN(std::ostream &s)
Definition: InfoStream.C:82
SubmitReduction * willSubmit(int setID, int size=-1)
Definition: ReductionMgr.C:366
void createGridForcedIdxList(int numGridForcedAtoms)
void doForce(FullAtom *p, Results *r)
int8 j
Definition: NamdTypes.h:44
static ReductionMgr * Object(void)
Definition: ReductionMgr.h:279
#define iout
Definition: InfoStream.h:51
Molecule stores the structural information for the system.
Definition: Molecule.h:175
bool gridForceIdxChecked
Definition: HomePatch.h:402
Flags flags
Definition: Patch.h:128
uint32 id
Definition: NamdTypes.h:156
FullAtomList & getAtomList()
Definition: HomePatch.h:528
bool fits_lattice(const Lattice &lattice)
Definition: GridForceGrid.C:84
void NAMD_bug(const char *err_msg)
Definition: common.C:195
virtual Position get_center(void) const =0
Force * f[maxNumForces]
Definition: PatchTypes.h:146
virtual ~ComputeGridForce()
SubmitReduction * reduction
BigReal x
Definition: Vector.h:74
PatchID getPatchID() const
Definition: Patch.h:114
void get_gridfrc_params(Real &k, Charge &q, int atomnum, int gridnum) const
Definition: Molecule.h:1357
int checkGridForceRatio()
if fewer than half the atoms in the patch need grid forces, use a list
void NAMD_die(const char *err_msg)
Definition: common.C:147
virtual Bool get_checksize(void) const =0
virtual Vector get_scale(void) const =0
#define simParams
Definition: Output.C:129
iterator begin(void)
Definition: ResizeArray.h:36
Definition: Tensor.h:15
BigReal y
Definition: Vector.h:74
virtual Tensor get_e(void) const =0
#define ADD_VECTOR_OBJECT(R, RL, D)
Definition: ReductionMgr.h:28
void do_calc(T *grid, int gridnum, FullAtom *p, int numAtoms, Molecule *mol, Force *forces, BigReal &energy, Force &extForce, Tensor &extVirial)
Bool is_atom_gridforced(int atomnum, int gridnum) const
Definition: Molecule.h:1249
GridforceGridType get_grid_type(void)
Definition: GridForceGrid.h:64
void submit(void)
Definition: ReductionMgr.h:324
int32 PatchID
Definition: NamdTypes.h:277
Molecule * molecule
Definition: Node.h:179
float Charge
Definition: NamdTypes.h:38
std::vector< std::vector< int > > gridForcedAtomIdxList
HomePatch * homePatch
int8 k
Definition: NamdTypes.h:44
double BigReal
Definition: common.h:123
Transform transform
Definition: NamdTypes.h:219
int step
Definition: PatchTypes.h:16