You have performed a set of analyses on a design with an initial geometry file. These analyses have been saved as a number of different Ansys Workbench projects. The design has been modified, and you have been provided with a new geometry file that represents the updated design. After you extract the ScriptingGuideExamples.zip file, you will find the files for this example in the Design_Modification directory.
To automate the update of all affected projects, you would write a script that does the following:
Finds all Ansys Workbench projects within a specified directory.
For each project that has been found:
Replaces the original geometry with the new geometry file in any system in the project.
Updates the project and reports any errors from the update.
If the update was successful, reports the values of key output parameters under the modified geometry.
Saves the modified project with the new geometry file to a new directory.
Although the analysis specifics are secondary for the purposes of this example, a CFD analysis of a blood mixing device is used. This device attempts to maximize mixing of two blood streams while minimizing flow vorticity (which is an indicator of blood damage potential). Three projects involving a coarse mesh model, a fine mesh model, and an asymmetric flow condition were created. The parameters of interest are pressure drop, average and maximum vorticity, and mixing factor of blood stream 1 at the exit.
Workbench Script — The script for this example follows. Each line is numbered for reference in the discussion that follows.
1 # import the 'os' module, which provides a portable way of using operating system dependent functionality 2 import os 3 4 # Helper function to write parameters to the log file 5 def writeParams(logFile): 6 for param in Parameters.GetAllParameters(): 7 prmString = " " + param.Name + ": " + param.DisplayText + " = " + param.Value.ToString() 8 logFile.write(prmString + "\n") 9 logFile.flush() 10 11 workDir = "ScriptingGuideExamples/Design_Modification/" 12 13 # Define the original and target directories 14 origDir = AbsUserPathName(workDir + "Original") 15 newDir = AbsUserPathName(workDir + "Modified") 16 17 # Define new geometry file 18 newGeom = AbsUserPathName(workDir + "Geometry/bloodMix2.agdb") 19 20 # Open a log file to record script progress 21 logFile = open(AbsUserPathName(workDir + "GeometryReplace.log"),"w") 22 23 # Create the new directory if necessary 24 if not os.path.exists(newDir): 25 os.makedirs(newDir) 26 27 # Find all the projects in the original directory 28 projList = [] 29 for fileName in os.listdir(origDir): 30 if fileName.endswith(".wbpj"): 31 projList.append(fileName) 32 33 # Process each project one at a time 34 for projFile in projList: 35 36 # Open the project into Workbench and clear any starting messages 37 projPath = os.path.join(origDir, projFile) 38 logFile.write("Processing project in " + projPath + "\n") 39 Open(FilePath=projPath) 40 ClearMessages() 41 42 # Output project parameter values before update 43 logFile.write("Parameter values in original project:\n") 44 writeParams(logFile) 45 46 # Walk through each system in the project and replace the geometry file (if there is a geometry Component) 47 for system in GetAllSystems(): 48 try: 49 geometry = system.GetContainer(ComponentName="Geometry") 50 except: 51 logFile.write("No geometry to replace in system " + system.DisplayText + "\n") 52 else: 53 geometry.SetFile(FilePath=newGeom) 54 55 # Update the project 56 try: 57 Update() 58 except: 59 logFile.write("update failed") 60 61 # If the project has been successfully updated, write out the new parameter values 62 # If not, write any project messages 63 if IsProjectUpToDate(): 64 logFile.write("Parameter values in revised project:\n") 65 writeParams(logFile) 66 else: 67 logFile.write("ERROR: Project not successfully updated. The following messages were found:\n") 68 for msg in GetMessages(): 69 msgString = " " + msg.DateTimeStamp.ToString() + " " + msg.MessageType + ": " + msg.Summary + "\n" 70 logFile.write(msgString + "\n") 71 72 # In any case, save the modified project to the new directory 73 projPath = os.path.join(newDir, projFile) 74 Save(FilePath=projPath) 75 76 logFile.write("\n") 77 # End of project loop 78 76 logFile.close() 79
Log File — The log file generated by this script should look like this:
Processing project in C:\Users\neUser\Demo/ScriptExample1/Original/AsymmetricFlow.wbpj Parameter values in original project: P1: PressureDropCoeff = 34.2088 P2: mixing = 0.217835 P5: maxVorticity = 3939.22 [s^-1] P4: aveVorticity = 27.4697 [s^-1] Parameter values in revised project: P1: PressureDropCoeff = 34.0394 P2: mixing = 0.276673 P5: maxVorticity = 3939.22 [s^-1] P4: aveVorticity = 27.4034 [s^-1] Processing project in C:\Users\neUser\Demo/ScriptExample1/Original/BaseAnalysis.wbpj Parameter values in original project: P1: PressureDropCoeff = 30.04 P2: mixing = 0.248514 P5: maxVorticity = 3939.22 [s^-1] P4: aveVorticity = 36.8447 [s^-1] Parameter values in revised project: P1: PressureDropCoeff = 30.3782 P2: mixing = 0.288321 P5: maxVorticity = 3939.22 [s^-1] P4: aveVorticity = 36.6682 [s^-1] Processing project in C:\Users\neUser\Demo/ScriptExample1/Original/FineAnalysis.wbpj Parameter values in original project: P1: PressureDropCoeff = 29.0038 P2: mixing = 0.266388 P5: maxVorticity = 3939.22 [s^-1] P4: aveVorticity = 29.2073 [s^-1] Parameter values in revised project: P1: PressureDropCoeff = 30.7209 P2: mixing = 0.295078 P5: maxVorticity = 3939.22 [s^-1] P4: aveVorticity = 37.5408 [s^-1]
Discussion — This example demonstrates a number of the typical programming constructs and Ansys Workbench functionality that will be employed in the creation of scripts. The following discussion refers to the specified line numbers of the example script to illustrate some of these concepts and constructs.
- Lines 1-2
The
import
keyword is used to include Python modules that enhance functionality available within the script. The ‘os
’ module used in this script provides capabilities for interacting with operating system services. Refer to the Python Standard Library documentation for details on all available modules.- Lines 4-9
A common pattern is to encapsulate repeated operations in Python function definitions and then call these functions later in the script. Because the script is processed sequentially, the function must be defined before it is used. This example defines a function
writeParams()
to loop through all the parameters in the current project and write information to a provided file object. When concatenating data into a string for output, all non-String data types must first be explicitly converted to their string representation using thestr
(data
) function or.ToString()
method.- Lines 11-18
It is recommend that you use the
AbsUserPathName
function when working with directory or file paths to promote portability of the path between user accounts and operating systems. See File Path Handling in Ansys Workbench for further details.- Lines 20-21
Standard Python functionality is used to open and write output to a log file throughout this script.
- Lines 23-31
This section also employs standard Python to loop through all file names in a directory. All those file names that end with the .wbpj extension are added to a list of project files for further processing.
- Lines 33-40
The script now processes each project in turn. At the beginning of the loop, the full path to the project file is generated from the provided directory name and project file name in a platform-independent manner using Python’s
os.path.join
function. The project is then opened and messages are cleared so that later message processing will focus on new messages generated during the update. Note that the Python is case-sensitive. TheOpen
command is part of the Ansys WorkbenchProject
namespace and is used to open an Ansys Workbench project, while theopen
command is provide by Python and is used to open any file and create a Python file object.- Lines 42-44
The
writeParams
function defined earlier in the script is used to record parameter values to the log file before project modification.- Lines 46-47
The
GetAllSystems()
query is used to provide references to all systems in the project.- Lines 48-53
Because Geometry components are of specific interest, the system’s
GetContainer()
query is used to try to get a reference to the Geometry data. A Python try/except/else construct is used to handle the success or failure of the query.An alternate approach here would be to walk through each component in the system and then use information about the component to decide which to process. That approach is demonstrated in a subsequent example.
- Lines 55-59
An Ansys Workbench project update is used to recompute all aspects of the project affected by the geometry change. This step is the most computationally expensive part of the script. A Python try/except construct is used to handle the success or failure of the update and prevent a premature exit of the script.
- Lines 61-70
After the update operation has completed, the script checks the whole project to see if it has been successfully updated. If the project update was successful, the script calls the
writeParams
function again to output updated parameter information to the log file. If the update was not successful, the script records any project messages that were generated during the update.- Lines 66-70
Similar to the method used to process parameters, the script loops through all messages in the project and write key information about each message to the log file.
- Lines 72-77
A file path for the project within the desired directory for the modified projects is generated, and the Ansys Workbench
Save
command is called to save the modified project. After saving, the loop repeats for the next project in the list.