Retrieving all Faces for each Node in a femmesh

About the development of the FEM module/workbench.

Moderator: bernd

hdbondt
Posts: 27
Joined: Fri Jul 07, 2017 12:05 pm

Retrieving all Faces for each Node in a femmesh

Post by hdbondt »

Given a Femmesh I'm trying to build a python dictionary which contains a list of faces for each node in the femmesh.
This list is made of faces which have the respective node in FemMesh.getElementNodes(face)

below is my femmesh with 1392 nodes

========================== Dump contents of mesh ==========================

1) Total number of nodes: 1392
2) Total number of edges: 101
3) Total number of faces: 488
4) Total number of polygons: 0
5) Total number of volumes: 651
6) Total number of polyhedrons: 0


but:

Code: Select all

len(np.unique([[id for id in femmesh.getElementNodes(f)] for f in femmesh.Faces]))
returns 978

From which I think that 1392-978=414 nodes do not belong to a face.
But when I highlight these nodes, I see them on the FEMMesh.

which means that 414 nodes in my dictionary have an empty list of faces.
User avatar
bernd
Veteran
Posts: 12851
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland
Contact:

Re: Retrieving all Faces for each Node in a femmesh

Post by bernd »

Would you post your FEMMesh?
hdbondt
Posts: 27
Joined: Fri Jul 07, 2017 12:05 pm

Re: Retrieving all Faces for each Node in a femmesh

Post by hdbondt »

bernd wrote: Wed Aug 09, 2017 4:33 pm Would you post your FEMMesh?
Attachments
selfmadeAFO.FCStd
(216.46 KiB) Downloaded 30 times
User avatar
bernd
Veteran
Posts: 12851
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland
Contact:

Re: Retrieving all Faces for each Node in a femmesh

Post by bernd »

when I load your file and run the following code I get an error:

Code: Select all

import numpy as np
femmesh = App.ActiveDocument.getObject("FEMMeshGMSH001").FemMesh
len(np.unique([[id for id in femmesh.getElementNodes(f)] for f in femmesh.Faces]))

Code: Select all

>>> 
>>> import numpy as np
>>> femmesh = App.ActiveDocument.getObject("FEMMeshGMSH001").FemMesh
>>> len(np.unique([[id for id in femmesh.getElementNodes(f)] for f in femmesh.Faces]))
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "/usr/lib/python2.7/dist-packages/numpy/lib/arraysetops.py", line 166, in unique
    return np.sort(list(set(ar)))
TypeError: unhashable type: 'list'
>>> 
Would you post the code you used to get the 978
User avatar
bernd
Veteran
Posts: 12851
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland
Contact:

Re: Retrieving all Faces for each Node in a femmesh

Post by bernd »

hdbondt wrote: Wed Aug 09, 2017 2:18 pm Given a Femmesh I'm trying to build a python dictionary which contains a list of faces for each node in the femmesh.

Code: Select all

femmesh = App.ActiveDocument.getObject("FEMMeshGMSH001").FemMesh
nodefaces = {}
for k in femmesh.Nodes.keys():
    nodefaces[k] = []

for n in nodefaces:
    for f in femmesh.Faces:
        if n in femmesh.getElementNodes(f):
            nodefaces[n].append(f)
User avatar
bernd
Veteran
Posts: 12851
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland
Contact:

Re: Retrieving all Faces for each Node in a femmesh

Post by bernd »

BTW:

Code: Select all

for i in nodefaces.items():
    if not i:
        print("found node without faces")
returns:

Code: Select all

>>> 
>>> for i in nodefaces.items():
...     if not i:
...         print("found node without faces")
... 
>>> 
means all nodes have at least one face ...
hdbondt
Posts: 27
Joined: Fri Jul 07, 2017 12:05 pm

Re: Retrieving all Faces for each Node in a femmesh

Post by hdbondt »

bernd wrote: Thu Aug 10, 2017 8:12 pm BTW:

Code: Select all

for i in nodefaces.items():
    if not i:
        print("found node without faces")
