cad-to-dagmc 0.9.1__py3-none-any.whl → 0.9.3__py3-none-any.whl

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.
_version.py CHANGED
@@ -1,7 +1,14 @@
1
1
  # file generated by setuptools-scm
2
2
  # don't change, don't track in version control
3
3
 
4
- __all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
4
+ __all__ = [
5
+ "__version__",
6
+ "__version_tuple__",
7
+ "version",
8
+ "version_tuple",
9
+ "__commit_id__",
10
+ "commit_id",
11
+ ]
5
12
 
6
13
  TYPE_CHECKING = False
7
14
  if TYPE_CHECKING:
@@ -9,13 +16,19 @@ if TYPE_CHECKING:
9
16
  from typing import Union
10
17
 
11
18
  VERSION_TUPLE = Tuple[Union[int, str], ...]
19
+ COMMIT_ID = Union[str, None]
12
20
  else:
13
21
  VERSION_TUPLE = object
22
+ COMMIT_ID = object
14
23
 
15
24
  version: str
16
25
  __version__: str
17
26
  __version_tuple__: VERSION_TUPLE
18
27
  version_tuple: VERSION_TUPLE
28
+ commit_id: COMMIT_ID
29
+ __commit_id__: COMMIT_ID
19
30
 
20
- __version__ = version = '0.9.1'
21
- __version_tuple__ = version_tuple = (0, 9, 1)
31
+ __version__ = version = '0.9.3'
32
+ __version_tuple__ = version_tuple = (0, 9, 3)
33
+
34
+ __commit_id__ = commit_id = None
cad_to_dagmc/core.py CHANGED
@@ -7,6 +7,7 @@ from cadquery import importers
7
7
  from pymoab import core, types
8
8
  import tempfile
9
9
  import warnings
10
+ from typing import Iterable
10
11
  from cad_to_dagmc import __version__
11
12
 
12
13
 
@@ -810,47 +811,112 @@ class CadToDagmc:
810
811
  def export_dagmc_h5m_file(
811
812
  self,
812
813
  filename: str = "dagmc.h5m",
813
- min_mesh_size: float | None = None,
814
- max_mesh_size: float | None = None,
815
- mesh_algorithm: int = 1,
814
+ meshing_backend: str = "cadquery",
816
815
  implicit_complement_material_tag: str | None = None,
817
- method: str = "file",
818
816
  scale_factor: float = 1.0,
819
817
  imprint: bool = True,
820
- set_size: dict[int, float] | None = None,
818
+ **kwargs,
821
819
  ) -> str:
822
820
  """Saves a DAGMC h5m file of the geometry
823
821
 
824
822
  Args:
825
- filename (str, optional): the filename to use for the saved DAGMC file. Defaults to "dagmc.h5m".
826
- min_mesh_size (float, optional): the minimum size of mesh elements to use. Defaults to 1.
827
- max_mesh_size (float, optional): the maximum size of mesh elements to use. Defaults to 5.
828
- mesh_algorithm (int, optional): the GMSH mesh algorithm to use.. Defaults to 1.
829
- implicit_complement_material_tag (str | None, optional):
830
- the name of the material tag to use for the implicit complement
831
- (void space). Defaults to None which is a vacuum. Defaults to None.
832
- method: the method to use to import the geometry into gmsh. Options
833
- are 'file' or 'in memory'. 'file' is the default and will write
834
- the geometry to a temporary file before importing it into gmsh.
835
- 'in memory' will import the geometry directly into gmsh but
836
- requires the version of OpenCASCADE used to build gmsh to be
837
- the same as the version used by CadQuery. This is possible to
838
- ensure when installing the package with Conda but harder when
839
- installing from PyPI.
840
- scale_factor: a scaling factor to apply to the geometry that can be
841
- used to enlarge or shrink the geometry. Useful when converting
842
- Useful when converting the geometry to cm for use in neutronics
843
- imprint: whether to imprint the geometry or not. Defaults to True as this is
844
- normally needed to ensure the geometry is meshed correctly. However if
845
- you know your geometry does not need imprinting you can set this to False
846
- and this can save time.
847
- set_size: a dictionary of volume ids (int) and target mesh sizes
848
- (floats) to set for each volume, passed to gmsh.model.mesh.setSize.
823
+ filename: the filename to use for the saved DAGMC file.
824
+ meshing_backend: determines whether gmsh or cadquery's direct mesh method
825
+ is used for meshing. Options are 'gmsh' or 'cadquery'.
826
+ implicit_complement_material_tag: the name of the material tag to use
827
+ for the implicit complement (void space).
828
+ scale_factor: a scaling factor to apply to the geometry.
829
+ imprint: whether to imprint the geometry or not.
830
+
831
+ **kwargs: Backend-specific parameters:
832
+
833
+ For GMSH backend:
834
+ - min_mesh_size (float): minimum mesh element size
835
+ - max_mesh_size (float): maximum mesh element size
836
+ - mesh_algorithm (int): GMSH mesh algorithm (default: 1)
837
+ - method (str): import method 'file' or 'in memory' (default: 'file')
838
+ - set_size (dict[int, float]): volume ids and target mesh sizes
839
+ - unstructured_volumes (Iterable[int]): volume ids for unstructured mesh
840
+ - umesh_filename (str): filename for unstructured mesh (default: 'umesh.vtk')
841
+
842
+ For CadQuery backend:
843
+ - tolerance (float): meshing tolerance (default: 0.1)
844
+ - angular_tolerance (float): angular tolerance (default: 0.1)
849
845
 
850
846
  Returns:
851
- str: the DAGMC filename saved
847
+ str: the filename(s) for the files created.
848
+
849
+ Raises:
850
+ ValueError: If invalid parameter combinations are used.
852
851
  """
