cad-to-dagmc 0.9.0__py3-none-any.whl → 0.9.1__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.

Potentially problematic release.


This version of cad-to-dagmc might be problematic. Click here for more details.

_version.py CHANGED
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '0.9.0'
21
- __version_tuple__ = version_tuple = (0, 9, 0)
20
+ __version__ = version = '0.9.1'
21
+ __version_tuple__ = version_tuple = (0, 9, 1)
cad_to_dagmc/core.py CHANGED
@@ -1,4 +1,5 @@
1
1
  from pathlib import Path
2
+ from typing import Iterable
2
3
  import cadquery as cq
3
4
  import gmsh
4
5
  import numpy as np
@@ -234,15 +235,14 @@ def init_gmsh():
234
235
  return gmsh
235
236
 
236
237
 
237
- def mesh_brep(
238
+ def set_sizes_for_mesh(
238
239
  gmsh,
239
240
  min_mesh_size: float | None = None,
240
241
  max_mesh_size: float | None = None,
241
242
  mesh_algorithm: int = 1,
242
- dimensions: int = 2,
243
243
  set_size: dict[int, float] | None = None,
244
244
  ):
245
- """Creates a conformal surface meshes of the volumes in a Brep file using Gmsh.
245
+ """Sets up the mesh sizes for each volume in the mesh.
246
246
 
247
247
  Args:
248
248
  occ_shape: the occ_shape of the Brep file to convert
@@ -252,8 +252,6 @@ def mesh_brep(
252
252
  into gmsh.option.setNumber("Mesh.MeshSizeMax", max_mesh_size)
253
253
  mesh_algorithm: The Gmsh mesh algorithm number to use. Passed into
254
254
  gmsh.option.setNumber("Mesh.Algorithm", mesh_algorithm)
255
- dimensions: The number of dimensions, 2 for a surface mesh 3 for a
256
- volume mesh. Passed to gmsh.model.mesh.generate()
257
255
  set_size: a dictionary of volume ids (int) and target mesh sizes
258
256
  (floats) to set for each volume, passed to gmsh.model.mesh.setSize.
259
257
 
@@ -279,25 +277,42 @@ def mesh_brep(
279
277
  volumes = gmsh.model.getEntities(3)
280
278
  available_volumes = [volume[1] for volume in volumes]
281
279
  print("volumes", volumes)
282
- for volume_id, size in set_size.items():
283
- if volume_id in available_volumes:
284
- size = set_size[volume_id]
285
- if isinstance(size, dict):
286
- # TODO face specific mesh sizes
287
- pass
288
- else:
289
- boundaries = gmsh.model.getBoundary(
290
- [(3, volume_id)], recursive=True
291
- ) # dim must be set to 3
292
- print("boundaries", boundaries)
293
- gmsh.model.mesh.setSize(boundaries, size)
294
- print(f"Set size of {size} for volume {volume_id}")
295
- else:
280
+
281
+ # Ensure all volume IDs in set_size exist in the available volumes
282
+ for volume_id in set_size.keys():
283
+ if volume_id not in available_volumes:
296
284
  raise ValueError(
297
285
  f"volume ID of {volume_id} set in set_sizes but not found in available volumes {volumes}"
298
286
  )
299
287
 
300
- gmsh.model.mesh.generate(dimensions)
288
+ # Step 1: Preprocess boundaries to find shared surfaces and decide mesh sizes
289
+ boundary_sizes = {} # Dictionary to store the mesh size and count for each boundary
290
+ for volume_id, size in set_size.items():
291
+ boundaries = gmsh.model.getBoundary(
292
+ [(3, volume_id)], recursive=True
293
+ ) # dim must be set to 3
294
+ print(f"Boundaries for volume {volume_id}: {boundaries}")
295
+
296
+ for boundary in boundaries:
297
+ boundary_key = (boundary[0], boundary[1]) # (dimension, tag)
298
+ if boundary_key in boundary_sizes:
299
+ # If the boundary is already processed, add the size to the list
300
+ boundary_sizes[boundary_key]["total_size"] += size
301
+ boundary_sizes[boundary_key]["count"] += 1
302
+ else:
303
+ # Otherwise, initialize the boundary with the current size
304
+ boundary_sizes[boundary_key] = {"total_size": size, "count": 1}
305
+
306
+ # Step 2: Calculate the average size for each boundary
307
+ averaged_boundary_sizes = {
308
+ boundary: data["total_size"] / data["count"]
309
+ for boundary, data in boundary_sizes.items()
310
+ }
311
+
312
+ # Step 3: Apply mesh sizes to all boundaries
313
+ for boundary, size in averaged_boundary_sizes.items():
314
+ gmsh.model.mesh.setSize([boundary], size)
315
+ print(f"Set mesh size {size} for boundary {boundary}")
301
316
 
302
317
  return gmsh
303
318
 
@@ -615,11 +630,13 @@ class CadToDagmc:
615
630
  scale_factor: float = 1.0,
616
631
  imprint: bool = True,
617
632
  set_size: dict[int, float] | None = None,
633
+ volumes: Iterable[int] | None = None,
618
634
  ):
619
635
  """
620
- Exports an unstructured mesh file in VTK format for use with openmc.UnstructuredMesh.
621
- Compatible with the MOAB unstructured mesh library. Example useage
622
- openmc.UnstructuredMesh(filename="umesh.vtk", library="moab")
636
+ Exports an unstructured mesh file in VTK format for use with
637
+ openmc.UnstructuredMesh. Compatible with the MOAB unstructured mesh
638
+ library. Example useage openmc.UnstructuredMesh(filename="umesh.vtk",
639
+ library="moab").
623
640
 
624
641
  Parameters:
625
642
  -----------
@@ -648,6 +665,8 @@ class CadToDagmc:
648
665
  and this can save time.
649
666
  set_size: a dictionary of volume ids (int) and target mesh sizes
650
667
  (floats) to set for each volume, passed to gmsh.model.mesh.setSize.
668
+ volumes: a list of volume ids (int) to include in the mesh. If left
669
+ as default (None) then all volumes will be included.
651
670
 
652
671
 
653
672
  Returns:
@@ -672,17 +691,30 @@ class CadToDagmc:
672
691
 
673
692
  gmsh = init_gmsh()
674
693
 
675
- gmsh, _ = get_volumes(gmsh, imprinted_assembly, method=method, scale_factor=scale_factor)
694
+ gmsh, volumes_in_model = get_volumes(
695
+ gmsh, imprinted_assembly, method=method, scale_factor=scale_factor
696
+ )
676
697
 
677
- gmsh = mesh_brep(
698
+ gmsh = set_sizes_for_mesh(
678
699
  gmsh=gmsh,
679
700
  min_mesh_size=min_mesh_size,
680
701
  max_mesh_size=max_mesh_size,
681
702
  mesh_algorithm=mesh_algorithm,
682
- dimensions=3,
683
703
  set_size=set_size,
684
704
  )
685
705
 
706
+ if volumes:
707
+ for volume_id in volumes_in_model:
708
+ if volume_id[1] not in volumes:
709
+ gmsh.model.occ.remove([volume_id], recursive=True)
710
+ gmsh.option.setNumber("Mesh.SaveAll", 1)
711
+ gmsh.model.occ.synchronize()
712
+ # Clear the mesh
713
+ gmsh.model.mesh.clear()
714
+ gmsh.option.setNumber("Mesh.SaveElementTagType", 3) # Save only volume elements
715
+
716
+ gmsh.model.mesh.generate(3)
717
+
686
718
  # makes the folder if it does not exist
687
719
  if Path(filename).parent:
688
720
  Path(filename).parent.mkdir(parents=True, exist_ok=True)
@@ -695,7 +727,7 @@ class CadToDagmc:
695
727
 
696
728
  gmsh.finalize()
697
729
 
698
- return gmsh
730
+ return filename
699
731
 
700
732
  def export_gmsh_mesh_file(
701
733
  self,
@@ -751,15 +783,16 @@ class CadToDagmc:
751
783
 
752
784
  gmsh, _ = get_volumes(gmsh, imprinted_assembly, method=method, scale_factor=scale_factor)
753
785
 
754
- gmsh = mesh_brep(
786
+ gmsh = set_sizes_for_mesh(
755
787
  gmsh=gmsh,
756
788
  min_mesh_size=min_mesh_size,
757
789
  max_mesh_size=max_mesh_size,
758
790
  mesh_algorithm=mesh_algorithm,
759
- dimensions=dimensions,
760
791
  set_size=set_size,
761
792
  )
762
793
 
794
+ gmsh.model.mesh.generate(dimensions)
795
+
763
796
  # makes the folder if it does not exist
764
797
  if Path(filename).parent:
765
798
  Path(filename).parent.mkdir(parents=True, exist_ok=True)
@@ -852,7 +885,7 @@ class CadToDagmc:
852
885
  gmsh, imprinted_assembly, method=method, scale_factor=scale_factor
853
886
  )
854
887
 
855
- gmsh = mesh_brep(
888
+ gmsh = set_sizes_for_mesh(
856
889
  gmsh=gmsh,
857
890
  min_mesh_size=min_mesh_size,
858
891
  max_mesh_size=max_mesh_size,
@@ -860,6 +893,8 @@ class CadToDagmc:
860
893
  set_size=set_size,
861
894
  )
862
895
 
896
+ gmsh.model.mesh.generate(2)
897
+
863
898
  dims_and_vol_ids = volumes
864
899
 
865
900
  vertices, triangles_by_solid_by_face = mesh_to_vertices_and_triangles(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cad_to_dagmc
3
- Version: 0.9.0
3
+ Version: 0.9.1
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,6 +55,7 @@ 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
59
  - Parallel meshing to quickly mesh the geometry using multiple CPU cores
59
60
  - Imprint and merging of CAD geometry, or disable with the ```imprint``` argument
60
61
  - 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)
@@ -130,21 +131,10 @@ First ensure hdf5 is installed as this is needed by MOAB pip install command
130
131
  sudo apt-get install libhdf5-dev
131
132
  ```
132
133
 
133
- Then clone the latest version of MOAB and cd into the moab directory.
134
+ Then install MOAB, currently available from the repo.
134
135
 
135
136
  ```
136
- git clone master https://bitbucket.org/fathomteam/moab/
137
- cd moab
138
- ```
139
-
140
- Ensure pip is up to date as a new version is needed
141
- ```
142
- python -m pip install --upgrade pip
143
- ```
144
-
145
- Run the pip install command with cmake arguments.
146
- ```
147
- pip install . --config-settings=cmake.args=-DENABLE_HDF5=ON
137
+ pip install git+https://bitbucket.org/fathomteam/moab/
148
138
  ```
149
139
 
150
140
  Then you can install the cad_to_dagmc package with ```pip```
@@ -0,0 +1,8 @@
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,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (78.1.0)
2
+ Generator: setuptools (80.3.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,8 +0,0 @@
1
- _version.py,sha256=fqtOm8q4HIqAgc-mXbjsKoz34kMK1y3t9LDhc4497WE,511
2
- cad_to_dagmc/__init__.py,sha256=fskHUTyCunSpnpJUvBfAYjx4uwDKXHTTiMP6GqnFRf0,494
3
- cad_to_dagmc/core.py,sha256=C3NEy5z4bjbg0SQjodGcZSOVqMAc8g5e0zLoF2gs0Og,34140
4
- cad_to_dagmc-0.9.0.dist-info/licenses/LICENSE,sha256=B8kznH_777JVNZ3HOKDc4Tj24F7wJ68ledaNYeL9sCw,1070
5
- cad_to_dagmc-0.9.0.dist-info/METADATA,sha256=J3Q4BXSU_ApF86K8sjDXA_hYT_k5GRRAKXaYc-ksbuw,9092
6
- cad_to_dagmc-0.9.0.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
7
- cad_to_dagmc-0.9.0.dist-info/top_level.txt,sha256=zTi8C64SEBsE5WOtPovnxhOzt-E6Oc5nC3RW6M_5aEA,22
8
- cad_to_dagmc-0.9.0.dist-info/RECORD,,