Option Explicit
'Script written by <insert name>
'Script copyrighted by <insert company name>
'Script version Friday, July 31, 2015 2:09:30 PM

Call Main()
Sub Main()
	
	'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
	'Script Initialization
	'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
	
	'Declare Variables
	
	'SnS object, solid UID
	Dim objSnSPlugIn, solid 
	
	'SnS solver values
	Dim resolution, resolution_initial
	
	'Factor used to decrease element edge length and volumetrically increase the resolution
	Dim edge_factor
	
	'Solution values to store
	Dim coarse_s, medium_s, fine_s
	
	'Changes between the solution values
	Dim change_coarse_s, change_medium_s
	
	'Point to query, and the tolerance of the converging solution
	Dim point, tolerance

	'Enable SnSScript
	Set objSnSPlugIn = Rhino.GetPluginObject("SnSScript")
	
	'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
	
	'Select solid to analyze
	solid = Rhino.GetObject("Select the solid to check for convergence. The solid must already have loads and restraints defined.")
	
	
	'Check to see if the solid is an extrusion.
	If ( Rhino.IsExtrusion(solid) } Then
		Rhino.MessageBox("Convert the extrusion to a closed polysurface by running the ConvertExtrusion command.  You will have to redefine the loads and restraints by running SnS.")
		Exit Sub
	End If
	

	
	'Select point in the solid to check for convergence
	Point = Rhino.GetPointOnSurface(solid, "Select point to query stress.")

	'edge_factor value:  this is the fraction that the element edge length is decreased by.  
	'A factor of 2 is best, 5/3 is less resource intensive
	edge_factor = 5 / 3
	'Set the initial resolution to run at
	resolution_initial = 20000
	
	'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
	'Iterate through the solutions
	'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
	
	'The course resolution (initial)
	resolution = resolution_initial
	
	'Solve the solid at the initial resolution
	objSnSPlugIn.Solve solid, resolution
	
	'Query the solution at the selected point
	coarse_s = objSnSPlugIn.QuerySolutionValue(solid, "VONM", point)
	
	'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
		
	'Refine the resolution.  The number of elements is related to the edge length cubicly.  
	'Thus, the edge length factor is cubed, and multiplied by the previous resolution, then rounded to an integer.
	resolution = Rhino.Ceil(resolution * edge_factor ^ 3)
	
	'Solve at the intermediate resolution, and query the solution value.
	objSnSPlugIn.Solve solid, resolution
	medium_s = objSnSPlugIn.QuerySolutionValue(solid, "VONM", point)
	
	'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

	'Refine the resolution for the fine resolution
	resolution = Rhino.Ceil(resolution * edge_factor ^ 3)
	'Solve at the fine resolution
	objSnSPlugIn.Solve solid, resolution
	fine_s = objSnSPlugIn.QuerySolutionValue(solid, "VONM", point)
	
	'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
	'Iterations completed:  Show the stress state at best resolution:
	objSnSPlugIn.SolutionDisplayEnable solid, "VONM", 1
	'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
	
	'Calculate the changes in solution value between the resolution steps
	change_coarse_s = medium_s - coarse_s
	change_medium_s = fine_s - medium_s

	'The solution is converging if the second change in solution value is smaller than the first change in solution value.
	'The absolute value of the change values is used to include the possibility of oscillatory convergence.
	If ( Abs(change_coarse_s) > Abs(change_medium_s) ) Then	
		'if the solution is converging, calculate the tolerance.
		'Tolerance is calculated as the percent difference (rounded) between the second and third solution value.
		tolerance = Rhino.Ceil(1000 * Abs(change_medium_s / fine_s)) / 10
		
		'Report convergence and tolerance
		Rhino.MessageBox("Solution is converging, and has converged to a tolerance of:  " & tolerance & "%")
	Else 
		'Report non-convergence
		Rhino.MessageBox("Solution did not converge at the selected point.")
	End If
	

	Rhino.MessageBox("SnS solution data displayed was computed with " & resolution & " elements.")
	
	
End Sub