Пример #1
0
def jolaKap(jolaLogNums, dfBydw, jolaPoints, numDeps, temp, rho):

    log10E = math.log10(math.e)
    nm2cm = 1.0e-7

    numPoints = len(jolaPoints)

    logKappaJola = [[0.0 for i in range(numDeps)] for j in range(numPoints)]
    #//Initialize this carefully:

    for iD in range(numDeps):
        for iW in range(numPoints):
            logKappaJola[iW][iD] = -999.0

    #double stimEmExp, stimEmLogExp, stimEmLogExpHelp, stimEm;
    #double freq, lastFreq, w, lastW, deltaW, thisDeltaF;
    logSigma = -999.0
    logFreq = Useful.logC() - math.log(nm2cm * jolaPoints[0])
    logW = 0.0 - math.log(nm2cm * jolaPoints[0])  #//if w is waveno in cm^-1
    #//lastFreq = Math.exp(logFreq)
    lastW = math.exp(logW)

    #//try accumulating oscillator strenth, f, across band - assumes f = 0 at first (largest) lambda- ??
    thisF = 0.0

    #//If f is cumulative in wavenumber, then we have to make the wavenumber loop the inner one even if it
    #//means re-calculating depth-independent quantities each time:
    for iD in range(numDeps):

        thisF = 0.0  #//re-set accumulator

        #//loop in order of *increasing* wavenumber
        #for (int iW = numPoints-1; iW >=1; iW--){
        for iW in range(numPoints - 1, 1, -1):

            #//df/dv is a differential oscillator strength in *frequency* space:
            logFreq = Useful.logC() - math.log(nm2cm * jolaPoints[iW])
            freq = math.exp(logFreq)
            logW = 0.0 - math.log(
                nm2cm * jolaPoints[iW])  #//if w is waveno in cm^-1
            w = math.exp(logW)  #//if w is waveno in cm^-1
            #//System.out.println("w " + w);
            #//deltaW = Math.abs(freq - lastFreq);
            deltaW = abs(w - lastW)

            #//For LTE stimulated emission correction:
            stimEmLogExpHelp = Useful.logH() + logFreq - Useful.logK()

            #//        for (int iD = 0; iD < numDeps; iD++){

            thisDeltaF = deltaW * dfBydw[iW][iD]
            if (thisDeltaF > 0.0):
                #thisF += thisDeltaF #//cumulative version
                thisF = thisDeltaF
                #//non-cumulative version
                logSigma = math.log(thisF) + math.log(
                    math.pi) + 2.0 * Useful.logEe() - Useful.logMe(
                    ) - Useful.logC()
            else:
                logSigma = -999.0

            #// LTE stimulated emission correction:
            stimEmLogExp = stimEmLogExpHelp - temp[1][iD]
            stimEmExp = -1.0 * math.exp(stimEmLogExp)
            stimEm = (1.0 - math.exp(stimEmExp))

            #//extinction coefficient in cm^2 g^-1:
            logKappaJola[iW][iD] = logSigma + jolaLogNums[iD] - rho[1][
                iD] + math.log(stimEm)
            #//logKappaJola[iW][iD] = -999.0;
            #//if (iD%10 == 1){
            #//System.out.println("iD " + iD + " iW " + iW + " logFreq " + log10E*logFreq + " logW " + log10E*logW + " logStimEm " + log10E*Math.log(stimEm));
            #//System.out.println("iD " + iD + " iW " + iW + " thisDeltaF " + thisDeltaF + " logSigma " + log10E*logSigma + " jolaLogNums " + log10E*jolaLogNums[iD] + " rho " + log10E*rho[1][iD] + " logKappaJola " + log10E*logKappaJola[iW][iD]);
            #//}

            #//        } //iD loop - depths

            lastFreq = freq
        #} //iW loop - wavelength

    #} //iD loop - depths

    return logKappaJola
Пример #2
0
def sahaRHS(chiI, logUwU, logUwL, temp):
    """RHS of partial pressure formulation of Saha equation in standard form (N_U*P_e/N_L on LHS)
 // Returns depth distribution of LHS: Phi(T) === N_U*P_e/N_L (David Gray notation)

// Input parameters:
// chiI - ground state ionization energy of lower stage 
// log10UwUArr, log10UwLArr - array of temperature-dependent partition function for upper and lower ionization stage
// Also needs atsmopheric structure information:
// numDeps
// temp structure 
//
// Atomic element "A" is the one whose ionization fractions are being computed
//  Element "B" refers to array of other species with which A forms molecules "AB" """

    ln10 = math.log(10.0)
    logE = math.log10(math.e)  #// for debug output
    log2pi = math.log(2.0 * math.pi)
    log2 = math.log(2.0)

    #//    var numMols = dissEArr.length;

    #// Parition functions passed in are 2-element vectore with remperature-dependent base 10 log Us
    #// Convert to natural logs:
    #double Ttheta, thisTemp;
    #//Default initializations:
    #//We need one more stage in size of saha factor than number of stages we're actualy populating
    thisLogUwU = 0.0
    thisLogUwL = 0.0

    logE10 = math.log(10.0)
    #//We need one more stage in size of saha factor than number of stages we're actualy populating
    #logUwU = [0.0 for i in range(5)]
    #logUwL = [0.0 for i in range(5)]
    for kk in range(len(logUwL)):
        logUwU[kk] = logUwL[kk]
    #   logUwL[kk] = logE10*log10UwLArr[kk]

    #//System.out.println("chiL before: " + chiL);
    #// If we need to subtract chiI from chiL, do so *before* converting to tiny numbers in ergs!

#//atomic ionization stage Boltzmann factors:
#double logChiI, logBoltzFacI;
#double boltzFacI;
    logChiI = math.log(chiI) + Useful.logEv()
    logBoltzFacI = logChiI - Useful.logK()
    boltzFacI = math.exp(logBoltzFacI)

    #//Extra factor of k to get k^5/2 in the P_e formulation of Saha Eq.
    logSahaFac = log2 + (3.0 / 2.0) * (log2pi + Useful.logMe() + Useful.logK()
                                       - 2.0 * Useful.logH()) + Useful.logK()

    #//double[] logLHS = new double[numDeps];
    #double logLHS;

    #//   For atomic ionization stages:
    #double logSaha, saha, expFac;

    #//  for (int id = 0; id < numDeps; id++) {

    #//
    #//Determine temperature dependent partition functions Uw:
    thisTemp = temp[0]
    #Ttheta = 5040.0 / thisTemp
    """         
    if (Ttheta >= 1.0):
        thisLogUwU = logUwU[0]
        thisLogUwL = logUwL[0]
       
    if (Ttheta <= 0.5):
        thisLogUwU = logUwU[1]
        thisLogUwL = logUwL[1]
       
    if (Ttheta > 0.5 and Ttheta < 1.0):
        thisLogUwU = ( logUwU[1] * (Ttheta - 0.5)/(1.0 - 0.5) )
        + ( logUwU[0] * (1.0 - Ttheta)/(1.0 - 0.5) )
        thisLogUwL = ( logUwL[1] * (Ttheta - 0.5)/(1.0 - 0.5) )
        + ( logUwL[0] * (1.0 - Ttheta)/(1.0 - 0.5) )
    """

    if (thisTemp <= 130):
        thisLogUwU = logUwU[0]
        thisLogUwL = logUwL[0]

    if (thisTemp > 130 and thisTemp <= 500):
        thisLogUwU = logUwU[1] * (thisTemp - 130)/(500 - 130) \
            + logUwU[0] * (500 - thisTemp)/(500 - 130)
        thisLogUwL = logUwL[1] * (thisTemp - 130)/(500 - 130) \
            + logUwL[0] * (500 - thisTemp)/(500 - 130)

    if (thisTemp > 500 and thisTemp <= 3000):
        thisLogUwU = logUwU[2] * (thisTemp - 500)/(3000 - 500) \
            + logUwU[1] * (3000 - thisTemp)/(3000 - 500)
        thisLogUwL = logUwL[2] * (thisTemp - 500)/(3000 - 500) \
            + logUwL[1] * (3000 - thisTemp)/(3000 - 500)

    if (thisTemp > 3000 and thisTemp <= 8000):
        thisLogUwU = logUwU[3] * (thisTemp - 3000)/(8000 - 3000) \
            + logUwU[2] * (8000 - thisTemp)/(8000 - 3000)
        thisLogUwL = logUwL[3] * (thisTemp - 3000)/(8000 - 3000) \
            + logUwL[2] * (8000 - thisTemp)/(8000 - 3000)

    if (thisTemp > 8000 and thisTemp < 10000):
        thisLogUwU = logUwU[4] * (thisTemp - 8000)/(10000 - 8000) \
            + logUwU[3] * (10000 - thisTemp)/(10000 - 8000)
        thisLogUwL = logUwL[4] * (thisTemp - 8000)/(10000 - 8000) \
            + logUwL[3] * (10000 - thisTemp)/(10000 - 8000)

    if (thisTemp >= 10000):
        thisLogUwU = logUwU[4]
        thisLogUwL = logUwL[4]

#//Ionization stage Saha factors:

#//Need T_kin^5/2 in the P_e formulation of Saha Eq.
    logSaha = logSahaFac - (boltzFacI / temp[0]) + (
        5.0 * temp[1] / 2.0) + thisLogUwU - thisLogUwL
    #// saha = Math.exp(logSaha);

    #//logLHS[id] = logSaha;
    logLHS = logSaha
    #//    } //id loop

    return logLHS
