ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-3.0/src/types/MoleculeStamp.cpp
(Generate patch)

Comparing trunk/OOPSE-3.0/src/types/MoleculeStamp.cpp (file contents):
Revision 1930 by gezelter, Wed Jan 12 22:41:40 2005 UTC vs.
Revision 2515 by tim, Fri Dec 16 18:26:41 2005 UTC

# Line 1 | Line 1
1 < /*
1 > /*
2   * Copyright (c) 2005 The University of Notre Dame. All Rights Reserved.
3   *
4   * The University of Notre Dame grants you ("Licensee") a
# Line 38 | Line 38
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>
41  
42 + #include <functional>
43 + #include <iostream>
44 + #include <sstream>
45   #include "types/MoleculeStamp.hpp"
46 + #include "utils/Tuple.hpp"
47 + #include "utils/MemoryUtils.hpp"
48 + namespace oopse {
49  
50 < char MoleculeStamp::errMsg[500];
50 > template<class ContainerType>
51 > std::string containerToString(ContainerType& cont) {
52 >    std::ostringstream oss;
53 >    oss << "(";
54 >    typename ContainerType::iterator i = cont.begin();
55 >    if (i != cont.end()) {
56 >        oss << *i;
57 >        ++i;
58 >    }
59 >    for (; i != cont.end();++i) {
60 >        oss << ", ";
61 >        oss << *i;
62 >    }
63 >    oss << ")";
64 >    return oss.str();
65 > }
66  
67 < MoleculeStamp::MoleculeStamp(){
68 <  
69 <  n_atoms = 0;
70 <  n_bonds = 0;
71 <  n_bends = 0;
72 <  n_torsions = 0;
73 <  n_rigidbodies = 0;
74 <  n_cutoffgroups = 0;
75 <  n_integrable = 0;
67 > MoleculeStamp::MoleculeStamp() {
68 >    DefineParameter(Name, "name");
69 >    
70 >    deprecatedKeywords_.insert("nAtoms");
71 >    deprecatedKeywords_.insert("nBonds");
72 >    deprecatedKeywords_.insert("nBends");
73 >    deprecatedKeywords_.insert("nTorsions");
74 >    deprecatedKeywords_.insert("nRigidBodies");
75 >    deprecatedKeywords_.insert("nCutoffGroups");
76 >    
77 > }
78  
79 <  unhandled = NULL;
80 <  atoms = NULL;
81 <  bonds = NULL;
82 <  bends = NULL;
83 <  torsions = NULL;
84 <  rigidBodies = NULL;
85 <  cutoffGroups = NULL;
79 > MoleculeStamp::~MoleculeStamp() {
80 >    MemoryUtils::deletePointers(atomStamps_);
81 >    MemoryUtils::deletePointers(bondStamps_);
82 >    MemoryUtils::deletePointers(bendStamps_);
83 >    MemoryUtils::deletePointers(torsionStamps_);
84 >    MemoryUtils::deletePointers(rigidBodyStamps_);
85 >    MemoryUtils::deletePointers(cutoffGroupStamps_);
86 >    MemoryUtils::deletePointers(fragmentStamps_);    
87 > }
88  
89 <  have_name = 0;
90 <  have_atoms = 0;
91 <  have_bonds = 0;
92 <  have_bends = 0;
93 <  have_torsions = 0;
94 <  have_rigidbodies = 0;
95 <  have_cutoffgroups = 0;
89 > bool MoleculeStamp::addAtomStamp( AtomStamp* atom) {
90 >    bool ret = addIndexSensitiveStamp(atomStamps_, atom);
91 >    if (!ret) {
92 >         std::cout<< "Error in Molecule " << getName()  << ": multiple atoms have the same indices"<< atom->getIndex() <<"\n";
93 >    }
94 >    return ret;
95 >    
96 > }
97  
98 + bool MoleculeStamp::addBondStamp( BondStamp* bond) {
99 +    bondStamps_.push_back(bond);
100 +    return true;
101   }
102  
103 < MoleculeStamp::~MoleculeStamp(){
104 <  int i;
105 <  
106 <  if( unhandled != NULL) delete unhandled;
83 <  
84 <  if( rigidBodies != NULL ) {
85 <    for( i=0; i<n_rigidbodies; i++ ) delete rigidBodies[i];
86 <  }
87 <  delete[] rigidBodies;
103 > bool MoleculeStamp::addBendStamp( BendStamp* bend) {
104 >    bendStamps_.push_back(bend);
105 >    return true;
106 > }
107  
108 <  if( cutoffGroups != NULL ) {
109 <    for( i=0; i<n_cutoffgroups; i++ ) delete cutoffGroups[i];
110 <  }
111 <  delete[] cutoffGroups;
93 <  
94 <  if( atoms != NULL ){
95 <    for( i=0; i<n_atoms; i++ ) delete atoms[i];
96 <  }
97 <  delete[] atoms;
98 <  
99 <  if( bonds != NULL ){
100 <    for( i=0; i<n_bonds; i++ ) delete bonds[i];
101 <  }
102 <  delete[] bonds;
103 <  
104 <  if( bends != NULL ){
105 <    for( i=0; i<n_bends; i++ ) delete bends[i];
106 <  }
107 <  delete[] bends;
108 <  
109 <  if( torsions != NULL ){
110 <    for( i=0; i<n_torsions; i++ ) delete torsions[i];
111 <  }
112 <  delete[] torsions;
113 <  
108 > bool MoleculeStamp::addTorsionStamp( TorsionStamp* torsion) {
109 >    torsionStamps_.push_back(torsion);
110 >    return true;
111 > }
112  
113 + bool MoleculeStamp::addRigidBodyStamp( RigidBodyStamp* rigidbody) {
114 +    bool ret = addIndexSensitiveStamp(rigidBodyStamps_, rigidbody);
115 +    if (!ret) {
116 +        std::cout<< "Error in Molecule " << getName()  << ": multiple rigidbodies have the same indices: " << rigidbody->getIndex() <<"\n";
117 +    }
118 +    return ret;
119 + }
120  
121 <
121 > bool MoleculeStamp::addCutoffGroupStamp( CutoffGroupStamp* cutoffgroup) {
122 >    cutoffGroupStamps_.push_back(cutoffgroup);
123 >    return true;
124   }
125  
126 < char* MoleculeStamp::assignString( char* lhs, char* rhs ){
127 <  
121 <  if( !strcmp( lhs, "name" ) ){
122 <    strcpy( name, rhs );
123 <    have_name = 1;
124 <  }
125 <  else{
126 <    if( unhandled == NULL ) unhandled = new LinkedAssign( lhs, rhs );
127 <    else unhandled->add( lhs, rhs );
128 <    have_extras = 1;
129 <  }
130 <  return NULL;
126 > bool MoleculeStamp::addFragmentStamp( FragmentStamp* fragment) {
127 >    return addIndexSensitiveStamp(fragmentStamps_, fragment);
128   }
129 +    
130 + void MoleculeStamp::validate() {
131 +    DataHolder::validate();
132  
133 < char* MoleculeStamp::assignDouble( char* lhs, double rhs ){
134 <  int i;
133 >    atom2Rigidbody.resize(getNAtoms());
134 >    // negative number means atom is a free atom, does not belong to rigidbody
135 >    //every element in atom2Rigidbody has unique negative number at the very beginning
136 >    for(int i = 0; i < atom2Rigidbody.size(); ++i) {
137 >        atom2Rigidbody[i] = -1 - i;
138 >    }
139 >    for (int i = 0; i < getNRigidBodies(); ++i) {
140 >        RigidBodyStamp* rbStamp = getRigidBodyStamp(i);
141 >        std::vector<int> members = rbStamp->getMembers();
142 >        for(std::vector<int>::iterator j = members.begin(); j != members.end(); ++j) {
143 >            atom2Rigidbody[*j] = i;                
144 >        }
145 >    }
146  
147 <  if( !strcmp( lhs, "nAtoms" ) ){
148 <    n_atoms = (int)rhs;
149 <    
150 <    if( have_atoms ){
151 <      sprintf( errMsg,
152 <               "MoleculeStamp error, n_atoms already declared"
153 <               " for molecule: %s\n",
154 <               name);
155 <      return strdup( errMsg );
147 >    checkAtoms();
148 >    checkBonds();
149 >    fillBondInfo();
150 >    checkBends();
151 >    checkTorsions();
152 >    checkRigidBodies();
153 >    checkCutoffGroups();
154 >    checkFragments();
155 >
156 >    int nrigidAtoms = 0;
157 >    for (int i = 0; i < getNRigidBodies(); ++i) {
158 >        RigidBodyStamp* rbStamp = getRigidBodyStamp(i);
159 >        nrigidAtoms += rbStamp->getNMembers();
160      }
161 <    have_atoms = 1;
147 <    atoms = new AtomStamp*[n_atoms];
148 <    for( i=0; i<n_atoms; i++ ) atoms[i] = NULL;
149 <  }
150 <  
151 <  else if( !strcmp( lhs, "nBonds" ) ){
152 <    n_bonds = (int)rhs;
161 >    nintegrable_ = getNAtoms()+ getNRigidBodies() - nrigidAtoms;
162  
163 <    if( have_bonds ){
164 <      sprintf( errMsg,  
165 <               "MoleculeStamp error, n_bonds already declared for"
166 <               " molecule: %s\n",
167 <               name);
168 <      return strdup( errMsg );
163 > }
164 >
165 > void MoleculeStamp::checkAtoms() {
166 >    std::vector<AtomStamp*>::iterator ai = std::find(atomStamps_.begin(), atomStamps_.end(), static_cast<AtomStamp*>(NULL));
167 >    if (ai != atomStamps_.end()) {
168 >        std::cout << "Error in Molecule " << getName() << ": atom[" << ai - atomStamps_.begin()<< "] is missing\n";
169      }
161    have_bonds = 1;
162    bonds = new BondStamp*[n_bonds];
163    for( i=0; i<n_bonds; i++ ) bonds[i] = NULL;
164  }
165  
166  else if( !strcmp( lhs, "nBends" ) ){
167    n_bends = (int)rhs;
170  
171 <    if( have_bends ){
172 <      sprintf( errMsg,
173 <               "MoleculeStamp error, n_bends already declared for"
174 <               " molecule: %s\n",
175 <               name);
176 <      return strdup( errMsg );
171 > }
172 >
173 > void MoleculeStamp::checkBonds() {
174 >    //make sure index is not out of range
175 >    int natoms = getNAtoms();
176 >    for(int i = 0; i < getNBonds(); ++i) {
177 >        BondStamp* bondStamp = getBondStamp(i);
178 >        if (bondStamp->getA() >=  natoms && bondStamp->getB() >= natoms) {
179 >            std::cout << "Error in Molecule " << getName() <<  ": bond(" << bondStamp->getA() << ", " << bondStamp->getB() << ") is invalid\n";
180 >        }
181      }
182 <    have_bends = 1;
183 <    bends = new BendStamp*[n_bends];
184 <    for( i=0; i<n_bends; i++ ) bends[i] = NULL;
185 <  }
186 <  
187 <  else if( !strcmp( lhs, "nTorsions" ) ){
188 <    n_torsions = (int)rhs;
189 <
190 <    if( have_torsions ){
191 <      sprintf( errMsg,
192 <               "MoleculeStamp error, n_torsions already declared for"
193 <               " molecule: %s\n",
194 <               name );
195 <      return strdup( errMsg );
182 >    
183 >    //make sure bonds are unique
184 >    std::set<std::pair<int, int> > allBonds;
185 >    for(int i = 0; i < getNBonds(); ++i) {
186 >        BondStamp* bondStamp= getBondStamp(i);        
187 >        std::pair<int, int> bondPair(bondStamp->getA(), bondStamp->getB());
188 >        //make sure bondTuple.first is always less than or equal to bondTuple.third
189 >        if (bondPair.first > bondPair.second) {
190 >            std::swap(bondPair.first, bondPair.second);
191 >        }
192 >        
193 >        std::set<std::pair<int, int> >::iterator iter = allBonds.find(bondPair);
194 >        if ( iter != allBonds.end()) {
195 >            std::cout << "Error in Molecule " << getName() << ": " << "bond(" <<iter->first << ", "<< iter->second << ")appears multiple times\n";
196 >        } else {
197 >            allBonds.insert(bondPair);
198 >        }
199      }
191    have_torsions = 1;
192    torsions = new TorsionStamp*[n_torsions];
193    for( i=0; i<n_torsions; i++ ) torsions[i] = NULL;
194  }
195
196  else if( !strcmp( lhs, "nRigidBodies" ) ){
197    n_rigidbodies = (int)rhs;
198
199    if( have_rigidbodies ){
200      sprintf( errMsg,
201               "MoleculeStamp error, n_rigidbodies already declared for"
202               " molecule: %s\n",
203               name );
204      return strdup( errMsg );
205    }
206    have_rigidbodies = 1;
207    rigidBodies = new RigidBodyStamp*[n_rigidbodies];
208    for( i=0; i<n_rigidbodies; i++ ) rigidBodies[i] = NULL;
209  }
210
211  else if( !strcmp( lhs, "nCutoffGroups" ) ){
212    n_cutoffgroups = (int)rhs;
213
214    if( have_cutoffgroups ){
215      sprintf( errMsg,
216               "MoleculeStamp error, n_cutoffgroups already declared for"
217               " molecule: %s\n",
218               name );
219      return strdup( errMsg );
220    }
221    have_cutoffgroups = 1;
222    cutoffGroups = new CutoffGroupStamp*[n_cutoffgroups];
223    for( i=0; i<n_cutoffgroups; i++ ) cutoffGroups[i] = NULL;
224  }
225  
226  else{
227    if( unhandled == NULL ) unhandled = new LinkedAssign( lhs, rhs );
228    else unhandled->add( lhs, rhs );
229    have_extras = 1;
230  }
231  return NULL;
232 }
233
234 char*  MoleculeStamp::assignInt( char* lhs, int rhs ){
235  int i;
236  
237  if( !strcmp( lhs, "nAtoms" ) ){
238    n_atoms = rhs;
200      
201 <    if( have_atoms ){
202 <      sprintf( errMsg,
203 <               "MoleculeStamp error, n_atoms already declared for"
204 <               " molecule: %s\n",
205 <               name);
206 <      return strdup( errMsg );
201 >    //make sure atoms belong to same rigidbody do not bond to each other
202 >    for(int i = 0; i < getNBonds(); ++i) {
203 >        BondStamp* bondStamp = getBondStamp(i);
204 >        if (atom2Rigidbody[bondStamp->getA()] == atom2Rigidbody[bondStamp->getB()]) {
205 >            std::cout << "Error in Molecule " << getName() << ": "<<"bond(" << bondStamp->getA() << ", " << bondStamp->getB() << ") belong to same rigidbody " << atom2Rigidbody[bondStamp->getA()] << "\n";
206 >        }
207      }
208 <    have_atoms = 1;
248 <    atoms = new AtomStamp*[n_atoms];
249 <    for( i=0; i<n_atoms; i++ ) atoms[i] = NULL;
250 <  }
251 <  
252 <  else if( !strcmp( lhs, "nBonds" ) ){
253 <    n_bonds = rhs;
254 <
255 <    if( have_bonds ){
256 <      sprintf( errMsg,
257 <               "MoleculeStamp error, n_bonds already declared for"
258 <               " molecule: %s\n",
259 <               name);
260 <      return strdup( errMsg );
261 <    }
262 <    have_bonds = 1;
263 <    bonds = new BondStamp*[n_bonds];
264 <    for( i=0; i<n_bonds; i++ ) bonds[i] = NULL;
265 <  }
266 <  
267 <  else if( !strcmp( lhs, "nBends" ) ){
268 <    n_bends = rhs;
269 <
270 <    if( have_bends ){
271 <      sprintf( errMsg,
272 <               "MoleculeStamp error, n_bends already declared for"
273 <               " molecule: %s\n",
274 <               name );
275 <      return strdup( errMsg );
276 <    }
277 <    have_bends = 1;
278 <    bends = new BendStamp*[n_bends];
279 <    for( i=0; i<n_bends; i++ ) bends[i] = NULL;
280 <  }
281 <  
282 <  else if( !strcmp( lhs, "nTorsions" ) ){
283 <    n_torsions = rhs;
284 <
285 <    if( have_torsions ){
286 <      sprintf( errMsg,
287 <               "MoleculeStamp error, n_torsions already declared for"
288 <               " molecule: %s\n",
289 <               name);
290 <      return strdup( errMsg );
291 <    }
292 <    have_torsions = 1;
293 <    torsions = new TorsionStamp*[n_torsions];
294 <    for( i=0; i<n_torsions; i++ ) torsions[i] = NULL;
295 <  }
296 <
297 <  else if( !strcmp( lhs, "nRigidBodies" ) ){
298 <    n_rigidbodies = rhs;
299 <
300 <    if( have_rigidbodies ){
301 <      sprintf( errMsg,
302 <               "MoleculeStamp error, n_rigidbodies already declared for"
303 <               " molecule: %s\n",
304 <               name);
305 <      return strdup( errMsg );
306 <    }
307 <    have_rigidbodies = 1;
308 <    rigidBodies = new RigidBodyStamp*[n_rigidbodies];
309 <    for( i=0; i<n_rigidbodies; i++ ) rigidBodies[i] = NULL;
310 <  }
311 <  else if( !strcmp( lhs, "nCutoffGroups" ) ){
312 <    n_cutoffgroups = rhs;
313 <
314 <    if( have_cutoffgroups ){
315 <      sprintf( errMsg,
316 <               "MoleculeStamp error, n_cutoffgroups already declared for"
317 <               " molecule: %s\n",
318 <               name);
319 <      return strdup( errMsg );
320 <    }
321 <    have_cutoffgroups = 1;
322 <    cutoffGroups = new CutoffGroupStamp*[n_cutoffgroups];
323 <    for( i=0; i<n_cutoffgroups; i++ ) cutoffGroups[i] = NULL;
324 <  }
325 <  else{
326 <    if( unhandled == NULL ) unhandled = new LinkedAssign( lhs, rhs );
327 <    else unhandled->add( lhs, rhs );
328 <    have_extras = 1;
329 <  }
330 <  return NULL;
208 >    
209   }
210  
211 < char* MoleculeStamp::addAtom( AtomStamp* the_atom, int atomIndex ){
212 <  
213 <  if( have_atoms && atomIndex < n_atoms ) atoms[atomIndex] = the_atom;
214 <  else {
215 <    if( have_atoms ){
216 <      sprintf( errMsg, "MoleculeStamp error, %d out of nAtoms range",
217 <               atomIndex );
218 <      return strdup( errMsg );
341 <    }
342 <    else return strdup("MoleculeStamp error, nAtoms not given before"
343 <                       " first atom declaration." );
344 <  }
211 > void MoleculeStamp::checkBends() {
212 >    for(int i = 0; i < getNBends(); ++i) {
213 >        BendStamp* bendStamp = getBendStamp(i);
214 >        std::vector<int> bendAtoms =  bendStamp->getMembers();
215 >        std::vector<int>::iterator j =std::find_if(bendAtoms.begin(), bendAtoms.end(), std::bind2nd(std::greater<int>(), getNAtoms()-1));
216 >        if (j != bendAtoms.end()) {
217 >            std::cout << "Error in Molecule " << getName() << " : atoms of bend" << containerToString(bendAtoms) << "have invalid indices\n";
218 >        }
219  
220 <  return NULL;
221 < }
222 <
223 < char* MoleculeStamp::addRigidBody( RigidBodyStamp* the_rigidbody,
224 <                                   int rigidBodyIndex ){
225 <  
226 <  if( have_rigidbodies && rigidBodyIndex < n_rigidbodies )
227 <    rigidBodies[rigidBodyIndex] = the_rigidbody;
228 <  else {
229 <    if( have_rigidbodies ){
230 <      sprintf( errMsg, "MoleculeStamp error, %d out of nRigidBodies range",
231 <               rigidBodyIndex );
232 <      return strdup( errMsg );
220 >        if (bendAtoms.size() == 2 ) {
221 >            if (!bendStamp->haveGhostVectorSource()) {
222 >                std::cout << "Error in Molecule " << getName() << ": ghostVectorSouce is missing\n";
223 >            }else{
224 >                int ghostIndex = bendStamp->getGhostVectorSource();
225 >                if (ghostIndex < getNAtoms()) {
226 >                    if (std::find(bendAtoms.begin(), bendAtoms.end(), ghostIndex) == bendAtoms.end()) {
227 >                      std::cout <<  "Error in Molecule " << getName() << ": ghostVectorSouce "<< ghostIndex<<"is invalid\n";
228 >                    }
229 >                    if (!getAtomStamp(ghostIndex)->haveOrientation()) {
230 >                        std::cout <<  "Error in Molecule " << getName() << ": ghost atom must be a directioanl atom\n";
231 >                    }
232 >                }else {
233 >                    std::cout << "Error in Molecule " << getName() <<  ": ghostVectorsource " << ghostIndex<< "  is invalid\n";
234 >                }
235 >            }
236 >        } else if (bendAtoms.size() == 3 && bendStamp->haveGhostVectorSource()) {
237 >            std::cout <<  "Error in Molecule " << getName() << ": normal bend should not have ghostVectorSouce\n";
238 >        }
239      }
360    else return strdup("MoleculeStamp error, nRigidBodies not given before"
361                       " first rigidBody declaration." );
362  }
363  
364  return NULL;
365 }
240  
241 < char* MoleculeStamp::addCutoffGroup( CutoffGroupStamp* the_cutoffgroup,
242 <                                     int cutoffGroupIndex ){
243 <  
244 <  if( have_cutoffgroups && cutoffGroupIndex < n_cutoffgroups )
245 <    cutoffGroups[cutoffGroupIndex] = the_cutoffgroup;
246 <  else {
247 <    if( have_cutoffgroups ){
248 <      sprintf( errMsg, "MoleculeStamp error, %d out of nCutoffGroups range",
249 <               cutoffGroupIndex );
250 <      return strdup( errMsg );
241 >    for(int i = 0; i < getNBends(); ++i) {
242 >        BendStamp* bendStamp = getBendStamp(i);
243 >        std::vector<int> bendAtoms =  bendStamp->getMembers();
244 >        std::vector<int> rigidSet(getNRigidBodies(), 0);
245 >        std::vector<int>::iterator j;
246 >        for( j = bendAtoms.begin(); j != bendAtoms.end(); ++j) {
247 >            int rigidbodyIndex = atom2Rigidbody[*j];
248 >            if (rigidbodyIndex >= 0) {
249 >                ++rigidSet[rigidbodyIndex];
250 >                if (rigidSet[rigidbodyIndex] > 1) {
251 >                    std::cout << "Error in Molecule " << getName() << ": bend" << containerToString(bendAtoms) << " belong to same rigidbody " << rigidbodyIndex << "\n";                    
252 >                }
253 >            }
254 >        }
255 >    }
256 >    
257 >    
258 >    std::set<IntTuple3> allBends;
259 >    std::set<IntTuple3>::iterator iter;
260 >    for(int i = 0; i < getNBends(); ++i) {
261 >        BendStamp* bendStamp= getBendStamp(i);
262 >        std::vector<int> bend = bendStamp->getMembers();
263 >        if (bend.size() == 2) {
264 >        // in case we have two ghost bend. For example,
265 >        // bend {
266 >        // members (0, 1);
267 >        //   ghostVectorSource = 0;
268 >        // }
269 >        // and
270 >        // bend {
271 >        //   members (0, 1);
272 >        // ghostVectorSource = 0;
273 >        // }
274 >        // In order to distinguish them. we expand them to Tuple3.
275 >        // the first one is expanded to (0, 0, 1) while the second one is expaned to (0, 1, 1)
276 >             int ghostIndex = bendStamp->getGhostVectorSource();
277 >             std::vector<int>::iterator j = std::find(bend.begin(), bend.end(), ghostIndex);
278 >             if (j != bend.end()) {
279 >                bend.insert(j, ghostIndex);
280 >             }
281 >        }
282 >        
283 >        IntTuple3 bendTuple(bend[0], bend[1], bend[2]);
284 >        //make sure bendTuple.first is always less than or equal to bendTuple.third
285 >        if (bendTuple.first > bendTuple.third) {
286 >            std::swap(bendTuple.first, bendTuple.third);
287 >        }
288 >        
289 >        iter = allBends.find(bendTuple);
290 >        if ( iter != allBends.end()) {
291 >            std::cout << "Error in Molecule " << getName() << ": " << "Bend appears multiple times\n";
292 >        } else {
293 >            allBends.insert(bendTuple);
294 >        }
295      }
378    else return strdup("MoleculeStamp error, nCutoffGroups not given before"
379                       " first CutoffGroup declaration." );
380  }
381  
382  return NULL;
383 }
296  
297 < char* MoleculeStamp::addBond( BondStamp* the_bond, int bondIndex ){
298 <  
299 <  
300 <  if( have_bonds && bondIndex < n_bonds ) bonds[bondIndex] = the_bond;
389 <  else{
390 <    if( have_bonds ){
391 <      sprintf( errMsg, "MoleculeStamp error, %d out of nBonds range",
392 <               bondIndex );
393 <      return strdup( errMsg );
394 <    }
395 <    else return strdup("MoleculeStamp error, nBonds not given before"
396 <                       "first bond declaration." );
397 <  }
297 >    for (int i = 0; i < getNBonds(); ++i) {
298 >        BondStamp* bondStamp = getBondStamp(i);
299 >        int a = bondStamp->getA();
300 >        int b = bondStamp->getB();
301  
302 <  return NULL;
303 < }
302 >        AtomStamp* atomA = getAtomStamp(a);
303 >        AtomStamp* atomB = getAtomStamp(b);
304  
305 < char* MoleculeStamp::addBend( BendStamp* the_bend, int bendIndex ){
306 <  
307 <  
308 <  if( have_bends && bendIndex < n_bends ) bends[bendIndex] = the_bend;
309 <  else{
310 <    if( have_bends ){
311 <      sprintf( errMsg, "MoleculeStamp error, %d out of nBends range",
312 <               bendIndex );
313 <      return strdup( errMsg );
305 >        //find bend c--a--b
306 >        AtomStamp::AtomIter ai;
307 >        for(int c= atomA->getFirstBonedAtom(ai);c != -1;c = atomA->getNextBonedAtom(ai))
308 >        {
309 >            if(b == c)
310 >                continue;          
311 >            
312 >            IntTuple3 newBend(c, a, b);
313 >            if (newBend.first > newBend.third) {
314 >                std::swap(newBend.first, newBend.third);
315 >            }
316 >
317 >            if (allBends.find(newBend) == allBends.end() ) {                
318 >                allBends.insert(newBend);
319 >                BendStamp * newBendStamp = new BendStamp();
320 >                newBendStamp->setMembers(newBend);
321 >                addBendStamp(newBendStamp);
322 >            }
323 >        }        
324 >
325 >        //find bend a--b--c
326 >        for(int c= atomB->getFirstBonedAtom(ai);c != -1;c = atomB->getNextBonedAtom(ai))
327 >        {
328 >            if(a == c)
329 >                continue;          
330 >
331 >            IntTuple3 newBend( a, b, c);
332 >            if (newBend.first > newBend.third) {
333 >                std::swap(newBend.first, newBend.third);
334 >            }            
335 >            if (allBends.find(newBend) == allBends.end() ) {                
336 >                allBends.insert(newBend);
337 >                BendStamp * newBendStamp = new BendStamp();
338 >                newBendStamp->setMembers(newBend);
339 >                addBendStamp(newBendStamp);
340 >            }
341 >        }        
342      }
412    else return strdup("MoleculeStamp error, nBends not given before"
413                       "first bend declaration." );
414  }
343  
416  return NULL;
344   }
345  
346 < char* MoleculeStamp::addTorsion( TorsionStamp* the_torsion, int torsionIndex ){
347 <  
348 <  
349 <  if( have_torsions && torsionIndex < n_torsions )
350 <    torsions[torsionIndex] = the_torsion;
351 <  else{
352 <    if( have_torsions ){
353 <      sprintf( errMsg, "MoleculeStamp error, %d out of nTorsions range",
427 <               torsionIndex );
428 <      return strdup( errMsg );
346 > void MoleculeStamp::checkTorsions() {
347 >    for(int i = 0; i < getNTorsions(); ++i) {
348 >        TorsionStamp* torsionStamp = getTorsionStamp(i);
349 >        std::vector<int> torsionAtoms =  torsionStamp ->getMembers();
350 >        std::vector<int>::iterator j =std::find_if(torsionAtoms.begin(), torsionAtoms.end(), std::bind2nd(std::greater<int>(), getNAtoms()-1));
351 >        if (j != torsionAtoms.end()) {
352 >            std::cout << "Error in Molecule " << getName() << ": atoms of torsion" << containerToString(torsionAtoms) << " have invalid indices\n";
353 >        }
354      }
355 <    else return strdup("MoleculeStamp error, nTorsions not given before"
356 <                       "first torsion declaration." );
357 <  }
355 >    
356 >    for(int i = 0; i < getNTorsions(); ++i) {
357 >        TorsionStamp* torsionStamp = getTorsionStamp(i);
358 >        std::vector<int> torsionAtoms =  torsionStamp->getMembers();
359 >        std::vector<int> rigidSet(getNRigidBodies(), 0);
360 >        std::vector<int>::iterator j;
361 >        for( j = torsionAtoms.begin(); j != torsionAtoms.end(); ++j) {
362 >            int rigidbodyIndex = atom2Rigidbody[*j];
363 >            if (rigidbodyIndex >= 0) {
364 >                ++rigidSet[rigidbodyIndex];
365 >                if (rigidSet[rigidbodyIndex] > 1) {
366 >                    std::cout << "Error in Molecule " << getName() << ": torsion" << containerToString(torsionAtoms) << "is invalid\n";                  
367 >                }
368 >            }
369 >        }
370 >    }    
371  
372 <  return NULL;
372 >    std::set<IntTuple4> allTorsions;
373 >    std::set<IntTuple4>::iterator iter;
374 >     for(int i = 0; i < getNTorsions(); ++i) {
375 >         TorsionStamp* torsionStamp= getTorsionStamp(i);
376 >         std::vector<int> torsion = torsionStamp->getMembers();
377 >         if (torsion.size() == 3) {
378 >             int ghostIndex = torsionStamp->getGhostVectorSource();
379 >             std::vector<int>::iterator j = std::find(torsion.begin(), torsion.end(), ghostIndex);
380 >             if (j != torsion.end()) {
381 >                torsion.insert(j, ghostIndex);
382 >             }
383 >         }
384 >
385 >        IntTuple4 torsionTuple(torsion[0], torsion[1], torsion[2], torsion[3]);
386 >        if (torsionTuple.first > torsionTuple.fourth) {
387 >            std::swap(torsionTuple.first, torsionTuple.fourth);
388 >            std::swap(torsionTuple.second, torsionTuple.third);                    
389 >        }                
390 >
391 >         iter = allTorsions.find(torsionTuple);
392 >         if ( iter == allTorsions.end()) {
393 >            allTorsions.insert(torsionTuple);
394 >         } else {
395 >            std::cout << "Error in Molecule " << getName() << ": " << "Torsion appears multiple times\n";
396 >         }
397 >     }
398 >
399 >    for (int i = 0; i < getNBonds(); ++i) {
400 >        BondStamp* bondStamp = getBondStamp(i);
401 >        int b = bondStamp->getA();
402 >        int c = bondStamp->getB();
403 >
404 >        AtomStamp* atomB = getAtomStamp(b);
405 >        AtomStamp* atomC = getAtomStamp(c);
406 >
407 >        AtomStamp::AtomIter ai2;
408 >        AtomStamp::AtomIter ai3;
409 >
410 >        for(int a = atomB->getFirstBonedAtom(ai2);a != -1;a = atomB->getNextBonedAtom(ai2))
411 >        {
412 >            if(a == c)
413 >                continue;
414 >
415 >            for(int d = atomC->getFirstBonedAtom(ai3);d != -1;d = atomC->getNextBonedAtom(ai3))
416 >            {
417 >                if(d == b)
418 >                    continue;
419 >                
420 >                IntTuple4 newTorsion(a, b, c, d);
421 >                //make sure the first element is always less than or equal to the fourth element in IntTuple4
422 >                if (newTorsion.first > newTorsion.fourth) {
423 >                    std::swap(newTorsion.first, newTorsion.fourth);
424 >                    std::swap(newTorsion.second, newTorsion.third);                    
425 >                }                
426 >                if (allTorsions.find(newTorsion) == allTorsions.end() ) {                
427 >                    allTorsions.insert(newTorsion);
428 >                    TorsionStamp * newTorsionStamp = new TorsionStamp();
429 >                    newTorsionStamp->setMembers(newTorsion);
430 >                    addTorsionStamp(newTorsionStamp);                    
431 >                }            
432 >            }
433 >        }    
434 >    }
435 >
436   }
437  
438 < char* MoleculeStamp::checkMe( void ){
439 <  
440 <  int i;
441 <  short int no_atom, no_rigidbody, no_cutoffgroup;
438 > void MoleculeStamp::checkRigidBodies() {
439 >     std::vector<RigidBodyStamp*>::iterator ri = std::find(rigidBodyStamps_.begin(), rigidBodyStamps_.end(), static_cast<RigidBodyStamp*>(NULL));
440 >     if (ri != rigidBodyStamps_.end()) {
441 >         std::cout << "Error in Molecule " << getName() << ":rigidBody[" <<  ri - rigidBodyStamps_.begin()<< "] is missing\n";
442 >     }
443  
444 <  if( !have_name ) return strdup( "MoleculeStamp error. Molecule's name"
445 <                                  " was not given.\n" );
446 <  
447 <  if( !have_atoms ){
448 <    return strdup( "MoleculeStamp error. Molecule contains no atoms." );
449 <  }
450 <  
451 <  no_rigidbody = 0;
452 <  for( i=0; i<n_rigidbodies; i++ ){
453 <    if( rigidBodies[i] == NULL ) no_rigidbody = 1;
452 <  }
444 >    for (int i = 0; i < getNRigidBodies(); ++i) {
445 >        RigidBodyStamp* rbStamp = getRigidBodyStamp(i);
446 >        std::vector<int> rigidAtoms =  rbStamp ->getMembers();
447 >        std::vector<int>::iterator j =std::find_if(rigidAtoms.begin(), rigidAtoms.end(), std::bind2nd(std::greater<int>(), getNAtoms()-1));
448 >        if (j != rigidAtoms.end()) {
449 >            std::cout << "Error in Molecule " << getName();
450 >        }
451 >        
452 >    }    
453 > }
454  
455 <  if( no_rigidbody ){
455 <    sprintf( errMsg,
456 <             "MoleculeStamp error. Not all of the RigidBodies were"
457 <             " declared in molecule \"%s\".\n", name );
458 <    return strdup( errMsg );
459 <  }
455 > void MoleculeStamp::checkCutoffGroups() {
456  
457 <  no_cutoffgroup = 0;
458 <  for( i=0; i<n_cutoffgroups; i++ ){
459 <    if( cutoffGroups[i] == NULL ) no_cutoffgroup = 1;
460 <  }
457 >    for(int i = 0; i < getNCutoffGroups(); ++i) {
458 >        CutoffGroupStamp* cutoffGroupStamp = getCutoffGroupStamp(i);
459 >        std::vector<int> cutoffGroupAtoms =  cutoffGroupStamp ->getMembers();
460 >        std::vector<int>::iterator j =std::find_if(cutoffGroupAtoms.begin(), cutoffGroupAtoms.end(), std::bind2nd(std::greater<int>(), getNAtoms()-1));
461 >        if (j != cutoffGroupAtoms.end()) {
462 >            std::cout << "Error in Molecule " << getName() << ": cutoffGroup" << " is out of range\n";
463 >        }
464 >    }    
465 > }
466  
467 <  if( no_cutoffgroup ){
467 <    sprintf( errMsg,
468 <             "MoleculeStamp error. Not all of the CutoffGroups were"
469 <             " declared in molecule \"%s\".\n", name );
470 <    return strdup( errMsg );
471 <  }
472 <  
473 <  no_atom = 0;
474 <  for( i=0; i<n_atoms; i++ ){
475 <    if( atoms[i] == NULL ) no_atom = 1;
476 <  }
467 > void MoleculeStamp::checkFragments() {
468  
469 <  if( no_atom ){
470 <    sprintf( errMsg,
471 <             "MoleculeStamp error. Not all of the atoms were"
472 <             " declared in molecule \"%s\".\n", name );
473 <    return strdup( errMsg );
474 <  }
469 >    std::vector<FragmentStamp*>::iterator fi = std::find(fragmentStamps_.begin(), fragmentStamps_.end(), static_cast<FragmentStamp*>(NULL));
470 >    if (fi != fragmentStamps_.end()) {
471 >        std::cout << "Error in Molecule " << getName() << ":fragment[" <<  fi - fragmentStamps_.begin()<< "] is missing\n";
472 >    }
473 >    
474 > }
475  
476 <  n_integrable = n_atoms;
486 <  for (i = 0; i < n_rigidbodies; i++)
487 <    n_integrable = n_integrable - rigidBodies[i]->getNMembers() + 1; //rigidbody is an integrable object
488 <  
489 <  if (n_integrable <= 0 || n_integrable > n_atoms) {
490 <    sprintf( errMsg,
491 <             "MoleculeStamp error. n_integrable is either <= 0 or"
492 <             " greater than n_atoms in molecule \"%s\".\n", name );
493 <    return strdup( errMsg );
494 <  }
476 > void MoleculeStamp::fillBondInfo() {
477  
478 <  return NULL;
479 < }  
478 >    for (int i = 0; i < getNBonds(); ++i) {
479 >        BondStamp* bondStamp = getBondStamp(i);
480 >        int a = bondStamp->getA();
481 >        int b = bondStamp->getB();
482 >        AtomStamp* atomA = getAtomStamp(a);
483 >        AtomStamp* atomB = getAtomStamp(b);
484 >        atomA->addBond(i);
485 >        atomA->addBondedAtom(b);
486 >        atomB->addBond(i);        
487 >        atomB->addBondedAtom(a);
488  
489 +    }
490 + }
491  
492 +
493 +
494   //Function Name: isBondInSameRigidBody
495   //Return true is both atoms of the bond belong to the same rigid body, otherwise return false
496   bool MoleculeStamp::isBondInSameRigidBody(BondStamp* bond){
# Line 520 | Line 514 | bool MoleculeStamp::isAtomInRigidBody(int atomIndex){
514   // Function Name: isAtomInRigidBody
515   //return false if atom does not belong to a rigid body, otherwise return true
516   bool MoleculeStamp::isAtomInRigidBody(int atomIndex){
517 <  int whichRigidBody;
524 <  int consAtomIndex;
525 <
526 <  return isAtomInRigidBody(atomIndex, whichRigidBody, consAtomIndex);
517 >  return atom2Rigidbody[atomIndex] >=0 ;
518    
519   }
520  
# Line 534 | Line 525 | bool MoleculeStamp::isAtomInRigidBody(int atomIndex, i
525   //whichRigidBody: the index of rigidbody in component
526   //consAtomIndex:  the position of joint atom apears in  rigidbody's definition
527   bool MoleculeStamp::isAtomInRigidBody(int atomIndex, int& whichRigidBody, int& consAtomIndex){
537  RigidBodyStamp* rbStamp;
538  int numRb;
539  int numAtom;
528  
529 +  
530 +
531    whichRigidBody = -1;
532    consAtomIndex = -1;
533  
534 <  numRb = this->getNRigidBodies();
535 <  
536 <  for(int i = 0 ; i < numRb; i++){
537 <    rbStamp = this->getRigidBody(i);
538 <    numAtom = rbStamp->getNMembers();
539 <    for(int j = 0; j < numAtom; j++)
550 <      if (rbStamp->getMember(j) == atomIndex){
551 <        whichRigidBody = i;
534 >  if (atom2Rigidbody[atomIndex] >=0) {
535 >    whichRigidBody = atom2Rigidbody[atomIndex];
536 >    RigidBodyStamp* rbStamp = getRigidBodyStamp(whichRigidBody);
537 >    int numAtom = rbStamp->getNMembers();
538 >    for(int j = 0; j < numAtom; j++) {
539 >      if (rbStamp->getMemberAt(j) == atomIndex){
540          consAtomIndex = j;
541          return true;
542        }
543 +    }
544    }
545  
546    return false;
# Line 561 | Line 550 | bool MoleculeStamp::isAtomInRigidBody(int atomIndex, i
550   //return the position of joint atom apears in  rigidbody's definition
551   //for the time being, we will use the most inefficient algorithm, the complexity is O(N2)
552   //actually we could improve the complexity to O(NlgN) by sorting the atom index in rigid body first
553 < std::vector<std::pair<int, int> > MoleculeStamp::getJointAtoms(int rb1, int rb2){
553 > std::vector<std::pair<int, int> > MoleculeStamp::getJointAtoms(int rb1, int rb2){
554    RigidBodyStamp* rbStamp1;
555    RigidBodyStamp* rbStamp2;
556    int natomInRb1;
557    int natomInRb2;
558    int atomIndex1;
559    int atomIndex2;
560 <   std::vector<std::pair<int, int> > jointAtomIndexPair;
560 >  std::vector<std::pair<int, int> > jointAtomIndexPair;
561    
562 <  rbStamp1 = this->getRigidBody(rb1);
562 >  rbStamp1 = this->getRigidBodyStamp(rb1);
563    natomInRb1 =rbStamp1->getNMembers();
564  
565 <  rbStamp2 = this->getRigidBody(rb2);
565 >  rbStamp2 = this->getRigidBodyStamp(rb2);
566    natomInRb2 =rbStamp2->getNMembers();
567  
568    for(int i = 0; i < natomInRb1; i++){
569 <    atomIndex1 = rbStamp1->getMember(i);
569 >    atomIndex1 = rbStamp1->getMemberAt(i);
570        
571      for(int j= 0; j < natomInRb1; j++){
572 <      atomIndex2 = rbStamp2->getMember(j);
572 >      atomIndex2 = rbStamp2->getMemberAt(j);
573  
574        if(atomIndex1 == atomIndex2){
575          jointAtomIndexPair.push_back(std::make_pair(i, j));
576          break;
577        }
578        
579 <    }//end for(j =0)
579 >    }
580  
581 <  }//end for (i = 0)
581 >  }
582  
583    return jointAtomIndexPair;
584   }
585 +
586 + }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines