ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/branches/new_design/OOPSE-3.0/src/brains/MoleculeCreator.cpp
Revision: 1805
Committed: Tue Nov 30 20:50:47 2004 UTC (19 years, 8 months ago) by tim
File size: 14008 byte(s)
Log Message:
brains get built, io is next

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

Properties

Name Value
svn:executable *