Exodus 7.22

Polyhedral Element Support

# Storage of 3D arbitrary polyhedra elements in Exodus.

The 3D polyhedra elements are represented as elements with a variable number of faces in their connectivity. The faces can either be regular faces such as quadrilateral or triangles; or they can be topologically two-dimensional arbitrary polyhedra themselves.

An arbitrary polyhedra 3D element block will have an element type of "nfaced" or "NFACED".

The faces that are used in the connectivity of this block should be defined in one or more face blocks. If the faces are arbitrary polyhedra, then they will have a face type of "nsided" or "NSIDED".

An annotated example of defining an arbitrary polyhedral element block consisting of 3 elements is shown below.

The three elements have the following geometry:

- Element 1: 5 faces.
  - Face 1: triangle with nodes 5, 6, 8
  - Face 2: triangle with nodes 2, 1, 4
  - Face 3: quadrilateral with nodes 6, 2, 4, 8
  - Face 4: quadrilateral with nodes 8, 4, 1, 5
  - Face 5: quadrilateral with nodes 1, 2, 6, 5
- Element 2: 5 faces.
  - Face 6: triangle with nodes 5, 8, 7
  - Face 7: triangle with nodes 1, 3, 4
  - Face 8: quadrilateral with nodes 7, 8, 4, 3
  - Face 9: quadrilateral with nodes 7, 3, 1, 5
  - Face 4: quadrilateral with nodes 8, 4, 1, 5 (shared with element 1)
- Element 3: 7 faces.
  - Face 8: quadrilateral with nodes 7, 8, 4, 3 (shared with element 2)
  - Face 10: pentagonal with nodes 8, 4, 14, 10, 12
  - Face 11: pentagonal with nodes 7, 11, 9, 13, 3
  - Face 12: quadrilateral with nodes 7, 8, 12, 11
  - Face 13: quadrilateral with nodes 11, 12, 10, 9
  - Face 14: quadrilateral with nodes 9, 10, 14, 13
  - Face 15: quadrilateral with nodes 12, 14, 4, 3

The Exodus model is created via the following calls:

- Output the initial information. Since the model contains faces and a face block, the "extended" version of the `ex_put_init_ext()` call must be used:
  ex_init_params par;
  ex_copy_string(par.title, "This is the title", MAX_LINE_LENGTH + 1);
  par.num_dim = 3;
  par.num_nodes = 14;
  par.num_edge = 0;
  par.num_edge_blk = 0;
  par.num_face = 15;
  par.num_face_blk = 1;
  par.num_elem = 3;
  par.num_elem_blk = 1;
  par.num_node_sets = 0;
  par.num_edge_sets = 0;
  par.num_face_sets = 0;
  par.num_side_sets = 0;
  par.num_elem_sets = 0;
  par.num_node_maps = 0;
  par.num_edge_maps = 0;
  par.num_face_maps = 0;
  par.num_elem_maps = 0;
  ex_put_init_ext (exoid, &par);
- Coordinate output is normal...
- Define the face block.
  block_name = "face_block_1";
  num_face_in_block[0] = 15;
  num_total_nodes_per_blk[0] = 58;
  block_id = 10;
  ex_put_block (exoid, EX_FACE_BLOCK, block_id, "nsided",
  num_face_in_block[0],
  num_total_nodes_per_blk[0],
  0, 0, 0);
  ex_put_name(exoid, EX_FACE_BLOCK, block_id, block_name);
- Output the face connectivity for "face_block_1". The data for the face connectivity is listed above; a portion is shown below...
  connect = (int *) calloc(num_total_nodes_per_blk[0], sizeof(int));
  i = 0
  connect[i++] = 5;
  connect[i++] = 6;
  connect[i++] = 8; /* connectivity of face 1 of element 1 */
  connect[i++] = 2;
  connect[i++] = 1;
  connect[i++] = 4; /* face 2 of element 1 */
  connect[i++] = 6;
  connect[i++] = 2;
  connect[i++] = 4;
  connect[i++] = 8; /* face 3 of element 1 */
  connect[i++] = 8;
  connect[i++] = 4;
  connect[i++] = 1;
  connect[i++] = 5; /* face 4 of element 1 */
  connect[i++] = 1;
  connect[i++] = 2;
  connect[i++] = 6;
  connect[i++] = 5; /* face 5 of element 1 */
  connect[i++] = 5;
  connect[i++] = 8;
  connect[i++] = 7; /* connectivity of face 1 of element 2 */
  ... and so on....
  assert(i == num_total_nodes_per_blk[0]);
  ex_put_conn (exoid, EX_FACE_BLOCK, block_id, connect, NULL, NULL);
- Output the number of nodes per face count for "face_block_1":
  j = 0;
  nnpe[ 1] = 3; /* Face 1 */
  nnpe[ 2] = 3;
  nnpe[ 3] = 4;
  nnpe[ 4] = 4;
  nnpe[ 5] = 4;
  nnpe[ 6] = 3;
  nnpe[ 7] = 3;
  nnpe[ 8] = 4;
  nnpe[ 9] = 4;
  nnpe[10] = 5;
  nnpe[11] = 5;
  nnpe[12] = 4;
  nnpe[13] = 4;
  nnpe[14] = 4;
  nnpe[15] = 4;
  ex_put_entity_count_per_polyhedra(exoid, EX_FACE_BLOCK, block_id, nnpe);

