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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 964 - (hide annotations)
Tue Feb 13 05:10:26 2007 UTC (12 years, 9 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 jgs 150 /*
2 elspeth 616 ************************************************************
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 jgs 150 */
12    
13 jgs 82 /**************************************************************/
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 jgs 123 dim_t n,len;
36     index_t id,max_id,min_id,*maskReducedDOF=NULL,*maskDOF=NULL,*reducedNodesMask=NULL,*index=NULL;
37 bcumming 751 #ifdef PASO_MPI
38 bcumming 782 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 jgs 82
43 bcumming 751 #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 jgs 82 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 jgs 123 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 jgs 82 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 bcumming 751
90 jgs 82 #pragma omp parallel for private(n) schedule(static)
91 bcumming 751 for (n=0;n<in->Nodes->reducedNumNodes;n++)
92     in->Nodes->toReduced[index[n]]=n;
93    
94 jgs 82 /* 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 gross 964 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 bcumming 751
105 gross 964 /* 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 jgs 82 }
126     }
127 bcumming 751
128     #ifdef PASO_MPI
129     /***********************************************************
130     update the distribution data
131     ***********************************************************/
132 bcumming 782
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 bcumming 751
159 bcumming 782 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 bcumming 751 /* update the forward and backward indices for each neighbour */
166     for( n=0; n<in->Nodes->degreeOfFreedomDistribution->numNeighbours; n++ ){
167 bcumming 782 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 bcumming 751 }
178    
179 bcumming 782 Finley_NodeDistribution_formCommBuffer( in->Nodes->degreeOfFreedomDistribution, in->Nodes->CommBuffer );
180     if ( !Finley_MPI_noError( in->MPIInfo )) {
181     goto clean;
182     }
183    
184 bcumming 751 /* update the global indices for the external DOF on this subdomain */
185     Finley_NodeDistribution_calculateIndexExternal( in->Nodes->degreeOfFreedomDistribution, in->Nodes->CommBuffer );
186 bcumming 782 if( !Finley_MPI_noError( in->MPIInfo ) ) {
187     goto clean;
188     }
189 bcumming 751
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 bcumming 782 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 bcumming 751
213     numReducedLocal = numReducedInternal + numReducedBoundary;
214    
215 bcumming 782 Finley_NodeDistribution_allocTable( in->Nodes->reducedDegreeOfFreedomDistribution, numReducedLocal, numReducedExternal, 0 );
216 bcumming 751 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 bcumming 782 /* 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 bcumming 751 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 bcumming 782 if( !Finley_MPI_noError( in->MPIInfo ) ) {
251     TMPMEMFREE( indexLocal );
252     goto clean;
253     }
254 bcumming 751 Finley_NodeDistribution_formCommBuffer( in->Nodes->reducedDegreeOfFreedomDistribution, in->Nodes->reducedCommBuffer );
255 bcumming 782 if( !Finley_MPI_noError( in->MPIInfo ) ) {
256     TMPMEMFREE( indexLocal );
257     goto clean;
258     }
259 bcumming 751 Finley_NodeDistribution_calculateIndexExternal( in->Nodes->reducedDegreeOfFreedomDistribution, in->Nodes->reducedCommBuffer );
260 bcumming 782 TMPMEMFREE( indexLocal );
261 bcumming 751 }
262 bcumming 782 MEMFREE( mask );
263     Finley_MPI_noError( in->MPIInfo );
264 gross 783 clean:
265 bcumming 751 #endif
266     TMPMEMFREE(reducedNodesMask);
267     TMPMEMFREE(maskDOF);
268     TMPMEMFREE(maskReducedDOF);
269     TMPMEMFREE(index);
270 gross 964 if (Finley_noError()) in->Nodes->isPrepared=TRUE;
271 jgs 82 }
272    

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26