ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/mpiSimulation.cpp
Revision: 378
Committed: Fri Mar 21 17:42:12 2003 UTC (21 years, 3 months ago) by mmeineke
File size: 4823 byte(s)
Log Message:
This commit was generated by cvs2svn to compensate for changes in r377,
which included commits to RCS files with non-trunk default branches.

File Contents

# Content
1 #ifdef IS_MPI
2
3 #include <cstdlib>
4 #include <cstring>
5 #include <mpi.h>
6 #include <mpi++.h>
7
8 #include "mpiSimulation.hpp"
9 #include "simError.h"
10 #include "fortranWrappers.hpp"
11
12
13
14
15 mpiSimulation* mpiSim;
16
17 mpiSimulation::mpiSimulation(SimInfo* the_entryPlug)
18 {
19 entryPlug = the_entryPlug;
20 mpiPlug = new mpiSimData;
21
22 mpiPlug->numberProcessors = MPI::COMM_WORLD.Get_size();
23 mpiPlug->myNode = worldRank;
24
25 mpiSim = this;
26 wrapMeSimParallel( this );
27 }
28
29
30 mpiSimulation::~mpiSimulation(){
31
32 delete mpiPlug;
33 // perhaps we should let fortran know the party is over.
34
35 }
36
37
38
39 int* mpiSimulation::divideLabor( void ){
40
41 int* globalIndex;
42
43 int nComponents;
44 MoleculeStamp** compStamps;
45 int* componentsNmol;
46
47 double numerator;
48 double denominator;
49 double precast;
50
51 int nTarget;
52 int molIndex, atomIndex, compIndex, compStart;
53 int done;
54 int nLocal, molLocal;
55 int i, index;
56 int smallDiff, bigDiff;
57
58 int testSum;
59
60 nComponents = entryPlug->nComponents;
61 compStamps = entryPlug->compStamps;
62 componentsNmol = entryPlug->componentsNmol;
63
64 mpiPlug->nAtomsGlobal = entryPlug->n_atoms;
65 mpiPlug->nBondsGlobal = entryPlug->n_bonds;
66 mpiPlug->nBendsGlobal = entryPlug->n_bends;
67 mpiPlug->nTorsionsGlobal = entryPlug->n_torsions;
68 mpiPlug->nSRIGlobal = entryPlug->n_SRI;
69 mpiPlug->nMolGlobal = entryPlug->n_mol;
70
71 numerator = (double) entryPlug->n_atoms;
72 denominator = (double) mpiPlug->numberProcessors;
73 precast = numerator / denominator;
74 nTarget = (int)( precast + 0.5 );
75
76 molIndex = 0;
77 atomIndex = 0;
78 compIndex = 0;
79 compStart = 0;
80 for( i=0; i<(mpiPlug->numberProcessors-1); i++){
81
82 done = 0;
83 nLocal = 0;
84 molLocal = 0;
85
86 if( i == mpiPlug->myNode ){
87 mpiPlug->myMolStart = molIndex;
88 mpiPlug->myAtomStart = atomIndex;
89 }
90
91 while( !done ){
92
93 if( (molIndex-compStart) >= componentsNmol[compIndex] ){
94 compStart = molIndex;
95 compIndex++;
96 continue;
97 }
98
99 nLocal += compStamps[compIndex]->getNAtoms();
100 atomIndex += compStamps[compIndex]->getNAtoms();
101 molIndex++;
102 molLocal++;
103
104 if ( nLocal == nTarget ) done = 1;
105
106 else if( nLocal < nTarget ){
107 smallDiff = nTarget - nLocal;
108 }
109 else if( nLocal > nTarget ){
110 bigDiff = nLocal - nTarget;
111
112 if( bigDiff < smallDiff ) done = 1;
113 else{
114 molIndex--;
115 molLocal--;
116 atomIndex -= compStamps[compIndex]->getNAtoms();
117 nLocal -= compStamps[compIndex]->getNAtoms();
118 done = 1;
119 }
120 }
121 }
122
123 if( i == mpiPlug->myNode ){
124 mpiPlug->myMolEnd = (molIndex - 1);
125 mpiPlug->myAtomEnd = (atomIndex - 1);
126 mpiPlug->myNlocal = nLocal;
127 mpiPlug->myMol = molLocal;
128 }
129
130 numerator = (double)( entryPlug->n_atoms - atomIndex );
131 denominator = (double)( mpiPlug->numberProcessors - (i+1) );
132 precast = numerator / denominator;
133 nTarget = (int)( precast + 0.5 );
134 }
135
136 if( mpiPlug->myNode == mpiPlug->numberProcessors-1 ){
137 mpiPlug->myMolStart = molIndex;
138 mpiPlug->myAtomStart = atomIndex;
139
140 nLocal = 0;
141 molLocal = 0;
142 while( compIndex < nComponents ){
143
144 if( (molIndex-compStart) >= componentsNmol[compIndex] ){
145 compStart = molIndex;
146 compIndex++;
147 continue;
148 }
149
150 nLocal += compStamps[compIndex]->getNAtoms();
151 atomIndex += compStamps[compIndex]->getNAtoms();
152 molIndex++;
153 molLocal++;
154 }
155
156 mpiPlug->myMolEnd = (molIndex - 1);
157 mpiPlug->myAtomEnd = (atomIndex - 1);
158 mpiPlug->myNlocal = nLocal;
159 mpiPlug->myMol = molLocal;
160 }
161
162
163 MPI_Allreduce( &nLocal, &testSum, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD );
164
165 if( mpiPlug->myNode == 0 ){
166 if( testSum != entryPlug->n_atoms ){
167 sprintf( painCave.errMsg,
168 "The summ of all nLocals, %d, did not equal the total number of atoms, %d.\n",
169 testSum, entryPlug->n_atoms );
170 painCave.isFatal = 1;
171 simError();
172 }
173 }
174
175 sprintf( checkPointMsg,
176 "Successfully divided the molecules among the processors.\n" );
177 MPIcheckPoint();
178
179 // lets create the identity array
180
181 globalIndex = new int[mpiPlug->myNlocal];
182 index = mpiPlug->myAtomStart;
183 for( i=0; i<mpiPlug->myNlocal; i++){
184 globalIndex[i] = index;
185 index++;
186 }
187
188 return globalIndex;
189 }
190
191
192 void mpiSimulation::mpiRefresh( void ){
193
194 int isError, i;
195 int *globalIndex = new int[mpiPlug->myNlocal];
196
197 for(i=0; i<mpiPlug->myNlocal; i++) globalIndex[i] = entryPlug->atoms[i]->getGlobalIndex();
198
199
200 isError = 0;
201 setFsimParallel( mpiPlug, &(entryPlug->n_atoms), globalIndex, &isError );
202 if( isError ){
203
204 sprintf( painCave.errMsg,
205 "mpiRefresh errror: fortran didn't like something we gave it.\n" );
206 painCave.isFatal = 1;
207 simError();
208 }
209
210 delete[] globalIndex;
211
212 sprintf( checkPointMsg,
213 " mpiRefresh successful.\n" );
214 MPIcheckPoint();
215 }
216
217
218 #endif // is_mpi