CATIA and SIMULIA Scripting and Automation with Python

Jun 9, 2015

Introduction

CATIA is a 3D parametric modelling program that is ubiquitous in large engineering and manufacturing firms. SIMULIA is a finite element simulation package integrated into CATIA that allows for complex and powerful analysis to be performed on exiting models and assemblies with relative ease. This demonstration is two-fold. First, is to give the user an example of how a simple python script can be used to generate a solid model. The second is to use the same scripting capabilities to run a simple FEA simulation. The ideas here can be extrapolated with the assistance of the references found in (References). Computer aided engineering (CAE) requires a solid understanding of computer software, specifically CAD surface and solid modelling systems and FEA analysis. Not required, but highly useful is having the capability to not only read, but write computer code. An excellent language that is compatible in most operating systems, is open-source(free), and has powerful engineering libraries is python. A demonstration of python is given to show how simple tasks in CATIA can be automated to improve analysis consistency and repeatability and save time. CATIA natively uses Visual Basic for Applications (VBA) [ziethen_catia_2013]. However, VBA is limited in functionality, especially when data analysis and plotting are desired. Python is a much more capable engineering language that works with many programs, such as Microsoft Excel, and many other programs to utilize VBA [hammond_python_2000]. Finally, the demonstration here is based on an excellent site [woyand_h.b._mechanical_2015] that has many engineering applications for python.

Walkthrough

The final result will be a model that can be easily edited and simulation results where visualization that allows for a more in-depth analysis of the component.

Stress result of simulation

CATIA Setup

To prepare CATIA for script execution, it is recommended to launch a new instance of CATIA and close any files that are automatically created, as show in .

Start CATIA with no files open

Python Setup

Python is open-source and can be freely downloaded without licensing restrictions. I recommend either Anaconda Python 2.7 or Pyzo. Once the software is installed, retrieve the python script at the end of this post. Now, the python script can be executed via the command line argument:

    python CATIA-and-SIMULIA-Scripting-and-Automation-with-Python.py

Execution and explanation of the Code

The very first operation of python is to import the modules that are used. Then, the python kernal attempts to connect to the CATIA application running in windows

In [1]:
# import python modules
import os
from win32com.client import Dispatch
# Connecting to windows COM 
CATIA = Dispatch('CATIA.Application')
# optional CATIA visibility
CATIA.Visible = True

Next, a Part and Sketch are created in CATIA Part Design workbench

In [1]:
# Create an empty part
partDocument1 = CATIA.Documents.Add("Part")

# Create the point that the plane and sketch reference
Xcoord=100
Ycoord=100
Zcoord=100
NewPoint = CATIA.ActiveDocument.Part.HybridShapeFactory.AddNewPointCoord(Xcoord, Ycoord, Zcoord)
Mainbody = CATIA.ActiveDocument.Part.MainBody
Mainbody.InsertHybridShape(NewPoint)

# Create reference plane for sketch
AxisXY = CATIA.ActiveDocument.Part.OriginElements.PlaneXY
Referenceplane = CATIA.ActiveDocument.Part.CreateReferenceFromObject(AxisXY)
Referencepoint = CATIA.ActiveDocument.Part.CreateReferenceFromObject(NewPoint)
NewPlane = CATIA.ActiveDocument.Part.HybridShapeFactory.AddNewPlaneOffsetPt(Referenceplane, Referencepoint)
Mainbody.InsertHybridShape(NewPlane)

# create sketch
sketches1 = CATIA.ActiveDocument.Part.Bodies.Item("PartBody").Sketches
reference1 = partDocument1.part.OriginElements.PlaneXY
NewSketch = sketches1.Add(reference1)
CATIA.ActiveDocument.Part.InWorkObject = NewSketch