Пример #3
0
def levelPops(lam0In, logNStage, chiL, logUw, gwL, numDeps, temp):
    """ Returns depth distribution of occupation numbers in lower level of b-b transition,

// Input parameters:
// lam0 - line centre wavelength in nm
// logNStage - log_e density of absorbers in relevent ion stage (cm^-3)
// logFlu - log_10 oscillator strength (unitless)
// chiL - energy of lower atomic E-level of b-b transition in eV
// Also needs atsmopheric structure information:
// numDeps
// temp structure """

    c = Useful.c()
    logC = Useful.logC()
    k = Useful.k()
    logK = Useful.logK()
    logH = Useful.logH()
    logEe = Useful.logEe()
    logMe = Useful.logMe()

    ln10 = math.log(10.0)
    logE = math.log10(math.e)
    #// for debug output
    log2pi = math.log(2.0 * math.pi)
    log2 = math.log(2.0)

    #//double logNl = logNlIn * ln10;  // Convert to base e

    #// Parition functions passed in are 2-element vectore with remperature-dependent base 10 log Us
    #// Convert to natural logs:
    #double thisLogUw, Ttheta;
    thisLogUw = 0.0  # //default initialization
    #logUw = [ 0.0 for i in range(5) ]
    logE10 = math.log(10.0)
    #print("log10UwStage ", log10UwStage)
    #for kk in range(len(logUw)):
    #    logUw[kk] = logE10*log10UwStage[kk] #// lburns new loop

    logGwL = math.log(gwL)

    #//System.out.println("chiL before: " + chiL);
    #// If we need to subtract chiI from chiL, do so *before* converting to tiny numbers in ergs!
    #////For testing with Ca II lines using gS3 internal line list only:
    #//boolean ionized = true;
    #//if (ionized) {
    #//    //System.out.println("ionized, doing chiL - chiI: " + ionized);
    #//    //         chiL = chiL - chiI;
    #//             chiL = chiL - 6.113;
    #//          }
    #//   //

    #//Log of line-center wavelength in cm
    logLam0 = math.log(lam0In)  #// * 1.0e-7);

    #// energy of b-b transition
    logTransE = logH + logC - logLam0  #//ergs

    if (chiL <= 0.0):
        chiL = 1.0e-49
    logChiL = math.log(
        chiL) + Useful.logEv()  #// Convert lower E-level from eV to ergs

    logBoltzFacL = logChiL - Useful.logK(
    )  #// Pre-factor for exponent of excitation Boltzmann factor
    boltzFacL = math.exp(logBoltzFacL)

    boltzFacGround = 0.0 / k  #//I know - its zero, but let's do it this way anyway'

    #// return a 1D numDeps array of logarithmic number densities
    #// level population of lower level of bb transition (could be in either stage I or II!)

    logNums = [0.0 for i in range(numDeps)]

    #double num, logNum, expFac;

    for id in range(numDeps):

        #//Determine temperature dependenet partition functions Uw:

        #Ttheta = 5040.0 / temp[0][id]
        #//NEW Determine temperature dependent partition functions Uw: lburns
        thisTemp = temp[0][id]
        """
        if (Ttheta >= 1.0):
            thisLogUw = logUw[0]
        
        if (Ttheta <= 0.5):
            thisLogUw = logUw[1]
        
        if (Ttheta > 0.5 and Ttheta < 1.0):
            thisLogUw = ( logUw[1] * (Ttheta - 0.5)/(1.0 - 0.5) ) \
                      + ( logUw[0] * (1.0 - Ttheta)/(1.0 - 0.5) )
        """
        if (thisTemp >= 10000):
            thisLogUw = logUw[4]

        if (thisTemp <= 130):
            thisLogUw = logUw[0]

        if (thisTemp > 130 and thisTemp <= 500):
            thisLogUw = logUw[1] * (thisTemp - 130)/(500 - 130) \
                      + logUw[0] * (500 - thisTemp)/(500 - 130)

        if (thisTemp > 500 and thisTemp <= 3000):
            thisLogUw = logUw[2] * (thisTemp - 500)/(3000 - 500) \
                      + logUw[1] * (3000 - thisTemp)/(3000 - 500)

        if (thisTemp > 3000 and thisTemp <= 8000):
            thisLogUw = logUw[3] * (thisTemp - 3000)/(8000 - 3000) \
                      + logUw[2] * (8000 - thisTemp)/(8000 - 3000)

        if (thisTemp > 8000 and thisTemp < 10000):
            thisLogUw = logUw[4] * (thisTemp - 8000)/(10000 - 8000) \
                      + logUw[3] * (10000 - thisTemp)/(10000 - 8000)

        #print("logUw ", logUw, " thisLogUw ", thisLogUw)

        #//System.out.println("LevPops: ionized branch taken, ionized =  " + ionized);
        #// Take stat weight of ground state as partition function:
        logNums[id] = logNStage[id] - boltzFacL / temp[0][
            id] + logGwL - thisLogUw  #// lower level of b-b transition
        #print("LevelPopsServer.stagePops id ", id, " logNStage[id] ", logNStage[id], " boltzFacL ", boltzFacL, " temp[0][id] ", temp[0][id], " logGwL ", logGwL, " thisLogUw ", thisLogUw, " logNums[id] ", logNums[id]);

        #// System.out.println("LevelPops: id, logNums[0][id], logNums[1][id], logNums[2][id], logNums[3][id]: " + id + " "
        #//          + Math.exp(logNums[0][id]) + " "
        #//         + Math.exp(logNums[1][id]) + " "
        #//          + Math.exp(logNums[2][id]) + " "
        #//        + Math.exp(logNums[3][id]));
        #//System.out.println("LevelPops: id, logNums[0][id], logNums[1][id], logNums[2][id], logNums[3][id], logNums[4][id]: " + id + " "
        #//        + logE * (logNums[0][id]) + " "
        #//        + logE * (logNums[1][id]) + " "
        #//        + logE * (logNums[2][id]) + " "
        # //        + logE * (logNums[3][id]) + " "
        #//        + logE * (logNums[4][id]) );
        #//System.out.println("LevelPops: id, logIonFracI, logIonFracII: " + id + " " + logE*logIonFracI + " " + logE*logIonFracII
        #//        + "logNum, logNumI, logNums[0][id], logNums[1][id] "
        #//        + logE*logNum + " " + logE*logNumI + " " + logE*logNums[0][id] + " " + logE*logNums[1][id]);
        #//System.out.println("LevelPops: id, logIonFracI: " + id + " " + logE*logIonFracI
        #//        + "logNums[0][id], boltzFacL/temp[0][id], logNums[2][id]: "
        #//        + logNums[0][id] + " " + boltzFacL/temp[0][id] + " " + logNums[2][id]);
    #//id loop
    #stop
    return logNums
Пример #4
0
def stagePops2(logNum, Ne, chiIArr, logUw,  \
               numMols, logNumB, dissEArr, logUwB, logQwABArr, logMuABArr, \
               numDeps, temp):
    #line 1: //species A data - ionization equilibrium of A
    #line 2: //data for set of species "B" - molecular equlibrium for set {AB}
    """Ionization equilibrium routine that accounts for molecule formation:
    // Returns depth distribution of ionization stage populations 

    // Input parameters:
    // logNum - array with depth-dependent total element number densities (cm^-3) 
    // chiI1 - ground state ionization energy of neutral stage 
    // chiI2 - ground state ionization energy of singly ionized stage 
    // Also needs atsmopheric structure information:
    // numDeps
    // temp structure 
    // rho structure
    // Atomic element A is the one whose ionization fractions are being computed
    //  Element B refers to array of other species with which A forms molecules AB """

    ln10 = math.log(10.0)
    logE = math.log10(math.e)  #// for debug output
    log2pi = math.log(2.0 * math.pi)
    log2 = math.log(2.0)

    numStages = len(
        chiIArr
    )  #// + 1; //need one more stage above the highest stage to be populated

    #//    var numMols = dissEArr.length;

    #// Parition functions passed in are 2-element vectore with remperature-dependent base 10 log Us
    #// Convert to natural logs:
    #double Ttheta, thisTemp;
    #//Default initializations:
    #//We need one more stage in size of saha factor than number of stages we're actualy populating
    thisLogUw = [0.0 for i in range(numStages + 1)]
    for i in range(numStages + 1):
        thisLogUw[i] = 0.0

    logE10 = math.log(10.0)
    #//We need one more stage in size of saha factor than number of stages we're actualy populating
    #double[][] logUw = new double[numStages+1][2];
    #logUw = [ [ 0.0 for i in range(5) ] for j in range(numStages+1) ]
    #for i in range(numStages):
    #    for kk in range(5):
    #        logUw[i][kk] = logE10*log10UwAArr[i][kk]
    #// lburns- what variable can we use instead of 5?

    #//Assume ground state statistical weight (or partition fn) of highest stage is 1.0;
    #//var logGw5 = 0.0;

    #for kk in range(5):
    #    logUw[numStages][kk] = 0.0
    #// lburns

    #//System.out.println("chiL before: " + chiL);
    #// If we need to subtract chiI from chiL, do so *before* converting to tiny numbers in ergs!

    #//atomic ionization stage Boltzmann factors:
    #double logChiI, logBoltzFacI;
    boltzFacI = [0.0 for i in range(numStages)]
    #print("numStages ", numStages, " Useful.logEv ", Useful.logEv())
    for i in range(numStages):
        #print("i ", i, " chiIArr ", chiIArr[i])
        logChiI = math.log(chiIArr[i]) + Useful.logEv()
        logBoltzFacI = logChiI - Useful.logK()
        boltzFacI[i] = math.exp(logBoltzFacI)

    logSahaFac = log2 + (3.0 / 2.0) * (log2pi + Useful.logMe() +
                                       Useful.logK() - 2.0 * Useful.logH())

    #// return a 2D 5 x numDeps array of logarithmic number densities
    #// Row 0: neutral stage ground state population
    #// Row 1: singly ionized stage ground state population
    #// Row 2: doubly ionized stage ground state population
    #// Row 3: triply ionized stage ground state population
    #// Row 4: quadruply ionized stage ground state population
    #double[][] logNums = new double[numStages][numDeps];
    logNums = [[0.0 for i in range(numDeps)] for j in range(numStages)]

    #//We need one more stage in size of saha factor than number of stages we're actualy populating
    #//   for index accounting pirposes
    #//   For atomic ionization stages:
    # double[][] logSaha = new double[numStages+1][numStages+1];
    # double[][] saha = new double[numStages+1][numStages+1];
    logSaha = [[0.0 for i in range(numStages + 1)]
               for j in range(numStages + 1)]
    saha = [[0.0 for i in range(numStages + 1)] for j in range(numStages + 1)]
    #//

    logIonFrac = [0.0 for i in range(numStages)]
    #double expFac, logNe;

    #// Now - molecular variables:

    #//Treat at least one molecule - if there are really no molecules for an atomic species,
    #//there will be one phantom molecule in the denominator of the ionization fraction
    #//with an impossibly high dissociation energy
    ifMols = True
    if (numMols == 0):
        ifMols = False
        numMols = 1
        #//This should be inherited, but let's make sure:
        dissEArr[0] = 19.0  #//eV

#//Molecular partition functions - default initialization:
#double[] thisLogUwB = new double[numMols];
    thisLogUwB = [0.0 for i in range(numMols)]
    for iMol in range(numMols):
        thisLogUwB[
            iMol] = 0.0  #// variable for temp-dependent computed partn fn of array element B

    thisLogUwA = 0.0  #// element A
    thisLogQwAB = math.log(300.0)

    #//For clarity: neutral stage of atom whose ionization equilibrium is being computed is element A
    #// for molecule formation:
    logUwA = [0.0 for i in range(5)]
    if (numMols > 0):
        for kk in range(len(logUwA)):
            logUwA[kk] = logUw[0][kk]
        #// lburns

#// Array of elements B for all molecular species AB:
#double[][] logUwB = new double[numMols][2];
#logUwB = [ [ 0.0 for i in range(5) ] for j in range(numMols) ]
#//if (numMols > 0){
#for iMol in range(numMols):
#    for kk in range(5):
#        #print("iMol ", iMol, " kk ", kk)
#        logUwB[iMol][kk] = logE10*log10UwBArr[iMol][kk]
#// lburns new loop

#//}
#//// Molecular partition functions:
#//       double[] logQwAB = new double[numMols];
#//      //if (numMols > 0){
#//       for (int iMol = 0; iMol < numMols; iMol++){
#//          logQwAB[iMol] = logE10*log10QwABArr[iMol];
#//       }
#      //}
#//Molecular dissociation Boltzmann factors:
    boltzFacIAB = [0.0 for i in range(numMols)]
    logMolSahaFac = [0.0 for i in range(numMols)]
    #//if (numMols > 0){
    #double logDissE, logBoltzFacIAB;
    for iMol in range(numMols):
        logDissE = math.log(dissEArr[iMol]) + Useful.logEv()
        logBoltzFacIAB = logDissE - Useful.logK()
        boltzFacIAB[iMol] = math.exp(logBoltzFacIAB)
        logMolSahaFac[iMol] = (3.0 / 2.0) * (
            log2pi + logMuABArr[iMol] + Useful.logK() - 2.0 * Useful.logH())
        #//console.log("iMol " + iMol + " dissEArr[iMol] " + dissEArr[iMol] + " logDissE " + logE*logDissE + " logBoltzFacIAB " + logE*logBoltzFacIAB + " boltzFacIAB[iMol] " + boltzFacIAB[iMol] + " logMuABArr " + logE*logMuABArr[iMol] + " logMolSahaFac " + logE*logMolSahaFac[iMol]);

    #//}
#//   For molecular species:
    logSahaMol = [0.0 for i in range(numMols)]
    invSahaMol = [0.0 for i in range(numMols)]

    for id in range(numDeps):

        #//// reduce or enhance number density by over-all Rosseland opcity scale parameter
        #//
        #//Row 1 of Ne is log_e Ne in cm^-3
        logNe = Ne[1][id]

        #//Determine temperature dependent partition functions Uw:
        thisTemp = temp[0][id]
        #Ttheta = 5040.0 / thisTemp
        """         
        if (Ttheta >= 1.0):
            for iStg in range(numStages):
                thisLogUw[iStg] = logUw[iStg][0]
           
            for iMol in range(numMols):
                thisLogUwB[iMol] = logUwB[iMol][0]
           
            
       
        if (Ttheta <= 0.5):
            for iStg in range(numStages):
                thisLogUw[iStg] = logUw[iStg][1]
           
            for iMol in range(numMols):
                thisLogUwB[iMol] = logUwB[iMol][1]
           
       
        if (Ttheta > 0.5 and Ttheta < 1.0):
            for iStg in range(numStages):
                thisLogUw[iStg] = ( logUw[iStg][1] * (Ttheta - 0.5)/(1.0 - 0.5) ) \
                                + ( logUw[iStg][0] * (1.0 - Ttheta)/(1.0 - 0.5) )
        """

        #// NEW Determine temperature dependent partition functions Uw: lburns
        if (thisTemp <= 130):
            for iStg in range(numStages):
                thisLogUw[iStg] = logUw[iStg][0]

            for iMol in range(numMols):
                thisLogUwB[iMol] = logUwB[iMol][0]

        if (thisTemp > 130 and thisTemp <= 500):
            for iStg in range(numStages):
                thisLogUw[iStg] = logUw[iStg][1] * (thisTemp - 130)/(500 - 130) \
                                + logUw[iStg][0] * (500 - thisTemp)/(500 - 130)

            for iMol in range(numMols):
                thisLogUwB[iMol] = logUwB[iMol][1] * (thisTemp - 130)/(500 - 130) \
                                 + logUwB[iMol][0] * (500 - thisTemp)/(500 - 130)

        if (thisTemp > 500 and thisTemp <= 3000):
            for iStg in range(numStages):
                thisLogUw[iStg] = logUw[iStg][2] * (thisTemp - 500)/(3000 - 500) \
                                + logUw[iStg][1] * (3000 - thisTemp)/(3000 - 500)

            for iMol in range(numMols):
                thisLogUwB[iMol] = logUwB[iMol][2] * (thisTemp - 500)/(3000 - 500) \
                                 + logUwB[iMol][1] * (3000 - thisTemp)/(3000 - 500)

        if (thisTemp > 3000 and thisTemp <= 8000):
            for iStg in range(numStages):
                thisLogUw[iStg] = logUw[iStg][3] * (thisTemp - 3000)/(8000 - 3000) \
                                + logUw[iStg][2] * (8000 - thisTemp)/(8000 - 3000)

            for iMol in range(numMols):
                thisLogUwB[iMol] = logUwB[iMol][3] * (thisTemp - 3000)/(8000 - 3000) \
                                 + logUwB[iMol][2] * (8000 - thisTemp)/(8000 - 3000)

        if (thisTemp > 8000 and thisTemp < 10000):
            for iStg in range(numStages):
                thisLogUw[iStg] = logUw[iStg][4] * (thisTemp - 8000)/(10000 - 8000) \
                                + logUw[iStg][3] * (10000 - thisTemp)/(10000 - 8000)

            for iMol in range(numMols):
                thisLogUwB[iMol] = logUwB[iMol][4] * (thisTemp - 8000)/(10000 - 8000) \
                                 + logUwB[iMol][3] * (10000 - thisTemp)/(10000 - 8000)

        if (thisTemp >= 10000):
            for iStg in range(numStages):
                thisLogUw[iStg] = logUw[iStg][4]

            for iMol in range(numMols):
                thisLogUwB[iMol] = logUwB[iMol][4]

        thisLogUw[numStages] = 0.0
        for iMol in range(numMols):
            if (thisTemp < 3000.0):
                thisLogQwAB = ( logQwABArr[iMol][1] * (3000.0 - thisTemp)/(3000.0 - 500.0) ) \
                            + ( logQwABArr[iMol][2] * (thisTemp - 500.0)/(3000.0 - 500.0) )

            if ((thisTemp >= 3000.0) and (thisTemp <= 8000.0)):
                thisLogQwAB = ( logQwABArr[iMol][2] * (8000.0 - thisTemp)/(8000.0 - 3000.0) ) \
                            + ( logQwABArr[iMol][3] * (thisTemp - 3000.0)/(8000.0 - 3000.0) )

            if (thisTemp > 8000.0):
                thisLogQwAB = ( logQwABArr[iMol][3] * (10000.0 - thisTemp)/(10000.0 - 8000.0) ) \
                            + ( logQwABArr[iMol][4] * (thisTemp - 8000.0)/(10000.0 - 8000.0) )

        #// iMol loop

#//For clarity: neutral stage of atom whose ionization equilibrium is being computed is element A
#// for molecule formation:
        thisLogUwA = thisLogUw[0]

        #//Ionization stage Saha factors:
        for iStg in range(numStages):
            #print("iStg ", iStg)
            #stop
            logSaha[iStg + 1][iStg] = logSahaFac - logNe - (
                boltzFacI[iStg] /
                temp[0][id]) + (3.0 * temp[1][id] /
                                2.0) + thisLogUw[iStg + 1] - thisLogUw[iStg]
            saha[iStg + 1][iStg] = math.exp(logSaha[iStg + 1][iStg])

            #// if (id == 36){
            #// console.log("iStg " + iStg + " boltzFacI[iStg] " + boltzFacI[iStg] + " thisLogUw[iStg] " + logE*thisLogUw[iStg] + " thisLogUw[iStg+1] " + logE*thisLogUw[iStg+1]);
            #// console.log("iStg+1 " + (iStg+1) + " iStg " + iStg + " logSahaji " + logE*logSaha[iStg+1][iStg] + " saha[iStg+1][iStg] " + saha[iStg+1][iStg]);
        #// }

#//Molecular Saha factors:
        for iMol in range(numMols):
            logSahaMol[iMol] = logMolSahaFac[iMol] - logNumB[iMol][id] - (
                boltzFacIAB[iMol] / temp[0][id]) + (
                    3.0 * temp[1][id] /
                    2.0) + thisLogUwB[iMol] + thisLogUwA - thisLogQwAB
            #//For denominator of ionization fraction, we need *inverse* molecular Saha factors (N_AB/NI):
            logSahaMol[iMol] = -1.0 * logSahaMol[iMol]
            invSahaMol[iMol] = math.exp(logSahaMol[iMol])
            #//TEST invSahaMol[iMol] = 1.0e-99; //test
            #// if (id == 36){
            #//     console.log("iMol " + iMol + " boltzFacIAB[iMol] " + boltzFacIAB[iMol] + " thisLogUwB[iMol] " + logE*thisLogUwB[iMol] + " logNumB[iMol][id] " + logE*logNumB[iMol][id] + " logMolSahaFac[iMol] " + logMolSahaFac[iMol]);
            #//     console.log("iMol " + iMol + " logSahaMol " + logE*logSahaMol[iMol] + " invSahaMol[iMol] " + invSahaMol[iMol]);
            #// }

        #//logSaha32 = logSahaFac - logNe - (boltzFacI2 / temp[0][id]) + (3.0 * temp[1][id] / 2.0) + thisLogUw3 - thisLogUw2; // log(RHS) of standard Saha equation
        #//saha32 = Math.exp(logSaha32);   //RHS of standard Saha equation

#//Compute log of denominator is ionization fraction, f_stage
        denominator = 1.0  #//default initialization - leading term is always unity
        #//ion stage contributions:
        for jStg in range(1, numStages + 1):
            addend = 1.0  #//default initialization for product series
            for iStg in range(jStg):
                #//console.log("jStg " + jStg + " saha[][] indices " + (iStg+1) + " " + iStg);
                addend = addend * saha[iStg + 1][iStg]

            denominator = denominator + addend

#//molecular contribution
        if (ifMols == True):
            for iMol in range(numMols):
                denominator = denominator + invSahaMol[iMol]

#//
        logDenominator = math.log(denominator)
        #//if (id == 36){
        #//     console.log("logDenominator " + logE*logDenominator);
        #// }
        #//var logDenominator = Math.log( 1.0 + saha21 + (saha32 * saha21) + (saha43 * saha32 * saha21) + (saha54 * saha43 * saha32 * saha21) );

        logIonFrac[
            0] = -1.0 * logDenominator  #// log ionization fraction in stage I
        #//if (id == 36){
        #     //console.log("jStg 0 " + " logIonFrac[jStg] " + logE*logIonFrac[0]);
        #//}
        for jStg in range(1, numStages):
            addend = 0.0  #//default initialization for product series
            for iStg in range(jStg):
                #//console.log("jStg " + jStg + " saha[][] indices " + (iStg+1) + " " + iStg);
                addend = addend + logSaha[iStg + 1][iStg]

            logIonFrac[jStg] = addend - logDenominator
        #//if (id == 36){
        #//    console.log("jStg " + jStg + " logIonFrac[jStg] " + logE*logIonFrac[jStg]);
        #//}

        #//logIonFracI = -1.0 * logDenominator;     // log ionization fraction in stage I
        #//logIonFracII = logSaha21 - logDenominator; // log ionization fraction in stage II
        #//logIonFracIII = logSaha32 + logSaha21 - logDenominator; //log ionization fraction in stage III
        #//logIonFracIV = logSaha43 + logSaha32 + logSaha21 - logDenominator; //log ionization fraction in stage III

        #//if (id == 36) {
        #//    System.out.println("logSaha21 " + logE*logSaha21 + " logSaha32 " + logE*logSaha32);
        #//    System.out.println("IonFracII " + Math.exp(logIonFracII) + " IonFracI " + Math.exp(logIonFracI) + " logNe " + logE*logNe);
        #//}
        #//System.out.println("LevelPops: id, ionFracI, ionFracII: " + id + " " + Math.exp(logIonFracI) + " " + Math.exp(logIonFracII) );
        #    //System.out.println("LevPops: ionized branch taken, ionized =  " + ionized);

        for iStg in range(numStages):
            logNums[iStg][id] = logNum[id] + logIonFrac[iStg]

    #//id loop

    return logNums
Пример #5
0
def lineKap(lam0In, logNums, logFluIn, linePoints, lineProf, numDeps, zScale,
            tauRos, temp, rho, logFudgeTune):

    logE10 = math.log(10.0)  #//natural log of 10

    c = Useful.c()
    logC = Useful.logC()
    k = Useful.k()
    logK = Useful.logK()
    logH = Useful.logH()
    logEe = Useful.logEe()
    logMe = Useful.logMe()

    ln10 = math.log(10.0)
    logE = math.log10(math.e)  #// for debug output
    log2pi = math.log(2.0 * math.pi)
    log2 = math.log(2.0)

    lam0 = lam0In  #// * 1.0E-7; //nm to cm
    logLam0 = math.log(lam0)
    #//double logNl = logNlIn * ln10;  // Convert to base e
    logFlu = logFluIn * ln10  #// Convert to base e
    logKScale = math.log10(zScale)

    #//chiI = chiI * Useful.eV;  // Convert lower E-level from eV to ergs
    #//double boltzFacI = chiI / k; // Pre-factor for exponent of excitation Boltzmann factor
    #//double logSahaFac = log2 + (3.0/2.0) * ( log2pi + logMe + logK - 2.0*logH);
    #//chiL = chiL * Useful.eV;  // Convert lower E-level from eV to ergs
    #//double boltzFac = chiL / k; // Pre-factor for exponent of excitation Boltzmann factor
    numPoints = len(linePoints[0])
    #//System.out.println("LineKappa: numPoints: " + numPoints);

    #double logPreFac;
    #//This converts f_lu to a volume extinction coefficient per particle - Rutten, p. 23
    logPreFac = logFlu + math.log(math.pi) + 2.0 * logEe - logMe - logC
    #//System.out.println("LINEKAPPA: logPreFac " + logPreFac);

    #//Assume wavelength, lambda, is constant throughout line profile for purpose
    #// of computing the stimulated emission correction
    #double logExpFac;
    logExpFac = logH + logC - logK - logLam0
    #//System.out.println("LINEKAPPA: logExpFac " + logExpFac);

    #// int refRhoIndx = TauPoint.tauPoint(numDeps, tauRos, 1.0);
    #// double refLogRho = rho[1][refRhoIndx];
    #//System.out.println("LINEKAPPA: refRhoIndx, refRho " + refRhoIndx + " " + logE*refRho);
    #// return a 2D numPoints x numDeps array of monochromatic *LINE* extinction line profiles

    logKappaL = [[0.0 for i in range(numDeps)] for j in range(numPoints)]
    #double num, logNum, logExpFac2, expFac, stimEm, logStimEm, logSaha, saha, logIonFrac;
    #double logNe;

    for id in range(numDeps):

        logExpFac2 = logExpFac - temp[1][id]
        expFac = -1.0 * math.exp(logExpFac2)

        stimEm = 1.0 - math.exp(expFac)
        logStimEm = math.log(stimEm)

        logNum = logNums[id]

        #//if (id == refRhoIndx) {
        #//    System.out.println("LINEKAPPA: logStimEm " + logE*logStimEm);
        #//}
        for il in range(numPoints):

            #// From Radiative Transfer in Stellar Atmospheres (Rutten), p.31
            #// This is a *volume* co-efficient ("alpha_lambda") in cm^-1:
            logKappaL[il][id] = logPreFac + logStimEm + logNum + math.log(
                lineProf[il][id])
            #//if (id == 36) {
            #//    System.out.println("il " + il + " logNum " + logE*logNum + " Math.log(lineProf[il][id]) " + logE*Math.log(lineProf[il][id]));
            #////    //System.out.println("logPreFac " + logPreFac + " logStimEm " + logStimEm);
            #//}
            #//System.out.println("LINEKAPPA: id, il " + id + " " + il + " logKappaL " + logE * logKappaL[il][id]);

            #//Convert to mass co-efficient in g/cm^2:
            #// This direct approach won't work - is not consistent with fake Kramer's law scaling of Kapp_Ros with g instead of rho
            logKappaL[il][id] = logKappaL[il][id] - rho[1][id]
            #//Try something:
            #//
            #// **********************
            #//  Opacity problem #2
            #//
            #//Line opacity needs to be enhanced by same factor as the conitnuum opacity
            #//  - related to Opacity problem #1 (logFudgeTune in GrayStarServer3.java) - ??
            #//
            logKappaL[il][id] = logKappaL[il][id] + logE10 * logFudgeTune

            #//if (id == 12) {
            #//  System.out.println("LINEKAPPA: id, il " + id + " " + il + " logKappaL " + logE * logKappaL[il][id]
            #//   + " logPreFac " + logE*logPreFac + " logStimEm " + logE*logStimEm + " logNum " + logE*logNum
            #//  + " log(lineProf[il]) " + logE*Math.log(lineProf[il][id]) + " rho[1][id] " + logE * rho[1][id]);
            #// }
            #//if (id == refRhoIndx-45) {
            #//    System.out.println("LINEKAPPA: id, il " + id + " " + il + " logKappaL " + logE*logKappaL[il][id]
            #//    + " logPreFac " + logE*logPreFac + " logStimEm " + logE*logStimEm + " logNum " + logE*logNum + " logRho " + logE*rho[1][id]
            #//    + " log(lineProf[1]) " + logE*Math.log(lineProf[1][il]) );
            #//}
        #} // il - lambda loop

    #} // id - depth loop

    return logKappaL