API create Springs or Beam at Coincidental Nodes to Represent Fastener Holes

Pioneer
Pioneer

Hi

I am looking for an API to create springs or Beam to represent Rivets or Hardwares between the two nodes offset by distance.

 

Inputs - Nodel tolerance or offset between the Nodes

Output - Beam or Springs between the nodes

 

I am having ~ 1000+ Hardwares in my Model. I am using Femap 10.0.2

 

Regards

srini

6 REPLIES 6

Re: API create Springs or Beam at Coincidental Nodes to Represent Fastener Holes

Pioneer
Pioneer

I am using the Following Code which exists in Femap 11.4 , creates fastener by selecting the two curves. This is the Description

 

This API is designed for shell/mid-surface FEA models.  It is limited to connecting two
circular holes, made up of two sets of curves.  

The API asks the user to select two sets of curves.  From the first set, first curve,
it finds the diameter of the hole.  It then uses this, and the active material, to
create, or locate and existing beam property.  It then creates two rigid spiders and
connects them with an element using the property.

Sub Main

    Dim App As femap.model
    Set App = feFemap()

    Dim feNode As femap.Node

    Dim nodeSet As femap.Set

    Dim feElem As femap.Elem

    Dim nodeCount As Long
    Dim nodeX As Double
    Dim nodeY As Double
    Dim nodeZ As Double
    Dim nodeID As Long
    Dim elemID As Long
    Dim vNodeArray As Variant
    Dim RAD As Double

    Dim cuSet As femap.Set
    Set cuSet = App.feSet

	Set nodeSet = App.feSet()
    Set cuSet = App.feSet

    Set nodeSet = App.feSet()

   	Dim cuID As Long

	Dim feCurve As femap.Curve
	Set feCurve = App.feCurve

	Dim cuCenter As Variant
	Dim cuNormal As Variant
	Dim cuStartPt As Variant
	Dim cuEndPt As Variant
	Dim cuAngle As Double
	Dim cuRadius As Double
	Dim pt1(3) As Double
	Dim pt2(3) As Double
	Dim ptID1 As Long
	Dim ptID2 As Long

	Dim fePoint As femap.Point
	Set fePoint = App.fePoint

	Dim passCount As Long

	Dim nodeSet1 As femap.Set
    Dim nodeCount1 As Long
    Dim nodeX1 As Double
    Dim nodeY1 As Double
    Dim nodeZ1 As Double
    Dim nodeID1 As Long
    Dim elemID1 As Long
    Dim vNodeArray1 As Variant
    Dim passCount1 As Long

	Dim feProp As femap.Prop
	Set feProp = App.feProp

	Dim BeamArea As Double
    Dim Vec(3) As Variant
    Dim X As Double
    Dim Y As Double
    Dim Z As Double
    Dim X1 As Double
    Dim Y1 As Double
    Dim Z1 As Double
    Dim VecP As Variant

    Set nodeSet1 = App.feSet()

    Dim feMatl As femap.Matl
    Set feMatl = App.feMatl
    Dim matID As Long

    matID = App.Info_ActiveID( FT_MATL )

    If matID = 0 Then
    	Msg = "No active material for fastener, please activate a material and re-run."
        rc = MsgBox( Msg, vbOkOnly, "No Material" )
        GoTo Jumping_Out
    End If

    rc = feMatl.Get( matID )

DO_IT_AGAIN:
    RAD= 0.0
    nodeX = 0#
    nodeY = 0#
    nodeZ = 0#
    nodeX1 = 0#
    nodeY1 = 0#
    nodeZ1 = 0#


     ' Get a set of nodes for this rigid element

	rc = cuSet.Select( FT_CURVE, True, "Select Curves at Fastener Bottom")
	If cuSet.count = 0 Then
		GoTo Jumping_Out
	End If

	cuID = cuSet.First
	rc = feCurve.Get(cuID)
	rc = feCurve.ArcCircleInfo( cuCenter, cuNormal, cuStartPt, cuEndPt, cuAngle, cuRadius )
	If rc <> FE_OK Then
    	Msg = "Curves must be circular, exiting."
        rc = MsgBox( Msg, vbOkOnly, "No Material" )
        GoTo Jumping_Out
	End If

    RAD = cuRadius

	rc = nodeSet.Clear()
	rc = nodeSet.AddSetRule( cuSet.ID, FGD_NODE_ATCURVE )

    If rc = -1 Then 'return code FE_OK
	    'Lets see how many nodes were selected
	    nodeCount = nodeSet.count()
	    If nodeCount > 0 Then
	       ' Walk the nodes and find the average
	        Set feNode = App.feNode()
	        rc = nodeSet.Reset()
	        nodeID = nodeSet.Next()
	        ReDim nodeArray(nodeCount) As Long
	        passCount = 0
	        Do While nodeID <> 0
	            nodeArray(passCount) = nodeID
	            passCount = passCount + 1
	            rc = feNode.Get(nodeID)
	            nodeX = nodeX + feNode.x
	            nodeY = nodeY + feNode.y
	            nodeZ = nodeZ + feNode.z
	            nodeID = nodeSet.Next()
	        Loop
			vNodeArray = nodeArray
	        nodeID = feNode.NextEmptyID
	        feNode.ID = nodeID
	        feNode.x = nodeX / nodeCount
	        feNode.y = nodeY / nodeCount
	        feNode.z = nodeZ / nodeCount
	        rc = feNode.Put(nodeID)
	        If rc = -1 Then 'return code FE_OK
	        	' create the element
				Set feElem = App.feElem()
				elemID = feElem.NextEmptyID
	            feElem.type = FET_L_RIGID
                feElem.topology = FTO_RIGIDLIST
	            feElem.Node(0) = nodeID 'Independent Node
	            feElem.release(0, 0) = 1
	            feElem.release(0, 1) = 1
	            feElem.release(0, 2) = 1
	            feElem.ID = elemID
                rc = feElem.PutNodeList(0, nodeCount, vNodeArray, Null, Null, Null)
	            rc = feElem.Put(elemID)
	        End If
	    End If
	End If

    ' Get a set of nodes for this rigid element
    rc = cuSet.Select( FT_CURVE, True, "Select Curves at Top at Hole")
    rc = nodeSet1.Clear()
    rc = nodeSet1.AddSetRule( cuSet.ID, FGD_NODE_ATCURVE )
    If rc = -1 Then 'return code FE_OK
	    'Lets see how many nodes were selected
	    nodeCount1 = nodeSet1.count()
	    If nodeCount1 > 0 Then
	        ' Walk the nodes and find the average
	        Set feNode = App.feNode()
	        rc = nodeSet1.Reset()
	        nodeID1 = nodeSet1.Next()
	        ReDim nodeArray1(nodeCount1) As Long

	        passCount1 = 0
	        Do While nodeID1 <> 0
	        	nodeArray1(passCount1) = nodeID1
        		passCount1 = passCount1 + 1
	            rc = feNode.Get(nodeID1)
	            nodeX1 = nodeX1 + feNode.x
	            nodeY1 = nodeY1 + feNode.y
	            nodeZ1 = nodeZ1 + feNode.z
	            nodeID1 = nodeSet1.Next()
	        Loop
        	vNodeArray1 = nodeArray1
	        nodeID1 = feNode.NextEmptyID
	        feNode.ID = nodeID1
	        feNode.x = nodeX1/ nodeCount1
	        feNode.y = nodeY1/ nodeCount1
	        feNode.z = nodeZ1/ nodeCount1
	        rc = feNode.Put(nodeID1)
	        If rc = -1 Then 'return code FE_OK
	            ' create the element
	            Set feElem = App.feElem()
	            elemID = feElem.NextEmptyID
                feElem.type = FET_L_RIGID
                feElem.topology = FTO_RIGIDLIST
	            feElem.Node(0) = nodeID1 'Independent Node
	            feElem.release(0, 0) = 1
	            feElem.release(0, 1) = 1
	            feElem.release(0, 2) = 1
	            feElem.ID = elemID
	            rc = feElem.PutNodeList(0, nodeCount1, vNodeArray1, Null, Null, Null)
	            rc = feElem.Put(elemID)
	        End If
	    End If
	End If

    Dim El As femap.Elem
    Set El = App.feElem
    Dim BeamElID As Long
    Dim PropID As Long
    Dim P As femap.Prop
    Set P = App.feProp
    Dim BeamID As Long

	'Section Values A
	If RAD = 0.0 Then
		 App.feGetReal ("Enter Bolt Radius", 0.000000001, 100000, RAD)
	End If

	PropID = 0


	BeamArea = 3.141592653 * RAD * RAD

	While feProp.Next
		If feProp.title = "API Fastener" Then
			If Abs( feProp.pval(0) - BeamArea ) < 0.001 Then
				PropID = feProp.ID
				GoTo GOT_A_PROP
			End If
		End If
	Wend

	PropID = P.NextEmptyID
	P.title = "API Fastener"
    P.type = FET_L_BEAM
    P.flagI(1) = 5
    P.pval (40) = RAD
    P.ComputeShape (False, False, True)
    P.Put(PropID)

