NAMD
ComputeBonds.C
Go to the documentation of this file.
1 
7 #include "InfoStream.h"
8 #include "ComputeBonds.h"
9 #include "Molecule.h"
10 #include "Parameters.h"
11 #include "Node.h"
12 #include "ReductionMgr.h"
13 #include "Lattice.h"
14 #include "PressureProfile.h"
15 #include "Debug.h"
16 
17 
18 // static initialization
23 
25  (Molecule* mol, int* count, int32*** byatom, Bond** structarray)
26 {
27 #ifdef MEM_OPT_VERSION
28  NAMD_die("Should not be called in BondElem::getMoleculePointers in memory optimized version!");
29 #else
30  *count = mol->numBonds;
31  *byatom = mol->bondsByAtom;
32  *structarray = mol->bonds;
33 #endif
34 }
35 
37  *v = p->bond_array;
38 }
39 
40 void BondElem::computeForce(BondElem *tuples, int ntuple, BigReal *reduction,
41  BigReal *pressureProfileData)
42 {
44  const Lattice & lattice = tuples[0].p[0]->p->lattice;
45 
46  //fepb BKR
47  const int step = tuples[0].p[0]->p->flags.step;
48  const BigReal alchLambda = simParams->getCurrentLambda(step);
49  const BigReal alchLambda2 = simParams->getCurrentLambda2(step);
50  const BigReal bond_lambda_1 = simParams->getBondLambda(alchLambda);
51  const BigReal bond_lambda_2 = simParams->getBondLambda(1-alchLambda);
52  const BigReal bond_lambda_12 = simParams->getBondLambda(alchLambda2);
53  const BigReal bond_lambda_22 = simParams->getBondLambda(1-alchLambda2);
54  Molecule *const mol = Node::Object()->molecule;
55  //fepe
56 
57  for ( int ituple=0; ituple<ntuple; ++ituple ) {
58  const BondElem &tup = tuples[ituple];
59  enum { size = 2 };
60  const AtomID (&atomID)[size](tup.atomID);
61  const int (&localIndex)[size](tup.localIndex);
62  TuplePatchElem * const(&p)[size](tup.p);
63  const Real (&scale)(tup.scale);
64  const BondValue * const(&value)(tup.value);
65 
66 #if defined(DEBUG_PROTOCELL)
67  if ((PRMIN <= atomID[0] && atomID[0] <= PRMAX) &&
68  (PRMIN <= atomID[1] && atomID[1] <= PRMAX)) {
69  int i = atomID[0];
70  int j = atomID[1];
71  if (atomID[1] < atomID[0]) {
72  i = atomID[1];
73  j = atomID[0];
74  }
75  double k = value->k;
76  double r0 = value->x0;
77  CkPrintf("%11d %11d k=%g r0=%g\n", i, j, k, r0);
78  }
79 #endif
80 
81  DebugM(1, "::computeForce() localIndex = " << localIndex[0] << " "
82  << localIndex[1] << std::endl);
83 
84  // skip Lonepair bonds (other k=0. bonds have been filtered out)
85  if (0. == value->k) continue;
86 
87  BigReal scal; // force scaling
88  BigReal energy; // energy from the bond
89 
90  //DebugM(3, "::computeForce() -- starting with bond type " << bondType << std::endl);
91 
92  // get the bond information
93  Real k = value->k * scale;
94  Real x0 = value->x0;
95  Real x1 = value->x1;
96 
97  // compute vectors between atoms and their distances
98  const Vector r12 = lattice.delta(p[0]->x[localIndex[0]].position,
99  p[1]->x[localIndex[1]].position);
100 
101  if (0. == x0) {
102  BigReal r2 = r12.length2();
103  scal = -2.0*k; // bond interaction for equilibrium length 0
104  energy = k*r2;
105  // TODO: Instead flag by mass for Drude particles, otherwise mixing and
106  // matching Drude and alchemical "twin" particles will likely not work as
107  // expected.
108  if( simParams->drudeOn && !simParams->drudeHardWallOn ) { // for Drude bonds
109  BigReal drudeBondLen = simParams->drudeBondLen;
110  BigReal drudeBondConst = simParams->drudeBondConst;
111  if ( drudeBondConst > 0 && r2 > drudeBondLen*drudeBondLen ) {
112  // add a quartic restraining potential to keep Drude bond short
113  BigReal r = sqrt(r2);
114  BigReal diff = r - drudeBondLen;
115  BigReal diff2 = diff*diff;
116 
117  scal += -4*drudeBondConst * diff2 * diff / r;
118  energy += drudeBondConst * diff2 * diff2;
119  }
120  }
121  }
122  else {
123  BigReal r = r12.length(); // Distance between atoms
124  BigReal diff = r - x0; // Compare it to the rest bond
125 
126  if (x1) {
127  // in this case, the bond represents a harmonic wall potential
128  // where x0 is the lower wall and x1 is the upper
129  diff = (r > x1 ? r - x1 : (r > x0 ? 0 : diff));
130  }
131 
132  // Add the energy from this bond to the total energy
133  energy = k*diff*diff;
134 
135  // Determine the magnitude of the force
136  diff *= -2.0*k;
137 
138  // Scale the force vector accordingly
139  scal = (diff/r);
140  }
141 
142  //fepb - BKR scaling of alchemical bonded terms
143  // NB: TI derivative is the _unscaled_ energy.
144  if ( simParams->alchOn && !simParams->singleTopology) {
145  switch ( mol->get_fep_bonded_type(atomID, 2) ) {
146  case 1:
147  reduction[bondEnergyIndex_ti_1] += energy;
148  reduction[bondEnergyIndex_f] += (bond_lambda_12 - bond_lambda_1)*energy;
149  energy *= bond_lambda_1;
150  scal *= bond_lambda_1;
151  break;
152  case 2:
153  reduction[bondEnergyIndex_ti_2] += energy;
154  reduction[bondEnergyIndex_f] += (bond_lambda_22 - bond_lambda_2)*energy;
155  energy *= bond_lambda_2;
156  scal *= bond_lambda_2;
157  break;
158  }
159  }
160  //fepe
161  const Force f12 = scal * r12;
162 
163 
164  // Now add the forces to each force vector
165  p[0]->f[localIndex[0]] += f12;
166  p[1]->f[localIndex[1]] -= f12;
167 
168  DebugM(3, "::computeForce() -- ending with delta energy " << energy << std::endl);
169  reduction[bondEnergyIndex] += energy;
170  reduction[virialIndex_XX] += f12.x * r12.x;
171  reduction[virialIndex_XY] += f12.x * r12.y;
172  reduction[virialIndex_XZ] += f12.x * r12.z;
173  reduction[virialIndex_YX] += f12.y * r12.x;
174  reduction[virialIndex_YY] += f12.y * r12.y;
175  reduction[virialIndex_YZ] += f12.y * r12.z;
176  reduction[virialIndex_ZX] += f12.z * r12.x;
177  reduction[virialIndex_ZY] += f12.z * r12.y;
178  reduction[virialIndex_ZZ] += f12.z * r12.z;
179 
180  if (pressureProfileData) {
181  BigReal z1 = p[0]->x[localIndex[0]].position.z;
182  BigReal z2 = p[1]->x[localIndex[1]].position.z;
183  int n1 = (int)floor((z1-pressureProfileMin)/pressureProfileThickness);
184  int n2 = (int)floor((z2-pressureProfileMin)/pressureProfileThickness);
187  int p1 = p[0]->x[localIndex[0]].partition;
188  int p2 = p[1]->x[localIndex[1]].partition;
189  int pn = pressureProfileAtomTypes;
191  n1, n2,
192  p1, p2, pn,
193  f12.x * r12.x, f12.y * r12.y, f12.z * r12.z,
194  pressureProfileData);
195  }
196 
197  }
198 }
199 
201 {
202  reduction->item(REDUCTION_BOND_ENERGY) += data[bondEnergyIndex];
203  reduction->item(REDUCTION_BONDED_ENERGY_F) += data[bondEnergyIndex_f];
206  ADD_TENSOR(reduction,REDUCTION_VIRIAL_NORMAL,data,virialIndex);
207 }
208 
static Node * Object()
Definition: Node.h:86
int numBonds
Definition: Molecule.h:588
static void getParameterPointers(Parameters *, const BondValue **)
Definition: ComputeBonds.C:36
Lattice & lattice
Definition: Patch.h:127
#define ADD_TENSOR(R, RL, D, DL)
Definition: ReductionMgr.h:33
void pp_reduction(int nslabs, int n1, int n2, int atype1, int atype2, int numtypes, BigReal vxx, BigReal vyy, BigReal vzz, BigReal *reduction)
static void getMoleculePointers(Molecule *, int *, int32 ***, Bond **)
Definition: ComputeBonds.C:25
Definition: Vector.h:72
static void computeForce(BondElem *, int, BigReal *, BigReal *)
Definition: ComputeBonds.C:40
SimParameters * simParameters
Definition: Node.h:181
float Real
Definition: common.h:118
int32_t int32
Definition: common.h:38
BigReal & item(int i)
Definition: ReductionMgr.h:313
#define DebugM(x, y)
Definition: Debug.h:75
BigReal z
Definition: Vector.h:74
Position position
Definition: NamdTypes.h:77
static int pressureProfileAtomTypes
Definition: ComputeBonds.h:39
Real scale
Definition: ComputeBonds.h:27
Molecule stores the structural information for the system.
Definition: Molecule.h:175
AtomID atomID[size]
Definition: ComputeBonds.h:24
static BigReal pressureProfileMin
Definition: ComputeBonds.h:41
static BigReal pressureProfileThickness
Definition: ComputeBonds.h:40
Flags flags
Definition: Patch.h:128
void pp_clamp(int &n, int nslabs)
int localIndex[size]
Definition: ComputeBonds.h:25
NAMD_HOST_DEVICE BigReal length(void) const
Definition: Vector.h:202
NAMD_HOST_DEVICE BigReal length2(void) const
Definition: Vector.h:206
uint8 partition
Definition: NamdTypes.h:80
BigReal x
Definition: Vector.h:74
int get_fep_bonded_type(const int *atomID, unsigned int order) const
Definition: Molecule.h:1477
void NAMD_die(const char *err_msg)
Definition: common.C:147
static void submitReductionData(BigReal *, SubmitReduction *)
Definition: ComputeBonds.C:200
static int pressureProfileSlabs
Definition: ComputeBonds.h:38
#define simParams
Definition: Output.C:129
int32 AtomID
Definition: NamdTypes.h:35
BigReal y
Definition: Vector.h:74
const BondValue * value
Definition: ComputeBonds.h:46
TuplePatchElem * p[size]
Definition: ComputeBonds.h:26
Molecule * molecule
Definition: Node.h:179
double BigReal
Definition: common.h:123
NAMD_HOST_DEVICE Vector delta(const Position &pos1, const Position &pos2) const
Definition: Lattice.h:149
int step
Definition: PatchTypes.h:16