Skip to content

Commit

Permalink
Merge branch 'master' into compathelper/new_version/2022-04-09-00-17-…
Browse files Browse the repository at this point in the history
…28-701-01708008276
  • Loading branch information
chrisbrahms authored Sep 6, 2022
2 parents cf49a69 + 2cb6d59 commit a312db5
Show file tree
Hide file tree
Showing 29 changed files with 1,075 additions and 49 deletions.
20 changes: 20 additions & 0 deletions .github/workflows/TagBot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: TagBot
on:
issue_comment:
types:
- created
workflow_dispatch:
inputs:
lookback:
default: 3
permissions:
contents: write
jobs:
TagBot:
if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot'
runs-on: ubuntu-latest
steps:
- uses: JuliaRegistries/TagBot@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
ssh: ${{ secrets.DOCUMENTER_KEY }}
2 changes: 1 addition & 1 deletion .github/workflows/run_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
strategy:
fail-fast: false
matrix:
julia-version: ['1.7']
julia-version: ['1.7', '1.8']
julia-arch: [x64]
os: [ubuntu-latest, windows-latest, macos-latest]
if: github.event.pull_request.draft == false
Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "Luna"
uuid = "30eb0fb0-5147-11e9-3356-d75b018717ce"
authors = ["chrisbrahms <38351086+chrisbrahms@users.noreply.github.com>"]
version = "0.1.3"
version = "0.1.4"

[deps]
ArgParse = "c7e460c6-2fb9-53a9-8c5b-16f535851c63"
Expand Down
39 changes: 26 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
[![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://lupo-lab.com/Luna.jl)


Luna.jl is a flexible platform for the simulation of nonlinear optical dynamics—both in waveguides (such as optical fibres) and free-space geometries—using the unidirectional pulse propagation equation (UPPE). Some of the key features of Luna:
Luna.jl is a flexible platform for the simulation of nonlinear optical dynamics—both in waveguides (such as optical fibres) and free-space geometries—using the unidirectional pulse propagation equation (UPPE) and its approximate forms, such as the commonly used generalised nonlinear Schrödinger equation (GNLSE). Some of the key features of Luna:
- A variety of propagation geometries treated in a unified way:
- Single-mode (mode-averaged) propagation in waveguides
- Multi-mode propagation in waveguides with arbitrary (including non-symmetric) mode-shapes, full polarisation resolution, and intermodal coupling for arbitrary nonlinear polarisation terms
Expand All @@ -16,36 +16,31 @@ Luna.jl is a flexible platform for the simulation of nonlinear optical dynamics
- A range of linear and nonlinear optical effects:
- Modal dispersion and loss in waveguides
- Optical Kerr effect (third-order nonlinearity)
- Raman scattering in molecular gases
- Raman scattering in molecular gases or glasses
- Strong-field photoionisation and plasma dynamics
- A built-in interface for the running and processing of multi-dimensional [parameter scans](#running-parameter-scans) in serial or parallel
- A standard library of [plotting](#plotting-results) and [processing](#output-processing) functions, including calculation of spectrograms and beam properties

Luna is designed to be extensible: adding e.g. a new type of waveguide or a new nonlinear effect is straightforward, even without editing the main source code.

Luna was originally developed for modelling ultrafast pulse propagation in gas-filled hollow capillary fibres and hollow-core photonic crystal fibres. Therefore such simulations have particularly good support.
Luna was originally developed for modelling ultrafast pulse propagation in gas-filled hollow capillary fibres and hollow-core photonic crystal fibres. Therefore, such simulations have particularly good support. It is also excellent for modelling propagation in solid-core fibres.

Luna is written in the [Julia programming language](https://julialang.org/), chosen for its unique combination of readability, ease of use, and speed. If you want to use Luna but are new to Julia, see [the relevant section of this README](#new-to-julia).

There are two ways of using Luna:
1. A very simple high-level interface for the most heavily optimised application of Lunapropagation in gas-filled hollow capillary fibres and hollow-core photonic crystal fibresconsisting of the function [`prop_capillary`](#quickstart) and some helper functions to create input pulses.
1. A very simple high-level interface for the most heavily optimised applications of Luna: propagation in gas-filled hollow capillary fibres and hollow-core photonic crystal fibres (consisting of the function [`prop_capillary`](#quickstart) and some helper functions to create input pulses); or propagation of simple GNLSE simulations (consisting of the function [`prop_gnlse`](#gnlse)).
2. A low-level interface which allows for full control and customisation of the simulation parameters, the use of custom waveguide modes and gas fills (including gas mixtures), and free-space propagation simulations.

For a short introduction on how to use the simple interface, see the [Quickstart](#quickstart) section below. More information, including on the internals of Luna, can be found in the [Documentation](http://lupo-lab.com/Luna.jl).
For a short introduction on how to use the simple interface, see the [Quickstart](#quickstart) or [GNLSE](#gnlse) sections below. More information, including on the internals of Luna, can be found in the [Documentation](http://lupo-lab.com/Luna.jl).

## Installation
Luna requires Julia v1.7, which can be obtained from [here](https://julialang.org/downloads/). Once Julia is installed, open a new Julia terminal and install Luna:
Luna requires Julia v1.7 or later, which can be obtained from [here](https://julialang.org/downloads/). In a Julia terminal, to install Luna simply enter the package manager with `]` and run `add Luna`:

```julia
]
add https://github.com/LupoLab/Luna
```
or using `Pkg`

```julia
using Pkg
Pkg.add(PackageSpec(url="https://github.com/LupoLab/Luna", rev="master"))
add Luna
```
This will install and precompile Luna and all its dependencies.

## Quickstart
To run a simple simulation of ultrafast pulse propagation in a gas-filled hollow capillary fibre, you can use `prop_capillary`. As an example, take a 3-metre length of HCF with 125 μm core radius, filled with 1 bar of helium gas, and driving pulses centred at 800 nm wavelength with 120 μJ of energy and 10 fs duration. We consider a frequency grid which spans from 120 nm to 4 μm and a time window of 1 ps.
Expand Down Expand Up @@ -126,6 +121,24 @@ The `Processing` module contains many useful functions for more detailed process
- FWHM widths in frequency (`Processing.fwhm_f`) and time (`Processing.fwhm_t`) as well as time-bandwidth product (`Processing.time_bandwidth`)
- g₁₂ coherence between multiple fields (`Processing.coherence`)
## GNLSE propagation
To run a simple simulation of nonlinear pulse propagation in an optical fibre using the generalised nonlinear Schrödinger equation (GNLSE), you can use `prop_gnlse`. As an example, we can model supercontinuum generation in a solid-core photonic crystal fibre for parameters corresponding to the simulations in Fig. 3 of Dudley et. al, RMP 78 1135 (2006).
```julia
julia> using Luna
julia> γ = 0.11
julia> flength = 15e-2
julia> βs = [0.0, 0.0, -1.1830e-26, 8.1038e-41, -9.5205e-56, 2.0737e-70, -5.3943e-85, 1.3486e-99, -2.5495e-114, 3.0524e-129, -1.7140e-144]
julia> output = prop_gnlse(γ, flength, βs; λ0=835e-9, τfwhm=50e-15, power=10e3, pulseshape=:sech, λlims=(400e-9, 2400e-9), trange=12.5e-12)
```
After this has run, you can visualise the output, with e.g.
```julia
julia> Plotting.prop_2D(output, , dBmin=-40.0, λrange=(400e-9, 1300e-9), trange=(-1e-12, 5e-12))
PyPlot.Figure(PyObject <Figure size 2400x800 with 4 Axes>)
```
This should show a plot like this:
![GNLSE propagation example](assets/readme_gnlse_scg.png)
## Examples
The [examples folder](examples/) contains complete simulation examples for a variety of scenarios, both for the [simple interface](examples/simple_interface/) and the [low-level interface](examples/low_level_interface). Some of the simple interface examples require the `PyPlot` package to be present, and many of the low-level examples require other packages as well--you can install these by simply typing `] add PyPlot` at the Julia REPL or the equivalent for other packages.
Expand Down
Binary file added assets/readme_gnlse_scg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
40 changes: 40 additions & 0 deletions examples/low_level_interface/gnlse/simplescg_modeAvg.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# supercontinuum from simple GNLSE parameters
# Fig.3 of Dudley et. al, RMP 78 1135 (2006)

using Luna

βs = [0.0, 0.0, -1.1830e-26, 8.1038e-41, -9.5205e-56, 2.0737e-70, -5.3943e-85, 1.3486e-99, -2.5495e-114, 3.0524e-129, -1.7140e-144]
γ = 0.11
flength = 15e-2
fr = 0.18
τfwhm = 50e-15
λ0 = 835e-9
energy = 568e-12

grid = Grid.RealGrid(flength, λ0, (400e-9, 1400e-9), 10e-12)

m = SimpleFibre.SimpleMode(PhysData.wlfreq(λ0), βs)
aeff = z -> 1.0
densityfun = z -> 1.0

linop, βfun!, β1, αfun = LinearOps.make_const_linop(grid, m, λ0)

k0 = 2π/λ0
n2 = γ/k0*aeff(0.0)
χ3 = 4/3 * n2 * (PhysData.ε_0*PhysData.c)
responses = (Nonlinear.Kerr_field((1 - fr)*χ3),
Nonlinear.RamanPolarField(grid.to, Raman.raman_response(grid.to, :SiO2, fr*χ3*PhysData.ε_0)))

inputs = (Fields.SechField(λ0=λ0, τfwhm=τfwhm, energy=energy), Fields.ShotNoise())
norm! = NonlinearRHS.norm_mode_average_gnlse(grid, aeff)
Eω, transform, FT = Luna.setup(grid, densityfun, responses, inputs, βfun!, aeff, norm! = norm!)

output = Output.MemoryOutput(0, grid.zmax, 201)
Luna.run(Eω, grid, linop, transform, FT, output)

##
Plotting.pygui(true)
#Plotting.stats(output)
#Plotting.prop_2D(output, :λ, dBmin=-40.0, λrange=(400e-9, 1300e-9), trange=(-1e-12, 5e-12))
#Plotting.time_1D(output, range(0.0, 1.0, length=5).*flength, trange=(-1e-12, 5e-12))
Plotting.spec_1D(output, range(0.0, 1.0, length=5).*flength, λrange=(400e-9, 1300e-9))
40 changes: 40 additions & 0 deletions examples/low_level_interface/gnlse/simplescg_modeAvg_env.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# supercontinuum from simple GNLSE parameters
# Fig.3 of Dudley et. al, RMP 78 1135 (2006)

using Luna

βs = [0.0, 0.0, -1.1830e-26, 8.1038e-41, -9.5205e-56, 2.0737e-70, -5.3943e-85, 1.3486e-99, -2.5495e-114, 3.0524e-129, -1.7140e-144]
γ = 0.11
flength = 15e-2
fr = 0.18
τfwhm = 50e-15
λ0 = 835e-9
energy = 568e-12

grid = Grid.EnvGrid(flength, λ0, (400e-9, 1400e-9), 10e-12)

m = SimpleFibre.SimpleMode(PhysData.wlfreq(λ0), βs)
aeff = z -> 1.0
densityfun = z -> 1.0

linop, βfun!, β1, αfun = LinearOps.make_const_linop(grid, m, λ0)

k0 = 2π/λ0
n2 = γ/k0*aeff(0.0)
χ3 = 4/3 * n2 * (PhysData.ε_0*PhysData.c)
responses = (Nonlinear.Kerr_env((1 - fr)*χ3),
Nonlinear.RamanPolarEnv(grid.to, Raman.raman_response(grid.to, :SiO2, fr*χ3*PhysData.ε_0)))

inputs = (Fields.SechField(λ0=λ0, τfwhm=τfwhm, energy=energy), Fields.ShotNoise())
norm! = NonlinearRHS.norm_mode_average_gnlse(grid, aeff)
Eω, transform, FT = Luna.setup(grid, densityfun, responses, inputs, βfun!, aeff, norm! = norm!)

output = Output.MemoryOutput(0, grid.zmax, 201)
Luna.run(Eω, grid, linop, transform, FT, output)

##
Plotting.pygui(true)
#Plotting.stats(output)
Plotting.prop_2D(output, , dBmin=-40.0, λrange=(400e-9, 1300e-9), trange=(-1e-12, 5e-12))
#Plotting.time_1D(output, [0.0, 2.5, 5.0], trange=(-5e-12, 5e-12))
Plotting.spec_1D(output, range(0.0, 1.0, length=5).*flength, λrange=(400e-9, 1300e-9))
39 changes: 39 additions & 0 deletions examples/low_level_interface/stepindex/step_modeAvg_env.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# propagation in step index fibre

using Luna

# single mode fibre at 1030 nm
a = 5e-6
NA = 0.08
flength = 2.0
fr = 0.18
τfwhm = 1e-12
λ0 = 1030e-9
energy = 10e-9

grid = Grid.EnvGrid(flength, λ0, (980e-9, 1200e-9), 10e-12)

m = StepIndexFibre.StepIndexMode(a, NA, accellims=(900e-9, 1200e-9, 100))
aeff = let aeffc=Modes.Aeff(m, z=0.0)
z -> aeffc
end
densityfun = z -> 1.0

linop, βfun!, β1, αfun = LinearOps.make_const_linop(grid, m, λ0)

responses = (Nonlinear.Kerr_env((1 - fr)*PhysData.χ3(:SiO2)),
Nonlinear.RamanPolarEnv(grid.to, Raman.raman_response(grid.to, :SiO2, fr*PhysData.ε_0*PhysData.χ3(:SiO2))))

inputs = Fields.GaussField(λ0=λ0, τfwhm=τfwhm, energy=energy)
Eω, transform, FT = Luna.setup(grid, densityfun, responses, inputs, βfun!, aeff)

statsfun = Stats.default(grid, Eω, m, linop, transform)
output = Output.MemoryOutput(0, grid.zmax, 201, statsfun)
Luna.run(Eω, grid, linop, transform, FT, output)

##
Plotting.pygui(true)
#Plotting.stats(output)
Plotting.prop_2D(output, , dBmin=-40.0, λrange=(980e-9, 1200e-9), trange=(-2e-12, 2e-12))
#Plotting.time_1D(output, [0.0, 2.5, 5.0], trange=(-5e-12, 5e-12))
Plotting.spec_1D(output, [0.0, 2.5, 5.0], λrange=(980e-9, 1080e-9))
38 changes: 38 additions & 0 deletions examples/low_level_interface/stepindex/stepscg_modeAvg.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# supercontinuum in strand of silica in air

using Luna

# single mode fibre at 1030 nm
a = 1.25e-6
flength = 15e-2
fr = 0.18
τfwhm = 50e-15
λ0 = 835e-9
energy = 568e-12

grid = Grid.RealGrid(flength, λ0, (400e-9, 1400e-9), 10e-12)

m = StepIndexFibre.StepIndexMode(a, accellims=(400e-9, 1400e-9, 100))
aeff = let aeffc=Modes.Aeff(m, z=0.0)
z -> aeffc
end
densityfun = z -> 1.0

linop, βfun!, β1, αfun = LinearOps.make_const_linop(grid, m, λ0)

responses = (Nonlinear.Kerr_field((1 - fr)*PhysData.χ3(:SiO2)),
Nonlinear.RamanPolarField(grid.to, Raman.raman_response(grid.to, :SiO2, fr*PhysData.ε_0*PhysData.χ3(:SiO2))))

inputs = Fields.GaussField(λ0=λ0, τfwhm=τfwhm, energy=energy)
Eω, transform, FT = Luna.setup(grid, densityfun, responses, inputs, βfun!, aeff)

statsfun = Stats.default(grid, Eω, m, linop, transform)
output = Output.MemoryOutput(0, grid.zmax, 201, statsfun)
Luna.run(Eω, grid, linop, transform, FT, output)

##
Plotting.pygui(true)
#Plotting.stats(output)
#Plotting.prop_2D(output)
#Plotting.time_1D(output, [0.0, 2.5, 5.0], trange=(-5e-12, 5e-12))
Plotting.spec_1D(output, range(0.0, 1.0, length=5).*flength, λrange=(400e-9, 1300e-9))
38 changes: 38 additions & 0 deletions examples/low_level_interface/stepindex/stepscg_modeAvg_env.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# supercontinuum in strand of silica in air

using Luna

# single mode fibre at 1030 nm
a = 1.25e-6
flength = 15e-2
fr = 0.18
τfwhm = 50e-15
λ0 = 835e-9
energy = 568e-12

grid = Grid.EnvGrid(flength, λ0, (400e-9, 1400e-9), 10e-12)

m = StepIndexFibre.StepIndexMode(a, accellims=(400e-9, 1400e-9, 100))
aeff = let aeffc = Modes.Aeff(m, z=0)
z -> aeffc
end
densityfun = z -> 1.0

linop, βfun!, β1, αfun = LinearOps.make_const_linop(grid, m, λ0)

responses = (Nonlinear.Kerr_env((1 - fr)*PhysData.χ3(:SiO2)),
Nonlinear.RamanPolarEnv(grid.to, Raman.raman_response(grid.to, :SiO2, fr*PhysData.ε_0*PhysData.χ3(:SiO2))))

inputs = (Fields.SechField(λ0=λ0, τfwhm=τfwhm, energy=energy), Fields.ShotNoise())
Eω, transform, FT = Luna.setup(grid, densityfun, responses, inputs, βfun!, aeff)


output = Output.MemoryOutput(0, grid.zmax, 201)
Luna.run(Eω, grid, linop, transform, FT, output)

##
Plotting.pygui(true)
#Plotting.stats(output)
Plotting.prop_2D(output, , dBmin=-40.0, λrange=(400e-9, 1300e-9), trange=(-1e-12, 5e-12))
#Plotting.time_1D(output, [0.0, 2.5, 5.0], trange=(-5e-12, 5e-12))
Plotting.spec_1D(output, range(0.0, 1.0, length=5).*flength, λrange=(400e-9, 1300e-9))
Loading

0 comments on commit a312db5

Please sign in to comment.