FEM: add to ccxInpWriter: CLOAD for shell meshes and solid meshes without face data
This commit is contained in:
parent
b553d9895d
commit
5a2940fb82
|
@ -168,6 +168,9 @@ class inp_writer:
|
|||
f.write('\n***********************************************************\n')
|
||||
f.write('** Node loads\n')
|
||||
f.write('** written by {} function\n'.format(sys._getframe().f_code.co_name))
|
||||
if is_shell_mesh(self.mesh_object.FemMesh) or (is_solid_mesh(self.mesh_object.FemMesh) and has_no_face_data(self.mesh_object.FemMesh)):
|
||||
if not hasattr(self,'fem_element_table'):
|
||||
self.fem_element_table = getFemElementTable(self.mesh_object.FemMesh)
|
||||
for fobj in self.force_objects:
|
||||
frc_obj = fobj['Object']
|
||||
if 'NodeLoad' in fobj:
|
||||
|
@ -205,10 +208,30 @@ class inp_writer:
|
|||
f.write('*CLOAD\n')
|
||||
f.write('** node loads on element face: ' + o.Name + '.' + elem + '\n')
|
||||
|
||||
volume_faces = self.mesh_object.FemMesh.getVolumesByFace(ref_face)
|
||||
face_table = {} # { meshfaceID : ( nodeID, ... , nodeID ) }
|
||||
for mv, mf in volume_faces:
|
||||
face_table[mf] = self.mesh_object.FemMesh.getElementNodes(mf)
|
||||
if is_solid_mesh(self.mesh_object.FemMesh):
|
||||
if has_no_face_data(self.mesh_object.FemMesh):
|
||||
ref_face_volume_elements = self.mesh_object.FemMesh.getccxVolumesByFace(ref_face) # list of tupels
|
||||
ref_face_nodes = self.mesh_object.FemMesh.getNodesByFace(ref_face)
|
||||
# print ref_face_nodes
|
||||
# print ref_face_volume_elements
|
||||
for ve in ref_face_volume_elements:
|
||||
veID = ve[0]
|
||||
ve_ref_face_nodes = []
|
||||
for nodeID in self.fem_element_table[veID]:
|
||||
if nodeID in ref_face_nodes:
|
||||
ve_ref_face_nodes.append(nodeID)
|
||||
face_table[veID] = ve_ref_face_nodes # { volumeID : ( facenodeID, ... , facenodeID ) }
|
||||
# print veID, ' --> ', face_table[veID]
|
||||
else:
|
||||
volume_faces = self.mesh_object.FemMesh.getVolumesByFace(ref_face) # (mv, mf)
|
||||
for mv, mf in volume_faces:
|
||||
face_table[mf] = self.mesh_object.FemMesh.getElementNodes(mf)
|
||||
elif is_shell_mesh(self.mesh_object.FemMesh):
|
||||
ref_face_nodes = self.mesh_object.FemMesh.getNodesByFace(ref_face)
|
||||
ref_face_elements = getFemElementsByNodes(self.fem_element_table, ref_face_nodes)
|
||||
for mf in ref_face_elements:
|
||||
face_table[mf] = self.fem_element_table[mf]
|
||||
|
||||
# calulate the appropriate node_areas for every node of every mesh face (mf)
|
||||
# G. Lakshmi Narasaiah, Finite Element Analysis, p206ff
|
||||
|
@ -238,7 +261,10 @@ class inp_writer:
|
|||
node_area_table.append((face_table[mf][1], corner_node_area))
|
||||
node_area_table.append((face_table[mf][2], corner_node_area))
|
||||
|
||||
if len(face_table[mf]) == 6: # 6 node mesh face triangle
|
||||
elif len(face_table[mf]) == 4: # 4 node mesh face quad
|
||||
FreeCAD.Console.PrintError('Face load on 4 node quad faces are not supported\n')
|
||||
|
||||
elif len(face_table[mf]) == 6: # 6 node mesh face triangle
|
||||
# corner_node_area = 0
|
||||
# middle_node_area = mesh_face_area / 3.0
|
||||
# P3
|
||||
|
@ -271,6 +297,9 @@ class inp_writer:
|
|||
node_area_table.append((face_table[mf][4], middle_node_area))
|
||||
node_area_table.append((face_table[mf][5], middle_node_area))
|
||||
|
||||
elif len(face_table[mf]) == 8: # 8 node mesh face quad
|
||||
FreeCAD.Console.PrintError('Face load on 8 node quad faces are not supported\n')
|
||||
|
||||
# node_sumarea_table
|
||||
for n, A in node_area_table:
|
||||
# print n, ' --> ', A
|
||||
|
@ -371,9 +400,65 @@ class inp_writer:
|
|||
f.write('**\n')
|
||||
|
||||
|
||||
|
||||
# Helpers
|
||||
def getTriangleArea(P1, P2, P3):
|
||||
vec1 = P2 - P1
|
||||
vec2 = P3 - P1
|
||||
vec3 = vec1.cross(vec2)
|
||||
return 0.5 * vec3.Length
|
||||
return 0.5 * vec3.Length
|
||||
|
||||
|
||||
def getFemElementTable(fem_mesh):
|
||||
""" getFemElementTable(fem_mesh): { elementid : [ nodeid, nodeid, ... , nodeid ] }"""
|
||||
fem_element_table = {}
|
||||
if is_solid_mesh(fem_mesh):
|
||||
for i in fem_mesh.Volumes:
|
||||
fem_element_table[i] = fem_mesh.getElementNodes(i)
|
||||
elif is_shell_mesh(fem_mesh):
|
||||
for i in fem_mesh.Faces:
|
||||
fem_element_table[i] = fem_mesh.getElementNodes(i)
|
||||
elif is_beam_mesh(fem_mesh):
|
||||
for i in fem_mesh.Edges:
|
||||
fem_element_table[i] = fem_mesh.getElementNodes(i)
|
||||
else:
|
||||
print 'Neither solid nor shell nor beam mesh!'
|
||||
# print len(fem_element_table), ' elements in fem_element_table'
|
||||
return fem_element_table
|
||||
|
||||
|
||||
def getFemElementsByNodes(fem_element_table, node_list):
|
||||
'''if all nodes of an fem_element are in node_list,
|
||||
the fem_element is added to the list which is returned
|
||||
e: elementlist
|
||||
nodes: nodelist '''
|
||||
e = [] # elementlist
|
||||
for elementID in sorted(fem_element_table):
|
||||
nodecount = 0
|
||||
for nodeID in fem_element_table[elementID]:
|
||||
if nodeID in node_list:
|
||||
nodecount = nodecount + 1
|
||||
if nodecount == len(fem_element_table[elementID]): # all nodes of the element are in the node_list!
|
||||
e.append(elementID)
|
||||
return e
|
||||
|
||||
|
||||
def is_solid_mesh(fem_mesh):
|
||||
if fem_mesh.VolumeCount > 0: # solid mesh
|
||||
print 'solid mesh'
|
||||
return True
|
||||
|
||||
def has_no_face_data(fem_mesh):
|
||||
if fem_mesh.FaceCount == 0 : # mesh has no face data, could be a beam mesh or a solid mesh without face data
|
||||
print 'mesh without face data'
|
||||
return True
|
||||
|
||||
def is_shell_mesh(fem_mesh):
|
||||
if fem_mesh.VolumeCount == 0 and fem_mesh.FaceCount > 0 : # shell mesh
|
||||
print 'shell mesh'
|
||||
return True
|
||||
|
||||
def is_beam_mesh(fem_mesh):
|
||||
if fem_mesh.VolumeCount == 0 and fem_mesh.FaceCount == 0 and fem_mesh.EdgeCount > 0 : # beam mesh
|
||||
print 'beam mesh'
|
||||
return True
|
||||
|
|
|
@ -479,6 +479,47 @@ FemConstraintFixed,3
|
|||
** FemConstraintForce
|
||||
*CLOAD
|
||||
** node loads on element face: Box.Face3
|
||||
1,1,-0.0000000000000E+00
|
||||
2,1,-0.0000000000000E+00
|
||||
5,1,-0.0000000000000E+00
|
||||
6,1,-0.0000000000000E+00
|
||||
9,1,-0.0000000000000E+00
|
||||
10,1,-2.0833333333333E-01
|
||||
11,1,-2.0833333333333E-01
|
||||
21,1,-0.0000000000000E+00
|
||||
22,1,-2.0833333333333E-01
|
||||
23,1,-2.0833333333333E-01
|
||||
33,1,-0.0000000000000E+00
|
||||
34,1,-2.0833333333333E-01
|
||||
35,1,-2.0833333333333E-01
|
||||
36,1,-0.0000000000000E+00
|
||||
37,1,-2.0833333333333E-01
|
||||
38,1,-2.0833333333333E-01
|
||||
95,1,-0.0000000000000E+00
|
||||
96,1,-0.0000000000000E+00
|
||||
97,1,-0.0000000000000E+00
|
||||
98,1,-0.0000000000000E+00
|
||||
99,1,-0.0000000000000E+00
|
||||
100,1,-4.1666666666667E-01
|
||||
101,1,-4.1666666666667E-01
|
||||
102,1,-4.1666666666667E-01
|
||||
103,1,-4.1666666666667E-01
|
||||
104,1,-4.1666666666667E-01
|
||||
105,1,-4.1666666666667E-01
|
||||
106,1,-4.1666666666667E-01
|
||||
107,1,-4.1666666666667E-01
|
||||
108,1,-4.1666666666667E-01
|
||||
109,1,-4.1666666666667E-01
|
||||
110,1,-4.1666666666667E-01
|
||||
111,1,-4.1666666666667E-01
|
||||
112,1,-4.1666666666667E-01
|
||||
113,1,-4.1666666666667E-01
|
||||
114,1,-4.1666666666667E-01
|
||||
115,1,-4.1666666666667E-01
|
||||
116,1,-4.1666666666667E-01
|
||||
117,1,-4.1666666666667E-01
|
||||
118,1,-4.1666666666667E-01
|
||||
119,1,-4.1666666666667E-01
|
||||
|
||||
|
||||
|
||||
|
@ -524,8 +565,8 @@ S
|
|||
***********************************************************
|
||||
** CalculiX Input file
|
||||
** written by write_footer function
|
||||
** written by --> FreeCAD 0.16.5287 (Git)
|
||||
** written on --> Thu Jul 30 11:22:52 2015
|
||||
** written by --> FreeCAD 0.16.5485 (Git)
|
||||
** written on --> Mon Sep 14 06:41:34 2015
|
||||
** file name -->
|
||||
** analysis name --> MechanicalAnalysis
|
||||
**
|
||||
|
|
Loading…
Reference in New Issue
Block a user