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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines