Пример #1
0
def toENDL(incoherentElastic, energyMin_MeV, energyMax_MeV, temperature_MeV):

    sigma_b = incoherentElastic.characteristicCrossSection.getValueAs('b')
    temperature = PQUModule.PQU(temperature_MeV, 'MeV/k').getValueAs(
        incoherentElastic.DebyeWaller.axes[1].unit)
    debyeWallerPrime = incoherentElastic.DebyeWaller.evaluate(temperature)
    debyeWallerPrime = PQUModule.PQU(
        debyeWallerPrime,
        incoherentElastic.DebyeWaller.axes[0].unit).getValueAs('1/MeV')

    parameters = {'debyeWallerPrime': debyeWallerPrime, 'sigma_b': sigma_b}

    crossSection = [[energy, crossSectionAtEnergy(energy, parameters)]
                    for energy in [energyMin_MeV, energyMax_MeV]]
    crossSection = fudgemath.thickenXYList(crossSection,
                                           evaluator(crossSectionAtEnergy,
                                                     parameters),
                                           biSectionMax=12)

    PmuGivenE = []
    for energy, sigma in crossSection:
        parameters['energy'] = energy
        PmuForEachE = [[mu, incoherentElasticPmuGivenE(mu, parameters)]
                       for mu in [-1., 1.]]
        PmuForEachE = fudgemath.thickenXYList(PmuForEachE,
                                              evaluator(
                                                  incoherentElasticPmuGivenE,
                                                  parameters),
                                              biSectionMax=12)
        PmuGivenE.append([energy, PmuForEachE])

    return (crossSection, PmuGivenE, None)
Пример #2
0
    def toPointwise_withLinearXYs(self, accuracy=None, lowerEps=0, upperEps=0):

        from fudge.gnd import product
        from fudge.gnd import reactionSuite
        from fudge.gnd.reactions import reaction
        from fudge.gnd import channels
        from fudge.core.math import fudgemath

        class tester:
            def __init__(self, relativeTolerance, absoluteTolerance, n):

                self.relativeTolerance = relativeTolerance
                self.absoluteTolerance = absoluteTolerance
                self.n = n
                self.setEMax_i(1)

            def evaluateAtX(self, x):

                return (math.sqrt(x) * math.pow(
                    (self.EMax_i - x), 0.5 * (3. * self.n - 5.)))

            def setEMax_i(self, EMax_i):

                self.EMax_i = EMax_i

        p = self.findClassInAncestry(product.product)
        numberOfProductsMasses, massUnit = self.numberOfProductsMasses.getValue(
        ), self.numberOfProductsMasses.getUnitName()
        productMass = p.getMass(massUnit)

        r = self.findClassInAncestry(reaction.reaction)
        energyUnit = r.domainUnit()
        EMin, EMax = r.domain()

        rs = self.findClassInAncestry(reactionSuite.reactionSuite)
        projectileMass, targetMass = rs.projectile.getMass(
            massUnit), rs.target.getMass(massUnit)

        c = self.findClassInAncestry(channels.channel)
        Q = c.Q.getConstantAs(energyUnit)

        axes = XYs2d.defaultAxes(standardsModule.frames.centerOfMassToken,
                                 energyUnit=energyUnit)
        pwl = XYs2d(axes)

        t = tester(accuracy, 1e-10, self.numberOfProducts)
        n = 21
        f = math.pow(EMax / EMin, 1. / n)
        E_ins = [EMin * f**idx for idx in xrange(n)]
        E_ins[-1] = EMax  # Fix possible round off issue.
        for idx, E_in in enumerate(E_ins):
            Ea = targetMass / (targetMass + projectileMass) * E_in + Q
            EMax_i = Ea * (numberOfProductsMasses -
                           productMass) / numberOfProductsMasses
            if (EMax_i < 0): EMax_i = 1e-5  # This is a kludge
            t.setEMax_i(EMax_i)
            t.absoluteTolerance = 1e-10 * t.evaluateAtX(0.5 * EMax_i)
            data = fudgemath.thickenXYList([[0., 0.], [EMax_i, 0.]],
                                           t,
                                           biSectionMax=10)
            data = XYs1d(data, accuracy=accuracy, value=E_in)
            data.normalize(insitu=True)
            pwl.append(data)
        return (pwl)
