# | Line 1 | Line 1 | |
---|---|---|
1 | < | /** |
2 | < | * @file ForceDecomposition.cpp |
3 | < | * @author Charles Vardeman <cvardema.at.nd.edu> |
4 | < | * @date 08/18/2010 |
5 | < | * @time 11:56am |
6 | < | * @version 1.0 |
1 | > | /* |
2 | > | * Copyright (c) 2005 The University of Notre Dame. All Rights Reserved. |
3 | * | |
8 | – | * @section LICENSE |
9 | – | * Copyright (c) 2010 The University of Notre Dame. All Rights Reserved. |
10 | – | * |
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 | |
# | Line 45 | Line 38 | |
38 | * [3] Sun, Lin & Gezelter, J. Chem. Phys. 128, 24107 (2008). | |
39 | * [4] Vardeman & Gezelter, in progress (2009). | |
40 | */ | |
41 | + | #include "parallel/ForceDecomposition.hpp" |
42 | + | #include "parallel/Communicator.hpp" |
43 | + | #include "math/SquareMatrix3.hpp" |
44 | ||
45 | + | namespace OpenMD { |
46 | ||
47 | < | |
51 | < | /* -*- c++ -*- */ |
52 | < | #include "config.h" |
53 | < | #include <stdlib.h> |
47 | > | void ForceDecomposition::distributeInitialData() { |
48 | #ifdef IS_MPI | |
55 | – | #include <mpi.h> |
56 | – | #endif |
49 | ||
50 | < | #include <iostream> |
51 | < | #include <vector> |
60 | < | #include <algorithm> |
61 | < | #include <cmath> |
62 | < | #include "parallel/ForceDecomposition.hpp" |
50 | > | int nAtoms; |
51 | > | int nGroups; |
52 | ||
53 | + | AtomCommRealI = new Comm<I,RealType>(nAtoms); |
54 | + | AtomCommVectorI = new Comm<I,Vector3d>(nAtoms); |
55 | + | AtomCommMatrixI = new Comm<I,Mat3x3d>(nAtoms); |
56 | ||
57 | < | using namespace std; |
58 | < | using namespace OpenMD; |
57 | > | AtomCommRealJ = new Comm<J,RealType>(nAtoms); |
58 | > | AtomCommVectorJ = new Comm<J,Vector3d>(nAtoms); |
59 | > | AtomCommMatrixJ = new Comm<J,Mat3x3d>(nAtoms); |
60 | ||
61 | < | //__static |
62 | < | #ifdef IS_MPI |
63 | < | static vector<MPI:Comm> communictors; |
61 | > | cgCommVectorI = new Comm<I,Vector3d>(nGroups); |
62 | > | cgCommVectorJ = new Comm<J,Vector3d>(nGroups); |
63 | > | // more to come |
64 | #endif | |
65 | + | } |
66 | + | |
67 | ||
73 | – | //____ MPITypeTraits |
74 | – | template<typename T> |
75 | – | struct MPITypeTraits; |
68 | ||
69 | + | void ForceDecomposition::distributeData() { |
70 | #ifdef IS_MPI | |
71 | < | template<> |
79 | < | struct MPITypeTraits<RealType> { |
80 | < | static const MPI::Datatype datatype; |
81 | < | }; |
82 | < | const MPI_Datatype MPITypeTraits<RealType>::datatype = MY_MPI_REAL; |
71 | > | Snapshot* snap = sman_->getCurrentSnapshot(); |
72 | ||
73 | < | template<> |
74 | < | struct MPITypeTraits<int> { |
75 | < | static const MPI::Datatype datatype; |
76 | < | }; |
77 | < | const MPI::Datatype MPITypeTraits<int>::datatype = MPI_INT; |
78 | < | #endif |
79 | < | |
80 | < | /** |
81 | < | * Constructor for ForceDecomposition Parallel Decomposition Method |
82 | < | * Will try to construct a symmetric grid of processors. Ideally, the |
83 | < | * number of processors will be a square ex: 4, 9, 16, 25. |
84 | < | * |
85 | < | */ |
86 | < | |
87 | < | ForceDecomposition::ForceDecomposition() { |
88 | < | |
73 | > | // gather up the atomic positions |
74 | > | AtomCommVectorI->gather(snap->atomData.position, |
75 | > | snap->atomIData.position); |
76 | > | AtomCommVectorJ->gather(snap->atomData.position, |
77 | > | snap->atomJData.position); |
78 | > | |
79 | > | // gather up the cutoff group positions |
80 | > | cgCommVectorI->gather(snap->cgData.position, |
81 | > | snap->cgIData.position); |
82 | > | cgCommVectorJ->gather(snap->cgData.position, |
83 | > | snap->cgJData.position); |
84 | > | |
85 | > | // if needed, gather the atomic rotation matrices |
86 | > | if (snap->atomData.getStorageLayout() & DataStorage::dslAmat) { |
87 | > | AtomCommMatrixI->gather(snap->atomData.aMat, |
88 | > | snap->atomIData.aMat); |
89 | > | AtomCommMatrixJ->gather(snap->atomData.aMat, |
90 | > | snap->atomJData.aMat); |
91 | > | } |
92 | > | |
93 | > | // if needed, gather the atomic eletrostatic frames |
94 | > | if (snap->atomData.getStorageLayout() & DataStorage::dslElectroFrame) { |
95 | > | AtomCommMatrixI->gather(snap->atomData.electroFrame, |
96 | > | snap->atomIData.electroFrame); |
97 | > | AtomCommMatrixJ->gather(snap->atomData.electroFrame, |
98 | > | snap->atomJData.electroFrame); |
99 | > | } |
100 | > | #endif |
101 | > | } |
102 | > | |
103 | > | void ForceDecomposition::collectIntermediateData() { |
104 | #ifdef IS_MPI | |
105 | < | int nProcs = MPI::COMM_WORLD.Get_size(); |
106 | < | int worldRank = MPI::COMM_WORLD.Get_rank(); |
105 | > | Snapshot* snap = sman_->getCurrentSnapshot(); |
106 | > | // gather up the atomic positions |
107 | > | |
108 | > | if (snap->atomData.getStorageLayout() & DataStorage::dslDensity) { |
109 | > | AtomCommRealI->scatter(snap->atomIData.density, |
110 | > | snap->atomData.density); |
111 | > | std::vector<RealType> rho_tmp; |
112 | > | int n = snap->getNumberOfAtoms(); |
113 | > | rho_tmp.reserve( n ); |
114 | > | AtomCommRealJ->scatter(snap->atomJData.density, rho_tmp); |
115 | > | for (int i = 0; i < n; i++) |
116 | > | snap->atomData.density[i] += rho_tmp[i]; |
117 | > | } |
118 | #endif | |
119 | < | |
120 | < | // First time through, construct column stride. |
121 | < | if (communicators.size() == 0) |
122 | < | { |
123 | < | int nColumnsMax = (int) round(sqrt((float) nProcs)); |
124 | < | for (int i = 0; i < nProcs; ++i) |
125 | < | { |
126 | < | if (nProcs%i==0) nColumns=i; |
119 | > | } |
120 | > | |
121 | > | void ForceDecomposition::distributeIntermediateData() { |
122 | > | #ifdef IS_MPI |
123 | > | Snapshot* snap = sman_->getCurrentSnapshot(); |
124 | > | if (snap->atomData.getStorageLayout() & DataStorage::dslFunctional) { |
125 | > | AtomCommRealI->gather(snap->atomData.functional, |
126 | > | snap->atomIData.functional); |
127 | > | AtomCommRealJ->gather(snap->atomData.functional, |
128 | > | snap->atomJData.functional); |
129 | } | |
130 | < | |
131 | < | int nRows = nProcs/nColumns; |
132 | < | myRank_ = (int) worldRank%nColumns; |
130 | > | |
131 | > | if (snap->atomData.getStorageLayout() & DataStorage::dslFunctionalDerivative) { |
132 | > | AtomCommRealI->gather(snap->atomData.functionalDerivative, |
133 | > | snap->atomIData.functionalDerivative); |
134 | > | AtomCommRealJ->gather(snap->atomData.functionalDerivative, |
135 | > | snap->atomJData.functionalDerivative); |
136 | > | } |
137 | > | #endif |
138 | } | |
117 | – | else |
118 | – | { |
119 | – | myRank_ = myRank/nColumns; |
120 | – | } |
121 | – | MPI::Comm newComm = MPI:COMM_WORLD.Split(myRank_,0); |
139 | ||
123 | – | isColumn_ = false; |
140 | ||
141 | < | } |
142 | < | |
143 | < | ForceDecomposition::gather(sendbuf, receivebuf){ |
144 | < | communicators(myIndex_).Allgatherv(); |
145 | < | } |
146 | < | |
131 | < | |
132 | < | |
133 | < | ForceDecomposition::scatter(sbuffer, rbuffer){ |
134 | < | communicators(myIndex_).Reduce_scatter(sbuffer, recevbuf. recvcounts, MPI::DOUBLE, MPI::SUM); |
135 | < | } |
136 | < | |
137 | < | |
141 | > | void ForceDecomposition::collectData() { |
142 | > | #ifdef IS_MPI |
143 | > | #endif |
144 | > | } |
145 | > | |
146 | > | } //end namespace OpenMD |
– | Removed lines |
+ | Added lines |
< | Changed lines |
> | Changed lines |