ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/branches/new_design/OOPSE-4/src/brains/MoleculeCreator.cpp
Revision: 1857
Committed: Mon Dec 6 20:15:02 2004 UTC (19 years, 7 months ago) by tim
File size: 13583 byte(s)
Log Message:
short range interaction for butane is correct.Still something wrong with long range one

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 <cassert>
35
36 #include "brains/MoleculeCreator.hpp"
37 #include "primitives/GhostBend.hpp"
38 #include "types/DirectionalAtomType.hpp"
39 #include "utils/simError.h"
40 #include "utils/StringUtils.hpp"
41
42 namespace oopse {
43
44 Molecule* MoleculeCreator::createMolecule(ForceField* ff, MoleculeStamp *molStamp,
45 int stampId, int globalIndex, LocalIndexManager* localIndexMan) {
46
47 Molecule* mol = new Molecule(stampId, globalIndex, molStamp->getID());
48
49 //create atoms
50 Atom* atom;
51 AtomStamp* currentAtomStamp;
52 int nAtom = molStamp->getNAtoms();
53 for (int i = 0; i < nAtom; ++i) {
54 currentAtomStamp = molStamp->getAtom(i);
55 atom = createAtom(ff, mol, currentAtomStamp, localIndexMan);
56 mol->addAtom(atom);
57 }
58
59 //create rigidbodies
60 RigidBody* rb;
61 RigidBodyStamp * currentRigidBodyStamp;
62 int nRigidbodies = molStamp->getNRigidBodies();
63
64 for (int i = 0; i < nRigidbodies; ++i) {
65 currentRigidBodyStamp = molStamp->getRigidBody(i);
66 rb = createRigidBody(molStamp, mol, currentRigidBodyStamp, localIndexMan);
67 mol->addRigidBody(rb);
68 }
69
70 //create bonds
71 Bond* bond;
72 BondStamp* currentBondStamp;
73 int nBonds = molStamp->getNBonds();
74
75 for (int i = 0; i < nBonds; ++i) {
76 currentBondStamp = molStamp->getBond(i);
77 bond = createBond(ff, mol, currentBondStamp);
78 mol->addBond(bond);
79 }
80
81 //create bends
82 Bend* bend;
83 BendStamp* currentBendStamp;
84 int nBends = molStamp->getNBends();
85 for (int i = 0; i < nBends; ++i) {
86 currentBendStamp = molStamp->getBend(i);
87 bend = createBend(ff, mol, currentBendStamp);
88 mol->addBend(bend);
89 }
90
91 //create torsions
92 Torsion* torsion;
93 TorsionStamp* currentTorsionStamp;
94 int nTorsions = molStamp->getNTorsions();
95 for (int i = 0; i < nTorsions; ++i) {
96 currentTorsionStamp = molStamp->getTorsion(i);
97 torsion = createTorsion(ff, mol, currentTorsionStamp);
98 mol->addTorsion(torsion);
99 }
100
101 //create cutoffGroups
102 CutoffGroup* cutoffGroup;
103 CutoffGroupStamp* currentCutoffGroupStamp;
104 int nCutoffGroups = molStamp->getNCutoffGroups();
105 for (int i = 0; i < nCutoffGroups; ++i) {
106 currentCutoffGroupStamp = molStamp->getCutoffGroup(i);
107 cutoffGroup = createCutoffGroup(mol, currentCutoffGroupStamp);
108 mol->addCutoffGroup(cutoffGroup);
109 }
110
111 //every free atom is a cutoff group
112 std::set<Atom*> allAtoms;
113 Molecule::AtomIterator ai;
114
115 //add all atoms into allAtoms set
116 for(atom = mol->beginAtom(ai); atom != NULL; atom = mol->nextAtom(ai)) {
117 allAtoms.insert(atom);
118 }
119
120 Molecule::CutoffGroupIterator ci;
121 CutoffGroup* cg;
122 std::set<Atom*> cutoffAtoms;
123
124 //add all of the atoms belong to cutoff groups into cutoffAtoms set
125 for (cg = mol->beginCutoffGroup(ci); cg != NULL; cg = mol->nextCutoffGroup(ci)) {
126
127 for(atom = cg->beginAtom(ai); atom != NULL; atom = cg->nextAtom(ai)) {
128 cutoffAtoms.insert(atom);
129 }
130
131 }
132
133 //find all free atoms (which do not belong to cutoff groups)
134 //performs the "difference" operation from set theory, the output range contains a copy of every
135 //element that is contained in [allAtoms.begin(), allAtoms.end()) and not contained in
136 //[cutoffAtoms.begin(), cutoffAtoms.end()).
137 std::vector<Atom*> freeAtoms;
138 std::set_difference(allAtoms.begin(), allAtoms.end(), cutoffAtoms.begin(), cutoffAtoms.end(),
139 std::back_inserter(freeAtoms));
140
141 if (freeAtoms.size() != allAtoms.size() - cutoffAtoms.size()) {
142 //Some atoms in rigidAtoms are not in allAtoms, something must be wrong
143 sprintf(painCave.errMsg, "Atoms in cutoff groups are not in the atom list of the same molecule");
144
145 painCave.isFatal = 1;
146 simError();
147 }
148
149 //loop over the free atoms and then create one cutoff group for every single free atom
150 std::vector<Atom*>::iterator fai;
151
152 for (fai = freeAtoms.begin(); fai != freeAtoms.end(); ++fai) {
153 cutoffGroup = createCutoffGroup(mol, *fai);
154 mol->addCutoffGroup(cutoffGroup);
155 }
156 //create constraints
157
158 //the construction of this molecule is finished
159 mol->complete();
160
161 return mol;
162 }
163
164
165 Atom* MoleculeCreator::createAtom(ForceField* ff, Molecule* mol, AtomStamp* stamp,
166 LocalIndexManager* localIndexMan) {
167 AtomType * atomType;
168 Atom* atom;
169
170 atomType = ff->getAtomType(stamp->getType());
171
172 if (atomType == NULL) {
173 sprintf(painCave.errMsg, "Can not find Matching Atom Type for[%s]",
174 stamp->getType());
175
176 painCave.isFatal = 1;
177 simError();
178 }
179
180 //below code still have some kind of hard-coding smell
181 if (atomType->isDirectional()){
182
183 DirectionalAtomType* dAtomType = dynamic_cast<DirectionalAtomType*>(atomType);
184
185 if (dAtomType == NULL) {
186 sprintf(painCave.errMsg, "Can not cast AtomType to DirectionalAtomType");
187
188 painCave.isFatal = 1;
189 simError();
190 }
191
192 DirectionalAtom* dAtom;
193 dAtom = new DirectionalAtom(dAtomType);
194 atom = dAtom;
195 }
196 else{
197 atom = new Atom(atomType);
198 }
199
200 atom->setLocalIndex(localIndexMan->getNextAtomIndex());
201
202 return atom;
203 }
204
205 RigidBody* MoleculeCreator::createRigidBody(MoleculeStamp *molStamp, Molecule* mol,
206 RigidBodyStamp* rbStamp,
207 LocalIndexManager* localIndexMan) {
208 Atom* atom;
209 int nAtoms;
210 Vector3d refCoor;
211 AtomStamp* atomStamp;
212
213 RigidBody* rb = new RigidBody();
214 nAtoms = rbStamp->getNMembers();
215 for (int i = 0; i < nAtoms; ++i) {
216 //rbStamp->getMember(i) return the local index of current atom inside the molecule.
217 //It is not the same as local index of atom which is the index of atom at DataStorage class
218 atom = mol->getAtomAt(rbStamp->getMember(i));
219 atomStamp= molStamp->getAtom(rbStamp->getMember(i));
220 rb->addAtom(atom, atomStamp);
221 }
222
223 //after all of the atoms are added, we need to calculate the reference coordinates
224 rb->calcRefCoords();
225
226 //set the local index of this rigid body, global index will be set later
227 rb->setLocalIndex(localIndexMan->getNextRigidBodyIndex());
228
229 //the rule for naming rigidbody MoleculeName_RB_Integer
230 //The first part is the name of the molecule
231 //The second part is alway fixed as "RB"
232 //The third part is the index of the rigidbody defined in meta-data file
233 //For example, Butane_RB_0 is a valid rigid body name of butane molecule
234 /**@todo replace itoa by lexi_cast */
235 rb->setType(mol->getType() + "_RB_" + toString(mol->getNRigidBodies()));
236
237 return rb;
238 }
239
240 Bond* MoleculeCreator::createBond(ForceField* ff, Molecule* mol, BondStamp* stamp) {
241 BondType* bondType;
242 Atom* atomA;
243 Atom* atomB;
244
245 atomA = mol->getAtomAt(stamp->getA());
246 atomB = mol->getAtomAt(stamp->getB());
247
248 assert( atomA && atomB);
249
250 bondType = ff->getBondType(atomA->getType(), atomB->getType());
251
252 if (bondType == NULL) {
253 sprintf(painCave.errMsg, "Can not find Matching Bond Type for[%s, %s]",
254 atomA->getType().c_str(),
255 atomB->getType().c_str());
256
257 painCave.isFatal = 1;
258 simError();
259 }
260 return new Bond(atomA, atomB, bondType);
261 }
262
263 Bend* MoleculeCreator::createBend(ForceField* ff, Molecule* mol, BendStamp* stamp) {
264 bool isGhostBend = false;
265 int ghostIndex;
266
267
268 //
269 if (stamp->haveExtras()){
270 LinkedAssign* extras = stamp->getExtras();
271 LinkedAssign* currentExtra = extras;
272
273 while (currentExtra != NULL){
274 if (!strcmp(currentExtra->getlhs(), "ghostVectorSource")){
275 switch (currentExtra->getType()){
276 case 0:
277 ghostIndex = currentExtra->getInt();
278 isGhostBend = true;
279 break;
280
281 default:
282 sprintf(painCave.errMsg,
283 "SimSetup Error: ghostVectorSource must be an int.\n");
284 painCave.isFatal = 1;
285 simError();
286 }
287 } else{
288 sprintf(painCave.errMsg,
289 "SimSetup Error: unhandled bend assignment:\n");
290 painCave.isFatal = 1;
291 simError();
292 }
293 currentExtra = currentExtra->getNext();
294 }
295
296 }
297
298 if (isGhostBend) {
299
300 int indexA = stamp->getA();
301 int indexB= stamp->getB();
302
303 assert(indexA != indexB);
304
305 int normalIndex;
306 if (indexA == ghostIndex) {
307 normalIndex = indexB;
308 } else if (indexB == ghostIndex) {
309 normalIndex = indexA;
310 }
311
312 Atom* normalAtom = mol->getAtomAt(normalIndex) ;
313 DirectionalAtom* ghostAtom = dynamic_cast<DirectionalAtom*>(mol->getAtomAt(ghostIndex));
314 if (ghostAtom == NULL) {
315 sprintf(painCave.errMsg, "Can not cast Atom to DirectionalAtom");
316 painCave.isFatal = 1;
317 simError();
318 }
319
320 BendType* bendType = ff->getBendType(normalAtom->getType(), ghostAtom->getType(), "GHOST");
321
322 if (bendType == NULL) {
323 sprintf(painCave.errMsg, "Can not find Matching Bend Type for[%s, %s, %s]",
324 normalAtom->getType().c_str(),
325 ghostAtom->getType().c_str(),
326 "GHOST");
327
328 painCave.isFatal = 1;
329 simError();
330 }
331
332 return new GhostBend(normalAtom, ghostAtom, bendType);
333
334 } else {
335
336 Atom* atomA = mol->getAtomAt(stamp->getA());
337 Atom* atomB = mol->getAtomAt(stamp->getB());
338 Atom* atomC = mol->getAtomAt(stamp->getC());
339
340 assert( atomA && atomB && atomC);
341
342 BendType* bendType = ff->getBendType(atomA->getType(), atomB->getType(), atomC->getType());
343
344 if (bendType == NULL) {
345 sprintf(painCave.errMsg, "Can not find Matching Bend Type for[%s, %s, %s]",
346 atomA->getType().c_str(),
347 atomB->getType().c_str(),
348 atomC->getType().c_str());
349
350 painCave.isFatal = 1;
351 simError();
352 }
353
354 return new Bend(atomA, atomB, atomC, bendType);
355 }
356 }
357
358 Torsion* MoleculeCreator::createTorsion(ForceField* ff, Molecule* mol, TorsionStamp* stamp) {
359 TorsionType* torsionType;
360 Atom* atomA;
361 Atom* atomB;
362 Atom* atomC;
363 Atom* atomD;
364
365 atomA = mol->getAtomAt(stamp->getA());
366 atomB = mol->getAtomAt(stamp->getB());
367 atomC = mol->getAtomAt(stamp->getC());
368 atomD = mol->getAtomAt(stamp->getD());
369
370 assert(atomA && atomB && atomC && atomD);
371
372 torsionType = ff->getTorsionType(atomA->getType(), atomB->getType(),
373 atomC->getType(), atomD->getType());
374
375 if (torsionType == NULL) {
376 sprintf(painCave.errMsg, "Can not find Matching Torsion Type for[%s, %s, %s, %s]",
377 atomA->getType().c_str(),
378 atomB->getType().c_str(),
379 atomC->getType().c_str(),
380 atomD->getType().c_str());
381
382 painCave.isFatal = 1;
383 simError();
384 }
385
386 return new Torsion(atomA, atomB, atomC, atomD, torsionType);
387 }
388
389 CutoffGroup* MoleculeCreator::createCutoffGroup(Molecule* mol, CutoffGroupStamp* stamp) {
390 int nAtoms;
391 CutoffGroup* cg;
392 Atom* atom;
393 cg = new CutoffGroup();
394
395 nAtoms = stamp->getNMembers();
396 for (int i =0; i < nAtoms; ++i) {
397 atom = mol->getAtomAt(stamp->getMember(i));
398 assert(atom);
399 cg->addAtom(atom);
400 }
401
402 return cg;
403 }
404
405 CutoffGroup* MoleculeCreator::createCutoffGroup(Molecule * mol, Atom* atom) {
406 CutoffGroup* cg;
407 cg = new CutoffGroup();
408 cg->addAtom(atom);
409 return cg;
410 }
411 //Constraint* MoleculeCreator::createConstraint() {
412
413 //}
414
415 }

Properties

Name Value
svn:executable *