Skip to content

Entity Attributes

Greg Sjaardema edited this page Jul 7, 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 object in the entity (e.g., not a value per element in an element block), but a value for the entity (e.g. element block). For now, the 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 attribute 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 an attribute at the "root" level.
   ex_put_text_attribute(exoid, EX_GLOBAL, 0, "SOLID_MODEL", "STEP-X-43-1547836-Rev 0");
  • 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.

Still Needed

  • Conventions for passing certain data via entity attributes. For example, material properties or material models or BC specifications