cad-to-dagmc 0.9.9__tar.gz → 0.10.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/.github/workflows/ci_with_conda_install.yml +2 -0
  2. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/.github/workflows/ci_with_pip_install.yml +1 -0
  3. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/PKG-INFO +3 -2
  4. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/examples/surface_and_unstructured_mesh/unstructured_mesh_with_conformal_surface_mesh.py +6 -2
  5. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/examples/surface_mesh/cadquery_assembly_with_materials.py +9 -4
  6. cad_to_dagmc-0.10.0/examples/surface_mesh/cadquery_assembly_with_names.py +18 -0
  7. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/examples/surface_mesh/cadquery_assembly_with_scaled_geometry.py +3 -1
  8. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/examples/surface_mesh/cadquery_compound.py +9 -2
  9. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/examples/surface_mesh/multiple_cadquery_objects.py +3 -1
  10. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/examples/surface_mesh/single_stp_file.py +6 -1
  11. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/examples/unstrucutred_volume_mesh/curved_cadquery_object_to_dagmc_volume_mesh.py +3 -1
  12. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/examples/unstrucutred_volume_mesh/simulate_unstrucutred_volume_mesh_with_openmc.py +3 -1
  13. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/pyproject.toml +2 -1
  14. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/src/_version.py +3 -3
  15. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/src/cad_to_dagmc/__init__.py +0 -1
  16. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/src/cad_to_dagmc/core.py +83 -30
  17. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/src/cad_to_dagmc.egg-info/PKG-INFO +3 -2
  18. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/src/cad_to_dagmc.egg-info/SOURCES.txt +3 -2
  19. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/src/cad_to_dagmc.egg-info/requires.txt +2 -1
  20. cad_to_dagmc-0.10.0/tests/test_assembly_with_materials.py +91 -0
  21. cad_to_dagmc-0.10.0/tests/test_assembly_with_names.py +106 -0
  22. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/tests/test_file_creation.py +27 -7
  23. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/tests/test_h5m_in_transport.py +17 -5
  24. cad_to_dagmc-0.10.0/tests/test_invalid_material_tags_string.py +16 -0
  25. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/tests/test_kwarg_args.py +9 -4
  26. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/tests/test_python_api.py +5 -1
  27. cad_to_dagmc-0.9.9/.github/workflows/black.yml +0 -32
  28. cad_to_dagmc-0.9.9/src/cad_to_dagmc/direct_mesh_plugin.py +0 -510
  29. cad_to_dagmc-0.9.9/tests/test_assembly_with_materials.py +0 -52
  30. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/.github/workflows/ci_with_benchmarks.yml +0 -0
  31. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/.github/workflows/python-publish.yml +0 -0
  32. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/.gitignore +0 -0
  33. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/CITATION.cff +0 -0
  34. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/LICENSE +0 -0
  35. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/README.md +0 -0
  36. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/examples/surface_mesh/cadquery_assembly.py +0 -0
  37. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/examples/surface_mesh/cadquery_object_and_stp_file.py +0 -0
  38. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/examples/surface_mesh/cadquery_text.py +0 -0
  39. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/examples/surface_mesh/curved_cadquery_object_to_dagmc_surface_mesh.py +0 -0
  40. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/examples/surface_mesh/different_resolution_meshes.py +0 -0
  41. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/examples/surface_mesh/from_gmsh_mesh_file.py +0 -0
  42. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/examples/surface_mesh/from_gmsh_mesh_file_with_tags.py +0 -0
  43. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/examples/surface_mesh/from_gmsh_object_with_tag.py +0 -0
  44. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/examples/surface_mesh/multiple_stp_files.py +0 -0
  45. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/examples/surface_mesh/single_cadquery_object.py +0 -0
  46. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/examples/surface_mesh/single_stp_file_multiple_volumes.py +0 -0
  47. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/examples/surface_mesh/tagged_mesh.msh +0 -0
  48. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/examples/unstrucutred_volume_mesh/different_resolution_meshes.py +0 -0
  49. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/setup.cfg +0 -0
  50. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/src/cad_to_dagmc.egg-info/dependency_links.txt +0 -0
  51. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/src/cad_to_dagmc.egg-info/top_level.txt +0 -0
  52. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/tests/ENDFB-7.1-NNDC_H1.h5 +0 -0
  53. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/tests/ball_reactor.brep +0 -0
  54. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/tests/curved_extrude.stp +0 -0
  55. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/tests/extrude_rectangle.stp +0 -0
  56. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/tests/multi_volume_cylinders.stp +0 -0
  57. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/tests/one_cube.brep +0 -0
  58. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/tests/single_cube.stp +0 -0
  59. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/tests/single_volume_thin.stp +0 -0
  60. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/tests/single_volume_thin.vtk +0 -0
  61. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/tests/tagged_mesh.msh +0 -0
  62. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/tests/test_brep_file.brep +0 -0
  63. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/tests/test_get_volumes.py +0 -0
  64. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/tests/test_loading_from_file_vs_shape_object.py +0 -0
  65. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/tests/test_mesh_to_dagmc.py +0 -0
  66. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/tests/test_two_joined_cubes.brep +0 -0
  67. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/tests/test_two_sep_cubes.brep +0 -0
  68. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/tests/test_version.py +0 -0
  69. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/tests/two_connected_cubes.stp +0 -0
  70. {cad_to_dagmc-0.9.9 → cad_to_dagmc-0.10.0}/tests/two_disconnected_cubes.stp +0 -0
