Gets electro-magnetic fields at position pos
or beam_grid indices ind
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(LocalEMFields), | intent(out) | :: | fields | Electro-magnetic fields at |
||
real(kind=Float64), | intent(in), | optional | dimension(3) | :: | pos | Position in beam grid coordinates |
integer(kind=Int32), | intent(in), | optional | dimension(3) | :: | ind | beam_grid indices |
integer(kind=Int32), | intent(in), | optional | :: | input_coords | Indicates coordinate system of inputs. Beam grid (0), machine (1) and cylindrical (2) |
|
integer(kind=Int32), | intent(in), | optional | :: | output_coords | Indicates coordinate system of outputs. Beam grid (0), machine (1) and cylindrical (2) |
subroutine get_fields(fields, pos, ind, input_coords, output_coords)
!+ Gets electro-magnetic fields at position `pos` or [[libfida:beam_grid]] indices `ind`
type(LocalEMFields),intent(out) :: fields
!+ Electro-magnetic fields at `pos`/`ind`
real(Float64), dimension(3), intent(in), optional :: pos
!+ Position in beam grid coordinates
integer(Int32), dimension(3), intent(in), optional :: ind
!+ [[libfida:beam_grid]] indices
integer(Int32), intent(in), optional :: input_coords
!+ Indicates coordinate system of inputs. Beam grid (0), machine (1) and cylindrical (2)
integer(Int32), intent(in), optional :: output_coords
!+ Indicates coordinate system of outputs. Beam grid (0), machine (1) and cylindrical (2)
logical :: inp
real(Float64), dimension(3) :: xyz, uvw
real(Float64), dimension(3) :: uvw_bfield, uvw_efield
real(Float64), dimension(3) :: xyz_bfield, xyz_efield
real(Float64) :: phi, s, c
type(InterpolCoeffs3D) :: coeffs
integer :: i, j, k, k2, mc, ocs, ics
fields%in_plasma = .False.
if(present(input_coords)) then
ics = input_coords
else
ics = 0
endif
if(present(output_coords)) then
ocs = output_coords
else
ocs = 0
endif
if(present(ind)) call get_position(ind,xyz)
if(present(pos)) then
if(ics.eq.0) then
xyz = pos
call xyz_to_uvw(xyz, uvw)
endif
if(ics.eq.1) then
uvw = pos
call uvw_to_xyz(uvw, xyz)
endif
endif
call in_plasma(xyz,inp,0,coeffs)
if(inp) then
i = coeffs%i
j = coeffs%j
k = coeffs%k
if(inter_grid%nphi .eq. 1) then
k2 = min(k+1,inter_grid%nphi)
else
k2 = k+1
endif
fields = coeffs%b111*equil%fields(i,j,k) + coeffs%b121*equil%fields(i,j+1,k) + &
coeffs%b112*equil%fields(i,j,k2) + coeffs%b122*equil%fields(i,j+1,k2) + &
coeffs%b211*equil%fields(i+1,j,k) + coeffs%b221*equil%fields(i+1,j+1,k) + &
coeffs%b212*equil%fields(i+1,j,k2) + coeffs%b222*equil%fields(i+1,j+1,k2)
phi = atan2(uvw(2),uvw(1))
s = sin(phi) ; c = cos(phi)
!Convert cylindrical coordinates to uvw
uvw_bfield(1) = c*fields%br - s*fields%bt
uvw_bfield(2) = s*fields%br + c*fields%bt
uvw_bfield(3) = fields%bz
uvw_efield(1) = c*fields%er - s*fields%et
uvw_efield(2) = s*fields%er + c*fields%et
uvw_efield(3) = fields%ez
if(ocs.eq.0) then
!Represent fields in beam grid coordinates
xyz_bfield = matmul(beam_grid%inv_basis,uvw_bfield)
xyz_efield = matmul(beam_grid%inv_basis,uvw_efield)
fields%pos = xyz
endif
if(ocs.eq.1) then
xyz_bfield = uvw_bfield
xyz_efield = uvw_efield
fields%pos = uvw
endif
!Calculate field directions and magnitudes
fields%b_abs = norm2(xyz_bfield)
fields%e_abs = norm2(xyz_efield)
if(fields%b_abs.gt.0.d0) fields%b_norm = xyz_bfield/fields%b_abs
if(fields%e_abs.gt.0.d0) fields%e_norm = xyz_efield/fields%e_abs
call calc_perp_vectors(fields%b_norm,fields%a_norm,fields%c_norm)
fields%uvw = uvw
fields%in_plasma = .True.
fields%coords = ocs
fields%b = coeffs
endif
end subroutine get_fields