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:
Michele Guerini Rocco 2023-03-30 00:12:34 +02:00
parent 1b814fcb8a
commit c9c20198a7
Signed by: rnhmjoj
GPG Key ID: BFBAF4C975F76450
5 changed files with 116 additions and 49 deletions

View File

@ -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

View File

@ -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

View File

@ -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 ! (, )
! 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) ! position
anv = y(4:6) ! refractive index
! computes derivatives of plasma quantities: , X, Y,
! (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: Λ/, Λ/
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 ! = (, )
real(wp_), dimension(6), intent(in) :: yp ! ˙ = (dx̅/dσ, dN̅/dσ)
procedure(rhs_function) :: f ! dy̅/dσ = ()
real(wp_), intent(in) :: h ! step size
integer, intent(in) :: method
fk1 = yp ! local variables
yy = y + fk1*hh real(wp_), dimension(6) :: yy, k1, k2, k3, k4
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) select case (method)
end subroutine rkstep case (0)
! Explicit Euler (1 order)
y = y + yp*h
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
subroutine rhs(sox,bres,xgcn,y,dgr,ddgr,dery,igrad) case (3)
! Compute right-hand side terms of the ray equations (dery) ! 2-stage Runge-Kutta (2 order)
! used in R-K integrator k1 = yp
implicit none yy = y + k1*h
! arguments k2 = f(yy)
real(wp_), dimension(6), intent(in) :: y yy = y + k2*h
real(wp_), intent(in) :: bres,xgcn y = y + (k1 + k2)*h/2
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
real(wp_) :: dens,btot,xg,yg
real(wp_), dimension(3) :: xv,anv,bv,derxg,deryg
real(wp_), dimension(3,3) :: derbv
xv = y(1:3)
call plas_deriv(xv,bres,xgcn,dens,btot,bv,derbv,xg,yg,derxg,deryg)
anv = y(4:6)
call disp_deriv(anv,sox,xg,yg,derxg,deryg,bv,derbv,dgr,ddgr,igrad,dery)
end subroutine rhs
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, &

View File

@ -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

View File

@ -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'