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

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 tim 1907 #include <set>
36 tim 1719
37 tim 1805 #include "brains/MoleculeCreator.hpp"
38     #include "primitives/GhostBend.hpp"
39 tim 1832 #include "types/DirectionalAtomType.hpp"
40 tim 1901 #include "types/FixedBondType.hpp"
41 tim 1805 #include "utils/simError.h"
42     #include "utils/StringUtils.hpp"
43    
44 tim 1719 namespace oopse {
45    
46 tim 1805 Molecule* MoleculeCreator::createMolecule(ForceField* ff, MoleculeStamp *molStamp,
47     int stampId, int globalIndex, LocalIndexManager* localIndexMan) {
48    
49 tim 1733 Molecule* mol = new Molecule(stampId, globalIndex, molStamp->getID());
50 tim 1719
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 tim 1805 atom = createAtom(ff, mol, currentAtomStamp, localIndexMan);
58 tim 1719 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 tim 1805 rb = createRigidBody(molStamp, mol, currentRigidBodyStamp, localIndexMan);
69 tim 1719 mol->addRigidBody(rb);
70     }
71    
72     //create bonds
73     Bond* bond;
74     BondStamp* currentBondStamp;
75 tim 1857 int nBonds = molStamp->getNBonds();
76 tim 1719
77     for (int i = 0; i < nBonds; ++i) {
78 tim 1805 currentBondStamp = molStamp->getBond(i);
79 tim 1719 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 tim 1805 cutoffGroup = createCutoffGroup(mol, currentCutoffGroupStamp);
110 tim 1719 mol->addCutoffGroup(cutoffGroup);
111     }
112    
113 tim 1734 //every free atom is a cutoff group
114     std::set<Atom*> allAtoms;
115 tim 1805 Molecule::AtomIterator ai;
116 tim 1734
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 tim 1805 Molecule::CutoffGroupIterator ci;
123 tim 1734 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 tim 1805 std::back_inserter(freeAtoms));
142 tim 1734
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 tim 1842 cutoffGroup = createCutoffGroup(mol, *fai);
156 tim 1734 mol->addCutoffGroup(cutoffGroup);
157     }
158 tim 1719 //create constraints
159 tim 1907 createConstraintPair(mol);
160     createConstraintElem(mol);
161    
162 tim 1719 //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 tim 1804 if (atomType == NULL) {
177 tim 1733 sprintf(painCave.errMsg, "Can not find Matching Atom Type for[%s]",
178     stamp->getType());
179    
180     painCave.isFatal = 1;
181     simError();
182     }
183    
184 tim 1719 //below code still have some kind of hard-coding smell
185 tim 1813 if (atomType->isDirectional()){
186    
187 tim 1804 DirectionalAtomType* dAtomType = dynamic_cast<DirectionalAtomType*>(atomType);
188 tim 1813
189 tim 1804 if (dAtomType == NULL) {
190     sprintf(painCave.errMsg, "Can not cast AtomType to DirectionalAtomType");
191    
192     painCave.isFatal = 1;
193     simError();
194     }
195 tim 1813
196     DirectionalAtom* dAtom;
197 tim 1804 dAtom = new DirectionalAtom(dAtomType);
198 tim 1719 atom = dAtom;
199     }
200     else{
201     atom = new Atom(atomType);
202     }
203    
204     atom->setLocalIndex(localIndexMan->getNextAtomIndex());
205 tim 1805
206     return atom;
207 tim 1719 }
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 tim 1805 nAtoms = rbStamp->getNMembers();
219 tim 1719 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 tim 1805 atomStamp= molStamp->getAtom(rbStamp->getMember(i));
224 tim 1719 rb->addAtom(atom, atomStamp);
225     }
226 tim 1733
227     //after all of the atoms are added, we need to calculate the reference coordinates
228 tim 1719 rb->calcRefCoords();
229 tim 1733
230     //set the local index of this rigid body, global index will be set later
231 tim 1719 rb->setLocalIndex(localIndexMan->getNextRigidBodyIndex());
232 tim 1733
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 tim 1805 /**@todo replace itoa by lexi_cast */
239     rb->setType(mol->getType() + "_RB_" + toString(mol->getNRigidBodies()));
240 tim 1719
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 tim 1805 bondType = ff->getBondType(atomA->getType(), atomB->getType());
255 tim 1719
256 tim 1733 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 tim 1719 return new Bond(atomA, atomB, bondType);
265     }
266    
267     Bend* MoleculeCreator::createBend(ForceField* ff, Molecule* mol, BendStamp* stamp) {
268 tim 1774 bool isGhostBend = false;
269     int ghostIndex;
270 tim 1719
271    
272 tim 1774 //
273     if (stamp->haveExtras()){
274 tim 1805 LinkedAssign* extras = stamp->getExtras();
275 tim 1774 LinkedAssign* currentExtra = extras;
276 tim 1719
277 tim 1774 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 tim 1719
285 tim 1774 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 tim 1733 }
301    
302 tim 1774 if (isGhostBend) {
303 tim 1733
304 tim 1774 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 tim 1805 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 tim 1774 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 tim 1805
336 tim 1774 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 tim 1719 }
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 tim 1805 torsionType = ff->getTorsionType(atomA->getType(), atomB->getType(),
377 tim 1719 atomC->getType(), atomD->getType());
378    
379 tim 1733 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 tim 1805 return new Torsion(atomA, atomB, atomC, atomD, torsionType);
391 tim 1719 }
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 tim 1734 CutoffGroup* MoleculeCreator::createCutoffGroup(Molecule * mol, Atom* atom) {
410     CutoffGroup* cg;
411     cg = new CutoffGroup();
412 tim 1805 cg->addAtom(atom);
413 tim 1734 return cg;
414     }
415 tim 1719
416 tim 1901 void MoleculeCreator::createConstraintPair(Molecule* mol) {
417 tim 1719
418 tim 1901 //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 tim 1907 //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 tim 1901 mol->addConstraintPair(consPair);
439     }
440     }
441    
442     //rigidbody -- rigidbody constraint is not support yet
443 tim 1719 }
444 tim 1901
445 tim 1907 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 tim 1901 }
467 tim 1907
468     }

Properties

Name Value
svn:executable *