@@ -69,6 +69,8 @@ jobs:
69
69
  source "${HOME}/miniforge/etc/profile.d/conda.sh"
70
70
  conda activate ci-env
71
71
  python examples/surface_mesh/cadquery_assembly.py
72
+ python examples/surface_mesh/cadquery_assembly_with_materials.py
73
+ python examples/surface_mesh/cadquery_assembly_with_names.py
72
74
  python examples/surface_mesh/cadquery_assembly_with_scaled_geometry.py
73
75
  python examples/surface_mesh/cadquery_compound.py
74
76
  python examples/surface_mesh/cadquery_object_and_stp_file.py
@@ -49,6 +49,7 @@ jobs:
49
49
  pytest -v tests
50
50
  python examples/surface_mesh/cadquery_assembly.py
51
51
  python examples/surface_mesh/cadquery_assembly_with_materials.py
52
+ python examples/surface_mesh/cadquery_assembly_with_names.py
52
53
  python examples/surface_mesh/cadquery_assembly_with_scaled_geometry.py
53
54
  python examples/surface_mesh/cadquery_compound.py
54
55
  python examples/surface_mesh/cadquery_object_and_stp_file.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cad_to_dagmc
3
- Version: 0.9.9
3
+ Version: 0.10.0
4
4
  Summary: Converts CAD files to a DAGMC h5m file
5
5
  Author-email: Jonathan Shimwell <mail@jshimwell.com>
6
6
  Project-URL: Homepage, https://github.com/fusion-energy/cad_to_dagmc
@@ -14,9 +14,10 @@ Description-Content-Type: text/markdown
14
14
  License-File: LICENSE
15
15
  Requires-Dist: trimesh
16
16
  Requires-Dist: networkx
17
- Requires-Dist: cadquery>=2.5.2
17
+ Requires-Dist: cadquery>=2.6.0
18
18
  Requires-Dist: numpy
19
19
  Requires-Dist: gmsh
20
+ Requires-Dist: cadquery_direct_mesh_plugin>=0.1.0
20
21
  Provides-Extra: tests
21
22
  Requires-Dist: pytest; extra == "tests"
22
23
  Requires-Dist: vtk; extra == "tests"
@@ -13,7 +13,9 @@ import openmc
13
13
  box_cutter = cq.Workplane("XY").moveTo(0, 5).box(20, 10, 20)
14
14
  inner_sphere = cq.Workplane("XY").sphere(6).cut(box_cutter)
15
15
  middle_sphere = cq.Workplane("XY").sphere(6.1).cut(box_cutter).cut(inner_sphere)
16
- outer_sphere = cq.Workplane("XY").sphere(10).cut(box_cutter).cut(inner_sphere).cut(middle_sphere)
16
+ outer_sphere = (
17
+ cq.Workplane("XY").sphere(10).cut(box_cutter).cut(inner_sphere).cut(middle_sphere)
18
+ )
17
19
 
18
20
  assembly = cq.Assembly()
19
21
  assembly.add(inner_sphere, name="inner_sphere")
@@ -101,5 +103,7 @@ umesh_from_sp = sp.meshes[1]
101
103
  centroids = umesh_from_sp.centroids
102
104
  mesh_vols = umesh_from_sp.volumes
103
105
 
104
- flux_mean = tally_result.get_values(scores=["flux"], value="mean").reshape(umesh_from_sp.dimension)
106
+ flux_mean = tally_result.get_values(scores=["flux"], value="mean").reshape(
107
+ umesh_from_sp.dimension
108
+ )
105
109
  umesh_from_sp.write_data_to_vtk(filename="tally.vtk", datasets={"mean": flux_mean})
