!
! This file is part of SACAMOS, State of the Art CAble MOdels for Spice.
! It was developed by the University of Nottingham and the Netherlands Aerospace
! Centre (NLR) for ESA under contract number 4000112765/14/NL/HK.
!
! Copyright (C) 2016-2018 University of Nottingham
!
! SACAMOS 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.
!
! SACAMOS 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.
!
! A copy of the GNU General Public License version 3 can be found in the
! file GNU_GPL_v3 in the root or at .
!
! SACAMOS uses the EISPACK library (in /SRC/EISPACK). EISPACK is subject to
! the GNU Lesser General Public License. A copy of the GNU Lesser General Public
! License version can be found in the file GNU_LGPL in the root of EISPACK
! (/SRC/EISPACK ) or at .
!
! The University of Nottingham can be contacted at: ggiemr@nottingham.ac.uk
!
!
! File Contents:
! SUBROUTINE calc_incident_field_components
! SUBROUTINE calculate_incident_field_sources
! SUBROUTINE calculate_ZT_incident_field_sources
! SUBROUTINE calc_incident_field_FD_values
! SUBROUTINE calc_incident_field_FD_values_GP
! SUBROUTINE calculate_lumped_incident_field_sources
!
! NAME
! calc_incident_field_components
!
! AUTHORS
! Chris Smartt
!
! DESCRIPTION
! This subroutine calculates the cartesian components of the incident field
! excitation and the propagation (k) vector from the inputs which are in
! a spherical coordinate system ! #FIGURE_REFERENCE_REQUIRED
!
! COMMENTS
!
!
! HISTORY
!
! started 13/6/2016 CJS: STAGE_6 developments
! 8/5/2017 CJS: Include references to Theory_Manual
!
SUBROUTINE calc_incident_field_components(Ktheta,Kphi,Etheta,Ephi, &
Ex,Ey,Ez,Hx,Hy,Hz,kx,ky,kz)
USE type_specifications
USE general_module
USE constants
USE eispack
USE maths
IMPLICIT NONE
! variables passed to the subroutine
real(dp),intent(IN) :: ktheta ! theta component of k vector
real(dp),intent(IN) :: kphi ! phi component of k vector
real(dp),intent(IN) :: etheta ! theta component of E field polarisation vector
real(dp),intent(IN) :: ephi ! phi component of E field polarisation vector
! Cartesian field components
real(dp),intent(OUT) :: Ex
real(dp),intent(OUT) :: Ey
real(dp),intent(OUT) :: Ez
real(dp),intent(OUT) :: Hx
real(dp),intent(OUT) :: Hy
real(dp),intent(OUT) :: Hz
! Cartesian propagation vector components
real(dp),intent(OUT) :: kx
real(dp),intent(OUT) :: ky
real(dp),intent(OUT) :: kz
! local variables
real(dp) :: r,theta,phi
real(dp) :: x,y,z
real(dp) :: dxdt,dxdp
real(dp) :: dydt,dydp
real(dp) :: dzdt,dzdp
real(dp) :: vx,vy,vz
real(dp) :: norm
! START
! calculate unit length incident wave vector Theory_Manual_Eqn 3.135
r=1d0
theta=Ktheta
phi=Kphi
kx=r*sin(theta)*cos(phi)
ky=r*sin(theta)*sin(phi)
kz=r*cos(theta)
! Calculate cartesian unit vectors in the theta and phi directions. Theory_Manual_Eqn 3.137, 3.138
dxdt= r*cos(theta)*cos(phi)
dxdp=-r*sin(phi)
dydt= r*cos(theta)*sin(phi)
dydp= r*cos(phi)
dzdt=-r*sin(theta)
dzdp=0d0
! Calculate the cartesian E field vector from the sum of Etheta and Ephi contributions. Theory_Manual_Eqn 3.139
vx=Etheta*dxdt+Ephi*dxdp
vy=Etheta*dydt+Ephi*dydp
vz=Etheta*dzdt+Ephi*dzdp
! Normalise the E field vector to a length of 1
norm=sqrt(vx*vx+vy*vy+vz*vz)
if (norm.eq.0d0) then
if (verbose) then
write(*,*)'Error calculating incident field data'
write(*,8000)'E vector(theta)=',dxdt,dydt,dzdt
write(*,8000)'E vector(phi)=',dxdp,dydp,dzdp
write(*,8000)'E vector=',Etheta,Ephi
end if
run_status='ERROR in calc_incident_field_components: Zero length incident E field vector'
CALL write_program_status()
STOP 1
end if
Ex=vx/norm
Ey=vy/norm
Ez=vz/norm
! H = (K x E)/Z0. Theory_Manual_Eqn 3.142
Hx=(ky*Ez-kz*Ey)/Z0
Hy=(kz*Ex-kx*Ez)/Z0
Hz=(kx*Ey-ky*Ex)/Z0
if (verbose) then
write(*,*)'Incident_field_components:'
write(*,8000)'K=',kx,ky,kz
write(*,8000)'E=',Ex,Ey,Ez
write(*,8000)'H=',Hx,Hy,Hz
8000 format(A,3E16.6)
end if
RETURN
END SUBROUTINE calc_incident_field_components
!
! NAME
! calculate_incident_field_sources
!
! DESCRIPTION
! calculate constants required to determine the controlled sources
! for Spice models of transient incident field illumination using the
! method of characterisitcs based solution
!
!
! COMMENTS
! Refer to Theory_Manual_Section 3.7
! Also discussed in more depth in C.R. Paul, "Analysis of Multiconductor Transmission Lines"
! 1st edition, section 7.3.2
!
!
! HISTORY
!
! started 16/06/2016 CJS
! 28/6/2016 CJS :Include the presence of a ground plane if required.
! 8/5/2017 CJS: Include references to Theory_Manual
!
!
SUBROUTINE calculate_incident_field_sources(xcoord,ycoord,Eamplitude,Ex,Ey,Ez,Hx,Hy,Hz,kx,ky,kz, &
ground_plane_present,ground_plane_x,ground_plane_y,ground_plane_theta, &
length,n_modes,TI,Tdi,Tdz,alpha_0,alpha_L)
USE type_specifications
USE constants
USE general_module
IMPLICIT NONE
! variables passed to subroutine
integer,intent(IN) :: n_modes ! input: number of modes in the illuminated domain
real(dp),intent(IN) :: xcoord(n_modes+1),ycoord(n_modes+1) ! input: centre coordinates of conductors
real(dp),intent(IN) :: Eamplitude,Ex,Ey,Ez,Hx,Hy,Hz,kx,ky,kz ! input: incident field specification
logical ,intent(IN) :: ground_plane_present ! input: flag indicating the presence of a ground plane
real(dp),intent(IN) :: ground_plane_x,ground_plane_y ! input: x and y coordinates of a point on the ground plane
real(dp),intent(IN) :: ground_plane_theta ! input: angle of the ground plane from the x axis
real(dp),intent(IN) :: length ! input: length of transmission line
real(dp),intent(IN) :: TI(n_modes,n_modes) ! input: mode decomposition matrix
real(dp),intent(IN) :: Tdi(n_modes) ! input: mode delays
real(dp),intent(OUT) :: alpha_0(n_modes),alpha_L(n_modes) ! output: constants for controlled sources at z=0 and z=L
real(dp),intent(OUT) :: Tdz ! output: incident field delay time
! local variables
integer :: n_conductors
real(dp) :: xk,yk
real(dp) :: rvx,rvy,rvz
real(dp) :: Tdxyk(n_modes)
real(dp) :: vi
integer :: i,k
! START
n_conductors=n_modes+1
alpha_0(:)=0d0
alpha_L(:)=0d0
if (Eamplitude.eq.0d0) then ! there is no incident field so return zero constants
return
end if
! calculate 1/velocity in each direction (avoids divide by zeros using reciprocal values)
! obtained from Theory_Manual_Eqn 3.136
rvx=kx/c0
rvy=ky/c0
rvz=kz/c0
! Time delay in Z direction
Tdz=length*rvz
! loop over all conductors except the reference conductor
do k=1,n_conductors-1
! Assume that the final (reference) conductor lies at the origin of the xy plane
! and calculate the vector xk,yk from the reference conductor to conductor k.
! If there is a ground plane then calculate the vector to the closest point on the ground plane
! i.e. in the y direction since the ground plane is along the x axis.
if (ground_plane_present) then
xk=0d0
else
xk=xcoord(k)-xcoord(n_modes+1)
end if
yk=ycoord(k)-ycoord(n_modes+1)
! work out the delay propagating from this conductor to the reference
Tdxyk(k)=xk*rvx+yk*rvy
end do
! loop over modes, i
do i=1,n_modes
! loop over all conductors except the reference conductor
do k=1,n_conductors-1
! Again, assume that the final (reference) conductor lies at the origin of the xy plane
! and calculate the vector xk,yk from the reference conductor to conductor k.
! If there is a ground plane then calculate the vector to the closest point on the ground plane
! i.e. in the y direction since the ground plane is along the x axis.
if (ground_plane_present) then
! only the height over the ground plane matters so set x coordinate to zero and y is the height over ground
xk=0d0
else
xk=xcoord(k)-xcoord(n_modes+1)
end if
yk=ycoord(k)-ycoord(n_modes+1)
! note alpha_0,alpha_L are used to calculate the response of mode i due to excitations on all conductors, k
! hence the summation with over k with coefficients TI(k,i)
! Theory_Manual_Eqn 3.167
alpha_0(i)=alpha_0(i)+( Ez*Tdxyk(k)*length - (Ex*xk+Ey*yk)*(Tdi(i)+Tdz) )*TI(k,i) ! note, TI(k,i) = TI(conductor,mode)
alpha_L(i)=alpha_L(i)+( Ez*Tdxyk(k)*length + (Ex*xk+Ey*yk)*(Tdi(i)-Tdz) )*TI(k,i)
end do ! next conductor
end do ! next mode
if (ground_plane_present) then ! See Theory_Manual_Section 3.7.2
! the alpha terms are doubled
alpha_0(:)=2d0*alpha_0(:)
alpha_L(:)=2d0*alpha_L(:)
end if
if (.NOT.verbose) RETURN
write(*,*)'calculate_incident_field_sources'
write(*,*)'ex=',ex
write(*,*)'ey=',ey
write(*,*)'ez=',ez
write(*,*)'kx=',kx
write(*,*)'ky=',ky
write(*,*)'kz=',kz
write(*,*)'rvx=',rvx
write(*,*)'rvy=',rvy
write(*,*)'rvz=',rvz
write(*,*)'Tdz=',Tdz
RETURN
END SUBROUTINE calculate_incident_field_sources
!
! NAME
! calculate_ZT_incident_field_sources
!
! DESCRIPTION
! calculate the controlled sources for Spice modelling of transient incident field illumination
! of shielded cables (Xie's model), method of characterisitcs based solution
!
!
! COMMENTS
! Refer to Theory_Manual_Section 3.8
!
!
! HISTORY
!
! started 3/10/2016 CJS
! 8/5/2017 CJS: Include references to Theory_Manual
!
!
SUBROUTINE calculate_ZT_incident_field_sources(xcoord,ycoord,Eamplitude,Ex,Ey,Ez,Hx,Hy,Hz,kx,ky,kz, &
ground_plane_present,ground_plane_x,ground_plane_y,ground_plane_theta, &
length,n_modes,shield_conductor,TI,Tdi,Tdz,c1,c2,c1b)
USE type_specifications
USE constants
USE general_module
IMPLICIT NONE
! variables passed to subroutine
integer,intent(IN) :: n_modes ! input: number of modes in the illuminated domain
real(dp),intent(IN) :: xcoord(n_modes+1),ycoord(n_modes+1) ! input: centre coordinates of conductors
real(dp),intent(IN) :: Eamplitude,Ex,Ey,Ez,Hx,Hy,Hz,kx,ky,kz ! input: incident field specification
logical,intent(IN) :: ground_plane_present ! input: flag indicating the presence of a ground plane
real(dp),intent(IN) :: ground_plane_x,ground_plane_y ! input: x and y coordinates of a point on the ground plane
real(dp),intent(IN) :: ground_plane_theta ! input: angle of the ground plane from the x axis
real(dp),intent(IN) :: length ! input: length of transmission line
integer,intent(IN) :: shield_conductor ! input: the number of the shield conductor
real(dp),intent(IN) :: TI(n_modes,n_modes) ! input: mode decomposition matrix
real(dp),intent(IN) :: Tdi(n_modes) ! input: mode delays
real(dp),intent(OUT) :: c1(n_modes),c2(n_modes),c1b(n_modes) ! output: constants for controlled sources in shielded domains
real(dp),intent(OUT) :: Tdz ! output: incident field delay time
! local variables
integer :: n_conductors
real(dp) :: xk,yk
real(dp) :: rvx,rvy,rvz
real(dp) :: Tx(n_modes),dk,kw_rx,kw_ry,kw_r,vw_r
real(dp) :: vi
real(dp) :: Tsum
! loop variables
integer :: i,k
! START
if(verbose) write(*,*)'CALLED: calculate_ZT_incident_field_sources'
n_conductors=n_modes+1
if(verbose) then
write(*,*)'n_modes=',n_modes
write(*,*)'shield_conductor=',shield_conductor
end if
! Zero the coefficients initially
c1(:)=0d0
c2(:)=0d0
c1b(:)=0d0
if (Eamplitude.eq.0d0) then ! there is no incident field so return zero constants
return
end if
! calculate 1/velocity in each direction (avoids divide by zeros using reciprocal values)
! obtained from Theory_Manual_Eqn 3.136
rvx=kx/c0
rvy=ky/c0
rvz=kz/c0
Tdz=length*rvz
! loop over all conductors except the reference conductor
do k=1,n_conductors-1
! Assume that the final (reference) conductor lies at the origin of the xy plane
! and calculate the vector xk,yk from the reference conductor to conductor k.
! If there is a ground plane then calculate the vector to the closest point on the ground plane
! i.e. in the y direction since the ground plane is along the x axis.
if (ground_plane_present) then
! only the height over the ground plane matters so set x coordinate to zero and y is the height over ground
xk=0d0
else
xk=xcoord(k)-xcoord(n_modes+1)
end if
yk=ycoord(k)-ycoord(n_modes+1)
! distance from this conductor to the reference conductor
dk=sqrt(xk*xk+yk*yk)
! unit vector from this conductor to the reference conductor
kw_rx=xk/dk
kw_ry=yk/dk
! project the k vector along this direction
kw_r=kx*kw_rx+ky*kw_ry
! reciprocal velocity in this direction
vw_r=kw_r/c0
! Tx definition in Xie paper - see also Theory_Manual_Section 3.8 comment in the text below equation 3.198
! where here we have generalised to allow for general conductor offsets in the x-y plane of the bundle
Tx(k)=length*vw_r
end do
! Calculate C1(i), C2(i) , C1b(i) where i is the source domain mode.
! We only have contributions relating to the shield conductor whose transfer impedance we are
! including in the model.
! loop over modes, i in the source domain
do i=1,n_modes
! loop over all conductors except the reference conductor
do k=1,n_conductors-1
! Again, assume that the final (reference) conductor lies at the origin of the xy plane
! and calculate the vector xk,yk from the reference conductor to conductor k.
! If there is a ground plane then calculate the vector to the closest point on the ground plane
! i.e. in the y direction since the ground plane is along the x axis.
if (ground_plane_present) then
xk=0d0
else
xk=xcoord(k)-xcoord(n_modes+1)
end if
yk=ycoord(k)-ycoord(n_modes+1)
dk=sqrt(xk*xk+yk*yk)
! note c1,c2 are used to calculate the response of mode i due to excitations on all conductors, k
! hence the summation with over k with coefficients TI(k,i)
! See the two coefficients for the delayed incident field in Theory_Manual_Eqn 3.195 to 3.198
c1(i)=c1(i)+dk*length*(-Ez*Tx(k) +(Ex*xk/dk+Ey*yk/dk)*(Tdz-Tdi(i)) )*TI(k,i)
c2(i)=c2(i)+dk*length*(-Ez*Tx(k) +(Ex*xk/dk+Ey*yk/dk)*(Tdz+Tdi(i)) )*TI(k,i)
! C1b is for the special case when Tdz=Tdi, see the last paragraph in Theory_Manual_Section 3.8.3
c1b(i)=c1b(i)+dk*length*( Ex*xk/dk+Ey*yk/dk )*TI(k,i)
end do ! next conductor
end do ! next mode
if (ground_plane_present) then ! See Theory_Manual_Section 3.7.2
! the alpha terms are doubled
c1(:)=2d0*c1(:)
c2(:)=2d0*c2(:)
c1b(:)=2d0*c1b(:)
end if
if (.NOT.verbose) RETURN
write(*,*)'calculate_incident_field_sources'
write(*,*)'ex=',ex
write(*,*)'ey=',ey
write(*,*)'ez=',ez
write(*,*)'kx=',kx
write(*,*)'ky=',ky
write(*,*)'kz=',kz
write(*,*)'rvx=',rvx
write(*,*)'rvy=',rvy
write(*,*)'rvz=',rvz
write(*,*)'Tdz=',Tdz
! loop over conductors
do k=1,n_modes
xk=xcoord(k)-xcoord(n_modes+1)
yk=ycoord(k)-ycoord(n_modes+1)
! distance from this conductor to the reference conductor
dk=sqrt(xk*xk+yk*yk)
! unit vector from this conductor to the reference conductor
kw_rx=xk/dk
kw_ry=yk/dk
! project the k vector along this direction
kw_r=kx*kw_rx+ky*kw_ry
write(*,*)'conductor ',k
write(*,*)'xk',xk
write(*,*)'yk',yk
write(*,*)'dk=',dk
write(*,*)'kw_rx=',kw_rx
write(*,*)'kw_ry=',kw_ry
write(*,*)'kw_r=',kw_r
write(*,*)'Tx=',Tx(k)
end do
! loop over modes, i
do i=1,n_modes
write(*,*)'mode ',i
write(*,*)'Tdi=',Tdi(i)
write(*,*)'Tdi(i)+Tdz=',Tdi(i)+Tdz
write(*,*)'c1=',c1(i)
write(*,*)'c2=',c2(i)
write(*,*)'c1b=',c1b(i)
end do
RETURN
END SUBROUTINE calculate_ZT_incident_field_sources
!
! NAME
! calc_incident_field_values
!
! DESCRIPTION
! given coordinates in space and frequency calculate the incident E and H field component values
!
! COMMENTS
!
!
! HISTORY
!
! started 29/04/2015 CJS
! 8/5/2017 CJS: Include references to Theory_Manual
!
!
SUBROUTINE calc_incident_field_FD_values(x,y,z,f,Eamplitude,Ex,Ey,Ez,Hx,Hy,Hz,kx,ky,kz, &
Ex_value,Ey_value,Ez_value,Hx_value,Hy_value,Hz_value)
USE type_specifications
USE constants
IMPLICIT NONE
complex(dp),intent(IN) :: Eamplitude ! E field amplitude
real(dp),intent(IN) :: Ex,Ey,Ez,Hx,Hy,Hz,kx,ky,kz ! Cartesian components of field and propgation vector
real(dp),intent(IN) :: x,y,z ! coordinates in 3D space of field evaluation point
real(dp),intent(IN) :: f ! frequency
complex(dp),intent(OUT) :: Ex_value,Ey_value,Ez_value,Hx_value,Hy_value,Hz_value ! output cartesian field values
! local variables
real(dp) :: w ! angular frequency
complex(dp) :: phase ! phase at field evaluation point
! START
! Theory_Manual_Eqn 3.140
w=2d0*pi*f
phase=exp( -j*(w/c0)*( kx*x+ky*y+kz*z ) )
Ex_value=Eamplitude*Ex*phase
Ey_value=Eamplitude*Ey*phase
Ez_value=Eamplitude*Ez*phase
! Theory_Manual_Eqn 3.140 and 3.142
Hx_value=Eamplitude*Hx*phase
Hy_value=Eamplitude*Hy*phase
Hz_value=Eamplitude*Hz*phase
RETURN
END SUBROUTINE calc_incident_field_FD_values
!
! NAME
! calc_incident_field_FD_values_GP
!
! DESCRIPTION
! given coordinates in space and frequency calculate the incident E and H field component values
! with a ground plane present
! The ground plane is assumed to lie along the x axis
!
! COMMENTS
!
!
! HISTORY
!
! started 28/06/2016 CJS
!
!
SUBROUTINE calc_incident_field_FD_values_GP(x,y,z,f,Eamplitude,Ex,Ey,Ez,Hx,Hy,Hz,kx,ky,kz, &
Ex_value,Ey_value,Ez_value,Hx_value,Hy_value,Hz_value)
USE type_specifications
USE constants
IMPLICIT NONE
complex(dp),intent(IN) :: Eamplitude ! E field amplitude
real(dp),intent(IN) :: Ex,Ey,Ez,Hx,Hy,Hz,kx,ky,kz ! Cartesian components of field and propgation vector
real(dp),intent(IN) :: x,y,z ! coordinates in 3D space of field evaluation point
real(dp),intent(IN) :: f ! frequency
complex(dp),intent(OUT) :: Ex_value,Ey_value,Ez_value,Hx_value,Hy_value,Hz_value ! output cartesian field values
! local variables
real(dp) :: w ! angular frequency
complex(dp) :: phase ! phase at field evaluation point
! START
w=2d0*pi*f
! Theory_Manual_Eqn 3.140 with the addition of a reflected plane wave from the ground plane (y=0 plane)
! in which ky_reflected=-ky_incident and
! Ex_reflected=-Ex_incident, Ez_reflected=-Ez_incident, Hy_reflected=-Hy_incident
! Incident plane wave
phase=exp( -j*(w/c0)*( kx*x+ky*y+kz*z ) )
Ex_value=Eamplitude*Ex*phase
Ey_value=Eamplitude*Ey*phase
Ez_value=Eamplitude*Ez*phase
Hx_value=Eamplitude*Hx*phase
Hy_value=Eamplitude*Hy*phase
Hz_value=Eamplitude*Hz*phase
! Add reflected plane wave
phase=exp( -j*(w/c0)*(kx*x-ky*y+kz*z ) )
Ex_value=Ex_value-Eamplitude*Ex*phase
Ey_value=Ey_value+Eamplitude*Ey*phase
Ez_value=Ez_value-Eamplitude*Ez*phase
Hx_value=Hx_value+Eamplitude*Hx*phase
Hy_value=Hy_value-Eamplitude*Hy*phase
Hz_value=Hz_value+Eamplitude*Hz*phase
RETURN
END SUBROUTINE calc_incident_field_FD_values_GP
!
! NAME
! calculate_lumped_incident_field_sources
!
! DESCRIPTION
! calculate the lumped sources at z=l due to incident field excitation
!
!
! COMMENTS
! The code is based on Theory_Manual_Section 2.4
! Detailed discussions and derivations are found in
! C.R. Paul, "Analysis of Multiconductor Transmission Lines" 1st edition, section 7.2.1.
!
! The sources are calculated by numerical integration
!
! HISTORY
!
! started 29/04/2015 CJS ESA Spice cable modelling, Phase 1
! 8/5/2017 CJS: Include references to Theory_Manual
!
!
SUBROUTINE calculate_lumped_incident_field_sources(xcoord,ycoord,is_shielded,Eamplitude,Ex,Ey,Ez,Hx,Hy,Hz,kx,ky,kz, &
ground_plane_present,length,f,VFT,IFT,dim, &
T,TI,Y,Z,ZC,YC,GAMMA_C)
USE type_specifications
USE constants
USE maths
IMPLICIT NONE
integer,intent(IN) :: dim ! matrix system dimension
real(dp),intent(IN) :: xcoord(dim+1),ycoord(dim+1) ! note that we need the reference conductor position in space
logical,intent(IN) :: is_shielded(dim) ! flag to indicated shielded conductors
complex(dp),intent(IN) :: Eamplitude ! incident field amplitude
real(dp),intent(IN) :: Ex,Ey,Ez,Hx,Hy,Hz,kx,ky,kz ! incident field cartesian field components and propagation vector
real(dp),intent(IN) :: length ! transmission line length
real(dp),intent(IN) :: f ! frequency
logical,intent(IN) :: ground_plane_present ! flag to indicate the presence of a ground plane
complex(dp),intent(IN) :: T(dim,dim) ! modal decomposition matrix
complex(dp),intent(IN) :: TI(dim,dim) ! modal decomposition matrix (inverse of [T])
complex(dp),intent(IN) :: Y(dim,dim) ! global admittance matrix
complex(dp),intent(IN) :: Z(dim,dim) ! global impedance matrix
complex(dp),intent(IN) :: ZC(dim,dim) ! characteristic impedance matrix
complex(dp),intent(IN) :: YC(dim,dim) ! characteristic admittance matrix
complex(dp),intent(IN) :: GAMMA_C(dim) ! modal propagation constants
complex(dp),intent(OUT) :: VFT(dim),IFT(dim) ! incident field voltage and current sources
! local variables
real(dp) :: xp,yp,zp
real(dp) :: vx,vy,norm
real(dp) :: w,lambda
real(dp) :: dz ! space step for numerical integration
integer :: nz,zloop ! loop variables for integration along the transmission line
! Cartesian field values on a conductor
complex(dp) :: Ex_c,Ey_c,Ez_c
complex(dp) :: Hx_c,Hy_c,Hz_c
! Cartesian field values on the reference conductor
complex(dp) :: Ex_r,Ey_r,Ez_r
complex(dp) :: Hx_r,Hy_r,Hz_r
! Temporary matrices for calculating the chain parameter matrices
complex(dp) :: M1(dim,dim),YI(dim,dim)
complex(dp) :: sinh_gamma_z(dim,dim)
complex(dp) :: cosh_gamma_z(dim,dim)
complex(dp) :: TSTI(dim,dim),TCTI(dim,dim)
! chain parameter matrix elements
complex(dp) :: PHI_11(dim,dim)
complex(dp) :: PHI_12(dim,dim)
complex(dp) :: PHI_21(dim,dim)
complex(dp) :: PHI_22(dim,dim)
!temporary vectors used in the calculations
complex(dp) :: VF1(dim),VF2(dim),VF3(dim),VF(dim),IF1(dim),IF(dim)
complex(dp) :: TV1(dim),TV2(dim),TV3(dim),TV4(dim)
! error code for matrix inverse
integer :: ierr
! loop variables
integer :: conductor
integer :: i
! START
IFT(:)=(0d0,0d0)
VFT(:)=(0d0,0d0)
if (Eamplitude.eq.0d0) then ! there is no incident field so return with zero value source terms
return
end if
! calculate angular frequency(rad/s) and wavelength(m)
w=2d0*pi*f
lambda=c0/f
ierr=0 ! exit on error with the matrix inverse
CALL cinvert_Gauss_Jordan(Y,dim,YI,dim,ierr)
dz=lambda/20d0 ! space step for numerical integration
nz=NINT(length/dz)
! ensure a minimum number of integration points
if (nz.LT.10) nz=10
dz=length/nz
! calculate source integrals
! loop over the transmission line length
do zloop=1,nz
zp=(zloop-1)*dz+dz/2d0 ! z coordinate at the current point. We assume the integrand is uniform over intervals, dz.
! Calculate the chain parameter matrices for the current z value Theory_Manual_Eqns 2.58
sinh_gamma_z(:,:)=(0d0,0d0)
cosh_gamma_z(:,:)=(0d0,0d0)
do i=1,dim
cosh_gamma_z(i,i)=0.5d0*( exp( GAMMA_C(i)*(length-zp) )+exp( -GAMMA_C(i)*(length-zp) ) )
sinh_gamma_z(i,i)=0.5d0*( exp( GAMMA_C(i)*(length-zp) )-exp( -GAMMA_C(i)*(length-zp) ) )
end do
M1=matmul(T,cosh_gamma_z)
TCTI=matmul(M1,TI)
M1=matmul(T,sinh_gamma_z)
TSTI=matmul(M1,TI)
! Phi11
M1=matmul(YI,TCTI)
PHI_11=matmul(M1,Y)
! Phi12
M1=matmul(ZC,TSTI)
PHI_12=-M1
! Phi21
M1=matmul(TSTI,YC)
PHI_21=-M1
! Phi22
PHI_22=TCTI
! loop over conductors (other than the reference)
do conductor=1,dim
! calculate the cartesian field values at the current conductor and the reference conductor
if (.NOT.ground_plane_present) then
! get the field values at the reference conductor i.e. the (dim+1)th conductor
xp=xcoord(dim+1)
yp=ycoord(dim+1)
CALL calc_incident_field_FD_values(xp,yp,zp,f,Eamplitude,Ex,Ey,Ez,Hx,Hy,Hz, &
kx,ky,kz,Ex_r,Ey_r,Ez_r,Hx_r,Hy_r,Hz_r)
! get the field values at the conductor
xp=xcoord(conductor)
yp=ycoord(conductor)
CALL calc_incident_field_FD_values(xp,yp,zp,f,Eamplitude,Ex,Ey,Ez,Hx,Hy,Hz, &
kx,ky,kz,Ex_c,Ey_c,Ez_c,Hx_c,Hy_c,Hz_c)
! calculate a vector from the reference to the conductor
vx=xp-xcoord(dim+1)
vy=yp-ycoord(dim+1)
else
! get the field values at the reference conductor i.e. the (dim+1)th conductor
! under the conductor we are interested in
xp=xcoord(dim+1) ! The 'reference' is at the origin when a ground plane is present
yp=ycoord(dim+1)
CALL calc_incident_field_FD_values_GP(xp,yp,zp,f,Eamplitude,Ex,Ey,Ez,Hx,Hy,Hz,kx,ky,kz, &
Ex_r,Ey_r,Ez_r,Hx_r,Hy_r,Hz_r)
! get the field values at the conductor
xp=xcoord(conductor)
yp=ycoord(conductor)
CALL calc_incident_field_FD_values_GP(xp,yp,zp,f,Eamplitude,Ex,Ey,Ez,Hx,Hy,Hz,kx,ky,kz, &
Ex_c,Ey_c,Ez_c,Hx_c,Hy_c,Hz_c)
! calculate a vector from the reference to the conductor
vx=xp-xcoord(dim+1) ! Made the vector consistent with the field evaluation points 16/8/2016
vy=yp-ycoord(dim+1) ! The 'reference' is at the origin when a ground plane is present
end if
! the first part is due to the z component of the E field
VF1(conductor)=(Ez_c-Ez_r) ! C. Paul, equation 7.24(e), Ez contribution ! Theory_Manual_Eqn 2.53(second term) using 2.54
! the second part is due to the z derivative of the incident field integrated from the reference to conductor
! note the field is assumed to be linearly varying between its endpoint values in the integration
VF2(conductor)=j*(w/c0)*kz*(0.5d0*(Ex_c+Ex_r)*vx+0.5d0*(Ey_c+Ey_r)*vy) ! C. Paul, equation 7.24(e), Et contribution, Theory_Manual_Eqn 2.53, first term
! An alternative is the time derivative of the B field integrated from reference to conductor
! VF3(conductor)=j*w*mu0*(-0.5d0*(Hx_c+Hx_r)*vy+0.5d0*(Hy_c+Hy_r)*vx) ! C. Paul, equation 7.24(c), B.dA contribution (H field form)
! the IF source term is due to the incident field integrated from the reference to conductor
! note the field is assumed to be linearly varying between its endpoint values in the integration
! this needs to be pre-multiplied by G+jwC but this happens later...
! C. Paul, equation 7.24(d), Et contribution, Theory_Manual_Eqn 2.55 using a linear interpolation of the field
! between the reference conductor and the conductor k.
IF1(conductor)=-(0.5d0*(Ex_c+Ex_r)*vx+0.5d0*(Ey_c+Ey_r)*vy)
end do ! next conductor
VF(:)=VF1(:)+VF2(:) ! E field form
! VF(:)=VF3(:) ! H field form
! multiply IF1 by Y, the MTL admittance matrix (G+jwC) ! Theory_Manual_Eqn 2.56 transformed to the time domain
IF=matmul(Y,IF1)
! Special process for shielded conductors - set IF to zero
do conductor=1,dim
if (is_shielded(conductor)) then
! set the current sources to zero, note that voltage sources must remain even for shielded conductors.
! Note also that provided shielded cables are centred on their respective shield then this step should
! not be necessary due to the structure of the [Y] matrix and (IF)=[Y](IF1)
IF(conductor)=(0d0,0d0)
end if
end do ! next conductor
! add the contribution to the integration in Theory_Manual_Eqns 2.60
! C. Paul, equation 7.29b,7.29c
TV1=matmul(PHI_11,VF)
TV2=matmul(PHI_12,IF)
TV3=matmul(PHI_21,VF)
TV4=matmul(PHI_22,IF)
! Add contribution to the integral over z assuming constant value of integrand over this section, dz
do conductor=1,dim
VFT(conductor)=VFT(conductor)+dz*(TV1(conductor)+TV2(conductor))
IFT(conductor)=IFT(conductor)+dz*(TV3(conductor)+TV4(conductor))
end do
end do ! next z value
END SUBROUTINE calculate_lumped_incident_field_sources