diff --git a/Examples/ExampleSecondOrderNonlinearTmm.py b/Examples/ExampleSecondOrderNonlinearTmm.py index 3220327..e273779 100644 --- a/Examples/ExampleSecondOrderNonlinearTmm.py +++ b/Examples/ExampleSecondOrderNonlinearTmm.py @@ -7,46 +7,125 @@ from NonlinearTMM import Material, SecondOrderNLTMM -if __name__ == "__main__": - # Define params - wlP1 = 1000e-9 - wlP2 = 1000e-9 - polP1 = "s" - polP2 = "s" - polGen = "s" - I0P1 = 1.0 - I0P2 = I0P1 - betas = np.linspace(0.0, 0.99, 10000) - crystalD = 1000e-6 + +def CalcSHG() -> None: + # Parameters + # --------------------------------------------------------------------------- + wl = 1000e-9 # Pump wavelength + pol = "s" # Polarization + I0 = 1.0 # Intensity of incident pump wave + crystalD = 1000e-6 # Crystal thickness + betas = np.linspace(0.0, 0.99, 10000) # Sweep range for beta # Define materials + # --------------------------------------------------------------------------- wlsCrystal = np.array([400e-9, 1100e-9]) nsCrystal = np.array([1.54, 1.53], dtype=complex) prism = Material.Static(1.0) crystal = Material(wlsCrystal, nsCrystal) - dielectric = Material.Static(1.0) crystal.chi2.Update(d22=1e-12) + dielectric = Material.Static(1.0) # Init SecondOrderNLTMM + # --------------------------------------------------------------------------- tmm = SecondOrderNLTMM() - tmm.P1.SetParams(wl=1000e-9, pol="s", beta=0.2, I0=1.0) - tmm.P2.SetParams(wl=1000e-9, pol="s", beta=0.2, I0=1.0) - tmm.Gen.SetParams(pol="s") + tmm.P1.SetParams(wl=wl, pol=pol, beta=0.2, I0=I0) + tmm.P2.SetParams(wl=wl, pol=pol, beta=0.2, I0=I0) + tmm.Gen.SetParams(pol=pol) # Add layers tmm.AddLayer(math.inf, prism) tmm.AddLayer(crystalD, crystal) tmm.AddLayer(math.inf, dielectric) - # Sweep over beta = sin(th) * n_prism - sr = tmm.Sweep("beta", betas, betas) + # Beta sweep + # --------------------------------------------------------------------------- + sr = tmm.Sweep("beta", betas, betas, outP1=True, outGen=True) + + # Crystal thickness sweep at normal incidence (beta = 0) + # --------------------------------------------------------------------------- + thicknesses = np.linspace(10e-6, 2000e-6, 200) + shg_t = np.empty(len(thicknesses)) + for i, d in enumerate(thicknesses): + tmm2 = SecondOrderNLTMM() + tmm2.P1.SetParams(wl=wl, pol=pol, beta=0.0, I0=I0) + tmm2.P2.SetParams(wl=wl, pol=pol, beta=0.0, I0=I0) + tmm2.Gen.SetParams(pol=pol) + tmm2.AddLayer(math.inf, prism) + tmm2.AddLayer(d, crystal) + tmm2.AddLayer(math.inf, dielectric) + tmm2.Solve() + intensities = tmm2.GetIntensities() + shg_t[i] = intensities.Gen.T + + # Plot results + # --------------------------------------------------------------------------- + fig, axes = plt.subplots(1, 3, figsize=(9.6, 3.2)) + + # Left: Schematic of the setup + ax = axes[0] + ax.set_xlim(-1, 5) + ax.set_ylim(-2, 2) + ax.set_aspect("equal") + ax.axis("off") + ax.set_title("Setup") + + # Draw layers + from matplotlib.patches import Rectangle - # Plot generated reflection and transmission - plt.title(rf"SHG generation from crystal (d = {1e6 * crystalD:.0f} $\mu m$)") - plt.plot(betas, sr.Gen.Ir, label="R") - plt.plot(betas, sr.Gen.It, label="T") - plt.legend() - plt.xlabel(r"$\beta$") - plt.ylabel(r"($W / m^{2}$)") + ax.add_patch(Rectangle((-0.5, -1.5), 1.5, 3, fc="#ddeeff", ec="k", lw=0.8)) + ax.add_patch(Rectangle((1, -1.5), 2, 3, fc="#ffe0cc", ec="k", lw=1.2)) + ax.add_patch(Rectangle((3, -1.5), 1.5, 3, fc="#ddeeff", ec="k", lw=0.8)) + ax.text(0.25, -1.8, "air", ha="center", fontsize=8) + ax.text(2.0, -1.8, r"$\chi^{(2)}$ crystal", ha="center", fontsize=8) + ax.text(3.75, -1.8, "air", ha="center", fontsize=8) + # Pump arrow + ax.annotate( + "", + xy=(0.9, 0.3), + xytext=(-0.6, 0.3), + arrowprops=dict(arrowstyle="-|>", color="C0", lw=2), + ) + ax.text(-0.5, 0.6, r"$\omega$ pump", fontsize=7, color="C0") + + # SHG arrows (reflected + transmitted) + ax.annotate( + "", + xy=(-0.6, -0.3), + xytext=(0.9, -0.3), + arrowprops=dict(arrowstyle="-|>", color="C3", lw=1.5, ls="--"), + ) + ax.text(-0.5, -0.7, r"$2\omega$ R", fontsize=7, color="C3") + + ax.annotate( + "", + xy=(4.6, -0.3), + xytext=(3.1, -0.3), + arrowprops=dict(arrowstyle="-|>", color="C3", lw=2), + ) + ax.text(3.7, -0.7, r"$2\omega$ T", fontsize=7, color="C3") + + # Middle: SHG R, T vs beta + ax = axes[1] + ax.plot(betas, sr.Gen.Ir, label="R") + ax.plot(betas, sr.Gen.It, label="T") + ax.set_xlabel(r"$\beta$") + ax.set_ylabel(r"Intensity ($W/m^{2}$)") + ax.set_title(r"SHG intensity vs $\beta$") + ax.legend() + + # Right: SHG T vs crystal thickness + ax = axes[2] + ax.plot(thicknesses * 1e6, shg_t) + ax.set_xlabel(r"Crystal thickness ($\mu m$)") + ax.set_ylabel(r"SHG transmitted ($W/m^{2}$)") + ax.set_title(r"Thickness dependence ($\beta$ = 0)") + + fig.tight_layout() + fig.savefig("docs/images/SecondOrderNLTMM-example.png", dpi=100) plt.show() + + +if __name__ == "__main__": + CalcSHG() diff --git a/Examples/ExampleTMM.py b/Examples/ExampleTMM.py index 25f219c..62ed4b0 100644 --- a/Examples/ExampleTMM.py +++ b/Examples/ExampleTMM.py @@ -89,6 +89,7 @@ def CalcSpp() -> None: plt.colorbar(label=r"$E_z$ (V/m)") plt.tight_layout() + plt.savefig("docs/images/TMM-example.png", dpi=100) plt.show() diff --git a/Examples/ExampleTMMForWaves.py b/Examples/ExampleTMMForWaves.py index 106d1a1..809ff93 100644 --- a/Examples/ExampleTMMForWaves.py +++ b/Examples/ExampleTMMForWaves.py @@ -81,6 +81,7 @@ def CalcSppGaussianBeam() -> None: plt.colorbar(cm, label=r"$‖E‖$ (kV/m)") plt.tight_layout() + plt.savefig("docs/images/TMMForWaves-example.png", dpi=100) plt.show() diff --git a/README.md b/README.md index 9e74eb0..17d5b2f 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,203 @@ [![PyPI version](https://badge.fury.io/py/NonlinearTMM.svg)](https://badge.fury.io/py/NonlinearTMM) +[![Python](https://img.shields.io/pypi/pyversions/NonlinearTMM)](https://pypi.org/project/NonlinearTMM/) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Pytest](https://github.com/ardiloot/NonlinearTMM/actions/workflows/pytest.yml/badge.svg)](https://github.com/ardiloot/NonlinearTMM/actions/workflows/pytest.yml) -[![PyPI](https://github.com/ardiloot/NonlinearTMM/actions/workflows/publish.yml/badge.svg)](https://github.com/ardiloot/NonlinearTMM/actions/workflows/publish.yml) +[![Pre-commit](https://github.com/ardiloot/NonlinearTMM/actions/workflows/pre-commit.yml/badge.svg)](https://github.com/ardiloot/NonlinearTMM/actions/workflows/pre-commit.yml) +[![Build and upload to PyPI](https://github.com/ardiloot/NonlinearTMM/actions/workflows/publish.yml/badge.svg)](https://github.com/ardiloot/NonlinearTMM/actions/workflows/publish.yml) +# NonlinearTMM: Nonlinear Transfer-Matrix Method -# NonlinearTMM : Nonlinear transfer-matrix method +A Python library for optical simulations of **multilayer structures** using the transfer-matrix method, extended to support **nonlinear processes** (SHG, SFG, DFG) and **Gaussian beam propagation**. -## Overview +

