Analysis Solution

Analysis Modeler

Exporting an Analysis Document in ASCII Format

How to navigate inside an Analysis document in order to export the physical data
Use Case

Abstract

This article discusses the CAAAniExport use case. This use case explains how to manage an Analysis document (create, open or write) and explore its content from the analysis specification modeler view, down to the physical data supported by finite element entities. This covers the meshing entities, pre and post-processing physical data. It is based on a model created by the Structural Analysis application.

What You Will Learn With This Use Case

This use case is intended to help you make your first steps in programming with the CATIA Analysis Modeler. This means, intent is to introduce important concepts about the underlying data structure of the analysis modeler, and ways to navigate inside it. More specifically, you will learn how to:

Before getting to the use case itself, it is important to have an understanding of some of the concepts that are the heart of the Analysis Modeler, since the use case basically navigates among objects that represent those concepts. This is the goal of the next section. You can skip it and get directly to the use case itself if you are already familiar with them.

[Top]

Some Analysis Modeler Important Concepts

Before discussing the use case, some concepts of the Analysis Modeler have to be introduced. These are:

These concepts are the counterpart, on the programming side, of what the end users see and manipulate on the screen. So we will start with the end user view in order to understand what the program manipulates inside.

[Top]

The End User View

This is a typical CATIA V5 work session within the Structural Analysis application. This Analysis document contains a reference to a design document (in this case, a Part document) on which a stress analysis is computed.

The Links Manager role is to keep the link to the referenced design document. It can be a Part for single part analysis, a Product for analysis of design assemblies or other external documents.

The Analysis model is made of some different features. The Analysis Manager is the root feature that allows any other feature to be managed, such as:

  1. The Finite Element Model, dedicated to the discretization (meshing global and local specifications) and idealization (behavior of the part as physical properties). By default it contains a meshing set called "Nodes and Elements", a material set, a property set and an axis set.
  2. Relative to one Finite Element Model, some analysis cases are created in order to group all kinds of external data applied to the idealization. (In this case, Boundaries, Loads and the solution set that will give access to all the physical data that can be computed by the solver.)
  3. The analysis case is defined for a given solver and for a specific computation. (In this case, static linear.) It is made of analysis sets
  4. The analysis sets group some analysis entities, which represent some physical preprocessing actions applied to the design. (For this example, apply a clamp or a momentum to B-rep elements of the part).
  5. In order to have the result visualization, two images are in the tree. One to display the deformed mesh and one for the Stress VonMises Iso display. Associated to the second image, a color table is presented in order to inform about the stress variation on the structure.

The feature tree shows the required analysis specifications that may be used in order to build or scan an Analysis model.

[Top]

Beyond the End User View

The main goal of the analysis specification modeler is to capture as much as possible the user's design intent under the form of specifications, and to derive from it an analysis model supported by finite element entities. This second model is the result view of the specifications. It is called the field model and is managed by specific objects called Analysis Explicit objects.

[Top]

Features

Features embody the know-how necessary to produce an analysis model. Sets are mainly designed in order to structure the model, by grouping entities for consistency: the Nodes and Element set (Meshing set) groups the MESH Part definitions, the load set groups the loading conditions (preprocessing entities) applied on the FEM model. The Entities are made of two kinds of objects: The Component, based on the Knowledge modeler, manages the numerical values of the physical data applied to the Support. As of today the support can be a B-rep element of a part, or an Assembly constraint for connection. Another goal of the feature is to implement all the basic behaviors of CAA V5 applications (Copy/Paste, Update, Delete, Properties, etc.).

Analysis features, as all features, capture essentially the design intent of the end user. During the update step, each feature generates a finite element model that corresponds to this intent. To do this, it relies on an underlying modeler, the Field Data Modeler. This is assumed by implementing the CATISamExplicitation interface. This interface will be called by the CATISamExplicit interface during the feature build. Another relation with the field model is the behavior of these features to extract a finite element view of the data that is defined inside it by implementing the CATICharacCollector interface. This behavior allows a set to get access to physical value data that can be stored in the field model.

