diff --git a/.gitignore b/.gitignore
index 795de19..f2c5b1f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,46 +1,48 @@
.vimrc
*.swp
*~
*.asv
*.m.orig
*.DS_Store
*.fig
*.pdf
*.eps
*.mov
*.mp4
*.emf
*.pptx
*.jpg
*.gif
*.jpeg
*.mat
*.dat
*.mod
*.h5
*.o
*.a
*.png
logs/
results/
results_old/
mod/
obj/
bin/
wk/fort*.90
.directory
checkpoint/
FM/
iCa/
*.out
src/srcinfo.h
src/srcinfo/srcinfo.h
local/
*/*.sh
Gallery/
.vscode/settings.json
*figure*
*results*
out*
!scripts/*
*.avi
+gyacomo
+gyacomo_dbg
diff --git a/Makefile b/Makefile
index fd9aa22..9a0ccb3 100644
--- a/Makefile
+++ b/Makefile
@@ -1,240 +1,279 @@
include local/dirs.inc
include local/make.inc
EXEC = $(BINDIR)/gyacomo
EFST = $(BINDIR)/gyacomo_fst
EDBG = $(BINDIR)/gyacomo_dbg
F90 = mpiifort
# #F90 = ftn #for piz-daint cluster
# # Add Multiple-Precision Library
# EXTLIBS += -L$(FMDIR)/lib
# EXTINC += -I$(FMDIR)/mod
# # Add local fftw dir
# EXTLIBS += -L$(FFTWDIR)/lib
# EXTINC += -I$(FFTWDIR)/include
# # Add lapack
# EXTLIBS += -L$(LAPACKDIR)/lib
# EXTINC += -I$(LAPACKDIR)/mod
all: dirs src/srcinfo.h
all: F90FLAGS = -O3 -xHOST
all: $(EXEC)
fast: dirs src/srcinfo.h
fast: F90FLAGS = -fast
fast: $(EFST)
dbg: dirs src/srcinfo.h
dbg: F90FLAGS = -g -traceback -CB
dbg: $(EDBG)
install: dirs src/srcinfo.h $(EXEC) mvmod
run: all
(cd wk; $(EXEC);)
dirs:
mkdir -p $(BINDIR)
mkdir -p $(OBJDIR)
mkdir -p $(MODDIR)
src/srcinfo.h:
( cd src/srcinfo; $(MAKE);)
clean: cleanobj cleanmod
@rm -f src/srcinfo.h
@rm -f src/srcinfo/srcinfo.h
cleanobj:
@rm -f $(OBJDIR)/*o
cleanmod:
@rm -f $(MODDIR)/*mod
@rm -f *.mod
cleanbin:
@rm -f $(EXEC)
mvmod:
mv *.mod mod/.
$(OBJDIR)/diagnose.o : src/srcinfo.h
FOBJ=$(OBJDIR)/advance_field.o $(OBJDIR)/array_mod.o $(OBJDIR)/auxval.o \
$(OBJDIR)/basic_mod.o $(OBJDIR)/coeff_mod.o $(OBJDIR)/closure_mod.o \
$(OBJDIR)/collision_mod.o $(OBJDIR)/nonlinear_mod.o $(OBJDIR)/control.o \
$(OBJDIR)/diagnose.o $(OBJDIR)/diagnostics_par_mod.o $(OBJDIR)/endrun.o \
$(OBJDIR)/fields_mod.o $(OBJDIR)/fourier_mod.o $(OBJDIR)/geometry_mod.o \
$(OBJDIR)/ghosts_mod.o $(OBJDIR)/grid_mod.o $(OBJDIR)/inital.o \
-$(OBJDIR)/initial_par_mod.o $(OBJDIR)/main.o $(OBJDIR)/memory.o \
-$(OBJDIR)/model_mod.o $(OBJDIR)/moments_eq_rhs_mod.o $(OBJDIR)/numerics_mod.o \
-$(OBJDIR)/parallel_mod.o $(OBJDIR)/ppexit.o $(OBJDIR)/ppinit.o \
-$(OBJDIR)/prec_const_mod.o $(OBJDIR)/processing_mod.o $(OBJDIR)/readinputs.o \
-$(OBJDIR)/restarts_mod.o $(OBJDIR)/solve_EM_fields.o $(OBJDIR)/stepon.o \
-$(OBJDIR)/tesend.o $(OBJDIR)/time_integration_mod.o $(OBJDIR)/utility_mod.o
+$(OBJDIR)/initial_par_mod.o $(OBJDIR)/lag_interp_mod.o $(OBJDIR)/main.o \
+$(OBJDIR)/memory.o $(OBJDIR)/miller_mod.o $(OBJDIR)/model_mod.o \
+$(OBJDIR)/moments_eq_rhs_mod.o $(OBJDIR)/numerics_mod.o $(OBJDIR)/parallel_mod.o \
+$(OBJDIR)/ppexit.o $(OBJDIR)/ppinit.o $(OBJDIR)/prec_const_mod.o \
+$(OBJDIR)/processing_mod.o $(OBJDIR)/readinputs.o $(OBJDIR)/restarts_mod.o \
+$(OBJDIR)/solve_EM_fields.o $(OBJDIR)/stepon.o $(OBJDIR)/tesend.o \
+$(OBJDIR)/time_integration_mod.o $(OBJDIR)/utility_mod.o
$(EXEC): $(FOBJ)
$(F90) $(LDFLAGS) $(OBJDIR)/*.o $(EXTMOD) $(EXTINC) $(EXTLIBS) -o $@
$(EFST): $(FOBJ)
$(F90) $(LDFLAGS) $(OBJDIR)/*.o $(EXTMOD) $(EXTINC) $(EXTLIBS) -o $@
$(EDBG): $(FOBJ)
$(F90) $(LDFLAGS) $(OBJDIR)/*.o $(EXTMOD) $(EXTINC) $(EXTLIBS) -o $@
- $(OBJDIR)/advance_field.o : src/advance_field.F90 $(OBJDIR)/grid_mod.o $(OBJDIR)/array_mod.o \
- $(OBJDIR)/initial_par_mod.o $(OBJDIR)/prec_const_mod.o $(OBJDIR)/time_integration_mod.o \
- $(OBJDIR)/basic_mod.o $(OBJDIR)/fields_mod.o
+ $(OBJDIR)/advance_field.o : src/advance_field.F90 \
+ $(OBJDIR)/grid_mod.o $(OBJDIR)/array_mod.o $(OBJDIR)/initial_par_mod.o \
+ $(OBJDIR)/prec_const_mod.o $(OBJDIR)/time_integration_mod.o $(OBJDIR)/basic_mod.o \
+ $(OBJDIR)/fields_mod.o
$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/advance_field.F90 -o $@
- $(OBJDIR)/array_mod.o : src/array_mod.F90 $(OBJDIR)/prec_const_mod.o
+ $(OBJDIR)/array_mod.o : src/array_mod.F90 \
+ $(OBJDIR)/prec_const_mod.o
$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/array_mod.F90 -o $@
- $(OBJDIR)/auxval.o : src/auxval.F90 $(OBJDIR)/fourier_mod.o $(OBJDIR)/memory.o \
- $(OBJDIR)/model_mod.o $(OBJDIR)/geometry_mod.o $(OBJDIR)/grid_mod.o $(OBJDIR)/numerics_mod.o\
- $(OBJDIR)/parallel_mod.o
+ $(OBJDIR)/auxval.o : src/auxval.F90 \
+ $(OBJDIR)/fourier_mod.o $(OBJDIR)/memory.o $(OBJDIR)/model_mod.o \
+ $(OBJDIR)/geometry_mod.o $(OBJDIR)/grid_mod.o $(OBJDIR)/numerics_mod.o \
+ $(OBJDIR)/parallel_mod.o
$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/auxval.F90 -o $@
- $(OBJDIR)/basic_mod.o : src/basic_mod.F90 $(OBJDIR)/prec_const_mod.o
+ $(OBJDIR)/basic_mod.o : src/basic_mod.F90 \
+ $(OBJDIR)/prec_const_mod.o
$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/basic_mod.F90 -o $@
- $(OBJDIR)/calculus_mod.o : src/calculus_mod.F90 $(OBJDIR)/basic_mod.o $(OBJDIR)/prec_const_mod.o \
- $(OBJDIR)/grid_mod.o $(OBJDIR)/parallel_mod.o
+ $(OBJDIR)/calculus_mod.o : src/calculus_mod.F90 \
+ $(OBJDIR)/basic_mod.o $(OBJDIR)/prec_const_mod.o $(OBJDIR)/grid_mod.o \
+ $(OBJDIR)/parallel_mod.o
$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/calculus_mod.F90 -o $@
- $(OBJDIR)/coeff_mod.o : src/coeff_mod.F90 $(OBJDIR)/prec_const_mod.o $(OBJDIR)/basic_mod.o \
- $(OBJDIR)/model_mod.o $(OBJDIR)/basic_mod.o
+ $(OBJDIR)/coeff_mod.o : src/coeff_mod.F90 \
+ $(OBJDIR)/prec_const_mod.o $(OBJDIR)/basic_mod.o $(OBJDIR)/model_mod.o \
+ $(OBJDIR)/basic_mod.o
$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/coeff_mod.F90 -o $@
- $(OBJDIR)/closure_mod.o : src/closure_mod.F90 $(OBJDIR)/model_mod.o $(OBJDIR)/basic_mod.o \
- $(OBJDIR)/grid_mod.o $(OBJDIR)/array_mod.o $(OBJDIR)/fields_mod.o
+ $(OBJDIR)/closure_mod.o : src/closure_mod.F90 \
+ $(OBJDIR)/model_mod.o $(OBJDIR)/basic_mod.o $(OBJDIR)/grid_mod.o \
+ $(OBJDIR)/array_mod.o $(OBJDIR)/fields_mod.o
$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/closure_mod.F90 -o $@
- $(OBJDIR)/collision_mod.o : src/collision_mod.F90 $(OBJDIR)/array_mod.o $(OBJDIR)/basic_mod.o \
- $(OBJDIR)/fields_mod.o $(OBJDIR)/grid_mod.o $(OBJDIR)/model_mod.o $(OBJDIR)/prec_const_mod.o \
+ $(OBJDIR)/collision_mod.o : src/collision_mod.F90 \
+ $(OBJDIR)/array_mod.o $(OBJDIR)/basic_mod.o $(OBJDIR)/fields_mod.o \
+ $(OBJDIR)/grid_mod.o $(OBJDIR)/model_mod.o $(OBJDIR)/prec_const_mod.o \
$(OBJDIR)/time_integration_mod.o $(OBJDIR)/utility_mod.o
$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/collision_mod.F90 -o $@
- $(OBJDIR)/control.o : src/control.F90 $(OBJDIR)/auxval.o $(OBJDIR)/geometry_mod.o \
- $(OBJDIR)/prec_const_mod.o $(OBJDIR)/basic_mod.o $(OBJDIR)/ppexit.o $(OBJDIR)/ppinit.o \
+ $(OBJDIR)/control.o : src/control.F90 \
+ $(OBJDIR)/auxval.o $(OBJDIR)/geometry_mod.o $(OBJDIR)/prec_const_mod.o \
+ $(OBJDIR)/basic_mod.o $(OBJDIR)/ppexit.o $(OBJDIR)/ppinit.o \
$(OBJDIR)/readinputs.o $(OBJDIR)/tesend.o
$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/control.F90 -o $@
- $(OBJDIR)/diagnose.o : src/diagnose.F90 $(OBJDIR)/prec_const_mod.o $(OBJDIR)/processing_mod.o\
- $(OBJDIR)/array_mod.o $(OBJDIR)/basic_mod.o $(OBJDIR)/diagnostics_par_mod.o $(OBJDIR)/fields_mod.o \
- $(OBJDIR)/grid_mod.o $(OBJDIR)/initial_par_mod.o $(OBJDIR)/model_mod.o $(OBJDIR)/time_integration_mod.o\
+ $(OBJDIR)/diagnose.o : src/diagnose.F90 \
+ $(OBJDIR)/prec_const_mod.o $(OBJDIR)/processing_mod.o $(OBJDIR)/array_mod.o \
+ $(OBJDIR)/basic_mod.o $(OBJDIR)/diagnostics_par_mod.o $(OBJDIR)/fields_mod.o \
+ $(OBJDIR)/grid_mod.o $(OBJDIR)/initial_par_mod.o $(OBJDIR)/model_mod.o \
+ $(OBJDIR)/time_integration_mod.o\
$(OBJDIR)/parallel_mod.o
$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/diagnose.F90 -o $@
- $(OBJDIR)/diagnostics_par_mod.o : src/diagnostics_par_mod.F90 $(OBJDIR)/prec_const_mod.o \
- $(OBJDIR)/basic_mod.o
+ $(OBJDIR)/diagnostics_par_mod.o : src/diagnostics_par_mod.F90 \
+ $(OBJDIR)/prec_const_mod.o $(OBJDIR)/basic_mod.o
$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/diagnostics_par_mod.F90 -o $@
- $(OBJDIR)/endrun.o : src/endrun.F90 $(OBJDIR)/prec_const_mod.o $(OBJDIR)/basic_mod.o
+ $(OBJDIR)/endrun.o : src/endrun.F90 \
+ $(OBJDIR)/prec_const_mod.o $(OBJDIR)/basic_mod.o
$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/endrun.F90 -o $@
- $(OBJDIR)/fields_mod.o : src/fields_mod.F90 $(OBJDIR)/prec_const_mod.o
+ $(OBJDIR)/fields_mod.o : src/fields_mod.F90 \
+ $(OBJDIR)/prec_const_mod.o
$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/fields_mod.F90 -o $@
- $(OBJDIR)/fourier_mod.o : src/fourier_mod.F90 $(OBJDIR)/basic_mod.o $(OBJDIR)/prec_const_mod.o \
- $(OBJDIR)/grid_mod.o
+ $(OBJDIR)/fourier_mod.o : src/fourier_mod.F90 \
+ $(OBJDIR)/basic_mod.o $(OBJDIR)/prec_const_mod.o $(OBJDIR)/grid_mod.o
$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/fourier_mod.F90 -o $@
- $(OBJDIR)/geometry_mod.o : src/geometry_mod.F90 $(OBJDIR)/array_mod.o $(OBJDIR)/calculus_mod.o\
- $(OBJDIR)/grid_mod.o $(OBJDIR)/model_mod.o $(OBJDIR)/prec_const_mod.o $(OBJDIR)/utility_mod.o
+ $(OBJDIR)/geometry_mod.o : src/geometry_mod.F90 \
+ $(OBJDIR)/array_mod.o $(OBJDIR)/calculus_mod.o $(OBJDIR)/miller_mod.o \
+ $(OBJDIR)/grid_mod.o $(OBJDIR)/model_mod.o $(OBJDIR)/prec_const_mod.o \
+ $(OBJDIR)/utility_mod.o
$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/geometry_mod.F90 -o $@
- $(OBJDIR)/ghosts_mod.o : src/ghosts_mod.F90 $(OBJDIR)/basic_mod.o $(OBJDIR)/fields_mod.o \
- $(OBJDIR)/grid_mod.o $(OBJDIR)/geometry_mod.o $(OBJDIR)/ppinit.o $(OBJDIR)/time_integration_mod.o
+ $(OBJDIR)/ghosts_mod.o : src/ghosts_mod.F90 \
+ $(OBJDIR)/basic_mod.o $(OBJDIR)/fields_mod.o $(OBJDIR)/grid_mod.o\
+ $(OBJDIR)/geometry_mod.o $(OBJDIR)/ppinit.o $(OBJDIR)/time_integration_mod.o
$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/ghosts_mod.F90 -o $@
- $(OBJDIR)/grid_mod.o : src/grid_mod.F90 $(OBJDIR)/basic_mod.o $(OBJDIR)/model_mod.o\
- $(OBJDIR)/prec_const_mod.o
+ $(OBJDIR)/grid_mod.o : src/grid_mod.F90 \
+ $(OBJDIR)/basic_mod.o $(OBJDIR)/model_mod.o $(OBJDIR)/prec_const_mod.o
$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/grid_mod.F90 -o $@
- $(OBJDIR)/inital.o : src/inital.F90 $(OBJDIR)/array_mod.o $(OBJDIR)/basic_mod.o \
- $(OBJDIR)/fields_mod.o $(OBJDIR)/initial_par_mod.o $(OBJDIR)/model_mod.o $(OBJDIR)/numerics_mod.o \
- $(OBJDIR)/solve_EM_fields.o $(OBJDIR)/prec_const_mod.o $(OBJDIR)/ghosts_mod.o $(OBJDIR)/grid_mod.o \
+ $(OBJDIR)/inital.o : src/inital.F90 \
+ $(OBJDIR)/array_mod.o $(OBJDIR)/basic_mod.o $(OBJDIR)/fields_mod.o \
+ $(OBJDIR)/initial_par_mod.o $(OBJDIR)/model_mod.o $(OBJDIR)/numerics_mod.o \
+ $(OBJDIR)/solve_EM_fields.o $(OBJDIR)/prec_const_mod.o $(OBJDIR)/ghosts_mod.o \
+ $(OBJDIR)/grid_mod.o \
$(OBJDIR)/restarts_mod.o $(OBJDIR)/time_integration_mod.o $(OBJDIR)/utility_mod.o
$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/inital.F90 -o $@
- $(OBJDIR)/initial_par_mod.o : src/initial_par_mod.F90 $(OBJDIR)/basic_mod.o \
- $(OBJDIR)/prec_const_mod.o
+ $(OBJDIR)/initial_par_mod.o : src/initial_par_mod.F90 \
+ $(OBJDIR)/basic_mod.o $(OBJDIR)/prec_const_mod.o
$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/initial_par_mod.F90 -o $@
+ $(OBJDIR)/lag_interp_mod.o : src/lag_interp_mod.F90 \
+ $(OBJDIR)/prec_const_mod.o
+ $(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/lag_interp_mod.F90 -o $@
+
$(OBJDIR)/main.o : src/main.F90 $(OBJDIR)/prec_const_mod.o
$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/main.F90 -o $@
- $(OBJDIR)/memory.o : src/memory.F90 $ $(OBJDIR)/array_mod.o $(OBJDIR)/basic_mod.o \
- $(OBJDIR)/collision_mod.o $(OBJDIR)/fields_mod.o $(OBJDIR)/model_mod.o $(OBJDIR)/time_integration_mod.o \
+ $(OBJDIR)/memory.o : src/memory.F90 $ \
+ $(OBJDIR)/array_mod.o $(OBJDIR)/basic_mod.o $(OBJDIR)/collision_mod.o\
+ $(OBJDIR)/fields_mod.o $(OBJDIR)/model_mod.o $(OBJDIR)/time_integration_mod.o \
$(OBJDIR)/grid_mod.o
$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/memory.F90 -o $@
- $(OBJDIR)/model_mod.o : src/model_mod.F90 $(OBJDIR)/prec_const_mod.o
+ $(OBJDIR)/miller_mod.o : src/miller_mod.F90 \
+ $(OBJDIR)/basic_mod.o $(OBJDIR)/model_mod.o $(OBJDIR)/lag_interp_mod.o \
+ $(OBJDIR)/prec_const_mod.o
+ $(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/miller_mod.F90 -o $@
+
+ $(OBJDIR)/model_mod.o : src/model_mod.F90 \
+ $(OBJDIR)/prec_const_mod.o
$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/model_mod.F90 -o $@
- $(OBJDIR)/moments_eq_rhs_mod.o : src/moments_eq_rhs_mod.F90 $(OBJDIR)/array_mod.o \
- $(OBJDIR)/calculus_mod.o $(OBJDIR)/fields_mod.o $(OBJDIR)/prec_const_mod.o $(OBJDIR)/grid_mod.o \
- $(OBJDIR)/model_mod.o $(OBJDIR)/time_integration_mod.o
+ $(OBJDIR)/moments_eq_rhs_mod.o : src/moments_eq_rhs_mod.F90 \
+ $(OBJDIR)/array_mod.o $(OBJDIR)/calculus_mod.o $(OBJDIR)/fields_mod.o \
+ $(OBJDIR)/prec_const_mod.o $(OBJDIR)/grid_mod.o $(OBJDIR)/model_mod.o \
+ $(OBJDIR)/time_integration_mod.o
$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/moments_eq_rhs_mod.F90 -o $@
- $(OBJDIR)/nonlinear_mod.o : src/nonlinear_mod.F90 $(OBJDIR)/array_mod.o $(OBJDIR)/basic_mod.o \
- $(OBJDIR)/fourier_mod.o $(OBJDIR)/fields_mod.o $(OBJDIR)/grid_mod.o $(OBJDIR)/model_mod.o\
+ $(OBJDIR)/nonlinear_mod.o : src/nonlinear_mod.F90 \
+ $(OBJDIR)/array_mod.o $(OBJDIR)/basic_mod.o $(OBJDIR)/fourier_mod.o \
+ $(OBJDIR)/fields_mod.o $(OBJDIR)/grid_mod.o $(OBJDIR)/model_mod.o\
$(OBJDIR)/prec_const_mod.o $(OBJDIR)/time_integration_mod.o
$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/nonlinear_mod.F90 -o $@
- $(OBJDIR)/numerics_mod.o : src/numerics_mod.F90 $(OBJDIR)/prec_const_mod.o $(OBJDIR)/basic_mod.o \
- $(OBJDIR)/coeff_mod.o $(OBJDIR)/utility_mod.o
+ $(OBJDIR)/numerics_mod.o : src/numerics_mod.F90 \
+ $(OBJDIR)/prec_const_mod.o $(OBJDIR)/basic_mod.o $(OBJDIR)/coeff_mod.o \
+ $(OBJDIR)/utility_mod.o
$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/numerics_mod.F90 -o $@
- $(OBJDIR)/parallel_mod.o : src/parallel_mod.F90 $(OBJDIR)/basic_mod.o $(OBJDIR)/prec_const_mod.o \
- $(OBJDIR)/grid_mod.o
+ $(OBJDIR)/parallel_mod.o : src/parallel_mod.F90 \
+ $(OBJDIR)/basic_mod.o $(OBJDIR)/prec_const_mod.o $(OBJDIR)/grid_mod.o
$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/parallel_mod.F90 -o $@
- $(OBJDIR)/ppexit.o : src/ppexit.F90 $(OBJDIR)/prec_const_mod.o $(OBJDIR)/basic_mod.o \
- $(OBJDIR)/coeff_mod.o
+ $(OBJDIR)/ppexit.o : src/ppexit.F90 \
+ $(OBJDIR)/prec_const_mod.o $(OBJDIR)/basic_mod.o $(OBJDIR)/coeff_mod.o
$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/ppexit.F90 -o $@
- $(OBJDIR)/ppinit.o : src/ppinit.F90 $(OBJDIR)/array_mod.o $(OBJDIR)/prec_const_mod.o \
- $(OBJDIR)/grid_mod.o $(OBJDIR)/fields_mod.o $(OBJDIR)/array_mod.o $(OBJDIR)/time_integration_mod.o \
+ $(OBJDIR)/ppinit.o : src/ppinit.F90 \
+ $(OBJDIR)/array_mod.o $(OBJDIR)/prec_const_mod.o $(OBJDIR)/grid_mod.o\
+ $(OBJDIR)/fields_mod.o $(OBJDIR)/array_mod.o $(OBJDIR)/time_integration_mod.o \
$(OBJDIR)/basic_mod.o
$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/ppinit.F90 -o $@
$(OBJDIR)/prec_const_mod.o : src/prec_const_mod.F90
$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/prec_const_mod.F90 -o $@
- $(OBJDIR)/processing_mod.o : src/processing_mod.F90 $(OBJDIR)/array_mod.o $(OBJDIR)/prec_const_mod.o \
- $(OBJDIR)/grid_mod.o $(OBJDIR)/fields_mod.o $(OBJDIR)/basic_mod.o
+ $(OBJDIR)/processing_mod.o : src/processing_mod.F90 \
+ $(OBJDIR)/array_mod.o $(OBJDIR)/prec_const_mod.o $(OBJDIR)/grid_mod.o \
+ $(OBJDIR)/fields_mod.o $(OBJDIR)/basic_mod.o
$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/processing_mod.F90 -o $@
- $(OBJDIR)/readinputs.o : src/readinputs.F90 $(OBJDIR)/diagnostics_par_mod.o $(OBJDIR)/initial_par_mod.o \
- $(OBJDIR)/model_mod.o $(OBJDIR)/prec_const_mod.o $(OBJDIR)/grid_mod.o $(OBJDIR)/time_integration_mod.o
+ $(OBJDIR)/readinputs.o : src/readinputs.F90 \
+ $(OBJDIR)/diagnostics_par_mod.o $(OBJDIR)/initial_par_mod.o $(OBJDIR)/model_mod.o \
+ $(OBJDIR)/prec_const_mod.o $(OBJDIR)/grid_mod.o $(OBJDIR)/time_integration_mod.o
$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/readinputs.F90 -o $@
- $(OBJDIR)/restarts_mod.o : src/restarts_mod.F90 $(OBJDIR)/diagnostics_par_mod.o \
- $(OBJDIR)/grid_mod.o $(OBJDIR)/time_integration_mod.o
+ $(OBJDIR)/restarts_mod.o : src/restarts_mod.F90 \
+ $(OBJDIR)/diagnostics_par_mod.o $(OBJDIR)/grid_mod.o $(OBJDIR)/time_integration_mod.o
$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/restarts_mod.F90 -o $@
- $(OBJDIR)/solve_EM_fields.o : src/solve_EM_fields.F90 $(OBJDIR)/array_mod.o $(OBJDIR)/prec_const_mod.o \
- $(OBJDIR)/grid_mod.o $(OBJDIR)/ghosts_mod.o $(OBJDIR)/fields_mod.o $(OBJDIR)/array_mod.o \
+ $(OBJDIR)/solve_EM_fields.o : src/solve_EM_fields.F90 \
+ $(OBJDIR)/array_mod.o $(OBJDIR)/prec_const_mod.o $(OBJDIR)/grid_mod.o \
+ $(OBJDIR)/ghosts_mod.o $(OBJDIR)/fields_mod.o $(OBJDIR)/array_mod.o \
$(OBJDIR)/time_integration_mod.o $(OBJDIR)/basic_mod.o $(OBJDIR)/parallel_mod.o
$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/solve_EM_fields.F90 -o $@
- $(OBJDIR)/stepon.o : src/stepon.F90 $(OBJDIR)/initial_par_mod.o $(OBJDIR)/prec_const_mod.o \
- $(OBJDIR)/advance_field.o $(OBJDIR)/basic_mod.o $(OBJDIR)/nonlinear_mod.o $(OBJDIR)/grid_mod.o \
- $(OBJDIR)/array_mod.o $(OBJDIR)/numerics_mod.o $(OBJDIR)/fields_mod.o $(OBJDIR)/ghosts_mod.o \
- $(OBJDIR)/moments_eq_rhs_mod.o $(OBJDIR)/solve_EM_fields.o $(OBJDIR)/time_integration_mod.o \
- $(OBJDIR)/utility_mod.o $(OBJDIR)/model_mod.o
+ $(OBJDIR)/stepon.o : src/stepon.F90 \
+ $(OBJDIR)/initial_par_mod.o $(OBJDIR)/prec_const_mod.o $(OBJDIR)/advance_field.o \
+ $(OBJDIR)/basic_mod.o $(OBJDIR)/nonlinear_mod.o $(OBJDIR)/grid_mod.o \
+ $(OBJDIR)/array_mod.o $(OBJDIR)/numerics_mod.o $(OBJDIR)/fields_mod.o \
+ $(OBJDIR)/ghosts_mod.o $(OBJDIR)/moments_eq_rhs_mod.o $(OBJDIR)/solve_EM_fields.o\
+ $(OBJDIR)/utility_mod.o $(OBJDIR)/model_mod.o $(OBJDIR)/time_integration_mod.o
$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/stepon.F90 -o $@
- $(OBJDIR)/tesend.o : src/tesend.F90 $(OBJDIR)/basic_mod.o $(OBJDIR)/prec_const_mod.o
+ $(OBJDIR)/tesend.o : src/tesend.F90 \
+ $(OBJDIR)/basic_mod.o $(OBJDIR)/prec_const_mod.o
$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/tesend.F90 -o $@
- $(OBJDIR)/time_integration_mod.o : src/time_integration_mod.F90 $(OBJDIR)/basic_mod.o \
- $(OBJDIR)/prec_const_mod.o
+ $(OBJDIR)/time_integration_mod.o : src/time_integration_mod.F90 \
+ $(OBJDIR)/basic_mod.o $(OBJDIR)/prec_const_mod.o
$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/time_integration_mod.F90 -o $@
- $(OBJDIR)/utility_mod.o : src/utility_mod.F90 $(OBJDIR)/basic_mod.o $(OBJDIR)/prec_const_mod.o \
- $(OBJDIR)/grid_mod.o
+ $(OBJDIR)/utility_mod.o : src/utility_mod.F90 \
+ $(OBJDIR)/grid_mod.o $(OBJDIR)/basic_mod.o $(OBJDIR)/prec_const_mod.o
$(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/utility_mod.F90 -o $@
diff --git a/README.md b/README.md
index e88d563..55f0f19 100644
--- a/README.md
+++ b/README.md
@@ -1,105 +1,106 @@
GYACOMO (Gyrokinetic Advanced Collision Moment solver, 2021)
Copyright (C) 2022 A.C.D. Hoffmann
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
# How to compile and run GYACOMO
To compile it check INSTALLATION.txt
How to run it
1. Be sure to have correct library paths in local/dirs.inc for the different libraries
2. Compile from /gyacomo using make, the binary will be located in /gyacomo/bin
4. You can run a typical CBC to test the compilation using the basic fort.90 parameter file,
just type ./bin/gyacomo
5. It is possible to run it in parallel (MPI) as mpirun -np N ./bin/gyacomo Np Ny Nz
- where N=Np x Ny x Nz is the number of processes and Np Ny Nz are the parallel dimensions in
- Hermite polynomials, binormal direction and parallel direction, respectively
+ where N=Np x Ny x Nz is the number of processes and Np Ny Nz are the parallel dimensions in Hermite polynomials, binormal direction and parallel direction, respectively
6. You can stop your simulation without breaking output file by creating a blank file call "mystop"
in the directory where the simulation is running. (the file will be removed once read)
7. You can obtain various plots and gifs using gyacomo/wk/header_3D_results.m once the simulation is done.
-// Comment : For some collision operators (Sugama and Full Coulomb) you have to run COSOlver from B.J.Frei first in order to generate the required matrices in gyacomo/iCa folder.
+// Comment : For some collision operators (Sugama and Full Coulomb) you have to run COSOlver from B.J.Frei first in order to generate the required matrices in gyacomo/iCa folder. //
# Changelog
4. GYACOMO
+ 4.1 Miller geometry is added and benchmarked for CBC adiabatic electrons
+
4.0 new naming and opening the code with GNU GPLv3 license
3. HeLaZ 3D
3.9 HeLaZ can now evolve electromagnetic fluctuations by solving Ampere equations (benchmarked linearly)
3.8 HeLaZ has been benchmarked for CBC with GENE for various gradients values (see Dimits_fig3.m)
3.7 The frequency plane has been transposed from positive kx to positive ky for easier implementation of shear. Also added 3D zpinch geometry
3.6 HeLaZ is now parallelized in p, kx and z and benchmarked for each parallel options with gbms (new molix) for linear fluxtube shearless.
3.5 Staggered grid for parallel odd/even coupling
3.4 HeLaZ can run with adiabatic electrons now!
3.3 HeLaZ 3D has been benchmarked in fluxtube salphaB geometry linear run with molix (B.J.Frei) code and works now for shear = 0 with periodic z BC
3.2 Stopping file procedure like in GBS is added
3.1 Implementation of mirror force
3.0 HeLaZ is now 3D and works like HeLaZ 2D if Nz = 1, the axis were renamed (r,z) -> (x,y,z) and now the parallel direction is ez. All arrays have been extended, diagnostics and analysis too. The linear coefficients are now precomputed with lin_coeff_and_geometry routines.
2. MPI parallel version
2.7 Versatile interpolation of kperp for the cosolver matrices and corrections done on DGGK
2.6 Change of collisionality normalisation (from nu_ei to nu_ii), implementation of FCGK
2.5 GK cosolver collision implementation
2.4 2D cartesian parallel (along p and kr)
2.3 GK Dougherty operator
2.2 Allow restart with different P,J values (results are not concluents)
2.1 First compilable parallel version (1D parallel along kr)
1. Implementation of the non linear Poisson brackets term
1.4 Quantitative study with stationary average particle flux \Gamma_\infty
1.3 Linear analysis showed that a certain amount of PJ are recquired to trigger mode
1.2 Zonal flows are observed in a similar way to Ricci Rogers 2006 with GS2
1.1 Qualitative test : find similar turbulences as Hasegawa Wakatani system with few moments
1.1 Methods in fourier_mod.f90 have been validated by tests on Hasegawa Wakatani system
1.1 Methods in fourier_mod.f90 have been validated by tests on Hasegawa Wakatani system
1.0 FFTW3 has been used to treat the convolution as a product and discrete fourier transform
0. Write MOLI matlab solver in Fortran using Monli1D as starting point
0.6 Benchmarks now include Dougherty, Lenard-Bernstein and Full Coulomb collision operators
0.5 Load COSOlver matrices
0.4 Benchmark with MOLI matlab results for Z-pinch (cf. kz_linear script)
0.3 RK4 time solver
0.2 implement moment hierarchy linear terms
0.1 implement linear Poisson equation in fourier space
0.0 go from 1D space to 2D fourier and from Hermite basis to Hermite-Laguerre basis
diff --git a/matlab/compute/compute_fluxtube_growth_rate.m b/matlab/compute/compute_fluxtube_growth_rate.m
index d0beda9..bb7cea9 100644
--- a/matlab/compute/compute_fluxtube_growth_rate.m
+++ b/matlab/compute/compute_fluxtube_growth_rate.m
@@ -1,95 +1,104 @@
-function [ linear_gr ] = compute_fluxtube_growth_rate(DATA, TRANGE, PLOT)
+function [ linear_gr ] = compute_fluxtube_growth_rate(DATA, OPTIONS)
% Remove AA part
if DATA.Nx > 1
ikxnz = abs(DATA.PHI(1,:,1,1)) > 0;
else
ikxnz = abs(DATA.PHI(1,:,1,1)) > -1;
end
ikynz = (abs(DATA.PHI(:,1,1,1)) > 0);
ikynz = logical(ikynz .* (DATA.ky > 0));
phi = DATA.PHI(ikynz,ikxnz,:,:);
t = DATA.Ts3D;
-[~,its] = min(abs(t-TRANGE(1)));
-[~,ite] = min(abs(t-TRANGE(end)));
+[~,its] = min(abs(t-OPTIONS.TRANGE(1)));
+[~,ite] = min(abs(t-OPTIONS.TRANGE(end)));
w_ky = zeros(sum(ikynz),ite-its);
ce = zeros(sum(ikynz),ite-its);
is = 1;
for it = its+1:ite
phi_n = phi(:,:,:,it);
phi_nm1 = phi(:,:,:,it-1);
dt = t(it)-t(it-1);
ZS = sum(sum(phi_nm1,2),3);
wl = log(phi_n./phi_nm1)/dt;
w_ky(:,is) = squeeze(sum(sum(wl.*phi_nm1,2),3)./ZS);
for iky = 1:numel(w_ky(:,is))
ce(iky,is) = abs(sum(sum(abs(w_ky(iky,is)-wl(iky,:,:)).^2.*phi_nm1(iky,:,:),2),3)./ZS(iky,:,:));
end
is = is + 1;
end
[kys, Is] = sort(DATA.ky(ikynz));
-linear_gr.trange = t(its:ite);
+linear_gr.OPTIONS.TRANGE = t(its:ite);
linear_gr.g_ky = real(w_ky(Is,:));
linear_gr.w_ky = imag(w_ky(Is,:));
linear_gr.ce = abs(ce);
linear_gr.ky = kys;
linear_gr.std_g = std (real(w_ky(Is,:)),[],2);
linear_gr.avg_g = mean(real(w_ky(Is,:)),2);
linear_gr.std_w = std (imag(w_ky(Is,:)),[],2);
linear_gr.avg_w = mean(imag(w_ky(Is,:)),2);
-if PLOT >0
+if OPTIONS.NPLOTS >0
figure
-if PLOT > 1
+if OPTIONS.NPLOTS > 1
subplot(1,2,1)
end
+ x_ = linear_gr.ky;
+ plt = @(x) x;
+ OVERK = '';
+ if OPTIONS.GOK == 1
+ plt = @(x) x./x_;
+ OVERK = '/$k_y$';
+ elseif OPTIONS.GOK == 2
+ plt = @(x) x.^2./x_.^3;
+ OVERK = '/$k_y$';
+ end
+ plot(x_,plt(linear_gr.g_ky(:,end)),'-o','DisplayName',['$Re(\omega_{k_y})$',OVERK]); hold on;
+ plot(x_,plt(linear_gr.w_ky(:,end)),'--*','DisplayName',['$Im(\omega_{k_y})$',OVERK]); hold on;
+ plot(x_,plt(linear_gr.ce (:,end)),'x','DisplayName',['$\epsilon$',OVERK]); hold on;
- plot(linear_gr.ky,linear_gr.g_ky(:,end),'-o','DisplayName','$Re(\omega_{k_y})$'); hold on;
- plot(linear_gr.ky,linear_gr.w_ky(:,end),'--*','DisplayName','$Im(\omega_{k_y})$'); hold on;
- plot(linear_gr.ky,linear_gr.ce (:,end),'x','DisplayName','$\epsilon$'); hold on;
-
- errorbar(linear_gr.ky,linear_gr.avg_g,linear_gr.std_g,...
+ errorbar(linear_gr.ky,plt(linear_gr.avg_g),plt(linear_gr.std_g),...
'-o','DisplayName','$Re(\omega_{k_y})$',...
'LineWidth',1.5); hold on;
- errorbar(linear_gr.ky,linear_gr.avg_w,linear_gr.std_w,...
+ errorbar(linear_gr.ky,plt(linear_gr.avg_w),plt(linear_gr.std_w),...
'--*','DisplayName','$Im(\omega_{k_y})$',...
'LineWidth',1.5); hold on;
% xlim([min(linear_gr.ky) max(linear_gr.ky)]);
xlabel('$k_y$');
legend('show');
title(DATA.param_title);
-if PLOT > 1
- if PLOT == 2
+if OPTIONS.NPLOTS > 1
+ if OPTIONS.NPLOTS == 2
subplot(1,2,2)
- elseif PLOT == 3
+ elseif OPTIONS.NPLOTS == 3
subplot(2,2,2)
end
plot(DATA.Ts3D(its+1:ite),linear_gr.g_ky(Is,:)); hold on;
plot(DATA.Ts3D(its+1:ite),linear_gr.w_ky(Is,:));
xlabel('t'); ylabel('$\gamma(t),\omega(t)$'); xlim([DATA.Ts3D(1) DATA.Ts3D(end)]);
end
-if PLOT > 2
+if OPTIONS.NPLOTS > 2
xlabel([]); xticks([]);
subplot(2,2,4)
[~,ikx0] = min(abs(DATA.kx));
for i_ = 1:(DATA.Nkx+1)/2
iky = 1 + (DATA.ky(1) == 0);
ikx = ikx0 + (i_-1);
semilogy(DATA.Ts3D,squeeze(abs(DATA.PHI(iky,ikx,DATA.Nz/2,:))),...
'DisplayName',['$k_x=',num2str(DATA.kx(ikx)),'$, $k_y=',num2str(DATA.ky(iky)),'$']);
hold on;
xlabel('t,'); ylabel('$|\phi_{ky}|(t)$')
end
legend('show')
end
end
\ No newline at end of file
diff --git a/matlab/evolve_tracers.m b/matlab/evolve_tracers.m
index a6a738c..4725ede 100644
--- a/matlab/evolve_tracers.m
+++ b/matlab/evolve_tracers.m
@@ -1,338 +1,342 @@
% Options
SHOW_FILM = 1;
field2plot ='phi';
INIT = 'lin'; % lin (for a line)/ round (for a small round)/ gauss for random
-U_TIME = 40; % >0 for frozen velocity at a given time, -1 for evolving field
+U_TIME = 1000; % >0 for frozen velocity at a given time, -1 for evolving field
Evolve_U = 1; % 0 for frozen velocity at a given time, 1 for evolving field
-Tfin = 100;
-dt_ = 0.01;
+Tfin = 500;
+dt_ = 0.1;
Nstep = ceil(Tfin/dt_);
% Init tracers
-Np = 20; %number of tracers
+Np = 200; %number of tracers
% color = tcolors;
color = jet(Np);
tcolors = distinguishable_colors(Np); %Their colors
dimmed = 0; % to dimm the colormap in the background (infty = white, 0 normal color)
Na = 10/dt_; %length of trace
Traj_x = zeros(Np,Nstep);
Traj_y = zeros(Np,Nstep);
Disp_x = zeros(Np,Nstep);
Disp_y = zeros(Np,Nstep);
xmax = max(data.x); xmin = min(data.x);
ymax = max(data.y); ymin = min(data.y);
switch INIT
case 'lin'
% Evenly distributed initial positions
dp_ = (xmax-xmin)/(Np-1);
Xp = linspace(xmin+dp_/2,xmax-dp_/2,Np);
Yp = zeros(1,Np);
Zp = zeros(Np);
case 'round'
% All particles arround a same point
xc = 0; yc = 0;
theta = rand(1,Np)*2*pi; r = 0.1;
Xp = xc + r*cos(theta);
Yp = yc + r*sin(theta);
Zp = zeros(Np);
case 'gauss'
% normal distribution arround a point
xc = 0; yc = 0; sgm = 1.0;
dx = normrnd(0,sgm,[1,Np]); dx = dx - mean(dx);
Xp = xc + dx;
dy = normrnd(0,sgm,[1,Np]); dy = dy - mean(dy);
Yp = yc + dy;
Zp = zeros(Np);
end
% position grid and velocity field
[YY_, XX_ ,ZZ_] = meshgrid(data.y,data.x,data.z);
[KX,KY] = meshgrid(data.kx,data.ky);
Ux = zeros(size(XX_));
Uy = zeros(size(XX_));
Uz = zeros(size(XX_));
ni = zeros(size(XX_));
[~,itu_] = min(abs(U_TIME-data.Ts3D));
% computing the frozen velocity field
for iz = 1:data.Nz
% Ux(:,:,iz) = real(ifft2( 1i*KY.*(data.PHI(:,:,iz,itu_)),data.Nx,data.Ny));
% Uy(:,:,iz) = real(ifft2(-1i*KX.*(data.PHI(:,:,iz,itu_)),data.Nx,data.Ny));
% ni(:,:,iz) = real(ifft2(data.DENS_I(:,:,iz,itu_),data.Nx,data.Ny));
Ux(:,:,iz) = ifourier_GENE( 1i*KY.*(data.PHI(:,:,iz,itu_)))';
Uy(:,:,iz) = ifourier_GENE(-1i*KX.*(data.PHI(:,:,iz,itu_)))';
ni(:,:,iz) = ifourier_GENE(data.DENS_I(:,:,iz,itu_))';
end
%% FILM options
FPS = 30; DELAY = 1/FPS;
FORMAT = '.gif';
if SHOW_FILM
FILENAME = [data.localdir,'tracer_evolution',FORMAT];
switch FORMAT
case '.avi'
vidfile = VideoWriter(FILENAME,'Uncompressed AVI');
vidfile.FrameRate = FPS;
open(vidfile);
end
fig = figure;
end
%
%Time loop
t_ = 0;
it = 1;
itu_old = 0;
nbytes = fprintf(2,'frame %d/%d',it,Nstep);
while(t_ data.x(ixC) % right from grid point
ix0 = ixC;
ix1 = ixC+1;
else % left
ix0 = ixC-1;
ix1 = ixC;
end
y_ = Yp(ip);
[e_y,iyC] = min(abs(y_-data.y));
if e_y == 0 % on the face
iy0 = iyC;
iy1 = iyC;
elseif y_ > data.y(iyC) % above
iy0 = iyC;
iy1 = iyC+1;
else % under
iy0 = iyC-1;
iy1 = iyC;
end
z_ = Zp(ip,1);
[e_z,izC] = min(abs(z_-data.z));
if e_z == 0 % on the face
iz0 = izC;
iz1 = izC;
elseif z_ > data.z(izC) % before
iz0 = izC;
iz1 = izC+1;
else % behind
iz0 = izC-1;
iz1 = izC;
end
x0 = data.x(ix0); x1 = data.x(ix1); %left right
y0 = data.y(iy0); y1 = data.y(iy1); %down top
z0 = data.z(iz0); z1 = data.z(iz1); %back front
if(e_x > 0)
ai__ = (x_ - x0)/(x1-x0); % interp coeff x
else
ai__ = 0;
end
if(e_y > 0)
a_i_ = (y_ - y0)/(y0-y1); % interp coeff y
else
a_i_ = 0;
end
if(e_z > 0)
a__i = (z_ - z0)/(z1-z0); % interp coeff z
else
a__i = 0;
end
% interp velocity and density
%velocity values
u000 = [Ux(ix0,iy0,iz0) Uy(ix0,iy0,iz0) ni(ix0,iy0,iz0)];
u001 = [Ux(ix0,iy0,iz1) Uy(ix0,iy0,iz1) ni(ix0,iy0,iz1)];
u010 = [Ux(ix0,iy1,iz0) Uy(ix0,iy1,iz0) ni(ix0,iy1,iz0)];
u011 = [Ux(ix0,iy1,iz1) Uy(ix0,iy1,iz1) ni(ix0,iy1,iz1)];
u100 = [Ux(ix1,iy0,iz0) Uy(ix1,iy0,iz0) ni(ix1,iy0,iz0)];
u101 = [Ux(ix1,iy0,iz1) Uy(ix1,iy0,iz1) ni(ix1,iy0,iz1)];
u110 = [Ux(ix1,iy1,iz0) Uy(ix1,iy1,iz0) ni(ix1,iy1,iz0)];
u111 = [Ux(ix1,iy1,iz1) Uy(ix1,iy1,iz1) ni(ix1,iy1,iz1)];
%linear interpolation
linterp = @(x1,x2,a) (1-a)*x1 + a*x2;
u_00 = linterp(u000,u100,ai__);
u_10 = linterp(u010,u110,ai__);
u__0 = linterp(u_00,u_10,a_i_);
u_01 = linterp(u001,u101,ai__);
u_11 = linterp(u011,u111,ai__);
u__1 = linterp(u_01,u_11,a_i_);
u___ = linterp(u__0,u__1,a__i);
% push the particle
-% q = sign(-u___(3));
- q = -u___(3);
+ q = sign(-u___(3));
% q =1;
x_ = x_ + dt_*u___(1)*q;
y_ = y_ + dt_*u___(2)*q;
% apply periodic boundary conditions
if(x_ > xmax)
x_ = xmin + (x_ - xmax);
elseif(x_ < xmin)
x_ = xmax + (x_ - xmin);
end
if(y_ > ymax)
y_ = ymin + (y_ - ymax);
elseif(y_ < ymin)
y_ = ymax + (y_ - ymin);
end
% store data
% Trajectory
Traj_x(ip,it) = x_;
Traj_y(ip,it) = y_;
% Displacement
Disp_x(ip,it) = Disp_x(ip,it) + dt_*u___(1)*q;
Disp_y(ip,it) = Disp_y(ip,it) + dt_*u___(2)*q;
% update position
Xp(ip) = x_; Yp(ip) = y_;
end
%% Movie
if SHOW_FILM && (~Evolve_U || (itu_old ~= itu_))
% updating the velocity field
clf(fig);
switch field2plot
case 'phi'
F2P = ifourier_GENE(data.PHI(:,:,iz,itu_))';
case 'ni'
F2P = ifourier_GENE(data.DENS_I(:,:,iz,itu_))';
case 'Ni00'
F2P = ifourier_GENE(data.Ni00(:,:,iz,itu_))';
case 'none'
F2P = 0*XX_;
end
scale = max(max(abs(F2P))); % Scaling to normalize
pclr = pcolor(XX_,YY_,F2P/scale);
- caxis([-1 1]); colormap(bluewhitered); colorbar;
+ caxis([-1 1]); colormap(bluewhitered); %colorbar;
set(pclr, 'edgecolor','none'); hold on; caxis([-1+dimmed,1+dimmed]); shading interp
for ip = 1:Np
ia0 = max(1,it-Na);
plot(Traj_x(ip,ia0:it),Traj_y(ip,ia0:it),'.','Color',color(ip,:)); hold on
end
for ip = 1:Np
- plot(Traj_x(ip, 1),Traj_y(ip, 1),'xk'); hold on
+% plot(Traj_x(ip, 1),Traj_y(ip, 1),'xk'); hold on
plot(Traj_x(ip,it),Traj_y(ip,it),'ok','MarkerFaceColor',color(ip,:)); hold on
end
title(['$t \approx$', sprintf('%.3d',ceil(data.Ts3D(itu_)))]);
axis equal
xlim([xmin xmax]); ylim([ymin ymax]);
+ xlabel('$x/\rho_s$'); ylabel('$y/\rho_s$');
drawnow
% Capture the plot as an image
frame = getframe(fig);
switch FORMAT
case '.gif'
im = frame2im(frame);
[imind,cm] = rgb2ind(im,32);
% Write to the GIF File
if it == 1
imwrite(imind,cm,FILENAME,'gif', 'Loopcount',inf);
else
imwrite(imind,cm,FILENAME,'gif','WriteMode','append', 'DelayTime',DELAY);
end
case '.avi'
writeVideo(vidfile,frame);
otherwise
disp('Unknown format');
break
end
end
t_ = t_ + dt_; it = it + 1; itu_old = itu_;
% terminal info
while nbytes > 0
fprintf('\b')
nbytes = nbytes - 1;
end
nbytes = fprintf(2,'frame %d/%d',it,Nstep);
end
disp(' ')
switch FORMAT
case '.gif'
disp(['Gif saved @ : ',FILENAME])
case '.avi'
disp(['Video saved @ : ',FILENAME])
close(vidfile);
end
Nt = it;
%% Plot trajectories and statistics
xtot = Disp_x;
ytot = Disp_y;
% aggregate the displacements
for iq = 1:Np
x_ = 0; y_ = 0;
for iu = 1:Nt-1
x_ = x_ + Disp_x(iq,iu);
y_ = y_ + Disp_y(iq,iu);
xtot(iq,iu) = x_;
ytot(iq,iu) = y_;
end
end
ma = @(x) x;%movmean(x,100);
time_ = linspace(U_TIME,U_TIME+Tfin,it-1);
figure;
subplot(221);
for ip = 1:Np
% plot(ma(time_),ma(Traj_x(ip,:)),'-','Color',tcolors(ip,:)); hold on
plot(ma(time_),xtot(ip,:),'-','Color',tcolors(ip,:)); hold on
% plot(ma(time_),ma(Disp_x(ip,:)),'-','Color',tcolors(ip,:)); hold on
end
ylabel('$x_p$');
xlim(U_TIME + [0 Tfin]);
subplot(222);
itf = floor(Nt/2); %fit end time
% x^2 displacement
- plot(time_,mean(xtot.^2,1),'DisplayName','$\langle x.^2\rangle_p$'); hold on
+ x2tot = mean(xtot.^2,1);
+ plot(time_-time_(1),x2tot,'DisplayName','$\langle x.^2\rangle_p$'); hold on
fit = polyfit(time_(1:itf),mean(xtot(:,1:itf).^2,1),1);
- plot(time_,fit(1)*time_+fit(2),'--k'); hold on
- ylabel('$\langle x^2 \rangle_p$');
+ plot(time_-time_(1),fit(1)*time_+fit(2),'--k'); hold on
+ % Put a linear growth from the first point to check if it super/sub
+ % diffusive
+% loglog(time_-time_(1),(time_-time_(1))*x2tot(2)/(time_(2)-time_(1)),'--k'); hold on
+% ylabel('$\langle x^2 \rangle_p$');
% % y^2 displacement
% fit = polyfit(time_(1:itf),mean(ytot(:,1:itf).^2,1),1);
% plot(time_,fit(1)*time_+fit(2),'--k','DisplayName',['$\alpha=',num2str(fit(1)),'$']); hold on
% plot(time_,mean(ytot.^2,1),'DisplayName','$\langle y.^2\rangle_p$');
%
% % r^2 displacement
% fit = polyfit(time_(1:itf),mean(xtot(:,1:itf).^2+ytot(:,1:itf).^2,1),1);
% plot(time_,fit(1)*time_+fit(2),'--k','DisplayName',['$\alpha=',num2str(fit(1)),'$']); hold on
% plot(time_,mean(xtot.^2+ytot.^2,1),'DisplayName','$\langle r.^2\rangle_p$');
% ylabel('$\langle x^2 \rangle_p$');
% xlim(U_TIME + [0 Tfin]);
subplot(223);
for ip = 1:Np
% plot(ma(time_),ma(Traj_y(ip,:)),'-','Color',tcolors(ip,:)); hold on
plot(ma(time_),ytot(ip,:),'-','Color',tcolors(ip,:)); hold on
% plot(ma(time_),ma(Disp_y(ip,:)),'-','Color',tcolors(ip,:)); hold on
end
xlabel('time');
ylabel('$y_p$');
xlim(U_TIME + [0 Tfin]);
subplot(224);
histogram(xtot(:,1),20); hold on
histogram(xtot(:,end),20)
xlabel('position');
ylabel('$n$');
diff --git a/matlab/extract_fig_data.m b/matlab/extract_fig_data.m
index b9d69af..a036d18 100644
--- a/matlab/extract_fig_data.m
+++ b/matlab/extract_fig_data.m
@@ -1,53 +1,53 @@
% tw = [500 1000];
% tw = [1000 1500];
% tw = [2000 3000];
% tw = [3000 4000];
% tw = [4000 4500];
% tw = [4500 5000];
-tw = [500 1000];
+tw = [00 5000];
fig = gcf;
axObjs = fig.Children;
dataObjs = axObjs.Children;
X_ = [];
Y_ = [];
for i = 1:numel(dataObjs)
X_ = [X_ dataObjs(i).XData];
Y_ = [Y_ dataObjs(i).YData];
end
% n0 = 1;
% n1 = numel(X_);
[~,n0] = min(abs(X_-tw(1)));
[~,n1] = min(abs(X_-tw(2)));
-mvm = @(x) movmean(x,50);
-shift = X_(n0);
+mvm = @(x) movmean(x,1);
+shift = 0;%X_(n0);
% shift = 0;
+skip = 50;
figure;
-plot(X_(n0:end),Y_(n0:end));
-plot(mvm(X_(n0:n1)-shift),mvm(Y_(n0:n1))); hold on;
+plot(mvm(X_(n0:skip:n1)-shift),mvm(Y_(n0:skip:n1))); hold on;
% t0 = ceil(numel(X_)*0.2); t1 = numel(X_);
avg= mean(Y_(n0:n1)); dev = std(Y_(n0:n1));
disp(['AVG =',sprintf('%4.4f',avg),'+-',sprintf('%4.4f',dev)]);
%
% n1 = n0+1; n2 = min(n1 + 50000,numel(Y_));
% avg_ = mean(Y_(n1:n2));
% std_ = std(Y_(n1:n2));
% title(['avg = ',num2str(avg_),' std = ', num2str(std_)])
% plot([X_(n1),X_(n2)],[1 1]*avg_,'--k')
% ylim([0,avg_*3]);
% sum(Y_(2:end)./X_(2:end).^(3/2))
%%
if 0
%%
m1 = mean(y1); m2 = mean(y2);
s1 = std(y1); s2 = std(y2);
delta = abs(m2-m1)/min(s1,s2);
delta
end
% xlim([-3,3]); ylim([0,4.5]);
\ No newline at end of file
diff --git a/matlab/load/load_3D_data.m b/matlab/load/load_3D_data.m
index 0a4fee1..37b5454 100644
--- a/matlab/load/load_3D_data.m
+++ b/matlab/load/load_3D_data.m
@@ -1,17 +1,32 @@
function [ data, time, dt ] = load_3D_data( filename, variablename )
%LOAD_2D_DATA load a 2D variable stored in a hdf5 result file from HeLaZ
time = h5read(filename,'/data/var3d/time');
kx = h5read(filename,'/data/grid/coordkx');
ky = h5read(filename,'/data/grid/coordky');
z = h5read(filename,'/data/grid/coordz');
dt = h5readatt(filename,'/data/input','dt');
cstart= h5readatt(filename,'/data/input','start_iframe3d');
data = zeros(numel(ky),numel(kx),numel(z),numel(time));
- for it = 1:numel(time)
- tmp = h5read(filename,['/data/var3d/',variablename,'/', num2str(cstart+it,'%06d')]);
- data(:,:,:,it) = tmp.real + 1i * tmp.imaginary;
+ [KX,KY] = meshgrid(kx,ky);
+
+ switch variablename
+ case 'vEx'
+ for it = 1:numel(time)
+ tmp = h5read(filename,['/data/var3d/phi/', num2str(cstart+it,'%06d')]);
+ data(:,:,:,it) = 1i.*KY.*(tmp.real + 1i * tmp.imaginary);
+ end
+ case 'vEy'
+ for it = 1:numel(time)
+ tmp = h5read(filename,['/data/var3d/phi/', num2str(cstart+it,'%06d')]);
+ data(:,:,:,it) = -1i.*KX.*(tmp.real + 1i * tmp.imaginary);
+ end
+ otherwise
+ for it = 1:numel(time)
+ tmp = h5read(filename,['/data/var3d/',variablename,'/', num2str(cstart+it,'%06d')]);
+ data(:,:,:,it) = tmp.real + 1i * tmp.imaginary;
+ end
end
end
diff --git a/matlab/plot/plot_cosol_mat.m b/matlab/plot/plot_cosol_mat.m
index f10777e..686686f 100644
--- a/matlab/plot/plot_cosol_mat.m
+++ b/matlab/plot/plot_cosol_mat.m
@@ -1,180 +1,181 @@
% MAT = results.iCa;
% figure
% suptitle('FCGK,P=6,J=3');
% subplot(221)
% imagesc(log(abs(MAT)));
% title('log abs')
% subplot(222)
% imagesc(imag(MAT)); colormap(bluewhitered)
% title('imag'); colorbar
% subplot(223)
% imagesc(imag(MAT)>0);
% title('imag$>$0');
% subplot(224)
% imagesc(imag(MAT)<0);
% title('imag$<$0');
%
%
%% SGGK
P_ = 20; J_ = 10;
mat_file_name = '/home/ahoffman/HeLaZ/iCa/gk_sugama_P_20_J_10_N_150_kpm_8.0.h5';
SGGK_self = h5read(mat_file_name,'/00000/Caapj/Ciipj');
SGGK_ei = h5read(mat_file_name,'/00000/Ceipj/CeipjF')+h5read(mat_file_name,'/00000/Ceipj/CeipjT');
SGGK_ie = h5read(mat_file_name,'/00000/Ciepj/CiepjF')+h5read(mat_file_name,'/00000/Ciepj/CiepjT');
figure
MAT = 1i*SGGK_self; suptitle('SGGK ii,P=20,J=10, k=0');
% MAT = 1i*SGGK_ei; suptitle('SGGK ei,P=20,J=10');
% MAT = 1i*SGGK_ie; suptitle('SGGK ie,P=20,J=10');
subplot(221)
imagesc(abs(MAT));
title('log abs')
subplot(222)
imagesc(imag(MAT)); colormap(bluewhitered)
title('imag'); colorbar
subplot(223)
imagesc(imag(MAT)>0);
title('imag$>$0');
subplot(224)
imagesc(imag(MAT)<0);
title('imag$<$0');
%% PAGK
P_ = 20; J_ = 10;
mat_file_name = '/home/ahoffman/HeLaZ/iCa/gk_pitchangle_8_P_20_J_10_N_150_kpm_8.0.h5';
PAGK_self = h5read(mat_file_name,'/00000/Caapj/Ceepj');
% PAGK_ei = h5read(mat_file_name,'/00000/Ceipj/CeipjF')+h5read(mat_file_name,'/00000/Ceipj/CeipjT');
% PAGK_ie = h5read(mat_file_name,'/00000/Ciepj/CiepjF')+h5read(mat_file_name,'/00000/Ciepj/CiepjT');
figure
MAT = 1i*PAGK_self; suptitle('PAGK ii,P=20,J=10, k=0');
subplot(221)
imagesc(abs(MAT));
title('log abs')
subplot(222)
imagesc(imag(MAT)); colormap(bluewhitered)
title('imag'); colorbar
subplot(223)
imagesc(imag(MAT)>0);
title('imag$>$0');
subplot(224)
imagesc(imag(MAT)<0);
title('imag$<$0');
%% FCGK
P_ = 4; J_ = 2;
-% mat_file_name = '/home/ahoffman/cosolver/gk.coulomb_NFLR_12_P_4_J_2_N_50_kpm_4.0.h5';
mat_file_name = '/home/ahoffman/gyacomo/iCa/gk_coulomb_NFLR_12_P_4_J_2_N_50_kpm_4.0.h5';
+% mat_file_name = '/home/ahoffman/gyacomo/iCa/LDGK_P6_J3_dk_5e-2_km_2.5_NFLR_20.h5';
% mat_file_name = '/home/ahoffman/gyacomo/iCa/LDGK_P10_J5_dk_5e-2_km_5_NFLR_12.h5';
-kp = 2.0;
+kp = 0.0;
kp_a = h5read(mat_file_name,'/coordkperp');
[~,matidx] = min(abs(kp_a-kp));
matidx = sprintf('%5.5i',matidx);
FCGK_self = h5read(mat_file_name,['/',matidx,'/Caapj/Ciipj']);
FCGK_ei = h5read(mat_file_name,['/',matidx,'/Ceipj/CeipjF'])+h5read(mat_file_name,'/00000/Ceipj/CeipjT');
FCGK_ie = h5read(mat_file_name,['/',matidx,'/Ciepj/CiepjF'])+h5read(mat_file_name,'/00000/Ciepj/CiepjT');
figure
MAT = 1i*FCGK_self; suptitle(['FCGK ii,P=6,J=3, k=',num2str(kp),' (',matidx,')']);
% MAT = 1i*FCGK_ei; suptitle('FCGK ei,P=20,J=10');
% MAT = 1i*FCGK_ie; suptitle('FCGK ie,P=20,J=10');
subplot(221)
imagesc(abs(MAT));
title('log abs')
subplot(222)
imagesc(imag(MAT)); colormap(bluewhitered)
title('imag'); colorbar
subplot(223)
imagesc(imag(MAT)>0);
title('imag$>$0');
subplot(224)
imagesc(imag(MAT)<0);
title('imag$<$0');
%% Eigenvalue spectrum analysis
if 0
%%
mfns = {...
'/home/ahoffman/gyacomo/iCa/gk_sugama_P_20_J_10_N_150_kpm_8.0.h5',...
% '/home/ahoffman/gyacomo/iCa/gk_pitchangle_8_P_20_J_10_N_150_kpm_8.0.h5',...
-% '/home/ahoffman/gyacomo/iCa/LDGK_P10_J5_dk_5e-2_km_5_NFLR_4.h5',...
-% '/home/ahoffman/gyacomo/iCa/LDGK_P10_J5_dk_5e-2_km_5_NFLR_12.h5',...
-% '/home/ahoffman/gyacomo/iCa/LDGK_P10_J5_dk_5e-2_km_5_NFLR_12_k2trunc.h5',...
- '/home/ahoffman/gyacomo/iCa/LDGK_P10_J5_dk_5e-2_km_5_NFLR_30.h5',...
+% '/home/ahoffman/gyacomo/iCa/LDGKii_P10_J5_dk_5e-2_km_5_NFLR_4.h5',...
+% '/home/ahoffman/gyacomo/iCa/LDGKii_P10_J5_dk_5e-2_km_5_NFLR_12.h5',...
+% '/home/ahoffman/gyacomo/iCa/LDGKii_P10_J5_dk_5e-2_km_5_NFLR_12_k2trunc.h5',...
+% '/home/ahoffman/gyacomo/iCa/LDGKii_P10_J5_dk_5e-2_km_5_NFLR_30.h5',...
+ '/home/ahoffman/gyacomo/iCa/LDGK_P6_J3_dk_5e-2_km_2.5_NFLR_20.h5',...
% '/home/ahoffman/gyacomo/iCa/gk_coulomb_NFLR_6_P_4_J_2_N_50_kpm_4.0.h5',...
'/home/ahoffman/gyacomo/iCa/gk_coulomb_NFLR_12_P_4_J_2_N_50_kpm_4.0.h5',...
% '/home/ahoffman/gyacomo/iCa/gk.hacked_sugama_P_10_J_5_N_150_kpm_8.0.h5',...
% '/home/ahoffman/gyacomo/iCa/gk.hacked_sugama_P_4_J_2_N_75_kpm_5.0.h5',...
};
CONAME_A = {...
'SG 20 10',...
% 'PA 20 10',...
% 'FC 10 5 NFLR 4',...
% 'FC 10 5 NFLR 12',...
% 'FC 10 5 NFLR 12 k<2', ...
- 'FC 10 5 NFLR 30', ...
+ 'LD 6 3 NFLR 20', ...
% 'FC 4 2 NFLR 6',...
'FC 4 2 NFLR 12', ...
% 'Hacked SG A',...
% 'Hacked SG B',...
};
figure
for j_ = 1:numel(mfns)
mat_file_name = mfns{j_}; disp(mat_file_name);
kp_a = h5read(mat_file_name,'/coordkperp');
% kp_a = kp_a(kp_a<=3);
gmax = zeros(size(kp_a));
wmax = zeros(size(kp_a));
for idx_ = 0:numel(kp_a)-1
matidx = sprintf('%5.5i',idx_);
MAT = h5read(mat_file_name,['/',matidx,'/Caapj/Ciipj']);
gmax(idx_+1) = max(abs(real(eig(MAT))));
wmax(idx_+1) = max(abs(imag(eig(MAT))));
end
subplot(121)
plot(kp_a,gmax,'DisplayName',CONAME_A{j_}); hold on;
subplot(122)
plot(kp_a,wmax,'DisplayName',CONAME_A{j_}); hold on;
end
subplot(121)
legend('show'); grid on;
ylim([0,100]);
xlabel('$k_\perp$'); ylabel('$\gamma_{max}$ from Eig(iCa)')
subplot(122)
legend('show'); grid on;
xlabel('$k_\perp$'); ylabel('$\omega_{max}$ from Eig(iCa)')
end
%% Van Kampen plot
if 0
%%
kperp= 1.5;
-mfns = {'/home/ahoffman/HeLaZ/iCa/gk_sugama_P_20_J_10_N_150_kpm_8.0.h5',...
- '/home/ahoffman/HeLaZ/iCa/gk_pitchangle_8_P_20_J_10_N_150_kpm_8.0.h5',...
- '/home/ahoffman/HeLaZ/iCa/gk_coulomb_NFLR_6_P_4_J_2_N_50_kpm_4.0.h5',...
- '/home/ahoffman/HeLaZ/iCa/gk_coulomb_NFLR_12_P_4_J_2_N_50_kpm_4.0.h5',...
- '/home/ahoffman/HeLaZ/iCa/LDGK_P10_J5_dk_5e-2_km_5_NFLR_12.h5',...
+mfns = {'/home/ahoffman/gyacomo/iCa/gk_sugama_P_20_J_10_N_150_kpm_8.0.h5',...
+ '/home/ahoffman/gyacomo/iCa/gk_pitchangle_8_P_20_J_10_N_150_kpm_8.0.h5',...
+ '/home/ahoffman/gyacomo/iCa/gk_coulomb_NFLR_6_P_4_J_2_N_50_kpm_4.0.h5',...
+ '/home/ahoffman/gyacomo/iCa/gk_coulomb_NFLR_12_P_4_J_2_N_50_kpm_4.0.h5',...
+ '/home/ahoffman/gyacomo/iCa/LDGK_P6_J3_dk_5e-2_km_2.5_NFLR_20.h5',...
};
-CONAME_A = {'SG 20 10','PA 20 10', 'FC 4 2 NFLR 6', 'FC 4 2 NFLR 12', 'FC 10 5 NFLR 12'};
+CONAME_A = {'SG 20 10','PA 20 10', 'FC 4 2 NFLR 6', 'FC 4 2 NFLR 12', 'LD 6 3 NFLR 12'};
grow = {};
puls = {};
for j_ = 1:numel(mfns)
mat_file_name = mfns{j_}; disp(mat_file_name);
kp_a = h5read(mat_file_name,'/coordkperp');
[~,idx_] = min(abs(kp_a-kperp));
matidx = sprintf('%5.5i',idx_);
MAT = h5read(mat_file_name,['/',matidx,'/Caapj/Ciipj']);
grow{j_} = real(eig(MAT));
puls{j_} = imag(eig(MAT));
end
figure
for j_ = 1:numel(mfns)
% plot(puls{j_}, grow{j_},'o','DisplayName',CONAME_A{j_}); hold on;
plot(grow{j_},'o','DisplayName',CONAME_A{j_}); hold on;
end
legend('show'); grid on; title(['$k_\perp=$',num2str(kperp)]);
xlabel('$\omega$ from Eig(iCa)'); ylabel('$\gamma$ from Eig(iCa)')
end
\ No newline at end of file
diff --git a/matlab/plot/plot_metric.m b/matlab/plot/plot_metric.m
index 7b95c93..377c80f 100644
--- a/matlab/plot/plot_metric.m
+++ b/matlab/plot/plot_metric.m
@@ -1,30 +1,41 @@
-function [ fig ] = plot_metric( data )
+function [ fig ] = plot_metric( data, options )
names = {'Jacobian','gradxB','gradyB','gradzB','gradz_coeff',...
'gxx','gxy','gyy','gyz','gzz','hatB','hatR','hatZ'};
geo_arrays = zeros(2,data.Nz,numel(names));
for i_ = 1:numel(names)
namae = names{i_};
geo_arrays(:,:,i_) = h5read(data.outfilenames{end},['/data/metric/',namae])';
end
-fig = figure;
-subplot(311)
- for i = 1:5
- plot(data.z, geo_arrays(1,:,i),'DisplayName',names{i}); hold on;
- end
- xlim([min(data.z),max(data.z)]); legend('show'); title('MoNoLiT geometry');
+NPLOT = options.SHOW_FLUXSURF + options.SHOW_METRICS;
+if NPLOT > 0
+ fig = figure;
+ if options.SHOW_METRICS
+ subplot(311)
+ for i = 1:5
+ plot(data.z, geo_arrays(1,:,i),'DisplayName',names{i}); hold on;
+ end
+ xlim([min(data.z),max(data.z)]); legend('show'); title('GYACOMO geometry');
-subplot(312)
- for i = 6:10
- plot(data.z, geo_arrays(1,:,i),'DisplayName',names{i}); hold on;
- end
- xlim([min(data.z),max(data.z)]); legend('show');
+ subplot(312)
+ for i = 6:10
+ plot(data.z, geo_arrays(1,:,i),'DisplayName',names{i}); hold on;
+ end
+ xlim([min(data.z),max(data.z)]); legend('show');
-subplot(313)
- for i = 11:13
- plot(data.z, geo_arrays(1,:,i),'DisplayName',names{i}); hold on;
+ subplot(313)
+ for i = 11:13
+ plot(data.z, geo_arrays(1,:,i),'DisplayName',names{i}); hold on;
+ end
+ xlim([min(data.z),max(data.z)]); legend('show');
end
- xlim([min(data.z),max(data.z)]); legend('show');
+ if options.SHOW_FLUXSURF
+ R = [geo_arrays(1,:,12),geo_arrays(1,1,12)];
+ Z = [geo_arrays(1,:,13),geo_arrays(1,1,13)];
+ plot(R,Z);
+ axis equal
+ end
+end
end
diff --git a/matlab/plot/statistical_transport_averaging.m b/matlab/plot/statistical_transport_averaging.m
index eb284c6..3a7cc92 100644
--- a/matlab/plot/statistical_transport_averaging.m
+++ b/matlab/plot/statistical_transport_averaging.m
@@ -1,45 +1,50 @@
function [ fig ] = statistical_transport_averaging( data, options )
scale = data.scale;
Trange = options.T;
[~,it0] = min(abs(Trange(1)-data.Ts0D));
[~,it1] = min(abs(Trange(end)-data.Ts0D));
gamma = data.PGAMMA_RI(it0:it1)*scale;
Qx = data.HFLUX_X(it0:it1)*scale;
dt_const = numel(unique(round(diff(data.Ts0D(it0:it1))*100)))==1;
% if ~dt_const
% disp('DT not const on given interval');
% else
Ntot = (it1-it0)+1;
transp_seg_avg = 1:Ntot;
transp_seg_std = 1:Ntot;
for Np = 1:Ntot % Loop on the number of segments
transp_seg_avg(Np) = mean(gamma(1:Np));
transp_seg_std(Np) = std(gamma(1:Np));
end
time_seg = (data.Ts0D(it0:it1)-data.Ts0D(it0));
-
+
+ fig = 0;
+if options.NPLOTS > 0
fig = figure;
subplot(211)
plot(time_seg,transp_seg_avg,'-'); hold on;
xlabel('Averaging time'); ylabel('$\langle\Gamma_x\rangle_{\tau}$');
legend(['$\Gamma_x^\infty=$',sprintf('%2.2e',transp_seg_avg(end))])
title(sprintf('Transport averaging from t=%2.2f',data.Ts0D(it0)));
for Np = 1:Ntot % Loop on the number of segments
transp_seg_avg(Np) = mean(Qx(1:Np));
end
subplot(212)
plot(time_seg,transp_seg_avg,'-'); hold on;
xlabel('Averaging time'); ylabel('$\langle Q_x\rangle_{\tau}$');
legend(['$Q_x^\infty=$',sprintf('%2.2e',transp_seg_avg(end))])
-
+end
+Gx_infty_avg = mean(gamma);
+Gx_infty_std = std (gamma);
+disp(['G_x=',sprintf('%2.2e',Gx_infty_avg),'+-',sprintf('%2.2e',Gx_infty_std)]);
end
diff --git a/matlab/setup.m b/matlab/setup.m
index 966b6fb..3b8be6c 100644
--- a/matlab/setup.m
+++ b/matlab/setup.m
@@ -1,186 +1,190 @@
%% _______________________________________________________________________
SIMDIR = ['../results/',SIMID,'/'];
% Grid parameters
GRID.pmaxe = PMAXE; % Electron Hermite moments
GRID.jmaxe = JMAXE; % Electron Laguerre moments
GRID.pmaxi = PMAXI; % Ion Hermite moments
GRID.jmaxi = JMAXI; % Ion Laguerre moments
GRID.Nx = NX; % x grid resolution
GRID.Lx = LX; % x length
GRID.Nexc = NEXC; % to extend Lx when s>0
GRID.Ny = NY; % y ''
GRID.Ly = LY; % y ''
GRID.Nz = NZ; % z resolution
GRID.Npol = NPOL; % z resolution
if SG; GRID.SG = '.true.'; else; GRID.SG = '.false.';end;
% Geometry
GEOM.geom = ['''',GEOMETRY,''''];
GEOM.q0 = Q0; % q factor
GEOM.shear = SHEAR; % shear
GEOM.eps = EPS; % inverse aspect ratio
+GEOM.kappa = KAPPA; % elongation
+GEOM.delta = DELTA; % triangularity
+GEOM.zeta = ZETA; % squareness
% Model parameters
MODEL.CLOS = CLOS;
MODEL.NL_CLOS = NL_CLOS;
MODEL.LINEARITY = ['''',LINEARITY,''''];
MODEL.KIN_E = KIN_E;
if KIN_E; MODEL.KIN_E = '.true.'; else; MODEL.KIN_E = '.false.';end;
MODEL.beta = BETA;
MODEL.mu_x = MU_X;
MODEL.mu_y = MU_Y;
MODEL.N_HD = N_HD;
MODEL.mu_z = MU_Z;
MODEL.mu_p = MU_P;
MODEL.mu_j = MU_J;
MODEL.nu = NU; % hyper diffusive coefficient nu for HW
% temperature ratio T_a/T_e
MODEL.tau_e = TAU;
MODEL.tau_i = TAU;
% mass ratio sqrt(m_a/m_i)
MODEL.sigma_e = SIGMA_E;
MODEL.sigma_i = 1.0;
% charge q_a/e
MODEL.q_e =-1.0;
MODEL.q_i = 1.0;
if MODEL.q_e == 0; SIMID = [SIMID,'_i']; end;
% gradients L_perp/L_x
MODEL.K_Ni = K_Ni;
MODEL.K_Ne = K_Ne;
MODEL.K_Ti = K_Ti;
MODEL.K_Te = K_Te;
MODEL.GradB = GRADB; % Magnetic gradient
MODEL.CurvB = CURVB; % Magnetic curvature
MODEL.lambdaD = LAMBDAD;
% Collision parameters
COLL.collision_model = ['''',CO,''''];
if (GKCO); COLL.gyrokin_CO = '.true.'; else; COLL.gyrokin_CO = '.false.';end;
if (ABCO); COLL.interspecies = '.true.'; else; COLL.interspecies = '.false.';end;
COLL.mat_file = '''null''';
switch CO
case 'SG'
COLL.mat_file = '''../../../iCa/gk_sugama_P_20_J_10_N_150_kpm_8.0.h5''';
% COLL.mat_file = '''../../../iCa/gk.hacked_sugama_P_10_J_5_N_150_kpm_8.0.h5''';
% COLL.mat_file = '''../../../iCa/gk.hacked_sugama_P_4_J_2_N_75_kpm_5.0.h5''';
case 'LR'
COLL.mat_file = '''../../../iCa/gk_pitchangle_8_P_20_J_10_N_150_kpm_8.0.h5''';
case 'LD'
% COLL.mat_file = '''../../../iCa/gk_coulomb_NFLR_12_P_4_J_2_N_50_kpm_4.0.h5''';
-% COLL.mat_file = '''../../../iCa/LDGK_P10_J5_dk_5e-2_km_5_NFLR_12_k2trunc.h5''';
- COLL.mat_file = '''../../../iCa/LDGK_P10_J5_dk_5e-2_km_5_NFLR_30.h5''';
+% COLL.mat_file = '''../../../iCa/LDGKii_P10_J5_dk_5e-2_km_5_NFLR_12_k2trunc.h5''';
+% COLL.mat_file = '''../../../iCa/LDGKii_P10_J5_dk_5e-2_km_5_NFLR_30.h5''';
+ COLL.mat_file = '''../../../iCa/LDGK_P6_J3_dk_5e-2_km_2.5_NFLR_20.h5''';
end
COLL.coll_kcut = COLL_KCUT;
% Time integration and intialization parameters
TIME_INTEGRATION.numerical_scheme = '''RK4''';
INITIAL.INIT_OPT = ['''',INIT_OPT,''''];
INITIAL.ACT_ON_MODES = ['''',ACT_ON_MODES,''''];
INITIAL.init_background = BCKGD0;
INITIAL.init_noiselvl = NOISE0;
INITIAL.iseed = 42;
% Naming and creating input file
CONAME = CO;
if GKCO
CONAME = [CONAME,'GK'];
else
CONAME = [CONAME,'DK'];
end
if ~ABCO
CONAME = [CONAME,'aa'];
end
if (CLOS == 0); CLOSNAME = 'Trunc.';
elseif(CLOS == 1); CLOSNAME = 'Clos. 1';
elseif(CLOS == 2); CLOSNAME = 'Clos. 2';
end
% Hermite-Laguerre degrees naming
if (PMAXE == PMAXI) && (JMAXE == JMAXI)
HLdeg_ = ['_',num2str(PMAXE+1),'x',num2str(JMAXE+1)];
else
HLdeg_ = ['_Pe_',num2str(PMAXE+1),'_Je_',num2str(JMAXE+1),...
'_Pi_',num2str(PMAXI+1),'_Ji_',num2str(JMAXI+1)];
end
% temp. dens. drives
drives_ = [];
if abs(K_Ni) > 0; drives_ = [drives_,'_kN_',num2str(K_Ni)]; end;
if abs(K_Ti) > 0; drives_ = [drives_,'_kT_',num2str(K_Ti)]; end;
% collision
coll_ = ['_nu_%1.1e_',CONAME];
coll_ = sprintf(coll_,NU);
% nonlinear
lin_ = [];
if ~LINEARITY; lin_ = '_lin'; end
adiabe_ = [];
if ~KIN_E; adiabe_ = '_adiabe'; end
% resolution and boxsize
res_ = [num2str(GRID.Nx),'x',num2str(GRID.Ny)];
if (LX ~= LY)
geo_ = ['_Lx_',num2str(LX),'_Ly_',num2str(LY)];
else
geo_ = ['_L_',num2str(LX)];
end
if (NZ > 1) %3D case
res_ = [res_,'x',num2str(NZ)];
if abs(Q0) > 0
geo_ = [geo_,'_q0_',num2str(Q0)];
end
if abs(EPS) > 0
geo_ = [geo_,'_e_',num2str(EPS)];
end
if abs(SHEAR) > 0
geo_ = [geo_,'_s_',num2str(SHEAR)];
end
end
switch GEOMETRY
case 'circular'
geo_ = [geo_,'_circ_'];
end
% put everything together in the param character chain
u_ = '_'; % underscore variable
PARAMS = [res_,HLdeg_,geo_,drives_,coll_,lin_,adiabe_];
BASIC.RESDIR = [SIMDIR,PARAMS,'/'];
BASIC.MISCDIR = ['/misc/HeLaZ_outputs/',SIMDIR(4:end),PARAMS,'/'];
BASIC.PARAMS = PARAMS;
BASIC.SIMID = SIMID;
BASIC.nrun = 1e8;
BASIC.dt = DT;
BASIC.tmax = TMAX; %time normalized to 1/omega_pe
BASIC.maxruntime = str2num(CLUSTER.TIME(1:2))*3600 ...
+ str2num(CLUSTER.TIME(4:5))*60 ...
+ str2num(CLUSTER.TIME(7:8));
% Outputs parameters
OUTPUTS.nsave_0d = floor(1.0/SPS0D/DT);
OUTPUTS.nsave_1d = -1;
OUTPUTS.nsave_2d = floor(1.0/SPS2D/DT);
OUTPUTS.nsave_3d = floor(1.0/SPS3D/DT);
OUTPUTS.nsave_5d = floor(1.0/SPS5D/DT);
if W_DOUBLE; OUTPUTS.write_doubleprecision = '.true.'; else; OUTPUTS.write_doubleprecision = '.false.';end;
if W_GAMMA; OUTPUTS.write_gamma = '.true.'; else; OUTPUTS.write_gamma = '.false.';end;
if W_HF; OUTPUTS.write_hf = '.true.'; else; OUTPUTS.write_hf = '.false.';end;
if W_PHI; OUTPUTS.write_phi = '.true.'; else; OUTPUTS.write_phi = '.false.';end;
if W_NA00; OUTPUTS.write_Na00 = '.true.'; else; OUTPUTS.write_Na00 = '.false.';end;
if W_NAPJ; OUTPUTS.write_Napj = '.true.'; else; OUTPUTS.write_Napj = '.false.';end;
if W_SAPJ; OUTPUTS.write_Sapj = '.true.'; else; OUTPUTS.write_Sapj = '.false.';end;
if W_DENS; OUTPUTS.write_dens = '.true.'; else; OUTPUTS.write_dens = '.false.';end;
if W_TEMP; OUTPUTS.write_temp = '.true.'; else; OUTPUTS.write_temp = '.false.';end;
OUTPUTS.job2load = JOB2LOAD;
%% Create directories
if ~exist(SIMDIR, 'dir')
mkdir(SIMDIR)
end
if ~exist(BASIC.RESDIR, 'dir')
mkdir(BASIC.RESDIR)
end
if ~exist(BASIC.MISCDIR, 'dir')
mkdir(BASIC.MISCDIR)
end
%% Compile and WRITE input file
INPUT = write_fort90(OUTPUTS,GRID,GEOM,MODEL,COLL,INITIAL,TIME_INTEGRATION,BASIC);
nproc = 1;
MAKE = 'cd ..; make; cd wk';
% system(MAKE);
%%
disp(['Set up ',SIMID]);
disp([res_,geo_,HLdeg_]);
if JOB2LOAD>=0
disp(['- restarting from JOBNUM = ',num2str(JOB2LOAD)]); else
disp(['- starting from T = 0']);
end
diff --git a/matlab/write_fort90.m b/matlab/write_fort90.m
index d42c780..29304ef 100644
--- a/matlab/write_fort90.m
+++ b/matlab/write_fort90.m
@@ -1,105 +1,108 @@
function [INPUT] = write_fort90(OUTPUTS,GRID,GEOM,MODEL,COLL,INITIAL,TIME_INTEGRATION,BASIC)
% Write the input script "fort.90" with desired parameters
INPUT = ['fort_',sprintf('%2.2d',OUTPUTS.job2load+1),'.90'];
fid = fopen(INPUT,'wt');
fprintf(fid,'&BASIC\n');
fprintf(fid,[' nrun = ', num2str(BASIC.nrun),'\n']);
fprintf(fid,[' dt = ', num2str(BASIC.dt),'\n']);
fprintf(fid,[' tmax = ', num2str(BASIC.tmax),'\n']);
fprintf(fid,[' maxruntime = ', num2str(BASIC.maxruntime),'\n']);
fprintf(fid,'/\n');
fprintf(fid,'&GRID\n');
fprintf(fid,[' pmaxe = ', num2str(GRID.pmaxe),'\n']);
fprintf(fid,[' jmaxe = ', num2str(GRID.jmaxe),'\n']);
fprintf(fid,[' pmaxi = ', num2str(GRID.pmaxi),'\n']);
fprintf(fid,[' jmaxi = ', num2str(GRID.jmaxi),'\n']);
fprintf(fid,[' Nx = ', num2str(GRID.Nx),'\n']);
fprintf(fid,[' Lx = ', num2str(GRID.Lx),'\n']);
fprintf(fid,[' Nexc = ', num2str(GRID.Nexc),'\n']);
fprintf(fid,[' Ny = ', num2str(GRID.Ny),'\n']);
fprintf(fid,[' Ly = ', num2str(GRID.Ly),'\n']);
fprintf(fid,[' Nz = ', num2str(GRID.Nz),'\n']);
fprintf(fid,[' Npol = ', num2str(GRID.Npol),'\n']);
fprintf(fid,[' SG = ', GRID.SG,'\n']);
fprintf(fid,'/\n');
fprintf(fid,'&GEOMETRY\n');
fprintf(fid,[' geom = ', GEOM.geom,'\n']);
fprintf(fid,[' q0 = ', num2str(GEOM.q0),'\n']);
fprintf(fid,[' shear = ', num2str(GEOM.shear),'\n']);
fprintf(fid,[' eps = ', num2str(GEOM.eps),'\n']);
+fprintf(fid,[' kappa = ', num2str(GEOM.kappa),'\n']);
+fprintf(fid,[' delta = ', num2str(GEOM.delta),'\n']);
+fprintf(fid,[' zeta = ', num2str(GEOM.zeta),'\n']);
fprintf(fid,'/\n');
fprintf(fid,'&OUTPUT_PAR\n');
fprintf(fid,[' nsave_0d = ', num2str(OUTPUTS.nsave_0d),'\n']);
fprintf(fid,[' nsave_1d = ', num2str(OUTPUTS.nsave_1d),'\n']);
fprintf(fid,[' nsave_2d = ', num2str(OUTPUTS.nsave_2d),'\n']);
fprintf(fid,[' nsave_3d = ', num2str(OUTPUTS.nsave_3d),'\n']);
fprintf(fid,[' nsave_5d = ', num2str(OUTPUTS.nsave_5d),'\n']);
fprintf(fid,[' write_doubleprecision = ', OUTPUTS.write_doubleprecision,'\n']);
fprintf(fid,[' write_gamma = ', OUTPUTS.write_gamma,'\n']);
fprintf(fid,[' write_hf = ', OUTPUTS.write_hf,'\n']);
fprintf(fid,[' write_phi = ', OUTPUTS.write_phi,'\n']);
fprintf(fid,[' write_Na00 = ', OUTPUTS.write_Na00,'\n']);
fprintf(fid,[' write_Napj = ', OUTPUTS.write_Napj,'\n']);
fprintf(fid,[' write_Sapj = ', OUTPUTS.write_Sapj,'\n']);
fprintf(fid,[' write_dens = ', OUTPUTS.write_dens,'\n']);
fprintf(fid,[' write_temp = ', OUTPUTS.write_temp,'\n']);
fprintf(fid,[' job2load = ', num2str(OUTPUTS.job2load),'\n']);
fprintf(fid,'/\n');
fprintf(fid,'&MODEL_PAR\n');
fprintf(fid,' ! Collisionality\n');
fprintf(fid,[' CLOS = ', num2str(MODEL.CLOS),'\n']);
fprintf(fid,[' NL_CLOS = ', num2str(MODEL.NL_CLOS),'\n']);
fprintf(fid,[' LINEARITY = ', MODEL.LINEARITY,'\n']);
fprintf(fid,[' KIN_E = ', MODEL.KIN_E,'\n']);
fprintf(fid,[' mu_x = ', num2str(MODEL.mu_x),'\n']);
fprintf(fid,[' mu_y = ', num2str(MODEL.mu_y),'\n']);
fprintf(fid,[' N_HD = ', num2str(MODEL.N_HD),'\n']);
fprintf(fid,[' mu_z = ', num2str(MODEL.mu_z),'\n']);
fprintf(fid,[' mu_p = ', num2str(MODEL.mu_p),'\n']);
fprintf(fid,[' mu_j = ', num2str(MODEL.mu_j),'\n']);
fprintf(fid,[' nu = ', num2str(MODEL.nu),'\n']);
fprintf(fid,[' tau_e = ', num2str(MODEL.tau_e),'\n']);
fprintf(fid,[' tau_i = ', num2str(MODEL.tau_i),'\n']);
fprintf(fid,[' sigma_e = ', num2str(MODEL.sigma_e),'\n']);
fprintf(fid,[' sigma_i = ', num2str(MODEL.sigma_i),'\n']);
fprintf(fid,[' q_e = ', num2str(MODEL.q_e),'\n']);
fprintf(fid,[' q_i = ', num2str(MODEL.q_i),'\n']);
fprintf(fid,[' K_Ne = ', num2str(MODEL.K_Ne),'\n']);
fprintf(fid,[' K_Ni = ', num2str(MODEL.K_Ni),'\n']);
fprintf(fid,[' K_Te = ', num2str(MODEL.K_Te),'\n']);
fprintf(fid,[' K_Ti = ', num2str(MODEL.K_Ti),'\n']);
fprintf(fid,[' GradB = ', num2str(MODEL.GradB),'\n']);
fprintf(fid,[' CurvB = ', num2str(MODEL.CurvB),'\n']);
fprintf(fid,[' lambdaD = ', num2str(MODEL.lambdaD),'\n']);
fprintf(fid,[' beta = ', num2str(MODEL.beta),'\n']);
fprintf(fid,'/\n');
fprintf(fid,'&COLLISION_PAR\n');
fprintf(fid,[' collision_model = ', COLL.collision_model,'\n']);
fprintf(fid,[' gyrokin_CO = ', COLL.gyrokin_CO,'\n']);
fprintf(fid,[' interspecies = ', COLL.interspecies,'\n']);
fprintf(fid,[' mat_file = ', COLL.mat_file,'\n']);
fprintf(fid,[' collision_kcut = ', num2str(COLL.coll_kcut),'\n']);
fprintf(fid,'/\n');
fprintf(fid,'&INITIAL_CON\n');
fprintf(fid,[' INIT_OPT = ', INITIAL.INIT_OPT,'\n']);
fprintf(fid,[' ACT_ON_MODES = ', INITIAL.ACT_ON_MODES,'\n']);
fprintf(fid,[' init_background = ', num2str(INITIAL.init_background),'\n']);
fprintf(fid,[' init_noiselvl = ', num2str(INITIAL.init_noiselvl),'\n']);
fprintf(fid,[' iseed = ', num2str(INITIAL.iseed),'\n']);
fprintf(fid,'/\n');
fprintf(fid,'&TIME_INTEGRATION_PAR\n');
fprintf(fid,[' numerical_scheme = ', TIME_INTEGRATION.numerical_scheme,'\n']);
fprintf(fid,'/');
fclose(fid);
system(['cp fort*.90 ',BASIC.RESDIR,'/.']);
end
diff --git a/src/diagnose.F90 b/src/diagnose.F90
index bfd9e9b..0763216 100644
--- a/src/diagnose.F90
+++ b/src/diagnose.F90
@@ -1,646 +1,648 @@
SUBROUTINE diagnose(kstep)
! Diagnostics, writing simulation state to disk
USE basic
USE diagnostics_par
IMPLICIT NONE
INTEGER, INTENT(in) :: kstep
CALL cpu_time(t0_diag) ! Measuring time
!! Basic diagnose loop for reading input file, displaying advancement and ending
IF ((kstep .EQ. 0)) THEN
INQUIRE(unit=lu_in, name=input_fname)
CLOSE(lu_in)
ENDIF
IF (kstep .GE. 0) THEN
! Terminal info
IF (MOD(cstep, INT(1.0/dt)) == 0 .AND. (my_id .EQ. 0)) THEN
WRITE(*,"(F6.0,A,F6.0)") time,"/",tmax
ENDIF
ELSEIF (kstep .EQ. -1) THEN
CALL cpu_time(finish)
! Display computational time cost
IF (my_id .EQ. 0) CALL display_h_min_s(finish-start)
END IF
!! Specific diagnostic calls
CALL diagnose_full(kstep)
CALL cpu_time(t1_diag); tc_diag = tc_diag + (t1_diag - t0_diag)
END SUBROUTINE diagnose
SUBROUTINE init_outfile(comm,file0,file,fid)
USE diagnostics_par, ONLY : write_doubleprecision, diag_par_outputinputs, input_fname
USE basic, ONLY : my_id, jobnum, lu_in, basic_outputinputs
USE grid, ONLY : grid_outputinputs
USE geometry, ONLY : geometry_outputinputs
USE model, ONLY : model_outputinputs
USE collision, ONLY : coll_outputinputs
USE initial_par, ONLY : initial_outputinputs
USE time_integration,ONLY : time_integration_outputinputs
USE futils, ONLY : creatf, creatg, creatd, attach, putfile
IMPLICIT NONE
!input
INTEGER, INTENT(IN) :: comm
CHARACTER(len=256), INTENT(IN) :: file0
CHARACTER(len=256), INTENT(OUT) :: file
INTEGER, INTENT(OUT) :: fid
CHARACTER(len=256) :: str,fname
INCLUDE 'srcinfo.h'
! Writing output filename
WRITE(file,'(a,a1,i2.2,a3)') TRIM(file0) ,'_',jobnum,'.h5'
! 1.1 Initial run
! Main output file creation
IF (write_doubleprecision) THEN
CALL creatf(file, fid, real_prec='d', mpicomm=comm)
ELSE
CALL creatf(file, fid, mpicomm=comm)
END IF
IF (my_id .EQ. 0) WRITE(*,'(3x,a,a)') TRIM(file), ' created'
! basic data group
CALL creatg(fid, "/data", "data")
! File group
CALL creatg(fid, "/files", "files")
CALL attach(fid, "/files", "jobnum", jobnum)
! Add the code info and parameters to the file
WRITE(str,'(a,i2.2)') "/data/input"
CALL creatd(fid, 0,(/0/),TRIM(str),'Input parameters')
CALL attach(fid, TRIM(str), "version", VERSION) !defined in srcinfo.h
CALL attach(fid, TRIM(str), "branch", BRANCH) !defined in srcinfo.h
CALL attach(fid, TRIM(str), "author", AUTHOR) !defined in srcinfo.h
CALL attach(fid, TRIM(str), "execdate", EXECDATE) !defined in srcinfo.h
CALL attach(fid, TRIM(str), "host", HOST) !defined in srcinfo.h
CALL basic_outputinputs(fid,str)
CALL grid_outputinputs(fid, str)
CALL geometry_outputinputs(fid, str)
CALL diag_par_outputinputs(fid, str)
CALL model_outputinputs(fid, str)
CALL coll_outputinputs(fid, str)
CALL initial_outputinputs(fid, str)
CALL time_integration_outputinputs(fid, str)
! Save STDIN (input file) of this run
IF(jobnum .LE. 99) THEN
WRITE(str,'(a,i2.2)') "/files/STDIN.",jobnum
ELSE
WRITE(str,'(a,i3.2)') "/files/STDIN.",jobnum
END IF
CALL putfile(fid, TRIM(str), TRIM(input_fname),ionode=0)
END SUBROUTINE init_outfile
SUBROUTINE diagnose_full(kstep)
USE basic
USE grid
USE diagnostics_par
USE futils, ONLY: creatf, creatg, creatd, closef, putarr, putfile, attach, openf, putarrnd
USE array
USE model
USE initial_par
USE fields
USE time_integration
USE parallel
USE prec_const
USE collision, ONLY: coll_outputinputs
USE geometry
IMPLICIT NONE
INTEGER, INTENT(in) :: kstep
INTEGER, parameter :: BUFSIZE = 2
INTEGER :: rank = 0
INTEGER :: dims(1) = (/0/)
INTEGER :: cp_counter = 0
CHARACTER(len=256) :: str,test_
!____________________________________________________________________________
! 1. Initial diagnostics
IF ((kstep .EQ. 0)) THEN
CALL init_outfile(comm0, resfile0,resfile,fidres)
! Profiler time measurement
CALL creatg(fidres, "/profiler", "performance analysis")
CALL creatd(fidres, 0, dims, "/profiler/Tc_rhs", "cumulative rhs computation time")
CALL creatd(fidres, 0, dims, "/profiler/Tc_adv_field", "cumulative adv. fields computation time")
CALL creatd(fidres, 0, dims, "/profiler/Tc_clos", "cumulative closure computation time")
CALL creatd(fidres, 0, dims, "/profiler/Tc_ghost", "cumulative communication time")
CALL creatd(fidres, 0, dims, "/profiler/Tc_coll", "cumulative collision computation time")
CALL creatd(fidres, 0, dims, "/profiler/Tc_poisson", "cumulative poisson computation time")
CALL creatd(fidres, 0, dims, "/profiler/Tc_Sapj", "cumulative Sapj computation time")
CALL creatd(fidres, 0, dims, "/profiler/Tc_checkfield", "cumulative checkfield computation time")
CALL creatd(fidres, 0, dims, "/profiler/Tc_diag", "cumulative sym computation time")
CALL creatd(fidres, 0, dims, "/profiler/Tc_process", "cumulative process computation time")
CALL creatd(fidres, 0, dims, "/profiler/Tc_step", "cumulative total step computation time")
CALL creatd(fidres, 0, dims, "/profiler/time", "current simulation time")
! Grid info
CALL creatg(fidres, "/data/grid", "Grid data")
CALL putarr(fidres, "/data/grid/coordkx", kxarray_full, "kx*rho_s0", ionode=0)
CALL putarr(fidres, "/data/grid/coordky", kyarray_full, "ky*rho_s0", ionode=0)
CALL putarr(fidres, "/data/grid/coordz", zarray_full, "z/R", ionode=0)
CALL putarr(fidres, "/data/grid/coordp_e" , parray_e_full, "p_e", ionode=0)
CALL putarr(fidres, "/data/grid/coordj_e" , jarray_e_full, "j_e", ionode=0)
CALL putarr(fidres, "/data/grid/coordp_i" , parray_i_full, "p_i", ionode=0)
CALL putarr(fidres, "/data/grid/coordj_i" , jarray_i_full, "j_i", ionode=0)
! Metric info
CALL creatg(fidres, "/data/metric", "Metric data")
CALL putarrnd(fidres, "/data/metric/gxx", gxx(izs:ize,0:1), (/1, 1, 1/))
CALL putarrnd(fidres, "/data/metric/gxy", gxy(izs:ize,0:1), (/1, 1, 1/))
+ CALL putarrnd(fidres, "/data/metric/gxz", gxz(izs:ize,0:1), (/1, 1, 1/))
CALL putarrnd(fidres, "/data/metric/gyy", gyy(izs:ize,0:1), (/1, 1, 1/))
CALL putarrnd(fidres, "/data/metric/gyz", gyz(izs:ize,0:1), (/1, 1, 1/))
CALL putarrnd(fidres, "/data/metric/gzz", gzz(izs:ize,0:1), (/1, 1, 1/))
CALL putarrnd(fidres, "/data/metric/hatR", hatR(izs:ize,0:1), (/1, 1, 1/))
CALL putarrnd(fidres, "/data/metric/hatZ", hatZ(izs:ize,0:1), (/1, 1, 1/))
CALL putarrnd(fidres, "/data/metric/hatB", hatB(izs:ize,0:1), (/1, 1, 1/))
+ CALL putarrnd(fidres, "/data/metric/hatB_NL", hatB_NL(izs:ize,0:1), (/1, 1, 1/))
CALL putarrnd(fidres, "/data/metric/gradxB", gradxB(izs:ize,0:1), (/1, 1, 1/))
CALL putarrnd(fidres, "/data/metric/gradyB", gradyB(izs:ize,0:1), (/1, 1, 1/))
CALL putarrnd(fidres, "/data/metric/gradzB", gradzB(izs:ize,0:1), (/1, 1, 1/))
CALL putarrnd(fidres, "/data/metric/Jacobian", Jacobian(izs:ize,0:1), (/1, 1, 1/))
CALL putarrnd(fidres, "/data/metric/gradz_coeff", gradz_coeff(izs:ize,0:1), (/1, 1, 1/))
CALL putarrnd(fidres, "/data/metric/Ckxky", Ckxky(ikys:ikye,ikxs:ikxe,izs:ize,0:1), (/1, 1, 3/))
CALL putarrnd(fidres, "/data/metric/kernel_i", kernel_i(ijs_i:ije_i,ikys:ikye,ikxs:ikxe,izs:ize,0:1), (/ 1, 2, 4/))
! var0d group (gyro transport)
IF (nsave_0d .GT. 0) THEN
CALL creatg(fidres, "/data/var0d", "0d profiles")
CALL creatd(fidres, rank, dims, "/data/var0d/time", "Time t*c_s/R")
CALL creatd(fidres, rank, dims, "/data/var0d/cstep", "iteration number")
IF (write_gamma) THEN
CALL creatd(fidres, rank, dims, "/data/var0d/gflux_ri", "Radial gyro ion transport")
CALL creatd(fidres, rank, dims, "/data/var0d/pflux_ri", "Radial part ion transport")
IF(KIN_E) THEN
CALL creatd(fidres, rank, dims, "/data/var0d/gflux_re", "Radial gyro electron transport")
CALL creatd(fidres, rank, dims, "/data/var0d/pflux_re", "Radial part electron transport")
ENDIF
ENDIF
IF (write_hf) THEN
CALL creatd(fidres, rank, dims, "/data/var0d/hflux_xi", "Radial part ion heat flux")
IF(KIN_E) THEN
CALL creatd(fidres, rank, dims, "/data/var0d/hflux_xe", "Radial part electron heat flux")
ENDIF
ENDIF
IF (cstep==0) THEN
iframe0d=0
ENDIF
CALL attach(fidres,"/data/var0d/" , "frames", iframe0d)
END IF
! var2d group (??)
IF (nsave_2d .GT. 0) THEN
CALL creatg(fidres, "/data/var2d", "2d profiles")
CALL creatd(fidres, rank, dims, "/data/var2d/time", "Time t*c_s/R")
CALL creatd(fidres, rank, dims, "/data/var2d/cstep", "iteration number")
IF (cstep==0) THEN
iframe2d=0
ENDIF
CALL attach(fidres,"/data/var2d/" , "frames", iframe2d)
END IF
! var3d group (electro. pot., Ni00 moment)
IF (nsave_3d .GT. 0) THEN
CALL creatg(fidres, "/data/var3d", "3d profiles")
CALL creatd(fidres, rank, dims, "/data/var3d/time", "Time t*c_s/R")
CALL creatd(fidres, rank, dims, "/data/var3d/cstep", "iteration number")
IF (write_phi) CALL creatg(fidres, "/data/var3d/phi", "phi")
IF (write_phi) CALL creatg(fidres, "/data/var3d/psi", "psi")
IF (write_Na00) THEN
IF(KIN_E)&
CALL creatg(fidres, "/data/var3d/Ne00", "Ne00")
CALL creatg(fidres, "/data/var3d/Ni00", "Ni00")
IF(KIN_E)&
CALL creatg(fidres, "/data/var3d/Nepjz", "Nepjz")
CALL creatg(fidres, "/data/var3d/Nipjz", "Nipjz")
ENDIF
IF (write_dens) THEN
IF(KIN_E)&
CALL creatg(fidres, "/data/var3d/dens_e", "dens_e")
CALL creatg(fidres, "/data/var3d/dens_i", "dens_i")
ENDIF
IF (write_fvel) THEN
IF(KIN_E) THEN
CALL creatg(fidres, "/data/var3d/upar_e", "upar_e")
CALL creatg(fidres, "/data/var3d/uper_e", "uper_e")
ENDIF
CALL creatg(fidres, "/data/var3d/upar_i", "upar_i")
CALL creatg(fidres, "/data/var3d/uper_i", "uper_i")
ENDIF
IF (write_temp) THEN
IF(KIN_E) THEN
CALL creatg(fidres, "/data/var3d/Tper_e", "Tper_e")
CALL creatg(fidres, "/data/var3d/Tpar_e", "Tpar_e")
CALL creatg(fidres, "/data/var3d/temp_e", "temp_e")
ENDIF
CALL creatg(fidres, "/data/var3d/Tper_i", "Tper_i")
CALL creatg(fidres, "/data/var3d/Tpar_i", "Tpar_i")
CALL creatg(fidres, "/data/var3d/temp_i", "temp_i")
ENDIF
IF (cstep==0) THEN
iframe3d=0
ENDIF
CALL attach(fidres,"/data/var3d/" , "frames", iframe3d)
END IF
! var5d group (moments)
IF (nsave_5d .GT. 0) THEN
CALL creatg(fidres, "/data/var5d", "5d profiles")
CALL creatd(fidres, rank, dims, "/data/var5d/time", "Time t*c_s/R")
CALL creatd(fidres, rank, dims, "/data/var5d/cstep", "iteration number")
IF (write_Napj) THEN
IF(KIN_E)&
CALL creatg(fidres, "/data/var5d/moments_e", "moments_e")
CALL creatg(fidres, "/data/var5d/moments_i", "moments_i")
ENDIF
IF (write_Sapj) THEN
IF(KIN_E)&
CALL creatg(fidres, "/data/var5d/Sepj", "Sepj")
CALL creatg(fidres, "/data/var5d/Sipj", "Sipj")
ENDIF
IF (cstep==0) THEN
iframe5d=0
END IF
CALL attach(fidres,"/data/var5d/" , "frames", iframe5d)
END IF
ENDIF
!_____________________________________________________________________________
! 2. Periodic diagnostics
!
IF (kstep .GE. 0) THEN
! 2.1 0d history arrays
IF (nsave_0d .GT. 0) THEN
IF ( MOD(cstep, nsave_0d) == 0 ) THEN
CALL diagnose_0d
END IF
END IF
! 2.2 1d profiles
! empty in our case
! 2.3 2d profiles
! empty in our case
! 2.3 3d profiles
IF (nsave_3d .GT. 0) THEN
IF (MOD(cstep, nsave_3d) == 0) THEN
CALL diagnose_3d
! Looks at the folder if the file check_phi exists and spits a snapshot
! of the current electrostatic potential in a basic text file
CALL spit_snapshot_check
ENDIF
ENDIF
! 2.4 5d profiles
IF (nsave_5d .GT. 0 .AND. cstep .GT. 0) THEN
IF (MOD(cstep, nsave_5d) == 0) THEN
CALL diagnose_5d
END IF
END IF
!_____________________________________________________________________________
! 3. Final diagnostics
ELSEIF (kstep .EQ. -1) THEN
CALL attach(fidres, "/data/input","cpu_time",finish-start)
! make a checkpoint at last timestep if not crashed
IF(.NOT. crashed) THEN
IF(my_id .EQ. 0) write(*,*) 'Saving last state'
IF (nsave_5d .GT. 0) &
CALL diagnose_5d
ENDIF
! Close all diagnostic files
CALL mpi_barrier(MPI_COMM_WORLD, ierr)
CALL closef(fidres)
END IF
END SUBROUTINE diagnose_full
!!-------------- Auxiliary routines -----------------!!
SUBROUTINE diagnose_0d
USE basic
USE futils, ONLY: append, attach, getatt
USE diagnostics_par
USE prec_const
USE processing
USE model, ONLY: KIN_E
IMPLICIT NONE
! Time measurement data
CALL append(fidres, "/profiler/Tc_rhs", tc_rhs,ionode=0)
CALL append(fidres, "/profiler/Tc_adv_field", tc_adv_field,ionode=0)
CALL append(fidres, "/profiler/Tc_clos", tc_clos,ionode=0)
CALL append(fidres, "/profiler/Tc_ghost", tc_ghost,ionode=0)
CALL append(fidres, "/profiler/Tc_coll", tc_coll,ionode=0)
CALL append(fidres, "/profiler/Tc_poisson", tc_poisson,ionode=0)
CALL append(fidres, "/profiler/Tc_Sapj", tc_Sapj,ionode=0)
CALL append(fidres, "/profiler/Tc_checkfield",tc_checkfield,ionode=0)
CALL append(fidres, "/profiler/Tc_diag", tc_diag,ionode=0)
CALL append(fidres, "/profiler/Tc_process", tc_process,ionode=0)
CALL append(fidres, "/profiler/Tc_step", tc_step,ionode=0)
CALL append(fidres, "/profiler/time", time,ionode=0)
! Processing data
CALL append(fidres, "/data/var0d/time", time,ionode=0)
CALL append(fidres, "/data/var0d/cstep", real(cstep,dp),ionode=0)
CALL getatt(fidres, "/data/var0d/", "frames",iframe2d)
iframe0d=iframe0d+1
CALL attach(fidres,"/data/var0d/" , "frames", iframe0d)
! Ion transport data
IF (write_gamma) THEN
CALL compute_radial_ion_transport
CALL append(fidres, "/data/var0d/gflux_ri",gflux_ri,ionode=0)
CALL append(fidres, "/data/var0d/pflux_ri",pflux_ri,ionode=0)
IF(KIN_E) THEN
CALL compute_radial_electron_transport
CALL append(fidres, "/data/var0d/gflux_re",gflux_re,ionode=0)
CALL append(fidres, "/data/var0d/pflux_re",pflux_re,ionode=0)
ENDIF
ENDIF
IF (write_hf) THEN
CALL compute_radial_ion_heatflux
CALL append(fidres, "/data/var0d/hflux_xi",hflux_xi,ionode=0)
IF(KIN_E) THEN
CALL compute_radial_electron_heatflux
CALL append(fidres, "/data/var0d/hflux_xe",hflux_xe,ionode=0)
ENDIF
ENDIF
END SUBROUTINE diagnose_0d
SUBROUTINE diagnose_3d
USE basic
USE futils, ONLY: append, getatt, attach, putarrnd, putarr
USE fields
USE array
USE grid, ONLY: ikxs,ikxe, ikys,ikye, Nkx, Nky, local_nkx, ikx, iky, ips_e, ips_i
USE time_integration
USE diagnostics_par
USE prec_const
USE processing
USE model, ONLY: KIN_E
IMPLICIT NONE
INTEGER :: i_, root, world_rank, world_size
CHARACTER(256) :: dset_name
CALL append(fidres, "/data/var3d/time", time,ionode=0)
CALL append(fidres, "/data/var3d/cstep", real(cstep,dp),ionode=0)
CALL getatt(fidres, "/data/var3d/", "frames",iframe3d)
iframe3d=iframe3d+1
CALL attach(fidres,"/data/var3d/" , "frames", iframe3d)
IF (write_phi) CALL write_field3d_kykxz(phi (ikys:ikye,ikxs:ikxe,izs:ize), 'phi')
IF (write_phi) CALL write_field3d_kykxz(psi (ikys:ikye,ikxs:ikxe,izs:ize), 'psi')
IF (write_Na00) THEN
IF(KIN_E)THEN
IF (CONTAINS_ip0_e) &
Ne00(ikys:ikye,ikxs:ikxe,izs:ize) = moments_e(ip0_e,ij0_e,ikys:ikye,ikxs:ikxe,izs:ize,updatetlevel)
CALL write_field3d_kykxz(Ne00(ikys:ikye,ikxs:ikxe,izs:ize), 'Ne00')
ENDIF
IF (CONTAINS_ip0_i) &
Ni00(ikys:ikye,ikxs:ikxe,izs:ize) = moments_i(ip0_i,ij0_i,ikys:ikye,ikxs:ikxe,izs:ize,updatetlevel)
CALL write_field3d_kykxz(Ni00(ikys:ikye,ikxs:ikxe,izs:ize), 'Ni00')
! CALL compute_Napjz_spectrum
! IF(KIN_E) &
! CALL write_field3d_pjz_e(Nepjz(ips_e:ipe_e,ijs_e:ije_e,izs:ize), 'Nepjz')
! CALL write_field3d_pjz_i(Nipjz(ips_i:ipe_i,ijs_i:ije_i,izs:ize), 'Nipjz')
ENDIF
!! Fuid moments
IF (write_dens .OR. write_fvel .OR. write_temp) &
CALL compute_fluid_moments
IF (write_dens) THEN
IF(KIN_E)&
CALL write_field3d_kykxz(dens_e(ikys:ikye,ikxs:ikxe,izs:ize), 'dens_e')
CALL write_field3d_kykxz(dens_i(ikys:ikye,ikxs:ikxe,izs:ize), 'dens_i')
ENDIF
IF (write_fvel) THEN
IF(KIN_E)&
CALL write_field3d_kykxz(upar_e(ikys:ikye,ikxs:ikxe,izs:ize), 'upar_e')
CALL write_field3d_kykxz(upar_i(ikys:ikye,ikxs:ikxe,izs:ize), 'upar_i')
IF(KIN_E)&
CALL write_field3d_kykxz(uper_e(ikys:ikye,ikxs:ikxe,izs:ize), 'uper_e')
CALL write_field3d_kykxz(uper_i(ikys:ikye,ikxs:ikxe,izs:ize), 'uper_i')
ENDIF
IF (write_temp) THEN
IF(KIN_E)&
CALL write_field3d_kykxz(Tpar_e(ikys:ikye,ikxs:ikxe,izs:ize), 'Tpar_e')
CALL write_field3d_kykxz(Tpar_i(ikys:ikye,ikxs:ikxe,izs:ize), 'Tpar_i')
IF(KIN_E)&
CALL write_field3d_kykxz(Tper_e(ikys:ikye,ikxs:ikxe,izs:ize), 'Tper_e')
CALL write_field3d_kykxz(Tper_i(ikys:ikye,ikxs:ikxe,izs:ize), 'Tper_i')
IF(KIN_E)&
CALL write_field3d_kykxz(temp_e(ikys:ikye,ikxs:ikxe,izs:ize), 'temp_e')
CALL write_field3d_kykxz(temp_i(ikys:ikye,ikxs:ikxe,izs:ize), 'temp_i')
ENDIF
CONTAINS
SUBROUTINE write_field3d_kykxz(field, text)
USE parallel, ONLY : gather_xyz
IMPLICIT NONE
COMPLEX(dp), DIMENSION(ikys:ikye,ikxs:ikxe, izs:ize), INTENT(IN) :: field
CHARACTER(*), INTENT(IN) :: text
COMPLEX(dp), DIMENSION(1:Nky,1:Nkx,1:Nz) :: field_full
CHARACTER(256) :: dset_name
WRITE(dset_name, "(A, '/', A, '/', i6.6)") "/data/var3d", TRIM(text), iframe3d
IF (num_procs .EQ. 1) THEN ! no data distribution
CALL putarr(fidres, dset_name, field(ikys:ikye,ikxs:ikxe, izs:ize), ionode=0)
ELSEIF(GATHERV_OUTPUT) THEN ! output using one node (gatherv)
CALL gather_xyz(field(ikys:ikye,1:Nkx,izs:ize),field_full(1:Nky,1:Nkx,1:Nz))
CALL putarr(fidres, dset_name, field_full(1:Nky,1:Nkx,1:Nz), ionode=0)
ELSE ! output using putarrnd (very slow on marconi)
CALL putarrnd(fidres, dset_name, field(ikys:ikye,ikxs:ikxe, izs:ize), (/1, 1, 3/))
ENDIF
CALL attach(fidres, dset_name, "time", time)
END SUBROUTINE write_field3d_kykxz
SUBROUTINE write_field3d_pjz_i(field, text)
IMPLICIT NONE
REAL(dp), DIMENSION(ips_i:ipe_i,ijs_i:ije_i,izs:ize), INTENT(IN) :: field
CHARACTER(*), INTENT(IN) :: text
CHARACTER(LEN=50) :: dset_name
WRITE(dset_name, "(A, '/', A, '/', i6.6)") "/data/var3d", TRIM(text), iframe3d
IF (num_procs .EQ. 1) THEN ! no data distribution
CALL putarr(fidres, dset_name, field(ips_i:ipe_i,ijs_i:ije_i,izs:ize), ionode=0)
ELSE
CALL putarrnd(fidres, dset_name, field(ips_i:ipe_i,ijs_i:ije_i,izs:ize), (/1, 0, 3/))
ENDIF
CALL attach(fidres, dset_name, "time", time)
END SUBROUTINE write_field3d_pjz_i
SUBROUTINE write_field3d_pjz_e(field, text)
IMPLICIT NONE
REAL(dp), DIMENSION(ips_e:ipe_e,ijs_e:ije_e,izs:ize), INTENT(IN) :: field
CHARACTER(*), INTENT(IN) :: text
CHARACTER(LEN=50) :: dset_name
WRITE(dset_name, "(A, '/', A, '/', i6.6)") "/data/var3d", TRIM(text), iframe3d
IF (num_procs .EQ. 1) THEN ! no data distribution
CALL putarr(fidres, dset_name, field(ips_e:ipe_e,ijs_e:ije_e,izs:ize), ionode=0)
ELSE
CALL putarrnd(fidres, dset_name, field(ips_e:ipe_e,ijs_e:ije_e,izs:ize), (/1, 0, 3/))
ENDIF
CALL attach(fidres, dset_name, "time", time)
END SUBROUTINE write_field3d_pjz_e
END SUBROUTINE diagnose_3d
SUBROUTINE diagnose_5d
USE basic
USE futils, ONLY: append, getatt, attach, putarrnd, putarr
USE fields
USE array!, ONLY: Sepj, Sipj
USE grid, ONLY: ips_e,ipe_e, ips_i, ipe_i, &
ijs_e,ije_e, ijs_i, ije_i, &
Np_i, Nj_i, Np_e, Nj_e, Nky, Nkx, Nz, &
ikxs,ikxe,ikys,ikye,izs,ize
USE time_integration
USE diagnostics_par
USE prec_const
USE model, ONLY: KIN_E
IMPLICIT NONE
CHARACTER(LEN=50) :: dset_name
CALL append(fidres, "/data/var5d/time", time,ionode=0)
CALL append(fidres, "/data/var5d/cstep", real(cstep,dp),ionode=0)
CALL getatt(fidres, "/data/var5d/", "frames",iframe5d)
iframe5d=iframe5d+1
CALL attach(fidres,"/data/var5d/" , "frames", iframe5d)
IF (write_Napj) THEN
IF(KIN_E)&
CALL write_field5d_e(moments_e(ips_e:ipe_e,ijs_e:ije_e,ikys:ikye,ikxs:ikxe,izs:ize,updatetlevel), 'moments_e')
CALL write_field5d_i(moments_i(ips_i:ipe_i,ijs_i:ije_i,ikys:ikye,ikxs:ikxe,izs:ize,updatetlevel), 'moments_i')
ENDIF
IF (write_Sapj) THEN
IF(KIN_E)&
CALL write_field5d_e(Sepj(ips_e:ipe_e,ijs_e:ije_e,ikys:ikye,ikxs:ikxe,izs:ize), 'Sepj')
CALL write_field5d_i(Sipj(ips_i:ipe_i,ijs_i:ije_i,ikys:ikye,ikxs:ikxe,izs:ize), 'Sipj')
ENDIF
CONTAINS
SUBROUTINE write_field5d_e(field, text)
USE futils, ONLY: attach, putarr, putarrnd
USE parallel, ONLY: gather_pjxyz_e
USE grid, ONLY: ips_e,ipe_e, ijs_e,ije_e, ikxs,ikxe, ikys,ikye, izs,ize
USE prec_const
IMPLICIT NONE
COMPLEX(dp), DIMENSION(ips_e:ipe_e,ijs_e:ije_e,ikys:ikye,ikxs:ikxe,izs:ize), INTENT(IN) :: field
CHARACTER(*), INTENT(IN) :: text
COMPLEX(dp), DIMENSION(1:Np_e,1:Nj_e,1:Nky,1:Nkx,1:Nz) :: field_full
CHARACTER(LEN=50) :: dset_name
WRITE(dset_name, "(A, '/', A, '/', i6.6)") "/data/var5d", TRIM(text), iframe5d
IF (num_procs .EQ. 1) THEN
CALL putarr(fidres, dset_name, field(ips_e:ipe_e,ijs_e:ije_e,ikys:ikye,ikxs:ikxe,izs:ize), ionode=0)
ELSEIF(GATHERV_OUTPUT) THEN ! output using one node (gatherv)
CALL gather_pjxyz_e(field(ips_e:ipe_e,ijs_e:ije_e,ikys:ikye,ikxs:ikxe,izs:ize),&
field_full(1:Np_e,1:Nj_e,1:Nky,1:Nkx,1:Nz))
CALL putarr(fidres, dset_name, field_full(1:Np_i,1:Nj_i,1:Nky,1:Nkx,1:Nz), ionode=0)
ELSE
CALL putarrnd(fidres, dset_name, field(ips_e:ipe_e,ijs_e:ije_e,ikys:ikye,ikxs:ikxe,izs:ize), (/1,3,5/))
ENDIF
CALL attach(fidres, dset_name, 'cstep', cstep)
CALL attach(fidres, dset_name, 'time', time)
CALL attach(fidres, dset_name, 'jobnum', jobnum)
CALL attach(fidres, dset_name, 'dt', dt)
CALL attach(fidres, dset_name, 'iframe2d', iframe2d)
CALL attach(fidres, dset_name, 'iframe5d', iframe5d)
END SUBROUTINE write_field5d_e
SUBROUTINE write_field5d_i(field, text)
USE futils, ONLY: attach, putarr, putarrnd
USE parallel, ONLY: gather_pjxyz_i
USE grid, ONLY: ips_i,ipe_i, ijs_i,ije_i, ikxs,ikxe, ikys,ikye, izs,ize
USE prec_const
IMPLICIT NONE
COMPLEX(dp), DIMENSION(ips_i:ipe_i,ijs_i:ije_i,ikys:ikye,ikxs:ikxe,izs:ize), INTENT(IN) :: field
CHARACTER(*), INTENT(IN) :: text
COMPLEX(dp), DIMENSION(1:Np_i,1:Nj_i,1:Nky,1:Nkx,1:Nz) :: field_full
CHARACTER(LEN=50) :: dset_name
WRITE(dset_name, "(A, '/', A, '/', i6.6)") "/data/var5d", TRIM(text), iframe5d
IF (num_procs .EQ. 1) THEN
CALL putarr(fidres, dset_name, field(ips_i:ipe_i,ijs_i:ije_i,ikys:ikye,ikxs:ikxe,izs:ize), ionode=0)
ELSEIF(GATHERV_OUTPUT) THEN ! output using one node (gatherv)
CALL gather_pjxyz_i(field(ips_i:ipe_i,ijs_i:ije_i,ikys:ikye,ikxs:ikxe,izs:ize),&
field_full(1:Np_i,1:Nj_i,1:Nky,1:Nkx,1:Nz))
CALL putarr(fidres, dset_name, field_full(1:Np_i,1:Nj_i,1:Nky,1:Nkx,1:Nz), ionode=0)
ELSE
CALL putarrnd(fidres, dset_name, field(ips_i:ipe_i,ijs_i:ije_i,ikys:ikye,ikxs:ikxe,izs:ize), (/1,3,5/))
ENDIF
CALL attach(fidres, dset_name, 'cstep', cstep)
CALL attach(fidres, dset_name, 'time', time)
CALL attach(fidres, dset_name, 'jobnum', jobnum)
CALL attach(fidres, dset_name, 'dt', dt)
CALL attach(fidres, dset_name, 'iframe2d', iframe2d)
CALL attach(fidres, dset_name, 'iframe5d', iframe5d)
END SUBROUTINE write_field5d_i
END SUBROUTINE diagnose_5d
SUBROUTINE spit_snapshot_check
USE fields, ONLY: phi
USE grid, ONLY: ikxs,ikxe,Nkx,ikys,ikye,Nky,izs,ize,Nz
USE parallel, ONLY: gather_xyz
USE basic
IMPLICIT NONE
LOGICAL :: file_exist
INTEGER :: fid_check, ikx, iky, iz
CHARACTER(256) :: check_filename
COMPLEX(dp), DIMENSION(1:Nky,1:Nkx,1:Nz) :: field_to_check
!! Spit a snapshot of PHI if requested (triggered by creating a file named "check_phi")
INQUIRE(file='check_phi', exist=file_exist)
IF( file_exist ) THEN
IF(my_id.EQ. 0) WRITE(*,*) 'Check file found -> gather phi..'
CALL gather_xyz(phi(ikys:ikye,ikxs:ikxe,izs:ize), field_to_check)
IF(my_id.EQ. 0) THEN
WRITE(check_filename,'(a16)') 'check_phi.out'
OPEN(fid_check, file=check_filename, form='formatted')
WRITE(*,*) 'Check file found -> output phi ..'
WRITE(fid_check,*) Nky, Nkx, Nz
DO iky = 1,Nky; DO ikx = 1, Nkx; DO iz = 1,Nz
WRITE(fid_check,*) real(field_to_check(iky,ikx,iz)), ',' , imag(field_to_check(iky,ikx,iz))
ENDDO; ENDDO; ENDDO
CLOSE(fid_check)
WRITE(*,*) 'Check file found -> done.'
! delete the check_phi flagfile
OPEN(fid_check, file='check_phi')
CLOSE(fid_check, status='delete')
ENDIF
ENDIF
END SUBROUTINE spit_snapshot_check
diff --git a/src/geometry_mod.F90 b/src/geometry_mod.F90
index 665f18b..72b7104 100644
--- a/src/geometry_mod.F90
+++ b/src/geometry_mod.F90
@@ -1,567 +1,452 @@
module geometry
! computes geometrical quantities
! Adapted from B.J.Frei MOLIX code (2021)
use prec_const
use model
use grid
use array
use fields
use basic
use calculus, ONLY: simpson_rule_z
-
+ use miller, ONLY: set_miller_parameters, get_miller
implicit none
PRIVATE
- ! Geometry parameters
+ ! Geometry input parameters
CHARACTER(len=16), &
PUBLIC, PROTECTED :: geom
- REAL(dp), PUBLIC, PROTECTED :: q0 = 1.4_dp ! safety factor
- REAL(dp), PUBLIC, PROTECTED :: shear = 0._dp ! magnetic field shear
- REAL(dp), PUBLIC, PROTECTED :: eps = 0.18_dp ! inverse aspect ratio
- LOGICAL, PUBLIC, PROTECTED :: SHEARED = .false. ! flag for shear magn. geom or not
- ! Geometrical operators
+ REAL(dp), PUBLIC, PROTECTED :: q0 = 1.4_dp ! safety factor
+ REAL(dp), PUBLIC, PROTECTED :: shear = 0._dp ! magnetic field shear
+ REAL(dp), PUBLIC, PROTECTED :: eps = 0.18_dp ! inverse aspect ratio
+ REAL(dp), PUBLIC, PROTECTED :: alpha_MHD = 0 ! shafranov shift effect alpha = -q2 R dbeta/dr
+ ! parameters for Miller geometry
+ REAL(dp), PUBLIC, PROTECTED :: kappa = 1._dp ! elongation
+ REAL(dp), PUBLIC, PROTECTED :: s_kappa = 0._dp ! r normalized derivative skappa = r/kappa dkappa/dr
+ REAL(dp), PUBLIC, PROTECTED :: delta = 0._dp ! triangularity
+ REAL(dp), PUBLIC, PROTECTED :: s_delta = 0._dp ! '' sdelta = r/sqrt(1-delta2) ddelta/dr
+ REAL(dp), PUBLIC, PROTECTED :: zeta = 0._dp ! squareness
+ REAL(dp), PUBLIC, PROTECTED :: s_zeta = 0._dp ! '' szeta = r dzeta/dr
+
+ ! GENE unused additional parameters for miller_mod
+ REAL(dp), PUBLIC, PROTECTED :: edge_opt = 0 ! meant to redistribute the points in z
+ REAL(dp), PUBLIC, PROTECTED :: major_R = 1 ! major radius
+ REAL(dp), PUBLIC, PROTECTED :: major_Z = 0 ! vertical elevation
+ REAL(dp), PUBLIC, PROTECTED :: dpdx_pm_geom = 0 ! amplitude mag. eq. pressure grad.
+ REAL(dp), PUBLIC, PROTECTED :: C_y = 0 ! defines y coordinate : Cy (q theta - phi)
+ REAL(dp), PUBLIC, PROTECTED :: C_xy = 0 ! defines x coordinate : B = Cxy Vx x Vy
+
+ ! Geometrical auxiliary variables
+ LOGICAL, PUBLIC, PROTECTED :: SHEARED = .false. ! flag for shear magn. geom or not
! Curvature
REAL(dp), PUBLIC, DIMENSION(:,:,:,:), ALLOCATABLE :: Ckxky ! dimensions: kx, ky, z, odd/even p
! Jacobian
REAL(dp), PUBLIC, DIMENSION(:,:), ALLOCATABLE :: Jacobian ! dimensions: z, odd/even p
COMPLEX(dp), PUBLIC, PROTECTED :: iInt_Jacobian ! Inverse integrated Jacobian
! Metric
REAL(dp), PUBLIC, DIMENSION(:,:), ALLOCATABLE :: gxx, gxy, gxz, gyy, gyz, gzz ! dimensions: z, odd/even p
REAL(dp), PUBLIC, DIMENSION(:,:), ALLOCATABLE :: dxdr, dxdZ, Rc, phic, Zc
! derivatives of magnetic field strength
REAL(dp), PUBLIC, DIMENSION(:,:), ALLOCATABLE :: gradxB, gradyB, gradzB
! Relative magnetic field strength
REAL(dp), PUBLIC, DIMENSION(:,:), ALLOCATABLE :: hatB, hatB_NL
! Relative strength of major radius
REAL(dp), PUBLIC, DIMENSION(:,:), ALLOCATABLE :: hatR, hatZ
! Some geometrical coefficients
REAL(dp), PUBLIC, DIMENSION(:,:) , ALLOCATABLE :: gradz_coeff ! 1 / [ J_{xyz} \hat{B} ]
! Array to map the index of mode (kx,ky,-pi) to (kx+2pi*s*ky,ky,pi) for sheared periodic boundary condition
INTEGER, PUBLIC, DIMENSION(:,:), ALLOCATABLE :: ikx_zBC_L, ikx_zBC_R
+
! Functions
PUBLIC :: geometry_readinputs, geometry_outputinputs,&
eval_magnetic_geometry, set_ikx_zBC_map
CONTAINS
SUBROUTINE geometry_readinputs
! Read the input parameters
IMPLICIT NONE
- NAMELIST /GEOMETRY/ geom, q0, shear, eps
+ NAMELIST /GEOMETRY/ geom, q0, shear, eps,&
+ kappa, s_kappa,delta, s_delta, zeta, s_zeta ! For miller
READ(lu_in,geometry)
IF(shear .NE. 0._dp) SHEARED = .true.
END SUBROUTINE geometry_readinputs
subroutine eval_magnetic_geometry
! evalute metrix, elementwo_third_kpmaxts, jacobian and gradient
implicit none
REAL(dp) :: kx,ky
COMPLEX(dp), DIMENSION(izs:ize) :: integrant
INTEGER :: fid
+ real(dp) :: G1,G2,G3,Cx,Cy
! Allocate arrays
CALL geometry_allocate_mem
!
IF( (Ny .EQ. 1) .AND. (Nz .EQ. 1)) THEN !1D perp linear run
IF( my_id .eq. 0 ) WRITE(*,*) '1D perpendicular geometry'
call eval_1D_geometry
ELSE
SELECT CASE(geom)
- CASE('circular')
- IF( my_id .eq. 0 ) WRITE(*,*) 'circular geometry'
- call eval_circular_geometry
CASE('s-alpha')
IF( my_id .eq. 0 ) WRITE(*,*) 's-alpha-B geometry'
call eval_salphaB_geometry
CASE('Z-pinch')
IF( my_id .eq. 0 ) WRITE(*,*) 'Z-pinch geometry'
call eval_zpinch_geometry
SHEARED = .FALSE.
+ CASE('miller')
+ IF( my_id .eq. 0 ) WRITE(*,*) 'Miller geometry'
+ call set_miller_parameters(kappa,s_kappa,delta,s_delta,zeta,s_zeta)
+ call get_miller(eps,major_R,major_Z,q0,shear,alpha_MHD,edge_opt,&
+ C_y,C_xy,dpdx_pm_geom,gxx,gyy,gzz,gxy,gxz,gyz,&
+ gradxB,gradyB,hatB,jacobian,gradzB,hatR,hatZ,dxdR,dxdZ,&
+ Ckxky,gradz_coeff)
CASE DEFAULT
- ERROR STOP 'Error stop: geometry not recognized!!'
+ STOP 'geometry not recognized!!'
END SELECT
ENDIF
!
! Evaluate perpendicular wavenumber
! k_\perp^2 = g^{xx} k_x^2 + 2 g^{xy}k_x k_y + k_y^2 g^{yy}
! normalized to rhos_
DO eo = 0,1
- DO iky = ikys, ikye
- ky = kyarray(iky)
- DO ikx = ikxs, ikxe
- kx = kxarray(ikx)
- DO iz = izgs,izge
- kparray(iky, ikx, iz, eo) = &
- SQRT( gxx(iz,eo)*kx**2 + 2._dp*gxy(iz,eo)*kx*ky + gyy(iz,eo)*ky**2)/hatB(iz,eo)
- ! there is a factor 1/B from the normalization; important to match GENE
+ DO iz = izgs,izge
+ DO iky = ikys, ikye
+ ky = kyarray(iky)
+ DO ikx = ikxs, ikxe
+ kx = kxarray(ikx)
+ kparray(iky, ikx, iz, eo) = &
+ SQRT( gxx(iz,eo)*kx**2 + 2._dp*gxy(iz,eo)*kx*ky + gyy(iz,eo)*ky**2)/hatB(iz,eo)
+ ! there is a factor 1/B from the normalization; important to match GENE
ENDDO
- ENDDO
- ENDDO
+ ENDDO
+ ENDDO
+ ! Curvature operator (Frei et al. 2022 eq 2.15)
+ DO iz = izgs,izge
+ G1 = gxy(iz,eo)*gxy(iz,eo)-gxx(iz,eo)*gyy(iz,eo)
+ G2 = gxy(iz,eo)*gxz(iz,eo)-gxx(iz,eo)*gyz(iz,eo)
+ G3 = gyy(iz,eo)*gxz(iz,eo)-gxy(iz,eo)*gyz(iz,eo)
+ Cx = (G1*gradyB(iz,eo) + G2*gradzB(iz,eo))/hatB(iz,eo)
+ Cy = (G3*gradzB(iz,eo) - G1*gradxB(iz,eo))/hatB(iz,eo)
+
+ DO iky = ikys, ikye
+ ky = kyarray(iky)
+ DO ikx= ikxs, ikxe
+ kx = kxarray(ikx)
+ Ckxky(iky, ikx, iz,eo) = (Cx*kx + Cy*ky)
+ ENDDO
+ ENDDO
+ ! coefficient in the front of parallel derivative
+ gradz_coeff(iz,eo) = 1._dp / jacobian(iz,eo) / hatB(iz,eo)
+ ! Factor in front of the nonlinear term
+ hatB_NL(iz,eo) = Jacobian(iz,eo)&
+ *(gxx(iz,eo)*gyy(iz,eo) - gxy(iz,eo)**2)/hatB(iz,eo)
+ ENDDO
ENDDO
+
+
! set the mapping for parallel boundary conditions
CALL set_ikx_zBC_map
two_third_kpmax = 2._dp/3._dp * MAXVAL(kparray)
!
! Compute the inverse z integrated Jacobian (useful for flux averaging)
integrant = Jacobian(izs:ize,0) ! Convert into complex array
CALL simpson_rule_z(integrant,iInt_Jacobian)
iInt_Jacobian = 1._dp/iInt_Jacobian ! reverse it
END SUBROUTINE eval_magnetic_geometry
!
!--------------------------------------------------------------------------------
!
SUBROUTINE eval_salphaB_geometry
! evaluate s-alpha geometry model
implicit none
- REAL(dp) :: z, kx, ky, alpha_MHD, Gx, Gy
+ REAL(dp) :: z, kx, ky, Gx, Gy
alpha_MHD = 0._dp
parity: DO eo = 0,1
zloop: DO iz = izgs,izge
z = zarray(iz,eo)
! metric
gxx(iz,eo) = 1._dp
gxy(iz,eo) = shear*z - alpha_MHD*SIN(z)
gxz(iz,eo) = 0._dp
gyy(iz,eo) = 1._dp + (shear*z - alpha_MHD*SIN(z))**2
gyz(iz,eo) = 1._dp/eps
gzz(iz,eo) = 0._dp
dxdR(iz,eo)= COS(z)
dxdZ(iz,eo)= SIN(z)
! Relative strengh of radius
hatR(iz,eo) = 1._dp + eps*COS(z)
hatZ(iz,eo) = 1._dp + eps*SIN(z)
! toroidal coordinates
Rc (iz,eo) = hatR(iz,eo)
phic(iz,eo) = z
Zc (iz,eo) = hatZ(iz,eo)
! Jacobian
Jacobian(iz,eo) = q0*hatR(iz,eo)
! Relative strengh of modulus of B
- hatB (iz,eo) = 1._dp / hatR(iz,eo)
- hatB_NL(iz,eo) = 1._dp ! Factor in front of the nonlinear term
+ hatB(iz,eo) = 1._dp / hatR(iz,eo)
! Derivative of the magnetic field strenght
gradxB(iz,eo) = -COS(z) ! Gene put a factor hatB^2 or 1/hatR^2 in this
gradyB(iz,eo) = 0._dp
gradzB(iz,eo) = eps*SIN(z)/hatR(iz,eo) ! Gene put a factor hatB or 1/hatR in this
! Curvature operator
Gx = (gxz(iz,eo) * gxy(iz,eo) - gxx(iz,eo) * gyz(iz,eo)) *eps*SIN(Z) ! Kx
Gy = -COS(z) + (gxz(iz,eo) * gyy(iz,eo) - gxy(iz,eo) * gyz(iz,eo)) *eps*SIN(Z) ! Ky
DO iky = ikys, ikye
ky = kyarray(iky)
DO ikx= ikxs, ikxe
kx = kxarray(ikx)
- Ckxky(iky, ikx, iz,eo) = (-SIN(z)*kx - COS(z)*ky -(shear*z-alpha_MHD*SIN(z))*SIN(z)*ky)* hatB(iz,eo) ! .. multiply by hatB to cancel the 1/ hatB factor in moments_eqs_rhs.f90 routine
+ Ckxky(iky, ikx, iz,eo) = (-SIN(z)*kx - COS(z)*ky -(shear*z-alpha_MHD*SIN(z))*SIN(z)*ky)/ hatB(iz,eo)
! Ckxky(iky, ikx, iz,eo) = (Gx*kx + Gy*ky) * hatB(iz,eo) ! .. multiply by hatB to cancel the 1/ hatB factor in moments_eqs_rhs.f90 routine
ENDDO
ENDDO
! coefficient in the front of parallel derivative
gradz_coeff(iz,eo) = 1._dp / Jacobian(iz,eo) / hatB(iz,eo)
ENDDO zloop
ENDDO parity
END SUBROUTINE eval_salphaB_geometry
!
!--------------------------------------------------------------------------------
!
-
- SUBROUTINE eval_circular_geometry
- ! evaluate circular geometry model
- ! Ref: Lapilonne et al., PoP, 2009, GENE circular.F90 applied at r=r0
+ SUBROUTINE eval_zpinch_geometry
implicit none
- REAL(dp) :: chi, kx, ky, Gx, Gy
+ REAL(dp) :: z, kx, ky, alpha_MHD
+ alpha_MHD = 0._dp
- parity: DO eo = 0,1
- zloop: DO iz = izgs,izge
- chi = zarray(iz,eo) ! = chi
+ parity: DO eo = 0,1
+ zloop: DO iz = izgs,izge
+ z = zarray(iz,eo)
- ! metric in x,y,z
+ ! metric
gxx(iz,eo) = 1._dp
- gyy(iz,eo) = 1._dp + (shear*chi)**2 - 2._dp*eps*COS(chi) - 2._dp*shear*chi*eps*SIN(chi)
- gxy(iz,eo) = shear*chi - eps*SIN(chi)
- gxz(iz,eo) = -SIN(chi)
- gyz(iz,eo) = (1._dp - 2._dp*eps*COS(chi) - shear*chi*eps*SIN(chi))/eps
- gzz(iz,eo) = (1._dp - 2._dp*eps*COS(chi))/eps**2
- dxdR(iz,eo)= COS(chi)
- dxdZ(iz,eo)= SIN(chi)
+ gxy(iz,eo) = 0._dp
+ gxz(iz,eo) = 0._dp
+ gyy(iz,eo) = 1._dp
+ gyz(iz,eo) = 0._dp
+ gzz(iz,eo) = 1._dp
+ dxdR(iz,eo)= COS(z)
+ dxdZ(iz,eo)= SIN(z)
! Relative strengh of radius
- hatR(iz,eo) = 1._dp + eps*COS(chi)
- hatZ(iz,eo) = 1._dp + eps*SIN(chi)
+ hatR(iz,eo) = 1._dp
+ hatZ(iz,eo) = 1._dp
! toroidal coordinates
Rc (iz,eo) = hatR(iz,eo)
- phic(iz,eo) = chi
+ phic(iz,eo) = z
Zc (iz,eo) = hatZ(iz,eo)
! Jacobian
- Jacobian(iz,eo) = q0*hatR(iz,eo)
+ Jacobian(iz,eo) = 1._dp
! Relative strengh of modulus of B
- hatB (iz,eo) = 1._dp / hatR(iz,eo)
- hatB_NL(iz,eo) = 1._dp ! Factor in front of the nonlinear term
+ hatB (iz,eo) = 1._dp
+ hatB_NL(iz,eo) = 1._dp
! Derivative of the magnetic field strenght
- gradxB(iz,eo) = -COS(chi) ! Gene put a factor hatB^2 or 1/hatR^2 in this
- gradyB(iz,eo) = 0._dp
- gradzB(iz,eo) = eps * SIN(chi) / hatR(iz,eo) ! Gene put a factor hatB or 1/hatR in this
+ gradxB(iz,eo) = -1._dp ! Gene put a factor hatB^2 or 1/hatR^2 in this
+ gradyB(iz,eo) = 0._dp
+ gradzB(iz,eo) = 0._dp ! Gene put a factor hatB or 1/hatR in this
! Curvature operator
- Gx = (gxz(iz,eo) * gxy(iz,eo) - gxx(iz,eo) * gyz(iz,eo)) *eps*SIN(chi) ! Kx
- Gy = -COS(chi) + (gxz(iz,eo) * gyy(iz,eo) - gxy(iz,eo) * gyz(iz,eo)) *eps*SIN(chi) ! Ky
- DO iky = ikys, ikye
+ DO iky = ikys, ikye
ky = kyarray(iky)
DO ikx= ikxs, ikxe
kx = kxarray(ikx)
- Ckxky(iky, ikx, iz,eo) = (Gx*kx + Gy*ky) * hatB(iz,eo) ! .. multiply by hatB to cancel the 1/ hatB factor in moments_eqs_rhs.f90 routine
+ Ckxky(iky, ikx, iz,eo) = -ky
ENDDO
ENDDO
! coefficient in the front of parallel derivative
gradz_coeff(iz,eo) = 1._dp / Jacobian(iz,eo) / hatB(iz,eo)
- ENDDO zloop
- ENDDO parity
-
- END SUBROUTINE eval_circular_geometry
- !
- !--------------------------------------------------------------------------------
- !
-
- SUBROUTINE eval_circular_geometry_GENE
- ! evaluate circular geometry model
- ! Ref: Lapilonne et al., PoP, 2009, GENE circular.F90 applied at r=r0
- implicit none
- REAL(dp) :: qbar, dxdr_, dpsidr, dqdr, dqbardr, Cy, dCydr_Cy, Cxy, fac2, &
- cost, sint, dchidr, dchidt, sign_Ip, B, dBdt, dBdr, &
- g11, g22, g12, g33, dBdchi, dBdr_c !GENE variables
- REAL(dp) :: X, z, kx, ky, Gamma1, Gamma2, Gamma3, feps
-
- sign_Ip = 1._dp
- feps = SQRT(1._dp-eps**2)
- qbar = q0 * feps
- dxdr_ = 1._dp
- dpsidr = eps/qbar
- dqdr = q0/eps*shear
- dqbardr = feps*q0/eps*(shear - eps**2/feps**2)
- Cy = eps/q0 * sign_Ip
- dCydr_Cy = 0._dp
- Cxy = 1._dp/feps
- fac2 = dCydr_Cy + dqdr/q0
-
-
- parity: DO eo = 0,1
- zloop: DO iz = izgs,izge
- z = zarray(iz,eo)
-
- cost = (COS(z)-eps)/(1._dp-eps*COS(z))
- sint = feps*sin(sign_Ip*z)/(1._dp-eps*COS(z))
- dchidr = -SIN(z)/feps**2
- dchidt = sign_Ip*feps/(1._dp+eps*cost)
- B = SQRT(1._dp+(eps/qbar)**2)/(1._dp+eps*cost)
- dBdt = eps*sint*B/(1._dp+eps*cost)
-
- ! metric in r,chi,Phi
- g11 = 1._dp
- g22 = dchidr**2 + dchidt**2/eps**2
- g12 = dchidr
- g33 = 1._dp/(1._dp+eps*cost)**2
-
- ! magnetic field derivatives in
- dBdchi=dBdt/dchidt
- dBdr_c=(dBdr-g12*dBdt/dchidt)/g11
-
- ! metric in x,y,z
- gxx(iz,eo) = dxdr_**2*g11
- gyy(iz,eo) = (Cy*q0)**2 * (fac2*z)**2*g11 &
- + 2._dp*fac2*z*g12 &
- + Cy**2*g33
- gxy(iz,eo) = dxdr_*Cy*sign_Ip*q0*(fac2*z*g11 + g12)
- gxz(iz,eo) = dxdr_*g12
- gyz(iz,eo) = Cy*q0*sign_Ip*(fac2*z*g12 + g22)
- gzz(iz,eo) = g22
-
- ! Jacobian
- Jacobian(iz,eo) = Cxy*abs(q0)*(1._dp+eps*cost)**2
-
- ! Background equilibrium magnetic field
- hatB (iz,eo) = B
- hatB_NL(iz,eo) = SQRT(gxx(iz,eo)*gyy(iz,eo) - (gxy(iz,eo))**2) ! In front of the NL term
- gradxB(iz,eo) = dBdr_c/dxdr_ ! Gene put a factor hatB^2 or 1/hatR^2 in this
- gradyB(iz,eo) = 0._dp
- gradzB(iz,eo) = dBdchi! Gene put a factor hatB or 1/hatR in this
-
- ! Cylindrical coordinates derivatives
- dxdR(iz,eo) = cost
- dxdZ(iz,eo) = sint
- hatR(iz,eo) = 1._dp + eps*cost
- hatZ(iz,eo) = 1._dp + eps*sint
-
- ! toroidal coordinates
- Rc (iz,eo) = hatR(iz,eo)
- phic(iz,eo) = X
- Zc (iz,eo) = hatZ(iz,eo)
-
- Gamma1 = gxy(iz,eo) * gxy(iz,eo) - gxx(iz,eo) * gyy(iz,eo)
- Gamma2 = gxz(iz,eo) * gxy(iz,eo) - gxx(iz,eo) * gyz(iz,eo) ! Kx
- Gamma3 = gxz(iz,eo) * gyy(iz,eo) - gxy(iz,eo) * gyz(iz,eo) ! Ky
- ! Curvature operator
- DO iky = ikys, ikye
- ky = kyarray(iky)
- DO ikx= ikxs, ikxe
- kx = kxarray(ikx)
- ! Ckxky(iky, ikx, iz,eo) = (-SIN(z)*kx - (COS(z) + (shear*z - alpha_MHD*SIN(z))* SIN(z))*ky) * hatB(iz,eo) ! .. multiply by hatB to cancel the 1/ hatB factor in moments_eqs_rhs.f90 routine
- Ckxky(iky, ikx, iz,eo) = (-sint*kx - cost*ky) * hatB(iz,eo) ! .. multiply by hatB to cancel the 1/ hatB factor in moments_eqs_rhs.f90 routine
- ENDDO
- ENDDO
- ! coefficient in the front of parallel derivative
- gradz_coeff(iz,eo) = 1._dp / Jacobian(iz,eo) / hatB(iz,eo)
-
- ENDDO zloop
- ENDDO parity
-
- END SUBROUTINE eval_circular_geometry_GENE
- !
- !--------------------------------------------------------------------------------
- !
-
- SUBROUTINE eval_zpinch_geometry
- ! evaluate s-alpha geometry model
- implicit none
- REAL(dp) :: z, kx, ky, alpha_MHD
- alpha_MHD = 0._dp
-
- parity: DO eo = 0,1
- zloop: DO iz = izgs,izge
- z = zarray(iz,eo)
-
- ! metric
- gxx(iz,eo) = 1._dp
- gxy(iz,eo) = 0._dp
- gxz(iz,eo) = 0._dp
- gyy(iz,eo) = 1._dp
- gyz(iz,eo) = 0._dp
- gzz(iz,eo) = 1._dp
- dxdR(iz,eo)= COS(z)
- dxdZ(iz,eo)= SIN(z)
-
- ! Relative strengh of radius
- hatR(iz,eo) = 1._dp
- hatZ(iz,eo) = 1._dp
-
- ! toroidal coordinates
- Rc (iz,eo) = hatR(iz,eo)
- phic(iz,eo) = z
- Zc (iz,eo) = hatZ(iz,eo)
-
- ! Jacobian
- Jacobian(iz,eo) = 1._dp
-
- ! Relative strengh of modulus of B
- hatB (iz,eo) = 1._dp
- hatB_NL(iz,eo) = 1._dp
-
- ! Derivative of the magnetic field strenght
- gradxB(iz,eo) = 0._dp ! Gene put a factor hatB^2 or 1/hatR^2 in this
- gradyB(iz,eo) = 0._dp
- gradzB(iz,eo) = 0._dp ! Gene put a factor hatB or 1/hatR in this
-
- ! Curvature operator
- DO iky = ikys, ikye
- ky = kyarray(iky)
- DO ikx= ikxs, ikxe
- kx = kxarray(ikx)
- Ckxky(iky, ikx, iz,eo) = -ky * hatB(iz,eo) ! .. multiply by hatB to cancel the 1/ hatB factor in moments_eqs_rhs.f90 routine
- ENDDO
- ENDDO
- ! coefficient in the front of parallel derivative
- gradz_coeff(iz,eo) = 1._dp / Jacobian(iz,eo) / hatB(iz,eo)
-
- ENDDO zloop
- ENDDO parity
+ ENDDO zloop
+ ENDDO parity
END SUBROUTINE eval_zpinch_geometry
!
!--------------------------------------------------------------------------------
!
subroutine eval_1D_geometry
! evaluate 1D perp geometry model
implicit none
REAL(dp) :: z, kx, ky
parity: DO eo = 0,1
zloop: DO iz = izs,ize
z = zarray(iz,eo)
! metric
gxx(iz,eo) = 1._dp
gxy(iz,eo) = 0._dp
gyy(iz,eo) = 1._dp
! Relative strengh of radius
hatR(iz,eo) = 1._dp
! Jacobian
Jacobian(iz,eo) = 1._dp
! Relative strengh of modulus of B
hatB(iz,eo) = 1._dp
! Curvature operator
DO iky = ikys, ikye
ky = kyarray(iky)
DO ikx= ikxs, ikxe
kx = kxarray(ikx)
Ckxky(ikx, iky, iz,eo) = -kx ! .. multiply by hatB to cancel the 1/ hatB factor in moments_eqs_rhs.f90 routine
ENDDO
ENDDO
! coefficient in the front of parallel derivative
gradz_coeff(iz,eo) = 1._dp
ENDDO zloop
ENDDO parity
END SUBROUTINE eval_1D_geometry
!
!--------------------------------------------------------------------------------
!
SUBROUTINE set_ikx_zBC_map
IMPLICIT NONE
REAL :: shift, kx_shift
! For periodic CHI BC or 0 dirichlet
LOGICAL :: PERIODIC_CHI_BC = .TRUE.
ALLOCATE(ikx_zBC_R(ikys:ikye,ikxs:ikxe))
ALLOCATE(ikx_zBC_L(ikys:ikye,ikxs:ikxe))
! No periodic connection for extension of the domain
IF(Nexc .GT. 1) PERIODIC_CHI_BC = .TRUE.
!! No shear case (simple id mapping)
!3 | 1 2 3 4 5 6 | ky = 3 dky
!2 ky | 1 2 3 4 5 6 | ky = 2 dky
!1 A | 1 2 3 4 5 6 | ky = 1 dky
!0 | -> kx | 1____2____3____4____5____6 | ky = 0 dky
!(e.g.) kx = 0 0.1 0.2 0.3 -0.2 -0.1 (dkx=free)
DO iky = ikys,ikye
DO ikx = ikxs,ikxe
ikx_zBC_L(iky,ikx) = ikx
ikx_zBC_R(iky,ikx) = ikx
ENDDO
ENDDO
! Modify connection map only at border of z
IF(SHEARED) THEN
! connection map BC of the RIGHT boundary (z=pi*Npol-dz) (even NZ)
!3 | 4 x x x 2 3 | ky = 3 dky
!2 ky | 3 4 x x 1 2 | ky = 2 dky
!1 A | 2 3 4 x 6 1 | ky = 1 dky
!0 | -> kx | 1____2____3____4____5____6 | ky = 0 dky
!kx = 0 0.1 0.2 0.3 -0.2 -0.1 (dkx=2pi*shear*npol*dky)
! connection map BC of the RIGHT boundary (z=pi*Npol-dz) (ODD NZ)
!3 | x x x 2 3 | ky = 3 dky
!2 ky | 3 x x 1 2 | ky = 2 dky
!1 A | 2 3 x 5 1 | ky = 1 dky
!0 | -> kx | 1____2____3____4____5 | ky = 0 dky
!kx = 0 0.1 0.2 -0.2 -0.1 (dkx=2pi*shear*npol*dky)
IF(contains_zmax) THEN ! Check if the process is at the end of the FT
DO iky = ikys,ikye
shift = 2._dp*PI*shear*kyarray(iky)*Npol
DO ikx = ikxs,ikxe
kx_shift = kxarray(ikx) + shift
! We use EPSILON() to treat perfect equality case
IF( ((kx_shift-EPSILON(kx_shift)) .GT. kx_max) .AND. (.NOT. PERIODIC_CHI_BC) )THEN ! outside of the frequ domain
ikx_zBC_R(iky,ikx) = -99
ELSE
ikx_zBC_R(iky,ikx) = ikx+(iky-1)*Nexc
IF( ikx_zBC_R(iky,ikx) .GT. Nkx ) &
ikx_zBC_R(iky,ikx) = ikx_zBC_R(iky,ikx) - Nkx
ENDIF
ENDDO
ENDDO
ENDIF
! connection map BC of the LEFT boundary (z=-pi*Npol)
!3 | x 5 6 1 x x | ky = 3 dky
!2 ky | 5 6 1 2 x x | ky = 2 dky
!1 A | 6 1 2 3 x 5 | ky = 1 dky
!0 | -> kx | 1____2____3____4____5____6 | ky = 0 dky
!(e.g.) kx = 0 0.1 0.2 0.3 -0.2 -0.1 (dkx=2pi*shear*npol*dky)
IF(contains_zmin) THEN ! Check if the process is at the start of the FT
DO iky = ikys,ikye
shift = 2._dp*PI*shear*kyarray(iky)*Npol
DO ikx = ikxs,ikxe
kx_shift = kxarray(ikx) - shift
! We use EPSILON() to treat perfect equality case
IF( ((kx_shift+EPSILON(kx_shift)) .LT. kx_min) .AND. (.NOT. PERIODIC_CHI_BC) ) THEN ! outside of the frequ domain
ikx_zBC_L(iky,ikx) = -99
ELSE
ikx_zBC_L(iky,ikx) = ikx-(iky-1)*Nexc
IF( ikx_zBC_L(iky,ikx) .LT. 1 ) &
ikx_zBC_L(iky,ikx) = ikx_zBC_L(iky,ikx) + Nkx
ENDIF
ENDDO
ENDDO
ENDIF
ELSE
ENDIF
END SUBROUTINE set_ikx_zBC_map
!
!--------------------------------------------------------------------------------
!
SUBROUTINE geometry_allocate_mem
! Curvature and geometry
CALL allocate_array( Ckxky, ikys,ikye, ikxs,ikxe,izgs,izge,0,1)
CALL allocate_array( Jacobian,izgs,izge, 0,1)
CALL allocate_array( gxx,izgs,izge, 0,1)
CALL allocate_array( gxy,izgs,izge, 0,1)
CALL allocate_array( gxz,izgs,izge, 0,1)
CALL allocate_array( gyy,izgs,izge, 0,1)
CALL allocate_array( gyz,izgs,izge, 0,1)
CALL allocate_array( gzz,izgs,izge, 0,1)
CALL allocate_array( gradxB,izgs,izge, 0,1)
CALL allocate_array( gradyB,izgs,izge, 0,1)
CALL allocate_array( gradzB,izgs,izge, 0,1)
CALL allocate_array( hatB,izgs,izge, 0,1)
CALL allocate_array( hatB_NL,izgs,izge, 0,1)
CALL allocate_array( hatR,izgs,izge, 0,1)
CALL allocate_array( hatZ,izgs,izge, 0,1)
CALL allocate_array( Rc,izgs,izge, 0,1)
CALL allocate_array( phic,izgs,izge, 0,1)
CALL allocate_array( Zc,izgs,izge, 0,1)
CALL allocate_array( dxdR,izgs,izge, 0,1)
CALL allocate_array( dxdZ,izgs,izge, 0,1)
call allocate_array(gradz_coeff,izgs,izge, 0,1)
CALL allocate_array( kparray, ikys,ikye, ikxs,ikxe,izgs,izge,0,1)
END SUBROUTINE geometry_allocate_mem
SUBROUTINE geometry_outputinputs(fidres, str)
! Write the input parameters to the results_xx.h5 file
USE futils, ONLY: attach
USE prec_const
IMPLICIT NONE
INTEGER, INTENT(in) :: fidres
CHARACTER(len=256), INTENT(in) :: str
CALL attach(fidres, TRIM(str),"geometry", geom)
CALL attach(fidres, TRIM(str), "q0", q0)
CALL attach(fidres, TRIM(str), "shear", shear)
CALL attach(fidres, TRIM(str), "eps", eps)
END SUBROUTINE geometry_outputinputs
end module geometry
diff --git a/src/grid_mod.F90 b/src/grid_mod.F90
index 719effe..9bba37a 100644
--- a/src/grid_mod.F90
+++ b/src/grid_mod.F90
@@ -1,630 +1,630 @@
MODULE grid
! Grid module for spatial discretization
USE prec_const
USE basic
IMPLICIT NONE
PRIVATE
! GRID Namelist
INTEGER, PUBLIC, PROTECTED :: pmaxe = 1 ! The maximal electron Hermite-moment computed
INTEGER, PUBLIC, PROTECTED :: jmaxe = 1 ! The maximal electron Laguerre-moment computed
INTEGER, PUBLIC, PROTECTED :: pmaxi = 1 ! The maximal ion Hermite-moment computed
INTEGER, PUBLIC, PROTECTED :: jmaxi = 1 ! The maximal ion Laguerre-moment computed
INTEGER, PUBLIC, PROTECTED :: maxj = 1 ! The maximal Laguerre-moment
INTEGER, PUBLIC, PROTECTED :: dmaxe = 1 ! The maximal full GF set of e-moments v^dmax
INTEGER, PUBLIC, PROTECTED :: dmaxi = 1 ! The maximal full GF set of i-moments v^dmax
INTEGER, PUBLIC, PROTECTED :: Nx = 16 ! Number of total internal grid points in x
REAL(dp), PUBLIC, PROTECTED :: Lx = 1._dp ! horizontal length of the spatial box
INTEGER, PUBLIC, PROTECTED :: Nexc = 1 ! factor to increase Lx when shear>0 (Lx = Nexc/kymin/shear)
INTEGER, PUBLIC, PROTECTED :: Ny = 16 ! Number of total internal grid points in y
REAL(dp), PUBLIC, PROTECTED :: Ly = 1._dp ! vertical length of the spatial box
INTEGER, PUBLIC, PROTECTED :: Nz = 1 ! Number of total perpendicular planes
REAL(dp), PUBLIC, PROTECTED :: Npol = 1._dp ! number of poloidal turns
INTEGER, PUBLIC, PROTECTED :: Odz = 4 ! order of z interp and derivative schemes
INTEGER, PUBLIC, PROTECTED :: Nkx = 8 ! Number of total internal grid points in kx
REAL(dp), PUBLIC, PROTECTED :: Lkx = 1._dp ! horizontal length of the fourier box
INTEGER, PUBLIC, PROTECTED :: Nky = 16 ! Number of total internal grid points in ky
REAL(dp), PUBLIC, PROTECTED :: Lky = 1._dp ! vertical length of the fourier box
REAL(dp), PUBLIC, PROTECTED :: kpar = 0_dp ! parallel wave vector component
! For Orszag filter
REAL(dp), PUBLIC, PROTECTED :: two_third_kxmax
REAL(dp), PUBLIC, PROTECTED :: two_third_kymax
REAL(dp), PUBLIC :: two_third_kpmax
! 1D Antialiasing arrays (2/3 rule)
REAL(dp), DIMENSION(:), ALLOCATABLE, PUBLIC :: AA_x
REAL(dp), DIMENSION(:), ALLOCATABLE, PUBLIC :: AA_y
! Grids containing position in physical space
REAL(dp), DIMENSION(:), ALLOCATABLE, PUBLIC :: xarray
REAL(dp), DIMENSION(:), ALLOCATABLE, PUBLIC :: yarray
! Local and global z grids, 2D since it has to store odd and even grids
REAL(dp), DIMENSION(:,:), ALLOCATABLE, PUBLIC :: zarray
REAL(dp), DIMENSION(:), ALLOCATABLE, PUBLIC :: zarray_full
! local z weights for computing simpson rule
INTEGER, DIMENSION(:), ALLOCATABLE, PUBLIC :: zweights_SR
REAL(dp), PUBLIC, PROTECTED :: deltax, deltay, deltaz, inv_deltaz
REAL(dp), PUBLIC, PROTECTED :: diff_kx_coeff, diff_ky_coeff, diff_dz_coeff
INTEGER, PUBLIC, PROTECTED :: ixs, ixe, iys, iye, izs, ize
INTEGER, PUBLIC, PROTECTED :: izgs, izge ! ghosts
LOGICAL, PUBLIC, PROTECTED :: SG = .true.! shifted grid flag
INTEGER, PUBLIC :: ir,iz ! counters
! Data about parallel distribution for ky.kx
integer(C_INTPTR_T), PUBLIC :: local_nkx, local_nky
integer(C_INTPTR_T), PUBLIC :: local_nkx_offset, local_nky_offset
INTEGER, PUBLIC :: local_nkp
INTEGER, DIMENSION(:), ALLOCATABLE, PUBLIC :: counts_nkx, counts_nky
INTEGER, DIMENSION(:), ALLOCATABLE, PUBLIC :: displs_nkx, displs_nky
! "" for p
INTEGER, PUBLIC :: local_np_e, local_np_i
INTEGER, PUBLIC :: total_np_e, total_np_i, Np_e, Np_i
integer(C_INTPTR_T), PUBLIC :: local_np_e_offset, local_np_i_offset
INTEGER, DIMENSION(:), ALLOCATABLE, PUBLIC :: rcv_p_e, rcv_p_i
INTEGER, DIMENSION(:), ALLOCATABLE, PUBLIC :: dsp_p_e, dsp_p_i
! "" for z
INTEGER, PUBLIC :: local_nz
INTEGER, PUBLIC :: total_nz
integer(C_INTPTR_T), PUBLIC :: local_nz_offset
INTEGER, DIMENSION(:), ALLOCATABLE, PUBLIC :: counts_nz
INTEGER, DIMENSION(:), ALLOCATABLE, PUBLIC :: displs_nz
! "" for j (not parallelized)
INTEGER, PUBLIC :: local_nj_e, local_nj_i, Nj_e, Nj_i
! Grids containing position in fourier space
REAL(dp), DIMENSION(:), ALLOCATABLE, PUBLIC :: kxarray, kxarray_full
REAL(dp), DIMENSION(:), ALLOCATABLE, PUBLIC :: kyarray, kyarray_full
! Kperp array depends on kx, ky, z (geometry), eo (even or odd zgrid)
REAL(dp), DIMENSION(:,:,:,:), ALLOCATABLE, PUBLIC :: kparray
REAL(dp), PUBLIC, PROTECTED :: deltakx, deltaky, kx_max, ky_max, kx_min, ky_min!, kp_max
REAL(dp), PUBLIC, PROTECTED :: local_kxmax, local_kymax
INTEGER, PUBLIC, PROTECTED :: ikxs, ikxe, ikys, ikye!, ikps, ikpe
INTEGER, PUBLIC, PROTECTED :: ikx_0, iky_0, ikx_max, iky_max ! Indices of k-grid origin and max
INTEGER, PUBLIC :: ikx, iky, ip, ij, ikp, pp2, eo ! counters
LOGICAL, PUBLIC, PROTECTED :: contains_kx0 = .false. ! flag if the proc contains kx=0 index
LOGICAL, PUBLIC, PROTECTED :: contains_ky0 = .false. ! flag if the proc contains ky=0 index
LOGICAL, PUBLIC, PROTECTED :: contains_kymax = .false. ! flag if the proc contains kx=kxmax index
LOGICAL, PUBLIC, PROTECTED :: contains_zmax = .false. ! flag if the proc contains z=pi-dz index
LOGICAL, PUBLIC, PROTECTED :: contains_zmin = .false. ! flag if the proc contains z=-pi index
LOGICAL, PUBLIC, PROTECTED :: SINGLE_KY = .false. ! to check if it is a single non 0 ky simulation
! Grid containing the polynomials degrees
INTEGER, DIMENSION(:), ALLOCATABLE, PUBLIC :: parray_e, parray_e_full
INTEGER, DIMENSION(:), ALLOCATABLE, PUBLIC :: parray_i, parray_i_full
INTEGER, DIMENSION(:), ALLOCATABLE, PUBLIC :: jarray_e, jarray_e_full
INTEGER, DIMENSION(:), ALLOCATABLE, PUBLIC :: jarray_i, jarray_i_full
INTEGER, PUBLIC, PROTECTED :: ips_e,ipe_e, ijs_e,ije_e ! Start and end indices for pol. deg.
INTEGER, PUBLIC, PROTECTED :: ips_i,ipe_i, ijs_i,ije_i
INTEGER, PUBLIC, PROTECTED :: ipgs_e,ipge_e, ijgs_e,ijge_e ! Ghosts start and end indices
INTEGER, PUBLIC, PROTECTED :: ipgs_i,ipge_i, ijgs_i,ijge_i
INTEGER, PUBLIC, PROTECTED :: deltape, ip0_e, ip1_e, ip2_e, ip3_e ! Pgrid spacing and moment 0,1,2 index
INTEGER, PUBLIC, PROTECTED :: deltapi, ip0_i, ip1_i, ip2_i, ip3_i
LOGICAL, PUBLIC, PROTECTED :: CONTAINS_ip0_e, CONTAINS_ip0_i
LOGICAL, PUBLIC, PROTECTED :: CONTAINS_ip1_e, CONTAINS_ip1_i
LOGICAL, PUBLIC, PROTECTED :: CONTAINS_ip2_e, CONTAINS_ip2_i
LOGICAL, PUBLIC, PROTECTED :: CONTAINS_ip3_e, CONTAINS_ip3_i
LOGICAL, PUBLIC, PROTECTED :: SOLVE_POISSON, SOLVE_AMPERE
INTEGER, PUBLIC, PROTECTED :: ij0_i, ij0_e
! Usefull inverse numbers
REAL(dp), PUBLIC, PROTECTED :: inv_Nx, inv_Ny, inv_Nz
! Public Functions
PUBLIC :: init_1Dgrid_distr
PUBLIC :: set_pgrid, set_jgrid
PUBLIC :: set_kxgrid, set_kygrid, set_zgrid
PUBLIC :: grid_readinputs, grid_outputinputs
PUBLIC :: bare, bari
! Precomputations
real(dp), PUBLIC, PROTECTED :: pmaxe_dp, pmaxi_dp, jmaxe_dp,jmaxi_dp
CONTAINS
SUBROUTINE grid_readinputs
! Read the input parameters
USE prec_const
IMPLICIT NONE
INTEGER :: lu_in = 90 ! File duplicated from STDIN
NAMELIST /GRID/ pmaxe, jmaxe, pmaxi, jmaxi, &
Nx, Lx, Nexc, Ny, Ly, Nz, Npol, SG
READ(lu_in,grid)
IF(Nz .EQ. 1) & ! overwrite SG option if Nz = 1 for safety of use
SG = .FALSE.
!! Compute the maximal degree of full GF moments set
! i.e. : all moments N_a^pj s.t. p+2j<=d are simulated (see GF closure)
dmaxe = min(pmaxe,2*jmaxe+1)
dmaxi = min(pmaxi,2*jmaxi+1)
! Usefull precomputations
inv_Nx = 1._dp/REAL(Nx,dp)
inv_Ny = 1._dp/REAL(Ny,dp)
END SUBROUTINE grid_readinputs
SUBROUTINE init_1Dgrid_distr
! write(*,*) Nx
local_nky = (Ny/2+1)/num_procs_ky
! write(*,*) local_nkx
local_nky_offset = rank_ky*local_nky
if (rank_ky .EQ. num_procs_ky-1) local_nky = (Ny/2+1)-local_nky_offset
END SUBROUTINE init_1Dgrid_distr
SUBROUTINE set_pgrid
USE prec_const
USE model, ONLY: beta ! To know if we solve ampere or not and put odd p moments
IMPLICIT NONE
INTEGER :: ip, istart, iend, in
! If no parallel dim (Nz=1) and no EM effects (beta=0), the moment hierarchy
!! is separable between odds and even P and since the energy is injected in
!! P=0 and P=2 for density/temperature gradients there is no need of
!! simulating the odd p which will only be damped.
!! We define in this case a grid Parray = 0,2,4,...,Pmax i.e. deltap = 2
!! instead of 1 to spare computation
IF((Nz .EQ. 1) .AND. (beta .EQ. 0._dp)) THEN
deltape = 2; deltapi = 2;
pp2 = 1; ! index p+2 is ip+1
ELSE
deltape = 1; deltapi = 1;
pp2 = 2; ! index p+2 is ip+2
ENDIF
! Total number of Hermite polynomials we will evolve
total_np_e = (Pmaxe/deltape) + 1
total_np_i = (Pmaxi/deltapi) + 1
Np_e = total_np_e ! Reduced names (redundant)
Np_i = total_np_i
! Build the full grids on process 0 to diagnose it without comm
ALLOCATE(parray_e_full(1:total_np_e))
ALLOCATE(parray_i_full(1:total_np_i))
! P
DO ip = 1,total_np_e; parray_e_full(ip) = (ip-1)*deltape; END DO
DO ip = 1,total_np_i; parray_i_full(ip) = (ip-1)*deltapi; END DO
!! Parallel data distribution
! Local data distribution
CALL decomp1D(total_np_e, num_procs_p, rank_p, ips_e, ipe_e)
CALL decomp1D(total_np_i, num_procs_p, rank_p, ips_i, ipe_i)
local_np_e = ipe_e - ips_e + 1
local_np_i = ipe_i - ips_i + 1
! Ghosts boundaries
ipgs_e = ips_e - 2/deltape; ipge_e = ipe_e + 2/deltape;
ipgs_i = ips_i - 2/deltapi; ipge_i = ipe_i + 2/deltapi;
! List of shift and local numbers between the different processes (used in scatterv and gatherv)
ALLOCATE(rcv_p_e (1:num_procs_p))
ALLOCATE(rcv_p_i (1:num_procs_p))
ALLOCATE(dsp_p_e (1:num_procs_p))
ALLOCATE(dsp_p_i (1:num_procs_p))
DO in = 0,num_procs_p-1
CALL decomp1D(total_np_e, num_procs_p, in, istart, iend)
rcv_p_e(in+1) = iend-istart+1
dsp_p_e(in+1) = istart-1
CALL decomp1D(total_np_i, num_procs_p, in, istart, iend)
rcv_p_i(in+1) = iend-istart+1
dsp_p_i(in+1) = istart-1
ENDDO
!! local grid computations
! Flag to avoid unnecessary logical operations
CONTAINS_ip0_e = .FALSE.; CONTAINS_ip1_e = .FALSE.
CONTAINS_ip2_e = .FALSE.; CONTAINS_ip3_e = .FALSE.
CONTAINS_ip0_i = .FALSE.; CONTAINS_ip1_i = .FALSE.
CONTAINS_ip2_i = .FALSE.; CONTAINS_ip3_i = .FALSE.
SOLVE_POISSON = .FALSE.; SOLVE_AMPERE = .FALSE.
ALLOCATE(parray_e(ipgs_e:ipge_e))
ALLOCATE(parray_i(ipgs_i:ipge_i))
DO ip = ipgs_e,ipge_e
parray_e(ip) = (ip-1)*deltape
! Storing indices of particular degrees for fluid moments computations
SELECT CASE (parray_e(ip))
CASE(0); ip0_e = ip; CONTAINS_ip0_e = .TRUE.
CASE(1); ip1_e = ip; CONTAINS_ip1_e = .TRUE.
CASE(2); ip2_e = ip; CONTAINS_ip2_e = .TRUE.
CASE(3); ip3_e = ip; CONTAINS_ip3_e = .TRUE.
END SELECT
END DO
DO ip = ipgs_i,ipge_i
parray_i(ip) = (ip-1)*deltapi
! Storing indices of particular degrees for fluid moments computations
SELECT CASE (parray_i(ip))
CASE(0); ip0_i = ip; CONTAINS_ip0_i = .TRUE.
CASE(1); ip1_i = ip; CONTAINS_ip1_i = .TRUE.
CASE(2); ip2_i = ip; CONTAINS_ip2_i = .TRUE.
CASE(3); ip3_i = ip; CONTAINS_ip3_i = .TRUE.
END SELECT
END DO
IF(CONTAINS_ip0_e .AND. CONTAINS_ip0_i) SOLVE_POISSON = .TRUE.
IF(CONTAINS_ip1_e .AND. CONTAINS_ip1_i) SOLVE_AMPERE = .TRUE.
!DGGK operator uses moments at index p=2 (ip=3) for the p=0 term so the
! process that contains ip=1 MUST contain ip=3 as well for both e and i.
IF(((ips_e .EQ. ip0_e) .OR. (ips_i .EQ. ip0_e)) .AND. ((ipe_e .LT. ip2_e) .OR. (ipe_i .LT. ip2_i)))&
WRITE(*,*) "Warning : distribution along p may not work with DGGK"
! Precomputations
pmaxe_dp = real(pmaxe,dp)
pmaxi_dp = real(pmaxi,dp)
! Overwrite SOLVE_AMPERE flag if beta is zero
IF(beta .EQ. 0._dp) THEN
SOLVE_AMPERE = .FALSE.
ENDIF
END SUBROUTINE set_pgrid
SUBROUTINE set_jgrid
USE prec_const
IMPLICIT NONE
INTEGER :: ij
! Total number of J degrees
Nj_e = jmaxe+1
Nj_i = jmaxi+1
! Build the full grids on process 0 to diagnose it without comm
ALLOCATE(jarray_e_full(1:jmaxe+1))
ALLOCATE(jarray_i_full(1:jmaxi+1))
! J
DO ij = 1,jmaxe+1; jarray_e_full(ij) = (ij-1); END DO
DO ij = 1,jmaxi+1; jarray_i_full(ij) = (ij-1); END DO
! Local data
ijs_e = 1; ije_e = jmaxe + 1
ijs_i = 1; ije_i = jmaxi + 1
! Ghosts boundaries
ijgs_e = ijs_e - 1; ijge_e = ije_e + 1;
ijgs_i = ijs_i - 1; ijge_i = ije_i + 1;
! Local number of J
local_nj_e = ijge_e - ijgs_e + 1
local_nj_i = ijge_i - ijgs_i + 1
ALLOCATE(jarray_e(ijgs_e:ijge_e))
ALLOCATE(jarray_i(ijgs_i:ijge_i))
DO ij = ijgs_e,ijge_e; jarray_e(ij) = ij-1; END DO
DO ij = ijgs_i,ijge_i; jarray_i(ij) = ij-1; END DO
! Precomputations
maxj = MAX(jmaxi, jmaxe)
jmaxe_dp = real(jmaxe,dp)
jmaxi_dp = real(jmaxi,dp)
! j=0 indices
- DO ij = ijs_e,ij0_e; IF(jarray_e(ij) .EQ. 0) ij0_e = ij; END DO
- DO ij = ijs_i,ij0_i; IF(jarray_i(ij) .EQ. 0) ij0_i = ij; END DO
+ DO ij = ijs_e,ije_e; IF(jarray_e(ij) .EQ. 0) ij0_e = ij; END DO
+ DO ij = ijs_i,ije_i; IF(jarray_i(ij) .EQ. 0) ij0_i = ij; END DO
END SUBROUTINE set_jgrid
SUBROUTINE set_kygrid
USE prec_const
USE model, ONLY: LINEARITY, N_HD
IMPLICIT NONE
INTEGER :: i_, in, istart, iend
Nky = Ny/2+1 ! Defined only on positive kx since fields are real
! Grid spacings
IF (Ny .EQ. 1) THEN
deltaky = 2._dp*PI/Ly
ky_max = deltaky
ky_min = deltaky
ELSE
deltaky = 2._dp*PI/Ly
ky_max = (Nky-1)*deltaky
ky_min = deltaky
ENDIF
! Build the full grids on process 0 to diagnose it without comm
ALLOCATE(kyarray_full(1:Nky))
DO iky = 1,Nky
kyarray_full(iky) = REAL(iky-1,dp) * deltaky
END DO
!! Parallel distribution
ikys = local_nky_offset + 1
ikye = ikys + local_nky - 1
ALLOCATE(kyarray(ikys:ikye))
local_kymax = 0._dp
! List of shift and local numbers between the different processes (used in scatterv and gatherv)
ALLOCATE(counts_nky (1:num_procs_ky))
ALLOCATE(displs_nky (1:num_procs_ky))
DO in = 0,num_procs_ky-1
CALL decomp1D(Nky, num_procs_ky, in, istart, iend)
counts_nky(in+1) = iend-istart+1
displs_nky(in+1) = istart-1
ENDDO
! Creating a grid ordered as dk*(0 1 2 3)
DO iky = ikys,ikye
IF(Ny .EQ. 1) THEN
kyarray(iky) = deltaky
kyarray_full(iky) = deltaky
SINGLE_KY = .TRUE.
ELSE
kyarray(iky) = REAL(iky-1,dp) * deltaky
ENDIF
! Finding kx=0
IF (kyarray(iky) .EQ. 0) THEN
iky_0 = iky
contains_ky0 = .true.
ENDIF
! Finding local kxmax value
IF (ABS(kyarray(iky)) .GT. local_kymax) THEN
local_kymax = ABS(kyarray(iky))
ENDIF
! Finding kxmax idx
IF (kyarray(iky) .EQ. ky_max) THEN
iky_max = iky
contains_kymax = .true.
ENDIF
END DO
! Orszag 2/3 filter
two_third_kymax = 2._dp/3._dp*deltaky*(Nky-1)
! For hyperdiffusion
IF(LINEARITY.EQ.'linear') THEN
diff_ky_coeff= (1._dp/ky_max)**N_HD
ELSE
diff_ky_coeff= (1._dp/two_third_kymax)**N_HD
ENDIF
ALLOCATE(AA_y(ikys:ikye))
DO iky = ikys,ikye
IF ( (kyarray(iky) .LT. two_third_kymax) .OR. (LINEARITY .EQ. 'linear')) THEN
AA_y(iky) = 1._dp;
ELSE
AA_y(iky) = 0._dp;
ENDIF
END DO
END SUBROUTINE set_kygrid
SUBROUTINE set_kxgrid(shear)
USE prec_const
USE model, ONLY: LINEARITY, N_HD
IMPLICIT NONE
REAL(dp), INTENT(IN) :: shear
REAL :: Lx_adapted
INTEGER :: i_, counter
IF(shear .GT. 0._dp) THEN
IF(my_id.EQ.0) write(*,*) 'Magnetic shear detected: set up sheared kx grid..'
! mininal size of box in x to respect dkx = 2pi shear dky
Lx_adapted = Ly/(2._dp*pi*shear*Npol)
! Put Nexc to 0 so that it is computed from a target value Lx
IF(Nexc .EQ. 0) THEN
Nexc = CEILING(0.9 * Lx/Lx_adapted)
IF(my_id.EQ.0) write(*,*) 'Adapted Nexc =', Nexc
ENDIF
! x length is adapted
Lx = Lx_adapted*Nexc
ENDIF
Nkx = Nx;
! Local data
! Start and END indices of grid
ikxs = 1
ikxe = Nkx
local_nkx = ikxe - ikxs + 1
ALLOCATE(kxarray(ikxs:ikxe))
ALLOCATE(kxarray_full(1:Nkx))
IF (Nx .EQ. 1) THEN
deltakx = 1._dp
kxarray(1) = 0._dp
ikx_0 = 1
contains_kx0 = .true.
kx_max = 0._dp
ikx_max = 1
kx_min = 0._dp
kxarray_full(1) = 0._dp
local_kxmax = 0._dp
ELSE ! Build apprpopriate grid
deltakx = 2._dp*PI/Lx
IF(MODULO(Nkx,2) .EQ. 0) THEN ! Even number of Nkx (-2 -1 0 1 2 3)
kx_max = (Nkx/2)*deltakx
kx_min = -kx_max+deltakx
! Creating a grid ordered as dk*(0 1 2 3 -2 -1)
local_kxmax = 0._dp
DO ikx = ikxs,ikxe
kxarray(ikx) = deltakx*(MODULO(ikx-1,Nkx/2)-Nkx/2*FLOOR(2.*real(ikx-1)/real(Nkx)))
if (ikx .EQ. Nx/2+1) kxarray(ikx) = -kxarray(ikx)
! Finding kx=0
IF (kxarray(ikx) .EQ. 0) THEN
ikx_0 = ikx
contains_kx0 = .true.
ENDIF
! Finding local kxmax
IF (ABS(kxarray(ikx)) .GT. local_kxmax) THEN
local_kxmax = ABS(kxarray(ikx))
ENDIF
! Finding kxmax
IF (kxarray(ikx) .EQ. kx_max) ikx_max = ikx
END DO
! Build the full grids on process 0 to diagnose it without comm
! kx
DO ikx = 1,Nkx
kxarray_full(ikx) = deltakx*(MODULO(ikx-1,Nkx/2)-Nkx/2*FLOOR(2.*real(ikx-1)/real(Nkx)))
IF (ikx .EQ. Nx/2+1) kxarray_full(ikx) = -kxarray_full(ikx)
END DO
ELSE ! Odd number of kx (-2 -1 0 1 2)
kx_max = (Nkx-1)/2*deltakx
kx_min = -kx_max
! Creating a grid ordered as dk*(0 1 2 -2 -1)
local_kxmax = 0._dp
DO ikx = ikxs,ikxe
IF(ikx .LE. (Nkx-1)/2+1) THEN
kxarray(ikx) = deltakx*(ikx-1)
ELSE
kxarray(ikx) = deltakx*(ikx-Nkx-1)
ENDIF
! Finding kx=0
IF (kxarray(ikx) .EQ. 0) THEN
ikx_0 = ikx
contains_kx0 = .true.
ENDIF
! Finding local kxmax
IF (ABS(kxarray(ikx)) .GT. local_kxmax) THEN
local_kxmax = ABS(kxarray(ikx))
ENDIF
! Finding kxmax
IF (kxarray(ikx) .EQ. kx_max) ikx_max = ikx
END DO
! Build the full grids on process 0 to diagnose it without comm
! kx
DO ikx = 1,Nkx
IF(ikx .LE. (Nkx-1)/2+1) THEN
kxarray_full(ikx) = deltakx*(ikx-1)
ELSE
kxarray_full(ikx) = deltakx*(ikx-Nkx-1)
ENDIF
END DO
ENDIF
ENDIF
! Orszag 2/3 filter
two_third_kxmax = 2._dp/3._dp*kx_max;
! For hyperdiffusion
IF(LINEARITY.EQ.'linear') THEN
diff_kx_coeff= (1._dp/kx_max)**N_HD
ELSE
diff_kx_coeff= (1._dp/two_third_kxmax)**N_HD
ENDIF
! Antialiasing filter
ALLOCATE(AA_x(ikxs:ikxe))
DO ikx = ikxs,ikxe
IF ( ((kxarray(ikx) .GT. -two_third_kxmax) .AND. &
(kxarray(ikx) .LT. two_third_kxmax)) .OR. (LINEARITY .EQ. 'linear')) THEN
AA_x(ikx) = 1._dp;
ELSE
AA_x(ikx) = 0._dp;
ENDIF
END DO
END SUBROUTINE set_kxgrid
SUBROUTINE set_zgrid
USE prec_const
USE model, ONLY: mu_z, N_HD
IMPLICIT NONE
INTEGER :: i_, fid
REAL :: grid_shift, Lz, zmax, zmin
INTEGER :: ip, istart, iend, in
total_nz = Nz
! Length of the flux tube (in ballooning angle)
Lz = 2_dp*pi*Npol
! Z stepping (#interval = #points since periodic)
deltaz = Lz/REAL(Nz,dp)
inv_deltaz = 1._dp/deltaz
! Parallel hyperdiffusion coefficient
IF(mu_z .GT. 0) THEN
diff_dz_coeff = REAL((imagu*deltaz/2._dp)**4) ! adaptive fourth derivative (~GENE)
ELSE
diff_dz_coeff = 1._dp ! non adaptive (positive sign to compensate mu_z neg)
ENDIF
IF (SG) THEN
grid_shift = deltaz/2._dp
ELSE
grid_shift = 0._dp
ENDIF
! Build the full grids on process 0 to diagnose it without comm
ALLOCATE(zarray_full(1:Nz))
IF (Nz .EQ. 1) Npol = 0
zmax = 0; zmin = 0;
DO iz = 1,total_nz ! z in [-pi pi-dz] x Npol
zarray_full(iz) = REAL(iz-1,dp)*deltaz - Lz/2._dp
IF(zarray_full(iz) .GT. zmax) zmax = zarray_full(iz)
IF(zarray_full(iz) .LT. zmin) zmin = zarray_full(iz)
END DO
!! Parallel data distribution
! Local data distribution
CALL decomp1D(total_nz, num_procs_z, rank_z, izs, ize)
local_nz = ize - izs + 1
! Ghosts boundaries (depend on the order of z operators)
IF(Nz .EQ. 1) THEN
izgs = izs; izge = ize;
zarray(izs,:) = 0; zarray_full(izs) = 0;
ELSEIF(Nz .GE. 4) THEN
izgs = izs - 2; izge = ize + 2;
ELSE
ERROR STOP 'Error stop: Nz is not appropriate!!'
ENDIF
! List of shift and local numbers between the different processes (used in scatterv and gatherv)
ALLOCATE(counts_nz (1:num_procs_z))
ALLOCATE(displs_nz (1:num_procs_z))
DO in = 0,num_procs_z-1
CALL decomp1D(total_nz, num_procs_z, in, istart, iend)
counts_nz(in+1) = iend-istart+1
displs_nz(in+1) = istart-1
ENDDO
! Local z array
ALLOCATE(zarray(izgs:izge,0:1))
DO iz = izgs,izge
IF(iz .EQ. 0) THEN
zarray(iz,0) = zarray_full(total_nz)
zarray(iz,1) = zarray_full(total_nz) + grid_shift
ELSEIF(iz .EQ. -1) THEN
zarray(iz,0) = zarray_full(total_nz-1)
zarray(iz,1) = zarray_full(total_nz-1) + grid_shift
ELSEIF(iz .EQ. total_nz + 1) THEN
zarray(iz,0) = zarray_full(1)
zarray(iz,1) = zarray_full(1) + grid_shift
ELSEIF(iz .EQ. total_nz + 2) THEN
zarray(iz,0) = zarray_full(2)
zarray(iz,1) = zarray_full(2) + grid_shift
ELSE
zarray(iz,0) = zarray_full(iz)
zarray(iz,1) = zarray_full(iz) + grid_shift
ENDIF
ENDDO
IF(abs(zarray(izs,0) - zmin) .LT. EPSILON(zmin)) &
contains_zmin = .TRUE.
IF(abs(zarray(ize,0) - zmax) .LT. EPSILON(zmax)) &
contains_zmax = .TRUE.
! Weitghs for Simpson rule
ALLOCATE(zweights_SR(izs:ize))
DO iz = izs,ize
IF(MODULO(iz,2) .EQ. 1) THEN ! odd iz
zweights_SR(iz) = 2._dp
ELSE ! even iz
zweights_SR(iz) = 4._dp
ENDIF
ENDDO
END SUBROUTINE set_zgrid
SUBROUTINE grid_outputinputs(fidres, str)
! Write the input parameters to the results_xx.h5 file
USE futils, ONLY: attach
USE prec_const
IMPLICIT NONE
INTEGER, INTENT(in) :: fidres
CHARACTER(len=256), INTENT(in) :: str
CALL attach(fidres, TRIM(str), "pmaxe", pmaxe)
CALL attach(fidres, TRIM(str), "jmaxe", jmaxe)
CALL attach(fidres, TRIM(str), "pmaxi", pmaxi)
CALL attach(fidres, TRIM(str), "jmaxi", jmaxi)
CALL attach(fidres, TRIM(str), "Nx", Nx)
CALL attach(fidres, TRIM(str), "Lx", Lx)
CALL attach(fidres, TRIM(str), "Nexc", Nexc)
CALL attach(fidres, TRIM(str), "Ny", Ny)
CALL attach(fidres, TRIM(str), "Ly", Ly)
CALL attach(fidres, TRIM(str), "Nz", Nz)
CALL attach(fidres, TRIM(str), "Nkx", Nkx)
CALL attach(fidres, TRIM(str), "Lkx", Lkx)
CALL attach(fidres, TRIM(str), "Nky", Nky)
CALL attach(fidres, TRIM(str), "Lky", Lky)
CALL attach(fidres, TRIM(str), "SG", SG)
END SUBROUTINE grid_outputinputs
FUNCTION bare(p_,j_)
IMPLICIT NONE
INTEGER :: bare, p_, j_
bare = (jmaxe+1)*p_ + j_ + 1
END FUNCTION
FUNCTION bari(p_,j_)
IMPLICIT NONE
INTEGER :: bari, p_, j_
bari = (jmaxi+1)*p_ + j_ + 1
END FUNCTION
SUBROUTINE decomp1D( n, numprocs, myid, s, e )
INTEGER :: n, numprocs, myid, s, e
INTEGER :: nlocal
INTEGER :: deficit
nlocal = n / numprocs
s = myid * nlocal + 1
deficit = MOD(n,numprocs)
s = s + MIN(myid,deficit)
IF (myid .LT. deficit) nlocal = nlocal + 1
e = s + nlocal - 1
IF (e .GT. n .OR. myid .EQ. numprocs-1) e = n
END SUBROUTINE decomp1D
END MODULE grid
diff --git a/src/inital.F90 b/src/inital.F90
index 8ccb5f2..6d4fe5a 100644
--- a/src/inital.F90
+++ b/src/inital.F90
@@ -1,517 +1,517 @@
!******************************************************************************!
!!!!!! initialize the moments and load/build coeff tables
!******************************************************************************!
SUBROUTINE inital
USE basic, ONLY: my_id
USE initial_par, ONLY: INIT_OPT
USE time_integration, ONLY: set_updatetlevel
USE collision, ONLY: load_COSOlver_mat, cosolver_coll
USE closure, ONLY: apply_closure_model
USE ghosts, ONLY: update_ghosts_moments, update_ghosts_EM
USE restarts, ONLY: load_moments, job2load
USE numerics, ONLY: play_with_modes, save_EM_ZF_modes
USE processing, ONLY: compute_fluid_moments
USE model, ONLY: KIN_E, LINEARITY
USE nonlinear, ONLY: compute_Sapj, nonlinear_init
IMPLICIT NONE
CALL set_updatetlevel(1)
!!!!!! Set the moments arrays Nepj, Nipj and phi!!!!!!
! through loading a previous state
IF ( job2load .GE. 0 ) THEN
IF (my_id .EQ. 0) WRITE(*,*) 'Load moments'
CALL load_moments ! get N_0
CALL update_ghosts_moments
CALL solve_EM_fields ! compute phi_0=phi(N_0)
CALL update_ghosts_EM
! through initialization
ELSE
SELECT CASE (INIT_OPT)
! set phi with noise and set moments to 0
CASE ('phi')
IF (my_id .EQ. 0) WRITE(*,*) 'Init noisy phi'
CALL init_phi
CALL update_ghosts_EM
! set moments_00 (GC density) with noise and compute phi afterwards
CASE('mom00')
IF (my_id .EQ. 0) WRITE(*,*) 'Init noisy gyrocenter density'
CALL init_gyrodens ! init only gyrocenter density
CALL update_ghosts_moments
CALL solve_EM_fields
CALL update_ghosts_EM
! init all moments randomly (unadvised)
CASE('allmom')
IF (my_id .EQ. 0) WRITE(*,*) 'Init noisy moments'
CALL init_moments ! init all moments
CALL update_ghosts_moments
CALL solve_EM_fields
CALL update_ghosts_EM
! init a gaussian blob in gyrodens
CASE('blob')
IF (my_id .EQ. 0) WRITE(*,*) '--init a blob'
CALL initialize_blob
CALL update_ghosts_moments
CALL solve_EM_fields
CALL update_ghosts_EM
! init moments 00 with a power law similarly to GENE
CASE('ppj')
IF (my_id .EQ. 0) WRITE(*,*) 'ppj init ~ GENE'
call init_ppj
CALL update_ghosts_moments
CALL solve_EM_fields
CALL update_ghosts_EM
END SELECT
ENDIF
! closure of j>J, p>P and j<0, p<0 moments
IF (my_id .EQ. 0) WRITE(*,*) 'Apply closure'
CALL apply_closure_model
! ghosts for p parallelization
IF (my_id .EQ. 0) WRITE(*,*) 'Ghosts communication'
CALL update_ghosts_moments
CALL update_ghosts_EM
!! End of phi and moments initialization
! Save (kx,0) and (0,ky) modes for num exp
CALL save_EM_ZF_modes
! Freeze/Wipe some selected modes (entropy,zonal,turbulent)
CALL play_with_modes
! Load the COSOlver collision operator coefficients
IF(cosolver_coll) &
CALL load_COSOlver_mat
!! Preparing auxiliary arrays at initial state
! particle density, fluid velocity and temperature (used in diagnose)
IF (my_id .EQ. 0) WRITE(*,*) 'Computing fluid moments'
CALL compute_fluid_moments
! init auxval for nonlinear
CALL nonlinear_init
! compute nonlinear for t=0 diagnostic
CALL compute_Sapj ! compute S_0 = S(phi_0,N_0)
END SUBROUTINE inital
!******************************************************************************!
!******************************************************************************!
!!!!!!! Initialize all the moments randomly
!******************************************************************************!
SUBROUTINE init_moments
USE basic
USE grid
USE initial_par,ONLY: iseed, init_noiselvl, init_background
USE fields, ONLY: moments_e, moments_i
USE prec_const, ONLY: dp
USE utility, ONLY: checkfield
USE model, ONLY : LINEARITY, KIN_E
IMPLICIT NONE
REAL(dp) :: noise
INTEGER, DIMENSION(12) :: iseedarr
! Seed random number generator
iseedarr(:)=iseed
CALL RANDOM_SEED(PUT=iseedarr+my_id)
!**** Broad noise initialization *******************************************
! Electron init
IF(KIN_E) THEN
DO ip=ips_e,ipe_e
DO ij=ijs_e,ije_e
DO ikx=ikxs,ikxe
DO iky=ikys,ikye
DO iz=izs,ize
CALL RANDOM_NUMBER(noise)
moments_e(ip,ij,iky,ikx,iz,:) = (init_background + init_noiselvl*(noise-0.5_dp))
END DO
END DO
END DO
IF ( contains_ky0 ) THEN
DO iky=2,Nky/2 !symmetry at ky = 0 for all z
moments_e(ip,ij,iky_0,ikx,:,:) = moments_e( ip,ij,iky_0,Nkx+2-ikx,:, :)
END DO
ENDIF
END DO
END DO
ENDIF
! Ion init
DO ip=ips_i,ipe_i
DO ij=ijs_i,ije_i
DO ikx=ikxs,ikxe
DO iky=ikys,ikye
DO iz=izs,ize
CALL RANDOM_NUMBER(noise)
moments_i(ip,ij,iky,ikx,iz,:) = (init_background + init_noiselvl*(noise-0.5_dp))
END DO
END DO
END DO
IF ( contains_ky0 ) THEN
DO ikx=2,Nkx/2 !symmetry at ky = 0 for all z
moments_i( ip,ij,iky_0,ikx,:,:) = moments_i( ip,ij,iky_0,Nkx+2-ikx,:,:)
END DO
ENDIF
END DO
END DO
! Putting to zero modes that are not in the 2/3 Orszag rule
IF (LINEARITY .NE. 'linear') THEN
DO ikx=ikxs,ikxe
DO iky=ikys,ikye
DO iz=izs,ize
IF(KIN_E) THEN
DO ip=ips_e,ipe_e
DO ij=ijs_e,ije_e
moments_e( ip,ij,iky,ikx,iz, :) = moments_e( ip,ij,iky,ikx,iz, :)*AA_x(ikx)*AA_y(iky)
ENDDO
ENDDO
ENDIF
DO ip=ips_i,ipe_i
DO ij=ijs_i,ije_i
moments_i( ip,ij,iky,ikx,iz, :) = moments_i( ip,ij,iky,ikx,iz, :)*AA_x(ikx)*AA_y(iky)
ENDDO
ENDDO
ENDDO
ENDDO
ENDDO
ENDIF
END SUBROUTINE init_moments
!******************************************************************************!
!******************************************************************************!
!!!!!!! Initialize the gyrocenter density randomly
!******************************************************************************!
SUBROUTINE init_gyrodens
USE basic
USE grid
USE fields
USE prec_const
USE utility, ONLY: checkfield
USE initial_par
USE model, ONLY: KIN_E, LINEARITY
IMPLICIT NONE
REAL(dp) :: noise
REAL(dp) :: kx, ky, sigma, gain, ky_shift
INTEGER, DIMENSION(12) :: iseedarr
! Seed random number generator
iseedarr(:)=iseed
CALL RANDOM_SEED(PUT=iseedarr+my_id)
!**** Broad noise initialization *******************************************
IF(KIN_E) THEN
DO ip=ips_e,ipe_e
DO ij=ijs_e,ije_e
DO ikx=ikxs,ikxe
DO iky=ikys,ikye
DO iz=izs,ize
CALL RANDOM_NUMBER(noise)
IF ( (ip .EQ. 1) .AND. (ij .EQ. 1) ) THEN
moments_e(ip,ij,iky,ikx,iz,:) = (init_background + init_noiselvl*(noise-0.5_dp))
ELSE
moments_e(ip,ij,iky,ikx,iz,:) = 0._dp
ENDIF
END DO
END DO
END DO
IF ( contains_ky0 ) THEN
DO ikx=2,Nkx/2 !symmetry at ky = 0 for all z
moments_e(ip,ij,iky_0,ikx,:,:) = moments_e(ip,ij,iky_0,Nkx+2-ikx,:,:)
END DO
ENDIF
END DO
END DO
ENDIF
DO ip=ips_i,ipe_i
DO ij=ijs_i,ije_i
DO ikx=ikxs,ikxe
DO iky=ikys,ikye
DO iz=izs,ize
CALL RANDOM_NUMBER(noise)
IF ( (ip .EQ. 1) .AND. (ij .EQ. 1) ) THEN
moments_i(ip,ij,iky,ikx,iz,:) = (init_background + init_noiselvl*(noise-0.5_dp))
ELSE
moments_i(ip,ij,iky,ikx,iz,:) = 0._dp
ENDIF
END DO
END DO
END DO
IF ( contains_ky0 ) THEN
- DO iky=2,Nky/2 !symmetry at ky = 0 for all z
+ DO ikx=2,Nkx/2 !symmetry at ky = 0 for all z
moments_i( ip,ij,iky_0,ikx,:,:) = moments_i( ip,ij,iky_0,Nkx+2-ikx,:,:)
END DO
ENDIF
END DO
END DO
! Putting to zero modes that are not in the 2/3 Orszag rule
IF (LINEARITY .NE. 'linear') THEN
DO ikx=ikxs,ikxe
DO iky=ikys,ikye
DO iz=izs,ize
IF(KIN_E) THEN
DO ip=ips_e,ipe_e
DO ij=ijs_e,ije_e
moments_e( ip,ij,iky,ikx,iz, :) = moments_e( ip,ij,iky,ikx,iz, :)*AA_x(ikx)*AA_y(iky)
ENDDO
ENDDO
ENDIF
DO ip=ips_i,ipe_i
DO ij=ijs_i,ije_i
moments_i( ip,ij,iky,ikx,iz, :) = moments_i( ip,ij,iky,ikx,iz, :)*AA_x(ikx)*AA_y(iky)
ENDDO
ENDDO
ENDDO
ENDDO
ENDDO
ENDIF
END SUBROUTINE init_gyrodens
!******************************************************************************!
!******************************************************************************!
!!!!!!! Initialize a noisy ES potential and cancel the moments
!******************************************************************************!
SUBROUTINE init_phi
USE basic
USE grid
USE fields
USE prec_const
USE initial_par
USE model, ONLY: KIN_E, LINEARITY
IMPLICIT NONE
REAL(dp) :: noise
REAL(dp) :: kx, ky, kp, sigma, gain, ky_shift
INTEGER, DIMENSION(12) :: iseedarr
! Seed random number generator
iseedarr(:)=iseed
CALL RANDOM_SEED(PUT=iseedarr+my_id)
!**** noise initialization *******************************************
DO ikx=ikxs,ikxe
DO iky=ikys,ikye
DO iz=izs,ize
CALL RANDOM_NUMBER(noise)
phi(iky,ikx,iz) = (init_background + init_noiselvl*(noise-0.5_dp))!*AA_x(ikx)*AA_y(iky)
ENDDO
END DO
END DO
!symmetry at ky = 0 to keep real inverse transform
IF ( contains_ky0 ) THEN
DO ikx=2,Nkx/2
phi(iky_0,ikx,izs:ize) = phi(iky_0,Nkx+2-ikx,izs:ize)
END DO
phi(iky_0,ikx_0,izs:ize) = REAL(phi(iky_0,ikx_0,izs:ize)) !origin must be real
ENDIF
!**** ensure no previous moments initialization
IF(KIN_E) moments_e = 0._dp
moments_i = 0._dp
!**** Zonal Flow initialization *******************************************
! put a mode at ikx = mode number + 1, symmetry is already included since kx>=0
IF(INIT_ZF .GT. 0) THEN
IF (my_id .EQ. 0) WRITE(*,*) 'Init ZF phi'
IF( (INIT_ZF+1 .GT. ikxs) .AND. (INIT_ZF+1 .LT. ikxe) ) THEN
DO iz = izs,ize
phi(iky_0,INIT_ZF+1,iz) = ZF_AMP*(2._dp*PI)**2/deltakx/deltaky/2._dp * COS((iz-1)/Nz*2._dp*PI)
moments_i(1,1,iky_0,INIT_ZF+1,iz,:) = kxarray(INIT_ZF+1)**2*phi(iky_0,INIT_ZF+1,iz)* COS((iz-1)/Nz*2._dp*PI)
IF(KIN_E) moments_e(1,1,iky_0,INIT_ZF+1,iz,:) = 0._dp
ENDDO
ENDIF
ENDIF
END SUBROUTINE init_phi
!******************************************************************************!
!******************************************************************************!
!******************************************************************************!
!!!!!!! Initialize an ionic Gaussian blob on top of the preexisting modes
!******************************************************************************!
SUBROUTINE initialize_blob
USE fields
USE grid
USE model, ONLY: sigmai2_taui_o2, KIN_E, LINEARITY
IMPLICIT NONE
REAL(dp) ::kx, ky, sigma, gain
sigma = 0.5_dp
gain = 5e2_dp
DO ikx=ikxs,ikxe
kx = kxarray(ikx)
DO iky=ikys,ikye
ky = kyarray(iky)
DO iz=izs,ize
DO ip=ips_i,ipe_i
DO ij=ijs_i,ije_i
IF( (iky .NE. iky_0) .AND. (ip .EQ. 1) .AND. (ij .EQ. 1)) THEN
moments_i( ip,ij,iky,ikx,iz, :) = moments_i( ip,ij,iky,ikx,iz, :) &
+ gain*sigma/SQRT2 * exp(-(kx**2+ky**2)*sigma**2/4._dp) &
* AA_x(ikx)*AA_y(iky)!&
! * exp(sigmai2_taui_o2*(kx**2+ky**2))
ENDIF
ENDDO
ENDDO
IF(KIN_E) THEN
DO ip=ips_e,ipe_e
DO ij=ijs_e,ije_e
IF( (iky .NE. iky_0) .AND. (ip .EQ. 1) .AND. (ij .EQ. 1)) THEN
moments_e( ip,ij,iky,ikx,iz, :) = moments_e( ip,ij,iky,ikx,iz, :) &
+ gain*sigma/SQRT2 * exp(-(kx**2+ky**2)*sigma**2/4._dp) &
* AA_x(ikx)*AA_y(iky)!&
! * exp(sigmai2_taui_o2*(kx**2+ky**2))
ENDIF
ENDDO
ENDDO
ENDIF
ENDDO
ENDDO
ENDDO
END SUBROUTINE initialize_blob
!******************************************************************************!
!******************************************************************************!
!!!!!!! Initialize the gyrocenter in a ppj gene manner (power law)
!******************************************************************************!
SUBROUTINE init_ppj
USE basic
USE grid
USE fields, ONLY: moments_e, moments_i
USE array, ONLY: kernel_e, kernel_i
USE prec_const
USE utility, ONLY: checkfield
USE initial_par
USE model, ONLY: KIN_E, LINEARITY
USE geometry, ONLY: Jacobian, iInt_Jacobian
IMPLICIT NONE
REAL(dp) :: noise
REAL(dp) :: kx, ky, sigma_z, amp, ky_shift, z
INTEGER, DIMENSION(12) :: iseedarr
sigma_z = pi/4._dp
amp = 1.0_dp
!**** Broad noise initialization *******************************************
! Electrons
IF (KIN_E) THEN
DO ip=ips_e,ipe_e
DO ij=ijs_e,ije_e
IF ( (ip .EQ. 1) .AND. (ij .EQ. 1) ) THEN
DO ikx=ikxs,ikxe
kx = kxarray(ikx)
DO iky=ikys,ikye
ky = kyarray(iky)
DO iz=izs,ize
z = zarray(iz,0)
IF (kx .EQ. 0) THEN
IF(ky .EQ. 0) THEN
moments_e(ip,ij,iky,ikx,iz,:) = 0._dp
ELSE
moments_e(ip,ij,iky,ikx,iz,:) = 0.5_dp * ky_min/(ABS(ky)+ky_min)
ENDIF
ELSE
IF(ky .GT. 0) THEN
moments_e(ip,ij,iky,ikx,iz,:) = (deltakx/(ABS(kx)+deltakx))*(ky_min/(ABS(ky)+ky_min))
ELSE
moments_e(ip,ij,iky,ikx,iz,:) = 0.5_dp*amp*(deltakx/(ABS(kx)+deltakx))
ENDIF
ENDIF
! z-dep and noise
moments_e(ip,ij,iky,ikx,iz,:) = moments_e(ip,ij,iky,ikx,iz,:) * &
(Jacobian(iz,0)*iInt_Jacobian)**2
! divide by kernel_0 to adjust to particle density (n = kernel_0 N00)
moments_e(ip,ij,iky,ikx,iz,:) = moments_e(ip,ij,iky,ikx,iz,:)/kernel_e(ij,iky,ikx,iz,0)
END DO
END DO
END DO
IF ( contains_ky0 ) THEN
DO ikx=2,Nkx/2 !symmetry at kx = 0 for all z
moments_e(ip,ij,iky_0,ikx,:,:) = moments_e( ip,ij,iky_0,Nkx+2-ikx,:, :)
END DO
ENDIF
ELSE
moments_e(ip,ij,:,:,:,:) = 0._dp
ENDIF
END DO
END DO
ENDIF
! Ions
DO ip=ips_i,ipe_i
DO ij=ijs_i,ije_i
IF ( (ip .EQ. 1) .AND. (ij .EQ. 1) ) THEN
DO ikx=ikxs,ikxe
kx = kxarray(ikx)
DO iky=ikys,ikye
ky = kyarray(iky)
DO iz=izs,ize
z = zarray(iz,0)
IF (kx .EQ. 0) THEN
IF(ky .EQ. 0) THEN
moments_i(ip,ij,iky,ikx,iz,:) = 0._dp
ELSE
moments_i(ip,ij,iky,ikx,iz,:) = 0.5_dp * ky_min/(ABS(ky)+ky_min)
ENDIF
ELSE
IF(ky .GT. 0) THEN
moments_i(ip,ij,iky,ikx,iz,:) = (deltakx/(ABS(kx)+deltakx))*(ky_min/(ABS(ky)+ky_min))
ELSE
moments_i(ip,ij,iky,ikx,iz,:) = 0.5_dp*amp*(deltakx/(ABS(kx)+deltakx))
ENDIF
ENDIF
! z-dep and noise
moments_i(ip,ij,iky,ikx,iz,:) = moments_i(ip,ij,iky,ikx,iz,:) * &
(Jacobian(iz,0)*iInt_Jacobian)**2
! divide by kernel_0 to adjust to particle density (n = kernel_0 N00)
moments_i(ip,ij,iky,ikx,iz,:) = moments_i(ip,ij,iky,ikx,iz,:)/kernel_i(ij,iky,ikx,iz,0)
END DO
END DO
END DO
IF ( contains_ky0 ) THEN
DO ikx=2,Nkx/2 !symmetry at kx = 0 for all z
moments_i(ip,ij,iky_0,ikx,:,:) = moments_i( ip,ij,iky_0,Nkx+2-ikx,:, :)
END DO
ENDIF
ELSE
moments_i(ip,ij,:,:,:,:) = 0._dp
ENDIF
END DO
END DO
! Putting to zero modes that are not in the 2/3 Orszag rule
IF (LINEARITY .NE. 'linear') THEN
DO ikx=ikxs,ikxe
DO iky=ikys,ikye
DO iz=izs,ize
DO ip=ips_e,ipe_e
DO ij=ijs_e,ije_e
moments_e( ip,ij,iky,ikx,iz, :) = moments_e( ip,ij,iky,ikx,iz, :)*AA_x(ikx)*AA_y(iky)
ENDDO
ENDDO
DO ip=ips_i,ipe_i
DO ij=ijs_i,ije_i
moments_i( ip,ij,iky,ikx,iz, :) = moments_i( ip,ij,iky,ikx,iz, :)*AA_x(ikx)*AA_y(iky)
ENDDO
ENDDO
ENDDO
ENDDO
ENDDO
ENDIF
END SUBROUTINE init_ppj
!******************************************************************************!
diff --git a/src/lag_interp_mod.F90 b/src/lag_interp_mod.F90
new file mode 100644
index 0000000..8415df5
--- /dev/null
+++ b/src/lag_interp_mod.F90
@@ -0,0 +1,256 @@
+!! This source is taken from GENE https://genecode.org/ !!
+!>lagrange_interpolation contains subroutines to perform
+!!a mid-point lagrange interpolation of order 3
+MODULE lagrange_interpolation
+ USE prec_const
+ IMPLICIT NONE
+ PUBLIC:: lag3interp, lag3deriv, lag3interp_2d
+ PUBLIC:: lag3interp_complex
+ PRIVATE
+
+ INTERFACE lag3interp
+ MODULE PROCEDURE lag3interp_scalar, lag3interp_array
+ END INTERFACE
+
+ INTERFACE lag3deriv
+ MODULE PROCEDURE lag3deriv_scalar, lag3deriv_array
+ END INTERFACE
+
+CONTAINS
+
+ !> Third order lagrange interpolation
+ SUBROUTINE lag3interp_scalar(y_in,x_in,n_in,y_out,x_out)
+ INTEGER, INTENT(IN) :: n_in
+ REAL(dp), DIMENSION(n_in), INTENT(IN) :: y_in,x_in
+ REAL(dp), INTENT(IN) :: x_out
+ REAL(dp), INTENT(OUT) :: y_out
+
+ REAL(dp), DIMENSION(1) :: xout_wrap, yout_wrap
+
+ xout_wrap = x_out
+ call lag3interp_array(y_in,x_in,n_in,yout_wrap,xout_wrap,1)
+ y_out = yout_wrap(1)
+
+ END SUBROUTINE lag3interp_scalar
+
+ !> Third order lagrange interpolation
+ subroutine lag3interp_array(y_in,x_in,n_in,y_out,x_out,n_out)
+ INTEGER, INTENT(IN) :: n_in,n_out
+ REAL(dp), DIMENSION(n_in), INTENT(IN) :: y_in,x_in
+ REAL(dp), DIMENSION(n_out), INTENT(IN) :: x_out
+ REAL(dp), DIMENSION(n_out), INTENT(OUT) :: y_out
+
+ REAL(dp) :: x,aintm,aint0,aint1,aint2,xm,x0,x1,x2
+ INTEGER :: j,jm,j0,j1,j2
+ INTEGER :: jstart,jfirst,jlast,jstep
+
+ IF (x_in(n_in) > x_in(1)) THEN
+ jstart=3
+ jfirst=1
+ jlast=n_out
+ jstep=1
+ ELSE
+ jstart=n_in-2
+ jfirst=n_out
+ jlast=1
+ jstep=-1
+ END IF
+
+ j1=jstart
+ DO j=jfirst,jlast,jstep
+ x=x_out(j)
+ DO WHILE (x >= x_in(j1) .AND. j1 < n_in-1 .AND. j1 > 2)
+ j1=j1+jstep
+ END DO
+
+ j2=j1+jstep
+ j0=j1-jstep
+ jm=j1-2*jstep
+
+ !... extrapolate inside or outside
+
+ x2=x_in(j2)
+ x1=x_in(j1)
+ x0=x_in(j0)
+ xm=x_in(jm)
+
+ aintm=(x-x0)*(x-x1)*(x-x2)/((xm-x0)*(xm-x1)*(xm-x2))
+ aint0=(x-xm)*(x-x1)*(x-x2)/((x0-xm)*(x0-x1)*(x0-x2))
+ aint1=(x-xm)*(x-x0)*(x-x2)/((x1-xm)*(x1-x0)*(x1-x2))
+ aint2=(x-xm)*(x-x0)*(x-x1)/((x2-xm)*(x2-x0)*(x2-x1))
+
+ y_out(j)=aintm*y_in(jm)+aint0*y_in(j0) &
+ +aint1*y_in(j1)+aint2*y_in(j2)
+
+ END DO
+
+ END SUBROUTINE Lag3interp_array
+
+
+ !> Third order lagrange interpolation for complex arrays
+ SUBROUTINE lag3interp_complex(y_in,x_in,n_in,y_out,x_out,n_out)
+ INTEGER, INTENT(IN) :: n_in,n_out
+ COMPLEX, DIMENSION(n_in), INTENT(IN) :: y_in
+ REAL(dp), DIMENSION(n_in), INTENT(IN) :: x_in
+ COMPLEX, DIMENSION(n_out), INTENT(OUT) :: y_out
+ REAL(dp), DIMENSION(n_out), INTENT(IN) :: x_out
+
+ REAL(dp) :: x,aintm,aint0,aint1,aint2,xm,x0,x1,x2
+ INTEGER :: j,jm,j0,j1,j2
+ INTEGER :: jstart,jfirst,jlast,jstep
+
+ IF (x_in(n_in) > x_in(1)) THEN
+ jstart=3
+ jfirst=1
+ jlast=n_out
+ jstep=1
+ ELSE
+ jstart=n_in-2
+ jfirst=n_out
+ jlast=1
+ jstep=-1
+ END IF
+
+ j1=jstart
+ DO j=jfirst,jlast,jstep
+ x=x_out(j)
+ DO WHILE (x >= x_in(j1) .AND. j1 < n_in-1 .AND. j1 > 2)
+ j1=j1+jstep
+ END DO
+
+ j2=j1+jstep
+ j0=j1-jstep
+ jm=j1-2*jstep
+
+ !... extrapolate inside or outside
+
+ x2=x_in(j2)
+ x1=x_in(j1)
+ x0=x_in(j0)
+ xm=x_in(jm)
+
+ aintm=(x-x0)*(x-x1)*(x-x2)/((xm-x0)*(xm-x1)*(xm-x2))
+ aint0=(x-xm)*(x-x1)*(x-x2)/((x0-xm)*(x0-x1)*(x0-x2))
+ aint1=(x-xm)*(x-x0)*(x-x2)/((x1-xm)*(x1-x0)*(x1-x2))
+ aint2=(x-xm)*(x-x0)*(x-x1)/((x2-xm)*(x2-x0)*(x2-x1))
+
+ y_out(j)=aintm*y_in(jm)+aint0*y_in(j0) &
+ +aint1*y_in(j1)+aint2*y_in(j2)
+
+ END DO
+
+ END SUBROUTINE lag3interp_complex
+
+
+ !>2D interpolation
+ !\TODO check whether a "REAL(dp)" 2D interpolation would
+ !! be more appropriate
+ SUBROUTINE lag3interp_2d(y_in,x1_in,n1_in,x2_in,n2_in,&
+ &y_out,x1_out,n1_out,x2_out,n2_out)
+ INTEGER, INTENT(IN) :: n1_in,n2_in,n1_out,n2_out
+ REAL(dp), DIMENSION(n1_in,n2_in), INTENT(IN) :: y_in
+ REAL(dp), DIMENSION(n1_in) :: x1_in
+ REAL(dp), DIMENSION(n2_in) :: x2_in
+ REAL(dp), DIMENSION(n1_out), INTENT(IN) :: x1_out
+ REAL(dp), DIMENSION(n2_out), INTENT(IN) :: x2_out
+ REAL(dp), DIMENSION(n1_out,n2_out), INTENT(OUT) :: y_out
+
+ !local variables
+ REAL(dp), DIMENSION(n2_in) :: y2_in_tmp
+ REAL(dp), DIMENSION(n2_out) :: y2_out_tmp
+ REAL(dp), DIMENSION(n1_in,n2_out) :: y_tmp
+ INTEGER :: i
+
+ DO i=1,n1_in
+ y2_in_tmp = y_in(i,:)
+ call lag3interp(y2_in_tmp,x2_in,n2_in,&
+ y2_out_tmp,x2_out,n2_out)
+ y_tmp(i,:) = y2_out_tmp
+ ENDDO
+
+ DO i=1,n2_out
+ call lag3interp(y_tmp(:,i),x1_in,n1_in,&
+ y_out(:,i),x1_out,n1_out)
+ END DO
+
+ END SUBROUTINE lag3interp_2d
+
+ !> Third order lagrange interpolation
+ SUBROUTINE lag3deriv_scalar(y_in,x_in,n_in,dydx_out,x_out)
+
+ IMPLICIT NONE
+
+ INTEGER, INTENT(IN) :: n_in
+ REAL(dp), DIMENSION(n_in), INTENT(IN) :: y_in,x_in
+ REAL(dp), INTENT(IN) :: x_out
+ REAL(dp), INTENT(OUT) :: dydx_out
+
+ REAL(dp), DIMENSION(1) :: xout_wrap, dydxout_wrap
+
+ xout_wrap = x_out
+ call lag3deriv_array(y_in,x_in,n_in,dydxout_wrap,xout_wrap,1)
+ dydx_out = dydxout_wrap(1)
+
+ END SUBROUTINE lag3deriv_scalar
+
+
+
+!>Returns Derivative based on a 3rd order lagrange interpolation
+ subroutine lag3deriv_array(y_in,x_in,n_in,dydx_out,x_out,n_out)
+ INTEGER :: n_in,n_out
+ REAL(dp), DIMENSION(n_in), INTENT(IN) :: y_in,x_in
+ REAL(dp), DIMENSION(n_out), INTENT(IN) :: x_out
+ REAL(dp), DIMENSION(n_out), INTENT(OUT) :: dydx_out
+
+ REAL(dp) :: x,aintm,aint0,aint1,aint2,xm,x0,x1,x2
+ INTEGER :: j,jm,j0,j1,j2
+ INTEGER :: jstart,jfirst,jlast,jstep
+
+ IF (x_in(n_in) > x_in(1)) THEN
+ jstart=3
+ jfirst=1
+ jlast=n_out
+ jstep=1
+ ELSE
+ jstart=n_in-2
+ jfirst=n_out
+ jlast=1
+ jstep=-1
+ END IF
+
+ j1=jstart
+ DO j=jfirst,jlast,jstep
+ x=x_out(j)
+ DO WHILE (x >= x_in(j1) .AND. j1 < n_in-1 .AND. j1 > 2)
+ j1=j1+jstep
+ END DO
+
+ j2=j1+jstep
+ j0=j1-jstep
+ jm=j1-2*jstep
+
+ !... extrapolate inside or outside
+
+ x2=x_in(j2)
+ x1=x_in(j1)
+ x0=x_in(j0)
+ xm=x_in(jm)
+
+ aintm=((x-x1)*(x-x2)+(x-x0)*(x-x2)+(x-x0)*(x-x1)) &
+ /((xm-x0)*(xm-x1)*(xm-x2))
+ aint0=((x-x1)*(x-x2)+(x-xm)*(x-x2)+(x-xm)*(x-x1)) &
+ /((x0-xm)*(x0-x1)*(x0-x2))
+ aint1=((x-x0)*(x-x2)+(x-xm)*(x-x2)+(x-xm)*(x-x0)) &
+ /((x1-xm)*(x1-x0)*(x1-x2))
+ aint2=((x-x0)*(x-x1)+(x-xm)*(x-x1)+(x-xm)*(x-x0)) &
+ /((x2-xm)*(x2-x0)*(x2-x1))
+
+ dydx_out(j)=aintm*y_in(jm)+aint0*y_in(j0) &
+ +aint1*y_in(j1)+aint2*y_in(j2)
+
+ END DO
+
+ end subroutine Lag3deriv_array
+
+
+end module lagrange_interpolation
diff --git a/src/miller_mod.F90 b/src/miller_mod.F90
new file mode 100644
index 0000000..eb3a9e5
--- /dev/null
+++ b/src/miller_mod.F90
@@ -0,0 +1,667 @@
+!! This source has been adapted from GENE https://genecode.org/ !!
+!>Implementation of the local equilibrium model of [R.L. Miller et al., PoP 5, 973 (1998)
+!>and [J. Candy, PPCF 51, 105009 (2009)]
+MODULE miller
+ USE prec_const
+ USE basic
+ ! use coordinates,only: gcoor, get_dzprimedz
+ USE grid
+ ! use discretization
+ USE lagrange_interpolation
+ ! use par_in, only: beta, sign_Ip_CW, sign_Bt_CW, Npol
+ USE model
+
+ implicit none
+ public:: get_miller, set_miller_parameters
+ public:: rho, kappa, delta, s_kappa, s_delta, drR, drZ, zeta, s_zeta
+ public:: thetaShift
+ public:: mMode, nMode
+ public:: thetak, thetad
+ public:: aSurf, Delta2, Delta3, theta2, theta3, Raxis, Zaxis
+ public:: Deltam, Deltan, s_Deltam, s_Deltan, thetam, thetan
+ public:: cN_m, sN_m, cNdr_m, sNdr_m
+
+ private
+
+ real(dp) :: rho, kappa, delta, s_kappa, s_delta, drR, drZ, zeta, s_zeta
+
+ INTEGER :: mMode, nMode
+ real(dp) :: thetaShift
+ real(dp) :: thetak, thetad
+ real(dp) :: aSurf, Delta2, Delta3, theta2, theta3, Raxis, Zaxis
+ real(dp) :: Deltam, Deltan, s_Deltam, s_Deltan, thetam, thetan
+
+ INTEGER, PARAMETER :: IND_M=32
+ real(dp), DIMENSION(0:IND_M-1) :: cN_m, sN_m, cNdr_m, sNdr_m
+
+CONTAINS
+
+ !>Set defaults for miller parameters
+ subroutine set_miller_parameters(kappa_,s_kappa_,delta_,s_delta_,zeta_,s_zeta_)
+ real(dp), INTENT(IN) :: kappa_,s_kappa_,delta_,s_delta_,zeta_,s_zeta_
+ rho = -1.0
+ kappa = kappa_
+ s_kappa = s_kappa_
+ delta = delta_
+ s_delta = s_delta_
+ zeta = zeta_
+ s_zeta = s_zeta_
+ drR = 0.0
+ drZ = 0.0
+
+ thetak = 0.0
+ thetad = 0.0
+
+ aSurf = 0.54
+ Delta2 = 1.0
+ Delta3 = 1.0
+ theta2 = 0.0
+ theta3 = 0.0
+ Raxis = 1.0
+ Zaxis = 0.0
+
+ mMode = 2
+ nMode = 3
+ Deltam = 1.0
+ Deltan = 1.0
+ s_Deltam = 0.0
+ s_Deltan = 0.0
+ thetam = 0.0
+ thetan = 0.0
+
+ cN_m = 0.0
+ sN_m = 0.0
+ cNdr_m = 0.0
+ sNdr_m = 0.0
+ end subroutine set_miller_parameters
+
+ !>Get Miller metric, magnetic field, jacobian etc.
+ subroutine get_miller(trpeps,major_R,major_Z,q0,shat,amhd,edge_opt,&
+ C_y,C_xy,dpdx_pm_geom,gxx_,gyy_,gzz_,gxy_,gxz_,gyz_,dBdx_,dBdy_,&
+ Bfield_,jacobian_,dBdz_,R_hat_,Z_hat_,dxdR_,dxdZ_,Ckxky_,gradz_coeff_)
+ !!!!!!!!!!!!!!!! GYACOMO INTERFACE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ real(dp), INTENT(INOUT) :: trpeps ! eps in gyacomo (inverse aspect ratio)
+ real(dp), INTENT(INOUT) :: major_R ! major radius
+ real(dp), INTENT(INOUT) :: major_Z ! major Z
+ real(dp), INTENT(INOUT) :: q0 ! safetyfactor
+ real(dp), INTENT(INOUT) :: shat ! safetyfactor
+ real(dp), INTENT(INOUT) :: amhd ! alpha mhd
+ real(dp), INTENT(INOUT) :: edge_opt ! alpha mhd
+ real(dp), INTENT(INOUT) :: dpdx_pm_geom ! amplitude mag. eq. pressure grad.
+ real(dp), INTENT(INOUT) :: C_y, C_xy
+
+ real(dp), dimension(izgs:izge,0:1), INTENT(INOUT) :: &
+ gxx_,gyy_,gzz_,gxy_,gxz_,gyz_,&
+ dBdx_,dBdy_,Bfield_,jacobian_,&
+ dBdz_,R_hat_,Z_hat_,dxdR_,dxdZ_, &
+ gradz_coeff_
+ real(dp), dimension(ikys:ikye,ikxs:ikxe,izgs:izge,0:1), INTENT(INOUT) :: Ckxky_
+ ! No parameter in gyacomo yet
+ integer :: ikxgs =1 ! the left ghost gpdisc%pi1gl
+ real(dp) :: sign_Ip_CW=1 ! current sign (only normal current)
+ real(dp) :: sign_Bt_CW=1 ! current sign (only normal current)
+ !!!!!!!!!!!!!! END GYACOMO INTERFACE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ ! Auxiliary variables for curvature computation
+ real(dp) :: G1,G2,G3,Cx,Cy,ky,kx
+
+ integer:: np, np_s, Npol_ext, Npol_s
+
+ real(dp), dimension(500*(Npol+2)):: R,Z,R_rho,Z_rho,R_theta,Z_theta,R_theta_theta,Z_theta_theta,dlp,Rc,cosu,sinu,Bphi
+ real(dp), dimension(500*(Npol+2)):: drRcirc, drRelong, drRelongTilt, drRtri, drRtriTilt, drZcirc, drZelong, drZelongTilt
+ real(dp), dimension(500*(Npol+2)):: drZtri, drZtriTilt, dtdtRcirc, dtdtRelong, dtdtRelongTilt, dtdtRtri, dtdtRtriTilt
+ real(dp), dimension(500*(Npol+2)):: dtdtZcirc, dtdtZelong, dtdtZelongTilt, dtdtZtri, dtdtZtriTilt, dtRcirc, dtRelong
+ real(dp), dimension(500*(Npol+2)):: dtRelongTilt, dtRtri, dtRtriTilt, dtZcirc, dtZelong, dtZelongTilt, dtZtri, dtZtriTilt
+ real(dp), dimension(500*(Npol+2)):: Rcirc, Relong, RelongTilt, Rtri, RtriTilt, Zcirc, Zelong, ZelongTilt, Ztri, ZtriTilt
+ real(dp), dimension(500*(Npol+2)):: drrShape, drrAng, drxAng, dryAng, dtdtrShape, dtdtrAng, dtdtxAng
+ real(dp), dimension(500*(Npol+2)):: dtdtyAng, dtrShape, dtrAng, dtxAng, dtyAng, rShape, rAng, xAng, yAng
+ real(dp), dimension(500*(Npol+2)):: theta, thAdj, J_r, B, Bp, D0, D1, D2, D3, nu, chi, psi1, nu1
+ real(dp), dimension(500*(Npol+2)):: tmp_reverse, theta_reverse, tmp_arr
+
+ real(dp), dimension(500*(Npol+1)):: theta_s, thAdj_s, chi_s, theta_s_reverse
+ real(dp), dimension(500*(Npol+1)):: R_s, Z_s, R_theta_s, Z_theta_s, Rc_s, cosu_s, sinu_s, Bphi_s, B_s, Bp_s, dlp_s
+ real(dp), dimension(500*(Npol+1)):: dtRcirc_s, dtRelong_s, dtRelongTilt_s, dtRtri_s, dtRtriTilt_s, dtZcirc_s
+ real(dp), dimension(500*(Npol+1)):: dtZelong_s, dtZelongTilt_s, dtZtri_s, dtZtriTilt_s, Rcirc_s, Relong_s, RelongTilt_s
+ real(dp), dimension(500*(Npol+1)):: Rtri_s, RtriTilt_s, Zcirc_s, Zelong_s, ZelongTilt_s, Ztri_s, ZtriTilt_s, dtrShape_s
+ real(dp), dimension(500*(Npol+1)):: dtrAng_s, dtxAng_s, dtyAng_s, rShape_s, rAng_s, xAng_s, yAng_s
+ real(dp), dimension(500*(Npol+1)):: psi1_s, nu1_s, dchidx_s, dB_drho_s, dB_dl_s, dnu_drho_s, dnu_dl_s, grad_nu_s
+ real(dp), dimension(500*(Npol+1)):: gxx, gxy, gxz, gyy, gyz, gzz, dtheta_dchi_s, dBp_dchi_s, jacobian, dBdx, dBdz
+ real(dp), dimension(500*(Npol+1)):: g_xx, g_xy, g_xz, g_yy, g_yz, g_zz, tmp_arr_s, dxdR_s, dxdZ_s, K_x, K_y !tmp_arr2
+
+ real(dp), dimension(1:Nz):: gxx_out,gxy_out,gxz_out,gyy_out,gyz_out,gzz_out,Bfield_out,jacobian_out, dBdx_out, dBdz_out, chi_out
+ real(dp), dimension(1:Nz):: R_out, Z_out, dxdR_out, dxdZ_out
+ real(dp):: d_inv, drPsi, dxPsi, dq_dx, dq_dpsi, R0, Z0, B0, F, D0_full, D1_full, D2_full, D3_full
+ !real(dp) :: Lnorm, Psi0 ! currently module-wide defined anyway
+ real(dp):: pprime, ffprime, D0_mid, D1_mid, D2_mid, D3_mid, dx_drho, pi, mu_0, dzprimedz
+ real(dp):: rho_a, psiN, drpsiN, CN2, CN3, Rcenter, Zcenter, drRcenter, drZcenter
+ logical:: bMaxShift
+ integer:: i, k, iBmax
+
+ Npol_ext = Npol+2
+ Npol_s = Npol+1
+ np = 500*Npol_ext
+ np_s = 500*Npol_s
+
+ rho = trpeps*major_R
+ if (rho.le.0.0) stop 'flux surface radius not defined'
+ trpeps = rho/major_R
+
+ q0 = sign_Ip_CW * sign_Bt_CW * abs(q0)
+
+ R0=major_R
+ B0=1.0*sign_Bt_CW
+ F=R0*B0
+ Z0=major_Z
+ pi = acos(-1.0)
+ mu_0=4.0*pi
+
+ theta=linspace(-pi*Npol_ext,pi*Npol_ext-2._dp*pi*Npol_ext/np,np)
+ d_inv=asin(delta)
+
+ thetaShift = 0.0
+ iBmax = 1
+
+ !flux surface parametrization
+ thAdj = theta + thetaShift
+ if (zeta/=0.0 .or. s_zeta/=0.0) then
+ R = R0 + rho*Cos(thAdj + d_inv*Sin(thAdj))
+ Z = Z0 + kappa*rho*Sin(thAdj + zeta*Sin(2*thAdj))
+
+ R_rho = drR + Cos(thAdj + d_inv*Sin(thAdj)) - s_delta*Sin(thAdj)*Sin(thAdj + d_inv*Sin(thAdj))
+ Z_rho = drZ + kappa*s_zeta*Cos(thAdj + zeta*Sin(2*thAdj))*Sin(2*thAdj) &
+ + kappa*Sin(thAdj + zeta*Sin(2*thAdj)) + kappa*s_kappa*Sin(thAdj + zeta*Sin(2*thAdj))
+
+ R_theta = -(rho*(1 + d_inv*Cos(thAdj))*Sin(thAdj + d_inv*Sin(thAdj)))
+ Z_theta = kappa*rho*(1 + 2*zeta*Cos(2*thAdj))*Cos(thAdj + zeta*Sin(2*thAdj))
+
+ R_theta_theta = -(rho*(1 + d_inv*Cos(thAdj))**2*Cos(thAdj + d_inv*Sin(thAdj))) &
+ + d_inv*rho*Sin(thAdj)*Sin(thAdj + d_inv*Sin(thAdj))
+ Z_theta_theta = -4*kappa*rho*zeta*Cos(thAdj + zeta*Sin(2*thAdj))*Sin(2*thAdj) &
+ - kappa*rho*(1 + 2*zeta*Cos(2*thAdj))**2*Sin(thAdj + zeta*Sin(2*thAdj))
+ else
+ Rcirc = rho*Cos(thAdj - thetad + thetak)
+ Zcirc = rho*Sin(thAdj - thetad + thetak)
+ Relong = Rcirc
+ Zelong = Zcirc + (-1 + kappa)*rho*Sin(thAdj - thetad + thetak)
+ RelongTilt = Relong*Cos(thetad - thetak) - Zelong*Sin(thetad - thetak)
+ ZelongTilt = Zelong*Cos(thetad - thetak) + Relong*Sin(thetad - thetak)
+ Rtri = RelongTilt - rho*Cos(thAdj) + rho*Cos(thAdj + delta*Sin(thAdj))
+ Ztri = ZelongTilt
+ RtriTilt = Rtri*Cos(thetad) + Ztri*Sin(thetad)
+ ZtriTilt = Ztri*Cos(thetad) - Rtri*Sin(thetad)
+ R = R0 + RtriTilt
+ Z = Z0 + ZtriTilt
+
+ drRcirc = Cos(thAdj - thetad + thetak)
+ drZcirc = Sin(thAdj - thetad + thetak)
+ drRelong = drRcirc
+ drZelong = drZcirc - (1 - kappa - kappa*s_kappa)*Sin(thAdj - thetad + thetak)
+ drRelongTilt = drRelong*Cos(thetad - thetak) - drZelong*Sin(thetad - thetak)
+ drZelongTilt = drZelong*Cos(thetad - thetak) + drRelong*Sin(thetad - thetak)
+ drRtri = drRelongTilt - Cos(thAdj) + Cos(thAdj + delta*Sin(thAdj)) &
+ - s_delta*Sin(thAdj)*Sin(thAdj + delta*Sin(thAdj))
+ drZtri = drZelongTilt
+ drRtriTilt = drRtri*Cos(thetad) + drZtri*Sin(thetad)
+ drZtriTilt = drZtri*Cos(thetad) - drRtri*Sin(thetad)
+ R_rho = drR + drRtriTilt
+ Z_rho = drZ + drZtriTilt
+
+ dtRcirc = -(rho*Sin(thAdj - thetad + thetak))
+ dtZcirc = rho*Cos(thAdj - thetad + thetak)
+ dtRelong = dtRcirc
+ dtZelong = dtZcirc + (-1 + kappa)*rho*Cos(thAdj - thetad + thetak)
+ dtRelongTilt = dtRelong*Cos(thetad - thetak) - dtZelong*Sin(thetad - thetak)
+ dtZelongTilt = dtZelong*Cos(thetad - thetak) + dtRelong*Sin(thetad - thetak)
+ dtRtri = dtRelongTilt + rho*Sin(thAdj) - rho*(1 + delta*Cos(thAdj))*Sin(thAdj + delta*Sin(thAdj))
+ dtZtri = dtZelongTilt
+ dtRtriTilt = dtRtri*Cos(thetad) + dtZtri*Sin(thetad)
+ dtZtriTilt = dtZtri*Cos(thetad) - dtRtri*Sin(thetad)
+ R_theta = dtRtriTilt
+ Z_theta = dtZtriTilt
+
+ dtdtRcirc = -(rho*Cos(thAdj - thetad + thetak))
+ dtdtZcirc = -(rho*Sin(thAdj - thetad + thetak))
+ dtdtRelong = dtdtRcirc
+ dtdtZelong = dtdtZcirc - (-1 + kappa)*rho*Sin(thAdj - thetad + thetak)
+ dtdtRelongTilt = dtdtRelong*Cos(thetad - thetak) - dtdtZelong*Sin(thetad - thetak)
+ dtdtZelongTilt = dtdtZelong*Cos(thetad - thetak) + dtdtRelong*Sin(thetad - thetak)
+ dtdtRtri = dtdtRelongTilt + rho*Cos(thAdj) - rho*(1 + delta*Cos(thAdj))**2*Cos(thAdj + delta*Sin(thAdj)) &
+ + delta*rho*Sin(thAdj)*Sin(thAdj + delta*Sin(thAdj))
+ dtdtZtri = dtdtZelongTilt
+ dtdtRtriTilt = dtdtRtri*Cos(thetad) + dtdtZtri*Sin(thetad)
+ dtdtZtriTilt = dtdtZtri*Cos(thetad) - dtdtRtri*Sin(thetad)
+ R_theta_theta = dtdtRtriTilt
+ Z_theta_theta = dtdtZtriTilt
+ endif
+
+ !dl/dtheta
+ dlp=(R_theta**2+Z_theta**2)**0.5
+
+ !curvature radius
+ Rc=dlp**3*(R_theta*Z_theta_theta-Z_theta*R_theta_theta)**(-1)
+
+ ! some useful quantities (see papers for definition of u)
+ cosu=Z_theta/dlp
+ sinu=-R_theta/dlp
+
+ !Jacobian J_r = (dPsi/dr) J_psi = (dPsi/dr) / [(nabla fz x nabla psi)* nabla theta]
+ ! = R * (dR/drho dZ/dtheta - dR/dtheta dZ/drho) = R dlp / |nabla r|
+ J_r=R*(R_rho*Z_theta-R_theta*Z_rho)
+
+ !From definition of q = 1/(2 pi) int (B nabla fz) / (B nabla theta) dtheta:
+ !dPsi/dr = sign_Bt sign_Ip / (2 pi q) int F / R^2 J_r dtheta
+ ! = F / (2 pi |q|) int J_r/R^2 dtheta
+ tmp_arr=J_r/R**2
+ drPsi=sign_Ip_CW*F/(2.*pi*Npol_ext*q0)*sum(tmp_arr)*2*pi*Npol_ext/np !dlp_int(tmp_arr,1.0)
+
+ !Poloidal field (Bp = Bvec * nabla l)
+ Bp=sign_Ip_CW * drPsi / J_r * dlp
+
+ !toroidal field
+ Bphi=F/R
+
+ !total modulus of Bfield
+ B=sqrt(Bphi**2+Bp**2)
+
+ bMaxShift = .false.
+ ! if (thetaShift==0.0.and.trim(magn_geometry).ne.'miller_general') then
+ if (thetaShift==0.0) then
+ do i = 2,np-1
+ if (B(iBmax) x = r
+ dx_drho=1. !drPsi/Psi0*Lnorm*q0
+ if (my_id==0) write(*,"(A,ES12.4)") 'Using radial coordinate with dx/dr = ',dx_drho
+ dxPsi = drPsi/dx_drho
+ C_y = dxPsi*sign_Ip_CW
+ C_xy = abs(B0*dxPsi/C_y)
+
+ if (my_id==0) then
+ write(*,"(A,ES12.4,A,ES12.4,A,ES12.4)") &
+ "Setting C_xy = ",C_xy,' C_y = ', C_y," C_x' = ", 1./dxPsi
+ write(*,'(A,ES12.4)') "B_unit/Bref conversion factor = ", q0/rho*drPsi
+ write(*,'(A,ES12.4)') "dPsi/dr = ", drPsi
+ if (thetaShift.ne.0.0) write(*,'(A,ES12.4)') "thetaShift = ", thetaShift
+ endif
+
+
+ !--------shear is expected to be defined as rho/q*dq/drho--------!
+ dq_dx=shat*q0/rho/dx_drho
+ dq_dpsi=dq_dx/dxPsi
+ pprime=-amhd/q0**2/R0/(2*mu_0)*B0**2/drPsi
+
+ !neg. dpdx normalized to magnetic pressure for pressure term
+ dpdx_pm_geom=amhd/q0**2/R0/dx_drho
+
+ !first coefficient of psi in varrho expansion
+ psi1 = R*Bp*sign_Ip_CW
+
+ !integrals for ffprime evaluation
+ do i=1,np
+ tmp_arr=(2./Rc-2.*cosu/R)/(R*psi1**2)
+ D0(i)=-F*dlp_int_ind(tmp_arr,dlp,i)
+ tmp_arr=B**2*R/psi1**3
+ D1(i)=-dlp_int_ind(tmp_arr,dlp,i)/F
+ tmp_arr=mu_0*R/psi1**3
+ D2(i)=-dlp_int_ind(tmp_arr,dlp,i)*F
+ tmp_arr=1./(R*psi1)
+ D3(i)=-dlp_int_ind(tmp_arr,dlp,i)*F
+ enddo
+ tmp_arr=(2./Rc-2.*cosu/R)/(R*psi1**2)
+ D0_full=-F*dlp_int(tmp_arr,dlp)
+ tmp_arr=B**2*R/psi1**3
+ D1_full=-dlp_int(tmp_arr,dlp)/F
+ tmp_arr=mu_0*R/psi1**3
+ D2_full=-dlp_int(tmp_arr,dlp)*F
+ tmp_arr=1./(R*psi1)
+ D3_full=-dlp_int(tmp_arr,dlp)*F
+ D0_mid=D0(np/2+1)
+ D1_mid=D1(np/2+1)
+ D2_mid=D2(np/2+1)
+ D3_mid=D3(np/2+1)
+
+ ffprime=-(sign_Ip_CW*dq_dpsi*2.*pi*Npol_ext+D0_full+D2_full*pprime)/D1_full
+
+ if (my_id==0) then
+ write(*,'(A,ES12.4)') "ffprime = ", ffprime
+ endif
+ D0=D0-D0_mid
+ D1=D1-D1_mid
+ D2=D2-D2_mid
+ nu=D3-D3_mid
+
+ nu1=psi1*(D0+D1*ffprime+D2*pprime)
+
+ !straight field line angle defined on equidistant theta grid
+ !alpha = fz + nu = - (q chi - fz) => chi = -nu / q
+ chi=-nu/q0
+
+ !correct small scaling error (<0.5%, due to finite integration resolution)
+ chi=chi*(maxval(theta)-minval(theta))/(maxval(chi)-minval(chi))
+
+ !new grid equidistant in straight field line angle
+ chi_s = linspace(-pi*Npol_s,pi*Npol_s-2*pi*Npol_s/np_s,np_s)
+
+ if (sign_Ip_CW.lt.0.0) then !make chi increasing function to not confuse lag3interp
+ tmp_reverse = chi(np:1:-1)
+ theta_reverse = theta(np:1:-1)
+ call lag3interp(theta_reverse,tmp_reverse,np,theta_s,chi_s,np_s)
+ theta_s_reverse = theta_s(np_s:1:-1)
+ else
+ !lag3interp(y_in,x_in,n_in,y_out,x_out,n_out)
+ call lag3interp(theta,chi,np,theta_s,chi_s,np_s)
+ endif
+ dtheta_dchi_s=deriv_fd(theta_s,chi_s,np_s)
+
+ !arrays equidistant in straight field line angle
+ thAdj_s = theta_s + thetaShift
+
+ if (zeta/=0.0 .or. s_zeta/=0.0) then
+ R_s = R0 + rho*Cos(thAdj_s + d_inv*Sin(thAdj_s))
+ Z_s = Z0 + kappa*rho*Sin(thAdj_s + zeta*Sin(2*thAdj_s))
+
+ R_theta_s = -(dtheta_dchi_s*rho*(1 + d_inv*Cos(thAdj_s))*Sin(thAdj_s + d_inv*Sin(thAdj_s)))
+ Z_theta_s = dtheta_dchi_s*kappa*rho*(1 + 2*zeta*Cos(2*thAdj_s))*Cos(thAdj_s + zeta*Sin(2*thAdj_s))
+ else
+ Rcirc_s = rho*Cos(thAdj_s - thetad + thetak)
+ Zcirc_s = rho*Sin(thAdj_s - thetad + thetak)
+ Relong_s = Rcirc_s
+ Zelong_s = Zcirc_s + (-1 + kappa)*rho*Sin(thAdj_s - thetad + thetak)
+ RelongTilt_s = Relong_s*Cos(thetad - thetak) - Zelong_s*Sin(thetad - thetak)
+ ZelongTilt_s = Zelong_s*Cos(thetad - thetak) + Relong_s*Sin(thetad - thetak)
+ Rtri_s = RelongTilt_s - rho*Cos(thAdj_s) + rho*Cos(thAdj_s + delta*Sin(thAdj_s))
+ Ztri_s = ZelongTilt_s
+ RtriTilt_s = Rtri_s*Cos(thetad) + Ztri_s*Sin(thetad)
+ ZtriTilt_s = Ztri_s*Cos(thetad) - Rtri_s*Sin(thetad)
+ R_s = R0 + RtriTilt_s
+ Z_s = Z0 + ZtriTilt_s
+
+ dtRcirc_s = -(rho*Sin(thAdj_s - thetad + thetak))
+ dtZcirc_s = rho*Cos(thAdj_s - thetad + thetak)
+ dtRelong_s = dtRcirc_s
+ dtZelong_s = dtZcirc_s + (-1 + kappa)*rho*Cos(thAdj_s - thetad + thetak)
+ dtRelongTilt_s = dtRelong_s*Cos(thetad - thetak) - dtZelong_s*Sin(thetad - thetak)
+ dtZelongTilt_s = dtZelong_s*Cos(thetad - thetak) + dtRelong_s*Sin(thetad - thetak)
+ dtRtri_s = dtRelongTilt_s + rho*Sin(thAdj_s) &
+ - rho*(1 + delta*Cos(thAdj_s))*Sin(thAdj_s + delta*Sin(thAdj_s))
+ dtZtri_s = dtZelongTilt_s
+ dtRtriTilt_s = dtRtri_s*Cos(thetad) + dtZtri_s*Sin(thetad)
+ dtZtriTilt_s = dtZtri_s*Cos(thetad) - dtRtri_s*Sin(thetad)
+ R_theta_s = dtheta_dchi_s*dtRtriTilt_s
+ Z_theta_s = dtheta_dchi_s*dtZtriTilt_s
+ endif
+ if (sign_Ip_CW.lt.0.0) then
+ call lag3interp(nu1,theta,np,tmp_arr_s,theta_s_reverse,np_s)
+ nu1_s = tmp_arr_s(np_s:1:-1)
+ call lag3interp(Bp,theta,np,tmp_arr_s,theta_s_reverse,np_s)
+ Bp_s = tmp_arr_s(np_s:1:-1)
+ call lag3interp(dlp,theta,np,tmp_arr_s,theta_s_reverse,np_s)
+ dlp_s = tmp_arr_s(np_s:1:-1)
+ call lag3interp(Rc,theta,np,tmp_arr_s,theta_s_reverse,np_s)
+ Rc_s = tmp_arr_s(np_s:1:-1)
+ else
+ call lag3interp(nu1,theta,np,nu1_s,theta_s,np_s)
+ call lag3interp(Bp,theta,np,Bp_s,theta_s,np_s)
+ call lag3interp(dlp,theta,np,dlp_s,theta_s,np_s)
+ call lag3interp(Rc,theta,np,Rc_s,theta_s,np_s)
+ endif
+
+ psi1_s = R_s*Bp_s*sign_Ip_CW
+
+ dBp_dchi_s=deriv_fd(Bp_s,chi_s,np_s)
+
+ Bphi_s=F/R_s
+ B_s=sqrt(Bphi_s**2+Bp_s**2)
+ cosu_s=Z_theta_s/dlp_s/dtheta_dchi_s
+ sinu_s=-R_theta_s/dlp_s/dtheta_dchi_s
+
+ !radial derivative of straight field line angle
+ dchidx_s=-(nu1_s/psi1_s*dxPsi+chi_s*dq_dx)/q0
+
+ !Bfield derivatives in Mercier-Luc coordinates (varrho,l,fz)
+ dB_drho_s=-1./B_s*(F**2/R_s**3*cosu_s+Bp_s**2/Rc_s+mu_0*psi1_s*pprime)
+ dB_dl_s=1./B_s*(Bp_s*dBp_dchi_s/dtheta_dchi_s/dlp_s+F**2/R_s**3*sinu_s)
+
+ dnu_drho_s=nu1_s
+ dnu_dl_s=-F/(R_s*psi1_s)
+ grad_nu_s=sqrt(dnu_drho_s**2+dnu_dl_s**2)
+
+ !contravariant metric coefficients (varrho,l,fz)->(x,y,z)
+ gxx=(psi1_s/dxPsi)**2
+ gxy=-psi1_s/dxPsi*C_y*sign_Ip_CW*nu1_s
+ gxz=-psi1_s/dxPsi*(nu1_s+psi1_s*dq_dpsi*chi_s)/q0
+ gyy=C_y**2*(grad_nu_s**2+1/R_s**2)
+ gyz=sign_Ip_CW*C_y/q0*(grad_nu_s**2+dq_dpsi*nu1_s*psi1_s*chi_s)
+ gzz=1./q0**2*(grad_nu_s**2+2.*dq_dpsi*nu1_s*psi1_s*chi_s+(dq_dpsi*psi1_s*chi_s)**2)
+
+ jacobian=1./sqrt(gxx*gyy*gzz + 2.*gxy*gyz*gxz - gxz**2*gyy - gyz**2*gxx - gzz*gxy**2)
+
+ !covariant metric coefficients
+ g_xx=jacobian**2*(gyy*gzz-gyz**2)
+ g_xy=jacobian**2*(gxz*gyz-gxy*gzz)
+ g_xz=jacobian**2*(gxy*gyz-gxz*gyy)
+ g_yy=jacobian**2*(gxx*gzz-gxz**2)
+ g_yz=jacobian**2*(gxz*gxy-gxx*gyz)
+ g_zz=jacobian**2*(gxx*gyy-gxy**2)
+
+ !Bfield derivatives
+ !dBdx = e_x * nabla B = J (nabla y x nabla z) * nabla B
+ dBdx=jacobian*C_y/(q0*R_s)*(F/(R_s*psi1_s)*dB_drho_s+(nu1_s+dq_dpsi*chi_s*psi1_s)*dB_dl_s)
+ dBdz=1./B_s*(Bp_s*dBp_dchi_s-F**2/R_s**3*R_theta_s)
+
+ !curvature terms (these are just local and will be recalculated in geometry.F90)
+ K_x = (0.-g_yz/g_zz*dBdz)
+ K_y = (dBdx-g_xz/g_zz*dBdz)
+
+ !(R,Z) derivatives for visualization
+ dxdR_s = dx_drho/drPsi*psi1_s*cosu_s
+ dxdZ_s = dx_drho/drPsi*psi1_s*sinu_s
+
+ if (edge_opt==0.0) then
+ !gene z-grid
+ chi_out=linspace(-pi*Npol,pi*Npol-2*pi*Npol/Nz,Nz)
+ else
+ !new parallel coordinate chi_out==zprime
+ !see also tracer_aux.F90
+ if (Npol>1) STOP "ERROR: Npol>1 has not been implemented for edge_opt=\=0.0"
+ do k=izs,ize
+ chi_out(k)=sinh((-pi+k*2.*pi/Nz)*log(edge_opt*pi+sqrt(edge_opt**2*pi**2+1))/pi)/edge_opt
+ enddo
+ !transform metrics according to chain rule
+ do k=1,np_s
+ !>dz'/dz conversion for edge_opt as function of z
+ if (edge_opt.gt.0) then
+ dzprimedz = edge_opt*pi/log(edge_opt*pi+sqrt((edge_opt*pi)**2+1))/&
+ sqrt((edge_opt*chi_s(k))**2+1)
+ else
+ dzprimedz = 1.0
+ endif
+ gxz(k)=gxz(k)*dzprimedz
+ gyz(k)=gyz(k)*dzprimedz
+ gzz(k)=gzz(k)*dzprimedz**2
+ jacobian(k)=jacobian(k)/dzprimedz
+ dBdz(k)=dBdz(k)/dzprimedz
+ enddo
+ endif !edge_opt
+
+ !interpolate down to GENE z-grid
+ call lag3interp(gxx,chi_s,np_s,gxx_out,chi_out,Nz)
+ call lag3interp(gxy,chi_s,np_s,gxy_out,chi_out,Nz)
+ call lag3interp(gxz,chi_s,np_s,gxz_out,chi_out,Nz)
+ call lag3interp(gyy,chi_s,np_s,gyy_out,chi_out,Nz)
+ call lag3interp(gyz,chi_s,np_s,gyz_out,chi_out,Nz)
+ call lag3interp(gzz,chi_s,np_s,gzz_out,chi_out,Nz)
+ call lag3interp(B_s,chi_s,np_s,Bfield_out,chi_out,Nz)
+ call lag3interp(jacobian,chi_s,np_s,jacobian_out,chi_out,Nz)
+ call lag3interp(dBdx,chi_s,np_s,dBdx_out,chi_out,Nz)
+ call lag3interp(dBdz,chi_s,np_s,dBdz_out,chi_out,Nz)
+ call lag3interp(R_s,chi_s,np_s,R_out,chi_out,Nz)
+ call lag3interp(Z_s,chi_s,np_s,Z_out,chi_out,Nz)
+ call lag3interp(dxdR_s,chi_s,np_s,dxdR_out,chi_out,Nz)
+ call lag3interp(dxdZ_s,chi_s,np_s,dxdZ_out,chi_out,Nz)
+ ! Fill the geom arrays with the results
+ do eo=0,1
+ gxx_(izs:ize,eo) =gxx_out(izs:ize)
+ gyy_(izs:ize,eo) =gyy_out(izs:ize)
+ gxz_(izs:ize,eo) =gxz_out(izs:ize)
+ gyz_(izs:ize,eo) =gyz_out(izs:ize)
+ dBdx_(izs:ize,eo) =dBdx_out(izs:ize)
+ dBdy_(izs:ize,eo) =0.
+ gxy_(izs:ize,eo) =gxy_out(izs:ize)
+ gzz_(izs:ize,eo) =gzz_out(izs:ize)
+ Bfield_(izs:ize,eo) =Bfield_out(izs:ize)
+ jacobian_(izs:ize,eo) =jacobian_out(izs:ize)
+ dBdz_(izs:ize,eo) =dBdz_out(izs:ize)
+ R_hat_(izs:ize,eo) =R_out(izs:ize)
+ Z_hat_(izs:ize,eo) =Z_out(izs:ize)
+ dxdR_(izs:ize,eo) = dxdR_out(izs:ize)
+ dxdZ_(izs:ize,eo) = dxdZ_out(izs:ize)
+
+ !! UPDATE GHOSTS VALUES (since the miller function in GENE does not)
+ CALL update_ghosts_z(gxx_(:,eo))
+ CALL update_ghosts_z(gyy_(:,eo))
+ CALL update_ghosts_z(gxz_(:,eo))
+ CALL update_ghosts_z(gxy_(:,eo))
+ CALL update_ghosts_z(gzz_(:,eo))
+ CALL update_ghosts_z(Bfield_(:,eo))
+ CALL update_ghosts_z(dBdx_(:,eo))
+ CALL update_ghosts_z(dBdy_(:,eo))
+ CALL update_ghosts_z(dBdz_(:,eo))
+ CALL update_ghosts_z(jacobian_(:,eo))
+ CALL update_ghosts_z(R_hat_(:,eo))
+ CALL update_ghosts_z(Z_hat_(:,eo))
+ CALL update_ghosts_z(dxdR_(:,eo))
+ CALL update_ghosts_z(dxdZ_(:,eo))
+
+ ! Curvature operator (Frei et al. 2022 eq 2.15)
+ DO iz = izgs,izge
+ G1 = gxy_(iz,eo)*gxy_(iz,eo)-gxx_(iz,eo)*gyy_(iz,eo)
+ G2 = gxy_(iz,eo)*gxz_(iz,eo)-gxx_(iz,eo)*gyz_(iz,eo)
+ G3 = gyy_(iz,eo)*gxz_(iz,eo)-gxy_(iz,eo)*gyz_(iz,eo)
+ Cx = (G1*dBdy_(iz,eo) + G2*dBdz_(iz,eo))/Bfield_(iz,eo)
+ Cy = (G3*dBdz_(iz,eo) - G1*dBdx_(iz,eo))/Bfield_(iz,eo)
+
+ DO iky = ikys, ikye
+ ky = kyarray(iky)
+ DO ikx= ikxs, ikxe
+ kx = kxarray(ikx)
+ Ckxky_(iky, ikx, iz,eo) = (Cx*kx + Cy*ky)
+ ENDDO
+ ENDDO
+ ! coefficient in the front of parallel derivative
+ gradz_coeff_(iz,eo) = 1._dp / jacobian_(iz,eo) / Bfield_(iz,eo)
+ ENDDO
+ ENDDO
+
+ contains
+
+
+ SUBROUTINE update_ghosts_z(fz_)
+ IMPLICIT NONE
+ ! INTEGER, INTENT(IN) :: nztot_
+ REAL(dp), DIMENSION(izgs:izge), INTENT(INOUT) :: fz_
+ REAL(dp), DIMENSION(-2:2) :: buff
+ INTEGER :: status(MPI_STATUS_SIZE), count
+
+ IF(Nz .GT. 1) THEN
+ IF (num_procs_z .GT. 1) THEN
+ CALL MPI_BARRIER(MPI_COMM_WORLD,ierr)
+ count = 1 ! one point to exchange
+ !!!!!!!!!!! Send ghost to up neighbour !!!!!!!!!!!!!!!!!!!!!!
+ CALL mpi_sendrecv(fz_(ize), count, MPI_DOUBLE, nbr_U, 0, & ! Send to Up the last
+ buff(-1), count, MPI_DOUBLE, nbr_D, 0, & ! Receive from Down the first-1
+ comm0, status, ierr)
+
+ CALL mpi_sendrecv(fz_(ize-1), count, MPI_DOUBLE, nbr_U, 0, & ! Send to Up the last
+ buff(-2), count, MPI_DOUBLE, nbr_D, 0, & ! Receive from Down the first-2
+ comm0, status, ierr)
+
+ !!!!!!!!!!! Send ghost to down neighbour !!!!!!!!!!!!!!!!!!!!!!
+ CALL mpi_sendrecv(fz_(izs), count, MPI_DOUBLE, nbr_D, 0, & ! Send to Down the first
+ buff(+1), count, MPI_DOUBLE, nbr_U, 0, & ! Recieve from Up the last+1
+ comm0, status, ierr)
+
+ CALL mpi_sendrecv(fz_(izs+1), count, MPI_DOUBLE, nbr_D, 0, & ! Send to Down the first
+ buff(+2), count, MPI_DOUBLE, nbr_U, 0, & ! Recieve from Up the last+2
+ comm0, status, ierr)
+ ELSE
+ buff(-1) = fz_(ize )
+ buff(-2) = fz_(ize-1)
+ buff(+1) = fz_(izs )
+ buff(+2) = fz_(izs+1)
+ ENDIF
+ fz_(ize+1) = buff(+1)
+ fz_(ize+2) = buff(+2)
+ fz_(izs-1) = buff(-1)
+ fz_(izs-2) = buff(-2)
+ ENDIF
+ END SUBROUTINE update_ghosts_z
+
+
+ !> Generate an equidistant array from min to max with n points
+ function linspace(min,max,n) result(out)
+ real(dp):: min, max
+ integer:: n
+ real(dp), dimension(n):: out
+
+ do i=1,n
+ out(i)=min+(i-1)*(max-min)/(n-1)
+ enddo
+ end function linspace
+
+ !> Weighted average
+ real(dp) function average(var,weight)
+ real(dp), dimension(np):: var, weight
+ average=sum(var*weight)/sum(weight)
+ end function average
+
+ !> full theta integral with weight function dlp
+ real(dp) function dlp_int(var,dlp)
+ real(dp), dimension(np):: var, dlp
+ dlp_int=sum(var*dlp)*2*pi*Npol_ext/np
+ end function dlp_int
+
+ !> theta integral with weight function dlp, up to index 'ind'
+ real(dp) function dlp_int_ind(var,dlp,ind)
+ real(dp), dimension(np):: var, dlp
+ integer:: ind
+
+ dlp_int_ind=0.
+ if (ind.gt.1) then
+ dlp_int_ind=dlp_int_ind+var(1)*dlp(1)*pi*Npol_ext/np
+ dlp_int_ind=dlp_int_ind+(sum(var(2:ind-1)*dlp(2:ind-1)))*2*pi*Npol_ext/np
+ dlp_int_ind=dlp_int_ind+var(ind)*dlp(ind)*pi*Npol_ext/np
+ endif
+ end function dlp_int_ind
+
+ !> 1st derivative with 2nd order finite differences
+ function deriv_fd(y,x,n) result(out)
+ integer, intent(in) :: n
+ real(dp), dimension(n):: x,y,out,dx
+
+ !call lag3deriv(y,x,n,out,x,n)
+
+ out=0.
+ do i=2,n-1
+ out(i)=out(i)-y(i-1)/2
+ out(i)=out(i)+y(i+1)/2
+ enddo
+ out(1)=y(2)-y(1)
+ out(n)=y(n)-y(n-1)
+ dx=x(2)-x(1)
+ out=out/dx
+
+ end function deriv_fd
+
+
+ end subroutine get_miller
+
+
+END MODULE miller
diff --git a/src/model_mod.F90 b/src/model_mod.F90
index 75a2768..5d28283 100644
--- a/src/model_mod.F90
+++ b/src/model_mod.F90
@@ -1,152 +1,154 @@
MODULE model
! Module for diagnostic parameters
USE prec_const
IMPLICIT NONE
PRIVATE
INTEGER, PUBLIC, PROTECTED :: CLOS = 0 ! linear truncation method
INTEGER, PUBLIC, PROTECTED :: NL_CLOS = 0 ! nonlinear truncation method
INTEGER, PUBLIC, PROTECTED :: KERN = 0 ! Kernel model
CHARACTER(len=16), &
PUBLIC, PROTECTED ::LINEARITY= 'linear' ! To turn on non linear bracket term
LOGICAL, PUBLIC, PROTECTED :: KIN_E = .true. ! Simulate kinetic electron (adiabatic otherwise)
REAL(dp), PUBLIC, PROTECTED :: mu_x = 0._dp ! spatial x-Hyperdiffusivity coefficient (for num. stability)
REAL(dp), PUBLIC, PROTECTED :: mu_y = 0._dp ! spatial y-Hyperdiffusivity coefficient (for num. stability)
REAL(dp), PUBLIC, PROTECTED :: mu_z = 0._dp ! spatial z-Hyperdiffusivity coefficient (for num. stability)
REAL(dp), PUBLIC, PROTECTED :: mu_p = 0._dp ! kinetic para hyperdiffusivity coefficient (for num. stability)
REAL(dp), PUBLIC, PROTECTED :: mu_j = 0._dp ! kinetic perp hyperdiffusivity coefficient (for num. stability)
INTEGER, PUBLIC, PROTECTED :: N_HD = 4 ! order of numerical spatial diffusion
REAL(dp), PUBLIC, PROTECTED :: nu = 0._dp ! Collision frequency
REAL(dp), PUBLIC, PROTECTED :: tau_e = 1._dp ! Temperature
REAL(dp), PUBLIC, PROTECTED :: tau_i = 1._dp !
REAL(dp), PUBLIC, PROTECTED :: sigma_e = 0.023338_dp! sqrt of electron ion mass ratio
REAL(dp), PUBLIC, PROTECTED :: sigma_i = 1._dp !
REAL(dp), PUBLIC, PROTECTED :: q_e = -1._dp ! Charge
REAL(dp), PUBLIC, PROTECTED :: q_i = 1._dp !
REAL(dp), PUBLIC, PROTECTED :: k_Ni = 7._dp ! Ion density drive
REAL(dp), PUBLIC, PROTECTED :: k_Ne = 7._dp ! Ele ''
REAL(dp), PUBLIC, PROTECTED :: k_Ti = 2._dp ! Ion temperature drive
REAL(dp), PUBLIC, PROTECTED :: k_Te = 2._dp ! Ele ''
REAL(dp), PUBLIC, PROTECTED :: K_E = 0._dp ! Backg. electric field drive
REAL(dp), PUBLIC, PROTECTED :: GradB = 1._dp ! Magnetic gradient
REAL(dp), PUBLIC, PROTECTED :: CurvB = 1._dp ! Magnetic curvature
REAL(dp), PUBLIC, PROTECTED :: lambdaD = 1._dp ! Debye length
REAL(dp), PUBLIC, PROTECTED :: beta = 0._dp ! electron plasma Beta (8piNT_e/B0^2)
LOGICAL, PUBLIC, PROTECTED :: EM = .false. ! Electromagnetic effects flag
REAL(dp), PUBLIC, PROTECTED :: taue_qe ! factor of the magnetic moment coupling
REAL(dp), PUBLIC, PROTECTED :: taui_qi !
REAL(dp), PUBLIC, PROTECTED :: qi_taui !
REAL(dp), PUBLIC, PROTECTED :: qe_taue !
REAL(dp), PUBLIC, PROTECTED :: sqrtTaue_qe ! factor of parallel moment term
REAL(dp), PUBLIC, PROTECTED :: sqrtTaui_qi !
REAL(dp), PUBLIC, PROTECTED :: qe_sigmae_sqrtTaue ! factor of parallel phi term
REAL(dp), PUBLIC, PROTECTED :: qi_sigmai_sqrtTaui !
REAL(dp), PUBLIC, PROTECTED :: sigmae2_taue_o2 ! factor of the Kernel argument
REAL(dp), PUBLIC, PROTECTED :: sigmai2_taui_o2 !
REAL(dp), PUBLIC, PROTECTED :: sqrt_sigmae2_taue_o2 ! factor of the Kernel argument
REAL(dp), PUBLIC, PROTECTED :: sqrt_sigmai2_taui_o2
REAL(dp), PUBLIC, PROTECTED :: nu_e, nu_i ! electron-ion, ion-ion collision frequency
REAL(dp), PUBLIC, PROTECTED :: nu_ee, nu_ie ! e-e, i-e coll. frequ.
REAL(dp), PUBLIC, PROTECTED :: qe2_taue, qi2_taui ! factor of the gammaD sum
REAL(dp), PUBLIC, PROTECTED :: q_o_sqrt_tau_sigma_e, q_o_sqrt_tau_sigma_i
REAL(dp), PUBLIC, PROTECTED :: sqrt_tau_o_sigma_e, sqrt_tau_o_sigma_i
+ REAL(dp), PUBLIC, PROTECTED :: dpdx = 0 ! radial pressure gradient
PUBLIC :: model_readinputs, model_outputinputs
CONTAINS
SUBROUTINE model_readinputs
! Read the input parameters
USE basic, ONLY : lu_in, my_id
USE prec_const
IMPLICIT NONE
NAMELIST /MODEL_PAR/ CLOS, NL_CLOS, KERN, LINEARITY, KIN_E, &
mu_x, mu_y, N_HD, mu_z, mu_p, mu_j, nu,&
tau_e, tau_i, sigma_e, sigma_i, q_e, q_i,&
k_Ne, k_Ni, k_Te, k_Ti, GradB, CurvB, lambdaD, beta
READ(lu_in,model_par)
IF(.NOT. KIN_E) THEN
IF(my_id.EQ.0) print*, 'Adiabatic electron model -> beta = 0'
beta = 0._dp
ENDIF
IF(beta .GT. 0) THEN
- EM = .TRUE.
IF(my_id.EQ.0) print*, 'Electromagnetic effects are included'
+ EM = .TRUE.
+ dpdx = -(tau_i*(k_Ni + k_Ti) + tau_e*(k_Ne + k_Te))
ENDIF
taue_qe = tau_e/q_e ! factor of the magnetic moment coupling
taui_qi = tau_i/q_i ! factor of the magnetic moment coupling
qe_taue = q_e/tau_e
qi_taui = q_i/tau_i
sqrtTaue_qe = sqrt(tau_e)/q_e ! factor of parallel moment term
sqrtTaui_qi = sqrt(tau_i)/q_i ! factor of parallel moment term
qe_sigmae_sqrtTaue = q_e/sigma_e/SQRT(tau_e) ! factor of parallel phi term
qi_sigmai_sqrtTaui = q_i/sigma_i/SQRT(tau_i)
qe2_taue = (q_e**2)/tau_e ! factor of the gammaD sum
qi2_taui = (q_i**2)/tau_i
sigmae2_taue_o2 = sigma_e**2 * tau_e/2._dp ! factor of the Kernel argument
sigmai2_taui_o2 = sigma_i**2 * tau_i/2._dp
sqrt_sigmae2_taue_o2 = SQRT(sigma_e**2 * tau_e/2._dp) ! to avoid multiple SQRT eval
sqrt_sigmai2_taui_o2 = SQRT(sigma_i**2 * tau_i/2._dp)
q_o_sqrt_tau_sigma_e = q_e/SQRT(tau_e)/sigma_e ! For psi field terms
q_o_sqrt_tau_sigma_i = q_i/SQRT(tau_i)/sigma_i ! For psi field terms
sqrt_tau_o_sigma_e = SQRT(tau_e)/sigma_e ! For Ampere eq
sqrt_tau_o_sigma_i = SQRT(tau_i)/sigma_i
!! We use the ion-ion collision as normalization with definition
! nu_ii = 4 sqrt(pi)/3 T_i^(-3/2) m_i^(-1/2) q^4 n_i0 ln(Lambda)
!
nu_e = nu/sigma_e * (tau_e)**(3._dp/2._dp) ! electron-ion collision frequency (where already multiplied by 0.532)
nu_i = nu ! ion-ion collision frequ.
nu_ee = nu_e ! e-e coll. frequ.
nu_ie = nu_i ! i-e coll. frequ.
! Old normalization (MOLI Jorge/Frei)
! nu_e = 0.532_dp*nu ! electron-ion collision frequency (where already multiplied by 0.532)
! nu_i = 0.532_dp*nu*sigma_e*tau_e**(-3._dp/2._dp)/SQRT2 ! ion-ion collision frequ.
! nu_ee = nu_e/SQRT2 ! e-e coll. frequ.
! nu_ie = 0.532_dp*nu*sigma_e**2 ! i-e coll. frequ.
END SUBROUTINE model_readinputs
SUBROUTINE model_outputinputs(fidres, str)
! Write the input parameters to the results_xx.h5 file
USE futils, ONLY: attach
USE prec_const
IMPLICIT NONE
INTEGER, INTENT(in) :: fidres
CHARACTER(len=256), INTENT(in) :: str
CALL attach(fidres, TRIM(str), "CLOS", CLOS)
CALL attach(fidres, TRIM(str), "KERN", KERN)
CALL attach(fidres, TRIM(str), "LINEARITY", LINEARITY)
CALL attach(fidres, TRIM(str), "KIN_E", KIN_E)
CALL attach(fidres, TRIM(str), "nu", nu)
CALL attach(fidres, TRIM(str), "mu", 0)
CALL attach(fidres, TRIM(str), "mu_x", mu_x)
CALL attach(fidres, TRIM(str), "mu_y", mu_y)
CALL attach(fidres, TRIM(str), "mu_z", mu_z)
CALL attach(fidres, TRIM(str), "mu_p", mu_p)
CALL attach(fidres, TRIM(str), "mu_j", mu_j)
CALL attach(fidres, TRIM(str), "tau_e", tau_e)
CALL attach(fidres, TRIM(str), "tau_i", tau_i)
CALL attach(fidres, TRIM(str), "sigma_e", sigma_e)
CALL attach(fidres, TRIM(str), "sigma_i", sigma_i)
CALL attach(fidres, TRIM(str), "q_e", q_e)
CALL attach(fidres, TRIM(str), "q_i", q_i)
CALL attach(fidres, TRIM(str), "k_Ne", k_Ne)
CALL attach(fidres, TRIM(str), "k_Ni", k_Ni)
CALL attach(fidres, TRIM(str), "k_Te", k_Te)
CALL attach(fidres, TRIM(str), "k_Ti", k_Ti)
CALL attach(fidres, TRIM(str), "K_E", K_E)
CALL attach(fidres, TRIM(str), "lambdaD", lambdaD)
CALL attach(fidres, TRIM(str), "beta", beta)
END SUBROUTINE model_outputinputs
END MODULE model
diff --git a/src/moments_eq_rhs_mod.F90 b/src/moments_eq_rhs_mod.F90
index 8123fe7..948d66c 100644
--- a/src/moments_eq_rhs_mod.F90
+++ b/src/moments_eq_rhs_mod.F90
@@ -1,403 +1,407 @@
MODULE moments_eq_rhs
IMPLICIT NONE
PUBLIC :: compute_moments_eq_rhs
CONTAINS
SUBROUTINE compute_moments_eq_rhs
USE model, only: KIN_E
IMPLICIT NONE
IF(KIN_E) CALL moments_eq_rhs_e
CALL moments_eq_rhs_i
!! BETA TESTING !!
IF(.false.) CALL add_Maxwellian_background_terms
END SUBROUTINE compute_moments_eq_rhs
!_____________________________________________________________________________!
!_____________________________________________________________________________!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!! Electrons moments RHS !!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!_____________________________________________________________________________!
SUBROUTINE moments_eq_rhs_e
USE basic
USE time_integration
USE array, ONLY: xnepj, xnepp2j, xnepm2j, xnepjp1, xnepjm1, xnepp1j, xnepm1j,&
ynepp1j, ynepp1jm1, ynepm1j, ynepm1jm1, &
znepm1j, znepm1jp1, znepm1jm1, &
xphij_e, xphijp1_e, xphijm1_e, xpsij_e, xpsijp1_e, xpsijm1_e,&
nadiab_moments_e, ddz_nepj, interp_nepj, moments_rhs_e, Sepj,&
TColl_e, ddzND_nepj, kernel_e
USE fields, ONLY: phi, psi, moments_e
USE grid
USE model
USE prec_const
USE collision
- USE geometry, ONLY: gradz_coeff, gradzB, Ckxky, hatB_NL, hatR
+ USE geometry, ONLY: gradz_coeff, gradzB, Ckxky, hatB_NL, hatB
USE calculus, ONLY : interp_z, grad_z, grad_z2
IMPLICIT NONE
INTEGER :: p_int, j_int ! loops indices and polynom. degrees
REAL(dp) :: kx, ky, kperp2, dzlnB_o_J
COMPLEX(dp) :: Tnepj, Tnepp2j, Tnepm2j, Tnepjp1, Tnepjm1 ! Terms from b x gradB and drives
COMPLEX(dp) :: Tnepp1j, Tnepm1j, Tnepp1jm1, Tnepm1jm1 ! Terms from mirror force with non adiab moments
COMPLEX(dp) :: Tperp, Tpar, Tmir, Tphi, Tpsi
COMPLEX(dp) :: Unepm1j, Unepm1jp1, Unepm1jm1 ! Terms from mirror force with adiab moments
COMPLEX(dp) :: i_kx,i_ky,phikykxz, psikykxz
! Measuring execution time
CALL cpu_time(t0_rhs)
! Spatial loops
zloope : DO iz = izs,ize
kxloope : DO ikx = ikxs,ikxe
kx = kxarray(ikx) ! radial wavevector
i_kx = imagu * kx ! toroidal derivative
kyloope : DO iky = ikys,ikye
ky = kyarray(iky) ! toroidal wavevector
i_ky = imagu * ky ! toroidal derivative
phikykxz = phi(iky,ikx,iz)! tmp phi value
psikykxz = psi(iky,ikx,iz)! tmp psi value
! Kinetic loops
jloope : DO ij = ijs_e, ije_e ! This loop is from 1 to jmaxi+1
j_int = jarray_e(ij)
ploope : DO ip = ips_e, ipe_e ! Hermite loop
p_int = parray_e(ip) ! Hermite degree
eo = MODULO(p_int,2) ! Indicates if we are on odd or even z grid
kperp2= kparray(iky,ikx,iz,eo)**2
IF((CLOS .NE. 1) .OR. (p_int+2*j_int .LE. dmaxe)) THEN
!! Compute moments mixing terms
Tperp = 0._dp; Tpar = 0._dp; Tmir = 0._dp
! Perpendicular dynamic
! term propto n_e^{p,j}
Tnepj = xnepj(ip,ij)* nadiab_moments_e(ip,ij,iky,ikx,iz)
! term propto n_e^{p+2,j}
Tnepp2j = xnepp2j(ip) * nadiab_moments_e(ip+pp2,ij,iky,ikx,iz)
! term propto n_e^{p-2,j}
Tnepm2j = xnepm2j(ip) * nadiab_moments_e(ip-pp2,ij,iky,ikx,iz)
! term propto n_e^{p,j+1}
Tnepjp1 = xnepjp1(ij) * nadiab_moments_e(ip,ij+1,iky,ikx,iz)
! term propto n_e^{p,j-1}
Tnepjm1 = xnepjm1(ij) * nadiab_moments_e(ip,ij-1,iky,ikx,iz)
! Tperp
Tperp = Tnepj + Tnepp2j + Tnepm2j + Tnepjp1 + Tnepjm1
! Parallel dynamic
! ddz derivative for Landau damping term
Tpar = xnepp1j(ip) * ddz_nepj(ip+1,ij,iky,ikx,iz) &
+ xnepm1j(ip) * ddz_nepj(ip-1,ij,iky,ikx,iz)
! Mirror terms
Tnepp1j = ynepp1j (ip,ij) * interp_nepj(ip+1,ij ,iky,ikx,iz)
Tnepp1jm1 = ynepp1jm1(ip,ij) * interp_nepj(ip+1,ij-1,iky,ikx,iz)
Tnepm1j = ynepm1j (ip,ij) * interp_nepj(ip-1,ij ,iky,ikx,iz)
Tnepm1jm1 = ynepm1jm1(ip,ij) * interp_nepj(ip-1,ij-1,iky,ikx,iz)
! Trapping terms
Unepm1j = znepm1j (ip,ij) * interp_nepj(ip-1,ij ,iky,ikx,iz)
Unepm1jp1 = znepm1jp1(ip,ij) * interp_nepj(ip-1,ij+1,iky,ikx,iz)
Unepm1jm1 = znepm1jm1(ip,ij) * interp_nepj(ip-1,ij-1,iky,ikx,iz)
Tmir = Tnepp1j + Tnepp1jm1 + Tnepm1j + Tnepm1jm1 + Unepm1j + Unepm1jp1 + Unepm1jm1
!! Electrical potential term
IF ( p_int .LE. 2 ) THEN ! kronecker p0 p1 p2
Tphi = (xphij_e (ip,ij)*kernel_e(ij ,iky,ikx,iz,eo) &
+ xphijp1_e(ip,ij)*kernel_e(ij+1,iky,ikx,iz,eo) &
+ xphijm1_e(ip,ij)*kernel_e(ij-1,iky,ikx,iz,eo))*phikykxz
ELSE
Tphi = 0._dp
ENDIF
!! Vector potential term
IF ( (p_int .LE. 3) .AND. (p_int .GE. 1) ) THEN ! Kronecker p1 or p3
Tpsi = (xpsij_e (ip,ij)*kernel_e(ij ,iky,ikx,iz,eo) &
+ xpsijp1_e(ip,ij)*kernel_e(ij+1,iky,ikx,iz,eo) &
+ xpsijm1_e(ip,ij)*kernel_e(ij-1,iky,ikx,iz,eo))*psikykxz
ELSE
Tpsi = 0._dp
ENDIF
!! Sum of all RHS terms
moments_rhs_e(ip,ij,iky,ikx,iz,updatetlevel) = &
! Perpendicular magnetic gradient/curvature effects
- -imagu*Ckxky(iky,ikx,iz,eo)*hatR(iz,eo) * Tperp&
+ -imagu*Ckxky(iky,ikx,iz,eo)*hatB(iz,eo) * Tperp&
+ ! Perpendicular pressure effects
+ -i_ky*beta*dpdx * Tperp&
! Parallel coupling (Landau Damping)
-gradz_coeff(iz,eo) * Tpar &
! Mirror term (parallel magnetic gradient)
-gradzB(iz,eo)*gradz_coeff(iz,eo) * Tmir&
! Drives (density + temperature gradients)
-i_ky * (Tphi - Tpsi) &
! Numerical perpendicular hyperdiffusion (totally artificial, for stability purpose)
-mu_x*diff_kx_coeff*kx**N_HD*moments_e(ip,ij,iky,ikx,iz,updatetlevel) &
-mu_y*diff_ky_coeff*ky**N_HD*moments_e(ip,ij,iky,ikx,iz,updatetlevel) &
! Numerical parallel hyperdiffusion "mu_z*ddz**4" see Pueschel 2010 (eq 25)
-mu_z*diff_dz_coeff*ddzND_nepj(ip,ij,iky,ikx,iz) &
! Collision term
+TColl_e(ip,ij,iky,ikx,iz) &
! Nonlinear term
-hatB_NL(iz,eo) * Sepj(ip,ij,iky,ikx,iz)
IF(ip-4 .GT. 0) &
! Numerical parallel velocity hyperdiffusion "+ dvpar4 g_a" see Pueschel 2010 (eq 33)
moments_rhs_e(ip,ij,iky,ikx,iz,updatetlevel) = &
moments_rhs_e(ip,ij,iky,ikx,iz,updatetlevel) &
+ mu_p * moments_e(ip-4,ij,iky,ikx,iz,updatetlevel)
ELSE
moments_rhs_e(ip,ij,iky,ikx,iz,updatetlevel) = 0._dp
ENDIF
END DO ploope
END DO jloope
END DO kyloope
END DO kxloope
END DO zloope
! Execution time end
CALL cpu_time(t1_rhs)
tc_rhs = tc_rhs + (t1_rhs-t0_rhs)
END SUBROUTINE moments_eq_rhs_e
!_____________________________________________________________________________!
!_____________________________________________________________________________!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!! Ions moments RHS !!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!_____________________________________________________________________________!
SUBROUTINE moments_eq_rhs_i
USE basic
USE time_integration, ONLY: updatetlevel
USE array, ONLY: xnipj, xnipp2j, xnipm2j, xnipjp1, xnipjm1, xnipp1j, xnipm1j,&
ynipp1j, ynipp1jm1, ynipm1j, ynipm1jm1, &
znipm1j, znipm1jp1, znipm1jm1, &
xphij_i, xphijp1_i, xphijm1_i, xpsij_i, xpsijp1_i, xpsijm1_i,&
nadiab_moments_i, ddz_nipj, interp_nipj, moments_rhs_i, Sipj,&
TColl_i, ddzND_nipj, kernel_i
USE fields, ONLY: phi, psi, moments_i
USE grid
USE model
USE prec_const
USE collision
- USE geometry, ONLY: gradz_coeff, gradzB, Ckxky, hatB_NL, hatR
+ USE geometry, ONLY: gradz_coeff, gradzB, Ckxky, hatB_NL, hatB
USE calculus, ONLY : interp_z, grad_z, grad_z2
IMPLICIT NONE
INTEGER :: p_int, j_int ! loops indices and polynom. degrees
REAL(dp) :: kx, ky, kperp2
COMPLEX(dp) :: Tnipj, Tnipp2j, Tnipm2j, Tnipjp1, Tnipjm1
COMPLEX(dp) :: Tnipp1j, Tnipm1j, Tnipp1jm1, Tnipm1jm1 ! Terms from mirror force with non adiab moments
COMPLEX(dp) :: Unipm1j, Unipm1jp1, Unipm1jm1 ! Terms from mirror force with adiab moments
COMPLEX(dp) :: Tperp, Tpar, Tmir, Tphi, Tpsi
COMPLEX(dp) :: i_kx, i_ky, phikykxz, psikykxz
! Measuring execution time
CALL cpu_time(t0_rhs)
! Spatial loops
zloopi : DO iz = izs,ize
kxloopi : DO ikx = ikxs,ikxe
kx = kxarray(ikx) ! radial wavevector
i_kx = imagu * kx ! toroidal derivative
kyloopi : DO iky = ikys,ikye
ky = kyarray(iky) ! toroidal wavevector
i_ky = imagu * ky ! toroidal derivative
phikykxz = phi(iky,ikx,iz)! tmp phi value
psikykxz = psi(iky,ikx,iz)! tmp phi value
! Kinetic loops
jloopi : DO ij = ijs_i, ije_i ! This loop is from 1 to jmaxi+1
j_int = jarray_i(ij)
ploopi : DO ip = ips_i, ipe_i ! Hermite loop
p_int = parray_i(ip) ! Hermite degree
eo = MODULO(p_int,2) ! Indicates if we are on odd or even z grid
kperp2= kparray(iky,ikx,iz,eo)**2
IF((CLOS .NE. 1) .OR. (p_int+2*j_int .LE. dmaxi)) THEN
!! Compute moments mixing terms
Tperp = 0._dp; Tpar = 0._dp; Tmir = 0._dp
! Perpendicular dynamic
! term propto n_i^{p,j}
Tnipj = xnipj(ip,ij) * nadiab_moments_i(ip ,ij ,iky,ikx,iz)
! term propto n_i^{p+2,j}
Tnipp2j = xnipp2j(ip) * nadiab_moments_i(ip+pp2,ij ,iky,ikx,iz)
! term propto n_i^{p-2,j}
Tnipm2j = xnipm2j(ip) * nadiab_moments_i(ip-pp2,ij ,iky,ikx,iz)
! term propto n_i^{p,j+1}
Tnipjp1 = xnipjp1(ij) * nadiab_moments_i(ip ,ij+1,iky,ikx,iz)
! term propto n_i^{p,j-1}
Tnipjm1 = xnipjm1(ij) * nadiab_moments_i(ip ,ij-1,iky,ikx,iz)
! Tperp
Tperp = Tnipj + Tnipp2j + Tnipm2j + Tnipjp1 + Tnipjm1
! Parallel dynamic
! ddz derivative for Landau damping term
Tpar = xnipp1j(ip) * ddz_nipj(ip+1,ij,iky,ikx,iz) &
+ xnipm1j(ip) * ddz_nipj(ip-1,ij,iky,ikx,iz)
! Mirror terms
Tnipp1j = ynipp1j (ip,ij) * interp_nipj(ip+1,ij ,iky,ikx,iz)
Tnipp1jm1 = ynipp1jm1(ip,ij) * interp_nipj(ip+1,ij-1,iky,ikx,iz)
Tnipm1j = ynipm1j (ip,ij) * interp_nipj(ip-1,ij ,iky,ikx,iz)
Tnipm1jm1 = ynipm1jm1(ip,ij) * interp_nipj(ip-1,ij-1,iky,ikx,iz)
! Trapping terms
Unipm1j = znipm1j (ip,ij) * interp_nipj(ip-1,ij ,iky,ikx,iz)
Unipm1jp1 = znipm1jp1(ip,ij) * interp_nipj(ip-1,ij+1,iky,ikx,iz)
Unipm1jm1 = znipm1jm1(ip,ij) * interp_nipj(ip-1,ij-1,iky,ikx,iz)
Tmir = Tnipp1j + Tnipp1jm1 + Tnipm1j + Tnipm1jm1 + Unipm1j + Unipm1jp1 + Unipm1jm1
!! Electrical potential term
IF ( p_int .LE. 2 ) THEN ! kronecker p0 p1 p2
Tphi = (xphij_i (ip,ij)*kernel_i(ij ,iky,ikx,iz,eo) &
+ xphijp1_i(ip,ij)*kernel_i(ij+1,iky,ikx,iz,eo) &
+ xphijm1_i(ip,ij)*kernel_i(ij-1,iky,ikx,iz,eo))*phikykxz
ELSE
Tphi = 0._dp
ENDIF
!! Vector potential term
IF ( (p_int .LE. 3) .AND. (p_int .GE. 1) ) THEN ! Kronecker p1 or p3
Tpsi = (xpsij_i (ip,ij)*kernel_i(ij ,iky,ikx,iz,eo) &
+ xpsijp1_i(ip,ij)*kernel_i(ij+1,iky,ikx,iz,eo) &
+ xpsijm1_i(ip,ij)*kernel_i(ij-1,iky,ikx,iz,eo))*psikykxz
ELSE
Tpsi = 0._dp
ENDIF
!! Sum of all RHS terms
moments_rhs_i(ip,ij,iky,ikx,iz,updatetlevel) = &
! Perpendicular magnetic gradient/curvature effects
- -imagu*Ckxky(iky,ikx,iz,eo)*hatR(iz,eo) * Tperp &
+ -imagu*Ckxky(iky,ikx,iz,eo)*hatB(iz,eo) * Tperp &
+ ! Perpendicular pressure effects
+ -i_ky*beta*dpdx * Tperp&
! Parallel coupling (Landau damping)
-gradz_coeff(iz,eo) * Tpar &
! Mirror term (parallel magnetic gradient)
-gradzB(iz,eo)*gradz_coeff(iz,eo) * Tmir &
! Drives (density + temperature gradients)
-i_ky * (Tphi - Tpsi) &
! Numerical hyperdiffusion (totally artificial, for stability purpose)
-mu_x*diff_kx_coeff*kx**N_HD*moments_i(ip,ij,iky,ikx,iz,updatetlevel) &
-mu_y*diff_ky_coeff*ky**N_HD*moments_i(ip,ij,iky,ikx,iz,updatetlevel) &
! Numerical parallel hyperdiffusion "mu_z*ddz**4"
-mu_z*diff_dz_coeff*ddzND_nipj(ip,ij,iky,ikx,iz) &
! Collision term
+TColl_i(ip,ij,iky,ikx,iz)&
! Nonlinear term with a (gxx*gxy - gxy**2)^1/2 factor
-hatB_NL(iz,eo) * Sipj(ip,ij,iky,ikx,iz)
IF(ip-4 .GT. 0) &
! Numerical parallel velocity hyperdiffusion "+ dvpar4 g_a" see Pueschel 2010 (eq 33)
moments_rhs_i(ip,ij,iky,ikx,iz,updatetlevel) = &
moments_rhs_i(ip,ij,iky,ikx,iz,updatetlevel) &
+ mu_p * moments_i(ip-4,ij,iky,ikx,iz,updatetlevel)
ELSE
moments_rhs_i(ip,ij,iky,ikx,iz,updatetlevel) = 0._dp
ENDIF
END DO ploopi
END DO jloopi
END DO kyloopi
END DO kxloopi
END DO zloopi
! Execution time end
CALL cpu_time(t1_rhs)
tc_rhs = tc_rhs + (t1_rhs-t0_rhs)
END SUBROUTINE moments_eq_rhs_i
SUBROUTINE add_Maxwellian_background_terms
! This routine is meant to add the terms rising from the magnetic operator,
! i.e. (B x GradB) Grad, applied on the background Maxwellian distribution
! (x_a + spar^2)(b x GradB) GradFaM
! It gives birth to kx=ky=0 sources terms (averages) that hit moments 00, 20,
! 40, 01,02, 21 with background gradient dependences.
USE prec_const
USE time_integration, ONLY : updatetlevel
USE model, ONLY: taue_qe, taui_qi, k_Ni, k_Ne, k_Ti, k_Te, KIN_E
USE array, ONLY: moments_rhs_e, moments_rhs_i
USE grid, ONLY: contains_kx0, contains_ky0, ikx_0, iky_0,&
ips_e,ipe_e,ijs_e,ije_e,ips_i,ipe_i,ijs_i,ije_i,&
jarray_e,parray_e,jarray_i,parray_i, zarray, izs,ize,&
ip,ij
IMPLICIT NONE
real(dp), DIMENSION(izs:ize) :: sinz
sinz(izs:ize) = SIN(zarray(izs:ize,0))
IF(contains_kx0 .AND. contains_ky0) THEN
IF(KIN_E) THEN
DO ip = ips_e,ipe_e
DO ij = ijs_e,ije_e
SELECT CASE(ij-1)
CASE(0) ! j = 0
SELECT CASE (ip-1)
CASE(0) ! Na00 term
moments_rhs_e(ip,ij,iky_0,ikx_0,izs:ize,updatetlevel) = moments_rhs_e(ip,ij,iky_0,ikx_0,izs:ize,updatetlevel)&
+taue_qe * sinz(izs:ize) * (1.5_dp*k_Ne - 1.125_dp*k_Te)
CASE(2) ! Na20 term
moments_rhs_e(ip,ij,iky_0,ikx_0,izs:ize,updatetlevel) = moments_rhs_e(ip,ij,iky_0,ikx_0,izs:ize,updatetlevel)&
+taue_qe * sinz(izs:ize) * (SQRT2*0.5_dp*k_Ne - 2.75_dp*k_Te)
CASE(4) ! Na40 term
moments_rhs_e(ip,ij,iky_0,ikx_0,izs:ize,updatetlevel) = moments_rhs_e(ip,ij,iky_0,ikx_0,izs:ize,updatetlevel)&
+taue_qe * sinz(izs:ize) * SQRT6*0.75_dp*k_Te
END SELECT
CASE(1) ! j = 1
SELECT CASE (ip-1)
CASE(0) ! Na01 term
moments_rhs_e(ip,ij,iky_0,ikx_0,izs:ize,updatetlevel) = moments_rhs_e(ip,ij,iky_0,ikx_0,izs:ize,updatetlevel)&
-taue_qe * sinz(izs:ize) * (k_Ne + 3.5_dp*k_Te)
CASE(2) ! Na21 term
moments_rhs_e(ip,ij,iky_0,ikx_0,izs:ize,updatetlevel) = moments_rhs_e(ip,ij,iky_0,ikx_0,izs:ize,updatetlevel)&
-taue_qe * sinz(izs:ize) * SQRT2*k_Te
END SELECT
CASE(2) ! j = 2
SELECT CASE (ip-1)
CASE(0) ! Na02 term
moments_rhs_e(ip,ij,iky_0,ikx_0,izs:ize,updatetlevel) = moments_rhs_e(ip,ij,iky_0,ikx_0,izs:ize,updatetlevel)&
+taue_qe * sinz(izs:ize) * 2._dp*k_Te
END SELECT
END SELECT
ENDDO
ENDDO
ENDIF
DO ip = ips_i,ipe_i
DO ij = ijs_i,ije_i
SELECT CASE(ij-1)
CASE(0) ! j = 0
SELECT CASE (ip-1)
CASE(0) ! Na00 term
moments_rhs_i(ip,ij,iky_0,ikx_0,izs:ize,updatetlevel) = moments_rhs_i(ip,ij,iky_0,ikx_0,izs:ize,updatetlevel)&
+taui_qi * sinz(izs:ize) * (1.5_dp*k_Ni - 1.125_dp*k_Ti)
CASE(2) ! Na20 term
moments_rhs_i(ip,ij,iky_0,ikx_0,izs:ize,updatetlevel) = moments_rhs_i(ip,ij,iky_0,ikx_0,izs:ize,updatetlevel)&
+taui_qi * sinz(izs:ize) * (SQRT2*0.5_dp*k_Ni - 2.75_dp*k_Ti)
CASE(4) ! Na40 term
moments_rhs_i(ip,ij,iky_0,ikx_0,izs:ize,updatetlevel) = moments_rhs_i(ip,ij,iky_0,ikx_0,izs:ize,updatetlevel)&
+taui_qi * sinz(izs:ize) * SQRT6*0.75_dp*k_Ti
END SELECT
CASE(1) ! j = 1
SELECT CASE (ip-1)
CASE(0) ! Na01 term
moments_rhs_i(ip,ij,iky_0,ikx_0,izs:ize,updatetlevel) = moments_rhs_i(ip,ij,iky_0,ikx_0,izs:ize,updatetlevel)&
-taui_qi * sinz(izs:ize) * (k_Ni + 3.5_dp*k_Ti)
CASE(2) ! Na21 term
moments_rhs_i(ip,ij,iky_0,ikx_0,izs:ize,updatetlevel) = moments_rhs_i(ip,ij,iky_0,ikx_0,izs:ize,updatetlevel)&
-taui_qi * sinz(izs:ize) * SQRT2*k_Ti
END SELECT
CASE(2) ! j = 2
SELECT CASE (ip-1)
CASE(0) ! Na02 term
moments_rhs_i(ip,ij,iky_0,ikx_0,izs:ize,updatetlevel) = moments_rhs_i(ip,ij,iky_0,ikx_0,izs:ize,updatetlevel)&
+taui_qi * sinz(izs:ize) * 2._dp*k_Ti
END SELECT
END SELECT
ENDDO
ENDDO
ENDIF
END SUBROUTINE
END MODULE moments_eq_rhs
diff --git a/src/nonlinear_mod.F90 b/src/nonlinear_mod.F90
index 8e9a2ce..6154717 100644
--- a/src/nonlinear_mod.F90
+++ b/src/nonlinear_mod.F90
@@ -1,463 +1,463 @@
MODULE nonlinear
USE array, ONLY : dnjs, Sepj, Sipj, kernel_i, kernel_e,&
moments_e_ZF, moments_i_ZF, phi_ZF
USE initial_par, ONLY : ACT_ON_MODES
USE basic
USE fourier
USE fields, ONLY : phi, psi, moments_e, moments_i
USE grid
USE model
USE prec_const
USE time_integration, ONLY : updatetlevel
IMPLICIT NONE
INCLUDE 'fftw3-mpi.f03'
COMPLEX(dp), DIMENSION(:,:), ALLOCATABLE :: F_cmpx, G_cmpx
COMPLEX(dp), DIMENSION(:,:), ALLOCATABLE :: Fx_cmpx, Gy_cmpx
COMPLEX(dp), DIMENSION(:,:), ALLOCATABLE :: Fy_cmpx, Gx_cmpx, F_conv_G
INTEGER :: in, is, p_int, j_int
INTEGER :: nmax, smax ! Upper bound of the sums
REAL(dp):: kx, ky, kerneln, sqrt_p, sqrt_pp1
PUBLIC :: compute_Sapj, nonlinear_init
CONTAINS
SUBROUTINE nonlinear_init
ALLOCATE( F_cmpx(ikys:ikye,ikxs:ikxe))
ALLOCATE( G_cmpx(ikys:ikye,ikxs:ikxe))
ALLOCATE(Fx_cmpx(ikys:ikye,ikxs:ikxe))
ALLOCATE(Gy_cmpx(ikys:ikye,ikxs:ikxe))
ALLOCATE(Fy_cmpx(ikys:ikye,ikxs:ikxe))
ALLOCATE(Gx_cmpx(ikys:ikye,ikxs:ikxe))
ALLOCATE(F_conv_G(ikys:ikye,ikxs:ikxe))
END SUBROUTINE nonlinear_init
SUBROUTINE compute_Sapj
! This routine is meant to compute the non linear term for each specie and degree
!! In real space Sapj ~ b*(grad(phi) x grad(g)) which in moments in fourier becomes
!! Sapj = Sum_n (ikx Kn phi)#(iky Sum_s d_njs Naps) - (iky Kn phi)#(ikx Sum_s d_njs Naps)
!! where # denotes the convolution.
! Execution time start
CALL cpu_time(t0_Sapj)
SELECT CASE(LINEARITY)
CASE ('nonlinear')
CALL compute_nonlinear
CASE ('ZF_semilin')
CALL compute_semi_linear_ZF
CASE ('NZ_semilin')
CALL compute_semi_linear_NZ
CASE ('linear')
Sepj = 0._dp; Sipj = 0._dp
CASE DEFAULT
IF(my_id.EQ.0) write(*,*) '/!\ Linearity not recognized /!\'
stop
END SELECT
! Execution time END
CALL cpu_time(t1_Sapj)
tc_Sapj = tc_Sapj + (t1_Sapj - t0_Sapj)
END SUBROUTINE compute_Sapj
SUBROUTINE compute_nonlinear
IMPLICIT NONE
!!!!!!!!!!!!!!!!!!!! ELECTRON non linear term computation (Sepj)!!!!!!!!!!
IF(KIN_E) THEN
zloope: DO iz = izs,ize
ploope: DO ip = ips_e,ipe_e ! Loop over Hermite moments
eo = MODULO(parray_e(ip),2)
p_int = parray_e(ip)
sqrt_p = SQRT(REAL(p_int,dp)); sqrt_pp1 = SQRT(REAL(p_int,dp)+1._dp);
jloope: DO ij = ijs_e, ije_e ! Loop over Laguerre moments
j_int=jarray_e(ij)
IF((CLOS .NE. 1) .OR. (p_int+2*j_int .LE. dmaxe)) THEN !compute
! Set non linear sum truncation
IF (NL_CLOS .EQ. -2) THEN
nmax = Jmaxe
ELSEIF (NL_CLOS .EQ. -1) THEN
nmax = Jmaxe-j_int
ELSE
nmax = min(NL_CLOS,Jmaxe-j_int)
ENDIF
bracket_sum_r = 0._dp ! initialize sum over real nonlinear term
nloope: DO in = 1,nmax+1 ! Loop over laguerre for the sum
!-----------!! ELECTROSTATIC CONTRIBUTION {Sum_s dnjs Naps, Kernel phi}
! First convolution terms
F_cmpx(ikys:ikye,ikxs:ikxe) = phi(ikys:ikye,ikxs:ikxe,iz) * kernel_e(in, ikys:ikye,ikxs:ikxe, iz, eo)
! Second convolution terms
G_cmpx(ikys:ikye,ikxs:ikxe) = 0._dp ! initialization of the sum
smax = MIN( (in-1)+(ij-1), Jmaxe );
DO is = 1, smax+1 ! sum truncation on number of moments
G_cmpx(ikys:ikye,ikxs:ikxe) = G_cmpx(ikys:ikye,ikxs:ikxe) + &
dnjs(in,ij,is) * moments_e(ip,is,ikys:ikye,ikxs:ikxe,iz,updatetlevel)
ENDDO
!/!\ this function add its result to bracket_sum_r (hard to read sorry) /!\
CALL poisson_bracket_and_sum(F_cmpx,G_cmpx)
!-----------!! ELECTROMAGNETIC CONTRIBUTION -sqrt(tau)/sigma*{Sum_s dnjs [sqrt(p+1)Nap+1s + sqrt(p)Nap-1s], Kernel psi}
IF(EM) THEN
! First convolution terms
F_cmpx(ikys:ikye,ikxs:ikxe) = -sqrt_tau_o_sigma_e * psi(ikys:ikye,ikxs:ikxe,iz) * kernel_e(in, ikys:ikye,ikxs:ikxe, iz, eo)
! Second convolution terms
G_cmpx(ikys:ikye,ikxs:ikxe) = 0._dp ! initialization of the sum
smax = MIN( (in-1)+(ij-1), Jmaxe );
DO is = 1, smax+1 ! sum truncation on number of moments
G_cmpx(ikys:ikye,ikxs:ikxe) = G_cmpx(ikys:ikye,ikxs:ikxe) + &
dnjs(in,ij,is) * (sqrt_pp1*moments_e(ip+1,is,ikys:ikye,ikxs:ikxe,iz,updatetlevel)&
+sqrt_p *moments_e(ip-1,is,ikys:ikye,ikxs:ikxe,iz,updatetlevel))
ENDDO
!/!\ this function add its result to bracket_sum_r (hard to read sorry) /!\
CALL poisson_bracket_and_sum(F_cmpx,G_cmpx)
ENDIF
ENDDO nloope
!---------! Put back the real nonlinear product into k-space
call fftw_mpi_execute_dft_r2c(planf, bracket_sum_r, bracket_sum_c)
! Retrieve convolution in input format
DO iky = ikys, ikye
Sepj(ip,ij,iky,ikxs:ikxe,iz) = bracket_sum_c(ikxs:ikxe,iky-local_nky_offset)*AA_x(ikxs:ikxe)*AA_y(iky) !Anti aliasing filter
ENDDO
ELSE
Sepj(ip,ij,:,:,iz) = 0._dp
ENDIF
ENDDO jloope
ENDDO ploope
ENDDO zloope
ENDIF
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!! ION non linear term computation (Sipj)!!!!!!!!!!
zloopi: DO iz = izs,ize
ploopi: DO ip = ips_i,ipe_i ! Loop over Hermite moments
p_int = parray_i(ip)
eo = MODULO(parray_i(ip),2)
jloopi: DO ij = ijs_i, ije_i ! Loop over Laguerre moments
j_int=jarray_i(ij)
- IF((CLOS .NE. 1) .OR. (p_int+2*j_int .LE. dmaxi)) THEN !compute
+ IF((CLOS .NE. 1) .OR. (p_int+2*j_int .LE. dmaxi)) THEN !compute for every moments except for closure 1
! Set non linear sum truncation
IF (NL_CLOS .EQ. -2) THEN
nmax = Jmaxi
ELSEIF (NL_CLOS .EQ. -1) THEN
nmax = Jmaxi-j_int
ELSE
nmax = min(NL_CLOS,Jmaxi-j_int)
ENDIF
bracket_sum_r = 0._dp ! initialize sum over real nonlinear term
nloopi: DO in = 1,nmax+1 ! Loop over laguerre for the sum
-!-----------!! ELECTROMAGNETIC CONTRIBUTION -sqrt(tau)/sigma*{Sum_s dnjs [sqrt(p+1)Nap+1s + sqrt(p)Nap-1s], Kernel psi}
+!-----------!! ELECTROSTATIC CONTRIBUTION
! First convolution terms
F_cmpx(ikys:ikye,ikxs:ikxe) = phi(ikys:ikye,ikxs:ikxe,iz) * kernel_i(in, ikys:ikye,ikxs:ikxe, iz, eo)
! Second convolution terms
G_cmpx(ikys:ikye,ikxs:ikxe) = 0._dp ! initialization of the sum
smax = MIN( (in-1)+(ij-1), jmaxi );
DO is = 1, smax+1 ! sum truncation on number of moments
G_cmpx(ikys:ikye,ikxs:ikxe) = G_cmpx(ikys:ikye,ikxs:ikxe) + &
dnjs(in,ij,is) * moments_i(ip,is,ikys:ikye,ikxs:ikxe,iz,updatetlevel)
ENDDO
!/!\ this function add its result to bracket_sum_r (hard to read sorry) /!\
CALL poisson_bracket_and_sum(F_cmpx,G_cmpx)
!-----------!! ELECTROMAGNETIC CONTRIBUTION -sqrt(tau)/sigma*{Sum_s dnjs [sqrt(p+1)Nap+1s + sqrt(p)Nap-1s], Kernel psi}
IF(EM) THEN
! First convolution terms
F_cmpx(ikys:ikye,ikxs:ikxe) = -sqrt_tau_o_sigma_i * psi(ikys:ikye,ikxs:ikxe,iz) * kernel_i(in, ikys:ikye,ikxs:ikxe, iz, eo)
! Second convolution terms
G_cmpx(ikys:ikye,ikxs:ikxe) = 0._dp ! initialization of the sum
smax = MIN( (in-1)+(ij-1), Jmaxi );
DO is = 1, smax+1 ! sum truncation on number of moments
G_cmpx(ikys:ikye,ikxs:ikxe) = G_cmpx(ikys:ikye,ikxs:ikxe) + &
dnjs(in,ij,is) * (sqrt_pp1*moments_i(ip+1,is,ikys:ikye,ikxs:ikxe,iz,updatetlevel)&
+sqrt_p *moments_i(ip-1,is,ikys:ikye,ikxs:ikxe,iz,updatetlevel))
ENDDO
!/!\ this function add its result to bracket_sum_r (hard to read sorry) /!\
CALL poisson_bracket_and_sum(F_cmpx,G_cmpx)
ENDIF
ENDDO nloopi
! Put the real nonlinear product into k-space
call fftw_mpi_execute_dft_r2c(planf, bracket_sum_r, bracket_sum_c)
! Retrieve convolution in input format
DO iky = ikys, ikye
Sipj(ip,ij,iky,ikxs:ikxe,iz) = bracket_sum_c(ikxs:ikxe,iky-local_nky_offset)*AA_x(ikxs:ikxe)*AA_y(iky)
ENDDO
ELSE
Sipj(ip,ij,:,:,iz) = 0._dp
ENDIF
ENDDO jloopi
ENDDO ploopi
ENDDO zloopi
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
END SUBROUTINE compute_nonlinear
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! Semi linear computation : Only NZ-ZF convolutions are kept
SUBROUTINE compute_semi_linear_ZF
IMPLICIT NONE
!!!!!!!!!!!!!!!!!!!! ELECTRON semi linear term computation (Sepj)!!!!!!!!!!
IF(KIN_E) THEN
zloope: DO iz = izs,ize
ploope: DO ip = ips_e,ipe_e ! Loop over Hermite moments
eo = MODULO(parray_e(ip),2)
jloope: DO ij = ijs_e, ije_e ! Loop over Laguerre moments
j_int=jarray_e(ij)
! Set non linear sum truncation
IF (NL_CLOS .EQ. -2) THEN
nmax = Jmaxe
ELSEIF (NL_CLOS .EQ. -1) THEN
nmax = Jmaxe-(ij-1)
ELSE
nmax = NL_CLOS
ENDIF
bracket_sum_r = 0._dp ! initialize sum over real nonlinear term
nloope: DO in = 1,nmax+1 ! Loop over laguerre for the sum
! Build the terms to convolve
kxloope: DO ikx = ikxs,ikxe ! Loop over kx
kyloope: DO iky = ikys,ikye ! Loop over ky
kx = kxarray(ikx)
ky = kyarray(iky)
kerneln = kernel_e(in, ikx, iky, iz, eo)
! Zonal terms (=0 for all ky not 0)
Fx_cmpx(iky,ikx) = 0._dp
Gx_cmpx(iky,ikx) = 0._dp
IF(iky .EQ. iky_0) THEN
Fx_cmpx(iky,ikx) = imagu*kx* phi(iky,ikx,iz) * kerneln
smax = MIN( (in-1)+(ij-1), jmaxe );
DO is = 1, smax+1 ! sum truncation on number of moments
Gx_cmpx(iky,ikx) = Gx_cmpx(iky,ikx) + &
dnjs(in,ij,is) * moments_e(ip,is,iky,ikx,iz,updatetlevel)
ENDDO
Gx_cmpx(iky,ikx) = imagu*kx*Gx_cmpx(iky,ikx)
ENDIF
! NZ terms
Fy_cmpx(iky,ikx) = imagu*ky* phi(iky,ikx,iz) * kerneln
Gy_cmpx(iky,ikx) = 0._dp ! initialization of the sum
smax = MIN( (in-1)+(ij-1), jmaxe );
DO is = 1, smax+1 ! sum truncation on number of moments
Gy_cmpx(iky,ikx) = Gy_cmpx(iky,ikx) + &
dnjs(in,ij,is) * moments_e(ip,is,iky,ikx,iz,updatetlevel)
ENDDO
Gy_cmpx(iky,ikx) = imagu*ky*Gy_cmpx(iky,ikx)
ENDDO kyloope
ENDDO kxloope
! First term df/dx x dg/dy
CALL convolve_and_add(Fx_cmpx,Gy_cmpx)
! Second term -df/dy x dg/dx
CALL convolve_and_add(-Fy_cmpx,Gx_cmpx)
ENDDO nloope
! Put the real nonlinear product into k-space
call fftw_mpi_execute_dft_r2c(planf, bracket_sum_r, bracket_sum_c)
! Retrieve convolution in input format
DO ikx = ikxs, ikxe
DO iky = ikys, ikye
Sepj(ip,ij,iky,ikx,iz) = bracket_sum_c(ikx,iky-local_nky_offset)*AA_x(ikx)*AA_y(iky) !Anti aliasing filter
ENDDO
ENDDO
ENDDO jloope
ENDDO ploope
ENDDO zloope
ENDIF
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!! ION non linear term computation (Sipj)!!!!!!!!!!
zloopi: DO iz = izs,ize
ploopi: DO ip = ips_i,ipe_i ! Loop over Hermite moments
eo = MODULO(parray_i(ip),2)
jloopi: DO ij = ijs_i, ije_i ! Loop over Laguerre moments
j_int=jarray_i(ij)
! Set non linear sum truncation
IF (NL_CLOS .EQ. -2) THEN
nmax = Jmaxi
ELSEIF (NL_CLOS .EQ. -1) THEN
nmax = Jmaxi-(ij-1)
ELSE
nmax = NL_CLOS
ENDIF
bracket_sum_r = 0._dp ! initialize sum over real nonlinear term
nloopi: DO in = 1,nmax+1 ! Loop over laguerre for the sum
kxloopi: DO ikx = ikxs,ikxe ! Loop over kx
kyloopi: DO iky = ikys,ikye ! Loop over ky
! Zonal terms (=0 for all ky not 0)
Fx_cmpx(iky,ikx) = 0._dp
Gx_cmpx(iky,ikx) = 0._dp
IF(iky .EQ. iky_0) THEN
Fx_cmpx(iky,ikx) = imagu*kx* phi(iky,ikx,iz) * kerneln
smax = MIN( (in-1)+(ij-1), jmaxi );
DO is = 1, smax+1 ! sum truncation on number of moments
Gx_cmpx(iky,ikx) = Gx_cmpx(iky,ikx) + &
dnjs(in,ij,is) * moments_i(ip,is,iky,ikx,iz,updatetlevel)
ENDDO
Gx_cmpx(iky,ikx) = imagu*kx*Gx_cmpx(iky,ikx)
ENDIF
! NZ terms
Fy_cmpx(iky,ikx) = imagu*ky* phi(iky,ikx,iz) * kerneln
Gy_cmpx(iky,ikx) = 0._dp ! initialization of the sum
smax = MIN( (in-1)+(ij-1), jmaxi );
DO is = 1, smax+1 ! sum truncation on number of moments
Gy_cmpx(iky,ikx) = Gy_cmpx(iky,ikx) + &
dnjs(in,ij,is) * moments_i(ip,is,iky,ikx,iz,updatetlevel)
ENDDO
Gy_cmpx(iky,ikx) = imagu*ky*Gy_cmpx(iky,ikx)
ENDDO kyloopi
ENDDO kxloopi
! First term drphi x dzf
CALL convolve_and_add(Fy_cmpx,Gx_cmpx)
! Second term -dzphi x drf
CALL convolve_and_add(Fy_cmpx,Gx_cmpx)
ENDDO nloopi
! Put the real nonlinear product into k-space
call fftw_mpi_execute_dft_r2c(planf, bracket_sum_r, bracket_sum_c)
! Retrieve convolution in input format
DO ikx = ikxs, ikxe
DO iky = ikys, ikye
Sipj(ip,ij,iky,ikx,iz) = bracket_sum_c(ikx,iky-local_nky_offset)*AA_x(ikx)*AA_y(iky)
ENDDO
ENDDO
ENDDO jloopi
ENDDO ploopi
ENDDO zloopi
END SUBROUTINE compute_semi_linear_ZF
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! Semi linear computation : Only kx=0*all convolutions are kept
SUBROUTINE compute_semi_linear_NZ
IMPLICIT NONE
!!!!!!!!!!!!!!!!!!!! ELECTRON semi linear term computation (Sepj)!!!!!!!!!!
IF(KIN_E) THEN
zloope: DO iz = izs,ize
ploope: DO ip = ips_e,ipe_e ! Loop over Hermite moments
eo = MODULO(parray_e(ip),2)
jloope: DO ij = ijs_e, ije_e ! Loop over Laguerre moments
j_int=jarray_e(ij)
! Set non linear sum truncation
IF (NL_CLOS .EQ. -2) THEN
nmax = Jmaxe
ELSEIF (NL_CLOS .EQ. -1) THEN
nmax = Jmaxe-(ij-1)
ELSE
nmax = NL_CLOS
ENDIF
bracket_sum_r = 0._dp ! initialize sum over real nonlinear term
nloope: DO in = 1,nmax+1 ! Loop over laguerre for the sum
! Build the terms to convolve
kxloope: DO ikx = ikxs,ikxe ! Loop over kx
kyloope: DO iky = ikys,ikye ! Loop over ky
kx = kxarray(ikx)
ky = kyarray(iky)
kerneln = kernel_e(in, ikx, iky, iz, eo)
! All terms
Fx_cmpx(iky,ikx) = imagu*kx* phi(iky,ikx,iz) * kerneln
smax = MIN( (in-1)+(ij-1), jmaxe );
DO is = 1, smax+1 ! sum truncation on number of moments
Gx_cmpx(iky,ikx) = Gx_cmpx(iky,ikx) + &
dnjs(in,ij,is) * moments_e(ip,is,iky,ikx,iz,updatetlevel)
ENDDO
Gx_cmpx(iky,ikx) = imagu*kx*Gx_cmpx(iky,ikx)
! Kx = 0 terms
Fy_cmpx(iky,ikx) = 0._dp
Gy_cmpx(iky,ikx) = 0._dp
IF (ikx .EQ. ikx_0) THEN
Fy_cmpx(iky,ikx) = imagu*ky* phi(iky,ikx,iz) * kerneln
Gy_cmpx(iky,ikx) = 0._dp ! initialization of the sum
smax = MIN( (in-1)+(ij-1), jmaxe );
DO is = 1, smax+1 ! sum truncation on number of moments
Gy_cmpx(iky,ikx) = Gy_cmpx(iky,ikx) + &
dnjs(in,ij,is) * moments_e(ip,is,iky,ikx,iz,updatetlevel)
ENDDO
Gy_cmpx(iky,ikx) = imagu*ky*Gy_cmpx(iky,ikx)
ENDIF
ENDDO kyloope
ENDDO kxloope
! First term df/dx x dg/dy
CALL convolve_and_add(Fx_cmpx,Gy_cmpx)
! Second term -df/dy x dg/dx
CALL convolve_and_add(-Fy_cmpx,Gx_cmpx)
ENDDO nloope
! Put the real nonlinear product into k-space
call fftw_mpi_execute_dft_r2c(planf, bracket_sum_r, bracket_sum_c)
! Retrieve convolution in input format
DO ikx = ikxs, ikxe
DO iky = ikys, ikye
Sepj(ip,ij,iky,ikx,iz) = bracket_sum_c(ikx,iky-local_nky_offset)*AA_x(ikx)*AA_y(iky) !Anti aliasing filter
ENDDO
ENDDO
ENDDO jloope
ENDDO ploope
ENDDO zloope
ENDIF
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!! ION non linear term computation (Sipj)!!!!!!!!!!
zloopi: DO iz = izs,ize
ploopi: DO ip = ips_i,ipe_i ! Loop over Hermite moments
eo = MODULO(parray_i(ip),2)
jloopi: DO ij = ijs_i, ije_i ! Loop over Laguerre moments
j_int=jarray_i(ij)
! Set non linear sum truncation
IF (NL_CLOS .EQ. -2) THEN
nmax = Jmaxi
ELSEIF (NL_CLOS .EQ. -1) THEN
nmax = Jmaxi-(ij-1)
ELSE
nmax = NL_CLOS
ENDIF
bracket_sum_r = 0._dp ! initialize sum over real nonlinear term
nloopi: DO in = 1,nmax+1 ! Loop over laguerre for the sum
kxloopi: DO ikx = ikxs,ikxe ! Loop over kx
kyloopi: DO iky = ikys,ikye ! Loop over ky
! Zonal terms (=0 for all ky not 0)
Fx_cmpx(iky,ikx) = imagu*kx* phi(iky,ikx,iz) * kerneln
smax = MIN( (in-1)+(ij-1), jmaxi );
DO is = 1, smax+1 ! sum truncation on number of moments
Gx_cmpx(iky,ikx) = Gx_cmpx(iky,ikx) + &
dnjs(in,ij,is) * moments_i(ip,is,iky,ikx,iz,updatetlevel)
ENDDO
Gx_cmpx(iky,ikx) = imagu*kx*Gx_cmpx(iky,ikx)
! Kx = 0 terms
Fy_cmpx(iky,ikx) = 0._dp
Gy_cmpx(iky,ikx) = 0._dp
IF (ikx .EQ. ikx_0) THEN
Fy_cmpx(iky,ikx) = imagu*ky* phi(iky,ikx,iz) * kerneln
Gy_cmpx(iky,ikx) = 0._dp ! initialization of the sum
smax = MIN( (in-1)+(ij-1), jmaxi );
DO is = 1, smax+1 ! sum truncation on number of moments
Gy_cmpx(iky,ikx) = Gy_cmpx(iky,ikx) + &
dnjs(in,ij,is) * moments_i(ip,is,iky,ikx,iz,updatetlevel)
ENDDO
Gy_cmpx(iky,ikx) = imagu*ky*Gy_cmpx(iky,ikx)
ENDIF
ENDDO kyloopi
ENDDO kxloopi
! First term drphi x dzf
CALL convolve_and_add(Fy_cmpx,Gx_cmpx)
! Second term -dzphi x drf
CALL convolve_and_add(Fy_cmpx,Gx_cmpx)
ENDDO nloopi
! Put the real nonlinear product into k-space
call fftw_mpi_execute_dft_r2c(planf, bracket_sum_r, bracket_sum_c)
! Retrieve convolution in input format
DO ikx = ikxs, ikxe
DO iky = ikys, ikye
Sipj(ip,ij,iky,ikx,iz) = bracket_sum_c(ikx,iky-local_nky_offset)*AA_x(ikx)*AA_y(iky)
ENDDO
ENDDO
ENDDO jloopi
ENDDO ploopi
ENDDO zloopi
END SUBROUTINE compute_semi_linear_NZ
END MODULE nonlinear
diff --git a/src/processing_mod.F90 b/src/processing_mod.F90
index 54f99c6..2c34792 100644
--- a/src/processing_mod.F90
+++ b/src/processing_mod.F90
@@ -1,800 +1,800 @@
MODULE processing
USE basic
USE prec_const
USE grid
implicit none
REAL(dp), PUBLIC, PROTECTED :: pflux_ri, gflux_ri, pflux_re, gflux_re
REAL(dp), PUBLIC, PROTECTED :: hflux_xi, hflux_xe
PUBLIC :: compute_nadiab_moments_z_gradients_and_interp
PUBLIC :: compute_density, compute_upar, compute_uperp
PUBLIC :: compute_Tpar, compute_Tperp, compute_fluid_moments
PUBLIC :: compute_radial_ion_transport, compute_radial_electron_transport
PUBLIC :: compute_radial_ion_heatflux, compute_radial_electron_heatflux
PUBLIC :: compute_Napjz_spectrum
CONTAINS
! 1D diagnostic to compute the average radial particle transport _xyz
SUBROUTINE compute_radial_ion_transport
USE fields, ONLY : moments_i, phi, psi
USE array, ONLY : kernel_i
USE geometry, ONLY : Jacobian, iInt_Jacobian
USE time_integration, ONLY : updatetlevel
USE calculus, ONLY : simpson_rule_z
USE model, ONLY : sqrt_tau_o_sigma_i, EM
IMPLICIT NONE
COMPLEX(dp) :: pflux_local, gflux_local, integral
REAL(dp) :: ky_, buffer(1:2)
INTEGER :: i_, world_rank, world_size, root
COMPLEX(dp), DIMENSION(izgs:izge) :: integrant
pflux_local = 0._dp ! particle flux
gflux_local = 0._dp ! gyrocenter flux
integrant = 0._dp ! auxiliary variable for z integration
!!---------- Gyro center flux (drift kinetic) ------------
! Electrostatic part
IF(CONTAINS_ip0_i) THEN
DO iky = ikys,ikye
ky_ = kyarray(iky)
DO ikx = ikxs,ikxe
integrant(izgs:izge) = integrant(izgs:izge) &
+moments_i(ip0_i,ij0_i,iky,ikx,izgs:izge,updatetlevel)&
*imagu*ky_*CONJG(phi(iky,ikx,izgs:izge))
ENDDO
ENDDO
ENDIF
! Electromagnetic part
IF( EM .AND. CONTAINS_ip1_i ) THEN
DO iky = ikys,ikye
ky_ = kyarray(iky)
DO ikx = ikxs,ikxe
integrant(izgs:izge) = integrant(izgs:izge)&
-sqrt_tau_o_sigma_i*moments_i(ip1_i,ij0_i,iky,ikx,izgs:izge,updatetlevel)&
*imagu*ky_*CONJG(psi(iky,ikx,izgs:izge))
ENDDO
ENDDO
ENDIF
! Integrate over z
integrant(izgs:izge) = Jacobian(izgs:izge,0)*integrant(izgs:izge)
call simpson_rule_z(integrant,integral)
! Get process local gyrocenter flux
gflux_local = integral*iInt_Jacobian
!
integrant = 0._dp ! reset auxiliary variable
!!---------- Particle flux (gyrokinetic) ------------
! Electrostatic part
IF(CONTAINS_ip0_i) THEN
DO iky = ikys,ikye
ky_ = kyarray(iky)
DO ikx = ikxs,ikxe
DO ij = ijs_i, ije_i
integrant(izgs:izge) = integrant(izgs:izge)&
+moments_i(ip0_i,ij,iky,ikx,izgs:izge,updatetlevel)&
*imagu*ky_*kernel_i(ij,iky,ikx,izgs:izge,0)*CONJG(phi(iky,ikx,izgs:izge))
ENDDO
ENDDO
ENDDO
ENDIF
! Electromagnetic part
IF( EM .AND. CONTAINS_ip1_i ) THEN
DO iky = ikys,ikye
ky_ = kyarray(iky)
DO ikx = ikxs,ikxe
integrant = 0._dp ! auxiliary variable for z integration
DO ij = ijs_i, ije_i
integrant(izgs:izge) = integrant(izgs:izge)&
-sqrt_tau_o_sigma_i*moments_i(ip1_i,ij,iky,ikx,izgs:izge,updatetlevel)&
*imagu*ky_*kernel_i(ij,iky,ikx,izgs:izge,0)*CONJG(psi(iky,ikx,izgs:izge))
ENDDO
ENDDO
ENDDO
ENDIF
! Integrate over z
integrant(izgs:izge) = Jacobian(izgs:izge,0)*integrant(izgs:izge)
call simpson_rule_z(integrant,integral)
! Get process local particle flux
pflux_local = integral*iInt_Jacobian
!!!!---------- Sum over all processes ----------
buffer(1) = 2._dp*REAL(gflux_local)
buffer(2) = 2._dp*REAL(pflux_local)
root = 0
!Gather manually among the rank_p=0 processes and perform the sum
gflux_ri = 0
pflux_ri = 0
IF (num_procs_ky .GT. 1) THEN
!! Everyone sends its local_sum to root = 0
IF (rank_ky .NE. root) THEN
CALL MPI_SEND(buffer, 2 , MPI_DOUBLE_PRECISION, root, 1234, comm_ky, ierr)
ELSE
! Recieve from all the other processes
DO i_ = 0,num_procs_ky-1
IF (i_ .NE. rank_ky) &
CALL MPI_RECV(buffer, 2 , MPI_DOUBLE_PRECISION, i_, 1234, comm_ky, MPI_STATUS_IGNORE, ierr)
gflux_ri = gflux_ri + buffer(1)
pflux_ri = pflux_ri + buffer(2)
ENDDO
ENDIF
ELSE
gflux_ri = gflux_local
pflux_ri = pflux_local
ENDIF
! if(my_id .eq. 0) write(*,*) 'pflux_ri = ',pflux_ri
END SUBROUTINE compute_radial_ion_transport
! 1D diagnostic to compute the average radial particle transport _xyz
SUBROUTINE compute_radial_electron_transport
USE fields, ONLY : moments_e, phi, psi
USE array, ONLY : kernel_e
USE geometry, ONLY : Jacobian, iInt_Jacobian
USE time_integration, ONLY : updatetlevel
USE calculus, ONLY : simpson_rule_z
USE model, ONLY : sqrt_tau_o_sigma_e, EM
IMPLICIT NONE
COMPLEX(dp) :: pflux_local, gflux_local, integral
REAL(dp) :: ky_, buffer(1:2)
INTEGER :: i_, world_rank, world_size, root
COMPLEX(dp), DIMENSION(izgs:izge) :: integrant
pflux_local = 0._dp ! particle flux
gflux_local = 0._dp ! gyrocenter flux
integrant = 0._dp ! auxiliary variable for z integration
!!---------- Gyro center flux (drift kinetic) ------------
! Electrostatic part
IF(CONTAINS_ip0_e) THEN
DO iky = ikys,ikye
ky_ = kyarray(iky)
DO ikx = ikxs,ikxe
integrant(izgs:izge) = integrant(izgs:izge) &
+moments_e(ip0_e,ij0_e,iky,ikx,izgs:izge,updatetlevel)&
*imagu*ky_*CONJG(phi(iky,ikx,izgs:izge))
ENDDO
ENDDO
ENDIF
! Electromagnetic part
IF( EM .AND. CONTAINS_ip1_e ) THEN
DO iky = ikys,ikye
ky_ = kyarray(iky)
DO ikx = ikxs,ikxe
integrant(izgs:izge) = integrant(izgs:izge)&
-sqrt_tau_o_sigma_e*moments_e(ip1_e,ij0_e,iky,ikx,izgs:izge,updatetlevel)&
*imagu*ky_*CONJG(psi(iky,ikx,izgs:izge))
ENDDO
ENDDO
ENDIF
! Integrate over z
integrant(izgs:izge) = Jacobian(izgs:izge,0)*integrant(izgs:izge)
call simpson_rule_z(integrant,integral)
! Get process local gyrocenter flux
gflux_local = integral*iInt_Jacobian
!
integrant = 0._dp ! reset auxiliary variable
!!---------- Particle flux (gyrokinetic) ------------
! Electrostatic part
IF(CONTAINS_ip0_e) THEN
DO iky = ikys,ikye
ky_ = kyarray(iky)
DO ikx = ikxs,ikxe
DO ij = ijs_e, ije_e
integrant(izgs:izge) = integrant(izgs:izge)&
+moments_e(ip0_e,ij,iky,ikx,izgs:izge,updatetlevel)&
*imagu*ky_*kernel_e(ij,iky,ikx,izgs:izge,0)*CONJG(phi(iky,ikx,izgs:izge))
ENDDO
ENDDO
ENDDO
ENDIF
! Electromagnetic part
IF( EM .AND. CONTAINS_ip1_e ) THEN
DO iky = ikys,ikye
ky_ = kyarray(iky)
DO ikx = ikxs,ikxe
integrant = 0._dp ! auxiliary variable for z integration
DO ij = ijs_e, ije_e
integrant(izgs:izge) = integrant(izgs:izge)&
-sqrt_tau_o_sigma_e*moments_e(ip1_e,ij,iky,ikx,izgs:izge,updatetlevel)&
*imagu*ky_*kernel_e(ij,iky,ikx,izgs:izge,0)*CONJG(psi(iky,ikx,izgs:izge))
ENDDO
ENDDO
ENDDO
ENDIF
! Integrate over z
integrant(izgs:izge) = Jacobian(izgs:izge,0)*integrant(izgs:izge)
call simpson_rule_z(integrant,integral)
! Get process local particle flux
pflux_local = integral*iInt_Jacobian
!!!!---------- Sum over all processes ----------
buffer(1) = 2._dp*REAL(gflux_local)
buffer(2) = 2._dp*REAL(pflux_local)
root = 0
!Gather manually among the rank_p=0 processes and perform the sum
gflux_re = 0
pflux_re = 0
IF (num_procs_ky .GT. 1) THEN
!! Everyone sends its local_sum to root = 0
IF (rank_ky .NE. root) THEN
CALL MPI_SEND(buffer, 2 , MPI_DOUBLE_PRECISION, root, 1234, comm_ky, ierr)
ELSE
! Recieve from all the other processes
DO i_ = 0,num_procs_ky-1
IF (i_ .NE. rank_ky) &
CALL MPI_RECV(buffer, 2 , MPI_DOUBLE_PRECISION, i_, 1234, comm_ky, MPI_STATUS_IGNORE, ierr)
gflux_re = gflux_re + buffer(1)
pflux_re = pflux_re + buffer(2)
ENDDO
ENDIF
ELSE
gflux_re = gflux_local
pflux_re = pflux_local
ENDIF
END SUBROUTINE compute_radial_electron_transport
! 1D diagnostic to compute the average radial particle transport _xyz
SUBROUTINE compute_radial_ion_heatflux
USE fields, ONLY : moments_i, phi, psi
USE array, ONLY : kernel_i, HF_phi_correction_operator
USE geometry, ONLY : Jacobian, iInt_Jacobian
USE time_integration, ONLY : updatetlevel
USE model, ONLY : qi_taui, KIN_E, tau_i, EM
USE calculus, ONLY : simpson_rule_z
USE model, ONLY : sqrt_tau_o_sigma_i
IMPLICIT NONE
COMPLEX(dp) :: hflux_local, integral
REAL(dp) :: ky_, buffer(1:2), n_dp
INTEGER :: i_, world_rank, world_size, root, in
COMPLEX(dp), DIMENSION(izgs:izge) :: integrant ! charge density q_a n_a
hflux_local = 0._dp ! heat flux
integrant = 0._dp ! z integration auxiliary variable
!!----------------ELECTROSTATIC CONTRIBUTION---------------------------
IF(CONTAINS_ip0_i .AND. CONTAINS_ip2_i) THEN
! Loop to compute gamma_kx = sum_ky sum_j -i k_z Kernel_j Ni00 * phi
DO iky = ikys,ikye
ky_ = kyarray(iky)
DO ikx = ikxs,ikxe
DO in = ijs_i, ije_i
n_dp = jarray_i(in)
integrant(izgs:izge) = integrant(izgs:izge) + tau_i*imagu*ky_*CONJG(phi(iky,ikx,izgs:izge))&
*kernel_i(in,iky,ikx,izgs:izge,0)*(&
0.5_dp*SQRT2*moments_i(ip2_i,in ,iky,ikx,izgs:izge,updatetlevel)&
+(2._dp*n_dp + 1.5_dp)*moments_i(ip0_i,in ,iky,ikx,izgs:izge,updatetlevel)&
-(n_dp+1._dp)*moments_i(ip0_i,in+1,iky,ikx,izgs:izge,updatetlevel)&
-n_dp*moments_i(ip0_i,in-1,iky,ikx,izgs:izge,updatetlevel))
ENDDO
ENDDO
ENDDO
ENDIF
IF(EM .AND. CONTAINS_ip1_i .AND. CONTAINS_ip3_i) THEN
!!----------------ELECTROMAGNETIC CONTRIBUTION--------------------
DO iky = ikys,ikye
ky_ = kyarray(iky)
DO ikx = ikxs,ikxe
DO in = ijs_i, ije_i
n_dp = jarray_i(in)
integrant(izgs:izge) = integrant(izgs:izge) &
+tau_i*sqrt_tau_o_sigma_i*imagu*ky_*CONJG(psi(iky,ikx,izgs:izge))&
*kernel_i(in,iky,ikx,izgs:izge,0)*(&
0.5_dp*SQRT2*SQRT3*moments_i(ip3_i,in ,iky,ikx,izgs:izge,updatetlevel)&
+1.5_dp*moments_i(ip1_i,in ,iky,ikx,izgs:izge,updatetlevel)&
+(2._dp*n_dp+1._dp)*moments_i(ip1_i,in ,iky,ikx,izgs:izge,updatetlevel)&
-(n_dp+1._dp)*moments_i(ip1_i,in+1,iky,ikx,izgs:izge,updatetlevel)&
-n_dp*moments_i(ip1_i,in-1,iky,ikx,izgs:izge,updatetlevel))
ENDDO
ENDDO
ENDDO
ENDIF
! Add polarisation contribution
- integrant(izs:ize) = integrant(izs:ize) + tau_i*imagu*ky_&
- *CONJG(phi(iky,ikx,izs:ize))*phi(iky,ikx,izs:ize) * HF_phi_correction_operator(iky,ikx,izs:ize)
+ ! integrant(izgs:izge) = integrant(izgs:izge) + tau_i*imagu*ky_&
+ ! *CONJG(phi(iky,ikx,izgs:izge))*phi(iky,ikx,izgs:izge) * HF_phi_correction_operator(iky,ikx,izgs:izge)
! Integrate over z
integrant(izgs:izge) = Jacobian(izgs:izge,0)*integrant(izgs:izge)
call simpson_rule_z(integrant,integral)
hflux_local = hflux_local + integral*iInt_Jacobian
! Double it for taking into account the other half plane
buffer(2) = 2._dp*REAL(hflux_local)
root = 0
!Gather manually among the rank_p=0 processes and perform the sum
hflux_xi = 0
IF (num_procs_ky .GT. 1) THEN
!! Everyone sends its local_sum to root = 0
IF (rank_ky .NE. root) THEN
CALL MPI_SEND(buffer, 2 , MPI_DOUBLE_PRECISION, root, 1234, comm_ky, ierr)
ELSE
! Recieve from all the other processes
DO i_ = 0,num_procs_ky-1
IF (i_ .NE. rank_ky) &
CALL MPI_RECV(buffer, 2 , MPI_DOUBLE_PRECISION, i_, 1234, comm_ky, MPI_STATUS_IGNORE, ierr)
hflux_xi = hflux_xi + buffer(2)
ENDDO
ENDIF
ELSE
hflux_xi = hflux_local
ENDIF
END SUBROUTINE compute_radial_ion_heatflux
! 1D diagnostic to compute the average radial particle transport _xyz
SUBROUTINE compute_radial_electron_heatflux
USE fields, ONLY : moments_e, phi, psi
USE array, ONLY : kernel_e, HF_phi_correction_operator
USE geometry, ONLY : Jacobian, iInt_Jacobian
USE time_integration, ONLY : updatetlevel
USE model, ONLY : qi_taui, KIN_E, tau_e, EM
USE calculus, ONLY : simpson_rule_z
USE model, ONLY : sqrt_tau_o_sigma_e
IMPLICIT NONE
COMPLEX(dp) :: hflux_local, integral
REAL(dp) :: ky_, buffer(1:2), n_dp
INTEGER :: i_, world_rank, world_size, root, in
COMPLEX(dp), DIMENSION(izgs:izge) :: integrant ! charge density q_a n_a
hflux_local = 0._dp ! heat flux
integrant = 0._dp ! z integration auxiliary variable
!!----------------ELECTROSTATIC CONTRIBUTION---------------------------
IF(CONTAINS_ip0_e .AND. CONTAINS_ip2_e) THEN
! Loop to compute gamma_kx = sum_ky sum_j -i k_z Kernel_j Ni00 * phi
DO iky = ikys,ikye
ky_ = kyarray(iky)
DO ikx = ikxs,ikxe
DO in = ijs_e, ije_e
n_dp = jarray_e(in)
integrant(izgs:izge) = integrant(izgs:izge) + tau_e*imagu*ky_*CONJG(phi(iky,ikx,izgs:izge))&
*kernel_e(in,iky,ikx,izgs:izge,0)*(&
0.5_dp*SQRT2*moments_e(ip2_e,in ,iky,ikx,izgs:izge,updatetlevel)&
+(2._dp*n_dp + 1.5_dp)*moments_e(ip0_e,in ,iky,ikx,izgs:izge,updatetlevel)&
-(n_dp+1._dp)*moments_e(ip0_e,in+1,iky,ikx,izgs:izge,updatetlevel)&
-n_dp*moments_e(ip0_e,in-1,iky,ikx,izgs:izge,updatetlevel))
ENDDO
ENDDO
ENDDO
ENDIF
IF(EM .AND. CONTAINS_ip1_e .AND. CONTAINS_ip3_e) THEN
!!----------------ELECTROMAGNETIC CONTRIBUTION--------------------
DO iky = ikys,ikye
ky_ = kyarray(iky)
DO ikx = ikxs,ikxe
DO in = ijs_e, ije_e
n_dp = jarray_e(in)
integrant(izgs:izge) = integrant(izgs:izge) &
+tau_e*sqrt_tau_o_sigma_e*imagu*ky_*CONJG(psi(iky,ikx,izgs:izge))&
*kernel_e(in,iky,ikx,izgs:izge,0)*(&
0.5_dp*SQRT2*SQRT3*moments_e(ip3_e,in ,iky,ikx,izgs:izge,updatetlevel)&
+1.5_dp*CONJG(moments_e(ip1_e,in ,iky,ikx,izgs:izge,updatetlevel))& !?????
+(2._dp*n_dp+1._dp)*moments_e(ip1_e,in ,iky,ikx,izgs:izge,updatetlevel)&
-(n_dp+1._dp)*moments_e(ip1_e,in+1,iky,ikx,izgs:izge,updatetlevel)&
-n_dp*moments_e(ip1_e,in-1,iky,ikx,izgs:izge,updatetlevel))
ENDDO
ENDDO
ENDDO
ENDIF
! Add polarisation contribution
- integrant(izs:ize) = integrant(izs:ize) + tau_e*imagu*ky_&
- *CONJG(phi(iky,ikx,izs:ize))*phi(iky,ikx,izs:ize) * HF_phi_correction_operator(iky,ikx,izs:ize)
+ ! integrant(izs:ize) = integrant(izs:ize) + tau_e*imagu*ky_&
+ ! *CONJG(phi(iky,ikx,izs:ize))*phi(iky,ikx,izs:ize) * HF_phi_correction_operator(iky,ikx,izs:ize)
! Integrate over z
integrant(izgs:izge) = Jacobian(izgs:izge,0)*integrant(izgs:izge)
call simpson_rule_z(integrant,integral)
hflux_local = hflux_local + integral*iInt_Jacobian
! Double it for taking into account the other half plane
buffer(2) = 2._dp*REAL(hflux_local)
root = 0
!Gather manually among the rank_p=0 processes and perform the sum
hflux_xi = 0
IF (num_procs_ky .GT. 1) THEN
!! Everyone sends its local_sum to root = 0
IF (rank_ky .NE. root) THEN
CALL MPI_SEND(buffer, 2 , MPI_DOUBLE_PRECISION, root, 1234, comm_ky, ierr)
ELSE
! Recieve from all the other processes
DO i_ = 0,num_procs_ky-1
IF (i_ .NE. rank_ky) &
CALL MPI_RECV(buffer, 2 , MPI_DOUBLE_PRECISION, i_, 1234, comm_ky, MPI_STATUS_IGNORE, ierr)
hflux_xi = hflux_xi + buffer(2)
ENDDO
ENDIF
ELSE
hflux_xi = hflux_local
ENDIF
END SUBROUTINE compute_radial_electron_heatflux
SUBROUTINE compute_nadiab_moments_z_gradients_and_interp
! evaluate the non-adiabatique ion moments
!
! n_{pi} = N^{pj} + kernel(j) /tau_i phi delta_p0
!
USE fields, ONLY : moments_i, moments_e, phi, psi
USE array, ONLY : kernel_e, kernel_i, nadiab_moments_e, nadiab_moments_i, &
ddz_nepj, ddzND_nepj, interp_nepj,&
ddz_nipj, ddzND_nipj, interp_nipj
USE time_integration, ONLY : updatetlevel
USE model, ONLY : qe_taue, qi_taui,q_o_sqrt_tau_sigma_e, q_o_sqrt_tau_sigma_i, &
KIN_E, CLOS, beta
USE calculus, ONLY : grad_z, grad_z2, grad_z4, interp_z
IMPLICIT NONE
INTEGER :: eo, p_int, j_int
CALL cpu_time(t0_process)
! Electron non adiab moments
IF(KIN_E) THEN
DO ip=ipgs_e,ipge_e
IF(parray_e(ip) .EQ. 0) THEN
DO ij=ijgs_e,ijge_e
nadiab_moments_e(ip,ij,ikys:ikye,ikxs:ikxe,izgs:izge) = moments_e(ip,ij,ikys:ikye,ikxs:ikxe,izgs:izge,updatetlevel) &
+ qe_taue*kernel_e(ij,ikys:ikye,ikxs:ikxe,izgs:izge,0)*phi(ikys:ikye,ikxs:ikxe,izgs:izge)
ENDDO
ELSEIF( (parray_e(ip) .EQ. 1) .AND. (beta .GT. 0) ) THEN
DO ij=ijgs_e,ijge_e
nadiab_moments_e(ip,ij,ikys:ikye,ikxs:ikxe,izgs:izge) = moments_e(ip,ij,ikys:ikye,ikxs:ikxe,izgs:izge,updatetlevel) &
- q_o_sqrt_tau_sigma_e*kernel_e(ij,ikys:ikye,ikxs:ikxe,izgs:izge,0)*psi(ikys:ikye,ikxs:ikxe,izgs:izge)
ENDDO
ELSE
DO ij=ijgs_e,ijge_e
nadiab_moments_e(ip,ij,ikys:ikye,ikxs:ikxe,izgs:izge) = moments_e(ip,ij,ikys:ikye,ikxs:ikxe,izgs:izge,updatetlevel)
ENDDO
ENDIF
ENDDO
ENDIF
! Ions non adiab moments
DO ip=ipgs_i,ipge_i
IF(parray_i(ip) .EQ. 0) THEN
DO ij=ijgs_i,ijge_i
nadiab_moments_i(ip,ij,ikys:ikye,ikxs:ikxe,izgs:izge) = moments_i(ip,ij,ikys:ikye,ikxs:ikxe,izgs:izge,updatetlevel) &
+ qi_taui*kernel_i(ij,ikys:ikye,ikxs:ikxe,izgs:izge,0)*phi(ikys:ikye,ikxs:ikxe,izgs:izge)
ENDDO
ELSEIF( (parray_i(ip) .EQ. 1) .AND. (beta .GT. 0) ) THEN
DO ij=ijgs_i,ijge_i
nadiab_moments_i(ip,ij,ikys:ikye,ikxs:ikxe,izgs:izge) = moments_i(ip,ij,ikys:ikye,ikxs:ikxe,izgs:izge,updatetlevel) &
- q_o_sqrt_tau_sigma_i*kernel_i(ij,ikys:ikye,ikxs:ikxe,izgs:izge,0)*psi(ikys:ikye,ikxs:ikxe,izgs:izge)
ENDDO
ELSE
DO ij=ijgs_i,ijge_i
nadiab_moments_i(ip,ij,ikys:ikye,ikxs:ikxe,izgs:izge) = moments_i(ip,ij,ikys:ikye,ikxs:ikxe,izgs:izge,updatetlevel)
ENDDO
ENDIF
ENDDO
!! Ensure to kill the moments too high if closue option is set to 1
IF(CLOS .EQ. 1) THEN
IF(KIN_E) THEN
DO ip=ipgs_e,ipge_e
p_int = parray_e(ip)
DO ij=ijgs_e,ijge_e
j_int = jarray_e(ij)
IF(p_int+2*j_int .GT. dmaxe) &
nadiab_moments_e(ip,ij,:,:,:) = 0._dp
ENDDO
ENDDO
ENDIF
DO ip=ipgs_i,ipge_i
p_int = parray_i(ip)
DO ij=ijgs_i,ijge_i
j_int = jarray_i(ij)
IF(p_int+2*j_int .GT. dmaxi) &
nadiab_moments_i(ip,ij,:,:,:) = 0._dp
ENDDO
ENDDO
ENDIF
!------------- INTERP AND GRADIENTS ALONG Z ----------------------------------
IF (KIN_E) THEN
DO ikx = ikxs,ikxe
DO iky = ikys,ikye
DO ij = ijgs_e,ijge_e
DO ip = ipgs_e,ipge_e
p_int = parray_e(ip)
eo = MODULO(p_int,2) ! Indicates if we are on even or odd z grid
! Compute z derivatives
CALL grad_z(eo,nadiab_moments_e(ip,ij,iky,ikx,izgs:izge), ddz_nepj(ip,ij,iky,ikx,izs:ize))
! Parallel hyperdiffusion
CALL grad_z4(moments_e(ip,ij,iky,ikx,izgs:izge,updatetlevel),ddzND_nepj(ip,ij,iky,ikx,izs:ize))
! CALL grad_z2(nadiab_moments_e(ip,ij,iky,ikx,izgs:izge),ddzND_nepj(ip,ij,iky,ikx,izs:ize))
! Compute even odd grids interpolation
CALL interp_z(eo,nadiab_moments_e(ip,ij,iky,ikx,izgs:izge), interp_nepj(ip,ij,iky,ikx,izs:ize))
ENDDO
ENDDO
ENDDO
ENDDO
ENDIF
DO ikx = ikxs,ikxe
DO iky = ikys,ikye
DO ij = ijgs_i,ijge_i
DO ip = ipgs_i,ipge_i
p_int = parray_i(ip)
eo = MODULO(p_int,2) ! Indicates if we are on even or odd z grid
! Compute z first derivative
CALL grad_z(eo,nadiab_moments_i(ip,ij,iky,ikx,izgs:izge), ddz_nipj(ip,ij,iky,ikx,izs:ize))
! Parallel numerical diffusion
CALL grad_z4(moments_i(ip,ij,iky,ikx,izgs:izge,updatetlevel),ddzND_nipj(ip,ij,iky,ikx,izs:ize))
! CALL grad_z2(nadiab_moments_i(ip,ij,iky,ikx,izgs:izge),ddzND_nipj(ip,ij,iky,ikx,izs:ize))
! Compute even odd grids interpolation
CALL interp_z(eo,nadiab_moments_i(ip,ij,iky,ikx,izgs:izge), interp_nipj(ip,ij,iky,ikx,izs:ize))
ENDDO
ENDDO
ENDDO
ENDDO
! Execution time end
CALL cpu_time(t1_process)
tc_process = tc_process + (t1_process - t0_process)
END SUBROUTINE compute_nadiab_moments_z_gradients_and_interp
SUBROUTINE compute_Napjz_spectrum
USE fields, ONLY : moments_e, moments_i
USE model, ONLY : KIN_E
USE array, ONLY : Nipjz, Nepjz
USE time_integration, ONLY : updatetlevel
IMPLICIT NONE
REAL(dp), DIMENSION(ips_e:ipe_e,ijs_e:ije_e,izs:ize) :: local_sum_e,global_sum_e, buffer_e
REAL(dp), DIMENSION(ips_i:ipe_i,ijs_i:ije_i,izs:ize) :: local_sum_i,global_sum_i, buffer_i
INTEGER :: i_, world_rank, world_size, root, count
root = 0
! Electron moments spectrum
IF (KIN_E) THEN
! build local sum
local_sum_e = 0._dp
DO ikx = ikxs,ikxe
DO iky = ikys,ikye
local_sum_e(:,:,:) = local_sum_e(:,:,:) + &
moments_e(:,:,iky,ikx,:,updatetlevel) * CONJG(moments_e(:,:,iky,ikx,:,updatetlevel))
ENDDO
ENDDO
! sum reduction
buffer_e = local_sum_e
global_sum_e = 0._dp
count = (ipe_e-ips_e+1)*(ije_e-ijs_e+1)*(ize-izs+1)
IF (num_procs_ky .GT. 1) THEN
!! Everyone sends its local_sum to root = 0
IF (rank_ky .NE. root) THEN
CALL MPI_SEND(buffer_e, count , MPI_DOUBLE_PRECISION, root, 1234, comm_ky, ierr)
ELSE
! Recieve from all the other processes
DO i_ = 0,num_procs_ky-1
IF (i_ .NE. rank_ky) &
CALL MPI_RECV(buffer_e, count , MPI_DOUBLE_PRECISION, i_, 1234, comm_ky, MPI_STATUS_IGNORE, ierr)
global_sum_e = global_sum_e + buffer_e
ENDDO
ENDIF
ELSE
global_sum_e = local_sum_e
ENDIF
Nepjz = global_sum_e
ENDIF
! Ion moment spectrum
! build local sum
local_sum_i = 0._dp
DO ikx = ikxs,ikxe
DO iky = ikys,ikye
local_sum_i(:,:,:) = local_sum_i(:,:,:) + &
moments_i(:,:,iky,ikx,:,updatetlevel) * CONJG(moments_i(:,:,iky,ikx,:,updatetlevel))
ENDDO
ENDDO
! sum reduction
buffer_i = local_sum_i
global_sum_i = 0._dp
count = (ipe_i-ips_i+1)*(ije_i-ijs_i+1)*(ize-izs+1)
IF (num_procs_ky .GT. 1) THEN
!! Everyone sends its local_sum to root = 0
IF (rank_ky .NE. root) THEN
CALL MPI_SEND(buffer_i, count , MPI_DOUBLE_PRECISION, root, 1234, comm_ky, ierr)
ELSE
! Recieve from all the other processes
DO i_ = 0,num_procs_ky-1
IF (i_ .NE. rank_ky) &
CALL MPI_RECV(buffer_i, count , MPI_DOUBLE_PRECISION, i_, 1234, comm_ky, MPI_STATUS_IGNORE, ierr)
global_sum_i = global_sum_i + buffer_i
ENDDO
ENDIF
ELSE
global_sum_i = local_sum_i
ENDIF
Nipjz = global_sum_i
END SUBROUTINE compute_Napjz_spectrum
!_____________________________________________________________________________!
!!!!! FLUID MOMENTS COMPUTATIONS !!!!!
! Compute the 2D particle density for electron and ions (sum over Laguerre)
SUBROUTINE compute_density
USE array, ONLY : dens_e, dens_i, kernel_e, kernel_i, nadiab_moments_e, nadiab_moments_i
USE model, ONLY : KIN_E
IMPLICIT NONE
COMPLEX(dp) :: dens
IF ( CONTAINS_ip0_e .AND. CONTAINS_ip0_i ) THEN
! Loop to compute dens_i = sum_j kernel_j Ni0j at each k
DO iz = izs,ize
DO iky = ikys,ikye
DO ikx = ikxs,ikxe
IF(KIN_E) THEN
! electron density
dens = 0._dp
DO ij = ijs_e, ije_e
dens = dens + kernel_e(ij,iky,ikx,iz,0) * nadiab_moments_e(ip0_e,ij,iky,ikx,iz)
ENDDO
dens_e(iky,ikx,iz) = dens
ENDIF
! ion density
dens = 0._dp
DO ij = ijs_i, ije_i
dens = dens + kernel_i(ij,iky,ikx,iz,0) * nadiab_moments_i(ip0_e,ij,iky,ikx,iz)
ENDDO
dens_i(iky,ikx,iz) = dens
ENDDO
ENDDO
ENDDO
ENDIF
END SUBROUTINE compute_density
! Compute the 2D particle fluid perp velocity for electron and ions (sum over Laguerre)
SUBROUTINE compute_uperp
USE array, ONLY : uper_e, uper_i, kernel_e, kernel_i, nadiab_moments_e, nadiab_moments_i
USE model, ONLY : KIN_E
IMPLICIT NONE
COMPLEX(dp) :: uperp
IF ( CONTAINS_ip0_e .AND. CONTAINS_ip0_i ) THEN
DO iz = izs,ize
DO iky = ikys,ikye
DO ikx = ikxs,ikxe
IF(KIN_E) THEN
! electron
uperp = 0._dp
DO ij = ijs_e, ije_e
uperp = uperp + kernel_e(ij,iky,ikx,iz,0) *&
0.5_dp*(nadiab_moments_e(ip0_e,ij,iky,ikx,iz) - nadiab_moments_e(ip0_e,ij-1,iky,ikx,iz))
ENDDO
uper_e(iky,ikx,iz) = uperp
ENDIF
! ion
uperp = 0._dp
DO ij = ijs_i, ije_i
uperp = uperp + kernel_i(ij,iky,ikx,iz,0) *&
0.5_dp*(nadiab_moments_i(ip0_i,ij,iky,ikx,iz) - nadiab_moments_i(ip0_i,ij-1,iky,ikx,iz))
ENDDO
uper_i(iky,ikx,iz) = uperp
ENDDO
ENDDO
ENDDO
ENDIF
END SUBROUTINE compute_uperp
! Compute the 2D particle fluid par velocity for electron and ions (sum over Laguerre)
SUBROUTINE compute_upar
USE array, ONLY : upar_e, upar_i, kernel_e, kernel_i, nadiab_moments_e, nadiab_moments_i
USE model, ONLY : KIN_E
IMPLICIT NONE
COMPLEX(dp) :: upar
IF ( CONTAINS_ip1_e .AND. CONTAINS_ip1_i ) THEN
DO iz = izs,ize
DO iky = ikys,ikye
DO ikx = ikxs,ikxe
IF(KIN_E) THEN
! electron
upar = 0._dp
DO ij = ijs_e, ije_e
upar = upar + kernel_e(ij,iky,ikx,iz,1)*nadiab_moments_e(ip1_e,ij,iky,ikx,iz)
ENDDO
upar_e(iky,ikx,iz) = upar
ENDIF
! ion
upar = 0._dp
DO ij = ijs_i, ije_i
upar = upar + kernel_i(ij,iky,ikx,iz,1)*nadiab_moments_i(ip1_i,ij,iky,ikx,iz)
ENDDO
upar_i(iky,ikx,iz) = upar
ENDDO
ENDDO
ENDDO
ELSE
IF(KIN_E)&
upar_e = 0
upar_i = 0
ENDIF
END SUBROUTINE compute_upar
! Compute the 2D particle temperature for electron and ions (sum over Laguerre)
SUBROUTINE compute_tperp
USE array, ONLY : Tper_e, Tper_i, kernel_e, kernel_i, nadiab_moments_e, nadiab_moments_i
USE model, ONLY : KIN_E
IMPLICIT NONE
REAL(dp) :: j_dp
COMPLEX(dp) :: Tperp
IF ( CONTAINS_ip0_e .AND. CONTAINS_ip0_i .AND. &
CONTAINS_ip2_e .AND. CONTAINS_ip2_i ) THEN
! Loop to compute T = 1/3*(Tpar + 2Tperp)
DO iz = izs,ize
DO iky = ikys,ikye
DO ikx = ikxs,ikxe
! electron temperature
IF(KIN_E) THEN
Tperp = 0._dp
DO ij = ijs_e, ije_e
j_dp = REAL(ij-1,dp)
Tperp = Tperp + kernel_e(ij,iky,ikx,iz,0)*&
((2_dp*j_dp+1)*nadiab_moments_e(ip0_e,ij ,iky,ikx,iz)&
-j_dp *nadiab_moments_e(ip0_e,ij-1,iky,ikx,iz)&
-j_dp+1 *nadiab_moments_e(ip0_e,ij+1,iky,ikx,iz))
ENDDO
Tper_e(iky,ikx,iz) = Tperp
ENDIF
! ion temperature
Tperp = 0._dp
DO ij = ijs_i, ije_i
j_dp = REAL(ij-1,dp)
Tperp = Tperp + kernel_i(ij,iky,ikx,iz,0)*&
((2_dp*j_dp+1)*nadiab_moments_i(ip0_i,ij ,iky,ikx,iz)&
-j_dp *nadiab_moments_i(ip0_i,ij-1,iky,ikx,iz)&
-j_dp+1 *nadiab_moments_i(ip0_i,ij+1,iky,ikx,iz))
ENDDO
Tper_i(iky,ikx,iz) = Tperp
ENDDO
ENDDO
ENDDO
ENDIF
END SUBROUTINE compute_Tperp
! Compute the 2D particle temperature for electron and ions (sum over Laguerre)
SUBROUTINE compute_Tpar
USE array, ONLY : Tpar_e, Tpar_i, kernel_e, kernel_i, nadiab_moments_e, nadiab_moments_i
USE model, ONLY : KIN_E
IMPLICIT NONE
REAL(dp) :: j_dp
COMPLEX(dp) :: tpar
IF ( CONTAINS_ip0_e .AND. CONTAINS_ip0_i .AND. &
CONTAINS_ip2_e .AND. CONTAINS_ip2_i ) THEN
! Loop to compute T = 1/3*(Tpar + 2Tperp)
DO iz = izs,ize
DO iky = ikys,ikye
DO ikx = ikxs,ikxe
! electron temperature
IF(KIN_E) THEN
Tpar = 0._dp
DO ij = ijs_e, ije_e
j_dp = REAL(ij-1,dp)
Tpar = Tpar + kernel_e(ij,iky,ikx,iz,0)*&
(SQRT2 * nadiab_moments_e(ip2_e,ij,iky,ikx,iz) &
+ nadiab_moments_e(ip0_e,ij,iky,ikx,iz))
ENDDO
Tpar_e(iky,ikx,iz) = Tpar
ENDIF
! ion temperature
Tpar = 0._dp
DO ij = ijs_i, ije_i
j_dp = REAL(ij-1,dp)
Tpar = Tpar + kernel_i(ij,iky,ikx,iz,0)*&
(SQRT2 * nadiab_moments_i(ip2_i,ij,iky,ikx,iz) &
+ nadiab_moments_i(ip0_i,ij,iky,ikx,iz))
ENDDO
Tpar_i(iky,ikx,iz) = Tpar
ENDDO
ENDDO
ENDDO
ENDIF
END SUBROUTINE compute_Tpar
! Compute the 2D particle fluid moments for electron and ions (sum over Laguerre)
SUBROUTINE compute_fluid_moments
USE array, ONLY : dens_e, Tpar_e, Tper_e, dens_i, Tpar_i, Tper_i, temp_e, temp_i
USE model, ONLY : KIN_E
IMPLICIT NONE
CALL compute_density
CALL compute_upar
CALL compute_uperp
CALL compute_Tpar
CALL compute_Tperp
! Temperature
temp_e = (Tpar_e - 2._dp * Tper_e)/3._dp - dens_e
temp_i = (Tpar_i - 2._dp * Tper_i)/3._dp - dens_i
END SUBROUTINE compute_fluid_moments
END MODULE processing
diff --git a/testcases/cyclone_example/cyclone_example.txt b/testcases/cyclone_example/cyclone_example.txt
new file mode 100644
index 0000000..b38bfef
--- /dev/null
+++ b/testcases/cyclone_example/cyclone_example.txt
@@ -0,0 +1,4 @@
+This is a testcase reproducing the cyclone base case of Dimits 2000
+Adiabatic electrons, s-alpha geometry, gradlnN = 2.22, gradlnT = 6.96
+With a small P,J=4,2 polynomial basis, one should observe the secondary instability (KHI) at t~50R/cs.
+The saturated heat flux should be located around Qx ~ 30, i.e. Qx/QGB ~ 2 which is close to Dimits results.
diff --git a/testcases/cyclone_example/fort.90 b/testcases/cyclone_example/fort.90
new file mode 100644
index 0000000..d562465
Binary files /dev/null and b/testcases/cyclone_example/fort.90 differ
diff --git a/testcases/fort.90 b/testcases/fort.90
new file mode 100644
index 0000000..abce02c
--- /dev/null
+++ b/testcases/fort.90
@@ -0,0 +1,86 @@
+&BASIC
+ nrun = 100000000
+ dt = 0.01
+ tmax = 100
+ maxruntime = 356400
+/
+&GRID
+ pmaxe = 2
+ jmaxe = 1
+ pmaxi = 2
+ jmaxi = 1
+ Nx = 128
+ Lx = 100
+ Ny = 128
+ Ly = 240
+ Nz = 16
+ Npol = 1
+ SG = .false.
+/
+&GEOMETRY
+ geom = 'miller'
+ q0 = 1.4
+ shear = 0.0
+ eps = 0.18
+/
+&OUTPUT_PAR
+ nsave_0d = 50
+ nsave_1d = -1
+ nsave_2d = Inf
+ nsave_3d = 100
+ nsave_5d = 1000
+ write_doubleprecision = .false.
+ write_gamma = .true.
+ write_hf = .true.
+ write_phi = .true.
+ write_Na00 = .true.
+ write_Napj = .true.
+ write_Sapj = .false.
+ write_dens = .true.
+ write_temp = .true.
+ job2load = -1
+/
+&MODEL_PAR
+ ! Collisionality
+ CLOS = 0
+ NL_CLOS = -1
+ LINEARITY = 'nonlinear'
+ KIN_E = .false.
+ mu_x = 1.0
+ mu_y = 1.0
+ N_HD = 4
+ mu_z = 1.0
+ mu_p = 0
+ mu_j = 0
+ nu = 0.2
+ tau_e = 1
+ tau_i = 1
+ sigma_e = 0.023338
+ sigma_i = 1
+ q_e = -1
+ q_i = 1
+ K_Ni = 2.22
+ K_Ti = 6.92
+ K_Ne = 0
+ K_Te = 0
+ GradB = 1
+ CurvB = 1
+ lambdaD = 0
+ beta = 0
+/
+&COLLISION_PAR
+ collision_model = 'DG'
+ gyrokin_CO = .false.
+ interspecies = .true.
+ mat_file = 'null'
+/
+&INITIAL_CON
+ INIT_OPT = 'ppj'
+ ACT_ON_MODES = 'none'
+ init_background = 0
+ init_noiselvl = 1e-3
+ iseed = 42
+/
+&TIME_INTEGRATION_PAR
+ numerical_scheme = 'RK4'
+/
diff --git a/testcases/kobayashi_2015_linear_results.m b/testcases/kobayashi_2015_linear_results.m
deleted file mode 100644
index 82f3391..0000000
--- a/testcases/kobayashi_2015_linear_results.m
+++ /dev/null
@@ -1,19 +0,0 @@
-% results for blue triangles in Kobayashi 2015
-% x_ = [0.06 0.4 0.6];
-% y_ = [0.0 0.1 0.0];
-% plot(x_,y_,'^b','DisplayName','Kobayashi et al. 2015');
-
-
-% results for red squares in Kobayashi 2015
-% x_ = [0.065 0.15 0.35];
-% y_ = [0.0 0.15 0.0];
-% plot(x_,y_,'sr','DisplayName','Kobayashi et al. 2015');
-
-
-% results for green triangles in Kobayashi 2015
-x_ = [0.06 0.5 1.8];
-y_ = [0.0 0.2 0.0];
-plot(x_,y_,'dg','DisplayName','Kobayashi et al. 2015');
-
-
-
diff --git a/testcases/Hallenbert.m b/testcases/matlab_testscripts/Hallenbert.m
similarity index 100%
rename from testcases/Hallenbert.m
rename to testcases/matlab_testscripts/Hallenbert.m
diff --git a/testcases/benchmark_HeLaZ_gene_transport_zpinch.m b/testcases/matlab_testscripts/benchmark_HeLaZ_gene_transport_zpinch.m
similarity index 100%
rename from testcases/benchmark_HeLaZ_gene_transport_zpinch.m
rename to testcases/matlab_testscripts/benchmark_HeLaZ_gene_transport_zpinch.m
diff --git a/testcases/benchmark_HeLaZ_molix.m b/testcases/matlab_testscripts/benchmark_HeLaZ_molix.m
similarity index 100%
rename from testcases/benchmark_HeLaZ_molix.m
rename to testcases/matlab_testscripts/benchmark_HeLaZ_molix.m
diff --git a/testcases/benchmark_linear_1D_entropy_mode.m b/testcases/matlab_testscripts/benchmark_linear_1D_entropy_mode.m
similarity index 100%
rename from testcases/benchmark_linear_1D_entropy_mode.m
rename to testcases/matlab_testscripts/benchmark_linear_1D_entropy_mode.m
diff --git a/testcases/cyclone_test_case.m b/testcases/matlab_testscripts/cyclone_test_case.m
similarity index 100%
rename from testcases/cyclone_test_case.m
rename to testcases/matlab_testscripts/cyclone_test_case.m
diff --git a/testcases/linear_1D_entropy_mode.m b/testcases/matlab_testscripts/linear_1D_entropy_mode.m
similarity index 100%
rename from testcases/linear_1D_entropy_mode.m
rename to testcases/matlab_testscripts/linear_1D_entropy_mode.m
diff --git a/testcases/linear_damping.m b/testcases/matlab_testscripts/linear_damping.m
similarity index 100%
rename from testcases/linear_damping.m
rename to testcases/matlab_testscripts/linear_damping.m
diff --git a/testcases/miller_example_w_salpha/fort_00.90 b/testcases/miller_example_w_salpha/fort_00.90
new file mode 100644
index 0000000..2701de9
--- /dev/null
+++ b/testcases/miller_example_w_salpha/fort_00.90
@@ -0,0 +1,86 @@
+&BASIC
+ nrun = 100000000
+ dt = 0.01
+ tmax = 100
+ maxruntime = 356400
+/
+&GRID
+ pmaxe = 2
+ jmaxe = 1
+ pmaxi = 2
+ jmaxi = 1
+ Nx = 128
+ Lx = 100
+ Ny = 64
+ Ly = 120
+ Nz = 16
+ Npol = 1
+ SG = .false.
+/
+&GEOMETRY
+ geom = 's-alpha'
+ q0 = 1.4
+ shear = 0.0
+ eps = 0.18
+/
+&OUTPUT_PAR
+ nsave_0d = 50
+ nsave_1d = -1
+ nsave_2d = Inf
+ nsave_3d = 100
+ nsave_5d = 500
+ write_doubleprecision = .false.
+ write_gamma = .true.
+ write_hf = .true.
+ write_phi = .true.
+ write_Na00 = .true.
+ write_Napj = .true.
+ write_Sapj = .false.
+ write_dens = .true.
+ write_temp = .true.
+ job2load = -1
+/
+&MODEL_PAR
+ ! Collisionality
+ CLOS = 0
+ NL_CLOS = -1
+ LINEARITY = 'nonlinear'
+ KIN_E = .false.
+ mu_x = 0.1
+ mu_y = 0.1
+ N_HD = 4
+ mu_z = 0.2
+ mu_p = 0
+ mu_j = 0
+ nu = 0.2
+ tau_e = 1
+ tau_i = 1
+ sigma_e = 0.023338
+ sigma_i = 1
+ q_e = -1
+ q_i = 1
+ K_Ni = 2.22
+ K_Ti = 6.92
+ K_Ne = 0
+ K_Te = 0
+ GradB = 1
+ CurvB = 1
+ lambdaD = 0
+ beta = 0
+/
+&COLLISION_PAR
+ collision_model = 'DG'
+ gyrokin_CO = .false.
+ interspecies = .true.
+ mat_file = 'null'
+/
+&INITIAL_CON
+ INIT_OPT = 'ppj'
+ ACT_ON_MODES = 'none'
+ init_background = 0
+ init_noiselvl = 1e-3
+ iseed = 42
+/
+&TIME_INTEGRATION_PAR
+ numerical_scheme = 'RK4'
+/
diff --git a/testcases/miller_example_w_salpha/fort_01.90 b/testcases/miller_example_w_salpha/fort_01.90
new file mode 100644
index 0000000..7deb16c
--- /dev/null
+++ b/testcases/miller_example_w_salpha/fort_01.90
@@ -0,0 +1,86 @@
+&BASIC
+ nrun = 100000000
+ dt = 0.01
+ tmax = 400
+ maxruntime = 356400
+/
+&GRID
+ pmaxe = 2
+ jmaxe = 1
+ pmaxi = 2
+ jmaxi = 1
+ Nx = 128
+ Lx = 100
+ Ny = 64
+ Ly = 120
+ Nz = 16
+ Npol = 1
+ SG = .false.
+/
+&GEOMETRY
+ geom = 'miller'
+ q0 = 1.4
+ shear = 0.0
+ eps = 0.18
+/
+&OUTPUT_PAR
+ nsave_0d = 50
+ nsave_1d = -1
+ nsave_2d = Inf
+ nsave_3d = 100
+ nsave_5d = 500
+ write_doubleprecision = .false.
+ write_gamma = .true.
+ write_hf = .true.
+ write_phi = .true.
+ write_Na00 = .true.
+ write_Napj = .true.
+ write_Sapj = .false.
+ write_dens = .true.
+ write_temp = .true.
+ job2load = 0
+/
+&MODEL_PAR
+ ! Collisionality
+ CLOS = 0
+ NL_CLOS = -1
+ LINEARITY = 'nonlinear'
+ KIN_E = .false.
+ mu_x = 0.1
+ mu_y = 0.1
+ N_HD = 4
+ mu_z = 0.2
+ mu_p = 0
+ mu_j = 0
+ nu = 0.2
+ tau_e = 1
+ tau_i = 1
+ sigma_e = 0.023338
+ sigma_i = 1
+ q_e = -1
+ q_i = 1
+ K_Ni = 2.22
+ K_Ti = 6.92
+ K_Ne = 0
+ K_Te = 0
+ GradB = 1
+ CurvB = 1
+ lambdaD = 0
+ beta = 0
+/
+&COLLISION_PAR
+ collision_model = 'DG'
+ gyrokin_CO = .false.
+ interspecies = .true.
+ mat_file = 'null'
+/
+&INITIAL_CON
+ INIT_OPT = 'ppj'
+ ACT_ON_MODES = 'none'
+ init_background = 0
+ init_noiselvl = 1e-3
+ iseed = 42
+/
+&TIME_INTEGRATION_PAR
+ numerical_scheme = 'RK4'
+/
diff --git a/fort.90 b/testcases/zpinch_example/fort.90
similarity index 76%
rename from fort.90
rename to testcases/zpinch_example/fort.90
index ae9af96..f769f6b 100644
--- a/fort.90
+++ b/testcases/zpinch_example/fort.90
@@ -1,84 +1,85 @@
&BASIC
nrun = 100000000
- dt = 0.01
- tmax = 400
+ dt = 0.005
+ tmax = 100
maxruntime = 356400
/
&GRID
pmaxe = 4
jmaxe = 2
pmaxi = 4
jmaxi = 2
Nx = 128
- Lx = 120
- Ny = 40
+ Lx = 200
+ Ny = 48
Ly = 60
Nz = 1
SG = .f.
/
&GEOMETRY
geom = 'Z-pinch'
- q0 = 1.4
+ q0 = 0
shear = 0
- eps = 0.18
+ eps = 0
/
&OUTPUT_PAR
nsave_0d = 10
nsave_1d = -1
nsave_2d = -1
- nsave_3d = 20
+ nsave_3d = 100
nsave_5d = 1000
write_doubleprecision = .f.
write_gamma = .t.
write_hf = .t.
write_phi = .t.
write_Na00 = .t.
write_Napj = .t.
write_Sapj = .f.
write_dens = .t.
write_temp = .t.
job2load = -1
/
&MODEL_PAR
! Collisionality
CLOS = 0
- NL_CLOS = 0
+ NL_CLOS = -1
LINEARITY = 'nonlinear'
- KIN_E = .f.
+ KIN_E = .t.
mu_x = 1.0
mu_y = 1.0
N_HD = 4
mu_z = 0.0
mu_p = 0
mu_j = 0
nu = 0.1
tau_e = 1
tau_i = 1
sigma_e = 0.023338
sigma_i = 1
q_e = -1
q_i = 1
- K_n = 2.22
- K_T = 6.96
- K_E = 0
+ K_Ne = 2.22
+ K_Te = 6.96
+ K_Ni = 2.22
+ K_Ti = 6.96
GradB = 1
CurvB = 1
lambdaD = 0
+ beta = 1e-4
/
&COLLISION_PAR
collision_model = 'SG' !DG/SG/PA/LD (dougherty, sugama, pitch angle, landau)
gyrokin_CO = .false.
interspecies = .true.
- mat_file = 'iCa/gk_sugama_P_20_J_10_N_150_kpm_8.0.h5'
-! mat_file = 'iCa/gk_pitchangle_8_P_20_J_10_N_150_kpm_8.0.h5'
+ mat_file = 'gk_sugama_P_20_J_10_N_150_kpm_8.0.h5'
/
&INITIAL_CON
- INIT_OPT = 'ppj'
+ INIT_OPT = 'phi'
ACT_ON_MODES = 'donothing'
init_background = 0
init_noiselvl = 0.00005
iseed = 42
/
&TIME_INTEGRATION_PAR
numerical_scheme = 'RK4'
/
diff --git a/wk/Zpinch_coll_scan_kN_1.7.m b/wk/Zpinch_coll_scan_kN_1.7.m
index e223e0e..ad00ba1 100644
--- a/wk/Zpinch_coll_scan_kN_1.7.m
+++ b/wk/Zpinch_coll_scan_kN_1.7.m
@@ -1,68 +1,83 @@
-%%
if 0
+%%
figure
Kn = 1.7;
% SUGAMA DK 4,2
% nu_a = 1e-2*[1.00 2.00 3.00 4.00 5.00 6.00 7.00];
% Gavg_a = 1e-2*[1.00 1.71 2.18 3.11 4.11 5.20 6.08];
% Gstd_a = 1e-2*[1.78 2.67 2.82 3.08 2.33 1.35 1.43];
% errorbar(nu_a, Gavg_a/Kn, Gstd_a/Kn,'DisplayName','Sugama DK (4,2)'); hold on
-% SUGAMA GK 4,2
+% SUGAMA GK 4,2 200x32
nu_a = 1e-2*[1.00 2.00 3.00 4.00 5.00 6.00 7.00 8.00 9.00 10.0];
-Gavg_a = [2.54e-2 4.66e-2 6.96e-2 8.98e-2 1.06e-1 1.24e-1 1.43e-1 1.52e-1 1.69e-1 1.09e-1];
+Gavg_a = [2.54e-2 4.66e-2 6.96e-2 8.98e-2 1.06e-1 1.24e-1 1.43e-1 1.52e-1 1.69e-1 1.79e-1];
Gstd_a = [3.04e-2 1.42e-2 1.56e-2 1.23e-2 1.20e-2 1.57e-2 1.63e-2 2.06e-2 2.14e-02 1.78e-2];
-errorbar(nu_a, Gavg_a/Kn, Gstd_a/Kn,'DisplayName','Sugama GK (4,2)'); hold on
+errorbar(nu_a, Gavg_a/Kn, Gstd_a/Kn,'DisplayName','Sugama GK (4,2) 200x32'); hold on
+
+% SUGAMA GK 4,2 256x64
+nu_a = 1e-2*[1.00 2.00 3.00 4.00 5.00 6.00 7.00 8.00 9.00 10.0];
+Gavg_a = [1.99e-2 3.03e-2 4.44e-2 5.87e-2 7.87e-2 1.07e-1 1.22e-1 1.38e-1 1.63e-1 1.75e-1];
+Gstd_a = [1.55e-2 2.22e-2 1.12e-2 1.54e-2 2.20e-2 2.76e-2 2.44e-2 3.20e-2 3.12e-2 3.13e-2];
+errorbar(nu_a, Gavg_a/Kn, Gstd_a/Kn,'DisplayName','Sugama GK (4,2) 256x64'); hold on
-% FCGK 4,2
+
+% SUGAMA GK 6,3 200x32
+nu_a = 1e-2*[1.00 2.00 3.00 4.00 5.00 6.00 7.00 8.00 9.00 10.0];
+Gavg_a = [2.35e-2 3.57e-2 5.09e-2 6.97e-2 8.65e-2 1.01e-1 1.16e-1 1.33e-1 1.49e-1 1.62e-1];
+Gstd_a = [3.76e-2 3.91e-2 2.96e-2 1.57e-2 1.73e-2 1.94e-2 2.21e-2 2.01e-2 1.93e-2 2.24e-2];
+
+errorbar(nu_a, Gavg_a/Kn, Gstd_a/Kn,'DisplayName','Sugama GK (6,3) 200x32'); hold on
+
+
+% FCGK 4,2 200x32
nu_a = 1e-2*[1.00 2.00 3.00 4.00 5.00 6.00 7.00 10.0];
Gavg_a = [8.57e-2 1.45e-1 2.25e-1 2.87e-1 3.48e-1 4.06e-1 4.51e-1 3.65e-1*Kn];
Gstd_a = [2.07e-2 2.61e-2 2.40e-2 3.46e-2 4.30e-2 5.00e-2 5.11e-2 0];
-errorbar(nu_a, Gavg_a/Kn, Gstd_a/Kn,'DisplayName','Coulomb (4,2)'); hold on
-
-% LDGK ii 6,3
-nu_a = 1e-2*[1.00 2.00 3.00 4.00 5.00 6.00 7.00 8.00 9.00];
-Gavg_a = [3.86e-2 1.82e-2 3.08e-2 5.24e-2 7.08e-2 8.26e-2 5.78e-2 7.16e-2 7.96e-2];
-Gstd_a = [3.52e-2 1.87e-2 2.86e-2 2.79e-2 1.72e-2 2.40e-2 2.46e-2 1.01e-2 1.21e-2];
+errorbar(nu_a, Gavg_a/Kn, Gstd_a/Kn,'DisplayName','Coulomb (4,2) 200x32'); hold on
-errorbar(nu_a, Gavg_a/Kn, Gstd_a/Kn,'DisplayName','Landau ii (6,3)'); hold on
+% % LDGK ii 6,3 200x32
+% nu_a = 1e-2*[1.00 2.00 3.00 4.00 5.00 6.00 7.00 8.00 9.00];
+% Gavg_a = [3.86e-2 1.82e-2 3.08e-2 5.24e-2 7.08e-2 8.26e-2 5.78e-2 7.16e-2 7.96e-2];
+% Gstd_a = [3.52e-2 1.87e-2 2.86e-2 2.79e-2 1.72e-2 2.40e-2 2.46e-2 1.01e-2 1.21e-2];
+%
+% errorbar(nu_a, Gavg_a/Kn, Gstd_a/Kn,'DisplayName','Landau ii (6,3) 200x32'); hold on
% Collisionless
plot([0 1], 0.02343*[1 1],'--k','DisplayName','$\nu=0$');
%
xlim([0 0.1]);
legend('show');
xlabel('$\nu R/c_s$'); ylabel('$\Gamma_x^\infty/\kappa_N$');
-
+set(gca,'Yscale','log');
end
if 0
%%
figure
nu = 0.1;
% FCGK 4,2
kn_a = [1.60 1.80 2.00 2.20 2.40];
Gavg_a = [1.11e-1 6.86e-1 3.44e-0 1.12e+1 2.87e+1];
Gstd_a = [7.98e-3 1.10e-1 4.03e-1 2.03e+0 7.36e+0];
errorbar(kn_a, Gavg_a./kn_a, Gstd_a./kn_a,'DisplayName','Coulomb (4,2)'); hold on
% % Collisionless
% plot([0 1], 0.02343*[1 1],'--k','DisplayName','$\nu=0$');
%
xlim([1.6 2.5]);
legend('show');
xlabel('$\nu R/c_s$'); ylabel('$\Gamma_x^\infty/\kappa_N$');
end
\ No newline at end of file
diff --git a/wk/analysis_gene.m b/wk/analysis_gene.m
index f45fc16..53f11c4 100644
--- a/wk/analysis_gene.m
+++ b/wk/analysis_gene.m
@@ -1,158 +1,159 @@
helazdir = '/home/ahoffman/HeLaZ/';
addpath(genpath([helazdir,'matlab'])) % ... add
addpath(genpath([helazdir,'matlab/plot'])) % ... add
addpath(genpath([helazdir,'matlab/compute'])) % ... add
addpath(genpath([helazdir,'matlab/load'])) % ... add
% folder = '/misc/gene_results/shearless_cyclone/miller_output_1.0/';
% folder = '/misc/gene_results/shearless_cyclone/miller_output_0.8/';
% folder = '/misc/gene_results/shearless_cyclone/s_alpha_output_1.0/';
% folder = '/misc/gene_results/shearless_cyclone/rm_corrections_HF/';
% folder = '/misc/gene_results/shearless_cyclone/linear_s_alpha_CBC_100/';
% folder = '/misc/gene_results/shearless_cyclone/s_alpha_output_0.5/';
% folder = '/misc/gene_results/shearless_cyclone/LD_s_alpha_output_1.0/';
% folder = '/misc/gene_results/shearless_cyclone/LD_s_alpha_output_0.8/';
-% folder = '/misc/gene_results/HP_fig_2a_mu_1e-2/';
-% folder = '/misc/gene_results/HP_fig_2b_mu_5e-2/';
-% folder = '/misc/gene_results/HP_fig_2c_mu_5e-2/';
+folder = '/misc/gene_results/Z-pinch/HP_fig_2a_mu_1e-2/';
+% folder = '/misc/gene_results/Z-pinch/HP_fig_2b_mu_5e-2/';
+% folder = '/misc/gene_results/Z-pinch/HP_fig_2c_mu_5e-2/';
% folder = '/misc/gene_results/LD_zpinch_1.6/';
% folder = '/misc/gene_results/ZP_HP_kn_1.6_nuv_3.2/';
% folder = '/misc/gene_results/ZP_HP_kn_1.6_nuv_3.2/';
% folder = '/misc/gene_results/Z-pinch/ZP_HP_kn_1.6_HRES/';
% folder = '/misc/gene_results/ZP_kn_2.5_large_box/';
% folder = '/misc/gene_results/CBC/128x64x16x24x12/';
% folder = '/misc/gene_results/CBC/196x96x20x32x16_02/';
% folder = '/misc/gene_results/CBC/128x64x16x6x4/';
% folder = '/misc/gene_results/CBC/KT_5.3_128x64x16x24x12_01/';
% folder = '/misc/gene_results/CBC/KT_4.5_128x64x16x24x12_01/';
% folder = '/misc/gene_results/CBC/KT_9_128x64x16x24x12/';
% folder = '/misc/gene_results/CBC/KT_13_large_box_128x64x16x24x12/';
% folder = '/misc/gene_results/CBC/Lapillone_Fig6/';
-folder = '/misc/gene_results/Z-pinch/HP_kN_1.6_adapt_mu_01/';
+% folder = '/misc/gene_results/Z-pinch/HP_kN_1.6_adapt_mu_01/';
+% folder = '/misc/gene_results/miller/';
gene_data = load_gene_data(folder);
gene_data = invert_kxky_to_kykx_gene_results(gene_data);
if 1
%% Space time diagramm (fig 11 Ivanov 2020)
options.TAVG_0 = 0.1*gene_data.Ts3D(end);
options.TAVG_1 = gene_data.Ts3D(end); % Averaging times duration
options.NMVA = 1; % Moving average for time traces
options.ST_FIELD = '\phi'; % chose your field to plot in spacetime diag (e.g \phi,v_x,G_x, Q_x)
options.INTERP = 1;
gene_data.FIGDIR = folder;
fig = plot_radial_transport_and_spacetime(gene_data,options);
save_figure(gene_data,fig,'.png')
end
if 0
%% statistical transport averaging
options.T = [100 500];
fig = statistical_transport_averaging(gene_data,options);
end
if 0
%% 2D snapshots
% Options
options.INTERP = 1;
options.POLARPLOT = 0;
options.AXISEQUAL = 0;
% options.NAME = 'Q_x';
options.NAME = '\phi';
% options.NAME = 'n_i';
% options.NAME = '\Gamma_x';
% options.NAME = 'k^2n_e';
options.PLAN = 'kxky';
% options.NAME ='f_e';
% options.PLAN = 'sx';
options.COMP = 'avg';
options.TIME = [325 400];
gene_data.a = data.EPS * 2000;
fig = photomaton(gene_data,options);
save_figure(gene_data,fig,'.png')
end
if 0
%% MOVIES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Options
options.INTERP = 1;
options.POLARPLOT = 0;
-options.NAME = '\phi';
+% options.NAME = '\phi';
% options.NAME = 'v_y';
-% options.NAME = 'n_i^{NZ}';
+options.NAME = 'n_i';
% options.NAME = '\Gamma_x';
% options.NAME = 'n_i';
options.PLAN = 'xy';
% options.NAME = 'f_e';
% options.PLAN = 'sx';
options.COMP = 'avg';
options.TIME = gene_data.Ts3D;
gene_data.a = data.EPS * 2000;
create_film(gene_data,options,'.gif')
end
if 0
%% Geometry
names = {'$g^{xx}$','$g^{xy}$','$g^{xz}$','$g^{yy}$','$g^{yz}$','$g^{zz}$',...
'$B_0$','$\partial_x B_0$','$\partial_y B_0$','$\partial_z B_0$',...
'$J$','$R$','$\phi$','$Z$','$\partial_R x$','$\partial_Z x$'};
figure;
subplot(311)
for i = 1:6
plot(gene_data.z, gene_data.geo_arrays(:,i),'DisplayName',names{i}); hold on;
end
xlim([min(gene_data.z),max(gene_data.z)]); legend('show'); title('GENE geometry');
subplot(312)
for i = 7:10
plot(gene_data.z, gene_data.geo_arrays(:,i),'DisplayName',names{i}); hold on;
end
xlim([min(gene_data.z),max(gene_data.z)]); legend('show');
subplot(313)
for i = 11:16
plot(gene_data.z, gene_data.geo_arrays(:,i),'DisplayName',names{i}); hold on;
end
xlim([min(gene_data.z),max(gene_data.z)]); legend('show');
end
if 0
%% Show f_i(vpar,mu)
options.times = 250:500;
options.specie = 'i';
options.PLT_FCT = 'contour';
options.folder = folder;
options.iz = 'avg';
options.FIELD = '';
options.ONED = 0;
% options.FIELD = 'Q_es';
plot_fa_gene(options);
end
if 0
%% Time averaged spectrum
-options.TIME = 300:600;
+options.TIME = [4000 8000];
options.NORM =1;
-options.NAME = '\phi';
+% options.NAME = '\phi';
% options.NAME = 'n_i';
-% options.NAME ='\Gamma_x';
+options.NAME ='\Gamma_x';
options.PLAN = 'kxky';
options.COMPZ = 'avg';
options.OK = 0;
-options.COMPXY = 'zero';
+options.COMPXY = 'avg'; % avg/sum/max/zero/ 2D plot otherwise
options.COMPT = 'avg';
options.PLOT = 'semilogy';
fig = spectrum_1D(gene_data,options);
% save_figure(data,fig)
end
if 0
%% Mode evolution
options.NORMALIZED = 0;
options.K2PLOT = 1;
options.TIME = 100:700;
options.NMA = 1;
options.NMODES = 15;
options.iz = 'avg';
fig = mode_growth_meter(gene_data,options);
save_figure(gene_data,fig)
end
diff --git a/wk/analysis_gyacomo.m b/wk/analysis_gyacomo.m
index eecf714..2a875f6 100644
--- a/wk/analysis_gyacomo.m
+++ b/wk/analysis_gyacomo.m
@@ -1,222 +1,230 @@
%% UNCOMMENT FOR TUTORIAL
% gyacomodir = pwd; gyacomodir = gyacomodir(1:end-2); % get code directory
% resdir = '.'; %Name of the directory where the results are located
% JOBNUMMIN = 00; JOBNUMMAX = 10;
%%
addpath(genpath([gyacomodir,'matlab'])) % ... add
addpath(genpath([gyacomodir,'matlab/plot'])) % ... add
addpath(genpath([gyacomodir,'matlab/compute'])) % ... add
addpath(genpath([gyacomodir,'matlab/load'])) % ... add
%% Load the results
LOCALDIR = [gyacomodir,resdir,'/'];
MISCDIR = ['/misc/gyacomo_outputs/',resdir,'/']; %For long term storage
system(['mkdir -p ',MISCDIR]);
system(['mkdir -p ',LOCALDIR]);
CMD = ['rsync ', LOCALDIR,'outputs* ',MISCDIR]; disp(CMD);
system(CMD);
% Load outputs from jobnummin up to jobnummax
data = compile_results(MISCDIR,JOBNUMMIN,JOBNUMMAX); %Compile the results from first output found to JOBNUMMAX if existing
data.localdir = LOCALDIR;
data.FIGDIR = LOCALDIR;
%% PLOTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
default_plots_options
disp('Plots')
FMT = '.fig';
if 1
%% Space time diagramm (fig 11 Ivanov 2020)
% data.scale = 1;%/(data.Nx*data.Ny)^2;
-i_ = 11;
+i_ = 1;
disp([num2str(data.TJOB_SE(i_)),' ',num2str(data.TJOB_SE(i_+1))])
disp([num2str(data.NU_EVOL(i_)),' ',num2str(data.NU_EVOL(i_+1))])
options.TAVG_0 = data.TJOB_SE(i_);%0.4*data.Ts3D(end);
options.TAVG_1 = data.TJOB_SE(i_+1);%0.9*data.Ts3D(end); % Averaging times duration
options.NCUT = 4; % Number of cuts for averaging and error estimation
options.NMVA = 100; % Moving average for time traces
% options.ST_FIELD = '\Gamma_x'; % chose your field to plot in spacetime diag (e.g \phi,v_x,G_x)
-% options.ST_FIELD = '\phi'; % chose your field to plot in spacetime diag (e.g \phi,v_x,G_x)
-% options.INTERP = 1;
+options.ST_FIELD = '\phi'; % chose your field to plot in spacetime diag (e.g \phi,v_x,G_x)
+options.INTERP = 0;
+options.RESOLUTION = 256;
fig = plot_radial_transport_and_spacetime(data,options);
save_figure(data,fig,'.png')
end
if 0
%% statistical transport averaging
-options.T = [200 400];
+for i_ = 1:2:21
+% i_ = 3;
+disp([num2str(data.TJOB_SE(i_)),' ',num2str(data.TJOB_SE(i_+1))])
+disp([num2str(data.NU_EVOL(i_)),' ',num2str(data.NU_EVOL(i_+1))])
+options.T = [data.TJOB_SE(i_) data.TJOB_SE(i_+1)];
+options.NPLOTS = 0;
fig = statistical_transport_averaging(data,options);
end
-
+end
if 0
%% MOVIES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Options
options.INTERP = 1;
options.POLARPLOT = 0;
-options.NAME = '\phi';
+% options.NAME = '\phi';
% options.NAME = '\omega_z';
% options.NAME = 'N_i^{00}';
% options.NAME = 'v_y';
% options.NAME = 'n_i^{NZ}';
% options.NAME = '\Gamma_x';
-% options.NAME = 'n_i';
+options.NAME = 'n_i';
options.PLAN = 'xy';
% options.NAME = 'f_i';
% options.PLAN = 'sx';
-% options.COMP = 'avg';
+options.COMP = 'avg';
% options.TIME = data.Ts5D(end-30:end);
% options.TIME = data.Ts3D;
-options.TIME = [000:50:7000];
+options.TIME = [000:0.1:7000];
data.EPS = 0.1;
data.a = data.EPS * 2000;
options.RESOLUTION = 256;
create_film(data,options,'.gif')
end
if 1
%% 2D snapshots
% Options
options.INTERP = 1;
options.POLARPLOT = 0;
options.AXISEQUAL = 1;
options.NAME = '\phi';
% options.NAME = '\psi';
% options.NAME = 'n_i';
% options.NAME = 'N_i^{00}';
% options.NAME = 'T_i';
% options.NAME = '\Gamma_x';
% options.NAME = 'k^2n_e';
options.PLAN = 'xy';
% options.NAME 'f_i';
% options.PLAN = 'sx';
options.COMP = 'avg';
options.TIME = [1000 1800 2500 3000 4000];
data.a = data.EPS * 2e3;
fig = photomaton(data,options);
% save_figure(data,fig)
end
if 0
%% 3D plot on the geometry
options.INTERP = 0;
options.NAME = '\phi';
options.PLANES = [1];
options.TIME = [30];
options.PLT_MTOPO = 1;
options.PLT_FTUBE = 0;
data.EPS = 0.4;
data.rho_o_R = 3e-3; % Sound larmor radius over Machine size ratio
fig = show_geometry(data,options);
save_figure(data,fig,'.png')
end
if 0
%% Kinetic distribution function sqrt(xy) (GENE vsp)
options.SPAR = linspace(-3,3,32)+(6/127/2);
options.XPERP = linspace( 0,6,32);
% options.SPAR = gene_data.vp';
% options.XPERP = gene_data.mu';
options.iz = 'avg';
options.T = [250 600];
options.PLT_FCT = 'pcolor';
options.ONED = 0;
options.non_adiab = 0;
options.SPECIE = 'i';
options.RMS = 1; % Root mean square i.e. sqrt(sum_k|f_k|^2) as in Gene
fig = plot_fa(data,options);
% save_figure(data,fig,'.png')
end
if 0
%% Hermite-Laguerre spectrum
% options.TIME = 'avg';
options.P2J = 0;
options.ST = 1;
options.PLOT_TYPE = 'space-time';
options.NORMALIZED = 0;
options.JOBNUM = 0;
options.TIME = [1000];
options.specie = 'i';
options.compz = 'avg';
fig = show_moments_spectrum(data,options);
% fig = show_napjz(data,options);
% save_figure(data,fig,'.png');
end
if 0
%% Time averaged spectrum
-options.TIME = [300 600];
+options.TIME = [2000 3000];
options.NORM =1;
-options.NAME = '\phi';
+% options.NAME = '\phi';
% options.NAME = 'N_i^{00}';
-% options.NAME ='\Gamma_x';
+options.NAME ='\Gamma_x';
options.PLAN = 'kxky';
options.COMPZ = 'avg';
options.OK = 0;
options.COMPXY = 'avg'; % avg/sum/max/zero/ 2D plot otherwise
options.COMPT = 'avg';
options.PLOT = 'semilogy';
fig = spectrum_1D(data,options);
% save_figure(data,fig,'.png')
end
if 0
%% 1D real plot
options.TIME = [50 100 200];
options.NORM = 0;
options.NAME = '\phi';
% options.NAME = 'n_i';
% options.NAME ='\Gamma_x';
% options.NAME ='s_y';
options.COMPX = 'avg';
options.COMPY = 'avg';
options.COMPZ = 1;
options.COMPT = 1;
options.MOVMT = 1;
fig = real_plot_1D(data,options);
% save_figure(data,fig,'.png')
end
if 0
%% Mode evolution
options.NORMALIZED = 0;
options.K2PLOT = [0.1 0.2 0.3 0.4];
options.TIME = [00:1200];
options.NMA = 1;
options.NMODES = 5;
options.iz = 'avg';
fig = mode_growth_meter(data,options);
save_figure(data,fig,'.png')
end
if 0
%% ZF caracteristics (space time diagrams)
TAVG_0 = 1200; TAVG_1 = 1500; % Averaging times duration
% chose your field to plot in spacetime diag (uzf,szf,Gx)
fig = ZF_spacetime(data,TAVG_0,TAVG_1);
save_figure(data,fig,'.png')
end
if 0
%% Metric infos
-fig = plot_metric(data);
+options.SHOW_FLUXSURF = 1;
+options.SHOW_METRICS = 0;
+fig = plot_metric(data,options);
end
if 0
%% linear growth rate for 3D fluxtube
trange = [0 100];
nplots = 1;
lg = compute_fluxtube_growth_rate(data,trange,nplots);
end
if 0
%% linear growth rate for 3D Zpinch
trange = [5 15];
options.keq0 = 1; % chose to plot planes at k=0 or max
options.kxky = 1;
options.kzkx = 0;
options.kzky = 1;
[lg, fig] = compute_3D_zpinch_growth_rate(data,trange,options);
save_figure(data,fig,'.png')
end
diff --git a/wk/header_2DZP_results.m b/wk/header_2DZP_results.m
index b180dd5..cdd4074 100644
--- a/wk/header_2DZP_results.m
+++ b/wk/header_2DZP_results.m
@@ -1,200 +1,224 @@
%% Directory of the simulation
gyacomodir = pwd; gyacomodir = gyacomodir(1:end-2); % get code directory
% if 1% Local results
resdir ='';
resdir ='';
resdir ='';
resdir ='';
% resdir ='debug/ppj_init';
%% nu = 5e-1
% Sugama
% resdir ='Hallenbert_nu_5e-01/200x32_5x3_L_120_kN_1.5_kT_0.375_nu_5e-01_SGGK';% also in 7x4
% resdir ='Hallenbert_nu_5e-01/200x32_5x3_L_120_kN_1.6_kT_0.4_nu_5e-01_SGGK';
% resdir ='Hallenbert_nu_5e-01/200x32_7x4_L_120_kN_1.7_kT_0.425_nu_5e-01_SGGK';% also in 7x4
% resdir ='Hallenbert_nu_5e-01/200x32_5x3_L_120_kN_1.8_kT_0.45_nu_5e-01_SGGK';
% resdir ='Hallenbert_nu_5e-01/200x32_5x3_L_120_kN_1.9_kT_0.475_nu_5e-01_SGGK';%also in 7x4
%% nu = 1e-1
% Landau
% resdir ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.5_kT_0.375_nu_1e-01_LDGK';
% resdir ='Hallenbert_nu_1e-01/150x50_5x3_L_120_kN_1.6_kT_0.4_nu_1e-01_LDGK';
% resdir ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.6_kT_0.4_nu_1e-01_LDGK';
% resdir ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.7_kT_0.425_nu_1e-01_LDGK';
% resdir ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.8_kT_0.45_nu_1e-01_LDGK';
% resdir ='Hallenbert_nu_1e-01/150x50_5x3_L_120_kN_1.8_kT_0.45_nu_1e-01_LDGK';
% resdir ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.9_kT_0.475_nu_1e-01_LDGK';
% Sugama
% resdir ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.5_kT_0.375_nu_1e-01_SGGK';
% resdir ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.7_kT_0.425_nu_1e-01_SGGK';
% resdir ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.8_kT_0.45_nu_1e-01_SGGK';
% resdir ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.9_kT_0.475_nu_1e-01_SGGK';
% Dougherty
% resdir ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.5_kT_0.375_nu_1e-01_DGGK';
% resdir ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.6_kT_0.4_nu_1e-01_DGGK';
% resdir ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.7_kT_0.425_nu_1e-01_DGGK';
% resdir ='Hallenbert_nu_1e-01/200x32_5x3_L_120_kN_1.8_kT_0.45_nu_1e-01_DGGK';
%% nu = 5e-2
% resdir ='Hallenbert_nu_5e-02/200x32_11x6_L_120_kN_1.8_kT_0.45_nu_5e-02_SGGK';%For GENE benchmark % to analyse (added HD)
% resdir ='Hallenbert_nu_5e-02/200x32_11x6_Lx_120_Ly_60_kN_1.8_kT_0.45_nu_5e-02_SGGK';
% testing various NL closures
% resdir ='Hallenbert_nu_5e-02/200x32_7x4_Lx_120_Ly_60_kN_1.8_kT_0.45_nu_5e-02_SGGK';
% resdir ='Hallenbert_nu_5e-02/200x32_5x3_Lx_120_Ly_60_kN_1.8_kT_0.45_nu_5e-02_SGDK';
% resdir ='Hallenbert_nu_5e-02/200x32_11x6_Lx_120_Ly_60_kN_1.8_kT_0.45_nu_5e-02_SGDK';
% resdir ='Hallenbert_nu_5e-02/256x64_5x3_Lx_120_Ly_60_kN_1.8_kT_0.45_nu_5e-02_SGDK';
% resdir ='Hallenbert_nu_5e-02/256x64_11x6_Lx_120_Ly_60_kN_1.8_kT_0.45_nu_5e-02_SGDK';
% resdir ='Hallenbert_nu_5e-02/200x32_21x3_Lx_120_Ly_60_kN_1.8_kT_0.45_nu_5e-02_SGDK';
% resdir ='Hallenbert_nu_5e-02/200x32_17x9_L_120_kN_1.8_kT_0.45_nu_5e-02_SGDK';
% resdir ='Hallenbert_nu_5e-02/200x32_5x3_Lx_120_Ly_60_kN_1.8_kT_0.45_nu_5e-02_DGGK';
% resdir ='Hallenbert_nu_5e-02/200x32_11x6_Lx_120_Ly_60_kN_1.8_kT_0.45_nu_5e-02_DGGK';
% resdir ='Hallenbert_nu_5e-02/128x32_5x3_Lx_120_Ly_60_kN_1.8_kT_0.45_nu_5e-02_FCGK';
%% nu = 1e-2
% Landau
% resdir ='Hallenbert_nu_1e-02/200x32_5x3_L_120_kN_1.5_kT_0.375_nu_1e-02_LDGK';
% resdir ='Hallenbert_nu_1e-02/200x32_5x3_L_120_kN_1.6_kT_0.4_nu_1e-02_LDGK';
% resdir ='Hallenbert_nu_1e-02/200x32_5x3_L_120_kN_1.7_kT_0.425_nu_1e-02_LDGK';
% resdir ='Hallenbert_nu_1e-02/200x32_5x3_L_120_kN_1.8_kT_0.45_nu_1e-02_LDGK';
% resdir ='Hallenbert_nu_1e-02/200x32_5x3_L_120_kN_1.9_kT_0.475_nu_1e-02_LDGK';
% Sugama
% resdir ='kobayashi_2015_fig1/150x150_5x3_L_100_kN_1.4_nu_5e-03_SGGK';
% resdir ='Hallenbert_nu_1e-02/200x32_7x4_L_120_kN_1.5_kT_0.375_nu_1e-02_SGGK';
% resdir ='Hallenbert_nu_1e-02/200x32_5x3_L_120_kN_1.5_kT_0.375_nu_1e-02_SGGK';
% resdir ='Hallenbert_nu_1e-02/200x32_5x3_L_120_kN_1.6_kT_0.4_nu_1e-02_SGGK';
% resdir ='Hallenbert_nu_1e-02/200x32_7x4_L_120_kN_1.6_kT_0.4_nu_1e-02_SGGK';
% resdir ='Hallenbert_nu_1e-02/200x32_5x3_L_120_kN_1.7_kT_0.425_nu_1e-02_SGGK';
% resdir ='Hallenbert_nu_1e-02/300x64_5x3_L_120_kN_1.7_kT_0.425_nu_1e-02_SGGK';
% resdir ='Hallenbert_nu_1e-02/200x32_11x6_L_120_kN_1.7_kT_0.425_nu_1e-02_SGGK';
% resdir ='Hallenbert_nu_1e-02/200x32_5x3_L_120_kN_1.8_kT_0.45_nu_1e-02_SGGK'; % To analyse (added HD)
% resdir ='Hallenbert_nu_1e-02/200x32_5x3_L_120_kN_1.9_kT_0.475_nu_1e-02_SGGK';
% resdir ='Hallenbert_nu_1e-02/200x32_11x6_L_120_kN_1.9_kT_0.475_nu_1e-02_SGGK';
% Dougherty
% resdir ='Hallenbert_nu_1e-02/200x32_7x4_L_120_kN_1.5_kT_0.375_nu_1e-02_DGGK';
% resdir ='Hallenbert_nu_1e-02/200x32_5x3_L_120_kN_1.6_kT_0.4_nu_1e-02_DGGK';
% resdir ='Hallenbert_nu_1e-02/200x32_8x5_L_120_kN_1.6_kT_0.4_nu_0e+00_DGGK';
% resdir ='Hallenbert_nu_1e-02/200x32_5x3_L_120_kN_1.8_kT_0.45_nu_1e-02_DGGK';
%% nu = 5e-3
% resdir ='Hallenbert_nu_5e-03/200x32_5x3_Lx_120_Ly_60_kN_1.8_eta_0.25_nuSG_5e-03_muxy_5e-2';
% resdir ='Hallenbert_nu_5e-03/200x32_5x3_Lx_120_Ly_60_kN_1.8_eta_0.25_nuSG_5e-03_mux_5e-2_muy_6e-1';
% resdir ='Hallenbert_nu_5e-03/200x32_11x6_Lx_120_Ly_60_kN_1.8_eta_0.25_nuSG_5e-03_mux_5e-2_muy_6e-1';
% resdir ='Hallenbert_nu_5e-03/200x32_11x6_Lx_120_Ly_60_kN_1.8_eta_0.25_nuSG_5e-03_muxy_5e-2';
%% nu = 0
% resdir ='Hallenbert_fig2a/200x32_21x11_Lx_120_Ly_60_kN_1.6_eta_0.4_nu_0_muxy_1e-2';
% resdir ='Hallenbert_fig2a/200x32_11x6_Lx_120_Ly_60_kN_1.6_eta_0.4_nu_0_muxy_1e-2';
% resdir ='Hallenbert_fig2a/200x32_5x3_Lx_120_Ly_60_kN_1.6_eta_0.4_nu_0_muxy_1e-2';
% resdir ='Hallenbert_fig2a/200x32_5x3_Lx_120_Ly_60_kN_1.6_eta_0.4_nuDGGK_0.1_muxy_1e-2';
% resdir ='Hallenbert_fig2a/200x32_11x6_Lx_120_Ly_60_kN_1.6_eta_0.4_nuDGGK_0.1_muxy_1e-2';
% resdir ='Hallenbert_fig2a/200x32_5x3_Lx_120_Ly_60_kN_1.6_eta_0.4_nuSGGK_0.1_muxy_1e-2';
% resdir ='Hallenbert_fig2a/200x32_11x6_Lx_120_Ly_60_kN_1.6_eta_0.4_nuSGGK_0.1_muxy_1e-2';
% resdir ='Hallenbert_fig2a/200x32_5x3_Lx_120_Ly_60_kN_1.6_eta_0.4_nuLDGK_0.1_muxy_1e-2';
% resdir ='Hallenbert_fig2a/200x32_5x3_Lx_120_Ly_60_kN_1.6_eta_0.4_nuLRGK_0.1_muxy_1e-2';
% resdir ='Hallenbert_fig2b/200x32_11x6_Lx_240_Ly_120_kN_2.5_eta_0.25_nu_0_muxy_1e-1';
% resdir ='Hallenbert_fig2b/200x32_5x3_Lx_240_Ly_120_kN_2.5_eta_0.25_nu_0_muxy_1e-1';
% resdir ='Hallenbert_fig2b/200x32_5x3_Lx_240_Ly_120_kN_2.5_eta_0.25_nuSGGK_0.1_muxy_1e-1';
% resdir ='Hallenbert_fig2b/200x32_5x3_Lx_240_Ly_120_kN_2.5_eta_0.25_nuDGGK_0.1_muxy_1e-1';
% resdir ='Hallenbert_fig2b/200x32_5x3_Lx_240_Ly_120_kN_2.5_eta_0.25_nuLDGK_0.1_muxy_1e-1';
% resdir ='Hallenbert_fig2b/200x32_5x3_Lx_240_Ly_120_kN_2.5_eta_0.25_nuLRGK_0.1_muxy_1e-1';
% resdir ='Hallenbert_fig2c/200x32_11x6_Lx_120_Ly_60_kN_2.0_eta_0.25_nu_0_muxy_5e-2';
% resdir ='Hallenbert_fig2c/200x32_5x3_Lx_120_Ly_60_kN_2.0_eta_0.25_nu_0_muxy_5e-2';
% resdir ='Hallenbert_fig2c/200x32_5x3_Lx_120_Ly_60_kN_2.0_eta_0.25_nuSGGK_0.1_muxy_5e-2';
% resdir ='Hallenbert_fig2c/200x32_11x6_Lx_120_Ly_60_kN_2.0_eta_0.25_nuSGGK_0.1_muxy_5e-2';
% resdir ='Hallenbert_fig2c/200x32_5x3_Lx_120_Ly_60_kN_2.0_eta_0.25_nuDGGK_0.1_muxy_5e-2';
% resdir ='Hallenbert_fig2c/200x32_11x6_Lx_120_Ly_60_kN_2.0_eta_0.25_nuDGGK_0.1_muxy_5e-2';
% resdir ='Hallenbert_fig2c/200x32_5x3_Lx_120_Ly_60_kN_2.0_eta_0.25_nuLDGK_0.1_muxy_5e-2';
% resdir ='Hallenbert_fig2c/200x32_5x3_Lx_120_Ly_60_kN_2.0_eta_0.25_nuLRGK_0.1_muxy_5e-2';
% resdir ='Hallenbert_fig2c/200x32_9x5_Lx_120_Ly_60_kN_2.0_eta_0.25_nuLRGK_0.1_muxy_5e-2';
%% Transport scan
% resdir = 'nu_0.1_transport_scan/colless_kn_1.7_to_2.0';
% resdir = 'nu_0.1_transport_scan/colless_kn_2.1_to_2.5';
% resdir = 'nu_0.1_transport_scan/LB_kn_2.0';
% resdir = 'nu_0.1_transport_scan/DG_kn_1.8_to_2.1';
% resdir = 'nu_0.1_transport_scan/DG_kn_2.2_to_2.5';
% resdir = 'nu_0.1_transport_scan/DG_conv_kN_1.9';
% resdir = 'nu_0.1_transport_scan/SG_kn_1.7_to_2.0';
% resdir = 'nu_0.1_transport_scan/SG_10x5_conv_test';
% resdir = 'nu_0.1_transport_scan/SG_kn_2.2_to_2.5';
% resdir = 'nu_0.1_transport_scan/LD_kn_2.0_to_2.5';
% resdir = 'nu_0.1_transport_scan/LD_kn_1.7_to_2.5';
% resdir = 'nu_0.1_transport_scan/LR_kn_1.7_to_2.0';
% resdir = 'nu_0.1_transport_scan/LR_kn_2.1_to_2.5';
% resdir = 'nu_0.1_transport_scan/colless_kn_2.2_Lx1.5';
% resdir = 'nu_0.1_transport_scan/colless_kn_2.2_HD';
% resdir = 'nu_0.1_transport_scan/colless_kn_1.6_HD';
% resdir = 'nu_0.1_transport_scan/large_box_kN_2.1_nu_0.1';
% resdir = 'nu_0.1_transport_scan/large_box_kN_2.0_nu_0.1';
% resdir = 'predator_prey_nu_scan/DG_Kn_1.7_nu_0.01';
% resdir = 'ZF_damping_linear_nu_0_20x10_kn_1.6_GK/LR_4x2_nu_0.1';
% resdir = 'ZF_damping_nu_0_20x10_kn_1.6_GK/HSG_4x2_nu_0.1';
% resdir = 'ZF_damping_nu_0_5x3_kn_2.5_GK/LR_4x2_nu_0.1';
% resdir = 'hacked_sugama/hacked_B_kn_1.6_200x32_L_120x60_nu_0.1';
% resdir = 'shearless_cyclone/200x32x24_5x4_Lx_120_Ly_60_q0_1.4_e_0.18_kN_2.22_kT_6.9_nuLR_0.01_adiab_e';
% resdir = 'shearless_cyclone/no_sg_128x32x36_6x3_Lx_120_Ly_60_q0_1.4_e_0.18_kN_2.22_kT_6.9_adiab_e';
% resdir = 'shearless_cyclone/sgrid_128x64x32_4x2_Lx_100_Ly_120_q0_1.4_e_0.18_kN_2.22_kT_6.96_adiab_e';
% resdir = 'shearless_cyclone/sgrid_128x64x32_4x2_Lx_100_Ly_120_q0_1.4_e_0.18_kN_1.78_kT_5.52_adiab_e';
% resdir = 'linear_shearless_cyclone/4_2_cyclone_1.0';
% resdir = 'linear_shearless_cyclone/test_fmom';
% else% Marconi results
% resdir ='';
% resdir ='';
% resdir ='';fd
% resdir ='';
% resdir ='/marconi_scratch/userexternal/ahoffman/HeLaZ/results/simulation_A_new/300x300_5x3_L_120_kN_1.6667_nu_1e-01_SGGK/out.txt';
% % resdir ='/marconi_scratch/userexternal/ahoffman/HeLaZ/results/simulation_A/300x150_L_120_P_8_J_4_eta_0.6_nu_1e-01_SGGK_mu_0e+00/out.txt';
% % BASIC.RESDIR = ['../',resdir(46:end-8),'/'];
% MISCDIR = ['/misc/HeLaZ_outputs/',resdir(46:end-8),'/'];
% end
%% ZPINCH rerun
% resdir ='Zpinch_rerun/Kn_2.5_200x48x5x3';
% resdir ='Zpinch_rerun/Kn_2.5_256x128x5x3';
% resdir ='Zpinch_rerun/Kn_2.5_312x196x5x3_Lx_400_Ly_200';
% resdir ='Zpinch_rerun/Kn_2.5_256x64x5x3';
% resdir ='Zpinch_rerun/Kn_2.0_200x48x9x5_large_box';
% resdir ='Zpinch_rerun/Kn_2.0_256x64x9x5_Lx_240_Ly_120';
% resdir ='Zpinch_rerun/Kn_1.6_256x128x7x4';
% resdir ='Zpinch_rerun/Kn_1.6_200x64x11x6';
% resdir ='Zpinch_rerun/Kn_1.6_200x64x11x6_conv';
% resdir ='Zpinch_rerun/Kn_1.6_200x64x11x6_mu_0.5';
% resdir ='Zpinch_rerun/Kn_1.6_256x128x21x11';
%% nu scan
% resdir = 'Zpinch_rerun/kN_2.2_coll_scan_128x48x5x3';
% resdir = 'Zpinch_rerun/Ultra_HD_312x196x5x3';
% resdir = 'Zpinch_rerun/UHD_nu_001_LDGK';
% resdir = 'Zpinch_rerun/UHD_nu_01_LDGK';
% resdir = 'Zpinch_rerun/UHD_nu_1_LDGK';
% resdir ='Zpinch_rerun/kN_1.7_SGGK_conv_200x32x7x3_nu_0.01';
% resdir ='Zpinch_rerun/kN_1.7_LDGKii_200x32x7x3_nu_scan';
% resdir ='Zpinch_rerun/nu_0.1_LDGKii_200x48x7x4_kN_scan';
-resdir ='Zpinch_rerun/nu_0.1_FCGK_200x48x5x3_kN_scan';
+% resdir ='Zpinch_rerun/nu_0.1_FCGK_200x48x5x3_kN_scan';
+% resdir ='Zpinch_rerun/nu_0.1_SGGK_200x48x5x3_kN_scan';
% resdir = 'Zpinch_rerun/kN_1.7_FCGK_200x32x5x3_nu_scan';
-% resdir = 'Zpinch_rerun/kN_1.7_SGGK_200x32x7x4_nu_scan';
-%%
-JOBNUMMIN = 00; JOBNUMMAX = 10;
+% % resdir = 'Zpinch_rerun/kN_1.7_SGGK_200x32x7x4_nu_scan';
+% resdir = 'Zpinch_rerun/kN_2.2_SGGK_200x32x5x3_nu_scan';
+% resdir = 'Zpinch_rerun/kN_1.7_SGGK_256x64x5x3_nu_scan';
+%% Convergence cases kN = (1.6 2.2) nu = (0.01 1.0)
+% resdir = 'Zpinch_rerun/convcoll_Kn_1.6_200x32x3x2_mu_0.01';
+% resdir = 'Zpinch_rerun/convcoll_Kn_1.6_200x32x5x3_mu_0.01';
+% resdir = 'Zpinch_rerun/convcoll_Kn_1.6_200x32x7x4_mu_0.01';
+% resdir = 'Zpinch_rerun/convcoll_Kn_1.6_200x32x9x5_mu_0.01';
+
+% resdir = 'Zpinch_rerun/convcoll_Kn_2.2_200x32x3x2_mu_0.01';
+% resdir = 'Zpinch_rerun/convcoll_Kn_2.2_200x32x5x3_mu_0.01';
+% resdir = 'Zpinch_rerun/convcoll_Kn_2.2_200x32x7x4_mu_0.01';
+resdir = 'Zpinch_rerun/convcoll_Kn_2.2_200x32x9x5_mu_0.01';
+
+% resdir = 'Zpinch_rerun/convcoll_Kn_1.6_200x32x3x2_nu_0.1';
+% resdir = 'Zpinch_rerun/convcoll_Kn_1.6_200x32x5x3_nu_0.1';
+% resdir = 'Zpinch_rerun/convcoll_Kn_1.6_200x32x7x4_nu_0.1';
+% resdir = 'Zpinch_rerun/convcoll_Kn_1.6_200x32x9x5_nu_0.1';
+
+% resdir = 'Zpinch_rerun/convcoll_Kn_2.2_200x32x3x2_nu_0.1';
+% resdir = 'Zpinch_rerun/convcoll_Kn_2.2_200x32x5x3_nu_0.1';
+% resdir = 'Zpinch_rerun/convcoll_Kn_2.2_200x32x7x4_nu_0.1';
+% resdir = 'Zpinch_rerun/convcoll_Kn_2.2_200x32x9x5_nu_0.1';
+
+
+JOBNUMMIN = 00; JOBNUMMAX = 03;
resdir = ['results/',resdir];
run analysis_gyacomo
\ No newline at end of file
diff --git a/wk/header_3D_results.m b/wk/header_3D_results.m
index 2a56c2d..63cb0bf 100644
--- a/wk/header_3D_results.m
+++ b/wk/header_3D_results.m
@@ -1,64 +1,66 @@
% Directory of the code "mypathtoHeLaZ/HeLaZ/"
-helazdir = '/home/ahoffman/HeLaZ/';
+gyacomodir = '/home/ahoffman/gyacomo/';
% Directory of the simulation (from results)
% if 1% Local results
-% outfile ='volcokas/64x32x16x5x3_kin_e_npol_1';
+% resdir ='volcokas/64x32x16x5x3_kin_e_npol_1';
%% Dimits
-% outfile ='shearless_cyclone/128x64x16x5x3_Dim_90';
-% outfile ='shearless_cyclone/128x64x16x9x5_Dim_scan/128x64x16x9x5_Dim_60';
-% outfile ='shearless_cyclone/128x64x16x5x3_Dim_scan/128x64x16x5x3_Dim_70';
-% outfile ='shearless_cyclone/64x32x16x5x3_Dim_scan/64x32x16x5x3_Dim_70';
+% resdir ='shearless_cyclone/128x64x16x5x3_Dim_90';
+% resdir ='shearless_cyclone/128x64x16x9x5_Dim_scan/128x64x16x9x5_Dim_60';
+% resdir ='shearless_cyclone/128x64x16x5x3_Dim_scan/128x64x16x5x3_Dim_70';
+% resdir ='shearless_cyclone/64x32x16x5x3_Dim_scan/64x32x16x5x3_Dim_70';
%% AVS
-% outfile = 'volcokas/64x32x16x5x3_kin_e_npol_1';
-% outfile = 'volcokas/64x32x16x5x3_kin_e_npol_1';
-% outfile = 'shearless_cyclone/64x32x80x5x3_CBC_Npol_5_kine';
-% outfile = 'shearless_cyclone/96x32x160x5x3_CBC_Npol_10_kine';
-% outfile = 'shearless_cyclone/64x32x160x5x3_CBC_Npol_10_kine';
-% outfile = 'shearless_cyclone/96x32x160x5x3_CBC_Npol_10_kine';
+% resdir = 'volcokas/64x32x16x5x3_kin_e_npol_1';
+% resdir = 'volcokas/64x32x16x5x3_kin_e_npol_1';
+% resdir = 'shearless_cyclone/64x32x80x5x3_CBC_Npol_5_kine';
+% resdir = 'shearless_cyclone/96x32x160x5x3_CBC_Npol_10_kine';
+% resdir = 'shearless_cyclone/64x32x160x5x3_CBC_Npol_10_kine';
+% resdir = 'shearless_cyclone/96x32x160x5x3_CBC_Npol_10_kine';
%% shearless CBC
-% outfile ='shearless_cyclone/64x32x16x5x3_CBC_080';
-% outfile ='shearless_cyclone/64x32x16x5x3_CBC_scan/64x32x16x5x3_CBC_100';
-% outfile ='shearless_cyclone/64x32x16x5x3_CBC_120';
+% resdir ='shearless_cyclone/64x32x16x5x3_CBC_080';
+% resdir ='shearless_cyclone/64x32x16x5x3_CBC_scan/64x32x16x5x3_CBC_100';
+% resdir ='shearless_cyclone/64x32x16x5x3_CBC_120';
-% outfile ='shearless_cyclone/64x32x16x9x5_CBC_080';
-% outfile ='shearless_cyclone/64x32x16x9x5_CBC_100';
-% outfile ='shearless_cyclone/64x32x16x9x5_CBC_120';
+% resdir ='shearless_cyclone/64x32x16x9x5_CBC_080';
+% resdir ='shearless_cyclone/64x32x16x9x5_CBC_100';
+% resdir ='shearless_cyclone/64x32x16x9x5_CBC_120';
-% outfile = 'shearless_cyclone/64x32x16x5x3_CBC_CO/64x32x16x5x3_CBC_LRGK';
+% resdir = 'shearless_cyclone/64x32x16x5x3_CBC_CO/64x32x16x5x3_CBC_LRGK';
%% CBC
-% outfile = 'CBC/64x32x16x5x3';
-% outfile = 'CBC/64x128x16x5x3';
-% outfile = 'CBC/128x64x16x5x3';
-% outfile = 'CBC/96x96x16x3x2_Nexc_6';
-% outfile = 'CBC/128x96x16x3x2';
-% outfile = 'CBC/192x96x16x3x2';
-% outfile = 'CBC/192x96x24x13x7';
-% outfile = 'CBC/kT_11_128x64x16x5x3';
-% outfile = 'CBC/kT_9_256x128x16x3x2';
-% outfile = 'CBC/kT_4.5_128x64x16x13x3';
-% outfile = 'CBC/kT_4.5_192x96x24x13x7';
-% outfile = 'CBC/kT_4.5_128x64x16x13x7';
-% outfile = 'CBC/kT_4.5_128x96x24x15x5';
-% outfile = 'CBC/kT_5.3_192x96x24x13x7';
-% outfile = 'CBC/kT_13_large_box_128x64x16x5x3';
-% outfile = 'CBC/kT_11_96x64x16x5x3_ky_0.02';
+% resdir = 'CBC/64x32x16x5x3';
+% resdir = 'CBC/64x128x16x5x3';
+% resdir = 'CBC/128x64x16x5x3';
+% resdir = 'CBC/96x96x16x3x2_Nexc_6';
+% resdir = 'CBC/128x96x16x3x2';
+% resdir = 'CBC/192x96x16x3x2';
+% resdir = 'CBC/192x96x24x13x7';
+% resdir = 'CBC/kT_11_128x64x16x5x3';
+% resdir = 'CBC/kT_9_256x128x16x3x2';
+% resdir = 'CBC/kT_4.5_128x64x16x13x3';
+% resdir = 'CBC/kT_4.5_192x96x24x13x7';
+% resdir = 'CBC/kT_4.5_128x64x16x13x7';
+% resdir = 'CBC/kT_4.5_128x96x24x15x5';
+% resdir = 'CBC/kT_5.3_192x96x24x13x7';
+% resdir = 'CBC/kT_13_large_box_128x64x16x5x3';
+% resdir = 'CBC/kT_11_96x64x16x5x3_ky_0.02';
-% outfile = 'CBC/kT_scan_128x64x16x5x3';
-% outfile = 'CBC/kT_scan_192x96x16x3x2';
-% outfile = 'CBC/kT_13_96x96x16x3x2_Nexc_6';
-% outfile = 'dbg/nexc_dbg';
-outfile = 'CBC/NM_F4_kT_4.5_192x64x24x6x4';
+% resdir = 'CBC/kT_scan_128x64x16x5x3';
+% resdir = 'CBC/kT_scan_192x96x16x3x2';
+% resdir = 'CBC/kT_13_96x96x16x3x2_Nexc_6';
+% resdir = 'dbg/nexc_dbg';
+% resdir = 'CBC/NM_F4_kT_4.5_192x64x24x6x4';
-% outfile = 'CBC_Ke_EM/192x96x24x5x3';
-% outfile = 'CBC_Ke_EM/96x48x16x5x3';
-% outfile = 'CBC_Ke_EM/minimal_res';
+% resdir = 'CBC_Ke_EM/192x96x24x5x3';
+% resdir = 'CBC_Ke_EM/96x48x16x5x3';
+% resdir = 'CBC_Ke_EM/minimal_res';
%% KBM
-% outfile = 'NL_KBM/192x64x24x5x3';
+% resdir = 'NL_KBM/192x64x24x5x3';
%% Linear CBC
-% outfile = 'linear_CBC/20x2x32_21x11_Lx_62.8319_Ly_31.4159_q0_1.4_e_0.18_s_0.8_kN_2.22_kT_5.3_nu_1e-02_DGDK_adiabe';
-
+% resdir = 'linear_CBC/20x2x32_21x11_Lx_62.8319_Ly_31.4159_q0_1.4_e_0.18_s_0.8_kN_2.22_kT_5.3_nu_1e-02_DGDK_adiabe';
+% resdir = 'testcases/miller_example';
+resdir = 'Miller/128x256x3x2_CBC_dt_5e-3';
+% resdir = ['results/',resdir];
JOBNUMMIN = 00; JOBNUMMAX = 10;
-run analysis_HeLaZ
+run analysis_gyacomo
diff --git a/wk/lin_EPY.m b/wk/lin_EPY.m
index 41abd8a..2ddd756 100644
--- a/wk/lin_EPY.m
+++ b/wk/lin_EPY.m
@@ -1,179 +1,182 @@
%% QUICK RUN SCRIPT for linear entropy mode in a Zpinch
% This script create a directory in /results and run a simulation directly
% from matlab framework. It is meant to run only small problems in linear
% for benchmark and debugging purpose since it makes matlab "busy"
%
SIMID = 'lin_EPY'; % Name of the simulation
-RUN = 1; % To run or just to load
+% SIMID = 'dbg'; % Name of the simulation
+RUN = 0; % To run or just to load
addpath(genpath('../matlab')) % ... add
default_plots_options
PROGDIR = '/home/ahoffman/gyacomo/';
-% EXECNAME = 'gyacomo_1.0';
+% EXECNAME = 'gyacomo_dbg';
EXECNAME = 'gyacomo';
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Set Up parameters
CLUSTER.TIME = '99:00:00'; % allocation time hh:mm:ss
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% PHYSICAL PARAMETERS
NU = 0.1; % Collision frequency
TAU = 1.0; % e/i temperature ratio
-K_Ne = 2.2; % ele Density '''
+K_Ne = 1.6; % ele Density '''
K_Te = K_Ne/4; % ele Temperature '''
K_Ni = K_Ne; % ion Density gradient drive
K_Ti = K_Ni/4; % ion Temperature '''
SIGMA_E = 0.0233380; % mass ratio sqrt(m_a/m_i) (correct = 0.0233380)
KIN_E = 1; % 1: kinetic electrons, 2: adiabatic electrons
BETA = 0.0; % electron plasma beta
%% GRID PARAMETERS
-P = 4;
+P = 2;
J = P/2;
PMAXE = P; % Hermite basis size of electrons
JMAXE = J; % Laguerre "
PMAXI = P; % " ions
JMAXI = J; % "
NX = 2; % real space x-gridpoints
NY = 100; % '' y-gridpoints
LX = 2*pi/0.8; % Size of the squared frequency domain
LY = 120;%2*pi/0.05; % Size of the squared frequency domain
NZ = 1; % number of perpendicular planes (parallel grid)
NPOL = 1;
SG = 0; % Staggered z grids option
%% GEOMETRY
GEOMETRY= 'Z-pinch'; % Z-pinch overwrites q0, shear and eps
Q0 = 1.4; % safety factor
SHEAR = 0.8; % magnetic shear
NEXC = 1; % To extend Lx if needed (Lx = Nexc/(kymin*shear))
EPS = 0.18; % inverse aspect ratio
%% TIME PARMETERS
-TMAX = 50; % Maximal time unit
+TMAX = 500; % Maximal time unit
DT = 1e-2; % Time step
SPS0D = 1; % Sampling per time unit for 2D arrays
SPS2D = 0; % Sampling per time unit for 2D arrays
-SPS3D = 2; % Sampling per time unit for 2D arrays
+SPS3D = 1/5; % Sampling per time unit for 2D arrays
SPS5D = 1/5; % Sampling per time unit for 5D arrays
SPSCP = 0; % Sampling per time unit for checkpoints
JOB2LOAD= -1;
%% OPTIONS
LINEARITY = 'linear'; % activate non-linearity (is cancelled if KXEQ0 = 1)
% Collision operator
% (LB:L.Bernstein, DG:Dougherty, SG:Sugama, LR: Lorentz, LD: Landau)
-CO = 'DG';
+CO = 'SG';
GKCO = 1; % gyrokinetic operator
ABCO = 1; % interspecies collisions
INIT_ZF = 0; ZF_AMP = 0.0;
CLOS = 0; % Closure model (0: =0 truncation, 1: v^Nmax closure (p+2j<=Pmax))s
NL_CLOS = 0; % nonlinear closure model (-2:nmax=jmax; -1:nmax=jmax-j; >=0:nmax=NL_CLOS)
KERN = 0; % Kernel model (0 : GK)
INIT_OPT= 'mom00'; % Start simulation with a noisy mom00/phi/allmom
%% OUTPUTS
W_DOUBLE = 1;
W_GAMMA = 1; W_HF = 1;
W_PHI = 1; W_NA00 = 1;
W_DENS = 1; W_TEMP = 1;
W_NAPJ = 1; W_SAPJ = 0;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% unused
HD_CO = 0.0; % Hyper diffusivity cutoff ratio
MU = 0.0; % Hyperdiffusivity coefficient
INIT_BLOB = 0; WIPE_TURB = 0; ACT_ON_MODES = 0;
MU_X = MU; %
MU_Y = MU; %
N_HD = 4;
MU_Z = 2.0; %
MU_P = 0.0; %
MU_J = 0.0; %
LAMBDAD = 0.0;
NOISE0 = 0.0e-5; % Init noise amplitude
BCKGD0 = 1.0; % Init background
GRADB = 1.0;
CURVB = 1.0;
%%-------------------------------------------------------------------------
%% RUN
setup
% system(['rm fort*.90']);
% Run linear simulation
if RUN
- system(['cd ../results/',SIMID,'/',PARAMS,'/; mpirun -np 6 ',PROGDIR,'bin/',EXECNAME,' 1 6 1 0; cd ../../../wk'])
+% system(['cd ../results/',SIMID,'/',PARAMS,'/; mpirun -np 6 ',PROGDIR,'bin/',EXECNAME,' 1 6 1 0; cd ../../../wk'])
+ system(['cd ../results/',SIMID,'/',PARAMS,'/; mpirun -np 1 ',PROGDIR,'bin/',EXECNAME,' 1 1 1 0; cd ../../../wk'])
end
%% Load results
%%
filename = [SIMID,'/',PARAMS,'/'];
LOCALDIR = [PROGDIR,'results/',filename,'/'];
% Load outputs from jobnummin up to jobnummax
JOBNUMMIN = 00; JOBNUMMAX = 00;
data = compile_results(LOCALDIR,JOBNUMMIN,JOBNUMMAX); %Compile the results from first output found to JOBNUMMAX if existing
%% Short analysis
if 1
%% linear growth rate (adapted for 2D zpinch and fluxtube)
-trange = [0.5 1]*data.Ts3D(end);
-nplots = 1; % 1 for only growth rate and error, 2 for omega local evolution, 3 for plot according to z
-lg = compute_fluxtube_growth_rate(data,trange,nplots);
+options.TRANGE = [0.5 1]*data.Ts3D(end);
+options.NPLOTS = 2; % 1 for only growth rate and error, 2 for omega local evolution, 3 for plot according to z
+options.GOK = 0; %plot 0: gamma 1: gamma/k 2: gamma^2/k^3
+lg = compute_fluxtube_growth_rate(data,options);
[gmax, kmax] = max(lg.g_ky(:,end));
[gmaxok, kmaxok] = max(lg.g_ky(:,end)./lg.ky);
msg = sprintf('gmax = %2.2f, kmax = %2.2f',gmax,lg.ky(kmax)); disp(msg);
msg = sprintf('gmax/k = %2.2f, kmax/k = %2.2f',gmaxok,lg.ky(kmaxok)); disp(msg);
end
if 0
%% Ballooning plot
options.time_2_plot = [120];
options.kymodes = [0.9];
options.normalized = 1;
% options.field = 'phi';
fig = plot_ballooning(data,options);
end
if 0
%% Hermite-Laguerre spectrum
% options.TIME = 'avg';
options.P2J = 1;
options.ST = 1;
options.PLOT_TYPE = 'space-time';
% options.PLOT_TYPE = 'Tavg-1D';
% options.PLOT_TYPE = 'Tavg-2D';
options.NORMALIZED = 0;
options.JOBNUM = 0;
options.TIME = [0 50];
options.specie = 'i';
options.compz = 'avg';
fig = show_moments_spectrum(data,options);
% fig = show_napjz(data,options);
save_figure(data,fig)
end
if 0
%% linear growth rate for 3D Zpinch (kz fourier transform)
trange = [0.5 1]*data.Ts3D(end);
options.keq0 = 1; % chose to plot planes at k=0 or max
options.kxky = 1;
options.kzkx = 0;
options.kzky = 0;
[lg, fig] = compute_3D_zpinch_growth_rate(data,trange,options);
save_figure(data,fig)
end
-if 0
+if 1
%% Mode evolution
options.NORMALIZED = 0;
-options.K2PLOT = 1;
+options.K2PLOT = 10;
options.TIME = [0:1000];
options.NMA = 1;
-options.NMODES = 1;
+options.NMODES = 10;
options.iz = 'avg';
fig = mode_growth_meter(data,options);
save_figure(data,fig,'.png')
end
if 0
%% RH TEST
ikx = 2; iky = 2; t0 = 0; t1 = data.Ts3D(end);
[~, it0] = min(abs(t0-data.Ts3D));[~, it1] = min(abs(t1-data.Ts3D));
plt = @(x) squeeze(mean(real(x(iky,ikx,:,it0:it1)),3))./squeeze(mean(real(x(iky,ikx,:,it0)),3));
figure
plot(data.Ts3D(it0:it1), plt(data.PHI));
xlabel('$t$'); ylabel('$\phi_z(t)/\phi_z(0)$')
title(sprintf('$k_x=$%2.2f, $k_y=$%2.2f',data.kx(ikx),data.ky(iky)))
end
diff --git a/wk/lin_ITG.m b/wk/lin_ITG.m
index bdf3ec0..3ebe622 100644
--- a/wk/lin_ITG.m
+++ b/wk/lin_ITG.m
@@ -1,186 +1,189 @@
%% QUICK RUN SCRIPT
% This script create a directory in /results and run a simulation directly
% from matlab framework. It is meant to run only small problems in linear
% for benchmark and debugging purpose since it makes matlab "busy"
%
SIMID = 'lin_ITG'; % Name of the simulation
-RUN = 1; % To run or just to load
+RUN = 0; % To run or just to load
addpath(genpath('../matlab')) % ... add
default_plots_options
-HELAZDIR = '/home/ahoffman/HeLaZ/';
-% EXECNAME = 'helaz3';
-EXECNAME = 'helaz3_dbg';
+HELAZDIR = '/home/ahoffman/gyacomo/';
+% EXECNAME = 'gyacomo_1.0';
+% EXECNAME = 'gyacomo_dbg';
+EXECNAME = 'gyacomo';
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Set Up parameters
CLUSTER.TIME = '99:00:00'; % allocation time hh:mm:ss
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% PHYSICAL PARAMETERS
-NU = 0.0; % Collision frequency
+NU = 0.05; % Collision frequency
TAU = 1.0; % e/i temperature ratio
K_Ne = 2.22; % ele Density '''
K_Te = 6.96; % ele Temperature '''
K_Ni = 2.22; % ion Density gradient drive
K_Ti = 6.96; % ion Temperature '''
SIGMA_E = 0.05196152422706632; % mass ratio sqrt(m_a/m_i) (correct = 0.0233380)
% SIGMA_E = 0.0233380; % mass ratio sqrt(m_a/m_i) (correct = 0.0233380)
KIN_E = 0; % 1: kinetic electrons, 2: adiabatic electrons
BETA = 0.0; % electron plasma beta
%% GRID PARAMETERS
P = 4;
J = P/2;
PMAXE = P; % Hermite basis size of electrons
JMAXE = J; % Laguerre "
PMAXI = P; % " ions
JMAXI = J; % "
-NX = 11; % real space x-gridpoints
+NX = 20; % real space x-gridpoints
NY = 2; % '' y-gridpoints
LX = 2*pi/0.8; % Size of the squared frequency domain
LY = 2*pi/0.3; % Size of the squared frequency domain
-NZ = 16; % number of perpendicular planes (parallel grid)
+NZ = 32; % number of perpendicular planes (parallel grid)
NPOL = 1;
SG = 0; % Staggered z grids option
%% GEOMETRY
-% GEOMETRY= 'Z-pinch'; % Z-pinch overwrites q0, shear and eps
-GEOMETRY= 's-alpha';
-% GEOMETRY= 'circular';
+% GEOMETRY= 's-alpha';
+GEOMETRY= 'miller';
Q0 = 1.4; % safety factor
SHEAR = 0.8; % magnetic shear
+KAPPA = 0.0; % elongation
+DELTA = 0.0; % triangularity
+ZETA = 0.0; % squareness
NEXC = 1; % To extend Lx if needed (Lx = Nexc/(kymin*shear))
EPS = 0.18; % inverse aspect ratio
%% TIME PARMETERS
-TMAX = 25; % Maximal time unit
-DT = 5e-3; % Time step
+TMAX = 1; % Maximal time unit
+DT = 3e-3; % Time step
SPS0D = 1; % Sampling per time unit for 2D arrays
SPS2D = 0; % Sampling per time unit for 2D arrays
SPS3D = 5; % Sampling per time unit for 2D arrays
SPS5D = 1/5; % Sampling per time unit for 5D arrays
SPSCP = 0; % Sampling per time unit for checkpoints
JOB2LOAD= -1;
%% OPTIONS
LINEARITY = 'linear'; % activate non-linearity (is cancelled if KXEQ0 = 1)
% Collision operator
% (LB:L.Bernstein, DG:Dougherty, SG:Sugama, LR: Lorentz, LD: Landau)
CO = 'DG';
GKCO = 0; % gyrokinetic operator
ABCO = 1; % interspecies collisions
INIT_ZF = 0; ZF_AMP = 0.0;
CLOS = 0; % Closure model (0: =0 truncation, 1: v^Nmax closure (p+2j<=Pmax))s
NL_CLOS = 0; % nonlinear closure model (-2:nmax=jmax; -1:nmax=jmax-j; >=0:nmax=NL_CLOS)
KERN = 0; % Kernel model (0 : GK)
INIT_OPT= 'mom00'; % Start simulation with a noisy mom00/phi/allmom
%% OUTPUTS
W_DOUBLE = 1;
W_GAMMA = 1; W_HF = 1;
W_PHI = 1; W_NA00 = 1;
W_DENS = 1; W_TEMP = 1;
W_NAPJ = 1; W_SAPJ = 0;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% unused
HD_CO = 0.0; % Hyper diffusivity cutoff ratio
MU = 0.0; % Hyperdiffusivity coefficient
INIT_BLOB = 0; WIPE_TURB = 0; ACT_ON_MODES = 0;
MU_X = MU; %
MU_Y = MU; %
N_HD = 4;
MU_Z = 2.0; %
MU_P = 0.0; %
MU_J = 0.0; %
LAMBDAD = 0.0;
NOISE0 = 0.0e-5; % Init noise amplitude
BCKGD0 = 1.0; % Init background
GRADB = 1.0;
CURVB = 1.0;
%%-------------------------------------------------------------------------
%% RUN
setup
% system(['rm fort*.90']);
% Run linear simulation
if RUN
% system(['cd ../results/',SIMID,'/',PARAMS,'/; time mpirun -np 4 ',HELAZDIR,'bin/',EXECNAME,' 1 4 1 0; cd ../../../wk'])
% system(['cd ../results/',SIMID,'/',PARAMS,'/; mpirun -np 4 ',HELAZDIR,'bin/',EXECNAME,' 1 4 1 0; cd ../../../wk'])
% system(['cd ../results/',SIMID,'/',PARAMS,'/; mpirun -np 1 ',HELAZDIR,'bin/',EXECNAME,' 1 1 1 0; cd ../../../wk'])
system(['cd ../results/',SIMID,'/',PARAMS,'/; mpirun -np 6 ',HELAZDIR,'bin/',EXECNAME,' 1 2 3 0; cd ../../../wk'])
% system(['cd ../results/',SIMID,'/',PARAMS,'/; mpirun -np 6 ',HELAZDIR,'bin/',EXECNAME,' 1 6 1 0; cd ../../../wk'])
end
%% Load results
%%
filename = [SIMID,'/',PARAMS,'/'];
LOCALDIR = [HELAZDIR,'results/',filename,'/'];
% Load outputs from jobnummin up to jobnummax
JOBNUMMIN = 00; JOBNUMMAX = 00;
data = compile_results(LOCALDIR,JOBNUMMIN,JOBNUMMAX); %Compile the results from first output found to JOBNUMMAX if existing
%% Short analysis
if 1
%% linear growth rate (adapted for 2D zpinch and fluxtube)
trange = [0.5 1]*data.Ts3D(end);
nplots = 3;
lg = compute_fluxtube_growth_rate(data,trange,nplots);
[gmax, kmax] = max(lg.g_ky(:,end));
[gmaxok, kmaxok] = max(lg.g_ky(:,end)./lg.ky);
msg = sprintf('gmax = %2.2f, kmax = %2.2f',gmax,lg.ky(kmax)); disp(msg);
msg = sprintf('gmax/k = %2.2f, kmax/k = %2.2f',gmaxok,lg.ky(kmaxok)); disp(msg);
end
if 1
%% Ballooning plot
options.time_2_plot = [120];
-options.kymodes = [0.9];
+options.kymodes = [0.3];
options.normalized = 1;
% options.field = 'phi';
fig = plot_ballooning(data,options);
end
if 0
%% Hermite-Laguerre spectrum
% options.TIME = 'avg';
options.P2J = 1;
options.ST = 1;
options.PLOT_TYPE = 'space-time';
% options.PLOT_TYPE = 'Tavg-1D';
% options.PLOT_TYPE = 'Tavg-2D';
options.NORMALIZED = 0;
options.JOBNUM = 0;
options.TIME = [0 50];
options.specie = 'i';
options.compz = 'avg';
fig = show_moments_spectrum(data,options);
% fig = show_napjz(data,options);
save_figure(data,fig)
end
if 0
%% linear growth rate for 3D Zpinch (kz fourier transform)
trange = [0.5 1]*data.Ts3D(end);
options.keq0 = 1; % chose to plot planes at k=0 or max
options.kxky = 1;
options.kzkx = 0;
options.kzky = 0;
[lg, fig] = compute_3D_zpinch_growth_rate(data,trange,options);
save_figure(data,fig)
end
if 0
%% Mode evolution
options.NORMALIZED = 0;
options.K2PLOT = 1;
options.TIME = [0:1000];
options.NMA = 1;
options.NMODES = 1;
options.iz = 'avg';
fig = mode_growth_meter(data,options);
save_figure(data,fig,'.png')
end
if 1
%% RH TEST
ikx = 2; iky = 2; t0 = 0; t1 = data.Ts3D(end);
[~, it0] = min(abs(t0-data.Ts3D));[~, it1] = min(abs(t1-data.Ts3D));
plt = @(x) squeeze(mean(real(x(iky,ikx,:,it0:it1)),3))./squeeze(mean(real(x(iky,ikx,:,it0)),3));
figure
plot(data.Ts3D(it0:it1), plt(data.PHI));
xlabel('$t$'); ylabel('$\phi_z(t)/\phi_z(0)$')
title(sprintf('$k_x=$%2.2f, $k_y=$%2.2f',data.kx(ikx),data.ky(iky)))
end
diff --git a/wk/save_iFFT.m b/wk/save_iFFT.m
index d429b62..d9b3dc9 100644
--- a/wk/save_iFFT.m
+++ b/wk/save_iFFT.m
@@ -1,35 +1,35 @@
%% INPUT
simdir = '/misc/gyacomo_outputs/results/Zpinch_rerun';
resolu = 'UHD_512x256x2x1';
output = 'outputs_01.h5';
filename = [simdir,'/',resolu,'/',output];
-fieldname = 'Ni00';
+fieldname = 'vEy';
%% OUTPUT
outdir = '.';
outname = [fieldname,'_real_',resolu,'.h5'];
outfile = [outdir,'/',outname];
%% Load the complex field F_c
[ F_c, Ts3D, ~] = load_3D_data(filename, fieldname);
%% Measure size and allocate the real field ff_
sz_ =size(real(fftshift(ifourier_GENE(F_c(:,:,1,1))))); % size one frame for the real dimensions
f_r = zeros(sz_(1),sz_(2),numel(Ts3D));
sz_ = size(f_r);
%% Fill the real field f_r
for it = 1:numel(Ts3D)
f_r(:,:,it) = squeeze(real(fftshift(ifourier_GENE(F_c(:,:,1,it)))));
end
clear F_c;
%% Save the real field
h5create(outfile,'/data',sz_,'Datatype','single')
h5write(outfile,'/data',f_r)
h5disp(outfile)
clear f_r
%% small check
test_ = h5read(outfile,'/data');
figure; imagesc(test_(:,:,end));
\ No newline at end of file