Ejemplo n.º 1
0
                    prefix = "{}_{}_amp={}_per={}__".format(
                        state.n, state.l, amp, period)
                    t_init = 0
                    t_final = 20 * period * asec

                    window = ion.potentials.LinearRampTimeWindow(
                        ramp_on_time=t_init + period * asec,
                        ramp_time=5 * period * asec)
                    e_field = ion.SineWave(
                        omega=twopi / (period * asec),
                        amplitude=amp * atomic_electric_field,
                        window=window,
                    )
                    internal_potential = ion.Coulomb()
                    mask = ion.RadialCosineMask(
                        inner_radius=(bound - 50) * bohr_radius,
                        outer_radius=bound * bohr_radius,
                    )

                    # animators = [ion.animators.CylindricalSliceAnimator(target_dir = OUT_DIR),
                    #              ion.animators.CylindricalSliceAnimator(postfix = 'log', target_dir = OUT_DIR, log = True, renormalize = False),
                    #              ion.animators.CylindricalSliceAnimator(postfix = '30', target_dir = OUT_DIR, plot_limit = 30 * bohr_radius),
                    #              ion.animators.CylindricalSliceAnimator(postfix = '100', target_dir = OUT_DIR, plot_limit = 100 * bohr_radius)]
                    # spec = ion.mesh.CylindricalSliceSpecification(prefix + 'cyl_slice', time_initial = t_init, time_final = t_final, time_step = dt,
                    #                                          z_bound = bound * bohr_radius, z_points = bound * 10,
                    #                                          rho_bound = bound * bohr_radius, rho_points = bound * 5,
                    #                                          initial_state = state,
                    #                                          internal_potential = internal_potential,
                    #                                          electric_potential = e_field,
                    #                                          animators = animators
                    #                                          )
                    # specs.append(spec)
Ejemplo n.º 2
0
        #                       window = window)

        spec_kwargs = dict(
            r_bound=bound * bohr_radius,
            r_points=bound * points_per_bohr_radius,
            l_bound=20,
            initial_state=ion.HydrogenBoundState(1, 0),
            time_initial=-t_bound * asec,
            time_final=(t_bound + t_extra) * asec,
            time_step=1 * asec,
            use_numeric_eigenstates=True,
            numeric_eigenstate_max_energy=50 * eV,
            numeric_eigenstate_max_angular_momentum=5,
            electric_potential=efield,
            electric_potential_dc_correction=True,
            mask=ion.RadialCosineMask(inner_radius=0.8 * bound * bohr_radius,
                                      outer_radius=bound * bohr_radius),
            store_data_every=-1,
        )

        sim = ion.SphericalHarmonicSpecification(
            f"PWTest_amp={amp}aef_phase={phase / pi:3f}pi__tB={t_bound}pw__tE={t_extra}asec",
            **spec_kwargs,
        ).to_sim()

        sim.run()
        print(sim.info())

        # sim.mesh.plot_g(target_dir = OUT_DIR)
        # sim.mesh.plot_g(target_dir = OUT_DIR, name_postfix = '_25', plot_limit = 25 * bohr_radius)
        #
        # plot_kwargs = dict(
