The following example demonstrates how internal stresses computed using Scan&Solve can be integrated to approximate the bending moment acting in a beam model. A short video showing the script in operation may be viewed here.
Option Explicit
'Script written by Michael Freytag
'Script version Monday, September 16, 2013 3:10:56 PM
'variable for the SnSScript plug-in object
Public objSnSPlugin
'quadIntegrateMoments: Integrate over the triangle defined by the array of vertices
'in arrVerts using a 7 point quadrature rule
'strObject -the solid with SnS solution data
'arrVerts -the vertices of the triangle to integrate over
'arrCentroid -the centroid of the surface around which moments are being computed
Function IntegrateMoments(strObject, arrVerts, arrCentroid)
Dim quadWts:quadWts = Array(0.225, 0.13239415, 0.13239415, 0.13239415, 0.12593918, 0.12593918, 0.12593918)
Dim quadCoords:quadCoords = Array(0.33333333, 0.33333333, 0.33333333, 0.05961587, 0.47014206, 0.47014206, 0.47014206, 0.05961587, 0.47014206, 0.47014206, 0.47014206, 0.05961587, 0.79742699, 0.10128651, 0.10128651, 0.10128651, 0.79742699, 0.10128651, 0.10128651, 0.10128651, 0.79742699)
Dim quadPt(2), coord
Dim area: area = TriangleArea(arrVerts)
Dim arrQuadratureForce, arrQuadratureMoment, arrQuadratureRadius, arrSum
Dim quadID: quadID = 0
arrSum = Array(0, 0, 0)
While quadID <= UBound(quadWts)
For coord= 0 To 2
quadPt(coord) = (arrVerts(0)(coord) * quadCoords(quadID * 3)) + (arrVerts(1)(coord) * quadCoords(quadID * 3 + 1)) + (arrVerts(2)(coord) * quadCoords(quadID * 3 + 2))
Next
'retrieve the component stresses at the quadrature point
arrQuadratureForce = Array(objSnSPlugin.QuerySolutionValue(strObject, "SIGXX", quadPt), objSnSPlugin.QuerySolutionValue(strObject, "SIGYY", quadPt), objSnSPlugin.QuerySolutionValue(strObject, "SIGZZ", quadPt))
'multiply component stress by area to get force at quadrature point
arrQuadratureForce = Rhino.VectorScale(arrQuadratureForce, quadWts(quadID) * area)
'compute the radius to the quadrature point
arrQuadratureRadius = Rhino.VectorSubtract(quadPt, arrCentroid)
'compute RxF to get the contribution to the moment
arrQuadratureMoment = Rhino.VectorCrossProduct(arrQuadratureRadius, arrQuadratureForce)
'accumulate the sum for the numerical integration, skip numerical outliers
If Rhino.VectorLength(arrQuadratureForce) < 10000 Then
arrSum = Rhino.VectorAdd(arrSum, arrQuadratureMoment)
End If
quadID = quadID + 1
Wend
IntegrateMoments = arrSum
End Function
'TriangleArea: Utility function to compute the area of the triangle defined
'by the array of vertices in arrVerts
Function TriangleArea(arrVerts)
Dim vec0: vec0 = Rhino.VectorSubtract(arrVerts(1), arrVerts(0))
Dim vec1: vec1 = Rhino.VectorSubtract(arrVerts(2), arrVerts(0))
Dim vecCross: vecCross = Rhino.VectorCrossProduct(vec0, vec1)
TriangleArea = 0.5 * Rhino.VectorLength(vecCross)
End Function
'StressForce: Utility function to integrate a stress components over a surface
'to determine the moments acting about the centroid of the surface
'strObject -the solid with SnS solution data
'strSurfaceObject -the surface over which the integration should occur (typically a cross-section of strObject)
Function StressMoment(strSolid, strSection)
Dim meshObject,arrFaces,arrVerts(2),fid,arrCentroid
Dim sumStressMoment
sumStressMoment = Array(0, 0, 0)
'Extract the analysis mesh for the surface objects
If Rhino.IsObject(strSection) Then
meshObject = Rhino.ExtractAnalysisMesh(strSection)
Else
Rhino.Print "Invalid surface object"
StressMoment = Array(0, 0, 0)
End If
'Integrate the desired stress component over the facets of the extracted mesh
If Not IsNull(meshObject) Then
arrCentroid = Rhino.SurfaceAreaCentroid(strSection)
Rhino.MeshQuadsToTriangles meshObject
arrFaces = Rhino.MeshFaces(meshObject, False)
If IsArray(arrFaces) Then
fid = 0
While fid <= UBound(arrFaces)
arrVerts(0) = arrFaces(fid)
arrVerts(1) = arrFaces(fid + 1)
arrVerts(2) = arrFaces(fid + 2)
fid = fid + 3
sumStressMoment = Rhino.VectorAdd(sumStressMoment, IntegrateMoments(strSolid, arrVerts, arrCentroid(0)))
Wend
End If
Rhino.DeleteObject meshObject
Else
Rhino.Print "Unable to extract analysis mesh"
End If
StressMoment = sumStressMoment
End Function
Call Main()
Sub Main()
Dim strObject, strPlane, arrCurves, arrSection, strSection, arrMoments
On Error Resume Next
Set objSnSPlugIn = Rhino.GetPluginObject("SnSScript")
objSnSPlugIn.SetOutputOnOff False
If Err Then
MsgBox Err.Description
Exit Sub
End If
strObject = Rhino.GetObject("Select a solid")
strPlane = Rhino.GetObject("Select a plane", 8)
'compute the curves of the intersection between the solid and the plane
arrCurves = Rhino.IntersectBreps(strObject, strPlane)
If Not IsNull(arrCurves) Then
'construct a planar surface
arrSection = Rhino.AddPlanarSrf(arrCurves)
'WARNING! The output from AddPlanarSrf can be a collection of surfaces.
'For simplicity only the zeroth one is used. Otherwise their collective
'centroid must be used and their results accumulated. This code DOESN'T
'do that.
arrMoments = StressMoment(strObject, arrSection(0))
Rhino.Print arrMoments(0) & "," & arrMoments(1) & "," & arrMoments(2)
'clean up by deleting curves and the cross-sections
Dim i
For i = 0 To ubound(arrCurves)
Rhino.DeleteObject arrCurves(i)
Next
For i= 0 To ubound(arrSection)
Rhino.DeleteObject arrSection(i)
Next
End If
End Sub
| Line # | Description |
|---|---|
| 1 | Only scripts with Option Explicit specified can be debugged in the RhinoScript editor (Monkey). |
| 6 | Global variable for the SnSScript plug-in object. |
| 13-42 | Define a function to numerically integrate a solution component over a triangle. |
| 14-15 | Define the quadrature weights and points for integrating over a triangle. |
| 18 | Compute the area of the current triangle. |
| 22-40 | Iterate over quadrature weights and points, evaluating the integral of the bending moment due to component stresses. |
| 46-51 | Define a function to compute the area of a triangle using the cross-product. |
| 57-90 | Define a function to integrate moments due to component stresses over a surface in Rhino. |
| 64 | Extract a mesh approximation of the surface. |
| 73 | Convert the mesh quads to triangles for compatibility with integration algorithm. |
| 77-83 | Integrate over each mesh face, accumulating their contributions in sumStressMoment. |
| 85 | Delete the mesh object for the surface. |
| 93-130 | The main body of the script. |
| 97 | Load the SnSScript plug-in object. |
| 105 | Prompt the user to select a solid from the Rhino document. The solid is identified by its GUID stored in strObject. |
| 106 | Prompt the user to select a section plane from the Rhino document. |
| 109 | Intersect the plane with the solid to get the intersection curves. |
| 113 | Convert the section curves into a trimmed plane. |
| 118-119 | Compute the bending moments from the component stresses and print them out. |
| 121-127 | Clean up the temporary objects. |