ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/branches/new_design/OOPSE-4/src/brains/MoleculeCreator.cpp
Revision: 1901
Committed: Tue Jan 4 22:18:36 2005 UTC (19 years, 7 months ago) by tim
File size: 14223 byte(s)
Log Message:
constraints in progress

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

Properties

Name Value
svn:executable *