Scheme¶
You can find these Scheme scripts here.
Gauss beam in 2d¶
;;-------------------------------------------------------------------------------------------------
;; file: Gauss2d.ctl
;; brief: Scheme configuration input file for the FDTD solver Meep simulating the scattering of a
;; Gaussian beam at planar and curved dielectric interfaces
;; author: Daniel Kotik
;; version: 1.2.0
;; date: 28.11.2019
;;
;; example invocations: a) launch the serial version of meep with specified polarisation (p)
;;
;; meep s-pol\?=false Gauss2d.ctl
;;
;; b) launch the parallel version of meep using 8 cores with specified interface (concave)
;;
;; mpirun -quiet -np 8 meep-mpi interface='"concave"' Gauss2d.ctl
;;
;; coordinate system in meep (defines center of computational cell): --|-----> x
;; |
;; |
;; v y
;;
;; example visualisations (square brackets contain optional arguments for overlaying the dielectric function):
;;
;; h5topng -S2 -c hot [-a yarg -A eps-000000000.h5] e2_s-000003696.h5
;; h5topng -S2 -Zc dkbluered [-a gray -A eps-000000000.h5] ez-000003696.h5
;;
;;------------------------------------------------------------------------------------------------
(print "\nstart time: "(strftime "%c" (localtime (current-time))) "\n")
;;------------------------------------------------------------------------------------------------
;; physical parameters characterizing light source and interface characteristics
;; (must be adjusted - either here or via command line)
;;------------------------------------------------------------------------------------------------
(define-input-var interface "planar" ; specify type of interface
'string (lambda type (or (string=? type "planar" )
(string=? type "concave")
(string=? type "convex" ))))
(define-param s-pol? true ) ; true for s-spol, false for p-pol
(define-param ref_medium 0) ; reference medium whose wavenumber is used as inverse scaling length
; (0 - free space, 1 - incident medium, 2 - refracted medium)
; k is then equivalent to k_ref_medium: k_1 = k_0*n_1 or k_2 = k_0*n_2
(define-param n1 1.54) ; index of refraction of the incident medium
(define-param n2 1.00) ; index of refraction of the refracted medium
(define-param kw_0 8) ; beam width (>5 is good)
(define-param kr_w 60) ; beam waist distance to interface (30 to 50 is good if
; source position coincides with beam waist)
(define-param kr_c 150) ; radius of curvature (if interface is either concave of convex)
(define (Critical n1 n2) ; calculates the critical angle in degrees
(cond
((> n1 n2) (* (/ (asin (/ n2 n1)) (* 2.0 pi)) 360.0))
((< n1 n2) (print "\nWarning: Critical angle is not defined, since n1 < n2!\n\n") (exit))
((= n1 n2) (print "\nWarning: Critical angle is not defined, since n1 = n2!\n\n") (exit))
))
(define (Brewster n1 n2) ; calculates the Brewster angle in degrees
(* (/ (atan (/ n2 n1)) (* 2.0 pi)) 360.0))
;; define incidence angle relative to the Brewster or critical angle, or set it explicitly (in degrees)
;(define-param chi_deg (* 0.85 (Brewster n1 n2)))
;(define-param chi_deg (* 0.99 (Critical n1 n2)))
(define-param chi_deg 45.0)
;;------------------------------------------------------------------------------------------------
;; specific Meep paramters (may need to be adjusted - either here or via command line)
;;------------------------------------------------------------------------------------------------
(define-param sx 5) ; size of cell including PML in x-direction
(define-param sy 5) ; size of cell including PML in y-direction
(define-param pml_thickness 0.25) ; thickness of PML layer
(define-param freq 12) ; vacuum frequency of source (5 to 12 is good)
(define-param runtime 10) ; runs simulation for 10 times freq periods
(define-param pixel 10) ; number of pixels per wavelength in the denser
; medium (at least 10, 20 to 30 is a good choice)
(define-param source_shift -2.15) ; source position with respect to the center (point of impact) in Meep
;(define-param source_shift (* -1.0 rw)) ; units (-2.15 good); if equal -rw, then source position coincides with
; waist position
(define-param relerr 0.0001) ; relative error for integration routine (0.0001 or smaller)
;;------------------------------------------------------------------------------------------------
;; derived Meep parameters (do not change)
;;------------------------------------------------------------------------------------------------
(define k_vac (* 2.0 pi freq))
(define k1 (* n1 k_vac )) ; wave number inside the incident medium
(define n_ref (cond ((= ref_medium 0) 1.0) ; index of refraction of the reference medium
((= ref_medium 1) n1)
((= red_medium 2) n2)))
(define rw (/ kr_w (* n_ref k_vac)))
(define w_0 (/ kw_0 (* n_ref k_vac)))
(define r_c (/ kr_c (* n_ref k_vac)))
(define shift (+ source_shift rw)) ; distance from source position to beam waist (along y-axis)
;;------------------------------------------------------------------------------------------------
;; placement of the dielectric interface within the computational cell
;;------------------------------------------------------------------------------------------------
;; helper functions
(define (alpha _chi_deg) ; angle of inclined plane with y-axis
(- (/ pi 2.0) (* (/ _chi_deg 360) 2 pi)))
(define (Delta_x _alpha) ; inclined plane offset to the center of the cell
(* (/ sx 2.0) (/ (-(- (sqrt 2.0) (cos _alpha)) (sin _alpha)) (sin _alpha))))
(define (chi_rad _chi_deg) ; conversion degrees to radians
(* (/ _chi_deg 360.0) (* 2.0 pi)))
(set! geometry-lattice (make lattice (size sx sy no-size)))
(cond
((string=? interface "planar")
(set! default-material (make dielectric (index n1)))
(set! geometry (list
(make block ; located at lower right edge for 45 degree tilt
(center (+ (/ sx 2.0) (Delta_x (alpha chi_deg))) (/ sy -2.0))
(size infinity (* (sqrt 2.0) sx) infinity)
(e1 (/ 1.0 (tan (alpha chi_deg))) 1 0)
(e2 -1 (/ 1.0 (tan (alpha chi_deg))) 0)
(e3 0 0 1)
(material (make dielectric (index n2)))))
))
((string=? interface "concave")
(set! default-material (make dielectric (index n2)))
(set! geometry (list
(make cylinder
(center (* -1 (* r_c (cos (chi_rad chi_deg)))) (* r_c (sin (chi_rad chi_deg))))
; move center to the right in order to ensure that the point of impact is
; always centrally placed
(height infinity)
(radius r_c)
(material (make dielectric (index n1)))))
))
((string=? interface "convex" )
(set! default-material (make dielectric (index n1)))
(set! geometry (list
(make cylinder
(center (* r_c (cos (chi_rad chi_deg))) (* -1.0 (* r_c (sin (chi_rad chi_deg)))))
; move center to the right in order to ensure that the point of impact is
; always centrally placed
(height infinity)
(radius r_c)
(material (make dielectric (index n2)))))
))
)
;;------------------------------------------------------------------------------------------------
;; add absorbing boundary conditions and discretize structure
;;------------------------------------------------------------------------------------------------
(set! pml-layers
(list (make pml (thickness pml_thickness))))
(set! resolution ; set resolution in pixels per Meep distance unit
(* pixel (* (if (> n1 n2) n1 n2) freq)))
(set! Courant ; set Courant factor (mandatory if either n1 or n2 is smaller than 1)
(/ (if (< n1 n2) n1 n2) 2))
;;------------------------------------------------------------------------------------------------
;; beam profile distribution(s) (field amplitude) at the waist of the beam
;;------------------------------------------------------------------------------------------------
(define (Gauss W_y)
(lambda (r) (exp (* -1.0 (expt (/ (vector3-y r) W_y) 2.0)))
))
;(define (Asymmetric W_y)
; (lambda (r) ...
; ))
;;------------------------------------------------------------------------------------------------
;; spectrum amplitude distribution(s)
;;------------------------------------------------------------------------------------------------
(define (f_Gauss W_y)
(lambda (k_y) (exp (* -1.0 (expt (* 0.5 k_y W_y) 2.0)))
))
;(define (f_asymmetric W_y)
; (lambda (k_y) ...
; ))
;;------------------------------------------------------------------------------------------------
;; plane wave decomposition
;; (purpose: calculate field amplitude at light source position if not coinciding with beam waist)
;;------------------------------------------------------------------------------------------------
(define (integrand f x y)
(lambda (k_y) (* (f k_y)
(exp (* 0+1i x (sqrt (- (* k1 k1) (* k_y k_y)))))
(exp (* 0+1i k_y y)))
))
;; complex field amplitude at position (x, y) with spectrum amplitude distribution f
;; (one may have to adjust the 'relerr' parameter value in the integrate function)
(define (psi f x)
(lambda (r) (car (integrate (integrand f x (vector3-y r))
(* -1.0 k1) (* 1.0 k1) relerr))
))
;;------------------------------------------------------------------------------------------------
;; display values of physical variables
;;------------------------------------------------------------------------------------------------
(print "\n")
(print "Specified variables and derived values: \n")
(print "chi: " chi_deg " [degree]\n") ; angle of incidence
(print "incl.: " (- 90 chi_deg) " [degree]\n") ; interface inclination with respect to the x-axis
(print "kw_0: " kw_0 "\n")
(print "kr_w: " kr_w "\n")
(if (not (string=? interface "planar")) (print "kr_c: " kr_c "\n"))
(print "k_vac: " k_vac "\n")
(print "polarisation: " (if s-pol? "s" "p") "\n")
(print "interface: " interface "\n")
(print "\n")
;(print "spectrum amplitude: " ((f_Gauss w_0) 20.0) "\n")
;(print "integrand: " ((integrand (f_Gauss w_0) 0.8 2.0) 20.0) "\n")
;(print "field amplitude: " ((psi (f_Gauss w_0) 0.8) (vector3 0 0.2 0)) "\n")
;(exit)
;;------------------------------------------------------------------------------------------------
;; specify current source, output functions and run simulation
;;------------------------------------------------------------------------------------------------
(use-output-directory interface) ; put output files in a separate folder
(set! force-complex-fields? false) ; default: false
(set! eps-averaging? true) ; default: true
(set! sources (list
(make source
(src (make continuous-src (frequency freq) (width 0.5)))
(if s-pol? (component Ez) (component Ey))
(size 0 2.0 0)
(center source_shift 0 0)
;(amp-func (Gauss w_0)))
;(amp-func (Asymmetric (/ w_0 (sqrt 3.0)))))
(amp-func (psi (f_Gauss w_0) shift)))
))
;; calculates |E|^2 with |.| denoting the complex modulus if 'force-complex-fields?' is set to true, otherwise |.|
;; gives the Euclidean norm
(define (eSquared r ex ey ez)
(+ (expt (magnitude ex) 2) (expt (magnitude ey) 2) (expt (magnitude ez) 2)))
(define (output-efield2) (output-real-field-function (if s-pol? "e2_s" "e2_p")
(list Ex Ey Ez) eSquared))
(run-until runtime
(at-beginning (lambda () (print "\nCalculating inital field configuration. This will take some time...\n\n")))
(at-beginning output-epsilon) ; output of dielectric function
(if s-pol?
(at-end output-efield-z) ; output of E_z component (for s-polarisation)
(at-end output-efield-y)) ; output of E_y component (for p-polarisation)
(at-end output-efield2) ; output of electric field intensity
)
(print "\nend time: "(strftime "%c" (localtime (current-time))) "\n")
Airy beam in 2d¶
;;-------------------------------------------------------------------------------------------------
;; file: Airy2d.ctl
;; brief: Scheme configuration input file for the FDTD solver Meep simulating the scattering of an
;; incomplete Airy beam at a planar dielectric interface
;; author: Daniel Kotik
;; version: 1.2.0
;; date: 28.11.2019
;;
;; example invocations: a) launch the serial version of meep with specified polarisation (p)
;;
;; meep s-pol\?=false Airy2d.ctl
;;
;; b) launch the parallel version of meep using 8 cores
;;
;; mpirun -quiet -np 8 meep-mpi Airy2d.ctl
;;
;; coordinate system in meep (defines center of computational cell): --|-----> x
;; |
;; |
;; v y
;;
;; example visualisation (square brackets contain optional arguments for overlaying the dielectric function):
;;
;; h5topng -S2 -X scalex -c hot [-a yarg -A eps-000000000.h5] e2_s-000003696.h5
;;
;; (if necessary, scale the x dimension of the image by scalex)
;;------------------------------------------------------------------------------------------------
(print "\nstart time: "(strftime "%c" (localtime (current-time))) "\n")
;;------------------------------------------------------------------------------------------------
;; physical parameters characterizing light source and interface characteristics
;; (must be adjusted - either here or via command line)
;;------------------------------------------------------------------------------------------------
(define-param s-pol? true ) ; true for s-spol, false for p-pol
(define-param ref_medium 0) ; reference medium whose wavenumber is used as inverse scaling length
; (0 - free space, 1 - incident medium, 2 - refracted medium)
; k is then equivalent to k_ref_medium: k_1 = k_0*n_1 or k_2 = k_0*n_2
(define-param n1 1.00) ; index of refraction of the incident medium
(define-param n2 0.65) ; index of refraction of the refracted medium
(define-param kw_0 7) ; beam width (>5 is good)
(define-param kr_w 0) ; beam waist distance to interface (30 to 50 is good if
; source position coincides with beam waist)
(define-param M 0) ; center of integration window
(set-param! W 4) ; width of integration window
(define (Critical n1 n2) ; calculates the critical angle in degrees
(cond
((> n1 n2) (* (/ (asin (/ n2 n1)) (* 2.0 pi)) 360.0))
((< n1 n2) (print "\nWarning: Critical angle is not defined, since n1 < n2!\n\n") (exit))
((= n1 n2) (print "\nWarning: Critical angle is not defined, since n1 = n2!\n\n") (exit))
))
(define (Brewster n1 n2) ; calculates the Brewster angle in degrees
(* (/ (atan (/ n2 n1)) (* 2.0 pi)) 360.0))
;; define incidence angle relative to the Brewster or critical angle, or set it explicitly (in degrees)
;(define-param chi_deg (* 0.85 (Brewster n1 n2)))
;(define-param chi_deg (* 1.0 (Critical n1 n2)))
(define-param chi_deg 45.0)
;;------------------------------------------------------------------------------------------------
;; specific Meep paramters (may need to be adjusted - either here or via command line)
;;------------------------------------------------------------------------------------------------
(define-param sx 10) ; size of cell including PML in x-direction
(define-param sy 10) ; size of cell including PML in y-direction
(define-param pml_thickness 0.25) ; thickness of PML layer
(define-param freq 12) ; vacuum frequency of source (4 to 12 is good)
(define-param runtime 90) ; runs simulation for X times freq periods
(define-param pixel 15) ; number of pixels per wavelength in the denser medium
; (at least 10, 20 to 30 is a good choice)
;(define-param source_shift 0) ; source position with respect to the center (point of impact) in Meep
;(define-param source_shift (* -1.0 rw)) ; units (-2.15 good); if equal -rw, then source position coincides with
; waist position
(define-param source_shift (* -0.4 (- sx (* 2 pml_thickness))))
(define-param relerr 1.0e-5) ; relative error for integration routine (1.0e-4 or smaller)
;;------------------------------------------------------------------------------------------------
;; derived Meep parameters (do not change)
;;------------------------------------------------------------------------------------------------
(define k_vac (* 2.0 pi freq))
(define k1 (* n1 k_vac )) ; wave number inside the incident medium
(define n_ref (cond ((= ref_medium 0) 1.0) ; index of refraction of the reference medium
((= ref_medium 1) n1)
((= red_medium 2) n2)))
(define rw (/ kr_w (* n_ref k_vac)))
(define w_0 (/ kw_0 (* n_ref k_vac)))
(define shift (+ source_shift rw)) ; distance from source position to beam waist (along y-axis)
;;------------------------------------------------------------------------------------------------
;; placement of the dielectric interface within the computational cell
;;------------------------------------------------------------------------------------------------
;; helper functions
(define (alpha _chi_deg) ; angle of inclined plane with y-axis
(- (/ pi 2.0) (* (/ _chi_deg 360) 2 pi)))
(define (Delta_x _alpha) ; inclined plane offset to the center of the cell
(* (/ sx 2.0) (/ (-(- (sqrt 2.0) (cos _alpha)) (sin _alpha)) (sin _alpha))))
(define (chi_rad _chi_deg) ; conversion degrees to radians
(* (/ _chi_deg 360.0) (* 2.0 pi)))
(set! geometry-lattice (make lattice (size sx sy no-size)))
(set! default-material (make dielectric (index n1)))
(set! geometry (list
(make block ; located at lower right edge for 45 degree tilt
(center (+ (/ sx 2.0) (Delta_x (alpha chi_deg))) (/ sy -2.0))
(size infinity (* (sqrt 2.0) sx) infinity)
(e1 (/ 1.0 (tan (alpha chi_deg))) 1 0)
(e2 -1 (/ 1.0 (tan (alpha chi_deg))) 0)
(e3 0 0 1)
(material (make dielectric (index n2))))
))
;;------------------------------------------------------------------------------------------------
;; add absorbing boundary conditions and discretize structure
;;------------------------------------------------------------------------------------------------
(set! pml-layers
(list (make pml (thickness pml_thickness))))
(set! resolution ; set resolution in pixels per Meep distance unit
(* pixel (* (if (> n1 n2) n1 n2) freq)))
(set! Courant ; set Courant factor (mandatory if either n1 or n2 is smaller than 1)
(/ (if (< n1 n2) n1 n2) 2))
;;------------------------------------------------------------------------------------------------
;; beam profile distribution (field amplitude) at the waist of the beam
;;------------------------------------------------------------------------------------------------
(define (Gauss W_y)
(lambda (r) (exp (* -1.0 (expt (/ (vector3-y r) W_y) 2.0)))
))
;; incomplete Airy function
(define (Ai_inc W_y M W)
(lambda (r) (car
(integrate (lambda (xi) (exp (* 0+1i (+ (* (/ -1 3) (expt xi 3)) (* xi (/ (vector3-y r) W_y))))))
(- M W) (+ M W) relerr))
))
;; simple test outputs
;(print "w_0: " w_0 "\n")
;(print "Airy function 1: " ((Ai_inc w_0 0 4) (vector3 1 -0.3 1)) "\n")
;(exit)
;;------------------------------------------------------------------------------------------------
;; spectrum amplitude distribution
;;------------------------------------------------------------------------------------------------
(define Heaviside
(lambda (x) (cond ((< x 0) 0) ((>= x 0) 1))
))
(define (f_Gauss W_y)
(lambda (k_y) (exp (* -1.0 (expt (* 0.5 k_y W_y) 2)))
))
(define (f_Airy W_y M W)
(lambda (k_y) (* W_y (exp (* 0+1i (* (/ -1 3) (expt (* k_y W_y) 3))))
(Heaviside (- (* W_y k_y) (- M W))) (Heaviside (- (+ M W) (* W_y k_y))))
))
;; simple test outputs
;(print "Airy spectrum: " ((f_Airy w_0 0 4) 0.2) "\n")
;(exit)
;;------------------------------------------------------------------------------------------------
;; plane wave decomposition
;; (purpose: calculate field amplitude at light source position if not coinciding with beam waist)
;;------------------------------------------------------------------------------------------------
(define (integrand f x y)
(lambda (k_y) (* (f k_y)
(exp (* 0+1i x (sqrt (- (* k1 k1) (* k_y k_y)))))
(exp (* 0+1i k_y y)))
))
;; complex field amplitude at position (x, y) with spectrum amplitude distribution f
;; (one may have to adjust the 'relerr' parameter value in the integrate function)
(define (psi f x)
(lambda (r) (car (integrate (integrand f x (vector3-y r))
(* -1.0 k1) (* 1.0 k1) relerr))
))
;(print "Airy function 2: " ((psi (f_Airy w_0 0 4) 0) (vector3 1 -0.3 1)) "\n")
;(exit)
;;------------------------------------------------------------------------------------------------
;; display values of physical variables
;;------------------------------------------------------------------------------------------------
(print "\n")
(print "Specified variables and derived values: \n")
(print "chi: " chi_deg " [degree]\n") ; angle of incidence
(print "incl.: " (- 90 chi_deg) " [degree]\n") ; interface inclination with respect to the x-axis
(print "kw_0: " kw_0 "\n")
(print "kr_w: " kr_w "\n")
(print "k_vac: " k_vac "\n")
(print "polarisation: " (if s-pol? "s" "p") "\n")
(print "\n")
;;------------------------------------------------------------------------------------------------
;; specify current source, output functions and run simulation
;;------------------------------------------------------------------------------------------------
(use-output-directory) ; put output files in a separate folder
(set! force-complex-fields? false) ; default: false
(set! eps-averaging? true) ; default: true
(set! sources (list
(make source
(src (make continuous-src (frequency freq) (width 0.5)))
(if s-pol? (component Ez) (component Ey))
(size 0 9 0)
(center source_shift 0 0)
;(amp-func (Gauss w_0)))
;(amp-func (Ai_inc w_0 M W)))
(amp-func (psi (f_Airy w_0 M W) shift)))
))
;; calculates |E|^2 with |.| denoting the complex modulus if 'force-complex-fields?' is set to true, otherwise |.|
;; gives the Euclidean norm
(define (eSquared r ex ey ez)
(+ (expt (magnitude ex) 2) (expt (magnitude ey) 2) (expt (magnitude ez) 2)))
(define (output-efield2) (output-real-field-function (if s-pol? "e2_s" "e2_p")
(list Ex Ey Ez) eSquared))
(run-until runtime
(at-beginning (lambda () (print "\nCalculating inital field configuration. This will take some time...\n\n")))
(at-beginning output-epsilon) ; output of dielectric function
(if s-pol?
(at-end output-efield-z) ; output of E_z component (for s-polarisation)
(at-end output-efield-y)) ; output of E_y component (for p-polarisation)
(at-end output-efield2)) ; output of electric field intensity
(print "\nend time: "(strftime "%c" (localtime (current-time))) "\n")
Laguerre-Gauss beam¶
;;-------------------------------------------------------------------------------------------------
;; file: LaguerreGauss3d.ctl
;; brief: Scheme configuration input file for the FDTD solver Meep simulating the scattering of a polarised
;; Laguerre-Gaussian beam at a planar dielectric interface (3d)
;; author: Daniel Kotik
;; version: 1.2.0
;; date: 28.11.2019
;;
;; example invocations: a) launch the serial version of meep with specified polarisation (p)
;;
;; meep e_z=0 e_y=1 LaguerreGauss3d.ctl
;;
;; b) launch the parallel version of meep using 8 cores
;;
;; mpirun -quiet -np 8 meep-mpi LaguerreGauss3d.ctl
;;
;; coordinate system in meep (defines center of computational cell): --|-----> x
;; |
;; |
;; v y
;;
;; example visualisations:
;; - slice within the plane of incidence (x-y plane)
;; h5topng -S2 -0 -z 0 -c hot [HDF5FILE]
;;
;; - slice transversal to the incident propagation axis (INDEX specifies slice index)
;; h5topng -S2 -x INDEX -c hot [HDF5FILE]
;;
;; - full 3D simulation (creating a VTK file to be opened e.g., with MayaVi or ParaView)
;; h5tovtk [HDF5FILE]
;;
;; As input HDF5FILE choose between, for example, 'e_real2_p-000001500.h5', 'e_imag2_p-000001500.h5' (these are
;; proportional to the electric field energy density) or the sum of both 'e2.h5' (which is proportional to the complex
;; modulus of the complex electric field) obtained by
;; h5math -e "d1 + d2" e2.h5 e_real2_p-000001500.h5 e_imag2_p-000001500.h5
;;
;;------------------------------------------------------------------------------------------------
(print "\nstart time: "(strftime "%c" (localtime (current-time))) "\n")
;;------------------------------------------------------------------------------------------------
;; physical parameters characterizing light source and interface characteristics
;; (must be adjusted - either here or via command line)
;;------------------------------------------------------------------------------------------------
(define-param e_z 1) ; z-component of Jones vector (s-polarisation: e_z = 1, e_y = 0)
(define-param e_y 0) ; y-component of Jones vector (p-polarisation: e_z = 0, e_y = 1)
; (circular-polarisation: e_z = (/ 1+1i 2),
; e_y = (/ 1-1i 2))
(define-param m_charge 2) ; vortex charge (azimuthal quantum number, integer number)
(define-param ref_medium 0) ; reference medium whose wavenumber is used as inverse scaling length
; (0 - free space, 1 - incident medium, 2 - refracted medium)
; k is then equivalent to k_ref_medium: k_1 = k_0*n_1 or k_2 = k_0*n_2
(define-param n1 1.00) ; index of refraction of the incident medium
(define-param n2 1.54) ; index of refraction of the refracted medium
(define-param kw_0 8) ; beam width (>5 is good)
(define-param kr_w 0) ; beam waist distance to interface (30 to 50 is good if
; source position coincides with beam waist)
(define (Critical n1 n2) ; calculates the critical angle in degrees
(cond
((> n1 n2) (* (/ (asin (/ n2 n1)) (* 2.0 pi)) 360.0))
((< n1 n2) (print "\nWarning: Critical angle is not defined, since n1 < n2!\n\n") (exit))
((= n1 n2) (print "\nWarning: Critical angle is not defined, since n1 = n2!\n\n") (exit))
))
(define (Brewster n1 n2) ; calculates the Brewster angle in degrees
(* (/ (atan (/ n2 n1)) (* 2.0 pi)) 360.0))
;; define incidence angle relative to the Brewster or critical angle, or set it explicitly (in degrees)
;(define-param chi_deg (* 0.85 (Brewster n1 n2)))
;(define-param chi_deg (* 0.99 (Critical n1 n2)))
(define-param chi_deg 45.0)
;;------------------------------------------------------------------------------------------------
;; specific Meep paramters (may need to be adjusted - either here or via command line)
;;------------------------------------------------------------------------------------------------
(define-param sx 5) ; size of cell including PML in x-direction
(define-param sy 5) ; size of cell including PML in y-direction
(define-param sz 4) ; size of cell including PML in z-direction
(define-param pml_thickness 0.25) ; thickness of PML layer
(define-param freq 5) ; vacuum frequency of source (default 5)
(define-param runtime 10) ; runs simulation for 10 times freq periods
(define-param pixel 10) ; number of pixels per wavelength in the denser
; medium (at least 10, 20 to 30 is a good choice)
(define-param source_shift -2.15) ; source position with respect to the center (point of impact) in Meep
;(define-param source_shift (* -1.0 r_w)) ; units (-2.15 good); if equal -r_w, then source position coincides with
; waist position
(define-param relerr 0.0001) ; relative error for integration routine (0.0001 or smaller)
(define-param maxeval 10000) ; maximum evaluations for integration routine (we recommend 1000 for testing
; purposes and 10000 or higher for a final simulation run)
;;------------------------------------------------------------------------------------------------
;; derived Meep parameters (do not change)
;;------------------------------------------------------------------------------------------------
(define k_vac (* 2.0 pi freq)) ; vacuum wave number
(define k1 (* n1 k_vac )) ; wave number inside the incident medium
(define n_ref (cond ((= ref_medium 0) 1.0) ; index of refraction of the reference medium
((= ref_medium 1) n1)
((= red_medium 2) n2)))
(define r_w (/ kr_w (* n_ref k_vac)))
(define w_0 (/ kw_0 (* n_ref k_vac)))
(define shift (+ source_shift r_w)) ; distance from source position to beam waist (along y-axis)
(define s-pol? ; true if s-polarised
(if (and (= e_z 1 ) (= e_y 0 )) true false))
(define p-pol? ; true if p-polarised
(if (and (= e_z 0 ) (= e_y 1 )) true false))
(define a-pol? ; true if arbitrary (complex) polarised
(if (and (not s-pol?) (not p-pol?)) true false))
;;------------------------------------------------------------------------------------------------
;; placement of the planar dielectric interface within the computational cell
;;------------------------------------------------------------------------------------------------
;; helper functions
(define (alpha _chi_deg) ; angle of inclined plane with y-axis
(- (/ pi 2.0) (* (/ _chi_deg 360) 2 pi)))
(define (Delta_x _alpha) ; inclined plane offset to the center of the cell
(* (/ sx 2.0) (/ (-(- (sqrt 2.0) (cos _alpha)) (sin _alpha)) (sin _alpha))))
(set! geometry-lattice (make lattice (size sx sy sz)))
(set! default-material (make dielectric (index n1)))
(set! geometry (list
(make block ; located at lower right edge for 45 degree tilt
(center (+ (/ sx 2.0) (Delta_x (alpha chi_deg))) (/ sy -2.0))
(size infinity (* (sqrt 2.0) sx) infinity)
(e1 (/ 1.0 (tan (alpha chi_deg))) 1 0)
(e2 -1 (/ 1.0 (tan (alpha chi_deg))) 0)
(e3 0 0 1)
(material (make dielectric (index n2))))
))
;;------------------------------------------------------------------------------------------------
;; add absorbing boundary conditions and discretize structure
;;------------------------------------------------------------------------------------------------
(set! pml-layers
(list (make pml (thickness pml_thickness))))
(set! resolution ; set resolution in pixels per Meep distance unit
(* pixel (* (if (> n1 n2) n1 n2) freq)))
(set! Courant ; set Courant factor (mandatory if either n1 or n2 is smaller than 1)
(/ (if (< n1 n2) n1 n2) 3))
;;------------------------------------------------------------------------------------------------
;; 2d-beam profile distribution (field amplitude) at the waist of the beam
;;------------------------------------------------------------------------------------------------
(define (Gauss W_y)
(lambda (r) (exp (* -1.0 (/ (+ (* (vector3-y r) (vector3-y r)) (* (vector3-z r) (vector3-z r)))
(* W_y W_y))))
))
;;------------------------------------------------------------------------------------------------
;; some test outputs (uncomment if needed)
;;------------------------------------------------------------------------------------------------
;(print "Gauss 2d beam profile: " ((Gauss w_0) (vector3 0 0.5 0.2)) "\n")
;(exit)
;;------------------------------------------------------------------------------------------------
;; spectrum amplitude distribution(s)
;;------------------------------------------------------------------------------------------------
;;cartesian coordinates (not recommended) ---------------------------
;; coordinate transformation: from k-space to (theta, phi)-space
(define (phi k)
(lambda (k_y k_z) (atan (/ k_y k) (/ (* -1 k_z) k))
))
(define (theta k)
(lambda (k_y k_z) (acos (/ (real-part (sqrt (- (* k k) (* k_y k_y) (* k_z k_z)))) k))
))
(define (f_Gauss_cartesian W_y)
(lambda (k_y k_z) (exp (* -1 (* (* W_y W_y) (/ (+ (* k_y k_y) (* k_z k_z)) 4))))
))
(define (f_Laguerre_Gauss_cartesian W_y m)
(lambda (k_y k_z) (* ((f_Gauss_cartesian W_y) k_y k_z) (exp (* 0+1i m ((phi k1) k_y k_z)))
(expt ((theta k1) k_y k_z) (abs m)))
))
;; spherical coordinates --------------------------------------------
(define (f_Gauss_spherical W_y)
(lambda (sin_theta . opt) ; opt is an optional list of (unused) arguments (here: theta, phi)
(exp (* -1 (expt (/ (* k1 W_y sin_theta) 2) 2)))
))
(define (f_Laguerre_Gauss_spherical W_y m)
(lambda (sin_theta theta phi) (* ((f_Gauss_spherical W_y) sin_theta) (expt theta (abs m)) (exp (* 0+1i m phi)))
))
;;------------------------------------------------------------------------------------------------
;; some test outputs (uncomment if needed)
;;------------------------------------------------------------------------------------------------
;(let ((k_y 1.0) (k_z 5.2)) ; set local test values
; (print "\nGauss spectrum (cartesian): " ((f_Gauss_cartesian w_0) k_y k_z) "\n")
; (print "Gauss spectrum (spherical): " ((f_Gauss_spherical w_0) (sin ((theta k1) k_y k_z))) "\n")
;
; (print "\nL-G spectrum (cartesian): " ((f_Laguerre_Gauss_cartesian w_0 m_charge) k_y k_z) "\n")
; (print "L-G spectrum (spherical): " ((f_Laguerre_Gauss_spherical w_0 m_charge) (sin ((theta k1) k_y k_z))
; ((theta k1) k_y k_z)
; ((phi k1) k_y k_z)) "\n\n")
;)
;;------------------------------------------------------------------------------------------------
;; plane wave decomposition
;; (purpose: calculate field amplitude at light source position if not coinciding with beam waist)
;;------------------------------------------------------------------------------------------------
(define (integrand_cartesian f x y z)
(lambda (k_y k_z) (* (f k_y k_z)
;(exp (* 0+1i x (real-part (sqrt (- (* k1 k1) (* k_y k_y) (* k_z k_z))))))
;(exp (* 0+1i y k_y))
;(exp (* 0+1i z k_z)))
(exp (* 0+1i (+ (* x (real-part (sqrt (- (* k1 k1) (* k_y k_y) (* k_z k_z)))))
(* y k_y) (* z k_z)))))
))
(define (integrand_spherical f x y z)
(lambda (theta phi) (let ((sin_theta (sin theta)) (cos_theta (cos theta)))
(* sin_theta cos_theta (f sin_theta theta phi)
;(exp (* 0-1i k1 z (sin theta) (cos phi)))
;(exp (* 0+1i k1 y (sin theta) (sin phi)))
;(exp (* 0+1i k1 x (cos theta))))
(exp (* 0+1i k1 (+ (* sin_theta (- (* y (sin phi)) (* z (cos phi))))
(* cos_theta x))))))
))
;; complex field amplitude at position (x, y) with spectrum amplitude distribution f
;; (one may have to adjust the 'relerr' and 'maxeval' parameter values in the integrate function)
(define (psi_cartesian f x)
(lambda (r) (car (integrate (integrand_cartesian f x (vector3-y r) (vector3-z r))
(list (* -1.0 k1) (* -1.0 k1)) (list (* 1.0 k1) (* 1.0 k1)) relerr 0 maxeval))
))
(define (psi_spherical f x)
(lambda (r) (* k1 k1 (car (integrate (integrand_spherical f x (vector3-y r) (vector3-z r))
(list 0 0) (list (/ pi 2) (* 2 pi)) relerr 0 maxeval)))
))
;;------------------------------------------------------------------------------------------------
;; some test outputs (uncomment if needed)
;;------------------------------------------------------------------------------------------------
;(let ((k_y 1.0) (k_z 5.2) (x -2.15) (y 0.3) (z 0.5)) ; set local test values
; (print "integrand (cartesian): " ((integrand_cartesian (f_Laguerre_Gauss_cartesian w_0 m_charge) x y z)
; k_y k_z) "\n")
; (print "integrand (spherical): " ((integrand_spherical (f_Laguerre_Gauss_spherical w_0 m_charge)
; x y z) ((theta k1) k_y k_z) ((phi k1) k_y k_z)) "\n\n")
;
; (print "psi (cartesian): " ((psi_cartesian (f_Laguerre_Gauss_cartesian w_0 m_charge) x)
; (vector3 0 y z)) "\n")
;
; (print "psi (spherical): " ((psi_spherical (f_Laguerre_Gauss_spherical w_0 m_charge) x)
; (vector3 0 y z)) "\n")
;
; (print "psi (origin, simple): " ((Gauss w_0) (vector3 0 y z)) "\n")
;)
;(exit)
;;------------------------------------------------------------------------------------------------
;; display values of various variables
;;------------------------------------------------------------------------------------------------
(print "\n")
(print "Expected output file size: " (round (* 8 (/ (* sx sy sz (expt resolution 3)) (expt 1024 2)))) " MiB\n")
(print "\n")
(print "Specified variables and derived values: \n")
(print "n1: " n1 "\n")
(print "n2: " n2 "\n")
(print "chi: " chi_deg " [degree]\n") ; angle of incidence
(print "incl.: " (- 90 chi_deg) " [degree]\n") ; interface inclination with respect to the x-axis
(print "kw_0: " kw_0 "\n")
(print "kr_w: " kr_w "\n")
(print "k_vac: " k_vac "\n")
(print "vortex charge: " m_charge "\n")
(print "Jones vector components: (e_z=" e_z ", e_y=" e_y ")")
(print " ---> " (cond (s-pol? "s-") (p-pol? "p-") (a-pol? "mixed-")) "polarisation" "\n")
(print "degree of linear polarisation at pi/4: " (* 2 (real-part (* (conj (- 0 e_z)) e_y))) "\n")
(print "degree of circular polarisation: " (* 2 (imag-part (* (conj (- 0 e_z)) e_y))) "\n")
(print "\n")
;;------------------------------------------------------------------------------------------------
;; exploiting symmetries to reduce computational effort
;; (only possible for beams without intrinsic orbital angular momentum, i.e. no vortex charge)
;;------------------------------------------------------------------------------------------------
;; The plane of incidence (x-y-plane) is a mirror plane which is characterised to be orthogonal to the z-axis
;; (symmetry of the geometric structure). Symmetry of the sources must be ensured simultaneously, which is only
;; possible for certain cases. If I am not mistaken this can only be achieved for vortex free beams with pure s- or
;; p-polarisation, i.e. where either the Ez or Ey component is specified.
(if (equal? m_charge 0)
(cond (s-pol? ; s-polarisation
(set! symmetries (list (make mirror-sym (direction Z) (phase -1)))))
(p-pol? ; p-polarisation
(set! symmetries (list (make mirror-sym (direction Z) ))))
)
)
;;------------------------------------------------------------------------------------------------
;; specify current source, output functions and run simulation
;;------------------------------------------------------------------------------------------------
(use-output-directory) ; put output files in a separate folder
(set! force-complex-fields? true) ; default: true
(set! eps-averaging? true) ; default: true
(set! sources (filter (compose not unspecified?)
(list
(if (not (equal? e_z 0))
(make source
(src (make continuous-src (frequency freq) (width 0.5)))
(component Ez)
(amplitude e_z)
(size 0 3 3)
(center source_shift 0 0)
;(amp-func (Gauss w_0))
;(amp-func (psi_cartesian (f_Laguerre_Gauss_cartesian w_0 m_charge) shift))
(if (equal? m_charge 0)
;; if vortex charge is zero use Gauss spectrum distribution (improves perfomance)
(amp-func (psi_spherical (f_Gauss_spherical w_0) shift))
(amp-func (psi_spherical (f_Laguerre_Gauss_spherical w_0 m_charge) shift))
)
)
)
(if (not (equal? e_y 0))
(make source
(src (make continuous-src (frequency freq) (width 0.5)))
(component Ey)
(amplitude e_y)
(size 0 3 3)
(center source_shift 0 0)
;(amp-func (Gauss w_0))
;(amp-func (psi_cartesian (f_Laguerre_Gauss_cartesian w_0 m_charge) shift))
(if (equal? m_charge 0)
;; if vortex charge is zero use Gauss spectrum distribution (improves perfomance)
(amp-func (psi_spherical (f_Gauss_spherical w_0) shift))
(amp-func (psi_spherical (f_Laguerre_Gauss_spherical w_0 m_charge) shift))
)
)
)
))
)
(define (efield-real-squared r ex ey ez) ; calculates |Re E|^2
(+ (expt (real-part ex) 2) (expt (real-part ey) 2) (expt (real-part ez) 2)))
(define (efield-imag-squared r ex ey ez) ; calculates |Im E|^2
(+ (expt (imag-part ex) 2) (expt (imag-part ey) 2) (expt (imag-part ez) 2)))
(define (output-efield-real-squared) (output-real-field-function (cond (s-pol? "e_real2_s") (p-pol? "e_real2_p")
(a-pol? "e_real2_mixed"))
(list Ex Ey Ez) efield-real-squared))
(define (output-efield-imag-squared) (output-real-field-function (cond (s-pol? "e_imag2_s") (p-pol? "e_imag2_p")
(a-pol? "e_imag2_mixed"))
(list Ex Ey Ez) efield-imag-squared))
(run-until runtime
(at-beginning (lambda () (print "\nCalculating inital field configuration. This will take some time...\n\n")))
; (at-beginning output-epsilon) ; output of dielectric function
; (at-end output-efield-x) ; output of E_x component
; (at-end output-efield-y) ; output of E_y component
; (at-end output-efield-z) ; output of E_z component
(at-end output-efield-real-squared) ; output of electric field intensity
(at-end (when-true (lambda () force-complex-fields?) output-efield-imag-squared))
)
(print "\nend time: "(strftime "%c" (localtime (current-time))) "\n")