Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Mesh/TopologyInfo.cpp
Go to the documentation of this file.
1 /* *****************************************************************
2  MESQUITE -- The Mesh Quality Improvement Toolkit
3 
4  Copyright 2004 Lawrence Livermore National Laboratory. Under
5  the terms of Contract B545069 with the University of Wisconsin --
6  Madison, Lawrence Livermore National Laboratory retains certain
7  rights in this software.
8 
9  This library is free software; you can redistribute it and/or
10  modify it under the terms of the GNU Lesser General Public
11  License as published by the Free Software Foundation; either
12  version 2.1 of the License, or (at your option) any later version.
13 
14  This library 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 GNU
17  Lesser General Public License for more details.
18 
19  You should have received a copy of the GNU Lesser General Public License
20  (lgpl.txt) along with this library; if not, write to the Free Software
21  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 
23  kraftche@cae.wisc.edu
24 
25  ***************************************************************** */
26 
27 #include "MsqError.hpp"
28 #include "TopologyInfo.hpp"
29 
30 #include <string.h>
31 #include <assert.h>
32 
33 namespace Mesquite {
34 
35 TopologyInfo TopologyInfo::instance;
36 
37 
39 {
40  memset( dimMap, 0, sizeof(dimMap) );
41  memset( adjMap, 0, sizeof(adjMap) );
42  memset( edgeMap, 0, sizeof(edgeMap) );
43  memset( faceMap, 0, sizeof(faceMap) );
44 
45  dimMap[POLYGON ] = 2;
46  dimMap[TRIANGLE] = 2;
47  dimMap[QUADRILATERAL] = 2;
48  dimMap[POLYHEDRON] = 3;
49  dimMap[TETRAHEDRON] = 3;
50  dimMap[HEXAHEDRON] = 3;
51  dimMap[PRISM] = 3;
52  dimMap[PYRAMID] = 3;
53  dimMap[SEPTAHEDRON] = 3;
54 
55  adjMap[TRIANGLE][0] = 3;
56  adjMap[TRIANGLE][1] = 3;
57 
58  adjMap[QUADRILATERAL][0] = 4;
59  adjMap[QUADRILATERAL][1] = 4;
60 
61  adjMap[TETRAHEDRON][0] = 4;
62  adjMap[TETRAHEDRON][1] = 6;
63  adjMap[TETRAHEDRON][2] = 4;
64 
65  adjMap[HEXAHEDRON][0] = 8;
66  adjMap[HEXAHEDRON][1] = 12;
67  adjMap[HEXAHEDRON][2] = 6;
68 
69  adjMap[PRISM][0] = 6;
70  adjMap[PRISM][1] = 9;
71  adjMap[PRISM][2] = 5;
72 
73  adjMap[PYRAMID][0] = 5;
74  adjMap[PYRAMID][1] = 8;
75  adjMap[PYRAMID][2] = 5;
76 
77  adjMap[SEPTAHEDRON][0] = 7;
78  adjMap[SEPTAHEDRON][1] = 11;
79  adjMap[SEPTAHEDRON][2] = 6; /* See description in TSTT mesh interface doc */
80 
81  int side;
82  for (side = 0; side < 3; ++side)
83  {
84  edgeMap[TRIANGLE-FIRST_FACE][side][0] = side;
85  edgeMap[TRIANGLE-FIRST_FACE][side][1] = (side+1)%3;
86  }
87  for (side = 0; side < 4; ++side)
88  {
89  edgeMap[QUADRILATERAL-FIRST_FACE][side][0] = side;
90  edgeMap[QUADRILATERAL-FIRST_FACE][side][1] = (side+1)%4;
91  }
92  for (side = 0; side < 3; ++side)
93  {
94  edgeMap[TETRAHEDRON-FIRST_FACE][side][0] = side;
95  edgeMap[TETRAHEDRON-FIRST_FACE][side][1] = (side+1)%3;
96  }
97  for (side = 3; side < 6; ++side)
98  {
99  edgeMap[TETRAHEDRON-FIRST_FACE][side][0] = side -3 ;
100  edgeMap[TETRAHEDRON-FIRST_FACE][side][1] = 3;
101  }
102  for (side = 0; side < 4; ++side)
103  {
104  edgeMap[HEXAHEDRON-FIRST_FACE][side][0] = side;
105  edgeMap[HEXAHEDRON-FIRST_FACE][side][1] = (side+1)%4;
106  }
107  for (side = 4; side < 8; ++side)
108  {
109  edgeMap[HEXAHEDRON-FIRST_FACE][side][0] = side - 4;
110  edgeMap[HEXAHEDRON-FIRST_FACE][side][1] = side;
111  }
112  for (side = 8; side < 12; ++side)
113  {
114  edgeMap[HEXAHEDRON-FIRST_FACE][side][0] = side - 4;
115  edgeMap[HEXAHEDRON-FIRST_FACE][side][1] = 4+(side+1)%4;
116  }
117  for (side = 0; side < 3; ++side)
118  {
119  edgeMap[PRISM-FIRST_FACE][side][0] = side;
120  edgeMap[PRISM-FIRST_FACE][side][1] = (side+1)%3;
121  }
122  for (side = 3; side < 6; ++side)
123  {
124  edgeMap[PRISM-FIRST_FACE][side][0] = side - 3;
125  edgeMap[PRISM-FIRST_FACE][side][1] = side;
126  }
127  for (side = 6; side < 9; ++side)
128  {
129  edgeMap[PRISM-FIRST_FACE][side][0] = side-3;
130  edgeMap[PRISM-FIRST_FACE][side][1] = 3+(side+1)%3;
131  }
132  for (side = 0; side < 4; ++side)
133  {
134  edgeMap[PYRAMID-FIRST_FACE][side][0] = side;
135  edgeMap[PYRAMID-FIRST_FACE][side][1] = (side+1)%4;
136  }
137  for (side = 4; side < 8; ++side)
138  {
139  edgeMap[PYRAMID-FIRST_FACE][side][0] = side - 4;
140  edgeMap[PYRAMID-FIRST_FACE][side][1] = 4;
141  }
142 
143  for (side = 0; side < 3; ++side)
144  {
145  faceMap[TETRAHEDRON-FIRST_VOL][side][0] = 3;
146  faceMap[TETRAHEDRON-FIRST_VOL][side][1] = side;
147  faceMap[TETRAHEDRON-FIRST_VOL][side][2] = (side+1)%3;
148  faceMap[TETRAHEDRON-FIRST_VOL][side][3] = 3;
149  }
150  faceMap[TETRAHEDRON-FIRST_VOL][3][0] = 3;
151  faceMap[TETRAHEDRON-FIRST_VOL][3][1] = 2;
152  faceMap[TETRAHEDRON-FIRST_VOL][3][2] = 1;
153  faceMap[TETRAHEDRON-FIRST_VOL][3][3] = 0;
154 
155  for (side = 0; side < 4; ++side)
156  {
157  faceMap[HEXAHEDRON-FIRST_VOL][side][0] = 4;
158  faceMap[HEXAHEDRON-FIRST_VOL][side][1] = side;
159  faceMap[HEXAHEDRON-FIRST_VOL][side][2] = (side+1)%4;
160  faceMap[HEXAHEDRON-FIRST_VOL][side][3] = 4+(side+1)%4;
161  faceMap[HEXAHEDRON-FIRST_VOL][side][4] = side + 4;
162  }
163  faceMap[HEXAHEDRON-FIRST_VOL][4][0] = 4;
164  faceMap[HEXAHEDRON-FIRST_VOL][4][1] = 3;
165  faceMap[HEXAHEDRON-FIRST_VOL][4][2] = 2;
166  faceMap[HEXAHEDRON-FIRST_VOL][4][3] = 1;
167  faceMap[HEXAHEDRON-FIRST_VOL][4][4] = 0;
168  faceMap[HEXAHEDRON-FIRST_VOL][5][0] = 4;
169  faceMap[HEXAHEDRON-FIRST_VOL][5][1] = 4;
170  faceMap[HEXAHEDRON-FIRST_VOL][5][2] = 5;
171  faceMap[HEXAHEDRON-FIRST_VOL][5][3] = 6;
172  faceMap[HEXAHEDRON-FIRST_VOL][5][4] = 7;
173 
174  for (side = 0; side < 4; ++side)
175  {
176  faceMap[PYRAMID-FIRST_VOL][side][0] = 3;
177  faceMap[PYRAMID-FIRST_VOL][side][1] = side;
178  faceMap[PYRAMID-FIRST_VOL][side][2] = (side+1)%4;
179  faceMap[PYRAMID-FIRST_VOL][side][3] = 4;
180  }
181  faceMap[PYRAMID-FIRST_VOL][4][0] = 4;
182  faceMap[PYRAMID-FIRST_VOL][4][1] = 3;
183  faceMap[PYRAMID-FIRST_VOL][4][2] = 2;
184  faceMap[PYRAMID-FIRST_VOL][4][3] = 1;
185  faceMap[PYRAMID-FIRST_VOL][4][4] = 0;
186 
187  for (side = 0; side < 3; ++side)
188  {
189  faceMap[PRISM-FIRST_VOL][side][0] = 4;
190  faceMap[PRISM-FIRST_VOL][side][1] = side;
191  faceMap[PRISM-FIRST_VOL][side][2] = (side+1)%3;
192  faceMap[PRISM-FIRST_VOL][side][3] = 3+(side+1)%3;
193  faceMap[PRISM-FIRST_VOL][side][4] = side + 3;
194  }
195  faceMap[PRISM-FIRST_VOL][3][0] = 3;
196  faceMap[PRISM-FIRST_VOL][3][1] = 2;
197  faceMap[PRISM-FIRST_VOL][3][2] = 1;
198  faceMap[PRISM-FIRST_VOL][3][3] = 0;
199  faceMap[PRISM-FIRST_VOL][4][0] = 3;
200  faceMap[PRISM-FIRST_VOL][4][1] = 3;
201  faceMap[PRISM-FIRST_VOL][4][2] = 4;
202  faceMap[PRISM-FIRST_VOL][4][3] = 5;
203 }
204 
206  unsigned num_nodes,
207  bool& midedge,
208  bool& midface,
209  bool& midvol,
210  MsqError& err )
211 {
212  midedge = midface = midvol = false;
213  if (topo >= MIXED || num_nodes < instance.adjMap[topo][0])
214  {
215  MSQ_SETERR(err)("Invalid element topology", MsqError::INVALID_ARG);
216  return;
217  }
218 
219  unsigned dim = instance.dimMap[topo];
220  assert( num_nodes >= instance.adjMap[topo][0] );
221  unsigned nodes = num_nodes - instance.adjMap[topo][0];
222  unsigned edges = instance.adjMap[topo][1];
223  unsigned faces = instance.adjMap[topo][2];
224  if (edges && nodes >= edges)
225  {
226  nodes -= edges;
227  midedge = true;
228  }
229  if (faces && nodes >= faces)
230  {
231  nodes -= faces;
232  midface = true;
233  }
234  if (1 == nodes)
235  {
236  if (2 == dim)
237  {
238  nodes -= 1;
239  midface = true;
240  }
241  else if(3 == dim)
242  {
243  nodes -= 1;
244  midvol = true;
245  }
246  }
247 
248  if (nodes)
249  {
250  MSQ_SETERR(err)("Invalid element topology", MsqError::INVALID_STATE);
251  }
252 }
253 
254 
256  unsigned edge,
257  MsqError& err)
258 {
259  if (topo < (EntityTopology)FIRST_FACE ||
260  topo > (EntityTopology)LAST_VOL ||
261  edge >= edges( topo ) )
262  {
264  topo = (EntityTopology)FIRST_FACE;
265  edge = 0;
266  }
267 
268  return instance.edgeMap[topo-FIRST_FACE][edge];
269 }
270 
272  unsigned face,
273  unsigned& length,
274  MsqError& err )
275 {
276  if (topo < (EntityTopology)FIRST_VOL ||
277  topo > (EntityTopology)LAST_VOL ||
278  face >= faces( topo ) )
279  {
281  topo = (EntityTopology)FIRST_VOL;
282  face = 0;
283  }
284 
285  length = instance.faceMap[topo-FIRST_VOL][face][0];
286  return instance.faceMap[topo-FIRST_VOL][face] + 1;
287 }
288 
289 
290 
291 
293  unsigned dim,
294  unsigned side,
295  unsigned& count_out,
296  MsqError& err )
297 {
298  static const unsigned all[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
299  const unsigned* result;
300 
301  if (dim != 0 && dim == dimension(topo))
302  {
303  count_out = corners( topo );
304  result = all;
305  }
306  else if (dim == 1)
307  {
308  count_out = 2;
309  result = edge_vertices( topo, side, err );
310  }
311  else if( dim == 2)
312  {
313  result = face_vertices( topo, side, count_out, err );
314  }
315  else
316  {
318  count_out = 0;
319  result = 0;
320  }
321  return result;
322 }
323 
324 
325 
327  unsigned num_nodes,
328  unsigned node_index,
329  unsigned& side_dim_out,
330  unsigned& side_num_out,
331  MsqError& err )
332 {
333  if (topo >= (EntityTopology)MIXED || num_nodes < instance.adjMap[topo][0])
334  {
335  MSQ_SETERR(err)("Invalid element topology", MsqError::INVALID_ARG);
336  return;
337  }
338 
339  unsigned nodes = instance.adjMap[topo][0];
340  unsigned edges = instance.adjMap[topo][1];
341  unsigned faces = instance.adjMap[topo][2];
342  side_num_out = node_index;
343 
344  if (side_num_out < nodes)
345  {
346  side_dim_out = 0;
347  return;
348  }
349  num_nodes -= nodes;
350  side_num_out -= nodes;
351 
352  if (edges && num_nodes >= edges)
353  {
354  if (side_num_out < edges)
355  {
356  side_dim_out = 1;
357  return;
358  }
359  num_nodes -= edges;
360  side_num_out -= edges;
361  }
362  if (faces && num_nodes >= faces)
363  {
364  if (side_num_out < faces)
365  {
366  side_dim_out = 2;
367  return;
368  }
369  num_nodes -= faces;
370  side_num_out -= faces;
371  }
372  if (side_num_out == 0)
373  {
374  side_dim_out = instance.dimMap[topo];
375  side_num_out = 0;
376  return;
377  }
378 
380 }
381 
382 
383 
384 
385 
386 
387 } //namepsace Mesquite
unsigned dimMap[MIXED]
Get dimension of entity given topology.
unsigned faceMap[LAST_VOL-FIRST_VOL+1][MAX_FACES][MAX_FACE_CONN]
Vertex indices for element faces.
Definition: face.h:90
Used to hold the error state and return it to the application.
EntityTopology
Definition: Mesquite.hpp:92
unsigned edgeMap[LAST_VOL-FIRST_FACE+1][MAX_EDGES][2]
Vertex indices for element edges.
static unsigned faces(EntityTopology topo)
Get the number of faces in a given topology.
double length(Vector3D *const v, int n)
const int num_nodes
Definition: ex1.C:96
invalid function argument passed
static void higher_order(EntityTopology topo, unsigned num_nodes, bool &midedge, bool &midface, bool &midvol, MsqError &err)
Check which mid-nodes a higher-order element has.
static unsigned dimension(EntityTopology topo)
Dimension of element topology.
static const unsigned * edge_vertices(EntityTopology topo, unsigned edge_number, MsqError &err)
Get indices of edge ends in element connectivity array.
#define MSQ_SETERR(err)
Macro to set error - use err.clear() to clear.
static unsigned corners(EntityTopology topo)
Get the number of defining vertices for a given element topology.
static unsigned edges(EntityTopology topo)
Get the number of edges in a given topology.
static const unsigned * face_vertices(EntityTopology topo, unsigned face_number, unsigned &num_vertices_out, MsqError &err)
Get face corner indices in element connectivity array.
unsigned adjMap[MIXED][3]
Get number of adj entities of dimension 0, 1 and dimension 2.
static const unsigned * side_vertices(EntityTopology topo, unsigned side_dimension, unsigned side_number, unsigned &num_verts_out, MsqError &err)
Get corner indices of side.
static T_VertexSet * face
Definition: vinci_lass.c:79
object is in an invalid state
static void side_number(EntityTopology topo, unsigned connectivity_length, unsigned node_index, unsigned &side_dimension_out, unsigned &side_number_out, MsqError &err)
Return which side the specified mid-node lies on.