853
852
 
853
+ # Validate meshing backend
854
+ if meshing_backend not in ["gmsh", "cadquery"]:
855
+ raise ValueError(
856
+ f'meshing_backend "{meshing_backend}" not supported. '
857
+ 'Available options are "gmsh" or "cadquery"'
858
+ )
859
+
860
+ # Initialize variables to avoid unbound errors
861
+ tolerance = 0.1
862
+ angular_tolerance = 0.1
863
+ min_mesh_size = None
864
+ max_mesh_size = None
865
+ mesh_algorithm = 1
866
+ method = "file"
867
+ set_size = None
868
+ unstructured_volumes = None
869
+ umesh_filename = "umesh.vtk"
870
+
871
+ # Extract backend-specific parameters with defaults
872
+ if meshing_backend == "cadquery":
873
+ # CadQuery parameters
874
+ tolerance = kwargs.get("tolerance", 0.1)
875
+ angular_tolerance = kwargs.get("angular_tolerance", 0.1)
876
+
877
+ # Check for invalid parameters
878
+ unstructured_volumes = kwargs.get("unstructured_volumes")
879
+ if unstructured_volumes is not None:
880
+ raise ValueError(
881
+ "CadQuery backend cannot be used for volume meshing. "
882
+ "unstructured_volumes must be None when using 'cadquery' backend."
883
+ )
884
+
885
+ # Warn about unused GMSH parameters
886
+ gmsh_params = [
887
+ "min_mesh_size",
888
+ "max_mesh_size",
889
+ "mesh_algorithm",
890
+ "set_size",
891
+ "umesh_filename",
892
+ "method",
893
+ ]
894
+ unused_params = [param for param in gmsh_params if param in kwargs]
895
+ if unused_params:
896
+ warnings.warn(
897
+ f"The following parameters are ignored when using CadQuery backend: "
898
+ f"{', '.join(unused_params)}"
899
+ )
900
+
901
+ elif meshing_backend == "gmsh":
902
+ # GMSH parameters
903
+ min_mesh_size = kwargs.get("min_mesh_size")
904
+ max_mesh_size = kwargs.get("max_mesh_size")
905
+ mesh_algorithm = kwargs.get("mesh_algorithm", 1)
906
+ method = kwargs.get("method", "file")
907
+ set_size = kwargs.get("set_size")
908
+ unstructured_volumes = kwargs.get("unstructured_volumes")
909
+ umesh_filename = kwargs.get("umesh_filename", "umesh.vtk")
910
+
911
+ # Warn about unused CadQuery parameters
912
+ cq_params = ["tolerance", "angular_tolerance"]
913
+ unused_params = [param for param in cq_params if param in kwargs]
914
+ if unused_params:
915
+ warnings.warn(
916
+ f"The following parameters are ignored when using GMSH backend: "
917
+ f"{', '.join(unused_params)}"
918
+ )
919
+
854
920
  assembly = cq.Assembly()
855
921
  for part in self.parts:
856
922
  assembly.add(part)
@@ -863,51 +929,108 @@ class CadToDagmc:
863
929
  msg = f"Number of volumes {len(original_ids)} is not equal to number of material tags {len(self.material_tags)}"
864
930
  raise ValueError(msg)
865
931
 
