diff --git a/src/DataLib/ALARAJOY.cpp b/src/DataLib/ALARAJOY.cpp index 5112e47d..65ba6600 100644 --- a/src/DataLib/ALARAJOY.cpp +++ b/src/DataLib/ALARAJOY.cpp @@ -35,7 +35,8 @@ void ALARAJOYLib::loadDSVData() // Read header containing energy group number in first entry std::string groupName; - inTrans >> nGroups >> groupName; + std::string weightFunction; + inTrans >> nGroups >> groupName >> weightFunction; // Extract Parent KZA until EOF at pKZA == -1 while ((inTrans >> row.parentKZA) && row.parentKZA != -1) diff --git a/tools/ALARAJOYWrapper/README.md b/tools/ALARAJOYWrapper/README.md index ca2c080c..7bacb97b 100644 --- a/tools/ALARAJOYWrapper/README.md +++ b/tools/ALARAJOYWrapper/README.md @@ -55,7 +55,7 @@ ALARAJOYWrapper is designed to produce a space-delimited DSV containing cross-da Running ALARAJOYWrapper can be done with one Python command: ``` -python preprocess_fendl3.py -f /path/to/fendl3_data_dir/ -d /path/to/decay_library/ decay_library-type -g group_name -a -t -r -p +python preprocess_fendl3.py -f /path/to/fendl3_data_dir/ -d /path/to/decay_library/ decay_library-type -g group_name -w weight_function -a -t -r -p ``` To read in detail about each of these arguments, call this command: ``` diff --git a/tools/ALARAJOYWrapper/njoy_tools.py b/tools/ALARAJOYWrapper/njoy_tools.py index ba16798c..db4d3181 100644 --- a/tools/ALARAJOYWrapper/njoy_tools.py +++ b/tools/ALARAJOYWrapper/njoy_tools.py @@ -86,7 +86,7 @@ def set_directory(): """ groupr/ $NENDF $NPEND $NGOUT1 $NGOUT2/ - $mat_id $ign $IGG $IWT $LORD $NTEMP $NSIGZ $IPRINT_groupr/ + $mat_id $ign $IGG $iwt $LORD $NTEMP $NSIGZ $IPRINT_groupr/ $title/ $groupr_temp $SIGZ_groupr/ @@ -103,7 +103,6 @@ def set_directory(): NGOUT1 = 0, # unit for input gout tape (default=0) NGOUT2 = 31, # unit for output gout tape (default=0) IGG = 0, # gamma group structure option - IWT = 11, # weight function option (corresponding to Vitamin E) LORD = 0, # Legendre order NTEMP = 1, # number of temperatures (default=1) NSIGZ = 1, # number of sigma zeroes (default=1) @@ -164,6 +163,20 @@ def set_directory(): 34 : 'LANL-618' } +NJOY_WEIGHT_FUNCTIONS = { + 2 : 'CONSTANT', + 3 : '1/E', + 4 : '1/E_+_FISSION_SPECTRUM_+_THERMAL MAXWELLIAN', + 5 : 'EPRI-CELL_LWR', + 6 : '(THERMAL)--(1/E)--(FISSION_+_FUSION)', + 7 : '(THERMAL)--(1/E)--(FISSION_+_FUSION)_WITH_T-DEP_THERMAL_PART', + 8 : 'THERMAL--1/E--FAST REACTOR--FISSION_+_FUSION', + 9 : 'CLAW_WEIGHT_FUNCTION', + 10 : 'CLAW_WITH_T-DEPENDENT_THERMAL_PART', + 11 : 'VITAMIN-E_WEIGHT_FUNCTION_(ORNL_5505)', + 12 : 'VIT-E_WITH_T-DEP_THERMAL_PART' +} + def load_external_group_struct(group_struct): """ For a group-structure that is not included among the built-in group @@ -231,23 +244,33 @@ def load_external_group_struct(group_struct): return group_name, group_bounds -def set_group_structure(group_struct_arg): +def set_modifiable_groupr_parameters(parsed_arg, njoy_ref_dict): """ - Interpret the group_structure argument (`-g`) to define the requisite NJOY - parameters to convert TENDL data to the given multi-group energy - structure. By default, the Vitamin-J 175 group structure is used for - ALARAJOY preprocessing and this function will return the appropriate - values for NJOY to run GROUPR with these settings. If another group - structure is desired, however, there are three ways in which this - group structure can be set: - - 1) Provide the GROUPR `ign` key or group name corresponding to the - desired group structure. NJOY has 33 built-in group structures from - which GROUPR can access their data, including for Vitamin-J. These can - be found in Section 8.18 ("Running GROUPR") of the NJOY User Manual + Interpret the group structure (`-g`) or weight function (`-w`) argument + in `preprocess_fendl3` to define the requisite NJOY parameters to + convert TENDL data to the specified multi-group energy structure + weighted by a specified weight function. By default, ALARAJOY + preprocessing is done by converting to the Vitamin-J 175 group + structure and weighted by the Vitamin-E weight function. If one or + both of these optional arguments is not supplied when running the + preprocessor, the respective default value will be passed to this + function. However, one of the two, group structure or weight function, + can be customized without affecting the other. To select a non-default + group structure or weight function by which to process TENDL data, one + of the following approaches can be taken (only Option 1 is currently + available for custom weight function selection): + + 1) Provide the GROUPR `ign` or `iwt` key or name corresponding to the + desired group structure or weight function, respectively. NJOY has 33 + built-in group structures from which GROUPR can access their data, + including for Vitamin-J. Likewise, NJOY has 11 built-in weight + functions, including Vitamin-E. These can be fond in Section 8.18 + ("Running GROUPR") fo the NJOY User manual (https://github.com/njoy/NJOY2016-manual/raw/master/njoy16.pdf) or in - the dictionary njoy_tools.NJOY_GROUPS. - + either of the dictionaries `njoy_tools.NJOY_GROUPS`, + `njoy_tools.NJOY_WEIGHT_FUNCTIONS`. + (Available for group structure or weight function selection) + 2) Provide a support file containing the explicit energy bounds of a multi-group energy structure. NJOY is not limited to its pre-set structures, and is capable of converting cross-sections to an @@ -263,6 +286,7 @@ def set_group_structure(group_struct_arg): read in, the values will be sorted to ensure compliance to NJOY's expectation of ascending energy bounds for an arbitrary group structure. + (Only available for group structure selection) 3) Provide a group-structure name corresponding to a key in the `openmc.mgxs.GROUP_STRUCTURES` dictionary. The open-source Monte Carlo @@ -271,47 +295,72 @@ def set_group_structure(group_struct_arg): included in the list of NJOY options mentioned in `(1)`, such as the 'CCFE-709' group structure used by FISPACT-II. These group structures can be found at https://docs.openmc.org/en/stable/pythonapi/mgxs.html. - + (Only available for group structure selection) + + Functionality to wrap NJOY's arbitrary weight function application is + not currently available in ALARAJOYWrapper. If desired, please open an + Issue on the ALARA GitHub (https://github.com/svalinn/ALARA/issues) to + request development of this capability. + Arguments: - group_struct_arg (list of str): Group structure argument following the - procedures described above. + parsed_arg (list of str): Group structure or weight function argument + following procedures described above. + njoy_ref_dict (dict): Reference dictionary from which to look for + appropriate NJOY parameter keys, names. Either + `njoy_tools.NJOY_GROUPS` or `njoy_tools.NJOY_WEIGHT_FUNCTIONS` for + group structure or weight function, respectively. Returns: - ign (int): GROUPR neutron group structure parameter. ign = 1 for - arbitrary group structures not contained in NJOY's built-in list - of options. - ngn (str): Number of groups. Will be an empty string unless ign == 1. - egn (str): Space-joined string of all energy group bounds in - ascending order. Will be an empty string unless ign == 1. - group_name (str): Name of the provided group structure. + characteristic_parameter (int): GROUPR parameter value for either + group structure (`ign`) or weight function (`iwt`). + parameter_name (str): Name of the provided group structure or weight + function. + ngn (str): Number of groups. Will be an empty string unless + `ign == 1`; always empty for weight function case. + egn (str): Space-joined string of all energy group bounds in ascending + order. Will be an empty string unless `ign == 1`; always empty for + weight function case. """ + characteristic_parameter = None + parameter_name = '' + value = parsed_arg[0] + + # Default values only needed for group structure case ngn = '' egn = '' - group_struct = group_struct_arg[0] - - # Check if provided group structure is among the list of built-in NJOY - # group structures by key (ign values 2-34) - if group_struct in np.array(list(NJOY_GROUPS)).astype(str): - ign = int(group_struct) - group_name = NJOY_GROUPS[ign] - # Check if provided group structure is among the list of built-in NJOY - # group structures by name (values of NJOY_GROUPS dict) - elif group_struct.upper() in NJOY_GROUPS.values(): - group_name = group_struct.upper() - ign = list(NJOY_GROUPS.keys())[ - list(NJOY_GROUPS.values()).index(group_name) + # Check if provided parameter is among the list of built-in NJOY group + # structures or weight functions by key (ign values 2-34; iwt values 2-12) + if value in np.asarray(list(njoy_ref_dict), dtype=str): + characteristic_parameter = int(value) + parameter_name = njoy_ref_dict[characteristic_parameter] + + # Check if the provided parameter is among the list of built-in NJOY group + # structures or weight functions by name (values of NJOY_GROUPS or + # NJOY_WEIGHT_FUNCTIONS dictionaries, respectively) + elif value.upper() in njoy_ref_dict.values(): + parameter_name = value.upper() + characteristic_parameter = list(njoy_ref_dict)[ + list(njoy_ref_dict.values()).index(parameter_name) ] - # NJOY "arbitrary group structure" option - else: - ign = 1 - group_name, group_bounds = load_external_group_struct(group_struct) + # Group structure case: NJOY "arbitrary group structure" option + elif njoy_ref_dict == NJOY_GROUPS: + characteristic_parameter = 1 + parameter_name, group_bounds = load_external_group_struct(value) ngn = str(len(group_bounds) - 1) - egn = ' '.join(np.array(sorted(group_bounds)).astype(str)) + egn = ' '.join(np.asarray(sorted(group_bounds), dtype=str)) + + if not (characteristic_parameter and parameter_name): + raise ValueError( + f'Invalid argument "{value}" for associated GROUPR parameter. ' \ + 'Consult set_modifiable_groupr_parameters() docstring for ' \ + 'guidance on accepted inputs for group structure, weight ' \ + 'function parameters.' + ) - return ign, ngn, egn, group_name + return characteristic_parameter, parameter_name, ngn, egn def card9_special_isomer_reactions(pKZA, MT, mt_data, isomer_data, mtname): """ @@ -323,7 +372,6 @@ def card9_special_isomer_reactions(pKZA, MT, mt_data, isomer_data, mtname): appropriate values supplied in the input isomer_dict. The formatting for isomeric states follows the guidelines provided in - the develop branch (db71977593d084ae5bbb9e5c88a926541718d313) of NJOY-2016, described in NJOY2016/src/groupr.f90: card9a Extended residual format (mfd = -1 only) @@ -366,7 +414,7 @@ def card9_special_isomer_reactions(pKZA, MT, mt_data, isomer_data, mtname): def fill_input_template( inp, material_id, MTs, element, A, mt_dict, temperature, pKZA=None, isomer_dict={}, unresr_fail=False, err=0.001, - ign=17, ngn='', egn='' + iwt=11, ign=17, ngn='', egn='' ): """ Substitute in the material-specific values for a given ENDF/PENDF file @@ -472,7 +520,8 @@ def fill_input_template( title=title, ign=ign, ngn=ngn, - egn=egn, + egn=egn, + iwt=iwt, reactions=card9, npend_gaspr=npend_gaspr, err=err diff --git a/tools/ALARAJOYWrapper/preprocess_fendl3.py b/tools/ALARAJOYWrapper/preprocess_fendl3.py index f71fe285..9492ebe0 100644 --- a/tools/ALARAJOYWrapper/preprocess_fendl3.py +++ b/tools/ALARAJOYWrapper/preprocess_fendl3.py @@ -62,6 +62,14 @@ def make_argparser(): details for acceptable forms in which to supply this argument. ''') ) + parser.add_argument( + '--weight_function', '-w', required=False, nargs=1, default=[11], + help=(''' + Specification for weight function with which to group TENDL cross- + sections. See njoy_tools.set_weight_function() for specific + details for acceptable forms in which to supply this argument. + ''') + ) parser.add_argument( '--xs_plotting', '-p', action='store_true', help=(''' @@ -227,7 +235,7 @@ def process_pendf( def process_gendf( njoy_groupr_input, material_id, MTs, mt_dict, temperature, pKZA, isomer_dict, all_rxns, all_nucs, group_name, tendl_dir, - ign=17, ngn='', egn='' + iwt=11, ign=17, ngn='', egn='' ): """ Prepare and run NJOY run with GROUPR and iteratively extract cross-section @@ -289,7 +297,7 @@ def process_gendf( groupr_input = njt.fill_input_template( njoy_groupr_input, material_id, MTs, element, A, mt_dict, temperature, pKZA, isomer_dict, - ign=ign, ngn=ngn, egn=egn + iwt=iwt, ign=ign, ngn=ngn, egn=egn ) njt.write_njoy_input_file(groupr_input) gendf_path, njoy_error, _ = njt.run_njoy( @@ -429,7 +437,7 @@ def rxn_to_str(parent, daughter, MT, rxn): return dsv_row + ' '.join(str(xs) for xs in rxn['xsections']) def store_results( - dsv_path, all_rxns, nGroups, tendl_dir, group_name, plotting + dsv_path, all_rxns, nGroups, tendl_dir, group_name, weight_function, plotting ): """ Save groupwise-converted cross-section data to a space-delimited DSV file @@ -471,6 +479,8 @@ def store_results( group_name (str): Name of the group structure according to which GROUPR converted continuous energy cross-sections to groupwise cross-sections. + weight_function (str): Name of the weight function with which GROUPR + calibrated groupwise cross-section conversion calculations. plotting (bool): Boolean to set whether to produce cross-section plots. @@ -479,7 +489,7 @@ def store_results( """ with open(dsv_path, 'w') as dsv: - dsv.write(f'{nGroups} {group_name}\n') + dsv.write(f'{nGroups} {group_name} {weight_function}\n') for parent in sorted(all_rxns): element, A = tp.interpret_KZA(parent) for daughter in all_rxns[parent]: @@ -554,7 +564,12 @@ def main(): Path(args.fendlFileDir[0]) if args.fendlFileDir else dir ) temperature = args.temperature[0] - ign, ngn, egn, group_name = njt.set_group_structure(args.group_structure) + ign, group_name, ngn, egn = njt.set_modifiable_groupr_parameters( + args.group_structure, njt.NJOY_GROUPS + ) + iwt, weight_function, _, _ = njt.set_modifiable_groupr_parameters( + args.weight_function, njt.NJOY_WEIGHT_FUNCTIONS + ) mt_dict = rxd.process_mt_data(rxd.load_mt_table(dir / 'mt_table.csv')) endf6_MTs = set(mt_dict) @@ -601,7 +616,7 @@ def main(): all_rxns, nGroups = process_gendf( njt.groupr_input, material_id, MTs, mt_dict, temperature, pKZA, isomer_dict, all_rxns, all_nucs, group_name, search_dir, - ign=ign, ngn=ngn, egn=egn + iwt=iwt, ign=ign, ngn=ngn, egn=egn ) else: @@ -627,8 +642,8 @@ def main(): dsv_path = dir / 'cumulative_gendf_data.dsv' store_results( - dsv_path, gas_filtered, nGroups, - search_dir, group_name, args.xs_plotting + dsv_path, gas_filtered, nGroups, search_dir, + group_name, weight_function, args.xs_plotting ) print( f'Neutron activation cross-sections converted to {nGroups} groups ' \