def fluxTrans(intens, flx, lambdas, cosTheta, radius, iFirstTheta, numTransThetas, rPlanet): #print("iFirstTheta ", iFirstTheta, " numTransThetas ", numTransThetas,\ # " rPlanet ", rPlanet) #//console.log("Entering flux3"); logTiny = -49.0 tiny = math.exp(logTiny) logPi = math.log(math.pi) numLams = len(lambdas) numThetas = len(cosTheta[0]) fluxTransSpec = [[[numpy.double(0.0) for i in range(numTransThetas)] for k in range(numLams)] for j in range(2)] #Earth-radii to solar radii: rPlanet = numpy.double(rPlanet) rPlanet = rPlanet * Useful.rEarth() / Useful.rSun() #dPlanet = 2.0 * rPlanet #print("dPlanet ", dPlanet) #subtract off flux eclipsed by transiting planet: #thisImpct = rPlanet #Default ##Can it really be this simple??: logOmega = math.log(math.pi) + (numpy.double(2.0) * (math.log(rPlanet) - math.log(radius))) #omega = math.exp(logOmega) #print("omega ", omega) helper = 0.0 logHelper = 0.0 for it in range(iFirstTheta, numThetas): for il in range(numLams): #Subtracting the very small from the very large - let's be sophisticated about it: logHelper = logPi + math.log( intens[il][it]) + logOmega - flx[1][il] helper = numpy.double(1.0) - math.exp(logHelper) #if (fluxTransSpec[0][il][it-iFirstTheta] > tiny): fluxTransSpec[1][il][it - iFirstTheta] = flx[1][il] + math.log(helper) #if (il == 150): # print("logHelper ", logHelper, " helper ", helper, " logFluxTransSpec ", logFluxTransSpec) fluxTransSpec[0][il][it - iFirstTheta] = math.exp( fluxTransSpec[1][il][it - iFirstTheta]) #if (il == 150): # print("fluxTransSpec 2 ", fluxTransSpec[0][il][it-iFirstTheta]) #plt.plot(cosTheta[1][iFirstTheta: iFirstTheta+numTransThetas],\ # ) return fluxTransSpec
def radPress(numDeps, temp): pRad = [[0.0 for i in range(numDeps)] for j in range(2)] logC = Useful.logC() logSigma = Useful.logSigma() radFac = math.log(4.0) + logSigma - math.log(3.0) - logC for i in range(numDeps): pRad[1][i] = radFac + 4.0 * temp[1][i] pRad[0][i] = math.exp(pRad[1][i]) return pRad
def opacHescat(numDeps, temp, lambda2, logGroundPops): """//c****************************************************************************** //c This routine computes He I Rayleigh scattering opacities. //c******************************************************************************""" #//System.out.println("opacHescat called"); sigHe = [0.0 for i in range(numDeps)] #//cross-section is zero below threshold, so initialize: for i in range(numDeps): sigHe[i] = 0.0 freq = Useful.c() / lambda2 #// include 'Atmos.com' #// include 'Kappa.com' #// include 'Linex.com' wavetemp = 2.997925e18 / min(freq, 5.15e15) ww = math.pow(wavetemp, 2) sig = (5.484e-14 / ww / ww) * math.pow( (1.0 + ((2.44e5 + (5.94e10 / (ww - 2.90e5))) / ww)), 2) for i in range(numDeps): sigHe[i] = sig * math.exp(logGroundPops[i]) return sigHe
def opacH2scat(numDeps, temp, lambda2, molPops): sigH2 = [0.0e0 for i in range(numDeps)] #//cross-section is zero below threshold, so initialize: for i in range(numDeps): sigH2[i] = 0.0 freq = Useful.c() / lambda2 """ //c****************************************************************************** //c This routine computes H2 I Rayleigh scattering opacities. //c****************************************************************************** // include 'Atmos.com' // include 'Kappa.com' // include 'Linex.com' """ wavetemp = 2.997925e18 / min(freq, 2.463e15) ww = wavetemp**2 sig = (8.14e-13 + (1.28e-6 / ww) + (1.61 / (ww * ww))) / (ww * ww) #print("freq ", freq, " wavetemp ", wavetemp, " ww ", ww, " sig ", sig) for i in range(numDeps): sigH2[i] = sig * math.exp(molPops[i]) #print("i " , i , " molPops " , molPops[i] , " sigH2 " , sigH2[i]) return sigH2
def plot_Oede(i, param, ylabel=None, ytick=None, ymax=1.01, quint=False, ylim=None): ax = fig.add_subplot(4, 3, i) for i in range(rr): sc = ax.scatter(Oede_cmb[i], param[i], color=Usf.colour(i + 1)) ax.grid(True) if quint: plt.xticks(np.arange(0.02, 0.0601, 0.01)) plt.xlim([0.02, 0.0601]) else: plt.xticks(np.arange(0.0, 0.09, 0.02)) plt.xlim(xmin=0) if ylim is not None: yin, yf = ylim plt.ylim([yin, yf]) if ytick is not None: yin, yf, yd = ytick plt.yticks(np.arange(yin, yf, yd)) plt.xlabel("$ \Omega_{ede}(z_{drag})$") plt.ylabel(ylabel)
def getNz(numDeps, temp, pGas, pe, ATot, nelemAbnd, logAz): #double[][] logNz = new double[nelemAbnd][numDeps]; logNz = [ [0.0 for i in range(numDeps)] for j in range(nelemAbnd) ] logATot = math.log(ATot) #double help, logHelp, logNumerator; for i in range(numDeps): #// Initial safety check to avoid negative logNz as Pg and Pe each converge: #// maximum physical Pe is about 0.5*PGas (complete ionization of pure H): if (pe[0][i] > 0.5 * pGas[0][i]): pe[0][i] = 0.5 * pGas[0][i] pe[1][i] = math.log(pe[0][i]) #// H (Z=1) is a special case: N_H(tau) = (Pg(tau)-Pe(tau))/{kTk(tau)A_Tot} logHelp = pe[1][i] - pGas[1][i] help = 1.0 - math.exp(logHelp) logHelp = math.log(help) logNumerator = pGas[1][i] + logHelp logNz[0][i] = logNumerator - Useful.logK() - temp[1][i] - logATot #// Remaining elements: for j in range(nelemAbnd): #// N_z = A_z * N_H: logNz[j][i] = logAz[j] + logNz[0][i] return logNz
def opacHscat(numDeps, temp, lambda2, logGroundPops): """//c****************************************************************************** //c This routine computes H I Rayleigh scattering opacities. //c******************************************************************************""" #//System.out.println("opacHscat called"); sigH = [0.0 for i in range(numDeps)] #//cross-section is zero below threshold, so initialize: for i in range(numDeps): sigH[i] = 0.0 freq = Useful.c() / lambda2 #// include 'Atmos.com' #// include 'Kappa.com' #// include 'Linex.com' wavetemp = 2.997925e18 / min(freq, 2.463e15) ww = math.pow(wavetemp, 2) sig = (5.799e-13 + (1.422e-6 / ww) + (2.784 / (ww * ww))) / (ww * ww) for i in range(numDeps): sigH[i] = sig * 2.0 * math.exp(logGroundPops[i]) return sigH
def PickTopLap(y,MU,mret,epsilon=1.0,sc=[],sens=-1): n=len(y); m=len(sc); deltQ=sens; scDP=[s+us.Lap(0,2*deltQ/epsilon) for s in sc]; return sorted([i for i in range(0,m)],key=lambda i:-scDP[i])[:mret];
def f(n): s = 0 for x in xrange(2,n/2): for y in range(1,x): if not Useful.gcd(x,y) == 1 and not y == 1: continue if (x+y)<= (n/2): s += n/(x+y)-1 return s*12 + (n-1)*6 + (n/2-1)*6
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
def phxSunNe(grav, numDeps, tauRos, scaleTemp, kappaScale): logE = math.log10(math.e) logEg = math.log(grav) #//base e! logEkappaScale = math.log(kappaScale); #//Theoretical radiative/convective model from Phoenix V15: phxSunPe64 = [ 1.53086468021591745e-07, 5.66518458165471424e-03, 6.72808433760886656e-03, 8.00271552708326656e-03, 9.51809762875982208e-03, 1.13117438884935648e-02, 1.34299756939525680e-02, 1.59287848014678144e-02, 1.88751877391284448e-02, 2.23491173128862976e-02, 2.64457686695698400e-02, 3.12779350532322240e-02, 3.69791374171045888e-02, 4.37078139287801024e-02, 5.16503829681397248e-02, 6.10221573903118336e-02, 7.20768505868849536e-02, 8.51123959415642752e-02, 1.00475763241309840e-01, 1.18571138726675232e-01, 1.39870552376136714e-01, 1.64923053015554560e-01, 1.94357063774820192e-01, 2.28928720249475840e-01, 2.69525262128246720e-01, 3.17192228891198592e-01, 3.73192988074577856e-01, 4.39058414038311360e-01, 5.16615873984964544e-01, 6.08066526878471680e-01, 7.16264581324812416e-01, 8.44657163125294336e-01, 9.97267452897639808e-01, 1.17915717019238848e+00, 1.39715732004723136e+00, 1.66026825646718432e+00, 1.97886823850223904e+00, 2.36716912384854112e+00, 2.84540915928013805e+00, 3.44853013665125120e+00, 4.21529199485384704e+00, 5.21488490421314560e+00, 6.56660005867586432e+00, 8.55643059606379776e+00, 1.16931723772200080e+01, 1.71629079266534368e+01, 2.75152019254691616e+01, 4.18720694941323264e+01, 7.66283674228108288e+01, 1.45995186997127872e+02, 3.04766672331673792e+02, 5.44151864837275328e+02, 8.17181982032739072e+02, 1.11216222784450608e+03, 1.43633935534913856e+03, 1.79603721463325728e+03, 2.19692608617747040e+03, 2.64548745663525184e+03, 3.14931730610757952e+03, 3.71721361233669376e+03, 4.35932065708395904e+03, 5.08736399892079296e+03, 5.91634943413070720e+03, 6.85104524590000384e+03] numPhxDeps = len(phxSunPe64) #//yeah, I know, 64, but that could change! logPhxSunPe64 = [0.0 for i in range(numPhxDeps)] for i in range(len(phxSunPe64)): logPhxSunPe64[i] = math.log(phxSunPe64[i]); logPhxSunTau64 = getLogPhxSunTau64() #// interpolate onto gS3 tauRos grid and re-scale with Teff: phxSunPe = [0.0 for i in range(numDeps)] logPhxSunPe = [0.0 for i in range(numDeps)] logScalePe = [0.0 for i in range(numDeps)] scaleNe = [ [0.0 for i in range(numDeps)] for j in range(2) ] for i in range(numDeps): logPhxSunPe[i] = ToolBox.interpol(logPhxSunTau64, logPhxSunPe64, tauRos[1][i]) logScalePe[i] = logEg + logPhxSunPe[i] - phxSunLogEg() - logEkappaScale scaleNe[1][i] = logScalePe[i] - scaleTemp[1][i] - Useful.logK() scaleNe[0][i] = math.exp(scaleNe[1][i]) #//System.out.println("scaleNe[1][i] " + logE * scaleNe[1][i]); return scaleNe
def dBdT(temp, lambda2): """// Computes the first partial derivative of B(T) wrt T, dB/dT:""" #double logdBdTlam; #//double c = Useful.c; //linear logC = Useful.logC() #//log #//double k = Useful.k #//linear logK = Useful.logK() #//log #//double h = Useful.h #//linear logH = Useful.logH() #//log logPreFac = math.log(2.0) + logH + 2.0 * logC #//log logExpFac = logH + logC - logK #//log #//Declare scratch variables: #double logLam, logTemp, logPreLamFac, logExpLamFac, expon, logExpon, eTerm, denom, logDenom; //log #//lambda = lambda * 1.0E-7; // convert nm to cm logLam = math.log(lambda2) #// Do the call to log for lambda once //log logTemp = math.log(temp) logPreLamFac = logPreFac + logExpFac - 6.0 * logLam - 2.0 * logTemp #//log logExpLamFac = logExpFac - logLam #//log #//This is very subtle and dangerous! logExpon = logExpLamFac - logTemp #// log of hc/kTlambda expon = math.exp(logExpon) #// hc/kTlambda eTerm = math.exp(expon) #// e^hc/ktlambda denom = eTerm - 1.0 #// e^hc/ktlambda - 1 logDenom = math.log(denom) #// log(e^hc/ktlambda - 1) logdBdTlam = logPreLamFac + expon - 2.0 * logDenom #//log return logdBdTlam; #} //end method dBdT
def phxRefNe(numDeps, scaleTemp, scalePe): logE = math.log10(math.e) scaleNe = [[0.0 for i in range(numDeps)] for j in range(2)] #for i in range(numDeps): # scaleNe[1][i] = scalePe[1][i] - scaleTemp[1][i] - Useful.logK() # scaleNe[0][i] = math.exp(scaleNe[1][i]) scaleNe[1] = [ scalePe[1][i] - scaleTemp[1][i] - Useful.logK() for i in range(numDeps) ] scaleNe[0] = [math.exp(x) for x in scaleNe[1]] return scaleNe
def estHerit(filename, num, epsilon, getVar=False, mph=3, direct="Temp"): varEst = divideData(filename, direct, num=num, mph=mph, delet=True) if getVar: return varEst[0] est = sum([v[1] / (sum(v)) for v in varEst]) / float(num) if epsilon < 0: return [sum(varEst[0]), est] print "Averaging and adding noise" est = est + us.Lap(0, epsilon / float(num)) if est < 0: est = 0.0 if est > 1: est = 1.0 print "The Result is " + str(est) return est
def plot_Oede(i, param, ylabel= None, ytick=None, ymax=1.01, quint= False, ylim=None): ax = fig.add_subplot(4,3,i) for i in range(rr): sc = ax.scatter(Oede_cmb[i], param[i], color=Usf.colour(i+1)) ax.grid(True) if quint: plt.xticks(np.arange(0.02, 0.0601, 0.01)) plt.xlim([0.02,0.0601]) else: plt.xticks(np.arange(0.0, 0.09, 0.02)) plt.xlim(xmin=0) if ylim is not None: yin, yf = ylim plt.ylim([yin, yf]) if ytick is not None: yin, yf, yd= ytick plt.yticks(np.arange(yin, yf, yd)) plt.xlabel("$ \Omega_{ede}(z_{drag})$") plt.ylabel(ylabel)
def PickTopNeigh(y,MU,mret,epsilon,neighDist=[],randBND=True,bnd=-1): n=len(y); m=len(neighDist); ep1=.1*epsilon; ep2=.9*epsilon; if len(neighDist)==0: sc=np.dot(MU,y);#[abs(sum([y[i]*mu[i] for i in range(0,n)])) for mu in MU]; sc=[abs(s) for s in sc] if bnd<0: bnd=sum(sorted(sc,reverse=True)[mret-1:mret+1])/2.0; if randBND: bnd=bnd+us.Lap(0,np.max(np.abs(MU))/ep1); bnd=abs(bnd); print "Calculating Distance" neighDist=fastNeigh(bnd,MU,y) m=len(MU); sc=[nei*ep2/(2.0*mret) for nei in neighDist]; return expPick(sc,mret);
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
def TransLight2(radius, cosTheta, vTrans, iFirstTheta, numTransThetas, impct): #Safety first: tiny = numpy.double(1.0e-49) logTiny = math.log(tiny) if (impct >= radius): #There is no eclipse (transit) return #thetaMinRad is also the minimum theta of the eclipse path chord, in RAD thetaMinRad = math.asin(impct / radius) #cos(theta) *decreases* with increasing theta in Quadrant I: cosThetaMax = math.cos(thetaMinRad) #Compute array of distances traveled, r, along semi-chord from position of #minimum impact parameter #12D array of length number-of-eclipse-thetas transit = [0.0 for i in range(numTransThetas)] #test = [0.0 for i in range(numThetas)] thisImpct = numpy.double(0.0) for i in range(numTransThetas): #print("i ", i) thisTheta = math.acos(cosTheta[1][i + iFirstTheta]) thisImpct = radius * math.sin(thisTheta) #test[i+iFirstTheta] = math.exp(logRatio) # impact parameter corresponding to this theta: thisB = radius * math.sin(thisTheta) # linear distance travelled along transit semi-path in solar radii transit[i] = math.sqrt(thisB**2 - impct**2) transit[i] = transit[i] * Useful.rSun() #RSun to cm #row 1 is Times at which successive annuli are eclipsed, in s: #Ephemeris zero point at transit mid-point transit[i] = transit[i] / vTrans #print("i ", i, " i+iFirstTheta ", i+iFirstTheta, " transit[1] ", transit[1][i+iFirstTheta]) return transit
#!/usr/bin/env python import pylab import numpy as np import matplotlib.pyplot as plt from scipy.interpolate import interp1d import matplotlib.cm as cm import pandas as pd import Useful as Usf params1 = Usf.setting_plot() pylab.rcParams.update(params1) zLOWZ = 0.32 zCMASS = 0.57 zLyaA = 2.34-0.06 zLyaC = 2.36+0.06 z_CMB = 1090.43 rd_EHtoCAMB =153.19/149.281 H0_lcdm = 67.31 rs_lcdm = 147.42 Om_lcdm = 0.31457 sig_lcdm= 0.82853 lna_cmb = np.log(1./(1+1060.0)) quint = True
def kappas2(numDeps, pe, zScale, temp, rho, numLams, lambdas, logAHe, \ logNH1, logNH2, logNHe1, logNHe2, Ne, teff, logKapFudge): """/* Compute opacities properly from scratch with real physical cross-sections */ // *** CAUTION: // // This return's "kappa" as defined by Gray 3rd Ed. - cm^2 per *relelvant particle* where the "releveant particle" // depends on *which* kappa """ #// #// *** CAUTION: #// #// This return's "kappa" as defined by Gray 3rd Ed. - cm^2 per *relelvant particle* where the "releveant particle" #// depends on *which* kappa log10E = math.log10(math.e) #//needed for g_ff logLog10E = math.log(log10E) logE10 = math.log(10.0) logNH = [0.0 for i in range(numDeps)] #//Total H particle number density cm^-3 #double logPH1, logPH2, logPHe1, logPHe2; for i in range(numDeps): logNH[i] = math.exp(logNH1[i]) + math.exp(logNH2[i]) logNH[i] = math.log(logNH[i]) #//System.out.println("i " + i + " logNH1 " + log10E*logNH1[i] + " logNH2 " + log10E*logNH2[i] #//+ " logNHe1 " + log10E*logNHe1[i] + " logNHe2 " + log10E*logNHe2[i] + " logPe " + log10E*pe[1][i]); #// logPH1 = logNH1[i] + temp[1][i] + Useful.logK(); #// logPH2 = logNH2[i] + temp[1][i] + Useful.logK(); #// logPHe1 = logNHe1[i] + temp[1][i] + Useful.logK(); #// logPHe2 = logNHe2[i] + temp[1][i] + Useful.logK(); #//System.out.println("i " + i + " logPH1 " + log10E*logPH1 + " logPH2 " + log10E*logPH2 #//+ " logPHe1 " + log10E*logPHe1 + " logPHe2 " + log10E*logPHe2 + " logPe " + log10E*pe[1][i]); #double[][] logKappa = new double[numLams][numDeps]; logKappa = [ [0.0 for i in range(numDeps)] for j in range(numLams) ] #double kappa; //helper #double stimEm; //temperature- and wavelength-dependent stimulated emission correction #double stimHelp, logStimEm; #double ii; //useful for converting integer loop counter, i, to float #// #// #//Input data and variable declarations: #// #// #// H I b-f & f-f chiIH = 13.598433 #//eV Rydberg = 1.0968e-2 #// "R" in nm^-1 #//Generate threshold wavelengths and b-f Gaunt (g_bf) helper factors up to n=10: #double n; //principle quantum number of Bohr atom E-level numHlevs = 10 #double logChiHlev; invThresh = [0.0 for i in range(numHlevs)] #//also serves as g_bf helper factor threshLambs = [0.0 for i in range(numHlevs)] chiHlev = [0.0 for i in range(numHlevs)] for i in range(numHlevs): n = 1.0 + float(i) invThresh[i] = Rydberg / n / n #//nm^-1; also serves as g_bf helper factor threshLambs[i] = 1.0 / invThresh[i] #//nm logChiHlev = Useful.logH() + Useful.logC() + math.log(invThresh[i]) + 7.0*logE10 #// ergs chiHlev[i] = math.exp(logChiHlev - Useful.logEv()) #//eV chiHlev[i] = chiIH - chiHlev[i] #// System.out.println("i " + i + " n " + n + " invThresh " + invThresh[i] + " threshLambs[i] " + threshLambs[i] + " chiHlev " + chiHlev[i]); logGauntPrefac = math.log(0.3456) - 0.333333*math.log(Rydberg) #// **** Caution: this will require lamba in A!: a0 = 1.0449e-26 #//if lambda in A logA0 = math.log(a0) #// Boltzmann const "k" in eV/K - needed for "theta" logKeV = Useful.logK() - Useful.logEv() #//g_bf Gaunt factor - depends on lower E-level, n: loggbf = [0.0 for i in range(numHlevs)] #//initialize quantities that depend on lowest E-level contributing to opacity at current wavelength: for iThresh in range(numHlevs): loggbf[iThresh] = 0.0 #double logGauntHelp, gauntHelp; #double gbf, gbfHelp, loggbfHelp; #double gff, gffHelp, loggffHelp, logffHelp, loggff; #double help, logHelp3; #double chiLambda, logChiLambda; #double bfTerm, logbfTerm, bfSum, logKapH1bf, logKapH1ff; #//initial defaults: gbf = 1.0 gff = 1.0 loggff = 0.0 logChiFac = math.log(1.2398e3) #// eV per lambda, for lambda in nm #// Needed for kappa_ff: #double ffBracket; logffHelp = logLog10E - math.log(chiIH) - math.log(2.0) #//logHelp = logffHelp - math.log(2.0) #// #//Hminus: #// #// H^- b-f #//This is for the sixth order polynomial fit to the cross-section's wavelength dependence numHmTerms = 7 logAHm = [0.0 for i in range(numHmTerms)] signAHm = [0.0 for i in range(numHmTerms)] aHmbf = 4.158e-10 #//double logAHmbf = Math.log(aHmbf); #//Is the factor of 10^-18cm^2 from the polynomial fit to alpha_Hmbf missing in Eq. 8.12 on p. 156 of Gray 3rd Ed?? logAHmbf = math.log(aHmbf) - 18.0*logE10 #double alphaHmbf, logAlphaHmbf, logTermHmbf, logKapHmbf; #//Computing each polynomial term logarithmically logAHm[0] = math.log(1.99654) signAHm[0] = 1.0 logAHm[1] = math.log(1.18267e-5) signAHm[1] = -1.0 logAHm[2] = math.log(2.64243e-6) signAHm[2] = 1.0 logAHm[3] = math.log(4.40524e-10) signAHm[3] = -1.0 logAHm[4] = math.log(3.23992e-14) signAHm[4] = 1.0 logAHm[5] = math.log(1.39568e-18) signAHm[5] = -1.0 logAHm[6] = math.log(2.78701e-23) signAHm[6] = 1.0 alphaHmbf = math.exp(logAHm[0]) #//initialize accumulator #// H^- f-f: logAHmff = -26.0*logE10 numHmffTerms = 5 #double fPoly, logKapHmff, logLambdaAFac; fHmTerms = [ [ 0.0 for i in range(numHmffTerms) ] for j in range(3) ] fHm = [0.0 for i in range(3)] fHmTerms[0][0] = -2.2763 fHmTerms[0][1] = -1.6850 fHmTerms[0][2] = 0.76661 fHmTerms[0][3] = -0.053346 fHmTerms[0][4] = 0.0 fHmTerms[1][0] = 15.2827 fHmTerms[1][1] = -9.2846 fHmTerms[1][2] = 1.99381 fHmTerms[1][3] = -0.142631 fHmTerms[1][4] = 0.0 fHmTerms[2][0] = -197.789 fHmTerms[2][1] = 190.266 fHmTerms[2][2] = -67.9775 fHmTerms[2][3] = 10.6913 fHmTerms[2][4] = -0.625151 #// #//H_2^+ molecular opacity - cool stars #// scasles with proton density (H^+) #//This is for the third order polynomial fit to the "sigma_l(lambda)" and "U_l(lambda)" #//terms in the cross-section numH2pTerms = 4 sigmaH2pTerm = [0.0 for i in range(numH2pTerms)] UH2pTerm = [0.0 for i in range(numH2pTerms)] #double logSigmaH2p, sigmaH2p, UH2p, logKapH2p; aH2p = 2.51e-42 logAH2p = math.log(aH2p) sigmaH2pTerm[0] = -1040.54 sigmaH2pTerm[1] = 1345.71 sigmaH2pTerm[2] = -547.628 sigmaH2pTerm[3] = 71.9684 #//UH2pTerm[0] = 54.0532 #//UH2pTerm[1] = -32.713 #//UH2pTerm[2] = 6.6699 #//UH2pTerm[3] = -0.4574 #//Reverse signs on U_1 polynomial expansion co-efficients - Dave Gray private communcation #//based on Bates (1952) UH2pTerm[0] = -54.0532 UH2pTerm[1] = 32.713 UH2pTerm[2] = -6.6699 UH2pTerm[3] = 0.4574 #// He I b-f & ff: #double totalH1Kap, logTotalH1Kap, helpHe, logKapHe; #// #//He^- f-f AHe = math.exp(logAHe) #double logKapHemff, nHe, logNHe, thisTerm, thisLogTerm, alphaHemff, log10AlphaHemff; #// Gray does not have this pre-factor, but PHOENIX seems to and without it #// the He opacity is about 10^26 too high!: logAHemff = -26.0*logE10 numHemffTerms = 5 logC0HemffTerm = [0.0 for i in range(numHemffTerms)] logC1HemffTerm = [0.0 for i in range(numHemffTerms)] logC2HemffTerm = [0.0 for i in range(numHemffTerms)] logC3HemffTerm = [0.0 for i in range(numHemffTerms)] signC0HemffTerm = [0.0 for i in range(numHemffTerms)] signC1HemffTerm = [0.0 for i in range(numHemffTerms)] signC2HemffTerm = [0.0 for i in range(numHemffTerms)] signC3HemffTerm = [0.0 for i in range(numHemffTerms)] #//we'll be evaluating the polynominal in theta logarithmically by adding logarithmic terms - logC0HemffTerm[0] = math.log(9.66736) signC0HemffTerm[0] = 1.0 logC0HemffTerm[1] = math.log(71.76242) signC0HemffTerm[1] = -1.0 logC0HemffTerm[2] = math.log(105.29576) signC0HemffTerm[2] = 1.0 logC0HemffTerm[3] = math.log(56.49259) signC0HemffTerm[3] = -1.0 logC0HemffTerm[4] = math.log(10.69206) signC0HemffTerm[4] = 1.0 logC1HemffTerm[0] = math.log(10.50614) signC1HemffTerm[0] = -1.0 logC1HemffTerm[1] = math.log(48.28802) signC1HemffTerm[1] = 1.0 logC1HemffTerm[2] = math.log(70.43363) signC1HemffTerm[2] = -1.0 logC1HemffTerm[3] = math.log(37.80099) signC1HemffTerm[3] = 1.0 logC1HemffTerm[4] = math.log(7.15445) signC1HemffTerm[4] = -1.0 logC2HemffTerm[0] = math.log(2.74020) signC2HemffTerm[0] = 1.0 logC2HemffTerm[1] = math.log(10.62144) signC2HemffTerm[1] = -1.0 logC2HemffTerm[2] = math.log(15.50518) signC2HemffTerm[2] = 1.0 logC2HemffTerm[3] = math.log(8.33845) signC2HemffTerm[3] = -1.0 logC2HemffTerm[4] = math.log(1.57960) signC2HemffTerm[4] = 1.0 logC3HemffTerm[0] = math.log(0.19923) signC3HemffTerm[0] = -1.0 logC3HemffTerm[1] = math.log(0.77485) signC3HemffTerm[1] = 1.0 logC3HemffTerm[2] = math.log(1.13200) signC3HemffTerm[2] = -1.0 logC3HemffTerm[3] = math.log(0.60994) signC3HemffTerm[3] = 1.0 logC3HemffTerm[4] = math.log(0.11564) signC3HemffTerm[4] = -1.0 # //initialize accumulators: cHemff = [0.0 for i in range(4)] cHemff[0] = signC0HemffTerm[0] * math.exp(logC0HemffTerm[0]); cHemff[1] = signC1HemffTerm[0] * math.exp(logC1HemffTerm[0]); cHemff[2] = signC2HemffTerm[0] * math.exp(logC2HemffTerm[0]); cHemff[3] = signC3HemffTerm[0] * math.exp(logC3HemffTerm[0]); #// #//Should the polynomial expansion for the Cs by in 10g10Theta?? No! Doesn't help: #//double[] C0HemffTerm = new double[numHemffTerms]; #//double[] C1HemffTerm = new double[numHemffTerms]; #//double[] C2HemffTerm = new double[numHemffTerms]; #//double[] C3HemffTerm = new double[numHemffTerms]; #// #//C0HemffTerm[0] = 9.66736; #//C0HemffTerm[1] = -71.76242; #//C0HemffTerm[2] = 105.29576; #//C0HemffTerm[3] = -56.49259; #//C0HemffTerm[4] = 10.69206; #//C1HemffTerm[0] = -10.50614; #//C1HemffTerm[1] = 48.28802; #//C1HemffTerm[2] = -70.43363; #//C1HemffTerm[3] = 37.80099; #//C1HemffTerm[4] = -7.15445; #//C2HemffTerm[0] = 2.74020; #//C2HemffTerm[1] = -10.62144; #//C2HemffTerm[2] = 15.50518; #//C2HemffTerm[3] = -8.33845; #//C2HemffTerm[4] = 1.57960; #//C3HemffTerm[0] = -0.19923; #//C3HemffTerm[1] = 0.77485; #//C3HemffTerm[2] = -1.13200; #//C3HemffTerm[3] = 0.60994; #//C3HemffTerm[4] = -0.11564; #//initialize accumulators: #// double[] cHemff = new double[4]; #// cHemff[0] = C0HemffTerm[0]; #// cHemff[1] = C1HemffTerm[0]; #// cHemff[2] = C2HemffTerm[0]; #// cHemff[3] = C3HemffTerm[0]; #// #// electron (e^-1) scattering (Thomson scattering) #double kapE, logKapE; alphaE = 0.6648e-24 #//cm^2/e^-1 logAlphaE = math.log(0.6648e-24) #//Universal: #// # double theta, logTheta, log10Theta, log10ThetaFac; # double logLambda, lambdaA, logLambdaA, log10LambdaA, lambdanm, logLambdanm; #//Okay - here we go: #//Make the wavelength loop the outer loop - lots of depth-independnet lambda-dependent quantities: #// #// # //System.out.println("Kappas called..."); #// #// **** START WAVELENGTH LOOP iLam #// #// #// for iLam in range(numLams): #// #//Re-initialize all accumulators to be on safe side: kappa = 0.0 logKapH1bf = -99.0 logKapH1ff = -99.0 logKapHmbf = -99.0 logKapHmff = -99.0 logKapH2p = -99.0 logKapHe = -99.0 logKapHemff = -99.0 logKapE = -99.0 #// #//*** CAUTION: lambda MUST be in nm here for consistency with Rydbeg logLambda = math.log(lambdas[iLam]) #//log cm lambdanm = 1.0e7 * lambdas[iLam] logLambdanm = math.log(lambdanm) lambdaA = 1.0e8 * lambdas[iLam] #//Angstroms logLambdaA = math.log(lambdaA) log10LambdaA = log10E * logLambdaA logChiLambda = logChiFac - logLambdanm chiLambda = math.exp(logChiLambda) #//eV #// Needed for both g_bf AND g_ff: logGauntHelp = logGauntPrefac - 0.333333*logLambdanm #//lambda in nm here gauntHelp = math.exp(logGauntHelp) #// if (iLam == 142){ #// System.out.println("lambdaA " + lambdaA); #// } #//HI b-f depth independent factors: #//Start at largest threshold wavelength and break out of loop when next threshold lambda is less than current lambda: #for (iThresh = numHlevs-1; iThresh >= 0; iThresh--){ for iThresh in range(0, numHlevs-1, -1): if (threshLambs[iThresh] < lambdanm): break if (lambdanm <= threshLambs[iThresh]): #//this E-level contributes loggbfHelp = logLambdanm + math.log(invThresh[iThresh]) # //lambda in nm here; invThresh here as R/n^2 gbfHelp = math.exp(loggbfHelp) gbf = 1.0 - (gauntHelp * (gbfHelp - 0.5)) #// if (iLam == 1){} #// System.out.println("iThresh " + iThresh + " threshLambs " + threshLambs[iThresh] + " gbf " + gbf); #// } loggbf[iThresh] = math.log(gbf) #//end iThresh loop #//HI f-f depth independent factors: # //logChi = logLog10E + logLambdanm - logChiFac; //lambda in nm here # //chi = Math.exp(logChi); loggffHelp = logLog10E - logChiLambda #// #// #// #// ****** Start depth loop iTau ****** #// #// #// #// for iTau in range(numDeps): #// # //Re-initialize all accumulators to be on safe side: kappa = 0.0 logKapH1bf = -99.0 logKapH1ff = -99.0 logKapHmbf = -99.0 logKapHmff = -99.0 logKapH2p = -99.0 logKapHe = -99.0 logKapHemff = -99.0 logKapE = -99.0 #// #// #//if (iTau == 36 && iLam == 142){ #// System.out.println("lambdanm[142] " + lambdanm + " temp[0][iTau=36] " + temp[0][iTau=36]); #// } #//This is "theta" ~ 5040/T: logTheta = logLog10E - logKeV - temp[1][iTau] log10Theta = log10E * logTheta theta = math.exp(logTheta) #//System.out.println("theta " + theta + " logTheta " + logTheta); #// temperature- and wavelength-dependent stimulated emission coefficient: stimHelp = -1.0 * theta * chiLambda * logE10 stimEm = 1.0 - math.exp(stimHelp) logStimEm = math.log(stimEm) # // if (iTau == 36 && iLam == 142){ # // System.out.println("stimEm " + stimEm); # //} ffBracket = math.exp(loggffHelp - logTheta) + 0.5 gff = 1.0 + (gauntHelp*ffBracket) #//if (iTau == 36 && iLam == 1){ #// System.out.println("gff " + gff); #// } loggff = math.log(gff) #//H I b-f: #//Start at largest threshold wavelength and break out of loop when next threshold lambda is less than current lambda: bfSum = 0.0 #//initialize accumulator logHelp3 = logA0 + 3.0*logLambdaA #//lambda in A here #for (int iThresh = numHlevs-1; iThresh >= 0; iThresh--){ for iThresh in range(0, numHlevs-1, -1): if (threshLambs[iThresh] < lambdanm): break n = 1.0 + float(iThresh) if (lambdanm <= threshLambs[iThresh]): #//this E-level contributes logbfTerm = loggbf[iThresh] - 3.0*math.log(n) logbfTerm = logbfTerm - (theta*chiHlev[iThresh])*logE10 bfSum = bfSum + math.exp(logbfTerm) #//if (iTau == 36 && iLam == 142){ # //System.out.println("lambdanm " + lambdanm + " iThresh " + iThresh + " threshLambs[iThresh] " + threshLambs[iThresh]); # //System.out.println("loggbf " + loggbf[iThresh] + " theta " + theta + " chiHlev " + chiHlev[iThresh]); # //System.out.println("bfSum " + bfSum + " logbfTerm " + logbfTerm); #// } #//end iThresh loop #// cm^2 per *neutral* H atom logKapH1bf = logHelp3 + math.log(bfSum) #//Stimulated emission correction logKapH1bf = logKapH1bf + logStimEm #//System.out.println("lambda " + lambdas[iLam] + "iTau " + iTau + " sigma " + Math.exp(logKapH1bf)); #//Add it in to total - opacity per neutral HI atom, so multiply by logNH1 #// This is now linear opacity in cm^-1 logKapH1bf = logKapH1bf + logNH1[iTau] #//System.out.println(" aH1 " + Math.exp(logKapH1bf)); #////Nasty fix to make Balmer lines show up in A0 stars! #// if (teff > 8000){ #// logKapH1bf = logKapH1bf - logE10*1.5; #// kappa = math.exp(logKapH1bf) #//System.out.println("HIbf " + log10E*logKapH1bf); #//if (iTau == 36 && iLam == 142){ #// System.out.println("lambdaA " + lambdaA + " logKapH1bf " + log10E*(logKapH1bf)); //-rho[1][iTau])); #//} #//H I f-f: #// cm^2 per *neutral* H atom logKapH1ff = logHelp3 + loggff + logffHelp - logTheta - (theta*chiIH)*logE10 #//Stimulated emission correction logKapH1ff = logKapH1ff + logStimEm #//Add it in to total - opacity per neutral HI atom, so multiply by logNH1 #// This is now linear opacity in cm^-1 logKapH1ff = logKapH1ff + logNH1[iTau] #////Nasty fix to make Balmer lines show up in A0 stars! #// if (teff > 8000){ #// logKapH1ff = logKapH1ff - logE10*1.5; #// kappa = kappa + math.exp(logKapH1ff); #//System.out.println("HIff " + log10E*logKapH1ff); #//if (iTau == 36 && iLam == 142){ #// System.out.println("logKapH1ff " + log10E*(logKapH1ff)); //-rho[1][iTau])); #//} #// #//Hminus: #// #// H^- b-f: #//if (iTau == 36 && iLam == 142){ # // System.out.println("temp " + temp[0][iTau] + " lambdanm " + lambdanm); # // } logKapHmbf = -99.0 #//initialize default #//if ( (temp[0][iTau] > 2500.0) && (temp[0][iTau] < 10000.0) ){ #//if ( (temp[0][iTau] > 2500.0) && (temp[0][iTau] < 8000.0) ){ #//Try lowering lower Teff limit to avoid oapcity collapse in outer layers of late-type stars if ( (temp[0][iTau] > 1000.0) and (temp[0][iTau] < 10000.0) ): if ((lambdanm > 225.0) and (lambdanm < 1500.0) ): # //nm #//if (iTau == 36 && iLam == 142){ # // System.out.println("In KapHmbf condition..."); #//} ii = 0.0 alphaHmbf = signAHm[0]*math.exp(logAHm[0]) #//initialize accumulator #for (int i = 1; i < numHmTerms; i++){ for i in range(1, numHmTerms): ii = float(i) #//if (iTau == 36 && iLam == 142){ #// System.out.println("ii " + ii); #//} logTermHmbf = logAHm[i] + ii*logLambdaA alphaHmbf = alphaHmbf + signAHm[i]*math.exp(logTermHmbf) #//if (iTau == 36 && iLam == 142){ #// System.out.println("logTermHmbf " + log10E*logTermHmbf + " i " + i + " logAHm " + log10E*logAHm[i]); #//} logAlphaHmbf = math.log(alphaHmbf) #// cm^2 per neutral H atom logKapHmbf = logAHmbf + logAlphaHmbf + pe[1][iTau] + 2.5*logTheta + (0.754*theta)*logE10 #//Stimulated emission correction logKapHmbf = logKapHmbf + logStimEm #//if (iTau == 36 && iLam == 142){ #// System.out.println("alphaHmbf " + alphaHmbf); #// System.out.println("logKapHmbf " + log10E*logKapHmbf + " logAHmbf " + log10E*logAHmbf + " logAlphaHmbf " + log10E*logAlphaHmbf); #// } #//Add it in to total - opacity per neutral HI atom, so multiply by logNH1 #// This is now linear opacity in cm^-1 logKapHmbf = logKapHmbf + logNH1[iTau] kappa = kappa + math.exp(logKapHmbf) #//System.out.println("Hmbf " + log10E*logKapHmbf); #//if (iTau == 36 && iLam == 142){ #// System.out.println("logKapHmbf " + log10E*(logKapHmbf)); //-rho[1][iTau])); #//} #//wavelength condition #// temperature condition #// H^- f-f: logKapHmff = -99.0 #//initialize default #//if ( (temp[0][iTau] > 2500.0) && (temp[0][iTau] < 10000.0) ){ #//Try lowering lower Teff limit to avoid oapcity collapse in outer layers of late-type stars #//if ( (temp[0][iTau] > 2500.0) && (temp[0][iTau] < 8000.0) ){ if ( (temp[0][iTau] > 1000.0) and (temp[0][iTau] < 10000.0) ): if ((lambdanm > 260.0) and (lambdanm < 11390.0) ): #//nm #//construct "f_n" polynomials in log(lambda) for j in range(3): fHm[j] = fHmTerms[j][0] #//initialize accumulators ii = 0.0 for i in range(1, numHmffTerms): ii = float(i) logLambdaAFac = math.pow(log10LambdaA, ii) for j in range(3): fHm[j] = fHm[j] + (fHmTerms[j][i]*logLambdaAFac) #} #// i #} #// j #// fPoly = fHm[0] + fHm[1]*log10Theta + fHm[2]*log10Theta*log10Theta #// In cm^2 per neutral H atom: #// Stimulated emission alreadya ccounted for logKapHmff = logAHmff + pe[1][iTau] + fPoly*logE10 #//Add it in to total - opacity per neutral HI atom, so multiply by logNH1 #// This is now linear opacity in cm^-1 logKapHmff = logKapHmff + logNH1[iTau] kappa = kappa + math.exp(logKapHmff) #//System.out.println("Hmff " + log10E*logKapHmff); #//if (iTau == 36 && iLam == 142){ #// System.out.println("logKapHmff " + log10E*(logKapHmff)); //-rho[1][iTau])); #//} #//wavelength condition #// temperature condition #// H^+_2: #// logKapH2p = -99.0 #//initialize default if ( temp[0][iTau] < 4000.0 ): if ((lambdanm > 380.0) and (lambdanm < 2500.0) ): # //nm sigmaH2p = sigmaH2pTerm[0] #//initialize accumulator UH2p = UH2pTerm[0] #//initialize accumulator ii = 0.0# for i in range(1, numH2pTerms): ii = float(i) logLambdaAFac = math.pow(log10LambdaA, ii) #// kapH2p way too large with lambda in A - try cm: No! - leads to negative logs #//logLambdaAFac = Math.pow(logLambda, ii); sigmaH2p = sigmaH2p + sigmaH2pTerm[i] * logLambdaAFac UH2p = UH2p + UH2pTerm[i] * logLambdaAFac logSigmaH2p = math.log(sigmaH2p) logKapH2p = logAH2p + logSigmaH2p - (UH2p*theta)*logE10 + logNH2[iTau] #//Stimulated emission correction logKapH2p = logKapH2p + logStimEm #//Add it in to total - opacity per neutral HI atom, so multiply by logNH1 #// This is now linear opacity in cm^-1 logKapH2p = logKapH2p + logNH1[iTau] kappa = kappa + math.exp(logKapH2p) #//System.out.println("H2p " + log10E*logKapH2p); #//if (iTau == 16 && iLam == 142){ # //System.out.println("logKapH2p " + log10E*(logKapH2p-rho[1][iTau]) + " logAH2p " + log10E*logAH2p #// + " logSigmaH2p " + log10E*logSigmaH2p + " (UH2p*theta)*logE10 " + log10E*((UH2p*theta)*logE10) + " logNH2[iTau] " + log10E*logNH2[iTau]); #//} #//wavelength condition #// temperature condition #//He I #// #// HeI b-f + f-f #//Scale sum of He b-f and f-f with sum of HI b-f and f-f #//wavelength condition comes from requirement that lower E level be greater than n=2 (edge at 22.78 nm) logKapHe = -99.0 #//default intialization if ( temp[0][iTau] > 10000.0 ): if (lambdanm > 22.8): #//nm totalH1Kap = math.exp(logKapH1bf) + math.exp(logKapH1ff) logTotalH1Kap = math.log(totalH1Kap) helpHe = Useful.k() * temp[0][iTau] #// cm^2 per neutral H atom (after all, it's scaled wrt kappHI #// Stimulated emission already accounted for #// #// *** CAUTION: Is this *really* the right thing to do??? #// - we're re-scaling the final H I kappa in cm^2/g corrected for stim em, NOT the raw cross section logKapHe = math.log(4.0) - (10.92 / helpHe) + logTotalH1Kap #//Add it in to total - opacity per neutral HI atom, so multiply by logNH1 #// This is now linear opacity in cm^-1 logKapHe = logKapHe + logNH1[iTau] kappa = kappa + math.exp(logKapHe) #//System.out.println("He " + log10E*logKapHe); #//if (iTau == 36 && iLam == 142){ #// System.out.println("logKapHe " + log10E*(logKapHe)); //-rho[1][iTau])); #//} #//wavelength condition #// temperature condition #// #//He^- f-f: logKapHemff = -99.0 #//default initialization if ( (theta > 0.5) and (theta < 2.0) ): if ((lambdanm > 500.0) and (lambdanm < 15000.0) ): #// initialize accumulators: cHemff[0] = signC0HemffTerm[0]*math.exp(logC0HemffTerm[0]); #//System.out.println("C0HemffTerm " + signC0HemffTerm[0]*Math.exp(logC0HemffTerm[0])); cHemff[1] = signC1HemffTerm[0]*math.exp(logC1HemffTerm[0]); #//System.out.println("C1HemffTerm " + signC1HemffTerm[0]*Math.exp(logC1HemffTerm[0])); cHemff[2] = signC2HemffTerm[0]*math.exp(logC2HemffTerm[0]); #//System.out.println("C2HemffTerm " + signC2HemffTerm[0]*Math.exp(logC2HemffTerm[0])); cHemff[3] = signC3HemffTerm[0]*math.exp(logC3HemffTerm[0]); #//System.out.println("C3HemffTerm " + signC3HemffTerm[0]*Math.exp(logC3HemffTerm[0])); #//build the theta polynomial coefficients ii = 0.0 for i in range(1, numHemffTerms): ii = float(i) thisLogTerm = ii*logTheta + logC0HemffTerm[i] cHemff[0] = cHemff[0] + signC0HemffTerm[i]*math.exp(thisLogTerm) #//System.out.println("i " + i + " ii " + ii + " C0HemffTerm " + signC0HemffTerm[i]*Math.exp(logC0HemffTerm[i])); thisLogTerm = ii*logTheta + logC1HemffTerm[i] cHemff[1] = cHemff[1] + signC1HemffTerm[i]*math.exp(thisLogTerm) #//System.out.println("i " + i + " ii " + ii + " C1HemffTerm " + signC1HemffTerm[i]*Math.exp(logC1HemffTerm[i])); thisLogTerm = ii*logTheta + logC2HemffTerm[i] cHemff[2] = cHemff[2] + signC2HemffTerm[i]*math.exp(thisLogTerm) #//System.out.println("i " + i + " ii " + ii + " C2HemffTerm " + signC2HemffTerm[i]*Math.exp(logC2HemffTerm[i])); thisLogTerm = ii*logTheta + logC3HemffTerm[i] cHemff[3] = cHemff[3] + signC3HemffTerm[i]*math.exp(thisLogTerm) #//System.out.println("i " + i + " ii " + ii + " C3HemffTerm " + signC3HemffTerm[i]*Math.exp(logC3HemffTerm[i])); #//// Should polynomial expansion for Cs be in log10Theta??: - No! Doesn't help #// initialize accumulators: #// cHemff[0] = C0HemffTerm[0]; #// cHemff[1] = C1HemffTerm[0]; #// cHemff[2] = C2HemffTerm[0]; #// cHemff[3] = C3HemffTerm[0]; #// ii = 0.0; #// for (int i = 1; i < numHemffTerms; i++){ #// ii = (double) i; #// log10ThetaFac = Math.pow(log10Theta, ii); #// thisTerm = log10ThetaFac * C0HemffTerm[i]; #// cHemff[0] = cHemff[0] + thisTerm; #// thisTerm = log10ThetaFac * C1HemffTerm[i]; #// cHemff[1] = cHemff[1] + thisTerm; #// thisTerm = log10ThetaFac * C2HemffTerm[i]; #// cHemff[2] = cHemff[2] + thisTerm; #// thisTerm = log10ThetaFac * C3HemffTerm[i]; #// cHemff[3] = cHemff[3] + thisTerm; #// } #//Build polynomial in logLambda for alpha(He^1_ff): log10AlphaHemff = cHemff[0] #//initialize accumulation #//System.out.println("cHemff[0] " + cHemff[0]); ii = 0.0 for i in range(1, 3+1): #//System.out.println("i " + i + " cHemff[i] " + cHemff[i]); ii = float(i) thisTerm = cHemff[i] * math.pow(log10LambdaA, ii) log10AlphaHemff = log10AlphaHemff + thisTerm #//System.out.println("log10AlphaHemff " + log10AlphaHemff); alphaHemff = math.pow(10.0, log10AlphaHemff) #//gives infinite alphas! #// alphaHemff = log10AlphaHemff; // ?????!!!!! #//System.out.println("alphaHemff " + alphaHemff); #// Note: this is the extinction coefficient per *Hydrogen* particle (NOT He- particle!) # //nHe = Math.exp(logNHe1[iTau]) + Math.exp(logNHe2[iTau]); # //logNHe = Math.log(nHe); # //logKapHemff = Math.log(alphaHemff) + Math.log(AHe) + pe[1][iTau] + logNHe1[iTau] - logNHe; logKapHemff = logAHemff + math.log(alphaHemff) + pe[1][iTau] + logNHe1[iTau] - logNH[iTau] #//Stimulated emission already accounted for #//Add it in to total - opacity per H particle, so multiply by logNH #// This is now linear opacity in cm^-1 logKapHemff = logKapHemff + logNH[iTau] kappa = kappa + math.exp(logKapHemff) #//System.out.println("Hemff " + log10E*logKapHemff); #//if (iTau == 36 && iLam == 155){ #//if (iLam == 155){ #// System.out.println("logKapHemff " + log10E*(logKapHemff)); //-rho[1][iTau])); #//} #//wavelength condition #// temperature condition #// #// electron (e^-1) scattering (Thomson scattering) #//coefficient per *"hydrogen atom"* (NOT per e^-!!) (neutral or total H??): logKapE = logAlphaE + Ne[1][iTau] - logNH[iTau] #//Stimulated emission not relevent #//Add it in to total - opacity per H particle, so multiply by logNH #// This is now linear opacity in cm^-1 #//I know, we're adding logNH right back in after subtracting it off, but this is for dlarity and consistency for now... : logKapE = logKapE + logNH[iTau] kappa = kappa + math.exp(logKapE) #//System.out.println("E " + log10E*logKapE); #//if (iTau == 36 && iLam == 142){ #// System.out.println("logKapE " + log10E*(logKapE)); //-rho[1][iTau])); #//} #//Metal b-f #//Fig. 8.6 Gray 3rd Ed. #// #// #// This is now linear opacity in cm^-1 #// Divide by mass density #// This is now mass extinction in cm^2/g #// logKappa[iLam][iTau] = math.log(kappa) - rho[1][iTau] #// Fudge is in cm^2/g: Converto to natural log: logEKapFudge = logE10 * logKapFudge logKappa[iLam][iTau] = logKappa[iLam][iTau] + logEKapFudge #//if (iTau == 36 && iLam == 142){ #//System.out.println(" " + log10E*(logKappa[iLam][iTau]+rho[1][iTau])); #//} #// close iTau depth loop #// #//close iLam wavelength loop return logKappa
pc = pycontrol.Idaq(cfgfile = configfile) pc.loadOptimizer() settings_pycontrol.debugging = False #pc.read('mlens1') # #pc.read('mlens12_diff') #pc.instr.mips.maxFI = 5.5 import Useful, collections import time import Useful as useful useful.add_path_for_instruments(thisdir) import AttrDict celln = 'l1 l2 l3pm1 l4fh l5pm2 l6 fbias fil filV filP'.split() tunelist = 'l1 l2 l3pm1 l4fh l5pm2 l6 fbias fil'.split() Vtune = {'l3pm1': -5.4, 'fbias': -14.3, 'l4fh': 4.7, 'l6': -3.4, 'l2': -7.0, 'l1': 18.1, 'l5pm2': 20.8, 'fil': 0.0} cellzero = {'l3pm1': 0, 'fbias': 0, 'l4fh': 0, 'l6': 0, 'l2': 0, 'l1': 0, 'l5pm2': 0, 'fil': 0} optprior = dict(l1=24, l2=-7, l3pm1=-10, l4fh=-15, l5pm2=12, l6=-3.4, fbias=-20) optavg = dict(l1=24.2, l2=-12.7, l3pm1=-0.2, l4fh=-20.6, l5pm2=11.9, l6=3.5, fbias=-24.9) optnew = dict(l1=27.6, l2=-16.3, l3pm1=2.1, l4fh=-20.5, l5pm2=15.2, l6=0.1, fbias=-24.9) ecdinit = {'l3pm1': 16.3, 'fbias': 7.44, 'l4fh': 22.28, 'l6': -6.0, 'l2': -20.3, 'l1': 23.3, 'l5pm2': 22.3, 'fil': 1.22} ecdtune1 = {'l3pm1': 16.309999999999999, 'fbias': 2.4199999999999999, 'l4fh': 23.989999999999998, 'l6': -6.0, 'l2': -20.300000000000001, 'l1': 23.300000000000001, 'l5pm2': 22.300000000000001, 'fil': 1.22}
#based on http://arxiv.org/pdf/0906.0396.pdf # or http://arxiv.org/pdf/gr-qc/9711068v2.pdf #Scalar Field potential V=V0*exp[-lam*\phi] from RunBase import * from scipy import * import numpy as np from matplotlib import pyplot as plt from scipy.integrate import odeint from scipy.interpolate import interp1d from matplotlib import gridspec import pylab, sys import scipy.optimize as optimize import Useful as Usf params1 = Usf.setting_plot() pylab.rcParams.update(params1) name = 'Quint_vl_phi' pts, pts2, pts3, pts4 =[], [], [], [] Oma, Ora = [], [] lam = [] H_0, Om0 = 0.6821, 0.3038 Cte=sqrt(3.0)*H_0 Or0= sqrt(3.05)*Om0*1E-4
def estVarY(y, epsilon): vr = np.var(y) n = len(y) return vr + us.Lap(0, epsilon * 3 / float(n))
import Useful def has_mult(ps): for i,e in enumerate(ps): if e in ps[0:i]: return False return True primes = Useful.sieve(10**7) check = range(1,10) remain = list(check) count = 0 setsize = 2 while setsize < 10: for p in primes: ps = [int(n) for n in str(p)] ps.sort()
def flux3(intens, lambdas, cosTheta, phi, radius, omegaSini, macroV): #//console.log("Entering flux3"); #//System.out.println("radius " + radius + " omegaSini " + omegaSini + " macroV " + macroV); numLams = len(lambdas) numThetas = len(cosTheta[0]) fluxSurfSpec = [ [ 0.0 for i in range(numLams) ] for j in range(2) ] #// returns surface flux as a 2XnumLams vector #// - Row 0 linear flux (cgs units) #// - Row 1 log_e flux #// cosTheta is a 2xnumThetas array: #// row 0 is used for Gaussian quadrature weights #// row 1 is used for cos(theta) values #// Gaussian quadrature: #// Number of angles, numThetas, will have to be determined after the fact """/* Re-sampling makes thing worse - ?? //For internal use, interpolate flux spectrum onto uniform fine sampling grid: double specRes = 3.0e5; //spectral resolution R = lambda/deltaLambda double midLam = lambdas[numLams/2] * 1.0e7; //nm double delFine = midLam / specRes; //nm double lam1 = lambdas[0] * 1.0e7; //nm double lam2 = lambdas[numLams-1] * 1.0e7; //nm; double numFineD = (lam2 - lam1) / delFine; int numFine = (int) numFineD - 1; double newLambda[] = new double[numFine]; double newIntens[][] = new double[numFine][numThetas]; double thisNewIntens[] = new double[numFine]; double thisIntens[] = new double[numLams]; //System.out.println("midLam " + midLam + " delFine " + delFine + " lam1 " + lam1 + " lam2 " + lam2 + " numFine " + numFine); //Create fine wavelength array double ilD; for (int il = 0; il < numFine; il++){ ilD = (double) il; newLambda[il] = lam1 + ilD*delFine; //nm newLambda[il] = newLambda[il] * 1.0e-7; //cm } //System.out.println("newLambda[0] " + newLambda[0] + " [numFine-1] " + newLambda[numFine-1]); for (int it = 0; it < numThetas; it++){ for (int il = 0; il < numLams; il++){ thisIntens[il] = intens[il][it]; } //il loop thisNewIntens = ToolBox.interpolV(thisIntens, lambdas, newLambda); for (int il = 0; il < numFine; il++){ newIntens[il][it] = thisNewIntens[il]; } //il } //it loop */""" #//For geometry calculations: phi = 0 is direction of positive x-axis of right-handed #// 2D Cartesian coord system in plane of sky with origin at sub-stellar point (phi #// increases CCW) #double thisThetFctr; #//var numThetas = 11; numPhi = len(phi) delPhi = 2.0 * math.pi / numPhi #//console.log("delPhi " + delPhi); #//macroturbulent broadening helpers: #double uRnd1, uRnd2, ww, arg, gRnd1, gRnd2; #//intializations: uRnd1 = 0.0 uRnd2 = 0.0 gRnd1 = 0.0 gRnd2 = 0.0 arg = 0.0 #//For macroturbulent broadening, we need to transform uniformly #//generated random numbers on [0, 1] to a Gaussian distribution #// with a mean of 0.0 and a sigma of 1.0 #//Use the polar form of the Box-Muller transformation #// http://www.design.caltech.edu/erik/Misc/Gaussian.html #// Everett (Skip) Carter, Taygeta Scientific Inc. #//// Original code in c: #// ww = Math.sqrt #// do { #// x1 = 2.0 * ranf() - 1.0; #// x2 = 2.0 * ranf() - 1.0; #// w = x1 * x1 + x2 * x2; #// } while ( w >= 1.0 ); #// #// w = sqrt( (-2.0 * log( w ) ) / w ); #// y1 = x1 * w; #// y2 = x2 * w; #//helpers for rotational broadening #double x, opposite, theta; //, delLam; thisIntens = [0.0 for i in range(numLams)] intensLam = [0.0 for i in range(numLams)] #//double[] intensLam = new double[numFine]; #//This might not be the smartest approach, but, for now, compute the #//Doppler shifted wavelength scale across the whole tiled projected disk: #// #double sinTheta; #//double shiftedLam = 0.0; shiftedLamV = [0.0 for i in range(numLams)] #//double[] shiftedLamV = new double[numFine]; vRad = [ [ 0.0 for i in range(numPhi) ] for j in range(numThetas) ] #//For each (theta, phi) tile, compute the contributions to radial velocity #// from rotational broadening and macoturbulent broadening: #//test omegaSini = 0.0; //test for it in range(numThetas): #//theta = Math.acos(cosTheta[1][it]); #//opposite = radius * Math.sin(theta); #// Faster?? sinTheta = math.sqrt( 1.0 - (cosTheta[1][it]*cosTheta[1][it]) ) opposite = radius * sinTheta for ip in range(numPhi): #// x-position of each (theta, phi) point: #////theta = Math.acos(cosTheta[1][it]); #////opposite = radius * Math.sin(theta); #//sinTheta = Math.sqrt( 1.0 - (cosTheta[1][it]*cosTheta[1][it]) ); #//opposite = radius * sinTheta; x = opposite * math.cos(phi[ip]) vRad[it][ip] = x * omegaSini #// should be in cm/s #//System.out.println("it " + it + " cosTheta[1][it] " + cosTheta[1][it] + " ip " + ip + " phi[ip] " + (phi[ip]/2.0/Math.PI) + " x/R " + (x/radius) + " vRad " + (vRad[it][ip]/1.0e5)); #//For macroturbulent broadening, we need to transform uniformly #//generated random numbers on [0, 1] to a Gaussian distribution #// with a mean of 0.0 and a sigma of 1.0 #//Use the polar form of the Box-Muller transformation #// http://www.design.caltech.edu/erik/Misc/Gaussian.html #// Everett (Skip) Carter, Taygeta Scientific Inc. #//initialization that guarantees at least one cycle of the while loop ww = 2.0; #//cycle through pairs of uniform random numbers until we get a #//ww value that is less than unity while (ww >= 1.0): #// range [0, 1] uRnd1 = random.random() uRnd2 = random.random() #// range [-1, 1] uRnd1 = (2.0 * uRnd1) - 1.0 uRnd2 = (2.0 * uRnd2) - 1.0 ww = (uRnd1 * uRnd1) + (uRnd2 * uRnd2) #// We have a valid ww value - transform the uniform random numbers #// to Gaussian random numbers with sigma = macroturbulent velocity broadening arg = (-2.0 * math.log(ww)) / ww gRnd1 = macroV * arg * uRnd1 #//gRnd2 = macroV * arg * uRnd2; //not needed? #//console.log("gRnd1 " + gRnd1) vRad[it][ip] = vRad[it][ip] + gRnd1 #// should be in cm/s #} //ip loop - phi #} //it loop - theta flx = [0.0 for i in range(numLams)] #//double[] newFlx = new double[numFine]; #//Inititalize flux acumulator: for il in range(numLams): #//for (int il = 0; il < numFine; il++){ flx[il] = 0.0 #//newFlx[il] = 0.0; for it in range(numThetas): #//flx = flx + ( intens[it] * cosTheta[1][it] * cosTheta[0][it] ); //axi-symmetric version #//non-axi-symmetric version: thisThetFctr = cosTheta[1][it] * cosTheta[0][it] #//console.log("it " + it + " cosTheta[1] " + cosTheta[1][it] + " cosTheta[0] " + cosTheta[0][it]); #//console.log("thisThetFctr " + thisThetFctr); for il in range(numLams): #//for (int il = 0; il < numFine; il++){ intensLam[il] = intens[il][it] #//intensLam[il] = newIntens[il][it]; for ip in range(numPhi): for il in range(numLams): #//for (int il = 0; il < numFine; il++){ #//delLam = lambdas[il] * vRad[it][ip] / Useful.c; #//shiftedLamV[il] = lambdas[il] + delLam; shiftedLamV[il] = lambdas[il] * ( (vRad[it][ip]/Useful.c()) + 1.0 ) #//delLam = newLambda[il] * vRad[it][ip] / Useful.c; #//shiftedLamV[il] = newLambda[il] + delLam; #//shiftedLamV[il] = shiftedLam; #//if (il == 1){ #//System.out.println("it " + it + " cosTheta[1][it] " + cosTheta[1][it] + " ip " + ip + " phi[ip] " + (phi[ip]/2.0/Math.PI) + " vRad[it][ip] " + (vRad[it][ip]/1.0e5)); #// System.out.println("it " + it + " ip " + ip + " il " + il + " delLam " + delLam + " shiftedLamV " + shiftedLamV[il] + " intensLam[il] " + intensLam[il]); #//} #} #//for (int il = 0; il < numLams; il++){ #// intensLam[il] = intens[il][it]; #//} #thisIntens = ToolBox.interpolV(intensLam, shiftedLamV, lambdas); thisIntens = numpy.interp(lambdas, shiftedLamV, intensLam) #//thisIntens = ToolBox.interpolV(intensLam, shiftedLamV, newLambda); #//flx = flx + ( intens[it] * thisThetFctr * delPhi ); for il in range(numLams): #//for (int il = 0; il < numFine; il++){ flx[il] = flx[il] + ( thisIntens[il] * thisThetFctr * delPhi ) #//newFlx[il] = newFlx[il] + ( thisIntens[il] * thisThetFctr * delPhi ) #//console.log("il " + il + " thisIntens " + thisIntens[il] + " flx " + flx[il]); #} //ip - phi loop #} // it - theta loop #//flx = ToolBox.interpolV(newFlx, newLambda, lambdas); #//fluxSurfSpec[0] = 2.0 * Math.PI * flx; //axi-symmetric version for il in range(numLams): fluxSurfSpec[0][il] = flx[il] #// non-axi-symmetric version fluxSurfSpec[1][il] = math.log(fluxSurfSpec[0][il]) return fluxSurfSpec
def opacFe1(numDeps, temp, lambda2, logGroundPops): """//c****************************************************************************** //c This routine computes the bound-free absorption due to Fe I. //c******************************************************************************""" #//System.out.println("opacFe1 called..."); sigma = 0.0 aFe1 = [0.0 for i in range(numDeps)] #//cross-section is zero below threshold, so initialize: for i in range(numDeps): aFe1[i] = 0.0 waveno = 1.0 / lambda2 #//cm^-1?? freq = Useful.c() / lambda2 #// include 'Atmos.com' #// include 'Kappa.com' # //real*8 bolt(48,100), gg(48), ee(48), wno(48), xsect(48) #// double[] gg = new double[48]; bolt = [[0.0 for i in range(100)] for j in range(48)] xsect = [0.0 for i in range(48)] gg = [25.0, 35.0, 21.0, 15.0, 9.0, 35.0, 33.0, 21.0, 27.0, 49.0, 9.0, 21.0, 27.0, 9.0, 9.0, \ 25.0, 33.0, 15.0, 35.0, 3.0, 5.0, 11.0, 15.0, 13.0, 15.0, 9.0, 21.0, 15.0, 21.0, 25.0, 35.0, \ 9.0, 5.0, 45.0, 27.0, 21.0, 15.0, 21.0, 15.0, 25.0, 21.0, 35.0, 5.0, 15.0, 45.0, 35.0, 55.0, 25.0] #// double[] ee = new double[48]; ee = [ 500.0, 7500.0, 12500.0, 17500.0, 19000.0, 19500.0, 19500.0, 21000.0, 22000.0, 23000.0, 23000.0, 24000.0, 24000.0, 24500.0, 24500.0, 26000.0, 26500.0, 26500.0, 27000.0, 27500.0, 28500.0, 29000.0, 29500.0, 29500.0, 29500.0, 30000.0, 31500.0, 31500.0, 33500.0, 33500.0, 34000.0, 34500.0, 34500.0, 35000.0, 35500.0, 37000.0, 37000.0, 37000.0, 38500.0, 40000.0, 40000.0, 41000.0, 41000.0, 43000.0, 43000.0, 43000.0, 43000.0, 44000.0 ] #// double[] wno = new double[48]; wno = [ 63500.0, 58500.0, 53500.0, 59500.0, 45000.0, 44500.0, 44500.0, 43000.0, 58000.0, 41000.0, 54000.0, 40000.0, 40000.0, 57500.0, 55500.0, 38000.0, 57500.0, 57500.0, 37000.0, 54500.0, 53500.0, 55000.0, 34500.0, 34500.0, 34500.0, 34000.0, 32500.0, 32500.0, 32500.0, 32500.0, 32000.0, 29500.0, 29500.0, 31000.0, 30500.0, 29000.0, 27000.0, 54000.0, 27500.0, 24000.0, 47000.0, 23000.0, 44000.0, 42000.0, 42000.0, 21000.0, 42000.0, 42000.0 ] #//data freq1, modcount/0., 0/ freq1 = 0.0 #double hkt; #//c set up some data upon first entrance with a new model atmosphere #// if (modelnum .ne. modcount) then #// modcount = modelnum for i in range(numDeps): hkt = 6.6256e-27 / (1.38054e-16 * temp[0][i]) #//do k=1,48 for k in range(48): bolt[k][i] = gg[k] * math.exp(-ee[k] * Useful.c() * hkt) #// endif #//c initialize some quantities for each new model atmosphere or new frequency; #//c the absorption begins at 4762 A. #// if (modelnum.ne.modcount .or. freq.ne.freq1) then freq1 = freq #//waveno = freq/2.99792458d10 #//if (waveno .ge. 21000.) then if (waveno >= 21000.0): #//do k=1,48 for k in range(48): xsect[k] = 0.0 #//if (wno(k) .lt. waveno){ if (wno[k] < waveno): xsect[k] = 3.0e-18 / (1.0 + math.pow( ((wno[k] + 3000.0 - waveno) / wno[k] / 0.1), 4)) #// endif # //do i=1,ntau for i in range(numDeps): #//aFe1 seems to be cumulative. Moog does not seem to have this reset for each depth, but my aFe is blowing up, so let's try it... aFe1[i] = 0.0 #//reset accumulator each depth- ??? #//if (waveno .ge. 21000.) then if (waveno >= 21000.0): #//do k=1,48 for k in range(48): aFe1[ i] = 0.0 #//reset accumulator each 'k' - ??? (like removing aFe1 term in expression below... sigma = aFe1[i] + xsect[k] * bolt[k][i] aFe1[i] = sigma * math.exp(logGroundPops[i]) #//System.out.println("i " + i + " sigma " + sigma + " aFe1 " + aFe1[i]); return aFe1
def opacSi2(numDeps, temp, lambda2, logGroundPops): """//c****************************************************************************** //c This routine computes the bound-free absorption due to Si II. //c******************************************************************************""" #//System.out.println("opacSi2 called..."); sigma = 0.0 aSi2 = [0.0 for i in range(numDeps)] #//cross-section is zero below threshold, so initialize: for i in range(numDeps): aSi2[i] = 0.0 freq = Useful.c() / lambda2 freqlg = math.log(freq) #//base e? #int thelp, nn; #double dd, dd1; #// include 'Atmos.com' #// include 'Kappa.com' xx = [0.0 for i in range(6)] dt = [0.0 for i in range(100)] nt = [0 for i in range(100)] #/double peach = new double[6][14]; #//c 10000 peach0 = [ -43.8941, -42.2444, -40.6054, -54.2389, -50.4108, -52.0936, -51.9548, -54.2407, -52.7355, -53.5387, -53.2417, -53.5097, -54.0561, -53.8469 ] #//c 12000 peach1 = [ -43.8941, -42.2444, -40.6054, -52.2906, -48.4892, -50.0741, -49.9371, -51.7319, -50.2218, -50.9189, -50.6234, -50.8535, -51.2365, -51.0256 ] #//c 14000 peach2 = [ -43.8941, -42.2444, -40.6054, -50.8799, -47.1090, -48.5999, -48.4647, -49.9178, -48.4059, -49.0200, -48.7252, -48.9263, -49.1980, -48.9860 ] #//c 16000 peach3 = [ -43.8941, -42.2444, -40.6054, -49.8033, -46.0672, -47.4676, -47.3340, -48.5395, -47.0267, -47.5750, -47.2810, -47.4586, -47.6497, -47.4368 ] #//c 18000 peach4 = [ -43.8941, -42.2444, -40.6054, -48.9485, -45.2510, -46.5649, -46.4333, -47.4529, -45.9402, -46.4341, -46.1410, -46.2994, -46.4302, -46.2162 ] #//c 20000 peach5 = [ -43.8941, -42.2444, -40.6054, -48.2490, -44.5933, -45.8246, -45.6947, -46.5709, -45.0592, -45.5082, -45.2153, -45.3581, -45.4414, -45.2266 ] peach = [peach0, peach1, peach2, peach3, peach4, peach5] #//double[] freqSi = new double[7]; freqSi = [ 4.9965417e15, 3.9466738e15, 1.5736321e15, \ 1.5171539e15, 9.2378947e14, 8.3825004e14, \ 7.6869872e14] #//c 2P, 2D, 2P, 2D, 2P # //double[] flog = new double[9]; flog = [ 36.32984, 36.14752, 35.91165, 34.99216, 34.95561, \ 34.45951, 34.36234, 34.27572, 34.20161 ] #//double[] tlg = new double[6]; tlg = [9.21034, 9.39266, 9.54681, 9.68034, 9.79813, 9.90349] freq1 = 0.0 # // modcount/0/ #//c set up some data upon first entrance with a new model atmosphere #// if (modelnum .ne. modcount) then #// modcount = modelnum for i in range(numDeps): thelp = int(math.floor(temp[0][i] / 2000.0)) - 4 #// -1 term to adjust from FORTRAN to Java subscripting #//n = Math.max( Math.min(5, thelp-4), 1 ); nn = max(min(5, thelp), 1) - 1 nt[i] = nn dt[i] = (temp[1][i] - tlg[nn]) / (tlg[nn + 1] - tlg[nn]) #// endif #//c initialize some quantities for each new model atmosphere or new frequency #// if (modelnum.ne.modcount .or. freq.ne.freq1) then freq1 = freq #// do n=1,7 #// if (freq .gt. freqSi(n)) go to 23 #// enddo #// n = 8 # //n = 0; # //while ( (freq <= freqSi[n]) && (n < 6) ) { # // n++; # // } nn = 0 for n in range(7): if (freq > freqSi[n]): break nn += 1 if (freq <= freqSi[6]): nn = 7 #// #// dd = (freqlg - flog[nn]) / (flog[nn + 1] - flog[nn]) #// -1 term to adjust from FORTRAN to Java subscripting #//if (n > 2){ if (nn > 1): #// -1 term to adjust from FORTRAN to Java subscripting #//n = 2*n - 2; nn = 2 * nn - 2 #// - 1; //n already adjusted by this point? #// -1 term to adjust from FORTRAN to Java subscripting #//if (n == 14){ if (nn == 13): #// -1 term to adjust from FORTRAN to Java subscripting #//n = 13; nn = 12 dd1 = 1.0 - dd for it in range(6): xx[it] = peach[it][nn + 1] * dd + peach[it][nn] * dd1 #// endif for i in range(numDeps): if (freq >= 7.6869872e14): nn = nt[i] sigma = (6.0 * math.exp(xx[nn] * (1.0 - dt[i]) + xx[nn + 1] * dt[i])) aSi2[i] = sigma * math.exp(logGroundPops[i]) #//System.out.println("i " + i + " sigma " + sigma + " aSi2 " + aSi2[i]); return aSi2
def opacSi1(numDeps, temp, lambda2, logGroundPops): """//c****************************************************************************** //c This routine computes the bound-free absorption due to Si I. //c******************************************************************************""" #//System.out.println("opacSi1 called..."); sigma = 0.0 aSi1 = [0.0 for i in range(numDeps)] #//cross-section is zero below threshold, so initialize: for i in range(numDeps): aSi1[i] = 0.0 freq = Useful.c() / lambda2 freqlg = math.log(freq) #//base e? #// include 'Atmos.com' #// include 'Kappa.com' xx = [0.0 for i in range(9)] dt = [0.0 for i in range(100)] nt = [0 for i in range(100)] #// save #//c 4000 peach0 = [ 38.136, 37.834, 37.898, 40.737, 40.581, 45.521, 45.520, 55.068, 53.868, 54.133, 54.051, 54.442, 54.320, 55.691, 55.661, 55.973, 55.922, 56.828, 56.657 ] #//c 5000 peach1 = [ 38.138, 37.839, 37.898, 40.319, 40.164, 44.456, 44.455, 51.783, 50.369, 50.597, 50.514, 50.854, 50.722, 51.965, 51.933, 52.193, 52.141, 52.821, 52.653 ] #//c 6000 peach2 = [ 38.140, 37.843, 37.897, 40.047, 39.893, 43.753, 43.752, 49.553, 48.031, 48.233, 48.150, 48.455, 48.313, 49.444, 49.412, 49.630, 49.577, 50.110, 49.944 ] #//c 7000 peach3 = [ 38.141, 37.847, 37.897, 39.855, 39.702, 43.254, 43.251, 47.942, 46.355, 46.539, 46.454, 46.733, 46.583, 47.615, 47.582, 47.769, 47.715, 48.146, 47.983 ] #//c 8000 peach4 = [ 38.143, 37.850, 37.897, 39.714, 39.561, 42.878, 42.871, 46.723, 45.092, 45.261, 45.176, 45.433, 45.277, 46.221, 46.188, 46.349, 46.295, 46.654, 46.491 ] #//c 9000 peach5 = [ 38.144, 37.853, 37.896, 39.604, 39.452, 42.580, 42.569, 45.768, 44.104, 44.262, 44.175, 44.415, 44.251, 45.119, 45.085, 45.226, 45.172, 45.477, 45.315 ] #//c 10000 peach6 = [ 38.144, 37.855, 37.895, 39.517, 39.366, 42.332, 42.315, 44.997, 43.308, 43.456, 43.368, 43.592, 43.423, 44.223, 44.189, 44.314, 44.259, 44.522, 44.360 ] #//c 11000 peach7 = [ 38.145, 37.857, 37.895, 39.445, 39.295, 42.119, 42.094, 44.360, 42.652, 42.790, 42.702, 42.912, 42.738, 43.478, 43.445, 43.555, 43.500, 43.730, 43.569 ] #//c 12000 peach8 = [ 38.145, 37.858, 37.894, 39.385, 39.235, 41.930, 41.896, 43.823, 42.100, 42.230, 42.141, 42.340, 42.160, 42.848, 42.813, 42.913, 42.858, 43.061, 42.901 ] #// real*8 peach(9,19) # //double[][] peach = new double[9][19]; peach = [ peach0, peach1, peach2, peach3, peach4, peach5, peach6, peach7, peach8 ] #//c 3P, 1D, 1S, 1D, 3D, 3F, 1D, 3P freqSi = [ 2.1413750e15, 1.9723165e15, 1.7879689e15, \ 1.5152920e15, 5.5723927e14, 5.3295914e14, \ 4.7886458e14, 4.7216422e14, 4.6185133e14 ] #//double[] flog = new double[11]; flog = [ 35.45438, 35.30022, 35.21799, 35.11986, 34.95438, \ 33.95402, 33.90947, 33.80244, 33.78835, 33.76626, \ 33.70518 ] #//double[] tlg = new double[9]; tlg = [ 8.29405, 8.51719, 8.69951, 8.85367, 8.98720, 9.10498, \ 9.21034, 9.30565, 9.39266 ] freq1 = 0.0 #//, modcount/0/ # int thelp, nn; # double dd, dd1; #//c initialize some quantities for each new model atmosphere #// if (modelnum .ne. modcount) then #// modcount = modelnum # //do i=1,ntau for i in range(numDeps): thelp = int(math.floor(temp[0][i] / 1000.0)) - 3 #// -1 term to adjust from FORTRAN to Java subscripting #//n = Math.max( Math.min(8, thelp-3), 1 ); nn = max(min(8, thelp), 1) - 1 nt[i] = nn dt[i] = (temp[1][i] - tlg[nn]) / (tlg[nn + 1] - tlg[nn]) #// endif #// initialize some quantities for each new model atmosphere or new frequency #//if (modelnum.ne.modcount .or. freq.ne.freq1) then freq1 = freq #// do n=1,9 #// if (freq .gt. freqSi(n)) go to 23 #// enddo #// n = 9; # // n = 0; # // while ( (freq <= freqSi[n]) && (n < 8) ) { # // n++; # // } nn = 0 for n in range(9): if (freq > freqSi[n]): break nn += 1 if (freq <= freqSi[8]): nn = 9 #// dd = (freqlg - flog[nn]) / (flog[nn + 1] - flog[nn]) #// -1 term to adjust from FORTRAN to Java subscripting #//if (n > 2) { if (nn > 1): #// -1 term to adjust from FORTRAN to Java subscripting nn = 2 * nn - 2 #// - 1 #// n already adjusted by this point? dd1 = 1.0 - dd for it in range(9): xx[it] = peach[it][nn + 1] * dd + peach[it][nn] * dd1 #//endif for i in range(numDeps): if (freq >= 2.997925e+14): nn = nt[i] sigma = (9.0 * math.exp(-(xx[nn] * (1. - dt[i]) + xx[nn + 1] * dt[i]))) aSi1[i] = sigma * math.exp(logGroundPops[i]) #//System.out.println("i " + i + " sigma " + sigma + " aSi1 " + aSi1[i]); return aSi1
def opacMg2(numDeps, temp, lambda2, logGroundPops): """//c****************************************************************************** //c This routine computes the bound-free absorption due to Mg II. //c******************************************************************************""" #//System.out.println("opacMg2 called..."); sigma = 0.0 aMg2 = [0.0 for i in range(numDeps)] #//cross-section is zero below threshold, so initialize: for i in range(numDeps): aMg2[i] = 0.0 freq = Useful.c / lambda2 #double logTkev; tkev = [0.0 for i in range(numDeps)] #// include 'Atmos.com' #// include 'Kappa.com' c1169 = [0.0 for i in range(100)] freq1 = 0.0 x824 = 0.0 x1169 = 0.0 #//data modcount/0/ #// initialize some quantities for each new model atmosphere #// if (modelnum .ne. modcount) then #// modcount = modelnum for i in range(numDeps): logTkev = temp[1][i] + Useful.logK() - Useful.logEv() tkev[i] = math.exp(logTkev) #//do i=1,ntau for i in range(numDeps): c1169[i] = 6.0 * math.exp(-4.43e+0 / tkev[i]) #// endif #//c initialize some quantities for each new model atmosphere or new frequency; #//c there are two edges, one at 824 A and the other at 1169 A #// if (modelnum.ne.modcount .or. freq.ne.freq1) then #freq1 = freq; if (freq >= 3.635492e15): x824 = seaton(3.635492e15, 1.40e-19, 4.0e0, 6.7e0, freq) else: x824 = 1.0e-99 if (freq >= 2.564306e15): x1169 = 5.11e-19 * math.pow((2.564306e15 / freq), 3.0) else: x1169 = 1.0e-99 #// endif for i in range(numDeps): if (x1169 >= 1.0e-90): sigma = (x824 * 2.0 + x1169 * c1169[i]) aMg2[i] = sigma * math.exp(logGroundPops[i]) #//System.out.println("i " + i + " sigma " + sigma + " aMg2 " + aMg2[i]); return aMg2
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
def hydroFormalSoln(numDeps, grav, tauRos, kappa, temp, guessPGas): """This approach is based on integrating the formal solution of the hydrostaitc equilibrium equation // on the otical depth (Tau) scale. Advantage is that it makes better use of the itial guess at // pgas // // Takes in *Gas* pressure, converts tot *total pressure*, then returns *Gas* pressure // """ press = [[0.0 for i in range(numDeps)] for j in range(2)] logC = Useful.logC() logSigma = Useful.logSigma() radFac = math.log(4.0) + logSigma - math.log(3.0) - logC logEg = math.log(grav) #//Natural log g!! #// no needed if integrating in natural log?? //double logLogE = Math.log(Math.log10(Math.E)); log1p5 = math.log(1.5) logE = math.log10(math.e) #//Compute radiation pressure for this temperature structure and add it to Pgas #// #double pT, pRad; logPRad = [0.0 for i in range(numDeps)] logPTot = [0.0 for i in range(numDeps)] #// System.out.println("hydroFormalSoln: "); for i in range(numDeps): logPRad[i] = radFac + 4.0 * temp[1][i] pRad = math.exp(logPRad[i]) #//System.out.println("i " + i + " pRad " + pRad); pT = guessPGas[0][i] + pRad #// System.out.println("i " + i + " guessPGas[1] " + logE*guessPGas[1][i]); logPTot[i] = math.log(pT) #double help, logHelp, logPress; #double term, logSum, integ, logInteg, lastInteg; #double deltaLogT; sum = [0.0 for i in range(numDeps)] #//Upper boundary - inherit from intiial guess: #//Carefull here - P at upper boundary can be an underestimate, but it must not be greater than value at next depth in! #// press[1][0] = logPTot[0]; #// press[1][0] = guessPGas[1][0]; #// press[1][0] = Math.log(1.0e-4); //try same upper boundary as Phoenix #// #// press[0][0] = Math.exp(press[1][0]); press[0][0] = 0.1 * guessPGas[0][0] press[1][0] = math.log(press[0][0]) #//Corresponding value of basic integrated quantity at top of atmosphere: logSum = 1.5 * press[1][0] + math.log(0.666667) - logEg sum[0] = math.exp(logSum) #// Integrate inward on logTau scale #// CAUTION; This is not an integral for Delta P, but for P once integral at each tau is exponentiated by 2/3! #// Accumulate basic integral to be exponentiated, then construct pressure values later: #//Jump start integration with an Euler step: deltaLogT = tauRos[1][1] - tauRos[1][0] #// log of integrand logInteg = tauRos[1][1] + 0.5 * logPTot[1] - kappa[1][1] lastInteg = math.exp(logInteg) sum[1] = sum[0] + lastInteg * deltaLogT #// Continue with extended trapezoid rule: for i in range(2, numDeps): deltaLogT = tauRos[1][i] - tauRos[1][i - 1] logInteg = tauRos[1][i] + 0.5 * logPTot[i] - kappa[1][i] integ = math.exp(logInteg) term = 0.5 * (integ + lastInteg) * deltaLogT sum[i] = sum[i - 1] + term #//accumulate basic integrated quantity lastInteg = integ #//System.out.println("hydroFormalSoln: "); for i in range(1, numDeps): #//Evaluate total pressures from basic integrated quantity at edach depth #// our integration variable is the natural log, so I don't think we need the 1/log(e) factor logPress = 0.666667 * (log1p5 + logEg + math.log(sum[i])) #//Subtract radiation pressure: logHelp = logPRad[i] - logPress help = math.exp(logHelp) # For hot and low g stars: limit Prad to 50% Ptot so we doen't get netaive Pgas and rho values: if (help > 0.5): help = 0.5 press[1][i] = logPress + math.log(1.0 - help) #//System.out.println("i " + i + " guessPGas[1] " + logE*guessPGas[1][i] + " press[1] " + logE*press[1][i]); press[0][i] = math.exp(press[1][i]) return press #//*Gas* pressure
def masterMetal(numDeps, numLams, temp, lambdaScale, stagePops): """/* Metal b-f opacity routines taken from Moog (moogjul2014/, MOOGJUL2014.tar) Chris Sneden (Universtiy of Texas at Austin) and collaborators http://www.as.utexas.edu/~chris/moog.html //From Moog source file Opacitymetals.f */""" #//System.out.println("masterMetal called..."); #//From Moog source file Opacitymetals.f #// From how values such as aC1[] are used in Moog file Opacit.f to compute the total opacity #// and then the optical depth scale, I infer that they are extinction coefficients #// in cm^-1 #// There does not seem to be any correction for stimulated emission logE = math.log10(math.e) masterBF = [[0.0 for i in range(numDeps)] for j in range(numLams)] logUC1 = [0.0 for i in range(5)] logUMg1 = [0.0 for i in range(5)] logUMg2 = [0.0 for i in range(5)] logUAl1 = [0.0 for i in range(5)] logUSi1 = [0.0 for i in range(5)] logUSi2 = [0.0 for i in range(5)] logUFe1 = [0.0 for i in range(5)] logStatWC1 = 0.0 logStatWMg1 = 0.0 logStatWMg2 = 0.0 logStatWAl1 = 0.0 logStatWSi1 = 0.0 logStatWSi2 = 0.0 logStatWFe1 = 0.0 theta = 1.0 species = "" logGroundPopsC1 = [0.0 for i in range(numDeps)] logGroundPopsMg1 = [0.0 for i in range(numDeps)] logGroundPopsMg2 = [0.0 for i in range(numDeps)] logGroundPopsAl1 = [0.0 for i in range(numDeps)] logGroundPopsSi1 = [0.0 for i in range(numDeps)] logGroundPopsSi2 = [0.0 for i in range(numDeps)] logGroundPopsFe1 = [0.0 for i in range(numDeps)] #// #// C I: Z=6 --> iZ=5: aC1 = [0.0 for i in range(numDeps)] #// Mg I: Z=12 --> iZ=11: aMg1 = [0.0 for i in range(numDeps)] #// Mg II: Z=12 --> iZ=11: aMg2 = [0.0 for i in range(numDeps)] #// Al I: Z=13 --> iZ=12: aAl1 = [0.0 for i in range(numDeps)] #// Si I: Z=14 --> iZ=13: aSi1 = [0.0 for i in range(numDeps)] #// Si II: Z=14 --> iZ =13: aSi2 = [0.0 for i in range(numDeps)] #// Fe I: Z=26 --> iZ=25 aFe1 = [0.0 for i in range(numDeps)] species = "CI" logUC1 = PartitionFn.getPartFn2(species) species = "MgI" logUMg1 = PartitionFn.getPartFn2(species) species = "MgII" logUMg2 = PartitionFn.getPartFn2(species) species = "AlI" logUAl1 = PartitionFn.getPartFn2(species) species = "SiI" logUSi1 = PartitionFn.getPartFn2(species) species = "SiII" logUSi2 = PartitionFn.getPartFn2(species) species = "FeI" logUFe1 = PartitionFn.getPartFn2(species) #//System.out.println("iD PpC1 PpMg1 PpMg2 PpAl1 PpSi1 PpSi2 PpFe1"); for iD in range(numDeps): #//neutral stage #//Assumes ground state stat weight, g_1, is 1.0 #theta = 5040.0 / temp[0][iD] #// U[0]: theta = 1.0, U[1]: theta = 0.5 """ if (theta <= 0.5): logStatWC1 = logUC1[1] logStatWMg1 = logUMg1[1] logStatWMg2 = logUMg2[1] logStatWAl1 = logUAl1[1] logStatWSi1 = logUSi1[1] logStatWSi2 = logUSi2[1] logStatWFe1 = logUFe1[1] elif ( (theta < 1.0) and (theta > 0.5) ): logStatWC1 = ( (theta-0.5) * logUC1[0] ) + ( (1.0-theta) * logUC1[1] ) #//divide by common factor of interpolation interval of 0.5 = (1.0 - 0.5): logStatWC1 = 2.0 * logStatWC1 logStatWMg1 = ( (theta-0.5) * logUMg1[0] ) + ( (1.0-theta) * logUMg1[1] ); logStatWMg1 = 2.0 * logStatWMg1; logStatWMg2 = ( (theta-0.5) * logUMg2[0] ) + ( (1.0-theta) * logUMg2[1] ); logStatWMg2 = 2.0 * logStatWMg2; logStatWAl1 = ( (theta-0.5) * logUAl1[0] ) + ( (1.0-theta) * logUAl1[1] ); logStatWAl1 = 2.0 * logStatWAl1; logStatWSi1 = ( (theta-0.5) * logUSi1[0] ) + ( (1.0-theta) * logUSi1[1] ); logStatWSi1 = 2.0 * logStatWSi1; logStatWSi2 = ( (theta-0.5) * logUSi2[0] ) + ( (1.0-theta) * logUSi2[1] ); logStatWSi2 = 2.0 * logStatWSi2; logStatWFe1 = ( (theta-0.5) * logUFe1[0] ) + ( (1.0-theta) * logUFe1[1] ); logStatWFe1 = 2.0 * logStatWFe1; else: logStatWC1 = logUC1[0] logStatWMg1 = logUMg1[0] logStatWMg2 = logUMg2[0] logStatWAl1 = logUAl1[0] logStatWSi1 = logUSi1[0] logStatWSi2 = logUSi2[0] logStatWFe1 = logUFe1[0] """ #// NEW Interpolation involving temperature for new partition function: lburns thisTemp = temp[0][iD] if (thisTemp <= 130): logStatWC1 = logUC1[0] logStatWMg1 = logUMg1[0] logStatWMg2 = logUMg2[0] logStatWAl1 = logUAl1[0] logStatWSi1 = logUSi1[0] logStatWSi2 = logUSi2[0] logStatWFe1 = logUFe1[0] elif (thisTemp > 130 and thisTemp <= 500): #// Add in interpolation here lburns logStatWC1 = logUC1[1] * (thisTemp - 130)/(500 - 130) \ + logUC1[0] * (500 - thisTemp)/(500 - 130) logStatWMg1 = logUMg1[1] * (thisTemp - 130)/(500 - 130) \ + logUMg1[0] * (500 - thisTemp)/(500 - 130) logStatWMg2 = logUMg2[1] * (thisTemp - 130)/(500 - 130) \ + logUMg2[0] * (500 - thisTemp)/(500 - 130) logStatWAl1 = logUAl1[1] * (thisTemp - 130)/(500 - 130) \ + logUAl1[0] * (500 - thisTemp)/(500 - 130) logStatWSi1 = logUSi1[1] * (thisTemp - 130)/(500 - 130) \ + logUSi1[0] * (500 - thisTemp)/(500 - 130) logStatWSi2 = logUSi2[1] * (thisTemp - 130)/(500 - 130) \ + logUSi2[0] * (500 - thisTemp)/(500 - 130) logStatWFe1 = logUFe1[1] * (thisTemp - 130)/(500 - 130) \ + logUFe1[0] * (500 - thisTemp)/(500 - 130) elif (thisTemp > 500 and thisTemp <= 3000): logStatWC1 = logUC1[2] * (thisTemp - 500)/(3000 - 500) \ + logUC1[1] * (3000 - thisTemp)/(3000 - 500) logStatWMg1 = logUMg1[2] * (thisTemp - 500)/(3000 - 500) \ + logUMg1[1] * (3000 - thisTemp)/(3000 - 500) logStatWMg2 = logUMg2[2] * (thisTemp - 500)/(3000 - 500) \ + logUMg2[1] * (3000 - thisTemp)/(3000 - 500) logStatWAl1 = logUAl1[2] * (thisTemp - 500)/(3000 - 500) \ + logUAl1[1] * (3000 - thisTemp)/(3000 - 500) logStatWSi1 = logUSi1[2] * (thisTemp - 500)/(3000 - 500) \ + logUSi1[1] * (3000 - thisTemp)/(3000 - 500) logStatWSi2 = logUSi2[2] * (thisTemp - 500)/(3000 - 500) \ + logUSi2[1] * (3000 - thisTemp)/(3000 - 500) logStatWFe1 = logUFe1[2] * (thisTemp - 500)/(3000 - 500) \ + logUFe1[1] * (3000 - thisTemp)/(3000 - 500) elif (thisTemp > 3000 and thisTemp <= 8000): logStatWC1 = logUC1[3] * (thisTemp - 3000)/(8000 - 3000) \ + logUC1[2] * (8000 - thisTemp)/(8000 - 3000) logStatWMg1 = logUMg1[3] * (thisTemp - 3000)/(8000 - 3000) \ + logUMg1[2] * (8000 - thisTemp)/(8000 - 3000) logStatWMg2 = logUMg2[3] * (thisTemp - 3000)/(8000 - 3000) \ + logUMg2[2] * (8000 - thisTemp)/(8000 - 3000) logStatWAl1 = logUAl1[3] * (thisTemp - 3000)/(8000 - 3000) \ + logUAl1[2] * (8000 - thisTemp)/(8000 - 3000) logStatWSi1 = logUSi1[3] * (thisTemp - 3000)/(8000 - 3000) \ + logUSi1[2] * (8000 - thisTemp)/(8000 - 3000) logStatWSi2 = logUSi2[3] * (thisTemp - 3000)/(8000 - 3000) \ + logUSi2[2] * (8000 - thisTemp)/(8000 - 3000) logStatWFe1 = logUFe1[3] * (thisTemp - 3000)/(8000 - 3000) \ + logUFe1[2] * (8000 - thisTemp)/(8000 - 3000) elif (thisTemp > 8000 and thisTemp < 10000): logStatWC1 = logUC1[4] * (thisTemp - 8000)/(10000 - 8000) \ + logUC1[3] * (10000 - thisTemp)/(10000 - 8000) logStatWMg1 = logUMg1[4] * (thisTemp - 8000)/(10000 - 8000) \ + logUMg1[3] * (10000 - thisTemp)/(10000 - 8000) logStatWMg2 = logUMg2[4] * (thisTemp - 8000)/(10000 - 8000) \ + logUMg2[3] * (10000 - thisTemp)/(10000 - 8000) logStatWAl1 = logUAl1[4] * (thisTemp - 8000)/(10000 - 8000) \ + logUAl1[3] * (10000 - thisTemp)/(10000 - 8000) logStatWSi1 = logUSi1[4] * (thisTemp - 8000)/(10000 - 8000) \ + logUSi1[3] * (10000 - thisTemp)/(10000 - 8000) logStatWSi2 = logUSi2[4] * (thisTemp - 8000)/(10000 - 8000) \ + logUSi2[3] * (10000 - thisTemp)/(10000 - 8000) logStatWFe1 = logUFe1[4] * (thisTemp - 8000)/(10000 - 8000) \ + logUFe1[3] * (10000 - thisTemp)/(10000 - 8000) else: #// for temperatures greater than or equal to 10000 logStatWC1 = logUC1[4] logStatWMg1 = logUMg1[4] logStatWMg2 = logUMg2[4] logStatWAl1 = logUAl1[4] logStatWSi1 = logUSi1[4] logStatWSi2 = logUSi2[4] logStatWFe1 = logUFe1[4] logGroundPopsC1[iD] = stagePops[5][0][iD] - logStatWC1 logGroundPopsMg1[iD] = stagePops[11][0][iD] - logStatWMg1 logGroundPopsMg2[iD] = stagePops[11][1][iD] - logStatWMg2 logGroundPopsAl1[iD] = stagePops[12][0][iD] - logStatWAl1 logGroundPopsSi1[iD] = stagePops[13][0][iD] - logStatWSi1 logGroundPopsSi2[iD] = stagePops[13][1][iD] - logStatWSi2 logGroundPopsFe1[iD] = stagePops[25][0][iD] - logStatWFe1 #// if (iD%5 == 1){ #// System.out.format("%03d, %21.15f, %21.15f, %21.15f, %21.15f, %21.15f, %21.15f, %21.15f %n", #// iD, logE*(logGroundPopsC1[iD]+temp[1][iD]+Useful.logK()), #// logE*(logGroundPopsMg1[iD]+temp[1][iD]+Useful.logK()), #// logE*(logGroundPopsMg2[iD]+temp[1][iD]+Useful.logK()), #// logE*(logGroundPopsAl1[iD]+temp[1][iD]+Useful.logK()), #// logE*(logGroundPopsSi1[iD]+temp[1][iD]+Useful.logK()), #// logE*(logGroundPopsSi2[iD]+temp[1][iD]+Useful.logK()), #// logE*(logGroundPopsFe1[iD]+temp[1][iD]+Useful.logK())); #id loop// } #double waveno; //cm?? #double freq, logFreq, kapBF; #double stimEmExp, stimEmLogExp, stimEmLogExpHelp, stimEm; #//System.out.println("iD iL lambda stimEm aC1 aMg1 aMg2 aAl1 aSi1 aSi2 aFe1 "); for iL in range(numLams): #print("iL ", iL) #// #//initialization: for i in range(numDeps): aC1[i] = 0.0 aMg1[i] = 0.0 aMg2[i] = 0.0 aAl1[i] = 0.0 aSi1[i] = 0.0 aSi2[i] = 0.0 aFe1[i] = 0.0 waveno = 1.0 / lambdaScale[iL] #//cm^-1?? logFreq = Useful.logC() - math.log(lambdaScale[iL]) freq = math.exp(logFreq) #if (iL%20 == 1): # print("freq ", freq) stimEmLogExpHelp = Useful.logH() + logFreq - Useful.logK() #//System.out.println("Calling opacC1 from masterMetal..."); if (freq >= 2.0761e15): aC1 = opacC1(numDeps, temp, lambdaScale[iL], logGroundPopsC1) if (freq >= 2.997925e+14): #print("opacMg1 called") aMg1 = opacMg1(numDeps, temp, lambdaScale[iL], logGroundPopsMg1) if (freq >= 2.564306e15): aMg2 = opacMg2(numDeps, temp, lambdaScale[iL], logGroundPopsMg2) if (freq >= 1.443e15): aAl1 = opacAl1(numDeps, temp, lambdaScale[iL], logGroundPopsAl1) if (freq >= 2.997925e+14): #print("opacSi1 called") aSi1 = opacSi1(numDeps, temp, lambdaScale[iL], logGroundPopsSi1) if (freq >= 7.6869872e14): aSi2 = opacSi2(numDeps, temp, lambdaScale[iL], logGroundPopsSi2) if (waveno >= 21000.0): aFe1 = opacFe1(numDeps, temp, lambdaScale[iL], logGroundPopsFe1) for iD in range(numDeps): kapBF = 1.0e-99 #minimum safe value stimEmLogExp = stimEmLogExpHelp - temp[1][iD] stimEmExp = -1.0 * math.exp(stimEmLogExp) stimEm = (1.0 - math.exp(stimEmExp) ) #//LTE correction for stimulated emission kapBF = kapBF + aC1[iD] + aMg1[iD] + aMg2[iD] + aAl1[iD] + aSi1[ iD] + aSi2[iD] + aFe1[iD] #kapBF = aC1[iD] + aMg2[iD] + aAl1[iD] + aSi2[iD] + aFe1[iD] #if ( (iL%20 == 1) and (iD%10 == 1) ): #print("iL ", iL, " iD ", iD, " stimEm ", stimEm, " kapBF ", kapBF) # print("aMg1 ", aMg1[iD], " aSi1 ", aSi1[iD]) masterBF[iL][iD] = math.log(kapBF) + math.log(stimEm) #// if ( (iD%10 == 0) && (iL%10 == 0) ) { #// System.out.format("%03d, %03d, %21.15f, %21.15f, %21.15f, %21.15f, %21.15f, %21.15f, %21.15f, %21.15f, %21.15f, %n", #// iD, iL, lambdaScale[iL], Math.log10(stimEm), Math.log10(aC1[iD]), Math.log10(aMg1[iD]), Math.log10(aMg2[iD]), Math.log10(aAl1[iD]), Math.log10(aSi1[iD]), Math.log10(aSi2[iD]), Math.log10(aFe1[iD])); #// } #} //iD #} //iL return masterBF
def planck(temp, lambda2): """ /** * Inputs: lambda: a single scalar wavelength in cm temp: a single scalar * temperature in K Returns log of Plank function in logBBlam - B_lambda * distribution in pure cgs units: ergs/s/cm^2/ster/cm */""" #//int numLams = (int) (( lamSetup[1] - lamSetup[0] ) / lamSetup[2]) + 1; #double logBBlam; //, BBlam; #//double c = Useful.c; //linear logC = Useful.logC() # //log #//double k = Useful.k; //linear logK = Useful.logK() #//log #//double h = Useful.h; //linear logH = Useful.logH() #//log logPreFac = math.log(2.0) + logH + 2.0 * logC #//log logExpFac = logH + logC - logK #//log #//double preFac = 2.0 * h * ( c * c ); //linear #//double expFac = ( h / k ) * c; //linear #//System.out.println("logC " + logC + " logK " + logK + " logH " + logH); #//System.out.println("logPreFac " + logPreFac + " logExpFac " + logExpFac); #//Declare scratch variables: #double logLam, logPreLamFac, logExpLamFac, expon, logExpon, eTerm, denom, logDenom; //log #//double preLamFac, expLamFac, expon, denom; //linear #//for (int il = 0; il < numLams; il++){ #//lambda = lambda[il] * 1.0E-7; // convert nm to cm #//lambda = lambda * 1.0E-7; // convert nm to cm logLam = math.log(lambda2) #// Do the call to log for lambda once //log #//System.out.println("lambda " + lambda + " logLam " + logLam); logPreLamFac = logPreFac - 5.0 * logLam #//log logExpLamFac = logExpFac - logLam #//log #//System.out.println("logPreLamFac " + logPreLamFac + " logExpLamFac " + logExpLamFac); #// Be VERY careful about how we divide by lambda^5: #//preLamFac = preFac / ( lambda * lambda ); //linear #//preLamFac = preLamFac / ( lambda * lambda ); //linear #//preLamFac = preLamFac / lambda; //linear #//expLamFac = expFac / lambda; #//for (int id = 0; id < numDeps; id++){ #//logExpon = logExpLamFac - temp[1][id]; #//This is very subtle and dangerous! logExpon = logExpLamFac - math.log(temp) #// log of hc/kTlambda #//System.out.println("temp " + temp + " logTemp " + Math.log(temp)); expon = math.exp(logExpon) #// hc/kTlambda #//System.out.println("logExpon " + logExpon + " expon " + expon + " denom " + denom); #// expon = expLamFac / temp; //linear eTerm = math.exp(expon) #// e^hc/ktlambda denom = eTerm - 1.0 #// e^hc/ktlambda - 1 logDenom = math.log(denom) #// log(e^hc/ktlambda - 1) #//BBlam[1][id][il] = logPreLamFac - logDenom; #//BBlam[0][id][il] = Math.exp(BBlam[1][id][il]); logBBlam = logPreLamFac - logDenom #//log #// Not needed? BBlam = math.exp(logBBlam) #//log #//BBlam = preLamFac / denom; //linear #// } //id loop - depths #// } //il loop - lambdas return logBBlam;
def opacC1(numDeps, temp, lambda2, logGroundPops): """#//c****************************************************************************** #//c This routine computes the bound-free absorption due to C I. #//c******************************************************************************""" #//System.out.println("opacC1 called..."); #// include 'Atmos.com' #// include 'Kappa.com' sigma = 0.0 aC1 = [0.0 for i in range(numDeps)] #//cross-section is zero below threshold, so initialize: for i in range(numDeps): aC1[i] = 0.0 waveno = 1.0 / lambda2 #//cm^-1?? freq = Useful.c / lambda2 #double arg; c1240 = [0.0 for i in range(numDeps)] c1444 = [0.0 for i in range(numDeps)] freq1 = 0.0 #double logTkev; tkev = [0.0 for i in range(numDeps)] #// int modcount = 0; for i in range(numDeps): logTkev = temp[1][i] + Useful.logK() - Useful.logEv() tkev[i] = math.exp(logTkev) #//c initialize some quantities for each new model atmosphere for i in range(numDeps): c1240[i] = 5.0 * math.exp(-1.264 / tkev[i]) c1444[i] = math.exp(-2.683 / tkev[i]) #//c initialize some quantities for each new model atmosphere or new frequency; #//c Luo, D. and Pradhan, A.K. 1989, J.Phys. B, 22, 3377-3395. #//c Burke, P.G. and Taylor, K.T. 1979, J. Phys. B, 12, 2971-2984. #// if (modelnum.ne.modcount .or. freq.ne.freq1) then #double aa, bb, eeps; #freq1 = freq; ryd = 109732.298 #//Rydberg constant in cm^-1 #//waveno = freq/2.99792458d10 xs0 = 0.0 xs1 = 0.0 xd0 = 0.0 xd1 = 0.0 xd2 = 0.0 x1444 = 0.0 x1240 = 0.0 x1100 = 0.0 #//c P2 3P 1 #//c I AM NOT SURE WHETHER THE CALL TO SEATON IN THE NEXT STATEMENT IS #//c CORRECT, BUT IT ONLY AFFECTS THINGS BELOW 1100A if (freq >= 2.7254e15): arg = -16.80 - ((waveno - 90777.000) / 3.0 / ryd) x1100 = math.pow(10.0, arg) * seaton(2.7254e15, 1.219e-17, 2.0e0, 3.317e0, freq) #//c P2 1D 2 if (freq >= 2.4196e15): arg = -16.80 - ((waveno - 80627.760) / 3.0 / ryd) xd0 = math.pow(10.0, arg) eeps = (waveno - 93917.0) * 2.0 / 9230.0 aa = 22.0e-18 bb = 26.0e-18 xd1 = ((aa * eeps) + bb) / (math.pow(eeps, 2) + 1.0) eeps = (waveno - 111130.0) * 2.0 / 2743.0 aa = -10.5e-18 bb = 46.0e-18 xd2 = ((aa * eeps) + bb) / (math.pow(eeps, 2) + 1.0) x1240 = xd0 + xd1 + xd2 #//c P2 1S 3 if (freq >= 2.0761e15): arg = -16.80 - ((waveno - 69172.400) / 3.0 / ryd) xs0 = math.pow(10.0, arg) eeps = (waveno - 97700.0) * 2.0 / 2743.0 aa = 68.0e-18 bb = 118.0e-18 xs1 = ((aa * eeps) + bb) / (math.pow(eeps, 2) + 1.0) x1444 = xs0 + xs1 #//System.out.println("freq " + freq + " lambda " + lambda); for i in range(numDeps): if (freq >= 2.0761e15): sigma = (x1100 * 9.0 + x1240 * c1240[i] + x1444 * c1444[i]) aC1[i] = sigma * math.exp(logGroundPops[i]) #//System.out.println("i " + i + " sigma " + sigma + " aC1 " + aC1[i]); #//System.out.println("i " + i + " logPop " + logGroundPops[i] + " aC1 " + aC1[i]); return aC1
def opacMg1(numDeps, temp, lambda2, logGroundPops): """//c****************************************************************************** //c This routine computes the bound-free absorption due to Mg I. //c******************************************************************************""" #//System.out.println("opacMg1 called..."); sigma = 0.0 aMg1 = [0.0 for i in range(numDeps)] #//cross-section is zero below threshold, so initialize: for i in range(numDeps): aMg1[i] = 0.0 freq = Useful.c() / lambda2 #//System.out.println("opacMg1: lambda, freq " + lambda + " " + freq); freqlg = math.log(freq) #//base e? #// include 'Atmos.com' #// include 'Kappa.com' #// real*8 flog(9), freqMg(7), peach(7,15), xx(7), tlg(7) #// real*8 dt(100) #// integer nt(100) xx = [0.0 for i in range(7)] dt = [0.0 for i in range(100)] nt = [0 for i in range(100)] #// data peach/ # //double[][] peach = new double[7][15]; #//c 4000 K peach0 = [ -42.474, -41.808, -41.273, -45.583, -44.324, -50.969, -50.633, -53.028, -51.785, -52.285, -52.028, -52.384, -52.363, -54.704, -54.359 ] #//c 5000 K peach1 = [ -42.350, -41.735, -41.223, -44.008, -42.747, -48.388, -48.026, -49.643, -48.352, -48.797, -48.540, -48.876, -48.856, -50.772, -50.349 ] #//c 6000 K peach2 = [ -42.109, -41.582, -41.114, -42.957, -41.694, -46.630, -46.220, -47.367, -46.050, -46.453, -46.196, -46.513, -46.493, -48.107, -47.643 ] #//c 7000 K peach3 = [ -41.795, -41.363, -40.951, -42.205, -40.939, -45.344, -44.859, -45.729, -44.393, -44.765, -44.507, -44.806, -44.786, -46.176, -45.685 ] #//c 8000 K peach4 = [ -41.467, -41.115, -40.755, -41.639, -40.370, -44.355, -43.803, -44.491, -43.140, -43.486, -43.227, -43.509, -43.489, -44.707, -44.198 ] #//c 9000 K peach5 = [ -41.159, -40.866, -40.549, -41.198, -39.925, -43.568, -42.957, -43.520, -42.157, -42.480, -42.222, -42.488, -42.467, -43.549, -43.027 ] #//c 10000 K peach6 = [ -40.883, -40.631, -40.347, -40.841, -39.566, -42.924, -42.264, -42.736, -41.363, -41.668, -41.408, -41.660, -41.639, -42.611, -42.418 ] peach = [peach0, peach1, peach2, peach3, peach4, peach5, peach6] #// double[] freqMg = new double[7]; freqMg = [ 1.9341452e15, 1.8488510e15, 1.1925797e15, \ 7.9804046e14, 4.5772110e14, 4.1440977e14, \ 4.1113514e14 ] #// double[] flog = new double[9]; flog = [ 35.23123, 35.19844, 35.15334, 34.71490, 34.31318, \ 33.75728, 33.65788, 33.64994, 33.43947 ] #// double[] tlg = new double[7]; tlg = [ 8.29405, 8.51719, 8.69951, 8.85367, 8.98720, 9.10498, \ 9.21034 ] #//base e? freq1 = 0.0 #//modcount/0/ #int thelp, nn; #double dd, dd1; #//double log10E = Math.log10(Math.E); #//c initialize some quantities for each new model atmosphere #// if (modelnum .ne. modcount) then #// modcount = modelnum # //System.out.println("opacMg1 call, lambda " + lambda); for i in range(numDeps): thelp = int(math.floor((temp[0][i] / 1000.0))) - 3 #//System.out.println("i " + i + " temp[0] " + temp[0][i] + " thelp " + thelp); #//n = Math.max( Math.min(6, thelp-3), 1 ); #// -1 term to adjust from FORTRAN to Java subscripting nn = max( min(6, thelp), 1) - 1 #// -1 term to adjust from FORTRAN to Java subscripting nt[i] = nn dt[i] = (temp[1][i] - tlg[nn]) / (tlg[nn + 1] - tlg[nn]) #//base e? #//System.out.println(" nn " + nn + " temp[1] " + temp[1][i] + " tlg[nn+1] " + tlg[nn+1] + " tlg[nn] " + tlg[nn] + " dt[i] " + dt[i]); #// endif #//c initialize some quantities for each new model atmosphere or new frequency; #//if (modelnum.ne.modcount .or. freq.ne.freq1) then freq1 = freq #// do n=1,7 #// if (freq .gt. freqMg(n)) go to 23 #// enddo #//n = 7; #// n = 0; #// while ( (freq <= freqMg[n]) && (n < 6) ) { #// n++; #// } nn = 0 for n in range(7): #//System.out.println("freq " + freq + " n " + n + " freqMg[n] " + freqMg[n]); if (freq > freqMg[n]): break nn += 1 if (freq <= freqMg[6]): nn = 7 #//System.out.println("nn " + nn + " flog[nn+1] " + flog[nn+1] + " flog[nn] " + flog[nn]); dd = (freqlg - flog[nn]) / (flog[nn + 1] - flog[nn]) #//System.out.println("dd " + dd + " freqlg " + freqlg); #//if (n .gt. 2) n = 2*n -2 #// -1 term to adjust from FORTRAN to Java subscripting #//if (n > 2){ if (nn > 1): #// -1 term to adjust from FORTRAN to Java subscripting #//n = 2*n - 2 - 1; nn = 2 * nn - 2 #// - 1; dd1 = 1.0 - dd #//do it=1,7 #//System.out.println("nn " + nn + " dd1 " + dd1); for it in range(7): xx[it] = peach[it][nn + 1] * dd + peach[it][nn] * dd1 #//System.out.println("it " + it + " peach[it][nn+1] " + peach[it][nn+1] + " peach[it][nn] " + peach[it][nn] + " xx[it] " + xx[it]); #//enddo #//endif #//do i=1,ntau for i in range(numDeps): #//if (freq .ge. 2.997925d+14) then if (freq >= 2.997925e+14): nn = nt[i] sigma = math.exp((xx[nn] * (1.0e0 - dt[i])) + (xx[nn + 1] * dt[i])) aMg1[i] = sigma * math.exp(logGroundPops[i]) #//System.out.println("i " + i + " sigma " + sigma + " aMg1 " + aMg1[i]); #//endif #//enddo return aMg1
import Useful, time def pell(d): p = 1 k = 1 x1 = 1 y = 0 sd = d**.5 while k != 1 or y == 0: p = k*(p/k+1)-p p = p - int((p-sd)/k)*k x = (p*x1+d*y) / abs(k) y = (p*y+x1) / abs(k) k = (p*p-d) / k x1 = x return x time.clock() print max([(pell(d),d) for d in Useful.get_primes(1000)]) print str(time.clock()*1000)+'ms'