FEM: Fenics mesh: added mesh group task panel for xdmf export, flake8, improves issue #3038

This commit is contained in:
joha2
2017-07-28 00:29:46 +02:00
committed by wmayer
parent 841d7c7c88
commit 69cd7ba949
6 changed files with 184 additions and 17 deletions

View File

@@ -173,6 +173,7 @@ SET(FemGuiScripts_SRCS
PyGui/TaskPanelFemMeshBoundaryLayer.ui
PyGui/TaskPanelFemMeshGmsh.ui
PyGui/TaskPanelFemMeshGroup.ui
PyGui/TaskPanelFemMeshGroupXDMFExport.ui
PyGui/TaskPanelFemMeshRegion.ui
PyGui/TaskPanelFemResultShow.ui
PyGui/TaskPanelFemSolverCalculix.ui

View File

@@ -126,6 +126,7 @@ INSTALL(
PyGui/TaskPanelFemMeshBoundaryLayer.ui
PyGui/TaskPanelFemMeshGmsh.ui
PyGui/TaskPanelFemMeshGroup.ui
PyGui/TaskPanelFemMeshGroupXDMFExport.ui
PyGui/TaskPanelFemMeshRegion.ui
PyGui/TaskPanelFemResultShow.ui
PyGui/TaskPanelFemSolverCalculix.ui

View File

@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>570</width>
<height>235</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<property name="modal">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Mesh groups detected. Please choose values for the different groups.</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QTableWidget" name="tableGroups">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustToContentsOnFirstShow</enum>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
<property name="rowCount">
<number>1</number>
</property>
<attribute name="horizontalHeaderCascadingSectionResizes">
<bool>false</bool>
</attribute>
<attribute name="horizontalHeaderShowSortIndicator" stdset="0">
<bool>false</bool>
</attribute>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
<row/>
<column>
<property name="text">
<string>Id</string>
</property>
</column>
<column>
<property name="text">
<string>Label</string>
</property>
</column>
<column>
<property name="text">
<string>Elements</string>
</property>
</column>
<column>
<property name="text">
<string>Not Marked</string>
</property>
</column>
<column>
<property name="text">
<string>Marked</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -29,7 +29,10 @@ __url__ = "http://www.freecadweb.org"
# \ingroup FEM
# \brief FreeCAD Fenics Mesh reader and writer for FEM workbench
from PySide import QtGui, QtCore
import FreeCAD
import FreeCADGui
import importToolsFem
import os
@@ -48,6 +51,64 @@ elif open.__module__ == 'io':
pyopen = open
class WriteXDMFTaskPanel:
"""
This task panel is used to write mesh groups with user defined values.
It will called if there are mesh groups detected. Else it will be bypassed.
"""
def __init__(self, fem_mesh_obj, fileString):
self.form = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Fem/PyGui/TaskPanelFemMeshGroupXDMFExport.ui")
self.result_dict = {}
self.fem_mesh_obj = fem_mesh_obj
self.fileString = fileString
self.convert_fem_mesh_obj_to_table()
def convert_fem_mesh_obj_to_table(self):
def ro(item):
item.setFlags(~QtCore.Qt.ItemIsEditable & ~QtCore.Qt.ItemIsEnabled)
return item
gmshgroups = importToolsFem.get_FemMeshObjectMeshGroups(self.fem_mesh_obj)
fem_mesh = self.fem_mesh_obj.FemMesh
self.form.tableGroups.setRowCount(0)
self.form.tableGroups.setRowCount(len(gmshgroups))
for (ind, gind) in enumerate(gmshgroups):
# group number
self.form.tableGroups.setItem(ind, 0, ro(QtGui.QTableWidgetItem(str(gind))))
# group name
self.form.tableGroups.setItem(ind, 1, ro(QtGui.QTableWidgetItem(fem_mesh.getGroupName(gind))))
# group elements
self.form.tableGroups.setItem(ind, 2, ro(QtGui.QTableWidgetItem(fem_mesh.getGroupElementType(gind))))
# default value for not marked elements
self.form.tableGroups.setItem(ind, 3, QtGui.QTableWidgetItem(str(-1)))
# default value for marked elements
self.form.tableGroups.setItem(ind, 4, QtGui.QTableWidgetItem(str(gind)))
def convert_table_to_group_dict(self):
group_values_dict = {}
num_rows = self.form.tableGroups.rowCount()
for r in range(num_rows):
g = int(self.form.tableGroups.item(r, 0).text())
default_value = int(self.form.tableGroups.item(r, 3).text())
marked_value = int(self.form.tableGroups.item(r, 4).text())
group_values_dict[g] = (marked_value, default_value)
return group_values_dict
def accept(self):
group_values_dict = self.convert_table_to_group_dict()
writeFenicsXDMF.write_fenics_mesh_xdmf(self.fem_mesh_obj, self.fileString, group_values_dict=group_values_dict)
FreeCADGui.Control.closeDialog()
def open(filename):
"called when freecad opens a file"
docname = os.path.splitext(os.path.basename(filename))[0]
@@ -79,9 +140,12 @@ def export(objectslist, fileString):
if fileExtension.lower() == '.xml':
writeFenicsXML.write_fenics_mesh_xml(obj, fileString)
elif fileExtension.lower() == '.xdmf':
writeFenicsXDMF.write_fenics_mesh_xdmf(obj, fileString)
# write_fenics_mesh(obj, filename)
if importToolsFem.get_FemMeshObjectMeshGroups(obj) is not ():
# if there are groups found, make task panel available
panel = WriteXDMFTaskPanel(obj, fileString)
FreeCADGui.Control.showDialog(panel)
else:
writeFenicsXDMF.write_fenics_mesh_xdmf(obj, fileString)
def import_fenics_mesh(filename, analysis=None):

View File

@@ -33,6 +33,20 @@ from math import pow, sqrt
import numpy as np
def get_FemMeshObjectMeshGroups(fem_mesh_obj):
"""
Get mesh groups from mesh. This also throws no exception if there
is no Groups property at all (e.g. Netgen meshes).
"""
fem_mesh = fem_mesh_obj.FemMesh
try:
gmshgroups = fem_mesh.Groups
except:
gmshgroups = ()
return gmshgroups
def get_FemMeshObjectOrder(fem_mesh_obj):
"""
Gets element order. Element order counting based on number of nodes on

View File

@@ -21,7 +21,11 @@
# ***************************************************************************
from __future__ import print_function
from importToolsFem import get_FemMeshObjectDimension, get_FemMeshObjectElementTypes, get_MaxDimElementFromList, get_FemMeshObjectOrder
from importToolsFem import get_FemMeshObjectDimension,\
get_FemMeshObjectElementTypes,\
get_MaxDimElementFromList,\
get_FemMeshObjectOrder,\
get_FemMeshObjectMeshGroups
from xml.etree import ElementTree as ET # parsing xml files and exporting
import numpy as np
@@ -54,10 +58,6 @@ FreeCAD_to_Fenics_XDMF_dict = {
("Tetra", 2): ("tet_10", 10)
}
# TODO: export mesh functions (to be defined, cell functions, vertex functions, facet functions)
# TODO: integrate cell function
# we need numpy functions to later access and process large data sets in a fast manner
# also the hd5 support better works together with numpy
@@ -210,7 +210,7 @@ Example: mesh with two topologies and one mesh function for the facet one
"""
def write_fenics_mesh_xdmf(fem_mesh_obj, outputfile, encoding=ENCODING_ASCII):
def write_fenics_mesh_xdmf(fem_mesh_obj, outputfile, group_values_dict={}, encoding=ENCODING_ASCII):
"""
For the export of xdmf.
"""
@@ -254,12 +254,10 @@ def write_fenics_mesh_xdmf(fem_mesh_obj, outputfile, encoding=ENCODING_ASCII):
#####################################
fem_mesh = fem_mesh_obj.FemMesh
try:
gmshgroups = fem_mesh.Groups
except:
gmshgroups = ()
gmshgroups = get_FemMeshObjectMeshGroups(fem_mesh_obj)
print('found mesh groups')
if gmshgroups is not ():
print('found mesh groups')
for g in gmshgroups:
mesh_function_type = fem_mesh.getGroupElementType(g)
@@ -282,9 +280,7 @@ def write_fenics_mesh_xdmf(fem_mesh_obj, outputfile, encoding=ENCODING_ASCII):
mesh_function_attribute = ET.SubElement(mesh_function_grid, "Attribute")
elem_dict = {}
elem_mark_default = -1
elem_mark_group = g
elem_mark_overlap = g/2
(elem_mark_group, elem_mark_default) = group_values_dict.get(g, (g, -1))
# TODO: is it better to save all groups each at once or collect all codim equal
# groups to put them into one function?