Ejemplo n.º 3
0
        sim = ion.LineSpecification(
            "fsw",
            x_bound=space_bound,
            x_points=2**14,
            internal_potential=pot,
            electric_potential=electric,
            test_mass=mass,
            test_states=test_states,
            dipole_gauges=(),
            initial_state=init,
            # time_initial = 0, time_final = 1000 * asec, time_step = 1 * asec,
            time_initial=-pw * time_bound * asec,
            time_final=pw * time_bound * asec,
            time_step=1 * asec,
            minimum_time_final=3 * pw * time_bound * asec,
            mask=ion.RadialCosineMask(inner_radius=space_bound * 0.8,
                                      outer_radius=space_bound),
            animators=ani,
            evolution_method="SO",
        ).to_sim()

        print(sim.info())

        si.vis.xy_plot(
            "fsw_potential",
            sim.mesh.x_mesh,
            pot(distance=sim.mesh.x_mesh),
            x_unit="bohr_radius",
            y_unit="eV",
            x_lower_limit=-3 * width,
            x_upper_limit=3 * width,
            target_dir=OUT_DIR,
Ejemplo n.º 4
0
        cosine_pulse = ion.potentials.GaussianPulse(
            pulse_width=pw, fluence=flu, phase=0, window=window
        )
        sine_pulse = ion.potentials.GaussianPulse(
            pulse_width=pw, fluence=flu, phase=pi / 2, window=window
        )

        shared_kwargs = dict(
            r_bound=r_bound * bohr_radius,
            r_points=r_bound * 4,
            l_bound=100,
            time_initial=-time_bound * pw,
            time_final=time_bound * pw,
            time_step=1 * asec,
            mask=ion.RadialCosineMask(
                inner_radius=(r_bound * 0.8) * bohr_radius,
                outer_radius=r_bound * bohr_radius,
            ),
            use_numeric_eigenstates=True,
            numeric_eigenstate_max_energy=10 * eV,
            numeric_eigenstate_max_angular_momentum=10,
            electric_potential_dc_correction=True,
            store_data_every=20,
        )

        specs = [
            ion.SphericalHarmonicSpecification(
                "cosine", electric_potential=cosine_pulse, **shared_kwargs
            ),
            ion.SphericalHarmonicSpecification(
                "sine", electric_potential=sine_pulse, **shared_kwargs
            ),
            time_final=12 * pulse_width,
        )

        ide_shared_kwargs = dict(evolution_method="RK4", time_step=1 * asec)

        msh_spec = ion.LineSpecification(
            "msh",
            time_step=1 * asec,
            x_bound=200 * bohr_radius,
            x_points=2**10,
            internal_potential=gaussian_well,
            initial_state=variational_ground_state,
            use_numeric_eigenstates=True,
            numeric_eigenstate_max_energy=20 * eV,
            analytic_eigenstate_type=ion.GaussianWellState,
            mask=ion.RadialCosineMask(inner_radius=175 * bohr_radius,
                                      outer_radius=200 * bohr_radius),
            animators=[
                animation.animators.RectangleSplitLowerAnimator(
                    postfix="__g2",
                    axman_wavefunction=animation.animators.LineMeshAxis(),
                    axman_lower_left=animation.animators.
                    ElectricPotentialPlotAxis(show_vector_potential=False),
                    axman_lower_right=animation.animators.
                    WavefunctionStackplotAxis(
                        states=[variational_ground_state]),
                    fig_dpi_scale=1,
                    target_dir=OUT_DIR,
                )
            ],
            **shared_kwargs,
        )
                fluence=flu,
                phase=cep,
                number_of_cycles=n_cycles,
                number_of_pulse_widths=3,
                window=ion.potentials.LogisticWindow(
                    window_time=pulse_time_bound * pw, window_width=0.2 * pw),
            )

            specs.append(
                ion.SphericalHarmonicSpecification(
                    f"{pulse_type.__name__}__Nc={n_cycles}_pw={pw / asec:3f}as_flu={flu / Jcm2:3f}jcm2_cep={cep / pi:3f}pi__R={r_bound / bohr_radius:3f}br_ppbr={r_points_per_br}_L={l_bound}_dt={dt / asec:3f}as",
                    r_bound=r_bound,
                    r_points=r_points_per_br * r_bound / bohr_radius,
                    l_bound=l_bound,
                    time_step=dt,
                    time_initial=-sim_time_bound * pw,
                    time_final=(sim_time_bound + extra_end_time) * pw,
                    mask=ion.RadialCosineMask(0.8 * r_bound, r_bound),
                    electric_potential=pulse,
                    electric_potential_dc_correction=True,
                    use_numeric_eigenstates=True,
                    numeric_eigenstate_max_energy=20 * eV,
                    numeric_eigenstate_max_angular_momentum=20,
                    checkpoints=True,
                    checkpoint_dir=SIM_LIB,
                    checkpoint_every=datetime.timedelta(minutes=1),
                    store_radial_probability_current=True,
                ))

        si.utils.multi_map(run_spec, specs, processes=4)
