Trellis Logo Software Framework for Geometry Based Numerical
			Mechanics       
 www.scorec.rpi.edu/Trellis  

Home
SCOREC
 
About Trellis
Documentation
Code Documentation
Projects/Papers
 
Downloads
Support
 
SCOREC Publications
AOMD

Attribute System
In addition to geometry, the definition of a simulation problem requires other information that describes material properties, loads and boundary conditions. This information, to be referred to as attributes, is tensor valued, has general variations and dependencies, and must be associated with the definition of the domain. Although current CAD and CAE systems support some specification of attributes, they do not provide the full set of capabilities needed to effectively support simulation during the design process. Starting from requirements an initial attribute specification capability has been developed and implemented into Trellis.
In general attribute information can be classified into three main groups:
  • physical parameters for the analysis problem specification,
  • numerical discretization control information, and
  • mathematical and numerical methods used in analyzing the problem.
The physical parameters are directly associated with geometric entities. This information is associated to the numerical analysis discretization using the links from those entities to the geometric model. Using a geometry-based attribute specification is needed to support the use of adaptively defined discretization.

The numerical discretization control information provides a means to control the discretization parameters, such as the size of the discretization entities. The possibility to apply these type of attributes to the model as well as to individual model entities provides easy global and local discretization control.

Mathematical and numerical methods such as the type of nonlinear solver used and the type of time integrator, belong to the last class of information needed to specify a numerical analysis.

The attribute information is stored in an Attribute Manager. The Attribute Manager acts as a container for attributes associated with a model entity of a given model. The association between an attribute and a model entity is based on a key consisting of the model entity tag, the model entity dimension (vertex, edge, face or region), the model name and the attribute name. It's main functionality is to allow the insertion of attributes and later on provide iterators over attributes associated with certain model entities so that the corresponding actions can be performed.

Attributes can be grouped together into groups and cases. Groups are used to group attributes together, e.g. the parameters of a material law could be grouped together so that later on an iterator can be retrieved that iterates over all the attributes (material parameters) belonging to the gourp. A case is a special group refering to a set of attributes that have a meaning as a whole with respect to the specification of a simulation. For example, all the attributes describing the numerical solution procedure for a specific problem would be called a case.

The implementation of the attribute structures as well as the modules it interacts with (expression system, unit system) has been developed in C++. It is a template library allowing to use any build in type and any user defined class as an attribute to be associated with a model entity.

The attribute system makes use of the expression system to provide support for spatial and time dependent variations of attributes. The expression system acts as a parser and lexicographical analyzer to convert strings into expressions that can be numerically evaluated. The expression system understands general algebraic expressions, several common mathematical functions (sine, cosine, logarithm etc.), well known mathematical constants, and simple control structures (if, else). Reserved key words are introduced to consider the time and spatial orientation as parameters for an attribute.


The following example demonstrates how an attribute consisting of a user defined class together with a unit can be associated with a model entity.

    // This is a simple test class that we want to use as an attribute
    class myclass{
    public:
    myclass &operator*=(double a);
    double a[2][2];
    };

    // Since we want to use a unit with the class we
    // need to provide a way to multiply the class with a
    // double. That will allow to convert between different
    // unit prefixes.
    myclass &myclass::operator*=(double d)
    {
      a[0][0]*=d; a[0][1]*=d; a[1][0]*=d; a[1][1]*=d;
      return *this;
    }

    int main(int argc, char* argv[])
    {
      // We get an instance of the attribute manager as follows:
      AttributeManager *AttMngr = AttributeManager::Instance();

      // We want to create an attribute of our own type and associate it
      // with an model entity.

      // this typedef will be handy
      typedef Attribute<UnitVariable<myclass>,DoubleValuedToFromFile> myclassAtt;

      // Let's create a new object of type myclass and feed it with
      // some values
      myclass mm;
      mm.a[0][0] = 1.1; mm.a[1][0] = 1.2; mm.a[0][1] = 1.3; mm.a[1][1] = 1.4;

      // We want to store that object together with the unit
      UnitVariable myvar(mm,SCOREC_UnitSystem::kg(1));

      // Create a name for the attribute and create the attribute
      string AttName("load");
      myclassAtt *att = new myclassAtt(AttName,myvar);

      // add the attribute to the attribute manager
      int tag = 3; // model entity tag where the attribute gets attached
      int dim = 3; // is being attached to a region.
      string modelName("model name");
      AttMngr->insert(tag,dim,modelName,att);

      // Now let's retrieve it. Since there can be more than one attribute
      // with the same name an iterator is provided that allows us to
      // iterate over all the attributes that match the request
      AttributeIterator attIter(tag,dim,modelName,AttName);
      while (!attIter.end())
      {

        typedef AttributeIter<myclassAtt> myclassAttIter;

        const AttributeBase *nn = *attIter;
        // We believe that the attribute we retrieve is of type myclassAtt
        // Let's make sure:
        const myclassAtt *att = dynamic_cast<const myclassAtt *>(nn);
        assert(att);
        // Each attribute can consist of more than one component. Again
        // an iterator provides the ability to get to each of them
        ArgumentList args; // is not being used at this point
        AttributeIter AttIter(att,args);
        AttributeIter::constIter iter = AttIter.begin();
        AttributeIter::constIter iterend = AttIter.end();
        while (iter != iterend)
        {
          UnitVariable unv = *iter;
          assert(unv.getValue().a[0][0] = 1.1)
          assert(unv.getValue().a[1][0] != 1.2)
          ++iter;
        }
        ++attIter;
      }
      return 0;
    }
 

Andrew Bauer