Macro Mesh Data

About the development of the FEM module/workbench.

Moderator: bernd

User avatar
HarryvL
Posts: 1042
Joined: Sat Jan 06, 2018 7:38 pm

Macro Mesh Data

Postby HarryvL » Sun Jan 20, 2019 7:59 pm

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
(6.43 KiB) Downloaded 5 times
test1.FCMacro
(260 Bytes) Downloaded 8 times
fandaL
Posts: 333
Joined: Thu Jul 24, 2014 8:29 am

Re: Macro Mesh Data

Postby fandaL » Sun Jan 20, 2019 9:12 pm

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
User avatar
HarryvL
Posts: 1042
Joined: Sat Jan 06, 2018 7:38 pm

Re: Macro Mesh Data

Postby HarryvL » Mon Jan 21, 2019 1:27 am

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: 333
Joined: Thu Jul 24, 2014 8:29 am

Re: Macro Mesh Data

Postby fandaL » Mon Jan 21, 2019 8:11 am

Code: Select all

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

Re: Macro Mesh Data

Postby HarryvL » Mon Jan 21, 2019 8:13 am

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

Re: Macro Mesh Data

Postby bernd » Tue Jan 22, 2019 4:01 pm

What would you like to make a macro for?
User avatar
HarryvL
Posts: 1042
Joined: Sat Jan 06, 2018 7:38 pm

Re: Macro Mesh Data

Postby HarryvL » Tue Jan 22, 2019 7:30 pm

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.
User avatar
HarryvL
Posts: 1042
Joined: Sat Jan 06, 2018 7:38 pm

Re: Macro Mesh Data

Postby HarryvL » Wed Jan 23, 2019 6:29 am

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?
User avatar
HarryvL
Posts: 1042
Joined: Sat Jan 06, 2018 7:38 pm

Re: Macro Mesh Data

Postby HarryvL » Wed Jan 23, 2019 3:51 pm

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?
User avatar
HarryvL
Posts: 1042
Joined: Sat Jan 06, 2018 7:38 pm

Re: Macro Mesh Data

Postby HarryvL » Wed Jan 23, 2019 11:28 pm

and the final version:

Code: Select all

dispfaces=[]

for obj in FreeCAD.ActiveDocument.Objects:
    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])