Source code for RbwrAc

#! /usr/bin/env python3

###
### Library imports
###

if 'Offline' in __file__.split('/')[-1].replace('.py', ''):
    from MocDown import Array,\
                        Class,\
                        Exponent,\
                        LinearInterpolate,\
                        McnpInputFile,\
                        MocDownInputFile,\
                        Nan2Num,\
                        NaturalLogarithm,\
                        NonZero,\
                        PrintNow,\
                        WordArrange,\
                        WriteFile,\
                        ZaIsActinide,\
                        Zeros,\
                        avogadrosNumber,\
                        epsilon;

###
### Custom functions
###

###
# RBWR-AC recycling scheme
###
[docs]def RbwrACRecycle(bocTransportFile, eocTransportFile): '''Override fuel processing.'''; ### # Hard code the blanket and seed cell parameters ### numberOfUpperBlanketCells = 8; numberOfUpperSeedCells = 12; numberOfInternalBlanketCells = 12; numberOfLowerSeedCells = 12; numberOfLowerBlanketCells = 12; ### firstCellNumber = 3; ### # Define the blanket and seed cell numbers ### previous = firstCellNumber; upperBlanketCellNumbers = list(range(previous, previous + numberOfUpperBlanketCells)); previous = max(upperBlanketCellNumbers) + 1; upperSeedCellNumbers = list(range(previous, previous + numberOfUpperSeedCells)); previous = max(upperBlanketCellNumbers + upperSeedCellNumbers) + 1; internalBlanketCellNumbers = list(range(previous, previous + numberOfInternalBlanketCells)); previous = max(upperBlanketCellNumbers + upperSeedCellNumbers + internalBlanketCellNumbers) + 1; lowerSeedCellNumbers = list(range(previous, previous + numberOfLowerSeedCells)); previous = max(upperBlanketCellNumbers + upperSeedCellNumbers + internalBlanketCellNumbers + lowerSeedCellNumbers) + 1; lowerBlanketCellNumbers = list(range(previous, previous + numberOfLowerBlanketCells)); ### upperSeedVolumeFraction = 28 / (28 + 19.3); lowerSeedVolumeFraction = 1 - upperSeedVolumeFraction; ### # Isotopic ZA ### oxygen = 8016; depletedUranium = { 92235 : 2.5e-3, 92238 : 1 - 2.5e-3, }; ### # Calculate the number of BOEC seed heavy-metal moles; # This number is conserved across recycles ### chargeMoles = sum(moles for cellNumber in upperSeedCellNumbers + lowerSeedCellNumbers for za, moles in bocTransportFile.FindCell(cellNumber).GetZa2Moles().items() if ZaIsActinide(za)); ### # Construct the seed charge: # First, EOEC heavy metal moles are accumulated; # Second, any mole deficit or surplus is made up with uranium # Third, add twice as many oxygen moles as heavy metal moles ### za2ChargeMoles = {}; for cellNumber in upperBlanketCellNumbers + upperSeedCellNumbers + internalBlanketCellNumbers + lowerSeedCellNumbers + lowerBlanketCellNumbers: for za, moles in eocTransportFile.FindCell(cellNumber).GetZa2Moles().items(): if ZaIsActinide(za): try: za2ChargeMoles[za] += moles; except KeyError: za2ChargeMoles[za] = moles; ### deviation = chargeMoles - sum(za2ChargeMoles.values()); uranium2Fraction = {za : moles for za, moles in za2ChargeMoles.items() if 92 == za // 1000}; uranium2Fraction = {za : moles / sum(uranium2Fraction.values()) for za, moles in uranium2Fraction.items()}; try: for za, fraction in uranium2Fraction.items(): za2ChargeMoles[za] += deviation * fraction; except KeyError: for za, fraction in uranium2Fraction.items(): za2ChargeMoles[za] = deviation * fraction; assert(all(za2ChargeMoles[za] > 0 for za in depletedUranium)); ### za2ChargeMoles[oxygen] = 2 * chargeMoles; ### # Distribute the seed charge: # First, split moles evenly between seed cells # Second, match BOEC moles for each cell by adjusting depleted urania moles ### cellNumber2Za2ChargeMoles = {cellNumber : {za : moles * upperSeedVolumeFraction / numberOfUpperSeedCells for za, moles in za2ChargeMoles.items()} for cellNumber in upperSeedCellNumbers}; cellNumber2Za2ChargeMoles.update({cellNumber : {za : moles * lowerSeedVolumeFraction / numberOfUpperSeedCells for za, moles in za2ChargeMoles.items()} for cellNumber in lowerSeedCellNumbers}); ### for cellNumber in upperSeedCellNumbers + lowerSeedCellNumbers: bocCell = bocTransportFile.FindCell(cellNumber); deviation = bocCell.GetMoles() - sum(cellNumber2Za2ChargeMoles[cellNumber].values()); try: for za, fraction in depletedUranium.items(): cellNumber2Za2ChargeMoles[cellNumber][za] += deviation * fraction * 1 / 3; cellNumber2Za2ChargeMoles[cellNumber][oxygen] += deviation * 2 / 3; except KeyError: for za, fraction in depletedUranium.items(): cellNumber2Za2ChargeMoles[cellNumber][za] = deviation * fraction * 1 / 3; cellNumber2Za2ChargeMoles[cellNumber][oxygen] = deviation * 2 / 3; assert(all(cellNumber2Za2ChargeMoles[cellNumber][za] > 0 for za in depletedUranium)); ### # Distribute the blanket charge: # Simply grab the BOEC moles ### cellNumber2Za2ChargeMoles.update({cellNumber : bocTransportFile.FindCell(cellNumber).GetZa2Moles() for cellNumber in upperBlanketCellNumbers + internalBlanketCellNumbers + lowerBlanketCellNumbers}); ### # Recharge cells ### for cellNumber in upperBlanketCellNumbers + upperSeedCellNumbers + internalBlanketCellNumbers + lowerSeedCellNumbers + lowerBlanketCellNumbers: za2ChargeMoles = cellNumber2Za2ChargeMoles[cellNumber]; ### # Replace cell cards ### cell = eocTransportFile.FindCell(cellNumber); ### numberDensity = sum(za2ChargeMoles.values()) / cell.GetVolume() * avogadrosNumber; cellCard = cell.GetMaterialDensityRegex().sub('{:+10.7f}'.format(numberDensity), cell.GetRaw()); ### eocTransportFile.ReplaceNewputCard(cell, cellCard); ### # Replace material cards ### material = eocTransportFile.FindCellMaterial(cellNumber); ### suffix = cell.GetSuffix(); totalMoles = sum(za2ChargeMoles.values()) / 3; zaid2AtomFraction = {'{}.{}'.format(za, suffix) : moles / totalMoles for za, moles in za2ChargeMoles.items()}; materialCard = WordArrange(words = ('{:>10} {:+.5E}'.format(zaid, atomFraction) for zaid, atomFraction in sorted(zaid2AtomFraction.items(), key = lambda item: (item[1], item[0]), reverse = True)), prefix = '\nm{:<6d}'.format(material.GetNumber()), indent = 8); ### eocTransportFile.ReplaceNewputCard(material, materialCard); ### return eocTransportFile; ### ### Replacement for DepletionCalculation methods ### ### # DepletionCalculation.ProcessFuel() ###
ProcessFuel = lambda self : RbwrACRecycle(self.GetOriginalTransportFile(), McnpInputFile(self.GetFileName('i', withoutTH = True))); ### ### Offline helper functions ### ### # Process fuel ###
[docs]def ProcessFuelOffline(bocFileName, eocFileName, newFileName): '''Offline fuel processing helper.'''; newInputFile = RbwrACRecycle(McnpInputFile(bocFileName), McnpInputFile(eocFileName)); ### WriteFile(newFileName, newInputFile.GetNewputRaw()); ### return;