diff --git a/docs/.documenter-siteinfo.json b/docs/.documenter-siteinfo.json
index f03c537..d13a00e 100644
--- a/docs/.documenter-siteinfo.json
+++ b/docs/.documenter-siteinfo.json
@@ -1 +1 @@
-{"documenter":{"julia_version":"1.10.0","generation_timestamp":"2024-01-25T16:10:05","documenter_version":"1.2.1"}}
\ No newline at end of file
+{"documenter":{"julia_version":"1.10.0","generation_timestamp":"2024-01-30T23:44:56","documenter_version":"1.2.1"}}
\ No newline at end of file
diff --git a/docs/guide/index.html b/docs/guide/index.html
index 2e3a931..ef9d113 100644
--- a/docs/guide/index.html
+++ b/docs/guide/index.html
@@ -1,2 +1,2 @@
-
Engineers run simulations to improve designs. Each time the design changes, the simulation is re-run. This can be done systematically in "parameter sweeps" where different combinations of parameter values are simulated to determine the best design. However, this scales exponentially wrt the number of parameters or DOFs.
We use gradient descent, the same as in machine learning. In lieu of optimizing neural network parameters, we're optimizing geometry (or source) parameters. In each training iteration, we generate geometry, run the simulation, calculate the objective metric, and do a backward pass to derive the gradient wrt the geometry parameters. We then do a gradient based parameter update in preparation for the next iteration.
The geometry is thus the first step. It typically has a static component which we can't change such as interfacing waveguides. Then there's a design component which we can change or optimize. The user is responsible for generating the design geometry wrt design parameters. If any pattern is allowed in the design region, our sister package Jello.jl can be used as a length scale controlled geometry generator. In any case, the result needs to be a 2d/3d array of each relevant materials property eg permitivity.
With geometry ready, we can run the simulation. Duration is roughly the time it takes to reach steady state, such as how long it take for the signal to reach output port. The objective is usually a steady state metric which can be computed using values from the final period. We optimize geometry for some objective.
Settings
This document was generated with Documenter.jl version 1.2.1 on Thursday 25 January 2024. Using Julia version 1.10.0.
Engineers run simulations to improve designs. Each time the design changes, the simulation is re-run. This can be done systematically in "parameter sweeps" where different combinations of parameter values are simulated to determine the best design. However, this scales exponentially wrt the number of parameters or DOFs.
We use gradient descent, the same as in machine learning. In lieu of optimizing neural network parameters, we're optimizing geometry (or source) parameters. In each training iteration, we generate geometry, run the simulation, calculate the objective metric, and do a backward pass to derive the gradient wrt the geometry parameters. We then do a gradient based parameter update in preparation for the next iteration.
The geometry is thus the first step. It typically has a static component which we can't change such as interfacing waveguides. Then there's a design component which we can change or optimize. The user is responsible for generating the design geometry wrt design parameters. If any pattern is allowed in the design region, our sister package Jello.jl can be used as a length scale controlled geometry generator. In any case, the result needs to be a 2d/3d array of each relevant materials property eg permitivity.
With geometry ready, we can run the simulation. Duration is roughly the time it takes to reach steady state, such as how long it take for the signal to reach output port. The objective is usually a steady state metric which can be computed using values from the final period. We optimize geometry for some objective.
Settings
This document was generated with Documenter.jl version 1.2.1 on Tuesday 30 January 2024. Using Julia version 1.10.0.
Differentiable FDTD package for inverse design & topology optimization in photonics, acoustics and RF. Uses automatic differentiation by Zygote.jl for adjoint optimization. Integrates with Jello.jl to generate length scale controlled paramaterized geometry . Staggered Yee grid update with fully featured boundary conditions & sources. Customizable physics to potentially incorporate dynamics like heat transfer, charge transport.
Differentiable FDTD package for inverse design & topology optimization in photonics, acoustics and RF. Uses automatic differentiation by Zygote.jl for adjoint optimization. Integrates with Jello.jl to generate length scale controlled paramaterized geometry . Staggered Yee grid update with fully featured boundary conditions & sources. Customizable physics to potentially incorporate dynamics like heat transfer, charge transport.
Install via Pkg.add(url="https://github.com/paulxshen/FDTDEngine.jl"). You can additionally access plotting and movie making scripts via include("_your_path/scripts/plot_recipes.jl")
Supports 1d (Ez, Hy), 2d TMz (Ez, Hx, Hy), 2d TEz (Hz, Ex, Ey) and 3d. Length and time are in units of wavelength and period. This normalization allows usage of relative permitivity and permeability in equations . Fields including electric, magnetic and current density are simply bundled as a vector of arrays . Boundary conditions pad the field arrays . PML paddings are multilayered, stateful and permanent, increasing size of field and geometry arrays. All other boundaries only add transient single layers which are subsequently consumed by finite differencing every update step. Paddings are coordinated to implictly implement staggered Yee's grid for finite differencing.
If a source has fewer nonzero dimensions than the simulation domain, its signal will get normalized along its singleton dimensions. For example, all planar sources in 3d or line sources in 2d will get scaled up by a factor of 1/dx. This way, discretisation would not affect radiated power.
Supports 1d (Ez, Hy), 2d TMz (Ez, Hx, Hy), 2d TEz (Hz, Ex, Ey) and 3d. Length and time are in units of wavelength and period. This normalization allows usage of relative permitivity and permeability in equations . Fields including electric, magnetic and current density are simply bundled as a vector of arrays . Boundary conditions pad the field arrays . PML paddings are multilayered, stateful and permanent, increasing size of field and geometry arrays. All other boundaries only add transient single layers which are subsequently consumed by finite differencing every update step. Paddings are coordinated to implictly implement staggered Yee's grid for finite differencing.
If a source has fewer nonzero dimensions than the simulation domain, its signal will get normalized along its singleton dimensions. For example, all planar sources in 3d or line sources in 2d will get scaled up by a factor of 1/dx. This way, discretisation would not affect radiated power.
Constructs perfectly matched layers (PML aka ABC, RBC) boundary of depth d wavelengths Doesn't need to be explictly declared as all unspecified boundaries default to PML
This document was generated with Documenter.jl version 1.2.1 on Tuesday 30 January 2024. Using Julia version 1.10.0.
diff --git a/docs/search_index.js b/docs/search_index.js
index d25a288..3916e29 100644
--- a/docs/search_index.js
+++ b/docs/search_index.js
@@ -1,3 +1,3 @@
var documenterSearchIndex = {"docs":
-[{"location":"guide/#","page":"-","title":"","text":"","category":"section"},{"location":"guide/","page":"-","title":"-","text":"Engineers run simulations to improve designs. Each time the design changes, the simulation is re-run. This can be done systematically in \"parameter sweeps\" where different combinations of parameter values are simulated to determine the best design. However, this scales exponentially wrt the number of parameters or DOFs. ","category":"page"},{"location":"guide/#General-workflow","page":"-","title":"General workflow","text":"","category":"section"},{"location":"guide/","page":"-","title":"-","text":"We use gradient descent, the same as in machine learning. In lieu of optimizing neural network parameters, we're optimizing geometry (or source) parameters. In each training iteration, we generate geometry, run the simulation, calculate the objective metric, and do a backward pass to derive the gradient wrt the geometry parameters. We then do a gradient based parameter update in preparation for the next iteration.","category":"page"},{"location":"guide/","page":"-","title":"-","text":"The geometry is thus the first step. It typically has a static component which we can't change such as interfacing waveguides. Then there's a design component which we can change or optimize. The user is responsible for generating the design geometry wrt design parameters. If any pattern is allowed in the design region, our sister package Jello.jl can be used as a length scale controlled geometry generator. In any case, the result needs to be a 2d/3d array of each relevant materials property eg permitivity. ","category":"page"},{"location":"guide/","page":"-","title":"-","text":"With geometry ready, we can run the simulation. Duration is roughly the time it takes to reach steady state, such as how long it take for the signal to reach output port. The objective is usually a steady state metric which can be computed using values from the final period. We optimize geometry for some objective. ","category":"page"},{"location":"#FDTDEngine.jl","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"","category":"section"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"Only 3d works in latest patch. 2d/1d will be fixed in future. Prerelease. Expect breaking changes","category":"page"},{"location":"#Overview","page":"FDTDEngine.jl","title":"Overview","text":"","category":"section"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"Differentiable FDTD package for inverse design & topology optimization in photonics, acoustics and RF. Uses automatic differentiation by Zygote.jl for adjoint optimization. Integrates with Jello.jl to generate length scale controlled paramaterized geometry . Staggered Yee grid update with fully featured boundary conditions & sources. Customizable physics to potentially incorporate dynamics like heat transfer, charge transport.","category":"page"},{"location":"#Gallery","page":"FDTDEngine.jl","title":"Gallery","text":"","category":"section"},{"location":"#Periodic-scattering","page":"FDTDEngine.jl","title":"Periodic scattering","text":"","category":"section"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"(Image: )","category":"page"},{"location":"#Quarter-wavelength-antenna","page":"FDTDEngine.jl","title":"Quarter wavelength antenna","text":"","category":"section"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"(Image: )","category":"page"},{"location":"#Inverse-design-of-compact-silicon-photonic-splitter-(coming-soon)","page":"FDTDEngine.jl","title":"Inverse design of compact silicon photonic splitter (coming soon)","text":"","category":"section"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":" ","category":"page"},{"location":"#Quickstart","page":"FDTDEngine.jl","title":"Quickstart","text":"","category":"section"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"We do a quick 3d simulation of plane wave scattering on periodic array of dielectric spheres (first gallery movie)","category":"page"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"\"\"\"\nsimulation of plane wave scattering on periodic array of dielectric spheres\n\"\"\"\n\nusing UnPack, LinearAlgebra, GLMakie\nusing FDTDEngine\ninclude(\"$(pwd())/scripts/plot_recipes.jl\")\n\n\nF = Float32\nname = \"3d_scattering\"\nT = 4.0f0 # simulation duration in [periods]\nnres = 16\ndx = 1.0f0 / nres # pixel resolution in [wavelengths]\nCourant = 0.25f0 # Courant number\n\n\"geometry\"\nl = 2 # domain physical size length\nsz = nres .* (l, l, l) # domain voxel dimensions\nϵ1 = 1 #\nϵ2 = 2.25f0 # \nb = F.([norm(v .- sz ./ 2) < 0.5 / dx for v = Base.product(Base.oneto.(sz)...)]) # sphere\nϵ = ϵ2 * b + ϵ1 * (1 .- b)\n\n\"setup\"\nboundaries = [Periodic(2), Periodic(3)]# unspecified boundaries default to PML\n# n = [1, 0, 0]\nmonitors = []\nsources = [\n PlaneWave(t -> cos(F(2π) * t), -1; Jz=1) # Jz excited plane wave from -x plane (eg -1)\n # PlaneWave(t -> t < 1 ? cos(F(2π) * t) : 0.0f0, -1; Jz=1)\n]\nconfigs = setup(boundaries, sources, monitors, dx, sz; F, Courant, T)\n@unpack μ, σ, σm, dt, geometry_padding, geometry_splits, field_padding, source_effects, monitor_instances, fields, step, power = configs\n\nϵ, μ, σ, σm = apply(geometry_padding; ϵ, μ, σ, σm)\np = apply(geometry_splits; ϵ, μ, σ, σm)\nu0 = collect(values(fields))\n\n# run simulation\n@showtime sol = accumulate((u, t) -> step(u, p, t, configs), 0:dt:T, init=u0)\n\n# make movie\nEz = map(sol) do u\n u[3]\nend\nϵz = p[1][3]\ndir = @__DIR__\nrecordsim(Ez, ϵz, configs, \"$dir/$(name)_nres_$nres.mp4\", title=\"$name\"; playback=1, bipolar=true)\n","category":"page"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"","category":"page"},{"location":"#Installation","page":"FDTDEngine.jl","title":"Installation","text":"","category":"section"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"Install via Pkg.add(url=\"https://github.com/paulxshen/FDTDEngine.jl\"). You can additionally access plotting and movie making scripts via include(\"_your_path/scripts/plot_recipes.jl\") ","category":"page"},{"location":"#Implementation","page":"FDTDEngine.jl","title":"Implementation","text":"","category":"section"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"Supports 1d (Ez, Hy), 2d TMz (Ez, Hx, Hy), 2d TEz (Hz, Ex, Ey) and 3d. Length and time are in units of wavelength and period. This normalization allows usage of relative permitivity and permeability in equations . Fields including electric, magnetic and current density are simply bundled as a vector of arrays . Boundary conditions pad the field arrays . PML paddings are multilayered, stateful and permanent, increasing size of field and geometry arrays. All other boundaries only add transient single layers which are subsequently consumed by finite differencing every update step. Paddings are coordinated to implictly implement staggered Yee's grid for finite differencing.","category":"page"},{"location":"#Sources","page":"FDTDEngine.jl","title":"Sources","text":"","category":"section"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"If a source has fewer nonzero dimensions than the simulation domain, its signal will get normalized along its singleton dimensions. For example, all planar sources in 3d or line sources in 2d will get scaled up by a factor of 1/dx. This way, discretisation would not affect radiated power.","category":"page"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"PlaneWave\nGaussianBeam\nSource","category":"page"},{"location":"#PlaneWave","page":"FDTDEngine.jl","title":"PlaneWave","text":"function PlaneWave(f, dims; fields...)\n\nConstructs plane wave source\n\nArgs\n\nf: time function\ndims: eg -1 for wave coming from -x edge\nfields: which fields to excite & their scaling constants (typically a current source, eg Jz=1)\n\n\n\n\n\n","category":"type"},{"location":"#GaussianBeam","page":"FDTDEngine.jl","title":"GaussianBeam","text":"function GaussianBeam(f, σ, center, dims; fields...)\n\nConstructs gaussian beam source\n\nArgs\n\nf: time function\nσ: std dev length\ndims: eg 1 for x direction\nfields: which fields to excite & their scaling constants (typically a current source, eg Jz=1)\n\n\n\n\n\n","category":"type"},{"location":"#Source","page":"FDTDEngine.jl","title":"Source","text":"function Source(f, center, bounds; fields...)\nfunction Source(f, center, L::AbstractVector{<:Real}; fields...)\n\nConstructs custom centered source. Can be used to specify modal sources\n\nArgs\n\nf: time function\nL: source dimensions in [wavelengths]\nfields: which fields to excite & their scaling constants (typically a current source, eg Jz=1)\n\n\n\n\n\n","category":"type"},{"location":"#Boundaries","page":"FDTDEngine.jl","title":"Boundaries","text":"","category":"section"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"Unspecified boundaries default to PML ","category":"page"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"Periodic\nPML\nPEC\nPMC","category":"page"},{"location":"#Periodic","page":"FDTDEngine.jl","title":"Periodic","text":"Periodic(dims)\n\nperiodic boundary\n\n\n\n\n\n","category":"type"},{"location":"#PML","page":"FDTDEngine.jl","title":"PML","text":"function PML(dims, d=0.25f0, σ=20.0f0)\n\nConstructs perfectly matched layers (PML aka ABC, RBC) boundary of depth d wavelengths \n\n\n\n\n\n","category":"type"},{"location":"#PEC","page":"FDTDEngine.jl","title":"PEC","text":"PEC(dims)\n\nperfect electrical conductor\n\n\n\n\n\n","category":"type"},{"location":"#PMC","page":"FDTDEngine.jl","title":"PMC","text":"PMC(dims)\n\nperfect magnetic conductor\n\n\n\n\n\n","category":"type"},{"location":"#Monitors","page":"FDTDEngine.jl","title":"Monitors","text":"","category":"section"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"Monitor","category":"page"},{"location":"#Monitor","page":"FDTDEngine.jl","title":"Monitor","text":"function Monitor(span, normal=nothing)\n\nConstructs monitor which can span a point, line, surface, or volume\n\nArgs\n\nspan\nnormal: flux monitor direction\n\n\n\n\n\n","category":"type"},{"location":"#Physics","page":"FDTDEngine.jl","title":"Physics","text":"","category":"section"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"step1\nstepTMz\nstepTEz\nstep3","category":"page"},{"location":"#step1","page":"FDTDEngine.jl","title":"step1","text":"function step1(u, p, t, configs)\n\nUpdates fields for 1D (Ez, Hy)\n\n\n\n\n\n","category":"function"},{"location":"#stepTMz","page":"FDTDEngine.jl","title":"stepTMz","text":"function stepTMz(u, p, t, configs)\n\nUpdates fields for 2d TMz\n\n\n\n\n\n","category":"function"},{"location":"#stepTEz","page":"FDTDEngine.jl","title":"stepTEz","text":"function stepTEz(u, p, t, configs)\n\nUpdates fields for 2d TEz (Hz, Ex, Ey)\n\n\n\n\n\n","category":"function"},{"location":"#step3","page":"FDTDEngine.jl","title":"step3","text":"function step3(u, p, t, configs)\n\nUpdates fields for 3d\n\n\n\n\n\n","category":"function"},{"location":"#Tutorials","page":"FDTDEngine.jl","title":"Tutorials","text":"","category":"section"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"see examples/","category":"page"},{"location":"#Generative-inverse-design","page":"FDTDEngine.jl","title":"Generative inverse design","text":"","category":"section"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"Please contact us for latest scripts.","category":"page"},{"location":"#Community","page":"FDTDEngine.jl","title":"Community","text":"","category":"section"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"Discussion & updates at Julia Discourse","category":"page"},{"location":"#Contributors","page":"FDTDEngine.jl","title":"Contributors","text":"","category":"section"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"Paul Shen ","category":"page"}]
+[{"location":"guide/#","page":"-","title":"","text":"","category":"section"},{"location":"guide/","page":"-","title":"-","text":"Engineers run simulations to improve designs. Each time the design changes, the simulation is re-run. This can be done systematically in \"parameter sweeps\" where different combinations of parameter values are simulated to determine the best design. However, this scales exponentially wrt the number of parameters or DOFs. ","category":"page"},{"location":"guide/#General-workflow","page":"-","title":"General workflow","text":"","category":"section"},{"location":"guide/","page":"-","title":"-","text":"We use gradient descent, the same as in machine learning. In lieu of optimizing neural network parameters, we're optimizing geometry (or source) parameters. In each training iteration, we generate geometry, run the simulation, calculate the objective metric, and do a backward pass to derive the gradient wrt the geometry parameters. We then do a gradient based parameter update in preparation for the next iteration.","category":"page"},{"location":"guide/","page":"-","title":"-","text":"The geometry is thus the first step. It typically has a static component which we can't change such as interfacing waveguides. Then there's a design component which we can change or optimize. The user is responsible for generating the design geometry wrt design parameters. If any pattern is allowed in the design region, our sister package Jello.jl can be used as a length scale controlled geometry generator. In any case, the result needs to be a 2d/3d array of each relevant materials property eg permitivity. ","category":"page"},{"location":"guide/","page":"-","title":"-","text":"With geometry ready, we can run the simulation. Duration is roughly the time it takes to reach steady state, such as how long it take for the signal to reach output port. The objective is usually a steady state metric which can be computed using values from the final period. We optimize geometry for some objective. ","category":"page"},{"location":"#FDTDEngine.jl","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"","category":"section"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"Only 3d works in latest patch. 2d/1d will be fixed in future. Prerelease. Expect breaking changes","category":"page"},{"location":"#Overview","page":"FDTDEngine.jl","title":"Overview","text":"","category":"section"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"Differentiable FDTD package for inverse design & topology optimization in photonics, acoustics and RF. Uses automatic differentiation by Zygote.jl for adjoint optimization. Integrates with Jello.jl to generate length scale controlled paramaterized geometry . Staggered Yee grid update with fully featured boundary conditions & sources. Customizable physics to potentially incorporate dynamics like heat transfer, charge transport.","category":"page"},{"location":"#Gallery","page":"FDTDEngine.jl","title":"Gallery","text":"","category":"section"},{"location":"#Periodic-scattering","page":"FDTDEngine.jl","title":"Periodic scattering","text":"","category":"section"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"(Image: )","category":"page"},{"location":"#Quarter-wavelength-antenna","page":"FDTDEngine.jl","title":"Quarter wavelength antenna","text":"","category":"section"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"(Image: )","category":"page"},{"location":"#Inverse-design-of-compact-silicon-photonic-splitter-(coming-soon)","page":"FDTDEngine.jl","title":"Inverse design of compact silicon photonic splitter (coming soon)","text":"","category":"section"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"In progress, split ratio isn't correct (Image: ) (Image: )","category":"page"},{"location":"#Quickstart","page":"FDTDEngine.jl","title":"Quickstart","text":"","category":"section"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"We do a quick 3d simulation of plane wave scattering on periodic array of dielectric spheres (first gallery movie)","category":"page"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"using UnPack, LinearAlgebra, GLMakie\nusing FDTDEngine,FDTDToolkit\n\nF = Float32\nname = \"3d_scattering\"\nT = 8.0f0 # simulation duration in [periods]\nnres = 16\ndx = 1.0f0 / nres # pixel resolution in [wavelengths]\nCourant = 0.8 / √3 # Courant number\n\n\"geometry\"\nl = 2 # domain physical size length\nsz = nres .* (l, l, l) # domain voxel dimensions\nϵ1 = 1 #\nϵ2 = 2.25f0 # \nb = F.([norm(v .- sz ./ 2) < 0.5 / dx for v = Base.product(Base.oneto.(sz)...)]) # sphere\nϵ = ϵ2 * b + ϵ1 * (1 .- b)\n\n\"setup\"\nboundaries = [Periodic(2), Periodic(3)]# unspecified boundaries default to PML\n# n = [1, 0, 0]\nmonitors = []\nsources = [\n PlaneWave(t -> cos(F(2π) * t), -1; Jz=1) # Jz excited plane wave from -x plane (eg -1)\n # PlaneWave(t -> t < 1 ? cos(F(2π) * t) : 0.0f0, -1; Jz=1)\n]\nconfigs = setup(boundaries, sources, monitors, dx, sz; F, Courant, T)\n@unpack μ, σ, σm, dt, geometry_padding, geometry_splits, field_padding, source_effects, monitor_instances, fields, power = configs\n\nϵ, μ, σ, σm = apply(geometry_padding; ϵ, μ, σ, σm)\np = apply(geometry_splits; ϵ, μ, σ, σm)\nu0 = collect(values(fields))\n\n# run simulation\nt = 0:dt:T\nsol = similar([u0], length(t))\n@showtime sol = accumulate!((u, t) -> step!(u, p, t, configs), sol, t, init=u0)\n\n# make movie\nEz = map(sol) do u\n u[3]\nend\nϵz = p[1][3]\ndir = @__DIR__\n° = π / 180\nrecordsim(Ez, ϵz, configs, \"$dir/$(name)_nres_$nres.mp4\", title=\"$name\"; elevation=30°, playback=1, bipolar=true)\n","category":"page"},{"location":"#Installation","page":"FDTDEngine.jl","title":"Installation","text":"","category":"section"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"Install via ","category":"page"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"Pkg.add(url=\"https://github.com/paulxshen/FDTDEngine.jl\")\nPkg.add(url=\"https://github.com/paulxshen/FDTDToolkit.jl\")","category":"page"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"FDTDToolkit.jl contains visualization utilities","category":"page"},{"location":"#Implementation","page":"FDTDEngine.jl","title":"Implementation","text":"","category":"section"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"Supports 1d (Ez, Hy), 2d TMz (Ez, Hx, Hy), 2d TEz (Hz, Ex, Ey) and 3d. Length and time are in units of wavelength and period. This normalization allows usage of relative permitivity and permeability in equations . Fields including electric, magnetic and current density are simply bundled as a vector of arrays . Boundary conditions pad the field arrays . PML paddings are multilayered, stateful and permanent, increasing size of field and geometry arrays. All other boundaries only add transient single layers which are subsequently consumed by finite differencing every update step. Paddings are coordinated to implictly implement staggered Yee's grid for finite differencing.","category":"page"},{"location":"#Sources","page":"FDTDEngine.jl","title":"Sources","text":"","category":"section"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"If a source has fewer nonzero dimensions than the simulation domain, its signal will get normalized along its singleton dimensions. For example, all planar sources in 3d or line sources in 2d will get scaled up by a factor of 1/dx. This way, discretisation would not affect radiated power.","category":"page"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"PlaneWave\nSource","category":"page"},{"location":"#PlaneWave","page":"FDTDEngine.jl","title":"PlaneWave","text":"function PlaneWave(f, dims; fields...)\n\nConstructs plane wave source\n\nArgs\n\nf: time function\ndims: eg -1 for wave coming from -x edge\nfields: which fields to excite & their scaling constants (typically a current source, eg Jz=1)\n\n\n\n\n\n","category":"type"},{"location":"#Source","page":"FDTDEngine.jl","title":"Source","text":"function Source(f, center, bounds; fields...)\nfunction Source(f, center, L::AbstractVector{<:Real}; fields...)\n\nConstructs custom source. Can be used to specify uniform or modal sources\n\nArgs\n\nf: time function\nL: source dimensions in [wavelengths]\nfields: which fields to excite & their scaling constants (typically a current source, eg Jz=1)\n\n\n\n\n\n","category":"type"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"","category":"page"},{"location":"#Boundaries","page":"FDTDEngine.jl","title":"Boundaries","text":"","category":"section"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"Unspecified boundaries default to PML ","category":"page"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"Periodic\nPML\nPEC\nPMC","category":"page"},{"location":"#Periodic","page":"FDTDEngine.jl","title":"Periodic","text":"Periodic(dims)\n\nperiodic boundary\n\n\n\n\n\n","category":"type"},{"location":"#PML","page":"FDTDEngine.jl","title":"PML","text":"function PML(dims, d=0.25f0, σ=20.0f0)\n\nConstructs perfectly matched layers (PML aka ABC, RBC) boundary of depth d wavelengths Doesn't need to be explictly declared as all unspecified boundaries default to PML\n\n\n\n\n\n","category":"type"},{"location":"#PEC","page":"FDTDEngine.jl","title":"PEC","text":"PEC(dims)\n\nperfect electrical conductor dims: eg -1 for -x side\n\n\n\n\n\n","category":"type"},{"location":"#PMC","page":"FDTDEngine.jl","title":"PMC","text":"PMC(dims)\n\nperfect magnetic conductor\n\n\n\n\n\n","category":"type"},{"location":"#Monitors","page":"FDTDEngine.jl","title":"Monitors","text":"","category":"section"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"Monitor","category":"page"},{"location":"#Monitor","page":"FDTDEngine.jl","title":"Monitor","text":"function Monitor(span, normal=nothing)\n\nConstructs monitor which can span a point, line, surface, or volume\n\nArgs\n\nspan\nnormal: flux monitor direction\n\n\n\n\n\n","category":"type"},{"location":"#Physics","page":"FDTDEngine.jl","title":"Physics","text":"","category":"section"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"step3!","category":"page"},{"location":"#step3!","page":"FDTDEngine.jl","title":"step3!","text":"function step3(u, p, t, configs)\n\nUpdates fields for 3d\n\n\n\n\n\n","category":"function"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":" ","category":"page"},{"location":"#Tutorials","page":"FDTDEngine.jl","title":"Tutorials","text":"","category":"section"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"see examples/","category":"page"},{"location":"#Generative-inverse-design","page":"FDTDEngine.jl","title":"Generative inverse design","text":"","category":"section"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"Please contact us for latest scripts.","category":"page"},{"location":"#Community","page":"FDTDEngine.jl","title":"Community","text":"","category":"section"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"Discussion & updates at Julia Discourse","category":"page"},{"location":"#Contributors","page":"FDTDEngine.jl","title":"Contributors","text":"","category":"section"},{"location":"","page":"FDTDEngine.jl","title":"FDTDEngine.jl","text":"Paul Shen ","category":"page"}]
}
diff --git a/examples/3d_dipole_antenna/3d_quarter_wavelength_antenna_nres_16.mp4 b/examples/3d_dipole_antenna/3d_quarter_wavelength_antenna_nres_16.mp4
index 6fcf978..7bc3da9 100644
Binary files a/examples/3d_dipole_antenna/3d_quarter_wavelength_antenna_nres_16.mp4 and b/examples/3d_dipole_antenna/3d_quarter_wavelength_antenna_nres_16.mp4 differ
diff --git a/examples/3d_periodic_scattering/3d_scattering_nres_16.mp4 b/examples/3d_periodic_scattering/3d_scattering_nres_16.mp4
index 0a71ef6..eeba144 100644
Binary files a/examples/3d_periodic_scattering/3d_scattering_nres_16.mp4 and b/examples/3d_periodic_scattering/3d_scattering_nres_16.mp4 differ
diff --git a/examples/inverse_design_3d_silicon_photonics_splitter/_nres_16.mp4 b/makedocs/inverse_design_3d_silicon_photonics_splitter/_nres_16.mp4
similarity index 100%
rename from examples/inverse_design_3d_silicon_photonics_splitter/_nres_16.mp4
rename to makedocs/inverse_design_3d_silicon_photonics_splitter/_nres_16.mp4
diff --git a/examples/inverse_design_3d_silicon_photonics_splitter/inverse_design_3d_silicon_photonics_splitter.jl b/makedocs/inverse_design_3d_silicon_photonics_splitter/inverse_design_3d_silicon_photonics_splitter.jl
similarity index 100%
rename from examples/inverse_design_3d_silicon_photonics_splitter/inverse_design_3d_silicon_photonics_splitter.jl
rename to makedocs/inverse_design_3d_silicon_photonics_splitter/inverse_design_3d_silicon_photonics_splitter.jl
diff --git a/examples/inverse_design_3d_silicon_photonics_splitter/layout.jl b/makedocs/inverse_design_3d_silicon_photonics_splitter/layout.jl
similarity index 100%
rename from examples/inverse_design_3d_silicon_photonics_splitter/layout.jl
rename to makedocs/inverse_design_3d_silicon_photonics_splitter/layout.jl
diff --git a/examples/inverse_design_3d_silicon_photonics_splitter/mode.bson b/makedocs/inverse_design_3d_silicon_photonics_splitter/mode.bson
similarity index 100%
rename from examples/inverse_design_3d_silicon_photonics_splitter/mode.bson
rename to makedocs/inverse_design_3d_silicon_photonics_splitter/mode.bson
diff --git a/examples/inverse_design_3d_silicon_photonics_splitter/model b/makedocs/inverse_design_3d_silicon_photonics_splitter/model
similarity index 100%
rename from examples/inverse_design_3d_silicon_photonics_splitter/model
rename to makedocs/inverse_design_3d_silicon_photonics_splitter/model
diff --git a/examples/inverse_design_3d_silicon_photonics_splitter/post_training_nres_16.mp4 b/makedocs/inverse_design_3d_silicon_photonics_splitter/post_training_nres_16.mp4
similarity index 100%
rename from examples/inverse_design_3d_silicon_photonics_splitter/post_training_nres_16.mp4
rename to makedocs/inverse_design_3d_silicon_photonics_splitter/post_training_nres_16.mp4
diff --git a/examples/inverse_design_3d_silicon_photonics_splitter/pre_training_nres_16.mp4 b/makedocs/inverse_design_3d_silicon_photonics_splitter/pre_training_nres_16.mp4
similarity index 100%
rename from examples/inverse_design_3d_silicon_photonics_splitter/pre_training_nres_16.mp4
rename to makedocs/inverse_design_3d_silicon_photonics_splitter/pre_training_nres_16.mp4
diff --git a/examples/inverse_design_3d_silicon_photonics_splitter/silicon_photonics_splitter_nres_16.mp4 b/makedocs/inverse_design_3d_silicon_photonics_splitter/silicon_photonics_splitter_nres_16.mp4
similarity index 100%
rename from examples/inverse_design_3d_silicon_photonics_splitter/silicon_photonics_splitter_nres_16.mp4
rename to makedocs/inverse_design_3d_silicon_photonics_splitter/silicon_photonics_splitter_nres_16.mp4
diff --git a/examples/inverse_design_3d_silicon_photonics_splitter/vis.jl b/makedocs/inverse_design_3d_silicon_photonics_splitter/vis.jl
similarity index 100%
rename from examples/inverse_design_3d_silicon_photonics_splitter/vis.jl
rename to makedocs/inverse_design_3d_silicon_photonics_splitter/vis.jl
diff --git a/examples/inverse_design_3d_silicon_photonics_splitter/waveguide_bend_nres_16.mp4 b/makedocs/inverse_design_3d_silicon_photonics_splitter/waveguide_bend_nres_16.mp4
similarity index 100%
rename from examples/inverse_design_3d_silicon_photonics_splitter/waveguide_bend_nres_16.mp4
rename to makedocs/inverse_design_3d_silicon_photonics_splitter/waveguide_bend_nres_16.mp4
diff --git a/makedocs/make.jl b/makedocs/make.jl
index 6c2dbfa..a8a93ce 100644
--- a/makedocs/make.jl
+++ b/makedocs/make.jl
@@ -3,7 +3,7 @@ include("../src/FDTDEngine.jl")
using .FDTDEngine
makedocs(
- sitename="FDTDEngine",
+ sitename="FDTDEngine.jl",
format=Documenter.HTML(),
# modules=[FDTDEngine],
pages=[
diff --git a/makedocs/src/index.md b/makedocs/src/index.md
index d7bfe8d..2bc4ee4 100644
--- a/makedocs/src/index.md
+++ b/makedocs/src/index.md
@@ -15,21 +15,15 @@ In progress, split ratio isn't correct
## Quickstart
We do a quick 3d simulation of plane wave scattering on periodic array of dielectric spheres (first gallery movie)
```julia
-"""
-simulation of plane wave scattering on periodic array of dielectric spheres
-"""
-
using UnPack, LinearAlgebra, GLMakie
-using FDTDEngine
-include("$(pwd())/scripts/plot_recipes.jl")
-
+using FDTDEngine,FDTDToolkit
F = Float32
name = "3d_scattering"
-T = 4.0f0 # simulation duration in [periods]
+T = 8.0f0 # simulation duration in [periods]
nres = 16
dx = 1.0f0 / nres # pixel resolution in [wavelengths]
-Courant = 0.25f0 # Courant number
+Courant = 0.8 / √3 # Courant number
"geometry"
l = 2 # domain physical size length
@@ -48,14 +42,16 @@ sources = [
# PlaneWave(t -> t < 1 ? cos(F(2π) * t) : 0.0f0, -1; Jz=1)
]
configs = setup(boundaries, sources, monitors, dx, sz; F, Courant, T)
-@unpack μ, σ, σm, dt, geometry_padding, geometry_splits, field_padding, source_effects, monitor_instances, fields, step, power = configs
+@unpack μ, σ, σm, dt, geometry_padding, geometry_splits, field_padding, source_effects, monitor_instances, fields, power = configs
ϵ, μ, σ, σm = apply(geometry_padding; ϵ, μ, σ, σm)
p = apply(geometry_splits; ϵ, μ, σ, σm)
u0 = collect(values(fields))
# run simulation
-@showtime sol = accumulate((u, t) -> step(u, p, t, configs), 0:dt:T, init=u0)
+t = 0:dt:T
+sol = similar([u0], length(t))
+@showtime sol = accumulate!((u, t) -> step!(u, p, t, configs), sol, t, init=u0)
# make movie
Ez = map(sol) do u
@@ -63,11 +59,18 @@ Ez = map(sol) do u
end
ϵz = p[1][3]
dir = @__DIR__
-recordsim(Ez, ϵz, configs, "$dir/$(name)_nres_$nres.mp4", title="$name"; playback=1, bipolar=true)
+° = π / 180
+recordsim(Ez, ϵz, configs, "$dir/$(name)_nres_$nres.mp4", title="$name"; elevation=30°, playback=1, bipolar=true)
```
## Installation
-Install via `Pkg.add(url="https://github.com/paulxshen/FDTDEngine.jl")`. You can additionally access plotting and movie making scripts via `include("_your_path/scripts/plot_recipes.jl")`
+Install via
+```
+Pkg.add(url="https://github.com/paulxshen/FDTDEngine.jl")
+Pkg.add(url="https://github.com/paulxshen/FDTDToolkit.jl")
+```
+`FDTDToolkit.jl` contains visualization utilities
+
## Implementation
Supports 1d (Ez, Hy), 2d TMz (Ez, Hx, Hy), 2d TEz (Hz, Ex, Ey) and 3d. Length and time are in units of wavelength and period. This normalization allows usage of relative permitivity and permeability in equations . Fields including electric, magnetic and current density are simply bundled as a vector of arrays . Boundary conditions pad the field arrays . PML paddings are multilayered, stateful and permanent, increasing size of field and geometry arrays. All other boundaries only add transient single layers which are subsequently consumed by finite differencing every update step. Paddings are coordinated to implictly implement staggered Yee's grid for finite differencing.
@@ -94,11 +97,11 @@ Monitor
## Physics
```@docs
-step1
-stepTMz
-stepTEz
-step3
+step3!
```
+
+
+
## Tutorials
see `examples/`
diff --git a/src/FDTDEngine.jl b/src/FDTDEngine.jl
index d7bad7f..bf201fb 100644
--- a/src/FDTDEngine.jl
+++ b/src/FDTDEngine.jl
@@ -1,7 +1,8 @@
module FDTDEngine
include("main.jl")
export reindex, sandwich
-export Del, stepTMz, step1, step3, stepTEz
+export Del, step3!, step!
+# stepTMz, step1, , stepTEz
export Periodic, PML, PEC, PMC, Padding
export PlaneWave, GaussianBeam, UniformSource, Source, place
export Monitor
diff --git a/src/sources.jl b/src/sources.jl
index c511c32..e910fa5 100644
--- a/src/sources.jl
+++ b/src/sources.jl
@@ -107,7 +107,7 @@ function SourceEffect(s::PlaneWave, dx, sizes, starts, sz0)
starts[k] .+ (dims < 0 ? 0 : [i == abs(dims) ? sizes[k][i] - 1 : 0 for i = 1:d])
for k = keys(starts)])
_g = Dict([k => place(zeros(F, sizes[k]), g[k], starts[k]) for k = keys(fields)])
- center = NamedTuple([k => round.(Int, starts[k] .+ size(g[k]) ./ 2) for k = keys(starts)])
+ center = NamedTuple([k => round.(Int, starts[k] .+ size(first(values(g))) ./ 2) for k = keys(starts)])
SourceEffect(f, g, _g, fields, starts, center, label)
end
@@ -122,7 +122,7 @@ function SourceEffect(s::GaussianBeam, dx, sizes, starts, stop)
SourceEffect(f, g, _g, fields, start)
end
function SourceEffect(s::Source, dx, sizes, starts, stop)
- @unpack f, fields, center, bounds = s
+ @unpack f, fields, center, bounds, label = s
# R = round.(Int, L ./ 2 / dx)
# I = range.(-R, R)
# I = [round(Int, a / dx):round(Int, b / dx) for (a, b) = bounds]
@@ -132,7 +132,8 @@ function SourceEffect(s::Source, dx, sizes, starts, stop)
o = -1 .+ index(center, dx) .- round.(Int, (length.(I) .- 1) ./ 2)
starts = NamedTuple([k => starts[k] .+ o for k = keys(starts)])
_g = Dict([k => place(zeros(F, sizes[k]), g[k], starts[k]) for k = keys(fields)])
- SourceEffect(f, g, _g, fields, starts)
+ center = NamedTuple([k => round.(Int, starts[k] .+ size(first(values(g))) ./ 2) for k = keys(starts)])
+ SourceEffect(f, g, _g, fields, starts, center, label)
# n = max.(1, round.(Int, L ./ dx))
# g = ones(n...) / dx^count(L .== 0)
# start = start .+ round.(Int, center ./ dx .- (n .- 1) ./ 2)