#Drawing the sketch
NewSketch.OpenEdition()
#                                  Start (H,   V)  End(H,V)
NewLine1 = NewSketch.Factory2D.CreateLine(0  , 0  , 0   ,50)
NewLine2 = NewSketch.Factory2D.CreateLine(0  , 50 , 50  ,50)
NewLine3 = NewSketch.Factory2D.CreateLine(50 , 50 , 50  ,55)
NewLine4 = NewSketch.Factory2D.CreateLine(50 , 55 , 150 ,55)
NewLine5 = NewSketch.Factory2D.CreateLine(150, 55 , 150  ,-5)
NewLine6 = NewSketch.Factory2D.CreateLine(50, -5 , 50  ,0)
NewLine7 = NewSketch.Factory2D.CreateLine(50 , -5 , 75  ,-5)
NewLine8 = NewSketch.Factory2D.CreateLine(150 , -5 , 125  ,-5)
NewLine9 = NewSketch.Factory2D.CreateLine(125 , -5 , 125  ,25)
NewLine0 = NewSketch.Factory2D.CreateLine(125 , 25 , 75  ,25)
NewLine11 = NewSketch.Factory2D.CreateLine(75 , 25 , 75  ,-5)
NewLine12 = NewSketch.Factory2D.CreateLine(50 , 0  , 0   ,0)
NewSketch.CloseEdition()

Then, a pad/extrusion operation gives the 2D sketch volume.

In [1]:
# Create a pad from sketch
LengthBlock=50
NewBlock = CATIA.ActiveDocument.Part.ShapeFactory.AddNewPad (NewSketch, LengthBlock)
CATIA.ActiveDocument.Part.Update()

Sketch defining the shape

The material properties are tricky to assign via scripting, but as long as the CATMaterial file location is known, then it is recommended to hard code. During the python script execution, CATIA should show the activity of the script because we have the value CATIA.Visible = True set. When the script completes(~30 seconds), the results can be manipulated as usual in CATIA.

Property Value

Material Steel

Young's modulus 200 GPa

Poisson's ratio 0.266

Yield strength 250 MPa

Element Type Parabolic Tetrahedron-TE10

Element Count 74671

Node Count 113760

Number of D.O.F. 341280 Table 1: Properties of the material simulated and FEA model

In [1]:
# Assign Material
MatManager=CATIA.ActiveDocument.Part.GetItem("CATMatManagerVBExt")
hk=CATIA.ActiveDocument.Part.MainBody
systempath= CATIA.SystemService.Environ("CATDocView")
path= "C:\\Program Files\\Dassault Systemes\\B23\win_b64\\startup\\materials\\Catalog.CATMaterial"
MatDoc=CATIA.Documents.Open(path)
oMaterial=MatDoc.Families.Item("Metal").Materials.Item("Steel")
MatManager.ApplyMaterialOnBody (hk,oMaterial,1)
MatDoc.Close()

Now lets get our hands dirty with the CATIA Generative Structural Analysis (GPS) workbench. This snippet of code will allows to create our mesh from the 3D solid body we just created. The parameters for the FE model must be assigned, and SIMULIA makes meshing very easy. It done automatically and the resultant properties are shown in table

In [1]:
# Activate the Generative Structural Analysis (GPS) Workbench
PartDoc=CATIA.ActiveDocument
CATIA.StartWorkbench ("GPSCfg")
CATIA.ActiveDocument.Analysis.Import(PartDoc)
CATIA.ActiveDocument.Analysis.AnalysisModels.Item(1).RunTransition ("CATGPSStressAnalysis_template")
CATIA.ActiveWindow.ActiveViewer.Reframe ()

The mesh parameters can be adjusted to depending on the desired accuracy of the results and run-time. These default settings will take about 60 seconds to run on an i7 intel processor with 8 GB of RAM.

In [1]:
# Create a Mesh
mesh=CATIA.ActiveDocument.Analysis.AnalysisModels.Item(1).MeshManager.AnalysisMeshParts.Item(1)
mesh.SetGlobalSpecification ("SizeValue", "2.5 mm")
mesh.SetGlobalSpecification ("AbsoluteSag", 2)
mesh.SetGlobalSpecification ("AbsoluteSagValue", "1.0 mm")
mesh.SetGlobalSpecification ("ElementOrder", "Parabolic")
mesh.Update()

