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 1590 by gezelter, Mon Jul 11 01:39:49 2011 UTC vs.
Revision 1616 by gezelter, Tue Aug 30 15:45:35 2011 UTC

# Line 47 | Line 47 | namespace OpenMD {
47   using namespace std;
48   namespace OpenMD {
49  
50 +  ForceMatrixDecomposition::ForceMatrixDecomposition(SimInfo* info, InteractionManager* iMan) : ForceDecomposition(info, iMan) {
51 +
52 +    // In a parallel computation, row and colum scans must visit all
53 +    // surrounding cells (not just the 14 upper triangular blocks that
54 +    // are used when the processor can see all pairs)
55 + #ifdef IS_MPI
56 +    cellOffsets_.clear();
57 +    cellOffsets_.push_back( Vector3i(-1,-1,-1) );
58 +    cellOffsets_.push_back( Vector3i( 0,-1,-1) );
59 +    cellOffsets_.push_back( Vector3i( 1,-1,-1) );                          
60 +    cellOffsets_.push_back( Vector3i(-1, 0,-1) );
61 +    cellOffsets_.push_back( Vector3i( 0, 0,-1) );
62 +    cellOffsets_.push_back( Vector3i( 1, 0,-1) );
63 +    cellOffsets_.push_back( Vector3i(-1, 1,-1) );
64 +    cellOffsets_.push_back( Vector3i( 0, 1,-1) );      
65 +    cellOffsets_.push_back( Vector3i( 1, 1,-1) );
66 +    cellOffsets_.push_back( Vector3i(-1,-1, 0) );
67 +    cellOffsets_.push_back( Vector3i( 0,-1, 0) );
68 +    cellOffsets_.push_back( Vector3i( 1,-1, 0) );
69 +    cellOffsets_.push_back( Vector3i(-1, 0, 0) );      
70 +    cellOffsets_.push_back( Vector3i( 0, 0, 0) );
71 +    cellOffsets_.push_back( Vector3i( 1, 0, 0) );
72 +    cellOffsets_.push_back( Vector3i(-1, 1, 0) );
73 +    cellOffsets_.push_back( Vector3i( 0, 1, 0) );
74 +    cellOffsets_.push_back( Vector3i( 1, 1, 0) );
75 +    cellOffsets_.push_back( Vector3i(-1,-1, 1) );
76 +    cellOffsets_.push_back( Vector3i( 0,-1, 1) );
77 +    cellOffsets_.push_back( Vector3i( 1,-1, 1) );
78 +    cellOffsets_.push_back( Vector3i(-1, 0, 1) );
79 +    cellOffsets_.push_back( Vector3i( 0, 0, 1) );
80 +    cellOffsets_.push_back( Vector3i( 1, 0, 1) );
81 +    cellOffsets_.push_back( Vector3i(-1, 1, 1) );
82 +    cellOffsets_.push_back( Vector3i( 0, 1, 1) );
83 +    cellOffsets_.push_back( Vector3i( 1, 1, 1) );
84 + #endif    
85 +  }
86 +
87 +
88    /**
89     * distributeInitialData is essentially a copy of the older fortran
90     * SimulationSetup
91     */
54  
92    void ForceMatrixDecomposition::distributeInitialData() {
93      snap_ = sman_->getCurrentSnapshot();
94      storageLayout_ = sman_->getStorageLayout();
# Line 74 | Line 111 | namespace OpenMD {
111  
112   #ifdef IS_MPI
113  
114 <    AtomCommIntRow = new Communicator<Row,int>(nLocal_);
115 <    AtomCommRealRow = new Communicator<Row,RealType>(nLocal_);
79 <    AtomCommVectorRow = new Communicator<Row,Vector3d>(nLocal_);
80 <    AtomCommMatrixRow = new Communicator<Row,Mat3x3d>(nLocal_);
81 <    AtomCommPotRow = new Communicator<Row,potVec>(nLocal_);
114 >    MPI::Intracomm row = rowComm.getComm();
115 >    MPI::Intracomm col = colComm.getComm();
116  
117 <    AtomCommIntColumn = new Communicator<Column,int>(nLocal_);
118 <    AtomCommRealColumn = new Communicator<Column,RealType>(nLocal_);
119 <    AtomCommVectorColumn = new Communicator<Column,Vector3d>(nLocal_);
120 <    AtomCommMatrixColumn = new Communicator<Column,Mat3x3d>(nLocal_);
121 <    AtomCommPotColumn = new Communicator<Column,potVec>(nLocal_);
117 >    AtomPlanIntRow = new Plan<int>(row, nLocal_);
118 >    AtomPlanRealRow = new Plan<RealType>(row, nLocal_);
119 >    AtomPlanVectorRow = new Plan<Vector3d>(row, nLocal_);
120 >    AtomPlanMatrixRow = new Plan<Mat3x3d>(row, nLocal_);
121 >    AtomPlanPotRow = new Plan<potVec>(row, nLocal_);
122  
123 <    cgCommIntRow = new Communicator<Row,int>(nGroups_);
124 <    cgCommVectorRow = new Communicator<Row,Vector3d>(nGroups_);
125 <    cgCommIntColumn = new Communicator<Column,int>(nGroups_);
126 <    cgCommVectorColumn = new Communicator<Column,Vector3d>(nGroups_);
123 >    AtomPlanIntColumn = new Plan<int>(col, nLocal_);
124 >    AtomPlanRealColumn = new Plan<RealType>(col, nLocal_);
125 >    AtomPlanVectorColumn = new Plan<Vector3d>(col, nLocal_);
126 >    AtomPlanMatrixColumn = new Plan<Mat3x3d>(col, nLocal_);
127 >    AtomPlanPotColumn = new Plan<potVec>(col, nLocal_);
128  
129 <    nAtomsInRow_ = AtomCommIntRow->getSize();
130 <    nAtomsInCol_ = AtomCommIntColumn->getSize();
131 <    nGroupsInRow_ = cgCommIntRow->getSize();
132 <    nGroupsInCol_ = cgCommIntColumn->getSize();
129 >    cgPlanIntRow = new Plan<int>(row, nGroups_);
130 >    cgPlanVectorRow = new Plan<Vector3d>(row, nGroups_);
131 >    cgPlanIntColumn = new Plan<int>(col, nGroups_);
132 >    cgPlanVectorColumn = new Plan<Vector3d>(col, nGroups_);
133  
134 +    nAtomsInRow_ = AtomPlanIntRow->getSize();
135 +    nAtomsInCol_ = AtomPlanIntColumn->getSize();
136 +    nGroupsInRow_ = cgPlanIntRow->getSize();
137 +    nGroupsInCol_ = cgPlanIntColumn->getSize();
138 +
139      // Modify the data storage objects with the correct layouts and sizes:
140      atomRowData.resize(nAtomsInRow_);
141      atomRowData.setStorageLayout(storageLayout_);
# Line 109 | Line 149 | namespace OpenMD {
149      identsRow.resize(nAtomsInRow_);
150      identsCol.resize(nAtomsInCol_);
151      
152 <    AtomCommIntRow->gather(idents, identsRow);
153 <    AtomCommIntColumn->gather(idents, identsCol);
152 >    AtomPlanIntRow->gather(idents, identsRow);
153 >    AtomPlanIntColumn->gather(idents, identsCol);
154      
155      // allocate memory for the parallel objects
156 +    atypesRow.resize(nAtomsInRow_);
157 +    atypesCol.resize(nAtomsInCol_);
158 +
159 +    for (int i = 0; i < nAtomsInRow_; i++)
160 +      atypesRow[i] = ff_->getAtomType(identsRow[i]);
161 +    for (int i = 0; i < nAtomsInCol_; i++)
162 +      atypesCol[i] = ff_->getAtomType(identsCol[i]);        
163 +
164 +    pot_row.resize(nAtomsInRow_);
165 +    pot_col.resize(nAtomsInCol_);
166 +
167      AtomRowToGlobal.resize(nAtomsInRow_);
168      AtomColToGlobal.resize(nAtomsInCol_);
169 +    AtomPlanIntRow->gather(AtomLocalToGlobal, AtomRowToGlobal);
170 +    AtomPlanIntColumn->gather(AtomLocalToGlobal, AtomColToGlobal);
171 +
172      cgRowToGlobal.resize(nGroupsInRow_);
173      cgColToGlobal.resize(nGroupsInCol_);
174 +    cgPlanIntRow->gather(cgLocalToGlobal, cgRowToGlobal);
175 +    cgPlanIntColumn->gather(cgLocalToGlobal, cgColToGlobal);
176 +
177      massFactorsRow.resize(nAtomsInRow_);
178      massFactorsCol.resize(nAtomsInCol_);
179 <    pot_row.resize(nAtomsInRow_);
180 <    pot_col.resize(nAtomsInCol_);
179 >    AtomPlanRealRow->gather(massFactors, massFactorsRow);
180 >    AtomPlanRealColumn->gather(massFactors, massFactorsCol);
181  
125    AtomCommIntRow->gather(AtomLocalToGlobal, AtomRowToGlobal);
126    AtomCommIntColumn->gather(AtomLocalToGlobal, AtomColToGlobal);
127    
128    cgCommIntRow->gather(cgLocalToGlobal, cgRowToGlobal);
129    cgCommIntColumn->gather(cgLocalToGlobal, cgColToGlobal);
130
131    AtomCommRealRow->gather(massFactors, massFactorsRow);
132    AtomCommRealColumn->gather(massFactors, massFactorsCol);
133
182      groupListRow_.clear();
183      groupListRow_.resize(nGroupsInRow_);
184      for (int i = 0; i < nGroupsInRow_; i++) {
# Line 185 | Line 233 | namespace OpenMD {
233        }      
234      }
235  
236 < #endif
189 <
190 <    groupList_.clear();
191 <    groupList_.resize(nGroups_);
192 <    for (int i = 0; i < nGroups_; i++) {
193 <      int gid = cgLocalToGlobal[i];
194 <      for (int j = 0; j < nLocal_; j++) {
195 <        int aid = AtomLocalToGlobal[j];
196 <        if (globalGroupMembership[aid] == gid) {
197 <          groupList_[i].push_back(j);
198 <        }
199 <      }      
200 <    }
201 <
236 > #else
237      excludesForAtom.clear();
238      excludesForAtom.resize(nLocal_);
239      toposForAtom.clear();
# Line 231 | Line 266 | namespace OpenMD {
266          }
267        }      
268      }
269 <    
269 > #endif
270 >
271 >    // allocate memory for the parallel objects
272 >    atypesLocal.resize(nLocal_);
273 >
274 >    for (int i = 0; i < nLocal_; i++)
275 >      atypesLocal[i] = ff_->getAtomType(idents[i]);
276 >
277 >    groupList_.clear();
278 >    groupList_.resize(nGroups_);
279 >    for (int i = 0; i < nGroups_; i++) {
280 >      int gid = cgLocalToGlobal[i];
281 >      for (int j = 0; j < nLocal_; j++) {
282 >        int aid = AtomLocalToGlobal[j];
283 >        if (globalGroupMembership[aid] == gid) {
284 >          groupList_[i].push_back(j);
285 >        }
286 >      }      
287 >    }
288 >
289 >
290      createGtypeCutoffMap();
291  
292    }
# Line 239 | Line 294 | namespace OpenMD {
294    void ForceMatrixDecomposition::createGtypeCutoffMap() {
295      
296      RealType tol = 1e-6;
297 +    largestRcut_ = 0.0;
298      RealType rc;
299      int atid;
300      set<AtomType*> atypes = info_->getSimulatedAtomTypes();
301 +    
302      map<int, RealType> atypeCutoff;
303        
304      for (set<AtomType*>::iterator at = atypes.begin();
# Line 249 | Line 306 | namespace OpenMD {
306        atid = (*at)->getIdent();
307        if (userChoseCutoff_)
308          atypeCutoff[atid] = userCutoff_;
309 <      else
309 >      else
310          atypeCutoff[atid] = interactionMan_->getSuggestedCutoffRadius(*at);
311      }
312 <
312 >    
313      vector<RealType> gTypeCutoffs;
314      // first we do a single loop over the cutoff groups to find the
315      // largest cutoff for any atypes present in this group.
# Line 312 | Line 369 | namespace OpenMD {
369      vector<RealType> groupCutoff(nGroups_, 0.0);
370      groupToGtype.resize(nGroups_);
371      for (int cg1 = 0; cg1 < nGroups_; cg1++) {
315
372        groupCutoff[cg1] = 0.0;
373        vector<int> atomList = getAtomsInGroupRow(cg1);
318
374        for (vector<int>::iterator ia = atomList.begin();
375             ia != atomList.end(); ++ia) {            
376          int atom1 = (*ia);
377          atid = idents[atom1];
378 <        if (atypeCutoff[atid] > groupCutoff[cg1]) {
378 >        if (atypeCutoff[atid] > groupCutoff[cg1])
379            groupCutoff[cg1] = atypeCutoff[atid];
325        }
380        }
381 <
381 >      
382        bool gTypeFound = false;
383        for (int gt = 0; gt < gTypeCutoffs.size(); gt++) {
384          if (abs(groupCutoff[cg1] - gTypeCutoffs[gt]) < tol) {
# Line 332 | Line 386 | namespace OpenMD {
386            gTypeFound = true;
387          }
388        }
389 <      if (!gTypeFound) {
389 >      if (!gTypeFound) {      
390          gTypeCutoffs.push_back( groupCutoff[cg1] );
391          groupToGtype[cg1] = gTypeCutoffs.size() - 1;
392        }      
# Line 376 | Line 430 | namespace OpenMD {
430  
431          pair<int,int> key = make_pair(i,j);
432          gTypeCutoffMap[key].first = thisRcut;
379
433          if (thisRcut > largestRcut_) largestRcut_ = thisRcut;
381
434          gTypeCutoffMap[key].second = thisRcut*thisRcut;
383        
435          gTypeCutoffMap[key].third = pow(thisRcut + skinThickness_, 2);
385
436          // sanity check
437          
438          if (userChoseCutoff_) {
# Line 508 | Line 558 | namespace OpenMD {
558   #ifdef IS_MPI
559      
560      // gather up the atomic positions
561 <    AtomCommVectorRow->gather(snap_->atomData.position,
561 >    AtomPlanVectorRow->gather(snap_->atomData.position,
562                                atomRowData.position);
563 <    AtomCommVectorColumn->gather(snap_->atomData.position,
563 >    AtomPlanVectorColumn->gather(snap_->atomData.position,
564                                   atomColData.position);
565      
566      // gather up the cutoff group positions
567 <    cgCommVectorRow->gather(snap_->cgData.position,
567 >
568 >    cgPlanVectorRow->gather(snap_->cgData.position,
569                              cgRowData.position);
570 <    cgCommVectorColumn->gather(snap_->cgData.position,
570 >
571 >    cgPlanVectorColumn->gather(snap_->cgData.position,
572                                 cgColData.position);
573 +
574      
575      // if needed, gather the atomic rotation matrices
576      if (storageLayout_ & DataStorage::dslAmat) {
577 <      AtomCommMatrixRow->gather(snap_->atomData.aMat,
577 >      AtomPlanMatrixRow->gather(snap_->atomData.aMat,
578                                  atomRowData.aMat);
579 <      AtomCommMatrixColumn->gather(snap_->atomData.aMat,
579 >      AtomPlanMatrixColumn->gather(snap_->atomData.aMat,
580                                     atomColData.aMat);
581      }
582      
583      // if needed, gather the atomic eletrostatic frames
584      if (storageLayout_ & DataStorage::dslElectroFrame) {
585 <      AtomCommMatrixRow->gather(snap_->atomData.electroFrame,
585 >      AtomPlanMatrixRow->gather(snap_->atomData.electroFrame,
586                                  atomRowData.electroFrame);
587 <      AtomCommMatrixColumn->gather(snap_->atomData.electroFrame,
587 >      AtomPlanMatrixColumn->gather(snap_->atomData.electroFrame,
588                                     atomColData.electroFrame);
589      }
590  
# Line 548 | Line 601 | namespace OpenMD {
601      
602      if (storageLayout_ & DataStorage::dslDensity) {
603        
604 <      AtomCommRealRow->scatter(atomRowData.density,
604 >      AtomPlanRealRow->scatter(atomRowData.density,
605                                 snap_->atomData.density);
606        
607        int n = snap_->atomData.density.size();
608        vector<RealType> rho_tmp(n, 0.0);
609 <      AtomCommRealColumn->scatter(atomColData.density, rho_tmp);
609 >      AtomPlanRealColumn->scatter(atomColData.density, rho_tmp);
610        for (int i = 0; i < n; i++)
611          snap_->atomData.density[i] += rho_tmp[i];
612      }
# Line 569 | Line 622 | namespace OpenMD {
622      storageLayout_ = sman_->getStorageLayout();
623   #ifdef IS_MPI
624      if (storageLayout_ & DataStorage::dslFunctional) {
625 <      AtomCommRealRow->gather(snap_->atomData.functional,
625 >      AtomPlanRealRow->gather(snap_->atomData.functional,
626                                atomRowData.functional);
627 <      AtomCommRealColumn->gather(snap_->atomData.functional,
627 >      AtomPlanRealColumn->gather(snap_->atomData.functional,
628                                   atomColData.functional);
629      }
630      
631      if (storageLayout_ & DataStorage::dslFunctionalDerivative) {
632 <      AtomCommRealRow->gather(snap_->atomData.functionalDerivative,
632 >      AtomPlanRealRow->gather(snap_->atomData.functionalDerivative,
633                                atomRowData.functionalDerivative);
634 <      AtomCommRealColumn->gather(snap_->atomData.functionalDerivative,
634 >      AtomPlanRealColumn->gather(snap_->atomData.functionalDerivative,
635                                   atomColData.functionalDerivative);
636      }
637   #endif
# Line 592 | Line 645 | namespace OpenMD {
645      int n = snap_->atomData.force.size();
646      vector<Vector3d> frc_tmp(n, V3Zero);
647      
648 <    AtomCommVectorRow->scatter(atomRowData.force, frc_tmp);
648 >    AtomPlanVectorRow->scatter(atomRowData.force, frc_tmp);
649      for (int i = 0; i < n; i++) {
650        snap_->atomData.force[i] += frc_tmp[i];
651        frc_tmp[i] = 0.0;
652      }
653      
654 <    AtomCommVectorColumn->scatter(atomColData.force, frc_tmp);
655 <    for (int i = 0; i < n; i++)
654 >    AtomPlanVectorColumn->scatter(atomColData.force, frc_tmp);
655 >    for (int i = 0; i < n; i++) {
656        snap_->atomData.force[i] += frc_tmp[i];
657 +    }
658          
659      if (storageLayout_ & DataStorage::dslTorque) {
660  
661        int nt = snap_->atomData.torque.size();
662        vector<Vector3d> trq_tmp(nt, V3Zero);
663  
664 <      AtomCommVectorRow->scatter(atomRowData.torque, trq_tmp);
664 >      AtomPlanVectorRow->scatter(atomRowData.torque, trq_tmp);
665        for (int i = 0; i < nt; i++) {
666          snap_->atomData.torque[i] += trq_tmp[i];
667          trq_tmp[i] = 0.0;
668        }
669        
670 <      AtomCommVectorColumn->scatter(atomColData.torque, trq_tmp);
670 >      AtomPlanVectorColumn->scatter(atomColData.torque, trq_tmp);
671        for (int i = 0; i < nt; i++)
672          snap_->atomData.torque[i] += trq_tmp[i];
673      }
# Line 623 | Line 677 | namespace OpenMD {
677        int ns = snap_->atomData.skippedCharge.size();
678        vector<RealType> skch_tmp(ns, 0.0);
679  
680 <      AtomCommRealRow->scatter(atomRowData.skippedCharge, skch_tmp);
680 >      AtomPlanRealRow->scatter(atomRowData.skippedCharge, skch_tmp);
681        for (int i = 0; i < ns; i++) {
682          snap_->atomData.skippedCharge[i] += skch_tmp[i];
683          skch_tmp[i] = 0.0;
684        }
685        
686 <      AtomCommRealColumn->scatter(atomColData.skippedCharge, skch_tmp);
687 <      for (int i = 0; i < ns; i++)
686 >      AtomPlanRealColumn->scatter(atomColData.skippedCharge, skch_tmp);
687 >      for (int i = 0; i < ns; i++)
688          snap_->atomData.skippedCharge[i] += skch_tmp[i];
689 +            
690      }
691      
692      nLocal_ = snap_->getNumberOfAtoms();
# Line 641 | Line 696 | namespace OpenMD {
696  
697      // scatter/gather pot_row into the members of my column
698            
699 <    AtomCommPotRow->scatter(pot_row, pot_temp);
699 >    AtomPlanPotRow->scatter(pot_row, pot_temp);
700  
701      for (int ii = 0;  ii < pot_temp.size(); ii++ )
702        pairwisePot += pot_temp[ii];
# Line 649 | Line 704 | namespace OpenMD {
704      fill(pot_temp.begin(), pot_temp.end(),
705           Vector<RealType, N_INTERACTION_FAMILIES> (0.0));
706        
707 <    AtomCommPotColumn->scatter(pot_col, pot_temp);    
707 >    AtomPlanPotColumn->scatter(pot_col, pot_temp);    
708      
709      for (int ii = 0;  ii < pot_temp.size(); ii++ )
710        pairwisePot += pot_temp[ii];    
711 +    
712 +    for (int ii = 0; ii < N_INTERACTION_FAMILIES; ii++) {
713 +      RealType ploc1 = pairwisePot[ii];
714 +      RealType ploc2 = 0.0;
715 +      MPI::COMM_WORLD.Allreduce(&ploc1, &ploc2, 1, MPI::REALTYPE, MPI::SUM);
716 +      pairwisePot[ii] = ploc2;
717 +    }
718 +
719 +    for (int ii = 0; ii < N_INTERACTION_FAMILIES; ii++) {
720 +      RealType ploc1 = embeddingPot[ii];
721 +      RealType ploc2 = 0.0;
722 +      MPI::COMM_WORLD.Allreduce(&ploc1, &ploc2, 1, MPI::REALTYPE, MPI::SUM);
723 +      embeddingPot[ii] = ploc2;
724 +    }
725 +
726   #endif
727  
728    }
# Line 765 | Line 835 | namespace OpenMD {
835     */
836    bool ForceMatrixDecomposition::skipAtomPair(int atom1, int atom2) {
837      int unique_id_1, unique_id_2;
838 <
838 >        
839   #ifdef IS_MPI
840      // in MPI, we have to look up the unique IDs for each atom
841      unique_id_1 = AtomRowToGlobal[atom1];
842      unique_id_2 = AtomColToGlobal[atom2];
843 + #else
844 +    unique_id_1 = AtomLocalToGlobal[atom1];
845 +    unique_id_2 = AtomLocalToGlobal[atom2];
846 + #endif  
847  
774    // this situation should only arise in MPI simulations
848      if (unique_id_1 == unique_id_2) return true;
849 <    
849 >
850 > #ifdef IS_MPI
851      // this prevents us from doing the pair on multiple processors
852      if (unique_id_1 < unique_id_2) {
853        if ((unique_id_1 + unique_id_2) % 2 == 0) return true;
854      } else {
855 <      if ((unique_id_1 + unique_id_2) % 2 == 1) return true;
855 >      if ((unique_id_1 + unique_id_2) % 2 == 1) return true;
856      }
857   #endif
858 +    
859      return false;
860    }
861  
# Line 794 | Line 869 | namespace OpenMD {
869     * field) must still be handled for these pairs.
870     */
871    bool ForceMatrixDecomposition::excludeAtomPair(int atom1, int atom2) {
872 <    int unique_id_2;
873 <    
874 < #ifdef IS_MPI
800 <    // in MPI, we have to look up the unique IDs for the row atom.
801 <    unique_id_2 = AtomColToGlobal[atom2];
802 < #else
803 <    // in the normal loop, the atom numbers are unique
804 <    unique_id_2 = atom2;
805 < #endif
872 >
873 >    // excludesForAtom was constructed to use row/column indices in the MPI
874 >    // version, and to use local IDs in the non-MPI version:
875      
876      for (vector<int>::iterator i = excludesForAtom[atom1].begin();
877           i != excludesForAtom[atom1].end(); ++i) {
878 <      if ( (*i) == unique_id_2 ) return true;
878 >      if ( (*i) == atom2 ) return true;
879      }
880  
881      return false;
# Line 836 | Line 905 | namespace OpenMD {
905      idat.excluded = excludeAtomPair(atom1, atom2);
906    
907   #ifdef IS_MPI
908 +    idat.atypes = make_pair( atypesRow[atom1], atypesCol[atom2]);
909 +    //idat.atypes = make_pair( ff_->getAtomType(identsRow[atom1]),
910 +    //                         ff_->getAtomType(identsCol[atom2]) );
911      
840    idat.atypes = make_pair( ff_->getAtomType(identsRow[atom1]),
841                             ff_->getAtomType(identsCol[atom2]) );
842    
912      if (storageLayout_ & DataStorage::dslAmat) {
913        idat.A1 = &(atomRowData.aMat[atom1]);
914        idat.A2 = &(atomColData.aMat[atom2]);
# Line 882 | Line 951 | namespace OpenMD {
951  
952   #else
953  
954 <    idat.atypes = make_pair( ff_->getAtomType(idents[atom1]),
955 <                             ff_->getAtomType(idents[atom2]) );
954 >    idat.atypes = make_pair( atypesLocal[atom1], atypesLocal[atom2]);
955 >    //idat.atypes = make_pair( ff_->getAtomType(idents[atom1]),
956 >    //                         ff_->getAtomType(idents[atom2]) );
957  
958      if (storageLayout_ & DataStorage::dslAmat) {
959        idat.A1 = &(snap_->atomData.aMat[atom1]);
# Line 1021 | Line 1091 | namespace OpenMD {
1091          // add this cutoff group to the list of groups in this cell;
1092          cellListRow_[cellIndex].push_back(i);
1093        }
1024      
1094        for (int i = 0; i < nGroupsInCol_; i++) {
1095          rs = cgColData.position[i];
1096          
# Line 1046 | Line 1115 | namespace OpenMD {
1115          // add this cutoff group to the list of groups in this cell;
1116          cellListCol_[cellIndex].push_back(i);
1117        }
1118 +    
1119   #else
1120        for (int i = 0; i < nGroups_; i++) {
1121          rs = snap_->cgData.position[i];
# Line 1066 | Line 1136 | namespace OpenMD {
1136          whichCell.z() = nCells_.z() * scaled.z();
1137          
1138          // find single index of this cell:
1139 <        cellIndex = Vlinear(whichCell, nCells_);      
1139 >        cellIndex = Vlinear(whichCell, nCells_);
1140          
1141          // add this cutoff group to the list of groups in this cell;
1142          cellList_[cellIndex].push_back(i);
1143        }
1144 +
1145   #endif
1146  
1147        for (int m1z = 0; m1z < nCells_.z(); m1z++) {
# Line 1083 | Line 1154 | namespace OpenMD {
1154                   os != cellOffsets_.end(); ++os) {
1155                
1156                Vector3i m2v = m1v + (*os);
1157 <              
1157 >            
1158 >
1159                if (m2v.x() >= nCells_.x()) {
1160                  m2v.x() = 0;          
1161                } else if (m2v.x() < 0) {
# Line 1101 | Line 1173 | namespace OpenMD {
1173                } else if (m2v.z() < 0) {
1174                  m2v.z() = nCells_.z() - 1;
1175                }
1176 <              
1176 >
1177                int m2 = Vlinear (m2v, nCells_);
1178                
1179   #ifdef IS_MPI
# Line 1110 | Line 1182 | namespace OpenMD {
1182                  for (vector<int>::iterator j2 = cellListCol_[m2].begin();
1183                       j2 != cellListCol_[m2].end(); ++j2) {
1184                    
1185 <                  // Always do this if we're in different cells or if
1186 <                  // we're in the same cell and the global index of the
1187 <                  // j2 cutoff group is less than the j1 cutoff group
1188 <                  
1189 <                  if (m2 != m1 || cgColToGlobal[(*j2)] < cgRowToGlobal[(*j1)]) {
1190 <                    dr = cgColData.position[(*j2)] - cgRowData.position[(*j1)];
1191 <                    snap_->wrapVector(dr);
1192 <                    cuts = getGroupCutoffs( (*j1), (*j2) );
1193 <                    if (dr.lengthSquare() < cuts.third) {
1122 <                      neighborList.push_back(make_pair((*j1), (*j2)));
1123 <                    }
1124 <                  }
1185 >                  // In parallel, we need to visit *all* pairs of row
1186 >                  // & column indicies and will divide labor in the
1187 >                  // force evaluation later.
1188 >                  dr = cgColData.position[(*j2)] - cgRowData.position[(*j1)];
1189 >                  snap_->wrapVector(dr);
1190 >                  cuts = getGroupCutoffs( (*j1), (*j2) );
1191 >                  if (dr.lengthSquare() < cuts.third) {
1192 >                    neighborList.push_back(make_pair((*j1), (*j2)));
1193 >                  }                  
1194                  }
1195                }
1196   #else
1128              
1197                for (vector<int>::iterator j1 = cellList_[m1].begin();
1198                     j1 != cellList_[m1].end(); ++j1) {
1199                  for (vector<int>::iterator j2 = cellList_[m2].begin();
1200                       j2 != cellList_[m2].end(); ++j2) {
1201 <                  
1201 >    
1202                    // Always do this if we're in different cells or if
1203 <                  // we're in the same cell and the global index of the
1204 <                  // j2 cutoff group is less than the j1 cutoff group
1205 <                  
1206 <                  if (m2 != m1 || (*j2) < (*j1)) {
1203 >                  // we're in the same cell and the global index of
1204 >                  // the j2 cutoff group is greater than or equal to
1205 >                  // the j1 cutoff group.  Note that Rappaport's code
1206 >                  // has a "less than" conditional here, but that
1207 >                  // deals with atom-by-atom computation.  OpenMD
1208 >                  // allows atoms within a single cutoff group to
1209 >                  // interact with each other.
1210 >
1211 >
1212 >
1213 >                  if (m2 != m1 || (*j2) >= (*j1) ) {
1214 >
1215                      dr = snap_->cgData.position[(*j2)] - snap_->cgData.position[(*j1)];
1216                      snap_->wrapVector(dr);
1217                      cuts = getGroupCutoffs( (*j1), (*j2) );
# Line 1154 | Line 1230 | namespace OpenMD {
1230        // branch to do all cutoff group pairs
1231   #ifdef IS_MPI
1232        for (int j1 = 0; j1 < nGroupsInRow_; j1++) {
1233 <        for (int j2 = 0; j2 < nGroupsInCol_; j2++) {      
1233 >        for (int j2 = 0; j2 < nGroupsInCol_; j2++) {    
1234            dr = cgColData.position[j2] - cgRowData.position[j1];
1235            snap_->wrapVector(dr);
1236            cuts = getGroupCutoffs( j1, j2 );
# Line 1162 | Line 1238 | namespace OpenMD {
1238              neighborList.push_back(make_pair(j1, j2));
1239            }
1240          }
1241 <      }
1241 >      }      
1242   #else
1243 <      for (int j1 = 0; j1 < nGroups_ - 1; j1++) {
1244 <        for (int j2 = j1 + 1; j2 < nGroups_; j2++) {
1243 >      // include all groups here.
1244 >      for (int j1 = 0; j1 < nGroups_; j1++) {
1245 >        // include self group interactions j2 == j1
1246 >        for (int j2 = j1; j2 < nGroups_; j2++) {
1247            dr = snap_->cgData.position[j2] - snap_->cgData.position[j1];
1248            snap_->wrapVector(dr);
1249            cuts = getGroupCutoffs( j1, j2 );
1250            if (dr.lengthSquare() < cuts.third) {
1251              neighborList.push_back(make_pair(j1, j2));
1252            }
1253 <        }
1254 <      }        
1253 >        }    
1254 >      }
1255   #endif
1256      }
1257        

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines