FEM: constraint tie, implement object and ccx writer
This commit is contained in:
@@ -229,6 +229,7 @@ SET(FemObjectsScripts_SRCS
|
||||
femobjects/_FemConstraintFlowVelocity.py
|
||||
femobjects/_FemConstraintInitialFlowVelocity.py
|
||||
femobjects/_FemConstraintSelfWeight.py
|
||||
femobjects/_FemConstraintTie.py
|
||||
femobjects/_FemElementFluid1D.py
|
||||
femobjects/_FemElementGeometry1D.py
|
||||
femobjects/_FemElementGeometry2D.py
|
||||
@@ -312,6 +313,7 @@ SET(FemGuiScripts_SRCS
|
||||
femguiobjects/_ViewProviderFemConstraintFlowVelocity.py
|
||||
femguiobjects/_ViewProviderFemConstraintInitialFlowVelocity.py
|
||||
femguiobjects/_ViewProviderFemConstraintSelfWeight.py
|
||||
femguiobjects/_ViewProviderFemConstraintTie.py
|
||||
femguiobjects/_ViewProviderFemElementFluid1D.py
|
||||
femguiobjects/_ViewProviderFemElementGeometry1D.py
|
||||
femguiobjects/_ViewProviderFemElementGeometry2D.py
|
||||
|
||||
@@ -258,6 +258,23 @@ def makeConstraintTransform(
|
||||
return obj
|
||||
|
||||
|
||||
def makeConstraintTie(
|
||||
doc,
|
||||
name="ConstraintTie"
|
||||
):
|
||||
"""makeConstraintTie(document, [name]):
|
||||
creates an tie object to define bonded faces constraint"""
|
||||
obj = doc.addObject("Fem::ConstraintPython", name)
|
||||
from femobjects import _FemConstraintTie
|
||||
_FemConstraintTie._FemConstraintTie(obj)
|
||||
if FreeCAD.GuiUp:
|
||||
from femguiobjects import _ViewProviderFemConstraintTie
|
||||
_ViewProviderFemConstraintTie._ViewProviderFemConstraintTie(
|
||||
obj.ViewObject
|
||||
)
|
||||
return obj
|
||||
|
||||
|
||||
# ********* element definition objects ***********************************************************
|
||||
def makeElementFluid1D(
|
||||
doc,
|
||||
|
||||
80
src/Mod/Fem/femguiobjects/_ViewProviderFemConstraintTie.py
Normal file
80
src/Mod/Fem/femguiobjects/_ViewProviderFemConstraintTie.py
Normal file
@@ -0,0 +1,80 @@
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * Copyright (c) 2015 Bernd Hahnebach <bernd@bimstatik.org> *
|
||||
# * *
|
||||
# * This program is free software; you can redistribute it and/or modify *
|
||||
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
# * as published by the Free Software Foundation; either version 2 of *
|
||||
# * the License, or (at your option) any later version. *
|
||||
# * for detail see the LICENCE text file. *
|
||||
# * *
|
||||
# * This program is distributed in the hope that it will be useful, *
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
# * GNU Library General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU Library General Public *
|
||||
# * License along with this program; if not, write to the Free Software *
|
||||
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
__title__ = "FreeCAD FEM constraint tie ViewProvider for the document object"
|
||||
__author__ = "Bernd Hahnebach"
|
||||
__url__ = "http://www.freecadweb.org"
|
||||
|
||||
## @package ViewProviderFemConstraintTie
|
||||
# \ingroup FEM
|
||||
# \brief FreeCAD FEM _ViewProviderFemConstraintTie
|
||||
|
||||
import FreeCAD
|
||||
import FreeCADGui
|
||||
import FemGui # needed to display the icons in TreeView
|
||||
|
||||
# for the panel
|
||||
from PySide import QtCore
|
||||
from . import FemSelectionWidgets
|
||||
|
||||
False if FemGui.__name__ else True # flake8, dummy FemGui usage
|
||||
|
||||
|
||||
class _ViewProviderFemConstraintTie:
|
||||
"A View Provider for the FemConstraintTie object"
|
||||
|
||||
def __init__(self, vobj):
|
||||
vobj.Proxy = self
|
||||
|
||||
def getIcon(self):
|
||||
return ":/icons/fem-constraint-tie.svg"
|
||||
|
||||
def attach(self, vobj):
|
||||
from pivy import coin
|
||||
self.ViewObject = vobj
|
||||
self.Object = vobj.Object
|
||||
self.standard = coin.SoGroup()
|
||||
vobj.addDisplayMode(self.standard, "Default")
|
||||
|
||||
def getDisplayModes(self, obj):
|
||||
return ["Default"]
|
||||
|
||||
def getDefaultDisplayMode(self):
|
||||
return "Default"
|
||||
|
||||
def updateData(self, obj, prop):
|
||||
return
|
||||
|
||||
def onChanged(self, vobj, prop):
|
||||
return
|
||||
|
||||
def setEdit(self, vobj, mode=0):
|
||||
return True
|
||||
|
||||
def unsetEdit(self, vobj, mode=0):
|
||||
return True
|
||||
|
||||
def __getstate__(self):
|
||||
return None
|
||||
|
||||
def __setstate__(self, state):
|
||||
return None
|
||||
44
src/Mod/Fem/femobjects/_FemConstraintTie.py
Normal file
44
src/Mod/Fem/femobjects/_FemConstraintTie.py
Normal file
@@ -0,0 +1,44 @@
|
||||
# ***************************************************************************
|
||||
# * Copyright (c) 2015 Bernd Hahnebach <bernd@bimstatik.org> *
|
||||
# * *
|
||||
# * This program is free software; you can redistribute it and/or modify *
|
||||
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
# * as published by the Free Software Foundation; either version 2 of *
|
||||
# * the License, or (at your option) any later version. *
|
||||
# * for detail see the LICENCE text file. *
|
||||
# * *
|
||||
# * This program is distributed in the hope that it will be useful, *
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
# * GNU Library General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU Library General Public *
|
||||
# * License along with this program; if not, write to the Free Software *
|
||||
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
__title__ = "FreeCAD FEM constraint tie document object"
|
||||
__author__ = "Bernd Hahnebach"
|
||||
__url__ = "https://www.freecadweb.org"
|
||||
|
||||
## @package FemConstraintTie
|
||||
# \ingroup FEM
|
||||
# \brief FreeCAD FEM constraint tie object
|
||||
|
||||
|
||||
class _FemConstraintTie:
|
||||
"The FemConstraintTie object"
|
||||
def __init__(self, obj):
|
||||
obj.addProperty(
|
||||
"App::PropertyLength",
|
||||
"Tolerance",
|
||||
"Geometry",
|
||||
"set max gap between tied faces"
|
||||
)
|
||||
obj.Proxy = self
|
||||
self.Type = "Fem::ConstraintTie"
|
||||
|
||||
def execute(self, obj):
|
||||
return
|
||||
@@ -117,6 +117,8 @@ class FemInputWriterCcx(writerbase.FemInputWriter):
|
||||
self.write_node_sets_constraints_planerotation(inpfile)
|
||||
if self.contact_objects:
|
||||
self.write_surfaces_constraints_contact(inpfile)
|
||||
if self.tie_objects:
|
||||
self.write_surfaces_constraints_tie(inpfile)
|
||||
if self.transform_objects:
|
||||
self.write_node_sets_constraints_transform(inpfile)
|
||||
if self.analysis_type == "thermomech" and self.temperature_objects:
|
||||
@@ -143,6 +145,8 @@ class FemInputWriterCcx(writerbase.FemInputWriter):
|
||||
self.write_constraints_planerotation(inpfile)
|
||||
if self.contact_objects:
|
||||
self.write_constraints_contact(inpfile)
|
||||
if self.tie_objects:
|
||||
self.write_constraints_tie(inpfile)
|
||||
if self.transform_objects:
|
||||
self.write_constraints_transform(inpfile)
|
||||
|
||||
@@ -229,6 +233,8 @@ class FemInputWriterCcx(writerbase.FemInputWriter):
|
||||
inpfileHeatflux = open(name + "_Node_Heatlfux.inp", "w")
|
||||
if self.contact_objects:
|
||||
inpfileContact = open(name + "_Surface_Contact.inp", "w")
|
||||
if self.tie_objects:
|
||||
inpfileContact = open(name + "_Surface_Tie.inp", "w")
|
||||
if self.transform_objects:
|
||||
inpfileTransform = open(name + "_Node_Transform.inp", "w")
|
||||
|
||||
@@ -242,6 +248,8 @@ class FemInputWriterCcx(writerbase.FemInputWriter):
|
||||
self.write_node_sets_constraints_planerotation(inpfileNodes)
|
||||
if self.contact_objects:
|
||||
self.write_surfaces_constraints_contact(inpfileContact)
|
||||
if self.tie_objects:
|
||||
self.write_surfaces_constraints_tie(inpfileContact)
|
||||
if self.transform_objects:
|
||||
self.write_node_sets_constraints_transform(inpfileTransform)
|
||||
|
||||
@@ -260,6 +268,12 @@ class FemInputWriterCcx(writerbase.FemInputWriter):
|
||||
if self.contact_objects:
|
||||
inpfileMain.write("*INCLUDE,INPUT=" + include_name + "_Surface_Contact.inp \n")
|
||||
|
||||
inpfileMain.write("\n***********************************************************\n")
|
||||
inpfileMain.write("** Surfaces for tie constraint\n")
|
||||
inpfileMain.write("** written by write_surfaces_constraints_tie\n")
|
||||
if self.tie_objects:
|
||||
inpfileMain.write("*INCLUDE,INPUT=" + include_name + "_Surface_Tie.inp \n")
|
||||
|
||||
inpfileMain.write("\n***********************************************************\n")
|
||||
inpfileMain.write("** Node sets for transform constraint\n")
|
||||
inpfileMain.write("** written by write_node_sets_constraints_transform\n")
|
||||
@@ -295,6 +309,8 @@ class FemInputWriterCcx(writerbase.FemInputWriter):
|
||||
self.write_constraints_planerotation(inpfileMain)
|
||||
if self.contact_objects:
|
||||
self.write_constraints_contact(inpfileMain)
|
||||
if self.tie_objects:
|
||||
self.write_constraints_tie(inpfileMain)
|
||||
if self.transform_objects:
|
||||
self.write_constraints_transform(inpfileMain)
|
||||
|
||||
@@ -574,6 +590,46 @@ class FemInputWriterCcx(writerbase.FemInputWriter):
|
||||
for i in femobj["ContactMasterFaces"]:
|
||||
f.write("{},S{}\n".format(i[0], i[1]))
|
||||
|
||||
def write_surfaces_constraints_tie(self, f):
|
||||
# get surface nodes and write them 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)
|
||||
)
|
||||
|
||||
def write_node_sets_constraints_transform(self, f):
|
||||
# get nodes
|
||||
self.get_constraints_transform_nodes()
|
||||
@@ -1005,6 +1061,25 @@ class FemInputWriterCcx(writerbase.FemInputWriter):
|
||||
stick = (slope / 10.0)
|
||||
f.write(str(friction) + ", " + str(stick) + " \n")
|
||||
|
||||
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)
|
||||
)
|
||||
ind_surf = "TIE_IND" + str(obj)
|
||||
dep_surf = "TIE_DEP" + str(obj)
|
||||
f.write("{},{}\n".format(dep_surf, ind_surf))
|
||||
|
||||
def write_constraints_planerotation(self, f):
|
||||
f.write("\n***********************************************************\n")
|
||||
f.write("** PlaneRotation Constraints\n")
|
||||
|
||||
@@ -66,6 +66,7 @@ class FemInputWriter():
|
||||
self.pressure_objects = member.cons_pressure
|
||||
self.selfweight_objects = member.cons_selfweight
|
||||
self.temperature_objects = member.cons_temperature
|
||||
self.tie_objects = member.cons_tie
|
||||
self.transform_objects = member.cons_transform
|
||||
# working dir
|
||||
self.dir_name = dir_name
|
||||
|
||||
@@ -68,6 +68,7 @@ class TestObjectCreate(unittest.TestCase):
|
||||
analysis.addObject(ObjectsFem.makeConstraintBearing(doc))
|
||||
analysis.addObject(ObjectsFem.makeConstraintBodyHeatSource(doc))
|
||||
analysis.addObject(ObjectsFem.makeConstraintContact(doc))
|
||||
analysis.addObject(ObjectsFem.makeConstraintTie(doc))
|
||||
analysis.addObject(ObjectsFem.makeConstraintDisplacement(doc))
|
||||
analysis.addObject(ObjectsFem.makeConstraintElectrostaticPotential(doc))
|
||||
analysis.addObject(ObjectsFem.makeConstraintFixed(doc))
|
||||
@@ -260,6 +261,10 @@ class TestObjectType(unittest.TestCase):
|
||||
"Fem::ConstraintTemperature",
|
||||
type_of_obj(ObjectsFem.makeConstraintTemperature(doc))
|
||||
)
|
||||
self.assertEqual(
|
||||
"Fem::ConstraintTie",
|
||||
type_of_obj(ObjectsFem.makeConstraintTie(doc))
|
||||
)
|
||||
self.assertEqual(
|
||||
"Fem::ConstraintTransform",
|
||||
type_of_obj(ObjectsFem.makeConstraintTransform(doc))
|
||||
@@ -453,6 +458,10 @@ class TestObjectType(unittest.TestCase):
|
||||
ObjectsFem.makeConstraintTemperature(doc),
|
||||
"Fem::ConstraintTemperature"
|
||||
))
|
||||
self.assertTrue(is_of_type(
|
||||
ObjectsFem.makeConstraintTie(doc),
|
||||
"Fem::ConstraintTie"
|
||||
))
|
||||
self.assertTrue(is_of_type(
|
||||
ObjectsFem.makeConstraintTransform(doc),
|
||||
"Fem::ConstraintTransform"
|
||||
@@ -855,6 +864,25 @@ class TestObjectType(unittest.TestCase):
|
||||
"Fem::ConstraintTemperature"
|
||||
))
|
||||
|
||||
# ConstraintTie
|
||||
constraint_tie = ObjectsFem.makeConstraintTie(doc)
|
||||
self.assertTrue(is_derived_from(
|
||||
constraint_tie,
|
||||
"App::DocumentObject"
|
||||
))
|
||||
self.assertTrue(is_derived_from(
|
||||
constraint_tie,
|
||||
"Fem::Constraint"
|
||||
))
|
||||
self.assertTrue(is_derived_from(
|
||||
constraint_tie,
|
||||
"Fem::ConstraintPython"
|
||||
))
|
||||
self.assertTrue(is_derived_from(
|
||||
constraint_tie,
|
||||
"Fem::ConstraintTie"
|
||||
))
|
||||
|
||||
# ConstraintTransform
|
||||
constraint_transform = ObjectsFem.makeConstraintTransform(doc)
|
||||
self.assertTrue(is_derived_from(
|
||||
@@ -1345,6 +1373,11 @@ class TestObjectType(unittest.TestCase):
|
||||
doc
|
||||
).isDerivedFrom("Fem::ConstraintTemperature")
|
||||
)
|
||||
self.assertTrue(
|
||||
ObjectsFem.makeConstraintTie(
|
||||
doc
|
||||
).isDerivedFrom("Fem::ConstraintPython")
|
||||
)
|
||||
self.assertTrue(
|
||||
ObjectsFem.makeConstraintTransform(
|
||||
doc).isDerivedFrom("Fem::ConstraintTransform")
|
||||
|
||||
@@ -456,6 +456,17 @@ class FemToolsCcx(QtCore.QRunnable, QtCore.QObject):
|
||||
for c in self.member.cons_contact:
|
||||
if len(c["Object"].References) == 0:
|
||||
message += "{} has empty references.".format(c["Object"].Name)
|
||||
# tie
|
||||
if self.member.cons_tie:
|
||||
for c in self.member.cons_tie:
|
||||
items = 0
|
||||
for reference in c["Object"].References:
|
||||
items += len(reference[1])
|
||||
if items != 2:
|
||||
message += (
|
||||
"{} doesn't references exactly two needed faces.\n"
|
||||
.format(c["Object"].Name)
|
||||
)
|
||||
# transform
|
||||
if self.member.cons_transform:
|
||||
for c in self.member.cons_transform:
|
||||
|
||||
@@ -226,6 +226,10 @@ class AnalysisMember():
|
||||
list of temperatures for the analysis.
|
||||
[{"Object":temerature_obj, "xxxxxxxx":value}, {}, ...]
|
||||
|
||||
constraints_tie : list of dictionaries
|
||||
list of ties for the analysis.
|
||||
[{"Object":tie_obj, "xxxxxxxx":value}, {}, ...]
|
||||
|
||||
constraints_transform : list of dictionaries
|
||||
list of transform constraints from the analysis.
|
||||
[{"Object":transform_obj, "xxxxxxxx":value}, {}, ...]
|
||||
@@ -290,6 +294,9 @@ class AnalysisMember():
|
||||
self.cons_temperature = self.get_several_member(
|
||||
"Fem::ConstraintTemperature"
|
||||
)
|
||||
self.cons_tie = self.get_several_member(
|
||||
"Fem::ConstraintTie"
|
||||
)
|
||||
self.cons_transform = self.get_several_member(
|
||||
"Fem::ConstraintTransform"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user