FEM: added object FemShellThickness and FemBeamSection to enable shell and beam analysises
This commit is contained in:
parent
de1bdefc7c
commit
705c339f21
|
@ -72,6 +72,10 @@ SET(FemScripts_SRCS
|
|||
ccxFrdReader.py
|
||||
ccxInpWriter.py
|
||||
TestFem.py
|
||||
FemShellThickness.py
|
||||
FemShellThickness.ui
|
||||
FemBeamSection.py
|
||||
FemBeamSection.ui
|
||||
FemTools.py
|
||||
MechanicalAnalysis.ui
|
||||
MechanicalAnalysis.py
|
||||
|
|
|
@ -14,7 +14,11 @@ INSTALL(
|
|||
ccxInpWriter.py
|
||||
FemTools.py
|
||||
TestFem.py
|
||||
FemBeamSection.py
|
||||
FemBeamSection.ui
|
||||
FemExample.py
|
||||
FemShellThickness.py
|
||||
FemShellThickness.ui
|
||||
MechanicalAnalysis.py
|
||||
MechanicalMaterial.py
|
||||
MechanicalMaterial.ui
|
||||
|
|
227
src/Mod/Fem/FemBeamSection.py
Normal file
227
src/Mod/Fem/FemBeamSection.py
Normal file
|
@ -0,0 +1,227 @@
|
|||
#***************************************************************************
|
||||
#* *
|
||||
#* 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 *
|
||||
#* *
|
||||
#***************************************************************************
|
||||
|
||||
import FreeCAD
|
||||
|
||||
if FreeCAD.GuiUp:
|
||||
import FreeCADGui
|
||||
import FemGui
|
||||
from PySide import QtGui
|
||||
from PySide import QtCore
|
||||
from pivy import coin
|
||||
|
||||
|
||||
__title__ = "FemBeamSection"
|
||||
__author__ = "Bernd Hahnebach"
|
||||
__url__ = "http://www.freecadweb.org"
|
||||
|
||||
|
||||
def makeFemBeamSection(width=20.0, height=20.0, name="BeamSection"):
|
||||
'''makeFemBeamSection([width], [height], [name]): creates an beamsection object to define a cross section'''
|
||||
obj = FreeCAD.ActiveDocument.addObject("App::FeaturePython", name)
|
||||
_FemBeamSection(obj)
|
||||
obj.Width = width
|
||||
obj.Height = height
|
||||
if FreeCAD.GuiUp:
|
||||
_ViewProviderFemBeamSection(obj.ViewObject)
|
||||
return obj
|
||||
|
||||
|
||||
class _CommandFemBeamSection:
|
||||
"The Fem_BeamSection command definition"
|
||||
def GetResources(self):
|
||||
return {'Pixmap': 'fem-beam-section',
|
||||
'MenuText': QtCore.QT_TRANSLATE_NOOP("Fem_BeamSection", "FEM Beam Cross Section Definition ..."),
|
||||
'Accel': "C, B",
|
||||
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Fem_BeamSection", "Creates a FEM Beam Cross Section")}
|
||||
|
||||
def Activated(self):
|
||||
FreeCAD.ActiveDocument.openTransaction("Create FemBeamSection")
|
||||
FreeCADGui.addModule("FemBeamSection")
|
||||
FreeCADGui.doCommand("FemBeamSection.makeFemBeamSection()")
|
||||
FreeCADGui.doCommand("App.activeDocument()." + FemGui.getActiveAnalysis().Name + ".Member = App.activeDocument()." + FemGui.getActiveAnalysis().Name + ".Member + [App.ActiveDocument.ActiveObject]")
|
||||
|
||||
def IsActive(self):
|
||||
True if FemGui.getActiveAnalysis() else False
|
||||
|
||||
|
||||
class _FemBeamSection:
|
||||
"The FemBeamSection object"
|
||||
def __init__(self, obj):
|
||||
obj.addProperty("App::PropertyLength", "Width", "BeamSection", "set width of the beam elements")
|
||||
obj.addProperty("App::PropertyLength", "Height", "BeamSection", "set height of the beam elements")
|
||||
obj.addProperty("App::PropertyLinkSubList", "References", "BeamSection", "List of beam section shapes")
|
||||
obj.Proxy = self
|
||||
self.Type = "FemBeamSection"
|
||||
|
||||
def execute(self, obj):
|
||||
return
|
||||
|
||||
|
||||
class _ViewProviderFemBeamSection:
|
||||
"A View Provider for the FemBeamSection object"
|
||||
def __init__(self, vobj):
|
||||
vobj.Proxy = self
|
||||
|
||||
def getIcon(self):
|
||||
return ":/icons/fem-beam-section.svg"
|
||||
|
||||
def attach(self, vobj):
|
||||
self.ViewObject = vobj
|
||||
self.Object = vobj.Object
|
||||
self.standard = coin.SoGroup()
|
||||
vobj.addDisplayMode(self.standard, "Standard")
|
||||
|
||||
def getDisplayModes(self, obj):
|
||||
return ["Standard"]
|
||||
|
||||
def getDefaultDisplayMode(self):
|
||||
return "Standard"
|
||||
|
||||
def updateData(self, obj, prop):
|
||||
return
|
||||
|
||||
def onChanged(self, vobj, prop):
|
||||
return
|
||||
|
||||
def setEdit(self, vobj, mode=0):
|
||||
taskd = _FemBeamSectionTaskPanel(self.Object)
|
||||
taskd.obj = vobj.Object
|
||||
#taskd.update() When is this needed ?
|
||||
FreeCADGui.Control.showDialog(taskd)
|
||||
return True
|
||||
|
||||
def unsetEdit(self, vobj, mode=0):
|
||||
FreeCADGui.Control.closeDialog()
|
||||
return
|
||||
|
||||
def doubleClicked(self, vobj):
|
||||
self.setEdit(vobj)
|
||||
|
||||
def __getstate__(self):
|
||||
return None
|
||||
|
||||
def __setstate__(self, state):
|
||||
return None
|
||||
|
||||
|
||||
class _FemBeamSectionTaskPanel:
|
||||
'''The TaskPanel for editing References property of FemBeamSection objects'''
|
||||
def __init__(self, obj):
|
||||
FreeCADGui.Selection.clearSelection()
|
||||
self.sel_server = None
|
||||
self.obj = obj
|
||||
self.form = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Fem/FemBeamSection.ui")
|
||||
|
||||
QtCore.QObject.connect(self.form.pushButton_Reference, QtCore.SIGNAL("clicked()"), self.add_references)
|
||||
self.form.list_References.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
|
||||
self.form.list_References.connect(self.form.list_References, QtCore.SIGNAL("customContextMenuRequested(QPoint)"), self.references_list_right_clicked)
|
||||
|
||||
self.previous_references = self.obj.References
|
||||
self.references = self.obj.References
|
||||
self.rebuild_list_References()
|
||||
|
||||
def accept(self):
|
||||
if self.sel_server:
|
||||
FreeCADGui.Selection.removeObserver(self.sel_server)
|
||||
self.obj.References = self.references
|
||||
FreeCADGui.ActiveDocument.resetEdit()
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
return True
|
||||
|
||||
def reject(self):
|
||||
if self.sel_server:
|
||||
FreeCADGui.Selection.removeObserver(self.sel_server)
|
||||
FreeCADGui.ActiveDocument.resetEdit()
|
||||
return True
|
||||
|
||||
def references_list_right_clicked(self, QPos):
|
||||
self.form.contextMenu = QtGui.QMenu()
|
||||
menu_item = self.form.contextMenu.addAction("Remove Reference")
|
||||
if not self.references:
|
||||
menu_item.setDisabled(True)
|
||||
self.form.connect(menu_item, QtCore.SIGNAL("triggered()"), self.remove_reference)
|
||||
parentPosition = self.form.list_References.mapToGlobal(QtCore.QPoint(0, 0))
|
||||
self.form.contextMenu.move(parentPosition + QPos)
|
||||
self.form.contextMenu.show()
|
||||
|
||||
def remove_reference(self):
|
||||
if not self.references:
|
||||
return
|
||||
currentItemName = str(self.form.list_References.currentItem().text())
|
||||
for ref in self.references:
|
||||
refname_to_compare_listentry = ref[0].Name + '-->' + ref[1]
|
||||
if refname_to_compare_listentry == currentItemName:
|
||||
self.references.remove(ref)
|
||||
self.rebuild_list_References()
|
||||
|
||||
def add_references(self):
|
||||
'''Called if Button add_reference is triggered'''
|
||||
# in constraints EditTaskPanel the selection is active as soon as the taskpanel is open
|
||||
# here the addReference button EditTaskPanel has to be triggered to start selection mode
|
||||
FreeCADGui.Selection.clearSelection()
|
||||
# start SelectionObserver and parse the function to add the References to the widget
|
||||
self.sel_server = ReferenceShapeSelectionObserver(self.selectionParser)
|
||||
|
||||
def selectionParser(self, selsub):
|
||||
sel = selsub[0]
|
||||
sub = selsub[1]
|
||||
# print 'selection: ', sel.Shape.ShapeType, ' ', sel.Name, ' ', sub
|
||||
if hasattr(sel, "Shape"):
|
||||
elt = sel.Shape.getElement(sub)
|
||||
if elt.ShapeType == 'Edge':
|
||||
if selsub not in self.references:
|
||||
self.references.append(selsub)
|
||||
self.rebuild_list_References()
|
||||
else:
|
||||
print sel.Name, '-->', sub, ' is already in reference list!'
|
||||
|
||||
else:
|
||||
print 'Selection has no shape!'
|
||||
|
||||
def rebuild_list_References(self):
|
||||
self.form.list_References.clear()
|
||||
items = []
|
||||
for i in self.references:
|
||||
item_name = i[0].Name + '-->' + i[1]
|
||||
items.append(item_name)
|
||||
for listItemName in sorted(items):
|
||||
listItem = QtGui.QListWidgetItem(listItemName, self.form.list_References) # listItem = is needed
|
||||
|
||||
|
||||
class ReferenceShapeSelectionObserver:
|
||||
'''ReferenceShapeSelectionObserver
|
||||
started on click button addReference'''
|
||||
def __init__(self, parseSelectionFunction):
|
||||
self.parseSelectionFunction = parseSelectionFunction
|
||||
FreeCADGui.Selection.addObserver(self)
|
||||
FreeCAD.Console.PrintMessage("Select Faces to add them to the list!\n")
|
||||
|
||||
def addSelection(self, docName, objName, sub, pos):
|
||||
selected_object = FreeCAD.getDocument(docName).getObject(objName) # get the obj objName
|
||||
self.added_obj = (selected_object, sub)
|
||||
if sub: # on doubleClick the solid is selected and sub will be empty
|
||||
self.parseSelectionFunction(self.added_obj)
|
||||
|
||||
|
||||
if FreeCAD.GuiUp:
|
||||
FreeCADGui.addCommand('Fem_BeamSection', _CommandFemBeamSection())
|
99
src/Mod/Fem/FemBeamSection.ui
Normal file
99
src/Mod/Fem/FemBeamSection.ui
Normal file
|
@ -0,0 +1,99 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Form</class>
|
||||
<widget class="QWidget" name="Form">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>249</width>
|
||||
<height>379</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>1677215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Cross Section</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<widget class="QLabel" name="l_label_text_3">
|
||||
<property name="text">
|
||||
<string>Use FreeCAD Property Editor</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="l_label_text_4">
|
||||
<property name="text">
|
||||
<string>to edit the cross section values</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_1">
|
||||
<property name="title">
|
||||
<string>Reference</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="l_label_text_1">
|
||||
<property name="text">
|
||||
<string>Leave reference blank </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="l_label_text_2">
|
||||
<property name="text">
|
||||
<string>to choose all remaining shapes</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_Reference">
|
||||
<property name="text">
|
||||
<string>Add reference</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListWidget" name="list_References"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
225
src/Mod/Fem/FemShellThickness.py
Normal file
225
src/Mod/Fem/FemShellThickness.py
Normal file
|
@ -0,0 +1,225 @@
|
|||
#***************************************************************************
|
||||
#* *
|
||||
#* 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 *
|
||||
#* *
|
||||
#***************************************************************************
|
||||
|
||||
import FreeCAD
|
||||
|
||||
if FreeCAD.GuiUp:
|
||||
import FreeCADGui
|
||||
import FemGui
|
||||
from PySide import QtGui
|
||||
from PySide import QtCore
|
||||
from pivy import coin
|
||||
|
||||
|
||||
__title__ = "FemShellThickness"
|
||||
__author__ = "Bernd Hahnebach"
|
||||
__url__ = "http://www.freecadweb.org"
|
||||
|
||||
|
||||
def makeFemShellThickness(thickness=20.0, name="ShellThickness"):
|
||||
'''makeFemShellThickness([thickness], [name]): creates an shellthickness object to define a plate thickness'''
|
||||
obj = FreeCAD.ActiveDocument.addObject("App::FeaturePython", name)
|
||||
_FemShellThickness(obj)
|
||||
obj.Thickness = thickness
|
||||
if FreeCAD.GuiUp:
|
||||
_ViewProviderFemShellThickness(obj.ViewObject)
|
||||
return obj
|
||||
|
||||
|
||||
class _CommandFemShellThickness:
|
||||
"The Fem_ShellThickness command definition"
|
||||
def GetResources(self):
|
||||
return {'Pixmap': 'fem-shell-thickness',
|
||||
'MenuText': QtCore.QT_TRANSLATE_NOOP("Fem_ShellThickness", "FEM Shell Plate Thickness Definition ..."),
|
||||
'Accel': "C, S",
|
||||
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Fem_ShellThickness", "Creates a FEM Shell Thickness")}
|
||||
|
||||
def Activated(self):
|
||||
FreeCAD.ActiveDocument.openTransaction("Create FemShellThickness")
|
||||
FreeCADGui.addModule("FemShellThickness")
|
||||
FreeCADGui.doCommand("FemShellThickness.makeFemShellThickness()")
|
||||
FreeCADGui.doCommand("App.activeDocument()." + FemGui.getActiveAnalysis().Name + ".Member = App.activeDocument()." + FemGui.getActiveAnalysis().Name + ".Member + [App.ActiveDocument.ActiveObject]")
|
||||
|
||||
def IsActive(self):
|
||||
True if FemGui.getActiveAnalysis() else False
|
||||
|
||||
|
||||
class _FemShellThickness:
|
||||
"The FemShellThickness object"
|
||||
def __init__(self, obj):
|
||||
obj.addProperty("App::PropertyLength", "Thickness", "ShellThickness", "set thickness of the shell elements")
|
||||
obj.addProperty("App::PropertyLinkSubList", "References", "ShellThickness", "List of shell thickness shapes")
|
||||
obj.Proxy = self
|
||||
self.Type = "FemShellThickness"
|
||||
|
||||
def execute(self, obj):
|
||||
return
|
||||
|
||||
|
||||
class _ViewProviderFemShellThickness:
|
||||
"A View Provider for the FemShellThickness object"
|
||||
def __init__(self, vobj):
|
||||
vobj.Proxy = self
|
||||
|
||||
def getIcon(self):
|
||||
return ":/icons/fem-shell-thickness.svg"
|
||||
|
||||
def attach(self, vobj):
|
||||
self.ViewObject = vobj
|
||||
self.Object = vobj.Object
|
||||
self.standard = coin.SoGroup()
|
||||
vobj.addDisplayMode(self.standard, "Standard")
|
||||
|
||||
def getDisplayModes(self, obj):
|
||||
return ["Standard"]
|
||||
|
||||
def getDefaultDisplayMode(self):
|
||||
return "Standard"
|
||||
|
||||
def updateData(self, obj, prop):
|
||||
return
|
||||
|
||||
def onChanged(self, vobj, prop):
|
||||
return
|
||||
|
||||
def setEdit(self, vobj, mode=0):
|
||||
taskd = _FemShellThicknessTaskPanel(self.Object)
|
||||
taskd.obj = vobj.Object
|
||||
# taskd.update() When is this needed ?
|
||||
FreeCADGui.Control.showDialog(taskd)
|
||||
return True
|
||||
|
||||
def unsetEdit(self, vobj, mode=0):
|
||||
FreeCADGui.Control.closeDialog()
|
||||
return
|
||||
|
||||
def doubleClicked(self, vobj):
|
||||
self.setEdit(vobj)
|
||||
|
||||
def __getstate__(self):
|
||||
return None
|
||||
|
||||
def __setstate__(self, state):
|
||||
return None
|
||||
|
||||
|
||||
class _FemShellThicknessTaskPanel:
|
||||
'''The TaskPanel for editing References property of FemShellThickness objects'''
|
||||
def __init__(self, obj):
|
||||
FreeCADGui.Selection.clearSelection()
|
||||
self.sel_server = None
|
||||
self.obj = obj
|
||||
self.form = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Fem/FemShellThickness.ui")
|
||||
|
||||
QtCore.QObject.connect(self.form.pushButton_Reference, QtCore.SIGNAL("clicked()"), self.add_references)
|
||||
self.form.list_References.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
|
||||
self.form.list_References.connect(self.form.list_References, QtCore.SIGNAL("customContextMenuRequested(QPoint)"), self.references_list_right_clicked)
|
||||
|
||||
self.previous_references = self.obj.References
|
||||
self.references = self.obj.References
|
||||
self.rebuild_list_References()
|
||||
|
||||
def accept(self):
|
||||
if self.sel_server:
|
||||
FreeCADGui.Selection.removeObserver(self.sel_server)
|
||||
self.obj.References = self.references
|
||||
FreeCADGui.ActiveDocument.resetEdit()
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
return True
|
||||
|
||||
def reject(self):
|
||||
if self.sel_server:
|
||||
FreeCADGui.Selection.removeObserver(self.sel_server)
|
||||
FreeCADGui.ActiveDocument.resetEdit()
|
||||
return True
|
||||
|
||||
def references_list_right_clicked(self, QPos):
|
||||
self.form.contextMenu = QtGui.QMenu()
|
||||
menu_item = self.form.contextMenu.addAction("Remove Reference")
|
||||
if not self.references:
|
||||
menu_item.setDisabled(True)
|
||||
self.form.connect(menu_item, QtCore.SIGNAL("triggered()"), self.remove_reference)
|
||||
parentPosition = self.form.list_References.mapToGlobal(QtCore.QPoint(0, 0))
|
||||
self.form.contextMenu.move(parentPosition + QPos)
|
||||
self.form.contextMenu.show()
|
||||
|
||||
def remove_reference(self):
|
||||
if not self.references:
|
||||
return
|
||||
currentItemName = str(self.form.list_References.currentItem().text())
|
||||
for ref in self.references:
|
||||
refname_to_compare_listentry = ref[0].Name + '-->' + ref[1]
|
||||
if refname_to_compare_listentry == currentItemName:
|
||||
self.references.remove(ref)
|
||||
self.rebuild_list_References()
|
||||
|
||||
def add_references(self):
|
||||
'''Called if Button add_reference is triggered'''
|
||||
# in constraints EditTaskPanel the selection is active as soon as the taskpanel is open
|
||||
# here the addReference button EditTaskPanel has to be triggered to start selection mode
|
||||
FreeCADGui.Selection.clearSelection()
|
||||
# start SelectionObserver and parse the function to add the References to the widget
|
||||
self.sel_server = ReferenceShapeSelectionObserver(self.selectionParser)
|
||||
|
||||
def selectionParser(self, selsub):
|
||||
sel = selsub[0]
|
||||
sub = selsub[1]
|
||||
# print 'selection: ', sel.Shape.ShapeType, ' ', sel.Name, ' ', sub
|
||||
if hasattr(sel, "Shape"):
|
||||
elt = sel.Shape.getElement(sub)
|
||||
if elt.ShapeType == 'Face':
|
||||
if selsub not in self.references:
|
||||
self.references.append(selsub)
|
||||
self.rebuild_list_References()
|
||||
else:
|
||||
print sel.Name, '-->', sub, ' is already in reference list!'
|
||||
|
||||
else:
|
||||
print 'Selection has no shape!'
|
||||
|
||||
def rebuild_list_References(self):
|
||||
self.form.list_References.clear()
|
||||
items = []
|
||||
for i in self.references:
|
||||
item_name = i[0].Name + '-->' + i[1]
|
||||
items.append(item_name)
|
||||
for listItemName in sorted(items):
|
||||
listItem = QtGui.QListWidgetItem(listItemName, self.form.list_References) # listItem = is needed
|
||||
|
||||
|
||||
class ReferenceShapeSelectionObserver:
|
||||
'''ReferenceShapeSelectionObserver
|
||||
started on click button addReference'''
|
||||
def __init__(self, parseSelectionFunction):
|
||||
self.parseSelectionFunction = parseSelectionFunction
|
||||
FreeCADGui.Selection.addObserver(self)
|
||||
FreeCAD.Console.PrintMessage("Select Faces to add them to the list!\n")
|
||||
|
||||
def addSelection(self, docName, objName, sub, pos):
|
||||
selected_object = FreeCAD.getDocument(docName).getObject(objName) # get the obj objName
|
||||
self.added_obj = (selected_object, sub)
|
||||
if lsub: # on doubleClick the solid is selected and sub will be empty
|
||||
self.parseSelectionFunction(self.added_obj)
|
||||
|
||||
|
||||
if FreeCAD.GuiUp:
|
||||
FreeCADGui.addCommand('Fem_ShellThickness', _CommandFemShellThickness())
|
99
src/Mod/Fem/FemShellThickness.ui
Normal file
99
src/Mod/Fem/FemShellThickness.ui
Normal file
|
@ -0,0 +1,99 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Form</class>
|
||||
<widget class="QWidget" name="Form">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>249</width>
|
||||
<height>379</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>1677215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Thickness</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<widget class="QLabel" name="l_label_text_3">
|
||||
<property name="text">
|
||||
<string>Use FreeCAD Property Editor</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="l_label_text_4">
|
||||
<property name="text">
|
||||
<string>to edit the thickness value</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_1">
|
||||
<property name="title">
|
||||
<string>Reference</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="l_label_text_1">
|
||||
<property name="text">
|
||||
<string>Leave reference blank </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="l_label_text_2">
|
||||
<property name="text">
|
||||
<string>to choose all remaining shapes</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_Reference">
|
||||
<property name="text">
|
||||
<string>Add reference</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListWidget" name="list_References"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -118,11 +118,15 @@ class FemTools(QtCore.QRunnable, QtCore.QObject):
|
|||
# [{'Object':fixed_constraints, 'NodeSupports':bool}, {}, ...]
|
||||
# [{'Object':force_constraints, 'NodeLoad':value}, {}, ...
|
||||
# [{'Object':pressure_constraints, 'xxxxxxxx':value}, {}, ...]
|
||||
# [{'Object':beam_sections, 'xxxxxxxx':value}, {}, ...]
|
||||
# [{'Object':shell_thicknesses, 'xxxxxxxx':value}, {}, ...]
|
||||
self.mesh = None
|
||||
self.material = []
|
||||
self.fixed_constraints = []
|
||||
self.force_constraints = []
|
||||
self.pressure_constraints = []
|
||||
self.beam_sections = []
|
||||
self.shell_thicknesses = []
|
||||
|
||||
for m in self.analysis.Member:
|
||||
if m.isDerivedFrom("Fem::FemMeshObject"):
|
||||
|
@ -143,6 +147,14 @@ class FemTools(QtCore.QRunnable, QtCore.QObject):
|
|||
PressureObjectDict = {}
|
||||
PressureObjectDict['Object'] = m
|
||||
self.pressure_constraints.append(PressureObjectDict)
|
||||
elif hasattr(m, "Proxy") and m.Proxy.Type == 'FemBeamSection':
|
||||
beam_section_dict = {}
|
||||
beam_section_dict['Object'] = m
|
||||
self.beam_sections.append(beam_section_dict)
|
||||
elif hasattr(m, "Proxy") and m.Proxy.Type == 'FemShellThickness':
|
||||
shell_thickness_dict = {}
|
||||
shell_thickness_dict['Object'] = m
|
||||
self.shell_thicknesses.append(shell_thickness_dict)
|
||||
|
||||
def check_prerequisites(self):
|
||||
message = ""
|
||||
|
@ -159,6 +171,20 @@ class FemTools(QtCore.QRunnable, QtCore.QObject):
|
|||
if self.analysis_type == "static":
|
||||
if not (self.force_constraints or self.pressure_constraints):
|
||||
message += "No force-constraint or pressure-constraint defined in the Analysis\n"
|
||||
if self.beam_sections:
|
||||
has_no_references = False
|
||||
for b in self.beam_sections:
|
||||
if len(b['Object'].References) == 0:
|
||||
if has_no_references is True:
|
||||
message += "More than one BeamSection has empty References list (Only one empty References list is allowed!).\n"
|
||||
has_no_references = True
|
||||
if self.shell_thicknesses:
|
||||
has_no_references = False
|
||||
for s in self.shell_thicknesses:
|
||||
if len(s['Object'].References) == 0:
|
||||
if has_no_references is True:
|
||||
message += "More than one ShellThickness has empty References list (Only one empty References list is allowed!).\n"
|
||||
has_no_references = True
|
||||
return message
|
||||
|
||||
def write_inp_file(self):
|
||||
|
@ -167,9 +193,11 @@ class FemTools(QtCore.QRunnable, QtCore.QObject):
|
|||
self.inp_file_name = ""
|
||||
try:
|
||||
inp_writer = iw.inp_writer(self.analysis, self.mesh, self.material,
|
||||
self.fixed_constraints, self.force_constraints,
|
||||
self.pressure_constraints, self.analysis_type,
|
||||
self.eigenmode_parameters, self.working_dir)
|
||||
self.fixed_constraints,
|
||||
self.force_constraints, self.pressure_constraints,
|
||||
self.beam_sections, self.shell_thicknesses,
|
||||
self.analysis_type, self.eigenmode_parameters,
|
||||
self.working_dir)
|
||||
self.inp_file_name = inp_writer.write_calculix_input_file()
|
||||
except:
|
||||
print "Unexpected error when writing CalculiX input file:", sys.exc_info()[0]
|
||||
|
|
|
@ -104,6 +104,8 @@ void FemGuiExport initFemGui()
|
|||
|
||||
Base::Interpreter().loadModule("MechanicalAnalysis");
|
||||
Base::Interpreter().loadModule("MechanicalMaterial");
|
||||
Base::Interpreter().loadModule("FemBeamSection");
|
||||
Base::Interpreter().loadModule("FemShellThickness");
|
||||
|
||||
// register preferences pages
|
||||
new Gui::PrefPageProducer<FemGui::DlgSettingsFemImp> ("FEM");
|
||||
|
|
|
@ -58,6 +58,8 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
|
|||
*fem << "Fem_NewMechanicalAnalysis"
|
||||
<< "Fem_CreateFromShape"
|
||||
<< "Fem_MechanicalMaterial"
|
||||
<< "Fem_BeamSection"
|
||||
<< "Fem_ShellThickness"
|
||||
<< "Separator"
|
||||
<< "Fem_CreateNodesSet"
|
||||
<< "Separator"
|
||||
|
@ -86,6 +88,8 @@ Gui::MenuItem* Workbench::setupMenuBar() const
|
|||
*fem << "Fem_NewMechanicalAnalysis"
|
||||
<< "Fem_CreateFromShape"
|
||||
<< "Fem_MechanicalMaterial"
|
||||
<< "Fem_BeamSection"
|
||||
<< "Fem_ShellThickness"
|
||||
<< "Separator"
|
||||
<< "Fem_CreateNodesSet"
|
||||
<< "Separator"
|
||||
|
|
|
@ -590,7 +590,8 @@ class _ResultControlTaskPanel:
|
|||
def vm_stress_selected(self, state):
|
||||
FreeCAD.FEM_dialog["results_type"] = "Sabs"
|
||||
QApplication.setOverrideCursor(Qt.WaitCursor)
|
||||
self.MeshObject.ViewObject.setNodeColorByScalars(self.result_object.ElementNumbers, self.result_object.StressValues)
|
||||
if self.suitable_results:
|
||||
self.MeshObject.ViewObject.setNodeColorByScalars(self.result_object.ElementNumbers, self.result_object.StressValues)
|
||||
(minm, avg, maxm) = self.get_result_stats("Sabs")
|
||||
self.set_result_stats("MPa", minm, avg, maxm)
|
||||
QtGui.qApp.restoreOverrideCursor()
|
||||
|
@ -598,12 +599,14 @@ class _ResultControlTaskPanel:
|
|||
def select_displacement_type(self, disp_type):
|
||||
QApplication.setOverrideCursor(Qt.WaitCursor)
|
||||
if disp_type == "Uabs":
|
||||
self.MeshObject.ViewObject.setNodeColorByScalars(self.result_object.ElementNumbers, self.result_object.DisplacementLengths)
|
||||
if self.suitable_results:
|
||||
self.MeshObject.ViewObject.setNodeColorByScalars(self.result_object.ElementNumbers, self.result_object.DisplacementLengths)
|
||||
else:
|
||||
match = {"U1": 0, "U2": 1, "U3": 2}
|
||||
d = zip(*self.result_object.DisplacementVectors)
|
||||
displacements = list(d[match[disp_type]])
|
||||
self.MeshObject.ViewObject.setNodeColorByScalars(self.result_object.ElementNumbers, displacements)
|
||||
if self.suitable_results:
|
||||
self.MeshObject.ViewObject.setNodeColorByScalars(self.result_object.ElementNumbers, displacements)
|
||||
(minm, avg, maxm) = self.get_result_stats(disp_type)
|
||||
self.set_result_stats("mm", minm, avg, maxm)
|
||||
QtGui.qApp.restoreOverrideCursor()
|
||||
|
@ -631,7 +634,8 @@ class _ResultControlTaskPanel:
|
|||
if FreeCAD.FEM_dialog["result_object"] != self.result_object:
|
||||
self.update_displacement()
|
||||
FreeCAD.FEM_dialog["result_object"] = self.result_object
|
||||
self.MeshObject.ViewObject.setNodeDisplacementByVectors(self.result_object.ElementNumbers, self.result_object.DisplacementVectors)
|
||||
if self.suitable_results:
|
||||
self.MeshObject.ViewObject.setNodeDisplacementByVectors(self.result_object.ElementNumbers, self.result_object.DisplacementVectors)
|
||||
self.update_displacement()
|
||||
QtGui.qApp.restoreOverrideCursor()
|
||||
|
||||
|
@ -656,6 +660,15 @@ class _ResultControlTaskPanel:
|
|||
self.MeshObject = i
|
||||
break
|
||||
|
||||
if self.MeshObject.FemMesh.NodeCount == len(self.result_object.ElementNumbers):
|
||||
self.suitable_results = True
|
||||
else:
|
||||
self.suitable_results = False
|
||||
if not self.MeshObject.FemMesh.VolumeCount:
|
||||
FreeCAD.Console.PrintError('Graphical output for beam or shell FEM Meshes not yet supported!\n')
|
||||
else:
|
||||
FreeCAD.Console.PrintError('Result node numbers are not equal to FEM Mesh NodeCount!\n')
|
||||
|
||||
def accept(self):
|
||||
FreeCADGui.Control.closeDialog()
|
||||
|
||||
|
|
|
@ -5,8 +5,12 @@ import time
|
|||
|
||||
|
||||
class inp_writer:
|
||||
def __init__(self, analysis_obj, mesh_obj, mat_obj, fixed_obj, force_obj,
|
||||
pressure_obj, analysis_type=None, eigenmode_parameters=None, dir_name=None):
|
||||
def __init__(self, analysis_obj, mesh_obj, mat_obj,
|
||||
fixed_obj,
|
||||
force_obj, pressure_obj,
|
||||
beamsection_obj, shellthickness_obj,
|
||||
analysis_type=None, eigenmode_parameters=None,
|
||||
dir_name=None):
|
||||
self.dir_name = dir_name
|
||||
self.analysis = analysis_obj
|
||||
self.mesh_object = mesh_obj
|
||||
|
@ -19,6 +23,8 @@ class inp_writer:
|
|||
self.eigenfrequeny_range_low = eigenmode_parameters[1]
|
||||
self.eigenfrequeny_range_high = eigenmode_parameters[2]
|
||||
self.analysis_type = analysis_type
|
||||
self.beamsection_objects = beamsection_obj
|
||||
self.shellthickness_objects = shellthickness_obj
|
||||
if not dir_name:
|
||||
self.dir_name = FreeCAD.ActiveDocument.TransientDir.replace('\\', '/') + '/FemAnl_' + analysis_obj.Uid[-4:]
|
||||
if not os.path.isdir(self.dir_name):
|
||||
|
@ -37,6 +43,7 @@ class inp_writer:
|
|||
self.write_node_sets_constraints_fixed(inpfile)
|
||||
self.write_node_sets_constraints_force(inpfile)
|
||||
self.write_materials(inpfile)
|
||||
self.write_femelementsets(inpfile)
|
||||
self.write_step_begin(inpfile)
|
||||
self.write_constraints_fixed(inpfile)
|
||||
if self.analysis_type is None or self.analysis_type == "static":
|
||||
|
@ -54,13 +61,113 @@ class inp_writer:
|
|||
f.write('\n***********************************************************\n')
|
||||
f.write('** Element sets for materials and FEM element type (solid, shell, beam)\n')
|
||||
f.write('** written by {} function\n'.format(sys._getframe().f_code.co_name))
|
||||
for m in self.material_objects:
|
||||
if len(self.material_objects) == 1:
|
||||
f.write('*ELSET,ELSET=MaterialSolidElements\n')
|
||||
if len(self.material_objects) > 1:
|
||||
FreeCAD.Console.PrintError('Multiple materials defined, this could result in a broken CalculiX input file!\n')
|
||||
if len(self.shellthickness_objects) > 1 or len(self.beamsection_objects) > 1:
|
||||
if not hasattr(self, 'fem_element_table'):
|
||||
self.fem_element_table = getFemElementTable(self.mesh_object.FemMesh)
|
||||
for mi, m in enumerate(self.material_objects):
|
||||
mat_obj = m['Object']
|
||||
if self.beamsection_objects: # all fem_elements are beamsection_obj --> beam mesh
|
||||
remaining_material_beam_elementset_line = None
|
||||
e_count = 0
|
||||
e_referenced = []
|
||||
e_not_referenced = []
|
||||
for bi, b in enumerate(self.beamsection_objects):
|
||||
beamsection_obj = b['Object']
|
||||
material_elementset_name = mat_obj.Name + beamsection_obj.Name
|
||||
# max identifier length in CalculiX for beam sections see http://forum.freecadweb.org/viewtopic.php?f=18&t=12509
|
||||
if len(material_elementset_name) > 20:
|
||||
material_elementset_name = 'Mat' + str(mi) + 'Beam' + str(bi)
|
||||
b['MaterialElementsetName'] = material_elementset_name # the last material is taken in def write_femelementsets()
|
||||
material_elementset_line = '*ELSET,ELSET=' + material_elementset_name + '\n'
|
||||
if not beamsection_obj.References:
|
||||
if len(self.beamsection_objects) == 1: # all beam elements have the section of this beamsection_obj
|
||||
f.write(material_elementset_line)
|
||||
f.write('Eall\n')
|
||||
else: # remaining beam elements have the beamsection_obj of this beamsection_obj
|
||||
remaining_material_beam_elementset_line = material_elementset_line
|
||||
else: # use reference shapes for the beamsection_obj of this beamsection_obj
|
||||
f.write(material_elementset_line)
|
||||
for ref in beamsection_obj.References:
|
||||
no = []
|
||||
el = []
|
||||
r = ref[0].Shape.getElement(ref[1])
|
||||
if r.ShapeType == 'Edge':
|
||||
# print ' BeamSectionReferenceEdge : ', ref[0].Name, ', ', ref[0].Label, ' --> ', ref[1]
|
||||
no = self.mesh_object.FemMesh.getNodesByEdge(r)
|
||||
el = getFemElementsByNodes(self.fem_element_table, no)
|
||||
else:
|
||||
print ' No Edge, but BeamSection needs Edges as reference shapes!'
|
||||
for e in sorted(el):
|
||||
f.write(str(e) + ',\n')
|
||||
e_count += len(el)
|
||||
e_referenced += el
|
||||
# write remaining beamsection elements
|
||||
if remaining_material_beam_elementset_line:
|
||||
f.write(remaining_material_beam_elementset_line)
|
||||
f.write('**remaining elements\n')
|
||||
for e in self.fem_element_table:
|
||||
if e not in e_referenced:
|
||||
e_not_referenced.append(e)
|
||||
for e in sorted(e_not_referenced):
|
||||
f.write(str(e) + ',\n')
|
||||
e_count += len(e_not_referenced)
|
||||
f.write('\n')
|
||||
elif self.shellthickness_objects: # all fem_elements are shells --> shell mesh
|
||||
remaining_material_shellthicknes_elementset_line = None
|
||||
e_count = 0
|
||||
e_referenced = []
|
||||
e_not_referenced = []
|
||||
for si, s in enumerate(self.shellthickness_objects):
|
||||
shellthickness_obj = s['Object']
|
||||
material_elementset_name = mat_obj.Name + shellthickness_obj.Name
|
||||
if len(material_elementset_name) > 80: # standard max identifier lenght in CalculiX
|
||||
material_elementset_name = 'Mat' + str(mi) + 'Shell' + str(si)
|
||||
s['MaterialElementsetName'] = material_elementset_name # the last material is taken in def write_femelementsets()
|
||||
material_elementset_line = '*ELSET,ELSET=' + material_elementset_name + '\n'
|
||||
if not shellthickness_obj.References:
|
||||
if len(self.shellthickness_objects) == 1: # all shell elements have the thickness of this shellthickness_obj
|
||||
f.write(material_elementset_line)
|
||||
f.write('Eall\n')
|
||||
else: # remaining shell elements have the thickness of this shellthickness_obj
|
||||
remaining_material_shellthicknes_elementset_line = material_elementset_line
|
||||
else: # use reference shapes for the thickness of this shellthickness_obj
|
||||
f.write(material_elementset_line)
|
||||
for ref in shellthickness_obj.References:
|
||||
no = []
|
||||
el = []
|
||||
r = ref[0].Shape.getElement(ref[1])
|
||||
if r.ShapeType == 'Face':
|
||||
# print ' ShellThicknessReferenceFace : ', ref[0].Name, ', ', ref[0].Label, ' --> ', ref[1]
|
||||
no = self.mesh_object.FemMesh.getNodesByFace(r)
|
||||
el = getFemElementsByNodes(self.fem_element_table, no)
|
||||
else:
|
||||
print ' No Face, but ShellThickness needs Faces as reference shapes!'
|
||||
for e in sorted(el):
|
||||
f.write(str(e) + ',\n')
|
||||
e_count += len(el)
|
||||
e_referenced += el
|
||||
# write remaining shellthickness elements
|
||||
if remaining_material_shellthicknes_elementset_line:
|
||||
f.write(remaining_material_shellthicknes_elementset_line)
|
||||
f.write('**remaining elements\n')
|
||||
for e in self.fem_element_table:
|
||||
if e not in e_referenced:
|
||||
e_not_referenced.append(e)
|
||||
for e in sorted(e_not_referenced):
|
||||
f.write(str(e) + ',\n')
|
||||
e_count += len(e_not_referenced)
|
||||
f.write('\n')
|
||||
else: # all fem_elements are solids --> volume mesh
|
||||
material_elementset_name = 'MaterialSolidElements'
|
||||
f.write('*ELSET,ELSET=' + material_elementset_name + '\n')
|
||||
f.write('Eall\n')
|
||||
else:
|
||||
print 'material object count: ', len(self.material_objects)
|
||||
FreeCAD.Console.PrintError('Multiple materials are not yet supported!\n')
|
||||
if hasattr(self, 'fem_element_table'):
|
||||
if e_count != len(self.fem_element_table):
|
||||
print 'ERROR: self.fem_element_table != e_count'
|
||||
print 'Elements written to CalculiX file: ', e_count
|
||||
print 'Elements of the FreeCAD FEM Mesh: ', len(self.fem_element_table)
|
||||
|
||||
def write_node_sets_constraints_fixed(self, f):
|
||||
f.write('\n***********************************************************\n')
|
||||
|
@ -121,7 +228,6 @@ class inp_writer:
|
|||
YM = FreeCAD.Units.Quantity(mat_obj.Material['YoungsModulus'])
|
||||
YM_in_MPa = YM.getValueAs('MPa')
|
||||
PR = float(mat_obj.Material['PoissonRatio'])
|
||||
mat_obj_name = mat_obj.Name
|
||||
mat_name = mat_obj.Material['Name'][:80]
|
||||
# write material properties
|
||||
f.write('*MATERIAL, NAME=' + mat_name + '\n')
|
||||
|
@ -132,12 +238,39 @@ class inp_writer:
|
|||
density_in_tone_per_mm3 = float(density.getValueAs('t/mm^3'))
|
||||
f.write('*DENSITY \n')
|
||||
f.write('{0:.3e}, \n'.format(density_in_tone_per_mm3))
|
||||
# write element properties
|
||||
if len(self.material_objects) == 1:
|
||||
f.write('*SOLID SECTION, ELSET=MaterialSolidElements, MATERIAL=' + mat_name + '\n')
|
||||
else:
|
||||
if mat_obj_name == 'MechanicalMaterial':
|
||||
f.write('*SOLID SECTION, ELSET=MaterialSolidElements, MATERIAL=' + mat_name + '\n')
|
||||
|
||||
def write_femelementsets(self, f):
|
||||
f.write('\n***********************************************************\n')
|
||||
f.write('** Sections\n')
|
||||
f.write('** written by {} function\n'.format(sys._getframe().f_code.co_name))
|
||||
for m in self.material_objects:
|
||||
mat_obj = m['Object']
|
||||
mat_name = mat_obj.Material['Name'][:80]
|
||||
if self.beamsection_objects: # all fem_elements are beams
|
||||
for b in self.beamsection_objects:
|
||||
beamsection_obj = b['Object']
|
||||
material_elementset_name = b['MaterialElementsetName']
|
||||
el_set = 'ELSET=' + material_elementset_name + ', '
|
||||
material = 'MATERIAL=' + mat_name
|
||||
el_prop = '*BEAM SECTION, ' + el_set + material + ', SECTION=RECT\n'
|
||||
sc_prop = str(beamsection_obj.Hight.getValueAs('mm')) + ', ' + str(beamsection_obj.Width.getValueAs('mm')) + '\n'
|
||||
f.write(el_prop)
|
||||
f.write(sc_prop)
|
||||
elif self.shellthickness_objects: # all fem_elements are shells
|
||||
for s in self.shellthickness_objects:
|
||||
shellthickness_obj = s['Object']
|
||||
material_elementset_name = s['MaterialElementsetName']
|
||||
el_set = 'ELSET=' + material_elementset_name + ', '
|
||||
material = 'MATERIAL=' + mat_name
|
||||
el_prop = '*SHELL SECTION, ' + el_set + material + '\n'
|
||||
sc_prop = str(shellthickness_obj.Thickness.getValueAs('mm')) + '\n'
|
||||
f.write(el_prop)
|
||||
f.write(sc_prop)
|
||||
else: # all fem_elements are solids
|
||||
el_set = 'ELSET=' + 'MaterialSolidElements' + ', '
|
||||
material = 'MATERIAL=' + mat_name
|
||||
el_prop = '*SOLID SECTION, ' + el_set + material + '\n'
|
||||
f.write(el_prop)
|
||||
|
||||
def write_step_begin(self, f):
|
||||
f.write('\n***********************************************************\n')
|
||||
|
@ -156,7 +289,12 @@ class inp_writer:
|
|||
f.write('*BOUNDARY\n')
|
||||
f.write(fix_obj_name + ',1\n')
|
||||
f.write(fix_obj_name + ',2\n')
|
||||
f.write(fix_obj_name + ',3\n\n')
|
||||
f.write(fix_obj_name + ',3\n')
|
||||
if self.beamsection_objects or self.shellthickness_objects:
|
||||
f.write(fix_obj_name + ',4\n')
|
||||
f.write(fix_obj_name + ',5\n')
|
||||
f.write(fix_obj_name + ',6\n')
|
||||
f.write('\n')
|
||||
|
||||
def write_constraints_force(self, f):
|
||||
f.write('\n***********************************************************\n')
|
||||
|
|
|
@ -479,6 +479,10 @@ Eall
|
|||
0.300
|
||||
*DENSITY
|
||||
7.900e-09,
|
||||
|
||||
***********************************************************
|
||||
** Sections
|
||||
** written by write_femelementsets function
|
||||
*SOLID SECTION, ELSET=MaterialSolidElements, MATERIAL=Steel
|
||||
|
||||
***********************************************************
|
||||
|
@ -523,8 +527,8 @@ S
|
|||
***********************************************************
|
||||
** CalculiX Input file
|
||||
** written by write_footer function
|
||||
** written by --> FreeCAD 0.16.5561 (Git)
|
||||
** written on --> Thu Sep 17 14:54:31 2015
|
||||
** written by --> FreeCAD 0.16.5604 (Git)
|
||||
** written on --> Mon Sep 21 16:49:37 2015
|
||||
** file name -->
|
||||
** analysis name --> MechanicalAnalysis
|
||||
**
|
||||
|
|
|
@ -479,6 +479,10 @@ Eall
|
|||
0.300
|
||||
*DENSITY
|
||||
7.900e-09,
|
||||
|
||||
***********************************************************
|
||||
** Sections
|
||||
** written by write_femelementsets function
|
||||
*SOLID SECTION, ELSET=MaterialSolidElements, MATERIAL=Steel
|
||||
|
||||
***********************************************************
|
||||
|
@ -589,8 +593,8 @@ S
|
|||
***********************************************************
|
||||
** CalculiX Input file
|
||||
** written by write_footer function
|
||||
** written by --> FreeCAD 0.16.5561 (Git)
|
||||
** written on --> Thu Sep 17 14:52:57 2015
|
||||
** written by --> FreeCAD 0.16.5604 (Git)
|
||||
** written on --> Mon Sep 21 16:46:15 2015
|
||||
** file name -->
|
||||
** analysis name --> MechanicalAnalysis
|
||||
**
|
||||
|
|
|
@ -455,6 +455,10 @@ Eall
|
|||
0.360
|
||||
*DENSITY
|
||||
1.000e-09,
|
||||
|
||||
***********************************************************
|
||||
** Sections
|
||||
** written by write_femelementsets function
|
||||
*SOLID SECTION, ELSET=MaterialSolidElements, MATERIAL=TestMaterial
|
||||
|
||||
***********************************************************
|
||||
|
|
|
@ -455,6 +455,10 @@ Eall
|
|||
0.360
|
||||
*DENSITY
|
||||
1.000e-09,
|
||||
|
||||
***********************************************************
|
||||
** Sections
|
||||
** written by write_femelementsets function
|
||||
*SOLID SECTION, ELSET=MaterialSolidElements, MATERIAL=TestMaterial
|
||||
|
||||
***********************************************************
|
||||
|
|
Loading…
Reference in New Issue
Block a user