Last active
October 24, 2023 05:10
-
-
Save pshriwise/669019eda50c95e8aecf7e5c0d5ba11a to your computer and use it in GitHub Desktop.
How to swap materials in a DAGMC .h5m file using PyMOAB
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"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