| 57 | 
  | 
    storageLayout_ = sman_->getStorageLayout(); | 
| 58 | 
  | 
    ff_ = info_->getForceField(); | 
| 59 | 
  | 
    nLocal_ = snap_->getNumberOfAtoms(); | 
| 60 | 
< | 
 | 
| 60 | 
> | 
     | 
| 61 | 
  | 
    nGroups_ = info_->getNLocalCutoffGroups(); | 
| 62 | 
– | 
    cerr << "in dId, nGroups = " << nGroups_ << "\n"; | 
| 62 | 
  | 
    // gather the information for atomtype IDs (atids): | 
| 63 | 
  | 
    idents = info_->getIdentArray(); | 
| 64 | 
  | 
    AtomLocalToGlobal = info_->getGlobalAtomIndices(); | 
| 65 | 
  | 
    cgLocalToGlobal = info_->getGlobalGroupIndices(); | 
| 66 | 
  | 
    vector<int> globalGroupMembership = info_->getGlobalGroupMembership(); | 
| 67 | 
+ | 
 | 
| 68 | 
  | 
    massFactors = info_->getMassFactors(); | 
| 69 | 
– | 
    PairList excludes = info_->getExcludedInteractions(); | 
| 70 | 
– | 
    PairList oneTwo = info_->getOneTwoInteractions(); | 
| 71 | 
– | 
    PairList oneThree = info_->getOneThreeInteractions(); | 
| 72 | 
– | 
    PairList oneFour = info_->getOneFourInteractions(); | 
| 69 | 
  | 
 | 
| 70 | 
+ | 
    PairList* excludes = info_->getExcludedInteractions(); | 
| 71 | 
+ | 
    PairList* oneTwo = info_->getOneTwoInteractions(); | 
| 72 | 
+ | 
    PairList* oneThree = info_->getOneThreeInteractions(); | 
| 73 | 
+ | 
    PairList* oneFour = info_->getOneFourInteractions(); | 
| 74 | 
+ | 
 | 
| 75 | 
  | 
#ifdef IS_MPI | 
| 76 | 
  | 
  | 
| 77 | 
  | 
    AtomCommIntRow = new Communicator<Row,int>(nLocal_); | 
| 112 | 
  | 
    AtomCommIntRow->gather(idents, identsRow); | 
| 113 | 
  | 
    AtomCommIntColumn->gather(idents, identsCol); | 
| 114 | 
  | 
     | 
| 115 | 
+ | 
    // allocate memory for the parallel objects | 
| 116 | 
+ | 
    AtomRowToGlobal.resize(nAtomsInRow_); | 
| 117 | 
+ | 
    AtomColToGlobal.resize(nAtomsInCol_); | 
| 118 | 
+ | 
    cgRowToGlobal.resize(nGroupsInRow_); | 
| 119 | 
+ | 
    cgColToGlobal.resize(nGroupsInCol_); | 
| 120 | 
+ | 
    massFactorsRow.resize(nAtomsInRow_); | 
| 121 | 
+ | 
    massFactorsCol.resize(nAtomsInCol_); | 
| 122 | 
+ | 
    pot_row.resize(nAtomsInRow_); | 
| 123 | 
+ | 
    pot_col.resize(nAtomsInCol_); | 
| 124 | 
+ | 
 | 
| 125 | 
  | 
    AtomCommIntRow->gather(AtomLocalToGlobal, AtomRowToGlobal); | 
| 126 | 
  | 
    AtomCommIntColumn->gather(AtomLocalToGlobal, AtomColToGlobal); | 
| 127 | 
  | 
     | 
| 153 | 
  | 
      }       | 
| 154 | 
  | 
    } | 
| 155 | 
  | 
 | 
| 156 | 
< | 
    skipsForAtom.clear(); | 
| 157 | 
< | 
    skipsForAtom.resize(nAtomsInRow_); | 
| 156 | 
> | 
    excludesForAtom.clear(); | 
| 157 | 
> | 
    excludesForAtom.resize(nAtomsInRow_); | 
| 158 | 
  | 
    toposForAtom.clear(); | 
| 159 | 
  | 
    toposForAtom.resize(nAtomsInRow_); | 
| 160 | 
  | 
    topoDist.clear(); | 
