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 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 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 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 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 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 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 lineGridGauss(lam0In, massIn, xiTIn, numDeps, teff, numCore): c = Useful.c() logC = Useful.logC() #//double k = Useful.k; logK = Useful.logK() #//double e = Useful.e; #//double mE = Useful.mE; amu = Useful.amu() dln10 = math.log(10.0) ln2 = math.log(2.0) logE = math.log10(math.e) #// for debug output #//Put input parameters into linear cgs units: #//double gammaCol = Math.pow(10.0, logGammaCol); logTeff = math.log(teff) xiT = xiTIn * 1.0E5 #//km/s to cm/s lam0 = lam0In #// * 1.0E-7; //nm to cm logLam0 = math.log(lam0) logMass = math.log(massIn * amu) #//amu to g #// Compute depth-independent Doppler width, Delta_lambda_D: #double doppler, logDopp; #double logHelp, help; //scratch logHelp = ln2 + logK + logTeff - logMass #// M-B dist, square of v_mode help = math.exp( logHelp) + xiT * xiT #// quadratic sum of thermal v and turbulent v logHelp = 0.5 * math.log(help) logDopp = logHelp + logLam0 - logC doppler = math.exp(logDopp) #// cm #//System.out.println("LineGrid: doppler, logDopp: " + doppler + " " + logE*logDopp); #//Set up a half-profile Delta_lambda grid in Doppler width units #//from line centre to wing #//int numCore = 5; #//int numWing = 5; #//int numWing = 0; //debug numPoints = numCore #// a 2D 2 X numPoints array of Delta Lambdas #// Row 0 : Delta lambdas in cm - will need to be in nm for Planck and Rad Trans? #// Row 1 : Delta lambdas in Doppler widths linePoints = [[0.0 for i in range(numPoints)] for j in range(2)] #// Line profiel points in Doppler widths - needed for Voigt function, H(a,v): v = [0.0 for i in range(numPoints)] maxCoreV = 3.5 #//core half-width ~ in Doppler widths #//double maxWingDeltaLogV = 1.5 * ln10; //maximum base e logarithmic shift from line centre in Doppler widths minWingDeltaLogV = math.log(maxCoreV + 1.5) maxWingDeltaLogV = 9.0 + minWingDeltaLogV #double logV, ii, jj; for il in range(numPoints): ii = float(il) #// In core, space v points linearly: #// Voigt "v" parameter #// v > 0 --> This is the *red* wing: v[il] = ii * maxCoreV / (numCore - 1) linePoints[0][il] = doppler * v[il] linePoints[1][il] = v[il] #//System.out.println("LineGrid: il, lam, v: " + il + " " + #// linePoints[0][il] + " " + linePoints[1][il]); #} // il lambda loop #// Add the negative DeltaLambda half of the line: numPoints2 = (2 * numPoints) - 1 #//System.out.println("LineGrid: numpoints2: " + numPoints2); #// Return a 2D 2 X (2xnumPoints-1) array of Delta Lambdas #// Row 0 : Delta lambdas in cm - will need to be in nm for Planck and Rad Trans? #// Row 1 : Delta lambdas in Doppler widths linePoints2 = [[0.0 for i in range(numPoints2)] for j in range(2)] #//wavelengths are depth-independent - just put them in the 0th depth slot: for il2 in range(numPoints2): if (il2 < numPoints - 1): il = (numPoints - 1) - il2 linePoints2[0][il2] = -1.0 * linePoints[0][il] linePoints2[1][il2] = -1.0 * linePoints[1][il] else: #//Positive DelataLambda half: il = il2 - (numPoints - 1) linePoints2[0][il2] = linePoints[0][il] linePoints2[1][il2] = linePoints[1][il] #//System.out.println("LineGrid: il2, lam, v: " + il2 + " " + #// linePoints2[0][il2] + " " + linePoints2[1][il2]); #} //il2 loop return linePoints2
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
def levelPops(lam0In, logNStage, chiL, logUw, gwL, numDeps, temp): """ Returns depth distribution of occupation numbers in lower level of b-b transition, // Input parameters: // lam0 - line centre wavelength in nm // logNStage - log_e density of absorbers in relevent ion stage (cm^-3) // logFlu - log_10 oscillator strength (unitless) // chiL - energy of lower atomic E-level of b-b transition in eV // Also needs atsmopheric structure information: // numDeps // temp structure """ c = Useful.c() logC = Useful.logC() k = Useful.k() logK = Useful.logK() logH = Useful.logH() logEe = Useful.logEe() logMe = Useful.logMe() ln10 = math.log(10.0) logE = math.log10(math.e) #// for debug output log2pi = math.log(2.0 * math.pi) log2 = math.log(2.0) #//double logNl = logNlIn * ln10; // Convert to base e #// Parition functions passed in are 2-element vectore with remperature-dependent base 10 log Us #// Convert to natural logs: #double thisLogUw, Ttheta; thisLogUw = 0.0 # //default initialization #logUw = [ 0.0 for i in range(5) ] logE10 = math.log(10.0) #print("log10UwStage ", log10UwStage) #for kk in range(len(logUw)): # logUw[kk] = logE10*log10UwStage[kk] #// lburns new loop logGwL = math.log(gwL) #//System.out.println("chiL before: " + chiL); #// If we need to subtract chiI from chiL, do so *before* converting to tiny numbers in ergs! #////For testing with Ca II lines using gS3 internal line list only: #//boolean ionized = true; #//if (ionized) { #// //System.out.println("ionized, doing chiL - chiI: " + ionized); #// // chiL = chiL - chiI; #// chiL = chiL - 6.113; #// } #// // #//Log of line-center wavelength in cm logLam0 = math.log(lam0In) #// * 1.0e-7); #// energy of b-b transition logTransE = logH + logC - logLam0 #//ergs if (chiL <= 0.0): chiL = 1.0e-49 logChiL = math.log( chiL) + Useful.logEv() #// Convert lower E-level from eV to ergs logBoltzFacL = logChiL - Useful.logK( ) #// Pre-factor for exponent of excitation Boltzmann factor boltzFacL = math.exp(logBoltzFacL) boltzFacGround = 0.0 / k #//I know - its zero, but let's do it this way anyway' #// return a 1D numDeps array of logarithmic number densities #// level population of lower level of bb transition (could be in either stage I or II!) logNums = [0.0 for i in range(numDeps)] #double num, logNum, expFac; for id in range(numDeps): #//Determine temperature dependenet partition functions Uw: #Ttheta = 5040.0 / temp[0][id] #//NEW Determine temperature dependent partition functions Uw: lburns thisTemp = temp[0][id] """ if (Ttheta >= 1.0): thisLogUw = logUw[0] if (Ttheta <= 0.5): thisLogUw = logUw[1] if (Ttheta > 0.5 and Ttheta < 1.0): thisLogUw = ( logUw[1] * (Ttheta - 0.5)/(1.0 - 0.5) ) \ + ( logUw[0] * (1.0 - Ttheta)/(1.0 - 0.5) ) """ if (thisTemp >= 10000): thisLogUw = logUw[4] if (thisTemp <= 130): thisLogUw = logUw[0] if (thisTemp > 130 and thisTemp <= 500): thisLogUw = logUw[1] * (thisTemp - 130)/(500 - 130) \ + logUw[0] * (500 - thisTemp)/(500 - 130) if (thisTemp > 500 and thisTemp <= 3000): thisLogUw = logUw[2] * (thisTemp - 500)/(3000 - 500) \ + logUw[1] * (3000 - thisTemp)/(3000 - 500) if (thisTemp > 3000 and thisTemp <= 8000): thisLogUw = logUw[3] * (thisTemp - 3000)/(8000 - 3000) \ + logUw[2] * (8000 - thisTemp)/(8000 - 3000) if (thisTemp > 8000 and thisTemp < 10000): thisLogUw = logUw[4] * (thisTemp - 8000)/(10000 - 8000) \ + logUw[3] * (10000 - thisTemp)/(10000 - 8000) #print("logUw ", logUw, " thisLogUw ", thisLogUw) #//System.out.println("LevPops: ionized branch taken, ionized = " + ionized); #// Take stat weight of ground state as partition function: logNums[id] = logNStage[id] - boltzFacL / temp[0][ id] + logGwL - thisLogUw #// lower level of b-b transition #print("LevelPopsServer.stagePops id ", id, " logNStage[id] ", logNStage[id], " boltzFacL ", boltzFacL, " temp[0][id] ", temp[0][id], " logGwL ", logGwL, " thisLogUw ", thisLogUw, " logNums[id] ", logNums[id]); #// System.out.println("LevelPops: id, logNums[0][id], logNums[1][id], logNums[2][id], logNums[3][id]: " + id + " " #// + Math.exp(logNums[0][id]) + " " #// + Math.exp(logNums[1][id]) + " " #// + Math.exp(logNums[2][id]) + " " #// + Math.exp(logNums[3][id])); #//System.out.println("LevelPops: id, logNums[0][id], logNums[1][id], logNums[2][id], logNums[3][id], logNums[4][id]: " + id + " " #// + logE * (logNums[0][id]) + " " #// + logE * (logNums[1][id]) + " " #// + logE * (logNums[2][id]) + " " # // + logE * (logNums[3][id]) + " " #// + logE * (logNums[4][id]) ); #//System.out.println("LevelPops: id, logIonFracI, logIonFracII: " + id + " " + logE*logIonFracI + " " + logE*logIonFracII #// + "logNum, logNumI, logNums[0][id], logNums[1][id] " #// + logE*logNum + " " + logE*logNumI + " " + logE*logNums[0][id] + " " + logE*logNums[1][id]); #//System.out.println("LevelPops: id, logIonFracI: " + id + " " + logE*logIonFracI #// + "logNums[0][id], boltzFacL/temp[0][id], logNums[2][id]: " #// + logNums[0][id] + " " + boltzFacL/temp[0][id] + " " + logNums[2][id]); #//id loop #stop return logNums
def lineGridDelta(lam0In, massIn, xiTIn, numDeps, teff): c = Useful.c() logC = Useful.logC() #//double k = Useful.k; logK = Useful.logK() #//double e = Useful.e; #//double mE = Useful.mE; amu = Useful.amu() ln10 = math.log(10.0) ln2 = math.log(2.0) logE = math.log10(math.e) #// for debug output #//Put input parameters into linear cgs units: #//double gammaCol = Math.pow(10.0, logGammaCol); logTeff = math.log(teff) xiT = xiTIn * 1.0E5 #//km/s to cm/s lam0 = lam0In #// * 1.0E-7; //nm to cm logLam0 = math.log(lam0) logMass = math.log(massIn * amu) #//amu to g #// Compute depth-independent Doppler width, Delta_lambda_D: #double doppler, logDopp; #double logHelp, help; //scratch logHelp = ln2 + logK + logTeff - logMass #// M-B dist, square of v_mode help = math.exp( logHelp) + xiT * xiT #// quadratic sum of thermal v and turbulent v logHelp = 0.5 * math.log(help) logDopp = logHelp + logLam0 - logC doppler = math.exp(logDopp) #// cm #//System.out.println("LineGrid: doppler, logDopp: " + doppler + " " + logE*logDopp); #//Set up a half-profile Delta_lambda grid in Doppler width units #//from line centre to wing #//int numCore = 5; #//int numWing = 5; #//int numWing = 0; //debug numPoints = 1 #// a 2D 2 X numPoints array of Delta Lambdas #// Row 0 : Delta lambdas in cm - will need to be in nm for Planck and Rad Trans? #// Row 1 : Delta lambdas in Doppler widths linePoints = [[0.0 for i in range(numPoints)] for j in range(2)] #// Line profiel points in Doppler widths - needed for Voigt function, H(a,v): v = [0.0 for i in range(numPoints)] #double logV, ii, jj; il = 0 ii = float(il) #// In core, space v points linearly: #// Voigt "v" parameter #// v > 0 --> This is the *red* wing: v[il] = ii linePoints[0][il] = doppler * v[il] linePoints[1][il] = v[il] #//System.out.println("LineGrid: il, lam, v: " + il + " " + #// linePoints[0][il] + " " + linePoints[1][il]); return linePoints
def lineKap(lam0In, logNums, logFluIn, linePoints, lineProf, numDeps, zScale, tauRos, temp, rho, logFudgeTune): logE10 = math.log(10.0) #//natural log of 10 c = Useful.c() logC = Useful.logC() k = Useful.k() logK = Useful.logK() logH = Useful.logH() logEe = Useful.logEe() logMe = Useful.logMe() ln10 = math.log(10.0) logE = math.log10(math.e) #// for debug output log2pi = math.log(2.0 * math.pi) log2 = math.log(2.0) lam0 = lam0In #// * 1.0E-7; //nm to cm logLam0 = math.log(lam0) #//double logNl = logNlIn * ln10; // Convert to base e logFlu = logFluIn * ln10 #// Convert to base e logKScale = math.log10(zScale) #//chiI = chiI * Useful.eV; // Convert lower E-level from eV to ergs #//double boltzFacI = chiI / k; // Pre-factor for exponent of excitation Boltzmann factor #//double logSahaFac = log2 + (3.0/2.0) * ( log2pi + logMe + logK - 2.0*logH); #//chiL = chiL * Useful.eV; // Convert lower E-level from eV to ergs #//double boltzFac = chiL / k; // Pre-factor for exponent of excitation Boltzmann factor numPoints = len(linePoints[0]) #//System.out.println("LineKappa: numPoints: " + numPoints); #double logPreFac; #//This converts f_lu to a volume extinction coefficient per particle - Rutten, p. 23 logPreFac = logFlu + math.log(math.pi) + 2.0 * logEe - logMe - logC #//System.out.println("LINEKAPPA: logPreFac " + logPreFac); #//Assume wavelength, lambda, is constant throughout line profile for purpose #// of computing the stimulated emission correction #double logExpFac; logExpFac = logH + logC - logK - logLam0 #//System.out.println("LINEKAPPA: logExpFac " + logExpFac); #// int refRhoIndx = TauPoint.tauPoint(numDeps, tauRos, 1.0); #// double refLogRho = rho[1][refRhoIndx]; #//System.out.println("LINEKAPPA: refRhoIndx, refRho " + refRhoIndx + " " + logE*refRho); #// return a 2D numPoints x numDeps array of monochromatic *LINE* extinction line profiles logKappaL = [[0.0 for i in range(numDeps)] for j in range(numPoints)] #double num, logNum, logExpFac2, expFac, stimEm, logStimEm, logSaha, saha, logIonFrac; #double logNe; for id in range(numDeps): logExpFac2 = logExpFac - temp[1][id] expFac = -1.0 * math.exp(logExpFac2) stimEm = 1.0 - math.exp(expFac) logStimEm = math.log(stimEm) logNum = logNums[id] #//if (id == refRhoIndx) { #// System.out.println("LINEKAPPA: logStimEm " + logE*logStimEm); #//} for il in range(numPoints): #// From Radiative Transfer in Stellar Atmospheres (Rutten), p.31 #// This is a *volume* co-efficient ("alpha_lambda") in cm^-1: logKappaL[il][id] = logPreFac + logStimEm + logNum + math.log( lineProf[il][id]) #//if (id == 36) { #// System.out.println("il " + il + " logNum " + logE*logNum + " Math.log(lineProf[il][id]) " + logE*Math.log(lineProf[il][id])); #//// //System.out.println("logPreFac " + logPreFac + " logStimEm " + logStimEm); #//} #//System.out.println("LINEKAPPA: id, il " + id + " " + il + " logKappaL " + logE * logKappaL[il][id]); #//Convert to mass co-efficient in g/cm^2: #// This direct approach won't work - is not consistent with fake Kramer's law scaling of Kapp_Ros with g instead of rho logKappaL[il][id] = logKappaL[il][id] - rho[1][id] #//Try something: #// #// ********************** #// Opacity problem #2 #// #//Line opacity needs to be enhanced by same factor as the conitnuum opacity #// - related to Opacity problem #1 (logFudgeTune in GrayStarServer3.java) - ?? #// logKappaL[il][id] = logKappaL[il][id] + logE10 * logFudgeTune #//if (id == 12) { #// System.out.println("LINEKAPPA: id, il " + id + " " + il + " logKappaL " + logE * logKappaL[il][id] #// + " logPreFac " + logE*logPreFac + " logStimEm " + logE*logStimEm + " logNum " + logE*logNum #// + " log(lineProf[il]) " + logE*Math.log(lineProf[il][id]) + " rho[1][id] " + logE * rho[1][id]); #// } #//if (id == refRhoIndx-45) { #// System.out.println("LINEKAPPA: id, il " + id + " " + il + " logKappaL " + logE*logKappaL[il][id] #// + " logPreFac " + logE*logPreFac + " logStimEm " + logE*logStimEm + " logNum " + logE*logNum + " logRho " + logE*rho[1][id] #// + " log(lineProf[1]) " + logE*Math.log(lineProf[1][il]) ); #//} #} // il - lambda loop #} // id - depth loop return logKappaL
def stark(linePoints, lam0In, logAij, logGammaCol, numDeps, teff, tauRos, temp, pGas, Ne, tempSun, pGasSun, hjertComp, lineName): c = Useful.c() logC = Useful.logC() #//double k = Useful.k; logK = Useful.logK() #//double e = Useful.e; #//double mE = Useful.mE; lam0 = lam0In #// * 1.0E-7; //nm to cm logLam0 = math.log(lam0) logLam0A = math.log(lam0) + 8.0*math.log(10.0) #//cm to A ln10 = math.log(10.0) ln2 = math.log(2.0) ln4pi = math.log(4.0 * math.pi) lnSqRtPi = 0.5 * math.log(math.pi) sqRtPi = math.sqrt(math.pi) sqPi = math.sqrt(math.pi) #//double ln100 = 2.0*Math.log(10.0); logE = math.log10(math.e) #// for debug output doppler = linePoints[0][1] / linePoints[1][1] logDopp = math.log(doppler) #//System.out.println("LineProf: doppler, logDopp: " + doppler + " " + logE*logDopp); #//Put input parameters into linear cgs units: #//double gammaCol = Math.pow(10.0, logGammaCol); #// Lorentzian broadening: #// Assumes Van der Waals dominates radiative damping #// log_10 Gamma_6 for van der Waals damping around Tau_Cont = 1 in Sun #// - p. 57 of Radiative Transfer in Stellar Atmospheres (Rutten) logGammaSun = 9.0 * ln10 #// Convert to base e #//double logFudge = Math.log(2.5); // Van der Waals enhancement factor tau1 = ToolBox.tauPoint(numDeps, tauRos, 1.0) #//System.out.println("LINEGRID: Tau1: " + tau1); #//logA = 2.0 * logLam0 + logGamma - ln4pi - logC - logDopp; #//a = Math.exp(logA); #//System.out.println("LINEGRID: logA: " + logE * logA); #//Set up a half-profile Delta_lambda grid in Doppler width units #//from line centre to wing numPoints = len(linePoints[0]) #//System.out.println("LineProf: numPoints: " + numPoints); #// Return a 2D numPoints X numDeps array of normalized line profile points (phi) lineProf = [ [ 0.0 for i in range(numDeps) ] for j in range(numPoints) ] #// Line profiel points in Doppler widths - needed for Voigt function, H(a,v): v = [0.0 for i in range(numPoints)] #double logV, ii; #// lineProf[0][0] = 0.0; v[0] = 0.0; //Line centre - cannot do logaritmically! #double gamma, logGamma, a, logA, voigt, core, wing, logWing, logVoigt; Aij = math.pow(10.0, logAij) il0 = 36 #// For Hjerting function approximation: #double vSquare, vFourth, vAbs, a2, a3, a4, Hjert0, Hjert1, Hjert2, Hjert3, Hjert4, hjertFn; #//Parameters for linear Stark broadening: #//Assymptotic ("far wing") "K" parameters #//Stehle & Hutcheon, 1999, A&A Supp Ser, 140, 93 and CDS data table #//Assume K has something to do with "S" and proceed as in Observation and Analysis of #// Stellar Photosphere, 3rd Ed. (D. Gray), Eq. 11.50, #// logTuneStark = math.log(3.16e7) #//convert DeltaI K parameters to deltaS STark profile parameters logKStark = [0.0 for i in range(11)] logKStark[0] = math.log(2.56e-03) + logTuneStark #//Halpha logKStark[1] = math.log(7.06e-03) + logTuneStark #//Hbeta logKStark[2] = math.log(1.19e-02) + logTuneStark #//Hgamma logKStark[3] = math.log(1.94e-02) + logTuneStark #//Hdelta logKStark[4] = math.log(2.95e-02) + logTuneStark #//Hepsilon logKStark[5] = math.log(4.62e-02) + logTuneStark #//H8 JB logKStark[6] = math.log(6.38e-02) + logTuneStark #//H9 JB logKStark[7] = math.log(8.52e-02) + logTuneStark #//H10 JB logKStark[8] = math.log(1.12e-01) + logTuneStark #//H11 JB logKStark[9] = math.log(1.43e-01) + logTuneStark #//H12 JB logKStark[10] = math.log(1.80e-01) + logTuneStark #//H13 JB #//logKStark[11] = Math.log(2.11) + logTuneStark; //H30 JB thisLogK = [0.0 for i in range(4)] #//default initialization #//double thisLogK = logKStark[10]; //default initialization #//which Balmer line are we? crude but effective: if (lam0In > 650.0e-7): thisLogK = logKStark[0] #//Halpha #//System.out.println("Halpha") #} if ( (lam0In > 480.0e-7) and (lam0In < 650.0e-7) ): #//System.out.println("Hbeta"); thisLogK = logKStark[1] #//Hbeta #} if ( (lam0In > 420.0e-7) and (lam0In < 470.0e-7) ): #//System.out.println("Hgamma"); thisLogK = logKStark[2] #//Hgamma #} if ( (lam0In > 400.0e-7) and (lam0In < 450.0e-7) ): #//System.out.println("Hdelta"); thisLogK = logKStark[3] #//Hdelta if ( (lam0In < 400.0e-7) ): #//System.out.println("Hepsilon"); thisLogK = logKStark[4] #//Hepsilon #} #// if ((lam0In < 390.0e-7)){ #// #////This won't work here - "species" is always just "HI": #// int numberInName = (int) lineName.substring("HI".length()); #// //console.log(numberInName); #// thisLogK = logKStark[numberInName-3]; #// } #// #double F0, logF0, lamOverF0, logLamOverF0; //electrostatic field strength (e.s.u.) #double deltaAlpha, logDeltaAlpha, logStark, logStarkTerm; //reduced wavelength de-tuning parameter (Angstroms/e.s.u.) logF0Fac = math.log(1.249e-9) #// log wavelength de-tunings in A: #double logThisPoint, thisPoint; #//System.out.println("il0 " + il0 + " temp[il] " + temp[0][il0] + " press[il] " + logE*press[1][il0]); for id in range(numDeps): #//linear Stark broadening stuff: logF0 = logF0Fac + (0.666667)*Ne[1][id] logLamOverF0 = logLam0A - logF0 lamOverF0 = math.exp(logLamOverF0) #//System.out.println("id " + id + " logF0 " + logE*logF0 + " logLamOverF0 " + logE*logLamOverF0 + " lamOverF0 " + lamOverF0); #//Formula from p. 56 of Radiative Transfer in Stellar Atmospheres (Rutten), #// logarithmically with respect to solar value: logGamma = pGas[1][id] - pGasSun[1][tau1] + 0.7 * (tempSun[1][tau1] - temp[1][id]) + logGammaSun #//logGamma = logGamma + logFudge + logGammaCol logGamma = logGamma + logGammaCol #//Add radiation (natural) broadning: gamma = math.exp(logGamma) + Aij logGamma = math.log(gamma) #// #//if (id == 12){ #//System.out.println("LineGrid: logGamma: " + id + " " + logE * logGamma + " press[1][id] " + press[1][id] + " pressSun[1][tau1] " #// + pressSun[1][tau1] + " temp[1][id] " + temp[1][id] + " tempSun[1][tau1] " + tempSun[1][tau1]); #// } #//Voigt "a" parameter with line centre wavelength: logA = 2.0 * logLam0 + logGamma - ln4pi - logC - logDopp a = math.exp(logA) a2 = math.exp(2.0*logA) a3 = math.exp(3.0*logA) a4 = math.exp(4.0*logA) #// if (id == 12) { #//System.out.println("LineGrid: lam0: " + lam0 + " logGam " + logE * logGamma + " logA " + logE * logA); #// } #//if (id == 30) { #// //System.out.println("il v[il] iy y logNumerator logDenominator logInteg "); #// System.out.println("voigt: v logVoigt: "); #//} for il in range(numPoints): v[il] = linePoints[1][il] vAbs = abs(v[il]) vSquare = vAbs * vAbs vFourth = vSquare * vSquare #//System.out.println("LineProf: il, v[il]: " + il + " " + v[il]); #//Approximate Hjerting fn from tabulated expansion coefficients: #// Interpolate in Hjerting table to exact "v" value for each expanstion coefficient: #// Row 0 of Hjerting component table used for tabulated abscissae, Voigt "v" parameter if (vAbs <= 12.0): #//we are within abscissa domain of table Hjert0 = ToolBox.interpol(hjertComp[0], hjertComp[1], vAbs) Hjert1 = ToolBox.interpol(hjertComp[0], hjertComp[2], vAbs) Hjert2 = ToolBox.interpol(hjertComp[0], hjertComp[3], vAbs) Hjert3 = ToolBox.interpol(hjertComp[0], hjertComp[4], vAbs) Hjert4 = ToolBox.interpol(hjertComp[0], hjertComp[5], vAbs) else: #// We use the analytic expansion Hjert0 = 0.0 Hjert1 = (0.56419 / vSquare) + (0.846 / vFourth) Hjert2 = 0.0 Hjert3 = -0.56 / vFourth Hjert4 = 0.0 #} #//Approximate Hjerting fn with power expansion in Voigt "a" parameter #// "Observation & Analysis of Stellar Photospeheres" (D. Gray), 3rd Ed., p. 258: hjertFn = Hjert0 + a*Hjert1 + a2*Hjert2 + a3*Hjert3 + a4*Hjert4; logStark = -49.0 #//re-initialize if (vAbs > 2.0): #//System.out.println("Adding in Stark wing"); thisPoint = 1.0e8 * abs(linePoints[0][il]) #//cm to A logThisPoint = math.log(thisPoint) logDeltaAlpha = logThisPoint - logF0 deltaAlpha = math.exp(logDeltaAlpha) logStarkTerm = ( math.log(lamOverF0 + deltaAlpha) - logLamOverF0 ) logStark = thisLogK + 0.5*logStarkTerm - 2.5*logDeltaAlpha #//System.out.println("il " + il + " logDeltaAlpha " + logE*logDeltaAlpha + " logStarkTerm " + logE*logStarkTerm + " logStark " + logE*logStark); #//console.log("il " + il + " logDeltaAlpha " + logE*logDeltaAlpha + " logStarkTerm " + logE*logStarkTerm + " logStark " + logE*logStark); #//System.out.println("id " + id + " il " + il + " v[il] " + v[il] #// + " hjertFn " + hjertFn + " Math.exp(logStark) " + Math.exp(logStark)); #//not here! hjertFn = hjertFn + Math.exp(logStark); #//System.out.println("LINEGRID: il, v[il]: " + il + " " + v[il] + " lineProf[0][il]: " + lineProf[0][il]); #//System.out.println("LINEGRID: il, Voigt, H(): " + il + " " + voigt); #//Convert from H(a,v) in dimensionless Voigt units to physical phi((Delta lambda) profile: #//logVoigt = Math.log(voigt) + 2.0 * logLam0 - lnSqRtPi - logDopp - logC; #//System.out.println("stark: Before log... id " + id + " il " + il + " hjertFn " + hjertFn); #logVoigt = math.log(hjertFn) - lnSqRtPi - logDopp voigt = hjertFn / sqRtPi / doppler #//logVoigt = math.log(voigt) logStark = logStark - logF0 if (vAbs > 2.0): #//if (id == 24) { #// System.out.println("il " + il + " v[il] " + v[il] + " logVoigt " + logE*logVoigt + " logStark " + logE*logStark); #//} #//voigt = math.exp(logVoigt) + math.exp(logStark) voigt = voigt + math.exp(logStark) #//logVoigt = math.log(voigt) #logVoigt = logVoigt + 2.0 * logLam0 - logC voigt = voigt * math.pow(lam0, 2) / c #//lineProf[il][id] = math.exp(logVoigt) lineProf[il][id] = voigt if (lineProf[il][id] <= 0.0): lineProf[il][id] = 1.0e-49 #//if (id == 24) { #// System.out.println("lam0In " + lam0In); #// System.out.println("il " + il + " linePoints " + 1.0e7 * linePoints[0][il] + " id " + id + " lineProf[il][id] " + lineProf[il][id]); #//} #//System.out.println("LineProf: il, id, lineProf[il][id]: " + il + " " + id + " " + lineProf[il][id]); #} // il lambda loop #// if (id == 20) { #// for (int il = 0; il < numPoints; il++) { #// System.out.format("Voigt: %20.16f %20.16f%n", linePoints[1][il], logE * Math.log(lineProf[il][id])); #// } #// } #} //id loop return lineProf
def delta(linePoints, lam0In, numDeps, tauRos, massIn, xiTIn, teff): """//delta function line profile for initiali check of line strength""" lam0 = lam0In #// * 1.0E-7; //nm to cm logLam0 = math.log(lam0) logE = math.log10(math.e) #// for debug output #//System.out.println("LineProf: doppler, logDopp: " + doppler + " " + logE*logDopp); #//Put input parameters into linear cgs units: #//System.out.println("LINEGRID: Tau1: " + tau1); #//logA = 2.0 * logLam0 + logGamma - ln4pi - logC - logDopp; #//a = Math.exp(logA); #//System.out.println("LINEGRID: logA: " + logE * logA); #//Set up a half-profile Delta_lambda grid in Doppler width units #//from line centre to wing numPoints = 1 #//System.out.println("LineProf: numPoints: " + numPoints); #// Return a 2D numPoints X numDeps array of normalized line profile points (phi) lineProf = [ [ 0.0 for i in range(numDeps) ] for j in range(1) ] c = Useful.c() logC = Useful.logC() logK = Useful.logK() amu = Useful.amu() ln10 = math.log(10.0) ln2 = math.log(2.0) lnSqRtPi = 0.5 * math.log(math.pi) logTeff = math.log(teff) xiT = xiTIn * 1.0E5 #//km/s to cm/s logMass = math.log(massIn * amu) #//amu to g #// Compute depth-independent Doppler width, Delta_lambda_D: #double doppler, logDopp; #double logHelp, help; //scratch logHelp = ln2 + logK + logTeff - logMass #// M-B dist, square of v_mode help = math.exp(logHelp) + xiT * xiT #// quadratic sum of thermal v and turbulent v logHelp = 0.5 * math.log(help) logDopp = logHelp + logLam0 - logC doppler = math.exp(logDopp) #// cm #// Line profile points in Doppler widths - needed for Voigt function, H(a,v): #double ii; #// lineProf[0][0] = 0.0; v[0] = 0.0; //Line centre - cannot do logaritmically! #double delta, core, logDelta; #//int il0 = 36; #//System.out.println("il0 " + il0 + " temp[il] " + temp[0][il0] + " press[il] " + logE*press[1][il0]); for id in range(numDeps): #//if (il <= numCore) { #// - Gaussian ONLY - at line centre Lorentzian will diverge! delta = 1.0 #//System.out.println("LINEGRID- CORE: core: " + core); #//System.out.println("LINEGRID: il, v[il]: " + il + " " + v[il] + " lineProf[0][il]: " + lineProf[0][il]); #//System.out.println("LINEGRID: il, Voigt, H(): " + il + " " + voigt); #//Convert from H(a,v) in dimensionless Voigt units to physical phi((Delta lambda) profile: logDelta = math.log(delta) + 2.0 * logLam0 - lnSqRtPi - logDopp - logC lineProf[0][id] = math.exp(logDelta) #//if (id == 36) { #// System.out.println("il " + il + " linePoints " + 1.0e7 * linePoints[0][il] + " id " + id + " lineProf[il][id] " + lineProf[il][id]); #//} #//System.out.println("LineProf: il, id, lineProf[il][id]: " + il + " " + id + " " + lineProf[il][id]); #// if (id == 20) { #// for (int il = 0; il < numPoints; il++) { #// System.out.format("Voigt: %20.16f %20.16f%n", linePoints[1][il], logE * Math.log(lineProf[il][id])); #// } #// } #} //id loop return lineProf
def voigt(linePoints, lam0In, logAij, logGammaCol, numDeps, teff, tauRos, temp, pGas, tempSun, pGasSun, hjertComp, dbgHandle): c = Useful.c() logC = Useful.logC() #//double k = Useful.k; logK = Useful.logK() #//double e = Useful.e; #//double mE = Useful.mE; lam0 = lam0In #// * 1.0E-7; //nm to cm logLam0 = math.log(lam0) ln10 = math.log(10.0) ln2 = math.log(2.0); ln4pi = math.log(4.0 * math.pi) #lnSqRtPi = 0.5 * math.log(math.pi) sqRtPi = math.sqrt(math.pi) sqPi = math.sqrt(math.pi) #//double ln100 = 2.0*Math.log(10.0); logE = math.log10(math.e) #// for debug output doppler = linePoints[0][1] / linePoints[1][1] logDopp = math.log(doppler) #//System.out.println("LineProf: doppler, logDopp: " + doppler + " " + logE*logDopp); #//Put input parameters into linear cgs units: #//double gammaCol = Math.pow(10.0, logGammaCol); #// Lorentzian broadening: #// Assumes Van der Waals dominates radiative damping #// log_10 Gamma_6 for van der Waals damping around Tau_Cont = 1 in Sun #// - p. 57 of Radiative Transfer in Stellar Atmospheres (Rutten) logGammaSun = 9.0 * ln10 #// Convert to base e #//double logFudge = Math.log(2.5); // Van der Waals enhancement factor tau1 = ToolBox.tauPoint(numDeps, tauRos, 1.0) #outline = ("tau1 "+ str(tau1) + "\n") #dbgHandle.write(outline) #//System.out.println("LINEGRID: Tau1: " + tau1); #//logA = 2.0 * logLam0 + logGamma - ln4pi - logC - logDopp; #//a = Math.exp(logA); #//System.out.println("LINEGRID: logA: " + logE * logA); #//Set up a half-profile Delta_lambda grid in Doppler width units #//from line centre to wing numPoints = len(linePoints[0]) #//System.out.println("LineProf: numPoints: " + numPoints); #// Return a 2D numPoints X numDeps array of normalized line profile points (phi) lineProf = [ [ 0.0 for i in range(numDeps) ] for j in range(numPoints) ] #// Line profiel points in Doppler widths - needed for Voigt function, H(a,v): v = [0.0 for i in range(numPoints)] #double logV, ii; #// lineProf[0][0] = 0.0; v[0] = 0.0; //Line centre - cannot do logaritmically! #double gamma, logGamma, a, logA, voigt, core, wing, logWing, logVoigt; Aij = math.pow(10.0, logAij) il0 = 36 #// For Hjerting function approximation: #double vSquare, vFourth, vAbs, a2, a3, a4, Hjert0, Hjert1, Hjert2, Hjert3, Hjert4, hjertFn; #//System.out.println("il0 " + il0 + " temp[il] " + temp[0][il0] + " press[il] " + logE*press[1][il0]); for id in range(numDeps): #//Formula from p. 56 of Radiative Transfer in Stellar Atmospheres (Rutten), #// logarithmically with respect to solar value: logGamma = pGas[1][id] - pGasSun[1][tau1] + 0.7 * (tempSun[1][tau1] - temp[1][id]) + logGammaSun #if (id%5 == 1): # outline = ("id "+ str(id)+ " logGamma "+ str(logGamma) + "\n") # dbgHandle.write(outline) #//logGamma = logGamma + logFudge + logGammaCol; logGamma = logGamma + logGammaCol #//Add radiation (natural) broadning: gamma = math.exp(logGamma) + Aij logGamma = math.log(gamma) #// #//if (id == 12){ #//System.out.println("LineGrid: logGamma: " + id + " " + logE * logGamma + " press[1][id] " + press[1][id] + " pressSun[1][tau1] " #// + pressSun[1][tau1] + " temp[1][id] " + temp[1][id] + " tempSun[1][tau1] " + tempSun[1][tau1]); #// } #//Voigt "a" parameter with line centre wavelength: logA = 2.0 * logLam0 + logGamma - ln4pi - logC - logDopp a = math.exp(logA) a2 = math.exp(2.0*logA) a3 = math.exp(3.0*logA) a4 = math.exp(4.0*logA) #// if (id == 12) { #//System.out.println("LineGrid: lam0: " + lam0 + " logGam " + logE * logGamma + " logA " + logE * logA); #// } #//if (id == 30) { #// //System.out.println("il v[il] iy y logNumerator logDenominator logInteg "); #// System.out.println("voigt: v logVoigt: "); #//} for il in range(numPoints): v[il] = linePoints[1][il] vAbs = abs(v[il]) vSquare = vAbs * vAbs vFourth = vSquare * vSquare #//System.out.println("LineProf: il, v[il]: " + il + " " + v[il]); #//Approximate Hjerting fn from tabulated expansion coefficients: #// Interpolate in Hjerting table to exact "v" value for each expanstion coefficient: #// Row 0 of Hjerting component table used for tabulated abscissae, Voigt "v" parameter if (vAbs <= 12.0): #//we are within abscissa domain of table Hjert0 = ToolBox.interpol(hjertComp[0], hjertComp[1], vAbs) Hjert1 = ToolBox.interpol(hjertComp[0], hjertComp[2], vAbs) Hjert2 = ToolBox.interpol(hjertComp[0], hjertComp[3], vAbs) Hjert3 = ToolBox.interpol(hjertComp[0], hjertComp[4], vAbs) Hjert4 = ToolBox.interpol(hjertComp[0], hjertComp[5], vAbs) else: #// We use the analytic expansion Hjert0 = 0.0 Hjert1 = (0.56419 / vSquare) + (0.846 / vFourth) Hjert2 = 0.0 Hjert3 = -0.56 / vFourth Hjert4 = 0.0 #//Approximate Hjerting fn with power expansion in Voigt "a" parameter #// "Observation & Analysis of Stellar Photospeheres" (D. Gray), 3rd Ed., p. 258: hjertFn = Hjert0 + a*Hjert1 + a2*Hjert2 + a3*Hjert3 + a4*Hjert4 #if ((id%5 == 1) and (il%2 == 0)): # outline = ("il "+ str(il)+ " hjertFn "+ str(hjertFn) + "\n") # dbgHandle.write(outline) """/* Gaussian + Lorentzian approximation: //if (il <= numCore) { if (v[il] <= 2.0 && v[il] >= -2.0) { // - Gaussian ONLY - at line centre Lorentzian will diverge! core = Math.exp(-1.0 * (v[il] * v[il])); voigt = core; //System.out.println("LINEGRID- CORE: core: " + core); } else { logV = Math.log(Math.abs(v[il])); //Gaussian core: core = Math.exp(-1.0 * (v[il] * v[il])); // if (id == 12) { // System.out.println("LINEGRID- WING: core: " + core); // } //Lorentzian wing: logWing = logA - lnSqRtPi - (2.0 * logV); wing = Math.exp(logWing); voigt = core + wing; // if (id == 12) { // System.out.println("LINEGRID- WING: wing: " + wing + " logV " + logV); // } } // end else */""" #//System.out.println("LINEGRID: il, v[il]: " + il + " " + v[il] + " lineProf[0][il]: " + lineProf[0][il]); #//System.out.println("LINEGRID: il, Voigt, H(): " + il + " " + voigt); #//Convert from H(a,v) in dimensionless Voigt units to physical phi((Delta lambda) profile: #//logVoigt = Math.log(voigt) + 2.0 * logLam0 - lnSqRtPi - logDopp - logC; #//System.out.println("voigt: Before log... id " + id + " il " + il + " hjertFn " + hjertFn); #logVoigt = math.log(hjertFn) + 2.0 * logLam0 - lnSqRtPi - logDopp - logC voigt = hjertFn * math.pow(lam0, 2) / sqRtPi / doppler / c #logVoigt = math.log(voigt) #lineProf[il][id] = math.exp(logVoigt) lineProf[il][id] = voigt if (lineProf[il][id] <= 0.0): lineProf[il][id] = 1.0e-49 #// if (id == 12) { #// System.out.println("il " + il + " linePoints " + 1.0e7 * linePoints[0][il] + " id " + id + " lineProf[il][id] " + lineProf[il][id]); #// } #//System.out.println("LineProf: il, id, lineProf[il][id]: " + il + " " + id + " " + lineProf[il][id]); #} // il lambda loop #// if (id == 20) { #// for (int il = 0; il < numPoints; il++) { #// System.out.format("Voigt: %20.16f %20.16f%n", linePoints[1][il], logE * Math.log(lineProf[il][id])); #// } #// } #} //id loop return lineProf
def gauss(linePoints, lam0In, numDeps, teff, tauRos, temp, tempSun): c = Useful.c() logC = Useful.logC() #//double k = Useful.k; logK = Useful.logK() #//double e = Useful.e; #//double mE = Useful.mE; lam0 = lam0In #// * 1.0E-7; //nm to cm logLam0 = math.log(lam0) ln10 = math.log(10.0) ln2 = math.log(2.0) ln4pi = math.log(4.0 * math.pi) lnSqRtPi = 0.5 * math.log(math.pi) sqPi = math.sqrt(math.pi) #//double ln100 = 2.0*Math.log(10.0); logE = math.log10(math.e) #// for debug output doppler = linePoints[0][1] / linePoints[1][1] logDopp = math.log(doppler) tiny = 1.0e-19 #//?? #//System.out.println("LineProf: doppler, logDopp: " + doppler + " " + logE*logDopp); #//Put input parameters into linear cgs units: #//System.out.println("LINEGRID: Tau1: " + tau1); #//logA = 2.0 * logLam0 + logGamma - ln4pi - logC - logDopp; #//a = Math.exp(logA); #//System.out.println("LINEGRID: logA: " + logE * logA); #//Set up a half-profile Delta_lambda grid in Doppler width units #//from line centre to wing numPoints = len(linePoints[0]) #//System.out.println("LineProf: numPoints: " + numPoints); #// Return a 2D numPoints X numDeps array of normalized line profile points (phi) lineProf = [ [ 0.0 for i in range(numDeps) ] for j in range(numPoints) ] #// Line profiel points in Doppler widths - needed for Voigt function, H(a,v): v = [ 0.0 for i in range(numPoints) ] #double logV, ii; #// lineProf[0][0] = 0.0; v[0] = 0.0; //Line centre - cannot do logaritmically! #double gauss, core, logGauss; gauss = tiny #//default initialization #//int il0 = 36; #//System.out.println("il0 " + il0 + " temp[il] " + temp[0][il0] + " press[il] " + logE*press[1][il0]); for id in range(numDeps): for il in range(numPoints): v[il] = linePoints[1][il] #//System.out.println("LineProf: il, v[il]: " + il + " " + v[il]); #//if (il <= numCore) { if (v[il] <= 3.5 and v[il] >= -3.5): #// - Gaussian ONLY - at line centre Lorentzian will diverge! core = math.exp(-1.0 * (v[il] * v[il])) gauss = core #//System.out.println("LINEGRID- CORE: core: " + core); #} #//System.out.println("LINEGRID: il, v[il]: " + il + " " + v[il] + " lineProf[0][il]: " + lineProf[0][il]); #//System.out.println("LINEGRID: il, Voigt, H(): " + il + " " + voigt); #//Convert from H(a,v) in dimensionless Voigt units to physical phi((Delta lambda) profile: logGauss = math.log(gauss) + 2.0 * logLam0 - lnSqRtPi - logDopp - logC lineProf[il][id] = math.exp(logGauss) #//if (id == 36) { #// System.out.println("il " + il + " linePoints " + 1.0e7 * linePoints[0][il] + " id " + id + " lineProf[il][id] " + lineProf[il][id]); #//} #//System.out.println("LineProf: il, id, lineProf[il][id]: " + il + " " + id + " " + lineProf[il][id]); #} // il lambda loop #// if (id == 20) { #// for (int il = 0; il < numPoints; il++) { #// System.out.format("Voigt: %20.16f %20.16f%n", linePoints[1][il], logE * Math.log(lineProf[il][id])); #// } #// } #} //id loop """ /* Debug // Check that line profile is area-normalized (it is NOT, area = 1.4845992503443734E-19!, but IS constant with depth - !?: double delta; for (int id = 0; id < numDeps; id++) { double sum = 0.0; for (int il = 1; il < numPoints2; il++) { delta = lineProf2[0][il][id] - lineProf2[0][il - 1][id]; sum = sum + (lineProf2[1][il][id] * delta); } System.out.println("LineGrid: id, Profile area = " + id + " " + sum ); } */ """ return lineProf