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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 782 - (hide annotations)
Tue Jul 18 00:47:47 2006 UTC (13 years, 4 months ago) by bcumming
File MIME type: text/plain
File size: 3817 byte(s)
Large number of changes to Finley for meshing in MPI.

- optimisation and neatening up of rectcanglular mesh generation code
- first and second order 1D, 2D and 3D rectangular meshes are now
  available in finley and escript using MPI.
- reduced meshes now generated in MPI, and interpolation to and from 
  reduced data types now supported.  

1 bcumming 782 /* created on 3-7-2006 by Ben Cumming */
2    
3     /* Take a distributed mesh and relable the degrees of freedom
4     in the order Internal-Boundary-External. For a 2nd order mesh
5     it is assumed that degrees of freedom are ordered local-external,
6     so as to avoid ambiguity */
7    
8     #include "Mesh.h"
9     #include "Util.h"
10    
11     #ifdef PASO_MPI
12     #include "Distribution.h"
13    
14     void Finley_Mesh_resolveDegreeOfFreedomOrder( Finley_Mesh *in, bool_t doReduced )
15     {
16     index_t *mask;
17     index_t i, n, iI=0, iB=0, iE=0, minDOF, maxDOF, len;
18     dim_t numInternal, numBoundary, numLocal, numExternal, totalDOF;
19     int status;
20     Finley_NodeDistribution *distribution=NULL;
21    
22     minDOF = Finley_Util_getMinInt( 1, in->Nodes->numNodes, in->Nodes->degreeOfFreedom );
23     maxDOF = Finley_Util_getMaxInt( 1, in->Nodes->numNodes, in->Nodes->degreeOfFreedom );
24     len = maxDOF - 2*minDOF + 1;
25    
26     /* generate the DOF mask */
27     mask = MEMALLOC( len, index_t );
28     for( n=0; n<len; n++ )
29     mask[n] = -1;
30    
31     for( n=0; n<in->Nodes->numNodes; n++ )
32     mask[in->Nodes->degreeOfFreedom[n]-minDOF] = in->Nodes->Dom[n];
33    
34     /* determine the number of internal/boundary/external DOF */
35     numInternal = numBoundary = numLocal = numExternal = 0;
36     for( n=0; n<len; n++ )
37     switch( mask[n] ) {
38     case NODE_INTERNAL :
39     numInternal++;
40     break;
41     case NODE_BOUNDARY :
42     numBoundary++;
43     break;
44     case NODE_EXTERNAL :
45     numExternal++;
46     break;
47     }
48     numLocal = numInternal+numBoundary;
49    
50     /* find the new DOF labels according to the internal/boundary/external info */
51     iI = iB = iE = 0;
52     for( n=0; n<len; n++ )
53     switch( mask[n] ){
54     case NODE_INTERNAL :
55     mask[n] = iI++;
56     break;
57     case NODE_BOUNDARY :
58     mask[n] = numInternal + iB++;
59     break;
60     case NODE_EXTERNAL :
61     mask[n] = numLocal + iE++;
62     break;
63     }
64    
65     /* update the NodeFile to the new DOF labels */
66     for( n=0; n<in->Nodes->numNodes; n++ )
67     in->Nodes->degreeOfFreedom[n] = mask[ in->Nodes->degreeOfFreedom[n]-minDOF ];
68    
69     /* update the distribution information */
70     in->Nodes->degreeOfFreedomDistribution->numLocal = numLocal;
71     in->Nodes->degreeOfFreedomDistribution->numInternal = numInternal;
72     in->Nodes->degreeOfFreedomDistribution->numBoundary = numBoundary;
73     in->Nodes->degreeOfFreedomDistribution->numExternal = numExternal;
74    
75     /* update the forward and backward indices for each neighbour */
76     for( n=0; n<in->Nodes->degreeOfFreedomDistribution->numNeighbours; n++ ){
77     for( i=0, iI=0; i<in->Nodes->degreeOfFreedomDistribution->edges[n]->numForward; i++ ){
78     in->Nodes->degreeOfFreedomDistribution->edges[n]->indexForward[iI++] = mask[in->Nodes->degreeOfFreedomDistribution->edges[n]->indexForward[i]];
79     }
80     for( i=0, iI=0; i<in->Nodes->degreeOfFreedomDistribution->edges[n]->numBackward; i++ ){
81     in->Nodes->degreeOfFreedomDistribution->edges[n]->indexBackward[iI++] = mask[in->Nodes->degreeOfFreedomDistribution->edges[n]->indexBackward[i]];
82     }
83     }
84    
85     /* recalculate vtxdist */
86     distribution = in->Nodes->degreeOfFreedomDistribution;
87    
88     status = MPI_Allgather( &distribution->numLocal, 1, MPI_INT, distribution->vtxdist+1, 1, MPI_INT, in->MPIInfo->comm );
89     if( status!=MPI_SUCCESS ){
90     Finley_setError( PASO_MPI_ERROR, "Mesh_resolveDegreeOfFreedomOrder() : error performing global MPI operation : MPI_Allgather()" );
91     goto clean;
92     }
93    
94     distribution->vtxdist[0] = 0;
95     for( i=2; i<in->MPIInfo->size+1; i++ )
96     distribution->vtxdist[i] += distribution->vtxdist[i-1];
97    
98     status = MPI_Allreduce( &distribution->numLocal, &distribution->numGlobal, 1, MPI_INT, MPI_SUM, in->MPIInfo->comm );
99     if( status!=MPI_SUCCESS ){
100     Finley_setError( PASO_MPI_ERROR, "Mesh_resolveDegreeOfFreedomOrder() : error performing global MPI operation : MPI_Allreduce()" );
101     goto clean;
102     }
103     clean:
104     /* make the global error status local on each MPI process */
105     Finley_MPI_noError(in->MPIInfo);
106     MEMFREE( mask);
107     }
108     #endif
109    

  ViewVC Help
Powered by ViewVC 1.1.26