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

Options
Abel Ramos
Abel Ramos Member, Employee Posts: 30
5 Likes First Answer First Comment First Anniversary

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: 30
    5 Likes First Answer First Comment First Anniversary
    Options

    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: