In FreeCAD ci sono diverse possibilità per creare una Mesh FEM:
Sono supportati gli oggetti creati in Part Design e Parte, così come le copie semplici di tali corpi. Sono disponibili due mesher: Netgen e GMSH. Netgen è incluso in FreeCAD. Fare riferimento a Installare FEM. Per generare una Mesh FEM con GMSH l'utente psicofil ha fornito la Macro GMSHMesh.
FreeCAD supporta vari tipi di elementi. Questo blog esterno vi spiega le differenze tra i tipi di elementi e come utilizzarli: https://www.comsol.com/blogs/meshing-your-geometry-various-element-types/
Maggiori informazioni sui tipi di elementi FEM e la loro struttura dei dati all'interno di FreeCAD si trovano nella pagina Tipi di elementi FEM.
import FreeCAD, Fem # create a empty mesh m = Fem.FemMesh() #create the nodes m.addNode(0,1,0) m.addNode(0,0,1) m.addNode(1,0,0) m.addNode(0,0,0) m.addNode(0,0.5,0.5) m.addNode(0.5,0.03,.5) m.addNode(0.5,0.5,0.03) m.addNode(0,0.5,0) m.addNode(0.03,0,0.5) m.addNode(0.5,0,0) # add the volume with the created nodes m.addVolume([1,2,3,4,5,6,7,8,9,10]) Fem.show(m)
Se si desidera avere un elemento predefinito e la numerazione del nodo:
m.addNode(0.0,1.0,0.0,1) m.addVolume([1,2,3,4,5,6,7,8,9,10],1)
Evidenziare alcuni nodi nella vista:
import FreeCAD, Fem m = Fem.FemMesh() m.addNode(0,1,0) m.addNode(0,0,1) m.addNode(1,0,0) m.addNode(0,0,0) m.addNode(0,0.5,0.5) m.addNode(0.5,0.03,.5) m.addNode(0.5,0.5,0.03) m.addNode(0,0.5,0) m.addNode(0.03,0,0.5) m.addNode(0.5,0,0) m.addVolume([1,2,3,4,5,6,7,8,9,10]) Fem.show(m) Gui.ActiveDocument.ActiveObject.HighlightedNodes = [1,2,3]
Post-elaborazione dei colori e della posizione:
# set the volume 1 to red Gui.ActiveDocument.ActiveObject.ElementColor= {1:(1,0,0)} # set the node 1 and 2 to a certain Color and interpolate the survace Gui.ActiveDocument.ActiveObject.NodeColor= {1:(1,0,0),2:(1,0,0)} # set the node 1 and 2 to a certain displacement Gui.ActiveDocument.ActiveObject.NodeDisplacement= {1:FreeCAD.Vector(1,0,0),2:FreeCAD.Vector(1,0,0)} # double the factor of the displacement shown Gui.ActiveDocument.ActiveObject.animate(2.0)
import Fem ################################################# # Beams # 2 node line --> seg2 ########################## seg2 = Fem.FemMesh() seg2.addNode( 0, 0, 0, 1) seg2.addNode(10, 0, 0, 2) seg2.addEdge(1, 2) seg2 obj = App.ActiveDocument.addObject("Fem::FemMeshObject","seg2") obj.FemMesh = seg2 obj.Placement.Base = (0,110,0) obj.ViewObject.DisplayMode = "Faces, Wireframe & Nodes" # 3 node line --> seg3 ########################## seg3 = Fem.FemMesh() seg3.addNode( 0, 0, 0, 1) seg3.addNode(10, 0, 0, 2) seg3.addNode( 5, 0, 0, 3) seg3.addEdge([1, 2, 3]) seg3 obj = App.ActiveDocument.addObject("Fem::FemMeshObject","seg3") obj.FemMesh = seg3 obj.Placement.Base = (30,110,0) obj.ViewObject.DisplayMode = "Faces, Wireframe & Nodes" ################################################# # Shells # 3 node triangle --> tria3 ##################### tria3 = Fem.FemMesh() tria3.addNode( 0, 0, 0, 1) tria3.addNode( 6, 12, 0, 2) tria3.addNode(12, 0, 0, 3) tria3.addFace([1, 2, 3]) tria3 obj = App.ActiveDocument.addObject("Fem::FemMeshObject","tria3") obj.FemMesh = tria3 obj.Placement.Base = (0,80,0) obj.ViewObject.DisplayMode = "Faces, Wireframe & Nodes" obj.ViewObject.BackfaceCulling = False # add Face with element number elemtria3 = Fem.FemMesh() nds = tria3.Nodes for n in nds: elemtria3.addNode(nds[n].x, nds[n].y, nds[n].z, n) elemtria3.addFace([1, 2, 3], 88) obj = App.ActiveDocument.addObject("Fem::FemMeshObject","elemtria3") obj.FemMesh = elemtria3 obj.Placement.Base = (200,80,0) obj.ViewObject.DisplayMode = "Faces, Wireframe & Nodes" obj.ViewObject.BackfaceCulling = False elemtria3.Faces # 6 node triangle --> tria 6 #################### tria6 = Fem.FemMesh() tria6.addNode( 0, 0, 0, 1) tria6.addNode( 6, 12, 0, 2) tria6.addNode(12, 0, 0, 3) tria6.addNode( 3, 6, 0, 4) tria6.addNode( 9, 6, 0, 5) tria6.addNode( 6, 0, 0, 6) tria6.addFace([1, 2, 3, 4, 5, 6]) tria6 obj = App.ActiveDocument.addObject("Fem::FemMeshObject","tria6") obj.FemMesh = tria6 obj.Placement.Base = (30,80,0) obj.ViewObject.DisplayMode = "Faces, Wireframe & Nodes" obj.ViewObject.BackfaceCulling = False # add Face with element number elemtria6 = Fem.FemMesh() nds = tria6.Nodes for n in nds: elemtria6.addNode(nds[n].x, nds[n].y, nds[n].z, n) elemtria6.addFace([1, 2, 3, 4, 5, 6], 88) obj = App.ActiveDocument.addObject("Fem::FemMeshObject","elemtria6") obj.FemMesh = elemtria6 obj.Placement.Base = (230,80,0) obj.ViewObject.DisplayMode = "Faces, Wireframe & Nodes" obj.ViewObject.BackfaceCulling = False elemtria6.Faces # 4 node quad --> quad4 ######################### quad4 = Fem.FemMesh() quad4.addNode( 0, 10, 0, 1) quad4.addNode(10, 10, 0, 2) quad4.addNode(10, 0, 0, 3) quad4.addNode( 0, 0, 0, 4) quad4.addFace([1, 2, 3, 4]) quad4 obj = App.ActiveDocument.addObject("Fem::FemMeshObject","quad4") obj.FemMesh = quad4 obj.Placement.Base = (60,80,0) obj.ViewObject.DisplayMode = "Faces, Wireframe & Nodes" obj.ViewObject.BackfaceCulling = False # add Face with element number elemquad4 = Fem.FemMesh() nds = quad4.Nodes for n in nds: elemquad4.addNode(nds[n].x, nds[n].y, nds[n].z, n) elemquad4.addFace([1, 2, 3, 4], 88) obj = App.ActiveDocument.addObject("Fem::FemMeshObject","elemquad4") obj.FemMesh = elemquad4 obj.Placement.Base = (260,80,0) obj.ViewObject.DisplayMode = "Faces, Wireframe & Nodes" obj.ViewObject.BackfaceCulling = False elemquad4.Faces # 8 node quad --> quad8 ######################### quad8 = Fem.FemMesh() quad8.addNode( 0, 10, 0, 1) quad8.addNode(10, 10, 0, 2) quad8.addNode(10, 0, 0, 3) quad8.addNode( 0, 0, 0, 4) quad8.addNode( 5, 10, 0, 5) quad8.addNode(10, 5, 0, 6) quad8.addNode( 5, 0, 0, 7) quad8.addNode( 0, 5, 0, 8) quad8.addFace([1, 2, 3, 4, 5, 6, 7, 8]) quad8 obj = App.ActiveDocument.addObject("Fem::FemMeshObject","quad8") obj.FemMesh = quad8 obj.ViewObject.BackfaceCulling = False obj.Placement.Base = (90,80,0) obj.ViewObject.DisplayMode = "Faces, Wireframe & Nodes" # add Face with element number elemquad8 = Fem.FemMesh() nds = quad8.Nodes for n in nds: elemquad8.addNode(nds[n].x, nds[n].y, nds[n].z, n) elemquad8.addFace([1, 2, 3, 4, 5, 6, 7, 8], 88) obj = App.ActiveDocument.addObject("Fem::FemMeshObject","elemquad8") obj.FemMesh = elemquad8 obj.Placement.Base = (290,80,0) obj.ViewObject.DisplayMode = "Faces, Wireframe & Nodes" obj.ViewObject.BackfaceCulling = False elemquad8.Faces ################################################# # Volumes # 4 node tetrahedron --> tetra4 ################# tetra4 = Fem.FemMesh() tetra4.addNode( 6, 12, 18, 1) tetra4.addNode( 0, 0, 18, 2) tetra4.addNode(12, 0, 18, 3) tetra4.addNode( 6, 6, 0, 4) tetra4.addVolume([1, 2, 3, 4]) tetra4 obj = App.ActiveDocument.addObject("Fem::FemMeshObject","tetra4") obj.FemMesh = tetra4 obj.Placement.Base = (0,50,0) obj.ViewObject.DisplayMode = "Faces, Wireframe & Nodes" # add Volume with element number elemtetra4 = Fem.FemMesh() nds = tetra4.Nodes for n in nds: elemtetra4.addNode(nds[n].x, nds[n].y, nds[n].z, n) elemtetra4.addVolume([1, 2, 3, 4], 88) obj = App.ActiveDocument.addObject("Fem::FemMeshObject","elemtetra4") obj.FemMesh = elemtetra4 obj.Placement.Base = (200,50,0) obj.ViewObject.DisplayMode = "Faces, Wireframe & Nodes" elemtetra4.Volumes # 10 node tetrahedron --> tetra10 ############### tetra10 = Fem.FemMesh() tetra10.addNode( 6, 12, 18, 1) tetra10.addNode( 0, 0, 18, 2) tetra10.addNode(12, 0, 18, 3) tetra10.addNode( 6, 6, 0, 4) tetra10.addNode( 3, 6, 18, 5) tetra10.addNode( 6, 0, 18, 6) tetra10.addNode( 9, 6, 18, 7) tetra10.addNode( 6, 9, 9, 8) tetra10.addNode( 3, 3, 9, 9) tetra10.addNode( 9, 3, 9,10) tetra10.addVolume([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) tetra10 obj = App.ActiveDocument.addObject("Fem::FemMeshObject","tetra10") obj.FemMesh = tetra10 obj.Placement.Base = (30,50,0) obj.ViewObject.DisplayMode = "Faces, Wireframe & Nodes" # add Volume with element number elemtetra10 = Fem.FemMesh() nds = tetra10.Nodes for n in nds: elemtetra10.addNode(nds[n].x, nds[n].y, nds[n].z, n) elemtetra10.addVolume([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 88) obj = App.ActiveDocument.addObject("Fem::FemMeshObject","elemtetra10") obj.FemMesh = elemtetra10 obj.Placement.Base = (230,50,0) obj.ViewObject.DisplayMode = "Faces, Wireframe & Nodes" elemtetra10.Volumes # 8 node Hexahedron --> hexa8 ################### hexa8 = Fem.FemMesh() hexa8.addNode( 0, 10, 10, 1) hexa8.addNode( 0, 0, 10, 2) hexa8.addNode(10, 0, 10, 3) hexa8.addNode(10, 10, 10, 4) hexa8.addNode( 0, 10, 0, 5) hexa8.addNode( 0, 0, 0, 6) hexa8.addNode(10, 0, 0, 7) hexa8.addNode(10, 10, 0, 8) hexa8.addVolume([1, 2, 3, 4, 5, 6, 7, 8]) hexa8 obj = App.ActiveDocument.addObject("Fem::FemMeshObject","hexa8") obj.FemMesh = hexa8 obj.Placement.Base = (60,50,0) obj.ViewObject.DisplayMode = "Faces, Wireframe & Nodes" # add Volume with element number elemhexa8 = Fem.FemMesh() nds = hexa8.Nodes for n in nds: elemhexa8.addNode(nds[n].x, nds[n].y, nds[n].z, n) elemhexa8.addVolume([1, 2, 3, 4, 5, 6, 7, 8], 88) obj = App.ActiveDocument.addObject("Fem::FemMeshObject","elemhexa8") obj.FemMesh = elemhexa8 obj.Placement.Base = (260,50,0) obj.ViewObject.DisplayMode = "Faces, Wireframe & Nodes" elemhexa8.Volumes # 20 node Hexahedron --> hexa20 ################# hexa20 = Fem.FemMesh() hexa20.addNode( 0, 10, 10, 1) hexa20.addNode( 0, 0, 10, 2) hexa20.addNode(10, 0, 10, 3) hexa20.addNode(10, 10, 10, 4) hexa20.addNode( 0, 10, 0, 5) hexa20.addNode( 0, 0, 0, 6) hexa20.addNode(10, 0, 0, 7) hexa20.addNode(10, 10, 0, 8) hexa20.addNode( 0, 5, 10, 9) hexa20.addNode( 5, 0, 10, 10) hexa20.addNode(10, 5, 10, 11) hexa20.addNode( 5, 10, 10, 12) hexa20.addNode( 0, 5, 0, 13) hexa20.addNode( 5, 0, 0, 14) hexa20.addNode(10, 5, 0, 15) hexa20.addNode( 5, 10, 0, 16) hexa20.addNode( 0, 10, 5, 17) hexa20.addNode( 0, 0, 5, 18) hexa20.addNode(10, 0, 5, 19) hexa20.addNode(10, 10, 5, 20) hexa20.addVolume([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]) hexa20 obj = App.ActiveDocument.addObject("Fem::FemMeshObject","hexa20") obj.FemMesh = hexa20 obj.Placement.Base = (90,50,0) obj.ViewObject.DisplayMode = "Faces, Wireframe & Nodes" # add Volume with element number elemhexa20 = Fem.FemMesh() nds = hexa20.Nodes for n in nds: elemhexa20.addNode(nds[n].x, nds[n].y, nds[n].z, n) elemhexa20.addVolume([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], 88) obj = App.ActiveDocument.addObject("Fem::FemMeshObject","elemhexa20") obj.FemMesh = elemhexa20 obj.Placement.Base = (290,50,0) obj.ViewObject.DisplayMode = "Faces, Wireframe & Nodes" elemhexa20.Volumes # 6 node pentahedron --> penta6 ################# penta6 = Fem.FemMesh() penta6.addNode(10,10,10, 1) penta6.addNode( 0, 0,10, 2) penta6.addNode(20, 0,10, 3) penta6.addNode(10,10, 0, 4) penta6.addNode( 0, 0, 0, 5) penta6.addNode(20, 0, 0, 6) penta6.addVolume([1, 2, 3, 4, 5, 6]) penta6 obj = App.ActiveDocument.addObject("Fem::FemMeshObject","penta6") obj.FemMesh = penta6 obj.Placement.Base = (0,0,0) obj.ViewObject.DisplayMode = "Faces, Wireframe & Nodes" # add Volume with element number elempenta6 = Fem.FemMesh() nds = penta6.Nodes for n in nds: elempenta6.addNode(nds[n].x, nds[n].y, nds[n].z, n) elempenta6.addVolume([ 1, 2, 3, 4, 5, 6], 88) obj = App.ActiveDocument.addObject("Fem::FemMeshObject","elempenta6") obj.FemMesh = elempenta6 obj.Placement.Base = (200,0,0) obj.ViewObject.DisplayMode = "Faces, Wireframe & Nodes" elempenta6.Volumes # 15 node pentahedron --> penta15 ############### penta15 = Fem.FemMesh() penta15.addNode(10,10,10, 1) penta15.addNode( 0, 0,10, 2) penta15.addNode(20, 0,10, 3) penta15.addNode(10,10, 0, 4) penta15.addNode( 0, 0, 0, 5) penta15.addNode(20, 0, 0, 6) penta15.addNode( 5, 5,10, 7) penta15.addNode(10, 0,10, 8) penta15.addNode(15, 5,10, 9) penta15.addNode( 5, 5, 0,10) penta15.addNode(10, 0, 0,11) penta15.addNode(15, 5, 0,12) penta15.addNode(10,10, 5,13) penta15.addNode( 0, 0, 5,14) penta15.addNode(20, 0, 5,15) penta15.addVolume([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]) penta15 obj = App.ActiveDocument.addObject("Fem::FemMeshObject","penta15") obj.FemMesh = penta15 obj.Placement.Base = (40,0,0) obj.ViewObject.DisplayMode = "Faces, Wireframe & Nodes" # add Volume with element number elempenta15 = Fem.FemMesh() nds = penta15.Nodes for n in nds: elempenta15.addNode(nds[n].x, nds[n].y, nds[n].z, n) elempenta15.addVolume([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], 88) obj = App.ActiveDocument.addObject("Fem::FemMeshObject","elempenta15") obj.FemMesh = elempenta15 obj.Placement.Base = (240,0,0) obj.ViewObject.DisplayMode = "Faces, Wireframe & Nodes" elempenta15.Volumes # 5 node pyramid --> pyra5 ###################### pyra5 = Fem.FemMesh() pyra5.addNode( 0,20, 0, 1) pyra5.addNode(20,20, 0, 2) pyra5.addNode(20, 0, 0, 3) pyra5.addNode( 0, 0, 0, 4) pyra5.addNode(10,10,10, 5) pyra5.addVolume([1, 2, 3, 4, 5]) pyra5 obj = App.ActiveDocument.addObject("Fem::FemMeshObject","pyra5") obj.FemMesh = pyra5 obj.Placement.Base = (80,0,0) obj.ViewObject.DisplayMode = "Faces, Wireframe & Nodes" # add Volume with element number elempyra5 = Fem.FemMesh() nds = pyra5.Nodes for n in nds: elempyra5.addNode(nds[n].x, nds[n].y, nds[n].z, n) elempyra5.addVolume([1, 2, 3, 4, 5], 88) obj = App.ActiveDocument.addObject("Fem::FemMeshObject","elempyra5") obj.FemMesh = elempyra5 obj.Placement.Base = (280,0,0) obj.ViewObject.DisplayMode = "Faces, Wireframe & Nodes" elempyra5.Volumes # 13 node pyramid --> pyra13 #################### pyra13 = Fem.FemMesh() pyra13.addNode( 0,20, 0, 1) pyra13.addNode(20,20, 0, 2) pyra13.addNode(20, 0, 0, 3) pyra13.addNode( 0, 0, 0, 4) pyra13.addNode(10,10,10, 5) pyra13.addNode(10,20, 0, 6) pyra13.addNode(20,10, 0, 7) pyra13.addNode(10, 0, 0, 8) pyra13.addNode( 0,10, 0, 9) pyra13.addNode( 5,15, 5,10) pyra13.addNode(15,15, 5,11) pyra13.addNode(15, 5, 5,12) pyra5 = Fem.FemMesh() pyra13.addNode( 5, 5, 5,13) pyra13.addVolume([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]) pyra13 obj = App.ActiveDocument.addObject("Fem::FemMeshObject","pyra13") obj.FemMesh = pyra13 obj.Placement.Base = (120,0,0) obj.ViewObject.DisplayMode = "Faces, Wireframe & Nodes" # add Volume with element number elempyra13 = Fem.FemMesh() nds = pyra13.Nodes for n in nds: elempyra13.addNode(nds[n].x, nds[n].y, nds[n].z, n) elempyra13.addVolume([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], 88) obj = App.ActiveDocument.addObject("Fem::FemMeshObject","elempyra13") obj.FemMesh = elempyra13 obj.Placement.Base = (320,0,0) obj.ViewObject.DisplayMode = "Faces, Wireframe & Nodes" elempyra13.Volumes