Skip to content

Allow import of geometry sets with non-consecutive numbering #324

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions src/meshpy/core/boundary_condition.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,10 @@ def __init__(self, geometry_set, bc_type=None, **kwargs):
self.geometry_set = geometry_set

@classmethod
def from_dict(cls, geometry_sets, bc_key, bc_dict):
def from_dict(cls, geometry_set, bc_key, bc_dict):
"""This function acts as a factory and creates the correct boundary
condition object from a dictionary parsed from an input file."""

geometry_set_id = int(bc_dict["E"]) - 1
geometry_set = geometry_sets[geometry_set_id]
del bc_dict["E"]

if bc_key in (
Expand Down
38 changes: 22 additions & 16 deletions src/meshpy/four_c/input_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,30 +74,28 @@ def _get_geometry_set_indices_from_section(

geometry_set_dict: _Dict[int, _List[int]] = {}
for line in section_list:
index_geometry_set = int(line.split()[-1])
id_geometry_set = int(line.split()[-1])
index_node = int(line.split()[1]) - 1
if index_geometry_set not in geometry_set_dict:
geometry_set_dict[index_geometry_set] = []
if id_geometry_set not in geometry_set_dict:
geometry_set_dict[id_geometry_set] = []
if append_node_ids:
geometry_set_dict[index_geometry_set].append(index_node)
geometry_set_dict[id_geometry_set].append(index_node)

return geometry_set_dict


def _get_yaml_geometry_sets(
nodes: _List[_Node], geometry_key: _conf.Geometry, section_list: _List
):
) -> _Dict[int, _GeometrySetNodes]:
"""Add sets of points, lines, surfaces or volumes to the object."""

# Create the individual geometry sets. The nodes are still integers at this
# point. They have to be converted to links to the actual nodes later on.
geometry_set_dict = _get_geometry_set_indices_from_section(section_list)
geometry_sets_in_this_section = []
for node_ids in geometry_set_dict.values():
geometry_sets_in_this_section.append(
_GeometrySetNodes(
geometry_key, nodes=[nodes[node_id] for node_id in node_ids]
)
geometry_sets_in_this_section = {}
for geometry_set_id, node_ids in geometry_set_dict.items():
geometry_sets_in_this_section[geometry_set_id] = _GeometrySetNodes(
geometry_key, nodes=[nodes[node_id] for node_id in node_ids]
)
return geometry_sets_in_this_section

Expand Down Expand Up @@ -219,6 +217,10 @@ def sections_to_mesh(self):
"""Convert mesh items, e.g., nodes, elements, element sets, node sets,
boundary conditions, materials, ...

Note: In the current implementation we cannibalize the mesh sections in
the self.sections dictionary. This should be reconsidered and be done
in a better way when this function is generalized.

to "true" MeshPy objects.
"""

Expand Down Expand Up @@ -266,6 +268,7 @@ def _get_section_items(section_name):
mesh.elements.append(_Element.from_legacy_string(element_nodes, item))

# Add geometry sets
geometry_sets_in_sections = {key: None for key in _mpy.geo}
for section_name in self.sections.keys():
if section_name.endswith("TOPOLOGY"):
section_items = _get_section_items(section_name)
Expand All @@ -277,22 +280,25 @@ def _get_section_items(section_name):
break
else:
raise ValueError(f"Could not find the set {section_name}")
geometry_sets_in_this_section = _get_yaml_geometry_sets(
geometry_sets_in_section = _get_yaml_geometry_sets(
mesh.nodes, geometry_key, section_items
)
mesh.geometry_sets[geometry_key] = geometry_sets_in_this_section
geometry_sets_in_sections[geometry_key] = geometry_sets_in_section
mesh.geometry_sets[geometry_key] = list(
geometry_sets_in_section.values()
)

# Add boundary conditions
for (
bc_key,
geometry_key,
), section_name in self.boundary_condition_names.items():
for item in _get_section_items(section_name):
geometry_set_id = item["E"]
geometry_set = geometry_sets_in_sections[geometry_key][geometry_set_id]
mesh.boundary_conditions.append(
(bc_key, geometry_key),
_BoundaryConditionBase.from_dict(
mesh.geometry_sets[geometry_key], bc_key, item
),
_BoundaryConditionBase.from_dict(geometry_set, bc_key, item),
)

self.add(mesh)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
DLINE-NODE TOPOLOGY:
- NODE 1 DLINE 2
- NODE 2 DLINE 2
- NODE 3 DLINE 2
- NODE 4 DLINE 2
- NODE 5 DLINE 2
- NODE 6 DLINE 4
- NODE 7 DLINE 4
- NODE 8 DLINE 4
- NODE 9 DLINE 4
- NODE 10 DLINE 4
- NODE 11 DLINE 7
- NODE 12 DLINE 7
- NODE 13 DLINE 7
- NODE 14 DLINE 7
- NODE 15 DLINE 7
- NODE 16 DLINE 8
- NODE 17 DLINE 8
- NODE 18 DLINE 8
- NODE 19 DLINE 8
- NODE 20 DLINE 8
- NODE 21 DLINE 9
- NODE 22 DLINE 9
- NODE 23 DLINE 9
- NODE 24 DLINE 9
- NODE 25 DLINE 9
- NODE 26 DLINE 10
- NODE 27 DLINE 10
- NODE 28 DLINE 10
- NODE 29 DLINE 10
- NODE 30 DLINE 10
DNODE-NODE TOPOLOGY:
- NODE 5 DNODE 2
- NODE 1 DNODE 4
- NODE 10 DNODE 7
- NODE 6 DNODE 11
- NODE 15 DNODE 13
- NODE 11 DNODE 17
- NODE 20 DNODE 18
- NODE 16 DNODE 19
- NODE 25 DNODE 20
- NODE 21 DNODE 21
- NODE 30 DNODE 22
- NODE 26 DNODE 23
MATERIALS:
- MAT: 1
MAT_BeamReissnerElastHyper:
CROSSAREA: 3.141592653589793
DENS: 0.0
MOMIN2: 0.7853981633974483
MOMIN3: 0.7853981633974483
MOMINPOL: 1.5707963267948966
POISSONRATIO: 0.0
SHEARCORR: 1
YOUNG: -1.0
NODE COORDS:
- NODE 1 COORD 0 0 0
- NODE 2 COORD 0 0 1
- NODE 3 COORD 0 0 2
- NODE 4 COORD 0 0 3
- NODE 5 COORD 0 0 4
- NODE 6 COORD 1 0 0
- NODE 7 COORD 1 0 1
- NODE 8 COORD 1 0 2
- NODE 9 COORD 1 0 3
- NODE 10 COORD 1 0 4
- NODE 11 COORD 2 0 0
- NODE 12 COORD 2 0 1
- NODE 13 COORD 2 0 2
- NODE 14 COORD 2 0 3
- NODE 15 COORD 2 0 4
- NODE 16 COORD 3 0 0
- NODE 17 COORD 3 0 1
- NODE 18 COORD 3 0 2
- NODE 19 COORD 3 0 3
- NODE 20 COORD 3 0 4
- NODE 21 COORD 4 0 0
- NODE 22 COORD 4 0 1
- NODE 23 COORD 4 0 2
- NODE 24 COORD 4 0 3
- NODE 25 COORD 4 0 4
- NODE 26 COORD 5 0 0
- NODE 27 COORD 5 0 1
- NODE 28 COORD 5 0 2
- NODE 29 COORD 5 0 3
- NODE 30 COORD 5 0 4
STRUCTURE ELEMENTS:
- 1 BEAM3R HERM2LINE3 16 18 17 MAT 1 TRIADS 0 -1.57079632679 0 0 -1.57079632679 0 0 -1.57079632679 0
- 2 BEAM3R HERM2LINE3 18 20 19 MAT 1 TRIADS 0 -1.57079632679 0 0 -1.57079632679 0 0 -1.57079632679 0
- 3 BEAM3R HERM2LINE3 21 23 22 MAT 1 TRIADS 0 -1.57079632679 0 0 -1.57079632679 0 0 -1.57079632679 0
- 4 BEAM3R HERM2LINE3 23 25 24 MAT 1 TRIADS 0 -1.57079632679 0 0 -1.57079632679 0 0 -1.57079632679 0
- 5 BEAM3R HERM2LINE3 26 28 27 MAT 1 TRIADS 0 -1.57079632679 0 0 -1.57079632679 0 0 -1.57079632679 0
- 6 BEAM3R HERM2LINE3 28 30 29 MAT 1 TRIADS 0 -1.57079632679 0 0 -1.57079632679 0 0 -1.57079632679 0
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
DLINE-NODE TOPOLOGY:
- NODE 1 DLINE 1
- NODE 2 DLINE 1
- NODE 3 DLINE 1
- NODE 4 DLINE 1
- NODE 5 DLINE 1
- NODE 6 DLINE 2
- NODE 7 DLINE 2
- NODE 8 DLINE 2
- NODE 9 DLINE 2
- NODE 10 DLINE 2
- NODE 11 DLINE 3
- NODE 12 DLINE 3
- NODE 13 DLINE 3
- NODE 14 DLINE 3
- NODE 15 DLINE 3
- NODE 16 DLINE 4
- NODE 17 DLINE 4
- NODE 18 DLINE 4
- NODE 19 DLINE 4
- NODE 20 DLINE 4
- NODE 21 DLINE 5
- NODE 22 DLINE 5
- NODE 23 DLINE 5
- NODE 24 DLINE 5
- NODE 25 DLINE 5
- NODE 26 DLINE 6
- NODE 27 DLINE 6
- NODE 28 DLINE 6
- NODE 29 DLINE 6
- NODE 30 DLINE 6
DNODE-NODE TOPOLOGY:
- NODE 5 DNODE 1
- NODE 1 DNODE 2
- NODE 10 DNODE 3
- NODE 6 DNODE 4
- NODE 15 DNODE 5
- NODE 11 DNODE 6
- NODE 20 DNODE 7
- NODE 16 DNODE 8
- NODE 25 DNODE 9
- NODE 21 DNODE 10
- NODE 30 DNODE 11
- NODE 26 DNODE 12
MATERIALS:
- MAT: 1
MAT_BeamReissnerElastHyper:
CROSSAREA: 3.141592653589793
DENS: 0.0
MOMIN2: 0.7853981633974483
MOMIN3: 0.7853981633974483
MOMINPOL: 1.5707963267948966
POISSONRATIO: 0.0
SHEARCORR: 1
YOUNG: -1.0
NODE COORDS:
- NODE 1 COORD 0 0 0
- NODE 2 COORD 0 0 1
- NODE 3 COORD 0 0 2
- NODE 4 COORD 0 0 3
- NODE 5 COORD 0 0 4
- NODE 6 COORD 1 0 0
- NODE 7 COORD 1 0 1
- NODE 8 COORD 1 0 2
- NODE 9 COORD 1 0 3
- NODE 10 COORD 1 0 4
- NODE 11 COORD 2 0 0
- NODE 12 COORD 2 0 1
- NODE 13 COORD 2 0 2
- NODE 14 COORD 2 0 3
- NODE 15 COORD 2 0 4
- NODE 16 COORD 3 0 0
- NODE 17 COORD 3 0 1
- NODE 18 COORD 3 0 2
- NODE 19 COORD 3 0 3
- NODE 20 COORD 3 0 4
- NODE 21 COORD 4 0 0
- NODE 22 COORD 4 0 1
- NODE 23 COORD 4 0 2
- NODE 24 COORD 4 0 3
- NODE 25 COORD 4 0 4
- NODE 26 COORD 5 0 0
- NODE 27 COORD 5 0 1
- NODE 28 COORD 5 0 2
- NODE 29 COORD 5 0 3
- NODE 30 COORD 5 0 4
STRUCTURE ELEMENTS:
- 1 BEAM3R HERM2LINE3 16 18 17 MAT 1 TRIADS 0 -1.57079632679 0 0 -1.57079632679 0 0 -1.57079632679 0
- 2 BEAM3R HERM2LINE3 18 20 19 MAT 1 TRIADS 0 -1.57079632679 0 0 -1.57079632679 0 0 -1.57079632679 0
- 3 BEAM3R HERM2LINE3 21 23 22 MAT 1 TRIADS 0 -1.57079632679 0 0 -1.57079632679 0 0 -1.57079632679 0
- 4 BEAM3R HERM2LINE3 23 25 24 MAT 1 TRIADS 0 -1.57079632679 0 0 -1.57079632679 0 0 -1.57079632679 0
- 5 BEAM3R HERM2LINE3 26 28 27 MAT 1 TRIADS 0 -1.57079632679 0 0 -1.57079632679 0 0 -1.57079632679 0
- 6 BEAM3R HERM2LINE3 28 30 29 MAT 1 TRIADS 0 -1.57079632679 0 0 -1.57079632679 0 0 -1.57079632679 0
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
DLINE-NODE TOPOLOGY:
- NODE 1 DLINE 2
- NODE 2 DLINE 2
- NODE 3 DLINE 2
- NODE 4 DLINE 2
- NODE 5 DLINE 2
- NODE 6 DLINE 4
- NODE 7 DLINE 4
- NODE 8 DLINE 4
- NODE 9 DLINE 4
- NODE 10 DLINE 4
- NODE 11 DLINE 7
- NODE 12 DLINE 7
- NODE 13 DLINE 7
- NODE 14 DLINE 7
- NODE 15 DLINE 7
DNODE-NODE TOPOLOGY:
- NODE 5 DNODE 2
- NODE 1 DNODE 4
- NODE 10 DNODE 7
- NODE 6 DNODE 11
- NODE 15 DNODE 13
- NODE 11 DNODE 17
NODE COORDS:
- NODE 1 COORD 0 0 0
- NODE 2 COORD 0 0 1
- NODE 3 COORD 0 0 2
- NODE 4 COORD 0 0 3
- NODE 5 COORD 0 0 4
- NODE 6 COORD 1 0 0
- NODE 7 COORD 1 0 1
- NODE 8 COORD 1 0 2
- NODE 9 COORD 1 0 3
- NODE 10 COORD 1 0 4
- NODE 11 COORD 2 0 0
- NODE 12 COORD 2 0 1
- NODE 13 COORD 2 0 2
- NODE 14 COORD 2 0 3
- NODE 15 COORD 2 0 4
32 changes: 32 additions & 0 deletions tests/test_four_c.py
Original file line number Diff line number Diff line change
Expand Up @@ -709,3 +709,35 @@ def test_four_c_beam_to_solid(
mpy.bc.beam_to_solid_surface_contact,
)
assert_results_equal(get_corresponding_reference_file_path(), input_file)


@pytest.mark.parametrize(
("full_import", "additional_identifier"),
[(False, "dict_import"), (True, "full_import")],
)
def test_four_c_import_non_consecutive_geometry_sets(
full_import,
additional_identifier,
get_corresponding_reference_file_path,
assert_results_equal,
):
"""Test that we can import non-consecutively numbered geometry sets."""

mpy.import_mesh_full = full_import
input_file = InputFile(
yaml_file=get_corresponding_reference_file_path(additional_identifier="input")
)

material = MaterialReissner()
for i in range(3):
beam_set = create_beam_mesh_line(
input_file, Beam3rHerm2Line3, material, [i + 3, 0, 0], [i + 3, 0, 4], n_el=2
)
input_file.add(beam_set)

assert_results_equal(
get_corresponding_reference_file_path(
additional_identifier=additional_identifier
),
input_file,
)