+ Gaussian beam exciting surface plasmon polaritons +

-Transfer-matrix method (TMM) is powerful analytical method to solve Maxwell equations in layered structures. However, standard TMM is limited by infinite plane waves (e.g no Gaussian beam excitation) and it is only limited to linear processes (i.e calculation of second-harmonic, sum-frequency, difference-frequency generation is not possible). The aim of this package is extand standard TMM to include those features. The physics of those extensions are described in the follwoing publications, first extends the standard TMM to nonlinear processes and the second extends to the beams with arbritary profiles. +> **See also:** [GeneralTmm](https://github.com/ardiloot/GeneralTmm) — a 4×4 TMM for **anisotropic** (birefringent) multilayer structures. -1. [A. Loot and V. Hizhnyakov, “Extension of standard transfer-matrix method for three-wave mixing for plasmonic structures,” Appl. Phys. A, vol. 123, no. 3, p. 152, 2017.](https://link.springer.com/article/10.1007%2Fs00339-016-0733-0) -2. [A. Loot and V. Hizhnyakov, “Modeling of enhanced spontaneous parametric down-conversion in plasmonic and dielectric structures with realistic waves,” Journal of Optics, vol. 20, no. 055502, 2018.](http://iopscience.iop.org/article/10.1088/2040-8986/aab6c0/meta) +## Table of Contents -For additional details see our documentation https://ardiloot.github.io/NonlinearTMM/. For getting started guide see [Getting started](https://ardiloot.github.io/NonlinearTMM/GettingStarted.html). +- [Features](#features) +- [Installation](#installation) +- [API Overview](#api-overview) +- [Examples](#examples) + - [Surface Plasmon Polaritons](#surface-plasmon-polaritons--exampletmmpy) + - [Gaussian Beam Excitation](#gaussian-beam-excitation--exampletmmforwavespy) + - [Second-Harmonic Generation](#second-harmonic-generation--examplesecondordernonlineartmmpy) +- [References](#references) +- [Documentation](#documentation) +- [Development](#development) + - [Setup](#setup) + - [Running tests](#running-tests) + - [Code formatting and linting](#code-formatting-and-linting) + - [CI overview](#ci-overview) +- [Releasing](#releasing) +- [License](#license) -## Main features +## Features -In addition to the standard TMM features this package also supports: +- **Standard TMM** — reflection, transmission, absorption for p- and s-polarized plane waves at arbitrary angles +- **Parameter sweeps** — over wavelength, angle of incidence, layer thickness, or any other parameter +- **1D and 2D electromagnetic field profiles** — E and H field distributions through the structure +- **Field enhancement** — calculation of field enhancement factors (e.g. for SPP excitation) +- **Gaussian beam propagation** — any beam profile through layered structures, not just plane waves +- **Second-order nonlinear processes** — SHG, SFG, DFG in multilayer structures +- **Wavelength-dependent materials** — interpolated from measured optical data (YAML format) +- **High performance** — C++ core (Eigen) with Cython bindings, OpenMP parallelization +- **Cross-platform wheels** — Linux (x86_64), Windows (x64, ARM64), macOS (ARM64); Python 3.10–3.14 -* Calculation of Gaussian beam (or any other beam) propagartion inside layered structures -* Calculation of nonlinear processes SHG/SFG/DFG +## Installation -## Technical features +```bash +pip install NonlinearTMM +``` -* Written in C++ -* Python wrapper written in Cython -* Parallerization through OpenMP -* Use of SSE instructions for speedup +Pre-built wheels are available for most platforms. A C++ compiler is only needed when installing from source. + +## API Overview + +The library exposes three main classes: `Material`, `TMM`, and `SecondOrderNLTMM`. + +| Class / method | Purpose | +|---|---| +| `Material(wls, ns)` | Wavelength-dependent material from arrays of λ and complex n | +| `Material.Static(n)` | Constant refractive index (shortcut) | +| `TMM(wl=…, pol=…, I0=…)` | Create a solver; `wl` = wavelength (m), `pol` = `"p"` or `"s"` | +| `tmm.AddLayer(d, mat)` | Append layer (`d` in m, `inf` for semi-infinite) | +| `tmm.Sweep(param, values)` | Solve for an array of values of any parameter | +| `tmm.GetFields(zs)` | E, H field profiles along the layer normal | +| `tmm.GetFields2D(zs, xs)` | E, H on a 2-D grid | +| `tmm.GetEnhancement(layerNr)` | Field enhancement in a given layer | +| `tmm.wave` | Access `_Wave` parameters for Gaussian beam calculations | +| `tmm.WaveSweep(param, values)` | Parameter sweep for beam calculations | +| `tmm.WaveGetFields2D(zs, xs)` | 2-D field map for beam excitation | +| `SecondOrderNLTMM(…)` | Second-order nonlinear TMM (SHG, SFG, DFG) | + +For the full API, see the [reference documentation](https://ardiloot.github.io/NonlinearTMM/Reference.html). + +## Examples + +### Surface Plasmon Polaritons — [ExampleTMM.py](Examples/ExampleTMM.py) + +Kretschmann configuration (prism | 50 nm Ag | air) at 532 nm. Demonstrates +reflection sweeps, field enhancement, and 1D/2D field visualization of surface +plasmon polaritons. + +```python +import math +import numpy as np +from NonlinearTMM import TMM, Material + +# Materials +prism = Material.Static(1.5) +ag = Material.Static(0.054007 + 3.4290j) # Silver @ 532nm +air = Material.Static(1.0) + +# Set up TMM (Kretschmann configuration) +tmm = TMM(wl=532e-9, pol="p", I0=1.0) +tmm.AddLayer(math.inf, prism) +tmm.AddLayer(50e-9, ag) +tmm.AddLayer(math.inf, air) + +# Sweep angle of incidence +betas = np.sin(np.radians(np.linspace(0, 80, 500))) * 1.5 +result = tmm.Sweep("beta", betas, outEnh=True, layerNr=2) +``` + +

+ SPP reflection, enhancement, and field profiles +

+ +### Gaussian Beam Excitation — [ExampleTMMForWaves.py](Examples/ExampleTMMForWaves.py) + +The same Kretschmann structure excited by a 10 mW Gaussian beam (waist 10 μm). +Shows how finite beam width affects resonance depth and field enhancement. + +

+ Gaussian beam SPP excitation +

+ +### Second-Harmonic Generation — [ExampleSecondOrderNonlinearTmm.py](Examples/ExampleSecondOrderNonlinearTmm.py) + +Second-harmonic generation (SHG) in a 1 mm nonlinear crystal with +χ⁽²⁾ nonlinearity. Two s-polarized pump beams at 1000 nm generate a +second-harmonic signal at 500 nm. The `SecondOrderNLTMM` class also supports +sum-frequency generation (SFG) and difference-frequency generation (DFG). + +

+ SHG reflected and transmitted intensity vs beta +

+ +## References + +> Loot, A., & Hizhnyakov, V. (2017). Extension of standard transfer-matrix method for three-wave mixing for plasmonic structures. *Applied Physics A*, 123(3), 152. [doi:10.1007/s00339-016-0733-0](https://link.springer.com/article/10.1007%2Fs00339-016-0733-0) +> +> Loot, A., & Hizhnyakov, V. (2018). Modeling of enhanced spontaneous parametric down-conversion in plasmonic and dielectric structures with realistic waves. *Journal of Optics*, 20, 055502. [doi:10.1088/2040-8986/aab6c0](https://doi.org/10.1088/2040-8986/aab6c0) ## Documentation -https://ardiloot.github.io/NonlinearTMM/ +Full documentation is available at https://ardiloot.github.io/NonlinearTMM/. + +- [Getting started](https://ardiloot.github.io/NonlinearTMM/GettingStarted.html) — installation, package structure, examples +- [API reference](https://ardiloot.github.io/NonlinearTMM/Reference.html) — complete class and method reference + +## Development + +### Setup + +```bash +git clone --recurse-submodules https://github.com/ardiloot/NonlinearTMM.git +cd NonlinearTMM + +# Install uv if not already installed: +# https://docs.astral.sh/uv/getting-started/installation/ + +# Create venv, build the C++ extension, and install all dependencies +uv sync +``` + +### Running tests + +```bash +uv run pytest -v +``` + +### Code formatting and linting + +[Pre-commit](https://pre-commit.com/) hooks are configured to enforce formatting (ruff, clang-format) and catch common issues. To install the git hook locally: + +```bash +uv run pre-commit install +``` + +To run all checks manually: + +```bash +uv run pre-commit run --all-files +``` + +### CI overview + +| Workflow | Trigger | What it does | +|----------|---------|--------------| +| [Pytest](.github/workflows/pytest.yml) | Push to `master` / PRs | Tests on {ubuntu, windows, macos} × Python {3.10–3.14} | +| [Pre-commit](.github/workflows/pre-commit.yml) | Push to `master` / PRs | Runs ruff, clang-format, ty, and other checks | +| [Publish to PyPI](.github/workflows/publish.yml) | Release published | Builds wheels + sdist via cibuildwheel, uploads to PyPI | +| [Publish docs](.github/workflows/publish_docs.yml) | Release published | Builds Sphinx docs and deploys to GitHub Pages | + +## Releasing + +Versioning is handled automatically by [setuptools-scm](https://github.com/pypa/setuptools-scm) from git tags. + +1. **Ensure CI is green** on the `master` branch. +2. **Create a new release** on GitHub: + - Go to [Releases](https://github.com/ardiloot/NonlinearTMM/releases) → **Draft a new release** + - Create a new tag following [PEP 440](https://peps.python.org/pep-0440/) (e.g. `v1.2.0`) + - Target the `master` branch (or a specific commit on master) + - Click **Generate release notes** for an auto-generated changelog + - For pre-releases (e.g. `v1.2.0rc1`), check **Set as a pre-release** — these upload to TestPyPI instead of PyPI +3. **Publish the release** — the workflow builds wheels for Linux (x86_64), Windows (x64, ARM64), and macOS (ARM64), and uploads to [PyPI](https://pypi.org/project/NonlinearTMM/). + +## License + +[MIT](LICENSE) diff --git a/docs/GettingStarted.rst b/docs/GettingStarted.rst index d977257..eeef1eb 100644 --- a/docs/GettingStarted.rst +++ b/docs/GettingStarted.rst @@ -6,16 +6,16 @@ Getting started Installation ************ -Installation of NonlinearTMM package is possible through pip or from source +Installation of the NonlinearTMM package is possible through pip or from source code. Requirements: -* `Python >= 3.6 `_ +* `Python >= 3.10 `_ Dependencies: -* C++ code depends on `Eigen library `_ (already included in package) +* C++ code depends on `Eigen library `_ (already included in package) Installation through pip is done like: @@ -23,7 +23,7 @@ Installation through pip is done like: pip install NonlinearTMM -Alternatively, it is possible to install the package form the source code by +Alternatively, it is possible to install the package from the source code by .. code-block:: bash @@ -41,33 +41,33 @@ The package has three main classes: * :class:`TMM` * :class:`SecondOrderNLTMM` -Class :class:`Material` is responsible to represent the properties of optical -material. Mainly wavelength dependent refractive indices and second-order -suceptibility tensor for nonlinear processes. +Class :class:`Material` is responsible for representing the properties of optical +material, mainly wavelength-dependent refractive indices and second-order +susceptibility tensor for nonlinear processes. -Class :class:`TMM` (alias of :class:`NonlinearTMM`) is has all the standard TMM features: +Class :class:`TMM` (alias of :class:`NonlinearTMM`) has all the standard TMM features: * Both p- and s-polarization -* Arbritarty angle of incidence +* Arbitrary angle of incidence * Calculation of reflection, transmission and absorption of plane waves (:any:`GetIntensities ` and :any:`GetAbsorbedIntensity `) -* Calculaion of electric and magnetic fields inside structure (:any:`GetFields ` and :any:`GetFields2D `) +* Calculation of electric and magnetic fields inside structure (:any:`GetFields ` and :any:`GetFields2D `) * Calculation of field enhancement (:any:`GetEnhancement `) * Sweep over any parameter (:any:`Sweep `) In addition to those standard features, the class has similar functionality to -work with waves with arbritarty profile (e.g. Gaussian beam). The configuration +work with waves with arbitrary profile (e.g. Gaussian beam). The configuration of the beam is done through attribute :any:`wave ` (see class :any:`_Wave`). -The interface for the calculations with arbritarty beams is similar to standard TMM: +The interface for the calculations with arbitrary beams is similar to standard TMM: * Calculation of reflection, transmission and absorption of beams (:any:`WaveGetPowerFlows `) -* Calculaion of electric and magnetic fields inside structure (:any:`WaveGetFields2D `) +* Calculation of electric and magnetic fields inside structure (:any:`WaveGetFields2D `) * Calculation of field enhancement (:any:`WaveGetEnhancement `) * Sweep over any parameter (:any:`WaveSweep `) -Finally, :class:`SecondOrderNLTMM` class ic capable of calculating second-order +Finally, :class:`SecondOrderNLTMM` class is capable of calculating second-order nonlinear processes like second-harmonic generation, sum-frequency generation and -difference frequency generation. This has similar interface as :any:`TMM` - it -supports both the plane waves and beams. +difference frequency generation. This has a similar interface to :any:`TMM` - it +supports both plane waves and beams. Standard TMM ************ @@ -75,50 +75,50 @@ Standard TMM Plane waves example =================== -As an example three layer structure consisting of a prism (z < 0), 50 nm thick silver -film and air is studied. Such kind of structure supports surface plasmon -resonance (SPP) if excited by p-polarized light and is named Kretschmann -configuration. The example code is shown bellow and could be divided into -following steps: +As an example, a three-layer structure consisting of a prism (z < 0), a 50-nm-thick silver +film and air is studied. Such a structure supports surface plasmon +resonance (SPR) if excited by p-polarized light and is known as the Kretschmann +configuration. The example code is shown below and could be divided into +the following steps: -1. Specifying materials refractive indices. +1. Specifying material refractive indices. 2. Initializing :class:`TMM`, setting params and adding layers. -3. By using :any:`Sweep ` calculate the dependence of reflection, transmission and enhancment factor on the angle of incidence. -4. Find the plasmonic resonance by maximum enhancment. +3. By using :any:`Sweep ` calculate the dependence of reflection, transmission and enhancement factor on the angle of incidence. +4. Find the plasmonic resonance from the maximum enhancement. 5. Calculate 1D fields at plasmonic resonance by :any:`GetFields `. 6. Calculate 2D fields at plasmonic resonance by :any:`GetFields2D `. 7. Plot all results .. literalinclude:: ../Examples/ExampleTMM.py -The results of the calculations are shown bellow. Indeed there is a sharrp dip -in the reflection (R) near the angle of incidence ca 44 degrees. At the same angle -the field enhancement factor is maximum and is more than 12 times. In the second -the results of the fields calculations at plasmonic resonance is presented. Indeed, -surface wave on the silver-air interface is excited and characteristic pattern of -fields for SPP is visible. +The results of the calculations are shown below. Indeed, there is a sharp dip +in the reflection (R) near the angle of incidence of approximately 44 degrees. At the same angle, +the field enhancement factor is at its maximum and is more than 12 times the incident field. In the lower +panels, the results of the field calculations at plasmonic resonance are presented. +Indeed, a surface wave on the silver-air interface is excited and the characteristic +pattern of fields for SPP is visible. .. image:: images/TMM-example.png Gaussian wave example ===================== -Previous example was entirely about standard TMM. Now, the calculations are -extended to the beams, in this case Gaussian beam. The steps of the calculations +The previous example was entirely about standard TMM. Now, the calculations are +extended to beams, in this case a Gaussian beam. The steps of the calculations remain the same, except :class:`_Wave` parameters must be set (:class:`TMM` has -attribute :any:`TMM.wave`). Gaussian beam power is set to 10 mW and waist size +attribute :any:`TMM.wave`). The Gaussian beam power is set to 10 mW and the waist size to 10 μm. .. literalinclude:: ../Examples/ExampleTMMForWaves.py -The results of those calculations are bellow. Despite the fact, that the structure +The results of those calculations are below. Despite the fact that the structure is the same, the dip in the reflection is different. The reason for this behaviour -is that as the resonances of SPPs are narrow, they also require well collimated -beam to excite them. Also field enhancment is ca 3 times lower, as expected. On -the right side, the electrical field norm is shown. It is clearly visible, that -Gaussian beam is incident form the left, and it gets reflected from the metal film (z = 0). +is that as the resonances of SPPs are narrow, they also require a well-collimated +beam to excite them. Also, the field enhancement is approximately 3 times lower, as expected. On +the right side, the electric field norm is shown. It is clearly visible that +a Gaussian beam is incident from the left, and it gets reflected from the metal film (z = 0). Part of the energy is transmitted to excite SPPs at the metal-air interface. The -excited SPPs are propagating on the metal film and are absorbe after ca 20 μm of +excited SPPs are propagating on the metal film and are absorbed after approximately 20 μm of propagation. .. image:: images/TMMForWaves-example.png @@ -129,9 +129,13 @@ Second-order nonlinear TMM Plane waves example =================== -Will be added in near future. +As an example, second-harmonic generation (SHG) in a nonlinear crystal is +calculated. The example code is shown below. -Gaussian wave example -===================== +.. literalinclude:: ../Examples/ExampleSecondOrderNonlinearTmm.py + +The results show the reflected and transmitted SHG intensity as a function +of the propagation parameter β. Two s-polarized pump beams at 1000 nm +generate a second-harmonic signal at 500 nm in a 1 mm nonlinear crystal. -Will be added in near future. +.. image:: images/SecondOrderNLTMM-example.png diff --git a/docs/Introduction.rst b/docs/Introduction.rst index 4d62c9c..8b57c83 100644 --- a/docs/Introduction.rst +++ b/docs/Introduction.rst @@ -5,17 +5,16 @@ Introduction Overview ******** -Transfer-matrix method (TMM) is powerful analytical method to solve Maxwell -equations in layered structures. However, standard TMM is limited by infinite -plane waves (e.g no Gaussian beam excitation) and it is only limited to linear -processes (i.e calculation of second-harmonic, sum-frequency, difference-frequency -generation is not possible). The aim of this package is extand standard TMM to -include those features. The physics of those extensionsare described in the -follwoing publications, first extends the standard TMM to nonlinear processes -and the second extends to the beams with arbritary profiles. +Transfer-matrix method (TMM) is a powerful analytical method to solve Maxwell's +equations in layered structures. However, standard TMM is limited to infinite +plane waves (e.g. no Gaussian beam excitation) and to linear processes (i.e. +calculation of second-harmonic, sum-frequency, and difference-frequency +generation is not possible). The aim of this package is to extend standard TMM to +include those features. The physics of these extensions is described in the +following publications: -1. `A. Loot and V. Hizhnyakov, “Extension of standard transfer-matrix method for three-wave mixing for plasmonic structures,” Appl. Phys. A, vol. 123, no. 3, p. 152, 2017. `_ -2. TPB +1. `A. Loot and V. Hizhnyakov, "Extension of standard transfer-matrix method for three-wave mixing for plasmonic structures," Appl. Phys. A, vol. 123, no. 3, p. 152, 2017. `_ +2. `A. Loot and V. Hizhnyakov, "Modeling of enhanced spontaneous parametric down-conversion in plasmonic and dielectric structures with realistic waves," J. Opt., vol. 20, no. 055502, 2018. `_ Main features @@ -23,13 +22,13 @@ Main features In addition to the standard TMM features this package also supports: -* Calculation of Gaussian beam (or any other beam) propagartion inside layered structures +* Calculation of Gaussian beam (or any other beam) propagation inside layered structures * Calculation of nonlinear processes SHG/SFG/DFG Technical features ================== -* Written in C++ -* Python wrappers written in Cython -* Parallerization through OpenMP -* Use of SSE instructions for speedup +* Core written in C++ +* Python bindings via Cython +* OpenMP parallelization (Linux and Windows) +* Supports Linux (x86_64), Windows (x64, ARM64), and macOS (ARM64) diff --git a/docs/conf.py b/docs/conf.py index c89aed7..e7106a2 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -56,7 +56,7 @@ # General information about the project. project = "NonlinearTMM" -copyright = "2017-2025, Ardi Loot" +copyright = "2017-2026, Ardi Loot" author = "Ardi Loot" # The version info for the project you're documenting, acts as replacement for @@ -80,7 +80,7 @@ # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. -# This patterns also effect to html_static_path and html_extra_path +# These patterns also affect html_static_path and html_extra_path exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] # The name of the Pygments (syntax highlighting) style to use. @@ -162,7 +162,7 @@ "NonlinearTMM Documentation", author, "NonlinearTMM", - "One line description of project.", + "Nonlinear transfer-matrix method.", "Miscellaneous", ), ] diff --git a/docs/images/SecondOrderNLTMM-example.png b/docs/images/SecondOrderNLTMM-example.png new file mode 100644 index 0000000..5dde0bf Binary files /dev/null and b/docs/images/SecondOrderNLTMM-example.png differ