Пример #3
0
    def toPointwise_withLinearXYs(self,
                                  accuracy=0.001,
                                  lowerEps=0,
                                  upperEps=0):

        from fudge.core.math import fudgemath

        class tester:
            def __init__(self, relativeTolerance, absoluteTolerance,
                         evaluateAtX):

                self.relativeTolerance = relativeTolerance
                self.absoluteTolerance = absoluteTolerance
                self.evaluateAtX_ = evaluateAtX
                self.setParameter1(1.)
                self.setParameter2(1.)

            def evaluateAtX(self, x):

                return (self.evaluateAtX_(self, x))

            def setParameter1(self, p1):

                self.p1 = p1

            def setParameter2(self, p2):

                self.p2 = p2

        parameter1 = self.data.parameter1.data.toPointwise_withLinearXYs(
            accuracy=None, lowerEps=lowerEps, upperEps=upperEps)
        axes = XYs2d.defaultAxes()
        pwl = XYs2d(axes=axes)
        one_eV = PQU.PQU('1 eV').getValueAs(axes[-1].unit)

        t = tester(accuracy, 1e-10, self.evaluateAtX)
        parameter2 = self.data.parameter2
        if (parameter2 is not None):
            parameter2 = parameter2.data.toPointwise_withLinearXYs(
                accuracy=None, lowerEps=lowerEps, upperEps=upperEps)
        for i, E_in_p1 in enumerate(parameter1):
            E_in, p1 = E_in_p1
            EpMax = E_in - self.data.U.getValue()
            EpMin = 0.  # Only used with debugging.
            if (EpMax == 0.):
                if (i != 0):
                    raise Exception("i = %d, E_in = %s, U = %s" %
                                    (E_in, self.data.U.getValue()))
                EpMax = E_in * 1e-6
                if (EpMax == 0.):
                    EpMax = parameter1[1][
                        1] * 1e-6  # This and the next line are arbitary.
                if (EpMax > 1e-3): EpMax = 2e-5
                data = [[EpMin, 1.], [EpMax, 1e-10]]
            else:
                t.setParameter1(p1)
                if (parameter2 is not None):
                    t.setParameter2(parameter2.evaluate(E_in))
                level, data = 0, [[EpMin, t.evaluateAtX(EpMin)],
                                  [EpMax, t.evaluateAtX(EpMax)]]
                while (data[1][1] < 1e-10
                       ):  # Fill in some tail points while they are < 1e-10
                    level, EpMax = level + 1, 0.5 * EpMax
                    data.insert(1, [EpMax, t.evaluateAtX(EpMax)])
                    if (level > 10): break
                if (data[0][0] < one_eV):
                    if (data[1][0] > 1e6 * one_eV):
                        data.insert(
                            1, [1e6 * one_eV,
                                t.evaluateAtX(1e6 * one_eV)])
                    if (data[1][0] > 1e3 * one_eV):
                        data.insert(
                            1, [1e3 * one_eV,
                                t.evaluateAtX(1e3 * one_eV)])
                    if (data[1][0] > one_eV):
                        data.insert(1, [one_eV, t.evaluateAtX(one_eV)])
                data = fudgemath.thickenXYList(data, t, biSectionMax=10)
            data = XYs1d(data=data, value=E_in)
            data.normalize(insitu=True)
            pwl.append(data)
        return (pwl)
