Пример #1
0
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
Пример #2
0
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
Пример #3
0
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
Пример #4
0
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
Пример #5
0
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
Пример #6
0
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
Пример #7
0
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
Пример #8
0
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
Пример #9
0
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
Пример #10
0
def levelPops(lam0In, logNStage, chiL, logUw, gwL, numDeps, temp):
    """ Returns depth distribution of occupation numbers in lower level of b-b transition,

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

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

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

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

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

    logGwL = math.log(gwL)

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

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

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

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

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

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

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

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

    #double num, logNum, expFac;

    for id in range(numDeps):

        #//Determine temperature dependenet partition functions Uw:

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

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

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

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

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

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

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

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

        #// System.out.println("LevelPops: id, logNums[0][id], logNums[1][id], logNums[2][id], logNums[3][id]: " + id + " "
        #//          + Math.exp(logNums[0][id]) + " "
        #//         + Math.exp(logNums[1][id]) + " "
        #//          + Math.exp(logNums[2][id]) + " "
        #//        + Math.exp(logNums[3][id]));
        #//System.out.println("LevelPops: id, logNums[0][id], logNums[1][id], logNums[2][id], logNums[3][id], logNums[4][id]: " + id + " "
        #//        + logE * (logNums[0][id]) + " "
        #//        + logE * (logNums[1][id]) + " "
        #//        + logE * (logNums[2][id]) + " "
        # //        + logE * (logNums[3][id]) + " "
        #//        + logE * (logNums[4][id]) );
        #//System.out.println("LevelPops: id, logIonFracI, logIonFracII: " + id + " " + logE*logIonFracI + " " + logE*logIonFracII
        #//        + "logNum, logNumI, logNums[0][id], logNums[1][id] "
        #//        + logE*logNum + " " + logE*logNumI + " " + logE*logNums[0][id] + " " + logE*logNums[1][id]);
        #//System.out.println("LevelPops: id, logIonFracI: " + id + " " + logE*logIonFracI
        #//        + "logNums[0][id], boltzFacL/temp[0][id], logNums[2][id]: "
        #//        + logNums[0][id] + " " + boltzFacL/temp[0][id] + " " + logNums[2][id]);
    #//id loop
    #stop
    return logNums
Пример #11
0
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
Пример #12
0
def lineKap(lam0In, logNums, logFluIn, linePoints, lineProf, numDeps, zScale,
            tauRos, temp, rho, logFudgeTune):

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

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

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

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

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

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

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

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

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

    for id in range(numDeps):

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

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

        logNum = logNums[id]

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

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

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

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

    #} // id - depth loop

    return logKappaL
Пример #13
0
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
Пример #14
0
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
Пример #15
0
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
Пример #16
0
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