Store heating, gas production, and damage energy as redundant reactions

This commit is contained in:
Paul Romano 2019-03-07 09:36:38 -06:00
parent b2d6a06284
commit a48d590158
10 changed files with 94 additions and 18 deletions

View file

@ -220,6 +220,16 @@ The following tables show all valid scores:
| |multiplicity from (n,2n), (n,3n), and (n,4n) |
| |reactions. |
+----------------------+---------------------------------------------------+
|H1-production |Total production of H1. |
+----------------------+---------------------------------------------------+
|H2-production |Total production of H2 (deuterium). |
+----------------------+---------------------------------------------------+
|H3-production |Total production of H1 (tritium). |
+----------------------+---------------------------------------------------+
|He3-production |Total production of He3. |
+----------------------+---------------------------------------------------+
|He4-production |Total production of He4 (alpha particles). |
+----------------------+---------------------------------------------------+
.. table:: **Miscellaneous scores: units are indicated for each.**
@ -246,6 +256,10 @@ The following tables show all valid scores:
|inverse-velocity |The flux-weighted inverse velocity where the |
| |velocity is in units of centimeters per second. |
+----------------------+---------------------------------------------------+
|heating |Total neutron heating in units of eV per source |
| |particle. This corresponds to MT=301 produced by |
| |NJOY's HEATR module. |
+----------------------+---------------------------------------------------+
|kappa-fission |The recoverable energy production rate due to |
| |fission. The recoverable energy is defined as the |
| |fission product kinetic energy, prompt and delayed |
@ -281,3 +295,7 @@ The following tables show all valid scores:
|decay-rate |The delayed-nu-fission-weighted decay rate where |
| |the decay rate is in units of inverse seconds. |
+----------------------+---------------------------------------------------+
|damage-energy |Damage energy production in units of eV per source |
| |particle. This corresponds to MT=444 produced by |
| |NJOY's HEATR module. |
+----------------------+---------------------------------------------------+

View file

@ -225,6 +225,13 @@ constexpr int N_3P {197};
constexpr int N_N3P {198};
constexpr int N_3N2PA {199};
constexpr int N_5N2P {200};
constexpr int N_XP {203};
constexpr int N_XD {204};
constexpr int N_XT {205};
constexpr int N_X3HE {206};
constexpr int N_XA {207};
constexpr int HEATING {301};
constexpr int DAMAGE_ENERGY {444};
constexpr int COHERENT {502};
constexpr int INCOHERENT {504};
constexpr int PAIR_PROD_ELEC {515};

View file

@ -448,11 +448,13 @@ class IncidentNeutron(EqualityMixin):
for rx in self.reactions.values():
# Skip writing redundant reaction if it doesn't have photon
# production or is a summed transmutation reaction. MT=4 is also
# sometimes needed for probability tables.
# sometimes needed for probability tables. Also write gas
# production, heating, and damage energy production.
if rx.redundant:
photon_rx = any(p.particle == 'photon' for p in rx.products)
transmutation_rx = (rx.mt in (16, 103, 104, 105, 106, 107))
if not (photon_rx or transmutation_rx or rx.mt == 4):
keep_mts = (4, 16, 103, 104, 105, 106, 107,
203, 204, 205, 206, 207, 301, 444)
if not (photon_rx or rx.mt in keep_mts):
continue
rx_group = rxs_group.create_group('reaction_{:03}'.format(rx.mt))
@ -615,13 +617,14 @@ class IncidentNeutron(EqualityMixin):
# Read energy grid
n_energy = ace.nxs[3]
energy = ace.xss[ace.jxs[1]:ace.jxs[1] + n_energy]*EV_PER_MEV
i = ace.jxs[1]
energy = ace.xss[i : i + n_energy]*EV_PER_MEV
data.energy[strT] = energy
total_xs = ace.xss[ace.jxs[1] + n_energy:ace.jxs[1] + 2 * n_energy]
absorption_xs = ace.xss[ace.jxs[1] + 2 * n_energy:ace.jxs[1] +
3 * n_energy]
total_xs = ace.xss[i + n_energy : i + 2*n_energy]
absorption_xs = ace.xss[i + 2*n_energy : i + 3*n_energy]
heating_number = ace.xss[i + 3*n_energy : i + 4*n_energy]*EV_PER_MEV
# Create redundant reactions (total and absorption)
# Create redundant reactions (total, absorption, and heating)
total = Reaction(1)
total.xs[strT] = Tabulated1D(energy, total_xs)
total.redundant = True
@ -633,13 +636,15 @@ class IncidentNeutron(EqualityMixin):
absorption.redundant = True
data.reactions[101] = absorption
heating = Reaction(301)
heating.xs[strT] = Tabulated1D(energy, heating_number)
heating.redundant = True
data.reactions[301] = heating
# Read each reaction
n_reaction = ace.nxs[4] + 1
for i in range(n_reaction):
rx = Reaction.from_ace(ace, i)
# Don't include gas production / damage cross sections
if 200 < rx.mt < 219 or rx.mt == 444:
continue
data.reactions[rx.mt] = rx
# Some photon production reactions may be assigned to MTs that don't
@ -690,6 +695,8 @@ class IncidentNeutron(EqualityMixin):
mts = data.get_reaction_components(rx.mt)
if mts != [rx.mt]:
rx.redundant = True
if rx.mt in (203, 204, 205, 206, 207, 444):
rx.redundant = True
# Read unresolved resonance probability tables
urr = ProbabilityTables.from_ace(ace)

View file

