/[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 1388 - (hide annotations)
Fri Jan 11 07:45:58 2008 UTC (11 years, 3 months ago) by trankine
Original Path: trunk/finley/src/Mesh_createNodeFileMappings.c
File MIME type: text/plain
File size: 17143 byte(s)
And get the *(&(*&(* name right
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 ksteube 1347
215     void Finley_Mesh_createMappings(Finley_Mesh* mesh, index_t* distribution) {
216     int i;
217     index_t *maskReducedNodes=NULL, *indexReducedNodes=NULL;
218     dim_t numReducedNodes;
219    
220     maskReducedNodes=TMPMEMALLOC(mesh->Nodes->numNodes,index_t);
221     indexReducedNodes=TMPMEMALLOC(mesh->Nodes->numNodes,index_t);
222    
223     if (! ( Finley_checkPtr(maskReducedNodes) || Finley_checkPtr(indexReducedNodes) ) ) {
224     #pragma omp parallel for private(i) schedule(static)
225     for (i=0;i<mesh->Nodes->numNodes;++i) maskReducedNodes[i]=-1;
226     Finley_Mesh_markNodes(maskReducedNodes,0,mesh,TRUE);
227     numReducedNodes=Finley_Util_packMask(mesh->Nodes->numNodes,maskReducedNodes,indexReducedNodes);
228     if (Finley_noError()) Finley_Mesh_createNodeFileMappings(mesh,numReducedNodes,indexReducedNodes,distribution);
229     }
230    
231     TMPMEMFREE(maskReducedNodes);
232     TMPMEMFREE(indexReducedNodes);
233     }
234    
235 ksteube 1315 void Finley_Mesh_createNodeFileMappings(Finley_Mesh* in, dim_t numReducedNodes, index_t* indexReducedNodes, index_t* dof_first_component) {
236    
237    
238     index_t myFirstDOF, myLastDOF, myFirstNode, myLastNode, *reduced_dof_first_component=NULL, *nodeMask=NULL,
239     *reduced_nodes_first_component=NULL, *nodes_first_component=NULL,k,
240     *maskMyReducedDOF=NULL, *indexMyReducedDOF=NULL, *maskMyReducedNodes=NULL, *indexMyReducedNodes=NULL;
241     dim_t myNumDOF, myNumNodes, myNumReducedNodes, myNumReducedDOF, globalNumReducedNodes, globalNumReducedDOF,i,mpiSize, globalNumNodes, n, lastn,n0, numNeighbors;
242     Paso_MPI_rank myRank;
243    
244     mpiSize=in->Nodes->MPIInfo->size;
245     myRank=in->Nodes->MPIInfo->rank;
246     /* mark the nodes used by the reduced mesh */
247    
248     reduced_dof_first_component=TMPMEMALLOC(mpiSize+1,index_t);
249     reduced_nodes_first_component=TMPMEMALLOC(mpiSize+1,index_t);
250     nodes_first_component=TMPMEMALLOC(mpiSize+1,index_t);
251    
252     if (! ( Finley_checkPtr(reduced_dof_first_component) || Finley_checkPtr(reduced_nodes_first_component) || Finley_checkPtr(nodes_first_component) ) ) {
253    
254     globalNumNodes=Finley_NodeFile_maxGlobalNodeIDIndex(in->Nodes)+1;
255     Paso_MPIInfo_setDistribution(in->Nodes->MPIInfo,0,globalNumNodes-1,nodes_first_component);
256    
257     myFirstDOF=dof_first_component[myRank];
258     myLastDOF=dof_first_component[myRank+1];
259     myNumDOF=myLastDOF-myFirstDOF;
260     myFirstNode=nodes_first_component[myRank];
261     myLastNode=nodes_first_component[myRank+1];
262     myNumNodes=myLastNode-myFirstNode;
263    
264     maskMyReducedDOF=TMPMEMALLOC(myNumDOF,index_t);
265     indexMyReducedDOF=TMPMEMALLOC(myNumDOF,index_t);
266     maskMyReducedNodes=TMPMEMALLOC(myNumNodes,index_t);
267     indexMyReducedNodes=TMPMEMALLOC(myNumNodes,index_t);
268    
269     if (! ( Finley_checkPtr(maskMyReducedDOF) || Finley_checkPtr(indexMyReducedDOF) || Finley_checkPtr(maskMyReducedNodes) || Finley_checkPtr(indexMyReducedNodes) ) ) {
270    
271     #pragma omp parallel private(i)
272     {
273     #pragma omp for schedule(static)
274     for (i=0;i<myNumNodes;++i) maskMyReducedNodes[i]=-1;
275     #pragma omp for schedule(static)
276     for (i=0;i<myNumDOF;++i) maskMyReducedDOF[i]=-1;
277     #pragma omp for private(k) schedule(static)
278     for (i=0;i<numReducedNodes;++i) {
279     k=in->Nodes->globalNodesIndex[indexReducedNodes[i]];
280     if ( (k>=myFirstNode) && (myLastNode>k) ) maskMyReducedNodes[k-myFirstNode]=i;
281     k=in->Nodes->globalDegreesOfFreedom[indexReducedNodes[i]];
282     if ( (k>=myFirstDOF) && (myLastDOF>k) ) maskMyReducedDOF[k-myFirstDOF]=i;
283     }
284     }
285     myNumReducedNodes=Finley_Util_packMask(myNumNodes,maskMyReducedNodes,indexMyReducedNodes);
286     myNumReducedDOF=Finley_Util_packMask(myNumDOF,maskMyReducedDOF,indexMyReducedDOF);
287    
288     #ifdef PASO_MPI
289     MPI_Allgather(&myNumReducedNodes,1,MPI_INT,reduced_nodes_first_component,1,MPI_INT,in->Nodes->MPIInfo->comm);
290     MPI_Allgather(&myNumReducedDOF,1,MPI_INT,reduced_dof_first_component,1,MPI_INT,in->Nodes->MPIInfo->comm);
291     #else
292     reduced_nodes_first_component[0]=myNumReducedNodes;
293     reduced_dof_first_component[0]=myNumReducedDOF;
294     #endif
295     globalNumReducedNodes=0;
296     globalNumReducedDOF=0;
297     for (i=0;i<mpiSize;++i) {
298     k=reduced_nodes_first_component[i];
299     reduced_nodes_first_component[i]=globalNumReducedNodes;
300     globalNumReducedNodes+=k;
301    
302     k=reduced_dof_first_component[i];
303     reduced_dof_first_component[i]=globalNumReducedDOF;
304     globalNumReducedDOF+=k;
305     }
306     reduced_nodes_first_component[mpiSize]=globalNumReducedNodes;
307     reduced_dof_first_component[mpiSize]=globalNumReducedDOF;
308     /* ==== distribution of Nodes ===============================*/
309     Paso_MPIInfo_setDistribution(in->Nodes->MPIInfo,0,globalNumNodes-1,nodes_first_component);
310     in->Nodes->nodesDistribution=Paso_Distribution_alloc(in->Nodes->MPIInfo,nodes_first_component,1,0);
311    
312     /* ==== distribution of Nodes ===============================*/
313     in->Nodes->degreesOfFreedomDistribution=Paso_Distribution_alloc(in->Nodes->MPIInfo,dof_first_component,1,0);
314    
315     /* ==== distribution of reduced Nodes ===============================*/
316     reduced_nodes_first_component[mpiSize]=globalNumReducedNodes;
317     in->Nodes->reducedNodesDistribution=Paso_Distribution_alloc(in->Nodes->MPIInfo,reduced_nodes_first_component,1,0);
318    
319     /* ==== distribution of reduced DOF ===============================*/
320     in->Nodes->reducedDegreesOfFreedomDistribution=Paso_Distribution_alloc(in->Nodes->MPIInfo,reduced_dof_first_component,1,0);
321     }
322     TMPMEMFREE(maskMyReducedDOF);
323     TMPMEMFREE(indexMyReducedDOF);
324     TMPMEMFREE(maskMyReducedNodes);
325     TMPMEMFREE(indexMyReducedNodes);
326     }
327     TMPMEMFREE(reduced_dof_first_component);
328     TMPMEMFREE(reduced_nodes_first_component);
329     TMPMEMFREE(nodes_first_component);
330    
331     nodeMask=TMPMEMALLOC(in->Nodes->numNodes,index_t);
332     if (! Finley_checkPtr(nodeMask) && Finley_noError()) {
333    
334     /* ==== nodes mapping which is a dummy structure ======== */
335     #pragma omp parallel for private(i) schedule(static)
336     for (i=0;i<in->Nodes->numNodes;++i) nodeMask[i]=i;
337     in->Nodes->nodesMapping=Finley_NodeMapping_alloc(in->Nodes->numNodes,nodeMask,UNUSED);
338    
339     /* ==== mapping between nodes and reduced nodes ========== */
340     #pragma omp parallel for private(i) schedule(static)
341     for (i=0;i<in->Nodes->numNodes;++i) nodeMask[i]=UNUSED;
342     #pragma omp parallel for private(i) schedule(static)
343     for (i=0;i<numReducedNodes;++i) nodeMask[indexReducedNodes[i]]=i;
344     in->Nodes->reducedNodesMapping=Finley_NodeMapping_alloc(in->Nodes->numNodes,nodeMask,UNUSED);
345    
346     }
347     TMPMEMFREE(nodeMask);
348     /* ==== mapping between nodes and DOFs + DOF coupler ========== */
349     if ( Finley_noError()) Mesh_createDOFMappingAndCoupling(in,FALSE);
350     /* ==== mapping between nodes and reduced DOFs + reduced DOF coupler ========== */
351     if ( Finley_noError()) Mesh_createDOFMappingAndCoupling(in,TRUE);
352    
353     /* get the Ids for DOFs and reduced nodes */
354     if (Finley_noError()) {
355     #pragma omp parallel private(i)
356     {
357     #pragma omp for
358     for (i=0;i<in->Nodes->reducedNodesMapping->numTargets;++i) in->Nodes->reducedNodesId[i]=in->Nodes->Id[in->Nodes->reducedNodesMapping->map[i]];
359     #pragma omp for
360     for (i=0;i<in->Nodes->degreesOfFreedomMapping->numTargets;++i) in->Nodes->degreesOfFreedomId[i]=in->Nodes->Id[in->Nodes->degreesOfFreedomMapping->map[i]];
361     #pragma omp for
362     for (i=0;i<in->Nodes->reducedDegreesOfFreedomMapping->numTargets;++i) in->Nodes->reducedDegreesOfFreedomId[i]=in->Nodes->Id[in->Nodes->reducedDegreesOfFreedomMapping->map[i]];
363     }
364     } else {
365     Finley_NodeMapping_free(in->Nodes->nodesMapping);
366     Finley_NodeMapping_free(in->Nodes->reducedNodesMapping);
367     Finley_NodeMapping_free(in->Nodes->degreesOfFreedomMapping);
368     Finley_NodeMapping_free(in->Nodes->reducedDegreesOfFreedomMapping);
369     Paso_Distribution_free(in->Nodes->nodesDistribution);
370     Paso_Distribution_free(in->Nodes->reducedNodesDistribution);
371     Paso_Distribution_free(in->Nodes->degreesOfFreedomDistribution);
372     Paso_Distribution_free(in->Nodes->reducedDegreesOfFreedomDistribution);
373     Paso_Coupler_free(in->Nodes->degreesOfFreedomCoupler);
374     Paso_Coupler_free(in->Nodes->reducedDegreesOfFreedomCoupler);
375     in->Nodes->nodesMapping=NULL;
376     in->Nodes->reducedNodesMapping=NULL;
377     in->Nodes->degreesOfFreedomMapping=NULL;
378     in->Nodes->reducedDegreesOfFreedomMapping=NULL;
379     in->Nodes->nodesDistribution=NULL;
380     in->Nodes->reducedNodesDistribution=NULL;
381     in->Nodes->degreesOfFreedomDistribution=NULL;
382     in->Nodes->reducedDegreesOfFreedomDistribution=NULL;
383     in->Nodes->degreesOfFreedomCoupler=NULL;
384     in->Nodes->reducedDegreesOfFreedomCoupler=NULL;
385     }
386     }
387    

  ViewVC Help
Powered by ViewVC 1.1.26