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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 782 - (show annotations)
Tue Jul 18 00:47:47 2006 UTC (13 years, 3 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 /* 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