@ -72,8 +72,13 @@ broadr / %%%%%%%%%%%%%%%%%%%%%%% Doppler broaden XS %%%%%%%%%%%%%%%%%%%%%%%%%%%%
_TEMPLATE_HEATR = """
heatr / %%%%%%%%%%%%%%%%%%%%%%%%% Add heating kerma %%%%%%%%%%%%%%%%%%%%%%%%%%%%
{nendf} {nheatr_in} {nheatr} /
{mat} 3 /
302 318 402 /
{mat} 4 /
302 318 402 444 /
"""
_TEMPLATE_GASPR = """
gaspr / %%%%%%%%%%%%%%%%%%%%%%%%% Add gas production %%%%%%%%%%%%%%%%%%%%%%%%%%%
{nendf} {ngaspr_in} {ngaspr} /
"""
_TEMPLATE_PURR = """
@ -211,8 +216,8 @@ def make_pendf(filename, pendf='pendf', error=0.001, stdout=False):
def make_ace(filename, temperatures=None, ace='ace', xsdir='xsdir', pendf=None,
error=0.001, broadr=True, heatr=True, purr=True, acer=True,
**kwargs):
error=0.001, broadr=True, heatr=True, gaspr=True, purr=True,
acer=True, **kwargs):
"""Generate incident neutron ACE file from an ENDF file
Parameters
@ -234,6 +239,8 @@ def make_ace(filename, temperatures=None, ace='ace', xsdir='xsdir', pendf=None,
Indicating whether to Doppler broaden XS when running NJOY
heatr : bool, optional
Indicating whether to add heating kerma when running NJOY
gaspr : bool, optional
Indicating whether to add gas production data when running NJOY
purr : bool, optional
Indicating whether to add probability table when running NJOY
acer : bool, optional
@ -285,6 +292,13 @@ def make_ace(filename, temperatures=None, ace='ace', xsdir='xsdir', pendf=None,
commands += _TEMPLATE_HEATR
nlast = nheatr
# gaspr
if gaspr:
ngaspr_in = nlast
ngaspr = ngaspr_in + 1
commands += _TEMPLATE_GASPR
nlast = ngaspr
# purr
if purr:
npurr_in = nlast

View file

@ -51,7 +51,9 @@ REACTION_NAME = {1: '(n,total)', 2: '(n,elastic)', 4: '(n,level)',
189: '(n,nta)', 190: '(n,2n2p)', 191: '(n,p3He)',
192: '(n,d3He)', 193: '(n,3Hea)', 194: '(n,4n2p)',
195: '(n,4n2a)', 196: '(n,4npa)', 197: '(n,3p)',
198: '(n,n3p)', 199: '(n,3n2pa)', 200: '(n,5n2p)', 444: '(n,damage)',
198: '(n,n3p)', 199: '(n,3n2pa)', 200: '(n,5n2p)', 203: '(n,Xp)',
204: '(n,Xd)', 205: '(n,Xt)', 206: '(n,X3He)', 207: '(n,Xa)',
301: 'heating', 444: 'damage-energy',
649: '(n,pc)', 699: '(n,dc)', 749: '(n,tc)', 799: '(n,3Hec)',
849: '(n,ac)', 891: '(n,2nc)'}
REACTION_NAME.update({i: '(n,n{})'.format(i - 50) for i in range(50, 91)})
@ -988,6 +990,10 @@ class Reaction(EqualityMixin):
# Read reaction cross section
xs = ace.xss[ace.jxs[7] + loc + 1:ace.jxs[7] + loc + 1 + n_energy]
# For damage energy production, convert to eV
if mt == 444:
xs *= EV_PER_MEV
# Fix negatives -- known issue for Y89 in JEFF 3.2
if np.any(xs < 0.0):
warn("Negative cross sections found for MT={} in {}. Setting "

View file

@ -229,8 +229,10 @@ std::string reaction_name(int mt)
return "(n,X3He)";
} else if (mt == 207) {
return "(n,Xa)";
} else if (mt == 301) {
return "heating";
} else if (mt == 444) {
return "(damage)";
return "damage-energy";
} else if (mt == COHERENT) {
return "coherent scatter";
} else if (mt == INCOHERENT) {

View file

@ -197,6 +197,20 @@ score_str_to_int(std::string score_str)
return N_PT;
if (score_str == "(n,da)")
return N_DA;
if (score_str == "(n,Xp)" || score_str == "H1-production")
return N_XP;
if (score_str == "(n,Xd)" || score_str == "H2-production")
return N_XD;
if (score_str == "(n,Xt)" || score_str == "H3-production")
return N_XT;
if (score_str == "(n,X3He)" || score_str == "He3-production")
return N_X3HE;
if (score_str == "(n,Xa)" || score_str == "He4-production")
return N_XA;
if (score_str == "heating")
return HEATING;
if (score_str == "damage-energy")
return DAMAGE_ENERGY;
// So far we have not identified this score string. Check to see if it is a
// deprecated score.

View file

@ -511,4 +511,7 @@
<scores>total</scores>
<estimator>tracklength</estimator>
</tally>
<tally id="33">
<scores>H1-production H2-production H3-production He3-production He4-production heating damage-energy</scores>
</tally>
</tallies>

View file

@ -1 +1 @@
b5edf87cb58db29aa1c38203141df2f055b88aca675aee9673879b579391412abd232cb3d404f60840ac86b936384050576cccb1e3a1fc5c8290b6e890dda74c
de773a799f84348241ebd65bf7beae8114861d8674b652bfd443d578c146a7d37ca38f2efc5d05124fdbb1cf12829907768351e6b2d6b5f4bd2c121417757507

View file

@ -165,6 +165,10 @@ def test_tallies():
all_nuclide_tallies[3].filters = [mesh_filter]
all_nuclide_tallies[3].nuclides = ['U235']
fusion_tally = Tally()
fusion_tally.scores = ['H1-production', 'H2-production', 'H3-production',
'He3-production', 'He4-production', 'heating', 'damage-energy']
model.tallies += [
azimuthal_tally1, azimuthal_tally2, azimuthal_tally3,
cellborn_tally, dg_tally, energy_tally, energyout_tally,
@ -174,5 +178,6 @@ def test_tallies():
model.tallies += score_tallies
model.tallies += flux_tallies
model.tallies += all_nuclide_tallies
model.tallies.append(fusion_tally)
harness.main()