Skip to content

Entity Attributes

Greg Sjaardema edited this page Jul 6, 2020 · 9 revisions

Arbitrary provenance or property data that can be applied to all entities (Blocks, Sets, Attributes, and Blobs) in the form of “key=value” or arbitrary string. The attribute is named and of type String, Integer, or Double. The Integer and Double attributes can have an arbitrary number of values; the String attribute has only a single value.

Define/Query assembly attributes and attribute names

An entity attribute is similar to an IOSS property consisting of a name, a type, and a value or values. It is not a value per entity in the entity, but a value for the entity. For now, they types will be limited to text, integer, and double to provide capability without the complexity of supporting the many types available in NetCDF-4 including user-defined types. Note that an attribute can have multiple values, for example if the attribute is a range, a single attributed could have two double values -- {1.0, 100.0}

NOTE: Need a better name or way of distinguishing from the attributes which are currently supported in Exodus.

  • define and output an attribute
   ex_attribute attribute = {EX_ASSEMBLY, 100, "Offset", EX_DOUBLE, 3, {1.1, 2.2, 3.3}};
   ex_put_attribute(exoid, attribute);
  • define and output multiple attributes
   ex_attribute attributes[10];
   /* ... Initialize `attributes` */
   ex_put_attributes(exoid, 10, attributes);
  • define and output a double attribute
   ex_put_double_attribute(exoid, EX_ASSEMBLY, id, name, num_values, values);
  • define and output an integer attribute
   ex_put_integer_attribute(exoid, EX_ASSEMBLY, id, name, num_values, values);

[The size of the integers used in values is based on int-size of the database]

  • define and output a text attribute....
   ex_put_text_attribute(exoid, EX_ASSEMBLY, id, name, char *values);
  • Query number of attributes on an assembly
   int num_attr = ex_get_attribute_count(exoid, EX_ASSEMBLY, id);
  • Query names, types, size/length, values of all attributes on an assembly
   int num_attr = ex_get_attribute_count(exoid, EX_ASSEMBLY, id);
   ex_attribute attributes[num_attr];
   ex_get_attributes(exoid, EX_ASSEMBLY, id, attributes);
  • Get values of all attributes on the specified entity (ASSEMBLY 100)
   int count = ex_get_attribute_count(exoid, EX_ASSEMBLY, 100)
   ex_attribute attributes[count];
   memset(attributes, 0, sizeof(ex_attribute)*count);
   ex_get_attribute_param(exoid, EX_ASSEMBLY, 100, attributes);
   /* Get attribute values for all attributes listed in `attributes`
      `ex_get_attributes()` will allocate memory for `attributes[i].values` 
      which must be freed by caller.
    */
   ex_get_attributes(exoid, count, attributes);
  • Get value of specific attribute on the specified entity (ASSEMBLY 100)
   int count = ex_get_attribute_count(exoid, EX_ASSEMBLY, 100)
   ex_attribute attributes[count];
   ex_get_attribute_param(exoid, EX_ASSEMBLY, 100, attributes);
   /* ... allocate space on specific attribute to store values. If
    *     not allocated, it will be allocated by `ex_get_attribute()`
    */
   attributes[3].values = calloc(attributes[3].value_count, sizeof(double));
   /* Get attribute values for attribute at index 3 */
   ex_get_attribute(exoid, attributes[3]);

The ex_attribute argument is the struct:

typedef struct ex_attribute
{
  ex_entity_type entity_type,
  int64_t   entity_id,
  char  name[EX_MAX_NAME];
  ex_type type; /* EX_INTEGER, EX_DOUBLE, EX_CHAR */
  size_t   value_count;
  void* values; /* not accessed if NULL */
} ex_attribute;

NOTE: is there benefit to getting all attribute names/types/size in single call, or can we simplify API and just provide the query of individual attribute. Can do this in single call if only fill in non-NULL arguments

IOSS-specific details

  • An entity attribute will appear on an IOSS entity as a Property with an origin of Ioss::Property::ATTRIBUTE
  • A global entity attribute will be a Property on the Ioss::Region
  • An application can query the entity attribute properties of an Ioss::GroupingEntity ge via:
  Ioss::NameList properties;
  ge->property_describe(origin, &properties);

  • The Ioss::NameList is a std::vector<std::string>>
  • Once the application has the list of property names, the values of the properties can be accessed via code similar to:
  for (const auto &property_name : properties) {
    fmt::print("{:>s}: ", property_name);
    auto prop = ge->get_property(property_name);
    switch (prop.get_type()) {
    case Ioss::Property::BasicType::REAL: fmt::print("{}\t", prop.get_real()); break;
    case Ioss::Property::BasicType::INTEGER: fmt::print("{}\t", prop.get_int()); break;
    case Ioss::Property::BasicType::STRING: fmt::print("'{}'\t", prop.get_string()); break;
    case Ioss::Property::BasicType::VEC_INTEGER:
      fmt::print("{}\t", fmt::join(prop.get_vec_int(), "  "));
      break;
    case Ioss::Property::BasicType::VEC_DOUBLE:
      fmt::print("{}\t", fmt::join(prop.get_vec_double(), "  "));
      break;
    default:; // Do nothing
    }
  • On output, all entity properties of type Ioss::Property::ATTRIBUTE will be written to the output exodus database as entity attributes on the specific entity.

[todo]