I am writing an optimisation algorithm in Python which evaluates its objective function by calling a CATIA macro (given to me) to modify a part and perform a finite element analysis on the structure to determine its maximum deflection under a load, and compute the volume of the modified part.
A simplified MWE of a single evaluation is given below:
from pycatia import catia
import numpy as np
import os
import time
MAX_EVAL_TIME = 300
f_part = 'myPart.CATPart'
f_script = 'myAnalysisScript.CATScript'
f_deflect = 'Cube Displacement Values.txt'
caa = catia()
caa.documents.open(f_part)
eval_time_counter = 0
out_of_time = False
try:
os.system(f_script)
while not os.path.exists(f_deflect) and not out_of_time:
time.sleep(1) # wait for output file to be generated
eval_time_counter = eval_time_counter + 1
if eval_time_counter > MAX_EVAL_TIME:
out_of_time = True
closed = False
while not closed:
for w in caa.windows:
if 'Analysis' in str(w):
w.close() # close analysis window so we can access part
closed = True
time.sleep(1)
except Exception as e:
print("ERROR: DIDNT WORK!")
print(e)
if not out_of_time:
deflect_data = np.loadtxt(f_deflect,skiprows=3)
os.remove(f_deflect)
doc = caa.active_document
prod = doc.product
vol = prod.analyze.volume
print(f"volume: {vol}, max deflection: {np.max(deflect_data)}")
else:
print("was not able to complete script in {MAX_EVAL_TIME} seconds.."}
for w in caa.windows:
w.close() # close all windows to prepare for next eval
The CATIA macro reads a .xlsx
file with the dimensions on it, modifies the part to fit those dimensions, performs the analysis and then outputs a .txt
file with the results. My Python script calls the CATIA macro and then waits until the .txt
is generated. At which point the Python script reads the output file and closes the windows in the CATIA application, so it is ready for the next evaluation.
This all works fine when the analysis script completes its execution faster than the allowed time (in this case, 300 seconds), but if the CATIA macro is still running when the Python script reaches the timeout, then none of the close
commands sent will work, and the next evaluation cannot proceed.
Ideally, once the timeout is reached, the optimisation algorithm would kill the analysis, assign an arbitrarily high value to the current design and move on to evaluate the next candidate. Is there a way to use pycatia
to send an interrupt signal to a CATIA macro to get it to stop running? or a way to include a timeout within the macro itself (I have included the macro code below)? or even a way to kill the CATIA process in the OS and relaunch it fresh? (I would rather not go this route as launching CATIA takes a fair while and I don't have direct physical access to the computer I am running this on, in case anything goes pear-shaped and needs to be rebooted)
Any suggestions would be greatly appreciated.
Sub CATMain()
On Error Resume Next
Dim partDocument1 As Document
Set partDocument1 = CATIA.ActiveDocument
Dim part1 As Part
Set part1 = partDocument1.Part
part1.Update
Dim documents1 As Documents
Set documents1 = CATIA.Documents
Dim analysisDocument1 As Document
Set analysisDocument1 = documents1.Open("D:\code\lattice_structures\Lattice\Cube Lattice Analysis.CATAnalysis")
Dim analysisManager1 As AnalysisManager
Set analysisManager1 = analysisDocument1.Analysis
Dim analysisModels1 As AnalysisModels
Set analysisModels1 = analysisManager1.AnalysisModels
Dim analysisModel1 As AnalysisModel
Set analysisModel1 = analysisModels1.Item(1)
Dim analysisCases1 As AnalysisCases
Set analysisCases1 = analysisModel1.AnalysisCases
Dim analysisCase1 As AnalysisCase
Set analysisCase1 = analysisCases1.Item(1)
analysisCase1.Compute
Dim analysisSets1 As AnalysisSets
Set analysisSets1 = analysisCase1.AnalysisSets
Dim analysisSet1 As AnalysisSet
Set analysisSet1 = analysisSets1.Item("Static Case Solution.1", catAnalysisSetSearchAll)
Dim analysisImages1 As AnalysisImages
Set analysisImages1 = analysisSet1.AnalysisImages
Dim analysisImage1 As AnalysisImage
Set analysisImage1 = analysisImages1.Add("Disp_Symbol", True, False, False)
Dim fileSystem1 As FileSystem
Set fileSystem1 = CATIA.FileSystem
Dim folder1 As Folder
Set folder1 = fileSystem1.GetFolder("D:\code\lattice_structures\Lattice")
analysisImage1.ExportDataInGlobalAxis folder1, "Cube Displacement Values", "txt", catSamCoordinateSystem_Cartesian, False
End Sub