Пример #4
0
    def calculate_a( self, energy_in, energy_out_cmMin, energy_out_cmMax, accuracy = 1e-6 ) :

        from fudge.core.math import fudgemath
        from fudge.particles import nuclear

        def getParticleData( particle ) :

            Z, A, suffix, ZA = particle.getZ_A_SuffixAndZA( )
            return( particle.name, Z, max( 0, A - Z ), A, particle.getMass( 'MeV/c**2' ) )

        energyFactor = PQU.PQU( 1, 'MeV' ).getValueAs( self.fSubform.data.axes[-1].unit )
        projectile = self.findAttributeInAncestry( 'projectile' )
        target = self.findAttributeInAncestry( 'target' )
        product = self.findClassInAncestry( fudge.gnd.product.product ).particle
        name_a, Z_a, N_a, A_a, AWRa = getParticleData( projectile )
        name_A, Z_A, N_A, A_A, AWRA = getParticleData( target )
        name_b, Z_b, N_b, A_b, AWRb = getParticleData( product )
        Z_C, N_C = Z_a + Z_A, N_a + N_A
        if( N_A == 0 ) : N_C = 0
        Z_B, N_B = Z_C - Z_b, max( 0, N_C - N_b )
        A_B = Z_B + N_B
        if( N_B == 0 ) : A_B = 0
        particles = self.findClassInAncestry( fudge.gnd.reactionSuite.reactionSuite ).particles
        residual = particles.getParticle( nuclear.nucleusNameFromZA( 1000 * Z_B + A_B ) )
        AWRB = residual.getMass( 'MeV/c**2' )
        Ma, Ia = self.KalbachMann_a_parameters[name_a]['M'], self.KalbachMann_a_parameters[name_a]['I']
        mb, Ib = self.KalbachMann_a_parameters[name_b]['m'], self.KalbachMann_a_parameters[name_b]['I']
        Sa, Sb = energyFactor * self.calculate_S_ab_MeV( Z_A, N_A, Z_C, N_C, Ia ), energyFactor * self.calculate_S_ab_MeV( Z_B, N_B, Z_C, N_C, Ib )

        C1, C2, C3 = 0.04 / energyFactor, 1.8e-6 / energyFactor**3, 6.7e-7 / energyFactor**4

        ea = energy_in * AWRA / ( AWRa + AWRA ) + Sa

        R1, R3 = 130 * energyFactor, 41 * energyFactor                        # MeV to self's energy units.
        if( ea < R1 ) : R1 = ea
        if( ea < R3 ) : R3 = ea

        def calculate_a2( energy_out_cm ) :

            eb = energy_out_cm * ( AWRb + AWRB ) / AWRB + Sb
            X1, X3 = R1 * eb / ea, R3 * eb / ea
            return( X1 * ( C1 + C2 * X1 * X1 ) + C3 * Ma * mb * X3**4 )

        class thicken_a :

            def __init__( self, calculate_a2, relativeTolerance, absoluteTolerance ) :

                self.calculate_a2 = calculate_a2
                self.relativeTolerance = relativeTolerance
                self.absoluteTolerance = absoluteTolerance

            def evaluateAtX( self, x ) :

                return( self.calculate_a2( x ) )

        a = [ [ energy_out_cmMin, calculate_a2( energy_out_cmMin ) ], [ energy_out_cmMax, calculate_a2( energy_out_cmMax ) ] ]
        a = fudgemath.thickenXYList( a, thicken_a( calculate_a2, accuracy, 1e-10 ) )

        axes = axesModule.axes( )
        axes[0] = axesModule.axis( 'a', 0, '' )
        axes[1] = self.fSubform.data.axes[1].copy( )
        return( XYsModule.XYs1d( data = a, axes = axes, accuracy = accuracy ) )
