FEM: constraint contact, move retrieving the face ids in writer base class
This commit is contained in:
@@ -1640,6 +1640,100 @@ def get_pressure_obj_faces_depreciated(
|
||||
return pressure_faces
|
||||
|
||||
|
||||
# ***** contact faces ****************************************************************************
|
||||
def get_contact_obj_faces(
|
||||
femmesh,
|
||||
femelement_table,
|
||||
femnodes_ele_table,
|
||||
femobj
|
||||
):
|
||||
# see comment on get_pressure_obj_faces_depreciated in the regard of getccxVolumesByFace()
|
||||
|
||||
# sets are needed for each of the references separated
|
||||
# BTW constraint tie works the same way AFAIK
|
||||
# TODO it might be useful to introduce a Reference_master and Reference_slave attribute
|
||||
|
||||
# groups makes no sense, since group would be needed for each contact face (master and slave)
|
||||
|
||||
# slave is DEP1 and master is IND1 in input file
|
||||
# first element face or ref_shape is slave, second is master
|
||||
|
||||
# TODO above pre check in ccxtools
|
||||
# TODO ref_shape_type should be Face
|
||||
|
||||
slave_faces, master_faces = [], []
|
||||
|
||||
contact_obj = femobj["Object"]
|
||||
if len(contact_obj.References) == 1 and len(contact_obj.References[0][1]) == 2:
|
||||
# [(<Part::PartFeature>, ('Face7', 'Face3'))]
|
||||
# refs are merged because they are on the same doc obj
|
||||
# but only one element face for each contact face (Gui, TaskPael contact)
|
||||
ref_obj = contact_obj.References[0][0]
|
||||
ref_ele = contact_obj.References[0][1]
|
||||
slave_ref = (ref_obj, (ref_ele[0],)) # the comma is needed!
|
||||
master_ref = (ref_obj, (ref_ele[1],)) # the comma is needed!
|
||||
elif (
|
||||
len(contact_obj.References) == 2
|
||||
and len(contact_obj.References[0][1]) == 1
|
||||
and len(contact_obj.References[1][1]) == 1
|
||||
):
|
||||
# [(<Part::PartFeature>, ('Face3',)), (<Part::PartFeature>, ('Face7',))]
|
||||
# refs are on different objects
|
||||
# but only one element face for each contact face (Gui, TaskPael contact)
|
||||
slave_ref = contact_obj.References[0]
|
||||
master_ref = contact_obj.References[1]
|
||||
else:
|
||||
FreeCAD.Console.PrintError(
|
||||
"Not valid (example: only master or slave defined) "
|
||||
"or not supported reference shape elements, contact face combination "
|
||||
"(example: multiple element faces per master or slave\n"
|
||||
)
|
||||
|
||||
FreeCAD.Console.PrintLog("Slave: {}, {}\n".format(slave_ref[0].Name, slave_ref))
|
||||
FreeCAD.Console.PrintLog("Master: {}, {}\n".format(master_ref[0].Name, master_ref))
|
||||
|
||||
if is_solid_femmesh(femmesh):
|
||||
# get the nodes, sorted and duplicates removed
|
||||
slaveface_nds = sorted(list(set(get_femnodes_by_refshape(femmesh, slave_ref))))
|
||||
masterface_nds = sorted(list(set(get_femnodes_by_refshape(femmesh, master_ref))))
|
||||
# FreeCAD.Console.PrintLog("slaveface_nds: {}\n".format(slaveface_nds))
|
||||
# FreeCAD.Console.PrintLog("masterface_nds: {}\n".format(slaveface_nds))
|
||||
|
||||
# fill the bit_pattern_dict and search for the faces
|
||||
slave_bit_pattern_dict = get_bit_pattern_dict(
|
||||
femelement_table,
|
||||
femnodes_ele_table,
|
||||
slaveface_nds
|
||||
)
|
||||
master_bit_pattern_dict = get_bit_pattern_dict(
|
||||
femelement_table,
|
||||
femnodes_ele_table,
|
||||
masterface_nds
|
||||
)
|
||||
|
||||
# get the faces ids
|
||||
slave_faces = get_ccxelement_faces_from_binary_search(slave_bit_pattern_dict)
|
||||
master_faces = get_ccxelement_faces_from_binary_search(master_bit_pattern_dict)
|
||||
|
||||
elif is_face_femmesh(femmesh):
|
||||
slave_ref_shape = slave_ref[0].Shape.getElement(slave_ref[1][0])
|
||||
master_ref_shape = master_ref[0].Shape.getElement(master_ref[1][0])
|
||||
# get the faces ids
|
||||
slave_face_ids = femmesh.getFacesByFace(slave_ref_shape)
|
||||
master_face_ids = femmesh.getFacesByFace(master_ref_shape)
|
||||
# build slave_faces and master_faces
|
||||
# face 2 for tria6 element
|
||||
# is it face 2 for all shell elements
|
||||
for fid in slave_face_ids:
|
||||
slave_faces.append([fid, 2])
|
||||
for fid in master_face_ids:
|
||||
master_faces.append([fid, 2])
|
||||
|
||||
FreeCAD.Console.PrintLog("slave_faces: {}\n".format(slave_faces))
|
||||
FreeCAD.Console.PrintLog("master_faces: {}\n".format(master_faces))
|
||||
return [slave_faces, master_faces]
|
||||
|
||||
|
||||
# ************************************************************************************************
|
||||
# ***** groups ***********************************************************************************
|
||||
def get_mesh_group_elements(
|
||||
|
||||
@@ -587,7 +587,9 @@ class FemInputWriterCcx(writerbase.FemInputWriter):
|
||||
f.write(str(MPC_nodes[i]) + ",\n")
|
||||
|
||||
def write_surfaces_constraints_contact(self, f):
|
||||
# get surface nodes and write them to file
|
||||
# get faces
|
||||
self.get_constraints_contact_faces()
|
||||
# write faces to file
|
||||
f.write("\n***********************************************************\n")
|
||||
f.write("** Surfaces for contact constraint\n")
|
||||
f.write("** written by {} function\n".format(sys._getframe().f_code.co_name))
|
||||
@@ -595,43 +597,14 @@ class FemInputWriterCcx(writerbase.FemInputWriter):
|
||||
# femobj --> dict, FreeCAD document object is femobj["Object"]
|
||||
contact_obj = femobj["Object"]
|
||||
f.write("** " + contact_obj.Label + "\n")
|
||||
cnt = 0
|
||||
for o, elem_tup in contact_obj.References:
|
||||
for elem in elem_tup:
|
||||
ref_shape = o.Shape.getElement(elem)
|
||||
cnt = cnt + 1
|
||||
if ref_shape.ShapeType == "Face":
|
||||
if cnt == 1:
|
||||
name = "DEP" + contact_obj.Name
|
||||
else:
|
||||
name = "IND" + contact_obj.Name
|
||||
f.write("*SURFACE, NAME=" + name + "\n")
|
||||
|
||||
v = self.mesh_object.FemMesh.getccxVolumesByFace(ref_shape)
|
||||
if len(v) > 0:
|
||||
# volume elements found
|
||||
FreeCAD.Console.PrintLog(
|
||||
"{}, surface {}, {} touching volume elements found\n"
|
||||
.format(contact_obj.Label, name, len(v))
|
||||
)
|
||||
for i in v:
|
||||
f.write("{},S{}\n".format(i[0], i[1]))
|
||||
else:
|
||||
# try shell elements
|
||||
v = self.mesh_object.FemMesh.getFacesByFace(ref_shape)
|
||||
if len(v) > 0:
|
||||
FreeCAD.Console.PrintLog(
|
||||
"{}, surface {}, {} touching shell elements found\n"
|
||||
.format(contact_obj.Label, name, len(v))
|
||||
)
|
||||
for i in v:
|
||||
f.write("{},S2\n".format(i))
|
||||
else:
|
||||
FreeCAD.Console.PrintError(
|
||||
"{}, surface {}, Error: "
|
||||
"Neither volume nor shell elements found!\n"
|
||||
.format(contact_obj.Label, name)
|
||||
)
|
||||
# slave DEP
|
||||
f.write("*SURFACE, NAME=DEP{}\n".format(contact_obj.Name))
|
||||
for i in femobj["ContactSlaveFaces"]:
|
||||
f.write("{},S{}\n".format(i[0], i[1]))
|
||||
# master IND
|
||||
f.write("*SURFACE, NAME=IND{}\n".format(contact_obj.Name))
|
||||
for i in femobj["ContactMasterFaces"]:
|
||||
f.write("{},S{}\n".format(i[0], i[1]))
|
||||
|
||||
def write_node_sets_constraints_transform(self, f):
|
||||
# get nodes
|
||||
|
||||
@@ -318,6 +318,32 @@ class FemInputWriter():
|
||||
femobj["PressureFaces"] = [(some_string, pressure_faces)]
|
||||
FreeCAD.Console.PrintLog("{}\n".format(femobj["PressureFaces"]))
|
||||
|
||||
def get_constraints_contact_faces(self):
|
||||
if not self.femnodes_mesh:
|
||||
self.femnodes_mesh = self.femmesh.Nodes
|
||||
if not self.femelement_table:
|
||||
self.femelement_table = meshtools.get_femelement_table(self.femmesh)
|
||||
if not self.femnodes_ele_table:
|
||||
self.femnodes_ele_table = meshtools.get_femnodes_ele_table(
|
||||
self.femnodes_mesh,
|
||||
self.femelement_table
|
||||
)
|
||||
|
||||
for femobj in self.contact_objects:
|
||||
# femobj --> dict, FreeCAD document object is femobj["Object"]
|
||||
print_obj_info(femobj["Object"])
|
||||
contact_slave_faces, contact_master_faces = meshtools.get_contact_obj_faces(
|
||||
self.femmesh,
|
||||
self.femelement_table,
|
||||
self.femnodes_ele_table, femobj
|
||||
)
|
||||
# [ele_id, ele_face_id], [ele_id, ele_face_id], ...]
|
||||
# whereas the ele_face_id might be ccx specific
|
||||
femobj["ContactSlaveFaces"] = contact_slave_faces
|
||||
femobj["ContactMasterFaces"] = contact_master_faces
|
||||
# FreeCAD.Console.PrintLog("{}\n".format(femobj["ContactSlaveFaces"]))
|
||||
# FreeCAD.Console.PrintLog("{}\n".format(femobj["ContactMasterFaces"]))
|
||||
|
||||
def get_element_geometry2D_elements(self):
|
||||
# get element ids and write them into the objects
|
||||
FreeCAD.Console.PrintMessage("Shell thicknesses\n")
|
||||
|
||||
Reference in New Issue
Block a user