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 1571 by gezelter, Fri May 27 16:45:44 2011 UTC vs.
Revision 1576 by gezelter, Wed Jun 8 16:05:07 2011 UTC

# Line 69 | Line 69 | namespace OpenMD {
69      PairList oneTwo = info_->getOneTwoInteractions();
70      PairList oneThree = info_->getOneThreeInteractions();
71      PairList oneFour = info_->getOneFourInteractions();
72    vector<RealType> pot_local(N_INTERACTION_FAMILIES, 0.0);
72  
73   #ifdef IS_MPI
74  
# Line 77 | 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 102 | Line 103 | namespace OpenMD {
103      cgRowData.setStorageLayout(DataStorage::dslPosition);
104      cgColData.resize(nGroupsInCol_);
105      cgColData.setStorageLayout(DataStorage::dslPosition);
106 <    
106 <    vector<vector<RealType> > pot_row(N_INTERACTION_FAMILIES,
107 <                                      vector<RealType> (nAtomsInRow_, 0.0));
108 <    vector<vector<RealType> > pot_col(N_INTERACTION_FAMILIES,
109 <                                      vector<RealType> (nAtomsInCol_, 0.0));
110 <    
106 >        
107      identsRow.reserve(nAtomsInRow_);
108      identsCol.reserve(nAtomsInCol_);
109      
# Line 229 | Line 225 | namespace OpenMD {
225            nTopos++;
226          }
227        }      
228 <    }
228 >    }    
229 >
230    }
231    
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 267 | 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 278 | 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 343 | 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  
# Line 462 | Line 714 | namespace OpenMD {
714    }
715  
716    /**
717 <   * there are a number of reasons to skip a pair or a particle mostly
718 <   * we do this to exclude atoms who are involved in short range
719 <   * interactions (bonds, bends, torsions), but we also need to
720 <   * exclude some overcounted interactions that result from the
721 <   * parallel decomposition.
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;
# Line 545 | Line 797 | namespace OpenMD {
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 565 | 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]),
# Line 595 | 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;
# Line 618 | Line 910 | namespace OpenMD {
910        idat.t1 = &(atomRowData.torque[atom1]);
911        idat.t2 = &(atomColData.torque[atom2]);
912      }
621    if (storageLayout_ & DataStorage::dslForce) {
622      idat.t1 = &(atomRowData.force[atom1]);
623      idat.t2 = &(atomColData.force[atom2]);
624    }
913   #else
914      idat.atypes = make_pair( ff_->getAtomType(identsLocal[atom1]),
915                               ff_->getAtomType(identsLocal[atom2]) );
# Line 634 | Line 922 | namespace OpenMD {
922        idat.t1 = &(snap_->atomData.torque[atom1]);
923        idat.t2 = &(snap_->atomData.torque[atom2]);
924      }
637    if (storageLayout_ & DataStorage::dslForce) {
638      idat.t1 = &(snap_->atomData.force[atom1]);
639      idat.t2 = &(snap_->atomData.force[atom2]);
640    }
925   #endif    
926    }
927  
# Line 650 | 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 657 | Line 942 | namespace OpenMD {
942      cellList_.clear();
943   #endif
944  
945 <    // dangerous to not do error checking.
661 <    RealType rCut_;
662 <
663 <    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 739 | Line 1021 | namespace OpenMD {
1021      }
1022   #endif
1023  
742
743
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 785 | 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 804 | 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