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:
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 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) } ;Notes
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 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 + ConversionOffsetThese 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 + ConversionOffsetwhere 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 / c_{∞} | ρ′ = ρ / ρ_{∞} | ||
y′ = y / L | v′ = v / c_{∞} | p′ = p / (ρ_{∞}c_{∞}^{2}) | ||
z′ = z / L | w′ = w / c_{∞} | μ′ = μ / μ_{∞} |
Consistent normalization avoids many of these problems. Here the number of scales used for normalization is the same as the number of fundamental dimensional units represented by the data. Using consistent normalization, the resulting nondimensionalized form of equations and definitions is identical to their original dimensional formulations. One piece of evidence to support this assertion is that it is not possible to form any nondimensional parameters from the set of dimensional scales used for normalization.
An important fallout of consistent normalization is that the actual scales used for normalization become immaterial for all data manipulation processes. To illustrate this consider the following nondimensionalization procedure: let M (mass), L (length) and T (time) be arbitrary dimensional scales by which all data is normalized (neglect temperature data for the present). The nondimensional data follows:
x′ = x / L | u′ = u / (L/T) | ρ′ = ρ / (M/L^{3}) | ||
y′ = y / L | v′ = v / (L/T) | p′ = p / (M/(LT^{2})) | ||
z′ = z / L | w′ = w / (L/T) | μ′ = μ / (M/(LT)) |
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) | ρ′_{ref} = ρ_{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) | μ′_{ref} = μ_{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} / (ρ_{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,
p″_{ijk} | ≡ p_{ijk} / (ρ_{ref}c_{ref}^{2}) | |
= [p_{ijk} / (M/(LT^{2})] [(M/L^{3}) / ρ_{ref}] [(L/T) / c_{ref}]^{2} | ||
= p′_{ijk} / (ρ′_{ref}(c′_{ref})^{2}) |
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,
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:
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 (μ_{∞}), and only use L, ρ_{∞} and c_{∞} for all normalizations (recall these are dimensional scales). The only change from the above example would be the nondimensionalization of viscosity, which would become μ″ = μ / (ρ_{∞}c_{∞}L). The code could then output all field data as,
x′_{ijk} = x_{ijk} / L | u′_{ijk} = u_{ijk} / c_{∞} | ρ′_{ijk} = ρ_{ijk} / ρ_{∞} | ||
y′_{ijk} = y_{ijk} / L | v′_{ijk} = v_{ijk} / c_{∞} | p′_{ijk} = p_{ijk} / (ρ_{∞}c_{∞}^{2}) | ||
z′_{ijk} = z_{ijk} / L | w′_{ijk} = w_{ijk} / c_{∞} | μ″_{ijk} = μ_{ijk} / (ρ_{∞}c_{∞}L) |
u′_{∞} = u_{∞} / c_{∞} | ρ′_{∞} = ρ_{∞} / ρ_{∞} = 1 | |
v′_{∞} = v_{∞} / c_{∞} | p′_{∞} = p_{∞} / (ρ_{∞}c_{∞}^{2}) = 1 / γ | |
w′_{∞} = w_{∞} / c_{∞} | μ″_{∞} = μ_{∞} / (ρ_{∞}c_{∞}L) ∼ O (1/Re) | |
c′_{∞} = c_{∞} / c_{∞} = 1 | L′ = L / L = 1 |
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 = VL_{R} / ν, where V, L_{R} and ν 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 × 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 × 9 × 17 containing nondimensional static enthalpy. The data is normalized by freestream velocity as follows:
! 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 × 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 × 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.