diff --git a/src/Mod/Fem/App/CMakeLists.txt b/src/Mod/Fem/App/CMakeLists.txt index aa75d945b4..7a36ecfd14 100644 --- a/src/Mod/Fem/App/CMakeLists.txt +++ b/src/Mod/Fem/App/CMakeLists.txt @@ -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 diff --git a/src/Mod/Fem/CMakeLists.txt b/src/Mod/Fem/CMakeLists.txt index 6d5deaa96e..315e4e9ea2 100755 --- a/src/Mod/Fem/CMakeLists.txt +++ b/src/Mod/Fem/CMakeLists.txt @@ -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 diff --git a/src/Mod/Fem/PyGui/TaskPanelFemMeshGroupXDMFExport.ui b/src/Mod/Fem/PyGui/TaskPanelFemMeshGroupXDMFExport.ui new file mode 100644 index 0000000000..aa55e691db --- /dev/null +++ b/src/Mod/Fem/PyGui/TaskPanelFemMeshGroupXDMFExport.ui @@ -0,0 +1,91 @@ + + + Dialog + + + + 0 + 0 + 570 + 235 + + + + Dialog + + + true + + + + + + Mesh groups detected. Please choose values for the different groups. + + + + + + + + 0 + 0 + + + + Qt::ScrollBarAsNeeded + + + QAbstractScrollArea::AdjustToContentsOnFirstShow + + + false + + + 1 + + + false + + + false + + + true + + + false + + + + + Id + + + + + Label + + + + + Elements + + + + + Not Marked + + + + + Marked + + + + + + + + + diff --git a/src/Mod/Fem/importFenicsMesh.py b/src/Mod/Fem/importFenicsMesh.py index 59b721bf6d..d04fd4f505 100644 --- a/src/Mod/Fem/importFenicsMesh.py +++ b/src/Mod/Fem/importFenicsMesh.py @@ -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): diff --git a/src/Mod/Fem/importToolsFem.py b/src/Mod/Fem/importToolsFem.py index ffab3f1a8a..12c874fe4a 100644 --- a/src/Mod/Fem/importToolsFem.py +++ b/src/Mod/Fem/importToolsFem.py @@ -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 diff --git a/src/Mod/Fem/writeFenicsXDMF.py b/src/Mod/Fem/writeFenicsXDMF.py index aeed1b5cac..05c960ff41 100644 --- a/src/Mod/Fem/writeFenicsXDMF.py +++ b/src/Mod/Fem/writeFenicsXDMF.py @@ -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?