Analysis Solution |
Analysis Modeler |
Creating Analysis Features - Part3Implement physics behavior |
Use Case |
AbstractThis paper accompanies the CAAAniNewfeatureOverview technical article. This tutorial explains how to instantiate the Aero-dynamicSet Feature's StartUp inside an Analysis Document and implement all required interfaces in order to integrate it inside analysis Infrastructure. This tutorial will focus on the implementation of the interface that allow to access to the physics associated to the aero dynamic solver file and the way to display an image. |
This use case is intended to help you create an Aero-Dynamic Set Feature that will be fully integrated inside Analysis Infrastructure. For this, we will see the implementation of CATISamExplicitation and CATICharacCollector interfaces.
The analysis Spec/Result approach generate inside the field model concrete classes and the feature have to manage the life cycle of these objects.
The AeroDynamic Set is created by derivation of the feature type SolutionSet. Il will use an implementation of CATISamExplicitation Method where you can insert your applicative software. This method generate inside the field model an Explicit Set that can be retrieved by using on the CATISamExplicit Interface the GetExplicitObject Method, and used to connect the physical data access by managing the CATAnalysisCharacCollector's. These Object are controlled by implementing a specific interface CATICharacCollector.
This use case focuses on the interfaces to implement on the feature. For programming with CATAnalysisCharacCollector object, see in the reference [2] the Field Model Chapter.
CAAAniAeroDTransition is a use case of the CAAAnalysisInterfaces.edu framework that illustrates the CATIA Analysis infrastructure frameworks capabilities.
The goal of this use case is to implement the access to the physics associated to the set. One this will be done, we can display the velocity vector by using an image. For this, copy the file called SPMUserImageDefinition in the "reffiles" directory:
This file is the definition of some images based on the velocity physical type. For example, some iso-surface of the velocity display on the finite elements:
To launch CAAAniAeroDTransition, you will need to set up the build time environment, then compile CAAAniAeroDTransition along with its prerequisites, set up the run time environment, and then execute the use case [1].
[Top]
The CAAAniAeroDTransition use case is made of classes located in the CAAAniAeroDTransition.m module of the CAAAnalysisInterfaces.edu framework:
Windows |
InstallRootDirectory\CAAAnalysisInterfaces.edu\CAAAniAeroDTransition.m\ |
Unix |
InstallRootDirectory/CAAAnalysisInterfaces.edu/CAAAniAeroDTransition.m/ |
where InstallRootDirectory
is the directory where the CAA
CD-ROM is installed.
It is made of two files CAAAniAeroDCharacCollector.cpp and CAAAniExplicitAeroSet.cpp and their associated header files. The module generated is a shared library.
Implement a characcollector needs to perform the following steps:
... CATImplementClass( CAAAniADCharacCollector,DataExtension,CATECharacCollector,AeroDynamicSet); // Tie the implementation to its interface // --------------------------------------- #include "TIE_CATICharacCollector.h" TIE_CATICharacCollector( CAAAniADCharacCollector); //----------------------------------------------------------------------------- // Implements CATICharacCollector::GetAvailablePhysicalTypes //----------------------------------------------------------------------------- HRESULT CAAAniADCharacCollector::GetAvailablePhysicalTypes (int &oNumber, const CATSamPhysicalType *&oPhysicalTypes, const CATString *&oUnits) { ... } ... |
Associated to this setup of code must be defined inside the Object Modeler
Dictionary. See CAAAnalysisInterfaces.edu.dico file defined in
CAAAnalysisInterfaces.edu\CNEXT\code\dictionary. This definition line
associates the AeroDynamicSet implementation of
CATICharacCollector
interface inside the shared library
libCAAAniAeroDTransition. The same remark can be done for implementing
the CATISamExplicitation method. For the features, this definition is based on the
late type of the feature.
AeroDynamicSet CATICharacCollector libCAAAniAeroDTransition AeroDynamicSet CATISamExplicitation libCAAAniAeroDTransition |
We will see all the methods that need to be implemented. Note that the implementation is using a default Adapter CATECharacCollector that provides default implementation of methods to manage life cycle of the CATAnalysisCharacCollector. Some data members are added on this interface and one method Init that will initialize the output for this implementation.
HRESULT Init(); CATAnalysisExplicitModel *Model ; CATAnalysisExplicitSet _Context ; CATSamPhysicalType * _PhysicalTypes ; CATString * _Units, *_Positions ; CATSamCharacVersion *_Versions ; int _NbPhysicalType; ... |
As seen before, there is one physical data included in the file, a velocity.
this physical data is associated by the physical type called "TRANSLATIONAL_VELOCITY
".
This data is a 3D vector of floats expressed at the nodes of the mesh. This
will defined the version and the Position. The Field model set
created by the feature is retrieved by using the CATISamExplicit. This set is
considererd as a context for the creation of the CATAnalysisCharacCollector.
... _NbPhysicalType = 0 ; // Initialize the Context with the Explicit Object associated. CATISamExplicit* piExplicit=NULL; hr = QueryInterface(IID_CATISamExplicit,(void**)&piExplicit); if (piExplicit == NULL) return E_NOINTERFACE ; hr= piExplicit->GetExplicitObject(_Context); piExplicit-> Release(); piExplicit=NULL; if (! SUCCEEDED(hr)) return E_FAIL ; // Get a protection if the set is not yet in the field model. if (_Context == NULL_exp) return hr; // retrieve the Explcit Model _Model = _Context.GetModel(); ... |
CATSamPhysicalType PhysType; const CATAnalysisExplicitRulesData *pRulesData = NULL; pRulesData = _Model->GetRulesData(); if (NULL == pRulesData) return E_FAIL ; hr = pRulesData-> GetPhysicalTypeNumber("TRANSLATIONAL_VELOCITY",PhysType); if (! SUCCEEDED(hr)) return E_FAIL ; _PhysicalTypes = new CATSamPhysicalType[1]; _Units = new CATString[1]; _Versions = new CATSamCharacVersion[1]; _Positions = new CATString[1]; _PhysicalTypes[0] = PhysType; _Units[0] = " "; CATSamMathType oMathematicalType; CATSamValue oValueType; int oMathematicalDimension,oRepeat ; //Retreive the version information inside the definition of the physical type. hr = aRulesData-> GetPhysicalTypeMathematicalInfo(PhysType, oMathematicalType, oValueType, oMathematicalDimension, oRepeat); _Versions[0].ValueType = oValueType ; _Versions[0].MathType = oMathematicalType ; _Versions[0].MathDimension = oMathematicalDimension ; _Versions[0].RefFrame = CATSamRefFrameNone ; _Versions[0].Category = CATSamValueNode ; _Positions[0] = "NODE" ; _NbPhysicalType = 1; ... |
Now we will see how to implement the required method. The data accessibility will be controlled by calling the Init method and the following method just have to returned the data members.
... HRESULT CAAAniADCharacCollector::GetAvailablePhysicalTypes (int & oNumber, const CATSamPhysicalType* & oPhysicalTypes, const CATString* & oUnits) { oNumber = 0; if (!SUCCEEDED(Init())) return E_FAIL ; oNumber = _NbPhysicalType; if (_NbPhysicalType) oPhysicalTypes = _PhysicalTypes; if (_NbPhysicalType) oUnits = _Units; return S_OK; } ... |
Now we will see how to implement the required method. The data accessibility will be controlled by calling the Init method and the following method just have to returned the data members.
... HRESULT CAAAniADCharacCollector::GetAvailableVersions (const CATSamPhysicalType iPhysicalType, int & oNumber, const CATSamCharacVersion* & oVersions) { oNumber = 0; if (!SUCCEEDED(Init())) return E_FAIL ; oNumber = _NbPhysicalType ; if (_NbPhysicalType) oVersions = _Versions; return S_OK; } ... |
Now we will see how to implement the required method. The data accessibility will be controled by calling the Init method and the following method just have to returned the data members.
... HRESULT CAAAniADCharacCollector::GetAvailablePositions (const CATSamPhysicalType iPhysicalType, const CATSamCharacVersion & iVersion, int & oNumber, const CATString* & oPositions) { oNumber = 0; if (!SUCCEEDED(Init())) return E_FAIL ; oNumber = _NbPhysicalType ; if (_NbPhysicalType) oPositions = _Positions; return S_OK; } ... |
This kind of solution may not support occurrences (Variable data according to a parameter). For this the GetNumberOfOccurrences Method will returned ZERO, and the Get and Set Current occurrences method will have no particular interest. But they have to be implemented.
The convention about the Number Of Occurrences and the index of the Current Occurrence is :
GetNumberOfOccurrences | GetCurrentOccurrence | |
Single Occurrence | 0 | -1 |
Multi Occurrence | N (N > 0) | [0,n-1] -1 if the Characteristics are not linked to any particular Occurrences or to all of them. |
... //============================================================================= HRESULT CAAAniADCharacCollector::GetNumberOfOccurrences (int & oNumberOfOccurrences) { oNumberOfOccurrences = 0; return S_OK; } //============================================================================= HRESULT CAAAniADCharacCollector::GetCurrentOccurrence (int & oOccurrenceNumber) { oOccurrenceNumber = -1; return S_OK; } //============================================================================= HRESULT CAAAniADCharacCollector::SetCurrentOccurrence (const int iOccurrenceNumber) { if (iOccurrenceNumber == -1) return S_OK; else return E_FAIL; } ... |
The path name of the file is stored on the analysis set in an attribute as defined in the CATfct file. The attribute is called ExternalFile. To get access to the file use the standard PPR modeler tools:
...
CATUnicodeString Path;
CATISpecAttrAccess *piAccess = NULL;
QueryInterface(IID_CATISpecAttrAccess,(void **)&piAccess);
if (NULL != Access)
{
CATILinkableObject *piLink = piAccess ->
GetExternalObject("ExternalFile");
if (Link)
{
CATDocument * pDoc = piLink -> GetDocument ();
if (NULL != pDoc) CATSamDocumentTools::GetFileStorage(pDoc,Path);
piLink -> Release();
}
piAccess -> Release(); piAccess = NULL;
}
|
Once the Path value is set; you can manipulate the file as usually, for example Open it:
... FILE * stream = fopen (Path.ConvertToChar(),"r"); ... |
This is the most important method. Its goal it to returned the CATAnalysisCharacCollector Object that will manage the results access. The first step is to control if this object exists. For this use the FindCharacCollector method on the Field model context. If the Collector exists, Increase its Life Counter with an AddRef and return it.
... _Context.FindCharacCollector(iPhysicalType, iVersion, iPosition, _CurrentOccurence, CharacCollector) ; if (CharacCollector) { CharacCollector -> AddRef(); oCharacCollector = CharacCollector; return S_OK; } ... |
If It does not exists, allocate a new one and fill its data. For this a sequence of method to call well defined.
... CharacCollector = new CATAnalysisCharacCollector; CharacCollector -> SetContext(_Context,TRUE); _Model->GetPhysicalTypeUnit(iPhysicalType, CharUnit) ; CharacCollector->SetDefinition(iPhysicalType, CharUnit, iVersion, iPosition, _CurrentOccurence); _Model -> GetNbNodes(_Context,NbEntities); CharacCollector->SetNbEntities(NbEntities) ; if (iEntityFlags == NULL) { EntityFlags = new char[NbEntities] ; // array of EntityFlags memset(EntityFlags, 1, NbEntities) ; // set them all == 1 CharacCollector->SetEntities(EntityFlags) ; // A pointer to the table of flag of the entities. } else CharacCollector->SetEntities(iEntityFlags); int nbRepeat[1]={1}; Dimensions = new CATSamDimension (1, 1, 1, nbRepeat, CATSamValueReal, CATSamMathTypeVector, 3) ; CharacCollector -> SetDimensions(1, Dimensions, DimensionPointers) ; delete Dimensions ; float *Fvalues; Fvalues = new float [3*NbEntities]; Values = _Fvalues; for( i=0;i<3*NbEntities;i++) { _Fvalues[i]=(float)(i); } CharacCollector -> SetValues(3*NbEntities,3*sizeof(float)*NbEntities,Values, ValuePointers) ; delete [] _Fvalues; CharacCollector -> AddRef(); oCharacCollector = CharacCollector; ... |
This is done in the CAAAniExplicitAeroSet.cpp file. This is the minimum implementation that is required to manage the Life Cycle of the explicit model object associated to this set.The intent is to create a new version of the field model object, and to ask to the system to remove the previous one (and all associated characCollectors). The system will also manage the undo/redo.
... CATBeginImplementClass(CAAAniExplicitAeroSet,CacheExtension,CATISamExplicitation,STRUCTURAL_AeroDynamicSet); CATEndImplementClass(CAAAniExplicitAeroSet); CATImplementBOA (CATISamExplicitation, CAAAniExplicitAeroSet); //----------------------------------------------------------------------------- // Implements CATISamExplicitation::TranslateToFieldModel //----------------------------------------------------------------------------- HRESULT CAAAniExplicitAeroSet::TranslateToFieldModel(CATISpecObject* iFeatToTranslate, CATISamAnalysisModel* iFEMModel, CATAnalysisExplicitListUsr& iOldExplObjects, CATAnalysisExplicitListUsr& oNewExplObjects) { HRESULT HR = S_OK ; CATISamExplicit *piExplicit = NULL ; CATAnalysisExplicitChild Child; CATAnalysisExplicitSet OldSet, NewSet ; CATAnalysisExplicitList Children ; CATAnalysisExplicitListUsr ContainingData ; CATAnalysisExplicitModel *ExplicitModel = NULL ; CATSamPhysicalType PhysicalType; CATISamAnalysisSet_var spSet(iFeatToTranslate); if(!iFeatToTranslate) goto error; // Retrieve CATISamExplicit interface for GetContainingData and UpdateExplicitList methods //----------------------------------------------------------------------------- iFeatToTranslate -> QueryInterface (IID_CATISamExplicit,(void**)& piExplicit); if (piExplicit == NULL) goto error; // Retrieve physcal type of the previous version OldSet = *(iOldExplObjects.First()) ; if (OldSet == NULL_exp) goto error; ExplicitModel = OldSet.GetModel(); if (ExplicitModel == NULL) goto error; OldSet.GetPhysicalType(PhysicalType); if (!SUCCEEDED(ContainingData.CreateList(ExplicitModel))) goto error; if (!SUCCEEDED(piExplicit -> GetContainingData(iOldExplObjects, ContainingData))) goto error; if (!SUCCEEDED(NewSet.CreateSet(ExplicitModel,PhysicalType))) goto error; oNewExplObjects += NewSet; OldSet.GetChildrenList(Children); Child = *(Children.First()); while ( Child != NULL_exp ) { CATSamDataType DataType = Child.GetType(); if (DataType == CATSamDataTypeSet || DataType == CATSamDataTypeEntity) NewSet.AddChild(Child); Child = *(Children.Next()) ; } if (!SUCCEEDED(piExplicit -> UpdateExplicitList(iOldExplObjects, ContainingData, oNewExplObjects))) goto error; piExplicit -> Release(); piExplicit = NULL; if (ContainingData != NULL_exp) ContainingData.Delete() ; cout << "Insert here the applicative software you need for updating the feature "<< endl; return S_OK; error: if (piExplicit) piExplicit -> Release(); piExplicit = NULL; if (ContainingData != NULL_exp) ContainingData.Delete() ; return E_FAIL; } ... |
This tutorial has demonstrated how to integrate the Aero-Dynamic Set Feature's Set into the feature modeler standards and retrieve some physics' for visualization.
[1] | Feature Modeler documentation |
[2] | Analysis Modeler Overview |
[3] | Integrate new Feature inside Analysis. |
[Top] |
Version: 1 [Sep 2005] | Document Reviewed |
[Top] |
Copyright © 2000, Dassault Systèmes. All rights reserved.