Skip to content

Commit

Permalink
FEM: constraint tie, get the faces data in writer base class
Browse files Browse the repository at this point in the history
  • Loading branch information
berndhahnebach committed Feb 5, 2020
1 parent f087655 commit 6c385b0
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 42 deletions.
75 changes: 75 additions & 0 deletions src/Mod/Fem/femmesh/meshtools.py
Expand Up @@ -1737,6 +1737,81 @@ def get_contact_obj_faces(
return [slave_faces, master_faces]


# ***** tie faces ****************************************************************************
def get_tie_obj_faces(
femmesh,
femelement_table,
femnodes_ele_table,
femobj
):
# see comment get_contact_obj_faces
# solid mesh is same as contact, but face mesh is not allowed for tie
# TODO get rid of duplicate code for contact and tie

slave_faces, master_faces = [], []

tie_obj = femobj["Object"]
if len(tie_obj.References) == 1 and len(tie_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 tie)
ref_obj = tie_obj.References[0][0]
ref_ele = tie_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(tie_obj.References) == 2
and len(tie_obj.References[0][1]) == 1
and len(tie_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 tie)
slave_ref = tie_obj.References[0]
master_ref = tie_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):
FreeCAD.Console.PrintError(
"Shell mesh is not allowed for constraint tie.\n"
)

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(
Expand Down
50 changes: 14 additions & 36 deletions src/Mod/Fem/femsolver/calculix/writer.py
Expand Up @@ -625,44 +625,24 @@ def write_surfaces_constraints_contact(self, f):
f.write("{},S{}\n".format(i[0], i[1]))

def write_surfaces_constraints_tie(self, f):
# get surface nodes and write them to file
# get faces
self.get_constraints_tie_faces()
# write faces to file
f.write("\n***********************************************************\n")
f.write("** Surfaces for tie constraint\n")
f.write("** written by {} function\n".format(sys._getframe().f_code.co_name))
obj = 0
for femobj in self.tie_objects:
# femobj --> dict, FreeCAD document object is femobj["Object"]
tie_obj = femobj["Object"]
f.write("** " + tie_obj.Label + "\n")
cnt = 0
obj = obj + 1
for o, elem_tup in tie_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 = "TIE_DEP" + str(obj)
else:
name = "TIE_IND" + str(obj)
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(tie_obj.Label, name, len(v))
)
for i in v:
f.write("{},S{}\n".format(i[0], i[1]))
else:
# no volume elements found, shell elements not allowed
FreeCAD.Console.PrintError(
"{}, surface {}, Error: "
"No volume elements found!\n"
.format(tie_obj.Label, name)
)
# slave DEP
f.write("*SURFACE, NAME=TIE_DEP{}\n".format(tie_obj.Name))
for i in femobj["TieSlaveFaces"]:
f.write("{},S{}\n".format(i[0], i[1]))
# master IND
f.write("*SURFACE, NAME=TIE_IND{}\n".format(tie_obj.Name))
for i in femobj["TieMasterFaces"]:
f.write("{},S{}\n".format(i[0], i[1]))

def write_node_sets_constraints_transform(self, f):
# get nodes
Expand Down Expand Up @@ -1098,19 +1078,17 @@ def write_constraints_tie(self, f):
f.write("\n***********************************************************\n")
f.write("** Tie Constraints\n")
f.write("** written by {} function\n".format(sys._getframe().f_code.co_name))
obj = 0
for femobj in self.tie_objects:
# femobj --> dict, FreeCAD document object is femobj["Object"]
obj = obj + 1
tie_obj = femobj["Object"]
f.write("** {}\n".format(tie_obj.Label))
tolerance = str(tie_obj.Tolerance.getValueAs("mm")).rstrip()
f.write(
"*TIE, POSITION TOLERANCE={}, ADJUST=NO, NAME=TIE{}\n"
.format(tolerance, obj)
.format(tolerance, tie_obj.Name)
)
ind_surf = "TIE_IND" + str(obj)
dep_surf = "TIE_DEP" + str(obj)
ind_surf = "TIE_IND" + tie_obj.Name
dep_surf = "TIE_DEP" + tie_obj.Name
f.write("{},{}\n".format(dep_surf, ind_surf))

def write_constraints_planerotation(self, f):
Expand Down
26 changes: 26 additions & 0 deletions src/Mod/Fem/femsolver/writerbase.py
Expand Up @@ -352,6 +352,32 @@ def get_constraints_contact_faces(self):
# FreeCAD.Console.PrintLog("{}\n".format(femobj["ContactSlaveFaces"]))
# FreeCAD.Console.PrintLog("{}\n".format(femobj["ContactMasterFaces"]))

def get_constraints_tie_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.tie_objects:
# femobj --> dict, FreeCAD document object is femobj["Object"]
print_obj_info(femobj["Object"])
slave_faces, master_faces = meshtools.get_tie_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["TieSlaveFaces"] = slave_faces
femobj["TieMasterFaces"] = 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")
Expand Down
12 changes: 6 additions & 6 deletions src/Mod/Fem/femtest/data/ccx/constraint_tie.inp
Expand Up @@ -18547,7 +18547,7 @@ Evolumes
** Surfaces for tie constraint
** written by write_surfaces_constraints_tie function
** ConstraintTie
*SURFACE, NAME=TIE_DEP1
*SURFACE, NAME=TIE_DEPConstraintTie
4834,S1
4835,S1
4890,S1
Expand All @@ -18570,7 +18570,7 @@ Evolumes
9637,S1
9877,S1
10493,S2
*SURFACE, NAME=TIE_IND1
*SURFACE, NAME=TIE_INDConstraintTie
4687,S4
5445,S3
5759,S4
Expand Down Expand Up @@ -18613,8 +18613,8 @@ Evolumes
** Tie Constraints
** written by write_constraints_tie function
** ConstraintTie
*TIE, POSITION TOLERANCE=25, ADJUST=NO, NAME=TIE1
TIE_DEP1,TIE_IND1
*TIE, POSITION TOLERANCE=25, ADJUST=NO, NAME=TIEConstraintTie
TIE_DEPConstraintTie,TIE_INDConstraintTie

***********************************************************
** At least one step is needed to run an CalculiX analysis of FreeCAD
Expand Down Expand Up @@ -18665,8 +18665,8 @@ RF
***********************************************************
** CalculiX Input file
** written by write_footer function
** written by --> FreeCAD 0.19.19475 (Git)
** written on --> Tue Feb 4 16:49:27 2020
** written by --> FreeCAD 0.19.19481 (Git)
** written on --> Wed Feb 5 08:55:37 2020
** file name -->
** analysis name --> Analysis
**
Expand Down

0 comments on commit 6c385b0

Please sign in to comment.