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 1569 by gezelter, Thu May 26 13:55:04 2011 UTC vs.
Revision 1576 by gezelter, Wed Jun 8 16:05:07 2011 UTC

# Line 42 | Line 42
42   #include "math/SquareMatrix3.hpp"
43   #include "nonbonded/NonBondedInteraction.hpp"
44   #include "brains/SnapshotManager.hpp"
45 + #include "brains/PairList.hpp"
46  
47   using namespace std;
48   namespace OpenMD {
# Line 54 | Line 55 | namespace OpenMD {
55    void ForceMatrixDecomposition::distributeInitialData() {
56      snap_ = sman_->getCurrentSnapshot();
57      storageLayout_ = sman_->getStorageLayout();
58 +    ff_ = info_->getForceField();
59      nLocal_ = snap_->getNumberOfAtoms();
60      nGroups_ = snap_->getNumberOfCutoffGroups();
61  
62      // gather the information for atomtype IDs (atids):
63 <    vector<int> identsLocal = info_->getIdentArray();
63 >    identsLocal = info_->getIdentArray();
64      AtomLocalToGlobal = info_->getGlobalAtomIndices();
65      cgLocalToGlobal = info_->getGlobalGroupIndices();
66      vector<int> globalGroupMembership = info_->getGlobalGroupMembership();
67      vector<RealType> massFactorsLocal = info_->getMassFactors();
68 <    vector<RealType> pot_local(N_INTERACTION_FAMILIES, 0.0);
68 >    PairList excludes = info_->getExcludedInteractions();
69 >    PairList oneTwo = info_->getOneTwoInteractions();
70 >    PairList oneThree = info_->getOneThreeInteractions();
71 >    PairList oneFour = info_->getOneFourInteractions();
72  
73   #ifdef IS_MPI
74  
# Line 71 | Line 76 | namespace OpenMD {
76      AtomCommRealRow = new Communicator<Row,RealType>(nLocal_);
77      AtomCommVectorRow = new Communicator<Row,Vector3d>(nLocal_);
78      AtomCommMatrixRow = new Communicator<Row,Mat3x3d>(nLocal_);
79 +    AtomCommPotRow = new Communicator<Row,potVec>(nLocal_);
80  
81      AtomCommIntColumn = new Communicator<Column,int>(nLocal_);
82      AtomCommRealColumn = new Communicator<Column,RealType>(nLocal_);
83      AtomCommVectorColumn = new Communicator<Column,Vector3d>(nLocal_);
84      AtomCommMatrixColumn = new Communicator<Column,Mat3x3d>(nLocal_);
85 +    AtomCommPotColumn = new Communicator<Column,potVec>(nLocal_);
86  
87      cgCommIntRow = new Communicator<Row,int>(nGroups_);
88      cgCommVectorRow = new Communicator<Row,Vector3d>(nGroups_);
# Line 96 | Line 103 | namespace OpenMD {
103      cgRowData.setStorageLayout(DataStorage::dslPosition);
104      cgColData.resize(nGroupsInCol_);
105      cgColData.setStorageLayout(DataStorage::dslPosition);
106 <    
100 <    vector<vector<RealType> > pot_row(N_INTERACTION_FAMILIES,
101 <                                      vector<RealType> (nAtomsInRow_, 0.0));
102 <    vector<vector<RealType> > pot_col(N_INTERACTION_FAMILIES,
103 <                                      vector<RealType> (nAtomsInCol_, 0.0));
104 <    
106 >        
107      identsRow.reserve(nAtomsInRow_);
108      identsCol.reserve(nAtomsInCol_);
109      
# Line 139 | Line 141 | namespace OpenMD {
141        }      
142      }
143  
144 +    skipsForRowAtom.clear();
145 +    skipsForRowAtom.reserve(nAtomsInRow_);
146 +    for (int i = 0; i < nAtomsInRow_; i++) {
147 +      int iglob = AtomRowToGlobal[i];
148 +      for (int j = 0; j < nAtomsInCol_; j++) {
149 +        int jglob = AtomColToGlobal[j];        
150 +        if (excludes.hasPair(iglob, jglob))
151 +          skipsForRowAtom[i].push_back(j);      
152 +      }      
153 +    }
154 +
155 +    toposForRowAtom.clear();
156 +    toposForRowAtom.reserve(nAtomsInRow_);
157 +    for (int i = 0; i < nAtomsInRow_; i++) {
158 +      int iglob = AtomRowToGlobal[i];
159 +      int nTopos = 0;
160 +      for (int j = 0; j < nAtomsInCol_; j++) {
161 +        int jglob = AtomColToGlobal[j];        
162 +        if (oneTwo.hasPair(iglob, jglob)) {
163 +          toposForRowAtom[i].push_back(j);
164 +          topoDistRow[i][nTopos] = 1;
165 +          nTopos++;
166 +        }
167 +        if (oneThree.hasPair(iglob, jglob)) {
168 +          toposForRowAtom[i].push_back(j);
169 +          topoDistRow[i][nTopos] = 2;
170 +          nTopos++;
171 +        }
172 +        if (oneFour.hasPair(iglob, jglob)) {
173 +          toposForRowAtom[i].push_back(j);
174 +          topoDistRow[i][nTopos] = 3;
175 +          nTopos++;
176 +        }
177 +      }      
178 +    }
179 +
180   #endif
181  
182      groupList_.clear();
# Line 152 | Line 190 | namespace OpenMD {
190        }      
191      }
192  
193 +    skipsForLocalAtom.clear();
194 +    skipsForLocalAtom.reserve(nLocal_);
195 +
196 +    for (int i = 0; i < nLocal_; i++) {
197 +      int iglob = AtomLocalToGlobal[i];
198 +      for (int j = 0; j < nLocal_; j++) {
199 +        int jglob = AtomLocalToGlobal[j];        
200 +        if (excludes.hasPair(iglob, jglob))
201 +          skipsForLocalAtom[i].push_back(j);      
202 +      }      
203 +    }
204 +
205 +    toposForLocalAtom.clear();
206 +    toposForLocalAtom.reserve(nLocal_);
207 +    for (int i = 0; i < nLocal_; i++) {
208 +      int iglob = AtomLocalToGlobal[i];
209 +      int nTopos = 0;
210 +      for (int j = 0; j < nLocal_; j++) {
211 +        int jglob = AtomLocalToGlobal[j];        
212 +        if (oneTwo.hasPair(iglob, jglob)) {
213 +          toposForLocalAtom[i].push_back(j);
214 +          topoDistLocal[i][nTopos] = 1;
215 +          nTopos++;
216 +        }
217 +        if (oneThree.hasPair(iglob, jglob)) {
218 +          toposForLocalAtom[i].push_back(j);
219 +          topoDistLocal[i][nTopos] = 2;
220 +          nTopos++;
221 +        }
222 +        if (oneFour.hasPair(iglob, jglob)) {
223 +          toposForLocalAtom[i].push_back(j);
224 +          topoDistLocal[i][nTopos] = 3;
225 +          nTopos++;
226 +        }
227 +      }      
228 +    }    
229 +
230 +  }
231    
232 <    // still need:
233 <    // topoDist
234 <    // exclude
232 >  void ForceMatrixDecomposition::createGtypeCutoffMap() {
233 >
234 >    RealType tol = 1e-6;
235 >    RealType rc;
236 >    int atid;
237 >    set<AtomType*> atypes = info_->getSimulatedAtomTypes();
238 >    vector<RealType> atypeCutoff;
239 >    atypeCutoff.reserve( atypes.size() );
240 >
241 >    for (set<AtomType*>::iterator at = atypes.begin(); at != atypes.end(); ++at){
242 >      rc = interactionMan_->getSuggestedCutoffRadius(*at);
243 >      atid = (*at)->getIdent();
244 >      atypeCutoff[atid] = rc;
245 >    }
246 >
247 >    vector<RealType> gTypeCutoffs;
248 >
249 >    // first we do a single loop over the cutoff groups to find the
250 >    // largest cutoff for any atypes present in this group.
251 > #ifdef IS_MPI
252 >    vector<RealType> groupCutoffRow(nGroupsInRow_, 0.0);
253 >    for (int cg1 = 0; cg1 < nGroupsInRow_; cg1++) {
254 >      vector<int> atomListRow = getAtomsInGroupRow(cg1);
255 >      for (vector<int>::iterator ia = atomListRow.begin();
256 >           ia != atomListRow.end(); ++ia) {            
257 >        int atom1 = (*ia);
258 >        atid = identsRow[atom1];
259 >        if (atypeCutoff[atid] > groupCutoffRow[cg1]) {
260 >          groupCutoffRow[cg1] = atypeCutoff[atid];
261 >        }
262 >      }
263 >
264 >      bool gTypeFound = false;
265 >      for (int gt = 0; gt < gTypeCutoffs.size(); gt++) {
266 >        if (abs(groupCutoffRow[cg1] - gTypeCutoffs[gt]) < tol) {
267 >          groupRowToGtype[cg1] = gt;
268 >          gTypeFound = true;
269 >        }
270 >      }
271 >      if (!gTypeFound) {
272 >        gTypeCutoffs.push_back( groupCutoffRow[cg1] );
273 >        groupRowToGtype[cg1] = gTypeCutoffs.size() - 1;
274 >      }
275 >      
276 >    }
277 >    vector<RealType> groupCutoffCol(nGroupsInCol_, 0.0);
278 >    for (int cg2 = 0; cg2 < nGroupsInCol_; cg2++) {
279 >      vector<int> atomListCol = getAtomsInGroupColumn(cg2);
280 >      for (vector<int>::iterator jb = atomListCol.begin();
281 >           jb != atomListCol.end(); ++jb) {            
282 >        int atom2 = (*jb);
283 >        atid = identsCol[atom2];
284 >        if (atypeCutoff[atid] > groupCutoffCol[cg2]) {
285 >          groupCutoffCol[cg2] = atypeCutoff[atid];
286 >        }
287 >      }
288 >      bool gTypeFound = false;
289 >      for (int gt = 0; gt < gTypeCutoffs.size(); gt++) {
290 >        if (abs(groupCutoffCol[cg2] - gTypeCutoffs[gt]) < tol) {
291 >          groupColToGtype[cg2] = gt;
292 >          gTypeFound = true;
293 >        }
294 >      }
295 >      if (!gTypeFound) {
296 >        gTypeCutoffs.push_back( groupCutoffCol[cg2] );
297 >        groupColToGtype[cg2] = gTypeCutoffs.size() - 1;
298 >      }
299 >    }
300 > #else
301 >    vector<RealType> groupCutoff(nGroups_, 0.0);
302 >    for (int cg1 = 0; cg1 < nGroups_; cg1++) {
303 >      groupCutoff[cg1] = 0.0;
304 >      vector<int> atomList = getAtomsInGroupRow(cg1);
305 >      for (vector<int>::iterator ia = atomList.begin();
306 >           ia != atomList.end(); ++ia) {            
307 >        int atom1 = (*ia);
308 >        atid = identsLocal[atom1];
309 >        if (atypeCutoff[atid] > groupCutoff[cg1]) {
310 >          groupCutoff[cg1] = atypeCutoff[atid];
311 >        }
312 >      }
313  
314 +      bool gTypeFound = false;
315 +      for (int gt = 0; gt < gTypeCutoffs.size(); gt++) {
316 +        if (abs(groupCutoff[cg1] - gTypeCutoffs[gt]) < tol) {
317 +          groupToGtype[cg1] = gt;
318 +          gTypeFound = true;
319 +        }
320 +      }
321 +      if (!gTypeFound) {
322 +        gTypeCutoffs.push_back( groupCutoff[cg1] );
323 +        groupToGtype[cg1] = gTypeCutoffs.size() - 1;
324 +      }      
325 +    }
326 + #endif
327 +
328 +    // Now we find the maximum group cutoff value present in the simulation
329 +
330 +    vector<RealType>::iterator groupMaxLoc = max_element(gTypeCutoffs.begin(), gTypeCutoffs.end());
331 +    RealType groupMax = *groupMaxLoc;
332 +
333 + #ifdef IS_MPI
334 +    MPI::COMM_WORLD.Allreduce(&groupMax, &groupMax, 1, MPI::REALTYPE, MPI::MAX);
335 + #endif
336 +    
337 +    RealType tradRcut = groupMax;
338 +
339 +    for (int i = 0; i < gTypeCutoffs.size();  i++) {
340 +      for (int j = 0; j < gTypeCutoffs.size();  j++) {
341 +        
342 +        RealType thisRcut;
343 +        switch(cutoffPolicy_) {
344 +        case TRADITIONAL:
345 +          thisRcut = tradRcut;
346 +        case MIX:
347 +          thisRcut = 0.5 * (gTypeCutoffs[i] + gTypeCutoffs[j]);
348 +        case MAX:
349 +          thisRcut = max(gTypeCutoffs[i], gTypeCutoffs[j]);
350 +        default:
351 +          sprintf(painCave.errMsg,
352 +                  "ForceMatrixDecomposition::createGtypeCutoffMap "
353 +                  "hit an unknown cutoff policy!\n");
354 +          painCave.severity = OPENMD_ERROR;
355 +          painCave.isFatal = 1;
356 +          simError();              
357 +        }
358 +
359 +        pair<int,int> key = make_pair(i,j);
360 +        gTypeCutoffMap[key].first = thisRcut;
361 +
362 +        if (thisRcut > largestRcut_) largestRcut_ = thisRcut;
363 +
364 +        gTypeCutoffMap[key].second = thisRcut*thisRcut;
365 +        
366 +        gTypeCutoffMap[key].third = pow(thisRcut + skinThickness_, 2);
367 +
368 +        // sanity check
369 +        
370 +        if (userChoseCutoff_) {
371 +          if (abs(gTypeCutoffMap[key].first - userCutoff_) > 0.0001) {
372 +            sprintf(painCave.errMsg,
373 +                    "ForceMatrixDecomposition::createGtypeCutoffMap "
374 +                    "user-specified rCut does not match computed group Cutoff\n");
375 +            painCave.severity = OPENMD_ERROR;
376 +            painCave.isFatal = 1;
377 +            simError();            
378 +          }
379 +        }
380 +      }
381 +    }
382    }
383 +
384 +
385 +  groupCutoffs ForceMatrixDecomposition::getGroupCutoffs(int cg1, int cg2) {
386 +    int i, j;
387 +
388 + #ifdef IS_MPI
389 +    i = groupRowToGtype[cg1];
390 +    j = groupColToGtype[cg2];
391 + #else
392 +    i = groupToGtype[cg1];
393 +    j = groupToGtype[cg2];
394 + #endif
395      
396 +    return gTypeCutoffMap[make_pair(i,j)];
397 +  }
398  
399  
400 +  void ForceMatrixDecomposition::zeroWorkArrays() {
401 +
402 +    for (int j = 0; j < N_INTERACTION_FAMILIES; j++) {
403 +      longRangePot_[j] = 0.0;
404 +    }
405 +
406 + #ifdef IS_MPI
407 +    if (storageLayout_ & DataStorage::dslForce) {
408 +      fill(atomRowData.force.begin(), atomRowData.force.end(), V3Zero);
409 +      fill(atomColData.force.begin(), atomColData.force.end(), V3Zero);
410 +    }
411 +
412 +    if (storageLayout_ & DataStorage::dslTorque) {
413 +      fill(atomRowData.torque.begin(), atomRowData.torque.end(), V3Zero);
414 +      fill(atomColData.torque.begin(), atomColData.torque.end(), V3Zero);
415 +    }
416 +    
417 +    fill(pot_row.begin(), pot_row.end(),
418 +         Vector<RealType, N_INTERACTION_FAMILIES> (0.0));
419 +
420 +    fill(pot_col.begin(), pot_col.end(),
421 +         Vector<RealType, N_INTERACTION_FAMILIES> (0.0));
422 +    
423 +    pot_local = Vector<RealType, N_INTERACTION_FAMILIES>(0.0);
424 +
425 +    if (storageLayout_ & DataStorage::dslParticlePot) {    
426 +      fill(atomRowData.particlePot.begin(), atomRowData.particlePot.end(), 0.0);
427 +      fill(atomColData.particlePot.begin(), atomColData.particlePot.end(), 0.0);
428 +    }
429 +
430 +    if (storageLayout_ & DataStorage::dslDensity) {      
431 +      fill(atomRowData.density.begin(), atomRowData.density.end(), 0.0);
432 +      fill(atomColData.density.begin(), atomColData.density.end(), 0.0);
433 +    }
434 +
435 +    if (storageLayout_ & DataStorage::dslFunctional) {  
436 +      fill(atomRowData.functional.begin(), atomRowData.functional.end(), 0.0);
437 +      fill(atomColData.functional.begin(), atomColData.functional.end(), 0.0);
438 +    }
439 +
440 +    if (storageLayout_ & DataStorage::dslFunctionalDerivative) {      
441 +      fill(atomRowData.functionalDerivative.begin(),
442 +           atomRowData.functionalDerivative.end(), 0.0);
443 +      fill(atomColData.functionalDerivative.begin(),
444 +           atomColData.functionalDerivative.end(), 0.0);
445 +    }
446 +
447 + #else
448 +    
449 +    if (storageLayout_ & DataStorage::dslParticlePot) {      
450 +      fill(snap_->atomData.particlePot.begin(),
451 +           snap_->atomData.particlePot.end(), 0.0);
452 +    }
453 +    
454 +    if (storageLayout_ & DataStorage::dslDensity) {      
455 +      fill(snap_->atomData.density.begin(),
456 +           snap_->atomData.density.end(), 0.0);
457 +    }
458 +    if (storageLayout_ & DataStorage::dslFunctional) {
459 +      fill(snap_->atomData.functional.begin(),
460 +           snap_->atomData.functional.end(), 0.0);
461 +    }
462 +    if (storageLayout_ & DataStorage::dslFunctionalDerivative) {      
463 +      fill(snap_->atomData.functionalDerivative.begin(),
464 +           snap_->atomData.functionalDerivative.end(), 0.0);
465 +    }
466 + #endif
467 +    
468 +  }
469 +
470 +
471    void ForceMatrixDecomposition::distributeData()  {
472      snap_ = sman_->getCurrentSnapshot();
473      storageLayout_ = sman_->getStorageLayout();
# Line 196 | Line 503 | namespace OpenMD {
503   #endif      
504    }
505    
506 +  /* collects information obtained during the pre-pair loop onto local
507 +   * data structures.
508 +   */
509    void ForceMatrixDecomposition::collectIntermediateData() {
510      snap_ = sman_->getCurrentSnapshot();
511      storageLayout_ = sman_->getStorageLayout();
# Line 207 | Line 517 | namespace OpenMD {
517                                 snap_->atomData.density);
518        
519        int n = snap_->atomData.density.size();
520 <      std::vector<RealType> rho_tmp(n, 0.0);
520 >      vector<RealType> rho_tmp(n, 0.0);
521        AtomCommRealColumn->scatter(atomColData.density, rho_tmp);
522        for (int i = 0; i < n; i++)
523          snap_->atomData.density[i] += rho_tmp[i];
524      }
525   #endif
526    }
527 <  
527 >
528 >  /*
529 >   * redistributes information obtained during the pre-pair loop out to
530 >   * row and column-indexed data structures
531 >   */
532    void ForceMatrixDecomposition::distributeIntermediateData() {
533      snap_ = sman_->getCurrentSnapshot();
534      storageLayout_ = sman_->getStorageLayout();
# Line 272 | Line 586 | namespace OpenMD {
586      
587      nLocal_ = snap_->getNumberOfAtoms();
588  
589 <    vector<vector<RealType> > pot_temp(N_INTERACTION_FAMILIES,
590 <                                       vector<RealType> (nLocal_, 0.0));
589 >    vector<potVec> pot_temp(nLocal_,
590 >                            Vector<RealType, N_INTERACTION_FAMILIES> (0.0));
591 >
592 >    // scatter/gather pot_row into the members of my column
593 >          
594 >    AtomCommPotRow->scatter(pot_row, pot_temp);
595 >
596 >    for (int ii = 0;  ii < pot_temp.size(); ii++ )
597 >      pot_local += pot_temp[ii];
598      
599 <    for (int i = 0; i < N_INTERACTION_FAMILIES; i++) {
600 <      AtomCommRealRow->scatter(pot_row[i], pot_temp[i]);
601 <      for (int ii = 0;  ii < pot_temp[i].size(); ii++ ) {
602 <        pot_local[i] += pot_temp[i][ii];
603 <      }
604 <    }
599 >    fill(pot_temp.begin(), pot_temp.end(),
600 >         Vector<RealType, N_INTERACTION_FAMILIES> (0.0));
601 >      
602 >    AtomCommPotColumn->scatter(pot_col, pot_temp);    
603 >    
604 >    for (int ii = 0;  ii < pot_temp.size(); ii++ )
605 >      pot_local += pot_temp[ii];
606 >    
607   #endif
608    }
609  
610 +  int ForceMatrixDecomposition::getNAtomsInRow() {  
611 + #ifdef IS_MPI
612 +    return nAtomsInRow_;
613 + #else
614 +    return nLocal_;
615 + #endif
616 +  }
617 +
618    /**
619     * returns the list of atoms belonging to this group.  
620     */
# Line 372 | Line 703 | namespace OpenMD {
703  
704      snap_->wrapVector(d);
705      return d;    
706 +  }
707 +
708 +  vector<int> ForceMatrixDecomposition::getSkipsForRowAtom(int atom1) {
709 + #ifdef IS_MPI
710 +    return skipsForRowAtom[atom1];
711 + #else
712 +    return skipsForLocalAtom[atom1];
713 + #endif
714 +  }
715 +
716 +  /**
717 +   * There are a number of reasons to skip a pair or a
718 +   * particle. Mostly we do this to exclude atoms who are involved in
719 +   * short range interactions (bonds, bends, torsions), but we also
720 +   * need to exclude some overcounted interactions that result from
721 +   * the parallel decomposition.
722 +   */
723 +  bool ForceMatrixDecomposition::skipAtomPair(int atom1, int atom2) {
724 +    int unique_id_1, unique_id_2;
725 +
726 + #ifdef IS_MPI
727 +    // in MPI, we have to look up the unique IDs for each atom
728 +    unique_id_1 = AtomRowToGlobal[atom1];
729 +    unique_id_2 = AtomColToGlobal[atom2];
730 +
731 +    // this situation should only arise in MPI simulations
732 +    if (unique_id_1 == unique_id_2) return true;
733 +    
734 +    // this prevents us from doing the pair on multiple processors
735 +    if (unique_id_1 < unique_id_2) {
736 +      if ((unique_id_1 + unique_id_2) % 2 == 0) return true;
737 +    } else {
738 +      if ((unique_id_1 + unique_id_2) % 2 == 1) return true;
739 +    }
740 + #else
741 +    // in the normal loop, the atom numbers are unique
742 +    unique_id_1 = atom1;
743 +    unique_id_2 = atom2;
744 + #endif
745 +    
746 + #ifdef IS_MPI
747 +    for (vector<int>::iterator i = skipsForRowAtom[atom1].begin();
748 +         i != skipsForRowAtom[atom1].end(); ++i) {
749 +      if ( (*i) == unique_id_2 ) return true;
750 +    }    
751 + #else
752 +    for (vector<int>::iterator i = skipsForLocalAtom[atom1].begin();
753 +         i != skipsForLocalAtom[atom1].end(); ++i) {
754 +      if ( (*i) == unique_id_2 ) return true;
755 +    }    
756 + #endif
757    }
758  
759 +  int ForceMatrixDecomposition::getTopoDistance(int atom1, int atom2) {
760 +    
761 + #ifdef IS_MPI
762 +    for (int i = 0; i < toposForRowAtom[atom1].size(); i++) {
763 +      if ( toposForRowAtom[atom1][i] == atom2 ) return topoDistRow[atom1][i];
764 +    }
765 + #else
766 +    for (int i = 0; i < toposForLocalAtom[atom1].size(); i++) {
767 +      if ( toposForLocalAtom[atom1][i] == atom2 ) return topoDistLocal[atom1][i];
768 +    }
769 + #endif
770 +
771 +    // zero is default for unconnected (i.e. normal) pair interactions
772 +    return 0;
773 +  }
774 +
775    void ForceMatrixDecomposition::addForceToAtomRow(int atom1, Vector3d fg){
776   #ifdef IS_MPI
777      atomRowData.force[atom1] += fg;
# Line 395 | Line 793 | namespace OpenMD {
793      InteractionData idat;
794  
795   #ifdef IS_MPI
796 +    
797 +    idat.atypes = make_pair( ff_->getAtomType(identsRow[atom1]),
798 +                             ff_->getAtomType(identsCol[atom2]) );
799 +
800 +    
801      if (storageLayout_ & DataStorage::dslAmat) {
802        idat.A1 = &(atomRowData.aMat[atom1]);
803        idat.A2 = &(atomColData.aMat[atom2]);
# Line 415 | Line 818 | namespace OpenMD {
818        idat.rho2 = &(atomColData.density[atom2]);
819      }
820  
821 +    if (storageLayout_ & DataStorage::dslFunctional) {
822 +      idat.frho1 = &(atomRowData.functional[atom1]);
823 +      idat.frho2 = &(atomColData.functional[atom2]);
824 +    }
825 +
826      if (storageLayout_ & DataStorage::dslFunctionalDerivative) {
827        idat.dfrho1 = &(atomRowData.functionalDerivative[atom1]);
828        idat.dfrho2 = &(atomColData.functionalDerivative[atom2]);
829      }
830 +
831 +    if (storageLayout_ & DataStorage::dslParticlePot) {
832 +      idat.particlePot1 = &(atomRowData.particlePot[atom1]);
833 +      idat.particlePot2 = &(atomColData.particlePot[atom2]);
834 +    }
835 +
836   #else
837 +
838 +    idat.atypes = make_pair( ff_->getAtomType(identsLocal[atom1]),
839 +                             ff_->getAtomType(identsLocal[atom2]) );
840 +
841      if (storageLayout_ & DataStorage::dslAmat) {
842        idat.A1 = &(snap_->atomData.aMat[atom1]);
843        idat.A2 = &(snap_->atomData.aMat[atom2]);
# Line 440 | Line 858 | namespace OpenMD {
858        idat.rho2 = &(snap_->atomData.density[atom2]);
859      }
860  
861 +    if (storageLayout_ & DataStorage::dslFunctional) {
862 +      idat.frho1 = &(snap_->atomData.functional[atom1]);
863 +      idat.frho2 = &(snap_->atomData.functional[atom2]);
864 +    }
865 +
866      if (storageLayout_ & DataStorage::dslFunctionalDerivative) {
867        idat.dfrho1 = &(snap_->atomData.functionalDerivative[atom1]);
868        idat.dfrho2 = &(snap_->atomData.functionalDerivative[atom2]);
869      }
870 +
871 +    if (storageLayout_ & DataStorage::dslParticlePot) {
872 +      idat.particlePot1 = &(snap_->atomData.particlePot[atom1]);
873 +      idat.particlePot2 = &(snap_->atomData.particlePot[atom2]);
874 +    }
875 +
876   #endif
877      return idat;
878    }
879  
880 +  
881 +  void ForceMatrixDecomposition::unpackInteractionData(InteractionData idat, int atom1, int atom2) {    
882 + #ifdef IS_MPI
883 +    pot_row[atom1] += 0.5 *  *(idat.pot);
884 +    pot_col[atom2] += 0.5 *  *(idat.pot);
885 +
886 +    atomRowData.force[atom1] += *(idat.f1);
887 +    atomColData.force[atom2] -= *(idat.f1);
888 + #else
889 +    longRangePot_ += *(idat.pot);
890 +    
891 +    snap_->atomData.force[atom1] += *(idat.f1);
892 +    snap_->atomData.force[atom2] -= *(idat.f1);
893 + #endif
894 +
895 +  }
896 +
897 +
898    InteractionData ForceMatrixDecomposition::fillSkipData(int atom1, int atom2){
899  
900      InteractionData idat;
901   #ifdef IS_MPI
902 +    idat.atypes = make_pair( ff_->getAtomType(identsRow[atom1]),
903 +                             ff_->getAtomType(identsCol[atom2]) );
904 +
905      if (storageLayout_ & DataStorage::dslElectroFrame) {
906        idat.eFrame1 = &(atomRowData.electroFrame[atom1]);
907        idat.eFrame2 = &(atomColData.electroFrame[atom2]);
# Line 460 | Line 910 | namespace OpenMD {
910        idat.t1 = &(atomRowData.torque[atom1]);
911        idat.t2 = &(atomColData.torque[atom2]);
912      }
463    if (storageLayout_ & DataStorage::dslForce) {
464      idat.t1 = &(atomRowData.force[atom1]);
465      idat.t2 = &(atomColData.force[atom2]);
466    }
913   #else
914 +    idat.atypes = make_pair( ff_->getAtomType(identsLocal[atom1]),
915 +                             ff_->getAtomType(identsLocal[atom2]) );
916 +
917      if (storageLayout_ & DataStorage::dslElectroFrame) {
918        idat.eFrame1 = &(snap_->atomData.electroFrame[atom1]);
919        idat.eFrame2 = &(snap_->atomData.electroFrame[atom2]);
# Line 473 | Line 922 | namespace OpenMD {
922        idat.t1 = &(snap_->atomData.torque[atom1]);
923        idat.t2 = &(snap_->atomData.torque[atom2]);
924      }
925 <    if (storageLayout_ & DataStorage::dslForce) {
477 <      idat.t1 = &(snap_->atomData.force[atom1]);
478 <      idat.t2 = &(snap_->atomData.force[atom2]);
479 <    }
480 < #endif
481 <    
925 > #endif    
926    }
927  
484
485
486
928    /*
929     * buildNeighborList
930     *
# Line 493 | Line 934 | namespace OpenMD {
934    vector<pair<int, int> > ForceMatrixDecomposition::buildNeighborList() {
935        
936      vector<pair<int, int> > neighborList;
937 +    groupCutoffs cuts;
938   #ifdef IS_MPI
939      cellListRow_.clear();
940      cellListCol_.clear();
# Line 500 | Line 942 | namespace OpenMD {
942      cellList_.clear();
943   #endif
944  
945 <    // dangerous to not do error checking.
504 <    RealType rCut_;
505 <
506 <    RealType rList_ = (rCut_ + skinThickness_);
945 >    RealType rList_ = (largestRcut_ + skinThickness_);
946      RealType rl2 = rList_ * rList_;
947      Snapshot* snap_ = sman_->getCurrentSnapshot();
948      Mat3x3d Hmat = snap_->getHmat();
# Line 582 | Line 1021 | namespace OpenMD {
1021      }
1022   #endif
1023  
585
586
1024      for (int m1z = 0; m1z < nCells_.z(); m1z++) {
1025        for (int m1y = 0; m1y < nCells_.y(); m1y++) {
1026          for (int m1x = 0; m1x < nCells_.x(); m1x++) {
# Line 628 | Line 1065 | namespace OpenMD {
1065                  if (m2 != m1 || cgColToGlobal[(*j2)] < cgRowToGlobal[(*j1)]) {
1066                    dr = cgColData.position[(*j2)] - cgRowData.position[(*j1)];
1067                    snap_->wrapVector(dr);
1068 <                  if (dr.lengthSquare() < rl2) {
1068 >                  cuts = getGroupCutoffs( (*j1), (*j2) );
1069 >                  if (dr.lengthSquare() < cuts.third) {
1070                      neighborList.push_back(make_pair((*j1), (*j2)));
1071                    }
1072                  }
# Line 647 | Line 1085 | namespace OpenMD {
1085                  if (m2 != m1 || (*j2) < (*j1)) {
1086                    dr = snap_->cgData.position[(*j2)] - snap_->cgData.position[(*j1)];
1087                    snap_->wrapVector(dr);
1088 <                  if (dr.lengthSquare() < rl2) {
1088 >                  cuts = getGroupCutoffs( (*j1), (*j2) );
1089 >                  if (dr.lengthSquare() < cuts.third) {
1090                      neighborList.push_back(make_pair((*j1), (*j2)));
1091                    }
1092                  }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines