ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/branches/new_design/OOPSE-4/src/brains/MoleculeCreator.cpp
Revision: 1774
Committed: Tue Nov 23 23:12:23 2004 UTC (19 years, 7 months ago) by tim
File size: 13248 byte(s)
Log Message:
refactory NPT integrator

File Contents

# Content
1 /*
2 * Copyright (C) 2000-2004 Object Oriented Parallel Simulation Engine (OOPSE) project
3 *
4 * Contact: oopse@oopse.org
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation; either version 2.1
9 * of the License, or (at your option) any later version.
10 * All we ask is that proper credit is given for our work, which includes
11 * - but is not limited to - adding the above copyright notice to the beginning
12 * of your source code files, and to any copyright notice that you may distribute
13 * with programs based on this work.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 *
24 */
25
26 /**
27 * @file MoleculeCreator.cpp
28 * @author tlin
29 * @date 11/04/2004
30 * @time 13:44am
31 * @version 1.0
32 */
33
34 #include "brains/MoleculeCreator.hpp"
35 #include <cassert>
36
37 namespace oopse {
38
39 Molecule* MoleculeCreator::createMolecule(ForceField* ff, MoleculeStamp *molStamp, int stampId, int globalIndex) {
40 Molecule* mol = new Molecule(stampId, globalIndex, molStamp->getID());
41
42 //create atoms
43 Atom* atom;
44 AtomStamp* currentAtomStamp;
45 int nAtom = molStamp->getNAtoms();
46 for (int i = 0; i < nAtom; ++i) {
47 currentAtomStamp = molStamp->getAtom(i);
48 atom = createAtom(ff, currentAtomStamp);
49 mol->addAtom(atom);
50 }
51
52 //create rigidbodies
53 RigidBody* rb;
54 RigidBodyStamp * currentRigidBodyStamp;
55 int nRigidbodies = molStamp->getNRigidBodies();
56
57 for (int i = 0; i < nRigidbodies; ++i) {
58 currentRigidBodyStamp = molStamp->getRigidBody(i);
59 rb = createRigidBody(ff, mol, currentRigidBodyStamp);
60 mol->addRigidBody(rb);
61 }
62
63 //create bonds
64 Bond* bond;
65 BondStamp* currentBondStamp;
66 int nBonds = molStamp->getNBends();
67
68 for (int i = 0; i < nBonds; ++i) {
69 currentBondStamp = molStamp->getBend(i);
70 bond = createBond(ff, mol, currentBondStamp);
71 mol->addBond(bond);
72 }
73
74 //create bends
75 Bend* bend;
76 BendStamp* currentBendStamp;
77 int nBends = molStamp->getNBends();
78 for (int i = 0; i < nBends; ++i) {
79 currentBendStamp = molStamp->getBend(i);
80 bend = createBend(ff, mol, currentBendStamp);
81 mol->addBend(bend);
82 }
83
84 //create torsions
85 Torsion* torsion;
86 TorsionStamp* currentTorsionStamp;
87 int nTorsions = molStamp->getNTorsions();
88 for (int i = 0; i < nTorsions; ++i) {
89 currentTorsionStamp = molStamp->getTorsion(i);
90 torsion = createTorsion(ff, mol, currentTorsionStamp);
91 mol->addTorsion(torsion);
92 }
93
94 //create cutoffGroups
95 CutoffGroup* cutoffGroup;
96 CutoffGroupStamp* currentCutoffGroupStamp;
97 int nCutoffGroups = molStamp->getNCutoffGroups();
98 for (int i = 0; i < nCutoffGroups; ++i) {
99 currentCutoffGroupStamp = molStamp->getCutoffGroup(i);
100 cutoffGroup = createCutoffGroup(ff, mol, currentCutoffGroupStamp);
101 mol->addCutoffGroup(cutoffGroup);
102 }
103
104 //every free atom is a cutoff group
105 std::set<Atom*> allAtoms;
106 typename Molecule::AtomIterator ai;
107
108 //add all atoms into allAtoms set
109 for(atom = mol->beginAtom(ai); atom != NULL; atom = mol->nextAtom(ai)) {
110 allAtoms.insert(atom);
111 }
112
113 typename Molecule::CutoffGroupIterator ci;
114 CutoffGroup* cg;
115 std::set<Atom*> cutoffAtoms;
116
117 //add all of the atoms belong to cutoff groups into cutoffAtoms set
118 for (cg = mol->beginCutoffGroup(ci); cg != NULL; cg = mol->nextCutoffGroup(ci)) {
119
120 for(atom = cg->beginAtom(ai); atom != NULL; atom = cg->nextAtom(ai)) {
121 cutoffAtoms.insert(atom);
122 }
123
124 }
125
126 //find all free atoms (which do not belong to cutoff groups)
127 //performs the "difference" operation from set theory, the output range contains a copy of every
128 //element that is contained in [allAtoms.begin(), allAtoms.end()) and not contained in
129 //[cutoffAtoms.begin(), cutoffAtoms.end()).
130 std::vector<Atom*> freeAtoms;
131 std::set_difference(allAtoms.begin(), allAtoms.end(), cutoffAtoms.begin(), cutoffAtoms.end(),
132 std::back_inserter(freeAtoms.end()));
133
134 if (freeAtoms.size() != allAtoms.size() - cutoffAtoms.size()) {
135 //Some atoms in rigidAtoms are not in allAtoms, something must be wrong
136 sprintf(painCave.errMsg, "Atoms in cutoff groups are not in the atom list of the same molecule");
137
138 painCave.isFatal = 1;
139 simError();
140 }
141
142 //loop over the free atoms and then create one cutoff group for every single free atom
143 std::vector<Atom*>::iterator fai;
144
145 for (fai = freeAtoms.begin(); fai != freeAtoms.end(); ++fai) {
146 createCutoffGroup(mol, *fai);
147 mol->addCutoffGroup(cutoffGroup);
148 }
149 //create constraints
150
151 //the construction of this molecule is finished
152 mol->complete();
153
154 return mol;
155 }
156
157
158 Atom* MoleculeCreator::createAtom(ForceField* ff, Molecule* mol, AtomStamp* stamp,
159 LocalIndexManager* localIndexMan) {
160 AtomType * atomType;
161 Atom* atom;
162
163 atomType = ff->getAtomType(stamp->getType());
164
165 if (bondType == NULL) {
166 sprintf(painCave.errMsg, "Can not find Matching Atom Type for[%s]",
167 stamp->getType());
168
169 painCave.isFatal = 1;
170 simError();
171 }
172
173 //below code still have some kind of hard-coding smell
174 if (stamp->haveOrientation()){
175 DirectionalAtom* dAtom;
176 double phi;
177 double theta;
178 double psi;
179
180 dAtom = new DirectionalAtom(atomType);
181
182 // Directional Atoms have standard unit vectors which are oriented
183 // in space using the three Euler angles. We assume the standard
184 // unit vector was originally along the z axis below.
185
186 phi = stamp->getEulerPhi() * M_PI / 180.0;
187 theta = stamp->getEulerTheta() * M_PI / 180.0;
188 psi = stamp->getEulerPsi()* M_PI / 180.0;
189
190 dAtom->setUnitFrameFromEuler(phi, theta, psi);
191 atom = dAtom;
192 }
193 else{
194 atom = new Atom(atomType);
195 }
196
197 atom->setLocalIndex(localIndexMan->getNextAtomIndex());
198 }
199
200 RigidBody* MoleculeCreator::createRigidBody(MoleculeStamp *molStamp, Molecule* mol,
201 RigidBodyStamp* rbStamp,
202 LocalIndexManager* localIndexMan) {
203 Atom* atom;
204 int nAtoms;
205 Vector3d refCoor;
206 AtomStamp* atomStamp;
207
208 nAtoms = molStamp->getNMembers();
209
210 RigidBody* rb = new RigidBody();
211
212 for (int i = 0; i < nAtoms; ++i) {
213 //rbStamp->getMember(i) return the local index of current atom inside the molecule.
214 //It is not the same as local index of atom which is the index of atom at DataStorage class
215 atom = mol->getAtomAt(rbStamp->getMember(i));
216 atomStamp= molStamp->molStamp->getAtom(rbStamp->getMember(i));
217 rb->addAtom(atom, atomStamp);
218 }
219
220 //after all of the atoms are added, we need to calculate the reference coordinates
221 rb->calcRefCoords();
222
223 //set the local index of this rigid body, global index will be set later
224 rb->setLocalIndex(localIndexMan->getNextRigidBodyIndex());
225
226 //the rule for naming rigidbody MoleculeName_RB_Integer
227 //The first part is the name of the molecule
228 //The second part is alway fixed as "RB"
229 //The third part is the index of the rigidbody defined in meta-data file
230 //For example, Butane_RB_0 is a valid rigid body name of butane molecule
231 rb->setType(mol->getType() + "_RB_" + itoa(mol.getNRigidBodies()));
232
233 return rb;
234 }
235
236 Bond* MoleculeCreator::createBond(ForceField* ff, Molecule* mol, BondStamp* stamp) {
237 BondType* bondType;
238 Atom* atomA;
239 Atom* atomB;
240
241 atomA = mol->getAtomAt(stamp->getA());
242 atomB = mol->getAtomAt(stamp->getB());
243
244 assert( atomA && atomB);
245
246 bondType = ff->getBondType(atomA, atomB);
247
248 if (bondType == NULL) {
249 sprintf(painCave.errMsg, "Can not find Matching Bond Type for[%s, %s]",
250 atomA->getType().c_str(),
251 atomB->getType().c_str());
252
253 painCave.isFatal = 1;
254 simError();
255 }
256 return new Bond(atomA, atomB, bondType);
257 }
258
259 Bend* MoleculeCreator::createBend(ForceField* ff, Molecule* mol, BendStamp* stamp) {
260 bool isGhostBend = false;
261 int ghostIndex;
262
263
264 //
265 if (stamp->haveExtras()){
266 LinkedAssign* extras = currentBend->getExtras();
267 LinkedAssign* currentExtra = extras;
268
269 while (currentExtra != NULL){
270 if (!strcmp(currentExtra->getlhs(), "ghostVectorSource")){
271 switch (currentExtra->getType()){
272 case 0:
273 ghostIndex = currentExtra->getInt();
274 isGhostBend = true;
275 break;
276
277 default:
278 sprintf(painCave.errMsg,
279 "SimSetup Error: ghostVectorSource must be an int.\n");
280 painCave.isFatal = 1;
281 simError();
282 }
283 } else{
284 sprintf(painCave.errMsg,
285 "SimSetup Error: unhandled bend assignment:\n");
286 painCave.isFatal = 1;
287 simError();
288 }
289 currentExtra = currentExtra->getNext();
290 }
291
292 }
293
294 if (isGhostBend) {
295
296 int indexA = stamp->getA();
297 int indexB= stamp->getB();
298
299 assert(indexA != indexB);
300
301 int normalIndex;
302 if (indexA == ghostIndex) {
303 normalIndex = indexB;
304 } else if (indexB == ghostIndex) {
305 normalIndex = indexA;
306 }
307
308 Atom* normalAtom = mol->getAtomAt(normalIndex) ;
309 Atom* ghostAtom = mol->getAtomAt(ghostIndex);
310
311 BendType* bendType = ff->getBendType(normalAtom->getType(), ghostAtom->getType(), "GHOST");
312
313 if (bendType == NULL) {
314 sprintf(painCave.errMsg, "Can not find Matching Bend Type for[%s, %s, %s]",
315 normalAtom->getType().c_str(),
316 ghostAtom->getType().c_str(),
317 "GHOST");
318
319 painCave.isFatal = 1;
320 simError();
321 }
322
323 return new GhostBend(normalAtom, ghostAtom, bendType);
324
325 } else {
326
327 Atom* atomA = mol->getAtomAt(stamp->getA());
328 Atom* atomB = mol->getAtomAt(stamp->getB());
329 Atom* atomC = mol->getAtomAt(stamp->getC());
330
331 assert( atomA && atomB && atomC);
332
333 BendType* bendType = ff->getBendType(atomA->getType(), atomB->getType(), atomC->getType());
334
335 if (bendType == NULL) {
336 sprintf(painCave.errMsg, "Can not find Matching Bend Type for[%s, %s, %s]",
337 atomA->getType().c_str(),
338 atomB->getType().c_str(),
339 atomC->getType().c_str());
340
341 painCave.isFatal = 1;
342 simError();
343 }
344
345 return new Bend(atomA, atomB, atomC, bendType);
346 }
347 }
348
349 Torsion* MoleculeCreator::createTorsion(ForceField* ff, Molecule* mol, TorsionStamp* stamp) {
350 TorsionType* torsionType;
351 Atom* atomA;
352 Atom* atomB;
353 Atom* atomC;
354 Atom* atomD;
355
356 atomA = mol->getAtomAt(stamp->getA());
357 atomB = mol->getAtomAt(stamp->getB());
358 atomC = mol->getAtomAt(stamp->getC());
359 atomD = mol->getAtomAt(stamp->getD());
360
361 assert(atomA && atomB && atomC && atomD);
362
363 torsionType = ff->getTosionType(atomA->getType(), atomB->getType(),
364 atomC->getType(), atomD->getType());
365
366 if (torsionType == NULL) {
367 sprintf(painCave.errMsg, "Can not find Matching Torsion Type for[%s, %s, %s, %s]",
368 atomA->getType().c_str(),
369 atomB->getType().c_str(),
370 atomC->getType().c_str(),
371 atomD->getType().c_str());
372
373 painCave.isFatal = 1;
374 simError();
375 }
376
377 return new Torsion(atomA, atomB, torsionType);
378 }
379
380 CutoffGroup* MoleculeCreator::createCutoffGroup(Molecule* mol, CutoffGroupStamp* stamp) {
381 int nAtoms;
382 CutoffGroup* cg;
383 Atom* atom;
384 cg = new CutoffGroup();
385
386 nAtoms = stamp->getNMembers();
387 for (int i =0; i < nAtoms; ++i) {
388 atom = mol->getAtomAt(stamp->getMember(i));
389 assert(atom);
390 cg->addAtom(atom);
391 }
392
393 return cg;
394 }
395
396 CutoffGroup* MoleculeCreator::createCutoffGroup(Molecule * mol, Atom* atom) {
397 CutoffGroup* cg;
398 cg = new CutoffGroup();
399 cg->addAtom();
400 return cg;
401 }
402 //Constraint* MoleculeCreator::createConstraint() {
403
404 //}
405
406 }

Properties

Name Value
svn:executable *