Пример #5
0
    def calculateAverageProductData( self, style, indent = '', **kwargs ) :

        def sqrtE_MuComAverage( f, r, a, tolerance ) :          # This still needs to be tested.?????????

            def u_mu_func( energy_out, parameters ) :

                a = parameters[2].evaluate( energy_out )
                if( abs( a ) < 1e-2 ) :
                    a2 = a * a
                    csa = a * ( 315. + a2 * ( -21. + 2. * a2 ) ) / 945.
                else :
                    csa = math.cosh( a ) / math.sinh( a ) - 1. / a
                return( math.sqrt( energy_out ) * parameters[0].evaluate( energy_out ) * parameters[1].evaluate( energy_out ) * csa )

            epMin = max( f.domainMin( ), r.domainMin( ), a.domainMin( ) )
            epMax = min( f.domainMax( ), r.domainMax( ), a.domainMax( ) )
            _sqrtE_mu_com, quadInfo = miscellaneous.GnG_adaptiveQuadrature( u_mu_func, epMin, epMax, [ f, r, a ], miscellaneous.GaussQuadrature2, tolerance )
            return( _sqrtE_mu_com )

        def calculateAverageProductDataAtEnergy( self, Ein ) :

            f, r, a = self.KalbackMannSelf.getFRAatEnergy_asLinearPointwise( Ein )
            E_com = self.m1x * Ein
            Ex_com = f.integrateWithWeight_x( )
            _sqrtE_mu_com = sqrtE_MuComAverage( f, r, a, energyAccuracy )
            E_mu = 2. * math.sqrt( self.m1x * Ein ) * _sqrtE_mu_com
            multi = self.multiplicity.getValue( Ein )
            return( multi * ( E_com + Ex_com + E_mu ), multi * math.sqrt( 2. * massx ) * ( math.sqrt( m1x * Ein ) + _sqrtE_mu_com ) )

        class calculateDepositionInfo :

            def __init__( self, KalbackMannSelf, multiplicity, massx, m1x ) :

                self.KalbackMannSelf = KalbackMannSelf
                self.multiplicity = multiplicity
                self.massx = massx
                self.m1x = m1x
                self.mode = 0

            def evaluateAtX( self, E ) :

                Eout, pout = calculateAverageProductDataAtEnergy( self, E )
                if( self.mode == 0 ) : return( Eout, pout )
                if( self.mode == 1 ) : return( Eout )
                return( pout )

            def setTolerances( self, relativeTolerance, absoluteTolerance ) :

                self.relativeTolerance = relativeTolerance
                self.absoluteTolerance = absoluteTolerance

        verbosity = kwargs.get( 'verbosity', 0 )
        indent2 = indent + kwargs.get( 'incrementalIndent', '  ' )
        energyUnit = kwargs['incidentEnergyUnit']
        momentumDepositionUnit = energyUnit + '/c'
        massUnit = energyUnit + '/c**2'
        multiplicity = kwargs['multiplicity']
        productMass = kwargs['product'].getMass( massUnit )
        energyAccuracy = kwargs['energyAccuracy']
        momentumAccuracy = kwargs['momentumAccuracy']
        reactionSuite = kwargs['reactionSuite']
        product = kwargs['product']
        mass1 = reactionSuite.projectile.getMass( massUnit )
        mass2 = reactionSuite.target.getMass( massUnit )
        massx = product.getMass( massUnit )
        EMin = kwargs['EMin']
        EMax = kwargs['EMax']
        
        m1x = mass1 * massx / ( mass1 + mass2 )**2

        calculationData = calculateDepositionInfo( self, multiplicity, massx, m1x )

        Es = [ coefficients.value for coefficients in self.fSubform.data ]
        if( EMin < Es[0] ) : EMin = Es[0]           # Fix some data issues.
        Es = sorted( set( Es + multiplicity.domainGrid( ) ) )
        while( Es[0] < EMin ) : del Es[0]
        aveEnergy = []
        aveMomentum = []
        for E in Es : 
            Eout, pout = calculateAverageProductDataAtEnergy( calculationData, E )
            aveEnergy.append( [ E, Eout ] )
            aveMomentum.append( [ E, pout ] )

        calculationData.mode = 1
        absoluteTolerance = 1e-3 * energyAccuracy * max( [ Ep for E, Ep in aveEnergy ] )
        calculationData.setTolerances( energyAccuracy, absoluteTolerance )
        aveEnergy = fudgemathModule.thickenXYList( aveEnergy, calculationData )

        calculationData.mode = 2
        absoluteTolerance = 1e-3 * momentumAccuracy * max( [ pp for E, pp in aveMomentum ] )
        calculationData.setTolerances( momentumAccuracy, absoluteTolerance )
        aveMomentum = fudgemathModule.thickenXYList( aveMomentum, calculationData )

        return( [ aveEnergy ], [ aveMomentum ] )