GOT_A_PROP:

    Msg = "Fastener Diameter " + Format$(2*cuRadius,"###.####") + ", Property " + Str$(PropID) + ", Material ID " + Str$(matID) + ", Titled " + feMatl.title
    rc = App.feAppMessage( FCM_NORMAL, Msg )

    BeamElID = El.NextEmptyID
    El.type = FET_L_BEAM
    El.Node (0) = nodeID
    El.Node (1) = nodeID1
    rc = feNode.Get (nodeID)
    X = feNode.x
    Y = feNode.y
    Z = feNode.z
    rc = feNode.Get (nodeID1)
    X1 = feNode.x
    Y1 = feNode.y
    Z1 = feNode.z
    Vec(0) = X - X1
    Vec(1) = Y - Y1
    Vec(2) = Z - Z1
    rc = App.feVectorPerpendicular (Vec, VecP)
    El.orient(0) = VecP(0)
    El.orient(1) = VecP(1)
    El.orient(2) = VecP(2)
    El.propID = PropID
    El.Put (BeamElID)

    rc = App.feViewRegenerate(0)

    GoTo DO_IT_AGAIN

Jumping_Out:

End Sub

I am facing the Following error in Femap 10.0.2

Error.png

 

Regards

srini

Re: API create Springs or Beam at Coincidental Nodes to Represent Fastener Holes

Siemens Phenom Siemens Phenom
Siemens Phenom

I ran it on a test model that looks like this in 10.0.2 and I wasn't getting that error. Are you trying it on a model without mesh?

 

Before:

Bolt for hole before.JPG

After:

Bolt for hole after.JPG

Re: API create Springs or Beam at Coincidental Nodes to Represent Fastener Holes

Pioneer
Pioneer

I am looking for the Modification of the Script where It can create springs are fasteners.

The Current scripts creates rigid followed by the spider.

 

I have two plates, Holes are not modelled but the center node is captured . Need to create a spring or beam element between the two plates as shown below.

Red color(I need to create springs or Beam)

Error.png

 

Regards

srini

Re: API create Springs or Beam at Coincidental Nodes to Represent Fastener Holes

Pioneer
Pioneer

This is the manual step I am following

Error.png

Re: API create Springs or Beam at Coincidental Nodes to Represent Fastener Holes

Siemens Phenom Siemens Phenom
Siemens Phenom

I have written an API that will automatically create beam elements to represent fasteners. The model must already have mesh points created at the center of holes on each surface. The user is prompted to specify a search tolerance which is the distance between the surfaces. If the user does not know the distance they can use “Ctrl + D” while focus is in the dialog box to measure the between the two surfaces. The distance will propagate in the dialog box. In the next dialog box the user will need to specify the diameter of faster which will be used to create the beam property.

Unfortunately there are some methods in this API that were not available in 10.0.2. I wrote this in 11.4.1 but all the methods should work in 11.3 as well.

Do you not have access to a newer version of Femap?

The HTML Clipboard

