This section defines the structure type `DataArray_t`

for describing data arrays.
This general-purpose structure is used to declare data arrays and scalars throughout the CGNS hierarchy.
It is used to describe grid coordinates, flow-solution data, governing flow parameters, boundary-condition data, and other information.
For most of these different types of CFD data, we have also established a list of standardized identifiers for entities of type `DataArray_t`

.
For example, `Density`

is used for data arrays containing static density.

We address five classes of data with the `DataArray_t`

structure type:

dimensional data (e.g., velocity in units of m/s);

nondimensional data normalized by dimensional reference quantities;

nondimensional data with associated nondimensional reference quantities;

nondimensional parameters (e.g., Reynolds number, pressure coefficient);

pure constants (e.g., \(π\), \(e\)).

The first two of these classes often occur within the same test case, where each piece of data is either dimensional itself or normalized by a dimensional quantity. The third data class is typical of a completely nondimensional test case, where all field data and reference quantities are nondimensional. The fourth class, nondimensional parameters, are universal in CFD, although not always consistently defined. The individual components of nondimensional parameters may be data from any of the first three classes.

Each of the five classes of data requires different information to describe dimensional units or normalization associated with the data.
These requirements are reflected in the structure definition for `DataArray_t`

.

The remainder of this section is as follows: The structure type `DataArray_t`

is first defined.
Then the class identification and data manipulation is discussed for each of the five data classes. Finally, examples of `DataArray_t`

entities are presented.

`DataArray_t`

¶`DataArray_t`

describes a multi-dimensional data array of given type, dimensionality and size in each dimension. The data may be dimensional, nondimensional or pure constants. Qualifiers are provided to describe dimensional units or normalization information associated with the data.

```
DataArray_t< DataType, int Dimension, int[Dimension] DimensionValues > :=
{
List( Descriptor_t Descriptor1 ... DescriptorN ) ; (o)
Data( DataType, Dimension, DimensionValues ) ; (r)
DataClass_t DataClass ; (o)
DimensionalUnits_t DimensionalUnits ; (o)
DimensionalExponents_t DimensionalExponents ; (o)
DataConversion_t DataConversion ; (o)
} ;
```

Note

Default names for the

`Descriptor_t`

list are as shown; users may choose other legitimate names. Legitimate names must be unique within a given instance of`DataArray_t`

and shall not include the names`DataClass`

,`DimensionalUnits`

,`DimensionalExponents`

, or`DataConversion`

.`Data()`

is the only required field for`DataArray_t`

.

`DataArray_t`

requires three structure parameters: `Dimension`

is the dimensionality of the data array; `DimensionValues`

is an array of length `Dimension`

that contains the size of the data arrays in each dimension; and `DataType`

is the data type of the data stored. `DataType`

will usually be real, but other data types are permissible.

The optional entities `DataClass`

, `DimensionalUnits`

, `DimensionalExponents`

and `DataConversion`

provide information on dimensional units and normalization associated with the data. The function of these qualifiers is provided in the next section.

This structure type is formulated to describe an array of scalars.
Therefore, for vector quantities (e.g., the position vector or the velocity vector), separate structure entities are required for each component of the vector.
For example, the Cartesian coordinates of a 3-D grid are described by three separate `DataArray_t`

entities: one for x, one for y and one for z (see the example for Cartesian Coordinates for a 2-D Structured Grid).

`DataConversion_t`

¶`DataConversion_t`

contains conversion factors for recovering raw dimensional data from given nondimensional data. These conversion factors are typically associated with nondimensional data that is normalized by dimensional reference quantities.

```
DataConversion_t :=
{
real ConversionScale ; (r)
real ConversionOffset ; (r)
} ;
```

Given a nondimensional piece of data, `Data(nondimensional)`

, the conversion to “raw” dimensional form is:

```
Data(raw) = Data(nondimensional)*ConversionScale + ConversionOffset
```

These conversion factors are further described in the section Nondimensional Data Normalized by Dimensional Quantities.