Пример #6
0
def calculateAverageProductData( productFrame, angularSubform, energySubform, style, indent, **kwargs ) :

    def fixLimits( EMin, EMax, Es ) :

        if( EMin not in Es ) : Es.append( EMin )
        if( EMax not in Es ) : Es.append( EMax )
        Es.sort( )
        while( Es[0] < EMin ) : del Es[0]
        while( Es[-1] > EMax ) : del Es[-1]

    def calculateAverageEnergy( self, Ein ) :

        averageEp = self.energySubform.averageEp( Ein )
        if( self.productFrame == standardsModule.frames.centerOfMassToken ) :
            A_Ein = self.massRatio * Ein
            if( not( self.angularSubform.isIsotropic( ) ) ) : averageEp += 2 * math.sqrt( A_Ein * averageEp ) * self.angularSubform.averageMu( Ein )
            averageEp += A_Ein
        averageEp *= self.multiplicity.getValue( Ein )
        return( averageEp )

    def calculateAverageMomentum( self, Ein ) :

        pp, averageMu = 0., self.angularSubform.averageMu( E )
        if( averageMu != 0. ) : pp = energySubform.sqrtEp_AverageAtE( E ) * averageMu
        if( self.productFrame == standardsModule.frames.centerOfMassToken ) : pp += math.sqrt( self.massRatio * Ein )
        return( multiplicity.getValue( E ) * math.sqrt( 2. * self.productMass ) * pp )

    def calculateAverageMomentumForPhoton( self, Ein ) :

        muAverage = angularSubform.averageMu( E )
        if( muAverage == 0. ) : return( 0. )
        return( multiplicity.getValue( E ) * energySubform.averageEp( E ) * muAverage )

    class calculateDepositionInfo :

        def __init__( self, productFrame, productMass, massRatio, angularSubform, energySubform, multiplicity ) :

            self.productFrame = productFrame
            self.productMass = productMass
            self.massRatio = massRatio
            self.angularSubform = angularSubform
            self.energySubform = energySubform
            self.multiplicity = multiplicity

        def evaluateAtX( self, E ) :

            return( self._evaluateAtX( self, E ) )

        def setEvaluateAtX( self, evaluateAtX ) :

            self._evaluateAtX = evaluateAtX

        def setTolerances( self, relativeTolerance, absoluteTolerance ) :

            self.relativeTolerance = relativeTolerance
            self.absoluteTolerance = absoluteTolerance

    class NBodyPhaseSpace :

        def __init__( self, energySubform, massUnit, projectileMass, targetMass, productMass, Q ) :

            self.energySubform = energySubform
            self.massUnit = massUnit
            self.projectileMass = projectileMass
            self.targetMass = targetMass
            self.productMass = productMass
            self.Q = Q

        def averageEp( self, Ein ) :

            return( self.energySubform.averageEp( Ein, self.massUnit, self.projectileMass, self.targetMass, self.productMass, self.Q ) )

        def getEnergyArray( self, EMin = None, EMax = None ) :

            return( [ EMin, EMax ] )

    energyUnit = kwargs['incidentEnergyUnit']
    momentumDepositionUnit = energyUnit + '/c'
    massUnit = energyUnit + '/c**2'
    multiplicity = kwargs['multiplicity']               # BRB - FIXME; Handle gamma data with 1 point for multiplicity weight until it is fixed.
    energyAccuracy = kwargs['energyAccuracy']
    momentumAccuracy = kwargs['momentumAccuracy']
    reactionSuite = kwargs['reactionSuite']
    projectileMass = reactionSuite.projectile.getMass( massUnit )
    targetMass = reactionSuite.target.getMass( massUnit )
    product = kwargs['product']
    productMass = product.getMass( massUnit )
    EMin = kwargs['EMin']
    EMax = kwargs['EMax']

    massRatio = projectileMass * productMass / ( projectileMass + targetMass )**2

    if( product.name == 'gamma' ) : productFrame = standardsModule.frames.labToken  # All gamma data treated as in lab frame.
    if( isinstance( energySubform, energyModule.NBodyPhaseSpace ) ) :
        Q = kwargs['reaction'].getQ( energyUnit, final = False, groundStateQ = True )
        energySubform = NBodyPhaseSpace( energySubform, massUnit, projectileMass, targetMass, productMass, Q )

    calculationData = calculateDepositionInfo( productFrame, productMass, massRatio, angularSubform, energySubform, multiplicity )

    Es = energySubform.getEnergyArray( )
    if( Es[0] is None ) : Es[0] = EMin
    if( Es[-1] is None ) : Es[-1] = EMax
    if( EMin < Es[0] ) : EMin = Es[0]
    if( EMax > Es[-1] ) : EMax = Es[-1]
    Es = sorted( set( energySubform.getEnergyArray( EMin, EMax ) + multiplicity.domainGrid( ) ) )
    fixLimits( EMin, EMax, Es )
    calculationData.setEvaluateAtX( calculateAverageEnergy )
    aveEnergy = [ [ E, calculationData.evaluateAtX( E ) ] for E in Es ]
    absoluteTolerance = 1e-3 * energyAccuracy * max( [ Ep for E, Ep in aveEnergy ] )
    calculationData.setTolerances( energyAccuracy, absoluteTolerance )
    aveEnergy = fudgemath.thickenXYList( aveEnergy, calculationData )

    if( isinstance( angularSubform, angularModule.isotropic ) and ( productFrame == standardsModule.frames.labToken ) ) :
        aveMomentum = [ [ aveEnergy[0][0], 0. ], [ aveEnergy[-1][0], 0. ] ]
    else :
        if( product.name == 'gamma' ) :
            calculationData.setEvaluateAtX( calculateAverageMomentumForPhoton )
        else :
            calculationData.setEvaluateAtX( calculateAverageMomentum )
        Es = sorted( set( Es + angularSubform.getEnergyArray( EMin, EMax ) ) )
        fixLimits( EMin, EMax, Es )
        aveMomentum = [ [ E, calculationData.evaluateAtX( E ) ] for E in Es ]
        absoluteTolerance = 1e-3 * momentumAccuracy * max( [ pp for E, pp in aveMomentum ] )
        calculationData.setTolerances( momentumAccuracy, absoluteTolerance )
        aveMomentum = fudgemath.thickenXYList( aveMomentum, calculationData )

    return( aveEnergy, aveMomentum )
