Skip to content

Commit 7be2e4f

Browse files
Merge pull request #101 from isteinbrecher/cmd_return_objects
Add functionality to get python objects created during string cmd
2 parents 61fd348 + ac9c20c commit 7be2e4f

File tree

2 files changed

+136
-1
lines changed

2 files changed

+136
-1
lines changed

src/cubitpy/cubitpy.py

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
import netCDF4
3030
from fourcipp.fourc_input import FourCInput
3131

32-
from cubitpy.conf import cupy
32+
from cubitpy.conf import GeometryType, cupy
3333
from cubitpy.cubit_group import CubitGroup
3434
from cubitpy.cubit_to_fourc_input import (
3535
add_exodus_geometry_section,
@@ -421,6 +421,87 @@ def reset(self):
421421
self.cubit.reset()
422422
self._default_cubit_variables()
423423

424+
def cmd_return(self, cmd: str, geometry_type: GeometryType, **kwargs):
425+
"""Run a cubit command and return the created geometry object.
426+
427+
Args:
428+
cmd: The cubit command to run.
429+
geometry_type: The geometry type that should be checked for a new geometry.
430+
kwargs: Will be passed on to `cmd_return_dict`.
431+
432+
Returns:
433+
If a single geometry object of the given type is created, this object
434+
is returned. This function expects that a single geometry item of the given
435+
type is created, otherwise an error will be raised. For use cases, where one
436+
expects a variable amount of created items or wants to check multiple
437+
different geometry types, please refer to `cmd_return_dict`.
438+
"""
439+
geometry_dict = self.cmd_return_dict(cmd, [geometry_type], **kwargs)
440+
if len(geometry_dict[geometry_type]) == 1:
441+
return geometry_dict[geometry_type][0]
442+
else:
443+
raise ValueError(
444+
f"Expected a single created item of type {geometry_type}, but got {geometry_dict[geometry_type]}"
445+
)
446+
447+
def cmd_return_dict(
448+
self,
449+
cmd: str,
450+
geometry_types: list[GeometryType],
451+
*,
452+
filter_sheet_bodies: bool = True,
453+
):
454+
"""Run a cubit command and return created geometry objects.
455+
456+
Args:
457+
cmd: The cubit command to run.
458+
geometry_types: The geometry types that should be checked for new geometries.
459+
filter_sheet_bodies: If volumes that are sheet bodies should be ignored.
460+
Defaults to true.
461+
462+
Returns:
463+
A dictionary of the created geometry objects. The dictionary keys are the
464+
geometry types, the values are lists containing the respective objects.
465+
"""
466+
467+
# Store the already existing ids for all requested geometry types.
468+
geometry_ids_before = {
469+
geometry: set(self.get_entities(geometry.get_cubit_string()))
470+
for geometry in geometry_types
471+
}
472+
473+
# For CoreForm, we need to check that the volumes are not sheet bodies
474+
if cupy.is_coreform() and filter_sheet_bodies:
475+
if cupy.geometry.volume in geometry_ids_before:
476+
volume_ids_before = geometry_ids_before[cupy.geometry.volume]
477+
volume_ids_before_no_sheet_bodies = {
478+
id for id in volume_ids_before if not self.is_sheet_body(id)
479+
}
480+
geometry_ids_before[cupy.geometry.volume] = (
481+
volume_ids_before_no_sheet_bodies
482+
)
483+
484+
# Run the command.
485+
self.cmd(cmd)
486+
487+
# Get the objects that were created by the command.
488+
create_objects = {}
489+
for geometry, ids_before in geometry_ids_before.items():
490+
ids_after = set(self.get_entities(geometry.get_cubit_string()))
491+
ids_new = ids_after - ids_before
492+
493+
if (
494+
cupy.is_coreform()
495+
and filter_sheet_bodies
496+
and geometry == cupy.geometry.volume
497+
):
498+
ids_new = {id for id in ids_new if not self.is_sheet_body(id)}
499+
500+
geometry_objects = self.get_items(geometry, item_ids=ids_new)
501+
create_objects[geometry] = geometry_objects
502+
503+
return create_objects
504+
424505
def display_in_cubit(self, labels=[], delay=0.5, testing=False):
425506
"""Save the state to a cubit file and open cubit with that file.
426507
Additionally labels can be displayed in cubit to simplify the mesh

tests/test_cubitpy.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2018,3 +2018,57 @@ def test_yaml_with_exo_export_fsi():
20182018

20192019
# Compare the input file created for 4C.
20202020
compare_yaml(cubit, mesh_in_exo=True)
2021+
2022+
2023+
def test_cmd_return():
2024+
"""Test the cmd_return function of CubitPy."""
2025+
2026+
cubit = CubitPy()
2027+
2028+
center = cubit.cmd_return("create vertex 0 0 0", cupy.geometry.vertex)
2029+
assert center.get_geometry_type() == cupy.geometry.vertex
2030+
assert center.id() == 1
2031+
2032+
arc_1 = cubit.cmd_return(
2033+
f"create curve arc center vertex {center.id()} radius 1 full",
2034+
cupy.geometry.curve,
2035+
)
2036+
assert arc_1.get_geometry_type() == cupy.geometry.curve
2037+
assert arc_1.id() == 1
2038+
2039+
center = cubit.cmd_return("create vertex 0.1 0 0", cupy.geometry.vertex)
2040+
assert center.get_geometry_type() == cupy.geometry.vertex
2041+
assert center.id() == 3
2042+
2043+
arc_2 = cubit.cmd_return(
2044+
f"create curve arc center vertex {center.id()} radius 2 full",
2045+
cupy.geometry.curve,
2046+
)
2047+
assert arc_2.get_geometry_type() == cupy.geometry.curve
2048+
assert arc_2.id() == 2
2049+
2050+
# We check the volume here as well, as in CoreForm a sheet body is created here that Cubit
2051+
# internally handles as a volume. But, we don't want this volume returned here.
2052+
create_surface_geometry = cubit.cmd_return_dict(
2053+
f"create surface curve {arc_1.id()} {arc_2.id()}",
2054+
[cupy.geometry.surface, cupy.geometry.volume],
2055+
)
2056+
for surface in create_surface_geometry[cupy.geometry.surface]:
2057+
assert surface.get_geometry_type() == cupy.geometry.surface
2058+
assert [item.id() for item in create_surface_geometry[cupy.geometry.surface]] == [1]
2059+
assert len(create_surface_geometry[cupy.geometry.volume]) == 0
2060+
2061+
sweep_geometry = cubit.cmd_return_dict(
2062+
f"sweep surface {surface.id()} perpendicular distance 2",
2063+
[
2064+
cupy.geometry.vertex,
2065+
cupy.geometry.curve,
2066+
cupy.geometry.surface,
2067+
cupy.geometry.volume,
2068+
],
2069+
)
2070+
assert len(sweep_geometry) == 4
2071+
assert [item.id() for item in sweep_geometry[cupy.geometry.vertex]] == [5, 6]
2072+
assert [item.id() for item in sweep_geometry[cupy.geometry.curve]] == [3, 4, 5, 6]
2073+
assert [item.id() for item in sweep_geometry[cupy.geometry.surface]] == [2, 3, 4]
2074+
assert [item.id() for item in sweep_geometry[cupy.geometry.volume]] == [1]

0 commit comments

Comments
 (0)