# | 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 Communicator<Row,RealType>(nAtoms); |
54 | + | AtomCommVectorI = new Communicator<Row,Vector3d>(nAtoms); |
55 | + | AtomCommMatrixI = new Communicator<Row,Mat3x3d>(nAtoms); |
56 | ||
57 | < | using namespace std; |
58 | < | using namespace OpenMD; |
57 | > | AtomCommRealJ = new Communicator<Column,RealType>(nAtoms); |
58 | > | AtomCommVectorJ = new Communicator<Column,Vector3d>(nAtoms); |
59 | > | AtomCommMatrixJ = new Communicator<Column,Mat3x3d>(nAtoms); |
60 | ||
61 | < | //__static |
62 | < | #ifdef IS_MPI |
63 | < | static vector<MPI:Comm> communictors; |
61 | > | cgCommVectorI = new Communicator<Row,Vector3d>(nGroups); |
62 | > | cgCommVectorJ = new Communicator<Column,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<> |
72 | < | struct MPITypeTraits<RealType> { |
73 | < | static const MPI::Datatype datatype; |
74 | < | }; |
75 | < | const MPI_Datatype MPITypeTraits<RealType>::datatype = MY_MPI_REAL; |
76 | < | |
77 | < | template<> |
78 | < | struct MPITypeTraits<int> { |
79 | < | static const MPI::Datatype datatype; |
80 | < | }; |
81 | < | const MPI::Datatype MPITypeTraits<int>::datatype = MPI_INT; |
82 | < | #endif |
83 | < | |
84 | < | /** |
85 | < | * Constructor for ForceDecomposition Parallel Decomposition Method |
86 | < | * Will try to construct a symmetric grid of processors. Ideally, the |
87 | < | * number of processors will be a square ex: 4, 9, 16, 25. |
88 | < | * |
89 | < | */ |
90 | < | |
91 | < | ForceDecomposition::ForceDecomposition() { |
92 | < | |
71 | > | Snapshot* snap = sman_->getCurrentSnapshot(); |
72 | > | |
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 | > | |
107 | > | if (snap->atomData.getStorageLayout() & DataStorage::dslDensity) { |
108 | > | AtomCommRealI->scatter(snap->atomIData.density, |
109 | > | snap->atomData.density); |
110 | > | std::vector<RealType> rho_tmp; |
111 | > | int n = snap->getNumberOfAtoms(); |
112 | > | rho_tmp.reserve( n ); |
113 | > | AtomCommRealJ->scatter(snap->atomJData.density, rho_tmp); |
114 | > | for (int i = 0; i < n; i++) |
115 | > | snap->atomData.density[i] += rho_tmp[i]; |
116 | > | } |
117 | #endif | |
118 | < | |
119 | < | // First time through, construct column stride. |
120 | < | if (communicators.size() == 0) |
121 | < | { |
122 | < | int nColumnsMax = (int) round(sqrt((float) nProcs)); |
123 | < | for (int i = 0; i < nProcs; ++i) |
124 | < | { |
125 | < | if (nProcs%i==0) nColumns=i; |
118 | > | } |
119 | > | |
120 | > | void ForceDecomposition::distributeIntermediateData() { |
121 | > | #ifdef IS_MPI |
122 | > | Snapshot* snap = sman_->getCurrentSnapshot(); |
123 | > | if (snap->atomData.getStorageLayout() & DataStorage::dslFunctional) { |
124 | > | AtomCommRealI->gather(snap->atomData.functional, |
125 | > | snap->atomIData.functional); |
126 | > | AtomCommRealJ->gather(snap->atomData.functional, |
127 | > | snap->atomJData.functional); |
128 | } | |
129 | < | |
130 | < | int nRows = nProcs/nColumns; |
131 | < | myRank_ = (int) worldRank%nColumns; |
129 | > | |
130 | > | if (snap->atomData.getStorageLayout() & DataStorage::dslFunctionalDerivative) { |
131 | > | AtomCommRealI->gather(snap->atomData.functionalDerivative, |
132 | > | snap->atomIData.functionalDerivative); |
133 | > | AtomCommRealJ->gather(snap->atomData.functionalDerivative, |
134 | > | snap->atomJData.functionalDerivative); |
135 | > | } |
136 | > | #endif |
137 | } | |
117 | – | else |
118 | – | { |
119 | – | myRank_ = myRank/nColumns; |
120 | – | } |
121 | – | MPI::Comm newComm = MPI:COMM_WORLD.Split(myRank_,0); |
138 | ||
123 | – | isColumn_ = false; |
139 | ||
140 | < | } |
140 | > | void ForceDecomposition::collectData() { |
141 | > | #ifdef IS_MPI |
142 | > | Snapshot* snap = sman_->getCurrentSnapshot(); |
143 | > | int n = snap->getNumberOfAtoms(); |
144 | ||
145 | < | ForceDecomposition::gather(sendbuf, receivebuf){ |
146 | < | communicators(myIndex_).Allgatherv(); |
147 | < | } |
145 | > | std::vector<Vector3d> frc_tmp; |
146 | > | frc_tmp.reserve( n ); |
147 | > | |
148 | > | AtomCommVectorI->scatter(snap->atomIData.force, frc_tmp); |
149 | > | for (int i = 0; i < n; i++) |
150 | > | snap->atomData.force[i] += frc_tmp[i]; |
151 | > | |
152 | > | AtomCommVectorJ->scatter(snap->atomJData.force, frc_tmp); |
153 | > | for (int i = 0; i < n; i++) |
154 | > | snap->atomData.force[i] += frc_tmp[i]; |
155 | > | |
156 | > | |
157 | > | if (snap->atomData.getStorageLayout() & DataStorage::dslTorque) { |
158 | > | std::vector<Vector3d> trq_tmp; |
159 | > | trq_tmp.reserve( n ); |
160 | > | |
161 | > | AtomCommVectorI->scatter(snap->atomIData.torque, trq_tmp); |
162 | > | for (int i = 0; i < n; i++) |
163 | > | snap->atomData.torque[i] += trq_tmp[i]; |
164 | > | |
165 | > | AtomCommVectorJ->scatter(snap->atomJData.torque, trq_tmp); |
166 | > | for (int i = 0; i < n; i++) |
167 | > | snap->atomData.torque[i] += trq_tmp[i]; |
168 | > | } |
169 | > | |
170 | > | // Still need pot! |
171 | > | |
172 | ||
173 | ||
174 | < | |
175 | < | ForceDecomposition::scatter(sbuffer, rbuffer){ |
176 | < | communicators(myIndex_).Reduce_scatter(sbuffer, recevbuf. recvcounts, MPI::DOUBLE, MPI::SUM); |
177 | < | } |
136 | < | |
137 | < | |
174 | > | #endif |
175 | > | } |
176 | > | |
177 | > | } //end namespace OpenMD |
– | Removed lines |
+ | Added lines |
< | Changed lines |
> | Changed lines |