Skip to content

Instantly share code, notes, and snippets.

@pshriwise
Last active October 24, 2023 05:10
Show Gist options
  • Save pshriwise/669019eda50c95e8aecf7e5c0d5ba11a to your computer and use it in GitHub Desktop.
Save pshriwise/669019eda50c95e8aecf7e5c0d5ba11a to your computer and use it in GitHub Desktop.
How to swap materials in a DAGMC .h5m file using PyMOAB
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"id": "a2f828c3-4a43-4c5d-81c5-70bff5106204",
"metadata": {},
"source": [
"To install pymoab to Python env, use `pip install` in `pymoab` subdirectory of the MOAB build dir (after building MOAB)."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "be172f88-d0fd-40f9-852e-dab58e606400",
"metadata": {},
"outputs": [],
"source": [
"from pymoab import core, types, rng"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "ff0a5c55-9a7f-4eac-8aab-971e2a26a834",
"metadata": {},
"outputs": [],
"source": [
"mb = core.Core()"
]
},
{
"cell_type": "markdown",
"id": "7eed05b9-fa3b-4880-b7e3-753b01a8d2b9",
"metadata": {},
"source": [
"## TAG info\n",
"\n",
" - ID tag: Volume/Surface IDs\n",
" - Name tag: metadata assignment values\n",
" - Category tag: Identifies what the mesh set is (\"Category\", \"Volume\", \"Surface\", etc.)\n"
]
},
{
"cell_type": "markdown",
"id": "c3145cfe-75a6-4348-bdef-33842cb0a3fa",
"metadata": {},
"source": [
"## Metadata structure\n",
"\n",
"There are entitysets for different geometric constructs\n",
"\n",
"**Volume** (empty) --> **Surface A** (triangles)\n",
" --> **Surface B** (triangles)\n",
"\n",
"\n",
"**Groups** (Volumes for materials or Surfaces for BC's)\n",
"\n",
"\n",
"Groups are tagged with a \"name\" tag to indicate the metadata they are applying to the contained entity sets."
]
},
{
"cell_type": "markdown",
"id": "41cd2c5c-86b0-4d68-9924-43d61943a9b3",
"metadata": {},
"source": [
"## Swap Volume Material Assignment\n",
"\n",
"**Group A** (Volume 1... Volume of intereset .. Volume N)\n",
"**Group B** (Volumes...)\n",
"\n",
" - Identify which group the volume is in\n",
" - Identify which group the volume needs to go to\n",
" - Remove from group A\n",
" - Add to group B"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "7efbc444-0423-4f2b-95f6-454e71b03c31",
"metadata": {},
"outputs": [],
"source": [
"mb.load_file('/home/pshriwise/repos/msre/h5m/msre_control_rod_1e-2.h5m')"
]
},
{
"cell_type": "code",
"execution_count": 67,
"id": "b971b3e4",
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"\n",
"_cat_tag = mb.tag_get_handle(types.CATEGORY_TAG_NAME)\n",
"_id_tag = mb.tag_get_handle(types.GLOBAL_ID_TAG_NAME)\n",
"_name_tag = mb.tag_get_handle(types.NAME_TAG_NAME)\n",
"\n",
"\n",
"def get_groups(mb):\n",
" group_handles = mb.get_entities_by_type_and_tag(mb.get_root_set(), types.MBENTITYSET, [_cat_tag], ['Group'])\n",
" groups = [Group(mb, group_handle) for group_handle in group_handles]\n",
" return {g.name: g for g in groups}\n",
"\n",
"\n",
"class DAGSet:\n",
"\n",
" def __init__(self, mb, handle):\n",
" self.mb = mb\n",
" self.handle = handle\n",
"\n",
" def __eq__(self, other):\n",
" return self.handle == other.handle\n",
" \n",
" @property\n",
" def id(self):\n",
" return mb.tag_get_data(_id_tag, self.handle, flat=True)[0]\n",
"\n",
" @property\n",
" def name(self):\n",
" return mb.tag_get_data(_name_tag, self.handle, flat=True)[0]\n",
"\n",
" def to_vtk(self, filename):\n",
" tmp_set = mb.create_meshset()\n",
" mb.add_entities(tmp_set, self._get_triangle_sets())\n",
" if not filename.endswith('.vtk'):\n",
" filename += '.vtk'\n",
" mb.write_file(filename, output_sets=[tmp_set])\n",
" mb.delete_entity(tmp_set)\n",
" \n",
"class DAGGeomSet(DAGSet):\n",
"\n",
" def __repr__(self):\n",
" return f'{type(self).__name__} {self.id}, {self.num_triangles()} triangles'\n",
"\n",
" def get_triangles(self):\n",
" r = rng.Range()\n",
" for s in self._get_triangle_sets():\n",
" r.merge(self.mb.get_entities_by_type(s.handle, types.MBTRI))\n",
" return r\n",
"\n",
"class Surface(DAGGeomSet):\n",
"\n",
" def get_volumes(self):\n",
" return [Volume(self.mb, h) for h in self.mb.get_parent_meshsets(self.handle)]\n",
"\n",
" def num_triangles(self):\n",
" return len(self.get_triangles())\n",
"\n",
" def _get_triangle_sets(self):\n",
" return [self]\n",
" \n",
"class Volume(DAGGeomSet):\n",
"\n",
" def get_surfaces(self):\n",
" surfs = [Surface(self.mb, h) for h in self.mb.get_child_meshsets(self.handle)]\n",
" return {s.id: s for s in surfs}\n",
"\n",
" def num_triangles(self):\n",
" return sum([s.num_triangles() for s in self.get_surfaces()])\n",
"\n",
" def _get_triangle_sets(self):\n",
" return [s.handle for s in self.get_surfaces().values()]\n",
" \n",
"class Group(DAGSet):\n",
"\n",
" def _get_geom_ent_by_id(self, entity_type, id):\n",
" category_ents = mb.get_entities_by_type_and_tag(self.handle, types.MBENTITYSET, [_cat_tag], [entity_type])\n",
" ids = mb.tag_get_data(_id_tag, category_ents, flat=True)\n",
" return category_ents[int(np.where(ids == id)[0][0])]\n",
"\n",
" def _remove_geom_ent_by_id(self, entity_type, id):\n",
" geom_ent = self._get_geom_ent_by_id(entity_type, id)\n",
" self.mb.remove_entities(self.handle, [geom_ent])\n",
"\n",
" def _get_triangle_sets(self):\n",
" \"\"\"Return any sets containing triangles\"\"\"\n",
" output = set()\n",
" output.update(self._get_geom_ent_sets('Surfaces'))\n",
" for v in self.get_volumes().values():\n",
" output.update(v._get_triangle_sets())\n",
" return list(output)\n",
" \n",
" def _get_geom_ent_sets(self, entity_type):\n",
" return mb.get_entities_by_type_and_tag(self.handle, types.MBENTITYSET, [_cat_tag], [entity_type])\n",
"\n",
" def _get_geom_ent_ids(self, entity_type):\n",
" return mb.tag_get_data(_id_tag, self._get_geom_ent_sets(entity_type), flat=True) \n",
"\n",
" def get_volumes(self):\n",
" vols = [Volume(self.mb, v) for v in self._get_geom_ent_sets('Volume')]\n",
" return {v.id: v for v in vols}\n",
" \n",
" def get_surfaces(self):\n",
" surfs = [Surface(self.mb, s) for s in self._get_geom_ent_sets('Surface')]\n",
" return {s.id: s for s in surfs}\n",
" \n",
" def get_volume_ids(self):\n",
" return self._get_geom_ent_ids('Volume')\n",
"\n",
" def get_surface_ids(self):\n",
" return self._get_geom_ent_ids('Surface')\n",
"\n",
" def remove_set(self, vol):\n",
" if isinstance(vol, DAGGeomSet):\n",
" self.mb.remove_entities(self.handle, [vol.handle])\n",
" else:\n",
" self.mb.remove_entities(self.handle, [vol])\n",
" \n",
" def add_set(self, entity):\n",
" if isinstance(entity, DAGGeomSet):\n",
" self.mb.add_entities(self.handle, [entity.handle])\n",
" else:\n",
" self.mb.add_entities(self.handle, [entity])\n",
" \n",
" def __repr__(self):\n",
" out = f'Group {self.id}, Name: {self.name}\\n'\n",
"\n",
" vol_ids = self.get_volume_ids()\n",
" if vol_ids.size:\n",
" out += 'Volume IDs:\\n'\n",
" out += f'{vol_ids}\\n'\n",
"\n",
" surf_ids = self.get_surface_ids()\n",
" if surf_ids.size:\n",
" out += 'Surface IDs:\\n'\n",
" out += f'{surf_ids}\\n'\n",
" return out\n"
]
},
{
"cell_type": "code",
"execution_count": 68,
"id": "88654b4c-390c-4eed-9970-8d3e5bde5941",
"metadata": {},
"outputs": [],
"source": [
"group_sets_dict = get_groups(mb)"
]
},
{
"cell_type": "code",
"execution_count": 69,
"id": "6a718665-0c7c-4d02-aff3-23ab910f08e9",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'picked': Group 1, Name: picked,\n",
" 'Msre_control_rod.step': Group 2, Name: Msre_control_rod.step\n",
" Volume IDs:\n",
" [ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18\n",
" 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36\n",
" 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54\n",
" 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72\n",
" 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90\n",
" 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108\n",
" 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126],\n",
" 'mat:inor-8': Group 3, Name: mat:inor-8\n",
" Volume IDs:\n",
" [ 1 5 6 7 9 10 11 16 17 18 19 20 21 22 25 30 31 33\n",
" 34 39 40 42 43 44 45 47 48 49 52 53 54 56 57 58 59 60\n",
" 62 63 64 65 66 69 71 72 75 77 78 79 80 81 82 83 84 86\n",
" 87 88 89 91 92 93 94 95 97 99 100 101 102 103 104 105 106 107\n",
" 109 111 113 115 117 118 119 124 125 126],\n",
" 'mat:bush': Group 4, Name: mat:bush\n",
" Volume IDs:\n",
" [ 2 3 4 8 12 14 15 23 24 26 27 28 29 32 35 36 37 38\n",
" 41 46 50 51 55 61 68 70 73 74 76 85 90 96 108 110 112 114\n",
" 116 120 121 122 123],\n",
" 'mat:inconel': Group 5, Name: mat:inconel\n",
" Volume IDs:\n",
" [ 6 13 67],\n",
" 'mat:ss316': Group 6, Name: mat:ss316\n",
" Volume IDs:\n",
" [98],\n",
" 'gr_surfs_merged': Group 7, Name: gr_surfs_merged\n",
" Surface IDs:\n",
" [ 1 6 28 33 43 48 58 63 86 87 92 97 116 117\n",
" 136 148 153 172 173 187 188 193 198 232 233 238 243 261\n",
" 266 301 302 316 317 326 331 350 351 372 377 406 411 430\n",
" 431 436 441 494 495 500 505 523 528 538 543 562 563 572\n",
" 577 596 597 632 637 660 661 696 701 733 738 761 762 799\n",
" 800 893 894 957 958 978 983 1012 1017 1057 1062 1109 1340 1345\n",
" 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448\n",
" 1453 1454 1459 1460 1467 1468 1469 1470 1475 1476 1481 1482 1487 1488\n",
" 1489 1490 1491 1492 1493 1497 1498 1499 1500 1501 1502 1503 1504 1509\n",
" 1510 1515 1516 1521 1522 1527 1528 1530 1532 1539 1540 1545 1546 1547\n",
" 1548 1549 1550 1551 1552 1559 1560 1561 1562 1563 1564 1565 1566 1567\n",
" 1568 1569 1570 1571 1572 1573 1574 1575 1576 1589 1590 1597 1598 1605\n",
" 1606 1607 1608 1609 1610 1613 1614 1615 1616 1617 1618 1625 1626 1628\n",
" 1630 1633 1634 1641 1642 1653 1654 1661 1662 1683 1684 1685 1686 1695\n",
" 1696 1709 1710 1717 1718 1732 1734 1743 1744 1751 1752 1769 1770 1772\n",
" 1774 1779 1780 1789 1790 1800 1802 1805 1806 1807 1808 1809 1810 1817\n",
" 1818 1819 1820 1821 1822 1824 1826 1857 1858 1860 1862 1871 1872 1897\n",
" 1898 1922 1924 1958 1960 1970 1972 2009 2010 2024 2026]}"
]
},
"execution_count": 69,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"group_sets_dict"
]
},
{
"cell_type": "markdown",
"id": "35e31871-5113-4a01-ada4-c3d2a9604b88",
"metadata": {},
"source": [
"Move Volume 6 from `mat:inor-8` to `mat:inconel`\n",
"\n",
"```\n",
"Group name: mat:inor-8\n",
"\t Idx: 0, Category: Volume, ID: 1\n",
"\t Idx: 1, Category: Volume, ID: 5\n",
"\t Idx: 2, Category: Volume, ID: 6\n",
"\t Idx: 3, Category: Volume, ID: 7\n",
"\t Idx: 4, Category: Volume, ID: 9\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": 70,
"id": "fc4b2454-699c-4b28-b68b-5b197f08be56",
"metadata": {},
"outputs": [],
"source": [
"volume_to_move = group_sets_dict['mat:inor-8'].get_volumes()[6]"
]
},
{
"cell_type": "code",
"execution_count": 71,
"id": "441f4ff0-8c96-4cf2-ad27-cc53768e205b",
"metadata": {},
"outputs": [],
"source": [
"group_sets_dict['mat:inconel'].add_set(volume_to_move)\n",
"group_sets_dict['mat:inor-8'].remove_set(volume_to_move)"
]
},
{
"cell_type": "code",
"execution_count": 72,
"id": "759ca680-3b6d-444f-b121-4cc658492a50",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[Group 1, Name: picked\n",
", Group 2, Name: Msre_control_rod.step\n",
"Volume IDs:\n",
"[ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18\n",
" 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36\n",
" 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54\n",
" 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72\n",
" 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90\n",
" 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108\n",
" 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126]\n",
", Group 3, Name: mat:inor-8\n",
"Volume IDs:\n",
"[ 1 5 7 9 10 11 16 17 18 19 20 21 22 25 30 31 33 34\n",
" 39 40 42 43 44 45 47 48 49 52 53 54 56 57 58 59 60 62\n",
" 63 64 65 66 69 71 72 75 77 78 79 80 81 82 83 84 86 87\n",
" 88 89 91 92 93 94 95 97 99 100 101 102 103 104 105 106 107 109\n",
" 111 113 115 117 118 119 124 125 126]\n",
", Group 4, Name: mat:bush\n",
"Volume IDs:\n",
"[ 2 3 4 8 12 14 15 23 24 26 27 28 29 32 35 36 37 38\n",
" 41 46 50 51 55 61 68 70 73 74 76 85 90 96 108 110 112 114\n",
" 116 120 121 122 123]\n",
", Group 5, Name: mat:inconel\n",
"Volume IDs:\n",
"[ 6 13 67]\n",
", Group 6, Name: mat:ss316\n",
"Volume IDs:\n",
"[98]\n",
", Group 7, Name: gr_surfs_merged\n",
"Surface IDs:\n",
"[ 1 6 28 33 43 48 58 63 86 87 92 97 116 117\n",
" 136 148 153 172 173 187 188 193 198 232 233 238 243 261\n",
" 266 301 302 316 317 326 331 350 351 372 377 406 411 430\n",
" 431 436 441 494 495 500 505 523 528 538 543 562 563 572\n",
" 577 596 597 632 637 660 661 696 701 733 738 761 762 799\n",
" 800 893 894 957 958 978 983 1012 1017 1057 1062 1109 1340 1345\n",
" 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448\n",
" 1453 1454 1459 1460 1467 1468 1469 1470 1475 1476 1481 1482 1487 1488\n",
" 1489 1490 1491 1492 1493 1497 1498 1499 1500 1501 1502 1503 1504 1509\n",
" 1510 1515 1516 1521 1522 1527 1528 1530 1532 1539 1540 1545 1546 1547\n",
" 1548 1549 1550 1551 1552 1559 1560 1561 1562 1563 1564 1565 1566 1567\n",
" 1568 1569 1570 1571 1572 1573 1574 1575 1576 1589 1590 1597 1598 1605\n",
" 1606 1607 1608 1609 1610 1613 1614 1615 1616 1617 1618 1625 1626 1628\n",
" 1630 1633 1634 1641 1642 1653 1654 1661 1662 1683 1684 1685 1686 1695\n",
" 1696 1709 1710 1717 1718 1732 1734 1743 1744 1751 1752 1769 1770 1772\n",
" 1774 1779 1780 1789 1790 1800 1802 1805 1806 1807 1808 1809 1810 1817\n",
" 1818 1819 1820 1821 1822 1824 1826 1857 1858 1860 1862 1871 1872 1897\n",
" 1898 1922 1924 1958 1960 1970 1972 2009 2010 2024 2026]\n",
"]\n"
]
}
],
"source": [
"print(groups)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "9cd9d409-d769-4da2-b396-8a2946beb5f2",
"metadata": {},
"outputs": [],
"source": [
"mb.write_file('msre_control_rod_1e-2_swap.h5m')"
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "5aad95c6-0b4a-45bc-a302-1a628ffda5fd",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Volume 1, 20350 triangles"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"v"
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "26496a84-cd0a-4999-801f-755f641abb85",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[Surface 1, 96 triangles,\n",
" Surface 3, 72 triangles,\n",
" Surface 5, 72 triangles,\n",
" Surface 6, 97 triangles,\n",
" Surface 7, 3656 triangles,\n",
" Surface 8, 158 triangles,\n",
" Surface 9, 2597 triangles,\n",
" Surface 10, 171 triangles,\n",
" Surface 11, 4168 triangles,\n",
" Surface 12, 193 triangles,\n",
" Surface 13, 4624 triangles,\n",
" Surface 14, 2371 triangles,\n",
" Surface 15, 1643 triangles,\n",
" Surface 1431, 72 triangles,\n",
" Surface 1432, 72 triangles,\n",
" Surface 1433, 72 triangles,\n",
" Surface 1434, 72 triangles,\n",
" Surface 1435, 72 triangles,\n",
" Surface 1436, 72 triangles]"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"v.get_surfaces()"
]
},
{
"cell_type": "code",
"execution_count": 20,
"id": "cc4fa1d2-9ba1-420f-8f37-9e23c6a51134",
"metadata": {},
"outputs": [],
"source": [
"s = v.get_surfaces()[3]"
]
},
{
"cell_type": "code",
"execution_count": 22,
"id": "4067546c-2d1c-487a-8141-c9f3d18c8730",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[Volume 1, 20350 triangles, Volume 77, 20338 triangles]"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"s.get_volumes()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.1"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment