00001 #include "DAPTA.hpp"
00002
00003 #include <vector>
00004
00005 namespace DAPTA {
00006
00007 template <typename Traits>
00008 MeshParalleliser<Traits>::MeshParalleliser(MPI_Comm _comm, Mesh<Traits> *_mesh)
00009 : communicator(_comm), mesh(_mesh) {
00010 assert(_comm != MPI_COMM_NULL);
00011 assert(_mesh != NULL);
00012 decomposer = new DomainDecomposerType();
00013
00014 std::vector<VertexHandle> elemCentres = mesh->GetCentres();
00015 decomposer->loadVertices(elemCentres);
00016 int numProcs, myRank;
00017 MPI_Comm_size(communicator, &numProcs);
00018 MPI_Comm_rank(communicator, &myRank);
00019
00020 std::vector<int> myElems = decomposer->decompose(numProcs, myRank);
00021
00022 mesh->SetActive(myElems);
00023 mesh->newPrefix = (myRank+1);
00024
00025
00026 }
00027
00028 template <typename Traits>
00029 MeshParalleliser<Traits>::~MeshParalleliser() {
00030 delete coupler;
00031 delete exchanger;
00032 delete decomposer;
00033 }
00034
00035 template <typename Traits>
00036 void MeshParalleliser<Traits>::initialiseCommunication() {
00037 std::set<EdgeElementType> tmpEdgesSet;
00038 for(typename Mesh<Traits>::ElementMapIterator e_iter=mesh->ElementMapBegin(); e_iter!=mesh->ElementMapEnd(); ++e_iter) {
00039 std::vector<EdgeElementType> edges_vec=(*e_iter)->GetAllEdges();
00040 std::copy(edges_vec.begin(), edges_vec.end(), std::inserter(tmpEdgesSet, tmpEdgesSet.end()));
00041 }
00042 std::copy(tmpEdgesSet.begin(), tmpEdgesSet.end(), std::back_inserter(edgesConnected));
00043
00044 std::set<VertexHandle> tmpVertexSet(mesh->VertexMapBegin(), mesh->VertexMapEnd());
00045 verticesConnected.reserve(tmpVertexSet.size());
00046 std::copy(tmpVertexSet.begin(), tmpVertexSet.end(), std::back_inserter(verticesConnected));
00047
00048 std::vector<typename VertexType::CoordType> coordinates;
00049 for(typename Mesh<Traits>::VertexMapIterator v_iter=mesh->VertexMapBegin(); v_iter!=mesh->VertexMapEnd(); ++v_iter) {
00050 std::copy((*v_iter)->coords.begin(), (*v_iter)->coords.end(), std::back_inserter(coordinates));
00051 }
00052
00053 coupler = new pico::DomainCoupler<VertexType>(communicator);
00054 coupler->registerSubDomain(pico::RED, &(coordinates[0]), coordinates.size()/VertexType::dimension, 0.0);
00055 coupler->prepareCommunicationsIntra(pico::RED);
00056
00057 std::vector<int> globalIDs;
00058 globalIDs.reserve(verticesConnected.size());
00059 std::transform(verticesConnected.begin(), verticesConnected.end(), std::back_inserter(globalIDs), GetID<VertexType>());
00060
00061 exchanger = new pico::FieldExchanger<VertexType>(coupler, globalIDs.begin(), globalIDs.size());
00062 }
00063
00064 template <typename Traits>
00065 void MeshParalleliser<Traits>::exchange() {
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 int pad_size=8;
00080 std::vector<int> link_states;
00081 link_states.reserve(edgesConnected.size() * pad_size);
00082
00083 for(_EdgeIt edge_iter=edgesConnected.begin(); edge_iter!=edgesConnected.end(); ++edge_iter) {
00084 mesh->edges[*edge_iter]->GetLinkStateArray(std::back_inserter(link_states));
00085
00086 for(int i=0; i<(pad_size-mesh->edges[*edge_iter]->size()); i++) {
00087 link_states.push_back(0);
00088 }
00089 }
00090
00091 exchanger->template exchange<8, int, LinkStateJoin>(&(link_states[0]), link_states.size());
00092
00093 int i=0;
00094 for(_EdgeIt edge_iter=edgesConnected.begin(); edge_iter!=edgesConnected.end(); ++edge_iter) {
00095 mesh->edges[*edge_iter]->SetLinkStateArray(link_states.begin()+(i*pad_size));
00096 i++;
00097 }
00098 }
00099
00100 }