For example, a preprocessing set will return a result view of the preprocessing entities. This is done by combining the analysis entity values. A solution set will be designed from a specification point if view as a feature with a link attribute in order to locate the output solver file and will dynamically give to the system the data values.

[Top]

Field Data Modeler

This modeler is designed in order to manage data that can be understandable by all solvers. Inside the field data model, six main kinds of objects are defined by the following classes:

  1. The CATAnalysisExplicitModel and CATAnalysisExplicitRulesData classes support the physical type definition, and the rules for its management. See [1] to list all physical data that can be managed by the Structural Analysis application.
  2. The CATAnalysisExplicitSet class is the image of the Feature sets.
  3. The CATAnalysisExplicitEntity class reflects a physical action applied to finite element support.
  4. The CATAnalysisExplicitCharac class is the physical data that supports the numerical values.
  5. The CATAnalysisCharacCollector class manages the characteristics obtained by combining the information of basic characteristics over several entities.
  6. The CATICharacCollector interface is dedicated to have specific implementations, such as a solver-dependent implementation (Automatic Output Acquisition). This interface has to be implemented for Analysis Feature Sets and Entities. In addition, a default implementation is provided for combining explicit entities and manage preprocessing sets and entities provided by CATIA applications.

[Top]

Explicit Objects as Feature Results

The implementation that is done inside our application will show how the consistency is managed between the two models. All the analysis features implement the CATIAnalysisExplicit interface in order to generate the adequate Field Model. The following image explains the link between the specifications and the result models.

For analysis sets, the CATIAnalysisExplicitation interface generates an explicit set in the field model. This set can be retrieved using the CATISamExplicit interface. It will manage through the CATISpecObject update schema, the update and clean of the field model. The CATAnalysisCharacCollector class that is generated by the CATICharacCollector interface returns the values as they are applied or can combine them. For example, forces applied in local axes by different features can be returned as a single vector in the global model axis system.

For an analysis entity, the CATIAnalysisExplicit interface generates in the field model explicit entities and characteristics, then applies the values of the finite element entities. The CharacCollector that are generated by the CATICharacCollector interface implementation will retrieve the same kind of information by several ways.

This can be done for pre-processing and post-processing sets. Another way to implement this interface can be notified. This way is mainly used for solver results. The feature set has a link to the output file in order to retrieve it from the model and to generate the CATAnalysisCharacCollector class according to the content of the file. Also, this data can be expressed in other positions or versions without being really stored in the field model.

[Top]

The CAAAniExport Use Case

CAAAniExport is a use case of the CAAAnalysisInterfaces.edu framework that illustrates the Analysis infrastructure frameworks capabilities.

[Top]

What Does CAAAniExport Do

From the user view image to:

The goal of analysis export is to open an Analysis document and to navigate inside its data structure that represents the concepts presented in the first part of this article. The different steps are:

[Top]

How to Launch CAAAniExport

To launch CAAAniExport, you will need to set up the build time environment, then compile CAAAniExport along with its prerequisites, set up the run time environment, and then execute the use case [1]. The program will take as first argument the complete pathname of the CATAnalysis document and as second one the complete pathname of the text file to generate.

[Top]

Where to Find the CAAAniExport Code

The CAAAniExport use case is made of classes located in the CAAAniExport.m module of the CAAAnalysisInterfaces.edu framework:

Windows InstallRootDirectory\CAAAnalysisInterfaces.edu\CAAAniExport.m\
Unix InstallRootDirectory/CAAAnalysisInterfaces.edu/CAAAniExport.m/

where InstallRootDirectory is the directory where the CAA CD-ROM is installed.

The following table shows which code resources are used in this Use Case. These resources are physically located within the appropriate directories (with same names) of your CAA installation.

Framework Module/Interface Source Content

