def prop2d(mode,
           dielectric,
           max_harmonic,
           max_power,
           has_main_phase=False,
           optimize_z=True):
    propagator = prop.ParaxialPerpendicularPropagator2D(
        p2d,
        dielectric,
        mode,
        direction=-1,
        ray_y=0,
        max_harmonic=max_harmonic,
        max_power=max_power)

    E = propagator.propagate(omega,
                             x_start,
                             x_end,
                             nx,
                             E_start,
                             Y1D,
                             Z1D,
                             mute=False,
                             debug_mode=True,
                             include_main_phase=has_main_phase,
                             optimize_z=optimize_z)

    return (E, propagator)
def error_2d(nx_power_min,
             nx_power_max,
             nx_power_step,
             mode='O',
             dielectric=dt.ColdElectronColdIon,
             max_harmonic=2,
             max_power=2,
             has_main_phase=False):
    """
    nx_step: the step size in nx power
    """
    nx_power_array = np.arange(nx_power_min, nx_power_max + 1, nx_power_step)
    nx_array = 2**nx_power_array
    x_stepsize = np.float(np.abs(x_end - x_start)) / nx_array

    p2 = prop.ParaxialPerpendicularPropagator2D(p2d_uni,
                                                dielectric,
                                                mode,
                                                direction=-1,
                                                ray_y=0,
                                                max_harmonic=max_harmonic,
                                                max_power=max_power)
    max_abs_err = np.zeros_like(nx_array, dtype='float')
    max_rel_err = np.zeros_like(max_abs_err)

    tstart = time.clock()

    E_mark = p2.propagate(omega,
                          x_start,
                          x_end,
                          nx_array[-1],
                          E_start,
                          Y1D,
                          Z1D,
                          include_main_phase=has_main_phase)

    for i, ni in enumerate(nx_array[:-1]):

        Ei = p2.propagate(omega,
                          x_start,
                          x_end,
                          ni,
                          E_start,
                          Y1D,
                          Z1D,
                          include_main_phase=has_main_phase)

        step = nx_array[-1] / nx_array[i]
        E_marki = E_mark[..., ::step]
        abs_err = np.abs(Ei - E_marki)
        max_abs_err[i] = np.max(abs_err)

        rel_idx = np.abs(E_marki) > 1e-3 * np.max(np.abs(E_marki))
        max_rel_err[i] = np.max(np.abs(abs_err[rel_idx] / E_marki[rel_idx]))

    tend = time.clock()
    print('Total time used: {:.4}s'.format(tend - tstart))

    return max_abs_err, max_rel_err, nx_array, x_stepsize
def compare_1d2d(mode,
                 dielectric,
                 max_harmonic,
                 max_power,
                 has_main_phase=False):

    propagator1d = prop.ParaxialPerpendicularPropagator1D(
        p1d,
        dielectric,
        mode,
        direction=-1,
        max_harmonic=max_harmonic,
        max_power=max_power)

    E1 = propagator1d.propagate(omega,
                                x_start,
                                x_end,
                                nx,
                                E_start,
                                Y1D,
                                Z1D,
                                include_main_phase=has_main_phase)

    propagator2d_uni = prop.ParaxialPerpendicularPropagator2D(
        p2d_uni,
        dielectric,
        mode,
        direction=-1,
        ray_y=0,
        max_harmonic=max_harmonic,
        max_power=max_power)

    E2d_uni = propagator2d_uni.propagate(omega,
                                         x_start,
                                         x_end,
                                         nx,
                                         E_start,
                                         Y1D,
                                         Z1D,
                                         include_main_phase=has_main_phase)

    return (E1, propagator1d, E2d_uni, propagator2d_uni)
def benchmark_1d2d(nx_power_min,
                   nx_power_max,
                   nx_step,
                   mode='O',
                   dielectric=dt.ColdElectronColdIon,
                   max_harmonic=2,
                   max_power=2,
                   has_main_phase=False):
    """calculate error convergence against x step size
    
    :param float nx_min: log2(nx) minimum, start point of log mesh of total x 
                         steps.
    :param float nx_max: log2(nx) maximum, end point of log mesh of total x 
                         steps.
    :param int nx_step: step size in power array
    :param string mode: polarization mode
    :param dielectric: dielectric tensor type
    :type dielectric: :py:class:`FPSDP.Plamsa.DielectricTensor.Dielectric`
    :param int max_harmonic: highest harmonic resonance included
    :param int max_power: highest FLR effect power included
    """
    tstart = time.clock()

    nx_power = np.arange(nx_power_min, nx_power_max + 1, nx_step)

    nx_array = 2**nx_power
    x_stepsize = np.float(np.abs(x_end - x_start)) / nx_array

    p1 = prop.ParaxialPerpendicularPropagator1D(p1d,
                                                dielectric,
                                                mode,
                                                direction=-1,
                                                max_harmonic=max_harmonic,
                                                max_power=max_power)
    p2 = prop.ParaxialPerpendicularPropagator2D(p2d_uni,
                                                dielectric,
                                                mode,
                                                direction=-1,
                                                ray_y=0,
                                                max_harmonic=max_harmonic,
                                                max_power=max_power)

    max_abs_err = np.empty_like(nx_array, dtype='float')
    max_rel_err = np.empty_like(max_abs_err)

    for i, ni in enumerate(nx_array):

        E1 = p1.propagate(omega,
                          x_start,
                          x_end,
                          ni,
                          E_start,
                          Y1D,
                          Z1D,
                          include_main_phase=has_main_phase)

        E2 = p2.propagate(omega,
                          x_start,
                          x_end,
                          ni,
                          E_start,
                          Y1D,
                          Z1D,
                          include_main_phase=has_main_phase)

        abs_err = np.abs(E2 - E1)
        max_abs_err[i] = np.max(abs_err)

        rel_idx = np.abs(E1) > 1e-3 * np.max(np.abs(E1))
        max_rel_err[i] = np.max(np.abs(abs_err[rel_idx] / E1[rel_idx]))

    print('Total time: {:.4}s'.format(time.clock() - tstart))

    return max_abs_err, max_rel_err, nx_array, x_stepsize