{"action":"created","issue":{"url":"https://api.github.com/repos/mit-crpg/openmc/issues/471","labels_url":"https://api.github.com/repos/mit-crpg/openmc/issues/471/labels{/name}","comments_url":"https://api.github.com/repos/mit-crpg/openmc/issues/471/comments","events_url":"https://api.github.com/repos/mit-crpg/openmc/issues/471/events","html_url":"https://github.com/mit-crpg/openmc/pull/471","id":109636191,"number":471,"title":"Multi-Group Cross Section Generation Module","user":{"login":"wbinventor","id":209492,"avatar_url":"https://avatars.githubusercontent.com/u/209492?v=3","gravatar_id":"","url":"https://api.github.com/users/wbinventor","html_url":"https://github.com/wbinventor","followers_url":"https://api.github.com/users/wbinventor/followers","following_url":"https://api.github.com/users/wbinventor/following{/other_user}","gists_url":"https://api.github.com/users/wbinventor/gists{/gist_id}","starred_url":"https://api.github.com/users/wbinventor/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wbinventor/subscriptions","organizations_url":"https://api.github.com/users/wbinventor/orgs","repos_url":"https://api.github.com/users/wbinventor/repos","events_url":"https://api.github.com/users/wbinventor/events{/privacy}","received_events_url":"https://api.github.com/users/wbinventor/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/mit-crpg/openmc/labels/Other%20Enhancement","name":"Other Enhancement","color":"e102d8"},{"url":"https://api.github.com/repos/mit-crpg/openmc/labels/Python%20API","name":"Python API","color":"bfd4f2"},{"url":"https://api.github.com/repos/mit-crpg/openmc/labels/Tallies","name":"Tallies","color":"02e10c"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":23,"created_at":"2015-10-03T18:00:51Z","updated_at":"2015-10-11T16:09:21Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/mit-crpg/openmc/pulls/471","html_url":"https://github.com/mit-crpg/openmc/pull/471","diff_url":"https://github.com/mit-crpg/openmc/pull/471.diff","patch_url":"https://github.com/mit-crpg/openmc/pull/471.patch"},"body":"This PR adds a new `openmc.mgxs` module to the Python API for multi-group cross section generation. This [IPython Notebook example](https://gist.github.com/wbinventor/44027a0f36908ab5cd9a#file-openmc-mgxs-ipynb) illustrates the use of  `openmc.mgxs` and is a good first place to start for any reviewers to see the functionality encapsulated by the module.\r\n\r\nIt would be great to receive input on this post-processing feature extension from all of the core developers, but perhaps in particular from @nelsonag since you have also used OpenMC for multi-group cross section generation for some time now. In addition, I know of several CRPG'ers whom have expressed interest (or the necessity) in using OpenMC for multi-group cross section generation. @samuelshaner @geogunow @friedmud @mellis13 @Johnny0719 if you have any thoughts or ideas around this - in particular, whether the functionality illustrated in the example [IPython Notebook](https://gist.github.com/wbinventor/44027a0f36908ab5cd9a#file-openmc-mgxs-ipynb) could be made more useful for you - please chime in here!\r\n\r\nI'll try to highlight the biggest changes made by this PR in what follows.\r\n\r\n**OPENMC.MGXS**\r\nA new `openmc.mgxs` sub-module has been implemented for the Python API. This sub-module defines classes and routines to help users quickly and easily do the following:\r\n\r\n* **Input Generation** - generate the inputs needed to compute multi-group cross sections\r\n* **Data Processing** - perform post-processing of tally data to compute cross sections\r\n* **Data Manipulation** - extract, store and visualize multi-group cross sectionS\r\n\r\nFirst, a generic `openmc.mgxs.EnergyGroups` class is used to define an energy group structure.\r\nAn abstract `MultiGroupXS` class defines the core functionality for the three items above. The following subclasses of the abstract `MultiGroupXS` class have been implemented for various cross section types:\r\n\r\n* `TotalXS`\r\n* `TransportXS`\r\n* `AbsorptionXS`\r\n* `CaptureXS`\r\n* `FissionXS`\r\n* `NuFissionXS`\r\n* `ScatterXS`\r\n* `NuScatterXS`\r\n* `ScatterMatrixXS`\r\n* `NuScatterMatrixXS`\r\n* `Chi`\r\n\r\nThese classes provide an interface to generate the tally inputs as well as perform post-processing of OpenMC's tally data to compute the respective multi-group cross sections. In particular, each class includes the following methods defined at the abstract `MultiGroupXS` class level to view and retrieve (\"slice-n-dice\") cross section data:\r\n\r\n* `MultiGroupXS.print_xs(...)` - print a formatted report of the cross section data\r\n* `MultiGroupXS.get_xs(...)` - extract cross sectionS for some set of nuclides and/or energy groups\r\n* `MultiGroupXS.get_pandas_dataframe(...)` - get a Pandas DataFrame of the cross section data\r\n\r\nSimilarly, these methods make it easy for users to export cross sections to a file for later use:\r\n\r\n* `MultiGroupXS.build_hdf5_store(...)` - build an HDF5 data store of the cross sections\r\n* `MultiGroupXS.export_xs_data(...)` - export cross sections to CSV, Excel or LaTeX formats\r\n\r\nFinally, some methods are defined to perform group condensation and spatial homogenization:\r\n\r\n* `MultiGroupXS.get_condensed_xs(coarse_groups)` - build condensed cross section using coarse groups\r\n* `MultiGroupXS.get_subdomain_avg_xs(subdomains)` - perform spatial homogenization across one, some or all spatial \"subdomains\" (*e.g.*, only distribcell instances are supported now, but cartesian mesh cells could potentially be implemented as well)\r\n\r\nThe `MultiGroupXS` class currently supports spatial domains over materials, cells, distribcells and universes. This is defined through the `MultiGroupXS.domain` instance attribute along with `MultiGroupXS.domain_type` attribute (which is albeit a little clunky, but allows one to easily switch between 'cell' and 'distribcell' for the same cell spatial domain). It forseeably would be straightforward to support mesh spatial subdomains as well (*e.g.*, cartesian tally meshes) but I haven't yet implemented or tested this since it isn't relevant to my needs.\r\n\r\n`MultiGroupXS` class wil compute macroscopic cross sections for all nuclides in the spatial domain by default. It is very easy to instead tally unique cross sections for each nuclide by setting the `MultiGroupXS.by_nuclide` instance attribute to `True` as is illustrated in the IPython Notebook example. Many of the methods for data visualization and storage accept a `nuclides` paramter which may be used to select all nuclides (*e.g.*, nuclides='all'), the sum across nuclides (*e.g.*, nuclides='sum'), or some subset of nuclides (*e.g.*, nuclides=['U-235', 'U-238']).\r\n\r\nFinally, I added the example IPython Notebook to the documentation as an example of how to use `openmc.mgxs`. I should note here that in the Notebook I verify the multi-group cross sections using [OpenMOC](https://mit-crpg.github.io/OpenMOC/), along with OpenCG to assist in transferring data between OpenMC's and OpenMOC's meshes. If @paulromano feels like this is a bit too much of a shameless plug for OpenMOC, I'm happy to remove those portions of the Notebook (and perhaps just do analytical verification of 1- and 2-group cross-sections for an infinite medium).\r\n\r\n**Tally Arithmetic**\r\nThis PR also adds some new functionality to make tally arithmetic easier to use by `openmc.mgxs`. In particular, the following new routines have been added to the `Tally` class\r\n\r\n* `Tally.summation(...)` - create derived tally as sum across some nuclides, scores and filter bins\r\n* `Tally.swap_filter(filter1, filter2)` - swap two filters and adjust tally data accordingly\r\n* `Tally.diagonalize_filter(new_filter)` - add new filter and diagonalize along its bins\r\n\r\nIn addition, the \"tally outer product\" concept was previously used if two tally operands did not have exactly the same set of filters. Now, an outer product is only created for those filters which are not shared between the two tally operands."},"comment":{"url":"https://api.github.com/repos/mit-crpg/openmc/issues/comments/147214191","html_url":"https://github.com/mit-crpg/openmc/pull/471#issuecomment-147214191","issue_url":"https://api.github.com/repos/mit-crpg/openmc/issues/471","id":147214191,"user":{"login":"smharper","id":4622797,"avatar_url":"https://avatars.githubusercontent.com/u/4622797?v=3","gravatar_id":"","url":"https://api.github.com/users/smharper","html_url":"https://github.com/smharper","followers_url":"https://api.github.com/users/smharper/followers","following_url":"https://api.github.com/users/smharper/following{/other_user}","gists_url":"https://api.github.com/users/smharper/gists{/gist_id}","starred_url":"https://api.github.com/users/smharper/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/smharper/subscriptions","organizations_url":"https://api.github.com/users/smharper/orgs","repos_url":"https://api.github.com/users/smharper/repos","events_url":"https://api.github.com/users/smharper/events{/privacy}","received_events_url":"https://api.github.com/users/smharper/received_events","type":"User","site_admin":false},"created_at":"2015-10-11T16:09:21Z","updated_at":"2015-10-11T16:09:21Z","body":"@wbinventor, usually when I get these mysterious CI failures, I'll add a line to run_tests.py that prints out the log file.  Look at lines 464-472.  Right after it does the `shutil.copy` you can add a\r\n```python\r\nwith open(logfilename) as fh: print(fh.read())\r\n```\r\nThen you can search the Travis log for \"Fail\" to find your error."}}