From d4b2bb4e12e2809349347caea2c0764fe62aea7c Mon Sep 17 00:00:00 2001 From: Antoine Hoffmann <antoine.hoffmann@epfl.ch> Date: Tue, 27 Jun 2023 08:56:03 +0200 Subject: [PATCH] tentative to implement adiabatic ion model (WIP) --- src/model_mod.F90 | 2 +- src/numerics_mod.F90 | 68 ++++++++++++++++++++++++++++++++--------- src/solve_EM_fields.F90 | 2 +- 3 files changed, 56 insertions(+), 16 deletions(-) diff --git a/src/model_mod.F90 b/src/model_mod.F90 index 4364d580..b6502694 100644 --- a/src/model_mod.F90 +++ b/src/model_mod.F90 @@ -60,7 +60,7 @@ CONTAINS CALL speak('Adiabatic electron model -> beta = 0') beta = 0._xp ENDIF - IF(ADIAB_I) CALL speak('Adiabatic ion model -> beta = 0') + IF(ADIAB_I) CALL speak('Adiabatic ion model') ENDIF IF(beta .GT. 0) THEN diff --git a/src/numerics_mod.F90 b/src/numerics_mod.F90 index e6d4ac94..0224a515 100644 --- a/src/numerics_mod.F90 +++ b/src/numerics_mod.F90 @@ -2,8 +2,9 @@ ! The module numerics contains a set of routines that are called only once at ! the beginng of a run. These routines do not need to be optimzed MODULE numerics + USE prec_const, ONLY: xp implicit none - + REAL(xp), PUBLIC, PROTECTED, ALLOCATABLE, DIMENSION(:,:,:,:,:) :: kernel_i PUBLIC :: build_dnjs_table, evaluate_kernels, evaluate_EM_op PUBLIC :: compute_lin_coeff, build_dv4Hp_table @@ -71,14 +72,16 @@ END SUBROUTINE build_dv4Hp_table !******************************************************************************! SUBROUTINE evaluate_kernels USE basic + USE prec_const, ONLY: xp USE array, ONLY : kernel!, HF_phi_correction_operator USE grid, ONLY : local_na, local_nj,ngj, local_nkx, local_nky, local_nz, ngz, jarray, kparray,& nzgrid USE species, ONLY : sigma2_tau_o2 - USE prec_const, ONLY: xp + USE model, ONLY : ADIAB_I, tau_i IMPLICIT NONE INTEGER :: j_int, ia, eo, ikx, iky, iz, ij - REAL(xp) :: j_xp, y_, factj + REAL(xp) :: j_xp, y_, factj, sigma_i + sigma_i = 1._xp ! trivial singe sigma_a = sqrt(m_a/m_i) DO ia = 1,local_na DO eo = 1,nzgrid @@ -100,6 +103,30 @@ DO ia = 1,local_na ENDDO ENDDO ENDDO + + !! ion kernels if we use adiabatic ions + IF(ADIAB_I) THEN + ALLOCATE(kernel_i(local_nj + ngj,local_nky,local_nkx,local_nz + ngz,nzgrid)) + DO eo = 1,nzgrid + DO ikx = 1,local_nkx + DO iky = 1,local_nky + DO iz = 1,local_nz + ngz + DO ij = 1,local_nj + ngj + j_int = jarray(ij) + j_xp = REAL(j_int,xp) + y_ = sigma_i**2*tau_i/2._xp * kparray(iky,ikx,iz,eo)**2 + IF(j_int .LT. 0) THEN !ghosts values + kernel_i(ij,iky,ikx,iz,eo) = 0._xp + ELSE + factj = REAL(GAMMA(j_xp+1._xp),xp) + kernel_i(ij,iky,ikx,iz,eo) = y_**j_int*EXP(-y_)/factj + ENDIF + ENDDO + ENDDO + ENDDO + ENDDO + ENDDO + ENDIF ! !! Correction term for the evaluation of the heat flux ! HF_phi_correction_operator(:,:,:) = & ! 2._xp * Kernel(ia,1,:,:,:,1) & @@ -137,10 +164,11 @@ SUBROUTINE evaluate_poisson_op USE model, ONLY : ADIAB_E, ADIAB_I, tau_i USE prec_const, ONLY: xp IMPLICIT NONE - REAL(xp) :: pol_tot, operator_ion ! (Z^2/tau (1-sum_n kernel_na^2)) + REAL(xp) :: pol_tot, operator_ion INTEGER :: in,ikx,iky,iz,ia - REAL(xp) :: sumker ! (Z_a^2/tau_a (1-sum_n kernel_na^2)) - + REAL(xp) :: sumker, q_i, sigma_i + q_i = 1._xp ! we assume single charge ions for adiab. ion model + sigma_i = 1._xp ! trivial singe sigma_a = sqrt(m_a/m_i) ! This term has no staggered grid dependence. It is evalued for the ! even z grid since poisson uses p=0 moments and phi only. kxloop: DO ikx = 1,local_nkx @@ -154,7 +182,7 @@ SUBROUTINE evaluate_poisson_op pol_tot = 0._xp ! total polarisation term a:DO ia = 1,local_na ! sum over species ! ia = 1 - sumker = 0._xp ! sum of ion polarisation term + sumker = 0._xp ! sum of ion polarisation term (Z_a^2/tau_a (1-sum_n kernel_na^2)) DO in=1,local_nj sumker = sumker + q2_tau(ia)*kernel(ia,in+ngj/2,iky,ikx,iz+ngz/2,ieven)**2 ! ... sum recursively ... END DO @@ -164,12 +192,17 @@ SUBROUTINE evaluate_poisson_op IF(ADIAB_E) & ! Adiabatic electron model pol_tot = pol_tot + 1._xp + + IF(ADIAB_I) THEN ! adiabatic ions model (add ions polarisation) + sumker = 0._xp ! sum of ion polarisation term + DO in=1,local_nj + sumker = sumker + q_i**2/tau_i * kernel_i(in+ngj/2,iky,ikx,iz+ngz/2,ieven)**2 ! ... sum recursively ... + END DO + pol_tot = pol_tot + q_i**2/tau_i - sumker + ENDIF inv_poisson_op(iky, ikx, iz) = 1._xp/pol_tot inv_pol_ion (iky, ikx, iz) = 1._xp/operator_ion - - IF(ADIAB_I) & ! adiabatic ions - inv_poisson_op(iky, ikx, iz) = tau_i ENDIF END DO zloop END DO kyloop @@ -185,13 +218,15 @@ SUBROUTINE evaluate_ampere_op USE array, ONLY : kernel, inv_ampere_op USE grid, ONLY : local_na, local_nkx, local_nky, local_nz, ngz, total_nj, ngj,& kparray, kxarray, kyarray, SOLVE_AMPERE, iodd - USE model, ONLY : beta + USE model, ONLY : beta, ADIAB_I USE species, ONLY : q, sigma USE geometry, ONLY : hatB USE prec_const, ONLY: xp IMPLICIT NONE - REAL(xp) :: sum_jpol, kperp2, operator ! (Z^2/tau (1-sum_n kernel_na^2)) + REAL(xp) :: sum_jpol, kperp2, operator, q_i, sigma_i INTEGER :: in,ikx,iky,iz,ia + q_i = 1._xp ! single charge ion + sigma_i = 1._xp ! trivial singe sigma_a = sqrt(m_a/m_i) ! We do not solve Ampere if beta = 0 to spare waste of ressources IF(SOLVE_AMPERE) THEN x:DO ikx = 1,local_nkx @@ -204,10 +239,15 @@ SUBROUTINE evaluate_ampere_op sum_jpol = 0._xp a:DO ia = 1,local_na ! loop over n only up to the max polynomial degree - j:DO in=1,total_nj + DO in=1,total_nj sum_jpol = sum_jpol + q(ia)**2/(sigma(ia)**2)*kernel(ia,in+ngj/2,iky,ikx,iz+ngz/2,iodd)**2 ! ... sum recursively ... - END DO j + END DO END DO a + IF(ADIAB_I) THEN ! Add ion contribution on the polarisation + DO in=1,total_nj + sum_jpol = sum_jpol + q_i**2/(sigma_i**2)*kernel_i(in+ngj/2,iky,ikx,iz+ngz/2,iodd)**2 ! ... sum recursively ... + END DO + ENDIF operator = 2._xp*kperp2*hatB(iz+ngz/2,iodd)**2 + beta*sum_jpol inv_ampere_op(iky, ikx, iz) = 1._xp/operator ENDIF diff --git a/src/solve_EM_fields.F90 b/src/solve_EM_fields.F90 index 099bfad6..34a4410f 100644 --- a/src/solve_EM_fields.F90 +++ b/src/solve_EM_fields.F90 @@ -22,7 +22,7 @@ CONTAINS ip0, total_nj, ngj USE calculus, ONLY: simpson_rule_z USE parallel, ONLY: manual_3D_bcast - USE model, ONLY: lambdaD, ADIAB_E, ADIAB_I, tau_i + USE model, ONLY: lambdaD, ADIAB_E, tau_i use species, ONLY: q USE processing, ONLY: compute_density USE geometry, ONLY: iInt_Jacobian, Jacobian -- GitLab