@@ -11,6 +11,76 @@ active batches <usersguide_batches>`. However, there are a couple of settings
1111that are unique to the random ray solver and a few areas that the random ray
1212run strategy differs, both of which will be described in this section.
1313
14+ .. _quick_start :
15+
16+ -----------
17+ Quick Start
18+ -----------
19+
20+ While this page contains a comprehensive guide to the random ray solver and
21+ its various parameters, the process of converting an existing continuous energy
22+ Monte Carlo model to a random ray model can be largely automated via convenience
23+ functions in OpenMC's Python interface::
24+
25+ # Define continuous energy model as normal
26+ model = openmc.Model()
27+ ...
28+
29+ # Convert model to multigroup (will auto-generate MGXS library if needed)
30+ model.convert_to_multigroup()
31+
32+ # Convert model to random ray and initialize random ray parameters
33+ # to reasonable defaults based on the specifics of the geometry
34+ model.convert_to_random_ray()
35+
36+ # (Optional) Overlay source region decomposition mesh to improve fidelity of the
37+ # random ray solver. Adjust 'n' for fidelity vs runtime.
38+ n = 100
39+ mesh = openmc.RegularMesh()
40+ mesh.dimension = (n, n, n)
41+ mesh.lower_left = model.geometry.bounding_box.lower_left
42+ mesh.upper_right = model.geometry.bounding_box.upper_right
43+ model.settings.random_ray['source_region_meshes'] = [(mesh, [model.geometry.root_universe])]
44+
45+ # (Optional) Improve fidelity of the random ray solver by enabling linear sources
46+ model.settings.random_ray['source_shape'] = 'linear'
47+
48+ # (Optional) Increase the number of rays/batch, to reduce uncertainty
49+ model.settings.particles = 500
50+
51+ The above strategy first converts the continuous energy model to a multigroup
52+ one using the :meth: `openmc.Model.convert_to_multigroup ` method. By default,
53+ this will internally run a coarsely converged continuous energy Monte Carlo
54+ simulation to produce an estimated multigroup macroscopic cross section set for
55+ each material specified in the model, and store this data into a multigroup
56+ cross section library file (``mgxs.h5 ``) that can be used by the random ray
57+ solver.
58+
59+ The :meth: `openmc.Model.convert_to_random_ray ` method enables random ray mode
60+ and performs an analysis of the model geometry to determine reasonable values
61+ for all required parameters. If default behavior is not satisfactory, the user
62+ can manually adjust the settings in the :attr: `~openmc.Settings.random_ray `
63+ dictionary in the :class: `openmc.Settings ` as described in the sections below.
64+
65+ Finally a few optional steps are shown. The first (recommended) step overlays a
66+ mesh over the geometry to create smaller source regions so that source
67+ resolution improves and the random ray solver becomes more accurate. Varying the
68+ mesh resolution can be used to trade off between accuracy and runtime.
69+ High-fidelity fission reactor simulation may require source region sizes below 1
70+ cm, while larger fixed source problems with some tolerance for error may be able
71+ to use source regions of 10 or 100 cm.
72+
73+ We also enable linear sources, which can improve the accuracy of the random ray
74+ solver and/or allow for a much coarser mesh resolution to be overlaid. Finally,
75+ the number of rays per batch is adjusted. The goal here is to ensure that the
76+ source region miss rate is below 1%, which is reported by OpenMC at the end of
77+ the simulation (or before via a warning if it is very high).
78+
79+ .. warning ::
80+ If using a mesh filter for tallying or weight window generation, ensure that
81+ the same mesh is used for source region decomposition via
82+ ``model.settings.random_ray['source_region_meshes'] ``.
83+
1484------------------------
1585Enabling Random Ray Mode
1686------------------------
@@ -557,37 +627,126 @@ variety of problem types (or through a multidimensional parameter sweep of
557627design variables) with only modest errors and at greatly reduced cost as
558628compared to using only continuous energy Monte Carlo.
559629
630+ ~~~~~~~~~~~~
631+ The Easy Way
632+ ~~~~~~~~~~~~
633+
634+ The easiest way to generate a multigroup cross section library is to use the
635+ :meth: `openmc.Model.convert_to_multigroup ` method. This method will
636+ automatically output a multigroup cross section library file (``mgxs.h5 ``) from
637+ a continuous energy Monte Carlo model and alter the material definitions in the
638+ model to use these multigroup cross sections. An example is given below::
639+
640+ # Assume we already have a working continuous energy model
641+ model.convert_to_multigroup(
642+ method="material_wise",
643+ groups="CASMO-2",
644+ nparticles=2000,
645+ overwrite_mgxs_library=False,
646+ mgxs_path="mgxs.h5",
647+ correction=None
648+ )
649+
650+ The most important parameter to set is the ``method `` parameter, which can be
651+ either "stochastic_slab", "material_wise", or "infinite_medium". An overview
652+ of these methods is given below:
653+
654+ .. list-table :: Comparison of Automatic MGXS Generation Methods
655+ :header-rows: 1
656+ :widths: 10 30 30 30
657+
658+ * - Method
659+ - Description
660+ - Pros
661+ - Cons
662+ * - ``material_wise `` (default)
663+ - * Higher Fidelity
664+ * Runs a CE simulation with the original geometry and source, tallying
665+ cross sections with a material filter.
666+ - * Typically the most accurate of the three methods
667+ * Accurately captures (averaged over the full problem domain)
668+ both spatial and resonance self shielding effects
669+ - * Potentially slower as the full geometry must be run
670+ * If a material is only present far from the source and doesn't get tallied
671+ to in the CE simulation, the MGXS will be zero for that material.
672+ * - ``stochastic_slab ``
673+ - * Medium Fidelity
674+ * Runs a CE simulation with a greatly simplified geometry, where materials
675+ are randomly assigned to layers in a 1D "stochastic slab sandwich" geometry
676+ - * Still captures resonant self shielding and resonance effects between materials
677+ * Fast due to the simplified geometry
678+ * Able to produce cross section data for all materials, regardless of how
679+ far they are from the source in the original geometry
680+ - * Does not capture most spatial self shielding effects, e.g., no lattice physics.
681+ * - ``infinite_medium ``
682+ - * Lower Fidelity
683+ * Runs one CE simulation per material independently. Each simulation is just
684+ an infinite medium slowing down problem, with an assumed external source term.
685+ - * Simple
686+ - * Poor accuracy (no spatial information, no lattice physics, no resonance effects
687+ between materials)
688+ * May hang if a material has a k-infinity greater than 1.0
689+
690+ When selecting a non-default energy group structure, you can manually define
691+ group boundaries or specify the name of a known group structure (a list of which
692+ can be found at :data: `openmc.mgxs.GROUP_STRUCTURES `). The ``nparticles ``
693+ parameter can be adjusted upward to improve the fidelity of the generated cross
694+ section library. The ``correction `` parameter can be set to ``"P0" `` to enable
695+ P0 transport correction. The ``overwrite_mgxs_library `` parameter can be set to
696+ ``True `` to overwrite an existing MGXS library file, or ``False `` to skip
697+ generation and use an existing library file.
698+
699+ .. note ::
700+ MGXS transport correction (via setting the ``correction `` parameter in the
701+ :meth: `openmc.Model.convert_to_multigroup ` method to ``"P0" ``) may
702+ result in negative in-group scattering cross sections, which can cause
703+ numerical instability. To mitigate this, during a random ray solve OpenMC
704+ will automatically apply
705+ `diagonal stabilization <https://doi.org/10.1016/j.anucene.2018.10.036 >`_
706+ with a :math: `\rho ` default value of 1.0, which can be adjusted with the
707+ ``settings.random_ray['diagonal_stabilization_rho'] `` parameter.
708+
709+ Ultimately, the methods described above are all just approximations.
710+ Approximations in the generated MGXS data will fundamentally limit the potential
711+ accuracy of the random ray solver. However, the methods described above are all
712+ useful in that they can provide a good starting point for a random ray
713+ simulation, and if more fidelity is needed the user may wish to follow the
714+ instructions below or experiment with transport correction techniques to improve
715+ the fidelity of the generated MGXS data.
716+
717+ ~~~~~~~~~~~~
718+ The Hard Way
719+ ~~~~~~~~~~~~
720+
560721We give here a quick summary of how to produce a multigroup cross section data
561722file (``mgxs.h5 ``) from a starting point of a typical continuous energy Monte
562- Carlo input file . Notably, continuous energy input files define materials as a
563- mixture of nuclides with different densities, whereas multigroup materials are
564- simply defined by which name they correspond to in a ``mgxs.h5 `` library file.
723+ Carlo model . Notably, continuous energy models define materials as a mixture of
724+ nuclides with different densities, whereas multigroup materials are simply
725+ defined by which name they correspond to in a ``mgxs.h5 `` library file.
565726
566727To generate the cross section data, we begin with a continuous energy Monte
567- Carlo input deck and add in the required tallies that will be needed to generate
568- our library. In this example, we will specify material-wise cross sections and a
569- two group energy decomposition::
728+ Carlo model and add in the tallies that are needed to generate our library. In
729+ this example, we will specify material-wise cross sections and a two-group
730+ energy decomposition::
570731
571732 # Define geometry
572733 ...
573- ...
574734 geometry = openmc.Geometry()
575735 ...
576- ...
577736
578737 # Initialize MGXS library with a finished OpenMC geometry object
579738 mgxs_lib = openmc.mgxs.Library(geometry)
580739
581740 # Pick energy group structure
582- groups = openmc.mgxs.EnergyGroups(openmc.mgxs.GROUP_STRUCTURES[ 'CASMO-2'] )
741+ groups = openmc.mgxs.EnergyGroups('CASMO-2')
583742 mgxs_lib.energy_groups = groups
584743
585744 # Disable transport correction
586745 mgxs_lib.correction = None
587746
588747 # Specify needed cross sections for random ray
589748 mgxs_lib.mgxs_types = ['total', 'absorption', 'nu-fission', 'fission',
590- 'nu-scatter matrix', 'multiplicity matrix', 'chi']
749+ 'nu-scatter matrix', 'multiplicity matrix', 'chi']
591750
592751 # Specify a "cell" domain type for the cross section tally filters
593752 mgxs_lib.domain_type = "material"
@@ -614,24 +773,21 @@ two group energy decomposition::
614773 ...
615774
616775When selecting an energy decomposition, you can manually define group boundaries
617- or pick out a group structure already known to OpenMC (a list of which can be
618- found at :class : `openmc.mgxs.GROUP_STRUCTURES `). Once the above input deck has
619- been run, the resulting statepoint file will contain the needed flux and
620- reaction rate tally data so that a MGXS library file can be generated. Below is
621- the postprocessing script needed to generate the ``mgxs.h5 `` library file given
622- a statepoint file (e.g., ``statepoint.100.h5 ``) file and summary file (e.g.,
623- `` summary.h5 ``) that resulted from running our previous example::
776+ or specify the name of known group structure (a list of which can be found at
777+ :data : `openmc.mgxs.GROUP_STRUCTURES `). Once the above model has been run, the
778+ resulting statepoint file will contain the needed flux and reaction rate tally
779+ data so that a MGXS library file can be generated. Below is the postprocessing
780+ script needed to generate the ``mgxs.h5 `` library file given a statepoint file
781+ (e.g., ``statepoint.100.h5 ``) file and summary file (e.g., `` summary.h5 ``) that
782+ resulted from running our previous example::
624783
625784 import openmc
626785
627786 summary = openmc.Summary('summary.h5')
628787 geom = summary.geometry
629788 mats = summary.materials
630789
631- statepoint_filename = 'statepoint.100.h5'
632- sp = openmc.StatePoint(statepoint_filename)
633-
634- groups = openmc.mgxs.EnergyGroups(openmc.mgxs.GROUP_STRUCTURES['CASMO-2'])
790+ groups = openmc.mgxs.EnergyGroups('CASMO-2')
635791 mgxs_lib = openmc.mgxs.Library(geom)
636792 mgxs_lib.energy_groups = groups
637793 mgxs_lib.correction = None
@@ -653,10 +809,10 @@ a statepoint file (e.g., ``statepoint.100.h5``) file and summary file (e.g.,
653809 # Construct all tallies needed for the multi-group cross section library
654810 mgxs_lib.build_library()
655811
656- mgxs_lib.load_from_statepoint(sp)
812+ with openmc.StatePoint('statepoint.100.h5') as sp:
813+ mgxs_lib.load_from_statepoint(sp)
657814
658- names = []
659- for mat in mgxs_lib.domains: names.append(mat.name)
815+ names = [mat.name for mat in mgxs_lib.domains]
660816
661817 # Create a MGXS File which can then be written to disk
662818 mgxs_file = mgxs_lib.create_mg_library(xs_type='macro', xsdata_names=names)
@@ -665,8 +821,8 @@ a statepoint file (e.g., ``statepoint.100.h5``) file and summary file (e.g.,
665821 mgxs_file.export_to_hdf5("mgxs.h5")
666822
667823Notably, the postprocessing script needs to match the same
668- :class: `openmc.mgxs.Library ` settings that were used to generate the tallies,
669- but otherwise is able to discern the rest of the simulation details from the
824+ :class: `openmc.mgxs.Library ` settings that were used to generate the tallies but
825+ is otherwise able to discern the rest of the simulation details from the
670826statepoint and summary files. Once the postprocessing script is successfully
671827run, the ``mgxs.h5 `` file can be loaded by subsequent runs of OpenMC.
672828
@@ -701,11 +857,11 @@ multigroup library instead of defining their isotopic contents, as::
701857 water_data = openmc.Macroscopic('Hot borated water')
702858
703859 # Instantiate some Materials and register the appropriate Macroscopic objects
704- fuel= openmc.Material(name='UO2 (2.4%)')
860+ fuel = openmc.Material(name='UO2 (2.4%)')
705861 fuel.set_density('macro', 1.0)
706862 fuel.add_macroscopic(fuel_data)
707863
708- water= openmc.Material(name='Hot borated water')
864+ water = openmc.Material(name='Hot borated water')
709865 water.set_density('macro', 1.0)
710866 water.add_macroscopic(water_data)
711867
0 commit comments