mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-21 14:35:27 -04:00
1091 lines
35 KiB
Text
1091 lines
35 KiB
Text
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"This IPython Notebook introduces the use of the `openmc.mgxs` module to calculate multi-group cross sections for an infinite homogeneous medium. In particular, this Notebook introduces the the following features:\n",
|
|
"\n",
|
|
"* Creation of multi-group cross sections for an **infinite homogeneous medium**\n",
|
|
"* Use of **tally arithmetic** to manipulate multi-group cross sections\n",
|
|
"\n",
|
|
"**Note:** This Notebook illustrates the use of Pandas DataFrames to containerize multi-group cross section data. We recommend using Pandas >v0.15.0 or later since OpenMC's Python API leverages the multi-indexing feature included in the most recent releases."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"import numpy as np\n",
|
|
"import matplotlib.pyplot as plt\n",
|
|
"\n",
|
|
"import openmc\n",
|
|
"import openmc.mgxs as mgxs\n",
|
|
"\n",
|
|
"%matplotlib inline"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"We first construct a simple homogeneous infinite medium problem to illustrate use of the `openmc.mgxs` module to generate multi-group cross sections."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Generate Input Files"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"First we need to define materials that will be used in the problem. Before defining a material, we must create nuclides that are used in the material."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"metadata": {
|
|
"collapsed": true
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Instantiate some Nuclides\n",
|
|
"h1 = openmc.Nuclide('H-1')\n",
|
|
"o16 = openmc.Nuclide('O-16')\n",
|
|
"u235 = openmc.Nuclide('U-235')\n",
|
|
"u238 = openmc.Nuclide('U-238')\n",
|
|
"zr90 = openmc.Nuclide('Zr-90')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"With the nuclides we defined, we will now create a material for the homogeneous medium."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"metadata": {
|
|
"collapsed": true
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Instantiate a Material and register the Nuclides\n",
|
|
"inf_medium = openmc.Material(name='moderator')\n",
|
|
"inf_medium.set_density('g/cc', 5.)\n",
|
|
"inf_medium.add_nuclide(h1, 0.028999667)\n",
|
|
"inf_medium.add_nuclide(o16, 0.01450188)\n",
|
|
"inf_medium.add_nuclide(u235, 0.000114142)\n",
|
|
"inf_medium.add_nuclide(u238, 0.006886019)\n",
|
|
"inf_medium.add_nuclide(zr90, 0.002116053)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"With our material, we can now create a materials file object that can be exported to an actual XML file."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"metadata": {
|
|
"collapsed": true
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Instantiate a MaterialsFile, register all Materials, and export to XML\n",
|
|
"materials_file = openmc.MaterialsFile()\n",
|
|
"materials_file.default_xs = '71c'\n",
|
|
"materials_file.add_material(inf_medium)\n",
|
|
"materials_file.export_to_xml()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Now let's move on to the geometry. This problem will be a simple square cell with reflective boundary conditions to simulate an infinite homogeneous medium. The first step is to create the outer bounding surfaces of the problem."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 5,
|
|
"metadata": {
|
|
"collapsed": true
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Instantiate boundary Planes\n",
|
|
"min_x = openmc.XPlane(boundary_type='reflective', x0=-0.63)\n",
|
|
"max_x = openmc.XPlane(boundary_type='reflective', x0=0.63)\n",
|
|
"min_y = openmc.YPlane(boundary_type='reflective', y0=-0.63)\n",
|
|
"max_y = openmc.YPlane(boundary_type='reflective', y0=0.63)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"With the surfaces defined, we can now create a cell that is defined by intersections of half-spaces created by the surfaces."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 6,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Instantiate a Cell\n",
|
|
"cell = openmc.Cell(cell_id=1, name='cell')\n",
|
|
"\n",
|
|
"# Register bounding Surfaces with the Cell\n",
|
|
"cell.region = +min_x & -max_x & +min_y & -max_y\n",
|
|
"\n",
|
|
"# Fill the Cell with the Material\n",
|
|
"cell.fill = inf_medium"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"OpenMC requires that there is a \"root\" universe. Let us create a root universe and add our square cell to it."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 7,
|
|
"metadata": {
|
|
"collapsed": true
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Instantiate Universe\n",
|
|
"root_universe = openmc.Universe(universe_id=0, name='root universe')\n",
|
|
"root_universe.add_cell(cell)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"We now must create a geometry that is assigned a root universe, put the geometry into a geometry file, and export it to XML."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 8,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Create Geometry and set root Universe\n",
|
|
"openmc_geometry = openmc.Geometry()\n",
|
|
"openmc_geometry.root_universe = root_universe\n",
|
|
"\n",
|
|
"# Instantiate a GeometryFile\n",
|
|
"geometry_file = openmc.GeometryFile()\n",
|
|
"geometry_file.geometry = openmc_geometry\n",
|
|
"\n",
|
|
"# Export to \"geometry.xml\"\n",
|
|
"geometry_file.export_to_xml()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Next, we must define simulation parameters. In this case, we will use 10 inactive batches and 40 active batches each with 2500 particles."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 9,
|
|
"metadata": {
|
|
"collapsed": true
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# OpenMC simulation parameters\n",
|
|
"batches = 50\n",
|
|
"inactive = 10\n",
|
|
"particles = 2500\n",
|
|
"\n",
|
|
"# Instantiate a SettingsFile\n",
|
|
"settings_file = openmc.SettingsFile()\n",
|
|
"settings_file.batches = batches\n",
|
|
"settings_file.inactive = inactive\n",
|
|
"settings_file.particles = particles\n",
|
|
"settings_file.output = {'tallies': True, 'summary': True}\n",
|
|
"bounds = [-0.63, -0.63, -0.63, 0.63, 0.63, 0.63]\n",
|
|
"settings_file.set_source_space('fission', bounds)\n",
|
|
"\n",
|
|
"# Export to \"settings.xml\"\n",
|
|
"settings_file.export_to_xml()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Now we are ready to generate multi-group cross sections! First, let's define a 2-group structure using the built-in `EnergyGroups` class."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 10,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Instantiate a 2-group EnergyGroups object\n",
|
|
"groups = mgxs.EnergyGroups()\n",
|
|
"groups.group_edges = np.array([0., 0.625e-6, 20.])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"We can now use the fine and coarse `EnergyGroups` objects, along with our previously created materials and geometry, to instantiate some `MGXS` objects from the `openmc.mgxs` module. In particular, the following are subclasses of the generic and abstract `MGXS` class:\n",
|
|
"\n",
|
|
"* `TotalXS`\n",
|
|
"* `TransportXS`\n",
|
|
"* `AbsorptionXS`\n",
|
|
"* `CaptureXS`\n",
|
|
"* `FissionXS`\n",
|
|
"* `NuFissionXS`\n",
|
|
"* `ScatterXS`\n",
|
|
"* `NuScatterXS`\n",
|
|
"* `ScatterMatrixXS`\n",
|
|
"* `NuScatterMatrixXS`\n",
|
|
"* `Chi`\n",
|
|
"\n",
|
|
"These classes provide us with 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 this case, let's create the multi-group total, absorption and scattering cross sections with our 2-group structure."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 11,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Instantiate a few different sections\n",
|
|
"total = mgxs.TotalXS(domain=cell, domain_type='cell', groups=groups)\n",
|
|
"absorption = mgxs.AbsorptionXS(domain=cell, domain_type='cell', groups=groups)\n",
|
|
"scattering = mgxs.ScatterXS(domain=cell, domain_type='cell', groups=groups)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Each multi-group cross section object stores its tallies in a Python dictionary called `tallies`. We can inspect the tallies in the dictionary for our `Absorption` object as follows. "
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 12,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"OrderedDict([('flux', Tally\n",
|
|
"\tID =\t10000\n",
|
|
"\tName =\t\n",
|
|
"\tFilters =\t\n",
|
|
" \t\tcell\t[1]\n",
|
|
" \t\tenergy\t[ 0.00000000e+00 6.25000000e-07 2.00000000e+01]\n",
|
|
"\tNuclides =\ttotal \n",
|
|
"\tScores =\t['flux']\n",
|
|
"\tEstimator =\ttracklength\n",
|
|
"), ('absorption', Tally\n",
|
|
"\tID =\t10001\n",
|
|
"\tName =\t\n",
|
|
"\tFilters =\t\n",
|
|
" \t\tcell\t[1]\n",
|
|
" \t\tenergy\t[ 0.00000000e+00 6.25000000e-07 2.00000000e+01]\n",
|
|
"\tNuclides =\ttotal \n",
|
|
"\tScores =\t['absorption']\n",
|
|
"\tEstimator =\ttracklength\n",
|
|
")])"
|
|
]
|
|
},
|
|
"execution_count": 12,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"absorption.tallies"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"The `Absorption` object includes tracklength tallies for the 'absorption' and 'flux' scores in the 2-group structure in cell 1. Now that each multi-group cross section object contains the tallies that it needs, we must add these tallies to a `TalliesFile` object to generate the \"tallies.xml\" input file for OpenMC."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 13,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Instantiate an empty TalliesFile\n",
|
|
"tallies_file = openmc.TalliesFile()\n",
|
|
"\n",
|
|
"# Add total tallies to the tallies file\n",
|
|
"for tally in total.tallies.values():\n",
|
|
" tallies_file.add_tally(tally)\n",
|
|
"\n",
|
|
"# Add absorption tallies to the tallies file\n",
|
|
"for tally in absorption.tallies.values():\n",
|
|
" tallies_file.add_tally(tally)\n",
|
|
"\n",
|
|
"# Add scattering tallies to the tallies file\n",
|
|
"for tally in scattering.tallies.values():\n",
|
|
" tallies_file.add_tally(tally)\n",
|
|
" \n",
|
|
"# Export to \"tallies.xml\"\n",
|
|
"tallies_file.export_to_xml()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Now we a have a complete set of inputs, so we can go ahead and run our simulation."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 14,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\n",
|
|
" .d88888b. 888b d888 .d8888b.\n",
|
|
" d88P\" \"Y88b 8888b d8888 d88P Y88b\n",
|
|
" 888 888 88888b.d88888 888 888\n",
|
|
" 888 888 88888b. .d88b. 88888b. 888Y88888P888 888 \n",
|
|
" 888 888 888 \"88b d8P Y8b 888 \"88b 888 Y888P 888 888 \n",
|
|
" 888 888 888 888 88888888 888 888 888 Y8P 888 888 888\n",
|
|
" Y88b. .d88P 888 d88P Y8b. 888 888 888 \" 888 Y88b d88P\n",
|
|
" \"Y88888P\" 88888P\" \"Y8888 888 888 888 888 \"Y8888P\"\n",
|
|
"__________________888______________________________________________________\n",
|
|
" 888\n",
|
|
" 888\n",
|
|
"\n",
|
|
" Copyright: 2011-2015 Massachusetts Institute of Technology\n",
|
|
" License: http://mit-crpg.github.io/openmc/license.html\n",
|
|
" Version: 0.7.0\n",
|
|
" Git SHA1: c4b14a5ef87f004528d35cbf33fef3ed15a386ca\n",
|
|
" Date/Time: 2015-11-29 17:50:29\n",
|
|
" MPI Processes: 1\n",
|
|
"\n",
|
|
" ===========================================================================\n",
|
|
" ========================> INITIALIZATION <=========================\n",
|
|
" ===========================================================================\n",
|
|
"\n",
|
|
" Reading settings XML file...\n",
|
|
" Reading cross sections XML file...\n",
|
|
" Reading geometry XML file...\n",
|
|
" Reading materials XML file...\n",
|
|
" Reading tallies XML file...\n",
|
|
" Building neighboring cells lists for each surface...\n",
|
|
" Loading ACE cross section table: 1001.71c\n",
|
|
" Loading ACE cross section table: 8016.71c\n",
|
|
" Loading ACE cross section table: 92235.71c\n",
|
|
" Loading ACE cross section table: 92238.71c\n",
|
|
" Loading ACE cross section table: 40090.71c\n",
|
|
" Maximum neutron transport energy: 20.0000 MeV for 1001.71c\n",
|
|
" Initializing source particles...\n",
|
|
"\n",
|
|
" ===========================================================================\n",
|
|
" ====================> K EIGENVALUE SIMULATION <====================\n",
|
|
" ===========================================================================\n",
|
|
"\n",
|
|
" Bat./Gen. k Average k \n",
|
|
" ========= ======== ==================== \n",
|
|
" 1/1 1.19804 \n",
|
|
" 2/1 1.12945 \n",
|
|
" 3/1 1.15573 \n",
|
|
" 4/1 1.13929 \n",
|
|
" 5/1 1.16300 \n",
|
|
" 6/1 1.22117 \n",
|
|
" 7/1 1.19012 \n",
|
|
" 8/1 1.11299 \n",
|
|
" 9/1 1.16066 \n",
|
|
" 10/1 1.12566 \n",
|
|
" 11/1 1.20854 \n",
|
|
" 12/1 1.14691 1.17773 +/- 0.03082\n",
|
|
" 13/1 1.17204 1.17583 +/- 0.01789\n",
|
|
" 14/1 1.14148 1.16724 +/- 0.01529\n",
|
|
" 15/1 1.17272 1.16834 +/- 0.01189\n",
|
|
" 16/1 1.18575 1.17124 +/- 0.01014\n",
|
|
" 17/1 1.20498 1.17606 +/- 0.00983\n",
|
|
" 18/1 1.14754 1.17249 +/- 0.00923\n",
|
|
" 19/1 1.18141 1.17348 +/- 0.00820\n",
|
|
" 20/1 1.15074 1.17121 +/- 0.00768\n",
|
|
" 21/1 1.15914 1.17011 +/- 0.00703\n",
|
|
" 22/1 1.14586 1.16809 +/- 0.00673\n",
|
|
" 23/1 1.18999 1.16978 +/- 0.00642\n",
|
|
" 24/1 1.15101 1.16844 +/- 0.00609\n",
|
|
" 25/1 1.13791 1.16640 +/- 0.00602\n",
|
|
" 26/1 1.19791 1.16837 +/- 0.00597\n",
|
|
" 27/1 1.19818 1.17012 +/- 0.00587\n",
|
|
" 28/1 1.14160 1.16854 +/- 0.00576\n",
|
|
" 29/1 1.11487 1.16571 +/- 0.00614\n",
|
|
" 30/1 1.17538 1.16620 +/- 0.00584\n",
|
|
" 31/1 1.20210 1.16791 +/- 0.00581\n",
|
|
" 32/1 1.20078 1.16940 +/- 0.00574\n",
|
|
" 33/1 1.14624 1.16839 +/- 0.00558\n",
|
|
" 34/1 1.14618 1.16747 +/- 0.00542\n",
|
|
" 35/1 1.16866 1.16752 +/- 0.00520\n",
|
|
" 36/1 1.18565 1.16821 +/- 0.00504\n",
|
|
" 37/1 1.16824 1.16821 +/- 0.00485\n",
|
|
" 38/1 1.18299 1.16874 +/- 0.00471\n",
|
|
" 39/1 1.21418 1.17031 +/- 0.00480\n",
|
|
" 40/1 1.11167 1.16835 +/- 0.00504\n",
|
|
" 41/1 1.11545 1.16665 +/- 0.00516\n",
|
|
" 42/1 1.11114 1.16491 +/- 0.00529\n",
|
|
" 43/1 1.14227 1.16423 +/- 0.00517\n",
|
|
" 44/1 1.14104 1.16355 +/- 0.00506\n",
|
|
" 45/1 1.16756 1.16366 +/- 0.00492\n",
|
|
" 46/1 1.13065 1.16274 +/- 0.00487\n",
|
|
" 47/1 1.11251 1.16139 +/- 0.00492\n",
|
|
" 48/1 1.14731 1.16101 +/- 0.00481\n",
|
|
" 49/1 1.16691 1.16117 +/- 0.00469\n",
|
|
" 50/1 1.19679 1.16206 +/- 0.00465\n",
|
|
" Creating state point statepoint.50.h5...\n",
|
|
"\n",
|
|
" ===========================================================================\n",
|
|
" ======================> SIMULATION FINISHED <======================\n",
|
|
" ===========================================================================\n",
|
|
"\n",
|
|
"\n",
|
|
" =======================> TIMING STATISTICS <=======================\n",
|
|
"\n",
|
|
" Total time for initialization = 4.2800E-01 seconds\n",
|
|
" Reading cross sections = 8.9000E-02 seconds\n",
|
|
" Total time in simulation = 1.4506E+01 seconds\n",
|
|
" Time in transport only = 1.4496E+01 seconds\n",
|
|
" Time in inactive batches = 1.7910E+00 seconds\n",
|
|
" Time in active batches = 1.2715E+01 seconds\n",
|
|
" Time synchronizing fission bank = 1.0000E-03 seconds\n",
|
|
" Sampling source sites = 0.0000E+00 seconds\n",
|
|
" SEND/RECV source sites = 1.0000E-03 seconds\n",
|
|
" Time accumulating tallies = 0.0000E+00 seconds\n",
|
|
" Total time for finalization = 0.0000E+00 seconds\n",
|
|
" Total time elapsed = 1.4943E+01 seconds\n",
|
|
" Calculation Rate (inactive) = 13958.7 neutrons/second\n",
|
|
" Calculation Rate (active) = 7864.73 neutrons/second\n",
|
|
"\n",
|
|
" ============================> RESULTS <============================\n",
|
|
"\n",
|
|
" k-effective (Collision) = 1.16131 +/- 0.00453\n",
|
|
" k-effective (Track-length) = 1.16206 +/- 0.00465\n",
|
|
" k-effective (Absorption) = 1.16096 +/- 0.00364\n",
|
|
" Combined k-effective = 1.16120 +/- 0.00325\n",
|
|
" Leakage Fraction = 0.00000 +/- 0.00000\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"0"
|
|
]
|
|
},
|
|
"execution_count": 14,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# Remove old HDF5 (summary, statepoint) files\n",
|
|
"!rm statepoint.*\n",
|
|
"\n",
|
|
"# Run OpenMC\n",
|
|
"executor = openmc.Executor()\n",
|
|
"executor.run_simulation()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Tally Data Processing"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Our simulation ran successfully and created a statepoint file with all the tally data in it. We begin our analysis here loading the statepoint file and \"reading\" the results. By default, data from the statepoint file is only read into memory when it is requested. This helps keep the memory use to a minimum even when a statepoint file may be huge."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 15,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Load the last statepoint file\n",
|
|
"sp = openmc.StatePoint('statepoint.50.h5')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"In addition to the statepoint file, our simulation also created a summary file which encapsulates information about the materials and geometry which is necessary for the `openmc.mgxs` module to properly process the tally data. We first create a summary object and link it with the statepoint."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 16,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Load the summary file and link it with the statepoint\n",
|
|
"su = openmc.Summary('summary.h5')\n",
|
|
"sp.link_with_summary(su)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"The statepoint is now ready to be analyzed by our multi-group cross sections. We simply have to load the tallies from the statepoint into each object as follows and our `MGXS` objects will compute the cross sections for us under-the-hood."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 17,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Load the tallies from the statepoint into each MGXS object\n",
|
|
"total.load_from_statepoint(sp)\n",
|
|
"absorption.load_from_statepoint(sp)\n",
|
|
"scattering.load_from_statepoint(sp)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Voila! Our multi-group cross sections are now ready to rock 'n roll!"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Extracting and Storing MGXS Data"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Let's first inspect our total cross section by printing it to the screen."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 18,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Multi-Group XS\n",
|
|
"\tReaction Type =\ttotal\n",
|
|
"\tDomain Type =\tcell\n",
|
|
"\tDomain ID =\t1\n",
|
|
"\tCross Sections [cm^-1]:\n",
|
|
" Group 1 [6.25e-07 - 20.0 MeV]:\t6.81e-01 +/- 1.88e-01%\n",
|
|
" Group 2 [0.0 - 6.25e-07 MeV]:\t1.40e+00 +/- 5.91e-01%\n",
|
|
"\n",
|
|
"\n",
|
|
"\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"total.print_xs()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Since the `openmc.mgxs` module uses tally arithmetic under-the-hood, the cross section is stored as a \"derived\" tally. This means that it can be queried and manipulated using all of the same method supported for the `Tally` class in the OpenMC Python API. For example, we can construct a Pandas DataFrame of the multi-group cross section data."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 19,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stderr",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"/usr/local/lib/python2.7/dist-packages/openmc-0.7.0-py2.7.egg/openmc/mgxs/mgxs.py:1254: FutureWarning: elementwise comparison failed; returning scalar instead, but in the future will perform elementwise comparison\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<div>\n",
|
|
"<table border=\"1\" class=\"dataframe\">\n",
|
|
" <thead>\n",
|
|
" <tr style=\"text-align: right;\">\n",
|
|
" <th></th>\n",
|
|
" <th>cell</th>\n",
|
|
" <th>group in</th>\n",
|
|
" <th>nuclide</th>\n",
|
|
" <th>mean</th>\n",
|
|
" <th>std. dev.</th>\n",
|
|
" </tr>\n",
|
|
" </thead>\n",
|
|
" <tbody>\n",
|
|
" <tr>\n",
|
|
" <th>1</th>\n",
|
|
" <td>1</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>total</td>\n",
|
|
" <td>0.668323</td>\n",
|
|
" <td>0.001264</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>0</th>\n",
|
|
" <td>1</td>\n",
|
|
" <td>2</td>\n",
|
|
" <td>total</td>\n",
|
|
" <td>1.293258</td>\n",
|
|
" <td>0.007624</td>\n",
|
|
" </tr>\n",
|
|
" </tbody>\n",
|
|
"</table>\n",
|
|
"</div>"
|
|
],
|
|
"text/plain": [
|
|
" cell group in nuclide mean std. dev.\n",
|
|
"1 1 1 total 0.668323 0.001264\n",
|
|
"0 1 2 total 1.293258 0.007624"
|
|
]
|
|
},
|
|
"execution_count": 19,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"df = scattering.get_pandas_dataframe()\n",
|
|
"df.head(10)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Each multi-group cross section object can be easily exported to a variety of file formats, including CSV, Excel, and LaTeX for storage or data processing."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 20,
|
|
"metadata": {
|
|
"collapsed": true
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"absorption.export_xs_data(filename='absorption-xs', format='excel')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"The following code snippet shows how to export all of three cross sections to the same HDF5 binary data store."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 21,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"total.build_hdf5_store(filename='mgxs', append=True)\n",
|
|
"absorption.build_hdf5_store(filename='mgxs', append=True)\n",
|
|
"scattering.build_hdf5_store(filename='mgxs', append=True)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Comparing MGXS with Tally Arithmetic"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Finally, we illustrate how one can leverage OpenMC's tally arithmetic data processing feature with `MGXS` objects. The `openmc.mgxs` module uses tally arithmetic to compute multi-group cross sections with automated uncertainty propagation. Each `MGXS` object includes an `xs_tally` attribute which is a \"derived\" tally based on the tallies needed to compute the cross section type of interest. These derived tallies can be used in subsequent tally arithmetic operations. For example, we can use tally artithmetic to confirm that the `TotalXS` is equal to the sum of the `AbsorptionXS` and `ScatterXS` objects."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 22,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<div>\n",
|
|
"<table border=\"1\" class=\"dataframe\">\n",
|
|
" <thead>\n",
|
|
" <tr style=\"text-align: right;\">\n",
|
|
" <th></th>\n",
|
|
" <th>cell</th>\n",
|
|
" <th>energy [MeV]</th>\n",
|
|
" <th>nuclide</th>\n",
|
|
" <th>score</th>\n",
|
|
" <th>mean</th>\n",
|
|
" <th>std. dev.</th>\n",
|
|
" </tr>\n",
|
|
" </thead>\n",
|
|
" <tbody>\n",
|
|
" <tr>\n",
|
|
" <th>0</th>\n",
|
|
" <td>1</td>\n",
|
|
" <td>(0.0e+00 - 6.3e-07)</td>\n",
|
|
" <td>total</td>\n",
|
|
" <td>(((total / flux) - (absorption / flux)) - (sca...</td>\n",
|
|
" <td>4.884981e-15</td>\n",
|
|
" <td>0.011274</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>1</th>\n",
|
|
" <td>1</td>\n",
|
|
" <td>(6.3e-07 - 2.0e+01)</td>\n",
|
|
" <td>total</td>\n",
|
|
" <td>(((total / flux) - (absorption / flux)) - (sca...</td>\n",
|
|
" <td>1.221245e-15</td>\n",
|
|
" <td>0.001802</td>\n",
|
|
" </tr>\n",
|
|
" </tbody>\n",
|
|
"</table>\n",
|
|
"</div>"
|
|
],
|
|
"text/plain": [
|
|
" cell energy [MeV] nuclide \\\n",
|
|
"0 1 (0.0e+00 - 6.3e-07) total \n",
|
|
"1 1 (6.3e-07 - 2.0e+01) total \n",
|
|
"\n",
|
|
" score mean std. dev. \n",
|
|
"0 (((total / flux) - (absorption / flux)) - (sca... 4.884981e-15 0.011274 \n",
|
|
"1 (((total / flux) - (absorption / flux)) - (sca... 1.221245e-15 0.001802 "
|
|
]
|
|
},
|
|
"execution_count": 22,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# Use tally arithmetic to compute the difference between the total, absorption and scattering\n",
|
|
"difference = total.xs_tally - absorption.xs_tally - scattering.xs_tally\n",
|
|
"\n",
|
|
"# The difference is a derived tally which can generate Pandas DataFrames for inspection\n",
|
|
"difference.get_pandas_dataframe()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Similarly, we can use tally arithmetic to compute the ratio of `AbsorptionXS` and `ScatterXS` to the `TotalXS`."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 23,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<div>\n",
|
|
"<table border=\"1\" class=\"dataframe\">\n",
|
|
" <thead>\n",
|
|
" <tr style=\"text-align: right;\">\n",
|
|
" <th></th>\n",
|
|
" <th>cell</th>\n",
|
|
" <th>energy [MeV]</th>\n",
|
|
" <th>nuclide</th>\n",
|
|
" <th>score</th>\n",
|
|
" <th>mean</th>\n",
|
|
" <th>std. dev.</th>\n",
|
|
" </tr>\n",
|
|
" </thead>\n",
|
|
" <tbody>\n",
|
|
" <tr>\n",
|
|
" <th>0</th>\n",
|
|
" <td>1</td>\n",
|
|
" <td>(0.0e+00 - 6.3e-07)</td>\n",
|
|
" <td>total</td>\n",
|
|
" <td>((absorption / flux) / (total / flux))</td>\n",
|
|
" <td>0.076219</td>\n",
|
|
" <td>0.000651</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>1</th>\n",
|
|
" <td>1</td>\n",
|
|
" <td>(6.3e-07 - 2.0e+01)</td>\n",
|
|
" <td>total</td>\n",
|
|
" <td>((absorption / flux) / (total / flux))</td>\n",
|
|
" <td>0.019319</td>\n",
|
|
" <td>0.000086</td>\n",
|
|
" </tr>\n",
|
|
" </tbody>\n",
|
|
"</table>\n",
|
|
"</div>"
|
|
],
|
|
"text/plain": [
|
|
" cell energy [MeV] nuclide score \\\n",
|
|
"0 1 (0.0e+00 - 6.3e-07) total ((absorption / flux) / (total / flux)) \n",
|
|
"1 1 (6.3e-07 - 2.0e+01) total ((absorption / flux) / (total / flux)) \n",
|
|
"\n",
|
|
" mean std. dev. \n",
|
|
"0 0.076219 0.000651 \n",
|
|
"1 0.019319 0.000086 "
|
|
]
|
|
},
|
|
"execution_count": 23,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# Use tally arithmetic to compute the absorption-to-total MGXS ratio\n",
|
|
"absorption_to_total = absorption.xs_tally / total.xs_tally\n",
|
|
"\n",
|
|
"# The absorption-to-total ratio is a derived tally which can generate Pandas DataFrames for inspection\n",
|
|
"absorption_to_total.get_pandas_dataframe()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 24,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<div>\n",
|
|
"<table border=\"1\" class=\"dataframe\">\n",
|
|
" <thead>\n",
|
|
" <tr style=\"text-align: right;\">\n",
|
|
" <th></th>\n",
|
|
" <th>cell</th>\n",
|
|
" <th>energy [MeV]</th>\n",
|
|
" <th>nuclide</th>\n",
|
|
" <th>score</th>\n",
|
|
" <th>mean</th>\n",
|
|
" <th>std. dev.</th>\n",
|
|
" </tr>\n",
|
|
" </thead>\n",
|
|
" <tbody>\n",
|
|
" <tr>\n",
|
|
" <th>0</th>\n",
|
|
" <td>1</td>\n",
|
|
" <td>(0.0e+00 - 6.3e-07)</td>\n",
|
|
" <td>total</td>\n",
|
|
" <td>((scatter / flux) / (total / flux))</td>\n",
|
|
" <td>0.923781</td>\n",
|
|
" <td>0.007714</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>1</th>\n",
|
|
" <td>1</td>\n",
|
|
" <td>(6.3e-07 - 2.0e+01)</td>\n",
|
|
" <td>total</td>\n",
|
|
" <td>((scatter / flux) / (total / flux))</td>\n",
|
|
" <td>0.980681</td>\n",
|
|
" <td>0.002617</td>\n",
|
|
" </tr>\n",
|
|
" </tbody>\n",
|
|
"</table>\n",
|
|
"</div>"
|
|
],
|
|
"text/plain": [
|
|
" cell energy [MeV] nuclide score \\\n",
|
|
"0 1 (0.0e+00 - 6.3e-07) total ((scatter / flux) / (total / flux)) \n",
|
|
"1 1 (6.3e-07 - 2.0e+01) total ((scatter / flux) / (total / flux)) \n",
|
|
"\n",
|
|
" mean std. dev. \n",
|
|
"0 0.923781 0.007714 \n",
|
|
"1 0.980681 0.002617 "
|
|
]
|
|
},
|
|
"execution_count": 24,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# Use tally arithmetic to compute the scattering-to-total MGXS ratio\n",
|
|
"scattering_to_total = scattering.xs_tally / total.xs_tally\n",
|
|
"\n",
|
|
"# The scattering-to-total ratio is a derived tally which can generate Pandas DataFrames for inspection\n",
|
|
"scattering_to_total.get_pandas_dataframe()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 25,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<div>\n",
|
|
"<table border=\"1\" class=\"dataframe\">\n",
|
|
" <thead>\n",
|
|
" <tr style=\"text-align: right;\">\n",
|
|
" <th></th>\n",
|
|
" <th>cell</th>\n",
|
|
" <th>energy [MeV]</th>\n",
|
|
" <th>nuclide</th>\n",
|
|
" <th>score</th>\n",
|
|
" <th>mean</th>\n",
|
|
" <th>std. dev.</th>\n",
|
|
" </tr>\n",
|
|
" </thead>\n",
|
|
" <tbody>\n",
|
|
" <tr>\n",
|
|
" <th>0</th>\n",
|
|
" <td>1</td>\n",
|
|
" <td>(0.0e+00 - 6.3e-07)</td>\n",
|
|
" <td>total</td>\n",
|
|
" <td>(((absorption / flux) / (total / flux)) + ((sc...</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>0.007741</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>1</th>\n",
|
|
" <td>1</td>\n",
|
|
" <td>(6.3e-07 - 2.0e+01)</td>\n",
|
|
" <td>total</td>\n",
|
|
" <td>(((absorption / flux) / (total / flux)) + ((sc...</td>\n",
|
|
" <td>1</td>\n",
|
|
" <td>0.002619</td>\n",
|
|
" </tr>\n",
|
|
" </tbody>\n",
|
|
"</table>\n",
|
|
"</div>"
|
|
],
|
|
"text/plain": [
|
|
" cell energy [MeV] nuclide \\\n",
|
|
"0 1 (0.0e+00 - 6.3e-07) total \n",
|
|
"1 1 (6.3e-07 - 2.0e+01) total \n",
|
|
"\n",
|
|
" score mean std. dev. \n",
|
|
"0 (((absorption / flux) / (total / flux)) + ((sc... 1 0.007741 \n",
|
|
"1 (((absorption / flux) / (total / flux)) + ((sc... 1 0.002619 "
|
|
]
|
|
},
|
|
"execution_count": 25,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"# Use tally arithmetic to ensure that the absorption- and scattering-to-total MGXS ratios sum to unity\n",
|
|
"sum_ratio = absorption_to_total + scattering_to_total\n",
|
|
"\n",
|
|
"# The scattering-to-total ratio is a derived tally which can generate Pandas DataFrames for inspection\n",
|
|
"sum_ratio.get_pandas_dataframe()"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "Python 2",
|
|
"language": "python",
|
|
"name": "python2"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 2
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython2",
|
|
"version": "2.7.6"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 0
|
|
}
|