ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-4/src/types/MoleculeStamp.cpp
Revision: 2469
Committed: Fri Dec 2 15:38:03 2005 UTC (18 years, 7 months ago) by tim
File size: 12467 byte(s)
Log Message:
End of the Link --> List
Return of the Oject-Oriented
replace yacc/lex parser with antlr parser

File Contents

# Content
1 /*
2 * Copyright (c) 2005 The University of Notre Dame. All Rights Reserved.
3 *
4 * The University of Notre Dame grants you ("Licensee") a
5 * non-exclusive, royalty free, license to use, modify and
6 * redistribute this software in source and binary code form, provided
7 * that the following conditions are met:
8 *
9 * 1. Acknowledgement of the program authors must be made in any
10 * publication of scientific results based in part on use of the
11 * program. An acceptable form of acknowledgement is citation of
12 * the article in which the program was described (Matthew
13 * A. Meineke, Charles F. Vardeman II, Teng Lin, Christopher
14 * J. Fennell and J. Daniel Gezelter, "OOPSE: An Object-Oriented
15 * Parallel Simulation Engine for Molecular Dynamics,"
16 * J. Comput. Chem. 26, pp. 252-271 (2005))
17 *
18 * 2. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 *
21 * 3. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the
24 * distribution.
25 *
26 * This software is provided "AS IS," without a warranty of any
27 * kind. All express or implied conditions, representations and
28 * warranties, including any implied warranty of merchantability,
29 * fitness for a particular purpose or non-infringement, are hereby
30 * excluded. The University of Notre Dame and its licensors shall not
31 * be liable for any damages suffered by licensee as a result of
32 * using, modifying or distributing the software or its
33 * derivatives. In no event will the University of Notre Dame or its
34 * licensors be liable for any lost revenue, profit or data, or for
35 * direct, indirect, special, consequential, incidental or punitive
36 * damages, however caused and regardless of the theory of liability,
37 * arising out of the use of or inability to use software, even if the
38 * University of Notre Dame has been advised of the possibility of
39 * such damages.
40 */
41
42 #include <stdlib.h>
43 #include <stdio.h>
44 #include <string.h>
45 #include <iostream>
46
47 #include "types/MoleculeStamp.hpp"
48
49 namespace oopse {
50 MoleculeStamp::MoleculeStamp() {
51 DefineParameter(Name, "name");
52
53 deprecatedKeywords_.insert("nAtoms");
54 deprecatedKeywords_.insert("nBonds");
55 deprecatedKeywords_.insert("nBends");
56 deprecatedKeywords_.insert("nTorsions");
57 deprecatedKeywords_.insert("nRigidBodies");
58 deprecatedKeywords_.insert("nCutoffGroups");
59
60 }
61
62 MoleculeStamp::~MoleculeStamp() {
63
64 }
65
66 bool MoleculeStamp::addAtomStamp( AtomStamp* atom) {
67 bool ret = addIndexSensitiveStamp(atomStamps_, atom);
68 if (!ret) {
69 std::cout << "multiple atoms have the same index: " << atom->getIndex() <<" in " << getName() << " Molecule\n";
70 }
71 return ret;
72
73 }
74
75 bool MoleculeStamp::addBondStamp( BondStamp* bond) {
76 bondStamps_.push_back(bond);
77 return true;
78 }
79
80 bool MoleculeStamp::addBendStamp( BendStamp* bend) {
81 bendStamps_.push_back(bend);
82 return true;
83 }
84
85 bool MoleculeStamp::addTorsionStamp( TorsionStamp* torsion) {
86 torsionStamps_.push_back(torsion);
87 return true;
88 }
89
90 bool MoleculeStamp::addRigidBodyStamp( RigidBodyStamp* rigidbody) {
91 bool ret = addIndexSensitiveStamp(rigidBodyStamps_, rigidbody);
92 if (!ret) {
93 std::cout << "multiple rigidbodies have the same index: " << rigidbody->getIndex() <<" in " << getName() << " Molecule\n";
94 }
95 return ret;
96 }
97
98 bool MoleculeStamp::addCutoffGroupStamp( CutoffGroupStamp* cutoffgroup) {
99 cutoffGroupStamps_.push_back(cutoffgroup);
100 return true;
101 }
102
103 bool MoleculeStamp::addFragmentStamp( FragmentStamp* fragment) {
104 return addIndexSensitiveStamp(fragmentStamps_, fragment);
105 }
106
107 void MoleculeStamp::validate() {
108 DataHolder::validate();
109
110 std::vector<AtomStamp*>::iterator ai = std::find(atomStamps_.begin(), atomStamps_.end(), static_cast<AtomStamp*>(NULL));
111 if (ai != atomStamps_.end()) {
112 std::cout << "Error in Molecule " << getName() << ": atom[" << ai - atomStamps_.begin()<< "] is missing\n";
113 }
114
115 std::vector<RigidBodyStamp*>::iterator ri = std::find(rigidBodyStamps_.begin(), rigidBodyStamps_.end(), static_cast<RigidBodyStamp*>(NULL));
116 if (ri != rigidBodyStamps_.end()) {
117 std::cout << "Error in Molecule " << getName() << ":rigidBody[" << ri - rigidBodyStamps_.begin()<< "] is missing\n";
118 }
119
120 std::vector<FragmentStamp*>::iterator fi = std::find(fragmentStamps_.begin(), fragmentStamps_.end(), static_cast<FragmentStamp*>(NULL));
121 if (fi != fragmentStamps_.end()) {
122 std::cout << "Error in Molecule " << getName() << ":fragment[" << fi - fragmentStamps_.begin()<< "] is missing\n";
123 }
124
125 //make sure index is not out of range
126 int natoms = getNAtoms();
127 for(int i = 0; i < getNBonds(); ++i) {
128 BondStamp* bondStamp = getBondStamp(i);
129 if (bondStamp->getA() >= natoms && bondStamp->getB() >= natoms) {
130 std::cout << "Error in Molecule " << getName() << ": bond between " << bondStamp->getA() << " and " << bondStamp->getB() << " is invalid\n";
131 }
132 }
133 for(int i = 0; i < getNBends(); ++i) {
134 BendStamp* bendStamp = getBendStamp(i);
135 std::vector<int> bendAtoms = bendStamp->getMembers();
136 std::vector<int>::iterator j =std::find_if(bendAtoms.begin(), bendAtoms.end(), std::bind2nd(std::greater<int>(), natoms-1));
137 if (j != bendAtoms.end()) {
138 std::cout << "Error in Molecule " << getName();
139 }
140
141 if (bendAtoms.size() == 2 && !bendStamp->haveGhostVectorSource()) {
142 std::cout << "Error in Molecule " << getName() << ": ghostVectorSouce is missing";
143 }
144 }
145 for(int i = 0; i < getNBends(); ++i) {
146 TorsionStamp* torsionStamp = getTorsionStamp(i);
147 std::vector<int> torsionAtoms = torsionStamp ->getMembers();
148 std::vector<int>::iterator j =std::find_if(torsionAtoms.begin(), torsionAtoms.end(), std::bind2nd(std::greater<int>(), natoms-1));
149 if (j != torsionAtoms.end()) {
150 std::cout << "Error in Molecule " << getName();
151 }
152 }
153 for(int i = 0; i < getNCutoffGroups(); ++i) {
154 CutoffGroupStamp* cutoffGroupStamp = getCutoffGroupStamp(i);
155 std::vector<int> cutoffGroupAtoms = cutoffGroupStamp ->getMembers();
156 std::vector<int>::iterator j =std::find_if(cutoffGroupAtoms.begin(), cutoffGroupAtoms.end(), std::bind2nd(std::greater<int>(), natoms-1));
157 if (j != cutoffGroupAtoms.end()) {
158 std::cout << "Error in Molecule " << getName();
159 }
160 }
161
162 atom2Rigidbody.resize(natoms);
163 // negative number means atom is a free atom, does not belong to rigidbody
164 //every element in atom2Rigidbody has unique negative number at the very beginning
165 for(int i = 0; i < atom2Rigidbody.size(); ++i) {
166 atom2Rigidbody[i] = -1 - i;
167 }
168
169 for (int i = 0; i < getNRigidBodies(); ++i) {
170 RigidBodyStamp* rbStamp = getRigidBodyStamp(i);
171 std::vector<int> members = rbStamp->getMembers();
172 for(std::vector<int>::iterator j = members.begin(); j != members.end(); ++j) {
173 atom2Rigidbody[*j] = i;
174 }
175 }
176 //make sure atoms belong to same rigidbody do not bond to each other
177 for(int i = 0; i < getNBonds(); ++i) {
178 BondStamp* bondStamp = getBondStamp(i);
179 if (atom2Rigidbody[bondStamp->getA()] == atom2Rigidbody[bondStamp->getB()])
180 std::cout << "Error in Molecule " << getName() << ": "<<"bond between " << bondStamp->getA() << " and " << bondStamp->getB() << "belong to same rigidbody " << atom2Rigidbody[bondStamp->getA()] << "\n";
181 }
182
183 for(int i = 0; i < getNBends(); ++i) {
184 BendStamp* bendStamp = getBendStamp(i);
185 std::vector<int> bendAtoms = bendStamp->getMembers();
186 std::vector<int> rigidSet(getNRigidBodies(), 0);
187 std::vector<int>::iterator j;
188 for( j = bendAtoms.begin(); j != bendAtoms.end(); ++j) {
189 int rigidbodyIndex = atom2Rigidbody[*j];
190 if (rigidbodyIndex >= 0) {
191 ++rigidSet[rigidbodyIndex];
192 if (rigidSet[rigidbodyIndex] > 1) {
193 std::cout << "Error in Molecule " << getName() << ": ";
194 //std::cout << "atoms of bend " << << "belong to same rigidbody " << rigidbodyIndex << "\n";
195 }
196 }
197 }
198 }
199 for(int i = 0; i < getNTorsions(); ++i) {
200 TorsionStamp* torsionStamp = getTorsionStamp(i);
201 std::vector<int> torsionAtoms = torsionStamp->getMembers();
202 std::vector<int> rigidSet(getNRigidBodies(), 0);
203 std::vector<int>::iterator j;
204 for( j = torsionAtoms.begin(); j != torsionAtoms.end(); ++j) {
205 int rigidbodyIndex = atom2Rigidbody[*j];
206 if (rigidbodyIndex >= 0) {
207 ++rigidSet[rigidbodyIndex];
208 if (rigidSet[rigidbodyIndex] > 1) {
209 std::cout << "Error in Molecule " << getName() << ": ";
210 //std::cout << "atoms of torsion " << << "belong to same rigidbody " << rigidbodyIndex << "\n";
211 }
212 }
213 }
214 }
215
216
217 //fill in bond information into atom
218 fillBondInfo();
219 findBends();
220 findTorsions();
221
222 int nrigidAtoms = 0;
223 for (int i = 0; i < getNRigidBodies(); ++i) {
224 RigidBodyStamp* rbStamp = getRigidBodyStamp(i);
225 nrigidAtoms += rbStamp->getNMembers();
226 }
227 nintegrable_ = getNAtoms()+ getNRigidBodies() - nrigidAtoms;
228
229 }
230
231 void MoleculeStamp::fillBondInfo() {
232 }
233
234 void MoleculeStamp::findBends() {
235
236 }
237
238 void MoleculeStamp::findTorsions() {
239
240 }
241
242 //Function Name: isBondInSameRigidBody
243 //Return true is both atoms of the bond belong to the same rigid body, otherwise return false
244 bool MoleculeStamp::isBondInSameRigidBody(BondStamp* bond){
245 int rbA;
246 int rbB;
247 int consAtomA;
248 int consAtomB;
249
250 if (!isAtomInRigidBody(bond->getA(),rbA, consAtomA))
251 return false;
252
253 if(!isAtomInRigidBody(bond->getB(),rbB, consAtomB) )
254 return false;
255
256 if(rbB == rbA)
257 return true;
258 else
259 return false;
260 }
261
262 // Function Name: isAtomInRigidBody
263 //return false if atom does not belong to a rigid body, otherwise return true
264 bool MoleculeStamp::isAtomInRigidBody(int atomIndex){
265 int whichRigidBody;
266 int consAtomIndex;
267
268 return isAtomInRigidBody(atomIndex, whichRigidBody, consAtomIndex);
269
270 }
271
272 // Function Name: isAtomInRigidBody
273 //return false if atom does not belong to a rigid body otherwise return true and set whichRigidBody
274 //and consAtomIndex
275 //atomIndex : the index of atom in component
276 //whichRigidBody: the index of rigidbody in component
277 //consAtomIndex: the position of joint atom apears in rigidbody's definition
278 bool MoleculeStamp::isAtomInRigidBody(int atomIndex, int& whichRigidBody, int& consAtomIndex){
279 RigidBodyStamp* rbStamp;
280 int numRb;
281 int numAtom;
282
283 whichRigidBody = -1;
284 consAtomIndex = -1;
285
286 numRb = this->getNRigidBodies();
287
288 for(int i = 0 ; i < numRb; i++){
289 rbStamp = this->getRigidBodyStamp(i);
290 numAtom = rbStamp->getNMembers();
291 for(int j = 0; j < numAtom; j++)
292 if (rbStamp->getMemberAt(j) == atomIndex){
293 whichRigidBody = i;
294 consAtomIndex = j;
295 return true;
296 }
297 }
298
299 return false;
300
301 }
302
303 //return the position of joint atom apears in rigidbody's definition
304 //for the time being, we will use the most inefficient algorithm, the complexity is O(N2)
305 //actually we could improve the complexity to O(NlgN) by sorting the atom index in rigid body first
306 std::vector<std::pair<int, int> > MoleculeStamp::getJointAtoms(int rb1, int rb2){
307 RigidBodyStamp* rbStamp1;
308 RigidBodyStamp* rbStamp2;
309 int natomInRb1;
310 int natomInRb2;
311 int atomIndex1;
312 int atomIndex2;
313 std::vector<std::pair<int, int> > jointAtomIndexPair;
314
315 rbStamp1 = this->getRigidBodyStamp(rb1);
316 natomInRb1 =rbStamp1->getNMembers();
317
318 rbStamp2 = this->getRigidBodyStamp(rb2);
319 natomInRb2 =rbStamp2->getNMembers();
320
321 for(int i = 0; i < natomInRb1; i++){
322 atomIndex1 = rbStamp1->getMemberAt(i);
323
324 for(int j= 0; j < natomInRb1; j++){
325 atomIndex2 = rbStamp2->getMemberAt(j);
326
327 if(atomIndex1 == atomIndex2){
328 jointAtomIndexPair.push_back(std::make_pair(i, j));
329 break;
330 }
331
332 }
333
334 }
335
336 return jointAtomIndexPair;
337 }
338
339 }