FEM: Fenics mesh issue #0003038: xml import fixed
This commit is contained in:
@@ -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 ():
|
||||
|
||||
@@ -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")
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user