Data ACT Migration
Data ACT Migration
Customization Products
ANSYS ACT Migration for Legacy Workbench Customization Products
ANSYS, ANSYS Workbench, AUTODYN, CFX, FLUENT and any and all ANSYS, Inc. brand, product, service
and feature names, logos and slogans are registered trademarks or trademarks of ANSYS, Inc. or its
subsidiaries located in the United States or other countries. ICEM CFD is a trademark used by ANSYS, Inc.
under license. CFX is a trademark of Sony Corporation in Japan. All other brand, product, service and
feature names or trademarks are the property of their respective owners. FLEXlm and FLEXnet are
trademarks of Flexera Software LLC.
Disclaimer Notice
THIS ANSYS SOFTWARE PRODUCT AND PROGRAM DOCUMENTATION INCLUDE TRADE SECRETS AND ARE
CONFIDENTIAL AND PROPRIETARY PRODUCTS OF ANSYS, INC., ITS SUBSIDIARIES, OR LICENSORS. The
software products and documentation are furnished by ANSYS, Inc., its subsidiaries, or affiliates under a
software license agreement that contains provisions concerning non-disclosure, copying, length and
nature of use, compliance with exporting laws, warranties, disclaimers, limitations of liability, and
remedies, and other provisions. The software products and documentation may be used, disclosed,
transferred, or copied only in accordance with the terms and conditions of that software license
agreement.
ANSYS, Inc. and ANSYS Europe, Ltd. are UL registered ISO 9001: 2008 companies.
For U.S. Government users, except as specifically granted by the ANSYS, Inc. software license
agreement, the use, duplication, or disclosure by the United States Government is subject to restrictions
stated in the ANSYS, Inc. software license agreement and FAR 12.212 (for non-DOD licenses).
Third-Party Software
See the legal information in the product help files for the complete Legal Notice for ANSYS proprietary
software and third-party software. If you are unable to access the Legal Notice, contact ANSYS, Inc.
ii
ANSYS ACT Migration for Legacy Workbench Customization Products
Contents
Advisory ........................................................................................................................................................ 1
ANSYS ACT ..................................................................................................................................................... 1
ACT for Workbench .................................................................................................................................. 2
Migration ...................................................................................................................................................... 2
External Connection Add-in .......................................................................................................................... 3
Customizing the Workbench User Interface ............................................................................................ 3
Toolbar Buttons .................................................................................................................................... 4
Context Menu Entries ........................................................................................................................... 6
Menu Entries ....................................................................................................................................... 10
Integrating an External Application ........................................................................................................ 14
Creating Custom Systems and Components .......................................................................................... 22
SDK .............................................................................................................................................................. 30
Add-in Versus Extension ......................................................................................................................... 31
Functionality ........................................................................................................................................... 32
User Interface Customization ............................................................................................................. 32
Data and Action Processing ................................................................................................................ 45
Workflow and Application Integration ............................................................................................... 52
Summary ..................................................................................................................................................... 92
iii
ANSYS ACT Migration for Legacy Workbench Customization Products
Advisory
As of release 19.0, ANSYS has ended support for the Workbench customization products listed below.
Our drive toward a simplified and consistent platform customization vision now delivers the preferred
ANSYS ACT approach for your Workbench customization projects. This document provides transition
guidance.
ANSYS understands the importance of software customization. We debuted ANSYS Workbench 12.0 as
an innovative platform for cohesive simulation workflow management. We placed high priority on
robust Workbench journaling, scripting, and extensibility. Accordingly, early in the Workbench timeline,
we offered a pair of customization tools:
The External Connection Add-in supported lightweight integration of external applications into
the Workbench Project Schematic. You could leverage additional customization opportunities
by defining new user interface elements. Solutions contained plain text XML files and
IronPython scripts. Development and deployment required neither additional licenses nor
specialized tools.
The ANSYS Workbench Software Development Kit (SDK) exposed C#-based APIs used by new
feature development to plug into Workbench’s modular add-in architecture. You could enrich
framework functionality and data-integrate external applications by creating add-ins of your
own. Add-in development required both an additional “ANSYS Customization Suite” license and
Microsoft .NET developer tools.
Please discontinue using customization solutions built with the External Connection Add-in and SDK. We
will neither support new External Connection Add-in development nor ship SDK packages at 19.0.
Existing Workbench projects (WBPJ or WBPZ files) that use External Connection Add-in references will
continue to operate at 19.0. However, we cannot guarantee compatibility beyond 19.0.
The SDK’s compiled nature requires immediate action by content providers. Developers should re-
implement their solutions with ACT extensions as soon as possible to ensure compatibility for 19.0 and
beyond. Users of SDK-based solutions should contact the solution owners or distributors to request new
ACT-based versions.
ANSYS ACT
Application customization can seem complex and time-consuming. That's why we've developed ANSYS
ACT. ACT removes the coding complexity to let you focus on driving your designs. Deliver in days what
would traditionally take weeks or months.
1
ANSYS ACT Migration for Legacy Workbench Customization Products
ACT provides a consistent approach for custom simulation experiences across the ANSYS product line.
Easy-to-use app creation tools and a global deployment strategy offer you the most robust and
straightforward ANSYS ecosystem opportunity to date.
Not an expert programmer? Don’t worry. ACT uses simple, plain-text file formats. XML describes your
customization. IronPython brings it to life. Additional ACT tools—App Builder, Debugger, and Console—
guide you through the app creation process.
Make our Workbench environment your own with ANSYS ACT. Inject your simulation requirements in a
platform where your own engineering tools coexist with the industry's broadest suite of advanced
engineering simulation technology.
Accomplish the opportunities offered by the legacy External Connection Add-in and SDK with improved
ease and rapid delivery. Uncover new customization possibilities with expanded access beyond legacy
capabilities.
Migration
The Workbench External Connection Add-in and SDK end-of-life requires you to migrate your
customization solutions to ANSYS ACT.
Before you review our migration guidance, please familiarize yourself with ACT philosophy, terms, and
usage—especially if you are new to ACT customization. We provide the following educational guides:
• ANSYS ACT Developer’s Guide—This guide offers an introduction to ACT, describing its
capabilities and how to use them. While primarily intended for developers of ACT apps, it also
provides information for end users who manage and execute apps.
• ANSYS ACT Customization Guide for Workbench—This guide offers information for using ACT to
customize Workbench.
The nature of customization and providing general application hooks offers almost unlimited
opportunity and creative solutions. The guidance we provide in this document covers common use cases
for each of our legacy customization products. We do not exhaustively cover every possible scenario.
Please use the following information as a foundation for migration and general guidance for mapping
between legacy code and new ACT APIs.
2
ANSYS ACT Migration for Legacy Workbench Customization Products
We will cover the migration process for each path. Along the way, we will illustrate migration by using
the examples listed in the legacy Workbench External Connection Add-In User Guide.
ANSYS_INSTALL/Addins/ExternalConnection
%APPDATA%\Ansys\version\ExternalConnection
$HOME/.config/Ansys/version/ExternalConnection
If your custom user interface entries referenced scripts and images, you also created Images and
Scripts folders under the Customization folder.
With ACT, you define an XML extension definition file, extension folder, scripts, and an images sub-
folder. You must place the XML file and folder in one of three locations:
ANSYS_INSTALL/Addins/ACT/extensions
3
ANSYS ACT Migration for Legacy Workbench Customization Products
For Windows:
%APPDATA%\Ansys\version\ACT\extensions
For Linux:
$HOME/.config/Ansys/version/ACT/extensions
3. User-specified directory
In Workbench, you can set a user-specific extension location in Tools > Options > Extensions.
Inside the ACT extension XML file, you define an <interface> tag to describe new user Interface
elements.
Toolbar Buttons
You can use specific ACT XML elements to define toolbars and toolbar entries at the interface level:
4
ANSYS ACT Migration for Legacy Workbench Customization Products
<Configuration ShowEditConfiguration="True">
<GuiOperations>
<GuiOperation Name="Button One" Priority="2" ScriptFile="main.py"
Image="mybutton1" Type="ToolbarButton" SourceType="Python" Entry="My
Toolbar"/>
</GuiOperations>
</Configuration>
The callback button1Click maps to the method button1Click defined in the extension’s script
main.py. Clicking the button displays a message box:
5
ANSYS ACT Migration for Legacy Workbench Customization Products
Context menu entries defined for custom tasks are covered in Creating Custom Systems and
Components. For application-wide context menu entries, you leverage the same interface block as
toolbar buttons. Instead of distinct XML elements, you enroll two callbacks for user interface
initialization and termination:
6
ANSYS ACT Migration for Legacy Workbench Customization Products
<guid shortid="DynamicContextMenus">9e701503-e8bc-4b9c-a12e-
6c285be5edc9</guid>
<script src="main.py" />
<interface context="Project">
<images>images</images>
<callbacks>
<oninit>createContextMenu</oninit>
<onterminate>removeContextMenu</onterminate>
</callbacks>
</interface>
</extension>
The two callbacks provide empty hooks into Workbench’s user interface. You use Workbench-provided
APIs to dynamically define your new context menus:
import System
import clr
clr.AddReference("Ans.UI")
import Ansys.UI
clr.AddReference("Ans.UI.Toolkit")
clr.AddReference("Ans.UI.Toolkit.Base")
import Ansys.UI.Toolkit
clr.AddReference("Ans.Core")
import Ansys.Core
def createContextMenu(context):
uiMgr = Ansys.UI.UIManager.Instance
menuMgr = uiMgr.ContextMenuManager
imgLib = Ansys.UI.Toolkit.ImageLibrary()
for imgDir in ExtAPI.Extension.GetImageDirectories():
imgLib.AddImagesFromDirectory(imgDir)
menuMgr.AddDynamicEntity(None, Ansys.UI.MenuEntityType.MenuEntry, "Custom
Entry", False, "customEntryIcon", imgLib, System.Single.Parse('1.0'), None,
7
ANSYS ACT Migration for Legacy Workbench Customization Products
This code adds a visible context menu that is only enabled when one or more task groups exist in the
Project Schematic and you right-click a task. The GuiItemCallBack approach for GuiOperations
allows you to leverage applicability previously inaccessible to External Connection Add-in solutions.
8
ANSYS ACT Migration for Legacy Workbench Customization Products
9
ANSYS ACT Migration for Legacy Workbench Customization Products
Menu Entries
Much like context menu entries, you use the initialize and terminate callbacks on the extension user
interface to define, register, and unregister menu entries:
10
ANSYS ACT Migration for Legacy Workbench Customization Products
<guid shortid="DynamicMenuBarMenus">886bfb1d-dd9c-42fa-9fcf-
c86ccc73bfbc</guid>
<script src="main.py" />
<interface context="Project">
<images>images</images>
<callbacks>
<oninit>createMenu</oninit>
<onterminate>removeMenu</onterminate>
</callbacks>
</interface>
</extension>
You access the MenuManager in your callbacks to register the custom entries:
import System
import clr
clr.AddReference("Ans.UI")
import Ansys.UI
clr.AddReference("Ans.UI.Toolkit")
clr.AddReference("Ans.UI.Toolkit.Base")
import Ansys.UI.Toolkit
def createMenu(context):
uiMgr = Ansys.UI.UIManager.Instance
menuMgr = uiMgr.MenuManager
imgLib = Ansys.UI.Toolkit.ImageLibrary()
for imgDir in ExtAPI.Extension.GetImageDirectories():
imgLib.AddImagesFromDirectory(imgDir)
menuLoc = System.Collections.Generic.List[System.String]()
menuLoc.Add("Custom Menu")
menuMgr.AddDynamicEntity(Ansys.UI.MenuEntityType.MenuEntry, "Custom
Entry...", "customEntryIcon", imgLib, System.Single(1.0), menuLoc,
11
ANSYS ACT Migration for Legacy Workbench Customization Products
MyCustomGuiOperation())
def removeMenu(context):
uiMgr = Ansys.UI.UIManager.Instance
menuMgr = uiMgr.MenuManager
menuMgr.RemoveDynamicEntity("DynamicEntity:Menu:System.Collections.Generic.L
ist`1[System.String]:Custom Entry...")
class MyCustomGuiOperation(Ansys.UI.Interfaces.IGuiOperation):
def Invoke(self, context):
Ansys.UI.Toolkit.MessageBox.Show("My Custom Gui Operation invoked...")
def GuiItemCallBack(self, context):
context.Visible = True
context.Enabled = True
12
ANSYS ACT Migration for Legacy Workbench Customization Products
Workbench displays the new entry when you load your extension:
13
ANSYS ACT Migration for Legacy Workbench Customization Products
14
ANSYS ACT Migration for Legacy Workbench Customization Products
15
ANSYS ACT Migration for Legacy Workbench Customization Products
After creating an External Connection system in Workbench and setting the configuration file, the
Project Schematic would look like this:
16
ANSYS ACT Migration for Legacy Workbench Customization Products
On updating the Squares component, the Tables view for the Parameter Set bar would display a
design point as the output:
With ACT, you define a new custom task and task group instead of configuring a prebuilt system and
component. The extension file contains:
17
ANSYS ACT Migration for Legacy Workbench Customization Products
The key difference with ACT: the script squares.py and the update callback handle all text parsing,
application execution, and parameter updates. The External Connection Add-in was plagued by
18
ANSYS ACT Migration for Legacy Workbench Customization Products
inflexibility and portability issues. By rebalancing the responsibility between the definition and
implementation files, you can achieve greater reliability in your customization solutions. The script
squares.py contains the following:
import System
import clr
clr.AddReference("Ans.Utilities")
import Ansys.Utilities
19
ANSYS ACT Migration for Legacy Workbench Customization Products
val = inputParam.Value
f = open(dpInputFile, "w")
f.write('input='+val.ToString(System.Globalization.NumberFormatInfo.Invarian
tInfo))
f.close()
runInMono =
Ansys.Utilities.ApplicationConfiguration.DefaultConfiguration.IsRuntimeMono
monoPath = "mono"
monoArgs = System.String.Format("{0} \"{1}\" \"{2}\"", solverPath,
dpInputFile, dpOutputFile)
info = None
if runInMono:
info = System.Diagnostics.ProcessStartInfo(monoPath, monoArgs)
else:
info = System.Diagnostics.ProcessStartInfo(solverPath,
System.String.Format("\"{0}\" \"{1}\"", dpInputFile, dpOutputFile))
info.CreateNoWindow = True
info.WindowStyle = System.Diagnostics.ProcessWindowStyle.Minimized
p = System.Diagnostics.Process.Start(info)
p.WaitForExit()
outValue = None
f = open(dpOutputFile, "r")
currLine = f.readline()
while currLine != "":
valuePair = currLine.split('=')
outValue = System.Double.Parse(valuePair[1],
System.Globalization.NumberFormatInfo.InvariantInfo)
currLine = f.readline()
f.close()
if outValue == None:
raise Exception("Error in update - no output value detected!")
else:
20
ANSYS ACT Migration for Legacy Workbench Customization Products
outputParam.Value = outValue
The result in Workbench, after loading the extension, would look like this:
21
ANSYS ACT Migration for Legacy Workbench Customization Products
22
ANSYS ACT Migration for Legacy Workbench Customization Products
The system definition file supplied the External Connection Add-in with component, input, and output
information:
<Configuration ShowEditConfiguration="False">
<Instructions>
<Instruction Type="Update">
<Name></Name>
<Script>path_to_python_file/test.py</Script>
</Instruction>
</Instructions>
</Configuration>
23
ANSYS ACT Migration for Legacy Workbench Customization Products
The Python script performed the command calls for the component update:
container = ExternalConnectionSystemContainer
upstreamData = container.GetInputDataByType(InputType="MeshingMesh")
meshFileRef = None
upstreamDataCount = upstreamData.Count
if upstreamDataCount > 0:
meshFileRef = upstreamData[0]
outputRefs = container.GetOutputData()
meshOutputSet = outputRefs["SimulationGeneratedMesh"]
meshOutput = meshOutputSet[0]
meshOutput.TransferFile = meshFileRef
You placed the system definition, configuration, script and image files in an install location at
%AWP_ROOTXXX%\Addins\ExternalConnection\SystemDefinitions. Once copied, you
could access the system from Workbench and load the component configuration file:
24
ANSYS ACT Migration for Legacy Workbench Customization Products
With ACT, you define the entire solution in one configuration file. No file assignment is required.
25
ANSYS ACT Migration for Legacy Workbench Customization Products
</extension>
def update(task):
upstreamData = task.InputData["MeshingMesh"]
meshFileRef = None
upstreamDataCount = upstreamData.Count
if upstreamDataCount > 0:
meshFileRef = upstreamData[0]
meshOutputSet = task.OutputData["SimulationGeneratedMesh"]
meshOutput = meshOutputSet[0]
meshOutput.TransferFile = meshFileRef
Once you load the extension in Workbench and construct the workflow, the Project Schematic contains
the same result:
26
ANSYS ACT Migration for Legacy Workbench Customization Products
Additionally, ACT provides a convenient process for defining custom context menus on custom
components. Many tasks offer a default Edit operation that is triggered when you either double-click the
left mouse button or right-click and select Edit from the context menu. You can define an <onedit>
task callback to automatically receive an Edit entry on the context menu:
Extension File
IronPython
def edit(task):
ExtAPI.Log.WriteMessage("edit...")
27
ANSYS ACT Migration for Legacy Workbench Customization Products
Project Schematic
You can specify additional task-scoped context menus by declaring entry items within a context menu
block on a task:
Extension File
28
ANSYS ACT Migration for Legacy Workbench Customization Products
</inputs>
<outputs/>
<contextmenus>
<entry name="ContextMenu1" caption="Context Menu One" icon=""
version="1" priority="1.">
<callbacks>
<onclick>cm1</onclick>
</callbacks>
</entry>
<entry name="ContextMenu2" caption="Context Menu Two" icon=""
version="1" priority="1.">
<callbacks>
<onclick>cm2</onclick>
</callbacks>
</entry>
</contextmenus>
</task>
IronPython
def cm1(task):
ExtAPI.Log.WriteMessage("context menu 1...")
def cm2(task):
ExtAPI.Log.WriteMessage("context menu 2...")
29
ANSYS ACT Migration for Legacy Workbench Customization Products
Project Schematic
SDK
Some customization projects require more nuanced control of ANSYS Workbench. Your solution before
19.0 -- the ANSYS Workbench Software Development Kit (SDK). However, prohibiting most users from
realizing its potential were SDK’s prerequisites: advanced programming experience, a commercial
Integrated Development Environment, and separate development module. You followed the same
development process as ANSYS’ own application integration efforts. Whether you wanted to “data-
integrate” your application or expose new user interface entries, you created a compiled Workbench
add-in.
30
ANSYS ACT Migration for Legacy Workbench Customization Products
An ACT extension file contains all definition information for your customization solution. The extension
attributes loadAsDefault and isNative allow you to obtain the same auto-load functionality as
SDK add-ins:
</interface>
31
ANSYS ACT Migration for Legacy Workbench Customization Products
</extension>
As long as you place your extension in one of the three Workbench-aware search paths, the extension
load process will resemble an SDK Add-in.
Functionality
SDK-based projects typically incorporated one or more of the SDK’s three core features:
GUI Operations
You can define arbitrary user interface entries with ACT. Past SDK implementations would contain the
following:
32
ANSYS ACT Migration for Legacy Workbench Customization Products
{
}
}
Your SDK add-in would register the GUI operations as a Load step:
With ACT, you define these entries dynamically from the extension’s User Interface initialize and
terminate callbacks as well as at the interface level (for toolbars):
33
ANSYS ACT Migration for Legacy Workbench Customization Products
</entry>
</toolbar>
</interface>
</extension>
You access the MenuManager in your callbacks to manage the custom entries:
import System
import clr
clr.AddReference("Ans.UI")
import Ansys.UI
clr.AddReference("Ans.UI.Toolkit")
clr.AddReference("Ans.UI.Toolkit.Base")
import Ansys.UI.Toolkit
def createOperations(context):
uiMgr = Ansys.UI.UIManager.Instance
menuMgr = uiMgr.MenuManager
imgLib = Ansys.UI.Toolkit.ImageLibrary()
for imgDir in ExtAPI.Extension.GetImageDirectories():
imgLib.AddImagesFromDirectory(imgDir)
menuLoc = System.Collections.Generic.List[System.String]()
menuLoc.Add("Custom Menu")
menuMgr.AddDynamicEntity(Ansys.UI.MenuEntityType.MenuEntry, "Custom
Entry...", "customEntryIcon", imgLib, System.Single(1.0), menuLoc,
MyCustomGuiOperation())
menuMgr = uiMgr.ContextMenuManager
menuMgr.AddDynamicEntity(None, Ansys.UI.MenuEntityType.MenuEntry, "Custom
Entry", False, "customEntryIcon", imgLib, System.Single.Parse('1.0'), None,
MyCustomGuiOperation(), True, False, Ansys.UI.OpClass.None, False, True,
True)
def removeOperations(context):
uiMgr = Ansys.UI.UIManager.Instance
34
ANSYS ACT Migration for Legacy Workbench Customization Products
menuMgr = uiMgr.MenuManager
menuMgr.RemoveDynamicEntity("DynamicEntity:Menu:System.Collections.Generic.L
ist`1[System.String]:Custom Entry...")
menuMgr = uiMgr.ContextMenuManager
menuMgr.RemoveDynamicEntity("DynamicEntity:ContextMenu:Custom Entry")
class MyCustomGuiOperation(Ansys.UI.Interfaces.IGuiOperation):
def Invoke(self, context):
Ansys.UI.Toolkit.MessageBox.Show("My Custom Gui Operation invoked...")
def GuiItemCallBack(self, context):
context.Visible = True
context.Enabled = True
The Project Schematic results are similar to those shown in External Connection Add-in:
Progress Monitoring
Within an ACT callback, you can access the Progress Monitor to report message updates to the user:
IronPython
def update(task):
monitor = ExtAPI.UserInterface.ProgressMonitor
monitor.BeginWork("Progress Example", 3)
monitor.WorkDetails = "Work started!"
35
ANSYS ACT Migration for Legacy Workbench Customization Products
System.Threading.Thread.Sleep(2000)
monitor.UpdateWork(1)
monitor.WorkDetails = "...more work..."
System.Threading.Thread.Sleep(2000)
monitor.UpdateWork(1)
monitor.WorkDetails = "...almost done..."
System.Threading.Thread.Sleep(2000)
monitor.UpdateWork(1)
monitor.WorkDetails = "Work completed!"
System.Threading.Thread.Sleep(2000)
monitor.EndWork()
Project Schematic
36
ANSYS ACT Migration for Legacy Workbench Customization Products
Extension File
IronPython
import System
import clr
clr.AddReference("Ans.UI")
import Ansys.UI
clr.AddReference("Ans.Utilities")
import Ansys.Utilities
37
ANSYS ACT Migration for Legacy Workbench Customization Products
clr.AddReference("Ans.UI.Toolkit")
clr.AddReference("Ans.UI.Toolkit.Base")
import Ansys.UI.Toolkit
import Ansys.UI.Toolkit.Base
def init(context):
ExtAPI.Log.WriteMessage("Init Scratch Extension ...")
uiManager = Ansys.UI.UIManager.Instance
t = uiManager.GetType()
p = t.GetProperty("ViewRegistry", System.Reflection.BindingFlags.Instance
| System.Reflection.BindingFlags.NonPublic)
registry = p.GetValue(uiManager)
t = registry.GetType()
m = t.GetMethod("RegisterView", System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.NonPublic)
args = System.Collections.Generic.List[System.Object]()
args.Add(clr.GetClrType(CustomView))
m.Invoke(registry, args.ToArray())
def showTab(entity):
global _p
ExtAPI.Log.WriteMessage("Button clicked...")
w = Ansys.UI.UIManager.Instance.GetActiveWorkspace()
v = w.GetView("CustomView")
if v == None:
builder = w.PanesBuilder
customPane = builder.CreateCustomerPane(w, "Custom")
customPane.AllowMinimized = False
customPane.AllowFloating = False
customPane.AllowDocking = False
header = customPane.Header
header.CloseVisible = False
header.AuxDropDownVisible = False
38
ANSYS ACT Migration for Legacy Workbench Customization Products
header.DropDownVisible = False
header.PinVisible = False
header.Active = False
header.Enabled = False
header.ArrangeVisible = False
header.RestoreVisible = False
v = CustomView("CustomView")
addMethod = w.GetType().GetMethod("AddViewToPane",
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.NonPublic)
argsList = System.Collections.Generic.List[System.Object]()
argsList.Add(customPane)
argsList.Add(v)
addMethod.Invoke(w, argsList.ToArray())
layout = builder.CreateNewLayout("CustomLayout", customPane)
header.Text = ""
Ansys.UI.Workspaces.Workspace.ActivateLayout("CustomLayout", "", "Custom
Page", None)
class CustomView(Ansys.UI.Views.View):
def __init__(self, name):
self._mainPanel = None
self.Initialize()
def Initialize(self):
if self._mainPanel == None:
self._mainPanel = Ansys.UI.Toolkit.TableLayoutPanel()
else:
self._mainPanel.Controls.Clear()
self._mainPanel.Rows.Clear()
self._mainPanel.Columns.Clear()
self._mainPanel.Rows.Add(Ansys.UI.Toolkit.TableLayoutSizeType.Percent,
100)
self._mainPanel.Columns.Add(Ansys.UI.Toolkit.TableLayoutSizeType.Percent,
39
ANSYS ACT Migration for Legacy Workbench Customization Products
100)
self._mainPanel.BackColor = Ansys.Utilities.Color(83, 83, 83)
htmlViewer = Ansys.UI.Toolkit.HtmlViewer()
htmlViewer.MinimumSize = self._mainPanel.Size
htmlViewer.Html = r"<html><head><title>Custom
Tab</title></head><body><center><h3>Sample HTML
Viewer</h3></center></body></html>"
self._mainPanel.Controls.Add(htmlViewer, 0, 0)
self.Control = self._mainPanel
Project Schematic
Property Display
You can use ACT to change the display of properties within the Project Schematic. For example, you can
instruct a property to display a dialog box for user input instead of direct property manipulation.
40
ANSYS ACT Migration for Legacy Workbench Customization Products
Extension File
IronPython
import System
import clr
clr.AddReference("Ans.Core")
import Ansys.Core
clr.AddReference("Ans.UI")
import Ansys.UI
clr.AddReference("Ans.UI.Toolkit")
clr.AddReference("Ans.UI.Toolkit.Base")
import Ansys.UI.Toolkit
import Ansys.UI.Toolkit.Base
import Ansys.UI.Toolkit.Drawing
def registerPropertyAction(context):
ExtAPI.Log.WriteMessage("Registering custom property action...")
uiMgr = Ansys.UI.UIManager.Instance
attributes = System.Collections.Generic.List[System.Attribute]()
attr =
41
ANSYS ACT Migration for Legacy Workbench Customization Products
Ansys.UI.Attributes.GuiOperationAttribute("ShowMyCustomPropertyAction")
attributes.Add(attr)
defineContext = uiMgr.CreateGuiDefineContext()
defineContext.RegisterOperation(MyCustomPropertyActionGuiOperation(),
attributes)
Ansys.UI.PropertyEditActionRegistry.RegisterAction("DesignPointSolveSettings
", "RsmUserString", "ShowMyCustomPropertyAction",
Ansys.UI.PropertyEditActionRegistry.ActivationMode.ByButton)
Ansys.UI.PropertyEditActionRegistry.RegisterAction("ComponentSolveSettingsFo
rAddin", "RsmUserString", "ShowMyCustomPropertyAction",
Ansys.UI.PropertyEditActionRegistry.ActivationMode.ByButton)
class MyCustomPropertyActionGuiOperation(Ansys.UI.Interfaces.IGuiOperation):
def Invoke(self, context):
selection =
context.View.GetSingleUISelection[Ansys.Core.DataModel.ProjectSystem.DataCon
tainerReference]()
if selection == None:
uiMgr = Ansys.UI.UIManager.Instance
workspace = uiMgr.GetActiveWorkspace()
view = workspace.GetView("ProjectSchematic")
selection =
view.GetSingleUISelection[Ansys.Core.DataModel.ProjectSystem.DataContainerRe
ference]()
dialog = MyCustomPropertyDialog(selection)
dialog.ShowDialog()
def GuiItemCallBack(self, context):
context.Visible = True
context.Enabled = True
class MyCustomPropertyDialog(Ansys.UI.Toolkit.Dialog):
mainPanel = None
userString = None
container = None
def __init__(self, container):
42
ANSYS ACT Migration for Legacy Workbench Customization Products
self.container = container
width = 250;
height = 100;
self.Text = "Set Text"
self.Width = width
self.Height = height
self.MaximizeBox = False
self.MinimumSize = Ansys.UI.Toolkit.Drawing.Size(width, height)
self.MaximumSize = Ansys.UI.Toolkit.Drawing.Size(width, height)
self.__BuildUI()
self.SetControl(self.mainPanel)
def __BuildUI(self):
self.mainPanel = Ansys.UI.Toolkit.TableLayoutPanel()
self.mainPanel.Rows.Add(Ansys.UI.Toolkit.TableLayoutSizeType.Percent,
50)
self.mainPanel.Rows.Add(Ansys.UI.Toolkit.TableLayoutSizeType.Percent,
50)
self.mainPanel.Columns.Add(Ansys.UI.Toolkit.TableLayoutSizeType.Percent,
50)
self.mainPanel.Columns.Add(Ansys.UI.Toolkit.TableLayoutSizeType.Percent,
50)
l = Ansys.UI.Toolkit.Label("Text:")
self.mainPanel.Controls.Add(l, 0, 0)
self.userString = Ansys.UI.Toolkit.TextBox()
self.mainPanel.Controls.Add(self.userString, 0, 1)
apply = Ansys.UI.Toolkit.Button("Apply")
apply.Click += Ansys.UI.Toolkit.EventDelegate(self.apply_Click)
self.mainPanel.Controls.Add(apply, 1, 0)
cancel = Ansys.UI.Toolkit.Button("Cancel")
cancel.Click += Ansys.UI.Toolkit.EventDelegate(self.cancel_Click)
self.mainPanel.Controls.Add(cancel, 1, 1)
def cancel_Click(self, sender, args):
self.Close()
43
ANSYS ACT Migration for Legacy Workbench Customization Products
Ansys.Core.Commands.Standard.SetEntityPropertyCommand.InvokeAndWait(dataRef,
"RsmUserString", self.userString.Text)
self.Close()
44
ANSYS ACT Migration for Legacy Workbench Customization Products
Project Schematic
45
ANSYS ACT Migration for Legacy Workbench Customization Products
Ansys.Core.Events.EventManager.FrameworkInstance.Subscribe(this, this);
context.CommandManager.RootContext.Project.EventSource.PersistenceStateChang
ed += new
EventHandler<Ansys.Core.Persistence.PersistenceActionsEventArgs>(EventSource
_PersistenceStateChanged);
}
46
ANSYS ACT Migration for Legacy Workbench Customization Products
In an ACT extension, you can either use the pre-defined workflow callbacks to handle Project Schematic
actions or register/unregister event handlers from the extension’s user interface initialize and terminate
callbacks.
Event Handlers
XML File
IronPython
import System
import clr
clr.AddReference('Ans.Core')
import Ansys.Core
clr.AddReference('Ans.UI')
import Ansys.UI
saveEventHandler = None
exitEventHandler = None
def init(context):
global saveEventHandler
global exitEventHandler
47
ANSYS ACT Migration for Legacy Workbench Customization Products
Workflow Callbacks
XML File
48
ANSYS ACT Migration for Legacy Workbench Customization Products
<onbeforetasksourceschanged>onBeforeSourcesChanged</onbeforetasksourceschang
ed>
<onaftertasksourceschanged>onAfterSourcesChanged</onaftertasksourceschanged>
<onbeforetaskcreation>onBeforeCreate</onbeforetaskcreation>
<onaftertaskcreation>onAfterCreate</onaftertaskcreation>
<onbeforetaskdeletion>onBeforeDelete</onbeforetaskdeletion>
<onaftertaskdeletion>onAfterDelete</onaftertaskdeletion>
<onbeforetaskcanusetransfer>onBeforeCanUseTransfer</onbeforetaskcanusetransf
er>
<onaftertaskcanusetransfer>onAfterCanUseTransfer</onaftertaskcanusetransfer>
<onbeforetaskcanduplicate>onBeforeCanDuplicate</onbeforetaskcanduplicate>
<onaftertaskcanduplicate>onAfterCanDuplicate</onaftertaskcanduplicate>
<onbeforetaskstatus order="1">onBeforeStatus1</onbeforetaskstatus>
<onaftertaskstatus order="2">onAfterStatus1</onaftertaskstatus>
<onbeforetaskpropertyretrieval>onBeforePropertyRetrieval</onbeforetaskproper
49
ANSYS ACT Migration for Legacy Workbench Customization Products
tyretrieval>
<onaftertaskpropertyretrieval>onAfterPropertyRetrieval</onaftertaskpropertyr
etrieval>
</callbacks>
</workflow>
</extension>
IronPython
def onBeforeReset(task):
msg = getPrintMessage('pre-reset', task)
ExtAPI.Log.WriteMessage(msg)
def onAfterReset(task):
msg = getPrintMessage('post-reset', task)
ExtAPI.Log.WriteMessage(msg)
def onBeforeRefresh(task):
msg = getPrintMessage('pre-refresh', task)
ExtAPI.Log.WriteMessage(msg)
def onAfterRefresh(task):
msg = getPrintMessage('post-refresh', task)
ExtAPI.Log.WriteMessage(msg)
def onBeforeUpdate(task):
msg = getPrintMessage('pre-update', task)
ExtAPI.Log.WriteMessage(msg)
def onAfterUpdate(task):
msg = getPrintMessage('post-update', task)
ExtAPI.Log.WriteMessage(msg)
def onBeforeDuplicate(task):
msg = getPrintMessage('pre-duplicate', task)
ExtAPI.Log.WriteMessage(msg)
def onAfterDuplicate(task):
50
ANSYS ACT Migration for Legacy Workbench Customization Products
51
ANSYS ACT Migration for Legacy Workbench Customization Products
52
ANSYS ACT Migration for Legacy Workbench Customization Products
interface of your application. Your application used the custom add-in as an intermediary with
Workbench to synchronize data and process action requests.
.SetDuplicateContainerCommand(typeof(Commands.DuplicateScratchComponentComma
nd))
.SetComponentPropertyDataQuery(typeof(Queries.GetScratchComponentPropertiesQ
uery))
.SetComponentStatusQuery(typeof(Queries.GetScratchComponentStatusQuery))
.SetCreateAllProvidesConnectionsToNewSystem(true)
.SetIsShareable(false)
.SetOutputTypes(new string[] {
Core.AddinConstants.ScratchDataTypeString })
.SetDisplayName("");
53
ANSYS ACT Migration for Legacy Workbench Customization Products
context.TemplateRepository.AddSystemTemplate("ScratchTemplate")
.SetToolboxGroup("Scratch")
.SetComponentTemplateNames(new string[] { "ScratchTemplate" })
.SetComponentNames(new string[] { "Scratch" })
.SetSystemTypeAbbreviation("ScratchEX")
.SetDefaultSystemName("Scratch Example")
.SetToolboxDisplayText("Scratch Example")
.SetImage("ScratchImage");
}
}
ACT uses the terms task and tas kgroup instead of component and system. In your ACT extension, you
define tasks and task groups in the XML definition file:
54
ANSYS ACT Migration for Legacy Workbench Customization Products
<inputs>
<input/>
</inputs>
<outputs/>
</task>
</tasks>
<taskgroups>
<taskgroup name="TaskGroup" caption="Task Group" icon="taskgroup"
category="ACT Workflows" headertext="Task Group" abbreviation="TG"
version="1">
<includeTask name="Task" caption="Task"/>
</taskgroup>
</taskgroups>
</workflow>
</extension>
Instead of defining ICommand and IQuery classes with the SDK, you define IronPython callbacks on
your task:
SDK
[Command("UpdateScratchComponent")]
public partial class UpdateScratchComponentCommand : ICommand
{
[Parameter]
public DataContainerReference Container;
55
ANSYS ACT Migration for Legacy Workbench Customization Products
Core.AddinConstants.ScratchDataTypeString)[0];
input = (double)context.Project.GetProperty(dr, "inValue");
}
using (context.ContainerWriteLock(Container))
{
context.Project.SetProperty(dr, "outValue", input * input);
DataObjectContainer containerObj =
context.Project.GetContainerObject(Container, Addin.key) as
DataObjectContainer;
containerObj.SignalOutputsGenerated();
}
}
}
ACT
def update(task):
inputValue = task.Properties["Inputs"].Properties["Input"].Value
task.Properties["Outputs"].Properties["Output"].Value = inputValue *
inputValue
Additionally, you can re-use pre-installed tasks to compose new analysis task groups, as long as you
maintain data transfer input and output rules:
56
ANSYS ACT Migration for Legacy Workbench Customization Products
57
ANSYS ACT Migration for Legacy Workbench Customization Products
Workflow Connections
The Project Schematic exposes a powerful workflow environment through the chaining together of
simulation blocks. Connections between upstream and downstream tasks allow data transfer to flow
from one application to another. With the SDK, you were required to implement data transfer by
specifying input and output combinations on your component template, implementing a complex
DataSourcesListChanged query, defining output data, and implementing the three data transfer
methods: Acquire, Retrieve, and Release.
ACT simplifies the connection process. If you want to connect with other ANSYS tasks, you reference a
list of input and output types from documentation.
Once you identify the connection type, you can list it as input to your task:
Extension File
58
ANSYS ACT Migration for Legacy Workbench Customization Products
</callbacks>
<inputs>
<input/>
<input type="MechanicalSolution" format=""/>
</inputs>
<outputs/>
</task>
</tasks>
<taskgroups>
<taskgroup name="RSTProcessor" caption="RST Processor"
icon="rst_taskgroup" category="ACT Custom Workflows" abbreviation="RSTP"
version="1">
<includeTask name="RSTProcessor" caption="RST"/>
</taskgroup>
</taskgroups>
</workflow>
</extension>
IronPython
def update(task):
ExtAPI.Log.WriteMessage("Updating " + task.Name)
if task.InputData.ContainsKey("MechanicalSolution"):
rstFile = task.InputData["MechanicalSolution"][0]
currRSTFile = GetDesignPointFile(rstFile)
rstFilePath = currRSTFile.Location
ExtAPI.Log.WriteMessage("Discovered RST File - " + rstFilePath)
59
ANSYS ACT Migration for Legacy Workbench Customization Products
Project Schematic
Similarly, if your task will output data to be consumed downstream, you can find the appropriate type
and enter it as output from your task. You can also define custom types to connect and transfer to tasks
only defined by your extension and mix the types within a workflow:
Extension File
60
ANSYS ACT Migration for Legacy Workbench Customization Products
<outputs>
<output type="CustomGeometry" format=""/>
</outputs>
<propertygroup name="Inputs">
<property name="dim1" caption="Length" control="double"
default="10.0" readonly="False" needupdate="true" visible="True"
persistent="True" parameterizable="True">
<callbacks>
<isvalid>isValid1</isvalid>
</callbacks>
</property>
<property name="dim2" caption="Width" control="double"
default="3.0" readonly="False" needupdate="true" visible="True"
persistent="True" parameterizable="True">
<callbacks>
<isvalid>isValid2</isvalid>
</callbacks>
</property>
</propertygroup>
</task>
<task name="Meshing" caption="Meshing Creation"
icon="meshing_component" version="1">
<callbacks>
<onupdate>updateMesh</onupdate>
</callbacks>
<inputs>
<input type="CustomGeometry" format=""/>
<input/>
</inputs>
<outputs>
<output type="CFXMesh" format=""/>
</outputs>
</task>
61
ANSYS ACT Migration for Legacy Workbench Customization Products
</tasks>
<taskgroups>
<taskgroup name="CFDGeomtryGroup" caption="CFD Geometry"
icon="geometry_system" category="ACT Workflows" abbreviation="CFDCAD"
version="1">
<includeTask name="Geometry" caption=""/>
</taskgroup>
<taskgroup name="CFDMeshGroup" caption="CFD Mesh"
icon="meshing_system" category="ACT Workflows" abbreviation="CFDMSH"
version="1">
<includeTask name="Meshing" caption=""/>
</taskgroup>
</taskgroups>
</workflow>
</extension>
IronPython
import clr
import os
clr.AddReference("Ans.Utilities")
clr.AddReference("Ans.UI.Toolkit")
clr.AddReference("Ans.UI.toolkit.Base")
import System
import sys
import subprocess
import shutil
global myres
import math
import time
62
ANSYS ACT Migration for Legacy Workbench Customization Products
def updateGeometry(task):
icemgeoAddinPath = task.Extension.InstallDir
installPath =
ApplicationConfiguration.DefaultConfiguration.WorkbenchInstallRootDirectoryP
ath
activeDir = task.ActiveDirectory
#geom replay contents
geomReplayContents = """
#you can find full replay file contents in template files.
"""
#Create the replay file in the project dir
replayFileName = "create_geom.rpl"
replayFilePath = Path.Combine(activeDir, replayFileName)
#Assembling the replay file with correct storage location
dim1 = task.Properties["Inputs"].Properties["dim1"].Value
dim2 = task.Properties["Inputs"].Properties["dim2"].Value
CreateRPLFile = open(replayFilePath,'w')
CreateRPLFile.write("set inp1 " + str(dim1) + '\n')
CreateRPLFile.write("set inp2 " + str(dim2) + '\n')
CreateRPLFile.write(geomReplayContents + '\n')
#Define the path for the tin file to save and write to the replay file
geoFileName = "channel.tin"
destinationPath = Path.Combine(activeDir, geoFileName)
#Write the save command to the rpl file
strReplace=destinationPath.replace('\\','/')
CreateRPLFile.write("ic_save_tetin " + strReplace + " 0 0 {} {} 0 0
1"+'\n')
CreateRPLFile.close()
#Launch icem
icemBin = Path.Combine(installPath, Path.Combine("icemcfd",
63
ANSYS ACT Migration for Legacy Workbench Customization Products
Path.Combine("win64_amd","bin")))
icemExeName = "icemcfd.bat"
icemExePath = Path.Combine(icemBin, icemExeName)
if File.Exists(icemExePath) == True:
info = ProcessStartInfo(icemExePath)
info.Arguments = System.String.Format("-batch -script \"{0}\"",
replayFilePath)
Process.Start(info).WaitForExit()
#Register the .tin file
geoFile = None
isRegistered = IsFileRegistered(FilePath=destinationPath)
if isRegistered == True:
geoFile = GetRegisteredFile(destinationPath)
else:
geoFile = task.RegisterFile(destinationPath)
#Transfer file downstreams
geoRefs = task.OutputData
geoSet = geoRefs["CustomGeometry"]
geoData = geoSet[0]
geoData.TransferFile = geoFile
def updateMesh(task):
#Calculate Paths
installPath =
ApplicationConfiguration.DefaultConfiguration.WorkbenchInstallRootDirectoryP
ath
icemmeshAddinPath = task.Extension.InstallDir
activeDir = task.ActiveDirectory
cfxFormattedActiveDir = activeDir.replace('\\','/')
#Obtain upstream data
upstreamData = task.InputData["CustomGeometry"]
geoFileRef = None
upstreamDataCount = upstreamData.Count
64
ANSYS ACT Migration for Legacy Workbench Customization Products
if upstreamDataCount > 0:
geoFileRef = upstreamData[0]
replayContents = """
#you can find full replay contents in template files
"""
#Create the replay file
replayFileName = "create_mesh.rpl"
mshFileName = "channel.msh"
replaydestinationPath = Path.Combine(activeDir, replayFileName)
mshFilePath = Path.Combine(activeDir, mshFileName)
CreateRPLFile = open(replaydestinationPath,'w')
strgeoFile = geoFileRef.Location
strgeoFileReplace=strgeoFile.replace('\\','/')
CreateRPLFile.write("ic_load_tetin " + strgeoFileReplace + '\n')
CreateRPLFile.write(replayContents + '\n')
#Add the path to the save location for mesh file
mshFileReplace=mshFilePath.replace('\\','/')
cfx5Path = Path.Combine(installPath, Path.Combine("icemcfd",
Path.Combine("win64_amd", Path.Combine("icemcfd", Path.Combine("output-
interfaces", "cfx5")))))
saveContent = "ic_exec {" + cfx5Path + "} -dom project1.uns -b
project1.fbc -ascii -db -internal_faces " + mshFileReplace + '\n'
CreateRPLFile.write(saveContent)
CreateRPLFile.close()
#Launch icem
icemBin = Path.Combine(installPath, Path.Combine("icemcfd",
Path.Combine("win64_amd","bin")))
icemExeName = "icemcfd.bat"
icemExePath = Path.Combine(icemBin, icemExeName)
if File.Exists(icemExePath) == True:
info = ProcessStartInfo(icemExePath)
info.Arguments = System.String.Format("-batch -script \"{0}\"",
replaydestinationPath)
65
ANSYS ACT Migration for Legacy Workbench Customization Products
Process.Start(info).WaitForExit()
#Register the .msh file
mshFile = None
isRegistered = IsFileRegistered(FilePath=mshFilePath)
if isRegistered == True:
mshFile = GetRegisteredFile(mshFilePath)
else:
mshFile = task.RegisterFile(mshFilePath)
#Convert File into a gtm file readable by the cfx system
targetGTMName = "channel_converted.gtm"
targetGTMPath = Path.Combine(activeDir, targetGTMName)
cfxBin = Path.Combine(installPath, Path.Combine("CFX", "bin"))
cfxConverterExeName = "cfx5gtmconv.exe"
cfxConverterExePath = Path.Combine(cfxBin, cfxConverterExeName)
if File.Exists(cfxConverterExePath) == True:
info = ProcessStartInfo(cfxConverterExePath)
info.Arguments = System.String.Format("-icem \"{0}\" \"{1}\"",
mshFilePath, targetGTMPath)
Process.Start(info).WaitForExit()
gtmFile = None
if File.Exists(targetGTMPath) == True:
if IsFileRegistered(FilePath=targetGTMPath) == False:
gtmFile = task.RegisterFile(targetGTMPath)
else:
gtmFile = GetRegisteredFile(FilePath=targetGTMPath)
outputRefs = task.OutputData
meshOutputSet = outputRefs["CFXMesh"]
meshOutput = meshOutputSet[0]
meshOutput.FileName = gtmFile
meshOutput.PreFileType = "GTM"
def isValid1(entity, property):
66
ANSYS ACT Migration for Legacy Workbench Customization Products
Project Schematic
A more simplistic example when you define custom transfer types for your own tasks and workflows:
Extension File
67
ANSYS ACT Migration for Legacy Workbench Customization Products
<onupdate>producer_update</onupdate>
</callbacks>
<inputs>
<input/>
</inputs>
<outputs>
<output format="" type="MyData"/>
</outputs>
</task>
<task name="Consumer" caption="consumer" icon="consumer_task"
version="1">
<callbacks>
<onupdate>consumer_update</onupdate>
</callbacks>
<inputs>
<input/>
<input format="" type="MyData"/>
</inputs>
<outputs/>
</task>
</tasks>
<taskgroups>
<taskgroup name="Producer" caption="Producer" icon="producer_system"
category="ACT Workflows" abbreviation="Producer" version="1">
<includeTask name="Producer" caption="Producer"/>
</taskgroup>
<taskgroup name="Consumer" caption="Consumer" icon="consumer_system"
category="ACT Workflows" abbreviation="Consumer" version="1">
<includeTask name="Consumer" caption="Consumer"/>
</taskgroup>
</workflow>
</extension>
68
ANSYS ACT Migration for Legacy Workbench Customization Products
IronPython
import System
def consumer_update(task):
ExtAPI.Log.WriteMessage("updating " + task.Name)
upstreamData = task.InputData["MyData"]
fileRef = None
upstreamDataCount = upstreamData.Count
if upstreamDataCount > 0:
fileRef = upstreamData[0]
AssociateFileWithContainer(fileRef, task.InternalObject)
ExtAPI.Log.WriteMessage("Recieved file "+fileRef.Location+" from
upstream task.")
#if no new data...nothing to process from upstream sources.
def producer_update(task):
ExtAPI.Log.WriteMessage("updating " + task.Name)
extensionDir = ExtAPI.ExtensionManager.CurrentExtension.InstallDir
filePath = System.IO.Path.Combine(extensionDir, "Sample_Materials.xml")
fileRef = task.RegisterFile(filePath)
outputSet = task.OutputData["MyData"]
myData = outputSet[0]
myData.TransferFile = fileRef
Project Schematic
ACT additionally exposes a generic transfer mechanism. When operating under general transfer, you
need not specify inputs or outputs on your tasks. Instead, ACT defines and manages the transfer types
for you. You can use generic transfer to connect one or more custom tasks as well as any ANSYS-based
Model, Setup, or Solution task inside an analysis system.
69
ANSYS ACT Migration for Legacy Workbench Customization Products
Re-writing the simple custom connection extension from earlier by using generic transfer makes
lightweight data exchange easier. You can push data into a data store for access by the downstream
tasks:
Extension File
70
ANSYS ACT Migration for Legacy Workbench Customization Products
<outputs/>
</task>
</tasks>
<taskgroups>
<taskgroup name="Producer" caption="Producer" icon="producer_system"
category="ACT Workflows" abbreviation="Producer" version="1">
<includeTask name="Producer" caption="Producer"/>
</taskgroup>
<taskgroup name="Consumer" caption="Consumer" icon="consumer_system"
category="ACT Workflows" abbreviation="Consumer" version="1">
<includeTask name="Consumer" caption="Consumer"/>
</taskgroup>
</taskgroups>
</workflow>
</extension>
IronPython
def consumer_update(task):
if task.SourceTasks.Count == 1:
data = task.SourceTasks[0].TransferData["Test"]
def producer_update(task):
task.TransferData["Test"] = "This is a test from " + task.Name
Project Schematic
Defining an extension for connection with ANSYS-based simulation tasks is just as easy:
Extension File
71
ANSYS ACT Migration for Legacy Workbench Customization Products
icon="images\customload_extension.png">
<guid shortid="CustomLoad">69d0590b-e138-4841-a13a-de12238c83f2</guid>
<script src="main.py" />
<interface context="Project">
<images>images</images>
</interface>
<interface context="Mechanical">
<images>images</images>
<toolbar name="CustomLoad" caption="">
<entry name="CustomLoad" icon="">
<callbacks>
<onclick>customLoadClick</onclick>
</callbacks>
</entry>
</toolbar>
</interface>
<workflow name="MyWorkflow" context="Project" version="1">
<callbacks>
<onaftertaskrefresh>pushGenericData</onaftertaskrefresh>
<onbeforetaskupdate>pushGenericData</onbeforetaskupdate>
</callbacks>
<tasks>
<task name="CustomLoad" caption="Custom Load" icon="customload_task"
version="1">
<property name="Pressure" caption="Pressure" control="float"
default="1.0" readonly="False" needupdate="true" visible="True"
persistent="True" parameterizable="True" />
<callbacks>
<onupdate>update</onupdate>
</callbacks>
<inputs>
<input/>
72
ANSYS ACT Migration for Legacy Workbench Customization Products
</inputs>
<outputs/>
</task>
</tasks>
<taskgroups>
<taskgroup name="CustomLoad" caption="Custom Load" icon="customload"
category="ACT Workflows" headertext="Custom Imported Load" abbreviation="C-
LOAD" version="1">
<includeTask name="CustomLoad" caption="Custom Load"/>
</taskgroup>
</taskgroups>
</workflow>
</extension>
IronPython
load = None
if not dict.ContainsKey(guid):
load = ExtAPI.DataModel.AnalysisList[0].AddPressure()
dict.Add(guid, load.ObjectId)
ExtAPI.Log.WriteMessage("created pressure load")
else:
load = ExtAPI.DataModel.GetObjectById(dict[guid])
ExtAPI.Log.WriteMessage("set pressure value")
73
ANSYS ACT Migration for Legacy Workbench Customization Products
load.Magnitude.Output.DiscreteValues=[Quantity("0
[Pa]"),Quantity(pressureValue+" [Pa]")]
def pushGenericData(task):
cmd = ""
sourceTask = None
if task.Name.Contains("Model"):
for source in task.SourceTasks:
if source.Name.Contains("CustomLoad"):
sourceTask = ACT.GetACTTaskForContainer(source.Container)
break
if sourceTask != None:
outputData = sourceTask.OutputData["GeneralTransfer"][0]
guid = outputData.Guids[0]
pressureVal = sourceTask.Properties['Pressure'].Value
task.ExecuteCommand("SendCommand", {
'Command':"ExtAPI.ExtensionManager.GetExtensionByName('"+sourceTask.Extensio
n.Name+"').GetModule().updateLoad(\""+str(guid)+"\",\""+str(pressureVal)+"\"
)", 'Language':"Python" })
def update(task):
ExtAPI.Log.WriteMessage('Updating ' + task.Name)
def customLoadClick(args):
ExtAPI.Log.WriteMessage('Custom Load Toolbar Button Clicked')
74
ANSYS ACT Migration for Legacy Workbench Customization Products
Project Schematic
[DataEntity(Core.AddinConstants.ScratchDataTypeString, Exposure =
ExposureLevel.AnyUser)]
public class ScratchData : DataObject
{
[Spec(Label = "Integer Input", Group = "Inputs", Default = 1, Usage =
SpecUsage.Input, Exposure = ExposureLevel.AnyUser, Access =
SpecAccess.UserWritable)]
public double inValue;
75
ANSYS ACT Migration for Legacy Workbench Customization Products
: base(name, Container)
{
}
public ScratchData()
: this(null, null)
{
}
}
ACT automatically creates a dynamic data entity to store all of your properties. You can declare
properties per task within your extension file. You can also use property groups to organize multiple
properties and their display within the Workbench Properties view:
Extension File
76
ANSYS ACT Migration for Legacy Workbench Customization Products
77
ANSYS ACT Migration for Legacy Workbench Customization Products
Project Schematic
ACT also simplifies property access. With the SDK, you had to obtain a container lock to read or write
property values:
[Command("UpdateScratchComponent")]
public partial class UpdateScratchComponentCommand : ICommand
{
[Parameter]
public DataContainerReference Container;
78
ANSYS ACT Migration for Legacy Workbench Customization Products
}
using (context.ContainerWriteLock(Container))
{
context.Project.SetProperty(dr, "outValue", input * input);
DataObjectContainer containerObj =
context.Project.GetContainerObject(Container, Addin.key) as
DataObjectContainer;
containerObj.SignalOutputsGenerated();
}
}
}
In your extension callbacks, you access properties directly off of your task and can manipulate the values
with no extra actions. Note how a property group inserts an extra level for property access:
def update(task):
inputValue = task.Properties["Inputs"].Properties["Input"].Value
task.Properties["Outputs"].Properties["Output"].Value = inputValue *
inputValue
79
ANSYS ACT Migration for Legacy Workbench Customization Products
Parameters
Data entity properties automatically support parameterization when you designate them as
input/output and parameterizable. With the SDK, you supplied this data within the property’s Spec
attribute:
The Project Schematic result is the same. Check boxes appear in the last column of the Properties view.
Selecting these boxes will create new parameters and display the Parameter Set bar in the Project
Schematic:
80
ANSYS ACT Migration for Legacy Workbench Customization Products
Sometimes your application may define parameters on-the-fly at runtime. With the SDK, you would
define dynamic data objects, add spec information, and create the new entities within your component
container. The process is similar in ACT:
import System
import clr
clr.AddReference("Ansys.ACT.WorkBench")
import Ansys.ACT.WorkBench
clr.AddReference("Ans.Utilities")
import Ansys.Utilities
81
ANSYS ACT Migration for Legacy Workbench Customization Products
clr.AddReference("Ans.UI.Toolkit")
clr.AddReference("Ans.UI.Toolkit.Base")
from Ansys.UI.Toolkit import *
from Ansys.UI.Toolkit.Base import *
from Ansys.UI.Toolkit.Drawing import *
clr.AddReference("Ans.Core")
import Ansys.Core
82
ANSYS ACT Migration for Legacy Workbench Customization Products
Parameters.CreateParameter(Entity=parameterSourceObject.GetDataReference(),
PropertyName="Value", IsOutput=isOutput, IsDirectOutput=isOutput,
Expression=value, DisplayText=paramName)
You would have defined one or more data entities for background job tracking, implemented the
“pending state” routines on your update command, added new queries and commands for job status
pinging, reconnect requests, and failure handling, and finally provide resync code to merge the remote
job results with the local project. For SDK developers, RSM was the second most complex add-in
development topic, behind data transfer.
83
ANSYS ACT Migration for Legacy Workbench Customization Products
Fortunately, ACT simplifies the process at the extension task level. You first define RSM-specific
information in the extension definition file as a child of the task:
84
ANSYS ACT Migration for Legacy Workbench Customization Products
f.write('input='+inputValue.ToString(System.Globalization.NumberFormatInfo.I
nvariantInfo))
f.close()
def reconnectJob(task, outputFilePaths):
ExtAPI.Log.WriteMessage('reconnecting job')
outputValue = None
outputFilePath = outputFilePaths[0] #I know we only have one specified
based on our definition...so work off of the first entry
f = open(outputFilePath, "r")
currLine = f.readline()
while currLine != "":
valuePair = currLine.split('=')
outputValue = System.Double.Parse(valuePair[1],
System.Globalization.NumberFormatInfo.InvariantInfo)
currLine = f.readline()
f.close()
#set output value
ExtAPI.Log.WriteMessage("Retrieved value (" + str(outputValue) + ") from
file (" + outputFilePath + ")")
if outputValue == None:
raise Exception("Error in update - no output value detected!")
else:
task.Properties["Outputs"].Properties["Output"].Value = outputValue
def getJobStatus(task, outputFiles):
ExtAPI.Log.WriteMessage('checking job status')
outputFilePath = outputFiles[0]
finished = System.IO.File.Exists(outputFilePath)
85
ANSYS ACT Migration for Legacy Workbench Customization Products
return finished
def cancelJob(task, inputFiles, outputFiles):
ExtAPI.Log.WriteMessage('performing cancellation clean up')
Now your task is RSM-compatible. The complete IronPython script with full update, progress
monitoring, and task callback routines:
def update(task):
activeDir = task.ActiveDirectory
extensionDir = task.Extension.InstallDir
exeName = "ExampleAddinExternalSolver.exe"
solverPath = System.IO.Path.Combine(extensionDir, exeName)
monitor = ExtAPI.UserInterface.ProgressMonitor
monitor.BeginWork("Data Sqaures Solver", 3)
monitor.WorkDetails = "Preparing solver input..."
monitor.UpdateWork(1)
inputFileName = "input.txt"
outputFileName = "output.txt"
dpInputFile = System.IO.Path.Combine(activeDir, inputFileName)
dpOutputFile = System.IO.Path.Combine(activeDir, outputFileName)
f.write('input='+inputValue.ToString(System.Globalization.NumberFormatInfo.I
nvariantInfo))
86
ANSYS ACT Migration for Legacy Workbench Customization Products
f.close()
monitor.UpdateWork(1)
#run exe
monitor.UpdateWork(1)
outputValue = None
f = open(dpOutputFile, "r")
currLine = f.readline()
while currLine != "":
valuePair = currLine.split('=')
outputValue = System.Double.Parse(valuePair[1],
System.Globalization.NumberFormatInfo.InvariantInfo)
currLine = f.readline()
f.close()
monitor.UpdateWork(1)
87
ANSYS ACT Migration for Legacy Workbench Customization Products
if outputValue == None:
raise Exception("Error in update - no output value detected!")
else:
task.Properties["Outputs"].Properties["Output"].Value = outputValue
monitor.WorkDetails = "Solve completed..."
monitor.EndWork()
f.write('input='+inputValue.ToString(System.Globalization.NumberFormatInfo.I
nvariantInfo))
f.close()
def reconnectJob(task, outputFilePaths):
ExtAPI.Log.WriteMessage('reconnecting job')
outputValue = None
outputFilePath = outputFilePaths[0] #I know we only have one specified
based on our definition...so work off of the first entry
f = open(outputFilePath, "r")
currLine = f.readline()
while currLine != "":
valuePair = currLine.split('=')
outputValue = System.Double.Parse(valuePair[1],
88
ANSYS ACT Migration for Legacy Workbench Customization Products
System.Globalization.NumberFormatInfo.InvariantInfo)
currLine = f.readline()
f.close()
#set output value
ExtAPI.Log.WriteMessage("Retrieved value (" + str(outputValue) + ") from
file (" + outputFilePath + ")")
if outputValue == None:
raise Exception("Error in update - no output value detected!")
else:
task.Properties["Outputs"].Properties["Output"].Value = outputValue
def getJobStatus(task, outputFiles):
ExtAPI.Log.WriteMessage('checking job status')
outputFilePath = outputFiles[0]
finished = System.IO.File.Exists(outputFilePath)
return finished
def cancelJob(task, inputFiles, outputFiles):
ExtAPI.Log.WriteMessage('performing cancellation clean up')
def status(task):
return None
def reset(task):
task.Properties["Inputs"].Properties["Input"].Value = 0
task.Properties["Outputs"].Properties["Output"].Value = 0
89
ANSYS ACT Migration for Legacy Workbench Customization Products
After selecting the task within the Project Schematic, you will see Solution Process options in the
Properties view. For Update Option, selecting Submit to Remote Solve Manager will display RSM
management properties:
90
ANSYS ACT Migration for Legacy Workbench Customization Products
On task update, you will see your task transition to the pending state while it waits for the job to
remotely execute:
91
ANSYS ACT Migration for Legacy Workbench Customization Products
When your task has processed the remote results, it will transition its state to “Up-to-Date” and the new
data will appear on the output property:
Summary
You should view ACT’s extension concept as a hook into the general processing within Workbench. This
generic hook allows you to take off-the-shelf ANSYS Workbench and customize it for your own unique
simulation needs.
For legacy External Connection Add-in projects, your migration should be straightforward and natural.
SDK projects typically exercised more nuanced behavior. Understanding the hooks exposed by ACT and
re-using your existing code will lead to a smoother transition.
Visit the ACT Resources page on the ANSYS Customer Portal for detailed ACT documentation and
Workflow templates, some of which are referenced within this migration guide. Leveraging the
Workflow-specific resources will help to ease your transition from our legacy customization products to
ANSYS ACT.
92