866
- if imprint:
867
- imprinted_assembly, imprinted_solids_with_org_id = cq.occ_impl.assembly.imprint(
868
- assembly
932
+ # Use the CadQuery direct mesh plugin
933
+ if meshing_backend == "cadquery":
934
+ import cadquery_direct_mesh_plugin
935
+
936
+ # Mesh the assembly using CadQuery's direct-mesh plugin
937
+ cq_mesh = assembly.toMesh(
938
+ imprint,
939
+ tolerance=tolerance,
940
+ angular_tolerance=angular_tolerance,
941
+ scale_factor=scale_factor,
869
942
  )
870
943
 
871
- scrambled_ids = get_ids_from_imprinted_assembly(imprinted_solids_with_org_id)
944
+ # Fix the material tag order for imprinted assemblies
945
+ if cq_mesh["imprinted_assembly"] is not None:
946
+ imprinted_solids_with_org_id = cq_mesh["imprinted_solids_with_orginal_ids"]
872
947
 
873
- material_tags_in_brep_order = order_material_ids_by_brep_order(
874
- original_ids, scrambled_ids, self.material_tags
875
- )
876
- else:
877
- material_tags_in_brep_order = self.material_tags
878
- imprinted_assembly = assembly
948
+ scrambled_ids = get_ids_from_imprinted_assembly(imprinted_solids_with_org_id)
879
949
 
880
- check_material_tags(material_tags_in_brep_order, self.parts)
950
+ material_tags_in_brep_order = order_material_ids_by_brep_order(
951
+ original_ids, scrambled_ids, self.material_tags
952
+ )
953
+ else:
954
+ material_tags_in_brep_order = self.material_tags
955
+
956
+ check_material_tags(material_tags_in_brep_order, self.parts)
957
+
958
+ # Extract the mesh information to allow export to h5m from the direct-mesh result
959
+ vertices = cq_mesh["vertices"]
960
+ triangles_by_solid_by_face = cq_mesh["solid_face_triangle_vertex_map"]
961
+ # Use gmsh
962
+ elif meshing_backend == "gmsh":
963
+ # If assembly is not to be imprinted, pass through the assembly as-is
964
+ if imprint:
965
+ imprinted_assembly, imprinted_solids_with_org_id = cq.occ_impl.assembly.imprint(
966
+ assembly
967
+ )
881
968
 
882
- gmsh = init_gmsh()
969
+ scrambled_ids = get_ids_from_imprinted_assembly(imprinted_solids_with_org_id)
883
970
 
884
- gmsh, volumes = get_volumes(
885
- gmsh, imprinted_assembly, method=method, scale_factor=scale_factor
886
- )
971
+ material_tags_in_brep_order = order_material_ids_by_brep_order(
972
+ original_ids, scrambled_ids, self.material_tags
973
+ )
887
974
 
888
- gmsh = set_sizes_for_mesh(
889
- gmsh=gmsh,
890
- min_mesh_size=min_mesh_size,
891
- max_mesh_size=max_mesh_size,
892
- mesh_algorithm=mesh_algorithm,
893
- set_size=set_size,
894
- )
975
+ else:
976
+ material_tags_in_brep_order = self.material_tags
977
+ imprinted_assembly = assembly
895
978
 
896
- gmsh.model.mesh.generate(2)
979
+ check_material_tags(material_tags_in_brep_order, self.parts)
897
980
 
898
- dims_and_vol_ids = volumes
981
+ # Start generating the mesh
982
+ gmsh = init_gmsh()
899
983
 
900
- vertices, triangles_by_solid_by_face = mesh_to_vertices_and_triangles(
901
- dims_and_vol_ids=dims_and_vol_ids
902
- )
984
+ gmsh, volumes = get_volumes(
985
+ gmsh, imprinted_assembly, method=method, scale_factor=scale_factor
986
+ )
903
987
 
904
- gmsh.finalize()
988
+ gmsh = set_sizes_for_mesh(
989
+ gmsh=gmsh,
990
+ min_mesh_size=min_mesh_size,
991
+ max_mesh_size=max_mesh_size,
992
+ mesh_algorithm=mesh_algorithm,
993
+ set_size=set_size,
994
+ )
995
+
996
+ gmsh.model.mesh.generate(2)
997
+
998
+ vertices, triangles_by_solid_by_face = mesh_to_vertices_and_triangles(
999
+ dims_and_vol_ids=volumes
1000
+ )
1001
+
1002
+ else:
1003
+ raise ValueError(
1004
+ f'meshing_backend {meshing_backend} not supported. Available options are "cadquery" or "gmsh"'
1005
+ )
905
1006
 
906
- # checks and fixes triangle fix_normals within vertices_to_h5m
907
- return vertices_to_h5m(
1007
+ dagmc_filename = vertices_to_h5m(
908
1008
  vertices=vertices,
909
1009
  triangles_by_solid_by_face=triangles_by_solid_by_face,
910
1010
  material_tags=material_tags_in_brep_order,
911
1011
  h5m_filename=filename,
912
1012
  implicit_complement_material_tag=implicit_complement_material_tag,
913
1013
  )
1014
+
1015
+ if unstructured_volumes:
1016
+ # remove all the unused occ volumes, this prevents them being meshed
1017
+ for volume_dim, volume_id in volumes:
1018
+ if volume_id not in unstructured_volumes:
1019
+ gmsh.model.occ.remove([(volume_dim, volume_id)], recursive=True)
1020
+ gmsh.option.setNumber("Mesh.SaveAll", 1)
1021
+ gmsh.model.occ.synchronize()
1022
+
1023
+ # removes all the 2D groups so that 2D faces are not included in the vtk file
1024
+ all_2d_groups = gmsh.model.getPhysicalGroups(2)
1025
+ for entry in all_2d_groups:
1026
+ gmsh.model.removePhysicalGroups([entry])
1027
+
1028
+ gmsh.model.mesh.generate(3)
1029
+ gmsh.option.setNumber("Mesh.SaveElementTagType", 3) # Save only volume elements
1030
+ gmsh.write(umesh_filename)
1031
+
1032
+ gmsh.finalize()
1033
+
1034
+ return dagmc_filename, umesh_filename
1035
+ else:
1036
+ return dagmc_filename
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cad_to_dagmc
3
- Version: 0.9.1
3
+ Version: 0.9.3
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
@@ -55,7 +55,8 @@ Cad-to-dagmc offers a wide range of features including.
55
55
  - Geometry scaling with ```scale_factor``` argument
56
56
  - Model wide mesh size parameters with ```min_mesh_size``` and ```max_mesh_size``` arguments
57
57
  - Volume specific mesh sizing parameters with the ```set_size``` argument
58
- - Volume mesh selected volumes in the geometry (helps ensure conformal volume and surface mesh).
58
+ - Unstructured mesh that share the same coordinates as the surface mesh.
59
+ - Volume mesh allows selecting individual volumes in the geometry.
59
60
  - Parallel meshing to quickly mesh the geometry using multiple CPU cores
60
61
  - Imprint and merging of CAD geometry, or disable with the ```imprint``` argument
61
62
  - Add geometry from multiple sources ([STEP](http://www.steptools.com/stds/step/) files, [CadQuery](https://cadquery.readthedocs.io) objects and [Gmsh](https://gmsh.info/) meshes)
@@ -0,0 +1,8 @@
1
+ _version.py,sha256=IVkGBvcxJApDB_GrSj1qL5BDxEvWBYmqcR3emEmrC0I,704
2
+ cad_to_dagmc/__init__.py,sha256=fskHUTyCunSpnpJUvBfAYjx4uwDKXHTTiMP6GqnFRf0,494
3
+ cad_to_dagmc/core.py,sha256=2OzaYEMcWr508PuyciESTJPvOKRAbEwfOOL6d4VKEzM,40333
4
+ cad_to_dagmc-0.9.3.dist-info/licenses/LICENSE,sha256=B8kznH_777JVNZ3HOKDc4Tj24F7wJ68ledaNYeL9sCw,1070
5
+ cad_to_dagmc-0.9.3.dist-info/METADATA,sha256=OmHxTGWZTity6KYaUwMwB9wppyBxxcry_ikCWOvSfPU,8990
6
+ cad_to_dagmc-0.9.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
7
+ cad_to_dagmc-0.9.3.dist-info/top_level.txt,sha256=zTi8C64SEBsE5WOtPovnxhOzt-E6Oc5nC3RW6M_5aEA,22
8
+ cad_to_dagmc-0.9.3.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.3.1)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,8 +0,0 @@
1
- _version.py,sha256=QG_t-w_CzDn2UjPaW-Svt-wTU1NXK2QkudawUihJfHA,511
2
- cad_to_dagmc/__init__.py,sha256=fskHUTyCunSpnpJUvBfAYjx4uwDKXHTTiMP6GqnFRf0,494
3
- cad_to_dagmc/core.py,sha256=ej1wk_-q-eXJ5F7jfjBwPII4qWHnMQWeMT_XZG_A0xI,35713
4
- cad_to_dagmc-0.9.1.dist-info/licenses/LICENSE,sha256=B8kznH_777JVNZ3HOKDc4Tj24F7wJ68ledaNYeL9sCw,1070
5
- cad_to_dagmc-0.9.1.dist-info/METADATA,sha256=S15I2B5N_eEUC7XqFB6sNyiuFwSLrHj8--1CraXkaMo,8947
6
- cad_to_dagmc-0.9.1.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
7
- cad_to_dagmc-0.9.1.dist-info/top_level.txt,sha256=zTi8C64SEBsE5WOtPovnxhOzt-E6Oc5nC3RW6M_5aEA,22
8
- cad_to_dagmc-0.9.1.dist-info/RECORD,,