Analysis Solution |
Analysis Modeler |
Exporting an Analysis Document in ASCII FormatHow to navigate inside an Analysis document in order to export the physical data |
Use Case |
AbstractThis 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. |
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]
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]
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:
The feature tree shows the required analysis specifications that may be used in order to build or scan an Analysis model.
[Top]
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 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]
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:
[Top]
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]
CAAAniExport is a use case of the CAAAnalysisInterfaces.edu framework that illustrates the Analysis infrastructure frameworks capabilities.
[Top]
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]
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]
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]
We will now comment each of those steps by looking at the code. This use case is made of the following steps:
[Top]
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]
... //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]
... // 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:
... // 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]
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:
CATISamAnalysisEntity::GetFEMModel
or CATISamAnalysisSet::GetFEMModel
to retrieve the
CATISamAnalysisModel and then the CATISamAnalysisModel::GetMesh
will return the manager defined as a CATBaseUnknown pointer as above.
... CATIMSHMeshManager *pMeshManager = Exp_Model -> GetMeshManager(); ... |
[Top]
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]
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]
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]
... 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]
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]
[1] | The Physical types for Physical Analysis |
[2] | Building and Launching a CAA V5 Use Case |
[Top] |
Version: 1 [Apr 2000] | Document created |
[Top] |
Copyright © 2000, Dassault Systèmes. All rights reserved.