@@ -10,11 +10,16 @@ result = cq.Workplane().sphere(5)
10
10
  result2 = cq.Workplane().moveTo(10, 0).sphere(2)
11
11
 
12
12
  assembly = cq.Assembly()
13
- assembly.add(result, name="result", material=cq.Material("mat1")) # note material assigned here
14
- assembly.add(result2, name="result2", material=cq.Material("mat2")) # note material assigned here
13
+ assembly.add(
14
+ result, name="result", material=cq.Material("mat1")
15
+ ) # note material assigned here
16
+ assembly.add(
17
+ result2, name="result2", material=cq.Material("mat2")
18
+ ) # note material assigned here
15
19
 
16
20
  my_model = CadToDagmc()
17
21
  my_model.add_cadquery_object(
18
- cadquery_object=assembly
19
- ) # note that material tags are not needed here
22
+ cadquery_object=assembly,
23
+ material_tags="assembly_materials",
24
+ )
20
25
  my_model.export_dagmc_h5m_file(min_mesh_size=0.5, max_mesh_size=1.0e6)
@@ -0,0 +1,18 @@
1
+ # This example makes a CadQuery assembly and assigns names to the parts
2
+ # These part names are then used when exporting to a DAGMC H5M file
3
+ # This avoids needing to specify material tags separately when adding the CadQuery object
4
+
5
+
6
+ import cadquery as cq
7
+ from cad_to_dagmc import CadToDagmc
8
+
9
+ result = cq.Workplane().sphere(5)
10
+ result2 = cq.Workplane().moveTo(10, 0).sphere(2)
11
+
12
+ assembly = cq.Assembly()
13
+ assembly.add(result, name="result")
14
+ assembly.add(result2, name="result2")
15
+
16
+ my_model = CadToDagmc()
17
+ my_model.add_cadquery_object(cadquery_object=assembly, material_tags="assembly_names")
18
+ my_model.export_dagmc_h5m_file(min_mesh_size=0.5, max_mesh_size=1.0e6)
@@ -11,4 +11,6 @@ assembly.add(result2)
11
11
  my_model = CadToDagmc()
12
12
  my_model.add_cadquery_object(cadquery_object=assembly, material_tags=["mat1", "mat2"])
13
13
  # scales geometry to makie it 10 times bigger
14
- my_model.export_dagmc_h5m_file(min_mesh_size=0.5, max_mesh_size=1.0e6, scale_factor=10.0)
14
+ my_model.export_dagmc_h5m_file(
15
+ min_mesh_size=0.5, max_mesh_size=1.0e6, scale_factor=10.0
16
+ )
@@ -17,12 +17,19 @@ r = s.lineTo(3.0, 0).lineTo(3.0, 1.0).spline(spline_points, includeCurrent=True)
17
17
  cq_shape_1 = r.extrude(-1)
18
18
 
19
19
  s2 = cq.Workplane("XY")
20
- r2 = s2.lineTo(3.0, 0).lineTo(3.0, 1.0).spline(spline_points, includeCurrent=True).close()
20
+ r2 = (
21
+ s2.lineTo(3.0, 0)
22
+ .lineTo(3.0, 1.0)
23
+ .spline(spline_points, includeCurrent=True)
24
+ .close()
25
+ )
21
26
  cq_shape_2 = r2.extrude(1)
22
27
 
23
28
 
24
29
  compound_of_shapes = cq.Compound.makeCompound([cq_shape_1.val(), cq_shape_2.val()])
25
30
 
26
31
  my_model = CadToDagmc()
27
- my_model.add_cadquery_object(cadquery_object=compound_of_shapes, material_tags=["mat1", "mat2"])
32
+ my_model.add_cadquery_object(
33
+ cadquery_object=compound_of_shapes, material_tags=["mat1", "mat2"]
34
+ )
28
35
  my_model.export_dagmc_h5m_file(max_mesh_size=0.2, min_mesh_size=0.1)
@@ -8,5 +8,7 @@ box_with_round_corners = cq.Workplane("XY").box(2, 1, 1)
8
8
 
9
9
  my_model = CadToDagmc()
10
10
  my_model.add_cadquery_object(cadquery_object=box, material_tags=["mat1"])
11
- my_model.add_cadquery_object(cadquery_object=box_with_round_corners, material_tags=["mat2"])
11
+ my_model.add_cadquery_object(
12
+ cadquery_object=box_with_round_corners, material_tags=["mat2"]
13
+ )
12
14
  my_model.export_dagmc_h5m_file()
