ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/mpiSimulation.cpp
Revision: 377
Committed: Fri Mar 21 17:42:12 2003 UTC (21 years, 3 months ago) by mmeineke
Original Path: branches/mmeineke/OOPSE/libmdtools/mpiSimulation.cpp
File size: 4823 byte(s)
Log Message:
New OOPSE Tree

File Contents

# User Rev Content
1 mmeineke 377 #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