.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/processes/plot_07_rdw_dispersive_kerr.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_processes_plot_07_rdw_dispersive_kerr.py: The vacuum-ultraviolet dispersive wave under a frequency-dependent Kerr response ================================================================================ The :doc:`dispersive-wave example ` runs the canonical helium case -- a 7.5 fs, 275 uJ pulse at 800 nm in 1.5 m of 125 um-radius capillary, helium falling from 0.8 bar to vacuum, four ``HE_1m`` modes, plasma on -- with the default electronic response, which freezes helium's Kerr coefficient at the 800 nm carrier and uses it for every quartet the cubic couples. This example repeats that run, unchanged but for the electronic policy, under the two frequency-dependent responses of :doc:`/guide/media/dispersive-kerr`: - ``"gas-polynomial"``, optmat's whole fit of helium's hyperpolarisability evaluated at the four frequencies of every quartet; - ``"symmetric-kerr"``, its cheaper symmetric factorisation, exact for self-phase modulation. The cubic source mixes spectral components of the self-compressing pulse through frequency quartets, so the coefficients that matter belong to quartets with one or more legs between 100 and 150 nm. That is beyond helium's data: optmat's fit holds every leg down to its **leg bound**, 151.9 nm, and beyond it the dispersive responses hold the leg there (the **bounded** region, a held-coefficient approximation rather than a certified bound on the observable); below helium's two-photon resonance at a 120.3 nm fundamental, the **band edge**, no off-resonant model is valid at all, and the same held value is labelled **best effort**. So this comparison is a **sensitivity study** -- how much the dispersive wave depends on the coefficients of its vacuum-ultraviolet legs, held at the 800 nm value by the carrier policy and at the leg bound's by the dispersive ones -- **not a qualified prediction**. A resonant helium response, such as the TDSE coupling of :doc:`/guide/media/tdse`, can explore resonant effects, but carries its own atomic-model, finite-window and calibration limitations; it is not an automatically qualified reference. The second half measures how that sensitivity depends on the mode set, with one, two and four modes, and the last cell separates what the plasma does. **What to look for.** The soliton's own self-phase modulation at 800 nm has the same coefficient under all three policies, and the dispersive wave's centre moves by only 2-3 nm, as its phase matching to the soliton predicts. Its energy does not: at the exit the 100-150 nm band carries about 30 % more under the dispersive responses than under the carrier one with two or four modes, and about 53 % more with one. The two dispersive evaluators agree to a fraction of a per cent. The pump's peak power, which oscillates along the second half of the fibre in step under every policy, is a few per cent lower under the dispersive responses; with plasma on, the lower peak ionises less, and about 9 % more energy leaves the fibre. **What is approximate.** Everything the :doc:`dispersive-wave example ` approximates, and the electronic response of the vacuum-ultraviolet legs, which is the point. A separate refinement study of these runs found that a hundred times tighter step tolerance leaves every band energy and centre unchanged to four digits, and a wider grid (70 nm to 6 um over 600 fs) moves the band energies by less than 1 % and the centres by less than 0.1 nm, so the differences reported here are the models', not the integrator's or the grid's. This page reruns the comparisons at one resolution. Numerical agreement cannot qualify the unknown ultraviolet electronic response. Start with :doc:`/introduction/lessons/plot_01_rdw` for the workflow. Interpret the comparisons alongside :doc:`/guide/media/dispersive-kerr` and the separate physical and numerical checks in :doc:`/guide/numerics/accuracy`. .. GENERATED FROM PYTHON SOURCE LINES 68-72 The runs -------- The run of the dispersive-wave example, with the electronic policy and the mode count as the only arguments. Every run takes the default backend. .. GENERATED FROM PYTHON SOURCE LINES 72-140 .. code-block:: Python import math import time import matplotlib.pyplot as plt import numpy as np from solprop.constants import C from solprop.driver import prop_capillary from solprop.physdata import MaterialSelection from solprop.processing import ( bandpass, energy, get_power, get_spectral_density, grid_of, ) from solprop.processing.time import moment POLICIES = ("carrier-kerr", "symmetric-kerr", "gas-polynomial") COLOURS = {policy: f"C{index}" for index, policy in enumerate(POLICIES)} VUV = (100e-9, 150e-9) """The band the dispersive wave is counted in, m.""" started = time.perf_counter() def m2_run(policy, modes=4, plasma=None): """Propagate the helium dispersive-wave case under one electronic policy.""" return prop_capillary( 125e-6, # core radius, m 1.5, # length, m "He", (0.8, 0.0), # bar, entrance to exit lambda0=800e-9, fwhm=7.5e-15, energy=275e-6, modes=modes, trange=400e-15, wavelength_limits=(90e-9, 4e-6), plasma=plasma, n_save=151, materials=MaterialSelection(electronic=policy), progress="none", ) def band_along(run): """Return the dispersive wave's energy at every saved plane, J.""" window = bandpass(grid_of(run), VUV) planes = np.asarray(run["z"]).size return np.array( [float(np.sum(energy(run, plane=i, bandpass=window))) for i in range(planes)] ) def centre_wavelength(run): """Return the energy-weighted centre of the band at the exit, m.""" band = (2 * math.pi * C / VUV[1], 2 * math.pi * C / VUV[0]) frequency, density = get_spectral_density( run, "omega", plane=-1, modes="sum", spec_range=band ) return 2 * math.pi * C / moment(frequency, density) runs = {policy: m2_run(policy) for policy in POLICIES} z = np.asarray(runs["carrier-kerr"]["z"]) .. GENERATED FROM PYTHON SOURCE LINES 141-147 The regions ----------- A dispersive run records, for each gas, where its active band falls: supported (every leg within helium's data), bounded (beyond the leg bound, inside the band edge) and best effort (beyond the band edge). Here the band runs to 82 nm, so all three occur, and the dispersive wave's band straddles the last two. .. GENERATED FROM PYTHON SOURCE LINES 147-154 .. code-block:: Python (entry,) = runs["gas-polynomial"].metadata.materials.electronic regions = entry["regions"] for name in ("supported", "bounded", "best_effort"): low, high = regions[name] print(f"{name:12s} {low * 1e9:6.1f} - {high * 1e9:7.1f} nm") .. rst-class:: sphx-glr-script-out .. code-block:: none supported 151.9 - 8000.0 nm bounded 120.3 - 151.9 nm best_effort 81.8 - 120.3 nm .. GENERATED FROM PYTHON SOURCE LINES 155-160 The dispersive wave and the pump -------------------------------- The energy of the 100-150 nm band along the fibre, the peak power of the pump, and the exit spectrum below 400 nm with the bounded (light) and best-effort (dark) bands shaded; four modes, summed. .. GENERATED FROM PYTHON SOURCE LINES 160-213 .. code-block:: Python fig, (left, middle, right) = plt.subplots( 1, 3, figsize=(13.0, 3.8), layout="constrained" ) summary = {} for policy, run in runs.items(): along = band_along(run) _, power = get_power(run, modes="sum", oversampling=4) peak = power.max(axis=1) summary[policy] = ( along[-1], centre_wavelength(run), peak.max(), float(np.sum(energy(run, plane=-1))), ) left.plot(z, 1e6 * along, lw=1.6, color=COLOURS[policy], label=policy) middle.plot(z, 1e-9 * peak, lw=1.4, color=COLOURS[policy], label=policy) wavelength, density = get_spectral_density( run, "wavelength", plane=-1, modes="sum", spec_range=(85e-9, 400e-9) ) right.semilogy( 1e9 * wavelength, density / density.max(), lw=1.0, color=COLOURS[policy], label=policy, ) for name, shade in (("bounded", "0.88"), ("best_effort", "0.72")): low, high = regions[name] right.axvspan( 1e9 * low, 1e9 * high, color=shade, lw=0, zorder=0, label=name.replace("_", " ") ) left.set_xlabel("z (m)") left.set_ylabel("100-150 nm energy (uJ)") left.legend(frameon=False) middle.set_xlabel("z (m)") middle.set_ylabel("peak power (GW)") middle.set_xlim(0.9, 1.5) right.set_xlim(85, 400) right.set_ylim(1e-5, 2.0) right.set_xlabel("wavelength (nm)") right.set_ylabel("exit spectrum (normalised)") right.legend(frameon=False, fontsize="small", ncols=2) reference = summary["gas-polynomial"] for policy, (band, centre, peak, total) in summary.items(): print( f"{policy:15s} 100-150 nm {1e6 * band:6.2f} uJ " f"({100 * (band / reference[0] - 1):+5.1f} % of the polynomial's), " f"centre {1e9 * centre:6.2f} nm; largest peak power {1e-9 * peak:4.0f} GW; " f"{1e6 * total:.1f} uJ at the exit" ) .. image-sg:: /auto_examples/processes/images/sphx_glr_plot_07_rdw_dispersive_kerr_001.png :alt: plot 07 rdw dispersive kerr :srcset: /auto_examples/processes/images/sphx_glr_plot_07_rdw_dispersive_kerr_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none carrier-kerr 100-150 nm 10.49 uJ (-23.2 % of the polynomial's), centre 134.51 nm; largest peak power 106 GW; 142.1 uJ at the exit symmetric-kerr 100-150 nm 13.68 uJ ( +0.1 % of the polynomial's), centre 132.14 nm; largest peak power 102 GW; 155.3 uJ at the exit gas-polynomial 100-150 nm 13.66 uJ ( +0.0 % of the polynomial's), centre 132.19 nm; largest peak power 102 GW; 155.0 uJ at the exit .. GENERATED FROM PYTHON SOURCE LINES 214-227 The pump's peak power oscillates along the second half of the fibre with a period of about 7 cm, in step under every policy, and is a few per cent lower under the dispersive responses. The dispersive wave's centre is set by phase matching to the soliton's nonlinear wavenumber, which comes from self-phase modulation at the carrier, identical under every policy; it moves by 2-3 nm. Its energy grows by about 30 %: every quartet that makes a vacuum-ultraviolet photon has its VUV leg held at helium's leg bound, 151.9 nm, by the dispersive responses, and the whole quartet at the 800 nm Kerr value by the carrier one. The symmetric factorisation, whose error grows with the spread of a quartet's four frequencies, is within a fraction of a per cent of the polynomial even here. The whole exit spectrum, on a logarithmic wavelength axis: away from the vacuum ultraviolet the three are hard to tell apart. .. GENERATED FROM PYTHON SOURCE LINES 227-247 .. code-block:: Python fig, ax = plt.subplots(figsize=(8.0, 3.4), layout="constrained") for policy, run in runs.items(): wavelength, density = get_spectral_density( run, "wavelength", plane=-1, modes="sum", spec_range=(85e-9, 1.3e-6) ) ax.semilogy( 1e9 * wavelength, density / density.max(), lw=1.0, color=COLOURS[policy], label=policy, ) ax.set_xscale("log") ax.set_xticks([100, 200, 400, 800], labels=["100", "200", "400", "800"]) ax.set_ylim(1e-6, 2.0) ax.set_xlabel("wavelength (nm)") ax.set_ylabel("exit spectrum (normalised)") _ = ax.legend(frameon=False) .. image-sg:: /auto_examples/processes/images/sphx_glr_plot_07_rdw_dispersive_kerr_002.png :alt: plot 07 rdw dispersive kerr :srcset: /auto_examples/processes/images/sphx_glr_plot_07_rdw_dispersive_kerr_002.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 248-253 The sensitivity by mode count ----------------------------- The same three policies with one and two modes. The mode set changes the soliton's dynamics, and with them how much the exit band depends on the vacuum-ultraviolet coefficients. .. GENERATED FROM PYTHON SOURCE LINES 253-285 .. code-block:: Python by_modes = {4: {policy: summary[policy][:2] for policy in POLICIES}} del runs # the four-mode fields are no longer needed for modes in (2, 1): by_modes[modes] = {} for policy in POLICIES: run = m2_run(policy, modes=modes) by_modes[modes][policy] = (band_along(run)[-1], centre_wavelength(run)) print("modes carrier symmetric polynomial (uJ) carrier vs polynomial") for modes in (1, 2, 4): bands = [1e6 * by_modes[modes][policy][0] for policy in POLICIES] change = 100 * (bands[0] / bands[2] - 1) print( f"{modes:5d} {bands[0]:7.2f} {bands[1]:9.2f} {bands[2]:10.2f} " f"{change:+6.1f} %" ) fig, ax = plt.subplots(figsize=(5.0, 3.4), layout="constrained") counts = (1, 2, 4) for offset, policy in zip((-0.25, 0.0, 0.25), POLICIES, strict=True): ax.bar( np.arange(3) + offset, [1e6 * by_modes[m][policy][0] for m in counts], width=0.25, color=COLOURS[policy], label=policy, ) ax.set_xticks(np.arange(3), labels=[f"{m} mode{'s' * (m > 1)}" for m in counts]) ax.set_ylabel("100-150 nm energy at the exit (uJ)") _ = ax.legend(frameon=False, fontsize="small") .. image-sg:: /auto_examples/processes/images/sphx_glr_plot_07_rdw_dispersive_kerr_003.png :alt: plot 07 rdw dispersive kerr :srcset: /auto_examples/processes/images/sphx_glr_plot_07_rdw_dispersive_kerr_003.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none modes carrier symmetric polynomial (uJ) carrier vs polynomial 1 6.58 10.10 10.06 -34.6 % 2 10.98 14.26 14.24 -22.9 % 4 10.49 13.68 13.66 -23.2 % .. GENERATED FROM PYTHON SOURCE LINES 286-296 With two and four modes the dispersive responses give the band about 30 % more energy than the carrier policy; with one, about 55 % more. The two-mode reduced case of the :doc:`tutorial ` (one metre, 1.2 bar, a narrower grid) differs by about 9 %. The sensitivity is a property of the case and its mode set, not one number: report it with them. Where the plasma comes in ------------------------- With plasma on, the dispersive runs' lower peak power went with less energy lost (above). The same two policies without plasma, four modes: .. GENERATED FROM PYTHON SOURCE LINES 296-307 .. code-block:: Python for policy in ("carrier-kerr", "gas-polynomial"): run = m2_run(policy, plasma=False) _, power = get_power(run, modes="sum", oversampling=4) peak = power.max(axis=1) print( f"{policy:15s} no plasma: largest peak power {1e-9 * peak.max():4.0f} GW; " f"100-150 nm {1e6 * band_along(run)[-1]:.2f} uJ; " f"{1e6 * float(np.sum(energy(run, plane=-1))):.1f} uJ at the exit" ) .. rst-class:: sphx-glr-script-out .. code-block:: none carrier-kerr no plasma: largest peak power 128 GW; 100-150 nm 12.29 uJ; 220.3 uJ at the exit gas-polynomial no plasma: largest peak power 118 GW; 100-150 nm 14.75 uJ; 220.3 uJ at the exit .. GENERATED FROM PYTHON SOURCE LINES 308-315 Without plasma the dispersive response's peak power is lower again, by 8 %, its dispersive wave a fifth stronger, and the energy leaving the fibre the same. So the lower peak is the electronic response's own; with plasma on, it ionises less, and the pump keeps about 13 uJ more to the exit. Runtime and reproducibility ---------------------------- .. GENERATED FROM PYTHON SOURCE LINES 315-317 .. code-block:: Python print(f"{time.perf_counter() - started:.0f} s; backend {run.metadata.backend.name}") .. rst-class:: sphx-glr-script-out .. code-block:: none 53 s; backend native .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 52.868 seconds) .. _sphx_glr_download_auto_examples_processes_plot_07_rdw_dispersive_kerr.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_07_rdw_dispersive_kerr.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_07_rdw_dispersive_kerr.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_07_rdw_dispersive_kerr.zip `