From 6620bf8ba18543896e8cddc2bbc028189cf484fb Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Mon, 4 Dec 2023 16:23:35 +0000 Subject: [PATCH 01/62] Modifications to the structure of the geometry inputs and how geometric coefficents are used to permit extending to more complex magnetic geometry. Input options (including defaults) are modified but the input parameters in the examples and runs .toml files are left to be modified in a future commit. --- src/force_balance.jl | 2 +- src/geo.jl | 91 +++++++++++++++++++++++++++++++++ src/initial_conditions.jl | 4 +- src/input_structs.jl | 14 ++--- src/load_data.jl | 8 ++- src/moment_kinetics.jl | 1 + src/moment_kinetics_input.jl | 30 ++++++----- src/r_advection.jl | 3 +- src/velocity_grid_transforms.jl | 21 ++++---- src/velocity_moments.jl | 8 +-- src/vpa_advection.jl | 2 +- src/z_advection.jl | 3 +- 12 files changed, 140 insertions(+), 47 deletions(-) create mode 100644 src/geo.jl diff --git a/src/force_balance.jl b/src/force_balance.jl index 413265260..562f59972 100644 --- a/src/force_balance.jl +++ b/src/force_balance.jl @@ -26,7 +26,7 @@ function force_balance!(pflx, density_out, fvec, moments, fields, collisions, dt dt*(moments.charged.dppar_dz[iz,ir,is] + upar[iz,ir,is]*upar[iz,ir,is]*moments.charged.ddens_dz_upwind[iz,ir,is] + 2.0*density[iz,ir,is]*upar[iz,ir,is]*moments.charged.dupar_dz_upwind[iz,ir,is] - - 0.5*geometry.bzed*fields.Ez[iz,ir]*density[iz,ir,is]) + 0.5*geometry.bzed[iz,ir]*fields.Ez[iz,ir]*density[iz,ir,is]) end if ion_source_settings.active && false diff --git a/src/geo.jl b/src/geo.jl new file mode 100644 index 000000000..c1bc4169f --- /dev/null +++ b/src/geo.jl @@ -0,0 +1,91 @@ +""" +module for including axisymmetric geometry +in coordinates (z,r), with z the vertical +coordinate and r the radial coordinate +""" +module geo + +export init_magnetic_geometry + +using ..input_structs: geometry_input +using ..file_io: input_option_error +using ..array_allocation: allocate_float +using ..type_definitions: mk_float, mk_int + +""" +struct containing the geometric data necessary for +non-trivial axisymmetric geometries, to be passed +around the inside of the code, replacing the +`geometry_input` struct from input_structs.jl + +The arrays of 2 dimensions are functions of (z,r) +""" +struct geometric_coefficients +# for now include the reference parameters in `geometry_input` +input::geometry_input +# also include a copy of rhostar for ease of use +rhostar::mk_float +# the spatially varying coefficients +# Bz/Bref +Bzed::Array{mk_float,2} +# Bzeta/Bref +Bzeta::Array{mk_float,2} +# Btot/Bref +Bmag::Array{mk_float,2} +# bz -- unit vector component in z direction +bzed::Array{mk_float,2} +# bz -- unit vector component in zeta direction +bzeta::Array{mk_float,2} + + +# now the new coefficients + +# d Bmag d z +dBdz::Array{mk_float,2} +# d Bmag d r +dBdr::Array{mk_float,2} + +end + +""" +function to initialise the geometry coefficients +input_data -- geometry_input type +z -- coordinate type +r -- coordinate type +""" +function init_magnetic_geometry(geometry_input_data::geometry_input,z,r) + nz = z.n + nr = r.n + Bzed = allocate_float(nz,nr) + Bzeta = allocate_float(nz,nr) + Bmag = allocate_float(nz,nr) + bzed = allocate_float(nz,nr) + bzeta = allocate_float(nz,nr) + dBdr = allocate_float(nz,nr) + dBdz = allocate_float(nz,nr) + + option = geometry_input_data.option + rhostar = geometry_input_data.rhostar + if option == "constant-helical" + pitch = geometry_input_data.pitch + for ir in 1:nr + for iz in 1:nz + bzed[iz,ir] = pitch + bzeta[iz,ir] = sqrt(1 - bzed[iz,ir]^2) + Bmag[iz,ir] = 1.0 + Bzed[iz,ir] = Bmag[iz,ir]*bzed[iz,ir] + Bzeta[iz,ir] = Bmag[iz,ir]*bzeta[iz,ir] + dBdr[iz,ir] = 0.0 + dBdz[iz,ir] = 0.0 + end + end + else + input_option_error("$option", option) + end + + geometry = geometric_coefficients(geometry_input_data, rhostar, + Bzed,Bzeta,Bmag,bzed,bzeta,dBdz,dBdr) + return geometry +end + +end diff --git a/src/initial_conditions.jl b/src/initial_conditions.jl index 88dbc1d70..d7662bc86 100644 --- a/src/initial_conditions.jl +++ b/src/initial_conditions.jl @@ -1479,12 +1479,12 @@ function enforce_neutral_z_boundary_condition!(pdf, density, uz, pz, moments, de # Note, have already calculated moments of ion distribution function(s), # so can use the moments here to get the flux if z.irank == 0 - ion_flux_0 = -density_ion[1,ir,isn] * (upar_ion[1,ir,isn]*geometry.bzed - 0.5*geometry.rhostar*Er[1,ir]) + ion_flux_0 = -density_ion[1,ir,isn] * (upar_ion[1,ir,isn]*geometry.bzed[1,ir] - 0.5*geometry.rhostar*Er[1,ir]) else ion_flux_0 = NaN end if z.irank == z.nrank - 1 - ion_flux_L = density_ion[end,ir,isn] * (upar_ion[end,ir,isn]*geometry.bzed - 0.5*geometry.rhostar*Er[end,ir]) + ion_flux_L = density_ion[end,ir,isn] * (upar_ion[end,ir,isn]*geometry.bzed[end,ir] - 0.5*geometry.rhostar*Er[end,ir]) else ion_flux_L = NaN end diff --git a/src/input_structs.jl b/src/input_structs.jl index 50c79486d..7bb2a47c5 100644 --- a/src/input_structs.jl +++ b/src/input_structs.jl @@ -327,18 +327,12 @@ end """ """ mutable struct geometry_input - # Bz/Bref - Bzed::mk_float - # Btot/Bref - Bmag::mk_float - # bz -- unit vector component in z direction - bzed::mk_float - # bz -- unit vector component in zeta direction - bzeta::mk_float - # Bzeta/Bref - Bzeta::mk_float # rhostar ion (ref) rhostar::mk_float #used to premultiply ExB drift terms + # magnetic geometry option + option::String + # pitch ( = Bzed/Bmag if geometry_option == "constant-helical") + pitch::mk_float end @enum binary_format_type hdf5 netcdf diff --git a/src/load_data.jl b/src/load_data.jl index 7a2152a76..816053264 100644 --- a/src/load_data.jl +++ b/src/load_data.jl @@ -625,7 +625,13 @@ function reload_evolving_fields!(pdf, moments, boundary_distributions, restart_p neutral_1V = (vzeta.n_global == 1 && vr.n_global == 1) restart_neutral_1V = (restart_vzeta.n_global == 1 && restart_vr.n_global == 1) - if geometry.bzeta != 0.0 && ((neutral1V && !restart_neutral_1V) || + geo_condition = false + for ir in 1:r.n + for iz in 1:z.n + geo_condition = geo_condition || (geometry.bzeta[iz,ir] != 0.0) + end + end + if geo_condition && ((neutral1V && !restart_neutral_1V) || (!neutral1V && restart_neutral_1V)) # One but not the other of the run being restarted from and this run are # 1V, but the interpolation below does not allow for vz and vpa being in diff --git a/src/moment_kinetics.jl b/src/moment_kinetics.jl index a09a68bbb..a25e43393 100644 --- a/src/moment_kinetics.jl +++ b/src/moment_kinetics.jl @@ -31,6 +31,7 @@ include("input_structs.jl") include("reference_parameters.jl") include("coordinates.jl") include("file_io.jl") +include("geo.jl") include("velocity_moments.jl") include("velocity_grid_transforms.jl") include("em_fields.jl") diff --git a/src/moment_kinetics_input.jl b/src/moment_kinetics_input.jl index 1164f22cb..3125b4fe9 100644 --- a/src/moment_kinetics_input.jl +++ b/src/moment_kinetics_input.jl @@ -18,6 +18,7 @@ using ..finite_differences: fd_check_option using ..input_structs using ..numerical_dissipation: setup_numerical_dissipation using ..reference_parameters +using ..geo: init_magnetic_geometry using MPI using TOML @@ -60,7 +61,7 @@ function mk_input(scan_input=Dict(); save_inputs_to_txt=false, ignore_MPI=true) # reference value using J_||e + J_||i = 0 at z = 0 electron_physics = get(scan_input, "electron_physics", boltzmann_electron_response) - z, r, vpa, vperp, gyrophase, vz, vr, vzeta, species, composition, drive, evolve_moments, collisions, geometry = + z, r, vpa, vperp, gyrophase, vz, vr, vzeta, species, composition, drive, evolve_moments, collisions, geometry_in = load_defaults(n_ion_species, n_neutral_species, electron_physics) # this is the prefix for all output files associated with this run @@ -100,12 +101,14 @@ function mk_input(scan_input=Dict(); save_inputs_to_txt=false, ignore_MPI=true) reference_params = setup_reference_parameters(scan_input) ## set geometry_input - geometry.Bzed = get(scan_input, "Bzed", 1.0) - geometry.Bmag = get(scan_input, "Bmag", 1.0) - geometry.bzed = geometry.Bzed/geometry.Bmag - geometry.bzeta = sqrt(1.0 - geometry.bzed^2.0) - geometry.Bzeta = geometry.Bmag*geometry.bzeta - geometry.rhostar = get(scan_input, "rhostar", get_default_rhostar(reference_params)) + #geometry.Bzed = get(scan_input, "Bzed", 1.0) + #geometry.Bmag = get(scan_input, "Bmag", 1.0) + #geometry.bzed = geometry.Bzed/geometry.Bmag + #geometry.bzeta = sqrt(1.0 - geometry.bzed^2.0) + #geometry.Bzeta = geometry.Bmag*geometry.bzeta + geometry_in.option = get(scan_input, "geometry_option", "constant-helical") + geometry_in.pitch = get(scan_input, "pitch", 1.0) + geometry_in.rhostar = get(scan_input, "rhostar", get_default_rhostar(reference_params)) #println("Info: Bzed is ",geometry.Bzed) #println("Info: Bmag is ",geometry.Bmag) #println("Info: rhostar is ",geometry.rhostar) @@ -529,6 +532,8 @@ function mk_input(scan_input=Dict(); save_inputs_to_txt=false, ignore_MPI=true) else io = devnull end + + geometry = init_magnetic_geometry(geometry_in,z,r) # check input (and initialized coordinate structs) to catch errors/unsupported options check_input(io, output_dir, nstep, dt, r, z, vpa, vperp, composition, @@ -995,15 +1000,12 @@ function load_defaults(n_ion_species, n_neutral_species, electron_physics) nuii = 0.0 collisions = collisions_input(charge_exchange, ionization, constant_ionization_rate, krook_collision_frequency_prefactor,"none", nuii) - Bzed = 1.0 # magnetic field component along z - Bmag = 1.0 # magnetic field strength - bzed = 1.0 # component of b unit vector along z - bzeta = 0.0 # component of b unit vector along zeta - Bzeta = 0.0 # magnetic field component along zeta rhostar = 0.0 #rhostar of ions for ExB drift - geometry = geometry_input(Bzed,Bmag,bzed,bzeta,Bzeta,rhostar) + option = "constant-helical" + pitch = 1.0 + geometry_in = geometry_input(rhostar,option,pitch) - return z, r, vpa, vperp, gyrophase, vz, vr, vzeta, species, composition, drive, evolve_moments, collisions, geometry + return z, r, vpa, vperp, gyrophase, vz, vr, vzeta, species, composition, drive, evolve_moments, collisions, geometry_in end """ diff --git a/src/r_advection.jl b/src/r_advection.jl index dcef106e6..bb18a7edc 100644 --- a/src/r_advection.jl +++ b/src/r_advection.jl @@ -93,10 +93,11 @@ function update_speed_r!(advect, upar, vth, fields, evolve_upar, evolve_ppar, vp error("r_advection is not compatible with evolve_upar or evolve_ppar") end if r.advection.option == "default" && r.n > 1 + Bmag = geometry.Bmag ExBfac = 0.5*geometry.rhostar @inbounds begin @loop_z_vperp_vpa iz ivperp ivpa begin - @views advect.speed[:,ivpa,ivperp,iz] .= ExBfac*fields.Ez[iz,:] + @views @. advect.speed[:,ivpa,ivperp,iz] = ExBfac*fields.Ez[iz,:]/Bmag[iz,:] end end elseif r.advection.option == "default" && r.n == 1 diff --git a/src/velocity_grid_transforms.jl b/src/velocity_grid_transforms.jl index 368ee73c2..ccb86b684 100644 --- a/src/velocity_grid_transforms.jl +++ b/src/velocity_grid_transforms.jl @@ -25,13 +25,15 @@ function vzvrvzeta_to_vpavperp!(f_out,f_in,vz,vr,vzeta,vpa,vperp,gyrophase,z,r,g begin_sn_r_z_region() @loop_sn_r_z isn ir iz begin + bzed = geometry.bzed[iz,ir] + bzeta = geometry.bzeta[iz,ir] @views vzvrvzeta_to_vpavperp_species!(f_out[:,:,iz,ir,isn],f_in[:,:,:,iz,ir,isn], - vz,vr,vzeta,vpa,vperp,gyrophase,geometry) + vz,vr,vzeta,vpa,vperp,gyrophase,bzed,bzeta) end end -function vzvrvzeta_to_vpavperp_species!(f_out,f_in,vz,vr,vzeta,vpa,vperp,gyrophase,geometry) +function vzvrvzeta_to_vpavperp_species!(f_out,f_in,vz,vr,vzeta,vpa,vperp,gyrophase,bzed,bzeta) @boundscheck vz.n == size(f_in, 1) || throw(BoundsError(f_in)) @boundscheck vr.n == size(f_in, 2) || throw(BoundsError(f_in)) @boundscheck vzeta.n == size(f_in, 3) || throw(BoundsError(f_in)) @@ -41,10 +43,7 @@ function vzvrvzeta_to_vpavperp_species!(f_out,f_in,vz,vr,vzeta,vpa,vperp,gyropha pdf_interp = linear_interpolation((vz.grid,vr.grid,vzeta.grid),f_in,extrapolation_bc = 0.0) # pdf_interp( vz_val, vr_val, vzeta_val) is interpolated value of f_in # extrapolation_bc = 0.0 makes pdf_interp = 0.0 for |vx| > vx.L/2 (x = z,r,zeta) - - bzed = geometry.bzed - bzeta = geometry.bzeta - + @loop_vperp_vpa ivperp ivpa begin # for each ivpa, ivperp, compute gyroaverage of f_in # use @@ -78,14 +77,16 @@ function vpavperp_to_vzvrvzeta!(f_out,f_in,vz,vr,vzeta,vpa,vperp,z,r,geometry,co begin_s_r_z_region() @loop_s_r_z is ir iz begin + bzed = geometry.bzed[iz,ir] + bzeta = geometry.bzeta[iz,ir] @views vpavperp_to_vzvrvzeta_species!(f_out[:,:,:,iz,ir,is],f_in[:,:,iz,ir,is], - vz,vr,vzeta,vpa,vperp,geometry) + vz,vr,vzeta,vpa,vperp,bzed,bzeta) end end -function vpavperp_to_vzvrvzeta_species!(f_out,f_in,vz,vr,vzeta,vpa,vperp,geometry) +function vpavperp_to_vzvrvzeta_species!(f_out,f_in,vz,vr,vzeta,vpa,vperp,bzed,bzeta) @boundscheck vz.n == size(f_out, 1) || throw(BoundsError(f_out)) @boundscheck vr.n == size(f_out, 2) || throw(BoundsError(f_out)) @boundscheck vzeta.n == size(f_out, 3) || throw(BoundsError(f_out)) @@ -95,10 +96,6 @@ function vpavperp_to_vzvrvzeta_species!(f_out,f_in,vz,vr,vzeta,vpa,vperp,geometr pdf_interp = linear_interpolation((vpa.grid,vperp.grid),f_in,extrapolation_bc = 0.0) # pdf_interp( vz_val, vr_val, vzeta_val) is interpolated value of f_in # extrapolation_bc = 0.0 makes pdf_interp = 0.0 for |vpa| > vpa.L/2 and vperp > vperp.L - - bzed = geometry.bzed - bzeta = geometry.bzeta - @loop_vzeta_vr_vz ivzeta ivr ivz begin # for each ivzeta, ivr, ivz interpolate f_in onto f_out # use diff --git a/src/velocity_moments.jl b/src/velocity_moments.jl index fc2f2d2ed..c3b874728 100644 --- a/src/velocity_moments.jl +++ b/src/velocity_moments.jl @@ -869,7 +869,7 @@ function update_chodura!(moments,ff,vpa,vperp,z,r,r_spectral,composition,geometr if z.irank == 0 @loop_s_r is ir begin @views moments.charged.chodura_integral_lower[ir,is] = update_chodura_integral_species!(ff[:,:,1,ir,is],dffdr[:,:,1,ir,is], - ff_dummy[:,:,1,ir,is],vpa,vperp,z,r,composition,geometry,z_advect[is].speed[1,:,:,ir],moments.charged.dens[1,ir,is],del_vpa) + ff_dummy[:,:,1,ir,is],vpa,vperp,z,r,composition,geometry,z_advect[is].speed[1,:,:,ir],moments.charged.dens[1,ir,is],del_vpa,1,ir) end else # we do not save this Chodura integral to the output file @loop_s_r is ir begin @@ -879,7 +879,7 @@ function update_chodura!(moments,ff,vpa,vperp,z,r,r_spectral,composition,geometr if z.irank == z.nrank - 1 @loop_s_r is ir begin @views moments.charged.chodura_integral_upper[ir,is] = update_chodura_integral_species!(ff[:,:,end,ir,is],dffdr[:,:,end,ir,is], - ff_dummy[:,:,end,ir,is],vpa,vperp,z,r,composition,geometry,z_advect[is].speed[end,:,:,ir],moments.charged.dens[end,ir,is],del_vpa) + ff_dummy[:,:,end,ir,is],vpa,vperp,z,r,composition,geometry,z_advect[is].speed[end,:,:,ir],moments.charged.dens[end,ir,is],del_vpa,z.n,ir) end else # we do not save this Chodura integral to the output file @loop_s_r is ir begin @@ -902,7 +902,7 @@ Chodura condition to a single species plasma with Z = 1 """ -function update_chodura_integral_species!(ff,dffdr,ff_dummy,vpa,vperp,z,r,composition,geometry,vz,dens,del_vpa) +function update_chodura_integral_species!(ff,dffdr,ff_dummy,vpa,vperp,z,r,composition,geometry,vz,dens,del_vpa,iz,ir) @boundscheck vpa.n == size(ff, 1) || throw(BoundsError(ff)) @boundscheck vperp.n == size(ff, 2) || throw(BoundsError(ff)) @boundscheck vpa.n == size(dffdr, 1) || throw(BoundsError(dffdr)) @@ -915,7 +915,7 @@ function update_chodura_integral_species!(ff,dffdr,ff_dummy,vpa,vperp,z,r,compos # we are more than a vpa mimimum grid spacing away from # the vz(vpa,r) = 0 velocity boundary if abs(vz[ivpa,ivperp]) > 0.5*del_vpa - ff_dummy[ivpa,ivperp] = (ff[ivpa,ivperp]*bzed^2/(vz[ivpa,ivperp]^2) + + ff_dummy[ivpa,ivperp] = (ff[ivpa,ivperp]*bzed[iz,ir]^2/(vz[ivpa,ivperp]^2) + geometry.rhostar*dffdr[ivpa,ivperp]/vz[ivpa,ivperp]) else ff_dummy[ivpa,ivperp] = 0.0 diff --git a/src/vpa_advection.jl b/src/vpa_advection.jl index c6dab7fb5..87aafc1d9 100644 --- a/src/vpa_advection.jl +++ b/src/vpa_advection.jl @@ -85,7 +85,7 @@ function update_speed_default!(advect, fields, fvec, moments, vpa, z, r, composi @inbounds @fastmath begin @loop_s_r_z_vperp_vpa is ir iz ivperp ivpa begin # bzed = B_z/B - advect[is].speed[ivpa,ivperp,iz,ir] = 0.5*bzed*fields.Ez[iz,ir] + advect[is].speed[ivpa,ivperp,iz,ir] = 0.5*bzed[iz,ir]*fields.Ez[iz,ir] end end end diff --git a/src/z_advection.jl b/src/z_advection.jl index f67996009..21a30e1cd 100644 --- a/src/z_advection.jl +++ b/src/z_advection.jl @@ -93,10 +93,11 @@ function update_speed_z!(advect, upar, vth, evolve_upar, evolve_ppar, fields, vp if z.advection.option == "default" # bzed = B_z/B only used for z.advection.option == "default" bzed = geometry.bzed + Bmag = geometry.Bmag ExBfac = -0.5*geometry.rhostar @inbounds begin @loop_r_vperp_vpa ir ivperp ivpa begin - @. @views advect.speed[:,ivpa,ivperp,ir] = vpa.grid[ivpa]*bzed + ExBfac*fields.Er[:,ir] + @. @views advect.speed[:,ivpa,ivperp,ir] = vpa.grid[ivpa]*bzed[:,ir] + ExBfac*fields.Er[:,ir]/Bmag[:,ir] end if evolve_ppar @loop_r_vperp_vpa ir ivperp ivpa begin From 011e5981147992f962f38c5c05bd512be9a9c795 Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Wed, 6 Dec 2023 10:24:21 +0000 Subject: [PATCH 02/62] Added advection of vperp by inhomogeneity of the magnetic field, for use in a non-trivial geometry. Untested. --- src/input_structs.jl | 1 + src/time_advance.jl | 19 ++++++++++++------- src/vperp_advection.jl | 42 ++++++++++++++++++++++++++++++------------ 3 files changed, 43 insertions(+), 19 deletions(-) diff --git a/src/input_structs.jl b/src/input_structs.jl index 7bb2a47c5..0227a0999 100644 --- a/src/input_structs.jl +++ b/src/input_structs.jl @@ -51,6 +51,7 @@ end """ mutable struct advance_info vpa_advection::Bool + vperp_advection::Bool z_advection::Bool r_advection::Bool neutral_z_advection::Bool diff --git a/src/time_advance.jl b/src/time_advance.jl index 109e94ebb..0af0f6f7b 100644 --- a/src/time_advance.jl +++ b/src/time_advance.jl @@ -290,11 +290,12 @@ function setup_time_advance!(pdf, vz, vr, vzeta, vpa, vperp, z, r, vz_spectral, begin_serial_region() vperp_advect = setup_advection(n_ion_species, vperp, vpa, z, r) # initialise the vperp advection speed + # note that z_advect and r_advect are arguments of update_speed_vperp! if vperp.n > 1 begin_serial_region() @serial_region begin for is ∈ 1:n_ion_species - @views update_speed_vperp!(vperp_advect[is], vpa, vperp, z, r) + @views update_speed_vperp!(vperp_advect[is], vpa, vperp, z, r, z_advect[is], r_advect[is], geometry) end end end @@ -453,6 +454,7 @@ function setup_advance_flags(moments, composition, t_input, collisions, vr, vz) # default is not to concurrently advance different operators advance_vpa_advection = false + advance_vperp_advection = false advance_z_advection = false advance_r_advection = false advance_cx_1V = false @@ -484,6 +486,7 @@ function setup_advance_flags(moments, composition, t_input, collisions, if !t_input.split_operators # default for non-split operators is to include both vpa and z advection together advance_vpa_advection = true && vpa.n > 1 && z.n > 1 + advance_vperp_advection = true && vperp.n > 1 && z.n > 1 && r.n > 1 advance_z_advection = true && z.n > 1 advance_r_advection = true && r.n > 1 if collisions.nuii > 0.0 && vperp.n > 1 @@ -585,7 +588,7 @@ function setup_advance_flags(moments, composition, t_input, collisions, manufactured_solns_test = manufactured_solns_input.use_for_advance - return advance_info(advance_vpa_advection, advance_z_advection, advance_r_advection, + return advance_info(advance_vpa_advection, advance_vperp_advection, advance_z_advection, advance_r_advection, advance_neutral_z_advection, advance_neutral_r_advection, advance_neutral_vz_advection, advance_cx, advance_cx_1V, advance_ionization, advance_ionization_1V, @@ -1720,7 +1723,7 @@ function euler_time_advance!(fvec_out, fvec_in, pdf, fields, moments, vpa_spectral, vperp_spectral, r_spectral, z_spectral = spectral_objects.vpa_spectral, spectral_objects.vperp_spectral, spectral_objects.r_spectral, spectral_objects.z_spectral vz_spectral, vr_spectral, vzeta_spectral = spectral_objects.vz_spectral, spectral_objects.vr_spectral, spectral_objects.vzeta_spectral - vpa_advect, r_advect, z_advect = advect_objects.vpa_advect, advect_objects.r_advect, advect_objects.z_advect + vpa_advect, vperp_advect, r_advect, z_advect = advect_objects.vpa_advect, advect_objects.vperp_advect, advect_objects.r_advect, advect_objects.z_advect neutral_z_advect, neutral_r_advect, neutral_vz_advect = advect_objects.neutral_z_advect, advect_objects.neutral_r_advect, advect_objects.neutral_vz_advect if advance.external_source @@ -1750,10 +1753,12 @@ function euler_time_advance!(fvec_out, fvec_in, pdf, fields, moments, r_advection!(fvec_out.pdf, fvec_in, moments, fields, r_advect, r, z, vperp, vpa, dt, r_spectral, composition, geometry, scratch_dummy) end - - #if advance.vperp_advection - # PLACEHOLDER - #end + # vperp_advection requires information about z and r advection + # so call vperp_advection! only after z and r advection routines + if advance.vperp_advection + vperp_advection!(fvec_out.pdf, fvec_in, vperp_advect, r, z, vperp, vpa, + dt, vperp_spectral, composition, z_advect, r_advect, geometry) + end if advance.source_terms source_terms!(fvec_out.pdf, fvec_in, moments, vpa, z, r, dt, z_spectral, diff --git a/src/vperp_advection.jl b/src/vperp_advection.jl index 0fc738923..c3ef31bd1 100644 --- a/src/vperp_advection.jl +++ b/src/vperp_advection.jl @@ -8,28 +8,46 @@ using ..chebyshev: chebyshev_info using ..looping # do a single stage time advance (potentially as part of a multi-stage RK scheme) -function vperp_advection!(f_out, fvec_in, advect, r, z, vperp, vpa, - dt, spectral, composition) +function vperp_advection!(f_out, fvec_in, vperp_advect, r, z, vperp, vpa, + dt, spectral, composition, z_advect, r_advect, geometry) + begin_s_r_z_vpa_region() @loop_s is begin # get the updated speed along the r direction using the current f - @views update_speed_vperp!(advect[is], vpa, vperp, z, r) + @views update_speed_vperp!(vperp_advect[is], vpa, vperp, z, r, z_advect, r_advect, geometry) @loop_r_z_vpa ir iz ivpa begin - @views advance_f_local!(f_out[ivpa,:,iz,ir,is], vperp.scratch, advect[is], ivpa, - r, dt, spectral) + @views advance_f_local!(f_out[ivpa,:,iz,ir,is], fvec_in.pdf[ivpa,:,iz,ir,is], + vperp_advect[is], ivpa, iz, ir, vperp, dt, vperp_spectral) end end end # calculate the advection speed in the vperp-direction at each grid point -function update_speed_vperp!(advect, vpa, vperp, z, r) - @boundscheck z.n == size(advect.speed,3) || throw(BoundsError(advect)) - @boundscheck vperp.n == size(advect.speed,1) || throw(BoundsError(advect)) - @boundscheck vpa.n == size(advect.speed,2) || throw(BoundsError(advect)) - @boundscheck r.n == size(advect.speed,4) || throw(BoundsError(speed)) - if vperp.advection.option == "default" || vperp.advection.option == "constant" +# note that the vperp advection speed depends on the z and r advection speeds +# It is important to ensure that z_advect and r_advect are updated before vperp_advect +function update_speed_vperp!(vperp_advect, vpa, vperp, z, r, z_advect, r_advect, geometry) + @boundscheck z.n == size(vperp_advect.speed,3) || throw(BoundsError(vperp_advect)) + @boundscheck vperp.n == size(vperp_advect.speed,1) || throw(BoundsError(vperp_advect)) + @boundscheck vpa.n == size(vperp_advect.speed,2) || throw(BoundsError(vperp_advect)) + @boundscheck r.n == size(vperp_advect.speed,4) || throw(BoundsError(vperp_speed)) + if vperp.advection.option == "default" + # advection of vperp due to conservation of + # the adiabatic invariant mu = vperp^2 / 2 B + dzdt = vperp.scratch + drdt = vperp.scratch2 + dBdr = geometry.dBdr + dBdz = geometry.dBdz + Bmag = geometry.Bmag @inbounds begin @loop_r_z_vpa ir iz ivpa begin - @views advect.speed[:,ivpa,iz,ir] .= vperp.advection.constant_speed + @. dzdt = z_advect.speed[iz,ivpa,:,ir] + @. drdt = r_advect.speed[ir,ivpa,:,iz] + @. @views vperp_advect.speed[:,ivpa,iz,ir] = (0.5*vperp.grid[:]/Bmag[iz,ir])*(dzdt[:]*dBdz[iz,ir] + drdt[:]*dBdr[iz,ir]) + end + end + elseif vperp.advection.option == "constant" + @inbounds begin + @loop_r_z_vpa ir iz ivpa begin + @views vperp_advect.speed[:,ivpa,iz,ir] .= vperp.advection.constant_speed end end end From d4ecf2f34da12e74f420572a6d959847e6f24a95 Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Wed, 6 Dec 2023 10:59:03 +0000 Subject: [PATCH 03/62] Added magnetic mirror term for standard drift-kinetic option. Not tested. --- src/vpa_advection.jl | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/vpa_advection.jl b/src/vpa_advection.jl index 87aafc1d9..b9e6e7ff2 100644 --- a/src/vpa_advection.jl +++ b/src/vpa_advection.jl @@ -42,8 +42,9 @@ function update_speed_vpa!(advect, fields, fvec, moments, vpa, vperp, z, r, comp @boundscheck composition.n_ion_species == size(advect,1) || throw(BoundsError(advect)) @boundscheck vpa.n == size(advect[1].speed,1) || throw(BoundsError(speed)) if vpa.advection.option == "default" - # dvpa/dt = Ze/m ⋅ E_parallel - update_speed_default!(advect, fields, fvec, moments, vpa, z, r, composition, + # dvpa/dt = Ze/m ⋅ E_parallel - (vperp^2/2B) bz dB/dz + # magnetic mirror term only supported for standard DK implementation + update_speed_default!(advect, fields, fvec, moments, vpa, vperp, z, r, composition, collisions, ion_source_settings, t, geometry) elseif vpa.advection.option == "constant" begin_serial_region() @@ -69,7 +70,7 @@ end """ """ -function update_speed_default!(advect, fields, fvec, moments, vpa, z, r, composition, +function update_speed_default!(advect, fields, fvec, moments, vpa, vperp, z, r, composition, collisions, ion_source_settings, t, geometry) if moments.evolve_ppar && moments.evolve_upar update_speed_n_u_p_evolution!(advect, fvec, moments, vpa, z, r, composition, @@ -82,10 +83,13 @@ function update_speed_default!(advect, fields, fvec, moments, vpa, z, r, composi collisions, ion_source_settings) else bzed = geometry.bzed + dBdz = geometry.dBdz + Bmag = geometry.Bmag @inbounds @fastmath begin @loop_s_r_z_vperp_vpa is ir iz ivperp ivpa begin # bzed = B_z/B - advect[is].speed[ivpa,ivperp,iz,ir] = 0.5*bzed[iz,ir]*fields.Ez[iz,ir] + advect[is].speed[ivpa,ivperp,iz,ir] = (0.5*bzed[iz,ir]*fields.Ez[iz,ir] - + (0.5*vperp.grid[ivperp]^2/Bmag[iz,ir])*bzed[iz,ir]*dBdz[iz,ir]) end end end From 250a324fa0d31e471ee5199aedca57e3ad176a04 Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Wed, 6 Dec 2023 12:40:23 +0000 Subject: [PATCH 04/62] Address issue https://github.com/mabarnes/moment_kinetics/issues/111 by incorporating the true geometric factor in the ExB drift terms. Note that this means that ExB drifts will only be present if bzeta > 0, so the pitch input parameter must be set to less that 1. This changes significantly the usage of the code so far, which assumed that bzeta ~= 1, whilst allowing an input parameter to set bzed. --- src/geo.jl | 7 +++++-- src/r_advection.jl | 6 +++++- src/z_advection.jl | 6 +++++- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/geo.jl b/src/geo.jl index c1bc4169f..8f12407f0 100644 --- a/src/geo.jl +++ b/src/geo.jl @@ -44,7 +44,8 @@ bzeta::Array{mk_float,2} dBdz::Array{mk_float,2} # d Bmag d r dBdr::Array{mk_float,2} - +# jacobian = grad r x grad z . grad zeta +jacobian::Array{mk_float,2} end """ @@ -63,6 +64,7 @@ function init_magnetic_geometry(geometry_input_data::geometry_input,z,r) bzeta = allocate_float(nz,nr) dBdr = allocate_float(nz,nr) dBdz = allocate_float(nz,nr) + jacobian = allocate_float(nz,nr) option = geometry_input_data.option rhostar = geometry_input_data.rhostar @@ -77,6 +79,7 @@ function init_magnetic_geometry(geometry_input_data::geometry_input,z,r) Bzeta[iz,ir] = Bmag[iz,ir]*bzeta[iz,ir] dBdr[iz,ir] = 0.0 dBdz[iz,ir] = 0.0 + jacobian[iz,ir] = 1.0 end end else @@ -84,7 +87,7 @@ function init_magnetic_geometry(geometry_input_data::geometry_input,z,r) end geometry = geometric_coefficients(geometry_input_data, rhostar, - Bzed,Bzeta,Bmag,bzed,bzeta,dBdz,dBdr) + Bzed,Bzeta,Bmag,bzed,bzeta,dBdz,dBdr,jacobian) return geometry end diff --git a/src/r_advection.jl b/src/r_advection.jl index bb18a7edc..f9c858aa4 100644 --- a/src/r_advection.jl +++ b/src/r_advection.jl @@ -95,9 +95,13 @@ function update_speed_r!(advect, upar, vth, fields, evolve_upar, evolve_ppar, vp if r.advection.option == "default" && r.n > 1 Bmag = geometry.Bmag ExBfac = 0.5*geometry.rhostar + bzeta = geometry.bzeta + jacobian = geometry.jacobian + geofac = r.scratch @inbounds begin @loop_z_vperp_vpa iz ivperp ivpa begin - @views @. advect.speed[:,ivpa,ivperp,iz] = ExBfac*fields.Ez[iz,:]/Bmag[iz,:] + @. geofac = bzeta[iz,:]*jacobian[iz,:]/Bmag[iz,:] + @views @. advect.speed[:,ivpa,ivperp,iz] = ExBfac*geofac*fields.Ez[iz,:] end end elseif r.advection.option == "default" && r.n == 1 diff --git a/src/z_advection.jl b/src/z_advection.jl index 21a30e1cd..3b70d9ce0 100644 --- a/src/z_advection.jl +++ b/src/z_advection.jl @@ -94,10 +94,14 @@ function update_speed_z!(advect, upar, vth, evolve_upar, evolve_ppar, fields, vp # bzed = B_z/B only used for z.advection.option == "default" bzed = geometry.bzed Bmag = geometry.Bmag + bzeta = geometry.bzeta + jacobian = geometry.jacobian ExBfac = -0.5*geometry.rhostar + geofac = z.scratch @inbounds begin @loop_r_vperp_vpa ir ivperp ivpa begin - @. @views advect.speed[:,ivpa,ivperp,ir] = vpa.grid[ivpa]*bzed[:,ir] + ExBfac*fields.Er[:,ir]/Bmag[:,ir] + @. geofac = bzeta[:,ir]*jacobian[:,ir]/Bmag[:,ir] + @. @views advect.speed[:,ivpa,ivperp,ir] = vpa.grid[ivpa]*bzed[:,ir] + ExBfac*geofac*fields.Er[:,ir] end if evolve_ppar @loop_r_vperp_vpa ir ivperp ivpa begin From 80cca93f388c943b9f740f71dfe1474468a2fd5f Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Thu, 14 Dec 2023 12:42:03 +0000 Subject: [PATCH 05/62] Add a 1D-mirror mock-up of the magnetic field strength, selected with geometry_option='1D-mirror'. Use the parameter DeltaB to set the change in the magnetic field strength from the centre to the edge of the domain. The exact functional form is chosen to be a quartic with dB/dz = 0 at the sheath entrance. --- src/geo.jl | 29 ++++++++++++++++++++++++++++- src/input_structs.jl | 4 +++- src/moment_kinetics_input.jl | 6 ++++-- 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/geo.jl b/src/geo.jl index 8f12407f0..b80972229 100644 --- a/src/geo.jl +++ b/src/geo.jl @@ -68,7 +68,9 @@ function init_magnetic_geometry(geometry_input_data::geometry_input,z,r) option = geometry_input_data.option rhostar = geometry_input_data.rhostar - if option == "constant-helical" + if option == "constant-helical" || option == "default" + # \vec{B} = B ( bz \hat{z} + bzeta \hat{zeta} ) + # with B a constant and \hat{z} x \hat{r} . \hat{zeta} = 1 pitch = geometry_input_data.pitch for ir in 1:nr for iz in 1:nz @@ -82,6 +84,31 @@ function init_magnetic_geometry(geometry_input_data::geometry_input,z,r) jacobian[iz,ir] = 1.0 end end + elseif option == "1D-mirror" + # a 1D configuration for testing mirror and vperp physics + # with \vec{B} = B(z) bz \hat{z} and + # with B = B(z) a specified function + if nr > 1 + input_option_error("$option: You have specified nr > 1 -> set nr = 1", option) + end + DeltaB = geometry_input_data.DeltaB + for ir in 1:nr + for iz in 1:nz + bzed[iz,ir] = 1.0 + bzeta[iz,ir] = 0.0 + # B(z)/Bref = 1 + DeltaB*( 2(2z/L)^2 - (2z/L)^4) + # chosen so that + # B(z)/Bref = 1 + DeltaB at 2z/L = +- 1 + # d B(z)d z = 0 at 2z/L = +- 1 + zfac = 2.0*z.grid[iz]/z.L + Bmag[iz,ir] = 1.0 + DeltaB*( 2.0*zfac^2 - zfac^4) + Bzed[iz,ir] = Bmag[iz,ir]*bzed[iz,ir] + Bzeta[iz,ir] = Bmag[iz,ir]*bzeta[iz,ir] + dBdr[iz,ir] = 0.0 + dBdz[iz,ir] = 4.0*DeltaB*zfac*(1.0 - zfac^2) + jacobian[iz,ir] = 1.0 + end + end else input_option_error("$option", option) end diff --git a/src/input_structs.jl b/src/input_structs.jl index 0227a0999..fd508dc6f 100644 --- a/src/input_structs.jl +++ b/src/input_structs.jl @@ -333,7 +333,9 @@ mutable struct geometry_input # magnetic geometry option option::String # pitch ( = Bzed/Bmag if geometry_option == "constant-helical") - pitch::mk_float + pitch::mk_float + # DeltaB ( = (Bzed(z=L/2) - Bzed(0))/Bref if geometry_option == "1D-mirror") + DeltaB::mk_float end @enum binary_format_type hdf5 netcdf diff --git a/src/moment_kinetics_input.jl b/src/moment_kinetics_input.jl index 3125b4fe9..8526f6fa6 100644 --- a/src/moment_kinetics_input.jl +++ b/src/moment_kinetics_input.jl @@ -106,9 +106,10 @@ function mk_input(scan_input=Dict(); save_inputs_to_txt=false, ignore_MPI=true) #geometry.bzed = geometry.Bzed/geometry.Bmag #geometry.bzeta = sqrt(1.0 - geometry.bzed^2.0) #geometry.Bzeta = geometry.Bmag*geometry.bzeta - geometry_in.option = get(scan_input, "geometry_option", "constant-helical") + geometry_in.option = get(scan_input, "geometry_option", "constant-helical") #"1D-mirror" geometry_in.pitch = get(scan_input, "pitch", 1.0) geometry_in.rhostar = get(scan_input, "rhostar", get_default_rhostar(reference_params)) + geometry_in.DeltaB = get(scan_input, "DeltaB", 1.0) #println("Info: Bzed is ",geometry.Bzed) #println("Info: Bmag is ",geometry.Bmag) #println("Info: rhostar is ",geometry.rhostar) @@ -1003,7 +1004,8 @@ function load_defaults(n_ion_species, n_neutral_species, electron_physics) rhostar = 0.0 #rhostar of ions for ExB drift option = "constant-helical" pitch = 1.0 - geometry_in = geometry_input(rhostar,option,pitch) + DeltaB = 1.0 + geometry_in = geometry_input(rhostar,option,pitch,DeltaB) return z, r, vpa, vperp, gyrophase, vz, vr, vzeta, species, composition, drive, evolve_moments, collisions, geometry_in end From 85aef9479ab5a2b2cf564d1db72839bb6f1dc683 Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Thu, 14 Dec 2023 13:28:32 +0000 Subject: [PATCH 06/62] Bring post_processing.jl up to date. --- src/moment_kinetics_input.jl | 1 + src/post_processing.jl | 24 +++++++++++++----------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/moment_kinetics_input.jl b/src/moment_kinetics_input.jl index 8526f6fa6..c4135a092 100644 --- a/src/moment_kinetics_input.jl +++ b/src/moment_kinetics_input.jl @@ -6,6 +6,7 @@ export mk_input export performance_test #export advective_form export read_input_file +export get_default_rhostar using ..type_definitions: mk_float, mk_int using ..array_allocation: allocate_float diff --git a/src/post_processing.jl b/src/post_processing.jl index 48c1b10ec..4e4b95826 100644 --- a/src/post_processing.jl +++ b/src/post_processing.jl @@ -51,9 +51,11 @@ using ..analysis: analyze_fields_data, analyze_moments_data, analyze_pdf_data, get_unnormalised_f_dzdt_1d, get_unnormalised_f_coords_2d using ..velocity_moments: integrate_over_vspace using ..manufactured_solns: manufactured_solutions, manufactured_electric_fields -using ..moment_kinetics_input: mk_input, get +using ..moment_kinetics_input: mk_input, get, get_default_rhostar using ..input_structs: geometry_input, grid_input, species_composition using ..input_structs: electron_physics_type, boltzmann_electron_response, boltzmann_electron_response_with_simple_sheath +using ..reference_parameters +using ..geo: init_magnetic_geometry using TOML import Base: get @@ -351,18 +353,18 @@ function get_coords_ngrid(scan_input) return z_ngrid, r_ngrid, vpa_ngrid, vperp_ngrid, vz_ngrid, vr_ngrid, vzeta_ngrid end -function get_geometry_and_composition(scan_input,n_ion_species,n_neutral_species) +function get_geometry_and_composition(scan_input,n_ion_species,n_neutral_species,z,r) + reference_params = setup_reference_parameters(scan_input) # set geometry_input # MRH need to get this in way that does not duplicate code # MRH from moment_kinetics_input.jl - Bzed = get(scan_input, "Bzed", 1.0) - Bmag = get(scan_input, "Bmag", 1.0) - bzed = Bzed/Bmag - bzeta = sqrt(1.0 - bzed^2.0) - Bzeta = Bmag*bzeta - rhostar = get(scan_input, "rhostar", 0.0) - geometry = geometry_input(Bzed,Bmag,bzed,bzeta,Bzeta,rhostar) - + option = get(scan_input, "geometry_option", "constant-helical") #"1D-mirror" + pitch = get(scan_input, "pitch", 1.0) + rhostar = get(scan_input, "rhostar", get_default_rhostar(reference_params)) + DeltaB = get(scan_input, "DeltaB", 1.0) + geo_in = geometry_input(rhostar,option,pitch,DeltaB) + geometry = init_magnetic_geometry(geo_in,z,r) + # set composition input # MRH need to get this in way that does not duplicate code # MRH from moment_kinetics_input.jl @@ -786,7 +788,7 @@ function analyze_and_plot_data(prefix...; run_index=nothing) geometry, composition = get_tuple_of_return_values(get_geometry_and_composition, scan_input, - n_ion_species, n_neutral_species) + n_ion_species, n_neutral_species, z, r) # initialise the post-processing input options nwrite_movie, itime_min, itime_max, nwrite_movie_pdfs, itime_min_pdfs, itime_max_pdfs, From 3b7bf896154120d4d7fbbc63d5536de3a168d0fd Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Thu, 14 Dec 2023 13:29:11 +0000 Subject: [PATCH 07/62] Example for using the 1D mirror geometry. --- examples/geometry/1D-mirror.toml | 81 ++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 examples/geometry/1D-mirror.toml diff --git a/examples/geometry/1D-mirror.toml b/examples/geometry/1D-mirror.toml new file mode 100644 index 000000000..31c87cd96 --- /dev/null +++ b/examples/geometry/1D-mirror.toml @@ -0,0 +1,81 @@ +n_ion_species = 1 +n_neutral_species = 0 +boltzmann_electron_response = true +evolve_moments_density = false +evolve_moments_parallel_flow = false +evolve_moments_parallel_pressure = false +evolve_moments_conservation = false +geometry_option="1D-mirror" +DeltaB=10.0 +#geometry_option="constant-helical" +#pitch=1.0 +T_e = 1.0 +T_wall = 1.0 +initial_density1 = 1.0 +initial_temperature1 = 1.0 +z_IC_option1 = "gaussian" +z_IC_density_amplitude1 = 0.001 +z_IC_density_phase1 = 0.0 +z_IC_upar_amplitude1 = 1.0 +z_IC_upar_phase1 = 0.0 +z_IC_temperature_amplitude1 = 0.0 +z_IC_temperature_phase1 = 0.0 +vpa_IC_option1 = "gaussian" +vpa_IC_density_amplitude1 = 1.0 +vpa_IC_density_phase1 = 0.0 +vpa_IC_upar_amplitude1 = 0.0 +vpa_IC_upar_phase1 = 0.0 +vpa_IC_temperature_amplitude1 = 0.0 +vpa_IC_temperature_phase1 = 0.0 +initial_density2 = 1.0 +initial_temperature2 = 1.0 +z_IC_option2 = "gaussian" +z_IC_density_amplitude2 = 0.001 +z_IC_density_phase2 = 0.0 +z_IC_upar_amplitude2 = -1.0 +z_IC_upar_phase2 = 0.0 +z_IC_temperature_amplitude2 = 0.0 +z_IC_temperature_phase2 = 0.0 +vpa_IC_option2 = "gaussian" +vpa_IC_density_amplitude2 = 1.0 +vpa_IC_density_phase2 = 0.0 +vpa_IC_upar_amplitude2 = 0.0 +vpa_IC_upar_phase2 = 0.0 +vpa_IC_temperature_amplitude2 = 0.0 +vpa_IC_temperature_phase2 = 0.0 +charge_exchange_frequency = 0.5 +ionization_frequency = 0.05 +constant_ionization_rate = true +nstep = 10000 +dt = 1.0e-3 +nwrite = 50 +nwrite_dfns = 50 +use_semi_lagrange = false +n_rk_stages = 4 +split_operators = false +r_ngrid = 1 +r_nelement = 1 +z_ngrid = 5 +z_nelement = 16 +z_bc = "wall" +z_discretization = "chebyshev_pseudospectral" +vpa_ngrid = 5 +vpa_nelement = 16 +vpa_L = 6.0 +vpa_bc = "zero" +vpa_discretization = "chebyshev_pseudospectral" +vperp_ngrid = 5 +vperp_nelement = 8 +vperp_L = 3.0 +vperp_bc = "zero" +vperp_discretization = "chebyshev_pseudospectral" +vz_ngrid = 9 +vz_nelement = 64 +vz_L = 18.0 +vz_bc = "both_zero" +vz_discretization = "chebyshev_pseudospectral" + +[numerical_dissipation] +vpa_dissipation_coefficient = 1.0e-3 #1.0e-2 #1.0e-1 +vperp_dissipation_coefficient = 1.0e-3 #1.0e-2 #1.0e-1 +force_minimum_pdf_value = 0.0 From 183c6f9d4e765a70437fb1a58e99544c46fc9ac1 Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Thu, 4 Jan 2024 10:54:11 +0000 Subject: [PATCH 08/62] Catch for DeltaB too negative. --- src/geo.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/geo.jl b/src/geo.jl index b80972229..041e0d84c 100644 --- a/src/geo.jl +++ b/src/geo.jl @@ -92,6 +92,9 @@ function init_magnetic_geometry(geometry_input_data::geometry_input,z,r) input_option_error("$option: You have specified nr > 1 -> set nr = 1", option) end DeltaB = geometry_input_data.DeltaB + if DeltaB < -0.99999999 + input_option_error("$option: You have specified DeltaB < -1 -> set DeltaB > -1", option) + end for ir in 1:nr for iz in 1:nz bzed[iz,ir] = 1.0 From 5c8e587b19435256811a01974c606d80bcdf5f86 Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Thu, 4 Jan 2024 11:12:30 +0000 Subject: [PATCH 09/62] Add struct of symbolic variables for magnetic geometry in the manufactured_solns.jl module. --- src/initial_conditions.jl | 2 +- src/manufactured_solns.jl | 70 ++++++++++++++++++++++++++++++++++++--- src/post_processing.jl | 2 +- src/time_advance.jl | 2 +- 4 files changed, 69 insertions(+), 7 deletions(-) diff --git a/src/initial_conditions.jl b/src/initial_conditions.jl index 496dde004..ce0ce8955 100644 --- a/src/initial_conditions.jl +++ b/src/initial_conditions.jl @@ -148,7 +148,7 @@ function init_pdf_and_moments!(pdf, moments, boundary_distributions, geometry, init_pdf_moments_manufactured_solns!(pdf, moments, vz, vr, vzeta, vpa, vperp, z, r, composition.n_ion_species, composition.n_neutral_species, - geometry, composition, species, + geometry.input, composition, species, manufactured_solns_input) else n_ion_species = composition.n_ion_species diff --git a/src/manufactured_solns.jl b/src/manufactured_solns.jl index 3130bd674..e0a35da3d 100644 --- a/src/manufactured_solns.jl +++ b/src/manufactured_solns.jl @@ -7,6 +7,7 @@ export manufactured_sources export manufactured_electric_fields using ..array_allocation: allocate_shared_float +using ..input_structs: geometry_input using ..input_structs using ..looping using ..type_definitions: mk_float, mk_int @@ -33,6 +34,62 @@ using IfElse fluxconst = 1.0 end + # struct of symbolic functions for geometric coefficients + struct geometric_coefficients_sym{T} + rhostar::mk_float + Bzed::T + Bzeta::T + Bmag::T + bzed::T + bzeta::T + dBdz::T + dBdr::T + jacobian::T + end + + function geometry_sym(geometry_input_data::geometry_input,Lz,Lr,nr) + # define derivative operators + Dr = Differential(r) + Dz = Differential(z) + # compute symbolic geometry functions + option = geometry_input_data.option + rhostar = geometry_input_data.rhostar + if option == "constant-helical" || option == "default" + pitch = geometry_input_data.pitch + bzed = pitch + bzeta = sqrt(1 - bzed^2) + Bmag = 1.0 + Bzed = Bmag*bzed + Bzeta = Bmag*bzeta + dBdr = 0.0 + dBdz = 0.0 + jacobian = 1.0 + elseif option == "1D-mirror" + DeltaB = geometry_input_data.DeltaB + bzed = 1.0 + bzeta = 0.0 + # B(z)/Bref = 1 + DeltaB*( 2(2z/L)^2 - (2z/L)^4) + # chosen so that + # B(z)/Bref = 1 + DeltaB at 2z/L = +- 1 + # d B(z)d z = 0 at 2z/L = +- 1 + zfac = 2.0*z/Lz + Bmag = 1.0 + DeltaB*( 2.0*zfac^2 - zfac^4) + Bzed = Bmag*bzed + Bzeta = Bmag*bzeta + if nr > 1 + dBdr = 0.0 + else + dBdr = Dr(Bmag) + end + dBdz = Dz(Bmag) + jacobian = 1.0 + else + input_option_error("$option", option) + end + geo_sym = geometric_coefficients_sym(rhostar,Bzed,Bzeta,Bmag,bzed,bzeta,dBdz,dBdr,jacobian) + return geo_sym + end + #standard functions for building densities function nplus_sym(Lr,Lz,r_bc,z_bc,epsilon,alpha) if r_bc == "periodic" @@ -376,7 +433,8 @@ using IfElse end function manufactured_solutions(manufactured_solns_input, Lr, Lz, r_bc, z_bc, - geometry, composition, species, nr, nvperp) + geometry_input_data::geometry_input, composition, species, nr, nvperp) + geometry = geometry_sym(geometry_input_data,Lz,Lr,nr) charged_species = species.charged[1] if composition.n_neutral_species > 0 neutral_species = species.neutral[1] @@ -444,9 +502,10 @@ using IfElse end function manufactured_sources(manufactured_solns_input, r_coord, z_coord, vperp_coord, - vpa_coord, vzeta_coord, vr_coord, vz_coord, composition, geometry, collisions, + vpa_coord, vzeta_coord, vr_coord, vz_coord, composition, + geometry_input_data::geometry_input, collisions, num_diss_params, species) - + geometry = geometry_sym(geometry_input_data,z_coord.L,r_coord.L,r_coord.n) charged_species = species.charged[1] if composition.n_neutral_species > 0 neutral_species = species.neutral[1] @@ -489,8 +548,11 @@ using IfElse # get geometric/composition data Bzed = geometry.Bzed + Bzeta = geometry.Bzeta Bmag = geometry.Bmag rhostar = geometry.rhostar + jacobian = geometry.jacobian + ExBgeofac = 0.5*rhostar*Bzeta*jacobian/Bmag^2 #exceptions for cases with missing terms if composition.n_neutral_species > 0 cx_frequency = collisions.charge_exchange @@ -511,7 +573,7 @@ using IfElse charged_species) # the ion source to maintain the manufactured solution - Si = ( Dt(dfni) + ( vpa * (Bzed/Bmag) - 0.5*rhostar*Er ) * Dz(dfni) + ( 0.5*rhostar*Ez*rfac ) * Dr(dfni) + ( 0.5*Ez*Bzed/Bmag ) * Dvpa(dfni) + Si = ( Dt(dfni) + ( vpa * (Bzed/Bmag) - ExBgeofac*Er ) * Dz(dfni) + ( ExBgeofac*Ez*rfac ) * Dr(dfni) + ( 0.5*Ez*Bzed/Bmag ) * Dvpa(dfni) + cx_frequency*( densn*dfni - densi*gav_dfnn ) - ionization_frequency*dense*gav_dfnn) nu_krook = collisions.krook_collision_frequency_prefactor if nu_krook > 0.0 diff --git a/src/post_processing.jl b/src/post_processing.jl index 4e4b95826..3a8817ae9 100644 --- a/src/post_processing.jl +++ b/src/post_processing.jl @@ -1230,7 +1230,7 @@ function analyze_and_plot_data(prefix...; run_index=nothing) manufactured_solns_list = manufactured_solutions(manufactured_solns_input, Lr_in, z_global.L, r_global.bc, - z_global.bc, geometry, + z_global.bc, geometry.input, composition, species, r_global.n, vperp.n) dfni_func = manufactured_solns_list.dfni_func densi_func = manufactured_solns_list.densi_func diff --git a/src/time_advance.jl b/src/time_advance.jl index 0af0f6f7b..1f4bb88fb 100644 --- a/src/time_advance.jl +++ b/src/time_advance.jl @@ -358,7 +358,7 @@ function setup_time_advance!(pdf, vz, vr, vzeta, vpa, vperp, z, r, vz_spectral, if(advance.manufactured_solns_test) manufactured_source_list = manufactured_sources(manufactured_solns_input, r, z, vperp, vpa, vzeta, vr, vz, - composition, geometry, collisions, + composition, geometry.input, collisions, num_diss_params, species) else manufactured_source_list = false # dummy Bool to be passed as argument instead of list From 3ce44f344d27359be584d30a2685d9ec4075b553 Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Thu, 4 Jan 2024 12:04:44 +0000 Subject: [PATCH 10/62] Refactor manufactured solutions module to permit tests with magnetic mirror geometry in 1D and magnetic mirror terms. --- src/manufactured_solns.jl | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/src/manufactured_solns.jl b/src/manufactured_solns.jl index e0a35da3d..58f24871b 100644 --- a/src/manufactured_solns.jl +++ b/src/manufactured_solns.jl @@ -35,16 +35,16 @@ using IfElse end # struct of symbolic functions for geometric coefficients - struct geometric_coefficients_sym{T} + struct geometric_coefficients_sym{T1,T2,T3,T4,T5,T6,T7,T8} rhostar::mk_float - Bzed::T - Bzeta::T - Bmag::T - bzed::T - bzeta::T - dBdz::T - dBdr::T - jacobian::T + Bzed::T1 + Bzeta::T2 + Bmag::T3 + bzed::T4 + bzeta::T5 + dBdz::T6 + dBdr::T7 + jacobian::T8 end function geometry_sym(geometry_input_data::geometry_input,Lz,Lr,nr) @@ -77,9 +77,9 @@ using IfElse Bzed = Bmag*bzed Bzeta = Bmag*bzeta if nr > 1 - dBdr = 0.0 - else dBdr = Dr(Bmag) + else + dBdr = 0.0 end dBdz = Dz(Bmag) jacobian = 1.0 @@ -550,6 +550,8 @@ using IfElse Bzed = geometry.Bzed Bzeta = geometry.Bzeta Bmag = geometry.Bmag + dBdz = geometry.dBdz + dBdr = geometry.dBdr rhostar = geometry.rhostar jacobian = geometry.jacobian ExBgeofac = 0.5*rhostar*Bzeta*jacobian/Bmag^2 @@ -572,9 +574,19 @@ using IfElse composition, r_coord.n, manufactured_solns_input, charged_species) + # the ion characteristic velocities + dzdt = vpa * (Bzed/Bmag) - ExBgeofac*Er + drdt = ExBgeofac*Ez*rfac + dvpadt = 0.5*Bzed/Bmag*(Ez - 0.5*((vperp^2)/Bmag)*dBdz) + dvperpdt = (0.5*vperp/Bmag)*(dzdt*dBdz + drdt*dBdr) # the ion source to maintain the manufactured solution - Si = ( Dt(dfni) + ( vpa * (Bzed/Bmag) - ExBgeofac*Er ) * Dz(dfni) + ( ExBgeofac*Ez*rfac ) * Dr(dfni) + ( 0.5*Ez*Bzed/Bmag ) * Dvpa(dfni) - + cx_frequency*( densn*dfni - densi*gav_dfnn ) - ionization_frequency*dense*gav_dfnn) + Si = ( Dt(dfni) + + dzdt * Dz(dfni) + + drdt * Dr(dfni) + + dvpadt * Dvpa(dfni) + + dvperpdt * Dvperp(dfni) + + cx_frequency*( densn*dfni - densi*gav_dfnn ) + - ionization_frequency*dense*gav_dfnn ) nu_krook = collisions.krook_collision_frequency_prefactor if nu_krook > 0.0 Ti_over_Tref = vthi^2 From a27d84bbcbc99541233bf66794210b848eae7e6a Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Thu, 4 Jan 2024 12:05:15 +0000 Subject: [PATCH 11/62] Input file for MMS test with mirror geometry. --- ..._new_nel_r_1_z_16_vpa_16_vperp_8_diss.toml | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 runs/1D-mirror_MMS_new_nel_r_1_z_16_vpa_16_vperp_8_diss.toml diff --git a/runs/1D-mirror_MMS_new_nel_r_1_z_16_vpa_16_vperp_8_diss.toml b/runs/1D-mirror_MMS_new_nel_r_1_z_16_vpa_16_vperp_8_diss.toml new file mode 100644 index 000000000..45d596904 --- /dev/null +++ b/runs/1D-mirror_MMS_new_nel_r_1_z_16_vpa_16_vperp_8_diss.toml @@ -0,0 +1,98 @@ +n_ion_species = 1 +n_neutral_species = 0 +electron_physics = "boltzmann_electron_response" +#electron_physics = "boltzmann_electron_response_with_simple_sheath" +evolve_moments_density = false +evolve_moments_parallel_flow = false +evolve_moments_parallel_pressure = false +evolve_moments_conservation = false +force_Er_zero_at_wall = false #true +geometry_option="1D-mirror" +DeltaB=10.0 +#geometry_option="constant-helical" +#pitch=1.0 +Er_constant = 0.0 +T_e = 1.0 +T_wall = 1.0 +rhostar = 1.0 +initial_density1 = 0.5 +initial_temperature1 = 1.0 +initial_density2 = 0.5 +initial_temperature2 = 1.0 +z_IC_option1 = "sinusoid" +z_IC_density_amplitude1 = 0.001 +z_IC_density_phase1 = 0.0 +z_IC_upar_amplitude1 = 0.0 +z_IC_upar_phase1 = 0.0 +z_IC_temperature_amplitude1 = 0.0 +z_IC_temperature_phase1 = 0.0 +z_IC_option2 = "sinusoid" +z_IC_density_amplitude2 = 0.001 +z_IC_density_phase2 = 0.0 +z_IC_upar_amplitude2 = 0.0 +z_IC_upar_phase2 = 0.0 +z_IC_temperature_amplitude2 = 0.0 +z_IC_temperature_phase2 = 0.0 +charge_exchange_frequency = 0.0 +ionization_frequency = 0.0 +nstep = 2000 +dt = 0.0005 +nwrite = 200 +nwrite_dfns = 200 +use_semi_lagrange = false +n_rk_stages = 4 +split_operators = false +z_ngrid = 17 +z_nelement = 16 +z_nelement_local = 16 +z_bc = "wall" +z_discretization = "chebyshev_pseudospectral" +r_ngrid = 1 +r_nelement = 1 +r_nelement_local = 1 +r_bc = "periodic" +r_discretization = "chebyshev_pseudospectral" +vpa_ngrid = 17 +vpa_nelement = 16 +vpa_L = 12.0 +vpa_bc = "zero" +vpa_discretization = "chebyshev_pseudospectral" +vperp_ngrid = 17 +vperp_nelement = 8 +vperp_L = 6.0 +#vperp_discretization = "finite_difference" +vperp_discretization = "chebyshev_pseudospectral" +vperp_bc = "zero" + +vz_ngrid = 17 +vz_nelement = 4 +vz_L = 12.0 +vz_bc = "periodic" +vz_discretization = "chebyshev_pseudospectral" + +vr_ngrid = 17 +vr_nelement = 4 +vr_L = 12.0 +vr_bc = "periodic" +vr_discretization = "chebyshev_pseudospectral" + +vzeta_ngrid = 17 +vzeta_nelement = 4 +vzeta_L = 12.0 +vzeta_bc = "periodic" +vzeta_discretization = "chebyshev_pseudospectral" + +[manufactured_solns] + use_for_advance=true + use_for_init=true + # constant to be used to control Ez divergence in MMS tests + epsilon_offset=0.1 + # bool to control if dfni is a function of vpa or vpabar in MMS test + use_vpabar_in_mms_dfni=true + alpha_switch=1.0 + type="default" +[numerical_dissipation] +vpa_dissipation_coefficient = 0.001 +vperp_dissipation_coefficient = 0.001 +#z_dissipation_coefficient = 0.1 +r_dissipation_coefficient = 0.0 From a3331d592dc7f11d597b98618f4392e882d532ad Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Thu, 4 Jan 2024 14:05:14 +0000 Subject: [PATCH 12/62] Parentheses for clarity. --- src/manufactured_solns.jl | 2 +- src/vpa_advection.jl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/manufactured_solns.jl b/src/manufactured_solns.jl index 58f24871b..bb3a552e7 100644 --- a/src/manufactured_solns.jl +++ b/src/manufactured_solns.jl @@ -577,7 +577,7 @@ using IfElse # the ion characteristic velocities dzdt = vpa * (Bzed/Bmag) - ExBgeofac*Er drdt = ExBgeofac*Ez*rfac - dvpadt = 0.5*Bzed/Bmag*(Ez - 0.5*((vperp^2)/Bmag)*dBdz) + dvpadt = 0.5*(Bzed/Bmag)*(Ez - 0.5*((vperp^2)/Bmag)*dBdz) dvperpdt = (0.5*vperp/Bmag)*(dzdt*dBdz + drdt*dBdr) # the ion source to maintain the manufactured solution Si = ( Dt(dfni) diff --git a/src/vpa_advection.jl b/src/vpa_advection.jl index b9e6e7ff2..30728a1f6 100644 --- a/src/vpa_advection.jl +++ b/src/vpa_advection.jl @@ -89,7 +89,7 @@ function update_speed_default!(advect, fields, fvec, moments, vpa, vperp, z, r, @loop_s_r_z_vperp_vpa is ir iz ivperp ivpa begin # bzed = B_z/B advect[is].speed[ivpa,ivperp,iz,ir] = (0.5*bzed[iz,ir]*fields.Ez[iz,ir] - - (0.5*vperp.grid[ivperp]^2/Bmag[iz,ir])*bzed[iz,ir]*dBdz[iz,ir]) + (0.5*(vperp.grid[ivperp]^2)/Bmag[iz,ir])*bzed[iz,ir]*dBdz[iz,ir]) end end end From cc3e8372225dfccc8d97bdb33e4868b13c70bb4f Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Thu, 4 Jan 2024 14:27:09 +0000 Subject: [PATCH 13/62] Correct factor of 2 error in dvpadt. --- src/manufactured_solns.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/manufactured_solns.jl b/src/manufactured_solns.jl index bb3a552e7..8c8e244b2 100644 --- a/src/manufactured_solns.jl +++ b/src/manufactured_solns.jl @@ -577,7 +577,7 @@ using IfElse # the ion characteristic velocities dzdt = vpa * (Bzed/Bmag) - ExBgeofac*Er drdt = ExBgeofac*Ez*rfac - dvpadt = 0.5*(Bzed/Bmag)*(Ez - 0.5*((vperp^2)/Bmag)*dBdz) + dvpadt = 0.5*(Bzed/Bmag)*(Ez - ((vperp^2)/Bmag)*dBdz) dvperpdt = (0.5*vperp/Bmag)*(dzdt*dBdz + drdt*dBdr) # the ion source to maintain the manufactured solution Si = ( Dt(dfni) From c689137234ab2f96a2066e7512605b2717729d3a Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Thu, 4 Jan 2024 16:41:27 +0000 Subject: [PATCH 14/62] Check of the manufactured solutions geometry and correction to magnetic field strength derivative. --- src/geo.jl | 2 +- src/manufactured_solns.jl | 23 +++++++++++++++++++++-- src/post_processing.jl | 38 +++++++++++++++++++++++++++++++++++++- 3 files changed, 59 insertions(+), 4 deletions(-) diff --git a/src/geo.jl b/src/geo.jl index 041e0d84c..1299c36cd 100644 --- a/src/geo.jl +++ b/src/geo.jl @@ -108,7 +108,7 @@ function init_magnetic_geometry(geometry_input_data::geometry_input,z,r) Bzed[iz,ir] = Bmag[iz,ir]*bzed[iz,ir] Bzeta[iz,ir] = Bmag[iz,ir]*bzeta[iz,ir] dBdr[iz,ir] = 0.0 - dBdz[iz,ir] = 4.0*DeltaB*zfac*(1.0 - zfac^2) + dBdz[iz,ir] = (2.0/z.L)*4.0*DeltaB*zfac*(1.0 - zfac^2) jacobian[iz,ir] = 1.0 end end diff --git a/src/manufactured_solns.jl b/src/manufactured_solns.jl index 8c8e244b2..a7327f1ec 100644 --- a/src/manufactured_solns.jl +++ b/src/manufactured_solns.jl @@ -5,6 +5,7 @@ module manufactured_solns export manufactured_solutions export manufactured_sources export manufactured_electric_fields +export manufactured_geometry using ..array_allocation: allocate_shared_float using ..input_structs: geometry_input @@ -77,11 +78,11 @@ using IfElse Bzed = Bmag*bzed Bzeta = Bmag*bzeta if nr > 1 - dBdr = Dr(Bmag) + dBdr = expand_derivatives(Dr(Bmag)) else dBdr = 0.0 end - dBdz = Dz(Bmag) + dBdz = expand_derivatives(Dz(Bmag)) jacobian = 1.0 else input_option_error("$option", option) @@ -501,6 +502,24 @@ using IfElse return manufactured_E_fields end + function manufactured_geometry(geometry_input_data::geometry_input,Lz,Lr,nr) + + # calculate the geometry symbolically + geosym = geometry_sym(geometry_input_data,Lz,Lr,nr) + Bmag = geosym.Bmag + bzed = geosym.bzed + dBdz = geosym.dBdz + Bmag_func = build_function(Bmag, z, r, expression=Val{false}) + bzed_func = build_function(bzed, z, r, expression=Val{false}) + dBdz_func = build_function(dBdz, z, r, expression=Val{false}) + + manufactured_geometry = (Bmag_func = Bmag_func, + bzed_func = bzed_func, + dBdz_func = dBdz_func) + + return manufactured_geometry + end + function manufactured_sources(manufactured_solns_input, r_coord, z_coord, vperp_coord, vpa_coord, vzeta_coord, vr_coord, vz_coord, composition, geometry_input_data::geometry_input, collisions, diff --git a/src/post_processing.jl b/src/post_processing.jl index 3a8817ae9..effa0affb 100644 --- a/src/post_processing.jl +++ b/src/post_processing.jl @@ -51,6 +51,7 @@ using ..analysis: analyze_fields_data, analyze_moments_data, analyze_pdf_data, get_unnormalised_f_dzdt_1d, get_unnormalised_f_coords_2d using ..velocity_moments: integrate_over_vspace using ..manufactured_solns: manufactured_solutions, manufactured_electric_fields +using ..manufactured_solns: manufactured_geometry using ..moment_kinetics_input: mk_input, get, get_default_rhostar using ..input_structs: geometry_input, grid_input, species_composition using ..input_structs: electron_physics_type, boltzmann_electron_response, boltzmann_electron_response_with_simple_sheath @@ -1227,7 +1228,7 @@ function analyze_and_plot_data(prefix...; run_index=nothing) else Lr_in = 1.0 end - + check_manufactured_solution_geometry(geometry,z_global,r_global) manufactured_solns_list = manufactured_solutions(manufactured_solns_input, Lr_in, z_global.L, r_global.bc, z_global.bc, geometry.input, @@ -3856,4 +3857,39 @@ function plot_charged_pdf_2D_at_wall(run_name, run_name_label, r_global, z_globa println("done.") end +function check_manufactured_solution_geometry(geometry,z,r) + Lz = z.L + nz = z.n + Lr = r.L + nr = r.n + + Bmag_num = geometry.Bmag + dBdz_num = geometry.dBdz + bzed_num = geometry.bzed + Bmag_sym = copy(Bmag_num) + bzed_sym = copy(bzed_num) + dBdz_sym = copy(dBdz_num) + + manufactured_geometry_list = manufactured_geometry(geometry.input,Lz,Lr,nr) + Bmag_func = manufactured_geometry_list.Bmag_func + bzed_func = manufactured_geometry_list.bzed_func + dBdz_func = manufactured_geometry_list.dBdz_func + for ir in 1:nr + for iz in 1:nz + Bmag_sym[iz,ir] = Bmag_func(z.grid[iz],r.grid[ir]) + bzed_sym[iz,ir] = bzed_func(z.grid[iz],r.grid[ir]) + dBdz_sym[iz,ir] = dBdz_func(z.grid[iz],r.grid[ir]) + end + end + println("Geometry check") + Bmag_err = sqrt(sum((Bmag_sym .- Bmag_num).^2)) + println("Bmag_err: ",Bmag_err) + bzed_err = sqrt(sum((bzed_sym .- bzed_num).^2)) + println("bzed_err: ",bzed_err) + dBdz_err = sqrt(sum((dBdz_sym .- dBdz_num).^2)) + println("dBdz_err: ",dBdz_err) + + return nothing +end + end From 2e0b46947840f2be019551e54fa5fca17e5fab19 Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Mon, 8 Jan 2024 18:08:05 +0000 Subject: [PATCH 15/62] Try to tidy up the implementation by using the adiabatic invariant mu as a shorthand in the mirror term. --- src/manufactured_solns.jl | 4 +++- src/vpa_advection.jl | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/manufactured_solns.jl b/src/manufactured_solns.jl index a7327f1ec..4850e352c 100644 --- a/src/manufactured_solns.jl +++ b/src/manufactured_solns.jl @@ -593,10 +593,12 @@ using IfElse composition, r_coord.n, manufactured_solns_input, charged_species) + # the adiabatic invariant (for compactness) + mu = 0.5*(vperp^2)/Bmag # the ion characteristic velocities dzdt = vpa * (Bzed/Bmag) - ExBgeofac*Er drdt = ExBgeofac*Ez*rfac - dvpadt = 0.5*(Bzed/Bmag)*(Ez - ((vperp^2)/Bmag)*dBdz) + dvpadt = 0.5*(Bzed/Bmag)*Ez - mu*(Bzed/Bmag)*dBdz dvperpdt = (0.5*vperp/Bmag)*(dzdt*dBdz + drdt*dBdr) # the ion source to maintain the manufactured solution Si = ( Dt(dfni) diff --git a/src/vpa_advection.jl b/src/vpa_advection.jl index 30728a1f6..47da74aff 100644 --- a/src/vpa_advection.jl +++ b/src/vpa_advection.jl @@ -87,9 +87,11 @@ function update_speed_default!(advect, fields, fvec, moments, vpa, vperp, z, r, Bmag = geometry.Bmag @inbounds @fastmath begin @loop_s_r_z_vperp_vpa is ir iz ivperp ivpa begin + # mu, the adiabatic invariant + mu = 0.5*(vperp.grid[ivperp]^2)/Bmag[iz,ir] # bzed = B_z/B advect[is].speed[ivpa,ivperp,iz,ir] = (0.5*bzed[iz,ir]*fields.Ez[iz,ir] - - (0.5*(vperp.grid[ivperp]^2)/Bmag[iz,ir])*bzed[iz,ir]*dBdz[iz,ir]) + mu*bzed[iz,ir]*dBdz[iz,ir]) end end end From c6e7401b3b29f2dd4384bd79a8f2bb554bd7660f Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Tue, 9 Jan 2024 13:16:55 +0000 Subject: [PATCH 16/62] speculative @views statments. --- src/vperp_advection.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vperp_advection.jl b/src/vperp_advection.jl index c3ef31bd1..91ae9a404 100644 --- a/src/vperp_advection.jl +++ b/src/vperp_advection.jl @@ -39,8 +39,8 @@ function update_speed_vperp!(vperp_advect, vpa, vperp, z, r, z_advect, r_advect, Bmag = geometry.Bmag @inbounds begin @loop_r_z_vpa ir iz ivpa begin - @. dzdt = z_advect.speed[iz,ivpa,:,ir] - @. drdt = r_advect.speed[ir,ivpa,:,iz] + @. @views dzdt = z_advect.speed[iz,ivpa,:,ir] + @. @views drdt = r_advect.speed[ir,ivpa,:,iz] @. @views vperp_advect.speed[:,ivpa,iz,ir] = (0.5*vperp.grid[:]/Bmag[iz,ir])*(dzdt[:]*dBdz[iz,ir] + drdt[:]*dBdr[iz,ir]) end end From 57b8b1ae09350c494c0149f8fc909754d4ec88a5 Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Tue, 9 Jan 2024 14:51:21 +0000 Subject: [PATCH 17/62] Correct several mistakes in the vperp advection implementation. Primarily, to restrict vperp advection to cases with r.n > 1, after relaxing this constraint in time_advance.jl, the remaining bugs in vperp_advection.jl were fixed. --- src/time_advance.jl | 2 +- src/vperp_advection.jl | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/time_advance.jl b/src/time_advance.jl index 1f4bb88fb..2fdd0851f 100644 --- a/src/time_advance.jl +++ b/src/time_advance.jl @@ -486,7 +486,7 @@ function setup_advance_flags(moments, composition, t_input, collisions, if !t_input.split_operators # default for non-split operators is to include both vpa and z advection together advance_vpa_advection = true && vpa.n > 1 && z.n > 1 - advance_vperp_advection = true && vperp.n > 1 && z.n > 1 && r.n > 1 + advance_vperp_advection = true && vperp.n > 1 && z.n > 1 advance_z_advection = true && z.n > 1 advance_r_advection = true && r.n > 1 if collisions.nuii > 0.0 && vperp.n > 1 diff --git a/src/vperp_advection.jl b/src/vperp_advection.jl index 91ae9a404..16c2697df 100644 --- a/src/vperp_advection.jl +++ b/src/vperp_advection.jl @@ -9,11 +9,11 @@ using ..looping # do a single stage time advance (potentially as part of a multi-stage RK scheme) function vperp_advection!(f_out, fvec_in, vperp_advect, r, z, vperp, vpa, - dt, spectral, composition, z_advect, r_advect, geometry) + dt, vperp_spectral, composition, z_advect, r_advect, geometry) begin_s_r_z_vpa_region() @loop_s is begin # get the updated speed along the r direction using the current f - @views update_speed_vperp!(vperp_advect[is], vpa, vperp, z, r, z_advect, r_advect, geometry) + @views update_speed_vperp!(vperp_advect[is], vpa, vperp, z, r, z_advect[is], r_advect[is], geometry) @loop_r_z_vpa ir iz ivpa begin @views advance_f_local!(f_out[ivpa,:,iz,ir,is], fvec_in.pdf[ivpa,:,iz,ir,is], vperp_advect[is], ivpa, iz, ir, vperp, dt, vperp_spectral) @@ -37,10 +37,14 @@ function update_speed_vperp!(vperp_advect, vpa, vperp, z, r, z_advect, r_advect, dBdr = geometry.dBdr dBdz = geometry.dBdz Bmag = geometry.Bmag + rfac = 0.0 + if r.n > 1 + rfac = 1.0 + end @inbounds begin @loop_r_z_vpa ir iz ivpa begin @. @views dzdt = z_advect.speed[iz,ivpa,:,ir] - @. @views drdt = r_advect.speed[ir,ivpa,:,iz] + @. @views drdt = rfac*r_advect.speed[ir,ivpa,:,iz] @. @views vperp_advect.speed[:,ivpa,iz,ir] = (0.5*vperp.grid[:]/Bmag[iz,ir])*(dzdt[:]*dBdz[iz,ir] + drdt[:]*dBdr[iz,ir]) end end From 868edcc6094b2fe76d28a7686a12c25291fad420 Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Tue, 9 Jan 2024 15:16:36 +0000 Subject: [PATCH 18/62] Safely initialise the advect[is].speed array in the case that the coordinate has coord.n = 1, but the corresponding advect[is].speed array is used in the calculation of another quantity (e.g. r.n = 1 for a 1D mirror example with vperp advection). If this is not done, then NaNs can be introduced by the uninitialised array. --- src/advection.jl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/advection.jl b/src/advection.jl index aad3a0df6..19468d542 100644 --- a/src/advection.jl +++ b/src/advection.jl @@ -64,6 +64,11 @@ function setup_advection_per_species(coords...) adv_fac = allocate_shared_float([coord.n for coord in coords]...) # create array for storing the speed along this coordinate speed = allocate_shared_float([coord.n for coord in coords]...) + # initialise speed to zero so that it can be used safely without + # introducing NaNs (if left uninitialised) when coordinate speeds + # are used but the coordinate has only a single point + # (e.g. dr/dt in dvperp/dt = (vperp/2B)dB/dt, see vperp_advection.jl) + @. speed = 0.0 # return advection_info struct containing necessary arrays return advection_info(rhs, df, speed, adv_fac) end From d338cd7d1b53c5436381899a06c6ab03ace454e2 Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Tue, 9 Jan 2024 15:28:58 +0000 Subject: [PATCH 19/62] Use stricter typing in the geometric_coefficients_sym struct. --- src/manufactured_solns.jl | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/manufactured_solns.jl b/src/manufactured_solns.jl index 4850e352c..fc22a0d1f 100644 --- a/src/manufactured_solns.jl +++ b/src/manufactured_solns.jl @@ -36,16 +36,21 @@ using IfElse end # struct of symbolic functions for geometric coefficients - struct geometric_coefficients_sym{T1,T2,T3,T4,T5,T6,T7,T8} + # Note that we restrict the types of the variables in the struct + # to be either a float or a Symbolics Num type. The Union appears + # to be required to permit geometry options where a symbolic variable + # does not appear in a particular geometric coefficient, because + # that coefficient is a constant. + struct geometric_coefficients_sym{} rhostar::mk_float - Bzed::T1 - Bzeta::T2 - Bmag::T3 - bzed::T4 - bzeta::T5 - dBdz::T6 - dBdr::T7 - jacobian::T8 + Bzed::Union{mk_float,Num} + Bzeta::Union{mk_float,Num} + Bmag::Union{mk_float,Num} + bzed::Union{mk_float,Num} + bzeta::Union{mk_float,Num} + dBdz::Union{mk_float,Num} + dBdr::Union{mk_float,Num} + jacobian::Union{mk_float,Num} end function geometry_sym(geometry_input_data::geometry_input,Lz,Lr,nr) From 073423cd22e6f9876ca1dd6a600a840d28e8806f Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Tue, 9 Jan 2024 15:47:35 +0000 Subject: [PATCH 20/62] Input file showing almost machine precision errors in a manufactured solutions test of a 1D mirror geometry. --- ...MS_new_nel_r_1_z_6_vpa_6_vperp_3_diss.toml | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 runs/1D-mirror_MMS_new_nel_r_1_z_6_vpa_6_vperp_3_diss.toml diff --git a/runs/1D-mirror_MMS_new_nel_r_1_z_6_vpa_6_vperp_3_diss.toml b/runs/1D-mirror_MMS_new_nel_r_1_z_6_vpa_6_vperp_3_diss.toml new file mode 100644 index 000000000..a465d248c --- /dev/null +++ b/runs/1D-mirror_MMS_new_nel_r_1_z_6_vpa_6_vperp_3_diss.toml @@ -0,0 +1,99 @@ +n_ion_species = 1 +n_neutral_species = 0 +electron_physics = "boltzmann_electron_response" +#electron_physics = "boltzmann_electron_response_with_simple_sheath" +evolve_moments_density = false +evolve_moments_parallel_flow = false +evolve_moments_parallel_pressure = false +evolve_moments_conservation = false +force_Er_zero_at_wall = false #true +geometry_option="1D-mirror" +DeltaB=0.5 +#geometry_option="constant-helical" +#pitch=1.0 +Er_constant = 0.0 +T_e = 1.0 +T_wall = 1.0 +rhostar = 1.0 +initial_density1 = 0.5 +initial_temperature1 = 1.0 +initial_density2 = 0.5 +initial_temperature2 = 1.0 +z_IC_option1 = "sinusoid" +z_IC_density_amplitude1 = 0.001 +z_IC_density_phase1 = 0.0 +z_IC_upar_amplitude1 = 0.0 +z_IC_upar_phase1 = 0.0 +z_IC_temperature_amplitude1 = 0.0 +z_IC_temperature_phase1 = 0.0 +z_IC_option2 = "sinusoid" +z_IC_density_amplitude2 = 0.001 +z_IC_density_phase2 = 0.0 +z_IC_upar_amplitude2 = 0.0 +z_IC_upar_phase2 = 0.0 +z_IC_temperature_amplitude2 = 0.0 +z_IC_temperature_phase2 = 0.0 +charge_exchange_frequency = 0.0 +ionization_frequency = 0.0 +nstep = 2000 +dt = 0.0005 +nwrite = 200 +nwrite_dfns = 200 +use_semi_lagrange = false +n_rk_stages = 4 +split_operators = false +z_ngrid = 17 +z_nelement = 6 +z_nelement_local = 6 +z_bc = "wall" +z_discretization = "chebyshev_pseudospectral" +r_ngrid = 1 +r_nelement = 1 +r_nelement_local = 1 +r_bc = "periodic" +r_discretization = "chebyshev_pseudospectral" +vpa_ngrid = 17 +vpa_nelement = 6 +vpa_L = 12.0 +vpa_bc = "zero" +vpa_discretization = "chebyshev_pseudospectral" +vperp_ngrid = 17 +vperp_nelement = 3 +vperp_L = 6.0 +#vperp_discretization = "finite_difference" +#vperp_discretization = "chebyshev_pseudospectral" +vperp_discretization = "gausslegendre_pseudospectral" +vperp_bc = "zero" + +vz_ngrid = 17 +vz_nelement = 4 +vz_L = 12.0 +vz_bc = "periodic" +vz_discretization = "chebyshev_pseudospectral" + +vr_ngrid = 17 +vr_nelement = 4 +vr_L = 12.0 +vr_bc = "periodic" +vr_discretization = "chebyshev_pseudospectral" + +vzeta_ngrid = 17 +vzeta_nelement = 4 +vzeta_L = 12.0 +vzeta_bc = "periodic" +vzeta_discretization = "chebyshev_pseudospectral" + +[manufactured_solns] + use_for_advance=true + use_for_init=true + # constant to be used to control Ez divergence in MMS tests + epsilon_offset=0.1 + # bool to control if dfni is a function of vpa or vpabar in MMS test + use_vpabar_in_mms_dfni=true + alpha_switch=1.0 + type="default" +[numerical_dissipation] +vpa_dissipation_coefficient = 0.001 +vperp_dissipation_coefficient = 0.001 +#z_dissipation_coefficient = 0.1 +r_dissipation_coefficient = 0.0 From 965dfae1a92fac7db9c3780d7c26950c29232f91 Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Wed, 10 Jan 2024 14:33:35 +0000 Subject: [PATCH 21/62] Initial addition of a geometry option that will in the future support magnetic drifts. Further work required to make options to determine whether or not r is the cylindrical radial coordinate or a local flux-tube radial coordinate. --- src/geo.jl | 52 +++++++++++++++++++++++++++++++++++++++++++++- src/r_advection.jl | 10 ++++++++- src/z_advection.jl | 14 +++++++++++-- 3 files changed, 72 insertions(+), 4 deletions(-) diff --git a/src/geo.jl b/src/geo.jl index 1299c36cd..75a0fdedb 100644 --- a/src/geo.jl +++ b/src/geo.jl @@ -46,6 +46,16 @@ dBdz::Array{mk_float,2} dBdr::Array{mk_float,2} # jacobian = grad r x grad z . grad zeta jacobian::Array{mk_float,2} + +# magnetic drift physics coefficients +# cvdriftr = (b/B) x (b.grad b) . grad r +cvdriftr::Array{mk_float,2} +# cvdriftz = (b/B) x (b.grad b) . grad z +cvdriftz::Array{mk_float,2} +# gbdriftr = (b/B^2) x grad B . grad r +gbdriftr::Array{mk_float,2} +# gbdriftz = (b/B^2) x grad B . grad z +gbdriftz::Array{mk_float,2} end """ @@ -65,6 +75,10 @@ function init_magnetic_geometry(geometry_input_data::geometry_input,z,r) dBdr = allocate_float(nz,nr) dBdz = allocate_float(nz,nr) jacobian = allocate_float(nz,nr) + cvdriftr = allocate_float(nz,nr) + cvdriftz = allocate_float(nz,nr) + gbdriftr = allocate_float(nz,nr) + gbdriftz = allocate_float(nz,nr) option = geometry_input_data.option rhostar = geometry_input_data.rhostar @@ -82,6 +96,11 @@ function init_magnetic_geometry(geometry_input_data::geometry_input,z,r) dBdr[iz,ir] = 0.0 dBdz[iz,ir] = 0.0 jacobian[iz,ir] = 1.0 + + cvdriftr[iz,ir] = 0.0 + cvdriftz[iz,ir] = 0.0 + gbdriftr[iz,ir] = 0.0 + gbdriftz[iz,ir] = 0.0 end end elseif option == "1D-mirror" @@ -110,6 +129,36 @@ function init_magnetic_geometry(geometry_input_data::geometry_input,z,r) dBdr[iz,ir] = 0.0 dBdz[iz,ir] = (2.0/z.L)*4.0*DeltaB*zfac*(1.0 - zfac^2) jacobian[iz,ir] = 1.0 + + cvdriftr[iz,ir] = 0.0 + cvdriftz[iz,ir] = 0.0 + gbdriftr[iz,ir] = 0.0 + gbdriftz[iz,ir] = 0.0 + end + end + elseif option == "low-beta-helix" + # a 2D configuration for testing magnetic drift physics + # with \vec{B} = (B0/r) \hat{zeta} + Bz \hat{z} + # with B0 and Bz constants + pitch = geometry_input_data.pitch + B0 = 1.0 # chose reference field strength to be Bzeta at r = 1 + Bz = pitch*B0 # pitch determines ratio of Bz/B0 at r = 1 + for ir in 1:nr + rr = r.grid[ir] + for iz in 1:nz + Bmag[iz,ir] = sqrt( (B0/rr)^2 + Bz^2 ) + bzed[iz,ir] = Bz/Bmag[iz,ir] + bzeta[iz,ir] = B0/(rr*Bmag[iz,ir]) + Bzed[iz,ir] = bzed[iz,ir]*Bmag[iz,ir] + Bzeta[iz,ir] = bzeta[iz,ir]*Bmag[iz,ir] + dBdz[iz,ir] = 0.0 + dBdr[iz,ir] = -(Bmag[iz,ir]/rr)*bzeta[iz,ir]^2 + jacobian[iz,ir] = 1.0 + + cvdriftr[iz,ir] = 0.0 + cvdriftz[iz,ir] = -(bzeta[iz,ir]/Bmag[iz,ir])*(bzeta[iz,ir]^2)/rr + gbdriftr[iz,ir] = 0.0 + gbdriftz[iz,ir] = cvdriftz[iz,ir] end end else @@ -117,7 +166,8 @@ function init_magnetic_geometry(geometry_input_data::geometry_input,z,r) end geometry = geometric_coefficients(geometry_input_data, rhostar, - Bzed,Bzeta,Bmag,bzed,bzeta,dBdz,dBdr,jacobian) + Bzed,Bzeta,Bmag,bzed,bzeta,dBdz,dBdr,jacobian, + cvdriftr,cvdriftz,gbdriftr,gbdriftz) return geometry end diff --git a/src/r_advection.jl b/src/r_advection.jl index f9c858aa4..d205b04a1 100644 --- a/src/r_advection.jl +++ b/src/r_advection.jl @@ -94,14 +94,22 @@ function update_speed_r!(advect, upar, vth, fields, evolve_upar, evolve_ppar, vp end if r.advection.option == "default" && r.n > 1 Bmag = geometry.Bmag - ExBfac = 0.5*geometry.rhostar + rhostar = geometry.rhostar + ExBfac = 0.5*rhostar bzeta = geometry.bzeta jacobian = geometry.jacobian geofac = r.scratch + cvdriftr = geometry.cvdriftr + gbdriftr = geometry.gbdriftr @inbounds begin @loop_z_vperp_vpa iz ivperp ivpa begin + # ExB drift @. geofac = bzeta[iz,:]*jacobian[iz,:]/Bmag[iz,:] @views @. advect.speed[:,ivpa,ivperp,iz] = ExBfac*geofac*fields.Ez[iz,:] + # magnetic curvature drift + @. @views advect.speed[:,ivpa,ivperp,iz] += rhostar*(vpa.grid[ivpa]^2)*cvdriftr[iz,:] + # magnetic grad B drift + @. @views advect.speed[:,ivpa,ivperp,iz] += 0.5*rhostar*(vperp.grid[ivperp]^2)*gbdriftr[iz,:] end end elseif r.advection.option == "default" && r.n == 1 diff --git a/src/z_advection.jl b/src/z_advection.jl index 3b70d9ce0..f39fc467f 100644 --- a/src/z_advection.jl +++ b/src/z_advection.jl @@ -96,12 +96,22 @@ function update_speed_z!(advect, upar, vth, evolve_upar, evolve_ppar, fields, vp Bmag = geometry.Bmag bzeta = geometry.bzeta jacobian = geometry.jacobian - ExBfac = -0.5*geometry.rhostar + rhostar = geometry.rhostar + ExBfac = -0.5*rhostar geofac = z.scratch + cvdriftz = geometry.cvdriftz + gbdriftz = geometry.gbdriftz @inbounds begin @loop_r_vperp_vpa ir ivperp ivpa begin + # vpa bzed + @. @views advect.speed[:,ivpa,ivperp,ir] = vpa.grid[ivpa]*bzed[:,ir] + # ExB drift @. geofac = bzeta[:,ir]*jacobian[:,ir]/Bmag[:,ir] - @. @views advect.speed[:,ivpa,ivperp,ir] = vpa.grid[ivpa]*bzed[:,ir] + ExBfac*geofac*fields.Er[:,ir] + @. @views advect.speed[:,ivpa,ivperp,ir] += ExBfac*geofac*fields.Er[:,ir] + # magnetic curvature drift + @. @views advect.speed[:,ivpa,ivperp,ir] += rhostar*(vpa.grid[ivpa]^2)*cvdriftz[:,ir] + # magnetic grad B drift + @. @views advect.speed[:,ivpa,ivperp,ir] += 0.5*rhostar*(vperp.grid[ivperp]^2)*gbdriftz[:,ir] end if evolve_ppar @loop_r_vperp_vpa ir ivperp ivpa begin From 89a9aa8bd4e5e4fc5c0478744c2110286200c580 Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Wed, 24 Jan 2024 15:14:23 +0000 Subject: [PATCH 22/62] Bring run_MMS_test.jl to a usable state and significant refactoring to permit interactive usage. --- run_MMS_test.jl | 182 +----------------------- src/makie_post_processing.jl | 2 +- src/plot_MMS_sequence.jl | 267 +++++++++++++++++++++++++++++++---- src/post_processing.jl | 40 ++++-- 4 files changed, 269 insertions(+), 222 deletions(-) diff --git a/run_MMS_test.jl b/run_MMS_test.jl index 50f8f9a14..e7e43ae61 100644 --- a/run_MMS_test.jl +++ b/run_MMS_test.jl @@ -1,183 +1,7 @@ if abspath(PROGRAM_FILE) == @__FILE__ using Pkg Pkg.activate(".") - - import moment_kinetics as mk - - #test_option = "collisional_soundwaves" - #test_option = "collisionless_soundwaves_ions_only" - #test_option = "collisionless_soundwaves" - #test_option = "collisionless_wall-1D-3V-new-dfni-Er" - #test_option = "collisionless_wall-2D-1V-Er-nonzero-at-plate" - #test_option = "collisionless_wall-2D-1V-Er-zero-at-plate" - #test_option = "collisionless_wall-1D-1V" - #test_option = "collisionless_wall-1D-1V-constant-Er" - #test_option = "collisionless_wall-1D-1V-constant-Er-zngrid-5" - #test_option = "collisionless_wall-1D-1V-constant-Er-ngrid-5" - #test_option = "collisionless_wall-1D-1V-constant-Er-ngrid-5-opt" - test_option = "krook_wall-1D-2V" - #test_option = "collisionless_wall-1D-3V" - #test_option = "collisionless_wall-2D-3V" - #test_option = "collisionless_wall-2D-3V-Er-zero-at-plate" - #test_option = "collisionless_biased_wall-2D-3V" - #test_option = "collisionless_wall-1D-3V-with-sheath" - - if test_option == "collisional_soundwaves" - # collisional - path_list = ["runs/2D-sound-wave_cheb_cxiz_nel_r_2_z_2_vpa_2_vperp_2","runs/2D-sound-wave_cheb_cxiz_nel_r_2_z_2_vpa_4_vperp_4", - "runs/2D-sound-wave_cheb_cxiz_nel_r_2_z_2_vpa_8_vperp_8","runs/2D-sound-wave_cheb_cxiz_nel_r_2_z_2_vpa_16_vperp_16"] - scan_type = "velocity_nelement" - scan_name = "2D-sound-wave_cheb_cxiz" - - elseif test_option == "collisionless_soundwaves" - # collisionless - path_list = ["runs/2D-sound-wave_cheb_nel_r_2_z_2_vpa_2_vperp_2","runs/2D-sound-wave_cheb_nel_r_4_z_4_vpa_4_vperp_4",# "runs/2D-sound-wave_cheb_nel_r_6_z_6_vpa_6_vperp_6", - "runs/2D-sound-wave_cheb_nel_r_8_z_8_vpa_8_vperp_8","runs/2D-sound-wave_cheb_nel_r_16_z_16_vpa_16_vperp_16" - ] - scan_type = "nelement" - scan_name = "2D-sound-wave_cheb" - elseif test_option == "collisionless_soundwaves_ions_only" - # collisionless - path_list = ["runs/2D-sound-wave_cheb_ion_only_nel_r_2_z_2_vpa_2_vperp_2","runs/2D-sound-wave_cheb_ion_only_nel_r_4_z_4_vpa_4_vperp_4", "runs/2D-sound-wave_cheb_ion_only_nel_r_8_z_8_vpa_8_vperp_8", -# "runs/2D-sound-wave_cheb_nel_r_8_z_8_vpa_8_vperp_8" -#,"runs/2D-sound-wave_cheb_nel_r_2_z_2_vpa_16_vperp_16" - ] - scan_type = "nelement" - scan_name = "2D-sound-wave_cheb_ions_only" - elseif test_option == "collisionless_wall-2D-3V-Er-zero-at-plate" - # collisionless wall test, no sheath for electrons, no radial coordinate - path_list = ["runs/2D-wall_cheb-with-neutrals_nel_r_2_z_2_vpa_2_vperp_2", - "runs/2D-wall_cheb-with-neutrals_nel_r_4_z_4_vpa_4_vperp_4", - "runs/2D-wall_cheb-with-neutrals_nel_r_6_z_6_vpa_6_vperp_6", - #"runs/2D-wall_cheb-with-neutrals_nel_r_2_z_2_vpa_16_vperp_16" - ] - scan_type = "velocity_nelement" - scan_name = "2D-3V-wall_cheb" - elseif test_option == "collisionless_wall-2D-3V" - # collisionless wall test, no sheath for electrons, no radial coordinate - path_list = ["runs/2D-wall_cheb-with-neutrals_nel_r_2_z_2_vpa_4_vperp_4", - "runs/2D-wall_cheb-with-neutrals_nel_r_2_z_2_vpa_8_vperp_8","runs/2D-wall_cheb-with-neutrals_nel_r_2_z_2_vpa_12_vperp_12", - "runs/2D-wall_cheb-with-neutrals_nel_r_2_z_2_vpa_16_vperp_16" ] - scan_type = "velocity_nelement" - scan_name = "2D-3V-wall_cheb" - elseif test_option == "collisionless_biased_wall-2D-3V" - # collisionless wall test, no sheath for electrons, no radial coordinate - path_list = ["runs/2D-wall-Dirichlet_nel_r_2_z_2_vpa_2","runs/2D-wall-Dirichlet_nel_r_2_z_2_vpa_4", - "runs/2D-wall-Dirichlet_nel_r_2_z_2_vpa_8","runs/2D-wall-Dirichlet_nel_r_2_z_2_vpa_16"] - scan_type = "velocity_nelement" - scan_name = "2D-3V-biased_wall_cheb" - - elseif test_option == "collisionless_wall-1D-3V" - # collisionless wall test, no sheath for electrons, no radial coordinate - path_list = ["runs/2D-wall_cheb-with-neutrals_nel_r_1_z_2_vpa_2_vperp_2","runs/2D-wall_cheb-with-neutrals_nel_r_1_z_2_vpa_4_vperp_4", - "runs/2D-wall_cheb-with-neutrals_nel_r_1_z_2_vpa_8_vperp_8",#"runs/2D-wall_cheb-with-neutrals_nel_r_1_z_2_vpa_12_vperp_12", - "runs/2D-wall_cheb-with-neutrals_nel_r_1_z_2_vpa_16_vperp_16"#,"runs/2D-wall_cheb-with-neutrals_nel_r_1_z_2_vpa_24_vperp_24" - ] - scan_type = "velocity_nelement" - scan_name = "1D-3V-wall_cheb" - - elseif test_option == "collisionless_wall-1D-3V-updated" - # collisionless wall test, no sheath for electrons, no radial coordinate - path_list = ["runs/2D-wall_cheb-with-neutrals_nel_r_1_z_2_vpa_2_vperp_2","runs/2D-wall_cheb-with-neutrals_nel_r_1_z_4_vpa_4_vperp_4", - "runs/2D-wall_cheb-with-neutrals_nel_r_1_z_8_vpa_8_vperp_8",#"runs/2D-wall_cheb-with-neutrals_nel_r_1_z_12_vpa_12_vperp_12", - # "runs/2D-wall_cheb-with-neutrals_nel_r_1_z_16_vpa_16_vperp_16"#,"runs/2D-wall_cheb-with-neutrals_nel_r_1_z_2_vpa_24_vperp_24" - ] - scan_type = "nelement" - scan_name = "1D-3V-wall_cheb-updated" - elseif test_option == "collisionless_wall-1D-3V-new-dfni" - # collisionless wall test, no sheath for electrons, no radial coordinate - path_list = ["runs/2D-wall_cheb-new-MMS-dfni-ngrid-9_nel_r_1_z_2_vpa_2_vperp_2", - "runs/2D-wall_cheb-new-MMS-dfni-ngrid-9_nel_r_1_z_4_vpa_4_vperp_4", - "runs/2D-wall_cheb-new-MMS-dfni-ngrid-9_nel_r_1_z_8_vpa_8_vperp_8", - "runs/2D-wall_cheb-new-MMS-dfni-ngrid-9_nel_r_1_z_16_vpa_16_vperp_16", - "runs/2D-wall_cheb-new-MMS-dfni-ngrid-9_nel_r_1_z_32_vpa_32_vperp_32" - ] - scan_type = "nelement" - scan_name = "1D-3V-wall_cheb-new-dfni" - elseif test_option == "collisionless_wall-1D-3V-new-dfni-Er" - # collisionless wall test, no sheath for electrons, no radial coordinate - path_list = ["runs/2D-wall_cheb-new-MMS-dfni-Er-ngrid-9_nel_r_1_z_2_vpa_2_vperp_2", - "runs/2D-wall_cheb-new-MMS-dfni-Er-ngrid-9_nel_r_1_z_4_vpa_4_vperp_4", - "runs/2D-wall_cheb-new-MMS-dfni-Er-ngrid-9_nel_r_1_z_8_vpa_8_vperp_8", - "runs/2D-wall_cheb-new-MMS-dfni-Er-ngrid-9_nel_r_1_z_16_vpa_16_vperp_16", - "runs/2D-wall_cheb-new-MMS-dfni-Er-ngrid-9_nel_r_1_z_32_vpa_32_vperp_32" - ] - scan_type = "nelement" - scan_name = "1D-3V-wall_cheb-new-dfni-Er" - elseif test_option == "collisionless_wall-1D-3V-with-sheath" - # collisionless wall test, no sheath for electrons, no radial coordinate - path_list = ["runs/2D-wall_cheb-with-neutrals-with-sheath_nel_r_1_z_2_vpa_2_vperp_2","runs/2D-wall_cheb-with-neutrals-with-sheath_nel_r_1_z_2_vpa_4_vperp_4", - "runs/2D-wall_cheb-with-neutrals-with-sheath_nel_r_1_z_2_vpa_8_vperp_8",#"runs/2D-wall_cheb-with-neutrals-with-sheath_nel_r_1_z_2_vpa_12_vperp_12", - "runs/2D-wall_cheb-with-neutrals-with-sheath_nel_r_1_z_2_vpa_16_vperp_16"#,"runs/2D-wall_cheb-with-neutrals-with-sheath_nel_r_1_z_2_vpa_24_vperp_24" - ] - scan_type = "velocity_nelement" - scan_name = "1D-3V-wall-sheath_cheb" - elseif test_option == "collisionless_wall-2D-1V-Er-zero-at-plate" - #path_list = ["runs/2D-wall_MMS_nel_r_2_z_2_vpa_16_vperp_1_diss","runs/2D-wall_MMS_nel_r_4_z_4_vpa_16_vperp_1_diss", - # "runs/2D-wall_MMS_nel_r_8_z_8_vpa_16_vperp_1_diss",#"runs/2D-wall_cheb-with-neutrals-with-sheath_nel_r_1_z_2_vpa_12_vperp_12", - # "runs/2D-wall_MMS_nel_r_16_z_16_vpa_16_vperp_1_diss", - # "runs/2D-wall_MMS_nel_r_32_z_32_vpa_16_vperp_1_diss5"#,"runs/2D-wall_cheb-with-neutrals-with-sheath_nel_r_1_z_2_vpa_24_vperp_24" - # ] - #scan_type = "zr_nelement" - path_list = ["runs/2D-wall_MMS_ngrid_5_nel_r_2_z_2_vpa_8_vperp_1_diss","runs/2D-wall_MMS_ngrid_5_nel_r_4_z_4_vpa_16_vperp_1_diss", - "runs/2D-wall_MMS_ngrid_5_nel_r_8_z_8_vpa_32_vperp_1_diss","runs/2D-wall_MMS_ngrid_5_nel_r_16_z_16_vpa_64_vperp_1_diss"] - scan_type = "vpazr_nelement0.25" - scan_name = "2D-1V-wall_cheb" - elseif test_option == "collisionless_wall-2D-1V-Er-nonzero-at-plate" - path_list = ["runs/2D-wall_MMSEr_ngrid_5_nel_r_2_z_2_vpa_8_vperp_1_diss","runs/2D-wall_MMSEr_ngrid_5_nel_r_4_z_4_vpa_16_vperp_1_diss","runs/2D-wall_MMSEr_ngrid_5_nel_r_8_z_8_vpa_32_vperp_1_diss","runs/2D-wall_MMSEr_ngrid_5_nel_r_16_z_16_vpa_64_vperp_1_diss", - ] - #path_list = ["runs/2D-wall_MMSEr_nel_r_2_z_2_vpa_2_vperp_1_diss","runs/2D-wall_MMSEr_nel_r_4_z_4_vpa_4_vperp_1_diss", - # "runs/2D-wall_MMSEr_nel_r_8_z_8_vpa_8_vperp_1_diss","runs/2D-wall_MMSEr_nel_r_16_z_16_vpa_16_vperp_1_diss" - # #"runs/2D-wall_MMSEr_nel_r_32_z_32_vpa_16_vperp_1_diss" - # ] - #path_list = ["runs/2D-wall_MMSEr_nel_r_2_z_2_vpa_16_vperp_1_diss","runs/2D-wall_MMSEr_nel_r_4_z_4_vpa_16_vperp_1_diss", - # "runs/2D-wall_MMSEr_nel_r_8_z_8_vpa_16_vperp_1_diss",#"runs/2D-wall_cheb-with-neutrals-with-sheath_nel_r_1_z_2_vpa_12_vperp_12", - # "runs/2D-wall_MMSEr_nel_r_16_z_16_vpa_16_vperp_1_diss", - # "runs/2D-wall_MMSEr_nel_r_32_z_32_vpa_16_vperp_1_diss"#,"runs/2D-wall_cheb-with-neutrals-with-sheath_nel_r_1_z_2_vpa_24_vperp_24" - # ] - scan_type = "vpazr_nelement0.25" - scan_name = "2D-1V-wall_cheb-nonzero-Er" - elseif test_option == "collisionless_wall-1D-1V-constant-Er-ngrid-5-opt" - # collisionless wall test, no sheath for electrons, no radial coordinate - path_list = ["runs/1D-wall_MMSEr_ngrid_5_nel_r_1_z_8_vpa_32_vperp_1","runs/1D-wall_MMSEr_ngrid_5_nel_r_1_z_16_vpa_64_vperp_1", - "runs/1D-wall_MMSEr_ngrid_5_nel_r_1_z_32_vpa_128_vperp_1","runs/1D-wall_MMSEr_ngrid_5_nel_r_1_z_64_vpa_256_vperp_1" - ] - scan_type = "vpaz_nelement0.25" - scan_name = "1D-1V-wall_cheb-constant-Er-ngrid-5-opt" - elseif test_option == "collisionless_wall-1D-1V-constant-Er-ngrid-5" - # collisionless wall test, no sheath for electrons, no radial coordinate - path_list = ["runs/1D-wall_MMSEr_ngrid_5_nel_r_1_z_8_vpa_8_vperp_1","runs/1D-wall_MMSEr_ngrid_5_nel_r_1_z_16_vpa_16_vperp_1", - "runs/1D-wall_MMSEr_ngrid_5_nel_r_1_z_32_vpa_32_vperp_1","runs/1D-wall_MMSEr_ngrid_5_nel_r_1_z_64_vpa_64_vperp_1" - ] - scan_type = "vpaz_nelement" - scan_name = "1D-1V-wall_cheb-constant-Er-ngrid-5" - elseif test_option == "collisionless_wall-1D-1V-constant-Er-zngrid-5" - # collisionless wall test, no sheath for electrons, no radial coordinate - path_list = ["runs/1D-wall_MMSEr_zngrid_5_nel_r_1_z_8_vpa_2_vperp_1","runs/1D-wall_MMSEr_zngrid_5_nel_r_1_z_16_vpa_4_vperp_1", - "runs/1D-wall_MMSEr_zngrid_5_nel_r_1_z_32_vpa_8_vperp_1","runs/1D-wall_MMSEr_zngrid_5_nel_r_1_z_64_vpa_16_vperp_1" - ] - scan_type = "vpaz_nelement4" - scan_name = "1D-1V-wall_cheb-constant-Er-zngrid-5" - elseif test_option == "collisionless_wall-1D-1V-constant-Er" - # collisionless wall test, no sheath for electrons, no radial coordinate - path_list = ["runs/1D-wall_MMSEr_nel_r_1_z_2_vpa_2_vperp_1","runs/1D-wall_MMSEr_nel_r_1_z_4_vpa_4_vperp_1", - "runs/1D-wall_MMSEr_nel_r_1_z_8_vpa_8_vperp_1","runs/1D-wall_MMSEr_nel_r_1_z_16_vpa_16_vperp_1" - ] - scan_type = "vpaz_nelement" - scan_name = "1D-1V-wall_cheb-constant-Er" - elseif test_option == "collisionless_wall-1D-1V" - # collisionless wall test, no sheath for electrons, no radial coordinate - path_list = ["runs/1D-wall_MMS_nel_r_1_z_2_vpa_2_vperp_1","runs/1D-wall_MMS_nel_r_1_z_4_vpa_4_vperp_1", - "runs/1D-wall_MMS_nel_r_1_z_8_vpa_8_vperp_1","runs/1D-wall_MMS_nel_r_1_z_16_vpa_16_vperp_1" - ] - scan_type = "vpaz_nelement" - scan_name = "1D-1V-wall_cheb" - elseif test_option == "krook_wall-1D-2V" - # Krook wall test, no sheath for electrons, no radial coordinate - path_list = ["runs/1D-wall_MMS_nel_r_1_z_2_vpa_2_vperp_2_krook","runs/1D-wall_MMS_nel_r_1_z_4_vpa_4_vperp_4_krook", - "runs/1D-wall_MMS_nel_r_1_z_8_vpa_8_vperp_8_krook" ] - scan_type = "vpavperpz_nelement" - scan_name = "1D-2V-wall_cheb_krook" - end - mk.plot_MMS_sequence.get_MMS_error_data(path_list,scan_type,scan_name) + import moment_kinetics + using moment_kinetics.plot_MMS_sequence + run_mms_test() end diff --git a/src/makie_post_processing.jl b/src/makie_post_processing.jl index 6cacb3a30..890ed9ccc 100644 --- a/src/makie_post_processing.jl +++ b/src/makie_post_processing.jl @@ -35,7 +35,7 @@ using ..load_data: open_readonly_output_file, get_group, load_block_data, load_species_data, load_time_data using ..initial_conditions: vpagrid_to_dzdt using ..post_processing: calculate_and_write_frequencies, construct_global_zr_coords, - get_geometry_and_composition, read_distributed_zr_data! + read_distributed_zr_data! using ..type_definitions: mk_float, mk_int using ..velocity_moments: integrate_over_vspace, integrate_over_neutral_vspace diff --git a/src/plot_MMS_sequence.jl b/src/plot_MMS_sequence.jl index d11a53c10..f0de15966 100644 --- a/src/plot_MMS_sequence.jl +++ b/src/plot_MMS_sequence.jl @@ -2,7 +2,8 @@ """ module plot_MMS_sequence -export get_MMS_error_data +#export get_MMS_error_data +export run_mms_test # packages using Plots @@ -18,7 +19,7 @@ using ..post_processing: compare_charged_pdf_symbolic_test, compare_fields_symbo using ..post_processing: compare_moments_symbolic_test, compare_neutral_pdf_symbolic_test using ..post_processing: read_distributed_zr_data!, construct_global_zr_coords using ..post_processing: allocate_global_zr_neutral_moments, allocate_global_zr_charged_moments -using ..post_processing: allocate_global_zr_fields, get_geometry_and_composition +using ..post_processing: allocate_global_zr_fields, get_composition using ..post_processing: get_coords_nelement, get_coords_ngrid using ..array_allocation: allocate_float using ..type_definitions: mk_float, mk_int @@ -29,7 +30,9 @@ using ..load_data: load_neutral_pdf_data, load_time_data, load_species_data using ..load_data: load_block_data, load_coordinate_data, load_input using ..velocity_moments: integrate_over_vspace using ..manufactured_solns: manufactured_solutions, manufactured_electric_fields -using ..moment_kinetics_input: mk_input, read_input_file +using ..moment_kinetics_input: mk_input, read_input_file, get_default_rhostar +using ..input_structs: geometry_input +using ..reference_parameters import Base: get @@ -69,12 +72,13 @@ function get_MMS_error_data(path_list,scan_type,scan_name) fid = open_readonly_output_file(run_name,"moments") scan_input = load_input(fid) - # get run-time input/composition/geometry/collisions/species info for convenience - #io_input, evolve_moments, t_input, z, z_spectral, r, r_spectral, vpa, vpa_spectral, - # vperp, vperp_spectral, gyrophase, gyrophase_spectral, vz, vz_spectral, vr, - # vr_spectral, vzeta, vzeta_spectral, composition, species, collisions, geometry, - # drive_input, external_source_settings, num_diss_params, - # manufactured_solns_input = mk_input(scan_input) + input = mk_input(scan_input) + # obtain input options from moment_kinetics_input.jl + # and check input to catch errors + io_input, evolve_moments, t_input, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, + composition, species, collisions, geometry, drive_input, external_source_settings, + num_diss_params, manufactured_solns_input = input + z_nelement, r_nelement, vpa_nelement, vperp_nelement, vz_nelement, vr_nelement, vzeta_nelement = get_coords_nelement(scan_input) z_ngrid, r_ngrid, vpa_ngrid, vperp_ngrid, @@ -133,6 +137,13 @@ function get_MMS_error_data(path_list,scan_type,scan_name) else println("ERROR: scan_type = ",scan_type," requires vpa_nelement = vperp_nelement = z_nelement") end + elseif scan_type == "vpa2vperpz_nelement" + nelement = z_nelement + if nelement == vpa_nelement && nelement == 2*vperp_nelement + nelement_sequence[isim] = nelement + else + println("ERROR: scan_type = ",scan_type," requires vpa_nelement = 2.0*vperp_nelement = z_nelement") + end elseif scan_type == "vpaz_nelement" nelement = z_nelement if nelement == vpa_nelement @@ -191,24 +202,27 @@ function get_MMS_error_data(path_list,scan_type,scan_name) r_global, z_global = construct_global_zr_coords(r, z) #println("z: ",z) #println("r: ",r) - + run_names = tuple(run_name) + nbs = tuple(nblocks) + print(run_names) + iskip = 1 # stride in slice of arrays # fields - read_distributed_zr_data!(phi,"phi",run_name,"moments",nblocks,z.n,r.n) - read_distributed_zr_data!(Ez,"Ez",run_name,"moments",nblocks,z.n,r.n) - read_distributed_zr_data!(Er,"Er",run_name,"moments",nblocks,z.n,r.n) + read_distributed_zr_data!(phi,"phi",run_names,"moments",nbs,z.n,r.n,iskip) + read_distributed_zr_data!(Ez,"Ez",run_names,"moments",nbs,z.n,r.n,iskip) + read_distributed_zr_data!(Er,"Er",run_names,"moments",nbs,z.n,r.n,iskip) # charged particle moments - read_distributed_zr_data!(density,"density",run_name,"moments",nblocks,z.n,r.n) - read_distributed_zr_data!(parallel_flow,"parallel_flow",run_name,"moments",nblocks,z.n,r.n) - read_distributed_zr_data!(parallel_pressure,"parallel_pressure",run_name,"moments",nblocks,z.n,r.n) - read_distributed_zr_data!(parallel_heat_flux,"parallel_heat_flux",run_name,"moments",nblocks,z.n,r.n) - read_distributed_zr_data!(thermal_speed,"thermal_speed",run_name,"moments",nblocks,z.n,r.n) + read_distributed_zr_data!(density,"density",run_names,"moments",nbs,z.n,r.n,iskip) + read_distributed_zr_data!(parallel_flow,"parallel_flow",run_names,"moments",nbs,z.n,r.n,iskip) + read_distributed_zr_data!(parallel_pressure,"parallel_pressure",run_names,"moments",nbs,z.n,r.n,iskip) + read_distributed_zr_data!(parallel_heat_flux,"parallel_heat_flux",run_names,"moments",nbs,z.n,r.n,iskip) + read_distributed_zr_data!(thermal_speed,"thermal_speed",run_names,"moments",nbs,z.n,r.n,iskip) # neutral particle moments if n_neutral_species > 0 - read_distributed_zr_data!(neutral_density,"density_neutral",run_name,"moments",nblocks,z.n,r.n) - read_distributed_zr_data!(neutral_uz,"uz_neutral",run_name,"moments",nblocks,z.n,r.n) - read_distributed_zr_data!(neutral_pz,"pz_neutral",run_name,"moments",nblocks,z.n,r.n) - read_distributed_zr_data!(neutral_qz,"qz_neutral",run_name,"moments",nblocks,z.n,r.n) - read_distributed_zr_data!(neutral_thermal_speed,"thermal_speed_neutral",run_name,"moments",nblocks,z.n,r.n) + read_distributed_zr_data!(neutral_density,"density_neutral",run_names,"moments",nbs,z.n,r.n,iskip) + read_distributed_zr_data!(neutral_uz,"uz_neutral",run_names,"moments",nbs,z.n,r.n,iskip) + read_distributed_zr_data!(neutral_pz,"pz_neutral",run_names,"moments",nbs,z.n,r.n,iskip) + read_distributed_zr_data!(neutral_qz,"qz_neutral",run_names,"moments",nbs,z.n,r.n,iskip) + read_distributed_zr_data!(neutral_thermal_speed,"thermal_speed_neutral",run_names,"moments",nbs,z.n,r.n,iskip) end @@ -220,15 +234,22 @@ function get_MMS_error_data(path_list,scan_type,scan_name) else Lr_in = 1.0 end - geometry, composition = get_geometry_and_composition(scan_input,n_ion_species,n_neutral_species) - - manufactured_solns_list = manufactured_solutions(Lr_in,z.L,r_bc,z_bc,geometry,composition,r.n,vperp.n) + composition = get_composition(scan_input,n_ion_species,n_neutral_species) + + reference_params = setup_reference_parameters(scan_input) + option = get(scan_input, "geometry_option", "constant-helical") #"1D-mirror" + pitch = get(scan_input, "pitch", 1.0) + rhostar = get(scan_input, "rhostar", get_default_rhostar(reference_params)) + DeltaB = get(scan_input, "DeltaB", 1.0) + geo_in = geometry_input(rhostar,option,pitch,DeltaB) + + manufactured_solns_list = manufactured_solutions(manufactured_solns_input,Lr_in,z.L,r_bc,z_bc,geo_in,composition,species,r.n,vperp.n) dfni_func = manufactured_solns_list.dfni_func densi_func = manufactured_solns_list.densi_func dfnn_func = manufactured_solns_list.dfnn_func densn_func = manufactured_solns_list.densn_func - manufactured_E_fields = manufactured_electric_fields(Lr_in,z.L,r_bc,z_bc,composition,r.n) + manufactured_E_fields = manufactured_electric_fields(Lr_in,z.L,r_bc,z_bc,composition,r.n,manufactured_solns_input,species) Er_func = manufactured_E_fields.Er_func Ez_func = manufactured_E_fields.Ez_func phi_func = manufactured_E_fields.phi_func @@ -324,6 +345,8 @@ function get_MMS_error_data(path_list,scan_type,scan_name) xlabel = L"z "*" & "*L"r "*" "*L"N_{element}" elseif scan_type == "vpavperpz_nelement" xlabel = L"N_{element}(z) = N_{element}(v_\perp) = N_{element}(v_{||})" + elseif scan_type == "vpa2vperpz_nelement" + xlabel = L"N_{element}(z) = 2N_{element}(v_\perp) = N_{element}(v_{||})" elseif scan_type == "vpazr_nelement0.25" xlabel = L"N_{element}(z) = N_{element}(r) = N_{element}(v_{||})/4" elseif scan_type == "vpaz_nelement0.25" @@ -466,4 +489,194 @@ function get_MMS_error_data(path_list,scan_type,scan_name) end +function run_mms_test() + #test_option = "collisional_soundwaves" + #test_option = "collisionless_soundwaves_ions_only" + #test_option = "collisionless_soundwaves" + #test_option = "collisionless_wall-1D-3V-new-dfni-Er" + #test_option = "collisionless_wall-2D-1V-Er-nonzero-at-plate" + #test_option = "collisionless_wall-2D-1V-Er-zero-at-plate" + #test_option = "collisionless_wall-1D-1V" + #test_option = "collisionless_wall-1D-1V-constant-Er" + #test_option = "collisionless_wall-1D-1V-constant-Er-zngrid-5" + #test_option = "collisionless_wall-1D-1V-constant-Er-ngrid-5" + #test_option = "collisionless_wall-1D-1V-constant-Er-ngrid-5-opt" + #test_option = "krook_wall-1D-2V" + test_option = "mirror_wall-1D-2V" + #test_option = "collisionless_wall-1D-3V" + #test_option = "collisionless_wall-2D-3V" + #test_option = "collisionless_wall-2D-3V-Er-zero-at-plate" + #test_option = "collisionless_biased_wall-2D-3V" + #test_option = "collisionless_wall-1D-3V-with-sheath" + + if test_option == "collisional_soundwaves" + # collisional + path_list = ["runs/2D-sound-wave_cheb_cxiz_nel_r_2_z_2_vpa_2_vperp_2","runs/2D-sound-wave_cheb_cxiz_nel_r_2_z_2_vpa_4_vperp_4", + "runs/2D-sound-wave_cheb_cxiz_nel_r_2_z_2_vpa_8_vperp_8","runs/2D-sound-wave_cheb_cxiz_nel_r_2_z_2_vpa_16_vperp_16"] + scan_type = "velocity_nelement" + scan_name = "2D-sound-wave_cheb_cxiz" + + elseif test_option == "collisionless_soundwaves" + # collisionless + path_list = ["runs/2D-sound-wave_cheb_nel_r_2_z_2_vpa_2_vperp_2","runs/2D-sound-wave_cheb_nel_r_4_z_4_vpa_4_vperp_4",# "runs/2D-sound-wave_cheb_nel_r_6_z_6_vpa_6_vperp_6", + "runs/2D-sound-wave_cheb_nel_r_8_z_8_vpa_8_vperp_8","runs/2D-sound-wave_cheb_nel_r_16_z_16_vpa_16_vperp_16" + ] + scan_type = "nelement" + scan_name = "2D-sound-wave_cheb" + elseif test_option == "collisionless_soundwaves_ions_only" + # collisionless + path_list = ["runs/2D-sound-wave_cheb_ion_only_nel_r_2_z_2_vpa_2_vperp_2","runs/2D-sound-wave_cheb_ion_only_nel_r_4_z_4_vpa_4_vperp_4", "runs/2D-sound-wave_cheb_ion_only_nel_r_8_z_8_vpa_8_vperp_8", +# "runs/2D-sound-wave_cheb_nel_r_8_z_8_vpa_8_vperp_8" +#,"runs/2D-sound-wave_cheb_nel_r_2_z_2_vpa_16_vperp_16" + ] + scan_type = "nelement" + scan_name = "2D-sound-wave_cheb_ions_only" + elseif test_option == "collisionless_wall-2D-3V-Er-zero-at-plate" + # collisionless wall test, no sheath for electrons, no radial coordinate + path_list = ["runs/2D-wall_cheb-with-neutrals_nel_r_2_z_2_vpa_2_vperp_2", + "runs/2D-wall_cheb-with-neutrals_nel_r_4_z_4_vpa_4_vperp_4", + "runs/2D-wall_cheb-with-neutrals_nel_r_6_z_6_vpa_6_vperp_6", + #"runs/2D-wall_cheb-with-neutrals_nel_r_2_z_2_vpa_16_vperp_16" + ] + scan_type = "velocity_nelement" + scan_name = "2D-3V-wall_cheb" + elseif test_option == "collisionless_wall-2D-3V" + # collisionless wall test, no sheath for electrons, no radial coordinate + path_list = ["runs/2D-wall_cheb-with-neutrals_nel_r_2_z_2_vpa_4_vperp_4", + "runs/2D-wall_cheb-with-neutrals_nel_r_2_z_2_vpa_8_vperp_8","runs/2D-wall_cheb-with-neutrals_nel_r_2_z_2_vpa_12_vperp_12", + "runs/2D-wall_cheb-with-neutrals_nel_r_2_z_2_vpa_16_vperp_16" ] + scan_type = "velocity_nelement" + scan_name = "2D-3V-wall_cheb" + elseif test_option == "collisionless_biased_wall-2D-3V" + # collisionless wall test, no sheath for electrons, no radial coordinate + path_list = ["runs/2D-wall-Dirichlet_nel_r_2_z_2_vpa_2","runs/2D-wall-Dirichlet_nel_r_2_z_2_vpa_4", + "runs/2D-wall-Dirichlet_nel_r_2_z_2_vpa_8","runs/2D-wall-Dirichlet_nel_r_2_z_2_vpa_16"] + scan_type = "velocity_nelement" + scan_name = "2D-3V-biased_wall_cheb" + + elseif test_option == "collisionless_wall-1D-3V" + # collisionless wall test, no sheath for electrons, no radial coordinate + path_list = ["runs/2D-wall_cheb-with-neutrals_nel_r_1_z_2_vpa_2_vperp_2","runs/2D-wall_cheb-with-neutrals_nel_r_1_z_2_vpa_4_vperp_4", + "runs/2D-wall_cheb-with-neutrals_nel_r_1_z_2_vpa_8_vperp_8",#"runs/2D-wall_cheb-with-neutrals_nel_r_1_z_2_vpa_12_vperp_12", + "runs/2D-wall_cheb-with-neutrals_nel_r_1_z_2_vpa_16_vperp_16"#,"runs/2D-wall_cheb-with-neutrals_nel_r_1_z_2_vpa_24_vperp_24" + ] + scan_type = "velocity_nelement" + scan_name = "1D-3V-wall_cheb" + + elseif test_option == "collisionless_wall-1D-3V-updated" + # collisionless wall test, no sheath for electrons, no radial coordinate + path_list = ["runs/2D-wall_cheb-with-neutrals_nel_r_1_z_2_vpa_2_vperp_2","runs/2D-wall_cheb-with-neutrals_nel_r_1_z_4_vpa_4_vperp_4", + "runs/2D-wall_cheb-with-neutrals_nel_r_1_z_8_vpa_8_vperp_8",#"runs/2D-wall_cheb-with-neutrals_nel_r_1_z_12_vpa_12_vperp_12", + # "runs/2D-wall_cheb-with-neutrals_nel_r_1_z_16_vpa_16_vperp_16"#,"runs/2D-wall_cheb-with-neutrals_nel_r_1_z_2_vpa_24_vperp_24" + ] + scan_type = "nelement" + scan_name = "1D-3V-wall_cheb-updated" + elseif test_option == "collisionless_wall-1D-3V-new-dfni" + # collisionless wall test, no sheath for electrons, no radial coordinate + path_list = ["runs/2D-wall_cheb-new-MMS-dfni-ngrid-9_nel_r_1_z_2_vpa_2_vperp_2", + "runs/2D-wall_cheb-new-MMS-dfni-ngrid-9_nel_r_1_z_4_vpa_4_vperp_4", + "runs/2D-wall_cheb-new-MMS-dfni-ngrid-9_nel_r_1_z_8_vpa_8_vperp_8", + "runs/2D-wall_cheb-new-MMS-dfni-ngrid-9_nel_r_1_z_16_vpa_16_vperp_16", + "runs/2D-wall_cheb-new-MMS-dfni-ngrid-9_nel_r_1_z_32_vpa_32_vperp_32" + ] + scan_type = "nelement" + scan_name = "1D-3V-wall_cheb-new-dfni" + elseif test_option == "collisionless_wall-1D-3V-new-dfni-Er" + # collisionless wall test, no sheath for electrons, no radial coordinate + path_list = ["runs/2D-wall_cheb-new-MMS-dfni-Er-ngrid-9_nel_r_1_z_2_vpa_2_vperp_2", + "runs/2D-wall_cheb-new-MMS-dfni-Er-ngrid-9_nel_r_1_z_4_vpa_4_vperp_4", + "runs/2D-wall_cheb-new-MMS-dfni-Er-ngrid-9_nel_r_1_z_8_vpa_8_vperp_8", + "runs/2D-wall_cheb-new-MMS-dfni-Er-ngrid-9_nel_r_1_z_16_vpa_16_vperp_16", + "runs/2D-wall_cheb-new-MMS-dfni-Er-ngrid-9_nel_r_1_z_32_vpa_32_vperp_32" + ] + scan_type = "nelement" + scan_name = "1D-3V-wall_cheb-new-dfni-Er" + elseif test_option == "collisionless_wall-1D-3V-with-sheath" + # collisionless wall test, no sheath for electrons, no radial coordinate + path_list = ["runs/2D-wall_cheb-with-neutrals-with-sheath_nel_r_1_z_2_vpa_2_vperp_2","runs/2D-wall_cheb-with-neutrals-with-sheath_nel_r_1_z_2_vpa_4_vperp_4", + "runs/2D-wall_cheb-with-neutrals-with-sheath_nel_r_1_z_2_vpa_8_vperp_8",#"runs/2D-wall_cheb-with-neutrals-with-sheath_nel_r_1_z_2_vpa_12_vperp_12", + "runs/2D-wall_cheb-with-neutrals-with-sheath_nel_r_1_z_2_vpa_16_vperp_16"#,"runs/2D-wall_cheb-with-neutrals-with-sheath_nel_r_1_z_2_vpa_24_vperp_24" + ] + scan_type = "velocity_nelement" + scan_name = "1D-3V-wall-sheath_cheb" + elseif test_option == "collisionless_wall-2D-1V-Er-zero-at-plate" + #path_list = ["runs/2D-wall_MMS_nel_r_2_z_2_vpa_16_vperp_1_diss","runs/2D-wall_MMS_nel_r_4_z_4_vpa_16_vperp_1_diss", + # "runs/2D-wall_MMS_nel_r_8_z_8_vpa_16_vperp_1_diss",#"runs/2D-wall_cheb-with-neutrals-with-sheath_nel_r_1_z_2_vpa_12_vperp_12", + # "runs/2D-wall_MMS_nel_r_16_z_16_vpa_16_vperp_1_diss", + # "runs/2D-wall_MMS_nel_r_32_z_32_vpa_16_vperp_1_diss5"#,"runs/2D-wall_cheb-with-neutrals-with-sheath_nel_r_1_z_2_vpa_24_vperp_24" + # ] + #scan_type = "zr_nelement" + path_list = ["runs/2D-wall_MMS_ngrid_5_nel_r_2_z_2_vpa_8_vperp_1_diss","runs/2D-wall_MMS_ngrid_5_nel_r_4_z_4_vpa_16_vperp_1_diss", + "runs/2D-wall_MMS_ngrid_5_nel_r_8_z_8_vpa_32_vperp_1_diss","runs/2D-wall_MMS_ngrid_5_nel_r_16_z_16_vpa_64_vperp_1_diss"] + scan_type = "vpazr_nelement0.25" + scan_name = "2D-1V-wall_cheb" + elseif test_option == "collisionless_wall-2D-1V-Er-nonzero-at-plate" + path_list = ["runs/2D-wall_MMSEr_ngrid_5_nel_r_2_z_2_vpa_8_vperp_1_diss","runs/2D-wall_MMSEr_ngrid_5_nel_r_4_z_4_vpa_16_vperp_1_diss","runs/2D-wall_MMSEr_ngrid_5_nel_r_8_z_8_vpa_32_vperp_1_diss","runs/2D-wall_MMSEr_ngrid_5_nel_r_16_z_16_vpa_64_vperp_1_diss", + ] + #path_list = ["runs/2D-wall_MMSEr_nel_r_2_z_2_vpa_2_vperp_1_diss","runs/2D-wall_MMSEr_nel_r_4_z_4_vpa_4_vperp_1_diss", + # "runs/2D-wall_MMSEr_nel_r_8_z_8_vpa_8_vperp_1_diss","runs/2D-wall_MMSEr_nel_r_16_z_16_vpa_16_vperp_1_diss" + # #"runs/2D-wall_MMSEr_nel_r_32_z_32_vpa_16_vperp_1_diss" + # ] + #path_list = ["runs/2D-wall_MMSEr_nel_r_2_z_2_vpa_16_vperp_1_diss","runs/2D-wall_MMSEr_nel_r_4_z_4_vpa_16_vperp_1_diss", + # "runs/2D-wall_MMSEr_nel_r_8_z_8_vpa_16_vperp_1_diss",#"runs/2D-wall_cheb-with-neutrals-with-sheath_nel_r_1_z_2_vpa_12_vperp_12", + # "runs/2D-wall_MMSEr_nel_r_16_z_16_vpa_16_vperp_1_diss", + # "runs/2D-wall_MMSEr_nel_r_32_z_32_vpa_16_vperp_1_diss"#,"runs/2D-wall_cheb-with-neutrals-with-sheath_nel_r_1_z_2_vpa_24_vperp_24" + # ] + scan_type = "vpazr_nelement0.25" + scan_name = "2D-1V-wall_cheb-nonzero-Er" + elseif test_option == "collisionless_wall-1D-1V-constant-Er-ngrid-5-opt" + # collisionless wall test, no sheath for electrons, no radial coordinate + path_list = ["runs/1D-wall_MMSEr_ngrid_5_nel_r_1_z_8_vpa_32_vperp_1","runs/1D-wall_MMSEr_ngrid_5_nel_r_1_z_16_vpa_64_vperp_1", + "runs/1D-wall_MMSEr_ngrid_5_nel_r_1_z_32_vpa_128_vperp_1","runs/1D-wall_MMSEr_ngrid_5_nel_r_1_z_64_vpa_256_vperp_1" + ] + scan_type = "vpaz_nelement0.25" + scan_name = "1D-1V-wall_cheb-constant-Er-ngrid-5-opt" + elseif test_option == "collisionless_wall-1D-1V-constant-Er-ngrid-5" + # collisionless wall test, no sheath for electrons, no radial coordinate + path_list = ["runs/1D-wall_MMSEr_ngrid_5_nel_r_1_z_8_vpa_8_vperp_1","runs/1D-wall_MMSEr_ngrid_5_nel_r_1_z_16_vpa_16_vperp_1", + "runs/1D-wall_MMSEr_ngrid_5_nel_r_1_z_32_vpa_32_vperp_1","runs/1D-wall_MMSEr_ngrid_5_nel_r_1_z_64_vpa_64_vperp_1" + ] + scan_type = "vpaz_nelement" + scan_name = "1D-1V-wall_cheb-constant-Er-ngrid-5" + elseif test_option == "collisionless_wall-1D-1V-constant-Er-zngrid-5" + # collisionless wall test, no sheath for electrons, no radial coordinate + path_list = ["runs/1D-wall_MMSEr_zngrid_5_nel_r_1_z_8_vpa_2_vperp_1","runs/1D-wall_MMSEr_zngrid_5_nel_r_1_z_16_vpa_4_vperp_1", + "runs/1D-wall_MMSEr_zngrid_5_nel_r_1_z_32_vpa_8_vperp_1","runs/1D-wall_MMSEr_zngrid_5_nel_r_1_z_64_vpa_16_vperp_1" + ] + scan_type = "vpaz_nelement4" + scan_name = "1D-1V-wall_cheb-constant-Er-zngrid-5" + elseif test_option == "collisionless_wall-1D-1V-constant-Er" + # collisionless wall test, no sheath for electrons, no radial coordinate + path_list = ["runs/1D-wall_MMSEr_nel_r_1_z_2_vpa_2_vperp_1","runs/1D-wall_MMSEr_nel_r_1_z_4_vpa_4_vperp_1", + "runs/1D-wall_MMSEr_nel_r_1_z_8_vpa_8_vperp_1","runs/1D-wall_MMSEr_nel_r_1_z_16_vpa_16_vperp_1" + ] + scan_type = "vpaz_nelement" + scan_name = "1D-1V-wall_cheb-constant-Er" + elseif test_option == "collisionless_wall-1D-1V" + # collisionless wall test, no sheath for electrons, no radial coordinate + path_list = ["runs/1D-wall_MMS_nel_r_1_z_2_vpa_2_vperp_1","runs/1D-wall_MMS_nel_r_1_z_4_vpa_4_vperp_1", + "runs/1D-wall_MMS_nel_r_1_z_8_vpa_8_vperp_1","runs/1D-wall_MMS_nel_r_1_z_16_vpa_16_vperp_1" + ] + scan_type = "vpaz_nelement" + scan_name = "1D-1V-wall_cheb" + elseif test_option == "krook_wall-1D-2V" + # Krook wall test, no sheath for electrons, no radial coordinate + path_list = ["runs/1D-wall_MMS_nel_r_1_z_2_vpa_2_vperp_2_krook","runs/1D-wall_MMS_nel_r_1_z_4_vpa_4_vperp_4_krook", + "runs/1D-wall_MMS_nel_r_1_z_8_vpa_8_vperp_8_krook" ] + scan_type = "vpavperpz_nelement" + scan_name = "1D-2V-wall_cheb_krook" + elseif test_option == "mirror_wall-1D-2V" + # Krook wall test, no sheath for electrons, no radial coordinate + path_list = ["runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_4_vpa_4_vperp_2_diss", + "runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_8_vpa_8_vperp_4_diss", + "runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_16_vpa_16_vperp_8_diss", + "runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_32_vpa_32_vperp_16_diss",] + scan_type = "vpa2vperpz_nelement" + scan_name = "mirror_wall-1D-2V" + end + print(path_list) + get_MMS_error_data(path_list,scan_type,scan_name) + return nothing +end + end diff --git a/src/post_processing.jl b/src/post_processing.jl index effa0affb..813b609ed 100644 --- a/src/post_processing.jl +++ b/src/post_processing.jl @@ -354,18 +354,9 @@ function get_coords_ngrid(scan_input) return z_ngrid, r_ngrid, vpa_ngrid, vperp_ngrid, vz_ngrid, vr_ngrid, vzeta_ngrid end -function get_geometry_and_composition(scan_input,n_ion_species,n_neutral_species,z,r) +function get_composition(scan_input,n_ion_species,n_neutral_species) reference_params = setup_reference_parameters(scan_input) - # set geometry_input - # MRH need to get this in way that does not duplicate code - # MRH from moment_kinetics_input.jl - option = get(scan_input, "geometry_option", "constant-helical") #"1D-mirror" - pitch = get(scan_input, "pitch", 1.0) - rhostar = get(scan_input, "rhostar", get_default_rhostar(reference_params)) - DeltaB = get(scan_input, "DeltaB", 1.0) - geo_in = geometry_input(rhostar,option,pitch,DeltaB) - geometry = init_magnetic_geometry(geo_in,z,r) - + # set composition input # MRH need to get this in way that does not duplicate code # MRH from moment_kinetics_input.jl @@ -404,7 +395,23 @@ function get_geometry_and_composition(scan_input,n_ion_species,n_neutral_species composition = species_composition(n_species, n_ion_species, n_neutral_species, electron_physics, use_test_neutral_wall_pdf, T_e, T_wall, phi_wall, Er_constant, mn_over_mi, me_over_mi, recycling_fraction, allocate_float(n_species)) - return geometry, composition + return composition + +end + +function get_geometry(scan_input,z,r) + reference_params = setup_reference_parameters(scan_input) + # set geometry_input + # MRH need to get this in way that does not duplicate code + # MRH from moment_kinetics_input.jl + option = get(scan_input, "geometry_option", "constant-helical") #"1D-mirror" + pitch = get(scan_input, "pitch", 1.0) + rhostar = get(scan_input, "rhostar", get_default_rhostar(reference_params)) + DeltaB = get(scan_input, "DeltaB", 1.0) + geo_in = geometry_input(rhostar,option,pitch,DeltaB) + geometry = init_magnetic_geometry(geo_in,z,r) + + return geometry end @@ -787,9 +794,12 @@ function analyze_and_plot_data(prefix...; run_index=nothing) end end - geometry, composition = - get_tuple_of_return_values(get_geometry_and_composition, scan_input, - n_ion_species, n_neutral_species, z, r) + geometry = + get_tuple_of_return_values(get_geometry, scan_input, + z, r) + composition = + get_tuple_of_return_values(get_composition, scan_input, + n_ion_species, n_neutral_species) # initialise the post-processing input options nwrite_movie, itime_min, itime_max, nwrite_movie_pdfs, itime_min_pdfs, itime_max_pdfs, From 7152d22169a73a949d906c39ec2a32197d0e3790 Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Wed, 24 Jan 2024 15:18:47 +0000 Subject: [PATCH 23/62] Input files for Mirror MMS test. --- ...id_9_nel_r_1_z_16_vpa_16_vperp_8_diss.toml | 99 +++++++++++++++++ ...d_9_nel_r_1_z_32_vpa_32_vperp_16_diss.toml | 99 +++++++++++++++++ ...grid_9_nel_r_1_z_4_vpa_4_vperp_2_diss.toml | 100 ++++++++++++++++++ ...d_9_nel_r_1_z_64_vpa_64_vperp_32_diss.toml | 99 +++++++++++++++++ ...grid_9_nel_r_1_z_8_vpa_8_vperp_4_diss.toml | 99 +++++++++++++++++ 5 files changed, 496 insertions(+) create mode 100644 runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_16_vpa_16_vperp_8_diss.toml create mode 100644 runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_32_vpa_32_vperp_16_diss.toml create mode 100644 runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_4_vpa_4_vperp_2_diss.toml create mode 100644 runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_64_vpa_64_vperp_32_diss.toml create mode 100644 runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_8_vpa_8_vperp_4_diss.toml diff --git a/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_16_vpa_16_vperp_8_diss.toml b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_16_vpa_16_vperp_8_diss.toml new file mode 100644 index 000000000..dd0df3fe8 --- /dev/null +++ b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_16_vpa_16_vperp_8_diss.toml @@ -0,0 +1,99 @@ +n_ion_species = 1 +n_neutral_species = 0 +electron_physics = "boltzmann_electron_response" +#electron_physics = "boltzmann_electron_response_with_simple_sheath" +evolve_moments_density = false +evolve_moments_parallel_flow = false +evolve_moments_parallel_pressure = false +evolve_moments_conservation = false +force_Er_zero_at_wall = false #true +geometry_option="1D-mirror" +DeltaB=0.5 +#geometry_option="constant-helical" +#pitch=1.0 +Er_constant = 0.0 +T_e = 1.0 +T_wall = 1.0 +rhostar = 1.0 +initial_density1 = 0.5 +initial_temperature1 = 1.0 +initial_density2 = 0.5 +initial_temperature2 = 1.0 +z_IC_option1 = "sinusoid" +z_IC_density_amplitude1 = 0.001 +z_IC_density_phase1 = 0.0 +z_IC_upar_amplitude1 = 0.0 +z_IC_upar_phase1 = 0.0 +z_IC_temperature_amplitude1 = 0.0 +z_IC_temperature_phase1 = 0.0 +z_IC_option2 = "sinusoid" +z_IC_density_amplitude2 = 0.001 +z_IC_density_phase2 = 0.0 +z_IC_upar_amplitude2 = 0.0 +z_IC_upar_phase2 = 0.0 +z_IC_temperature_amplitude2 = 0.0 +z_IC_temperature_phase2 = 0.0 +charge_exchange_frequency = 0.0 +ionization_frequency = 0.0 +nstep = 2000 +dt = 0.0005 +nwrite = 200 +nwrite_dfns = 200 +use_semi_lagrange = false +n_rk_stages = 4 +split_operators = false +z_ngrid = 9 +z_nelement = 16 +z_nelement_local = 16 +z_bc = "wall" +z_discretization = "chebyshev_pseudospectral" +r_ngrid = 1 +r_nelement = 1 +r_nelement_local = 1 +r_bc = "periodic" +r_discretization = "chebyshev_pseudospectral" +vpa_ngrid = 9 +vpa_nelement = 16 +vpa_L = 12.0 +vpa_bc = "zero" +vpa_discretization = "chebyshev_pseudospectral" +vperp_ngrid = 9 +vperp_nelement = 8 +vperp_L = 6.0 +#vperp_discretization = "finite_difference" +vperp_discretization = "chebyshev_pseudospectral" +#vperp_discretization = "gausslegendre_pseudospectral" +vperp_bc = "zero" + +vz_ngrid = 17 +vz_nelement = 4 +vz_L = 12.0 +vz_bc = "periodic" +vz_discretization = "chebyshev_pseudospectral" + +vr_ngrid = 17 +vr_nelement = 4 +vr_L = 12.0 +vr_bc = "periodic" +vr_discretization = "chebyshev_pseudospectral" + +vzeta_ngrid = 17 +vzeta_nelement = 4 +vzeta_L = 12.0 +vzeta_bc = "periodic" +vzeta_discretization = "chebyshev_pseudospectral" + +[manufactured_solns] + use_for_advance=true + use_for_init=true + # constant to be used to control Ez divergence in MMS tests + epsilon_offset=0.1 + # bool to control if dfni is a function of vpa or vpabar in MMS test + use_vpabar_in_mms_dfni=true + alpha_switch=1.0 + type="default" +[numerical_dissipation] +vpa_dissipation_coefficient = 0.001 +vperp_dissipation_coefficient = 0.0 +#z_dissipation_coefficient = 0.1 +r_dissipation_coefficient = 0.0 diff --git a/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_32_vpa_32_vperp_16_diss.toml b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_32_vpa_32_vperp_16_diss.toml new file mode 100644 index 000000000..1daefaa21 --- /dev/null +++ b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_32_vpa_32_vperp_16_diss.toml @@ -0,0 +1,99 @@ +n_ion_species = 1 +n_neutral_species = 0 +electron_physics = "boltzmann_electron_response" +#electron_physics = "boltzmann_electron_response_with_simple_sheath" +evolve_moments_density = false +evolve_moments_parallel_flow = false +evolve_moments_parallel_pressure = false +evolve_moments_conservation = false +force_Er_zero_at_wall = false #true +geometry_option="1D-mirror" +DeltaB=0.5 +#geometry_option="constant-helical" +#pitch=1.0 +Er_constant = 0.0 +T_e = 1.0 +T_wall = 1.0 +rhostar = 1.0 +initial_density1 = 0.5 +initial_temperature1 = 1.0 +initial_density2 = 0.5 +initial_temperature2 = 1.0 +z_IC_option1 = "sinusoid" +z_IC_density_amplitude1 = 0.001 +z_IC_density_phase1 = 0.0 +z_IC_upar_amplitude1 = 0.0 +z_IC_upar_phase1 = 0.0 +z_IC_temperature_amplitude1 = 0.0 +z_IC_temperature_phase1 = 0.0 +z_IC_option2 = "sinusoid" +z_IC_density_amplitude2 = 0.001 +z_IC_density_phase2 = 0.0 +z_IC_upar_amplitude2 = 0.0 +z_IC_upar_phase2 = 0.0 +z_IC_temperature_amplitude2 = 0.0 +z_IC_temperature_phase2 = 0.0 +charge_exchange_frequency = 0.0 +ionization_frequency = 0.0 +nstep = 2000 +dt = 0.0005 +nwrite = 200 +nwrite_dfns = 200 +use_semi_lagrange = false +n_rk_stages = 4 +split_operators = false +z_ngrid = 9 +z_nelement = 32 +z_nelement_local = 32 +z_bc = "wall" +z_discretization = "chebyshev_pseudospectral" +r_ngrid = 1 +r_nelement = 1 +r_nelement_local = 1 +r_bc = "periodic" +r_discretization = "chebyshev_pseudospectral" +vpa_ngrid = 9 +vpa_nelement = 32 +vpa_L = 12.0 +vpa_bc = "zero" +vpa_discretization = "chebyshev_pseudospectral" +vperp_ngrid = 9 +vperp_nelement = 16 +vperp_L = 6.0 +#vperp_discretization = "finite_difference" +vperp_discretization = "chebyshev_pseudospectral" +#vperp_discretization = "gausslegendre_pseudospectral" +vperp_bc = "zero" + +vz_ngrid = 17 +vz_nelement = 4 +vz_L = 12.0 +vz_bc = "periodic" +vz_discretization = "chebyshev_pseudospectral" + +vr_ngrid = 17 +vr_nelement = 4 +vr_L = 12.0 +vr_bc = "periodic" +vr_discretization = "chebyshev_pseudospectral" + +vzeta_ngrid = 17 +vzeta_nelement = 4 +vzeta_L = 12.0 +vzeta_bc = "periodic" +vzeta_discretization = "chebyshev_pseudospectral" + +[manufactured_solns] + use_for_advance=true + use_for_init=true + # constant to be used to control Ez divergence in MMS tests + epsilon_offset=0.1 + # bool to control if dfni is a function of vpa or vpabar in MMS test + use_vpabar_in_mms_dfni=true + alpha_switch=1.0 + type="default" +[numerical_dissipation] +vpa_dissipation_coefficient = 0.001 +vperp_dissipation_coefficient = 0.0 +#z_dissipation_coefficient = 0.1 +r_dissipation_coefficient = 0.0 diff --git a/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_4_vpa_4_vperp_2_diss.toml b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_4_vpa_4_vperp_2_diss.toml new file mode 100644 index 000000000..96013ee4a --- /dev/null +++ b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_4_vpa_4_vperp_2_diss.toml @@ -0,0 +1,100 @@ +n_ion_species = 1 +n_neutral_species = 0 +electron_physics = "boltzmann_electron_response" +#electron_physics = "boltzmann_electron_response_with_simple_sheath" +evolve_moments_density = false +evolve_moments_parallel_flow = false +evolve_moments_parallel_pressure = false +evolve_moments_conservation = false +force_Er_zero_at_wall = false #true +geometry_option="1D-mirror" +DeltaB=0.5 +#geometry_option="constant-helical" +#pitch=1.0 +Er_constant = 0.0 +T_e = 1.0 +T_wall = 1.0 +rhostar = 1.0 +initial_density1 = 0.5 +initial_temperature1 = 1.0 +initial_density2 = 0.5 +initial_temperature2 = 1.0 +z_IC_option1 = "sinusoid" +z_IC_density_amplitude1 = 0.001 +z_IC_density_phase1 = 0.0 +z_IC_upar_amplitude1 = 0.0 +z_IC_upar_phase1 = 0.0 +z_IC_temperature_amplitude1 = 0.0 +z_IC_temperature_phase1 = 0.0 +z_IC_option2 = "sinusoid" +z_IC_density_amplitude2 = 0.001 +z_IC_density_phase2 = 0.0 +z_IC_upar_amplitude2 = 0.0 +z_IC_upar_phase2 = 0.0 +z_IC_temperature_amplitude2 = 0.0 +z_IC_temperature_phase2 = 0.0 +charge_exchange_frequency = 0.0 +ionization_frequency = 0.0 +nstep = 2000 +dt = 0.0005 +nwrite = 200 +nwrite_dfns = 200 +use_semi_lagrange = false +n_rk_stages = 4 +split_operators = false +z_ngrid = 9 +z_nelement = 4 +z_nelement_local = 4 +z_bc = "wall" +z_discretization = "chebyshev_pseudospectral" +r_ngrid = 1 +r_nelement = 1 +r_nelement_local = 1 +r_bc = "periodic" +r_discretization = "chebyshev_pseudospectral" +vpa_ngrid = 9 +vpa_nelement = 4 +vpa_L = 12.0 +vpa_bc = "zero" +vpa_discretization = "chebyshev_pseudospectral" +vperp_ngrid = 9 +vperp_nelement = 2 +vperp_L = 6.0 +#vperp_discretization = "finite_difference" +vperp_discretization = "chebyshev_pseudospectral" +#vperp_discretization = "gausslegendre_pseudospectral" +#vperp_bc = "none" +vperp_bc = "zero" + +vz_ngrid = 17 +vz_nelement = 4 +vz_L = 12.0 +vz_bc = "periodic" +vz_discretization = "chebyshev_pseudospectral" + +vr_ngrid = 17 +vr_nelement = 4 +vr_L = 12.0 +vr_bc = "periodic" +vr_discretization = "chebyshev_pseudospectral" + +vzeta_ngrid = 17 +vzeta_nelement = 4 +vzeta_L = 12.0 +vzeta_bc = "periodic" +vzeta_discretization = "chebyshev_pseudospectral" + +[manufactured_solns] + use_for_advance=true + use_for_init=true + # constant to be used to control Ez divergence in MMS tests + epsilon_offset=0.1 + # bool to control if dfni is a function of vpa or vpabar in MMS test + use_vpabar_in_mms_dfni=true + alpha_switch=1.0 + type="default" +[numerical_dissipation] +vpa_dissipation_coefficient = 0.001 +vperp_dissipation_coefficient = 0.00 +#z_dissipation_coefficient = 0.1 +r_dissipation_coefficient = 0.0 diff --git a/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_64_vpa_64_vperp_32_diss.toml b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_64_vpa_64_vperp_32_diss.toml new file mode 100644 index 000000000..da3b6cf09 --- /dev/null +++ b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_64_vpa_64_vperp_32_diss.toml @@ -0,0 +1,99 @@ +n_ion_species = 1 +n_neutral_species = 0 +electron_physics = "boltzmann_electron_response" +#electron_physics = "boltzmann_electron_response_with_simple_sheath" +evolve_moments_density = false +evolve_moments_parallel_flow = false +evolve_moments_parallel_pressure = false +evolve_moments_conservation = false +force_Er_zero_at_wall = false #true +geometry_option="1D-mirror" +DeltaB=0.5 +#geometry_option="constant-helical" +#pitch=1.0 +Er_constant = 0.0 +T_e = 1.0 +T_wall = 1.0 +rhostar = 1.0 +initial_density1 = 0.5 +initial_temperature1 = 1.0 +initial_density2 = 0.5 +initial_temperature2 = 1.0 +z_IC_option1 = "sinusoid" +z_IC_density_amplitude1 = 0.001 +z_IC_density_phase1 = 0.0 +z_IC_upar_amplitude1 = 0.0 +z_IC_upar_phase1 = 0.0 +z_IC_temperature_amplitude1 = 0.0 +z_IC_temperature_phase1 = 0.0 +z_IC_option2 = "sinusoid" +z_IC_density_amplitude2 = 0.001 +z_IC_density_phase2 = 0.0 +z_IC_upar_amplitude2 = 0.0 +z_IC_upar_phase2 = 0.0 +z_IC_temperature_amplitude2 = 0.0 +z_IC_temperature_phase2 = 0.0 +charge_exchange_frequency = 0.0 +ionization_frequency = 0.0 +nstep = 2000 +dt = 0.0005 +nwrite = 200 +nwrite_dfns = 200 +use_semi_lagrange = false +n_rk_stages = 4 +split_operators = false +z_ngrid = 9 +z_nelement = 64 +z_nelement_local = 64 +z_bc = "wall" +z_discretization = "chebyshev_pseudospectral" +r_ngrid = 1 +r_nelement = 1 +r_nelement_local = 1 +r_bc = "periodic" +r_discretization = "chebyshev_pseudospectral" +vpa_ngrid = 9 +vpa_nelement = 64 +vpa_L = 12.0 +vpa_bc = "zero" +vpa_discretization = "chebyshev_pseudospectral" +vperp_ngrid = 9 +vperp_nelement = 32 +vperp_L = 6.0 +#vperp_discretization = "finite_difference" +vperp_discretization = "chebyshev_pseudospectral" +#vperp_discretization = "gausslegendre_pseudospectral" +vperp_bc = "zero" + +vz_ngrid = 17 +vz_nelement = 4 +vz_L = 12.0 +vz_bc = "periodic" +vz_discretization = "chebyshev_pseudospectral" + +vr_ngrid = 17 +vr_nelement = 4 +vr_L = 12.0 +vr_bc = "periodic" +vr_discretization = "chebyshev_pseudospectral" + +vzeta_ngrid = 17 +vzeta_nelement = 4 +vzeta_L = 12.0 +vzeta_bc = "periodic" +vzeta_discretization = "chebyshev_pseudospectral" + +[manufactured_solns] + use_for_advance=true + use_for_init=true + # constant to be used to control Ez divergence in MMS tests + epsilon_offset=0.1 + # bool to control if dfni is a function of vpa or vpabar in MMS test + use_vpabar_in_mms_dfni=true + alpha_switch=1.0 + type="default" +[numerical_dissipation] +vpa_dissipation_coefficient = 0.001 +vperp_dissipation_coefficient = 0.0 +#z_dissipation_coefficient = 0.1 +r_dissipation_coefficient = 0.0 diff --git a/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_8_vpa_8_vperp_4_diss.toml b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_8_vpa_8_vperp_4_diss.toml new file mode 100644 index 000000000..d33cc82fb --- /dev/null +++ b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_8_vpa_8_vperp_4_diss.toml @@ -0,0 +1,99 @@ +n_ion_species = 1 +n_neutral_species = 0 +electron_physics = "boltzmann_electron_response" +#electron_physics = "boltzmann_electron_response_with_simple_sheath" +evolve_moments_density = false +evolve_moments_parallel_flow = false +evolve_moments_parallel_pressure = false +evolve_moments_conservation = false +force_Er_zero_at_wall = false #true +geometry_option="1D-mirror" +DeltaB=0.5 +#geometry_option="constant-helical" +#pitch=1.0 +Er_constant = 0.0 +T_e = 1.0 +T_wall = 1.0 +rhostar = 1.0 +initial_density1 = 0.5 +initial_temperature1 = 1.0 +initial_density2 = 0.5 +initial_temperature2 = 1.0 +z_IC_option1 = "sinusoid" +z_IC_density_amplitude1 = 0.001 +z_IC_density_phase1 = 0.0 +z_IC_upar_amplitude1 = 0.0 +z_IC_upar_phase1 = 0.0 +z_IC_temperature_amplitude1 = 0.0 +z_IC_temperature_phase1 = 0.0 +z_IC_option2 = "sinusoid" +z_IC_density_amplitude2 = 0.001 +z_IC_density_phase2 = 0.0 +z_IC_upar_amplitude2 = 0.0 +z_IC_upar_phase2 = 0.0 +z_IC_temperature_amplitude2 = 0.0 +z_IC_temperature_phase2 = 0.0 +charge_exchange_frequency = 0.0 +ionization_frequency = 0.0 +nstep = 2000 +dt = 0.0005 +nwrite = 200 +nwrite_dfns = 200 +use_semi_lagrange = false +n_rk_stages = 4 +split_operators = false +z_ngrid = 9 +z_nelement = 8 +z_nelement_local = 8 +z_bc = "wall" +z_discretization = "chebyshev_pseudospectral" +r_ngrid = 1 +r_nelement = 1 +r_nelement_local = 1 +r_bc = "periodic" +r_discretization = "chebyshev_pseudospectral" +vpa_ngrid = 9 +vpa_nelement = 8 +vpa_L = 12.0 +vpa_bc = "zero" +vpa_discretization = "chebyshev_pseudospectral" +vperp_ngrid = 9 +vperp_nelement = 4 +vperp_L = 6.0 +#vperp_discretization = "finite_difference" +vperp_discretization = "chebyshev_pseudospectral" +#vperp_discretization = "gausslegendre_pseudospectral" +vperp_bc = "zero" + +vz_ngrid = 17 +vz_nelement = 4 +vz_L = 12.0 +vz_bc = "periodic" +vz_discretization = "chebyshev_pseudospectral" + +vr_ngrid = 17 +vr_nelement = 4 +vr_L = 12.0 +vr_bc = "periodic" +vr_discretization = "chebyshev_pseudospectral" + +vzeta_ngrid = 17 +vzeta_nelement = 4 +vzeta_L = 12.0 +vzeta_bc = "periodic" +vzeta_discretization = "chebyshev_pseudospectral" + +[manufactured_solns] + use_for_advance=true + use_for_init=true + # constant to be used to control Ez divergence in MMS tests + epsilon_offset=0.1 + # bool to control if dfni is a function of vpa or vpabar in MMS test + use_vpabar_in_mms_dfni=true + alpha_switch=1.0 + type="default" +[numerical_dissipation] +vpa_dissipation_coefficient = 0.001 +vperp_dissipation_coefficient = 0.0 +#z_dissipation_coefficient = 0.1 +r_dissipation_coefficient = 0.0 From 9a78fe0b43d4c9b333a4a928b5d9668bdbbbf93a Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Thu, 25 Jan 2024 08:56:08 +0000 Subject: [PATCH 24/62] Added vperp_diffusion flag to advance struct and use this to test when to apply the boundary conditions on vperp, also add a test of the sign of the advection speed to determine when to impose a boundary condition on vperp. --- src/initial_conditions.jl | 27 ++++++++++++++++----------- src/input_structs.jl | 1 + src/time_advance.jl | 15 +++++++++------ 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/src/initial_conditions.jl b/src/initial_conditions.jl index ce0ce8955..0d8baee8f 100644 --- a/src/initial_conditions.jl +++ b/src/initial_conditions.jl @@ -1134,8 +1134,8 @@ enforce boundary conditions in vpa and z on the evolved pdf; also enforce boundary conditions in z on all separately evolved velocity space moments of the pdf """ function enforce_boundary_conditions!(f, f_r_bc, density, upar, ppar, moments, vpa_bc, - z_bc, r_bc, vpa, vperp, z, r, vpa_spectral, vperp_spectral, vpa_adv, z_adv, r_adv, composition, scratch_dummy, - r_diffusion, vpa_diffusion) + z_bc, r_bc, vpa, vperp, z, r, vpa_spectral, vperp_spectral, vpa_adv, vperp_adv, z_adv, r_adv, composition, scratch_dummy, + r_diffusion, vpa_diffusion, vperp_diffusion) if vpa.n > 1 begin_s_r_z_vperp_region() @loop_s_r_z_vperp is ir iz ivperp begin @@ -1148,7 +1148,8 @@ function enforce_boundary_conditions!(f, f_r_bc, density, upar, ppar, moments, v end if vperp.n > 1 begin_s_r_z_vpa_region() - @views enforce_vperp_boundary_condition!(f, vperp.bc, vperp, vperp_spectral) + @views enforce_vperp_boundary_condition!(f, vperp.bc, vperp, vperp_spectral, + vperp_adv, vperp_diffusion) end if z.n > 1 begin_s_r_vperp_vpa_region() @@ -1169,12 +1170,12 @@ function enforce_boundary_conditions!(f, f_r_bc, density, upar, ppar, moments, v end end function enforce_boundary_conditions!(fvec_out::scratch_pdf, moments, f_r_bc, vpa_bc, - z_bc, r_bc, vpa, vperp, z, r, vpa_spectral, vperp_spectral, vpa_adv, z_adv, r_adv, composition, scratch_dummy, - r_diffusion, vpa_diffusion) + z_bc, r_bc, vpa, vperp, z, r, vpa_spectral, vperp_spectral, vpa_adv, vperp_adv, z_adv, r_adv, composition, scratch_dummy, + r_diffusion, vpa_diffusion, vperp_diffusion) enforce_boundary_conditions!(fvec_out.pdf, f_r_bc, fvec_out.density, fvec_out.upar, fvec_out.ppar, moments, vpa_bc, z_bc, r_bc, vpa, vperp, z, r, - vpa_spectral, vperp_spectral, vpa_adv, z_adv, - r_adv, composition, scratch_dummy, r_diffusion, vpa_diffusion) + vpa_spectral, vperp_spectral, vpa_adv, vperp_adv, z_adv, + r_adv, composition, scratch_dummy, r_diffusion, vpa_diffusion, vperp_diffusion) end """ @@ -2173,20 +2174,24 @@ end """ enforce zero boundary condition at vperp -> infinity """ -function enforce_vperp_boundary_condition!(f, bc, vperp, vperp_spectral) +function enforce_vperp_boundary_condition!(f, bc, vperp, vperp_spectral, vperp_advect, diffusion) if bc == "zero" nvperp = vperp.n ngrid = vperp.ngrid # set zero boundary condition @loop_s_r_z_vpa is ir iz ivpa begin - f[ivpa,nvperp,iz,ir,is] = 0.0 + if diffusion || vperp_advect[is].speed[nvperp,ivpa,iz,ir] < 0.0 + f[ivpa,nvperp,iz,ir,is] = 0.0 + end end # set regularity condition d F / d vperp = 0 at vperp = 0 if vperp.discretization == "gausslegendre_pseudospectral" || vperp.discretization == "chebyshev_pseudospectral" D0 = vperp_spectral.radau.D0 @loop_s_r_z_vpa is ir iz ivpa begin - # adjust F(vperp = 0) so that d F / d vperp = 0 at vperp = 0 - f[ivpa,1,iz,ir,is] = -sum(D0[2:ngrid].*f[ivpa,2:ngrid,iz,ir,is])/D0[1] + if diffusion || vperp_advect[is].speed[1,ivpa,iz,ir] > 0.0 + # adjust F(vperp = 0) so that d F / d vperp = 0 at vperp = 0 + f[ivpa,1,iz,ir,is] = -sum(D0[2:ngrid].*f[ivpa,2:ngrid,iz,ir,is])/D0[1] + end end else println("vperp.bc=\"$bc\" not supported by discretization " diff --git a/src/input_structs.jl b/src/input_structs.jl index fd508dc6f..301d09b87 100644 --- a/src/input_structs.jl +++ b/src/input_structs.jl @@ -79,6 +79,7 @@ mutable struct advance_info manufactured_solns_test::Bool r_diffusion::Bool #flag to control how r bc is imposed when r diffusion terms are present vpa_diffusion::Bool #flag to control how vpa bc is imposed when vpa diffusion terms are present + vperp_diffusion::Bool #flag to control how vperp bc is imposed when vperp diffusion terms are present vz_diffusion::Bool #flag to control how vz bc is imposed when vz diffusion terms are present end diff --git a/src/time_advance.jl b/src/time_advance.jl index 2fdd0851f..20f4a0bc8 100644 --- a/src/time_advance.jl +++ b/src/time_advance.jl @@ -375,8 +375,9 @@ function setup_time_advance!(pdf, vz, vr, vzeta, vpa, vperp, z, r, vz_spectral, pdf.charged.norm, boundary_distributions.pdf_rboundary_charged, moments.charged.dens, moments.charged.upar, moments.charged.ppar, moments, vpa.bc, z.bc, r.bc, vpa, vperp, z, r, vpa_spectral, vperp_spectral, - vpa_advect, z_advect, r_advect, - composition, scratch_dummy, advance.r_diffusion, advance.vpa_diffusion) + vpa_advect, vperp_advect, z_advect, r_advect, + composition, scratch_dummy, advance.r_diffusion, + advance.vpa_diffusion, advance.vperp_diffusion) # Ensure normalised pdf exactly obeys integral constraints if evolving moments begin_s_r_z_region() @loop_s_r_z is ir iz begin @@ -479,6 +480,7 @@ function setup_advance_flags(moments, composition, t_input, collisions, advance_neutral_energy = false r_diffusion = false vpa_diffusion = false + vperp_diffusion = false vz_diffusion = false explicit_weakform_fp_collisions = false # all advance flags remain false if using operator-splitting @@ -583,6 +585,7 @@ function setup_advance_flags(moments, composition, t_input, collisions, r_diffusion = (advance_numerical_dissipation && num_diss_params.r_dissipation_coefficient > 0.0) # flag to determine if a d^2/dvpa^2 operator is present vpa_diffusion = ((advance_numerical_dissipation && num_diss_params.vpa_dissipation_coefficient > 0.0) || explicit_weakform_fp_collisions) + vperp_diffusion = ((advance_numerical_dissipation && num_diss_params.vperp_dissipation_coefficient > 0.0) || explicit_weakform_fp_collisions) vz_diffusion = (advance_numerical_dissipation && num_diss_params.vz_dissipation_coefficient > 0.0) end @@ -599,7 +602,7 @@ function setup_advance_flags(moments, composition, t_input, collisions, advance_energy, advance_neutral_external_source, advance_neutral_sources, advance_neutral_continuity, advance_neutral_force_balance, advance_neutral_energy, rk_coefs, - manufactured_solns_test, r_diffusion, vpa_diffusion, vz_diffusion) + manufactured_solns_test, r_diffusion, vpa_diffusion, vperp_diffusion, vz_diffusion) end function setup_dummy_and_buffer_arrays(nr,nz,nvpa,nvperp,nvz,nvr,nvzeta,nspecies_ion,nspecies_neutral) @@ -1337,7 +1340,7 @@ function rk_update!(scratch, pdf, moments, fields, boundary_distributions, vz, v z_spectral, r_spectral, vpa_spectral, vperp_spectral = spectral_objects.z_spectral, spectral_objects.r_spectral, spectral_objects.vpa_spectral, spectral_objects.vperp_spectral vzeta_spectral, vr_spectral, vz_spectral = spectral_objects.vzeta_spectral, spectral_objects.vr_spectral, spectral_objects.vz_spectral - vpa_advect, r_advect, z_advect = advect_objects.vpa_advect, advect_objects.r_advect, advect_objects.z_advect + vpa_advect, vperp_advect, r_advect, z_advect = advect_objects.vpa_advect, advect_objects.vperp_advect, advect_objects.r_advect, advect_objects.z_advect neutral_z_advect, neutral_r_advect, neutral_vz_advect = advect_objects.neutral_z_advect, advect_objects.neutral_r_advect, advect_objects.neutral_vz_advect ## @@ -1366,8 +1369,8 @@ function rk_update!(scratch, pdf, moments, fields, boundary_distributions, vz, v enforce_boundary_conditions!(new_scratch, moments, boundary_distributions.pdf_rboundary_charged, vpa.bc, z.bc, r.bc, vpa, vperp, z, r, vpa_spectral, vperp_spectral, - vpa_advect, z_advect, r_advect, composition, scratch_dummy, - advance.r_diffusion, advance.vpa_diffusion) + vpa_advect, vperp_advect, z_advect, r_advect, composition, scratch_dummy, + advance.r_diffusion, advance.vpa_diffusion, advance.vperp_diffusion) if moments.evolve_density && moments.enforce_conservation begin_s_r_z_region() From 4b57277f7006b285f1e78428db189c687eb0339a Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Fri, 26 Jan 2024 08:54:23 +0000 Subject: [PATCH 25/62] Addition of test of derivative of exp(-y^2) at y = 0. --- test_scripts/chebyshev_radau_test.jl | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/test_scripts/chebyshev_radau_test.jl b/test_scripts/chebyshev_radau_test.jl index 57f2a0782..79ba9c96b 100644 --- a/test_scripts/chebyshev_radau_test.jl +++ b/test_scripts/chebyshev_radau_test.jl @@ -81,6 +81,15 @@ function chebyshevradau_test(; ngrid=5, L_in=3.0) println("f(y) = exp(-4 y) test") println("exact df: ",df_exact," num df: ",df_num," abs(err): ",df_err) + for iy in 1:y.n + ff[iy] = exp(-y.grid[iy]^2) + end + df_exact = 0.0 + df_num = sum(D0.*ff)/y.element_scale[1] + df_err = abs(df_num - df_exact) + println("f(y) = exp(-y^2) test") + println("exact df: ",df_exact," num df: ",df_num," abs(err): ",df_err) + for iy in 1:y.n ff[iy] = sin(y.grid[iy]) end @@ -89,6 +98,7 @@ function chebyshevradau_test(; ngrid=5, L_in=3.0) df_err = abs(df_num - df_exact) println("f(y) = sin(y) test") println("exact df: ",df_exact," num df: ",df_num," abs(err): ",df_err) + for iy in 1:y.n ff[iy] = y.grid[iy] + (y.grid[iy])^2 + (y.grid[iy])^3 end @@ -104,4 +114,4 @@ if abspath(PROGRAM_FILE) == @__FILE__ Pkg.activate(".") chebyshevradau_test() -end \ No newline at end of file +end From 3cdff8cc44d1be725b9d69ecd331bed9fb09159e Mon Sep 17 00:00:00 2001 From: John Omotani Date: Fri, 26 Jan 2024 14:12:11 +0000 Subject: [PATCH 26/62] Fix minor shared-memory bug Zero-initialization of `speed` variable in `setup_advection()` should be done in serial. --- src/advection.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/advection.jl b/src/advection.jl index 19468d542..3a78d500c 100644 --- a/src/advection.jl +++ b/src/advection.jl @@ -68,7 +68,9 @@ function setup_advection_per_species(coords...) # introducing NaNs (if left uninitialised) when coordinate speeds # are used but the coordinate has only a single point # (e.g. dr/dt in dvperp/dt = (vperp/2B)dB/dt, see vperp_advection.jl) - @. speed = 0.0 + @serial_region begin + @. speed = 0.0 + end # return advection_info struct containing necessary arrays return advection_info(rhs, df, speed, adv_fac) end From 13330b30cf2d54367dbe973524acf5c8c3955bbf Mon Sep 17 00:00:00 2001 From: John Omotani Date: Sun, 28 Jan 2024 13:13:06 +0000 Subject: [PATCH 27/62] Fix manufactured_solutions() input in makie_post_processing --- src/makie_post_processing.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/makie_post_processing.jl b/src/makie_post_processing.jl index 890ed9ccc..706ef70e4 100644 --- a/src/makie_post_processing.jl +++ b/src/makie_post_processing.jl @@ -5948,7 +5948,7 @@ function manufactured_solutions_get_field_and_field_sym(run_info, variable_name; :density_neutral, :f, :f_neutral) manufactured_funcs = manufactured_solutions(run_info.manufactured_solns_input, Lr_in, run_info.z.L, - run_info.r.bc, run_info.z.bc, run_info.geometry, + run_info.r.bc, run_info.z.bc, run_info.geometry.input, run_info.composition, run_info.species, run_info.r.n, nvperp) end From a9a26f231740ccd822fee627d4605845a9e68170 Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Wed, 31 Jan 2024 09:17:58 +0000 Subject: [PATCH 28/62] Correct silly factor of 2 error in the calculation for the vector D0 for d f / d coord at coord = -1 for Radau elements (which avoid the point at x = -1). --- src/chebyshev.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/chebyshev.jl b/src/chebyshev.jl index 9bac36633..4e7c25eff 100644 --- a/src/chebyshev.jl +++ b/src/chebyshev.jl @@ -794,11 +794,12 @@ function chebyshev_radau_forward_transform!(chebyf, fext, ff, transform, n) chebyshev_spectral_derivative!(cheby_df, cheby_f) # form the derivative at x = - 1 using that T_n(-1) = (-1)^n # and converting the normalisation factors to undo the normalisation in the FFT - # df = d0 + sum_n=1 (-1)^n d_n/2 with d_n the coeffs + # df = d0 + sum_n=1 (-1)^n d_n with d_n the coeffs # of the Cheb derivative in the Fourier representation + # df = sum_n=0,N-1 d_n T_n(x) df = cheby_df[1] for i in 2:coord.ngrid - df += ((-1)^(i-1))*0.5*cheby_df[i] + df += ((-1)^(i-1))*cheby_df[i] end return df end From ba47914bdc4893e362cfa0246facbaa4168a9f9e Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Wed, 31 Jan 2024 09:19:35 +0000 Subject: [PATCH 29/62] Correct error where "gausslegendre_pseudospectral" option was tested by default instead of "chebyshev_pseudospectral" option. discretization is now an optional argument so that this script can be used to test the vector D0 for both options. The tests currently pass. --- test_scripts/chebyshev_radau_test.jl | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/test_scripts/chebyshev_radau_test.jl b/test_scripts/chebyshev_radau_test.jl index 79ba9c96b..50c2222de 100644 --- a/test_scripts/chebyshev_radau_test.jl +++ b/test_scripts/chebyshev_radau_test.jl @@ -39,7 +39,7 @@ at the lower endpoint of the domain (-1,1] in the normalised coordinate x. Here in the tests the shifted coordinate y is used with the vperp label so that the grid runs from (0,L]. """ -function chebyshevradau_test(; ngrid=5, L_in=3.0) +function chebyshevradau_test(; ngrid=5, L_in=3.0, discretization="chebyshev_pseudospectral") # elemental grid tests #ngrid = 17 @@ -49,7 +49,8 @@ function chebyshevradau_test(; ngrid=5, L_in=3.0) y_nelement_global = y_nelement_local # total number of elements y_L = L_in bc = "zero" - discretization = "gausslegendre_pseudospectral" + #discretization = "gausslegendre_pseudospectral" + #discretization = "chebyshev_pseudospectral" # fd_option and adv_input not actually used so given values unimportant fd_option = "fourth_order_centered" cheb_option = "matrix" @@ -88,7 +89,9 @@ function chebyshevradau_test(; ngrid=5, L_in=3.0) df_num = sum(D0.*ff)/y.element_scale[1] df_err = abs(df_num - df_exact) println("f(y) = exp(-y^2) test") - println("exact df: ",df_exact," num df: ",df_num," abs(err): ",df_err) + println("exact df: ",df_exact," num df: ",df_num," abs(err): ",df_err) + f0 = -sum(D0[2:ngrid].*ff[2:ngrid])/D0[1] + println("exact f[0]: ",ff[1]," num f[0]: ",f0," abs(err): ",abs(f0-ff[1])) for iy in 1:y.n ff[iy] = sin(y.grid[iy]) From 8268c80377d32e16421baf8c0f6ea4a5512db231 Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Wed, 31 Jan 2024 11:47:29 +0000 Subject: [PATCH 30/62] Input files for the mirror manufactured solutions test. --- ...irror_MMS_ngrid_9_nel_r_1_z_16_vpa_16_vperp_8_diss.toml | 2 +- ...rror_MMS_ngrid_9_nel_r_1_z_32_vpa_32_vperp_16_diss.toml | 2 +- ...-mirror_MMS_ngrid_9_nel_r_1_z_4_vpa_4_vperp_2_diss.toml | 7 +++---- ...-mirror_MMS_ngrid_9_nel_r_1_z_8_vpa_8_vperp_4_diss.toml | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_16_vpa_16_vperp_8_diss.toml b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_16_vpa_16_vperp_8_diss.toml index dd0df3fe8..6f0ef7638 100644 --- a/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_16_vpa_16_vperp_8_diss.toml +++ b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_16_vpa_16_vperp_8_diss.toml @@ -94,6 +94,6 @@ vzeta_discretization = "chebyshev_pseudospectral" type="default" [numerical_dissipation] vpa_dissipation_coefficient = 0.001 -vperp_dissipation_coefficient = 0.0 +vperp_dissipation_coefficient = 0.001 #z_dissipation_coefficient = 0.1 r_dissipation_coefficient = 0.0 diff --git a/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_32_vpa_32_vperp_16_diss.toml b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_32_vpa_32_vperp_16_diss.toml index 1daefaa21..4165b2d36 100644 --- a/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_32_vpa_32_vperp_16_diss.toml +++ b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_32_vpa_32_vperp_16_diss.toml @@ -94,6 +94,6 @@ vzeta_discretization = "chebyshev_pseudospectral" type="default" [numerical_dissipation] vpa_dissipation_coefficient = 0.001 -vperp_dissipation_coefficient = 0.0 +vperp_dissipation_coefficient = 0.001 #z_dissipation_coefficient = 0.1 r_dissipation_coefficient = 0.0 diff --git a/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_4_vpa_4_vperp_2_diss.toml b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_4_vpa_4_vperp_2_diss.toml index 96013ee4a..7ea665889 100644 --- a/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_4_vpa_4_vperp_2_diss.toml +++ b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_4_vpa_4_vperp_2_diss.toml @@ -61,9 +61,8 @@ vperp_ngrid = 9 vperp_nelement = 2 vperp_L = 6.0 #vperp_discretization = "finite_difference" -vperp_discretization = "chebyshev_pseudospectral" -#vperp_discretization = "gausslegendre_pseudospectral" -#vperp_bc = "none" +#vperp_discretization = "chebyshev_pseudospectral" +vperp_discretization = "gausslegendre_pseudospectral" vperp_bc = "zero" vz_ngrid = 17 @@ -95,6 +94,6 @@ vzeta_discretization = "chebyshev_pseudospectral" type="default" [numerical_dissipation] vpa_dissipation_coefficient = 0.001 -vperp_dissipation_coefficient = 0.00 +vperp_dissipation_coefficient = 0.001 #z_dissipation_coefficient = 0.1 r_dissipation_coefficient = 0.0 diff --git a/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_8_vpa_8_vperp_4_diss.toml b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_8_vpa_8_vperp_4_diss.toml index d33cc82fb..e815c3be6 100644 --- a/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_8_vpa_8_vperp_4_diss.toml +++ b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_8_vpa_8_vperp_4_diss.toml @@ -94,6 +94,6 @@ vzeta_discretization = "chebyshev_pseudospectral" type="default" [numerical_dissipation] vpa_dissipation_coefficient = 0.001 -vperp_dissipation_coefficient = 0.0 +vperp_dissipation_coefficient = 0.001 #z_dissipation_coefficient = 0.1 r_dissipation_coefficient = 0.0 From cdec9ffa3bacd91915d7332885bdc335218ae1df Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Wed, 31 Jan 2024 11:49:34 +0000 Subject: [PATCH 31/62] Bring ticks to appropriate values for 1D-mirror MMS test. --- src/plot_MMS_sequence.jl | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/plot_MMS_sequence.jl b/src/plot_MMS_sequence.jl index f0de15966..b433010fb 100644 --- a/src/plot_MMS_sequence.jl +++ b/src/plot_MMS_sequence.jl @@ -377,7 +377,9 @@ function get_MMS_error_data(path_list,scan_type,scan_name) ytick_sequence = Array([1.0e-5,1.0e-4,1.0e-3,1.0e-2,1.0e-1,1.0e-0,1.0e1]) elseif scan_name == "1D-1V-wall_cheb" || scan_name == "1D-2V-wall_cheb_krook" ytick_sequence = Array([1.0e-13,1.0e-12,1.0e-11,1.0e-10,1.0e-9,1.0e-8,1.0e-7,1.0e-6,1.0e-5,1.0e-4,1.0e-3,1.0e-2,1.0e-1,1.0e-0,1.0e1]) - elseif scan_name == "1D-3V-wall_cheb-updated" || scan_name == "1D-3V-wall_cheb-new-dfni-Er" || scan_name == "1D-3V-wall_cheb-new-dfni" || scan_name == "2D-sound-wave_cheb" + elseif scan_name == "mirror_wall-1D-2V" + ytick_sequence = Array([1.0e-12,1.0e-11,1.0e-10,1.0e-9,1.0e-8,1.0e-7,1.0e-6,1.0e-5,1.0e-4,1.0e-3,1.0e-2,1.0e-1,1.0e-0,1.0e1]) + elseif scan_name == "1D-3V-wall_cheb-updated" || scan_name == "1D-3V-wall_cheb-new-dfni-Er" || scan_name == "1D-3V-wall_cheb-new-dfni" || scan_name == "2D-sound-wave_cheb" || scan_name == "mirror_wall-1D-2V" ytick_sequence = Array([1.0e-10,1.0e-9,1.0e-8,1.0e-7,1.0e-6,1.0e-5,1.0e-4,1.0e-3,1.0e-2,1.0e-1,1.0e-0,1.0e1]) elseif scan_name == "2D-1V-wall_cheb" || scan_name == "2D-1V-wall_cheb-nonzero-Er" || scan_name == "1D-1V-wall_cheb-constant-Er-ngrid-5-opt" ytick_sequence = Array([1.0e-8,1.0e-7,1.0e-6,1.0e-5,1.0e-4,1.0e-3,1.0e-2,1.0e-1,1.0e-0]) @@ -388,7 +390,8 @@ function get_MMS_error_data(path_list,scan_type,scan_name) plot(nelement_sequence, [ion_density_error_sequence,ion_pdf_error_sequence], xlabel=xlabel, label=[ylabel_ion_density ylabel_ion_pdf], ylabel="", shape =:circle, xscale=:log10, yscale=:log10, xticks = (nelement_sequence, nelement_sequence), yticks = (ytick_sequence, ytick_sequence), markersize = 5, linewidth=2, - xtickfontsize = fontsize, xguidefontsize = fontsize, ytickfontsize = fontsize, yguidefontsize = fontsize, legendfontsize = fontsize) + xtickfontsize = fontsize, xguidefontsize = fontsize, ytickfontsize = fontsize, yguidefontsize = fontsize, legendfontsize = fontsize, + foreground_color_legend = nothing, background_color_legend = nothing, legend=:bottomleft) outfile = outprefix*".pdf" savefig(outfile) println(outfile) @@ -397,7 +400,8 @@ function get_MMS_error_data(path_list,scan_type,scan_name) plot(nelement_sequence, [ion_density_error_sequence,phi_error_sequence,Er_error_sequence,Ez_error_sequence], xlabel=xlabel, label=[ylabel_ion_density ylabel_phi ylabel_Er ylabel_Ez], ylabel="", shape =:circle, xscale=:log10, yscale=:log10, xticks = (nelement_sequence, nelement_sequence), yticks = (ytick_sequence, ytick_sequence), markersize = 5, linewidth=2, - xtickfontsize = fontsize, xguidefontsize = fontsize, ytickfontsize = fontsize, yguidefontsize = fontsize, legendfontsize = fontsize) + xtickfontsize = fontsize, xguidefontsize = fontsize, ytickfontsize = fontsize, yguidefontsize = fontsize, legendfontsize = fontsize, + foreground_color_legend = nothing, background_color_legend = nothing, legend=:bottomleft) outfile = outprefix*"_fields.pdf" savefig(outfile) println(outfile) @@ -410,7 +414,8 @@ function get_MMS_error_data(path_list,scan_type,scan_name) plot(nelement_sequence, [ion_density_error_sequence,phi_error_sequence,Ez_error_sequence], xlabel=xlabel, label=[ylabel_ion_density ylabel_phi ylabel_Ez], ylabel="", shape =:circle, xscale=:log10, yscale=:log10, xticks = (nelement_sequence, nelement_sequence), yticks = (ytick_sequence, ytick_sequence), markersize = 5, linewidth=2, - xtickfontsize = fontsize, xguidefontsize = fontsize, ytickfontsize = fontsize, yguidefontsize = fontsize, legendfontsize = fontsize) + xtickfontsize = fontsize, xguidefontsize = fontsize, ytickfontsize = fontsize, yguidefontsize = fontsize, legendfontsize = fontsize, + foreground_color_legend = nothing, background_color_legend = nothing, legend=:bottomleft) outfile = outprefix*"_fields_no_Er.pdf" savefig(outfile) println(outfile) @@ -418,7 +423,8 @@ function get_MMS_error_data(path_list,scan_type,scan_name) plot(nelement_sequence, [ion_density_error_sequence,phi_error_sequence,Ez_error_sequence,ion_pdf_error_sequence,expected_scaling], xlabel=xlabel, label=[ylabel_ion_density ylabel_phi ylabel_Ez ylabel_ion_pdf expected_label], ylabel="", shape =:circle, xscale=:log10, yscale=:log10, xticks = (nelement_sequence, nelement_sequence), yticks = (ytick_sequence, ytick_sequence), markersize = 5, linewidth=2, - xtickfontsize = fontsize, xguidefontsize = fontsize, ytickfontsize = fontsize, yguidefontsize = fontsize, legendfontsize = fontsize) + xtickfontsize = fontsize, xguidefontsize = fontsize, ytickfontsize = fontsize, yguidefontsize = fontsize, legendfontsize = fontsize, + foreground_color_legend = nothing, background_color_legend = nothing, legend=:bottomleft) outfile = outprefix*"_fields_and_ion_pdf_no_Er.pdf" savefig(outfile) println(outfile) @@ -427,7 +433,8 @@ function get_MMS_error_data(path_list,scan_type,scan_name) plot(nelement_sequence, [ion_density_error_sequence,phi_error_sequence,Ez_error_sequence,Er_error_sequence,ion_pdf_error_sequence], xlabel=xlabel, label=[ylabel_ion_density ylabel_phi ylabel_Ez ylabel_Er ylabel_ion_pdf], ylabel="", shape =:circle, xscale=:log10, yscale=:log10, xticks = (nelement_sequence, nelement_sequence), yticks = (ytick_sequence, ytick_sequence), markersize = 5, linewidth=2, - xtickfontsize = fontsize, xguidefontsize = fontsize, ytickfontsize = fontsize, yguidefontsize = fontsize, legendfontsize = fontsize) + xtickfontsize = fontsize, xguidefontsize = fontsize, ytickfontsize = fontsize, yguidefontsize = fontsize, legendfontsize = fontsize, + foreground_color_legend = nothing, background_color_legend = nothing, legend=:bottomleft) outfile = outprefix*"_fields_and_ion_pdf.pdf" savefig(outfile) println(outfile) @@ -453,7 +460,8 @@ function get_MMS_error_data(path_list,scan_type,scan_name) plot(nelement_sequence, [ion_density_error_sequence, ion_pdf_error_sequence, neutral_density_error_sequence, neutral_pdf_error_sequence], xlabel=xlabel, label=[ylabel_ion_density ylabel_ion_pdf ylabel_neutral_density ylabel_neutral_pdf], ylabel="", shape =:circle, xscale=:log10, yscale=:log10, xticks = (nelement_sequence, nelement_sequence), yticks = (ytick_sequence, ytick_sequence), markersize = 5, linewidth=2, - xtickfontsize = fontsize, xguidefontsize = fontsize, ytickfontsize = fontsize, yguidefontsize = fontsize, legendfontsize = fontsize) + xtickfontsize = fontsize, xguidefontsize = fontsize, ytickfontsize = fontsize, yguidefontsize = fontsize, legendfontsize = fontsize, + foreground_color_legend = nothing, background_color_legend = nothing, legend=:bottomleft) outfile = outprefix*".pdf" savefig(outfile) println(outfile) @@ -461,7 +469,8 @@ function get_MMS_error_data(path_list,scan_type,scan_name) plot(nelement_sequence, [ion_density_error_sequence, neutral_density_error_sequence, phi_error_sequence, Er_error_sequence, Ez_error_sequence], xlabel=xlabel, label=[ylabel_ion_density ylabel_neutral_density ylabel_phi ylabel_Er ylabel_Ez], ylabel="", shape =:circle, xscale=:log10, yscale=:log10, xticks = (nelement_sequence, nelement_sequence), yticks = (ytick_sequence, ytick_sequence), markersize = 5, linewidth=2, - xtickfontsize = fontsize, xguidefontsize = fontsize, ytickfontsize = fontsize, yguidefontsize = fontsize, legendfontsize = fontsize) + xtickfontsize = fontsize, xguidefontsize = fontsize, ytickfontsize = fontsize, yguidefontsize = fontsize, legendfontsize = fontsize, + foreground_color_legend = nothing, background_color_legend = nothing, legend=:bottomleft) outfile = outprefix*"_fields.pdf" savefig(outfile) println(outfile) From d29a6a75c44e726efb348c156f31c11d5017a06f Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Wed, 31 Jan 2024 14:07:55 +0000 Subject: [PATCH 32/62] Test the 1D mirror geometry with another ngrid. --- src/plot_MMS_sequence.jl | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/plot_MMS_sequence.jl b/src/plot_MMS_sequence.jl index b433010fb..929693cec 100644 --- a/src/plot_MMS_sequence.jl +++ b/src/plot_MMS_sequence.jl @@ -511,7 +511,8 @@ function run_mms_test() #test_option = "collisionless_wall-1D-1V-constant-Er-ngrid-5" #test_option = "collisionless_wall-1D-1V-constant-Er-ngrid-5-opt" #test_option = "krook_wall-1D-2V" - test_option = "mirror_wall-1D-2V" + #test_option = "mirror_wall-1D-2V" + test_option = "mirror_wall-1D-2V-ngrid-5" #test_option = "collisionless_wall-1D-3V" #test_option = "collisionless_wall-2D-3V" #test_option = "collisionless_wall-2D-3V-Er-zero-at-plate" @@ -675,13 +676,22 @@ function run_mms_test() scan_type = "vpavperpz_nelement" scan_name = "1D-2V-wall_cheb_krook" elseif test_option == "mirror_wall-1D-2V" - # Krook wall test, no sheath for electrons, no radial coordinate + # Mirror wall test, no sheath for electrons, no radial coordinate path_list = ["runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_4_vpa_4_vperp_2_diss", "runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_8_vpa_8_vperp_4_diss", "runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_16_vpa_16_vperp_8_diss", "runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_32_vpa_32_vperp_16_diss",] scan_type = "vpa2vperpz_nelement" scan_name = "mirror_wall-1D-2V" + elseif test_option == "mirror_wall-1D-2V-ngrid-5" + # Mirror wall test, no sheath for electrons, no radial coordinate + path_list = ["runs/1D-mirror_MMS_ngrid_5_nel_r_1_z_4_vpa_4_vperp_2_diss", + "runs/1D-mirror_MMS_ngrid_5_nel_r_1_z_8_vpa_8_vperp_4_diss", + "runs/1D-mirror_MMS_ngrid_5_nel_r_1_z_16_vpa_16_vperp_8_diss", + "runs/1D-mirror_MMS_ngrid_5_nel_r_1_z_32_vpa_32_vperp_16_diss", + "runs/1D-mirror_MMS_ngrid_5_nel_r_1_z_64_vpa_64_vperp_32_diss",] + scan_type = "vpa2vperpz_nelement" + scan_name = "mirror_wall-1D-2V-ngrid-5" end print(path_list) get_MMS_error_data(path_list,scan_type,scan_name) From f132277bd055e3c9e42f8286c7247ec02ca0a74f Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Wed, 31 Jan 2024 14:09:23 +0000 Subject: [PATCH 33/62] Permit manufactured solutions testing in a 2D flux tube with a radial domain and the "1D-mirror" geometry. Correct the symbolic distribution function and symbolic upari to reflect the new form of the ExB drift. --- src/geo.jl | 6 +++--- src/manufactured_solns.jl | 11 +++++++++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/geo.jl b/src/geo.jl index 75a0fdedb..2045be042 100644 --- a/src/geo.jl +++ b/src/geo.jl @@ -107,9 +107,9 @@ function init_magnetic_geometry(geometry_input_data::geometry_input,z,r) # a 1D configuration for testing mirror and vperp physics # with \vec{B} = B(z) bz \hat{z} and # with B = B(z) a specified function - if nr > 1 - input_option_error("$option: You have specified nr > 1 -> set nr = 1", option) - end + #if nr > 1 + # input_option_error("$option: You have specified nr > 1 -> set nr = 1", option) + #end DeltaB = geometry_input_data.DeltaB if DeltaB < -0.99999999 input_option_error("$option: You have specified DeltaB < -1 -> set DeltaB > -1", option) diff --git a/src/manufactured_solns.jl b/src/manufactured_solns.jl index fc22a0d1f..b5dede69f 100644 --- a/src/manufactured_solns.jl +++ b/src/manufactured_solns.jl @@ -272,13 +272,17 @@ using IfElse elseif z_bc == "wall" densi = densi_sym(Lr,Lz,r_bc,z_bc,composition,manufactured_solns_input,species) Er, Ez, phi = electric_fields(Lr,Lz,r_bc,z_bc,composition,nr,manufactured_solns_input,species) + Bzeta = geometry.Bzeta + Bmag = geometry.Bmag rhostar = geometry.rhostar + jacobian = geometry.jacobian + ExBgeofac = 0.5*rhostar*Bzeta*jacobian/Bmag^2 bzed = geometry.bzed epsilon = manufactured_solns_input.epsilon_offset alpha = manufactured_solns_input.alpha_switch upari = ( (fluxconst/(sqrt(pi)*densi))*((z/Lz + 0.5)*nplus_sym(Lr,Lz,r_bc,z_bc,epsilon,alpha) - (0.5 - z/Lz)*nminus_sym(Lr,Lz,r_bc,z_bc,epsilon,alpha)) - + alpha*(rhostar/(2.0*bzed))*Er ) + + alpha*(ExBgeofac/bzed)*Er ) end return upari end @@ -357,14 +361,17 @@ using IfElse # get geometric/composition data Bzed = geometry.Bzed + Bzeta = geometry.Bzeta Bmag = geometry.Bmag rhostar = geometry.rhostar + jacobian = geometry.jacobian + ExBgeofac = 0.5*rhostar*Bzeta*jacobian/Bmag^2 epsilon = manufactured_solns_input.epsilon_offset alpha = manufactured_solns_input.alpha_switch if z_bc == "periodic" dfni = densi * exp( - vpa^2 - vperp^2) elseif z_bc == "wall" - vpabar = vpa - alpha*(rhostar/2.0)*(Bmag/Bzed)*Er # for alpha = 1.0, effective velocity in z direction * (Bmag/Bzed) + vpabar = vpa - alpha*ExBgeofac*(Bmag/Bzed)*Er # for alpha = 1.0, effective velocity in z direction * (Bmag/Bzed) Hplus = 0.5*(sign(vpabar) + 1.0) Hminus = 0.5*(sign(-vpabar) + 1.0) ffa = exp(- vperp^2) From 054431bbdfeb075b8c47bda1047efedbe59732b4 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Thu, 1 Feb 2024 14:21:44 +0000 Subject: [PATCH 34/62] Don't make bin/julia a symlink when enabling plots_post_processing Needs to be a bash script so we can activate the Python venv within it when enabling plots_post_processing. --- machines/shared/machine_setup.jl | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/machines/shared/machine_setup.jl b/machines/shared/machine_setup.jl index 75104a56a..c93696f78 100644 --- a/machines/shared/machine_setup.jl +++ b/machines/shared/machine_setup.jl @@ -301,7 +301,8 @@ function machine_setup_moment_kinetics(machine::String; no_force_exit::Bool=fals bindir = joinpath(repo_dir, "bin") mkpath(bindir) julia_executable_name = joinpath(bindir, "julia") - if batch_system || julia_directory == "" + println("check use_plots=", mk_preferences["use_plots"], " ", mk_preferences["use_plots"] == "n") + if batch_system || (julia_directory == "" && mk_preferences["use_plots"] == "n") # Make a local link to the Julia binary so scripts in the repo can find it println("\n** Making a symlink to the julia executable at bin/julia\n") islink(julia_executable_name) && rm(julia_executable_name) @@ -311,7 +312,9 @@ function machine_setup_moment_kinetics(machine::String; no_force_exit::Bool=fals # needing the julia.env setup open(julia_executable_name, "w") do io println(io, "#!/usr/bin/env bash") - println(io, "export JULIA_DEPOT_PATH=$julia_directory") + if julia_directory != "" + println(io, "export JULIA_DEPOT_PATH=$julia_directory") + end julia_path = joinpath(Sys.BINDIR, "julia") println(io, "$julia_path \"\$@\"") end From c0bf27f763f1143412fae86318da7f2b5dcf1aba Mon Sep 17 00:00:00 2001 From: John Omotani Date: Thu, 1 Feb 2024 14:57:31 +0000 Subject: [PATCH 35/62] Restore split into separate get_geometry() and get_composition() --- .../makie_post_processing/src/makie_post_processing.jl | 2 +- .../makie_post_processing/src/shared_utils.jl | 10 ++++++++-- .../plots_post_processing/src/plots_post_processing.jl | 9 +++++---- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/makie_post_processing/makie_post_processing/src/makie_post_processing.jl b/makie_post_processing/makie_post_processing/src/makie_post_processing.jl index 2e2b26369..cbfa90211 100644 --- a/makie_post_processing/makie_post_processing/src/makie_post_processing.jl +++ b/makie_post_processing/makie_post_processing/src/makie_post_processing.jl @@ -44,7 +44,7 @@ using moment_kinetics.load_data: close_run_info, get_run_info_no_setup, get_vari neutral_dfn_variables, all_dfn_variables, ion_variables, neutral_variables, all_variables using moment_kinetics.initial_conditions: vpagrid_to_dzdt -using .shared_utils: calculate_and_write_frequencies, get_geometry_and_composition +using .shared_utils: calculate_and_write_frequencies using moment_kinetics.type_definitions: mk_float, mk_int using moment_kinetics.velocity_moments: integrate_over_vspace, integrate_over_neutral_vspace diff --git a/makie_post_processing/makie_post_processing/src/shared_utils.jl b/makie_post_processing/makie_post_processing/src/shared_utils.jl index 4e4a4c17e..076e8010e 100644 --- a/makie_post_processing/makie_post_processing/src/shared_utils.jl +++ b/makie_post_processing/makie_post_processing/src/shared_utils.jl @@ -63,7 +63,7 @@ end """ """ -function get_geometry_and_composition(scan_input, z, r) +function get_geometry(scan_input, z, r) # set geometry reference_params = setup_reference_parameters(scan_input) # set geometry_input @@ -76,6 +76,12 @@ function get_geometry_and_composition(scan_input, z, r) geo_in = geometry_input(rhostar,option,pitch,DeltaB) geometry = init_magnetic_geometry(geo_in,z,r) + return geometry +end + +""" +""" +function get_composition(scan_input) # set composition input # MRH need to get this in way that does not duplicate code # MRH from moment_kinetics_input.jl @@ -116,7 +122,7 @@ function get_geometry_and_composition(scan_input, z, r) composition = species_composition(n_species, n_ion_species, n_neutral_species, electron_physics, use_test_neutral_wall_pdf, T_e, T_wall, phi_wall, Er_constant, mn_over_mi, me_over_mi, recycling_fraction, allocate_float(n_species)) - return geometry, composition + return composition end diff --git a/plots_post_processing/plots_post_processing/src/plots_post_processing.jl b/plots_post_processing/plots_post_processing/src/plots_post_processing.jl index f48084241..11bcaac08 100644 --- a/plots_post_processing/plots_post_processing/src/plots_post_processing.jl +++ b/plots_post_processing/plots_post_processing/src/plots_post_processing.jl @@ -66,7 +66,7 @@ using moment_kinetics.input_structs: electron_physics_type, boltzmann_electron_r using moment_kinetics.reference_parameters using moment_kinetics.geo: init_magnetic_geometry using .post_processing_input: pp -using .shared_utils: calculate_and_write_frequencies, get_geometry_and_composition +using .shared_utils: calculate_and_write_frequencies, get_geometry, get_composition using TOML import Base: get @@ -640,9 +640,10 @@ function analyze_and_plot_data(prefix...; run_index=nothing) end end - geometry, composition = - get_tuple_of_return_values(get_geometry_and_composition, scan_input, - z, r) + geometry = + get_tuple_of_return_values(get_geometry, scan_input, z, r) + composition = + get_tuple_of_return_values(get_composition, scan_input) # initialise the post-processing input options nwrite_movie, itime_min, itime_max, nwrite_movie_pdfs, itime_min_pdfs, itime_max_pdfs, From 5b6eb5281f60ac21bf923dfe4d9df5a61de1c040 Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Fri, 2 Feb 2024 10:01:34 +0000 Subject: [PATCH 36/62] Verion of merged code that runsi (and appears to be correct for runs of one core), but which seems to have a bug in the 1D-mirror MMS test for multiple cores (this could be due to compilation issues). --- .../makie_post_processing/src/shared_utils.jl | 4 +++- moment_kinetics/ext/manufactured_solns_ext.jl | 9 ++++++--- moment_kinetics/src/manufactured_solns.jl | 4 +++- .../plots_post_processing/src/plots_post_processing.jl | 8 ++++++-- 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/makie_post_processing/makie_post_processing/src/shared_utils.jl b/makie_post_processing/makie_post_processing/src/shared_utils.jl index 85d202baf..0de1cc4a6 100644 --- a/makie_post_processing/makie_post_processing/src/shared_utils.jl +++ b/makie_post_processing/makie_post_processing/src/shared_utils.jl @@ -9,7 +9,9 @@ using moment_kinetics.input_structs: boltzmann_electron_response, boltzmann_electron_response_with_simple_sheath, grid_input, geometry_input, species_composition using moment_kinetics.type_definitions: mk_float, mk_int - +using moment_kinetics.reference_parameters: setup_reference_parameters +using moment_kinetics.moment_kinetics_input: get_default_rhostar +using moment_kinetics.geo: init_magnetic_geometry using MPI """ diff --git a/moment_kinetics/ext/manufactured_solns_ext.jl b/moment_kinetics/ext/manufactured_solns_ext.jl index 05711067e..2662a157e 100644 --- a/moment_kinetics/ext/manufactured_solns_ext.jl +++ b/moment_kinetics/ext/manufactured_solns_ext.jl @@ -8,10 +8,10 @@ module manufactured_solns_ext using moment_kinetics.input_structs using moment_kinetics.looping -using moment_kinetics.type_definitions: mk_int +using moment_kinetics.type_definitions: mk_int, mk_float import moment_kinetics.manufactured_solns: manufactured_solutions, manufactured_sources_setup, - manufactured_electric_fields + manufactured_electric_fields, manufactured_geometry using Symbolics using IfElse @@ -446,7 +446,10 @@ using IfElse end function manufactured_solutions(manufactured_solns_input, Lr, Lz, r_bc, z_bc, - geometry, composition, species, nr, nvperp) + geometry_input_data::geometry_input, composition, species, nr, nvperp) + + # calculate the geometry symbolically + geometry = geometry_sym(geometry_input_data,Lz,Lr,nr) charged_species = species.charged[1] if composition.n_neutral_species > 0 neutral_species = species.neutral[1] diff --git a/moment_kinetics/src/manufactured_solns.jl b/moment_kinetics/src/manufactured_solns.jl index fb63ac598..c5feaa503 100644 --- a/moment_kinetics/src/manufactured_solns.jl +++ b/moment_kinetics/src/manufactured_solns.jl @@ -5,6 +5,7 @@ module manufactured_solns export manufactured_solutions export manufactured_sources export manufactured_electric_fields +export manufactured_geometry using ..array_allocation: allocate_shared_float using ..looping @@ -13,6 +14,7 @@ using ..type_definitions: mk_float, mk_int function manufactured_solutions end function manufactured_sources_setup end function manufactured_electric_fields end +function manufactured_geometry end function __init__() try @@ -41,7 +43,7 @@ function manufactured_sources(manufactured_solns_input, r_coord, z_coord, vperp_ Source_i_array = allocate_shared_float(vpa_coord.n,vperp_coord.n,z_coord.n,r_coord.n) begin_s_r_z_region() - println("here loop thing ", looping.loop_ranges[].s) + #println("here loop thing ", looping.loop_ranges[].s) @loop_s is begin if is == 1 @loop_r_z_vperp_vpa ir iz ivperp ivpa begin diff --git a/plots_post_processing/plots_post_processing/src/plots_post_processing.jl b/plots_post_processing/plots_post_processing/src/plots_post_processing.jl index 61ddbb43f..39f4a90a2 100644 --- a/plots_post_processing/plots_post_processing/src/plots_post_processing.jl +++ b/plots_post_processing/plots_post_processing/src/plots_post_processing.jl @@ -57,8 +57,9 @@ using moment_kinetics.analysis: analyze_fields_data, analyze_moments_data, get_unnormalised_f_coords_2d using moment_kinetics.velocity_moments: integrate_over_vspace using moment_kinetics.manufactured_solns: manufactured_solutions, - manufactured_electric_fields -using moment_kinetics.moment_kinetics_input: mk_input, geti, get_default_rhostar + manufactured_electric_fields, + manufactured_geometry +using moment_kinetics.moment_kinetics_input: mk_input, get, get_default_rhostar using moment_kinetics.input_structs: geometry_input, grid_input, species_composition using moment_kinetics.input_structs: electron_physics_type, boltzmann_electron_response, boltzmann_electron_response_with_simple_sheath @@ -1076,7 +1077,9 @@ function analyze_and_plot_data(prefix...; run_index=nothing) manufactured_solns_test = manufactured_solns_input.use_for_advance && manufactured_solns_input.use_for_init # Plots compare density and density_symbolic at last timestep #if(manufactured_solns_test && nr > 1) + println("manufactured_solns_test: ",manufactured_solns_test) if(manufactured_solns_test) + println("got here") # avoid passing Lr = 0 into manufactured_solns functions if r_global.n > 1 Lr_in = r_global.L @@ -1176,6 +1179,7 @@ function analyze_and_plot_data(prefix...; run_index=nothing) compare_neutral_pdf_symbolic_test(run_name_label,manufactured_solns_list,"neutral", L"\widetilde{f}_n",L"\widetilde{f}^{sym}_n",L"\varepsilon(\widetilde{f}_n)","pdf") end + println("got here") end end From 2337c89b71fcac89a86ac8d7c4fed88d021f78ef Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Fri, 2 Feb 2024 11:05:36 +0000 Subject: [PATCH 37/62] Remove print statements. --- .../plots_post_processing/src/plots_post_processing.jl | 2 -- 1 file changed, 2 deletions(-) diff --git a/plots_post_processing/plots_post_processing/src/plots_post_processing.jl b/plots_post_processing/plots_post_processing/src/plots_post_processing.jl index 39f4a90a2..4cb91132b 100644 --- a/plots_post_processing/plots_post_processing/src/plots_post_processing.jl +++ b/plots_post_processing/plots_post_processing/src/plots_post_processing.jl @@ -1079,7 +1079,6 @@ function analyze_and_plot_data(prefix...; run_index=nothing) #if(manufactured_solns_test && nr > 1) println("manufactured_solns_test: ",manufactured_solns_test) if(manufactured_solns_test) - println("got here") # avoid passing Lr = 0 into manufactured_solns functions if r_global.n > 1 Lr_in = r_global.L @@ -1179,7 +1178,6 @@ function analyze_and_plot_data(prefix...; run_index=nothing) compare_neutral_pdf_symbolic_test(run_name_label,manufactured_solns_list,"neutral", L"\widetilde{f}_n",L"\widetilde{f}^{sym}_n",L"\varepsilon(\widetilde{f}_n)","pdf") end - println("got here") end end From 6e9e2e39cad371c738f8990e169694a24c9243ce Mon Sep 17 00:00:00 2001 From: John Omotani Date: Fri, 2 Feb 2024 12:43:38 +0000 Subject: [PATCH 38/62] Fix export of get_geometry() and get_composition() --- makie_post_processing/makie_post_processing/src/shared_utils.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/makie_post_processing/makie_post_processing/src/shared_utils.jl b/makie_post_processing/makie_post_processing/src/shared_utils.jl index 076e8010e..bdaf99e53 100644 --- a/makie_post_processing/makie_post_processing/src/shared_utils.jl +++ b/makie_post_processing/makie_post_processing/src/shared_utils.jl @@ -1,6 +1,6 @@ module shared_utils -export calculate_and_write_frequencies, get_geometry_and_composition +export calculate_and_write_frequencies, get_geometry, get_composition using moment_kinetics.analysis: fit_delta_phi_mode using moment_kinetics.array_allocation: allocate_float From e0ef45291e85703115be046089b79184e3e74cb9 Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Sun, 4 Feb 2024 10:24:09 +0000 Subject: [PATCH 39/62] Modify how run_mms_test() is imported to reflect new package structure. --- run_MMS_test.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/run_MMS_test.jl b/run_MMS_test.jl index e7e43ae61..206b0df45 100644 --- a/run_MMS_test.jl +++ b/run_MMS_test.jl @@ -1,7 +1,7 @@ if abspath(PROGRAM_FILE) == @__FILE__ using Pkg Pkg.activate(".") - import moment_kinetics - using moment_kinetics.plot_MMS_sequence + import plots_post_processing + using plots_post_processing.plot_MMS_sequence run_mms_test() end From d8a6f0f8342b56012fd050e48b9213abd666a13c Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Sun, 4 Feb 2024 10:24:33 +0000 Subject: [PATCH 40/62] Add option for 2D2V mirror test. --- .../src/plot_MMS_sequence.jl | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/plots_post_processing/plots_post_processing/src/plot_MMS_sequence.jl b/plots_post_processing/plots_post_processing/src/plot_MMS_sequence.jl index 919f340ed..8654144b0 100644 --- a/plots_post_processing/plots_post_processing/src/plot_MMS_sequence.jl +++ b/plots_post_processing/plots_post_processing/src/plot_MMS_sequence.jl @@ -143,6 +143,13 @@ function get_MMS_error_data(path_list,scan_type,scan_name) else println("ERROR: scan_type = ",scan_type," requires vpa_nelement = 2.0*vperp_nelement = z_nelement") end + elseif scan_type == "vpa2vperpzr_nelement" + nelement = z_nelement + if nelement == vpa_nelement && nelement == 2*vperp_nelement && nelement == r_nelement + nelement_sequence[isim] = nelement + else + println("ERROR: scan_type = ",scan_type," requires vpa_nelement = 2.0*vperp_nelement = z_nelement = r_nelement") + end elseif scan_type == "vpaz_nelement" nelement = z_nelement if nelement == vpa_nelement @@ -346,6 +353,8 @@ function get_MMS_error_data(path_list,scan_type,scan_name) xlabel = L"N_{element}(z) = N_{element}(v_\perp) = N_{element}(v_{||})" elseif scan_type == "vpa2vperpz_nelement" xlabel = L"N_{element}(z) = 2N_{element}(v_\perp) = N_{element}(v_{||})" + elseif scan_type == "vpa2vperpzr_nelement" + xlabel = L"N_{element}(z) = N_{element}(r) = 2N_{element}(v_\perp) = N_{element}(v_{||})" elseif scan_type == "vpazr_nelement0.25" xlabel = L"N_{element}(z) = N_{element}(r) = N_{element}(v_{||})/4" elseif scan_type == "vpaz_nelement0.25" @@ -511,7 +520,8 @@ function run_mms_test() #test_option = "collisionless_wall-1D-1V-constant-Er-ngrid-5-opt" #test_option = "krook_wall-1D-2V" #test_option = "mirror_wall-1D-2V" - test_option = "mirror_wall-1D-2V-ngrid-5" + #test_option = "mirror_wall-1D-2V-ngrid-5" + test_option = "mirror_wall-2D-2V-ngrid-5" #test_option = "collisionless_wall-1D-3V" #test_option = "collisionless_wall-2D-3V" #test_option = "collisionless_wall-2D-3V-Er-zero-at-plate" @@ -691,6 +701,14 @@ function run_mms_test() "runs/1D-mirror_MMS_ngrid_5_nel_r_1_z_64_vpa_64_vperp_32_diss",] scan_type = "vpa2vperpz_nelement" scan_name = "mirror_wall-1D-2V-ngrid-5" + elseif test_option == "mirror_wall-2D-2V-ngrid-5" + # Mirror wall test, no sheath for electrons, no radial coordinate + path_list = ["runs/2D-mirror_MMS_ngrid_5_nel_r_4_z_4_vpa_4_vperp_2_diss", + "runs/2D-mirror_MMS_ngrid_5_nel_r_8_z_8_vpa_8_vperp_4_diss", + "runs/2D-mirror_MMS_ngrid_5_nel_r_16_z_16_vpa_16_vperp_8_diss", + "runs/2D-mirror_MMS_ngrid_5_nel_r_32_z_32_vpa_32_vperp_16_diss",] + scan_type = "vpa2vperpzr_nelement" + scan_name = "mirror_wall-2D-2V-ngrid-5" end print(path_list) get_MMS_error_data(path_list,scan_type,scan_name) From 514284726586484130fac3c59c618bd06a82258f Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Sun, 4 Feb 2024 21:19:02 +0000 Subject: [PATCH 41/62] Input files for MMS test with a 1D mirror geometry and a radial dimension. --- ...d_5_nel_r_16_z_16_vpa_16_vperp_8_diss.toml | 99 +++++++++++++++++++ ..._5_nel_r_32_z_32_vpa_32_vperp_16_diss.toml | 99 +++++++++++++++++++ ...grid_5_nel_r_4_z_4_vpa_4_vperp_2_diss.toml | 99 +++++++++++++++++++ ...grid_5_nel_r_8_z_8_vpa_8_vperp_4_diss.toml | 99 +++++++++++++++++++ 4 files changed, 396 insertions(+) create mode 100644 runs/2D-mirror_MMS_ngrid_5_nel_r_16_z_16_vpa_16_vperp_8_diss.toml create mode 100644 runs/2D-mirror_MMS_ngrid_5_nel_r_32_z_32_vpa_32_vperp_16_diss.toml create mode 100644 runs/2D-mirror_MMS_ngrid_5_nel_r_4_z_4_vpa_4_vperp_2_diss.toml create mode 100644 runs/2D-mirror_MMS_ngrid_5_nel_r_8_z_8_vpa_8_vperp_4_diss.toml diff --git a/runs/2D-mirror_MMS_ngrid_5_nel_r_16_z_16_vpa_16_vperp_8_diss.toml b/runs/2D-mirror_MMS_ngrid_5_nel_r_16_z_16_vpa_16_vperp_8_diss.toml new file mode 100644 index 000000000..69385dc8b --- /dev/null +++ b/runs/2D-mirror_MMS_ngrid_5_nel_r_16_z_16_vpa_16_vperp_8_diss.toml @@ -0,0 +1,99 @@ +n_ion_species = 1 +n_neutral_species = 0 +electron_physics = "boltzmann_electron_response" +#electron_physics = "boltzmann_electron_response_with_simple_sheath" +evolve_moments_density = false +evolve_moments_parallel_flow = false +evolve_moments_parallel_pressure = false +evolve_moments_conservation = false +force_Er_zero_at_wall = false #true +geometry_option="1D-mirror" +DeltaB=0.5 +#geometry_option="constant-helical" +#pitch=1.0 +Er_constant = 0.0 +T_e = 1.0 +T_wall = 1.0 +rhostar = 1.0 +initial_density1 = 0.5 +initial_temperature1 = 1.0 +initial_density2 = 0.5 +initial_temperature2 = 1.0 +z_IC_option1 = "sinusoid" +z_IC_density_amplitude1 = 0.001 +z_IC_density_phase1 = 0.0 +z_IC_upar_amplitude1 = 0.0 +z_IC_upar_phase1 = 0.0 +z_IC_temperature_amplitude1 = 0.0 +z_IC_temperature_phase1 = 0.0 +z_IC_option2 = "sinusoid" +z_IC_density_amplitude2 = 0.001 +z_IC_density_phase2 = 0.0 +z_IC_upar_amplitude2 = 0.0 +z_IC_upar_phase2 = 0.0 +z_IC_temperature_amplitude2 = 0.0 +z_IC_temperature_phase2 = 0.0 +charge_exchange_frequency = 0.0 +ionization_frequency = 0.0 +nstep = 2000 +dt = 0.0005 +nwrite = 200 +nwrite_dfns = 200 +use_semi_lagrange = false +n_rk_stages = 4 +split_operators = false +z_ngrid = 5 +z_nelement = 16 +z_nelement_local = 16 +z_bc = "wall" +z_discretization = "chebyshev_pseudospectral" +r_ngrid = 5 +r_nelement = 16 +r_nelement_local = 16 +r_bc = "periodic" +r_discretization = "chebyshev_pseudospectral" +vpa_ngrid = 5 +vpa_nelement = 16 +vpa_L = 12.0 +vpa_bc = "zero" +vpa_discretization = "chebyshev_pseudospectral" +vperp_ngrid = 5 +vperp_nelement = 8 +vperp_L = 6.0 +#vperp_discretization = "finite_difference" +#vperp_discretization = "chebyshev_pseudospectral" +vperp_discretization = "gausslegendre_pseudospectral" +vperp_bc = "zero" + +vz_ngrid = 17 +vz_nelement = 4 +vz_L = 12.0 +vz_bc = "periodic" +vz_discretization = "chebyshev_pseudospectral" + +vr_ngrid = 17 +vr_nelement = 4 +vr_L = 12.0 +vr_bc = "periodic" +vr_discretization = "chebyshev_pseudospectral" + +vzeta_ngrid = 17 +vzeta_nelement = 4 +vzeta_L = 12.0 +vzeta_bc = "periodic" +vzeta_discretization = "chebyshev_pseudospectral" + +[manufactured_solns] + use_for_advance=true + use_for_init=true + # constant to be used to control Ez divergence in MMS tests + epsilon_offset=0.1 + # bool to control if dfni is a function of vpa or vpabar in MMS test + use_vpabar_in_mms_dfni=true + alpha_switch=1.0 + type="default" +[numerical_dissipation] +vpa_dissipation_coefficient = 0.001 +vperp_dissipation_coefficient = 0.001 +#z_dissipation_coefficient = 0.1 +r_dissipation_coefficient = 0.01 diff --git a/runs/2D-mirror_MMS_ngrid_5_nel_r_32_z_32_vpa_32_vperp_16_diss.toml b/runs/2D-mirror_MMS_ngrid_5_nel_r_32_z_32_vpa_32_vperp_16_diss.toml new file mode 100644 index 000000000..00bc073ff --- /dev/null +++ b/runs/2D-mirror_MMS_ngrid_5_nel_r_32_z_32_vpa_32_vperp_16_diss.toml @@ -0,0 +1,99 @@ +n_ion_species = 1 +n_neutral_species = 0 +electron_physics = "boltzmann_electron_response" +#electron_physics = "boltzmann_electron_response_with_simple_sheath" +evolve_moments_density = false +evolve_moments_parallel_flow = false +evolve_moments_parallel_pressure = false +evolve_moments_conservation = false +force_Er_zero_at_wall = false #true +geometry_option="1D-mirror" +DeltaB=0.5 +#geometry_option="constant-helical" +#pitch=1.0 +Er_constant = 0.0 +T_e = 1.0 +T_wall = 1.0 +rhostar = 1.0 +initial_density1 = 0.5 +initial_temperature1 = 1.0 +initial_density2 = 0.5 +initial_temperature2 = 1.0 +z_IC_option1 = "sinusoid" +z_IC_density_amplitude1 = 0.001 +z_IC_density_phase1 = 0.0 +z_IC_upar_amplitude1 = 0.0 +z_IC_upar_phase1 = 0.0 +z_IC_temperature_amplitude1 = 0.0 +z_IC_temperature_phase1 = 0.0 +z_IC_option2 = "sinusoid" +z_IC_density_amplitude2 = 0.001 +z_IC_density_phase2 = 0.0 +z_IC_upar_amplitude2 = 0.0 +z_IC_upar_phase2 = 0.0 +z_IC_temperature_amplitude2 = 0.0 +z_IC_temperature_phase2 = 0.0 +charge_exchange_frequency = 0.0 +ionization_frequency = 0.0 +nstep = 2000 +dt = 0.0005 +nwrite = 200 +nwrite_dfns = 200 +use_semi_lagrange = false +n_rk_stages = 4 +split_operators = false +z_ngrid = 5 +z_nelement = 32 +z_nelement_local = 32 +z_bc = "wall" +z_discretization = "chebyshev_pseudospectral" +r_ngrid = 5 +r_nelement = 32 +r_nelement_local = 32 +r_bc = "periodic" +r_discretization = "chebyshev_pseudospectral" +vpa_ngrid = 5 +vpa_nelement = 32 +vpa_L = 12.0 +vpa_bc = "zero" +vpa_discretization = "chebyshev_pseudospectral" +vperp_ngrid = 5 +vperp_nelement = 16 +vperp_L = 6.0 +#vperp_discretization = "finite_difference" +#vperp_discretization = "chebyshev_pseudospectral" +vperp_discretization = "gausslegendre_pseudospectral" +vperp_bc = "zero" + +vz_ngrid = 17 +vz_nelement = 4 +vz_L = 12.0 +vz_bc = "periodic" +vz_discretization = "chebyshev_pseudospectral" + +vr_ngrid = 17 +vr_nelement = 4 +vr_L = 12.0 +vr_bc = "periodic" +vr_discretization = "chebyshev_pseudospectral" + +vzeta_ngrid = 17 +vzeta_nelement = 4 +vzeta_L = 12.0 +vzeta_bc = "periodic" +vzeta_discretization = "chebyshev_pseudospectral" + +[manufactured_solns] + use_for_advance=true + use_for_init=true + # constant to be used to control Ez divergence in MMS tests + epsilon_offset=0.1 + # bool to control if dfni is a function of vpa or vpabar in MMS test + use_vpabar_in_mms_dfni=true + alpha_switch=1.0 + type="default" +[numerical_dissipation] +vpa_dissipation_coefficient = 0.001 +vperp_dissipation_coefficient = 0.001 +#z_dissipation_coefficient = 0.1 +r_dissipation_coefficient = 0.01 diff --git a/runs/2D-mirror_MMS_ngrid_5_nel_r_4_z_4_vpa_4_vperp_2_diss.toml b/runs/2D-mirror_MMS_ngrid_5_nel_r_4_z_4_vpa_4_vperp_2_diss.toml new file mode 100644 index 000000000..099d42d59 --- /dev/null +++ b/runs/2D-mirror_MMS_ngrid_5_nel_r_4_z_4_vpa_4_vperp_2_diss.toml @@ -0,0 +1,99 @@ +n_ion_species = 1 +n_neutral_species = 0 +electron_physics = "boltzmann_electron_response" +#electron_physics = "boltzmann_electron_response_with_simple_sheath" +evolve_moments_density = false +evolve_moments_parallel_flow = false +evolve_moments_parallel_pressure = false +evolve_moments_conservation = false +force_Er_zero_at_wall = false #true +geometry_option="1D-mirror" +DeltaB=0.5 +#geometry_option="constant-helical" +#pitch=1.0 +Er_constant = 0.0 +T_e = 1.0 +T_wall = 1.0 +rhostar = 1.0 +initial_density1 = 0.5 +initial_temperature1 = 1.0 +initial_density2 = 0.5 +initial_temperature2 = 1.0 +z_IC_option1 = "sinusoid" +z_IC_density_amplitude1 = 0.001 +z_IC_density_phase1 = 0.0 +z_IC_upar_amplitude1 = 0.0 +z_IC_upar_phase1 = 0.0 +z_IC_temperature_amplitude1 = 0.0 +z_IC_temperature_phase1 = 0.0 +z_IC_option2 = "sinusoid" +z_IC_density_amplitude2 = 0.001 +z_IC_density_phase2 = 0.0 +z_IC_upar_amplitude2 = 0.0 +z_IC_upar_phase2 = 0.0 +z_IC_temperature_amplitude2 = 0.0 +z_IC_temperature_phase2 = 0.0 +charge_exchange_frequency = 0.0 +ionization_frequency = 0.0 +nstep = 2000 +dt = 0.0005 +nwrite = 200 +nwrite_dfns = 200 +use_semi_lagrange = false +n_rk_stages = 4 +split_operators = false +z_ngrid = 5 +z_nelement = 4 +z_nelement_local = 4 +z_bc = "wall" +z_discretization = "chebyshev_pseudospectral" +r_ngrid = 5 +r_nelement = 4 +r_nelement_local = 4 +r_bc = "periodic" +r_discretization = "chebyshev_pseudospectral" +vpa_ngrid = 5 +vpa_nelement = 4 +vpa_L = 12.0 +vpa_bc = "zero" +vpa_discretization = "chebyshev_pseudospectral" +vperp_ngrid = 5 +vperp_nelement = 2 +vperp_L = 6.0 +#vperp_discretization = "finite_difference" +#vperp_discretization = "chebyshev_pseudospectral" +vperp_discretization = "gausslegendre_pseudospectral" +vperp_bc = "zero" + +vz_ngrid = 17 +vz_nelement = 4 +vz_L = 12.0 +vz_bc = "periodic" +vz_discretization = "chebyshev_pseudospectral" + +vr_ngrid = 17 +vr_nelement = 4 +vr_L = 12.0 +vr_bc = "periodic" +vr_discretization = "chebyshev_pseudospectral" + +vzeta_ngrid = 17 +vzeta_nelement = 4 +vzeta_L = 12.0 +vzeta_bc = "periodic" +vzeta_discretization = "chebyshev_pseudospectral" + +[manufactured_solns] + use_for_advance=true + use_for_init=true + # constant to be used to control Ez divergence in MMS tests + epsilon_offset=0.1 + # bool to control if dfni is a function of vpa or vpabar in MMS test + use_vpabar_in_mms_dfni=true + alpha_switch=1.0 + type="default" +[numerical_dissipation] +vpa_dissipation_coefficient = 0.001 +vperp_dissipation_coefficient = 0.001 +#z_dissipation_coefficient = 0.1 +r_dissipation_coefficient = 0.01 diff --git a/runs/2D-mirror_MMS_ngrid_5_nel_r_8_z_8_vpa_8_vperp_4_diss.toml b/runs/2D-mirror_MMS_ngrid_5_nel_r_8_z_8_vpa_8_vperp_4_diss.toml new file mode 100644 index 000000000..1b7fd2fc6 --- /dev/null +++ b/runs/2D-mirror_MMS_ngrid_5_nel_r_8_z_8_vpa_8_vperp_4_diss.toml @@ -0,0 +1,99 @@ +n_ion_species = 1 +n_neutral_species = 0 +electron_physics = "boltzmann_electron_response" +#electron_physics = "boltzmann_electron_response_with_simple_sheath" +evolve_moments_density = false +evolve_moments_parallel_flow = false +evolve_moments_parallel_pressure = false +evolve_moments_conservation = false +force_Er_zero_at_wall = false #true +geometry_option="1D-mirror" +DeltaB=0.5 +#geometry_option="constant-helical" +#pitch=1.0 +Er_constant = 0.0 +T_e = 1.0 +T_wall = 1.0 +rhostar = 1.0 +initial_density1 = 0.5 +initial_temperature1 = 1.0 +initial_density2 = 0.5 +initial_temperature2 = 1.0 +z_IC_option1 = "sinusoid" +z_IC_density_amplitude1 = 0.001 +z_IC_density_phase1 = 0.0 +z_IC_upar_amplitude1 = 0.0 +z_IC_upar_phase1 = 0.0 +z_IC_temperature_amplitude1 = 0.0 +z_IC_temperature_phase1 = 0.0 +z_IC_option2 = "sinusoid" +z_IC_density_amplitude2 = 0.001 +z_IC_density_phase2 = 0.0 +z_IC_upar_amplitude2 = 0.0 +z_IC_upar_phase2 = 0.0 +z_IC_temperature_amplitude2 = 0.0 +z_IC_temperature_phase2 = 0.0 +charge_exchange_frequency = 0.0 +ionization_frequency = 0.0 +nstep = 2000 +dt = 0.0005 +nwrite = 200 +nwrite_dfns = 200 +use_semi_lagrange = false +n_rk_stages = 4 +split_operators = false +z_ngrid = 5 +z_nelement = 8 +z_nelement_local = 8 +z_bc = "wall" +z_discretization = "chebyshev_pseudospectral" +r_ngrid = 5 +r_nelement = 8 +r_nelement_local = 8 +r_bc = "periodic" +r_discretization = "chebyshev_pseudospectral" +vpa_ngrid = 5 +vpa_nelement = 8 +vpa_L = 12.0 +vpa_bc = "zero" +vpa_discretization = "chebyshev_pseudospectral" +vperp_ngrid = 5 +vperp_nelement = 4 +vperp_L = 6.0 +#vperp_discretization = "finite_difference" +#vperp_discretization = "chebyshev_pseudospectral" +vperp_discretization = "gausslegendre_pseudospectral" +vperp_bc = "zero" + +vz_ngrid = 17 +vz_nelement = 4 +vz_L = 12.0 +vz_bc = "periodic" +vz_discretization = "chebyshev_pseudospectral" + +vr_ngrid = 17 +vr_nelement = 4 +vr_L = 12.0 +vr_bc = "periodic" +vr_discretization = "chebyshev_pseudospectral" + +vzeta_ngrid = 17 +vzeta_nelement = 4 +vzeta_L = 12.0 +vzeta_bc = "periodic" +vzeta_discretization = "chebyshev_pseudospectral" + +[manufactured_solns] + use_for_advance=true + use_for_init=true + # constant to be used to control Ez divergence in MMS tests + epsilon_offset=0.1 + # bool to control if dfni is a function of vpa or vpabar in MMS test + use_vpabar_in_mms_dfni=true + alpha_switch=1.0 + type="default" +[numerical_dissipation] +vpa_dissipation_coefficient = 0.001 +vperp_dissipation_coefficient = 0.001 +#z_dissipation_coefficient = 0.1 +r_dissipation_coefficient = 0.01 From 0acbf8cfc93876fb49040d752f02825ed1e66e10 Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Mon, 5 Feb 2024 09:42:36 +0000 Subject: [PATCH 42/62] Fokker Planck relaxation example with the same resolutions as used for the ExCALIBUR report. --- ...-planck-relaxation-report-resolutions.toml | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 examples/fokker-planck/fokker-planck-relaxation-report-resolutions.toml diff --git a/examples/fokker-planck/fokker-planck-relaxation-report-resolutions.toml b/examples/fokker-planck/fokker-planck-relaxation-report-resolutions.toml new file mode 100644 index 000000000..2807ea335 --- /dev/null +++ b/examples/fokker-planck/fokker-planck-relaxation-report-resolutions.toml @@ -0,0 +1,65 @@ +# cheap input file for a 0D2V relaxation to a collisional Maxwellian distribution with self-ion collisions. +n_ion_species = 1 +n_neutral_species = 0 +electron_physics = "boltzmann_electron_response" +evolve_moments_density = false +evolve_moments_parallel_flow = false +evolve_moments_parallel_pressure = false +evolve_moments_conservation = false +T_e = 1.0 +T_wall = 1.0 +rhostar = 1.0 +Bzed = 1.0 +Bmag = 1.0 +initial_density1 = 0.5 +initial_temperature1 = 1.0 +initial_density2 = 0.5 +initial_temperature2 = 1.0 +z_IC_option1 = "sinusoid" +z_IC_density_amplitude1 = 0.001 +z_IC_density_phase1 = 0.0 +z_IC_upar_amplitude1 = 0.0 +z_IC_upar_phase1 = 0.0 +z_IC_temperature_amplitude1 = 0.0 +z_IC_temperature_phase1 = 0.0 +z_IC_option2 = "sinusoid" +z_IC_density_amplitude2 = 0.001 +z_IC_density_phase2 = 0.0 +z_IC_upar_amplitude2 = 0.0 +z_IC_upar_phase2 = 0.0 +z_IC_temperature_amplitude2 = 0.0 +z_IC_temperature_phase2 = 0.0 +charge_exchange_frequency = 0.0 +ionization_frequency = 0.0 +constant_ionization_rate = false +# nuii sets the normalised input C[F,F] Fokker-Planck collision frequency +nuii = 1.0 +nstep = 200000 +dt = 1.0e-3 +nwrite = 50 +nwrite_dfns = 50 +use_semi_lagrange = false +n_rk_stages = 4 +split_operators = false +z_ngrid = 1 +z_nelement = 1 +z_nelement_local = 1 +z_bc = "wall" +z_discretization = "chebyshev_pseudospectral" +r_ngrid = 1 +r_nelement = 1 +r_nelement_local = 1 +r_bc = "periodic" +r_discretization = "chebyshev_pseudospectral" +vpa_ngrid = 5 +vpa_nelement = 8 +vpa_L = 6.0 +vpa_bc = "zero" +vpa_discretization = "gausslegendre_pseudospectral" +vperp_ngrid = 5 +vperp_nelement = 4 +vperp_L = 3.0 +vperp_discretization = "gausslegendre_pseudospectral" +# Fokker-Planck operator requires the "gausslegendre_pseudospectral +# options for the vpa and vperp grids + From 9ff5669899302e419fc1d97580ccc8f82cf85405 Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Mon, 5 Feb 2024 14:58:20 +0000 Subject: [PATCH 43/62] Expected scaling for 2D2V plot. --- .../plots_post_processing/src/plot_MMS_sequence.jl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plots_post_processing/plots_post_processing/src/plot_MMS_sequence.jl b/plots_post_processing/plots_post_processing/src/plot_MMS_sequence.jl index 8654144b0..41eaebd38 100644 --- a/plots_post_processing/plots_post_processing/src/plot_MMS_sequence.jl +++ b/plots_post_processing/plots_post_processing/src/plot_MMS_sequence.jl @@ -392,6 +392,8 @@ function get_MMS_error_data(path_list,scan_type,scan_name) elseif scan_name == "2D-1V-wall_cheb" || scan_name == "2D-1V-wall_cheb-nonzero-Er" || scan_name == "1D-1V-wall_cheb-constant-Er-ngrid-5-opt" ytick_sequence = Array([1.0e-8,1.0e-7,1.0e-6,1.0e-5,1.0e-4,1.0e-3,1.0e-2,1.0e-1,1.0e-0]) #ytick_sequence = Array([1.0e-5,1.0e-4,1.0e-3,1.0e-2,1.0e-1,1.0e-0]) + elseif scan_name == "mirror_wall-2D-2V-ngrid-5" + ytick_sequence = Array([1.0e-6,1.0e-5,1.0e-4,1.0e-3,1.0e-2,1.0e-1,1.0e-0,1.0e1]) else ytick_sequence = Array([1.0e-7,1.0e-6,1.0e-5,1.0e-4,1.0e-3,1.0e-2,1.0e-1,1.0e-0,1.0e1]) end @@ -438,8 +440,8 @@ function get_MMS_error_data(path_list,scan_type,scan_name) println(outfile) try - plot(nelement_sequence, [ion_density_error_sequence,phi_error_sequence,Ez_error_sequence,Er_error_sequence,ion_pdf_error_sequence], xlabel=xlabel, - label=[ylabel_ion_density ylabel_phi ylabel_Ez ylabel_Er ylabel_ion_pdf], ylabel="", + plot(nelement_sequence, [ion_density_error_sequence,phi_error_sequence,Ez_error_sequence,Er_error_sequence,ion_pdf_error_sequence,expected_scaling], xlabel=xlabel, + label=[ylabel_ion_density ylabel_phi ylabel_Ez ylabel_Er ylabel_ion_pdf expected_label], ylabel="", shape =:circle, xscale=:log10, yscale=:log10, xticks = (nelement_sequence, nelement_sequence), yticks = (ytick_sequence, ytick_sequence), markersize = 5, linewidth=2, xtickfontsize = fontsize, xguidefontsize = fontsize, ytickfontsize = fontsize, yguidefontsize = fontsize, legendfontsize = fontsize, foreground_color_legend = nothing, background_color_legend = nothing, legend=:bottomleft) From 5abac5ee19375533809c55a3750b4e61d7292f61 Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Tue, 6 Feb 2024 16:13:57 +0000 Subject: [PATCH 44/62] Remove unnecessary packages. --- test_scripts/chebyshev_radau_test.jl | 3 --- 1 file changed, 3 deletions(-) diff --git a/test_scripts/chebyshev_radau_test.jl b/test_scripts/chebyshev_radau_test.jl index 50c2222de..c06b8bd00 100644 --- a/test_scripts/chebyshev_radau_test.jl +++ b/test_scripts/chebyshev_radau_test.jl @@ -1,10 +1,7 @@ export chebyshevradau_test using Printf -using Plots -using LaTeXStrings using MPI -using Measures import moment_kinetics using moment_kinetics.chebyshev From 9330f25989d522aeb81befb953ce757d97573127 Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Tue, 6 Feb 2024 16:17:43 +0000 Subject: [PATCH 45/62] Change the specification of the magnetic geometry to add a finite bzeta to the 1D mirror option to allow a nonzero ExB drift to emerge in 2D simulations. --- moment_kinetics/ext/manufactured_solns_ext.jl | 6 +++--- moment_kinetics/src/geo.jl | 5 +++-- ...mirror_MMS_ngrid_9_nel_r_1_z_16_vpa_16_vperp_8_diss.toml | 2 +- ...irror_MMS_ngrid_9_nel_r_1_z_32_vpa_32_vperp_16_diss.toml | 2 +- ...D-mirror_MMS_ngrid_9_nel_r_1_z_4_vpa_4_vperp_2_diss.toml | 2 +- ...irror_MMS_ngrid_9_nel_r_1_z_64_vpa_64_vperp_32_diss.toml | 2 +- ...D-mirror_MMS_ngrid_9_nel_r_1_z_8_vpa_8_vperp_4_diss.toml | 2 +- ...irror_MMS_ngrid_5_nel_r_16_z_16_vpa_16_vperp_8_diss.toml | 2 +- ...rror_MMS_ngrid_5_nel_r_32_z_32_vpa_32_vperp_16_diss.toml | 2 +- ...D-mirror_MMS_ngrid_5_nel_r_4_z_4_vpa_4_vperp_2_diss.toml | 2 +- ...D-mirror_MMS_ngrid_5_nel_r_8_z_8_vpa_8_vperp_4_diss.toml | 2 +- 11 files changed, 15 insertions(+), 14 deletions(-) diff --git a/moment_kinetics/ext/manufactured_solns_ext.jl b/moment_kinetics/ext/manufactured_solns_ext.jl index 7a43d0e94..2bad8dcf0 100644 --- a/moment_kinetics/ext/manufactured_solns_ext.jl +++ b/moment_kinetics/ext/manufactured_solns_ext.jl @@ -61,8 +61,8 @@ using IfElse # compute symbolic geometry functions option = geometry_input_data.option rhostar = geometry_input_data.rhostar + pitch = geometry_input_data.pitch if option == "constant-helical" || option == "default" - pitch = geometry_input_data.pitch bzed = pitch bzeta = sqrt(1 - bzed^2) Bmag = 1.0 @@ -73,8 +73,8 @@ using IfElse jacobian = 1.0 elseif option == "1D-mirror" DeltaB = geometry_input_data.DeltaB - bzed = 1.0 - bzeta = 0.0 + bzed = pitch + bzeta = sqrt(1 - bzed^2) # B(z)/Bref = 1 + DeltaB*( 2(2z/L)^2 - (2z/L)^4) # chosen so that # B(z)/Bref = 1 + DeltaB at 2z/L = +- 1 diff --git a/moment_kinetics/src/geo.jl b/moment_kinetics/src/geo.jl index 2045be042..a940e5455 100644 --- a/moment_kinetics/src/geo.jl +++ b/moment_kinetics/src/geo.jl @@ -114,10 +114,11 @@ function init_magnetic_geometry(geometry_input_data::geometry_input,z,r) if DeltaB < -0.99999999 input_option_error("$option: You have specified DeltaB < -1 -> set DeltaB > -1", option) end + pitch = geometry_input_data.pitch for ir in 1:nr for iz in 1:nz - bzed[iz,ir] = 1.0 - bzeta[iz,ir] = 0.0 + bzed[iz,ir] = pitch + bzeta[iz,ir] = sqrt(1 - bzed[iz,ir]^2) # B(z)/Bref = 1 + DeltaB*( 2(2z/L)^2 - (2z/L)^4) # chosen so that # B(z)/Bref = 1 + DeltaB at 2z/L = +- 1 diff --git a/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_16_vpa_16_vperp_8_diss.toml b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_16_vpa_16_vperp_8_diss.toml index 6f0ef7638..3cd1c515d 100644 --- a/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_16_vpa_16_vperp_8_diss.toml +++ b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_16_vpa_16_vperp_8_diss.toml @@ -10,7 +10,7 @@ force_Er_zero_at_wall = false #true geometry_option="1D-mirror" DeltaB=0.5 #geometry_option="constant-helical" -#pitch=1.0 +pitch=1.0 Er_constant = 0.0 T_e = 1.0 T_wall = 1.0 diff --git a/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_32_vpa_32_vperp_16_diss.toml b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_32_vpa_32_vperp_16_diss.toml index 4165b2d36..3c1684c52 100644 --- a/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_32_vpa_32_vperp_16_diss.toml +++ b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_32_vpa_32_vperp_16_diss.toml @@ -10,7 +10,7 @@ force_Er_zero_at_wall = false #true geometry_option="1D-mirror" DeltaB=0.5 #geometry_option="constant-helical" -#pitch=1.0 +pitch=1.0 Er_constant = 0.0 T_e = 1.0 T_wall = 1.0 diff --git a/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_4_vpa_4_vperp_2_diss.toml b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_4_vpa_4_vperp_2_diss.toml index 7ea665889..32188a931 100644 --- a/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_4_vpa_4_vperp_2_diss.toml +++ b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_4_vpa_4_vperp_2_diss.toml @@ -10,7 +10,7 @@ force_Er_zero_at_wall = false #true geometry_option="1D-mirror" DeltaB=0.5 #geometry_option="constant-helical" -#pitch=1.0 +pitch=1.0 Er_constant = 0.0 T_e = 1.0 T_wall = 1.0 diff --git a/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_64_vpa_64_vperp_32_diss.toml b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_64_vpa_64_vperp_32_diss.toml index da3b6cf09..e45a96c52 100644 --- a/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_64_vpa_64_vperp_32_diss.toml +++ b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_64_vpa_64_vperp_32_diss.toml @@ -10,7 +10,7 @@ force_Er_zero_at_wall = false #true geometry_option="1D-mirror" DeltaB=0.5 #geometry_option="constant-helical" -#pitch=1.0 +pitch=1.0 Er_constant = 0.0 T_e = 1.0 T_wall = 1.0 diff --git a/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_8_vpa_8_vperp_4_diss.toml b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_8_vpa_8_vperp_4_diss.toml index e815c3be6..c25e70d0d 100644 --- a/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_8_vpa_8_vperp_4_diss.toml +++ b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_8_vpa_8_vperp_4_diss.toml @@ -10,7 +10,7 @@ force_Er_zero_at_wall = false #true geometry_option="1D-mirror" DeltaB=0.5 #geometry_option="constant-helical" -#pitch=1.0 +pitch=1.0 Er_constant = 0.0 T_e = 1.0 T_wall = 1.0 diff --git a/runs/2D-mirror_MMS_ngrid_5_nel_r_16_z_16_vpa_16_vperp_8_diss.toml b/runs/2D-mirror_MMS_ngrid_5_nel_r_16_z_16_vpa_16_vperp_8_diss.toml index 69385dc8b..9bc5f0d5b 100644 --- a/runs/2D-mirror_MMS_ngrid_5_nel_r_16_z_16_vpa_16_vperp_8_diss.toml +++ b/runs/2D-mirror_MMS_ngrid_5_nel_r_16_z_16_vpa_16_vperp_8_diss.toml @@ -10,7 +10,7 @@ force_Er_zero_at_wall = false #true geometry_option="1D-mirror" DeltaB=0.5 #geometry_option="constant-helical" -#pitch=1.0 +pitch=0.5 Er_constant = 0.0 T_e = 1.0 T_wall = 1.0 diff --git a/runs/2D-mirror_MMS_ngrid_5_nel_r_32_z_32_vpa_32_vperp_16_diss.toml b/runs/2D-mirror_MMS_ngrid_5_nel_r_32_z_32_vpa_32_vperp_16_diss.toml index 00bc073ff..864b91acf 100644 --- a/runs/2D-mirror_MMS_ngrid_5_nel_r_32_z_32_vpa_32_vperp_16_diss.toml +++ b/runs/2D-mirror_MMS_ngrid_5_nel_r_32_z_32_vpa_32_vperp_16_diss.toml @@ -10,7 +10,7 @@ force_Er_zero_at_wall = false #true geometry_option="1D-mirror" DeltaB=0.5 #geometry_option="constant-helical" -#pitch=1.0 +pitch=0.5 Er_constant = 0.0 T_e = 1.0 T_wall = 1.0 diff --git a/runs/2D-mirror_MMS_ngrid_5_nel_r_4_z_4_vpa_4_vperp_2_diss.toml b/runs/2D-mirror_MMS_ngrid_5_nel_r_4_z_4_vpa_4_vperp_2_diss.toml index 099d42d59..aabf1ab4b 100644 --- a/runs/2D-mirror_MMS_ngrid_5_nel_r_4_z_4_vpa_4_vperp_2_diss.toml +++ b/runs/2D-mirror_MMS_ngrid_5_nel_r_4_z_4_vpa_4_vperp_2_diss.toml @@ -10,7 +10,7 @@ force_Er_zero_at_wall = false #true geometry_option="1D-mirror" DeltaB=0.5 #geometry_option="constant-helical" -#pitch=1.0 +pitch=0.5 Er_constant = 0.0 T_e = 1.0 T_wall = 1.0 diff --git a/runs/2D-mirror_MMS_ngrid_5_nel_r_8_z_8_vpa_8_vperp_4_diss.toml b/runs/2D-mirror_MMS_ngrid_5_nel_r_8_z_8_vpa_8_vperp_4_diss.toml index 1b7fd2fc6..f5220c537 100644 --- a/runs/2D-mirror_MMS_ngrid_5_nel_r_8_z_8_vpa_8_vperp_4_diss.toml +++ b/runs/2D-mirror_MMS_ngrid_5_nel_r_8_z_8_vpa_8_vperp_4_diss.toml @@ -10,7 +10,7 @@ force_Er_zero_at_wall = false #true geometry_option="1D-mirror" DeltaB=0.5 #geometry_option="constant-helical" -#pitch=1.0 +pitch=0.5 Er_constant = 0.0 T_e = 1.0 T_wall = 1.0 From d9b5aabe84530204104b4dd2a175b445df1d55ce Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Tue, 6 Feb 2024 16:19:40 +0000 Subject: [PATCH 46/62] Change comment to reflect correct definition of Jacobian. --- moment_kinetics/src/geo.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/moment_kinetics/src/geo.jl b/moment_kinetics/src/geo.jl index a940e5455..84808aea5 100644 --- a/moment_kinetics/src/geo.jl +++ b/moment_kinetics/src/geo.jl @@ -44,7 +44,7 @@ bzeta::Array{mk_float,2} dBdz::Array{mk_float,2} # d Bmag d r dBdr::Array{mk_float,2} -# jacobian = grad r x grad z . grad zeta +# jacobian = r grad r x grad z . grad zeta jacobian::Array{mk_float,2} # magnetic drift physics coefficients From d91aca721e781453c43258065a8120b7f9c32f12 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Wed, 13 Mar 2024 11:41:29 +0000 Subject: [PATCH 47/62] Create API docs page for `geo` module --- docs/src/zz_geo.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 docs/src/zz_geo.md diff --git a/docs/src/zz_geo.md b/docs/src/zz_geo.md new file mode 100644 index 000000000..c2608f8c5 --- /dev/null +++ b/docs/src/zz_geo.md @@ -0,0 +1,6 @@ +`geo` +===== + +```@autodocs +Modules = [moment_kinetics.geo] +``` From b52f9430a009702b61c1eb065bbb3d793bf7fc27 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Wed, 13 Mar 2024 12:15:36 +0000 Subject: [PATCH 48/62] Check for removed options: error telling user to update input file This feature is not ideal, as it gives the user no guidance on how to update the options to replace the removed ones, but better than nothing. --- moment_kinetics/src/moment_kinetics_input.jl | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/moment_kinetics/src/moment_kinetics_input.jl b/moment_kinetics/src/moment_kinetics_input.jl index 3d387e241..5ba6ec438 100644 --- a/moment_kinetics/src/moment_kinetics_input.jl +++ b/moment_kinetics/src/moment_kinetics_input.jl @@ -49,6 +49,17 @@ other situations (e.g. when post-processing). """ function mk_input(scan_input=Dict(); save_inputs_to_txt=false, ignore_MPI=true) + # Check for input options that used to exist, but do not any more. If these are + # present, the user probably needs to update their input file. + removed_options_list = ("Bzed", "Bmag") + for opt in removed_options_list + if opt ∈ keys(scan_input) + error("Option '$opt' is no longer used. Please update your input file. You " + * "may need to set some new options to replicate the effect of the " + * "removed ones.") + end + end + # n_ion_species is the number of evolved ion species # currently only n_ion_species = 1 is supported n_ion_species = get(scan_input, "n_ion_species", 1) @@ -102,18 +113,10 @@ function mk_input(scan_input=Dict(); save_inputs_to_txt=false, ignore_MPI=true) reference_params = setup_reference_parameters(scan_input) ## set geometry_input - #geometry.Bzed = get(scan_input, "Bzed", 1.0) - #geometry.Bmag = get(scan_input, "Bmag", 1.0) - #geometry.bzed = geometry.Bzed/geometry.Bmag - #geometry.bzeta = sqrt(1.0 - geometry.bzed^2.0) - #geometry.Bzeta = geometry.Bmag*geometry.bzeta geometry_in.option = get(scan_input, "geometry_option", "constant-helical") #"1D-mirror" geometry_in.pitch = get(scan_input, "pitch", 1.0) geometry_in.rhostar = get(scan_input, "rhostar", get_default_rhostar(reference_params)) geometry_in.DeltaB = get(scan_input, "DeltaB", 1.0) - #println("Info: Bzed is ",geometry.Bzed) - #println("Info: Bmag is ",geometry.Bmag) - #println("Info: rhostar is ",geometry.rhostar) ispecies = 1 species.charged[1].z_IC.initialization_option = get(scan_input, "z_IC_option$ispecies", "gaussian") From b3ad10bfffb7038173a764fc197f5f65a786f2a5 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Wed, 13 Mar 2024 12:29:43 +0000 Subject: [PATCH 49/62] Error if dBdz!=0 for moment-kinetic modes ...as mirror terms are not yet implemented in moment-kinetic modes. --- moment_kinetics/src/moment_kinetics_input.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/moment_kinetics/src/moment_kinetics_input.jl b/moment_kinetics/src/moment_kinetics_input.jl index 5ba6ec438..7c6c4cc2f 100644 --- a/moment_kinetics/src/moment_kinetics_input.jl +++ b/moment_kinetics/src/moment_kinetics_input.jl @@ -547,6 +547,9 @@ function mk_input(scan_input=Dict(); save_inputs_to_txt=false, ignore_MPI=true) end geometry = init_magnetic_geometry(geometry_in,z,r) + if any(geometry.dBdz .!= 0.0) && (evolve_density || evolve_upar || evolve_ppar) + error("Mirror terms not yet implemented for moment-kinetic modes") + end # check input (and initialized coordinate structs) to catch errors/unsupported options check_input(io, output_dir, nstep, dt, r, z, vpa, vperp, composition, From 347ff6b9b06a9f4f91d407d45ce5cb518245a1d1 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Wed, 13 Mar 2024 12:43:39 +0000 Subject: [PATCH 50/62] Remove debug print --- machines/shared/machine_setup.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/machines/shared/machine_setup.jl b/machines/shared/machine_setup.jl index c93696f78..51bb48ee9 100644 --- a/machines/shared/machine_setup.jl +++ b/machines/shared/machine_setup.jl @@ -301,7 +301,6 @@ function machine_setup_moment_kinetics(machine::String; no_force_exit::Bool=fals bindir = joinpath(repo_dir, "bin") mkpath(bindir) julia_executable_name = joinpath(bindir, "julia") - println("check use_plots=", mk_preferences["use_plots"], " ", mk_preferences["use_plots"] == "n") if batch_system || (julia_directory == "" && mk_preferences["use_plots"] == "n") # Make a local link to the Julia binary so scripts in the repo can find it println("\n** Making a symlink to the julia executable at bin/julia\n") From 9489a2f4f4e2aacda0141656cdc99a0f15e1c1b7 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Wed, 13 Mar 2024 12:44:04 +0000 Subject: [PATCH 51/62] Simplify 1D geometry check --- moment_kinetics/src/load_data.jl | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/moment_kinetics/src/load_data.jl b/moment_kinetics/src/load_data.jl index 6db676302..3ebbe06bf 100644 --- a/moment_kinetics/src/load_data.jl +++ b/moment_kinetics/src/load_data.jl @@ -624,13 +624,7 @@ function reload_evolving_fields!(pdf, moments, boundary_distributions, restart_p neutral_1V = (vzeta.n_global == 1 && vr.n_global == 1) restart_neutral_1V = (restart_vzeta.n_global == 1 && restart_vr.n_global == 1) - geo_condition = false - for ir in 1:r.n - for iz in 1:z.n - geo_condition = geo_condition || (geometry.bzeta[iz,ir] != 0.0) - end - end - if geo_condition && ((neutral1V && !restart_neutral_1V) || + if any(geometry.bzeta .!= 0.0) && ((neutral1V && !restart_neutral_1V) || (!neutral1V && restart_neutral_1V)) # One but not the other of the run being restarted from and this run are # 1V, but the interpolation below does not allow for vz and vpa being in From 5e821b24e05195819797ca959b72887959da24e2 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Wed, 13 Mar 2024 12:44:33 +0000 Subject: [PATCH 52/62] Tidy up setting of advance flags --- moment_kinetics/src/time_advance.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/moment_kinetics/src/time_advance.jl b/moment_kinetics/src/time_advance.jl index f3d08b899..f4114d196 100644 --- a/moment_kinetics/src/time_advance.jl +++ b/moment_kinetics/src/time_advance.jl @@ -485,10 +485,10 @@ function setup_advance_flags(moments, composition, t_input, collisions, # otherwise, check to see if the flags need to be set to true if !t_input.split_operators # default for non-split operators is to include both vpa and z advection together - advance_vpa_advection = true && vpa.n > 1 && z.n > 1 - advance_vperp_advection = true && vperp.n > 1 && z.n > 1 - advance_z_advection = true && z.n > 1 - advance_r_advection = true && r.n > 1 + advance_vpa_advection = vpa.n > 1 && z.n > 1 + advance_vperp_advection = vperp.n > 1 && z.n > 1 + advance_z_advection = z.n > 1 + advance_r_advection = r.n > 1 if collisions.nuii > 0.0 && vperp.n > 1 explicit_weakform_fp_collisions = true else From 0718045cca7e2517c237a2511620bdd44ea1322e Mon Sep 17 00:00:00 2001 From: John Omotani Date: Wed, 13 Mar 2024 12:45:15 +0000 Subject: [PATCH 53/62] Use one-liner instead of defining `geofac` Avoids extra allocation. --- moment_kinetics/src/z_advection.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/moment_kinetics/src/z_advection.jl b/moment_kinetics/src/z_advection.jl index f39fc467f..8a4a3f273 100644 --- a/moment_kinetics/src/z_advection.jl +++ b/moment_kinetics/src/z_advection.jl @@ -106,8 +106,7 @@ function update_speed_z!(advect, upar, vth, evolve_upar, evolve_ppar, fields, vp # vpa bzed @. @views advect.speed[:,ivpa,ivperp,ir] = vpa.grid[ivpa]*bzed[:,ir] # ExB drift - @. geofac = bzeta[:,ir]*jacobian[:,ir]/Bmag[:,ir] - @. @views advect.speed[:,ivpa,ivperp,ir] += ExBfac*geofac*fields.Er[:,ir] + @. @views advect.speed[:,ivpa,ivperp,ir] += ExBfac*bzeta[:,ir]*jacobian[:,ir]/Bmag[:,ir]*fields.Er[:,ir] # magnetic curvature drift @. @views advect.speed[:,ivpa,ivperp,ir] += rhostar*(vpa.grid[ivpa]^2)*cvdriftz[:,ir] # magnetic grad B drift From 90c10277562a4983072b81bbab07e2af180bb9ef Mon Sep 17 00:00:00 2001 From: John Omotani Date: Wed, 13 Mar 2024 12:45:32 +0000 Subject: [PATCH 54/62] Remove commented-out lines --- test_scripts/chebyshev_radau_test.jl | 2 -- 1 file changed, 2 deletions(-) diff --git a/test_scripts/chebyshev_radau_test.jl b/test_scripts/chebyshev_radau_test.jl index c06b8bd00..a4d7d6b65 100644 --- a/test_scripts/chebyshev_radau_test.jl +++ b/test_scripts/chebyshev_radau_test.jl @@ -46,8 +46,6 @@ function chebyshevradau_test(; ngrid=5, L_in=3.0, discretization="chebyshev_pseu y_nelement_global = y_nelement_local # total number of elements y_L = L_in bc = "zero" - #discretization = "gausslegendre_pseudospectral" - #discretization = "chebyshev_pseudospectral" # fd_option and adv_input not actually used so given values unimportant fd_option = "fourth_order_centered" cheb_option = "matrix" From 842bee5f04aa70dd7cc397c7bec98ec9f0fddca1 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Wed, 13 Mar 2024 13:36:56 +0000 Subject: [PATCH 55/62] Remove uses of Bzed and Bmag in example inputs and test scripts These input parameters are no longer used. The uses were only setting them to the default values anyway, so can just be deleted. --- .../fokker-planck-relaxation-report-resolutions.toml | 2 -- examples/fokker-planck/fokker-planck-relaxation.toml | 2 -- examples/numerical-dissipation/num-diss-relaxation.toml | 2 -- moment_kinetics/debug_test/fokker_planck_collisions_inputs.jl | 2 -- moment_kinetics/debug_test/mms_inputs.jl | 2 -- moment_kinetics/test/fokker_planck_time_evolution_tests.jl | 2 -- 6 files changed, 12 deletions(-) diff --git a/examples/fokker-planck/fokker-planck-relaxation-report-resolutions.toml b/examples/fokker-planck/fokker-planck-relaxation-report-resolutions.toml index 2807ea335..5f771f086 100644 --- a/examples/fokker-planck/fokker-planck-relaxation-report-resolutions.toml +++ b/examples/fokker-planck/fokker-planck-relaxation-report-resolutions.toml @@ -9,8 +9,6 @@ evolve_moments_conservation = false T_e = 1.0 T_wall = 1.0 rhostar = 1.0 -Bzed = 1.0 -Bmag = 1.0 initial_density1 = 0.5 initial_temperature1 = 1.0 initial_density2 = 0.5 diff --git a/examples/fokker-planck/fokker-planck-relaxation.toml b/examples/fokker-planck/fokker-planck-relaxation.toml index b12454e6f..780914505 100644 --- a/examples/fokker-planck/fokker-planck-relaxation.toml +++ b/examples/fokker-planck/fokker-planck-relaxation.toml @@ -9,8 +9,6 @@ evolve_moments_conservation = false T_e = 1.0 T_wall = 1.0 rhostar = 1.0 -Bzed = 1.0 -Bmag = 1.0 initial_density1 = 0.5 initial_temperature1 = 1.0 initial_density2 = 0.5 diff --git a/examples/numerical-dissipation/num-diss-relaxation.toml b/examples/numerical-dissipation/num-diss-relaxation.toml index 29965e248..3d305dfaa 100644 --- a/examples/numerical-dissipation/num-diss-relaxation.toml +++ b/examples/numerical-dissipation/num-diss-relaxation.toml @@ -9,8 +9,6 @@ evolve_moments_conservation = false T_e = 1.0 T_wall = 1.0 rhostar = 1.0 -Bzed = 1.0 -Bmag = 1.0 initial_density1 = 0.5 initial_temperature1 = 1.0 initial_density2 = 0.5 diff --git a/moment_kinetics/debug_test/fokker_planck_collisions_inputs.jl b/moment_kinetics/debug_test/fokker_planck_collisions_inputs.jl index 5f6a8d559..d68edf318 100644 --- a/moment_kinetics/debug_test/fokker_planck_collisions_inputs.jl +++ b/moment_kinetics/debug_test/fokker_planck_collisions_inputs.jl @@ -7,8 +7,6 @@ test_input_full_f = Dict( "nstep" => 3, "nwrite" => 2, "nwrite_dfns" => 2, - "Bmag" => 1.0, - "Bzed" => 1.0, "T_e" => 1.0, "T_wall" => 1.0, "electron_physics" => "boltzmann_electron_response", diff --git a/moment_kinetics/debug_test/mms_inputs.jl b/moment_kinetics/debug_test/mms_inputs.jl index 328e7aa3c..03d573694 100644 --- a/moment_kinetics/debug_test/mms_inputs.jl +++ b/moment_kinetics/debug_test/mms_inputs.jl @@ -13,8 +13,6 @@ test_input = Dict( "evolve_moments_conservation" => false, "T_e" => 1.0, "T_wall" => 1.0, - "Bzed" => 0.5, - "Bmag" => 1.0, "rhostar" => 1.0, "initial_density1" => 0.5, "initial_temperature1" => 1.0, diff --git a/moment_kinetics/test/fokker_planck_time_evolution_tests.jl b/moment_kinetics/test/fokker_planck_time_evolution_tests.jl index a022170cb..54e0c54ce 100644 --- a/moment_kinetics/test/fokker_planck_time_evolution_tests.jl +++ b/moment_kinetics/test/fokker_planck_time_evolution_tests.jl @@ -136,8 +136,6 @@ test_input_gauss_legendre = Dict("run_name" => "gausslegendre_pseudospectral", "electron_physics" => "boltzmann_electron_response", "nuii" => 1.0, "use_semi_lagrange" => false, - "Bzed" => 1.0, - "Bmag" => 1.0, "rhostar" => 1.0, "z_IC_upar_amplitude1" => 0.0, "z_IC_density_amplitude1" => 0.001, From 8605909343f333a24a9abffe31789d1b2b099b43 Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Wed, 13 Mar 2024 13:39:32 +0000 Subject: [PATCH 56/62] Improve comment regarding updating vperp_advect. --- moment_kinetics/src/time_advance.jl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/moment_kinetics/src/time_advance.jl b/moment_kinetics/src/time_advance.jl index f4114d196..796647860 100644 --- a/moment_kinetics/src/time_advance.jl +++ b/moment_kinetics/src/time_advance.jl @@ -288,7 +288,10 @@ function setup_time_advance!(pdf, vz, vr, vzeta, vpa, vperp, z, r, vz_spectral, begin_serial_region() vperp_advect = setup_advection(n_ion_species, vperp, vpa, z, r) # initialise the vperp advection speed - # note that z_advect and r_advect are arguments of update_speed_vperp! + # Note that z_advect and r_advect are arguments of update_speed_vperp! + # This means that z_advect[is].speed and r_advect[is].speed are used to determine + # vperp_advect[is].speed, so z_advect and r_advect must always be updated before + # vperp_advect is updated and used. if vperp.n > 1 begin_serial_region() @serial_region begin From 71733678ba7a74f037b0edaab671de9e0d54737a Mon Sep 17 00:00:00 2001 From: John Omotani Date: Wed, 13 Mar 2024 13:51:02 +0000 Subject: [PATCH 57/62] Fix geometry check for moment-kinetic cases --- moment_kinetics/src/moment_kinetics_input.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/moment_kinetics/src/moment_kinetics_input.jl b/moment_kinetics/src/moment_kinetics_input.jl index 7c6c4cc2f..aa8571532 100644 --- a/moment_kinetics/src/moment_kinetics_input.jl +++ b/moment_kinetics/src/moment_kinetics_input.jl @@ -547,7 +547,9 @@ function mk_input(scan_input=Dict(); save_inputs_to_txt=false, ignore_MPI=true) end geometry = init_magnetic_geometry(geometry_in,z,r) - if any(geometry.dBdz .!= 0.0) && (evolve_density || evolve_upar || evolve_ppar) + if any(geometry.dBdz .!= 0.0) && + (evolve_moments.density || evolve_moments.parallel_flow || + evolve_moments.parallel_pressure) error("Mirror terms not yet implemented for moment-kinetic modes") end From 0b1190ed1f822a040c8a6585e1a5f9ecabaed1cc Mon Sep 17 00:00:00 2001 From: mrhardman Date: Wed, 13 Mar 2024 14:25:07 +0000 Subject: [PATCH 58/62] Create geometry.md File to contain documentation of geometry and options --- docs/src/geometry.md | 71 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 docs/src/geometry.md diff --git a/docs/src/geometry.md b/docs/src/geometry.md new file mode 100644 index 000000000..b242c8436 --- /dev/null +++ b/docs/src/geometry.md @@ -0,0 +1,71 @@ +Magnetic Geometry +=============================================== + +We take the magnetic field $\mathbf{B}$ to have the form +```math +\begin{equation} +\mathbf{B} = B_z \hat{\mathbf{z}} + B_\zeta \hat{\mathbf{\zeta}}, +\end{equation} +``` +with $B_\zeta = B(r,z) b_\zeta$, $B_z = B(r,z) b_z$ and $b_z$ and $b_\zeta$ the direction cosines of the magnetic field vector. +Here the basis vectors are those of cylindrical geometry $(r,z,\zeta)$, i.e., +$\hat{\mathbf{r}} = \nabla r $, $\hat{\mathbf{z}} = \nabla z$, +and $\hat{\mathbf{\zeta}} = r \nabla \zeta$. The unit vectors $\hat{\mathbf{r}}$, $\hat{\mathbf{z}}$, and $\hat{\mathbf{\zeta}}$ +form a right-handed orthonormal basis. + +Supported options +=============================================== + +To choose the type of geometry, set the "geometry_option" + +geometry_option = "constant-helical" +=============================================== +Here $b_\zeta = \sqrt{1 - b_z^2}$ is a constant, $b_z$ is a constant input parameter ("pitch") and $B$ is taken to be 1 with respect to the reference value $B_{\rm ref}$. + +geometry_option = "1D-mirror" +=============================================== +Here $b_\zeta = \sqrt{1 - b_z^2}$ is a constant, $b_z$ is a constant input parameter ("pitch") and $B = B(z)$ is taken to be +the function +```math +\begin{equation} +\frac{B(z)}{B_{\rm ref}} = + 1 + \Delta B \left( 2\left(\frac{2z}{L_z}\right)^2 - \left(\frac{2z}{L_z}\right)^4\right) +\end{equation} +``` +where $\Delta B $ is an input parameter ("DeltaB") that must satisfy $\Delta B > -1$. +Recalling that the coordinate $z$ runs from +$z = -L_z/2$ to $L_z/2$, +if $\Delta B > 0$ than the field represents a magnetic mirror which traps particles, +whereas if $\Delta B < 0$ then the magnetic field accelerates particles +by the mirror force as they approach the wall. +Note that this field does not satisfy $\nabla \cdot \mathbf{B} = 0$, and is +only used to test the implementation of the magnetic mirror terms. 2D simulations with a radial domain and$\mathbf{E}\times\mathbf{B}$ drifts are supported in the "1D-mirror" +geometry option. + +Geometric coefficients +=============================================== +Here, we write the geometric coefficients appearing in the characteristic equations +explicitly. + +The $z$ component of the $\mathbf{E}\times\mathbf{B}$ drift is given by +```math +\begin{equation} \frac{\mathbf{E}\times\mathbf{B}}{B^2} \cdot \nabla z = \frac{E_r B_\zeta}{B^2} \nabla r \times \hat{\mathbf{\zeta}} \cdot \nabla z += - J \frac{E_r B_\zeta}{B^2}, +\end{equation} +``` +where we have defined $J = r \nabla r \times \nabla z \cdot \nabla \zeta$. +Note that $J$ is dimensionless. +The $r$ component of the $\mathbf{E}\times\mathbf{B}$ drift is given by +```math +\begin{equation} \frac{\mathbf{E}\times\mathbf{B}}{B^2} \cdot \nabla r = \frac{E_z B_\zeta}{B^2} \nabla z \times \hat{\mathbf{\zeta}} \cdot \nabla r += J \frac{E_z B_\zeta}{B^2}. +\end{equation} +``` +Due to the axisymmetry of the system, the differential operator + $\mathbf{b} \cdot \nabla (\cdot) = b_z \partial {(\cdot)}{\partial z}$, + and the convective derivative +```math +\begin{equation} +\frac{d B}{d t} = \frac{d z}{d t} \frac{\partial B}{ \partial z} + \frac{dr}{dt}\frac{\partial B}{\partial r}. +\end{equation} +``` From 7709ab43312b7534c44e38889260f3a9d29985d1 Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Wed, 13 Mar 2024 17:19:57 +0000 Subject: [PATCH 59/62] Add toml namelist [geometry] to the input files and modify existing input files to be compatible with this change. This changes is not backwards compatible. --- ...-planck-relaxation-report-resolutions.toml | 1 - .../fokker-planck-relaxation.toml | 1 - examples/geometry/1D-mirror.toml | 11 +++++--- .../num-diss-relaxation.toml | 1 - moment_kinetics/src/geo.jl | 25 +++++++++++++++++++ moment_kinetics/src/input_structs.jl | 10 ++++---- moment_kinetics/src/moment_kinetics_input.jl | 18 ++++--------- .../fokker_planck_time_evolution_tests.jl | 1 - ...id_9_nel_r_1_z_16_vpa_16_vperp_8_diss.toml | 12 +++++---- ...d_9_nel_r_1_z_32_vpa_32_vperp_16_diss.toml | 12 +++++---- ...grid_9_nel_r_1_z_4_vpa_4_vperp_2_diss.toml | 12 +++++---- ...d_9_nel_r_1_z_64_vpa_64_vperp_32_diss.toml | 12 +++++---- ...grid_9_nel_r_1_z_8_vpa_8_vperp_4_diss.toml | 12 +++++---- ...d_5_nel_r_16_z_16_vpa_16_vperp_8_diss.toml | 12 +++++---- ..._5_nel_r_32_z_32_vpa_32_vperp_16_diss.toml | 12 +++++---- ...grid_5_nel_r_4_z_4_vpa_4_vperp_2_diss.toml | 12 +++++---- ...grid_5_nel_r_8_z_8_vpa_8_vperp_4_diss.toml | 12 +++++---- 17 files changed, 105 insertions(+), 71 deletions(-) diff --git a/examples/fokker-planck/fokker-planck-relaxation-report-resolutions.toml b/examples/fokker-planck/fokker-planck-relaxation-report-resolutions.toml index 5f771f086..3eb069342 100644 --- a/examples/fokker-planck/fokker-planck-relaxation-report-resolutions.toml +++ b/examples/fokker-planck/fokker-planck-relaxation-report-resolutions.toml @@ -8,7 +8,6 @@ evolve_moments_parallel_pressure = false evolve_moments_conservation = false T_e = 1.0 T_wall = 1.0 -rhostar = 1.0 initial_density1 = 0.5 initial_temperature1 = 1.0 initial_density2 = 0.5 diff --git a/examples/fokker-planck/fokker-planck-relaxation.toml b/examples/fokker-planck/fokker-planck-relaxation.toml index 780914505..d3284322c 100644 --- a/examples/fokker-planck/fokker-planck-relaxation.toml +++ b/examples/fokker-planck/fokker-planck-relaxation.toml @@ -8,7 +8,6 @@ evolve_moments_parallel_pressure = false evolve_moments_conservation = false T_e = 1.0 T_wall = 1.0 -rhostar = 1.0 initial_density1 = 0.5 initial_temperature1 = 1.0 initial_density2 = 0.5 diff --git a/examples/geometry/1D-mirror.toml b/examples/geometry/1D-mirror.toml index 31c87cd96..66c36fd5b 100644 --- a/examples/geometry/1D-mirror.toml +++ b/examples/geometry/1D-mirror.toml @@ -5,10 +5,6 @@ evolve_moments_density = false evolve_moments_parallel_flow = false evolve_moments_parallel_pressure = false evolve_moments_conservation = false -geometry_option="1D-mirror" -DeltaB=10.0 -#geometry_option="constant-helical" -#pitch=1.0 T_e = 1.0 T_wall = 1.0 initial_density1 = 1.0 @@ -79,3 +75,10 @@ vz_discretization = "chebyshev_pseudospectral" vpa_dissipation_coefficient = 1.0e-3 #1.0e-2 #1.0e-1 vperp_dissipation_coefficient = 1.0e-3 #1.0e-2 #1.0e-1 force_minimum_pdf_value = 0.0 + +[geometry] +option="1D-mirror" +DeltaB=0.5 +#option="constant-helical" +pitch=1.0 +rhostar= 1.0 diff --git a/examples/numerical-dissipation/num-diss-relaxation.toml b/examples/numerical-dissipation/num-diss-relaxation.toml index 3d305dfaa..abd22e2da 100644 --- a/examples/numerical-dissipation/num-diss-relaxation.toml +++ b/examples/numerical-dissipation/num-diss-relaxation.toml @@ -8,7 +8,6 @@ evolve_moments_parallel_pressure = false evolve_moments_conservation = false T_e = 1.0 T_wall = 1.0 -rhostar = 1.0 initial_density1 = 0.5 initial_temperature1 = 1.0 initial_density2 = 0.5 diff --git a/moment_kinetics/src/geo.jl b/moment_kinetics/src/geo.jl index 84808aea5..fa3db990a 100644 --- a/moment_kinetics/src/geo.jl +++ b/moment_kinetics/src/geo.jl @@ -6,12 +6,14 @@ coordinate and r the radial coordinate module geo export init_magnetic_geometry +export setup_geometry_input using ..input_structs: geometry_input using ..file_io: input_option_error using ..array_allocation: allocate_float using ..type_definitions: mk_float, mk_int + """ struct containing the geometric data necessary for non-trivial axisymmetric geometries, to be passed @@ -58,6 +60,29 @@ gbdriftr::Array{mk_float,2} gbdriftz::Array{mk_float,2} end +""" +function to read the geometry input data from the TOML file + +the TOML namelist should be structured like + +[geometry] +pitch = 1.0 +rhostar = 1.0 +DeltaB = 0.0 +option = "" + +""" +function setup_geometry_input(toml_input::Dict, reference_rhostar) + input_section = get(toml_input, "geometry", Dict{String,Any}()) + if !("rhostar" ∈ keys(input_section)) + # Set default rhostar with reference value + input_section["rhostar"] = get(input_section, "rhostar", reference_rhostar) + end + input = Dict(Symbol(k)=>v for (k,v) in input_section) + println(input) + return geometry_input(; input...) +end + """ function to initialise the geometry coefficients input_data -- geometry_input type diff --git a/moment_kinetics/src/input_structs.jl b/moment_kinetics/src/input_structs.jl index 11db6faca..8e8e67bbe 100644 --- a/moment_kinetics/src/input_structs.jl +++ b/moment_kinetics/src/input_structs.jl @@ -327,15 +327,15 @@ end """ """ -mutable struct geometry_input +Base.@kwdef struct geometry_input # rhostar ion (ref) - rhostar::mk_float #used to premultiply ExB drift terms + rhostar::mk_float = 0.0 #used to premultiply ExB drift terms # magnetic geometry option - option::String + option::String = "constant-helical" # "1D-mirror" # pitch ( = Bzed/Bmag if geometry_option == "constant-helical") - pitch::mk_float + pitch::mk_float = 1.0 # DeltaB ( = (Bzed(z=L/2) - Bzed(0))/Bref if geometry_option == "1D-mirror") - DeltaB::mk_float + DeltaB::mk_float = 0.0 end @enum binary_format_type hdf5 netcdf diff --git a/moment_kinetics/src/moment_kinetics_input.jl b/moment_kinetics/src/moment_kinetics_input.jl index aa8571532..691571fca 100644 --- a/moment_kinetics/src/moment_kinetics_input.jl +++ b/moment_kinetics/src/moment_kinetics_input.jl @@ -19,7 +19,7 @@ using ..finite_differences: fd_check_option using ..input_structs using ..numerical_dissipation: setup_numerical_dissipation using ..reference_parameters -using ..geo: init_magnetic_geometry +using ..geo: init_magnetic_geometry, setup_geometry_input using MPI using TOML @@ -51,7 +51,7 @@ function mk_input(scan_input=Dict(); save_inputs_to_txt=false, ignore_MPI=true) # Check for input options that used to exist, but do not any more. If these are # present, the user probably needs to update their input file. - removed_options_list = ("Bzed", "Bmag") + removed_options_list = ("Bzed", "Bmag", "rhostar", "geometry_option", "pitch", "DeltaB") for opt in removed_options_list if opt ∈ keys(scan_input) error("Option '$opt' is no longer used. Please update your input file. You " @@ -73,7 +73,7 @@ function mk_input(scan_input=Dict(); save_inputs_to_txt=false, ignore_MPI=true) # reference value using J_||e + J_||i = 0 at z = 0 electron_physics = get(scan_input, "electron_physics", boltzmann_electron_response) - z, r, vpa, vperp, gyrophase, vz, vr, vzeta, species, composition, drive, evolve_moments, collisions, geometry_in = + z, r, vpa, vperp, gyrophase, vz, vr, vzeta, species, composition, drive, evolve_moments, collisions = load_defaults(n_ion_species, n_neutral_species, electron_physics) # this is the prefix for all output files associated with this run @@ -113,10 +113,7 @@ function mk_input(scan_input=Dict(); save_inputs_to_txt=false, ignore_MPI=true) reference_params = setup_reference_parameters(scan_input) ## set geometry_input - geometry_in.option = get(scan_input, "geometry_option", "constant-helical") #"1D-mirror" - geometry_in.pitch = get(scan_input, "pitch", 1.0) - geometry_in.rhostar = get(scan_input, "rhostar", get_default_rhostar(reference_params)) - geometry_in.DeltaB = get(scan_input, "DeltaB", 1.0) + geometry_in = setup_geometry_input(scan_input, get_default_rhostar(reference_params)) ispecies = 1 species.charged[1].z_IC.initialization_option = get(scan_input, "z_IC_option$ispecies", "gaussian") @@ -1018,13 +1015,8 @@ function load_defaults(n_ion_species, n_neutral_species, electron_physics) nuii = 0.0 collisions = collisions_input(charge_exchange, ionization, constant_ionization_rate, krook_collision_frequency_prefactor,"none", nuii) - rhostar = 0.0 #rhostar of ions for ExB drift - option = "constant-helical" - pitch = 1.0 - DeltaB = 1.0 - geometry_in = geometry_input(rhostar,option,pitch,DeltaB) - return z, r, vpa, vperp, gyrophase, vz, vr, vzeta, species, composition, drive, evolve_moments, collisions, geometry_in + return z, r, vpa, vperp, gyrophase, vz, vr, vzeta, species, composition, drive, evolve_moments, collisions end """ diff --git a/moment_kinetics/test/fokker_planck_time_evolution_tests.jl b/moment_kinetics/test/fokker_planck_time_evolution_tests.jl index 54e0c54ce..cf324766a 100644 --- a/moment_kinetics/test/fokker_planck_time_evolution_tests.jl +++ b/moment_kinetics/test/fokker_planck_time_evolution_tests.jl @@ -136,7 +136,6 @@ test_input_gauss_legendre = Dict("run_name" => "gausslegendre_pseudospectral", "electron_physics" => "boltzmann_electron_response", "nuii" => 1.0, "use_semi_lagrange" => false, - "rhostar" => 1.0, "z_IC_upar_amplitude1" => 0.0, "z_IC_density_amplitude1" => 0.001, "z_IC_upar_amplitude2" => 0.0, diff --git a/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_16_vpa_16_vperp_8_diss.toml b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_16_vpa_16_vperp_8_diss.toml index 3cd1c515d..6a89faab1 100644 --- a/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_16_vpa_16_vperp_8_diss.toml +++ b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_16_vpa_16_vperp_8_diss.toml @@ -7,14 +7,9 @@ evolve_moments_parallel_flow = false evolve_moments_parallel_pressure = false evolve_moments_conservation = false force_Er_zero_at_wall = false #true -geometry_option="1D-mirror" -DeltaB=0.5 -#geometry_option="constant-helical" -pitch=1.0 Er_constant = 0.0 T_e = 1.0 T_wall = 1.0 -rhostar = 1.0 initial_density1 = 0.5 initial_temperature1 = 1.0 initial_density2 = 0.5 @@ -97,3 +92,10 @@ vpa_dissipation_coefficient = 0.001 vperp_dissipation_coefficient = 0.001 #z_dissipation_coefficient = 0.1 r_dissipation_coefficient = 0.0 + +[geometry] +option="1D-mirror" +DeltaB=0.5 +#option="constant-helical" +pitch=1.0 +rhostar = 1.0 diff --git a/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_32_vpa_32_vperp_16_diss.toml b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_32_vpa_32_vperp_16_diss.toml index 3c1684c52..a90350f22 100644 --- a/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_32_vpa_32_vperp_16_diss.toml +++ b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_32_vpa_32_vperp_16_diss.toml @@ -7,14 +7,9 @@ evolve_moments_parallel_flow = false evolve_moments_parallel_pressure = false evolve_moments_conservation = false force_Er_zero_at_wall = false #true -geometry_option="1D-mirror" -DeltaB=0.5 -#geometry_option="constant-helical" -pitch=1.0 Er_constant = 0.0 T_e = 1.0 T_wall = 1.0 -rhostar = 1.0 initial_density1 = 0.5 initial_temperature1 = 1.0 initial_density2 = 0.5 @@ -97,3 +92,10 @@ vpa_dissipation_coefficient = 0.001 vperp_dissipation_coefficient = 0.001 #z_dissipation_coefficient = 0.1 r_dissipation_coefficient = 0.0 + +[geometry] +option="1D-mirror" +DeltaB=0.5 +#option="constant-helical" +pitch=1.0 +rhostar = 1.0 diff --git a/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_4_vpa_4_vperp_2_diss.toml b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_4_vpa_4_vperp_2_diss.toml index 32188a931..92a8aa331 100644 --- a/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_4_vpa_4_vperp_2_diss.toml +++ b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_4_vpa_4_vperp_2_diss.toml @@ -7,14 +7,9 @@ evolve_moments_parallel_flow = false evolve_moments_parallel_pressure = false evolve_moments_conservation = false force_Er_zero_at_wall = false #true -geometry_option="1D-mirror" -DeltaB=0.5 -#geometry_option="constant-helical" -pitch=1.0 Er_constant = 0.0 T_e = 1.0 T_wall = 1.0 -rhostar = 1.0 initial_density1 = 0.5 initial_temperature1 = 1.0 initial_density2 = 0.5 @@ -97,3 +92,10 @@ vpa_dissipation_coefficient = 0.001 vperp_dissipation_coefficient = 0.001 #z_dissipation_coefficient = 0.1 r_dissipation_coefficient = 0.0 + +[geometry] +option="1D-mirror" +DeltaB=0.5 +#option="constant-helical" +pitch=1.0 +rhostar = 1.0 diff --git a/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_64_vpa_64_vperp_32_diss.toml b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_64_vpa_64_vperp_32_diss.toml index e45a96c52..5f63e0aec 100644 --- a/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_64_vpa_64_vperp_32_diss.toml +++ b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_64_vpa_64_vperp_32_diss.toml @@ -7,14 +7,9 @@ evolve_moments_parallel_flow = false evolve_moments_parallel_pressure = false evolve_moments_conservation = false force_Er_zero_at_wall = false #true -geometry_option="1D-mirror" -DeltaB=0.5 -#geometry_option="constant-helical" -pitch=1.0 Er_constant = 0.0 T_e = 1.0 T_wall = 1.0 -rhostar = 1.0 initial_density1 = 0.5 initial_temperature1 = 1.0 initial_density2 = 0.5 @@ -97,3 +92,10 @@ vpa_dissipation_coefficient = 0.001 vperp_dissipation_coefficient = 0.0 #z_dissipation_coefficient = 0.1 r_dissipation_coefficient = 0.0 + +[geometry] +option="1D-mirror" +DeltaB=0.5 +#option="constant-helical" +pitch=1.0 +rhostar = 1.0 diff --git a/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_8_vpa_8_vperp_4_diss.toml b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_8_vpa_8_vperp_4_diss.toml index c25e70d0d..c8e8df9ee 100644 --- a/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_8_vpa_8_vperp_4_diss.toml +++ b/runs/1D-mirror_MMS_ngrid_9_nel_r_1_z_8_vpa_8_vperp_4_diss.toml @@ -7,14 +7,9 @@ evolve_moments_parallel_flow = false evolve_moments_parallel_pressure = false evolve_moments_conservation = false force_Er_zero_at_wall = false #true -geometry_option="1D-mirror" -DeltaB=0.5 -#geometry_option="constant-helical" -pitch=1.0 Er_constant = 0.0 T_e = 1.0 T_wall = 1.0 -rhostar = 1.0 initial_density1 = 0.5 initial_temperature1 = 1.0 initial_density2 = 0.5 @@ -97,3 +92,10 @@ vpa_dissipation_coefficient = 0.001 vperp_dissipation_coefficient = 0.001 #z_dissipation_coefficient = 0.1 r_dissipation_coefficient = 0.0 + +[geometry] +option="1D-mirror" +DeltaB=0.5 +#option="constant-helical" +pitch=1.0 +rhostar = 1.0 diff --git a/runs/2D-mirror_MMS_ngrid_5_nel_r_16_z_16_vpa_16_vperp_8_diss.toml b/runs/2D-mirror_MMS_ngrid_5_nel_r_16_z_16_vpa_16_vperp_8_diss.toml index 9bc5f0d5b..a300c9a56 100644 --- a/runs/2D-mirror_MMS_ngrid_5_nel_r_16_z_16_vpa_16_vperp_8_diss.toml +++ b/runs/2D-mirror_MMS_ngrid_5_nel_r_16_z_16_vpa_16_vperp_8_diss.toml @@ -7,14 +7,9 @@ evolve_moments_parallel_flow = false evolve_moments_parallel_pressure = false evolve_moments_conservation = false force_Er_zero_at_wall = false #true -geometry_option="1D-mirror" -DeltaB=0.5 -#geometry_option="constant-helical" -pitch=0.5 Er_constant = 0.0 T_e = 1.0 T_wall = 1.0 -rhostar = 1.0 initial_density1 = 0.5 initial_temperature1 = 1.0 initial_density2 = 0.5 @@ -97,3 +92,10 @@ vpa_dissipation_coefficient = 0.001 vperp_dissipation_coefficient = 0.001 #z_dissipation_coefficient = 0.1 r_dissipation_coefficient = 0.01 + +[geometry] +option="1D-mirror" +DeltaB=0.5 +#option="constant-helical" +pitch=0.5 +rhostar = 1.0 diff --git a/runs/2D-mirror_MMS_ngrid_5_nel_r_32_z_32_vpa_32_vperp_16_diss.toml b/runs/2D-mirror_MMS_ngrid_5_nel_r_32_z_32_vpa_32_vperp_16_diss.toml index 864b91acf..c98077d3a 100644 --- a/runs/2D-mirror_MMS_ngrid_5_nel_r_32_z_32_vpa_32_vperp_16_diss.toml +++ b/runs/2D-mirror_MMS_ngrid_5_nel_r_32_z_32_vpa_32_vperp_16_diss.toml @@ -7,14 +7,9 @@ evolve_moments_parallel_flow = false evolve_moments_parallel_pressure = false evolve_moments_conservation = false force_Er_zero_at_wall = false #true -geometry_option="1D-mirror" -DeltaB=0.5 -#geometry_option="constant-helical" -pitch=0.5 Er_constant = 0.0 T_e = 1.0 T_wall = 1.0 -rhostar = 1.0 initial_density1 = 0.5 initial_temperature1 = 1.0 initial_density2 = 0.5 @@ -97,3 +92,10 @@ vpa_dissipation_coefficient = 0.001 vperp_dissipation_coefficient = 0.001 #z_dissipation_coefficient = 0.1 r_dissipation_coefficient = 0.01 + +[geometry] +option="1D-mirror" +DeltaB=0.5 +#option="constant-helical" +pitch=0.5 +rhostar = 1.0 diff --git a/runs/2D-mirror_MMS_ngrid_5_nel_r_4_z_4_vpa_4_vperp_2_diss.toml b/runs/2D-mirror_MMS_ngrid_5_nel_r_4_z_4_vpa_4_vperp_2_diss.toml index aabf1ab4b..3ec12c9fe 100644 --- a/runs/2D-mirror_MMS_ngrid_5_nel_r_4_z_4_vpa_4_vperp_2_diss.toml +++ b/runs/2D-mirror_MMS_ngrid_5_nel_r_4_z_4_vpa_4_vperp_2_diss.toml @@ -7,14 +7,9 @@ evolve_moments_parallel_flow = false evolve_moments_parallel_pressure = false evolve_moments_conservation = false force_Er_zero_at_wall = false #true -geometry_option="1D-mirror" -DeltaB=0.5 -#geometry_option="constant-helical" -pitch=0.5 Er_constant = 0.0 T_e = 1.0 T_wall = 1.0 -rhostar = 1.0 initial_density1 = 0.5 initial_temperature1 = 1.0 initial_density2 = 0.5 @@ -97,3 +92,10 @@ vpa_dissipation_coefficient = 0.001 vperp_dissipation_coefficient = 0.001 #z_dissipation_coefficient = 0.1 r_dissipation_coefficient = 0.01 + +[geometry] +option="1D-mirror" +DeltaB=0.5 +#option="constant-helical" +pitch=0.5 +rhostar = 1.0 diff --git a/runs/2D-mirror_MMS_ngrid_5_nel_r_8_z_8_vpa_8_vperp_4_diss.toml b/runs/2D-mirror_MMS_ngrid_5_nel_r_8_z_8_vpa_8_vperp_4_diss.toml index f5220c537..e936ef06e 100644 --- a/runs/2D-mirror_MMS_ngrid_5_nel_r_8_z_8_vpa_8_vperp_4_diss.toml +++ b/runs/2D-mirror_MMS_ngrid_5_nel_r_8_z_8_vpa_8_vperp_4_diss.toml @@ -7,14 +7,9 @@ evolve_moments_parallel_flow = false evolve_moments_parallel_pressure = false evolve_moments_conservation = false force_Er_zero_at_wall = false #true -geometry_option="1D-mirror" -DeltaB=0.5 -#geometry_option="constant-helical" -pitch=0.5 Er_constant = 0.0 T_e = 1.0 T_wall = 1.0 -rhostar = 1.0 initial_density1 = 0.5 initial_temperature1 = 1.0 initial_density2 = 0.5 @@ -97,3 +92,10 @@ vpa_dissipation_coefficient = 0.001 vperp_dissipation_coefficient = 0.001 #z_dissipation_coefficient = 0.1 r_dissipation_coefficient = 0.01 + +[geometry] +option="1D-mirror" +DeltaB=0.5 +#option="constant-helical" +pitch=0.5 +rhostar = 1.0 From df1cff5e545ad21558852bc83a4e0f915d5b6b92 Mon Sep 17 00:00:00 2001 From: mrhardman Date: Thu, 14 Mar 2024 09:22:50 +0000 Subject: [PATCH 60/62] Update geometry.md Bring input parameter documentation up to date with the source. --- docs/src/geometry.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/docs/src/geometry.md b/docs/src/geometry.md index b242c8436..9b956e189 100644 --- a/docs/src/geometry.md +++ b/docs/src/geometry.md @@ -16,13 +16,21 @@ form a right-handed orthonormal basis. Supported options =============================================== -To choose the type of geometry, set the "geometry_option" +To choose the type of geometry, set the value of "option" in the geometry namelist. The namelist will have the following appearance in the TOML file. +``` +[geometry] +option="constant-helical" # ( or "1D-mirror" ) +pitch = 1.0 +rhostar = 1.0 +DeltaB = 0.0 +``` +If `rhostar` is not set then it is computed from reference parameters. -geometry_option = "constant-helical" +[geometry] option = "constant-helical" =============================================== Here $b_\zeta = \sqrt{1 - b_z^2}$ is a constant, $b_z$ is a constant input parameter ("pitch") and $B$ is taken to be 1 with respect to the reference value $B_{\rm ref}$. -geometry_option = "1D-mirror" +[geometry] option = "1D-mirror" =============================================== Here $b_\zeta = \sqrt{1 - b_z^2}$ is a constant, $b_z$ is a constant input parameter ("pitch") and $B = B(z)$ is taken to be the function From a13f9a04604f129b17e8d72290908e8aa6740f2a Mon Sep 17 00:00:00 2001 From: mrhardman Date: Thu, 14 Mar 2024 11:22:10 +0000 Subject: [PATCH 61/62] Update geo.jl Comment out print statement. --- moment_kinetics/src/geo.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/moment_kinetics/src/geo.jl b/moment_kinetics/src/geo.jl index fa3db990a..9ad6d4885 100644 --- a/moment_kinetics/src/geo.jl +++ b/moment_kinetics/src/geo.jl @@ -79,7 +79,7 @@ function setup_geometry_input(toml_input::Dict, reference_rhostar) input_section["rhostar"] = get(input_section, "rhostar", reference_rhostar) end input = Dict(Symbol(k)=>v for (k,v) in input_section) - println(input) + #println(input) return geometry_input(; input...) end From b6b7df0f08e8a43ad4670a19be58ad78d7538a6a Mon Sep 17 00:00:00 2001 From: John Omotani Date: Thu, 14 Mar 2024 14:19:08 +0000 Subject: [PATCH 62/62] Update debug_test inputs for changes to geometry input --- moment_kinetics/debug_test/fokker_planck_collisions_inputs.jl | 1 - moment_kinetics/debug_test/mms_inputs.jl | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/moment_kinetics/debug_test/fokker_planck_collisions_inputs.jl b/moment_kinetics/debug_test/fokker_planck_collisions_inputs.jl index d68edf318..199712b4c 100644 --- a/moment_kinetics/debug_test/fokker_planck_collisions_inputs.jl +++ b/moment_kinetics/debug_test/fokker_planck_collisions_inputs.jl @@ -29,7 +29,6 @@ test_input_full_f = Dict( "r_discretization" => "chebyshev_pseudospectral", "r_nelement" => 1, "r_ngrid" => 3, - "rhostar" => 1.0, "split_operators" => false, "vpa_L" => 6.0, "vpa_bc" => "zero", diff --git a/moment_kinetics/debug_test/mms_inputs.jl b/moment_kinetics/debug_test/mms_inputs.jl index 03d573694..5378c6602 100644 --- a/moment_kinetics/debug_test/mms_inputs.jl +++ b/moment_kinetics/debug_test/mms_inputs.jl @@ -13,7 +13,6 @@ test_input = Dict( "evolve_moments_conservation" => false, "T_e" => 1.0, "T_wall" => 1.0, - "rhostar" => 1.0, "initial_density1" => 0.5, "initial_temperature1" => 1.0, "initial_density2" => 0.5, @@ -72,6 +71,7 @@ test_input = Dict( "vzeta_L" => 12.0, "vzeta_bc" => "none", "vzeta_discretization" => "chebyshev_pseudospectral", + "geometry" => Dict{String,Any}("rhostar" => 1.0,), ) test_input_list = [