Example #1
0
def test_equlibrium_state_vs_chiantipy(natom=8):
    """
        Test equilibrium states saved in EigenData2 and compare them with
        Outputs from ChiantiPy.
        Note:
        This test requires ChiantiPy to be installed (see details
        in: https://github.com/chianti-atomic/ChiantiPy).
    """
    try:
        import ChiantiPy.core as ch
    except ImportError:
        warnings.warn('ChiantiPy is required in this test.', UserWarning)
        return

    temperatures = [1.0e4, 1.0e5, 1.0e6, 1.0e7, 1.0e8]
    eqi_ch = ch.ioneq(natom)
    eqi_ch.calculate(temperatures)
    conce = eqi_ch.Ioneq

    table_sta = nei.EigenData2(element=natom)
    for i in range(2):
        ch_conce = conce[:, i]
        table_conce = table_sta.equilibrium_state(T_e=temperatures[i])
        assert ch_conce.all() == table_conce.all()
    return
Example #2
0
def test_element_range():
    """
    Function test_element_range:
        This function is used to test element including Hydrogen to Iron.
    """
    atomic_numb = np.linspace(1, 26, 26, endpoint=True)
    for i in atomic_numb:
        element_symbol = atomic.atomic_symbol(int(i))
        eigen = nei.EigenData2(element=element_symbol)
        print(f'Element: ', element_symbol)
Example #3
0
def test_reachequlibrium_state_multisteps(natom=8):
    """
        Starting the random initial distribution, the charge states will reach
        to equilibrium cases after a long time (multiple steps).
        In this test, we set the ionization and recombination rates at
        Te0=2.0e6 K and plasma density ne0=1.0e+7. A random charge states
        distribution will be finally closed to equilibrium distribution at
        2.0e6K.
    """
    #
    # Initial conditions, set plasma temperature, density and dt
    #
    element_symbol = atomic.atomic_symbol(int(natom))
    te0 = 1.0e+6  # unit: K
    ne0 = 1.0e+8  # unit: cm^-3

    # Start from any ionizaiont states, e.g., Te = 4.0d4 K,
    time = 0
    table = nei.EigenData2(element=natom)
    f0 = table.equilibrium_state(T_e=4.0e+4)

    print('START test_reachequlibrium_state_multisteps:')
    print(f'time_sta = ', time)
    print(f'INI: ', f0)
    print(f'Sum(f0) = ', np.sum(f0))

    # After time + dt:
    dt = 100000.0  # unit: second

    # Enter the time loop:
    for it in range(100):
        ft = func_solver_eigenval(natom, te0, ne0, time + dt, f0, table)
        f0 = np.copy(ft)
        time = time + dt

    print(f'time_end = ', time + dt)
    print(f'NEI:', ft)
    print(f'Sum(ft) = ', np.sum(ft))

    print(f"EI :", table.equilibrium_state(T_e=te0))
    print("End Test.\n")
Example #4
0
def test_adapt_time_step(natom=26):
    """
        Set a set of Te/ne profiles. Perfrom NEI calculations using adaptive
        time-step method and compare it with constant dt results.
    """
    #
    # Set Te and rho profiles
    #
    ncase = 1
    for icase in range(ncase):
        data = create_te_ne_profile(icase=icase)
        time_arr = data["time_arr"]  # unit: [s]
        te_arr = data["te_arr"]  # unit: [K]
        rho_arr = data["ne_arr"]  # unit: [cm^-3]

        # Start from equilibrium ionizaiont(EI) states
        table = nei.EigenData2(element=natom)
        f_ini = table.equilibrium_state(T_e=te_arr[0])

        # Method 1: Adaptive time-step:
        newprofile = adaptive_time_step(
            te_arr, rho_arr, time_arr, table, accuracy_factor=1.0e-3)
        print(f"Origin sampling points = ", len(te_arr))
        dt_min = 10000.0
        for i in range(1, newprofile["ntime"]):
            dt_c = newprofile["time"][i] - newprofile["time"][i - 1]
            if (dt_c <= dt_min):
                dt_min = dt_c

        print(f"Adaptive samplinge points =", newprofile["ntime"])
        print(
            f"Time = {time_arr[-1]}, Te_sta={te_arr[0]}, Te_end={te_arr[-1]}")
        print(f"EI_start={f_ini}")

        f0 = np.copy(f_ini)
        for i in range(1, newprofile["ntime"]):
            im = i - 1
            ic = i
            time_im = newprofile["time"][im]
            time_ic = newprofile["time"][ic]

            # Time step between im and ic
            dt_mc = math.fabs(time_ic - time_im)
            # Constant Temperature
            te_mc = newprofile["te"][im]
            # Average Densisty
            ne_mc = newprofile["neavg"][im]

            # NEI one-step
            ft = func_solver_eigenval(natom, te_mc, ne_mc, dt_mc, f0, table)
            f0 = np.copy(ft)

        f_nei_ada_time = ft
        print(f"Min_dt= {dt_min}")
        print(f"NEI(adapt_dt)={f_nei_ada_time}")

        # Method 2: Constant time-step:
        f0 = np.copy(f_ini)
        time_current = 0.0
        dt_const = 0.05
        while time_current < time_arr[-1]:
            te_current = np.interp(time_current, time_arr, te_arr)
            ne_current = 0.5 * (
                np.interp(time_current, time_arr, rho_arr) + np.interp(
                    time_current + dt_const, time_arr, rho_arr))
            ft = func_solver_eigenval(natom, te_current, ne_current, dt_const,
                                      f0, table)
            f0 = np.copy(ft)
            time_current = time_current + dt_const
            stdout.write("\r%f" % time_current)
            stdout.flush()
        stdout.write("\n")
        dt = time_arr[-1] - time_current
        te_current = np.interp(time_current, time_arr, te_arr)
        ne_current = np.interp(time_current, time_arr, rho_arr)
        ft = func_solver_eigenval(natom, te_current, ne_current, dt, f0, table)
        ft_nei = ft

        # final results
        f_ei_end = table.equilibrium_state(T_e=te_arr[-1])
        print(f"const_dt = {dt_const}")
        print(f"NEI(const_dt)={ft_nei}")
        diff_adp_cdt = (ft_nei - f_nei_ada_time) / np.amax(
            [ft_nei, f_nei_ada_time])
        print(f"Dif_a&c ={diff_adp_cdt}")
        print(f"EI_end  ={f_ei_end}")

        #
        # Output results
        #
    return 1
Example #5
0
def test_nei_multisteps(natom=8):
    """
        Read temprature and density history file and perfrom NEI calculations.
        Starting the equilibrium states, and set any time-step in here
        (adaptive time-step is required in practice).
    """
    #
    # Read Te and rho profiles
    #
    file_path = '/Users/chshen/Works/Project/REU/REU_2018/2018_SummerProject/cr1913_traj_180601/'
    files = sorted(glob.glob(file_path + '*.sav'))

    for file in files:
        data = readsav(file, python_dict=True)
        time = data['time']  # unit: [s]
        te = data['te']  # unit: [K]
        rho = data['rho']  # unit: [cm^-3]
        v = data['v']  # unit: [km/s]
        r = data['r']  # r position in sphericalcoordinate: [Rolar radio]
        t = data['t']  # t position in sphericalcoordinate: [0 ~ PI]
        p = data['p']  # p position in sphericalcoordinate: [0 ~ 2PI]

        #
        # NEI calculations parametes: dt and element
        #
        dt = 0.1  # 0.1s

        # Start from equilibrium ionizaiont(EI) states
        time_current = 0
        table = nei.EigenData2(element=natom)
        f_ini = table.equilibrium_state(T_e=te[0])

        print('START:')
        print(f'time_sta = ', time_current, te[0])
        print(f_ini)

        # Get adaptive time-step
        newprofile = adaptive_time_step(te, rho, time, table)
        print(f"Origin points = ", len(te))
        dt_min = 10000.0
        for i in range(1, newprofile["ntime"]):
            dt_c = newprofile["time"][i] - newprofile["time"][i - 1]
            if (dt_c <= dt_min):
                dt_min = dt_c

        print(f"Adaptive time-step =", newprofile["ntime"], "min_dt=", dt_min)

        # Enter the time-advance using the adaptive time-step:
        f0 = np.copy(f_ini)
        for i in range(1, newprofile["ntime"]):
            im = i - 1
            ic = i
            dt_mc = math.fabs(newprofile["time"][ic] - newprofile["time"][im])
            te_mc = newprofile["te"][im]
            ne_mc = 0.5 * (newprofile["ne"][im] + newprofile["ne"][ic])
            ft = func_solver_eigenval(natom, te_mc, ne_mc, dt_mc, f0, table)
            f0 = np.copy(ft)
            stdout.write("\r%f" % time_current)
            stdout.flush()
        stdout.write("\n")
        f_nei_ada_time = ft
        print(f"NEI(adt)={f_nei_ada_time}")

        # Enter the time loop using constant time-step = 0.1s:
        f0 = np.copy(f_ini)
        while time_current < time[-1]:
            # The original time interval is 1.4458s in this test
            te_current = np.interp(time_current, time, te)
            ne_current = 0.5 * (np.interp(time_current, time, rho) +
                                np.interp(time_current + dt, time, rho))
            ft = func_solver_eigenval(natom, te_current, ne_current, dt, f0,
                                      table)
            f0 = np.copy(ft)
            time_current = time_current + dt
            stdout.write("\r%f" % time_current)
            stdout.flush()
        stdout.write("\n")

        # The last step
        dt = time[-1] - time_current
        te_current = np.interp(time_current, time, te)
        ne_current = np.interp(time_current, time, rho)
        ft = func_solver_eigenval(natom, te_current, ne_current, dt, f0, table)

        # final results
        f_ei_end = table.equilibrium_state(T_e=te[-1])

        print(f'time_end = ', time_current, te[-1])
        print(f"EI :", f_ei_end)
        print(f"NEI(cdt)={ft}")

        #
        # Output results
        #
    return 1