Newer
Older
MpiSimulation::MpiSimulation(int& argc, char**& argv) {
//number of (array) elements in struct elements
//dataytypes with lower bound and upper bound adresses of the structure
MPI::Datatype datatypes[7] = {MPI::LB, MPI::DOUBLE, MPI::DOUBLE, MPI::DOUBLE, MPI::DOUBLE, MPI::BOOL, MPI::UB};
MPI::Aint displacements[7];
this->mpiSize = MPI::COMM_WORLD.Get_size();
this->mpiRank = MPI::COMM_WORLD.Get_rank();
float log2 = logf(this->mpiSize) / logf(2.0f);
if (ceilf(log2) != log2 || floorf(log2) != log2) {
cerr << "number of processes needs to be a power of two" << endl;
MPI::Finalize();
exit(-1);
}
//displacements are calculated from the start of the structure
displacements[0] = MPI::Get_address(&(b[0])) - MPI::Get_address(&(b[0]));
displacements[1] = MPI::Get_address(&(b[0].position[0])) - MPI::Get_address(&(b[0]));
displacements[2] = MPI::Get_address(&(b[0].velocity[0])) - MPI::Get_address(&(b[0]));
displacements[3] = MPI::Get_address(&(b[0].acceleration[0])) - MPI::Get_address(&(b[0]));
displacements[4] = MPI::Get_address(&(b[0].mass)) - MPI::Get_address(&(b[0]));
displacements[5] = MPI::Get_address(&(b[0].refinement)) - MPI::Get_address(&(b[0]));
displacements[6] = MPI::Get_address(&(b[1])) - MPI::Get_address(&(b[0]));
this->bodyType = this->bodyType.Create_struct(7, blocklengths, displacements, datatypes);
this->bodyType.Commit();
if (this->mpiRank == 0) {
if (argc != 2) {
this->correctState = false;
} else {
this->bodies = Tree::dubinskiParse(string(argv[1]));
}
}
}
MPI::COMM_WORLD.Bcast(&this->correctState, 1, MPI::BOOL, 0);
if (!this->correctState) {
cerr << "Error occurred: terminating ..." << endl;
this->bodyType.Free();
MPI::Finalize();
exit(-1);
}
}
void MpiSimulation::cleanup() {
while (!this->comms.empty()) {
this->comms.back().cleanup();
this->comms.pop_back();
}
bool MpiSimulation::stateCorrect() {
return this->correctState;
int MpiSimulation::getNumberOfProcesses() {
return this->mpiSize;
}
int MpiSimulation::getProcessId() {
return this->mpiRank;
}
void MpiSimulation::distributeBodies() {
this->comms.push_back(MpiBodyComm(&this->bodyType));
if (this->mpiRank == 0) {
Box bb;
vector<Box> domains;
vector<MpiBodyComm>::iterator it;
bb.extendForBodies(this->bodies);
bb.extendToCube();
domains = bb.octreeSplit();
for (int i = 1; i < this->mpiSize; i++) {
vector<Body> toSend = domains[i].extractBodies(this->bodies);
it = this->comms.begin();
while (!it->sendUnblocking(i, toSend) && it != this->comms.end()) it++;
if (it == this->comms.end()) {
this->comms.push_back(MpiBodyComm(&this->bodyType));
this->comms.back().sendUnblocking(i, toSend);
}
}
} else {
this->comms[0].recvBlocking(0, this->bodies);
}
}