From ef95ecad13aeb8dec2db889bfe17c400acd4f220 Mon Sep 17 00:00:00 2001 From: lazersos Date: Wed, 23 Oct 2024 14:21:44 +0200 Subject: [PATCH 01/16] LIBSTELL: Added QI target variables to STELLOPT --- .../Sources/STELLOPT/stellopt_input_mod.f90 | 18 ++++++++++++++++++ LIBSTELL/Sources/STELLOPT/stellopt_targets.f90 | 4 ++++ 2 files changed, 22 insertions(+) diff --git a/LIBSTELL/Sources/STELLOPT/stellopt_input_mod.f90 b/LIBSTELL/Sources/STELLOPT/stellopt_input_mod.f90 index 0f1ce4dce..d8a5e95ae 100644 --- a/LIBSTELL/Sources/STELLOPT/stellopt_input_mod.f90 +++ b/LIBSTELL/Sources/STELLOPT/stellopt_input_mod.f90 @@ -355,6 +355,7 @@ MODULE stellopt_input_mod target_Jstar, sigma_Jstar, NumJstar,& target_helicity, sigma_helicity, helicity,& target_helicity_old, sigma_helicity_old, & + target_quasiiso, sigma_quasiiso, & target_resjac, sigma_resjac, xm_resjac, xn_resjac,& target_separatrix, sigma_separatrix, & r_separatrix, z_separatrix, phi_separatrix, & @@ -917,6 +918,8 @@ SUBROUTINE init_stellopt_input helicity = CMPLX(0.0,0.0) target_helicity_old(:) = 0.0 sigma_helicity_old(:) = bigno + target_quasiiso(:) = 0.0 + sigma_quasiiso(:) = bigno target_resjac(:) = 0.0 sigma_resjac(:) = bigno xn_resjac(:) = 0 @@ -1095,6 +1098,7 @@ SUBROUTINE read_stellopt_input(filename, istat) target_dkes(1) = 0.0; sigma_dkes(1) = bigno target_dkes(2) = 0.0; sigma_dkes(2) = bigno target_helicity(1) = 0.0; sigma_helicity(1) = bigno + target_quasiiso(1) = 0.0; sigma_quasiiso(1) = bigno target_Jstar(1) = 0.0; sigma_Jstar(1) = bigno target_dkes_Erdiff(1) = 0.0; sigma_dkes_Erdiff(1) = bigno target_dkes_alpha(1) = 0.0; sigma_dkes_alpha(1) = bigno @@ -1689,6 +1693,20 @@ SUBROUTINE write_optimum_namelist(iunit,istat) 'SIGMA_HELICITY_OLD(',ik,') = ',sigma_helicity_old(ik) END DO END IF + IF (ANY(sigma_quasiiso < bigno)) THEN + WRITE(iunit,'(A)') '!----------------------------------------------------------------------' + WRITE(iunit,'(A)') '! BOOZER QUASI-ISODYNAMIC METRIC' + WRITE(iunit,'(A)') '!----------------------------------------------------------------------' + n=0 + DO ik = 1,UBOUND(sigma_quasiiso,DIM=1) + IF(sigma_quasiiso(ik) < bigno) n=ik + END DO + DO ik = 1, n + IF (sigma_quasiiso(ik) < bigno) WRITE(iunit,"(2(2X,A,I3.3,A,ES22.12E3))") & + 'TARGET_QUASIISO(',ik,') = ',target_quasiiso(ik), & + 'SIGMA_QUASIISO(',ik,') = ',sigma_quasiiso(ik) + END DO + END IF IF (ANY(sigma_resjac < bigno)) THEN WRITE(iunit,'(A)') '!----------------------------------------------------------------------' WRITE(iunit,'(A)') '! BOOZER Resonant Modes' diff --git a/LIBSTELL/Sources/STELLOPT/stellopt_targets.f90 b/LIBSTELL/Sources/STELLOPT/stellopt_targets.f90 index 547883c0e..2f894ce04 100644 --- a/LIBSTELL/Sources/STELLOPT/stellopt_targets.f90 +++ b/LIBSTELL/Sources/STELLOPT/stellopt_targets.f90 @@ -157,6 +157,7 @@ MODULE stellopt_targets REAL(rprec), DIMENSION(nsd) :: target_magwell, sigma_magwell REAL(rprec), DIMENSION(nsd) :: target_helicity, sigma_helicity REAL(rprec), DIMENSION(nsd) :: target_helicity_old, sigma_helicity_old + REAL(rprec), DIMENSION(nsd) :: target_quasiiso, sigma_quasiiso COMPLEX :: helicity REAL(rprec), DIMENSION(nsd) :: target_resjac, sigma_resjac, & xm_resjac, xn_resjac @@ -273,6 +274,7 @@ MODULE stellopt_targets INTEGER, PARAMETER :: jtarget_neo = 603 INTEGER, PARAMETER :: jtarget_Jstar = 604 INTEGER, PARAMETER :: jtarget_helicity = 605 + INTEGER, PARAMETER :: jtarget_quasiiso = 6051 INTEGER, PARAMETER :: jtarget_resjac = 606 INTEGER, PARAMETER :: jtarget_txport = 607 INTEGER, PARAMETER :: jtarget_dkes = 608 @@ -417,6 +419,8 @@ SUBROUTINE write_targets(iunit,var_num) WRITE(iunit, out_format) 'Trapped Particle J*' CASE(jtarget_helicity) WRITE(iunit, out_format) 'Boozer Spectrum Helicity' + CASE(jtarget_quasiiso) + WRITE(iunit, out_format) 'Boozer Quasi-isodynamic metric' CASE(jtarget_txport) WRITE(iunit, out_format) 'Turbulent Transport' CASE(jtarget_orbit) From 51df9535d6e81b1f5a86f24cbe050ef1c27098b6 Mon Sep 17 00:00:00 2001 From: lazersos Date: Thu, 24 Oct 2024 06:46:08 +0200 Subject: [PATCH 02/16] STELLOPT: Initial commit of QI metric (not yet working) --- STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 | 118 ++++++++++++++++++ .../Sources/General/stellopt_load_targets.f90 | 3 + .../Sources/General/stellopt_renorm.f90 | 2 + 3 files changed, 123 insertions(+) create mode 100644 STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 diff --git a/STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 b/STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 new file mode 100644 index 000000000..55f5d5cbd --- /dev/null +++ b/STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 @@ -0,0 +1,118 @@ +!----------------------------------------------------------------------- +! Subroutine: chisq_quasiiso +! Authors: S. Lazerson (samuel.lazerson@gauss-fusion.com) +! Date: 10/08/2024 +! Description: This chisquared functional replicates the QI +! functional described in: +! https://doi.org/10.1017/S002237782300065X +! and +! https://doi.org/10.1103/PRXEnergy.3.023010 +!----------------------------------------------------------------------- + SUBROUTINE chisq_quasiiso(target,sigma,niter,iflag) +!----------------------------------------------------------------------- +! Libraries +!----------------------------------------------------------------------- + USE stellopt_runtime + USE stellopt_targets + +!----------------------------------------------------------------------- +! Input/Output Variables +! +!----------------------------------------------------------------------- + IMPLICIT NONE + REAL(rprec), INTENT(in) :: target(nsd) + REAL(rprec), INTENT(in) :: sigma(nsd) + INTEGER, INTENT(in) :: niter + INTEGER, INTENT(inout) :: iflag + +!----------------------------------------------------------------------- +! Local Variables +! +!----------------------------------------------------------------------- + INTEGER :: ik, mn, ier, l, lmin + INTEGER, PARAMETER :: nalpha = 65 ! must be odd + INTEGER, PARAMETER :: ntheta0 = 5 + INTEGER, PARAMETER :: nlambda = 4 + REAL(rprec) :: s_temp, iota0, phi, theta, deltaphi + REAL(rprec), DIMENSION(:), ALLOCATABLE :: modb, modbs + + +!----------------------------------------------------------------------- +! BEGIN SUBROUTINE +!----------------------------------------------------------------------- + IF (iflag < 0) RETURN + IF (iflag == 1) WRITE(iunit_out,'(A,2(2X,I3.3))') 'QUASIISO ',1,4 + IF (iflag == 1) WRITE(iunit_out,'(A)') 'TARGET SIGMA VAL' + IF (niter >= 0) THEN + ! Loop over surfaces + DO ik = 1, nsd + IF (ABS(sigma(ik)) >= bigno) CYCLE + ! Get iota for the surface + s_temp = DBLE(ik)/DBLE(ns_b) + ier = 0 + CALL get_equil_iota(s_temp,iota0,ier) + ! Calculate the distance to follow a field line + deltaphi = pi2/iota0 + ALLOCATE(modb(nalpha),modbs(nalpha)) + ! Loop over inital values of theta0 + DO i = 1, ntheta0 + DO l = 1, nalpha + phi = deltaphi*(l-1)/(nalpha-1) + theta = theta0 + iota0*phi + DO mn = 1, mnmax_b + modb(l) = bmnc_(mn,ik)*COS(ixm_b(mn)*theta+ixn_b(mn)*phi/nfp_b) + END DO + END DO + ! Find min/max values + lmin = MINLOC(modb) + ! Sort the arrays + lh = FLOOR(nalpha/2)+1 + modb = CSHIFT(modb,lmin-lh) !BOOSH + ! Squash the array + modbs = modb + DO l = lh,nalpha + IF (modbs(l) Date: Sun, 27 Oct 2024 14:46:30 +0100 Subject: [PATCH 03/16] STELLOPT: Quasiiso now runs. --- STELLOPTV2/ObjectList | 1 + STELLOPTV2/STELLOPTV2.dep | 7 ++ STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 | 111 ++++++++++++++++---- 3 files changed, 99 insertions(+), 20 deletions(-) diff --git a/STELLOPTV2/ObjectList b/STELLOPTV2/ObjectList index b2b460980..2f027307f 100644 --- a/STELLOPTV2/ObjectList +++ b/STELLOPTV2/ObjectList @@ -1,4 +1,5 @@ ObjectFiles = \ +chisq_quasiiso.o \ stellopt_read_cws.o \ stellopt_write_header.o \ chisq_dkes_alpha.o \ diff --git a/STELLOPTV2/STELLOPTV2.dep b/STELLOPTV2/STELLOPTV2.dep index 0cf028067..5b31d8d36 100644 --- a/STELLOPTV2/STELLOPTV2.dep +++ b/STELLOPTV2/STELLOPTV2.dep @@ -279,6 +279,13 @@ chisq_helicity_ornl.o : \ equil_vals.o \ $(LIB_DIR)/$(LOCTYPE)/read_boozer_mod.o + +chisq_quasiiso.o : \ + stellopt_runtime.o \ + $(LIB_DIR)/$(LOCTYPE)/stellopt_targets.o \ + equil_vals.o \ + $(LIB_DIR)/$(LOCTYPE)/read_boozer_mod.o + chisq_resjac.o : \ stellopt_runtime.o \ $(LIB_DIR)/$(LOCTYPE)/stellopt_targets.o \ diff --git a/STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 b/STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 index 55f5d5cbd..9e5d6b9d9 100644 --- a/STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 +++ b/STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 @@ -14,6 +14,9 @@ SUBROUTINE chisq_quasiiso(target,sigma,niter,iflag) !----------------------------------------------------------------------- USE stellopt_runtime USE stellopt_targets + USE equil_utils, ONLY: get_equil_iota + USE read_boozer_mod + USE vmec_input, ONLY: mpol, ntor !----------------------------------------------------------------------- ! Input/Output Variables @@ -29,12 +32,15 @@ SUBROUTINE chisq_quasiiso(target,sigma,niter,iflag) ! Local Variables ! !----------------------------------------------------------------------- - INTEGER :: ik, mn, ier, l, lmin + INTEGER :: ik, mn, ier, i, l, m, lmin, lmax, i1, i2, lh, lr INTEGER, PARAMETER :: nalpha = 65 ! must be odd INTEGER, PARAMETER :: ntheta0 = 5 INTEGER, PARAMETER :: nlambda = 4 - REAL(rprec) :: s_temp, iota0, phi, theta, deltaphi - REAL(rprec), DIMENSION(:), ALLOCATABLE :: modb, modbs + REAL(rprec) :: s_temp, iota0, phi, theta, deltaphi, ftemp, norm, & + Bmax, Bmin, Bmir, lambda, theta0, phimin,phimax + REAL(rprec), DIMENSION(:), ALLOCATABLE :: modb, modbs, dl, & + integral_A, integral_B + REAL(rprec), DIMENSION(:,:), ALLOCATABLE :: J_I, J_C !----------------------------------------------------------------------- @@ -42,8 +48,13 @@ SUBROUTINE chisq_quasiiso(target,sigma,niter,iflag) !----------------------------------------------------------------------- IF (iflag < 0) RETURN IF (iflag == 1) WRITE(iunit_out,'(A,2(2X,I3.3))') 'QUASIISO ',1,4 - IF (iflag == 1) WRITE(iunit_out,'(A)') 'TARGET SIGMA VAL' + IF (iflag == 1) WRITE(iunit_out,'(A)') 'TARGET SIGMA VAL K' IF (niter >= 0) THEN + ! Allocate helpers along field line + ALLOCATE(modb(nalpha),modbs(nalpha),dl(nalpha),integral_A(nalpha),& + integral_B(nalpha)) + ! Allocate J arrays + ALLOCATE(J_C(nlambda,ntheta0),J_I(nlambda,ntheta0)) ! Loop over surfaces DO ik = 1, nsd IF (ABS(sigma(ik)) >= bigno) CYCLE @@ -51,23 +62,46 @@ SUBROUTINE chisq_quasiiso(target,sigma,niter,iflag) s_temp = DBLE(ik)/DBLE(ns_b) ier = 0 CALL get_equil_iota(s_temp,iota0,ier) - ! Calculate the distance to follow a field line - deltaphi = pi2/iota0 - ALLOCATE(modb(nalpha),modbs(nalpha)) ! Loop over inital values of theta0 + J_C = 0.0; J_I = 0.0 DO i = 1, ntheta0 + ! Calculate the distance to follow a field line + deltaphi = pi2/iota0 + modb = 0.0 + modbs = 0.0 + !theta0 = pi2*i/(ntheta0-1) + theta0 = 0.0 DO l = 1, nalpha phi = deltaphi*(l-1)/(nalpha-1) theta = theta0 + iota0*phi - DO mn = 1, mnmax_b - modb(l) = bmnc_(mn,ik)*COS(ixm_b(mn)*theta+ixn_b(mn)*phi/nfp_b) + DO mn = 1, mnboz_b + !PRINT *,ik,mn,bmnc_b(mn,ik),ixm_b(mn),theta,ixn_b(mn),phi,nfp_b + modb(l) = modb(l)+bmnc_b(mn,ik)*COS(DBLE(ixm_b(mn))*theta+DBLE(ixn_b(mn))*phi/nfp_b) END DO END DO + !WRITE(290+i,*) modb; CALL FLUSH(290+i) ! Find min/max values - lmin = MINLOC(modb) + lmin = MINLOC(modb,DIM=1) + lmax = MAXLOC(modb,DIM=1) + phimin = deltaphi*(lmin-1)/(nalpha-1) + phimax = deltaphi*(lmax-1)/(nalpha-1) + deltaphi = ABS(phimax-phimin)*2.0 + ! Now recalculate modb centered around lmin + modb = 0 + DO l = 1, nalpha + phi = deltaphi*(l-lmin-1)/(nalpha-1) - deltaphi/2 + theta = theta0 + iota0*phi + DO mn = 1, mnboz_b + !PRINT *,ik,mn,bmnc_b(mn,ik),ixm_b(mn),theta,ixn_b(mn),phi,nfp_b + modb(l) = modb(l)+bmnc_b(mn,ik)*COS(DBLE(ixm_b(mn))*theta+DBLE(ixn_b(mn))*phi/nfp_b) + END DO + END DO ! Sort the arrays - lh = FLOOR(nalpha/2)+1 + lh = FLOOR(nalpha*0.5)+1 + PRINT *,lh,lmin + !WRITE(300+i,*) modb; CALL FLUSH(300+i) modb = CSHIFT(modb,lmin-lh) !BOOSH + !WRITE(310+i,*) modb; CALL FLUSH(310+i) ! Squash the array modbs = modb DO l = lh,nalpha @@ -76,25 +110,62 @@ SUBROUTINE chisq_quasiiso(target,sigma,niter,iflag) DO l = 1, lh IF (modbs(l)Bmir) + 1 + i2 = COUNT(modbs(lh:nalpha) Date: Mon, 28 Oct 2024 09:54:29 +0100 Subject: [PATCH 04/16] STELLOPT: QI metric now runs for multiple fieldlines. --- STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 b/STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 index 9e5d6b9d9..88c6c9152 100644 --- a/STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 +++ b/STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 @@ -69,8 +69,8 @@ SUBROUTINE chisq_quasiiso(target,sigma,niter,iflag) deltaphi = pi2/iota0 modb = 0.0 modbs = 0.0 - !theta0 = pi2*i/(ntheta0-1) - theta0 = 0.0 + theta0 = pi2*(i-1)/ntheta0 + !theta0 = 0.0 DO l = 1, nalpha phi = deltaphi*(l-1)/(nalpha-1) theta = theta0 + iota0*phi From 5a2dbea06099d3ab4e19660cd5912dcdee6c40af Mon Sep 17 00:00:00 2001 From: lazersos Date: Mon, 28 Oct 2024 14:36:09 +0100 Subject: [PATCH 05/16] STELLOPT: Fixed missing build dependencies --- STELLOPTV2/STELLOPTV2.dep | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/STELLOPTV2/STELLOPTV2.dep b/STELLOPTV2/STELLOPTV2.dep index 5b31d8d36..a51389ca0 100644 --- a/STELLOPTV2/STELLOPTV2.dep +++ b/STELLOPTV2/STELLOPTV2.dep @@ -283,8 +283,9 @@ chisq_helicity_ornl.o : \ chisq_quasiiso.o : \ stellopt_runtime.o \ $(LIB_DIR)/$(LOCTYPE)/stellopt_targets.o \ - equil_vals.o \ - $(LIB_DIR)/$(LOCTYPE)/read_boozer_mod.o + equil_utils.o \ + $(LIB_DIR)/$(LOCTYPE)/read_boozer_mod.o \ + $(LIB_DIR)/$(LOCTYPE)/vmec_input.o chisq_resjac.o : \ stellopt_runtime.o \ From 63f6599dd908945bd7c049a94ecf602567e96765 Mon Sep 17 00:00:00 2001 From: lazersos Date: Mon, 28 Oct 2024 16:37:29 +0100 Subject: [PATCH 06/16] STELLOPT: Quasi-isodynamic target now mostly working. --- STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 | 53 ++++++++++----------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 b/STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 index 88c6c9152..67b21b0c6 100644 --- a/STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 +++ b/STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 @@ -42,6 +42,8 @@ SUBROUTINE chisq_quasiiso(target,sigma,niter,iflag) integral_A, integral_B REAL(rprec), DIMENSION(:,:), ALLOCATABLE :: J_I, J_C + LOGICAL, PARAMETER :: lwrite_out = .False. + !----------------------------------------------------------------------- ! BEGIN SUBROUTINE @@ -65,62 +67,60 @@ SUBROUTINE chisq_quasiiso(target,sigma,niter,iflag) ! Loop over inital values of theta0 J_C = 0.0; J_I = 0.0 DO i = 1, ntheta0 - ! Calculate the distance to follow a field line + ! Calculate the initial distance to follow a field line deltaphi = pi2/iota0 modb = 0.0 modbs = 0.0 theta0 = pi2*(i-1)/ntheta0 - !theta0 = 0.0 DO l = 1, nalpha phi = deltaphi*(l-1)/(nalpha-1) theta = theta0 + iota0*phi DO mn = 1, mnboz_b - !PRINT *,ik,mn,bmnc_b(mn,ik),ixm_b(mn),theta,ixn_b(mn),phi,nfp_b modb(l) = modb(l)+bmnc_b(mn,ik)*COS(DBLE(ixm_b(mn))*theta+DBLE(ixn_b(mn))*phi/nfp_b) END DO END DO - !WRITE(290+i,*) modb; CALL FLUSH(290+i) - ! Find min/max values + IF (lwrite_out) WRITE(320,*) modb + ! Find min/max modB values lmin = MINLOC(modb,DIM=1) lmax = MAXLOC(modb,DIM=1) + ! Recalculate length of fieldline phimin = deltaphi*(lmin-1)/(nalpha-1) phimax = deltaphi*(lmax-1)/(nalpha-1) - deltaphi = ABS(phimax-phimin)*2.0 + deltaphi = ABS(phimax-phimin) ! Now recalculate modb centered around lmin modb = 0 DO l = 1, nalpha - phi = deltaphi*(l-lmin-1)/(nalpha-1) - deltaphi/2 + phi = phimin-deltaphi + 2*deltaphi*(l-1)/(nalpha-1) + !phi = deltaphi*(l-lmin-1)/(nalpha-1) - deltaphi/2 theta = theta0 + iota0*phi DO mn = 1, mnboz_b - !PRINT *,ik,mn,bmnc_b(mn,ik),ixm_b(mn),theta,ixn_b(mn),phi,nfp_b modb(l) = modb(l)+bmnc_b(mn,ik)*COS(DBLE(ixm_b(mn))*theta+DBLE(ixn_b(mn))*phi/nfp_b) END DO END DO + IF (lwrite_out) WRITE(321,*) modb ! Sort the arrays - lh = FLOOR(nalpha*0.5)+1 - PRINT *,lh,lmin - !WRITE(300+i,*) modb; CALL FLUSH(300+i) - modb = CSHIFT(modb,lmin-lh) !BOOSH - !WRITE(310+i,*) modb; CALL FLUSH(310+i) + !lh = FLOOR(nalpha*0.5)+1 + !modb = CSHIFT(modb,lmin-lh) !BOOSH + lh = MINLOC(modb,DIM=1) ! Squash the array modbs = modb + DO l = lh, 1, -1 + IF (modbs(l)Bmir) + 1 i2 = COUNT(modbs(lh:nalpha) Date: Mon, 28 Oct 2024 16:56:58 +0100 Subject: [PATCH 07/16] VMEC2STEL: Added QUASIISO target to utility. --- VMEC2STEL/Sources/vmec2stel_main.f90 | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/VMEC2STEL/Sources/vmec2stel_main.f90 b/VMEC2STEL/Sources/vmec2stel_main.f90 index b19aaf179..a4451ef48 100644 --- a/VMEC2STEL/Sources/vmec2stel_main.f90 +++ b/VMEC2STEL/Sources/vmec2stel_main.f90 @@ -36,7 +36,8 @@ PROGRAM VMEC2STEL lkink, lvaciota, ljcurv, loutput_harm, lmode, lorbit, & lac, lam, lai, lphiedge, lpscale, lcurtor, lkappa, & lwell, lcurvature, lfieldlines, & - ltxport, ltxport_tem, ltxport_ae, ldkes_erdiff + ltxport, ltxport_tem, ltxport_ae, ldkes_erdiff, & + lquasiiso INTEGER :: m,n,ns,j REAL(rprec) :: bound_min, bound_max, var, var_min, var_max, & temp, rho_exp,r1t,r2t,z1t, delta, filter_harm, pi2 @@ -107,6 +108,7 @@ PROGRAM VMEC2STEL lwell = .FALSE. lcurvature = .FALSE. loutput_harm = .FALSE. + lquasiiso = .FALSE. bound_min = -1.0 bound_max = 2.0 filter_harm = 0 @@ -260,6 +262,9 @@ PROGRAM VMEC2STEL lwell= .TRUE. CASE ("-curvature") lcurvature= .TRUE. + CASE ("-qi") + lquasiiso= .TRUE. + lneed_booz = .TRUE. CASE ("-help","-h") WRITE(6,'(a,f5.2)') 'VMEC2STEL Version ',VMEC2STEL_VERSION WRITE(6,*) ' STELLOPTV2 Input Generation Utility' @@ -290,6 +295,7 @@ PROGRAM VMEC2STEL WRITE(6,*) ' -qas QAS Target' WRITE(6,*) ' -qps QPS Target' WRITE(6,*) ' -helical Helical Target' + WRITE(6,*) ' -qi Quasi-Isodynamic Target' WRITE(6,*) ' -balloon Ballooning Target' WRITE(6,*) ' -neo Neoclassical (NEO) Target' WRITE(6,*) ' -dkes Neoclassical (DKES) Target' @@ -957,6 +963,12 @@ PROGRAM VMEC2STEL IF (lhelical) WRITE(6,'(2X,A)') 'HELICITY = (2,1)' WRITE(6,'(2X,A,I3.3,A,I3.3,A,I3.3,A,I3.3,A)') 'TARGET_HELICITY(1:',ns,') = ',ns,'*0.0 SIGMA_HELICITY(1:',ns,') = ',ns,'*-1.0' END IF + IF (lquasiiso) THEN + WRITE(6,'(A)')'!------------------------------------------------------------------------' + WRITE(6,'(A)')'! Quasi-Isodnamic Target (10.1103/PRXEnergy.3.023010)' + WRITE(6,'(A)')'!------------------------------------------------------------------------' + WRITE(6,'(2X,A,I3.3,A,I3.3,A,I3.3,A,I3.3,A)') 'TARGET_QUASIISO(1:',ns,') = ',ns,'*0.0 SIGMA_QUASIISO(1:',ns,') = ',ns,'*1.0' + END IF IF (lballoon) THEN WRITE(6,'(A)')'!------------------------------------------------------------------------' WRITE(6,'(A)')'! Ballooning Stability (as calculated by COBRA_VMEC)' From 37112989cf0581cbc6a02cd0be626f4d010ff802 Mon Sep 17 00:00:00 2001 From: lazersos Date: Sun, 10 Nov 2024 13:05:15 +0100 Subject: [PATCH 08/16] STELLOPT: Fixed issue where sometimes TXPORT header wouldn't be written to screen. --- STELLOPTV2/Sources/General/stellopt_txport.f90 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/STELLOPTV2/Sources/General/stellopt_txport.f90 b/STELLOPTV2/Sources/General/stellopt_txport.f90 index 4bb44c343..4b34cffd6 100644 --- a/STELLOPTV2/Sources/General/stellopt_txport.f90 +++ b/STELLOPTV2/Sources/General/stellopt_txport.f90 @@ -61,7 +61,7 @@ SUBROUTINE stellopt_txport(lscreen,iflag) ! ier Error flag ! iunit File unit number !---------------------------------------------------------------------- - LOGICAL :: file_test_eig,file_test_omega, lscreen_gene + LOGICAL :: file_test_eig,file_test_omega, lscreen_gene, lfirst_pass INTEGER :: maxPnt, nalpha0_, ialpha, i, iunit, ik, pol_turns_gene, & iunit_curv, irtmx, irt, iunit_eigen, nu, nv, spawn_procs, & spawn_root, spawn_info, spawn_comm, spawn_intercomm, ier @@ -128,6 +128,7 @@ SUBROUTINE stellopt_txport(lscreen,iflag) !---------------------------------------------------------------------- IF (iflag < 0) RETURN abserr = 1.0E-9 + lfirst_pass = .TRUE. !DEC$ IF DEFINED (TXPORT_OPT) IF (lscreen) WRITE(6,'(a)') ' -------------------- TURBULENT TRANSPORT CALC ----------------------' CALL FLUSH(6) @@ -721,7 +722,7 @@ SUBROUTINE stellopt_txport(lscreen,iflag) END SELECT WHERE (vqqprox /= vqqprox) vqqprox = bigno txport_q(ik,:,:) = vqqprox(:,:) - IF (lscreen .and. (ik==1)) WRITE(6,'(A)') ' s alpha0 iota shear Bref Lref Q_turb' + IF (lscreen .and. lfirst_pass) WRITE(6,'(A)') ' s alpha0 iota shear Bref Lref Q_turb' IF (lscreen) WRITE(6,'(7(F8.4))') s,alpha_start_txport,ABS(iot),shat,Ba,a,SUM(SUM(vqqprox,DIM=2)/maxPnt,DIM=1)/nalpha0_ WRITE(iunit,'(1pe14.6)') SUM(SUM(vqqprox,DIM=2)/maxPnt,DIM=1)/nalpha0_ DO i = 1, maxPnt @@ -729,6 +730,7 @@ SUBROUTINE stellopt_txport(lscreen,iflag) END DO CLOSE(iunit) CALL FLUSH(6) + lfirst_pass = .FALSE. END DO DEALLOCATE(phi0_gl,g11,g12,g22,Bhat,abs_jac,L2,L1,dBdt,kp1) DEALLOCATE(temp_arr,tout_arr) From ca58cbeef8ab64ef009ab66d5880ac038f217bb0 Mon Sep 17 00:00:00 2001 From: lazersos Date: Sun, 10 Nov 2024 13:05:51 +0100 Subject: [PATCH 09/16] pySTEL: Added QUASIISO to stellopt reading/plotting routines. --- pySTEL/STELLOPT.py | 17 +++++++++++++++-- pySTEL/libstell/stellopt.py | 2 +- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/pySTEL/STELLOPT.py b/pySTEL/STELLOPT.py index 53a17016d..77eca521b 100755 --- a/pySTEL/STELLOPT.py +++ b/pySTEL/STELLOPT.py @@ -877,7 +877,7 @@ def LoadSTELLOPT(self): 'HELICITY','HELICITY_FULL',\ 'KINK','ORBIT','JDOTB','J_STAR','NEO','TXPORT','ECEREFLECT',\ 'S11','S12','S21','S22','MAGWELL',\ - 'CURVATURE_KERT','CURVATURE_P2'] + 'CURVATURE_KERT','CURVATURE_P2','QUASIISO'] self.ui.ComboBoxOPTplot_type.clear() self.ui.ComboBoxOPTplot_type.addItem('Chi-Squared') # Handle Chisquared plots @@ -894,7 +894,7 @@ def LoadSTELLOPT(self): 'S11','S12','S21','S22','MAGWELL','VACIOTA',\ 'CURVATURE_KERT','CURVATURE_P2',\ 'ECEREFLECT','SXR','IOTA','PRESS','PRESSPRIME'\ - 'VISBREMLINE']: + 'VISBREMLINE','QUASIISO']: for item in vars(self.stel_data).keys(): if (name+'_TARGET' == item): self.ui.ComboBoxOPTplot_type.addItem(name+'_evolution') @@ -1130,6 +1130,19 @@ def UpdateOptplot(self): self.ax2.set_xlabel('Radial Grid') self.ax2.set_ylabel('Magnetic Well') self.ax2.set_title('Magnetic Well Evolution (>0 Well)') + elif (plot_name == 'QUASIISO_evolution'): + x = self.stel_data.QUASIISO_k + y = self.stel_data.QUASIISO_MAGWELL + t = self.stel_data.QUASIISO_TARGET + d = self.stel_data.QUASIISO_SIGMA + self.ax2.errorbar(x[0,:],t[0,:],yerr=d[0,:],fmt='ok',fillstyle='none',label='Target') + self.ax2.plot(x[0,:],y[0,:],'o',fillstyle='none',label='Initial',color='red') + for i in range(1,niter-1,1): + self.ax2.plot(x[i,:],y[i,:],'.k',fillstyle='none') + self.ax2.plot(x[niter-1,:],y[niter-1,:],'o',fillstyle='none',label='Final',color='green') + self.ax2.set_xlabel('Radial Grid') + self.ax2.set_ylabel('QI Metric') + self.ax2.set_title('Quasi-isodynamic Metric') elif (plot_name == 'CURVATURE_P2'): #x = self.stel_data.TXPORT_S #y = self.stel_data.CURVATURE_P2_P2 diff --git a/pySTEL/libstell/stellopt.py b/pySTEL/libstell/stellopt.py index eb0ef6456..3ce48f650 100644 --- a/pySTEL/libstell/stellopt.py +++ b/pySTEL/libstell/stellopt.py @@ -33,7 +33,7 @@ def __init__(self): 'NEO', 'DKES', 'DKES_ERDIFF', 'DKES_ALPHA', 'TXPORT', \ 'ORBIT', 'HELICITY', 'HELICITY_FULL', 'JSTAR', 'RESJAC', \ 'COIL_BNORM', 'REGCOIL_CHI2_B', 'CURVATURE_P2', 'GAMMA_C', \ - 'KINK'] + 'KINK', 'QUASIISO'] def read_stellopt_map(self,filename='map.dat'): """Reads a STELLOPT MAP output file From 7ec9e71e4d738977c5cd1e728555fe51f11f6430 Mon Sep 17 00:00:00 2001 From: lazersos Date: Sun, 10 Nov 2024 14:44:12 +0100 Subject: [PATCH 10/16] STELLOPT: Fixed bug in QUASIISO lh calculation. --- STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 | 1 + 1 file changed, 1 insertion(+) diff --git a/STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 b/STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 index 67b21b0c6..5323e73c0 100644 --- a/STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 +++ b/STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 @@ -102,6 +102,7 @@ SUBROUTINE chisq_quasiiso(target,sigma,niter,iflag) !lh = FLOOR(nalpha*0.5)+1 !modb = CSHIFT(modb,lmin-lh) !BOOSH lh = MINLOC(modb,DIM=1) + lh = MIN(MAX(lh,1),nalpha) ! Squash the array modbs = modb DO l = lh, 1, -1 From 7e3e9283d2447dd5e13d8f0b617756cfcc48bce8 Mon Sep 17 00:00:00 2001 From: lazersos Date: Sun, 10 Nov 2024 17:42:00 +0100 Subject: [PATCH 11/16] STELLOPT: Adjustment of lh min/max value to avoid walking off end of array. --- STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 b/STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 index 5323e73c0..c55318b62 100644 --- a/STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 +++ b/STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 @@ -102,7 +102,7 @@ SUBROUTINE chisq_quasiiso(target,sigma,niter,iflag) !lh = FLOOR(nalpha*0.5)+1 !modb = CSHIFT(modb,lmin-lh) !BOOSH lh = MINLOC(modb,DIM=1) - lh = MIN(MAX(lh,1),nalpha) + lh = MIN(MAX(lh,2),nalpha-1) ! Squash the array modbs = modb DO l = lh, 1, -1 From 6cffe880b1835823f26c36cabe977b445f0fa4fb Mon Sep 17 00:00:00 2001 From: lazersos Date: Mon, 11 Nov 2024 10:14:20 +0100 Subject: [PATCH 12/16] STELLOPT: Added in array shift in quasi-iso to improve calculations. --- STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 | 26 ++++++++++++--------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 b/STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 index c55318b62..df24a1125 100644 --- a/STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 +++ b/STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 @@ -98,27 +98,31 @@ SUBROUTINE chisq_quasiiso(target,sigma,niter,iflag) END DO END DO IF (lwrite_out) WRITE(321,*) modb - ! Sort the arrays - !lh = FLOOR(nalpha*0.5)+1 - !modb = CSHIFT(modb,lmin-lh) !BOOSH - lh = MINLOC(modb,DIM=1) - lh = MIN(MAX(lh,2),nalpha-1) + ! Find the Bmin and half point + lh = FLOOR(nalpha*0.5)+1 + lmin = MINLOC(modb,DIM=1) + lmin = MIN(MAX(lmin,2),nalpha-1) + ! Now shift lmin to the middle + modb = CSHIFT(modb,lmin-lh) !BOOSH + ! Now recalc lh as lmin + lmin = MINLOC(modb,DIM=1) + lmin = MIN(MAX(lmin,2),nalpha-1) ! Squash the array modbs = modb - DO l = lh, 1, -1 + DO l = lmin, 1, -1 IF (modbs(l)Bmir) + 1 - i2 = COUNT(modbs(lh:nalpha)Bmir) + 1 + i2 = COUNT(modbs(lmin:nalpha) Date: Mon, 11 Nov 2024 20:37:43 +0100 Subject: [PATCH 13/16] STELLOPT: Fixed issue with initalization of quasiiso target. --- STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 b/STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 index df24a1125..248ce700d 100644 --- a/STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 +++ b/STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 @@ -15,8 +15,9 @@ SUBROUTINE chisq_quasiiso(target,sigma,niter,iflag) USE stellopt_runtime USE stellopt_targets USE equil_utils, ONLY: get_equil_iota - USE read_boozer_mod + USE read_boozer_mod, ONLY: bmnc_b, ixn_b, ixm_b, mnboz_b, ns_b, nfp_b USE vmec_input, ONLY: mpol, ntor +! USE stel_kinds, ONLY: rprec !----------------------------------------------------------------------- ! Input/Output Variables @@ -179,10 +180,8 @@ SUBROUTINE chisq_quasiiso(target,sigma,niter,iflag) DO ik = 1, nsd IF (ABS(sigma(ik)) < bigno) THEN lbooz(ik) = .TRUE. - DO mn = 1, mnboz_b - mtargets = mtargets + 1 - IF (niter == -2) target_dex(mtargets) = jtarget_quasiiso - END DO + mtargets = mtargets + 1 + IF (niter == -2) target_dex(mtargets) = jtarget_quasiiso END IF END DO END IF From f59dcb3e9aa9761b6c33b187c9860b0a1a1a12cb Mon Sep 17 00:00:00 2001 From: lazersos Date: Tue, 12 Nov 2024 15:29:01 +0100 Subject: [PATCH 14/16] pySTEL: Fixed bug in STELLOPT related to the QI evo plot. --- pySTEL/STELLOPT.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pySTEL/STELLOPT.py b/pySTEL/STELLOPT.py index 77eca521b..c8615ca6d 100755 --- a/pySTEL/STELLOPT.py +++ b/pySTEL/STELLOPT.py @@ -1131,8 +1131,8 @@ def UpdateOptplot(self): self.ax2.set_ylabel('Magnetic Well') self.ax2.set_title('Magnetic Well Evolution (>0 Well)') elif (plot_name == 'QUASIISO_evolution'): - x = self.stel_data.QUASIISO_k - y = self.stel_data.QUASIISO_MAGWELL + x = self.stel_data.QUASIISO_K + y = self.stel_data.QUASIISO_VAL t = self.stel_data.QUASIISO_TARGET d = self.stel_data.QUASIISO_SIGMA self.ax2.errorbar(x[0,:],t[0,:],yerr=d[0,:],fmt='ok',fillstyle='none',label='Target') From 0151d90d3f81d4ba8b86c14bea196ebe6552712a Mon Sep 17 00:00:00 2001 From: lazersos Date: Tue, 12 Nov 2024 15:29:20 +0100 Subject: [PATCH 15/16] STELLOPT: Fixed header bug in QI metric. --- STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 b/STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 index 248ce700d..702cda87c 100644 --- a/STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 +++ b/STELLOPTV2/Sources/Chisq/chisq_quasiiso.f90 @@ -50,7 +50,8 @@ SUBROUTINE chisq_quasiiso(target,sigma,niter,iflag) ! BEGIN SUBROUTINE !----------------------------------------------------------------------- IF (iflag < 0) RETURN - IF (iflag == 1) WRITE(iunit_out,'(A,2(2X,I3.3))') 'QUASIISO ',1,4 + ik = COUNT(sigma < bigno) + IF (iflag == 1) WRITE(iunit_out,'(A,2(2X,I3.3))') 'QUASIISO ',ik,4 IF (iflag == 1) WRITE(iunit_out,'(A)') 'TARGET SIGMA VAL K' IF (niter >= 0) THEN ! Allocate helpers along field line From 2cbda30a70832308b7e253eb67a7695505f1a07a Mon Sep 17 00:00:00 2001 From: lazersos Date: Fri, 15 Nov 2024 14:04:30 +0100 Subject: [PATCH 16/16] SHARE: Macport file now uses detection for turning optional flags on. --- SHARE/make_macports.inc | 43 +++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/SHARE/make_macports.inc b/SHARE/make_macports.inc index d2c226953..db58d3db1 100644 --- a/SHARE/make_macports.inc +++ b/SHARE/make_macports.inc @@ -104,7 +104,8 @@ endif ####################################################################### # GENE Options ####################################################################### - LGENE = F +ifneq ("$(wildcard $(GENE_PATH))","") + LGENE = T GENE_INC = -I$(GENE_PATH) GENE_DIR = $(GENE_PATH) LIB_GENE = libgene.a @@ -113,30 +114,42 @@ endif -L$(FFTWHOME)/lib -lfftw3 \ -L$(SLEPC_DIR)/$(PETSC_ARCH)/lib -lslepc \ -L$(PETSC_DIR)/$(PETSC_ARCH)/lib -lpetsc -lX11 +else + LGENE = F +endif ####################################################################### # COILOPT++ Options ####################################################################### - LCOILOPT = F +ifneq ("$(wildcard $(COILOPT_PATH))","") + LCOILOPT = T COILOPT_INC = -I$(COILOPT_PATH) COILOPTPP_DIR = $(COILOPT_PATH) LIB_COILOPTPP = libcoilopt++.a COILOPT_LIB = $(COILOPT_PATH)/$(LIB_COILOPTPP) \ -L$(GSLHOME)/lib -lgsl -lgslcblas -lstdc++ -lmpi_cxx +else + LCOILOPT = F +endif ####################################################################### # TERPSICHORE Options ####################################################################### - LTERPSICHORE= F +ifneq ("$(wildcard $(TERPSICHORE_PATH))","") + LTERPSICHORE= T TERPSICHORE_INC = -I$(TERPSICHORE_PATH) TERPSICHORE_DIR = $(TERPSICHORE_PATH) LIB_TERPSICHORE = libterpsichore.a TERPSICHORE_LIB = $(TERPSICHORE_DIR)/$(LIB_TERPSICHORE) +else + LTERPSICHORE = F +endif ####################################################################### # TRAVIS Options ####################################################################### - LTRAVIS= F +ifneq ("$(wildcard $(TRAVIS_PATH))","") + LTRAVIS = T TRAVIS_DIR = $(TRAVIS_PATH) LIB_TRAVIS = libtravis64_sopt.a LIB_MCONF = libmconf64.a @@ -144,35 +157,49 @@ endif TRAVIS_LIB = $(TRAVIS_DIR)lib/$(LIB_TRAVIS) \ $(TRAVIS_DIR)faddeeva_package/lib/$(LIB_FADDEEVA) \ $(TRAVIS_DIR)magconf/lib/$(LIB_MCONF) -lc++ +else + LTRAVIS = F +endif ####################################################################### # REGCOIL Options ####################################################################### - LREGCOIL= F +ifneq ("$(wildcard $(REGCOIL_PATH))","") + LREGCOIL= T REGCOIL_DIR = $(REGCOIL_PATH) REGCOIL_INC = -I$(REGCOIL_DIR) LIB_REGCOIL = libregcoil.a REGCOIL_LIB = $(REGCOIL_DIR)/$(LIB_REGCOIL) -fopenmp +else + LREGCOIL = F +endif ####################################################################### # SFINCS Options ####################################################################### - - LSFINCS = F +ifneq ("$(wildcard $(SFINCS_PATH))","") + LSFINCS = T SFINCS_DIR = $(SFINCS_PATH) SFINCS_INC = -I$(SFINCS_DIR) LIB_SFINCS = libsfincs.a SFINCS_LIB = $(SFINCS_DIR)/$(LIB_SFINCS) \ -L$(PETSC_DIR)/$(PETSC_ARCH)/lib -lpetsc -lX11 +else + LSFINCS = F +endif ####################################################################### # Available Energy Options ####################################################################### - LAEOPT= F +ifneq ("$(wildcard $(AEOPT_PATH))","") + LAEOPT = T AEOPT_DIR = $(AEOPT_PATH) AEOPT_INC = -I$(AEOPT_DIR) LIB_AEOPT = libtrapAE.a AEOPT_LIB = $(AEOPT_PATH)/$(LIB_AEOPT) +else + LAEOPT = F +endif ####################################################################### # LIBSTELL Shared Options