ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/trunk/src/parallel/ForceMatrixDecomposition.cpp
(Generate patch)

Comparing branches/development/src/parallel/ForceMatrixDecomposition.cpp (file contents):
Revision 1612 by gezelter, Fri Aug 12 19:59:56 2011 UTC vs.
Revision 1688 by gezelter, Wed Mar 14 17:56:01 2012 UTC

# Line 36 | Line 36
36   * [1]  Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).            
37   * [2]  Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).          
38   * [3]  Sun, Lin & Gezelter, J. Chem. Phys. 128, 24107 (2008).          
39 < * [4]  Vardeman & Gezelter, in progress (2009).                        
39 > * [4]  Kuang & Gezelter,  J. Chem. Phys. 133, 164101 (2010).
40 > * [5]  Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011).
41   */
42   #include "parallel/ForceMatrixDecomposition.hpp"
43   #include "math/SquareMatrix3.hpp"
# Line 233 | Line 234 | namespace OpenMD {
234        }      
235      }
236  
237 < #endif
237 <
238 <    // allocate memory for the parallel objects
239 <    atypesLocal.resize(nLocal_);
240 <
241 <    for (int i = 0; i < nLocal_; i++)
242 <      atypesLocal[i] = ff_->getAtomType(idents[i]);
243 <
244 <    groupList_.clear();
245 <    groupList_.resize(nGroups_);
246 <    for (int i = 0; i < nGroups_; i++) {
247 <      int gid = cgLocalToGlobal[i];
248 <      for (int j = 0; j < nLocal_; j++) {
249 <        int aid = AtomLocalToGlobal[j];
250 <        if (globalGroupMembership[aid] == gid) {
251 <          groupList_[i].push_back(j);
252 <        }
253 <      }      
254 <    }
255 <
237 > #else
238      excludesForAtom.clear();
239      excludesForAtom.resize(nLocal_);
240      toposForAtom.clear();
# Line 285 | Line 267 | namespace OpenMD {
267          }
268        }      
269      }
270 <    
270 > #endif
271 >
272 >    // allocate memory for the parallel objects
273 >    atypesLocal.resize(nLocal_);
274 >
275 >    for (int i = 0; i < nLocal_; i++)
276 >      atypesLocal[i] = ff_->getAtomType(idents[i]);
277 >
278 >    groupList_.clear();
279 >    groupList_.resize(nGroups_);
280 >    for (int i = 0; i < nGroups_; i++) {
281 >      int gid = cgLocalToGlobal[i];
282 >      for (int j = 0; j < nLocal_; j++) {
283 >        int aid = AtomLocalToGlobal[j];
284 >        if (globalGroupMembership[aid] == gid) {
285 >          groupList_[i].push_back(j);
286 >        }
287 >      }      
288 >    }
289 >
290 >
291      createGtypeCutoffMap();
292  
293    }
# Line 683 | Line 685 | namespace OpenMD {
685        }
686        
687        AtomPlanRealColumn->scatter(atomColData.skippedCharge, skch_tmp);
688 <      for (int i = 0; i < ns; i++)
688 >      for (int i = 0; i < ns; i++)
689          snap_->atomData.skippedCharge[i] += skch_tmp[i];
690 +            
691      }
692      
693      nLocal_ = snap_->getNumberOfAtoms();
# Line 714 | Line 717 | namespace OpenMD {
717        pairwisePot[ii] = ploc2;
718      }
719  
720 +    for (int ii = 0; ii < N_INTERACTION_FAMILIES; ii++) {
721 +      RealType ploc1 = embeddingPot[ii];
722 +      RealType ploc2 = 0.0;
723 +      MPI::COMM_WORLD.Allreduce(&ploc1, &ploc2, 1, MPI::REALTYPE, MPI::SUM);
724 +      embeddingPot[ii] = ploc2;
725 +    }
726 +
727   #endif
728  
729    }
# Line 826 | Line 836 | namespace OpenMD {
836     */
837    bool ForceMatrixDecomposition::skipAtomPair(int atom1, int atom2) {
838      int unique_id_1, unique_id_2;
839 <    
839 >        
840   #ifdef IS_MPI
841      // in MPI, we have to look up the unique IDs for each atom
842      unique_id_1 = AtomRowToGlobal[atom1];
843      unique_id_2 = AtomColToGlobal[atom2];
844 + #else
845 +    unique_id_1 = AtomLocalToGlobal[atom1];
846 +    unique_id_2 = AtomLocalToGlobal[atom2];
847 + #endif  
848  
835    // this situation should only arise in MPI simulations
849      if (unique_id_1 == unique_id_2) return true;
850 <    
850 >
851 > #ifdef IS_MPI
852      // this prevents us from doing the pair on multiple processors
853      if (unique_id_1 < unique_id_2) {
854        if ((unique_id_1 + unique_id_2) % 2 == 0) return true;
855      } else {
856 <      if ((unique_id_1 + unique_id_2) % 2 == 1) return true;
856 >      if ((unique_id_1 + unique_id_2) % 2 == 1) return true;
857      }
858   #endif
859 +    
860      return false;
861    }
862  
# Line 855 | Line 870 | namespace OpenMD {
870     * field) must still be handled for these pairs.
871     */
872    bool ForceMatrixDecomposition::excludeAtomPair(int atom1, int atom2) {
873 <    int unique_id_2;
874 < #ifdef IS_MPI
875 <    // in MPI, we have to look up the unique IDs for the row atom.
861 <    unique_id_2 = AtomColToGlobal[atom2];
862 < #else
863 <    // in the normal loop, the atom numbers are unique
864 <    unique_id_2 = atom2;
865 < #endif
873 >
874 >    // excludesForAtom was constructed to use row/column indices in the MPI
875 >    // version, and to use local IDs in the non-MPI version:
876      
877      for (vector<int>::iterator i = excludesForAtom[atom1].begin();
878           i != excludesForAtom[atom1].end(); ++i) {
879 <      if ( (*i) == unique_id_2 ) return true;
879 >      if ( (*i) == atom2 ) return true;
880      }
881  
882      return false;
# Line 941 | Line 951 | namespace OpenMD {
951      }
952  
953   #else
954 +    
955  
956 +    // cerr << "atoms = " << atom1 << " " << atom2 << "\n";
957 +    // cerr << "pos1 = " << snap_->atomData.position[atom1] << "\n";
958 +    // cerr << "pos2 = " << snap_->atomData.position[atom2] << "\n";
959 +
960      idat.atypes = make_pair( atypesLocal[atom1], atypesLocal[atom2]);
961      //idat.atypes = make_pair( ff_->getAtomType(idents[atom1]),
962      //                         ff_->getAtomType(idents[atom2]) );
# Line 991 | Line 1006 | namespace OpenMD {
1006    
1007    void ForceMatrixDecomposition::unpackInteractionData(InteractionData &idat, int atom1, int atom2) {    
1008   #ifdef IS_MPI
1009 <    pot_row[atom1] += 0.5 *  *(idat.pot);
1010 <    pot_col[atom2] += 0.5 *  *(idat.pot);
1009 >    pot_row[atom1] += RealType(0.5) *  *(idat.pot);
1010 >    pot_col[atom2] += RealType(0.5) *  *(idat.pot);
1011  
1012      atomRowData.force[atom1] += *(idat.f1);
1013      atomColData.force[atom2] -= *(idat.f1);
# Line 1185 | Line 1200 | namespace OpenMD {
1200                  }
1201                }
1202   #else
1188              
1203                for (vector<int>::iterator j1 = cellList_[m1].begin();
1204                     j1 != cellList_[m1].end(); ++j1) {
1205                  for (vector<int>::iterator j2 = cellList_[m2].begin();
1206                       j2 != cellList_[m2].end(); ++j2) {
1207 <                  
1207 >    
1208                    // Always do this if we're in different cells or if
1209 <                  // we're in the same cell and the global index of the
1210 <                  // j2 cutoff group is less than the j1 cutoff group
1211 <                  
1212 <                  if (m2 != m1 || (*j2) < (*j1)) {
1209 >                  // we're in the same cell and the global index of
1210 >                  // the j2 cutoff group is greater than or equal to
1211 >                  // the j1 cutoff group.  Note that Rappaport's code
1212 >                  // has a "less than" conditional here, but that
1213 >                  // deals with atom-by-atom computation.  OpenMD
1214 >                  // allows atoms within a single cutoff group to
1215 >                  // interact with each other.
1216 >
1217 >
1218 >
1219 >                  if (m2 != m1 || (*j2) >= (*j1) ) {
1220 >
1221                      dr = snap_->cgData.position[(*j2)] - snap_->cgData.position[(*j1)];
1222                      snap_->wrapVector(dr);
1223                      cuts = getGroupCutoffs( (*j1), (*j2) );
# Line 1214 | Line 1236 | namespace OpenMD {
1236        // branch to do all cutoff group pairs
1237   #ifdef IS_MPI
1238        for (int j1 = 0; j1 < nGroupsInRow_; j1++) {
1239 <        for (int j2 = 0; j2 < nGroupsInCol_; j2++) {      
1239 >        for (int j2 = 0; j2 < nGroupsInCol_; j2++) {    
1240            dr = cgColData.position[j2] - cgRowData.position[j1];
1241            snap_->wrapVector(dr);
1242            cuts = getGroupCutoffs( j1, j2 );
# Line 1222 | Line 1244 | namespace OpenMD {
1244              neighborList.push_back(make_pair(j1, j2));
1245            }
1246          }
1247 <      }
1247 >      }      
1248   #else
1249 <      for (int j1 = 0; j1 < nGroups_ - 1; j1++) {
1250 <        for (int j2 = j1 + 1; j2 < nGroups_; j2++) {
1249 >      // include all groups here.
1250 >      for (int j1 = 0; j1 < nGroups_; j1++) {
1251 >        // include self group interactions j2 == j1
1252 >        for (int j2 = j1; j2 < nGroups_; j2++) {
1253            dr = snap_->cgData.position[j2] - snap_->cgData.position[j1];
1254            snap_->wrapVector(dr);
1255            cuts = getGroupCutoffs( j1, j2 );
1256            if (dr.lengthSquare() < cuts.third) {
1257              neighborList.push_back(make_pair(j1, j2));
1258            }
1259 <        }
1260 <      }        
1259 >        }    
1260 >      }
1261   #endif
1262      }
1263        

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines