NAMD
GlobalMasterSMD.C
Go to the documentation of this file.
1 
7 #include "InfoStream.h"
8 #include "Node.h"
9 #include "Molecule.h"
10 #include "NamdTypes.h"
11 
12 #include "GlobalMaster.h"
13 #include "GlobalMasterSMD.h"
14 #include "PDB.h"
15 #include "PDBData.h"
16 
17 /* XXX necessary?
18 #include <iostream.h>
19 #if !defined(WIN32) || defined(__CYGWIN__)
20 #include <strstream.h>
21 #else
22 #include <strstrea.h>
23 #endif
24 #include <string.h>
25 */
26 
27 //#define DEBUGM
28 #define MIN_DEBUG_LEVEL 1
29 #include "Debug.h"
30 
32  BigReal transverse_spring_constant, BigReal velocity,
33  const Vector direction, int output_frequency,
34  int first_timestep, const char *filename,
35  int numAtoms) {
36  DebugM(3,"initialize called\n");
37  moveVel = velocity;
38  moveDir = direction;
39  outputFreq = output_frequency;
40  k = spring_constant;
41  k2 = transverse_spring_constant;
42  currentTime = first_timestep;
43 
44  parseAtoms(filename,numAtoms);
45  iout << iINFO << requestedGroups()[0].size() << " SMD ATOMS\n" << endi;
46  DebugM(1,"done with initialize\n");
47 }
48 
49 void GlobalMasterSMD::parseAtoms(const char *file, int numTotalAtoms) {
50  DebugM(3,"parseAtoms called\n");
51  PDB smdpdb(file);
52  int numatoms = smdpdb.num_atoms();
53  if (numatoms < 1)
54  NAMD_die("No atoms found in SMDFile\n");
55  if (numatoms != numTotalAtoms)
56  NAMD_die("The number of atoms in SMDFile must be equal to the total number of atoms in the structure!");
57 
58  // add a single group
59  modifyRequestedGroups().resize(1);
60 
61  // add all the required atoms to the group
62 
63  // also compute the center of mass of these atoms
64  cm.x = cm.y = cm.z = 0;
65  Molecule *mol = Node::Object()->molecule; // to get masses
66  BigReal imass = 0;
67 
68  for (int i=0; i<numatoms; i++) {
69 #ifdef MEM_OPT_VERSION
70  PDBCoreData *atom = smdpdb.atom(i);
71 #else
72  PDBAtom *atom = smdpdb.atom(i); // get an atom from the file
73 #endif
74  if (atom->occupancy()) { // if occupancy is not 0, then add it!
75  // add the atom to the list
76  modifyRequestedGroups()[0].add(i);
77 
78  // compute the center of mass
79  BigReal mass = mol->atommass(i);
80  cm.x += atom->xcoor()*mass;
81  cm.y += atom->ycoor()*mass;
82  cm.z += atom->zcoor()*mass;
83  imass += mass;
84  }
85  }
86  if (imass == 0) // we didn't find any!
87  NAMD_die("SMDFile contained no SMD atoms (atoms w/ nonzero occupancy)\n");
88 
89  // now compute the center of mass
90  cm /= imass;
91  DebugM(1,"done with parseAtoms\n");
92 
94 }
95 
97 
98 void GlobalMasterSMD::calculate() {
99  DebugM(3,"calculate called\n");
100 
101  // make extra-sure we have been set up correctly
102  if(!requestedGroups().size() == 1)
103  NAMD_die("Internal error: uninitialized!");
104 
105  // set the correct forces
106  Position curcm = *getGroupPositionBegin(); // get the center of mass
107  DebugM(1,"Current CM "<<cm<<"\n");
108  Position diffCOM = curcm - cm;
109  BigReal diff = diffCOM*moveDir;
110  BigReal preFactor = moveVel*currentTime - diff;
111  // second term below is along transverse direction: -diff*moveDir + (diff*moveDir - (curcm-cm)) = -(curcm-cm)
112  // so if k = k2 and moveVel = 0, we see that f = -k * (curcm - cm), the desired result
113  Force f = k*preFactor*moveDir + k2*(diff*moveDir - diffCOM);
115  modifyGroupForces()[0] = f;
116  // calculate energy
117  // energy for restraint along the direction
118  BigReal energy = 0.5*k*preFactor*preFactor;
119  energy += 0.5*k2*(diffCOM.length2() - diff*diff);
120  reduction->item(REDUCTION_MISC_ENERGY) += energy;
121  reduction->submit();
122  // print some output sometimes
123  if (currentTime % outputFreq == 0)
124  output(currentTime, curcm, f);
125 
126  // keep track of the number of timesteps
127  currentTime++;
128 
129  DebugM(1,"done with calculate: force: "<<f<<"\n");
130 }
131 
132 void GlobalMasterSMD::output(int t, Position p, Force f) {
133  DebugM(3,"output called\n");
134 
135  if (t % (100*outputFreq) == 0)
136  iout << "SMDTITLE: TS CURRENT_POSITION FORCE\n" << endi;
137  iout << "SMD " << t << ' ' << p << ' ' << f*PNPERKCALMOL << '\n' << endi;
138 
139  DebugM(1,"done with output\n");
140 }
static Node * Object()
Definition: Node.h:86
std::ostream & iINFO(std::ostream &s)
Definition: InfoStream.C:81
Definition: PDB.h:36
Definition: Vector.h:72
static int numatoms
Definition: ScriptTcl.C:65
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
SubmitReduction * willSubmit(int setID, int size=-1)
Definition: ReductionMgr.C:366
BigReal zcoor(void)
Definition: PDBData.C:433
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
const ResizeArray< AtomIDList > & requestedGroups()
Definition: GlobalMaster.C:150
void resize(int i)
Definition: ResizeArray.h:84
GlobalMasterSMD(BigReal spring_constant, BigReal transverse_spring_constant, BigReal velocity, const Vector direction, int output_frequency, int first_timestep, const char *filename, int)
BigReal ycoor(void)
Definition: PDBData.C:429
NAMD_HOST_DEVICE BigReal length2(void) const
Definition: Vector.h:206
BigReal x
Definition: Vector.h:74
ResizeArray< AtomIDList > & modifyRequestedGroups()
Definition: GlobalMaster.C:185
void NAMD_die(const char *err_msg)
Definition: common.C:147
ForceList & modifyGroupForces()
Definition: GlobalMaster.C:168
Real atommass(int anum) const
Definition: Molecule.h:1107
BigReal xcoor(void)
Definition: PDBData.C:425
#define PNPERKCALMOL
Definition: common.h:59
BigReal y
Definition: Vector.h:74
BigReal occupancy(void)
Definition: PDBData.C:444
void submit(void)
Definition: ReductionMgr.h:324
PositionList::const_iterator getGroupPositionBegin()
Definition: GlobalMaster.C:203
Molecule * molecule
Definition: Node.h:179
double BigReal
Definition: common.h:123