1 |
|
2 |
/* $Id$ */ |
3 |
|
4 |
/******************************************************* |
5 |
* |
6 |
* Copyright 2003-2007 by ACceSS MNRF |
7 |
* Copyright 2007 by University of Queensland |
8 |
* |
9 |
* http://esscc.uq.edu.au |
10 |
* Primary Business: Queensland, Australia |
11 |
* Licensed under the Open Software License version 3.0 |
12 |
* http://www.opensource.org/licenses/osl-3.0.php |
13 |
* |
14 |
*******************************************************/ |
15 |
|
16 |
/**************************************************************/ |
17 |
|
18 |
/* Finley: Mesh: prepares the mesh for further calculations */ |
19 |
|
20 |
/**************************************************************/ |
21 |
|
22 |
#include "Mesh.h" |
23 |
|
24 |
/**************************************************************/ |
25 |
|
26 |
void Finley_Mesh_prepare(Finley_Mesh* in, bool_t optimize) { |
27 |
dim_t newGlobalNumDOFs=0, numReducedNodes=0,i; |
28 |
index_t* distribution=NULL, *maskReducedNodes=NULL, *indexReducedNodes=NULL, *node_distribution=NULL; |
29 |
if (in==NULL) return; |
30 |
if (in->Nodes == NULL) return; |
31 |
|
32 |
/* first step is to distribute the elements according to a global distribution of DOF */ |
33 |
|
34 |
distribution=TMPMEMALLOC(in->MPIInfo->size+1,index_t); |
35 |
node_distribution=TMPMEMALLOC(in->MPIInfo->size+1,index_t); |
36 |
if (! (Finley_checkPtr(distribution) || Finley_checkPtr(node_distribution))) { |
37 |
/* first we create dense labeling for the DOFs */ |
38 |
newGlobalNumDOFs=Finley_NodeFile_createDenseDOFLabeling(in->Nodes); |
39 |
|
40 |
/* create a distribution of the global DOFs and determine |
41 |
the MPI_rank controling the DOFs on this processor */ |
42 |
Paso_MPIInfo_setDistribution(in->MPIInfo,0,newGlobalNumDOFs-1,distribution); |
43 |
|
44 |
/* now the mesh is re-distributed according to the mpiRankOfDOF vector */ |
45 |
/* this will redistribute the Nodes and Elements including overlap and will create an element coloring |
46 |
but will not create any mappings (see later in this function) */ |
47 |
if (Finley_noError()) Finley_Mesh_distributeByRankOfDOF(in,distribution); |
48 |
} |
49 |
|
50 |
/* at this stage we are able to start an optimization of the DOF distribution using ParaMetis */ |
51 |
/* on return distribution is altered and new DOF ids have been assigned */ |
52 |
if (Finley_noError() && optimize && in->MPIInfo->size>1) { |
53 |
|
54 |
Finley_Mesh_optimizeDOFDistribution(in,distribution); |
55 |
|
56 |
if (Finley_noError()) Finley_Mesh_distributeByRankOfDOF(in,distribution); |
57 |
|
58 |
} |
59 |
/* now a local labeling of the DOF is introduced */ |
60 |
if (Finley_noError() && optimize) { |
61 |
Finley_Mesh_optimizeDOFLabeling(in,distribution); |
62 |
} |
63 |
/* rearrange elements with the attempt to bring elements closer to memory locations of the nodes (distributed shared memory!): */ |
64 |
if (Finley_noError()) Finley_Mesh_optimizeElementOrdering(in); |
65 |
|
66 |
|
67 |
/* create the global indices */ |
68 |
if (Finley_noError()) { |
69 |
maskReducedNodes=TMPMEMALLOC(in->Nodes->numNodes,index_t); |
70 |
indexReducedNodes=TMPMEMALLOC(in->Nodes->numNodes,index_t); |
71 |
if (! ( Finley_checkPtr(maskReducedNodes) || Finley_checkPtr(indexReducedNodes) ) ) { |
72 |
|
73 |
#pragma omp parallel for private(i) schedule(static) |
74 |
for (i=0;i<in->Nodes->numNodes;++i) maskReducedNodes[i]=-1; |
75 |
|
76 |
Finley_Mesh_markNodes(maskReducedNodes,0,in,1); |
77 |
|
78 |
numReducedNodes=Finley_Util_packMask(in->Nodes->numNodes,maskReducedNodes,indexReducedNodes); |
79 |
|
80 |
Finley_NodeFile_createDenseNodeLabeling(in->Nodes, node_distribution, distribution); |
81 |
|
82 |
Finley_NodeFile_createDenseReducedDOFLabeling(in->Nodes,maskReducedNodes); |
83 |
Finley_NodeFile_createDenseReducedNodeLabeling(in->Nodes,maskReducedNodes); |
84 |
/* create the missing mappings */ |
85 |
if (Finley_noError()) Finley_Mesh_createNodeFileMappings(in,numReducedNodes,indexReducedNodes,distribution, node_distribution); |
86 |
} |
87 |
|
88 |
TMPMEMFREE(maskReducedNodes); |
89 |
TMPMEMFREE(indexReducedNodes); |
90 |
} |
91 |
|
92 |
TMPMEMFREE(distribution); |
93 |
TMPMEMFREE(node_distribution); |
94 |
|
95 |
Finley_Mesh_setTagsInUse(in); |
96 |
|
97 |
return; |
98 |
} |
99 |
|
100 |
/* */ |
101 |
/* tries to reduce the coloring for all element files: */ |
102 |
/* */ |
103 |
void Finley_Mesh_createColoring(Finley_Mesh* in, index_t *node_localDOF_map) { |
104 |
if (Finley_noError()) Finley_ElementFile_createColoring(in->Elements,in->Nodes->numNodes,node_localDOF_map); |
105 |
if (Finley_noError()) Finley_ElementFile_createColoring(in->FaceElements,in->Nodes->numNodes,node_localDOF_map); |
106 |
if (Finley_noError()) Finley_ElementFile_createColoring(in->Points,in->Nodes->numNodes,node_localDOF_map); |
107 |
if (Finley_noError()) Finley_ElementFile_createColoring(in->ContactElements,in->Nodes->numNodes,node_localDOF_map); |
108 |
} |
109 |
/* */ |
110 |
/* redistribute elements to minimize communication during assemblage */ |
111 |
/* */ |
112 |
void Finley_Mesh_optimizeElementOrdering(Finley_Mesh* in) { |
113 |
if (Finley_noError()) Finley_ElementFile_optimizeOrdering(&(in->Elements)); |
114 |
if (Finley_noError()) Finley_ElementFile_optimizeOrdering(&(in->FaceElements)); |
115 |
if (Finley_noError()) Finley_ElementFile_optimizeOrdering(&(in->Points)); |
116 |
if (Finley_noError()) Finley_ElementFile_optimizeOrdering(&(in->ContactElements)); |
117 |
} |
118 |
|
119 |
/* */ |
120 |
/* redistribute elements to minimize communication during assemblage */ |
121 |
void Finley_Mesh_setTagsInUse(Finley_Mesh* in) |
122 |
{ |
123 |
if (Finley_noError()) Finley_NodeFile_setTagsInUse(in->Nodes); |
124 |
if (Finley_noError()) Finley_ElementFile_setTagsInUse(in->Elements); |
125 |
if (Finley_noError()) Finley_ElementFile_setTagsInUse(in->FaceElements); |
126 |
if (Finley_noError()) Finley_ElementFile_setTagsInUse(in->Points); |
127 |
if (Finley_noError()) Finley_ElementFile_setTagsInUse(in->ContactElements); |
128 |
} |