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: 1804
Committed: Tue Nov 30 19:58:25 2004 UTC (19 years, 7 months ago) by tim
File size: 13525 byte(s)
Log Message:
fix Thermo

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

Properties

Name Value
svn:executable *