Tip: Start typing in the input box for immediate search results.Can't find what you're looking for? Submit a support request here.
Advanced StressCheck Automation: Model Editing & Updating
Introduction
In the Advanced StressCheck Automation: Model Setup & Analysis article, we focused on model setup techniques (i.e. model creation, user-defined solution & extraction settings) for performing “on-the-fly”, customized StressCheck analyses. In the following article, we will learn to perform modeling querying, editing and updating tasks such as:
- Querying & updating geometric objects based on user input
- Updating automesh settings
- Updating load magnitude based on user input
- Updating a solution ID for a new load ID
- Updating linear solution p-level & p-limit settings
- Updating contour plot settings
- Updating min/max extraction settings based on user input
To demonstrate the VBA and Python code required for these advanced scripting tasks, we will open the StressCheck Project (SCP) file generated from Advanced StressCheck Automation: Model Setup & Analysis and walk through its existing object collections, properties and settings.
Python Script Prerequisites
In addition to importing the required win32com.client module at the beginning of our Python script, we must also import the os module so that we can perform advanced file I/O operations, and the pythoncom module so we can pass VARIANTs to StressCheck. Therefore, it is required to include the following at the top of your Python script:
#import libraries/modules
import os
import win32com.client as win32
from win32com.client import VARIANT
import pythoncom
from pythoncom import VT_ARRAY
from pythoncom import VT_R8
from pythoncom import VT_I4
Note that the line “import win32com.client as win32” simply maps the win32com.client module to win32 to save characters.
Querying & Updating Geometric Objects
After starting a new StressCheck session (see StressCheck Automation Fundamentals to review the requirements), we will open the countersink plate StressCheck Project (SCP) file. This can be done by accessing the Open method of the StressCheck Application’s Document level. Then, we simply provide the SCP path/filename as the argument:
Sub Open([file As String])
As discussed, once the SCP file is loaded into the StressCheck Application object we can access all of its collections, properties and members. Then, for a given item in a collection, we can access one or more of its properties/members and use Update methods to overwrite/replace the data (as we will see shortly). For this example, we would like to modify the major radius of the cone object used to generate the countersink bore to be a user-defined input value. To do so, we will need to access the StressCheck.Document.Model level’s Cones collection and then query the desired Cone item within the populated list of Cones.
To return the Cone item of interest from the list of Cones, we will use the ItemAtIndex method of the Cones collection. All we need to do is provide the 0-based index of the Cone of interest, and since there is only one Cone in the model we would provide “0” as the argument:
Function ItemAtIndex(Index As Long) As Unknown
As the return of this function is a specific Cone object, we can then query/update that particular Cone object’s properties/members. The members of a Cone object are as follows:
For this example, we are interested in obtaining the current values of the first radius (Radius1Constant) and second radius (Radius2Constant). We will then use this information to ask the user for the new value of the second (major) cone radius, and call the Update method of the Cone object to set the new Radius2 value.
Excel VBA
The Excel VBA code to open the SCP, access the Cone object at the 0th index in the Cones collection, obtain the current radii values, and update the Radius2 value based on a user-defined input would be:
'Open AutoMeshedPlate SCP
SCApp.Document.Open ThisWorkbook.Path & "\AutoMeshPlateSolved.scp"
'Query the countersink cone radii
Dim mycones As StressCheck.Cones, cskcone As StressCheck.Cone
Dim CurrentRad1 As Double, CurrentRad2 As Double, NewRad2 As Double
Set mycones = SCApp.Document.model.Cones
Set cskcone = mycones.ItemAtIndex(0)
CurrentRad1 = cskcone.Radius1Constant
CurrentRad2 = cskcone.Radius2Constant
'Update the major cone radius based on user input value
NewRad2 = CurrentRad1
Do While NewRad2 <= CurrentRad1
NewRad2 = InputBox("The current major radius of the countersink cone is " & CurrentRad2 & ". Enter a new value between " _
& CurrentRad1 & " and " & 1.5 * CurrentRad2 & ":", "Enter a new major cone radius value")
Loop
cskcone.Radius2 = NewRad2
cskcone.Update
Python
The Python code to open the SCP, access the Cone object at the 0th index in the Cones collection, obtain the current radii values, and update the Radius2 value based on a user-defined input would be :
#Open Automeshed Plate SCP
scapp.Document.Open(os.path.abspath(os.path.dirname(__file__)) + '\\AutomeshPlateSolved.scp')
#Query the cone countersink radii
mycones = scapp.Document.Model.Cones
cskcone = mycones.ItemAtIndex(0)
currentrad1 = cskcone.Radius1Constant
currentrad2 = cskcone.Radius2Constant
#Update the major cone radius based on user input
newrad2 = currentrad1
while newrad2 <= currentrad1:
newrad2 = float(input('Enter a new value for the major radius of the countersink cone > ' + str(currentrad1) + ':'))
cskcone.Radius2 = newrad2
cskcone.Update
Updating Automesh Settings
Similar to how we accessed the Cones collection of the Model object, we can access the Model’s Automeshes collection to update the Ratio setting of the global Automesh item to 1.0. To update a specific global Automesh item, we will use the Automesh property of the Automeshes collection:
Property Automesh(num As Long) As Automesh
Entering an integer value (>0) as the argument for the Automesh property will return the Automesh object associated with that item number in the Automeshes collection. We can then query/update that particular Automesh object’s properties/members. The members of an Automesh object are as follows:
We are interested in ensuring that the Automesh object’s Ratio setting is active (True) and then updating the Ratio setting’s value to 1.0. We can do so using the Active and Value properties of the Automesh object. The argument for the Active and Value properties is an AutomeshProperty enumeration:
Therefore, we will need to pass apRatio (or 1) into the Active and Value properties, and set these to True and 1.0 respectively.
Excel VBA
The Excel VBA code for activating and updating the Ratio setting for the 1st automesh item would be:
'Update the automesh Ratio value to 1.0
Dim myautomeshes As StressCheck.Automeshes, plateautomesh As StressCheck.Automesh
Set myautomeshes = SCApp.Document.model.Automeshes
Set plateautomesh = myautomeshes.Automesh(1)
plateautomesh.Active(apRatio) = True
plateautomesh.Value(apRatio) = 1
plateautomesh.Update
'Re-mesh the model
SCApp.Document.model.Automesh
'Update the display
SCApp.Document.model.Update
Python
The Python code for activating and updating the Ratio setting for the 1st automesh item would be:
#Update the automesh Ratio value to 1.0
myautomeshes = scapp.Document.Model.Automeshes
plateautomesh = myautomeshes.Automesh(1)
plateautomesh.SetActive(1,True)#Activate Ratio
plateautomesh.SetValue(1,1.0) #Update Ratio
plateautomesh.Update
#Re-mesh the model
scapp.Document.Model.Automesh (0)
#Update the display
scapp.Document.Model.Update (0)
Note that the SetActive and SetValue methods were used to update the Active and Value properties, respectively. These methods are automatically generated by the win32com module.
Updating Load Data
Similar to how we accessed the Automeshes collection of the Model object, we can access the Model’s Loads collection to update the magnitude of the applied traction Load item to a user-defined input value. To update a specific Load item, we will use the Load property of the Loads collection:
Property Load(num As Long) As Load
Entering an integer value (>=0) as the argument for the Load property will return the Load object associated with that index in the Loads collection. We can then query/update that particular Load object’s properties/members. The members of a Load object are as follows:
We are interested in updating the traction load direction from Normal/Tangent to XYZ, and the traction load magnitude in the global X-direction to a user-defined value. We can do so using the LoadDirection property and the SetData method of the Load object.
The LoadDirection property requires a Direction enumeration:
We will set the LoadDirection property to dtXYGlobal. The arguments for the SetData method are as follows:
Sub SetData(position As Long, Data)
In the 3D XYZ reference, there are three positions: 0 (i.e. X), 1 (i.e. Y) and 2 (i.e. Z). Note that if we were using the 3D Normal/Tangent reference, there would only be the Normal position (0). Therefore, in this case the position will be 0 and the Data would the new X value.
After using the SetData method, we have the option to update the load ID (Name) property of the Load object. In this case, we will set the new load ID to be “LOAD2”. Finally, we will call the Update method of the Load object. NOTE: in the event that the Update method results in the duplication of the original Load item with load ID “LOAD” to a new Load item with load ID “LOAD2”, the original Load item can be deleted using the Remove method of the Loads collection.
Excel VBA
The Excel VBA code for updating the traction load direction to XYZ, the traction load magnitude to a user-defined value, and the load ID to “LOAD2” would be:
'Update the applied traction based on user input
Dim Tx As Double
Tx = InputBox("Enter a new traction load magnitude, in psi", "Update traction load")
'Change the applied load from Normal = 1 to X = Tx
Dim myloads As StressCheck.Loads, tractionload As StressCheck.Load
Set myloads = SCApp.Document.model.Loads
Set tractionload = myloads.Load(0)
tractionload.LoadDirection = dtXYGlobal
tractionload.SetData 0, Tx 'Enter parameter name Tx as the X: field
tractionload.Name = "LOAD2"
tractionload.Update 'Update the load data
Python
The Python code for updating the traction load direction to XYZ, the traction load magnitude to a user-defined value, and the load ID to “LOAD2” would be:
#Update the applied traction based on user input
tx = float(input('Enter a new magnitude for the applied traction, in psi:'))
myloads = scapp.Document.Model.Loads
tractionload = myloads.Load(0)
tractionload.LoadDirection = 2 #dtXYGlobal
tractionload.SetData(0, (tx,)) #Update X value to Tx value
tractionload.Name = 'LOAD2'
tractionload.Update #Update the load data
Updating a Solution ID
Similar to how we accessed the Loads collection of the Model object, we can access the Model’s SolutionIDs collection to update the load ID of the defined SolutionID to “LOAD2”. To query/update a specific SolutionID item, we will use the SolutionID property of the SolutionIDs collection:
Property SolutionID(solution_name As String) As SolutionID
Entering a solution ID name (e.g. “SOL”) as the argument for the SolutionID property will return the SolutionID object associated with that solution ID name in the SolutionIDs collection. We can then query/update that particular SolutionID object’s properties/members. The members of a SolutionID object are as follows:
We are interested in updating the load ID to “LOAD2”. We can do so by setting the LoadName property to “LOAD2” and then using the Update method to update the SolutionID item.
Excel VBA
The VBA code to update the solution ID “SOL” to use load ID “LOAD2” would be:
'Update the solution ID to use LOAD2
Dim mysolids As StressCheck.SolutionIDs
Set mysolids = SCApp.Document.model.SolutionIDs
mysolids.SolutionID("SOL").LoadName = "LOAD2"
mysolids.SolutionID("SOL").Update
Python
The Python code to update the solution ID “SOL” to use load ID “LOAD2” would be :
#Update the solution ID to use LOAD2
mysolids = scapp.Document.Model.SolutionIDs
mysolids.SolutionID('SOL').LoadName = 'LOAD2'
mysolids.SolutionID('SOL').Update
Updating a Linear Solution
The solution settings, including the linear p-extension solution setting “LinearSol” defined in our previous exercise, are found in the Solutions collection of the Document object. To query/update a specific Solution item, we will use the Solution property of the Solutions collection:
Property Solution(solution_name As String) As Solution
Entering a solution setting name (e.g. “LinearSol”) as the argument for the Solution property will return the Solution object associated with that solution setting name in the Solutions collection. We can then query/update that particular Solution object’s properties/members. The members of a Solution object are as follows:
We are interested in updating the p-levels to be p=1 to 3. We can do so by setting the PLevel and PLimit properties to 1 and 3, respectively, and then using the Update method to update the Solution item.
After executing the updated solution via the Document object’s xSolve method, we may wish to update the model display settings for screen captures. We can write a function UpdateDisplay that takes the current Application object as an argument, and updates the various properties of the Model object’s Display members (i.e. Display Points, Display Element Edges, Orientation, etc.)
Excel VBA
The VBA code to update the solution setting “LinearSol” to p=1 to 3, and then re-solve, would be:
'Update the linear solution from p=2 to 4 to p=1 to 3
Dim mysols As StressCheck.Solutions, linearsol As StressCheck.Solution
Set mysols = SCApp.Document.Solutions
Set linearsol = mysols.Solution("LinearSol")
linearsol.PLevel = 1
linearsol.PLimit = 3
linearsol.Update
'Re-solve the model
SCApp.Document.xSolve "LinearSol"
'Update model display using UpdateDisplay function
UpdateDisplay SCApp
The UpdateDisplay function used to disable the display of all objects except Elements, center/rotate the model to the Isometric view, disable Element Edges, and enable the load and constraints attributes would be:
Function UpdateDisplay(SCApp As StressCheck.Application)
'Update display information
SCApp.Document.model.Display.Orientation = vtCenter
SCApp.Document.model.Display.Orientation = vtIsometric
'Change display of objects to show elements only
SCApp.Document.model.Display.Points = False
SCApp.Document.model.Display.Nodes = False
SCApp.Document.model.Display.Surfaces = False
SCApp.Document.model.Display.Curves = False
SCApp.Document.model.Display.Systems = False
SCApp.Document.model.Display.Elements = True
'Display load and constraint attributes
SCApp.Document.model.Display.Attribute(attribLoads, "LOAD2") = True
SCApp.Document.model.Display.Attribute(attribtConstraints, "CONST") = True
'Hide element edges
SCApp.Document.model.Display.Edges = False
End Function
Python
The Python code to update the solution setting “LinearSol” to p=1 to 3, and then re-solve, would be :
#Update the linear solution from p=2 to 4 to p=1 to 3
mysols = scapp.Document.Solutions
linearsol = mysols.Solution('LinearSol')
linearsol.PLevel = 1
linearsol.PLimit = 3
linearsol.Update
#Solve the linear solution
scapp.Document.xSolve('LinearSol')
#Update model display using UpdateDisplay function
UpdateDisplay(scapp)
The UpdateDisplay function used to disable the display of all objects except Elements, center/rotate the model to the Isometric view, disable Element Edges, and enable the load and constraints attributes would be:
def UpdateDisplay (scapp):
#Set display orientation
scapp.Document.Model.Display.Orientation = 0
scapp.Document.Model.Display.Orientation = 1
#Show elements only
scapp.Document.Model.Display.Points = False
scapp.Document.Model.Display.Nodes = False
scapp.Document.Model.Display.Surfaces = False
scapp.Document.Model.Display.Curves = False
scapp.Document.Model.Display.Systems = False
scapp.Document.Model.Display.Elements = True
#Display load and constraint attributes
scapp.Document.Model.Display.Load = 'LOAD2'
scapp.Document.Model.Display.Constraint = 'CONST'
#Disable element edges
scapp.Document.Model.Display.Edges = False
Updating a Plot Setting
The plot settings, including the contour plot setting “SeqPlot” defined in our previous exercise, are found in the Plots collection of the Document object. To query/update a specific Plot item, we will use the Plot property of the Plots collection:
Property Plot(plot_name As String) As Plot
Entering a plot setting name (e.g. “SeqPlot”) as the argument for the Plot property will return the Plot object associated with that plot setting name in the Plots collection. We can then query/update that particular Plot object’s properties/members. The members of a Plot object are as follows:
We are interested in updating the plot shape property to be Deformed (i.e. Shape = psDeformed/1), enabling the deformed shape autoscale property (i.e. DoAutoscale = True), increasing the contour intervals property to 20 (i.e. ContourLevels = 20), setting the plot view property to Current (i.e. View = “Current”), and setting the plot legend format property to %10.3f (i.e. Format = “%10.3f”).
We will then execute the updated contour plot setting, and write a JPG file of the fringe contours via the Document object’s xPlot method.
Excel VBA
The VBA code to update the plot setting “PlotSeq”, perform the contour plot and save the fringe contours to a JPG file would be:
'Update the plot to be deformed/autoscale and increase the contour levels
Dim myplots As StressCheck.Plots, fringeplot As StressCheck.Plot
Set myplots = SCApp.Document.Plots
Set fringeplot = myplots.Plot("SeqPlot")
fringeplot.Shape = psDeformed
fringeplot.DoAutoscale = True
fringeplot.ContourLevels = 20
fringeplot.View = "Current"
fringeplot.Format = "%10.3f"
'Update contour plot/JPG
SCApp.Document.xPlot "SeqPlot", ThisWorkbook.Path & "\updatedplotvba.jpg", 10, 10, utNone
Python
The Python code to update the plot setting “PlotSeq”, perform the contour plot and save the fringe contours to a JPG file would be:
#Update the plot to be deformed/autoscale and increase the contour levels
myplots = scapp.Document.Plots
fringeplot = myplots.Plot('SeqPlot')
fringeplot.Shape = 1 #psDeformed
fringeplot.DoAutoscale = True
fringeplot.ContourLevels = 20
fringeplot.View = 'Current'
fringeplot.Format = '%10.3f'
#Plot von Mises stress for the model
scapp.Document.xPlot('SeqPlot',os.path.abspath(os.path.dirname(__file__)) + '\updatedplotpy.jpg',10,10,0)
Updating an Extraction Setting
The extraction settings, including the maximum von Mises stress extraction setting “MaxSeq” defined in our previous exercise, are found in the Extractions collection of the Document object. To query/update a specific Extraction item, we will use the Extraction property of the Extractions collection:
Property Extraction(extract_name As String) As Extraction
Entering an extraction setting name (e.g. “MaxSeq”) as the argument for the Extraction property will return the Extraction object associated with that extraction setting name in the Extractions collection. We can then query/update that particular Extraction object’s properties/members. The members of an Extraction object are as follows (edited for length):
We are interested in updating the Min/Max extraction function (i.e. ElasticityFunction member, currently set to efSeq/30) based on user-defined input. We can use a function helper (i.e. StressFunc, defined in the below code) to convert a string representing a stress function (e.g. “S1”) to the appropriate ElasticityFunctions name/value (e.g. efS1/26).
We will then execute the updated extraction setting via the Document object’s xExtractData method, and write a TXT file from the DataTable object via the SaveAs method.
Excel VBA
The VBA code to update the extraction setting “MaxSeq” based on a user-defined input, perform the Min/Max extraction and save the resulting datatable to a TXT file would be:
'Update the min/max extraction to use a user-defined function
Dim myextractions As StressCheck.Extractions, maxextraction As StressCheck.Extraction
Dim UserFunction As String, MyFunc As StressCheck.ElasticityFunctions
UserFunction = InputBox("Enter a new stress function (Sx, Sy, Sz, S1, S2, S3) for max extraction", _
"Update max function extraction")
MyFunc = StressFunc(UserFunction)
Set myextractions = SCApp.Document.Extractions
Set maxextraction = myextractions.Extraction("MaxSeq")
maxextraction.ElasticityFunction = MyFunc
'Extract max and save DataTable to .txt file
Dim SCDT As StressCheck.DataTable
Set SCDT = SCApp.Document.xExtractData("MaxSeq")
SCDT.SaveAs ThisWorkbook.Path & "\max" & UserFunction & "vba.txt"
The function StressFunc is defined as follows:
Function StressFunc(UserFunc As String) As StressCheck.ElasticityFunctions
Select Case UserFunc
Case "S1"
StressFunc = efS1
Case "S2"
StressFunc = efS2
Case "S3"
StressFunc = efS3
Case "Sx"
StressFunc = efSx
Case "Sy"
StressFunc = efSy
Case "Sz"
StressFunc = efSz
Case Else
StressFunc = efSeq
End Select
End Function
Python
The Python code to update the extraction setting “MaxSeq” based on a user-defined input, perform the Min/Max extraction and save the resulting datatable to a TXT file would be :
#Update the min/max extraction to use a user-defined function
userfunction = input('Enter a new stress function (Sx, Sy, Sz, S1, S2, S3) for max extraction:')
myfunc = StressFunc(userfunction)
myextractions = scapp.Document.Extractions
maxextraction = myextractions.Extraction('MaxSeq')
maxextraction.ElasticityFunction = myfunc
#Extract maximum Seq for the model
scdt = scapp.Document.xExtractData('MaxSeq')
scdt.SaveAs(os.path.abspath(os.path.dirname(__file__)) + '\\max' + userfunction + 'py.txt')
The function StressFunc is defined as follows:
def StressFunc (newfunc):
if newfunc == 'Sx': return 20 #efSx
elif newfunc == 'Sy':return 21 #efSy
elif newfunc == 'Sz':return 22 #efSz
elif newfunc == 'S1':return 26 #efS1
elif newfunc == 'S2':return 27 #efS2
elif newfunc == 'S3':return 28 #efS3
else : return 30 #efSeq
Try It Yourself
The complete VBA code for the above example is as follows:
Sub Main()
'We don't want to be disturbed by Excel prompts and alert messages while the macro is running;
'any time a message requires a response, Microsoft Excel chooses the default response.
Application.DisplayAlerts = False
'Declare a StressCheck Application Object (SCApp)
Dim SCApp As StressCheck.Application
'Make SCApp a new StressCheck Application
Set SCApp = New StressCheck.Application
'Show StressCheck GUI
SCApp.Show True
'Open AutoMeshedPlate SCP
SCApp.Document.Open ThisWorkbook.Path & "\AutoMeshPlateSolved.scp"
'Query the countersink cone radii
Dim mycones As StressCheck.Cones, cskcone As StressCheck.Cone
Dim CurrentRad1 As Double, CurrentRad2 As Double, NewRad2 As Double
Set mycones = SCApp.Document.model.Cones
Set cskcone = mycones.ItemAtIndex(0)
CurrentRad1 = cskcone.Radius1Constant
CurrentRad2 = cskcone.Radius2Constant
'Update the major cone radius based on user input value
NewRad2 = CurrentRad1
Do While NewRad2 <= CurrentRad1
NewRad2 = InputBox("The current major radius of the countersink cone is " & CurrentRad2 & ". Enter a new value between " _
& CurrentRad1 & " and " & 1.5 * CurrentRad2 & ":", "Enter a new major cone radius value")
Loop
cskcone.Radius2 = NewRad2
cskcone.Update
'Update the automesh Ratio value to 1.0
Dim myautomeshes As StressCheck.Automeshes, plateautomesh As StressCheck.Automesh
Set myautomeshes = SCApp.Document.model.Automeshes
Set plateautomesh = myautomeshes.Automesh(1)
plateautomesh.Active(apRatio) = True
plateautomesh.Value(apRatio) = 1
plateautomesh.Update
'Re-mesh the model
SCApp.Document.model.Automesh
'Update the display
SCApp.Document.model.Update
'Update the applied traction based on user input
Dim Tx As Double
Tx = InputBox("Enter a new traction load magnitude, in psi", "Update traction load")
'Change the applied load from Normal = 1 to X = Tx
Dim myloads As StressCheck.Loads, tractionload As StressCheck.Load
Set myloads = SCApp.Document.model.Loads
Set tractionload = myloads.Load(0)
tractionload.LoadDirection = dtXYGlobal
tractionload.SetData 0, Tx 'Enter parameter name Tx as the X: field
tractionload.Name = "LOAD2"
tractionload.Update 'Update the load data
'Update the solution ID to use LOAD2
Dim mysolids As StressCheck.SolutionIDs
Set mysolids = SCApp.Document.model.SolutionIDs
mysolids.SolutionID("SOL").LoadName = "LOAD2"
mysolids.SolutionID("SOL").Update
'Update the linear solution from p=2 to 4 to p=1 to 3
Dim mysols As StressCheck.Solutions, linearsol As StressCheck.Solution
Set mysols = SCApp.Document.Solutions
Set linearsol = mysols.Solution("LinearSol")
linearsol.PLevel = 1
linearsol.PLimit = 3
linearsol.Update
'Re-solve the model
SCApp.Document.xSolve "LinearSol"
'Update model display using UpdateDisplay function
UpdateDisplay SCApp
'Update the plot to be deformed/autoscale and increase the contour levels
Dim myplots As StressCheck.Plots, fringeplot As StressCheck.Plot
Set myplots = SCApp.Document.Plots
Set fringeplot = myplots.Plot("SeqPlot")
fringeplot.Shape = psDeformed
fringeplot.DoAutoscale = True
fringeplot.ContourLevels = 20
fringeplot.View = "Current"
fringeplot.Format = "%10.3f"
'Update contour plot/JPG
SCApp.Document.xPlot "SeqPlot", ThisWorkbook.Path & "\updatedplotvba.jpg", 10, 10, utNone
'Update the min/max extraction to use a user-defined function
Dim myextractions As StressCheck.Extractions, maxextraction As StressCheck.Extraction
Dim UserFunction As String, MyFunc As StressCheck.ElasticityFunctions
UserFunction = InputBox("Enter a new stress function (Sx, Sy, Sz, S1, S2, S3) for max extraction", _
"Update max function extraction")
MyFunc = StressFunc(UserFunction)
Set myextractions = SCApp.Document.Extractions
Set maxextraction = myextractions.Extraction("MaxSeq")
maxextraction.ElasticityFunction = MyFunc
'Extract max and save DataTable to .txt file
Dim SCDT As StressCheck.DataTable
Set SCDT = SCApp.Document.xExtractData("MaxSeq")
SCDT.SaveAs ThisWorkbook.Path & "\max" & UserFunction & "vba.txt"
'Close StressCheck
SCApp.Close 'Close the application
Set SCApp = Nothing 'Clear out the SCApp
End Sub
Function UpdateDisplay(SCApp As StressCheck.Application)
'Update display information
SCApp.Document.model.Display.Orientation = vtCenter
SCApp.Document.model.Display.Orientation = vtIsometric
'Change display of objects to show elements only
SCApp.Document.model.Display.Points = False
SCApp.Document.model.Display.Nodes = False
SCApp.Document.model.Display.Surfaces = False
SCApp.Document.model.Display.Curves = False
SCApp.Document.model.Display.Systems = False
SCApp.Document.model.Display.Elements = True
'Display load and constraint attributes
SCApp.Document.model.Display.Attribute(attribLoads, "LOAD2") = True
SCApp.Document.model.Display.Attribute(attribtConstraints, "CONST") = True
'Hide element edges
SCApp.Document.model.Display.Edges = False
End Function
Function StressFunc(UserFunc As String) As StressCheck.ElasticityFunctions
Select Case UserFunc
Case "S1"
StressFunc = efS1
Case "S2"
StressFunc = efS2
Case "S3"
StressFunc = efS3
Case "Sx"
StressFunc = efSx
Case "Sy"
StressFunc = efSy
Case "Sz"
StressFunc = efSz
Case Else
StressFunc = efSeq
End Select
End Function
The complete Python code for the above example is as follows:
#import libraries/modules
import os
import win32com.client as win32
from win32com.client import VARIANT
import pythoncom
from pythoncom import VT_ARRAY
from pythoncom import VT_R8
from pythoncom import VT_I4
def Main():
#Open a new SC
scapp = win32.gencache.EnsureDispatch('StressCheck.Application')
scapp.Show(True)
#Open Automeshed Plate SCP
scapp.Document.Open(os.path.abspath(os.path.dirname(__file__)) + '\\AutomeshPlateSolved.scp')
#Query the cone countersink radii
mycones = scapp.Document.Model.Cones
cskcone = mycones.ItemAtIndex(0)
currentrad1 = cskcone.Radius1Constant
currentrad2 = cskcone.Radius2Constant
#Update the major cone radius based on user input
newrad2 = currentrad1
while newrad2 <= currentrad1:
newrad2 = float(input('Enter a new value for the major radius of the countersink cone > ' + str(currentrad1) + ':'))
cskcone.Radius2 = newrad2
cskcone.Update
#Update the automesh Ratio value to 1.0
myautomeshes = scapp.Document.Model.Automeshes
plateautomesh = myautomeshes.Automesh(1)
plateautomesh.SetActive(1,True)#Activate Ratio
plateautomesh.SetValue(1,1.0) #Update Ratio
plateautomesh.Update
#Re-mesh the model
scapp.Document.Model.Automesh (0)
#Update the display
scapp.Document.Model.Update (0)
#Update the applied traction based on user input
tx = float(input('Enter a new magnitude for the applied traction, in psi:'))
myloads = scapp.Document.Model.Loads
tractionload = myloads.Load(0)
tractionload.LoadDirection = 2 #dtXYGlobal
tractionload.SetData(0, (tx,)) #Update X value to Tx value
tractionload.Name = 'LOAD2'
tractionload.Update #Update the load data
#Update the solution ID to use LOAD2
mysolids = scapp.Document.Model.SolutionIDs
mysolids.SolutionID('SOL').LoadName = 'LOAD2'
mysolids.SolutionID('SOL').Update
#Update the linear solution from p=2 to 4 to p=1 to 3
mysols = scapp.Document.Solutions
linearsol = mysols.Solution('LinearSol')
linearsol.PLevel = 1
linearsol.PLimit = 3
linearsol.Update
#Solve the linear solution
scapp.Document.xSolve('LinearSol')
#Update model display using UpdateDisplay function
UpdateDisplay(scapp)
#Update the plot to be deformed/autoscale and increase the contour levels
myplots = scapp.Document.Plots
fringeplot = myplots.Plot('SeqPlot')
fringeplot.Shape = 1 #psDeformed
fringeplot.DoAutoscale = True
fringeplot.ContourLevels = 20
fringeplot.View = 'Current'
fringeplot.Format = '%10.3f'
#Plot von Mises stress for the model
scapp.Document.xPlot('SeqPlot',os.path.abspath(os.path.dirname(__file__)) + '\updatedplotpy.jpg',10,10,0)
#Update the min/max extraction to use a user-defined function
userfunction = input('Enter a new stress function (Sx, Sy, Sz, S1, S2, S3) for max extraction:')
myfunc = StressFunc(userfunction)
myextractions = scapp.Document.Extractions
maxextraction = myextractions.Extraction('MaxSeq')
maxextraction.ElasticityFunction = myfunc
#Extract maximum Seq for the model
scdt = scapp.Document.xExtractData('MaxSeq')
scdt.SaveAs(os.path.abspath(os.path.dirname(__file__)) + '\\max' + userfunction + 'py.txt')
#Close StressCheck
scapp.Close()
def UpdateDisplay (scapp):
#Set display orientation
scapp.Document.Model.Display.Orientation = 0
scapp.Document.Model.Display.Orientation = 1
#Show elements only
scapp.Document.Model.Display.Points = False
scapp.Document.Model.Display.Nodes = False
scapp.Document.Model.Display.Surfaces = False
scapp.Document.Model.Display.Curves = False
scapp.Document.Model.Display.Systems = False
scapp.Document.Model.Display.Elements = True
#Display load and constraint attributes
scapp.Document.Model.Display.Load = 'LOAD2'
scapp.Document.Model.Display.Constraint = 'CONST'
#Disable element edges
scapp.Document.Model.Display.Edges = False
def StressFunc (newfunc):
if newfunc == 'Sx': return 20 #efSx
elif newfunc == 'Sy':return 21 #efSy
elif newfunc == 'Sz':return 22 #efSz
elif newfunc == 'S1':return 26 #efS1
elif newfunc == 'S2':return 27 #efS2
elif newfunc == 'S3':return 28 #efS3
else : return 30 #efSeq
#Execute the script in Main()
Main()
Download the .xlsm and .py files associated with the above example here: