ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/branches/new_design/OOPSE-2.0/src/brains/MoleculeCreator.cpp
Revision: 1907
Committed: Thu Jan 6 22:31:07 2005 UTC (19 years, 6 months ago) by tim
File size: 15483 byte(s)
Log Message:
constraint is almost working

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

Properties

Name Value
svn:executable *