returns:

Code: Select all

>>> 
>>> for i in nodefaces.items():
...     if not i:
...         print("found node without faces")
... 
>>> 
means all nodes have at least one face ...
Not really, items() returns a tuple of key/value pair from the dictionary.
if you run:

Code: Select all

for n in nodefaces.items():
    print(n)
the output will be:
...
(1377L, [])
(1378L, [])
(1379L, [])
(1380L, [])
(1381L, [])
(1382L, [])
(1383L, [])
(1384L, [])
(1385L, [])
(1386L, [])
(1387L, [])
(1388L, [])
(1389L, [])
(1390L, [])
(1391L, [])
(1392L, [])


As you see the last nodes have an empty list, no faces.
bernd wrote: Thu Aug 10, 2017 7:57 pm when I load your file and run the following code I get an error:

...

Would you post the code you used to get the 978
When I run the code it works in my version of FreeCAD.
I don't understand why there is different behaviour, but I rewrote the code to have a flat list instead of a nested one.
Please try again.

Code: Select all

import numpy as np
femmesh = App.ActiveDocument.getObject("FEMMeshGMSH001").FemMesh
len(np.unique([id for f in femmesh.Faces for id in femmesh.getElementNodes(f) ]))
This should give the same output (978)

I think I found something which could explain the output (978)

Code: Select all

shape = App.ActiveDocument.Fusion001001.Shape
len(np.unique(( [ node_ids for f in shape.Faces for node_ids in (femmesh.getNodesByFace(f))])))
also returns 978

on an unrelated note:
My part is called Fusion001001, which, for code clarity, is not a good name.
But when I rename the part in the project (using F2 or right click rename) the label changes but the name used to acces the shape through code stays the same. Is this intended behavior?
When I change the label, it changes in the property view, but there's no code generated in the python console, maybe that's the problem?
User avatar
bernd
Veteran
Posts: 12851
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland
Contact:

Re: Retrieving all Faces for each Node in a femmesh

Post by bernd »

hdbondt wrote: Fri Aug 11, 2017 8:12 am on an unrelated note:
My part is called Fusion001001, which, for code clarity, is not a good name.
But when I rename the part in the project (using F2 or right click rename) the label changes but the name used to acces the shape through code stays the same. Is this intended behavior?
When I change the label, it changes in the property view, but there's no code generated in the python console, maybe that's the problem?
Yes it is intended. The name in FreeCAD is unique and can not be changed AFAIK. Rename (F2) changes the label of an object. The label and the name are two different properties of an object.
User avatar
bernd
Veteran
Posts: 12851
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland
Contact:

Re: Retrieving all Faces for each Node in a femmesh

Post by bernd »

@hdbondt: You are right ... on your file it gives lots of nodes without faces ...

Code: Select all

femmesh = App.ActiveDocument.getObject("FEMMeshGMSH001").FemMesh
nodefaces = {}
for k in femmesh.Nodes.keys():
    nodefaces[k] = []

for n in nodefaces:
    for f in femmesh.Faces:
        if n in femmesh.getElementNodes(f):
            nodefaces[n].append(f)

count = 0
for n in nodefaces.items():
    if not n[1]:
        # print(n)
        count += 1

print(count)

Code: Select all

...
414
Mhh strange ...
User avatar
bernd
Veteran
Posts: 12851
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland
Contact:

Re: Retrieving all Faces for each Node in a femmesh

Post by bernd »

hdbondt wrote: Fri Aug 11, 2017 8:12 am

Code: Select all

import numpy as np
femmesh = App.ActiveDocument.getObject("FEMMeshGMSH001").FemMesh
len(np.unique([id for f in femmesh.Faces for id in femmesh.getElementNodes(f) ]))
This should give the same output (978)
I get 978 too.

another version would be ...

Code: Select all

ids = []
for f in femmesh.Faces:
    for id in femmesh.getElementNodes(f):
        ids.append(id)

len(set(ids))
result will be 978 too
Post Reply