ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE_old/src/mdtools/libmdCode/mpiSimulation.cpp
Revision: 294
Committed: Thu Mar 6 17:04:09 2003 UTC (21 years, 4 months ago) by mmeineke
File size: 4791 byte(s)
Log Message:
finished conversion of all function wrapping into fortranWrappers.cpp and .hpp respectively

File Contents

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