Пример #7
0
def calculateAverageProductData(self, style, indent, **kwargs):
    """
    This function calculates average product data for two-body reactions.
    """
    def calculateDepositionEnergyAtE(angularData, E, parameters):

        a1x, a2y, Qp = parameters['a1x'], parameters['a2y'], parameters['Qp']
        dE = max(0., E - Qp)
        return (a1x * E + a2y * dE + 2. * math.sqrt(a1x * a2y * E * dE) *
                angularData.averageMu(E, accuracy=energyAccuracy))

    def calculateDepositionEnergyAtEForPhotoProjectile(angularData, E,
                                                       parameters):

        mass2, massx, massy, Q = parameters['m2'], parameters[
            'mx'], parameters['my'], parameters['Q']
        E__E_m2 = E / (E + mass2)
        dE = max(0., (E__E_m2 * mass2) + Q) * massy / (massx + massy)
        return (0.5 * E__E_m2**2 * massx + dE +
                E__E_m2 * math.sqrt(2. * dE * massx) *
                angularData.averageMu(E, accuracy=energyAccuracy))

    class calculateDepositionEnergyThicken:
        def __init__(self, data, angular, func, parameters, relativeTolerance,
                     absoluteTolerance):

            self.data = data
            self.angular = angular
            self.func = func
            self.parameters = parameters
            self.relativeTolerance = relativeTolerance
            self.absoluteTolerance = absoluteTolerance

        def evaluateAtX(self, E):

            return (self.func(self.angular, E, self.parameters))

    def calculateDepositionMomentumAtE(angularData, E, parameters):

        mass1, massx, b1x, a2y, Qp = parameters['m1'], parameters[
            'mx'], parameters['b1x'], parameters['a2y'], parameters['Qp']
        dE = max(0., E - Qp)
        return (b1x * math.sqrt(2. * E / mass1) +
                math.sqrt(2. * massx * a2y * dE) *
                angularData.averageMu(E, accuracy=momentumAccuracy))

    def calculateDepositionMomentumAtEForPhotoProjectile(
            angularData, E, parameters):

        mass2, massx, massy, Q = parameters['m2'], parameters[
            'mx'], parameters['my'], parameters['Q']
        E__E_m2 = E / (E + mass2)
        dE = max(0., (E__E_m2 * mass2) + Q) * massy / (massx + massy)
        return (E__E_m2 * massx + math.sqrt(2. * dE * massx) *
                angularData.averageMu(E, accuracy=momentumAccuracy))

    class calculateDepositionMomentumThicken:
        def __init__(self, data, angular, func, parameters, relativeTolerance,
                     absoluteTolerance):

            self.data = data
            self.angular = angular
            self.func = func
            self.parameters = parameters
            self.relativeTolerance = relativeTolerance
            self.absoluteTolerance = absoluteTolerance

        def evaluateAtX(self, E):

            return (self.func(self.angular, E, self.parameters))

    if (hasattr(self, 'calculateAverageProductData')
        ):  # This happends when, for example, the angular is a regions2d form.
        return (self.calculateAverageProductData(style,
                                                 indent=indent,
                                                 **kwargs))

    energyUnit = kwargs['incidentEnergyUnit']
    momentumDepositionUnit = energyUnit + '/c'
    massUnit = energyUnit + '/c**2'
    multiplicity = kwargs['multiplicity']
    productMass = kwargs['product'].getMass(massUnit)
    energyAccuracy = kwargs['energyAccuracy']
    momentumAccuracy = kwargs['momentumAccuracy']
    reactionSuite = kwargs['reactionSuite']
    reaction = kwargs['reaction']
    outputChannel = kwargs['outputChannel']
    productIndex = kwargs['productIndex']

    mass1 = reactionSuite.projectile.getMass(massUnit)
    mass2 = reactionSuite.target.getMass(massUnit)
    massx = outputChannel.products[0].getMass(massUnit)
    massy = outputChannel.products[1].getMass(massUnit)

    if (productIndex == '1'): massx, massy = massy, massx
    m12, mxy = mass1 + mass2, massx + massy
    b1x, a1x, a2y = mass1 * massx / m12, mass1 * massx / (
        m12 * m12), mass2 * massy / (m12 * mxy)
    Qm = m12 - mxy
    Q = reaction.getQ(energyUnit, final=False, groundStateQ=True)
    Qp = -float(Q) * m12 / mass2  # This is the threshold in the COM frame.

    if (mass1 == 0.):  # Photo as projectile
        energyFunc = calculateDepositionEnergyAtEForPhotoProjectile
        momentumFunc = calculateDepositionMomentumAtEForPhotoProjectile
        parameters = {'m2': mass2, 'mx': massx, 'my': massy, 'Q': Q}
    else:
        energyFunc = calculateDepositionEnergyAtE
        momentumFunc = calculateDepositionMomentumAtE
        parameters = {
            'm1': mass1,
            'mx': massx,
            'a1x': a1x,
            'a2y': a2y,
            'b1x': b1x,
            'Qp': Qp
        }

    Es = self.getEnergyArray(kwargs['EMin'], kwargs['EMax'])
    aveEnergy = [[E, energyFunc(self, E, parameters)] for E in Es]
    aveEnergy = fudgemath.thickenXYList(
        aveEnergy,
        calculateDepositionEnergyThicken(aveEnergy, self, energyFunc,
                                         parameters, energyAccuracy, 1e-10))

    aveMomentum = [[E, momentumFunc(self, E, parameters)] for E in Es]
    aveMomentum = fudgemath.thickenXYList(
        aveMomentum,
        calculateDepositionMomentumThicken(aveMomentum, self, momentumFunc,
                                           parameters, momentumAccuracy,
                                           1e-10))

    return ([aveEnergy], [aveMomentum])
