index = ii

        zeta = fz.get_zeta(NH2[index])
        print("CR ionization rate = ", zeta, "compared to Ntot",
              fz.get_zeta(Ntot[index]), "NH2 = ", NH2[index], "Ntot = ",
              Ntot[index])

        #zeta = fz.get_zeta(fH2shield[ii])

        ############################################################################################
        Jpe, Je, Jh, Jc, ZZall = fz.compute_currents([nH[index], nC[index]],
                                                     [xHp[index], xCp[index]],
                                                     xH2[index],
                                                     temp[index],
                                                     zeta,
                                                     grain_size,
                                                     Ntot[index],
                                                     grain_type,
                                                     Qabs,
                                                     G0=G0)
        JCRe, JCRpe, ZZnew = fz.compute_CR_currents(nH[index], zeta,
                                                    grain_size, grain_type,
                                                    Qabs)

        zeq = fz.get_zeq_vec(Jpe, Je, Jh, Jc, ZZall, grain_size, grain_type)
        new_zmin, new_zmax = fz.get_new_zmin_zmax([nH[index], nC[index]],
                                                  [xHp[index], xCp[index]],
                                                  temp[index],
                                                  grain_size,
                                                  Ntot[index],
                                                  grain_type,
    for ii in range(3):

        print("Running %s grain with size %i in phase %s" %
              (grain_type, grain_size[kk], phases[ii]))

        # Get the CR ionization rate given the Column density.
        # Update to the total column density instead of the weird Flash function.
        zeta = fz.get_zeta(Ntot[ii])

        ############################################################################################
        # Run the charge distribution calculation!!!
        Jpe, Je, Jh, Jc, ZZall = fz.compute_currents([nH[ii], nC[ii]],
                                                     [xe[ii], 0.0],
                                                     xH2[ii],
                                                     temp[ii],
                                                     zeta,
                                                     grain_size[kk],
                                                     Ntot[ii],
                                                     grain_type,
                                                     Qabs[kk],
                                                     G0=G0)
        JCRe, JCRpe, ZZnew = fz.compute_CR_currents(nH[ii], zeta,
                                                    grain_size[kk], grain_type,
                                                    Qabs[kk])
        zeq = fz.get_zeq_vec(Jpe, Je, Jh, Jc, ZZall, grain_size[kk],
                             grain_type)
        new_zmin, new_zmax = fz.get_new_zmin_zmax([nH[ii], nC[ii]],
                                                  [xe[ii], 0.0],
                                                  temp[ii],
                                                  grain_size[kk],
                                                  Ntot[ii],
                                                  grain_type,
def netHeating_full(grain_size,
                    grain_type,
                    nH,
                    temp,
                    xe,
                    xH2,
                    Ntot,
                    NH2,
                    G0=1.7,
                    save_output=False,
                    outdir="default",
                    pedantic=False):
    """
    Perform the full calculation of the net heating by a single grain given the ISM ambient parameters.
    """
    import _pickle as pickle
    import compute_charge_dist as fz
    import numpy as np
    import PeHeat_Functions as peh

    #Full calculation of the net heating by a grain at a given cell.
    Qabs = fz.get_QabsTable(grain_type, grain_size)

    #print("Running grain size %i, "%(grain_size))

    zeta = fz.get_zeta(NH2)

    # Compute the charge distribution.
    ############################################################################################
    Jpe, Je, Jh, Jc, ZZall = fz.compute_currents([nH, nH * 1.0e-4],
                                                 [xe, 1.0e4 * min(xe, 1.0e-4)],
                                                 xH2,
                                                 temp,
                                                 zeta,
                                                 grain_size,
                                                 Ntot,
                                                 grain_type,
                                                 Qabs,
                                                 G0=G0)
    JCRe, JCRpe, ZZnew = fz.compute_CR_currents(nH, zeta, grain_size,
                                                grain_type, Qabs)

    zeq = fz.get_zeq_vec(Jpe, Je, Jh, Jc, ZZall, grain_size, grain_type)
    new_zmin, new_zmax = fz.get_new_zmin_zmax([nH, nH * 1.0e-4],
                                              [xe, 1.0e4 * min(xe, 1.0e-4)],
                                              temp,
                                              grain_size,
                                              Ntot,
                                              grain_type,
                                              Qabs,
                                              zeta,
                                              zeq=zeq,
                                              G0=G0,
                                              includeCR=True)

    ffzCR, ZZfz = fz.vector_fz(Jpe,
                               Je,
                               Jh,
                               Jc,
                               JCRe,
                               JCRpe,
                               ZZall,
                               new_zmin,
                               new_zmax,
                               includeCR=True)

    # Compute the minimum and maximum allowd charges by this grain
    Zmin, Zmax = fz.get_Zmin(grain_size,
                             grain_type), fz.get_Zmax(grain_size, grain_type)
    Znum = int(Zmax + abs(Zmin) + 1)
    ZZ_all = np.linspace(Zmin, Zmax, num=Znum)

    Gamma_dotdot_Z = np.zeros_like(ZZ_all, dtype=np.float)

    for i in range(Znum):
        Gamma_dotdot_Z[i] = peh.get_Gamma_pe_dotdot(grain_size, ZZ_all[i],
                                                    grain_type, Ntot, Qabs)

    Cooling = peh.Cool_per_Grain(grain_size, grain_type, ZZfz, ffzCR, nH, xe,
                                 temp)

    Av = Ntot / 1.87e21

    Geff = G0 * np.exp(-2.5 * Av)
    G_CR = fz.get_G_CR(NH2)

    Gtot = Geff + G_CR

    Heating = peh.Gamma_per_grain(ZZ_all, Gamma_dotdot_Z, ZZfz, ffzCR)

    netHeating = Heating - Cooling

    if save_output:
        if nH < 1.0:
            phase = "WNM"
        elif nH > 1.0 and nH < 100:
            phase = "CNM"
        else:
            phase = "CMM"

        if outdir == "default":
            outdir = "/home/jcibanezm/codes/run/PeHeat"

        filename = "%s/TotalHeating_ISM%s_%s_%.3fAA.pkl" % (
            outdir, phase, grain_type, grain_size)

        dictionary = {
            "info":
            "Saving the Heating, Cooling, charge array and charge distribution."
        }
        dictionary["netHeating"] = netHeating
        dictionary["Heating"] = Heating
        dictionary["Cooling"] = Cooling
        dictionary["grain_size"] = grain_size
        dictionary["grain_type"] = grain_type
        dictionary["ffz"] = ffzCR
        dictionary["ZZ"] = ZZfz
        dictionary["nH"] = nH
        dictionary["temp"] = temp
        dictionary["Geff"] = Geff
        dictionary["Gtot"] = Gtot
        dictionary["zeta"] = zeta
        dictionary["Ntot"] = Ntot
        dictionary["NH2"] = NH2
        dictionary["ne"] = nH * xe
        dictionary["xe"] = xe
        dictionary["xH2"] = xH2
        dictionary["zmin"] = new_zmin
        dictionary["zmax"] = new_zmax

        if pedantic == True:
            print(
                "Saving a file with the information of the net Heating and Cooling in this cell."
            )
            print("Cell properties:")
            print("grain size = %.1f, grain type = %s" %
                  (grain_size, grain_type))
            print("ntot = %.2g \t temp = %.2g \t Geff = %.2g \t Gtot = %.2g" %
                  (nH, temp, Geff, Gtot))
            print("zeta = %.2g \t Ntot = %.2g \t NH2 = %.2g \t ne = %.2g" %
                  (zeta, Ntot, NH2, nH * xe))
            print("xe = %.2g \t xH2 = %.2g" % (xe, xH2))
            print("netHeating = %.2g erg s-1  \t Cooling %.2g erg s-1" %
                  (netHeating, Cooling))
            print("ZZ =", ZZfz)
            print("f(Z) = ", ffzCR)

        outfile = open('%s' % (filename), 'wb')
        pickle.dump(dictionary, outfile)
        outfile.close()

    #return netHeating, Cooling, ZZfz, ffzCR
    return Heating
Beispiel #4
0
def charge_dist(filename, pos, num_procs, grain_size, grain_type, test=False):
    """ Calculates the charge distribution """
    import compute_charge_dist as fz
    import yt
    import numpy as np
    import sys

    mH = 1.6733e-24  # g
    mC = 12.011 * mH

    print_to_logfile("Reading Flash file. \t proc = %i" % pos,
                     grain_size=grain_size,
                     grain_type=grain_type,
                     filename=filename,
                     first_call=True)

    pf = yt.load("%s" % (filename))

    ppc = 3.085677e18
    le = [-15 * ppc, -4.93696000e+19, -4.93696000e+19]
    re = [+15 * ppc, +4.93696000e+19, +4.93696000e+19]

    dd = pf.box(le, re)
    if pos == 0:
        print("Total number of cells = %i" % len(dd["dens"]))
    #dd = pf.all_data()

    # Read file and calculate the number of cells.
    if test == True:
        num_cells = 5 * num_procs
    else:
        num_cells = len(dd["dens"])

    # calculate the number of cells to be distributed per processor. [has to be an interger number]
    # Calculate the offset in the array to
    cells_per_proc = num_cells // num_procs

    # Find the offset in the array where the information is coming from.
    offset = cells_per_proc * pos

    # The missing cells are handled by the last processor
    if pos == (num_procs - 1): cells_per_proc += num_cells % num_procs

    dens = np.array(np.zeros(cells_per_proc))
    temp, Av = np.zeros_like(dens), np.zeros_like(dens)
    ih2, iha, ihp, ico, icp, dx, xx, yy, zz = np.zeros_like(
        dens), np.zeros_like(dens), np.zeros_like(dens), np.zeros_like(
            dens), np.zeros_like(dens), np.zeros_like(dens), np.zeros_like(
                dens), np.zeros_like(dens), np.zeros_like(dens)

    zmean, zmode, zstd = np.zeros_like(dens), np.zeros_like(
        dens), np.zeros_like(dens)

    nH, nC, xHp, xCp, ne, xe = np.zeros_like(dens), np.zeros_like(
        dens), np.zeros_like(dens), np.zeros_like(dens), np.zeros_like(
            dens), np.zeros_like(dens)

    zminmax = np.array(np.zeros(2 * cells_per_proc))

    tauz = np.zeros_like(dens)

    fdist = []
    #fdist = np.zeros_like(dens)

    dictionary = {
        "info": "charge distribution calculated in processor %i" % pos
    }

    ############################################################################
    # I should read the Qabs table here, and pass it to the Jrate, calculation.
    ############################################################################
    Qabs = fz.get_QabsTable(grain_type, grain_size)

    #########################################################################################################
    #                          Charge distribution loop over all cells.
    #########################################################################################################
    print_to_logfile("Looping over %i cells in proc = %i" %
                     (cells_per_proc, pos),
                     grain_size=grain_size,
                     grain_type=grain_type,
                     filename=filename)

    for ii in range(cells_per_proc):

        index = offset + ii

        if ii % 1.0e4 == 0:
            print("I'm proc %i, running cell %i" % (pos, index))

        dens[ii] = dd["dens"][index].value
        temp[ii] = dd["temp"][index].value
        Av[ii] = dd["cdto"][index].value

        ih2[ii] = dd["ih2 "][index].value
        iha[ii] = dd["iha "][index].value
        ihp[ii] = dd["ihp "][index].value
        ico[ii] = dd["ico "][index].value
        icp[ii] = dd["icp "][index].value
        dx[ii] = dd["dx"][index].value
        xx[ii] = dd["x"][index].value
        yy[ii] = dd["y"][index].value
        zz[ii] = dd["z"][index].value

        # Number density of hydrogen atoms.
        nH[ii] = dd["dens"][index].value * (
            dd["ihp "][index].value + dd["iha "][index].value +
            dd["ih2 "][index].value) / (1.4 * mH)
        nH2 = dd["dens"][index].value * (dd["ih2 "][index].value) / (1.4 * mH)

        # Number density of carbon atoms.
        nC[ii] = dd["dens"][index].value * (
            dd["icp "][index].value + dd["ico "][index].value) / (1.4 * mC)

        # fraction of ionized hydrogen and carbon
        xHp[ii] = dd["dens"][index].value * dd["ihp "][index].value / (
            1.4 * mH) / nH[ii]
        xCp[ii] = dd["dens"][index].value * dd["icp "][index].value / (
            1.4 * mC) / nC[ii]

        # Number density of electrons
        ne[ii] = dd["dens"][index].value * (dd["ihp "][index].value /
                                            (1.4 * mH) +
                                            dd["icp "][index].value /
                                            (1.4 * mC))

        # electron fraction.
        xe[ii] = ne[ii] / (nH[ii] + nC[ii])

        ############################################################################################
        # Run the charge distribution calculation!!!
        Jpe, Je, Jh, Jc, ZZall = fz.compute_currents([nH[ii], nC[ii]],
                                                     [xHp[ii], xCp[ii]],
                                                     temp[ii], grain_size,
                                                     Av[ii], grain_type, Qabs)
        # Compute CR currents
        JCRe, JCRpe, ZZnew = fz.compute_CR_currents(nH2, grain_size,
                                                    grain_type)

        zeq = fz.get_zeq_vec(Jpe, Je, Jh, Jc, ZZall, grain_size, grain_type)
        new_zmin, new_zmax = fz.get_new_zmin_zmax([nH[ii], nC[ii]],
                                                  [xHp[ii], xCp[ii]],
                                                  temp[ii],
                                                  grain_size,
                                                  Av[ii],
                                                  grain_type,
                                                  Qabs,
                                                  zeq=zeq)

        ffz, ZZ = fz.vector_fz(Jpe,
                               Je,
                               Jh,
                               Jc,
                               JCRe,
                               JCRpe,
                               ZZall,
                               new_zmin,
                               new_zmax,
                               includeCR=True)

        # This should be updated accordingly!!!
        tauz[ii] = fz.tauz_vec(Jpe, Je, Jh, Jc, ZZall, ffz, new_zmin, new_zmax)

        ######## Commented on Feb 13 2018 #### Before including CR currents.
        #        zeq                    = fz.get_zeq_vec      (Jpe, Je, Jh, Jc, ZZall, grain_size, grain_type)
        #        new_zmin, new_zmax     = fz.get_new_zmin_zmax([nH[ii], nC[ii]], [xHp[ii], xCp[ii]], temp[ii], grain_size, Av[ii], grain_type, Qabs, zeq=zeq)
        #        ffz, ZZ                = fz.vector_fz        (Jpe, Je, Jh, Jc, ZZall, new_zmin, new_zmax)
        #        tauz[ii]               = fz.tauz_vec         (Jpe, Je, Jh, Jc, ZZall, ffz, new_zmin, new_zmax)

        #zeq                 = fz.get_zeq          ([nH[ii], nC[ii]], [xHp[ii], xCp[ii]], temp[ii], grain_size, Av[ii], grain_type)
        #new_zmin, new_zmax  = fz.get_new_zmin_zmax([nH[ii], nC[ii]], [xHp[ii], xCp[ii]], temp[ii], grain_size, Av[ii], grain_type, zeq=zeq)
        #ffz, ZZ             = fz.compute_fz_speed ([nH[ii], nC[ii]], [xHp[ii], xCp[ii]], temp[ii], grain_size, Av[ii], grain_type, zmin=new_zmin, zmax=new_zmax)
        #tauz[ii] = fz.get_tauz(grain_size, grain_type, [nH[ii], nC[ii]], [xHp[ii], xCp[ii]], temp[ii], Av[ii], ZZ, ffz)

        Zm = fz.get_Zmode(ZZ, ffz)
        zmode[ii] = Zm

        avg, std = fz.weighted_avg_and_std(ZZ, ffz)
        zmean[ii] = avg
        zstd[ii] = std

        zminmax[ii * 2] = new_zmin
        zminmax[ii * 2 + 1] = new_zmax

        #fdist[ii]   = offset + ii
        for jj in range(len(ffz)):
            fdist.append(ffz[jj])

    print_to_logfile(
        "Finished loop over all cells in this processor. \t proc=%i" % pos,
        grain_size=grain_size,
        grain_type=grain_type,
        filename=filename)

    dictionary["dens"] = dens
    dictionary["temp"] = temp
    dictionary["Av"] = Av
    dictionary["zmean"] = zmean
    dictionary["zmode"] = zmode
    dictionary["zstd"] = zstd
    dictionary["tauz"] = tauz
    dictionary["fdist"] = np.array(fdist)
    dictionary["zminmax"] = np.array(zminmax)
    dictionary["nH"] = nH
    dictionary["nC"] = nC
    dictionary["xHp"] = xHp
    dictionary["xCp"] = xCp
    dictionary["ne"] = ne
    dictionary["xe"] = xe

    dictionary["iha"] = iha
    dictionary["ihp"] = ihp
    dictionary["ih2"] = ih2
    dictionary["ico"] = ico
    dictionary["icp"] = icp
    dictionary["dx"] = dx
    dictionary["xx"] = xx
    dictionary["yy"] = yy
    dictionary["zz"] = zz

    del dens, temp, Av, zmean, zmode, zstd, fdist, zminmax, nH, nC, ne, xe, xHp, xCp, tauz
    del pf, dd, iha, ihp, ih2, ico, icp, dx, xx, yy, zz

    gc.collect()

    return dictionary