정성균 매니저가 작성했던 지난 호의 원고 (ANZINE 74호: PyMechanical을 이용한 Python 환경에서의 밸브 해석) 에서는 PyMechanical을 소개하였는데, 이는 Ansys Mechanical™의 기능을 Python 환경에서 사용할 수 있도록 하는 API이다. 이를 통해 Ansys Mechanical의 GUI를 실행하지 않고도 전처리·해석·후처리가 가능하다. 다만 Engineering Data 기반의 재료 관리나 External Data/External Model과 같이 외부 데이터를 사용해야 할 땐 PyMechanical만으로는 한계가 있다. 이때 PyWorkbench를 활용하면 해당 작업들을 수행할 수 있다. 본 호에서는 PyWorkbench에서 Engineering Data 및 External Data 구성한 뒤 PyMechanical을 연결하여 해석을 수행하는 예시를 소개한다.
API를 사용하기 전에 아래 명령을 터미널에서 실행하여 라이브러리를 설치한다. 첫 번째 줄은 PyWorkbench, 두 번째 줄은 PyMechanical을 설치한다.
pip install ansys-workbench-core pip install ansys-mechanical-core |
설치가 완료되면, 아래 스크립트를 Python 콘솔에서 실행하여 PyWorkbench와 PyMechanical을 현재 세션에서 사용하도록 한다.
from ansys.workbench.core import launch_workbench from ansys.mechanical.core import connect_to_mechanical |
라이브러리를 설치했다면, 아래와 같이 launch_workbench() 함수를 사용하여 Workbench를 실행한다. PyWorkbench는 2024 R2 버전부터 지원되며, version 인자에 원하는 버전 코드를 지정한다(ex. 2024 R2 : version=”242”). 또한, show_gui 인자에 True를 입력하면 GUI 모드로, False를 입력하면 GUI가 없는 배치 모드로 실행된다. 아래 예시는 2025 R1 버전을 GUI로 실행하는 스크립트다.
wb = launch_workbench(version="251", show_gui=True) |
[그림 1] Workbench 실행 모습
Workbench가 실행되면, 이후부터는 run_script_string() 함수를 사용하여 Python에서 Workbench로 명령을 전송한다. 아래 예시는 Engineering Data를 생성하고 General Materials 라이브러리에 포함된 Aluminum Alloy를 추가하는 스크립트다. 먼저 GetTemplate로 Engineering Data 템플릿을 선언하고, CreateSystem으로 Engineering Data 시스템을 생성한다. 이어서 Engineering Data의 추가 설정을 위해 GetContainer로 접근한 뒤, ImportMaterial을 호출해 Aluminum Alloy 재료를 가져온다.
wb.run_script_string('''tempEngData = GetTemplate(TemplateName="EngData") sysEngData = tempEngData.CreateSystem() engineeringDataEngData = sysEngData.GetContainer(ComponentName="Engineering Data") mat1 = engineeringDataEngData.ImportMaterial(Name="Aluminum Alloy", |
[그림 2] Engineering Data 생성
아래 예시는 External Data 시스템을 생성하고 온도 데이터를 불러오는 스크립트다. 이전과 동일하게 GetTemplate로 External Data 템플릿을 선언한 뒤 CreateSystem으로 External Data를 생성하고, 추가 작업을 위해 GetContainer로 접근한다. 이어 AddDataFile로 준비된 외부 데이터의 경로를 지정하고, 그 데이터의 세부 설정을 위해 GetDataProperty 객체를 얻는다. 그런 다음 SetLengthUnit으로 단위계를, SetDelimiterType으로 구분자를 설정한다. 마지막으로 GetDataProperty에서 제공하는 GetColumnData에 접근하여 각 열의 의미(예: 시간, 온도, 좌표 등)를 지정한다.
wb.run_script_string('''tempExtData = GetTemplate(TemplateName="External Data") sysExtData = tempExtData.CreateSystem() setExtData = sysExtData.GetContainer(ComponentName="Setup") extData1 = setExtData.AddDataFile(FilePath="E:/temperature.txt") extData1_Property = extData1.GetDataProperty() extData1_Property.SetLengthUnit(Unit="mm") extData1.SetDelimiterType(FileDataProperty=extData1_Property, Delimiter="Tab", DelimiterString=r"\t") extData1_Col1 = extData1_Property.GetColumnData(Name="ExternalLoadColumnData 1") extData1_Property.SetColumnDataType(ColumnData=extData1_Col1, DataType="X Coordinate") extData1_Col2 = extData1_Property.GetColumnData(Name="ExternalLoadColumnData 2") extData1_Property.SetColumnDataType(ColumnData=extData1_Col2, DataType="Y Coordinate") extData1_Col3 = extData1_Property.GetColumnData(Name="ExternalLoadColumnData 3") extData1_Property.SetColumnDataType(ColumnData=extData1_Col3, DataType="Z Coordinate") extData1_Col4 = extData1_Property.GetColumnData(Name="ExternalLoadColumnData 4") extData1_Property.SetColumnDataType(ColumnData=extData1_Col4, DataType="Temperature") ''') |
[그림 3] External Data 생성
다음 스크립트는 외부 데이터를 맵핑할 형상 파일을 가져오는 예시다. 전 단계와 동일하게 GetTemplate으로 템플릿을 선언하고 CreateSystem으로 시스템을 생성한 뒤, GetContainer로 대상 컨테이너에 접근한다. 마지막으로 SetFile에 형상 파일의 경로를 지정한다.
wb.run_script_string('''tempGeom = GetTemplate(TemplateName="Geometry") sysGeom = tempGeom.CreateSystem() geom1 = sysGeom.GetContainer(ComponentName="Geometry") geom1.SetFile(FilePath="E:/Pump_housing.stp")''') |
[그림 4] Geometry 생성
다음은 정적 구조해석을 위한 Static Structural 시스템을 생성하는 단계다. GetTemplate으로 템플릿을 선언한 뒤 CreateSystem으로 생성하며, 이때 Name 인자를 함께 지정한다. Name 인자의 값은 이후 Workbench와 Mechanical 연동 시 참조할 식별자이므로 기억해 둔다.
wb.run_script_string(''' tempStatic = GetTemplate(TemplateName="Static Structural", Solver="ANSYS") sysStatic = tempStatic.CreateSystem(Name="TSNE")''') |
[그림 5] Static Structural 생성
이제 각 Component System을 Static Structural에 연결한다. 연결은 세 부분으로 나뉜다. 첫째, Engineering Data는 연결하려는 양쪽 셀을 GetComponent로 지정하고 ReplaceWithShare로 데이터를 전송한다. 둘째, Geometry도 마찬가지로 양쪽 셀을 GetComponent로 참조한 후 ReplaceWithShare로 연결한다. 셋째, External Data도 양쪽 셀을 GetComponent로 지정하되, TransferData로 데이터를 전송하고 Update까지 수행한다.
wb.run_script_string(''' engineeringData_sysStatic = sysStatic.GetComponent(Name="Engineering Data") engineeringData_sysEngData = sysEngData.GetComponent(Name="Engineering Data") engineeringData_sysStatic.ReplaceWithShare( TargetSystem=sysStatic, SourceSystem=sysEngData, ComponentToShare=engineeringData_sysEngData)
geometry_sysStatic = sysStatic.GetComponent(Name="Geometry") geometry_sysGeom = sysGeom.GetComponent(Name="Geometry") geometry_sysStatic.ReplaceWithShare( TargetSystem=sysStatic, SourceSystem=sysGeom, ComponentToShare=geometry_sysGeom)''')
setup_sysExtData = sysExtData.GetComponent(Name="Setup") setup_sysStatic = sysStatic.GetComponent(Name="Setup") setup_sysExtData.TransferData(TargetComponent=setup_sysStatic) setup_sysExtData.Update(AllDependencies=True) |
[그림 6] 각 시스템 간의 연결
이제 앞서 구성한 Workbench 설정을 기반으로 Mechanical을 실행한다. 단일 Python 세션에서 Workbench와 Mechanical을 연동해야 하므로, 아래와 같이 start_mechanical_server() 함수를 호출한다. 이때 system_name 인자에는 Static Structural을 생성할 때 CreateSystem(Name=…)에 지정한 값을 그대로 입력하고, 실행 결과는 pymech_port 변수에 할당한다.
pymech_port = wb.start_mechanical_server(system_name="TSNE") |
[그림 7] Mechanical 실행 모습
지금까지의 과정으로 Mechanical은 실행되었지만, Python 세션 관점에서 PyWorkbench와 PyMechanical은 아직 독립적이다. 두 서비스를 연결하기 위해 아래와 같이 connect_to_mechanical()을 호출한다. 이때 port 인자에는 앞 단계에서 저장한 pymech_port 값을 전달한다.
mechanical = connect_to_mechanical(port=pymech_port) |
이제부터 run_python_script()를 사용하여 Mechanical로 명령을 전송한다. 먼저 Engineering Data에서 추가한 Aluminum Alloy 재료를 모델에 할당한다.
mechanical.run_python_script('Model.Geometry.Children[0].Material = "Aluminum Alloy"') |
[그림 8] Aluminum Alloy 할당
다음은 전역 격자 크기를 3 mm로 설정한 뒤 Generate Mesh를 수행한다.
mechanical.run_python_script(''' Model.Mesh.ElementSize = Quantity("3 [mm]")') Model.Mesh.GenerateMesh()')''') |
[그림 9] 격자 생성
다음은 외부 데이터를 맵핑하기 위한 Imported Load 작업 스크립트다. PyAnsys와 같이 마우스를 사용하지 않는 환경에서는 경계 조건 정의 시 Selection Manager 또는 Named Selection을 활용하는 것이 일반적이며, 아래 스크립트는 Selection Manager를 이용한 Imported Load 조건 정의 흐름을 보여준다. 먼저 SelectionManager를 생성하고 선택 유형을 형상 관련 Entity로 지정한다. 이어서 대상 형상의 ID를 수집하여 SelectionManager에 할당한다. 그다음 Imported Body Temperature 조건을 추가하고, 앞서 구성한 SelectionManager를 통해 형상을 지정한 뒤 맵핑을 수행한다.
mechanical.run_python_script(''' selMan = ExtAPI.SelectionManager selection = selMan.CreateSelectionInfo(SelectionTypeEnum.GeometryEntities) selection.Ids = [ExtAPI.DataModel.GeoData.Assemblies[0].Parts[0].Bodies[0].Id]
imp_temp = Model.Analyses[0].Children[1].AddImportedBodyTemperature() imp_temp.Location = selection imp_temp.ImportLoad()''') |
[그림 10] Imported Load 작업 수행
이번에는 Named Selection을 이용해 구속 조건을 정의한다. 조건문 기반 정의를 위해 Worksheet에서 작업하며, 아래 스크립트의 조건은 Z축 기준 최하단에 위치한 Face를 선택하도록 설정한다. 이후 Fixed Support를 추가하고, Named Selection 기반으로 구속 조건을 정의한다.
mechanical.run_python_script(''' ns = Model.AddNamedSelection() ns.ScopingMethod = GeometryDefineByType.Worksheet criteria = ns.GenerationCriteria criteria.Add(None) criteria[0].Action = SelectionActionType.Add criteria[0].EntityType = SelectionType.GeoFace criteria[0].Criterion = SelectionCriterionType.LocationZ criteria[0].Operator = SelectionOperatorType.Smallest ns.Generate()
|
[그림 11] Fixed Support 정의
앞서 구성한 설정을 바탕으로 해석을 수행한다.
mechanical.run_python_script('Model.Analyses[0].Solve()') |
[그림 12] 해석 수행
마지막으로, 후처리 단계에서 결과 항목을 추가하고 결과를 검토한다.
mechanical.run_python_script(''' Model.Analyses[0].Solution.AddTotalDeformation() Model.Analyses[0].Solution.AddEquivalentStress() Model.Analyses[0].Solution.EvaluateAllResults()''') |
[그림 13] Equivalent Stress
본 호에서는 PyWorkbench와 PyMechanical을 연계하여 해석을 수행하는 예시를 소개했다. PyWorkbench로 Engineering Data와 External Data를 구성하고, PyMechanical을 통해 전처리·해석·후처리를 수행했다. 기존에 PyMechanical의 한계였던 Workbench 내 데이터 작업은 PyWorkbench의 연계로 보완할 수 있었다. 이번 호에서는 PyWorkbench에 PyMechanical을 연결하는 예시를 다뤘지만, 필요에 따라 PyFluent나 PySherlock과의 연계도 고려할 수 있다. 또한 후처리 과정에서는 PyDPF를 활용할 수 있다. 종합적으로, PyAnsys의 에코시스템은 라이브러리의 통합을 통해 단일 환경에서 처리하기 어려운 업무의 자동화와 확장성을 지원한다.