How can I calculate relative displacements in Ansys Mechanical using dpf?

Abel Ramos
Abel Ramos Member, Employee Posts: 42
Second Anniversary 5 Answers 10 Comments 5 Likes
✭✭✭✭

Is there a way to calculate the relative displacements between two nodes as a result of a Structural Analysis?

Answers

  • Abel Ramos
    Abel Ramos Member, Employee Posts: 42
    Second Anniversary 5 Answers 10 Comments 5 Likes
    ✭✭✭✭

    We can use dpf to calculate it in Mechanical. And use Mechanical scripting to display the distance in the UI.

    Let's review the following example:

    We have two different bodies with some absolute displacements as shown in the image:

    We can use nodal named selection to identify the reference node and the mobile node, that we'll use for the calculations:

    This is the vector we'd like to calculate to obtain the relative displacement between the two nodes:

    We can use this code to calculate the nodes positions, absolute displacements and relative displacements:

    import os
    import mech_dpf
    import Ans.DataProcessing as dpf
    mech_dpf.setExtAPI(ExtAPI)
    
    #Results File
    analysis = ExtAPI.DataModel.Project.Model.Analyses[0]
    fileLoc = analysis.WorkingDir
    fileName = "file.rst"
    filePath = os.path.join(fileLoc,fileName)
    
    #Get the data source (i.e. result file)
    dataSource = dpf.DataSources(filePath)
    
    #Get the model
    model=dpf.Model(filePath)
    
    #Time Scoping
    timeScoping = dpf.Scoping()
    timeScoping.Ids = [1]
    timeScoping.Location = 'Time'
    
    #-----------------------------------------------#
    #------         REFERENCE VECTOR          ------#
    #-----------------------------------------------#
    #Create Named Selection Scoping For Reference
    nsRefOp = dpf.operators.scoping.on_named_selection()
    nsRefOp.inputs.data_sources.Connect(dataSource)
    nsRefOp.inputs.requested_location.Connect('Nodal')
    nsRefOp.inputs.named_selection_name.Connect("REFERENCE")
    nsRefScoping = nsRefOp.outputs.mesh_scoping
    
    #Reference displacement
    uDispRefOp = dpf.operators.result.displacement()
    uDispRefOp.inputs.data_sources.Connect(dataSource)
    uDispRefOp.inputs.mesh_scoping.Connect(nsRefScoping)
    uDispRefOp.inputs.time_scoping.Connect(timeScoping)
    uDispRef = uDispRefOp.outputs.fields_container.GetData()
    
    #Node Initial Location
    namedSelMesh = nsRefScoping.GetData()
    modelMesh = model.Mesh
    referenceNode = modelMesh.NodeById(namedSelMesh.Ids[0])
    
    originPosField = dpf.FieldsFactory.Create3DVectorField(4,"Nodal")
    originPosField.Add(namedSelMesh.Ids[0],[referenceNode.X,referenceNode.Y,referenceNode.Z])
    
    #Add Operator
    AddOp1=dpf.operators.math.add()
    AddOp1.inputs.fieldA.Connect(uDispRef)
    AddOp1.inputs.fieldB.Connect(originPosField)
    referenceVect=AddOp1.outputs.field.GetData()
    
    #-----------------------------------------------#
    #------          MOBILE VECTOR            ------#
    #-----------------------------------------------#
    #Create Named Selection Scoping For Mobile
    nsMobOp = dpf.operators.scoping.on_named_selection()
    nsMobOp.inputs.data_sources.Connect(dataSource)
    nsMobOp.inputs.requested_location.Connect('Nodal')
    nsMobOp.inputs.named_selection_name.Connect("MOBILE")
    nsMobScoping = nsMobOp.outputs.mesh_scoping
    
    #Mobile displacement
    uDispMobOp = dpf.operators.result.displacement()
    uDispMobOp.inputs.data_sources.Connect(dataSource)
    uDispMobOp.inputs.mesh_scoping.Connect(nsMobScoping)
    uDispMobOp.inputs.time_scoping.Connect(timeScoping)
    uDispMob = uDispMobOp.outputs.fields_container.GetData()
    
    #Node Initial Location
    namedSelMobMesh = nsMobScoping.GetData()
    modelMobMesh = model.Mesh
    mobileNode = modelMobMesh.NodeById(namedSelMobMesh.Ids[0])
    
    originPosMobField = dpf.FieldsFactory.Create3DVectorField(4,"Nodal")
    originPosMobField.Add(namedSelMobMesh.Ids[0],[mobileNode.X,mobileNode.Y,mobileNode.Z])
    
    #Add Operator
    AddOp2=dpf.operators.math.add()
    AddOp2.inputs.fieldA.Connect(uDispMob)
    AddOp2.inputs.fieldB.Connect(originPosMobField)
    mobileVect=AddOp2.outputs.field.GetData()
    
    #-----------------------------------------------#
    #------          RELATIVE CALC            ------#
    #-----------------------------------------------#
    saveRefNodeId = referenceVect.ScopingIds
    referenceVect.ScopingIds = mobileVect.ScopingIds
    
    minusOp = dpf.operators.math.minus()
    minusOp.inputs.fieldA.Connect(mobileVect)
    minusOp.inputs.fieldB.Connect(referenceVect)
    relativeVector = minusOp.outputs.field.GetData()
    
    #Adding Reference Node
    relativeVector.Add(saveRefNodeId[0],[0.0,0.0,0.0])
    
    print(relativeVector)
    
    convFact=1e-3
    graphics = ExtAPI.Graphics
    p1=graphics.CreateWorldPoint(convFact*mobileVect.Data[0],convFact*mobileVect.Data[1],convFact*mobileVect.Data[2])
    p2=graphics.CreateWorldPoint(convFact*referenceVect.Data[0],convFact*referenceVect.Data[1],convFact*referenceVect.Data[2])
    line=graphics.Scene.Factory3D.CreatePolyline([p2,p1])
    line.LineWeight = 4
    
    #To Clean The Scene
    #graphics.Scene.Clear()
    
    

    Nodes Ids in this example:
    Reference = 7
    Mobile = 86

    The output will provide the values of the relative displacements:

    And it will display the distance in Mechanical UI

    Relative Vector Calc: