def toENDF6(self, baseMT, endfMFList, flags, targetInfo): MF, MT, LP = 12, baseMT + int(self.label), 0 nGammas, gammaData, levelEnergy_eV = len( self.gammas), [], self.energy.getValueAs('eV') for gamma in self.gammas: gammaData.append(gamma.toENDF6List()) LGp = len(gammaData[0]) for gamma in gammaData: gamma[0] = levelEnergy_eV - gamma[0] endfMFList[MF][MT] = [ endfFormatsModule.endfHeadLine(targetInfo['ZA'], targetInfo['mass'], 2, LGp - 1, MT - baseMT, 0), endfFormatsModule.endfHeadLine(levelEnergy_eV, 0., LP, 0, LGp * nGammas, nGammas) ] gammaData.sort(reverse=True) endfMFList[MF][MT] += endfFormatsModule.endfNdDataList(gammaData) endfMFList[MF][MT].append(endfFormatsModule.endfSENDLineNumber()) # Currently, assume all distributions are isotropic endfMFList[14][MT] = [ endfFormatsModule.endfHeadLine(targetInfo['ZA'], targetInfo['mass'], 1, 0, nGammas, 0) ] endfMFList[14][MT].append(endfFormatsModule.endfSENDLineNumber())
def toENDF6(self, flags={}, verbosityIndent=''): endfMFList = {1: {451: []}, 7: {}} targetInfo = {'ZA': self.MAT + 100, 'mass': self.mass} MAT = self.MAT NSUB, NVER = 12, 7 # 12: thermal scattering sub-library, 7: ENDF/B-VII for subsection in (thermalScatteringModule.coherentElasticToken, thermalScatteringModule.incoherentElasticToken, thermalScatteringModule.incoherentInelasticToken): if getattr(self, subsection) is not None: getattr(self, subsection).toENDF6(endfMFList, flags, targetInfo, verbosityIndent) endfDoc = self.documentation.getLines() docHeader = [ endfFormatsModule.endfHeadLine(targetInfo['ZA'], targetInfo['mass'], -1, 0, 0, 0), endfFormatsModule.endfHeadLine(0, 0, 0, 0, 0, 6), # ENDF-6 endfFormatsModule.endfHeadLine(1.0, self.emax.getValueAs('eV'), 1, 0, NSUB, NVER), endfFormatsModule.endfHeadLine(0.0, 0.0, 0, 0, len(endfDoc), 0) ] endfMFList[1][451] = docHeader + endfDoc return endfFormatsModule.endfMFListToFinalFile(endfMFList, MAT, lineNumbers=True)
def toENDF6(self, flags, targetInfo, verbosityIndent=''): gridded = self.forms[0] data = gridded.array.constructArray() Tlist = list(gridded.axes[-1].grid) #FIXME what if grid units aren't 'K'? Elist = list(gridded.axes[-2].grid) #FIXME "" 'eV'? LT = len(Tlist) - 1 # first temperature includes the energy list: endf = [ endfFormatsModule.endfHeadLine(Tlist[0], 0, LT, 0, 1, len(data[0])) ] independentInterp = gndToENDF6.gndToENDFInterpolationFlag( gridded.axes[1].interpolation) dependentInterp = gndToENDF6.gndToENDFInterpolationFlag( gridded.axes[2].interpolation) endf += ['%11i%11i%44s' % (len(data[0]), independentInterp, '') ] # no trailing zeros endf += endfFormatsModule.endfDataList( list(itertools.chain(*zip(Elist, data[0])))) # remaining temperatures: for T, datList in zip(Tlist[1:], data[1:]): endf += [ endfFormatsModule.endfHeadLine(T, 0, dependentInterp, 0, len(datList), 0) ] endf += endfFormatsModule.endfDataList(datList) return endf
def toENDF6(self, flags, targetInfo, verbosityIndent=''): NR = 1 NP = len(self) endf = [endfFormatsModule.endfHeadLine(0, 0, 0, 0, NR, NP)] interp = gndToENDF6.gndToENDFInterpolationFlag(self.interpolation) endf += ['%11i%11i%44s' % (len(self), interp, '')] endf += endfFormatsModule.endfDataList( list(itertools.chain(*self.copyDataToXYs()))) return endf
def toENDF6(self, endfMFList, flags, targetInfo, verbosityIndent=''): ZAM, AWT = targetInfo['ZA'], targetInfo['mass'] LTHR = 2 endf = [endfFormatsModule.endfHeadLine(ZAM, AWT, LTHR, 0, 0, 0)] targetInfo[ 'characteristicCrossSection'] = self.characteristicCrossSection.getValueAs( 'b') endf += self.DebyeWaller.toENDF6(flags, targetInfo, verbosityIndent='') del targetInfo['characteristicCrossSection'] endfMFList[7][2] = endf + [99999]
def toENDF6(self, endfMFList, flags, targetInfo, verbosityIndent=''): ZAM, AWT = targetInfo['ZA'], targetInfo['mass'] LTHR, LAT, LASYM = 0, self.calculatedAtThermal, self.asymmetric endf = [endfFormatsModule.endfHeadLine(ZAM, AWT, LTHR, LAT, LASYM, 0)] # describe scattering atoms: LLN, NS = 0, len(self.scatteringAtoms) - 1 NI = 6 * (NS + 1) endf += [endfFormatsModule.endfHeadLine(0, 0, LLN, 0, NI, NS)] # principal scattering atom: atom = self.scatteringAtoms[0] endf += [ endfFormatsModule.endfDataLine([ atom.freeAtomCrossSection.getValueAs('b'), atom.e_critical, atom.mass, atom.e_max.getValueAs('eV'), 0, atom.numberPerMolecule ]) ] for atom in self.scatteringAtoms[1:]: a1 = { 'SCT': 0.0, 'free_gas': 1.0, 'diffusive_motion': 2.0 }[atom.functionalForm] endf += [ endfFormatsModule.endfDataLine([ a1, atom.freeAtomCrossSection.getValueAs('b'), atom.mass, 0, 0, atom.numberPerMolecule ]) ] # convert data form: sort first by beta, then E, then T gridded = self.S_alpha_beta.forms[0] array = gridded.array.constructArray() # 3D numpy array Tlist = list(gridded.axes[3].grid) # FIXME check grid units betas = list(gridded.axes[2].grid) alphas = list(gridded.axes[1].grid) # switch array back to ENDF ordering: 1st beta, then T, then alpha: array = array.transpose((1, 0, 2)) NR = 1 NB = len(betas) endf += [endfFormatsModule.endfHeadLine(0, 0, 0, 0, NR, NB)] #endf += endfFormatsModule.endfInterpolationList( (NB, 4) ) endf += [ '%11i%11i%44s' % (NB, 4, '') ] # FIXME add 'suppressTrailingZeros' option to endfInterpolationList LT = len(Tlist) - 1 if LT: T_interp = gndToENDF6.gndToENDFInterpolationFlag( gridded.axes[3].interpolation) else: T_interp = None beta_interp = gndToENDF6.gndToENDFInterpolationFlag( gridded.axes[2].interpolation) alpha_interp = gndToENDF6.gndToENDFInterpolationFlag( gridded.axes[1].interpolation) for index, beta in enumerate(betas): data = array[index, :, :] # 2D sub-array for this beta endf += [ endfFormatsModule.endfHeadLine(Tlist[0], beta, LT, 0, 1, len(data[0])) ] endf += ['%11i%11i%44s' % (len(alphas), alpha_interp, '') ] # no trailing zeros # For each beta, the first temperature needs to include the energy list: endf += endfFormatsModule.endfDataList( list(itertools.chain(*zip(alphas, data[0])))) # remaining temperatures: for T, datList in zip(Tlist[1:], data[1:]): endf += [ endfFormatsModule.endfHeadLine(T, beta, T_interp, 0, len(datList), 0) ] endf += endfFormatsModule.endfDataList(datList) for atom in self.scatteringAtoms: if atom.effectiveTemperature is not None: endf += atom.effectiveTemperature.toENDF6(flags, targetInfo, verbosityIndent='') endfMFList[7][4] = endf + [99999]
def toENDF6(self, endfMFList, flags, targetInfo, verbosityIndent=''): ZAM, AWT = targetInfo['ZA'], targetInfo['mass'] LTHR = 1 endf = [endfFormatsModule.endfHeadLine(ZAM, AWT, LTHR, 0, 0, 0)] endf += self.S_table.toENDF6(flags, targetInfo, verbosityIndent='') endfMFList[7][2] = endf + [99999]
def toENDF6(self, endfMFList, flags, targetInfo, verbosityIndent=''): ZAM, AWT = targetInfo['ZA'], targetInfo['mass'] NIS, ABN = 1, 1.0 ZAI = ZAM # assuming only one isotope per file # get target spin from the particle list: target = targetInfo['reactionSuite'].getParticle( targetInfo['reactionSuite'].target.name) targetInfo['spin'] = target.getSpin().value endf = [endfFormatsModule.endfHeadLine(ZAM, AWT, 0, 0, NIS, 0)] resolvedCount, unresolvedCount = 0, 0 # resolved may have multiple energy regions: if self.resolved is not None: resolvedCount = max(1, len(self.resolved.regions)) if self.unresolved is not None: unresolvedCount = 1 # resonances may only contain a scattering radius: if not (resolvedCount + unresolvedCount) and self.scatteringRadius: scatRadius = self.scatteringRadius.form lowerBound, upperBound = scatRadius.bounds endf.append(endfFormatsModule.endfHeadLine(ZAM, ABN, 0, 0, 1, 0)) endf.append( endfFormatsModule.endfHeadLine(lowerBound.getValueAs('eV'), upperBound.getValueAs('eV'), 0, 0, 0, 0)) AP = scatRadius.value.getValueAs('10*fm') endf.append( endfFormatsModule.endfHeadLine(targetInfo['spin'], AP, 0, 0, 0, 0)) endf.append(endfFormatsModule.endfSENDLineNumber()) endfMFList[2][151] = endf return # For now I'm storing the LRF/LFW flags in xml, since they are tricky to compute # LFW is a pain: only applies to unresolved, but must be written at the start of MF2 LRFurr, LFW = 0, 0 if unresolvedCount != 0: LRF_LFW = self.unresolved.evaluated.ENDFconversionFlag LRFurr, LFW = map(int, LRF_LFW.split('=')[-1].split(',')) NER = resolvedCount + unresolvedCount endf.append(endfFormatsModule.endfHeadLine(ZAI, ABN, 0, LFW, NER, 0)) for idx in range(resolvedCount): if resolvedCount == 1: region = self.resolved else: region = self.resolved.regions[idx] LRU = 1 #resolved LRF = { resonancesModule.SLBW.moniker: 1, resonancesModule.MLBW.moniker: 2, resonancesModule.RM.moniker: 3, resonancesModule.RMatrix.moniker: 7 }[region.evaluated.moniker] EL, EH = region.lowerBound.getValueAs( 'eV'), region.upperBound.getValueAs('eV') if LRF == 7: NRO = 0 else: NRO = region.evaluated.scatteringRadius.isEnergyDependent() NAPS = not (region.evaluated.calculateChannelRadius) endf.append(endfFormatsModule.endfHeadLine(EL, EH, LRU, LRF, NRO, NAPS)) endf += region.evaluated.toENDF6(flags, targetInfo, verbosityIndent) if unresolvedCount != 0: LRU = 2 #unresolved region = self.unresolved EL, EH = region.lowerBound.getValueAs( 'eV'), region.upperBound.getValueAs('eV') NRO, NAPS = 0, 0 if region.evaluated.scatteringRadius.isEnergyDependent(): NRO = 1 endf.append( endfFormatsModule.endfHeadLine(EL, EH, LRU, LRFurr, NRO, NAPS)) # pass LFW/LRF so we don't have to calculate twice: targetInfo['unresolved_LFW'] = LFW targetInfo['unresolved_LRF'] = LRFurr targetInfo['regionEnergyBounds'] = (region.lowerBound, region.upperBound) endf += region.evaluated.toENDF6(flags, targetInfo, verbosityIndent) endf.append(endfFormatsModule.endfSENDLineNumber()) endfMFList[2][151] = endf
def toENDF6(self, flags, targetInfo, verbosityIndent=''): endf = [] AP = self.scatteringRadius if AP.isEnergyDependent(): scatRadius = AP.form NR, NP = 1, len(scatRadius) endf.append(endfFormatsModule.endfHeadLine(0, 0, 0, 0, NR, NP)) endf += endfFormatsModule.endfInterpolationList( (NP, gndToENDF6.gndToENDFInterpolationFlag(scatRadius.interpolation))) endf += endfFormatsModule.endfNdDataList( scatRadius.convertAxisToUnit(0, '10*fm')) AP = 0 else: AP = AP.getValueAs('10*fm') NLS = len(self.L_values) LFW = targetInfo['unresolved_LFW'] LRF = targetInfo['unresolved_LRF'] def v(val): # get value back from PhysicalQuantityWithUncertainty if type(val) == type(None): return return val.getValueAs('eV') if LFW == 0 and LRF == 1: # 'Case A' from ENDF 2010 manual pg 70 endf.append( endfFormatsModule.endfHeadLine(targetInfo['spin'], AP, self.forSelfShieldingOnly, 0, NLS, 0)) for Lval in self.L_values: NJS = len(Lval.J_values) endf.append( endfFormatsModule.endfHeadLine(targetInfo['mass'], 0, Lval.L, 0, 6 * NJS, NJS)) for Jval in Lval.J_values: # here we only have one width per J: ave = Jval.constantWidths endf.append( endfFormatsModule.endfDataLine([ v(ave.levelSpacing), Jval.J.value, Jval.neutronDOF, v(ave.neutronWidth), v(ave.captureWidth), 0 ])) elif LFW == 1 and LRF == 1: # 'Case B' energies = self.L_values[0].J_values[ 0].energyDependentWidths.getColumn('energy', units='eV') NE = len(energies) endf.append( endfFormatsModule.endfHeadLine(targetInfo['spin'], AP, self.forSelfShieldingOnly, 0, NE, NLS)) nlines = int(math.ceil(NE / 6.0)) for line in range(nlines): endf.append( endfFormatsModule.endfDataLine(energies[line * 6:line * 6 + 6])) for Lval in self.L_values: NJS = len(Lval.J_values) endf.append( endfFormatsModule.endfHeadLine(targetInfo['mass'], 0, Lval.L, 0, NJS, 0)) for Jval in Lval.J_values: cw = Jval.constantWidths endf.append( endfFormatsModule.endfHeadLine(0, 0, Lval.L, Jval.fissionDOF, NE + 6, 0)) endf.append( endfFormatsModule.endfDataLine([ v(cw.levelSpacing), Jval.J.value, Jval.neutronDOF, v(cw.neutronWidth), v(cw.captureWidth), 0 ])) fissWidths = Jval.energyDependentWidths.getColumn( 'fissionWidthA', units='eV') for line in range(nlines): endf.append( endfFormatsModule.endfDataLine( fissWidths[line * 6:line * 6 + 6])) elif LRF == 2: # 'Case C', most common in ENDF endf.append( endfFormatsModule.endfHeadLine(targetInfo['spin'], AP, self.forSelfShieldingOnly, 0, NLS, 0)) INT = gndToENDF6.gndToENDFInterpolationFlag(self.interpolation) for Lval in self.L_values: NJS = len(Lval.J_values) endf.append( endfFormatsModule.endfHeadLine(targetInfo['mass'], 0, Lval.L, 0, NJS, 0)) for Jval in Lval.J_values: NE = len(Jval.energyDependentWidths) useConstant = not NE if useConstant: NE = 2 endf.append( endfFormatsModule.endfHeadLine(Jval.J.value, 0, INT, 0, 6 * NE + 6, NE)) endf.append( endfFormatsModule.endfDataLine([ 0, 0, Jval.competitiveDOF, Jval.neutronDOF, Jval.gammaDOF, Jval.fissionDOF ])) cws = Jval.constantWidths if useConstant: # widths are all stored in 'constantWidths' instead. get energies from parent class NE = 2 useConstant = True eLow, eHigh = targetInfo['regionEnergyBounds'] for e in (eLow, eHigh): endf.append( endfFormatsModule.endfDataLine([ v(e), v(cws.levelSpacing), v(cws.competitiveWidth), v(cws.neutronWidth), v(cws.captureWidth), v(cws.fissionWidthA) ])) else: table = [ Jval.energyDependentWidths.getColumn('energy', units='eV') ] for attr in ('levelSpacing', 'competitiveWidth', 'neutronWidth', 'captureWidth', 'fissionWidthA'): # find each attribute, in energy-dependent or constant width section column = (Jval.energyDependentWidths.getColumn( attr, units='eV') or [v(getattr(cws, attr))] * NE) if not any(column): column = [0] * NE table.append(column) for row in zip(*table): endf.append(endfFormatsModule.endfDataLine(row)) return endf
def toENDF6(self, flags, targetInfo, verbosityIndent=''): KRM = { 'SLBW': 1, 'MLBW': 2, 'Reich_Moore': 3, 'Full R-Matrix': 4 }[self.approximation] endf = [ endfFormatsModule.endfHeadLine(0, 0, self.reducedWidthAmplitudes, KRM, len(self.spinGroups), self.relativisticKinematics) ] # first describe all the particle pairs (two-body output channels) NPP = len(self.channels) endf.append(endfFormatsModule.endfHeadLine(0, 0, NPP, 0, 12 * NPP, 2 * NPP)) def getENDFtuple(spin, parity): # ENDF combines spin & parity UNLESS spin==0. Then it wants (0,+/-1) if spin.value: return (spin.value * parity.value, 0) else: return (spin.value, parity.value) def MZIP(p): # helper: extract mass, z, spin and parity from particle list #mass = p.getMass( 'amu' ) / targetInfo['reactionSuite'].getParticle( 'n' ).getMass( 'amu' ) try: nMass = targetInfo['reactionSuite'].getParticle('n').getMass('amu') except: nMass = 1.00866491578 # From ENDF102 manual, Appendix H.4 mass = p.getMass('amu') / nMass Z = p.getZ_A_SuffixAndZA()[0] I, P = getENDFtuple(p.getSpin(), p.getParity()) return mass, Z, I, P for pp in self.channels: pA, pB = pp.name.split(' + ') # get the xParticle instances for pA and pB: pA, pB = targetInfo['reactionSuite'].getParticle( pA), targetInfo['reactionSuite'].getParticle(pB) MA, ZA, IA, PA = MZIP(pA) MB, ZB, IB, PB = MZIP(pB) MT = pp.ENDF_MT PNT = pp.calculatePenetrability if PNT is None: PNT = self.calculatePenetrability SHF = pp.calculateShift if SHF is None: SHF = self.calculateShift if MT in (19, 102): PNT = 0 # special case try: Q = pp.Q.inUnitsOf('eV').value except: Q = targetInfo['reactionSuite'].getReaction(pp.channel).getQ('eV') # getQ doesn't account for residual left in excited state: for particle in targetInfo['reactionSuite'].getReaction( pp.channel).outputChannel.particles: if (hasattr(particle, 'getLevelAsFloat')): Q -= particle.getLevelAsFloat('eV') if MT == 102: Q = 0 endf.append(endfFormatsModule.endfDataLine([MA, MB, ZA, ZB, IA, IB])) endf.append(endfFormatsModule.endfDataLine([Q, PNT, SHF, MT, PA, PB])) for spingrp in self.spinGroups: AJ, PJ = getENDFtuple(spingrp.spin, spingrp.parity) KBK = spingrp.background KPS = spingrp.applyPhaseShift NCH = len(spingrp.resonanceParameters.table.columns ) - 1 # skip the 'energy' column endf.append( endfFormatsModule.endfHeadLine(AJ, PJ, KBK, KPS, 6 * NCH, NCH)) for chan in spingrp.resonanceParameters.table.columns: # which open channel does it correspond to? if chan.name == 'energy': continue name = chan.name.split(' width')[0] PPI, openChannel = [ ch for ch in enumerate(self.channels) if ch[-1].name == name ][0] PPI += 1 # 1-based index in ENDF attr = chan.attributes L = attr['L'] SCH = attr['channelSpin'] # some data may have been moved up to the channel list: BND = float( attr.get('boundaryCondition') or self.boundaryCondition) channelOverride = resonancesModule.channelOverride( openChannel.label) if openChannel.label in spingrp.overrides: channelOverride = spingrp.overrides[openChannel.label] APT = channelOverride.scatteringRadius or openChannel.scatteringRadius or PQUModule.PQU( 0, 'fm') APE = channelOverride.effectiveRadius or openChannel.effectiveRadius or APT APT = APT.getValueAs('10*fm') APE = APE.getValueAs('10*fm') if openChannel.ENDF_MT == 102: APT, APE = 0, 0 endf.append( endfFormatsModule.endfDataLine([PPI, L, SCH, BND, APE, APT])) # resonances: NRS = len(spingrp.resonanceParameters.table) NX = (NCH // 6 + 1) * NRS if NRS == 0: NX = 1 # special case endf.append(endfFormatsModule.endfHeadLine(0, 0, 0, NRS, 6 * NX, NX)) for res in spingrp.resonanceParameters.table: #resproperties = [res.energy.inUnitsOf('eV').value] + [ # w.inUnitsOf('eV').value for w in res.widths] for jidx in range(NCH // 6 + 1): endfLine = res[jidx * 6:jidx * 6 + 6] while len(endfLine) < 6: endfLine.append(0) endf.append(endfFormatsModule.endfDataLine(endfLine)) if NRS == 0: endf.append(endfFormatsModule.endfDataLine([0, 0, 0, 0, 0, 0])) return endf
def toENDF6(self, flags, targetInfo, verbosityIndent=''): endf = [] AP = getattr(self, 'scatteringRadius') if AP.isEnergyDependent(): scatRadius = AP.form NR, NP = 1, len(scatRadius) endf.append(endfFormatsModule.endfHeadLine(0, 0, 0, 0, NR, NP)) endf += endfFormatsModule.endfInterpolationList( (NP, gndToENDF6.gndToENDFInterpolationFlag(scatRadius.interpolation))) endf += endfFormatsModule.endfNdDataList( scatRadius.convertAxisToUnit(0, '10*fm')) AP = 0 else: AP = self.scatteringRadius.getValueAs('10*fm') L_list = self.resonanceParameters.table.getColumn('L') NLS = len(set(L_list)) LAD = getattr(self, 'computeAngularDistribution') or 0 NLSC = getattr(self, 'LvaluesNeededForConvergence') or 0 endf += [ endfFormatsModule.endfHeadLine(targetInfo['spin'], AP, LAD, 0, NLS, NLSC) ] table = [ self.resonanceParameters.table.getColumn('energy', units='eV'), self.resonanceParameters.table.getColumn('J') ] NE = len(table[0]) if isinstance(self, (resonancesModule.SLBW, resonancesModule.MLBW)): attrList = ('totalWidth', 'neutronWidth', 'captureWidth', 'fissionWidthA') elif isinstance(self, resonancesModule.RM): attrList = ('neutronWidth', 'captureWidth', 'fissionWidthA', 'fissionWidthB') for attr in attrList: column = self.resonanceParameters.table.getColumn(attr, units='eV') if not column: column = [0] * NE table.append(column) CS = self.resonanceParameters.table.getColumn('channelSpin') if CS is not None: # ENDF hack: J<0 -> use lower available channel spin targetSpin = targetInfo['spin'] CS = [2 * (cs - targetSpin) for cs in CS] Js = [v[0] * v[1] for v in zip(table[1], CS)] table[1] = Js table = zip(*table) for L in set(L_list): APL = 0 if self.scatteringRadius.isLdependent( ) and L in self.scatteringRadius.form.lvals: APL = self.scatteringRadius.getValueAs('10*fm', L=L) resonances = [table[i] for i in range(NE) if L_list[i] == L] NRS = len(resonances) endf.append( endfFormatsModule.endfHeadLine(targetInfo['mass'], APL, L, 0, 6 * NRS, NRS)) for row in resonances: endf.append(endfFormatsModule.endfDataLine(row)) return endf
def toENDF6( self, style, flags, verbosityIndent = '', covarianceSuite = None ) : evaluatedStyle = self.styles.getEvaluatedStyle( ) if( evaluatedStyle is None ) : raise ValueError( 'no evaluation style found' ) if( flags['verbosity'] >= 10 ) : print '%s%s' % ( verbosityIndent, self.inputParticlesToReactionString( suffix = " -->" ) ) verbosityIndent2 = verbosityIndent + ' ' * ( len( self.inputParticlesToReactionString( suffix = " -->" ) ) + 1 ) projectile, target = self.projectile, self.target projectileZA = projectile.getZ_A_SuffixAndZA( )[-1] IPART = projectileZA if( projectile.name == 'e-' ) : IPART = 11 targetZA, MAT = endf_endl.ZAAndMATFromParticleName( target.name ) targetZ, targetA = divmod( targetZA, 1000 ) targetInfo = processingInfoModule.tempInfo( ) targetInfo['style'] = style targetInfo['reactionSuite'] = self targetInfo['ZA'] = targetZA if( self.particles.hasID( 'n' ) ) : # Need neutron mass in eV/c**2, but it may not be in the particle list. targetInfo['neutronMass'] = self.getParticle( 'n' ).getMass( 'eV/c**2' ) else : neutronAmu = masses.getMassFromZA( 1 ) targetInfo['neutronMass'] = PQU.PQU( neutronAmu, 'amu' ).getValueAs('eV/c**2') if( isinstance( target, fudge.gnd.xParticle.element ) ) : targetInfo['mass'] = elementalMass[targetZA] else : targetInfo['mass'] = target.getMass( 'eV/c**2' ) / targetInfo['neutronMass'] try : targetInfo['LIS'] = target['levelIndex'] except : targetInfo['LIS'] = 0 targetInfo['metastables'] = [] targetInfo['LISO'] = 0 for key, alias in self.aliases.items( ) : if( alias.hasAttribute( 'nuclearMetaStable' ) ) : targetInfo['metastables'].append( alias.getValue() ) if( alias.getValue() == target.name ) : targetInfo['LISO'] = int( alias.getAttribute( 'nuclearMetaStable' ) ) MAT += targetInfo['LISO'] if( self.MAT is not None ) : MAT = self.MAT ITYPE = 0 # Other ITYPE sublibraries not yet supported. BRB is this still true for reaction in self.reactions : if( 500 <= reaction.ENDF_MT < 573 ) : ITYPE = 3 targetInfo['crossSectionMF'] = { 0 : 3, 3 : 23 }[ITYPE] targetInfo['delayedRates'] = [] targetInfo['totalDelayedNubar'] = None targetInfo['MTs'], targetInfo['MF8'], targetInfo['LRs'] = {}, {}, {} endfMFList = { 1 : { 451 : [] }, 2 : {}, 3 : {}, 4 : {}, 5 : {}, 6 : {}, 8 : {}, 9 : {}, 10 : {}, 12 : {}, 13 : {}, 14 : {}, 15 : {}, 23 : {}, 26 : {}, 27 : {}, 31 : {}, 32 : {}, 33 : {}, 34 : {}, 35 : {}, 40 : {} } if( self.resonances is not None ) : # Add resonances, independent of reaction channels self.resonances.toENDF6( endfMFList, flags, targetInfo, verbosityIndent=verbosityIndent2 ) targetInfo['production_gammas'] = {} for reaction in self : reaction.toENDF6( endfMFList, flags, targetInfo, verbosityIndent = verbosityIndent2 ) gndToENDF6Module.upDateENDFMF8Data( endfMFList, targetInfo ) for MT, production_gammas in targetInfo['production_gammas'].items( ) : MF, production_gammas = production_gammas[0], production_gammas[1:] for productionReaction in production_gammas : gammas = [ gamma for gamma in productionReaction.outputChannel ] targetInfo['crossSection'] = productionReaction.crossSection[targetInfo['style']] gndToENDF6Module.gammasToENDF6_MF12_13( MT, MF, endfMFList, flags, targetInfo, gammas ) for particle in self.particles : # gamma decay data. if( isinstance( particle, fudge.gnd.xParticle.isotope ) ) : for level in particle : if( level.gammas ) : # non-empty gamma information for baseMT in [ 50, 600, 650, 700, 750, 800 ] : residualZA = endf_endl.ENDF_MTZAEquation( projectileZA, targetZA, baseMT )[0][-1] if( nuclear.nucleusNameFromZA( residualZA ) == particle.name ) : break level.toENDF6( baseMT, endfMFList, flags, targetInfo ) MFs = sorted( endfMFList.keys( ) ) endfList = [] totalNubar = None totalDelayedNubar = targetInfo['totalDelayedNubar'] if( 455 in endfMFList[5] ) : MF5MT455s = endfMFList[5][455] endfMFList[1][455] = [ endfFormatsModule.endfHeadLine( targetZA, targetInfo['mass'], 0, 2, 0, 0 ) ] # Currently, only LDG = 0, LNU = 2 is supported. endfMFList[1][455] += [ endfFormatsModule.endfHeadLine( 0, 0, 0, 0, len( targetInfo['delayedRates'] ), 0 ) ] endfMFList[1][455] += endfFormatsModule.endfDataList( targetInfo['delayedRates'] ) multiplicityModule.fissionNeutronsToENDF6( 455, totalDelayedNubar, endfMFList, flags, targetInfo ) MF5MT455List = [ endfFormatsModule.endfHeadLine( targetZA, targetInfo['mass'], 0, 0, len( MF5MT455s ), 0 ) ] for MF5MT455 in MF5MT455s : MF5MT455List += MF5MT455 if( len( MF5MT455s ) == 0 ) : del endfMFList[5][455] else : endfMFList[5][455] = MF5MT455List + [ endfFormatsModule.endfSENDLineNumber( ) ] if( 'promptNubar' in targetInfo.dict ) : promptNubar = targetInfo['promptNubar'] multiplicityModule.fissionNeutronsToENDF6( 456, promptNubar, endfMFList, flags, targetInfo ) totalNubar = promptNubar try : if( not( totalDelayedNubar is None ) ) : totalNubar = totalNubar + totalDelayedNubar except : # The following is a kludge for some "bad" data. if( ( totalNubar.domainMax( unitTo = 'MeV' ) == 30. ) and ( totalDelayedNubar.domainMax( unitTo = 'MeV' ) == 20. ) ) : totalDelayedNubar[-1] = [ totalNubar.domainMax( ), totalDelayedNubar.getValue( totalDelayedNubar.domainMax( ) ) ] totalNubar = totalNubar + totalDelayedNubar elif( 'totalNubar' in targetInfo.dict ) : totalNubar = targetInfo['totalNubar'] if( totalNubar is not None ) : multiplicityModule.fissionNeutronsToENDF6( 452, totalNubar, endfMFList, flags, targetInfo ) if( covarianceSuite ) : covarianceSuite.toENDF6( endfMFList, flags, targetInfo ) endfDoc = self.documentation.get( 'endfDoc' ) if( endfDoc is None ) : docHeader2 = [ ' %2d-%-2s-%3d LLNL EVAL-OCT03 Unknown' % ( targetZ, fudge.particles.nuclear.elementSymbolFromZ( targetZ ), targetA ), ' DIST-DEC99 19990101 ', '----ENDL MATERIAL %4d' % MAT, '-----INCIDENT %s DATA' % { 1 : 'NEUTRON', 1001 : 'PROTON', 1002 : 'DEUTERON', 1003 : 'TRITON', 2003 : 'HELION', 2004 : 'ALPHA' }[projectileZA], '------ENDF-6 FORMAT' ] endfDoc = [ 'LLNL ENDL file translated to ENDF6 by FUDGE.', '' ' ************************ C O N T E N T S ***********************' ] else : docHeader2 = [] endfDoc = endfDoc.getLines( ) # update the documentation, including metadata on first 4 lines: try : self.getReaction( 'fission' ) LFI = True except KeyError : LFI = False LRP = -1 if( self.resonances is not None ) : if( self.resonances.scatteringRadius ) : LRP = 0 elif( self.resonances.reconstructCrossSection ) : LRP = 1 elif( self.resonances.unresolved and not( self.resonances.resolved ) and self.resonances.unresolved.tabulatedWidths.forSelfShieldingOnly ) : LRP = 1 else : LRP = 2 EMAX = max( [ reaction.crossSection.domainMax( unitTo = 'eV' ) for reaction in self.reactions ] ) temperature = self.styles[style].temperature.getValueAs( 'K' ) library = evaluatedStyle.library version = evaluatedStyle.version if( library == 'ENDL' ) : # Additional ENDF meta-data. If the library is unknown, use NLIB = -1 NVER, LREL, NMOD = 1, 1, 1 NLIB = -1 else : NVER, LREL, NMOD = map( int, version.split( '.' ) ) # Version stored as '7.2.1' NLIB = { "ENDF/B" : 0, "ENDF/A" : 1, "JEFF" : 2, "EFF" : 3, "ENDF/B (HE)" : 4, "CENDL" : 5, "JENDL" : 6, "SG-23" : 21, "INDL/V" : 31, "INDL/A" : 32, "FENDL" : 33, "IRDF" : 34, "BROND (IAEA version)" : 35, "INGDB-90" : 36, "FENDL/A" : 37, "BROND" : 41 }.get( library, -1 ) NFOR = 6 # ENDF-6 format NSUB = 10 * IPART + ITYPE LDRV = 0 STA = 0 if( isinstance( self.target, fudge.gnd.xParticle.nuclearLevel ) or self.target.attributes.get( 'unstable' ) ) : STA = 1 if( targetInfo['LISO'] ) : STA = 1 levelIndex, level_eV = 0, 0. if( hasattr( self.target, 'getLevelIndex' ) ) : levelIndex, level_eV = self.target.getLevelIndex( ), self.target.getLevelAsFloat( 'eV' ) docHeader = [ endfFormatsModule.endfHeadLine( targetZA, targetInfo['mass'], LRP, LFI, NLIB, NMOD ), endfFormatsModule.endfHeadLine( level_eV, STA, levelIndex, targetInfo['LISO'], 0, NFOR ), endfFormatsModule.endfHeadLine( self.projectile.getMass( 'eV/c**2' ) / targetInfo['neutronMass'], EMAX, LREL, 0, NSUB, NVER ), endfFormatsModule.endfHeadLine( temperature, 0, LDRV, 0, len( endfDoc ), -1 ) ] new_doc = fudge.gnd.documentation.documentation( 'endf', '\n'.join( docHeader + docHeader2 + endfDoc ) ) endfMFList[1][451] += endfFormatsModule.toEndfStringList( new_doc ) return( endfFormatsModule.endfMFListToFinalFile( endfMFList, MAT, lineNumbers = True ) )
def upDateENDF_MT_MF8Data(MT, endfMFList, targetInfo): reactionSuite = targetInfo['reactionSuite'] MF8Channels = targetInfo['MF8'][MT] ZA, mass = targetInfo['ZA'], targetInfo['mass'] LIS, LISO, NO, NS = targetInfo['LIS'], targetInfo['LISO'], 1, len( MF8Channels) firstReaction = MF8Channels[0] residual = firstReaction.outputChannel[0] crossSection_ = firstReaction.crossSection[ targetInfo['style']] # LMF determines which MF section to write to. if (isinstance(crossSection_, crossSectionModule.reference)): multiplicity = residual.multiplicity[targetInfo['style']] if (isinstance(multiplicity, multiplicityModule.constant1d)): LMF = 3 elif (isinstance(multiplicity, multiplicityModule.reference)): LMF = 6 else: LMF = 9 else: LMF = 10 level = 0 if (hasattr(residual, 'getLevelAsFloat')): level = residual.getLevelAsFloat('eV') endfMFList[8][MT] = [ endfFormatsModule.endfHeadLine(ZA, mass, LIS, LISO, NS, NO) ] if (LMF not in [3, 6]): endfMFList[LMF][MT] = [ endfFormatsModule.endfHeadLine(ZA, mass, LIS, 0, NS, 0) ] for reaction in MF8Channels: outputChannel = reaction.outputChannel if (len(outputChannel) != 1): raise Exception( 'Currently, production channel can only have one product; not %d' % len(outputChannel)) product = outputChannel[0] particle = reactionSuite.PoPs[product.id] ZAP = miscPoPsModule.ZA(particle) QI = outputChannel.getConstantQAs('eV', final=True) LFS2, level2 = 0, 0 if (isinstance(particle, nuclearLevelModule.particle)): LFS2 = particle.intIndex level2 = particle.energy[0].float('eV') QM = QI + level2 endfMFList[8][MT].append( endfFormatsModule.endfHeadLine(ZAP, level2, LMF, LFS2, 0, 0)) if ( LMF == 9 ): # Currenty, multiplicity.toENDF6List only has one interpolation and its linear. multiplicity = product.multiplicity[targetInfo['style']] interpolationFlatData, nPoints, multiplicityList = multiplicity.toENDF6List( targetInfo) endfMFList[LMF][MT].append( endfFormatsModule.endfHeadLine(QM, QI, ZAP, LFS2, len(interpolationFlatData) / 2, nPoints)) endfMFList[LMF][MT] += endfFormatsModule.endfInterpolationList( interpolationFlatData) endfMFList[LMF][MT] += multiplicityList elif (LMF == 10): interpolationFlatData, flatData = reaction.crossSection[ targetInfo['style']].toENDF6Data(MT, endfMFList, targetInfo, level2) endfMFList[LMF][MT].append( endfFormatsModule.endfHeadLine(QM, QI, ZAP, LFS2, len(interpolationFlatData) / 2, len(flatData) / 2)) endfMFList[LMF][MT] += endfFormatsModule.endfInterpolationList( interpolationFlatData) endfMFList[LMF][MT] += endfFormatsModule.endfDataList(flatData) endfMFList[8][MT].append(endfFormatsModule.endfSENDLineNumber()) if (LMF not in [3, 6]): endfMFList[LMF][MT].append(endfFormatsModule.endfSENDLineNumber())