/[escript]/branches/domexper/dudley/src/Mesh_createNodeFileMappings.c
ViewVC logotype

Contents of /branches/domexper/dudley/src/Mesh_createNodeFileMappings.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1387 - (show annotations)
Fri Jan 11 07:45:26 2008 UTC (11 years, 5 months ago) by trankine
Original Path: temp/finley/src/Mesh_createNodeFileMappings.c
File MIME type: text/plain
File size: 17143 byte(s)
Restore the trunk that existed before the windows changes were committed to the (now moved to branches) old trunk.
1
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 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 #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 if (i < 0 || i >= len_loc_dof) { printf("BOUNDS_CHECK %s %d i=%d\n", __FILE__, __LINE__, i); exit(1); }
96 #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 if (i < 0 || i >= len_loc_dof) { printf("BOUNDS_CHECK %s %d p=%d i=%d\n", __FILE__, __LINE__, p, i); exit(1); }
109 #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 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 #endif
120 offsetInShared[numNeighbors]=lastn;
121 numNeighbors++;
122 lastn=n;
123 }
124 }
125 }
126 #ifdef BOUNDS_CHECK
127 if (numNeighbors < 0 || numNeighbors >= mpiSize+1) { printf("BOUNDS_CHECK %s %d numNeighbors=%d\n", __FILE__, __LINE__, numNeighbors); exit(1); }
128 #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 if (i < 0 || i >= numNodes*(p_max-p_min+1)) { printf("BOUNDS_CHECK %s %d i=%d\n", __FILE__, __LINE__, i); exit(1); }
144 }
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 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 #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 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 #endif
178 offsetInShared[numNeighbors]=lastn;
179 numNeighbors++;
180 lastn=n;
181 }
182 }
183 }
184 #ifdef BOUNDS_CHECK
185 if (numNeighbors < 0 || numNeighbors >= mpiSize+1) { printf("BOUNDS_CHECK %s %d numNeighbors=%d\n", __FILE__, __LINE__, numNeighbors); exit(1); }
186 #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
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 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