| 165 | 
  | 
      for (int j = 0; j < nAtomsInCol_; j++) { | 
| 166 | 
  | 
        int jglob = AtomColToGlobal[j]; | 
| 167 | 
  | 
 | 
| 168 | 
< | 
        if (excludes.hasPair(iglob, jglob))  | 
| 169 | 
< | 
          skipsForAtom[i].push_back(j);        | 
| 168 | 
> | 
        if (excludes->hasPair(iglob, jglob))  | 
| 169 | 
> | 
          excludesForAtom[i].push_back(j);        | 
| 170 | 
  | 
         | 
| 171 | 
< | 
        if (oneTwo.hasPair(iglob, jglob)) { | 
| 171 | 
> | 
        if (oneTwo->hasPair(iglob, jglob)) { | 
| 172 | 
  | 
          toposForAtom[i].push_back(j); | 
| 173 | 
  | 
          topoDist[i].push_back(1); | 
| 174 | 
  | 
        } else { | 
| 175 | 
< | 
          if (oneThree.hasPair(iglob, jglob)) { | 
| 175 | 
> | 
          if (oneThree->hasPair(iglob, jglob)) { | 
| 176 | 
  | 
            toposForAtom[i].push_back(j); | 
| 177 | 
  | 
            topoDist[i].push_back(2); | 
| 178 | 
  | 
          } else { | 
| 179 | 
< | 
            if (oneFour.hasPair(iglob, jglob)) { | 
| 179 | 
> | 
            if (oneFour->hasPair(iglob, jglob)) { | 
| 180 | 
  | 
              toposForAtom[i].push_back(j); | 
| 181 | 
  | 
              topoDist[i].push_back(3); | 
| 182 | 
  | 
            } | 
| 199 | 
  | 
      }       | 
| 200 | 
  | 
    } | 
| 201 | 
  | 
 | 
| 202 | 
< | 
    skipsForAtom.clear(); | 
| 203 | 
< | 
    skipsForAtom.resize(nLocal_); | 
| 202 | 
> | 
    excludesForAtom.clear(); | 
| 203 | 
> | 
    excludesForAtom.resize(nLocal_); | 
| 204 | 
  | 
    toposForAtom.clear(); | 
| 205 | 
  | 
    toposForAtom.resize(nLocal_); | 
| 206 | 
  | 
    topoDist.clear(); | 
| 212 | 
  | 
      for (int j = 0; j < nLocal_; j++) { | 
| 213 | 
  | 
        int jglob = AtomLocalToGlobal[j]; | 
| 214 | 
  | 
 | 
| 215 | 
< | 
        if (excludes.hasPair(iglob, jglob))  | 
| 216 | 
< | 
          skipsForAtom[i].push_back(j);               | 
| 215 | 
> | 
        if (excludes->hasPair(iglob, jglob))  | 
| 216 | 
> | 
          excludesForAtom[i].push_back(j);               | 
| 217 | 
  | 
         | 
| 218 | 
< | 
        if (oneTwo.hasPair(iglob, jglob)) { | 
| 218 | 
> | 
        if (oneTwo->hasPair(iglob, jglob)) { | 
| 219 | 
  | 
          toposForAtom[i].push_back(j); | 
| 220 | 
  | 
          topoDist[i].push_back(1); | 
| 221 | 
  | 
        } else { | 
| 222 | 
< | 
          if (oneThree.hasPair(iglob, jglob)) { | 
| 222 | 
> | 
          if (oneThree->hasPair(iglob, jglob)) { | 
| 223 | 
  | 
            toposForAtom[i].push_back(j); | 
| 224 | 
  | 
            topoDist[i].push_back(2); | 
| 225 | 
  | 
          } else { | 
| 226 | 
< | 
            if (oneFour.hasPair(iglob, jglob)) { | 
| 226 | 
> | 
            if (oneFour->hasPair(iglob, jglob)) { | 
| 227 | 
  | 
              toposForAtom[i].push_back(j); | 
| 228 | 
  | 
              topoDist[i].push_back(3); | 
| 229 | 
  | 
            } | 
| 233 | 
  | 
    } | 
| 234 | 
  | 
     | 
| 235 | 
  | 
    createGtypeCutoffMap(); | 
| 236 | 
+ | 
 | 
| 237 | 
  | 
  } | 
| 238 | 
  | 
    | 
| 239 | 
  | 
  void ForceMatrixDecomposition::createGtypeCutoffMap() { | 
| 240 | 
< | 
 | 
| 240 | 
> | 
     | 
| 241 | 
  | 
    RealType tol = 1e-6; | 
| 242 | 
  | 
    RealType rc; | 
| 243 | 
  | 
    int atid; | 
| 244 | 
  | 
    set<AtomType*> atypes = info_->getSimulatedAtomTypes(); | 
| 245 | 
< | 
    vector<RealType> atypeCutoff; | 
| 234 | 
< | 
    atypeCutoff.resize( atypes.size() ); | 
| 245 | 
> | 
    map<int, RealType> atypeCutoff; | 
| 246 | 
  | 
       | 
| 247 | 
  | 
    for (set<AtomType*>::iterator at = atypes.begin();  | 
| 248 | 
  | 
         at != atypes.end(); ++at){ | 
| 249 | 
  | 
      atid = (*at)->getIdent(); | 
| 250 | 
< | 
 | 
| 240 | 
< | 
      if (userChoseCutoff_) | 
| 250 | 
> | 
      if (userChoseCutoff_)  | 
| 251 | 
  | 
        atypeCutoff[atid] = userCutoff_; | 
| 252 | 
< | 
      else | 
| 252 | 
> | 
      else  | 
| 253 | 
  | 
        atypeCutoff[atid] = interactionMan_->getSuggestedCutoffRadius(*at); | 
| 254 | 
  | 
    } | 
| 255 | 
  | 
 | 
| 256 | 
  | 
    vector<RealType> gTypeCutoffs; | 
| 247 | 
– | 
 | 
| 257 | 
  | 
    // first we do a single loop over the cutoff groups to find the | 
| 258 | 
  | 
    // largest cutoff for any atypes present in this group. | 
| 259 | 
  | 
#ifdef IS_MPI | 
| 311 | 
  | 
 | 
| 312 | 
  | 
    vector<RealType> groupCutoff(nGroups_, 0.0); | 
| 313 | 
  | 
    groupToGtype.resize(nGroups_); | 
| 305 | 
– | 
 | 
| 306 | 
– | 
    cerr << "nGroups = " << nGroups_ << "\n"; | 
| 314 | 
  | 
    for (int cg1 = 0; cg1 < nGroups_; cg1++) { | 
| 315 | 
  | 
 | 
| 316 | 
  | 
      groupCutoff[cg1] = 0.0; | 
| 339 | 
  | 
    } | 
| 340 | 
  | 
#endif | 
| 341 | 
  | 
 | 
| 335 | 
– | 
    cerr << "gTypeCutoffs.size() = " << gTypeCutoffs.size() << "\n"; | 
| 342 | 
  | 
    // Now we find the maximum group cutoff value present in the simulation | 
| 343 | 
  | 
 | 
| 344 | 
  | 
    RealType groupMax = *max_element(gTypeCutoffs.begin(), gTypeCutoffs.end()); | 
| 459 | 
  | 
           atomRowData.functionalDerivative.end(), 0.0); | 
| 460 | 
  | 
      fill(atomColData.functionalDerivative.begin(),  | 
| 461 | 
  | 
           atomColData.functionalDerivative.end(), 0.0); | 
| 462 | 
+ | 
    } | 
| 463 | 
+ | 
 | 
| 464 | 
+ | 
    if (storageLayout_ & DataStorage::dslSkippedCharge) {       | 
| 465 | 
+ | 
      fill(atomRowData.skippedCharge.begin(),  | 
| 466 | 
+ | 
           atomRowData.skippedCharge.end(), 0.0); | 
| 467 | 
+ | 
      fill(atomColData.skippedCharge.begin(),  | 
| 468 | 
+ | 
           atomColData.skippedCharge.end(), 0.0); | 
| 469 | 
  | 
    } | 
| 470 | 
  | 
 | 
| 471 | 
  | 
#else | 
| 487 | 
  | 
      fill(snap_->atomData.functionalDerivative.begin(),  | 
| 488 | 
  | 
           snap_->atomData.functionalDerivative.end(), 0.0); | 
| 489 | 
  | 
    } | 
| 490 | 
+ | 
    if (storageLayout_ & DataStorage::dslSkippedCharge) {       | 
| 491 | 
+ | 
      fill(snap_->atomData.skippedCharge.begin(),  | 
| 492 | 
+ | 
           snap_->atomData.skippedCharge.end(), 0.0); | 
| 493 | 
+ | 
    } | 
| 494 | 
  | 
#endif | 
| 495 | 
  | 
     | 
| 496 | 
  | 
  } | 
| 598 | 
  | 
     | 
| 599 | 
  | 
    if (storageLayout_ & DataStorage::dslTorque) { | 
| 600 | 
  | 
 | 
| 601 | 
< | 
      int nt = snap_->atomData.force.size(); | 
| 601 | 
> | 
      int nt = snap_->atomData.torque.size(); | 
| 602 | 
  | 
      vector<Vector3d> trq_tmp(nt, V3Zero); | 
| 603 | 
  | 
 | 
| 604 | 
  | 
      AtomCommVectorRow->scatter(atomRowData.torque, trq_tmp); | 
| 605 | 
< | 
      for (int i = 0; i < n; i++) { | 
| 605 | 
> | 
      for (int i = 0; i < nt; i++) { | 
| 606 | 
  | 
        snap_->atomData.torque[i] += trq_tmp[i]; | 
| 607 | 
  | 
        trq_tmp[i] = 0.0; | 
| 608 | 
  | 
      } | 
| 609 | 
  | 
       | 
| 610 | 
  | 
      AtomCommVectorColumn->scatter(atomColData.torque, trq_tmp); | 
| 611 | 
< | 
      for (int i = 0; i < n; i++) | 
| 611 | 
> | 
      for (int i = 0; i < nt; i++) | 
| 612 | 
  | 
        snap_->atomData.torque[i] += trq_tmp[i]; | 
| 613 | 
+ | 
    } | 
| 614 | 
+ | 
 | 
| 615 | 
+ | 
    if (storageLayout_ & DataStorage::dslSkippedCharge) { | 
| 616 | 
+ | 
 | 
| 617 | 
+ | 
      int ns = snap_->atomData.skippedCharge.size(); | 
| 618 | 
+ | 
      vector<RealType> skch_tmp(ns, 0.0); | 
| 619 | 
+ | 
 | 
| 620 | 
+ | 
      AtomCommRealRow->scatter(atomRowData.skippedCharge, skch_tmp); | 
| 621 | 
+ | 
      for (int i = 0; i < ns; i++) { | 
| 622 | 
+ | 
        snap_->atomData.skippedCharge[i] = skch_tmp[i]; | 
| 623 | 
+ | 
        skch_tmp[i] = 0.0; | 
| 624 | 
+ | 
      } | 
| 625 | 
+ | 
       | 
| 626 | 
+ | 
      AtomCommRealColumn->scatter(atomColData.skippedCharge, skch_tmp); | 
| 627 | 
+ | 
      for (int i = 0; i < ns; i++) | 
| 628 | 
+ | 
        snap_->atomData.skippedCharge[i] += skch_tmp[i]; | 
| 629 | 
  | 
    } | 
| 630 | 
  | 
     | 
| 631 | 
  | 
    nLocal_ = snap_->getNumberOfAtoms(); | 
| 749 | 
  | 
    return d;     | 
| 750 | 
  | 
  } | 
| 751 | 
  | 
 | 
| 752 | 
< | 
  vector<int> ForceMatrixDecomposition::getSkipsForAtom(int atom1) { | 
| 753 | 
< | 
    return skipsForAtom[atom1]; | 
| 752 | 
> | 
  vector<int> ForceMatrixDecomposition::getExcludesForAtom(int atom1) { | 
| 753 | 
> | 
    return excludesForAtom[atom1]; | 
| 754 | 
  | 
  } | 
| 755 | 
  | 
 | 
| 756 | 
  | 
  /** | 
| 757 | 
< | 
   * There are a number of reasons to skip a pair or a | 
| 725 | 
< | 
   * particle. Mostly we do this to exclude atoms who are involved in | 
| 726 | 
< | 
   * short range interactions (bonds, bends, torsions), but we also | 
| 727 | 
< | 
   * need to exclude some overcounted interactions that result from | 
| 757 | 
> | 
   * We need to exclude some overcounted interactions that result from | 
| 758 | 
  | 
   * the parallel decomposition. | 
| 759 | 
  | 
   */ | 
| 760 | 
  | 
  bool ForceMatrixDecomposition::skipAtomPair(int atom1, int atom2) { | 
| 774 | 
  | 
    } else { | 
| 775 | 
  | 
      if ((unique_id_1 + unique_id_2) % 2 == 1) return true;  | 
| 776 | 
  | 
    } | 
| 777 | 
+ | 
#endif | 
| 778 | 
+ | 
    return false; | 
| 779 | 
+ | 
  } | 
| 780 | 
+ | 
 | 
| 781 | 
+ | 
  /** | 
| 782 | 
+ | 
   * We need to handle the interactions for atoms who are involved in | 
| 783 | 
+ | 
   * the same rigid body as well as some short range interactions | 
| 784 | 
+ | 
   * (bonds, bends, torsions) differently from other interactions. | 
| 785 | 
+ | 
   * We'll still visit the pairwise routines, but with a flag that | 
| 786 | 
+ | 
   * tells those routines to exclude the pair from direct long range | 
| 787 | 
+ | 
   * interactions.  Some indirect interactions (notably reaction | 
| 788 | 
+ | 
   * field) must still be handled for these pairs. | 
| 789 | 
+ | 
   */ | 
| 790 | 
+ | 
  bool ForceMatrixDecomposition::excludeAtomPair(int atom1, int atom2) { | 
| 791 | 
+ | 
    int unique_id_2; | 
| 792 | 
+ | 
     | 
| 793 | 
+ | 
#ifdef IS_MPI | 
| 794 | 
+ | 
    // in MPI, we have to look up the unique IDs for the row atom. | 
| 795 | 
+ | 
    unique_id_2 = AtomColToGlobal[atom2]; | 
| 796 | 
  | 
#else | 
| 797 | 
  | 
    // in the normal loop, the atom numbers are unique | 
| 749 | 
– | 
    unique_id_1 = atom1; | 
| 798 | 
  | 
    unique_id_2 = atom2; | 
| 799 | 
  | 
#endif | 
| 800 | 
  | 
     | 
| 801 | 
< | 
    for (vector<int>::iterator i = skipsForAtom[atom1].begin(); | 
| 802 | 
< | 
         i != skipsForAtom[atom1].end(); ++i) { | 
| 801 | 
> | 
    for (vector<int>::iterator i = excludesForAtom[atom1].begin(); | 
| 802 | 
> | 
         i != excludesForAtom[atom1].end(); ++i) { | 
| 803 | 
  | 
      if ( (*i) == unique_id_2 ) return true; | 
| 804 | 
  | 
    } | 
| 805 | 
  | 
 | 
| 825 | 
  | 
 | 
| 826 | 
  | 
    // filling interaction blocks with pointers | 
| 827 | 
  | 
  void ForceMatrixDecomposition::fillInteractionData(InteractionData &idat,  | 
| 828 | 
< | 
                                                     int atom1, int atom2) {     | 
| 828 | 
> | 
                                                     int atom1, int atom2) { | 
| 829 | 
> | 
 | 
| 830 | 
> | 
    idat.excluded = excludeAtomPair(atom1, atom2); | 
| 831 | 
> | 
    | 
| 832 | 
  | 
#ifdef IS_MPI | 
| 833 | 
  | 
     | 
| 834 | 
  | 
    idat.atypes = make_pair( ff_->getAtomType(identsRow[atom1]),  | 
| 869 | 
  | 
      idat.particlePot2 = &(atomColData.particlePot[atom2]); | 
| 870 | 
  | 
    } | 
| 871 | 
  | 
 | 
| 872 | 
+ | 
    if (storageLayout_ & DataStorage::dslSkippedCharge) {               | 
| 873 | 
+ | 
      idat.skippedCharge1 = &(atomRowData.skippedCharge[atom1]); | 
| 874 | 
+ | 
      idat.skippedCharge2 = &(atomColData.skippedCharge[atom2]); | 
| 875 | 
+ | 
    } | 
| 876 | 
+ | 
 | 
| 877 | 
  | 
#else | 
| 878 | 
  | 
 | 
| 879 | 
  | 
    idat.atypes = make_pair( ff_->getAtomType(idents[atom1]),  | 
| 914 | 
  | 
      idat.particlePot2 = &(snap_->atomData.particlePot[atom2]); | 
| 915 | 
  | 
    } | 
| 916 | 
  | 
 | 
| 917 | 
+ | 
    if (storageLayout_ & DataStorage::dslSkippedCharge) { | 
| 918 | 
+ | 
      idat.skippedCharge1 = &(snap_->atomData.skippedCharge[atom1]); | 
| 919 | 
+ | 
      idat.skippedCharge2 = &(snap_->atomData.skippedCharge[atom2]); | 
| 920 | 
+ | 
    } | 
| 921 | 
  | 
#endif | 
| 922 | 
  | 
  } | 
| 923 | 
  | 
 | 
| 935 | 
  | 
    snap_->atomData.force[atom1] += *(idat.f1); | 
| 936 | 
  | 
    snap_->atomData.force[atom2] -= *(idat.f1); | 
| 937 | 
  | 
#endif | 
| 938 | 
< | 
 | 
| 938 | 
> | 
     | 
| 939 | 
  | 
  } | 
| 940 | 
  | 
 | 
| 881 | 
– | 
 | 
| 882 | 
– | 
  void ForceMatrixDecomposition::fillSkipData(InteractionData &idat, | 
| 883 | 
– | 
                                              int atom1, int atom2) { | 
| 884 | 
– | 
    // Still Missing:: skippedCharge fill must be added to DataStorage | 
| 885 | 
– | 
#ifdef IS_MPI | 
| 886 | 
– | 
    idat.atypes = make_pair( ff_->getAtomType(identsRow[atom1]),  | 
| 887 | 
– | 
                             ff_->getAtomType(identsCol[atom2]) ); | 
| 888 | 
– | 
 | 
| 889 | 
– | 
    if (storageLayout_ & DataStorage::dslElectroFrame) { | 
| 890 | 
– | 
      idat.eFrame1 = &(atomRowData.electroFrame[atom1]); | 
| 891 | 
– | 
      idat.eFrame2 = &(atomColData.electroFrame[atom2]); | 
| 892 | 
– | 
    } | 
| 893 | 
– | 
    if (storageLayout_ & DataStorage::dslTorque) { | 
| 894 | 
– | 
      idat.t1 = &(atomRowData.torque[atom1]); | 
| 895 | 
– | 
      idat.t2 = &(atomColData.torque[atom2]); | 
| 896 | 
– | 
    } | 
| 897 | 
– | 
#else | 
| 898 | 
– | 
    idat.atypes = make_pair( ff_->getAtomType(idents[atom1]),  | 
| 899 | 
– | 
                             ff_->getAtomType(idents[atom2]) ); | 
| 900 | 
– | 
 | 
| 901 | 
– | 
    if (storageLayout_ & DataStorage::dslElectroFrame) { | 
| 902 | 
– | 
      idat.eFrame1 = &(snap_->atomData.electroFrame[atom1]); | 
| 903 | 
– | 
      idat.eFrame2 = &(snap_->atomData.electroFrame[atom2]); | 
| 904 | 
– | 
    } | 
| 905 | 
– | 
    if (storageLayout_ & DataStorage::dslTorque) { | 
| 906 | 
– | 
      idat.t1 = &(snap_->atomData.torque[atom1]); | 
| 907 | 
– | 
      idat.t2 = &(snap_->atomData.torque[atom2]); | 
| 908 | 
– | 
    } | 
| 909 | 
– | 
#endif     | 
| 910 | 
– | 
  } | 
| 911 | 
– | 
 | 
| 912 | 
– | 
 | 
| 913 | 
– | 
  void ForceMatrixDecomposition::unpackSkipData(InteractionData &idat, int atom1, int atom2) {     | 
| 914 | 
– | 
#ifdef IS_MPI | 
| 915 | 
– | 
    pot_row[atom1] += 0.5 *  *(idat.pot); | 
| 916 | 
– | 
    pot_col[atom2] += 0.5 *  *(idat.pot); | 
| 917 | 
– | 
#else | 
| 918 | 
– | 
    pairwisePot += *(idat.pot);    | 
| 919 | 
– | 
#endif | 
| 920 | 
– | 
 | 
| 921 | 
– | 
  } | 
| 922 | 
– | 
 | 
| 923 | 
– | 
 | 
| 941 | 
  | 
  /* | 
| 942 | 
  | 
   * buildNeighborList | 
| 943 | 
  | 
   * | 
| 948 | 
  | 
       | 
| 949 | 
  | 
    vector<pair<int, int> > neighborList; | 
| 950 | 
  | 
    groupCutoffs cuts; | 
| 951 | 
+ | 
    bool doAllPairs = false; | 
| 952 | 
+ | 
 | 
| 953 | 
  | 
#ifdef IS_MPI | 
| 954 | 
  | 
    cellListRow_.clear(); | 
| 955 | 
  | 
    cellListCol_.clear(); | 
| 969 | 
  | 
    nCells_.y() = (int) ( Hy.length() )/ rList_; | 
| 970 | 
  | 
    nCells_.z() = (int) ( Hz.length() )/ rList_; | 
| 971 | 
  | 
 | 
| 972 | 
+ | 
    // handle small boxes where the cell offsets can end up repeating cells | 
| 973 | 
+ | 
     | 
| 974 | 
+ | 
    if (nCells_.x() < 3) doAllPairs = true; | 
| 975 | 
+ | 
    if (nCells_.y() < 3) doAllPairs = true; | 
| 976 | 
+ | 
    if (nCells_.z() < 3) doAllPairs = true; | 
| 977 | 
+ | 
 | 
| 978 | 
  | 
    Mat3x3d invHmat = snap_->getInvHmat(); | 
| 979 | 
  | 
    Vector3d rs, scaled, dr; | 
| 980 | 
  | 
    Vector3i whichCell; | 
| 988 | 
  | 
    cellList_.resize(nCtot); | 
| 989 | 
  | 
#endif | 
| 990 | 
  | 
 | 
| 991 | 
+ | 
    if (!doAllPairs) { | 
| 992 | 
  | 
#ifdef IS_MPI | 
| 967 | 
– | 
    for (int i = 0; i < nGroupsInRow_; i++) { | 
| 968 | 
– | 
      rs = cgRowData.position[i]; | 
| 993 | 
  | 
 | 
| 994 | 
< | 
      // scaled positions relative to the box vectors | 
| 995 | 
< | 
      scaled = invHmat * rs; | 
| 996 | 
< | 
 | 
| 997 | 
< | 
      // wrap the vector back into the unit box by subtracting integer box  | 
| 998 | 
< | 
      // numbers | 
| 999 | 
< | 
      for (int j = 0; j < 3; j++) { | 
| 1000 | 
< | 
        scaled[j] -= roundMe(scaled[j]); | 
| 1001 | 
< | 
        scaled[j] += 0.5; | 
| 1002 | 
< | 
      } | 
| 1003 | 
< | 
      | 
| 1004 | 
< | 
      // find xyz-indices of cell that cutoffGroup is in. | 
| 1005 | 
< | 
      whichCell.x() = nCells_.x() * scaled.x(); | 
| 1006 | 
< | 
      whichCell.y() = nCells_.y() * scaled.y(); | 
| 1007 | 
< | 
      whichCell.z() = nCells_.z() * scaled.z(); | 
| 1008 | 
< | 
 | 
| 1009 | 
< | 
      // find single index of this cell: | 
| 1010 | 
< | 
      cellIndex = Vlinear(whichCell, nCells_); | 
| 1011 | 
< | 
 | 
| 1012 | 
< | 
      // add this cutoff group to the list of groups in this cell; | 
| 1013 | 
< | 
      cellListRow_[cellIndex].push_back(i); | 
| 1014 | 
< | 
    } | 
| 1015 | 
< | 
 | 
| 1016 | 
< | 
    for (int i = 0; i < nGroupsInCol_; i++) { | 
| 1017 | 
< | 
      rs = cgColData.position[i]; | 
| 1018 | 
< | 
 | 
| 1019 | 
< | 
      // scaled positions relative to the box vectors | 
| 1020 | 
< | 
      scaled = invHmat * rs; | 
| 1021 | 
< | 
 | 
| 1022 | 
< | 
      // wrap the vector back into the unit box by subtracting integer box  | 
| 1023 | 
< | 
      // numbers | 
| 1024 | 
< | 
      for (int j = 0; j < 3; j++) { | 
| 1025 | 
< | 
        scaled[j] -= roundMe(scaled[j]); | 
| 1026 | 
< | 
        scaled[j] += 0.5; | 
| 1027 | 
< | 
      } | 
| 1028 | 
< | 
 | 
| 1029 | 
< | 
      // find xyz-indices of cell that cutoffGroup is in. | 
| 1030 | 
< | 
      whichCell.x() = nCells_.x() * scaled.x(); | 
| 1031 | 
< | 
      whichCell.y() = nCells_.y() * scaled.y(); | 
| 1032 | 
< | 
      whichCell.z() = nCells_.z() * scaled.z(); | 
| 1033 | 
< | 
 | 
| 1034 | 
< | 
      // find single index of this cell: | 
| 1035 | 
< | 
      cellIndex = Vlinear(whichCell, nCells_); | 
| 1036 | 
< | 
 | 
| 1037 | 
< | 
      // add this cutoff group to the list of groups in this cell; | 
| 1038 | 
< | 
      cellListCol_[cellIndex].push_back(i); | 
| 1039 | 
< | 
    } | 
| 994 | 
> | 
      for (int i = 0; i < nGroupsInRow_; i++) { | 
| 995 | 
> | 
        rs = cgRowData.position[i]; | 
| 996 | 
> | 
         | 
| 997 | 
> | 
        // scaled positions relative to the box vectors | 
| 998 | 
> | 
        scaled = invHmat * rs; | 
| 999 | 
> | 
         | 
| 1000 | 
> | 
        // wrap the vector back into the unit box by subtracting integer box  | 
| 1001 | 
> | 
        // numbers | 
| 1002 | 
> | 
        for (int j = 0; j < 3; j++) { | 
| 1003 | 
> | 
          scaled[j] -= roundMe(scaled[j]); | 
| 1004 | 
> | 
          scaled[j] += 0.5; | 
| 1005 | 
> | 
        } | 
| 1006 | 
> | 
         | 
| 1007 | 
> | 
        // find xyz-indices of cell that cutoffGroup is in. | 
| 1008 | 
> | 
        whichCell.x() = nCells_.x() * scaled.x(); | 
| 1009 | 
> | 
        whichCell.y() = nCells_.y() * scaled.y(); | 
| 1010 | 
> | 
        whichCell.z() = nCells_.z() * scaled.z(); | 
| 1011 | 
> | 
         | 
| 1012 | 
> | 
        // find single index of this cell: | 
| 1013 | 
> | 
        cellIndex = Vlinear(whichCell, nCells_); | 
| 1014 | 
> | 
         | 
| 1015 | 
> | 
        // add this cutoff group to the list of groups in this cell; | 
| 1016 | 
> | 
        cellListRow_[cellIndex].push_back(i); | 
| 1017 | 
> | 
      } | 
| 1018 | 
> | 
       | 
| 1019 | 
> | 
      for (int i = 0; i < nGroupsInCol_; i++) { | 
| 1020 | 
> | 
        rs = cgColData.position[i]; | 
| 1021 | 
> | 
         | 
| 1022 | 
> | 
        // scaled positions relative to the box vectors | 
| 1023 | 
> | 
        scaled = invHmat * rs; | 
| 1024 | 
> | 
         | 
| 1025 | 
> | 
        // wrap the vector back into the unit box by subtracting integer box  | 
| 1026 | 
> | 
        // numbers | 
| 1027 | 
> | 
        for (int j = 0; j < 3; j++) { | 
| 1028 | 
> | 
          scaled[j] -= roundMe(scaled[j]); | 
| 1029 | 
> | 
          scaled[j] += 0.5; | 
| 1030 | 
> | 
        } | 
| 1031 | 
> | 
         | 
| 1032 | 
> | 
        // find xyz-indices of cell that cutoffGroup is in. | 
| 1033 | 
> | 
        whichCell.x() = nCells_.x() * scaled.x(); | 
| 1034 | 
> | 
        whichCell.y() = nCells_.y() * scaled.y(); | 
| 1035 | 
> | 
        whichCell.z() = nCells_.z() * scaled.z(); | 
| 1036 | 
> | 
         | 
| 1037 | 
> | 
        // find single index of this cell: | 
| 1038 | 
> | 
        cellIndex = Vlinear(whichCell, nCells_); | 
| 1039 | 
> | 
         | 
| 1040 | 
> | 
        // add this cutoff group to the list of groups in this cell; | 
| 1041 | 
> | 
        cellListCol_[cellIndex].push_back(i); | 
| 1042 | 
> | 
      } | 
| 1043 | 
  | 
#else | 
| 1044 | 
< | 
    for (int i = 0; i < nGroups_; i++) { | 
| 1045 | 
< | 
      rs = snap_->cgData.position[i]; | 
| 1046 | 
< | 
 | 
| 1047 | 
< | 
      // scaled positions relative to the box vectors | 
| 1048 | 
< | 
      scaled = invHmat * rs; | 
| 1049 | 
< | 
 | 
| 1050 | 
< | 
      // wrap the vector back into the unit box by subtracting integer box  | 
| 1051 | 
< | 
      // numbers | 
| 1052 | 
< | 
      for (int j = 0; j < 3; j++) { | 
| 1053 | 
< | 
        scaled[j] -= roundMe(scaled[j]); | 
| 1054 | 
< | 
        scaled[j] += 0.5; | 
| 1044 | 
> | 
      for (int i = 0; i < nGroups_; i++) { | 
| 1045 | 
> | 
        rs = snap_->cgData.position[i]; | 
| 1046 | 
> | 
         | 
| 1047 | 
> | 
        // scaled positions relative to the box vectors | 
| 1048 | 
> | 
        scaled = invHmat * rs; | 
| 1049 | 
> | 
         | 
| 1050 | 
> | 
        // wrap the vector back into the unit box by subtracting integer box  | 
| 1051 | 
> | 
        // numbers | 
| 1052 | 
> | 
        for (int j = 0; j < 3; j++) { | 
| 1053 | 
> | 
          scaled[j] -= roundMe(scaled[j]); | 
| 1054 | 
> | 
          scaled[j] += 0.5; | 
| 1055 | 
> | 
        } | 
| 1056 | 
> | 
         | 
| 1057 | 
> | 
        // find xyz-indices of cell that cutoffGroup is in. | 
| 1058 | 
> | 
        whichCell.x() = nCells_.x() * scaled.x(); | 
| 1059 | 
> | 
        whichCell.y() = nCells_.y() * scaled.y(); | 
| 1060 | 
> | 
        whichCell.z() = nCells_.z() * scaled.z(); | 
| 1061 | 
> | 
         | 
| 1062 | 
> | 
        // find single index of this cell: | 
| 1063 | 
> | 
        cellIndex = Vlinear(whichCell, nCells_);       | 
| 1064 | 
> | 
         | 
| 1065 | 
> | 
        // add this cutoff group to the list of groups in this cell; | 
| 1066 | 
> | 
        cellList_[cellIndex].push_back(i); | 
| 1067 | 
  | 
      } | 
| 1029 | 
– | 
 | 
| 1030 | 
– | 
      // find xyz-indices of cell that cutoffGroup is in. | 
| 1031 | 
– | 
      whichCell.x() = nCells_.x() * scaled.x(); | 
| 1032 | 
– | 
      whichCell.y() = nCells_.y() * scaled.y(); | 
| 1033 | 
– | 
      whichCell.z() = nCells_.z() * scaled.z(); | 
| 1034 | 
– | 
 | 
| 1035 | 
– | 
      // find single index of this cell: | 
| 1036 | 
– | 
      cellIndex = Vlinear(whichCell, nCells_);       | 
| 1037 | 
– | 
 | 
| 1038 | 
– | 
      // add this cutoff group to the list of groups in this cell; | 
| 1039 | 
– | 
      cellList_[cellIndex].push_back(i); | 
| 1040 | 
– | 
    } | 
| 1068 | 
  | 
#endif | 
| 1069 | 
  | 
 | 
| 1070 | 
< | 
    for (int m1z = 0; m1z < nCells_.z(); m1z++) { | 
| 1071 | 
< | 
      for (int m1y = 0; m1y < nCells_.y(); m1y++) { | 
| 1072 | 
< | 
        for (int m1x = 0; m1x < nCells_.x(); m1x++) { | 
| 1073 | 
< | 
          Vector3i m1v(m1x, m1y, m1z); | 
| 1074 | 
< | 
          int m1 = Vlinear(m1v, nCells_); | 
| 1048 | 
< | 
 | 
| 1049 | 
< | 
          for (vector<Vector3i>::iterator os = cellOffsets_.begin(); | 
| 1050 | 
< | 
               os != cellOffsets_.end(); ++os) { | 
| 1070 | 
> | 
      for (int m1z = 0; m1z < nCells_.z(); m1z++) { | 
| 1071 | 
> | 
        for (int m1y = 0; m1y < nCells_.y(); m1y++) { | 
| 1072 | 
> | 
          for (int m1x = 0; m1x < nCells_.x(); m1x++) { | 
| 1073 | 
> | 
            Vector3i m1v(m1x, m1y, m1z); | 
| 1074 | 
> | 
            int m1 = Vlinear(m1v, nCells_); | 
| 1075 | 
  | 
             | 
| 1076 | 
< | 
            Vector3i m2v = m1v + (*os); | 
| 1077 | 
< | 
             | 
| 1078 | 
< | 
            if (m2v.x() >= nCells_.x()) { | 
| 1079 | 
< | 
              m2v.x() = 0;            | 
| 1080 | 
< | 
            } else if (m2v.x() < 0) { | 
| 1081 | 
< | 
              m2v.x() = nCells_.x() - 1;  | 
| 1082 | 
< | 
            } | 
| 1083 | 
< | 
             | 
| 1084 | 
< | 
            if (m2v.y() >= nCells_.y()) { | 
| 1085 | 
< | 
              m2v.y() = 0;            | 
| 1086 | 
< | 
            } else if (m2v.y() < 0) { | 
| 1087 | 
< | 
              m2v.y() = nCells_.y() - 1;  | 
| 1088 | 
< | 
            } | 
| 1089 | 
< | 
             | 
| 1090 | 
< | 
            if (m2v.z() >= nCells_.z()) { | 
| 1091 | 
< | 
              m2v.z() = 0;            | 
| 1092 | 
< | 
            } else if (m2v.z() < 0) { | 
| 1093 | 
< | 
              m2v.z() = nCells_.z() - 1;  | 
| 1094 | 
< | 
            } | 
| 1095 | 
< | 
             | 
| 1096 | 
< | 
            int m2 = Vlinear (m2v, nCells_); | 
| 1097 | 
< | 
 | 
| 1076 | 
> | 
            for (vector<Vector3i>::iterator os = cellOffsets_.begin(); | 
| 1077 | 
> | 
                 os != cellOffsets_.end(); ++os) { | 
| 1078 | 
> | 
               | 
| 1079 | 
> | 
              Vector3i m2v = m1v + (*os); | 
| 1080 | 
> | 
               | 
| 1081 | 
> | 
              if (m2v.x() >= nCells_.x()) { | 
| 1082 | 
> | 
                m2v.x() = 0;            | 
| 1083 | 
> | 
              } else if (m2v.x() < 0) { | 
| 1084 | 
> | 
                m2v.x() = nCells_.x() - 1;  | 
| 1085 | 
> | 
              } | 
| 1086 | 
> | 
               | 
| 1087 | 
> | 
              if (m2v.y() >= nCells_.y()) { | 
| 1088 | 
> | 
                m2v.y() = 0;            | 
| 1089 | 
> | 
              } else if (m2v.y() < 0) { | 
| 1090 | 
> | 
                m2v.y() = nCells_.y() - 1;  | 
| 1091 | 
> | 
              } | 
| 1092 | 
> | 
               | 
| 1093 | 
> | 
              if (m2v.z() >= nCells_.z()) { | 
| 1094 | 
> | 
                m2v.z() = 0;            | 
| 1095 | 
> | 
              } else if (m2v.z() < 0) { | 
| 1096 | 
> | 
                m2v.z() = nCells_.z() - 1;  | 
| 1097 | 
> | 
              } | 
| 1098 | 
> | 
               | 
| 1099 | 
> | 
              int m2 = Vlinear (m2v, nCells_); | 
| 1100 | 
> | 
               | 
| 1101 | 
  | 
#ifdef IS_MPI | 
| 1102 | 
< | 
            for (vector<int>::iterator j1 = cellListRow_[m1].begin();  | 
| 1103 | 
< | 
                 j1 != cellListRow_[m1].end(); ++j1) { | 
| 1104 | 
< | 
              for (vector<int>::iterator j2 = cellListCol_[m2].begin();  | 
| 1105 | 
< | 
                   j2 != cellListCol_[m2].end(); ++j2) { | 
| 1106 | 
< | 
                                | 
| 1107 | 
< | 
                // Always do this if we're in different cells or if | 
| 1108 | 
< | 
                // we're in the same cell and the global index of the | 
| 1109 | 
< | 
                // j2 cutoff group is less than the j1 cutoff group | 
| 1110 | 
< | 
 | 
| 1111 | 
< | 
                if (m2 != m1 || cgColToGlobal[(*j2)] < cgRowToGlobal[(*j1)]) { | 
| 1112 | 
< | 
                  dr = cgColData.position[(*j2)] - cgRowData.position[(*j1)]; | 
| 1113 | 
< | 
                  snap_->wrapVector(dr); | 
| 1114 | 
< | 
                  cuts = getGroupCutoffs( (*j1), (*j2) ); | 
| 1115 | 
< | 
                  if (dr.lengthSquare() < cuts.third) { | 
| 1116 | 
< | 
                    neighborList.push_back(make_pair((*j1), (*j2))); | 
| 1102 | 
> | 
              for (vector<int>::iterator j1 = cellListRow_[m1].begin();  | 
| 1103 | 
> | 
                   j1 != cellListRow_[m1].end(); ++j1) { | 
| 1104 | 
> | 
                for (vector<int>::iterator j2 = cellListCol_[m2].begin();  | 
| 1105 | 
> | 
                     j2 != cellListCol_[m2].end(); ++j2) { | 
| 1106 | 
> | 
                   | 
| 1107 | 
> | 
                  // Always do this if we're in different cells or if | 
| 1108 | 
> | 
                  // we're in the same cell and the global index of the | 
| 1109 | 
> | 
                  // j2 cutoff group is less than the j1 cutoff group | 
| 1110 | 
> | 
                   | 
| 1111 | 
> | 
                  if (m2 != m1 || cgColToGlobal[(*j2)] < cgRowToGlobal[(*j1)]) { | 
| 1112 | 
> | 
                    dr = cgColData.position[(*j2)] - cgRowData.position[(*j1)]; | 
| 1113 | 
> | 
                    snap_->wrapVector(dr); | 
| 1114 | 
> | 
                    cuts = getGroupCutoffs( (*j1), (*j2) ); | 
| 1115 | 
> | 
                    if (dr.lengthSquare() < cuts.third) { | 
| 1116 | 
> | 
                      neighborList.push_back(make_pair((*j1), (*j2))); | 
| 1117 | 
> | 
                    } | 
| 1118 | 
  | 
                  } | 
| 1119 | 
  | 
                } | 
| 1120 | 
  | 
              } | 
| 1093 | 
– | 
            } | 
| 1121 | 
  | 
#else | 
| 1122 | 
< | 
 | 
| 1123 | 
< | 
            for (vector<int>::iterator j1 = cellList_[m1].begin();  | 
| 1124 | 
< | 
                 j1 != cellList_[m1].end(); ++j1) { | 
| 1125 | 
< | 
              for (vector<int>::iterator j2 = cellList_[m2].begin();  | 
| 1126 | 
< | 
                   j2 != cellList_[m2].end(); ++j2) { | 
| 1127 | 
< | 
 | 
| 1128 | 
< | 
                // Always do this if we're in different cells or if | 
| 1129 | 
< | 
                // we're in the same cell and the global index of the | 
| 1130 | 
< | 
                // j2 cutoff group is less than the j1 cutoff group | 
| 1131 | 
< | 
 | 
| 1132 | 
< | 
                if (m2 != m1 || (*j2) < (*j1)) { | 
| 1133 | 
< | 
                  dr = snap_->cgData.position[(*j2)] - snap_->cgData.position[(*j1)]; | 
| 1134 | 
< | 
                  snap_->wrapVector(dr); | 
| 1135 | 
< | 
                  cuts = getGroupCutoffs( (*j1), (*j2) ); | 
| 1136 | 
< | 
                  if (dr.lengthSquare() < cuts.third) { | 
| 1137 | 
< | 
                    neighborList.push_back(make_pair((*j1), (*j2))); | 
| 1122 | 
> | 
               | 
| 1123 | 
> | 
              for (vector<int>::iterator j1 = cellList_[m1].begin();  | 
| 1124 | 
> | 
                   j1 != cellList_[m1].end(); ++j1) { | 
| 1125 | 
> | 
                for (vector<int>::iterator j2 = cellList_[m2].begin();  | 
| 1126 | 
> | 
                     j2 != cellList_[m2].end(); ++j2) { | 
| 1127 | 
> | 
                   | 
| 1128 | 
> | 
                  // Always do this if we're in different cells or if | 
| 1129 | 
> | 
                  // we're in the same cell and the global index of the | 
| 1130 | 
> | 
                  // j2 cutoff group is less than the j1 cutoff group | 
| 1131 | 
> | 
                   | 
| 1132 | 
> | 
                  if (m2 != m1 || (*j2) < (*j1)) { | 
| 1133 | 
> | 
                    dr = snap_->cgData.position[(*j2)] - snap_->cgData.position[(*j1)]; | 
| 1134 | 
> | 
                    snap_->wrapVector(dr); | 
| 1135 | 
> | 
                    cuts = getGroupCutoffs( (*j1), (*j2) ); | 
| 1136 | 
> | 
                    if (dr.lengthSquare() < cuts.third) { | 
| 1137 | 
> | 
                      neighborList.push_back(make_pair((*j1), (*j2))); | 
| 1138 | 
> | 
                    } | 
| 1139 | 
  | 
                  } | 
| 1140 | 
  | 
                } | 
| 1141 | 
  | 
              } | 
| 1114 | 
– | 
            } | 
| 1142 | 
  | 
#endif | 
| 1143 | 
+ | 
            } | 
| 1144 | 
  | 
          } | 
| 1145 | 
  | 
        } | 
| 1146 | 
  | 
      } | 
| 1147 | 
+ | 
    } else { | 
| 1148 | 
+ | 
      // branch to do all cutoff group pairs | 
| 1149 | 
+ | 
#ifdef IS_MPI | 
| 1150 | 
+ | 
      for (int j1 = 0; j1 < nGroupsInRow_; j1++) { | 
| 1151 | 
+ | 
        for (int j2 = 0; j2 < nGroupsInCol_; j2++) {        | 
| 1152 | 
+ | 
          dr = cgColData.position[j2] - cgRowData.position[j1]; | 
| 1153 | 
+ | 
          snap_->wrapVector(dr); | 
| 1154 | 
+ | 
          cuts = getGroupCutoffs( j1, j2 ); | 
| 1155 | 
+ | 
          if (dr.lengthSquare() < cuts.third) { | 
| 1156 | 
+ | 
            neighborList.push_back(make_pair(j1, j2)); | 
| 1157 | 
+ | 
          } | 
| 1158 | 
+ | 
        } | 
| 1159 | 
+ | 
      } | 
| 1160 | 
+ | 
#else | 
| 1161 | 
+ | 
      for (int j1 = 0; j1 < nGroups_ - 1; j1++) { | 
| 1162 | 
+ | 
        for (int j2 = j1 + 1; j2 < nGroups_; j2++) { | 
| 1163 | 
+ | 
          dr = snap_->cgData.position[j2] - snap_->cgData.position[j1]; | 
| 1164 | 
+ | 
          snap_->wrapVector(dr); | 
| 1165 | 
+ | 
          cuts = getGroupCutoffs( j1, j2 ); | 
| 1166 | 
+ | 
          if (dr.lengthSquare() < cuts.third) { | 
| 1167 | 
+ | 
            neighborList.push_back(make_pair(j1, j2)); | 
| 1168 | 
+ | 
          } | 
| 1169 | 
+ | 
        } | 
| 1170 | 
+ | 
      }         | 
| 1171 | 
+ | 
#endif | 
| 1172 | 
  | 
    } | 
| 1173 | 
< | 
     | 
| 1173 | 
> | 
       | 
| 1174 | 
  | 
    // save the local cutoff group positions for the check that is | 
| 1175 | 
  | 
    // done on each loop: | 
| 1176 | 
  | 
    saved_CG_positions_.clear(); | 
| 1177 | 
  | 
    for (int i = 0; i < nGroups_; i++) | 
| 1178 | 
  | 
      saved_CG_positions_.push_back(snap_->cgData.position[i]); | 
| 1179 | 
< | 
    | 
| 1179 | 
> | 
     | 
| 1180 | 
  | 
    return neighborList; | 
| 1181 | 
  | 
  } | 
| 1182 | 
  | 
} //end namespace OpenMD |