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: 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

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

Properties

Name Value
svn:executable *