Skip to content

Instantly share code, notes, and snippets.

@aphirst
Last active January 3, 2016 23:09
Show Gist options
  • Save aphirst/8533106 to your computer and use it in GitHub Desktop.
Save aphirst/8533106 to your computer and use it in GitHub Desktop.
My old Master's code. I had planned to rewrite this, and re-reading it has given me a little more motivation to actually do so. Oh, how much I've improved in merely a year...
! This file is part of TammFTN.
! Copyright (C) 2013 Adam Hirst <adam@aphirst.karoo.co.uk>
!
! TammFTN is free software: you can redistribute it and/or modify
! it under the terms of the GNU General Public License as published by
! the Free Software Foundation, either version 3 of the License, or
! (at your option) any later version.
!
! TammFTN is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! GNU General Public License for more details.
!
! You should have received a copy of the GNU General Public License
! along with TammFTN. If not, see <http://www.gnu.org/licenses/>.
module photonics
implicit none
integer, parameter :: dp = selected_real_kind(15, 307)
real(dp), parameter :: c = 299792458_dp
real(dp), parameter :: hbar = 1.05457172647E-34_dp
real(dp), parameter :: q = 1.60217656535E-19_dp ! elementary charge
real(dp), parameter :: e0 = 8.854187817E-12_dp
real(dp), parameter :: mu0 = 16*atan(1.0_dp)*1E-7 ! 4 pi 10^-7
real(dp), parameter :: pi = 4*atan(1.0_dp)
contains
subroutine readin(Es, func, materl, pol, res, struct, thetas)
complex(dp), pointer, intent(out) :: Es(:)
character(len=5), intent(out) :: func
character(len=10), pointer, intent(out) :: materl(:)
character(len=2), intent(out) :: pol
integer, intent(out) :: res
real(dp), pointer, intent(out) :: struct(:), thetas(:)
integer :: a, b, i, ioerr, j, gap, n, tokens
real(dp), pointer :: Etemp(:)
character(len=30) :: filename
character(len=10000) :: line
character(len=10) :: resstr
call getarg(1, filename)
open(unit=10, file=trim(filename), status='old', iostat=ioerr)
if (ioerr /= 0) then
stop 'Error reading input file.'
end if
call getarg(2, func) ! function to perform, 'RT', 'EHS', 'SOLVE' or 'PHASE'
if (index('RT EHS SOLVE PHASE', func) == 0) then
stop 'Invalid function specified.'
end if
call getarg(3, pol) ! polarisation, either 'TE' or 'TM'
if (index('TE TM', pol) == 0) then
stop 'Invalid polarisation specified.'
end if
call getarg(4, resstr) ! number of points for graph-data generation, as string
read(resstr,*) res ! convert to integer via internal read
do i = 1, 4 ! first 4 lines have variable length, materials, thicknesses, energies, angles
read(10,'(a)') line ! '(a)' reads entire line
! EXPAND n(A B) INTO A B A B ...
if (i .le. 2) then ! only do for materials and thicknesses
do
a = scan(line, '(')
b = scan(line, ')')
if (a > b) then
stop 'Formatting error, check parentheses.'
else if ((a == 0) .or. (b == 0)) then
exit ! no more () terms, done
end if
gap = scan(line(1:a), ' ', .true.) ! search backwards from ( for blank
read(line(gap+1:a-1),*) n ! convert to integer using internal read
line = line(1:gap) // repeat(line(a+1:b-1) // ' ', n) // line(b+2:)
! b+2 is start of first token after ')'
end do
end if
! REMOVE DUPLICATED SPACES
do
gap = index(line(1:len_trim(line)),' ')
if (gap == 0) then
exit ! no more duplicated spaces, done
else
line(gap:) = line(gap+1:)
end if
end do
! COUNT TOKENS IN LINE
tokens = 0
gap = 1
do
if (len_trim(line(gap:)) == 0) then
exit ! break when no tokens in line
end if
gap = gap + scan(line(gap+1:), ' ') ! find next blank (end of current token)
tokens = tokens + 1
end do
! LOAD INTO ARRAYS
if (i == 1) then ! materials
allocate(materl(tokens))
read(line,*) materl ! internal read
else if (i == 2) then ! layer thicknesses, in nanometres
if (tokens /= size(materl) - 1) then
stop 'Mismatch between materials and thicknesses.'
end if
allocate(struct(tokens))
read(line,*) struct ! internal read
! converting thicknessses to positions deferred until later
else if (i == 3) then ! energies, in eV
if (mod(tokens,2) /= 0) then ! n complex numbers => 2n real numbers
stop 'Mismatch between number of real and imaginary energy components.'
end if
allocate(Etemp(tokens)) ! use Etemp as temporary store for Ereal and Eimag
read(line,*) Etemp ! internal read
allocate(Es(tokens/2))
do j = 1, size(Es)
Es(j) = cmplx(Etemp(2*j-1),Etemp(2*j),dp)
! cast real and imaginary components of energy into Es
end do
else if (i == 4) then ! angles, in degrees
if ((size(Es) == 2) .and. (size(thetas) == 2)) then
stop '2D contour plot of energy and angle not implemented at this time.'
end if
allocate(thetas(tokens))
read(line,*) thetas
thetas = pi*thetas/180
end if
end do
close(10)
end subroutine readin
subroutine refindex(Ein, materl, n)
complex(dp), intent(in) :: Ein
character(len=*), intent(in) :: materl(:)
complex(dp), pointer, intent(out) :: n(:)
complex(dp) :: E
integer :: i
allocate(n(size(materl)))
E = cmplx(real(Ein),0,dp)
! only real(E) needed for refractive index
do i = 1, size(materl)
! STANDARD DIELECTRICS
if (materl(i) == 'air') then
n(i) = (1,0)
else if (materl(i) == 'glass') then
n(i) = (1.5,0)
else if (materl(i) == 'prism') then
n(i) = (2,0)
else if (materl(i) == 'SiO2') then ! Silicon Dioxide
n(i) = (1.47,0)
else if (materl(i) == 'TiO2') then ! Titanium Dioxide
n(i) = (2.37,0)
! MODEL METAL
else if (materl(i) == 'modmet') then
n(i) = sqrt(1 - 1/(E*(E + (0,0.01))))
! STANDARD METALS
else if (materl(i) == 'Au') then ! Gold
n(i) = sqrt(1 - 73.1025/(E*(E + (0,0.0184))))
! OTHER DRUDE-FORM MATERIALS
else if (materl(i) == 'TiN') then
!n(i) = sqrt(1 - 33.64/(E*(E + (0,1.1))))
n(i) = sqrt( 1 - 33.64/(E*(E + (0,0.3))) + 33.64/(15.21 - E*(E + (0,0.3))) ) ! 1.1
! "SPP study of optical dielectric function of TiNx"
else if (materl(i) == 'ITO') then
n(i) = 1.94936 * sqrt(1 - 1.26113/(E * (E + (0,0.111)))) ! loss 0.111
! Rhodes et al, full loss term
else if (materl(i) == 'ITO_NL') then ! NL = No Losses
n(i) = 1.94936 * sqrt(1 - 1.26113/(E * (E + (0,0))))
! SPECIAL MATERIALS
else if (materl(i) == 'TiN_F') then
n(i) = sqrt(1.95 - 40.2083/(E**2 + E*(0,0.746)) + (2.16736)/(12.0409 - E**2 &
- E*(0,0.91261)) + (229.85)/(33.4084 - E**2 - E*(0,5.85514)))
! TiN Fitted, Applied Surface Science 175-176, p270
else
write(*,*) 'Unsupported material: ', materl(i), '.'
stop
end if
end do
end subroutine refindex
subroutine wavevect(n, theta, k)
complex(dp), intent(in) :: n(:)
real(dp), intent(in) :: theta
complex(dp), pointer, intent(out) :: k(:)
integer :: i
allocate(k(0:size(n))) ! k'z is at entry 0
k(0) = n(1) * sin(theta) ! fixed at left of structure
do i = 1, size(n)
k(i) = sqrt(n(i)**2 - k(0)**2)
end do
end subroutine wavevect
subroutine interpos(struct)
real(dp), intent(inout) :: struct(:)
integer :: i
if (size(struct) .gt. 1) then
do i = 2, size(struct)
struct(i) = struct(i) + struct(i-1) ! convert thicknesses into interface positions
end do
end if
end subroutine interpos
subroutine trnsmtrx(E, materl, pol, struct, theta, k, n, trnsfr)
complex(dp), intent(in) :: E
character(len=*), intent(in) :: materl(:), pol
real(dp), intent(in) :: struct(:), theta
complex(dp), pointer, intent(out) :: k(:), n(:), trnsfr(:,:,:)
complex(dp) :: M(2,2)
integer :: i
call refindex(E, materl, n)
call wavevect(n, theta, k)
allocate(trnsfr(size(n),2,2))
trnsfr(1,:,:) = reshape((/1,0,0,1/),(/2,2/))
! identity matrix, since transferring into layer 1 does not alter coefficients
do i = 2, size(n)
if (pol == 'TE') then
M(1,1) = (k(i) + k(i-1)) * exp(E * cmplx(0,pi*struct(i-1)/620,dp) * (k(i) - k(i-1)))
M(1,2) = (k(i) - k(i-1)) * exp(E * cmplx(0,pi*struct(i-1)/620,dp) * (k(i) + k(i-1)))
M(2,1) = (k(i) - k(i-1)) * exp(E * cmplx(0,-pi*struct(i-1)/620,dp) * (k(i) + k(i-1)))
M(2,2) = (k(i) + k(i-1)) * exp(E * cmplx(0,-pi*struct(i-1)/620,dp) * (k(i) - k(i-1)))
! interface matrix characterising coefficient transfer from (i-1) 'into' (i)
! struct(i-1) since (i-1)th interface precedes (i)th layer
trnsfr(i,:,:) = M / (2 * k(i))
else if (pol == 'TM') then
M(1,1) = (k(i-1)*n(i)**2 + k(i)*n(i-1)**2) * exp(E * cmplx(0,pi*struct(i-1)/620,dp) * (k(i) - k(i-1)))
M(1,2) = (k(i-1)*n(i)**2 - k(i)*n(i-1)**2) * exp(E * cmplx(0,pi*struct(i-1)/620,dp) * (k(i-1) + k(i)))
M(2,1) = (k(i-1)*n(i)**2 - k(i)*n(i-1)**2) * exp(E * cmplx(0,-pi*struct(i-1)/620,dp) * (k(i-1) + k(i)))
M(2,2) = (k(i-1)*n(i)**2 + k(i)*n(i-1)**2) * exp(E * cmplx(0,pi*struct(i-1)/620,dp) * (k(i-1) - k(i)))
trnsfr(i,:,:) = M / (2 * k(i-1) * n(i)**2)
end if
trnsfr(i,:,:) = matmul(trnsfr(i,:,:),trnsfr(i-1,:,:))
! multiply interface matrix with previous transfer matrix
end do
end subroutine trnsmtrx
subroutine fieldint(A, B, E, k, kz, n, pol, x, EH)
complex(dp), intent(in) :: A, B, E, k, kz, n
character(len=2), intent(in) :: pol
real(dp), intent(in) :: x
real(dp), intent(out) :: EH(2,2) ! E in row 1, H in row 2
if (pol == 'TE') then
! (:,1) is perpendicular to planar interfaces (x)
! (:,2) is parallel to planar interfaces (y or z)
! E_x, E_y
EH(1,1) = 0_dp
EH(1,2) = abs(A*exp(k*E*cmplx(0,-pi*x/620,dp)) + B*exp(k*E*cmplx(0,pi*x/620,dp)))**2
! H_x, H_z
EH(2,1) = abs(kz*(A*exp(k*E*cmplx(0,-pi*x/620,dp)) + B*exp(k*E*cmplx(0,pi*x/620,dp))) / (c*mu0))**2
EH(2,2) = abs(k*(B*exp(k*E*cmplx(0,pi*x/620,dp)) - A*exp(k*E*cmplx(0,-pi*x/620,dp))) /(c*mu0))**2
else if (pol == 'TM') then
! E_x, E_z
EH(1,1) = abs((kz/k)*(A*exp(k*E*cmplx(0,-pi*x/620,dp)) + B*exp(k*E*cmplx(0,pi*x/620,dp))))**2
EH(1,2) = abs(A*exp(k*E*cmplx(0,-pi*x/620,dp)) + B*exp(k*E*cmplx(0,pi*x/620,dp)))**2
! H_x, H_y
EH(2,1) = 0_dp
EH(2,2) = abs((A*exp(k*E*cmplx(0,-pi*x/620,dp)) - B*exp(k*E*cmplx(0,pi*x/620,dp))) * (n**2 * c * e0)/k)**2
end if
end subroutine fieldint
subroutine poweravg(A, B, E, k, n, pol, x, S)
complex(dp), intent(in) :: A, B, E, k, n
character(len=*), intent(in) :: pol
real(dp), intent(in) :: x
real(dp), intent(out) :: S
if (pol == 'TE') then
S = real((A*exp(k*E*cmplx(0,-pi*x/620,dp)) + B*exp(k*E*cmplx(0,pi*x/620,dp))) &
* conjg(k*(B*exp(k*E*cmplx(0,pi*x/620,dp)) - A*exp(k*E*cmplx(0,-pi*x/620,dp)))) / (2*c*mu0))
else if (pol == 'TM') then
S = real((A*exp(k*E*cmplx(0,-pi*x/620,dp)) + B*exp(k*E*cmplx(0,pi*x/620,dp))) * (c*e0/2) &
* conjg((n**2 / k) * (A*exp(k*E*cmplx(0,-pi*x/620,dp)) - B*exp(k*E*cmplx(0,pi*x/620,dp)))))
end if
end subroutine poweravg
subroutine reftrans(E, materl, pol, struct, theta, Rc, Tc, phi)
complex(dp), intent(in) :: E
character(len=*), intent(in) :: materl(:), pol
real(dp), intent(in) :: struct(:), theta
real(dp), intent(out) :: phi, Rc, Tc
complex(dp), pointer :: k(:), n(:), trnsfr(:,:,:)
complex(dp) :: M(2,2), r, t
real(dp) :: SI, ST
call trnsmtrx(E, materl, pol, struct, theta, k, n, trnsfr)
M = trnsfr(size(n),:,:)
r = -M(1,2)/M(1,1)
t = M(2,2) - M(1,2)*M(2,1)/M(1,1)
Rc = abs(r)**2
call poweravg(cmplx(0,0,dp), t, E, k(size(n)), n(size(n)), pol, struct(1), ST)
call poweravg(cmplx(0,0,dp), cmplx(1,0,dp), E, k(1), n(1), pol, struct(size(struct)), SI)
Tc = ST/SI
phi = 180 * atan2(imag(r),real(r)) / pi
! atan2(r%im, r%re)
! ENSURE -180 RENDERS AS 180
if (phi == -180.0) then
phi = 180.0
end if
end subroutine reftrans
subroutine rtenergy(Ecs, materl, pol, res, struct, theta, output)
complex(dp), intent(in) :: Ecs(2)
character(len=*), intent(in) :: materl(:), pol
integer, intent(in) :: res
real(dp), intent(in) :: struct(:), theta
real(dp), pointer, intent(out) :: output(:,:)
complex(dp) :: E, Es(2)
integer :: i
write(*,*) 'Plotting R, T and phi against E...'
do i = 1,2
Es(i) = cmplx(real(Ecs(i)),0,dp) ! varying E, so disregard imaginary components
end do
allocate(output(res,4)) ! E, R, T, phi
do i = 1, res
E = Es(1) + (Es(2) - Es(1))*(i-1)/res
output(i,1) = real(E)
call reftrans(E, materl, pol, struct, theta, output(i,2), output(i,3), output(i,4))
! outputs are (Rc, Tc, phi)
end do
end subroutine rtenergy
subroutine rttheta(E, materl, pol, res, struct, thetas, output)
complex(dp), intent(in) :: E
character(len=*), intent(in) :: materl(:), pol
integer, intent(in) :: res
real(dp), intent(in) :: struct(:), thetas(2)
real(dp), pointer, intent(out) :: output(:,:)
integer :: i
real(dp) :: theta
write(*,*) 'Plotting R, T and phi against theta...'
allocate(output(res,4)) ! theta, R, T, phi
do i = 1, res
theta = thetas(1) + (thetas(2) - thetas(1))*(i-1)/res
output(i,1) = 180*theta/pi
call reftrans(E, materl, pol, struct, theta, output(i,2), output(i,3), output(i,4)) ! R, T, phi
end do
end subroutine rttheta
subroutine ehsplot(E, func, materl, pol, res, struct, theta, output)
complex(dp), intent(in) :: E
character(len=*), intent(in) :: func, materl(:), pol
integer, intent(in) :: res
real(dp), intent(in) :: struct(:), theta
real(dp), pointer, intent(out) :: output(:,:)
complex(dp), pointer :: AB(:,:), k(:), n(:), trnsfr(:,:,:)
real(dp) :: EH(2,2), S, x
integer :: i, j
complex(dp) :: M(2,2), r
write(*,*) 'Plotting E, H and S through structure...'
allocate(output(res,7)) ! x, n, E(1er), E(||), H(1er), H(||), S
call trnsmtrx(E, materl, pol, struct, theta, k, n, trnsfr)
allocate(AB(size(n),2))
! SET LHS COEFFICIENTS TO (r,1) OR (1,0) FOR INCIDENT/SURFACE RESPECTIVELY
if (func == 'SOLVE') then
AB(1,:) = (/cmplx(1,0,dp), cmplx(0,0,dp)/) ! reflected = r, 0 (confined)
else
M = trnsfr(size(n),:,:)
r = -M(1,2)/M(1,1)
AB(1,:) = (/r, cmplx(1,0,dp)/) ! reflected, incident
end if
! GENERATE ALL COEFFICIENTS
do i = 2, size(n) ! no need to recalculate AB(1)
AB(i,:) = matmul(trnsfr(i,:,:),AB(1,:))
end do
! CALCULATE E, H AND S FOR ALL x
do i = 1, res
x = struct(1) + (struct(size(struct)) - struct(1))*(i-1)/res
output(i,1) = x
do j = 1, size(struct)
if (x < struct(j)) then ! .lt. interface i => in material i
call fieldint(AB(j,1), AB(j,2), E, k(j), k(0), n(j), pol, x, EH)
call poweravg(AB(j,1), AB(j,2), E, k(j), n(j), pol, x, S)
output(i,2) = real(n(j))
exit
end if
end do
output(i,3:4) = EH(1,:) ! store E
output(i,5:6) = EH(2,:) ! store H
output(i,7) = S ! store S
end do
end subroutine ehsplot
subroutine surfsolv(E, materl, pol, res, struct, theta, output)
complex(dp), intent(in) :: E
character(len=*), intent(in) :: materl(:), pol
integer, intent(in) :: res
real(dp), intent(in) :: struct(:), theta
real(dp), pointer, intent(out) :: output(:,:)
integer :: best, i, ioerr
complex(dp) :: Es(5)
character(len=10) :: filename
complex(dp), pointer :: k(:), n(:), trnsfr(:,:,:)
real(dp) :: M(5), step
write(*,*) 'Solving for defect/surface state...'
call getarg(1, filename)
open(unit=20, file= trim(filename) // '_log', status='replace', iostat=ioerr)
if (ioerr /= 0) then
stop 'Error writing to log file.'
end if
! DETERMINE BEST SOLUTION OF E
step = 0.01 ! eV
Es(1) = E
do
! GENERATE "CROSS" OF E "POINTS"
Es(:) = (/Es(1), Es(1)+step*(0,1), Es(1)+step, Es(1)-step*(0,1), Es(1)-step/)
! centre, up (+i), right (+1), down (-i), left (-1)
! CALCULATE M(1,1) FOR EACH E IN CROSS
do i = 1, 5
call trnsmtrx(Es(i), materl, pol, struct, theta, k, n, trnsfr)
M(i) = abs(trnsfr(size(n),1,1))
if (i == 1) then
write(*,*) real(E)*real(k(0))
end if
end do
best = minloc(M,1)
write(20,'(4ES14.6)') real(Es(best)), imag(Es(best)), step, M(best)
! HALVE STEP SIZE IF BEST E IS THE "CENTRE", ELSE RECENTRE AROUND BEST E
if (best == 1) then
step = step/2
else
Es(1) = Es(best)
end if
! SMALL STEP SIZE IMPLIES SUFFICIENT CONVERGENCE
if (step < epsilon(step)) then
exit
end if
end do
write(*,*) 'Solution found!'
write(*,*) 'E = ', real(Es(1)), '-', -imag(Es(1)), 'i'
write(*,*) 'Characteristic lifetime is ',-hbar/(q*imag(Es(1))),' seconds.'
close(20)
! GENERATE EHS PLOT DATA AT OPTIMUM E
call ehsplot(Es(1), 'SOLVE', materl, pol, res, struct, theta, output)
end subroutine surfsolv
subroutine phasmtch(Es, materl, pol, res, struct, theta, output)
complex(dp), intent(in) :: Es(:)
character(len=*), intent(in) :: materl(:), pol
integer, intent(in) :: res
real(dp), intent(in) :: struct(:), theta
real(dp), pointer, intent(out) :: output(:,:)
integer :: layer
character(len=10), pointer :: matlef(:), matrig(:)
complex(dp), pointer :: n(:)
real(dp), pointer :: strlef(:), strrig(:), outlef(:,:), outrig(:,:)
real(dp) :: thetin
!write(*,*) 'Generating phase plots for interface matching condition...'
allocate(output(res,4)) ! E, phiL, phiR, phiTOT
write(*,*) 'First three materials: ',trim(materl(1)),', ',trim(materl(2)),', ',trim(materl(3)),'.'
write(*,*) 'In which layer should the virtual interface be constructed (at the far left)?'
read(*,*) layer ! read layer # in which to perform phase-matching, as string
! ALLOCATE LEFT AND RIGHT materl(:) AND struct(:) ARRAYS
allocate(matlef(layer))
allocate(matrig(size(materl) - layer + 1))
allocate(strlef(layer - 1))
allocate(strrig(size(materl) - layer ))
! CONSTRUCT materl(:) ARRAYS
matlef(:) = materl(layer:1:-1) ! third entry indicates "stride", negative reverses
matrig(1) = materl(layer)
matrig(2:size(matrig)) = materl(layer:size(materl))
! CONSTRUCT struct(:) ARRAYS
strlef(1) = 0
strlef(2:size(strlef)) = struct(layer-1:2:-1)
strrig(1) = 0
strrig(2:size(strrig)) = struct(layer:size(struct))
! CONVERT THICKNESSES TO POSITIONS
call interpos(strlef)
call interpos(strrig)
! DETERMINE INTERNAL ANGLE WITHIN CONSIDERED INTERFACE
call refindex(cmplx(1,0,dp), materl(1:layer:layer-1), n)
thetin = asin(real(n(1))*sin(theta)/real(n(2)))
write(*,*) 'Internal angle is ',180*thetin/pi,' degrees.'
! PERFORM REFLECTION CALCULATION FOR LEFT AND RIGHT HALF-STRUCTURES
call rtenergy(Es, matlef, pol, res, strlef, thetin, outlef)
write(*,*) 'Left phase complete!'
call rtenergy(Es, matrig, pol, res, strrig, thetin, outrig)
write(*,*) 'Right phase complete!'
! EXTRACT PHASES AND CONSTRUCT FINAL OUTPUT ARRAY
output(:,1) = outlef(:,1) ! populate Energy column
output(:,2) = outlef(:,4) ! phiL
output(:,3) = outrig(:,4) ! phiR
output(:,4) = outlef(:,4) + outrig(:,4) ! phiL + phiR = phiTOT
end subroutine phasmtch
subroutine writeout(output)
real(dp), intent(in) :: output(:,:)
character(len=20) :: filename
integer :: i, ioerr, j
call getarg(1, filename)
write(*,*) 'Writing data to file...'
open(unit=30, file=trim(filename) // '_out', status='replace', iostat=ioerr)
if (ioerr /= 0) then
stop 'Error writing to output file.'
end if
do i = 1, size(output(:,1))
write(30,'(7ES13.5)') (output(i,j), j = 1, size(output(1,:)))
! format statement with 7 repeats, scientific, 14 width, 6 decimal
! implied do loop
end do
close(30)
write(*,*) 'Data written!'
end subroutine writeout
subroutine flowctrl
complex(dp), pointer :: Es(:)
character(len=5) :: func
character(len=10), pointer :: materl(:)
character(len=2) :: pol
integer :: res
real(dp), pointer :: output(:,:), struct(:), thetas(:)
call readin(Es, func, materl, pol, res, struct, thetas)
if (func .ne. 'PHASE') then
call interpos(struct) ! convert thicknesses to positions, except for phase-matching
end if
if ((func == 'RT') .and. (size(thetas) == 1)) then
call rtenergy(Es, materl, pol, res, struct, thetas(1), output)
else if ((func == 'RT') .and. (size(thetas) == 2)) then
call rttheta(Es(1), materl, pol, res, struct, thetas, output)
else if (func == 'EHS') then
call ehsplot(Es(1), func, materl, pol, res, struct, thetas(1), output)
else if (func == 'SOLVE') then
call surfsolv(Es(1), materl, pol, res, struct, thetas(1), output)
else if (func == 'PHASE') then
call phasmtch(Es, materl, pol, res, struct, thetas(1), output)
else
stop 'Parameters incompatible with desired function, or function unavailable.'
end if
call writeout(output)
end subroutine flowctrl
end module photonics
program main
use photonics
implicit none
call flowctrl
end program main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment