p4est  1.1
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
p6est_lnodes.h
1 /*
2  This file is part of p4est.
3  p4est is a C library to manage a collection (a forest) of multiple
4  connected adaptive quadtrees or octrees in parallel.
5 
6  Copyright (C) 2014 The University of Texas System
7  Written by Carsten Burstedde, Lucas C. Wilcox, and Tobin Isaac
8 
9  p4est is free software; you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation; either version 2 of the License, or
12  (at your option) any later version.
13 
14  p4est is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with p4est; if not, write to the Free Software Foundation, Inc.,
21  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 */
23 
24 #ifndef P6EST_LNODES_H
25 #define P6EST_LNODES_H
26 
27 #include <p6est.h>
28 #include <p6est_ghost.h>
29 #include <p4est_lnodes.h>
30 #include <p8est_lnodes.h>
31 
32 SC_EXTERN_C_BEGIN;
33 
34 /* A p6est_lnodes_t is exactly the same as a p8est_lnodes_t, with the only
35  * difference being that the face_codes are interpreted differently to account
36  * for the types of hanging faces that occur in a p6est. Please see the
37  * documentation for p8est_lnodes */
38 
39 /* The only other differece is in the numbering of nodes and the number of
40  * faces.
41  *
42  * Columns of nodes are numbered contiguously: this still generates a
43  * partition-unique numbering.
44  *
45  * Although we call a p2est_quadrant_t coordinate layer->z, the orientaton of
46  * a layer from lnodes perspective is that the vertical axis is the X axis of
47  * the 3D element, the x axis of the columns is the Y axis of the 3D element,
48  * and the y axis of the columns is the Z axis of the 3D element
49  */
50 
52 typedef p8est_lnodes_code_t p6est_lnodes_code_t;
55 
116 /*@unused@*/
117 static inline int
118 p6est_lnodes_decode (p6est_lnodes_code_t face_code, int hanging_face[6],
119  int hanging_edge[12])
120 {
121  P4EST_ASSERT (face_code >= 0);
122 
123  if (face_code) {
124  /* we pack the p4est_lnodes_code_t at the bottom, followed by a bit
125  * indicating whether this layer is a first or second sibling, followed by
126  * four bits indicating which of the four side faces are layerwise
127  * nonconforming, followed by four bits indicating which of the four side
128  * edges are layerwise nonconforming */
129  p4est_lnodes_code_t fc4 = face_code & 0x000f;
130  int16_t h = (face_code & 0x0010) >> 4;
131  int16_t work = face_code >> 5;
132  int hf;
133  int f, e, w;
134 
135  memset (hanging_face, -1, 6 * sizeof (int));
136  memset (hanging_edge, -1, 12 * sizeof (int));
137 
138  /* the first two faces are the top and bottom faces, which we know are not
139  * hanging */
140  p4est_lnodes_decode (fc4, hanging_face + 2);
141  for (f = 0; f < 4; f++) {
142  hf = hanging_face[f + 2];
143  w = work & 0x0001;
144  if (hf >= 0) {
145  hanging_edge[p8est_face_edges[f + 2][2]] = 2 + hf;
146  hanging_edge[p8est_face_edges[f + 2][3]] = 2 + hf;
147  hanging_edge[p8est_face_edges[f + 2][1 ^ hf]] = 4;
148  if (w) {
149  hanging_edge[p8est_face_edges[f + 2][3 ^ h]] = 4;
150  hanging_edge[p8est_face_edges[f + 2][1 ^ hf]] = 4;
151  hanging_edge[p8est_face_edges[f + 2][hf]] = 2 + h;
152  hanging_face[f + 2] = (hf << 1) | h;
153  }
154  else {
155  hanging_face[f + 2] = 4 + hf;
156  }
157  }
158  else if (w) {
159  hanging_edge[p8est_face_edges[f + 2][3 ^ h]] = 4;
160  hanging_edge[p8est_face_edges[f + 2][0]] =
161  SC_MAX (hanging_edge[p8est_face_edges[f + 2][0]], 2 + h);
162  hanging_edge[p8est_face_edges[f + 2][1]] =
163  SC_MAX (hanging_edge[p8est_face_edges[f + 2][1]], 2 + h);
164  hanging_face[f + 2] = 6 + h;
165  }
166  work >>= 1;
167  }
168  for (e = 0; e < 4; e++) {
169  if (work & 0x0001) {
170  if (hanging_edge[e] < 0) {
171  hanging_edge[e] = h;
172  }
173 #ifdef P4EST_DEBUG
174  else {
175  P4EST_ASSERT (hanging_edge[e] == 2 + h || hanging_edge[e] == 4);
176  }
177 #endif
178  }
179  work >>= 1;
180  }
181  return 1;
182  }
183  else {
184  return 0;
185  }
186 }
187 
188 p6est_lnodes_t *p6est_lnodes_new (p6est_t * p6est,
189  p6est_ghost_t * ghost_layer,
190  int degree);
191 
192 static inline void
193 p6est_lnodes_destroy (p6est_lnodes_t * lnodes)
194 {
195  p8est_lnodes_destroy (lnodes);
196 }
197 
198 /*@unused@*/
199 static inline p6est_lnodes_buffer_t *
200 p6est_lnodes_share_owned_begin (sc_array_t * node_data,
201  p6est_lnodes_t * lnodes)
202 {
203  return p8est_lnodes_share_owned_begin (node_data, lnodes);
204 }
205 
206 /*@unused@*/
207 static inline void
208 p6est_lnodes_share_owned_end (p6est_lnodes_buffer_t * buffer)
209 {
210  p8est_lnodes_share_owned_end (buffer);
211 }
212 
213 /*@unused@*/
214 static inline void
215 p6est_lnodes_share_owned (sc_array_t * node_data, p6est_lnodes_t * lnodes)
216 {
217  p8est_lnodes_share_owned (node_data, lnodes);
218 }
219 
220 /*@unused@*/
221 static inline p6est_lnodes_buffer_t *
222 p6est_lnodes_share_all_begin (sc_array_t * node_data, p6est_lnodes_t * lnodes)
223 {
224  return p8est_lnodes_share_all_begin (node_data, lnodes);
225 }
226 
227 /*@unused@*/
228 static inline void
229 p6est_lnodes_share_all_end (p6est_lnodes_buffer_t * buffer)
230 {
231  p8est_lnodes_share_all_end (buffer);
232 }
233 
234 /*@unused@*/
235 static inline p6est_lnodes_buffer_t *
236 p6est_lnodes_share_all (sc_array_t * node_data, p6est_lnodes_t * lnodes)
237 {
238  return p8est_lnodes_share_all (node_data, lnodes);
239 }
240 
241 /*@unused@*/
242 static inline void
243 p6est_lnodes_buffer_destroy (p6est_lnodes_buffer_t * buffer)
244 {
245  p8est_lnodes_buffer_destroy (buffer);
246 }
247 
248 /*@unused@*/
249 static inline p6est_lnodes_rank_t *
250 p6est_lnodes_rank_array_index_int (sc_array_t * array, int it)
251 {
252  return p8est_lnodes_rank_array_index_int (array, it);
253 }
254 
255 /*@unused@*/
256 static inline p6est_lnodes_rank_t *
257 p6est_lnodes_rank_array_index (sc_array_t * array, size_t it)
258 {
259  return p8est_lnodes_rank_array_index (array, it);
260 }
261 
262 /*@unused@*/
263 static inline p4est_gloidx_t
264 p6est_lnodes_global_index (p6est_lnodes_t * lnodes, p4est_locidx_t lidx)
265 {
266  return p8est_lnodes_global_index (lnodes, lidx);
267 }
268 
269 SC_EXTERN_C_END;
270 
271 #endif /* !P6EST_LNODES */
columns of layers that neighbor the local domain
Definition: p6est_ghost.h:40
const int p8est_face_edges[6][4]
Store the face numbers 0..12 for each tree face.
Definition: p8est_connectivity.c:36
The p6est forest datatype.
Definition: p6est.h:163
passing columns of layers and data to neighboring processes
int64_t p4est_gloidx_t
Typedef for globally unique indexing of quadrants.
Definition: p4est_base.h:84
The sc_array object provides a large array of equal-size elements.
Definition: sc_containers.h:92
Store a parallel numbering of Lobatto points of a given degree > 0.
Definition: p8est_lnodes.h:111
p8est_lnodes_buffer_t handles the communication of data associated with nodes.
Definition: p8est_lnodes.h:291
A hybrid 2D+1D AMR extension.
The structure stored in the sharers array.
Definition: p8est_lnodes.h:139
int32_t p4est_locidx_t
Typedef for processor-local indexing of quadrants and nodes.
Definition: p4est_base.h:74