Ejemplo n.º 7
0
        t_init = 0
        t_final = 1000
        dt = 1

        initial_state = ion.HydrogenBoundState(
            1, 0, 0) + ion.HydrogenBoundState(2, 1, 0)

        window = ion.potentials.LinearRampTimeWindow(ramp_on_time=t_init *
                                                     asec,
                                                     ramp_time=200 * asec)
        e_field = ion.SineWave.from_frequency(1 / (50 * asec),
                                              amplitude=1 *
                                              atomic_electric_field,
                                              window=window)
        mask = ion.RadialCosineMask(inner_radius=(bound - 25) * bohr_radius,
                                    outer_radius=bound * bohr_radius)

        animators = [
            src.ionization.animators.CylindricalSliceAnimator(
                postfix="_nm", target_dir=OUT_DIR, distance_unit="nm"),
            src.ionization.animators.CylindricalSliceAnimator(
                postfix="_br", target_dir=OUT_DIR,
                distance_unit="bohr_radius"),
        ]
        specs.append(
            ion.mesh.CylindricalSliceSpecification(
                "cyl_slice",
                time_initial=t_init * asec,
                time_final=t_final * asec,
                time_step=dt * asec,
                z_bound=20 * bohr_radius,
Ejemplo n.º 8
0
def compare_quasistatic_to_tdse(intensity, photon_energy):
    dummy = ion.SineWave.from_photon_energy(0.5 * eV)

    time_initial = 0
    time_final = 8 * dummy.period_carrier

    time_front = 1 * dummy.period_carrier
    time_plateau = 5 * dummy.period_carrier

    efield = ion.SineWave.from_photon_energy_and_intensity(
        photon_energy, intensity)
    efield.window = ion.potentials.SmoothedTrapezoidalWindow(
        time_front=time_front, time_plateau=time_plateau)

    r_bound = 100
    r_points = 4 * r_bound
    l_bound = 400
    dt = 4
    store = 5

    h = hash((
        intensity,
        photon_energy,
        time_initial,
        time_final,
        time_front,
        time_plateau,
        r_bound,
        r_points,
        l_bound,
        dt,
        store,
    ))

    title = f"P={intensity / atomic_intensity:5f}_E={photon_energy / eV:1f}_R={r_bound}_Rp={r_points}_L={l_bound}_dt={dt}_sde={store}"

    spec = ion.SphericalHarmonicSpecification(
        f"tdse_{h}",
        r_bound=r_bound * bohr_radius,
        r_points=r_points,
        l_bound=l_bound,
        internal_potential=ion.SoftCoulomb(softening_distance=0.05 *
                                           bohr_radius),
        time_initial=time_initial,
        time_final=time_final,
        time_step=dt * asec,
        electric_potential=efield,
        use_numeric_eigenstates=True,
        numeric_eigenstate_max_energy=20 * eV,
        numeric_eigenstate_max_angular_momentum=5,
        store_data_every=store,
        checkpoints=True,
        checkpoint_dir=SIM_LIB,
        checkpoint_every=50,
        mask=ion.RadialCosineMask(0.9 * r_bound * bohr_radius,
                                  r_bound * bohr_radius),
    )

    sim = si.utils.find_or_init_sim(spec, search_dir=SIM_LIB)

    sim.info().log()
    if not sim.status == si.Status.FINISHED:
        sim.run_simulation(progress_bar=True)
        sim.info().log()

    sim.save(target_dir=SIM_LIB)

    sim.plot_wavefunction_vs_time(**PLOT_KWARGS)

    times = np.linspace(time_initial, time_final, 1e3)

    si.vis.xy_plot(
        title + "__efield_vs_time",
        times,
        efield.get_electric_field_amplitude(times),
        x_label=r"Time $t$",
        x_unit="asec",
        y_label=fr"$ {ion.vis.LATEX_EFIELD}(t) $)",
        y_unit="atomic_electric_field",
        **PLOT_KWARGS,
    )

    tunneling_rate_vs_time = instantaneous_tunneling_rate(
        efield.get_electric_field_amplitude(times),
        sim.spec.initial_state.energy)

    si.vis.xy_plot(
        title + "__tunneling_rate_vs_time",
        times,
        tunneling_rate_vs_time * asec,
        x_label=r"Time $t$",
        x_unit="asec",
        y_label=r"Tunneling Rate ($\mathrm{as}^{-1}$)",
        **PLOT_KWARGS,
    )

    wavefunction_remaining = np.empty_like(times)
    wavefunction_remaining[0] = 1
    for ii, tunneling_rate in enumerate(tunneling_rate_vs_time[:-1]):
        wavefunction_remaining[ii + 1] = wavefunction_remaining[ii] * (
            1 - (tunneling_rate * np.abs(times[ii + 1] - times[ii])))

    cycle_avg_rate = averaged_tunneling_rate(efield.amplitude)
    cycle_avg_norm_remaining_plat = np.exp(-cycle_avg_rate * time_plateau)
    cycle_avg_norm_remaining_all = np.exp(-cycle_avg_rate * (time_plateau +
                                                             (2 * time_front)))

    for log in (True, False):
        si.vis.xxyy_plot(
            title + f"__comparison__log={log}",
            (sim.data_times, sim.data_times, sim.data_times, times),
            (
                sim.norm_vs_time,
                sim.total_bound_state_overlap_vs_time,
                sim.state_overlaps_vs_time[sim.spec.initial_state],
                wavefunction_remaining,
            ),
            line_labels=(
                "TDSE Norm",
                "TDSE Bound States",
                "TDSE Initial State",
                "Tunneling",
            ),
            x_label=r"Time $t$",
            x_unit="fsec",
            y_label="Remaining Wavefunction",
            y_log_axis=log,
            hlines=[
                cycle_avg_norm_remaining_plat, cycle_avg_norm_remaining_all
            ],
            hline_kwargs=[{
                "linestyle": "--"
            }, {
                "linestyle": ":"
            }],
            **PLOT_KWARGS,
        )
if __name__ == "__main__":
    with si.utils.LogManager(
            "simulacra",
            "ionization",
            stdout_level=logging.INFO,
            file_logs=False,
            file_dir=OUT_DIR,
            file_level=logging.DEBUG,
    ) as logger:
        source = ion.potentials.SincPulse(pulse_width=200 * asec,
                                          fluence=1 * (J / (cm**2)))
        pulse_widths = [290, 310, 390, 410]
        # pulse_widths = [50, 100, 200, 400, 600, 800]
        t_step = 2 * asec

        mask = ion.RadialCosineMask(inner_radius=100 * bohr_radius,
                                    outer_radius=150 * bohr_radius)

        specs = []
        for phase in ("cos", "sin"):
            for pw in pulse_widths:
                sinc = ion.potentials.SincPulse.from_amplitude_density(
                    pulse_width=pw * asec,
                    amplitude_density=source.amplitude_omega,
                    phase=phase,
                )

                specs.append(
                    ion.SphericalHarmonicSpecification(
                        "pw={}asec_phase={}".format(pw, phase),
                        r_bound=150 * bohr_radius,
                        r_points=600,
def make_plot(args):
    pulse_type, pw, flu, cep = args

    t_bound = T_BOUND_MAP[pulse_type]
    p_bound = P_BOUND_MAP[pulse_type]

    times = np.linspace(-t_bound * pw, t_bound * pw, 1e4)

    window = ion.potentials.LogisticWindow(
        window_time=p_bound * pw, window_width=0.2 * pw
    )
    pulse = pulse_type(pulse_width=pw, fluence=flu, phase=cep, window=window)
    corrected_pulse = ion.DC_correct_electric_potential(pulse, times)

    efield = corrected_pulse.get_electric_field_amplitude(times)
    afield = corrected_pulse.get_vector_potential_amplitude_numeric_cumulative(times)

    starts = range(0, len(times), 50)[50:-50]

    sliced_times = list(times[start:] for start in starts)
    sliced_alphas = list(
        (proton_charge / electron_mass)
        * integ.cumtrapz(
            y=integ.cumtrapz(y=efield[start:], x=times[start:], initial=0),
            x=times[start:],
            initial=0,
        )
        for start in starts
    )

    identifier = f"{pulse_type.__name__}__pw={pw / asec:0f}as_flu={flu / Jcm2:2f}jcm2_cep={cep / pi:2f}pi"

    spec = ion.SphericalHarmonicSpecification(
        identifier,
        r_bound=250 * bohr_radius,
        r_points=250 * 4,
        l_bound=500,
        time_initial=times[0],
        time_final=times[-1],
        use_numeric_eigenstates=True,
        numeric_eigenstate_max_energy=10 * eV,
        numeric_eigenstate_max_angular_momentum=5,
        electric_potential=pulse,
        electric_potential_dc_correction=True,
        mask=ion.RadialCosineMask(
            inner_radius=225 * bohr_radius, outer_radius=250 * bohr_radius
        ),
        checkpoints=True,
        checkpoint_every=50,
        checkpoint_dir=SIM_LIB,
    )

    sim = si.utils.find_or_init_sim(spec, search_dir=SIM_LIB)
    if sim.status != si.Status.FINISHED:
        sim.run_simulation()
        sim.save(target_dir=SIM_LIB)

    si.vis.xxyy_plot(
        identifier,
        [times, times, sim.times, *sliced_times],
        [
            efield / atomic_electric_field,
            afield * (proton_charge / atomic_momentum),
            sim.radial_position_expectation_value_vs_time / bohr_radius,
            *(alpha / bohr_radius for alpha in sliced_alphas),
        ],
        line_labels=[
            rf"$ {ion.vis.LATEX_EFIELD}(t) $",
            rf"$ e \, {ion.LATEX_AFIELD}(t) $",
            rf"$ \left\langle r(t) \right\rangle $",
            rf"$ \alpha(t) $",
        ],
        line_kwargs=[
            None,
            None,
            None,
            *({"color": "black", "alpha": 0.5} for _ in starts),
        ],
        x_label=r"Time $t$",
        x_unit="asec",
        # y_label = r'Field Amplitude (a.u.) / Distance ($a_0$)',
        title=rf"$ \tau = {pw / asec:0f} \, \mathrm{{as}}, \; H = {flu / Jcm2:2f} \, \mathrm{{J/cm^2}}, \; \varphi = {cep / pi:2f}\pi $",
        **PLOT_KWARGS,
    )
        spec_kwargs = dict(
            r_bound=r_bound * bohr_radius,
            r_points=r_bound * points_per_bohr_radius,
            l_bound=20,
            initial_state=ion.HydrogenBoundState(1, 0),
            time_initial=-t_bound * asec,
            time_final=(t_bound + t_extra) * asec,
            time_step=1 * asec,
            use_numeric_eigenstates=True,
            numeric_eigenstate_max_energy=10 * eV,
            numeric_eigenstate_max_angular_momentum=10,
            electric_potential=efield,
            electric_potential_dc_correction=True,
            mask=ion.RadialCosineMask(
                inner_radius=0.9 * r_bound * bohr_radius,
                outer_radius=r_bound * bohr_radius,
            ),
            store_data_every=10,
            snapshot_type=ion.SphericalHarmonicSnapshot,
            snapshot_times=[(t_bound + (n * 100)) * asec for n in range(100)],
            snapshot_kwargs=dict(
                plane_wave_overlap__max_wavenumber=60 * per_nm,
                plane_wave_overlap__wavenumber_points=200,
                plane_wave_overlap__theta_points=100,
            ),
        )

        sim = ion.SphericalHarmonicSpecification(
            f"R={r_bound}_amp={amp}_phase={phase / pi:3f}pi_tB={t_bound}_tE={t_extra}",
            **spec_kwargs,
        ).to_sim()
Ejemplo n.º 12
0
FILE_NAME = os.path.splitext(os.path.basename(__file__))[0]
OUT_DIR = os.path.join(os.getcwd(), "out", FILE_NAME)

PLOT_KWARGS = dict(target_dir=OUT_DIR, img_format="png", fig_dpi_scale=6)

if __name__ == "__main__":
    with si.utils.LogManager(
        "simulacra",
        "ionization",
        stdout_logs=True,
        stdout_level=logging.DEBUG,
        file_dir=OUT_DIR,
        file_logs=False,
    ) as logger:
        x = np.linspace(4.99, 5.01, 1e6)
        mask = ion.RadialCosineMask(inner_radius=2, outer_radius=5, smoothness=8)
        si.vis.xy_plot("mask_test", x, mask(r=x), **PLOT_KWARGS)

        # electric = ion.potentials.Rectangle(start_time = 25 * asec, end_time = 100 * asec, amplitude = 1 * atomic_electric_field)

        # mask = ion.RadialCosineMask(inner_radius = 40 * bohr_radius, outer_radius = 49 * bohr_radius)
        # sim = ion.SphericalHarmonicSpecification('mask',
        #                                          time_final = 200 * asec,
        #                                          r_bound = 50 * bohr_radius, r_points = 50 * 8,
        #                                          l_bound = 100,
        #                                          electric_potential = electric,
        #                                          test_states = [ion.HydrogenBoundState(n, l) for n in range(6) for l in range(n)],
        #                                          mask = mask).to_sim()
        #
        # sim.run_simulation()
        # sim.info().log()