The constraints used are a clamp of one side of the body. This constrains all 6 degrees of freedom (dof) for the elements on that face. The load is a distributed force on the inside of the component

In [1]:
# Define Constraints
analysisSet1 = CATIA.ActiveDocument.Analysis.AnalysisModels.Item(1).AnalysisCases.Item(1).AnalysisSets.Item(1, 3)
analysisEntity1 = analysisSet1.AnalysisEntities.Add("SAMClamp")
reference1 = partDocument1.Part.CreateReferenceFromName("Selection_RSur:(Face:(Brp:(Pad.1;0:(Brp:(Sketch.1;12)));None:();Cf11:());Pad.1_ResultOUT;Last;Z0;G4720)")
analysisEntity1.AddSupportFromProduct (partDocument1.Product, reference1)

# Defining the Load
analysisSet2 = CATIA.ActiveDocument.Analysis.AnalysisModels.Item(1).AnalysisCases.Item(1).AnalysisSets.Item(2, 3)
analysisEntity2 = analysisSet2.AnalysisEntities.Add("SAMDistributedForce")
reference2 = partDocument1.Part.CreateReferenceFromName("Selection_RSur:(Face:(Brp:(Pad.1;0:(Brp:(Sketch.1;5)));None:();Cf11:());Pad.1_ResultOUT;Last;Z0;G4720)")
analysisEntity2.AddSupportFromProduct (partDocument1.Product, reference2) #partDocument1 aus "leeres Part erstellen"
basicComponent1 = analysisEntity2.BasicComponents.GetItem("SAMForceAxis.1")
basicComponent1.SetValue ("Values", 0, 0, 0, 1)
basicComponent2 = analysisEntity2.BasicComponents.GetItem("SAMForceVector.1")
basicComponent2.SetDimensions (3, 1, 1)
basicComponent2.SetValue ("Values", 1, 1, 1, 0.0)
basicComponent2.SetValue ("Values", 2, 1, 1, 1500.0)
basicComponent2.SetValue ("Values", 3, 1, 1, 0.0)

To submit this finite element model for computation the following code can be executed

In [1]:
# Perform Calculation
print('Performing Calculaution')
CATIA.ActiveDocument.Analysis.AnalysisModels.Item(1).AnalysisCases.Item(1).Compute()
print('Calculaution Complete')

Once the execution is complete, the CATIA graphical user interface (GUI) can be used to navigate and visualize the data fields generated, such as stress, strain, as well as displacement scalars. However, if raw data is desired, then it is relatively simple to export data to text files, which can be opened with excel, or python! Check out scipy for many more tools for engineering analysis using python

In [1]:
# Export text file with von-mises stress
analysisSet1 = CATIA.ActiveDocument.Analysis.AnalysisModels.Item(1).AnalysisCases.Item(1).AnalysisSets.Item(3, 3)
analysisImage1 = analysisSet1.AnalysisImages.Add("StressVonMises_Iso_Smooth", True, False, False)
Folder = CATIA.FileSystem.GetFolder(os.getcwd())
analysisImage1.ExportDataInGlobalAxis(Folder, "mises", "txt", 0, False)
print("Created stress text file")

Animated stress

Finally, after the computation, the von-mises stress results are shown in figure .

Summary

A method utilizing CATIA CAD, SIMULIA FEA and python programming language is presented as a method for improving modelling and analysis by automating the steps required to acquire simulation results.

References

  1. D. Ziethen. CATIA V5 Macro Programming With Visual Basic Script, McGraw-Hill, 2013, http://www.mhprofessional.com/product.php?isbn=0071800026.

  2. M. Hammond and A. Robinson. Python Programming on Win32, O'Reilly Media, 2000, http://shop.oreilly.com/product/9781565926219.do.

  3. H. Woyand. Mechanical Engineering Informatics, http://mbi-wiki.uni-wuppertal.de/, 2015.

