ACT Customization Guide For Discovery AIM
ACT Customization Guide For Discovery AIM
AIM
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 CONFID-
ENTIAL 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: 2015 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.
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
of ANSYS, Inc. and its subsidiaries and affiliates. iii
ACT Customization Guide for Discovery AIM
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
iv of ANSYS, Inc. and its subsidiaries and affiliates.
Chapter 1: Introduction
This guide assumes that you are familiar with the general ACT usage information in the ACT Developer's
Guide. This section supplies ACT usage information specific to AIM:
1.1. ACT Start Page Access
1.2. ACT App Builder Access
AIM Wizards (p. 3) describes AIM project wizards and target product wizards, which create custom
templates, guided simulations, and guided setups.
Note
• While ACT extensions for AIM support custom boundary conditions for Fluent solvers, they
do not support them for non-Fluent solvers. If you need to use custom boundary conditions
alongside the MAPDL solver, you must use ANSYS Mechanical instead of AIM.
• For information on all ACT API changes and known issues and limitations that may affect
your existing ACT extensions, see Migration Notes and Known Issues and Limitations in the
ANSYS ACT Developer's Guide.
From an AIM project or study, you access the ACT Start Page by clicking the home button and then
selecting Extensions → ACT Start Page.
AIM's Extensions menu provides options for accessing many ACT tools, which are also accessible from
the ACT Start Page itself. Once accessed, the ACT Start Page and all ACT tools are used as described
in the ANSYS ACT Developer's Guide.
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
of ANSYS, Inc. and its subsidiaries and affiliates. 1
Introduction
• From the AIM start page, in the upper right corner, click the button with the three vertical dots and
then select Open App Builder.
• From an AIM project or study, click the home button and then select Extensions → Open App
Builder.
You can also access the ACT App Builder from the ACT Start Page by clicking the Open App Builder
button.
Once started, the ACT App Builder is used to create ACT extensions, or apps, in a visual environment
as described in the ANSYS ACT Developer's Guide.
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
2 of ANSYS, Inc. and its subsidiaries and affiliates.
Chapter 2: AIM Wizards
You can use ACT to create project wizards and target product wizards for AIM.
• Project wizards for AIM are executed from AIM's Project tab. Because they sit on top of AIM rather than
being integrated within AIM, project wizards are rarely used in AIM. Consequently, coverage on project
wizards is provided at the end of this section. For more information, see AIM Project Wizards (p. 51).
• Target product wizards for AIM are implemented and executed as custom templates, guided simulations,
and guided setups.
Note
The Extension Manager is available in AIM so that you can install and load ACT extensions
that contain AIM wizards.
The custom templates and guided simulations that you have installed and loaded in AIM are available
on AIM's start page. A guided simulation has the following icon on the bottom left of its tile to differ-
entiate it from a custom template:
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
of ANSYS, Inc. and its subsidiaries and affiliates. 3
AIM Wizards
The guided setups that you have installed and loaded in AIM appear in the Guide Me context (right-
click) menu when a compatible object and geometry entity are selected. The Guide Me menu is present
only if the object and geometry selection to which you’ve navigated matches the object or task and
geometry selection defined in the extension.
All custom templates that are installed and loaded in AIM are available on the start page. The following
figure displays both property-level and step-level help for the ANSYS- installed Structural template.
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
4 of ANSYS, Inc. and its subsidiaries and affiliates.
Guided Simulations
If you have created help for a custom template, the following occurs when the custom template is ex-
ecuted:
• Step-level help is shown in AIM's context-sensitive help panel. A double arrow icon switches between hiding
and displaying the panel. When the step-level panel is hidden, you can also click the question mark icon in
the step's header to display it.
Note
After moving to a different step, you must click the question mark icon in the header of
the step to refresh the step-level help panel with the appropriate content.
• Property-level help is shown only when you click the question mark icon that appears when you place the
mouse cursor over a property.
Extension examples for custom templates are supplied. For more information, see Custom Template
Examples (p. 37).
When you start a guided simulation, the view panel immediately displays a Guided Simulation tab
with all steps in the workflow. You do not have to complete the steps in a guided simulation sequentially.
Clicking any step in the Guided Simulation tab makes the step active in the data panel. Using this tab,
you can navigate to the various steps, supplying appropriate data and updating as necessary.
You can view the state of the active step in the data panel. You can view the states of all steps in the
Guided Simulation tab. If a step is disabled during execution, it is removed from this tab.
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
of ANSYS, Inc. and its subsidiaries and affiliates. 5
AIM Wizards
An extension example for a guided simulation is supplied. For more information, see Guided Simulation
Example (p. 45).
The Attention required state is tied to the current callback <isValid> to determine if the data
supplied for the step is valid. A step in this state has one or more fields that require your attention
before the step can be updated. The step cannot be updated if any previous step requires attention.
The Up-to-date state indicates that the callback <onUpdate> for the step has been executed and
that no change was made to this step or any previous step.
The Out-of-date state indicates that the step has been modified after an update and an update is
once again required. An up-to-date step becomes out-of-date if the data for a previous step is changed.
When an out-of-date step is active in the data panel, you click either the update icon or Update
button to execute the callback <onUpdate> for the step. Both the icon and button are blue when
the step requires an update. In a guided simulation, the update of a step invokes the callback
<onUpdate> for all previous steps that need to be updated.
Unlike a simulation template, a guided simulation is not dismissed when the last step is executed.
Unless you close a guided simulation, you can go back to any step and make changes and update
multiple times.
Currently, only one guided simulation or simulation template can be open at a time. If you attempt
to start another, a dialog box opens, indicating the name of the one that is already running. You can
choose to either close the running instance or let it remain running.
If you choose to close a guided simulation and then start it again later, the last created data is restored.
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
6 of ANSYS, Inc. and its subsidiaries and affiliates.
Guided Setups
• Data supplied in a guided simulation is persisted, which is not the case for a simulation template. Each
time you start a simulation template, a new instance is opened, which means that no previously created
data is restored. Each time you start a guided simulation, the same instance is opened, even after
closing and then resuming a project. Because your choices are saved with the project, AIM always
populates the guided simulation with your last choices.
• A guided simulation uses the Next and Back buttons in the data panel only for navigation through
the steps. These buttons are not tied to the execution of callbacks as they are in a simulation template.
Because the steps in a guided simulation do not have to be completed sequentially, you can navigate
to any step, regardless of its state.
– If you click Close, a dialog box opens, asking you to confirm that you want to close the guided
simulation. Because steps in a guided simulation do not have to be completed sequentially, the last
step does not have a Finish button.
– When you click the update icon or Update button for an out-of-date step in the data panel, the
callback <onUpdate> for the step is invoked. When the update of a step is invoked, the callback
<onUpdate> for any previous step that is out-of-date is executed before the update of the current
step. If any previous step requires attention, the Update button is not shown.
• In the Guided Simulation tab in the view panel, each step has a context menu with a command for
executing the callback <onUpdate>. If the callback <IsReset> is implemented for the step, the
context menu also includes a command for resetting the step. However, the reset of a step does not
invoke the callback <IsReset> for previous steps.
• When you start working on a guided simulation, the Workflow tab in the view panel disappears.
To see the internal name of a task, task group, or object, you place the mouse cursor in the upper left
corner of the data panel. The resulting tooltip displays this information. In the following figure, the
tooltip shows the task group has an internal name of Physics Solution
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
of ANSYS, Inc. and its subsidiaries and affiliates. 7
AIM Wizards
Example 1
<wizard name="Test1" caption = "Test1" version="1" context="Study" subcontext = "Physics Solution/Face" icon="Term
When AIM is displaying a task group of type Physics Solution, the template is shown in the Guide
Me context menu for the selected face.
Example 2
<wizard name="Test1" caption = "Test1" version="1" context="Study" subcontext = "Support/Face" icon="Terminal" per
When AIM is displaying an object of type Support, the template is shown in the Guide Me context
menu for the selected face.
Example 3
<wizard name="Test1" caption = "Test1" version="1" context="Study" subcontext = "Face" icon="Terminal" persistent=
Regardless of the type of task, task group, or object that AIM is displaying, the template is shown in
the Guide Me context menu for the selected face.
Example 4
<wizard name="Test1" caption = "Test1" version="1" context="Study" subcontext = "Meshing" icon="Terminal" persiste
The template is shown in the Guide Me content menu for the selected meshing task.
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
8 of ANSYS, Inc. and its subsidiaries and affiliates.
Helpful Wizard Creation Information
Summary
As you can see by the first two code examples, a forward slash (/) in the attribute subcontext identifies
a task, task group, or object before the slash and an object type after the slash. Object types include
Vertex, Edge, Face, and Body.
The second and third code examples demonstrate how you can enter a string for matching only a
particular type of task, task group, or object.
The following topics provides AIM-specific information about defining step callbacks:
2.5.1.1. Defining Step Callbacks
2.5.1.2. Enabling and Disabling Steps
2.5.1.3. Controlling Long-Running Callbacks
For information on defining properties and their callbacks, see Property Definition (p. 15). For general
information about wizard creation, see Simulation Wizards in the ANSYS ACT Developer’s Guide.
• The callback <oninit> is invoked when the custom template or guided simulation is started. This
callback should include commands that need to be executed only once to initialize the step.
• The callback <onrefresh> is invoked every time that the step is visited, before displaying the step
properties in AIM. For example, this callback can contain actions that change or refresh some property
options. This is necessary if the options depend on properties of other steps that might have changed
after the step was visited.
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
of ANSYS, Inc. and its subsidiaries and affiliates. 9
AIM Wizards
• The callback <onupdate> is used to perform actions that bring the step to an up-to-date state. This
action is invoked differently in guided simulations versus custom templates.
– For guided simulations, the Update button is available where the step properties appear. Addition-
ally, in the step representation of the workflow, the right-click menu provides an Update option.
If any step upstream of the given step is out-of-date, the step’s callback <onupdate> executes
the update of out-of-date steps that are upstream before executing its own update. The Update
option is disabled if the step state is already up-to-date or if the state of the step, or any upstream
step, is Attention Required.
– For custom templates, there is no display of step state and no button for invoking the update. In-
stead, the callback <onupdate> is executed when you click Next to navigate to the next step.
The Next button is disabled when any step property is in an invalid state. If you navigate through
the steps, you must make sure that the callback <onupdate> does not execute any duplicate
action.
Each step in a custom template or a guided simulation must define the callback <onupdate>.
You should define an empty callback for steps that do not perform any action.
• The callback <oncreate> is relevant only to guided simulations. If defined, it is used the first time
that a step is updated. Subsequent updates of the step invoke the callback <onupdate>. Typically
the first time that you initiate a step update, you must create the AIM objects for the step’s properties
in the IronPython script. This is the purpose of the callback <oncreate>. After the first update, you
must update object properties but not create new properties. This is the purpose of the callback
<onupdate>. You should also know that when you close and reopen a guided simulation, AIM
keeps track of whether an update was previously executed. Consequently, once the callback <oncre-
ate> is invoked, it is not invoked again. Again, the callback <oncreate> is invoked only on the
first update. The callback <onupdate> is invoked for every other update.
• The callback <onreset> is typically used to remove AIM data created in another callback. This action
is invoked differently in guided simulations versus custom templates.
– For guided simulations, the callback <onreset> can be invoked by right-clicking the step repres-
entation of the workflow and selecting Reset. This option is visible only if the callback <onreset>
has been defined in the XML file.
– For custom templates, the callback <onreset> is invoked when Back is clicked. The step must
define this callback for the Back button to display. If it is not defined, a Cancel button displays in-
stead. Clicking Cancel terminates the template execution. Although the callback <onreset>
must be defined to enable navigating back to the previous step, you can define an empty callback
if you don’t want the data for this previous step to be deleted when Back is clicked. As noted
earlier, clicking Next invokes an update. Consequently, you must ensure that no duplicate action
is executed if the callback <onreset> does not delete the data.
The following code samples provide a simple example of using the callbacks <oncreate> (first update
and object creation), <onupdate> (update of existing object properties), and <onreset> (deletion
of objects).
XML Definition
<step name="Inlet1" caption = "Inlet definition" version = "1" icon = "cht-header">
<description></description>
<property name="Location" caption="Inlet location" control="scoping" >
</property>
<property name = "VelocityMagnitude" caption = "Velocity Magnitude" control="float" unit="Velocity">
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
10 of ANSYS, Inc. and its subsidiaries and affiliates.
Helpful Wizard Creation Information
</property>
<callbacks>
<oncreate>stepFirstUpdate</oncreate>
<onupdate>stepUpdate</onupdate>
<onreset>stepReset</onreset>
</callbacks>
</step>
def stepUpdate(step):
system1 = GetSystem(Name="Study")
study1 = system1.GetContainer(ComponentName="Study")
#Retrieves the inlet name from the step attributes
inletName = inletStep.Properties.Attributes["inletName"]
#Retrieves the object by its name
inletCondition = study1.GetBoundary(Name=inletName)
#Assign properties
inletCondition.Location = inletLocation
inletCondition.Flow.Option = "Velocity"
inletCondition.Flow.Velocity.Magnitude = inletStep.Properties["VelocityMagnitude"].Value
def stepReset(step):
system1 = GetSystem(Name="Study")
study1 = system1.GetContainer(ComponentName="Study")
#Retrieves the inlet name from the step attributes
inletName = inletStep.Properties.Attributes["inletName"]
#Retrieves the object by its name
inletCondition = study1.GetBoundary(Name=inletName)
#Delete Object
Study.Delete(Items=[inletCondition1])
All steps are enabled by default. To disable a step, in the XML file, you must set the attribute enabled
to false:
<step name="Step1" caption="Step 1" version="1" enabled="false">
While the step definition specifies whether a step is displayed initially, workflow flexibility is achieved
by dynamically changing this setting in a function definition. You can achieve this in any callback for
a step or a property by setting step.IsEnabled to True or False:
def mycallback(step, prop):
step.IsEnabled = False
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
of ANSYS, Inc. and its subsidiaries and affiliates. 11
AIM Wizards
You can also access a specific step by name using the function getStepByName, which is described
in Accessing Properties and Their Values (p. 16).
This very simple example defines two Boolean properties in Step 1, which control the visibility of
the two subsequent steps (Step 2 and Step 3). The disabling or enabling of Step 2 and Step
3 is performed as part of the callback <onupdate> for Step 1.
XML Definition
<step name="Step1" caption="Step 1" version="1">
<property name="DisableStep2" caption="Disable Step 2" control="boolean" default = "false"/>
<property name="DisableStep3" caption="Disable Step 3" control="boolean" default = "false"/>
<callbacks>
<onupdate>updateStep1</onupdate>
</callbacks>
</step>
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
12 of ANSYS, Inc. and its subsidiaries and affiliates.
Helpful Wizard Creation Information
This more complex example goes through a number of identical steps, such as steps that each define
a given boundary condition. You use such code when you don’t know beforehand how many steps
will be necessary. While dynamic addition of steps is currently not possible, you can use step disabling
to achieve this objective.
Consider a workflow that allows you to define a variable number of inlet boundary conditions. You
must choose the maximum number allowed and then provide definitions for all of these steps in
the XML file.
In the first step, you define a property in which you can dynamically choose the number of inlets,
up to the maximum number allowed. This information is used to decide which of the following steps
to disable.
XML Definition
<step name="Inlet1" caption = "Inlet definition" version = "1" icon = "cht-header">
<description></description>
<property name="NumberOfInlets" caption="Number of inlets" control="select" default="1">
<attributes options="1,2,3,4,5" />
<callbacks>
<onvalidate>validateNumberOfInlets</onvalidate>
</callbacks>
</property>
<property name="Location" caption="Inlet location" control="scoping" >
</property>
<property name = "VelocityMagnitude" caption = "Velocity Magnitude" control="float" unit="Velocity">
</property>
<callbacks>
<onrefresh>refreshNumberOfInlets</onrefresh>
<oncreate>stepFirstUpdate</oncreate>
<onupdate>stepUpdate</onupdate>
<onreset>stepReset</onreset>
</callbacks>
</step>
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
of ANSYS, Inc. and its subsidiaries and affiliates. 13
AIM Wizards
• The callback <oninit> when the page is first visited to display the number of steps corresponding
to the initial (default) value
• The callback <onvalidate> for the property NumberOfInlets, where you set the desired
number of inlets
def initializeNumberOfInlets(step):
numberOfInlets = int(step.Properties["NumberOfInlets"].Value)
disableSteps(step, numberOfInlets)
For such a case, you might want to have some level of control on the long-running operation, such
as being able to:
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
14 of ANSYS, Inc. and its subsidiaries and affiliates.
Helpful Wizard Creation Information
• Interrupt the operation when the solution is not converging or you want to adjust the values of some
properties
When the callback <onupdate> specifies that it can be interrupted, AIM displays the interrupt icon.
When you click this icon, AIM ends the execution as soon as the next stopping point is reached. The
exact point at which the execution stops depends on the underlying operation that is being executed.
For example, the stopping point could be after execution of an iteration for a fluid solver or after
the update for a task. If no good stopping point is found, the execution continues until completion.
Specifying that an update can be interrupted prevents AIM from journaling the actions that are ex-
ecuted in the update callback. If you want actions to be recorded in a journal, you should not set
the attribute caninterrupt to true.
step.UpdateProgressInformation(25)
#Solve execution (60% of the time)
...
step.UpdateProgressInformation(65)
#Results evaluation (5% of the time)
.....
step.UpdateProgressInformation(5)
Setting a value of 100 before the completion of the update results in inaccurate information being
displayed in the progress bar. However, such an action has no effect on the actual completion of
the update callback.
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
of ANSYS, Inc. and its subsidiaries and affiliates. 15
AIM Wizards
• For a Boolean property, you must provide a default value for the property for it to display in AIM.
• For all other property types, AIM displays the error message Input required if you do not provide a
default value, even when leaving the default blank is a legitimate choice. You must enter a value to
make the property valid.
• For a multi-select property, if you do not want a default value selected, you must include de-
fault=“” in the property definition. Setting the attribute default to an empty string value ensures
that Input required is not shown.
• For a float property, if a unit is specified, the default value should be a string in the form "value [
unit ]".
You can also use the call step.Properties to access properties from a step-specific callback, such
as an update, that is passed only the step information.
In the XML code in the previous topic, callbacks invoke the following property definitions in the
IronPython script:
def myPropertyCallback(step, prop):
value = prop.Value # returns "Option A"
properties = step.Properties
intProp = properties["IntProp"]
def myUpdateCallback():
properties = step.Properties
boolProp = properties["BoolProp"]
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
16 of ANSYS, Inc. and its subsidiaries and affiliates.
Helpful Wizard Creation Information
In some cases, it is possible that a callback for a step or a property within a step must access inform-
ation about properties in a different step. Using the utility function getStepByName, you can access
a step by specifying the step name that is defined in the XML file:
def getStepByName(currentStep, stepName):
for step in currentStep.Wizard.Steps:
if step.Key == stepName:
return step.Value
return None
For example, you can access the properties for a step within the update callback of a different step:
def updateStep():
properties = step.Properties
step2 = getStepByName(step, "Step2")
step2Properties = step2.Properties
To access the value of a property, you use prop.Value. The type returned by prop.Value is often,
but not always, a string that can be converted to a different variable type if needed:
def updateStep(step, prop):
properties = step.Properties
intProp = properties["IntProp"]
intPropValue = int(intProp.Value) #returns 1
boolProp = properties["BoolProp"]
boolPropValue = bool(boolProp.Value) #returns False
Float Properties
For a float property:
• prop.Value returns a float value that contains the value of the property without need of conversion.
• prop.ValueString returns a string that contains the float value and the unit in which the property
is defined.
• For a select property, prop.Value is a string that contains the single value selected.
• For a multi-select property, prop.Value is a list that contains one or more values selected.
Sample code follows for both a select property and multi-select property:
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
of ANSYS, Inc. and its subsidiaries and affiliates. 17
AIM Wizards
Scoping Properties
For a scoping property, prop.Value can be used to access LocationSet, which defines the field
JournalString. This field contains the string identifiers for the entities that have been associated
with the scoping property.
In the following definition, the visibility of the property InletVelocity is based on the value of
the property FlowSpecification, which specifies the type of boundary condition to apply to a
given location.
XML Definition
<property name="FlowSpecification" caption="Flow specification" control="select" default="Velocity">
<attributes readonly-options="" options = "Velocity,Pressure,Mass flow"/>
</property>
<property name = "VelocityMagnitude" caption = "Velocity Magnitude" control="float" unit="Velocity">
<callbacks>
<isVisible>isVelocityVisible</isVisible>
</callbacks>
</property>
The XML definition assumes that the properties FlowSpecification and VelocityMagnitude
are defined in the same step. The callback obtains the value of the property FlowSpecification
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
18 of ANSYS, Inc. and its subsidiaries and affiliates.
Helpful Wizard Creation Information
from the IronPython script and then checks its value to determine the visibility of the property Ve-
locityMagnitude.
In a more complex scenario, you can specify the visibility of a property by the value of the property
defined in a different step. Two options are possible:
• Use a global variable to store the value of the property that determines visibility. You must define
the global variable in another callback before its use:
def isVelocityVisible(step, prop):
global flowSpecification
return flowSpecification == "Velocity"
• Access the step where the property FlowSpecification is defined and obtain the property
value. To accomplish this, you use the utility function getStepByName, which is described in the
previous topic, to retrieve the property and its value:
def isVelocityVisible(step, prop):
specificationStep = getStepByname(step, "SpeficationStep")
flowSpecification = specificationStep.Properties["FlowSpecification"].Value
return flowSpecification == "Velocity"
Note
The use of global variables is often a quick solution that works well for wizards used
as AIM custom templates. However, for guided simulations, the use of global variables
is discouraged because global variables are no longer defined when a guided simu-
lation is closed and reopened in a different session.
• Determine whether a property is valid depending upon dynamic manipulation of property options
The following code samples show how the callback can flag an error or display a message when
validating a property.
XML Definition
<property name="Bodies" caption="Bodies forming fluid region 1" control="scoping" >
<callbacks>
<isValid>isBodySelectionValid</isValid>
</callbacks>
</property>
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
of ANSYS, Inc. and its subsidiaries and affiliates. 19
AIM Wizards
In this function definition, the callback <isValid> validates whether the value selected for a
scoping control corresponds to an entity of type Body. If the selection corresponds to a different
type, an error message displays for the property, and the property is marked as invalid.
def isBodySelectionValid(step, prop):
if step.Properties["Bodies"].Value == None:
return False
locationSet = step.Properties["Bodies"].Value.LocationSet
model = Study.GetCurrentModelForExtension()
selectionTypes = Study.GetGeometryReferenceTypes(LocationSet = locationSet, Model = model)
if len(selectionTypes) > 1 or str(selectionTypes[0]).find("Body") < 0:
prop.StateMessage = "Invalid selection"
return False
return True
In this function definition, the callback <isValid> validates a custom property that represents a
material. If Unknown is selected, a warning message displays, indicating that additional steps must
be taken in AIM.
def isMaterialValid(step, prop):
prop.StateMessage = ""
if prop.Value == "Unknown":
prop.StateMessageType = StateMessageTypes.Information
prop.StateMessage = "You will need to visit the Material Assignments page to select the material."
if prop.Value == "":
prop.StateMessageType = StateMessageTypes.Error
prop.StateMessage = "Input required"
return False
return True
Note
AIM provides a built-in check when the value of a property is undefined. However,
a callback must implement a check if it overrides the built-in validation.
• The callback <onValidate> is invoked only when the value of the property for which it is defined
is modified. Inside the callback, other properties can be defined or some actions can be invoked in
AIM in response to the property change.
• The callbacks <isValid> and <isVisible> should be considered as "queries" that check only
the validity or visibility of a property. You do not want to use them to change the value of the
property for which they are defined or the value of any other property. You also should not use
them to invoke AIM user interface actions because these callbacks are invoked multiple times. Using
them to perform any change or action could result in subtle errors, often difficult to diagnose.
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
20 of ANSYS, Inc. and its subsidiaries and affiliates.
Helpful Wizard Creation Information
XML Definition
<property name="ScopingProp" caption="Scoping property" control="scoping" />
<property name="MultiSelectProp" caption="Multi Select Property" control="multiselect" default="Option A,Opt
<attributes readonly-options="Option C" options="Option A,Option B,Option C" />
</property>
In addition to accessing the property value, you can access and possibly modify options that are
available in AIM. To access and modify a list with the possible values for a property, you use
prop.Options.
You can also define options for a property as read-only, which means that they are visible in AIM but
are grayed out, indicating that values cannot be set. The following function definition shows how to
access options for a property. The options are a comma-separated string that you modify to specify
which options are read-only. Read-only options can also be accessed as a comma-separated string
within the IronPython callback.
The options and read-only options defined for the property in the XML file are initial values. You can
use callbacks to dynamically update options, which provides great flexibility for displaying choices
that cannot be statically defined in the XML file.
For example, assume that you want to define a property that allows selection of any of the available
tasks for a given type, such as Geometry.
XML Definition
In the XML file, the options should initially contain an empty string, and no default should be assigned
to the property:
<property name ="GeometryTasks" caption="Task containing geometry" control="select">
<attributes options=""/>
The property options can be filled in by one of the callbacks defined for the step. For example, the
options can be filled in by the callback <refresh> for the step. The callback <refresh> is invoked
when the step is visited to ensure that the list is correctly populated.
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
of ANSYS, Inc. and its subsidiaries and affiliates. 21
AIM Wizards
lastValue = None
for geom in getGeometryTasks():
prop.Options.Add(geom.DisplayText) #add the display text for the task to the option list
lastValue = geom.DisplayText
if prop.ValueString == "" and lastValue != None:
prop.Value = lastValue #if populate the value of the property with the last assigned value
geometryTasks = []
for task in Study.GetAllTasksInProject():
taskIdentifier = task.Container.Name #We use the container since the type is always Task
if taskIdentifier.Contains(modelingTaskIdentifier) or taskIdentifier.Contains(importTaskIdentifier)
geometryTasks.append(task)
return geometryTask
Another situation where dynamic manipulation of options is used involves removing one of the options,
or graying it out so that is visible but not available for selection.
For example, assume that a multi-select property defines options for selecting source terms for different
equations: three momentum sources, plus energy. A separate Boolean variable controls whether to
solve for the energy equation. The source term for energy is not applicable if the energy equation is
not solved.
XML Definition
<property name="SourceTerms" caption="Source terms" control="multiselect" default="">
<attributes readonly-options="" options="Momentum X,Momentum Y,Momentum Z,Energy" />
</property>
The callback <onvalidate> invokes the function validateEnergy, which provides the following
functionality:
• Removes the selection Energy (if present) from the list of values for the property Sources when
the value for the property IncludeEnergy is False.
• Stores the user-selected choice in a global variable so that it can be restored if the energy equation
is re-enabled.
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
22 of ANSYS, Inc. and its subsidiaries and affiliates.
Helpful Wizard Creation Information
if energySelected:
sourcePropertyValue.Add("Energy")
Note
The function validateEnergy should also be executed when the step is refreshed
to ensure that the values are consistent before visiting the step.
AIM groups the tasks Physics Definition and Solve Physics together into the task group
Physics Solution. However, the association between the data model and the tasks is done using
the tasks that are part of the task group.
To query the list of task groups that are present in the project, you use this query:
Study.GetAllTaskGroupsInProject()
To get the list of the tasks contained in the task group, you use the query GetTasks, which is invoked
using taskGroup:
taskGroup = Study.GetAllTaskGroupsInProject()[0] #gets the first task group
tasksForGroup = taskGroup.GetTasks() #gets the task for the group
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
of ANSYS, Inc. and its subsidiaries and affiliates. 23
AIM Wizards
To get the task or task group by its visible name, you use its property DisplayText as shown in
the utility functions getTaskByName and getTaskGroupByName, which you can add to your
Python script:
def getTaskByName(displayText):
for task in Study.GetAllTasksInProject():
If task.DisplayText == displayText:
return task
return None
def getTaskGroupByName(displayText):
for taskGroup in Study.GetAllTaskGroupsInProject():
If taskGroup.DisplayText == displayText:
return taskGroup
return None
In addition to the task that AIM displays, scripting uses two other objects to represent AIM tasks: task
component and task object. The following topics explain all three task-related objects:
2.5.3.1.1. Task
AIM displays objects of type Task. You can use these objects as a starting point to navigate through
other objects. You can also use them to query for other objects that are related to a task, such as
physics regions, structural, flow, or electromagnetic conditions. For more information, see Retrieving
Objects (p. 29).
In AIM scripts, you use a task component as an argument to a function that relates to task depend-
encies:
Note
As an AIM user, you never need to interact with task component objects. However, if you
access the Project tab, you can see them represented in the Project Schematic. They
are the objects that compose the system named Study.
A task component is the return argument of the command CreateTask. Consider the following
example:
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
24 of ANSYS, Inc. and its subsidiaries and affiliates.
Helpful Wizard Creation Information
system1 = GetSystem(Name="Study")
meshingComponent = Study.CreateTask(
Type="Meshing",
System=system1,
Input=geometryTaskComponent)
The command CreateTask creates a meshing task. The required arguments are the system (Study)
to which the component belongs and the task component upstream of the meshing component (in
this case a geometry task).
While the return argument of the command CreateTask is a task component, internally a task
and task object are also created.
To invoke the update of the task, you use the object meshingComponent:
meshingComponent.Update()
To access the task component for this task, you use the query GetComponentReference:
taskComponent = task.GetComponentReference()
To access the task object from either the task or task component, you use the function GetTaskOb-
ject:
taskObject = task.GetTaskObject()
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
of ANSYS, Inc. and its subsidiaries and affiliates. 25
AIM Wizards
taskObject = taskComponent.GetTaskObject()
XML Definition
<step name="CreateWorkflowFromGeometry" caption="Create Workflow From Geometry: Model" version="1">
<property name ="GeometryTasks" caption="Task containing geometry" control="select">
<attributes options=""/>
</property>
<callbacks>
<onrefresh>refreshGeometryOptions</onrefresh>
<onupdate>createStructuralSimulationProcess</onupdate>
</callbacks>
</step>
def getGeometryTasks():
modelingTaskIdentifier = "Geometry Modeling"
importTaskIdentifier = "Import"
geometryTasks = []
for task in Study.GetAllTasksInProject():
taskIdentifier = task.Container.Name #We use the container since the type is always Task
if taskIdentifier.Contains(modelingTaskIdentifier) or taskIdentifier.Contains(importTaskIdentifier):
geometryTasks.append(task)
return geometryTasks
def createStructuralSimulationProcess(step):
#Retrieves the user input
geometryTaskName = step.Properties["GeometryTasks"].Value
#Retrieves the Task from its name
geometryTask = getTaskByName(geometryTaskName)
#Retrieves the component reference from the task
geometryComponent = geometryTask.GetComponentReference()
system1 = GetSystem(Name="Study")
#Creates mesh task
meshingComponent = Study.CreateTask(
Type="Meshing",
System=system1,
Input=geometryComponent)
meshingTaskObject = meshingComponent.GetTaskObject()
meshingTaskObject.EngineeringIntent = "StructuralOrThermalOrElectricConduction"
meshingComponent.Refresh()
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
26 of ANSYS, Inc. and its subsidiaries and affiliates.
Helpful Wizard Creation Information
physicsDefinition = physicsDefinitionComponent.GetTaskObject()
physicsDefinition.CalculationType = "Static"
Other optional arguments depend on the specific object being created. They are used to set the
properties of the object.
For a specific object, the easiest way to obtain the information for the command CreateEntity
is to create the object in AIM and then look at what is recorded in the AIM journal.
While most of the information is object-specific, there are some general guidelines of which you
should be aware:
• In AIM, you can obtain the type of a given object by visiting the page where the object properties
are displayed and hovering the mouse cursor next to the image for the object.
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
of ANSYS, Inc. and its subsidiaries and affiliates. 27
AIM Wizards
• For the majority of objects, the parent to use for the association is the task object corresponding to
the task for which the object is created:
physicsRegion = study1.CreateEntity(
Type="PhysicsRegion",
Association=physicsDefinition)
physicsRegion.PhysicsType = "Structural"
materialAssignment1 = study1.CreateEntity(
Type="MaterialAssignment",
Association=physicsDefinition)
• For objects created from a task for fluid flow simulation, objects associated with the task object in-
clude physics region, solver settings, and material assignment. The majority of the other objects,
such as fluid condition, interface conditions, and numerical controls, are specific to a given physics
region. Thus, they are associated with the appropriate physics region:
physicsRegion1 = study1.CreateEntity(
Type="PhysicsRegion",
Association=physicsDefinition)
physicsRegion1.PhysicsType = "Fluid"
materialAssignment2 = study1.CreateEntity(
Type="MaterialAssignment",
Association=physicsDefinition)
inletCondition1 = study1.CreateEntity(
Type="InletBoundary",
Association=physicsRegion1)
• Deleting the parent object results in the deletion of all the objects associated with it. For example,
deleting a physics region in a flow task also deletes all fluid flow conditions associated with this region.
You can gather the arguments that set the properties of the object by looking at the object properties
in the Discovery AIM and Workbench Scripting Guide. Because the arguments are optional, they don’t
need to be specified during object creation. They can be set from the object returned from the
command CreateEntity:
inletCondition2 = study1.CreateEntity(
Type="InletBoundary",
Association=physicsRegion1) #creates an inlet object
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
28 of ANSYS, Inc. and its subsidiaries and affiliates.
Helpful Wizard Creation Information
While properties are specific to a given object, the following information is common to all objects:
• Name. A unique name that AIM assigns to the object for internal use. You cannot change the name.
You can see the name and object type in AIM by hovering the mouse cursor next to the image for
the object.
• DisplayText. The user-defined and editable name that AIM is to display for the object.
• Type. The type of object. To gather this information, you should use the query
Study.GetEntityType(Entity=object). You should not use object.Type because it
returns an internal type that can be different from the one that AIM displays.
For example, the following query returns all objects of the type Support:
Study.GetAllObjectOfType(Type = "Support")
If you have multiple simulation processes in your projects, you might need to access only the objects
associated with one of the tasks in your simulation process. In this case, you can invoke the query
GetAllObjectsOfType from the task of interest to get these objects.
Assume that you have two Physics Solution task groups with assigned display texts of
Physics 1 and Physics 2 and you want to get the support objects for only the first task group.
Because the support objects are associated with the physics definition task of your task group, you
first need to access the task from the task group list:
taskGroup = getTaskGroupByName("Physics 1")
task = taskGroup.GetTasks()[0] #physics definition task is the first task of the group
supports = task.GetObjectsOfType(Type="Support") #gets the support for a given type
Note
Although internally the support objects are associated with the taskObject, you can
directly use the task or task group that you see in AIM to query the information.
Another common scenario related to object query is the need to query one specific object. You can
use the query GetObjectOfTypeAndName for this purpose. The arguments of the query are Type
and Name for the object that you want to query. If you want to query using DisplayText rather
than the internal name, you should add "@" to the string that represents the DisplayText.
The following query retrieves an object of type Support with DisplayText set to BeamSupport:
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
of ANSYS, Inc. and its subsidiaries and affiliates. 29
AIM Wizards
Because the display text does not have to be unique, if multiple objects with the same display text
exist, the query returns the first one that is found. If you want to query the object by its unique
name, you should not add "@" to the string representing the name:
Study.GetObjectsOfTypeAndName(Type = "Support", Name="Support 2")
Again, to see the unique internal name, you hover the mouse cursor over the object in AIM.
To simplify the syntax of the query that searches an object by type, you can also use auto-generated
queries that explicitly contain the type of the object for which you are querying:
system1 = GetSystem(Name="Study")
study1 = system1.GetContainer(ComponentName="Study")
study1.GetSupport(Name="@BeamSupport")
study1.GetSupport(Name="@BeamSupport")
However, the automatically generated query should be explicitly invoked on the variable study1
as demonstrated earlier.
The same logic applies to all types. For the type SelectionSet, the following two queries obtain
an object selectionSet named supportFaces:
Study.GetObjectsOfTypeAndName(Type = "SelectionSet", Name="@supportFaces")
study1.GetSelectionSet(Name="@supportFaces")
Because you can make changes after a guided simulation is closed, you need to pay special attention
to how you create and access objects in your callbacks. Specifically, you need to ensure that:
• Your callbacks create objects in the AIM data model the first time that they are executed, but that
they do not duplicate object creation when you modify your inputs.
• You store the information about the objects that you created so you can retrieve them and modify
their properties.
The easiest way to separate object creation from object modification is to define a callback <oncre-
ate> in addition to a callback <onupdate> as described in Defining Step Callbacks (p. 9). Because
the callback <oncreate> is invoked only once, you use it to create the AIM objects for the step’s
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
30 of ANSYS, Inc. and its subsidiaries and affiliates.
Helpful Wizard Creation Information
properties. After the first update, when you need to update existing object properties but not create
new properties, you use the callback <onupdate>.
Using step.Attributes is a convenient way to store and retrieve an object. In it, you can store
the name of the object and use the methods described in Retrieving Objects (p. 29) to access the
created object:
#In the oncreate callback, create a physics region and store the name of the object
physicsRegion = study1.CreateEntity(
Type="PhysicsRegion",
Association=physicsDefinition)
physicsRegion.PhysicsType = "Structural"
physicsRegion.Location=["BODY1"]
step.Attributes["fluidPhysicsRegionName"] = fluidPhysicsRegion.Name
#in the onupdate callback, retrieve the physics region and modify its properties
physicsRegionName = step.Attributes["fluidPhysicsRegionName"]
system1 = GetSystem(Name="Study")
study1 = system1.GetContainer(ComponentName="Study")
physicsRegion = Study.GetPhysicsRegion(Name=physicsRegionName)
physicsRegion.Location=["BODY2"]
For the case where you need to save a taskComponent, you can include in your IronPython script
the utility function getComponentByName to retrieve it:
#In the oncreate callback, create a meshing task. meshingComponent is the return argument
meshingComponent = Study.CreateTask(
Type="Meshing",
System=system1,
Input=geometryComponent)
step.Attributes["meshingComponentName"] = meshingComponent .Name
def getCompomentByName(componentName):
#componentName = component.Name
for component in GetSystem(Name="Study").Components:
if component .Name == componentName:
return component
return None
While interface actions are equivalent to commands from a syntax standpoint, they are executed behind
the scenes in a different way. Commands provide the ability to directly manipulate data. Interface actions
are requests to the AIM interface to perform certain actions. The AIM interface processes and queues
the requests and then executes them at the proper time.
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
of ANSYS, Inc. and its subsidiaries and affiliates. 31
AIM Wizards
XML Definition
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
32 of ANSYS, Inc. and its subsidiaries and affiliates.
Helpful Wizard Creation Information
resultsEvaluationComponent1 = Study.CreateTask(
Type="Results Evaluation",
System=system1,
Input=solvePhysicsComponent1)
AddSourceToComponentInSystem(
SourceComponent=physicsDefinitionComponent1,
TargetComponent=resultsEvaluationComponent1)
resultsEvaluationComponent1.Refresh()
results1 = resultsEvaluationComponent1.GetTaskObject()
displacementMagnitude = study1.CreateEntity(
Type="ContourResult",
Association=results1)
displacementMagnitude.Variable = "Displacement.mag"
displacementMagnitude.DisplayText = "Displacement magnitude"
equivalentStress = study1.CreateEntity(
Type="ContourResult",
Association=results1)
equivalentStress.Variable = "Stress.eqv"
equivalentStress.DisplayText = "Equivalent stress"
plane1 = study1.CreateEntity(
Type="Plane",
Association=results1)
plane1.Definition.Origin.DefineBy = "Location"
plane1.Definition.Axis1.Direction.DefineBy = "Location"
fullStress = study1.CreateEntity(
Type="ContourResult",
Association=results1)
fullStress.Variable = "Stress.p1"
resultsEvaluationComponent1.Update()
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
of ANSYS, Inc. and its subsidiaries and affiliates. 33
AIM Wizards
The following code sample shows you how to hide a specific physics region. For this region, the
property Location contains a list of bodies, which is passed as the argument of HideBodies:
study1 = system1.GetContainer(ComponentName="Study")
physicsRegion = study1.GetPhysicsRegion(Name="PhysicsRegion 1")
StudyUI.HideBodies(Bodies=physicsRegion.Location)
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
34 of ANSYS, Inc. and its subsidiaries and affiliates.
Helpful Wizard Creation Information
The easiest way to provide the model information is in the callback that executes a geometry import.
As described in Controlling the Visibility for Topological Entities (p. 34), after importing a geometry,
you must make it visible in the graphics window. You add the command SetCurrentModelForEx-
tension to make AIM aware that your extension will work with this geometry model:
system1 = GetSystem(Name="Study")
importComponent = Study.CreateTask(
Type="Import",
System=system1)
importTaskObject = importComponent .GetTaskObject()
importTaskObject.ChooseImportSources(FilePaths=pathOfFileToBeImported)
importComponent.Update()
StudyUI.SetSelectionTo(Entity = importTaskObject)
model = Study.GetModelFromObject(Object=importTaskObject)
Study.SetCurrentModelForExtension(Model = model)
The next-to-last line shows how to gather the model information, based on your import task:
model = Study.GetModelFromObject(Object=importTaskObject)
Once the model is set, your custom template or guided simulation remains aware of it until the end
of its execution. For a guided simulation, you must invoke the command again when the execution
is resumed.
If you don’t associate the geometry model with your extension, some functionality in your application
will not work:
• An interface action for hiding and showing the topological entity will throw an error when the action
is invoked.
• Editing the location in AIM will not highlight the location in the graphics window.
You also need the model association if you are performing an action or query that involves geometry
information. If you use SetCurrentModelForExtension to set your model, you can use Get-
CurrentModelForExtension to retrieve this information.
The following code sample validates that the selection of a given scoping property is a body. You
can use the query GetGeometryReferenceTypes to validate the topology type. Arguments to
the query are the location set that you want to validate and the model that defines the geometry.
XML Definition
<property name="Bodies" caption="Bodies forming region" control="scoping" >
<callbacks>
<isValid>isBodySelectionValid</isValid>
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
of ANSYS, Inc. and its subsidiaries and affiliates. 35
AIM Wizards
</callbacks>
</property>
if step.Properties["Bodies"].Value == None:
return False
locationSet = step.Properties["Bodies"].Value.LocationSet
geometryDefinitionObject = meshingUpstreamTask.GetTaskObject()
model = Study.GetCurrentModelForExtension()
selectionTypes = Study.GetGeometryReferenceTypes(LocationSet = locationSet, Model = model)
if len(selectionTypes) > 1 or len(str(selectionTypes[0]).find("Body")) < 0:
prop.StateMessage = "Invalid selection"
return False
• Step-level help, which displays by default in AIM's context-sensitive help panel. If you hide this panel,
you can click the question mark icon in the step's header to display it again.
• Property-level help, which displays when you click the help button to the right of a property within
a step.
You can define both types of help for your custom wizards.
Step-Level Help
To provide custom help for wizard steps, you create HTML files that you then store in a child folder
in the extension's folder. The element <step> in the extension's XML file references the help file for
the step via the attribute helpFile. You use this attribute to reference the relative path for the
HTML file to display in the step's help panel.
In the example below, help for the step named Step1 is provided in an HTML file located in the
subfolder help for the extension:
<step name="Step1" caption="Load geometry file" version="1" context="Study" helpFile="help/StudyDemo1.html">
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
36 of ANSYS, Inc. and its subsidiaries and affiliates.
Custom Template Examples
If you give the help files for steps the same names as the steps themselves and then store these files
in a folder named help, you do not need to use the attribute helpFile to reference them. The
extension automatically finds and displays the appropriate help for each step. If, however, you give
the folder in which the help files are stored some other name, you must use the attribute helpFile
to reference the relative path.
Property-Level Help
To provide custom help for the properties that are defined within a step, you can either create HTML
files or define help text directly in the extension's XML file.
If you choose to create HTML files for properties, you can use the attribute helpfile in the element
<property> to point to the help file for this property.
If you give the help file the same name as the step and the property, separated by an underscore,
you do not need to use the attribute helpFile to explicitly reference the file. For example, assume
that MeshingStep is the step name and MeshResolution.html is the property name. The help
file for the property must be named MeshingStep_MeshResolution.html.
If you prefer to define the content for property-level help in the extension's XML file you use the
element <help> to define the text to display. Examples follow for properties named Geometry and
nAnalysis.
<property name="Geometry" caption="Geometry filename" control="fileopen" default="ANSYSInputs"> <help>The geomet
Note
When using HTML files for properties, the recommended practice is to avoid images and
to limit the text to no more than 200 characters.
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
of ANSYS, Inc. and its subsidiaries and affiliates. 37
AIM Wizards
<guid shortid="StudyDemo">150c0680-292b-4291-b46d-bac59949cd56</guid>
<interface context="Study">
<images>images</images>
</interface>
<callbacks>
<onupdate>action</onupdate>
<onreset>reset</onreset>
</callbacks>
</step>
</wizard>
</extension>
Step Definition
The wizard StudyDemo1 has only a single step named Step1. The optional attribute helpFile
sets the custom help file to display for this step.
Note
The attribute context is not used in step definitions for a target product wizard for AIM.
Callback Definition
A summary follows of the callbacks defined for this single step:
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
38 of ANSYS, Inc. and its subsidiaries and affiliates.
Custom Template Examples
• The callback <onupdate> executes the function action, which creates the AIM study.
• The callback <onreset> executes the function reset, which allows you to reset (delete) the data
created in other callbacks.
Property Definition
A summary follows of the properties defined for this single step:
• For the property Geometry, the attribute control is set to fileopen, which displays a file selection
property initialized to the default attribute value. The child element <help> indicates the text
message to display as the custom help for this property: The geometry file to import.
• For the property NAnalysis, the attribute control is set to integer, which allows the integer
value for the default attribute to be edited. The child element <help> indicates the text message
to display as the custom help for this property: The number of static structural ana-
lyses to create. You must enter an integer greater than 0.. The callback
<isvalid> invokes the function isvalid, which validates that the entered integer is not less than
1. A custom message can be displayed when the entered value fails validation.
def action(step):
global tasksToDelete,groupsToDelete
tasksToDelete = []
groupsToDelete = []
system1 = GetSystem(Name="Study")
importComponent1 = Study.CreateTask(
Type="Import",
System=system1)
tasksToDelete.Add(importComponent1)
study1 = system1.GetContainer(ComponentName="Study")
import1 = importComponent1.GetTaskObject()
geometryImportSource1 = study1.CreateEntity(
Type="GeometryImportSource",
Association=import1)
geometryImportSource1.FilePath = step.Properties["Geometry"].Value
geometryImportSource1.GenerateImportSourceOperation()
step.UpdateProgressInformation(10.)
pct = 10.
for i in range(step.Properties["NAnalysis"].Value):
meshingComponent1 = Study.CreateTask(
Type="Meshing",
System=system1,
Input=importComponent1)
tasksToDelete.Add(meshingComponent1)
meshingComponent1.Refresh()
physicsSolutionGroup1 = Study.CreateGroup(Name="Physics Solution")
groupsToDelete.Add(physicsSolutionGroup1)
physicsDefinitionComponent1 = Study.CreateTask(
Type="Physics Definition",
System=system1)
tasksToDelete.Add(physicsDefinitionComponent1)
solvePhysicsComponent1 = Study.CreateTask(
Type="Solve Physics",
System=system1)
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
of ANSYS, Inc. and its subsidiaries and affiliates. 39
AIM Wizards
tasksToDelete.Add(solvePhysicsComponent1)
physicsSolutionGroup1.Add(Component=physicsDefinitionComponent1)
physicsSolutionGroup1.Add(Component=solvePhysicsComponent1)
AddSourceToComponentInSystem(
SourceComponent=physicsDefinitionComponent1,
TargetComponent=solvePhysicsComponent1)
AddSourceToComponentInSystem(
SourceComponent=meshingComponent1,
TargetComponent=physicsDefinitionComponent1)
physicsDefinitionComponent1.Refresh()
solvePhysicsComponent1.Refresh()
physicsDefinition1 = physicsDefinitionComponent1.GetTaskObject()
physicsRegion1 = study1.CreateEntity(
Type="PhysicsRegion",
Association=physicsDefinition1)
solverSettings1 = study1.CreateEntity(
Type="SolverSettings",
Association=physicsDefinition1)
transcript1 = study1.CreateEntity(
Type="Transcript",
Association=physicsDefinition1)
physicsDefinitionComponent1.Refresh()
solvePhysicsComponent1.Refresh()
meshing1 = meshingComponent1.GetTaskObject()
meshing1.EngineeringIntent = "StructuralOrThermalOrElectricConduction"
physicsRegion1.Location = ["BODY1"]
physicsRegion1.PhysicsType = "Structural"
materialAssignment1 = study1.CreateEntity(
Type="MaterialAssignment",
Association=physicsDefinition1)
materialAssignment1.Location = ["BODY1"]
material1 = study1.CreateEntity(
Type="Material",
Association=physicsDefinition1)
material1.ImportEngineeringData(Name="Structural Steel")
materialAssignment1.Material = material1
pct += 10.
step.UpdateProgressInformation(pct)
if i==9:
raise UserErrorMessageException("My own error message.")
def reset(step):
global tasksToDelete,groupsToDelete
system1 = GetSystem(Name="Study")
for group in groupsToDelete:
Study.DeleteTaskGroup(Group=group)
for task in tasksToDelete:
task.DeleteTask(System=system1)
• The function action is the single step in the custom template. When Create Simulation is clicked,
the callback <onupdate> is invoked. It creates the Study workflow by creating and updating the
Geometry, Mesh, and Physics tasks.
• The callback <onreset> invokes the function reset, which allows you to reset (delete) the data
created in other callbacks.
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
40 of ANSYS, Inc. and its subsidiaries and affiliates.
Custom Template Examples
• The callback <isvalid> in the element <property> invokes the function isvalid, which validates
that the property value entered is not less than 1. A custom message can be displayed when the
entered value fails validation.
<interface context="Project">
<images>images</images>
</interface>
<callbacks>
<onupdate>importGeometry</onupdate>
</callbacks>
<callbacks>
<onupdate>refineMesh</onupdate>
</callbacks>
<callbacks>
<onupdate>setup</onupdate>
</callbacks>
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
of ANSYS, Inc. and its subsidiaries and affiliates. 41
AIM Wizards
<isvalid >isValid</isvalid>
</callbacks>
</property>
</step>
</extension>
Step Definition
The wizard PressureLossMultiple has four steps. The optional attribute helpFile sets the
custom help file to display for the step.
– The property geometryfile enables you to specify a geometry. You can either keep the geometry
specified by the attribute default or browse to select a different one (control="fileopen").
For this example, a geometry file named TubeSelectionSet.agdb is selected.
– The callback <onupdate> is invoked when Next is clicked. It executes the function importGeo-
metry, which imports the selected geometry and then creates the workflow in AIM. Specifically,
it creates the workflow from journal content included in the function.
• Step2: Refines the mesh for the geometry from low to high.
– The property MeshResolution enables you to set the resolution for the mesh. This property
has a default of 1 (default="1") and accepts only integer values (control="integer").
– The callback <onupdate> is invoked when Next is clicked. It executes the function refineMesh,
which creates a mesh according to the specification.
– The properties InletLocation and OutletLocation require the inlet and outlet locations
to which to apply the load (control="scoping") to be defined.
– When a value is entered for the outlet location, the callback <isvalid> is invoked. It executes
the function isValid, which verifies that the inlet and outlet locations are not the same.
– The callback <onupdate> invokes the function setup when Next is clicked. This function applies
the loads to the selected locations and performs the calculations.
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
42 of ANSYS, Inc. and its subsidiaries and affiliates.
Custom Template Examples
– The properties MaximumVelocity and PressureLoss show the calculated values in read-only
format (readonly="true").
– When Finish is clicked, the custom template closes, returning you to the analysis.
def getSelectionSetsForProject():
context = __scriptingEngine__.CommandContext
project = context.Project
containers = project.GetContainers()
dataEntity = "SelectionSet"
def importGeometry(step):
global meshingComponent1, import1, study1, results1, vectorResult1, singleValueResult1,
physicsDefinitionComponent1, resultsEvaluationComponent1, solvePhysicsComponent1, physicsRegion1,
materialAssignment1
with Transaction():
system1 = GetSystem(Name="Study")
physicsDefinitionComponent1 = Study.CreateTask( Type="Physics Definition", System=system1)
study1 = system1.GetContainer(ComponentName="Study")
physicsDefinition1 = physicsDefinitionComponent1.GetTaskObject()
physicsRegion1 = study1.CreateEntity( Type="PhysicsRegion", Association=physicsDefinition1)
solverSettings1 = study1.CreateEntity( Type="SolverSettings", Association=physicsDefinition1)
solvePhysicsComponent1 = Study.CreateTask( Type="Solve Physics", System=system1,
Input=physicsDefinitionComponent1)
solvePhysicsComponent1.Refresh()
resultsEvaluationComponent1 = Study.CreateTask( Type="Results Evaluation", System=system1,
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
of ANSYS, Inc. and its subsidiaries and affiliates. 43
AIM Wizards
Input=solvePhysicsComponent1)
resultsEvaluationComponent1.Refresh()
physicsDefinition1.CalculationType = "Static"
physicsRegion1.PhysicsType = "Fluid"
physicsRegion1.Location = "AllBodies()"
materialAssignment1 = study1.CreateEntity( Type="MaterialAssignment", Association=physicsDefinition1)
material1 = study1.CreateEntity( Type="Material", Association=physicsDefinition1)
material1.ImportEngineeringData(Name="Air")
materialAssignment1.Material = material1
materialAssignment1.Location = [physicsRegion1]
results1 = resultsEvaluationComponent1.GetTaskObject()
vectorResult1 = study1.CreateEntity( Type="VectorResult", Association=results1)
vectorResult1.Variable = "Velocity"
vectorResult1.DisplayText = "Velocity"
transcript1 = study1.CreateEntity( Type="Transcript", Association=physicsDefinition1)
transcript1.DisplayText = "Fluid Flow Output 1"
physicsSolutionGroup1 = Study.CreateGroup(Name="Physics Solution")
physicsSolutionGroup1.Add(Component=physicsDefinitionComponent1)
physicsSolutionGroup1.Add(Component=solvePhysicsComponent1)
meshingComponent1 = Study.CreateTask( Type="Meshing", System=system1, Output=physicsDefinitionComponent1
physicsDefinitionComponent1.Refresh()
solvePhysicsComponent1.Refresh()
resultsEvaluationComponent1.Refresh()
importComponent1 = Study.CreateTask( Type="Import", System=system1, Output=meshingComponent1)
meshingComponent1.Refresh()
physicsDefinitionComponent1.Refresh()
solvePhysicsComponent1.Refresh()
resultsEvaluationComponent1.Refresh()
import1 = importComponent1.GetTaskObject()
geometryImportSource1 = import1.AddGeometryImportSourceOperation()
geometryImportSource1.FilePath = step.Properties["geometryfile"].Value
importComponent1.Update(AllDependencies=True)
meshingComponent1.Refresh()
physicsDefinitionComponent1.Refresh()
solvePhysicsComponent1.Refresh()
resultsEvaluationComponent1.Refresh()
Study.ChangeModelSelectionContextTo(import1)
def refineMesh(step):
global meshingComponent1, import1, study1, results1, vectorResult1, physicsDefinitionComponent1, singleValue
resultsEvaluationComponent1, solvePhysicsComponent1, physicsRegion1
meshing1 = meshingComponent1.GetTaskObject()
meshing1.MeshResolution = step.Properties["MeshResolution"].Value
Study.ChangeModelSelectionContextTo(import1)
def setup(step):
global meshingComponent1, study1, results1, vectorResult1, physicsDefinitionComponent1, singleValueResult1,
resultsEvaluationComponent1, solvePhysicsComponent1, physicsRegion1
with Transaction():
meshing1 = meshingComponent1.GetTaskObject()
meshControlLocalInflation1 = study1.CreateEntity( Type="MeshControlLocalInflation", Association=meshing1
meshing1.EngineeringIntent = "FluidFlow"
AddSourceToComponentInSystem( SourceComponent=physicsDefinitionComponent1,
TargetComponent=resultsEvaluationComponent1)
resultsEvaluationComponent1.Refresh()
Study.Delete(Items=[meshControlLocalInflation1])
with Transaction():
meshingComponent1.Update(AllDependencies=True)
physicsDefinitionComponent1.Refresh()
solvePhysicsComponent1.Refresh()
resultsEvaluationComponent1.Refresh()
with Transaction():
inletBoundary1 = study1.CreateEntity( Type="InletBoundary", Association=physicsRegion1)
inlet_location = step.Properties["InletLocation"].Value.LocationSet
if inlet_location == None :
ExtAPI.Log.WriteMessage("inlet selection set does not exist")
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
44 of ANSYS, Inc. and its subsidiaries and affiliates.
Guided Simulation Example
inletBoundary1.Location = inlet_location
inletBoundary1.Flow.Velocity.Magnitude = step.Properties["Velocity"].DisplayString
if outlet_location == None :
ExtAPI.Log.WriteMessage("outlets selection set does not exist")
outletBoundary1.Location = outlet_location
outletBoundary1.Flow.Pressure.GaugeStaticPressure = step.Properties["GaugePressure"].DisplayString
with Transaction():
physicsDefinitionComponent1.Update(AllDependencies=True)
solvePhysicsComponent1.Update(AllDependencies=True)
resultsEvaluationComponent1.Refresh()
resultsEvaluationComponent1.Refresh()
resultsEvaluationComponent1.Update(AllDependencies=True)
vectorResult1.Legend.Coloring = "Banded"
vectorResult1.Legend.NumberOfColors = "10"
vectorResult1.Distribution = "Mesh"
vectorResult1.Evaluate()
maximum_velocity = vectorResult1.Summary.Max
step.NextStep.Properties["MaximumVelocity"].Value = maximum_velocity.ToString()
step.NextStep.Properties["PressureLoss"].Value = singleValueResult1.Value.ToString()
def solve(step):
global meshingComponent1, study1, results1, vectorResult1, physicsDefinitionComponent1,
singleValueResult1, resultsEvaluationComponent1, solvePhysicsComponent1, physicsRegion1
with Transaction():
physicsDefinitionComponent1.Update(AllDependencies=True)
solvePhysicsComponent1.Update(AllDependencies=True)
resultsEvaluationComponent1.Refresh()
resultsEvaluationComponent1.Refresh()
resultsEvaluationComponent1.Update(AllDependencies=True)
vectorResult1.Legend.Coloring = "Banded"
vectorResult1.Legend.NumberOfColors = "10"
vectorResult1.Distribution = "Mesh"
vectorResult1.Evaluate()
maximum_velocity = vectorResult1.Summary.Max
step.NextStep.Properties["MaximumVelocity"].Value = maximum_velocity.ToString()
step.NextStep.Properties["PressureLoss"].Value = singleValueResult1.Value.ToString()
Note
This extension is also available as the free Linear Extension app on the ANSYS Store.
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
of ANSYS, Inc. and its subsidiaries and affiliates. 45
AIM Wizards
<interface context="Study">
<images>images</images>
</interface>
• The callback <oncreate> is named createStep1. It creates the geometry task, executes the import
of the geometry, and proceeds to create all required tasks for the static structural computation. It only
executes the update of the geometry task because the user input gathered in step 2 is needed for the
structural computation. This callback also executes the following actions:
– Adds via UserCommands the custom code snippets for computation of the buckling load.
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
46 of ANSYS, Inc. and its subsidiaries and affiliates.
Guided Simulation Example
– Creates a contour result object for displaying displacement magnitude. This result object is to contain
the displacement that describes the shape of the first buckling mode.
• The callback <onupdate> is named updateStep1. It is invoked after the callback <oncreate>
has been executed once. In this callback, a new geometry file is imported. Any contact created for the
previous geometry is also deleted because it is generally not applicable to the new geometry.
• Location of the force applied to the structure for which a buckling load estimation is wanted
• The callback <refresh> is named refreshStep2. It is used to display the force that was applied
in the first step. Because the first step can be visited before it is updated, the callback ignores any error
generated if the force is not yet defined.
• The callback <update> is named updateStep2. It gathers the data entered for support, force, and
material properties and proceeds to update the mesh, physics (including the custom snippets), and
result task. At the end of the update, the callback retrieves the information about the buckling load
that was requested as part of the custom code snippet. This information is used to populate the result
shown in the third step.
• The callback <refresh> is named refreshStep3. It is used to display the contour of the displace-
ment magnitude for the deformation of the first buckling mode, which was calculated in the second
step. Because the third step can be visited before the second step is updated, the callback ignores
any error generated if the contour is not yet defined.
• The callback <update> is named updateStep3. It is the last action performed for this guided sim-
ulation. It simply exports a report containing a summary of the computation.
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
of ANSYS, Inc. and its subsidiaries and affiliates. 47
AIM Wizards
Study.SetCurrentModelForExtension(Model = model)
#Removes any contact generated for the previous geometry since they could be invalid for the new geometry
physicsDefinitionTask = getCompomentByName(step.Attributes["physicsDefinitionComponentName"]).GetTask()
with Transaction():
Study.Delete(Items=physicsDefinitionTask.GetAllObjectsOfType(Type="Contact"))
def resetStep1(step):
pass
def createStep1(step):
#This function is the update function that is invoked the first time update is invoked
#It imports a geometry, sets up the information for a structural computation and adds custom snippets for lin
system1 = GetSystem(Name="Study")
geometryModelingComponent1 = Study.CreateTask(
Type="Geometry Modeling",
System=system1)
step.Attributes["geometryModelingComponent"] = geometryModelingComponent1.Name
modeling1 = geometryModelingComponent1.GetTaskObject()
modeling1.SetImportPath(FilePath=step.Properties["geometry"].ValueString)
meshingComponent1 = Study.CreateTask(
Type="Meshing",
System=system1,
Input=geometryModelingComponent1)
meshing1 = meshingComponent1.GetTaskObject()
meshing1.EngineeringIntent = "StructuralOrThermalOrElectricConduction"
meshingComponent1.Refresh()
physicsDefinitionComponent1 = Study.CreateTask(
Type="Physics Definition",
System=system1,
Input=meshingComponent1)
step.Attributes["physicsDefinitionComponentName"] = physicsDefinitionComponent1.Name
physicsDefinition1 = physicsDefinitionComponent1.GetTaskObject()
physicsDefinition1.CalculationType = "Static"
study1 = system1.GetContainer(ComponentName="Study")
solverSettings1 = study1.CreateEntity(
Type="SolverSettings",
Association=physicsDefinition1)
solvePhysicsComponent1 = Study.CreateTask(
Type="Solve Physics",
System=system1,
Input=physicsDefinitionComponent1)
solvePhysicsComponent1.Refresh()
physicsSolutionGroup1 = Study.CreateGroup(Name="Physics Solution")
physicsSolutionGroup1.Add(Component=physicsDefinitionComponent1)
physicsSolutionGroup1.Add(Component=solvePhysicsComponent1)
physicsSolutionGroup1.DisplayText = "Buckling"
physicsRegion1 = study1.CreateEntity(
Type="PhysicsRegion",
Association=physicsDefinition1)
physicsRegion1.PhysicsType = "Structural"
physicsRegion1.Location = "AllBodies()"
physicsRegion1.DisplayText = "LinearBuckling"
materialAssignment1 = study1.CreateEntity(
Type="MaterialAssignment",
Association=physicsDefinition1)
material1 = study1.CreateEntity(
Type="Material",
Association=physicsDefinition1)
step.Attributes["materialName"] = material1.Name
material1.ImportEngineeringData(Name="Structural Steel")
material1.DisplayText = "Material"
materialAssignment1.Material = material1
materialAssignment1.Location = [physicsRegion1]
interfaceGenerator1 = study1.CreateEntity(
Type="InterfaceGenerator",
Association=physicsDefinition1)
transcript1 = study1.CreateEntity(
Type="Transcript",
Association=physicsDefinition1)
transcript1.DisplayText = "Structural Output 1"
resultsEvaluationComponent1 = Study.CreateTask(
Type="Results Evaluation",
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
48 of ANSYS, Inc. and its subsidiaries and affiliates.
Guided Simulation Example
System=system1,
Input=solvePhysicsComponent1)
AddSourceToComponentInSystem(
SourceComponent=physicsDefinitionComponent1,
TargetComponent=resultsEvaluationComponent1)
resultsEvaluationComponent1.Refresh()
results1 = resultsEvaluationComponent1.GetTaskObject()
contourResult1 = study1.CreateEntity(
Type="ContourResult",
Association=results1)
contourResult1.Variable = "Displacement.mag"
contourResult1.DisplayText = "Buckling Mode 1"
step.Attributes["bucklingDisplacementContourName"] = contourResult1.Name
geometryModelingComponent1.Update(AllDependencies=True)
model = Study.GetModelFromObject(Object = modeling1)
Study.SetCurrentModelForExtension(Model = model)
interfaceGenerator1.GenerateInteractions()
#The support and force are created in this step but their location is defined in the following step
#Step attributes are used to retrieve the created support and force
support1 = study1.CreateEntity(
Type="Support",
Association=physicsDefinition1)
step.Attributes["supportName"] = support1.Name
force1 = study1.CreateEntity(
Type="Force",
Association=physicsDefinition1)
step.Attributes["forceName"] = force1.Name
force1.Vector.VectorByMagnitudeAndDirection.Magnitude = "1 [N]"
force1.Vector.VectorByMagnitudeAndDirection.ReverseDirection = "True"
#Creates user command to executed custom MAPDL code that performs a linear
#eigenvalue buckling computation
userCommands1 = study1.CreateEntity(
Type="UserCommands",
Association=physicsDefinition1)
userCommands1.AddCodeSnippet(
SectionPath="Solve/Loadcase/JustBeforeSolveSection",
Commands="""solve
finish
/assign,rstp,file,rst
/solu
antype,,restart,,,perturb
perturb,buckle,,CURRENT,ALLKEEP
solve,elform
bucopt,lanb,1,,,center
outres,erase
outres,all,all""")
#Creates user command to executed custom MAPDL code that retrieves
#the buckling load for the eigenvalue buckling computation
userCommands1.AddCodeSnippet(
SectionPath="PostProcessingSection",
Commands=r"""/OUT,..\..\..\..\user_files\myloadfactors,txt
*GET,FREQ,MODE,1,FREQ
/output""")
def updateStep2(step):
system1 = GetSystem(Name="Study")
study1 = system1.GetContainer(ComponentName="Study")
#Retrieves the support and force and applies the user specified location
support1 = study1.GetSupport(Name=getStepByName(step, "Step_1").Attributes["supportName"])
support1.Location = step.Properties["support"].Value.LocationSet
force1 = study1.GetForce(Name=getStepByName(step, "Step_1").Attributes["forceName"])
force1.Location = step.Properties["force"].Value.LocationSet
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
of ANSYS, Inc. and its subsidiaries and affiliates. 49
AIM Wizards
material1.Solid.IsotropicElasticity.Magnitude.YoungsModulus = step.Properties["YoungsModulus"].ValueString
material1.Solid.IsotropicElasticity.Magnitude.PoissonsRatio = step.Properties["PoissonRatio"].ValueString
#Solution
resultsEvaluationComponent1 = system1.GetComponent(Name="Results Evaluation")
resultsEvaluationComponent1.Update(AllDependencies=True)
study1 = system1.GetContainer(ComponentName="Study")
contourResult1 = study1.GetContourResult(Name=getStepByName(step, "Step_1").Attributes["bucklingDisplacementC
contourResult1.Evaluate()
#Finds the results step and assigns the value of the computed buckling load
s = step.NextStep
s.Properties["bucklingLoad"].Value = force1
def refreshStep2(step):
system1 = GetSystem(Name="Study")
study1 = system1.GetContainer(ComponentName="Study")
#If the force is defined, it is set to be displayed in the UI
try:
force1 = study1.GetForce(Name=getStepByName(step, "Step_1").Attributes["forceName"])
StudyUI.SetSelectionTo(force1)
except:
force1 = None
def updateStep3(step):
clr.AddReference("Ans.UI.Toolkit")
clr.AddReference("Ans.UI.Toolkit.Base")
from Ansys.UI.Toolkit import *
# generates report
userDir = GetProjectFile().split(".wbpj")[0] + "_files"
file = userDir + "\\user_files\\" + "eulerbuckling.html"
ExportReport(FilePath=file)
MessageBox.Show("Report written to user_files: "+file)
def refreshStep3(step):
system1 = GetSystem(Name="Study")
study1 = system1.GetContainer(ComponentName="Study")
#If the displacement contour is defined, it is set to be displayed in the UI
try:
contourResult1 = study1.GetContourResult(Name=getStepByName(step, "Step_1").Attributes["bucklingDisplacem
StudyUI.SetSelectionTo(contourResult1)
except:
contourResult1 = None
pass
# helper functions
def getCompomentByName(componentName):
for c in GetSystem(Name="Study").Components:
if c.Name == componentName:
return c
return None
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
50 of ANSYS, Inc. and its subsidiaries and affiliates.
AIM Project Wizards
if step.Key == stepName:
return step.Value
return None
<interface context="Project">
<images>images</images>
</interface>
<callbacks>
<onupdate>importGeometry</onupdate>
</callbacks>
<callbacks>
<onupdate>refineMesh</onupdate>
</callbacks>
<callbacks>
<onrefresh>initLocations</onrefresh>
<onupdate>setup</onupdate>
</callbacks>
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
of ANSYS, Inc. and its subsidiaries and affiliates. 51
AIM Wizards
</extension>
Step Definition
You use the element <step> to define a step in the wizard. Required attributes are name and version.
The optional attribute caption sets the display text for the step. You only need to set the attribute
context if the context for a step differs from the context for the wizard. All four steps in the wizard
PressureLoss are executed from the Project tab in AIM.
Additional optional attributes can be defined for steps. For example, you can use the attribute Help-
File to specify an HTML file with the custom help to display for the step. In this example, the help
provided for each step indicates where each property is displayed in the Study panel.
Callback Definition
Each step defined in the XML file can have multiple callbacks invoking functions defined in the script.
You use the element <callbacks> to define the callbacks for the step. Each callback receives the
current step as a method argument.
• Step1: The callback <onupdate> executes the function importGeometry. This step creates the
CFD workflow, importing and then generating the specified geometry when Next is clicked.
• Step2: The callback <onupdate> executes the function refineMesh. This step allows the mesh
resolution to be specified and the mesh refined accordingly when Next is clicked.
• Step3: The callback <onrefresh> executes the function initLocations. The callback <onup-
date> executes the function setup. This step provides for specifying the loads to apply to the inlet
and outlet. You select a location and specify the velocity for the input and the gauge pressure for the
outlet. The callback <isvalid> on the property OutletLocation executes the action isValid,
validating the value selected for the outlet location.
• Step4: No callbacks are required. This step takes the value calculated for the property Calculated-
Maximum and populates it to the field Calculated maximum for the object Velocity.
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
52 of ANSYS, Inc. and its subsidiaries and affiliates.
AIM Project Wizards
def getSelectionSetsForProject():
context = __scriptingEngine__.CommandContext
project = context.Project
containers = project.GetContainers()
dataEntity = "SelectionSet"
def initLocations(step):
list = getSelectionSetsForProject()
propIn = step.Properties["Inlet/InletLocation"]
propIn.Options.Clear()
propOut = step.Properties["Outlet/OutletLocation"]
propOut.Options.Clear()
for sel in list:
ExtAPI.Log.WriteMessage("OPTION: "+sel.DisplayText)
propIn.Options.Add(sel.DisplayText)
propOut.Options.Add(sel.DisplayText)
comp = step.UserInterface.GetComponent("Properties")
comp.UpdateData()
comp.Refresh()
def importGeometry(step):
global meshingComponent1, study1, results1, vectorResult1, singleValueResult1, physicsDefinitionComponent1, re
with Transaction():
system1 = GetSystem(Name="Study")
physicsDefinitionComponent1 = Study.CreateTask( Type="Physics Definition", System=system1)
study1 = system1.GetContainer(ComponentName="Study")
physicsDefinition1 = physicsDefinitionComponent1.GetTaskObject()
physicsRegion1 = study1.CreateEntity( Type="PhysicsRegion", Association=physicsDefinition1)
solverSettings1 = study1.CreateEntity( Type="SolverSettings", Association=physicsDefinition1)
solvePhysicsComponent1 = Study.CreateTask( Type="Solve Physics", System=system1, Input=physicsDefinitionCom
solvePhysicsComponent1.Refresh()
resultsEvaluationComponent1 = Study.CreateTask( Type="Results Evaluation", System=system1, Input=solvePhysi
resultsEvaluationComponent1.Refresh()
physicsDefinition1.CalculationType = "Static"
physicsRegion1.PhysicsType = "Fluid"
physicsRegion1.Location = "AllBodies()"
materialAssignment1 = study1.CreateEntity( Type="MaterialAssignment", Association=physicsDefinition1)
material1 = study1.CreateEntity( Type="Material", Association=physicsDefinition1)
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
of ANSYS, Inc. and its subsidiaries and affiliates. 53
AIM Wizards
material1.ImportEngineeringData(Name="Air")
materialAssignment1.Material = material1
materialAssignment1.Location = [physicsRegion1]
results1 = resultsEvaluationComponent1.GetTaskObject()
vectorResult1 = study1.CreateEntity( Type="VectorResult", Association=results1)
vectorResult1.Variable = "Velocity"
vectorResult1.DisplayText = "Velocity"
transcript1 = study1.CreateEntity( Type="Transcript", Association=physicsDefinition1)
transcript1.DisplayText = "Fluid Flow Output 1"
physicsSolutionGroup1 = Study.CreateGroup(Name="Physics Solution")
physicsSolutionGroup1.Add(Component=physicsDefinitionComponent1)
physicsSolutionGroup1.Add(Component=solvePhysicsComponent1)
meshingComponent1 = Study.CreateTask( Type="Meshing", System=system1, Output=physicsDefinitionComponent1)
physicsDefinitionComponent1.Refresh()
solvePhysicsComponent1.Refresh()
resultsEvaluationComponent1.Refresh()
importComponent1 = Study.CreateTask( Type="Import", System=system1, Output=meshingComponent1)
meshingComponent1.Refresh()
physicsDefinitionComponent1.Refresh()
solvePhysicsComponent1.Refresh()
resultsEvaluationComponent1.Refresh()
import1 = importComponent1.GetTaskObject()
geometryImportSource1 = import1.AddGeometryImportSourceOperation()
geometryImportSource1.FilePath = step.Properties["geometryfile"].Value
importComponent1.Update(AllDependencies=True)
meshingComponent1.Refresh()
physicsDefinitionComponent1.Refresh()
solvePhysicsComponent1.Refresh()
resultsEvaluationComponent1.Refresh()
def refineMesh(step):
global meshingComponent1, study1, results1, vectorResult1, physicsDefinitionComponent1, singleValueResult1, res
meshing1 = meshingComponent1.GetTaskObject()
meshing1.MeshResolution = step.Properties["MeshResolution"].Value
def setup(step):
global meshingComponent1, study1, results1, vectorResult1, physicsDefinitionComponent1, singleValueResult1, res
with Transaction():
meshing1 = meshingComponent1.GetTaskObject()
meshControlLocalInflation1 = study1.CreateEntity( Type="MeshControlLocalInflation", Association=meshing1)
meshing1.EngineeringIntent = "FluidFlow"
AddSourceToComponentInSystem( SourceComponent=physicsDefinitionComponent1, TargetComponent=resultsEvaluatio
resultsEvaluationComponent1.Refresh()
#meshControlLocalInflation1.Location = ["FACE8", "FACE2", "FACE6"]
Study.Delete(Items=[meshControlLocalInflation1])
with Transaction():
meshingComponent1.Update(AllDependencies=True)
physicsDefinitionComponent1.Refresh()
solvePhysicsComponent1.Refresh()
resultsEvaluationComponent1.Refresh()
with Transaction():
inletBoundary1 = study1.CreateEntity( Type="InletBoundary", Association=physicsRegion1)
inlet_location = step.Properties["Inlet/InletLocation"].Value
ExtAPI.Log.WriteMessage("my inlet location property value is : " + inlet_location)
inlet_selection_set = None
selection_sets = getSelectionSetsForProject()
for selection_set in selection_sets:
if selection_set.DisplayText == inlet_location:
inlet_selection_set = selection_set
if inlet_selection_set == None :
ExtAPI.Log.WriteMessage("inlet selection set does not exist")
inletBoundary1.Location = [inlet_selection_set]
inletBoundary1.Flow.Velocity.Magnitude = step.Properties["Inlet/Velocity"].DisplayString
outlet_location = step.Properties["Outlet/OutletLocation"].Value
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
54 of ANSYS, Inc. and its subsidiaries and affiliates.
AIM Project Wizards
outlet_selection_set = None
selection_sets = getSelectionSetsForProject()
for selection_set in selection_sets:
if selection_set.DisplayText == outlet_location:
outlet_selection_set = selection_set
if outlet_selection_set == None :
ExtAPI.Log.WriteMessage("outlets selection set does not exist")
outletBoundary1.Location = [outlet_selection_set]
outletBoundary1.Flow.Pressure.GaugeStaticPressure = step.Properties["Outlet/GaugePressure"].DisplayString
with Transaction():
physicsDefinitionComponent1.Update(AllDependencies=True)
solvePhysicsComponent1.Update(AllDependencies=True)
resultsEvaluationComponent1.Refresh()
resultsEvaluationComponent1.Refresh()
resultsEvaluationComponent1.Update(AllDependencies=True)
vectorResult1.Legend.Coloring = "Banded"
vectorResult1.Legend.NumberOfColors = "10"
vectorResult1.Distribution = "Mesh"
vectorResult1.Evaluate()
maximum_velocity = vectorResult1.Summary.Max
step.NextStep.Properties["MaximumVelocity"].Value = maximum_velocity.ToString()
step.NextStep.Properties["PressureLoss"].Value = singleValueResult1.Value.ToString()
def solve(step):
global meshingComponent1, study1, results1, vectorResult1, physicsDefinitionComponent1, singleValueResult1, res
with Transaction():
physicsDefinitionComponent1.Update(AllDependencies=True)
solvePhysicsComponent1.Update(AllDependencies=True)
resultsEvaluationComponent1.Refresh()
resultsEvaluationComponent1.Refresh()
resultsEvaluationComponent1.Update(AllDependencies=True)
vectorResult1.Legend.Coloring = "Banded"
vectorResult1.Legend.NumberOfColors = "10"
vectorResult1.Distribution = "Mesh"
vectorResult1.Evaluate()
maximum_velocity = vectorResult1.Summary.Max
step.NextStep.Properties["MaximumVelocity"].Value = maximum_velocity.ToString()
step.NextStep.Properties["PressureLoss"].Value = singleValueResult1.Value.ToString()
When the project wizard PressureLoss executes, the final page shows the calculated Maximum
Velocity. The custom help, which the help panel displays, explains where the result is shown.
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
of ANSYS, Inc. and its subsidiaries and affiliates. 55
AIM Wizards
Clicking Finish on the final wizard page returns you to the ACT Start Page.
In the Study panel, you can see that the project wizard created the workflow in AIM and then auto-
matically executed the steps.
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
56 of ANSYS, Inc. and its subsidiaries and affiliates.
AIM Project Wizards
You can open the Results task to view the final results obtained by this simulation.
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
of ANSYS, Inc. and its subsidiaries and affiliates. 57
Release 2019 R3 - © ANSYS, Inc. All rights reserved. - Contains proprietary and confidential information
58 of ANSYS, Inc. and its subsidiaries and affiliates.