Jewenile
Jewenile

Reputation: 315

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 an outside area of an object.

Thanks!

Upvotes: 0

Views: 2203

Answers (2)

Matt P
Matt P

Reputation: 2357

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.

Upvotes: 4

max9111
max9111

Reputation: 6492

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 connectivity
def get_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.

def get_Surface_Nodes(Faces):
surface_Faces=[]
#get the surface Faces
for i in xrange(0,len(Faces)):
    Elements=Faces[i].getElements()
    if Elements is not None:
        if len(Elements)==1:
            surface_Faces.append(i)

S_Node_Labels=[]
#get the corresponding node labels
for 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)

Upvotes: 1

Related Questions