108 lines
2.7 KiB
C++
108 lines
2.7 KiB
C++
// MPI code in C++.
|
|
// See [Gropp/Lusk/Skjellum, "Using MPI", p.33/41 etc.]
|
|
// and /opt/mpich/include/mpi2c++/comm.h for details
|
|
|
|
#include "geom.h"
|
|
#include "par_geom.h"
|
|
#include "vdop.h"
|
|
|
|
#include <cassert>
|
|
#include <cmath>
|
|
#include <iostream>
|
|
#include <mpi.h> // MPI
|
|
//#include <omp.h> // OpenMP, for E9 it is not necessary
|
|
using namespace std;
|
|
|
|
|
|
int main(int argc, char **argv )
|
|
{
|
|
MPI_Init(&argc, &argv);
|
|
MPI_Comm const icomm(MPI_COMM_WORLD);
|
|
//omp_set_num_threads(1); // don't use OMP parallelization for a start
|
|
//
|
|
{
|
|
int np;
|
|
MPI_Comm_size(icomm, &np);
|
|
|
|
assert(4 == np); // example is only provided for 4 MPI processes
|
|
}
|
|
// #####################################################################
|
|
// ---- Read the f.e. mesh and the mapping of elements to MPI processes
|
|
//Mesh const mesh_c("square_4.txt"); // Files square_4.txt and square_4_sd.txt are needed
|
|
ParMesh const mesh("square",icomm);
|
|
|
|
int const numprocs = mesh.NumProcs();
|
|
int const myrank = mesh.MyRank();
|
|
if ( 0 == myrank ) {
|
|
cout << "\n There are " << numprocs << " processes running.\n \n";
|
|
}
|
|
|
|
int const check_rank=0; // choose the MPI process you would like to check the mesh
|
|
//if ( check_rank == myrank ) mesh.Debug();
|
|
//if ( check_rank == myrank ) mesh.DebugEdgeBased();
|
|
|
|
// ---- allocate local vectors and check skalar product and vector accumulation
|
|
vector<double> xl(mesh.Nnodes(), 1.0);
|
|
mesh.SetValues(xl, [](double x, double y) -> double {return x * x * std::sin(2.5 * M_PI * y);} );
|
|
|
|
//E9
|
|
if (myrank == check_rank){
|
|
cout << "E9" << endl;
|
|
}
|
|
|
|
double ss = mesh.dscapr(xl,xl);
|
|
if (myrank == check_rank){
|
|
cout << myrank << " : scalar : " << ss << endl << endl;
|
|
}
|
|
|
|
mesh.VecAccu(xl);
|
|
|
|
//E10
|
|
if (myrank == check_rank){
|
|
cout << "E10" << endl;
|
|
}
|
|
vector<int> xl_int(mesh.Nnodes(), 1);
|
|
|
|
// check accumulation (by console output)
|
|
mesh.VecAccu(xl_int);
|
|
|
|
vector<double> coords = mesh.GetCoords();
|
|
if (check_rank == myrank){
|
|
for (size_t i = 0; i < coords.size(); i += 2){
|
|
cout << "(" << coords[i] << ", " << coords[i + 1] << "):\t" << xl_int[i/2] << endl;
|
|
}
|
|
}
|
|
|
|
//E11
|
|
if (myrank == check_rank){
|
|
cout << "E11" << endl;
|
|
}
|
|
int global_nodes = mesh.GlobalNodes();
|
|
if (check_rank == myrank){
|
|
cout << "Global nodes: " << global_nodes << endl;
|
|
}
|
|
|
|
//E12
|
|
if (myrank == check_rank){
|
|
cout << "E12" << endl;
|
|
}
|
|
vector<double> xl_new(mesh.Nnodes(), 1.0);
|
|
|
|
mesh.Average(xl_new);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MPI_Finalize();
|
|
return 0;
|
|
}
|
|
|
|
|