1 #include <lifev/core/mesh/MeshColoring.hpp> 23 int numVertices = M_mesh->numGlobalVertices();
24 int numVolumes = M_mesh->numGlobalElements();
25 UInt numberLocalDof = 4;
27 M_nodesToVolumes.resize(numVertices);
28 M_volumesToNodes.resize(numVolumes);
29 M_numNeighbors.resize(numVertices);
31 for (
int i = 0; i < M_mesh->numElements(); ++i )
33 M_volumesToNodes[M_mesh->element(i).id()].resize(4);
34 for (
int j = 0; j < 4; ++j )
36 M_volumesToNodes[M_mesh->element(i).id()][j] = M_mesh->element(i).point(j).id();
37 M_nodesToVolumes[M_mesh->element(i).point(j).id()].push_back(M_mesh->element(i).id());
41 for (
int i = 0; i < numVertices; ++i )
43 M_numNeighbors[i] = M_nodesToVolumes[i].size();
46 std::vector<UInt>::iterator indexMaxNumNeighbors = std::max_element(M_numNeighbors.begin(), M_numNeighbors.end() );
47 M_indexNodeMaxNumNeighbors = std::distance(M_numNeighbors.begin(), indexMaxNumNeighbors);
48 M_maxNumNeighbors = M_numNeighbors[M_indexNodeMaxNumNeighbors];
55 M_volumesToVolumes.resize(numVolumes);
56 for (
int i = 0; i < M_mesh->numElements(); ++i )
58 for (
int j = 0; j < 4; ++j )
60 std::vector<UInt> volumes_tmp = M_nodesToVolumes[M_mesh->element(i).point(j).id()];
61 for (
int k = 0; k < volumes_tmp.size(); ++k )
63 M_volumesToVolumes[M_mesh->element(i).id()].push_back( volumes_tmp[k] );
66 std::sort( M_volumesToVolumes[M_mesh->element(i).id()].begin(), M_volumesToVolumes[M_mesh->element(i).id()].end() );
67 M_volumesToVolumes[M_mesh->element(i).id()].erase( unique( M_volumesToVolumes[M_mesh->element(i).id()].begin(),
68 M_volumesToVolumes[M_mesh->element(i).id()].end() ),
69 M_volumesToVolumes[M_mesh->element(i).id()].end() );
70 M_volumesToVolumes[M_mesh->element(i).id()].erase(std::remove(M_volumesToVolumes[M_mesh->element(i).id()].begin(),
71 M_volumesToVolumes[M_mesh->element(i).id()].end(),
72 M_mesh->element(i).id()),
73 M_volumesToVolumes[M_mesh->element(i).id()].end());
77 std::vector<
int> id_elem_scalar;
79 for (
int i = 0; i < M_mesh->numVolumes(); ++i )
81 id_elem_scalar.push_back ( M_mesh->element(i).id() );
84 int* pointerToDofs_scalar (0);
85 pointerToDofs_scalar = &id_elem_scalar[0];
86 std::shared_ptr<MapEpetra> map_scalar (
new MapEpetra ( -1,
static_cast<
int> (id_elem_scalar.size() ), pointerToDofs_scalar, M_comm ) );
88 M_vectorColors.reset (
new vector_Type ( *map_scalar, Unique ) );
89 M_vectorColors->zero();
95 M_colors.resize ( M_mesh->numGlobalElements() );
96 std::for_each ( M_colors.begin(), M_colors.end(), [] (
int&d) { d = -1.0;} );
100 M_colors[ M_nodesToVolumes[M_indexNodeMaxNumNeighbors][j] ] = j;
103 std::vector<
int> all_colors;
104 all_colors.resize(M_numColors);
105 std::iota (std::begin(all_colors), std::end(all_colors), 0);
107 for (
int k = 0; k < M_mesh->numElements(); ++k )
109 if ( M_colors[ M_mesh->element(k).id() ] == -1.0 )
111 std::vector<UInt> neigbors = M_volumesToVolumes[M_mesh->element(k).id()];
112 std::vector<
int> my_colors;
113 my_colors.resize(neigbors.size());
114 for (
int z = 0; z < neigbors.size(); ++z )
116 my_colors[z] = M_colors[neigbors[z]];
119 std::vector<
int> vector_diff;
120 std::sort (my_colors.begin(),my_colors.end());
121 std::set_difference (all_colors.begin(), all_colors.end(),
122 my_colors.begin(), my_colors.end(),
123 std::inserter(vector_diff, vector_diff.begin()) );
125 if ( vector_diff.size() == 0 )
127 M_numColors = M_numColors + 1;
128 M_colors[M_mesh->element(k).id()] = M_numColors-1;
129 all_colors.resize(M_numColors);
130 std::iota (std::begin(all_colors), std::end(all_colors), 0);
134 std::vector<
int>::iterator result = std::min_element(std::begin(vector_diff), std::end(vector_diff));
135 M_colors[M_mesh->element(k).id()] = vector_diff[std::distance(std::begin(vector_diff), result)];
141 for (
int i = 0; i < M_vectorColors->epetraVector().MyLength(); ++i )
143 (*M_vectorColors)[M_vectorColors->blockMap().GID(i)] = M_colors[M_vectorColors->blockMap().GID(i)];
150 M_colorsForAssembly.resize(M_numColors);
152 for (
int i = 0; i < M_vectorColors->epetraVector().MyLength(); ++i )
154 M_colorsForAssembly[ (*M_vectorColors)[M_vectorColors->blockMap().GID(i)] ].push_back(i);
161 for (
int i = 0; i < M_volumesToVolumes.size(); ++i )
163 std::cout <<
"\nElement " << i <<
" attached to elements " << std::flush;
164 for (
int j = 0; j < M_volumesToVolumes[i].size(); ++j )
166 std::cout << M_volumesToVolumes[i][j] <<
" ";
174 for (
int i = 0; i < M_nodesToVolumes.size(); ++i )
176 std::cout <<
"\nNode " << i <<
" attached to elements " << std::flush;
177 for (
int j = 0; j < M_nodesToVolumes[i].size(); ++j )
179 std::cout << M_nodesToVolumes[i][j] <<
" ";
187 for (
int i = 0; i < M_volumesToNodes.size(); ++i )
189 std::cout <<
"\nElement " << i <<
" has vertices " << std::flush;
190 for (
int j = 0; j < M_volumesToNodes[i].size(); ++j )
192 std::cout << M_volumesToNodes[i][j] <<
" ";
200 for (
int i = 0; i < M_numNeighbors.size(); ++i )
202 std::cout <<
"\nVertex " << i <<
" touches " << M_numNeighbors[i] <<
" elements " << std::endl;
208 for (
int i = 0; i < M_vectorColors->epetraVector().MyLength(); ++i )
210 std::cout <<
"\nElement " << M_vectorColors->blockMap().GID(i)
211 <<
" on proc ID " << M_comm->MyPID()
212 <<
" has color " << M_colors[M_vectorColors->blockMap().GID(i)]
222 for (
int k = 0; k < M_mesh->numVertices(); ++k )
224 std::vector<UInt> neigbors = M_nodesToVolumes[M_mesh->point(k).id()];
225 std::vector<
int> colors_neighbors;
226 for (
int z = 0; z < neigbors.size(); ++z )
228 colors_neighbors.push_back(M_colors[neigbors[z]]);
232 int size_initial = colors_neighbors.size();
233 std::sort( colors_neighbors.begin(), colors_neighbors.end() );
234 colors_neighbors.erase( unique( colors_neighbors.begin(), colors_neighbors.end() ), colors_neighbors.end() );
235 int size_after = colors_neighbors.size();
237 if ( size_after != size_initial )
240 std::cout <<
"\nInitial = " << size_initial <<
", after = " << size_after << std::endl;
241 std::cout <<
"\nError in coloring around vertex " << M_mesh->point(k).id() << std::endl;
249 for (
int i = 0; i < M_colorsForAssembly.size(); ++i )
251 if ( M_colorsForAssembly[i].size() > 0 )
253 std::cout <<
"\nColor " << i <<
" has elements with LID " << std::flush;
254 for (
int j = 0; j < M_colorsForAssembly[i].size(); ++j )
256 std::cout << M_colorsForAssembly[i][j] <<
" ";
258 std::cout << std::endl;
267 std::cout <<
"\nOn proc " << M_comm->MyPID() <<
" there are " << M_numColors <<
" colors\n";
271 for (
int k = 0; k < M_comm->NumProc(); ++k )
273 if ( M_comm->MyPID() == k )
275 for (
int i = 0; i < M_colorsForAssembly.size(); ++i )
277 if ( M_colorsForAssembly[i].size() > 0 )
279 std::cout <<
"\nColor " << i <<
" has elements " << M_colorsForAssembly[i].size() << std::endl;
std::shared_ptr< comm_Type > commPtr_Type
int performCheck()
Check if colors have been assigned correctly.
void printInfo()
Info about coloring.
void printVolumesToNodes()
Print volume to node connections.
void colorsForAssembly()
Vector of colors for the assembly.
void printNodesToVolumes()
Print node to volume connections.
void printColorsForAssembly()
Vector of colors used in the assembly.
void updateInverseJacobian(const UInt &iQuadPt)
void printVolumesToVolumes()
Print volume to volume connections.
~MeshColoring()
Destructor.
void setMesh(const meshPtr_Type &local_mesh)
Set the mesh.
MeshColoring(const commPtr_Type &communicator)
Empty Constructor.
std::shared_ptr< mesh_Type > meshPtr_Type
void setup()
Initial setup of the class.
void colorMesh()
Perform the coloring of the mesh.
void printColors()
Print vector of colors.
void printNumNeighbors()
Print number of element neighbors per node.
uint32_type UInt
generic unsigned integer (used mainly for addressing)
MeshData - class for coloring mesh.