For a solved Static Structural that includes an Equivalent Stress result, this script finds the locations where high stresses occur and places a label on them. Here is an illustrated example.
The script specifies the insertion of seven labels. The script places the first label at the result’s maximum value, and each subsequent label is placed at a distance of 0.01 (script line 25) in between each node. This distance between labels makes sure that all labels will not be clustered around the maximum value. The unit for this distance is based on what you have selected in your analysis. For the example above, the selected unit is meters. In addition, and again based on the currently selected unit of measure, the result threshold is 20 (script line 27). This means that no result value (or label) below this threshold is included.
import mech_dpf import Ans.DataProcessing as dpf def nodeDist(cur_node,nodes_dict,test_dist): # Compute distance between a reference node (cur_node) and # a set of nodes nodes_dict and check vs a test distance (test_dist) # if any of the nodes in nodes_dict is close to cur_node within # less than test_dist, then return False. Otherwise cur_node is # away from each node in nodes_dict by at least test_dist test=True for nodeId in nodes_dict.keys(): test_node=nodes_dict[nodeId] dist=0. for i in range(0,3): dist+=(test_node[i]-cur_node[i])**2 if (dist<=test_dist**2): test=False break return test # Number of labels to display numLabels=7 # Minimal distance between two labels (in current Mechanical unit) minDistBetweenNodes=0.1 # Minimal stress value for which label should be displayed (in current Mechanical Unit) thresholdStress=20. # Dictionaries to store results maxPairs={} maxNodes={} # Retrieve 'Static Structural' analysis - replace analysis name # based on your current model analysis=ExtAPI.DataModel.AnalysisByName('Static Structural') # Retrieve first 'Equivalent Stress' object. replace object name # based on your current model resultObject=ExtAPI.DataModel.GetObjectsByName('Equivalent Stress')[0] # Define datasources (rst from analysis) dataSource = dpf.DataSources(analysis.ResultFileName) # Create Mises operator vmises = dpf.operators.result.stress_von_mises() vmises.inputs.data_sources.Connect(dataSource) # retrieve mesh from rst model=dpf.Model(dataSource) mesh=model.Mesh # Min_max operator will be used to identify hotspots min_max = dpf.operators.min_max.min_max() # operator instanciation # Temporary operator currentMises = vmises.outputs.getfields_container() # Filter used to progressively filter data when maxima are found tempFilter = dpf.operators.filter.field_low_pass() # operator instanciation # Filter out stresses below thresholdStress initFilter = dpf.operators.filter.field_high_pass() # operator instanciation initFilter.inputs.field.Connect(currentMises) initFilter.inputs.threshold.Connect(thresholdStress) # update currentMises with results from filter currentMises = initFilter.outputs.getfield() if not(currentMises.Data): ExtAPI.Application.LogWarning('Threshold value exceeds maximum stress. Please set a lower value for "thresholdStress" variable ') # Start looking for hotspots numFound=0 while numFound<numLabels and currentMises.Data: # in current stress field, search for max value min_max.inputs.field.Connect(currentMises) maxData = min_max.outputs.field_max.GetData() # Check whether scoping node is far from other nodes if numFound>0: # at least one label was found, we need to check for distance maxNodeId=maxData.ScopingIds[0] maxValue=maxData.Data[0] # Retrieve information from node at max value out of result mesh node=mesh.NodeById(maxNodeId) nodeCoord=[node.X, node.Y,node.Z] if nodeDist(nodeCoord,maxNodes,minDistBetweenNodes): # node if node is far enough from all other nodes, add to labels # otherwise, we simply ignore this maximum maxNodes[maxNodeId]=nodeCoord maxPairs[maxValue]=maxNodeId numFound+=1 else: # first label at maximum value # Retrieve max value and corresponding node from maxData operator maxValue=maxData.Data[0] maxNodeId=maxData.ScopingIds[0] # Start population data in maxPairs (maxvalue:node id) # and maxNodes (node id: x,y,z) maxPairs[maxValue]=maxNodeId node=mesh.NodeById(maxNodeId) maxNodes[maxNodeId]=[node.X, node.Y,node.Z] numFound+=1 # Filter out anything above last max value from currentMises tempFilter.inputs.field.Connect(currentMises) tempFilter.inputs.threshold.Connect(maxValue) currentMises = tempFilter.outputs.getfield() if numFound<numLabels and numFound>0: ExtAPI.Application.LogWarning('Could not find more than '+str(numFound)+' hotspots. You should set "thresholdStress" variable or "minDistBetweenNodes" to lower values') if numFound==0: ExtAPI.Application.LogWarning('Could not find any hotspots. You should set "thresholdStress" variable or "minDistBetweenNodes" to lower values') else: # Create labels on result object with Transaction(): labelsForRes = Graphics.LabelManager.GetObjectLabels(resultObject) Graphics.LabelManager.DeleteLabels(labelsForRes) for node in maxPairs.values(): probeLabel = Graphics.LabelManager.CreateProbeLabel(resultObject) probeLabel.Scoping.Node = node