Getting Started

Bending Moment Extraction

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
1Only scripts with Option Explicit specified can be debugged in the RhinoScript editor (Monkey).
6Global variable for the SnSScript plug-in object.
13-42Define a function to numerically integrate a solution component over a triangle.
14-15Define the quadrature weights and points for integrating over a triangle.
18Compute the area of the current triangle.
22-40Iterate over quadrature weights and points, evaluating the integral of the bending moment due to component stresses.
46-51Define a function to compute the area of a triangle using the cross-product.
57-90Define a function to integrate moments due to component stresses over a surface in Rhino.
64Extract a mesh approximation of the surface.
73Convert the mesh quads to triangles for compatibility with integration algorithm.
77-83Integrate over each mesh face, accumulating their contributions in sumStressMoment.
85Delete the mesh object for the surface.
93-130The main body of the script.
97Load the SnSScript plug-in object.
105Prompt the user to select a solid from the Rhino document. The solid is identified by its GUID stored in strObject.
106Prompt the user to select a section plane from the Rhino document.
109Intersect the plane with the solid to get the intersection curves.
113Convert the section curves into a trimmed plane.
118-119Compute the bending moments from the component stresses and print them out.
121-127Clean up the temporary objects.