MeshPartitioner.cc 3.42 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//
// Software License for AMDiS
//
// Copyright (c) 2010 Dresden University of Technology 
// All rights reserved.
// Authors: Simon Vey, Thomas Witkowski et al.
//
// This file is part of AMDiS
//
// See also license.opensource.txt in the distribution.


#include "parallel/MeshPartitioner.h"
#include "Mesh.h"
#include "Traverse.h"
#include "Serializer.h"

namespace AMDiS {

  void MeshPartitioner::createInitialPartitioning() 
  {
    FUNCNAME("MeshPartitioner::createInitialPartitioning()");

    int mpiRank = mpiComm->Get_rank();
    int mpiSize = mpiComm->Get_size();
    int nLeaves = mesh->getNumberOfLeaves();
    int elPerRank = nLeaves / mpiSize;

    // === Create initial partitioning of the AMDiS mesh. ===

    elementInRank.clear();
Thomas Witkowski's avatar
Thomas Witkowski committed
32
    map<DofEdge, set<int> > vertexElements;
33
34

    TraverseStack stack;
35
36
    ElInfo *elInfo = 
      stack.traverseFirst(mesh, 0, 
Thomas Witkowski's avatar
Thomas Witkowski committed
37
			  Mesh::CALL_EL_LEVEL | Mesh::FILL_NEIGH | Mesh::FILL_COORDS |  Mesh::FILL_BOUND);
38
    while (elInfo) {
Thomas Witkowski's avatar
Thomas Witkowski committed
39
40
      Element *el = elInfo->getElement();
      int elIndex = el->getIndex();
41

42
43
44
      for (int i = 0; i < mesh->getGeo(NEIGH); i++)
	if (elInfo->getNeighbour(i) && elInfo->getBoundary(i) == INTERIOR) 
	  elNeighbours[elIndex].push_back(elInfo->getNeighbour(i)->getIndex());
Thomas Witkowski's avatar
Thomas Witkowski committed
45
46
47
48
49
50
51
52
53
54

      if (boxPartitioning) {
	vertexElements[el->getEdge(0)].insert(elIndex);
      } else {
	int elInRank = std::min(elIndex / elPerRank, mpiSize - 1);
	
	elementInRank[elIndex] = (elInRank == mpiRank);
	partitionMap[elIndex] = elInRank;	
      }

55
56
57
      
      elInfo = stack.traverseNext(elInfo);
    }
Thomas Witkowski's avatar
Thomas Witkowski committed
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104



    if (boxPartitioning) {
      TEST_EXIT(mesh->getDim() == 3)("Box partitioning only implemented for 3D!\n");

      int boxCounter = 0;
      for (map<DofEdge, set<int> >::iterator it = vertexElements.begin();
	   it != vertexElements.end(); ++it) {
	TEST_EXIT_DBG(it->second.size() == 6)("Should not happen!\n");
	
	boxSplitting[boxCounter] = it->second;

	for (set<int>::iterator elIt = it->second.begin();
	     elIt != it->second.end(); ++elIt)
	  elInBox[*elIt] = boxCounter;

	boxCounter++;
      }

      for (map<int, int>::iterator it = elInBox.begin(); it != elInBox.end(); ++it) {
	int elBoxNo = it->second;

	for (vector<int>::iterator neighIt = elNeighbours[it->first].begin();
	     neighIt != elNeighbours[it->first].end(); ++neighIt) {
	  int neighBoxNo = elInBox[*neighIt];

	  if (elBoxNo != neighBoxNo)
	    boxNeighbours[elBoxNo].insert(neighBoxNo);
	}
      }

      MSG("Box partitioning with %d boxes enabled!\n", boxCounter);

      int boxPerRank = boxCounter / mpiSize;

      for (map<int, set<int> >::iterator it = boxSplitting.begin();
	   it != boxSplitting.end(); ++it) {
	int boxInRank = std::min(it->first / boxPerRank, mpiSize - 1);

	for (set<int>::iterator elIt = it->second.begin();
	     elIt != it->second.end(); ++elIt) {
	  elementInRank[*elIt] = (boxInRank == mpiRank);
	  partitionMap[*elIt] = boxInRank;
	}
      }
    }
105
106
107
108
109
110
  }


  void MeshPartitioner::serialize(std::ostream &out)
  {
    SerUtil::serialize(out, elementInRank);
Thomas Witkowski's avatar
Thomas Witkowski committed
111
112
113
114
    SerUtil::serialize(out, boxPartitioning);
    SerUtil::serialize(out, boxSplitting);
    SerUtil::serialize(out, boxNeighbours);
    SerUtil::serialize(out, elInBox);
115
116
117
118
119
120
  }


  void MeshPartitioner::deserialize(std::istream &in)
  {
    SerUtil::deserialize(in, elementInRank);
Thomas Witkowski's avatar
Thomas Witkowski committed
121
122
123
124
    SerUtil::deserialize(in, boxPartitioning);
    SerUtil::deserialize(in, boxSplitting);
    SerUtil::deserialize(in, boxNeighbours);
    SerUtil::deserialize(in, elInBox);
125
126
127
  }

}