ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/parallel/ForceMatrixDecomposition.cpp
Revision: 1569
Committed: Thu May 26 13:55:04 2011 UTC (13 years, 11 months ago) by gezelter
File size: 22544 byte(s)
Log Message:
A few more fixes for the missing routines

File Contents

# User Rev Content
1 gezelter 1539 /*
2     * Copyright (c) 2005 The University of Notre Dame. All Rights Reserved.
3 chuckv 1538 *
4     * The University of Notre Dame grants you ("Licensee") a
5     * non-exclusive, royalty free, license to use, modify and
6     * redistribute this software in source and binary code form, provided
7     * that the following conditions are met:
8     *
9     * 1. Redistributions of source code must retain the above copyright
10     * notice, this list of conditions and the following disclaimer.
11     *
12     * 2. Redistributions in binary form must reproduce the above copyright
13     * notice, this list of conditions and the following disclaimer in the
14     * documentation and/or other materials provided with the
15     * distribution.
16     *
17     * This software is provided "AS IS," without a warranty of any
18     * kind. All express or implied conditions, representations and
19     * warranties, including any implied warranty of merchantability,
20     * fitness for a particular purpose or non-infringement, are hereby
21     * excluded. The University of Notre Dame and its licensors shall not
22     * be liable for any damages suffered by licensee as a result of
23     * using, modifying or distributing the software or its
24     * derivatives. In no event will the University of Notre Dame or its
25     * licensors be liable for any lost revenue, profit or data, or for
26     * direct, indirect, special, consequential, incidental or punitive
27     * damages, however caused and regardless of the theory of liability,
28     * arising out of the use of or inability to use software, even if the
29     * University of Notre Dame has been advised of the possibility of
30     * such damages.
31     *
32     * SUPPORT OPEN SCIENCE! If you use OpenMD or its source code in your
33     * research, please cite the appropriate papers when you publish your
34     * work. Good starting points are:
35     *
36     * [1] Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).
37     * [2] Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).
38     * [3] Sun, Lin & Gezelter, J. Chem. Phys. 128, 24107 (2008).
39     * [4] Vardeman & Gezelter, in progress (2009).
40     */
41 gezelter 1549 #include "parallel/ForceMatrixDecomposition.hpp"
42 gezelter 1539 #include "math/SquareMatrix3.hpp"
43 gezelter 1544 #include "nonbonded/NonBondedInteraction.hpp"
44     #include "brains/SnapshotManager.hpp"
45 chuckv 1538
46 gezelter 1541 using namespace std;
47 gezelter 1539 namespace OpenMD {
48 chuckv 1538
49 gezelter 1544 /**
50     * distributeInitialData is essentially a copy of the older fortran
51     * SimulationSetup
52     */
53    
54 gezelter 1549 void ForceMatrixDecomposition::distributeInitialData() {
55 gezelter 1551 snap_ = sman_->getCurrentSnapshot();
56     storageLayout_ = sman_->getStorageLayout();
57 gezelter 1567 nLocal_ = snap_->getNumberOfAtoms();
58     nGroups_ = snap_->getNumberOfCutoffGroups();
59 chuckv 1538
60 gezelter 1569 // gather the information for atomtype IDs (atids):
61     vector<int> identsLocal = info_->getIdentArray();
62     AtomLocalToGlobal = info_->getGlobalAtomIndices();
63     cgLocalToGlobal = info_->getGlobalGroupIndices();
64     vector<int> globalGroupMembership = info_->getGlobalGroupMembership();
65     vector<RealType> massFactorsLocal = info_->getMassFactors();
66     vector<RealType> pot_local(N_INTERACTION_FAMILIES, 0.0);
67    
68 gezelter 1567 #ifdef IS_MPI
69    
70     AtomCommIntRow = new Communicator<Row,int>(nLocal_);
71     AtomCommRealRow = new Communicator<Row,RealType>(nLocal_);
72     AtomCommVectorRow = new Communicator<Row,Vector3d>(nLocal_);
73     AtomCommMatrixRow = new Communicator<Row,Mat3x3d>(nLocal_);
74 chuckv 1538
75 gezelter 1567 AtomCommIntColumn = new Communicator<Column,int>(nLocal_);
76     AtomCommRealColumn = new Communicator<Column,RealType>(nLocal_);
77     AtomCommVectorColumn = new Communicator<Column,Vector3d>(nLocal_);
78     AtomCommMatrixColumn = new Communicator<Column,Mat3x3d>(nLocal_);
79 gezelter 1541
80 gezelter 1567 cgCommIntRow = new Communicator<Row,int>(nGroups_);
81     cgCommVectorRow = new Communicator<Row,Vector3d>(nGroups_);
82     cgCommIntColumn = new Communicator<Column,int>(nGroups_);
83     cgCommVectorColumn = new Communicator<Column,Vector3d>(nGroups_);
84 gezelter 1551
85 gezelter 1567 nAtomsInRow_ = AtomCommIntRow->getSize();
86     nAtomsInCol_ = AtomCommIntColumn->getSize();
87     nGroupsInRow_ = cgCommIntRow->getSize();
88     nGroupsInCol_ = cgCommIntColumn->getSize();
89    
90 gezelter 1551 // Modify the data storage objects with the correct layouts and sizes:
91 gezelter 1567 atomRowData.resize(nAtomsInRow_);
92 gezelter 1551 atomRowData.setStorageLayout(storageLayout_);
93 gezelter 1567 atomColData.resize(nAtomsInCol_);
94 gezelter 1551 atomColData.setStorageLayout(storageLayout_);
95 gezelter 1567 cgRowData.resize(nGroupsInRow_);
96 gezelter 1551 cgRowData.setStorageLayout(DataStorage::dslPosition);
97 gezelter 1567 cgColData.resize(nGroupsInCol_);
98 gezelter 1551 cgColData.setStorageLayout(DataStorage::dslPosition);
99 gezelter 1549
100 gezelter 1544 vector<vector<RealType> > pot_row(N_INTERACTION_FAMILIES,
101 gezelter 1567 vector<RealType> (nAtomsInRow_, 0.0));
102 gezelter 1544 vector<vector<RealType> > pot_col(N_INTERACTION_FAMILIES,
103 gezelter 1567 vector<RealType> (nAtomsInCol_, 0.0));
104 gezelter 1549
105 gezelter 1567 identsRow.reserve(nAtomsInRow_);
106     identsCol.reserve(nAtomsInCol_);
107 gezelter 1549
108     AtomCommIntRow->gather(identsLocal, identsRow);
109     AtomCommIntColumn->gather(identsLocal, identsCol);
110    
111     AtomCommIntRow->gather(AtomLocalToGlobal, AtomRowToGlobal);
112     AtomCommIntColumn->gather(AtomLocalToGlobal, AtomColToGlobal);
113    
114     cgCommIntRow->gather(cgLocalToGlobal, cgRowToGlobal);
115     cgCommIntColumn->gather(cgLocalToGlobal, cgColToGlobal);
116 gezelter 1541
117 gezelter 1569 AtomCommRealRow->gather(massFactorsLocal, massFactorsRow);
118     AtomCommRealColumn->gather(massFactorsLocal, massFactorsCol);
119    
120     groupListRow_.clear();
121     groupListRow_.reserve(nGroupsInRow_);
122     for (int i = 0; i < nGroupsInRow_; i++) {
123     int gid = cgRowToGlobal[i];
124     for (int j = 0; j < nAtomsInRow_; j++) {
125     int aid = AtomRowToGlobal[j];
126     if (globalGroupMembership[aid] == gid)
127     groupListRow_[i].push_back(j);
128     }
129     }
130    
131     groupListCol_.clear();
132     groupListCol_.reserve(nGroupsInCol_);
133     for (int i = 0; i < nGroupsInCol_; i++) {
134     int gid = cgColToGlobal[i];
135     for (int j = 0; j < nAtomsInCol_; j++) {
136     int aid = AtomColToGlobal[j];
137     if (globalGroupMembership[aid] == gid)
138     groupListCol_[i].push_back(j);
139     }
140     }
141    
142     #endif
143    
144     groupList_.clear();
145     groupList_.reserve(nGroups_);
146     for (int i = 0; i < nGroups_; i++) {
147     int gid = cgLocalToGlobal[i];
148     for (int j = 0; j < nLocal_; j++) {
149     int aid = AtomLocalToGlobal[j];
150     if (globalGroupMembership[aid] == gid)
151     groupList_[i].push_back(j);
152     }
153     }
154    
155    
156 gezelter 1544 // still need:
157     // topoDist
158     // exclude
159 gezelter 1569
160 gezelter 1539 }
161    
162 chuckv 1538
163    
164 gezelter 1549 void ForceMatrixDecomposition::distributeData() {
165 gezelter 1551 snap_ = sman_->getCurrentSnapshot();
166     storageLayout_ = sman_->getStorageLayout();
167 chuckv 1538 #ifdef IS_MPI
168 gezelter 1540
169 gezelter 1539 // gather up the atomic positions
170 gezelter 1551 AtomCommVectorRow->gather(snap_->atomData.position,
171     atomRowData.position);
172     AtomCommVectorColumn->gather(snap_->atomData.position,
173     atomColData.position);
174 gezelter 1539
175     // gather up the cutoff group positions
176 gezelter 1551 cgCommVectorRow->gather(snap_->cgData.position,
177     cgRowData.position);
178     cgCommVectorColumn->gather(snap_->cgData.position,
179     cgColData.position);
180 gezelter 1539
181     // if needed, gather the atomic rotation matrices
182 gezelter 1551 if (storageLayout_ & DataStorage::dslAmat) {
183     AtomCommMatrixRow->gather(snap_->atomData.aMat,
184     atomRowData.aMat);
185     AtomCommMatrixColumn->gather(snap_->atomData.aMat,
186     atomColData.aMat);
187 gezelter 1539 }
188    
189     // if needed, gather the atomic eletrostatic frames
190 gezelter 1551 if (storageLayout_ & DataStorage::dslElectroFrame) {
191     AtomCommMatrixRow->gather(snap_->atomData.electroFrame,
192     atomRowData.electroFrame);
193     AtomCommMatrixColumn->gather(snap_->atomData.electroFrame,
194     atomColData.electroFrame);
195 gezelter 1539 }
196     #endif
197     }
198    
199 gezelter 1549 void ForceMatrixDecomposition::collectIntermediateData() {
200 gezelter 1551 snap_ = sman_->getCurrentSnapshot();
201     storageLayout_ = sman_->getStorageLayout();
202 gezelter 1539 #ifdef IS_MPI
203    
204 gezelter 1551 if (storageLayout_ & DataStorage::dslDensity) {
205    
206     AtomCommRealRow->scatter(atomRowData.density,
207     snap_->atomData.density);
208    
209     int n = snap_->atomData.density.size();
210 gezelter 1541 std::vector<RealType> rho_tmp(n, 0.0);
211 gezelter 1551 AtomCommRealColumn->scatter(atomColData.density, rho_tmp);
212 gezelter 1539 for (int i = 0; i < n; i++)
213 gezelter 1551 snap_->atomData.density[i] += rho_tmp[i];
214 gezelter 1539 }
215 chuckv 1538 #endif
216 gezelter 1539 }
217    
218 gezelter 1549 void ForceMatrixDecomposition::distributeIntermediateData() {
219 gezelter 1551 snap_ = sman_->getCurrentSnapshot();
220     storageLayout_ = sman_->getStorageLayout();
221 chuckv 1538 #ifdef IS_MPI
222 gezelter 1551 if (storageLayout_ & DataStorage::dslFunctional) {
223     AtomCommRealRow->gather(snap_->atomData.functional,
224     atomRowData.functional);
225     AtomCommRealColumn->gather(snap_->atomData.functional,
226     atomColData.functional);
227 gezelter 1539 }
228    
229 gezelter 1551 if (storageLayout_ & DataStorage::dslFunctionalDerivative) {
230     AtomCommRealRow->gather(snap_->atomData.functionalDerivative,
231     atomRowData.functionalDerivative);
232     AtomCommRealColumn->gather(snap_->atomData.functionalDerivative,
233     atomColData.functionalDerivative);
234 gezelter 1539 }
235 chuckv 1538 #endif
236     }
237 gezelter 1539
238    
239 gezelter 1549 void ForceMatrixDecomposition::collectData() {
240 gezelter 1551 snap_ = sman_->getCurrentSnapshot();
241     storageLayout_ = sman_->getStorageLayout();
242     #ifdef IS_MPI
243     int n = snap_->atomData.force.size();
244 gezelter 1544 vector<Vector3d> frc_tmp(n, V3Zero);
245 gezelter 1541
246 gezelter 1551 AtomCommVectorRow->scatter(atomRowData.force, frc_tmp);
247 gezelter 1541 for (int i = 0; i < n; i++) {
248 gezelter 1551 snap_->atomData.force[i] += frc_tmp[i];
249 gezelter 1541 frc_tmp[i] = 0.0;
250     }
251 gezelter 1540
252 gezelter 1551 AtomCommVectorColumn->scatter(atomColData.force, frc_tmp);
253 gezelter 1540 for (int i = 0; i < n; i++)
254 gezelter 1551 snap_->atomData.force[i] += frc_tmp[i];
255 gezelter 1540
256    
257 gezelter 1551 if (storageLayout_ & DataStorage::dslTorque) {
258 gezelter 1541
259 gezelter 1551 int nt = snap_->atomData.force.size();
260 gezelter 1544 vector<Vector3d> trq_tmp(nt, V3Zero);
261 gezelter 1541
262 gezelter 1551 AtomCommVectorRow->scatter(atomRowData.torque, trq_tmp);
263 gezelter 1541 for (int i = 0; i < n; i++) {
264 gezelter 1551 snap_->atomData.torque[i] += trq_tmp[i];
265 gezelter 1541 trq_tmp[i] = 0.0;
266     }
267 gezelter 1540
268 gezelter 1551 AtomCommVectorColumn->scatter(atomColData.torque, trq_tmp);
269 gezelter 1540 for (int i = 0; i < n; i++)
270 gezelter 1551 snap_->atomData.torque[i] += trq_tmp[i];
271 gezelter 1540 }
272    
273 gezelter 1567 nLocal_ = snap_->getNumberOfAtoms();
274 gezelter 1544
275     vector<vector<RealType> > pot_temp(N_INTERACTION_FAMILIES,
276 gezelter 1567 vector<RealType> (nLocal_, 0.0));
277 gezelter 1540
278 gezelter 1544 for (int i = 0; i < N_INTERACTION_FAMILIES; i++) {
279 gezelter 1549 AtomCommRealRow->scatter(pot_row[i], pot_temp[i]);
280 gezelter 1541 for (int ii = 0; ii < pot_temp[i].size(); ii++ ) {
281     pot_local[i] += pot_temp[i][ii];
282     }
283     }
284 gezelter 1539 #endif
285 chuckv 1538 }
286 gezelter 1551
287 gezelter 1569 /**
288     * returns the list of atoms belonging to this group.
289     */
290     vector<int> ForceMatrixDecomposition::getAtomsInGroupRow(int cg1){
291     #ifdef IS_MPI
292     return groupListRow_[cg1];
293     #else
294     return groupList_[cg1];
295     #endif
296     }
297    
298     vector<int> ForceMatrixDecomposition::getAtomsInGroupColumn(int cg2){
299     #ifdef IS_MPI
300     return groupListCol_[cg2];
301     #else
302     return groupList_[cg2];
303     #endif
304     }
305 chuckv 1538
306 gezelter 1551 Vector3d ForceMatrixDecomposition::getIntergroupVector(int cg1, int cg2){
307     Vector3d d;
308    
309     #ifdef IS_MPI
310     d = cgColData.position[cg2] - cgRowData.position[cg1];
311     #else
312     d = snap_->cgData.position[cg2] - snap_->cgData.position[cg1];
313     #endif
314    
315     snap_->wrapVector(d);
316     return d;
317     }
318    
319    
320     Vector3d ForceMatrixDecomposition::getAtomToGroupVectorRow(int atom1, int cg1){
321    
322     Vector3d d;
323    
324     #ifdef IS_MPI
325     d = cgRowData.position[cg1] - atomRowData.position[atom1];
326     #else
327     d = snap_->cgData.position[cg1] - snap_->atomData.position[atom1];
328     #endif
329    
330     snap_->wrapVector(d);
331     return d;
332     }
333    
334     Vector3d ForceMatrixDecomposition::getAtomToGroupVectorColumn(int atom2, int cg2){
335     Vector3d d;
336    
337     #ifdef IS_MPI
338     d = cgColData.position[cg2] - atomColData.position[atom2];
339     #else
340     d = snap_->cgData.position[cg2] - snap_->atomData.position[atom2];
341     #endif
342    
343     snap_->wrapVector(d);
344     return d;
345     }
346 gezelter 1569
347     RealType ForceMatrixDecomposition::getMassFactorRow(int atom1) {
348     #ifdef IS_MPI
349     return massFactorsRow[atom1];
350     #else
351     return massFactorsLocal[atom1];
352     #endif
353     }
354    
355     RealType ForceMatrixDecomposition::getMassFactorColumn(int atom2) {
356     #ifdef IS_MPI
357     return massFactorsCol[atom2];
358     #else
359     return massFactorsLocal[atom2];
360     #endif
361    
362     }
363 gezelter 1551
364     Vector3d ForceMatrixDecomposition::getInteratomicVector(int atom1, int atom2){
365     Vector3d d;
366    
367     #ifdef IS_MPI
368     d = atomColData.position[atom2] - atomRowData.position[atom1];
369     #else
370     d = snap_->atomData.position[atom2] - snap_->atomData.position[atom1];
371     #endif
372    
373     snap_->wrapVector(d);
374     return d;
375     }
376    
377     void ForceMatrixDecomposition::addForceToAtomRow(int atom1, Vector3d fg){
378     #ifdef IS_MPI
379     atomRowData.force[atom1] += fg;
380     #else
381     snap_->atomData.force[atom1] += fg;
382     #endif
383     }
384    
385     void ForceMatrixDecomposition::addForceToAtomColumn(int atom2, Vector3d fg){
386     #ifdef IS_MPI
387     atomColData.force[atom2] += fg;
388     #else
389     snap_->atomData.force[atom2] += fg;
390     #endif
391     }
392    
393     // filling interaction blocks with pointers
394     InteractionData ForceMatrixDecomposition::fillInteractionData(int atom1, int atom2) {
395 gezelter 1567 InteractionData idat;
396 gezelter 1551
397     #ifdef IS_MPI
398     if (storageLayout_ & DataStorage::dslAmat) {
399 gezelter 1554 idat.A1 = &(atomRowData.aMat[atom1]);
400     idat.A2 = &(atomColData.aMat[atom2]);
401 gezelter 1551 }
402 gezelter 1567
403 gezelter 1551 if (storageLayout_ & DataStorage::dslElectroFrame) {
404 gezelter 1554 idat.eFrame1 = &(atomRowData.electroFrame[atom1]);
405     idat.eFrame2 = &(atomColData.electroFrame[atom2]);
406 gezelter 1551 }
407    
408     if (storageLayout_ & DataStorage::dslTorque) {
409 gezelter 1554 idat.t1 = &(atomRowData.torque[atom1]);
410     idat.t2 = &(atomColData.torque[atom2]);
411 gezelter 1551 }
412    
413     if (storageLayout_ & DataStorage::dslDensity) {
414 gezelter 1554 idat.rho1 = &(atomRowData.density[atom1]);
415     idat.rho2 = &(atomColData.density[atom2]);
416 gezelter 1551 }
417    
418     if (storageLayout_ & DataStorage::dslFunctionalDerivative) {
419 gezelter 1554 idat.dfrho1 = &(atomRowData.functionalDerivative[atom1]);
420     idat.dfrho2 = &(atomColData.functionalDerivative[atom2]);
421 gezelter 1551 }
422 gezelter 1562 #else
423     if (storageLayout_ & DataStorage::dslAmat) {
424     idat.A1 = &(snap_->atomData.aMat[atom1]);
425     idat.A2 = &(snap_->atomData.aMat[atom2]);
426     }
427    
428     if (storageLayout_ & DataStorage::dslElectroFrame) {
429     idat.eFrame1 = &(snap_->atomData.electroFrame[atom1]);
430     idat.eFrame2 = &(snap_->atomData.electroFrame[atom2]);
431     }
432    
433     if (storageLayout_ & DataStorage::dslTorque) {
434     idat.t1 = &(snap_->atomData.torque[atom1]);
435     idat.t2 = &(snap_->atomData.torque[atom2]);
436     }
437    
438     if (storageLayout_ & DataStorage::dslDensity) {
439     idat.rho1 = &(snap_->atomData.density[atom1]);
440     idat.rho2 = &(snap_->atomData.density[atom2]);
441     }
442    
443     if (storageLayout_ & DataStorage::dslFunctionalDerivative) {
444     idat.dfrho1 = &(snap_->atomData.functionalDerivative[atom1]);
445     idat.dfrho2 = &(snap_->atomData.functionalDerivative[atom2]);
446     }
447 gezelter 1551 #endif
448 gezelter 1567 return idat;
449 gezelter 1551 }
450 gezelter 1567
451 gezelter 1551 InteractionData ForceMatrixDecomposition::fillSkipData(int atom1, int atom2){
452 gezelter 1567
453 gezelter 1562 InteractionData idat;
454     #ifdef IS_MPI
455     if (storageLayout_ & DataStorage::dslElectroFrame) {
456     idat.eFrame1 = &(atomRowData.electroFrame[atom1]);
457     idat.eFrame2 = &(atomColData.electroFrame[atom2]);
458     }
459     if (storageLayout_ & DataStorage::dslTorque) {
460     idat.t1 = &(atomRowData.torque[atom1]);
461     idat.t2 = &(atomColData.torque[atom2]);
462     }
463 gezelter 1567 if (storageLayout_ & DataStorage::dslForce) {
464     idat.t1 = &(atomRowData.force[atom1]);
465     idat.t2 = &(atomColData.force[atom2]);
466     }
467     #else
468     if (storageLayout_ & DataStorage::dslElectroFrame) {
469     idat.eFrame1 = &(snap_->atomData.electroFrame[atom1]);
470     idat.eFrame2 = &(snap_->atomData.electroFrame[atom2]);
471     }
472     if (storageLayout_ & DataStorage::dslTorque) {
473     idat.t1 = &(snap_->atomData.torque[atom1]);
474     idat.t2 = &(snap_->atomData.torque[atom2]);
475     }
476     if (storageLayout_ & DataStorage::dslForce) {
477     idat.t1 = &(snap_->atomData.force[atom1]);
478     idat.t2 = &(snap_->atomData.force[atom2]);
479     }
480     #endif
481 gezelter 1562
482 gezelter 1551 }
483 gezelter 1567
484    
485 gezelter 1551
486 gezelter 1562
487     /*
488     * buildNeighborList
489     *
490     * first element of pair is row-indexed CutoffGroup
491     * second element of pair is column-indexed CutoffGroup
492     */
493 gezelter 1567 vector<pair<int, int> > ForceMatrixDecomposition::buildNeighborList() {
494    
495     vector<pair<int, int> > neighborList;
496     #ifdef IS_MPI
497 gezelter 1568 cellListRow_.clear();
498     cellListCol_.clear();
499 gezelter 1567 #else
500 gezelter 1568 cellList_.clear();
501 gezelter 1567 #endif
502 gezelter 1562
503 gezelter 1567 // dangerous to not do error checking.
504     RealType rCut_;
505    
506     RealType rList_ = (rCut_ + skinThickness_);
507     RealType rl2 = rList_ * rList_;
508     Snapshot* snap_ = sman_->getCurrentSnapshot();
509 gezelter 1562 Mat3x3d Hmat = snap_->getHmat();
510     Vector3d Hx = Hmat.getColumn(0);
511     Vector3d Hy = Hmat.getColumn(1);
512     Vector3d Hz = Hmat.getColumn(2);
513    
514 gezelter 1568 nCells_.x() = (int) ( Hx.length() )/ rList_;
515     nCells_.y() = (int) ( Hy.length() )/ rList_;
516     nCells_.z() = (int) ( Hz.length() )/ rList_;
517 gezelter 1562
518 gezelter 1567 Mat3x3d invHmat = snap_->getInvHmat();
519     Vector3d rs, scaled, dr;
520     Vector3i whichCell;
521     int cellIndex;
522    
523     #ifdef IS_MPI
524     for (int i = 0; i < nGroupsInRow_; i++) {
525 gezelter 1562 rs = cgRowData.position[i];
526 gezelter 1567 // scaled positions relative to the box vectors
527     scaled = invHmat * rs;
528     // wrap the vector back into the unit box by subtracting integer box
529     // numbers
530     for (int j = 0; j < 3; j++)
531     scaled[j] -= roundMe(scaled[j]);
532    
533     // find xyz-indices of cell that cutoffGroup is in.
534 gezelter 1568 whichCell.x() = nCells_.x() * scaled.x();
535     whichCell.y() = nCells_.y() * scaled.y();
536     whichCell.z() = nCells_.z() * scaled.z();
537 gezelter 1567
538     // find single index of this cell:
539 gezelter 1568 cellIndex = Vlinear(whichCell, nCells_);
540 gezelter 1567 // add this cutoff group to the list of groups in this cell;
541 gezelter 1568 cellListRow_[cellIndex].push_back(i);
542 gezelter 1562 }
543    
544 gezelter 1567 for (int i = 0; i < nGroupsInCol_; i++) {
545     rs = cgColData.position[i];
546     // scaled positions relative to the box vectors
547     scaled = invHmat * rs;
548     // wrap the vector back into the unit box by subtracting integer box
549     // numbers
550     for (int j = 0; j < 3; j++)
551     scaled[j] -= roundMe(scaled[j]);
552    
553     // find xyz-indices of cell that cutoffGroup is in.
554 gezelter 1568 whichCell.x() = nCells_.x() * scaled.x();
555     whichCell.y() = nCells_.y() * scaled.y();
556     whichCell.z() = nCells_.z() * scaled.z();
557 gezelter 1567
558     // find single index of this cell:
559 gezelter 1568 cellIndex = Vlinear(whichCell, nCells_);
560 gezelter 1567 // add this cutoff group to the list of groups in this cell;
561 gezelter 1568 cellListCol_[cellIndex].push_back(i);
562 gezelter 1562 }
563 gezelter 1567 #else
564     for (int i = 0; i < nGroups_; i++) {
565     rs = snap_->cgData.position[i];
566     // scaled positions relative to the box vectors
567     scaled = invHmat * rs;
568     // wrap the vector back into the unit box by subtracting integer box
569     // numbers
570     for (int j = 0; j < 3; j++)
571     scaled[j] -= roundMe(scaled[j]);
572    
573     // find xyz-indices of cell that cutoffGroup is in.
574 gezelter 1568 whichCell.x() = nCells_.x() * scaled.x();
575     whichCell.y() = nCells_.y() * scaled.y();
576     whichCell.z() = nCells_.z() * scaled.z();
577 gezelter 1567
578     // find single index of this cell:
579 gezelter 1568 cellIndex = Vlinear(whichCell, nCells_);
580 gezelter 1567 // add this cutoff group to the list of groups in this cell;
581 gezelter 1568 cellList_[cellIndex].push_back(i);
582 gezelter 1567 }
583     #endif
584    
585    
586    
587 gezelter 1568 for (int m1z = 0; m1z < nCells_.z(); m1z++) {
588     for (int m1y = 0; m1y < nCells_.y(); m1y++) {
589     for (int m1x = 0; m1x < nCells_.x(); m1x++) {
590 gezelter 1562 Vector3i m1v(m1x, m1y, m1z);
591 gezelter 1568 int m1 = Vlinear(m1v, nCells_);
592 gezelter 1562
593 gezelter 1568 for (vector<Vector3i>::iterator os = cellOffsets_.begin();
594     os != cellOffsets_.end(); ++os) {
595    
596     Vector3i m2v = m1v + (*os);
597    
598     if (m2v.x() >= nCells_.x()) {
599 gezelter 1562 m2v.x() = 0;
600     } else if (m2v.x() < 0) {
601 gezelter 1568 m2v.x() = nCells_.x() - 1;
602 gezelter 1562 }
603 gezelter 1568
604     if (m2v.y() >= nCells_.y()) {
605 gezelter 1562 m2v.y() = 0;
606     } else if (m2v.y() < 0) {
607 gezelter 1568 m2v.y() = nCells_.y() - 1;
608 gezelter 1562 }
609 gezelter 1568
610     if (m2v.z() >= nCells_.z()) {
611 gezelter 1567 m2v.z() = 0;
612     } else if (m2v.z() < 0) {
613 gezelter 1568 m2v.z() = nCells_.z() - 1;
614 gezelter 1567 }
615 gezelter 1568
616     int m2 = Vlinear (m2v, nCells_);
617 gezelter 1567
618     #ifdef IS_MPI
619 gezelter 1568 for (vector<int>::iterator j1 = cellListRow_[m1].begin();
620     j1 != cellListRow_[m1].end(); ++j1) {
621     for (vector<int>::iterator j2 = cellListCol_[m2].begin();
622     j2 != cellListCol_[m2].end(); ++j2) {
623 gezelter 1567
624     // Always do this if we're in different cells or if
625     // we're in the same cell and the global index of the
626     // j2 cutoff group is less than the j1 cutoff group
627    
628     if (m2 != m1 || cgColToGlobal[(*j2)] < cgRowToGlobal[(*j1)]) {
629     dr = cgColData.position[(*j2)] - cgRowData.position[(*j1)];
630     snap_->wrapVector(dr);
631     if (dr.lengthSquare() < rl2) {
632     neighborList.push_back(make_pair((*j1), (*j2)));
633 gezelter 1562 }
634     }
635     }
636     }
637 gezelter 1567 #else
638 gezelter 1568 for (vector<int>::iterator j1 = cellList_[m1].begin();
639     j1 != cellList_[m1].end(); ++j1) {
640     for (vector<int>::iterator j2 = cellList_[m2].begin();
641     j2 != cellList_[m2].end(); ++j2) {
642 gezelter 1567
643     // Always do this if we're in different cells or if
644     // we're in the same cell and the global index of the
645     // j2 cutoff group is less than the j1 cutoff group
646    
647     if (m2 != m1 || (*j2) < (*j1)) {
648     dr = snap_->cgData.position[(*j2)] - snap_->cgData.position[(*j1)];
649     snap_->wrapVector(dr);
650     if (dr.lengthSquare() < rl2) {
651     neighborList.push_back(make_pair((*j1), (*j2)));
652     }
653     }
654     }
655     }
656     #endif
657 gezelter 1562 }
658     }
659     }
660     }
661 gezelter 1568
662     // save the local cutoff group positions for the check that is
663     // done on each loop:
664     saved_CG_positions_.clear();
665     for (int i = 0; i < nGroups_; i++)
666     saved_CG_positions_.push_back(snap_->cgData.position[i]);
667    
668 gezelter 1567 return neighborList;
669 gezelter 1562 }
670 gezelter 1539 } //end namespace OpenMD