/[escript]/trunk/finley/src/Mesh_prepareNodes.c
ViewVC logotype

Contents of /trunk/finley/src/Mesh_prepareNodes.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 964 - (show annotations)
Tue Feb 13 05:10:26 2007 UTC (12 years, 11 months ago) by gross
File MIME type: text/plain
File size: 12457 byte(s)
The set/getRefVal functions of Data objects have been removed (mainly to avoid later problems with MPI).
Moreover, a faster access to the reference id of samples has been introduced. I don't think that anybody will
profit form this at this stage but it will allow a faster dump of data objects.


1 /*
2 ************************************************************
3 * Copyright 2006 by ACcESS MNRF *
4 * *
5 * http://www.access.edu.au *
6 * Primary Business: Queensland, Australia *
7 * Licensed under the Open Software License version 3.0 *
8 * http://www.opensource.org/licenses/osl-3.0.php *
9 * *
10 ************************************************************
11 */
12
13 /**************************************************************/
14
15 /* Finley: Mesh */
16 /* prepare nodes does */
17
18 /* - creates a dense labeling of degressOfFreedom */
19 /* - creates/overwrites in->Nodes->reducedDegressOfFreedom */
20 /* - creates/overwrites in->Nodes->reducedTo */
21
22 /**************************************************************/
23
24 /* Author: gross@access.edu.au */
25 /* Version: $Id$ */
26
27 /**************************************************************/
28
29 #include "Mesh.h"
30 #include "Util.h"
31
32 /**************************************************************/
33
34 void Finley_Mesh_prepareNodes(Finley_Mesh* in) {
35 dim_t n,len;
36 index_t id,max_id,min_id,*maskReducedDOF=NULL,*maskDOF=NULL,*reducedNodesMask=NULL,*index=NULL;
37 #ifdef PASO_MPI
38 index_t *maskDOFLocation=NULL, *indexLocal=NULL, *maskReducedDOFLocation=NULL, *mask=NULL;
39 index_t thisDom = in->MPIInfo->rank, i, iI, iB, iE;
40 dim_t bufferLength=0, numInternal, numBoundary, numExternal, numLocal, numReducedLocal, numReducedInternal, numReducedBoundary, numReducedExternal, numForward, numBackward, totalDOF;
41 Finley_NodeDistribution *distribution=NULL;
42
43 #endif
44
45 /* TODO */
46 /* this is ok for the automatically generated rectangular meshes, but for arbitrary meshes it
47 may be neccesary to make sure that
48 - the [internal][boundary][external] ordering is respected
49 - the distribution data in Nodes->degreeOfFreedomDistribution reflects any changes in the
50 DOF ordering. */
51
52 max_id=Finley_Util_getMaxInt(1,in->Nodes->numNodes,in->Nodes->degreeOfFreedom);
53 min_id=Finley_Util_getMinInt(1,in->Nodes->numNodes,in->Nodes->degreeOfFreedom);
54 len=max_id-min_id+1;
55
56 reducedNodesMask=TMPMEMALLOC(in->Nodes->numNodes,index_t);
57 maskDOF=TMPMEMALLOC(len,index_t);
58 maskReducedDOF=TMPMEMALLOC(len,index_t);
59 index=TMPMEMALLOC(MAX(in->Nodes->numNodes,len),index_t);
60 if (! (Finley_checkPtr(maskDOF) || Finley_checkPtr(maskReducedDOF)
61 || Finley_checkPtr(reducedNodesMask) || Finley_checkPtr(index) ) ) {
62 /* initialize everything */
63 #pragma omp parallel
64 {
65 #pragma omp for private(n) schedule(static)
66 for (n=0;n<in->Nodes->numNodes;n++) {
67 in->Nodes->toReduced[n]=-1;
68 in->Nodes->reducedDegreeOfFreedom[n]=-1;
69 reducedNodesMask[n]=-1;
70 }
71 #pragma omp for private(n) schedule(static)
72 for (n=0;n<len;n++) {
73 maskDOF[n]=-1;
74 maskReducedDOF[n]=-1;
75 }
76 }
77 /* mark all nodes used by reduced elements */
78 Finley_Mesh_markNodes(reducedNodesMask,0,in,TRUE);
79
80 /* mark used degrees of freedom */
81 /* OMP */
82 for (n=0;n<in->Nodes->numNodes;n++) {
83 id=in->Nodes->degreeOfFreedom[n]-min_id;
84 maskDOF[id]=1;
85 if (reducedNodesMask[n]>=0) maskReducedDOF[id]=1;
86 }
87 /* get a list of all nodes used in the reduced mesh and convert into in->Nodes->toReduced: */
88 in->Nodes->reducedNumNodes=Finley_Util_packMask(in->Nodes->numNodes,reducedNodesMask,index);
89
90 #pragma omp parallel for private(n) schedule(static)
91 for (n=0;n<in->Nodes->reducedNumNodes;n++)
92 in->Nodes->toReduced[index[n]]=n;
93
94 /* get a list of the DOFs in the reduced mesh and convert it into reducedDegreeOfFreedom */
95 in->Nodes->reducedNumDegreesOfFreedom=Finley_Util_packMask(len,maskReducedDOF,index);
96 MEMFREE(in->Nodes->reducedDegreeOfFreedomId);
97 in->Nodes->reducedDegreeOfFreedomId=MEMALLOC(in->Nodes->reducedNumDegreesOfFreedom,index_t);
98 if (! Finley_checkPtr(in->Nodes->reducedDegreeOfFreedomId) ) {
99 #pragma omp parallel for private(n) schedule(static)
100 for (n=0;n<in->Nodes->reducedNumDegreesOfFreedom;n++) {
101 maskReducedDOF[index[n]]=n;
102 in->Nodes->reducedDegreeOfFreedomId[n] = in->Nodes->Id[index[n]];
103 }
104
105 /* get a list of the DOFs and convert it into degreeOfFreedom */
106 in->Nodes->numDegreesOfFreedom=Finley_Util_packMask(len,maskDOF,index);
107 MEMFREE(in->Nodes->degreeOfFreedomId);
108 in->Nodes->degreeOfFreedomId=MEMALLOC(in->Nodes->numDegreesOfFreedom,index_t);
109 if (! Finley_checkPtr(in->Nodes->degreeOfFreedomId)) {
110 #pragma omp parallel
111 {
112 #pragma omp for private(n) schedule(static)
113 for (n=0;n<in->Nodes->numDegreesOfFreedom;n++) {
114 maskDOF[index[n]]=n;
115 in->Nodes->degreeOfFreedomId[n]=in->Nodes->Id[index[n]];
116 }
117 #pragma omp for private(n,id) schedule(static)
118 for (n=0;n<in->Nodes->numNodes;n++) {
119 id=in->Nodes->degreeOfFreedom[n]-min_id;
120 in->Nodes->degreeOfFreedom[n]=maskDOF[id];
121 in->Nodes->reducedDegreeOfFreedom[n]=maskReducedDOF[id];
122 }
123 }
124 }
125 }
126 }
127
128 #ifdef PASO_MPI
129 /***********************************************************
130 update the distribution data
131 ***********************************************************/
132
133 in->Nodes->degreeOfFreedomDistribution->numInternal = 0;
134 in->Nodes->degreeOfFreedomDistribution->numBoundary = 0;
135 in->Nodes->degreeOfFreedomDistribution->numExternal = 0;
136 mask = MEMALLOC(in->Nodes->numDegreesOfFreedom,index_t);
137 for( i=0; i<in->Nodes->numNodes; i++ )
138 mask[in->Nodes->degreeOfFreedom[i]] = in->Nodes->Dom[i];
139 for( i=0; i<in->Nodes->numDegreesOfFreedom; i++ )
140 switch( mask[i] ){
141 case NODE_INTERNAL :
142 in->Nodes->degreeOfFreedomDistribution->numInternal++;
143 break;
144 case NODE_BOUNDARY :
145 in->Nodes->degreeOfFreedomDistribution->numBoundary++;
146 break;
147 case NODE_EXTERNAL :
148 in->Nodes->degreeOfFreedomDistribution->numExternal++;
149 break;
150 }
151
152 in->Nodes->degreeOfFreedomDistribution->numLocal = in->Nodes->degreeOfFreedomDistribution->numInternal + in->Nodes->degreeOfFreedomDistribution->numBoundary;
153
154 /* reform the vtxdist */
155 distribution = in->Nodes->degreeOfFreedomDistribution;
156
157 MPI_Allgather( &distribution->numLocal, 1, MPI_INT, distribution->vtxdist+1, 1, MPI_INT, in->MPIInfo->comm );
158
159 distribution->vtxdist[0] = 0;
160 for( i=2; i<in->MPIInfo->size+1; i++ )
161 distribution->vtxdist[i] += distribution->vtxdist[i-1];
162
163 MPI_Allreduce( &distribution->numLocal, &distribution->numGlobal, 1, MPI_INT, MPI_SUM, in->MPIInfo->comm );
164
165 /* update the forward and backward indices for each neighbour */
166 for( n=0; n<in->Nodes->degreeOfFreedomDistribution->numNeighbours; n++ ){
167 for( i=0, iI=0; i<in->Nodes->degreeOfFreedomDistribution->edges[n]->numForward; i++ ){
168 if( maskDOF[in->Nodes->degreeOfFreedomDistribution->edges[n]->indexForward[i]]>=0 )
169 in->Nodes->degreeOfFreedomDistribution->edges[n]->indexForward[iI++] = maskDOF[in->Nodes->degreeOfFreedomDistribution->edges[n]->indexForward[i]];
170 }
171 in->Nodes->degreeOfFreedomDistribution->edges[n]->numForward = iI;
172 for( i=0, iI=0; i<in->Nodes->degreeOfFreedomDistribution->edges[n]->numBackward; i++ ){
173 if(maskDOF[in->Nodes->degreeOfFreedomDistribution->edges[n]->indexBackward[i]]>=0)
174 in->Nodes->degreeOfFreedomDistribution->edges[n]->indexBackward[iI++] = maskDOF[in->Nodes->degreeOfFreedomDistribution->edges[n]->indexBackward[i]];
175 }
176 in->Nodes->degreeOfFreedomDistribution->edges[n]->numBackward = iI;
177 }
178
179 Finley_NodeDistribution_formCommBuffer( in->Nodes->degreeOfFreedomDistribution, in->Nodes->CommBuffer );
180 if ( !Finley_MPI_noError( in->MPIInfo )) {
181 goto clean;
182 }
183
184 /* update the global indices for the external DOF on this subdomain */
185 Finley_NodeDistribution_calculateIndexExternal( in->Nodes->degreeOfFreedomDistribution, in->Nodes->CommBuffer );
186 if( !Finley_MPI_noError( in->MPIInfo ) ) {
187 goto clean;
188 }
189
190 /***********************************************************
191 compile distribution data for the reduced degrees of freedom
192 ***********************************************************/
193
194 /* determnine the number of internal, boundary and external DOF in the reduced distribution */
195 totalDOF = in->Nodes->degreeOfFreedomDistribution->numLocal + in->Nodes->degreeOfFreedomDistribution->numExternal;
196
197 numReducedInternal = numReducedBoundary = numReducedLocal = numReducedExternal = 0;
198 n=0;
199 for( n=0; n<len; n++ )
200 if( maskReducedDOF[n]>=0 )
201 switch( mask[maskDOF[n]] ){
202 case NODE_INTERNAL :
203 numReducedInternal++;
204 break;
205 case NODE_BOUNDARY :
206 numReducedBoundary++;
207 break;
208 case NODE_EXTERNAL :
209 numReducedExternal++;
210 break;
211 }
212
213 numReducedLocal = numReducedInternal + numReducedBoundary;
214
215 Finley_NodeDistribution_allocTable( in->Nodes->reducedDegreeOfFreedomDistribution, numReducedLocal, numReducedExternal, 0 );
216 if( Finley_MPI_noError( in->MPIInfo ) )
217 {
218 in->Nodes->reducedDegreeOfFreedomDistribution->numInternal = numReducedInternal;
219 in->Nodes->reducedDegreeOfFreedomDistribution->numBoundary = numReducedBoundary;
220
221 /* determine the forward and backward distributions for each neighbour */
222 bufferLength = 0;
223 for( n=0; n<in->Nodes->degreeOfFreedomDistribution->numNeighbours; n++ ){
224 if( in->Nodes->degreeOfFreedomDistribution->edges[n]->numForward>bufferLength )
225 bufferLength = in->Nodes->degreeOfFreedomDistribution->edges[n]->numForward;
226 else if( in->Nodes->degreeOfFreedomDistribution->edges[n]->numBackward>bufferLength )
227 bufferLength = in->Nodes->degreeOfFreedomDistribution->edges[n]->numBackward;
228 }
229 indexLocal = TMPMEMALLOC( bufferLength, index_t );
230
231 /* find the new mapping from full to reduced DOF */
232 for( i=0; i<in->Nodes->numNodes; i++ )
233 maskReducedDOF[in->Nodes->degreeOfFreedom[i]] = in->Nodes->reducedDegreeOfFreedom[i];
234
235 /* use the mapping to map the full distribution to the reduced distribution */
236 for( n=0; n<in->Nodes->degreeOfFreedomDistribution->numNeighbours; n++ ){
237 numForward = numBackward = 0;
238 for( i=0; i<in->Nodes->degreeOfFreedomDistribution->edges[n]->numForward; i++ )
239 if( maskReducedDOF[in->Nodes->degreeOfFreedomDistribution->edges[n]->indexForward[i]]>=0 )
240 indexLocal[numForward++] = maskReducedDOF[in->Nodes->degreeOfFreedomDistribution->edges[n]->indexForward[i]];
241 Finley_NodeDistribution_addForward( in->Nodes->reducedDegreeOfFreedomDistribution, in->Nodes->degreeOfFreedomDistribution->neighbours[n], numForward, indexLocal );
242 for( i=0; i<in->Nodes->degreeOfFreedomDistribution->edges[n]->numBackward; i++ )
243 if( maskReducedDOF[in->Nodes->degreeOfFreedomDistribution->edges[n]->indexBackward[i]]>=0 )
244 indexLocal[numBackward++] = maskReducedDOF[in->Nodes->degreeOfFreedomDistribution->edges[n]->indexBackward[i]];
245 Finley_NodeDistribution_addBackward( in->Nodes->reducedDegreeOfFreedomDistribution, in->Nodes->degreeOfFreedomDistribution->neighbours[n], numBackward, indexLocal );
246 }
247
248 /* update the global indices for the reduced external DOF on this subdomain */
249 Finley_NodeDistribution_calculateIndexExternal( in->Nodes->degreeOfFreedomDistribution, in->Nodes->CommBuffer );
250 if( !Finley_MPI_noError( in->MPIInfo ) ) {
251 TMPMEMFREE( indexLocal );
252 goto clean;
253 }
254 Finley_NodeDistribution_formCommBuffer( in->Nodes->reducedDegreeOfFreedomDistribution, in->Nodes->reducedCommBuffer );
255 if( !Finley_MPI_noError( in->MPIInfo ) ) {
256 TMPMEMFREE( indexLocal );
257 goto clean;
258 }
259 Finley_NodeDistribution_calculateIndexExternal( in->Nodes->reducedDegreeOfFreedomDistribution, in->Nodes->reducedCommBuffer );
260 TMPMEMFREE( indexLocal );
261 }
262 MEMFREE( mask );
263 Finley_MPI_noError( in->MPIInfo );
264 clean:
265 #endif
266 TMPMEMFREE(reducedNodesMask);
267 TMPMEMFREE(maskDOF);
268 TMPMEMFREE(maskReducedDOF);
269 TMPMEMFREE(index);
270 if (Finley_noError()) in->Nodes->isPrepared=TRUE;
271 }
272

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.26