@@ -12,7 +12,12 @@ spline_points = [
12
12
  (0.5, 1.0),
13
13
  (0, 1.0),
14
14
  ]
15
- r = result.lineTo(3.0, 0).lineTo(3.0, 1.0).spline(spline_points, includeCurrent=True).close()
15
+ r = (
16
+ result.lineTo(3.0, 0)
17
+ .lineTo(3.0, 1.0)
18
+ .spline(spline_points, includeCurrent=True)
19
+ .close()
20
+ )
16
21
  result = r.extrude(1.5)
17
22
  assembly = cq.Assembly()
18
23
  assembly.add(result)
@@ -59,4 +59,6 @@ my_model = CadToDagmc()
59
59
  my_model.add_cadquery_object(result, material_tags=["mat1"])
60
60
  my_model.add_cadquery_object(result2, material_tags=["mat2"])
61
61
 
62
- my_model.export_unstructured_mesh_file(filename="umesh.vtk", max_mesh_size=1, min_mesh_size=0.1)
62
+ my_model.export_unstructured_mesh_file(
63
+ filename="umesh.vtk", max_mesh_size=1, min_mesh_size=0.1
64
+ )
@@ -65,5 +65,7 @@ umesh_from_sp = sp.meshes[1]
65
65
  centroids = umesh_from_sp.centroids
66
66
  mesh_vols = umesh_from_sp.volumes
67
67
 
68
- flux_mean = tally_result.get_values(scores=["flux"], value="mean").reshape(umesh_from_sp.dimension)
68
+ flux_mean = tally_result.get_values(scores=["flux"], value="mean").reshape(
69
+ umesh_from_sp.dimension
70
+ )
69
71
  umesh_from_sp.write_data_to_vtk(filename="tally.vtk", datasets={"mean": flux_mean})
