| POSC Specifications Version 2.2 |
Data Access and Exchange DAE Specification |
This appendix is a summary of the specification, content, and interface for all of the data types used in Epicentre. It supplements information elsewhere in this specification. For the purpose of conformance, it is informative.
The Specification of the attributes of each data type is defined using the EXPRESS syntax. This is the syntax which is used, for example, in specifying a Named Defined Type (NDT). The parameters in the specification are reviewed and their constraints on the values are explained. This specification extends the methodology section of Epicentre.
The Content of a value for each type is described. For simple types, constraints on the values are explained. However the format for storing a value is implementation-defined: The POSC Exchange Format specifies how each value is represented for exchange, but each implementation of a POSC data access and exchange facility may choose its own internal format for values in a data store. For more complex types, an extended EXPRESS syntax that introduces the META_TYPE keyword is used to describe the content of a value. The META_TYPE allows us to subdivide a "complex" Epicentre Data Type into recognizable elements. Elements of a META_TYPE can point "out" but nothing external to the type can point "in". Note that the normative definition of the content of the types is defined in this Data Access and Exchange specification.
The Express-I is a pattern for use of the data type in an Express-I documentation of a mapping. Where appropriate, an example is given to illustrate the pattern.
The Interface to values of each data type is summarized. These interfaces are normatively defined in this Data Access and Exchange specification.
The diagrams referenced in this section include:
The section is organized into the following subsections:
| F.3.1 INTEGER | |
|
|
| F.4.1 COMPLEX | ||
|
|
An integer type is one whose domain is the integer numbers or a subset thereof.
A value of an integer is always expected to be within the range +/- 2x109 and may be represented by a 32-bit integer. There will be cases where a narrower range may be used. These are indicated only in range rules.
attribute --> IntegerValue;
Ex: count --> 87;
An integer attribute may be cast to a C short or long. The application writer should ensure that a sufficiently large representation is used.
A real type is one whose domain is the real numbers (rational, irrational or scientific) or a subset thereof. It may specify a required precision for elements of the type.
A value of a REAL is expected to be implemented in a floating point number format. The Epicentre model usually specifies precisions as 6 or 14. If no precision is specified, a precision of 6 may be assumed. Attributes with a precision of 6 or less may be implemented as a single precision floating point number; those with a precision of more than six require a double precision format. There are no uses of real in Epicentre version 2.1 requiring a precision of more than 14.
attribute --> RealValue;
Ex: scale change --> -99.23;
A REAL attribute value may be cast into a C float or double representation. It is the responsibility of the application writer to ensure that a representation has sufficient precision for the value.
A string type is one whose domain is an ordered set of similarly sized string literals (e.g., characters).
The string is an ordered sequence of 8-bit characters. Except where accessing schema information, collating sequences are implementation-defined.
No case transformations should be carried out implicitly.
attribute --> StringValue;
Ex: identifier --> 'J-01 installation';
The language bindings permit strings to be cast to an array of the C char data type. All other passing of strings is as a null terminated string. There is no distinction made between fixed and variable-length strings.
A boolean type is one which has as its domain the two logical values TRUE and FALSE.
The value may be one of TRUE or FALSE.
attribute --> BooleanValue;
Ex: connected --> FALSE;
A boolean value may be cast to any size of integer. FALSE is represented by 0 and TRUE by 1.
For clarity and convenience, a standard data type of daeBoolean is defined in the header. It is defined in such a way that the operations of a signed integer may be applied to variables of this type.
A logical type is one which has as its domain the three logical values TRUE, FALSE and UNKNOWN.
The value may be one of TRUE, FALSE or UNKNOWN.
attribute --> LogicalValue;
Ex: centered --> TRUE;.
A logical value may be cast to any size of signed integer. FALSE is represented by 0, TRUE by 1, and UNKNOWN by -1.
For clarity and convenience, a standard data type of daeLogical is defined in the header. It is defined in such a way that the operations of a signed integer may be applied to variables of this type.
A binary type is one which has as its domain an ordered sequence of bits.
The value will contain an ordered sequence of bits.
attribute --> BinaryValue; -- bits prefaced by percent sign
Ex: flag = %0010110;
A C structure is specified for passing values:
typedef struct daeBinaryStructure
{
daeInteger length;
daePointer data;
} daeBinary, *daeBinaryPtr;
The length passed indicates the number of bits in the data.
An enumeration type is a type whose domain consists of an ordered set of predefined identifiers.
This construct is not used in the Epicentre model, enumerated values being modeled using reference entities instead. It is used in the schema model and is included for completeness.
EXPRESS, an enumeration has to be defined within a TYPE clause that gives it a name. The enumeration may take only the values specified in its definition. An implementation may use any representation that can distinguish each value and associate each with its specifying identifier.
attribute --> EnumerationValue; -- value prefaced by !
Ex: color --> !RED;
An enumerated value is passed across the interface as a string. Only strings containing the identifier in upper case text are valid values.
An entity value holds a reference to an instance of a specified entity type. This is how relationships are specified and implemented.
The entity value must contain a reference to an instance of the specified entity. The way this reference is stored is implementation-defined.
For an INVERSE attribute, the derivation of the reference is implementation-defined. As examples, the references may be stored with automatic derivation as a side effect or they may be derived by a search after receiving a request for an attribute value.
InstanceId = EntityName {
... attributes ...
};
Ex: posc = BUSINESS_ASSOCIATE {
Ex: ...
Ex: };
(* The InstanceId is used to refer to an entity in later
references. This is done as "@InstanceId", for example @posc *)
The value of an entity data type is passed to an application as an instance handle. This handle may be used in operations on that instance as specified in Section 5, "Operations on Instances" and in setting up other references to that instance.
An aggregate value holds a collection of values. All the values in one aggregate value must be of the same type. EXPRESS defines four aggregates: BAG, SET, LIST, and ARRAY.
The content is implementation-defined.
attribute --> AggregationType (value, value, ...);
where AggregationType = BAG, LIST or SET
Ex: wellbore_interval --> SET (@wb_top, @wb_base);
An aggregate value is passed as a handle. The operations to access the elements are specified in this Data Access and Exchange specification.
Epicentre
data types have been defined to allow data behavior common in E&P activities to be specified by referring to the appropriate data type.These new types are analogous to the EXPRESS simple types. For example, the simple type STRING implies a behavior of an ordered list of characters, where the parameters associated with a STRING declaration can be used to declare additional restrictions on the list of characters. There is no implication of how these characters are represented, only the idea that you can find out what the characters are and their order. The type has a declaration syntax that includes the maximum width parameter and variable or fixed condition.
Similarly, each Epicentre data type has a defined behavior, usually some specification parameters, which constrain the instances of the data type, and a declaration syntax.
A complex number consists of a real and an imaginary part, each represented by a real number.
The content consists of two floating point numbers representing the real and imaginary part of the value. The representation of the floating point numbers must be adequate to hold the minimum precision specified, as is discussed for the REAL type.
META_TYPE complex;
real_part : REAL (precision);
imaginary_part : REAL (precision);
EXTERNAL
precision : INTEGER;
WHERE
precision_valid : 0 < precision;
END_META_TYPE;
attribute --> COMPLEX {
real_part (M) --> RealValue;
imaginary_part (M) --> RealValue; };
Ex: fk_value --> COMPLEX {
Ex: real_part (M) --> 18.3;
Ex: imaginary_part (M) --> 12.11; };
The value is cast to a structure holding a pair of either single or double precision real values:
typedef struct daeComplexRealStructure
{
daeReal realPart;
daeReal imaginaryPart;
} daeComplexReal;
typedef struct daeComplexDoubleStructure
{
daeDouble realPart;
daeDouble imaginaryPart;
} daeComplexDouble;
A rational number is represented as an integer numerator and an integer denominator.
The content consists of two integers representing the numerator and denominator.
META_TYPE rational;
numerator : INTEGER;
denominator : INTEGER;
END_META_TYPE;
attribute --> RATIONAL {
numerator (M) --> IntegerValue;
denominator (M) --> IntegerValue; };
Ex: map_scale --> RATIONAL {
Ex: numerator (M) --> 1;
Ex: denominator (M) --> 20000; };
A value is cast into a structure of two signed integers:
typedef struct daeRationalStructure
{
daeInteger numerator;
daeInteger denominator;
} daeRational;
A ratio value is the ratio of two signed numbers, represented by a real number numerator and a real number denominator.
The content consists of two floating point numbers representing the numerator and denominator parts of the value. The representation of the floating point numbers must be adequate to hold the minimum precision specified, as discussed for the REAL type.
META_TYPE ratio;
numerator : REAL (precision);
denominator : REAL (precision);
EXTERNAL
precision : INTEGER;
WHERE
precision_valid : 0 < precision;
END_META_TYPE;
attribute --> RATIO {
numerator (M) --> RealValue;
denominator (M) --> RealValue; };
Ex: depth_gradient --> RATIO {
Ex: numerator (M) --> 17.;
Ex: denominator (M) --> 100.; };
The value is cast to a structure holding a pair of either single or double precision real numbers:
typedef struct daeRatioRealStructure
{
daeReal numerator;
daeReal denominator;
} daeRatioReal;
typedef struct daeRatioDoubleStructure
{
daeDouble numerator;
daeDouble denominator;
} daeRatioDouble;
A money value is an amount of a specified currency, expressed as an integer number of currency units and an integer number for each of its sub-units.
The value is intended for economic estimates rather than accounting data. It consists of a currency value and unit and a sub-unit value. Each sub-unit value must be less than the number of sub-units that are equivalent to the unit.
META_TYPE money;
value : INTEGER;
ref_currency_unit : ref_currency_unit;
subvalue : OPTIONAL MONEY(ref_currency_unit.smaller_unit.name);
EXTERNAL
currency_name : OPTIONAL STRING(15);
WHERE
units_valid : ref_currency_unit.acronym = currency_name;
sign_valid : (( 0 <= value ) AND ( 0 <= subvalue.value ))
XOR (( 0 >= value ) AND ( 0 >= subvalue.value ));
subunits_valid : subvalue.value >= ref_currency_unit.sub_unit_per_unit;
END_META_TYPE;
attribute --> MONEY {
value (M)--> IntegerValue;
ref_currency_unit (M)--> @InstanceId;
subvalue --> MONEY {
value (M) --> IntegerValue;
ref_currency_unit (M) --> @InstanceId;
subvalue ...NESTED as far as necessary.
}; };
Ex: equipment_cost --> MONEY { -- $6213.85 US
Ex: value (M) --> 6213;
Ex: ref_currency_unit (M) --> @PRV_USD;
Ex: subvalue --> MONEY {
Ex: value (M) --> 85;
Ex: ref_currency_unit (M) --> @PRV_USDc'; }; };
The value is cast to a structure holding a currency unit acronym, an integer for the primary unit of currency, and an array of short integers for the sub-units. The size of the array is determined by the number of currency sub-units as specified by subunitsCount:
typedef struct daeMoneyStructure
{
daeInteger money;
daeShort subunitsCount;
daeShort *subunits;
daeCurrency currencyName;
} daeMoney, *daeMoneyPtr;
If there are no sub-units, the sub-units pointer must be null. If the values in the sub-units are all zero, the sub-units pointer can be null. Non-zero members of the structure must be all positive or all negative.
There is no model for currency conversion.
A location value consists of a set of ordinate values that map onto the axes of a specified coordinate system. The coordinates are measured with respect to a specified reference vertex or, if not defined, with respect to the origin of the coordinate system.
The coordinate systems that may be used by the location instance may be constrained by the type declaration to be one of a valid set. The coordinate values have associated units of measure which are constrained by the specification of the coordinate system axes of the coordinate system.
The location value is represented as:
META_TYPE location;
coordinate_system : coordinate_system;
vertex : OPTIONAL vertex;
coordinates : LIST[1:?] OF REAL (coord_precision);
ref_unit_of_measure : LIST[1:?] OF ref_unit_of_measure;
EXTERNAL
constraint_name : OPTIONAL STRING(40);
coord_precision : INTEGER;
WHERE
coord_precision_valid: 0 < coord_precision;
coordinate_axes_valid: SIZEOF(coordinates) <= SIZEOF(coordinate_system.coordinate_system_axis);
coordinate_units_valid: SIZEOF(ref_unit_of_measure) = SIZEOF(coordinates);
coordinate_axes_present: EXISTS(coordinate_system.coordinate_system_axis);
coordinate_system_valid: coordinate_system.ref_coordinate_system_constraint.name = constraint_name;
units_valid: axis_unit_correlation( coordinate_system, ref_unit_of_measure);
constraint_axis_valid: SIZEOF(coordinates) = SIZEOF(coordinate_system.ref_coordinate_system_constraint.ref_axis_type);
constraint_type_valid: axis_type_correlation( coordinate_system ); (* Delete this and add to Coordinate_system *)
END_META_TYPE;
FUNCTION axis_unit_correlation ( coordinate_system : coordinate_system ; axis_units : LIST [1:?] OF ref_unit_of_measure ) : BOOLEAN;
ALIAS csa FOR coordinate_system.coordinate_system_axis;
REPEAT i := LOINDEX(csa) TO HIINDEX(csa);
IF NOT (axis_units[i] IN csa[i].ref_quantity_property.ref_quantity_type.alternative_unit_of_measure) THEN
RETURN (FALSE);
END_IF;
END_REPEAT;
END_ALIAS;
RETURN (TRUE);
END_FUNCTION;
FUNCTION axis_type_correlation ( coordinate_system : coordinate_system ) : BOOLEAN;
ALIAS csa FOR coordinate_system.coordinate_system_axis;
REPEAT i := LOINDEX(csa) TO HIINDEX(csa);
IF NOT (csa[i].ref_quantity_property IN coordinate_system.ref_coordinate_system_constraint.ref_axis_type[i].ref_quantity_property) THEN
RETURN (FALSE);
END_IF;
END_REPEAT;
END_ALIAS;
RETURN (TRUE);
END_FUNCTION;
Where
attribute --> LOCATION {
coordinate_system (M) --> @InstanceId;
vertex --> @InstanceId;
coordinates (M) --> LIST ( RealValue, ... );
ref_unit_of_measure (M) --> LIST ( @InstanceId, ...); };
Ex: Give the (latitude, longitude) in NAD27 of (30deg 39min 43.8sec N, 98deg 09min 06.00sec W).
Ex: data_value --> LOCATION {
Ex: coordinate_system (M) --> @PRV_NAD27;
Ex: coordinates (M) --> LIST ( 30.6621782, -98.1516685);
Ex: ref_unit_of_measure (M) --> LIST (@PRV_dega, @PRV_dega); };
The following C structures are used to pass information about Locations between the layer and the application.
typedef struct daeLocationQuantityReal
{
daeInstance coordinateSystem;
daeInstance vertex;
daeInteger axesCount;
daeQuantityReal *coordinates;
} daeLocationQuantityReal;
typedef struct daeLocationQuantityDouble
{
daeInstance coordinateSystem;
daeInstance vertex;
daeInteger axesCount;
daeQuantityDouble *coordinates;
} daeLocationQuantityDouble;
The exact structure used depends on the significance of the coordinates. In each case the coordinates structure member is a pointer to an array of axesCount values.
The size of memory pointed to by the coordinates pointer does not change for a particular instantiation. A location is attached to a particular coordinate system and a particular coordinate system has an invariant number of axes. Therefore the total amount of memory allocated for a particular daeLocation... structure does not vary. To simplify memory management, the memory space for coordinates is placed at the bottom of a single block of memory allocated by malloc(). The coordinates pointer is therefore not a pointer to memory which must be freed. When the structure is freed the coordinates will be freed too.
The coordinateSystem member contains an instance handle which can be used to retrieve the coordinate system used for the location. This instance contains a repeat of the axes count. The coordinate system may have more axes than the location, but the reverse may not be true. The coordinates of the location correspond to the first axesCount dimensions of the coordinate system.
A set of ordinate values describing the location of a point in a coordinate system together with a set of specified property values associated with the point.
The selected coordinate system is specified by a reference to an instance of the Coordinate_system entity. The selected property types are specified by references to instances of the entity Ref_property_kind.
The coordinates may be evaluated with respect to a specified reference vertex or with respect to the origin of the selected coordinate system. The units of measure of the coordinates are constrained by the selected coordinate system axes. The units of measure of the properties are constrained by the quantity type of the property.
A point value consists of a location and a set of property values that apply to that location.
The location must satisfy the conditions for a value of type LOCATION ( coordinate_system, coord_precision_spec ).
META_TYPE point;
SUBTYPE OF (location);
property --> SET[1:?] OF point_property;
END_META_TYPE;
META_TYPE point_property;
ABSTRACT SUPERTYPE OF ( ONEOF( point_property_real, point_property_string ) );
ref_property_kind : ref_property_kind;
EXTERNAL
property_set_name : OPTIONAL STRING(40);
WHERE
set_valid : SIZEOF( QUERY ( tmp <* USEDIN( ref_property_
kind[1].ref_property_type, 'REF_PROPERTY_SET.REF_PROPERTY_TYPE') |
tmp.name = property_set_name ) ) > 0;
type_valid : type_correlation( ref_property_kind, property_set_name);
END_META_TYPE;
META_TYPE point_property_real;
SUBTYPE OF (point_property);
property_unit : ref_unit_of_measure;
real_value : REAL (property_precision);
coordinate_system_axis: OPTIONAL coordinate_system_axis;
EXTERNAL
property_precision: INTEGER;
WHERE
property_precision_valid: 0 < property_precision;
END_META_TYPE;
META_TYPE point_property_string;
SUBTYPE OF (point_property);
string_value : STRING;
END_META_TYPE;
FUNCTION type_correlation ( ref_property_kind : ref_property_kind ;
property_set_name : STRING(40 ) : BOOLEAN;
(* Check to see if the property type of the property kind is in
the set allowed by the property set. *)
IF NOT EXISTS(property_set_name) THEN
RETURN (TRUE); -- There is no set.
END_IF;
ref_property_set := QUERY ( tmp <* USEDIN( ref_property_kind.ref_
property_type, 'REF_PROPERTY_SET.REF_PROPERTY_TYPE') |
tmp.name = property_set_name );
IF NOT ( ref_property_kind.ref_property_type IN ref_property_
set.ref_property_type )THEN
RETURN (FALSE); -- The type is not in the set.
END_IF;
RETURN (TRUE); -- The type is in the set.
END_FUNCTION;
Where
The location attributes are inherited from meta type location. The example will specify both a real property and a string property.
attribute --> POINT {
coordinate_system (M) --> @InstanceId;
vertex --> @InstanceId;
coordinates (M) --> LIST( RealValue, ... );
ref_unit_of_measure (M) --> LIST( @InstanceId, ... ); };
property (M)--> SET (@prop1, @prop2, ... );
prop1 = POINT_PROPERTY_REAL {
ref_property_kind (M) --> @InstanceId;
coord_sys_axis --> @InstanceId;
ref_unit_of_measure (M) --> @InstanceId;
real_value (M) --> RealValue; };
prop2 = POINT_PROPERTY_STRING {
ref_property_kind (M) --> @InstanceId;
string_value (M) --> StringValue; };
... };
The following C structures are used to pass values of points between the facility and the application. The structure used depends on the significance of the coordinates.
typedef struct daePointVRealStructure
{
daeLocationQuantityReal location;
daeInteger propertyCount;
daePointPropertyReal *properties;
} daePointVReal;
typedef struct daePointVDoubleStructure
{
daeLocationQuantityDouble location;
daeInteger propertyCount;
daePointPropertyDouble *properties;
} daePointVDouble;
typedef struct daePointVAnyStructure
{
daeLocationReal location;
daeInteger propertyCount;
daePointPropertyAny *properties;
} daePointVAny;
typedef struct daePointPropertyRealStructure
{
daeInstance refProperty;
daeAcronym unitOfMeasure;
daeInstance coordinateAxis;
daeReal value;
} daePointPropertyReal;
typedef struct daePointPropertyDoubleStructure
{
daeInstance refProperty;
daeAcronym unitOfMeasure;
daeInstance coordinateAxis;
daeDouble value;
} daePointPropertyDouble;
typedef struct daePointPropertyAnyStructure
{
daeInstance refProperty;
daeAcronym unitOfMeasure;
daeInstance coordinateAxis;
daeAtype dataType;
daePointer valueAddress;
} daePointPropertyAny;
The daePointV... structure describes a point by the coordinate values of a location in a coordinate system together with zero or more property values. The propertyCount member specifies the number of properties. Each property is contained in a daePointProperty... structure.
The daePointProperty... structure specifies the value of a property associated with a point. The refProperty member is the instance of Ref_property_kind for the property and unitOfMeasure is the acronym attribute of the instance of Ref_unit_of_measure specifying the property units. The coordinateAxis member may be specified to be NULL or an instance of Coordinate_system_axis along which the property is measured.
A date value is a calendar date, specifying a year, month, and day of month. This is intended to conform to the SQL92 specification for DATE (see DATE in Section 9, "Language" ).
A date value must be suitable to represent a date in the Gregorian calendar. The value is expected to be able to represent modern dates. It need not be able to represent geological times.
META_TYPE date;
year : INTEGER;
month : INTEGER;
day : INTEGER;
WHERE
year_valid : { 1 <= year <= 9999 };
month_valid : { 1 <= month <= 12 } ;
day_valid: ( ( month IN [1,3,5,7,8,10,12] ) AND { 1 <= day <= 31 } ) XOR
( ( ( month IN [4,6,9,11] ) AND { 1 <= day <= 30 } ) XOR
( ( month = 2 ) AND
((((((year mod 4) = 0) AND ((year mod 100) <> 100)) OR
((year mod 400) = 0)) AND { 1 <= day <= 29 }) OR
{ 1 <= day <= 28 } )));
END_META_TYPE;
attribute --> DATE { -- yyyy-mmm-dd
year --> IntegerValue;
month --> IntegerValue;
day --> IntegerValue; };
Ex: start_date --> DATE { --1996-June-18
Ex: year --> 1996;
Ex: month --> 6;
Ex: day --> 18; };
The primary interface to a date is through a structure which separates the year, month, and day.
typedef struct daeDateStructure
{
daeShort year;
daeShort month;
daeShort day;
} daeDate, *daeDatePtr;
A date may alternatively be cast as a timestamp, or into a standard C "tm" structure, which is presented as the C data type daeTime. When a value is retrieved in these extended structures, the time values and UCT offset will be zero. When updated, the time values and UCT offset will be ignored.
A time value is a clock time in Universal Coordinated Time (UCT), where the clock time gives hour within day, minutes within hour, and seconds within minute. This is intended to conform to the SQL92 specification for TIME (see "TIME" in Section 9, "Language" ).
The value must represent the time within a day, to the precision specified. The SQL92 specification indicates that values are expected to be maintained in Universal Coordinated Time (UCT). This avoids ambiguity not only for which time zone the value is correct but also for the changes between standard and daylight savings times.
META_TYPE time;
hour : INTEGER;
minute : INTEGER;
second : REAL ( precision );
uct_offset : DAYTIMEINTERVAL;
EXTERNAL
precision : INTEGER;
WHERE
hour_valid : { 0 <= hour <= 23 };
minute_valid : { 0 <= minute <= 59 };
second_valid : { 0.0 <= second < 62.0 };
nonleap_second_valid: (second<60.0) OR ((hour=23) AND
(minute=59));
offset_valid : ( (uct_offset.days=0) AND
(uct_offset.seconds=0.0) AND
(uct_offset.hour >= -12) AND
(((uct_offset.hour=13) AND
(uct_offset.minute=0)) OR
(uct_offset.hour <= 12))) );
precision_valid : 0 < precision;
END_META_TYPE;
Where
attribute --> TIME { -- hh:mm:ss.sss (uct_offset)
hour (M) --> IntegerValue;
minute (M) --> IntegerValue;
second (M) --> RealValue;
uct_offset (M) --> DAYTIMEINTERVAL{
days (M) -- 0;
hours (M) --> IntegerValue;
minutes (M) --> IntegerValue;
seconds (M) --> 0; }; };
Ex: end_time --> TIME { -- 8:10 PM Houston time.
Ex: hour (M) --> 20;
Ex: minute (M) --> 10;
Ex: seconds (M) --> 0.0;
Ex: uct_offset (M) --> DAYTIMEINTERVAL {
Ex: days (M) --> 0;
Ex: hours (M) --> -6;
Ex: minutes (M) --> 0;
Ex: seconds (M) --> 0; }; };
Two structures are available for passing clock time: one casts the seconds to single precision real, the other casts the seconds to double precision.
typedef struct daeTimeRealStructure
{
daeShort hour;
daeShort minutes;
daeReal seconds;
daeBoolean uctOffsetFlag;
daeDayTimeIntervalReal uctOffset;
} daeTimeReal;
typedef struct daeTimeDoubleStructure
{
daeShort hour;
daeShort minutes;
daeDouble seconds;
daeBoolean uctOffsetFlag;
daeDayTimeIntervalReal uctOffset;
} daeTimeDouble;
The uctOffset member is a day-time interval specifying the difference between UCT and the specified time. When this structure is passed as an input argument uctOffsetFlag may be set to TRUE to indicate that uctOffset is specified. uctOffset is a hour to minute day-time interval with the permitted values of -12:59 through 13:00. If uctOffsetFlag is FALSE, then the offset from UCT of the local time zone for the session is implied and uctOffset is ignored. When this structure is returned as an output argument uctOffsetFlag is always set to TRUE and the returned time has a value for uctOffset which is the original UCT offset of the time.
A calendar date and clock time in UCT. This is intended to conform to the SQL92 specification for TIMESTAMP (see "TIMESTAMP" in Section 9, "Language" ).
A value of TIMESTAMP consists of a calendar date and a clock time.
META_TYPE timestamp;
date : date;
time : time ( precision );
EXTERNAL
precision : INTEGER;
WHERE
precision_valid : 0 < precision;
nonleap_second_valid: (time.second<60.0) OR
(leap_year(date.year) AND (date.month=12) AND
(date.day=31) AND (time.hour=23) AND
(time.minute=59));
END_META_TYPE;
FUNCTION leap_year ( year : integer ) : BOOLEAN;
IF ((((year mod 4) = 0) AND
((year mod 100) <> 100)) OR
((year mod 400) = 0)) THEN
RETURN (TRUE);
END_IF;
RETURN (FALSE);
END_FUNCTION;
attribute --> TIMESTAMP {
DATE {
attributes for date };
TIME {
attributes for time };
Ex: end_time --> TIMESTAMP { -- 1990-Dec-21 12 noon UCT;
Ex: date (M) --> DATE {
Ex: year (M) --> 1990;
Ex: month (M) --> 12;
Ex: day (M) --> 21; };
Ex: time (M) = TIME {
Ex: hour (M) --> 12;
Ex: minute (M) --> 0;
Ex: second (M) --> 0.0;
Ex: uct_offset (M) --> DAYTIMEINTERVAL {
Ex: days (M) --> 0;
Ex: hours (M) --> 0;
Ex: minutes (M) --> 0;
Ex: seconds (M) --> 0; }; }; };
A timestamp may be cast to a structure combining date and time:
typedef struct daeTimeStampRealStructure
{
daeDate date;
daeTimeReal time;
} daeTimeStampReal;
typedef struct daeTimeStampDoubleStructure
{
daeDate date;
daeTimeDouble time;
} daeTimeStampDouble;
or may be cast to the C "tm" structure:
typedef struct daeTimeStructure /
{
int tm_sec; /* seconds (0-62)(allows leap-seconds)*/
int tm_min; /* minutes (0-59) */
int tm_hour; /* hours (0-23) */
int tm_mday; /* day of month (1-31) */
int tm_mon; /* month of year (0-11) */
int tm_year; /* years since 1900 */
int tm_wday; /* days since Sunday (0-6) */
int tm_yday; /* days since January 1 (0-365) */
int tm_isdst; /* not used */
} daeTime, *daeTimePtr;
The tm_isdst value in this structure are not used; time is assumed to be in UCT.
A year-month-interval is an interval between two dates, given in years and months. The maximum range is +/- 99999 years. This is intended to conform to the SQL92 specification of year-month intervals (see "YEARMONTHINTERVAL" in Section 9, "Language" ).
The value must represent a time interval expressed in years and whole months, and it must be able to store the required range of values.
META_TYPE yearmonthinterval;
years : INTEGER;
months : INTEGER;
WHERE
year_valid : { 0 <= ABS(years) <= 9999 };
month_valid : { 0 <= ABS(months) <= 11 };
sign_valid : (( 0 <= years ) AND ( 0 <= months )) XOR
(( 0 >= years ) AND ( 0 >= months ));
END_META_TYPE;
attribute --> YEARMONTHINTERVAL {
years --> IntegerValue;
months --> IntegerValue; };
Ex: interval --> YEARMONTHINTERVAL { -- positive 2 months.
Ex: years --> 0;
Ex: months --> 2; };
Ex: interval --> YEARMONTHINTERVAL { -- negative 2 years 7 months.
Ex: years --> -2;
Ex: months --> -7; };
The value may be cast into a structure that represents years and months. Non-zero members of the structure must be all positive or all negative.
Years will be signed, except when years is zero. Non-zero members of the structure must be all positive or all negative.
typedef struct daeYearMonthIntervalStructure
{
daeInteger years;
daeShort months;
} daeYearMonthInterval;
A year month interval may be cast as if it were a quantity value of quantity type `time', but with some possible loss of precision. The length of each year shall be the same and the length of each month shall be one twelfth the length of a year. The casting algorithm shall take into account that the value can retain only whole months and round to the nearest month.
A day-time-interval is a time interval measured using certain combinations of days, hours, minutes, and seconds. The maximum size is +/- 99999 days. This is intended to conform to the SQL92 specification for day-time intervals (see"DAYTIMEINTERVAL" in Section 9, "Language" ).
The value must be able to hold a time interval of up to 99999 days to the precision specified for seconds. For example, a double precision floating point number can support a daytime interval with 4 significant figures for seconds.
META_TYPE daytimeinterval;
days : INTEGER;
hours : INTEGER;
minutes : INTEGER;
seconds : REAL ( precision );
EXTERNAL
precision : INTEGER;
WHERE
day_valid : { 0 <= ABS(day) <= 99999 };
hour_valid : { 0 <= ABS(hour) <= 23 };
minute_valid : { 0 <= ABS(minute) <= 59 };
second_valid : { 0.0 <= ABS(second) < 60 };
precision_valid : 0 < precision;
sign_valid : (( 0 <= day ) AND ( 0 <= hour ) AND
( 0 <= minute ) AND ( 0 <= second )) XOR
(( 0 >= day ) AND ( 0 >= hour ) AND
( 0 >= minute ) AND ( 0 >= second ));
END_META_TYPE;
attribute --> DAYTIMEINTERVAL {
days (M) -- IntegerValue;
hours (M) --> IntegerValue;
minutes (M) --> IntegerValue;
seconds (M) --> RealValue; };
Ex: interval --> DAYTIMEINTERVAL {
Ex: days (M) --> 12;
Ex: hours (M) --> 4;
Ex: minutes (M) --> 16;
Ex: seconds (M) --> 12.11; };
A value of type DAYTIMEINTERVAL can be cast as if it is a quantity value of quantity type `time'. The units defaults applying to `time' also apply to a DAYTIMEINTERVAL value.
In addition it may be cast into a structure which represents the seconds as a single or double precision floating point number.
typedef struct daeDayTimeIntervalRealStructure
{
daeInteger days;
daeShort hours;
daeShort minutes;
daeReal seconds;
} daeDayTimeIntervalReal;
typedef struct daeDayTimeIntervalDoubleStructure
{
daeInteger days;
daeShort hours;
daeShort minutes;
daeDouble seconds;
} daeDayTimeIntervalDouble;
Non-zero members of the structure must be all positive or all negative.
A quantity value consists of a real number and a unit of measure, qualifying the real number. Each quantity attribute is specified with a quantity_type. Each quantity_type has a set of alternative units of measure defined. These constrain the choice of unit of measure to one of the set.
Epicentre reference schema .
The content must reproduce the value, with at least the minimum precision specified, and with a unit of measure.
The Epicentre data model specifies the permitted units of measure for each quantity type [diagram MTP: Reference Properties] and the conversions between different units of measure [diagram MTU: Reference Unit of Measure].
META_TYPE quantity;
real_value : REAL ( precision );
ref_unit_of_measure : ref_unit_of_measure;
EXTERNAL
quantity_type_name : STRING(40);
precision : INTEGER;
WHERE
precision_valid : 0 < precision;
units_valid : SIZEOF ( QUERY ( tmp <* USEDIN ( ref_unit_of_measure,
'REF_QUANTITY_TYPE.ALTERNATIVE_UNIT_OF_MEASURE') |
tmp.name = quantity_type_name ) ) = 1;
END_META_TYPE;
attribute --> QUANTITY { -- name of ndt is recommended
real_value (M) --> RealValue;
ref_unit_of_measure (M) --> @InstanceId; };
Ex: pipe_length --> QUANTITY { -- ndt_length_midrange
Ex: real_value (M) --> 30.016;
Ex: ref_unit_of_measure (M) --> @PRV_ft; };
For each session, there are three modes of accessing quantities with units. First, DEFAULT_UNITS, in which all quantity values are converted from stored units to the default units on retrieval and converted from default units to stored units on input. Second, NO_DEFAULT_UNITS, in which all quantity values are retrieved in stored units and input with explicitly specified units which are converted to stored units. And third, REPORTED_UNITS, in which all quantity values are retrieved in stored units and are stored in their explicitly specified units with no units conversion taking place.
For passing a value with units, there are two structures defined: one for single precision and one for double precision values.
typedef struct daeQuantityRealStructure
{
daeReal quantity;
daeAcronym unit;
} daeQuantityReal;
typedef struct daeQuantityDoubleStructure
{
daeDouble quantity;
daeAcronym unit;
} daeQuantityDouble;
When working with default units, a quantity data type may also be passed as a float or double C value.
A value of type anyquantity can hold the value of any physical quantity. The value consists of the quantity type, a real number, and a unit of measure qualifying the real number. After a quantity type has been defined, the value may be treated like a value of type quantity.
The content must include a reference to Ref_quantity_type as well as any content required to represent a value of type quantity.
META_TYPE anyquantity_value;
real_value : REAL ( precision );
ref_unit_of_measure : ref_unit_of_measure;
ref_quantity_type : ref_quantity_type;
EXTERNAL
precision : INTEGER;
WHERE
precision_valid : 0 < precision;
units_valid : ref_unit_of_measure IN ref_quantity_type.alternative_unit_of_measure;
END_META_TYPE;
attribute --> ANYQUANTITY {
real_value (M) --> RealValue;
ref_unit_of_measure (M) --> @InstanceId;
ref_quantity_type (M) --> @InstanceId; };
Ex: value --> ANYQUANTITY {
Ex: real_value (M) --> 16.11729554;
Ex: ref_unit_of_measure (M) --> @PRV_dega;
Ex: ref_quantity_type (M) --> @PRV_plane_angle; };
For setting the value there are three structures defined: one for single and one for double precision and one for integer.
typedef struct daeQuantityRealStructure
{
daeReal quantity;
daeAcronym unit;
daeName quantity_type;
} daeAnyQuantityReal;
typedef struct daeAnyQuantityDoubleStructure
{
daeDouble quantity;
daeAcronym unit;
daeName quantity_type;
} daeAnyQuantityDouble;
typedef struct daeAnyQuantityIntegerStructure
{
daeInteger quantity;
daeAcronym unit;
daeName quantity_type;
} daeAnyQuantityInteger;
After an attribute value is assigned a quantity name, any of the casts permitted for a quantity type are allowed.
An angle value is a quantity value with quantity type that represents a plane angle and has a permitted unit of degrees. It may be used as if it were a quantity or it may be passed in a structure containing degrees, minutes, and seconds.
An angle is specified as degrees, minutes within a degree (0 to 59) and seconds within a minute (0 to less than 60).
META_TYPE angle;
ABSTRACT SUPERTYPE OF ( ONEOF(angle_quantity, angle_dms) );
END_META_TYPE;
META_TYPE angle_quantity;
SUBTYPE OF (angle, quantity);
END_META_TYPE;
META_TYPE angle_dms;
SUBTYPE OF (angle, quantity);
degrees : INTEGER;
minutes : INTEGER;
seconds : REAL ( precision-6 );
EXTERNAL
quantity_type_name : STRING(40);
precision : INTEGER;
WHERE
minute_valid : { 0 <= ABS(minutes) <= 59 };
second_valid : { 0 <= ABS(seconds) < 60 };
precision_valid : 0 < precision;
sign_valid : (( 0 <= degrees ) AND ( 0 <= minutes ) AND
( 0 <= seconds ) XOR (( 0 >= degrees ) AND
( 0 >= minutes ) AND ( 0 >= seconds ));
END_META_TYPE;
attribute --> ANGLE_DMS {
degrees (M) --> IntegerValue;
minutes (M) --> IntegerValue;
seconds (M) --> RealValue; };
or
attribute --> ANGLE_QUANTITY {
real_value (M) --> RealValue;
ref_unit_of_measure (M) --> @InstanceId; };
Ex: longitude --> ANGLE_DMS { -- 96:12:15.23 West
Ex: degrees (M) --> -96;
Ex: minutes (M) --> -12;
Ex: seconds (M) --> -15.23; };
or
Ex: longitude --> ANGLE_QUANTITY { -- ndt_earth_angle
Ex: real_value (M) --> -96.20423056;
Ex: ref_unit_of_measure (M) --> @PRV_dega; };
A value of type ANGLE can be cast as if it is a quantity value of a quantity type that represents a plane angle. The units defaults that apply to `plane angle' also apply to an ANGLE value.
In addition, an angle may be cast into a structure representing the seconds as a single or double precision floating point number.
typedef struct daeDMSRealStructure
{
daeShort degrees;
daeShort minutes;
daeReal seconds;
} daeDMSReal;
typedef struct daeDMSDoubleStructure
{
daeShort degrees;
daeShort minutes;
daeDouble seconds;
} daeDMSDouble;
Non-zero members of the structure must be all positive or all negative.
A continuous line described in a specific coordinate system. One representation is given consisting of a 1D grid of points where the grid may be indexed using an axis of the coordinate system, or it may be parametrically indexed. The points are measured with respect to a specified reference vertex or with respect to the origin of the coordinate system. This is illustrated in Figure F-1.
The value instance of line consists of a reference to an instance of the entity Grid_1d, which contains the grid index values, the remaining set of grid point coordinates for the specified coordinate system, and the units of measure of the coordinate values for each coordinate system axis.
Properties may be attached to the nodes and edges of the line grid using the data type ELEMENT. The line data type is declared as follows:
The only representation of a line is as the geometry on a 1D grid, implemented in a geometry frame as described in this Data Access and Exchange specification.
The content of a value of line data type is that it is a geometry frame with the following additional rules:
See also Appendix F.5, "Content Model for Frames" .
For a non-sparse representation. The dimension is described by a descriptor. The detailed_type of `FT_CLOSED_LINE' means that the last point will be connected to the first point.
attribute --> LINE_GRID {
gframe = GEOMETRY_FRAME {
detailed_type (M) --> `FT_LINE'; -- or `FT_CLOSED_LINE'
descriptor (M) --> LIST(@descr_1); (* There is only one
descriptor for a line (grid_1d) *)
leaf_frame (M) --> SET(@geom_leaf_1, ... ); (* There is a
leaf frame for every axis in the coordinate_system.
This may be (in general) one, two, or three. Only one
will be shown below. *)
grid_or_mesh (M) --> @InstanceId;
coordinate_system (M) --> @InstanceId;};
descr_1 = DESCRIPTOR {
dimension (M) --> `INDEX_I';
lower_bound (M) --> IntegerValue;
count (M) --> IntegerValue;};
geom_leaf_1 = LEAF_FRAME {
data_type (M) --> `DAE_C_...'; -- usually DAE_C_FLOAT.
ref_unit_of_measure --> @InstanceId;
coordinate_system_axis --> @InstanceId;
data_values --> LIST(array of count data values); }; };
For a sparse representation, a leaf is needed which will give the "array" of grid indexes.
attribute --> LINE_GRID {
gframe = GEOMETRY_FRAME {
detailed_type (M) --> `FT_SLINE'; -- or
`FT_SCLOSED_LINE'
descriptor (M) --> LIST(@descr_1);
leaf_frame (M) --> SET(@index_leaf, @geom_leaf_1, ...);
(* In addition, there is a leaf frame for every axis
in the coordinate_system. This may be (in general)
one, two, or three. Only one will be shown
below. *)
grid_or_mesh (M) --> @InstanceId;
coordinate_system --> @InstanceId;};
descr_1 = DESCRIPTOR{
dimension (M) --> `INDEX_UNDEFINED';
count (M) --> IntegerValue; };-- size of leaf arrays
index_leaf = LEAF_FRAME {
index_name --> `I';
data_type (M) --> `DAE_C_INT';
data_values --> LIST(array of "count" grid indexes); };
geom_leaf_1 = LEAF_FRAME {
data_type --> `DAE_C_...'; -- usually DAE_C_FLOAT.
ref_unit_of_measure --> @InstanceId;
coordinate_system_axis --> @InstanceId;
data_values --> LIST(array of "count" data values);}
... };
A line value maps directly to a geometry frame of frame type FT_LINE, FT_SLINE, FT_CLOSED_LINE or FT_SCLOSED_LINE. The geometry frame retains the references to coordinate system and grid.
The geometry frame has one leaf array for each coordinate system axis. Where the coordinate values for a coordinate system axis are held in a grid axis, the corresponding leaf is not filled in. For sparse frames, one index leaf must be defined representing dimension I.
A continuous surface described in a specific coordinate system with positions measured with respect to a specified reference vertex or with respect to the origin of the coordinate system. Three types of surface representation have been defined:
The surface contains a value that is one of these three.
All three representations share the same declaration syntax.
A surface value is either a surface mesh, a surface grid or a surface contour. The content is described as one of those three. See also Appendix F.5, "Content Model for Frames" .
If type is not specified, it is not possible for an application to directly retrieve the value of an attribute of type surface. First, an application must retrieve the internal data type using a call to daeGetAttributeType. This call returns the internal data type (daeDtype), which distinguishes between the mesh, the grid, and the contour.
This data type represents a surface as a set of interconnected triangles. Each triangle consists of three nodes and three edges. An edge may be shared by one or two triangles and be defined by two nodes. Any triangle can be reached from any other triangle by traversing their shared edges. The intent is illustrated in Figure F-2.
The type instance references an instance of the entity Grid_trimesh, which defines the number of nodes, edges, and triangles, and their connections using integer numbers to identify each mesh component. The type instance also references a coordinate system and contains the coordinate values of the mesh nodes evaluated in the selected units of the corresponding coordinate system axes.
Additional properties may be attached to the mesh nodes, edges and triangles using the ELEMENT types.
A surface mesh value consists of a property frame with the following constraints:
The content of a value of surface mesh data type is that it is a geometry frame with the following additional rules:
See also Appendix F.5, "Content Model for Frames" .
A surface mesh value maps directly to a geometry frame of frame type FT_MESH. The geometry frame retains the reference to the coordinate system and grid instances.
The geometry frame has one leaf array for each coordinate system axis.
This data type represents a surface using a two dimensional grid, consisting of nodes, edges and faces. The function of the grid is to uniquely describe every point of the surface. Each node is identified by two indices, i and j. Edges are defined between adjacent nodes, and faces are defined by four adjacent nodes. An edge may be shared by one or two faces and all faces can be reached from every other face by traversing the common edges. Additionally, the space of a face can be described by another 2D grid, otherwise known as local grid refinement. This is illustrated in Figure F-3.
The surface type instance references an instance of Grid_defined_grid and the selected coordinate system instance. Two of the coordinate system axes may be used to index the Grid_defined_grid. The remaining coordinate values of the nodes are contained by the surface type instance. All the coordinate values of a coordinate system axis have the same unit of measure, which is restricted by the Ref_quantity_property instance of the coordinate system axis.
Property values may be attached to some or all nodes, edges or faces of the grid using the ELEMENT data type.
A surface grid value consists of a geometry frame with the following constraints:
See also Appendix F.5, "Content Model for Frames" .
There are two possibilities that allow for sparse or dense storage. This section will give only the case of `FT_SURFACE'. The variations for sparse will be given after this pattern.
attribute --> SURFACE_GRID {
gframe = GEOMETRY_FRAME {
detailed_type (M) --> `FT_SURFACE';
descriptor (M) --> LIST(@descr_1, @descr_2); (* There
are two descriptors -One for each grid axis *)
leaf_frame (M) --> SET(@leaf_1, ...); (* There is
one leaf for every axis in the coordinate_system.
This may be, in general, one, two, or three. Only
one will be shown below. *)
grid_or_mesh (M) --> @InstanceId;
coordinate_system (M) --> @InstanceId;};
descr_1 = DESCRIPTOR { -- parameters for the first grid index
dimension (M) --> `INDEX_I';
lower_bound (M) --> IntegerValue;
count (M) --> IntegerValue;};
descr_2 = DESCRIPTOR { (* parameters for the second grid index *)
dimension (M) --> `INDEX_J';
lower_bound (M) --> IntegerValue;
count (M) --> IntegerValue;};
leaf_1 = LEAF_FRAME {
data_type (M) --> `DAE_C_...'; -- usually DAE_C_FLOAT
ref_unit_of_measure (M) --> @InstanceId;
coordinate_system_axis (M) --> @InstanceId;
data_values (M) --> LIST(array of count_1 times
count_2 data values); }; };
For a sparse representation, the detailed_type will be FT_SSURFACE and there will be one DESCRIPTOR using `INDEX_UNDEFINED'. There will need to be two index leaf frames, one for each of the grid axes. These two index frames together will define the pair of gird indexes that place the value on the grid. See the Express-I sparse example for LINE.
A surface grid value maps directly to a geometry frame of frame type FT_SURFACE or FT_SSURFACE. The geometry frame retains the coordinate system and grid instance.
The geometry frame visible in the interface has one leaf array for each coordinate system axis. For sparse frames, two index leaf must be defined representing dimensions I and J.
This data type represents a surface as a set of contours, where each contour is an iso value line of a surface specified property located in a 2D space. The 2D space is specified by selecting two coordinate axes of a coordinate system which conforms to the Ref_coordinate_system_constraint specification of the type and the surface property is specified by selecting any instance of the entity Ref_property_kind.
Each contour line, describing the surface, contains the value of the line. It is either open or closed and is described by a sequence of 2D coordinate locations.
The contour value consists of a set of lines, one for each property value. The contour value representation is quite different than the other surface representations.
META_TYPE surface_contour;
isoline_set : isoline_set;
END_META_TYPE;
attribute --> SURFACE_CONTOUR {
isoline_set = @isoset; };
isoset = ISOLINE_SET {
identifier (M) --> `string value';
ref_property_kind (M) --> @InstanceId;
ref_unit_of_measure --> @InstanceId;
isoline <-- SET( @isoline1, ... ); };
isoline1 = ISOLINE {
identifier (M) --> 'StringValue';
isovalue (M) --> RealValue; (* Specifies the value
associated with the contour, for example the
elevation. *)
line_geometry (M) --> LINE {...}; (* A line geometry
frame (see LINE) that holds the array of coordinate values.
Note that the line geometry can specify that the contour
is open or closed. *)
isoline_set (M) --> @isoset; };
Contours are represented as instances of the Epicentre entity Isoline_set which contains a reference to a property and a set of Isoline instances. Each Isoline instance contains an isovalue for the property and a LINE geometry frame holding positions of points along the line. Different isolines may have the same isovalue.
A continuous volume described in a specific coordinate system, with positions measured with respect to a specified reference vertex or with respect to the origin of the coordinate system.
The 3D grid can be regular 3D, irregular 3D, or unstructured 3D.
The intention of the 3d Grid representation is illustrated in Figure F-4.
Property values may be attached to some or all nodes, edges, faces or cells of the grid using ELEMENT data type.
The structure, refinements, and missing cells are modeled within a Grid_defined_grid having 3 axes [see diagram MTG: Grids and Meshes]. When Grid_1d_equal and Grid_1d_unequal are used to describe a grid in a 3D coordinate system, the positions of the nodes may be defined by the information stored with the grid instance.
The content of a value of volume data type is that it is a geometry frame with the following additional rules:
See also Appendix F.5, "Content Model for Frames" .
attribute --> VOLUME_GRID {
gframe = GEOMETRY_FRAME {
detailed_type (M) --> `FT_VOLUME';
descriptor (M) --> LIST(@descr_1, @descr_2, @descr_3);
(* There are three descriptors - One for each grid
axis *)
leaf_frame (M) --> SET(@leaf_1, ...); (* There is one
leaf for every axis in the coordinate_system. This may
be, in general, one, two, or three. Only one will be
shown below. *)
grid_or_mesh (M) --> @InstanceId;
coordinate_system (M) --> @InstanceId;};
descr_1 = DESCRIPTOR { (* parameters for the first grid index *)
dimension (M) --> `INDEX_I';
lower_bound (M) --> integer value;
count (M) --> integer value;};
(* descr_2 and descr_3 differ from descr_1 in that
they use `INDEX_J' and `INDEX_K' instead of
`INDEX_I' *)
leaf_1 = LEAF_FRAME {
data_type --> `DAE_C_...'; -- usually DAE_C_FLOAT
ref_unit_of_measure --> @InstanceId;
coordinate_system_axis --> @InstanceId;
data_values --> LIST(array of count_1 times count_2
times count_3 data values); }; };
For a sparse representation, there will be one DESCRIPTOR using `INDEX_UNDEFINED'. There will need to be three index leaf frames, one for each of the grid axes. These three index frames together will define the grid indexes that locate the value on the grid. See the Express-I sparse example for LINE.
A volume grid value maps directly to a geometry frame of frame type FT_VOLUME, FT_SVOLUME, FT_CORNER_POINT, or FT_UNSTRUCTURED. The geometry frame holds the references to the coordinate system and grid instance.
The geometry frame visible in the interface has one leaf array for each coordinate system axis. For sparse frames, three index leaf frames must be defined representing dimensions I, J and K.
This data type attaches property values to the elements of a Grid_or_mesh instance. The ELEMENT instance consists of an array of fixed or variable length values for a specified set of property types, where the array index corresponds to the node, edge, face, or cell indices of a specified Grid_or_mesh instance. The unit of measure used for each property type is also recorded.
One or more property types may be attached to a single grid element type. The element type and property types that can be specified in an instance are constrained by the declaration parameters.
Data instances of ELEMENT can refer to the same Grid_or_mesh instance allowing the Grid_or_mesh to be reused to add additional properties.
A value of element type is a property frame with the following additional rules:
See also Appendix F.5, "Content Model for Frames" .
attribute --> ELEMENT {
pframe = PROPERTY_FRAME {
detailed_type (M) --> E..._...; -- such as EGRID_3DNODE
descriptor (M) --> LIST(@descr_1,...); (* There is a
descriptor for each grid axis. Only one will be
shown below *)
leaf_frame (M) --> SET(@leaf_1,...); (* There is a leaf
frame for each related property. In general, there is
only one leaf frame for a pty_....data_value. Only one
will be shown in the example below. *)
grid_or_mesh (M) --> @InstanceId;};
descr_1 = DESCRIPTOR { (* parameters for the first index of the grid *)
dimension (M) --> `INDEX_I';
lower_bound (M) --> IntegerValue;
count (M) --> IntegerValue;}; (* descr_2 and descr_3
(if needed) differ from descr_1 in that they use
`INDEX_J' and `INDEX_K' instead of `INDEX_I'. *)
leaf_1 = LEAF_FRAME {
ref_property_kind --> @InstanceId;
coordinate_system_axis --> @InstanceId;
data_type --> `DAE_C_...'; (* usually numeric such as
DAE_C_FLOAT but may be DAE_C_CHAR *)
ref_unit_of_measure --> @InstanceId;
data_values --> LIST(array of "count 1" times "count 2"
times "count 3" data values); }; };
For a sparse representation, the frame type will be a sparse variation such as SGRID_3DNODE and there will be one DESCRIPTOR using `INDEX_UNDEFINED'. There will need to be one index leaf frame for each of the grid axes. These index frames together will define the gird indexes that locate the value on the grid. See the EXPRESS-I sparse example for LINE.
There is no special C structure for passing Elements back and forth between the application and the layer. None is needed because an element maps directly to a property frame having a grid. The property frame contains the reference to the grid, and one of the element types listed in the daeEtype data type. The element type determines the indexing system.
There will be one leaf frame for each property and, in the case of elements instantiated as sparse, one leaf frame for each dimension index.
This data type contains repeat sample values of a specified set of property types or independent variables. Each sample has a sample index and a set of property values, where the property types apply to all indexed samples. No dependence between indexed samples is implied.
The sample data type instance specifies the set of property types and the unit of measure used for each type.
A value of the sample data type is a property frame with the following additional rules:
See also Appendix F.5, "Content Model for Frames" .
attribute --> SAMPLE{
pframe = PROPERTY_FRAME {
detailed_type (M) --> `FT_SAMPLE';
descriptor (M) --> LIST(@descr_1); (* There is only one
descriptor. *)
leaf_frame (M) --> SET(@leaf_1,...); }; (* There is a
leaf frame for each stored property. Only one
will be shown in the example below. *)
descr_1 = DESCRIPTOR { (* parameters for the first index of the grid *)
dimension (M) --> `INDEX_UNDEFINED';
count (M) --> IntegerValue;};
leaf_1 = LEAF_FRAME {
ref_property_kind --> @InstanceId;
coordinate_system_axis --> @InstanceId; (* if appropriate *)
data_type --> `DAE_C_...'; -- usually DAE_C_FLOAT
ref_unit_of_measure --> @InstanceId;
data_values --> LIST(array of count data value); }; };
...};
There is not a sparse alternative for sample.
The sample value is presented as a property frame with the above content.
A set of cells, nodes, faces, and edges, and a description of the relationships between them. This data type is needed to support 3D unstructured grids. Compared to grids which Epicentre supported in V1.0, unstructured 3D grids contain a vast amount of information describing the relationships between the cells, faces, edges and nodes of which they are comprised. The definition of the cells and their components and relationships could have been done by creating a set of entities which would fully describe the grids. However, because the data is voluminous and of interest mainly to application programs rather than casual browsers, POSC decided to embed this information in a data type. This requires no parameters, all of the information being integer based.
Within the context of the discussion on UNSTRUCTURED 3D TOPOLOGY, a node is defined as a point having a single set of coordinates within the agreed upon coordinate system.
UNSTRUCTURED 3D TOPOLOGY embodies the following concepts:
These concepts lead to a set of usage conventions:
The UNSTRUCTURED_3D_TOPOLOGY value is represented as:
META_TYPE us3_geom;
ordinal : OPTIONAL INTEGER;
cell : SET [0:?] OF us3_cell;
END_META_TYPE;
META_TYPE us3_cell;
ordinal : OPTIONAL INTEGER;
center : OPTIONAL us3_node;
face : OPTIONAL SET [0:?] OF us3_face;
END_META_TYPE;
META_TYPE us3_face;
ordinal : OPTIONAL INTEGER;
adjacent_to : OPTIONAL SET [0:?] Of us3_face;
center : OPTIONAL us3_node;
edge : OPTIONAL SET [0:?] OF us3_edge;
INVERSE
cell : SET [1:?] OF us3_cell FOR face;
adjacent_from : SET {0,?] Of us3_face FOR adjacent_to;
END_META_TYPE;
META_TYPE us3_edge;
ordinal : OPTIONAL INTEGER;
node : OPTIONAL SET [0:?] OF us3_node;
INVERSE
face : SET [1:?] OF us3_face FOR edge;
END_META_TYPE;
META_TYPE us3_node;
ordinal : OPTIONAL INTEGER;
INVERSE
edge : SET [0:?] OF us3_edge FOR node;
center_of_cell : us3_cell FOR center;
center_of_face : us3_face FOR center;
END_META_TYPE;
Where
The following C structures are used to pass information about Locations between the layer and the application.
typedef enum {
DAE_US_CELL,
DAE_US_NODE,
DAE_US_FACE,
DAE_US_EDGE,
} daeUSGridElement;
typedef struct
{
daeInteger faceCount;
daeInteger *face;
daeInteger center;
} daeGridCell;
typedef struct
{
daeInteger adjacentCount;
daeInteger *adjacent;
daeInteger edgeCount;
daeInteger *edge;
daeInteger cellCount;
daeInteger *cell;
daeInteger center;
} daeGridFace;
typedef struct
{
daeInteger faceCount;
daeInteger *face;
daeInteger nodeCount;
daeInteger node;
} daeGridEdge;
typedef struct
{
daeInteger edgeCount;
daeInteger *edge;
daeInteger faceCenter;
daeInteger cellCenter;
} daeGridNode;
Cells, nodes, edges, and faces are all assigned implicit identifiers, which are zero-based ordinal numbers. The numbering is arbitrary, assigned by the definer of the grid. There are no missing numbers in the scheme. The API accepts and presents arrays of the structures identified above, and the identifiers are the indexes into individual structures in these arrays.
These cell, node, edge, or face identifiers also serve as the INDEX_UNDEFINED ordinals in the ELEMENT(unstructured3d,<cell | node | edge | face>,,) property frame as appropriate, thus tying a set of properties to a specific structure in the grid. This allows us to overload the operations currently used for ELEMENTS of type "trimesh, node" for unstructured properties.
In a similar manner, the node identifiers are used as the INDEX_UNDEFINED ordinals in the VOLUME unstructured 3d data type which is used to store the coordinates of the nodes in some specific coordinate system. This operation is the same as operations currently used for SURFACES of type "trimesh".
The UNSTRUCTURED_3D_TOPOLOGY structure and its operations are made more complex by the fact that no upper bound can be set on any of the relationships. Therefore, the actual lists of related structures must be kept apart from the structure arrays. These lists are kept in individual integer arrays, pointed to by the structures themselves.
For relationships which are lists, a null list is signified by a count of zero and a list address equal to NULL. Since NULL is generally equivalent to 0L and since 0 is a valid ordinal number, null relationships of cardinality 1 are signified by -1L.
The following EXPRESS indicates the content for the frames as stored. Note that this is a content model and represents the content of a stored value. It does not include the transient control frames which are described in this Data Access and Exchange specification. Its purpose is to illustrate. It is not a model that can be accessed as a data model. Where the attributes are accessible through the interface, they are in C data types or arguments to calls.
The content model is presented as annotated EXPRESS. It is not complete in all the rules and constraints, particularly for consistency with values in the Epicentre model. EXPRESS language is shown in Courier typeface, e.g.:
SCHEMA content;
The frames constructs are validated against instances of parts of the Epicentre model, principally diagrams MTG: Grids and Meshes, MTP: Reference Properties and CS1: Coordinate Systems. For each value there will be either one geometry frame or one property frame. These are control structures for a collection of multi-dimensional arrays.
A sparse representation holds a value of each property for identified occurrences of an element or a pair of elements on a grid or mesh. The representation has leaf frames to hold the grid indices to identify the occurrence of the element. Each leaf frame holds a one-dimensional array of values and each value is related to the grid by the stored grid indexes. An element may be a node, an edge, a face, or a cell. A sparse value may alternatively hold values for a pair of edges, faces, or cells. The grid and element are encoded in the frame type.
A geometry frame is a frame that is used to represent, on a coordinate system, the position of nodes on a grid or mesh.
META_TYPE geometry_frame; detailed_type : STRING; descriptor : LIST[1:15] OF UNIQUE descriptor; leaf_frame : SET[1:?] leaf_frame; grid_or_mesh : grid_or_mesh; coordinate_system : coordinate_system; vertex : OPTIONAL vertex; END_META_TYPE;
Where
A property frame is a frame whose content is specified through a property set. Each leaf of a property frame holds values for one of the properties in the set.
META_TYPE property_frame;
detailed_type : STRING;
descriptor : LIST[1:16] OF UNIQUE descriptor;
leaf_frame : SET[1:?] leaf_frame;
grid_or_mesh : OPTIONAL grid_or_mesh;
grid2 : OPTIONAL grid_or_mesh;
WHERE
grid_required_valid : (EXISTS(grid_or_mesh) AND (detailed_type
<> 'FT_SAMPLE')) OR ((NOT EXISTS(grid_or_mesh))
AND (detailed_type = 'FT_SAMPLE');
END_META_TYPE;
Where
The description of each dimension of the frame. This information is set by daeSetValuesOfDimension before calling daeMakeFrameInfoPersistent. Any calls to daeSetValuesOfDimension without calling daeMakeFrameInfoPersistent will affect the data accessed via get/put functions but will not affect the persistent description of the data. Get/put utilities have an increment capability but this only affects the access and not the persistent description of the data. For put, it is assumed that all values (i.e., defined at increment of 1) will have been written before calling daeUpdateLeafStatistics.
META_TYPE descriptor;
dimension : STRING;
lower_bound : INTEGER;
count : INTEGER;
END_META_TYPE;
Where