The optional entities of `DataArray_t`

provide information for manipulating the data, including changing units or normalization.
This section describes the rules under which these optional entities operate and the specific manipulations that can be performed on the data.

Within a given instance of `DataArray_t`

, the class of data and all information required for manipulations may be completely and precisely specified by the entities `DataClass`

, `DimensionalUnits`

, `DimensionalExponents`

and `DataConversion`

.
`DataClass`

identifies the class of data and governs the manipulations that can be performed.
Each of the five data classes is treated separately in the subsequent sections.

The entities `DataClass`

and `DimensionalUnits`

serve special functions in the CGNS hierarchy.
If `DataClass`

is absent from a given instance of `DataArray_t`

, then its value is determined from “global” data.
This global data may be set at any level of the CGNS hierarchy with the data set at the lowest level taking precedence.
`DimensionalUnits`

may be similarly set by global data.
The rules for determining the appropriate set of global data to apply is further detailed in the section Precedence Rules and Scope Within the Hierarchy.

This alternate functionality provides a measure of economy in describing dimensional units or normalization within the hierarchy. Examples that make use of global data are available for both grid coordinates and flow solutions. A complete two-zone example case also depicts this alternate functionality.

If `DataClass`

= `Dimensional`

, the data is dimensional.
The optional qualifiers `DimensionalUnits`

and `DimensionalExponents`

describe dimensional units associated with the data.
These qualifiers are provided to specify the system of dimensional units and the dimensional exponents, respectively.
For example, if the data is the x-component of velocity, then `DimensionalUnits`

will state that the pertinent dimensional units are, say, `Meter`

and `Second`

; `DimensionalExponents`

will specify that the pertinent dimensional exponents are `LengthExponent = 1`

and `TimeExponent = -1`

.
Combining the information gives the units m/s. Examples showing the use of these two qualifiers are provided.

If `DimensionalUnits`

is absent, then the appropriate set of dimensional units is obtained from “global” data.
The rules for determining this appropriate set of global dimensional units are presented in the section Precedence Rules and Scope Within the Hierarchy.

If `DimensionalExponents`

is absent, then the appropriate dimensional exponents can be determined by convention if the specific instance of `DataArray_t`

corresponds to one of the standardized data-name identifiers.
Otherwise, the exponents are unspecified. We strongly recommend inclusion of the `DimensionalExponents`

qualifier whenever the data is dimensional and the instance of `DataArray_t`

is not among the list of standardized identifiers.

If `DataClass`

= `NormalizedByDimensional`

, the data is nondimensional and is normalized by dimensional reference quantities.
All optional entities in `DataArray_t`

are used. `DataConversion`

contains factors to convert the nondimensional data to “raw” dimensional data; these factors are `ConversionScale`

and `ConversionOffset`

.
The conversion process is as follows:

```
Data(raw) = Data(nondimensional)*ConversionScale + ConversionOffset
```

where `Data(nondimensional)`

is the original nondimensional data, and `Data(raw)`

is the converted raw data.
This converted raw data is dimensional, and the optional qualifiers `DimensionalUnits`

and `DimensionalExponents`

describe the appropriate dimensional units and exponents.
Note that `DimensionalUnits`

and `DimensionalExponents`

also describe the units for `ConversionScale`

and `ConversionOffset`

.

If `DataConversion`

is absent, the equivalent defaults are `ConversionScale = 1`

and `ConversionOffset = 0`

.
If either `DimensionalUnits`

or `DimensionalExponents`

is absent, follow the rules described in the previous section.

Note that functionally there is little difference between these first two data classes (`DataClass`

= Dimensional and `NormalizedByDimensional`

).
In the first case the data is dimensional, and in the second, the converted raw data is dimensional.
Also, the equivalent defaults for `DataConversion`

produce no changes in the data; hence, it is almost the same as stating the original data is dimensional.

If `DataClass`

= `NormalizedByUnknownDimensional`

