FEM: Fenics mesh issue #0003038: xml import fixed

This commit is contained in:
joha2
2018-03-31 18:03:38 +02:00
committed by Bernd Hahnebach
parent d0651ba51f
commit a4316faa8e
3 changed files with 41 additions and 7 deletions

View File

@@ -150,6 +150,9 @@ def export(objectslist, fileString):
if fileString != "":
fileName, fileExtension = os.path.splitext(fileString)
if fileExtension.lower() == '.xml':
FreeCAD.Console.PrintWarning("XML is not designed to save higher order elements.\n")
FreeCAD.Console.PrintWarning("Reducing order for second order mesh.\n")
FreeCAD.Console.PrintWarning("Tri6 -> Tri3, Tet10 -> Tet4, etc.\n")
writeFenicsXML.write_fenics_mesh_xml(obj, fileString)
elif fileExtension.lower() == '.xdmf':
if importToolsFem.get_FemMeshObjectMeshGroups(obj) is not ():

View File

@@ -61,6 +61,8 @@ def read_fenics_mesh_xml(xmlfilename):
print("Mesh dimension: %d" % (dim,))
print("Mesh cell type: %s" % (cell_type,))
# every cell type contains a dict with key=dimension and value=number
cells_parts_dim = {'point': {0: 1},
'interval': {0: 2, 1: 1},
'triangle': {0: 3, 1: 3, 2: 1},
@@ -178,6 +180,10 @@ def read_fenics_mesh_xml(xmlfilename):
'hexahedron': ['quadrilateral', 'interval'],
'quadrilateral': ['interval']}
# generate cell list from file
# read vertex list from cells
# generate lower dimensional objects in mesh from cell
for (cell_index, cell) in list(cell_dict.items()):
cell_lower_dims = lower_dims_dict[cell_type]
element_counter[cell_type] += 1
@@ -189,18 +195,25 @@ def read_fenics_mesh_xml(xmlfilename):
vertextuple,
element_counter[ld])
length_counter = len(nodes)
length_counter = len(nodes) # maintain distinct counting values
# print("nodes")
# print("len & len counter", length_counter)
for (key, val_dict) in list(element_dict.items()):
# to ensure distinct indices for FreeCAD
# print('key: ', key)
for (vkey, it) in list(val_dict.items()):
val_dict[vkey] = it + length_counter
length_counter += len(val_dict)
val_dict[vkey] = it + length_counter # maintain distinct element numbers
len_val_dict = len(val_dict)
if len_val_dict > 0:
length_counter += len_val_dict + 1 # only if preceeding list is not empty
# print('len: ', len_val_dict)
# print('lencounter: ', length_counter)
# inverse of the dict (dict[key] = val -> dict[val] = key)
element_dict[key] = invertdict(val_dict)
correct_volume_det(element_dict)
correct_volume_det(element_dict) # corrects negative determinants
return element_dict
return element_dict # returns complete element dictionary
nodes = {}
element_dict = {}
@@ -219,6 +232,11 @@ def read_fenics_mesh_xml(xmlfilename):
print("Mesh found")
(nodes, cells_dict, cell_type, dim) = read_mesh_block(find_mesh)
element_dict = generate_lower_dimensional_structures(nodes, cells_dict, cell_type, dim)
print("Show min max element dict")
for (elm, numbers) in list(element_dict.items()):
lst = sorted(list(numbers.items()), key=lambda x: x[0])
if lst != []:
print(elm, " min: ", lst[0], " max: ", lst[-1])
else:
print("No mesh found")

View File

@@ -40,7 +40,9 @@ def write_fenics_mesh_xml(fem_mesh_obj, outputfile):
vertices to be exported. (For second order elements, we have to delete the mid element nodes.)
"""
# TODO: check for second order elements (what to do? deny export or reduce element order?)
# TODO: check for second order elements
# (reduce element order would be ok - all elements have at least the first
# necessary nodes)
FreeCAD_to_Fenics_dict = {
"Triangle": "triangle",
@@ -53,6 +55,15 @@ def write_fenics_mesh_xml(fem_mesh_obj, outputfile):
"Polygon": "unknown", "Polyhedron": "unknown",
"Prism": "unknown", "Pyramid": "unknown",
}
XML_Number_of_Nodes_dict = {
"point": 1,
"interval": 2,
"triangle": 3,
"quadrilateral": 4,
"tetrahedron": 4,
"hexahedron": 8
}
print("Converting " + fem_mesh_obj.Label + " to fenics XML File")
print("Dimension of mesh: %d" % (get_FemMeshObjectDimension(fem_mesh_obj),))
@@ -62,6 +73,7 @@ def write_fenics_mesh_xml(fem_mesh_obj, outputfile):
celltype_in_mesh = get_MaxDimElementFromList(elements_in_mesh)
(num_cells, cellname_fc, dim_cell) = celltype_in_mesh
cellname_fenics = FreeCAD_to_Fenics_dict[cellname_fc]
num_verts_cell = XML_Number_of_Nodes_dict[cellname_fenics]
print("Celltype in mesh -> %s and its Fenics name: %s" % (str(celltype_in_mesh), cellname_fenics))
root = ET.Element("dolfin", dolfin="http://fenicsproject.org")
@@ -90,7 +102,8 @@ def write_fenics_mesh_xml(fem_mesh_obj, outputfile):
cell_args = {}
for (vi, ni) in enumerate(nodeindices):
cell_args["v" + str(vi)] = str(ni - 1)
if vi < num_verts_cell: # XML only supports first order meshs
cell_args["v" + str(vi)] = str(ni - 1)
# generate as many v entries in dict as nodes are listed in cell (works only for first order elements)
ET.SubElement(cells, cellname_fenics, index=str(fen_ind), **cell_args)