## Macro Mesh Data

About the development of the FEM module/workbench.

Moderator: bernd

HarryvL
Posts: 1071
Joined: Sat Jan 06, 2018 7:38 pm
Location: Netherlands

### Macro Mesh Data

I am making a start with writing a FEM macro, but already stumble over the simplest of challenges.

The attached block has 24 2nd order Tetrahedrons, but the following macro:

Code: Select all

``````import numpy as np
doc = App.ActiveDocument
mesh = doc.getObject("FEMMeshGmsh").FemMesh
mesh.NodeCount # returns 63
mesh.VolumeCount # returns 24
for i in range(1,mesh.VolumeCount+1):
print(mesh.getElementNodes(i)) # returns 12 times 3 and 12 times 6
``````
returns 3 nodes for the first 12 elements and 6 for the second 12.

What am I doing wrong here?
TestMacro_1.FCStd
test1.FCMacro
fandaL
Posts: 354
Joined: Thu Jul 24, 2014 8:29 am

### Re: Macro Mesh Data

I guess you iterated through the elements with the lowest numbers, i.e. 12 edge elements and 6 face elements. But the mesh contains 6 edge elements, 24 face elements and 24 volume elements.

Code: Select all

``````for i in range(1,mesh.EdgeCount + mesh.FaceCount + mesh.VolumeCount + 1):
print(mesh.getElementNodes(i)) # returns 12 times 3, 24 times 6, 24 times 10``````
HarryvL
Posts: 1071
Joined: Sat Jan 06, 2018 7:38 pm
Location: Netherlands

### Re: Macro Mesh Data

Thanks @fandaL. Is there a direct way to address the volumes or do you always need to count edges and faces to get to the first one?
fandaL
Posts: 354
Joined: Thu Jul 24, 2014 8:29 am

### Re: Macro Mesh Data

Code: Select all

``````print(mesh.Volumes)  # volume element IDs
for i in mesh.Volumes:
print(mesh.getElementNodes(i))  # node IDs for all volume elements``````
HarryvL
Posts: 1071
Joined: Sat Jan 06, 2018 7:38 pm
Location: Netherlands

### Re: Macro Mesh Data

Thanks !!
bernd
Posts: 8986
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland

### Re: Macro Mesh Data

What would you like to make a macro for?
HarryvL
Posts: 1071
Joined: Sat Jan 06, 2018 7:38 pm
Location: Netherlands

### Re: Macro Mesh Data

bernd wrote:
Tue Jan 22, 2019 4:01 pm
What would you like to make a macro for?
I am doing a FEM test bench for "in-house" testing of some ideas, like the 6-node curved face interface element and improved (over CCX) beam and shell elements. So far its going quite well. I am impressed what can be done wit the API, although I come across some quirky behaviour that I will report on separately.
HarryvL
Posts: 1071
Joined: Sat Jan 06, 2018 7:38 pm
Location: Netherlands

### Re: Macro Mesh Data

I am trying to extract boundary conditions for nodes in the mesh and started as follows:

Code: Select all

``````for obj in FreeCAD.ActiveDocument.Objects:
if obj.isDerivedFrom('Fem::ConstraintDisplacement'):
if obj.References != []:
if "Vertex" in obj.References[0][1][0]:
print("Vertex constraint")
elif "Edge"in obj.References[0][1][0]:
print("Edge constraint")
else:
print("Face constraint")
else:
print("No constraint references")
``````
How do I get from here to the nodes on a vertex, edge or face?
HarryvL
Posts: 1071
Joined: Sat Jan 06, 2018 7:38 pm
Location: Netherlands

### Re: Macro Mesh Data

I think I cracked it:

Code: Select all

``````for obj in FreeCAD.ActiveDocument.Objects:
if obj.isDerivedFrom('Fem::ConstraintDisplacement'):
for part, boundaries in obj.References:
for boundary in boundaries:
ref = part.Shape.getElement(boundary)
if type(ref)==Part.Vertex:
nodes=mesh.getNodesByVertex(ref)
elif type(ref)==Part.Edge:
nodes=mesh.getNodesByEdge(ref)
elif type(ref)==Part.Face:
nodes=mesh.getNodesByFace(ref)
else:
print("No Boundaries Found")
``````
Is there a better way?
HarryvL
Posts: 1071
Joined: Sat Jan 06, 2018 7:38 pm
Location: Netherlands

### Re: Macro Mesh Data

and the final version:

Code: Select all

``````dispfaces=[]

if obj.isDerivedFrom('Fem::ConstraintDisplacement'):
bcnodes= []
bctype=[obj.xFree,obj.yFree,obj.zFree]
bcvalue=[obj.xDisplacement,obj.yDisplacement,obj.zDisplacement]
for part, boundaries in obj.References:
for boundary in boundaries:
ref = part.Shape.getElement(boundary)
if type(ref)==Part.Vertex:
bcnodes.append(mesh.getNodesByVertex(ref))
elif type(ref)==Part.Edge:
bcnodes.append(mesh.getNodesByEdge(ref))
elif type(ref)==Part.Face:
bcnodes.append(mesh.getNodesByFace(ref))
else:
print("No Boundaries Found")

dispfaces.append([[item for sublist in bcnodes for item in sublist],bctype,bcvalue])
``````