src/gray_core.f90: make integrator configurable
This change makes the integration method of the raytracing equations configurable and significantly simplifies the integrator subroutine by moving the implementation details outside.
This commit is contained in:
parent
1b814fcb8a
commit
c9c20198a7
@ -26,6 +26,14 @@ nstep = 12000
|
|||||||
; 2: real part of the eikonal (S_r)
|
; 2: real part of the eikonal (S_r)
|
||||||
idst = 0
|
idst = 0
|
||||||
|
|
||||||
|
; Choice of the integration method
|
||||||
|
; 0: Explicit Euler (1⁰ order)
|
||||||
|
; 1: Semi-implicit Euler (1⁰ order, symplectic)
|
||||||
|
; 2: Velocity Verlet (2⁰ order, symplectic)
|
||||||
|
; 3: 2-stage Runge-Kutta (2⁰ order)
|
||||||
|
; 4: 4-stage Runge-Kutta (4⁰ order)
|
||||||
|
integrator = 4
|
||||||
|
|
||||||
|
|
||||||
[ecrh_cd]
|
[ecrh_cd]
|
||||||
; Choice of the power absorption model
|
; Choice of the power absorption model
|
||||||
|
@ -3,14 +3,14 @@ module beamdata
|
|||||||
implicit none
|
implicit none
|
||||||
|
|
||||||
integer, save :: nray,nrayr,nrayth,nstep,jkray1
|
integer, save :: nray,nrayr,nrayth,nstep,jkray1
|
||||||
real(wp_), save :: dst,h,hh,h6,rwmax,twodr2
|
real(wp_), save :: dst,rwmax,twodr2
|
||||||
|
|
||||||
contains
|
contains
|
||||||
|
|
||||||
subroutine init_btr(rtrparam,ywork,ypwork,xc,du1,gri,ggri,psjki,ppabs,ccci, &
|
subroutine init_btr(rtrparam,ywork,ypwork,xc,du1,gri,ggri,psjki,ppabs,ccci, &
|
||||||
tau0,alphaabs0,dids0,ccci0,p0jk,ext,eyt,iiv)
|
tau0,alphaabs0,dids0,ccci0,p0jk,ext,eyt,iiv)
|
||||||
use gray_params, only : raytracing_parameters
|
use gray_params, only : raytracing_parameters
|
||||||
use const_and_precisions, only : half,two
|
use const_and_precisions, only : two
|
||||||
implicit none
|
implicit none
|
||||||
type(raytracing_parameters), intent(inout) :: rtrparam
|
type(raytracing_parameters), intent(inout) :: rtrparam
|
||||||
real(wp_), dimension(:,:), intent(out), pointer :: ywork,ypwork, &
|
real(wp_), dimension(:,:), intent(out), pointer :: ywork,ypwork, &
|
||||||
@ -24,10 +24,6 @@ contains
|
|||||||
integer :: jray1
|
integer :: jray1
|
||||||
|
|
||||||
dst = rtrparam%dst
|
dst = rtrparam%dst
|
||||||
h = dst
|
|
||||||
hh = h*half
|
|
||||||
h6 = h/6.0_wp_
|
|
||||||
|
|
||||||
nrayr = rtrparam%nrayr
|
nrayr = rtrparam%nrayr
|
||||||
nrayth = rtrparam%nrayth
|
nrayth = rtrparam%nrayth
|
||||||
rwmax = rtrparam%rwmax
|
rwmax = rtrparam%rwmax
|
||||||
|
@ -5,6 +5,15 @@ module gray_core
|
|||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
|
|
||||||
|
abstract interface
|
||||||
|
function rhs_function(y) result(f)
|
||||||
|
! Function passed to the integrator subroutine
|
||||||
|
use const_and_precisions, only : wp_
|
||||||
|
real(wp_), intent(in) :: y(6)
|
||||||
|
real(wp_) :: f(6)
|
||||||
|
end function
|
||||||
|
end interface
|
||||||
|
|
||||||
contains
|
contains
|
||||||
|
|
||||||
subroutine gray_main(params, data, results, error, rhout)
|
subroutine gray_main(params, data, results, error, rhout)
|
||||||
@ -265,7 +274,9 @@ contains
|
|||||||
do jk=1,params%raytracing%nray
|
do jk=1,params%raytracing%nray
|
||||||
if(iwait(jk)) cycle ! jk ray is waiting for next pass
|
if(iwait(jk)) cycle ! jk ray is waiting for next pass
|
||||||
stv(jk) = stv(jk) + params%raytracing%dst ! current ray step
|
stv(jk) = stv(jk) + params%raytracing%dst ! current ray step
|
||||||
call rkstep(sox,bres,xgcn,yw(:,jk),ypw(:,jk),gri(:,jk),ggri(:,:,jk),igrad_b)
|
call integrator(yw(:, jk), ypw(:, jk), rhs, &
|
||||||
|
params%raytracing%dst, &
|
||||||
|
params%raytracing%integrator)
|
||||||
end do
|
end do
|
||||||
! update position and grad
|
! update position and grad
|
||||||
if(igrad_b == 1) call gradi_upd(yw,ak0,xc,du1,gri,ggri)
|
if(igrad_b == 1) call gradi_upd(yw,ak0,xc,du1,gri,ggri)
|
||||||
@ -613,6 +624,39 @@ contains
|
|||||||
stnext,stv,p0ray,taus,tau1,etau1,cpls,cpl1,lgcpl1,jphi_beam, &
|
stnext,stv,p0ray,taus,tau1,etau1,cpls,cpl1,lgcpl1,jphi_beam, &
|
||||||
pins_beam,currins_beam,dpdv_beam,jcd_beam,psipv,chipv)
|
pins_beam,currins_beam,dpdv_beam,jcd_beam,psipv,chipv)
|
||||||
! =========== free memory END ===========
|
! =========== free memory END ===========
|
||||||
|
|
||||||
|
contains
|
||||||
|
|
||||||
|
! Functions that needs the scope of gray_main
|
||||||
|
|
||||||
|
function rhs(y) result(dery)
|
||||||
|
! Computes the right-hand-side terms of the ray equations
|
||||||
|
! To be passed to the integrator subroutine
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
! function arguments
|
||||||
|
real(wp_), dimension(6), intent(in) :: y ! (x̅, N̅)
|
||||||
|
! result
|
||||||
|
real(wp_), dimension(6) :: dery
|
||||||
|
|
||||||
|
! local variables
|
||||||
|
real(wp_) :: xg, yg
|
||||||
|
real(wp_), dimension(3) :: xv, anv, bv, derxg, deryg
|
||||||
|
real(wp_), dimension(3, 3) :: derbv
|
||||||
|
|
||||||
|
xv = y(1:3) ! x̅ position
|
||||||
|
anv = y(4:6) ! N̅ refractive index
|
||||||
|
|
||||||
|
! computes derivatives of plasma quantities: B̅, ∇X, ∇Y, ∇B̅
|
||||||
|
! (these are needed for the next part)
|
||||||
|
call plas_deriv(xv, bres, xgcn, dens, btot, bv, derbv, &
|
||||||
|
xg, yg, derxg, deryg)
|
||||||
|
|
||||||
|
! computes derivatives of dispersion relation: ∂Λ/∂x̅, ∂Λ/∂N̅
|
||||||
|
call disp_deriv(anv, sox, xg, yg, derxg, deryg, bv, derbv, &
|
||||||
|
gri(:, jk), ggri(:, :, jk), igrad_b, dery)
|
||||||
|
end function rhs
|
||||||
|
|
||||||
end subroutine gray_main
|
end subroutine gray_main
|
||||||
|
|
||||||
|
|
||||||
@ -966,55 +1010,65 @@ contains
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
subroutine rkstep(sox,bres,xgcn,y,yp,dgr,ddgr,igrad)
|
subroutine integrator(y, yp, f, h, method)
|
||||||
! Runge-Kutta integrator
|
! Integrator of the raytracing equations
|
||||||
! use gray_params, only : igrad
|
|
||||||
use beamdata, only : h,hh,h6
|
|
||||||
implicit none
|
implicit none
|
||||||
real(wp_), intent(in) :: bres,xgcn
|
|
||||||
real(wp_), dimension(6), intent(inout) :: y
|
|
||||||
real(wp_), dimension(6), intent(in) :: yp
|
|
||||||
real(wp_), dimension(3), intent(in) :: dgr
|
|
||||||
real(wp_), dimension(3,3), intent(in) :: ddgr
|
|
||||||
integer, intent(in) :: igrad,sox
|
|
||||||
|
|
||||||
real(wp_), dimension(6) :: yy,fk1,fk2,fk3,fk4
|
real(wp_), dimension(6), intent(inout) :: y ! y̅ = (x̅, N̅)
|
||||||
|
real(wp_), dimension(6), intent(in) :: yp ! y̅˙ = (dx̅/dσ, dN̅/dσ)
|
||||||
|
procedure(rhs_function) :: f ! dy̅/dσ = f̅(y̅)
|
||||||
|
real(wp_), intent(in) :: h ! step size
|
||||||
|
integer, intent(in) :: method
|
||||||
|
|
||||||
fk1 = yp
|
|
||||||
yy = y + fk1*hh
|
|
||||||
call rhs(sox,bres,xgcn,yy,dgr,ddgr,fk2,igrad)
|
|
||||||
yy = y + fk2*hh
|
|
||||||
call rhs(sox,bres,xgcn,yy,dgr,ddgr,fk3,igrad)
|
|
||||||
yy = y + fk3*h
|
|
||||||
call rhs(sox,bres,xgcn,yy,dgr,ddgr,fk4,igrad)
|
|
||||||
|
|
||||||
y = y + h6*(fk1 + 2*fk2 + 2*fk3 + fk4)
|
|
||||||
end subroutine rkstep
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
subroutine rhs(sox,bres,xgcn,y,dgr,ddgr,dery,igrad)
|
|
||||||
! Compute right-hand side terms of the ray equations (dery)
|
|
||||||
! used in R-K integrator
|
|
||||||
implicit none
|
|
||||||
! arguments
|
|
||||||
real(wp_), dimension(6), intent(in) :: y
|
|
||||||
real(wp_), intent(in) :: bres,xgcn
|
|
||||||
real(wp_), dimension(3), intent(in) :: dgr
|
|
||||||
real(wp_), dimension(3,3), intent(in) :: ddgr
|
|
||||||
real(wp_), dimension(6), intent(out) :: dery
|
|
||||||
integer, intent(in) :: igrad,sox
|
|
||||||
! local variables
|
! local variables
|
||||||
real(wp_) :: dens,btot,xg,yg
|
real(wp_), dimension(6) :: yy, k1, k2, k3, k4
|
||||||
real(wp_), dimension(3) :: xv,anv,bv,derxg,deryg
|
|
||||||
real(wp_), dimension(3,3) :: derbv
|
|
||||||
|
|
||||||
xv = y(1:3)
|
select case (method)
|
||||||
call plas_deriv(xv,bres,xgcn,dens,btot,bv,derbv,xg,yg,derxg,deryg)
|
case (0)
|
||||||
anv = y(4:6)
|
! Explicit Euler (1⁰ order)
|
||||||
call disp_deriv(anv,sox,xg,yg,derxg,deryg,bv,derbv,dgr,ddgr,igrad,dery)
|
y = y + yp*h
|
||||||
end subroutine rhs
|
|
||||||
|
|
||||||
|
case (1)
|
||||||
|
! Semi-implicit Euler (1⁰ order, symplectic)
|
||||||
|
! P = p - ∂H/∂q(q, p)
|
||||||
|
! Q = q + ∂H/∂p(q, P)
|
||||||
|
k1 = yp
|
||||||
|
y(4:6) = y(4:6) + k1(4:6)*h
|
||||||
|
k2 = f(y)
|
||||||
|
y(1:3) = y(1:3) + k2(1:3)*h
|
||||||
|
|
||||||
|
case (2)
|
||||||
|
! Velocity Verlet (2⁰ order, symplectic)
|
||||||
|
! p(n+½) = p(n) - ∂H/∂q(q(n), p(n))⋅h/2
|
||||||
|
! q(n+1) = q(n) + ∂H/∂p(q(n), p(n+½))⋅h
|
||||||
|
! p(n+1) = p(n+½) - ∂H/∂q(q(n+1), p(n+½))⋅h/2
|
||||||
|
k1 = yp
|
||||||
|
y(4:6) = y(4:6) + k1(4:6)*h/2
|
||||||
|
k2 = f(y)
|
||||||
|
y(1:3) = y(1:3) + k2(1:3)*h
|
||||||
|
k3 = f(y)
|
||||||
|
y(4:6) = y(4:6) + k3(4:6)*h/2
|
||||||
|
|
||||||
|
case (3)
|
||||||
|
! 2-stage Runge-Kutta (2⁰ order)
|
||||||
|
k1 = yp
|
||||||
|
yy = y + k1*h
|
||||||
|
k2 = f(yy)
|
||||||
|
yy = y + k2*h
|
||||||
|
y = y + (k1 + k2)*h/2
|
||||||
|
|
||||||
|
case default
|
||||||
|
! 4-stage Runge-Kutta (4⁰ order)
|
||||||
|
k1 = yp
|
||||||
|
yy = y + k1*h/2
|
||||||
|
k2 = f(yy)
|
||||||
|
yy = y + k2*h/2
|
||||||
|
k3 = f(yy)
|
||||||
|
yy = y + k3*h
|
||||||
|
k4 = f(yy)
|
||||||
|
y = y + (k1 + 2*k2 + 2*k3 + k4)*h/6
|
||||||
|
end select
|
||||||
|
end subroutine integrator
|
||||||
|
|
||||||
|
|
||||||
subroutine ywppla_upd(xv,anv,dgr,ddgr,sox,bres,xgcn,dery,psinv,dens,btot, &
|
subroutine ywppla_upd(xv,anv,dgr,ddgr,sox,bres,xgcn,dery,psinv,dens,btot, &
|
||||||
|
@ -5,6 +5,9 @@ module gray_params
|
|||||||
integer, parameter :: lenfnm = 256
|
integer, parameter :: lenfnm = 256
|
||||||
integer, parameter :: headw = 132, headl = 21
|
integer, parameter :: headw = 132, headl = 21
|
||||||
|
|
||||||
|
! Note: when adding/removing a parameter remember to keep
|
||||||
|
! the gray_params.sh script in sync with this file
|
||||||
|
|
||||||
! Antenna/wave launcher parameters
|
! Antenna/wave launcher parameters
|
||||||
type antenna_parameters
|
type antenna_parameters
|
||||||
! From gray_params.data:
|
! From gray_params.data:
|
||||||
@ -55,6 +58,7 @@ module gray_params
|
|||||||
integer :: igrad ! Complex eikonal switch
|
integer :: igrad ! Complex eikonal switch
|
||||||
integer :: nstep ! Max number of integration steps
|
integer :: nstep ! Max number of integration steps
|
||||||
integer :: idst ! Choice of the integration variable
|
integer :: idst ! Choice of the integration variable
|
||||||
|
integer :: integrator ! Choice of the integration method
|
||||||
integer :: ipass ! Number of plasma passes
|
integer :: ipass ! Number of plasma passes
|
||||||
integer :: ipol ! Whether to compute wave polarisation
|
integer :: ipol ! Whether to compute wave polarisation
|
||||||
end type
|
end type
|
||||||
@ -365,6 +369,11 @@ contains
|
|||||||
read(u, *) params%output%istpr, params%output%istpl
|
read(u, *) params%output%istpr, params%output%istpl
|
||||||
|
|
||||||
close(u)
|
close(u)
|
||||||
|
|
||||||
|
! Default values of parameters introduced after
|
||||||
|
! gray_params.data has been deprecated
|
||||||
|
params%raytracing%integrator = 4
|
||||||
|
|
||||||
end subroutine read_gray_params
|
end subroutine read_gray_params
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ sets='antenna equilibrium profiles raytracing ecrh_cd output misc'
|
|||||||
antenna='alpha beta power psi chi iox ibeam filenm fghz pos w ri phi'
|
antenna='alpha beta power psi chi iox ibeam filenm fghz pos w ri phi'
|
||||||
equilibrium='ssplps ssplf factb sgnb sgni ixp iequil icocos ipsinorm idesc ifreefmt filenm'
|
equilibrium='ssplps ssplf factb sgnb sgni ixp iequil icocos ipsinorm idesc ifreefmt filenm'
|
||||||
profiles='psnbnd sspld factne factte iscal irho iprof filenm'
|
profiles='psnbnd sspld factne factte iscal irho iprof filenm'
|
||||||
raytracing='rwmax dst nrayr nrayth nstep igrad idst ipass ipol'
|
raytracing='rwmax dst nrayr nrayth nstep igrad idst ipass ipol integrator'
|
||||||
ecrh_cd='iwarm ilarm imx ieccd'
|
ecrh_cd='iwarm ilarm imx ieccd'
|
||||||
output='ipec nrho istpr istpl'
|
output='ipec nrho istpr istpl'
|
||||||
misc='rwall'
|
misc='rwall'
|
||||||
|
Loading…
Reference in New Issue
Block a user