Code

In [1]:
%load CATIA-and-SIMULIA-Scripting-and-Automation-with-Python.py
In [ ]:
"""
Developed by:
Neal Gordon
NobleTek
nealagordon@gmail.com

Requires a CATIA license with the Generative Part Analysis (GPS) to run
"""

# import python modules
import os
from win32com.client import Dispatch

# Connecting to windows COM 
CATIA = Dispatch('CATIA.Application')
# optional CATIA visibility
CATIA.Visible = True

# Create an empty part
partDocument1 = CATIA.Documents.Add("Part")

# Create the point that the plane and sketch reference
Xcoord=100
Ycoord=100
Zcoord=100
NewPoint = CATIA.ActiveDocument.Part.HybridShapeFactory.AddNewPointCoord(Xcoord, Ycoord, Zcoord)
Mainbody = CATIA.ActiveDocument.Part.MainBody
Mainbody.InsertHybridShape(NewPoint)

# Create reference plane for sketch
AxisXY = CATIA.ActiveDocument.Part.OriginElements.PlaneXY
Referenceplane = CATIA.ActiveDocument.Part.CreateReferenceFromObject(AxisXY)
Referencepoint = CATIA.ActiveDocument.Part.CreateReferenceFromObject(NewPoint)
NewPlane = CATIA.ActiveDocument.Part.HybridShapeFactory.AddNewPlaneOffsetPt(Referenceplane, Referencepoint)
Mainbody.InsertHybridShape(NewPlane)

# create sketch
sketches1 = CATIA.ActiveDocument.Part.Bodies.Item("PartBody").Sketches
reference1 = partDocument1.part.OriginElements.PlaneXY
NewSketch = sketches1.Add(reference1)
CATIA.ActiveDocument.Part.InWorkObject = NewSketch

#Drawing the sketch
NewSketch.OpenEdition()
#                                  Start (H,   V)  End(H,V)
NewLine1 = NewSketch.Factory2D.CreateLine(0  , 0  , 0   ,50)
NewLine2 = NewSketch.Factory2D.CreateLine(0  , 50 , 50  ,50)
NewLine3 = NewSketch.Factory2D.CreateLine(50 , 50 , 50  ,55)
NewLine4 = NewSketch.Factory2D.CreateLine(50 , 55 , 150 ,55)
NewLine5 = NewSketch.Factory2D.CreateLine(150, 55 , 150  ,-5)
NewLine6 = NewSketch.Factory2D.CreateLine(50, -5 , 50  ,0)
NewLine7 = NewSketch.Factory2D.CreateLine(50 , -5 , 75  ,-5)
NewLine8 = NewSketch.Factory2D.CreateLine(150 , -5 , 125  ,-5)
NewLine9 = NewSketch.Factory2D.CreateLine(125 , -5 , 125  ,25)
NewLine0 = NewSketch.Factory2D.CreateLine(125 , 25 , 75  ,25)
NewLine11 = NewSketch.Factory2D.CreateLine(75 , 25 , 75  ,-5)
NewLine12 = NewSketch.Factory2D.CreateLine(50 , 0  , 0   ,0)
NewSketch.CloseEdition()

# Create a pad from sketch
LengthBlock=50
NewBlock = CATIA.ActiveDocument.Part.ShapeFactory.AddNewPad (NewSketch, LengthBlock)
CATIA.ActiveDocument.Part.Update()

# Assign Material
MatManager=CATIA.ActiveDocument.Part.GetItem("CATMatManagerVBExt")
hk=CATIA.ActiveDocument.Part.MainBody
systempath= CATIA.SystemService.Environ("CATDocView")
path= "C:\\Program Files\\Dassault Systemes\\B23\win_b64\\startup\\materials\\Catalog.CATMaterial"
MatDoc=CATIA.Documents.Open(path)
oMaterial=MatDoc.Families.Item("Metal").Materials.Item("Steel")
MatManager.ApplyMaterialOnBody (hk,oMaterial,1)
MatDoc.Close()


