/[escript]/branches/schroedinger_upto1946/finley/src/Mesh_createNodeFileMappings.c
ViewVC logotype

Annotation of /branches/schroedinger_upto1946/finley/src/Mesh_createNodeFileMappings.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1326 - (hide annotations)
Mon Oct 1 08:10:41 2007 UTC (11 years, 6 months ago) by ksteube
Original Path: trunk/finley/src/Mesh_createNodeFileMappings.c
File MIME type: text/plain
File size: 16287 byte(s)
Implemented domain.print_mesh_info() so we can see the distribution of elements & nodes.
Implemented -DBOUNDS_CHECK to catch an error with periodicN=True.

1 ksteube 1315
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: NodeFile : creates the mappings using the indexReducedNodes */
19     /* no distribution is happening */
20    
21     /**************************************************************/
22    
23     #include "Mesh.h"
24     #define UNUSED -1
25    
26     /**************************************************************/
27    
28     void Mesh_createDOFMappingAndCoupling(Finley_Mesh* in, bool_t use_reduced_elements)
29     {
30     index_t min_DOF, max_DOF, *shared=NULL, *offsetInShared=NULL, *locDOFMask=NULL, i, k, myFirstDOF, myLastDOF, *nodeMask=NULL, firstDOF, lastDOF, *globalDOFIndex;
31     dim_t mpiSize, len_loc_dof, numNeighbors, n, lastn, numNodes;
32     Paso_MPI_rank myRank,p,p_min,p_max, *neighbor=NULL;
33     Paso_SharedComponents *rcv_shcomp=NULL, *snd_shcomp=NULL;
34     Finley_NodeMapping *this_mapping=NULL;
35     Paso_Coupler* this_coupler=NULL;
36     Paso_Distribution* dof_distribution;
37    
38     numNodes=in->Nodes->numNodes;
39     if (use_reduced_elements) {
40     dof_distribution=in->Nodes->reducedDegreesOfFreedomDistribution;
41     globalDOFIndex=in->Nodes->globalReducedDOFIndex;
42     Finley_NodeFile_setReducedDOFRange(&min_DOF, &max_DOF,in->Nodes);
43     } else {
44     dof_distribution=in->Nodes->degreesOfFreedomDistribution;
45     globalDOFIndex=in->Nodes->globalDegreesOfFreedom;
46     Finley_NodeFile_setDOFRange(&min_DOF, &max_DOF,in->Nodes);
47     }
48    
49     mpiSize=dof_distribution->mpi_info->size;
50     myRank=dof_distribution->mpi_info->rank;
51    
52     min_DOF=Finley_Util_getFlaggedMinInt(1,numNodes,globalDOFIndex,-1);
53     max_DOF=Finley_Util_getFlaggedMaxInt(1,numNodes,globalDOFIndex,-1);
54    
55     p_min=mpiSize;
56     p_max=-1;
57    
58     for (p=0; p<mpiSize; ++p) {
59     if (dof_distribution->first_component[p]<=min_DOF) p_min=p;
60     if (dof_distribution->first_component[p]<=max_DOF) p_max=p;
61     }
62    
63     len_loc_dof=max_DOF-min_DOF+1;
64     myFirstDOF=Paso_Distribution_getFirstComponent(dof_distribution);
65     myLastDOF=Paso_Distribution_getLastComponent(dof_distribution);
66     if (! ((min_DOF<=myFirstDOF) && (myLastDOF-1<=max_DOF)) ) {
67     Finley_setError(SYSTEM_ERROR,"Local elements do not span local degrees of freedom.");
68     return;
69     }
70    
71     nodeMask=TMPMEMALLOC(numNodes,index_t);
72     neighbor=TMPMEMALLOC(mpiSize,Paso_MPI_rank);
73     shared=TMPMEMALLOC(numNodes*(p_max-p_min+1),index_t);
74     offsetInShared=TMPMEMALLOC(mpiSize+1,index_t);
75     locDOFMask=TMPMEMALLOC(len_loc_dof, index_t);
76     if (! ( Finley_checkPtr(neighbor) || Finley_checkPtr(shared) || Finley_checkPtr(offsetInShared) || Finley_checkPtr(locDOFMask) || Finley_checkPtr(nodeMask) )) {
77    
78    
79     #pragma omp parallel for private(i) schedule(static)
80     for (i=0;i<len_loc_dof;++i) locDOFMask[i]=UNUSED;
81     #pragma omp parallel for private(i) schedule(static)
82     for (i=0;i<numNodes;++i) nodeMask[i]=UNUSED;
83    
84     for (i=0;i<numNodes;++i) {
85     k=globalDOFIndex[i];
86     #ifdef BOUNDS_CHECK
87 ksteube 1326 if ((k-min_DOF) >= len_loc_dof) { printf("BOUNDS_CHECK %s %d i=%d k=%d min_DOF=%d\n", __FILE__, __LINE__, i, k, min_DOF); exit(1); }
88 ksteube 1315 #endif
89     if (k>-1) locDOFMask[k-min_DOF]=UNUSED-1;
90     }
91    
92     for (i=myFirstDOF-min_DOF;i<myLastDOF-min_DOF;++i) {
93     locDOFMask[i]=i-myFirstDOF+min_DOF;
94     #ifdef BOUNDS_CHECK
95 ksteube 1326 if (i < 0 || i >= len_loc_dof) { printf("BOUNDS_CHECK %s %d i=%d\n", __FILE__, __LINE__, i); exit(1); }
96 ksteube 1315 #endif
97     }
98    
99     numNeighbors=0;
100     n=0;
101     lastn=n;
102     for (p=p_min;p<=p_max;++p) {
103     firstDOF=MAX(min_DOF,dof_distribution->first_component[p]);
104     lastDOF=MIN(max_DOF+1,dof_distribution->first_component[p+1]);
105     if (p != myRank) {
106     for (i=firstDOF-min_DOF;i<lastDOF-min_DOF;++i) {
107     #ifdef BOUNDS_CHECK
108 ksteube 1326 if (i < 0 || i >= len_loc_dof) { printf("BOUNDS_CHECK %s %d p=%d i=%d\n", __FILE__, __LINE__, p, i); exit(1); }
109 ksteube 1315 #endif
110     if (locDOFMask[i] == UNUSED-1) {
111     locDOFMask[i]=myLastDOF-myFirstDOF+n;
112     ++n;
113     }
114     }
115     if (n>lastn) {
116     neighbor[numNeighbors]=p;
117     #ifdef BOUNDS_CHECK
118 ksteube 1326 if (numNeighbors < 0 || numNeighbors >= mpiSize+1) { printf("BOUNDS_CHECK %s %d p=%d numNeighbors=%d n=%d\n", __FILE__, __LINE__, p, numNeighbors, n); exit(1); }
119 ksteube 1315 #endif
120     offsetInShared[numNeighbors]=lastn;
121     numNeighbors++;
122     lastn=n;
123     }
124     }
125     }
126     #ifdef BOUNDS_CHECK
127 ksteube 1326 if (numNeighbors < 0 || numNeighbors >= mpiSize+1) { printf("BOUNDS_CHECK %s %d numNeighbors=%d\n", __FILE__, __LINE__, numNeighbors); exit(1); }
128 ksteube 1315 #endif
129     offsetInShared[numNeighbors]=lastn;
130    
131     /* assign new DOF labels to nodes */
132     #pragma omp parallel for private(i) schedule(static)
133     for (i=0;i<numNodes;++i) {
134     k=globalDOFIndex[i];
135     if (k>-1) nodeMask[i]=locDOFMask[k-min_DOF];
136     }
137    
138     /* now we can set the mapping from nodes to local DOFs */
139     this_mapping=Finley_NodeMapping_alloc(numNodes,nodeMask,UNUSED);
140     /* define how to get DOF values for controlled bu other processors */
141     #ifdef BOUNDS_CHECK
142     for (i=0;i<offsetInShared[numNeighbors];++i) {
143 ksteube 1326 if (i < 0 || i >= numNodes*(p_max-p_min+1)) { printf("BOUNDS_CHECK %s %d i=%d\n", __FILE__, __LINE__, i); exit(1); }
144 ksteube 1315 }
145     #endif
146     #pragma omp parallel for private(i) schedule(static)
147     for (i=0;i<offsetInShared[numNeighbors];++i) shared[i]=myLastDOF-myFirstDOF+i;
148    
149     rcv_shcomp=Paso_SharedComponents_alloc(numNeighbors,neighbor,shared,offsetInShared,1,0,dof_distribution->mpi_info);
150    
151     /* now it is determined which DOFs needs to be send off:*/
152     #pragma omp parallel for private(i) schedule(static)
153     for (i=0;i<len_loc_dof;++i) locDOFMask[i]=UNUSED;
154     n=0;
155     numNeighbors=0;
156     lastn=n;
157     for (p=p_min;p<=p_max;++p) {
158     firstDOF=dof_distribution->first_component[p];
159     lastDOF=dof_distribution->first_component[p+1];
160     if (p != myRank) {
161     /* mark a DOF by p if it will be requested by processor p */
162     Finley_Mesh_markDOFsConnectedToRange(locDOFMask,min_DOF,p,firstDOF,lastDOF,in,use_reduced_elements);
163    
164     for (i=myFirstDOF-min_DOF;i<myLastDOF-min_DOF;++i) {
165     if (locDOFMask[i] == p) {
166     #ifdef BOUNDS_CHECK
167 ksteube 1326 if (n < 0 || n >= numNodes*(p_max-p_min+1)) { printf("BOUNDS_CHECK %s %d p=%d i=%d n=%d\n", __FILE__, __LINE__, p, i, n); exit(1); }
168 ksteube 1315 #endif
169     shared[n]=i-myFirstDOF+min_DOF;
170     ++n;
171     }
172     }
173     if (n>lastn) {
174     neighbor[numNeighbors]=p;
175     #ifdef BOUNDS_CHECK
176 ksteube 1326 if (numNeighbors < 0 || numNeighbors >= mpiSize+1) { printf("BOUNDS_CHECK %s %d p=%d n=%d numNeighbors=%d\n", __FILE__, __LINE__, p, n, numNeighbors); exit(1); }
177 ksteube 1315 #endif
178     offsetInShared[numNeighbors]=lastn;
179     numNeighbors++;
180     lastn=n;
181     }
182     }
183     }
184     #ifdef BOUNDS_CHECK
185 ksteube 1326 if (numNeighbors < 0 || numNeighbors >= mpiSize+1) { printf("BOUNDS_CHECK %s %d numNeighbors=%d\n", __FILE__, __LINE__, numNeighbors); exit(1); }
186 ksteube 1315 #endif
187     offsetInShared[numNeighbors]=lastn;
188     snd_shcomp=Paso_SharedComponents_alloc(numNeighbors,neighbor,shared,offsetInShared,1,0,dof_distribution->mpi_info);
189    
190     if (Finley_noError()) this_coupler=Paso_Coupler_alloc(snd_shcomp,rcv_shcomp);
191     /* assign new DOF labels to nodes */
192     Paso_SharedComponents_free(rcv_shcomp);
193     Paso_SharedComponents_free(snd_shcomp);
194     }
195     TMPMEMFREE(nodeMask);
196     TMPMEMFREE(neighbor);
197     TMPMEMFREE(shared);
198     TMPMEMFREE(offsetInShared);
199     TMPMEMFREE(locDOFMask);
200     if (Finley_noError()) {
201     if (use_reduced_elements) {
202     in->Nodes->reducedDegreesOfFreedomMapping=this_mapping;
203     in->Nodes->reducedDegreesOfFreedomCoupler=this_coupler;
204     } else {
205     in->Nodes->degreesOfFreedomMapping=this_mapping;
206     in->Nodes->degreesOfFreedomCoupler=this_coupler;
207     }
208     } else {
209     Finley_NodeMapping_free(this_mapping);
210     Paso_Coupler_free(this_coupler);
211    
212     }
213     }
214     void Finley_Mesh_createNodeFileMappings(Finley_Mesh* in, dim_t numReducedNodes, index_t* indexReducedNodes, index_t* dof_first_component) {
215    
216    
217     index_t myFirstDOF, myLastDOF, myFirstNode, myLastNode, *reduced_dof_first_component=NULL, *nodeMask=NULL,
218     *reduced_nodes_first_component=NULL, *nodes_first_component=NULL,k,
219     *maskMyReducedDOF=NULL, *indexMyReducedDOF=NULL, *maskMyReducedNodes=NULL, *indexMyReducedNodes=NULL;
220     dim_t myNumDOF, myNumNodes, myNumReducedNodes, myNumReducedDOF, globalNumReducedNodes, globalNumReducedDOF,i,mpiSize, globalNumNodes, n, lastn,n0, numNeighbors;
221     Paso_MPI_rank myRank;
222    
223     mpiSize=in->Nodes->MPIInfo->size;
224     myRank=in->Nodes->MPIInfo->rank;
225     /* mark the nodes used by the reduced mesh */
226    
227     reduced_dof_first_component=TMPMEMALLOC(mpiSize+1,index_t);
228     reduced_nodes_first_component=TMPMEMALLOC(mpiSize+1,index_t);
229     nodes_first_component=TMPMEMALLOC(mpiSize+1,index_t);
230    
231     if (! ( Finley_checkPtr(reduced_dof_first_component) || Finley_checkPtr(reduced_nodes_first_component) || Finley_checkPtr(nodes_first_component) ) ) {
232    
233     globalNumNodes=Finley_NodeFile_maxGlobalNodeIDIndex(in->Nodes)+1;
234     Paso_MPIInfo_setDistribution(in->Nodes->MPIInfo,0,globalNumNodes-1,nodes_first_component);
235    
236     myFirstDOF=dof_first_component[myRank];
237     myLastDOF=dof_first_component[myRank+1];
238     myNumDOF=myLastDOF-myFirstDOF;
239     myFirstNode=nodes_first_component[myRank];
240     myLastNode=nodes_first_component[myRank+1];
241     myNumNodes=myLastNode-myFirstNode;
242    
243     maskMyReducedDOF=TMPMEMALLOC(myNumDOF,index_t);
244     indexMyReducedDOF=TMPMEMALLOC(myNumDOF,index_t);
245     maskMyReducedNodes=TMPMEMALLOC(myNumNodes,index_t);
246     indexMyReducedNodes=TMPMEMALLOC(myNumNodes,index_t);
247    
248     if (! ( Finley_checkPtr(maskMyReducedDOF) || Finley_checkPtr(indexMyReducedDOF) || Finley_checkPtr(maskMyReducedNodes) || Finley_checkPtr(indexMyReducedNodes) ) ) {
249    
250     #pragma omp parallel private(i)
251     {
252     #pragma omp for schedule(static)
253     for (i=0;i<myNumNodes;++i) maskMyReducedNodes[i]=-1;
254     #pragma omp for schedule(static)
255     for (i=0;i<myNumDOF;++i) maskMyReducedDOF[i]=-1;
256     #pragma omp for private(k) schedule(static)
257     for (i=0;i<numReducedNodes;++i) {
258     k=in->Nodes->globalNodesIndex[indexReducedNodes[i]];
259     if ( (k>=myFirstNode) && (myLastNode>k) ) maskMyReducedNodes[k-myFirstNode]=i;
260     k=in->Nodes->globalDegreesOfFreedom[indexReducedNodes[i]];
261     if ( (k>=myFirstDOF) && (myLastDOF>k) ) maskMyReducedDOF[k-myFirstDOF]=i;
262     }
263     }
264     myNumReducedNodes=Finley_Util_packMask(myNumNodes,maskMyReducedNodes,indexMyReducedNodes);
265     myNumReducedDOF=Finley_Util_packMask(myNumDOF,maskMyReducedDOF,indexMyReducedDOF);
266    
267     #ifdef PASO_MPI
268     MPI_Allgather(&myNumReducedNodes,1,MPI_INT,reduced_nodes_first_component,1,MPI_INT,in->Nodes->MPIInfo->comm);
269     MPI_Allgather(&myNumReducedDOF,1,MPI_INT,reduced_dof_first_component,1,MPI_INT,in->Nodes->MPIInfo->comm);
270     #else
271     reduced_nodes_first_component[0]=myNumReducedNodes;
272     reduced_dof_first_component[0]=myNumReducedDOF;
273     #endif
274     globalNumReducedNodes=0;
275     globalNumReducedDOF=0;
276     for (i=0;i<mpiSize;++i) {
277     k=reduced_nodes_first_component[i];
278     reduced_nodes_first_component[i]=globalNumReducedNodes;
279     globalNumReducedNodes+=k;
280    
281     k=reduced_dof_first_component[i];
282     reduced_dof_first_component[i]=globalNumReducedDOF;
283     globalNumReducedDOF+=k;
284     }
285     reduced_nodes_first_component[mpiSize]=globalNumReducedNodes;
286     reduced_dof_first_component[mpiSize]=globalNumReducedDOF;
287     /* ==== distribution of Nodes ===============================*/
288     Paso_MPIInfo_setDistribution(in->Nodes->MPIInfo,0,globalNumNodes-1,nodes_first_component);
289     in->Nodes->nodesDistribution=Paso_Distribution_alloc(in->Nodes->MPIInfo,nodes_first_component,1,0);
290    
291     /* ==== distribution of Nodes ===============================*/
292     in->Nodes->degreesOfFreedomDistribution=Paso_Distribution_alloc(in->Nodes->MPIInfo,dof_first_component,1,0);
293    
294     /* ==== distribution of reduced Nodes ===============================*/
295     reduced_nodes_first_component[mpiSize]=globalNumReducedNodes;
296     in->Nodes->reducedNodesDistribution=Paso_Distribution_alloc(in->Nodes->MPIInfo,reduced_nodes_first_component,1,0);
297    
298     /* ==== distribution of reduced DOF ===============================*/
299     in->Nodes->reducedDegreesOfFreedomDistribution=Paso_Distribution_alloc(in->Nodes->MPIInfo,reduced_dof_first_component,1,0);
300     }
301     TMPMEMFREE(maskMyReducedDOF);
302     TMPMEMFREE(indexMyReducedDOF);
303     TMPMEMFREE(maskMyReducedNodes);
304     TMPMEMFREE(indexMyReducedNodes);
305     }
306     TMPMEMFREE(reduced_dof_first_component);
307     TMPMEMFREE(reduced_nodes_first_component);
308     TMPMEMFREE(nodes_first_component);
309    
310     nodeMask=TMPMEMALLOC(in->Nodes->numNodes,index_t);
311     if (! Finley_checkPtr(nodeMask) && Finley_noError()) {
312    
313     /* ==== nodes mapping which is a dummy structure ======== */
314     #pragma omp parallel for private(i) schedule(static)
315     for (i=0;i<in->Nodes->numNodes;++i) nodeMask[i]=i;
316     in->Nodes->nodesMapping=Finley_NodeMapping_alloc(in->Nodes->numNodes,nodeMask,UNUSED);
317    
318     /* ==== mapping between nodes and reduced nodes ========== */
319     #pragma omp parallel for private(i) schedule(static)
320     for (i=0;i<in->Nodes->numNodes;++i) nodeMask[i]=UNUSED;
321     #pragma omp parallel for private(i) schedule(static)
322     for (i=0;i<numReducedNodes;++i) nodeMask[indexReducedNodes[i]]=i;
323     in->Nodes->reducedNodesMapping=Finley_NodeMapping_alloc(in->Nodes->numNodes,nodeMask,UNUSED);
324    
325     }
326     TMPMEMFREE(nodeMask);
327     /* ==== mapping between nodes and DOFs + DOF coupler ========== */
328     if ( Finley_noError()) Mesh_createDOFMappingAndCoupling(in,FALSE);
329     /* ==== mapping between nodes and reduced DOFs + reduced DOF coupler ========== */
330     if ( Finley_noError()) Mesh_createDOFMappingAndCoupling(in,TRUE);
331    
332     /* get the Ids for DOFs and reduced nodes */
333     if (Finley_noError()) {
334     #pragma omp parallel private(i)
335     {
336     #pragma omp for
337     for (i=0;i<in->Nodes->reducedNodesMapping->numTargets;++i) in->Nodes->reducedNodesId[i]=in->Nodes->Id[in->Nodes->reducedNodesMapping->map[i]];
338     #pragma omp for
339     for (i=0;i<in->Nodes->degreesOfFreedomMapping->numTargets;++i) in->Nodes->degreesOfFreedomId[i]=in->Nodes->Id[in->Nodes->degreesOfFreedomMapping->map[i]];
340     #pragma omp for
341     for (i=0;i<in->Nodes->reducedDegreesOfFreedomMapping->numTargets;++i) in->Nodes->reducedDegreesOfFreedomId[i]=in->Nodes->Id[in->Nodes->reducedDegreesOfFreedomMapping->map[i]];
342     }
343     } else {
344     Finley_NodeMapping_free(in->Nodes->nodesMapping);
345     Finley_NodeMapping_free(in->Nodes->reducedNodesMapping);
346     Finley_NodeMapping_free(in->Nodes->degreesOfFreedomMapping);
347     Finley_NodeMapping_free(in->Nodes->reducedDegreesOfFreedomMapping);
348     Paso_Distribution_free(in->Nodes->nodesDistribution);
349     Paso_Distribution_free(in->Nodes->reducedNodesDistribution);
350     Paso_Distribution_free(in->Nodes->degreesOfFreedomDistribution);
351     Paso_Distribution_free(in->Nodes->reducedDegreesOfFreedomDistribution);
352     Paso_Coupler_free(in->Nodes->degreesOfFreedomCoupler);
353     Paso_Coupler_free(in->Nodes->reducedDegreesOfFreedomCoupler);
354     in->Nodes->nodesMapping=NULL;
355     in->Nodes->reducedNodesMapping=NULL;
356     in->Nodes->degreesOfFreedomMapping=NULL;
357     in->Nodes->reducedDegreesOfFreedomMapping=NULL;
358     in->Nodes->nodesDistribution=NULL;
359     in->Nodes->reducedNodesDistribution=NULL;
360     in->Nodes->degreesOfFreedomDistribution=NULL;
361     in->Nodes->reducedDegreesOfFreedomDistribution=NULL;
362     in->Nodes->degreesOfFreedomCoupler=NULL;
363     in->Nodes->reducedDegreesOfFreedomCoupler=NULL;
364     }
365     }
366    

  ViewVC Help
Powered by ViewVC 1.1.26