, the data is nondimensional and is normalized by some unspecified dimensional quantities.
This type of data is typical of a completely nondimensional test case, where all field data and all reference quantities are nondimensional.

Only the `DimensionalExponents`

qualifier is used in this case, although it is expected that this qualifier will be seldom utilized in practice.
For entities of `DataArray_t`

that are not among the list of standardized data-name identifiers, the qualifier could provide useful information by defining the exponents of the dimensional form of the nondimensional data.

Rather than providing qualifiers to describe the normalization of the data, we instead dictate that all data of type `NormalizedByUnknownDimensional`

in a given database be nondimensionalized consistently.
This is done by picking one set of mass, length, time and temperature scales and normalizing all appropriate data by these scales.
We describe this process in detail in the following. A complete two-zone example case is also available that uses a completely nondimensional database with consistent normalization used throughout.

The practice of nondimensionalization within flow solvers and other application codes is quite popular.
The problem with this practice is that to manipulate the data from a given code, one must often know the particulars of the nondimensionalization used.
This largely results from what we call inconsistent normalization - more than the minimum required scales are used to normalize data within the code.
For example, in the *OVERFLOW* flow solver, the following nondimensionalization is used:

\(x' = x / L\) |
\(u' = u / (L/T)\) |
\(\rho' = \rho / (M/L^{3})\) |

\(y' = y / L\) |
\(v' = v / (L/T)\) |
\(p' = p / (M/(LT^{2}))\) |

\(z' = z / L\) |
\(w' = w / (L/T)\) |
\(\mu' = \mu / (M/(LT))\) |

where primed quantities are nondimensional and all others are dimensional.

Consider an existing database where all field data and all reference data is nondimensional and normalized as shown. Assume the database has a single reference state given by,

\(x'_{ref} = x_{ref} / L\) |
\(u'_{ref} = u_{ref} / (L/T)\) |
\(\rho'_{ref} = \rho_{ref} / (M/L^{3})\) |

\(y'_{ref} = y_{ref} / L\) |
\(v'_{ref} = v_{ref} / (L/T)\) |
\(p'_{ref} = p_{ref} / (M/(LT^{2}))\) |

\(z'_{ref} = z_{ref} / L\) |
\(w'_{ref} = w_{ref} / (L/T)\) |
\(\mu'_{ref} = \mu_{ref} / (M/(LT))\) |

If a user wanted to change the nondimensionalization of grid-point pressures, the procedure is straightforward. Let the desired new normalization be given by \(p''_{ijk} = p_{ijk} / (\rho_{ref} c_{ref}^{2})\), where all terms on the right-hand-side are *dimensional*, and as such they are unknown to the database user.
However, the desired manipulation is possible using only nondimensional data provided in the database,

\[\begin{split}p''_{ijk} &\equiv p_{ijk} / (\rho_{ref} c_{ref}^{2}) \\
&= [p_{ijk} / (M/(LT^{2})] [(M/L^{3}) / \rho_{ref}] [(L/T) / c_{ref}]^{2} \\
&= p'_{ijk} / (\rho'_{ref} (c'_{ref})^{2})\end{split}\]

Thus, the desired renormalization is possible using the database’s nondimensional data as if it were actually dimensional. There is, in fact, a high degree of equivalence between dimensional data and consistently normalized nondimensional data. The procedure shown in this example should extend to any desired renormalization, provided the needed reference-state quantities are included in the database.

This example points out two stipulations that we now dictate for data in the class `NormalizedByUnknownDimensional`

,

All nondimensional data within a given database that has

`DataClass = NormalizedByUnknownDimensional`

shall be consistently normalized.Any nondimensional reference state appearing in a database should be sufficiently populated with reference quantities to allow for renormalization procedures.

The second of these stipulations is somewhat ambiguous, but good practice would suggest that a flow solver, for example, should output to the database enough static and/or stagnation reference quantities to sufficiently define the state.

A two-zone example case is available that shows an example of a well-populated reference state.

With these two stipulations, we contend the following:

The dimensional scales used to nondimensionalize all data are immaterial, and there is no need to identify these quantities in a CGNS database.

The dimensional scales need not be reference-state quantities provided in the database. For example, a given database could contain freestream reference state conditions, but all the data is normalized by sonic conditions (which are not provided in the database).

All renormalization procedures can be carried out treating the data as if it were dimensional with a consistent set of units.

Any application code that internally uses consistent normalization can use the data provided in a CGNS database without modification or transformation to the code’s internal normalization.

Before ending this section, we note that the *OVERFLOW* flow solver mentioned above (or any other application code that internally uses inconsistent normalization) could easily read and write data to a nondimensional CGNS database that conforms to the above stipulations.
On output, the code could renormalize data so it is consistently normalized.
Probably, the easiest method would be to remove the molecular viscosity scale (\(\mu_\infty\)), and only use \(L\), \(\rho_\infty\) and \(c_\infty\) for all normalizations (recall these are dimensional scales).
The only change from the above example would be the nondimensionalization of viscosity, which would become \(\mu'' = \mu / (\rho_\infty c_\infty L)\).
The code could then output all field data as,

\(x'_{ijk} = x_{ijk} / L\) |
\(u'_{ijk} = u_{ijk} / c_\infty\) |
\(\rho'_{ijk} = \rho_{ijk} / \rho_\infty\) |

\(y'_{ijk} = y_{ijk} / L\) |
\(v'_{ijk} = v_{ijk} / c_\infty\) |
\(p'_{ijk} = p_{ijk} / (\rho_\infty c_\infty^{2})\) |

\(z'_{ijk} = z_{ijk} / L\) |
\(w'_{ijk} = w_{ijk} / c_\infty\) |
\(\mu'_{ijk} = \mu_{ijk} / (\rho_\infty c_\infty^{2} L)\) |

and output the freestream reference quantities,

\(u'_\infty = u_\infty / c_\infty\) |
\(\rho'_\infty = \rho_\infty / \rho_\infty = 1\) |

\(v'_\infty = v_\infty / c_\infty\) |
\(p'_\infty = p_\infty / (\rho_\infty c_\infty^{2}) = 1 / \gamma\) |

\(w'_\infty = w_\infty / c_\infty\) |
\(\mu''_\infty = \mu_\infty / (\rho_\infty c_\infty L) \sim O (1/Re)\) |

\(c'_\infty = c_\infty / c_\infty = 1\) |
\(L' = L / L = 1\) |

where \(\gamma\) is the specific heat ratio (assumes a perfect gas) and \(Re\) is the Reynolds number.

On input, the flow solver should be able to recover its internal normalizations from the data in a nondimensional CGNS database by treating the data as if it were dimensional.

If `DataClass = NondimensionalParameter`

, the data is a nondimensional parameter (or array of nondimensional parameters). Examples include Mach number, Reynolds number and pressure coefficient. These parameters are prevalent in CFD, although their definitions tend to vary between different application codes. A list of standardized data-name identifiers for nondimensional parameters is provided.

We distinguish nondimensional parameters from other data classes by the fact that they are *always* dimensionless. In a completely nondimensional database, they are distinct in that their normalization is not necessarily consistent with other data.

Typically, the `DimensionalUnits`

, `DimensionalExponents`

and `DataConversion`

qualifiers are not used for nondimensional parameters; although, there are a few situations where they may be used (these are discussed below).
Rather than rely on optional qualifiers to describe the normalization, we establish the convention that *any nondimensional parameters should be accompanied by their defining scales*; this is further discussed in the section on standardized data-name identifiers for nondimensional parameters.
An example is Reynolds number defined as \(Re = V L_{R} / \nu\), where \(V\), \(L_R\) and \(\nu\) are velocity, length, and viscosity scales, respectively.
Note that these defining scales may be dimensional or nondimensional data.
We establish the data-name identifiers `Reynolds`

, `Reynolds_Velocity`

, `Reynolds_Length`

and `Reynolds_ViscosityKinematic`

for the Reynolds number and its defining scales.
Anywhere an instance of `DataArray_t`

is found with the identifier `Reynolds`

, there should also be entities for the defining scales.
An example of this use for Reynolds number is available.

In certain situations, it may be more convenient to use the optional qualifiers of `DataArray_t`

to describe the normalization used in nondimensional parameters.
These situations must satisfy two requirements: First, the defining scales are dimensional; and second, the nondimensional parameter is a normalization of a single “raw” data quantity and it is clear what this raw data is.
Examples that satisfy this second constraint are pressure coefficient, where the raw data is static pressure, and lift coefficient, where the raw data is the lift force.
Conversely, Reynolds number is a parameter that violates the second requirement - there are three pieces of raw data rather than one that make up *Re*.
For nondimensional parameters that satisfy these two requirements, the qualifiers `DimensionalUnits`

, `DimensionalExponents`

and `DataConversion`

may be used as in the section Nondimensional Data Normalized by Dimensional Quantities to recover the raw dimensional data.

If `DataClass = DimensionlessConstant`

, the data is a constant (or array of constants) with no associated dimensional units. The `DimensionalUnits`

, `DimensionalExponents`

and `DataConversion`

qualifiers are not used.

This section presents five examples of data-array entities and illustrates the use of optional information for describing dimensional and nondimensional data.

A one-dimensional array of integers; the array is the integers from 1 to 10. The data is pure constants.

```
! DataType = int
! Dimension = 1
! DimensionValues = 10
DataArray_t<int, 1, 10> Data1 =
{{
Data(int, 1, 10) = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] ;
DataClass_t DataClass = DimensionlessConstant ;
}} ;
```

The structure parameters for `DataArray_t`

state the data is an one-dimensional integer array of length ten. The value of `DataClass`

indicates the data is unitless constants.

A two-dimensional array of pressures with size \(11 \times 9\) given by the array \(P(i,j)\). The data is dimensional with units of \(N/m^{2}\) (i.e., \(kg/(m s^{2})\)). Note that Pressure is the data-name identifier for static pressure.

```
! DataType = real
! Dimension = 2
! DimensionValues = [11,9]
DataArray_t<real, 2, [11,9]> Pressure =
{{
Data(real, 2, [11,9]) = ((P(i,j), i=1,11), j=1,9) ;
DataClass_t DataClass = Dimensional ;
DimensionalUnits_t DimensionalUnits =
{{
MassUnits = Kilogram ;
LengthUnits = Meter ;
TimeUnits = Second ;
TemperatureUnits = TemperatureUnitsNull ;
AngleUnits = AngleUnitsNull ;
}} ;
DimensionalExponents_t DimensionalExponents =
{{
MassExponent = +1 ;
LengthExponent = -1 ;
TimeExponent = -2 ;
TemperatureExponent = 0 ;
AngleExponent = 0 ;
}} ;
}} ;
```

From the data-name identifier conventions, `Pressure`

has a floating-point data type; hence, the appropriate structure parameter for `DataArray_t`

is `real`

.

The value of `DataClass`

indicates that the data is dimensional, and both the dimensional units and dimensional exponents are provided.
`DimensionalUnits`

specifies that the units are kilograms, meters, and seconds, and `DimensionalExponents`

specifies the appropriate exponents for pressure.
Combining the information gives pressure as \(kg/(m s^{2})\).
`DimensionalExponents`

could have been defaulted, since the dimensional exponents are part of the standardized data-name identifier for `Pressure`

.

Note that FORTRAN multidimensional array indexing is used to store the data; this is reflected in the FORTRAN-like implied do-loops for \(P(i,j)\).

A 3-D array of size \(33 \times 9 \times 17\) containing nondimensional static enthalpy. The data is normalized by freestream velocity as follows:

\[h'_{ijk} = h_{ijk} / q_{ref}^{2}\]

where \(h'_{ijk}\) is nondimensional static enthalpy. The freestream velocity is dimensional with a value of 10 m/s.

```
! DataType = real
! Dimension = 3
! DimensionValues = [33,9,17]
DataArray_t<real, 3, [33,9,17]> Enthalpy =
{{
Data(real, 3, [33,9,17]) = (((H(i,j,k), i=1,33), j=1,9), k=1,17) ;
DataClass_t DataClass = NormalizedByDimensional ;
DataConversion_t DataConversion =
{{
real ConversionScale = 100 ;
real ConversionOffset = 0 ;
}} ;
DimensionalUnits_t DimensionalUnits =
{{
MassUnits = MassUnitsNull ;
LengthUnits = Meter ;
TimeUnits = Second ;
TemperatureUnits = TemperatureUnitsNull ;
AngleUnits = AngleUnitsNull ;
}} ;
DimensionalExponents_t DimensionalExponents =
{{
MassExponent = 0 ;
LengthExponent = +2 ;
TimeExponent = -2 ;
TemperatureExponent = 0 ;
AngleExponent = 0 ;
}} ;
}} ;
```

From the list of standardized data-name identifiers, the identifier for static enthalpy is `Enthalpy`

and its data type is `real`

.

The value of `DataClass`

indicates that the data is nondimensional and normalized by a dimensional reference quantity.
`DataConversion`

provides the conversion factors for recovering the raw static enthalpy, which has units of \(m^{2}/s^{2}\) as indicated by `DimensionalUnits`

and `DimensionalExponents`

.
Note that `DimensionalExponents`

could have been defaulted using the conventions for the data-name identifier `Enthalpy`

.

The previous example for nondimensional enthalpy is repeated for a completely nondimensional database.

```
! DataType = real
! Dimension = 3
! DimensionValues = [33,9,17]
DataArray_t<real, 3, [33,9,17]> Enthalpy =
{{
Data(real, 3, [33,9,17]) = (((H(i,j,k), i=1,33), j=1,9), k=1,17) ;
DataClass_t DataClass = NormalizedByUnknownDimensional ;
}} ;
```

The value of `DataClass`

indicates the appropriate class.

Reynolds number of \(1.554 \times 10^{6}\) based on a velocity scale of \(10\ m/s\), a length scale of \(2.3\ m\) and a kinematic viscosity scale of \(1.48 \times 10^{−5}\ m^{2}/s\).
Assume the database has globally set the dimensional units to kilograms, meters, and seconds, and the global default data class to dimensional (`DataClass = Dimensional`

).

```
! DataType = real
! Dimension = 1
! DimensionValues = 1
DataArray_t<real, 1, 1> Reynolds =
{{
Data(real, 1, 1) = 1.554e+06 ;
DataClass_t DataClass = NondimensionalParameter ;
}} ;
DataArray_t<real, 1, 1> Reynolds_Velocity =
{{
Data(real, 1, 1) = 10. ;
}} ;
DataArray_t<real, 1, 1> Reynolds_Length =
{{
Data(real, 1, 1) = 2.3 ;
}} ;
DataArray_t<real, 1, 1> Reynolds_ViscosityKinematic =
{{
Data(real, 1, 1) = 1.48e-05 ;
}} ;
```

`Reynolds`

contains the value of the Reynolds number, and the value of its `DataClass`

qualifier designates it as a nondimensional parameter. By conventions for standardized data-name identifiers for nondimensional parameters, the defining scales are contained in the associated entities `Reynolds_Velocity`

, `Reynolds_Length`

, and `Reynolds_ViscosityKinematic`

.
Since each of these entities contain no qualifiers, global information is used to decipher that they are all dimensional with mass, length, and time units of kilograms, meters, and seconds.
The structure parameters for each `DataArray_t`

entity state that they contain a real scalar.

If a user wanted to convey the dimensional units of the defining scales using optional qualifiers of `DataArray_t`

, then the last three entities in this example would have a form similar to that in the Two-Dimensional Data Array example.