Sub Main
    Dim App As femap.model
    Set App = feFemap()

    Dim AllPtSet As femap.Set
    Set AllPtSet = App.feSet

    Dim AllCurveSet As femap.Set
    Set AllCurveSet = App.feSet

    Dim AllPtsOnCurvesSet As femap.Set
    Set AllPtsOnCurvesSet = App.feSet

    Dim pt As femap.Point
    Set pt = App.fePoint

    Dim nd As femap.Node
    Set nd = App.feNode

    Dim btNd1 As femap.Node
    Set btNd1 = App.feNode

    Dim btNd2 As femap.Node
    Set btNd2 = App.feNode

    Dim elm As femap.Elem
    Set elm = App.feElem

    Dim eSet As femap.Set
    Set eSet = App.feSet

    Dim nrmElem As femap.Elem
    Set nrmElem = App.feElem

    Dim prp As femap.Prop
    Set prp = App.feProp

    Dim tol As Double
    Dim ptID As Long
    Dim ndCnt As Long
    Dim ndVar As Variant
    Dim ptxyz(3) As Variant

    Dim vLen As Double
    Dim vBase As Variant
    Dim vDir As Variant

    Dim btNd1ID As Long
    Dim btNd2ID As Long
    Dim beamID As Long

    Dim btDia As Double
    Dim prpID As Long

    Dim vec(3) As Variant
    Dim vecP As Variant

    AllPtSet.AddAll (FT_POINT)

    AllCurveSet.AddAll (FT_CURVE)

    AllPtsOnCurvesSet.AddSetRule (AllCurveSet.ID, FGD_POINT_ONCURVE)

    AllPtSet.RemoveSet (AllPtsOnCurvesSet.ID)

    If AllPtSet.Count < 2 Then End

    AllPtSet.Show (FT_POINT)

    matID = App.Info_ActiveID( FT_MATL )

    If matID = 0 Then
        Msg = "No active material for fastener, please activate a material and re-run."
        rc = MsgBox( Msg, vbCritical, "No Material" )
        If rc = 1 Then End
    End If

    If App.feGetReal("Specify Tolerance (Distance Between Surfaces)", 0.0, 100000.0, tol) <> FE_OK Then End

    If App.feGetReal("Specify Diameter of Fastener", 0.0, 1000000.0, btDia) <> FE_OK Then End
    prpID = prp.NextEmptyID
    prp.title = "API Fastener"
    prp.type = FET_L_BEAM
    prp.flagI(1) = 5
    prp.pval (40) = btDia/2
    prp.ComputeShape (False, False, True)
    prp.Put(prpID)

    While AllPtSet.Next
        ptID = AllPtSet.CurrentID
        pt.Get(ptID)

        rc = pt.Nodes(ndCnt, ndVar)

        If rc = 0 Then
            GoTo next_pt
        End If

        btNd1ID = ndVar(0)

        eSet.Reset()
        eSet.AddRule(btNd1ID,FGD_ELEM_BYNODE)
        nrmElemID = eSet.First
        nrmElem.Get(nrmElemID)
        nrmElem.GetFaceNormal(2, vDir)

        ptxyz(0) = pt.x + tol*vDir(0)
        ptxyz(1) = pt.y + tol*vDir(1)
        ptxyz(2) = pt.z + tol*vDir(2)

        rc = pt.GetClosest(ptxyz)

        d = Sqr((pt.x-ptxyz(0))^2+(pt.y-ptxyz(1))^2+(pt.z-ptxyz(2))^2)

        If d > btDia/2 Then
            pt.Get(ptID)
            ptxyz(0) = pt.x - tol*vDir(0)
            ptxyz(1) = pt.y - tol*vDir(1)
            ptxyz(2) = pt.z - tol*vDir(2)

            rc = pt.GetClosest(ptxyz)
        End If

        If pt.ID = ptID Then
            ptxyz(0) = pt.x - tol*vDir(0)
            ptxyz(1) = pt.y - tol*vDir(1)
            ptxyz(2) = pt.z - tol*vDir(2)

            rc = pt.GetClosest(ptxyz)
        End If

        d = Sqr((pt.x-ptxyz(0))^2+(pt.y-ptxyz(1))^2+(pt.z-ptxyz(2))^2)

        If d > btDia/2 Then
            GoTo next_pt
        End If

        AllPtSet.Remove(pt.ID)

        ndCnt = vbNull
        ndVar = vbNull

        pt.Nodes(ndCnt, ndVar)

        btNd2ID = ndVar(0)

        btNd1.Get(btNd1ID)
        btNd2.Get(ntNd2ID)

        beamID = elm.NextEmptyID
        elm.type = FET_L_BEAM
        elm.Node (0) = btNd1ID
        elm.Node (1) = btNd2ID
        X = btNd1.x
        Y = btNd1.y
        Z = btNd1.z
        X1 = btNd2.x
        Y1 = btNd2.y
        Z1 = btNd2.z
        vec(0) = X - X1
        vec(1) = Y - Y1
        vec(2) = Z - Z1
        rc = App.feVectorPerpendicular (vec, vecP)
        elm.orient(0) = vecP(0)
        elm.orient(1) = vecP(1)
        elm.orient(2) = vecP(2)
        elm.propID = prpID
        elm.Put (beamID)

        next_pt:
    Wend

    App.feViewRegenerate(0)

End Sub

Re: API create Springs or Beam at Coincidental Nodes to Represent Fastener Holes

Pioneer
Pioneer

Hi Giampietro

Thank you so much for providing the API, It should work from 11.3 as mentioned.

But Unfortunately I don't have access to 11.3 as I am currently working now on 10.0.2.

Thank you so much for your quick reply and the solution I will get back to you shortly

 

Regards

srini