How to export node normal vectors at each node belonging to a nodal named selection into a csv?

Rohith Patchigolla
Rohith Patchigolla Member, Moderator, Employee Posts: 193
100 Comments 25 Answers Second Anniversary 25 Likes
✭✭✭✭

I have a nodal named selection in Ansys Mechanical. I would like to export the node normal vectors at each of these nodes into a csv file. How can we do this?

Answers

  • Rohith Patchigolla
    Rohith Patchigolla Member, Moderator, Employee Posts: 193
    100 Comments 25 Answers Second Anniversary 25 Likes
    ✭✭✭✭
    edited July 18

    We can do this in Mechanical using Mechanical scripting and Python.

    Below is an example script (there is still scope for improvement in cases where a node shares multiple faces), which takes nodal named selection name as an input, loops over nodes, gets the face ID of the node, and gets the normal. Once loop is completed, it writes out a csv.

    import csv
    import os
    
    # Name of the output CSV file
    output_file_path = "D:\del"
    output_file_name = "vector_data.csv"
    named_selection_name = "NS_Vectors_2"
    
    fullpath = os.path.join(output_file_path, output_file_name)
    
    nodalNS = DataModel.GetObjectsByName(named_selection_name)[0]
    nodeIDs = nodalNS.Location.Ids
    vecNormalX = []
    vecNormalY = []
    vecNormalZ = []
    matrix_full = []
    
    def writeCSV(t1,fileName):
        ExtAPI.Log.WriteMessage('my File name ' + fileName)
        with open(fileName , 'w') as f:
            for line in t1:
                for col in line:
                    #For Non-German
                    #f.write(str(col) + ', ')
                    #For German OS 
                    f.write(str(col).replace(".",",") + '; ')
                f.write('\n')
    
    for nodeId in nodeIDs:
        meshData = DataModel.MeshDataByName(DataModel.MeshDataNames[0])
        meshNode = meshData.NodeById(nodeId) 
        base_point = meshNode.X, meshNode.Y, meshNode.Z
    
        geoIDs = meshNode.GeoEntityIds
        connectedFaceIDs = []
        for geoID in geoIDs:
            if DataModel.GeoData.GeoEntityById(geoID).Type == GeoCellTypeEnum.GeoFace:
                connectedFaceIDs.append(geoID)
    
        if len(connectedFaceIDs) > 1:
            print "Node shared by multiple faces. Only printing of vectors is coded"
            for faceID in connectedFaceIDs:
                myface = DataModel.GeoData.GeoEntityById(faceID)
                u,v = myface.ParamAtPoint(base_point)
                vec_normal = myface.NormalAtParam(u,v)  #Normal Vector to the face at given node
                print(vec_normal)
        else:
            myface = DataModel.GeoData.GeoEntityById(connectedFaceIDs[0])
            u,v = myface.ParamAtPoint(base_point)
            vec_normal = myface.NormalAtParam(u,v)  #Normal Vector to the face at given node
            print(vec_normal)
            vecNormalX.append(vec_normal[0])
            vecNormalY.append(vec_normal[1])
            vecNormalZ.append(vec_normal[2])
    
    matrix_full = [[nodeIDs[i], vecNormalX[i], vecNormalY[i], vecNormalZ[i]] for i in range(len(nodeIDs))]
    writeCSV(matrix_full,fullpath)