diff --git a/src/korc_collisions.f90 b/src/korc_collisions.f90 index 29fe14b3..0a59f5ca 100755 --- a/src/korc_collisions.f90 +++ b/src/korc_collisions.f90 @@ -2586,6 +2586,176 @@ subroutine include_CoulombCollisions_GC_p(tt,params,Y_R,Y_PHI,Y_Z, & end subroutine include_CoulombCollisions_GC_p +subroutine include_CoulombCollisions_GC_p_ACC(tt,params,Y_R,Y_PHI,Y_Z, & + Ppll,Pmu,me,flagCon,flagCol,F,P,E_PHI,ne,Te,Zeff,nimp,PSIp) + !$acc routine seq + TYPE(PROFILES), INTENT(IN) :: P + TYPE(FIELDS), INTENT(IN) :: F + TYPE(KORC_PARAMS), INTENT(INOUT) :: params + REAL(rp), INTENT(INOUT) :: Ppll + REAL(rp), INTENT(INOUT) :: Pmu + REAL(rp) :: Bmag + REAL(rp) :: B_R,B_PHI,B_Z + REAL(rp) :: curlb_R,curlb_PHI,curlb_Z + REAL(rp) :: gradB_R,gradB_PHI,gradB_Z + REAL(rp) :: E_R,E_Z + REAL(rp), INTENT(OUT) :: E_PHI,ne,PSIp,Te,Zeff + REAL(rp), INTENT(IN) :: Y_R,Y_PHI,Y_Z + INTEGER(is), INTENT(INOUT) :: flagCol + INTEGER(is), INTENT(INOUT) :: flagCon + REAL(rp),INTENT(IN) :: me + REAL(rp) :: nAr0,nAr1,nAr2,nAr3,nAr4 + REAL(rp) :: nD,nD1 + REAL(rp),DIMENSION(2) :: dW + REAL(rp),DIMENSION(2) :: rnd1 + REAL(rp) :: dt,time + REAL(rp) :: pm + REAL(rp) :: dp + REAL(rp) :: xi + REAL(rp) :: dxi + REAL(rp) :: v,gam + !! speed of particle + REAL(rp) :: CAL + REAL(rp) :: dCAL + REAL(rp) :: CFL + REAL(rp) :: CBL + REAL(rp) :: SC_p,SC_mu,BREM_p + REAL(rp) :: kappa + integer(ip),INTENT(IN) :: tt + REAL(rp), DIMENSION(params%num_impurity_species), INTENT(OUT) :: nimp + REAL(rp) :: E_PHI_tmp + + !$acc routine (calculate_GCfieldswE_p_ACC) seq + !$acc routine (interp_Hcollision_p_ACC) seq + + pchunk=params%pchunk + + if (MODULO(params%it+tt,cparams_ss%subcycling_iterations) .EQ. 0_ip) then + dt = REAL(cparams_ss%subcycling_iterations,rp)*params%dt + time=params%init_time+(params%it-1+tt)*params%dt + +#ifdef PSPLINE + + call calculate_GCfieldswE_p_ACC(F,Y_R,Y_PHI,Y_Z,B_R,B_PHI,B_Z, & + E_R,E_PHI,E_Z,curlb_R,curlb_PHI,curlb_Z, & + gradB_R,gradB_PHI,gradB_Z,flagCon,PSIp) + +#endif PSPLINE + +#ifdef PSPLINE + + call interp_Hcollision_p_ACC(params,Y_R,Y_PHI,Y_Z,ne,Te,Zeff, & + nAr0,nAr1,nAr2,nAr3,nAr4,nD,nD1,flagCon) + + nimp(1)=nAr0 + nimp(2)=nAr1 + nimp(3)=nAr2 + nimp(4)=nAr3 + nimp(5)=nAr4 + nimp(6)=nD + nimp(7)=nD1 + + + !write(6,*) 'collisions ne',ne(1)*params%cpp%density + + +#endif PSPLINE + + + E_PHI_tmp=E_PHI + if (.not.params%FokPlan) E_PHI=0._rp + + Bmag=sqrt(B_R*B_R+B_PHI*B_PHI+B_Z*B_Z) + ! Transform p_pll,mu to P,eta + pm = SQRT(Ppll*Ppll+2*me*Bmag*Pmu) + xi = Ppll/pm + + gam = sqrt(1+pm*pm) + + v = pm/gam + ! normalized speed (v_K=v_P/c) + + +#ifdef PARALLEL_RANDOM + rnd1(1) = get_random_U() + rnd1(2) = get_random_U() + ! rnd1(:,1) = get_random_mkl() + ! rnd1(:,2) = get_random_mkl() +#else + call RANDOM_NUMBER(rnd1) +#endif PARALLEL_RANDOM + + dW(1) = SQRT(3*dt)*(-1+2*rnd1(1)) + dW(2) = SQRT(3*dt)*(-1+2*rnd1(2)) + + ! write(output_unit_write,'("dW1: ",E17.10)') dW(cc,1) + ! write(output_unit_write,'("dW2: ",E17.10)') dW(cc,2) + + if (params%profile_model(10:10).eq.'H') then + CAL = CA_SD(v,ne,Te) + dCAL= dCA_SD(v,me,ne,Te) + CFL = CF_SD_FIO(params,v,ne,Te,nimp) + CBL = (CB_ee_SD(v,ne,Te,Zeff)+ & + CB_ei_SD_FIO(params,v,ne,Te,nimp,Zeff)) + else + CAL = CA_SD(v,ne,Te) + dCAL= dCA_SD(v,me,ne,Te) + CFL = CF_SD(params,v,ne,Te,P,Y_R,Y_Z) + CBL = (CB_ee_SD(v,ne,Te,Zeff)+ & + CB_ei_SD(params,v,ne,Te,Zeff,P,Y_R,Y_Z)) + endif + + if (.not.cparams_ss%slowing_down) CFL=0._rp + if (.not.cparams_ss%pitch_diffusion) CBL=0._rp + if (.not.cparams_ss%energy_diffusion) THEN + CAL=0._rp + dCAL=0._rp + ENDIF + + dp=REAL(flagCol)*REAL(flagCon)* & + ((-CFL+dCAL+E_PHI*xi)*dt+ & + sqrt(2.0_rp*CAL)*dW(1)) + + dxi=REAL(flagCol)*REAL(flagCon)* & + ((-2*xi*CBL/(pm*pm)+ & + E_PHI*(1-xi*xi)/pm)*dt- & + sqrt(2.0_rp*CBL*(1-xi*xi))/pm*dW(2)) + + + pm=pm+dp + xi=xi+dxi + + + + + if (xi>1) then + + xi=1-mod(xi,1._rp) + else if (xi<-1) then + xi=-1-mod(xi,-1._rp) + + endif + + + + ! Transform P,xi to p_pll,mu + Ppll=pm*xi + Pmu=(pm*pm-Ppll*Ppll)/(2*me*Bmag) + + + + if ((pm.lt.min(cparams_ss%p_min*cparams_ss%pmin_scale, & + p_therm)).and.flagCol.eq.1_ip) then + flagCol=0_ip + end if + + + if (.not.params%FokPlan) E_PHI=E_PHI_tmp + + end if + +end subroutine include_CoulombCollisions_GC_p_ACC + subroutine include_CoulombCollisionsLA_GC_p(spp,achunk,tt,params, & Y_R,Y_PHI,Y_Z,Ppll,Pmu,me,flagCon,flagCol,F,P,E_PHI,ne,Te,PSIp) diff --git a/src/korc_interp.f90 b/src/korc_interp.f90 index 52688dff..34173409 100755 --- a/src/korc_interp.f90 +++ b/src/korc_interp.f90 @@ -3367,6 +3367,76 @@ subroutine calculate_GCfieldswE_p(pchunk,F,Y_R,Y_PHI,Y_Z,B_R,B_PHI,B_Z,E_R,E_PHI end subroutine calculate_GCfieldswE_p +subroutine calculate_GCfieldswE_p_ACC(F,Y_R,Y_PHI,Y_Z,B_R,B_PHI,B_Z,E_R,E_PHI,E_Z, & + curlb_R,curlb_PHI,curlb_Z,gradB_R,gradB_PHI,gradB_Z,flag_cache,PSIp) + !$acc routine seq + REAL(rp), INTENT(IN) :: Y_R,Y_PHI,Y_Z + TYPE(FIELDS), INTENT(IN) :: F + REAL(rp), INTENT(OUT) :: B_R,B_PHI,B_Z + REAL(rp), INTENT(OUT) :: gradB_R,gradB_PHI,gradB_Z + REAL(rp), INTENT(OUT) :: curlb_R,curlb_PHI,curlb_Z + REAL(rp), INTENT(OUT) :: E_R,E_PHI,E_Z + REAL(rp) :: Bmag,EPHI + INTEGER :: cc + REAL(rp),INTENT(OUT) :: PSIp + REAL(rp), DIMENSION(6) :: A + INTEGER(is),INTENT(INOUT) :: flag_cache + REAL(rp) :: psip_conv + + !$acc routine (EZspline_interp2_GCvarswE) seq + !$acc routine (EZspline_error) seq + + psip_conv=F%psip_conv + + call EZspline_interp2_GCvarswE(bfield_2d%A, efield_2d%PHI, Y_R, Y_Z, A, & + EPHI, ezerr) + call EZspline_error(ezerr) + + !A(:,1) = PSIp + !A(:,2) = dPSIp/dR + !A(:,3) = dPSIp/dZ + !A(:,4) = d^2PSIp/dR^2 + !A(:,5) = d^2PSIp/dZ^2 + !A(:,6) = d^2PSIp/dRdZ + + PSIp=A(1) + + B_R = psip_conv*A(3)/Y_R + ! BR = (dA/dZ)/R + B_PHI = -F%Bo*F%Ro/Y_R + ! BPHI = Fo*Ro/R + B_Z = -psip_conv*A(2)/Y_R + ! BR = -(dA/dR)/R + + + + Bmag=sqrt(B_R*B_R+B_PHI*B_PHI+B_Z*B_Z) + + gradB_R=(B_R*psip_conv*A(6)-B_Z*psip_conv*A(4)- & + Bmag*Bmag)/(Y_R*Bmag) + gradB_PHI=0._rp + gradB_Z=(B_R*psip_conv*A(5)-B_Z*psip_conv*A(6))/ & + (Y_R*Bmag) + + curlb_R=B_PHI*gradB_Z/(Bmag*Bmag) + curlb_PHI=(Bmag/Y_R*(B_Z+psip_conv*A(4)+ & + psip_conv*A(5))-B_R*gradB_Z+B_Z*gradB_R)/ & + (Bmag*Bmag) + curlb_Z=-B_PHI*gradB_R/(Bmag*Bmag) + + if (F%E_2x1t) then + E_R = 0._rp + E_PHI = EPHI + E_Z = 0._rp + else + E_R = 0._rp + E_PHI = 0._rp + E_Z = 0._rp + end if + + +end subroutine calculate_GCfieldswE_p_ACC + subroutine calculate_GCfields_p(pchunk,F,Y_R,Y_PHI,Y_Z,B_R,B_PHI,B_Z, & E_R,E_PHI,E_Z, & curlb_R,curlb_PHI,curlb_Z,gradB_R,gradB_PHI,gradB_Z,flag_cache,PSIp) @@ -3778,36 +3848,63 @@ end subroutine interp_fields #ifdef PSPLINE subroutine interp_Hcollision_p(params,pchunk,Y_R,Y_PHI,Y_Z,ne,Te,Zeff, & + nAr0,nAr1,nAr2,nAr3,nAr4,nD,nD1,flag_cache) + TYPE(KORC_PARAMS), INTENT(IN) :: params + INTEGER, INTENT(IN) :: pchunk + REAL(rp),DIMENSION(pchunk),INTENT(IN) :: Y_R,Y_PHI,Y_Z + REAL(rp),DIMENSION(pchunk),INTENT(OUT) :: ne,Te,Zeff + REAL(rp),DIMENSION(pchunk),INTENT(OUT) :: nAr0,nAr1,nAr2,nAr3,nAr4,nD,nD1 + INTEGER(is),DIMENSION(pchunk),INTENT(INOUT) :: flag_cache + INTEGER :: cc + + call check_if_in_profiles_domain_p(pchunk,Y_R,Y_PHI,Y_Z,flag_cache) + ! write(output_unit_write,'("YR: ",E17.10)') Y_R(1) + ! write(output_unit_write,'("YPHI: ",E17.10)') Y_PHI(1) + ! write(output_unit_write,'("YZ: ",E17.10)') Y_Z(1) + + ! write(output_unit_write,'("Te_interp_R",E17.10)') profiles_2d%Te%x1 + ! write(output_unit_write,'("Te_interp_Z",E17.10)') profiles_2d%Te%x2 + + do cc=1_idef,pchunk + call EZspline_interp2_Hcollision(profiles_2d%ne,profiles_2d%Te,profiles_2d%Zeff, & + profiles_2d%nAr0,profiles_2d%nAr1,profiles_2d%nAr2,profiles_2d%nAr3,profiles_2d%nAr4, & + profiles_2d%nD,profiles_2d%nD1,Y_R(cc),Y_Z(cc),ne(cc),Te(cc),Zeff(cc), & + nAr0(cc),nAr1(cc),nAr2(cc),nAr3(cc),nAr4(cc),nD(cc),nD1(cc),ezerr) + call EZspline_error(ezerr) + end do + + !write(6,*) 'interp ne%fspl',profiles_2d%ne%fspl(1,12,15)*params%cpp%density + + !write(6,*) 'interp ne',ne(1) + + end subroutine interp_Hcollision_p + +subroutine interp_Hcollision_p_ACC(params,Y_R,Y_PHI,Y_Z,ne,Te,Zeff, & nAr0,nAr1,nAr2,nAr3,nAr4,nD,nD1,flag_cache) + !$acc routine seq TYPE(KORC_PARAMS), INTENT(IN) :: params - INTEGER, INTENT(IN) :: pchunk - REAL(rp),DIMENSION(pchunk),INTENT(IN) :: Y_R,Y_PHI,Y_Z - REAL(rp),DIMENSION(pchunk),INTENT(OUT) :: ne,Te,Zeff - REAL(rp),DIMENSION(pchunk),INTENT(OUT) :: nAr0,nAr1,nAr2,nAr3,nAr4,nD,nD1 - INTEGER(is),DIMENSION(pchunk),INTENT(INOUT) :: flag_cache - INTEGER :: cc + REAL(rp),INTENT(IN) :: Y_R,Y_PHI,Y_Z + REAL(rp),INTENT(OUT) :: ne,Te,Zeff + REAL(rp),INTENT(OUT) :: nAr0,nAr1,nAr2,nAr3,nAr4,nD,nD1 + INTEGER(is),INTENT(INOUT) :: flag_cache - call check_if_in_profiles_domain_p(pchunk,Y_R,Y_PHI,Y_Z,flag_cache) - ! write(output_unit_write,'("YR: ",E17.10)') Y_R(1) - ! write(output_unit_write,'("YPHI: ",E17.10)') Y_PHI(1) - ! write(output_unit_write,'("YZ: ",E17.10)') Y_Z(1) - ! write(output_unit_write,'("Te_interp_R",E17.10)') profiles_2d%Te%x1 - ! write(output_unit_write,'("Te_interp_Z",E17.10)') profiles_2d%Te%x2 + !$acc routine (EZspline_interp2_Hcollision) seq + !$acc routine (EZspline_error) seq + - do cc=1_idef,pchunk call EZspline_interp2_Hcollision(profiles_2d%ne,profiles_2d%Te,profiles_2d%Zeff, & profiles_2d%nAr0,profiles_2d%nAr1,profiles_2d%nAr2,profiles_2d%nAr3,profiles_2d%nAr4, & - profiles_2d%nD,profiles_2d%nD1,Y_R(cc),Y_Z(cc),ne(cc),Te(cc),Zeff(cc), & - nAr0(cc),nAr1(cc),nAr2(cc),nAr3(cc),nAr4(cc),nD(cc),nD1(cc),ezerr) + profiles_2d%nD,profiles_2d%nD1,Y_R,Y_Z,ne,Te,Zeff, & + nAr0,nAr1,nAr2,nAr3,nAr4,nD,nD1,ezerr) call EZspline_error(ezerr) - end do + !write(6,*) 'interp ne%fspl',profiles_2d%ne%fspl(1,12,15)*params%cpp%density !write(6,*) 'interp ne',ne(1) -end subroutine interp_Hcollision_p +end subroutine interp_Hcollision_p_ACC subroutine interp_nRE(params,Y_R,Y_PHI,Y_Z,PSIp,EPHI,ne,Te,nRE, & nAr0,nAr1,nAr2,nAr3,nAr4,nD,nD1,g_test,fRE_out,rho1D) diff --git a/src/korc_ppusher.f90 b/src/korc_ppusher.f90 index f2ac5667..1356b654 100755 --- a/src/korc_ppusher.f90 +++ b/src/korc_ppusher.f90 @@ -5422,6 +5422,136 @@ end subroutine adv_GCinterp_fio_top #ifdef PSPLINE +subroutine adv_GCinterp_psiwE_top_ACC(params,spp,P,F) + + IMPLICIT NONE + + TYPE(KORC_PARAMS), INTENT(INOUT) :: params + !! Core KORC simulation parameters. + TYPE(PROFILES), INTENT(IN) :: P + TYPE(FIELDS), INTENT(INOUT) :: F + TYPE(SPECIES), DIMENSION(:), ALLOCATABLE, INTENT(INOUT) :: spp + !! An instance of the derived type SPECIES containing all the parameters + !! and simulation variables of the different species in the simulation. + REAL(rp) :: Bmag + REAL(rp) :: Y_R,Y_PHI,Y_Z + REAL(rp) :: Y_R0,Y_PHI0,Y_Z0 + REAL(rp) :: Y_R1,Y_PHI1,Y_Z1 + REAL(rp) :: B_R,B_PHI,B_Z + REAL(rp) :: E_R,E_PHI,E_Z + REAL(rp) :: ne,Te,Zeff + REAL(rp) :: V_PLL,V_MU + REAL(rp) :: PSIp + REAL(rp) :: curlb_R,curlb_PHI,curlb_Z + REAL(rp) :: gradB_R,gradB_PHI,gradB_Z + INTEGER(is) :: flagCon,flagCol + REAL(rp) :: m_cache,q_cache,B0,EF0,R0,q0,lam,ar + REAL(rp), DIMENSION(params%num_impurity_species) :: nimp + INTEGER :: ii + !! Species iterator. + INTEGER :: pp + !! Particles iterator. + INTEGER(ip) :: tt,ttt + !! time iterator. + INTEGER :: thread_num + + !$acc routine (advance_GCinterp_psiwE_vars_ACC) seq + !$acc routine (include_CoulombCollisions_GC_p_ACC) seq + + do ii = 1_idef,params%num_species + + q_cache=spp(ii)%q + m_cache=spp(ii)%m + + !$acc parallel loop + do pp=1_idef,spp(ii)%ppp + + Y_R=spp(ii)%vars%Y(pp,1) + Y_PHI=spp(ii)%vars%Y(pp,2) + Y_Z=spp(ii)%vars%Y(pp,3) + + Y_R0=spp(ii)%vars%Y0(pp,1) + Y_PHI0=spp(ii)%vars%Y0(pp,2) + Y_Z0=spp(ii)%vars%Y0(pp,3) + Y_R1=spp(ii)%vars%Y1(pp,1) + Y_PHI1=spp(ii)%vars%Y1(pp,2) + Y_Z1=spp(ii)%vars%Y1(pp,3) + + V_PLL=spp(ii)%vars%V(pp,1) + V_MU=spp(ii)%vars%V(pp,2) + + PSIp=spp(ii)%vars%PSI_P(pp) + + flagCon=spp(ii)%vars%flagCon(pp) + flagCol=spp(ii)%vars%flagCol(pp) + + do tt=1_ip,params%t_skip + + + call advance_GCinterp_psiwE_vars_ACC(spp(ii),pp,tt, & + params, & + Y_R,Y_PHI,Y_Z,V_PLL,V_MU,q_cache,m_cache,flagCon,flagCol, & + F,P,B_R,B_PHI,B_Z,E_PHI,PSIp,curlb_R,curlb_PHI, & + curlb_Z,gradB_R,gradB_PHI,gradB_Z, & + Y_R0,Y_PHI0,Y_Z0,Y_R1,Y_PHI1,Y_Z1) + + if (params%collisions) then + + call include_CoulombCollisions_GC_p_ACC(tt,params, & + Y_R,Y_PHI,Y_Z, V_PLL,V_MU,m_cache, & + flagCon,flagCol,F,P,E_PHI,ne,Te,Zeff,nimp,PSIp) + + end if + + + end do !timestep iterator + + + spp(ii)%vars%Y(pp,1)=Y_R + spp(ii)%vars%Y(pp,2)=Y_PHI + spp(ii)%vars%Y(pp,3)=Y_Z + spp(ii)%vars%V(pp,1)=V_PLL + spp(ii)%vars%V(pp,2)=V_MU + + spp(ii)%vars%Y0(pp,1)=Y_R0 + spp(ii)%vars%Y0(pp,2)=Y_PHI0 + spp(ii)%vars%Y0(pp,3)=Y_Z0 + spp(ii)%vars%Y1(pp,1)=Y_R1 + spp(ii)%vars%Y1(pp,2)=Y_PHI1 + spp(ii)%vars%Y1(pp,3)=Y_Z1 + + spp(ii)%vars%flagCon(pp)=flagCon + spp(ii)%vars%flagCol(pp)=flagCol + + spp(ii)%vars%B(pp,1) = B_R + spp(ii)%vars%B(pp,2) = B_PHI + spp(ii)%vars%B(pp,3) = B_Z + + spp(ii)%vars%E(pp,2) = E_PHI + spp(ii)%vars%PSI_P(pp) = PSIp + + spp(ii)%vars%ne(pp) = ne + spp(ii)%vars%Te(pp) = Te + spp(ii)%vars%Zeff(pp) = Zeff + spp(ii)%vars%nimp(pp,:) = nimp + + Bmag=sqrt(B_R*B_R+B_PHI*B_PHI+ & + B_Z*B_Z) + + spp(ii)%vars%g(pp)=sqrt(1+V_PLL**2+ & + 2*V_MU*Bmag) + + spp(ii)%vars%eta(pp) = atan2(sqrt(2*m_cache*Bmag* & + spp(ii)%vars%V(pp,2)),spp(ii)%vars%V(pp,1))* & + 180.0_rp/C_PI + + end do + !$acc end parallel loop + + end do !species iterator + + end subroutine adv_GCinterp_psiwE_top_ACC + subroutine adv_GCinterp_psiwE_top(params,spp,P,F) IMPLICIT NONE @@ -7326,6 +7456,295 @@ subroutine advance_GCinterp_psiwE_vars(spp,pchunk,pp,tt,params,Y_R,Y_PHI,Y_Z, & #endif DBG_CHECK end subroutine advance_GCinterp_psiwE_vars +subroutine advance_GCinterp_psiwE_vars_ACC(spp,pp,tt,params,Y_R,Y_PHI,Y_Z, & + V_PLL,V_MU,q_cache,m_cache,flagCon,flagCol,F,P,B_R,B_PHI,B_Z,E_PHI,PSIp, & + curlb_R,curlb_PHI,curlb_Z,gradB_R,gradB_PHI,gradB_Z, & + Y_R0,Y_PHI0,Y_Z0,Y_R1,Y_PHI1,Y_Z1) + !$acc routine seq + !! @note Subroutine to advance GC variables \(({\bf X},p_\parallel)\) + !! @endnote + !! Comment this section further with evolution equations, numerical + !! methods, and descriptions of both. + TYPE(KORC_PARAMS), INTENT(INOUT) :: params + !! Core KORC simulation parameters. + TYPE(SPECIES), INTENT(INOUT) :: spp + TYPE(PROFILES), INTENT(IN) :: P + TYPE(FIELDS), INTENT(IN) :: F + REAL(rp) :: dt + !! Time step used in the leapfrog step (\(\Delta t\)). + + INTEGER :: cc,ii + INTEGER(ip),intent(in) :: tt + !! time iterator. + INTEGER,intent(in) :: pp + REAL(rp) :: Bmag + REAL(rp) :: a1 = 1./5._rp + REAL(rp) :: a21 = 3./40._rp,a22=9./40._rp + REAL(rp) :: a31 = 3./10._rp,a32=-9./10._rp,a33=6./5._rp + REAL(rp) :: a41 = -11./54._rp,a42=5./2._rp,a43=-70./27._rp,a44=35./27._rp + REAL(rp) :: a51 = 1631./55296._rp,a52=175./512._rp,a53=575./13824._rp,a54=44275./110592._rp,a55=253./4096._rp + REAL(rp) :: b1=37./378._rp,b2=0._rp,b3=250./621._rp,b4=125./594._rp,b5=0._rp,b6=512./1771._rp + + REAL(rp) :: k1_R,k1_PHI,k1_Z,k1_PLL,k1_MU + REAL(rp):: k2_R,k2_PHI,k2_Z,k2_PLL,k2_MU + REAL(rp) :: k3_R,k3_PHI,k3_Z,k3_PLL,k3_MU + REAL(rp) :: k4_R,k4_PHI,k4_Z,k4_PLL,k4_MU + REAL(rp) :: k5_R,k5_PHI,k5_Z,k5_PLL,k5_MU + REAL(rp) :: k6_R,k6_PHI,k6_Z,k6_PLL,k6_MU + REAL(rp) :: Y0_R,Y0_PHI,Y0_Z + REAL(rp),INTENT(INOUT) :: Y_R,Y_PHI,Y_Z + REAL(rp),INTENT(INOUT) :: Y_R0,Y_PHI0,Y_Z0 + REAL(rp),INTENT(INOUT) :: Y_R1,Y_PHI1,Y_Z1 + REAL(rp),INTENT(OUT) :: B_R,B_PHI,B_Z + REAL(rp) :: E_R,E_Z + REAL(rp),INTENT(OUT) :: E_PHI + REAL(rp),INTENT(OUT) :: PSIp + REAL(rp),INTENT(OUT) :: curlb_R,curlb_PHI,curlb_Z + REAL(rp),INTENT(OUT) :: gradB_R,gradB_PHI,gradB_Z + REAL(rp),INTENT(INOUT) :: V_PLL,V_MU + REAL(rp) :: RHS_R,RHS_PHI,RHS_Z,RHS_PLL,RHS_MU + REAL(rp) :: V0_PLL,V0_MU + REAL(rp) :: Te,Zeff + + INTEGER(is),intent(INOUT) :: flagCon,flagCol + INTEGER(is) :: flagCon0 + REAL(rp),intent(IN) :: q_cache,m_cache + LOGICAL :: accepted + REAL(rp) :: Rmin,Rmax,Zmin,Zmax,Rtrial,Ztrial,rm_trial,pmag0,Bmag0,maxRnRE + REAL(rp),dimension(spp%BMC_Nra) :: RnRE + + !$acc routine (calculate_GCfieldswE_p_ACC) seq + !$acc routine (GCEoM1_p_ACC) seq + + dt=params%dt + + + + Y0_R=Y_R + Y0_PHI=Y_PHI + Y0_Z=Y_Z + V0_PLL=V_PLL + V0_MU=V_MU + + flagCon0=flagCon + + + + ! write(output_unit_write,*) 'R0',Y_R(1) + ! write(output_unit_write,*) 'PHI0',Y_PHI(1) + ! write(output_unit_write,*) 'Z0',Y_Z(1) + ! write(output_unit_write,*) 'PPLL0',V_PLL(1) + ! write(output_unit_write,*) 'MU0',V_MU(1) + + + ! call interp_fields_p(F,Y_R,Y_PHI,Y_Z,B_R,B_PHI,B_Z,E_R,E_PHI, & + call calculate_GCfieldswE_p_ACC(F,Y_R,Y_PHI,Y_Z,B_R,B_PHI,B_Z,E_R,E_PHI, & + E_Z,curlb_R,curlb_PHI,curlb_Z,gradB_R,gradB_PHI,gradB_Z, & + flagCon,PSIp) + + + call GCEoM1_p_ACC(tt,P,F,params,RHS_R,RHS_PHI,RHS_Z,RHS_PLL,RHS_MU,B_R,B_PHI, & + B_Z,E_R,E_PHI,E_Z,curlb_R,curlb_PHI,curlb_Z,gradB_R, & + gradB_PHI,gradB_Z,V_PLL,V_MU,Y_R,Y_PHI,Y_Z,q_cache,m_cache,PSIp,flagCon) + + ! write(output_unit_write,*) 'R0',Y_R(1) + ! write(output_unit_write,*) 'PHI0',Y_PHI(1) + ! write(output_unit_write,*) 'Z0',Y_Z(1) + ! write(output_unit_write,*) 'PPLL0',V_PLL(1) + ! write(output_unit_write,*) 'MU0',V_MU(1) + + ! write(output_unit_write,*) 'BR',B_R(1) + ! write(output_unit_write,*) 'BPHI',B_PHI(1) + ! write(output_unit_write,*) 'BZ',B_Z(1) + + ! write(output_unit_write,*) 'gradBR',gradB_R(1) + ! write(output_unit_write,*) 'gradBPHI',gradB_PHI(1) + ! write(output_unit_write,*) 'gradBZ',gradB_Z(1) + + ! write(output_unit_write,*) 'curlBR',curlB_R(1) + ! write(output_unit_write,*) 'curlBPHI',curlB_PHI(1) + ! write(output_unit_write,*) 'curlBZ',curlB_Z(1) + + ! write(output_unit_write,*) 'dt',params%dt + ! write(output_unit_write,*) 'RHS_R',RHS_R(1) + ! write(output_unit_write,*) 'RHS_PHI',RHS_PHI(1) + ! write(output_unit_write,*) 'RHS_Z',RHS_Z(1) + ! write(output_unit_write,*) 'RHS_PLL',RHS_PLL(1) + ! write(output_unit_write,*) 'RHS_MU',RHS_MU(1) + + + k1_R=dt*RHS_R + k1_PHI=dt*RHS_PHI + k1_Z=dt*RHS_Z + k1_PLL=dt*RHS_PLL + k1_MU=dt*RHS_MU + + Y_R=Y0_R+a1*k1_R + Y_PHI=Y0_PHI+a1*k1_PHI + Y_Z=Y0_Z+a1*k1_Z + V_PLL=V0_PLL +a1*k1_PLL + V_MU=V0_MU +a1*k1_MU + + + ! write(output_unit_write,*) 'R1',Y_R(1) + ! write(output_unit_write,*) 'PHI1',Y_PHI(1) + !! write(output_unit_write,*) 'Z1',Y_Z(1) + ! write(output_unit_write,*) 'PPLL1',V_PLL(1) + ! write(output_unit_write,*) 'MU1',V_MU(1) + + ! call interp_fields_p(F,Y_R,Y_PHI,Y_Z,B_R,B_PHI,B_Z,E_R,E_PHI, & + call calculate_GCfieldswE_p_ACC(F,Y_R,Y_PHI,Y_Z,B_R,B_PHI,B_Z,E_R,E_PHI, & + E_Z,curlb_R,curlb_PHI,curlb_Z,gradB_R,gradB_PHI,gradB_Z, & + flagCon,PSIp) + + + call GCEoM1_p_ACC(tt,P,F,params,RHS_R,RHS_PHI,RHS_Z,RHS_PLL,RHS_MU,B_R,B_PHI, & + B_Z,E_R,E_PHI,E_Z,curlb_R,curlb_PHI,curlb_Z,gradB_R, & + gradB_PHI,gradB_Z,V_PLL,V_MU,Y_R,Y_PHI,Y_Z,q_cache,m_cache,PSIp,flagCon) + + + k2_R=dt*RHS_R + k2_PHI=dt*RHS_PHI + k2_Z=dt*RHS_Z + k2_PLL=dt*RHS_PLL + k2_MU=dt*RHS_MU + + Y_R=Y0_R+a21*k1_R+a22*k2_R + Y_PHI=Y0_PHI+a21*k1_PHI+a22*k2_PHI + Y_Z=Y0_Z+a21*k1_Z+a22*k2_Z + V_PLL=V0_PLL +a21*k1_PLL+a22*k2_PLL + V_MU=V0_MU +a21*k1_MU+a22*k2_MU + + + + + ! call interp_fields_p(F,Y_R,Y_PHI,Y_Z,B_R,B_PHI,B_Z,E_R,E_PHI, & + call calculate_GCfieldswE_p_ACC(F,Y_R,Y_PHI,Y_Z,B_R,B_PHI,B_Z,E_R,E_PHI, & + E_Z,curlb_R,curlb_PHI,curlb_Z,gradB_R,gradB_PHI,gradB_Z, & + flagCon,PSIp) + + + call GCEoM1_p_ACC(tt,P,F,params,RHS_R,RHS_PHI,RHS_Z,RHS_PLL,RHS_MU,B_R,B_PHI, & + B_Z,E_R,E_PHI,E_Z,curlb_R,curlb_PHI,curlb_Z,gradB_R, & + gradB_PHI,gradB_Z,V_PLL,V_MU,Y_R,Y_PHI,Y_Z,q_cache,m_cache,PSIp,flagCon) + + + k3_R=dt*RHS_R + k3_PHI=dt*RHS_PHI + k3_Z=dt*RHS_Z + k3_PLL=dt*RHS_PLL + k3_MU=dt*RHS_MU + + Y_R=Y0_R+a31*k1_R+a32*k2_R+a33*k3_R + Y_PHI=Y0_PHI+a31*k1_PHI+a32*k2_PHI+ & + a33*k3_PHI + Y_Z=Y0_Z+a31*k1_Z+a32*k2_Z+a33*k3_Z + + V_PLL=V0_PLL +a31*k1_PLL+a32*k2_PLL+a33*k3_PLL + V_MU=V0_MU +a31*k1_MU+a32*k2_MU+a33*k3_MU + + + ! call interp_fields_p(F,Y_R,Y_PHI,Y_Z,B_R,B_PHI,B_Z,E_R,E_PHI, & + call calculate_GCfieldswE_p_ACC(F,Y_R,Y_PHI,Y_Z,B_R,B_PHI,B_Z,E_R,E_PHI, & + E_Z,curlb_R,curlb_PHI,curlb_Z,gradB_R,gradB_PHI,gradB_Z, & + flagCon,PSIp) + + call GCEoM1_p_ACC(tt,P,F,params,RHS_R,RHS_PHI,RHS_Z,RHS_PLL,RHS_MU,B_R,B_PHI, & + B_Z,E_R,E_PHI,E_Z,curlb_R,curlb_PHI,curlb_Z,gradB_R, & + gradB_PHI,gradB_Z,V_PLL,V_MU,Y_R,Y_PHI,Y_Z,q_cache,m_cache,PSIp,flagCon) + + k4_R=dt*RHS_R + k4_PHI=dt*RHS_PHI + k4_Z=dt*RHS_Z + k4_PLL=dt*RHS_PLL + k4_MU=dt*RHS_MU + + Y_R=Y0_R+a41*k1_R+a42*k2_R+a43*k3_R+ & + a44*k4_R + Y_PHI=Y0_PHI+a41*k1_PHI+a42*k2_PHI+ & + a43*k3_PHI+a44*k4_PHI + Y_Z=Y0_Z+a41*k1_Z+a42*k2_Z+a43*k3_Z+ & + a44*k4_Z + V_PLL=V0_PLL +a41*k1_PLL+a42*k2_PLL+ & + a43*k3_PLL+a44*k4_PLL + V_MU=V0_MU +a41*k1_MU+a42*k2_MU+ & + a43*k3_MU+a44*k4_MU + + + + ! call interp_fields_p(F,Y_R,Y_PHI,Y_Z,B_R,B_PHI,B_Z,E_R,E_PHI, & + call calculate_GCfieldswE_p_ACC(F,Y_R,Y_PHI,Y_Z,B_R,B_PHI,B_Z,E_R,E_PHI, & + E_Z,curlb_R,curlb_PHI,curlb_Z,gradB_R,gradB_PHI,gradB_Z, & + flagCon,PSIp) + + call GCEoM1_p_ACC(tt,P,F,params,RHS_R,RHS_PHI,RHS_Z,RHS_PLL,RHS_MU,B_R,B_PHI, & + B_Z,E_R,E_PHI,E_Z,curlb_R,curlb_PHI,curlb_Z,gradB_R, & + gradB_PHI,gradB_Z,V_PLL,V_MU,Y_R,Y_PHI,Y_Z,q_cache,m_cache,PSIp,flagCon) + + k5_R=dt*RHS_R + k5_PHI=dt*RHS_PHI + k5_Z=dt*RHS_Z + k5_PLL=dt*RHS_PLL + k5_MU=dt*RHS_MU + + Y_R=Y0_R+a51*k1_R+a52*k2_R+a53*k3_R+ & + a54*k4_R+a55*k5_R + Y_PHI=Y0_PHI+a51*k1_PHI+a52*k2_PHI+ & + a53*k3_PHI+a54*k4_PHI+a55*k5_PHI + Y_Z=Y0_Z+a51*k1_Z+a52*k2_Z+a53*k3_Z+ & + a54*k4_Z+a55*k5_Z + V_PLL=V0_PLL +a51*k1_PLL+a52*k2_PLL+ & + a53*k3_PLL+a54*k4_PLL+a55*k5_PLL + V_MU=V0_MU +a51*k1_MU+a52*k2_MU+ & + a53*k3_MU+a54*k4_MU+a55*k5_MU + + + ! call interp_fields_p(F,Y_R,Y_PHI,Y_Z,B_R,B_PHI,B_Z,E_R,E_PHI, & + call calculate_GCfieldswE_p_ACC(F,Y_R,Y_PHI,Y_Z,B_R,B_PHI,B_Z,E_R,E_PHI, & + E_Z,curlb_R,curlb_PHI,curlb_Z,gradB_R,gradB_PHI,gradB_Z, & + flagCon,PSIp) + + call GCEoM1_p_ACC(tt,P,F,params,RHS_R,RHS_PHI,RHS_Z,RHS_PLL,RHS_MU,B_R,B_PHI, & + B_Z,E_R,E_PHI,E_Z,curlb_R,curlb_PHI,curlb_Z,gradB_R, & + gradB_PHI,gradB_Z,V_PLL,V_MU,Y_R,Y_PHI,Y_Z,q_cache,m_cache,PSIp,flagCon) + + + k6_R=dt*RHS_R + k6_PHI=dt*RHS_PHI + k6_Z=dt*RHS_Z + k6_PLL=dt*RHS_PLL + k6_MU=dt*RHS_MU + + Y_R=Y0_R+(b1*k1_R+b2*k2_R+ & + b3*k3_R+b4*k4_R+b5*k5_R+b6*k6_R)* & + REAL(flagCol)*REAL(flagCon0) + Y_PHI=Y0_PHI+(b1*k1_PHI+b2*k2_PHI+ & + b3*k3_PHI+b4*k4_PHI+b5*k5_PHI+b6*k6_PHI)* & + REAL(flagCol)*REAL(flagCon0) + Y_Z=Y0_Z+(b1*k1_Z+b2*k2_Z+ & + b3*k3_Z+b4*k4_Z+b5*k5_Z+b6*k6_Z)* & + REAL(flagCol)*REAL(flagCon0) + V_PLL=V0_PLL+(b1*k1_PLL+b2*k2_PLL+ & + b3*k3_PLL+b4*k4_PLL+b5*k5_PLL+b6*k6_PLL)* & + REAL(flagCol)*REAL(flagCon0) + V_MU=V0_MU+(b1*k1_MU+b2*k2_MU+ & + b3*k3_MU+b4*k4_MU+b5*k5_MU+b6*k6_MU)* & + REAL(flagCol)*REAL(flagCon0) + + Y_R1=Y_R1+(Y_R0-Y_R1)*REAL(flagCon0) + Y_PHI1=Y_PHI1+(Y_PHI0-Y_PHI1)*REAL(flagCon0) + Y_Z1=Y_Z1+(Y_Z0-Y_Z1)*REAL(flagCon0) + + Y_R0=Y_R0+(Y0_R-Y_R0)*REAL(flagCon0) + Y_PHI0=Y_PHI0+(Y0_PHI-Y_PHI0)*REAL(flagCon0) + Y_Z0=Y_Z0+(Y0_Z-Y_Z0)*REAL(flagCon0) + + call calculate_GCfieldswE_p_ACC(F,Y_R,Y_PHI,Y_Z,B_R,B_PHI,B_Z,E_R,E_PHI, & + E_Z,curlb_R,curlb_PHI,curlb_Z,gradB_R,gradB_PHI,gradB_Z, & + flagCon,PSIp) + +end subroutine advance_GCinterp_psiwE_vars_ACC + FUNCTION fRE_BMC(Nr_a,r_a,nRE,rm) REAL(rp), INTENT(IN) :: rm INTEGER :: Nr_a @@ -8112,6 +8531,87 @@ subroutine GCEoM1_p(pchunk,tt,P,F,params,RHS_R,RHS_PHI,RHS_Z,RHS_PLL,RHS_MU, & end subroutine GCEoM1_p +subroutine GCEoM1_p_ACC(tt,P,F,params,RHS_R,RHS_PHI,RHS_Z,RHS_PLL,RHS_MU, & + B_R,B_PHI,B_Z,E_R,E_PHI,E_Z,curlb_R,curlb_PHI,curlb_Z, & + gradB_R,gradB_PHI,gradB_Z,V_PLL,V_MU,Y_R,Y_PHI,Y_Z,q_cache,m_cache,PSIp,flag_cache) +!$acc routine seq + IMPLICIT NONE + + TYPE(KORC_PARAMS), INTENT(INOUT) :: params + !! Core KORC simulation parameters. + TYPE(FIELDS), INTENT(IN) :: F + TYPE(PROFILES), INTENT(IN) :: P + REAL(rp) :: Bmag,bhat_R,bhat_PHI,bhat_Z,Bst_R,Bst_PHI + REAL(rp) :: BstdotE,BstdotgradB,EcrossB_R,EcrossB_PHI,bdotBst + REAL(rp) :: bcrossgradB_R,bcrossgradB_PHI,bcrossgradB_Z,gamgc + REAL(rp) :: EcrossB_Z,Bst_Z + REAL(rp) :: pm,xi,tau_R + REAL(rp) :: SR_PLL,SR_MU,BREM_PLL,BREM_MU,BREM_P + REAL(rp),INTENT(in) :: gradB_R,gradB_PHI,gradB_Z,curlb_R + REAL(rp),INTENT(in) :: curlb_Z,B_R,B_PHI,B_Z,E_R,E_PHI,E_Z + REAL(rp),INTENT(OUT) :: RHS_R,RHS_PHI,RHS_Z + REAL(rp),INTENT(OUT) :: RHS_PLL,RHS_MU + REAL(rp),INTENT(IN) :: V_PLL,V_MU,Y_R,Y_PHI,Y_Z,curlb_PHI + REAL(rp),INTENT(IN) :: PSIp + REAL(rp),INTENT(in) :: q_cache,m_cache + INTEGER :: cc + INTEGER(ip),INTENT(IN) :: tt + INTEGER(is),INTENT(OUT) :: flag_cache + REAL(rp) :: time,re_cache,alpha_cache + INTEGER :: thread_num + + Bmag = SQRT(B_R*B_R+B_PHI*B_PHI+B_Z*B_Z) + + bhat_R = B_R/Bmag + bhat_PHI = B_PHI/Bmag + bhat_Z = B_Z/Bmag + + Bst_R=q_cache*B_R+V_PLL*curlb_R + Bst_PHI=q_cache*B_PHI+V_PLL*curlb_PHI + Bst_Z=q_cache*B_Z+V_PLL*curlb_Z + + ! write(output_unit_write,*) 'bmag',Bmag,'bhat',bhat_R,bhat_PHI,bhat_Z,'Bst',Bst_R,Bst_PHI,Bst_Z + + bdotBst=bhat_R*Bst_R+bhat_PHI*Bst_PHI+ & + bhat_Z*Bst_Z + BstdotE=Bst_R*E_R+Bst_PHI*E_PHI+Bst_Z*E_Z + BstdotgradB=Bst_R*gradB_R+Bst_PHI*gradB_PHI+ & + Bst_Z*gradB_Z + + !write(output_unit_write,*) 'bdotBst',bdotBst,BstdotE,BstdotgradB + + Ecrossb_R=E_PHI*bhat_Z-E_Z*bhat_PHI + Ecrossb_PHI=E_Z*bhat_R-E_R*bhat_Z + Ecrossb_Z=E_R*bhat_PHI-E_PHI*bhat_R + + !write(output_unit_write,*) 'Ecrossb',Ecrossb_R,Ecrossb_PHI,Ecrossb_Z + + bcrossgradB_R=bhat_PHI*gradB_Z-bhat_Z*gradB_PHI + bcrossgradB_PHI=bhat_Z*gradB_R-bhat_R*gradB_Z + bcrossgradB_Z=bhat_R*gradB_PHI-bhat_PHI*gradB_R + + ! write(output_unit_write,*) 'bcrossgradB',bcrossgradB_R,bcrossgradB_PHI,bcrossgradB_Z + + gamgc=sqrt(1+V_PLL*V_PLL+2*V_MU*Bmag) + + pm=sqrt(gamgc**2-1) + xi=V_PLL/pm + + RHS_R=(q_cache*Ecrossb_R+(m_cache*V_MU* & + bcrossgradB_R+V_PLL*Bst_R)/(m_cache*gamgc))/ & + bdotBst + RHS_PHI=(q_cache*Ecrossb_PHI+(m_cache*V_MU* & + bcrossgradB_PHI+V_PLL*Bst_PHI)/(m_cache*gamgc))/ & + (Y_R*bdotBst) + RHS_Z=(q_cache*Ecrossb_Z+(m_cache*V_MU* & + bcrossgradB_Z+V_PLL*Bst_Z)/(m_cache*gamgc))/ & + bdotBst + RHS_PLL=(q_cache*BstdotE-V_MU*BstdotgradB/gamgc)/ & + bdotBst + RHS_MU=0._rp + +end subroutine GCEoM1_p_ACC + #ifdef FIO subroutine GCEoM1_fio_p(tt,P,F,params,RHS_R,RHS_PHI,RHS_Z,RHS_PLL,RHS_MU, &