# Activate the Generative Structural Analysis (GPS) Workbench
PartDoc=CATIA.ActiveDocument
CATIA.StartWorkbench ("GPSCfg")
CATIA.ActiveDocument.Analysis.Import(PartDoc)
CATIA.ActiveDocument.Analysis.AnalysisModels.Item(1).RunTransition ("CATGPSStressAnalysis_template")
CATIA.ActiveWindow.ActiveViewer.Reframe ()

# Create a Mesh
mesh=CATIA.ActiveDocument.Analysis.AnalysisModels.Item(1).MeshManager.AnalysisMeshParts.Item(1)
mesh.SetGlobalSpecification ("SizeValue", "2.5 mm")
mesh.SetGlobalSpecification ("AbsoluteSag", 2)
mesh.SetGlobalSpecification ("AbsoluteSagValue", "1.0 mm")
mesh.SetGlobalSpecification ("ElementOrder", "Parabolic")
mesh.Update()

# Define Constraints
analysisSet1 = CATIA.ActiveDocument.Analysis.AnalysisModels.Item(1).AnalysisCases.Item(1).AnalysisSets.Item(1, 3)
analysisEntity1 = analysisSet1.AnalysisEntities.Add("SAMClamp")
reference1 = partDocument1.Part.CreateReferenceFromName("Selection_RSur:(Face:(Brp:(Pad.1;0:(Brp:(Sketch.1;12)));None:();Cf11:());Pad.1_ResultOUT;Last;Z0;G4720)")
analysisEntity1.AddSupportFromProduct (partDocument1.Product, reference1)

# Defining the Load
analysisSet2 = CATIA.ActiveDocument.Analysis.AnalysisModels.Item(1).AnalysisCases.Item(1).AnalysisSets.Item(2, 3)
analysisEntity2 = analysisSet2.AnalysisEntities.Add("SAMDistributedForce")
reference2 = partDocument1.Part.CreateReferenceFromName("Selection_RSur:(Face:(Brp:(Pad.1;0:(Brp:(Sketch.1;5)));None:();Cf11:());Pad.1_ResultOUT;Last;Z0;G4720)")
analysisEntity2.AddSupportFromProduct (partDocument1.Product, reference2) #partDocument1 aus "leeres Part erstellen"
basicComponent1 = analysisEntity2.BasicComponents.GetItem("SAMForceAxis.1")
basicComponent1.SetValue ("Values", 0, 0, 0, 1)
basicComponent2 = analysisEntity2.BasicComponents.GetItem("SAMForceVector.1")
basicComponent2.SetDimensions (3, 1, 1)
basicComponent2.SetValue ("Values", 1, 1, 1, 1000.0)
basicComponent2.SetValue ("Values", 2, 1, 1, 1000.0)
basicComponent2.SetValue ("Values", 3, 1, 1, 1000.0)

# Perform Calculation
print('Performing Calculaution')
CATIA.ActiveDocument.Analysis.AnalysisModels.Item(1).AnalysisCases.Item(1).Compute()
print('Calculaution Complete')

# Export text file with von-mises stress
analysisSet1 = CATIA.ActiveDocument.Analysis.AnalysisModels.Item(1).AnalysisCases.Item(1).AnalysisSets.Item(3, 3)
analysisImage1 = analysisSet1.AnalysisImages.Add("StressVonMises_Iso_Smooth", True, False, False)
Folder = CATIA.FileSystem.GetFolder(os.getcwd())
analysisImage1.ExportDataInGlobalAxis(Folder, "mises", "txt", 0, False)
print("Created stress text file")

Comments

comments powered by Disqus