Supporting Inclusion Item Blocks in Attribute XML Files

Dealing with Attribute Definitions with “Similar” Structure

SMTK’s current Attribute Resource supports the idea of inheritance between Attribute Definitions. This provides the following capabilities:

  • Modeling an “isA” relationship between Definitions
  • Ability to “share” common item definitions between 2 related Attribute Definitions.

Lets assume we have the following:

  • Definition A
    • Has category CFD
    • Has Item Definition Ia
  • Definition B
    • Derived from A
    • Has category Heat Transfer
    • Has Item Definition Ib

If I create an Attribute b from Definition B I would get the following:

  • Item Ia belonging to category CFD
  • Item 1b belonging to category CFD or Heat Transfer

One shortcoming of this approach

As you can see the Item Definitions inherited by B are not effected by B’s categories. This category isolation was intentional to prevent derived Definitions changing the information classification of the Base Definition. In the example above, it is not desirable for the categories of Ia to be dependent on the Definitions using it. I’m not saying there are no use cases where you would want this behavior, its just not currently supported.

What if instead of an “isA” relationship, you wanted to model a “hasA” relationship. In this case there is no “base” Attribute Definition being used to derive the Attribute Definition.

Item Defintion Blocks

Instead of using Definition Inheritance, this approach would “instance” a block of Item Definitions into an Attribute or Item Definition.

The main goal of this approach is to reduce the need of explicitly copying Item Definitions within the XML file. Therefore the SMTK Attribute Resource would not need to know about them.

Assumptions

  • Item Definitions in the Block are added atomically (meaning the order of the Item Definitions in the block can not be changed
  • Blocks are only known at File Scope. This implementation would not support having Blocks defined in one SBT file and used in another.
  • Item Definitions in the Block can not be “modified” when they are instanced in the target Definition. For example, you could not change the name of the instanced Item Definition. However, categories inheritance from the target Definition would occur.

Possible Format

<ItemBlocks>
  <Block Name="B1">
      <ItemDefinitions>
        <String Name="s1">
          <Categories>
            <Cat>Solid Mechanics</Cat>
          </Categories>
        <Int Name="i1"/>
      </ItemDefinitions>
  </Block>
</ItemBlocks>
<Definitions>
  <AttDef Type="Type1">
    <Categories>
      <Cat>Fluid Flow</Cat>
    </Categories>
    <ItemDefinitions>
      <Double Name="foo"/>
      <Block Name="B1/>
      <String Name="bar"/>
    </AttDef>
  <AttDef Type="Type2">
    <Categories>
      <Cat>Heat Transfer</Cat>
    </Categories>
    <ItemDefinitions>
      <Block Name="B1/>
      <String Name="str2"/>
    </AttDef>
</Definitions>

In the created Attribute Resource we would have the following:

  • Definition Type 1 (Solid Mechanics or Fluid Flow)
    • Items
      • foo (Fluid Flow)
      • s1 (Solid Mechanics or Fluid Flow)
      • i1 (Fluid Flow)
      • bar (Fluid Flow)
  • Definition Type 2 (Solid Mechanics or Heat Transfer)
    • Items
      • s1 (Solid Mechanics or Heat Transfer)
      • i1 (Heat Transfer)
      • str2 (Heat Transfer)

Note Since the item names can not be changed at this stage. You can not include the same block in both a Definition and in a Definition derived from it since this would cause a name collision.

@chart3388 @amuhsin @johnt FYI - Corey you may want to make sure Aaron sees this.

2 Likes

Reusing chunks of SMTK templates would be very useful.

For the ResonantHPC project we used the XInclude mechanism to do this in an analogous way. If this proposal is to only support step & repeat, we might want to consider XInclude as an alternative to custom syntax. Having said that:

  • The xml parser used in SMTK (pugi) doesn’t natively support XInclude, so we would have to add some logic – albeit not much – to our attribute reader code. (For ResHPC we added a preprocessing script instead of modifying the SMTK code).
  • With XInclude, the reusable chunks are xml files instead of element blocks, so you could potentially end up with alot of tiny files each with a small xml fragment. FWIW that wasn’t the case for ResHPC, which has a pretty rich feature set and ony 6 xml files reused this way.

For ACE3P and Truchas, I don’t foresee switching from my use of pug templates, where I use its “mixin” feature (template with arguments), variable interpolation (string and arithmetic), and conditional logic. I also us Pug because it is less verbose. For Truchas functions, e.g., I have a 200-line .pug file that renders to over 1000 lines of xml.

Could you show an example of a pug template you are using?

Some snippets from truchas-extensions

1. Minimal Pug mixin to step and repeat categories list

mixin categories-all
  Categories
    Cat Fluid Flow
    Cat Heat Transfer
    Cat Solid Mechanics

doctype xml
SMTK_AttributeResource(Version="4")
  +categories-all

2. Pug mixin with integer argument/logic

mixin fnDiscreteInfo(nivars=0)
  //- DiscreteInfo section common to all functions
  DiscreteInfo
    Structure
      Value(Enum="Polynomial") polynomial
      Items
        Item center
        Item polynomial-terms
    Structure
      Value(Enum="Tabular") tabular
      Items
        Item interpolation
        Item extrapolation
        if nivars > 0
          Item independent-variable
        Item tabular-data

3. Pug mixin with stringlist arguments and nested mixins


mixin fn1(tabLabels, polyLabels)
  //- Omitting mulitple-line comments because discourse not rendering them correctly
  ItemDefinitions
    String(Name="type" Label="Function Type" Version="0")
      ChildrenDefinitions
        //- Tabular items
        +tabCommon
        Group(Name="tabular-data" Label=tabLabels[0] Extensible="true" NumberOfRequiredGroups="2")
          ItemDefinitions
            Double(Name="X" Label=tabLabels[1] NumberOfRequiredValues="1")
            Double(Name="Value" Label=tabLabels[2] NumberOfRequiredValues="1")
        //- Polynomical items
        Double(Name="center" Label=polyLabels[0])
          DefaultValue 0
        Group(Name="polynomial-terms" Label=polyLabels[1] Extensible="true" NumberOfRequiredGroups="1")
          ItemDefinitions
            Double(Name="X" Label=polyLabels[2] NumberOfRequiredValues="1")
            Int(Name="Value" Label=polyLabels[3] NumberOfRequiredValues="1")
      +fnDiscreteInfo