Automatically Update all Projects Affected by a Design Modification

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:

  1. Finds all Ansys Workbench projects within a specified directory.

  2. 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.

Figure 1: Mixing in base geometry

Mixing in base geometry

Figure 2: Mixing in modified geometry

Mixing in modified geometry

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 the str(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. The Open command is part of the Ansys Workbench Project namespace and is used to open an Ansys Workbench project, while the open 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.