Source code for fudge.gnds.channelData.fissionEnergyReleased

# <<BEGIN-copyright>>
# <<END-copyright>>

"""
This module contains a special type of Q-value, unique to fission reactions.
Fission releases energy several different ways (neutrons, gammas, etc.), and it's useful to subdivide the Q-value
into these different terms.
"""

# FIXME this is really a form of Q-value. Should it be defined in Q.py instead?

import xData.ancestry as ancestryModule
import xData.standards as standardsModule
import xData.axes as axesModule
import xData.series1d as series1dModule
import xData.XYs as XYsModule
import xData.gridded as griddedModule
import xData.uncertainties as uncertaintiesModule

__metaclass__ = type

[docs]def defaultAxes( energyUnit ) : axes = axesModule.axes( rank = 2 ) axes[0] = axesModule.axis( 'energy_out', 0, energyUnit ) axes[1] = axesModule.axis( 'energy_in', 1, energyUnit ) return( axes )
[docs]class polynomial1d( series1dModule.polynomial1d ): def __init__( self, coefficients, domainMin, domainMax, lowerIndex = 0, axes = None, index = None, valueType = standardsModule.types.float64Token, value = None, label = None, sep = ' ', coefficientUncertainties = None ): series1dModule.polynomial1d.__init__( self, coefficients=coefficients, domainMin=domainMin, domainMax=domainMax, lowerIndex=lowerIndex, axes=axes, index=index, valueType=valueType, value=value, label=label, sep=sep ) if coefficientUncertainties is not None: self.uncertainty = uncertaintiesModule.uncertainty( functional = series1dModule.polynomial1d( coefficientUncertainties, domainMin, domainMax, axes=axes ) )
[docs] def processMultiGroup( self, style, tempInfo, indent ) : return( self.toPointwise_withLinearXYs( accuracy = 1e-5, upperEps = 1e-8 ).processMultiGroup( style, tempInfo, indent ) )
[docs] def toLinearXYsClass( self ) : return( XYs1d )
[docs]class XYs1d( XYsModule.XYs1d ) :
[docs] def processMultiGroup( self, style, tempInfo, indent ) : from fudge.processing import miscellaneous as miscellaneousModule multiGroup = miscellaneousModule.groupFunctionCrossSectionAndFlux( gridded1d, style, tempInfo, self ) multiGroup.label = None return( multiGroup )
[docs]class gridded1d( griddedModule.gridded1d ) : pass
[docs]class fissionEnergyReleaseTerm( ancestryModule.ancestry ): """ Base class for all types of fission energy release. """ ancestryMembers = ( 'data', ) def __init__( self, data ) : ancestryModule.ancestry.__init__( self ) self.data = data @property def data(self): return self.__data @data.setter def data( self, value ) : if not isinstance( value, ( XYs1d, polynomial1d, gridded1d ) ) : raise TypeError( 'Invalid class "%s" for fissionEnergyReleaseTerm' % type(value) ) value.setAncestor(self) self.__data = value
[docs] def check(self, info): from fudge.gnds import warning warnings = [] linearized = self.data.toPointwise_withLinearXYs(accuracy=1e-6) if linearized.rangeMin < 0: warnings.append( warning.badFissionEnergyRelease( worstCase=linearized.rangeMin, obj=self) ) if not 0.1 < linearized.rangeMax / linearized.rangeMin < 10: warnings.append( warning.badFissionEnergyRelease( worstCase=linearized.rangeMax, obj=self) ) return warnings
[docs] def convertUnits( self, unitMap ) : "See documentation for reactionSuite.convertUnits." self.data.convertUnits( unitMap )
[docs] def processMultiGroup( self, style, tempInfo, indent ) : return( self.__class__( self.data.processMultiGroup( style, tempInfo, indent ) ) )
[docs] def toXMLList( self, indent="", **kwargs ): indent2 = indent + kwargs.get('incrementalIndent',' ') xmllist = ['%s<%s>' % (indent, self.moniker)] xmllist += self.data.toXMLList( indent2, **kwargs ) xmllist[-1] += '</%s>' % self.moniker return xmllist
[docs] @classmethod def parseXMLNode( cls, element, xPath, linkData ): xPath.append( element.tag ) dataClass = { XYs1d.moniker: XYs1d, polynomial1d.moniker: polynomial1d, gridded1d.moniker: gridded1d }.get( element[0].tag, None ) data = dataClass.parseXMLNode( element[0], xPath, linkData ) FERT = cls( data ) xPath.pop() return FERT
[docs]class promptProductKE( fissionEnergyReleaseTerm ): moniker = 'promptProductKE'
[docs]class promptNeutronKE( fissionEnergyReleaseTerm ): moniker = 'promptNeutronKE'
[docs]class delayedNeutronKE( fissionEnergyReleaseTerm ): moniker = 'delayedNeutronKE'
[docs]class promptGammaEnergy( fissionEnergyReleaseTerm ): moniker = 'promptGammaEnergy'
[docs]class delayedGammaEnergy( fissionEnergyReleaseTerm ): moniker = 'delayedGammaEnergy'
[docs]class delayedBetaEnergy( fissionEnergyReleaseTerm ): moniker = 'delayedBetaEnergy'
[docs]class neutrinoEnergy( fissionEnergyReleaseTerm ): moniker = 'neutrinoEnergy'
[docs]class nonNeutrinoEnergy( fissionEnergyReleaseTerm ): moniker = 'nonNeutrinoEnergy'
[docs]class totalEnergy( fissionEnergyReleaseTerm ): moniker = 'totalEnergy'
[docs]class field: """ Descriptor to ensure ancestry is set when adding energy release terms to fissionEnergyReleased class. """ def __init__(self, Class): self.Class = Class self.fname = '__' + Class.moniker def __get__(self, instance, owner): return getattr( instance, self.fname, None ) def __set__(self, instance, value): if not isinstance( value, self.Class ): raise TypeError( "Incorrect type: expected %s, got %s" % (self.Class.moniker, type(value)) ) value.setAncestor(instance) setattr( instance, self.fname, value )
[docs]class fissionEnergyReleased( ancestryModule.ancestry ) : """ Store average energy released to different types of fission products. (prompt and delayed neutrons, prompt / delayed gammas, betas, neutrinos, etc.) Each term is currently (when translating from ENDF) stored as a polynomial expansion, although we expect to also see XYs1d representations in future evaluations """ moniker = 'fissionEnergyReleased' ancestryMembers = ( 'promptProductKE', 'promptNeutronKE', 'delayedNeutronKE', 'promptGammaEnergy', 'delayedGammaEnergy', 'delayedBetaEnergy', 'neutrinoEnergy', 'nonNeutrinoEnergy', 'totalEnergy' ) promptProductKE = field( promptProductKE ) promptNeutronKE = field( promptNeutronKE ) delayedNeutronKE = field( delayedNeutronKE ) promptGammaEnergy = field( promptGammaEnergy ) delayedGammaEnergy = field( delayedGammaEnergy ) delayedBetaEnergy = field( delayedBetaEnergy ) neutrinoEnergy = field( neutrinoEnergy ) nonNeutrinoEnergy = field( nonNeutrinoEnergy ) totalEnergy = field( totalEnergy ) def __init__( self, label, **kwargs ) : ancestryModule.ancestry.__init__( self ) self.label = label for key in kwargs.keys() : if key in self.ancestryMembers: setattr( self, key, kwargs.pop( key, None ) ) if kwargs: raise TypeError("fissionEnergyReleased received unexpected argument(s): '%s'" % kwargs.keys()) def __iter__( self ) : for term in self.ancestryMembers : yield getattr( self, term )
[docs] def convertUnits( self, unitMap ) : "See documentation for reactionSuite.convertUnits." for term in self.ancestryMembers : fwarnings = getattr( self, term ).convertUnits( unitMap )
[docs] def check( self, info ) : from fudge.gnds import warning warnings = [] for term in self.ancestryMembers: fwarnings = getattr(self, term).check( info ) if fwarnings: warnings.append( warning.context('%s:' % term, fwarnings) ) return warnings
[docs] def processMultiGroup( self, style, tempInfo, indent ) : kwargs = {} for term in self.ancestryMembers : kwargs[term] = getattr( self, term ).processMultiGroup( style, tempInfo, indent ) return( fissionEnergyReleased( style.label, **kwargs ) )
[docs] def toPointwise_withLinearXYs( self, **kwargs ) : return( self.promptProductKE.data.toPointwise_withLinearXYs( **kwargs ) )
[docs] def toXML( self, indent = "", **kwargs ) : return( '\n'.join( self.toXMLList( indent = indent, **kwargs ) ) )
[docs] def toXMLList( self, indent="", **kwargs ): indent2 = indent+" " xmlList = ['%s<%s label="%s">' % ( indent, self.moniker, self.label )] for term in self.ancestryMembers: xmlList += getattr(self, term).toXMLList( indent2, **kwargs ) xmlList[-1] += "</%s>" % self.moniker return xmlList
[docs] @staticmethod def parseXMLNode( element, xPath, linkData ): """Parse <fissionEnergyReleased> from xml.""" xPath.append( element.tag ) children = {} childClasses = dict( [(Class.moniker, Class) for Class in ( promptProductKE, promptNeutronKE, delayedNeutronKE, promptGammaEnergy, delayedGammaEnergy, delayedBetaEnergy, neutrinoEnergy, nonNeutrinoEnergy, totalEnergy ) ] ) for child in element: children[ child.tag ] = childClasses[ child.tag ].parseXMLNode( child, xPath, linkData ) fer = fissionEnergyReleased( label = element.get( "label" ), **children ) xPath.pop() return fer