Skip to content Skip to sidebar Skip to footer

Abaqus: A Way To Localize External Nodes?

Does anyone of you know of (if there exists) a way to extract node numbers of an external surface of a model in Abaqus? By a surface I dont mean an entity, Im talking purely about

Solution 1:

If you have defined a Set or Surface, getting the nodes is trivial:

p = mdb.models[name].parts[name]
# Get the Node objects on the previously defined surface:node_objects = p.surfaces[name].nodes
# Same from a set:node_objects = p.sets[name].nodes
# Get the labels for the Node objects:node_labels = [node.label for node in node_objects]

If you define the Set or Surface using the part geometry, it doesn't change if you remesh the part.

However, if you do not have a Set or Surface, and you can't create/get one easily, then you have to loop over some other object in the part that you can use to check if it's on the surface. One approach is shown by @max9111. However, I suggest looping over the part elementFaces list. This is a list of unique Face objects defined by the elements of the mesh. I say unique because if two elements share a face, it's only put in the list once. This is different from the very similarly named elemFaces list. Look it up.

In the example below, you get the Node objects directly, and from them you can get the node labels/coordinates/etc if desired.

p = mdb.models[name].parts[name]
surf_nodes = []
for face in p.elementFaces():
    if len(face.getElements()) == 1:
        # Then the face has only one associated element, ie it's on the surface.# Get the nodes on the face:
        surf_nodes.extend([node for node in face.getNodes() if node not in surf_nodes])
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# Example usage/output for some arbitrary part/mesh:
>>>len(surf_nodes)           # <-- A normal list of node objects.
14
>>>surf_nodes[0]             # <-- Refer to an individual node object.
mdb.models[name].parts[name].nodes[2]
>>>surf_nodes[0].label       # <-- From it you can access all kinds of stuff.
3
>>>surf_nodes[0].coordinates
(0.0, 10.0, 10.0)

And so, in 5 lines of code you pretty efficiently obtain all of the nodes over the entire surface of the mesh. This works for any element type in the mesh, of course. Unfortunately, you still loop over all internal faces, but that's fewer operations than checking the face on each element, since each internal face must only be checked once. That said, you could probably reduce the number of faces that must be checked, but that is for another question.

Solution 2:

At first you will need the Connectivity of your Elements and the Element Type. In the Abaqus manual(+) you will find the definition of the element faces. Each face which exists only once in your model is a surface face, so the nodes belonging to that surface faces are surface nodes.

(+) 28.1.4 in the Abaqus Analysis User's Guide

The following example needs numpy >=1.9. If you have an older numpy version you have to find another way to get faces which occur only once.

# for example C3D4, np_Connectivity is a numpy array describing the element connectivitydefget_Surface_Nodes_tet(np_Connectivity):
    #Face definition
    Face=np.concatenate((np_Connectivity[:,[0,1,2]],np_Connectivity[:,[0,3,1]],np_Connectivity[:,[1,3,2]],np_Connectivity[:,[2,3,0]]))

    #Sort the nodes of the faces
    Face.sort()

    #get the faces which are only once in the array
    b = np.ascontiguousarray(Face).view(np.dtype((np.void, Face.dtype.itemsize * Face.shape[1])))
    #min numpy version=1.9
    _, idx_2,counts = np.unique(b, return_index=True,return_counts=True)
    only_once=np.where(counts<2)
    idx=idx_2[only_once[0]]

    #All nodes of faces, which occur only once are surface nodes
    SurfaceNodeLabels=np.unique(Face[idx])
    return SurfaceNodeLabels

EDIT The following function shows how to get the surface Nodes with abaqus cae. So for this version a license of abaqus cae is required.

defget_Surface_Nodes(Faces):
surface_Faces=[]
#get the surface Facesfor i in xrange(0,len(Faces)):
    Elements=Faces[i].getElements()
    if Elements isnotNone:
        iflen(Elements)==1:
            surface_Faces.append(i)

S_Node_Labels=[]
#get the corresponding node labelsfor i in surface_Faces:
    NodeO=Faces[i].getNodes()
    for Node in NodeO:
        S_Node_Labels.append(Node.label)

S_Node_Labels=np.unique(S_Node_Labels)
return S_Node_Labels

And a example how to use this function:

import part
import assembly
import numpy as np

#Get the Element Faces
Faces=mdb.models['Model_1'].rootAssembly.instances['Instance_1'].elementFaces
SurfaceNodeLabels=get_Surface_Nodes(Faces)

Post a Comment for "Abaqus: A Way To Localize External Nodes?"