mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-28 22:26:08 -04:00
Merge branch 'develop' into no_n_batches_in_statepoint
Conflicts: docs/source/devguide/statepoint.rst
This commit is contained in:
commit
db84521286
135 changed files with 3643 additions and 1446 deletions
BIN
docs/source/_images/loss.png
Normal file
BIN
docs/source/_images/loss.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
BIN
docs/source/_images/prod.png
Normal file
BIN
docs/source/_images/prod.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
|
|
@ -23,7 +23,7 @@ sys.path.insert(0, os.path.abspath('../sphinxext'))
|
|||
|
||||
# Add any Sphinx extension module names here, as strings. They can be extensions
|
||||
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||
extensions = ['sphinx.ext.pngmath']
|
||||
extensions = ['sphinx.ext.pngmath', 'sphinxcontrib.tikz']
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
|
@ -48,7 +48,7 @@ copyright = u'2011-2014, Massachusetts Institute of Technology'
|
|||
# The short X.Y version.
|
||||
version = "0.6"
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = "0.6.0"
|
||||
release = "0.6.1"
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
|
@ -188,7 +188,14 @@ latex_documents = [
|
|||
u'Massachusetts Institute of Technology', 'manual'),
|
||||
]
|
||||
|
||||
latex_elements = {'preamble': '\\usepackage{enumitem}\\setlistdepth{9}'}
|
||||
latex_elements = {
|
||||
'preamble': '''
|
||||
\usepackage{enumitem}
|
||||
\setlistdepth{9}
|
||||
\usepackage{tikz}
|
||||
\usetikzlibrary{shapes,snakes,shadows,arrows,calc,decorations.markings,patterns,fit,matrix,spy}
|
||||
'''
|
||||
}
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
|
|
|
|||
|
|
@ -290,6 +290,13 @@ if (run_mode == MODE_EIGENVALUE and source_present)
|
|||
|
||||
Energy of the i-th source particle.
|
||||
|
||||
-----------
|
||||
Revision 12
|
||||
-----------
|
||||
|
||||
Same as revision 11, except **tallies(i) % scatt_order(j)** is now **tallies(i)
|
||||
% moment_order(j)**.
|
||||
|
||||
-----------
|
||||
Revision 11
|
||||
-----------
|
||||
|
|
@ -504,13 +511,13 @@ if (run_mode == MODE_EIGENVALUE)
|
|||
**integer(4) tallies(i) % score_bins(j)**
|
||||
|
||||
Values of specified scoring bins (e.g. SCORE_FLUX).
|
||||
|
||||
|
||||
*do j = 1, tallies(i) % n_score_bins*
|
||||
|
||||
**integer(4) tallies(i) % scatt_order(j)**
|
||||
|
||||
Scattering Order specified scoring bins.
|
||||
|
||||
|
||||
**integer(4) tallies(i) % n_score_bins**
|
||||
|
||||
Number of scoring bins without accounting for those added by
|
||||
|
|
@ -551,7 +558,7 @@ if (tallies_on > 0)
|
|||
*do j = 1, size(tallies(i) % scores, 1)*
|
||||
|
||||
**real(8) tallies(i) % scores(j,k) % sum**
|
||||
|
||||
|
||||
Accumulated sum for the j-th score and k-th filter of the
|
||||
i-th tally
|
||||
|
||||
|
|
@ -581,7 +588,7 @@ if (run_mode == MODE_EIGENVALUE and source_present)
|
|||
Energy of the i-th source particle.
|
||||
|
||||
-----------
|
||||
Revision 10
|
||||
Revision 10
|
||||
-----------
|
||||
|
||||
**integer(4) FILETYPE_STATEPOINT**
|
||||
|
|
@ -794,13 +801,13 @@ if (run_mode == MODE_EIGENVALUE)
|
|||
**integer(4) tallies(i) % score_bins(j)**
|
||||
|
||||
Values of specified scoring bins (e.g. SCORE_FLUX).
|
||||
|
||||
|
||||
*do j = 1, tallies(i) % n_score_bins*
|
||||
|
||||
**integer(4) tallies(i) % scatt_order(j)**
|
||||
|
||||
Scattering Order specified scoring bins.
|
||||
|
||||
|
||||
**integer(4) tallies(i) % n_score_bins**
|
||||
|
||||
Number of scoring bins without accounting for those added by
|
||||
|
|
@ -837,7 +844,7 @@ if (tallies_on > 0)
|
|||
*do j = 1, size(tallies(i) % scores, 1)*
|
||||
|
||||
**real(8) tallies(i) % scores(j,k) % sum**
|
||||
|
||||
|
||||
Accumulated sum for the j-th score and k-th filter of the
|
||||
i-th tally
|
||||
|
||||
|
|
@ -1046,13 +1053,13 @@ if (run_mode == MODE_EIGENVALUE)
|
|||
**integer(4) tallies(i) % score_bins(j)**
|
||||
|
||||
Values of specified scoring bins (e.g. SCORE_FLUX).
|
||||
|
||||
|
||||
*do j = 1, tallies(i) % n_score_bins*
|
||||
|
||||
**integer(4) tallies(i) % scatt_order(j)**
|
||||
|
||||
Scattering Order specified scoring bins.
|
||||
|
||||
|
||||
**integer(4) tallies(i) % n_score_bins**
|
||||
|
||||
Number of scoring bins without accounting for those added by
|
||||
|
|
@ -1089,7 +1096,7 @@ if (tallies_on > 0)
|
|||
*do j = 1, size(tallies(i) % scores, 1)*
|
||||
|
||||
**real(8) tallies(i) % scores(j,k) % sum**
|
||||
|
||||
|
||||
Accumulated sum for the j-th score and k-th filter of the
|
||||
i-th tally
|
||||
|
||||
|
|
@ -1294,13 +1301,13 @@ if (run_mode == MODE_EIGENVALUE)
|
|||
**integer(4) tallies(i) % score_bins(j)**
|
||||
|
||||
Values of specified scoring bins (e.g. SCORE_FLUX).
|
||||
|
||||
|
||||
*do j = 1, tallies(i) % n_score_bins*
|
||||
|
||||
**integer(4) tallies(i) % scatt_order(j)**
|
||||
|
||||
Scattering Order specified scoring bins.
|
||||
|
||||
|
||||
**integer(4) tallies(i) % n_score_bins**
|
||||
|
||||
Number of scoring bins without accounting for those added by
|
||||
|
|
@ -1337,7 +1344,7 @@ if (tallies_on > 0)
|
|||
*do j = 1, size(tallies(i) % scores, 1)*
|
||||
|
||||
**real(8) tallies(i) % scores(j,k) % sum**
|
||||
|
||||
|
||||
Accumulated sum for the j-th score and k-th filter of the
|
||||
i-th tally
|
||||
|
||||
|
|
@ -1526,13 +1533,13 @@ if (run_mode == MODE_EIGENVALUE)
|
|||
**integer(4) tallies(i) % score_bins(j)**
|
||||
|
||||
Values of specified scoring bins (e.g. SCORE_FLUX).
|
||||
|
||||
|
||||
*do j = 1, tallies(i) % n_score_bins*
|
||||
|
||||
**integer(4) tallies(i) % scatt_order(j)**
|
||||
|
||||
Scattering Order specified scoring bins.
|
||||
|
||||
|
||||
**integer(4) tallies(i) % n_score_bins**
|
||||
|
||||
Number of scoring bins without accounting for those added by
|
||||
|
|
@ -1569,7 +1576,7 @@ if (tallies_on > 0)
|
|||
*do j = 1, size(tallies(i) % scores, 1)*
|
||||
|
||||
**real(8) tallies(i) % scores(j,k) % sum**
|
||||
|
||||
|
||||
Accumulated sum for the j-th score and k-th filter of the
|
||||
i-th tally
|
||||
|
||||
|
|
@ -1790,7 +1797,7 @@ if (tallies_on > 0)
|
|||
*do j = 1, size(tallies(i) % scores, 1)*
|
||||
|
||||
**real(8) tallies(i) % scores(j,k) % sum**
|
||||
|
||||
|
||||
Accumulated sum for the j-th score and k-th filter of the
|
||||
i-th tally
|
||||
|
||||
|
|
@ -1999,7 +2006,7 @@ if (tallies_on > 0)
|
|||
*do j = 1, size(tallies(i) % scores, 1)*
|
||||
|
||||
**real(8) tallies(i) % scores(j,k) % sum**
|
||||
|
||||
|
||||
Accumulated sum for the j-th score and k-th filter of the
|
||||
i-th tally
|
||||
|
||||
|
|
@ -2204,7 +2211,7 @@ if (tallies_on > 0)
|
|||
*do j = 1, size(tallies(i) % scores, 1)*
|
||||
|
||||
**real(8) tallies(i) % scores(j,k) % sum**
|
||||
|
||||
|
||||
Accumulated sum for the j-th score and k-th filter of the
|
||||
i-th tally
|
||||
|
||||
|
|
@ -2405,7 +2412,7 @@ if (tallies_on > 0)
|
|||
*do j = 1, size(tallies(i) % scores, 1)*
|
||||
|
||||
**real(8) tallies(i) % scores(j,k) % sum**
|
||||
|
||||
|
||||
Accumulated sum for the j-th score and k-th filter of the
|
||||
i-th tally
|
||||
|
||||
|
|
@ -2526,7 +2533,7 @@ Revision 2
|
|||
*do j = 1, size(tallies(i) % scores, 1)*
|
||||
|
||||
**real(8) tallies(i) % scores(j,k) % sum**
|
||||
|
||||
|
||||
Accumulated sum for the j-th score and k-th filter of the i-th
|
||||
tally
|
||||
|
||||
|
|
@ -2625,7 +2632,7 @@ Revision 1
|
|||
*do j = 1, size(tallies(i) % scores, 1)*
|
||||
|
||||
**real(8) tallies(i) % scores(j,k) % sum**
|
||||
|
||||
|
||||
Accumulated sum for the j-th score and k-th filter of the i-th
|
||||
tally
|
||||
|
||||
|
|
|
|||
561
docs/source/methods/cmfd.rst
Normal file
561
docs/source/methods/cmfd.rst
Normal file
|
|
@ -0,0 +1,561 @@
|
|||
.. _methods_cmfd:
|
||||
|
||||
================================================================
|
||||
Nonlinear Diffusion Acceleration - Coarse Mesh Finite Difference
|
||||
================================================================
|
||||
|
||||
This page section discusses how nonlinear diffusion acceleration (NDA) using
|
||||
coarse mesh finite difference (CMFD) is implemented into OpenMC. Before we get
|
||||
into the theory, general notation for this section is discussed.
|
||||
|
||||
--------
|
||||
Notation
|
||||
--------
|
||||
|
||||
Before deriving NDA relationships, notation is explained. If a parameter has a
|
||||
:math:`\overline{\cdot}`, it is surface area-averaged and if it has a
|
||||
:math:`\overline{\overline\cdot}`, it is volume-averaged. When describing a
|
||||
specific cell in the geometry, indices :math:`(i,j,k)` are used which correspond
|
||||
to directions :math:`(x,y,z)`. In most cases, the same operation is performed in
|
||||
all three directions. To compactly write this, an arbitrary direction set
|
||||
:math:`(u,v,w)` that corresponds to cell indices :math:`(l,m,n)` is used. Note
|
||||
that :math:`u` and :math:`l` do not have to correspond to :math:`x` and
|
||||
:math:`i`. However, if :math:`u` and :math:`l` correspond to :math:`y` and
|
||||
:math:`j`, :math:`v` and :math:`w` correspond to :math:`x` and :math:`z`
|
||||
directions. An example of this is shown in the following expression:
|
||||
|
||||
.. math::
|
||||
:label: not1
|
||||
|
||||
\sum\limits_{u\in(x,y,z)}\left\langle\overline{J}^{u,g}_{l+1/2,m,n}
|
||||
\Delta_m^v\Delta_n^w\right\rangle
|
||||
|
||||
Here, :math:`u` takes on each direction one at a time. The parameter :math:`J`
|
||||
is surface area-averaged over the transverse indices :math:`m` and :math:`n`
|
||||
located at :math:`l+1/2`. Usually, spatial indices are listed as subscripts and
|
||||
the direction as a superscript. Energy group indices represented by :math:`g`
|
||||
and :math:`h` are also listed as superscripts here. The group :math:`g` is the
|
||||
group of interest and, if present, :math:`h` is all groups. Finally, any
|
||||
parameter surrounded by :math:`\left\langle\cdot\right\rangle` represents a
|
||||
tally quantity that can be edited from a Monte Carlo (MC) solution.
|
||||
|
||||
------
|
||||
Theory
|
||||
------
|
||||
|
||||
NDA is a diffusion model that has equivalent physics to a transport model. There
|
||||
are many different methods that can be classified as NDA. The CMFD method is a
|
||||
type of NDA that represents second order multigroup diffusion equations on a
|
||||
coarse spatial mesh. Whether a transport model or diffusion model is used to
|
||||
represent the distribution of neutrons, these models must satisfy the *neutron
|
||||
balance equation*. This balance is represented by the following formula for a
|
||||
specific energy group :math:`g` in cell :math:`(l,m,n)`:
|
||||
|
||||
.. math::
|
||||
:label: eq_neut_bal
|
||||
|
||||
\sum\limits_{u\in(x,y,z)}\left(\left\langle\overline{J}^{u,g}_{l+1/2,m,n}
|
||||
\Delta_m^v\Delta_n^w\right\rangle -
|
||||
\left\langle\overline{J}^{u,g}_{l-1/2,m,n}
|
||||
\Delta_m^v\Delta_n^w\right\rangle\right)
|
||||
+
|
||||
\left\langle\overline{\overline\Sigma}_{t_{l,m,n}}^g
|
||||
\overline{\overline\phi}_{l,m,n}^g\Delta_l^u\Delta_m^v\Delta_n^w\right\rangle
|
||||
= \\
|
||||
\sum\limits_{h=1}^G\left\langle
|
||||
\overline{\overline{\nu_s\Sigma}}_{s_{l,m,n}}^{h\rightarrow
|
||||
g}\overline{\overline\phi}_{l,m,n}^h\Delta_l^u\Delta_m^v\Delta_n^w
|
||||
\right\rangle
|
||||
+
|
||||
\frac{1}{k_{eff}}\sum\limits_{h=1}^G
|
||||
\left\langle\overline{\overline{\nu_f\Sigma}}_{f_{l,m,n}}^{h\rightarrow
|
||||
g}\overline{\overline\phi}_{l,m,n}^h
|
||||
\Delta_l^u\Delta_m^v\Delta_n^w\right\rangle.
|
||||
|
||||
In eq. :eq:`eq_neut_bal` the parameters are defined as:
|
||||
|
||||
* :math:`\left\langle\overline{J}^{u,g}_{l\pm
|
||||
1/2,m,n}\Delta_m^v\Delta_n^w\right\rangle` --- surface area-integrated net
|
||||
current over surface :math:`(l\pm 1/2,m,n)` with surface normal in direction
|
||||
:math:`u` in energy group :math:`g`. By dividing this quantity by the transverse
|
||||
area, :math:`\Delta_m^v\Delta_n^w`, the surface area-averaged net current can
|
||||
be computed.
|
||||
* :math:`\left\langle\overline{\overline\Sigma}_{t_{l,m,n}}^g
|
||||
\overline{\overline\phi}_{l,m,n}^g\Delta_l^u\Delta_m^v\Delta_n^w\right\rangle`
|
||||
--- volume-integrated total reaction rate over energy group :math:`g`.
|
||||
* :math:`\left\langle\overline{\overline{\nu_s\Sigma}}_{s_{l,m,n}}^{h\rightarrow
|
||||
g}
|
||||
\overline{\overline\phi}_{l,m,n}^h\Delta_l^u\Delta_m^v\Delta_n^w\right\rangle`
|
||||
--- volume-integrated scattering production rate of neutrons that begin with
|
||||
energy in group :math:`h` and exit reaction in group :math:`g`. This reaction
|
||||
rate also includes the energy transfer of reactions (except fission) that
|
||||
produce multiple neutrons such as (n, 2n); hence, the need for :math:`\nu_s`
|
||||
to represent neutron multiplicity.
|
||||
* :math:`k_{eff}` --- core multiplication factor.
|
||||
* :math:`\left\langle\overline{\overline{\nu_f\Sigma}}_{f_{l,m,n}}^{h\rightarrow
|
||||
g}\overline{\overline\phi}_{l,m,n}^h\Delta_l^u\Delta_m^v\Delta_n^w\right\rangle`
|
||||
--- volume-integrated fission production rate of neutrons from fissions in
|
||||
group :math:`h` that exit in group :math:`g`.
|
||||
|
||||
Each quantity in :math:`\left\langle\cdot\right\rangle` represents a scalar value that
|
||||
is obtained from an MC tally. A good verification step when using an MC code is
|
||||
to make sure that tallies satisfy this balance equation within statistics. No
|
||||
NDA acceleration can be performed if the balance equation is not satisfied.
|
||||
|
||||
There are three major steps to consider when performing NDA: (1) calculation of
|
||||
macroscopic cross sections and nonlinear parameters, (2) solving an eigenvalue
|
||||
problem with a system of linear equations, and (3) modifying MC source
|
||||
distribution to align with the NDA solution on a chosen mesh. This process is
|
||||
illustrated as a flow chart below. After a batch of neutrons
|
||||
is simulated, NDA can take place. Each of the steps described above is described
|
||||
in detail in the following sections.
|
||||
|
||||
.. tikz:: Flow chart of NDA process. Note "XS" is used for cross section and
|
||||
"DC" is used for diffusion coefficient.
|
||||
:libs: shapes, snakes, shadows, arrows, calc, decorations.markings, patterns, fit, matrix, spy
|
||||
:include: cmfd_tikz/cmfd_flow.tikz
|
||||
|
||||
Calculation of Macroscopic Cross Sections
|
||||
-----------------------------------------
|
||||
|
||||
A diffusion model needs macroscopic cross sections and diffusion coefficients to
|
||||
solve for multigroup fluxes. Cross sections are derived by conserving reaction
|
||||
rates predicted by MC tallies. From Eq. :eq:`eq_neut_bal`, total, scattering
|
||||
production and fission production macroscopic cross sections are needed. They are
|
||||
defined from MC tallies as follows:
|
||||
|
||||
.. math::
|
||||
:label: xs1
|
||||
|
||||
\overline{\overline\Sigma}_{t_{l,m,n}}^g \equiv
|
||||
\frac{\left\langle\overline{\overline\Sigma}_{t_{l,m,n}}^g
|
||||
\overline{\overline\phi}_{l,m,n}^g\Delta_l^u\Delta_m^v\Delta_n^w\right\rangle}
|
||||
{\left\langle\overline{\overline\phi}_{l,m,n}^g
|
||||
\Delta_l^u\Delta_m^v\Delta_n^w\right\rangle},
|
||||
|
||||
.. math::
|
||||
:label: xs2
|
||||
|
||||
\overline{\overline{\nu_s\Sigma}}_{s_{l,m,n}}^{h\rightarrow g} \equiv
|
||||
\frac{\left\langle\overline{\overline{\nu_s\Sigma}}_{s_{l,m,n}}^{h\rightarrow
|
||||
g}\overline{\overline\phi}_{l,m,n}^h\Delta_l^u\Delta_m^v\Delta_n^w\right\rangle}
|
||||
{\left\langle\overline{\overline\phi}_{l,m,n}^h
|
||||
\Delta_l^u\Delta_m^v\Delta_n^w\right\rangle}
|
||||
|
||||
and
|
||||
|
||||
.. math::
|
||||
:label: xs3
|
||||
|
||||
\overline{\overline{\nu_f\Sigma}}_{f_{l,m,n}}^{h\rightarrow g} \equiv
|
||||
\frac{\left\langle\overline{\overline{\nu_f\Sigma}}_{f_{l,m,n}}^{h\rightarrow
|
||||
g}\overline{\overline\phi}_{l,m,n}^h\Delta_l^u\Delta_m^v\Delta_n^w\right\rangle}
|
||||
{\left\langle\overline{\overline\phi}_{l,m,n}^h\Delta_l^u\Delta_m^v\Delta_n^w\right\rangle}.
|
||||
|
||||
In order to fully conserve neutron balance, leakage rates also need to be
|
||||
preserved. In standard diffusion theory, leakage rates are represented by
|
||||
diffusion coefficients. Unfortunately, it is not easy in MC to calculate a
|
||||
single diffusion coefficient for a cell that describes leakage out of each
|
||||
surface. Luckily, it does not matter what definition of diffusion coefficient is
|
||||
used because nonlinear equivalence parameters will correct for this
|
||||
inconsistency. However, depending on the diffusion coefficient definition
|
||||
chosen, different convergence properties of NDA equations are observed.
|
||||
Here, we introduce a diffusion coefficient that is derived for a coarse energy
|
||||
transport reaction rate. This definition can easily be constructed from
|
||||
MC tallies provided that angular moments of scattering reaction rates can
|
||||
be obtained. The diffusion coefficient is defined as follows:
|
||||
|
||||
.. math::
|
||||
:label: eq_transD
|
||||
|
||||
\overline{\overline D}_{l,m,n}^g =
|
||||
\frac{\left\langle\overline{\overline\phi}_{l,m,n}^g
|
||||
\Delta_l^u\Delta_m^v\Delta_n^w\right\rangle}{3
|
||||
\left\langle\overline{\overline\Sigma}_{tr_{l,m,n}}^g
|
||||
\overline{\overline\phi}_{l,m,n}^g
|
||||
\Delta_l^u\Delta_m^v\Delta_n^w\right\rangle},
|
||||
|
||||
where
|
||||
|
||||
.. math::
|
||||
:label: xs4
|
||||
|
||||
\left\langle\overline{\overline\Sigma}_{tr_{l,m,n}}^g
|
||||
\overline{\overline\phi}_{l,m,n}^g\Delta_l^u\Delta_m^v\Delta_n^w\right\rangle
|
||||
=
|
||||
\left\langle\overline{\overline\Sigma}_{t_{l,m,n}}^g
|
||||
\overline{\overline\phi}_{l,m,n}^g\Delta_l^u\Delta_m^v\Delta_n^w\right\rangle
|
||||
\\ -
|
||||
\left\langle\overline{\overline{\nu_s\Sigma}}_{s1_{l,m,n}}^g
|
||||
\overline{\overline\phi}_{l,m,n}^g\Delta_l^u\Delta_m^v\Delta_n^w\right\rangle.
|
||||
|
||||
Note that the transport reaction rate is calculated from the total reaction rate
|
||||
reduced by the :math:`P_1` scattering production reaction rate. Equation :eq:`eq_transD`
|
||||
does not represent the best definition of diffusion coefficients from MC;
|
||||
however, it is very simple and usually fits into MC tally frameworks
|
||||
easily. Different methods to calculate more accurate diffusion coefficients can
|
||||
found in [Herman]_.
|
||||
|
||||
CMFD Equations
|
||||
--------------
|
||||
|
||||
The first part of this section is devoted to discussing second-order finite
|
||||
volume discretization of multigroup diffusion equations. This will be followed
|
||||
up by the formulation of CMFD equations that are used in this NDA
|
||||
scheme. When performing second-order finite volume discretization of the
|
||||
diffusion equation, we need information that relates current to flux. In this
|
||||
numerical scheme, each cell is coupled only to its direct neighbors. Therefore,
|
||||
only two types of coupling exist: (1) cell-to-cell coupling and (2)
|
||||
cell-to-boundary coupling. The derivation of this procedure is referred to as
|
||||
finite difference diffusion equations and can be found in literature such
|
||||
as [Hebert]_. These current/flux relationships are as follows:
|
||||
|
||||
* cell-to-cell coupling
|
||||
|
||||
.. math::
|
||||
:label: eq_cell_cell
|
||||
|
||||
\overline{J}^{u,g}_{l\pm1/2,m,n} = -\frac{2\overline{\overline
|
||||
D}_{l\pm1,m,n}^g\overline{\overline
|
||||
D}_{l,m,n}^g}{\overline{\overline D}_{l\pm1,m,n}^g\Delta_l^u +
|
||||
\overline{\overline
|
||||
D}_{l,m,n}^g\Delta_{l\pm1}^u}
|
||||
\left(\pm\overline{\overline{\phi}}_{l\pm1,m,n}^g\mp
|
||||
\overline{\overline{\phi}}_{l,m,n}^g\right),
|
||||
|
||||
* cell-to-boundary coupling
|
||||
|
||||
.. math::
|
||||
:label: eq_cell_bound
|
||||
|
||||
\overline{J}^{u,g}_{l\pm1/2,m,n} = \pm\frac{2\overline{\overline
|
||||
D}_{l,m,n}^g\left(1 -
|
||||
\beta_{l\pm1/2,m,n}^{u,g}\right)}{4\overline{\overline
|
||||
D}_{l,m,n}^g\left(1 + \beta_{l\pm1/2,m,n}^{u,g}\right) + \left(1 -
|
||||
\beta_{l\pm1/2,m,n}^{u,g}\right)\Delta_l^u}\overline{\overline{\phi}}_{l,m,n}^{g}.
|
||||
|
||||
In Eqs. :eq:`eq_cell_cell` and :eq:`eq_cell_bound`, the :math:`\pm` refers to
|
||||
left (:math:`-x`) or right (:math:`+x`) surface in the :math:`x` direction,
|
||||
back (:math:`-y`) or front (:math:`+y`) surface in the :math:`y` direction and
|
||||
bottom (:math:`-z`) or top (:math:`+z`) surface in the :math:`z` direction. For
|
||||
cell-to-boundary coupling, a general albedo, :math:`\beta_{l\pm1/2,m,n}^{u,g}`,
|
||||
is used. The albedo is defined as the ratio of incoming (:math:`-` superscript)
|
||||
to outgoing (:math:`+` superscript) partial current on any surface represented
|
||||
as
|
||||
|
||||
.. math::
|
||||
:label: eq_albedo
|
||||
|
||||
\beta_{l\pm1/2,m,n}^{u,g} =
|
||||
\frac{\overline{J}^{u,g-}_{l\pm1/2,m,n}}{\overline{J}^{u,g+}_{l\pm1/2,m,n}}.
|
||||
|
||||
Common boundary conditions are: vacuum (:math:`\beta=0`), reflective
|
||||
(:math:`\beta=1`) and zero flux (:math:`\beta=-1`). Both eq. :eq:`eq_cell_cell`
|
||||
and eq. :eq:`eq_cell_bound` can be written in this generic form,
|
||||
|
||||
.. math::
|
||||
:label: eq_dtilde
|
||||
|
||||
\overline{J}^{u,g}_{l\pm1/2,m,n} = \widetilde{D}_{l,m,n}^{u,g} \left(\dots\right).
|
||||
|
||||
The parameter :math:`\widetilde{D}_{l,m,n}^{u,g}` represents the linear
|
||||
coupling term between current and flux. These current relationships can be
|
||||
sustituted into eq. :eq:`eq_neut_bal` to produce a linear system of multigroup
|
||||
diffusion equations for each spatial cell and energy group. However, a solution
|
||||
to these equations is not consistent with a higher order transport solution
|
||||
unless equivalence factors are present. This is because both the diffusion
|
||||
approximation, governed by Fick's Law, and spatial trunction error will produce
|
||||
differences. Therefore, a nonlinear parameter,
|
||||
:math:`\widehat{D}_{l,m,n}^{u,g}`, is added to eqs. :eq:`eq_cell_cell` and
|
||||
:eq:`eq_cell_bound`. These equations are, respectively,
|
||||
|
||||
.. math::
|
||||
:label: eq_dhat_cell
|
||||
|
||||
\overline{J}^{u,g}_{l\pm1/2,m,n} = -\widetilde{D}_{l,m,n}^{u,g}
|
||||
\left(\pm\overline{\overline{\phi}}_{l\pm1,m,n}^g\mp
|
||||
\overline{\overline{\phi}}_{l,m,n}^g\right) + \widehat{D}_{l,m,n}^{u,g}
|
||||
\left(\overline{\overline{\phi}}_{l\pm1,m,n}^g +
|
||||
\overline{\overline{\phi}}_{l,m,n}^g\right)
|
||||
|
||||
and
|
||||
|
||||
.. math::
|
||||
:label: eq_dhat_bound
|
||||
|
||||
\overline{J}^{u,g}_{l\pm1/2,m,n} = \pm\widetilde{D}_{l,m,n}^{u,g}
|
||||
\overline{\overline{\phi}}_{l,m,n}^{g} + \widehat{D}_{l,m,n}^{u,g}
|
||||
\overline{\overline{\phi}}_{l,m,n}^{g}.
|
||||
|
||||
The only unknown in each of these equations is the equivalence parameter. The
|
||||
current, linear coupling term and flux can either be obtained or derived from
|
||||
MC tallies. Thus, it is called nonlinear because it is dependent on the flux
|
||||
which is updated on the next iteration.
|
||||
|
||||
Equations :eq:`eq_dhat_cell` and :eq:`eq_dhat_bound` can be substituted into
|
||||
eq. :eq:`eq_neut_bal` to create a linear system of equations that is consistent
|
||||
with transport physics. One example of this equation is written for an
|
||||
interior cell,
|
||||
|
||||
.. math::
|
||||
:label: eq_cmfd_sys
|
||||
|
||||
\sum_{u\in
|
||||
x,y,x}\frac{1}{\Delta_l^u}\left[\left(-\tilde{D}_{l-1/2,m,n}^{u,g} -
|
||||
\hat{D}_{l-1/2,m,n}^{u,g}\right)\overline{\overline{\phi}}_{l-1,m,n}^g\right.
|
||||
+ \left(\tilde{D}_{l-1/2,m,n}^{u,g} +
|
||||
\tilde{D}_{l+1/2,m,n}^{u,g} - \hat{D}_{l-1/2,m,n}^{u,g} +
|
||||
\hat{D}_{l+1/2,m,n}^{u,g}\right)\overline{\overline{\phi}}_{l,m,n}^g
|
||||
\\ +
|
||||
\left. \left(-\tilde{D}_{l+1/2,m,n}^{u,g} +
|
||||
\hat{D}_{l+1/2,m,n}^{u,g}\right)\overline{\overline{\phi}}_{l+1,m,n}^g
|
||||
\right] +
|
||||
\overline{\overline\Sigma}_{t_{l,m,n}}^g\overline{\overline{\phi}}_{l,m,n}^g
|
||||
- \sum\limits_{h=1}^G\overline{\overline{\nu_s\Sigma}}^{h\rightarrow
|
||||
g}_{s_{l,m,n}}\overline{\overline{\phi}}_{l,m,n}^h =
|
||||
\frac{1}{k}\sum\limits_{h=1}^G\overline{\overline{\nu_f\Sigma}}^{h\rightarrow
|
||||
g}_{f_{l,m,n}}\overline{\overline{\phi}}_{l,m,n}^h.
|
||||
|
||||
It should be noted that before substitution, eq. :eq:`eq_neut_bal` was divided
|
||||
by the volume of the cell, :math:`\Delta_l^u\Delta_m^v\Delta_n^w`. Equation
|
||||
:eq:`eq_cmfd_sys` can be represented in operator form as
|
||||
|
||||
.. math::
|
||||
:label: eq_CMFDopers
|
||||
|
||||
\mathbb{M}\mathbf{\Phi} = \frac{1}{k}\mathbb{F}\mathbf{\Phi},
|
||||
|
||||
where :math:`\mathbb{M}` is the neutron loss matrix operator,
|
||||
:math:`\mathbb{F}` is the neutron production matrix operator,
|
||||
:math:`\mathbf{\Phi}` is the multigroup flux vector and :math:`k` is the
|
||||
eigenvalue. This generalized eigenvalue problem is solved to obtain fundamental
|
||||
mode multigroup fluxes and eigenvalue. In order to produce consistent results
|
||||
with transport theory from these equations, the neutron balance equation must
|
||||
have been satisfied by MC tallies. The desire is that CMFD equations will
|
||||
produce a more accurate source than MC after each fission source generation.
|
||||
|
||||
CMFD Feedback
|
||||
-------------
|
||||
|
||||
Now that a more accurate representation of the expected source distribution is
|
||||
estimated from CMFD, it needs to be communicated back to MC. The first step
|
||||
in this process is to generate a probability mass function that provides
|
||||
information about how probable it is for a neutron to be born in a given cell
|
||||
and energy group. This is represented as
|
||||
|
||||
.. math::
|
||||
:label: eq_cmfd_psrc
|
||||
|
||||
p_{l,m,n}^g =
|
||||
\frac{\sum_{h=1}^{G}\overline{\overline{\nu_f\Sigma}}^{h\rightarrow
|
||||
g}_{f_{l,m,n}}\overline{\overline{\phi}}_{l,m,n}^h\Delta_l^u\Delta_m^v
|
||||
\Delta_n^w}{\sum_n\sum_m\sum_l\sum_{h=1}^{G}\overline{
|
||||
\overline{\nu_f\Sigma}}^{h\rightarrow
|
||||
g}_{f_{l,m,n}}\overline{\overline{\phi}}_{l,m,n}^h\Delta_l^u\Delta_m^v
|
||||
\Delta_n^w}.
|
||||
|
||||
This equation can be multiplied by the number of source neutrons to obtain an
|
||||
estimate of the expected number of neutrons to be born in a given cell and
|
||||
energy group. This distribution can be compared to the MC source distribution
|
||||
to generate weight adjusted factors defined as
|
||||
|
||||
.. math::
|
||||
:label: eq_waf
|
||||
|
||||
f_{l,m,n}^g = \frac{Np_{l,m,n}^g}{\sum\limits_s w_s};\quad s\in
|
||||
\left(g,l,m,n\right).
|
||||
|
||||
The MC source distribution is represented on the same coarse mesh as
|
||||
CMFD by summing all neutrons' weights, :math:`w_s`, in a given cell and
|
||||
energy group. MC source weights can then be modified by this weight
|
||||
adjustment factor so that it matches the CMFD solution on the coarse
|
||||
mesh,
|
||||
|
||||
.. math::
|
||||
:label: src_mod
|
||||
|
||||
w^\prime_s = w_s\times f_{l,m,n}^g;\quad s\in \left(g,l,m,n\right).
|
||||
|
||||
It should be noted that heterogeneous information about local coordinates and
|
||||
energy remain constant throughout this modification process.
|
||||
|
||||
------------------------
|
||||
Implementation in OpenMC
|
||||
------------------------
|
||||
|
||||
The section describes how CMFD was implemented in OpenMC. Before the simulation
|
||||
begins, a user sets up a CMFD input file that contains the following basic
|
||||
information:
|
||||
|
||||
* CMFD mesh (space and energy),
|
||||
* boundary conditions at edge of mesh (albedos),
|
||||
* acceleration region (subset of mesh, optional),
|
||||
* fission source generation (FSG)/batch that CMFD should begin, and
|
||||
* whether CMFD feedback should be applied.
|
||||
|
||||
It should be noted that for more difficult simulations (e.g., light water
|
||||
reactors), there are other options available to users such as tally resetting
|
||||
parameters, effective down-scatter usage, tally estimator, etc. For more
|
||||
information please see :ref:`usersguide_cmfd`.
|
||||
|
||||
Of the options described above, the optional acceleration subset region is an
|
||||
uncommon feature. Because OpenMC only has a structured Cartesian mesh, mesh
|
||||
cells may overlay regions that don't contain fissionable material and may be so
|
||||
far from the core that the neutron flux is very low. If these regions were
|
||||
included in the CMFD solution, bad estimates of diffusion parameters may result
|
||||
and affect CMFD feedback. To deal with this, a user can carve out an active
|
||||
acceleration region from their structured Cartesian mesh. This is illustrated
|
||||
in diagram below. When placing a CMFD mesh over a geometry, the boundary
|
||||
conditions must be known at the global edges of the mesh. If the geometry is
|
||||
complex like the one below, one may have to cover the whole geometry including
|
||||
the reactor pressure vessel because we know that there is a zero incoming
|
||||
current boundary condition at the outer edge of the pressure vessel. This is
|
||||
not viable in practice because neutrons in simulations may not reach mesh cells
|
||||
that are near the pressure vessel. To circumvent this, one can shrink the mesh
|
||||
to cover just the core region as shown in the diagram. However, one must still
|
||||
estimate the boundary conditions at the global boundaries, but at these
|
||||
locations, they are not readily known. In OpenMC, one can carve out the active
|
||||
core region from the entire structured Cartesian mesh. This is shown in the
|
||||
diagram below by the darkened region over the core. The albedo boundary
|
||||
conditions at the active core/reflector boundary can be tallied indirectly
|
||||
during the MC simulation with incoming and outgoing partial currents. This
|
||||
allows the user to not have to worry about neutrons producing adequate tallies
|
||||
in mesh cells far away from the core.
|
||||
|
||||
.. tikz:: Diagram of CMFD acceleration mesh
|
||||
:libs: shapes, snakes, shadows, arrows, calc, decorations.markings, patterns, fit, matrix, spy
|
||||
:include: cmfd_tikz/meshfig.tikz
|
||||
|
||||
During an MC simulation, CMFD tallies are accumulated. The basic tallies needed
|
||||
are listed in Table :ref:`tab_tally`. Each tally is performed on a spatial and
|
||||
energy mesh basis. The surface area-integrated net current is tallied on every
|
||||
surface of the mesh. OpenMC tally objects are created by the CMFD code
|
||||
internally, and cross sections are calculated at each CMFD feedback iteration.
|
||||
The first CMFD iteration, controlled by the user, occurs just after tallies are
|
||||
communicated to the master processor. Once tallies are collapsed, cross
|
||||
sections, diffusion coefficients and equivalence parameters are calculated. This
|
||||
is performed only on the acceleration region if that option has been activated
|
||||
by the user. Once all diffusion parameters are calculated, CMFD matrices are
|
||||
formed where energy groups are the inner most iteration index. In OpenMC,
|
||||
compressed row storage sparse matrices are used due to the sparsity of CMFD
|
||||
operators. An example of this sparsity is shown for the 3-D BEAVRS model in
|
||||
figures :ref:`fig_loss` and :ref:`fig_prod` [BEAVRS]_. These matrices represent
|
||||
an assembly radial mesh, 24 cell mesh in the axial direction and two energy
|
||||
groups. The loss matrix is 99.92% sparse and the production matrix is 99.99%
|
||||
sparse. Although the loss matrix looks like it is tridiagonal, it is really a
|
||||
seven banded matrix with a block diagonal matrix for scattering. The production
|
||||
matrix is a :math:`2\times 2` block diagonal; however, zeros are present because
|
||||
no fission neutrons appear with energies in the thermal group.
|
||||
|
||||
.. _tab_tally:
|
||||
|
||||
.. table:: OpenMC CMFD tally list
|
||||
|
||||
+--------------------------------------------------------------------------------------------+----------------+---------------------------+
|
||||
+--------------------------------------------------------------------------------------------+----------------+---------------------------+
|
||||
| tally | score | filter |
|
||||
+============================================================================================+================+===========================+
|
||||
| \ :math:`\left\langle\overline{\overline\phi}_{l,m,n}^g | flux | mesh, energy |
|
||||
| \Delta_l^u\Delta_m^v\Delta_n^w\right\rangle` | | |
|
||||
+--------------------------------------------------------------------------------------------+----------------+---------------------------+
|
||||
| \ :math:`\left\langle\overline{\overline\Sigma}_{t_{l,m,n}}^g | total | mesh, energy |
|
||||
| \overline{\overline\phi}_{l,m,n}^g\Delta_l^u\Delta_m^v\Delta_n^w\right\rangle` | | |
|
||||
+--------------------------------------------------------------------------------------------+----------------+---------------------------+
|
||||
| \ :math:`\left\langle\overline{\overline{\nu_s\Sigma}}_{s1_{l,m,n}}^g | nu-scatter-1 | mesh, energy |
|
||||
| \overline{\overline\phi}_{l,m,n}^g\Delta_l^u\Delta_m^v\Delta_n^w\right\rangle` | | |
|
||||
+--------------------------------------------------------------------------------------------+----------------+---------------------------+
|
||||
| \ :math:`\left\langle\overline{\overline{\nu_s\Sigma}}_{s_{l,m,n}}^{h\rightarrow g} | nu-scatter | mesh, energy, energyout |
|
||||
| \overline{\overline\phi}_{l,m,n}^h\Delta_l^u\Delta_m^v\Delta_n^w\right\rangle` | | |
|
||||
+--------------------------------------------------------------------------------------------+----------------+---------------------------+
|
||||
| \ :math:`\left\langle\overline{\overline{\nu_f\Sigma}}_{f_{l,m,n}}^{h\rightarrow g} | nu-fission | mesh, energy, energyout |
|
||||
| \overline{\overline\phi}_{l,m,n}^h\Delta_l^u\Delta_m^v\Delta_n^w\right\rangle` | | |
|
||||
+--------------------------------------------------------------------------------------------+----------------+---------------------------+
|
||||
| \ :math:`\left\langle\overline{J}^{u,g}_{l\pm 1/2,m,n}\Delta_m^v\Delta_n^w\right\rangle` | current | mesh, energy |
|
||||
+--------------------------------------------------------------------------------------------+----------------+---------------------------+
|
||||
|
||||
.. _fig_loss:
|
||||
|
||||
.. figure:: ../_images/loss.png
|
||||
:scale: 50
|
||||
|
||||
Sparsity of Neutron Loss Operator
|
||||
|
||||
.. _fig_prod:
|
||||
|
||||
.. figure:: ../_images/prod.png
|
||||
:scale: 50
|
||||
|
||||
Sparsity of Neutron Production Operator
|
||||
|
||||
To solve the eigenvalue problem with these matrices, different source iteration
|
||||
and linear solvers can be used. The most common source iteration solver used is
|
||||
standard power iteration as described in [Gill]_. To accelerate these source
|
||||
iterations, a Wielandt shift scheme can be used as discussed in [Park]_. PETSc
|
||||
solvers were first implemented to perform the linear solution in parallel that
|
||||
occurs once per source iteration. When using PETSc, different types of parallel
|
||||
linear solvers and preconditioners can be used. By default, OpenMC uses an
|
||||
incomplete LU preconditioner and a GMRES Krylov solver. After some initial
|
||||
studies of parallelization with PETSc, it was observed that because CMFD
|
||||
matrices are very sparse, solution times do not scale well. An additional
|
||||
Gauss-Seidel linear solver with Chebyshev acceleration was added that is
|
||||
similar to the one used for CMFD in CASMO [Rhodes]_ and [Smith]_. This solver
|
||||
was implemented with a custom section for two energy groups. Because energy
|
||||
group is the inner most index, a block diagonal is formed when using more than
|
||||
one group. For two groups, it is easy to invert this diagonal analytically
|
||||
inside the Gauss-Seidel iterative solver. For more than two groups, this
|
||||
analytic inversion can still be performed, but with more computational effort.
|
||||
A standard Gauss-Seidel solver is used for more than two groups.
|
||||
|
||||
Besides a power iteration, a Jacobian-free Newton-Krylov method was also
|
||||
implemented to obtain eigenvalue and multigroup fluxes as described in [Gill]_
|
||||
and [Knoll]_. This method is not the primary one used, but has gotten recent
|
||||
attention due to its coupling advantages to other physics such as thermal
|
||||
hydraulics. Once multigroup fluxes are obtained, a normalized fission source is
|
||||
calculated in the code using eq. :eq:`eq_cmfd_psrc` directly.
|
||||
|
||||
The next step in the process is to compute weight adjustment factors. These are
|
||||
calculated by taking the ratio of the expected number of neutrons from the CMFD
|
||||
source distribution to the current number of neutrons in each mesh. It is
|
||||
straightforward to compute the CMFD number of neutrons because it is the
|
||||
product between the total starting initial weight of neutrons and the CMFD
|
||||
normalized fission source distribution. To compute the number of neutrons from
|
||||
the current MC source, OpenMC sums the statistical
|
||||
weights of neutrons from the source bank on a given spatial and energy mesh.
|
||||
Once weight adjustment factors were calculated, each neutron's statistical
|
||||
weight in the source bank was modified according to its location and energy.
|
||||
Examples of CMFD simulations using OpenMC can be found in [Herman_Thesis]_.
|
||||
|
||||
----------
|
||||
References
|
||||
----------
|
||||
|
||||
.. [BEAVRS] Nick Horelik, Bryan Herman. *Benchmark for Evaluation And Verification of Reactor
|
||||
Simulations*. Massachusetts Institute of Technology, http://crpg.mit.edu/pub/beavrs
|
||||
, 2013.
|
||||
|
||||
.. [Gill] Daniel F. Gill. *Newton-Krylov methods for the solution of the k-eigenvalue problem in
|
||||
multigroup neutronics calculations*. Ph.D. thesis, Pennsylvania State University, 2010.
|
||||
|
||||
.. [Hebert] Alain Hebert. *Applied reactor physics*. Presses Internationales Polytechnique,
|
||||
Montreal, 2009.
|
||||
|
||||
.. [Herman] Bryan R. Herman, Benoit Forget, Kord Smith, and Brian N. Aviles. Improved
|
||||
diffusion coefficients generated from Monte Carlo codes. In *Proceedings of M&C
|
||||
2013*, Sun Valley, ID, USA, May 5 - 9, 2013.
|
||||
|
||||
.. [Herman_Thesis] Bryan R. Herman. *Monte Carlo and Thermal Hydraulic Coupling using
|
||||
Low-Order Nonlinear Diffusion Acceleration*. Sc.D. thesis,
|
||||
Massachusetts Institute of Technology, 2014.
|
||||
|
||||
.. [Knoll] D.A. Knoll, H. Park, and C. Newman. *Acceleration of k-eigenvalue/criticality
|
||||
calculations using the Jacobian-free Newton-Krylov method*. Nuclear Science and
|
||||
Engineering, 167:133–140, 2011.
|
||||
|
||||
.. [Park] H. Park, D.A. Knoll, and C.K. Newman. *Nonlinear acceleration of transport
|
||||
criticality problems*. Nuclear Science and Engineering, 172:52–65, 2012.
|
||||
|
||||
.. [Rhodes] Joel Rhodes and Malte Edenius. *CASMO-4 --- A Fuel Assembly Burnup Program.
|
||||
User’s Manual*. Studsvik of America, ssp-09/443-u rev 0, proprietary edition, 2001.
|
||||
|
||||
.. [Smith] Kord S Smith and Joel D Rhodes III. *Full-core, 2-D, LWR core calculations with
|
||||
CASMO-4E*. In Proceedings of PHYSOR 2002, Seoul, Korea, October 7 - 10, 2002.
|
||||
19
docs/source/methods/cmfd_tikz/cmfd_flow.tikz
Normal file
19
docs/source/methods/cmfd_tikz/cmfd_flow.tikz
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
\begin{tikzpicture}
|
||||
\matrix[every node/.style={draw, thick, minimum width=3cm, minimum height=1cm, align=center}, column sep=2cm, row sep=1cm] (m) {
|
||||
\node[draw, fill=red!40] (start) {Batch $i$ \\ tally NDA}; & \\
|
||||
\node[draw, diamond, aspect=2, fill=green!40] (cmfd) {Run NDA?}; & \node[draw, fill=red!40] (end) {Batch $i + 1$ \\ tally NDA}; \\
|
||||
\node[draw, fill=blue!40] (xs) {Calculate XS \& DC}; & \node[draw, fill=blue!40] (modify) {Modify MC Source}; \\
|
||||
\node[draw, fill=blue!40] (nonlinear) {Calculate Equivalence}; & \node[draw, fill=blue!40] (eqs) {Solve NDA eqs.};\\
|
||||
};
|
||||
|
||||
\begin{scope}[every path/.style={->,very thick,draw}]
|
||||
\draw (start.south) -- (cmfd.north);
|
||||
\draw (cmfd.east) -- node[above] {no} (end.west);
|
||||
\draw (cmfd.south) -- node[right] {yes} (xs.north);
|
||||
\draw (xs.south) -- (nonlinear.north);
|
||||
\draw (nonlinear.east) -- (eqs.west);
|
||||
\draw (eqs.north) -- (modify.south);
|
||||
\draw (modify.north) -- (end.south);
|
||||
\end{scope}
|
||||
|
||||
\end{tikzpicture}
|
||||
628
docs/source/methods/cmfd_tikz/meshfig.tikz
Normal file
628
docs/source/methods/cmfd_tikz/meshfig.tikz
Normal file
|
|
@ -0,0 +1,628 @@
|
|||
|
||||
% these dimensions are determined in arrow_dimms.ods
|
||||
|
||||
\def\scale{1.0}
|
||||
|
||||
\def\latWidth{0.2808363589*\scale}
|
||||
|
||||
\def\RPVOR{3*\scale}
|
||||
\def\rectW{0.75*\scale}
|
||||
\def\RPVIR{2.8694005485*\scale}
|
||||
\def\BarrelIR{2.4547472901*\scale}
|
||||
\def\BarrelOR{2.5293848766*\scale}
|
||||
\def\ShieldOR{2.6040224631*\scale}
|
||||
|
||||
\def\bafCIRx{0.9829272561*\scale}
|
||||
\def\bafCIRy{2.1062726917*\scale}
|
||||
\def\bafCORx{1.0119529842*\scale}
|
||||
\def\bafCORy{2.1352984197*\scale}
|
||||
\def\bafMIRx{1.8254363328*\scale}
|
||||
\def\bafMIRy{1.5445999739*\scale}
|
||||
\def\bafMORx{1.8544620609*\scale}
|
||||
\def\bafMORy{1.573625702*\scale}
|
||||
|
||||
\tikzset{Assembly/.style={
|
||||
inner sep=0pt,
|
||||
text width=\latWidth in,
|
||||
minimum size=\latWidth in,
|
||||
draw=black,
|
||||
align=center
|
||||
}
|
||||
}
|
||||
|
||||
\def\tkzRPV{(0,0) circle (\RPVIR) (0,0) circle (\RPVOR)}
|
||||
\def\tkzBarrel{(0,0) circle (\BarrelIR) (0,0) circle (\BarrelOR)}
|
||||
\def\tkzShields{(0,0) circle (\BarrelOR) (0,0) circle (\ShieldOR)}
|
||||
|
||||
\def\tkzBaffCOR{(-\bafCORx, -\bafCORy) rectangle (\bafCORx, \bafCORy)}
|
||||
\def\tkzBaffCIR{(-\bafCIRx, -\bafCIRy) rectangle (\bafCIRx, \bafCIRy)}
|
||||
\def\tkzBaffMOR{(-\bafMORx, -\bafMORy) rectangle (\bafMORx, \bafMORy)}
|
||||
\def\tkzBaffMIR{(-\bafMIRx, -\bafMIRy) rectangle (\bafMIRx, \bafMIRy) }
|
||||
\def\tkzBaffleC{ \tkzBaffCIR \tkzBaffCOR }
|
||||
\def\tkzBaffleM{ \tkzBaffMIR \tkzBaffMOR }
|
||||
|
||||
\def\tkzBaffCClip{\tkzBaffCIR (-\RPVOR, -\RPVOR) rectangle (\RPVOR, \RPVOR)}
|
||||
\def\tkzBaffMClip{\tkzBaffMIR (-\RPVOR, -\RPVOR) rectangle (\RPVOR, \RPVOR)}
|
||||
|
||||
\def\highenr{blue!50}
|
||||
\def\midenr{yellow!50}
|
||||
\def\lowenr{red!50}
|
||||
\def\lightgray{black!25}
|
||||
\def\darkgray{black!80}
|
||||
|
||||
\begin{tikzpicture}[x=1in,y=1in, xshift=3in]
|
||||
\scalebox{0.6}{
|
||||
% draw RPV, barrel, and shield panels
|
||||
|
||||
\path[fill=black,even odd rule] \tkzRPV;
|
||||
\path[fill=black,even odd rule] \tkzBarrel;
|
||||
\begin{scope}
|
||||
\clip[rotate around={45:(0,0)}] (-\RPVOR, -\rectW) rectangle (\RPVOR, \rectW) (-\rectW, \RPVOR) rectangle (\rectW, -\RPVOR);
|
||||
\path[fill=black,even odd rule] \tkzShields;
|
||||
\end{scope}
|
||||
|
||||
|
||||
% draw assembly row/column headers
|
||||
|
||||
\draw[red, thick] ($(-7*\latWidth,\RPVOR/\latWidth*\latWidth)$) node[above, anchor=south] {R} -- ($(-7*\latWidth,4*\latWidth)$);
|
||||
\draw[red, thick] ($(-6*\latWidth,\RPVOR/\latWidth*\latWidth)$) node[above, anchor=south] {P} -- ($(-6*\latWidth,6*\latWidth)$);
|
||||
\draw[red, thick] ($(-5*\latWidth,\RPVOR/\latWidth*\latWidth)$) node[above, anchor=south] {N} -- ($(-5*\latWidth,7*\latWidth)$);
|
||||
\draw[red, thick] ($(-4*\latWidth,\RPVOR/\latWidth*\latWidth)$) node[above, anchor=south] {M} -- ($(-4*\latWidth,7*\latWidth)$);
|
||||
\draw[red, thick] ($(-3*\latWidth,\RPVOR/\latWidth*\latWidth)$) node[above, anchor=south] {L} -- ($(-3*\latWidth,8*\latWidth)$);
|
||||
\draw[red, thick] ($(-2*\latWidth,\RPVOR/\latWidth*\latWidth)$) node[above, anchor=south] {K} -- ($(-2*\latWidth,8*\latWidth)$);
|
||||
\draw[red, thick] ($(-1*\latWidth,\RPVOR/\latWidth*\latWidth)$) node[above, anchor=south] {J} -- ($(-1*\latWidth,8*\latWidth)$);
|
||||
\draw[red, thick] ($(-0*\latWidth,\RPVOR/\latWidth*\latWidth)$) node[above, anchor=south] {H} -- ($(-0*\latWidth,8*\latWidth)$);
|
||||
\draw[red, thick] ($(1*\latWidth,\RPVOR/\latWidth*\latWidth)$) node[above, anchor=south] {G} -- ($(1*\latWidth,8*\latWidth)$);
|
||||
\draw[red, thick] ($(2*\latWidth,\RPVOR/\latWidth*\latWidth)$) node[above, anchor=south] {F} -- ($(2*\latWidth,8*\latWidth)$);
|
||||
\draw[red, thick] ($(3*\latWidth,\RPVOR/\latWidth*\latWidth)$) node[above, anchor=south] {E} -- ($(3*\latWidth,8*\latWidth)$);
|
||||
\draw[red, thick] ($(4*\latWidth,\RPVOR/\latWidth*\latWidth)$) node[above, anchor=south] {D} -- ($(4*\latWidth,7*\latWidth)$);
|
||||
\draw[red, thick] ($(5*\latWidth,\RPVOR/\latWidth*\latWidth)$) node[above, anchor=south] {C} -- ($(5*\latWidth,7*\latWidth)$);
|
||||
\draw[red, thick] ($(6*\latWidth,\RPVOR/\latWidth*\latWidth)$) node[above, anchor=south] {B} -- ($(6*\latWidth,6*\latWidth)$);
|
||||
\draw[red, thick] ($(7*\latWidth,\RPVOR/\latWidth*\latWidth)$) node[above, anchor=south] {A} -- ($(7*\latWidth,4*\latWidth)$);
|
||||
|
||||
\begin{scope}[rotate=90]
|
||||
\draw[red, thick] ($(-7*\latWidth,\RPVOR/\latWidth*\latWidth)$) node[left, anchor=east] {15} -- ($(-7*\latWidth,4*\latWidth)$);
|
||||
\draw[red, thick] ($(-6*\latWidth,\RPVOR/\latWidth*\latWidth)$) node[left, anchor=east] {14} -- ($(-6*\latWidth,6*\latWidth)$);
|
||||
\draw[red, thick] ($(-5*\latWidth,\RPVOR/\latWidth*\latWidth)$) node[left, anchor=east] {13} -- ($(-5*\latWidth,7*\latWidth)$);
|
||||
\draw[red, thick] ($(-4*\latWidth,\RPVOR/\latWidth*\latWidth)$) node[left, anchor=east] {12} -- ($(-4*\latWidth,7*\latWidth)$);
|
||||
\draw[red, thick] ($(-3*\latWidth,\RPVOR/\latWidth*\latWidth)$) node[left, anchor=east] {11} -- ($(-3*\latWidth,8*\latWidth)$);
|
||||
\draw[red, thick] ($(-2*\latWidth,\RPVOR/\latWidth*\latWidth)$) node[left, anchor=east] {10} -- ($(-2*\latWidth,8*\latWidth)$);
|
||||
\draw[red, thick] ($(-1*\latWidth,\RPVOR/\latWidth*\latWidth)$) node[left, anchor=east] {9} -- ($(-1*\latWidth,8*\latWidth)$);
|
||||
\draw[red, thick] ($(-0*\latWidth,\RPVOR/\latWidth*\latWidth)$) node[left, anchor=east] {8} -- ($(-0*\latWidth,8*\latWidth)$);
|
||||
\draw[red, thick] ($(1*\latWidth,\RPVOR/\latWidth*\latWidth)$) node[left, anchor=east] {7} -- ($(1*\latWidth,8*\latWidth)$);
|
||||
\draw[red, thick] ($(2*\latWidth,\RPVOR/\latWidth*\latWidth)$) node[left, anchor=east] {6} -- ($(2*\latWidth,8*\latWidth)$);
|
||||
\draw[red, thick] ($(3*\latWidth,\RPVOR/\latWidth*\latWidth)$) node[left, anchor=east] {5} -- ($(3*\latWidth,8*\latWidth)$);
|
||||
\draw[red, thick] ($(4*\latWidth,\RPVOR/\latWidth*\latWidth)$) node[left, anchor=east] {4} -- ($(4*\latWidth,7*\latWidth)$);
|
||||
\draw[red, thick] ($(5*\latWidth,\RPVOR/\latWidth*\latWidth)$) node[left, anchor=east] {3} -- ($(5*\latWidth,7*\latWidth)$);
|
||||
\draw[red, thick] ($(6*\latWidth,\RPVOR/\latWidth*\latWidth)$) node[left, anchor=east] {2} -- ($(6*\latWidth,6*\latWidth)$);
|
||||
\draw[red, thick] ($(7*\latWidth,\RPVOR/\latWidth*\latWidth)$) node[left, anchor=east] {1} -- ($(7*\latWidth,4*\latWidth)$);
|
||||
\end{scope}
|
||||
|
||||
% draw fuel assembly nodes
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-8*\latWidth,8*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-7*\latWidth,8*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-6*\latWidth,8*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-5*\latWidth,8*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-4*\latWidth,8*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-3*\latWidth,8*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-2*\latWidth,8*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-1*\latWidth,8*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-0*\latWidth,8*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 1*\latWidth,8*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 2*\latWidth,8*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 3*\latWidth,8*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 4*\latWidth,8*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 5*\latWidth,8*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 6*\latWidth,8*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 7*\latWidth,8*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 8*\latWidth,8*\latWidth)$) {};
|
||||
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-8*\latWidth,7*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-7*\latWidth,7*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-6*\latWidth,7*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-5*\latWidth,7*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-4*\latWidth,7*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($(-3*\latWidth,7*\latWidth)$) {}; % L1
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-3*\latWidth,7*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($(-2*\latWidth,7*\latWidth)$) {6}; % K1
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-2*\latWidth,7*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($(-1*\latWidth,7*\latWidth)$) {}; % J1
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-1*\latWidth,7*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($(-0*\latWidth,7*\latWidth)$) {6}; % H1
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-0*\latWidth,7*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($( 1*\latWidth,7*\latWidth)$) {}; % G1
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 1*\latWidth,7*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($( 2*\latWidth,7*\latWidth)$) {6}; % F1
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 2*\latWidth,7*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($( 3*\latWidth,7*\latWidth)$) {}; % E1
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 3*\latWidth,7*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 4*\latWidth,7*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 5*\latWidth,7*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 6*\latWidth,7*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 7*\latWidth,7*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 8*\latWidth,7*\latWidth)$) {};
|
||||
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-8*\latWidth,6*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-7*\latWidth,6*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-6*\latWidth,6*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($(-5*\latWidth,6*\latWidth)$) {}; % N2
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-5*\latWidth,6*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($(-4*\latWidth,6*\latWidth)$) {}; % M2
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-4*\latWidth,6*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($(-3*\latWidth,6*\latWidth)$) {16}; % L2
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-3*\latWidth,6*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($(-2*\latWidth,6*\latWidth)$) {}; % K2
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-2*\latWidth,6*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($(-1*\latWidth,6*\latWidth)$) {20}; % J2
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-1*\latWidth,6*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($(-0*\latWidth,6*\latWidth)$) {}; % H2
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-0*\latWidth,6*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($( 1*\latWidth,6*\latWidth)$) {20}; % G2
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 1*\latWidth,6*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($( 2*\latWidth,6*\latWidth)$) {}; % F2
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 2*\latWidth,6*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($( 3*\latWidth,6*\latWidth)$) {16}; % E2
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 3*\latWidth,6*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($( 4*\latWidth,6*\latWidth)$) {}; % D2
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 4*\latWidth,6*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($( 5*\latWidth,6*\latWidth)$) {}; % C2
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 5*\latWidth,6*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 6*\latWidth,6*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 7*\latWidth,6*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 8*\latWidth,6*\latWidth)$) {};
|
||||
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-8*\latWidth,5*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-7*\latWidth,5*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($(-6*\latWidth,5*\latWidth)$) {}; % P3
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-6*\latWidth,5*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($(-5*\latWidth,5*\latWidth)$) {15}; % N3
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-5*\latWidth,5*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($(-4*\latWidth,5*\latWidth)$) {16}; % M3
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-4*\latWidth,5*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($(-3*\latWidth,5*\latWidth)$) {}; % L3
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-3*\latWidth,5*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($(-2*\latWidth,5*\latWidth)$) {16}; % K3
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-2*\latWidth,5*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($(-1*\latWidth,5*\latWidth)$) {}; % J3
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-1*\latWidth,5*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($(-0*\latWidth,5*\latWidth)$) {16}; % H3
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-0*\latWidth,5*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($( 1*\latWidth,5*\latWidth)$) {}; % G3
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 1*\latWidth,5*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($( 2*\latWidth,5*\latWidth)$) {16}; % F3
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 2*\latWidth,5*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($( 3*\latWidth,5*\latWidth)$) {}; % E3
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 3*\latWidth,5*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($( 4*\latWidth,5*\latWidth)$) {16}; % D3
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 4*\latWidth,5*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($( 5*\latWidth,5*\latWidth)$) {15}; % C3
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 5*\latWidth,5*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($( 6*\latWidth,5*\latWidth)$) {}; % B3
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 6*\latWidth,5*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 7*\latWidth,5*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 8*\latWidth,5*\latWidth)$) {};
|
||||
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-8*\latWidth,4*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-7*\latWidth,4*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($(-6*\latWidth,4*\latWidth)$) {}; % P4
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-6*\latWidth,4*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($(-5*\latWidth,4*\latWidth)$) {16}; % N4
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-5*\latWidth,4*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($(-4*\latWidth,4*\latWidth)$) {}; % M4
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-4*\latWidth,4*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($(-3*\latWidth,4*\latWidth)$) {16}; % L4
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-3*\latWidth,4*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($(-2*\latWidth,4*\latWidth)$) {}; % K4
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-2*\latWidth,4*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($(-1*\latWidth,4*\latWidth)$) {12}; % J4
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-1*\latWidth,4*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($(-0*\latWidth,4*\latWidth)$) {}; % H4
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-0*\latWidth,4*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($( 1*\latWidth,4*\latWidth)$) {12}; % G4
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 1*\latWidth,4*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($( 2*\latWidth,4*\latWidth)$) {}; % F4
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 2*\latWidth,4*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($( 3*\latWidth,4*\latWidth)$) {16}; % E4
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 3*\latWidth,4*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($( 4*\latWidth,4*\latWidth)$) {}; % D4
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 4*\latWidth,4*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($( 5*\latWidth,4*\latWidth)$) {16}; % C4
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 5*\latWidth,4*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($( 6*\latWidth,4*\latWidth)$) {}; % B4
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 6*\latWidth,4*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 7*\latWidth,4*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 8*\latWidth,4*\latWidth)$) {};
|
||||
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-8*\latWidth,3*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($(-7*\latWidth,3*\latWidth)$) {}; % R5
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-7*\latWidth,3*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($(-6*\latWidth,3*\latWidth)$) {16}; % P5
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-6*\latWidth,3*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($(-5*\latWidth,3*\latWidth)$) {}; % N5
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-5*\latWidth,3*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($(-4*\latWidth,3*\latWidth)$) {16}; % M5
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-4*\latWidth,3*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($(-3*\latWidth,3*\latWidth)$) {}; % L5
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-3*\latWidth,3*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($(-2*\latWidth,3*\latWidth)$) {12}; % K5
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-2*\latWidth,3*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($(-1*\latWidth,3*\latWidth)$) {}; % J5
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-1*\latWidth,3*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($(-0*\latWidth,3*\latWidth)$) {12}; % H5
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-0*\latWidth,3*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($( 1*\latWidth,3*\latWidth)$) {}; % G5
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 1*\latWidth,3*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($( 2*\latWidth,3*\latWidth)$) {12}; % F5
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 2*\latWidth,3*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($( 3*\latWidth,3*\latWidth)$) {}; % E5
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 3*\latWidth,3*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($( 4*\latWidth,3*\latWidth)$) {16}; % D5
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 4*\latWidth,3*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($( 5*\latWidth,3*\latWidth)$) {}; % C5
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 5*\latWidth,3*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($( 6*\latWidth,3*\latWidth)$) {16}; % B5
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 6*\latWidth,3*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($( 7*\latWidth,3*\latWidth)$) {}; % A5
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 7*\latWidth,3*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 8*\latWidth,3*\latWidth)$) {};
|
||||
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-8*\latWidth,2*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($(-7*\latWidth,2*\latWidth)$) {6}; % R6
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-7*\latWidth,2*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($(-6*\latWidth,2*\latWidth)$) {}; % P6
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-6*\latWidth,2*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($(-5*\latWidth,2*\latWidth)$) {16}; % N6
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-5*\latWidth,2*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($(-4*\latWidth,2*\latWidth)$) {}; % M6
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-4*\latWidth,2*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($(-3*\latWidth,2*\latWidth)$) {12}; % L6
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-3*\latWidth,2*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($(-2*\latWidth,2*\latWidth)$) {}; % K6
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-2*\latWidth,2*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($(-1*\latWidth,2*\latWidth)$) {12}; % J6
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-1*\latWidth,2*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($(-0*\latWidth,2*\latWidth)$) {}; % H6
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-0*\latWidth,2*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($( 1*\latWidth,2*\latWidth)$) {12}; % G6
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 1*\latWidth,2*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($( 2*\latWidth,2*\latWidth)$) {}; % F6
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 2*\latWidth,2*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($( 3*\latWidth,2*\latWidth)$) {12}; % E6
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 3*\latWidth,2*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($( 4*\latWidth,2*\latWidth)$) {}; % D6
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 4*\latWidth,2*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($( 5*\latWidth,2*\latWidth)$) {16}; % C6
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 5*\latWidth,2*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($( 6*\latWidth,2*\latWidth)$) {}; % B6
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 6*\latWidth,2*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($( 7*\latWidth,2*\latWidth)$) {6}; % A6
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 7*\latWidth,2*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 8*\latWidth,2*\latWidth)$) {};
|
||||
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-8*\latWidth,1*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($(-7*\latWidth,1*\latWidth)$) {}; % R7
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-7*\latWidth,1*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($(-6*\latWidth,1*\latWidth)$) {20}; % P7
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-6*\latWidth,1*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($(-5*\latWidth,1*\latWidth)$) {}; % N7
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-5*\latWidth,1*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($(-4*\latWidth,1*\latWidth)$) {12}; % M7
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-4*\latWidth,1*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($(-3*\latWidth,1*\latWidth)$) {}; % L7
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-3*\latWidth,1*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($(-2*\latWidth,1*\latWidth)$) {12}; % K7
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-2*\latWidth,1*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($(-1*\latWidth,1*\latWidth)$) {}; % J7
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-1*\latWidth,1*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($(-0*\latWidth,1*\latWidth)$) {16}; % H7
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-0*\latWidth,1*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($( 1*\latWidth,1*\latWidth)$) {}; % G7
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 1*\latWidth,1*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($( 2*\latWidth,1*\latWidth)$) {12}; % F7
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 2*\latWidth,1*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($( 3*\latWidth,1*\latWidth)$) {}; % E7
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 3*\latWidth,1*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($( 4*\latWidth,1*\latWidth)$) {12}; % D7
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 4*\latWidth,1*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($( 5*\latWidth,1*\latWidth)$) {}; % C7
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 5*\latWidth,1*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($( 6*\latWidth,1*\latWidth)$) {20}; % B7
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 6*\latWidth,1*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($( 7*\latWidth,1*\latWidth)$) {}; % A7
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 7*\latWidth,1*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 8*\latWidth,1*\latWidth)$) {};
|
||||
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-8*\latWidth,0*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($(-7*\latWidth,0*\latWidth)$) {6}; % R8
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-7*\latWidth,0*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($(-6*\latWidth,0*\latWidth)$) {}; % P8
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-6*\latWidth,0*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($(-5*\latWidth,0*\latWidth)$) {16}; % N8
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-5*\latWidth,0*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($(-4*\latWidth,0*\latWidth)$) {}; % M8
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-4*\latWidth,0*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($(-3*\latWidth,0*\latWidth)$) {12}; % L8
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-3*\latWidth,0*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($(-2*\latWidth,0*\latWidth)$) {}; % K8
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-2*\latWidth,0*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($(-1*\latWidth,0*\latWidth)$) {16}; % J8
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-1*\latWidth,0*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($(-0*\latWidth,0*\latWidth)$) {}; % H8
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-0*\latWidth,0*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($( 1*\latWidth,0*\latWidth)$) {16}; % G8
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 1*\latWidth,0*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($( 2*\latWidth,0*\latWidth)$) {}; % F8
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 2*\latWidth,0*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($( 3*\latWidth,0*\latWidth)$) {12}; % E8
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 3*\latWidth,0*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($( 4*\latWidth,0*\latWidth)$) {}; % D8
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 4*\latWidth,0*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($( 5*\latWidth,0*\latWidth)$) {16}; % C8
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 5*\latWidth,0*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($( 6*\latWidth,0*\latWidth)$) {}; % B8
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 6*\latWidth,0*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($( 7*\latWidth,0*\latWidth)$) {6}; % A8
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 7*\latWidth,0*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 8*\latWidth,0*\latWidth)$) {};
|
||||
|
||||
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-8*\latWidth,-1*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($(-7*\latWidth,-1*\latWidth)$) {}; % R9
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-7*\latWidth,-1*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($(-6*\latWidth,-1*\latWidth)$) {20}; % P9
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-6*\latWidth,-1*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($(-5*\latWidth,-1*\latWidth)$) {}; % N9
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-5*\latWidth,-1*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($(-4*\latWidth,-1*\latWidth)$) {12}; % M9
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-4*\latWidth,-1*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($(-3*\latWidth,-1*\latWidth)$) {}; % L9
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-3*\latWidth,-1*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($(-2*\latWidth,-1*\latWidth)$) {12}; % K9
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-2*\latWidth,-1*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($(-1*\latWidth,-1*\latWidth)$) {}; % J9
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-1*\latWidth,-1*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($(-0*\latWidth,-1*\latWidth)$) {16}; % H9
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-0*\latWidth,-1*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($( 1*\latWidth,-1*\latWidth)$) {}; % G9
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 1*\latWidth,-1*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($( 2*\latWidth,-1*\latWidth)$) {12}; % F9
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 2*\latWidth,-1*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($( 3*\latWidth,-1*\latWidth)$) {}; % E9
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 3*\latWidth,-1*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($( 4*\latWidth,-1*\latWidth)$) {12}; % D9
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 4*\latWidth,-1*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($( 5*\latWidth,-1*\latWidth)$) {}; % C9
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 5*\latWidth,-1*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($( 6*\latWidth,-1*\latWidth)$) {20}; % B9
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 6*\latWidth,-1*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($( 7*\latWidth,-1*\latWidth)$) {}; % A9
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 7*\latWidth,-1*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 8*\latWidth,-1*\latWidth)$) {};
|
||||
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-8*\latWidth,-2*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($(-7*\latWidth,-2*\latWidth)$) {6}; % R10
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-7*\latWidth,-2*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($(-6*\latWidth,-2*\latWidth)$) {}; % P10
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-6*\latWidth,-2*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($(-5*\latWidth,-2*\latWidth)$) {16}; % N10
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-5*\latWidth,-2*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($(-4*\latWidth,-2*\latWidth)$) {}; % M10
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-4*\latWidth,-2*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($(-3*\latWidth,-2*\latWidth)$) {12}; % L10
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-3*\latWidth,-2*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($(-2*\latWidth,-2*\latWidth)$) {}; % K10
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-2*\latWidth,-2*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($(-1*\latWidth,-2*\latWidth)$) {12}; % J10
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-1*\latWidth,-2*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($(-0*\latWidth,-2*\latWidth)$) {}; % H10
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-0*\latWidth,-2*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($( 1*\latWidth,-2*\latWidth)$) {12}; % G10
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 1*\latWidth,-2*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($( 2*\latWidth,-2*\latWidth)$) {}; % F10
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 2*\latWidth,-2*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($( 3*\latWidth,-2*\latWidth)$) {12}; % E10
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 3*\latWidth,-2*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($( 4*\latWidth,-2*\latWidth)$) {}; % D10
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 4*\latWidth,-2*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($( 5*\latWidth,-2*\latWidth)$) {16}; % C10
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 5*\latWidth,-2*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($( 6*\latWidth,-2*\latWidth)$) {}; % B10
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 6*\latWidth,-2*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($( 7*\latWidth,-2*\latWidth)$) {6}; % A10
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 7*\latWidth,-2*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 8*\latWidth,-2*\latWidth)$) {};
|
||||
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-8*\latWidth,-3*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($(-7*\latWidth,-3*\latWidth)$) {}; % R11
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-7*\latWidth,-3*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($(-6*\latWidth,-3*\latWidth)$) {16}; % P11
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-6*\latWidth,-3*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($(-5*\latWidth,-3*\latWidth)$) {}; % N11
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-5*\latWidth,-3*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($(-4*\latWidth,-3*\latWidth)$) {16}; % M11
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-4*\latWidth,-3*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($(-3*\latWidth,-3*\latWidth)$) {}; % L11
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-3*\latWidth,-3*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($(-2*\latWidth,-3*\latWidth)$) {12}; % K11
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-2*\latWidth,-3*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($(-1*\latWidth,-3*\latWidth)$) {}; % J11
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-1*\latWidth,-3*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($(-0*\latWidth,-3*\latWidth)$) {12}; % H11
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-0*\latWidth,-3*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($( 1*\latWidth,-3*\latWidth)$) {}; % G11
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 1*\latWidth,-3*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($( 2*\latWidth,-3*\latWidth)$) {12}; % F11
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 2*\latWidth,-3*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($( 3*\latWidth,-3*\latWidth)$) {}; % E11
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 3*\latWidth,-3*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($( 4*\latWidth,-3*\latWidth)$) {16}; % D11
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 4*\latWidth,-3*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($( 5*\latWidth,-3*\latWidth)$) {}; % C11
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 5*\latWidth,-3*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($( 6*\latWidth,-3*\latWidth)$) {16}; % B11
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 6*\latWidth,-3*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($( 7*\latWidth,-3*\latWidth)$) {}; % A11
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 7*\latWidth,-3*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 8*\latWidth,-3*\latWidth)$) {};
|
||||
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-8*\latWidth,-4*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-7*\latWidth,-4*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($(-6*\latWidth,-4*\latWidth)$) {}; % P12
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-6*\latWidth,-4*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($(-5*\latWidth,-4*\latWidth)$) {16}; % N12
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-5*\latWidth,-4*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($(-4*\latWidth,-4*\latWidth)$) {}; % M12
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-4*\latWidth,-4*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($(-3*\latWidth,-4*\latWidth)$) {16}; % L12
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-3*\latWidth,-4*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($(-2*\latWidth,-4*\latWidth)$) {}; % K12
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-2*\latWidth,-4*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($(-1*\latWidth,-4*\latWidth)$) {12}; % J12
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-1*\latWidth,-4*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($(-0*\latWidth,-4*\latWidth)$) {}; % H12
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-0*\latWidth,-4*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($( 1*\latWidth,-4*\latWidth)$) {12}; % G12
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 1*\latWidth,-4*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($( 2*\latWidth,-4*\latWidth)$) {}; % F12
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 2*\latWidth,-4*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($( 3*\latWidth,-4*\latWidth)$) {16}; % E12
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 3*\latWidth,-4*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($( 4*\latWidth,-4*\latWidth)$) {}; % D12
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 4*\latWidth,-4*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($( 5*\latWidth,-4*\latWidth)$) {16}; % C12
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 5*\latWidth,-4*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($( 6*\latWidth,-4*\latWidth)$) {}; % B12
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 6*\latWidth,-4*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 7*\latWidth,-4*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 8*\latWidth,-4*\latWidth)$) {};
|
||||
|
||||
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-8*\latWidth,-5*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-7*\latWidth,-5*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($(-6*\latWidth,-5*\latWidth)$) {}; % P13
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-6*\latWidth,-5*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($(-5*\latWidth,-5*\latWidth)$) {15}; % N13
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-5*\latWidth,-5*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($(-4*\latWidth,-5*\latWidth)$) {16}; % M13
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-4*\latWidth,-5*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($(-3*\latWidth,-5*\latWidth)$) {}; % L13
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-3*\latWidth,-5*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($(-2*\latWidth,-5*\latWidth)$) {16}; % K13
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-2*\latWidth,-5*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($(-1*\latWidth,-5*\latWidth)$) {}; % J13
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-1*\latWidth,-5*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($(-0*\latWidth,-5*\latWidth)$) {16}; % H13
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-0*\latWidth,-5*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($( 1*\latWidth,-5*\latWidth)$) {}; % G13
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 1*\latWidth,-5*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($( 2*\latWidth,-5*\latWidth)$) {16}; % F13
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 2*\latWidth,-5*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($( 3*\latWidth,-5*\latWidth)$) {}; % E13
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 3*\latWidth,-5*\latWidth)$) {};
|
||||
\node [Assembly, fill=\midenr] at ($( 4*\latWidth,-5*\latWidth)$) {16}; % D13
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 4*\latWidth,-5*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($( 5*\latWidth,-5*\latWidth)$) {15}; % C13
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 5*\latWidth,-5*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($( 6*\latWidth,-5*\latWidth)$) {}; % B13
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 6*\latWidth,-5*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 7*\latWidth,-5*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 8*\latWidth,-5*\latWidth)$) {};
|
||||
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-8*\latWidth,-6*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-7*\latWidth,-6*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-6*\latWidth,-6*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($(-5*\latWidth,-6*\latWidth)$) {}; % N14
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-5*\latWidth,-6*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($(-4*\latWidth,-6*\latWidth)$) {}; % M14
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-4*\latWidth,-6*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($(-3*\latWidth,-6*\latWidth)$) {16}; % L14
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-3*\latWidth,-6*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($(-2*\latWidth,-6*\latWidth)$) {}; % K14
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-2*\latWidth,-6*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($(-1*\latWidth,-6*\latWidth)$) {20}; % J14
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-1*\latWidth,-6*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($(-0*\latWidth,-6*\latWidth)$) {}; % H14
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-0*\latWidth,-6*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($( 1*\latWidth,-6*\latWidth)$) {20}; % G14
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 1*\latWidth,-6*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lowenr] at ($( 2*\latWidth,-6*\latWidth)$) {}; % F14
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 2*\latWidth,-6*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($( 3*\latWidth,-6*\latWidth)$) {16}; % E14
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 3*\latWidth,-6*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($( 4*\latWidth,-6*\latWidth)$) {}; % D14
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 4*\latWidth,-6*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($( 5*\latWidth,-6*\latWidth)$) {}; % C14
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 5*\latWidth,-6*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 6*\latWidth,-6*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 7*\latWidth,-6*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 8*\latWidth,-6*\latWidth)$) {};
|
||||
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-8*\latWidth,-7*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-7*\latWidth,-7*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-6*\latWidth,-7*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-5*\latWidth,-7*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-4*\latWidth,-7*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($(-3*\latWidth,-7*\latWidth)$) {}; % L15
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-3*\latWidth,-7*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($(-2*\latWidth,-7*\latWidth)$) {6}; % K15
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-2*\latWidth,-7*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($(-1*\latWidth,-7*\latWidth)$) {}; % J15
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-1*\latWidth,-7*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($(-0*\latWidth,-7*\latWidth)$) {6}; % H15
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($(-0*\latWidth,-7*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($( 1*\latWidth,-7*\latWidth)$) {}; % G15
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 1*\latWidth,-7*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($( 2*\latWidth,-7*\latWidth)$) {6}; % F15
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 2*\latWidth,-7*\latWidth)$) {};
|
||||
\node [Assembly, fill=\highenr] at ($( 3*\latWidth,-7*\latWidth)$) {}; % E15
|
||||
\node [Assembly, fill=\darkgray, opacity=0.7] at ($( 3*\latWidth,-7*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 4*\latWidth,-7*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 5*\latWidth,-7*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 6*\latWidth,-7*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 7*\latWidth,-7*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 8*\latWidth,-7*\latWidth)$) {};
|
||||
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-8*\latWidth,-8*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-7*\latWidth,-8*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-6*\latWidth,-8*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-5*\latWidth,-8*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-4*\latWidth,-8*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-3*\latWidth,-8*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-2*\latWidth,-8*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-1*\latWidth,-8*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($(-0*\latWidth,-8*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 1*\latWidth,-8*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 2*\latWidth,-8*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 3*\latWidth,-8*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 4*\latWidth,-8*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 5*\latWidth,-8*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 6*\latWidth,-8*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 7*\latWidth,-8*\latWidth)$) {};
|
||||
\node [Assembly, fill=\lightgray, opacity=0.3] at ($( 8*\latWidth,-8*\latWidth)$) {};
|
||||
|
||||
% draw baffle north/south
|
||||
|
||||
\begin{scope}[even odd rule]
|
||||
\clip[rotate=90] \tkzBaffMClip;
|
||||
\path[fill=black] \tkzBaffleC;
|
||||
\end{scope}
|
||||
\begin{scope}[even odd rule]
|
||||
\clip \tkzBaffCClip;
|
||||
\clip \tkzBaffMClip;
|
||||
\path[fill=black, rotate=90] \tkzBaffleM;
|
||||
\end{scope}
|
||||
|
||||
% draw baffle east/west
|
||||
|
||||
\begin{scope}[rotate=90]
|
||||
\begin{scope}[even odd rule]
|
||||
\clip[rotate=90] \tkzBaffMClip;
|
||||
\path[fill=black] \tkzBaffleC;
|
||||
\end{scope}
|
||||
\begin{scope}[even odd rule]
|
||||
\clip \tkzBaffCClip;
|
||||
\clip \tkzBaffMClip;
|
||||
\path[fill=black, rotate=90] \tkzBaffleM;
|
||||
\end{scope}
|
||||
\end{scope}}
|
||||
\end{tikzpicture}
|
||||
|
|
@ -16,3 +16,4 @@ Theory and Methodology
|
|||
tallies
|
||||
eigenvalue
|
||||
parallelization
|
||||
cmfd
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ bugs fixed, and known issues for each successive release.
|
|||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
notes_0.6.1
|
||||
notes_0.6.0
|
||||
notes_0.5.4
|
||||
notes_0.5.3
|
||||
|
|
|
|||
65
docs/source/releasenotes/notes_0.6.1.rst
Normal file
65
docs/source/releasenotes/notes_0.6.1.rst
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
.. _notes_0.6.1:
|
||||
|
||||
==============================
|
||||
Release Notes for OpenMC 0.6.1
|
||||
==============================
|
||||
|
||||
-------------------
|
||||
System Requirements
|
||||
-------------------
|
||||
|
||||
There are no special requirements for running the OpenMC code. As of this
|
||||
release, OpenMC has been tested on a variety of Linux distributions, Mac OS X,
|
||||
and Microsoft Windows 7. Memory requirements will vary depending on the size of
|
||||
the problem at hand (mostly on the number of nuclides in the problem).
|
||||
|
||||
------------
|
||||
New Features
|
||||
------------
|
||||
|
||||
- Coarse mesh finite difference (CMFD) acceleration no longer requires PETSc
|
||||
- Statepoint file numbering is now zero-padded
|
||||
- Python scripts now compatible with Python 2 or 3
|
||||
- Ability to run particle restarts in fixed source calculations
|
||||
- Capability to filter box source by fissionable materials
|
||||
- Nuclide/element names are now case insensitive in input files
|
||||
- Improved treatment of resonance scattering for heavy nuclides
|
||||
|
||||
---------
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- 03e890_: Check for energy-dependent multiplicities in ACE files
|
||||
- 4439de_: Fix distance-to-surface calculation for general plane surface
|
||||
- 5808ed_: Account for differences in URR band probabilities at different energies
|
||||
- 2e60c0_: Allow zero atom/weight percents in materials
|
||||
- 3e0870_: Don't use PWD environment variable when setting path to input files
|
||||
- dc4776_: Handle probability table resampling correctly
|
||||
- 01178b_: Fix metastables nuclides in NNDC cross_sections.xml file
|
||||
- 62ec43_: Don't read tallies.xml when OpenMC is run in plotting mode
|
||||
- 2a95ef_: Prevent segmentation fault on "current" score without mesh filter
|
||||
- 93e482_: Check for negative values in probability tables
|
||||
|
||||
.. _03e890: https://github.com/mit-crpg/openmc/commit/03e890
|
||||
.. _4439de: https://github.com/mit-crpg/openmc/commit/4439de
|
||||
.. _5808ed: https://github.com/mit-crpg/openmc/commit/5808ed
|
||||
.. _2e60c0: https://github.com/mit-crpg/openmc/commit/2e60c0
|
||||
.. _3e0870: https://github.com/mit-crpg/openmc/commit/3e0870
|
||||
.. _dc4776: https://github.com/mit-crpg/openmc/commit/dc4776
|
||||
.. _01178b: https://github.com/mit-crpg/openmc/commit/01178b
|
||||
.. _62ec43: https://github.com/mit-crpg/openmc/commit/62ec43
|
||||
.. _2a95ef: https://github.com/mit-crpg/openmc/commit/2a95ef
|
||||
.. _93e482: https://github.com/mit-crpg/openmc/commit/93e482
|
||||
|
||||
------------
|
||||
Contributors
|
||||
------------
|
||||
|
||||
This release contains new contributions from the following people:
|
||||
|
||||
- `Sterling Harper <smharper@mit.edu>`_
|
||||
- `Bryan Herman <bherman@mit.edu>`_
|
||||
- `Adam Nelson <nelsonag@umich.edu>`_
|
||||
- `Paul Romano <paul.k.romano@gmail.com>`_
|
||||
- `Jon Walsh <walshjon@mit.edu>`_
|
||||
- `Will Boyd <wbinventor@gmail.com>`_
|
||||
|
|
@ -261,7 +261,7 @@ or sub-elements and can be set to either "false" or "true".
|
|||
*Default*: true
|
||||
|
||||
``<resonance_scattering>`` Element
|
||||
----------------------
|
||||
----------------------------------
|
||||
|
||||
The ``resonance_scattering`` element can contain one or more of the following
|
||||
attributes or sub-elements:
|
||||
|
|
@ -269,7 +269,7 @@ attributes or sub-elements:
|
|||
:scatterer:
|
||||
An element with attributes/sub-elements called ``nuclide``, ``method``,
|
||||
``xs_label``, ``xs_label_0K``, ``E_min``, and ``E_max``. The ``nuclide``
|
||||
attribute is the name, as given by the ``name`` attribute within the
|
||||
attribute is the name, as given by the ``name`` attribute within the
|
||||
``nuclide`` sub-element of the ``material`` element in ``materials.xml``,
|
||||
of the nuclide to which a resonance scattering treatment is to be applied.
|
||||
The ``method`` attribute gives the type of resonance scattering treatment
|
||||
|
|
@ -433,6 +433,13 @@ attributes/sub-elements:
|
|||
|
||||
*Default*: 0.988 2.249
|
||||
|
||||
:write_initial:
|
||||
An element specifying whether to write out the initial source bank used at
|
||||
the beginning of the first batch. The output file is named
|
||||
"initial_source.binary(h5)"
|
||||
|
||||
*Default*: false
|
||||
|
||||
``<state_point>`` Element
|
||||
-------------------------
|
||||
|
||||
|
|
@ -1085,10 +1092,10 @@ The ``<tally>`` element accepts the following sub-elements:
|
|||
all of the harmonic moments of order 0 to N. N must be between 0 and 10.
|
||||
|
||||
:total-YN:
|
||||
Spherical harmonic expansion of the incoming particle's direction of
|
||||
motion :math:`\left(\Omega\right)` of the total flux. This score will
|
||||
tally all of the harmonic moments of order 0 to N. N must be between 0
|
||||
and 10.
|
||||
The total reaction rate expanded via spherical harmonics about the
|
||||
direction of motion of the neutron, :math:`\Omega`.
|
||||
This score will tally all of the harmonic moments of order 0 to N. N must
|
||||
be between 0 and 10.
|
||||
|
||||
:current:
|
||||
Partial currents on the boundaries of each cell in a mesh.
|
||||
|
|
@ -1222,7 +1229,7 @@ sub-elements:
|
|||
attribute or sub-element:
|
||||
|
||||
:pixels:
|
||||
Specifies the number of pixes or voxels to be used along each of the basis
|
||||
Specifies the number of pixels or voxels to be used along each of the basis
|
||||
directions for "slice" and "voxel" plots, respectively. Should be two or
|
||||
three integers separated by spaces.
|
||||
|
||||
|
|
@ -1254,7 +1261,7 @@ attributes or sub-elements. These are not used in "voxel" plots:
|
|||
Specifies the RGB color of the regions where no OpenMC cell can be found.
|
||||
Should be three integers separated by spaces.
|
||||
|
||||
*Default*: 0 0 0 (white)
|
||||
*Default*: 0 0 0 (black)
|
||||
|
||||
:col_spec:
|
||||
Any number of this optional tag may be included in each ``<plot>`` element,
|
||||
|
|
@ -1294,6 +1301,37 @@ attributes or sub-elements. These are not used in "voxel" plots:
|
|||
|
||||
*Default*: None
|
||||
|
||||
:meshlines:
|
||||
The ``meshlines`` sub-element allows for plotting the boundaries of
|
||||
a tally mesh on top of a plot. Only one ``meshlines`` element is allowed per
|
||||
``plot`` element, and it must contain as attributes or sub-elements a mesh
|
||||
type and a linewidth. Optionally, a color may be specified for the overlay:
|
||||
|
||||
:meshtype:
|
||||
The type of the mesh to be plotted. Valid options are "tally", "entropy",
|
||||
"ufs", and "cmfd". If plotting "tally" meshes, the id of the mesh to plot
|
||||
must be specified with the ``id`` sub-element.
|
||||
|
||||
:id:
|
||||
A single integer id number for the mesh specified on ``tallies.xml`` that
|
||||
should be plotted. This element is only required for ``meshtype="tally"``.
|
||||
|
||||
:linewidth:
|
||||
A single integer number of pixels of linewidth to specify for the mesh
|
||||
boundaries. Specifying this as 0 indicates that lines will be 1 pixel
|
||||
thick, specifying 1 indicates 3 pixels thick, specifying 2 indicates
|
||||
5 pixels thick, etc.
|
||||
|
||||
:color:
|
||||
Specifies the custom color for the meshlines boundaries. Should be 3
|
||||
integers separated by whitespace. This element is optional.
|
||||
|
||||
*Default*: 0 0 0 (black)
|
||||
|
||||
*Default*: None
|
||||
|
||||
.. _usersguide_cmfd:
|
||||
|
||||
------------------------------
|
||||
CMFD Specification -- cmfd.xml
|
||||
------------------------------
|
||||
|
|
@ -1303,15 +1341,6 @@ Currently, it allows users to accelerate fission source convergence during
|
|||
inactive neutron batches. To run CMFD, the ``<run_cmfd>`` element in
|
||||
``settings.xml`` should be set to "true".
|
||||
|
||||
``<active_flush>`` Element
|
||||
--------------------------
|
||||
|
||||
The ``<active_flush>`` element controls the batch where CMFD tallies should be
|
||||
reset. CMFD tallies should be reset before active batches so they are accumulated
|
||||
without bias.
|
||||
|
||||
*Default*: 0
|
||||
|
||||
``<begin>`` Element
|
||||
-------------------
|
||||
|
||||
|
|
@ -1333,7 +1362,25 @@ The ``<display>`` element sets one additional CMFD output column. Options are:
|
|||
* "source" - prints the RMS [%] between the OpenMC fission source and CMFD
|
||||
fission source.
|
||||
|
||||
*Default*: None
|
||||
*Default*: balance
|
||||
|
||||
``<dhat_reset>`` Element
|
||||
------------------------
|
||||
|
||||
The ``<dhat_reset>`` element controls whether :math:`\widehat{D}` nonlinear
|
||||
CMFD parameters should be reset to zero before solving CMFD eigenproblem.
|
||||
It can be turned on with "true" and off with "false".
|
||||
|
||||
*Default*: false
|
||||
|
||||
``<downscatter>`` Element
|
||||
-------------------------
|
||||
|
||||
The ``<downscatter>`` element controls whether an effective downscatter cross
|
||||
section should be used when using 2-group CMFD. It can be turned on with "true"
|
||||
and off with "false".
|
||||
|
||||
*Default*: false
|
||||
|
||||
``<feedback>`` Element
|
||||
----------------------
|
||||
|
|
@ -1344,24 +1391,16 @@ It can be turned on with "true" and off with "false".
|
|||
|
||||
*Default*: false
|
||||
|
||||
``<inactive>`` Element
|
||||
----------------------
|
||||
``<gauss_seidel_tolerance>`` Element
|
||||
------------------------------------
|
||||
|
||||
The ``<inactive>`` element controls if cmfd tallies should be accumulated
|
||||
during inactive batches. For some applications, CMFD tallies may not be
|
||||
needed until the start of active batches. This option can be turned on
|
||||
with "true" and off with "false"
|
||||
The ``<gauss_seidel_tolerance>`` element specifies two parameters. The first is
|
||||
the absolute inner tolerance for Gauss-Seidel iterations when performing CMFD
|
||||
and the second is the relative inner tolerance for Gauss-Seidel iterations
|
||||
for CMFD calculations. It is only used in the standalone CMFD power iteration
|
||||
solver and not when PETSc is active.
|
||||
|
||||
*Default*: true
|
||||
|
||||
``<inactive_flush>`` Element
|
||||
----------------------------
|
||||
|
||||
The ``<inactive_flush>`` element controls when CMFD tallies are reset during
|
||||
inactive batches. The integer set here is the interval at which this reset
|
||||
occurs. The amout of resets is controlled with the ``<num_flushes>`` element.
|
||||
|
||||
*Defualt*: 9999
|
||||
*Default*: 1.e-10 1.e-5
|
||||
|
||||
``<ksp_monitor>`` Element
|
||||
-------------------------
|
||||
|
|
@ -1370,9 +1409,16 @@ The ``<ksp_monitor>`` element is used to view the convergence of linear GMRES
|
|||
iterations in PETSc. This option can be turned on with "true" and turned off
|
||||
with "false".
|
||||
|
||||
|
||||
*Default*: false
|
||||
|
||||
``<ktol>`` Element
|
||||
--------------------
|
||||
|
||||
The ``<ktol>`` element specifies the tolerance on the eigenvalue when performing
|
||||
CMFD power iteration.
|
||||
|
||||
*Default*: 1.e-8
|
||||
|
||||
``<mesh>`` Element
|
||||
------------------
|
||||
|
||||
|
|
@ -1441,14 +1487,6 @@ not impact the calculation.
|
|||
|
||||
*Default*: 1.0
|
||||
|
||||
``<num_flushes>`` Element
|
||||
-------------------------
|
||||
|
||||
The ``<num_flushes>`` element controls the number of CMFD tally resets that
|
||||
occur during inactive CMFD batches.
|
||||
|
||||
*Default*: 9999
|
||||
|
||||
``<power_monitor>`` Element
|
||||
---------------------------
|
||||
|
||||
|
|
@ -1461,16 +1499,8 @@ This option can be turned on with "true" and turned off with "false".
|
|||
-------------------------
|
||||
|
||||
The ``<run_adjoint>`` element can be turned on with "true" to have an adjoint
|
||||
calculation be performed on the last batch when CMFD is active.
|
||||
|
||||
*Default*: false
|
||||
|
||||
``<snes_monitor>`` Element
|
||||
--------------------------
|
||||
|
||||
The ``<snes_monitor>`` element is used to view the convergence of the nonlinear SNES
|
||||
function in PETSc. This option can be turned on with "true" and turned off with "false".
|
||||
|
||||
calculation be performed on the last batch when CMFD is active. OpenMC should be
|
||||
compiled with PETSc when using this option.
|
||||
|
||||
*Default*: false
|
||||
|
||||
|
|
@ -1483,6 +1513,41 @@ By setting "power", power iteration is used and by setting "jfnk", JFNK is used.
|
|||
|
||||
*Default*: power
|
||||
|
||||
``<shift>`` Element
|
||||
--------------------
|
||||
|
||||
The ``<shfit>`` element specifies an optional Wielandt shift parameter for
|
||||
accelerating power iterations. It can only be used when PETSc is not active.
|
||||
It is by default very large so the impact of the shift is effectively zero.
|
||||
|
||||
*Default*: 1e6
|
||||
|
||||
``<spectral>`` Element
|
||||
----------------------
|
||||
|
||||
The ``<spectral>`` element specifies an optional spectral radius that can be set to
|
||||
accelerate the convergence of Gauss-Seidel iterations during CMFD power iteration
|
||||
solve. Note this is only used in the standalone CMFD solver and does not affect
|
||||
the calculation when PETSc is active.
|
||||
|
||||
*Default*: power
|
||||
|
||||
``<stol>`` Element
|
||||
------------------
|
||||
|
||||
The ``<stol>`` element specifies the tolerance on the fission source when performing
|
||||
CMFD power iteration.
|
||||
|
||||
*Default*: 1.e-8
|
||||
|
||||
``<tally_reset>`` Element
|
||||
-------------------------
|
||||
|
||||
The ``<tally_reset>`` element contains a list of batch numbers in which CMFD tallies
|
||||
should be reset.
|
||||
|
||||
*Default*: None
|
||||
|
||||
``<write_matrices>`` Element
|
||||
----------------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -239,20 +239,22 @@ the root directory of the source code:
|
|||
|
||||
.. code-block:: sh
|
||||
|
||||
cd src
|
||||
mkdir src/build
|
||||
cd src/build
|
||||
cmake ..
|
||||
make
|
||||
sudo make install
|
||||
make install
|
||||
|
||||
This will build an executable named ``openmc`` and install it (by default in
|
||||
/usr/local/bin). If you do not have administrative privileges, you can install
|
||||
OpenMC locally by replacing the last command with:
|
||||
OpenMC locally by specifying an install prefix when running cmake:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
make install -e prefix=$HOME/.local
|
||||
cmake -DCMAKE_INSTALL_PREFIX=$HOME/.local ..
|
||||
|
||||
The ``prefix`` variable can be changed to any path for which you have
|
||||
write-access.
|
||||
The ``CMAKE_INSTALL_PREFIX`` variable can be changed to any path for which you
|
||||
have write-access.
|
||||
|
||||
Compiling on Windows
|
||||
--------------------
|
||||
|
|
@ -326,7 +328,7 @@ Testing Build
|
|||
-------------
|
||||
|
||||
If you have ENDF/B-VII.1 cross sections from NNDC_ you can test your build.
|
||||
Make sure the **CROSS_SECTIONS** environmental variable is set to the
|
||||
Make sure the **CROSS_SECTIONS** environmental variable is set to the
|
||||
*cross_sections.xml* file in the *data/nndc* directory.
|
||||
There are two ways to run tests. The first is to use the Makefile present in
|
||||
the source directory and run the following:
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
<origin>0. 0. 0.</origin>
|
||||
<width>4.0 4.0</width>
|
||||
<pixels>400 400</pixels>
|
||||
<!-- <meshlines mesh="1" linewidth="2" color="0 255 0"/> -->
|
||||
</plot>
|
||||
|
||||
</plots>
|
||||
|
|
|
|||
|
|
@ -261,7 +261,8 @@ install(FILES ../LICENSE DESTINATION "share/doc/${program}/copyright")
|
|||
find_package(PythonInterp)
|
||||
if(PYTHONINTERP_FOUND)
|
||||
install(CODE "execute_process(
|
||||
COMMAND ${PYTHON_EXECUTABLE} setup.py install --user
|
||||
COMMAND ${PYTHON_EXECUTABLE} setup.py install
|
||||
--prefix=${CMAKE_INSTALL_PREFIX}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/utils)")
|
||||
endif()
|
||||
|
||||
|
|
@ -277,7 +278,7 @@ file(GLOB_RECURSE TESTS ${CMAKE_CURRENT_SOURCE_DIR}/../tests/test_*.py)
|
|||
|
||||
# Check to see if PETSC is compiled for CMFD tests
|
||||
if (NOT ${PETSC_ENABLED})
|
||||
file(GLOB_RECURSE CMFD_TESTS ${CMAKE_CURRENT_SOURCE_DIR}/../tests/test_cmfd*.py)
|
||||
file(GLOB_RECURSE CMFD_TESTS ${CMAKE_CURRENT_SOURCE_DIR}/../tests/test_cmfd_jfnk.py)
|
||||
foreach(cmfd_test in ${CMFD_TESTS})
|
||||
list(REMOVE_ITEM TESTS ${cmfd_test})
|
||||
endforeach(cmfd_test)
|
||||
|
|
|
|||
65
src/ace.F90
65
src/ace.F90
|
|
@ -7,21 +7,21 @@ module ace
|
|||
use error, only: fatal_error, warning
|
||||
use fission, only: nu_total
|
||||
use global
|
||||
use list_header, only: ListElemInt, ListInt
|
||||
use list_header, only: ListInt
|
||||
use material_header, only: Material
|
||||
use output, only: write_message
|
||||
use set_header, only: SetChar
|
||||
use string, only: to_str
|
||||
use string, only: to_str, to_lower
|
||||
|
||||
implicit none
|
||||
|
||||
integer :: NXS(16) ! Descriptors for ACE XSS tables
|
||||
integer :: JXS(32) ! Pointers into ACE XSS tables
|
||||
real(8), allocatable :: XSS(:) ! Cross section data
|
||||
integer :: XSS_index ! current index in XSS data
|
||||
integer :: JXS(32) ! Pointers into ACE XSS tables
|
||||
integer :: NXS(16) ! Descriptors for ACE XSS tables
|
||||
real(8), allocatable :: XSS(:) ! Cross section data
|
||||
integer :: XSS_index ! Current index in XSS data
|
||||
|
||||
private :: NXS
|
||||
private :: JXS
|
||||
private :: NXS
|
||||
private :: XSS
|
||||
|
||||
contains
|
||||
|
|
@ -68,8 +68,8 @@ contains
|
|||
name = mat % names(j)
|
||||
|
||||
if (.not. already_read % contains(name)) then
|
||||
i_listing = xs_listing_dict % get_key(name)
|
||||
i_nuclide = nuclide_dict % get_key(name)
|
||||
i_listing = xs_listing_dict % get_key(to_lower(name))
|
||||
i_nuclide = nuclide_dict % get_key(to_lower(name))
|
||||
name = xs_listings(i_listing) % name
|
||||
alias = xs_listings(i_listing) % alias
|
||||
|
||||
|
|
@ -116,8 +116,8 @@ contains
|
|||
name = mat % sab_names(k)
|
||||
|
||||
if (.not. already_read % contains(name)) then
|
||||
i_listing = xs_listing_dict % get_key(name)
|
||||
i_sab = sab_dict % get_key(name)
|
||||
i_listing = xs_listing_dict % get_key(to_lower(name))
|
||||
i_sab = sab_dict % get_key(to_lower(name))
|
||||
|
||||
! Read the ACE table into the appropriate entry on the sab_tables
|
||||
! array
|
||||
|
|
@ -151,9 +151,9 @@ contains
|
|||
|
||||
! Check to make sure S(a,b) table matched a nuclide
|
||||
if (mat % i_sab_nuclides(k) == NONE) then
|
||||
message = "S(a,b) table " // trim(mat % sab_names(k)) // " did not &
|
||||
&match any nuclide on material " // trim(to_str(mat % id))
|
||||
call fatal_error()
|
||||
call fatal_error("S(a,b) table " // trim(mat % sab_names(k)) &
|
||||
&// " did not match any nuclide on material " &
|
||||
&// trim(to_str(mat % id)))
|
||||
end if
|
||||
end do ASSIGN_SAB
|
||||
|
||||
|
|
@ -264,17 +264,14 @@ contains
|
|||
! Check if ACE library exists and is readable
|
||||
inquire(FILE=filename, EXIST=file_exists, READ=readable)
|
||||
if (.not. file_exists) then
|
||||
message = "ACE library '" // trim(filename) // "' does not exist!"
|
||||
call fatal_error()
|
||||
call fatal_error("ACE library '" // trim(filename) // "' does not exist!")
|
||||
elseif (readable(1:3) == 'NO') then
|
||||
message = "ACE library '" // trim(filename) // "' is not readable! &
|
||||
&Change file permissions with chmod command."
|
||||
call fatal_error()
|
||||
call fatal_error("ACE library '" // trim(filename) // "' is not readable!&
|
||||
& Change file permissions with chmod command.")
|
||||
end if
|
||||
|
||||
! display message
|
||||
message = "Loading ACE cross section table: " // listing % name
|
||||
call write_message(6)
|
||||
call write_message("Loading ACE cross section table: " // listing % name, 6)
|
||||
|
||||
if (filetype == ASCII) then
|
||||
! =======================================================================
|
||||
|
|
@ -293,9 +290,8 @@ contains
|
|||
! Check that correct xs was found -- if cross_sections.xml is broken, the
|
||||
! location of the table may be wrong
|
||||
if(adjustl(name) /= adjustl(listing % name)) then
|
||||
message = "XS listing entry " // trim(listing % name) // " did not &
|
||||
&match ACE data, " // trim(name) // " found instead."
|
||||
call fatal_error()
|
||||
call fatal_error("XS listing entry " // trim(listing % name) // " did &
|
||||
¬ match ACE data, " // trim(name) // " found instead.")
|
||||
end if
|
||||
|
||||
! Read more header and NXS and JXS
|
||||
|
|
@ -377,8 +373,8 @@ contains
|
|||
! if any fissionable material is found in a fixed source calculation,
|
||||
! abort the run.
|
||||
if (run_mode == MODE_FIXEDSOURCE .and. nuc % fissionable) then
|
||||
message = "Cannot have fissionable material in a fixed source run."
|
||||
call fatal_error()
|
||||
call fatal_error("Cannot have fissionable material in a fixed source &
|
||||
&run.")
|
||||
end if
|
||||
|
||||
! for fissionable nuclides, precalculate microscopic nu-fission cross
|
||||
|
|
@ -1315,9 +1311,8 @@ contains
|
|||
|
||||
! Abort if no corresponding inelastic reaction was found
|
||||
if (nuc % urr_inelastic == NONE) then
|
||||
message = "Could not find inelastic reaction specified on " &
|
||||
// "unresolved resonance probability table."
|
||||
call fatal_error()
|
||||
call fatal_error("Could not find inelastic reaction specified on &
|
||||
&unresolved resonance probability table.")
|
||||
end if
|
||||
end if
|
||||
|
||||
|
|
@ -1343,9 +1338,8 @@ contains
|
|||
|
||||
! Check for negative values
|
||||
if (any(nuc % urr_data % prob < ZERO)) then
|
||||
message = "Negative value(s) found on probability table for nuclide " &
|
||||
// nuc % name
|
||||
call warning()
|
||||
if (master) call warning("Negative value(s) found on probability table &
|
||||
&for nuclide " // nuc % name)
|
||||
end if
|
||||
|
||||
end subroutine read_unr_res
|
||||
|
|
@ -1563,16 +1557,11 @@ contains
|
|||
|
||||
integer :: i ! index in nuclides array
|
||||
integer :: j ! index in nuclides array
|
||||
type(ListElemInt), pointer :: nuc_list => null() ! pointer to nuclide list
|
||||
|
||||
do i = 1, n_nuclides_total
|
||||
allocate(nuclides(i) % nuc_list)
|
||||
nuc_list => nuclides(i) % nuc_list
|
||||
do j = 1, n_nuclides_total
|
||||
if (nuclides(i) % zaid == nuclides(j) % zaid) then
|
||||
nuc_list % data = j
|
||||
allocate(nuc_list % next)
|
||||
nuc_list => nuc_list % next
|
||||
call nuclides(i) % nuc_list % append(j)
|
||||
end if
|
||||
end do
|
||||
end do
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ module ace_header
|
|||
|
||||
use constants, only: MAX_FILE_LEN
|
||||
use endf_header, only: Tab1
|
||||
use list_header, only: ListElemInt
|
||||
use list_header, only: ListInt
|
||||
|
||||
implicit none
|
||||
|
||||
|
|
@ -97,7 +97,7 @@ module ace_header
|
|||
real(8) :: kT ! temperature in MeV (k*T)
|
||||
|
||||
! Linked list of indices in nuclides array of instances of this same nuclide
|
||||
type(ListElemInt), pointer :: nuc_list => null()
|
||||
type(ListInt) :: nuc_list
|
||||
|
||||
! Energy grid information
|
||||
integer :: n_grid ! # of nuclide grid points
|
||||
|
|
@ -114,7 +114,7 @@ module ace_header
|
|||
|
||||
! Resonance scattering info
|
||||
logical :: resonant = .false. ! resonant scatterer?
|
||||
character(10) :: name_0K ! name of 0K nuclide, e.g. 92235.00c
|
||||
character(10) :: name_0K = '' ! name of 0K nuclide, e.g. 92235.00c
|
||||
character(16) :: scheme ! target velocity sampling scheme
|
||||
integer :: n_grid_0K ! number of 0K energy grid points
|
||||
real(8), allocatable :: energy_0K(:) ! energy grid for 0K xs
|
||||
|
|
@ -416,6 +416,8 @@ module ace_header
|
|||
deallocate(this % reactions)
|
||||
end if
|
||||
|
||||
call this % nuc_list % clear()
|
||||
|
||||
end subroutine nuclide_clear
|
||||
|
||||
end module ace_header
|
||||
|
|
|
|||
|
|
@ -5,13 +5,12 @@ module cmfd_data
|
|||
! parameters for CMFD calculation.
|
||||
!==============================================================================
|
||||
|
||||
use constants
|
||||
|
||||
implicit none
|
||||
private
|
||||
public :: set_up_cmfd, neutron_balance
|
||||
|
||||
logical :: dhat_reset = .false.
|
||||
|
||||
contains
|
||||
|
||||
!==============================================================================
|
||||
|
|
@ -55,7 +54,7 @@ contains
|
|||
OUT_FRONT, IN_TOP, OUT_TOP, CMFD_NOACCEL, ZERO, &
|
||||
ONE, TINY_BIT
|
||||
use error, only: fatal_error
|
||||
use global, only: cmfd, message, n_cmfd_tallies, cmfd_tallies, meshes,&
|
||||
use global, only: cmfd, n_cmfd_tallies, cmfd_tallies, meshes,&
|
||||
matching_bins
|
||||
use mesh, only: mesh_indices_to_bin
|
||||
use mesh_header, only: StructuredMesh
|
||||
|
|
@ -103,6 +102,8 @@ contains
|
|||
cmfd % hxyz(2,:,:,:) = m % width(2) ! set y width
|
||||
cmfd % hxyz(3,:,:,:) = m % width(3) ! set z width
|
||||
|
||||
cmfd % keff_bal = ZERO
|
||||
|
||||
! Begin loop around tallies
|
||||
TAL: do ital = 1, n_cmfd_tallies
|
||||
|
||||
|
|
@ -159,10 +160,9 @@ contains
|
|||
|
||||
! Detect zero flux, abort if located
|
||||
if ((flux - ZERO) < TINY_BIT) then
|
||||
message = 'Detected zero flux without coremap overlay at: (' &
|
||||
// to_str(i) // ',' // to_str(j) // ',' // to_str(k) &
|
||||
// ') in group ' // to_str(h)
|
||||
call fatal_error()
|
||||
call fatal_error('Detected zero flux without coremap overlay &
|
||||
&at: (' // to_str(i) // ',' // to_str(j) // ',' // &
|
||||
&to_str(k) // ') in group ' // to_str(h))
|
||||
end if
|
||||
|
||||
! Get total rr and convert to total xs
|
||||
|
|
@ -211,6 +211,9 @@ contains
|
|||
! Bank source
|
||||
cmfd % openmc_src(g,i,j,k) = cmfd % openmc_src(g,i,j,k) + &
|
||||
t % results(2,score_index) % sum
|
||||
cmfd % keff_bal = cmfd % keff_bal + &
|
||||
t % results(2,score_index) % sum / &
|
||||
dble(t % n_realizations)
|
||||
|
||||
end do INGROUP
|
||||
|
||||
|
|
@ -623,7 +626,9 @@ contains
|
|||
subroutine compute_dhat()
|
||||
|
||||
use constants, only: CMFD_NOACCEL, ZERO
|
||||
use global, only: cmfd, cmfd_coremap
|
||||
use global, only: cmfd, cmfd_coremap, dhat_reset
|
||||
use output, only: write_message
|
||||
use string, only: to_str
|
||||
|
||||
integer :: nx ! maximum number of cells in x direction
|
||||
integer :: ny ! maximum number of cells in y direction
|
||||
|
|
@ -743,7 +748,9 @@ contains
|
|||
cmfd%dhat(l,g,i,j,k) = dhat
|
||||
|
||||
! check for dhat reset
|
||||
if (dhat_reset) cmfd%dhat(l,g,i,j,k) = ZERO
|
||||
if (dhat_reset) then
|
||||
cmfd%dhat(l,g,i,j,k) = ZERO
|
||||
end if
|
||||
|
||||
end do LEAK
|
||||
|
||||
|
|
@ -755,6 +762,11 @@ contains
|
|||
|
||||
end do ZLOOP
|
||||
|
||||
! write that dhats are zero
|
||||
if (dhat_reset) then
|
||||
call write_message('Dhats reset to zero.', 1)
|
||||
end if
|
||||
|
||||
end subroutine compute_dhat
|
||||
|
||||
!===============================================================================
|
||||
|
|
@ -763,8 +775,8 @@ contains
|
|||
|
||||
function get_reflector_albedo(l, g, i, j, k)
|
||||
|
||||
use constants, only: ALBEDO_REJECT
|
||||
use global, only: cmfd, cmfd_hold_weights
|
||||
use constants, only: ONE
|
||||
use global, only: cmfd
|
||||
|
||||
real(8) :: get_reflector_albedo ! reflector albedo
|
||||
integer, intent(in) :: i ! iteration counter for x
|
||||
|
|
@ -786,8 +798,7 @@ contains
|
|||
! Calculate albedo
|
||||
if ((shift_idx == 1 .and. current(2*l ) < 1.0e-10_8) .or. &
|
||||
(shift_idx == -1 .and. current(2*l-1) < 1.0e-10_8)) then
|
||||
albedo = ALBEDO_REJECT
|
||||
cmfd_hold_weights = .true.
|
||||
albedo = ONE
|
||||
else
|
||||
albedo = (current(2*l-1)/current(2*l))**(shift_idx)
|
||||
end if
|
||||
|
|
@ -797,137 +808,6 @@ contains
|
|||
|
||||
end function get_reflector_albedo
|
||||
|
||||
!===============================================================================
|
||||
! FIX_NEUTRON_BALANCE is a method to adjust parameters to have perfect balance
|
||||
!===============================================================================
|
||||
#ifdef DEVELOPMENTAL
|
||||
subroutine fix_neutron_balance()
|
||||
|
||||
use constants, only: ONE, ZERO, CMFD_NOACCEL
|
||||
use global, only: cmfd, keff
|
||||
use, intrinsic :: ISO_FORTRAN_ENV
|
||||
|
||||
integer :: nx ! number of mesh cells in x direction
|
||||
integer :: ny ! number of mesh cells in y direction
|
||||
integer :: nz ! number of mesh cells in z direction
|
||||
integer :: ng ! number of energy groups
|
||||
integer :: i ! iteration counter for x
|
||||
integer :: j ! iteration counter for y
|
||||
integer :: k ! iteration counter for z
|
||||
integer :: l ! iteration counter for surface
|
||||
real(8) :: leak1 ! leakage rate in group 1
|
||||
real(8) :: leak2 ! leakage rate in group 2
|
||||
real(8) :: flux1 ! group 1 volume int flux
|
||||
real(8) :: flux2 ! group 2 volume int flux
|
||||
real(8) :: sigt1 ! group 1 total xs
|
||||
real(8) :: sigt2 ! group 2 total xs
|
||||
real(8) :: sigs11 ! scattering transfer 1 --> 1
|
||||
real(8) :: sigs21 ! scattering transfer 2 --> 1
|
||||
real(8) :: sigs12 ! scattering transfer 1 --> 2
|
||||
real(8) :: sigs22 ! scattering transfer 2 --> 2
|
||||
real(8) :: nsigf11 ! fission transfer 1 --> 1
|
||||
real(8) :: nsigf21 ! fission transfer 2 --> 1
|
||||
real(8) :: nsigf12 ! fission transfer 1 --> 2
|
||||
real(8) :: nsigf22 ! fission transfer 2 --> 2
|
||||
real(8) :: siga1 ! group 1 abs xs
|
||||
real(8) :: siga2 ! group 2 abs xs
|
||||
real(8) :: sigs12_eff ! effective downscatter xs
|
||||
|
||||
! Extract spatial and energy indices from object
|
||||
nx = cmfd % indices(1)
|
||||
ny = cmfd % indices(2)
|
||||
nz = cmfd % indices(3)
|
||||
ng = cmfd % indices(4)
|
||||
|
||||
! Return if not two groups
|
||||
if (ng /= 2) return
|
||||
|
||||
! Begin loop around space and energy groups
|
||||
ZLOOP: do k = 1, nz
|
||||
|
||||
YLOOP: do j = 1, ny
|
||||
|
||||
XLOOP: do i = 1, nx
|
||||
|
||||
! Check for active mesh
|
||||
if (allocated(cmfd%coremap)) then
|
||||
if (cmfd%coremap(i,j,k) == CMFD_NOACCEL) cycle
|
||||
end if
|
||||
|
||||
! Compute leakage in groups 1 and 2
|
||||
leak1 = ZERO
|
||||
leak2 = ZERO
|
||||
LEAK: do l = 1, 3
|
||||
|
||||
leak1 = leak1 + ((cmfd % current(4*l,1,i,j,k) - &
|
||||
cmfd % current(4*l-1,1,i,j,k))) - &
|
||||
((cmfd % current(4*l-2,1,i,j,k) - &
|
||||
cmfd % current(4*l-3,1,i,j,k)))
|
||||
|
||||
leak2 = leak2 + ((cmfd % current(4*l,2,i,j,k) - &
|
||||
cmfd % current(4*l-1,2,i,j,k))) - &
|
||||
((cmfd % current(4*l-2,2,i,j,k) - &
|
||||
cmfd % current(4*l-3,2,i,j,k)))
|
||||
|
||||
|
||||
end do LEAK
|
||||
|
||||
! Extract cross sections and flux from object
|
||||
flux1 = cmfd % flux(1,i,j,k)
|
||||
flux2 = cmfd % flux(2,i,j,k)
|
||||
sigt1 = cmfd % totalxs(1,i,j,k)
|
||||
sigt2 = cmfd % totalxs(2,i,j,k)
|
||||
sigs11 = cmfd % scattxs(1,1,i,j,k)
|
||||
sigs21 = cmfd % scattxs(2,1,i,j,k)
|
||||
sigs12 = cmfd % scattxs(1,2,i,j,k)
|
||||
sigs22 = cmfd % scattxs(2,2,i,j,k)
|
||||
nsigf11 = cmfd % nfissxs(1,1,i,j,k)
|
||||
nsigf21 = cmfd % nfissxs(2,1,i,j,k)
|
||||
nsigf12 = cmfd % nfissxs(1,2,i,j,k)
|
||||
nsigf22 = cmfd % nfissxs(2,2,i,j,k)
|
||||
|
||||
! Check for no fission into group 2
|
||||
if (.not.(nsigf12 < 1e-6_8 .and. nsigf22 < 1e-6_8)) then
|
||||
write(OUTPUT_UNIT,'(A,1PE11.4,1X,1PE11.4)') 'Fission in G=2', &
|
||||
nsigf12,nsigf22
|
||||
end if
|
||||
|
||||
! Compute absorption xs
|
||||
siga1 = sigt1 - sigs11 - sigs12
|
||||
siga2 = sigt2 - sigs22 - sigs21
|
||||
|
||||
! Compute effective downscatter xs
|
||||
sigs12_eff = (ONE/keff*nsigf11*flux1 - leak1 - siga1*flux1 &
|
||||
- ONE/keff*nsigf21/siga2*leak2 ) / ( flux1*(ONE &
|
||||
- ONE/keff*nsigf21/siga2))
|
||||
|
||||
! Redefine flux 2
|
||||
flux2 = (sigs12_eff*flux1 - leak2)/siga2
|
||||
cmfd % flux(2,i,j,k) = flux2
|
||||
|
||||
! Recompute total cross sections (use effective and no upscattering)
|
||||
sigt1 = siga1 + sigs11 + sigs12_eff
|
||||
sigt2 = siga2 + sigs22
|
||||
|
||||
! Record total xs
|
||||
cmfd % totalxs(1,i,j,k) = sigt1
|
||||
cmfd % totalxs(2,i,j,k) = sigt2
|
||||
|
||||
! Record effective downscatter xs
|
||||
cmfd % scattxs(1,2,i,j,k) = sigs12_eff
|
||||
|
||||
! Zero out upscatter cross section
|
||||
cmfd % scattxs(2,1,i,j,k) = ZERO
|
||||
|
||||
end do XLOOP
|
||||
|
||||
end do YLOOP
|
||||
|
||||
end do ZLOOP
|
||||
|
||||
end subroutine fix_neutron_balance
|
||||
#endif
|
||||
|
||||
!===============================================================================
|
||||
! COMPUTE_EFFECTIVE_DOWNSCATTER changes downscatter rate for zero upscatter
|
||||
!===============================================================================
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ contains
|
|||
use cmfd_data, only: set_up_cmfd
|
||||
use cmfd_power_solver, only: cmfd_power_execute
|
||||
use cmfd_jfnk_solver, only: cmfd_jfnk_execute
|
||||
use cmfd_solver, only: cmfd_solver_execute
|
||||
use error, only: warning, fatal_error
|
||||
|
||||
! CMFD single processor on master
|
||||
|
|
@ -37,14 +38,17 @@ contains
|
|||
call process_cmfd_options()
|
||||
|
||||
! Call solver
|
||||
#ifdef PETSC
|
||||
if (trim(cmfd_solver_type) == 'power') then
|
||||
call cmfd_power_execute()
|
||||
elseif (trim(cmfd_solver_type) == 'jfnk') then
|
||||
call cmfd_jfnk_execute()
|
||||
else
|
||||
message = 'solver type became invalid after input processing'
|
||||
call fatal_error()
|
||||
call fatal_error('solver type became invalid after input processing')
|
||||
end if
|
||||
#else
|
||||
call cmfd_solver_execute()
|
||||
#endif
|
||||
|
||||
! Save k-effective
|
||||
cmfd % k_cmfd(current_batch) = cmfd % keff
|
||||
|
|
@ -64,7 +68,7 @@ contains
|
|||
call calc_fission_source()
|
||||
|
||||
! calculate weight factors
|
||||
if (cmfd_feedback) call cmfd_reweight(.true.)
|
||||
call cmfd_reweight(.true.)
|
||||
|
||||
! stop cmfd timer
|
||||
if (master) call time_cmfd % stop()
|
||||
|
|
@ -77,36 +81,23 @@ contains
|
|||
|
||||
subroutine cmfd_init_batch()
|
||||
|
||||
use global, only: cmfd_begin, cmfd_on, cmfd_tally_on, &
|
||||
cmfd_inact_flush, cmfd_act_flush, cmfd_run, &
|
||||
current_batch, cmfd_hold_weights
|
||||
use global, only: cmfd_begin, cmfd_on, &
|
||||
cmfd_reset, cmfd_run, &
|
||||
current_batch
|
||||
|
||||
! Check to activate CMFD diffusion and possible feedback
|
||||
! this guarantees that when cmfd begins at least one batch of tallies are
|
||||
! accumulated
|
||||
if (cmfd_run .and. cmfd_begin == current_batch) then
|
||||
cmfd_on = .true.
|
||||
cmfd_tally_on = .true.
|
||||
end if
|
||||
|
||||
! If this is a restart run and we are just replaying batches leave
|
||||
if (restart_run .and. current_batch <= restart_batch) return
|
||||
|
||||
! Check to flush cmfd tallies for active batches, no more inactive flush
|
||||
if (cmfd_run .and. cmfd_act_flush == current_batch) then
|
||||
! Check to reset tallies
|
||||
if (cmfd_run .and. cmfd_reset % contains(current_batch)) then
|
||||
call cmfd_tally_reset()
|
||||
cmfd_tally_on = .true.
|
||||
cmfd_inact_flush(2) = -1
|
||||
end if
|
||||
|
||||
! Check to flush cmfd tallies during inactive batches (>= on number of
|
||||
! flushes important as the code will flush on the first batch which we
|
||||
! dont want to count)
|
||||
if (cmfd_run .and. mod(current_batch,cmfd_inact_flush(1)) &
|
||||
== 0 .and. cmfd_inact_flush(2) > 0 .and. cmfd_begin < current_batch) then
|
||||
cmfd_hold_weights = .true.
|
||||
call cmfd_tally_reset()
|
||||
cmfd_inact_flush(2) = cmfd_inact_flush(2) - 1
|
||||
end if
|
||||
|
||||
end subroutine cmfd_init_batch
|
||||
|
|
@ -139,6 +130,7 @@ contains
|
|||
|
||||
use constants, only: CMFD_NOACCEL, ZERO, TWO
|
||||
use global, only: cmfd, cmfd_coremap, master, entropy_on, current_batch
|
||||
use string, only: to_str
|
||||
|
||||
#ifdef MPI
|
||||
use global, only: mpi_err
|
||||
|
|
@ -262,11 +254,12 @@ contains
|
|||
|
||||
use constants, only: ZERO, ONE
|
||||
use error, only: warning, fatal_error
|
||||
use global, only: meshes, source_bank, work, n_user_meshes, message, &
|
||||
cmfd, master
|
||||
use global, only: meshes, source_bank, work, n_user_meshes, cmfd, &
|
||||
master
|
||||
use mesh_header, only: StructuredMesh
|
||||
use mesh, only: count_bank_sites, get_mesh_indices
|
||||
use search, only: binary_search
|
||||
use string, only: to_str
|
||||
|
||||
#ifdef MPI
|
||||
use global, only: mpi_err
|
||||
|
|
@ -287,7 +280,6 @@ contains
|
|||
logical :: in_mesh ! source site is inside mesh
|
||||
|
||||
type(StructuredMesh), pointer :: m ! point to mesh
|
||||
real(8), allocatable :: egrid(:) ! energy grid
|
||||
|
||||
! Associate pointer
|
||||
m => meshes(n_user_meshes + 1)
|
||||
|
|
@ -308,24 +300,20 @@ contains
|
|||
cmfd % weightfactors = ONE
|
||||
end if
|
||||
|
||||
! Allocate energy grid and reverse cmfd energy grid
|
||||
if (.not. allocated(egrid)) allocate(egrid(ng + 1))
|
||||
egrid = (/(cmfd % egrid(ng - i + 2), i = 1, ng + 1)/)
|
||||
|
||||
! Compute new weight factors
|
||||
if (new_weights) then
|
||||
|
||||
! Zero out weights
|
||||
cmfd%weightfactors = ZERO
|
||||
! Set weight factors to a default 1.0
|
||||
cmfd%weightfactors = ONE
|
||||
|
||||
! Count bank sites in mesh
|
||||
call count_bank_sites(m, source_bank, cmfd%sourcecounts, egrid, &
|
||||
! Count bank sites in mesh and reverse due to egrid structure
|
||||
call count_bank_sites(m, source_bank, cmfd%sourcecounts, cmfd % egrid, &
|
||||
sites_outside=outside, size_bank=work)
|
||||
cmfd % sourcecounts = cmfd%sourcecounts(ng:1:-1,:,:,:)
|
||||
|
||||
! Check for sites outside of the mesh
|
||||
if (master .and. outside) then
|
||||
message = "Source sites outside of the CMFD mesh!"
|
||||
call fatal_error()
|
||||
call fatal_error("Source sites outside of the CMFD mesh!")
|
||||
end if
|
||||
|
||||
! Have master compute weight factors (watch for 0s)
|
||||
|
|
@ -336,12 +324,14 @@ contains
|
|||
end where
|
||||
end if
|
||||
|
||||
if (.not. cmfd_feedback) return
|
||||
|
||||
! Broadcast weight factors to all procs
|
||||
#ifdef MPI
|
||||
call MPI_BCAST(cmfd % weightfactors, ng*nx*ny*nz, MPI_REAL8, 0, &
|
||||
MPI_COMM_WORLD, mpi_err)
|
||||
#endif
|
||||
end if
|
||||
end if
|
||||
|
||||
! begin loop over source bank
|
||||
do i = 1, int(work,4)
|
||||
|
|
@ -353,12 +343,10 @@ contains
|
|||
n_groups = size(cmfd % egrid) - 1
|
||||
if (source_bank(i) % E < cmfd % egrid(1)) then
|
||||
e_bin = 1
|
||||
message = 'Source pt below energy grid'
|
||||
call warning()
|
||||
if (master) call warning('Source pt below energy grid')
|
||||
elseif (source_bank(i) % E > cmfd % egrid(n_groups + 1)) then
|
||||
e_bin = n_groups
|
||||
message = 'Source pt above energy grid'
|
||||
call warning()
|
||||
if (master) call warning('Source pt above energy grid')
|
||||
else
|
||||
e_bin = binary_search(cmfd % egrid, n_groups + 1, source_bank(i) % E)
|
||||
end if
|
||||
|
|
@ -368,8 +356,7 @@ contains
|
|||
|
||||
! Check for outside of mesh
|
||||
if (.not. in_mesh) then
|
||||
message = 'Source site found outside of CMFD mesh'
|
||||
call fatal_error()
|
||||
call fatal_error('Source site found outside of CMFD mesh')
|
||||
end if
|
||||
|
||||
! Reweight particle
|
||||
|
|
@ -378,9 +365,6 @@ contains
|
|||
|
||||
end do
|
||||
|
||||
! Deallocate all
|
||||
if (allocated(egrid)) deallocate(egrid)
|
||||
|
||||
end subroutine cmfd_reweight
|
||||
|
||||
!===============================================================================
|
||||
|
|
@ -421,15 +405,14 @@ contains
|
|||
|
||||
subroutine cmfd_tally_reset()
|
||||
|
||||
use global, only: n_cmfd_tallies, cmfd_tallies, message
|
||||
use global, only: n_cmfd_tallies, cmfd_tallies
|
||||
use output, only: write_message
|
||||
use tally, only: reset_result
|
||||
|
||||
integer :: i ! loop counter
|
||||
|
||||
! Print message
|
||||
message = "CMFD tallies reset"
|
||||
call write_message(7)
|
||||
call write_message("CMFD tallies reset", 7)
|
||||
|
||||
! Begin loop around CMFD tallies
|
||||
do i = 1, n_cmfd_tallies
|
||||
|
|
|
|||
|
|
@ -83,6 +83,9 @@ module cmfd_header
|
|||
! List of CMFD k
|
||||
real(8), allocatable :: k_cmfd(:)
|
||||
|
||||
! Balance keff
|
||||
real(8) :: keff_bal
|
||||
|
||||
end type cmfd_type
|
||||
|
||||
contains
|
||||
|
|
|
|||
|
|
@ -62,16 +62,20 @@ contains
|
|||
use error, only: fatal_error, warning
|
||||
use global
|
||||
use output, only: write_message
|
||||
use string, only: lower_case
|
||||
use string, only: to_lower
|
||||
use xml_interface
|
||||
use, intrinsic :: ISO_FORTRAN_ENV
|
||||
|
||||
integer :: i
|
||||
integer :: ng
|
||||
integer :: n_params
|
||||
integer, allocatable :: iarray(:)
|
||||
integer, allocatable :: int_array(:)
|
||||
logical :: file_exists ! does cmfd.xml exist?
|
||||
logical :: found
|
||||
character(MAX_LINE_LEN) :: filename
|
||||
character(MAX_LINE_LEN) :: temp_str
|
||||
real(8) :: gs_tol(2)
|
||||
type(Node), pointer :: doc => null()
|
||||
type(Node), pointer :: node_mesh => null()
|
||||
|
||||
|
|
@ -81,15 +85,14 @@ contains
|
|||
if (.not. file_exists) then
|
||||
! CMFD is optional unless it is in on from settings
|
||||
if (cmfd_on) then
|
||||
message = "No CMFD XML file, '" // trim(filename) // "' does not exist!"
|
||||
call fatal_error()
|
||||
call fatal_error("No CMFD XML file, '" // trim(filename) // "' does not&
|
||||
& exist!")
|
||||
end if
|
||||
return
|
||||
else
|
||||
|
||||
! Tell user
|
||||
message = "Reading CMFD XML file..."
|
||||
call write_message(5)
|
||||
call write_message("Reading CMFD XML file...", 5)
|
||||
|
||||
end if
|
||||
|
||||
|
|
@ -101,8 +104,7 @@ contains
|
|||
|
||||
! Check if mesh is there
|
||||
if (.not.found) then
|
||||
message = "No CMFD mesh specified in CMFD XML file."
|
||||
call fatal_error()
|
||||
call fatal_error("No CMFD mesh specified in CMFD XML file.")
|
||||
end if
|
||||
|
||||
! Set spatial dimensions in cmfd object
|
||||
|
|
@ -133,8 +135,7 @@ contains
|
|||
cmfd % indices(3)))
|
||||
if (get_arraysize_integer(node_mesh, "map") /= &
|
||||
product(cmfd % indices(1:3))) then
|
||||
message = 'FATAL==>CMFD coremap not to correct dimensions'
|
||||
call fatal_error()
|
||||
call fatal_error('CMFD coremap not to correct dimensions')
|
||||
end if
|
||||
allocate(iarray(get_arraysize_integer(node_mesh, "map")))
|
||||
call get_node_array(node_mesh, "map", iarray)
|
||||
|
|
@ -151,91 +152,119 @@ contains
|
|||
! Set feedback logical
|
||||
if (check_for_node(doc, "feedback")) then
|
||||
call get_node_value(doc, "feedback", temp_str)
|
||||
call lower_case(temp_str)
|
||||
temp_str = to_lower(temp_str)
|
||||
if (trim(temp_str) == 'true' .or. trim(temp_str) == '1') &
|
||||
cmfd_feedback = .true.
|
||||
cmfd_feedback = .true.
|
||||
end if
|
||||
|
||||
! Set downscatter logical
|
||||
if (check_for_node(doc, "downscatter")) then
|
||||
call get_node_value(doc, "downscatter", temp_str)
|
||||
call lower_case(temp_str)
|
||||
temp_str = to_lower(temp_str)
|
||||
if (trim(temp_str) == 'true' .or. trim(temp_str) == '1') &
|
||||
cmfd_downscatter = .true.
|
||||
cmfd_downscatter = .true.
|
||||
end if
|
||||
|
||||
! Reset dhat parameters
|
||||
if (check_for_node(doc, "dhat_reset")) then
|
||||
call get_node_value(doc, "dhat_reset", temp_str)
|
||||
temp_str = to_lower(temp_str)
|
||||
if (trim(temp_str) == 'true' .or. trim(temp_str) == '1') &
|
||||
dhat_reset = .true.
|
||||
end if
|
||||
|
||||
! Set the solver type
|
||||
if (check_for_node(doc, "solver")) &
|
||||
call get_node_value(doc, "solver", cmfd_solver_type)
|
||||
call get_node_value(doc, "solver", cmfd_solver_type)
|
||||
|
||||
! Set monitoring
|
||||
if (check_for_node(doc, "snes_monitor")) then
|
||||
call get_node_value(doc, "snes_monitor", temp_str)
|
||||
call lower_case(temp_str)
|
||||
temp_str = to_lower(temp_str)
|
||||
if (trim(temp_str) == 'true' .or. trim(temp_str) == '1') &
|
||||
cmfd_snes_monitor = .true.
|
||||
cmfd_snes_monitor = .true.
|
||||
end if
|
||||
if (check_for_node(doc, "ksp_monitor")) then
|
||||
call get_node_value(doc, "ksp_monitor", temp_str)
|
||||
call lower_case(temp_str)
|
||||
temp_str = to_lower(temp_str)
|
||||
if (trim(temp_str) == 'true' .or. trim(temp_str) == '1') &
|
||||
cmfd_ksp_monitor = .true.
|
||||
cmfd_ksp_monitor = .true.
|
||||
end if
|
||||
if (check_for_node(doc, "power_monitor")) then
|
||||
call get_node_value(doc, "power_monitor", temp_str)
|
||||
call lower_case(temp_str)
|
||||
temp_str = to_lower(temp_str)
|
||||
if (trim(temp_str) == 'true' .or. trim(temp_str) == '1') &
|
||||
cmfd_power_monitor = .true.
|
||||
cmfd_power_monitor = .true.
|
||||
end if
|
||||
|
||||
! Output logicals
|
||||
if (check_for_node(doc, "write_matrices")) then
|
||||
call get_node_value(doc, "write_matices", temp_str)
|
||||
call lower_case(temp_str)
|
||||
call get_node_value(doc, "write_matrices", temp_str)
|
||||
temp_str = to_lower(temp_str)
|
||||
if (trim(temp_str) == 'true' .or. trim(temp_str) == '1') &
|
||||
cmfd_write_matrices = .true.
|
||||
cmfd_write_matrices = .true.
|
||||
end if
|
||||
|
||||
! Run an adjoint calc
|
||||
if (check_for_node(doc, "run_adjoint")) then
|
||||
call get_node_value(doc, "run_adjoint", temp_str)
|
||||
call lower_case(temp_str)
|
||||
temp_str = to_lower(temp_str)
|
||||
if (trim(temp_str) == 'true' .or. trim(temp_str) == '1') &
|
||||
#ifndef PETSC
|
||||
call fatal_error('Must use PETSc when running adjoint option.')
|
||||
#endif
|
||||
cmfd_run_adjoint = .true.
|
||||
end if
|
||||
|
||||
! Batch to begin cmfd
|
||||
if (check_for_node(doc, "begin")) &
|
||||
call get_node_value(doc, "begin", cmfd_begin)
|
||||
call get_node_value(doc, "begin", cmfd_begin)
|
||||
|
||||
! Tally during inactive batches
|
||||
if (check_for_node(doc, "inactive")) then
|
||||
call get_node_value(doc, "inactive", temp_str)
|
||||
call lower_case(temp_str)
|
||||
if (trim(temp_str) == 'false' .or. trim(temp_str) == '0') &
|
||||
cmfd_tally_on = .false.
|
||||
! Check for cmfd tally resets
|
||||
if (check_for_node(doc, "tally_reset")) then
|
||||
n_cmfd_resets = get_arraysize_integer(doc, "tally_reset")
|
||||
else
|
||||
n_cmfd_resets = 0
|
||||
end if
|
||||
if (n_cmfd_resets > 0) then
|
||||
allocate(int_array(n_cmfd_resets))
|
||||
call get_node_array(doc, "tally_reset", int_array)
|
||||
do i = 1, n_cmfd_resets
|
||||
call cmfd_reset % add(int_array(i))
|
||||
end do
|
||||
deallocate(int_array)
|
||||
end if
|
||||
|
||||
! Inactive batch flush window
|
||||
if (check_for_node(doc, "inactive_flush")) &
|
||||
call get_node_value(doc, "inactive_flush", cmfd_inact_flush(1))
|
||||
if (check_for_node(doc, "num_flushes")) &
|
||||
call get_node_value(doc, "num_flushes", cmfd_inact_flush(2))
|
||||
|
||||
! Last flush before active batches
|
||||
if (check_for_node(doc, "active_flush")) &
|
||||
call get_node_value(doc, "active_flush", cmfd_act_flush)
|
||||
|
||||
! Get display
|
||||
if (check_for_node(doc, "display")) &
|
||||
call get_node_value(doc, "display", cmfd_display)
|
||||
call get_node_value(doc, "display", cmfd_display)
|
||||
if (trim(cmfd_display) == 'dominance' .and. &
|
||||
trim(cmfd_solver_type) /= 'power') then
|
||||
message = 'Dominance Ratio only aviable with power iteration solver'
|
||||
call warning()
|
||||
trim(cmfd_solver_type) /= 'power') then
|
||||
if (master) call warning('Dominance Ratio only aviable with power &
|
||||
&iteration solver')
|
||||
cmfd_display = ''
|
||||
end if
|
||||
|
||||
! Read in spectral radius estimate and tolerances
|
||||
if (check_for_node(doc, "spectral")) &
|
||||
call get_node_value(doc, "spectral", cmfd_spectral)
|
||||
if (check_for_node(doc, "shift")) &
|
||||
call get_node_value(doc, "shift", cmfd_shift)
|
||||
if (check_for_node(doc, "ktol")) &
|
||||
call get_node_value(doc, "ktol", cmfd_ktol)
|
||||
if (check_for_node(doc, "stol")) &
|
||||
call get_node_value(doc, "stol", cmfd_stol)
|
||||
if (check_for_node(doc, "gauss_seidel_tolerance")) then
|
||||
n_params = get_arraysize_double(doc, "gauss_seidel_tolerance")
|
||||
if (n_params /= 2) then
|
||||
call fatal_error('Gauss Seidel tolerance is not 2 parameters &
|
||||
&(absolute, relative).')
|
||||
end if
|
||||
call get_node_array(doc, "gauss_seidel_tolerance", gs_tol)
|
||||
cmfd_atoli = gs_tol(1)
|
||||
cmfd_rtoli = gs_tol(2)
|
||||
end if
|
||||
|
||||
! Create tally objects
|
||||
call create_cmfd_tally(doc)
|
||||
|
||||
|
|
@ -299,8 +328,7 @@ contains
|
|||
! Determine number of dimensions for mesh
|
||||
n = get_arraysize_integer(node_mesh, "dimension")
|
||||
if (n /= 2 .and. n /= 3) then
|
||||
message = "Mesh must be two or three dimensions."
|
||||
call fatal_error()
|
||||
call fatal_error("Mesh must be two or three dimensions.")
|
||||
end if
|
||||
m % n_dimension = n
|
||||
|
||||
|
|
@ -313,9 +341,8 @@ contains
|
|||
! Check that dimensions are all greater than zero
|
||||
call get_node_array(node_mesh, "dimension", iarray3(1:n))
|
||||
if (any(iarray3(1:n) <= 0)) then
|
||||
message = "All entries on the <dimension> element for a tally mesh &
|
||||
&must be positive."
|
||||
call fatal_error()
|
||||
call fatal_error("All entries on the <dimension> element for a tally mesh&
|
||||
& must be positive.")
|
||||
end if
|
||||
|
||||
! Read dimensions in each direction
|
||||
|
|
@ -323,42 +350,37 @@ contains
|
|||
|
||||
! Read mesh lower-left corner location
|
||||
if (m % n_dimension /= get_arraysize_double(node_mesh, "lower_left")) then
|
||||
message = "Number of entries on <lower_left> must be the same as &
|
||||
&the number of entries on <dimension>."
|
||||
call fatal_error()
|
||||
call fatal_error("Number of entries on <lower_left> must be the same as &
|
||||
&the number of entries on <dimension>.")
|
||||
end if
|
||||
call get_node_array(node_mesh, "lower_left", m % lower_left)
|
||||
|
||||
! Make sure both upper-right or width were specified
|
||||
if (check_for_node(node_mesh, "upper_right") .and. &
|
||||
check_for_node(node_mesh, "width")) then
|
||||
message = "Cannot specify both <upper_right> and <width> on a &
|
||||
&tally mesh."
|
||||
call fatal_error()
|
||||
call fatal_error("Cannot specify both <upper_right> and <width> on a &
|
||||
&tally mesh.")
|
||||
end if
|
||||
|
||||
! Make sure either upper-right or width was specified
|
||||
if (.not.check_for_node(node_mesh, "upper_right") .and. &
|
||||
.not.check_for_node(node_mesh, "width")) then
|
||||
message = "Must specify either <upper_right> and <width> on a &
|
||||
&tally mesh."
|
||||
call fatal_error()
|
||||
call fatal_error("Must specify either <upper_right> and <width> on a &
|
||||
&tally mesh.")
|
||||
end if
|
||||
|
||||
if (check_for_node(node_mesh, "width")) then
|
||||
! Check to ensure width has same dimensions
|
||||
if (get_arraysize_double(node_mesh, "width") /= &
|
||||
get_arraysize_double(node_mesh, "lower_left")) then
|
||||
message = "Number of entries on <width> must be the same as the &
|
||||
&number of entries on <lower_left>."
|
||||
call fatal_error()
|
||||
call fatal_error("Number of entries on <width> must be the same as the &
|
||||
&number of entries on <lower_left>.")
|
||||
end if
|
||||
|
||||
! Check for negative widths
|
||||
call get_node_array(node_mesh, "width", rarray3(1:n))
|
||||
if (any(rarray3(1:n) < ZERO)) then
|
||||
message = "Cannot have a negative <width> on a tally mesh."
|
||||
call fatal_error()
|
||||
call fatal_error("Cannot have a negative <width> on a tally mesh.")
|
||||
end if
|
||||
|
||||
! Set width and upper right coordinate
|
||||
|
|
@ -369,17 +391,15 @@ contains
|
|||
! Check to ensure width has same dimensions
|
||||
if (get_arraysize_double(node_mesh, "upper_right") /= &
|
||||
get_arraysize_double(node_mesh, "lower_left")) then
|
||||
message = "Number of entries on <upper_right> must be the same as &
|
||||
&the number of entries on <lower_left>."
|
||||
call fatal_error()
|
||||
call fatal_error("Number of entries on <upper_right> must be the same &
|
||||
&as the number of entries on <lower_left>.")
|
||||
end if
|
||||
|
||||
! Check that upper-right is above lower-left
|
||||
call get_node_array(node_mesh, "upper_right", rarray3(1:n))
|
||||
if (any(rarray3(1:n) < m % lower_left)) then
|
||||
message = "The <upper_right> coordinates must be greater than the &
|
||||
&<lower_left> coordinates on a tally mesh."
|
||||
call fatal_error()
|
||||
call fatal_error("The <upper_right> coordinates must be greater than &
|
||||
&the <lower_left> coordinates on a tally mesh.")
|
||||
end if
|
||||
|
||||
! Set upper right coordinate and width
|
||||
|
|
@ -405,9 +425,9 @@ contains
|
|||
! Set reset property
|
||||
if (check_for_node(doc, "reset")) then
|
||||
call get_node_value(doc, "reset", temp_str)
|
||||
call lower_case(temp_str)
|
||||
temp_str = to_lower(temp_str)
|
||||
if (trim(temp_str) == 'true' .or. trim(temp_str) == '1') &
|
||||
t % reset = .true.
|
||||
t % reset = .true.
|
||||
end if
|
||||
|
||||
! Set up mesh filter
|
||||
|
|
|
|||
|
|
@ -242,7 +242,7 @@ contains
|
|||
|
||||
subroutine convergence(iter)
|
||||
|
||||
use constants, only: ONE, TINY_BIT
|
||||
use constants, only: ONE, ZERO
|
||||
use global, only: cmfd_power_monitor, master
|
||||
use, intrinsic :: ISO_FORTRAN_ENV
|
||||
|
||||
|
|
@ -255,7 +255,7 @@ contains
|
|||
kerr = abs(k_o - k_n)/k_n
|
||||
|
||||
! Calculate max error in source
|
||||
where (s_n % val > TINY_BIT)
|
||||
where (s_n % val > ZERO)
|
||||
serr_v % val = ((s_n % val - s_o % val)/s_n % val)**2
|
||||
end where
|
||||
serr = sqrt(ONE/dble(s_n % n) * sum(serr_v % val))
|
||||
|
|
|
|||
813
src/cmfd_solver.F90
Normal file
813
src/cmfd_solver.F90
Normal file
|
|
@ -0,0 +1,813 @@
|
|||
module cmfd_solver
|
||||
|
||||
! This module contains routines to execute the power iteration solver
|
||||
|
||||
use constants, only: MAX_LINE_LEN
|
||||
use cmfd_loss_operator, only: init_loss_matrix, build_loss_matrix
|
||||
use cmfd_prod_operator, only: init_prod_matrix, build_prod_matrix
|
||||
use matrix_header, only: Matrix
|
||||
use vector_header, only: Vector
|
||||
|
||||
implicit none
|
||||
private
|
||||
public :: cmfd_solver_execute
|
||||
|
||||
real(8) :: k_n ! New k-eigenvalue
|
||||
real(8) :: k_o ! Old k-eigenvalue
|
||||
real(8) :: k_s ! Shift of eigenvalue
|
||||
real(8) :: k_ln ! New shifted eigenvalue
|
||||
real(8) :: k_lo ! Old shifted eigenvalue
|
||||
real(8) :: norm_n ! Current norm of source vector
|
||||
real(8) :: norm_o ! Old norm of source vector
|
||||
real(8) :: kerr ! Error in keff
|
||||
real(8) :: serr ! Error in source
|
||||
real(8) :: ktol ! Tolerance on keff
|
||||
real(8) :: stol ! Tolerance on source
|
||||
logical :: adjoint_calc ! Run an adjoint calculation
|
||||
type(Matrix) :: loss ! Cmfd loss matrix
|
||||
type(Matrix) :: prod ! Cmfd prod matrix
|
||||
type(Vector) :: phi_n ! New flux vector
|
||||
type(Vector) :: phi_o ! Old flux vector
|
||||
type(Vector) :: s_n ! New source vector
|
||||
type(Vector) :: s_o ! Old flux vector
|
||||
type(Vector) :: serr_v ! Error in source
|
||||
|
||||
! CMFD linear solver interface
|
||||
procedure(linsolve), pointer :: cmfd_linsolver => null()
|
||||
abstract interface
|
||||
subroutine linsolve(A, b, x, tol, i)
|
||||
import :: Matrix
|
||||
import :: Vector
|
||||
type(Matrix), intent(inout) :: A
|
||||
type(Vector), intent(inout) :: b
|
||||
type(Vector), intent(inout) :: x
|
||||
real(8), intent(in) :: tol
|
||||
integer, intent(out) :: i
|
||||
end subroutine linsolve
|
||||
end interface
|
||||
|
||||
contains
|
||||
|
||||
!===============================================================================
|
||||
! CMFD_SOLVER_EXECUTE sets up and runs power iteration solver for CMFD
|
||||
!===============================================================================
|
||||
|
||||
subroutine cmfd_solver_execute(adjoint)
|
||||
|
||||
use global, only: cmfd_adjoint_type, time_cmfdbuild, time_cmfdsolve
|
||||
|
||||
logical, optional, intent(in) :: adjoint ! adjoint calc
|
||||
|
||||
logical :: physical_adjoint = .false.
|
||||
|
||||
! Check for adjoint execution
|
||||
adjoint_calc = .false.
|
||||
if (present(adjoint)) adjoint_calc = adjoint
|
||||
|
||||
! Check for physical adjoint
|
||||
if (adjoint_calc .and. trim(cmfd_adjoint_type) == 'physical') &
|
||||
physical_adjoint = .true.
|
||||
|
||||
! Start timer for build
|
||||
call time_cmfdbuild % start()
|
||||
|
||||
! Initialize matrices and vectors
|
||||
call init_data(physical_adjoint)
|
||||
|
||||
! Check for mathematical adjoint calculation
|
||||
if (adjoint_calc .and. trim(cmfd_adjoint_type) == 'math') &
|
||||
call compute_adjoint()
|
||||
|
||||
! Stop timer for build
|
||||
call time_cmfdbuild % stop()
|
||||
|
||||
! Begin power iteration
|
||||
call time_cmfdsolve % start()
|
||||
call execute_power_iter()
|
||||
call time_cmfdsolve % stop()
|
||||
|
||||
! Extract results
|
||||
call extract_results()
|
||||
|
||||
! Deallocate data
|
||||
call finalize()
|
||||
|
||||
end subroutine cmfd_solver_execute
|
||||
|
||||
!===============================================================================
|
||||
! INIT_DATA allocates matrices and vectors for CMFD solution
|
||||
!===============================================================================
|
||||
|
||||
subroutine init_data(adjoint)
|
||||
|
||||
use constants, only: ONE, ZERO
|
||||
use global, only: cmfd, cmfd_shift, keff, cmfd_ktol, cmfd_stol, &
|
||||
cmfd_write_matrices
|
||||
|
||||
logical, intent(in) :: adjoint
|
||||
|
||||
integer :: n ! problem size
|
||||
real(8) :: guess ! initial guess
|
||||
real(8) :: dw ! eigenvalue shift
|
||||
|
||||
! Set up matrices
|
||||
call init_loss_matrix(loss)
|
||||
call init_prod_matrix(prod)
|
||||
|
||||
! Get problem size
|
||||
n = loss % n
|
||||
|
||||
! Set up flux vectors
|
||||
call phi_n % create(n)
|
||||
call phi_o % create(n)
|
||||
|
||||
! Set up source vectors
|
||||
call s_n % create(n)
|
||||
call s_o % create(n)
|
||||
call serr_v % create(n)
|
||||
|
||||
! Set initial guess
|
||||
guess = ONE
|
||||
phi_n % val = guess
|
||||
phi_o % val = guess
|
||||
k_n = keff
|
||||
k_o = k_n
|
||||
dw = cmfd_shift
|
||||
k_s = k_o + dw
|
||||
k_ln = ONE/(ONE/k_n - ONE/k_s)
|
||||
k_lo = k_ln
|
||||
|
||||
! Fill in loss matrix
|
||||
call build_loss_matrix(loss, adjoint=adjoint)
|
||||
|
||||
! Fill in production matrix
|
||||
call build_prod_matrix(prod, adjoint=adjoint)
|
||||
|
||||
! Finalize setup of CSR matrices
|
||||
call loss % assemble()
|
||||
call prod % assemble()
|
||||
if (cmfd_write_matrices) then
|
||||
call loss % write('loss.dat')
|
||||
call prod % write('prod.dat')
|
||||
end if
|
||||
|
||||
! Set norms to 0
|
||||
norm_n = ZERO
|
||||
norm_o = ZERO
|
||||
|
||||
! Set up solver
|
||||
select case(cmfd % indices(4))
|
||||
case(1)
|
||||
cmfd_linsolver => cmfd_linsolver_1g
|
||||
case(2)
|
||||
cmfd_linsolver => cmfd_linsolver_2g
|
||||
case default
|
||||
cmfd_linsolver => cmfd_linsolver_ng
|
||||
end select
|
||||
|
||||
! Set tolerances
|
||||
ktol = cmfd_ktol
|
||||
stol = cmfd_stol
|
||||
|
||||
end subroutine init_data
|
||||
|
||||
!===============================================================================
|
||||
! COMPUTE_ADJOINT computes a mathematical adjoint of CMFD problem
|
||||
!===============================================================================
|
||||
|
||||
subroutine compute_adjoint()
|
||||
|
||||
use error, only: fatal_error
|
||||
#ifdef PETSC
|
||||
use global, only: cmfd_write_matrices
|
||||
#endif
|
||||
|
||||
#ifdef PETSC
|
||||
! Transpose matrices
|
||||
call loss % transpose()
|
||||
call prod % transpose()
|
||||
|
||||
! Write out matrix in binary file (debugging)
|
||||
if (cmfd_write_matrices) then
|
||||
call loss % write_petsc_binary('adj_lossmat.bin')
|
||||
call prod % write_petsc_binary('adj_prodmat.bin')
|
||||
end if
|
||||
#else
|
||||
call fatal_error('Adjoint calculations only allowed with PETSc')
|
||||
#endif
|
||||
|
||||
end subroutine compute_adjoint
|
||||
|
||||
!===============================================================================
|
||||
! EXECUTE_POWER_ITER is the main power iteration routine
|
||||
! for the cmfd calculation
|
||||
!===============================================================================
|
||||
|
||||
subroutine execute_power_iter()
|
||||
|
||||
use constants, only: ONE
|
||||
use error, only: fatal_error
|
||||
use global, only: cmfd_atoli, cmfd_rtoli
|
||||
|
||||
integer :: i ! iteration counter
|
||||
integer :: innerits ! # of inner iterations
|
||||
integer :: totalits ! total number of inners
|
||||
logical :: iconv ! did the problem converged
|
||||
real(8) :: atoli ! absolute minimum tolerance
|
||||
real(8) :: rtoli ! relative tolerance based on source conv
|
||||
real(8) :: toli ! the current tolerance of inners
|
||||
|
||||
! Reset convergence flag
|
||||
iconv = .false.
|
||||
|
||||
! Set up tolerances
|
||||
atoli = cmfd_atoli
|
||||
rtoli = cmfd_rtoli
|
||||
toli = rtoli*100._8
|
||||
|
||||
! Perform shift
|
||||
call wielandt_shift()
|
||||
totalits = 0
|
||||
|
||||
! Begin power iteration
|
||||
do i = 1, 10000
|
||||
|
||||
! Check if reached iteration 10000
|
||||
if (i == 10000) then
|
||||
call fatal_error('Reached maximum iterations in CMFD power iteration &
|
||||
&solver.')
|
||||
end if
|
||||
|
||||
! Compute source vector
|
||||
call prod % vector_multiply(phi_o, s_o)
|
||||
|
||||
! Normalize source vector
|
||||
s_o % val = s_o % val / k_lo
|
||||
|
||||
! Compute new flux vector
|
||||
call cmfd_linsolver(loss, s_o, phi_n, toli, innerits)
|
||||
|
||||
! Compute new source vector
|
||||
call prod % vector_multiply(phi_n, s_n)
|
||||
|
||||
! Compute new shifted eigenvalue
|
||||
k_ln = sum(s_n % val) / sum(s_o % val)
|
||||
|
||||
! Compute new eigenvalue
|
||||
k_n = ONE/(ONE/k_ln + ONE/k_s)
|
||||
|
||||
! Renormalize the old source
|
||||
s_o % val = s_o % val * k_lo
|
||||
|
||||
! Check convergence
|
||||
call convergence(i, innerits, iconv)
|
||||
totalits = totalits + innerits
|
||||
|
||||
! Break loop if converged
|
||||
if (iconv) exit
|
||||
|
||||
! Record old values
|
||||
phi_o % val = phi_n % val
|
||||
k_o = k_n
|
||||
k_lo = k_ln
|
||||
norm_o = norm_n
|
||||
|
||||
! Get new tolerance for inners
|
||||
toli = max(atoli, rtoli*serr)
|
||||
|
||||
end do
|
||||
|
||||
end subroutine execute_power_iter
|
||||
|
||||
!===============================================================================
|
||||
! WIELANDT SHIFT
|
||||
!===============================================================================
|
||||
|
||||
subroutine wielandt_shift()
|
||||
|
||||
use constants, only: ONE
|
||||
|
||||
integer :: irow ! row counter
|
||||
integer :: icol ! col counter
|
||||
integer :: jcol ! current col index in prod matrix
|
||||
|
||||
! perform subtraction
|
||||
jcol = 1
|
||||
ROWS: do irow = 1, loss % n
|
||||
COLS: do icol = loss % get_row(irow), loss % get_row(irow + 1) - 1
|
||||
if (loss % get_col(icol) == prod % get_col(jcol) .and. &
|
||||
jcol < prod % get_row(irow + 1)) then
|
||||
loss % val(icol) = loss % val(icol) - ONE/k_s*prod % val(jcol)
|
||||
jcol = jcol + 1
|
||||
end if
|
||||
end do COLS
|
||||
end do ROWS
|
||||
|
||||
end subroutine wielandt_shift
|
||||
|
||||
!===============================================================================
|
||||
! CONVERGENCE checks the convergence of the CMFD problem
|
||||
!===============================================================================
|
||||
|
||||
subroutine convergence(iter, innerits, iconv)
|
||||
|
||||
use constants, only: ONE, ZERO
|
||||
use global, only: cmfd_power_monitor, master
|
||||
use, intrinsic :: ISO_FORTRAN_ENV
|
||||
|
||||
integer, intent(in) :: iter ! outer iteration number
|
||||
integer, intent(in) :: innerits ! inner iteration nubmer
|
||||
logical, intent(out) :: iconv ! convergence logical
|
||||
|
||||
! Reset convergence flag
|
||||
iconv = .false.
|
||||
|
||||
! Calculate error in keff
|
||||
kerr = abs(k_o - k_n)/k_n
|
||||
|
||||
! Calculate max error in source
|
||||
where (s_n % val > ZERO)
|
||||
serr_v % val = ((s_n % val - s_o % val)/s_n % val)**2
|
||||
end where
|
||||
serr = sqrt(ONE/dble(s_n % n) * sum(serr_v % val))
|
||||
|
||||
! Check for convergence
|
||||
if(kerr < ktol .and. serr < stol) iconv = .true.
|
||||
|
||||
! Save the L2 norm of the source
|
||||
norm_n = serr
|
||||
|
||||
! Print out to user
|
||||
if (cmfd_power_monitor .and. master) then
|
||||
write(OUTPUT_UNIT,FMT='(I0,":",T10,"k-eff: ",F0.8,T30,"k-error: ", &
|
||||
&1PE12.5,T55, "src-error: ",1PE12.5,T80,I0)') iter, k_n, kerr, &
|
||||
serr, innerits
|
||||
end if
|
||||
|
||||
end subroutine convergence
|
||||
|
||||
!===============================================================================
|
||||
! CMFD_LINSOLVER_1g solves the CMFD linear system
|
||||
!===============================================================================
|
||||
|
||||
subroutine cmfd_linsolver_1g(A, b, x, tol, its)
|
||||
|
||||
use constants, only: ONE, ZERO
|
||||
use error, only: fatal_error
|
||||
use global, only: cmfd, cmfd_spectral
|
||||
|
||||
type(Matrix), intent(inout) :: A ! coefficient matrix
|
||||
type(Vector), intent(inout) :: b ! right hand side vector
|
||||
type(Vector), intent(inout) :: x ! unknown vector
|
||||
real(8), intent(in) :: tol ! tolerance on final error
|
||||
integer, intent(out) :: its ! number of inner iterations
|
||||
|
||||
integer :: g ! group index
|
||||
integer :: i ! loop counter for x
|
||||
integer :: j ! loop counter for y
|
||||
integer :: k ! loop counter for z
|
||||
integer :: n ! total size of vector
|
||||
integer :: nx ! maximum dimension in x direction
|
||||
integer :: ny ! maximum dimension in y direction
|
||||
integer :: nz ! maximum dimension in z direction
|
||||
integer :: ng ! number of energy groups
|
||||
integer :: igs ! Gauss-Seidel iteration counter
|
||||
integer :: irb ! Red/Black iteration switch
|
||||
integer :: irow ! row iteration
|
||||
integer :: icol ! iteration counter over columns
|
||||
integer :: didx ! index for diagonal component
|
||||
logical :: found ! did we find col
|
||||
real(8) :: tmp1 ! temporary sum g1
|
||||
real(8) :: x1 ! new g1 value of x
|
||||
real(8) :: err ! error in convergence of solution
|
||||
real(8) :: w ! overrelaxation parameter
|
||||
type(Vector) :: tmpx ! temporary solution vector
|
||||
|
||||
! Set overrelaxation parameter
|
||||
w = ONE
|
||||
|
||||
! Dimensions
|
||||
ng = 1
|
||||
nx = cmfd % indices(1)
|
||||
ny = cmfd % indices(2)
|
||||
nz = cmfd % indices(3)
|
||||
n = A % n
|
||||
|
||||
! Perform Gauss Seidel iterations
|
||||
GS: do igs = 1, 10000
|
||||
|
||||
! Check for max iterations met
|
||||
if (igs == 10000) then
|
||||
call fatal_error('Maximum Gauss-Seidel iterations encountered.')
|
||||
endif
|
||||
|
||||
! Copy over x vector
|
||||
call tmpx % copy(x)
|
||||
|
||||
! Perform red/black gs iterations
|
||||
REDBLACK: do irb = 0,1
|
||||
|
||||
! Begin loop around matrix rows
|
||||
ROWS: do irow = 1, n
|
||||
|
||||
! Get spatial location
|
||||
call matrix_to_indices(irow, g, i, j, k, ng, nx, ny, nz)
|
||||
|
||||
! Filter out black cells (even)
|
||||
if (mod(i+j+k,2) == irb) cycle
|
||||
|
||||
! Get the index of the diagonals for both rows
|
||||
call A % search_indices(irow, irow, didx, found)
|
||||
|
||||
! Perform temporary sums, first do left of diag block, then right of diag block
|
||||
tmp1 = ZERO
|
||||
do icol = A % get_row(irow), didx - 1
|
||||
tmp1 = tmp1 + A % val(icol)*x % val(A % get_col(icol))
|
||||
end do
|
||||
do icol = didx + 1, A % get_row(irow + 1) - 1
|
||||
tmp1 = tmp1 + A % val(icol)*x % val(A % get_col(icol))
|
||||
end do
|
||||
|
||||
! Solve for new x
|
||||
x1 = (b % val(irow) - tmp1)/A % val(didx)
|
||||
|
||||
! Perform overrelaxation
|
||||
x % val(irow) = (ONE - w)*x % val(irow) + w*x1
|
||||
|
||||
end do ROWS
|
||||
|
||||
end do REDBLACK
|
||||
|
||||
! Check convergence
|
||||
err = sqrt(sum(((tmpx % val - x % val)/tmpx % val)**2)/n)
|
||||
its = igs
|
||||
if (err < tol) exit
|
||||
|
||||
! Calculation new overrelaxation parameter
|
||||
w = ONE/(ONE - 0.25_8*cmfd_spectral*w)
|
||||
|
||||
end do GS
|
||||
|
||||
call tmpx % destroy()
|
||||
|
||||
end subroutine cmfd_linsolver_1g
|
||||
|
||||
!===============================================================================
|
||||
! CMFD_LINSOLVER_2G solves the CMFD linear system
|
||||
!===============================================================================
|
||||
|
||||
subroutine cmfd_linsolver_2g(A, b, x, tol, its)
|
||||
|
||||
use constants, only: ONE, ZERO
|
||||
use error, only: fatal_error
|
||||
use global, only: cmfd, cmfd_spectral
|
||||
|
||||
type(Matrix), intent(inout) :: A ! coefficient matrix
|
||||
type(Vector), intent(inout) :: b ! right hand side vector
|
||||
type(Vector), intent(inout) :: x ! unknown vector
|
||||
real(8), intent(in) :: tol ! tolerance on final error
|
||||
integer, intent(out) :: its ! number of inner iterations
|
||||
|
||||
integer :: g ! group index
|
||||
integer :: i ! loop counter for x
|
||||
integer :: j ! loop counter for y
|
||||
integer :: k ! loop counter for z
|
||||
integer :: n ! total size of vector
|
||||
integer :: nx ! maximum dimension in x direction
|
||||
integer :: ny ! maximum dimension in y direction
|
||||
integer :: nz ! maximum dimension in z direction
|
||||
integer :: ng ! number of energy groups
|
||||
integer :: d1idx ! index of row "1" diagonal
|
||||
integer :: d2idx ! index of row "2" diagonal
|
||||
integer :: igs ! Gauss-Seidel iteration counter
|
||||
integer :: irb ! Red/Black iteration switch
|
||||
integer :: irow ! row iteration
|
||||
integer :: icol ! iteration counter over columns
|
||||
logical :: found ! did we find col
|
||||
real(8) :: m11 ! block diagonal component 1,1
|
||||
real(8) :: m12 ! block diagonal component 1,2
|
||||
real(8) :: m21 ! block diagonal component 2,1
|
||||
real(8) :: m22 ! block diagonal component 2,2
|
||||
real(8) :: dm ! determinant of block diagonal
|
||||
real(8) :: d11 ! inverse component 1,1
|
||||
real(8) :: d12 ! inverse component 1,2
|
||||
real(8) :: d21 ! inverse component 2,1
|
||||
real(8) :: d22 ! inverse component 2,2
|
||||
real(8) :: tmp1 ! temporary sum g1
|
||||
real(8) :: tmp2 ! temporary sum g2
|
||||
real(8) :: x1 ! new g1 value of x
|
||||
real(8) :: x2 ! new g2 value of x
|
||||
real(8) :: err ! error in convergence of solution
|
||||
real(8) :: w ! overrelaxation parameter
|
||||
type(Vector) :: tmpx ! temporary solution vector
|
||||
|
||||
! Set tolerance and overrelaxation parameter
|
||||
w = ONE
|
||||
|
||||
! Dimensions
|
||||
ng = 2
|
||||
nx = cmfd % indices(1)
|
||||
ny = cmfd % indices(2)
|
||||
nz = cmfd % indices(3)
|
||||
n = A % n
|
||||
|
||||
! Perform Gauss Seidel iterations
|
||||
GS: do igs = 1, 10000
|
||||
|
||||
! Check for max iterations met
|
||||
if (igs == 10000) then
|
||||
call fatal_error('Maximum Gauss-Seidel iterations encountered.')
|
||||
endif
|
||||
|
||||
! Copy over x vector
|
||||
call tmpx % copy(x)
|
||||
|
||||
! Perform red/black gs iterations
|
||||
REDBLACK: do irb = 0,1
|
||||
|
||||
! Begin loop around matrix rows
|
||||
ROWS: do irow = 1, n, 2
|
||||
|
||||
! Get spatial location
|
||||
call matrix_to_indices(irow, g, i, j, k, ng, nx, ny, nz)
|
||||
|
||||
! Filter out black cells (even)
|
||||
if (mod(i+j+k,2) == irb) cycle
|
||||
|
||||
! Get the index of the diagonals for both rows
|
||||
call A % search_indices(irow, irow, d1idx, found)
|
||||
call A % search_indices(irow + 1, irow + 1, d2idx, found)
|
||||
|
||||
! Get block diagonal
|
||||
m11 = A % val(d1idx) ! group 1 diagonal
|
||||
m12 = A % val(d1idx + 1) ! group 1 right of diagonal (sorted by col)
|
||||
m21 = A % val(d2idx - 1) ! group 2 left of diagonal (sorted by col)
|
||||
m22 = A % val(d2idx) ! group 2 diagonal
|
||||
|
||||
! Analytically invert the diagonal
|
||||
dm = m11*m22 - m12*m21
|
||||
d11 = m22/dm
|
||||
d12 = -m12/dm
|
||||
d21 = -m21/dm
|
||||
d22 = m11/dm
|
||||
|
||||
! Perform temporary sums, first do left of diag block, then right of diag block
|
||||
tmp1 = ZERO
|
||||
tmp2 = ZERO
|
||||
do icol = A % get_row(irow), d1idx - 1
|
||||
tmp1 = tmp1 + A % val(icol)*x % val(A % get_col(icol))
|
||||
end do
|
||||
do icol = A % get_row(irow + 1), d2idx - 2
|
||||
tmp2 = tmp2 + A % val(icol)*x % val(A % get_col(icol))
|
||||
end do
|
||||
do icol = d1idx + 2, A % get_row(irow + 1) - 1
|
||||
tmp1 = tmp1 + A % val(icol)*x % val(A % get_col(icol))
|
||||
end do
|
||||
do icol = d2idx + 1, A % get_row(irow + 2) - 1
|
||||
tmp2 = tmp2 + A % val(icol)*x % val(A % get_col(icol))
|
||||
end do
|
||||
|
||||
! Adjust with RHS vector
|
||||
tmp1 = b % val(irow) - tmp1
|
||||
tmp2 = b % val(irow + 1) - tmp2
|
||||
|
||||
! Solve for new x
|
||||
x1 = d11*tmp1 + d12*tmp2
|
||||
x2 = d21*tmp1 + d22*tmp2
|
||||
|
||||
! Perform overrelaxation
|
||||
x % val(irow) = (ONE - w)*x % val(irow) + w*x1
|
||||
x % val(irow + 1) = (ONE - w)*x % val(irow + 1) + w*x2
|
||||
|
||||
end do ROWS
|
||||
|
||||
end do REDBLACK
|
||||
|
||||
! Check convergence
|
||||
err = sqrt(sum(((tmpx % val - x % val)/tmpx % val)**2)/n)
|
||||
its = igs
|
||||
if (err < tol) exit
|
||||
|
||||
! Calculation new overrelaxation parameter
|
||||
w = ONE/(ONE - 0.25_8*cmfd_spectral*w)
|
||||
|
||||
end do GS
|
||||
|
||||
call tmpx % destroy()
|
||||
|
||||
end subroutine cmfd_linsolver_2g
|
||||
|
||||
!===============================================================================
|
||||
! CMFD_LINSOLVER_ng solves the CMFD linear system
|
||||
!===============================================================================
|
||||
|
||||
subroutine cmfd_linsolver_ng(A, b, x, tol, its)
|
||||
|
||||
use constants, only: ONE, ZERO
|
||||
use error, only: fatal_error
|
||||
use global, only: cmfd, cmfd_spectral
|
||||
|
||||
type(Matrix), intent(inout) :: A ! coefficient matrix
|
||||
type(Vector), intent(inout) :: b ! right hand side vector
|
||||
type(Vector), intent(inout) :: x ! unknown vector
|
||||
real(8), intent(in) :: tol ! tolerance on final error
|
||||
integer, intent(out) :: its ! number of inner iterations
|
||||
|
||||
integer :: g ! group index
|
||||
integer :: i ! loop counter for x
|
||||
integer :: j ! loop counter for y
|
||||
integer :: k ! loop counter for z
|
||||
integer :: n ! total size of vector
|
||||
integer :: nx ! maximum dimension in x direction
|
||||
integer :: ny ! maximum dimension in y direction
|
||||
integer :: nz ! maximum dimension in z direction
|
||||
integer :: ng ! number of energy groups
|
||||
integer :: igs ! Gauss-Seidel iteration counter
|
||||
integer :: irow ! row iteration
|
||||
integer :: icol ! iteration counter over columns
|
||||
integer :: didx ! index for diagonal component
|
||||
logical :: found ! did we find col
|
||||
real(8) :: tmp1 ! temporary sum g1
|
||||
real(8) :: x1 ! new g1 value of x
|
||||
real(8) :: err ! error in convergence of solution
|
||||
real(8) :: w ! overrelaxation parameter
|
||||
type(Vector) :: tmpx ! temporary solution vector
|
||||
|
||||
! Set overrelaxation parameter
|
||||
w = ONE
|
||||
|
||||
! Dimensions
|
||||
ng = 1
|
||||
nx = cmfd % indices(1)
|
||||
ny = cmfd % indices(2)
|
||||
nz = cmfd % indices(3)
|
||||
n = A % n
|
||||
|
||||
! Perform Gauss Seidel iterations
|
||||
GS: do igs = 1, 10000
|
||||
|
||||
! Check for max iterations met
|
||||
if (igs == 10000) then
|
||||
call fatal_error('Maximum Gauss-Seidel iterations encountered.')
|
||||
endif
|
||||
|
||||
! Copy over x vector
|
||||
call tmpx % copy(x)
|
||||
|
||||
! Begin loop around matrix rows
|
||||
ROWS: do irow = 1, n
|
||||
|
||||
! Get spatial location
|
||||
call matrix_to_indices(irow, g, i, j, k, ng, nx, ny, nz)
|
||||
|
||||
! Get the index of the diagonals for both rows
|
||||
call A % search_indices(irow, irow, didx, found)
|
||||
|
||||
! Perform temporary sums, first do left of diag block, then right of diag block
|
||||
tmp1 = ZERO
|
||||
do icol = A % get_row(irow), didx - 1
|
||||
tmp1 = tmp1 + A % val(icol)*x % val(A % get_col(icol))
|
||||
end do
|
||||
do icol = didx + 1, A % get_row(irow + 1) - 1
|
||||
tmp1 = tmp1 + A % val(icol)*x % val(A % get_col(icol))
|
||||
end do
|
||||
|
||||
! Solve for new x
|
||||
x1 = (b % val(irow) - tmp1)/A % val(didx)
|
||||
|
||||
! Perform overrelaxation
|
||||
x % val(irow) = (ONE - w)*x % val(irow) + w*x1
|
||||
|
||||
end do ROWS
|
||||
|
||||
! Check convergence
|
||||
err = sqrt(sum(((tmpx % val - x % val)/tmpx % val)**2)/n)
|
||||
its = igs
|
||||
|
||||
if (err < tol) exit
|
||||
|
||||
! Calculation new overrelaxation parameter
|
||||
w = ONE/(ONE - 0.25_8*cmfd_spectral*w)
|
||||
|
||||
end do GS
|
||||
|
||||
call tmpx % destroy()
|
||||
|
||||
end subroutine cmfd_linsolver_ng
|
||||
|
||||
!===============================================================================
|
||||
! EXTRACT_RESULTS takes results and puts them in CMFD global data object
|
||||
!===============================================================================
|
||||
|
||||
subroutine extract_results()
|
||||
|
||||
use global, only: cmfd, cmfd_write_matrices, current_batch
|
||||
|
||||
character(len=25) :: filename ! name of file to write data
|
||||
integer :: n ! problem size
|
||||
|
||||
! Get problem size
|
||||
n = loss % n
|
||||
|
||||
! Allocate in cmfd object if not already allocated
|
||||
if (adjoint_calc) then
|
||||
if (.not. allocated(cmfd%adj_phi)) allocate(cmfd%adj_phi(n))
|
||||
else
|
||||
if (.not. allocated(cmfd%phi)) allocate(cmfd%phi(n))
|
||||
end if
|
||||
|
||||
! Save values
|
||||
if (adjoint_calc) then
|
||||
cmfd % adj_phi = phi_n % val
|
||||
else
|
||||
cmfd % phi = phi_n % val
|
||||
end if
|
||||
|
||||
! Save eigenvalue
|
||||
if(adjoint_calc) then
|
||||
cmfd%adj_keff = k_n
|
||||
else
|
||||
cmfd%keff = k_n
|
||||
end if
|
||||
|
||||
! Normalize phi to 1
|
||||
if (adjoint_calc) then
|
||||
cmfd%adj_phi = cmfd%adj_phi/sqrt(sum(cmfd%adj_phi*cmfd%adj_phi))
|
||||
else
|
||||
cmfd%phi = cmfd%phi/sqrt(sum(cmfd%phi*cmfd%phi))
|
||||
end if
|
||||
|
||||
! Save dominance ratio
|
||||
cmfd % dom(current_batch) = norm_n/norm_o
|
||||
|
||||
! Write out results
|
||||
if (cmfd_write_matrices) then
|
||||
if (adjoint_calc) then
|
||||
filename = 'adj_fluxvec.bin'
|
||||
else
|
||||
filename = 'fluxvec.bin'
|
||||
end if
|
||||
#ifdef PETSC
|
||||
call phi_n % write_petsc_binary(filename)
|
||||
#endif
|
||||
end if
|
||||
|
||||
end subroutine extract_results
|
||||
|
||||
!===============================================================================
|
||||
! MATRIX_TO_INDICES converts a matrix index to spatial and group indicies
|
||||
!===============================================================================
|
||||
|
||||
subroutine matrix_to_indices(irow, g, i, j, k, ng, nx, ny, nz)
|
||||
|
||||
use global, only: cmfd, cmfd_coremap
|
||||
|
||||
integer, intent(out) :: i ! iteration counter for x
|
||||
integer, intent(out) :: j ! iteration counter for y
|
||||
integer, intent(out) :: k ! iteration counter for z
|
||||
integer, intent(out) :: g ! iteration counter for groups
|
||||
integer, intent(in) :: irow ! iteration counter over row (0 reference)
|
||||
integer, intent(in) :: nx ! maximum number of x cells
|
||||
integer, intent(in) :: ny ! maximum number of y cells
|
||||
integer, intent(in) :: nz ! maximum number of z cells
|
||||
integer, intent(in) :: ng ! maximum number of groups
|
||||
|
||||
! Check for core map
|
||||
if (cmfd_coremap) then
|
||||
|
||||
! Get indices from indexmap
|
||||
g = mod(irow-1, ng) + 1
|
||||
i = cmfd % indexmap((irow-1)/ng+1,1)
|
||||
j = cmfd % indexmap((irow-1)/ng+1,2)
|
||||
k = cmfd % indexmap((irow-1)/ng+1,3)
|
||||
|
||||
else
|
||||
|
||||
! Compute indices
|
||||
g = mod(irow-1, ng) + 1
|
||||
i = mod(irow-1, ng*nx)/ng + 1
|
||||
j = mod(irow-1, ng*nx*ny)/(ng*nx)+ 1
|
||||
k = mod(irow-1, ng*nx*ny*nz)/(ng*nx*ny) + 1
|
||||
|
||||
end if
|
||||
|
||||
end subroutine matrix_to_indices
|
||||
|
||||
!===============================================================================
|
||||
! FINALIZE frees all memory associated with power iteration
|
||||
!===============================================================================
|
||||
|
||||
subroutine finalize()
|
||||
|
||||
! Destroy all objects
|
||||
call loss % destroy()
|
||||
call prod % destroy()
|
||||
call phi_n % destroy()
|
||||
call phi_o % destroy()
|
||||
call s_n % destroy()
|
||||
call s_o % destroy()
|
||||
call serr_v % destroy
|
||||
|
||||
end subroutine finalize
|
||||
|
||||
end module cmfd_solver
|
||||
|
|
@ -8,7 +8,7 @@ module constants
|
|||
! OpenMC major, minor, and release numbers
|
||||
integer, parameter :: VERSION_MAJOR = 0
|
||||
integer, parameter :: VERSION_MINOR = 6
|
||||
integer, parameter :: VERSION_RELEASE = 0
|
||||
integer, parameter :: VERSION_RELEASE = 1
|
||||
|
||||
! Revision numbers for binary files
|
||||
integer, parameter :: REVISION_STATEPOINT = 13
|
||||
|
|
@ -393,9 +393,6 @@ module constants
|
|||
! constant to represent a zero flux "albedo"
|
||||
real(8), parameter :: ZERO_FLUX = 999.0_8
|
||||
|
||||
! constant to represent albedo rejection
|
||||
real(8), parameter :: ALBEDO_REJECT = 999.0_8
|
||||
|
||||
! constant for writing out no residual
|
||||
real(8), parameter :: CMFD_NORES = 99999.0_8
|
||||
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ contains
|
|||
atom_density * micro_xs(i_nuclide) % elastic
|
||||
|
||||
! Add contributions to material macroscopic absorption cross section
|
||||
material_xs % absorption = material_xs % absorption + &
|
||||
material_xs % absorption = material_xs % absorption + &
|
||||
atom_density * micro_xs(i_nuclide) % absorption
|
||||
|
||||
! Add contributions to material macroscopic fission cross section
|
||||
|
|
@ -123,7 +123,7 @@ contains
|
|||
! Add contributions to material macroscopic nu-fission cross section
|
||||
material_xs % nu_fission = material_xs % nu_fission + &
|
||||
atom_density * micro_xs(i_nuclide) % nu_fission
|
||||
|
||||
|
||||
! Add contributions to material macroscopic energy release from fission
|
||||
material_xs % kappa_fission = material_xs % kappa_fission + &
|
||||
atom_density * micro_xs(i_nuclide) % kappa_fission
|
||||
|
|
@ -214,7 +214,7 @@ contains
|
|||
! Calculate microscopic nuclide nu-fission cross section
|
||||
micro_xs(i_nuclide) % nu_fission = (ONE - f) * nuc % nu_fission( &
|
||||
i_grid) + f * nuc % nu_fission(i_grid+1)
|
||||
|
||||
|
||||
! Calculate microscopic nuclide kappa-fission cross section
|
||||
! The ENDF standard (ENDF-102) states that MT 18 stores
|
||||
! the fission energy as the Q_value (fission(1))
|
||||
|
|
@ -276,7 +276,7 @@ contains
|
|||
f = ZERO
|
||||
else
|
||||
i_grid = binary_search(sab % inelastic_e_in, sab % n_inelastic_e_in, E)
|
||||
f = (E - sab%inelastic_e_in(i_grid)) / &
|
||||
f = (E - sab%inelastic_e_in(i_grid)) / &
|
||||
(sab%inelastic_e_in(i_grid+1) - sab%inelastic_e_in(i_grid))
|
||||
end if
|
||||
|
||||
|
|
@ -342,21 +342,22 @@ contains
|
|||
integer, intent(in) :: i_nuclide ! index into nuclides array
|
||||
real(8), intent(in) :: E ! energy
|
||||
|
||||
integer :: i_energy ! index for energy
|
||||
integer :: i_low ! band index at lower bounding energy
|
||||
integer :: i_up ! band index at upper bounding energy
|
||||
real(8) :: f ! interpolation factor
|
||||
real(8) :: r ! pseudo-random number
|
||||
real(8) :: elastic ! elastic cross section
|
||||
real(8) :: capture ! (n,gamma) cross section
|
||||
real(8) :: fission ! fission cross section
|
||||
real(8) :: inelastic ! inelastic cross section
|
||||
logical :: same_nuc ! do we know the xs for this nuclide at this energy?
|
||||
integer :: i ! loop index
|
||||
integer :: i_energy ! index for energy
|
||||
integer :: i_low ! band index at lower bounding energy
|
||||
integer :: i_up ! band index at upper bounding energy
|
||||
integer :: same_nuc_idx ! index of same nuclide
|
||||
real(8) :: f ! interpolation factor
|
||||
real(8) :: r ! pseudo-random number
|
||||
real(8) :: elastic ! elastic cross section
|
||||
real(8) :: capture ! (n,gamma) cross section
|
||||
real(8) :: fission ! fission cross section
|
||||
real(8) :: inelastic ! inelastic cross section
|
||||
logical :: same_nuc ! do we know the xs for this nuclide at this energy?
|
||||
type(UrrData), pointer, save :: urr => null()
|
||||
type(Nuclide), pointer, save :: nuc => null()
|
||||
type(Reaction), pointer, save :: rxn => null()
|
||||
type(ListElemInt), pointer :: nuc_list => null()
|
||||
!$omp threadprivate(urr, nuc, rxn, nuc_list)
|
||||
!$omp threadprivate(urr, nuc, rxn)
|
||||
|
||||
micro_xs(i_nuclide) % use_ptable = .true.
|
||||
|
||||
|
|
@ -381,18 +382,16 @@ contains
|
|||
! this energy but a different temperature, use the original random number to
|
||||
! preserve correlation of temperature in probability tables
|
||||
same_nuc = .false.
|
||||
nuc_list => nuc % nuc_list
|
||||
do
|
||||
if (E /= ZERO .and. E == micro_xs(nuc_list % data) % last_E) then
|
||||
do i = 1, nuc % nuc_list % size()
|
||||
if (E /= ZERO .and. E == micro_xs(nuc % nuc_list % get_item(i)) % last_E) then
|
||||
same_nuc = .true.
|
||||
same_nuc_idx = i
|
||||
exit
|
||||
end if
|
||||
nuc_list => nuc_list % next
|
||||
if (.not. associated(nuc_list % next)) exit
|
||||
end do
|
||||
|
||||
if (same_nuc) then
|
||||
r = micro_xs(nuc_list % data) % last_prn
|
||||
r = micro_xs(nuc % nuc_list % get_item(same_nuc_idx)) % last_prn
|
||||
else
|
||||
r = prn()
|
||||
micro_xs(i_nuclide) % last_prn = r
|
||||
|
|
@ -476,6 +475,11 @@ contains
|
|||
fission = fission * micro_xs(i_nuclide) % fission
|
||||
end if
|
||||
|
||||
! Check for negative values
|
||||
if (elastic < ZERO) elastic = ZERO
|
||||
if (fission < ZERO) fission = ZERO
|
||||
if (capture < ZERO) capture = ZERO
|
||||
|
||||
! Set elastic, absorption, fission, and total cross sections. Note that the
|
||||
! total cross section is calculated as sum of partials rather than using the
|
||||
! table-provided value
|
||||
|
|
@ -539,11 +543,11 @@ contains
|
|||
if (nuc % energy_0K(i_grid) == nuc % energy_0K(i_grid+1)) then
|
||||
i_grid = i_grid + 1
|
||||
end if
|
||||
|
||||
|
||||
! calculate interpolation factor
|
||||
f = (E - nuc % energy_0K(i_grid)) &
|
||||
& / (nuc % energy_0K(i_grid + 1) - nuc % energy_0K(i_grid))
|
||||
|
||||
|
||||
! Calculate microscopic nuclide elastic cross section
|
||||
xs_out = (ONE - f) * nuc % elastic_0K(i_grid) &
|
||||
& + f * nuc % elastic_0K(i_grid + 1)
|
||||
|
|
|
|||
|
|
@ -26,8 +26,9 @@ module eigenvalue
|
|||
private
|
||||
public :: run_eigenvalue
|
||||
|
||||
real(8) :: keff_generation ! Single-generation k on each processor
|
||||
real(8) :: k_sum(2) = ZERO ! used to reduce sum and sum_sq
|
||||
real(8) :: keff_generation ! Single-generation k on each
|
||||
! processor
|
||||
real(8) :: k_sum(2) = ZERO ! Used to reduce sum and sum_sq
|
||||
|
||||
contains
|
||||
|
||||
|
|
@ -114,8 +115,8 @@ contains
|
|||
|
||||
subroutine initialize_batch()
|
||||
|
||||
message = "Simulating batch " // trim(to_str(current_batch)) // "..."
|
||||
call write_message(8)
|
||||
call write_message("Simulating batch " // trim(to_str(current_batch)) &
|
||||
&// "...", 8)
|
||||
|
||||
! Reset total starting particle weight used for normalizing tallies
|
||||
total_weight = ZERO
|
||||
|
|
@ -301,8 +302,7 @@ contains
|
|||
! runs enough particles to avoid this in the first place.
|
||||
|
||||
if (n_bank == 0) then
|
||||
message = "No fission sites banked on processor " // to_str(rank)
|
||||
call fatal_error()
|
||||
call fatal_error("No fission sites banked on processor " // to_str(rank))
|
||||
end if
|
||||
|
||||
! Make sure all processors start at the same point for random sampling. Then
|
||||
|
|
@ -536,12 +536,12 @@ contains
|
|||
m % n_dimension = 3
|
||||
allocate(m % dimension(3))
|
||||
m % dimension = n
|
||||
|
||||
! determine width
|
||||
m % width = (m % upper_right - m % lower_left) / m % dimension
|
||||
|
||||
end if
|
||||
|
||||
! allocate and determine width
|
||||
allocate(m % width(3))
|
||||
m % width = (m % upper_right - m % lower_left) / m % dimension
|
||||
|
||||
! allocate p
|
||||
allocate(entropy_p(1, m % dimension(1), m % dimension(2), &
|
||||
m % dimension(3)))
|
||||
|
|
@ -553,8 +553,7 @@ contains
|
|||
|
||||
! display warning message if there were sites outside entropy box
|
||||
if (sites_outside) then
|
||||
message = "Fission source site(s) outside of entropy box."
|
||||
call warning()
|
||||
if (master) call warning("Fission source site(s) outside of entropy box.")
|
||||
end if
|
||||
|
||||
! sum values to obtain shannon entropy
|
||||
|
|
@ -772,8 +771,7 @@ contains
|
|||
|
||||
! Check for sites outside of the mesh
|
||||
if (master .and. sites_outside) then
|
||||
message = "Source sites outside of the UFS mesh!"
|
||||
call fatal_error()
|
||||
call fatal_error("Source sites outside of the UFS mesh!")
|
||||
end if
|
||||
|
||||
#ifdef MPI
|
||||
|
|
@ -803,8 +801,7 @@ contains
|
|||
|
||||
! Write message at beginning
|
||||
if (current_batch == 1) then
|
||||
message = "Replaying history from state point..."
|
||||
call write_message(1)
|
||||
call write_message("Replaying history from state point...", 1)
|
||||
end if
|
||||
|
||||
do current_gen = 1, gen_per_batch
|
||||
|
|
@ -821,8 +818,7 @@ contains
|
|||
|
||||
! Write message at end
|
||||
if (current_batch == restart_batch) then
|
||||
message = "Resuming simulation..."
|
||||
call write_message(1)
|
||||
call write_message("Resuming simulation...", 1)
|
||||
end if
|
||||
|
||||
end subroutine replay_batch_history
|
||||
|
|
|
|||
|
|
@ -21,8 +21,7 @@ contains
|
|||
type(ListReal), pointer :: list => null()
|
||||
type(Nuclide), pointer :: nuc => null()
|
||||
|
||||
message = "Creating unionized energy grid..."
|
||||
call write_message(5)
|
||||
call write_message("Creating unionized energy grid...", 5)
|
||||
|
||||
! Add grid points for each nuclide in the problem
|
||||
do i = 1, n_nuclides_total
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
module error
|
||||
|
||||
use, intrinsic :: ISO_FORTRAN_ENV
|
||||
use constants
|
||||
|
||||
use global
|
||||
|
||||
|
|
@ -17,9 +18,9 @@ contains
|
|||
! stream.
|
||||
!===============================================================================
|
||||
|
||||
subroutine warning(force)
|
||||
subroutine warning(message)
|
||||
|
||||
logical, optional :: force ! force write from proc other than master
|
||||
character(*) :: message
|
||||
|
||||
integer :: i_start ! starting position
|
||||
integer :: i_end ! ending position
|
||||
|
|
@ -27,9 +28,6 @@ contains
|
|||
integer :: length ! length of message
|
||||
integer :: indent ! length of indentation
|
||||
|
||||
! Only allow master to print to screen
|
||||
if (.not. master .and. .not. present(force)) return
|
||||
|
||||
! Write warning at beginning
|
||||
write(ERROR_UNIT, fmt='(1X,A)', advance='no') 'WARNING: '
|
||||
|
||||
|
|
@ -78,8 +76,9 @@ contains
|
|||
! the program is aborted.
|
||||
!===============================================================================
|
||||
|
||||
subroutine fatal_error(error_code)
|
||||
subroutine fatal_error(message, error_code)
|
||||
|
||||
character(*) :: message
|
||||
integer, optional :: error_code ! error code
|
||||
|
||||
integer :: code ! error code
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ module fission
|
|||
use ace_header, only: Nuclide
|
||||
use constants
|
||||
use error, only: fatal_error
|
||||
use global, only: message
|
||||
use interpolation, only: interpolate_tab1
|
||||
use search, only: binary_search
|
||||
|
||||
|
|
@ -27,8 +26,7 @@ contains
|
|||
real(8) :: c ! polynomial coefficient
|
||||
|
||||
if (nuc % nu_t_type == NU_NONE) then
|
||||
message = "No neutron emission data for table: " // nuc % name
|
||||
call fatal_error()
|
||||
call fatal_error("No neutron emission data for table: " // nuc % name)
|
||||
elseif (nuc % nu_t_type == NU_POLYNOMIAL) then
|
||||
! determine number of coefficients
|
||||
NC = int(nuc % nu_t_data(1))
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
module fixed_source
|
||||
|
||||
use constants, only: ZERO
|
||||
use constants, only: ZERO, MAX_LINE_LEN
|
||||
use global
|
||||
use output, only: write_message, header
|
||||
use particle_header, only: Particle
|
||||
|
|
@ -94,8 +94,8 @@ contains
|
|||
|
||||
subroutine initialize_batch()
|
||||
|
||||
message = "Simulating batch " // trim(to_str(current_batch)) // "..."
|
||||
call write_message(1)
|
||||
call write_message("Simulating batch " // trim(to_str(current_batch)) &
|
||||
&// "...", 1)
|
||||
|
||||
! Reset total starting particle weight used for normalizing tallies
|
||||
total_weight = ZERO
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ module geometry
|
|||
use tally, only: score_surface_current
|
||||
|
||||
implicit none
|
||||
|
||||
|
||||
contains
|
||||
|
||||
!===============================================================================
|
||||
|
|
@ -100,11 +100,10 @@ contains
|
|||
if (simple_cell_contains(c, p)) then
|
||||
! the particle should only be contained in one cell per level
|
||||
if (index_cell /= coord % cell) then
|
||||
message = "Overlapping cells detected: " // &
|
||||
trim(to_str(cells(index_cell) % id)) // ", " // &
|
||||
trim(to_str(cells(coord % cell) % id)) // &
|
||||
" on universe " // trim(to_str(univ % id))
|
||||
call fatal_error()
|
||||
call fatal_error("Overlapping cells detected: " &
|
||||
&// trim(to_str(cells(index_cell) % id)) // ", " &
|
||||
&// trim(to_str(cells(coord % cell) % id)) &
|
||||
&// " on universe " // trim(to_str(univ % id)))
|
||||
end if
|
||||
|
||||
overlap_check_cnt(index_cell) = overlap_check_cnt(index_cell) + 1
|
||||
|
|
@ -179,8 +178,7 @@ contains
|
|||
|
||||
! Show cell information on trace
|
||||
if (verbosity >= 10 .or. trace) then
|
||||
message = " Entering cell " // trim(to_str(c % id))
|
||||
call write_message()
|
||||
call write_message(" Entering cell " // trim(to_str(c % id)))
|
||||
end if
|
||||
|
||||
if (c % type == CELL_NORMAL) then
|
||||
|
|
@ -384,8 +382,7 @@ contains
|
|||
i_surface = abs(p % surface)
|
||||
surf => surfaces(i_surface)
|
||||
if (verbosity >= 10 .or. trace) then
|
||||
message = " Crossing surface " // trim(to_str(surf % id))
|
||||
call write_message()
|
||||
call write_message(" Crossing surface " // trim(to_str(surf % id)))
|
||||
end if
|
||||
|
||||
if (surf % bc == BC_VACUUM .and. (run_mode /= MODE_PLOTTING)) then
|
||||
|
|
@ -417,8 +414,8 @@ contains
|
|||
|
||||
! Display message
|
||||
if (verbosity >= 10 .or. trace) then
|
||||
message = " Leaked out of surface " // trim(to_str(surf % id))
|
||||
call write_message()
|
||||
call write_message(" Leaked out of surface " &
|
||||
&// trim(to_str(surf % id)))
|
||||
end if
|
||||
return
|
||||
|
||||
|
|
@ -428,9 +425,8 @@ contains
|
|||
|
||||
! Do not handle reflective boundary conditions on lower universes
|
||||
if (.not. associated(p % coord, p % coord0)) then
|
||||
message = "Cannot reflect particle " // trim(to_str(p % id)) // &
|
||||
" off surface in a lower universe."
|
||||
call handle_lost_particle(p)
|
||||
call handle_lost_particle(p, "Cannot reflect particle " &
|
||||
&// trim(to_str(p % id)) // " off surface in a lower universe.")
|
||||
return
|
||||
end if
|
||||
|
||||
|
|
@ -562,9 +558,8 @@ contains
|
|||
w = w + 2*dot_prod*R*z
|
||||
|
||||
case default
|
||||
message = "Reflection not supported for surface " // &
|
||||
trim(to_str(surf % id))
|
||||
call fatal_error()
|
||||
call fatal_error("Reflection not supported for surface " &
|
||||
&// trim(to_str(surf % id)))
|
||||
end select
|
||||
|
||||
! Set new particle direction
|
||||
|
|
@ -583,8 +578,8 @@ contains
|
|||
call deallocate_coord(p % coord0 % next)
|
||||
call find_cell(p, found)
|
||||
if (.not. found) then
|
||||
message = "Couldn't find particle after reflecting from surface."
|
||||
call handle_lost_particle(p)
|
||||
call handle_lost_particle(p, "Couldn't find particle after reflecting&
|
||||
& from surface.")
|
||||
return
|
||||
end if
|
||||
end if
|
||||
|
|
@ -594,8 +589,8 @@ contains
|
|||
|
||||
! Diagnostic message
|
||||
if (verbosity >= 10 .or. trace) then
|
||||
message = " Reflected from surface " // trim(to_str(surf%id))
|
||||
call write_message()
|
||||
call write_message(" Reflected from surface " &
|
||||
&// trim(to_str(surf%id)))
|
||||
end if
|
||||
return
|
||||
end if
|
||||
|
|
@ -643,10 +638,9 @@ contains
|
|||
! undefined region in the geometry.
|
||||
|
||||
if (.not. found) then
|
||||
message = "After particle " // trim(to_str(p % id)) // " crossed surface " &
|
||||
// trim(to_str(surfaces(i_surface) % id)) // " it could not be &
|
||||
&located in any cell and it did not leak."
|
||||
call handle_lost_particle(p)
|
||||
call handle_lost_particle(p, "After particle " // trim(to_str(p % id)) &
|
||||
&// " crossed surface " // trim(to_str(surfaces(i_surface) % id)) &
|
||||
&// " it could not be located in any cell and it did not leak.")
|
||||
return
|
||||
end if
|
||||
end if
|
||||
|
|
@ -672,11 +666,10 @@ contains
|
|||
lat => lattices(p % coord % lattice)
|
||||
|
||||
if (verbosity >= 10 .or. trace) then
|
||||
message = " Crossing lattice " // trim(to_str(lat % id)) // &
|
||||
". Current position (" // trim(to_str(p % coord % lattice_x)) &
|
||||
// "," // trim(to_str(p % coord % lattice_y)) // "," // &
|
||||
trim(to_str(p % coord % lattice_z)) // ")"
|
||||
call write_message()
|
||||
call write_message(" Crossing lattice " // trim(to_str(lat % id)) &
|
||||
&// ". Current position (" // trim(to_str(p % coord % lattice_x)) &
|
||||
&// "," // trim(to_str(p % coord % lattice_y)) // "," &
|
||||
&// trim(to_str(p % coord % lattice_z)) // ")")
|
||||
end if
|
||||
|
||||
if (lat % type == LATTICE_RECT) then
|
||||
|
|
@ -739,9 +732,8 @@ contains
|
|||
! Search for particle
|
||||
call find_cell(p, found)
|
||||
if (.not. found) then
|
||||
message = "Could not locate particle " // trim(to_str(p % id)) // &
|
||||
" after crossing a lattice boundary."
|
||||
call handle_lost_particle(p)
|
||||
call handle_lost_particle(p, "Could not locate particle " &
|
||||
&// trim(to_str(p % id)) // " after crossing a lattice boundary.")
|
||||
return
|
||||
end if
|
||||
else
|
||||
|
|
@ -762,9 +754,9 @@ contains
|
|||
! Search for particle
|
||||
call find_cell(p, found)
|
||||
if (.not. found) then
|
||||
message = "Could not locate particle " // trim(to_str(p % id)) // &
|
||||
" after crossing a lattice boundary."
|
||||
call handle_lost_particle(p)
|
||||
call handle_lost_particle(p, "Could not locate particle " &
|
||||
&// trim(to_str(p % id)) &
|
||||
&// " after crossing a lattice boundary.")
|
||||
return
|
||||
end if
|
||||
end if
|
||||
|
|
@ -1494,8 +1486,8 @@ contains
|
|||
type(Cell), pointer :: c
|
||||
type(Surface), pointer :: surf
|
||||
|
||||
message = "Building neighboring cells lists for each surface..."
|
||||
call write_message(4)
|
||||
call write_message("Building neighboring cells lists for each surface...", &
|
||||
&4)
|
||||
|
||||
allocate(count_positive(n_surfaces))
|
||||
allocate(count_negative(n_surfaces))
|
||||
|
|
@ -1562,12 +1554,13 @@ contains
|
|||
! HANDLE_LOST_PARTICLE
|
||||
!===============================================================================
|
||||
|
||||
subroutine handle_lost_particle(p)
|
||||
subroutine handle_lost_particle(p, message)
|
||||
|
||||
type(Particle), intent(inout) :: p
|
||||
character(*) :: message
|
||||
|
||||
! Print warning and write lost particle file
|
||||
call warning(force = .true.)
|
||||
call warning(message)
|
||||
call write_particle_restart(p)
|
||||
|
||||
! Increment number of lost particles
|
||||
|
|
@ -1579,8 +1572,7 @@ contains
|
|||
! Abort the simulation if the maximum number of lost particles has been
|
||||
! reached
|
||||
if (n_lost_particles == MAX_LOST_PARTICLES) then
|
||||
message = "Maximum number of lost particles has been reached."
|
||||
call fatal_error()
|
||||
call fatal_error("Maximum number of lost particles has been reached.")
|
||||
end if
|
||||
|
||||
end subroutine handle_lost_particle
|
||||
|
|
|
|||
|
|
@ -272,9 +272,6 @@ module global
|
|||
character(MAX_FILE_LEN) :: path_particle_restart ! Path to particle restart
|
||||
character(MAX_FILE_LEN) :: path_output = '' ! Path to output directory
|
||||
|
||||
! Message used in message/warning/fatal_error
|
||||
character(2*MAX_LINE_LEN) :: message
|
||||
|
||||
! Random number seed
|
||||
integer(8) :: seed = 1_8
|
||||
|
||||
|
|
@ -299,6 +296,9 @@ module global
|
|||
! Particle restart run
|
||||
logical :: particle_restart_run = .false.
|
||||
|
||||
! Write out initial source
|
||||
logical :: write_initial_source = .false.
|
||||
|
||||
! ============================================================================
|
||||
! CMFD VARIABLES
|
||||
|
||||
|
|
@ -329,9 +329,6 @@ module global
|
|||
integer :: n_cmfd_meshes = 1 ! # of structured meshes
|
||||
integer :: n_cmfd_tallies = 3 ! # of user-defined tallies
|
||||
|
||||
! Flag to hold cmfd weight adjustment factors
|
||||
logical :: cmfd_hold_weights = .false.
|
||||
|
||||
! Eigenvalue solver type
|
||||
character(len=10) :: cmfd_solver_type = 'power'
|
||||
|
||||
|
|
@ -344,11 +341,9 @@ module global
|
|||
! Batch to begin cmfd
|
||||
integer :: cmfd_begin = 1
|
||||
|
||||
! When and how long to flush cmfd tallies during inactive batches
|
||||
integer :: cmfd_inact_flush(2) = (/9999,1/)
|
||||
|
||||
! Batch to last flush before active batches
|
||||
integer :: cmfd_act_flush = 0
|
||||
! Tally reset list
|
||||
integer :: n_cmfd_resets
|
||||
type(SetInt) :: cmfd_reset
|
||||
|
||||
! Compute effective downscatter cross section
|
||||
logical :: cmfd_downscatter = .false.
|
||||
|
|
@ -366,11 +361,18 @@ module global
|
|||
|
||||
! CMFD run logicals
|
||||
logical :: cmfd_on = .false.
|
||||
logical :: cmfd_tally_on = .true.
|
||||
|
||||
! CMFD display info
|
||||
character(len=25) :: cmfd_display = 'balance'
|
||||
|
||||
! Estimate of spectral radius of CMFD matrices and tolerances
|
||||
real(8) :: cmfd_spectral = ZERO
|
||||
real(8) :: cmfd_shift = 1.e6
|
||||
real(8) :: cmfd_ktol = 1.e-8_8
|
||||
real(8) :: cmfd_stol = 1.e-8_8
|
||||
real(8) :: cmfd_atoli = 1.e-10_8
|
||||
real(8) :: cmfd_rtoli = 1.e-5_8
|
||||
|
||||
! Information about state points to be written
|
||||
integer :: n_state_points = 0
|
||||
type(SetInt) :: statepoint_batch
|
||||
|
|
@ -391,7 +393,7 @@ module global
|
|||
integer :: n_res_scatterers_total = 0 ! total number of resonant scatterers
|
||||
type(Nuclide0K), allocatable, target :: nuclides_0K(:) ! 0K nuclides info
|
||||
|
||||
!$omp threadprivate(micro_xs, material_xs, fission_bank, n_bank, message, &
|
||||
!$omp threadprivate(micro_xs, material_xs, fission_bank, n_bank, &
|
||||
!$omp& trace, thread_id, current_work, matching_bins)
|
||||
|
||||
contains
|
||||
|
|
|
|||
|
|
@ -156,10 +156,8 @@ contains
|
|||
|
||||
! Warn if overlap checking is on
|
||||
if (master .and. check_overlaps) then
|
||||
message = ""
|
||||
call write_message()
|
||||
message = "Cell overlap checking is ON"
|
||||
call warning()
|
||||
call write_message("")
|
||||
call warning("Cell overlap checking is ON")
|
||||
end if
|
||||
|
||||
! Stop initialization timer
|
||||
|
|
@ -342,9 +340,8 @@ contains
|
|||
|
||||
! Check that number specified was valid
|
||||
if (n_particles == ERROR_INT) then
|
||||
message = "Must specify integer after " // trim(argv(i-1)) // &
|
||||
" command-line flag."
|
||||
call fatal_error()
|
||||
call fatal_error("Must specify integer after " // trim(argv(i-1)) &
|
||||
&// " command-line flag.")
|
||||
end if
|
||||
case ('-r', '-restart', '--restart')
|
||||
! Read path for state point/particle restart
|
||||
|
|
@ -364,8 +361,7 @@ contains
|
|||
path_particle_restart = argv(i)
|
||||
particle_restart_run = .true.
|
||||
case default
|
||||
message = "Unrecognized file after restart flag."
|
||||
call fatal_error()
|
||||
call fatal_error("Unrecognized file after restart flag.")
|
||||
end select
|
||||
|
||||
! If its a restart run check for additional source file
|
||||
|
|
@ -383,8 +379,8 @@ contains
|
|||
call sp % read_data(filetype, 'filetype')
|
||||
call sp % file_close()
|
||||
if (filetype /= FILETYPE_SOURCE) then
|
||||
message = "Second file after restart flag must be a source file"
|
||||
call fatal_error()
|
||||
call fatal_error("Second file after restart flag must be a &
|
||||
&source file")
|
||||
end if
|
||||
|
||||
! It is a source file
|
||||
|
|
@ -418,13 +414,13 @@ contains
|
|||
! Read and set number of OpenMP threads
|
||||
n_threads = int(str_to_int(argv(i)), 4)
|
||||
if (n_threads < 1) then
|
||||
message = "Invalid number of threads specified on command line."
|
||||
call fatal_error()
|
||||
call fatal_error("Invalid number of threads specified on command &
|
||||
&line.")
|
||||
end if
|
||||
call omp_set_num_threads(n_threads)
|
||||
#else
|
||||
message = "Ignoring number of threads specified on command line."
|
||||
call warning()
|
||||
if (master) call warning("Ignoring number of threads specified on &
|
||||
&command line.")
|
||||
#endif
|
||||
|
||||
case ('-?', '-h', '-help', '--help')
|
||||
|
|
@ -440,8 +436,7 @@ contains
|
|||
write_all_tracks = .true.
|
||||
i = i + 1
|
||||
case default
|
||||
message = "Unknown command line option: " // argv(i)
|
||||
call fatal_error()
|
||||
call fatal_error("Unknown command line option: " // argv(i))
|
||||
end select
|
||||
|
||||
last_flag = i
|
||||
|
|
@ -577,9 +572,8 @@ contains
|
|||
i_array = surface_dict % get_key(abs(id))
|
||||
c % surfaces(j) = sign(i_array, id)
|
||||
else
|
||||
message = "Could not find surface " // trim(to_str(abs(id))) // &
|
||||
" specified on cell " // trim(to_str(c % id))
|
||||
call fatal_error()
|
||||
call fatal_error("Could not find surface " // trim(to_str(abs(id)))&
|
||||
&// " specified on cell " // trim(to_str(c % id)))
|
||||
end if
|
||||
end if
|
||||
end do
|
||||
|
|
@ -591,9 +585,8 @@ contains
|
|||
if (universe_dict % has_key(id)) then
|
||||
c % universe = universe_dict % get_key(id)
|
||||
else
|
||||
message = "Could not find universe " // trim(to_str(id)) // &
|
||||
" specified on cell " // trim(to_str(c % id))
|
||||
call fatal_error()
|
||||
call fatal_error("Could not find universe " // trim(to_str(id)) &
|
||||
&// " specified on cell " // trim(to_str(c % id)))
|
||||
end if
|
||||
|
||||
! =======================================================================
|
||||
|
|
@ -607,9 +600,8 @@ contains
|
|||
c % type = CELL_NORMAL
|
||||
c % material = material_dict % get_key(id)
|
||||
else
|
||||
message = "Could not find material " // trim(to_str(id)) // &
|
||||
" specified on cell " // trim(to_str(c % id))
|
||||
call fatal_error()
|
||||
call fatal_error("Could not find material " // trim(to_str(id)) &
|
||||
&// " specified on cell " // trim(to_str(c % id)))
|
||||
end if
|
||||
else
|
||||
id = c % fill
|
||||
|
|
@ -626,15 +618,14 @@ contains
|
|||
else if (material_dict % has_key(mid)) then
|
||||
c % material = material_dict % get_key(mid)
|
||||
else
|
||||
message = "Could not find material " // trim(to_str(mid)) // &
|
||||
" specified on lattice " // trim(to_str(lid))
|
||||
call fatal_error()
|
||||
call fatal_error("Could not find material " // trim(to_str(mid)) &
|
||||
&// " specified on lattice " // trim(to_str(lid)))
|
||||
end if
|
||||
|
||||
else
|
||||
message = "Specified fill " // trim(to_str(id)) // " on cell " // &
|
||||
trim(to_str(c % id)) // " is neither a universe nor a lattice."
|
||||
call fatal_error()
|
||||
call fatal_error("Specified fill " // trim(to_str(id)) // " on cell "&
|
||||
&// trim(to_str(c % id)) // " is neither a universe nor a &
|
||||
&lattice.")
|
||||
end if
|
||||
end if
|
||||
end do
|
||||
|
|
@ -659,9 +650,8 @@ contains
|
|||
if (universe_dict % has_key(id)) then
|
||||
lat % universes(j,k,m) = universe_dict % get_key(id)
|
||||
else
|
||||
message = "Invalid universe number " // trim(to_str(id)) &
|
||||
// " specified on lattice " // trim(to_str(lat % id))
|
||||
call fatal_error()
|
||||
call fatal_error("Invalid universe number " // trim(to_str(id)) &
|
||||
&// " specified on lattice " // trim(to_str(lat % id)))
|
||||
end if
|
||||
end do
|
||||
end do
|
||||
|
|
@ -685,9 +675,8 @@ contains
|
|||
if (cell_dict % has_key(id)) then
|
||||
t % filters(j) % int_bins(k) = cell_dict % get_key(id)
|
||||
else
|
||||
message = "Could not find cell " // trim(to_str(id)) // &
|
||||
" specified on tally " // trim(to_str(t % id))
|
||||
call fatal_error()
|
||||
call fatal_error("Could not find cell " // trim(to_str(id)) &
|
||||
&// " specified on tally " // trim(to_str(t % id)))
|
||||
end if
|
||||
end do
|
||||
|
||||
|
|
@ -701,9 +690,8 @@ contains
|
|||
if (surface_dict % has_key(id)) then
|
||||
t % filters(j) % int_bins(k) = surface_dict % get_key(id)
|
||||
else
|
||||
message = "Could not find surface " // trim(to_str(id)) // &
|
||||
" specified on tally " // trim(to_str(t % id))
|
||||
call fatal_error()
|
||||
call fatal_error("Could not find surface " // trim(to_str(id)) &
|
||||
&// " specified on tally " // trim(to_str(t % id)))
|
||||
end if
|
||||
end do
|
||||
|
||||
|
|
@ -714,9 +702,8 @@ contains
|
|||
if (universe_dict % has_key(id)) then
|
||||
t % filters(j) % int_bins(k) = universe_dict % get_key(id)
|
||||
else
|
||||
message = "Could not find universe " // trim(to_str(id)) // &
|
||||
" specified on tally " // trim(to_str(t % id))
|
||||
call fatal_error()
|
||||
call fatal_error("Could not find universe " // trim(to_str(id)) &
|
||||
&// " specified on tally " // trim(to_str(t % id)))
|
||||
end if
|
||||
end do
|
||||
|
||||
|
|
@ -727,9 +714,8 @@ contains
|
|||
if (material_dict % has_key(id)) then
|
||||
t % filters(j) % int_bins(k) = material_dict % get_key(id)
|
||||
else
|
||||
message = "Could not find material " // trim(to_str(id)) // &
|
||||
" specified on tally " // trim(to_str(t % id))
|
||||
call fatal_error()
|
||||
call fatal_error("Could not find material " // trim(to_str(id)) &
|
||||
&// " specified on tally " // trim(to_str(t % id)))
|
||||
end if
|
||||
end do
|
||||
|
||||
|
|
@ -864,8 +850,7 @@ contains
|
|||
|
||||
! Check for allocation errors
|
||||
if (alloc_err /= 0) then
|
||||
message = "Failed to allocate source bank."
|
||||
call fatal_error()
|
||||
call fatal_error("Failed to allocate source bank.")
|
||||
end if
|
||||
|
||||
#ifdef _OPENMP
|
||||
|
|
@ -892,8 +877,7 @@ contains
|
|||
|
||||
! Check for allocation errors
|
||||
if (alloc_err /= 0) then
|
||||
message = "Failed to allocate fission bank."
|
||||
call fatal_error()
|
||||
call fatal_error("Failed to allocate fission bank.")
|
||||
end if
|
||||
|
||||
end subroutine allocate_banks
|
||||
|
|
|
|||
1063
src/input_xml.F90
1063
src/input_xml.F90
File diff suppressed because it is too large
Load diff
|
|
@ -3,7 +3,6 @@ module interpolation
|
|||
use constants
|
||||
use endf_header, only: Tab1
|
||||
use error, only: fatal_error
|
||||
use global, only: message
|
||||
use search, only: binary_search
|
||||
use string, only: to_str
|
||||
|
||||
|
|
@ -118,8 +117,7 @@ contains
|
|||
r = (log(x) - log(x0))/(log(x1) - log(x0))
|
||||
y = exp((1-r)*log(y0) + r*log(y1))
|
||||
case default
|
||||
message = "Unsupported interpolation scheme: " // to_str(interp)
|
||||
call fatal_error()
|
||||
call fatal_error("Unsupported interpolation scheme: " // to_str(interp))
|
||||
end select
|
||||
|
||||
end function interpolate_tab1_array
|
||||
|
|
@ -204,8 +202,7 @@ contains
|
|||
r = (log(x) - log(x0))/(log(x1) - log(x0))
|
||||
y = exp((1-r)*log(y0) + r*log(y1))
|
||||
case default
|
||||
message = "Unsupported interpolation scheme: " // to_str(interp)
|
||||
call fatal_error()
|
||||
call fatal_error("Unsupported interpolation scheme: " // to_str(interp))
|
||||
end select
|
||||
|
||||
end function interpolate_tab1_object
|
||||
|
|
|
|||
|
|
@ -20,19 +20,22 @@ module matrix_header
|
|||
# endif
|
||||
logical :: petsc_active
|
||||
contains
|
||||
procedure :: create => matrix_create
|
||||
procedure :: destroy => matrix_destroy
|
||||
procedure :: add_value => matrix_add_value
|
||||
procedure :: new_row => matrix_new_row
|
||||
procedure :: assemble => matrix_assemble
|
||||
procedure :: get_row => matrix_get_row
|
||||
procedure :: get_col => matrix_get_col
|
||||
procedure :: create => matrix_create
|
||||
procedure :: destroy => matrix_destroy
|
||||
procedure :: add_value => matrix_add_value
|
||||
procedure :: new_row => matrix_new_row
|
||||
procedure :: assemble => matrix_assemble
|
||||
procedure :: get_row => matrix_get_row
|
||||
procedure :: get_col => matrix_get_col
|
||||
procedure :: vector_multiply => matrix_vector_multiply
|
||||
#ifdef PETSC
|
||||
procedure :: transpose => matrix_transpose
|
||||
procedure :: search_indices => matrix_search_indices
|
||||
procedure :: write => matrix_write
|
||||
procedure :: copy => matrix_copy
|
||||
# ifdef PETSC
|
||||
procedure :: setup_petsc => matrix_setup_petsc
|
||||
procedure :: write_petsc_binary => matrix_write_petsc_binary
|
||||
#endif
|
||||
procedure :: transpose => matrix_transpose
|
||||
# endif
|
||||
end type matrix
|
||||
|
||||
#ifdef PETSC
|
||||
|
|
@ -359,4 +362,87 @@ contains
|
|||
|
||||
end subroutine matrix_vector_multiply
|
||||
|
||||
!===============================================================================
|
||||
! MATRIX_SEARCH_INDICES searches for an index in column corresponding to a row
|
||||
!===============================================================================
|
||||
|
||||
subroutine matrix_search_indices(self, row, col, idx, found)
|
||||
|
||||
class(Matrix), intent(inout) :: self
|
||||
integer, intent(in) :: row
|
||||
integer, intent(in) :: col
|
||||
integer, intent(out) :: idx
|
||||
logical, intent(out) :: found
|
||||
|
||||
integer :: j
|
||||
|
||||
found = .false.
|
||||
|
||||
COLS: do j = self % get_row(row), self % get_row(row + 1) - 1
|
||||
|
||||
if (self % get_col(j) == col) then
|
||||
idx = j
|
||||
found = .true.
|
||||
exit
|
||||
end if
|
||||
|
||||
end do COLS
|
||||
|
||||
end subroutine matrix_search_indices
|
||||
|
||||
!===============================================================================
|
||||
! MATRIX_WRITE writes a matrix to file
|
||||
!===============================================================================
|
||||
|
||||
subroutine matrix_write(self, filename)
|
||||
|
||||
character(*), intent(in) :: filename
|
||||
class(Matrix), intent(inout) :: self
|
||||
|
||||
integer :: unit_
|
||||
integer :: i
|
||||
integer :: j
|
||||
|
||||
open(newunit=unit_, file=filename)
|
||||
|
||||
do i = 1, self % n
|
||||
do j = self % get_row(i), self % get_row(i + 1) - 1
|
||||
write(unit_,*) i, self % get_col(j), self % val(j)
|
||||
end do
|
||||
end do
|
||||
|
||||
close(unit_)
|
||||
|
||||
end subroutine matrix_write
|
||||
|
||||
!===============================================================================
|
||||
! MATRIX_COPY copies a matrix
|
||||
!===============================================================================
|
||||
|
||||
subroutine matrix_copy(self, mattocopy)
|
||||
|
||||
class(Matrix), intent(inout) :: self
|
||||
type(Matrix), intent(in) :: mattocopy
|
||||
|
||||
! Set n and nnz
|
||||
self % n_count = mattocopy % n_count
|
||||
self % nz_count = mattocopy % nz_count
|
||||
self % n = mattocopy % n
|
||||
self % nnz = mattocopy % nnz
|
||||
|
||||
! Allocate vectors
|
||||
if (.not.allocated(self % row)) allocate(self % row(self % n + 1))
|
||||
if (.not.allocated(self % col)) allocate(self % col(self % nnz))
|
||||
if (.not.allocated(self % val)) allocate(self % val(self % nnz))
|
||||
|
||||
! Set PETSc active to false
|
||||
self % petsc_active = .false.
|
||||
|
||||
! Copy over data
|
||||
self % row = mattocopy % row
|
||||
self % col = mattocopy % col
|
||||
self % val = mattocopy % val
|
||||
|
||||
end subroutine matrix_copy
|
||||
|
||||
end module matrix_header
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ module output
|
|||
use mesh, only: mesh_indices_to_bin, bin_to_mesh_indices
|
||||
use particle_header, only: LocalCoord, Particle
|
||||
use plot_header
|
||||
use string, only: upper_case, to_str
|
||||
use string, only: to_upper, to_str
|
||||
use tally_header, only: TallyObject
|
||||
|
||||
implicit none
|
||||
|
|
@ -130,8 +130,7 @@ contains
|
|||
if (mod(len_trim(msg),2) == 0) m = m + 1
|
||||
|
||||
! convert line to upper case
|
||||
line = msg
|
||||
call upper_case(line)
|
||||
line = to_upper(msg)
|
||||
|
||||
! print header based on level
|
||||
select case (header_level)
|
||||
|
|
@ -194,8 +193,9 @@ contains
|
|||
! standard output stream.
|
||||
!===============================================================================
|
||||
|
||||
subroutine write_message(level)
|
||||
subroutine write_message(message, level)
|
||||
|
||||
character(*) :: message
|
||||
integer, optional :: level ! verbosity level
|
||||
|
||||
integer :: i_start ! starting position
|
||||
|
|
@ -1588,8 +1588,8 @@ contains
|
|||
write(ou,102) "Leakage Fraction", global_tallies(LEAKAGE) % sum, &
|
||||
global_tallies(LEAKAGE) % sum_sq
|
||||
else
|
||||
message = "Could not compute uncertainties -- only one active batch simulated!"
|
||||
call warning()
|
||||
if (master) call warning("Could not compute uncertainties -- only one &
|
||||
&active batch simulated!")
|
||||
|
||||
write(ou,103) "k-effective (Collision)", global_tallies(K_COLLISION) % sum
|
||||
write(ou,103) "k-effective (Track-length)", global_tallies(K_TRACKLENGTH) % sum
|
||||
|
|
|
|||
|
|
@ -16,8 +16,7 @@ module particle_restart
|
|||
private
|
||||
public :: run_particle_restart
|
||||
|
||||
! Binary file
|
||||
type(BinaryOutput) :: pr
|
||||
type(BinaryOutput) :: pr ! Binary file
|
||||
|
||||
contains
|
||||
|
||||
|
|
@ -73,9 +72,8 @@ contains
|
|||
type(Particle), intent(inout) :: p
|
||||
|
||||
! Write meessage
|
||||
message = "Loading particle restart file " // trim(path_particle_restart) &
|
||||
// "..."
|
||||
call write_message(1)
|
||||
call write_message("Loading particle restart file " &
|
||||
&// trim(path_particle_restart) // "...", 1)
|
||||
|
||||
! Open file
|
||||
call pr % file_open(path_particle_restart, 'r')
|
||||
|
|
|
|||
119
src/physics.F90
119
src/physics.F90
|
|
@ -47,17 +47,15 @@ contains
|
|||
|
||||
! Display information about collision
|
||||
if (verbosity >= 10 .or. trace) then
|
||||
message = " " // trim(reaction_name(p % event_MT)) // " with " // &
|
||||
trim(adjustl(nuclides(p % event_nuclide) % name)) // &
|
||||
". Energy = " // trim(to_str(p % E * 1e6_8)) // " eV."
|
||||
call write_message()
|
||||
call write_message(" " // trim(reaction_name(p % event_MT)) &
|
||||
&// " with " // trim(adjustl(nuclides(p % event_nuclide) % name)) &
|
||||
&// ". Energy = " // trim(to_str(p % E * 1e6_8)) // " eV.")
|
||||
end if
|
||||
|
||||
! check for very low energy
|
||||
if (p % E < 1.0e-100_8) then
|
||||
p % alive = .false.
|
||||
message = "Killing neutron with extremely low energy"
|
||||
call warning()
|
||||
if (master) call warning("Killing neutron with extremely low energy")
|
||||
end if
|
||||
|
||||
end subroutine collision
|
||||
|
|
@ -159,8 +157,7 @@ contains
|
|||
! Check to make sure that a nuclide was sampled
|
||||
if (i > mat % n_nuclides) then
|
||||
call write_particle_restart(p)
|
||||
message = "Did not sample any nuclide during collision."
|
||||
call fatal_error()
|
||||
call fatal_error("Did not sample any nuclide during collision.")
|
||||
end if
|
||||
|
||||
! Find atom density
|
||||
|
|
@ -368,9 +365,8 @@ contains
|
|||
! Check to make sure inelastic scattering reaction sampled
|
||||
if (i > nuc % n_reaction) then
|
||||
call write_particle_restart(p)
|
||||
message = "Did not sample any reaction for nuclide " // &
|
||||
trim(nuc % name)
|
||||
call fatal_error()
|
||||
call fatal_error("Did not sample any reaction for nuclide " &
|
||||
&// trim(nuc % name))
|
||||
end if
|
||||
|
||||
rxn => nuc % reactions(i)
|
||||
|
|
@ -721,8 +717,8 @@ contains
|
|||
mu = sab % inelastic_data(l) % mu(k, j)
|
||||
|
||||
else
|
||||
message = "Invalid secondary energy mode on S(a,b) table " // &
|
||||
trim(sab % name)
|
||||
call fatal_error("Invalid secondary energy mode on S(a,b) table " &
|
||||
&// trim(sab % name))
|
||||
end if ! (inelastic secondary energy treatment)
|
||||
end if ! (elastic or inelastic)
|
||||
|
||||
|
|
@ -974,8 +970,7 @@ contains
|
|||
end do
|
||||
|
||||
case default
|
||||
message = "Not a recognized resonance scattering treatment!"
|
||||
call fatal_error()
|
||||
call fatal_error("Not a recognized resonance scattering treatment!")
|
||||
end select
|
||||
|
||||
end subroutine sample_target_velocity
|
||||
|
|
@ -1093,8 +1088,7 @@ contains
|
|||
call get_mesh_indices(ufs_mesh, p % coord0 % xyz, ijk, in_mesh)
|
||||
if (.not. in_mesh) then
|
||||
call write_particle_restart(p)
|
||||
message = "Source site outside UFS mesh!"
|
||||
call fatal_error()
|
||||
call fatal_error("Source site outside UFS mesh!")
|
||||
end if
|
||||
|
||||
if (source_frac(1,ijk(1),ijk(2),ijk(3)) /= ZERO) then
|
||||
|
|
@ -1119,10 +1113,9 @@ contains
|
|||
|
||||
! Check for fission bank size getting hit
|
||||
if (n_bank + nu > size(fission_bank)) then
|
||||
message = "Maximum number of sites in fission bank reached. This can &
|
||||
&result in irreproducible results using different numbers of &
|
||||
&processes/threads."
|
||||
call warning()
|
||||
if (master) call warning("Maximum number of sites in fission bank &
|
||||
&reached. This can result in irreproducible results using different &
|
||||
&numbers of processes/threads.")
|
||||
end if
|
||||
|
||||
! Bank source neutrons
|
||||
|
|
@ -1247,9 +1240,8 @@ contains
|
|||
n_sample = n_sample + 1
|
||||
if (n_sample == MAX_SAMPLE) then
|
||||
! call write_particle_restart(p)
|
||||
message = "Resampled energy distribution maximum number of " // &
|
||||
"times for nuclide " // nuc % name
|
||||
call fatal_error()
|
||||
call fatal_error("Resampled energy distribution maximum number of " &
|
||||
&// "times for nuclide " // nuc % name)
|
||||
end if
|
||||
end do
|
||||
|
||||
|
|
@ -1274,9 +1266,8 @@ contains
|
|||
n_sample = n_sample + 1
|
||||
if (n_sample == MAX_SAMPLE) then
|
||||
! call write_particle_restart(p)
|
||||
message = "Resampled energy distribution maximum number of " // &
|
||||
"times for nuclide " // nuc % name
|
||||
call fatal_error()
|
||||
call fatal_error("Resampled energy distribution maximum number of " &
|
||||
&// "times for nuclide " // nuc % name)
|
||||
end if
|
||||
end do
|
||||
|
||||
|
|
@ -1457,8 +1448,7 @@ contains
|
|||
end if
|
||||
else
|
||||
! call write_particle_restart(p)
|
||||
message = "Unknown interpolation type: " // trim(to_str(interp))
|
||||
call fatal_error()
|
||||
call fatal_error("Unknown interpolation type: " // trim(to_str(interp)))
|
||||
end if
|
||||
|
||||
! Because of floating-point roundoff, it may be possible for mu to be
|
||||
|
|
@ -1469,8 +1459,8 @@ contains
|
|||
|
||||
else
|
||||
! call write_particle_restart(p)
|
||||
message = "Unknown angular distribution type: " // trim(to_str(type))
|
||||
call fatal_error()
|
||||
call fatal_error("Unknown angular distribution type: " &
|
||||
&// trim(to_str(type)))
|
||||
end if
|
||||
|
||||
end function sample_angle
|
||||
|
|
@ -1617,9 +1607,8 @@ contains
|
|||
NET = int(edist % data(3 + 2*NR + NE))
|
||||
if (NR > 0) then
|
||||
! call write_particle_restart(p)
|
||||
message = "Multiple interpolation regions not supported while &
|
||||
&attempting to sample equiprobable energy bins."
|
||||
call fatal_error()
|
||||
call fatal_error("Multiple interpolation regions not supported while &
|
||||
&attempting to sample equiprobable energy bins.")
|
||||
end if
|
||||
|
||||
! determine index on incoming energy grid and interpolation factor
|
||||
|
|
@ -1682,14 +1671,12 @@ contains
|
|||
NR = int(edist % data(1))
|
||||
NE = int(edist % data(2 + 2*NR))
|
||||
if (NR == 1) then
|
||||
message = "Assuming linear-linear interpolation when sampling &
|
||||
&continuous tabular distribution"
|
||||
call warning()
|
||||
if (master) call warning("Assuming linear-linear interpolation when &
|
||||
&sampling continuous tabular distribution")
|
||||
else if (NR > 1) then
|
||||
! call write_particle_restart(p)
|
||||
message = "Multiple interpolation regions not supported while &
|
||||
&attempting to sample continuous tabular distribution."
|
||||
call fatal_error()
|
||||
call fatal_error("Multiple interpolation regions not supported while &
|
||||
&attempting to sample continuous tabular distribution.")
|
||||
end if
|
||||
|
||||
! find energy bin and calculate interpolation factor -- if the energy is
|
||||
|
|
@ -1747,9 +1734,8 @@ contains
|
|||
if (ND > 0) then
|
||||
! discrete lines present
|
||||
! call write_particle_restart(p)
|
||||
message = "Discrete lines in continuous tabular distributed not &
|
||||
&yet supported"
|
||||
call fatal_error()
|
||||
call fatal_error("Discrete lines in continuous tabular distributed not &
|
||||
&yet supported")
|
||||
end if
|
||||
|
||||
! determine outgoing energy bin
|
||||
|
|
@ -1789,8 +1775,7 @@ contains
|
|||
end if
|
||||
else
|
||||
! call write_particle_restart(p)
|
||||
message = "Unknown interpolation type: " // trim(to_str(INTT))
|
||||
call fatal_error()
|
||||
call fatal_error("Unknown interpolation type: " // trim(to_str(INTT)))
|
||||
end if
|
||||
|
||||
! Now interpolate between incident energy bins i and i + 1
|
||||
|
|
@ -1831,8 +1816,7 @@ contains
|
|||
n_sample = n_sample + 1
|
||||
if (n_sample == MAX_SAMPLE) then
|
||||
! call write_particle_restart(p)
|
||||
message = "Too many rejections on Maxwell fission spectrum."
|
||||
call fatal_error()
|
||||
call fatal_error("Too many rejections on Maxwell fission spectrum.")
|
||||
end if
|
||||
end do
|
||||
|
||||
|
|
@ -1864,8 +1848,7 @@ contains
|
|||
n_sample = n_sample + 1
|
||||
if (n_sample == MAX_SAMPLE) then
|
||||
! call write_particle_restart(p)
|
||||
message = "Too many rejections on evaporation spectrum."
|
||||
call fatal_error()
|
||||
call fatal_error("Too many rejections on evaporation spectrum.")
|
||||
end if
|
||||
end do
|
||||
|
||||
|
|
@ -1906,8 +1889,7 @@ contains
|
|||
n_sample = n_sample + 1
|
||||
if (n_sample == MAX_SAMPLE) then
|
||||
! call write_particle_restart(p)
|
||||
message = "Too many rejections on Watt spectrum."
|
||||
call fatal_error()
|
||||
call fatal_error("Too many rejections on Watt spectrum.")
|
||||
end if
|
||||
end do
|
||||
|
||||
|
|
@ -1917,8 +1899,7 @@ contains
|
|||
|
||||
if (.not. present(mu_out)) then
|
||||
! call write_particle_restart(p)
|
||||
message = "Law 44 called without giving mu_out as argument."
|
||||
call fatal_error()
|
||||
call fatal_error("Law 44 called without giving mu_out as argument.")
|
||||
end if
|
||||
|
||||
! read number of interpolation regions and incoming energies
|
||||
|
|
@ -1926,9 +1907,8 @@ contains
|
|||
NE = int(edist % data(2 + 2*NR))
|
||||
if (NR > 0) then
|
||||
! call write_particle_restart(p)
|
||||
message = "Multiple interpolation regions not supported while &
|
||||
&attempting to sample Kalbach-Mann distribution."
|
||||
call fatal_error()
|
||||
call fatal_error("Multiple interpolation regions not supported while &
|
||||
&attempting to sample Kalbach-Mann distribution.")
|
||||
end if
|
||||
|
||||
! find energy bin and calculate interpolation factor -- if the energy is
|
||||
|
|
@ -1987,9 +1967,8 @@ contains
|
|||
if (ND > 0) then
|
||||
! discrete lines present
|
||||
! call write_particle_restart(p)
|
||||
message = "Discrete lines in continuous tabular distributed not &
|
||||
&yet supported"
|
||||
call fatal_error()
|
||||
call fatal_error("Discrete lines in continuous tabular distributed not &
|
||||
&yet supported")
|
||||
end if
|
||||
|
||||
! determine outgoing energy bin
|
||||
|
|
@ -2043,8 +2022,7 @@ contains
|
|||
KM_A = A_k + (A_k1 - A_k)*(E_out - E_l_k)/(E_l_k1 - E_l_k)
|
||||
else
|
||||
! call write_particle_restart()
|
||||
message = "Unknown interpolation type: " // trim(to_str(INTT))
|
||||
call fatal_error()
|
||||
call fatal_error("Unknown interpolation type: " // trim(to_str(INTT)))
|
||||
end if
|
||||
|
||||
! Now interpolate between incident energy bins i and i + 1
|
||||
|
|
@ -2070,8 +2048,7 @@ contains
|
|||
|
||||
if (.not. present(mu_out)) then
|
||||
! call write_particle_restart()
|
||||
message = "Law 61 called without giving mu_out as argument."
|
||||
call fatal_error()
|
||||
call fatal_error("Law 61 called without giving mu_out as argument.")
|
||||
end if
|
||||
|
||||
! read number of interpolation regions and incoming energies
|
||||
|
|
@ -2079,9 +2056,8 @@ contains
|
|||
NE = int(edist % data(2 + 2*NR))
|
||||
if (NR > 0) then
|
||||
! call write_particle_restart()
|
||||
message = "Multiple interpolation regions not supported while &
|
||||
&attempting to sample correlated energy-angle distribution."
|
||||
call fatal_error()
|
||||
call fatal_error("Multiple interpolation regions not supported while &
|
||||
&attempting to sample correlated energy-angle distribution.")
|
||||
end if
|
||||
|
||||
! find energy bin and calculate interpolation factor -- if the energy is
|
||||
|
|
@ -2140,9 +2116,8 @@ contains
|
|||
if (ND > 0) then
|
||||
! discrete lines present
|
||||
! call write_particle_restart()
|
||||
message = "Discrete lines in continuous tabular distributed not &
|
||||
&yet supported"
|
||||
call fatal_error()
|
||||
call fatal_error("Discrete lines in continuous tabular distributed not &
|
||||
&yet supported")
|
||||
end if
|
||||
|
||||
! determine outgoing energy bin
|
||||
|
|
@ -2183,8 +2158,7 @@ contains
|
|||
end if
|
||||
else
|
||||
! call write_particle_restart()
|
||||
message = "Unknown interpolation type: " // trim(to_str(INTT))
|
||||
call fatal_error()
|
||||
call fatal_error("Unknown interpolation type: " // trim(to_str(INTT)))
|
||||
end if
|
||||
|
||||
! Now interpolate between incident energy bins i and i + 1
|
||||
|
|
@ -2247,8 +2221,7 @@ contains
|
|||
end if
|
||||
else
|
||||
! call write_particle_restart()
|
||||
message = "Unknown interpolation type: " // trim(to_str(JJ))
|
||||
call fatal_error()
|
||||
call fatal_error("Unknown interpolation type: " // trim(to_str(JJ)))
|
||||
end if
|
||||
|
||||
case (66)
|
||||
|
|
|
|||
122
src/plot.F90
122
src/plot.F90
|
|
@ -5,6 +5,7 @@ module plot
|
|||
use geometry, only: find_cell, check_cell_overlap
|
||||
use geometry_header, only: Cell, BASE_UNIVERSE
|
||||
use global
|
||||
use mesh, only: get_mesh_indices
|
||||
use output, only: write_message
|
||||
use particle_header, only: deallocate_coord, Particle
|
||||
use plot_header
|
||||
|
|
@ -30,8 +31,8 @@ contains
|
|||
pl => plots(i)
|
||||
|
||||
! Display output message
|
||||
message = "Processing plot " // trim(to_str(pl % id)) // "..."
|
||||
call write_message(5)
|
||||
call write_message("Processing plot " // trim(to_str(pl % id)) &
|
||||
&// "...", 5)
|
||||
|
||||
if (pl % type == PLOT_TYPE_SLICE) then
|
||||
! create 2d image
|
||||
|
|
@ -118,27 +119,24 @@ contains
|
|||
call init_image(img)
|
||||
call allocate_image(img, pl % pixels(1), pl % pixels(2))
|
||||
|
||||
in_pixel = pl % width(1)/dble(pl % pixels(1))
|
||||
out_pixel = pl % width(2)/dble(pl % pixels(2))
|
||||
|
||||
if (pl % basis == PLOT_BASIS_XY) then
|
||||
in_i = 1
|
||||
out_i = 2
|
||||
in_pixel = pl % width(1)/dble(pl % pixels(1))
|
||||
out_pixel = pl % width(2)/dble(pl % pixels(2))
|
||||
xyz(1) = pl % origin(1) - pl % width(1) / 2.0
|
||||
xyz(2) = pl % origin(2) + pl % width(2) / 2.0
|
||||
xyz(3) = pl % origin(3)
|
||||
else if (pl % basis == PLOT_BASIS_XZ) then
|
||||
in_i = 1
|
||||
out_i = 3
|
||||
in_pixel = pl % width(1)/dble(pl % pixels(1))
|
||||
out_pixel = pl % width(2)/dble(pl % pixels(2))
|
||||
xyz(1) = pl % origin(1) - pl % width(1) / 2.0
|
||||
xyz(2) = pl % origin(2)
|
||||
xyz(3) = pl % origin(3) + pl % width(2) / 2.0
|
||||
else if (pl % basis == PLOT_BASIS_YZ) then
|
||||
in_i = 2
|
||||
out_i = 3
|
||||
in_pixel = pl % width(1)/dble(pl % pixels(1))
|
||||
out_pixel = pl % width(2)/dble(pl % pixels(2))
|
||||
xyz(1) = pl % origin(1)
|
||||
xyz(2) = pl % origin(2) - pl % width(1) / 2.0
|
||||
xyz(3) = pl % origin(3) + pl % width(2) / 2.0
|
||||
|
|
@ -169,6 +167,9 @@ contains
|
|||
p % coord0 % xyz(out_i) = p % coord0 % xyz(out_i) - out_pixel
|
||||
end do
|
||||
|
||||
! Draw tally mesh boundaries on the image if requested
|
||||
if (associated(pl % meshlines_mesh)) call draw_mesh_lines(pl, img)
|
||||
|
||||
! Write out the ppm to a file
|
||||
call output_ppm(pl,img)
|
||||
|
||||
|
|
@ -180,6 +181,111 @@ contains
|
|||
|
||||
end subroutine create_ppm
|
||||
|
||||
!===============================================================================
|
||||
! DRAW_MESH_LINES draws mesh line boundaries on an image
|
||||
!===============================================================================
|
||||
subroutine draw_mesh_lines(pl, img)
|
||||
|
||||
type(ObjectPlot), pointer, intent(in) :: pl
|
||||
type(Image), intent(inout) :: img
|
||||
|
||||
logical :: in_mesh
|
||||
integer :: out_, in_ ! pixel location
|
||||
integer :: r, g, b ! RGB color for meshlines pixels
|
||||
integer :: outrange(2), inrange(2) ! range of pixel locations
|
||||
integer :: i, j ! loop indices
|
||||
integer :: plus
|
||||
integer :: ijk_ll(3) ! mesh bin ijk indicies of plot lower left
|
||||
integer :: ijk_ur(3) ! mesh bin ijk indicies of plot upper right
|
||||
integer :: outer, inner
|
||||
real(8) :: frac
|
||||
real(8) :: width(3) ! real widths of the plot
|
||||
real(8) :: xyz_ll_plot(3) ! lower left xyz of plot image
|
||||
real(8) :: xyz_ur_plot(3) ! upper right xyz of plot image
|
||||
real(8) :: xyz_ll(3) ! lower left xyz
|
||||
real(8) :: xyz_ur(3) ! upper right xyz
|
||||
type(StructuredMesh), pointer :: m => null()
|
||||
|
||||
m => pl % meshlines_mesh
|
||||
|
||||
r = pl % meshlines_color % rgb(1)
|
||||
g = pl % meshlines_color % rgb(2)
|
||||
b = pl % meshlines_color % rgb(3)
|
||||
|
||||
select case (pl % basis)
|
||||
case(PLOT_BASIS_XY)
|
||||
outer = 1
|
||||
inner = 2
|
||||
case(PLOT_BASIS_XZ)
|
||||
outer = 1
|
||||
inner = 3
|
||||
case(PLOT_BASIS_YZ)
|
||||
outer = 2
|
||||
inner = 3
|
||||
end select
|
||||
|
||||
xyz_ll_plot = pl % origin
|
||||
xyz_ur_plot = pl % origin
|
||||
|
||||
xyz_ll_plot(outer) = pl % origin(1) - pl % width(1) / 2.0
|
||||
xyz_ll_plot(inner) = pl % origin(2) - pl % width(2) / 2.0
|
||||
xyz_ur_plot(outer) = pl % origin(1) + pl % width(1) / 2.0
|
||||
xyz_ur_plot(inner) = pl % origin(2) + pl % width(2) / 2.0
|
||||
|
||||
width = xyz_ur_plot - xyz_ll_plot
|
||||
|
||||
call get_mesh_indices(m, xyz_ll_plot, ijk_ll(:m % n_dimension), in_mesh)
|
||||
call get_mesh_indices(m, xyz_ur_plot, ijk_ur(:m % n_dimension), in_mesh)
|
||||
|
||||
! sweep through all meshbins on this plane and draw borders
|
||||
do i = ijk_ll(outer), ijk_ur(outer)
|
||||
do j = ijk_ll(inner), ijk_ur(inner)
|
||||
! check if we're in the mesh for this ijk
|
||||
if (i > 0 .and. i <= m % dimension(outer) .and. &
|
||||
j > 0 .and. j <= m % dimension(inner)) then
|
||||
|
||||
! get xyz's of lower left and upper right of this mesh cell
|
||||
xyz_ll(outer) = m % lower_left(outer) + m % width(outer) * (i - 1)
|
||||
xyz_ll(inner) = m % lower_left(inner) + m % width(inner) * (j - 1)
|
||||
xyz_ur(outer) = m % lower_left(outer) + m % width(outer) * i
|
||||
xyz_ur(inner) = m % lower_left(inner) + m % width(inner) * j
|
||||
|
||||
! map the xyz ranges to pixel ranges
|
||||
|
||||
frac = (xyz_ll(outer) - xyz_ll_plot(outer)) / width(outer)
|
||||
outrange(1) = int(frac * real(img % width, 8))
|
||||
frac = (xyz_ur(outer) - xyz_ll_plot(outer)) / width(outer)
|
||||
outrange(2) = int(frac * real(img % width, 8))
|
||||
|
||||
frac = (xyz_ll(inner) - xyz_ll_plot(inner)) / width(inner)
|
||||
inrange(1) = int(frac * real(img % height, 8))
|
||||
frac = (xyz_ur(inner) - xyz_ll_plot(inner)) / width(inner)
|
||||
inrange(2) = int(frac * real(img % height, 8))
|
||||
|
||||
! draw lines
|
||||
do out_ = outrange(1), outrange(2)
|
||||
do plus = 0, pl % meshlines_width
|
||||
call set_pixel(img, out_, inrange(1) + plus, r, g, b)
|
||||
call set_pixel(img, out_, inrange(2) + plus, r, g, b)
|
||||
call set_pixel(img, out_, inrange(1) - plus, r, g, b)
|
||||
call set_pixel(img, out_, inrange(2) - plus, r, g, b)
|
||||
end do
|
||||
end do
|
||||
do in_ = inrange(1), inrange(2)
|
||||
do plus = 0, pl % meshlines_width
|
||||
call set_pixel(img, outrange(1) + plus, in_, r, g, b)
|
||||
call set_pixel(img, outrange(2) + plus, in_, r, g, b)
|
||||
call set_pixel(img, outrange(1) - plus, in_, r, g, b)
|
||||
call set_pixel(img, outrange(2) - plus, in_, r, g, b)
|
||||
end do
|
||||
end do
|
||||
|
||||
end if
|
||||
end do
|
||||
end do
|
||||
|
||||
end subroutine draw_mesh_lines
|
||||
|
||||
!===============================================================================
|
||||
! OUTPUT_PPM writes out a previously generated image to a PPM file
|
||||
!===============================================================================
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
module plot_header
|
||||
|
||||
use constants
|
||||
use mesh_header, only: StructuredMesh
|
||||
|
||||
implicit none
|
||||
|
||||
|
|
@ -25,6 +26,9 @@ module plot_header
|
|||
real(8) :: width(3) ! xyz widths of plot
|
||||
integer :: basis ! direction of plot slice
|
||||
integer :: pixels(3) ! pixel width/height of plot slice
|
||||
integer :: meshlines_width ! pixel width of meshlines
|
||||
type(StructuredMesh), pointer :: meshlines_mesh => null() ! mesh to plot
|
||||
type(ObjectColor) :: meshlines_color ! Color for meshlines
|
||||
type(ObjectColor) :: not_found ! color for positions where no cell found
|
||||
type(ObjectColor), allocatable :: colors(:) ! colors of cells/mats
|
||||
end type ObjectPlot
|
||||
|
|
|
|||
|
|
@ -22,15 +22,9 @@ element cmfd {
|
|||
|
||||
element feedback { xsd:boolean }? &
|
||||
|
||||
element n_cmfd_procs { xsd:int }? &
|
||||
|
||||
element reset { xsd:boolean }? &
|
||||
|
||||
element balance { xsd:boolean }? &
|
||||
|
||||
element downscatter { xsd:boolean }? &
|
||||
|
||||
element run_2grp { xsd:boolean }? &
|
||||
element dhat_reset { xsd:boolean }? &
|
||||
|
||||
element solver { xsd:string }? &
|
||||
|
||||
|
|
@ -40,8 +34,6 @@ element cmfd {
|
|||
|
||||
element power_monitor { xsd:boolean }? &
|
||||
|
||||
element write_balance { xsd:boolean }? &
|
||||
|
||||
element write_matrices { xsd:boolean }? &
|
||||
|
||||
element run_adjoint { xsd:boolean }? &
|
||||
|
|
@ -50,9 +42,18 @@ element cmfd {
|
|||
|
||||
element begin { xsd:int }? &
|
||||
|
||||
element inactive { xsd:boolean }? &
|
||||
element tally_reset { list { xsd:int+ } }? &
|
||||
|
||||
element active_flush { xsd:int }? &
|
||||
element display { xsd:string }? &
|
||||
|
||||
element spectral { xsd:double }? &
|
||||
|
||||
element shift { xsd:double }? &
|
||||
|
||||
element ktol { xsd: double }? &
|
||||
|
||||
element stol { xsd: double }? &
|
||||
|
||||
element gauss_seidel_tolerance { list { xsd:double+ } }?
|
||||
|
||||
element keff_tol { xsd:double }?
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,29 +3,38 @@ element plots {
|
|||
(element id { xsd:int } | attribute id { xsd:int })? &
|
||||
(element filename { xsd:string { maxLength = "50" } } |
|
||||
attribute filename { xsd:string { maxLength = "50" } })? &
|
||||
(element type { "slice" } | attribute type { "slice" })? &
|
||||
(element type { "slice" | "voxel" } |
|
||||
attribute type { "slice" | "voxel" })? &
|
||||
(element color { ( "cell" | "mat" | "material" ) } |
|
||||
attribute color { ( "cell" | "mat" | "material" ) })? &
|
||||
(element origin { list { xsd:double+ } } |
|
||||
(element origin { list { xsd:double+ } } |
|
||||
attribute origin { list { xsd:double+ } })? &
|
||||
(element width { list { xsd:double+ } } |
|
||||
(element width { list { xsd:double+ } } |
|
||||
attribute width { list { xsd:double+ } })? &
|
||||
(element basis { ( "xy" | "yz" | "xz" ) } |
|
||||
attribute basis { ( "xy" | "yz" | "xz" ) })? &
|
||||
(element pixels { list { xsd:int+ } } |
|
||||
(element pixels { list { xsd:int+ } } |
|
||||
attribute pixels { list { xsd:int+ } })? &
|
||||
(element background { list { xsd:int+ } } |
|
||||
attribute background { list { xsd:int+ } })? &
|
||||
element col_spec {
|
||||
(element id { xsd:int } | attribute id { xsd:int }) &
|
||||
(element rgb { list { xsd:int+ } } |
|
||||
(element rgb { list { xsd:int+ } } |
|
||||
attribute rgb { list { xsd:int+ } })
|
||||
}* &
|
||||
element mask {
|
||||
(element components { list { xsd:int+ } } |
|
||||
(element components { list { xsd:int+ } } |
|
||||
attribute components { list { xsd:int+ } }) &
|
||||
(element background { list { xsd:int+ } } |
|
||||
(element background { list { xsd:int+ } } |
|
||||
attribute background { list { xsd:int+ } })
|
||||
}* &
|
||||
element meshlines {
|
||||
(element meshtype { ( "tally" | "entropy" | "ufs" | "cmfd" ) } |
|
||||
attribute meshtype { ( "tally" | "entropy" | "ufs" | "cmfd" ) }) &
|
||||
(element id { xsd:int } | attribute id { xsd:int })? &
|
||||
(element linewidth { xsd:int } | attribute linewidth { xsd:int }) &
|
||||
(element color { list { xsd:int+ } } |
|
||||
attribute color { list { xsd:int+ } })?
|
||||
}*
|
||||
}*
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,7 +85,8 @@ element settings {
|
|||
attribute interplation { xsd:string { maxLength = "10" } })? &
|
||||
(element parameters { list { xsd:double+ } } |
|
||||
attribute parameters { list { xsd:double+ } })?
|
||||
}?
|
||||
}? &
|
||||
(element write_initial { xsd:boolean } | attribute write_initial { xsd:boolean })?
|
||||
}? &
|
||||
|
||||
element state_point {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
module search
|
||||
|
||||
use constants
|
||||
use error, only: fatal_error
|
||||
use global, only: message
|
||||
|
||||
integer, parameter :: MAX_ITERATION = 64
|
||||
|
||||
|
|
@ -32,8 +32,7 @@ contains
|
|||
R = n
|
||||
|
||||
if (val < array(L) .or. val > array(R)) then
|
||||
message = "Value outside of array during binary search"
|
||||
call fatal_error()
|
||||
call fatal_error("Value outside of array during binary search")
|
||||
end if
|
||||
|
||||
n_iteration = 0
|
||||
|
|
@ -60,8 +59,8 @@ contains
|
|||
! check for large number of iterations
|
||||
n_iteration = n_iteration + 1
|
||||
if (n_iteration == MAX_ITERATION) then
|
||||
message = "Reached maximum number of iterations on binary search."
|
||||
call fatal_error()
|
||||
call fatal_error("Reached maximum number of iterations on binary &
|
||||
&search.")
|
||||
end if
|
||||
end do
|
||||
|
||||
|
|
@ -85,8 +84,7 @@ contains
|
|||
R = n
|
||||
|
||||
if (val < array(L) .or. val > array(R)) then
|
||||
message = "Value outside of array during binary search"
|
||||
call fatal_error()
|
||||
call fatal_error("Value outside of array during binary search")
|
||||
end if
|
||||
|
||||
n_iteration = 0
|
||||
|
|
@ -113,8 +111,8 @@ contains
|
|||
! check for large number of iterations
|
||||
n_iteration = n_iteration + 1
|
||||
if (n_iteration == MAX_ITERATION) then
|
||||
message = "Reached maximum number of iterations on binary search."
|
||||
call fatal_error()
|
||||
call fatal_error("Reached maximum number of iterations on binary &
|
||||
&search.")
|
||||
end if
|
||||
end do
|
||||
|
||||
|
|
@ -138,8 +136,7 @@ contains
|
|||
R = n
|
||||
|
||||
if (val < array(L) .or. val > array(R)) then
|
||||
message = "Value outside of array during binary search"
|
||||
call fatal_error()
|
||||
call fatal_error("Value outside of array during binary search")
|
||||
end if
|
||||
|
||||
n_iteration = 0
|
||||
|
|
@ -166,8 +163,8 @@ contains
|
|||
! check for large number of iterations
|
||||
n_iteration = n_iteration + 1
|
||||
if (n_iteration == MAX_ITERATION) then
|
||||
message = "Reached maximum number of iterations on binary search."
|
||||
call fatal_error()
|
||||
call fatal_error("Reached maximum number of iterations on binary &
|
||||
&search.")
|
||||
end if
|
||||
end do
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
module solver_interface
|
||||
|
||||
use error, only: fatal_error
|
||||
use global, only: message
|
||||
use matrix_header, only: Matrix
|
||||
use vector_header, only: Vector
|
||||
|
||||
|
|
|
|||
|
|
@ -27,21 +27,21 @@ contains
|
|||
|
||||
subroutine initialize_source()
|
||||
|
||||
character(MAX_FILE_LEN) :: filename
|
||||
integer(8) :: i ! loop index over bank sites
|
||||
integer(8) :: id ! particle id
|
||||
integer(4) :: itmp ! temporary integer
|
||||
type(Bank), pointer :: src => null() ! source bank site
|
||||
type(BinaryOutput) :: sp ! statepoint/source binary file
|
||||
|
||||
message = "Initializing source particles..."
|
||||
call write_message(6)
|
||||
call write_message("Initializing source particles...", 6)
|
||||
|
||||
if (path_source /= '') then
|
||||
! Read the source from a binary file instead of sampling from some
|
||||
! assumed source distribution
|
||||
|
||||
message = 'Reading source file from ' // trim(path_source) // '...'
|
||||
call write_message(6)
|
||||
call write_message('Reading source file from ' // trim(path_source) &
|
||||
&// '...', 6)
|
||||
|
||||
! Open the binary file
|
||||
call sp % file_open(path_source, 'r', serial = .false.)
|
||||
|
|
@ -51,8 +51,8 @@ contains
|
|||
|
||||
! Check to make sure this is a source file
|
||||
if (itmp /= FILETYPE_SOURCE) then
|
||||
message = "Specified starting source file not a source file type."
|
||||
call fatal_error()
|
||||
call fatal_error("Specified starting source file not a source file &
|
||||
&type.")
|
||||
end if
|
||||
|
||||
! Read in the source bank
|
||||
|
|
@ -76,6 +76,19 @@ contains
|
|||
end do
|
||||
end if
|
||||
|
||||
! Write out initial source
|
||||
if (write_initial_source) then
|
||||
call write_message('Writing out initial source guess...', 1)
|
||||
#ifdef HDF5
|
||||
filename = trim(path_output) // 'initial_source.h5'
|
||||
#else
|
||||
filename = trim(path_output) // 'initial_source.binary'
|
||||
#endif
|
||||
call sp % file_create(filename, serial = .false.)
|
||||
call sp % write_source_bank()
|
||||
call sp % file_close()
|
||||
end if
|
||||
|
||||
end subroutine initialize_source
|
||||
|
||||
!===============================================================================
|
||||
|
|
@ -127,9 +140,8 @@ contains
|
|||
if (.not. found) then
|
||||
num_resamples = num_resamples + 1
|
||||
if (num_resamples == MAX_EXTSRC_RESAMPLES) then
|
||||
message = "Maximum number of external source spatial resamples &
|
||||
&reached!"
|
||||
call fatal_error()
|
||||
call fatal_error("Maximum number of external source spatial &
|
||||
&resamples reached!")
|
||||
end if
|
||||
end if
|
||||
end do
|
||||
|
|
@ -157,9 +169,8 @@ contains
|
|||
if (.not. found) then
|
||||
num_resamples = num_resamples + 1
|
||||
if (num_resamples == MAX_EXTSRC_RESAMPLES) then
|
||||
message = "Maximum number of external source spatial resamples &
|
||||
&reached!"
|
||||
call fatal_error()
|
||||
call fatal_error("Maximum number of external source spatial &
|
||||
&resamples reached!")
|
||||
end if
|
||||
cycle
|
||||
end if
|
||||
|
|
@ -192,8 +203,7 @@ contains
|
|||
site % uvw = external_source % params_angle
|
||||
|
||||
case default
|
||||
message = "No angle distribution specified for external source!"
|
||||
call fatal_error()
|
||||
call fatal_error("No angle distribution specified for external source!")
|
||||
end select
|
||||
|
||||
! Sample energy distribution
|
||||
|
|
@ -224,8 +234,7 @@ contains
|
|||
end do
|
||||
|
||||
case default
|
||||
message = "No energy distribution specified for external source!"
|
||||
call fatal_error()
|
||||
call fatal_error("No energy distribution specified for external source!")
|
||||
end select
|
||||
|
||||
! Set the random number generator back to the tracking stream.
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ module state_point
|
|||
|
||||
implicit none
|
||||
|
||||
type(BinaryOutput) :: sp ! statepoint/source output file
|
||||
type(BinaryOutput) :: sp ! Statepoint/source output file
|
||||
|
||||
contains
|
||||
|
||||
|
|
@ -54,8 +54,7 @@ contains
|
|||
#endif
|
||||
|
||||
! Write message
|
||||
message = "Creating state point " // trim(filename) // "..."
|
||||
call write_message(1)
|
||||
call write_message("Creating state point " // trim(filename) // "...", 1)
|
||||
|
||||
if (master) then
|
||||
! Create statepoint file
|
||||
|
|
@ -314,8 +313,8 @@ contains
|
|||
#endif
|
||||
|
||||
! Write message for new file creation
|
||||
message = "Creating source file " // trim(filename) // "..."
|
||||
call write_message(1)
|
||||
call write_message("Creating source file " // trim(filename) // "...", &
|
||||
&1)
|
||||
|
||||
! Create separate source file
|
||||
call sp % file_create(filename, serial = .false.)
|
||||
|
|
@ -359,8 +358,7 @@ contains
|
|||
#endif
|
||||
|
||||
! Write message for new file creation
|
||||
message = "Creating source file " // trim(filename) // "..."
|
||||
call write_message(1)
|
||||
call write_message("Creating source file " // trim(filename) // "...", 1)
|
||||
|
||||
! Always create this file because it will be overwritten
|
||||
call sp % file_create(filename, serial = .false.)
|
||||
|
|
@ -530,8 +528,8 @@ contains
|
|||
type(TallyObject), pointer :: t => null()
|
||||
|
||||
! Write message
|
||||
message = "Loading state point " // trim(path_state_point) // "..."
|
||||
call write_message(1)
|
||||
call write_message("Loading state point " // trim(path_state_point) &
|
||||
&// "...", 1)
|
||||
|
||||
! Open file for reading
|
||||
call sp % file_open(path_state_point, 'r', serial = .false.)
|
||||
|
|
@ -543,9 +541,8 @@ contains
|
|||
! current version
|
||||
call sp % read_data(int_array(1), "revision")
|
||||
if (int_array(1) /= REVISION_STATEPOINT) then
|
||||
message = "State point version does not match current version " &
|
||||
// "in OpenMC."
|
||||
call fatal_error()
|
||||
call fatal_error("State point version does not match current version &
|
||||
&in OpenMC.")
|
||||
end if
|
||||
|
||||
! Read OpenMC version
|
||||
|
|
@ -554,9 +551,8 @@ contains
|
|||
call sp % read_data(int_array(3), "version_release")
|
||||
if (int_array(1) /= VERSION_MAJOR .or. int_array(2) /= VERSION_MINOR &
|
||||
.or. int_array(3) /= VERSION_RELEASE) then
|
||||
message = "State point file was created with a different version " &
|
||||
// "of OpenMC."
|
||||
call warning()
|
||||
if (master) call warning("State point file was created with a different &
|
||||
&version of OpenMC.")
|
||||
end if
|
||||
|
||||
! Read date and time
|
||||
|
|
@ -668,8 +664,8 @@ contains
|
|||
! Check size of tally results array
|
||||
if (int_array(1) /= t % total_score_bins .and. &
|
||||
int_array(2) /= t % total_filter_bins) then
|
||||
message = "Input file tally structure is different from restart."
|
||||
call fatal_error()
|
||||
call fatal_error("Input file tally structure is different from &
|
||||
&restart.")
|
||||
end if
|
||||
|
||||
! Read number of filters
|
||||
|
|
@ -742,8 +738,8 @@ contains
|
|||
|
||||
! Check to make sure source bank is present
|
||||
if (path_source_point == path_state_point .and. .not. source_present) then
|
||||
message = "Source bank must be contained in statepoint restart file"
|
||||
call fatal_error()
|
||||
call fatal_error("Source bank must be contained in statepoint restart &
|
||||
&file")
|
||||
end if
|
||||
|
||||
! Read tallies to master
|
||||
|
|
@ -755,8 +751,8 @@ contains
|
|||
! Read number of global tallies
|
||||
call sp % read_data(int_array(1), "n_global_tallies", collect=.false.)
|
||||
if (int_array(1) /= N_GLOBAL_TALLIES) then
|
||||
message = "Number of global tallies does not match in state point."
|
||||
call fatal_error()
|
||||
call fatal_error("Number of global tallies does not match in state &
|
||||
&point.")
|
||||
end if
|
||||
|
||||
! Read global tally data
|
||||
|
|
@ -792,8 +788,8 @@ contains
|
|||
call sp % file_close()
|
||||
|
||||
! Write message
|
||||
message = "Loading source file " // trim(path_source_point) // "..."
|
||||
call write_message(1)
|
||||
call write_message("Loading source file " // trim(path_source_point) &
|
||||
&// "...", 1)
|
||||
|
||||
! Open source file
|
||||
call sp % file_open(path_source_point, 'r', serial = .false.)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ module string
|
|||
|
||||
use constants, only: MAX_WORDS, MAX_LINE_LEN, ERROR_INT, ERROR_REAL
|
||||
use error, only: fatal_error, warning
|
||||
use global, only: message
|
||||
use global, only: master
|
||||
|
||||
implicit none
|
||||
|
||||
|
|
@ -49,9 +49,8 @@ contains
|
|||
if (i_end > 0) then
|
||||
n = n + 1
|
||||
if (i_end - i_start + 1 > len(words(n))) then
|
||||
message = "The word '" // string(i_start:i_end) // &
|
||||
"' is longer than the space allocated for it."
|
||||
call warning()
|
||||
if (master) call warning("The word '" // string(i_start:i_end) &
|
||||
&// "' is longer than the space allocated for it.")
|
||||
end if
|
||||
words(n) = string(i_start:i_end)
|
||||
! reset indices
|
||||
|
|
@ -152,37 +151,47 @@ contains
|
|||
! LOWER_CASE converts a string to all lower case characters
|
||||
!===============================================================================
|
||||
|
||||
elemental subroutine lower_case(word)
|
||||
elemental function to_lower(word) result(word_lower)
|
||||
|
||||
character(*), intent(inout) :: word
|
||||
character(*), intent(in) :: word
|
||||
character(len=len(word)) :: word_lower
|
||||
|
||||
integer :: i
|
||||
integer :: ic
|
||||
|
||||
do i = 1, len(word)
|
||||
ic = ichar(word(i:i))
|
||||
if (ic >= 65 .and. ic <= 90) word(i:i) = char(ic+32)
|
||||
if (ic >= 65 .and. ic <= 90) then
|
||||
word_lower(i:i) = char(ic+32)
|
||||
else
|
||||
word_lower(i:i) = word(i:i)
|
||||
end if
|
||||
end do
|
||||
|
||||
end subroutine lower_case
|
||||
end function to_lower
|
||||
|
||||
!===============================================================================
|
||||
! UPPER_CASE converts a string to all upper case characters
|
||||
!===============================================================================
|
||||
|
||||
elemental subroutine upper_case(word)
|
||||
elemental function to_upper(word) result(word_upper)
|
||||
|
||||
character(*), intent(inout) :: word
|
||||
character(*), intent(in) :: word
|
||||
character(len=len(word)) :: word_upper
|
||||
|
||||
integer :: i
|
||||
integer :: ic
|
||||
|
||||
do i = 1, len(word)
|
||||
ic = ichar(word(i:i))
|
||||
if (ic >= 97 .and. ic <= 122) word(i:i) = char(ic-32)
|
||||
if (ic >= 97 .and. ic <= 122) then
|
||||
word_upper(i:i) = char(ic-32)
|
||||
else
|
||||
word_upper(i:i) = word(i:i)
|
||||
end if
|
||||
end do
|
||||
|
||||
end subroutine upper_case
|
||||
end function to_upper
|
||||
|
||||
!===============================================================================
|
||||
! ZERO_PADDED returns a string of the input integer padded with zeros to the
|
||||
|
|
@ -200,8 +209,8 @@ function zero_padded(num, n_digits) result(str)
|
|||
! Make sure n_digits is reasonable. 10 digits is the maximum needed for the
|
||||
! largest integer(4).
|
||||
if (n_digits > 10) then
|
||||
message = 'zero_padded called with an unreasonably large n_digits (>10)'
|
||||
call fatal_error()
|
||||
call fatal_error('zero_padded called with an unreasonably large &
|
||||
&n_digits (>10)')
|
||||
end if
|
||||
|
||||
! Write a format string of the form '(In.m)' where n is the max width and
|
||||
|
|
@ -317,7 +326,7 @@ end function zero_padded
|
|||
! the loop automatically exits when n_digits = 10.
|
||||
n_digits = n_digits + 1
|
||||
end do
|
||||
|
||||
|
||||
end function count_digits
|
||||
|
||||
!===============================================================================
|
||||
|
|
@ -349,21 +358,21 @@ end function zero_padded
|
|||
end function int8_to_str
|
||||
|
||||
!===============================================================================
|
||||
! STR_TO_INT converts a string to an integer.
|
||||
! STR_TO_INT converts a string to an integer.
|
||||
!===============================================================================
|
||||
|
||||
function str_to_int(str) result(num)
|
||||
|
||||
character(*), intent(in) :: str
|
||||
integer(8) :: num
|
||||
|
||||
|
||||
character(5) :: fmt
|
||||
integer :: w
|
||||
integer :: ioError
|
||||
|
||||
! Determine width of string
|
||||
w = len_trim(str)
|
||||
|
||||
|
||||
! Create format specifier for reading string
|
||||
write(UNIT=fmt, FMT='("(I",I2,")")') w
|
||||
|
||||
|
|
@ -404,7 +413,7 @@ end function zero_padded
|
|||
|
||||
integer :: decimal ! number of places after decimal
|
||||
integer :: width ! total field width
|
||||
real(8) :: num2 ! absolute value of number
|
||||
real(8) :: num2 ! absolute value of number
|
||||
character(9) :: fmt ! format specifier for writing number
|
||||
|
||||
! set default field width
|
||||
|
|
|
|||
|
|
@ -21,8 +21,7 @@ module tally
|
|||
|
||||
implicit none
|
||||
|
||||
! Tally map positioning array
|
||||
integer :: position(N_FILTER_TYPES - 3) = 0
|
||||
integer :: position(N_FILTER_TYPES - 3) = 0 ! Tally map positioning array
|
||||
!$omp threadprivate(position)
|
||||
|
||||
contains
|
||||
|
|
@ -871,8 +870,8 @@ contains
|
|||
end do REACTION_LOOP
|
||||
|
||||
else
|
||||
message = "Invalid score type on tally " // to_str(t % id) // "."
|
||||
call fatal_error()
|
||||
call fatal_error("Invalid score type on tally " &
|
||||
&// to_str(t % id) // ".")
|
||||
end if
|
||||
end select
|
||||
|
||||
|
|
@ -1009,8 +1008,8 @@ contains
|
|||
end do
|
||||
|
||||
else
|
||||
message = "Invalid score type on tally " // to_str(t % id) // "."
|
||||
call fatal_error()
|
||||
call fatal_error("Invalid score type on tally " &
|
||||
&// to_str(t % id) // ".")
|
||||
end if
|
||||
end select
|
||||
end if
|
||||
|
|
@ -1209,8 +1208,8 @@ contains
|
|||
end do REACTION_LOOP
|
||||
|
||||
else
|
||||
message = "Invalid score type on tally " // to_str(t % id) // "."
|
||||
call fatal_error()
|
||||
call fatal_error("Invalid score type on tally " &
|
||||
&// to_str(t % id) // ".")
|
||||
end if
|
||||
end select
|
||||
|
||||
|
|
@ -1361,8 +1360,8 @@ contains
|
|||
end do
|
||||
|
||||
else
|
||||
message = "Invalid score type on tally " // to_str(t % id) // "."
|
||||
call fatal_error()
|
||||
call fatal_error("Invalid score type on tally " &
|
||||
&// to_str(t % id) // ".")
|
||||
end if
|
||||
end select
|
||||
|
||||
|
|
@ -1707,9 +1706,8 @@ contains
|
|||
case (SCORE_EVENTS)
|
||||
score = ONE
|
||||
case default
|
||||
message = "Invalid score type on tally " // &
|
||||
to_str(t % id) // "."
|
||||
call fatal_error()
|
||||
call fatal_error("Invalid score type on tally " &
|
||||
&// to_str(t % id) // ".")
|
||||
end select
|
||||
|
||||
else
|
||||
|
|
@ -1783,9 +1781,8 @@ contains
|
|||
case (SCORE_EVENTS)
|
||||
score = ONE
|
||||
case default
|
||||
message = "Invalid score type on tally " // &
|
||||
to_str(t % id) // "."
|
||||
call fatal_error()
|
||||
call fatal_error("Invalid score type on tally " &
|
||||
&// to_str(t % id) // ".")
|
||||
end select
|
||||
end if
|
||||
|
||||
|
|
@ -2223,8 +2220,7 @@ contains
|
|||
! Check for errors
|
||||
if (filter_index <= 0 .or. filter_index > &
|
||||
t % total_filter_bins) then
|
||||
message = "Score index outside range."
|
||||
call fatal_error()
|
||||
call fatal_error("Score index outside range.")
|
||||
end if
|
||||
|
||||
! Add to surface current tally
|
||||
|
|
@ -2563,18 +2559,16 @@ contains
|
|||
|
||||
! check to see if any of the active tally lists has been allocated
|
||||
if (active_tallies % size() > 0) then
|
||||
message = "Active tallies should not exist before CMFD tallies!"
|
||||
call fatal_error()
|
||||
call fatal_error("Active tallies should not exist before CMFD tallies!")
|
||||
else if (active_analog_tallies % size() > 0) then
|
||||
message = 'Active analog tallies should not exist before CMFD tallies!'
|
||||
call fatal_error()
|
||||
call fatal_error('Active analog tallies should not exist before CMFD &
|
||||
&tallies!')
|
||||
else if (active_tracklength_tallies % size() > 0) then
|
||||
message = "Active tracklength tallies should not exist before CMFD &
|
||||
&tallies!"
|
||||
call fatal_error()
|
||||
call fatal_error("Active tracklength tallies should not exist before &
|
||||
&CMFD tallies!")
|
||||
else if (active_current_tallies % size() > 0) then
|
||||
message = "Active current tallies should not exist before CMFD tallies!"
|
||||
call fatal_error()
|
||||
call fatal_error("Active current tallies should not exist before CMFD &
|
||||
&tallies!")
|
||||
end if
|
||||
|
||||
do i = 1, n_cmfd_tallies
|
||||
|
|
|
|||
|
|
@ -39,8 +39,7 @@ contains
|
|||
|
||||
! Display message if high verbosity or trace is on
|
||||
if (verbosity >= 9 .or. trace) then
|
||||
message = "Simulating Particle " // trim(to_str(p % id))
|
||||
call write_message()
|
||||
call write_message("Simulating Particle " // trim(to_str(p % id)))
|
||||
end if
|
||||
|
||||
! If the cell hasn't been determined based on the particle's location,
|
||||
|
|
@ -50,8 +49,7 @@ contains
|
|||
|
||||
! Particle couldn't be located
|
||||
if (.not. found_cell) then
|
||||
message = "Could not locate particle " // trim(to_str(p % id))
|
||||
call fatal_error()
|
||||
call fatal_error("Could not locate particle " // trim(to_str(p % id)))
|
||||
end if
|
||||
|
||||
! set birth cell attribute
|
||||
|
|
@ -198,9 +196,8 @@ contains
|
|||
! If particle has too many events, display warning and kill it
|
||||
n_event = n_event + 1
|
||||
if (n_event == MAX_EVENTS) then
|
||||
message = "Particle " // trim(to_str(p%id)) // " underwent maximum &
|
||||
&number of events."
|
||||
call warning()
|
||||
if (master) call warning("Particle " // trim(to_str(p%id)) &
|
||||
&// " underwent maximum number of events.")
|
||||
p % alive = .false.
|
||||
end if
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
from distutils.core import setup
|
||||
|
||||
setup(name='statepoint',
|
||||
version='0.6.0',
|
||||
version='0.6.1',
|
||||
description='OpenMC StatePoint',
|
||||
author='Paul Romano',
|
||||
author_email='paul.k.romano@gmail.com',
|
||||
|
|
|
|||
|
|
@ -21,10 +21,11 @@ module vector_header
|
|||
procedure :: create => vector_create
|
||||
procedure :: destroy => vector_destroy
|
||||
procedure :: add_value => vector_add_value
|
||||
#ifdef PETSC
|
||||
procedure :: copy => vector_copy
|
||||
# ifdef PETSC
|
||||
procedure :: setup_petsc => vector_setup_petsc
|
||||
procedure :: write_petsc_binary => vector_write_petsc_binary
|
||||
#endif
|
||||
# endif
|
||||
end type Vector
|
||||
|
||||
#ifdef PETSC
|
||||
|
|
@ -127,4 +128,28 @@ contains
|
|||
end subroutine vector_write_petsc_binary
|
||||
#endif
|
||||
|
||||
!===============================================================================
|
||||
! VECTOR_COPY allocates a separate vector and copies
|
||||
!===============================================================================
|
||||
|
||||
subroutine vector_copy(self, vectocopy)
|
||||
|
||||
class(Vector), target, intent(inout) :: self
|
||||
type(Vector), intent(in) :: vectocopy
|
||||
|
||||
! Preallocate vector
|
||||
if (.not.allocated(self % data)) allocate(self % data(vectocopy % n))
|
||||
self % val => self % data(1:vectocopy % n)
|
||||
|
||||
! Set n
|
||||
self % n = vectocopy % n
|
||||
|
||||
! Copy values
|
||||
self % val = vectocopy % val
|
||||
|
||||
! Petsc is default not active
|
||||
self % petsc_active = .false.
|
||||
|
||||
end subroutine vector_copy
|
||||
|
||||
end module vector_header
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ module xml_interface
|
|||
|
||||
use constants, only: MAX_LINE_LEN
|
||||
use error, only: fatal_error
|
||||
use global, only: message
|
||||
use openmc_fox
|
||||
|
||||
implicit none
|
||||
|
|
@ -201,9 +200,8 @@ contains
|
|||
|
||||
! Leave if it was not found
|
||||
if (.not. found) then
|
||||
message = "Node " // node_name // " not part of Node " // &
|
||||
getNodeName(ptr) // "."
|
||||
call fatal_error()
|
||||
call fatal_error("Node " // node_name // " not part of Node " &
|
||||
&// getNodeName(ptr) // ".")
|
||||
end if
|
||||
|
||||
! Extract value
|
||||
|
|
@ -234,9 +232,8 @@ contains
|
|||
|
||||
! Leave if it was not found
|
||||
if (.not. found) then
|
||||
message = "Node " // node_name // " not part of Node " // &
|
||||
getNodeName(ptr) // "."
|
||||
call fatal_error()
|
||||
call fatal_error("Node " // node_name // " not part of Node " &
|
||||
&// getNodeName(ptr) // ".")
|
||||
end if
|
||||
|
||||
! Extract value
|
||||
|
|
@ -267,9 +264,8 @@ contains
|
|||
|
||||
! Leave if it was not found
|
||||
if (.not. found) then
|
||||
message = "Node " // node_name // " not part of Node " // &
|
||||
getNodeName(ptr) // "."
|
||||
call fatal_error()
|
||||
call fatal_error("Node " // node_name // " not part of Node " &
|
||||
&// getNodeName(ptr) // ".")
|
||||
end if
|
||||
|
||||
! Extract value
|
||||
|
|
@ -300,9 +296,8 @@ contains
|
|||
|
||||
! Leave if it was not found
|
||||
if (.not. found) then
|
||||
message = "Node " // node_name // " not part of Node " // &
|
||||
getNodeName(ptr) // "."
|
||||
call fatal_error()
|
||||
call fatal_error("Node " // node_name // " not part of Node " &
|
||||
&// getNodeName(ptr) // ".")
|
||||
end if
|
||||
|
||||
! Extract value
|
||||
|
|
@ -333,9 +328,8 @@ contains
|
|||
|
||||
! Leave if it was not found
|
||||
if (.not. found) then
|
||||
message = "Node " // node_name // " not part of Node " // &
|
||||
getNodeName(ptr) // "."
|
||||
call fatal_error()
|
||||
call fatal_error("Node " // node_name // " not part of Node " &
|
||||
&// getNodeName(ptr) // ".")
|
||||
end if
|
||||
|
||||
! Extract value
|
||||
|
|
@ -366,9 +360,8 @@ contains
|
|||
|
||||
! Leave if it was not found
|
||||
if (.not. found) then
|
||||
message = "Node " // node_name // " not part of Node " // &
|
||||
getNodeName(ptr) // "."
|
||||
call fatal_error()
|
||||
call fatal_error("Node " // node_name // " not part of Node " &
|
||||
&// getNodeName(ptr) // ".")
|
||||
end if
|
||||
|
||||
! Extract value
|
||||
|
|
@ -399,9 +392,8 @@ contains
|
|||
|
||||
! Leave if it was not found
|
||||
if (.not. found) then
|
||||
message = "Node " // node_name // " not part of Node " // &
|
||||
getNodeName(ptr) // "."
|
||||
call fatal_error()
|
||||
call fatal_error("Node " // node_name // " not part of Node " // &
|
||||
getNodeName(ptr) // ".")
|
||||
end if
|
||||
|
||||
! Extract value
|
||||
|
|
@ -432,9 +424,8 @@ contains
|
|||
|
||||
! Leave if it was not found
|
||||
if (.not. found) then
|
||||
message = "Node " // node_name // " not part of Node " // &
|
||||
getNodeName(ptr) // "."
|
||||
call fatal_error()
|
||||
call fatal_error("Node " // node_name // " not part of Node " &
|
||||
&// getNodeName(ptr) // ".")
|
||||
end if
|
||||
|
||||
! Get the size
|
||||
|
|
@ -461,9 +452,8 @@ contains
|
|||
|
||||
! Leave if it was not found
|
||||
if (.not. found) then
|
||||
message = "Node " // node_name // " not part of Node " // &
|
||||
getNodeName(ptr) // "."
|
||||
call fatal_error()
|
||||
call fatal_error("Node " // node_name // " not part of Node " &
|
||||
&// getNodeName(ptr) // ".")
|
||||
end if
|
||||
|
||||
! Get the size
|
||||
|
|
@ -490,9 +480,8 @@ contains
|
|||
|
||||
! Leave if it was not found
|
||||
if (.not. found) then
|
||||
message = "Node " // node_name // " not part of Node " // &
|
||||
getNodeName(ptr) // "."
|
||||
call fatal_error()
|
||||
call fatal_error("Node " // node_name // " not part of Node " // &
|
||||
getNodeName(ptr) // ".")
|
||||
end if
|
||||
|
||||
! Get the size
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import sys
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -12,5 +12,5 @@
|
|||
<display> dominance </display>
|
||||
<solver> power </solver>
|
||||
<feedback> true </feedback>
|
||||
|
||||
<gauss_seidel_tolerance> 1.e-15 1.e-20 </gauss_seidel_tolerance>
|
||||
</cmfd>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import sys
|
|||
import numpy as np
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import sys
|
|||
import numpy as np
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -12,5 +12,6 @@
|
|||
<display> dominance </display>
|
||||
<solver> power </solver>
|
||||
<feedback> false </feedback>
|
||||
<gauss_seidel_tolerance> 1.e-15 1.e-20 </gauss_seidel_tolerance>
|
||||
|
||||
</cmfd>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import sys
|
|||
import numpy as np
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import sys
|
|||
import numpy as np
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import sys
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import sys
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import sys
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import sys
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import sys
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import sys
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import sys
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import sys
|
|||
import numpy as np
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import sys
|
|||
import numpy as np
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import sys
|
|||
import numpy as np
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import sys
|
|||
import numpy as np
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import sys
|
|||
import numpy as np
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import sys
|
|||
import numpy as np
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import sys
|
|||
import numpy as np
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import sys
|
|||
import numpy as np
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import sys
|
|||
import numpy as np
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import sys
|
|||
import numpy as np
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import sys
|
|||
import numpy as np
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import sys
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import sys
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import sys
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import sys
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import sys
|
||||
|
||||
# import particle restart
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import particle_restart as pr
|
||||
|
||||
# read in particle restart file
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import sys
|
||||
|
||||
# import particle restart
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import particle_restart as pr
|
||||
|
||||
# read in particle restart file
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import sys
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import sys
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import sys
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import sys
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import sys
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import sys
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import sys
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import sys
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import sys
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import sys
|
|||
import numpy as np
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import sys
|
|||
import numpy as np
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import sys
|
|||
import numpy as np
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import sys
|
|||
import numpy as np
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import sys
|
|||
import numpy as np
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import sys
|
|||
import numpy as np
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import sys
|
|||
import numpy as np
|
||||
|
||||
# import statepoint
|
||||
sys.path.append('../../src/utils')
|
||||
sys.path.insert(0, '../../src/utils')
|
||||
import statepoint
|
||||
|
||||
# read in statepoint file
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue