# CFD General Notation System (CGNS) Usage for Unstructured Grids

Edwin van der Weide
Stanford University

## Example Unstructured Grid  ## Unstructured grid storage

• Several possibilities to store an unstructured grid.
• Every element type is stored in a separate Elements_t node. Recommended.
• One Elements_t node, which stores all elements using the MIXED Element type.
• Store all elements as arbitrary polygons, NGON_n Element type.
• Arbitrary combinations of the possibilities above.
• Pros
• Flexibility.
• Cons
• Reading becomes complicated.

## Connectivities (linear elements) See sids/conv.html#unstructgrid for all supported elements.

## Info in the zone

• # elements = # elements of highest dimension.
• E.g. for a 3D problem the number elements of the surface grid should NOT be stored in the zone. ## Single Zone vs. Multiple Zones

• Multiple zones can be used when there is relative motion, non-matching grids
• Multiple zones can also be used to store a domain decomposition
• Drawback: not very flexible
• Better: use the partial read/write functions

## Example - CGNS Code (1)

```#include "cgnslib.h"

/* Open the CGNS for reading and check if the file was found. */

if(cg_open(gridFile, MODE_READ, &fileInd) != CG_OK)

/* Determine the of bases in the grid. This example assumes */
/* one base. However it is allowed to have multiple bases. */

if(cg_nbases(fileInd, &nBases)!= CG_OK)
if(nBases != 1)
Terminate("readGridCGNS", "This example assumes one base");
base = 1;

/* Check the cell and physical dimensions of the bases. */
/* Both should be 3. */

if(cg_base_read(fileInd, base, cgnsName, &cellDim, &physDim) != CG_OK)
``` ## Example - CGNS Code (2)

```   /* Read the number of zones in the grid. */
/* This example assumes one zone. */

if(cg_nzones(fileInd, base, &nZones) != CG_OK)
if(nZones != 1)
Terminate("readGridCGNS", "This example assumes one zone");
zone = 1;

/* Check the zone type. This should be Unstructured. */

if(cg_zone_type(fileInd, base, zone, &zoneType) != CG_OK)
if(zoneType != Unstructured)
Terminate("readGridCGNS", "Unstructured zone expected");

/* Determine the number of vertices and volume elements in this */
/* zone (and thus in the grid, because one zone is assumed). */

if(cg_zone_read(fileInd, base, zone, zoneName, sizes) != CG_OK)
nVertices    = sizes;
nVolElements = sizes;
``` ## Example - CGNS Code (3)

```   /* Determine the number and names of the coordinates. */

if(cg_ncoords(fileInd, base, zone, &nCoords) != CG_OK)

if(cg_coord_info(fileInd, base, zone, 1, &dataType, name) != CG_OK)

/* Read the x-coordinates. The y and z-coordinates can be read */
/* similarly. Just replace CoordinateX by CoordinateY and */
/* CoordinateZ respectively. This assumes Cartesian coordinates */
/* in double precision. Note that CGNS starts the numbering at */
/* 1 even if C is used. */

one = 1;
if(cg_coord_read(fileInd, base, zone, "CoordinateX", realDouble, &one,
&nVertices, coorX) != CG_OK)

/* Determine the number of sections for this zone. Note that */
/* surface elements can be stored in a volume zone, but they */
/* are NOT taken into account in the number obtained from */

if(cg_nsections(fileInd, base, zone, &nSections) != CG_OK)
``` ## Example - CGNS Code (4)

```   /* Loop over the number of sections and read the element */
/* connectivities. As CGNS starts the numbering at 1 the */
/* for-loop starts at 1 as well. */

for(sec=1; sec<=nSections; sec++)
{
/* Determine the element type and set the pointer for the */
/* connectivity accordingly. */

if(cg_section_read(fileInd, base, zone, sec, secName, &type,
&eBeg, &eEnd, &nBdry, &parentFlag) != CG_OK)

switch (type)
{
case TETRA_4:
conn = connTetra; break;
case PYRA_5:
conn = connPyra; break;
case PENTA_6:
conn = connPrisms; break;
case HEXA_8:
conn = connHexa; break;
case TRI_3:
conn = connTri; break;
conn = connQuad; break;
default:
Terminate("readGridCGNS", "Unsupported element encountered.");
break;
}

/* Read the connectivity. Again, the node numbering of the */
/* connectivities start at 1. If internally a starting index */
/* of 0 is used (typical for C-codes) 1 must be substracted */
/* from the connectivities read. */

if(cg_elements_read(fileInd, base, zone, sec, conn, NULL) != CG_OK)
}
``` ## Example - CGNS Code (5)

```   /* Determine the number of boundary conditions for this zone. */

if(cg_nbocos(fileInd, base, zone, &nBocos) != CG_OK)

/* Loop over the number of boundary conditions. */

for(boco=1; boco<=nBocos; boco++)
{
/* Read the info for this boundary condition. */

if(cg_boco_info(fileInd, base, zone, boco, bocoName, &bocoType, &ptsetType,
&nBCElem, &normalIndex, &normListFlag, &normDataType,
&nDataSet) != CG_OK)

/* Read the element ID's. */

if(cg_boco_read(fileInd, base, zone, boco, BCElemRead, NULL) != CG_OK) 