@@ -20,9 +20,10 @@ classifiers = [
20
20
  dependencies = [
21
21
  "trimesh",
22
22
  "networkx",
23
- "cadquery>=2.5.2",
23
+ "cadquery>=2.6.0",
24
24
  "numpy",
25
25
  "gmsh",
26
+ "cadquery_direct_mesh_plugin>=0.1.0"
26
27
  # TODO once on pypi include moab here and remove from CI
27
28
  # python -m pip install --extra-index-url https://shimwell.github.io/wheels moab
28
29
  ]
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '0.9.9'
32
- __version_tuple__ = version_tuple = (0, 9, 9)
31
+ __version__ = version = '0.10.0'
32
+ __version_tuple__ = version_tuple = (0, 10, 0)
33
33
 
34
- __commit_id__ = commit_id = 'g72b88f255'
34
+ __commit_id__ = commit_id = 'g9c4662166'
@@ -13,5 +13,4 @@ except PackageNotFoundError:
13
13
 
14
14
  __all__ = ["__version__"]
15
15
 
16
- from .direct_mesh_plugin import *
17
16
  from .core import *
@@ -9,7 +9,7 @@ import tempfile
9
9
  import warnings
10
10
  from typing import Iterable
11
11
  from cad_to_dagmc import __version__
12
- from .direct_mesh_plugin import to_mesh
12
+ import cadquery_direct_mesh_plugin
13
13
 
14
14
 
15
15
  def define_moab_core_and_tags() -> tuple[core.Core, dict]:
@@ -89,7 +89,11 @@ def vertices_to_h5m(
89
89
  raise ValueError(msg)
90
90
 
91
91
  # limited attribute checking to see if user passed in a list of CadQuery vectors
92
- if hasattr(vertices[0], "x") and hasattr(vertices[0], "y") and hasattr(vertices[0], "z"):
92
+ if (
93
+ hasattr(vertices[0], "x")
94
+ and hasattr(vertices[0], "y")
95
+ and hasattr(vertices[0], "z")
96
+ ):
93
97
  vertices_floats = []
94
98
  for vert in vertices:
95
99
  vertices_floats.append((vert.x, vert.y, vert.z))
@@ -142,7 +146,9 @@ def vertices_to_h5m(
142
146
  if len(face_ids_with_solid_ids[face_id]) == 2:
143
147
  other_solid_id = face_ids_with_solid_ids[face_id][1]
144
148
  other_volume_set = volume_sets_by_solid_id[other_solid_id]
145
- sense_data = np.array([other_volume_set, volume_set], dtype="uint64")
149
+ sense_data = np.array(
150
+ [other_volume_set, volume_set], dtype="uint64"
151
+ )
146
152
  else:
147
153
  sense_data = np.array([volume_set, 0], dtype="uint64")
148
154
 
@@ -233,7 +239,9 @@ def get_volumes(gmsh, assembly, method="file", scale_factor=1.0):
233
239
 
234
240
  if scale_factor != 1.0:
235
241
  dim_tags = gmsh.model.getEntities(3)
236
- gmsh.model.occ.dilate(dim_tags, 0.0, 0.0, 0.0, scale_factor, scale_factor, scale_factor)
242
+ gmsh.model.occ.dilate(
243
+ dim_tags, 0.0, 0.0, 0.0, scale_factor, scale_factor, scale_factor
244
+ )
237
245
  # update the model to ensure the scaling factor has been applied
238
246
  gmsh.model.occ.synchronize()
239
247
 
@@ -298,7 +306,9 @@ def set_sizes_for_mesh(
298
306
  )
299
307
 
300
308
  # Step 1: Preprocess boundaries to find shared surfaces and decide mesh sizes
301
- boundary_sizes = {} # Dictionary to store the mesh size and count for each boundary
309
+ boundary_sizes = (
310
+ {}
311
+ ) # Dictionary to store the mesh size and count for each boundary
302
312
  for volume_id, size in set_size.items():
303
313
  boundaries = gmsh.model.getBoundary(
304
314
  [(3, volume_id)], recursive=True
@@ -373,7 +383,8 @@ def mesh_to_vertices_and_triangles(
373
383
  for nodeTag in nodeTags:
374
384
  shifted_node_tags.append(nodeTag - 1)
375
385
  grouped_node_tags = [
376
- shifted_node_tags[i : i + n] for i in range(0, len(shifted_node_tags), n)
386
+ shifted_node_tags[i : i + n]
387
+ for i in range(0, len(shifted_node_tags), n)
377
388
  ]
378
389
  nodes_in_each_surface[surface] = grouped_node_tags
379
390
  triangles_by_solid_by_face[vol_id] = nodes_in_each_surface
@@ -583,14 +594,18 @@ class CadToDagmc:
583
594
  scaled_part = part
584
595
  else:
585
596
  scaled_part = part.scale(scale_factor)
586
- return self.add_cadquery_object(cadquery_object=scaled_part, material_tags=material_tags)
597
+ return self.add_cadquery_object(
598
+ cadquery_object=scaled_part, material_tags=material_tags
599
+ )
587
600
 
588
601
  def add_cadquery_object(
589
602
  self,
590
603
  cadquery_object: (
591
- cq.assembly.Assembly | cq.occ_impl.shapes.Compound | cq.occ_impl.shapes.Solid
604
+ cq.assembly.Assembly
605
+ | cq.occ_impl.shapes.Compound
606
+ | cq.occ_impl.shapes.Solid
592
607
  ),
593
- material_tags: list[str] | None = None,
608
+ material_tags: list[str] | str,
594
609
  scale_factor: float = 1.0,
595
610
  ) -> int:
596
611
  """Loads the parts from CadQuery object into the model.
@@ -612,25 +627,43 @@ class CadToDagmc:
612
627
  int: number of volumes in the stp file.
613
628
  """
614
629
 
630
+ if isinstance(material_tags, str) and material_tags not in [
631
+ "assembly_materials",
632
+ "assembly_names",
633
+ ]:
634
+ raise ValueError(
635
+ f"If material_tags is a string it must be 'assembly_materials' or 'assembly_names' but got {material_tags}"
636
+ )
637
+
615
638
  if isinstance(cadquery_object, cq.assembly.Assembly):
616
639
  # look for materials in each part of the assembly
617
- if material_tags is None:
640
+ if material_tags == "assembly_materials":
618
641
  material_tags = []
619
- for child in cadquery_object.children:
642
+ for child in _get_all_leaf_children(cadquery_object):
620
643
  if child.material is not None and child.material.name is not None:
621
- material_tags.append(child.material.name)
644
+ material_tags.append(str(child.material.name))
622
645
  else:
623
646
  raise ValueError(
624
- f"Not all parts in the assembly have material tags assigned. "
625
- f"Missing material tag for child: {child}. "
626
- "Please assign material tags to all parts or provide material_tags argument when adding the assembly."
647
+ f"Not all parts in the assembly have materials assigned.\n"
648
+ f"When adding to an assembly include material=cadquery.Material('material_name')\n"
649
+ f"Missing material tag for child: {child}.\n"
650
+ "Please assign material tags to all parts or provide material_tags argument when adding the assembly.\n"
627
651
  )
652
+ print("material_tags found from assembly materials:", material_tags)
653
+ elif material_tags == "assembly_names":
654
+ material_tags = []
655
+ for child in _get_all_leaf_children(cadquery_object):
656
+ # parts always have a name as cq will auto assign one
657
+ material_tags.append(child.name)
658
+ print("material_tags found from assembly names:", material_tags)
628
659
 
629
660
  cadquery_compound = cadquery_object.toCompound()
630
661
  else:
631
662
  cadquery_compound = cadquery_object
632
663
 
633
- if isinstance(cadquery_compound, (cq.occ_impl.shapes.Compound, cq.occ_impl.shapes.Solid)):
664
+ if isinstance(
665
+ cadquery_compound, (cq.occ_impl.shapes.Compound, cq.occ_impl.shapes.Solid)
666
+ ):
634
667
  iterable_solids = cadquery_compound.Solids()
635
668
  else:
636
669
  iterable_solids = cadquery_compound.val().Solids()
@@ -638,10 +671,9 @@ class CadToDagmc:
638
671
  if scale_factor == 1.0:
639
672
  scaled_iterable_solids = iterable_solids
640
673
  else:
641
- scaled_iterable_solids = [part.scale(scale_factor) for part in iterable_solids]
642
-
643
- # look for materials in the
644
- # if material_tags is None:
674
+ scaled_iterable_solids = [
675
+ part.scale(scale_factor) for part in iterable_solids
676
+ ]
645
677
 
646
678
  check_material_tags(material_tags, scaled_iterable_solids)
647
679
  if material_tags:
@@ -742,7 +774,9 @@ class CadToDagmc:
742
774
  gmsh.model.occ.synchronize()
743
775
  # Clear the mesh
744
776
  gmsh.model.mesh.clear()
745
- gmsh.option.setNumber("Mesh.SaveElementTagType", 3) # Save only volume elements
777
+ gmsh.option.setNumber(
778
+ "Mesh.SaveElementTagType", 3
779
+ ) # Save only volume elements
746
780
 
747
781
  gmsh.model.mesh.generate(3)
748
782
 
@@ -813,7 +847,9 @@ class CadToDagmc:
813
847
 
814
848
  gmsh = init_gmsh()
815
849
 
816
- gmsh, _ = get_volumes(gmsh, imprinted_assembly, method=method, scale_factor=scale_factor)
850
+ gmsh, _ = get_volumes(
851
+ gmsh, imprinted_assembly, method=method, scale_factor=scale_factor
852
+ )
817
853
 
818
854
  gmsh = set_sizes_for_mesh(
819
855
  gmsh=gmsh,
@@ -1014,8 +1050,7 @@ class CadToDagmc:
1014
1050
  if meshing_backend == "cadquery":
1015
1051
 
1016
1052
  # Mesh the assembly using CadQuery's direct-mesh plugin
1017
- cq_mesh = to_mesh(
1018
- assembly,
1053
+ cq_mesh = assembly.toMesh(
1019
1054
  imprint=imprint,
1020
1055
  tolerance=tolerance,
1021
1056
  angular_tolerance=angular_tolerance,
@@ -1024,9 +1059,13 @@ class CadToDagmc:
1024
1059
 
1025
1060
  # Fix the material tag order for imprinted assemblies
1026
1061
  if cq_mesh["imprinted_assembly"] is not None:
1027
- imprinted_solids_with_org_id = cq_mesh["imprinted_solids_with_orginal_ids"]
1062
+ imprinted_solids_with_org_id = cq_mesh[
1063
+ "imprinted_solids_with_orginal_ids"
1064
+ ]
1028
1065
 
1029
- scrambled_ids = get_ids_from_imprinted_assembly(imprinted_solids_with_org_id)
1066
+ scrambled_ids = get_ids_from_imprinted_assembly(
1067
+ imprinted_solids_with_org_id
1068
+ )
1030
1069
 
1031
1070
  material_tags_in_brep_order = order_material_ids_by_brep_order(
1032
1071
  original_ids, scrambled_ids, self.material_tags
@@ -1044,11 +1083,13 @@ class CadToDagmc:
1044
1083
  # If assembly is not to be imprinted, pass through the assembly as-is
1045
1084
  if imprint:
1046
1085
  print("Imprinting assembly for mesh generation")
1047
- imprinted_assembly, imprinted_solids_with_org_id = cq.occ_impl.assembly.imprint(
1048
- assembly
1086
+ imprinted_assembly, imprinted_solids_with_org_id = (
1087
+ cq.occ_impl.assembly.imprint(assembly)
1049
1088
  )
1050
1089
 
1051
- scrambled_ids = get_ids_from_imprinted_assembly(imprinted_solids_with_org_id)
1090
+ scrambled_ids = get_ids_from_imprinted_assembly(
1091
+ imprinted_solids_with_org_id
1092
+ )
1052
1093
 
1053
1094
  material_tags_in_brep_order = order_material_ids_by_brep_order(
1054
1095
  original_ids, scrambled_ids, self.material_tags
@@ -1108,7 +1149,9 @@ class CadToDagmc:
1108
1149
  gmsh.model.removePhysicalGroups([entry])
1109
1150
 
1110
1151
  gmsh.model.mesh.generate(3)
1111
- gmsh.option.setNumber("Mesh.SaveElementTagType", 3) # Save only volume elements
1152
+ gmsh.option.setNumber(
1153
+ "Mesh.SaveElementTagType", 3
1154
+ ) # Save only volume elements
1112
1155
  gmsh.write(umesh_filename)
1113
1156
 
1114
1157
  gmsh.finalize()
@@ -1116,3 +1159,13 @@ class CadToDagmc:
1116
1159
  return dagmc_filename, umesh_filename
1117
1160
  else:
1118
1161
  return dagmc_filename
1162
+
1163
+
1164
+ def _get_all_leaf_children(assembly):
1165
+ """Recursively yield all leaf children (parts, not assemblies) from a CadQuery assembly."""
1166
+ for child in assembly.children:
1167
+ # If the child is itself an assembly, recurse
1168
+ if hasattr(child, "children") and len(child.children) > 0:
1169
+ yield from _get_all_leaf_children(child)
1170
+ else:
1171
+ yield child
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cad_to_dagmc
3
- Version: 0.9.9
3
+ Version: 0.10.0
4
4
  Summary: Converts CAD files to a DAGMC h5m file
5
5
  Author-email: Jonathan Shimwell <mail@jshimwell.com>
6
6
  Project-URL: Homepage, https://github.com/fusion-energy/cad_to_dagmc
@@ -14,9 +14,10 @@ Description-Content-Type: text/markdown
14
14
  License-File: LICENSE
15
15
  Requires-Dist: trimesh
16
16
  Requires-Dist: networkx
17
- Requires-Dist: cadquery>=2.5.2
17
+ Requires-Dist: cadquery>=2.6.0
18
18
  Requires-Dist: numpy
19
19
  Requires-Dist: gmsh
20
+ Requires-Dist: cadquery_direct_mesh_plugin>=0.1.0
20
21
  Provides-Extra: tests
21
22
  Requires-Dist: pytest; extra == "tests"
22
23
  Requires-Dist: vtk; extra == "tests"
@@ -3,7 +3,6 @@ CITATION.cff
3
3
  LICENSE
4
4
  README.md
5
5
  pyproject.toml
6
- .github/workflows/black.yml
7
6
  .github/workflows/ci_with_benchmarks.yml
8
7
  .github/workflows/ci_with_conda_install.yml
9
8
  .github/workflows/ci_with_pip_install.yml
@@ -11,6 +10,7 @@ pyproject.toml
11
10
  examples/surface_and_unstructured_mesh/unstructured_mesh_with_conformal_surface_mesh.py
12
11
  examples/surface_mesh/cadquery_assembly.py
13
12
  examples/surface_mesh/cadquery_assembly_with_materials.py
13
+ examples/surface_mesh/cadquery_assembly_with_names.py
14
14
  examples/surface_mesh/cadquery_assembly_with_scaled_geometry.py
15
15
  examples/surface_mesh/cadquery_compound.py
16
16
  examples/surface_mesh/cadquery_object_and_stp_file.py
@@ -32,7 +32,6 @@ examples/unstrucutred_volume_mesh/simulate_unstrucutred_volume_mesh_with_openmc.
32
32
  src/_version.py
33
33
  src/cad_to_dagmc/__init__.py
34
34
  src/cad_to_dagmc/core.py
35
- src/cad_to_dagmc/direct_mesh_plugin.py
36
35
  src/cad_to_dagmc.egg-info/PKG-INFO
37
36
  src/cad_to_dagmc.egg-info/SOURCES.txt
38
37
  src/cad_to_dagmc.egg-info/dependency_links.txt
@@ -49,10 +48,12 @@ tests/single_volume_thin.stp
49
48
  tests/single_volume_thin.vtk
50
49
  tests/tagged_mesh.msh
51
50
  tests/test_assembly_with_materials.py
51
+ tests/test_assembly_with_names.py
52
52
  tests/test_brep_file.brep
53
53
  tests/test_file_creation.py
54
54
  tests/test_get_volumes.py
55
55
  tests/test_h5m_in_transport.py
56
+ tests/test_invalid_material_tags_string.py
56
57
  tests/test_kwarg_args.py
57
58
  tests/test_loading_from_file_vs_shape_object.py
58
59
  tests/test_mesh_to_dagmc.py
@@ -1,8 +1,9 @@
1
1
  trimesh
2
2
  networkx
3
- cadquery>=2.5.2
3
+ cadquery>=2.6.0
4
4
  numpy
5
5
  gmsh
6
+ cadquery_direct_mesh_plugin>=0.1.0
6
7
 
7
8
  [tests]
8
9
  pytest
@@ -0,0 +1,91 @@
1
+ import tempfile
2
+ import cadquery as cq
3
+ from cad_to_dagmc import CadToDagmc
4
+ from pathlib import Path
5
+ import pytest
6
+ from test_python_api import get_volumes_and_materials_from_h5m
7
+
8
+
9
+ def test_cadquery_assembly_with_materials():
10
+
11
+ with tempfile.TemporaryDirectory() as tmpdir:
12
+
13
+ result = cq.Workplane().sphere(5)
14
+ result2 = cq.Workplane().moveTo(10, 0).sphere(2)
15
+
16
+ assembly = cq.Assembly()
17
+ assembly.add(
18
+ result, name="result", material=cq.Material("diamond")
19
+ ) # note material assigned here
20
+ assembly.add(
21
+ result2, name="result2", material=cq.Material("gold")
22
+ ) # note material assigned here
23
+
24
+ my_model = CadToDagmc()
25
+ # note that material tags are not needed here
26
+ my_model.add_cadquery_object(
27
+ cadquery_object=assembly, material_tags="assembly_materials"
28
+ )
29
+ test_h5m_filename = my_model.export_dagmc_h5m_file(
30
+ min_mesh_size=0.5, max_mesh_size=1.0e6
31
+ )
32
+
33
+ assert Path(test_h5m_filename).is_file()
34
+
35
+ assert get_volumes_and_materials_from_h5m(test_h5m_filename) == {
36
+ 1: "mat:diamond",
37
+ 2: "mat:gold",
38
+ }
39
+
40
+
41
+ def test_assembly_missing_material_tag_raises():
42
+ # Create two parts, only one with a material
43
+ result = cq.Workplane().sphere(5)
44
+ result2 = cq.Workplane().moveTo(10, 0).sphere(2)
45
+
46
+ assembly = cq.Assembly()
47
+ assembly.add(result, name="result", material=cq.Material("diamond"))
48
+ assembly.add(result2, name="result2") # No material assigned
49
+
50
+ my_model = CadToDagmc()
51
+ # Should raise ValueError when adding the assembly
52
+ with pytest.raises(ValueError) as excinfo:
53
+ my_model.add_cadquery_object(
54
+ cadquery_object=assembly, material_tags="assembly_materials"
55
+ )
56
+ # Check error message is informative
57
+ assert "Not all parts in the assembly have materials assigned" in str(excinfo.value)
58
+
59
+
60
+ def test_cadquery_assembly_with_nested_assembly():
61
+
62
+ with tempfile.TemporaryDirectory() as tmpdir:
63
+
64
+ result = cq.Workplane().sphere(5)
65
+ result2 = cq.Workplane().moveTo(10, 0).sphere(2)
66
+ result3 = cq.Workplane().moveTo(-10, 0).sphere(2)
67
+
68
+ assembly = cq.Assembly()
69
+ assembly.add(result, name="result", material=cq.Material("diamond"))
70
+ assembly.add(result2, name="result2", material=cq.Material("gold"))
71
+
72
+ assembly2 = cq.Assembly()
73
+ assembly2.add(assembly, name="assembly1")
74
+ assembly2.add(result3, name="result3", material=cq.Material("silver"))
75
+
76
+ my_model = CadToDagmc()
77
+ # note that material tags are not needed here
78
+ my_model.add_cadquery_object(
79
+ cadquery_object=assembly2, material_tags="assembly_materials"
80
+ )
81
+ test_h5m_filename = my_model.export_dagmc_h5m_file(
82
+ min_mesh_size=0.5, max_mesh_size=1.0e6
83
+ )
84
+
85
+ assert Path(test_h5m_filename).is_file()
86
+
87
+ assert get_volumes_and_materials_from_h5m(test_h5m_filename) == {
88
+ 1: "mat:diamond",
89
+ 2: "mat:gold",
90
+ 3: "mat:silver",
91
+ }