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: 1901
Committed: Tue Jan 4 22:18:36 2005 UTC (19 years, 6 months ago) by tim
File size: 14223 byte(s)
Log Message:
constraints in progress

File Contents

# User Rev Content
1 tim 1719 /*
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 tim 1805 #include "brains/MoleculeCreator.hpp"
37     #include "primitives/GhostBend.hpp"
38 tim 1832 #include "types/DirectionalAtomType.hpp"
39 tim 1901 #include "types/FixedBondType.hpp"
40 tim 1805 #include "utils/simError.h"
41     #include "utils/StringUtils.hpp"
42    
43 tim 1719 namespace oopse {
44    
45 tim 1805 Molecule* MoleculeCreator::createMolecule(ForceField* ff, MoleculeStamp *molStamp,
46     int stampId, int globalIndex, LocalIndexManager* localIndexMan) {
47    
48 tim 1733 Molecule* mol = new Molecule(stampId, globalIndex, molStamp->getID());
49 tim 1719
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 tim 1805 atom = createAtom(ff, mol, currentAtomStamp, localIndexMan);
57 tim 1719 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 tim 1805 rb = createRigidBody(molStamp, mol, currentRigidBodyStamp, localIndexMan);
68 tim 1719 mol->addRigidBody(rb);
69     }
70    
71     //create bonds
72     Bond* bond;
73     BondStamp* currentBondStamp;
74 tim 1857 int nBonds = molStamp->getNBonds();
75 tim 1719
76     for (int i = 0; i < nBonds; ++i) {
77 tim 1805 currentBondStamp = molStamp->getBond(i);
78 tim 1719 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 tim 1805 cutoffGroup = createCutoffGroup(mol, currentCutoffGroupStamp);
109 tim 1719 mol->addCutoffGroup(cutoffGroup);
110     }
111    
112 tim 1734 //every free atom is a cutoff group
113     std::set<Atom*> allAtoms;
114 tim 1805 Molecule::AtomIterator ai;
115 tim 1734
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 tim 1805 Molecule::CutoffGroupIterator ci;
122 tim 1734 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 tim 1805 std::back_inserter(freeAtoms));
141 tim 1734
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 tim 1842 cutoffGroup = createCutoffGroup(mol, *fai);
155 tim 1734 mol->addCutoffGroup(cutoffGroup);
156     }
157 tim 1719 //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 tim 1804 if (atomType == NULL) {
174 tim 1733 sprintf(painCave.errMsg, "Can not find Matching Atom Type for[%s]",
175     stamp->getType());
176    
177     painCave.isFatal = 1;
178     simError();
179     }
180    
181 tim 1719 //below code still have some kind of hard-coding smell
182 tim 1813 if (atomType->isDirectional()){
183    
184 tim 1804 DirectionalAtomType* dAtomType = dynamic_cast<DirectionalAtomType*>(atomType);
185 tim 1813
186 tim 1804 if (dAtomType == NULL) {
187     sprintf(painCave.errMsg, "Can not cast AtomType to DirectionalAtomType");
188    
189     painCave.isFatal = 1;
190     simError();
191     }
192 tim 1813
193     DirectionalAtom* dAtom;
194 tim 1804 dAtom = new DirectionalAtom(dAtomType);
195 tim 1719 atom = dAtom;
196     }
197     else{
198     atom = new Atom(atomType);
199     }
200    
201     atom->setLocalIndex(localIndexMan->getNextAtomIndex());
202 tim 1805
203     return atom;
204 tim 1719 }
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 tim 1805 nAtoms = rbStamp->getNMembers();
216 tim 1719 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 tim 1805 atomStamp= molStamp->getAtom(rbStamp->getMember(i));
221 tim 1719 rb->addAtom(atom, atomStamp);
222     }
223 tim 1733
224     //after all of the atoms are added, we need to calculate the reference coordinates
225 tim 1719 rb->calcRefCoords();
226 tim 1733
227     //set the local index of this rigid body, global index will be set later
228 tim 1719 rb->setLocalIndex(localIndexMan->getNextRigidBodyIndex());
229 tim 1733
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 tim 1805 /**@todo replace itoa by lexi_cast */
236     rb->setType(mol->getType() + "_RB_" + toString(mol->getNRigidBodies()));
237 tim 1719
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 tim 1805 bondType = ff->getBondType(atomA->getType(), atomB->getType());
252 tim 1719
253 tim 1733 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 tim 1719 return new Bond(atomA, atomB, bondType);
262     }
263    
264     Bend* MoleculeCreator::createBend(ForceField* ff, Molecule* mol, BendStamp* stamp) {
265 tim 1774 bool isGhostBend = false;
266     int ghostIndex;
267 tim 1719
268    
269 tim 1774 //
270     if (stamp->haveExtras()){
271 tim 1805 LinkedAssign* extras = stamp->getExtras();
272 tim 1774 LinkedAssign* currentExtra = extras;
273 tim 1719
274 tim 1774 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 tim 1719
282 tim 1774 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 tim 1733 }
298    
299 tim 1774 if (isGhostBend) {
300 tim 1733
301 tim 1774 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 tim 1805 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 tim 1774 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 tim 1805
333 tim 1774 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 tim 1719 }
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 tim 1805 torsionType = ff->getTorsionType(atomA->getType(), atomB->getType(),
374 tim 1719 atomC->getType(), atomD->getType());
375    
376 tim 1733 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 tim 1805 return new Torsion(atomA, atomB, atomC, atomD, torsionType);
388 tim 1719 }
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 tim 1734 CutoffGroup* MoleculeCreator::createCutoffGroup(Molecule * mol, Atom* atom) {
407     CutoffGroup* cg;
408     cg = new CutoffGroup();
409 tim 1805 cg->addAtom(atom);
410 tim 1734 return cg;
411     }
412 tim 1719
413 tim 1901 void MoleculeCreator::createConstraintPair(Molecule* mol) {
414 tim 1719
415 tim 1901 //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 tim 1719 }
434 tim 1901
435     }

Properties

Name Value
svn:executable *