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 2204 by gezelter, Fri Apr 15 22:04:00 2005 UTC vs.
Revision 2493 by tim, Tue Dec 6 21:01:08 2005 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines