Пример #1
0
def massDensity(numDeps, temp, press, mmw, zScale):

    """Solves the equation of state (EOS) for the mass density (rho) given total
 * pressure from HSE solution, for a mixture of ideal gas particles and photons
 *
 * Need to assume a mean molecular weight structure, mu(Tau)
  """
    
    logE = math.log10(math.e) #// for debug output

    #//press is a 4 x numDeps array:
    #// rows 0 & 1 are linear and log *gas* pressure, respectively
    #// rows 2 & 3 are linear and log *radiation* pressure
    #// double c = 9.9989E+10; // light speed in vaccuum in cm/s
    #// double sigma = 5.670373E-5;   //Stefan-Boltzmann constant ergs/s/cm^2/K^4   
    #//Row 0 of mmwNe is Mean molecular weight in amu
    k = Useful.k()
    logK = Useful.logK()
    amu = Useful.amu()
    logAmu = Useful.logAmu()
    #double logMuAmu

#//System.out.println("STATE: logK " + logK + " logMuAmu " + logMuAmu);
    rho = [[0.0 for i in range(numDeps)] for j in range(2)]

    #// Declare scatch variables:
    #// double logPrad, pRad, pGas, logPgas;
    for i in range(numDeps):

        logMuAmu = math.log(mmw[i]) + logAmu

        #// Compute LTE bolometric radiation contribution to total HSE pressure
        #//logPrad = radFac + 4.0*temp[1][i] ;
        #//pRad = Math.exp(logPrad);
        #//pGas = press[0][i] - pRad;
        #//logPgas = Math.log(pGas);
        rho[1][i] = press[1][i] - temp[1][i] + (logMuAmu - logK)
        rho[0][i] = math.exp(rho[1][i])
        #//System.out.println("i " + i + " press[1] " + logE * press[1][i] + " mmw[i] " + mmw[i] + " rho " + logE * rho[1][i]);
        #//System.out.println("temp " + temp[0][i] + " rho " + rho[0][i]);
        

    return rho
Пример #2
0
def massDensity2(numDeps, nelemAbnd, logNz, cname):
   
    rho = [[0.0 for i in range(numDeps)] for j in range(2)]

    #double logAddend, addend;
    lAmu = Useful.logAmu()

#//Prepare log atomic masses once for each element:
    logAMass = [0.0 for i in range(nelemAbnd)]
    for j in range(nelemAbnd):
        logAMass[j] = math.log(AtomicMass.getMass(cname[j]))
        #//System.out.println("j " + j + " logAMass " + logAMass[j]);
     
    for i in range(numDeps):

        rho[0][i] = 0.0
        for j in range(nelemAbnd):
            logAddend = logNz[j][i] + lAmu + logAMass[j]
            rho[0][i] = rho[0][i] + math.exp(logAddend) 
            rho[1][i] = math.log(rho[0][i])
            
    return rho  
Пример #3
0
def convec(numDeps, tauRos, depths, temp, press, rho, kappa, kappaSun, zScale,
           teff, logg, mmw):

    logE = math.log10(math.E)  #// for debug output
    ln10 = math.log(10.0)  #//needed to convert logg from base 10 to base e

    convTemp = [[0.0 for i in range(numDeps)] for j in range(2)]

    #//Schwarzschild criterion for convective instability:
    gamma = 5.0 / 3.0  #//adiabatic gamma for ideal monatomic gas - the photon gas is negligible in stars w convection
    gammaFac = gamma / (
        gamma - 1.0
    )  #// yeah, yeah - I know it's 2.5, but let's show where it comes from for the record...
    invGamFac = 1.0 / gammaFac
    #//CHEAT: Set gammaThing to value that makes convection just disappear at bottom of mid-F star (7000 K)
    #//double gammaThing = 1.60;
    #//double invGamThing = 1.0 / gammaThing;
    #double invGamThing;
    #//System.out.println("gammaThing " + gammaThing);

    #double deltaP, deltaT; //, dlnPdlnT;
    #double dlnTdlnP, dlnMudlnP, deltaMu;

    #double Hp, logHp;

    #//double HpSun = 1.2535465715411615E7;  //cm, as computed by GrayStar at depth index=36
    HpSun = 2.0e7  #//cm, approximately as computed by GrayStar at depth index=36
    logHpSun = math.log(HpSun)

    #//Compute the presure scale height as a reality check:
    HpRefDep = 36  #//index of reference depth for computing pressure scale height
    logHp = press[1][HpRefDep] - rho[1][HpRefDep] - ln10 * logg
    Hp = math.exp(logHp)

    #//Try scaling gamma to "fix" the convective boundary
    #//invGamThing = invGamFac * HpSun/Hp;

    #//System.out.println("Hp/HpSun " + Hp/HpSun);

    #//double[] mmw = State.mmwFn(numDeps, temp, zScale);

    #//Search outward for top of convection zone
    isStable = False
    iBound = numDeps - 1  #//initialize index of depth where convection begins to bottom of atmosphere
    for i in range(numDeps - 2, 0, -1):

        #//System.out.println("Hp " + Hp);
        #//1st order finite difference - erratic?
        #//double deltaP = press[1][i] - press[1][i-1];
        #//double deltaT = temp[1][i] - temp[1][i-1];
        #//Try "2nd order" finite difference - non-uniform spacing in deltaT
        deltaP = press[1][i + 1] - press[1][i - 1]
        deltaT = temp[1][i + 1] - temp[1][i - 1]
        deltaMu = (mmw[i + 1] - mmw[i]) * Useful.amu
        #//dlnPdlnT = deltaP / deltaT;
        dlnTdlnP = deltaT / deltaP
        dlnMudlnP = deltaMu / deltaP
        #//System.out.format("%12.8f   %12.8f%n", logE * tauRos[1][i], dlnPlndT);
        #// This can be finicky - let's say we have not found the radiative zone unless two consecutive layers meet the criterion
        #//if (dlnPdlnT > gammaThing) {
        if (dlnTdlnP < invGamFac + dlnMudlnP):

            #//Convectively stable
            if (isStable == False):
                #//The previous convectively unstable layer was an isolated anomoly - we're have NOT found the zone!  Reset:
                isStable = true
                iBound = i
                #//System.out.println("First stable layer was found, tauRos " + logE * tauRos[1][i] + " NOW: isStable " + isStable);

            #}
        #}
    #}
    #//System.out.println("Convec: iBound " + iBound);

    #//Radiative zone - leave temperatures alone:
    for i in range(iBound):
        convTemp[0][i] = temp[0][i]
        convTemp[1][i] = temp[1][i]

    baseTemp = temp[0][iBound]
    baseLogTemp = temp[1][iBound]
    baseTau = tauRos[0][iBound]
    baseLogTau = tauRos[1][iBound]
    #//double baseDepth = depths[iBound]

    logSigma = Useful.logSigma()
    logK = Useful.logK()
    logAmu = Useful.logAmu()

    mixLSun = 1.0  #// convective mixing length in pressure scale heights (H_P)

    betaSun = 0.5  #// factor for square of  convective bubble velocity (range: 0.0 - 1.0)

    #double Cp, logCp;  //Specific heat capacity at constant pressure
    mixL = mixLSun  #//initialization
    beta = betaSun  #//initialization
    teffSun = 5778.0
    loggSun = 4.44

    #//Shameless fix:
    #//It seems mixL and beta need to be temp and press dependent:
    if (teff < teffSun):
        mixL = mixLSun * math.pow(
            teff / teffSun,
            4.0)  #//lower teff -> smaller mixL -> steeper SAdGrad
        beta = betaSun * math.pow(
            teff / teffSun,
            4.0)  #//lower teff -> smaller beta -> steeper SAdGrad

    mixL = mixL * math.pow(
        loggSun / logg, 2.0)  #// lower logg -> larger mixL -> smaller sAdGrad
    beta = beta * math.pow(
        loggSun / logg, 2.0)  #// lower logg -> larger beta -> smaller sAdGrad
    """/*
        //Shameless fix:
        beta = betaSun;  // no fix?
        mixL = mixLSun * Math.pow(Hp / HpSun, 4.0);  //lower teff -> smaller Hp -> smaller mixL -> steeper SAdGrad
        //mixL = mixL * Math.pow(logg / loggSun, 4.0); // lower logg -> smaller mixL -> larger sAdGrad
    */"""
    logMixL = math.log(mixL)
    logBeta = math.log(beta)

    logFluxSurfBol = logSigma + 4.0 * math.log(teff)

    #// This will get hairy when we take it super-adiabatic so let's take it *really* easy and make every factor and term clear:
    logInvGamFac = math.log(invGamFac)

    #//Get the mean molecular weight in amu from State - Row 0 is "mu" in amu:
    #double mu, logMu, logFctr1, logFctr2, logFctr3;
    #double nextTemp, lastTemp, nextTemp2;

    #//Adiabatic dT/dx gradients in various coordinates
    #//tau, logTau space
    #double logAdGradTauMag, logAdGradLogTauMag, adGradLogTau;
    #//SuperAdiabatic dT/dx gradients in various coordinates
    #double deltaTau, logDeltaTau, deltaLogTau, logDeltaLogTau;
    #double sAdGradLogTau, logSadGradR, logSadGradTau, logSadGradLogTau;
    #double lastLogTau;

    #//r space:
    #double logAdGradRMag, adGradR;

    #//SuperAdiabatic dT/dx gradients in various coordinates
    #double deltaR, logDeltaR;
    #/*
    #     double sAdGradR;
    #     double lastDepth;
    #     */

    lastTemp = baseTemp
    lastLogTau = baseLogTau
    #//lastDepth = baseDepth;

    #//System.out.println(
    #//        "tauRos[1][i]   (tauRos[1][i]-lastLogTau)   adGradLogTau   rho[1][i]   kappa[1][i]   lastTemp   nextTemp");
    for i in range(iBound, numDeps):

        mu = mmw[i]
        logMu = math.log(mu)
        logFctr1 = logMu + logAmu - logK
        #//System.out.println("logFactr1 " + logE*logFctr1 + " logInvGamFac " + logE*logInvGamFac + " logg " + logg);
        logCp = math.log(
            5.0 / 2.0
        ) - logFctr1  #//ideal monatomic gas - underestimate that neglects partial ionization

        #// ** Caution: These are log_e of the *magnitude* of the temperature gradients!
        #//The adiabatic dT/dTau in r space
        logAdGradRMag = logInvGamFac + logFctr1 + ln10 * logg  #//logg is in base 10

        #//This is baaad stuff - remember our tuaRos scale has *nothing* to do with our kappa values!
        #//The adiabatic dT/dTau in tau space - divide dT/dr by rho and kappa and make it +ve becasue we're in tau-space:
        #//Bad fake to fix artificially small dT/dr at low Teff - use kappaSun instead of kappa
        logAdGradTauMag = logAdGradRMag - rho[1][i] - kappa[1][i]
        #//The adiabatic dT/dLnTau in log_e(tau) space
        logAdGradLogTauMag = tauRos[1][i] + logAdGradTauMag

        #//Build the T(tau) in the convection zone:
        #// Work in logTau space - numerically safer??
        adGradLogTau = math.exp(
            logAdGradLogTauMag)  #//No minus sign - logTau increases inward...
        nextTemp = lastTemp + adGradLogTau * (tauRos[1][i] - lastLogTau)

        #//System.out.format("%12.8f   %12.8f   %12.8f   %12.8f   %12.8f   %7.1f   %7.1f%n", logE * tauRos[1][i], logE * (tauRos[1][i] - lastLogTau), adGradLogTau, logE * rho[1][i], logE * kappa[1][i], lastTemp, nextTemp);
        """/*
             // Do in geometric depth space
             adGradR = Math.exp(logAdGradRMag); // no minus sign - our depths *increase* inwards (they're NOT heights!)
             nextTemp = lastTemp + adGradR * (depths[i] - lastDepth);  
            
             //System.out.format("%12.8f   %12.8f   %12.8f   %7.1f   %7.1f%n", logE*tauRos[1][i], (depths[i] - lastDepth), adGradR, lastTemp, nextTemp);
             */"""
        #//Okay - now the difference between the superadiabatic and adiabatic dT/dr:
        logFctr2 = rho[1][i] + logCp + 2.0 * logMixL

        #// ** NOTE ** Should temp in the following line be the *convective* temp of the last depth???
        #// logg is in base 10 - convert to base e
        logFctr3 = 3.0 * (ln10 * logg - math.log(lastTemp)) / 2.0

        #//Difference between SuperAdibatic dT/dr and Adiabtic dT/dr in r-space - Carroll & Ostlie 2nd Ed. p. 328
        #//System.out.println("logFluxSurfBol " + logE * logFluxSurfBol + " logFctr2 " + logE * logFctr2 + " logFctr1 " + logE * logFctr1 + " logFctr3 " + logE * logFctr3 + " logBeta " + logE * logBeta);
        logDeltaR = logFluxSurfBol - logFctr2 + 2.0 * logFctr1 + logFctr3 - 0.5 * logBeta
        logDeltaR = 2.0 * logDeltaR / 3.0  #//DeltaR is above formula to the 2/3 power

        #//This is baaad stuff - remember our tuaRos scale has *nothing* to do with our kappa values!
        #//Bad fake to fix artificially small dT/dr at low Teff - use kappaSun instead of kappa
        logDeltaTau = logDeltaR - rho[1][i] - kappa[1][i]
        logDeltaLogTau = tauRos[1][i] + logDeltaTau
        sAdGradLogTau = adGradLogTau + math.exp(logDeltaLogTau)
        #//System.out.format("%12.8f   %12.8f   %12.8f   %12.8f%n", logE*tauRos[1][i], logE*logDeltaR, logE*logDeltaTau, logE*logDeltaLogTau);
        nextTemp2 = lastTemp + sAdGradLogTau * (tauRos[1][i] - lastLogTau)
        """/*
        // Do in geometric depth space
        sAdGradR = adGradR + Math.exp(logDeltaR);
        nextTemp2 = lastTemp + sAdGradR * (depths[i] - lastDepth);
        */"""
        #// set everything to nextTemp2 for superadibatic dT/dr, and to nexTemp for adiabatic dT/dr
        convTemp[0][i] = nextTemp2
        convTemp[1][i] = math.log(nextTemp2)
        lastTemp = nextTemp2
        lastLogTau = tauRos[1][i]
        #//lastDepth = depths[i]
    #}

    return convTemp