Skip to content
This repository has been archived by the owner on Aug 2, 2024. It is now read-only.

Commit

Permalink
Merge pull request #35 from fusion-energy/develop
Browse files Browse the repository at this point in the history
Adding tet mesh and scale options
  • Loading branch information
shimwell authored Sep 4, 2021
2 parents cc2c167 + 805f74e commit 3b21641
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 29 deletions.
66 changes: 62 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,10 @@ cad_to_h5m(
)
```

Creating a EXODUS mesh files compatible with the DAGMC Unstructured mesh format
is also possible. Another entry must be added to the ```files_with_tags```
argument. The following command will produce a ```unstructured_mesh_file.exo```
Creating a tet mesh files compatible with the OpenMC / DAGMC Unstructured mesh
format is also possible. Another key called ```tet_mesh``` to the ```files_with_tags``` dictionary will tirgger the meshing of that CAD file.
The value of the key will be passed to the Cubit mesh command as an instruction.
The following command will produce a ```unstructured_mesh_file.exo```
file that can then be used in DAGMC compatable neutronics codes. There are examples
[1](https://docs.openmc.org/en/latest/examples/unstructured-mesh-part-i.html)
[2](https://docs.openmc.org/en/latest/examples/unstructured-mesh-part-ii.html)
Expand All @@ -106,13 +107,70 @@ for the use of unstructured meshes in OpenMC.
from cad_to_h5m import cad_to_h5m

cad_to_h5m(
files_with_tags=[{'cad_filename':'part1.sat', 'material_tags':'m1', 'tet_mesh': 'size 0.5'}],
files_with_tags=[
{
'cad_filename':'part1.sat',
'material_tags':'m1',
'tet_mesh': 'size 0.5'
}
],
h5m_filename='dagmc.h5m',
cubit_path='/opt/Coreform-Cubit-2021.5/bin/'
exo_filename='unstructured_mesh_file.exo'
)
```