CAAAnalysisInterfaces.edu

CAAAniExport.m

main.cpp

Manages the document

  CAAAniExport.m CAAAniExport.cpp Scans the CATAnalysis
  CAAAniExport.m CAAAniSelectPhyscis.cpp Selects some physical data
  CAAAniExport.m CAAAniExportMesh.cpp Accesses Meshing information
  CAAAniExport.m CAAAniDumpByGroup.cpp Generates the file for the selected characteristics. This file contains two methods :CAAAniDumpByGroup and  CAAAniDumpByFEentity

[Top]

Step-by-Step

We will now comment each of those steps by looking at the code. This use case is made of the following steps:

  1. Checking Arguments
  2. Reading the CATAnalysis Document from Disk and preparing it for Export
  3. Getting Access to the Analysis Manager
  4. Getting Access to Meshing Set
  5. Getting Access to Sets
  6. Generating the Output File
  7. Getting the Associated CATCharacCollector
  8. Closing the Session and Exiting

[Top]

Checking Arguments

int main(int iArgc,  // Number of arguments (2)
         char** iArgv)  // Path of an existing *.CATAnalysis document
                        // Path of the exported file.
{
  // Checking arguments
  if(iArgc != 2) return 1;
...

The use case is a main (batch) program that takes two arguments. The first one is the complete path and name of an existing CATAnalysis document. The second is the complete path and name of the file that will be generated by the program.

[Top]

Reading the CATAnalysis Document from Disk and Preparing it for Export

...
  //ObjectModelerBase Framework
  #include "CATSessionServices.h"     // Create, Delete_Session
  #include "CATDocumentServices.h"    // New, Open, Save, Remove Document

  char       *sessionName = "CAA2_Sample_Session";
  CATSession *pSession    = NULL;
  HRESULT rc = ::Create_Session(sessionName, pSession);
  if ((! SUCCEEDED(rc)) || (!pSession))
  {
    cout << "ERROR in creating session" << endl << flush;
    return 1;
  }
  CATDocument *pDoc = NULL;
  rc = CATDocumentServices::Open(argv[1], pDoc);
  if (SUCCEEDED(rc) && pDoc) cout << "Document opened OK" << endl << flush;
  else
  {
    cout << "ERROR in opening an existing document" << endl << flush;
    return 2;
  }
... 

This first step deals with CAA document management and uses standard interfaces of the ObjectModelerBase framework. In brief, a session must be created. This object manages all open documents and therefore should exist prior to the loading of any document. The necessary include files for programming are CATSessionServices and CATDocumentServices.

Then, if a program needs to have an empty CATDocument created in memory instead of an existing document, you can use the following sample that creates a CATDocument with a versatile type that can be parameterized at run time. Here it is parameterized with the type of the document that we want to manipulate, "CATAnalysis".

...
  CATDocument *pDoc = NULL;
  rc = CATDocumentServices::New("CATAnalysis", pDoc);
  if (SUCCEEDED(rc) && pDoc) cout << "Document creation OK" << endl << flush;
  else
  {
    cout << "ERROR in creating an empty document" << endl << flush;
    return 2;
  }
...

[Top]

Getting Access to the Analysis Manager

...
// Extract from document a reference to the Analysis Manager 
CATIContainer *oSpecContainer=NULL;
CATISamAnalysisContainer_var AnalysisContainer = NULL_var ;
CATISamAnalysisManager_var   AnalysisManager = NULL_var ;

CATISamAccess_var SamAccess (pDoc);
if (!SamAccess) return E_FAIL;
hr = SamAccess->GetSpecContainer(oSpecContainer) ;
if (! SUCCEEDED(hr)) return E_FAIL;

AnalysisContainer = oSpecContainer ;
if (! AnalysisContainer) return E_FAIL;
oSpecContainer->Release();

hr = AnalysisContainer->GetAnalysisManager(AnalysisManager);
if (! AnalysisManager) return E_FAIL;

The Analysis Manager is the first feature to retrieve in the document in order to be able to scan the data structure of all the modelisation. From this Manager, you can:

  1. get all analysis models
  2. get one analysis model according to its name
  3. get all the cases of the document
  4. get one Case according to its name or type.
...
// Extract from the document the field model pointer.
CATAnalysisExplicitModel *ExplicitModel = CATAnalysisExplicitModel::GetDocumentModel(pDoc);

// Extract from the document the Rules data manager pointer.
const CATAnalysisExplicitRulesData *aRulesData = NULL;
aRulesData = ExplicitModel->GetRulesData();

if (!aRulesData)  return E_FAIL;
...

With the pointer to the CATAnalysisExplicitRulesData , the string that represents the Physical type definition can be converted into CATSamPhysical type, some information on the model rules definition can be retrieved.

...
// Extract from the Analysis Manager all the Analysis models.
CATLISTV(CATBaseUnknown_var) AnalysisModels;
hr = AnalysisManager->GetAllAnalysisModels(AnalysisModels);
if ( ! SUCCEEDED(hr)) return E_FAIL;


...

[Top]

Getting Access to the Meshing Set

One of the set of the Analysis model has the physical type MESHSET. In order to retrieve this set from the Analysis model, the GetMesh method must be used. The returned value is defined as a CATBaseUnknown pointer. This pointer can be cast as a CATIMSHMeshManager pointer in order to access the container that manages the MSHNodes and MSHElements (by using the GetMesh method), or the associativity pointer, or the meshing specifications (MeshParts). Other solution is to use the CATAnalysisExplicitTopology Object that returns some topology arrays and allows to take into account the MESHPart Activity parameter. 

...
CATBaseUnknown *Base = NULL;
hr = AnalysisModel->GetMesh(Base);
if (!Base) return E_NOINTERFACE;

Base->QueryInterface(CATIMSHMeshManager::ClassId(),(void**)&pMeshManager);
if (!MeshManager) return E_NOINTERFACE;

CATIMSHMesh * mesh = pMeshManager -> GetMesh ();
if (pMeshManager) pMeshManager -> Release(); 

...

Other interfaces, to retrieve the MeshManager:

...
CATIMSHMeshManager *pMeshManager = Exp_Model -> GetMeshManager();
...

[Top]

Getting Access to Sets

The Analysis case and Model have a specific behavior called CATISamAnalysisScan that allows sets to be scanned (all the sets included or a specific one according to its name, type or both).

...
CATISamAnalysisScan_var      hAnalysisScan  =AnalysisModels[1];
CATLISTV(CATBaseUnknown_var) oSetsList = NULL;
hAnalysisScan  = AnalysisScan ->GetAllSets(oSetsList);
...

This function returns a collection of Analysis sets. These sets are designed as features Modeler. They can be cast as CATISpecObject in order to retrieve name, type and standard attributes.

For each set the CAAAniSelectPhysics function will generate some traces in the file. Required inputs are the Set (defined as a CATISamAnalysisSet), and the pointer on the Field Model.

...
CATISamAnalysisSet_var hFeatureSet = oSetsList[1];
CATISpecObject_var SpecObjectSet = oSetsList[1];
CATUnicodeString SetType(SpecObjectSet->GetType());
hr = CAAAniSelectPhysics(File,ExplicitModel,hFeatureSet);
...

The next step consists in generating a trace of the output that can be generated by the sets. The interface used is CATICharacCollector. For all preprocessing sets, a default implementation is provided by the analysis modeler. It is built by combining the Explicit Charac Objects that are created in the Field Model.

[Top]

Generating the Output File

The definition of a CATAnalysisCharacCollector is based on a physical type, and version expressed for a given position. A physical type is the conversion of a string by using the GetPhysicalTypeNumber method of the CATAnalysisExplicitRulesData. The position is a string. The version is build with the following attributes:

CATSamMathType MathType
CATSamValue ValueType
Int MathDimension
CATSamRefFrame RefFrame
CATSamValue Category

Some prefer enumerations show the possible values associated with this attributes. The position none is used for getting values expressed by group, the information at node or element will be reached by using the position NODE or ELEMENT.

...
CATICharacCollector_var Collect = FeatureSet;
hr=Collect->GetAvailablePhysicalTypes(NbPhyTypes,PhyTypes,Units);
if(! NbPhyTypes) {cout << " Empty Set !"<< endl;}
if (! SUCCEEDED(hr)) return E_FAIL;

for (i=0 ; i<NbPhyTypes ; i++)
{
  aRulesData -> GetPhysicalTypeString(PhyTypes[i],oString);
  oNbVersions = 0;
  hr=Collect->GetAvailableVersions(PhyTypes[i],oNbVersions,oVersions);
  if (! SUCCEEDED(hr)) goto error;
  for (j=0 ; j<oNbVersions ; j++)
  {
  oNbPositions = 0;
  hr=Collect->GetAvailablePositions (PhyTypes[i],oVersions[j],oNbPositions,oPositions);
  if (!SUCCEEDED(hr)) goto error;

    for (k=0 ; k<oNbPositions ; k++)
    {
      cout << "Physical Types "<< oString << " Units:" << *Units <<
         " Position : " << (const char *) oPositions[k] << endl;
      cout << " Version "<< endl;
      oVersions[j].Dump();
    }
  }
}

Example:

Physical Types Position Version Return a Collector for
Physical type NONE Type of value: Integer
Mathematical type: Scalar
Mathematical dimension: 1
Reference frame: None
Category: Preprocessor entity
Get the list of entity types from the set (i.e., list of material types for the material set)
User number NONE Type of value: Integer
Mathematical type: Scalar
Mathematical dimension: 1
Reference frame: None
Category: Preprocessor entity
Get the list of the user numbers of the entities from the set (i.e., list of material user numbers for the material set)
Young's modulus NONE Type of value: Real
Mathematical type: Scalar
Mathematical dimension: 1
Reference frame: None
Category: Preprocessor entity
Get the collector of the Young modulus for all the materials
Property set ELEMENT Type of value: Integer
Mathematical type: Scalar
Mathematical dimension: 1
Reference frame: None
Category: Element

Get the group number for element properties.

[Top]

Getting the Associated CATCharacCollector

If the defined physical type, version and position are interesting for the program, call from the CATICharacCollector the GetCharacCollector method.

CATAnalysisCharacCollector *CharacCollector = NULL;
kr = Collect->GetCharacCollector(PhyTypes[i],oPositions[k],oVersions[j],NULL,CharacCollector;
if (! SUCCEEDED(hr)) return E_FAIL;

From this CATAnalysisCharacCollector, the program can access the values defined at a given position and version as:

TheCC -> GetDefinition(PhysicalType,Unit,Version,Position,NumOccurrence);
Model -> GetPhysicalTypeString(PhysicalType, Name);
cout <<"Physical type: " << Name << " Position: "<< *Position << endl ;
cout << "Unit: " << (const char *) *Unit<<"Occurrence Number : " << NumOccurrence << endl ; Version -> Dump();
cout << " Values definition for Entities :" << endl ;
hr = TheCC -> GetNbEntities(NbEntities);
cout << " Number : " << NbEntities << endl ;
Entities = new  char[NbEntities];
if (!Entities) return E_FAIL;
hr = TheCC -> GetEntities(Entities);
if (Entities)
{
  cout << " Flags : " ;
  cout << (int) Entities[0] ;
  for (i = 1 ; (i < NbEntities) ; i++)
    cout << ", " << (int) Entities[i] ;
  cout << endl ;
}
cout << "Dimensions :" << endl ;
hr = TheCC -> GetDimensions(NbDimensions,Dimensions,DimensionPointers);
cout << " Number : " << NbDimensions << endl ;
cout << "Values :" << endl ;
hr = TheCC ->GetValues(NbValues,SizeValues,ValuePointers);
cout << " Number : " << NbValues << endl ;
cout << " Size : " << SizeValues << endl ;
if (NbValues != 0)
{
  cout << " Values : " << endl ;
  if (ValuePointers)
  {
    for (i = 0 ; i < NbEntities ; i++)
    {
      if (DimensionPointers)
        EntDimens = DimensionPointers[i] ;
      else EntDimens = Dimensions ;
      cout << " Entity " << (i + 1) << " : " ;
      if (ValuePointers[i])
      {
        switch (Version->ValueType)
        {
          case CATSamValueCharacter :
            charPtr = (const char *) ValuePointers[i] ;
            cout << charPtr[0] ;
            for (j=1;j<EntDimens->GetNbValues();j++)
              cout<<", <<charPtr[j] ;
            break ;
          case CATSamValueShort :
            shortPtr = (const short *) ValuePointers[i] ;
            cout << shortPtr[0] ;
            for (j=1;j<EntDimens->GetNbValues();j++)
              cout<<", "<<shortPtr[j] ;
              break ;
          case CATSamValueInteger :
            intPtr = (const int *) ValuePointers[i] ;
            cout << intPtr[0] ;
            for (j=1;j<EntDimens->GetNbValues();j++)
              cout<<", "<<intPtr[j] ;
            break ;
          case CATSamValueReal :
            floatPtr = (const float *) ValuePointers[i] ;
            cout << floatPtr[0] ;
            for (j=1;j<EntDimens->GetNbValues();j++)
              cout <<", "<<floatPtr[j] ;
            break ;
          case CATSamValueDouble :
            doublePtr = (const double *) ValuePointers[i] ;
            cout << doublePtr[0] ;
            for (j=1;j<EntDimens->GetNbValues();j++)
              cout <<", "<<doublePtr[j];
            break ;
          case CATSamValuePointer :
          case CATSamValueNode :
          case CATSamValueElement :
          case CATSamValueMaterial :
          case CATSamValueAxis :
          case CATSamValueProperty :
          case CATSamValueRestraint :
          case CATSamValueLoad :
          case CATSamValueMass :
            voidPtr = (const void **) ValuePointers[i] ;
            cout << (unsigned int) voidPtr[0] ;
            for (j=1;j<EntDimens->GetNbValues();j++)
              cout<<", "<<(unsigned int) voidPtr[j] ;
            break ;
          case CATSamValueComplex :
          case CATSamValueComplexDouble :
          default :
             cout << "invalid value type" ;
        }
        cout << endl ;
      }
      else
        cout << "no values" << endl ;
    }
  }
}
 

This is a generic example on how to dump a CATAnalysisCharacCollector. The life cycle of this object is managed by using the AddRef and Release methods. Inside its constructor, the object receive an AddRef and before being deleted, a Release is needed in order to inform that the object is no more referenced.

CAAAniDumpByGroup and CAAAniDumpByFEentity functions show how to extract data associated respectively to a group definition or finite element definition. All of these outputs are piloted by the choice of a physical type, a version and a position. CAAAniDumpByGroup is useful for Material, Local Axis , properties and CAAAniDumpByFEentity will be preferred for Restraints, Load, Solution Sets.

[Top]

Closing the Session and Exiting

...
rc = CATDocumentServices::Remove (*pDoc);
rc = ::Delete_Session(sessionName);
...

In any case, at the end of the program, the document has to be removed from memory, and the session as well.

[Top]


In Short

This use case can be used as an example to scan some different kinds of entities managed inside the Analysis document, or to extract the physical data related to these entities.

[Top]


References

[1] The Physical types for Physical Analysis
[2] Building and Launching a CAA V5 Use Case
[Top]

History

Version: 1 [Apr 2000] Document created
[Top]

Copyright © 2000, Dassault Systèmes. All rights reserved.