- The face block is now fully defined; now define the nfaced element block which uses these faces.

  block_name = "nfaced_1";
  num_elem_in_block = 3;
  num_total_faces_per_blk = 5 + 5 + 7;
  block_id = 10;
  ex_put_block (exoid, EX_ELEM_BLOCK, block_id, "nfaced",
  num_elem_in_block,
  0, /* nodes */
  0, /* edges */
  num_total_faces_per_blk,
  0); /* attribute count */
  ex_put_name(exoid, EX_ELEM_BLOCK, block_id, block_name);

  In the `ex_put_block()` function, the element type is "nfaced". The connectivity is defined in terms of the faces, so the node and edge arguments are passed zeros. The nodal connectivity can be defined, but it isn't required. The face connectivity argument for an nfaced block is the total number of faces in the connectivity for all elements in the nfaced block.

- Write the face connectivity:
  /* write element-face connectivity */
  connect = (int *) calloc(num_total_faces_per_blk, sizeof(int));
  i = 0;
  connect[i++] = 1;
  connect[i++] = 2;
  connect[i++] = 3;
  connect[i++] = 4;
  connect[i++] = 5;
  connect[i++] = 4;
  connect[i++] = 6;
  connect[i++] = 7;
  connect[i++] = 8;
  connect[i++] = 9;
  connect[i++] = 8;
  connect[i++] = 10;
  connect[i++] = 11;
  connect[i++] = 12;
  connect[i++] = 13;
  connect[i++] = 14;
  connect[i++] = 15;
  assert(i == num_total_faces_per_blk);
  ex_put_conn (exoid, EX_ELEM_BLOCK, block_id, NULL, NULL, connect);
- Output the number of faces per element count for "nfaced_1":
  nnpe[1] = 5; /* Number of faces per element 1 */
  nnpe[2] = 5; /* Number of faces per element 2 */
  nnpe[3] = 7; /* Number of faces per element 3 */
  ex_put_entity_count_per_polyhedra(exoid, EX_ELEM_BLOCK, block_id, nnpe);
- That's all; the rest of the calls are the same as normal Exodus except:
  - There is a similar `ex_get_entity_count_per_polyhedra()` function for read.
  - The `ex_get_block()` functions return the total number of nodes or faces for all faces or element for "nfaced" and "nsided" blocks and not the number per element
- An example read/write usage is shown in the testwt-nfaced.c and testrd-nfaced files.
- These changes are in Exodus version v4.93 and later.

ex_init_params::num_side_sets
int64_t num_side_sets
Definition: exodusII.h:342
ex_put_block
int ex_put_block(int exoid, ex_entity_type blk_type, ex_entity_id blk_id, const char *entry_descrip, int64_t num_entries_this_blk, int64_t num_nodes_per_entry, int64_t num_edges_per_entry, int64_t num_faces_per_entry, int64_t num_attr_per_entry)
Definition: ex_put_block.c:73
ex_init_params::num_dim
int64_t num_dim
Definition: exodusII.h:331
ex_put_name
int ex_put_name(int exoid, ex_entity_type obj_type, ex_entity_id entity_id, const char *name)
Definition: ex_put_name.c:67
ex_init_params::num_edge_maps
int64_t num_edge_maps
Definition: exodusII.h:345
ex_init_params::num_face_maps
int64_t num_face_maps
Definition: exodusII.h:346
ex_init_params::num_elem
int64_t num_elem
Definition: exodusII.h:337
ex_init_params::num_face
int64_t num_face
Definition: exodusII.h:335
ex__obj_stats::exoid
int exoid
Definition: exodusII_int.h:666
ex_init_params::num_node_maps
int64_t num_node_maps
Definition: exodusII.h:344
ex_init_params::num_node_sets
int64_t num_node_sets
Definition: exodusII.h:339
MAX_LINE_LENGTH
#define MAX_LINE_LENGTH
Definition: exodusII.h:306
ex_init_params::num_elem_blk
int64_t num_elem_blk
Definition: exodusII.h:338
ex_put_conn
int ex_put_conn(int exoid, ex_entity_type blk_type, ex_entity_id blk_id, const void_int *node_conn, const void_int *elem_edge_conn, const void_int *elem_face_conn)
Definition: ex_put_conn.c:71
EX_FACE_BLOCK
Definition: exodusII.h:259
ex_init_params::num_elem_maps
int64_t num_elem_maps
Definition: exodusII.h:347
ex_init_params::num_face_blk
int64_t num_face_blk
Definition: exodusII.h:336
ex_init_params::num_elem_sets
int64_t num_elem_sets
Definition: exodusII.h:343
ex_init_params::num_nodes
int64_t num_nodes
Definition: exodusII.h:332
ex_put_init_ext
int ex_put_init_ext(int exoid, const ex_init_params *model)
Definition: ex_put_init_ext.c:237
ex_init_params::num_edge_sets
int64_t num_edge_sets
Definition: exodusII.h:340
ex_init_params::num_edge_blk
int64_t num_edge_blk
Definition: exodusII.h:334
ex_init_params::title
char title[MAX_LINE_LENGTH+1]
Definition: exodusII.h:330
ex_put_entity_count_per_polyhedra
int ex_put_entity_count_per_polyhedra(int exoid, ex_entity_type blk_type, ex_entity_id blk_id, const int *entity_counts)
Definition: ex_put_entity_count_per_polyhedra.c:52
EX_ELEM_BLOCK
Definition: exodusII.h:261
ex_init_params::num_face_sets
int64_t num_face_sets
Definition: exodusII.h:341
ex_init_params::num_edge
int64_t num_edge
Definition: exodusII.h:333
ex_copy_string
char * ex_copy_string(char *dest, char const *source, size_t elements)
Definition: ex_utils.c:2174
ex_init_params
Definition: exodusII.h:328