This section defines structure types for describing the grid coordinates, element data, and flow solution data pertaining to a zone. Entities of each of the structure types defined in this section are contained in the Zone_t structure.
The physical coordinates of the grid vertices are described by the GridCoordinates_t structure. This structure contains a list for the data arrays of the individual components of the position vector. It also provides a mechanism for identifying rind-point data included within the position-vector arrays.
GridCoordinates_t< int IndexDimension, int VertexSize[IndexDimension] > := { List( Descriptor_t Descriptor1 ... DescriptorN ) ; (o) Rind_t<IndexDimension> Rind ; (o/d) List( DataArray_t<DataType, IndexDimension, DataSize[]> DataArray1 ... DataArrayN ) ; (o) DataClass_t DataClass ; (o) DimensionalUnits_t DimensionalUnits ; (o) List( UserDefinedData_t UserDefinedData1 ... UserDefinedDataN ) ; (o) } ;Notes
GridCoordinates_t requires two structure parameters: IndexDimension identifies the dimensionality of the grid-size arrays, and VertexSize is the number of vertices in each index direction excluding rind points. For unstructured zones, IndexDimension is always 1 and VertexSize is the total number of vertices, excluding rind points.
The grid-coordinates data is stored in the list of DataArray_t entities; each DataArray_t structure entity may contain a single component of the position vector (e.g., three separate DataArray_t entities are used for x, y, and z).
Standardized data-name identifiers for the grid coordinates are described in Conventions for Data-Name Identifiers.
Rind is an optional field that indicates the number of rind planes (for structured grids) or rind points (for unstructured grids) included in the grid-coordinates data. If Rind is absent, then the DataArray_t structure entities contain only "core" vertices of a zone; core refers to all interior and bounding vertices of a zone - VertexSize is the number of core vertices. Core vertices in a zone are assumed to begin at [1,1,1] (for a structured zone in 3-D) and end at VertexSize. If Rind is present, it will provide information on the number of "rind" points in addition to the core points that are contained in the DataArray_t structures.
DataClass defines the default class for data contained in the DataArray_t entities. For dimensional grid coordinates, DimensionalUnits may be used to describe the system of units employed. If present, these two entities take precedence over the corresponding entities at higher levels of the CGNS hierarchy, following the standard precedence rules. An example that uses these grid-coordinate defaults is shown under Grid Coordinates Examples.
The UserDefinedData_t data structure allows arbitrary user-defined data to be stored in Descriptor_t and DataArray_t children without the restrictions or implicit meanings imposed on these node types at other node locations.
GridCoordinates_t requires a single structure function, named DataSize, to identify the array sizes of the grid-coordinates data. A function is required for the following reasons:
if (Rind is absent) then { DataSize[] = VertexSize[] ; } else if (Rind is present) then { DataSize[] = VertexSize[] + [a + b,...] ; }where RindPlanes = [a,b,...] (see the Rind_t structure for the definition of RindPlanes).
This section contains examples of grid coordinates. These examples show the storage of the grid-coordinate data arrays, as well as different mechanisms for describing the class of data and the system of units or normalization.
Cartesian coordinates for a 2-D grid of size 17 × 33; the data arrays include only core vertices, and the coordinates are in units of feet.
! IndexDimension = 2 ! VertexSize = [17,33] GridCoordinates_t<2, [17,33]> GridCoordinates = {{ DataArray_t<real, 2, [17,33]> CoordinateX = {{ Data(real, 2, [17,33]) = ((x(i,j), i=1,17), j=1,33) ; DataClass_t DataClass = Dimensional ; DimensionalUnits_t DimensionalUnits = {{ MassUnits = MassUnitsNull ; LengthUnits = Foot ; TimeUnits = TimeUnitsNull ; TemperatureUnits = TemperatureUnitsNull ; AngleUnits = AngleUnitsNull ; }} ; }} ; DataArray_t<real, 2, [17,33]> CoordinateY = {{ Data(real, 2, [17,33]) = ((y(i,j), i=1,17), j=1,33) ; DataClass_t DataClass = Dimensional ; DimensionalUnits_t DimensionalUnits = {{ MassUnits = MassUnitsNull ; LengthUnits = Foot ; TimeUnits = TimeUnitsNull ; TemperatureUnits = TemperatureUnitsNull ; AngleUnits = AngleUnitsNull ; }} ; }} ; }} ;From the Conventions for Data-Name Identifiers, the identifiers for x and y are CoordinateX and CoordinateY, respectively, and both have a data type of real. The value of DataClass in CoordinateX and CoordinateY indicate the data is dimensional, and DimensionalUnits specifies the appropriate units are feet. The DimensionalExponents entity is absent from both CoordinateX and CoordinateY; the information that x and y are lengths can be inferred from the data-name identifier conventions for coordinate systems.
Note that FORTRAN multidimensional array indexing is used to store the data; this is reflected in the FORTRAN-like implied do-loops for x(i,j) and y(i,j).
Since the dimensional units for both x and y are the same, an alternate approach is to set the data class and system of units using DataClass and DimensionalUnits at the GridCoordinates_t level, and eliminate this information from each instance of DataArray_t.
GridCoordinates_t<2, [17,33]> GridCoordinates = {{ DataClass_t DataClass = Dimensional ; DimensionalUnits_t DimensionalUnits = {{ MassUnits = MassUnitsNull ; LengthUnits = Foot ; TimeUnits = TimeUnitsNull ; TemperatureUnits = TemperatureUnitsNull ; AngleUnits = AngleUnitsNull ; }} ; DataArray_t<real, 2, [17,33]> CoordinateX = {{ Data(real, 2, [17,33]) = ((x(i,j), i=1,17), j=1,33) ; }} ; DataArray_t<real, 2, [17,33]> CoordinateY = {{ Data(real, 2, [17,33]) = ((y(i,j), i=1,17), j=1,33) ; }} ; }} ;Since the DataClass and DimensionalUnits entities are not present in CoordinateX and CoordinateY, the established rules for dimensional data dictate that DataClass and DimensionalUnits specified at the GridCoordinates_t level be used to retrieve the information.
Cylindrical coordinates for a 3-D grid whose core size is 17 × 33 × 9. The grid contains a single plane of rind on the minimum and maximum k faces. The coordinates are nondimensional.
! IndexDimension = 3 ! VertexSize = [17,33,9] GridCoordinates_t<3, [17,33,9]> GridCoordinates = {{ Rind_t<3> Rind = {{ int[6] RindPlanes = [0,0,0,0,1,1] ; }} ; ! DataType = real ! IndexDimension = 3 ! DataSize = VertexSize + [0,0,2] = [17,33,11] DataArray_t<real, 3, [17,33,11]> CoordinateRadius = {{ Data(real, 3, [17,33,11]) = (((r(i,j,k), i=1,17), j=1,33), k=0,10) ; DataClass_t DataClass = NormalizedByUnknownDimensional ; }} ; DataArray_t<real, 3, [17,33,11]> CoordinateZ = {{ }} ; DataArray_t<real, 3, [17,33,11]> CoordinateTheta = {{ }} ; }} ;The value of RindPlanes specifies two rind planes on the minimum and maximum k faces. These rind planes are reflected in the structure function DataSize which is equal to the number of core vertices plus two in the k dimension. The value of DataSize is passed to the DataArray_t entities. The value of DataClass indicates the data is nondimensional. Note that if DataClass is set as NormalizedByUnknownDimensional at a higher level (CGNSBase_t or Zone_t), then it is not needed here.
Note that the entities CoordinateZ and CoordinateTheta are abbreviated.
Cartesian grid coordinates for a 3-D unstructured zone where VertexSize is 15.
GridCoordinates_t<1, 15> GridCoordinates = {{ ! DataType = real ! IndexDimension = 1 ! DataSize = VertexSize = 15 DataArray_t<real, 1, 15> CoordinateX = {{ Data(real, 1, 15) = (x(i), i=1,15) ; }} ; DataArray_t<real, 1, 15> CoordinateY = {{ Data(real, 1, 15) = (y(i), i=1,15) ; }} ; DataArray_t<real, 1, 15> CoordinateZ = {{ Data(real, 1, 15) = (z(i), i=1,15) ; }} ; }} ;
The Elements_t data structure is required for unstructured zones, and contains the element connectivity data, the element type, the element range, the parent elements data, and the number of boundary elements.
Elements_t := { List( Descriptor_t Descriptor1 ... DescriptorN ) ; (o) Rind_t<IndexDimension> Rind ; (o/d) IndexRange_t ElementRange ; (r) int ElementSizeBoundary ; (o/d) ElementType_t ElementType ; (r) DataArray_t<int, 1, ElementDataSize> ElementConnectivity ; (r) DataArray_t<int, 2, [ElementSize, 4]> ParentData; (o) List( UserDefinedData_t UserDefinedData1 ... UserDefinedDataN ) ; (o) } ;Notes
Rind is an optional field that indicates the number of rind elements included in the elements data. If Rind is absent, then the DataArray_t structure entities contain only core elements of a zone. If Rind is present, it will provide information on the number of rind elements, in addition to the core elements, that are contained in the DataArray_t structures.
Note that the usage of rind data with respect to the size of the DataArray_t structures is different under Elements_t than elsewhere. For example, when rind coordinate data is stored under GridCoordinates_t, the parameter VertexSize accounts for the core data only. The size of the DataArray_t structures containing the grid coordinates is determined by the DataSize function, which adds the number of rind planes or points to VertexSize. But for the element connectivity, the size of the DataArray_t structures containing the connectivity data is just ElementDataSize, which depends on ElementSize, and includes both the core and rind elements.
ElementRange contains the index of the first and last elements defined in ElementConnectivity. The elements are indexed with a global numbering system, starting at 1, for all element sections under a given Zone_t data structure. The global numbering insures that each element, whether it's a cell, a face, or an edge, is uniquely identified by its number. They are also listed as a continuous list of element numbers within any single element section. Therefore the number of elements in a section is:
ElementSize = ElementRange.end - ElementRange.start + 1
The element indices are used for the boundary condition and zone connectivity definition.
ElementSizeBoundary indicates if the elements are sorted, and how many boundary elements are recorded. By default, ElementSizeBoundary is set to zero, indicating that the elements are not sorted. If the elements are sorted, ElementSizeBoundary is set to the number of elements at the boundary. Consequently:
ElementSizeInterior = ElementSize - ElementSizeBoundary
ElementType_t is an enumeration of the supported element types:
ElementType_t := Enumeration( ElementTypeNull, ElementTypeUserDefined, NODE, BAR_2, BAR_3, TRI_3, TRI_6, QUAD_4, QUAD_8, QUAD_9, TETRA_4, TETRA_10, PYRA_5, PYRA_14, PENTA_6, PENTA_15, PENTA_18, HEXA_8, HEXA_20, HEXA_27, MIXED, PYRA_13, NGON_n, NFACE_n );The conventions for element numbering for the various supported types are described in Unstructured Grid Element Numbering Conventions.
For all element types except MIXED, NGON_n, and NFACE_n, ElementConnectivity contains the list of nodes for each element. If the elements are sorted, then it must first list the connectivity of the boundary elements, then that of the interior elements.
ElementConnectivity = Node11, Node21, ... NodeN1, Node12, Node22, ... NodeN2, ... Node1M, Node2M, ... NodeNMwhere M is the total number of elements (i.e., ElementSize), and N is the number of nodes per element.
ElementDataSize indicates the total size (number of integers) of the array ElementConnectivity. For all element types except MIXED, NGON_n, and NFACE_n, ElementDataSize is given by:
ElementDataSize = ElementSize * NPE[ElementType]where NPE[ElementType] is a function returning the number of nodes for the given ElementType. For example, NPE[HEXA_8]=8.
When the section ElementType is MIXED, the data array ElementConnectivity contains one extra integer per element, to hold each individual element type:
ElementConnectivity = Etype1, Node11, Node21, ... NodeN1, Etype2, Node12, Node22, ... NodeN2, ... EtypeM, Node1M, Node2M, ... NodeNMwhere again M is the total number of elements, and Ni is the number of nodes in element i. In the case of MIXED element section, ElementDataSize is given by:
ElementDataSize = ∑(NPE[ElementTypen] + 1)where the summation is over n, and n represents a specific element type.
Arbitrary polyhedral elements may be defined using the NGON_n and NFACE_n element types. The NGON_n element type is used to specify all the faces in the grid, and the NFACE_n element type is then used to define the polyhedral elements as a collection of these faces. Except for boundary faces, each face of a polyhedral element must be shared by another polyhedral element.
I.e., for NGON_n, the data array ElementConnectivity contains a list of nodes making up each face in the grid, with the first value for each face defining the number of nodes making up that face:
ElementConnectivity = Nnodes1, Node11, Node21, ... NodeN1, Nnodes2, Node12, Node22, ... NodeN2, ... NnodesM, Node1M, Node2M, ... NodeNMwhere here M is the total number of faces, and Ni is the number of nodes in face i. The ElementDataSize is the total number of nodes defining all the faces, plus one value per face specifying the number of nodes making up that face.
Then for NFACE_n, ElementConnectivity contains the list of face elements making up each polyhedral element, with the first value for each element defining the number of faces making up that element.
ElementConnectivity = Nfaces1, Face11, Face21, ... FaceN1, Nfaces2, Face12, Face22, ... FaceN2, ... NfacesM, Face1M, Face2M, ... FaceNMwhere now M is the total number of polyhedral elements, and Ni is the number of faces in element i. The sign of the face number determines its orientation (i.e., the direction of the face normal, constructed as defined by the convention for 2-D elements). If the face number is positive, the face normal is directed outward; if it's negative, the face normal is directed inward. The ElementDataSize is the sum of the number of faces defining each polyhedral element, plus one value per polyhedral element specifying the number of faces making up that element.
For face elements in 3D, or bar elements in 2D, four more data may be saved for each element - the corresponding parents' element numbers, and the face position within these parent elements. At the boundaries, the second parent is set to zero.
The UserDefinedData_t data structure allows arbitrary user-defined data to be stored in Descriptor_t and DataArray_t children without the restrictions or implicit meanings imposed on these node types at other node locations.
This section contains four examples of elements definition in CGNS. The first example is for a simple three-element tetrahedral grid, using the TETRA_4 element type. The second example is for the same grid as the first example, but the elements are treated as general polyhedra to illustrate the use of the NGON_n and NFACE_n element types. The third and fourth examples are for an unstructured zone with 15 tetrahedral and 10 hexahedral elements, with the third example defining the elements in separate sections for the TETRA_4 and HEXA_8 element types, and the fourth example combining them using the MIXED element type.
The element type is TETRA_4, and the connectivity is defined in ElementConnectivity by specifying the four nodes comprising each element, with the order consistent with the numbering conventions for tetrahedral elements. The data in ElementConnectivity is grouped by element; note that the parentheses are added here for presentation purposes only.
Zone_t UnstructuredZone = {{ Elements_t TetraElements = {{ IndexRange_t ElementRange = [1,3] ; ElementType_t ElementType = TETRA_4 ; DataArray_t<int, 1, NPE[TETRA_4] × 3> ElementConnectivity = {{ Data(int, 1, NPE[TETRA_4] × 3) = (1, 2, 3, 4), (2, 5, 3, 6), (2, 6, 3, 4) ; }} ; }} ; }} ;
This example uses the same grid as in the previous example, but treats the elements as general polyhedra to illustrate the use of the NGON_n and NFACE_n element types. The grid consists of three volume elements, each made up of four face elements, with each face defined by three nodes.
For each face, the nodes comprising that face are listed in ElementConnectivity for the NGON_n element type. The ElementRange is [1,10], corresponding to the 10 total faces in the grid. The ElementDataSize is 40, corresponding to the total of 30 nodes defining the 10 faces, plus one value per face specifying the number of nodes making up that face.
The faces making up the three volume elements are then listed in ElementConnectivity for the NFACE_n element type. The ElementRange is [1,3], corresponding to the three volume elements. The ElementDataSize is 15, corresponding to three volume elements with four faces per element, plus one value per volume element specifying the number of faces making up that element. Note that the face numbers for faces 3 and 8 are negative in the definition of volume element 3, since their normals point inward for that element. Again, the parentheses in ElementConnectivity are for presentation purposes only.
Zone_t UnstructuredZone = {{ Elements_t NgonElements = {{ IndexRange_t ElementRange = [1,10] ; ElementType_t ElementType = NGON_n ; DataArray_t<int, 1, 40> ElementConnectivity = {{ Data(int, 1, 40) = (3, 1, 3, 2), (3, 1, 2, 4), (3, 2, 3, 4), (3, 3, 1, 4), (3, 2, 3, 5), (3, 2, 5, 6), (3, 5, 3, 6), (3, 3, 2, 6), (3, 2, 6, 4), (3, 6, 3, 4) ; }} ; }} ; Elements_t NfaceElements = {{ IndexRange_t ElementRange = [1,3] ; ElementType_t ElementType = NFACE_n ; DataArray_t<int, 1, 15> ElementConnectivity = {{ Data(int, 1, 15) = (4, 1, 2, 3, 4), (4, 5, 6, 7, 8), (4, -8, 9, 10, -3) ; }} ; }} ; }} ;
In this example, elements are defined for an unstructured zone with 15 tetrahedral and 10 hexahedral elements. The elements are written in two separate sections, one for the tetrahedral elements and one for the hexahedral elements.
Zone_t UnstructuredZone = {{ Elements_t TetraElements = {{ IndexRange_t ElementRange = [1,15] ; int ElementSizeBoundary = 10 ; ElementType_t ElementType = TETRA_4 ; DataArray_t<int, 1, NPE[TETRA_4] × 15> ElementConnectivity = {{ Data(int, 1, NPE[TETRA_4] × 15) = (node(i,j), i=1,NPE[TETRA_4], j=1,15) ; }} ; }} ; Elements_t HexaElements = {{ IndexRange_t ElementRange = [16,25] ; int ElementSizeBoundary = 0 ; ElementType_t ElementType = HEXA_8 ; DataArray_t<int, 1, NPE[HEXA_8] × 10> ElementConnectivity = {{ Data(int, 1, NPE[HEXA_8] × 10) = (node(i,j), i=1,NPE[HEXA_8], j=1,10) ; }} ; }} ; }} ;
In this example, the same unstructured zone described in the previous example is written in a single element section of type MIXED (i.e., an unstructured grid composed of mixed elements).
Zone_t UnstructuredZone = {{ Elements_t MixedElementsSection = {{ IndexRange_t ElementRange = [1,25] ; ElementType_t ElementType = MIXED ; DataArray_t<int, 1, ElementDataSize> ElementConnectivity = {{ Data(int, 1, ElementDataSize) = (etype(j),(node(i,j), i=1,NPE[etype(j)]), j=1,25) ; }} ; }} ; }} ;
The Axisymmetry_t data structure allows recording the axis of rotation and the angle of rotation around this axis for a two-dimensional dataset that represents an axisymmetric database.
Axisymmetry_t := { List( Descriptor_t Descriptor1 ... DescriptorN ) ; (o) DataArray_t<real,1,2> AxisymmetryReferencePoint ; (r) DataArray_t<real,1,2> AxisymmetryAxisVector ; (r) DataArray_t<real,1,1> AxisymmetryAngle ; (o) DataArray_t<char,2,[32,2]> CoordinateNames ; (o) DataClass_t DataClass ; (o) DimensionalUnits_t DimensionalUnits ; (o) List( UserDefinedData_t UserDefinedData1 ... UserDefinedDataN ) ; (o) } ;Notes
AxisymmetryReferencePoint specifies the origin used for defining the axis of rotation.
AxisymmetryAxisVector contains the direction cosines of the axis of rotation, through the AxisymmetryReferencePoint. For example, for a 2-D dataset defined in the (x,y) plane, if AxisymmetryReferencePoint contains (0,0) and AxisymmetryAxisVector contains (1,0), the x-axis is the axis of rotation.
AxisymmetryAngle allows specification of the circumferential extent about the axis of rotation. If this angle is undefined, it is assumed to be 360°.
CoordinateNames may be used to specify the first and second coordinates used in the definition of AxisymmetryReferencePoint and AxisymmetryAxisVector. If not found, it is assumed that the first coordinate is CoordinateX and the second is CoordinateY. The coordinates given under CoordinateNames, or implied by using the default, must correspond to those found under GridCoordinates_t.
DataClass defines the default class for numerical data contained in the DataArray_t entities. For dimensional data, DimensionalUnits may be used to describe the system of units employed. If present, these two entities take precedence over the corresponding entities at higher levels of the CGNS hierarchy, following the standard precedence rules.
The UserDefinedData_t data structure allows arbitrary user-defined data to be stored in Descriptor_t and DataArray_t children without the restrictions or implicit meanings imposed on these node types at other node locations.
The RotatingCoordinates_t data structure is used to record the rotation center and rotation rate vector of a rotating coordinate system.
RotatingCoordinates_t := { List( Descriptor_t Descriptor1 ... DescriptorN ) ; (o) DataArray_t<real,1,PhysicalDimension> RotationCenter ; (r) DataArray_t<real,1,PhysicalDimension> RotationRateVector ; (r) DataClass_t DataClass ; (o) DimensionalUnits_t DimensionalUnits ; (o) List( UserDefinedData_t UserDefinedData1 ... UserDefinedDataN ) ; (o) } ;Notes
RotationCenter specifies the coordinates of the center of rotation, and RotationRateVector specifies the components of the angular velocity of the grid about the center of rotation. Together, they define the angular velocity vector. The direction of the angular velocity vector specifies the axis of rotation, and its magnitude specifies the rate of rotation.
For example, for the common situation of rotation about the x-axis, RotationCenter would be specified as any point on the x-axis, like (0,0,0). RotationRateVector would then be specified as (ω,0,0), where ω is the rotation rate. Using the right-hand rule, ω would be positive for clockwise rotation (looking in the +x direction), and negative for counter-clockwise rotation.
Note that for a rotating coordinate system, the axis of rotation is defined in the inertial frame of reference, while the grid coordinates stored using the GridCoordinates_t data structure are relative to the rotating frame of reference.
DataClass defines the default class for data contained in the DataArray_t entities. For dimensional data, DimensionalUnits may be used to describe the system of units employed. If present, these two entities take precedence over the corresponding entities at higher levels of the CGNS hierarchy, following the standard precedence rules.
The UserDefinedData_t data structure allows arbitrary user-defined data to be stored in Descriptor_t and DataArray_t children without the restrictions or implicit meanings imposed on these node types at other node locations.
If rotating coordinates are used, it is useful to store variables relative to the rotating frame. Standardized data-name identifiers should be used for these variables, as defined for flow-solution quantities in the section Conventions for Data-Name Identifiers.
The flow solution within a given zone is described by the FlowSolution_t structure. This structure contains a list for the data arrays of the individual flow-solution variables, as well as identifying the grid location of the solution. It also provides a mechanism for identifying rind-point data included within the data arrays.
FlowSolution_t< int IndexDimension, int VertexSize[IndexDimension], int CellSize[IndexDimension] > := { List( Descriptor_t Descriptor1 ... DescriptorN ) ; (o) GridLocation_t GridLocation ; (o/d) Rind_t<IndexDimension> Rind ; (o/d) List( DataArray_t<DataType, IndexDimension, DataSize[]> DataArray1 ... DataArrayN ) ; (o) DataClass_t DataClass ; (o) DimensionalUnits_t DimensionalUnits ; (o) List( UserDefinedData_t UserDefinedData1 ... UserDefinedDataN ) ; (o) } ;Notes
FlowSolution_t requires three structure parameters; IndexDimension identifies the dimensionality of the grid-size arrays, and VertexSize and CellSize are the number of core vertices and cells, respectively, in each index direction. For unstructured zones, IndexDimension is always 1.
The flow solution data is stored in the list of DataArray_t entities; each DataArray_t structure entity may contain a single component of the solution vector. Standardized data-name identifiers for the flow-solution quantities are described in the section Conventions for Data-Name Identifiers. The field GridLocation specifies the location of the solution data with respect to the grid; if absent, the data is assumed to coincide with grid vertices (i.e., GridLocation = Vertex). All data within a given instance of FlowSolution_t must reside at the same grid location.
Rind is an optional field that indicates the number of rind planes (for structured grids) or rind points or elements (for unstructured grids) included in the data. Its purpose and function are identical to those described for the GridCoordinates_t structure. Note, however, that the Rind in this structure is independent of the Rind contained in GridCoordinates_t. They are not required to contain the same number of rind planes or elements. Also, the location of any flow-solution rind points is assumed to be consistent with the location of the core flow solution points (e.g., if GridLocation = CellCenter, rind points are assumed to be located at fictitious cell centers).
DataClass defines the default class for data contained in the DataArray_t entities. For dimensional flow solution data, DimensionalUnits may be used to describe the system of units employed. If present, these two entities take precedence over the corresponding entities at higher levels of the CGNS hierarchy, following the standard precedence rules.
The UserDefinedData_t data structure allows arbitrary user-defined data to be stored in Descriptor_t and DataArray_t children without the restrictions or implicit meanings imposed on these node types at other node locations.
The function DataSize[] is the size of flow solution data arrays. If Rind is absent then DataSize represents only the core points; it will be the same as VertexSize or CellSize depending on GridLocation. The definition of the function DataSize[] is as follows:
if (Rind is absent) then { if (GridLocation = Vertex) or (GridLocation is absent) { DataSize[] = VertexSize[] ; } else if (GridLocation = CellCenter) then { DataSize[] = CellSize[] ; } } else if (Rind is present) then { if (GridLocation = Vertex) or (GridLocation is absent) then { DataSize[] = VertexSize[] + [a + b,...] ; } else if (GridLocation = CellCenter) { DataSize[] = CellSize[] + [a + b,...] ; } }where RindPlanes = [a,b,...] (see the Rind_t structure for the definition of RindPlanes).
This section contains an example of the flow solution entity, including the designation of grid location and rind planes and data-normalization mechanisms.
Conservation-equation variables (ρ, ρu, ρv, and ρe0) for a 2-D grid of size 11 × 5. The flowfield is cell-centered with two planes of rind data. The density, momentum and stagnation energy (ρe0) data is nondimensionalized with respect to a freestream reference state whose quantities are dimensional. The freestream density and pressure are used for normalization; these values are 1.226 kg/m3 and 1.0132×105 N/m2 (standard atmosphere conditions). The data-name identifier conventions for the conservation-equation variables are Density, MomentumX, MomentumY and EnergyStagnationDensity.
! IndexDimension = 2 ! VertexSize = [11,5] ! CellSize = [10,4] FlowSolution_t<2, [11,5], [10,4]> FlowExample = {{ GridLocation_t GridLocation = CellCenter ; Rind_t<2> Rind = {{ int[4] RindPlanes = [2,2,2,2] ; }} ; DataClass_t DataClass = NormalizedByDimensional ; DimensionalUnits_t DimensionalUnits = {{ MassUnits = Kilogram ; LengthUnits = Meter ; TimeUnits = Second ; TemperatureUnits = TemperatureUnitsNull ; AngleUnits = AngleUnitsNull ; }} ; ! DataType = real ! Dimension = 2 ! DataSize = CellSize + [4,4] = [14,8] DataArray_t<real, 2, [14,8]> Density = {{ Data(real, 2, [14,8]) = ((rho(i,j), i=-1,12), j=-1,6) ; DataConversion_t DataConversion = {{ ConversionScale = 1.226 ; ConversionOffset = 0 ; }} ; DimensionalExponents_t DimensionalExponents = {{ MassExponent = +1 ; LengthExponent = -3 ; TimeExponent = 0 ; TemperatureExponent = 0 ; AngleExponent = 0 ; }} ; }} ; DataArray_t<real, 2, [14,8]> MomentumX = {{ Data(real, 2, [14,8]) = ((rho_u(i,j), i=-1,12), j=-1,6) ; DataConversion_t DataConversion = {{ ConversionScale = 352.446 ; ConversionOffset = 0 ; }} ; }} ; DataArray_t<real, 2, [14,8]> MomentumY = {{ Data(real, 2, [14,8]) = ((rho_v(i,j), i=-1,12), j=-1,6) ; DataConversion_t DataConversion = {{ ConversionScale = 352.446 ; ConversionOffset = 0 ; }} ; }} ; DataArray_t<real, 2, [14,8]> EnergyStagnationDensity = {{ Data(real, 2, [14,8]) = ((rho_e0(i,j), i=-1,12), j=-1,6) ; DataConversion_t DataConversion = {{ ConversionScale = 1.0132e+05 ; ConversionOffset = 0 ; }} ; }} ; }} ;The value of GridLocation indicates the data is at cell centers, and the value of RindPlanes specifies two rind planes on each face of the zone. The resulting value of the structure function DataSize is the number of cells plus four in each coordinate direction; this value is passed to each of the DataArray_t entities.
Since the data are all nondimensional and normalized by dimensional reference quantities, this information is stated in DataClass and DimensionalUnits at the FlowSolution_t level rather than attaching the appropriate DataClass and DimensionalUnits to each DataArray_t entity. It could possibly be at even higher levels in the heirarchy. The contents of DataConversion are in each case the denominator of the normalization; this is ρ∞ for density, (p∞ ρ∞)1/2 for momentum, and p∞ for stagnation energy. The dimensional exponents are specified for density. For all the other data, the dimensional exponents are to be inferred from the data-name identifiers.
Note that no information is provided to identify the actual reference state or indicate that it is freestream. This information is not needed for data manipulations involving renormalization or changing the units of the converted raw data.