Пример #8
0
    def calculate_a(self,
                    energy_in,
                    energy_out_cmMin,
                    energy_out_cmMax,
                    accuracy=1e-6):

        reactionSuite = self.getRootAncestor()

        def getParticleData(particleID):

            particle = reactionSuite.PoPs[particleID]
            Z, A, ZA, level = miscPoPsModule.ZAInfo(particle)
            mass = particle.getMass('MeV/c**2')
            return (particleID, Z, max(0, A - Z), A, mass)

# BRB6 hardwired

        energyFactor = PQUModule.PQU(1, 'MeV').getValueAs(
            self.fSubform.data.axes[-1].unit)
        projectileID = self.findAttributeInAncestry('projectile')
        targetID = self.findAttributeInAncestry('target')
        productID = self.findClassInAncestry(fudge.gnd.product.product).id
        name_a, Z_a, N_a, A_a, AWRa = getParticleData(projectileID)
        name_A, Z_A, N_A, A_A, AWRA = getParticleData(targetID)
        name_b, Z_b, N_b, A_b, AWRb = getParticleData(productID)
        Z_C, N_C = Z_a + Z_A, N_a + N_A
        if (N_A == 0): N_C = 0
        Z_B, N_B = Z_C - Z_b, max(0, N_C - N_b)
        A_B = Z_B + N_B
        if (N_B == 0): A_B = 0

        residualID = miscPoPsModule.idFromZAndA(Z_B, A_B)
        residual = reactionSuite.PoPs[residualID]
        try:
            numberOfMasses = len(residual.mass)
        except:
            numberOfMasses = 0
        if (numberOfMasses == 0):
            AWRB = PQUModule.PQU(
                massTrackerModule.massTracker.elementalMass[1000 * Z_B],
                'amu').getValueAs('MeV/c**2')
        else:
            AWRB = residual.getMass('MeV/c**2')
        Ma, Ia = self.KalbachMann_a_parameters[name_a][
            'M'], self.KalbachMann_a_parameters[name_a]['I']
        mb, Ib = self.KalbachMann_a_parameters[name_b][
            'm'], self.KalbachMann_a_parameters[name_b]['I']
        Sa, Sb = energyFactor * self.calculate_S_ab_MeV(
            Z_A, N_A, Z_C, N_C, Ia), energyFactor * self.calculate_S_ab_MeV(
                Z_B, N_B, Z_C, N_C, Ib)

        C1, C2, C3 = 0.04 / energyFactor, 1.8e-6 / energyFactor**3, 6.7e-7 / energyFactor**4

        ea = energy_in * AWRA / (AWRa + AWRA) + Sa

        R1, R3 = 130 * energyFactor, 41 * energyFactor  # MeV to self's energy units.
        if (ea < R1): R1 = ea
        if (ea < R3): R3 = ea

        def calculate_a2(energy_out_cm):

            eb = energy_out_cm * (AWRb + AWRB) / AWRB + Sb
            X1, X3 = R1 * eb / ea, R3 * eb / ea
            return (X1 * (C1 + C2 * X1 * X1) + C3 * Ma * mb * X3**4)

        class thicken_a:
            def __init__(self, calculate_a2, relativeTolerance,
                         absoluteTolerance):

                self.calculate_a2 = calculate_a2
                self.relativeTolerance = relativeTolerance
                self.absoluteTolerance = absoluteTolerance

            def evaluateAtX(self, x):

                return (self.calculate_a2(x))

        a = [[energy_out_cmMin,
              calculate_a2(energy_out_cmMin)],
             [energy_out_cmMax,
              calculate_a2(energy_out_cmMax)]]
        a = fudgemathModule.thickenXYList(
            a, thicken_a(calculate_a2, accuracy, 1e-10))

        axes = aSubform.defaultAxes(self.fSubform.data.axes[1].unit)
        return (XYsModule.XYs1d(data=a, axes=axes, value=energy_in))