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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3231 - (show annotations)
Fri Oct 1 01:53:46 2010 UTC (9 years, 4 months ago) by jfenwick
File MIME type: text/plain
File size: 5088 byte(s)
Fix MPI and OMP problems not detected in serial

1
2 /*******************************************************
3 *
4 * Copyright (c) 2003-2010 by University of Queensland
5 * Earth Systems Science Computational Center (ESSCC)
6 * http://www.uq.edu.au/esscc
7 *
8 * Primary Business: Queensland, Australia
9 * Licensed under the Open Software License version 3.0
10 * http://www.opensource.org/licenses/osl-3.0.php
11 *
12 *******************************************************/
13
14 /**************************************************************/
15
16 /* Dudley: Mesh */
17
18 /* at input the element nodes refers to the numbering defined the global Id assigned to the nodes in the */
19 /* NodeFile. It is also not ensured that all nodes refered by an element is actually available */
20 /* on the process. At the output, a local node labeling is used and all nodes are available */
21 /* In particular the numbering of the element nodes is between 0 and in->NodeFile->numNodes */
22 /* The function does not create a distribution of the degrees of freedom. */
23
24 /**************************************************************/
25
26 #include "Mesh.h"
27 #include "Util.h"
28
29 /**************************************************************/
30
31 void Dudley_Mesh_resolveNodeIds(Dudley_Mesh * in)
32 {
33
34 index_t min_id, max_id, min_id2, max_id2, global_min_id, global_max_id,
35 *globalToNewLocalNodeLabels = NULL, *newLocalToGlobalNodeLabels = NULL;
36 dim_t len, n, newNumNodes, numDim;
37 Dudley_NodeFile *newNodeFile = NULL;
38 #ifdef ESYS_MPI
39 index_t id_range[2], global_id_range[2];
40 #endif
41 numDim = Dudley_Mesh_getDim(in);
42 /* find the minimum and maximum id used by elements: */
43 min_id = INDEX_T_MAX;
44 max_id = -INDEX_T_MAX;
45 Dudley_ElementFile_setNodeRange(&min_id2, &max_id2, in->Elements);
46 max_id = MAX(max_id, max_id2);
47 min_id = MIN(min_id, min_id2);
48 Dudley_ElementFile_setNodeRange(&min_id2, &max_id2, in->FaceElements);
49 max_id = MAX(max_id, max_id2);
50 min_id = MIN(min_id, min_id2);
51 Dudley_ElementFile_setNodeRange(&min_id2, &max_id2, in->Points);
52 max_id = MAX(max_id, max_id2);
53 min_id = MIN(min_id, min_id2);
54 #ifdef ESYS_MPI
55 id_range[0] = -min_id;
56 id_range[1] = max_id;
57 MPI_Allreduce(id_range, global_id_range, 2, MPI_INT, MPI_MAX, in->MPIInfo->comm);
58 global_min_id = -global_id_range[0];
59 global_max_id = global_id_range[1];
60 #else
61 global_min_id = min_id;
62 global_max_id = max_id;
63 #endif
64 #ifdef Dudley_TRACE
65 printf("Node id range used by elements is %d:%d\n", global_min_id, global_max_id);
66 #endif
67 if (min_id > max_id)
68 {
69 max_id = -1;
70 min_id = 0;
71 }
72
73 /* allocate mappings for new local node labeling to global node labeling (newLocalToGlobalNodeLabels)
74 and global node labeling to the new local node labeling (globalToNewLocalNodeLabels[i-min_id] is the
75 new local id of global node i) */
76 len = (max_id >= min_id) ? max_id - min_id + 1 : 0;
77 globalToNewLocalNodeLabels = TMPMEMALLOC(len, index_t); /* local mask for used nodes */
78 newLocalToGlobalNodeLabels = TMPMEMALLOC(len, index_t);
79 if (!((Dudley_checkPtr(globalToNewLocalNodeLabels) && Dudley_checkPtr(newLocalToGlobalNodeLabels))))
80 {
81
82 #pragma omp parallel
83 {
84 #pragma omp for private(n) schedule(static)
85 for (n = 0; n < len; n++)
86 newLocalToGlobalNodeLabels[n] = -1;
87 #pragma omp for private(n) schedule(static)
88 for (n = 0; n < len; n++)
89 globalToNewLocalNodeLabels[n] = -1;
90 }
91
92 /* mark the nodes referred by elements in globalToNewLocalNodeLabels which is currently used as a mask: */
93 Dudley_Mesh_markNodes(globalToNewLocalNodeLabels, min_id, in, FALSE);
94
95 /* create a local labeling newLocalToGlobalNodeLabels of the local nodes by packing the mask globalToNewLocalNodeLabels */
96
97 newNumNodes = Dudley_Util_packMask(len, globalToNewLocalNodeLabels, newLocalToGlobalNodeLabels);
98
99 /* invert the new labeling and shift the index newLocalToGlobalNodeLabels to global node ids */
100 #pragma omp parallel for private(n) schedule(static)
101 for (n = 0; n < newNumNodes; n++)
102 {
103 #ifdef BOUNDS_CHECK
104 if (n >= len || n < 0)
105 {
106 printf("BOUNDS_CHECK %s %d n=%d\n", __FILE__, __LINE__, n);
107 exit(1);
108 }
109 if (newLocalToGlobalNodeLabels[n] >= len || newLocalToGlobalNodeLabels[n] < 0)
110 {
111 printf("BOUNDS_CHECK %s %d n=%d\n", __FILE__, __LINE__, n);
112 exit(1);
113 }
114 #endif
115 globalToNewLocalNodeLabels[newLocalToGlobalNodeLabels[n]] = n;
116 newLocalToGlobalNodeLabels[n] += min_id;
117 }
118 /* create a new table */
119 newNodeFile = Dudley_NodeFile_alloc(numDim, in->MPIInfo);
120 if (Dudley_noError())
121 {
122 Dudley_NodeFile_allocTable(newNodeFile, newNumNodes);
123 }
124 if (Dudley_noError())
125 {
126 Dudley_NodeFile_gather_global(newLocalToGlobalNodeLabels, in->Nodes, newNodeFile);
127 }
128 if (Dudley_noError())
129 {
130 Dudley_NodeFile_free(in->Nodes);
131 in->Nodes = newNodeFile;
132 /* relable nodes of the elements: */
133 Dudley_Mesh_relableElementNodes(globalToNewLocalNodeLabels, min_id, in);
134 }
135 }
136 TMPMEMFREE(globalToNewLocalNodeLabels);
137 TMPMEMFREE(newLocalToGlobalNodeLabels);
138 if (!Dudley_noError())
139 {
140 Dudley_NodeFile_free(newNodeFile);
141 }
142 }

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.26