Use if ```exo``` files requires OpenMC to be compiled with LibMesh. OpenMC also
accepts DAGMC tet meshes made with MOAB which is another option. The following
example creates a ```cub``` file that contains a mesh. The MOAB tool
```mbconvert``` is then used to extract the tet mesh and save it as a ```h5m```
file which cna be used in OpenMC as shown in the OpenMC [examples](https://docs.openmc.org/en/stable/examples/unstructured-mesh-part-i.html)

```python
from cad_to_h5m import cad_to_h5m

cad_to_h5m(
files_with_tags=[
{
'cad_filename':'part1.sat',
'material_tags':'m1',
'tet_mesh': 'size 0.5'
}
],
h5m_filename='dagmc.h5m',
cubit_path='/opt/Coreform-Cubit-2021.5/bin/'
cubit_filename='unstructured_mesh_file.cub'
)
```
mbconvert is a terminal command that is part of MOAB.
```bash
mbconvert unstructured_mesh_file.cub unstructured_mesh_file.h5m
```

Scaling geometry is also possible. This is useful as particle transport codes
often make use of cm as the default unit. CAD files typically appear in mm as
the default limit. Some CAD packages ignore units while others make use of them.
The h5m files are assumed to be in cm by particle transport codes so often it
is nessecary to scale up or down the geometry. This can be done by adding
another key called ```scale``` and a value to the ```files_with_tags```
dictionary. This example multiplies the geometry by 10.

```python
from cad_to_h5m import cad_to_h5m

cad_to_h5m(
files_with_tags=[
{
'cad_filename':'part1.sat',
'material_tags':'m1',
'scale': 10
}
],
h5m_filename='dagmc.h5m',
)
```


# Installation

The package is available via the PyPi package manager and the recommended
Expand Down
53 changes: 40 additions & 13 deletions cad_to_h5m/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class FilesWithTags(TypedDict, total=False):
filename: str
material_tag: str
tet_mesh: str
scale: float


def cad_to_h5m(
Expand All @@ -22,7 +23,7 @@ def cad_to_h5m(
imprint: bool = True,
geometry_details_filename: Optional[str] = None,
surface_reflectivity_name: str = "reflective",
exo_filename: str = "tet_mesh.exo",
exo_filename: Optional[str] = None,
):
"""Converts a CAD files in STP or SAT format into a h5m file for use in
DAGMC simulations. The h5m file contains material tags associated with the
Expand All @@ -35,10 +36,16 @@ def cad_to_h5m(
"mat2", "cad_filename": "part2.stp"}]. There is also an option to create
a tet mesh of entries by including a "tet_mesh" key in the dictionary.
The value is passed to the Cubit mesh command. An example entry would be
"tet_mesh": "size 0.5"
h5m_filename: the file name of the output h5m file
"tet_mesh": "size 0.5". The scale key can also be included to scale up
or down the geometry so that it is in cm units as required by most
particle transport codes. And example entry would be "scale": 10 which
would make the geometry 10 times bigger.
h5m_filename: the file name of the output h5m file which is suitable for
use in DAGMC enabled particle transport codes.
cubit_filename: the file name of the output cubit file. Should end with .cub
or .cub5
or .cub5. Includes any tet meshes produced and therefore this output
can be useful for producing unstructured meshs for use in DAGMC
simulations.
cubit_path: the path to the Cubit directory used to import Cubit from. On
Ubuntu with Cubit 2021.5 this would be "/opt/Coreform-Cubit-2021.5/bin/"
merge_tolerance: The merge tolerance to apply when merging surfaces into
Expand Down Expand Up @@ -100,25 +107,29 @@ def cad_to_h5m(
geometry_details, total_number_of_volumes = find_number_of_volumes_in_each_step_file(
files_with_tags, cubit)
print(geometry_details)

scale_geometry(cubit, geometry_details)

tag_geometry_with_mats(geometry_details, cubit)

if imprint and total_number_of_volumes > 1:
imprint_geometry(cubit)
if total_number_of_volumes > 1:
merge_geometry(merge_tolerance, cubit)

# TODO method requires further testing
find_reflecting_surfaces_of_reflecting_wedge(
geometry_details, surface_reflectivity_name, cubit
)

create_tet_mesh(geometry_details, exo_filename, cubit)

save_output_files(
make_watertight,
geometry_details,
h5m_filename,
cubit_filename,
geometry_details_filename,
faceting_tolerance,
exo_filename,
cubit,
)
return h5m_filename
Expand All @@ -129,19 +140,25 @@ def create_tet_mesh(geometry_details, exo_filename, cubit):

cubit.cmd("volume all size auto factor 5")
for entry in geometry_details:
print('entry=', entry)
if "tet_mesh" in entry.keys():
for volume in entry["volumes"]:
print('volume=', volume)
cubit.cmd(
"volume " + str(volume) + " size auto factor 6"
) # this number is the size of the mesh 1 is small 10 is large
cubit.cmd(
"volume all scheme tetmesh proximity layers off geometric sizing on")
cubit.cmd("volume all scheme tetmesh proximity layers off")
# example entry ' size 0.5'
cubit.cmd(f"volume {str(volume)} " + entry["tet_mesh"])
cubit.cmd(f"volume {volume} " + entry["tet_mesh"])
cubit.cmd("mesh volume " + str(volume))
print('meshed some volumes')

cubit.cmd(f'export mesh "{exo_filename}" overwrite')

def scale_geometry(cubit, geometry_details):
for entry in geometry_details:
if 'scale' in entry.keys():
cubit.cmd(
f'volume {" ".join(entry["volumes"])} scale {entry["scale"]}')


# def save_tet_details_to_json_file(
Expand All @@ -164,6 +181,7 @@ def save_output_files(
cubit_filename,
geometry_details_filename,
faceting_tolerance,
exo_filename,
cubit,
):
"""This saves the output files"""
Expand All @@ -173,9 +191,6 @@ def save_output_files(
with open(geometry_details_filename, "w") as outfile:
json.dump(geometry_details, outfile, indent=4)

if cubit_filename is not None:
cubit.cmd('save as "' + cubit_filename + '" overwrite')

Path(h5m_filename).parents[0].mkdir(parents=True, exist_ok=True)

print("using faceting_tolerance of ", faceting_tolerance)
Expand All @@ -194,6 +209,16 @@ def save_output_files(
+ '" faceting_tolerance '
+ str(faceting_tolerance)
)

create_tet_mesh(geometry_details, exo_filename, cubit)

if exo_filename is not None:
Path(exo_filename).parents[0].mkdir(parents=True, exist_ok=True)
cubit.cmd(f'export mesh "{exo_filename}" overwrite')

if cubit_filename is not None:
cubit.cmd('save as "' + cubit_filename + '" overwrite')

return h5m_filename


Expand Down Expand Up @@ -226,6 +251,8 @@ def find_all_surfaces_of_reflecting_wedge(new_vols, cubit):
print("surface_info_dict", surface_info_dict)
return surface_info_dict

# todo additional testing required


def find_reflecting_surfaces_of_reflecting_wedge(
geometry_details, surface_reflectivity_name, cubit
Expand Down
51 changes: 39 additions & 12 deletions tests/test_python_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ def setUp(self):
tar.extractall("tests")
tar.close()

url = "https://raw.githubusercontent.com/fusion-energy/neutronics_workflow/2f65bdeb802f2b1b25da683d13dcd2b29ffc9ed3/example_05_3D_unstructured_mesh_tally/stage_1_output/steel.stp"
urllib.request.urlretrieve(url, "tests/steel.stp")

def test_h5m_file_creation(self):
"""Checks that a h5m file is created from stp files when make_watertight
is set to false"""
Expand Down Expand Up @@ -140,34 +143,36 @@ def test_faceting_tolerance_increases_file_size(self):
def test_exo_file_creation_with_different_sizes(self):
"""Checks that a h5m file is created from stp files"""

os.system("rm umesh_3.exo")
os.system("rm umesh_2.exo")

cad_to_h5m(
files_with_tags=[
{
"cad_filename": "tests/fusion_example_for_openmc_using_paramak-0.0.1/stp_files/pf_coils.stp",
"cad_filename": "tests/steel.stp",
"material_tag": "mat1",
"tet_mesh": "size 3"}],
exo_filename="umesh_3.exo",
"tet_mesh": "size 2"
}],
exo_filename="umesh_2.exo",
)

assert Path("umesh_3.exo").is_file()
assert Path("umesh_2.exo").is_file()

os.system("rm umesh_10.exo")
os.system("rm umesh_3.exo")

cad_to_h5m(
files_with_tags=[
{
"cad_filename": "tests/fusion_example_for_openmc_using_paramak-0.0.1/stp_files/pf_coils.stp",
"cad_filename": "tests/steel.stp",
"material_tag": "mat1",
"tet_mesh": "size 10"}],
exo_filename="umesh_10.exo",
"tet_mesh": "size 3"
}],
exo_filename="umesh_3.exo",
)

assert Path("umesh_10.exo").is_file()
assert Path("umesh_3.exo").is_file()

assert (Path("umesh_10.exo").stat().st_size >
Path("umesh_3.exo").stat().st_size)
assert (Path("umesh_3.exo").stat().st_size >
Path("umesh_2.exo").stat().st_size)

def test_exo_file_creation_with_default_size(self):
"""Checks that a h5m file is created from stp files"""
Expand Down Expand Up @@ -226,3 +231,25 @@ def incorrect_suffix():
cubit_filename="output_file_with.not_correct_suffix",
)
self.assertRaises(ValueError, incorrect_suffix)

def test_h5m_file_creation_with_scaling(self):
"""Checks that a h5m file is created from stp files when make_watertight
is set to false"""

os.system("rm test_dagmc.h5m")

test_h5m_filename = "test_dagmc.h5m"

returned_filename = cad_to_h5m(
files_with_tags=[
{
"cad_filename": "tests/fusion_example_for_openmc_using_paramak-0.0.1/stp_files/blanket.stp",
"material_tag": "mat1",
"scale": 0.1,
}],
h5m_filename=test_h5m_filename,
)

assert Path(test_h5m_filename).is_file()
assert Path(returned_filename).is_file()
assert test_h5m_filename == returned_filename

0 comments on commit 3b21641

Please sign in to comment.