From fd796723fea385eae2e1ad9096a6757711dee740 Mon Sep 17 00:00:00 2001 From: Michael Hardman Date: Wed, 7 Aug 2024 10:10:25 +0000 Subject: [PATCH 01/87] Tidy up plots. --- .../src/plots_post_processing.jl | 34 +++++++++++++++---- 1 file changed, 27 insertions(+), 7 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 8fdb8fd81..1343f7612 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 @@ -3091,7 +3091,7 @@ function plot_fields_2D(phi, Ez, Er, time, z, r, iz0, ir0, trygif(anim, outfile, fps=5) elseif pp.animate_phi_vs_r_z && nr == 1 && nz > 1 # make a gif animation of ϕ(z) at different times anim = @animate for i ∈ itime_min:nwrite_movie:itime_max - @views plot(z, phi[:,1,i], xlabel="z", ylabel=L"\widetilde{\phi}", ylims = (phimin,phimax)) + @views plot(z, phi[:,1,i], xlabel="z", ylabel=L"\widetilde{\phi}", ylims = (phimin,phimax),label ="") end outfile = string(run_name, "_phi_vs_z.gif") trygif(anim, outfile, fps=5) @@ -3116,13 +3116,13 @@ function plot_fields_2D(phi, Ez, Er, time, z, r, iz0, ir0, outfile = string(run_name, "_Ez"*description*"_vs_r_z.gif") trygif(anim, outfile, fps=5) anim = @animate for i ∈ itime_min:nwrite_movie:itime_max - @views plot(r, Ez[1,:,i], xlabel="r", ylabel=L"\widetilde{E}_z", ylims = (Ezmin,Ezmax)) + @views plot(r, Ez[1,:,i], xlabel="r", ylabel=L"\widetilde{E}_z", ylims = (Ezmin,Ezmax), label="") end outfile = string(run_name, "_Ez(zwall-)_vs_r.gif") trygif(anim, outfile, fps=5) elseif pp.animate_Ez_vs_r_z && nr == 1 && nz > 1 anim = @animate for i ∈ itime_min:nwrite_movie:itime_max - @views plot(z, Ez[:,1,i], xlabel="z", ylabel=L"\widetilde{E}_z", ylims = (Ezmin,Ezmax)) + @views plot(z, Ez[:,1,i], xlabel="z", ylabel=L"\widetilde{E}_z", ylims = (Ezmin,Ezmax), label="") end outfile = string(run_name, "_Ez_vs_z.gif") trygif(anim, outfile, fps=5) @@ -3139,7 +3139,7 @@ function plot_fields_2D(phi, Ez, Er, time, z, r, iz0, ir0, outfile = string(run_name, "_Er"*description*"(r,z_wall-)_vs_r.pdf") trysavefig(outfile) anim = @animate for i ∈ itime_min:nwrite_movie:itime_max - @views plot(r, Er[1,:,i], xlabel="r", ylabel=L"\widetilde{E}_r", ylims = (Ermin,Ermax)) + @views plot(r, Er[1,:,i], xlabel="r", ylabel=L"\widetilde{E}_r", ylims = (Ermin,Ermax), label="") end outfile = string(run_name, "_Er(zwall-)_vs_r.gif") trygif(anim, outfile, fps=5) @@ -3168,7 +3168,7 @@ function plot_ion_moments_2D(density, parallel_flow, parallel_pressure, description = "_ion_spec"*string(is)*"_" # the density densitymin = minimum(density[:,:,is,:]) - densitymax = maximum(density) + densitymax = maximum(density[:,:,is,:]) if pp.plot_density_vs_r0_z && nz > 1 # plot last timestep density[z,ir0] @views plot(z, density[:,ir0,is,end], xlabel=L"z/L_z", ylabel=L"n_i") outfile = string(run_name, "_density"*description*"(r0,z)_vs_z.pdf") @@ -3186,7 +3186,13 @@ function plot_ion_moments_2D(density, parallel_flow, parallel_pressure, end outfile = string(run_name, "_density"*description*"_vs_r_z.gif") trygif(anim, outfile, fps=5) - end + elseif pp.animate_density_vs_r_z && nr == 1 && nz > 1 + anim = @animate for i ∈ itime_min:nwrite_movie:itime_max + @views plot(z, density[:,1,is,i], xlabel="z", ylabel=L"n_i", ylims = (densitymin,densitymax),label ="") + end + outfile = string(run_name, "_density"*description*"_vs_z.gif") + trygif(anim, outfile, fps=5) + end if pp.plot_density_vs_r_z && nr > 1 && nz > 1 @views heatmap(r, z, density[:,:,is,end], xlabel=L"r", ylabel=L"z", c = :deep, interpolation = :cubic, windowsize = (360,240), margin = 15pt) @@ -3203,7 +3209,7 @@ function plot_ion_moments_2D(density, parallel_flow, parallel_pressure, end # the parallel flow parallel_flowmin = minimum(parallel_flow[:,:,is,:]) - parallel_flowmax = maximum(parallel_flow) + parallel_flowmax = maximum(parallel_flow[:,:,is,:]) if pp.plot_parallel_flow_vs_r0_z && nz > 1 # plot last timestep parallel_flow[z,ir0] @views plot(z, parallel_flow[:,ir0,is,end], xlabel=L"z/L_z", ylabel=L"u_{i\|\|}") outfile = string(run_name, "_parallel_flow"*description*"(r0,z)_vs_z.pdf") @@ -3221,6 +3227,12 @@ function plot_ion_moments_2D(density, parallel_flow, parallel_pressure, end outfile = string(run_name, "_parallel_flow"*description*"_vs_r_z.gif") trygif(anim, outfile, fps=5) + elseif pp.animate_parallel_flow_vs_r_z && nr == 1 && nz > 1 + anim = @animate for i ∈ itime_min:nwrite_movie:itime_max + @views plot(z, parallel_flow[:,1,is,i], xlabel="z", ylabel=L"u_{i\|\|}", ylims = (parallel_flowmin,parallel_flowmax),label ="") + end + outfile = string(run_name, "_parallel_flow"*description*"_vs_z.gif") + trygif(anim, outfile, fps=5) end if pp.plot_parallel_flow_vs_r_z && nr > 1 && nz > 1 @views heatmap(r, z, parallel_flow[:,:,is,end], xlabel=L"r", ylabel=L"z", c = :deep, interpolation = :cubic, @@ -3348,6 +3360,14 @@ function plot_ion_moments_2D(density, parallel_flow, parallel_pressure, label = [L"p_{i\|\|}" L"p_{i\perp}" L"p_{i}"], foreground_color_legend = nothing, background_color_legend = nothing) outfile = string(run_name, "_all_pressures"*description*"(r0,z)_vs_z.pdf") trysavefig(outfile) + pmin = min(minimum(parallel_pressure[:,ir0,is,:]),minimum(perpendicular_pressure[:,ir0,is,:]),minimum(total_pressure[:,ir0,is,:])) + pmax = max(maximum(parallel_pressure[:,ir0,is,:]),maximum(perpendicular_pressure[:,ir0,is,:]),maximum(total_pressure[:,ir0,is,:])) + anim = @animate for i ∈ itime_min:nwrite_movie:itime_max + @views plot([z,z,z], [parallel_pressure[:,ir0,is,i],perpendicular_pressure[:,ir0,is,i],total_pressure[:,ir0,is,i]], xlabel=L"z/L_z", ylabel="", + label = [L"p_{i\|\|}" L"p_{i\perp}" L"p_{i}"], foreground_color_legend = nothing, background_color_legend = nothing, ylims = (pmin,pmax)) + end + outfile = string(run_name, "_all_pressures"*description*"(r0,z)_vs_z.gif") + trygif(anim, outfile, fps=5) end # the thermal speed if pp.plot_vth0_vs_t From af494328893af9eb56d75d1c85b84e0e09c85242 Mon Sep 17 00:00:00 2001 From: Lucas McConnell Date: Fri, 6 Sep 2024 14:02:17 +0100 Subject: [PATCH 02/87] Split get_settings function for neutrals and ions, in preparation for multiple source profiles --- moment_kinetics/src/external_sources.jl | 99 +++++++++++++++++-------- 1 file changed, 69 insertions(+), 30 deletions(-) diff --git a/moment_kinetics/src/external_sources.jl b/moment_kinetics/src/external_sources.jl index 98fe4169c..a264a1191 100644 --- a/moment_kinetics/src/external_sources.jl +++ b/moment_kinetics/src/external_sources.jl @@ -40,13 +40,13 @@ Returns a NamedTuple `(ion=ion_source_settings, neutral=neutral_source_settings) containing two NamedTuples of settings. """ function setup_external_sources!(input_dict, r, z, electron_physics) - function get_settings(neutrals) + function get_settings_ions() input = set_defaults_and_check_section!( - input_dict, neutrals ? "neutral_source" : "ion_source"; + input_dict, "ion_source"; active=false, source_strength=1.0, source_n=1.0, - source_T=neutrals ? get(input_dict, "T_wall", 1.0) : 1.0, + source_T=1.0, source_v0=0.0, # birth speed for "alphas" option source_vpa0=0.0, # birth vpa for "beam" option source_vperp0=0.0, # birth vperp for "beam" option @@ -137,7 +137,65 @@ function setup_external_sources!(input_dict, r, z, electron_physics) else PI_density_target_rank = nothing end - elseif neutrals && input["source_type"] == "recycling" + elseif input["source_type"] ∈ ("Maxwellian", "energy", "alphas", "alphas-with-losses", "beam", "beam-with-losses") + PI_density_target = nothing + PI_controller_amplitude = nothing + controller_source_profile = nothing + PI_density_target_ir = nothing + PI_density_target_iz = nothing + PI_density_target_rank = nothing + else + error("Unrecognised ion source_type=$(input["source_type"])." + * "Possible values are: Maxwellian, density_profile_control, " + * "density_midpoint_control") + end + + return (; (Symbol(k)=>v for (k,v) ∈ input)..., r_amplitude=r_amplitude, + z_amplitude=z_amplitude, PI_density_target=PI_density_target, + PI_controller_amplitude=PI_controller_amplitude, + controller_source_profile=controller_source_profile, + PI_density_target_ir=PI_density_target_ir, + PI_density_target_iz=PI_density_target_iz, + PI_density_target_rank=PI_density_target_rank) + end + + function get_settings_neutrals() + input = set_defaults_and_check_section!( + input_dict, "neutral_source"; + active=false, + source_strength=1.0, + source_n=1.0, + source_T=get(input_dict, "T_wall", 1.0), + source_v0=0.0, # birth speed for "alphas" option + source_vpa0=0.0, # birth vpa for "beam" option + source_vperp0=0.0, # birth vperp for "beam" option + sink_strength=1.0, # strength of sink in "alphas-with-losses" & "beam-with-losses" option + sink_vth=0.0, # thermal speed for sink in "alphas-with-losses" & "beam-with-losses" option + r_profile="constant", + r_width=1.0, + r_relative_minimum=0.0, + z_profile="constant", + z_width=1.0, + z_relative_minimum=0.0, + source_type="recycling", # "energy", "alphas", "alphas-with-losses", "beam", "beam-with-losses" + PI_density_controller_P=0.0, + PI_density_controller_I=0.0, + PI_density_target_amplitude=1.0, + PI_density_target_r_profile="constant", + PI_density_target_r_width=1.0, + PI_density_target_r_relative_minimum=0.0, + PI_density_target_z_profile="constant", + PI_density_target_z_width=1.0, + PI_density_target_z_relative_minimum=0.0, + recycling_controller_fraction=0.5, + ) + + r_amplitude = get_source_profile(input["r_profile"], input["r_width"], + input["r_relative_minimum"], r) + z_amplitude = get_source_profile(input["z_profile"], input["z_width"], + input["z_relative_minimum"], z) + + if input["source_type"] == "recycling" recycling = input["recycling_controller_fraction"] if recycling ≤ 0.0 # Don't allow 0.0 as this is the default value, but makes no sense to have @@ -171,34 +229,15 @@ function setup_external_sources!(input_dict, r, z, electron_physics) end controller_source_profile ./= controller_source_integral end - - PI_density_target = nothing - PI_controller_amplitude = nothing - PI_density_target_ir = nothing - PI_density_target_iz = nothing - PI_density_target_rank = nothing - elseif input["source_type"] ∈ ("Maxwellian", "energy", "alphas", "alphas-with-losses", "beam", "beam-with-losses") - PI_density_target = nothing - PI_controller_amplitude = nothing - controller_source_profile = nothing - PI_density_target_ir = nothing - PI_density_target_iz = nothing - PI_density_target_rank = nothing else - error("Unrecognised source_type=$(input["source_type"])." - * "Possible values are: Maxwellian, density_profile_control, " - * "density_midpoint_control, recycling (for neutrals only)") + error("Unrecognised neutral source_type=$(input["source_type"])." + * "Possible values are: recycling ") end - return (; (Symbol(k)=>v for (k,v) ∈ input)..., r_amplitude=r_amplitude, - z_amplitude=z_amplitude, PI_density_target=PI_density_target, - PI_controller_amplitude=PI_controller_amplitude, - controller_source_profile=controller_source_profile, - PI_density_target_ir=PI_density_target_ir, - PI_density_target_iz=PI_density_target_iz, - PI_density_target_rank=PI_density_target_rank) + return (; (Symbol(k)=>v for (k,v) ∈ input)..., + r_amplitude=r_amplitude, z_amplitude=z_amplitude, + controller_source_profile=controller_source_profile) end - function get_electron_settings(ion_settings) # Note most settings for the electron source are copied from the ion source, # because we require that the particle sources are the same for ions and @@ -226,14 +265,14 @@ function setup_external_sources!(input_dict, r, z, electron_physics) source_type=ion_settings.source_type) end - ion_settings = get_settings(false) + ion_settings = get_settings_ions() if electron_physics ∈ (braginskii_fluid, kinetic_electrons, kinetic_electrons_with_temperature_equation) electron_settings = get_electron_settings(ion_settings) else electron_settings = (active=false,) end - neutral_settings = get_settings(true) + neutral_settings = get_settings_neutrals() return (ion=ion_settings, electron=electron_settings, neutral=neutral_settings) end From 0c67d262a5e7ff1d8ca908bb14c3da247661216b Mon Sep 17 00:00:00 2001 From: Lucas McConnell Date: Fri, 6 Sep 2024 20:21:10 +0100 Subject: [PATCH 03/87] Convert form of ion_settings, electron_settings and neutral_settings from NamedTuple to structs --- moment_kinetics/src/external_sources.jl | 118 +++++++++++++++---- moment_kinetics/src/input_structs.jl | 143 ++++++++++++++++++++++++ 2 files changed, 239 insertions(+), 22 deletions(-) diff --git a/moment_kinetics/src/external_sources.jl b/moment_kinetics/src/external_sources.jl index a264a1191..5295176f3 100644 --- a/moment_kinetics/src/external_sources.jl +++ b/moment_kinetics/src/external_sources.jl @@ -149,14 +149,11 @@ function setup_external_sources!(input_dict, r, z, electron_physics) * "Possible values are: Maxwellian, density_profile_control, " * "density_midpoint_control") end - - return (; (Symbol(k)=>v for (k,v) ∈ input)..., r_amplitude=r_amplitude, + println(input) + return ion_source_profile(; Dict(Symbol(k)=>v for (k,v) ∈ input)..., r_amplitude, z_amplitude=z_amplitude, PI_density_target=PI_density_target, - PI_controller_amplitude=PI_controller_amplitude, - controller_source_profile=controller_source_profile, - PI_density_target_ir=PI_density_target_ir, - PI_density_target_iz=PI_density_target_iz, - PI_density_target_rank=PI_density_target_rank) + PI_controller_amplitude, controller_source_profile, + PI_density_target_ir, PI_density_target_iz, PI_density_target_rank) end function get_settings_neutrals() @@ -177,7 +174,7 @@ function setup_external_sources!(input_dict, r, z, electron_physics) z_profile="constant", z_width=1.0, z_relative_minimum=0.0, - source_type="recycling", # "energy", "alphas", "alphas-with-losses", "beam", "beam-with-losses" + source_type="Maxwellian", # "energy", "alphas", "alphas-with-losses", "beam", "beam-with-losses" PI_density_controller_P=0.0, PI_density_controller_I=0.0, PI_density_target_amplitude=1.0, @@ -187,15 +184,76 @@ function setup_external_sources!(input_dict, r, z, electron_physics) PI_density_target_z_profile="constant", PI_density_target_z_width=1.0, PI_density_target_z_relative_minimum=0.0, - recycling_controller_fraction=0.5, + recycling_controller_fraction=0.0, ) r_amplitude = get_source_profile(input["r_profile"], input["r_width"], input["r_relative_minimum"], r) z_amplitude = get_source_profile(input["z_profile"], input["z_width"], input["z_relative_minimum"], z) + if input["source_type"] == "density_profile_control" + PI_density_target_amplitude = input["PI_density_target_amplitude"] + PI_density_target_r_factor = + get_source_profile(input["PI_density_target_r_profile"], + input["PI_density_target_r_width"], + input["PI_density_target_r_relative_minimum"], r) + PI_density_target_z_factor = + get_source_profile(input["PI_density_target_z_profile"], + input["PI_density_target_z_width"], + input["PI_density_target_z_relative_minimum"], z) + PI_density_target = allocate_shared_float(z.n,r.n) + @serial_region begin + for ir ∈ 1:r.n, iz ∈ 1:z.n + PI_density_target[iz,ir] = + PI_density_target_amplitude * PI_density_target_r_factor[ir] * + PI_density_target_z_factor[iz] + end + end + PI_controller_amplitude = nothing + controller_source_profile = nothing + PI_density_target_ir = nothing + PI_density_target_iz = nothing + PI_density_target_rank = nothing + elseif input["source_type"] == "density_midpoint_control" + PI_density_target = input["PI_density_target_amplitude"] + + if comm_block[] != MPI.COMM_NULL + PI_controller_amplitude = allocate_shared_float(1) + controller_source_profile = allocate_shared_float(z.n, r.n) + else + PI_controller_amplitude = allocate_float(1) + controller_source_profile = allocate_float(z.n, r.n) + end + for ir ∈ 1:r.n, iz ∈ 1:z.n + controller_source_profile[iz,ir] = r_amplitude[ir] * z_amplitude[iz] + end - if input["source_type"] == "recycling" + # Find the indices, and process rank of the point at r=0, z=0. + # The result of findfirst() will be `nothing` if the point was not found. + PI_density_target_ir = findfirst(x->abs(x)<1.e-14, r.grid) + PI_density_target_iz = findfirst(x->abs(x)<1.e-14, z.grid) + if block_rank[] == 0 + # Only need to do communications from the root process of each + # shared-memory block + if PI_density_target_ir !== nothing && PI_density_target_iz !== nothing + PI_density_target_rank = iblock_index[] + else + PI_density_target_rank = 0 + end + if comm_inter_block[] != MPI.COMM_NULL + PI_density_target_rank = MPI.Allreduce(PI_density_target_rank, +, + comm_inter_block[]) + end + if PI_density_target_rank == 0 && iblock_index[] == 0 && + (PI_density_target_ir === nothing || + PI_density_target_iz === nothing) + error("No grid point with r=0 and z=0 was found for the " + * "'density_midpoint' controller.") + end + else + PI_density_target_rank = nothing + end + elseif input["source_type"] == "recycling" recycling = input["recycling_controller_fraction"] if recycling ≤ 0.0 # Don't allow 0.0 as this is the default value, but makes no sense to have @@ -229,16 +287,31 @@ function setup_external_sources!(input_dict, r, z, electron_physics) end controller_source_profile ./= controller_source_integral end + + PI_density_target = nothing + PI_controller_amplitude = nothing + PI_density_target_ir = nothing + PI_density_target_iz = nothing + PI_density_target_rank = nothing + elseif input["source_type"] ∈ ("Maxwellian", "energy", "alphas", "alphas-with-losses", "beam", "beam-with-losses") + PI_density_target = nothing + PI_controller_amplitude = nothing + controller_source_profile = nothing + PI_density_target_ir = nothing + PI_density_target_iz = nothing + PI_density_target_rank = nothing else error("Unrecognised neutral source_type=$(input["source_type"])." - * "Possible values are: recycling ") + * "Possible values are: Maxwellian, density_profile_control, " + * "density_midpoint_control, recycling (for neutrals only)") end - return (; (Symbol(k)=>v for (k,v) ∈ input)..., - r_amplitude=r_amplitude, z_amplitude=z_amplitude, - controller_source_profile=controller_source_profile) + return neutral_source_profile(; Dict(Symbol(k)=>v for (k,v) ∈ input)..., r_amplitude, + z_amplitude=z_amplitude, PI_density_target=PI_density_target, + PI_controller_amplitude, controller_source_profile, + PI_density_target_ir, PI_density_target_iz, PI_density_target_rank) end - function get_electron_settings(ion_settings) + function get_settings_electrons(ion_settings) # Note most settings for the electron source are copied from the ion source, # because we require that the particle sources are the same for ions and # electrons. `source_T` can be set independently, and when using @@ -259,21 +332,22 @@ function setup_external_sources!(input_dict, r, z, electron_physics) end input["source_strength"] = ion_settings.source_strength end - return (; (Symbol(k)=>v for (k,v) ∈ input)..., active=ion_settings.active, - r_amplitude=ion_settings.r_amplitude, - z_amplitude=ion_settings.z_amplitude, - source_type=ion_settings.source_type) + return electron_source_profile(input["source_strength"], input["source_T"], + ion_settings.active, ion_settings.r_amplitude, + ion_settings.z_amplitude, ion_settings.source_type) end ion_settings = get_settings_ions() if electron_physics ∈ (braginskii_fluid, kinetic_electrons, kinetic_electrons_with_temperature_equation) - electron_settings = get_electron_settings(ion_settings) + electron_settings = get_settings_electrons(ion_settings) else - electron_settings = (active=false,) + electron_settings = electron_source_profile(ion_settings.source_strength, + ion_settings.source_T, false, ion_settings.r_amplitude, + ion_settings.z_amplitude, ion_settings.source_type) end neutral_settings = get_settings_neutrals() - + return (ion=ion_settings, electron=electron_settings, neutral=neutral_settings) end diff --git a/moment_kinetics/src/input_structs.jl b/moment_kinetics/src/input_structs.jl index 30bc39cb2..ebf735495 100644 --- a/moment_kinetics/src/input_structs.jl +++ b/moment_kinetics/src/input_structs.jl @@ -12,6 +12,7 @@ export mk_to_toml export species_parameters, species_parameters_mutable export species_composition export drive_input, drive_input_mutable +export ion_source_profile, electron_source_profile, neutral_source_profile export collisions_input, krook_collisions_input, fkpl_collisions_input export io_input export pp_input @@ -383,6 +384,148 @@ struct drive_input force_Er_zero_at_wall::Bool end +""" +Source profile structs for ions and electrons which allows them to have any number +of different sources (from wall perhaps, superposition of core sources, etc.). These +sources are then contained in a vector of structs. + +Since the ion source must be the same as the electron source in all respects (apart +from possibly a different electron temperature or source strength), the electron +vector of source profile structs will be a kind of mirror of the ion vector of structs. +""" +Base.@kwdef struct ion_source_profile + # struct containing source profile data for ions + # is the source active or not + active::Bool + # An overall multiplier for the strength (i.e. 0.0 would turn off the source) + source_strength::mk_float + # For use with "energy" option, Krook source (...) + source_n::mk_float + # Temperature of source (variation along z can be introduced later) + source_T::mk_float + # birth speed for "alphas" option + source_v0::mk_float + # birth vpa for "beam" option + source_vpa0::mk_float + # birth vperp for "beam" option + source_vperp0::mk_float + # strength of sink in "alphas-with-losses" & "beam-with-losses" option + sink_strength::mk_float + # thermal speed for sink in "alphas-with-losses" & "beam-with-losses" option + sink_vth::mk_float + # profile for source in r ('constant' or 'gaussian' or 'parabolic' etc.) + r_profile::String + # width of source in r (doesn't apply to constant profile) + r_width::mk_float + # relative minimum of source in r, acts as the baseline + r_relative_minimum::mk_float + # profile for source in z ('constant' or 'gaussian' or 'parabolic' etc.) + z_profile::String + # width of source in z (doesn't apply to constant profile) + z_width::mk_float + # relative minimum of source in z, acts as the baseline (so you can elevate + # your gaussian source above 0, for example) + z_relative_minimum::mk_float + # velocity profile for the source, Maxwellian would be default, can have beams too + source_type::String #"Maxwellian" "energy", "alphas", "alphas-with-losses", "beam", "beam-with-losses" + # proportional integral controllers - for when you want to find a source profile that matches + # a target density + PI_density_controller_P::mk_float + PI_density_controller_I::mk_float + PI_density_target_amplitude::mk_float + PI_density_target_r_profile::String + PI_density_target_r_width::mk_float + PI_density_target_r_relative_minimum::mk_float + PI_density_target_z_profile::String + PI_density_target_z_width::mk_float + PI_density_target_z_relative_minimum::mk_float + recycling_controller_fraction::mk_float + # r_amplitude through the r coordinate (in 1D this can just be set to 1.0) + r_amplitude::Vector{mk_float} + # z_amplitude through the z coordinate, which will have your gaussian profile, + # constant profile, parabolic, etc.. + z_amplitude::Vector{mk_float} + PI_density_target::Union{mk_float, Nothing, MPISharedArray{mk_float,2}} + PI_controller_amplitude::Union{Nothing, MPISharedArray{mk_float,1}} + controller_source_profile::Union{Nothing, MPISharedArray{mk_float,2}, Array{mk_float, 2}} + PI_density_target_ir::Union{mk_int, Nothing} + PI_density_target_iz::Union{mk_int, Nothing} + PI_density_target_rank::Union{mk_int, Nothing} #possibly this should have Int64 as well, + # in the event that the code is running with mk_int = Int32 but the rank is set to 0::Int64 +end + +Base.@kwdef struct electron_source_profile + # most of the electron parameters must be the same as for ions, so only + # source strength (in the case of an ion energy source) and source Temperature + # can be different. The other four are set by the ion source profile. + source_strength::mk_float + source_T::mk_float + active::Bool + r_amplitude::Vector{mk_float} + z_amplitude::Vector{mk_float} + source_type::String +end + +Base.@kwdef struct neutral_source_profile + # struct containing source profile data for neutrals + # is the source active or not + active::Bool + # An overall multiplier for the strength (i.e. 0.0 would turn off the source) + source_strength::mk_float + # For use with "energy" option, Krook source (...) + source_n::mk_float + # Temperature of source (variation along z can be introduced later) + source_T::mk_float + # birth speed for "alphas" option + source_v0::mk_float + # birth vpa for "beam" option + source_vpa0::mk_float + # birth vperp for "beam" option + source_vperp0::mk_float + # strength of sink in "alphas-with-losses" & "beam-with-losses" option + sink_strength::mk_float + # thermal speed for sink in "alphas-with-losses" & "beam-with-losses" option + sink_vth::mk_float + # profile for source in r ('constant' or 'gaussian' or 'parabolic' etc.) + r_profile::String + # width of source in r (doesn't apply to constant profile) + r_width::mk_float + # relative minimum of source in r, acts as the baseline + r_relative_minimum::mk_float + # profile for source in z ('constant' or 'gaussian' or 'parabolic' etc.) + z_profile::String + # width of source in z (doesn't apply to constant profile) + z_width::mk_float + # relative minimum of source in z, acts as the baseline (so you can elevate + # your gaussian source above 0, for example) + z_relative_minimum::mk_float + # velocity profile for the source, Maxwellian would be default, can have beams too + source_type::String #"Maxwellian" "energy", "alphas", "alphas-with-losses", "beam", "beam-with-losses" + # proportional integral controllers - for when you want to find a source profile that matches + # a target density + PI_density_controller_P::mk_float + PI_density_controller_I::mk_float + PI_density_target_amplitude::mk_float + PI_density_target_r_profile::String + PI_density_target_r_width::mk_float + PI_density_target_r_relative_minimum::mk_float + PI_density_target_z_profile::String + PI_density_target_z_width::mk_float + PI_density_target_z_relative_minimum::mk_float + recycling_controller_fraction::mk_float + # r_amplitude through the r coordinate (in 1D this can just be set to 1.0) + r_amplitude::Vector{mk_float} + # z_amplitude through the z coordinate, which will have your gaussian profile, + # constant profile, parabolic, etc.. + z_amplitude::Vector{mk_float} + PI_density_target::Union{mk_float, Nothing, MPISharedArray{mk_float,2}} + PI_controller_amplitude::Union{Nothing, MPISharedArray{mk_float,1}} + controller_source_profile::Union{Nothing, MPISharedArray{mk_float,2}, Array{mk_float, 2}} + PI_density_target_ir::Union{mk_int, Nothing} + PI_density_target_iz::Union{mk_int, Nothing} + PI_density_target_rank::Union{mk_int, Nothing} #possibly this should have Int64 as well, + # in the event that the code is running with mk_int = Int32 but the rank is set to 0::Int64 +end """ Structs set up for the collision operators so far in use. These will each be contained in the main collisions_input struct below, as substructs. From 372988aa7a76b065b121584eb3f57657e14ca2ab Mon Sep 17 00:00:00 2001 From: Lucas McConnell Date: Fri, 6 Sep 2024 20:28:15 +0100 Subject: [PATCH 04/87] Add options to ion and neutral source profile type error --- moment_kinetics/src/external_sources.jl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/moment_kinetics/src/external_sources.jl b/moment_kinetics/src/external_sources.jl index 5295176f3..dcaca6905 100644 --- a/moment_kinetics/src/external_sources.jl +++ b/moment_kinetics/src/external_sources.jl @@ -147,7 +147,8 @@ function setup_external_sources!(input_dict, r, z, electron_physics) else error("Unrecognised ion source_type=$(input["source_type"])." * "Possible values are: Maxwellian, density_profile_control, " - * "density_midpoint_control") + * "density_midpoint_control, energy, alphas, alphas-with-losses, " + * "beam, beam-with-losses") end println(input) return ion_source_profile(; Dict(Symbol(k)=>v for (k,v) ∈ input)..., r_amplitude, @@ -303,7 +304,8 @@ function setup_external_sources!(input_dict, r, z, electron_physics) else error("Unrecognised neutral source_type=$(input["source_type"])." * "Possible values are: Maxwellian, density_profile_control, " - * "density_midpoint_control, recycling (for neutrals only)") + * "density_midpoint_control, energy, alphas, alphas-with-losses, " + * "beam, beam-with-losses, recycling (for neutrals only)") end return neutral_source_profile(; Dict(Symbol(k)=>v for (k,v) ∈ input)..., r_amplitude, From 4a74181e55d116dfed18daf1f08f08edbd6128dc Mon Sep 17 00:00:00 2001 From: Lucas McConnell Date: Fri, 6 Sep 2024 21:44:46 +0100 Subject: [PATCH 05/87] Change names of structs from 'profile' to 'data' --- moment_kinetics/src/input_structs.jl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/moment_kinetics/src/input_structs.jl b/moment_kinetics/src/input_structs.jl index ebf735495..284cf147a 100644 --- a/moment_kinetics/src/input_structs.jl +++ b/moment_kinetics/src/input_structs.jl @@ -12,7 +12,7 @@ export mk_to_toml export species_parameters, species_parameters_mutable export species_composition export drive_input, drive_input_mutable -export ion_source_profile, electron_source_profile, neutral_source_profile +export ion_source_data, electron_source_data, neutral_source_data export collisions_input, krook_collisions_input, fkpl_collisions_input export io_input export pp_input @@ -393,8 +393,8 @@ Since the ion source must be the same as the electron source in all respects (ap from possibly a different electron temperature or source strength), the electron vector of source profile structs will be a kind of mirror of the ion vector of structs. """ -Base.@kwdef struct ion_source_profile - # struct containing source profile data for ions +Base.@kwdef struct ion_source_data + # struct containing source data for ions # is the source active or not active::Bool # An overall multiplier for the strength (i.e. 0.0 would turn off the source) @@ -454,10 +454,10 @@ Base.@kwdef struct ion_source_profile # in the event that the code is running with mk_int = Int32 but the rank is set to 0::Int64 end -Base.@kwdef struct electron_source_profile +Base.@kwdef struct electron_source_data # most of the electron parameters must be the same as for ions, so only # source strength (in the case of an ion energy source) and source Temperature - # can be different. The other four are set by the ion source profile. + # can be different. The other four are set by the ion source data. source_strength::mk_float source_T::mk_float active::Bool @@ -466,8 +466,8 @@ Base.@kwdef struct electron_source_profile source_type::String end -Base.@kwdef struct neutral_source_profile - # struct containing source profile data for neutrals +Base.@kwdef struct neutral_source_data + # struct containing source data for neutrals # is the source active or not active::Bool # An overall multiplier for the strength (i.e. 0.0 would turn off the source) From a3812405e996e51e0a3c20b0b7609c7d527ed0f9 Mon Sep 17 00:00:00 2001 From: Lucas McConnell Date: Sat, 7 Sep 2024 10:37:05 +0100 Subject: [PATCH 06/87] Change create_moments_ion and create_moments_neutral functions to be compatible with source struct vectors --- moment_kinetics/src/velocity_moments.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/moment_kinetics/src/velocity_moments.jl b/moment_kinetics/src/velocity_moments.jl index 29684c26a..0b48035d7 100644 --- a/moment_kinetics/src/velocity_moments.jl +++ b/moment_kinetics/src/velocity_moments.jl @@ -138,7 +138,7 @@ function create_moments_ion(nz, nr, n_species, evolve_density, evolve_upar, entropy_production = allocate_shared_float(nz, nr, n_species) - if ion_source_settings.active + if any(x -> x.active, ion_source_settings) external_source_amplitude = allocate_shared_float(nz, nr) if evolve_density external_source_density_amplitude = allocate_shared_float(nz, nr) @@ -363,7 +363,7 @@ function create_moments_neutral(nz, nr, n_species, evolve_density, evolve_upar, dvth_dz = nothing end - if neutral_source_settings.active + if any(x -> x.active, neutral_source_settings) external_source_amplitude = allocate_shared_float(nz, nr) if evolve_density external_source_density_amplitude = allocate_shared_float(nz, nr) From fb0b082c44e057ddf26854eb93d8738b96d41801 Mon Sep 17 00:00:00 2001 From: Lucas McConnell Date: Sun, 8 Sep 2024 09:19:27 +0100 Subject: [PATCH 07/87] Restructure main initialisation files and update loops to view each source for each species as a vector of structs, rather than a NamedTuple for each. This means each amplitude array for the moments structs has one extra dimension, one for each source, so that each source can be applied to each species pdf in turn. --- .../src/electron_kinetic_equation.jl | 11 +- moment_kinetics/src/external_sources.jl | 633 +++++++++++------- moment_kinetics/src/initial_conditions.jl | 4 +- .../src/moment_kinetics_structs.jl | 30 +- moment_kinetics/src/time_advance.jl | 14 +- moment_kinetics/src/velocity_moments.jl | 74 +- 6 files changed, 450 insertions(+), 316 deletions(-) diff --git a/moment_kinetics/src/electron_kinetic_equation.jl b/moment_kinetics/src/electron_kinetic_equation.jl index fe1aeeb1e..e88476c29 100644 --- a/moment_kinetics/src/electron_kinetic_equation.jl +++ b/moment_kinetics/src/electron_kinetic_equation.jl @@ -1819,12 +1819,11 @@ function electron_kinetic_equation_euler_update!(fvec_out, fvec_in, moments, z, vperp, vpa, dt) end - if external_source_settings.electron.active - external_electron_source!(fvec_out.pdf_electron, fvec_in.pdf_electron, - moments.electron.dens, moments.electron.upar, moments, - composition, external_source_settings.electron, vperp, - vpa, dt) - end + total_external_electron_sources!(fvec_out.pdf_electron, fvec_in.pdf_electron, + moments.electron.dens, moments.electron.upar, moments, + composition, external_source_settings.electron, vperp, + vpa, dt) + if evolve_ppar electron_energy_equation!(fvec_out.electron_ppar, fvec_in.electron_ppar, diff --git a/moment_kinetics/src/external_sources.jl b/moment_kinetics/src/external_sources.jl index dcaca6905..2fc218aec 100644 --- a/moment_kinetics/src/external_sources.jl +++ b/moment_kinetics/src/external_sources.jl @@ -14,7 +14,9 @@ module external_sources export setup_external_sources!, external_ion_source!, external_neutral_source!, external_ion_source_controller!, external_neutral_source_controller!, initialize_external_source_amplitude!, - initialize_external_source_controller_integral! + initialize_external_source_controller_integral!, + total_external_ion_sources!, total_external_neutral_sources!, + total_external_ion_source_controllers!, total_external_neutral_source_controllers! using ..array_allocation: allocate_float, allocate_shared_float using ..calculus @@ -40,10 +42,10 @@ Returns a NamedTuple `(ion=ion_source_settings, neutral=neutral_source_settings) containing two NamedTuples of settings. """ function setup_external_sources!(input_dict, r, z, electron_physics) - function get_settings_ions() + function get_settings_ions(source_index, active_flag) input = set_defaults_and_check_section!( - input_dict, "ion_source"; - active=false, + input_dict, "ion_source_$source_index"; + active=active_flag, source_strength=1.0, source_n=1.0, source_T=1.0, @@ -150,17 +152,16 @@ function setup_external_sources!(input_dict, r, z, electron_physics) * "density_midpoint_control, energy, alphas, alphas-with-losses, " * "beam, beam-with-losses") end - println(input) - return ion_source_profile(; Dict(Symbol(k)=>v for (k,v) ∈ input)..., r_amplitude, + return ion_source_data(; Dict(Symbol(k)=>v for (k,v) ∈ input)..., r_amplitude, z_amplitude=z_amplitude, PI_density_target=PI_density_target, PI_controller_amplitude, controller_source_profile, PI_density_target_ir, PI_density_target_iz, PI_density_target_rank) end - function get_settings_neutrals() + function get_settings_neutrals(source_index, active_flag) input = set_defaults_and_check_section!( - input_dict, "neutral_source"; - active=false, + input_dict, "neutral_source_$source_index"; + active=active_flag, source_strength=1.0, source_n=1.0, source_T=get(input_dict, "T_wall", 1.0), @@ -308,7 +309,7 @@ function setup_external_sources!(input_dict, r, z, electron_physics) * "beam, beam-with-losses, recycling (for neutrals only)") end - return neutral_source_profile(; Dict(Symbol(k)=>v for (k,v) ∈ input)..., r_amplitude, + return neutral_source_data(; Dict(Symbol(k)=>v for (k,v) ∈ input)..., r_amplitude, z_amplitude=z_amplitude, PI_density_target=PI_density_target, PI_controller_amplitude, controller_source_profile, PI_density_target_ir, PI_density_target_iz, PI_density_target_rank) @@ -334,23 +335,51 @@ function setup_external_sources!(input_dict, r, z, electron_physics) end input["source_strength"] = ion_settings.source_strength end - return electron_source_profile(input["source_strength"], input["source_T"], + return electron_source_data(input["source_strength"], input["source_T"], ion_settings.active, ion_settings.r_amplitude, ion_settings.z_amplitude, ion_settings.source_type) end - ion_settings = get_settings_ions() + # put all ion sources into ion_source_data struct vector + ion_sources = ion_source_data[] + counter = 1 + while "ion_source_$counter" ∈ keys(input_dict) + push!(ion_sources, get_settings_ions(counter, true)) + counter += 1 + end + + # If there are no ion sources, add an inactive ion source to the vector + if counter == 1 + inactive_ion_source = get_settings_ions(1, false) + push!(ion_sources, inactive_ion_source) + counter += 1 + end + + # put all electron sources into electron_source_data struct vector, where + # each entry is a mirror of the ion source vector. + electron_sources = electron_source_data[] if electron_physics ∈ (braginskii_fluid, kinetic_electrons, kinetic_electrons_with_temperature_equation) - electron_settings = get_settings_electrons(ion_settings) + electron_sources .= get_settings_electrons.(ion_sources) else - electron_settings = electron_source_profile(ion_settings.source_strength, - ion_settings.source_T, false, ion_settings.r_amplitude, - ion_settings.z_amplitude, ion_settings.source_type) + # this is not very efficient because we're copying the same electron_settings + # for each ion source + push!(electron_sources, get_settings_electrons(inactive_ion_source)) end - neutral_settings = get_settings_neutrals() - - return (ion=ion_settings, electron=electron_settings, neutral=neutral_settings) + + # put all neutral sources into neutral_source_data struct vector + neutral_sources = neutral_source_data[] + counter = 1 + while "neutral_source_$counter" ∈ keys(input_dict) + push!(neutral_sources, get_settings_neutrals(counter, true)) + counter += 1 + end + # If there are no neutral sources, add an inactive neutral source to the vector + if counter == 1 + inactive_neutral_source = get_settings_neutrals(1, false) + push!(neutral_sources, inactive_neutral_source) + end + return (ion=ion_sources, electron=electron_sources, neutral=neutral_sources) end """ @@ -407,195 +436,204 @@ function initialize_external_source_amplitude!(moments, external_source_settings begin_r_z_region() ion_source_settings = external_source_settings.ion - if ion_source_settings.active - if ion_source_settings.source_type == "energy" - @loop_r_z ir iz begin - moments.ion.external_source_amplitude[iz,ir] = - ion_source_settings.source_strength * - ion_source_settings.r_amplitude[ir] * - ion_source_settings.z_amplitude[iz] - end - if moments.evolve_density + # The electron loop must be in the same as the ion loop so that each electron source + # can be matched to the corresponding ion source. + electron_source_settings = external_source_settings.electron + + for index ∈ eachindex(ion_source_settings) + if ion_source_settings[index].active + if ion_source_settings[index].source_type == "energy" @loop_r_z ir iz begin - moments.ion.external_source_density_amplitude[iz,ir] = 0.0 + moments.ion.external_source_amplitude[iz,ir,index] = + ion_source_settings[index].source_strength * + ion_source_settings[index].r_amplitude[ir] * + ion_source_settings[index].z_amplitude[iz] end - end - if moments.evolve_upar - @loop_r_z ir iz begin - moments.ion.external_source_momentum_amplitude[iz,ir] = - - moments.ion.dens[iz,ir] * moments.ion.upar[iz,ir] * - ion_source_settings.source_strength * - ion_source_settings.r_amplitude[ir] * - ion_source_settings.z_amplitude[iz] + if moments.evolve_density + @loop_r_z ir iz begin + moments.ion.external_source_density_amplitude[iz,ir,index] = 0.0 + end end - end - if moments.evolve_ppar + if moments.evolve_upar + @loop_r_z ir iz begin + moments.ion.external_source_momentum_amplitude[iz,ir,index]= + - moments.ion.dens[iz,ir] * moments.ion.upar[iz,ir] * + ion_source_settings[index].source_strength * + ion_source_settings[index].r_amplitude[ir] * + ion_source_settings[index].z_amplitude[iz] + end + end + if moments.evolve_ppar + @loop_r_z ir iz begin + moments.ion.external_source_pressure_amplitude[iz,ir,index] = + (0.5 * ion_source.source_T + + moments.ion.upar[iz,ir]^2 - moments.ion.ppar[iz,ir]) * + ion_source_settings[index].source_strength * + ion_source_settings[index].r_amplitude[ir] * + ion_source_settings[index].z_amplitude[iz] + end + end + else @loop_r_z ir iz begin - moments.ion.external_source_pressure_amplitude[iz,ir] = - (0.5 * ion_source_settings.source_T + - moments.ion.upar[iz,ir]^2 - moments.ion.ppar[iz,ir]) * - ion_source_settings.source_strength * - ion_source_settings.r_amplitude[ir] * - ion_source_settings.z_amplitude[iz] + moments.ion.external_source_amplitude[iz,ir,index] = + ion_source_settings[index].source_strength * + ion_source_settings[index].r_amplitude[ir] * + ion_source_settings[index].z_amplitude[iz] + end + if moments.evolve_density + @loop_r_z ir iz begin + moments.ion.external_source_density_amplitude[iz,ir,index] = + ion_source_settings[index].source_strength * + ion_source_settings[index].r_amplitude[ir] * + ion_source_settings[index].z_amplitude[iz] + end + end + if moments.evolve_upar + @loop_r_z ir iz begin + moments.ion.external_source_momentum_amplitude[iz,ir,index] = 0.0 + end + end + if moments.evolve_ppar + @loop_r_z ir iz begin + moments.ion.external_source_pressure_amplitude[iz,ir,index] = + (0.5 * ion_source_settings[index].source_T + + moments.ion.upar[iz,ir]^2) * + ion_source_settings[index].source_strength * + ion_source_settings[index].r_amplitude[ir] * + ion_source_settings[index].z_amplitude[iz] + end end end - else - @loop_r_z ir iz begin - moments.ion.external_source_amplitude[iz,ir] = - ion_source_settings.source_strength * - ion_source_settings.r_amplitude[ir] * - ion_source_settings.z_amplitude[iz] - end - if moments.evolve_density + end + + # now do same for electron sources, which (if present) are mostly mirrors of ion sources + println(electron_source_settings) + if electron_source_settings[index].active + if electron_source_settings[index].source_type == "energy" @loop_r_z ir iz begin - moments.ion.external_source_density_amplitude[iz,ir] = - ion_source_settings.source_strength * - ion_source_settings.r_amplitude[ir] * - ion_source_settings.z_amplitude[iz] + moments.electron.external_source_amplitude[iz,ir,index] = + electron_source_settings[index].source_strength * + electron_source_settings[index].r_amplitude[ir] * + electron_source_settings[index].z_amplitude[iz] end - end - if moments.evolve_upar @loop_r_z ir iz begin - moments.ion.external_source_momentum_amplitude[iz,ir] = 0.0 + moments.electron.external_source_density_amplitude[iz,ir,index] = 0.0 end - end - if moments.evolve_ppar @loop_r_z ir iz begin - moments.ion.external_source_pressure_amplitude[iz,ir] = - (0.5 * ion_source_settings.source_T + - moments.ion.upar[iz,ir]^2) * - ion_source_settings.source_strength * - ion_source_settings.r_amplitude[ir] * - ion_source_settings.z_amplitude[iz] + moments.electron.external_source_momentum_amplitude[iz,ir,index] = + - moments.electron.dens[iz,ir] * moments.electron.upar[iz,ir] * + electron_source_settings[index].source_strength * + electron_source_settings[index].r_amplitude[ir] * + electron_source_settings[index].z_amplitude[iz] end - end - end - end - - electron_source_settings = external_source_settings.electron - if electron_source_settings.active - if electron_source_settings.source_type == "energy" - @loop_r_z ir iz begin - moments.electron.external_source_amplitude[iz,ir] = - electron_source_settings.source_strength * - electron_source_settings.r_amplitude[ir] * - electron_source_settings.z_amplitude[iz] - end - @loop_r_z ir iz begin - moments.electron.external_source_density_amplitude[iz,ir] = 0.0 - end - @loop_r_z ir iz begin - moments.electron.external_source_momentum_amplitude[iz,ir] = - - moments.electron.dens[iz,ir] * moments.electron.upar[iz,ir] * - electron_source_settings.source_strength * - electron_source_settings.r_amplitude[ir] * - electron_source_settings.z_amplitude[iz] - end - @loop_r_z ir iz begin - moments.electron.external_source_pressure_amplitude[iz,ir] = - (0.5 * electron_source_settings.source_T + - moments.electron.upar[iz,ir]^2 - moments.electron.ppar[iz,ir]) * - electron_source_settings.source_strength * - electron_source_settings.r_amplitude[ir] * - electron_source_settings.z_amplitude[iz] - end - else - @loop_r_z ir iz begin - moments.electron.external_source_amplitude[iz,ir] = - moments.ion.external_source_amplitude[iz,ir] - end - if moments.evolve_density @loop_r_z ir iz begin - moments.electron.external_source_density_amplitude[iz,ir] = - moments.ion.external_source_density_amplitude[iz,ir] + moments.electron.external_source_pressure_amplitude[iz,ir,index] = + (0.5 * electron_source_settings[index].source_T + + moments.electron.upar[iz,ir]^2 - moments.electron.ppar[iz,ir]) * + electron_source_settings[index].source_strength * + electron_source_settings[index].r_amplitude[ir] * + electron_source_settings[index].z_amplitude[iz] end else @loop_r_z ir iz begin - # Note set this using *ion* settings to force electron density source - # to always be equal to ion density source (even when - # evolve_density=false) to ensure the source does not inject charge - # into the simulation. - moments.electron.external_source_density_amplitude[iz,ir] = - ion_source_settings.source_strength * - ion_source_settings.r_amplitude[ir] * - ion_source_settings.z_amplitude[iz] + moments.electron.external_source_amplitude[iz,ir,index] = + moments.ion.external_source_amplitude[iz,ir,index] + end + if moments.evolve_density + @loop_r_z ir iz begin + moments.electron.external_source_density_amplitude[iz,ir,index] = + moments.ion.external_source_density_amplitude[iz,ir,index] + end + else + @loop_r_z ir iz begin + # Note set this using *ion* settings to force electron density source + # to always be equal to ion density source (even when + # evolve_density=false) to ensure the source does not inject charge + # into the simulation. + moments.electron.external_source_density_amplitude[iz,ir,index] = + ion_source_settings[index].source_strength * + ion_source_settings[index].r_amplitude[ir] * + ion_source_settings[index].z_amplitude[iz] + end + end + @loop_r_z ir iz begin + moments.electron.external_source_momentum_amplitude[iz,ir,index] = 0.0 + end + @loop_r_z ir iz begin + moments.electron.external_source_pressure_amplitude[iz,ir,index] = + (0.5 * electron_source_settings[index].source_T + + moments.electron.upar[iz,ir]^2) * + moments.electron.external_source_amplitude[iz,ir,index] end - end - @loop_r_z ir iz begin - moments.electron.external_source_momentum_amplitude[iz,ir] = 0.0 - end - @loop_r_z ir iz begin - moments.electron.external_source_pressure_amplitude[iz,ir] = - (0.5 * electron_source_settings.source_T + - moments.electron.upar[iz,ir]^2) * - moments.electron.external_source_amplitude[iz,ir] end end end if n_neutral_species > 0 neutral_source_settings = external_source_settings.neutral - if neutral_source_settings.active - if neutral_source_settings.source_type == "energy" - @loop_r_z ir iz begin - moments.neutral.external_source_amplitude[iz,ir] = - neutral_source_settings.source_strength * - neutral_source_settings.r_amplitude[ir] * - neutral_source_settings.z_amplitude[iz] - end - if moments.evolve_density + for index ∈ eachindex(neutral_source_settings) + if neutral_source_settings[index].active + if neutral_source.source_type == "energy" @loop_r_z ir iz begin - moments.neutral.external_source_density_amplitude[iz,ir] = 0.0 + moments.neutral.external_source_amplitude[iz,ir,index] = + neutral_source_settings[index].source_strength * + neutral_source_settings[index].r_amplitude[ir] * + neutral_source_settings[index].z_amplitude[iz] end - end - if moments.evolve_upar - @loop_r_z ir iz begin - moments.neutral.external_source_momentum_amplitude[iz,ir] = - - moments.neutral.dens[iz,ir] * moments.neutral.upar[iz,ir] * - neutral_source_settings.source_strength * - neutral_source_settings.r_amplitude[ir] * - neutral_source_settings.z_amplitude[iz] + if moments.evolve_density + @loop_r_z ir iz begin + moments.neutral.external_source_density_amplitude[iz,ir,index] = 0.0 + end end - end - if moments.evolve_ppar - @loop_r_z ir iz begin - moments.neutral.external_source_pressure_amplitude[iz,ir] = - (0.5 * neutral_source_settings.source_T + - moments.neutral.upar[iz,ir]^2 - - moments.neutral.ppar[iz,ir]) * - neutral_source_settings.source_strength * - neutral_source_settings.r_amplitude[ir] * - neutral_source_settings.z_amplitude[iz] + if moments.evolve_upar + @loop_r_z ir iz begin + moments.neutral.external_source_momentum_amplitude[iz,ir,index] = + - moments.neutral.dens[iz,ir] * moments.neutral.upar[iz,ir] * + neutral_source_settings[index].source_strength * + neutral_source_settings[index].r_amplitude[ir] * + neutral_source_settings[index].z_amplitude[iz] + end end - end - else - @loop_r_z ir iz begin - moments.neutral.external_source_amplitude[iz,ir] = - neutral_source_settings.source_strength * - neutral_source_settings.r_amplitude[ir] * - neutral_source_settings.z_amplitude[iz] + if moments.evolve_ppar + @loop_r_z ir iz begin + moments.neutral.external_source_pressure_amplitude[iz,ir,index] = + (0.5 * neutral_source_settings[index].source_T + + moments.neutral.upar[iz,ir]^2 - + moments.neutral.ppar[iz,ir]) * + neutral_source_settings[index].source_strength * + neutral_source_settings[index].r_amplitude[ir] * + neutral_source_settings[index].z_amplitude[iz] + end end - if moments.evolve_density + else @loop_r_z ir iz begin - moments.neutral.external_source_density_amplitude[iz,ir] = - neutral_source_settings.source_strength * - neutral_source_settings.r_amplitude[ir] * - neutral_source_settings.z_amplitude[iz] + moments.neutral.external_source_amplitude[iz,ir,index] = + neutral_source_settings[index].source_strength * + neutral_source_settings[index].r_amplitude[ir] * + neutral_source_settings[index].z_amplitude[iz] end - end - if moments.evolve_upar - @loop_r_z ir iz begin - moments.neutral.external_source_momentum_amplitude[iz,ir] = 0.0 + if moments.evolve_density + @loop_r_z ir iz begin + moments.neutral.external_source_density_amplitude[iz,ir,index] = + neutral_source_settings[index].source_strength * + neutral_source_settings[index].r_amplitude[ir] * + neutral_source_settings[index].z_amplitude[iz] + end end - end - if moments.evolve_ppar - @loop_r_z ir iz begin - moments.neutral.external_source_pressure_amplitude[iz,ir] = - (0.5 * neutral_source_settings.source_T + - moments.neutral.uz[iz,ir]^2) * - neutral_source_settings.source_strength * - neutral_source_settings.r_amplitude[ir] * - neutral_source_settings.z_amplitude[iz] + if moments.evolve_upar + @loop_r_z ir iz begin + moments.neutral.external_source_momentum_amplitude[iz,ir,index] = 0.0 + end + end + if moments.evolve_ppar + @loop_r_z ir iz begin + moments.neutral.external_source_pressure_amplitude[iz,ir,index] = + (0.5 * neutral_source_settings[index].source_T + + moments.neutral.uz[iz,ir]^2) * + neutral_source_settings[index].source_strength * + neutral_source_settings[index].r_amplitude[ir] * + neutral_source_settings[index].z_amplitude[iz] + end end end end @@ -618,21 +656,21 @@ function initialize_external_source_controller_integral!( begin_serial_region() @serial_region begin ion_source_settings = external_source_settings.ion - if ion_source_settings.active - if ion_source_settings.PI_density_controller_I != 0.0 && - ion_source_settings.source_type ∈ ("density_profile_control", - "density_midpoint_control") - moments.ion.external_source_controller_integral .= 0.0 + for index ∈ eachindex(ion_source_settings) + if ion_source_settings[index].active && + ion_source_settings[index].PI_density_controller_I != 0.0 && + ion_source_settings[index].source_type ∈ ("density_profile_control", "density_midpoint_control") + moments.ion.external_source_controller_integral[:, :, index] .= 0.0 end end if n_neutral_species > 0 neutral_source_settings = external_source_settings.neutral - if neutral_source_settings.active - if neutral_source_settings.PI_density_controller_I != 0.0 && - neutral_source_settings.source_type ∈ ("density_profile_control", - "density_midpoint_control") - moments.neutral.external_source_controller_integral .= 0.0 + for index ∈ eachindex(neutral_source_settings) + if neutral_source_settings[index].active && + neutral_source_settings[index].PI_density_controller_I != 0.0 && + neutral_source_settings[index].source_type ∈ ("density_profile_control", "density_midpoint_control") + moments.neutral.external_source_controller_integral[:, :, index] .= 0.0 end end end @@ -641,17 +679,33 @@ function initialize_external_source_controller_integral!( return nothing end +""" + total_external_ion_sources!(pdf, fvec, moments, ion_sources, vperp, vpa, dt, scratch_dummy) + +Contribute all of the ion sources to the ion pdf, one by one. +""" +function total_external_ion_sources!(pdf, fvec, moments, ion_sources, vperp, + vpa, dt, scratch_dummy) + for index ∈ eachindex(ion_sources) + if ion_sources[index].active + external_ion_source!(pdf, fvec, moments, ion_sources[index], + index, vperp, vpa, dt, scratch_dummy) + end + end + return nothing +end + """ external_ion_source!(pdf, fvec, moments, ion_source_settings, vperp, vpa, dt) Add external source term to the ion kinetic equation. """ -function external_ion_source!(pdf, fvec, moments, ion_source_settings, vperp, vpa, dt, scratch_dummy) +function external_ion_source!(pdf, fvec, moments, ion_source, index, vperp, vpa, dt, scratch_dummy) - source_type = ion_source_settings.source_type - source_amplitude = moments.ion.external_source_amplitude - source_T = ion_source_settings.source_T - source_n = ion_source_settings.source_n + source_type = ion_source.source_type + @views source_amplitude = moments.ion.external_source_amplitude[:,:,index] + source_T = ion_source.source_T + source_n = ion_source.source_n if vperp.n == 1 vth_factor = 1.0 / sqrt(source_T) else @@ -862,6 +916,24 @@ function external_ion_source!(pdf, fvec, moments, ion_source_settings, vperp, vp return nothing end +""" + total_external_electron_sources!(pdf, fvec, moments, electron_sources, vperp, vpa, dt, scratch_dummy) + +Contribute all of the electron sources to the electron pdf, one by one. +""" +function total_external_electron_sources!(pdf_out, pdf_in, electron_density, electron_upar, + moments, composition, electron_sources, vperp, + vpa, dt) + for index ∈ eachindex(electron_sources) + if electron_sources[index].active + external_electron_source!(pdf_out, pdf_in, electron_density, electron_upar, + moments, composition, electron_sources[index], index, + vperp, vpa, dt) + end + end + return nothing +end + """ external_electron_source!(pdf, fvec, moments, electron_source_settings, vperp, vpa, dt) @@ -869,14 +941,14 @@ end Add external source term to the electron kinetic equation. """ function external_electron_source!(pdf_out, pdf_in, electron_density, electron_upar, - moments, composition, electron_source_settings, vperp, + moments, composition, electron_source, index, vperp, vpa, dt) begin_r_z_vperp_region() me_over_mi = composition.me_over_mi - source_amplitude = moments.electron.external_source_amplitude - source_T = electron_source_settings.source_T + @views source_amplitude = moments.electron.external_source_amplitude[:, :, index] + source_T = electron_source.source_T if vperp.n == 1 vth_factor = 1.0 / sqrt(source_T / me_over_mi) else @@ -913,18 +985,36 @@ function external_electron_source!(pdf_out, pdf_in, electron_density, electron_u return nothing end + +""" + total_external_neutral_sources!(pdf, fvec, moments, neutral_sources, vperp, vpa, dt, scratch_dummy) + +Contribute all of the neutral sources to the neutral pdf, one by one. +""" +function total_external_neutral_sources!(pdf, fvec, moments, neutral_sources, + vzeta, vr, vz, dt) + for index ∈ eachindex(neutral_sources) + if neutral_sources[index].active + external_neutral_source!(pdf, fvec, moments, neutral_sources[index], + index, vzeta, vr, vz, dt) + end + end + return nothing +end + + """ external_neutral_source!(pdf, fvec, moments, neutral_source_settings, vzeta, vr, vz, dt) Add external source term to the neutral kinetic equation. """ -function external_neutral_source!(pdf, fvec, moments, neutral_source_settings, vzeta, vr, - vz, dt) +function external_neutral_source!(pdf, fvec, moments, neutral_source, index, vzeta, vr, + vz, dt) begin_sn_r_z_vzeta_vr_region() - source_amplitude = moments.neutral.external_source_amplitude - source_T = neutral_source_settings.source_T + @views source_amplitude = moments.neutral.external_source_amplitude[:, :, index] + source_T = neutral_source.source_T if vzeta.n == 1 && vr.n == 1 vth_factor = 1.0 / sqrt(source_T) else @@ -1009,13 +1099,27 @@ function external_neutral_source!(pdf, fvec, moments, neutral_source_settings, v return nothing end +""" + total_external_ion_source_controllers!(fvec_in, moments, ion_sources, dt) + +Contribute all of the ion source controllers to fvec_in, one by one. +""" +function total_external_ion_source_controllers!(fvec_in, moments, ion_sources, dt) + for index ∈ eachindex(ion_sources) + if ion_sources[index].active + external_ion_source_controller!(fvec_in, moments, ion_sources[index], index, dt) + end + end + return nothing +end + """ external_ion_source_controller!(fvec_in, moments, ion_source_settings, dt) Calculate the amplitude when using a PI controller for the density to set the external source amplitude. """ -function external_ion_source_controller!(fvec_in, moments, ion_source_settings, dt) +function external_ion_source_controller!(fvec_in, moments, ion_source_settings, index, dt) begin_r_z_region() is = 1 @@ -1027,15 +1131,15 @@ function external_ion_source_controller!(fvec_in, moments, ion_source_settings, if ion_source_settings.source_type == "Maxwellian" if moments.evolve_ppar @loop_r_z ir iz begin - ion_moments.external_source_pressure_amplitude[iz,ir] = + ion_moments.external_source_pressure_amplitude[iz,ir,index] = (0.5 * ion_source_settings.source_T + upar[iz,ir,is]^2) * - ion_moments.external_source_amplitude[iz,ir] + ion_moments.external_source_amplitude[iz,ir,index] end end elseif ion_source_settings.source_type == "energy" if moments.evolve_upar @loop_r_z ir iz begin - ion_moments.external_source_momentum_amplitude[iz,ir] = + ion_moments.external_source_momentum_amplitude[iz,ir,index] = - density[iz,ir] * upar[iz,ir] * ion_source_settings.source_strength * ion_source_settings.r_amplitude[ir] * @@ -1044,7 +1148,7 @@ function external_ion_source_controller!(fvec_in, moments, ion_source_settings, end if moments.evolve_ppar @loop_r_z ir iz begin - ion_moments.external_source_pressure_amplitude[iz,ir] = + ion_moments.external_source_pressure_amplitude[iz,ir,index] = (0.5 * ion_source_settings.source_T + upar[iz,ir]^2 - ppar[iz,ir]) * ion_source_settings.source_strength * ion_source_settings.r_amplitude[ir] * @@ -1065,13 +1169,13 @@ function external_ion_source_controller!(fvec_in, moments, ion_source_settings, ion_source_settings.PI_density_target_ir, is] n_error = ion_source_settings.PI_density_target - n_mid - ion_moments.external_source_controller_integral[1,1] += + ion_moments.external_source_controller_integral[1,1,index] += dt * ion_source_settings.PI_density_controller_I * n_error # Only want a source, so never allow amplitude to be negative amplitude = max( ion_source_settings.PI_density_controller_P * n_error + - ion_moments.external_source_controller_integral[1,1], + ion_moments.external_source_controller_integral[1,1,index], 0) else amplitude = nothing @@ -1085,18 +1189,18 @@ function external_ion_source_controller!(fvec_in, moments, ion_source_settings, amplitude = controller_amplitude[1] @loop_r_z ir iz begin - ion_moments.external_source_amplitude[iz,ir] = + ion_moments.external_source_amplitude[iz,ir,index] = amplitude * ion_source_settings.controller_source_profile[iz,ir] end if moments.evolve_density @loop_r_z ir iz begin - ion_moments.external_source_density_amplitude[iz,ir] = + ion_moments.external_source_density_amplitude[iz,ir,index] = amplitude * ion_source_settings.controller_source_profile[iz,ir] end end if moments.evolve_ppar @loop_r_z ir iz begin - ion_moments.external_source_pressure_amplitude[iz,ir] = + ion_moments.external_source_pressure_amplitude[iz,ir,index] = (0.5 * ion_source_settings.source_T + upar[iz,ir,is]^2) * amplitude * ion_source_settings.controller_source_profile[iz,ir] end @@ -1111,20 +1215,20 @@ function external_ion_source_controller!(fvec_in, moments, ion_source_settings, amplitude = ion_moments.external_source_amplitude @loop_r_z ir iz begin n_error = target[iz,ir] - density[iz,ir,is] - integral[iz,ir] += dt * I * n_error + integral[iz,ir,index] += dt * I * n_error # Only want a source, so never allow amplitude to be negative - amplitude[iz,ir] = max(P * n_error + integral[iz,ir], 0) + amplitude[iz,ir,index] = max(P * n_error + integral[iz,ir,index], 0) end if moments.evolve_density @loop_r_z ir iz begin - ion_moments.external_source_density_amplitude[iz,ir] = amplitude[iz,ir] + ion_moments.external_source_density_amplitude[iz,ir,index] = amplitude[iz,ir,index] end end if moments.evolve_ppar @loop_r_z ir iz begin - ion_moments.external_source_pressure_amplitude[iz,ir] = + ion_moments.external_source_pressure_amplitude[iz,ir,index] = (0.5 * ion_source_settings.source_T + upar[iz,ir,is]^2) * - amplitude[iz,ir] + amplitude[iz,ir,index] end end elseif ion_source_settings.source_type == "alphas" @@ -1142,6 +1246,20 @@ function external_ion_source_controller!(fvec_in, moments, ion_source_settings, return nothing end +""" + total_external_electron_source_controllers!(fvec_in, moments, electron_sources, dt) + +Contribute all of the electron source controllers to fvec_in, one by one. +""" +function total_external_electron_source_controllers!(fvec_in, moments, electron_sources, dt) + for index ∈ eachindex(electron_sources) + if electron_sources[index].active + external_electron_source_controller!(fvec_in, moments, electron_sources[index], index, dt) + end + end + return nothing +end + """ external_electron_source_controller!(fvec_in, moments, electron_source_settings, dt) @@ -1155,30 +1273,30 @@ called before this function is called so that `moments.ion.external_source_ampli up to date. """ function external_electron_source_controller!(fvec_in, moments, electron_source_settings, - dt) + index, dt) begin_r_z_region() is = 1 electron_moments = moments.electron - ion_source_amplitude = moments.ion.external_source_amplitude + @views ion_source_amplitude = moments.ion.external_source_amplitude[:, :, index] if electron_source_settings.source_type == "Maxwellian" @loop_r_z ir iz begin - electron_moments.external_source_pressure_amplitude[iz,ir] = + electron_moments.external_source_pressure_amplitude[iz,ir,index] = (0.5 * electron_source_settings.source_T + fvec_in.electron_upar[iz,ir,is]^2) * - electron_moments.external_source_amplitude[iz,ir] + electron_moments.external_source_amplitude[iz,ir,index] end elseif electron_source_settings.source_type == "energy" @loop_r_z ir iz begin - electron_moments.external_source_momentum_amplitude[iz,ir] = + electron_moments.external_source_momentum_amplitude[iz,ir,index] = - electron_moments.density[iz,ir] * electron_moments.upar[iz,ir] * electron_source_settings.source_strength * electron_source_settings.r_amplitude[ir] * electron_source_settings.z_amplitude[iz] end @loop_r_z ir iz begin - electron_moments.external_source_pressure_amplitude[iz,ir] = + electron_moments.external_source_pressure_amplitude[iz,ir,index] = (0.5 * electron_source_settings.source_T + electron_moments.upar[iz,ir]^2 - electron_moments.ppar[iz,ir]) * electron_source_settings.source_strength * @@ -1187,30 +1305,45 @@ function external_electron_source_controller!(fvec_in, moments, electron_source_ end else @loop_r_z ir iz begin - electron_moments.external_source_amplitude[iz,ir] = ion_source_amplitude[iz,ir] + electron_moments.external_source_amplitude[iz,ir,index] = ion_source_amplitude[iz,ir,index] end @loop_r_z ir iz begin - electron_moments.external_source_momentum_amplitude[iz,ir] = + electron_moments.external_source_momentum_amplitude[iz,ir,index] = - electron_moments.density[iz,ir] * electron_moments.upar[iz,ir] * - electron_moments.external_source_amplitude[iz,ir] + electron_moments.external_source_amplitude[iz,ir,index] end @loop_r_z ir iz begin - electron_moments.external_source_pressure_amplitude[iz,ir] = + electron_moments.external_source_pressure_amplitude[iz,ir,index] = (0.5 * electron_source_settings.source_T + electron_moments.upar[iz,ir]^2 - electron_moments.ppar[iz,ir]) * - electron_moments.external_source_amplitude[iz,ir] + electron_moments.external_source_amplitude[iz,ir,index] end end # Density source is always the same as the ion one @loop_r_z ir iz begin - electron_moments.external_source_density_amplitude[iz,ir] = - moments.ion.external_source_density_amplitude[iz,ir] + electron_moments.external_source_density_amplitude[iz,ir,index] = + moments.ion.external_source_density_amplitude[iz,ir,index] end return nothing end +""" + total_external_neutral_source_controllers!(fvec_in, moments, neutral_sources, dt) + +Contribute all of the neutral source controllers to fvec_in, one by one. +""" +function total_external_neutral_source_controllers!(fvec_in, moments, neutral_sources, r, z, dt) + for index ∈ eachindex(neutral_sources) + if neutral_sources[index].active + external_neutral_source_controller!(fvec_in, moments, neutral_sources[index], + index, r, z, dt) + end + end + return nothing +end + """ external_neutral_source_controller!(fvec_in, moments, neutral_source_settings, r, z, dt) @@ -1218,8 +1351,8 @@ end Calculate the amplitude when using a PI controller for the density to set the external source amplitude. """ -function external_neutral_source_controller!(fvec_in, moments, neutral_source_settings, r, - z, dt) +function external_neutral_source_controller!(fvec_in, moments, neutral_source_settings, index, + r, z, dt) begin_r_z_region() is = 1 @@ -1228,15 +1361,15 @@ function external_neutral_source_controller!(fvec_in, moments, neutral_source_se if neutral_source_settings.source_type == "Maxwellian" if moments.evolve_ppar @loop_r_z ir iz begin - neutral_moments.external_source_pressure_amplitude[iz,ir] = + neutral_moments.external_source_pressure_amplitude[iz,ir,index] = (0.5 * neutral_source_settings.source_T + fvec_in.upar[iz,ir,is]^2) * - neutral_moments.external_source_amplitude[iz,ir] + neutral_moments.external_source_amplitude[iz,ir,index] end end elseif neutral_source_settings.source_type == "energy" if moments.evolve_upar @loop_r_z ir iz begin - neutral_moments.external_source_momentum_amplitude[iz,ir] = + neutral_moments.external_source_momentum_amplitude[iz,ir,index] = - neutral_moments.density[iz,ir] * neutral_moments.uz[iz,ir] * neutral_source_settings.source_strength * neutral_source_settings.r_amplitude[ir] * @@ -1245,7 +1378,7 @@ function external_neutral_source_controller!(fvec_in, moments, neutral_source_se end if moments.evolve_ppar @loop_r_z ir iz begin - neutral_moments.external_source_pressure_amplitude[iz,ir] = + neutral_moments.external_source_pressure_amplitude[iz,ir,index] = (0.5 * neutral_source_settings.source_T + neutral_moments.uz[iz,ir]^2 - neutral_moments.pz[iz,ir]) * neutral_source_settings.source_strength * @@ -1268,13 +1401,13 @@ function external_neutral_source_controller!(fvec_in, moments, neutral_source_se is] n_error = neutral_source_settings.PI_density_target - n_mid - neutral_moments.external_source_controller_integral[1,1] += + neutral_moments.external_source_controller_integral[1,1,index] += dt * neutral_source_settings.PI_density_controller_I * n_error # Only want a source, so never allow amplitude to be negative amplitude = max( neutral_source_settings.PI_density_controller_P * n_error + - neutral_moments.external_source_controller_integral[1,1], + neutral_moments.external_source_controller_integral[1,1,index], 0) else amplitude = nothing @@ -1288,20 +1421,20 @@ function external_neutral_source_controller!(fvec_in, moments, neutral_source_se amplitude = controller_amplitude[1] @loop_r_z ir iz begin - neutral_moments.external_source_amplitude[iz,ir] = - amplitude * neutral_source_settings.controller_source_profile[iz,ir] + neutral_moments.external_source_amplitude[iz,ir,index] = + amplitude * neutral_source_settings.controller_source_profile[iz,ir,index] end if moments.evolve_density @loop_r_z ir iz begin - neutral_moments.external_source_density_amplitude[iz,ir] = - amplitude * neutral_source_settings.controller_source_profile[iz,ir] + neutral_moments.external_source_density_amplitude[iz,ir,index] = + amplitude * neutral_source_settings.controller_source_profile[iz,ir,index] end end if moments.evolve_ppar @loop_r_z ir iz begin - neutral_moments.external_source_pressure_amplitude[iz,ir] = + neutral_moments.external_source_pressure_amplitude[iz,ir,index] = (0.5 * neutral_source_settings.source_T + fvec_in.upar[iz,ir,is]^2) * - amplitude * neutral_source_settings.controller_source_profile[iz,ir] + amplitude * neutral_source_settings.controller_source_profile[iz,ir,index] end end elseif neutral_source_settings.source_type == "density_profile_control" @@ -1315,19 +1448,19 @@ function external_neutral_source_controller!(fvec_in, moments, neutral_source_se amplitude = neutral_moments.external_source_amplitude @loop_r_z ir iz begin n_error = target[iz,ir] - density[iz,ir,is] - PI_integral[iz,ir] += dt * I * n_error - amplitude[iz,ir] = P * n_error + PI_integral[iz,ir] + PI_integral[iz,ir,index] += dt * I * n_error + amplitude[iz,ir,index] = P * n_error + PI_integral[iz,ir,index] end if moments.evolve_density @loop_r_z ir iz begin - neutral_moments.external_source_density_amplitude[iz,ir] = amplitude[iz,ir] + neutral_moments.external_source_density_amplitude[iz,ir,index] = amplitude[iz,ir,index] end end if moments.evolve_ppar @loop_r_z ir iz begin - neutral_moments.external_source_pressure_amplitude[iz,ir] = + neutral_moments.external_source_pressure_amplitude[iz,ir,index] = (0.5 * neutral_source_settings.source_T + fvec_in.upar[iz,ir,is]^2) * - amplitude[iz,ir] + amplitude[iz,ir,index] end end elseif neutral_source_settings.source_type == "recycling" @@ -1365,18 +1498,18 @@ function external_neutral_source_controller!(fvec_in, moments, neutral_source_se profile = neutral_source_settings.controller_source_profile prefactor = target_flux * neutral_source_settings.recycling_controller_fraction @loop_r_z ir iz begin - amplitude[iz,ir] = prefactor * profile[iz,ir] + amplitude[iz,ir,index] = prefactor * profile[iz,ir] end if moments.evolve_density @loop_r_z ir iz begin - neutral_moments.external_source_density_amplitude[iz,ir] = amplitude[iz,ir] + neutral_moments.external_source_density_amplitude[iz,ir,index] = amplitude[iz,ir,index] end end if moments.evolve_ppar @loop_r_z ir iz begin - neutral_moments.external_source_pressure_amplitude[iz,ir] = + neutral_moments.external_source_pressure_amplitude[iz,ir,index] = (0.5 * neutral_source_settings.source_T + fvec_in.upar[iz,ir,is]^2) * - amplitude[iz,ir] + amplitude[iz,ir,index] end end else diff --git a/moment_kinetics/src/initial_conditions.jl b/moment_kinetics/src/initial_conditions.jl index 8d7db7598..2549e07f4 100644 --- a/moment_kinetics/src/initial_conditions.jl +++ b/moment_kinetics/src/initial_conditions.jl @@ -67,8 +67,8 @@ function allocate_pdf_and_moments(composition, r, z, vperp, vpa, vzeta, vr, vz, evolve_moments.density, evolve_moments.parallel_flow, evolve_moments.parallel_pressure, external_source_settings.ion, num_diss_params) - electron = create_moments_electron(z.n, r.n, - composition.electron_physics, num_diss_params) + electron = create_moments_electron(z.n, r.n, composition.electron_physics, + num_diss_params, length(external_source_settings.electron)) neutral = create_moments_neutral(z.n, r.n, composition.n_neutral_species, evolve_moments.density, evolve_moments.parallel_flow, evolve_moments.parallel_pressure, external_source_settings.neutral, diff --git a/moment_kinetics/src/moment_kinetics_structs.jl b/moment_kinetics/src/moment_kinetics_structs.jl index acb1a378e..d16138fd1 100644 --- a/moment_kinetics/src/moment_kinetics_structs.jl +++ b/moment_kinetics/src/moment_kinetics_structs.jl @@ -132,18 +132,18 @@ struct moments_ion_substruct dvth_dz::Union{MPISharedArray{mk_float,3},Nothing} # this is the entropy production dS/dt = - int (ln f sum_s' C_ss' [f_s,f_s']) d^3 v dSdt::MPISharedArray{mk_float,3} - # Spatially varying amplitude of the external source term - external_source_amplitude::MPISharedArray{mk_float,2} + # Spatially varying amplitude of the external source term (third index is for different sources) + external_source_amplitude::MPISharedArray{mk_float,3} # Spatially varying amplitude of the density moment of the external source term - external_source_density_amplitude::MPISharedArray{mk_float,2} + external_source_density_amplitude::MPISharedArray{mk_float,3} # Spatially varying amplitude of the parallel momentum moment of the external source # term - external_source_momentum_amplitude::MPISharedArray{mk_float,2} + external_source_momentum_amplitude::MPISharedArray{mk_float,3} # Spatially varying amplitude of the parallel pressure moment of the external source # term - external_source_pressure_amplitude::MPISharedArray{mk_float,2} + external_source_pressure_amplitude::MPISharedArray{mk_float,3} # Integral term for the PID controller of the external source term - external_source_controller_integral::MPISharedArray{mk_float,2} + external_source_controller_integral::MPISharedArray{mk_float,3} # Store coefficient 'A' from applying moment constraints so we can write it out as a # diagnostic constraints_A_coefficient::Union{MPISharedArray{mk_float,3},Nothing} @@ -184,15 +184,15 @@ struct moments_electron_substruct # this is the parallel friction force between ions and electrons parallel_friction::MPISharedArray{mk_float,2} # Spatially varying amplitude of the external source term - external_source_amplitude::MPISharedArray{mk_float,2} + external_source_amplitude::MPISharedArray{mk_float,3} # Spatially varying amplitude of the density moment of the external source term - external_source_density_amplitude::MPISharedArray{mk_float,2} + external_source_density_amplitude::MPISharedArray{mk_float,3} # Spatially varying amplitude of the parallel momentum moment of the external source # term - external_source_momentum_amplitude::MPISharedArray{mk_float,2} + external_source_momentum_amplitude::MPISharedArray{mk_float,3} # Spatially varying amplitude of the parallel pressure moment of the external source # term - external_source_pressure_amplitude::MPISharedArray{mk_float,2} + external_source_pressure_amplitude::MPISharedArray{mk_float,3} # if evolve_ppar = true, then the velocity variable is (vpa - upa)/vth, which introduces # a factor of vth for each power of wpa in velocity space integrals. # v_norm_fac accounts for this: it is vth if using the above definition for the parallel velocity, @@ -297,17 +297,17 @@ struct moments_neutral_substruct # this is the z-derivative of the heat flux along z dqz_dz::Union{MPISharedArray{mk_float,3},Nothing} # Spatially varying amplitude of the external source term - external_source_amplitude::MPISharedArray{mk_float,2} + external_source_amplitude::MPISharedArray{mk_float,3} # Spatially varying amplitude of the density moment of the external source term - external_source_density_amplitude::MPISharedArray{mk_float,2} + external_source_density_amplitude::MPISharedArray{mk_float,3} # Spatially varying amplitude of the parallel momentum moment of the external source # term - external_source_momentum_amplitude::MPISharedArray{mk_float,2} + external_source_momentum_amplitude::MPISharedArray{mk_float,3} # Spatially varying amplitude of the parallel pressure moment of the external source # term - external_source_pressure_amplitude::MPISharedArray{mk_float,2} + external_source_pressure_amplitude::MPISharedArray{mk_float,3} # Integral term for the PID controller of the external source term - external_source_controller_integral::MPISharedArray{mk_float,2} + external_source_controller_integral::MPISharedArray{mk_float,3} # Store coefficient 'A' from applying moment constraints so we can write it out as a # diagnostic constraints_A_coefficient::Union{MPISharedArray{mk_float,3},Nothing} diff --git a/moment_kinetics/src/time_advance.jl b/moment_kinetics/src/time_advance.jl index 774028179..40dcca66d 100644 --- a/moment_kinetics/src/time_advance.jl +++ b/moment_kinetics/src/time_advance.jl @@ -1197,8 +1197,8 @@ function setup_advance_flags(moments, composition, t_params, collisions, if collisions.mxwl_diff.D_nn > 0.0 advance_maxwell_diffusion_nn = true end - advance_external_source = external_source_settings.ion.active && !t_params.implicit_ion_advance - advance_neutral_external_source = external_source_settings.neutral.active + advance_external_source = any(x -> x.active, external_source_settings.ion) && !t_params.implicit_ion_advance + advance_neutral_external_source = any(x -> x.active, external_source_settings.neutral) advance_ion_numerical_dissipation = !(t_params.implicit_ion_advance || t_params.implicit_vpa_advection) advance_neutral_numerical_dissipation = true # if evolving the density, must advance the continuity equation, @@ -1369,7 +1369,7 @@ function setup_implicit_advance_flags(moments, composition, t_params, collisions end end advance_krook_collisions_ii = collisions.krook.nuii0 > 0.0 - advance_external_source = external_source_settings.ion.active + advance_external_source = any(x -> x.active, external_source_settings.ion) advance_ion_numerical_dissipation = true advance_sources = moments.evolve_density || moments.evolve_upar || moments.evolve_ppar explicit_weakform_fp_collisions = collisions.fkpl.nuii > 0.0 && vperp.n > 1 @@ -3222,11 +3222,11 @@ function euler_time_advance!(fvec_out, fvec_in, pdf, fields, moments, 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 - external_ion_source_controller!(fvec_in, moments, external_source_settings.ion, + total_external_ion_source_controllers!(fvec_in, moments, external_source_settings.ion, dt) end if advance.neutral_external_source - external_neutral_source_controller!(fvec_in, moments, + total_external_neutral_source_controllers!(fvec_in, moments, external_source_settings.neutral, r, z, dt) end @@ -3350,11 +3350,11 @@ function euler_time_advance!(fvec_out, fvec_in, pdf, fields, moments, end if advance.external_source - external_ion_source!(fvec_out.pdf, fvec_in, moments, external_source_settings.ion, + total_external_ion_sources!(fvec_out.pdf, fvec_in, moments, external_source_settings.ion, vperp, vpa, dt, scratch_dummy) end if advance.neutral_external_source - external_neutral_source!(fvec_out.pdf_neutral, fvec_in, moments, + total_external_neutral_sources!(fvec_out.pdf_neutral, fvec_in, moments, external_source_settings.neutral, vzeta, vr, vz, dt) end diff --git a/moment_kinetics/src/velocity_moments.jl b/moment_kinetics/src/velocity_moments.jl index 0b48035d7..b362b721b 100644 --- a/moment_kinetics/src/velocity_moments.jl +++ b/moment_kinetics/src/velocity_moments.jl @@ -138,39 +138,40 @@ function create_moments_ion(nz, nr, n_species, evolve_density, evolve_upar, entropy_production = allocate_shared_float(nz, nr, n_species) + n_sources = length(ion_source_settings) if any(x -> x.active, ion_source_settings) - external_source_amplitude = allocate_shared_float(nz, nr) + external_source_amplitude = allocate_shared_float(nz, nr, n_sources) if evolve_density - external_source_density_amplitude = allocate_shared_float(nz, nr) + external_source_density_amplitude = allocate_shared_float(nz, nr, n_sources) else - external_source_density_amplitude = allocate_shared_float(1, 1) + external_source_density_amplitude = allocate_shared_float(1, 1, n_sources) end if evolve_upar - external_source_momentum_amplitude = allocate_shared_float(nz, nr) + external_source_momentum_amplitude = allocate_shared_float(nz, nr, n_sources) else - external_source_momentum_amplitude = allocate_shared_float(1, 1) + external_source_momentum_amplitude = allocate_shared_float(1, 1, n_sources) end if evolve_ppar - external_source_pressure_amplitude = allocate_shared_float(nz, nr) + external_source_pressure_amplitude = allocate_shared_float(nz, nr, n_sources) else - external_source_pressure_amplitude = allocate_shared_float(1, 1) + external_source_pressure_amplitude = allocate_shared_float(1, 1, n_sources) end if ion_source_settings.PI_density_controller_I != 0.0 && ion_source_settings.source_type ∈ ("density_profile_control", "density_midpoint_control") if ion_source_settings.source_type == "density_profile_control" - external_source_controller_integral = allocate_shared_float(nz, nr) + external_source_controller_integral = allocate_shared_float(nz, nr, n_sources) else - external_source_controller_integral = allocate_shared_float(1, 1) + external_source_controller_integral = allocate_shared_float(1, 1, n_sources) end else - external_source_controller_integral = allocate_shared_float(1, 1) + external_source_controller_integral = allocate_shared_float(1, 1, n_sources) end else - external_source_amplitude = allocate_shared_float(1, 1) - external_source_density_amplitude = allocate_shared_float(1, 1) - external_source_momentum_amplitude = allocate_shared_float(1, 1) - external_source_pressure_amplitude = allocate_shared_float(1, 1) - external_source_controller_integral = allocate_shared_float(1, 1) + external_source_amplitude = allocate_shared_float(1, 1, n_sources) + external_source_density_amplitude = allocate_shared_float(1, 1, n_sources) + external_source_momentum_amplitude = allocate_shared_float(1, 1, n_sources) + external_source_pressure_amplitude = allocate_shared_float(1, 1, n_sources) + external_source_controller_integral = allocate_shared_float(1, 1, n_sources) end if evolve_density || evolve_upar || evolve_ppar @@ -199,7 +200,7 @@ end """ create a moment struct containing information about the electron moments """ -function create_moments_electron(nz, nr, electron_model, num_diss_params) +function create_moments_electron(nz, nr, electron_model, num_diss_params, n_sources) # allocate array used for the particle density density = allocate_shared_float(nz, nr) # initialise Bool variable that indicates if the density is updated for each species @@ -222,11 +223,11 @@ function create_moments_electron(nz, nr, electron_model, num_diss_params) parallel_heat_flux_updated = Ref(false) # allocate array used for the election-ion parallel friction force parallel_friction_force = allocate_shared_float(nz, nr) - # allocate arrays used for external sources - external_source_amplitude = allocate_shared_float(nz, nr) - external_source_density_amplitude = allocate_shared_float(nz, nr) - external_source_momentum_amplitude = allocate_shared_float(nz, nr) - external_source_pressure_amplitude = allocate_shared_float(nz, nr) + # allocate arrays used for external sources (third index is for the different sources) + external_source_amplitude = allocate_shared_float(nz, nr, n_sources) + external_source_density_amplitude = allocate_shared_float(nz, nr, n_sources) + external_source_momentum_amplitude = allocate_shared_float(nz, nr, n_sources) + external_source_pressure_amplitude = allocate_shared_float(nz, nr, n_sources) # allocate array used for the thermal speed thermal_speed = allocate_shared_float(nz, nr) # if evolving the electron pdf, it will be a function of the vth-normalised peculiar velocity @@ -363,39 +364,40 @@ function create_moments_neutral(nz, nr, n_species, evolve_density, evolve_upar, dvth_dz = nothing end + n_sources = length(neutral_source_settings) if any(x -> x.active, neutral_source_settings) - external_source_amplitude = allocate_shared_float(nz, nr) + external_source_amplitude = allocate_shared_float(nz, nr, n_sources) if evolve_density - external_source_density_amplitude = allocate_shared_float(nz, nr) + external_source_density_amplitude = allocate_shared_float(nz, nr, n_sources) else - external_source_density_amplitude = allocate_shared_float(1, 1) + external_source_density_amplitude = allocate_shared_float(1, 1, n_sources) end if evolve_upar - external_source_momentum_amplitude = allocate_shared_float(nz, nr) + external_source_momentum_amplitude = allocate_shared_float(nz, nr, n_sources) else - external_source_momentum_amplitude = allocate_shared_float(1, 1) + external_source_momentum_amplitude = allocate_shared_float(1, 1, n_sources) end if evolve_ppar - external_source_pressure_amplitude = allocate_shared_float(nz, nr) + external_source_pressure_amplitude = allocate_shared_float(nz, nr, n_sources) else - external_source_pressure_amplitude = allocate_shared_float(1, 1) + external_source_pressure_amplitude = allocate_shared_float(1, 1, n_sources) end if neutral_source_settings.PI_density_controller_I != 0.0 && neutral_source_settings.source_type ∈ ("density_profile_control", "density_midpoint_control") if neutral_source_settings.source_type == "density_profile_control" - external_source_controller_integral = allocate_shared_float(nz, nr) + external_source_controller_integral = allocate_shared_float(nz, nr, n_sources) else - external_source_controller_integral = allocate_shared_float(1, 1) + external_source_controller_integral = allocate_shared_float(1, 1, n_sources) end else - external_source_controller_integral = allocate_shared_float(1, 1) + external_source_controller_integral = allocate_shared_float(1, 1, n_sources) end else - external_source_amplitude = allocate_shared_float(1, 1) - external_source_density_amplitude = allocate_shared_float(1, 1) - external_source_momentum_amplitude = allocate_shared_float(1, 1) - external_source_pressure_amplitude = allocate_shared_float(1, 1) - external_source_controller_integral = allocate_shared_float(1, 1) + external_source_amplitude = allocate_shared_float(1, 1, n_sources) + external_source_density_amplitude = allocate_shared_float(1, 1, n_sources) + external_source_momentum_amplitude = allocate_shared_float(1, 1, n_sources) + external_source_pressure_amplitude = allocate_shared_float(1, 1, n_sources) + external_source_controller_integral = allocate_shared_float(1, 1, n_sources) end if evolve_density || evolve_upar || evolve_ppar From 2e5527ab3ffee1ecdbfd14456635edbe0784ce31 Mon Sep 17 00:00:00 2001 From: Lucas McConnell Date: Sun, 8 Sep 2024 10:16:49 +0100 Subject: [PATCH 08/87] Update file_io.jl to write out external_source_amplitudes for each moment and species as an r, z, n array instead of just r, z. --- moment_kinetics/src/file_io.jl | 37 ++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/moment_kinetics/src/file_io.jl b/moment_kinetics/src/file_io.jl index 2515be182..0951973a6 100644 --- a/moment_kinetics/src/file_io.jl +++ b/moment_kinetics/src/file_io.jl @@ -1332,14 +1332,15 @@ function define_dynamic_ion_moment_variables!(fid, n_ion_species, r::coordinate, units="") ion_source_settings = external_source_settings.ion - if ion_source_settings.active + if any(x -> x.active, ion_source_settings) + n = length(ion_source_settings) external_source_amplitude = create_dynamic_variable!( - dynamic, "external_source_amplitude", mk_float, z, r; + dynamic, "external_source_amplitude", mk_float, z, r, n; parallel_io=parallel_io, description="Amplitude of the external source for ions", units="n_ref/c_ref^3*c_ref/L_ref") if evolve_density external_source_density_amplitude = create_dynamic_variable!( - dynamic, "external_source_density_amplitude", mk_float, z, r; + dynamic, "external_source_density_amplitude", mk_float, z, r, n; parallel_io=parallel_io, description="Amplitude of the external density source for ions", units="n_ref*c_ref/L_ref") else @@ -1347,7 +1348,7 @@ function define_dynamic_ion_moment_variables!(fid, n_ion_species, r::coordinate, end if evolve_upar external_source_momentum_amplitude = create_dynamic_variable!( - dynamic, "external_source_momentum_amplitude", mk_float, z, r; + dynamic, "external_source_momentum_amplitude", mk_float, z, r, n; parallel_io=parallel_io, description="Amplitude of the external momentum source for ions", units="m_ref*n_ref*c_ref*c_ref/L_ref") else @@ -1355,7 +1356,7 @@ function define_dynamic_ion_moment_variables!(fid, n_ion_species, r::coordinate, end if evolve_ppar external_source_pressure_amplitude = create_dynamic_variable!( - dynamic, "external_source_pressure_amplitude", mk_float, z, r; + dynamic, "external_source_pressure_amplitude", mk_float, z, r, n; parallel_io=parallel_io, description="Amplitude of the external pressure source for ions", units="m_ref*n_ref*c_ref^2*c_ref/L_ref") else @@ -1365,7 +1366,7 @@ function define_dynamic_ion_moment_variables!(fid, n_ion_species, r::coordinate, ion_source_settings.source_type ∈ ("density_profile_control", "density_midpoint_control") if ion_source_settings.source_type == "density_profile_control" external_source_controller_integral = create_dynamic_variable!( - dynamic, "external_source_controller_integral", mk_float, z, r; + dynamic, "external_source_controller_integral", mk_float, z, r, n; parallel_io=parallel_io, description="Integral term for the PID controller of the external source for ions") else @@ -1544,21 +1545,22 @@ function define_dynamic_electron_moment_variables!(fid, r::coordinate, z::coordi units="c_ref") electron_source_settings = external_source_settings.electron - if electron_source_settings.active + if any(x -> x.active, electron_source_settings) + n = length(electron_source_settings) external_source_electron_amplitude = create_dynamic_variable!( - dynamic, "external_source_electron_amplitude", mk_float, z, r; + dynamic, "external_source_electron_amplitude", mk_float, z, r, n; parallel_io=parallel_io, description="Amplitude of the external source for electrons", units="n_ref/c_ref^3*c_ref/L_ref") external_source_electron_density_amplitude = create_dynamic_variable!( - dynamic, "external_source_electron_density_amplitude", mk_float, z, r; + dynamic, "external_source_electron_density_amplitude", mk_float, z, r, n; parallel_io=parallel_io, description="Amplitude of the external density source for electrons", units="n_ref*c_ref/L_ref") external_source_electron_momentum_amplitude = create_dynamic_variable!( - dynamic, "external_source_electron_momentum_amplitude", mk_float, z, r; + dynamic, "external_source_electron_momentum_amplitude", mk_float, z, r, n; parallel_io=parallel_io, description="Amplitude of the external momentum source for electrons", units="m_ref*n_ref*c_ref*c_ref/L_ref") external_source_electron_pressure_amplitude = create_dynamic_variable!( - dynamic, "external_source_electron_pressure_amplitude", mk_float, z, r; + dynamic, "external_source_electron_pressure_amplitude", mk_float, z, r, n; parallel_io=parallel_io, description="Amplitude of the external pressure source for electrons", units="m_ref*n_ref*c_ref^2*c_ref/L_ref") else @@ -1752,14 +1754,15 @@ function define_dynamic_neutral_moment_variables!(fid, n_neutral_species, r::coo units="c_ref") neutral_source_settings = external_source_settings.neutral - if n_neutral_species > 0 && neutral_source_settings.active + if n_neutral_species > 0 && any(x -> x.active, neutral_source_settings) + n = length(neutral_source_settings) external_source_neutral_amplitude = create_dynamic_variable!( - dynamic, "external_source_neutral_amplitude", mk_float, z, r; + dynamic, "external_source_neutral_amplitude", mk_float, z, r, n; parallel_io=parallel_io, description="Amplitude of the external source for neutrals", units="n_ref/c_ref^3*c_ref/L_ref") if evolve_density external_source_neutral_density_amplitude = create_dynamic_variable!( - dynamic, "external_source_neutral_density_amplitude", mk_float, z, r; + dynamic, "external_source_neutral_density_amplitude", mk_float, z, r, n; parallel_io=parallel_io, description="Amplitude of the external density source for neutrals", units="n_ref*c_ref/L_ref") else @@ -1767,7 +1770,7 @@ function define_dynamic_neutral_moment_variables!(fid, n_neutral_species, r::coo end if evolve_upar external_source_neutral_momentum_amplitude = create_dynamic_variable!( - dynamic, "external_source_neutral_momentum_amplitude", mk_float, z, r; + dynamic, "external_source_neutral_momentum_amplitude", mk_float, z, r, n; parallel_io=parallel_io, description="Amplitude of the external momentum source for neutrals", units="m_ref*n_ref*c_ref*c_ref/L_ref") else @@ -1775,7 +1778,7 @@ function define_dynamic_neutral_moment_variables!(fid, n_neutral_species, r::coo end if evolve_ppar external_source_neutral_pressure_amplitude = create_dynamic_variable!( - dynamic, "external_source_neutral_pressure_amplitude", mk_float, z, r; + dynamic, "external_source_neutral_pressure_amplitude", mk_float, z, r, n; parallel_io=parallel_io, description="Amplitude of the external pressure source for neutrals", units="m_ref*n_ref*c_ref^2*c_ref/L_ref") else @@ -1785,7 +1788,7 @@ function define_dynamic_neutral_moment_variables!(fid, n_neutral_species, r::coo neutral_source_settings.source_type ∈ ("density_profile_control", "density_midpoint_control") if neutral_source_settings.source_type == "density_profile_control" external_source_neutral_controller_integral = create_dynamic_variable!( - dynamic, "external_source_neutral_controller_integral", mk_float, z, r; + dynamic, "external_source_neutral_controller_integral", mk_float, z, r, n; parallel_io=parallel_io, description="Integral term for the PID controller of the external source for neutrals") else From 0cf1c36af6158d73df48d278db7eb5d52dec1c71 Mon Sep 17 00:00:00 2001 From: Lucas McConnell Date: Sun, 8 Sep 2024 10:37:42 +0100 Subject: [PATCH 09/87] Update load_data.jl for multiple sources --- moment_kinetics/src/load_data.jl | 72 +++++++++++++++++--------------- 1 file changed, 39 insertions(+), 33 deletions(-) diff --git a/moment_kinetics/src/load_data.jl b/moment_kinetics/src/load_data.jl index 936301dc1..c2e6a53e7 100644 --- a/moment_kinetics/src/load_data.jl +++ b/moment_kinetics/src/load_data.jl @@ -4336,28 +4336,30 @@ function get_variable(run_info, variable_name; normalize_advection_speed_shape=t dppar_dz = get_z_derivative(run_info, "parallel_pressure") dvth_dz = get_z_derivative(run_info, "thermal_speed") dqpar_dz = get_z_derivative(run_info, "parallel_heat_flux") - if run_info.external_source_settings.ion.active + if any(x -> x.active, run_info.external_source_settings.ion) + n_sources = length(run_info.external_source_settings.ion) external_source_amplitude = get_variable(run_info, "external_source_amplitude") if run_info.evolve_density external_source_density_amplitude = get_variable(run_info, "external_source_density_amplitude") else - external_source_density_amplitude = zeros(0,0,run_info.nt) + external_source_density_amplitude = zeros(0,0,n_sources,run_info.nt) end if run_info.evolve_upar external_source_momentum_amplitude = get_variable(run_info, "external_source_momentum_amplitude") else - external_source_momentum_amplitude = zeros(0,0,run_info.nt) + external_source_momentum_amplitude = zeros(0,0,n_sources,run_info.nt) end if run_info.evolve_ppar external_source_pressure_amplitude = get_variable(run_info, "external_source_pressure_amplitude") else - external_source_pressure_amplitude = zeros(0,0,run_info.nt) + external_source_pressure_amplitude = zeros(0,0,n_sources,run_info.nt) end else - external_source_amplitude = zeros(0,0,run_info.nt) - external_source_density_amplitude = zeros(0,0,run_info.nt) - external_source_momentum_amplitude = zeros(0,0,run_info.nt) - external_source_pressure_amplitude = zeros(0,0,run_info.nt) + n_sources = 0 + external_source_amplitude = zeros(0,0,n_sources,run_info.nt) + external_source_density_amplitude = zeros(0,0,n_sources,run_info.nt) + external_source_momentum_amplitude = zeros(0,0,n_sources,run_info.nt) + external_source_pressure_amplitude = zeros(0,0,n_sources,run_info.nt) end nz, nr, nspecies, nt = size(vth) @@ -4389,10 +4391,10 @@ function get_variable(run_info, variable_name; normalize_advection_speed_shape=t dvth_dz=dvth_dz[:,:,:,it], dqpar_dz=dqpar_dz[:,:,:,it], vth=vth[:,:,:,it], - external_source_amplitude=external_source_amplitude[:,:,it], - external_source_density_amplitude=external_source_density_amplitude[:,:,it], - external_source_momentum_amplitude=external_source_momentum_amplitude[:,:,it], - external_source_pressure_amplitude=external_source_pressure_amplitude[:,:,it]), + external_source_amplitude=external_source_amplitude[:,:,n_sources,it], + external_source_density_amplitude=external_source_density_amplitude[:,:,n_sources,it], + external_source_momentum_amplitude=external_source_momentum_amplitude[:,:,n_sources,it], + external_source_pressure_amplitude=external_source_pressure_amplitude[:,:,n_sources,it]), evolve_density=run_info.evolve_density, evolve_upar=run_info.evolve_upar, evolve_ppar=run_info.evolve_ppar) @@ -4475,16 +4477,18 @@ function get_variable(run_info, variable_name; normalize_advection_speed_shape=t dppar_dz = get_z_derivative(run_info, "electron_parallel_pressure") dvth_dz = get_z_derivative(run_info, "electron_thermal_speed") dqpar_dz = get_z_derivative(run_info, "electron_parallel_heat_flux") - if run_info.external_source_settings.electron.active + if any(x -> x.active, run_info.external_source_settings.electron) + n_sources = length(run_info.external_source_settings.electron) external_source_amplitude = get_variable(run_info, "external_source_electron_amplitude") external_source_density_amplitude = get_variable(run_info, "external_source_electron_density_amplitude") external_source_momentum_amplitude = get_variable(run_info, "external_source_electron_momentum_amplitude") external_source_pressure_amplitude = get_variable(run_info, "external_source_electron_pressure_amplitude") else - external_source_amplitude = zeros(0,0,run_info.nt) - external_source_density_amplitude = zeros(0,0,run_info.nt) - external_source_momentum_amplitude = zeros(0,0,run_info.nt) - external_source_pressure_amplitude = zeros(0,0,run_info.nt) + n_sources = 0 + external_source_amplitude = zeros(0,0,n_sources,run_info.nt) + external_source_density_amplitude = zeros(0,0,n_sources,run_info.nt) + external_source_momentum_amplitude = zeros(0,0,n_sources,run_info.nt) + external_source_pressure_amplitude = zeros(0,0,n_sources,run_info.nt) end nz, nr, nt = size(vth) @@ -4508,10 +4512,10 @@ function get_variable(run_info, variable_name; normalize_advection_speed_shape=t dppar_dz=dppar_dz[:,:,it], dqpar_dz=dqpar_dz[:,:,it], dvth_dz=dvth_dz[:,:,it], - external_source_amplitude=external_source_amplitude[:,:,it], - external_source_density_amplitude=external_source_density_amplitude[:,:,it], - external_source_momentum_amplitude=external_source_momentum_amplitude[:,:,it], - external_source_pressure_amplitude=external_source_pressure_amplitude[:,:,it]),) + external_source_amplitude=external_source_amplitude[:,:,n_sources,it], + external_source_density_amplitude=external_source_density_amplitude[:,:,n_sources,it], + external_source_momentum_amplitude=external_source_momentum_amplitude[:,:,n_sources,it], + external_source_pressure_amplitude=external_source_pressure_amplitude[:,:,n_sources,it]),) @views update_electron_speed_vpa!(advect, density[:,:,it], upar[:,:,it], ppar[:,:,it], moments, run_info.vpa.grid, run_info.external_source_settings.electron) @@ -4593,28 +4597,30 @@ function get_variable(run_info, variable_name; normalize_advection_speed_shape=t dpz_dz = get_z_derivative(run_info, "pz_neutral") dvth_dz = get_z_derivative(run_info, "thermal_speed_neutral") dqz_dz = get_z_derivative(run_info, "qz_neutral") - if run_info.external_source_settings.neutral.active + if any(x -> x.active, run_info.external_source_settings.neutral) + n_sources = length(run_info.external_source_settings.neutral) external_source_amplitude = get_variable(run_info, "external_source_neutral_amplitude") if run_info.evolve_density external_source_density_amplitude = get_variable(run_info, "external_source_neutral_density_amplitude") else - external_source_density_amplitude = zeros(0,0,run_info.nt) + external_source_density_amplitude = zeros(0,0,n_sources,run_info.nt) end if run_info.evolve_upar external_source_momentum_amplitude = get_variable(run_info, "external_source_neutral_momentum_amplitude") else - external_source_momentum_amplitude = zeros(0,0,run_info.nt) + external_source_momentum_amplitude = zeros(0,0,n_sources,run_info.nt) end if run_info.evolve_ppar external_source_pressure_amplitude = get_variable(run_info, "external_source_neutral_pressure_amplitude") else - external_source_pressure_amplitude = zeros(0,0,run_info.nt) + external_source_pressure_amplitude = zeros(0,0,n_sources,run_info.nt) end else - external_source_amplitude = zeros(0,0,run_info.nt) - external_source_density_amplitude = zeros(0,0,run_info.nt) - external_source_momentum_amplitude = zeros(0,0,run_info.nt) - external_source_pressure_amplitude = zeros(0,0,run_info.nt) + n_sources = 0 + external_source_amplitude = zeros(0,0,n_sources,run_info.nt) + external_source_density_amplitude = zeros(0,0,n_sources,run_info.nt) + external_source_momentum_amplitude = zeros(0,0,n_sources,run_info.nt) + external_source_pressure_amplitude = zeros(0,0,n_sources,run_info.nt) end nz, nr, nspecies, nt = size(vth) @@ -4644,10 +4650,10 @@ function get_variable(run_info, variable_name; normalize_advection_speed_shape=t dvth_dz=dvth_dz[:,:,:,it], dqz_dz=dqz_dz[:,:,:,it], vth=vth[:,:,:,it], - external_source_amplitude=external_source_amplitude[:,:,it], - external_source_density_amplitude=external_source_density_amplitude[:,:,it], - external_source_momentum_amplitude=external_source_momentum_amplitude[:,:,it], - external_source_pressure_amplitude=external_source_pressure_amplitude[:,:,it]), + external_source_amplitude=external_source_amplitude[:,:,n_sources,it], + external_source_density_amplitude=external_source_density_amplitude[:,:,n_sources,it], + external_source_momentum_amplitude=external_source_momentum_amplitude[:,:,n_sources,it], + external_source_pressure_amplitude=external_source_pressure_amplitude[:,:,n_sources,it]), evolve_density=run_info.evolve_density, evolve_upar=run_info.evolve_upar, evolve_ppar=run_info.evolve_ppar) From 0362f2155fc308c5aaaabe8a5581af386ba8158a Mon Sep 17 00:00:00 2001 From: Lucas McConnell Date: Sun, 8 Sep 2024 11:44:18 +0100 Subject: [PATCH 10/87] Update source functionality for all moment kinetic advances of density, flow and pressure for each species --- moment_kinetics/src/continuity.jl | 24 +++--- .../src/electron_fluid_equations.jl | 26 ++++--- .../src/electron_kinetic_equation.jl | 22 +++--- moment_kinetics/src/electron_vpa_advection.jl | 29 ++++---- moment_kinetics/src/energy_equation.jl | 20 +++-- moment_kinetics/src/force_balance.jl | 24 +++--- moment_kinetics/src/neutral_vz_advection.jl | 63 ++++++++-------- moment_kinetics/src/source_terms.jl | 74 ++++++++++--------- moment_kinetics/src/vpa_advection.jl | 66 +++++++++-------- 9 files changed, 193 insertions(+), 155 deletions(-) diff --git a/moment_kinetics/src/continuity.jl b/moment_kinetics/src/continuity.jl index 26e9e1314..6a7c328e8 100644 --- a/moment_kinetics/src/continuity.jl +++ b/moment_kinetics/src/continuity.jl @@ -30,11 +30,13 @@ function continuity_equation!(dens_out, fvec_in, moments, composition, dt, spect end end - if ion_source_settings.active - source_amplitude = moments.ion.external_source_density_amplitude - @loop_s_r_z is ir iz begin - dens_out[iz,ir,is] += - dt * source_amplitude[iz,ir] + for index ∈ eachindex(ion_source_settings) + if ion_source_settings[index].active + @views source_amplitude = moments.ion.external_source_density_amplitude[:, :, index] + @loop_s_r_z is ir iz begin + dens_out[iz,ir,is] += + dt * source_amplitude[iz,ir] + end end end @@ -71,11 +73,13 @@ function neutral_continuity_equation!(dens_out, fvec_in, moments, composition, d end end - if neutral_source_settings.active - source_amplitude = moments.neutral.external_source_density_amplitude - @loop_s_r_z is ir iz begin - dens_out[iz,ir,is] += - dt * source_amplitude[iz,ir] + for index ∈ eachindex(neutral_source_settings) + if neutral_source_settings[index].active + @views source_amplitude = moments.neutral.external_source_density_amplitude[:, :, index] + @loop_s_r_z is ir iz begin + dens_out[iz,ir,is] += + dt * source_amplitude[iz,ir] + end end end diff --git a/moment_kinetics/src/electron_fluid_equations.jl b/moment_kinetics/src/electron_fluid_equations.jl index 395a94f4c..1ddc44046 100644 --- a/moment_kinetics/src/electron_fluid_equations.jl +++ b/moment_kinetics/src/electron_fluid_equations.jl @@ -225,13 +225,15 @@ function electron_energy_equation!(ppar_out, ppar_in, electron_density, electron end end - if electron_source_settings.active - pressure_source_amplitude = moments.external_source_pressure_amplitude - density_source_amplitude = moments.external_source_density_amplitude - @loop_r_z ir iz begin - ppar_out[iz,ir] += dt * (2.0 * pressure_source_amplitude[iz,ir] - - T_in[iz,ir] * density_source_amplitude[iz,ir]) / - electron_density[iz,ir] + for index ∈ eachindex(electron_source_settings) + if electron_source_settings[index].active + @views pressure_source_amplitude = moments.external_source_pressure_amplitude[:, :, index] + @views density_source_amplitude = moments.external_source_density_amplitude[:, :, index] + @loop_r_z ir iz begin + ppar_out[iz,ir] += dt * (2.0 * pressure_source_amplitude[iz,ir] + - T_in[iz,ir] * density_source_amplitude[iz,ir]) / + electron_density[iz,ir] + end end end @@ -306,10 +308,12 @@ function electron_energy_equation!(ppar_out, ppar_in, electron_density, electron end end - if electron_source_settings.active - source_amplitude = moments.external_source_pressure_amplitude - @loop_r_z ir iz begin - ppar_out[iz,ir] += dt * source_amplitude[iz,ir] + for index ∈ eachindex(electron_source_settings) + if electron_source_settings[index].active + @views source_amplitude = moments.external_source_pressure_amplitude[:, :, index] + @loop_r_z ir iz begin + ppar_out[iz,ir] += dt * source_amplitude[iz,ir] + end end end end diff --git a/moment_kinetics/src/electron_kinetic_equation.jl b/moment_kinetics/src/electron_kinetic_equation.jl index e88476c29..ce89fdc81 100644 --- a/moment_kinetics/src/electron_kinetic_equation.jl +++ b/moment_kinetics/src/electron_kinetic_equation.jl @@ -2273,16 +2273,18 @@ function add_contribution_from_pdf_term!(pdf_out, pdf_in, ppar, dens, upar, mome end end - if electron_source_settings.active - source_density_amplitude = moments.electron.external_source_density_amplitude - source_momentum_amplitude = moments.electron.external_source_momentum_amplitude - source_pressure_amplitude = moments.electron.external_source_pressure_amplitude - @loop_r_z ir iz begin - term = dt * (1.5 * source_density_amplitude[iz,ir] / dens[iz,ir] - - (0.5 * source_pressure_amplitude[iz,ir] + - source_momentum_amplitude[iz,ir]) / ppar[iz,ir]) - @loop_vperp_vpa ivperp ivpa begin - pdf_out[ivpa,ivperp,iz,ir] -= term * pdf_in[ivpa,ivperp,iz,ir] + for index ∈ eachindex(electron_source_settings) + if electron_source_settings[index].active + @views source_density_amplitude = moments.electron.external_source_density_amplitude[:, :, index] + @views source_momentum_amplitude = moments.electron.external_source_momentum_amplitude[:, :, index] + @views source_pressure_amplitude = moments.electron.external_source_pressure_amplitude[:, :, index] + @loop_r_z ir iz begin + term = dt * (1.5 * source_density_amplitude[iz,ir] / dens[iz,ir] - + (0.5 * source_pressure_amplitude[iz,ir] + + source_momentum_amplitude[iz,ir]) / ppar[iz,ir]) + @loop_vperp_vpa ivperp ivpa begin + pdf_out[ivpa,ivperp,iz,ir] -= term * pdf_in[ivpa,ivperp,iz,ir] + end end end end diff --git a/moment_kinetics/src/electron_vpa_advection.jl b/moment_kinetics/src/electron_vpa_advection.jl index 2d7968286..5f8abe6b5 100644 --- a/moment_kinetics/src/electron_vpa_advection.jl +++ b/moment_kinetics/src/electron_vpa_advection.jl @@ -66,19 +66,22 @@ function update_electron_speed_vpa!(advect, density, upar, ppar, moments, vpa, advect.speed[ivpa,ivperp,iz,ir] = ((vth[iz,ir] * dppar_dz[iz,ir] + vpa[ivpa] * dqpar_dz[iz,ir]) / (2 * ppar[iz,ir]) - vpa[ivpa]^2 * dvth_dz[iz,ir]) end - if electron_source_settings.active - source_density_amplitude = moments.electron.external_source_density_amplitude - source_momentum_amplitude = moments.electron.external_source_momentum_amplitude - source_pressure_amplitude = moments.electron.external_source_pressure_amplitude - @loop_r_z ir iz begin - term1 = source_density_amplitude[iz,ir] * upar[iz,ir]/(density[iz,ir]*vth[iz,ir]) - term2_over_vpa = - -0.5 * (source_pressure_amplitude[iz,ir] + - 2.0 * upar[iz,ir] * source_momentum_amplitude[iz,ir]) / - ppar[iz,ir] + - 0.5 * source_density_amplitude[iz,ir] / density[iz,ir] - @loop_vperp_vpa ivperp ivpa begin - advect.speed[ivpa,ivperp,iz,ir] += term1 + vpa[ivpa] * term2_over_vpa + + for index ∈ eachindex(electron_source_settings) + if electron_source_settings[index].active + @views source_density_amplitude = moments.electron.external_source_density_amplitude[:, :, index] + @views source_momentum_amplitude = moments.electron.external_source_momentum_amplitude[:, :, index] + @views source_pressure_amplitude = moments.electron.external_source_pressure_amplitude[:, :, index] + @loop_r_z ir iz begin + term1 = source_density_amplitude[iz,ir] * upar[iz,ir]/(density[iz,ir]*vth[iz,ir]) + term2_over_vpa = + -0.5 * (source_pressure_amplitude[iz,ir] + + 2.0 * upar[iz,ir] * source_momentum_amplitude[iz,ir]) / + ppar[iz,ir] + + 0.5 * source_density_amplitude[iz,ir] / density[iz,ir] + @loop_vperp_vpa ivperp ivpa begin + advect.speed[ivpa,ivperp,iz,ir] += term1 + vpa[ivpa] * term2_over_vpa + end end end end diff --git a/moment_kinetics/src/energy_equation.jl b/moment_kinetics/src/energy_equation.jl index 8890be3b6..7e708a61e 100644 --- a/moment_kinetics/src/energy_equation.jl +++ b/moment_kinetics/src/energy_equation.jl @@ -23,10 +23,12 @@ function energy_equation!(ppar, fvec, moments, collisions, dt, spectral, composi end - if ion_source_settings.active - source_amplitude = moments.ion.external_source_pressure_amplitude - @loop_s_r_z is ir iz begin - ppar[iz,ir,is] += dt * source_amplitude[iz,ir] + for index ∈ eachindex(ion_source_settings) + if ion_source_settings[index].active + @views source_amplitude = moments.ion.external_source_pressure_amplitude[:, :, index] + @loop_s_r_z is ir iz begin + ppar[iz,ir,is] += dt * source_amplitude[iz,ir] + end end end @@ -75,10 +77,12 @@ function neutral_energy_equation!(pz, fvec, moments, collisions, dt, spectral, - 3.0*fvec.pz_neutral[iz,ir,isn]*moments.neutral.duz_dz[iz,ir,isn]) end - if neutral_source_settings.active - source_amplitude = moments.neutral.external_source_pressure_amplitude - @loop_s_r_z isn ir iz begin - pz[iz,ir,isn] += dt * source_amplitude[iz,ir] + for index ∈ eachindex(neutral_source_settings) + if neutral_source_settings[index].active + @views source_amplitude = moments.neutral.external_source_pressure_amplitude[:, :, index] + @loop_s_r_z isn ir iz begin + pz[iz,ir,isn] += dt * source_amplitude[iz,ir] + end end end diff --git a/moment_kinetics/src/force_balance.jl b/moment_kinetics/src/force_balance.jl index 902c3901e..d96301711 100644 --- a/moment_kinetics/src/force_balance.jl +++ b/moment_kinetics/src/force_balance.jl @@ -29,11 +29,13 @@ function force_balance!(pflx, density_out, fvec, moments, fields, collisions, dt 0.5*geometry.bzed[iz,ir]*fields.Ez[iz,ir]*density[iz,ir,is]) end - if ion_source_settings.active && false - source_amplitude = moments.ion.external_source_momentum_amplitude - @loop_s_r_z is ir iz begin - pflx[iz,ir,is] += - dt * source_amplitude[iz,ir] + for index ∈ eachindex(ion_source_settings) + if ion_source_settings[index].active && false + @views source_amplitude = moments.ion.external_source_momentum_amplitude[:, :, index] + @loop_s_r_z is ir iz begin + pflx[iz,ir,is] += + dt * source_amplitude[iz,ir] + end end end @@ -83,11 +85,13 @@ function neutral_force_balance!(pflx, density_out, fvec, moments, fields, collis 2.0*density[iz,ir,isn]*uz[iz,ir,isn]*moments.neutral.duz_dz_upwind[iz,ir,isn]) end - if neutral_source_settings.active && false - source_amplitude = moments.neutral.external_source_momentum_amplitude - @loop_sn_r_z isn ir iz begin - pflx[iz,ir,isn] += - dt * source_amplitude[iz,ir] + for index ∈ eachindex(neutral_source_settings) + if neutral_source_settings[index].active && false + @views source_amplitude = moments.neutral.external_source_momentum_amplitude[:, :, index] + @loop_sn_r_z isn ir iz begin + pflx[iz,ir,isn] += + dt * source_amplitude[iz,ir] + end end end diff --git a/moment_kinetics/src/neutral_vz_advection.jl b/moment_kinetics/src/neutral_vz_advection.jl index 96b61cd39..a0f9dbdc5 100644 --- a/moment_kinetics/src/neutral_vz_advection.jl +++ b/moment_kinetics/src/neutral_vz_advection.jl @@ -126,25 +126,28 @@ function update_speed_n_u_p_evolution_neutral!(advect, fvec, moments, vz, z, r, end end end - if neutral_source_settings.active - source_density_amplitude = moments.neutral.external_source_density_amplitude - source_momentum_amplitude = moments.neutral.external_source_momentum_amplitude - source_pressure_amplitude = moments.neutral.external_source_pressure_amplitude - density = fvec.density_neutral - uz = fvec.uz_neutral - pz = fvec.pz_neutral - vth = moments.neutral.vth - vz_grid = vz.grid - @loop_s_r_z is ir iz begin - term1 = source_density_amplitude[iz,ir] * uz[iz,ir,is]/(density[iz,ir,is]*vth[iz,ir,is]) - term2_over_vpa = - -0.5 * (source_pressure_amplitude[iz,ir] + - 2.0 * uz[iz,ir,is] * source_momentum_amplitude[iz,ir]) / - pz[iz,ir,is] + - 0.5 * source_density_amplitude[iz,ir] / density[iz,ir,is] - @loop_vzeta_vr_vz ivzeta ivr ivz begin - advect[is].speed[ivz,ivr,ivzeta,iz,ir] += term1 + - vz_grid[ivz] * term2_over_vpa + + for index ∈ eachindex(neutral_source_settings) + if neutral_source_settings[index].active + @views source_density_amplitude = moments.neutral.external_source_density_amplitude[:, :, index] + @views source_momentum_amplitude = moments.neutral.external_source_momentum_amplitude[:, :, index] + @views source_pressure_amplitude = moments.neutral.external_source_pressure_amplitude[:, :, index] + density = fvec.density_neutral + uz = fvec.uz_neutral + pz = fvec.pz_neutral + vth = moments.neutral.vth + vz_grid = vz.grid + @loop_s_r_z is ir iz begin + term1 = source_density_amplitude[iz,ir] * uz[iz,ir,is]/(density[iz,ir,is]*vth[iz,ir,is]) + term2_over_vpa = + -0.5 * (source_pressure_amplitude[iz,ir] + + 2.0 * uz[iz,ir,is] * source_momentum_amplitude[iz,ir]) / + pz[iz,ir,is] + + 0.5 * source_density_amplitude[iz,ir] / density[iz,ir,is] + @loop_vzeta_vr_vz ivzeta ivr ivz begin + advect[is].speed[ivz,ivr,ivzeta,iz,ir] += term1 + + vz_grid[ivz] * term2_over_vpa + end end end end @@ -184,7 +187,7 @@ function update_speed_n_p_evolution_neutral!(advect, fields, fvec, moments, vz, end end end - if ion_source_settings.active + if any(x -> x.active, neutral_source_settings) error("External source not implemented for evolving n and ppar case") end end @@ -219,15 +222,17 @@ function update_speed_n_u_evolution_neutral!(advect, fvec, moments, vz, z, r, co end end end - if neutral_source_settings.active - source_density_amplitude = moments.neutral.external_source_density_amplitude - density = fvec.density_neutral - uz = fvec.uz_neutral - vth = moments.neutral.vth - @loop_sn_r_z isn ir iz begin - term = source_density_amplitude[iz,ir] * uz[iz,ir,isn] / density[iz,ir,isn] - @loop_vzeta_vr_vz ivzeta ivr ivz begin - advect[isn].speed[ivz,ivr,ivzeta,iz,ir] += term + for index ∈ eachindex(neutral_source_settings) + if neutral_source_settings[index].active + @views source_density_amplitude = moments.neutral.external_source_density_amplitude[:, :, index] + density = fvec.density_neutral + uz = fvec.uz_neutral + vth = moments.neutral.vth + @loop_sn_r_z isn ir iz begin + term = source_density_amplitude[iz,ir] * uz[iz,ir,isn] / density[iz,ir,isn] + @loop_vzeta_vr_vz ivzeta ivr ivz begin + advect[isn].speed[ivz,ivr,ivzeta,iz,ir] += term + end end end end diff --git a/moment_kinetics/src/source_terms.jl b/moment_kinetics/src/source_terms.jl index 9850d6f23..8a0a1dbe8 100644 --- a/moment_kinetics/src/source_terms.jl +++ b/moment_kinetics/src/source_terms.jl @@ -64,12 +64,14 @@ function source_terms_evolve_density!(pdf_out, pdf_in, dens, upar, ddens_dz, dup end end - if ion_source_settings.active - source_density_amplitude = moments.ion.external_source_density_amplitude - @loop_r_z ir iz begin - term = dt * source_density_amplitude[iz,ir] / dens[iz,ir] - @loop_vperp_vpa ivperp ivpa begin - pdf_out[ivpa,ivperp,iz,ir] -= term * pdf_in[ivpa,ivperp,iz,ir] + for index ∈ eachindex(ion_source_settings) + if ion_source_settings[index].active + @views source_density_amplitude = moments.ion.external_source_density_amplitude[:, :, index] + @loop_r_z ir iz begin + term = dt * source_density_amplitude[iz,ir] / dens[iz,ir] + @loop_vperp_vpa ivperp ivpa begin + pdf_out[ivpa,ivperp,iz,ir] -= term * pdf_in[ivpa,ivperp,iz,ir] + end end end end @@ -96,16 +98,18 @@ function source_terms_evolve_ppar_no_collisions!(pdf_out, pdf_in, dens, upar, pp end end - if ion_source_settings.active - source_density_amplitude = moments.ion.external_source_density_amplitude - source_momentum_amplitude = moments.ion.external_source_momentum_amplitude - source_pressure_amplitude = moments.ion.external_source_pressure_amplitude - @loop_r_z ir iz begin - term = dt * (1.5 * source_density_amplitude[iz,ir] / dens[iz,ir] - - (0.5 * source_pressure_amplitude[iz,ir] + - source_momentum_amplitude[iz,ir]) / ppar[iz,ir]) - @loop_vperp_vpa ivperp ivpa begin - pdf_out[ivpa,ivperp,iz,ir] -= term * pdf_in[ivpa,ivperp,iz,ir] + for index ∈ eachindex(ion_source_settings) + if ion_source_settings[index].active + @views source_density_amplitude = moments.ion.external_source_density_amplitude[:, :, index] + @views source_momentum_amplitude = moments.ion.external_source_momentum_amplitude[:, :, index] + @views source_pressure_amplitude = moments.ion.external_source_pressure_amplitude[:, :, index] + @loop_r_z ir iz begin + term = dt * (1.5 * source_density_amplitude[iz,ir] / dens[iz,ir] - + (0.5 * source_pressure_amplitude[iz,ir] + + source_momentum_amplitude[iz,ir]) / ppar[iz,ir]) + @loop_vperp_vpa ivperp ivpa begin + pdf_out[ivpa,ivperp,iz,ir] -= term * pdf_in[ivpa,ivperp,iz,ir] + end end end end @@ -192,12 +196,14 @@ function source_terms_evolve_density_neutral!(pdf_out, pdf_in, dens, upar, ddens end end - if neutral_source_settings.active - source_density_amplitude = moments.neutral.external_source_density_amplitude - @loop_r_z ir iz begin - term = dt * source_density_amplitude[iz,ir] / dens[iz,ir] - @loop_vzeta_vr_vz ivzeta ivr ivz begin - pdf_out[ivz,ivr,ivzeta,iz,ir] -= term * pdf_in[ivz,ivr,ivzeta,iz,ir] + for index ∈ eachindex(neutral_source_settings) + if neutral_source_settings[index].active + @views source_density_amplitude = moments.neutral.external_source_density_amplitude[:, :, index] + @loop_r_z ir iz begin + term = dt * source_density_amplitude[iz,ir] / dens[iz,ir] + @loop_vzeta_vr_vz ivzeta ivr ivz begin + pdf_out[ivz,ivr,ivzeta,iz,ir] -= term * pdf_in[ivz,ivr,ivzeta,iz,ir] + end end end end @@ -223,20 +229,22 @@ function source_terms_evolve_ppar_no_collisions_neutral!(pdf_out, pdf_in, dens, end end - if neutral_source_settings.active - source_density_amplitude = moments.neutral.external_source_density_amplitude - source_momentum_amplitude = moments.neutral.external_source_momentum_amplitude - source_pressure_amplitude = moments.neutral.external_source_pressure_amplitude - @loop_r_z ir iz begin - term = dt * (1.5 * source_density_amplitude[iz,ir] / dens[iz,ir] - - (0.5 * source_pressure_amplitude[iz,ir] + - source_momentum_amplitude[iz,ir]) / ppar[iz,ir]) - @loop_vzeta_vr_vz ivzeta ivr ivz begin - pdf_out[ivz,ivr,ivzeta,iz,ir] -= term * pdf_in[ivz,ivr,ivzeta,iz,ir] + for index ∈ eachindex(neutral_source_settings) + if neutral_source_settings[index].active + @views source_density_amplitude = moments.neutral.external_source_density_amplitude[:, :, index] + @views source_momentum_amplitude = moments.neutral.external_source_momentum_amplitude[:, :, index] + @views source_pressure_amplitude = moments.neutral.external_source_pressure_amplitude[:, :, index] + @loop_r_z ir iz begin + term = dt * (1.5 * source_density_amplitude[iz,ir] / dens[iz,ir] - + (0.5 * source_pressure_amplitude[iz,ir] + + source_momentum_amplitude[iz,ir]) / ppar[iz,ir]) + @loop_vzeta_vr_vz ivzeta ivr ivz begin + pdf_out[ivz,ivr,ivzeta,iz,ir] -= term * pdf_in[ivz,ivr,ivzeta,iz,ir] + end end end end - + return nothing end diff --git a/moment_kinetics/src/vpa_advection.jl b/moment_kinetics/src/vpa_advection.jl index bd70b3503..328395e9a 100644 --- a/moment_kinetics/src/vpa_advection.jl +++ b/moment_kinetics/src/vpa_advection.jl @@ -433,24 +433,26 @@ function update_speed_n_u_p_evolution!(advect, fvec, moments, vpa, z, r, composi end end end - if ion_source_settings.active - source_density_amplitude = moments.ion.external_source_density_amplitude - source_momentum_amplitude = moments.ion.external_source_momentum_amplitude - source_pressure_amplitude = moments.ion.external_source_pressure_amplitude - density = fvec.density - upar = fvec.upar - ppar = fvec.ppar - vth = moments.ion.vth - vpa_grid = vpa.grid - @loop_s_r_z is ir iz begin - term1 = source_density_amplitude[iz,ir] * upar[iz,ir,is]/(density[iz,ir,is]*vth[iz,ir,is]) - term2_over_vpa = - -0.5 * (source_pressure_amplitude[iz,ir] + - 2.0 * upar[iz,ir,is] * source_momentum_amplitude[iz,ir]) / - ppar[iz,ir,is] + - 0.5 * source_density_amplitude[iz,ir] / density[iz,ir,is] - @loop_vperp_vpa ivperp ivpa begin - advect[is].speed[ivpa,ivperp,iz,ir] += term1 + vpa_grid[ivpa] * term2_over_vpa + for index ∈ eachindex(ion_source_settings.ion) + if ion_source_settings[index].active + @views source_density_amplitude = moments.ion.external_source_density_amplitude[:, :, index] + @views source_momentum_amplitude = moments.ion.external_source_momentum_amplitude[:, :, index] + @views source_pressure_amplitude = moments.ion.external_source_pressure_amplitude[:, :, index] + density = fvec.density + upar = fvec.upar + ppar = fvec.ppar + vth = moments.ion.vth + vpa_grid = vpa.grid + @loop_s_r_z is ir iz begin + term1 = source_density_amplitude[iz,ir] * upar[iz,ir,is]/(density[iz,ir,is]*vth[iz,ir,is]) + term2_over_vpa = + -0.5 * (source_pressure_amplitude[iz,ir] + + 2.0 * upar[iz,ir,is] * source_momentum_amplitude[iz,ir]) / + ppar[iz,ir,is] + + 0.5 * source_density_amplitude[iz,ir] / density[iz,ir,is] + @loop_vperp_vpa ivperp ivpa begin + advect[is].speed[ivpa,ivperp,iz,ir] += term1 + vpa_grid[ivpa] * term2_over_vpa + end end end end @@ -494,7 +496,7 @@ function update_speed_n_p_evolution!(advect, fields, fvec, moments, vpa, z, r, end end end - if ion_source_settings.active + if any(x -> x.active, ion_source_settings) error("External source not implemented for evolving n and ppar case") end end @@ -538,18 +540,20 @@ function update_speed_n_u_evolution!(advect, fvec, moments, vpa, z, r, compositi end end end - if ion_source_settings.active - source_density_amplitude = moments.ion.external_source_density_amplitude - source_strength = ion_source_settings.source_strength - r_amplitude = ion_source_settings.r_amplitude - z_amplitude = ion_source_settings.z_amplitude - density = fvec.density - upar = fvec.upar - vth = moments.ion.vth - @loop_s_r_z is ir iz begin - term = source_density_amplitude[iz,ir] * upar[iz,ir,is] / density[iz,ir,is] - @loop_vperp_vpa ivperp ivpa begin - advect[is].speed[ivpa,ivperp,iz,ir] += term + for index ∈ eachindex(ion_source_settings.ion) + if ion_source_settings[index].active + @views source_density_amplitude = moments.ion.external_source_density_amplitude[:, :, index] + source_strength = ion_source_settings[index].source_strength + r_amplitude = ion_source_settings[index].r_amplitude + z_amplitude = ion_source_settings[index].z_amplitude + density = fvec.density + upar = fvec.upar + vth = moments.ion.vth + @loop_s_r_z is ir iz begin + term = source_density_amplitude[iz,ir] * upar[iz,ir,is] / density[iz,ir,is] + @loop_vperp_vpa ivperp ivpa begin + advect[is].speed[ivpa,ivperp,iz,ir] += term + end end end end From 41759d9a3f9ef75b7241837c9e3ceebd5f6ac478 Mon Sep 17 00:00:00 2001 From: Lucas McConnell Date: Sun, 8 Sep 2024 11:48:58 +0100 Subject: [PATCH 11/87] clean up external_sources.jl --- moment_kinetics/src/external_sources.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/moment_kinetics/src/external_sources.jl b/moment_kinetics/src/external_sources.jl index 2fc218aec..c3a7d8b7e 100644 --- a/moment_kinetics/src/external_sources.jl +++ b/moment_kinetics/src/external_sources.jl @@ -507,7 +507,6 @@ function initialize_external_source_amplitude!(moments, external_source_settings end # now do same for electron sources, which (if present) are mostly mirrors of ion sources - println(electron_source_settings) if electron_source_settings[index].active if electron_source_settings[index].source_type == "energy" @loop_r_z ir iz begin From e30e924bafc3e7cbab1d3910e7dbf10dbc5bee0a Mon Sep 17 00:00:00 2001 From: John Omotani Date: Fri, 6 Sep 2024 17:00:05 +0100 Subject: [PATCH 12/87] Get coordinate input from separate sections in input file Also tidy up the coordinate initialisation. --- moment_kinetics/src/coordinates.jl | 186 ++++-- moment_kinetics/src/file_io.jl | 3 +- moment_kinetics/src/finite_differences.jl | 26 +- moment_kinetics/src/input_structs.jl | 76 +-- moment_kinetics/src/load_data.jl | 68 +- moment_kinetics/src/moment_kinetics_input.jl | 588 ++---------------- .../src/plot_MMS_sequence.jl | 5 +- .../src/plots_post_processing.jl | 37 +- 8 files changed, 285 insertions(+), 704 deletions(-) diff --git a/moment_kinetics/src/coordinates.jl b/moment_kinetics/src/coordinates.jl index 158de0074..18cb0b04a 100644 --- a/moment_kinetics/src/coordinates.jl +++ b/moment_kinetics/src/coordinates.jl @@ -15,7 +15,7 @@ using ..communication using ..finite_differences: finite_difference_info using ..gauss_legendre: scaled_gauss_legendre_lobatto_grid, scaled_gauss_legendre_radau_grid, setup_gausslegendre_pseudospectral using ..quadrature: composite_simpson_weights -using ..input_structs: advection_input +using ..input_structs using ..moment_kinetics_structs: null_spatial_dimension_info, null_velocity_dimension_info using MPI @@ -58,8 +58,8 @@ struct coordinate{T <: AbstractVector{mk_float}} igrid_full::Array{mk_int,2} # discretization option for the grid discretization::String - # if the discretization is finite differences, fd_option provides the precise scheme - fd_option::String + # if the discretization is finite differences, finite_difference_option provides the precise scheme + finite_difference_option::String # if the discretization is chebyshev_pseudospectral, cheb_option chooses whether to use FFT or differentiation matrices for d / d coord cheb_option::String # bc is the boundary condition option for this coordinate @@ -129,40 +129,145 @@ struct coordinate{T <: AbstractVector{mk_float}} end """ + get_coordinate_input(input_dict, name) + +Read the input for coordinate `name` from `input_dict`, setting defaults, etc. +""" +function get_coordinate_input(input_dict, name; ignore_MPI=false) + if name == "z" + default_bc = "wall" + elseif name == "r" + default_bc = "periodic" + elseif name == "vperp" + default_bc = "zero" + else + default_bc = "zero" + end + coord_input_dict = set_defaults_and_check_section!( + input_dict, name; + # ngrid is number of grid points per element + ngrid=1, + # nelement is the number of elements in total + nelement=1, + # nelement_local is the number of elements on each process + nelement_local=-1, + # L is the box length in this coordinate + L=1.0, + # discretization option for the coordinate grid supported options are + # "chebyshev_pseudospectral", "gausslegendre_pseudospectral" and + # "finite_difference" + discretization="chebyshev_pseudospectral", + # option for implementation of chebyshev discretization: "FFT" or "matrix" + cheb_option="FFT", + # finite_difference_option determines the finite difference scheme to be used + # supported options are "third_order_upwind", "second_order_upwind" and + # "first_order_upwind" + finite_difference_option="third_order_upwind", + element_spacing_option="uniform", + # which boundary condition to use + bc=default_bc, + # determine the option used for the advection speed in z supported options are + # "constant" and "oscillating", in addition to the "default" option which uses + # d(coord)/dt from the moment-kinetic equations as the advection speed + advection_option="default", + # constant advection speed to use with advection_option = "constant" + advection_speed=0.0, + # for advection_option = "oscillating", advection speed is of form + # speed = advection_speed*(1 + advection_oscillation_amplitude*sinpi(advection_oscillation_frequency*t)) + advection_oscillation_amplitude=1.0, + advection_oscillation_frequency=1.0, + ) + if coord_input_dict["nelement_local"] == -1 || ignore_MPI + coord_input_dict["nelement_local"] = coord_input_dict["nelement"] + end + if name == "vperp" && coord_input_dict["bc"] == "default" + if coord_input_dict["ngrid"] == 1 && coord_input_dict["nelement"] == 1 + # 1V simulation, so boundary condition should be "none" + coord_input_dict["bc"] = "none" + else + # 2V simulation, so boundary condition should be "zero" + coord_input_dict["bc"] = "zero" + end + end + # Make a copy so we do not add "name" to the global input_dict + coord_input_dict = copy(coord_input_dict) + coord_input_dict["name"] = name + coord_input = Dict_to_NamedTuple(coord_input_dict) + + return coord_input +end + +""" + define_coordinate(input_dict, name; parallel_io::Bool=false, + run_directory=nothing, ignore_MPI=false, + collision_operator_dim::Bool=true) + create arrays associated with a given coordinate, setup the coordinate grid, and populate the coordinate structure containing all of this information """ -function define_coordinate(input, parallel_io::Bool=false; run_directory=nothing, - ignore_MPI=false, collision_operator_dim::Bool=true) +function define_coordinate end + +function define_coordinate(input_dict, name; kwargs...) + + coord_input = get_coordinate_input(input_dict, name) + + return define_coordinate(coord_input; kwargs...) +end + +function define_coordinate(coord_input::NamedTuple; parallel_io::Bool=false, + run_directory=nothing, ignore_MPI=false, + collision_operator_dim::Bool=true, irank=0, nrank=1, + comm=MPI.COMM_NULL) + + if coord_input.name ∉ ("r", "z") + if irank != 0 || nrank != 1 || comm != MPI.COMM_NULL + if comm == MPI.COMM_NULL + comm_message = "comm is MPI.COMM_NULL" + else + comm_message = "comm is not MPI.COMM_NULL" + end + error("Distributed-memory MPI is not supported for coordinate " + * "$(coord_input.name), but got irank=$irank, nrank=$nrank and " + * "$comm_message") + end + end + # total number of grid points is ngrid for the first element # plus ngrid-1 unique points for each additional element due # to the repetition of a point at the element boundary - n_global = (input.ngrid-1)*input.nelement_global + 1 + n_global = (coord_input.ngrid-1)*coord_input.nelement + 1 # local number of points on this process - n_local = (input.ngrid-1)*input.nelement_local + 1 + n_local = (coord_input.ngrid-1)*coord_input.nelement_local + 1 # obtain index mapping from full (local) grid to the # grid within each element (igrid, ielement) - igrid, ielement = full_to_elemental_grid_map(input.ngrid, - input.nelement_local, n_local) + igrid, ielement = full_to_elemental_grid_map(coord_input.ngrid, + coord_input.nelement_local, n_local) # obtain (local) index mapping from the grid within each element # to the full grid - imin, imax, igrid_full = elemental_to_full_grid_map(input.ngrid, input.nelement_local) + imin, imax, igrid_full = elemental_to_full_grid_map(coord_input.ngrid, + coord_input.nelement_local) # initialise the data used to construct the grid # boundaries for each element - element_boundaries = set_element_boundaries(input.nelement_global, input.L, input.element_spacing_option, input.name) + element_boundaries = set_element_boundaries(coord_input.nelement, + coord_input.L, + coord_input.element_spacing_option, + coord_input.name) # shift and scale factors for each local element - element_scale, element_shift = set_element_scale_and_shift(input.nelement_global, input.nelement_local, input.irank, element_boundaries) + element_scale, element_shift = + set_element_scale_and_shift(coord_input.nelement, coord_input.nelement_local, + irank, element_boundaries) # initialize the grid and the integration weights associated with the grid # also obtain the Chebyshev theta grid and spacing if chosen as discretization option - grid, wgts, uniform_grid, radau_first_element = init_grid(input.ngrid, - input.nelement_local, n_global, n_local, input.irank, input.L, element_scale, - element_shift, imin, imax, igrid, input.discretization, input.name) + grid, wgts, uniform_grid, radau_first_element = + init_grid(coord_input.ngrid, coord_input.nelement_local, n_global, n_local, + irank, coord_input.L, element_scale, element_shift, imin, imax, igrid, + coord_input.discretization, coord_input.name) # calculate the widths of the cells between neighboring grid points cell_width = grid_spacing(grid, n_local) # duniform_dgrid is the local derivative of the uniform grid with respect to # the coordinate grid - duniform_dgrid = allocate_float(input.ngrid, input.nelement_local) + duniform_dgrid = allocate_float(coord_input.ngrid, coord_input.nelement_local) # scratch is an array used for intermediate calculations requiring n entries scratch = allocate_float(n_local) if ignore_MPI @@ -182,9 +287,12 @@ function define_coordinate(input, parallel_io::Bool=false; run_directory=nothing _block_synchronize() end # scratch_2d is an array used for intermediate calculations requiring ngrid x nelement entries - scratch_2d = allocate_float(input.ngrid, input.nelement_local) + scratch_2d = allocate_float(coord_input.ngrid, coord_input.nelement_local) # struct containing the advection speed options/inputs for this coordinate - advection = input.advection + advection = advection_input(coord_input.advection_option, + coord_input.advection_speed, + coord_input.advection_oscillation_frequency, + coord_input.advection_oscillation_amplitude) # buffers for cyclic communication of boundary points # each chain of elements has only two external (off-rank) # endpoints, so only two pieces of information must be shared @@ -195,23 +303,24 @@ function define_coordinate(input, parallel_io::Bool=false; run_directory=nothing # No parallel io, just write everything local_io_range = 1:n_local global_io_range = 1:n_local - elseif input.irank == input.nrank-1 + elseif irank == nrank-1 # Include endpoint on final block local_io_range = 1:n_local - global_io_range = input.irank*(n_local-1)+1:n_global + global_io_range = irank*(n_local-1)+1:n_global else # Skip final point, because it is shared with the next block # Choose to skip final point in each block so all blocks (except the final one) # write a 'chunk' of the same size to the output file. This makes it simple to # align HDF5 'chunks' with the data being written local_io_range = 1 : n_local-1 - global_io_range = input.irank*(n_local-1)+1 : (input.irank+1)*(n_local-1) + global_io_range = irank*(n_local-1)+1 : (irank+1)*(n_local-1) end # Precompute some values for Lagrange polynomial evaluation - other_nodes = allocate_float(input.ngrid-1, input.ngrid, input.nelement_local) - one_over_denominator = allocate_float(input.ngrid, input.nelement_local) - for ielement ∈ 1:input.nelement_local + other_nodes = allocate_float(coord_input.ngrid-1, coord_input.ngrid, + coord_input.nelement_local) + one_over_denominator = allocate_float(coord_input.ngrid, coord_input.nelement_local) + for ielement ∈ 1:coord_input.nelement_local if ielement == 1 this_imin = imin[ielement] else @@ -219,11 +328,11 @@ function define_coordinate(input, parallel_io::Bool=false; run_directory=nothing end this_imax = imax[ielement] this_grid = grid[this_imin:this_imax] - for j ∈ 1:input.ngrid + for j ∈ 1:coord_input.ngrid @views other_nodes[1:j-1,j,ielement] .= this_grid[1:j-1] @views other_nodes[j:end,j,ielement] .= this_grid[j+1:end] - if input.ngrid == 1 + if coord_input.ngrid == 1 one_over_denominator[j,ielement] = 1.0 else one_over_denominator[j,ielement] = 1.0 / prod(this_grid[j] - n for n ∈ @view other_nodes[:,j,ielement]) @@ -231,16 +340,17 @@ function define_coordinate(input, parallel_io::Bool=false; run_directory=nothing end end - coord = coordinate(input.name, n_global, n_local, input.ngrid, - input.nelement_global, input.nelement_local, input.nrank, input.irank, input.L, grid, - cell_width, igrid, ielement, imin, imax, igrid_full, input.discretization, input.fd_option, input.cheb_option, - input.bc, wgts, uniform_grid, duniform_dgrid, scratch, copy(scratch), - copy(scratch), copy(scratch), copy(scratch), copy(scratch), copy(scratch), - copy(scratch), copy(scratch), scratch_shared, scratch_shared2, scratch_2d, - copy(scratch_2d), advection, send_buffer, receive_buffer, input.comm, - local_io_range, global_io_range, element_scale, element_shift, - input.element_spacing_option, element_boundaries, radau_first_element, - other_nodes, one_over_denominator) + coord = coordinate(coord_input.name, n_global, n_local, coord_input.ngrid, + coord_input.nelement, coord_input.nelement_local, nrank, irank, coord_input.L, + grid, cell_width, igrid, ielement, imin, imax, igrid_full, + coord_input.discretization, coord_input.finite_difference_option, + coord_input.cheb_option, coord_input.bc, wgts, uniform_grid, duniform_dgrid, + scratch, copy(scratch), copy(scratch), copy(scratch), copy(scratch), + copy(scratch), copy(scratch), copy(scratch), copy(scratch), scratch_shared, + scratch_shared2, scratch_2d, copy(scratch_2d), advection, send_buffer, + receive_buffer, comm, local_io_range, global_io_range, element_scale, + element_shift, coord_input.element_spacing_option, element_boundaries, + radau_first_element, other_nodes, one_over_denominator) if coord.n == 1 && occursin("v", coord.name) spectral = null_velocity_dimension_info() @@ -248,14 +358,14 @@ function define_coordinate(input, parallel_io::Bool=false; run_directory=nothing elseif coord.n == 1 spectral = null_spatial_dimension_info() coord.duniform_dgrid .= 1.0 - elseif input.discretization == "chebyshev_pseudospectral" + elseif coord_input.discretization == "chebyshev_pseudospectral" # create arrays needed for explicit Chebyshev pseudospectral treatment in this # coordinate and create the plans for the forward and backward fast Chebyshev # transforms spectral = setup_chebyshev_pseudospectral(coord, run_directory; ignore_MPI=ignore_MPI) # obtain the local derivatives of the uniform grid with respect to the used grid derivative!(coord.duniform_dgrid, coord.uniform_grid, coord, spectral) - elseif input.discretization == "gausslegendre_pseudospectral" + elseif coord_input.discretization == "gausslegendre_pseudospectral" # create arrays needed for explicit GaussLegendre pseudospectral treatment in this # coordinate and create the matrices for differentiation spectral = setup_gausslegendre_pseudospectral(coord, collision_operator_dim=collision_operator_dim) diff --git a/moment_kinetics/src/file_io.jl b/moment_kinetics/src/file_io.jl index 5f6adab0d..2b2b77ff8 100644 --- a/moment_kinetics/src/file_io.jl +++ b/moment_kinetics/src/file_io.jl @@ -945,7 +945,8 @@ function define_io_coordinate!(parent, coord, coord_name, description, parallel_ description="discretization used for $coord_name") # write the finite-difference option for the coordinate - write_single_value!(group, "fd_option", coord.fd_option; parallel_io=parallel_io, + write_single_value!(group, "finite_difference_option", + coord.finite_difference_option; parallel_io=parallel_io, description="type of finite difference for $coord_name, if used") write_single_value!(group, "cheb_option", coord.cheb_option; parallel_io=parallel_io, diff --git a/moment_kinetics/src/finite_differences.jl b/moment_kinetics/src/finite_differences.jl index ae18c7d7d..cc2d9583b 100644 --- a/moment_kinetics/src/finite_differences.jl +++ b/moment_kinetics/src/finite_differences.jl @@ -36,11 +36,11 @@ end elementwise_derivative!(coord, f, adv_fac, not_spectral::finite_difference_info) Calculate the derivative of f using finite differences, with particular scheme -specified by coord.fd_option; result stored in coord.scratch_2d. +specified by coord.finite_difference_option; result stored in coord.scratch_2d. """ function elementwise_derivative!(coord, f, adv_fac, not_spectral::finite_difference_info) return derivative_finite_difference!(coord.scratch_2d, f, coord.cell_width, adv_fac, - coord.bc, coord.fd_option, coord.igrid, coord.ielement) + coord.bc, coord.finite_difference_option, coord.igrid, coord.ielement) end """ @@ -79,18 +79,19 @@ end """ """ -function derivative_finite_difference!(df, f, del, adv_fac, bc, fd_option, igrid, ielement) - if fd_option == "second_order_upwind" +function derivative_finite_difference!(df, f, del, adv_fac, bc, finite_difference_option, + igrid, ielement) + if finite_difference_option == "second_order_upwind" upwind_second_order!(df, f, del, adv_fac, bc, igrid, ielement) - elseif fd_option == "third_order_upwind" + elseif finite_difference_option == "third_order_upwind" upwind_third_order!(df, f, del, adv_fac, bc, igrid, ielement) - elseif fd_option == "fourth_order_upwind" + elseif finite_difference_option == "fourth_order_upwind" upwind_fourth_order!(df, f, del, bc, igrid, ielement) - elseif fd_option == "second_order_centered" + elseif finite_difference_option == "second_order_centered" centered_second_order!(df, f, del, bc, igrid, ielement) - elseif fd_option == "fourth_order_centered" + elseif finite_difference_option == "fourth_order_centered" centered_fourth_order!(df, f, del, bc, igrid, ielement) - elseif fd_option == "first_order_upwind" + elseif finite_difference_option == "first_order_upwind" upwind_first_order!(df, f, del, adv_fac, bc, igrid, ielement) end # have not filled df array values for the first grid point in each element @@ -110,10 +111,11 @@ end """ """ -function derivative_finite_difference!(df, f, del, bc, fd_option, igrid, ielement) - if fd_option == "fourth_order_centered" +function derivative_finite_difference!(df, f, del, bc, finite_difference_option, igrid, + ielement) + if finite_difference_option == "fourth_order_centered" centered_fourth_order!(df, f, del, bc, igrid, ielement) - elseif fd_option == "second_order_centered" + elseif finite_difference_option == "second_order_centered" centered_second_order!(df, f, del, bc, igrid, ielement) end return nothing diff --git a/moment_kinetics/src/input_structs.jl b/moment_kinetics/src/input_structs.jl index 2c257d5f1..cc4c6edd9 100644 --- a/moment_kinetics/src/input_structs.jl +++ b/moment_kinetics/src/input_structs.jl @@ -5,8 +5,7 @@ module input_structs export advance_info export evolve_moments_options export time_info -export advection_input, advection_input_mutable -export grid_input, grid_input_mutable +export advection_input export initial_condition_input, initial_condition_input_mutable export spatial_initial_condition_input, velocity_initial_condition_input export ion_species_parameters, neutral_species_parameters, species_parameters_mutable @@ -142,19 +141,6 @@ mutable struct advance_info vz_diffusion::Bool #flag to control how vz bc is imposed when vz diffusion terms are present end -""" -""" -mutable struct advection_input_mutable - # advection speed option - option::String - # constant advection speed to use with the "constant" advection option - constant_speed::mk_float - # for option = "oscillating", advection speed is of form - # speed = constant_speed*(1 + oscillation_amplitude*sinpi(frequency*t)) - frequency::mk_float - oscillation_amplitude::mk_float -end - """ """ struct advection_input @@ -184,66 +170,6 @@ export braginskii_fluid export kinetic_electrons export kinetic_electrons_with_temperature_equation -""" -""" -mutable struct grid_input_mutable - # name of the variable associated with this coordinate - name::String - # number of grid points per element - ngrid::mk_int - # number of elements in global grid across ranks - nelement_global::mk_int - # number of elements in local grid on this rank - nelement_local::mk_int - # box length - L::mk_float - # discretization option - discretization::String - # finite difference option (only used if discretization is "finite_difference") - fd_option::String - # cheb option (only used if discretization is "chebyshev_pseudospectral") - cheb_option::String - # boundary option - bc::String - # mutable struct containing advection speed options - advection::advection_input_mutable - # string option determining boundary spacing - element_spacing_option::String -end - -""" -""" -struct grid_input - # name of the variable associated with this coordinate - name::String - # number of grid points per element - ngrid::mk_int - # number of elements globally - nelement_global::mk_int - # number of elements locally - nelement_local::mk_int - # number of ranks involved in the calculation - nrank::mk_int - # rank of this process - irank::mk_int - # box length - L::mk_float - # discretization option - discretization::String - # finite difference option (only used if discretization is "finite_difference") - fd_option::String - # cheb option (only used if discretization is "chebyshev_pseudospectral") - cheb_option::String - # boundary option - bc::String - # struct containing advection speed options - advection::advection_input - # MPI communicator - comm::MPI.Comm - # string option determining boundary spacing - element_spacing_option::String -end - """ """ mutable struct initial_condition_input_mutable diff --git a/moment_kinetics/src/load_data.jl b/moment_kinetics/src/load_data.jl index f77d6bfd3..401bebd77 100644 --- a/moment_kinetics/src/load_data.jl +++ b/moment_kinetics/src/load_data.jl @@ -246,7 +246,9 @@ function load_coordinate_data(fid, name; printout=false, irank=nothing, nrank=no return nothing, nothing, nothing end + input = OptionsDict() ngrid = load_variable(coord_group, "ngrid") + input["ngrid"] = ngrid n_local = load_variable(coord_group, "n_local") n_global = load_variable(coord_group, "n_global") grid = load_variable(coord_group, "grid") @@ -303,30 +305,35 @@ function load_coordinate_data(fid, name; printout=false, irank=nothing, nrank=no chunk_size = n_local - 1 end end + input["nelement"] = nelement_global + input["nelement_local"] = nelement_local # L = global box length - L = load_variable(coord_group, "L") - discretization = load_variable(coord_group, "discretization") - fd_option = load_variable(coord_group, "fd_option") + input["L"] = load_variable(coord_group, "L") + input["discretization"] = load_variable(coord_group, "discretization") + if "finite_difference_option" ∈ keys(coord_group) + input["finite_difference_option"] = load_variable(coord_group, "finite_difference_option") + else + # Older output file + input["finite_difference_option"] = load_variable(coord_group, "fd_option") + end if "cheb_option" ∈ keys(coord_group) - cheb_option = load_variable(coord_group, "cheb_option") + input["cheb_option"] = load_variable(coord_group, "cheb_option") else # Old output file - cheb_option = "FFT" + input["cheb_option"] = "FFT" end - bc = load_variable(coord_group, "bc") + input["bc"] = load_variable(coord_group, "bc") if "element_spacing_option" ∈ keys(coord_group) - element_spacing_option = load_variable(coord_group, "element_spacing_option") + input["element_spacing_option"] = load_variable(coord_group, "element_spacing_option") else - element_spacing_option = "uniform" + input["element_spacing_option"] = "uniform" end - # Define input to create coordinate struct - input = grid_input(name, ngrid, nelement_global, nelement_local, nrank, irank, L, - discretization, fd_option, cheb_option, bc, - advection_input("default", 0.0, 0.0, 0.0), MPI.COMM_NULL, - element_spacing_option) - coord, spectral = define_coordinate(input, parallel_io; run_directory=run_directory, - ignore_MPI=ignore_MPI) + coord, spectral = define_coordinate(OptionsDict(name => input), name; + parallel_io=parallel_io, + run_directory=run_directory, + ignore_MPI=ignore_MPI, irank=irank, nrank=nrank, + comm=MPI.COMM_NULL) return coord, spectral, chunk_size end @@ -3506,14 +3513,12 @@ function get_run_info_no_setup(run_dir::Union{AbstractString,Tuple{AbstractStrin else dummy_adv_input = advection_input("default", 1.0, 0.0, 0.0) dummy_comm = MPI.COMM_NULL - dummy_input = grid_input("dummy", 1, 1, 1, 1, 0, 1.0, - "chebyshev_pseudospectral", "", "", "periodic", - dummy_adv_input, dummy_comm, "uniform") - vzeta, vzeta_spectral = define_coordinate(dummy_input; ignore_MPI = true) + dummy_input = OptionsDict("dummy" => OptionsDict()) + vzeta, vzeta_spectral = define_coordinate(dummy_input, "dummy"; ignore_MPI = true) vzeta_chunk_size = 1 - vr, vr_spectral = define_coordinate(dummy_input; ignore_MPI = true) + vr, vr_spectral = define_coordinate(dummy_input, "dummy"; ignore_MPI = true) vr_chunk_size = 1 - vz, vz_spectral = define_coordinate(dummy_input; ignore_MPI = true) + vz, vz_spectral = define_coordinate(dummy_input, "dummy"; ignore_MPI = true) vz_chunk_size = 1 end @@ -5075,14 +5080,19 @@ end function construct_global_zr_coords(r_local, z_local; ignore_MPI=true) function make_global_input(coord_local) - return grid_input(coord_local.name, coord_local.ngrid, - coord_local.nelement_global, coord_local.nelement_global, 1, 0, coord_local.L, - coord_local.discretization, coord_local.fd_option, coord_local.cheb_option, coord_local.bc, - coord_local.advection, MPI.COMM_NULL, coord_local.element_spacing_option) - end - - r_global, r_global_spectral = define_coordinate(make_global_input(r_local); ignore_MPI=ignore_MPI) - z_global, z_global_spectral = define_coordinate(make_global_input(z_local); ignore_MPI=ignore_MPI) + return OptionsDict(coord_local.name => OptionsDict("ngrid" => coord_local.ngrid, + "nelement" => coord_local.nelement_global, + "nelement_local" => coord_local.nelement_global, + "L" => coord_local.L, + "discretization" => coord_local.discretization, + "cheb_option" => coord_local.cheb_option, + "bc" => coord_local.bc, + "element_spacing_option" => coord_local.element_spacing_option,), + ) + end + + r_global, r_global_spectral = define_coordinate(make_global_input(r_local), "r"; ignore_MPI=ignore_MPI) + z_global, z_global_spectral = define_coordinate(make_global_input(z_local), "z"; ignore_MPI=ignore_MPI) return r_global, r_global_spectral, z_global, z_global_spectral end diff --git a/moment_kinetics/src/moment_kinetics_input.jl b/moment_kinetics/src/moment_kinetics_input.jl index 99459663c..037a1c195 100644 --- a/moment_kinetics/src/moment_kinetics_input.jl +++ b/moment_kinetics/src/moment_kinetics_input.jl @@ -10,7 +10,7 @@ export read_input_file using ..type_definitions: mk_float, mk_int, OptionsDict using ..array_allocation: allocate_float using ..communication -using ..coordinates: define_coordinate +using ..coordinates: define_coordinate, get_coordinate_input using ..external_sources using ..file_io: io_has_parallel, input_option_error, open_ascii_output_file using ..krook_collisions: setup_krook_collisions_input @@ -49,15 +49,25 @@ false for other situations (e.g. when post-processing). `ignore_MPI` should be false when actually running a simulation, but defaults to true for other situations (e.g. when post-processing). """ -function mk_input(scan_input=Dict(); save_inputs_to_txt=false, ignore_MPI=true) +function mk_input(scan_input=OptionsDict(); 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", "rhostar", "geometry_option", "pitch", "DeltaB", - "n_ion_species","n_neutral_species","recycling_fraction","gyrokinetic_ions","T_e","T_wall", - "z_IC_option1","z_IC_option2","vpa_IC_option1","vpa_IC_option2", - "boltzmann_electron_response","boltzmann_electron_response_with_simple_sheath", - "electron_physics","nstep","dt") + removed_options_list = ("Bzed", "Bmag", "rhostar", "geometry_option", "pitch", + "DeltaB", "n_ion_species", "n_neutral_species", + "recycling_fraction", "gyrokinetic_ions", "T_e", "T_wall", + "z_IC_option1", "z_IC_option2", "vpa_IC_option1", + "vpa_IC_option2", "boltzmann_electron_response", + "boltzmann_electron_response_with_simple_sheath", + "electron_physics", "nstep", "dt", + ("$(c)_$(opt)" + for c ∈ ("r", "z", "vperp", "vpa", "vzeta", "vr", "vz"), + opt ∈ ("ngrid", "nelement", "nelement_local", "L", + "discretization", "cheb_option", + "finite_difference_option", + "element_spacing_option", "bc") + )..., + ) for opt in removed_options_list if opt ∈ keys(scan_input) error("Option '$opt' is no longer used. Please update your input file. You " @@ -71,8 +81,7 @@ function mk_input(scan_input=Dict(); save_inputs_to_txt=false, ignore_MPI=true) n_ion_species = composition.n_ion_species n_neutral_species = composition.n_neutral_species - z, r, vpa, vperp, gyrophase, vz, vr, vzeta, drive, evolve_moments = - load_defaults() + drive, evolve_moments = load_defaults() # this is the prefix for all output files associated with this run run_name = get(scan_input, "run_name", "wallBC") @@ -313,156 +322,6 @@ function mk_input(scan_input=Dict(); save_inputs_to_txt=false, ignore_MPI=true) end manufactured_solns_input = Dict_to_NamedTuple(manufactured_solns_section) - # overwrite some default parameters related to the r grid - # ngrid is number of grid points per element - r.ngrid = get(scan_input, "r_ngrid", 9) - # nelement_global is the number of elements in total - r.nelement_global = get(scan_input, "r_nelement", 8) - # nelement_local is the number of elements on each process - r.nelement_local = get(scan_input, "r_nelement_local", r.nelement_global) - # L is the box length in units of cs0/Omega_i - r.L = get(scan_input, "r_L", 1.0) - # determine the discretization option for the r grid - # supported options are "chebyshev_pseudospectral" and "finite_difference" - r.discretization = get(scan_input, "r_discretization", "finite_difference") - r.fd_option = get(scan_input, "r_finite_difference_option", "third_order_upwind") - # determine the boundary condition to impose in r - # supported options are "periodic" and "Dirichlet" - r.bc = get(scan_input, "r_bc", "periodic") - r.element_spacing_option = get(scan_input, "r_element_spacing_option", "uniform") - - # overwrite some default parameters related to the z grid - # ngrid is number of grid points per element - z.ngrid = get(scan_input, "z_ngrid", 9) - # nelement_global is the number of elements in total - z.nelement_global = get(scan_input, "z_nelement", 8) - # nelement_local is the number of elements on each process - z.nelement_local = get(scan_input, "z_nelement_local", z.nelement_global) - # L is the box length in units of cs0/Omega_i - z.L = get(scan_input, "z_L", 1.0) - # determine the discretization option for the z grid - # supported options are "chebyshev_pseudospectral" and "finite_difference" - z.discretization = get(scan_input, "z_discretization", "chebyshev_pseudospectral") - z.fd_option = get(scan_input, "z_finite_difference_option", "third_order_upwind") - # determine the boundary condition to impose in z - # supported options are "constant", "periodic" and "wall" - z.bc = get(scan_input, "z_bc", "wall") - z.element_spacing_option = get(scan_input, "z_element_spacing_option", "uniform") - - # overwrite some default parameters related to the vpa grid - # ngrid is the number of grid points per element - vpa.ngrid = get(scan_input, "vpa_ngrid", 17) - # nelement is the number of elements - vpa.nelement_global = get(scan_input, "vpa_nelement", 10) - # do not parallelise vpa with distributed-memory MPI - vpa.nelement_local = vpa.nelement_global - # L is the box length in units of vthermal_species - vpa.L = get(scan_input, "vpa_L", 8.0*sqrt(composition.ion[1].initial_temperature)) - # determine the boundary condition - # only supported option at present is "zero" and "periodic" - vpa.bc = get(scan_input, "vpa_bc", "periodic") - # determine the discretization option for the vpa grid - # supported options are "chebyshev_pseudospectral" and "finite_difference" - vpa.discretization = get(scan_input, "vpa_discretization", "chebyshev_pseudospectral") - vpa.fd_option = get(scan_input, "vpa_finite_difference_option", "third_order_upwind") - vpa.element_spacing_option = get(scan_input, "vpa_element_spacing_option", "uniform") - - # overwrite some default parameters related to the vperp grid - # ngrid is the number of grid points per element - vperp.ngrid = get(scan_input, "vperp_ngrid", 1) - # nelement is the number of elements - vperp.nelement_global = get(scan_input, "vperp_nelement", 1) - # do not parallelise vperp with distributed-memory MPI - vperp.nelement_local = vperp.nelement_global - # L is the box length in units of vthermal_species - vperp.L = get(scan_input, "vperp_L", 8.0*sqrt(composition.ion[1].initial_temperature)) - # Note vperp.bc is set below, after numerical dissipation is initialized, so that it - # can use the numerical dissipation settings to set its default value. - # - # determine the discretization option for the vperp grid - # supported options are "finite_difference_vperp" "chebyshev_pseudospectral" - vperp.discretization = get(scan_input, "vperp_discretization", "chebyshev_pseudospectral") - vperp.element_spacing_option = get(scan_input, "vperp_element_spacing_option", "uniform") - - # overwrite some default parameters related to the gyrophase grid - # ngrid is the number of grid points per element - gyrophase.ngrid = get(scan_input, "gyrophase_ngrid", 17) - # nelement is the number of elements - gyrophase.nelement_global = get(scan_input, "gyrophase_nelement", 10) - # do not parallelise gyrophase with distributed-memory MPI - gyrophase.nelement_local = gyrophase.nelement_global - - if n_neutral_species > 0 - # overwrite some default parameters related to the vz grid - # use vpa grid values as defaults - # ngrid is the number of grid points per element - vz.ngrid = get(scan_input, "vz_ngrid", vpa.ngrid) - # nelement is the number of elements - vz.nelement_global = get(scan_input, "vz_nelement", vpa.nelement_global) - # do not parallelise vz with distributed-memory MPI - vz.nelement_local = vz.nelement_global - # L is the box length in units of vthermal_species - vz.L = get(scan_input, "vz_L", vpa.L) - # determine the boundary condition - # only supported option at present is "zero" and "periodic" - vz.bc = get(scan_input, "vz_bc", "none") - # determine the discretization option for the vz grid - # supported options are "chebyshev_pseudospectral" and "finite_difference" - vz.discretization = get(scan_input, "vz_discretization", vpa.discretization) - vz.element_spacing_option = get(scan_input, "vz_element_spacing_option", "uniform") - - # overwrite some default parameters related to the vr grid - # ngrid is the number of grid points per element - vr.ngrid = get(scan_input, "vr_ngrid", 1) - # nelement is the number of elements - vr.nelement_global = get(scan_input, "vr_nelement", 1) - # do not parallelise vz with distributed-memory MPI - vr.nelement_local = vr.nelement_global - # L is the box length in units of vthermal_species - vr.L = get(scan_input, "vr_L", 8.0*sqrt(composition.ion[1].initial_temperature)) - # determine the boundary condition - # only supported option at present is "zero" and "periodic" - vr.bc = get(scan_input, "vr_bc", "none") - # determine the discretization option for the vr grid - # supported options are "chebyshev_pseudospectral" and "finite_difference" - vr.discretization = get(scan_input, "vr_discretization", "chebyshev_pseudospectral") - vr.element_spacing_option = get(scan_input, "vr_element_spacing_option", "uniform") - - # overwrite some default parameters related to the vzeta grid - # ngrid is the number of grid points per element - vzeta.ngrid = get(scan_input, "vzeta_ngrid", 1) - # nelement is the number of elements - vzeta.nelement_global = get(scan_input, "vzeta_nelement", 1) - # do not parallelise vz with distributed-memory MPI - vzeta.nelement_local = vzeta.nelement_global - # L is the box length in units of vthermal_species - vzeta.L = get(scan_input, "vzeta_L", 8.0*sqrt(composition.ion[1].initial_temperature)) - # determine the boundary condition - # only supported option at present is "zero" and "periodic" - vzeta.bc = get(scan_input, "vzeta_bc", "none") - # determine the discretization option for the vzeta grid - # supported options are "chebyshev_pseudospectral" and "finite_difference" - vzeta.discretization = get(scan_input, "vzeta_discretization", "chebyshev_pseudospectral") - vzeta.element_spacing_option = get(scan_input, "vzeta_element_spacing_option", "uniform") - end - - is_1V = (vperp.ngrid == vperp.nelement_global == 1 && vzeta.ngrid == - vzeta.nelement_global == 1 && vr.ngrid == vr.nelement_global == 1) - - ion_num_diss_param_dict = get(scan_input, "ion_numerical_dissipation", OptionsDict()) - electron_num_diss_param_dict = get(scan_input, "electron_numerical_dissipation", OptionsDict()) - neutral_num_diss_param_dict = get(scan_input, "neutral_numerical_dissipation", OptionsDict()) - num_diss_params = setup_numerical_dissipation(ion_num_diss_param_dict, - electron_num_diss_param_dict, - neutral_num_diss_param_dict, is_1V) - - # vperp.bc is set here (a bit out of place) so that we can use - # num_diss_params.ion.vperp_dissipation_coefficient to set the default. - vperp.bc = get(scan_input, "vperp_bc", - ( collisions.fkpl.nuii > 0.0 || - num_diss_params.ion.vperp_dissipation_coefficient > 0.0) ? - "zero" : "none") - ######################################################################### ########## end user inputs. do not modify following code! ############### ######################################################################### @@ -470,26 +329,19 @@ function mk_input(scan_input=Dict(); save_inputs_to_txt=false, ignore_MPI=true) # set up distributed-memory MPI information for z and r coords # need grid and MPI information to determine these values # MRH just put dummy values now + r_coord_input = get_coordinate_input(scan_input, "r"; ignore_MPI=ignore_MPI) + z_coord_input = get_coordinate_input(scan_input, "z"; ignore_MPI=ignore_MPI) if ignore_MPI irank_z = irank_r = 0 nrank_z = nrank_r = 1 comm_sub_z = comm_sub_r = MPI.COMM_NULL - r.nelement_local = r.nelement_global - z.nelement_local = z.nelement_global - vperp.nelement_local = vperp.nelement_global - vpa.nelement_local = vpa.nelement_global - vzeta.nelement_local = vzeta.nelement_global - vr.nelement_local = vr.nelement_global - vz.nelement_local = vz.nelement_global else - irank_z, nrank_z, comm_sub_z, irank_r, nrank_r, comm_sub_r = setup_distributed_memory_MPI(z.nelement_global,z.nelement_local,r.nelement_global,r.nelement_local) + irank_z, nrank_z, comm_sub_z, irank_r, nrank_r, comm_sub_r = + setup_distributed_memory_MPI(z_coord_input.nelement, + z_coord_input.nelement_local, + r_coord_input.nelement, + r_coord_input.nelement_local) end - #comm_sub_r = false - #irank_r = 0 - #nrank_r = 0 - #comm_sub_z = false - #irank_z = 0 - #nrank_z = 0 # Create output_dir if it does not exist. if !ignore_MPI @@ -499,43 +351,6 @@ function mk_input(scan_input=Dict(); save_inputs_to_txt=false, ignore_MPI=true) _block_synchronize() end - # replace mutable structures with immutable ones to optimize performance - # and avoid possible misunderstandings - z_advection_immutable = advection_input(z.advection.option, z.advection.constant_speed, - z.advection.frequency, z.advection.oscillation_amplitude) - z_immutable = grid_input("z", z.ngrid, z.nelement_global, z.nelement_local, nrank_z, irank_z, z.L, - z.discretization, z.fd_option, z.cheb_option, z.bc, z_advection_immutable, comm_sub_z, z.element_spacing_option) - r_advection_immutable = advection_input(r.advection.option, r.advection.constant_speed, - r.advection.frequency, r.advection.oscillation_amplitude) - r_immutable = grid_input("r", r.ngrid, r.nelement_global, r.nelement_local, nrank_r, irank_r, r.L, - r.discretization, r.fd_option, r.cheb_option, r.bc, r_advection_immutable, comm_sub_r, r.element_spacing_option) - # for dimensions below which do not currently use distributed-memory MPI - # assign dummy values to nrank, irank and comm of coord struct - vpa_advection_immutable = advection_input(vpa.advection.option, vpa.advection.constant_speed, - vpa.advection.frequency, vpa.advection.oscillation_amplitude) - vpa_immutable = grid_input("vpa", vpa.ngrid, vpa.nelement_global, vpa.nelement_local, 1, 0, vpa.L, - vpa.discretization, vpa.fd_option, vpa.cheb_option, vpa.bc, vpa_advection_immutable, MPI.COMM_NULL, vpa.element_spacing_option) - vperp_advection_immutable = advection_input(vperp.advection.option, vperp.advection.constant_speed, - vperp.advection.frequency, vperp.advection.oscillation_amplitude) - vperp_immutable = grid_input("vperp", vperp.ngrid, vperp.nelement_global, vperp.nelement_local, 1, 0, vperp.L, - vperp.discretization, vperp.fd_option, vperp.cheb_option, vperp.bc, vperp_advection_immutable, MPI.COMM_NULL, vperp.element_spacing_option) - gyrophase_advection_immutable = advection_input(gyrophase.advection.option, gyrophase.advection.constant_speed, - gyrophase.advection.frequency, gyrophase.advection.oscillation_amplitude) - gyrophase_immutable = grid_input("gyrophase", gyrophase.ngrid, gyrophase.nelement_global, gyrophase.nelement_local, 1, 0, gyrophase.L, - gyrophase.discretization, gyrophase.fd_option, gyrophase.cheb_option, gyrophase.bc, gyrophase_advection_immutable, MPI.COMM_NULL, gyrophase.element_spacing_option) - vz_advection_immutable = advection_input(vz.advection.option, vz.advection.constant_speed, - vz.advection.frequency, vz.advection.oscillation_amplitude) - vz_immutable = grid_input("vz", vz.ngrid, vz.nelement_global, vz.nelement_local, 1, 0, vz.L, - vz.discretization, vz.fd_option, vz.cheb_option, vz.bc, vz_advection_immutable, MPI.COMM_NULL, vz.element_spacing_option) - vr_advection_immutable = advection_input(vr.advection.option, vr.advection.constant_speed, - vr.advection.frequency, vr.advection.oscillation_amplitude) - vr_immutable = grid_input("vr", vr.ngrid, vr.nelement_global, vr.nelement_local, 1, 0, vr.L, - vr.discretization, vr.fd_option, vr.cheb_option, vr.bc, vr_advection_immutable, MPI.COMM_NULL, vr.element_spacing_option) - vzeta_advection_immutable = advection_input(vzeta.advection.option, vzeta.advection.constant_speed, - vzeta.advection.frequency, vzeta.advection.oscillation_amplitude) - vzeta_immutable = grid_input("vzeta", vzeta.ngrid, vzeta.nelement_global, vzeta.nelement_local, 1, 0, vzeta.L, - vzeta.discretization, vzeta.fd_option, vzeta.cheb_option, vzeta.bc, vzeta_advection_immutable, MPI.COMM_NULL, vzeta.element_spacing_option) - force_Er_zero = get(scan_input, "force_Er_zero_at_wall", false) drive_immutable = drive_input(drive.force_phi, drive.amplitude, drive.frequency, force_Er_zero) @@ -574,40 +389,57 @@ function mk_input(scan_input=Dict(); save_inputs_to_txt=false, ignore_MPI=true) else run_directory = output_dir end - z, z_spectral = define_coordinate(z_immutable, io_immutable.parallel_io; - run_directory=run_directory, ignore_MPI=ignore_MPI) + z, z_spectral = define_coordinate(z_coord_input; parallel_io=io_immutable.parallel_io, + run_directory=run_directory, ignore_MPI=ignore_MPI, + irank=irank_z, nrank=nrank_z, comm=comm_sub_z) # initialize r grid and write grid point locations to file - r, r_spectral = define_coordinate(r_immutable, io_immutable.parallel_io; - run_directory=run_directory, ignore_MPI=ignore_MPI) + r, r_spectral = define_coordinate(r_coord_input; parallel_io=io_immutable.parallel_io, + run_directory=run_directory, ignore_MPI=ignore_MPI, + irank=irank_r, nrank=nrank_r, comm=comm_sub_r) # initialize vpa grid and write grid point locations to file - vpa, vpa_spectral = define_coordinate(vpa_immutable, io_immutable.parallel_io; + vpa, vpa_spectral = define_coordinate(scan_input, "vpa"; + parallel_io=io_immutable.parallel_io, run_directory=run_directory, ignore_MPI=ignore_MPI) # initialize vperp grid and write grid point locations to file - vperp, vperp_spectral = define_coordinate(vperp_immutable, io_immutable.parallel_io; + vperp, vperp_spectral = define_coordinate(scan_input, "vperp"; + parallel_io=io_immutable.parallel_io, run_directory=run_directory, ignore_MPI=ignore_MPI) # initialize gyrophase grid and write grid point locations to file - gyrophase, gyrophase_spectral = define_coordinate(gyrophase_immutable, - io_immutable.parallel_io; + gyrophase, gyrophase_spectral = define_coordinate(scan_input, "gyrophase"; + parallel_io=io_immutable.parallel_io, run_directory=run_directory, ignore_MPI=ignore_MPI) # initialize vz grid and write grid point locations to file - vz, vz_spectral = define_coordinate(vz_immutable, io_immutable.parallel_io; + vz, vz_spectral = define_coordinate(scan_input, "vz"; + parallel_io=io_immutable.parallel_io, run_directory=run_directory, ignore_MPI=ignore_MPI) # initialize vr grid and write grid point locations to file - vr, vr_spectral = define_coordinate(vr_immutable, io_immutable.parallel_io; + vr, vr_spectral = define_coordinate(scan_input, "vr"; + parallel_io=io_immutable.parallel_io, run_directory=run_directory, ignore_MPI=ignore_MPI) # initialize vr grid and write grid point locations to file - vzeta, vzeta_spectral = define_coordinate(vzeta_immutable, io_immutable.parallel_io; + vzeta, vzeta_spectral = define_coordinate(scan_input, "vzeta"; + parallel_io=io_immutable.parallel_io, run_directory=run_directory, ignore_MPI=ignore_MPI) external_source_settings = setup_external_sources!(scan_input, r, z, composition.electron_physics) + is_1V = (vperp.ngrid == vperp.nelement_global == 1 && vzeta.ngrid == + vzeta.nelement_global == 1 && vr.ngrid == vr.nelement_global == 1) + + ion_num_diss_param_dict = get(scan_input, "ion_numerical_dissipation", OptionsDict()) + electron_num_diss_param_dict = get(scan_input, "electron_numerical_dissipation", OptionsDict()) + neutral_num_diss_param_dict = get(scan_input, "neutral_numerical_dissipation", OptionsDict()) + num_diss_params = setup_numerical_dissipation(ion_num_diss_param_dict, + electron_num_diss_param_dict, + neutral_num_diss_param_dict, is_1V) + if global_rank[] == 0 && save_inputs_to_txt # Make file to log some information about inputs into. io = open_ascii_output_file(string(output_dir,"/",run_name), "input") @@ -653,315 +485,7 @@ function load_defaults() conservation = true #advective_form = false evolve_moments = evolve_moments_options(evolve_density, evolve_parallel_flow, evolve_parallel_pressure, conservation)#advective_form) - # cheb option switch - cheb_option = "FFT" # "matrix" # #################### parameters related to the z grid ###################### - # ngrid_z is number of grid points per element - ngrid_z = 100 - # nelement_z is the number of elements on each process - nelement_local_z = 1 - # nelement_z is the number of elements in total - nelement_global_z = 1 - # L_z is the box length in z - L_z = 1.0 - # determine the boundary condition in z - # currently supported options are "constant" and "periodic" - boundary_option_z = "periodic" - #boundary_option_z = "constant" - # determine the discretization option for the z grid - # supported options are "chebyshev_pseudospectral" and "finite_difference" - #discretization_option_z = "chebyshev_pseudospectral" - discretization_option_z = "finite_difference" - # if discretization_option_z = "finite_difference", then - # finite_difference_option_z determines the finite difference scheme to be used - # supported options are "third_order_upwind", "second_order_upwind" and "first_order_upwind" - #finite_difference_option_z = "first_order_upwind" - #finite_difference_option_z = "second_order_upwind" - finite_difference_option_z = "third_order_upwind" - #cheb_option_z = "FFT" # "matrix" - cheb_option_z = cheb_option - # determine the option used for the advection speed in z - # supported options are "constant" and "oscillating", - # in addition to the "default" option which uses dz/dt = vpa as the advection speed - advection_option_z = "default" - # constant advection speed in z to use with advection_option_z = "constant" - advection_speed_z = 1.0 - # for advection_option_z = "oscillating", advection speed is of form - # speed = advection_speed_z*(1 + oscillation_amplitude_z*sinpi(frequency_z*t)) - frequency_z = 1.0 - oscillation_amplitude_z = 1.0 - # mutable struct containing advection speed options/inputs for z - advection_z = advection_input_mutable(advection_option_z, advection_speed_z, - frequency_z, oscillation_amplitude_z) - element_spacing_option_z = "uniform" - # create a mutable structure containing the input info related to the z grid - z = grid_input_mutable("z", ngrid_z, nelement_global_z, nelement_local_z, L_z, - discretization_option_z, finite_difference_option_z, cheb_option_z, boundary_option_z, - advection_z, element_spacing_option_z) - #################### parameters related to the r grid ###################### - # ngrid_r is number of grid points per element - ngrid_r = 1 - # nelement_r is the number of elements in total - nelement_global_r = 1 - # nelement_r is the number of elements on each process - nelement_local_r = 1 - # L_r is the box length in r - L_r = 1.0 - # determine the boundary condition in r - # currently supported options are "constant" and "periodic" - boundary_option_r = "periodic" - #boundary_option_r = "constant" - # determine the discretization option for the r grid - # supported options are "chebyshev_pseudospectral" and "finite_difference" - #discretization_option_r = "chebyshev_pseudospectral" - discretization_option_r = "finite_difference" - # if discretization_option_r = "finite_difference", then - # finite_difference_option_r determines the finite difference scheme to be used - # supported options are "third_order_upwind", "second_order_upwind" and "first_order_upwind" - #finite_difference_option_r = "first_order_upwind" - #finite_difference_option_r = "second_order_upwind" - finite_difference_option_r = "third_order_upwind" - #cheb_option_r = "FFT" #"matrix" - cheb_option_r = cheb_option - # determine the option used for the advection speed in r - # supported options are "constant" and "oscillating", - # in addition to the "default" option which uses dr/dt = vpa as the advection speed - advection_option_r = "default" # MRH -- NEED TO CHANGE THIS ASAP! - # constant advection speed in r to use with advection_option_r = "constant" - advection_speed_r = 1.0 - # for advection_option_r = "oscillating", advection speed is of form - # speed = advection_speed_r*(1 + oscillation_amplitude_r*sinpi(frequency_r*t)) - frequency_r = 1.0 - oscillation_amplitude_r = 1.0 - # mutable struct containing advection speed options/inputs for r - advection_r = advection_input_mutable(advection_option_r, advection_speed_r, - frequency_r, oscillation_amplitude_r) - element_spacing_option_r = "uniform" - # create a mutable structure containing the input info related to the r grid - r = grid_input_mutable("r", ngrid_r, nelement_global_r, nelement_local_r, L_r, - discretization_option_r, finite_difference_option_r, cheb_option_r, boundary_option_r, - advection_r, element_spacing_option_r) - ############################################################################ - ################### parameters related to the vpa grid ##################### - # ngrid_vpa is the number of grid points per element - ngrid_vpa = 300 - # nelement_vpa is the number of elements - nelement_vpa = 1 - # L_vpa is the box length in units of vthermal_species - L_vpa = 6.0 - # determine the boundary condition - # currently supported options are "zero" and "periodic" - #boundary_option_vpa = "zero" - boundary_option_vpa = "periodic" - # determine the discretization option for the vpa grid - # supported options are "chebyshev_pseudospectral" and "finite_difference" - #discretization_option_vpa = "chebyshev_pseudospectral" - discretization_option_vpa = "finite_difference" - # if discretization_option_vpa = "finite_difference", then - # finite_difference_option_vpa determines the finite difference scheme to be used - # supported options are "third_order_upwind", "second_order_upwind" and "first_order_upwind" - #finite_difference_option_vpa = "second_order_upwind" - finite_difference_option_vpa = "third_order_upwind" - #cheb_option_vpa = "FFT" # "matrix" - cheb_option_vpa = cheb_option - # determine the option used for the advection speed in vpa - # supported options are "constant" and "oscillating", - # in addition to the "default" option which uses dvpa/dt = q*Ez/m as the advection speed - advection_option_vpa = "default" - # constant advection speed in vpa to use with advection_option_vpa = "constant" - advection_speed_vpa = 1.0 - # for advection_option_vpa = "oscillating", advection speed is of form - # speed = advection_speed_vpa*(1 + oscillation_amplitude_vpa*sinpi(frequency_vpa*t)) - frequency_vpa = 1.0 - oscillation_amplitude_vpa = 1.0 - # mutable struct containing advection speed options/inputs for z - advection_vpa = advection_input_mutable(advection_option_vpa, advection_speed_vpa, - frequency_vpa, oscillation_amplitude_vpa) - element_spacing_option_vpa = "uniform" - # create a mutable structure containing the input info related to the vpa grid - vpa = grid_input_mutable("vpa", ngrid_vpa, nelement_vpa, nelement_vpa, L_vpa, - discretization_option_vpa, finite_difference_option_vpa, cheb_option_vpa, boundary_option_vpa, - advection_vpa, element_spacing_option_vpa) - ############################################################################ - ################### parameters related to the vperp grid ##################### - # ngrid_vperp is the number of grid points per element - ngrid_vperp = 1 - # nelement_vperp is the number of elements - nelement_vperp = 1 - # L_vperp is the box length in units of vthermal_species - L_vperp = 6.0 - # determine the boundary condition - # currently supported options are "zero" and "periodic" - # MRH probably need new bc option here - #boundary_option_vperp = "zero" - boundary_option_vperp = "periodic" - # determine the discretization option for the vperp grid - # supported options are "finite_difference_vperp" - discretization_option_vperp = "finite_difference_vperp" - # if discretization_option_vperp = "finite_difference_vperp", then - # finite_difference_option_vperp determines the finite difference scheme to be used - # supported options are "third_order_upwind", "second_order_upwind" and "first_order_upwind" - #finite_difference_option_vperp = "second_order_upwind" - finite_difference_option_vperp = "third_order_upwind" - #cheb_option_vperp = "FFT" # "matrix" - cheb_option_vperp = cheb_option - # determine the option used for the advection speed in vperp - # supported options are "constant" and "oscillating", - advection_option_vperp = "default" - # constant advection speed in vperp to use with advection_option_vperp = "constant" - advection_speed_vperp = 0.0 - # for advection_option_vperp = "oscillating", advection speed is of form - # speed = advection_speed_vperp*(1 + oscillation_amplitude_vperp*sinpi(frequency_vperp*t)) - frequency_vperp = 1.0 - oscillation_amplitude_vperp = 1.0 - # mutable struct containing advection speed options/inputs for z - advection_vperp = advection_input_mutable(advection_option_vperp, advection_speed_vperp, - frequency_vperp, oscillation_amplitude_vperp) - element_spacing_option_vperp = "uniform" - # create a mutable structure containing the input info related to the vperp grid - vperp = grid_input_mutable("vperp", ngrid_vperp, nelement_vperp, nelement_vperp, L_vperp, - discretization_option_vperp, finite_difference_option_vperp, cheb_option_vperp, boundary_option_vperp, - advection_vperp, element_spacing_option_vperp) - ############################################################################ - ################### parameters related to the gyrophase grid ##################### - # ngrid_gyrophase is the number of grid points per element - ngrid_gyrophase = 300 - # nelement_gyrophase is the number of elements - nelement_gyrophase = 1 - # L_gyrophase is the box length in units of vthermal_species - L_gyrophase = 2*pi - # determine the boundary condition - # currently supported option is "periodic" - boundary_option_gyrophase = "periodic" - discretization_option_gyrophase = "finite_difference" - finite_difference_option_gyrophase = "third_order_upwind" - #cheb_option_gyrophase = "FFT" #"matrix" - cheb_option_gyrophase = cheb_option - advection_option_gyrophase = "default" - advection_speed_gyrophase = 0.0 - frequency_gyrophase = 1.0 - oscillation_amplitude_gyrophase = 1.0 - advection_gyrophase = advection_input_mutable(advection_option_gyrophase, advection_speed_gyrophase, - frequency_gyrophase, oscillation_amplitude_gyrophase) - element_spacing_option_gyrophase = "uniform" - # create a mutable structure containing the input info related to the gyrophase grid - gyrophase = grid_input_mutable("gyrophase", ngrid_gyrophase, nelement_gyrophase, nelement_gyrophase, L_gyrophase, - discretization_option_gyrophase, finite_difference_option_gyrophase, cheb_option_gyrophase, boundary_option_gyrophase, - advection_gyrophase, element_spacing_option_gyrophase) - ############################################################################ - ################### parameters related to the vr grid ##################### - # ngrid_vr is the number of grid points per element - ngrid_vr = 1 - # nelement_vr is the number of elements - nelement_vr = 1 - # L_vr is the box length in units of vthermal_species - L_vr = 1.0 - # determine the boundary condition - # currently supported options are "zero" and "periodic" - boundary_option_vr = "periodic" - # determine the discretization option for the vr grid - # supported options are "finite_difference" "chebyshev_pseudospectral" - discretization_option_vr = "chebyshev_pseudospectral" - # if discretization_option_vr = "finite_difference", then - # finite_difference_option_vr determines the finite difference scheme to be used - # supported options are "third_order_upwind", "second_order_upwind" and "first_order_upwind" - #finite_difference_option_vr = "second_order_upwind" - finite_difference_option_vr = "third_order_upwind" - #cheb_option_vr = "FFT" # "matrix" - cheb_option_vr = cheb_option - # determine the option used for the advection speed in vr - # supported options are "constant" and "oscillating", - advection_option_vr = "default" - # constant advection speed in vr to use with advection_option_vr = "constant" - advection_speed_vr = 0.0 - # for advection_option_vr = "oscillating", advection speed is of form - # speed = advection_speed_vr*(1 + oscillation_amplitude_vr*sinpi(frequency_vr*t)) - frequency_vr = 1.0 - oscillation_amplitude_vr = 1.0 - # mutable struct containing advection speed options/inputs for z - advection_vr = advection_input_mutable(advection_option_vr, advection_speed_vr, - frequency_vr, oscillation_amplitude_vr) - element_spacing_option_vr = "uniform" - # create a mutable structure containing the input info related to the vr grid - vr = grid_input_mutable("vr", ngrid_vr, nelement_vr, nelement_vr, L_vr, - discretization_option_vr, finite_difference_option_vr, cheb_option_vr, boundary_option_vr, - advection_vr, element_spacing_option_vr) - ############################################################################ - ################### parameters related to the vz grid ##################### - # ngrid_vz is the number of grid points per element - ngrid_vz = 1 - # nelement_vz is the number of elements - nelement_vz = 1 - # L_vz is the box length in units of vthermal_species - L_vz = 1.0 - # determine the boundary condition - # currently supported options are "zero" and "periodic" - boundary_option_vz = "periodic" - # determine the discretization option for the vz grid - # supported options are "finite_difference" "chebyshev_pseudospectral" - discretization_option_vz = "chebyshev_pseudospectral" - # if discretization_option_vz = "finite_difference", then - # finite_difference_option_vz determines the finite difference scheme to be used - # supported options are "third_order_upwind", "second_order_upwind" and "first_order_upwind" - #finite_difference_option_vz = "second_order_upwind" - finite_difference_option_vz = "third_order_upwind" - #cheb_option_vz = "FFT" # "matrix" - cheb_option_vz = cheb_option - # determine the option used for the advection speed in vz - # supported options are "constant" and "oscillating", - advection_option_vz = "default" - # constant advection speed in vz to use with advection_option_vz = "constant" - advection_speed_vz = 0.0 - # for advection_option_vz = "oscillating", advection speed is of form - # speed = advection_speed_vz*(1 + oscillation_amplitude_vz*sinpi(frequency_vz*t)) - frequency_vz = 1.0 - oscillation_amplitude_vz = 1.0 - # mutable struct containing advection speed options/inputs for z - advection_vz = advection_input_mutable(advection_option_vz, advection_speed_vz, - frequency_vz, oscillation_amplitude_vz) - element_spacing_option_vz = "uniform" - # create a mutable structure containing the input info related to the vz grid - vz = grid_input_mutable("vz", ngrid_vz, nelement_vz, nelement_vz, L_vz, - discretization_option_vz, finite_difference_option_vz, cheb_option_vz, boundary_option_vz, - advection_vz, element_spacing_option_vz) - ############################################################################ - ################### parameters related to the vzeta grid ##################### - # ngrid_vzeta is the number of grid points per element - ngrid_vzeta = 1 - # nelement_vzeta is the number of elements - nelement_vzeta = 1 - # L_vzeta is the box length in units of vthermal_species - L_vzeta =1.0 - # determine the boundary condition - # currently supported options are "zero" and "periodic" - boundary_option_vzeta = "periodic" - # determine the discretization option for the vzeta grid - # supported options are "finite_difference" "chebyshev_pseudospectral" - discretization_option_vzeta = "chebyshev_pseudospectral" - # if discretization_option_vzeta = "finite_difference", then - # finite_difference_option_vzeta determines the finite difference scheme to be used - # supported options are "third_order_upwind", "second_order_upwind" and "first_order_upwind" - #finite_difference_option_vzeta = "second_order_upwind" - finite_difference_option_vzeta = "third_order_upwind" - #cheb_option_vzeta = "FFT" # "matrix" - cheb_option_vzeta = cheb_option - # determine the option used for the advection speed in vzeta - # supported options are "constant" and "oscillating", - advection_option_vzeta = "default" - # constant advection speed in vzeta to use with advection_option_vzeta = "constant" - advection_speed_vzeta = 0.0 - # for advection_option_vzeta = "oscillating", advection speed is of form - # speed = advection_speed_vzeta*(1 + oscillation_amplitude_vzeta*sinpi(frequency_vzeta*t)) - frequency_vzeta = 1.0 - oscillation_amplitude_vzeta = 1.0 - # mutable struct containing advection speed options/inputs for z - advection_vzeta = advection_input_mutable(advection_option_vzeta, advection_speed_vzeta, - frequency_vzeta, oscillation_amplitude_vzeta) - element_spacing_option_vzeta = "uniform" - # create a mutable structure containing the input info related to the vzeta grid - vzeta = grid_input_mutable("vzeta", ngrid_vzeta, nelement_vzeta, nelement_vzeta, L_vzeta, - discretization_option_vzeta, finite_difference_option_vzeta, cheb_option_vzeta, boundary_option_vzeta, - advection_vzeta, element_spacing_option_vzeta) # if drive_phi = true, include external electrostatic potential of form # phi(z,t=0)*drive_amplitude*sinpi(time*drive_frequency) @@ -970,7 +494,7 @@ function load_defaults() drive_frequency = 1.0 drive = drive_input_mutable(drive_phi, drive_amplitude, drive_frequency) - return z, r, vpa, vperp, gyrophase, vz, vr, vzeta, drive, evolve_moments + return drive, evolve_moments end """ @@ -1035,9 +559,9 @@ function check_coordinate_input(coord, coord_name, io) println(io,"using a Gauss-Legendre-Lobatto pseudospectral method in $coord_name.") elseif coord.discretization == "finite_difference" println(io,">$coord_name.discretization = 'finite_difference', ", - "and $coord_name.fd_option = ", coord.fd_option, + "and $coord_name.finite_difference_option = ", coord.finite_difference_option, " using finite differences on an equally spaced grid in $coord_name.") - fd_check_option(coord.fd_option, coord.ngrid) + fd_check_option(coord.finite_difference_option, coord.ngrid) else input_option_error("$coord_name.discretization", coord.discretization) end 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 17ba9c02b..1be774f68 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 @@ -33,6 +33,7 @@ using moment_kinetics.moment_kinetics_input: mk_input, read_input_file using moment_kinetics.input_structs: geometry_input using moment_kinetics.reference_parameters using moment_kinetics.species_input: get_species_input +using moment_kinetics.type_definitions: OptionsDict import Base: get @@ -233,8 +234,8 @@ function get_MMS_error_data(path_list,scan_type,scan_name) end - r_bc = get(scan_input, "r_bc", "periodic") - z_bc = get(scan_input, "z_bc", "periodic") + r_bc = get(get(scan_input, "r", OptionsDict()), "bc", "periodic") + z_bc = get(get(scan_input, "z", OptionsDict()), "bc", "periodic") # avoid passing Lr = 0 into manufactured_solns functions if r.n > 1 Lr_in = r.L 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 2c56208de..a186acf1f 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 @@ -38,7 +38,7 @@ using moment_kinetics.quadrature: composite_simpson_weights using moment_kinetics.array_allocation: allocate_float using moment_kinetics.coordinates: define_coordinate using moment_kinetics.file_io: open_ascii_output_file -using moment_kinetics.type_definitions: mk_float, mk_int +using moment_kinetics.type_definitions: mk_float, mk_int, OptionsDict using moment_kinetics.load_data: open_readonly_output_file, get_group, load_input, load_time_data, construct_global_zr_coords using moment_kinetics.load_data: get_nranks @@ -239,27 +239,34 @@ function allocate_global_zr_neutral_moments(nz_global,nr_global,n_neutral_specie return neutral_density, neutral_uz, neutral_pz, neutral_qz, neutral_thermal_speed end +function _get_nested(scan_input, section, option, default) + if section ∉ keys(scan_input) + return default + end + return get(scan_input[section], option, default) +end + function get_coords_nelement(scan_input) # use 1 as default because these values should be set in input .toml - z_nelement = get(scan_input, "z_nelement", 1) - r_nelement = get(scan_input, "r_nelement", 1) - vpa_nelement = get(scan_input, "vpa_nelement", 1) - vperp_nelement = get(scan_input, "vperp_nelement", 1) - vz_nelement = get(scan_input, "vz_nelement", 1) - vr_nelement = get(scan_input, "vr_nelement", 1) - vzeta_nelement = get(scan_input, "vzeta_nelement", 1) + z_nelement = _get_nested(scan_input, "z", "nelement", 1) + r_nelement = _get_nested(scan_input, "r", "nelement", 1) + vpa_nelement = _get_nested(scan_input, "vpa", "nelement", 1) + vperp_nelement = _get_nested(scan_input, "vperp", "nelement", 1) + vz_nelement = _get_nested(scan_input, "vz", "nelement", 1) + vr_nelement = _get_nested(scan_input, "vr", "nelement", 1) + vzeta_nelement = _get_nested(scan_input, "vzeta", "nelement", 1) return z_nelement, r_nelement, vpa_nelement, vperp_nelement, vz_nelement, vr_nelement, vzeta_nelement end function get_coords_ngrid(scan_input) # use 1 as default because these values should be set in input .toml - z_ngrid = get(scan_input, "z_ngrid", 1) - r_ngrid = get(scan_input, "r_ngrid", 1) - vpa_ngrid = get(scan_input, "vpa_ngrid", 1) - vperp_ngrid = get(scan_input, "vperp_ngrid", 1) - vz_ngrid = get(scan_input, "vz_ngrid", 1) - vr_ngrid = get(scan_input, "vr_ngrid", 1) - vzeta_ngrid = get(scan_input, "vzeta_ngrid", 1) + z_ngrid = _get_nested(scan_input, "z", "ngrid", 1) + r_ngrid = _get_nested(scan_input, "r", "ngrid", 1) + vpa_ngrid = _get_nested(scan_input, "vpa", "ngrid", 1) + vperp_ngrid = _get_nested(scan_input, "vperp", "ngrid", 1) + vz_ngrid = _get_nested(scan_input, "vz", "ngrid", 1) + vr_ngrid = _get_nested(scan_input, "vr", "ngrid", 1) + vzeta_ngrid = _get_nested(scan_input, "vzeta", "ngrid", 1) return z_ngrid, r_ngrid, vpa_ngrid, vperp_ngrid, vz_ngrid, vr_ngrid, vzeta_ngrid end From cca406c51b9d19867a17ee7e821a6a421b3b8bc7 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Sat, 7 Sep 2024 14:07:35 +0100 Subject: [PATCH 13/87] Add recursive_merge() function to merge nested Dicts --- moment_kinetics/src/utils.jl | 22 +++++++++++++++++++++- moment_kinetics/test/setup.jl | 3 ++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/moment_kinetics/src/utils.jl b/moment_kinetics/src/utils.jl index 2118c0407..33aebfc57 100644 --- a/moment_kinetics/src/utils.jl +++ b/moment_kinetics/src/utils.jl @@ -4,7 +4,7 @@ Utility functions module utils export get_unnormalized_parameters, print_unnormalized_parameters, to_seconds, to_minutes, - to_hours + to_hours, recursive_merge using ..communication using ..constants @@ -294,6 +294,26 @@ function enum_from_string(enum_type, name) return nothing end +""" + recursive_merge(a, b) + +Merge two AbstractDicts `a` and `b`. Any elements that are AbstractDicts are also merged +(rather than just replacing with the entry in `b`). +""" +function recursive_merge end +function recursive_merge(a::AbstractDict, b::AbstractDict) + return mergewith(recursive_merge, a, b) +end +function recursive_merge(a::AbstractDict, b) + error("Cannot merge a Dict with a non-Dict, got $a and $b") +end +function recursive_merge(a, b::AbstractDict) + error("Cannot merge a Dict with a non-Dict, got $a and $b") +end +function recursive_merge(a, b) + return b +end + # Utility functions for timestepping """ diff --git a/moment_kinetics/test/setup.jl b/moment_kinetics/test/setup.jl index 555824d00..8657bd170 100644 --- a/moment_kinetics/test/setup.jl +++ b/moment_kinetics/test/setup.jl @@ -13,10 +13,11 @@ using moment_kinetics module MKTestUtilities export use_verbose, force_optional_dependencies, @long, quietoutput, get_MPI_tempdir, - global_rank, global_size, maxabs_norm, @testset_skip + global_rank, global_size, maxabs_norm, @testset_skip, recursive_merge using moment_kinetics.communication: comm_world, global_rank, global_size using moment_kinetics.command_line_options: get_options +using moment_kinetics.utils: recursive_merge using MPI From 644a215236b092014a7f5ae83337e88915bec8d3 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Sat, 7 Sep 2024 21:37:52 +0100 Subject: [PATCH 14/87] Replace merge_dict_of_dicts() with recursive_merge() recursive_merge() is more flexible, as it can handle arbitrarily deep nesting of Dicts. Also move merge_dict_with_kwargs() to utils module, as it is only needed in the tests, not within the moment_kinetics module itself. --- moment_kinetics/debug_test/wall_bc_inputs.jl | 10 ++-- moment_kinetics/src/input_structs.jl | 52 ------------------- moment_kinetics/src/utils.jl | 19 ++++++- .../test/Krook_collisions_tests.jl | 3 +- .../test/braginskii_electrons_imex_tests.jl | 3 +- .../fokker_planck_time_evolution_tests.jl | 3 +- moment_kinetics/test/harrisonthompson.jl | 2 +- .../test/nonlinear_sound_wave_tests.jl | 3 +- .../test/recycling_fraction_tests.jl | 3 +- .../test/restart_interpolation_tests.jl | 3 +- moment_kinetics/test/sound_wave_tests.jl | 3 +- moment_kinetics/test/wall_bc_tests.jl | 3 +- 12 files changed, 40 insertions(+), 67 deletions(-) diff --git a/moment_kinetics/debug_test/wall_bc_inputs.jl b/moment_kinetics/debug_test/wall_bc_inputs.jl index 6698d2700..48560dd6d 100644 --- a/moment_kinetics/debug_test/wall_bc_inputs.jl +++ b/moment_kinetics/debug_test/wall_bc_inputs.jl @@ -1,6 +1,6 @@ test_type = "Wall boundary conditions" using moment_kinetics.type_definitions: OptionsDict -using moment_kinetics.input_structs: merge_dict_of_dicts +using moment_kinetics.util: recursive_merge # default inputs for tests test_input_finite_difference_1D1V = OptionsDict( @@ -46,7 +46,7 @@ test_input_finite_difference_1D1V = OptionsDict( "vr_ngrid" => 1, "vr_nelement" => 1) -test_input_finite_difference_simple_sheath_1D1V = merge_dict_of_dicts( +test_input_finite_difference_simple_sheath_1D1V = recursive_merge( test_input_finite_difference_1D1V, OptionsDict("run_name" => "finite_difference_simple_sheath_1D1V", "composition" => OptionsDict("electron_physics" => "boltzmann_electron_response_with_simple_sheath"))) @@ -70,7 +70,7 @@ test_input_finite_difference = merge( "vzeta_nelement" => 1, "vzeta_discretization" => "finite_difference")) -test_input_finite_difference_simple_sheath = merge_dict_of_dicts( +test_input_finite_difference_simple_sheath = recursive_merge( test_input_finite_difference, OptionsDict("run_name" => "finite_difference_simple_sheath", "composition" => OptionsDict("electron_physics" => "boltzmann_electron_response_with_simple_sheath"))) @@ -101,7 +101,7 @@ test_input_chebyshev_split3_1D1V = merge(test_input_chebyshev_split2_1D1V, "evolve_moments_parallel_pressure" => true)) -test_input_chebyshev_simple_sheath_1D1V = merge_dict_of_dicts( +test_input_chebyshev_simple_sheath_1D1V = recursive_merge( test_input_chebyshev_1D1V, OptionsDict("run_name" => "chebyshev_pseudospectral_simple_sheath_1D1V", "composition" => OptionsDict("electron_physics" => "boltzmann_electron_response_with_simple_sheath"))) @@ -125,7 +125,7 @@ test_input_chebyshev = merge( "vzeta_ngrid" => 3, "vzeta_nelement" => 1)) -test_input_chebyshev_simple_sheath = merge_dict_of_dicts( +test_input_chebyshev_simple_sheath = recursive_merge( test_input_chebyshev, OptionsDict("run_name" => "chebyshev_pseudospectral_simple_sheath", "composition" => OptionsDict("electron_physics" => "boltzmann_electron_response_with_simple_sheath"))) diff --git a/moment_kinetics/src/input_structs.jl b/moment_kinetics/src/input_structs.jl index cc4c6edd9..8b681178d 100644 --- a/moment_kinetics/src/input_structs.jl +++ b/moment_kinetics/src/input_structs.jl @@ -17,7 +17,6 @@ export pp_input export geometry_input export set_defaults_and_check_top_level!, set_defaults_and_check_section!, options_to_TOML, Dict_to_NamedTuple -export merge_dict_with_kwargs!, merge_dict_of_dicts!, merge_dict_of_dicts using ..communication using ..type_definitions: mk_float, mk_int @@ -758,57 +757,6 @@ function Dict_to_NamedTuple(d) return NamedTuple(Symbol(k)=>v for (k,v) ∈ d) end -""" -Dict merge function for named keyword arguments -for case when input Dict is a mixed Dict of Dicts -and non-Dict float/int/string entries, and the -keyword arguments are also a mix of Dicts and non-Dicts -""" - -function merge_dict_with_kwargs!(dict_base; args...) - for (k,v) in args - k = String(k) - if k in keys(dict_base) && isa(v, AbstractDict) - v = merge(dict_base[k], v) - end - dict_base[k] = v - end - return nothing -end - -""" -Dict merge function for merging Dicts of Dicts -In place merge, returns nothing -""" - -function merge_dict_of_dicts!(dict_base, dict_mod) - for (k,v) in dict_mod - k = String(k) - if k in keys(dict_base) && isa(v, AbstractDict) - v = merge(dict_base[k], v) - end - dict_base[k] = v - end - return nothing -end - -""" -Dict merge function for merging Dicts of Dicts -Creates new dict, which is returned -""" - -function merge_dict_of_dicts(dict_base, dict_mod) - dict_new = deepcopy(dict_base) - for (k,v) in dict_mod - k = String(k) - if k in keys(dict_new) && isa(v, AbstractDict) - v = merge(dict_new[k], v) - end - dict_new[k] = v - end - return dict_new -end - """ options_to_toml(io::IO [=stdout], data::AbstractDict; sorted=false, by=identity) diff --git a/moment_kinetics/src/utils.jl b/moment_kinetics/src/utils.jl index 33aebfc57..af6d76368 100644 --- a/moment_kinetics/src/utils.jl +++ b/moment_kinetics/src/utils.jl @@ -4,7 +4,7 @@ Utility functions module utils export get_unnormalized_parameters, print_unnormalized_parameters, to_seconds, to_minutes, - to_hours, recursive_merge + to_hours, recursive_merge, merge_dict_with_kwargs! using ..communication using ..constants @@ -314,6 +314,23 @@ function recursive_merge(a, b) return b end +""" +Dict merge function for named keyword arguments +for case when input Dict is a mixed Dict of Dicts +and non-Dict float/int/string entries, and the +keyword arguments are also a mix of Dicts and non-Dicts +""" +function merge_dict_with_kwargs!(dict_base; args...) + for (k,v) in args + k = String(k) + if k in keys(dict_base) && isa(v, AbstractDict) + v = recursive_merge(dict_base[k], v) + end + dict_base[k] = v + end + return nothing +end + # Utility functions for timestepping """ diff --git a/moment_kinetics/test/Krook_collisions_tests.jl b/moment_kinetics/test/Krook_collisions_tests.jl index 806bad279..5bbc9e49b 100644 --- a/moment_kinetics/test/Krook_collisions_tests.jl +++ b/moment_kinetics/test/Krook_collisions_tests.jl @@ -7,7 +7,7 @@ include("setup.jl") using Base.Filesystem: tempname using moment_kinetics.coordinates: define_coordinate -using moment_kinetics.input_structs: grid_input, advection_input, merge_dict_with_kwargs! +using moment_kinetics.input_structs: grid_input, advection_input using moment_kinetics.load_data: open_readonly_output_file, load_coordinate_data, load_species_data, load_fields_data, load_ion_moments_data, load_pdf_data, @@ -15,6 +15,7 @@ using moment_kinetics.load_data: open_readonly_output_file, load_coordinate_data load_neutral_pdf_data, load_time_data, load_species_data using moment_kinetics.interpolation: interpolate_to_grid_z, interpolate_to_grid_vpa using moment_kinetics.type_definitions: mk_float, OptionsDict +using moment_kinetics.utils: merge_dict_with_kwargs! # Useful parameters const z_L = 1.0 # always 1 in normalized units? diff --git a/moment_kinetics/test/braginskii_electrons_imex_tests.jl b/moment_kinetics/test/braginskii_electrons_imex_tests.jl index 4bf902b8c..02e0cc1a8 100644 --- a/moment_kinetics/test/braginskii_electrons_imex_tests.jl +++ b/moment_kinetics/test/braginskii_electrons_imex_tests.jl @@ -10,10 +10,11 @@ using Base.Filesystem: tempname using MPI using moment_kinetics.coordinates: define_coordinate -using moment_kinetics.input_structs: grid_input, advection_input, merge_dict_with_kwargs! +using moment_kinetics.input_structs: grid_input, advection_input using moment_kinetics.interpolation: interpolate_to_grid_z using moment_kinetics.load_data: get_run_info_no_setup, close_run_info, get_variable using moment_kinetics.type_definitions: OptionsDict +using moment_kinetics.utils: merge_dict_with_kwargs! # default inputs for tests test_input = OptionsDict( "composition" => OptionsDict("n_ion_species" => 1, diff --git a/moment_kinetics/test/fokker_planck_time_evolution_tests.jl b/moment_kinetics/test/fokker_planck_time_evolution_tests.jl index 544a5fafa..b306e5baf 100644 --- a/moment_kinetics/test/fokker_planck_time_evolution_tests.jl +++ b/moment_kinetics/test/fokker_planck_time_evolution_tests.jl @@ -5,12 +5,13 @@ using Base.Filesystem: tempname using MPI using moment_kinetics.coordinates: define_coordinate -using moment_kinetics.input_structs: grid_input, advection_input, merge_dict_with_kwargs! +using moment_kinetics.input_structs: grid_input, advection_input using moment_kinetics.load_data: open_readonly_output_file, load_coordinate_data, load_species_data, load_fields_data, load_ion_moments_data, load_pdf_data, load_time_data, load_species_data using moment_kinetics.type_definitions: mk_float, OptionsDict +using moment_kinetics.utils: merge_dict_with_kwargs! const analytical_rtol = 3.e-2 const regression_rtol = 2.e-8 diff --git a/moment_kinetics/test/harrisonthompson.jl b/moment_kinetics/test/harrisonthompson.jl index 0945f72e2..eef9bd950 100644 --- a/moment_kinetics/test/harrisonthompson.jl +++ b/moment_kinetics/test/harrisonthompson.jl @@ -11,8 +11,8 @@ using SpecialFunctions: dawson using moment_kinetics.load_data: open_readonly_output_file using moment_kinetics.load_data: load_fields_data, load_time_data using moment_kinetics.load_data: load_species_data, load_coordinate_data -using moment_kinetics.input_structs: merge_dict_with_kwargs! using moment_kinetics.type_definitions: OptionsDict +using moment_kinetics.utils: merge_dict_with_kwargs! ionization_frequency = 0.688 diff --git a/moment_kinetics/test/nonlinear_sound_wave_tests.jl b/moment_kinetics/test/nonlinear_sound_wave_tests.jl index 7da52ab70..7e3a7efd6 100644 --- a/moment_kinetics/test/nonlinear_sound_wave_tests.jl +++ b/moment_kinetics/test/nonlinear_sound_wave_tests.jl @@ -5,11 +5,12 @@ include("setup.jl") using Base.Filesystem: tempname using moment_kinetics.coordinates: define_coordinate -using moment_kinetics.input_structs: grid_input, advection_input, merge_dict_with_kwargs! +using moment_kinetics.input_structs: grid_input, advection_input using moment_kinetics.interpolation: interpolate_to_grid_z, interpolate_to_grid_vpa using moment_kinetics.load_data: get_run_info_no_setup, close_run_info, postproc_load_variable using moment_kinetics.type_definitions: mk_float, OptionsDict +using moment_kinetics.utils: merge_dict_with_kwargs! const analytical_rtol = 3.e-2 const regression_rtol = 2.e-8 diff --git a/moment_kinetics/test/recycling_fraction_tests.jl b/moment_kinetics/test/recycling_fraction_tests.jl index deb5a178c..b371da032 100644 --- a/moment_kinetics/test/recycling_fraction_tests.jl +++ b/moment_kinetics/test/recycling_fraction_tests.jl @@ -10,11 +10,12 @@ using Base.Filesystem: tempname using MPI using moment_kinetics.coordinates: define_coordinate -using moment_kinetics.input_structs: grid_input, advection_input, merge_dict_with_kwargs! +using moment_kinetics.input_structs: grid_input, advection_input using moment_kinetics.interpolation: interpolate_to_grid_z using moment_kinetics.load_data: get_run_info_no_setup, close_run_info, postproc_load_variable using moment_kinetics.type_definitions: OptionsDict +using moment_kinetics.utils: merge_dict_with_kwargs! # default inputs for tests test_input = Dict("composition" => OptionsDict("n_ion_species" => 1, diff --git a/moment_kinetics/test/restart_interpolation_tests.jl b/moment_kinetics/test/restart_interpolation_tests.jl index ca6a166ba..3995e536e 100644 --- a/moment_kinetics/test/restart_interpolation_tests.jl +++ b/moment_kinetics/test/restart_interpolation_tests.jl @@ -9,7 +9,7 @@ using Base.Filesystem: tempname using moment_kinetics.communication using moment_kinetics.coordinates: define_coordinate using moment_kinetics.file_io: io_has_parallel -using moment_kinetics.input_structs: grid_input, advection_input, hdf5, merge_dict_with_kwargs! +using moment_kinetics.input_structs: grid_input, advection_input, hdf5 using moment_kinetics.load_data: open_readonly_output_file, load_coordinate_data, load_species_data, load_fields_data, load_ion_moments_data, load_pdf_data, @@ -19,6 +19,7 @@ using moment_kinetics.interpolation: interpolate_to_grid_z, interpolate_to_grid_ using moment_kinetics.load_data: get_run_info_no_setup, close_run_info, postproc_load_variable using moment_kinetics.type_definitions: mk_float, OptionsDict +using moment_kinetics.utils: merge_dict_with_kwargs! include("nonlinear_sound_wave_inputs_and_expected_data.jl") diff --git a/moment_kinetics/test/sound_wave_tests.jl b/moment_kinetics/test/sound_wave_tests.jl index 7da2ab497..9716b74bc 100644 --- a/moment_kinetics/test/sound_wave_tests.jl +++ b/moment_kinetics/test/sound_wave_tests.jl @@ -6,7 +6,7 @@ using Base.Filesystem: tempname #using Plots: plot, plot!, gui using moment_kinetics.array_allocation: allocate_float -using moment_kinetics.input_structs: netcdf, merge_dict_with_kwargs! +using moment_kinetics.input_structs: netcdf using moment_kinetics.file_io: io_has_implementation using moment_kinetics.load_data: open_readonly_output_file using moment_kinetics.load_data: load_fields_data, load_time_data @@ -14,6 +14,7 @@ using moment_kinetics.load_data: load_species_data, load_coordinate_data using moment_kinetics.analysis: analyze_fields_data using moment_kinetics.analysis: fit_delta_phi_mode using moment_kinetics.type_definitions: OptionsDict +using moment_kinetics.utils: merge_dict_with_kwargs! const analytical_rtol = 3.e-2 const regression_rtol = 1.e-14 diff --git a/moment_kinetics/test/wall_bc_tests.jl b/moment_kinetics/test/wall_bc_tests.jl index ccb03adbe..e95502719 100644 --- a/moment_kinetics/test/wall_bc_tests.jl +++ b/moment_kinetics/test/wall_bc_tests.jl @@ -9,13 +9,14 @@ using Base.Filesystem: tempname using MPI using moment_kinetics.coordinates: define_coordinate -using moment_kinetics.input_structs: grid_input, advection_input, merge_dict_with_kwargs! +using moment_kinetics.input_structs: grid_input, using moment_kinetics.interpolation: interpolate_to_grid_z using moment_kinetics.load_data: open_readonly_output_file using moment_kinetics.load_data: load_fields_data, load_pdf_data, load_time_data, load_species_data using moment_kinetics.type_definitions: OptionsDict +using moment_kinetics.utils: merge_dict_with_kwargs! # default inputs for tests test_input_finite_difference = Dict("composition" => OptionsDict("n_ion_species" => 1, From 2622a24ec073a2808d77bad7cf4db29b753cd5fd Mon Sep 17 00:00:00 2001 From: Lucas McConnell Date: Sun, 8 Sep 2024 16:08:26 +0100 Subject: [PATCH 15/87] Clean up small typos --- moment_kinetics/src/external_sources.jl | 2 +- moment_kinetics/src/vpa_advection.jl | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/moment_kinetics/src/external_sources.jl b/moment_kinetics/src/external_sources.jl index c3a7d8b7e..48546a02f 100644 --- a/moment_kinetics/src/external_sources.jl +++ b/moment_kinetics/src/external_sources.jl @@ -364,7 +364,7 @@ function setup_external_sources!(input_dict, r, z, electron_physics) else # this is not very efficient because we're copying the same electron_settings # for each ion source - push!(electron_sources, get_settings_electrons(inactive_ion_source)) + push!(electron_sources, get_settings_electrons(get_settings_ions(1, false))) end # put all neutral sources into neutral_source_data struct vector diff --git a/moment_kinetics/src/vpa_advection.jl b/moment_kinetics/src/vpa_advection.jl index 328395e9a..32f43007a 100644 --- a/moment_kinetics/src/vpa_advection.jl +++ b/moment_kinetics/src/vpa_advection.jl @@ -433,7 +433,7 @@ function update_speed_n_u_p_evolution!(advect, fvec, moments, vpa, z, r, composi end end end - for index ∈ eachindex(ion_source_settings.ion) + for index ∈ eachindex(ion_source_settings) if ion_source_settings[index].active @views source_density_amplitude = moments.ion.external_source_density_amplitude[:, :, index] @views source_momentum_amplitude = moments.ion.external_source_momentum_amplitude[:, :, index] @@ -540,7 +540,7 @@ function update_speed_n_u_evolution!(advect, fvec, moments, vpa, z, r, compositi end end end - for index ∈ eachindex(ion_source_settings.ion) + for index ∈ eachindex(ion_source_settings) if ion_source_settings[index].active @views source_density_amplitude = moments.ion.external_source_density_amplitude[:, :, index] source_strength = ion_source_settings[index].source_strength From 6123063d5ed901c9ce516d746f3980b748a5b663 Mon Sep 17 00:00:00 2001 From: Lucas McConnell Date: Sun, 8 Sep 2024 16:09:17 +0100 Subject: [PATCH 16/87] Update all example input files and test files --- .../fokker-planck-relaxation-slowing-down-alphas.toml | 2 +- ...ck-source-sink-slowing-down-alphas-no-self-collisions.toml | 2 +- .../fokker-planck-source-sink-slowing-down-alphas.toml | 2 +- .../wall-bc_recyclefraction0.5_split3_boltzmann-vpadiss0.toml | 2 +- .../wall-bc_recyclefraction0.5_split3_boltzmann.toml | 2 +- ...bc_recyclefraction0.5_split3_braginskii-vpadiss0-IMEX.toml | 2 +- .../wall-bc_recyclefraction0.5_split3_kinetic-vpadiss0.toml | 2 +- .../recycling-fraction/wall-bc_recyclefraction0.5-init.toml | 2 +- examples/recycling-fraction/wall-bc_recyclefraction0.5.toml | 2 +- .../recycling-fraction/wall-bc_recyclefraction0.5_split1.toml | 2 +- .../recycling-fraction/wall-bc_recyclefraction0.5_split2.toml | 2 +- .../wall-bc_recyclefraction0.5_split3-init.toml | 2 +- .../recycling-fraction/wall-bc_recyclefraction0.5_split3.toml | 2 +- .../wall-bc_recyclefraction0.5_split3_SSPRK4.toml | 2 +- .../wall-bc_recyclefraction0.5_split3_fekete104.toml | 2 +- .../wall-bc_recyclefraction0.5_split3_fekete42.toml | 2 +- .../wall-bc_recyclefraction0.5_split3_fekete64.toml | 2 +- .../wall-bc_recyclefraction0.5_split3_rkf54.toml | 2 +- examples/wall-bc/wall-bc_no-neutrals.toml | 2 +- examples/wall-bc/wall-bc_no-neutrals_split1.toml | 2 +- examples/wall-bc/wall-bc_no-neutrals_split2.toml | 2 +- examples/wall-bc/wall-bc_no-neutrals_split3.toml | 2 +- examples/wall-bc/wall-bc_volumerecycle.toml | 4 ++-- examples/wall-bc/wall-bc_volumerecycle_split1.toml | 4 ++-- examples/wall-bc/wall-bc_volumerecycle_split2.toml | 4 ++-- examples/wall-bc/wall-bc_volumerecycle_split3.toml | 4 ++-- moment_kinetics/debug_test/kinetic_electron_inputs.jl | 2 +- moment_kinetics/debug_test/recycling_fraction_inputs.jl | 2 +- moment_kinetics/test/harrisonthompson.jl | 2 +- moment_kinetics/test/recycling_fraction_tests.jl | 2 +- .../wall-bc/wall-bc_recyclefraction0.5.toml | 2 +- .../wall-bc/wall-bc_recyclefraction0.5_split1.toml | 2 +- .../wall-bc/wall-bc_recyclefraction0.5_split2.toml | 2 +- .../wall-bc/wall-bc_recyclefraction0.5_split3.toml | 2 +- 34 files changed, 38 insertions(+), 38 deletions(-) diff --git a/examples/fokker-planck/fokker-planck-relaxation-slowing-down-alphas.toml b/examples/fokker-planck/fokker-planck-relaxation-slowing-down-alphas.toml index e6b75e29c..5218fbf4f 100644 --- a/examples/fokker-planck/fokker-planck-relaxation-slowing-down-alphas.toml +++ b/examples/fokker-planck/fokker-planck-relaxation-slowing-down-alphas.toml @@ -65,7 +65,7 @@ sd_mi = 0.5 # mD/malpha sd_me = 0.000013616 # 0.25/1836.0 me/malpha sd_q = 1.0 -[ion_source] +[ion_source_1] active=false source_strength=0.0 source_T=0.005 diff --git a/examples/fokker-planck/fokker-planck-source-sink-slowing-down-alphas-no-self-collisions.toml b/examples/fokker-planck/fokker-planck-source-sink-slowing-down-alphas-no-self-collisions.toml index 1a95fc210..bb69178fb 100644 --- a/examples/fokker-planck/fokker-planck-source-sink-slowing-down-alphas-no-self-collisions.toml +++ b/examples/fokker-planck/fokker-planck-source-sink-slowing-down-alphas-no-self-collisions.toml @@ -64,7 +64,7 @@ sd_mi = 0.5 # mD/malpha sd_me = 0.000013616 # 0.25/1836.0 me/malpha sd_q = 1.0 -[ion_source] +[ion_source_1] active=true source_strength=1.0 source_T=0.005 diff --git a/examples/fokker-planck/fokker-planck-source-sink-slowing-down-alphas.toml b/examples/fokker-planck/fokker-planck-source-sink-slowing-down-alphas.toml index cd49c82e7..fc53ee470 100644 --- a/examples/fokker-planck/fokker-planck-source-sink-slowing-down-alphas.toml +++ b/examples/fokker-planck/fokker-planck-source-sink-slowing-down-alphas.toml @@ -64,7 +64,7 @@ sd_mi = 0.5 # mD/malpha sd_me = 0.000013616 # 0.25/1836.0 me/malpha sd_q = 1.0 -[ion_source] +[ion_source_1] active=true source_strength=1.0 source_T=0.005 diff --git a/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_boltzmann-vpadiss0.toml b/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_boltzmann-vpadiss0.toml index 58998f2f0..b09ee80c6 100644 --- a/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_boltzmann-vpadiss0.toml +++ b/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_boltzmann-vpadiss0.toml @@ -74,7 +74,7 @@ nwrite_dfns = 100000 steady_state_residual = true converged_residual_value = 1.0e-3 -[ion_source] +[ion_source_1] active = true z_profile = "gaussian" z_width = 0.125 diff --git a/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_boltzmann.toml b/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_boltzmann.toml index 4b36701ae..f993e7561 100644 --- a/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_boltzmann.toml +++ b/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_boltzmann.toml @@ -74,7 +74,7 @@ nwrite_dfns = 100000 steady_state_residual = true converged_residual_value = 1.0e-3 -[ion_source] +[ion_source_1] active = true z_profile = "gaussian" z_width = 0.125 diff --git a/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_braginskii-vpadiss0-IMEX.toml b/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_braginskii-vpadiss0-IMEX.toml index c9230a33a..c6f91785d 100644 --- a/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_braginskii-vpadiss0-IMEX.toml +++ b/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_braginskii-vpadiss0-IMEX.toml @@ -84,7 +84,7 @@ steady_state_residual = true converged_residual_value = 1.0e-3 #write_after_fixed_step_count = true -[ion_source] +[ion_source_1] active = true z_profile = "gaussian" z_width = 0.125 diff --git a/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_kinetic-vpadiss0.toml b/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_kinetic-vpadiss0.toml index 0a66ed75e..9af371c6a 100644 --- a/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_kinetic-vpadiss0.toml +++ b/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_kinetic-vpadiss0.toml @@ -90,7 +90,7 @@ minimum_dt = 1.0e-9 initialization_residual_value = 2.5 converged_residual_value = 0.1 #1.0e-3 -[ion_source] +[ion_source_1] active = true z_profile = "gaussian" z_width = 0.125 diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5-init.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5-init.toml index 9442b1dde..6c73e7b25 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5-init.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5-init.toml @@ -75,7 +75,7 @@ converged_residual_value = 1.0e-3 [krook_collisions] use_krook = true -[ion_source] +[ion_source_1] active = true z_profile = "gaussian" z_width = 0.125 diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5.toml index 70e81e234..85ab587b9 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5.toml @@ -80,7 +80,7 @@ converged_residual_value = 1.0e-3 [krook_collisions] use_krook = true -[ion_source] +[ion_source_1] active = true z_profile = "gaussian" z_width = 0.125 diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split1.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split1.toml index 634959e88..60a6b8671 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split1.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split1.toml @@ -80,7 +80,7 @@ converged_residual_value = 1.0e-3 [krook_collisions] use_krook = true -[ion_source] +[ion_source_1] active = true z_profile = "gaussian" z_width = 0.125 diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split2.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split2.toml index f1ba6bc68..770c49197 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split2.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split2.toml @@ -80,7 +80,7 @@ converged_residual_value = 1.0e-3 [krook_collisions] use_krook = true -[ion_source] +[ion_source_1] active = true z_profile = "gaussian" z_width = 0.125 diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3-init.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3-init.toml index 7c6e17f90..4ea030e52 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3-init.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3-init.toml @@ -75,7 +75,7 @@ converged_residual_value = 1.0e-3 [krook_collisions] use_krook = true -[ion_source] +[ion_source_1] active = true z_profile = "gaussian" z_width = 0.125 diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3.toml index 1352d2fdd..96dfe0d41 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3.toml @@ -80,7 +80,7 @@ converged_residual_value = 1.0e-3 [krook_collisions] use_krook = true -[ion_source] +[ion_source_1] active = true z_profile = "gaussian" z_width = 0.125 diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_SSPRK4.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_SSPRK4.toml index 73be81551..30f0ab14d 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_SSPRK4.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_SSPRK4.toml @@ -74,7 +74,7 @@ converged_residual_value = 1.0e-3 [krook_collisions] use_krook = true -[ion_source] +[ion_source_1] active = true z_profile = "gaussian" z_width = 0.125 diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete104.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete104.toml index 26a9fda8b..a489cfbd7 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete104.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete104.toml @@ -82,7 +82,7 @@ converged_residual_value = 1.0e-3 [krook_collisions] use_krook = true -[ion_source] +[ion_source_1] active = true z_profile = "gaussian" z_width = 0.125 diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete42.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete42.toml index 7478a386e..f8f00d7e3 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete42.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete42.toml @@ -82,7 +82,7 @@ converged_residual_value = 1.0e-3 [krook_collisions] use_krook = true -[ion_source] +[ion_source_1] active = true z_profile = "gaussian" z_width = 0.125 diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete64.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete64.toml index 3c86487ac..5814d393e 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete64.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete64.toml @@ -82,7 +82,7 @@ converged_residual_value = 1.0e-3 [krook_collisions] use_krook = true -[ion_source] +[ion_source_1] active = true z_profile = "gaussian" z_width = 0.125 diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_rkf54.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_rkf54.toml index 8372db4cc..5534ffc3d 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_rkf54.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_rkf54.toml @@ -82,7 +82,7 @@ converged_residual_value = 1.0e-3 [krook_collisions] use_krook = true -[ion_source] +[ion_source_1] active = true z_profile = "gaussian" z_width = 0.125 diff --git a/examples/wall-bc/wall-bc_no-neutrals.toml b/examples/wall-bc/wall-bc_no-neutrals.toml index ce5da5ba8..ab5b26595 100644 --- a/examples/wall-bc/wall-bc_no-neutrals.toml +++ b/examples/wall-bc/wall-bc_no-neutrals.toml @@ -70,7 +70,7 @@ nwrite = 5000 nwrite_dfns = 5000 split_operators = false -[ion_source] +[ion_source_1] active = true z_profile = "gaussian" z_width = 0.125 diff --git a/examples/wall-bc/wall-bc_no-neutrals_split1.toml b/examples/wall-bc/wall-bc_no-neutrals_split1.toml index cae94a045..0e6086ed0 100644 --- a/examples/wall-bc/wall-bc_no-neutrals_split1.toml +++ b/examples/wall-bc/wall-bc_no-neutrals_split1.toml @@ -70,7 +70,7 @@ nwrite = 5000 nwrite_dfns = 5000 split_operators = false -[ion_source] +[ion_source_1] active = true z_profile = "gaussian" z_width = 0.125 diff --git a/examples/wall-bc/wall-bc_no-neutrals_split2.toml b/examples/wall-bc/wall-bc_no-neutrals_split2.toml index ce74ec368..2159851d8 100644 --- a/examples/wall-bc/wall-bc_no-neutrals_split2.toml +++ b/examples/wall-bc/wall-bc_no-neutrals_split2.toml @@ -70,7 +70,7 @@ nwrite = 5000 nwrite_dfns = 5000 split_operators = false -[ion_source] +[ion_source_1] active = true z_profile = "gaussian" z_width = 0.125 diff --git a/examples/wall-bc/wall-bc_no-neutrals_split3.toml b/examples/wall-bc/wall-bc_no-neutrals_split3.toml index 23316e611..25664c688 100644 --- a/examples/wall-bc/wall-bc_no-neutrals_split3.toml +++ b/examples/wall-bc/wall-bc_no-neutrals_split3.toml @@ -70,7 +70,7 @@ nwrite = 5000 nwrite_dfns = 5000 split_operators = false -[ion_source] +[ion_source_1] active = true z_profile = "gaussian" z_width = 0.125 diff --git a/examples/wall-bc/wall-bc_volumerecycle.toml b/examples/wall-bc/wall-bc_volumerecycle.toml index 1cbf7f1b2..ee6a36dd6 100644 --- a/examples/wall-bc/wall-bc_volumerecycle.toml +++ b/examples/wall-bc/wall-bc_volumerecycle.toml @@ -72,14 +72,14 @@ nwrite = 10000 nwrite_dfns = 10000 split_operators = false -[ion_source] +[ion_source_1] active = true z_profile = "gaussian" z_width = 0.125 source_strength = 2.0 source_T = 2.0 -[neutral_source] +[neutral_source_1] active = true source_type = "recycling" recycling_controller_fraction = 0.25 diff --git a/examples/wall-bc/wall-bc_volumerecycle_split1.toml b/examples/wall-bc/wall-bc_volumerecycle_split1.toml index 442ce033d..a2fba2249 100644 --- a/examples/wall-bc/wall-bc_volumerecycle_split1.toml +++ b/examples/wall-bc/wall-bc_volumerecycle_split1.toml @@ -72,14 +72,14 @@ nwrite = 10000 nwrite_dfns = 10000 split_operators = false -[ion_source] +[ion_source_1] active = true z_profile = "gaussian" z_width = 0.125 source_strength = 2.0 source_T = 2.0 -[neutral_source] +[neutral_source_1] active = true source_type = "recycling" recycling_controller_fraction = 0.25 diff --git a/examples/wall-bc/wall-bc_volumerecycle_split2.toml b/examples/wall-bc/wall-bc_volumerecycle_split2.toml index 08eb2ed6c..1a5c2e968 100644 --- a/examples/wall-bc/wall-bc_volumerecycle_split2.toml +++ b/examples/wall-bc/wall-bc_volumerecycle_split2.toml @@ -72,14 +72,14 @@ nwrite = 10000 nwrite_dfns = 10000 split_operators = false -[ion_source] +[ion_source_1] active = true z_profile = "gaussian" z_width = 0.125 source_strength = 2.0 source_T = 2.0 -[neutral_source] +[neutral_source_1] active = true source_type = "recycling" recycling_controller_fraction = 0.25 diff --git a/examples/wall-bc/wall-bc_volumerecycle_split3.toml b/examples/wall-bc/wall-bc_volumerecycle_split3.toml index 0c8dad98d..6b3e03cb9 100644 --- a/examples/wall-bc/wall-bc_volumerecycle_split3.toml +++ b/examples/wall-bc/wall-bc_volumerecycle_split3.toml @@ -72,14 +72,14 @@ nwrite = 10000 nwrite_dfns = 10000 split_operators = false -[ion_source] +[ion_source_1] active = true z_profile = "gaussian" z_width = 0.125 source_strength = 2.0 source_T = 2.0 -[neutral_source] +[neutral_source_1] active = true source_type = "recycling" recycling_controller_fraction = 0.25 diff --git a/moment_kinetics/debug_test/kinetic_electron_inputs.jl b/moment_kinetics/debug_test/kinetic_electron_inputs.jl index 684b114ff..5b8d4f7b0 100644 --- a/moment_kinetics/debug_test/kinetic_electron_inputs.jl +++ b/moment_kinetics/debug_test/kinetic_electron_inputs.jl @@ -81,7 +81,7 @@ test_input = Dict("n_ion_species" => 1, "vz_L" => 6.0, "vz_bc" => "zero", "vz_discretization" => "chebyshev_pseudospectral", - "ion_source" => Dict{String,Any}("active" => true, + "ion_source_1" => Dict{String,Any}("active" => true, "z_profile" => "gaussian", "z_width" => 0.125, "source_strength" => 2.0, diff --git a/moment_kinetics/debug_test/recycling_fraction_inputs.jl b/moment_kinetics/debug_test/recycling_fraction_inputs.jl index 7f4b24266..a49015970 100644 --- a/moment_kinetics/debug_test/recycling_fraction_inputs.jl +++ b/moment_kinetics/debug_test/recycling_fraction_inputs.jl @@ -73,7 +73,7 @@ test_input = Dict("n_ion_species" => 1, "vz_L" => 6.0, "vz_bc" => "zero", "vz_discretization" => "chebyshev_pseudospectral", - "ion_source" => Dict("active" => true, + "ion_source_1" => Dict("active" => true, "z_profile" => "gaussian", "z_width" => 0.125, "source_strength" => 2.0, diff --git a/moment_kinetics/test/harrisonthompson.jl b/moment_kinetics/test/harrisonthompson.jl index 06206a263..4830cb216 100644 --- a/moment_kinetics/test/harrisonthompson.jl +++ b/moment_kinetics/test/harrisonthompson.jl @@ -112,7 +112,7 @@ test_input_finite_difference = Dict("n_ion_species" => 1, "vz_L" => 8.0, "vz_bc" => "zero", "vz_discretization" => "finite_difference", - "ion_source" => Dict("active" => true, + "ion_source_1" => Dict("active" => true, "source_strength" => ionization_frequency, "source_T" => 0.25, "z_profile" => "constant", diff --git a/moment_kinetics/test/recycling_fraction_tests.jl b/moment_kinetics/test/recycling_fraction_tests.jl index fed259261..8add56a1f 100644 --- a/moment_kinetics/test/recycling_fraction_tests.jl +++ b/moment_kinetics/test/recycling_fraction_tests.jl @@ -83,7 +83,7 @@ test_input = Dict("n_ion_species" => 1, "vz_L" => 18.0, "vz_bc" => "zero", "vz_discretization" => "chebyshev_pseudospectral", - "ion_source" => Dict("active" => true, + "ion_source_1" => Dict("active" => true, "z_profile" => "gaussian", "z_width" => 0.125, "source_strength" => 2.0, diff --git a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5.toml b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5.toml index 8943ac402..a25476a08 100644 --- a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5.toml +++ b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5.toml @@ -75,7 +75,7 @@ nwrite_dfns = 10000 n_rk_stages = 4 split_operators = false -[ion_source] +[ion_source_1] active = true z_profile = "gaussian" z_width = 0.125 diff --git a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split1.toml b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split1.toml index f7a1484d7..cf192f884 100644 --- a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split1.toml +++ b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split1.toml @@ -75,7 +75,7 @@ nwrite_dfns = 10000 n_rk_stages = 4 split_operators = false -[ion_source] +[ion_source_1] active = true z_profile = "gaussian" z_width = 0.125 diff --git a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split2.toml b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split2.toml index ef1a221cb..d6bba39f0 100644 --- a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split2.toml +++ b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split2.toml @@ -75,7 +75,7 @@ nwrite_dfns = 10000 n_rk_stages = 4 split_operators = false -[ion_source] +[ion_source_1] active = true z_profile = "gaussian" z_width = 0.125 diff --git a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split3.toml b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split3.toml index 79c01a3be..0c0c2711d 100644 --- a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split3.toml +++ b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split3.toml @@ -75,7 +75,7 @@ nwrite_dfns = 10000 n_rk_stages = 4 split_operators = false -[ion_source] +[ion_source_1] active = true z_profile = "gaussian" z_width = 0.125 From dddad290b8620b37ee44301ac1f26d75dd1cdc9b Mon Sep 17 00:00:00 2001 From: Lucas McConnell Date: Mon, 9 Sep 2024 09:52:53 +0100 Subject: [PATCH 17/87] Fix bug in velocity_moments.jl PI_density_controller loop --- moment_kinetics/src/velocity_moments.jl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/moment_kinetics/src/velocity_moments.jl b/moment_kinetics/src/velocity_moments.jl index b362b721b..096dae7b2 100644 --- a/moment_kinetics/src/velocity_moments.jl +++ b/moment_kinetics/src/velocity_moments.jl @@ -156,9 +156,9 @@ function create_moments_ion(nz, nr, n_species, evolve_density, evolve_upar, else external_source_pressure_amplitude = allocate_shared_float(1, 1, n_sources) end - if ion_source_settings.PI_density_controller_I != 0.0 && - ion_source_settings.source_type ∈ ("density_profile_control", "density_midpoint_control") - if ion_source_settings.source_type == "density_profile_control" + if any(x -> x.PI_density_controller_I != 0.0 && x.source_type ∈ + ("density_profile_control", "density_midpoint_control"), ion_source_settings) + if any(x -> x.source_type == "density_profile_control", ion_source_settings) external_source_controller_integral = allocate_shared_float(nz, nr, n_sources) else external_source_controller_integral = allocate_shared_float(1, 1, n_sources) @@ -382,9 +382,9 @@ function create_moments_neutral(nz, nr, n_species, evolve_density, evolve_upar, else external_source_pressure_amplitude = allocate_shared_float(1, 1, n_sources) end - if neutral_source_settings.PI_density_controller_I != 0.0 && - neutral_source_settings.source_type ∈ ("density_profile_control", "density_midpoint_control") - if neutral_source_settings.source_type == "density_profile_control" + if any(x -> x.PI_density_controller_I != 0.0 && x.source_type ∈ + ("density_profile_control", "density_midpoint_control"), neutral_source_settings) + if any(x -> x.source_type == "density_profile_control", neutral_source_settings) external_source_controller_integral = allocate_shared_float(nz, nr, n_sources) else external_source_controller_integral = allocate_shared_float(1, 1, n_sources) From da0f366ee874bc1dcde966f86ca792fa19fd3acf Mon Sep 17 00:00:00 2001 From: Lucas McConnell Date: Mon, 9 Sep 2024 11:08:13 +0100 Subject: [PATCH 18/87] Add exponential wall decay profile option to simulate neutral ionisation for ions when n_neutrals = 0, and fix some more small errors introduced during restructuring of source system --- moment_kinetics/src/external_sources.jl | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/moment_kinetics/src/external_sources.jl b/moment_kinetics/src/external_sources.jl index 48546a02f..b53e8b71e 100644 --- a/moment_kinetics/src/external_sources.jl +++ b/moment_kinetics/src/external_sources.jl @@ -350,9 +350,7 @@ function setup_external_sources!(input_dict, r, z, electron_physics) # If there are no ion sources, add an inactive ion source to the vector if counter == 1 - inactive_ion_source = get_settings_ions(1, false) - push!(ion_sources, inactive_ion_source) - counter += 1 + push!(ion_sources, get_settings_ions(1, false)) end # put all electron sources into electron_source_data struct vector, where @@ -360,11 +358,9 @@ function setup_external_sources!(input_dict, r, z, electron_physics) electron_sources = electron_source_data[] if electron_physics ∈ (braginskii_fluid, kinetic_electrons, kinetic_electrons_with_temperature_equation) - electron_sources .= get_settings_electrons.(ion_sources) + electron_sources = [get_settings_electrons(ion_sources[i]) for i ∈ 1:counter] else - # this is not very efficient because we're copying the same electron_settings - # for each ion source - push!(electron_sources, get_settings_electrons(get_settings_ions(1, false))) + electron_sources = [get_settings_electrons(get_settings_ions(1, false)) for i ∈ 1:counter] end # put all neutral sources into neutral_source_data struct vector @@ -408,6 +404,10 @@ function get_source_profile(profile_type, width, relative_minimum, coord) end end return profile + elseif profile_type == "wall_exp_decay" + x = coord.grid + return @. (1.0 - relative_minimum) * exp(-(x-x[1]) / width) + relative_minimum + + (1.0 - relative_minimum) * exp(-(x[end]-x) / width) + relative_minimum else error("Unrecognised source profile type '$profile_type'.") end @@ -572,7 +572,7 @@ function initialize_external_source_amplitude!(moments, external_source_settings neutral_source_settings = external_source_settings.neutral for index ∈ eachindex(neutral_source_settings) if neutral_source_settings[index].active - if neutral_source.source_type == "energy" + if neutral_source_settings[index].source_type == "energy" @loop_r_z ir iz begin moments.neutral.external_source_amplitude[iz,ir,index] = neutral_source_settings[index].source_strength * @@ -1087,7 +1087,7 @@ function external_neutral_source!(pdf, fvec, moments, neutral_source, index, vze end - if neutral_source_settings.source_type == "energy" + if neutral_source.source_type == "energy" # Take particles out of pdf so source does not change density @loop_sn_r_z_vzeta_vr_vz isn ir iz ivzeta ivr ivz begin pdf[iveta,ivr,ivz,iz,ir,isn] -= dt * source_amplitude[iz,ir] * From 9bfb6310a9c69685a363fe1d3997e7277ec1ae00 Mon Sep 17 00:00:00 2001 From: Lucas McConnell Date: Mon, 9 Sep 2024 11:09:32 +0100 Subject: [PATCH 19/87] Temporary fix for file_io.jl, where only the first source profile of each species has its information written out to the HDF5 file. Need to update this when possible, so that each source_amplitude can be written out for each source instead. --- moment_kinetics/src/file_io.jl | 67 ++++++++++++++++------------------ 1 file changed, 32 insertions(+), 35 deletions(-) diff --git a/moment_kinetics/src/file_io.jl b/moment_kinetics/src/file_io.jl index 0951973a6..48b60dee2 100644 --- a/moment_kinetics/src/file_io.jl +++ b/moment_kinetics/src/file_io.jl @@ -1333,14 +1333,13 @@ function define_dynamic_ion_moment_variables!(fid, n_ion_species, r::coordinate, ion_source_settings = external_source_settings.ion if any(x -> x.active, ion_source_settings) - n = length(ion_source_settings) external_source_amplitude = create_dynamic_variable!( - dynamic, "external_source_amplitude", mk_float, z, r, n; + dynamic, "external_source_amplitude", mk_float, z, r; parallel_io=parallel_io, description="Amplitude of the external source for ions", units="n_ref/c_ref^3*c_ref/L_ref") if evolve_density external_source_density_amplitude = create_dynamic_variable!( - dynamic, "external_source_density_amplitude", mk_float, z, r, n; + dynamic, "external_source_density_amplitude", mk_float, z, r; parallel_io=parallel_io, description="Amplitude of the external density source for ions", units="n_ref*c_ref/L_ref") else @@ -1348,7 +1347,7 @@ function define_dynamic_ion_moment_variables!(fid, n_ion_species, r::coordinate, end if evolve_upar external_source_momentum_amplitude = create_dynamic_variable!( - dynamic, "external_source_momentum_amplitude", mk_float, z, r, n; + dynamic, "external_source_momentum_amplitude", mk_float, z, r; parallel_io=parallel_io, description="Amplitude of the external momentum source for ions", units="m_ref*n_ref*c_ref*c_ref/L_ref") else @@ -1356,17 +1355,17 @@ function define_dynamic_ion_moment_variables!(fid, n_ion_species, r::coordinate, end if evolve_ppar external_source_pressure_amplitude = create_dynamic_variable!( - dynamic, "external_source_pressure_amplitude", mk_float, z, r, n; + dynamic, "external_source_pressure_amplitude", mk_float, z, r; parallel_io=parallel_io, description="Amplitude of the external pressure source for ions", units="m_ref*n_ref*c_ref^2*c_ref/L_ref") else external_source_pressure_amplitude = nothing end - if ion_source_settings.PI_density_controller_I != 0.0 && - ion_source_settings.source_type ∈ ("density_profile_control", "density_midpoint_control") - if ion_source_settings.source_type == "density_profile_control" + if any(x -> x.PI_density_controller_I != 0.0 && x.source_type ∈ + ("density_profile_control", "density_midpoint_control"), ion_source_settings) + if any(x -> x.source_type == "density_profile_control", ion_source_settings) external_source_controller_integral = create_dynamic_variable!( - dynamic, "external_source_controller_integral", mk_float, z, r, n; + dynamic, "external_source_controller_integral", mk_float, z, r; parallel_io=parallel_io, description="Integral term for the PID controller of the external source for ions") else @@ -1546,21 +1545,20 @@ function define_dynamic_electron_moment_variables!(fid, r::coordinate, z::coordi electron_source_settings = external_source_settings.electron if any(x -> x.active, electron_source_settings) - n = length(electron_source_settings) external_source_electron_amplitude = create_dynamic_variable!( - dynamic, "external_source_electron_amplitude", mk_float, z, r, n; + dynamic, "external_source_electron_amplitude", mk_float, z, r; parallel_io=parallel_io, description="Amplitude of the external source for electrons", units="n_ref/c_ref^3*c_ref/L_ref") external_source_electron_density_amplitude = create_dynamic_variable!( - dynamic, "external_source_electron_density_amplitude", mk_float, z, r, n; + dynamic, "external_source_electron_density_amplitude", mk_float, z, r; parallel_io=parallel_io, description="Amplitude of the external density source for electrons", units="n_ref*c_ref/L_ref") external_source_electron_momentum_amplitude = create_dynamic_variable!( - dynamic, "external_source_electron_momentum_amplitude", mk_float, z, r, n; + dynamic, "external_source_electron_momentum_amplitude", mk_float, z, r; parallel_io=parallel_io, description="Amplitude of the external momentum source for electrons", units="m_ref*n_ref*c_ref*c_ref/L_ref") external_source_electron_pressure_amplitude = create_dynamic_variable!( - dynamic, "external_source_electron_pressure_amplitude", mk_float, z, r, n; + dynamic, "external_source_electron_pressure_amplitude", mk_float, z, r; parallel_io=parallel_io, description="Amplitude of the external pressure source for electrons", units="m_ref*n_ref*c_ref^2*c_ref/L_ref") else @@ -1755,14 +1753,13 @@ function define_dynamic_neutral_moment_variables!(fid, n_neutral_species, r::coo neutral_source_settings = external_source_settings.neutral if n_neutral_species > 0 && any(x -> x.active, neutral_source_settings) - n = length(neutral_source_settings) external_source_neutral_amplitude = create_dynamic_variable!( - dynamic, "external_source_neutral_amplitude", mk_float, z, r, n; + dynamic, "external_source_neutral_amplitude", mk_float, z, r; parallel_io=parallel_io, description="Amplitude of the external source for neutrals", units="n_ref/c_ref^3*c_ref/L_ref") if evolve_density external_source_neutral_density_amplitude = create_dynamic_variable!( - dynamic, "external_source_neutral_density_amplitude", mk_float, z, r, n; + dynamic, "external_source_neutral_density_amplitude", mk_float, z, r; parallel_io=parallel_io, description="Amplitude of the external density source for neutrals", units="n_ref*c_ref/L_ref") else @@ -1770,7 +1767,7 @@ function define_dynamic_neutral_moment_variables!(fid, n_neutral_species, r::coo end if evolve_upar external_source_neutral_momentum_amplitude = create_dynamic_variable!( - dynamic, "external_source_neutral_momentum_amplitude", mk_float, z, r, n; + dynamic, "external_source_neutral_momentum_amplitude", mk_float, z, r; parallel_io=parallel_io, description="Amplitude of the external momentum source for neutrals", units="m_ref*n_ref*c_ref*c_ref/L_ref") else @@ -1778,17 +1775,17 @@ function define_dynamic_neutral_moment_variables!(fid, n_neutral_species, r::coo end if evolve_ppar external_source_neutral_pressure_amplitude = create_dynamic_variable!( - dynamic, "external_source_neutral_pressure_amplitude", mk_float, z, r, n; + dynamic, "external_source_neutral_pressure_amplitude", mk_float, z, r; parallel_io=parallel_io, description="Amplitude of the external pressure source for neutrals", units="m_ref*n_ref*c_ref^2*c_ref/L_ref") else external_source_neutral_pressure_amplitude = nothing end - if neutral_source_settings.PI_density_controller_I != 0.0 && - neutral_source_settings.source_type ∈ ("density_profile_control", "density_midpoint_control") - if neutral_source_settings.source_type == "density_profile_control" + if any(x -> x.PI_density_controller_I != 0.0 && x.source_type ∈ + ("density_profile_control", "density_midpoint_control"), neutral_source_settings) + if any(x -> x.source_type == "density_profile_control", neutral_source_settings) external_source_neutral_controller_integral = create_dynamic_variable!( - dynamic, "external_source_neutral_controller_integral", mk_float, z, r, n; + dynamic, "external_source_neutral_controller_integral", mk_float, z, r; parallel_io=parallel_io, description="Integral term for the PID controller of the external source for neutrals") else @@ -2515,21 +2512,21 @@ function write_ion_moments_data_to_binary(scratch, moments, n_ion_species, t_par end if io_moments.external_source_amplitude !== nothing append_to_dynamic_var(io_moments.external_source_amplitude, - moments.ion.external_source_amplitude, t_idx, + moments.ion.external_source_amplitude[:, :, 1], t_idx, parallel_io, z, r) if moments.evolve_density append_to_dynamic_var(io_moments.external_source_density_amplitude, - moments.ion.external_source_density_amplitude, + moments.ion.external_source_density_amplitude[:, :, 1], t_idx, parallel_io, z, r) end if moments.evolve_upar append_to_dynamic_var(io_moments.external_source_momentum_amplitude, - moments.ion.external_source_momentum_amplitude, + moments.ion.external_source_momentum_amplitude[:, :, 1], t_idx, parallel_io, z, r) end if moments.evolve_ppar append_to_dynamic_var(io_moments.external_source_pressure_amplitude, - moments.ion.external_source_pressure_amplitude, + moments.ion.external_source_pressure_amplitude[:, :, 1], t_idx, parallel_io, z, r) end end @@ -2613,16 +2610,16 @@ function write_electron_moments_data_to_binary(scratch, moments, t_params, elect t_idx, parallel_io, z, r) if io_moments.external_source_electron_amplitude !== nothing append_to_dynamic_var(io_moments.external_source_electron_amplitude, - moments.electron.external_source_amplitude, t_idx, + moments.electron.external_source_amplitude[:, :, 1], t_idx, parallel_io, z, r) append_to_dynamic_var(io_moments.external_source_electron_density_amplitude, - moments.electron.external_source_density_amplitude, + moments.electron.external_source_density_amplitude[:, :, 1], t_idx, parallel_io, z, r) append_to_dynamic_var(io_moments.external_source_electron_momentum_amplitude, - moments.electron.external_source_momentum_amplitude, + moments.electron.external_source_momentum_amplitude[:, :, 1], t_idx, parallel_io, z, r) append_to_dynamic_var(io_moments.external_source_electron_pressure_amplitude, - moments.electron.external_source_pressure_amplitude, + moments.electron.external_source_pressure_amplitude[:, :, 1], t_idx, parallel_io, z, r) end append_to_dynamic_var(io_moments.electron_constraints_A_coefficient, @@ -2725,21 +2722,21 @@ function write_neutral_moments_data_to_binary(scratch, moments, n_neutral_specie t_idx, parallel_io, z, r, n_neutral_species) if io_moments.external_source_neutral_amplitude !== nothing append_to_dynamic_var(io_moments.external_source_neutral_amplitude, - moments.neutral.external_source_amplitude, t_idx, + moments.neutral.external_source_amplitude[:, :, 1], t_idx, parallel_io, z, r) if moments.evolve_density append_to_dynamic_var(io_moments.external_source_neutral_density_amplitude, - moments.neutral.external_source_density_amplitude, + moments.neutral.external_source_density_amplitude[:, :, 1], t_idx, parallel_io, z, r) end if moments.evolve_upar append_to_dynamic_var(io_moments.external_source_neutral_momentum_amplitude, - moments.neutral.external_source_momentum_amplitude, + moments.neutral.external_source_momentum_amplitude[:, :, 1], t_idx, parallel_io, z, r) end if moments.evolve_ppar append_to_dynamic_var(io_moments.external_source_neutral_pressure_amplitude, - moments.neutral.external_source_pressure_amplitude, + moments.neutral.external_source_pressure_amplitude[:, :, 1], t_idx, parallel_io, z, r) end end From 25bdbfe4a59490929a8b62af458bf36d2adbba55 Mon Sep 17 00:00:00 2001 From: Lucas McConnell Date: Mon, 9 Sep 2024 14:47:20 +0100 Subject: [PATCH 20/87] Add collisionality_scan option to krook operator for ions --- moment_kinetics/src/krook_collisions.jl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/moment_kinetics/src/krook_collisions.jl b/moment_kinetics/src/krook_collisions.jl index 1880610e9..c113f0bca 100644 --- a/moment_kinetics/src/krook_collisions.jl +++ b/moment_kinetics/src/krook_collisions.jl @@ -41,6 +41,10 @@ function setup_krook_collisions_input(toml_input::Dict, reference_params) input_section["nuii0"] = nuii_krook_default input_section["nuee0"] = nuee_krook_default input_section["nuei0"] = nuei_krook_default + elseif frequency_option == "collisionality_scan" + input_section["nuii0"] *= nuii_krook_default + input_section["nuee0"] *= nuee_krook_default + input_section["nuei0"] *= nuei_krook_default elseif frequency_option == "manual" # use the frequency from the input file # do nothing @@ -74,7 +78,7 @@ function get_collision_frequency_ii(collisions, n, vth) colk = collisions.krook nuii0 = colk.nuii0 frequency_option = colk.frequency_option - if frequency_option == "reference_parameters" + if frequency_option ∈ ("reference_parameters", "collisionality_scan") return @. nuii0 * n * vth^(-3) elseif frequency_option == "manual" # Include 0.0*n so that the result gets promoted to an array if n is an array, From e95e9c0e54fb4cc11b7d9ed52fbf0a85c53f2b13 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Fri, 6 Sep 2024 18:17:50 +0100 Subject: [PATCH 21/87] Update inputs with new coordinate inputs structure --- ...lanck-1D2V-even_nz-shorttest-nstep200.toml | 63 +- ...-planck-relaxation-report-resolutions.toml | 47 +- ...planck-relaxation-slowing-down-alphas.toml | 47 +- ...fokker-planck-relaxation-slowing-down.toml | 46 +- .../fokker-planck-relaxation.toml | 45 +- ...lowing-down-alphas-no-self-collisions.toml | 47 +- ...lanck-source-sink-slowing-down-alphas.toml | 47 +- examples/geometry/1D-mirror.toml | 52 +- examples/gk-ions/2D-periodic-gk.toml | 54 +- .../periodic_split3_boltzmann.toml | 44 +- .../periodic_split3_braginskii-IMEX.toml | 44 +- .../periodic_split3_braginskii.toml | 44 +- .../periodic_split3_kinetic-IMEX.toml | 44 +- .../periodic_split3_kinetic.toml | 44 +- ...ic_split3_kinetic_high-collisionality.toml | 44 +- .../wall+sheath-bc_boltzmann_loworder.toml | 52 +- .../wall+sheath-bc_kinetic.toml | 54 +- ...wall+sheath-bc_kinetic_krook_loworder.toml | 52 +- .../wall+sheath-bc_kinetic_loworder.toml | 52 +- ...on0.5_split3_braginskii-vpadiss0-IMEX.toml | 46 +- ...lefraction0.5_split3_kinetic-vpadiss0.toml | 46 +- .../nonlinear-sound-wave_cheb_split1.toml | 35 +- .../nonlinear-sound-wave_cheb_split2.toml | 35 +- .../nonlinear-sound-wave_cheb_split3.toml | 35 +- .../nonlinear-sound-wave_fd.toml | 35 +- .../nonlinear-sound-wave_fd_split1.toml | 35 +- .../nonlinear-sound-wave_fd_split2.toml | 35 +- .../nonlinear-sound-wave_fd_split3.toml | 35 +- .../num-diss-relaxation.toml | 48 +- .../wall-bc_recyclefraction0.5-init.toml | 50 +- .../wall-bc_recyclefraction0.5.toml | 50 +- .../wall-bc_recyclefraction0.5_split1.toml | 50 +- .../wall-bc_recyclefraction0.5_split2.toml | 50 +- ...all-bc_recyclefraction0.5_split3-init.toml | 50 +- .../wall-bc_recyclefraction0.5_split3.toml | 50 +- ...l-bc_recyclefraction0.5_split3_SSPRK4.toml | 50 +- ...c_recyclefraction0.5_split3_fekete104.toml | 50 +- ...bc_recyclefraction0.5_split3_fekete42.toml | 50 +- ...bc_recyclefraction0.5_split3_fekete64.toml | 50 +- ...ll-bc_recyclefraction0.5_split3_rkf54.toml | 50 +- .../sheath-bc_cheb_test.toml | 37 +- .../wall-bc_cheb_test.toml | 37 +- examples/sound-wave/sound-wave_cheb.toml | 39 +- .../sound-wave/sound-wave_cheb_split1.toml | 35 +- .../sound-wave/sound-wave_cheb_split2.toml | 35 +- .../sound-wave/sound-wave_cheb_split3.toml | 35 +- examples/sound-wave/sound-wave_fd.toml | 35 +- examples/sound-wave/sound-wave_fd_split1.toml | 35 +- examples/sound-wave/sound-wave_fd_split2.toml | 35 +- examples/sound-wave/sound-wave_fd_split3.toml | 35 +- examples/wall-bc/wall+sheath-bc.toml | 40 +- examples/wall-bc/wall-bc_cheb.toml | 44 +- examples/wall-bc/wall-bc_cheb_split1.toml | 44 +- examples/wall-bc/wall-bc_cheb_split2.toml | 44 +- examples/wall-bc/wall-bc_cheb_split3.toml | 44 +- examples/wall-bc/wall-bc_no-neutrals.toml | 42 +- .../wall-bc/wall-bc_no-neutrals_split1.toml | 44 +- .../wall-bc/wall-bc_no-neutrals_split2.toml | 44 +- .../wall-bc/wall-bc_no-neutrals_split3.toml | 44 +- examples/wall-bc/wall-bc_volumerecycle.toml | 48 +- .../wall-bc/wall-bc_volumerecycle_split1.toml | 48 +- .../wall-bc/wall-bc_volumerecycle_split2.toml | 48 +- .../wall-bc/wall-bc_volumerecycle_split3.toml | 48 +- .../src/makie_post_processing.jl | 1 - .../fokker_planck_collisions_inputs.jl | 34 +- .../debug_test/gyroaverage_inputs.jl | 44 +- .../debug_test/kinetic_electron_inputs.jl | 152 +- moment_kinetics/debug_test/mms_inputs.jl | 64 +- .../debug_test/recycling_fraction_inputs.jl | 171 +- .../restart_interpolation_inputs.jl | 75 +- .../debug_test/sound_wave_inputs.jl | 229 +- moment_kinetics/debug_test/wall_bc_inputs.jl | 148 +- .../test/Krook_collisions_tests.jl | 131 +- .../test/braginskii_electrons_imex_tests.jl | 51 +- moment_kinetics/test/calculus_tests.jl | 352 +-- moment_kinetics/test/fokker_planck_tests.jl | 30 +- .../fokker_planck_time_evolution_tests.jl | 117 +- moment_kinetics/test/gyroaverage_tests.jl | 66 +- moment_kinetics/test/harrisonthompson.jl | 101 +- moment_kinetics/test/interpolation_tests.jl | 23 +- .../test/nonlinear_solver_tests.jl | 2 +- ...ear_sound_wave_inputs_and_expected_data.jl | 176 +- .../test/nonlinear_sound_wave_tests.jl | 4 +- .../test/recycling_fraction_tests.jl | 262 +- .../test/restart_interpolation_tests.jl | 113 +- moment_kinetics/test/setup.jl | 3 +- moment_kinetics/test/sound_wave_tests.jl | 187 +- .../test/velocity_integral_tests.jl | 55 +- moment_kinetics/test/wall_bc_tests.jl | 223 +- performance-tests/plot_performance.jl | 4 +- performance-tests/sound_wave-2xres.jl | 155 +- performance-tests/sound_wave.jl | 155 +- .../src/plots_post_processing.jl | 1 - profiling/sound_wave_chebyshev.toml | 22 +- .../sound_wave_chebyshev_split_1_moment.toml | 22 +- .../sound_wave_chebyshev_split_2_moments.toml | 22 +- .../sound_wave_chebyshev_split_3_moments.toml | 22 +- profiling/sound_wave_finite_difference.toml | 28 +- ...wave_finite_difference_split_1_moment.toml | 22 +- ...ave_finite_difference_split_2_moments.toml | 22 +- ...ave_finite_difference_split_3_moments.toml | 22 +- .../sound-wave/scan_sound-wave_T0.25.toml | 40 +- .../scan_sound-wave_T0.25_split1.toml | 40 +- .../scan_sound-wave_T0.25_split2.toml | 40 +- .../scan_sound-wave_T0.25_split3.toml | 40 +- .../sound-wave/scan_sound-wave_T0.5.toml | 40 +- .../scan_sound-wave_T0.5_split1.toml | 40 +- .../scan_sound-wave_T0.5_split2.toml | 40 +- .../scan_sound-wave_T0.5_split3.toml | 40 +- .../sound-wave/scan_sound-wave_T1.toml | 40 +- .../sound-wave/scan_sound-wave_T1_split1.toml | 40 +- .../sound-wave/scan_sound-wave_T1_split2.toml | 40 +- .../sound-wave/scan_sound-wave_T1_split3.toml | 40 +- .../sound-wave/scan_sound-wave_T2.toml | 40 +- .../sound-wave/scan_sound-wave_T2_split1.toml | 40 +- .../sound-wave/scan_sound-wave_T2_split2.toml | 40 +- .../sound-wave/scan_sound-wave_T2_split3.toml | 40 +- .../sound-wave/scan_sound-wave_T4.toml | 40 +- .../sound-wave/scan_sound-wave_T4_split1.toml | 40 +- .../sound-wave/scan_sound-wave_T4_split2.toml | 40 +- .../sound-wave/scan_sound-wave_T4_split3.toml | 40 +- .../sound-wave/scan_sound-wave_nratio.toml | 40 +- .../scan_sound-wave_nratio_split1.toml | 40 +- .../scan_sound-wave_nratio_split2.toml | 40 +- .../scan_sound-wave_nratio_split3.toml | 40 +- .../wall-bc/wall-bc_recyclefraction0.5.toml | 44 +- .../wall-bc_recyclefraction0.5_split1.toml | 44 +- .../wall-bc_recyclefraction0.5_split2.toml | 44 +- .../wall-bc_recyclefraction0.5_split3.toml | 44 +- test_scripts/2D_FEM_assembly_test.jl | 37 +- test_scripts/GaussLobattoLegendre_test.jl | 21 +- test_scripts/cheb_matrix_test.jl | 2322 +++++++++-------- test_scripts/chebyshev_radau_test.jl | 17 +- test_scripts/fkpl_direct_integration_test.jl | 24 +- test_scripts/gyroaverage_test.jl | 78 +- test_scripts/spline_derivatives_test.jl | 178 +- util/precompile_makie_plots.jl | 72 +- util/precompile_plots_plots.jl | 72 +- util/precompile_run.jl | 168 +- util/precompile_run_kinetic-electrons.jl | 94 +- util/precompile_run_long.jl | 37 +- util/precompile_run_long_debug1.jl | 37 +- 142 files changed, 5647 insertions(+), 4754 deletions(-) diff --git a/examples/fokker-planck-1D2V/fokker-planck-1D2V-even_nz-shorttest-nstep200.toml b/examples/fokker-planck-1D2V/fokker-planck-1D2V-even_nz-shorttest-nstep200.toml index 9f56e39db..34e8a84f2 100644 --- a/examples/fokker-planck-1D2V/fokker-planck-1D2V-even_nz-shorttest-nstep200.toml +++ b/examples/fokker-planck-1D2V/fokker-planck-1D2V-even_nz-shorttest-nstep200.toml @@ -6,30 +6,45 @@ charge_exchange_frequency = 0.0 ionization_frequency = 1.0 constant_ionization_rate = true -z_ngrid = 5 -z_nelement = 16 -#z_nelement_local = 2 -z_bc = "wall" -z_element_spacing_option = "sqrt" -z_discretization = "chebyshev_pseudospectral" -r_ngrid = 1 -r_nelement = 1 -r_nelement_local = 1 -r_bc = "periodic" -r_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 6 -vpa_nelement = 15 -vpa_L = 6.0 -vpa_bc = "zero" -#vpa_discretization = "chebyshev_pseudospectral" -vpa_discretization = "gausslegendre_pseudospectral" -vperp_ngrid = 5 -vperp_nelement = 4 -vperp_L = 3.0 -#vperp_bc = "periodic" -#vperp_discretization = "finite_difference" -#vperp_discretization = "chebyshev_pseudospectral" -vperp_discretization = "gausslegendre_pseudospectral" +[z] +ngrid = 5 +nelement = 16 +#nelement_local = 2 +bc = "wall" +element_spacing_option = "sqrt" +discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 +nelement_local = 1 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 6 +nelement = 15 +L = 6.0 +bc = "zero" +#discretization = "chebyshev_pseudospectral" +discretization = "gausslegendre_pseudospectral" + +[vz] +ngrid = 6 +nelement = 15 +L = 6.0 +bc = "zero" +#discretization = "chebyshev_pseudospectral" +discretization = "gausslegendre_pseudospectral" + +[vperp] +ngrid = 5 +nelement = 4 +L = 3.0 +#bc = "periodic" +#discretization = "finite_difference" +#discretization = "chebyshev_pseudospectral" +discretization = "gausslegendre_pseudospectral" [composition] n_ion_species = 1 diff --git a/examples/fokker-planck/fokker-planck-relaxation-report-resolutions.toml b/examples/fokker-planck/fokker-planck-relaxation-report-resolutions.toml index b79376025..e5583d33a 100644 --- a/examples/fokker-planck/fokker-planck-relaxation-report-resolutions.toml +++ b/examples/fokker-planck/fokker-planck-relaxation-report-resolutions.toml @@ -7,26 +7,33 @@ charge_exchange_frequency = 0.0 ionization_frequency = 0.0 constant_ionization_rate = 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" -vperp_bc = "zero" +[z] +ngrid = 1 +nelement = 1 +nelement_local = 1 +bc = "wall" +discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 +nelement_local = 1 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 5 +nelement = 8 +L = 6.0 +bc = "zero" +discretization = "gausslegendre_pseudospectral" + +[vperp] +ngrid = 5 +nelement = 4 +L = 3.0 +discretization = "gausslegendre_pseudospectral" +bc = "zero" # Fokker-Planck operator requires the "gausslegendre_pseudospectral # options for the vpa and vperp grids diff --git a/examples/fokker-planck/fokker-planck-relaxation-slowing-down-alphas.toml b/examples/fokker-planck/fokker-planck-relaxation-slowing-down-alphas.toml index f6bccbe51..fbc9a881a 100644 --- a/examples/fokker-planck/fokker-planck-relaxation-slowing-down-alphas.toml +++ b/examples/fokker-planck/fokker-planck-relaxation-slowing-down-alphas.toml @@ -8,26 +8,33 @@ charge_exchange_frequency = 0.0 ionization_frequency = 0.0 constant_ionization_rate = 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 = 32 -vpa_L = 3.0 -vpa_bc = "zero" -vpa_discretization = "gausslegendre_pseudospectral" -vperp_ngrid = 5 -vperp_nelement = 16 -vperp_L = 1.5 -vperp_discretization = "gausslegendre_pseudospectral" -vperp_bc = "zero" +[z] +ngrid = 1 +nelement = 1 +nelement_local = 1 +bc = "wall" +discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 +nelement_local = 1 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 5 +nelement = 32 +L = 3.0 +bc = "zero" +discretization = "gausslegendre_pseudospectral" + +[vperp] +ngrid = 5 +nelement = 16 +L = 1.5 +discretization = "gausslegendre_pseudospectral" +bc = "zero" # Fokker-Planck operator requires the "gausslegendre_pseudospectral # options for the vpa and vperp grids diff --git a/examples/fokker-planck/fokker-planck-relaxation-slowing-down.toml b/examples/fokker-planck/fokker-planck-relaxation-slowing-down.toml index f637a06ef..98e890945 100644 --- a/examples/fokker-planck/fokker-planck-relaxation-slowing-down.toml +++ b/examples/fokker-planck/fokker-planck-relaxation-slowing-down.toml @@ -6,25 +6,33 @@ evolve_moments_conservation = false charge_exchange_frequency = 0.0 ionization_frequency = 0.0 constant_ionization_rate = 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 = 32 -vpa_L = 6.0 -vpa_bc = "zero" -vpa_discretization = "gausslegendre_pseudospectral" -vperp_ngrid = 5 -vperp_nelement = 16 -vperp_L = 3.0 -vperp_discretization = "gausslegendre_pseudospectral" + +[z] +ngrid = 1 +nelement = 1 +nelement_local = 1 +bc = "wall" +discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 +nelement_local = 1 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 5 +nelement = 32 +L = 6.0 +bc = "zero" +discretization = "gausslegendre_pseudospectral" + +[vperp] +ngrid = 5 +nelement = 16 +L = 3.0 +discretization = "gausslegendre_pseudospectral" # Fokker-Planck operator requires the "gausslegendre_pseudospectral # options for the vpa and vperp grids diff --git a/examples/fokker-planck/fokker-planck-relaxation.toml b/examples/fokker-planck/fokker-planck-relaxation.toml index 9a512fbf8..b5156939c 100644 --- a/examples/fokker-planck/fokker-planck-relaxation.toml +++ b/examples/fokker-planck/fokker-planck-relaxation.toml @@ -7,25 +7,32 @@ charge_exchange_frequency = 0.0 ionization_frequency = 0.0 constant_ionization_rate = 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 = 3 -vpa_nelement = 6 -vpa_L = 6.0 -vpa_bc = "zero" -vpa_discretization = "gausslegendre_pseudospectral" -vperp_ngrid = 3 -vperp_nelement = 3 -vperp_L = 3.0 -vperp_discretization = "gausslegendre_pseudospectral" +[z] +ngrid = 1 +nelement = 1 +nelement_local = 1 +bc = "wall" +discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 +nelement_local = 1 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 3 +nelement = 6 +L = 6.0 +bc = "zero" +discretization = "gausslegendre_pseudospectral" + +[vperp] +ngrid = 3 +nelement = 3 +L = 3.0 +discretization = "gausslegendre_pseudospectral" # Fokker-Planck operator requires the "gausslegendre_pseudospectral # options for the vpa and vperp grids diff --git a/examples/fokker-planck/fokker-planck-source-sink-slowing-down-alphas-no-self-collisions.toml b/examples/fokker-planck/fokker-planck-source-sink-slowing-down-alphas-no-self-collisions.toml index 1300c4ef9..cff4b6251 100644 --- a/examples/fokker-planck/fokker-planck-source-sink-slowing-down-alphas-no-self-collisions.toml +++ b/examples/fokker-planck/fokker-planck-source-sink-slowing-down-alphas-no-self-collisions.toml @@ -7,26 +7,33 @@ charge_exchange_frequency = 0.0 ionization_frequency = 0.0 constant_ionization_rate = 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 = 32 -vpa_L = 3.0 -vpa_bc = "zero" -vpa_discretization = "gausslegendre_pseudospectral" -vperp_ngrid = 5 -vperp_nelement = 16 -vperp_L = 1.5 -vperp_discretization = "gausslegendre_pseudospectral" -vperp_bc = "zero" +[z] +ngrid = 1 +nelement = 1 +nelement_local = 1 +bc = "wall" +discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 +nelement_local = 1 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 5 +nelement = 32 +L = 3.0 +bc = "zero" +discretization = "gausslegendre_pseudospectral" + +[vperp] +ngrid = 5 +nelement = 16 +L = 1.5 +discretization = "gausslegendre_pseudospectral" +bc = "zero" # Fokker-Planck operator requires the "gausslegendre_pseudospectral # options for the vpa and vperp grids diff --git a/examples/fokker-planck/fokker-planck-source-sink-slowing-down-alphas.toml b/examples/fokker-planck/fokker-planck-source-sink-slowing-down-alphas.toml index 13c56692e..cb9e4e076 100644 --- a/examples/fokker-planck/fokker-planck-source-sink-slowing-down-alphas.toml +++ b/examples/fokker-planck/fokker-planck-source-sink-slowing-down-alphas.toml @@ -7,26 +7,33 @@ charge_exchange_frequency = 0.0 ionization_frequency = 0.0 constant_ionization_rate = 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 = 32 -vpa_L = 3.0 -vpa_bc = "zero" -vpa_discretization = "gausslegendre_pseudospectral" -vperp_ngrid = 5 -vperp_nelement = 16 -vperp_L = 1.5 -vperp_discretization = "gausslegendre_pseudospectral" -vperp_bc = "zero" +[z] +ngrid = 1 +nelement = 1 +nelement_local = 1 +bc = "wall" +discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 +nelement_local = 1 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 5 +nelement = 32 +L = 3.0 +bc = "zero" +discretization = "gausslegendre_pseudospectral" + +[vperp] +ngrid = 5 +nelement = 16 +L = 1.5 +discretization = "gausslegendre_pseudospectral" +bc = "zero" # Fokker-Planck operator requires the "gausslegendre_pseudospectral # options for the vpa and vperp grids diff --git a/examples/geometry/1D-mirror.toml b/examples/geometry/1D-mirror.toml index 4b7a954b1..45ce9ba6d 100644 --- a/examples/geometry/1D-mirror.toml +++ b/examples/geometry/1D-mirror.toml @@ -5,27 +5,37 @@ evolve_moments_conservation = false charge_exchange_frequency = 0.5 ionization_frequency = 0.05 constant_ionization_rate = true -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" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 5 +nelement = 16 +bc = "wall" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 5 +nelement = 16 +L = 6.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" + +[vperp] +ngrid = 5 +nelement = 8 +L = 3.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 9 +nelement = 64 +L = 18.0 +bc = "both_zero" +discretization = "chebyshev_pseudospectral" [composition] n_ion_species = 1 diff --git a/examples/gk-ions/2D-periodic-gk.toml b/examples/gk-ions/2D-periodic-gk.toml index 19659aede..6cffea952 100644 --- a/examples/gk-ions/2D-periodic-gk.toml +++ b/examples/gk-ions/2D-periodic-gk.toml @@ -5,28 +5,38 @@ evolve_moments_conservation = false charge_exchange_frequency = 0.0 ionization_frequency = 0.05 constant_ionization_rate = true -r_ngrid = 5 -r_nelement = 2 -r_bc = "periodic" -z_ngrid = 5 -z_nelement = 2 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 5 -vpa_nelement = 2 -vpa_L = 6.0 -vpa_bc = "zero" -vpa_discretization = "chebyshev_pseudospectral" -vperp_ngrid = 5 -vperp_nelement = 1 -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" + +[r] +ngrid = 5 +nelement = 2 +bc = "periodic" + +[z] +ngrid = 5 +nelement = 2 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 5 +nelement = 2 +L = 6.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" + +[vperp] +ngrid = 5 +nelement = 1 +L = 3.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 9 +nelement = 64 +L = 18.0 +bc = "both_zero" +discretization = "chebyshev_pseudospectral" [composition] n_ion_species = 1 diff --git a/examples/kinetic-electrons/periodic_split3_boltzmann.toml b/examples/kinetic-electrons/periodic_split3_boltzmann.toml index 5ad042d4b..a5105138f 100644 --- a/examples/kinetic-electrons/periodic_split3_boltzmann.toml +++ b/examples/kinetic-electrons/periodic_split3_boltzmann.toml @@ -7,23 +7,31 @@ charge_exchange_frequency = 0.75 ionization_frequency = 0.0 constant_ionization_rate = false nu_ei = 1000.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 17 -z_nelement = 16 -#z_nelement_local = 16 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 6 -vpa_nelement = 31 -vpa_L = 12.0 -vpa_bc = "zero" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 6 -vz_nelement = 31 -vz_L = 12.0 -vz_bc = "zero" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 17 +nelement = 16 +#nelement_local = 16 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 6 +nelement = 31 +L = 12.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 6 +nelement = 31 +L = 12.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" [composition] n_ion_species = 1 @@ -68,7 +76,7 @@ upar_phase = 0.0 temperature_amplitude = 0.0 temperature_phase = 0.0 -[vpa_IC_neutral_species_1] +[vz_IC_neutral_species_1] initialization_option = "gaussian" density_amplitude = 1.0 density_phase = 0.0 diff --git a/examples/kinetic-electrons/periodic_split3_braginskii-IMEX.toml b/examples/kinetic-electrons/periodic_split3_braginskii-IMEX.toml index f359c859d..b2655403b 100644 --- a/examples/kinetic-electrons/periodic_split3_braginskii-IMEX.toml +++ b/examples/kinetic-electrons/periodic_split3_braginskii-IMEX.toml @@ -7,23 +7,31 @@ charge_exchange_frequency = 0.75 ionization_frequency = 0.0 constant_ionization_rate = false nu_ei = 1000.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 17 -z_nelement = 16 -#z_nelement_local = 16 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 6 -vpa_nelement = 31 -vpa_L = 12.0 -vpa_bc = "zero" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 6 -vz_nelement = 31 -vz_L = 12.0 -vz_bc = "zero" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 17 +nelement = 16 +#nelement_local = 16 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 6 +nelement = 31 +L = 12.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 6 +nelement = 31 +L = 12.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" [composition] n_ion_species = 1 @@ -68,7 +76,7 @@ upar_phase = 0.0 temperature_amplitude = 0.0 temperature_phase = 0.0 -[vpa_IC_neutral_species_1] +[vz_IC_neutral_species_1] initialization_option = "gaussian" density_amplitude = 1.0 density_phase = 0.0 diff --git a/examples/kinetic-electrons/periodic_split3_braginskii.toml b/examples/kinetic-electrons/periodic_split3_braginskii.toml index 6f5c8d737..b3b971397 100644 --- a/examples/kinetic-electrons/periodic_split3_braginskii.toml +++ b/examples/kinetic-electrons/periodic_split3_braginskii.toml @@ -7,23 +7,31 @@ charge_exchange_frequency = 0.75 ionization_frequency = 0.0 constant_ionization_rate = false nu_ei = 1000.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 17 -z_nelement = 16 -#z_nelement_local = 16 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 6 -vpa_nelement = 31 -vpa_L = 12.0 -vpa_bc = "zero" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 6 -vz_nelement = 31 -vz_L = 12.0 -vz_bc = "zero" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 17 +nelement = 16 +#nelement_local = 16 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 6 +nelement = 31 +L = 12.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 6 +nelement = 31 +L = 12.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" [composition] n_ion_species = 1 @@ -68,7 +76,7 @@ upar_phase = 0.0 temperature_amplitude = 0.0 temperature_phase = 0.0 -[vpa_IC_neutral_species_1] +[vz_IC_neutral_species_1] initialization_option = "gaussian" density_amplitude = 1.0 density_phase = 0.0 diff --git a/examples/kinetic-electrons/periodic_split3_kinetic-IMEX.toml b/examples/kinetic-electrons/periodic_split3_kinetic-IMEX.toml index e5a02086f..268f52889 100644 --- a/examples/kinetic-electrons/periodic_split3_kinetic-IMEX.toml +++ b/examples/kinetic-electrons/periodic_split3_kinetic-IMEX.toml @@ -7,23 +7,31 @@ charge_exchange_frequency = 0.75 ionization_frequency = 0.0 constant_ionization_rate = false nu_ei = 1000.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 17 -z_nelement = 16 -#z_nelement_local = 16 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 6 -vpa_nelement = 31 -vpa_L = 12.0 -vpa_bc = "zero" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 6 -vz_nelement = 31 -vz_L = 12.0 -vz_bc = "zero" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 17 +nelement = 16 +#nelement_local = 16 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 6 +nelement = 31 +L = 12.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 6 +nelement = 31 +L = 12.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" [composition] n_ion_species = 1 @@ -68,7 +76,7 @@ upar_phase = 0.0 temperature_amplitude = 0.0 temperature_phase = 0.0 -[vpa_IC_neutral_species_1] +[vz_IC_neutral_species_1] initialization_option = "gaussian" density_amplitude = 1.0 density_phase = 0.0 diff --git a/examples/kinetic-electrons/periodic_split3_kinetic.toml b/examples/kinetic-electrons/periodic_split3_kinetic.toml index d4a1140d0..465de6619 100644 --- a/examples/kinetic-electrons/periodic_split3_kinetic.toml +++ b/examples/kinetic-electrons/periodic_split3_kinetic.toml @@ -7,23 +7,31 @@ charge_exchange_frequency = 0.75 ionization_frequency = 0.0 constant_ionization_rate = false nu_ei = 1000.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 17 -z_nelement = 16 -#z_nelement_local = 16 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 6 -vpa_nelement = 31 -vpa_L = 12.0 -vpa_bc = "zero" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 6 -vz_nelement = 31 -vz_L = 12.0 -vz_bc = "zero" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 17 +nelement = 16 +#nelement_local = 16 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 6 +nelement = 31 +L = 12.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 6 +nelement = 31 +L = 12.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" [composition] n_ion_species = 1 @@ -68,7 +76,7 @@ upar_phase = 0.0 temperature_amplitude = 0.0 temperature_phase = 0.0 -[vpa_IC_neutral_species_1] +[vz_IC_neutral_species_1] initialization_option = "gaussian" density_amplitude = 1.0 density_phase = 0.0 diff --git a/examples/kinetic-electrons/periodic_split3_kinetic_high-collisionality.toml b/examples/kinetic-electrons/periodic_split3_kinetic_high-collisionality.toml index a0c44f500..d94684ba1 100644 --- a/examples/kinetic-electrons/periodic_split3_kinetic_high-collisionality.toml +++ b/examples/kinetic-electrons/periodic_split3_kinetic_high-collisionality.toml @@ -7,23 +7,31 @@ charge_exchange_frequency = 0.75 ionization_frequency = 0.0 constant_ionization_rate = false nu_ei = 1000.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 17 -z_nelement = 16 -#z_nelement_local = 16 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 6 -vpa_nelement = 31 -vpa_L = 12.0 -vpa_bc = "zero" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 6 -vz_nelement = 31 -vz_L = 12.0 -vz_bc = "zero" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 17 +nelement = 16 +#nelement_local = 16 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 6 +nelement = 31 +L = 12.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 6 +nelement = 31 +L = 12.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" [composition] n_ion_species = 1 @@ -68,7 +76,7 @@ upar_phase = 0.0 temperature_amplitude = 0.0 temperature_phase = 0.0 -[vpa_IC_neutral_species_1] +[vz_IC_neutral_species_1] initialization_option = "gaussian" density_amplitude = 1.0 density_phase = 0.0 diff --git a/examples/kinetic-electrons/wall+sheath-bc_boltzmann_loworder.toml b/examples/kinetic-electrons/wall+sheath-bc_boltzmann_loworder.toml index cb1b24116..727121f5b 100644 --- a/examples/kinetic-electrons/wall+sheath-bc_boltzmann_loworder.toml +++ b/examples/kinetic-electrons/wall+sheath-bc_boltzmann_loworder.toml @@ -11,27 +11,35 @@ ionization_frequency = 2.0 #electron_ionization_frequency = 2.0 #ionization_energy = 1.0 constant_ionization_rate = false -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 5 -#z_nelement = 32 -z_nelement = 64 -#z_nelement = 128 -z_bc = "wall" -z_discretization = "chebyshev_pseudospectral" -z_spacing_option = "sqrt" -vpa_ngrid = 5 -#vpa_nelement = 40 -vpa_nelement = 80 -vpa_L = 12.0 #8.0 -vpa_bc = "zero" -vpa_discretization = "chebyshev_pseudospectral" -#vpa_discretization = "gausslegendre_pseudospectral" -vz_ngrid = 5 -vz_nelement = 80 -vz_L = 12.0 -vz_bc = "zero" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 5 +#nelement = 32 +nelement = 64 +#nelement = 128 +bc = "wall" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "sqrt" + +[vpa] +ngrid = 5 +#nelement = 40 +nelement = 80 +L = 12.0 #8.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" +#discretization = "gausslegendre_pseudospectral" + +[vz] +ngrid = 5 +nelement = 80 +L = 12.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" [composition] n_ion_species = 1 @@ -75,7 +83,7 @@ upar_phase = 0.0 temperature_amplitude = 0.0 temperature_phase = 0.0 -[vpa_IC_neutral_species_1] +[vz_IC_neutral_species_1] initialization_option = "gaussian" density_amplitude = 1.0 density_phase = 0.0 diff --git a/examples/kinetic-electrons/wall+sheath-bc_kinetic.toml b/examples/kinetic-electrons/wall+sheath-bc_kinetic.toml index 8136e86d0..66da6581b 100644 --- a/examples/kinetic-electrons/wall+sheath-bc_kinetic.toml +++ b/examples/kinetic-electrons/wall+sheath-bc_kinetic.toml @@ -9,28 +9,36 @@ ionization_frequency = 2.0 electron_ionization_frequency = 2.0 ionization_energy = 1.0 constant_ionization_rate = false -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 9 -#z_nelement = 16 -z_nelement = 32 -#z_nelement = 64 -z_bc = "wall" -z_discretization = "chebyshev_pseudospectral" -z_spacing_option = "sqrt" -vpa_ngrid = 17 -#vpa_nelement = 10 -vpa_nelement = 20 -vpa_L = 12.0 #8.0 -vpa_bc = "zero" -vpa_discretization = "chebyshev_pseudospectral" -#vpa_discretization = "gausslegendre_pseudospectral" -vz_ngrid = 17 -#vz_nelement = 10 -vz_nelement = 20 -vz_L = 8.0 -vz_bc = "zero" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 9 +#nelement = 16 +nelement = 32 +#nelement = 64 +bc = "wall" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "sqrt" + +[vpa] +ngrid = 17 +#nelement = 10 +nelement = 20 +L = 12.0 #8.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" +#discretization = "gausslegendre_pseudospectral" + +[vz] +ngrid = 17 +#nelement = 10 +nelement = 20 +L = 8.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" [composition] n_ion_species = 1 @@ -74,7 +82,7 @@ upar_phase = 0.0 temperature_amplitude = 0.0 temperature_phase = 0.0 -[vpa_IC_neutral_species_1] +[vz_IC_neutral_species_1] initialization_option = "gaussian" density_amplitude = 1.0 density_phase = 0.0 diff --git a/examples/kinetic-electrons/wall+sheath-bc_kinetic_krook_loworder.toml b/examples/kinetic-electrons/wall+sheath-bc_kinetic_krook_loworder.toml index f932d0357..06b996e56 100644 --- a/examples/kinetic-electrons/wall+sheath-bc_kinetic_krook_loworder.toml +++ b/examples/kinetic-electrons/wall+sheath-bc_kinetic_krook_loworder.toml @@ -9,27 +9,35 @@ ionization_frequency = 2.0 electron_ionization_frequency = 2.0 ionization_energy = 1.0 constant_ionization_rate = false -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 5 -#z_nelement = 32 -z_nelement = 64 -#z_nelement = 128 -z_bc = "wall" -z_discretization = "chebyshev_pseudospectral" -z_spacing_option = "sqrt" -vpa_ngrid = 5 -#vpa_nelement = 40 -vpa_nelement = 80 -vpa_L = 12.0 #8.0 -vpa_bc = "zero" -vpa_discretization = "chebyshev_pseudospectral" -#vpa_discretization = "gausslegendre_pseudospectral" -vz_ngrid = 17 -vz_nelement = 10 -vz_L = 8.0 -vz_bc = "zero" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 5 +#nelement = 32 +nelement = 64 +#nelement = 128 +bc = "wall" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "sqrt" + +[vpa] +ngrid = 5 +#nelement = 40 +nelement = 80 +L = 12.0 #8.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" +#discretization = "gausslegendre_pseudospectral" + +[vz] +ngrid = 17 +nelement = 10 +L = 8.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" [composition] n_ion_species = 1 @@ -73,7 +81,7 @@ upar_phase = 0.0 temperature_amplitude = 0.0 temperature_phase = 0.0 -[vpa_IC_neutral_species_1] +[vz_IC_neutral_species_1] initialization_option = "gaussian" density_amplitude = 1.0 density_phase = 0.0 diff --git a/examples/kinetic-electrons/wall+sheath-bc_kinetic_loworder.toml b/examples/kinetic-electrons/wall+sheath-bc_kinetic_loworder.toml index 1b8ca705d..d481945bd 100644 --- a/examples/kinetic-electrons/wall+sheath-bc_kinetic_loworder.toml +++ b/examples/kinetic-electrons/wall+sheath-bc_kinetic_loworder.toml @@ -11,27 +11,35 @@ ionization_frequency = 2.0 #electron_ionization_frequency = 2.0 #ionization_energy = 1.0 constant_ionization_rate = false -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 5 -#z_nelement = 32 -z_nelement = 64 -#z_nelement = 128 -z_bc = "wall" -z_discretization = "chebyshev_pseudospectral" -z_spacing_option = "sqrt" -vpa_ngrid = 5 -#vpa_nelement = 40 -vpa_nelement = 80 -vpa_L = 12.0 #8.0 -vpa_bc = "zero" -vpa_discretization = "chebyshev_pseudospectral" -#vpa_discretization = "gausslegendre_pseudospectral" -vz_ngrid = 5 -vz_nelement = 80 -vz_L = 12.0 -vz_bc = "zero" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 5 +#nelement = 32 +nelement = 64 +#nelement = 128 +bc = "wall" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "sqrt" + +[vpa] +ngrid = 5 +#nelement = 40 +nelement = 80 +L = 12.0 #8.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" +#discretization = "gausslegendre_pseudospectral" + +[vz] +ngrid = 5 +nelement = 80 +L = 12.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" [composition] n_ion_species = 1 @@ -75,7 +83,7 @@ upar_phase = 0.0 temperature_amplitude = 0.0 temperature_phase = 0.0 -[vpa_IC_neutral_species_1] +[vz_IC_neutral_species_1] initialization_option = "gaussian" density_amplitude = 1.0 density_phase = 0.0 diff --git a/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_braginskii-vpadiss0-IMEX.toml b/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_braginskii-vpadiss0-IMEX.toml index d0ab7a225..50759a94c 100644 --- a/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_braginskii-vpadiss0-IMEX.toml +++ b/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_braginskii-vpadiss0-IMEX.toml @@ -7,24 +7,32 @@ charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false nu_ei = 1000.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 5 -z_nelement = 32 -#z_nelement_local = 16 -z_bc = "wall" -z_discretization = "chebyshev_pseudospectral" -z_element_spacing_option = "sqrt" -vpa_ngrid = 6 -vpa_nelement = 63 -vpa_L = 36.0 -vpa_bc = "zero" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 6 -vz_nelement = 63 -vz_L = 36.0 -vz_bc = "zero" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 5 +nelement = 32 +#nelement_local = 16 +bc = "wall" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "sqrt" + +[vpa] +ngrid = 6 +nelement = 63 +L = 36.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 6 +nelement = 63 +L = 36.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" [composition] n_ion_species = 1 @@ -69,7 +77,7 @@ upar_phase = 0.0 temperature_amplitude = 0.0 temperature_phase = 0.0 -[vpa_IC_neutral_species_1] +[vz_IC_neutral_species_1] initialization_option = "gaussian" density_amplitude = 1.0 density_phase = 0.0 diff --git a/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_kinetic-vpadiss0.toml b/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_kinetic-vpadiss0.toml index 1fb3f2874..3776a0287 100644 --- a/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_kinetic-vpadiss0.toml +++ b/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_kinetic-vpadiss0.toml @@ -6,24 +6,32 @@ evolve_moments_conservation = true charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 5 -z_nelement = 32 -#z_nelement_local = 16 -z_bc = "wall" -z_discretization = "chebyshev_pseudospectral" -z_element_spacing_option = "sqrt" -vpa_ngrid = 6 -vpa_nelement = 63 -vpa_L = 48.0 -vpa_bc = "zero" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 6 -vz_nelement = 63 -vz_L = 36.0 -vz_bc = "zero" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 5 +nelement = 32 +#nelement_local = 16 +bc = "wall" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "sqrt" + +[vpa] +ngrid = 6 +nelement = 63 +L = 48.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 6 +nelement = 63 +L = 36.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" [composition] n_ion_species = 1 @@ -68,7 +76,7 @@ upar_phase = 0.0 temperature_amplitude = 0.0 temperature_phase = 0.0 -[vpa_IC_neutral_species_1] +[vz_IC_neutral_species_1] initialization_option = "gaussian" density_amplitude = 1.0 density_phase = 0.0 diff --git a/examples/nonlinear-sound-wave/nonlinear-sound-wave_cheb_split1.toml b/examples/nonlinear-sound-wave/nonlinear-sound-wave_cheb_split1.toml index c8178024f..167a8611b 100644 --- a/examples/nonlinear-sound-wave/nonlinear-sound-wave_cheb_split1.toml +++ b/examples/nonlinear-sound-wave/nonlinear-sound-wave_cheb_split1.toml @@ -4,17 +4,30 @@ evolve_moments_parallel_pressure = false evolve_moments_conservation = true charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 9 -z_nelement = 2 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 8 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 9 +nelement = 2 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 17 +nelement = 8 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 17 +nelement = 8 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" [composition] n_ion_species = 1 diff --git a/examples/nonlinear-sound-wave/nonlinear-sound-wave_cheb_split2.toml b/examples/nonlinear-sound-wave/nonlinear-sound-wave_cheb_split2.toml index 46326e0f4..99e9ec127 100644 --- a/examples/nonlinear-sound-wave/nonlinear-sound-wave_cheb_split2.toml +++ b/examples/nonlinear-sound-wave/nonlinear-sound-wave_cheb_split2.toml @@ -4,17 +4,30 @@ evolve_moments_parallel_pressure = false evolve_moments_conservation = true charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 9 -z_nelement = 2 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 8 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 9 +nelement = 2 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 17 +nelement = 8 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 17 +nelement = 8 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" [composition] n_ion_species = 1 diff --git a/examples/nonlinear-sound-wave/nonlinear-sound-wave_cheb_split3.toml b/examples/nonlinear-sound-wave/nonlinear-sound-wave_cheb_split3.toml index fed5d3635..65ce1cb0f 100644 --- a/examples/nonlinear-sound-wave/nonlinear-sound-wave_cheb_split3.toml +++ b/examples/nonlinear-sound-wave/nonlinear-sound-wave_cheb_split3.toml @@ -4,17 +4,30 @@ evolve_moments_parallel_pressure = true evolve_moments_conservation = true charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 9 -z_nelement = 2 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 8 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 9 +nelement = 2 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 17 +nelement = 8 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 17 +nelement = 8 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" [composition] n_ion_species = 1 diff --git a/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd.toml b/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd.toml index 2d15df95f..2994d865d 100644 --- a/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd.toml +++ b/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd.toml @@ -4,17 +4,30 @@ evolve_moments_parallel_pressure = false evolve_moments_conservation = true charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 100 -z_nelement = 1 -z_bc = "periodic" -z_discretization = "finite_difference" -vpa_ngrid = 400 -vpa_nelement = 1 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "finite_difference" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 100 +nelement = 1 +bc = "periodic" +discretization = "finite_difference" + +[vpa] +ngrid = 400 +nelement = 1 +L = 8.0 +bc = "periodic" +discretization = "finite_difference" + +[vz] +ngrid = 400 +nelement = 1 +L = 8.0 +bc = "periodic" +discretization = "finite_difference" [composition] n_ion_species = 1 diff --git a/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd_split1.toml b/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd_split1.toml index 0de21547e..0f060b8ef 100644 --- a/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd_split1.toml +++ b/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd_split1.toml @@ -4,17 +4,30 @@ evolve_moments_parallel_pressure = false evolve_moments_conservation = true charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 100 -z_nelement = 1 -z_bc = "periodic" -z_discretization = "finite_difference" -vpa_ngrid = 400 -vpa_nelement = 1 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "finite_difference" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 100 +nelement = 1 +bc = "periodic" +discretization = "finite_difference" + +[vpa] +ngrid = 400 +nelement = 1 +L = 8.0 +bc = "periodic" +discretization = "finite_difference" + +[vz] +ngrid = 400 +nelement = 1 +L = 8.0 +bc = "periodic" +discretization = "finite_difference" [composition] n_ion_species = 1 diff --git a/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd_split2.toml b/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd_split2.toml index a5322c378..a22fa0eee 100644 --- a/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd_split2.toml +++ b/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd_split2.toml @@ -4,17 +4,30 @@ evolve_moments_parallel_pressure = false evolve_moments_conservation = true charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 100 -z_nelement = 1 -z_bc = "periodic" -z_discretization = "finite_difference" -vpa_ngrid = 400 -vpa_nelement = 1 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "finite_difference" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 100 +nelement = 1 +bc = "periodic" +discretization = "finite_difference" + +[vpa] +ngrid = 400 +nelement = 1 +L = 8.0 +bc = "periodic" +discretization = "finite_difference" + +[vz] +ngrid = 400 +nelement = 1 +L = 8.0 +bc = "periodic" +discretization = "finite_difference" [composition] n_ion_species = 1 diff --git a/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd_split3.toml b/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd_split3.toml index b17c8ff55..ab4fa6715 100644 --- a/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd_split3.toml +++ b/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd_split3.toml @@ -4,17 +4,30 @@ evolve_moments_parallel_pressure = true evolve_moments_conservation = true charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 100 -z_nelement = 1 -z_bc = "periodic" -z_discretization = "finite_difference" -vpa_ngrid = 400 -vpa_nelement = 1 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "finite_difference" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 100 +nelement = 1 +bc = "periodic" +discretization = "finite_difference" + +[vpa] +ngrid = 400 +nelement = 1 +L = 8.0 +bc = "periodic" +discretization = "finite_difference" + +[vz] +ngrid = 400 +nelement = 1 +L = 8.0 +bc = "periodic" +discretization = "finite_difference" [composition] n_ion_species = 1 diff --git a/examples/numerical-dissipation/num-diss-relaxation.toml b/examples/numerical-dissipation/num-diss-relaxation.toml index 3b9e46fe5..2486495dd 100644 --- a/examples/numerical-dissipation/num-diss-relaxation.toml +++ b/examples/numerical-dissipation/num-diss-relaxation.toml @@ -7,26 +7,34 @@ charge_exchange_frequency = 0.0 ionization_frequency = 0.0 constant_ionization_rate = false nuii = 0.0 -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 = 16 -vpa_L = 6.0 -vpa_bc = "zero" -vpa_discretization = "gausslegendre_pseudospectral" -vperp_ngrid = 5 -vperp_nelement = 8 -vperp_L = 3.0 -vperp_bc = "zero" -vperp_discretization = "gausslegendre_pseudospectral" + +[z] +ngrid = 1 +nelement = 1 +nelement_local = 1 +bc = "wall" +discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 +nelement_local = 1 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 5 +nelement = 16 +L = 6.0 +bc = "zero" +discretization = "gausslegendre_pseudospectral" + +[vperp] +ngrid = 5 +nelement = 8 +L = 3.0 +bc = "zero" +discretization = "gausslegendre_pseudospectral" [composition] n_ion_species = 1 diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5-init.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5-init.toml index 037890334..ffbca9ebd 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5-init.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5-init.toml @@ -5,26 +5,34 @@ evolve_moments_conservation = false charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 5 -z_nelement = 32 -z_nelement_local = 16 -z_bc = "wall" -z_discretization = "chebyshev_pseudospectral" -z_element_spacing_option = "sqrt" -vpa_ngrid = 6 -vpa_nelement = 63 -vpa_L = 36.0 -vpa_bc = "zero" -vpa_discretization = "chebyshev_pseudospectral" -vpa_element_spacing_option = "coarse_tails" -vz_ngrid = 6 -vz_nelement = 63 -vz_L = 36.0 -vz_bc = "zero" -vz_discretization = "chebyshev_pseudospectral" -vz_element_spacing_option = "coarse_tails" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 5 +nelement = 32 +nelement_local = 16 +bc = "wall" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "sqrt" + +[vpa] +ngrid = 6 +nelement = 63 +L = 36.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "coarse_tails" + +[vz] +ngrid = 6 +nelement = 63 +L = 36.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "coarse_tails" [composition] n_ion_species = 1 @@ -68,7 +76,7 @@ upar_phase = 0.0 temperature_amplitude = 0.0 temperature_phase = 0.0 -[vpa_IC_neutral_species_1] +[vz_IC_neutral_species_1] initialization_option = "gaussian" density_amplitude = 1.0 density_phase = 0.0 diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5.toml index aff3860ba..4e3511752 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5.toml @@ -5,26 +5,34 @@ evolve_moments_conservation = false charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 9 -z_nelement = 32 -z_nelement_local = 16 -z_bc = "wall" -z_discretization = "chebyshev_pseudospectral" -z_element_spacing_option = "sqrt" -vpa_ngrid = 10 -vpa_nelement = 63 -vpa_L = 36.0 -vpa_bc = "zero" -vpa_discretization = "chebyshev_pseudospectral" -vpa_element_spacing_option = "coarse_tails" -vz_ngrid = 10 -vz_nelement = 63 -vz_L = 36.0 -vz_bc = "zero" -vz_discretization = "chebyshev_pseudospectral" -vz_element_spacing_option = "coarse_tails" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 9 +nelement = 32 +nelement_local = 16 +bc = "wall" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "sqrt" + +[vpa] +ngrid = 10 +nelement = 63 +L = 36.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "coarse_tails" + +[vz] +ngrid = 10 +nelement = 63 +L = 36.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "coarse_tails" [composition] n_ion_species = 1 @@ -68,7 +76,7 @@ upar_phase = 0.0 temperature_amplitude = 0.0 temperature_phase = 0.0 -[vpa_IC_neutral_species_1] +[vz_IC_neutral_species_1] initialization_option = "gaussian" density_amplitude = 1.0 density_phase = 0.0 diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split1.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split1.toml index db1f3d37d..881adbc94 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split1.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split1.toml @@ -5,26 +5,34 @@ evolve_moments_conservation = true charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 9 -z_nelement = 32 -z_nelement_local = 16 -z_bc = "wall" -z_discretization = "chebyshev_pseudospectral" -z_element_spacing_option = "sqrt" -vpa_ngrid = 10 -vpa_nelement = 63 -vpa_L = 36.0 -vpa_bc = "zero" -vpa_discretization = "chebyshev_pseudospectral" -vpa_element_spacing_option = "coarse_tails" -vz_ngrid = 10 -vz_nelement = 63 -vz_L = 36.0 -vz_bc = "zero" -vz_discretization = "chebyshev_pseudospectral" -vz_element_spacing_option = "coarse_tails" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 9 +nelement = 32 +nelement_local = 16 +bc = "wall" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "sqrt" + +[vpa] +ngrid = 10 +nelement = 63 +L = 36.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "coarse_tails" + +[vz] +ngrid = 10 +nelement = 63 +L = 36.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "coarse_tails" [composition] n_ion_species = 1 @@ -68,7 +76,7 @@ upar_phase = 0.0 temperature_amplitude = 0.0 temperature_phase = 0.0 -[vpa_IC_neutral_species_1] +[vz_IC_neutral_species_1] initialization_option = "gaussian" density_amplitude = 1.0 density_phase = 0.0 diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split2.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split2.toml index 74ab5a029..d6b120767 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split2.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split2.toml @@ -5,26 +5,34 @@ evolve_moments_conservation = true charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 9 -z_nelement = 32 -z_nelement_local = 16 -z_bc = "wall" -z_discretization = "chebyshev_pseudospectral" -z_element_spacing_option = "sqrt" -vpa_ngrid = 10 -vpa_nelement = 63 -vpa_L = 36.0 -vpa_bc = "zero" -vpa_discretization = "chebyshev_pseudospectral" -vpa_element_spacing_option = "coarse_tails" -vz_ngrid = 10 -vz_nelement = 63 -vz_L = 36.0 -vz_bc = "zero" -vz_discretization = "chebyshev_pseudospectral" -vz_element_spacing_option = "coarse_tails" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 9 +nelement = 32 +nelement_local = 16 +bc = "wall" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "sqrt" + +[vpa] +ngrid = 10 +nelement = 63 +L = 36.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "coarse_tails" + +[vz] +ngrid = 10 +nelement = 63 +L = 36.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "coarse_tails" [composition] n_ion_species = 1 @@ -69,7 +77,7 @@ upar_phase = 0.0 temperature_amplitude = 0.0 temperature_phase = 0.0 -[vpa_IC_neutral_species_1] +[vz_IC_neutral_species_1] initialization_option= "gaussian" density_amplitude = 1.0 density_phase = 0.0 diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3-init.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3-init.toml index 3e5dbdd9d..a442890df 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3-init.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3-init.toml @@ -5,26 +5,34 @@ evolve_moments_conservation = true charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 5 -z_nelement = 32 -z_nelement_local = 16 -z_bc = "wall" -z_discretization = "chebyshev_pseudospectral" -z_element_spacing_option = "sqrt" -vpa_ngrid = 6 -vpa_nelement = 63 -vpa_L = 36.0 -vpa_bc = "zero" -vpa_discretization = "chebyshev_pseudospectral" -vpa_element_spacing_option = "coarse_tails" -vz_ngrid = 6 -vz_nelement = 63 -vz_L = 36.0 -vz_bc = "zero" -vz_discretization = "chebyshev_pseudospectral" -vz_element_spacing_option = "coarse_tails" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 5 +nelement = 32 +nelement_local = 16 +bc = "wall" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "sqrt" + +[vpa] +ngrid = 6 +nelement = 63 +L = 36.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "coarse_tails" + +[vz] +ngrid = 6 +nelement = 63 +L = 36.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "coarse_tails" [composition] n_ion_species = 1 @@ -69,7 +77,7 @@ upar_phase = 0.0 temperature_amplitude = 0.0 temperature_phase = 0.0 -[vpa_IC_neutral_species_1] +[vz_IC_neutral_species_1] initialization_option= "gaussian" density_amplitude = 1.0 density_phase = 0.0 diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3.toml index 1dbb9b4ea..2d81d4845 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3.toml @@ -5,26 +5,34 @@ evolve_moments_conservation = true charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 9 -z_nelement = 32 -z_nelement_local = 16 -z_bc = "wall" -z_discretization = "chebyshev_pseudospectral" -z_element_spacing_option = "sqrt" -vpa_ngrid = 10 -vpa_nelement = 63 -vpa_L = 36.0 -vpa_bc = "zero" -vpa_discretization = "chebyshev_pseudospectral" -vpa_element_spacing_option = "coarse_tails" -vz_ngrid = 10 -vz_nelement = 63 -vz_L = 36.0 -vz_bc = "zero" -vz_discretization = "chebyshev_pseudospectral" -vz_element_spacing_option = "coarse_tails" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 9 +nelement = 32 +nelement_local = 16 +bc = "wall" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "sqrt" + +[vpa] +ngrid = 10 +nelement = 63 +L = 36.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "coarse_tails" + +[vz] +ngrid = 10 +nelement = 63 +L = 36.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "coarse_tails" [composition] n_ion_species = 1 @@ -69,7 +77,7 @@ upar_phase = 0.0 temperature_amplitude = 0.0 temperature_phase = 0.0 -[vpa_IC_neutral_species_1] +[vz_IC_neutral_species_1] initialization_option= "gaussian" density_amplitude = 1.0 density_phase = 0.0 diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_SSPRK4.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_SSPRK4.toml index 7440dac74..4e0065cae 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_SSPRK4.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_SSPRK4.toml @@ -5,26 +5,34 @@ evolve_moments_conservation = true charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 9 -z_nelement = 32 -z_nelement_local = 16 -z_bc = "wall" -z_discretization = "chebyshev_pseudospectral" -z_element_spacing_option = "sqrt" -vpa_ngrid = 10 -vpa_nelement = 63 -vpa_L = 36.0 -vpa_bc = "zero" -vpa_discretization = "chebyshev_pseudospectral" -vpa_element_spacing_option = "coarse_tails" -vz_ngrid = 10 -vz_nelement = 63 -vz_L = 36.0 -vz_bc = "zero" -vz_discretization = "chebyshev_pseudospectral" -vz_element_spacing_option = "coarse_tails" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 9 +nelement = 32 +nelement_local = 16 +bc = "wall" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "sqrt" + +[vpa] +ngrid = 10 +nelement = 63 +L = 36.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "coarse_tails" + +[vz] +ngrid = 10 +nelement = 63 +L = 36.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "coarse_tails" [composition] n_ion_species = 1 @@ -68,7 +76,7 @@ upar_phase = 0.0 temperature_amplitude = 0.0 temperature_phase = 0.0 -[vpa_IC_neutral_species_1] +[vz_IC_neutral_species_1] initialization_option = "gaussian" density_amplitude = 1.0 density_phase = 0.0 diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete104.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete104.toml index 71d776507..f41ff30b8 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete104.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete104.toml @@ -6,26 +6,34 @@ evolve_moments_conservation = true charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 9 -z_nelement = 32 -z_nelement_local = 16 -z_bc = "wall" -z_discretization = "chebyshev_pseudospectral" -z_element_spacing_option = "sqrt" -vpa_ngrid = 10 -vpa_nelement = 63 -vpa_L = 36.0 -vpa_bc = "zero" -vpa_discretization = "chebyshev_pseudospectral" -vpa_element_spacing_option = "coarse_tails" -vz_ngrid = 10 -vz_nelement = 63 -vz_L = 36.0 -vz_bc = "zero" -vz_discretization = "chebyshev_pseudospectral" -vz_element_spacing_option = "coarse_tails" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 9 +nelement = 32 +nelement_local = 16 +bc = "wall" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "sqrt" + +[vpa] +ngrid = 10 +nelement = 63 +L = 36.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "coarse_tails" + +[vz] +ngrid = 10 +nelement = 63 +L = 36.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "coarse_tails" [composition] n_ion_species = 1 @@ -70,7 +78,7 @@ upar_phase = 0.0 temperature_amplitude = 0.0 temperature_phase = 0.0 -[vpa_IC_neutral_species_1] +[vz_IC_neutral_species_1] initialization_option= "gaussian" density_amplitude = 1.0 density_phase = 0.0 diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete42.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete42.toml index 3cd67baeb..dd17b2e45 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete42.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete42.toml @@ -6,26 +6,34 @@ evolve_moments_conservation = true charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 9 -z_nelement = 32 -z_nelement_local = 16 -z_bc = "wall" -z_discretization = "chebyshev_pseudospectral" -z_element_spacing_option = "sqrt" -vpa_ngrid = 10 -vpa_nelement = 63 -vpa_L = 36.0 -vpa_bc = "zero" -vpa_discretization = "chebyshev_pseudospectral" -vpa_element_spacing_option = "coarse_tails" -vz_ngrid = 10 -vz_nelement = 63 -vz_L = 36.0 -vz_bc = "zero" -vz_discretization = "chebyshev_pseudospectral" -vz_element_spacing_option = "coarse_tails" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 9 +nelement = 32 +nelement_local = 16 +bc = "wall" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "sqrt" + +[vpa] +ngrid = 10 +nelement = 63 +L = 36.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "coarse_tails" + +[vz] +ngrid = 10 +nelement = 63 +L = 36.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "coarse_tails" [composition] n_ion_species = 1 @@ -70,7 +78,7 @@ upar_phase = 0.0 temperature_amplitude = 0.0 temperature_phase = 0.0 -[vpa_IC_neutral_species_1] +[vz_IC_neutral_species_1] initialization_option= "gaussian" density_amplitude = 1.0 density_phase = 0.0 diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete64.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete64.toml index f8354d268..7776446b2 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete64.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete64.toml @@ -6,26 +6,34 @@ evolve_moments_conservation = true charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 9 -z_nelement = 32 -z_nelement_local = 16 -z_bc = "wall" -z_discretization = "chebyshev_pseudospectral" -z_element_spacing_option = "sqrt" -vpa_ngrid = 10 -vpa_nelement = 63 -vpa_L = 36.0 -vpa_bc = "zero" -vpa_discretization = "chebyshev_pseudospectral" -vpa_element_spacing_option = "coarse_tails" -vz_ngrid = 10 -vz_nelement = 63 -vz_L = 36.0 -vz_bc = "zero" -vz_discretization = "chebyshev_pseudospectral" -vz_element_spacing_option = "coarse_tails" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 9 +nelement = 32 +nelement_local = 16 +bc = "wall" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "sqrt" + +[vpa] +ngrid = 10 +nelement = 63 +L = 36.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "coarse_tails" + +[vz] +ngrid = 10 +nelement = 63 +L = 36.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "coarse_tails" [composition] n_ion_species = 1 @@ -70,7 +78,7 @@ upar_phase = 0.0 temperature_amplitude = 0.0 temperature_phase = 0.0 -[vpa_IC_neutral_species_1] +[vz_IC_neutral_species_1] initialization_option= "gaussian" density_amplitude = 1.0 density_phase = 0.0 diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_rkf54.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_rkf54.toml index 52aeb9d2a..3502216ec 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_rkf54.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_rkf54.toml @@ -6,26 +6,34 @@ evolve_moments_conservation = true charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 9 -z_nelement = 32 -z_nelement_local = 16 -z_bc = "wall" -z_discretization = "chebyshev_pseudospectral" -z_element_spacing_option = "sqrt" -vpa_ngrid = 10 -vpa_nelement = 63 -vpa_L = 36.0 -vpa_bc = "zero" -vpa_discretization = "chebyshev_pseudospectral" -vpa_element_spacing_option = "coarse_tails" -vz_ngrid = 10 -vz_nelement = 63 -vz_L = 36.0 -vz_bc = "zero" -vz_discretization = "chebyshev_pseudospectral" -vz_element_spacing_option = "coarse_tails" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 9 +nelement = 32 +nelement_local = 16 +bc = "wall" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "sqrt" + +[vpa] +ngrid = 10 +nelement = 63 +L = 36.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "coarse_tails" + +[vz] +ngrid = 10 +nelement = 63 +L = 36.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "coarse_tails" [composition] n_ion_species = 1 @@ -70,7 +78,7 @@ upar_phase = 0.0 temperature_amplitude = 0.0 temperature_phase = 0.0 -[vpa_IC_neutral_species_1] +[vz_IC_neutral_species_1] initialization_option= "gaussian" density_amplitude = 1.0 density_phase = 0.0 diff --git a/examples/sheath+wall-bc_test/sheath-bc_cheb_test.toml b/examples/sheath+wall-bc_test/sheath-bc_cheb_test.toml index 4bb5e56a1..bc223dcdb 100644 --- a/examples/sheath+wall-bc_test/sheath-bc_cheb_test.toml +++ b/examples/sheath+wall-bc_test/sheath-bc_cheb_test.toml @@ -5,17 +5,30 @@ evolve_moments_conservation = false charge_exchange_frequency = 2.0 ionization_frequency = 2.0 constant_ionization_rate = false -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 9 -z_nelement = 2 -z_bc = "wall" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 10 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 9 +nelement = 2 +bc = "wall" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 17 +nelement = 10 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 17 +nelement = 10 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" [composition] n_ion_species = 1 @@ -60,7 +73,7 @@ upar_phase = 0.0 temperature_amplitude = 0.0 temperature_phase = 0.0 -[vpa_IC_neutral_species_1] +[vz_IC_neutral_species_1] initialization_option= "gaussian" density_amplitude = 1.0 density_phase = 0.0 diff --git a/examples/sheath+wall-bc_test/wall-bc_cheb_test.toml b/examples/sheath+wall-bc_test/wall-bc_cheb_test.toml index b9ed15f46..22a942e8c 100644 --- a/examples/sheath+wall-bc_test/wall-bc_cheb_test.toml +++ b/examples/sheath+wall-bc_test/wall-bc_cheb_test.toml @@ -5,17 +5,30 @@ evolve_moments_conservation = false charge_exchange_frequency = 2.0 ionization_frequency = 2.0 constant_ionization_rate = false -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 9 -z_nelement = 2 -z_bc = "wall" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 10 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 9 +nelement = 2 +bc = "wall" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 17 +nelement = 10 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 17 +nelement = 10 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" [composition] n_ion_species = 1 @@ -59,7 +72,7 @@ upar_phase = 0.0 temperature_amplitude = 0.0 temperature_phase = 0.0 -[vpa_IC_neutral_species_1] +[vz_IC_neutral_species_1] initialization_option= "gaussian" density_amplitude = 1.0 density_phase = 0.0 diff --git a/examples/sound-wave/sound-wave_cheb.toml b/examples/sound-wave/sound-wave_cheb.toml index 4c50b1c65..cf5ca9331 100644 --- a/examples/sound-wave/sound-wave_cheb.toml +++ b/examples/sound-wave/sound-wave_cheb.toml @@ -4,22 +4,29 @@ evolve_moments_parallel_pressure = false evolve_moments_conservation = true charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 9 -z_nelement = 2 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 8 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 17 -vz_nelement = 8 -vz_L = 8.0 -vz_bc = "periodic" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 +[z] +ngrid = 9 +nelement = 2 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 17 +nelement = 8 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 17 +nelement = 8 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" [composition] n_ion_species = 1 diff --git a/examples/sound-wave/sound-wave_cheb_split1.toml b/examples/sound-wave/sound-wave_cheb_split1.toml index 9ef684754..e26556303 100644 --- a/examples/sound-wave/sound-wave_cheb_split1.toml +++ b/examples/sound-wave/sound-wave_cheb_split1.toml @@ -4,17 +4,30 @@ evolve_moments_parallel_pressure = false evolve_moments_conservation = true charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 9 -z_nelement = 2 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 8 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 9 +nelement = 2 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 17 +nelement = 8 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 17 +nelement = 8 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" [composition] n_ion_species = 1 diff --git a/examples/sound-wave/sound-wave_cheb_split2.toml b/examples/sound-wave/sound-wave_cheb_split2.toml index 27989f73c..4fa8275f4 100644 --- a/examples/sound-wave/sound-wave_cheb_split2.toml +++ b/examples/sound-wave/sound-wave_cheb_split2.toml @@ -4,17 +4,30 @@ evolve_moments_parallel_pressure = false evolve_moments_conservation = true charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 9 -z_nelement = 2 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 8 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 9 +nelement = 2 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 17 +nelement = 8 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 17 +nelement = 8 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" [composition] n_ion_species = 1 diff --git a/examples/sound-wave/sound-wave_cheb_split3.toml b/examples/sound-wave/sound-wave_cheb_split3.toml index 0443db2d4..a18e377d6 100644 --- a/examples/sound-wave/sound-wave_cheb_split3.toml +++ b/examples/sound-wave/sound-wave_cheb_split3.toml @@ -4,17 +4,30 @@ evolve_moments_parallel_pressure = true evolve_moments_conservation = true charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 9 -z_nelement = 2 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 8 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 9 +nelement = 2 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 17 +nelement = 8 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 17 +nelement = 8 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" [composition] n_ion_species = 1 diff --git a/examples/sound-wave/sound-wave_fd.toml b/examples/sound-wave/sound-wave_fd.toml index 5c45c3183..3d228f230 100644 --- a/examples/sound-wave/sound-wave_fd.toml +++ b/examples/sound-wave/sound-wave_fd.toml @@ -4,17 +4,30 @@ evolve_moments_parallel_pressure = false evolve_moments_conservation = true charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 100 -z_nelement = 1 -z_bc = "periodic" -z_discretization = "finite_difference" -vpa_ngrid = 180 -vpa_nelement = 1 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "finite_difference" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 100 +nelement = 1 +bc = "periodic" +discretization = "finite_difference" + +[vpa] +ngrid = 180 +nelement = 1 +L = 8.0 +bc = "periodic" +discretization = "finite_difference" + +[vz] +ngrid = 180 +nelement = 1 +L = 8.0 +bc = "periodic" +discretization = "finite_difference" [composition] n_ion_species = 1 diff --git a/examples/sound-wave/sound-wave_fd_split1.toml b/examples/sound-wave/sound-wave_fd_split1.toml index d25a888d4..7c5914e8f 100644 --- a/examples/sound-wave/sound-wave_fd_split1.toml +++ b/examples/sound-wave/sound-wave_fd_split1.toml @@ -4,17 +4,30 @@ evolve_moments_parallel_pressure = false evolve_moments_conservation = true charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 100 -z_nelement = 1 -z_bc = "periodic" -z_discretization = "finite_difference" -vpa_ngrid = 180 -vpa_nelement = 1 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "finite_difference" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 100 +nelement = 1 +bc = "periodic" +discretization = "finite_difference" + +[vpa] +ngrid = 180 +nelement = 1 +L = 8.0 +bc = "periodic" +discretization = "finite_difference" + +[vz] +ngrid = 180 +nelement = 1 +L = 8.0 +bc = "periodic" +discretization = "finite_difference" [composition] n_ion_species = 1 diff --git a/examples/sound-wave/sound-wave_fd_split2.toml b/examples/sound-wave/sound-wave_fd_split2.toml index 658572f1f..622627963 100644 --- a/examples/sound-wave/sound-wave_fd_split2.toml +++ b/examples/sound-wave/sound-wave_fd_split2.toml @@ -4,17 +4,30 @@ evolve_moments_parallel_pressure = false evolve_moments_conservation = true charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 100 -z_nelement = 1 -z_bc = "periodic" -z_discretization = "finite_difference" -vpa_ngrid = 180 -vpa_nelement = 1 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "finite_difference" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 100 +nelement = 1 +bc = "periodic" +discretization = "finite_difference" + +[vpa] +ngrid = 180 +nelement = 1 +L = 8.0 +bc = "periodic" +discretization = "finite_difference" + +[vz] +ngrid = 180 +nelement = 1 +L = 8.0 +bc = "periodic" +discretization = "finite_difference" [composition] n_ion_species = 1 diff --git a/examples/sound-wave/sound-wave_fd_split3.toml b/examples/sound-wave/sound-wave_fd_split3.toml index 76c205b6a..51366f2da 100644 --- a/examples/sound-wave/sound-wave_fd_split3.toml +++ b/examples/sound-wave/sound-wave_fd_split3.toml @@ -4,17 +4,30 @@ evolve_moments_parallel_pressure = true evolve_moments_conservation = true charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 100 -z_nelement = 1 -z_bc = "periodic" -z_discretization = "finite_difference" -vpa_ngrid = 180 -vpa_nelement = 1 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "finite_difference" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 100 +nelement = 1 +bc = "periodic" +discretization = "finite_difference" + +[vpa] +ngrid = 180 +nelement = 1 +L = 8.0 +bc = "periodic" +discretization = "finite_difference" + +[vz] +ngrid = 180 +nelement = 1 +L = 8.0 +bc = "periodic" +discretization = "finite_difference" [composition] n_ion_species = 1 diff --git a/examples/wall-bc/wall+sheath-bc.toml b/examples/wall-bc/wall+sheath-bc.toml index 4e582624e..c4a936255 100644 --- a/examples/wall-bc/wall+sheath-bc.toml +++ b/examples/wall-bc/wall+sheath-bc.toml @@ -5,22 +5,30 @@ evolve_moments_conservation = false charge_exchange_frequency = 2.0 ionization_frequency = 2.0 constant_ionization_rate = false -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 9 -z_nelement = 2 -z_bc = "wall" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 10 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 17 -vz_nelement = 10 -vz_L = 8.0 -vz_bc = "periodic" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 9 +nelement = 2 +bc = "wall" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 17 +nelement = 10 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 17 +nelement = 10 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" [composition] n_ion_species = 1 diff --git a/examples/wall-bc/wall-bc_cheb.toml b/examples/wall-bc/wall-bc_cheb.toml index d0228533e..b5095d937 100644 --- a/examples/wall-bc/wall-bc_cheb.toml +++ b/examples/wall-bc/wall-bc_cheb.toml @@ -5,22 +5,30 @@ evolve_moments_conservation = false charge_exchange_frequency = 0.5 ionization_frequency = 0.75 constant_ionization_rate = false -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 9 -z_nelement = 32 -z_bc = "wall" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 9 -vpa_nelement = 64 -vpa_L = 18.0 -vpa_bc = "both_zero" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 9 -vz_nelement = 64 -vz_L = 18.0 -vz_bc = "both_zero" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 9 +nelement = 32 +bc = "wall" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 9 +nelement = 64 +L = 18.0 +bc = "both_zero" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 9 +nelement = 64 +L = 18.0 +bc = "both_zero" +discretization = "chebyshev_pseudospectral" [composition] n_ion_species = 1 @@ -64,7 +72,7 @@ upar_phase = 0.0 temperature_amplitude = 0.0 temperature_phase = 0.0 -[vpa_IC_neutral_species_1] +[vz_IC_neutral_species_1] initialization_option = "gaussian" density_amplitude = 1.0 density_phase = 0.0 @@ -85,4 +93,4 @@ force_minimum_pdf_value = 0.0 [neutral_numerical_dissipation] #vz_dissipation_coefficient = 1.0e-3 #1.0e-2 #1.0e-1 -force_minimum_pdf_value = 0.0 \ No newline at end of file +force_minimum_pdf_value = 0.0 diff --git a/examples/wall-bc/wall-bc_cheb_split1.toml b/examples/wall-bc/wall-bc_cheb_split1.toml index 78474d3d0..d40deb978 100644 --- a/examples/wall-bc/wall-bc_cheb_split1.toml +++ b/examples/wall-bc/wall-bc_cheb_split1.toml @@ -6,22 +6,30 @@ evolve_moments_conservation = true charge_exchange_frequency = 0.5 ionization_frequency = 0.75 constant_ionization_rate = false -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 9 -z_nelement = 32 -z_bc = "wall" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 9 -vpa_nelement = 64 -vpa_L = 18.0 -vpa_bc = "both_zero" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 9 -vz_nelement = 64 -vz_L = 18.0 -vz_bc = "both_zero" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 9 +nelement = 32 +bc = "wall" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 9 +nelement = 64 +L = 18.0 +bc = "both_zero" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 9 +nelement = 64 +L = 18.0 +bc = "both_zero" +discretization = "chebyshev_pseudospectral" [composition] n_ion_species = 1 @@ -65,7 +73,7 @@ upar_phase = 0.0 temperature_amplitude = 0.0 temperature_phase = 0.0 -[vpa_IC_neutral_species_1] +[vz_IC_neutral_species_1] initialization_option = "gaussian" density_amplitude = 1.0 density_phase = 0.0 @@ -86,4 +94,4 @@ force_minimum_pdf_value = 0.0 [neutral_numerical_dissipation] #vz_dissipation_coefficient = 1.0e-3 #1.0e-2 #1.0e-1 -force_minimum_pdf_value = 0.0 \ No newline at end of file +force_minimum_pdf_value = 0.0 diff --git a/examples/wall-bc/wall-bc_cheb_split2.toml b/examples/wall-bc/wall-bc_cheb_split2.toml index 81530feec..06cf14dec 100644 --- a/examples/wall-bc/wall-bc_cheb_split2.toml +++ b/examples/wall-bc/wall-bc_cheb_split2.toml @@ -6,22 +6,30 @@ evolve_moments_conservation = true charge_exchange_frequency = 0.5 ionization_frequency = 0.75 constant_ionization_rate = false -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 9 -z_nelement = 32 -z_bc = "wall" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 9 -vpa_nelement = 64 -vpa_L = 18.0 -vpa_bc = "both_zero" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 9 -vz_nelement = 64 -vz_L = 18.0 -vz_bc = "both_zero" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 9 +nelement = 32 +bc = "wall" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 9 +nelement = 64 +L = 18.0 +bc = "both_zero" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 9 +nelement = 64 +L = 18.0 +bc = "both_zero" +discretization = "chebyshev_pseudospectral" [composition] n_ion_species = 1 @@ -65,7 +73,7 @@ upar_phase = 0.0 temperature_amplitude = 0.0 temperature_phase = 0.0 -[vpa_IC_neutral_species_1] +[vz_IC_neutral_species_1] initialization_option = "gaussian" density_amplitude = 1.0 density_phase = 0.0 @@ -86,4 +94,4 @@ force_minimum_pdf_value = 0.0 [neutral_numerical_dissipation] #vz_dissipation_coefficient = 1.0e-3 #1.0e-2 #1.0e-1 -force_minimum_pdf_value = 0.0 \ No newline at end of file +force_minimum_pdf_value = 0.0 diff --git a/examples/wall-bc/wall-bc_cheb_split3.toml b/examples/wall-bc/wall-bc_cheb_split3.toml index 7834ba468..ca668cb8e 100644 --- a/examples/wall-bc/wall-bc_cheb_split3.toml +++ b/examples/wall-bc/wall-bc_cheb_split3.toml @@ -6,22 +6,30 @@ evolve_moments_conservation = true charge_exchange_frequency = 0.5 ionization_frequency = 0.75 constant_ionization_rate = false -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 9 -z_nelement = 32 -z_bc = "wall" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 9 -vpa_nelement = 64 -vpa_L = 18.0 -vpa_bc = "both_zero" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 9 -vz_nelement = 64 -vz_L = 18.0 -vz_bc = "both_zero" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 9 +nelement = 32 +bc = "wall" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 9 +nelement = 64 +L = 18.0 +bc = "both_zero" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 9 +nelement = 64 +L = 18.0 +bc = "both_zero" +discretization = "chebyshev_pseudospectral" [composition] n_ion_species = 1 @@ -65,7 +73,7 @@ upar_phase = 0.0 temperature_amplitude = 0.0 temperature_phase = 0.0 -[vpa_IC_neutral_species_1] +[vz_IC_neutral_species_1] initialization_option = "gaussian" density_amplitude = 1.0 density_phase = 0.0 @@ -86,4 +94,4 @@ force_minimum_pdf_value = 0.0 [neutral_numerical_dissipation] #vz_dissipation_coefficient = 1.0e-3 #1.0e-2 #1.0e-1 -force_minimum_pdf_value = 0.0 \ No newline at end of file +force_minimum_pdf_value = 0.0 diff --git a/examples/wall-bc/wall-bc_no-neutrals.toml b/examples/wall-bc/wall-bc_no-neutrals.toml index fc980405f..b937712fc 100644 --- a/examples/wall-bc/wall-bc_no-neutrals.toml +++ b/examples/wall-bc/wall-bc_no-neutrals.toml @@ -5,23 +5,31 @@ evolve_moments_density = false evolve_moments_parallel_flow = false evolve_moments_parallel_pressure = false evolve_moments_conservation = true -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 9 -z_nelement = 32 -#z_nelement_local = 4 -z_bc = "wall" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 10 -vpa_nelement = 63 -vpa_L = 18.0 -vpa_bc = "zero" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 10 -vz_nelement = 63 -vz_L = 18.0 -vz_bc = "zero" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 9 +nelement = 32 +#nelement_local = 4 +bc = "wall" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 10 +nelement = 63 +L = 18.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 10 +nelement = 63 +L = 18.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" [composition] n_ion_species = 1 diff --git a/examples/wall-bc/wall-bc_no-neutrals_split1.toml b/examples/wall-bc/wall-bc_no-neutrals_split1.toml index a9ac4ee25..51e2f11ac 100644 --- a/examples/wall-bc/wall-bc_no-neutrals_split1.toml +++ b/examples/wall-bc/wall-bc_no-neutrals_split1.toml @@ -5,23 +5,31 @@ evolve_moments_density = true evolve_moments_parallel_flow = false evolve_moments_parallel_pressure = false evolve_moments_conservation = true -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 9 -z_nelement = 32 -#z_nelement_local = 4 -z_bc = "wall" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 10 -vpa_nelement = 63 -vpa_L = 18.0 -vpa_bc = "zero" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 10 -vz_nelement = 63 -vz_L = 18.0 -vz_bc = "zero" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 9 +nelement = 32 +#nelement_local = 4 +bc = "wall" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 10 +nelement = 63 +L = 18.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 10 +nelement = 63 +L = 18.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" [composition] n_ion_species = 1 @@ -75,4 +83,4 @@ source_T = 1.0 [krook_collisions] use_krook = true -frequency_option = "reference_parameters" \ No newline at end of file +frequency_option = "reference_parameters" diff --git a/examples/wall-bc/wall-bc_no-neutrals_split2.toml b/examples/wall-bc/wall-bc_no-neutrals_split2.toml index 66728bc89..dfdfa2cb9 100644 --- a/examples/wall-bc/wall-bc_no-neutrals_split2.toml +++ b/examples/wall-bc/wall-bc_no-neutrals_split2.toml @@ -5,23 +5,31 @@ evolve_moments_density = true evolve_moments_parallel_flow = true evolve_moments_parallel_pressure = false evolve_moments_conservation = true -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 9 -z_nelement = 32 -#z_nelement_local = 4 -z_bc = "wall" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 10 -vpa_nelement = 63 -vpa_L = 18.0 -vpa_bc = "zero" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 10 -vz_nelement = 63 -vz_L = 18.0 -vz_bc = "zero" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 9 +nelement = 32 +#nelement_local = 4 +bc = "wall" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 10 +nelement = 63 +L = 18.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 10 +nelement = 63 +L = 18.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" [composition] n_ion_species = 1 @@ -75,4 +83,4 @@ source_T = 1.0 [krook_collisions] use_krook = true -frequency_option = "reference_parameters" \ No newline at end of file +frequency_option = "reference_parameters" diff --git a/examples/wall-bc/wall-bc_no-neutrals_split3.toml b/examples/wall-bc/wall-bc_no-neutrals_split3.toml index 126a72cfd..d05352b43 100644 --- a/examples/wall-bc/wall-bc_no-neutrals_split3.toml +++ b/examples/wall-bc/wall-bc_no-neutrals_split3.toml @@ -5,23 +5,31 @@ evolve_moments_density = true evolve_moments_parallel_flow = true evolve_moments_parallel_pressure = true evolve_moments_conservation = true -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 9 -z_nelement = 32 -#z_nelement_local = 4 -z_bc = "wall" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 10 -vpa_nelement = 63 -vpa_L = 18.0 -vpa_bc = "zero" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 10 -vz_nelement = 63 -vz_L = 18.0 -vz_bc = "zero" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 9 +nelement = 32 +#nelement_local = 4 +bc = "wall" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 10 +nelement = 63 +L = 18.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 10 +nelement = 63 +L = 18.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" [composition] n_ion_species = 1 @@ -75,4 +83,4 @@ force_minimum_pdf_value = 0.0 [krook_collisions] use_krook = true -frequency_option = "reference_parameters" \ No newline at end of file +frequency_option = "reference_parameters" diff --git a/examples/wall-bc/wall-bc_volumerecycle.toml b/examples/wall-bc/wall-bc_volumerecycle.toml index 71892195e..918cafa2f 100644 --- a/examples/wall-bc/wall-bc_volumerecycle.toml +++ b/examples/wall-bc/wall-bc_volumerecycle.toml @@ -8,24 +8,32 @@ evolve_moments_conservation = true charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 9 -z_nelement = 32 -#z_nelement_local = 4 -z_bc = "wall" -z_discretization = "chebyshev_pseudospectral" -z_element_spacing_option = "sqrt" -vpa_ngrid = 10 -vpa_nelement = 63 -vpa_L = 18.0 -vpa_bc = "zero" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 10 -vz_nelement = 63 -vz_L = 18.0 -vz_bc = "zero" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 9 +nelement = 32 +#nelement_local = 4 +bc = "wall" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "sqrt" + +[vpa] +ngrid = 10 +nelement = 63 +L = 18.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 10 +nelement = 63 +L = 18.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" [composition] n_ion_species = 1 @@ -70,7 +78,7 @@ upar_phase = 0.0 temperature_amplitude = 0.0 temperature_phase = 0.0 -[vpa_IC_neutral_species_1] +[vz_IC_neutral_species_1] initialization_option = "gaussian" density_amplitude = 1.0 density_phase = 0.0 @@ -112,4 +120,4 @@ force_minimum_pdf_value = 0.0 [krook_collisions] use_krook = true -frequency_option = "reference_parameters" \ No newline at end of file +frequency_option = "reference_parameters" diff --git a/examples/wall-bc/wall-bc_volumerecycle_split1.toml b/examples/wall-bc/wall-bc_volumerecycle_split1.toml index bc5123654..b1649dc74 100644 --- a/examples/wall-bc/wall-bc_volumerecycle_split1.toml +++ b/examples/wall-bc/wall-bc_volumerecycle_split1.toml @@ -8,24 +8,32 @@ evolve_moments_conservation = true charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 9 -z_nelement = 32 -#z_nelement_local = 4 -z_bc = "wall" -z_discretization = "chebyshev_pseudospectral" -z_element_spacing_option = "sqrt" -vpa_ngrid = 10 -vpa_nelement = 63 -vpa_L = 18.0 -vpa_bc = "zero" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 10 -vz_nelement = 63 -vz_L = 18.0 -vz_bc = "zero" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 9 +nelement = 32 +#nelement_local = 4 +bc = "wall" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "sqrt" + +[vpa] +ngrid = 10 +nelement = 63 +L = 18.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 10 +nelement = 63 +L = 18.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" [composition] n_ion_species = 1 @@ -70,7 +78,7 @@ upar_phase = 0.0 temperature_amplitude = 0.0 temperature_phase = 0.0 -[vpa_IC_neutral_species_1] +[vz_IC_neutral_species_1] initialization_option = "gaussian" density_amplitude = 1.0 density_phase = 0.0 @@ -112,4 +120,4 @@ recycling_controller_fraction = 0.25 [krook_collisions] use_krook = true -frequency_option = "reference_parameters" \ No newline at end of file +frequency_option = "reference_parameters" diff --git a/examples/wall-bc/wall-bc_volumerecycle_split2.toml b/examples/wall-bc/wall-bc_volumerecycle_split2.toml index acc92a7d2..94adb5859 100644 --- a/examples/wall-bc/wall-bc_volumerecycle_split2.toml +++ b/examples/wall-bc/wall-bc_volumerecycle_split2.toml @@ -8,24 +8,32 @@ evolve_moments_conservation = true charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 9 -z_nelement = 32 -#z_nelement_local = 4 -z_bc = "wall" -z_discretization = "chebyshev_pseudospectral" -z_element_spacing_option = "sqrt" -vpa_ngrid = 10 -vpa_nelement = 63 -vpa_L = 18.0 -vpa_bc = "zero" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 10 -vz_nelement = 63 -vz_L = 18.0 -vz_bc = "zero" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 9 +nelement = 32 +#nelement_local = 4 +bc = "wall" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "sqrt" + +[vpa] +ngrid = 10 +nelement = 63 +L = 18.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 10 +nelement = 63 +L = 18.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" [composition] n_ion_species = 1 @@ -70,7 +78,7 @@ upar_phase = 0.0 temperature_amplitude = 0.0 temperature_phase = 0.0 -[vpa_IC_neutral_species_1] +[vz_IC_neutral_species_1] initialization_option = "gaussian" density_amplitude = 1.0 density_phase = 0.0 @@ -112,4 +120,4 @@ recycling_controller_fraction = 0.25 [krook_collisions] use_krook = true -frequency_option = "reference_parameters" \ No newline at end of file +frequency_option = "reference_parameters" diff --git a/examples/wall-bc/wall-bc_volumerecycle_split3.toml b/examples/wall-bc/wall-bc_volumerecycle_split3.toml index 477a943e9..9abeb6950 100644 --- a/examples/wall-bc/wall-bc_volumerecycle_split3.toml +++ b/examples/wall-bc/wall-bc_volumerecycle_split3.toml @@ -8,24 +8,32 @@ evolve_moments_conservation = true charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 9 -z_nelement = 32 -#z_nelement_local = 4 -z_bc = "wall" -z_discretization = "chebyshev_pseudospectral" -z_element_spacing_option = "sqrt" -vpa_ngrid = 10 -vpa_nelement = 63 -vpa_L = 30.0 -vpa_bc = "zero" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 10 -vz_nelement = 63 -vz_L = 30.0 -vz_bc = "zero" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 9 +nelement = 32 +#nelement_local = 4 +bc = "wall" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "sqrt" + +[vpa] +ngrid = 10 +nelement = 63 +L = 30.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 10 +nelement = 63 +L = 30.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" [composition] n_ion_species = 1 @@ -70,7 +78,7 @@ upar_phase = 0.0 temperature_amplitude = 0.0 temperature_phase = 0.0 -[vpa_IC_neutral_species_1] +[vz_IC_neutral_species_1] initialization_option = "gaussian" density_amplitude = 1.0 density_phase = 0.0 @@ -112,4 +120,4 @@ force_minimum_pdf_value = 0.0 [krook_collisions] use_krook = true -frequency_option = "reference_parameters" \ No newline at end of file +frequency_option = "reference_parameters" 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 fb5aeefa0..9ed10e13a 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 @@ -29,7 +29,6 @@ using moment_kinetics.analysis: analyze_fields_data, check_Chodura_condition, get_unnormalised_f_1d, vpagrid_to_dzdt_2d, get_unnormalised_f_2d using moment_kinetics.array_allocation: allocate_float -using moment_kinetics.coordinates: define_coordinate using moment_kinetics.input_structs using moment_kinetics.looping: all_dimensions, ion_dimensions, neutral_dimensions using moment_kinetics.manufactured_solns: manufactured_solutions, diff --git a/moment_kinetics/debug_test/fokker_planck_collisions_inputs.jl b/moment_kinetics/debug_test/fokker_planck_collisions_inputs.jl index 671a69448..bedfe1a0c 100644 --- a/moment_kinetics/debug_test/fokker_planck_collisions_inputs.jl +++ b/moment_kinetics/debug_test/fokker_planck_collisions_inputs.jl @@ -32,23 +32,23 @@ test_input_full_f = OptionsDict( "fokker_planck_collisions" => OptionsDict("use_fokker_planck" => true, "nuii" => 1.0, "frequency_option" => "manual"), - "r_bc" => "periodic", - "r_discretization" => "chebyshev_pseudospectral", - "r_nelement" => 1, - "r_ngrid" => 3, - "vpa_L" => 6.0, - "vpa_bc" => "zero", - "vpa_discretization" => "gausslegendre_pseudospectral", - "vpa_nelement" => 2, - "vpa_ngrid" => 3, - "vperp_L" => 3.0, - "vperp_discretization" => "gausslegendre_pseudospectral", - "vperp_nelement" => 2, - "vperp_ngrid" => 3, - "z_bc" => "wall", - "z_discretization" => "chebyshev_pseudospectral", - "z_nelement" => 1, - "z_ngrid" => 3, + "r" => OptionsDict("bc" => "periodic", + "discretization" => "chebyshev_pseudospectral", + "nelement" => 1, + "ngrid" => 3), + "vpa" => OptionsDict("L" => 6.0, + "bc" => "zero", + "discretization" => "gausslegendre_pseudospectral", + "nelement" => 2, + "ngrid" => 3), + "vperp" => OptionsDict("L" => 3.0, + "discretization" => "gausslegendre_pseudospectral", + "nelement" => 2, + "ngrid" => 3), + "z" => OptionsDict("bc" => "wall", + "discretization" => "chebyshev_pseudospectral", + "nelement" => 1, + "ngrid" => 3), ) test_input_list = [ diff --git a/moment_kinetics/debug_test/gyroaverage_inputs.jl b/moment_kinetics/debug_test/gyroaverage_inputs.jl index 516d4c674..fe0543a80 100644 --- a/moment_kinetics/debug_test/gyroaverage_inputs.jl +++ b/moment_kinetics/debug_test/gyroaverage_inputs.jl @@ -36,28 +36,28 @@ test_input = OptionsDict( "dt" => 1.0e-12, "nwrite" => 2, "nwrite_dfns" => 2,), - "r_ngrid" => 5, - "r_nelement" => 2, - "r_bc" => "periodic", - "z_ngrid" => 5, - "z_nelement" => 2, - "z_bc" => "periodic", - "z_discretization" => "chebyshev_pseudospectral", - "vpa_ngrid" => 5, - "vpa_nelement" => 2, - "vpa_L" => 6.0, - "vpa_bc" => "zero", - "vpa_discretization" => "chebyshev_pseudospectral", - "vperp_ngrid" => 5, - "vperp_nelement" => 1, - "vperp_L" => 3.0, - "vperp_bc" => "zero", - "vperp_discretization" => "chebyshev_pseudospectral", - "vz_ngrid" => 5, - "vz_nelement" => 2, - "vz_L" => 6.0, - "vz_bc" => "zero", - "vz_discretization" => "chebyshev_pseudospectral", + "r" => OptionsDict("ngrid" => 5, + "nelement" => 2, + "bc" => "periodic"), + "z" => OptionsDict("ngrid" => 5, + "nelement" => 2, + "bc" => "periodic", + "discretization" => "chebyshev_pseudospectral"), + "vpa" => OptionsDict("ngrid" => 5, + "nelement" => 2, + "L" => 6.0, + "bc" => "zero", + "discretization" => "chebyshev_pseudospectral"), + "vperp" => OptionsDict("ngrid" => 5, + "nelement" => 1, + "L" => 3.0, + "bc" => "zero", + "discretization" => "chebyshev_pseudospectral"), + "vz" => OptionsDict("ngrid" => 5, + "nelement" => 2, + "L" => 6.0, + "bc" => "zero", + "discretization" => "chebyshev_pseudospectral"), "numerical_dissipation" => OptionsDict("vpa_dissipation_coefficient" => 1.0e-3, "vperp_dissipation_coefficient" => 1.0e-3), "geometry" => OptionsDict("DeltaB"=>0.0, diff --git a/moment_kinetics/debug_test/kinetic_electron_inputs.jl b/moment_kinetics/debug_test/kinetic_electron_inputs.jl index cc8c50f3e..2ceb7eee2 100644 --- a/moment_kinetics/debug_test/kinetic_electron_inputs.jl +++ b/moment_kinetics/debug_test/kinetic_electron_inputs.jl @@ -2,94 +2,94 @@ test_type = "Kinetic electron" using moment_kinetics.type_definitions: OptionsDict test_input = OptionsDict("composition" => OptionsDict("n_ion_species" => 1, - "n_neutral_species" => 1, - "electron_physics" => "kinetic_electrons", - "recycling_fraction" => 0.5, - "T_e" => 0.2, - "T_wall" => 0.1), - "run_name" => "kinetic_electron", - "base_directory" => test_output_directory, - "evolve_moments_density" => true, - "evolve_moments_parallel_flow" => true, - "evolve_moments_parallel_pressure" => true, - "evolve_moments_conservation" => true, - "ion_species_1" => OptionsDict("initial_density" => 1.0, - "initial_temperature" => 1.0), - "z_IC_ion_species_1" => OptionsDict("initialization_option" => "gaussian", - "density_amplitude" => 0.001, - "density_phase" => 0.0, - "upar_amplitude" => 1.0, - "upar_phase" => 0.0, - "temperature_amplitude" => 0.0, - "temperature_phase" => 0.0), - "vpa_IC_ion_species_1" => OptionsDict("initialization_option" => "gaussian", - "density_amplitude" => 1.0, + "n_neutral_species" => 1, + "electron_physics" => "kinetic_electrons", + "recycling_fraction" => 0.5, + "T_e" => 0.2, + "T_wall" => 0.1), + "run_name" => "kinetic_electron", + "base_directory" => test_output_directory, + "evolve_moments_density" => true, + "evolve_moments_parallel_flow" => true, + "evolve_moments_parallel_pressure" => true, + "evolve_moments_conservation" => true, + "ion_species_1" => OptionsDict("initial_density" => 1.0, + "initial_temperature" => 1.0), + "z_IC_ion_species_1" => OptionsDict("initialization_option" => "gaussian", + "density_amplitude" => 0.001, "density_phase" => 0.0, - "upar_amplitude" => 0.0, + "upar_amplitude" => 1.0, "upar_phase" => 0.0, "temperature_amplitude" => 0.0, "temperature_phase" => 0.0), - "neutral_species_1" => OptionsDict("initial_density" => 1.0, - "initial_temperature" => 1.0), - "z_IC_neutral_species_1" => OptionsDict("initialization_option" => "gaussian", - "density_amplitude" => 0.001, + "vpa_IC_ion_species_1" => OptionsDict("initialization_option" => "gaussian", + "density_amplitude" => 1.0, "density_phase" => 0.0, - "upar_amplitude" => -1.0, + "upar_amplitude" => 0.0, "upar_phase" => 0.0, "temperature_amplitude" => 0.0, "temperature_phase" => 0.0), - "vpa_IC_neutral_species_1" => OptionsDict("initialization_option" => "gaussian", - "density_amplitude" => 1.0, + "neutral_species_1" => OptionsDict("initial_density" => 1.0, + "initial_temperature" => 1.0), + "z_IC_neutral_species_1" => OptionsDict("initialization_option" => "gaussian", + "density_amplitude" => 0.001, "density_phase" => 0.0, - "upar_amplitude" => 0.0, + "upar_amplitude" => -1.0, "upar_phase" => 0.0, "temperature_amplitude" => 0.0, "temperature_phase" => 0.0), - "charge_exchange_frequency" => 0.75, - "ionization_frequency" => 0.5, - "constant_ionization_rate" => false, - "timestepping" => OptionsDict("type" => "Fekete4(3)", - "nstep" => 3, - "dt" => 2.0e-8, - "minimum_dt" => 1.0e-8, - "CFL_prefactor" => 1.0, - "step_update_prefactor" => 0.4, - "nwrite" => 2, - "split_operators" => false), - "electron_timestepping" => OptionsDict("type" => "Fekete4(3)", - "nstep" => 10, - "dt" => 4.0e-11, - "minimum_dt" => 2.0e-11, - "initialization_residual_value" => 1.e10, - "converged_residual_value" => 1.e10, - "nwrite" => 10000, - "nwrite_dfns" => 10000, - "no_restart" => true), - "r_ngrid" => 1, - "r_nelement" => 1, - "z_ngrid" => 3, - "z_nelement" => 24, - "z_bc" => "wall", - "z_discretization" => "chebyshev_pseudospectral", - "z_element_spacing_option" => "sqrt", - "vpa_ngrid" => 3, - "vpa_nelement" => 16, - "vpa_L" => 6.0, - "vpa_bc" => "zero", - "vpa_discretization" => "chebyshev_pseudospectral", - "vz_ngrid" => 3, - "vz_nelement" => 6, - "vz_L" => 6.0, - "vz_bc" => "zero", - "vz_discretization" => "chebyshev_pseudospectral", - "ion_source" => OptionsDict("active" => true, - "z_profile" => "gaussian", - "z_width" => 0.125, - "source_strength" => 2.0, - "source_T" => 2.0), - "krook_collisions" => OptionsDict("use_krook" => true), - "numerical_dissipation" => OptionsDict("force_minimum_pdf_value" => 0.0, - "vpa_dissipation_coefficient" => 1e-2)) + "vz_IC_neutral_species_1" => OptionsDict("initialization_option" => "gaussian", + "density_amplitude" => 1.0, + "density_phase" => 0.0, + "upar_amplitude" => 0.0, + "upar_phase" => 0.0, + "temperature_amplitude" => 0.0, + "temperature_phase" => 0.0), + "charge_exchange_frequency" => 0.75, + "ionization_frequency" => 0.5, + "constant_ionization_rate" => false, + "timestepping" => OptionsDict("type" => "Fekete4(3)", + "nstep" => 3, + "dt" => 2.0e-8, + "minimum_dt" => 1.0e-8, + "CFL_prefactor" => 1.0, + "step_update_prefactor" => 0.4, + "nwrite" => 2, + "split_operators" => false), + "electron_timestepping" => OptionsDict("type" => "Fekete4(3)", + "nstep" => 10, + "dt" => 4.0e-11, + "minimum_dt" => 2.0e-11, + "initialization_residual_value" => 1.e10, + "converged_residual_value" => 1.e10, + "nwrite" => 10000, + "nwrite_dfns" => 10000, + "no_restart" => true), + "r" => OptionsDict("ngrid" => 1, + "nelement" => 1), + "z" => OptionsDict("ngrid" => 3, + "nelement" => 24, + "bc" => "wall", + "discretization" => "chebyshev_pseudospectral", + "element_spacing_option" => "sqrt"), + "vpa" => OptionsDict("ngrid" => 3, + "nelement" => 16, + "L" => 6.0, + "bc" => "zero", + "discretization" => "chebyshev_pseudospectral"), + "vz" => OptionsDict("ngrid" => 3, + "nelement" => 6, + "L" => 6.0, + "bc" => "zero", + "discretization" => "chebyshev_pseudospectral"), + "ion_source" => OptionsDict("active" => true, + "z_profile" => "gaussian", + "z_width" => 0.125, + "source_strength" => 2.0, + "source_T" => 2.0), + "krook_collisions" => OptionsDict("use_krook" => true), + "numerical_dissipation" => OptionsDict("force_minimum_pdf_value" => 0.0, + "vpa_dissipation_coefficient" => 1e-2)) test_input_list = [ diff --git a/moment_kinetics/debug_test/mms_inputs.jl b/moment_kinetics/debug_test/mms_inputs.jl index 5db15d46b..e9ca8a483 100644 --- a/moment_kinetics/debug_test/mms_inputs.jl +++ b/moment_kinetics/debug_test/mms_inputs.jl @@ -21,38 +21,38 @@ test_input = OptionsDict( "nwrite" => 2, "type" => "SSPRK2", "split_operators" => false), - "z_ngrid" => 3, - "z_nelement" => 2, - "z_bc" => "wall", - "z_discretization" => "chebyshev_pseudospectral", - "r_ngrid" => 3, - "r_nelement" => 2, - "r_bc" => "periodic", - "r_discretization" => "chebyshev_pseudospectral", - "vpa_ngrid" => 3, - "vpa_nelement" => 2, - "vpa_L" => 12.0, - "vpa_bc" => "periodic", - "vpa_discretization" => "chebyshev_pseudospectral", - "vperp_ngrid" => 3, - "vperp_nelement" => 2, - "vperp_L" => 6.0, - "vperp_discretization" => "chebyshev_pseudospectral", - "vz_ngrid" => 3, - "vz_nelement" => 2, - "vz_L" => 12.0, - "vz_bc" => "none", - "vz_discretization" => "chebyshev_pseudospectral", - "vr_ngrid" => 3, - "vr_nelement" => 2, - "vr_L" => 12.0, - "vr_bc" => "none", - "vr_discretization" => "chebyshev_pseudospectral", - "vzeta_ngrid" => 3, - "vzeta_nelement" => 2, - "vzeta_L" => 12.0, - "vzeta_bc" => "none", - "vzeta_discretization" => "chebyshev_pseudospectral", + "z" => OptionsDict("ngrid" => 3, + "nelement" => 2, + "bc" => "wall", + "discretization" => "chebyshev_pseudospectral"), + "r" => OptionsDict("ngrid" => 3, + "nelement" => 2, + "bc" => "periodic", + "discretization" => "chebyshev_pseudospectral"), + "vpa" => OptionsDict("ngrid" => 3, + "nelement" => 2, + "L" => 12.0, + "bc" => "periodic", + "discretization" => "chebyshev_pseudospectral"), + "vperp" => OptionsDict("ngrid" => 3, + "nelement" => 2, + "L" => 6.0, + "discretization" => "chebyshev_pseudospectral"), + "vz" => OptionsDict("ngrid" => 3, + "nelement" => 2, + "L" => 12.0, + "bc" => "none", + "discretization" => "chebyshev_pseudospectral"), + "vr" => OptionsDict("ngrid" => 3, + "nelement" => 2, + "L" => 12.0, + "bc" => "none", + "discretization" => "chebyshev_pseudospectral"), + "vzeta" => OptionsDict("ngrid" => 3, + "nelement" => 2, + "L" => 12.0, + "bc" => "none", + "discretization" => "chebyshev_pseudospectral"), "geometry" => OptionsDict("rhostar" => 1.0,), ) diff --git a/moment_kinetics/debug_test/recycling_fraction_inputs.jl b/moment_kinetics/debug_test/recycling_fraction_inputs.jl index fdefdfe8a..ab519c68b 100644 --- a/moment_kinetics/debug_test/recycling_fraction_inputs.jl +++ b/moment_kinetics/debug_test/recycling_fraction_inputs.jl @@ -1,84 +1,85 @@ test_type = "Recycling fraction and adaptive timestepping" using moment_kinetics.type_definitions: OptionsDict +using moment_kinetics.utils: recursive_merge test_input = OptionsDict("composition" => OptionsDict("n_ion_species" => 1, - "n_neutral_species" => 1, - "electron_physics" => "boltzmann_electron_response", - "recycling_fraction" => 0.5, - "T_e" => 0.2, - "T_wall" => 2.0), - "ion_species_1" => OptionsDict("initial_density" => 1.0, - "initial_temperature" => 1.0), - "run_name" => "full-f", - "base_directory" => test_output_directory, - "evolve_moments_density" => false, - "evolve_moments_parallel_flow" => false, - "evolve_moments_parallel_pressure" => false, - "evolve_moments_conservation" => false, - "krook_collisions" => OptionsDict("use_krook" => true), - "z_IC_ion_species_1" => OptionsDict("density_amplitude" => 0.001, - "density_phase" => 0.0, - "upar_amplitude" => 1.0, - "upar_phase" => 0.0, - "temperature_amplitude" => 0.0, - "temperature_phase" => 0.0, - "initialization_option" => "gaussian"), - "vpa_IC_ion_species_1" => OptionsDict("initialization_option" => "gaussian", - "density_amplitude" => 1.0, - "density_phase" => 0.0, - "upar_amplitude" => 0.0, - "upar_phase" => 0.0, - "temperature_amplitude" => 0.0, - "temperature_phase" => 0.0), - "neutral_species_1" => OptionsDict("initial_density" => 1.0, - "initial_temperature" => 1.0), - "z_IC_neutral_species_1" => OptionsDict("initialization_option" => "gaussian", - "density_amplitude" => 0.001, - "density_phase" => 0.0, - "upar_amplitude" => -1.0, - "upar_phase" => 0.0, - "temperature_amplitude" => 0.0, - "temperature_phase" => 0.0), - "vpa_IC_neutral_species_1" => OptionsDict("initialization_option" => "gaussian", - "density_amplitude" => 1.0, - "density_phase" => 0.0, - "upar_amplitude" => 0.0, - "upar_phase" => 0.0, - "temperature_amplitude" => 0.0, - "temperature_phase" => 0.0), - "charge_exchange_frequency" => 0.75, - "ionization_frequency" => 0.5, - "constant_ionization_rate" => false, - "timestepping" => OptionsDict("type" => "Fekete4(3)", - "nstep" => 3, - "dt" => 1.0e-8, - "minimum_dt" => 1.0e-8, - "CFL_prefactor" => 1.0, - "step_update_prefactor" => 0.5, - "nwrite" => 2, - "split_operators" => false), - "r_ngrid" => 1, - "r_nelement" => 1, - "z_ngrid" => 3, - "z_nelement" => 2, - "z_bc" => "wall", - "z_discretization" => "chebyshev_pseudospectral", - "z_element_spacing_option" => "sqrt", - "vpa_ngrid" => 3, - "vpa_nelement" => 2, - "vpa_L" => 6.0, - "vpa_bc" => "zero", - "vpa_discretization" => "chebyshev_pseudospectral", - "vz_ngrid" => 3, - "vz_nelement" => 2, - "vz_L" => 6.0, - "vz_bc" => "zero", - "vz_discretization" => "chebyshev_pseudospectral", - "ion_source" => OptionsDict("active" => true, - "z_profile" => "gaussian", - "z_width" => 0.125, - "source_strength" => 2.0, - "source_T" => 2.0)) + "n_neutral_species" => 1, + "electron_physics" => "boltzmann_electron_response", + "recycling_fraction" => 0.5, + "T_e" => 0.2, + "T_wall" => 2.0), + "ion_species_1" => OptionsDict("initial_density" => 1.0, + "initial_temperature" => 1.0), + "run_name" => "full-f", + "base_directory" => test_output_directory, + "evolve_moments_density" => false, + "evolve_moments_parallel_flow" => false, + "evolve_moments_parallel_pressure" => false, + "evolve_moments_conservation" => false, + "krook_collisions" => OptionsDict("use_krook" => true), + "z_IC_ion_species_1" => OptionsDict("density_amplitude" => 0.001, + "density_phase" => 0.0, + "upar_amplitude" => 1.0, + "upar_phase" => 0.0, + "temperature_amplitude" => 0.0, + "temperature_phase" => 0.0, + "initialization_option" => "gaussian"), + "vpa_IC_ion_species_1" => OptionsDict("initialization_option" => "gaussian", + "density_amplitude" => 1.0, + "density_phase" => 0.0, + "upar_amplitude" => 0.0, + "upar_phase" => 0.0, + "temperature_amplitude" => 0.0, + "temperature_phase" => 0.0), + "neutral_species_1" => OptionsDict("initial_density" => 1.0, + "initial_temperature" => 1.0), + "z_IC_neutral_species_1" => OptionsDict("initialization_option" => "gaussian", + "density_amplitude" => 0.001, + "density_phase" => 0.0, + "upar_amplitude" => -1.0, + "upar_phase" => 0.0, + "temperature_amplitude" => 0.0, + "temperature_phase" => 0.0), + "vz_IC_neutral_species_1" => OptionsDict("initialization_option" => "gaussian", + "density_amplitude" => 1.0, + "density_phase" => 0.0, + "upar_amplitude" => 0.0, + "upar_phase" => 0.0, + "temperature_amplitude" => 0.0, + "temperature_phase" => 0.0), + "charge_exchange_frequency" => 0.75, + "ionization_frequency" => 0.5, + "constant_ionization_rate" => false, + "timestepping" => OptionsDict("type" => "Fekete4(3)", + "nstep" => 3, + "dt" => 1.0e-8, + "minimum_dt" => 1.0e-8, + "CFL_prefactor" => 1.0, + "step_update_prefactor" => 0.5, + "nwrite" => 2, + "split_operators" => false), + "r" => OptionsDict("ngrid" => 1, + "nelement" => 1), + "z" => OptionsDict("ngrid" => 3, + "nelement" => 2, + "bc" => "wall", + "discretization" => "chebyshev_pseudospectral", + "element_spacing_option" => "sqrt"), + "vpa" => OptionsDict("ngrid" => 3, + "nelement" => 2, + "L" => 6.0, + "bc" => "zero", + "discretization" => "chebyshev_pseudospectral"), + "vz" => OptionsDict("ngrid" => 3, + "nelement" => 2, + "L" => 6.0, + "bc" => "zero", + "discretization" => "chebyshev_pseudospectral"), + "ion_source" => OptionsDict("active" => true, + "z_profile" => "gaussian", + "z_width" => 0.125, + "source_strength" => 2.0, + "source_T" => 2.0)) test_input_split1 = merge(test_input, @@ -90,16 +91,16 @@ test_input_split2 = merge(test_input_split1, "evolve_moments_parallel_flow" => true)) test_input_split2["timestepping"] = merge(test_input_split2["timestepping"], OptionsDict("step_update_prefactor" => 0.4)) -test_input_split3 = merge(test_input_split2, - OptionsDict("run_name" => "split3", - "evolve_moments_parallel_pressure" => true, - "vpa_nelement" => 8, - "vz_nelement" => 8, - "numerical_dissipation" => OptionsDict("force_minimum_pdf_value" => 0.0, - "vpa_dissipation_coefficient" => 1e-2))) +test_input_split3 = recursive_merge(test_input_split2, + OptionsDict("run_name" => "split3", + "evolve_moments_parallel_pressure" => true, + "vpa" => OptionsDict("nelement" => 8), + "vz" => OptionsDict("nelement" => 8), + "numerical_dissipation" => OptionsDict("force_minimum_pdf_value" => 0.0, + "vpa_dissipation_coefficient" => 1e-2))) test_input_split3["timestepping"] = merge(test_input_split3["timestepping"], OptionsDict("dt" => 1.0e-9, - "minimum_dt" => 1.0e-9)) + "minimum_dt" => 1.0e-9)) test_input_list = [ diff --git a/moment_kinetics/debug_test/restart_interpolation_inputs.jl b/moment_kinetics/debug_test/restart_interpolation_inputs.jl index 1041423cf..45e725c82 100644 --- a/moment_kinetics/debug_test/restart_interpolation_inputs.jl +++ b/moment_kinetics/debug_test/restart_interpolation_inputs.jl @@ -1,13 +1,14 @@ test_type = "restart_interpolation" using moment_kinetics.type_definitions: OptionsDict +using moment_kinetics.utils: recursive_merge # default inputs for tests base_input = OptionsDict( "run_name" => "base", "composition" => OptionsDict("n_ion_species" => 2, - "n_neutral_species" => 2, - "electron_physics" => "boltzmann_electron_response", - "T_e" => 1.0), + "n_neutral_species" => 2, + "electron_physics" => "boltzmann_electron_response", + "T_e" => 1.0), "base_directory" => test_output_directory, "evolve_moments_density" => false, "evolve_moments_parallel_flow" => false, @@ -16,56 +17,56 @@ base_input = OptionsDict( "charge_exchange_frequency" => 2*π*0.1, "ionization_frequency" => 0.0, "timestepping" => OptionsDict("nstep" => 3, - "dt" => 0.0, - "nwrite" => 2, - "type" => "SSPRK2", - "split_operators" => false), - "z_ngrid" => 3, - "z_nelement" => 2, - "z_bc" => "periodic", - "z_discretization" => "chebyshev_pseudospectral", - "r_ngrid" => 1, - "r_nelement" => 1, - "vpa_ngrid" => 3, - "vpa_nelement" => 2, - "vpa_L" => 8.0, - "vpa_bc" => "periodic", - "vpa_discretization" => "chebyshev_pseudospectral", - "vperp_ngrid" => 1, - "vperp_nelement" => 1, - "vz_ngrid" => 3, - "vz_nelement" => 2, - "vz_L" => 8.0, - "vz_bc" => "periodic", - "vz_discretization" => "chebyshev_pseudospectral", - "vzeta_ngrid" => 1, - "vzeta_nelement" => 1, - "vr_ngrid" => 1, - "vr_nelement" => 1, + "dt" => 0.0, + "nwrite" => 2, + "type" => "SSPRK2", + "split_operators" => false), + "z" => OptionsDict("ngrid" => 3, + "nelement" => 2, + "bc" => "periodic", + "discretization" => "chebyshev_pseudospectral"), + "r" => OptionsDict("ngrid" => 1, + "nelement" => 1), + "vpa" => OptionsDict("ngrid" => 3, + "nelement" => 2, + "L" => 8.0, + "bc" => "periodic", + "discretization" => "chebyshev_pseudospectral"), + "vperp" => OptionsDict("ngrid" => 1, + "nelement" => 1), + "vz" => OptionsDict("ngrid" => 3, + "nelement" => 2, + "L" => 8.0, + "bc" => "periodic", + "discretization" => "chebyshev_pseudospectral"), + "vzeta" => OptionsDict("ngrid" => 1, + "nelement" => 1), + "vr" => OptionsDict("ngrid" => 1, + "nelement" => 1), "ion_numerical_dissipation" => OptionsDict("force_minimum_pdf_value" => 0.0), "neutral_numerical_dissipation" => OptionsDict("force_minimum_pdf_value" => 0.0)) test_input = - merge(base_input, - OptionsDict("run_name" => "full-f", - "z_nelement" => 3, - "vpa_nelement" => 3, - "vz_nelement" => 3)) + recursive_merge(base_input, + OptionsDict("run_name" => "full-f", + "z" => OptionsDict("nelement" => 3), + "vpa" => OptionsDict("nelement" => 3), + "vz" => OptionsDict("nelement" => 3))) test_input_split1 = merge(test_input, OptionsDict("run_name" => "split1", - "evolve_moments_density" => true)) + "evolve_moments_density" => true)) test_input_split2 = merge(test_input_split1 , OptionsDict("run_name" => "split2", - "evolve_moments_parallel_flow" => true)) + "evolve_moments_parallel_flow" => true)) test_input_split3 = merge(test_input_split2, OptionsDict("run_name" => "split3", - "evolve_moments_parallel_pressure" => true)) + "evolve_moments_parallel_pressure" => true)) test_input_list = [ test_input, diff --git a/moment_kinetics/debug_test/sound_wave_inputs.jl b/moment_kinetics/debug_test/sound_wave_inputs.jl index 45b8caedc..a94c4a6ce 100644 --- a/moment_kinetics/debug_test/sound_wave_inputs.jl +++ b/moment_kinetics/debug_test/sound_wave_inputs.jl @@ -2,242 +2,245 @@ test_type = "sound_wave" using moment_kinetics.type_definitions: OptionsDict # default inputs for tests -test_input_finite_difference_1D1V = OptionsDict( - "run_name" => "finite_difference_1D1V", - "composition" => OptionsDict("n_ion_species" => 2, - "n_neutral_species" => 2, - "electron_physics" => "boltzmann_electron_response", - "T_e" => 1.0), - "base_directory" => test_output_directory, - "evolve_moments_density" => false, - "evolve_moments_parallel_flow" => false, - "evolve_moments_parallel_pressure" => false, - "evolve_moments_conservation" => true, - "charge_exchange_frequency" => 2*π*0.1, - "ionization_frequency" => 0.0, - "timestepping" => OptionsDict("nstep" => 3, - "dt" => 1.e-8, - "nwrite" => 2, - "type" => "SSPRK2", - "split_operators" => false), - "z_ngrid" => 4, - "z_nelement" => 1, - "z_bc" => "periodic", - "z_discretization" => "finite_difference", - "r_ngrid" => 1, - "r_nelement" => 1, - "vpa_ngrid" => 4, - "vpa_nelement" => 1, - "vpa_L" => 8.0, - "vpa_bc" => "periodic", - "vpa_discretization" => "finite_difference", - "vperp_ngrid" => 1, - "vperp_nelement" => 1, - "vz_ngrid" => 4, - "vz_nelement" => 1, - "vz_L" => 8.0, - "vz_bc" => "periodic", - "vz_discretization" => "finite_difference", - "vzeta_ngrid" => 1, - "vzeta_nelement" => 1, - "vr_ngrid" => 1, - "vr_nelement" => 1) +test_input_finite_difference_1D1V = OptionsDict("run_name" => "finite_difference_1D1V", + "composition" => OptionsDict("n_ion_species" => 2, + "n_neutral_species" => 2, + "electron_physics" => "boltzmann_electron_response", + "T_e" => 1.0), + "base_directory" => test_output_directory, + "evolve_moments_density" => false, + "evolve_moments_parallel_flow" => false, + "evolve_moments_parallel_pressure" => false, + "evolve_moments_conservation" => true, + "charge_exchange_frequency" => 2*π*0.1, + "ionization_frequency" => 0.0, + "timestepping" => OptionsDict("nstep" => 3, + "dt" => 1.e-8, + "nwrite" => 2, + "type" => "SSPRK2", + "split_operators" => false), + "z" => OptionsDict("ngrid" => 4, + "nelement" => 1, + "bc" => "periodic", + "discretization" => "finite_difference"), + "r" => OptionsDict("ngrid" => 1, + "nelement" => 1), + "vpa" => OptionsDict("ngrid" => 4, + "nelement" => 1, + "L" => 8.0, + "bc" => "periodic", + "discretization" => "finite_difference"), + "vperp" => OptionsDict("ngrid" => 1, + "nelement" => 1), + "vz" => OptionsDict("ngrid" => 4, + "nelement" => 1, + "L" => 8.0, + "bc" => "periodic", + "discretization" => "finite_difference"), + "vzeta" => OptionsDict("ngrid" => 1, + "nelement" => 1), + "vr" => OptionsDict("ngrid" => 1, + "nelement" => 1), + ) test_input_finite_difference_1D1V_split_1_moment = merge(test_input_finite_difference_1D1V, OptionsDict("run_name" => "finite_difference_1D1V_split_1_moment", - "evolve_moments_density" => true)) + "evolve_moments_density" => true)) test_input_finite_difference_1D1V_split_2_moments = merge(test_input_finite_difference_1D1V_split_1_moment, OptionsDict("run_name" => "finite_difference_1D1V_split_2_moments", - "evolve_moments_parallel_flow" => true)) + "evolve_moments_parallel_flow" => true)) test_input_finite_difference_1D1V_split_3_moments = merge(test_input_finite_difference_1D1V_split_2_moments, OptionsDict("run_name" => "finite_difference_1D1V_split_3_moments", - "evolve_moments_parallel_pressure" => true)) + "evolve_moments_parallel_pressure" => true)) test_input_finite_difference_cx0_1D1V = merge(test_input_finite_difference_1D1V, OptionsDict("run_name" => "finite_difference_cx0_1D1V", - "charge_exchange_frequency" => 0.0)) + "charge_exchange_frequency" => 0.0)) test_input_finite_difference_cx0_1D1V_split_1_moment = merge(test_input_finite_difference_cx0_1D1V, OptionsDict("run_name" => "finite_difference_cx0_1D1V_split_1_moment", - "evolve_moments_density" => true)) + "evolve_moments_density" => true)) test_input_finite_difference_cx0_1D1V_split_2_moments = merge(test_input_finite_difference_cx0_1D1V_split_1_moment, OptionsDict("run_name" => "finite_difference_cx0_1D1V_split_2_moments", - "evolve_moments_parallel_flow" => true)) + "evolve_moments_parallel_flow" => true)) test_input_finite_difference_cx0_1D1V_split_3_moments = merge(test_input_finite_difference_cx0_1D1V_split_2_moments, OptionsDict("run_name" => "finite_difference_cx0_1D1V_split_3_moments", - "evolve_moments_parallel_pressure" => true)) + "evolve_moments_parallel_pressure" => true)) test_input_finite_difference = merge(test_input_finite_difference_1D1V, OptionsDict("run_name" => "finite_difference", - "r_ngrid" => 4, - "r_nelement" => 1, - "r_discretization" => "finite_difference", - "vperp_ngrid" => 4, - "vperp_nelement" => 1, - "vperp_discretization" => "finite_difference", - "vz_ngrid" => 4, - "vz_nelement" => 1, - "vz_discretization" => "finite_difference", - "vr_ngrid" => 4, - "vr_nelement" => 1, - "vr_discretization" => "finite_difference", - "vzeta_ngrid" => 4, - "vzeta_nelement" => 1, - "vzeta_discretization" => "finite_difference")) + "r" => OptionsDict("ngrid" => 4, + "nelement" => 1, + "discretization" => "finite_difference"), + "vperp" => OptionsDict("ngrid" => 4, + "nelement" => 1, + "discretization" => "finite_difference"), + "vz" => OptionsDict("ngrid" => 4, + "nelement" => 1, + "discretization" => "finite_difference"), + "vr" => OptionsDict("ngrid" => 4, + "nelement" => 1, + "discretization" => "finite_difference"), + "vzeta" => OptionsDict("ngrid" => 4, + "nelement" => 1, + "discretization" => "finite_difference"), + )) test_input_finite_difference_split_1_moment = merge(test_input_finite_difference, OptionsDict("run_name" => "finite_difference_split_1_moment", - "evolve_moments_density" => true)) + "evolve_moments_density" => true)) test_input_finite_difference_split_2_moments = merge(test_input_finite_difference_split_1_moment, OptionsDict("run_name" => "finite_difference_split_2_moments", - "evolve_moments_parallel_flow" => true)) + "evolve_moments_parallel_flow" => true)) test_input_finite_difference_split_3_moments = merge(test_input_finite_difference_split_2_moments, OptionsDict("run_name" => "finite_difference_split_3_moments", - "evolve_moments_parallel_pressure" => true)) + "evolve_moments_parallel_pressure" => true)) test_input_finite_difference_cx0 = merge(test_input_finite_difference, OptionsDict("run_name" => "finite_difference_cx0", - "charge_exchange_frequency" => 0.0)) + "charge_exchange_frequency" => 0.0)) test_input_finite_difference_cx0_split_1_moment = merge(test_input_finite_difference_cx0, OptionsDict("run_name" => "finite_difference_cx0_split_1_moment", - "evolve_moments_density" => true)) + "evolve_moments_density" => true)) test_input_finite_difference_cx0_split_2_moments = merge(test_input_finite_difference_cx0_split_1_moment, OptionsDict("run_name" => "finite_difference_cx0_split_2_moments", - "evolve_moments_parallel_flow" => true)) + "evolve_moments_parallel_flow" => true)) test_input_finite_difference_cx0_split_3_moments = merge(test_input_finite_difference_cx0_split_2_moments, OptionsDict("run_name" => "finite_difference_cx0_split_3_moments", - "evolve_moments_parallel_pressure" => true)) + "evolve_moments_parallel_pressure" => true)) test_input_chebyshev = merge(test_input_finite_difference, OptionsDict("run_name" => "chebyshev_pseudospectral", - "r_discretization" => "chebyshev_pseudospectral", - "r_ngrid" => 3, - "r_nelement" => 1, - "z_discretization" => "chebyshev_pseudospectral", - "z_ngrid" => 3, - "z_nelement" => 2, - "vperp_discretization" => "chebyshev_pseudospectral", - "vperp_ngrid" => 3, - "vperp_nelement" => 1, - "vpa_discretization" => "chebyshev_pseudospectral", - "vpa_ngrid" => 3, - "vpa_nelement" => 2, - "vz_discretization" => "chebyshev_pseudospectral", - "vz_ngrid" => 3, - "vz_nelement" => 2, - "vr_discretization" => "chebyshev_pseudospectral", - "vr_ngrid" => 3, - "vr_nelement" => 1, - "vzeta_discretization" => "chebyshev_pseudospectral", - "vzeta_ngrid" => 3, - "vzeta_nelement" => 1)) + "r" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 3, + "nelement" => 1), + "z" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 3, + "nelement" => 2), + "vperp" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 3, + "nelement" => 1), + "vpa" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 3, + "nelement" => 2), + "vz" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 3, + "nelement" => 2), + "vr" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 3, + "nelement" => 1), + "vzeta" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 3, + "nelement" => 1), + )) test_input_chebyshev_split_1_moment = merge(test_input_chebyshev, OptionsDict("run_name" => "chebyshev_pseudospectral_split_1_moment", - "evolve_moments_density" => true)) + "evolve_moments_density" => true)) test_input_chebyshev_split_2_moments = merge(test_input_chebyshev_split_1_moment, OptionsDict("run_name" => "chebyshev_pseudospectral_split_2_moments", - "evolve_moments_parallel_flow" => true)) + "evolve_moments_parallel_flow" => true)) test_input_chebyshev_split_3_moments = merge(test_input_chebyshev_split_2_moments, OptionsDict("run_name" => "chebyshev_pseudospectral_split_3_moments", - "evolve_moments_parallel_pressure" => true)) + "evolve_moments_parallel_pressure" => true)) test_input_chebyshev_cx0 = merge(test_input_chebyshev, OptionsDict("run_name" => "chebyshev_pseudospectral_cx0", - "charge_exchange_frequency" => 0.0)) + "charge_exchange_frequency" => 0.0)) test_input_chebyshev_cx0_split_1_moment = merge(test_input_chebyshev_cx0, OptionsDict("run_name" => "chebyshev_pseudospectral_cx0_split_1_moment", - "evolve_moments_density" => true)) + "evolve_moments_density" => true)) test_input_chebyshev_cx0_split_2_moments = merge(test_input_chebyshev_cx0_split_1_moment, OptionsDict("run_name" => "chebyshev_pseudospectral_cx0_split_2_moments", - "evolve_moments_parallel_flow" => true)) + "evolve_moments_parallel_flow" => true)) test_input_chebyshev_cx0_split_3_moments = merge(test_input_chebyshev_cx0_split_2_moments, OptionsDict("run_name" => "chebyshev_pseudospectral_cx0_split_3_moments", - "evolve_moments_parallel_pressure" => true)) + "evolve_moments_parallel_pressure" => true)) test_input_chebyshev_1D1V = merge(test_input_finite_difference_1D1V, OptionsDict("run_name" => "chebyshev_pseudospectral_1D1V", - "z_discretization" => "chebyshev_pseudospectral", - "z_ngrid" => 3, - "z_nelement" => 2, - "vpa_discretization" => "chebyshev_pseudospectral", - "vpa_ngrid" => 3, - "vpa_nelement" => 2, - "vz_discretization" => "chebyshev_pseudospectral", - "vz_ngrid" => 3, - "vz_nelement" => 2)) + "z" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 3, + "nelement" => 2), + "vpa" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 3, + "nelement" => 2), + "vz" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 3, + "nelement" => 2), + )) test_input_chebyshev_1D1V_split_1_moment = merge(test_input_chebyshev_1D1V, OptionsDict("run_name" => "chebyshev_pseudospectral_1D1V_split_1_moment", - "evolve_moments_density" => true)) + "evolve_moments_density" => true)) test_input_chebyshev_1D1V_split_2_moments = merge(test_input_chebyshev_1D1V_split_1_moment, OptionsDict("run_name" => "chebyshev_pseudospectral_1D1V_split_2_moments", - "evolve_moments_parallel_flow" => true)) + "evolve_moments_parallel_flow" => true)) test_input_chebyshev_1D1V_split_3_moments = merge(test_input_chebyshev_1D1V_split_2_moments, OptionsDict("run_name" => "chebyshev_pseudospectral_1D1V_split_3_moments", - "evolve_moments_parallel_pressure" => true, "runtime_plots" => true)) + "evolve_moments_parallel_pressure" => true, "runtime_plots" => true)) test_input_chebyshev_cx0_1D1V = merge(test_input_chebyshev_1D1V, OptionsDict("run_name" => "chebyshev_pseudospectral_cx0_1D1V", - "charge_exchange_frequency" => 0.0)) + "charge_exchange_frequency" => 0.0)) test_input_chebyshev_cx0_1D1V_split_1_moment = merge(test_input_chebyshev_cx0_1D1V, OptionsDict("run_name" => "chebyshev_pseudospectral_cx0_1D1V_split_1_moment", - "evolve_moments_density" => true)) + "evolve_moments_density" => true)) test_input_chebyshev_cx0_1D1V_split_2_moments = merge(test_input_chebyshev_cx0_1D1V_split_1_moment, OptionsDict("run_name" => "chebyshev_pseudospectral_cx0_1D1V_split_2_moments", - "evolve_moments_parallel_flow" => true)) + "evolve_moments_parallel_flow" => true)) test_input_chebyshev_cx0_1D1V_split_3_moments = merge(test_input_chebyshev_cx0_1D1V_split_2_moments, OptionsDict("run_name" => "chebyshev_pseudospectral_cx0_1D1V_split_3_moments", - "evolve_moments_parallel_pressure" => true)) + "evolve_moments_parallel_pressure" => true)) test_input_list = [ test_input_finite_difference, diff --git a/moment_kinetics/debug_test/wall_bc_inputs.jl b/moment_kinetics/debug_test/wall_bc_inputs.jl index 48560dd6d..c7b109ec7 100644 --- a/moment_kinetics/debug_test/wall_bc_inputs.jl +++ b/moment_kinetics/debug_test/wall_bc_inputs.jl @@ -1,6 +1,6 @@ test_type = "Wall boundary conditions" using moment_kinetics.type_definitions: OptionsDict -using moment_kinetics.util: recursive_merge +using moment_kinetics.utils: recursive_merge # default inputs for tests test_input_finite_difference_1D1V = OptionsDict( @@ -23,107 +23,111 @@ test_input_finite_difference_1D1V = OptionsDict( "nwrite" => 2, "type" => "SSPRK2", "split_operators" => false), - "r_ngrid" => 1, - "r_nelement" => 1, - "z_ngrid" => 4, - "z_nelement" => 1, - "z_bc" => "periodic", - "z_discretization" => "finite_difference", - "vpa_ngrid" => 4, - "vpa_nelement" => 8, - "vpa_L" => 8.0, - "vpa_bc" => "zero", - "vpa_discretization" => "finite_difference", - "vperp_ngrid" => 1, - "vperp_nelement" => 1, - "vz_ngrid" => 4, - "vz_nelement" => 1, - "vz_L" => 8.0, - "vz_bc" => "periodic", - "vz_discretization" => "finite_difference", - "vzeta_ngrid" => 1, - "vzeta_nelement" => 1, - "vr_ngrid" => 1, - "vr_nelement" => 1) + "r" => OptionsDict("ngrid" => 1, + "nelement" => 1), + "z" => OptionsDict("ngrid" => 4, + "nelement" => 1, + "bc" => "periodic", + "discretization" => "finite_difference"), + "vpa" => OptionsDict("ngrid" => 4, + "nelement" => 8, + "L" => 8.0, + "bc" => "zero", + "discretization" => "finite_difference"), + "vperp" => OptionsDict("ngrid" => 1, + "nelement" => 1), + "vz" => OptionsDict("ngrid" => 4, + "nelement" => 1, + "L" => 8.0, + "bc" => "periodic", + "discretization" => "finite_difference"), + "vzeta" => OptionsDict("ngrid" => 1, + "nelement" => 1), + "vr" => OptionsDict("ngrid" => 1, + "nelement" => 1), + ) test_input_finite_difference_simple_sheath_1D1V = recursive_merge( test_input_finite_difference_1D1V, OptionsDict("run_name" => "finite_difference_simple_sheath_1D1V", "composition" => OptionsDict("electron_physics" => "boltzmann_electron_response_with_simple_sheath"))) -test_input_finite_difference = merge( +test_input_finite_difference = recursive_merge( test_input_finite_difference_1D1V, OptionsDict("run_name" => "finite_difference", - "r_ngrid" => 4, - "r_nelement" => 1, - "r_discretization" => "finite_difference", - "vperp_ngrid" => 4, - "vperp_nelement" => 1, - "vperp_discretization" => "finite_difference", - "vz_ngrid" => 4, - "vz_nelement" => 1, - "vz_discretization" => "finite_difference", - "vr_ngrid" => 4, - "vr_nelement" => 1, - "vr_discretization" => "finite_difference", - "vzeta_ngrid" => 4, - "vzeta_nelement" => 1, - "vzeta_discretization" => "finite_difference")) + "r" => OptionsDict("ngrid" => 4, + "nelement" => 1, + "discretization" => "finite_difference"), + "vperp" => OptionsDict("ngrid" => 4, + "nelement" => 1, + "discretization" => "finite_difference"), + "vz" => OptionsDict("ngrid" => 4, + "nelement" => 1, + "discretization" => "finite_difference"), + "vr" => OptionsDict("ngrid" => 4, + "nelement" => 1, + "discretization" => "finite_difference"), + "vzeta" => OptionsDict("ngrid" => 4, + "nelement" => 1, + "discretization" => "finite_difference"), + )) test_input_finite_difference_simple_sheath = recursive_merge( test_input_finite_difference, OptionsDict("run_name" => "finite_difference_simple_sheath", "composition" => OptionsDict("electron_physics" => "boltzmann_electron_response_with_simple_sheath"))) -test_input_chebyshev_1D1V = merge( +test_input_chebyshev_1D1V = recursive_merge( test_input_finite_difference_1D1V, OptionsDict("run_name" => "chebyshev_pseudospectral_1D1V", - "z_discretization" => "chebyshev_pseudospectral", - "z_ngrid" => 3, - "z_nelement" => 2, - "vpa_discretization" => "chebyshev_pseudospectral", - "vpa_ngrid" => 3, - "vpa_nelement" => 2, - "vz_discretization" => "chebyshev_pseudospectral", - "vz_ngrid" => 3, - "vz_nelement" => 2)) + "z" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 3, + "nelement" => 2), + "vpa" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 3, + "nelement" => 2), + "vz" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 3, + "nelement" => 2), + )) test_input_chebyshev_split1_1D1V = merge(test_input_chebyshev_1D1V, - OptionsDict("run_name" => "chebyshev_pseudospectral_split1_1D1V", - "evolve_moments_density" => true)) + OptionsDict("run_name" => "chebyshev_pseudospectral_split1_1D1V", + "evolve_moments_density" => true)) test_input_chebyshev_split2_1D1V = merge(test_input_chebyshev_split1_1D1V, - OptionsDict("run_name" => "chebyshev_pseudospectral_split2_1D1V", - "evolve_moments_parallel_flow" => true)) + OptionsDict("run_name" => "chebyshev_pseudospectral_split2_1D1V", + "evolve_moments_parallel_flow" => true)) test_input_chebyshev_split3_1D1V = merge(test_input_chebyshev_split2_1D1V, - OptionsDict("run_name" => "chebyshev_pseudospectral_split3_1D1V", - "evolve_moments_parallel_pressure" => true)) + OptionsDict("run_name" => "chebyshev_pseudospectral_split3_1D1V", + "evolve_moments_parallel_pressure" => true)) test_input_chebyshev_simple_sheath_1D1V = recursive_merge( test_input_chebyshev_1D1V, OptionsDict("run_name" => "chebyshev_pseudospectral_simple_sheath_1D1V", - "composition" => OptionsDict("electron_physics" => "boltzmann_electron_response_with_simple_sheath"))) + "composition" => OptionsDict("electron_physics" => "boltzmann_electron_response_with_simple_sheath"))) -test_input_chebyshev = merge( +test_input_chebyshev = recursive_merge( test_input_chebyshev_1D1V, OptionsDict("run_name" => "chebyshev_pseudospectral", - "r_discretization" => "chebyshev_pseudospectral", - "r_ngrid" => 3, - "r_nelement" => 1, - "vperp_discretization" => "chebyshev_pseudospectral", - "vperp_ngrid" => 3, - "vperp_nelement" => 1, - "vz_discretization" => "chebyshev_pseudospectral", - "vz_ngrid" => 3, - "vz_nelement" => 2, - "vr_discretization" => "chebyshev_pseudospectral", - "vr_ngrid" => 3, - "vr_nelement" => 1, - "vzeta_discretization" => "chebyshev_pseudospectral", - "vzeta_ngrid" => 3, - "vzeta_nelement" => 1)) + "r" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 3, + "nelement" => 1), + "vperp" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 3, + "nelement" => 1), + "vz" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 3, + "nelement" => 2), + "vr" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 3, + "nelement" => 1), + "vzeta" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 3, + "nelement" => 1), + )) test_input_chebyshev_simple_sheath = recursive_merge( test_input_chebyshev, diff --git a/moment_kinetics/test/Krook_collisions_tests.jl b/moment_kinetics/test/Krook_collisions_tests.jl index 5bbc9e49b..b4991f8d7 100644 --- a/moment_kinetics/test/Krook_collisions_tests.jl +++ b/moment_kinetics/test/Krook_collisions_tests.jl @@ -6,15 +6,13 @@ include("setup.jl") using Base.Filesystem: tempname -using moment_kinetics.coordinates: define_coordinate -using moment_kinetics.input_structs: grid_input, advection_input using moment_kinetics.load_data: open_readonly_output_file, load_coordinate_data, load_species_data, load_fields_data, load_ion_moments_data, load_pdf_data, load_neutral_particle_moments_data, load_neutral_pdf_data, load_time_data, load_species_data using moment_kinetics.interpolation: interpolate_to_grid_z, interpolate_to_grid_vpa -using moment_kinetics.type_definitions: mk_float, OptionsDict +using moment_kinetics.type_definitions: mk_float using moment_kinetics.utils: merge_dict_with_kwargs! # Useful parameters @@ -86,76 +84,79 @@ const expected = 0.024284888662941113 0.010011392733734206 0.008423252360063494 0.019281192435730943 0.036719507768509525 0.041644492169994836 0.03692283098105331 0.03638215764882269 0.04191389118981368 0.04071460358290303 0.024284888662941134]) # default inputs for tests -test_input_full_f = Dict("composition" => OptionsDict("n_ion_species" => 1, - "n_neutral_species" => 1, - "electron_physics" => "boltzmann_electron_response", - "T_e" => 1.0, - "T_wall" => 1.0), - "ion_species_1" => OptionsDict("initial_density" => 0.5, - "initial_temperature" => 1.0), - "z_IC_ion_species_1" => OptionsDict("initialization_option" => "sinusoid", - "density_amplitude" => 0.5, - "density_phase" => 0.0, - "upar_amplitude" => 0.0, - "upar_phase" => 0.0, - "temperature_amplitude" => 0.5, - "temperature_phase" => mk_float(π)), - "neutral_species_1" => OptionsDict("initial_density" => 0.5, - "initial_temperature" => 1.0), - "z_IC_neutral_species_1" => OptionsDict("initialization_option" => "sinusoid", - "density_amplitude" => 0.5, - "density_phase" => mk_float(π), - "upar_amplitude" => 0.0, - "upar_phase" => 0.0, - "temperature_amplitude" => 0.5, - "temperature_phase" => 0.0), - "run_name" => "full_f", - "evolve_moments_density" => false, - "evolve_moments_parallel_flow" => false, - "evolve_moments_parallel_pressure" => false, - "evolve_moments_conservation" => true, - "krook_collisions" => OptionsDict("use_krook" => true,"frequency_option" => "reference_parameters"), - "charge_exchange_frequency" => 2*π*0.1, - "ionization_frequency" => 0.0, - "timestepping" => OptionsDict("nstep" => 100, - "dt" => 0.001, - "nwrite" => 100, - "nwrite_dfns" => 100, - "split_operators" => false), - "r_ngrid" => 1, - "r_nelement" => 1, - "r_bc" => "periodic", - "r_discretization" => "chebyshev_pseudospectral", - "z_ngrid" => 9, - "z_nelement" => 4, - "z_bc" => "periodic", - "z_discretization" => "chebyshev_pseudospectral", - "vpa_ngrid" => 17, - "vpa_nelement" => 8, - "vpa_L" => vpa_L, - "vpa_bc" => "periodic", - "vpa_discretization" => "chebyshev_pseudospectral", - "vz_ngrid" => 17, - "vz_nelement" => 8, - "vz_L" => vpa_L, - "vz_bc" => "periodic", - "vz_discretization" => "chebyshev_pseudospectral") +test_input_full_f = OptionsDict("composition" => OptionsDict("n_ion_species" => 1, + "n_neutral_species" => 1, + "electron_physics" => "boltzmann_electron_response", + "T_e" => 1.0, + "T_wall" => 1.0), + "ion_species_1" => OptionsDict("initial_density" => 0.5, + "initial_temperature" => 1.0), + "z_IC_ion_species_1" => OptionsDict("initialization_option" => "sinusoid", + "density_amplitude" => 0.5, + "density_phase" => 0.0, + "upar_amplitude" => 0.0, + "upar_phase" => 0.0, + "temperature_amplitude" => 0.5, + "temperature_phase" => mk_float(π)), + "neutral_species_1" => OptionsDict("initial_density" => 0.5, + "initial_temperature" => 1.0), + "z_IC_neutral_species_1" => OptionsDict("initialization_option" => "sinusoid", + "density_amplitude" => 0.5, + "density_phase" => mk_float(π), + "upar_amplitude" => 0.0, + "upar_phase" => 0.0, + "temperature_amplitude" => 0.5, + "temperature_phase" => 0.0), + "run_name" => "full_f", + "evolve_moments_density" => false, + "evolve_moments_parallel_flow" => false, + "evolve_moments_parallel_pressure" => false, + "evolve_moments_conservation" => true, + "krook_collisions" => OptionsDict("use_krook" => true,"frequency_option" => "reference_parameters"), + "charge_exchange_frequency" => 2*π*0.1, + "ionization_frequency" => 0.0, + "timestepping" => OptionsDict("nstep" => 100, + "dt" => 0.001, + "nwrite" => 100, + "nwrite_dfns" => 100, + "split_operators" => false), + "r" => OptionsDict("ngrid" => 1, + "nelement" => 1, + "bc" => "periodic", + "discretization" => "chebyshev_pseudospectral"), + "z" => OptionsDict("ngrid" => 9, + "nelement" => 4, + "bc" => "periodic", + "discretization" => "chebyshev_pseudospectral"), + "vpa" => OptionsDict("ngrid" => 17, + "nelement" => 8, + "L" => vpa_L, + "bc" => "periodic", + "discretization" => "chebyshev_pseudospectral"), + "vz" => OptionsDict("ngrid" => 17, + "nelement" => 8, + "L" => vpa_L, + "bc" => "periodic", + "discretization" => "chebyshev_pseudospectral") + ) test_input_split_1_moment = - merge(test_input_full_f, - Dict("run_name" => "split_1_moment", + recursive_merge(test_input_full_f, + OptionsDict("run_name" => "split_1_moment", "evolve_moments_density" => true)) test_input_split_2_moments = - merge(test_input_split_1_moment, - Dict("run_name" => "split_2_moments", + recursive_merge(test_input_split_1_moment, + OptionsDict("run_name" => "split_2_moments", "evolve_moments_parallel_flow" => true)) test_input_split_3_moments = - merge(test_input_split_2_moments, - Dict("run_name" => "split_3_moments", - "evolve_moments_parallel_pressure" => true, - "vpa_L" => 12.0, "vz_L" => 12.0)) + recursive_merge(test_input_split_2_moments, + OptionsDict("run_name" => "split_3_moments", + "evolve_moments_parallel_pressure" => true, + "vpa" => OptionsDict("L" => 12.0), + "vz" => OptionsDict("L" => 12.0), + )) """ diff --git a/moment_kinetics/test/braginskii_electrons_imex_tests.jl b/moment_kinetics/test/braginskii_electrons_imex_tests.jl index 02e0cc1a8..d23484000 100644 --- a/moment_kinetics/test/braginskii_electrons_imex_tests.jl +++ b/moment_kinetics/test/braginskii_electrons_imex_tests.jl @@ -9,11 +9,8 @@ include("setup.jl") using Base.Filesystem: tempname using MPI -using moment_kinetics.coordinates: define_coordinate -using moment_kinetics.input_structs: grid_input, advection_input using moment_kinetics.interpolation: interpolate_to_grid_z using moment_kinetics.load_data: get_run_info_no_setup, close_run_info, get_variable -using moment_kinetics.type_definitions: OptionsDict using moment_kinetics.utils: merge_dict_with_kwargs! # default inputs for tests @@ -51,13 +48,13 @@ test_input = OptionsDict( "composition" => OptionsDict("n_ion_species" => 1, "upar_phase" => 0.0, "temperature_amplitude" => 0.0, "temperature_phase" => 0.0), - "vpa_IC_neutral_species_1" => OptionsDict("initialization_option" => "gaussian", - "density_amplitude" => 1.0, - "density_phase" => 0.0, - "upar_amplitude" => 0.0, - "upar_phase" => 0.0, - "temperature_amplitude" => 0.0, - "temperature_phase" => 0.0), + "vz_IC_neutral_species_1" => OptionsDict("initialization_option" => "gaussian", + "density_amplitude" => 1.0, + "density_phase" => 0.0, + "upar_amplitude" => 0.0, + "upar_phase" => 0.0, + "temperature_amplitude" => 0.0, + "temperature_phase" => 0.0), "nu_ei" => 1.0e3, "charge_exchange_frequency" => 0.75, "ionization_frequency" => 0.5, @@ -72,22 +69,22 @@ test_input = OptionsDict( "composition" => OptionsDict("n_ion_species" => 1, "nwrite" => 10000, "high_precision_error_sum" => true), "nonlinear_solver" => OptionsDict("nonlinear_max_iterations" => 100), - "r_ngrid" => 1, - "r_nelement" => 1, - "z_ngrid" => 17, - "z_nelement" => 16, - "z_bc" => "periodic", - "z_discretization" => "chebyshev_pseudospectral", - "vpa_ngrid" => 6, - "vpa_nelement" => 31, - "vpa_L" => 12.0, - "vpa_bc" => "zero", - "vpa_discretization" => "chebyshev_pseudospectral", - "vz_ngrid" => 6, - "vz_nelement" => 31, - "vz_L" => 12.0, - "vz_bc" => "zero", - "vz_discretization" => "chebyshev_pseudospectral", + "r" => OptionsDict("ngrid" => 1, + "nelement" => 1), + "z" => OptionsDict("ngrid" => 17, + "nelement" => 16, + "bc" => "periodic", + "discretization" => "chebyshev_pseudospectral"), + "vpa" => OptionsDict("ngrid" => 6, + "nelement" => 31, + "L" => 12.0, + "bc" => "zero", + "discretization" => "chebyshev_pseudospectral"), + "vz" => OptionsDict("ngrid" => 6, + "nelement" => 31, + "L" => 12.0, + "bc" => "zero", + "discretization" => "chebyshev_pseudospectral"), "ion_numerical_dissipation" => OptionsDict("force_minimum_pdf_value" => 0.0, "vpa_dissipation_coefficient" => 1e0), "neutral_numerical_dissipation" => OptionsDict("force_minimum_pdf_value" => 0.0, @@ -95,7 +92,7 @@ test_input = OptionsDict( "composition" => OptionsDict("n_ion_species" => 1, if global_size[] > 2 && global_size[] % 2 == 0 # Test using distributed-memory - test_input["z_nelement_local"] = test_input["z_nelement"] ÷ 2 + test_input["z"]["nelement_local"] = test_input["z"]["nelement"] ÷ 2 end """ diff --git a/moment_kinetics/test/calculus_tests.jl b/moment_kinetics/test/calculus_tests.jl index ef13b75bb..d6a871cba 100644 --- a/moment_kinetics/test/calculus_tests.jl +++ b/moment_kinetics/test/calculus_tests.jl @@ -2,7 +2,6 @@ module CalculusTests include("setup.jl") -using moment_kinetics.input_structs: grid_input, advection_input using moment_kinetics.coordinates: define_coordinate using moment_kinetics.calculus: derivative!, second_derivative!, integral using moment_kinetics.calculus: laplacian_derivative! @@ -29,24 +28,25 @@ function runtests() # define inputs needed for the test L = 6.0 - bc = "periodic" - # fd_option and adv_input not actually used so given values unimportant + if discretization == "finite_difference" + bc = "periodic" + else + bc = "none" + end fd_option = "" - adv_input = advection_input("default", 1.0, 0.0, 0.0) # create the 'input' struct containing input info needed to create a # coordinate - nelement_local = nelement - nrank_per_block = 0 # dummy value - irank = 0 # dummy value - comm = MPI.COMM_NULL # dummy value - input = grid_input("coord", ngrid, nelement, - nelement_local, nrank_per_block, irank, L, - discretization, fd_option, cheb_option, bc, adv_input, comm, - element_spacing_option) + input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, "nelement"=>nelement, + "L"=>L, + "discretization"=>discretization, + "finite_difference_option"=>fd_option, + "cheb_option"=>cheb_option, + "bc"=>bc, + "element_spacing_option"=>element_spacing_option)) # create the coordinate struct 'x' # This test runs effectively in serial, so use `ignore_MPI=true` to avoid # errors due to communicators not being fully set up. - x, spectral = define_coordinate(input; ignore_MPI=true) + x, spectral = define_coordinate(input, "coord"; ignore_MPI=true, collision_operator_dim=false) # create array for the function f(x) to be differentiated/integrated f = Array{Float64,1}(undef, x.n) # create array for the derivative df/dx @@ -80,25 +80,21 @@ function runtests() # define inputs needed for the test L = 6.0 bc = "periodic" - # fd_option and adv_input not actually used so given values unimportant fd_option = "" - adv_input = advection_input("default", 1.0, 0.0, 0.0) - cheb_option = "" # create the 'input' struct containing input info needed to create a # coordinate nelement_local = nelement - nrank_per_block = 0 # dummy value - irank = 0 # dummy value - comm = MPI.COMM_NULL # dummy value - element_spacing_option = "uniform" # dummy value - input = grid_input("coord", ngrid, nelement, - nelement_local, nrank_per_block, irank, L, - "finite_difference", fd_option, cheb_option, bc, adv_input, comm, - element_spacing_option) + element_spacing_option = "uniform" # dummy value + input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, "nelement"=>nelement, + "L"=>L, + "discretization"=>"finite_difference", + "finite_difference_option"=>fd_option, + "bc"=>bc, + "element_spacing_option"=>element_spacing_option)) # create the coordinate struct 'x' # This test runs effectively in serial, so use `ignore_MPI=true` to avoid # errors due to communicators not being fully set up. - x, spectral = define_coordinate(input; ignore_MPI=true) + x, spectral = define_coordinate(input, "coord"; ignore_MPI=true) # create array for the derivative df/dx and the expected result df = Array{Float64,1}(undef, x.n) @@ -132,25 +128,21 @@ function runtests() # define inputs needed for the test L = 6.0 bc = "periodic" - # fd_option and adv_input not actually used so given values unimportant fd_option = "fourth_order_centered" - adv_input = advection_input("default", 1.0, 0.0, 0.0) - cheb_option = "" # create the 'input' struct containing input info needed to create a # coordinate nelement_local = nelement - nrank_per_block = 0 # dummy value - irank = 0 # dummy value - comm = MPI.COMM_NULL # dummy value element_spacing_option = "uniform" # dummy value - input = grid_input("coord", ngrid, nelement, - nelement_local, nrank_per_block, irank, L, - "finite_difference", fd_option, cheb_option, bc, adv_input, comm, - element_spacing_option) + input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, "nelement"=>nelement, + "L"=>L, + "discretization"=>"finite_difference", + "finite_difference_option"=>fd_option, + "bc"=>bc, + "element_spacing_option"=>element_spacing_option)) # create the coordinate struct 'x' # This test runs effectively in serial, so use `ignore_MPI=true` to avoid # errors due to communicators not being fully set up. - x, spectral = define_coordinate(input; ignore_MPI=true) + x, spectral = define_coordinate(input, "coord"; ignore_MPI=true) # create array for the derivative df/dx and the expected result df = Array{Float64,1}(undef, x.n) @@ -180,25 +172,21 @@ function runtests() # define inputs needed for the test L = 6.0 - # fd_option and adv_input not actually used so given values unimportant fd_option = "" - adv_input = advection_input("default", 1.0, 0.0, 0.0) - cheb_option = "" # create the 'input' struct containing input info needed to create a # coordinate nelement_local = nelement - nrank_per_block = 0 # dummy value - irank = 0 # dummy value - comm = MPI.COMM_NULL # dummy value element_spacing_option = "uniform" # dummy value - input = grid_input("coord", ngrid, nelement, - nelement_local, nrank_per_block, irank, L, - "finite_difference", fd_option, cheb_option, bc, adv_input, comm, - element_spacing_option) + input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, "nelement"=>nelement, + "L"=>L, + "discretization"=>"finite_difference", + "finite_difference_option"=>fd_option, + "bc"=>bc, + "element_spacing_option"=>element_spacing_option)) # create the coordinate struct 'x' # This test runs effectively in serial, so use `ignore_MPI=true` to avoid # errors due to communicators not being fully set up. - x, spectral = define_coordinate(input; ignore_MPI=true) + x, spectral = define_coordinate(input, "coord"; ignore_MPI=true) # create array for the derivative df/dx and the expected result df = Array{Float64,1}(undef, x.n) @@ -237,24 +225,20 @@ function runtests() # define inputs needed for the test L = 6.0 - # fd_option and adv_input not actually used so given values unimportant - adv_input = advection_input("default", 1.0, 0.0, 0.0) - cheb_option = "" # create the 'input' struct containing input info needed to create a # coordinate nelement_local = nelement - nrank_per_block = 0 # dummy value - irank = 0 # dummy value - comm = MPI.COMM_NULL # dummy value element_spacing_option = "uniform" # dummy value - input = grid_input("coord", ngrid, nelement, - nelement_local, nrank_per_block, irank, L, - "finite_difference", fd_option, cheb_option, bc, adv_input, comm, - element_spacing_option) - # create the coordinate struct 'x' + input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, "nelement"=>nelement, + "L"=>L, + "discretization"=>"finite_difference", + "finite_difference_option"=>fd_option, + "bc"=>bc, + "element_spacing_option"=>element_spacing_option)) + # create the coordinate struct 'x' # This test runs effectively in serial, so use `ignore_MPI=true` to avoid # errors due to communicators not being fully set up. - x, spectral = define_coordinate(input; ignore_MPI=true) + x, spectral = define_coordinate(input, "coord"; ignore_MPI=true) # create array for the derivative df/dx and the expected result df = Array{Float64,1}(undef, x.n) @@ -455,24 +439,20 @@ function runtests() # define inputs needed for the test L = 6.0 bc = "periodic" - # fd_option and adv_input not actually used so given values unimportant - fd_option = "" - adv_input = advection_input("default", 1.0, 0.0, 0.0) # create the 'input' struct containing input info needed to create a # coordinate nelement_local = nelement - nrank_per_block = 0 # dummy value - irank = 0 # dummy value - comm = MPI.COMM_NULL # dummy value element_spacing_option = "uniform" - input = grid_input("coord", ngrid, nelement, - nelement_local, nrank_per_block, irank, L, - "chebyshev_pseudospectral", fd_option, cheb_option, bc, adv_input, comm, - element_spacing_option) - # create the coordinate struct 'x' and info for derivatives, etc. + input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, "nelement"=>nelement, + "L"=>L, + "discretization"=>"chebyshev_pseudospectral", + "cheb_option"=>cheb_option, + "bc"=>bc, + "element_spacing_option"=>element_spacing_option)) + # create the coordinate struct 'x' # This test runs effectively in serial, so use `ignore_MPI=true` to avoid # errors due to communicators not being fully set up. - x, spectral = define_coordinate(input; ignore_MPI=true) + x, spectral = define_coordinate(input, "coord"; ignore_MPI=true) offset = randn(rng) f = @. sinpi(2.0 * x.grid / L) + offset @@ -653,24 +633,20 @@ function runtests() # define inputs needed for the test L = 6.0 bc = "periodic" - # fd_option and adv_input not actually used so given values unimportant - fd_option = "" - adv_input = advection_input("default", 1.0, 0.0, 0.0) # create the 'input' struct containing input info needed to create a # coordinate nelement_local = nelement - nrank_per_block = 0 # dummy value - irank = 0 # dummy value - comm = MPI.COMM_NULL # dummy value element_spacing_option = "uniform" - input = grid_input("coord", ngrid, nelement, - nelement_local, nrank_per_block, irank, L, - "chebyshev_pseudospectral", fd_option, cheb_option, bc, adv_input, comm, - element_spacing_option) - # create the coordinate struct 'x' and info for derivatives, etc. + input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, "nelement"=>nelement, + "L"=>L, + "discretization"=>"chebyshev_pseudospectral", + "cheb_option"=>cheb_option, + "bc"=>bc, + "element_spacing_option"=>element_spacing_option)) + # create the coordinate struct 'x' # This test runs effectively in serial, so use `ignore_MPI=true` to avoid # errors due to communicators not being fully set up. - x, spectral = define_coordinate(input; ignore_MPI=true) + x, spectral = define_coordinate(input, "coord"; ignore_MPI=true) offset = randn(rng) f = @. sinpi(2.0 * x.grid / L) + offset @@ -699,23 +675,19 @@ function runtests() # define inputs needed for the test L = 1.0 bc = "constant" - # fd_option and adv_input not actually used so given values unimportant - fd_option = "" - adv_input = advection_input("default", 1.0, 0.0, 0.0) # create the 'input' struct containing input info needed to create a # coordinate nelement_local = nelement - nrank_per_block = 0 # dummy value - irank = 0 # dummy value - comm = MPI.COMM_NULL # dummy value - input = grid_input("coord", ngrid, nelement, - nelement_local, nrank_per_block, irank, L, - "chebyshev_pseudospectral", fd_option, cheb_option, bc, adv_input, comm, - element_spacing_option) - # create the coordinate struct 'x' and info for derivatives, etc. + input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, "nelement"=>nelement, + "L"=>L, + "discretization"=>"chebyshev_pseudospectral", + "cheb_option"=>cheb_option, + "bc"=>bc, + "element_spacing_option"=>element_spacing_option)) + # create the coordinate struct 'x' # This test runs effectively in serial, so use `ignore_MPI=true` to avoid # errors due to communicators not being fully set up. - x, spectral = define_coordinate(input; ignore_MPI=true) + x, spectral = define_coordinate(input, "coord"; ignore_MPI=true) # test polynomials up to order ngrid-1 for n ∈ 0:ngrid-1 # create array for the function f(x) to be differentiated/integrated @@ -751,23 +723,19 @@ function runtests() # define inputs needed for the test L = 1.0 bc = "constant" - # fd_option and adv_input not actually used so given values unimportant - fd_option = "" - adv_input = advection_input("default", 1.0, 0.0, 0.0) # create the 'input' struct containing input info needed to create a # coordinate nelement_local = nelement - nrank_per_block = 0 # dummy value - irank = 0 # dummy value - comm = MPI.COMM_NULL # dummy value - input = grid_input("coord", ngrid, nelement, - nelement_local, nrank_per_block, irank, L, - "chebyshev_pseudospectral", fd_option, cheb_option, bc, adv_input, comm, - element_spacing_option) - # create the coordinate struct 'x' and info for derivatives, etc. + input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, "nelement"=>nelement, + "L"=>L, + "discretization"=>"chebyshev_pseudospectral", + "cheb_option"=>cheb_option, + "bc"=>bc, + "element_spacing_option"=>element_spacing_option)) + # create the coordinate struct 'x' # This test runs effectively in serial, so use `ignore_MPI=true` to avoid # errors due to communicators not being fully set up. - x, spectral = define_coordinate(input; ignore_MPI=true) + x, spectral = define_coordinate(input, "coord"; ignore_MPI=true) # test polynomials up to order ngrid-1 for n ∈ 0:ngrid-1 # create array for the function f(x) to be differentiated/integrated @@ -887,25 +855,17 @@ function runtests() # define inputs needed for the test L = 6.0 bc = "periodic" - # fd_option and adv_input not actually used so given values unimportant - fd_option = "" - adv_input = advection_input("default", 1.0, 0.0, 0.0) - cheb_option = "" # create the 'input' struct containing input info needed to create a # coordinate nelement_local = nelement - nrank_per_block = 0 # dummy value - irank = 0 # dummy value - comm = MPI.COMM_NULL # dummy value - element_spacing_option = "uniform" - input = grid_input("coord", ngrid, nelement, - nelement_local, nrank_per_block, irank, L, - "gausslegendre_pseudospectral", fd_option, cheb_option, bc, adv_input, comm, - element_spacing_option) - # create the coordinate struct 'x' and info for derivatives, etc. + input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, "nelement"=>nelement, + "L"=>L, + "discretization"=>"gausslegendre_pseudospectral", + "bc"=>bc)) + # create the coordinate struct 'x' # This test runs effectively in serial, so use `ignore_MPI=true` to avoid # errors due to communicators not being fully set up. - x, spectral = define_coordinate(input; ignore_MPI=true, collision_operator_dim=false) + x, spectral = define_coordinate(input, "coord"; ignore_MPI=true, collision_operator_dim=false) offset = randn(rng) f = @. sinpi(2.0 * x.grid / L) + offset @@ -1006,25 +966,19 @@ function runtests() # define inputs needed for the test L = 6.0 bc = "periodic" - # fd_option and adv_input not actually used so given values unimportant - fd_option = "" - adv_input = advection_input("default", 1.0, 0.0, 0.0) - cheb_option = "" # create the 'input' struct containing input info needed to create a # coordinate nelement_local = nelement - nrank_per_block = 0 # dummy value - irank = 0 # dummy value - comm = MPI.COMM_NULL # dummy value element_spacing_option = "uniform" - input = grid_input("coord", ngrid, nelement, - nelement_local, nrank_per_block, irank, L, - "gausslegendre_pseudospectral", fd_option, cheb_option, bc, adv_input, comm, - element_spacing_option) - # create the coordinate struct 'x' and info for derivatives, etc. + input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, "nelement"=>nelement, + "L"=>L, + "discretization"=>"gausslegendre_pseudospectral", + "bc"=>bc, + "element_spacing_option"=>element_spacing_option)) + # create the coordinate struct 'x' # This test runs effectively in serial, so use `ignore_MPI=true` to avoid # errors due to communicators not being fully set up. - x, spectral = define_coordinate(input; ignore_MPI=true, collision_operator_dim=false) + x, spectral = define_coordinate(input, "coord"; ignore_MPI=true, collision_operator_dim=false) offset = randn(rng) f = @. sinpi(2.0 * x.grid / L) + offset @@ -1053,24 +1007,18 @@ function runtests() # define inputs needed for the test L = 1.0 bc = "constant" - # fd_option and adv_input not actually used so given values unimportant - fd_option = "" - adv_input = advection_input("default", 1.0, 0.0, 0.0) - cheb_option = "" #not used # create the 'input' struct containing input info needed to create a # coordinate nelement_local = nelement - nrank_per_block = 0 # dummy value - irank = 0 # dummy value - comm = MPI.COMM_NULL # dummy value - input = grid_input("coord", ngrid, nelement, - nelement_local, nrank_per_block, irank, L, - "gausslegendre_pseudospectral", fd_option, cheb_option, bc, adv_input, comm, - element_spacing_option) - # create the coordinate struct 'x' and info for derivatives, etc. + input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, "nelement"=>nelement, + "L"=>L, + "discretization"=>"gausslegendre_pseudospectral", + "bc"=>bc, + "element_spacing_option"=>element_spacing_option)) + # create the coordinate struct 'x' # This test runs effectively in serial, so use `ignore_MPI=true` to avoid # errors due to communicators not being fully set up. - x, spectral = define_coordinate(input; ignore_MPI=true, collision_operator_dim=false) + x, spectral = define_coordinate(input, "coord"; ignore_MPI=true, collision_operator_dim=false) # test polynomials up to order ngrid-1 for n ∈ 0:ngrid-1 # create array for the function f(x) to be differentiated/integrated @@ -1106,24 +1054,18 @@ function runtests() # define inputs needed for the test L = 1.0 bc = "constant" - # fd_option and adv_input not actually used so given values unimportant - fd_option = "" - adv_input = advection_input("default", 1.0, 0.0, 0.0) - cheb_option = "" # not used # create the 'input' struct containing input info needed to create a # coordinate nelement_local = nelement - nrank_per_block = 0 # dummy value - irank = 0 # dummy value - comm = MPI.COMM_NULL # dummy value - input = grid_input("coord", ngrid, nelement, - nelement_local, nrank_per_block, irank, L, - "gausslegendre_pseudospectral", fd_option, cheb_option, bc, adv_input, comm, - element_spacing_option) - # create the coordinate struct 'x' and info for derivatives, etc. + input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, "nelement"=>nelement, + "L"=>L, + "discretization"=>"gausslegendre_pseudospectral", + "bc"=>bc, + "element_spacing_option"=>element_spacing_option)) + # create the coordinate struct 'x' # This test runs effectively in serial, so use `ignore_MPI=true` to avoid # errors due to communicators not being fully set up. - x, spectral = define_coordinate(input; ignore_MPI=true, collision_operator_dim=false) + x, spectral = define_coordinate(input, "coord"; ignore_MPI=true, collision_operator_dim=false) # test polynomials up to order ngrid-1 for n ∈ 0:ngrid-1 # create array for the function f(x) to be differentiated/integrated @@ -1322,24 +1264,20 @@ function runtests() # define inputs needed for the test L = 6.0 bc = "periodic" - # fd_option and adv_input not actually used so given values unimportant - fd_option = "" - adv_input = advection_input("default", 1.0, 0.0, 0.0) # create the 'input' struct containing input info needed to create a # coordinate nelement_local = nelement - nrank_per_block = 0 # dummy value - irank = 0 # dummy value - comm = MPI.COMM_NULL # dummy value element_spacing_option = "uniform" - input = grid_input("coord", ngrid, nelement, - nelement_local, nrank_per_block, irank, L, - "chebyshev_pseudospectral", fd_option, cheb_option, bc, adv_input, comm, - element_spacing_option) - # create the coordinate struct 'x' and info for derivatives, etc. + input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, "nelement"=>nelement, + "L"=>L, + "discretization"=>"chebyshev_pseudospectral", + "cheb_option"=>cheb_option, + "bc"=>bc, + "element_spacing_option"=>element_spacing_option)) + # create the coordinate struct 'x' # This test runs effectively in serial, so use `ignore_MPI=true` to avoid # errors due to communicators not being fully set up. - x, spectral = define_coordinate(input; ignore_MPI=true) + x, spectral = define_coordinate(input, "coord"; ignore_MPI=true) offset = randn(rng) f = @. sinpi(2.0 * x.grid / L) + offset @@ -1419,24 +1357,23 @@ function runtests() # define inputs needed for the test L = 6.0 bc = "zero" - # fd_option and adv_input not actually used so given values unimportant - fd_option = "" - adv_input = advection_input("default", 1.0, 0.0, 0.0) # create the 'input' struct containing input info needed to create a # coordinate nelement_local = nelement - nrank_per_block = 0 # dummy value - irank = 0 # dummy value - comm = MPI.COMM_NULL # dummy value element_spacing_option = "uniform" - input = grid_input("vperp", ngrid, nelement, - nelement_local, nrank_per_block, irank, L, - "chebyshev_pseudospectral", fd_option, cheb_option, bc, adv_input, comm, - element_spacing_option) # create the coordinate struct 'x' and info for derivatives, etc. # This test runs effectively in serial, so use `ignore_MPI=true` to avoid # errors due to communicators not being fully set up. - x, spectral = define_coordinate(input; ignore_MPI=true) + input = OptionsDict("vperp" => OptionsDict("ngrid"=>ngrid, "nelement"=>nelement, + "L"=>L, + "discretization"=>"chebyshev_pseudospectral", + "cheb_option"=>cheb_option, + "bc"=>bc, + "element_spacing_option"=>element_spacing_option)) + # create the coordinate struct 'x' + # This test runs effectively in serial, so use `ignore_MPI=true` to avoid + # errors due to communicators not being fully set up. + x, spectral = define_coordinate(input, "vperp"; ignore_MPI=true) f = @. exp(-x.grid^2) expected_d2f = @. 4.0*(x.grid^2 - 1.0)*exp(-x.grid^2) @@ -1526,25 +1463,19 @@ function runtests() # define inputs needed for the test L = 6.0 bc = "periodic" - # fd_option and adv_input not actually used so given values unimportant - fd_option = "" - adv_input = advection_input("default", 1.0, 0.0, 0.0) - cheb_option = "" # create the 'input' struct containing input info needed to create a # coordinate nelement_local = nelement - nrank_per_block = 0 # dummy value - irank = 0 # dummy value - comm = MPI.COMM_NULL # dummy value element_spacing_option = "uniform" - input = grid_input("coord", ngrid, nelement, - nelement_local, nrank_per_block, irank, L, - "gausslegendre_pseudospectral", fd_option, cheb_option, bc, adv_input, comm, - element_spacing_option) - # create the coordinate struct 'x' and info for derivatives, etc. + input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, "nelement"=>nelement, + "L"=>L, + "discretization"=>"gausslegendre_pseudospectral", + "bc"=>bc, + "element_spacing_option"=>element_spacing_option)) + # create the coordinate struct 'x' # This test runs effectively in serial, so use `ignore_MPI=true` to avoid # errors due to communicators not being fully set up. - x, spectral = define_coordinate(input; ignore_MPI=true, collision_operator_dim=false) + x, spectral = define_coordinate(input, "coord"; ignore_MPI=true, collision_operator_dim=false) offset = randn(rng) f = @. sinpi(2.0 * x.grid / L) + offset @@ -1561,17 +1492,17 @@ function runtests() end end - @testset "GaussLegendre pseudospectral cylindrical laplacian derivatives (4 argument), zero" verbose=false begin + @testset "GaussLegendre pseudospectral cylindrical laplacian derivatives (4 argument), zero" verbose=false begin @testset "$nelement $ngrid" for (nelement, ngrid, rtol) ∈ ( - (1, 8, 5.e-2), + (1, 8, 1.e-1), (1, 9, 1.e-1), (1, 10, 2.e-1), - (1, 11, 5.e-2), + (1, 11, 6.e-2), (1, 12, 5.e-2), (1, 13, 5.e-2), (1, 14, 5.e-2), - (1, 15, 5.e-3), + (1, 15, 1.e-2), (1, 16, 5.e-2), (1, 17, 5.e-3), @@ -1633,25 +1564,22 @@ function runtests() # define inputs needed for the test L = 6.0 bc = "zero" - # fd_option and adv_input not actually used so given values unimportant - fd_option = "" - adv_input = advection_input("default", 1.0, 0.0, 0.0) - cheb_option = "" # create the 'input' struct containing input info needed to create a # coordinate nelement_local = nelement - nrank_per_block = 0 # dummy value - irank = 0 # dummy value - comm = MPI.COMM_NULL # dummy value element_spacing_option = "uniform" - input = grid_input("vperp", ngrid, nelement, - nelement_local, nrank_per_block, irank, L, - "gausslegendre_pseudospectral", fd_option, cheb_option, bc, adv_input, comm, - element_spacing_option) # create the coordinate struct 'x' and info for derivatives, etc. # This test runs effectively in serial, so use `ignore_MPI=true` to avoid # errors due to communicators not being fully set up. - x, spectral = define_coordinate(input; ignore_MPI=true, collision_operator_dim=false) + input = OptionsDict("vperp" => OptionsDict("ngrid"=>ngrid, "nelement"=>nelement, + "L"=>L, + "discretization"=>"gausslegendre_pseudospectral", + "bc"=>bc, + "element_spacing_option"=>element_spacing_option)) + # create the coordinate struct 'x' + # This test runs effectively in serial, so use `ignore_MPI=true` to avoid + # errors due to communicators not being fully set up. + x, spectral = define_coordinate(input, "vperp"; ignore_MPI=true, collision_operator_dim=false) f = @. exp(-x.grid^2) expected_d2f = @. 4.0*(x.grid^2 - 1.0)*exp(-x.grid^2) diff --git a/moment_kinetics/test/fokker_planck_tests.jl b/moment_kinetics/test/fokker_planck_tests.jl index c5b192bac..8f2dafbd7 100644 --- a/moment_kinetics/test/fokker_planck_tests.jl +++ b/moment_kinetics/test/fokker_planck_tests.jl @@ -8,7 +8,6 @@ using LinearAlgebra: mul!, ldiv! using moment_kinetics.communication using moment_kinetics.looping using moment_kinetics.array_allocation: allocate_float, allocate_shared_float -using moment_kinetics.input_structs: grid_input, advection_input using moment_kinetics.coordinates: define_coordinate using moment_kinetics.type_definitions: mk_float, mk_int using moment_kinetics.velocity_moments: get_density, get_upar, get_ppar, get_pperp, get_pressure @@ -33,32 +32,27 @@ function create_grids(ngrid,nelement_vpa,nelement_vperp; nelement_local_vperp = nelement_vperp # number of elements per rank nelement_global_vperp = nelement_local_vperp # total number of elements bc = "zero" # used only in derivative! functions - # fd_option and adv_input not actually used so given values unimportant #discretization = "chebyshev_pseudospectral" discretization = "gausslegendre_pseudospectral" - fd_option = "fourth_order_centered" - cheb_option = "matrix" - adv_input = advection_input("default", 1.0, 0.0, 0.0) - nrank = 1 - irank = 0 - comm = MPI.COMM_NULL # create the 'input' struct containing input info needed to create a # coordinate element_spacing_option = "uniform" - vpa_input = grid_input("vpa", ngrid, nelement_global_vpa, nelement_local_vpa, - nrank, irank, Lvpa, discretization, fd_option, cheb_option, bc, adv_input,comm,element_spacing_option) - vperp_input = grid_input("vperp", ngrid, nelement_global_vperp, nelement_local_vperp, - nrank, irank, Lvperp, discretization, fd_option, cheb_option, bc, adv_input,comm,element_spacing_option) - # create the coordinate struct 'x' - #println("made inputs") - #println("vpa: ngrid: ",ngrid," nelement: ",nelement_local_vpa, " Lvpa: ",Lvpa) - #println("vperp: ngrid: ",ngrid," nelement: ",nelement_local_vperp, " Lvperp: ",Lvperp) + coords_input = OptionsDict( + "vperp"=>OptionsDict("ngrid"=>ngrid, "nelement"=>nelement_global_vperp, + "nelement_local"=>nelement_local_vperp, "L"=>Lvperp, + "discretization"=>discretization, "bc"=>bc, + "element_spacing_option"=>element_spacing_option), + "vpa"=>OptionsDict("ngrid"=>ngrid, "nelement"=>nelement_global_vpa, + "nelement_local"=>nelement_local_vpa, "L"=>Lvpa, + "discretization"=>discretization, "bc"=>bc, + "element_spacing_option"=>element_spacing_option), + ) # Set up MPI initialize_comms!() setup_distributed_memory_MPI(1,1,1,1) - vpa, vpa_spectral = define_coordinate(vpa_input) - vperp, vperp_spectral = define_coordinate(vperp_input) + vperp, vperp_spectral = define_coordinate(coords_input, "vperp") + vpa, vpa_spectral = define_coordinate(coords_input, "vpa") looping.setup_loop_ranges!(block_rank[], block_size[]; s=1, sn=1, r=1, z=1, vperp=vperp.n, vpa=vpa.n, diff --git a/moment_kinetics/test/fokker_planck_time_evolution_tests.jl b/moment_kinetics/test/fokker_planck_time_evolution_tests.jl index b306e5baf..981d1e228 100644 --- a/moment_kinetics/test/fokker_planck_time_evolution_tests.jl +++ b/moment_kinetics/test/fokker_planck_time_evolution_tests.jl @@ -4,13 +4,11 @@ include("setup.jl") using Base.Filesystem: tempname using MPI -using moment_kinetics.coordinates: define_coordinate -using moment_kinetics.input_structs: grid_input, advection_input using moment_kinetics.load_data: open_readonly_output_file, load_coordinate_data, load_species_data, load_fields_data, load_ion_moments_data, load_pdf_data, load_time_data, load_species_data -using moment_kinetics.type_definitions: mk_float, OptionsDict +using moment_kinetics.type_definitions: mk_float using moment_kinetics.utils: merge_dict_with_kwargs! const analytical_rtol = 3.e-2 @@ -224,51 +222,53 @@ for k in 1:ntind end """ # default inputs for tests -test_input_gauss_legendre = Dict("run_name" => "gausslegendre_pseudospectral", - "base_directory" => test_output_directory, - "composition" => OptionsDict("n_ion_species" => 1, - "n_neutral_species" => 0, - "electron_physics" => "boltzmann_electron_response", - "T_e" => 1.0), - "ion_species_1" => OptionsDict("initial_density" => 0.5, - "initial_temperature" => 1.0), - "z_IC_ion_species_1" => OptionsDict("initialization_option" => "sinusoid", - "density_amplitude" => 0.0, - "density_phase" => 0.0, - "upar_amplitude" => 0.0, - "upar_phase" => 0.0, - "temperature_amplitude" => 0.0, - "temperature_phase" => 0.0), - "vpa_ngrid" => 3, - "vpa_L" => 6.0, - "vpa_nelement" => 6, - "vpa_bc" => "zero", - "vpa_discretization" => "gausslegendre_pseudospectral", - "vperp_ngrid" => 3, - "vperp_nelement" => 3, - "vperp_L" => 3.0, - "vperp_discretization" => "gausslegendre_pseudospectral", - "ionization_frequency" => 0.0, - "charge_exchange_frequency" => 0.0, - "fokker_planck_collisions" => OptionsDict("use_fokker_planck" => true, "nuii" => 1.0, "frequency_option" => "manual"), - "evolve_moments_parallel_pressure" => false, - "evolve_moments_conservation" => false, - "evolve_moments_parallel_flow" => false, - "z_discretization" => "chebyshev_pseudospectral", - "evolve_moments_density" => false, - "z_ngrid" => 1, - "z_nelement_local" => 1, - "z_nelement" => 1, - "z_bc" => "wall", - "r_discretization" => "chebyshev_pseudospectral", - "r_ngrid" => 1, - "r_nelement" => 1, - "r_nelement_local" => 1, - "r_bc" => "periodic", - "timestepping" => OptionsDict("dt" => 0.01, - "nstep" => 5000, - "nwrite" => 5000, - "nwrite_dfns" => 5000 )) +test_input_gauss_legendre = OptionsDict("run_name" => "gausslegendre_pseudospectral", + "base_directory" => test_output_directory, + "composition" => OptionsDict("n_ion_species" => 1, + "n_neutral_species" => 0, + "electron_physics" => "boltzmann_electron_response", + "T_e" => 1.0), + "ion_species_1" => OptionsDict("initial_density" => 0.5, + "initial_temperature" => 1.0), + "z_IC_ion_species_1" => OptionsDict("initialization_option" => "sinusoid", + "density_amplitude" => 0.0, + "density_phase" => 0.0, + "upar_amplitude" => 0.0, + "upar_phase" => 0.0, + "temperature_amplitude" => 0.0, + "temperature_phase" => 0.0), + + "vpa" => OptionsDict("ngrid" => 3, + "L" => 6.0, + "nelement" => 6, + "bc" => "zero", + "discretization" => "gausslegendre_pseudospectral"), + "vperp" => OptionsDict("ngrid" => 3, + "nelement" => 3, + "L" => 3.0, + "discretization" => "gausslegendre_pseudospectral"), + "ionization_frequency" => 0.0, + "charge_exchange_frequency" => 0.0, + "fokker_planck_collisions" => OptionsDict("use_fokker_planck" => true, "nuii" => 1.0, "frequency_option" => "manual"), + "evolve_moments_parallel_pressure" => false, + "evolve_moments_conservation" => false, + "evolve_moments_parallel_flow" => false, + "evolve_moments_density" => false, + "z" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 1, + "nelement_local" => 1, + "nelement" => 1, + "bc" => "wall"), + "r" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 1, + "nelement" => 1, + "nelement_local" => 1, + "bc" => "periodic"), + "timestepping" => OptionsDict("dt" => 0.01, + "nstep" => 5000, + "nwrite" => 5000, + "nwrite_dfns" => 5000), + ) """ @@ -288,12 +288,16 @@ function run_test(test_input, expected, rtol, atol, upar_rtol=nothing; args...) end # Convert keyword arguments to a unique name + function stringify_arg(key, value) + if isa(value, AbstractDict) + return string(string(key)[1], (stringify_arg(k, v) for (k, v) in value)...) + else + return string(string(key)[1], value) + end + end name = input["run_name"] if length(args) > 0 - name = string(name, "_", (string(k, "-", v, "_") for (k, v) in args)...) - - # Remove trailing "_" - name = chop(name) + name = string(name, "_", (stringify_arg(k, v) for (k, v) in args)...) end # Provide some progress info @@ -423,22 +427,21 @@ function runtests() vperp_bc = "zero-impose-regularity" run_test(test_input_gauss_legendre, expected_zero_impose_regularity, 1.0e-14, 1.0e-14; - vperp_bc=vperp_bc) + vperp=OptionsDict("bc" => vperp_bc)) end @testset "Gauss Legendre no enforced regularity condition at vperp = 0" begin run_name = "gausslegendre_pseudospectral_no_regularity" vperp_bc = "zero" run_test(test_input_gauss_legendre, expected_zero, - 1.0e-14, 1.0e-14; vperp_bc=vperp_bc) + 1.0e-14, 1.0e-14; vperp=OptionsDict("bc" => vperp_bc)) end @testset "Gauss Legendre no (explicitly) enforced boundary conditions" begin run_name = "gausslegendre_pseudospectral_none_bc" vperp_bc = "none" vpa_bc = "none" - run_test(test_input_gauss_legendre, - expected_none_bc, - 1.0e-14, 1.0e-14; vperp_bc=vperp_bc, vpa_bc=vpa_bc) + run_test(test_input_gauss_legendre, expected_none_bc, 1.0e-14, 1.0e-14; + vperp=OptionsDict("bc" => vperp_bc), vpa=OptionsDict("bc" => vpa_bc)) end end end diff --git a/moment_kinetics/test/gyroaverage_tests.jl b/moment_kinetics/test/gyroaverage_tests.jl index c4f2e5a2a..44c96e3a2 100644 --- a/moment_kinetics/test/gyroaverage_tests.jl +++ b/moment_kinetics/test/gyroaverage_tests.jl @@ -16,7 +16,7 @@ using moment_kinetics.looping using moment_kinetics.array_allocation: allocate_float, allocate_shared_float using moment_kinetics.gyroaverages: gyroaverage_pdf! using moment_kinetics.gyroaverages: gyroaverage_field!, init_gyro_operators -using moment_kinetics.type_definitions: mk_float, mk_int, OptionsDict +using moment_kinetics.type_definitions: mk_float, mk_int using moment_kinetics.species_input: get_species_input print_test_results = false @@ -107,14 +107,9 @@ function gyroaverage_test(absolute_error; rhostar=0.1, pitch=0.5, ngrid=5, kr=2, gyrophase_nelement_global = gyrophase_nelement_local # total number of elements gyrophase_discretization = "finite_difference" gyrophase_L = 2.0*pi + gyrophase_bc = "periodic" - # fd_option and adv_input not actually used so given values unimportant - fd_option = "fourth_order_centered" cheb_option = "matrix" - adv_input = advection_input("default", 1.0, 0.0, 0.0) - nrank = 1 - irank = 0#1 - comm = MPI.COMM_NULL element_spacing_option = "uniform" # create the 'input' struct containing input info needed to create a # coordinate @@ -124,23 +119,50 @@ function gyroaverage_test(absolute_error; rhostar=0.1, pitch=0.5, ngrid=5, kr=2, setup_distributed_memory_MPI(1,1,1,1) irank_z, nrank_z, comm_sub_z, irank_r, nrank_r, comm_sub_r = setup_distributed_memory_MPI(z_nelement_global,z_nelement_local,r_nelement_global,r_nelement_local) - r_input = grid_input("r", r_ngrid, r_nelement_global, r_nelement_local, - nrank_r, irank_r, r_L, discretization, fd_option, cheb_option, r_bc, adv_input,comm_sub_r,element_spacing_option) - z_input = grid_input("z", z_ngrid, z_nelement_global, z_nelement_local, - nrank_z, irank_z, z_L, discretization, fd_option, cheb_option, z_bc, adv_input,comm_sub_z,element_spacing_option) - vperp_input = grid_input("vperp", vperp_ngrid, vperp_nelement_global, vperp_nelement_local, - nrank, irank, vperp_L, discretization, fd_option, cheb_option, vperp_bc, adv_input,comm,element_spacing_option) - vpa_input = grid_input("vpa", vpa_ngrid, vpa_nelement_global, vpa_nelement_local, - nrank, irank, vpa_L, discretization, fd_option, cheb_option, vpa_bc, adv_input,comm,element_spacing_option) - gyrophase_input = grid_input("gyrophase", gyrophase_ngrid, gyrophase_nelement_global, gyrophase_nelement_local, - nrank, irank, gyrophase_L, gyrophase_discretization, fd_option, cheb_option, "periodic", adv_input,comm,element_spacing_option) + coords_input = OptionsDict( + "r"=>OptionsDict("ngrid"=>r_ngrid, "nelement"=>r_nelement_global, + "nelement_local"=>r_nelement_local, "L"=>r_L, + "discretization"=>discretization, "cheb_option"=>cheb_option, + "bc"=>r_bc, + "element_spacing_option"=>element_spacing_option), + "z"=>OptionsDict("ngrid"=>z_ngrid, "nelement"=>z_nelement_global, + "nelement_local"=>z_nelement_local, "L"=>z_L, + "discretization"=>discretization, "cheb_option"=>cheb_option, + "bc"=>z_bc, "element_spacing_option"=>element_spacing_option), + "vperp"=>OptionsDict("ngrid"=>vperp_ngrid, "nelement"=>vperp_nelement_global, + "nelement_local"=>vperp_nelement_local, "L"=>vperp_L, + "discretization"=>discretization, + "cheb_option"=>cheb_option, "bc"=>vperp_bc, + "element_spacing_option"=>element_spacing_option), + "vpa"=>OptionsDict("ngrid"=>vpa_ngrid, "nelement"=>vpa_nelement_global, + "nelement_local"=>vpa_nelement_local, "L"=>vpa_L, + "discretization"=>discretization, + "cheb_option"=>cheb_option, "bc"=>vpa_bc, + "element_spacing_option"=>element_spacing_option), + "gyrophase"=>OptionsDict("ngrid"=>gyrophase_ngrid, + "nelement"=>gyrophase_nelement_global, + "nelement_local"=>gyrophase_nelement_local, + "L"=>gyrophase_L, "discretization"=>discretization, + "cheb_option"=>cheb_option, "bc"=>gyrophase_bc, + "element_spacing_option"=>element_spacing_option), + ) # create the coordinate structs - r, r_spectral = define_coordinate(r_input; collision_operator_dim=false, run_directory=test_output_directory) - z, z_spectral = define_coordinate(z_input; collision_operator_dim=false, run_directory=test_output_directory) - vperp, vperp_spectral = define_coordinate(vperp_input; collision_operator_dim=false, run_directory=test_output_directory) - vpa, vpa_spectral = define_coordinate(vpa_input; collision_operator_dim=false, run_directory=test_output_directory) - gyrophase, gyrophase_spectral = define_coordinate(gyrophase_input; collision_operator_dim=false, run_directory=test_output_directory) + r, r_spectral = define_coordinate(coords_input, "r"; collision_operator_dim=false, + run_directory=test_output_directory, + irank=irank_r, nrank=nrank_r, comm=comm_sub_r) + z, z_spectral = define_coordinate(coords_input, "z"; collision_operator_dim=false, + run_directory=test_output_directory, + irank=irank_z, nrank=nrank_z, comm=comm_sub_z) + vperp, vperp_spectral = define_coordinate(coords_input, "vperp"; + collision_operator_dim=false, + run_directory=test_output_directory) + vpa, vpa_spectral = define_coordinate(coords_input, "vpa"; + collision_operator_dim=false, + run_directory=test_output_directory) + gyrophase, gyrophase_spectral = define_coordinate(coords_input, "gyrophase"; + collision_operator_dim=false, + run_directory=test_output_directory) # create test geometry option = "constant-helical" diff --git a/moment_kinetics/test/harrisonthompson.jl b/moment_kinetics/test/harrisonthompson.jl index eef9bd950..3b0accfc5 100644 --- a/moment_kinetics/test/harrisonthompson.jl +++ b/moment_kinetics/test/harrisonthompson.jl @@ -11,7 +11,6 @@ using SpecialFunctions: dawson using moment_kinetics.load_data: open_readonly_output_file using moment_kinetics.load_data: load_fields_data, load_time_data using moment_kinetics.load_data: load_species_data, load_coordinate_data -using moment_kinetics.type_definitions: OptionsDict using moment_kinetics.utils: merge_dict_with_kwargs! ionization_frequency = 0.688 @@ -96,56 +95,60 @@ test_input_finite_difference = Dict("composition" => OptionsDict("n_ion_species" "dt" => 0.0005, "nwrite" => 9000, "split_operators" => false), - "r_ngrid" => 1, - "r_nelement" => 1, - "r_bc" => "periodic", - "r_discretization" => "finite_difference", - "z_ngrid" => 100, - "z_nelement" => 1, - "z_bc" => "wall", - "z_discretization" => "finite_difference", - "vpa_ngrid" => 200, - "vpa_nelement" => 1, - "vpa_L" => 8.0, - "vpa_bc" => "zero", - "vpa_discretization" => "finite_difference", - "vz_ngrid" => 200, - "vz_nelement" => 1, - "vz_L" => 8.0, - "vz_bc" => "zero", - "vz_discretization" => "finite_difference", - "ion_source" => Dict("active" => true, - "source_strength" => ionization_frequency, - "source_T" => 0.25, - "z_profile" => "constant", - "r_profile" => "constant"), + "r" => OptionsDict("ngrid" => 1, + "nelement" => 1, + "bc" => "periodic", + "discretization" => "finite_difference"), + "z" => OptionsDict("ngrid" => 100, + "nelement" => 1, + "bc" => "wall", + "discretization" => "finite_difference"), + "vpa" => OptionsDict("ngrid" => 200, + "nelement" => 1, + "L" => 8.0, + "bc" => "zero", + "discretization" => "finite_difference"), + "vz" => OptionsDict("ngrid" => 200, + "nelement" => 1, + "L" => 8.0, + "bc" => "zero", + "discretization" => "finite_difference"), + "ion_source" => OptionsDict("active" => true, + "source_strength" => ionization_frequency, + "source_T" => 0.25, + "z_profile" => "constant", + "r_profile" => "constant"), ) -test_input_chebyshev = merge(test_input_finite_difference, - Dict("run_name" => "chebyshev_pseudospectral", - "z_discretization" => "chebyshev_pseudospectral", - "z_ngrid" => 9, - "z_nelement" => 2, - "vpa_discretization" => "chebyshev_pseudospectral", - "vpa_ngrid" => 17, - "vpa_nelement" => 10, - "vz_discretization" => "chebyshev_pseudospectral", - "vz_ngrid" => 17, - "vz_nelement" => 10)) - -test_input_chebyshev_split1 = merge(test_input_chebyshev, - Dict("run_name" => "chebyshev_pseudospectral_split1", - "evolve_moments_density" => true, - "evolve_moments_conservation" => true)) - -test_input_chebyshev_split2 = merge(test_input_chebyshev_split1, - Dict("run_name" => "chebyshev_pseudospectral_split2", - "evolve_moments_parallel_flow" => true, - "ion_numerical_dissipation" => Dict("force_minimum_pdf_value" => 0.0))) - -test_input_chebyshev_split3 = merge(test_input_chebyshev_split2, - Dict("run_name" => "chebyshev_pseudospectral_split3", - "evolve_moments_parallel_pressure" => true)) +test_input_chebyshev = recursive_merge(test_input_finite_difference, + OptionsDict("run_name" => "chebyshev_pseudospectral", + "z" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 9, + "nelement" => 2), + "vpa" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 17, + "nelement" => 10), + "vz" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 17, + "nelement" => 10), + )) + +test_input_chebyshev_split1 = recursive_merge(test_input_chebyshev, + OptionsDict("run_name" => "chebyshev_pseudospectral_split1", + "evolve_moments_density" => true, + "evolve_moments_conservation" => true, + )) + +test_input_chebyshev_split2 = recursive_merge(test_input_chebyshev_split1, + OptionsDict("run_name" => "chebyshev_pseudospectral_split2", + "evolve_moments_parallel_flow" => true, + "ion_numerical_dissipation" => OptionsDict("force_minimum_pdf_value" => 0.0), + )) + +test_input_chebyshev_split3 = recursive_merge(test_input_chebyshev_split2, + OptionsDict("run_name" => "chebyshev_pseudospectral_split3", + "evolve_moments_parallel_pressure" => true, + )) """ Run a test for a single set of parameters diff --git a/moment_kinetics/test/interpolation_tests.jl b/moment_kinetics/test/interpolation_tests.jl index 5e9a1d59c..c9525e770 100644 --- a/moment_kinetics/test/interpolation_tests.jl +++ b/moment_kinetics/test/interpolation_tests.jl @@ -2,7 +2,6 @@ module InterpolationTests include("setup.jl") -using moment_kinetics.input_structs: grid_input, advection_input using moment_kinetics.coordinates: define_coordinate using moment_kinetics.interpolation: interpolate_to_grid_1d, interpolate_to_grid_z, interpolate_to_grid_vpa @@ -20,9 +19,6 @@ println("interpolation tests") ngrid = 33 L = 6.0 bc = "periodic" -# fd_option and adv_input not actually used so given values unimportant -fd_option = "" -adv_input = advection_input("default", 1.0, 0.0, 0.0) function runtests() @testset "interpolation" verbose=use_verbose begin @@ -35,20 +31,19 @@ function runtests() ntest ∈ (3, 14), nelement ∈ (2, 8), zlim ∈ (L/2.0, L/5.0) # create the 'input' struct containing input info needed to create a coordinate - nelement_local = nelement - nrank_per_block = 0 # dummy value - irank = 0 # dummy value - comm = MPI.COMM_NULL # dummy value + nelement_local = nelement cheb_option = "FFT" - #element_spacing_option = "uniform" - input = grid_input("coord", ngrid, nelement, - nelement_local, nrank_per_block, irank, L, - discretization, fd_option, cheb_option, bc, adv_input, comm, - element_spacing_option) + input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, "nelement"=>nelement, + "L"=>L, + "discretization"=>discretization, + "cheb_option"=>cheb_option, + "bc"=>bc, + "element_spacing_option"=>element_spacing_option)) # create the coordinate struct 'z' # This test runs effectively in serial, so use `ignore_MPI=true` to avoid # errors due to communicators not being fully set up. - z, spectral = define_coordinate(input; ignore_MPI=true, collision_operator_dim=false) + z, spectral = define_coordinate(input, "coord"; ignore_MPI=true, + collision_operator_dim=false) test_grid = [z for z in range(-zlim, zlim, length=ntest)] diff --git a/moment_kinetics/test/nonlinear_solver_tests.jl b/moment_kinetics/test/nonlinear_solver_tests.jl index b37dc0187..4b70e57c7 100644 --- a/moment_kinetics/test/nonlinear_solver_tests.jl +++ b/moment_kinetics/test/nonlinear_solver_tests.jl @@ -9,7 +9,7 @@ using moment_kinetics.input_structs: advection_input using moment_kinetics.looping using moment_kinetics.looping: setup_loop_ranges! using moment_kinetics.nonlinear_solvers -using moment_kinetics.type_definitions: mk_float, mk_int, OptionsDict +using moment_kinetics.type_definitions: mk_float, mk_int using MPI diff --git a/moment_kinetics/test/nonlinear_sound_wave_inputs_and_expected_data.jl b/moment_kinetics/test/nonlinear_sound_wave_inputs_and_expected_data.jl index 031591e51..f534a6020 100644 --- a/moment_kinetics/test/nonlinear_sound_wave_inputs_and_expected_data.jl +++ b/moment_kinetics/test/nonlinear_sound_wave_inputs_and_expected_data.jl @@ -82,106 +82,110 @@ const expected = 0.024285034070612672 0.01001177872485688 0.00842420216637052 0.019283695804388705 0.03672486160719087 0.04165072188572364 0.0369234055803037 0.036374533667106045 0.041904838760501203 0.040712367539469434 0.02428503407061266]) # default inputs for tests -test_input_finite_difference = Dict("composition" => OptionsDict("n_ion_species" => 1, - "n_neutral_species" => 1, - "electron_physics" => "boltzmann_electron_response", - "T_e" => 1.0), - "ion_species_1" => OptionsDict("initial_density" => 0.5, - "initial_temperature" => 1.0), - "z_IC_ion_species_1" => OptionsDict("initialization_option" => "sinusoid", - "density_amplitude" => 0.5, - "density_phase" => 0.0, - "upar_amplitude" => 0.0, - "upar_phase" => 0.0, - "temperature_amplitude" => 0.5, - "temperature_phase" => mk_float(π)), - "neutral_species_1" => OptionsDict("initial_density" => 0.5, - "initial_temperature" => 1.0), - "z_IC_neutral_species_1" => OptionsDict("initialization_option" => "sinusoid", - "density_amplitude" => 0.5, - "density_phase" => mk_float(π), - "upar_amplitude" => 0.0, - "upar_phase" => 0.0, - "temperature_amplitude" => 0.5, - "temperature_phase" => 0.0), - "run_name" => "finite_difference", - "evolve_moments_density" => false, - "evolve_moments_parallel_flow" => false, - "evolve_moments_parallel_pressure" => false, - "evolve_moments_conservation" => true, - "charge_exchange_frequency" => 2*π*0.1, - "ionization_frequency" => 0.0, - "timestepping" => OptionsDict("nstep" => 100, - "dt" => 0.001, - "nwrite" => 100, - "nwrite_dfns" => 100, - "split_operators" => false), - "r_ngrid" => 1, - "r_nelement" => 1, - "r_bc" => "periodic", - "r_discretization" => "finite_difference", - "z_ngrid" => 100, - "z_nelement" => 1, - "z_bc" => "periodic", - "z_discretization" => "finite_difference", - "vpa_ngrid" => 400, - "vpa_nelement" => 1, - "vpa_L" => vpa_L, - "vpa_bc" => "periodic", - "vpa_discretization" => "finite_difference", - "vz_ngrid" => 400, - "vz_nelement" => 1, - "vz_L" => vpa_L, - "vz_bc" => "periodic", - "vz_discretization" => "finite_difference") +test_input_finite_difference = OptionsDict("composition" => OptionsDict("n_ion_species" => 1, + "n_neutral_species" => 1, + "electron_physics" => "boltzmann_electron_response", + "T_e" => 1.0), + "ion_species_1" => OptionsDict("initial_density" => 0.5, + "initial_temperature" => 1.0), + "z_IC_ion_species_1" => OptionsDict("initialization_option" => "sinusoid", + "density_amplitude" => 0.5, + "density_phase" => 0.0, + "upar_amplitude" => 0.0, + "upar_phase" => 0.0, + "temperature_amplitude" => 0.5, + "temperature_phase" => mk_float(π)), + "neutral_species_1" => OptionsDict("initial_density" => 0.5, + "initial_temperature" => 1.0), + "z_IC_neutral_species_1" => OptionsDict("initialization_option" => "sinusoid", + "density_amplitude" => 0.5, + "density_phase" => mk_float(π), + "upar_amplitude" => 0.0, + "upar_phase" => 0.0, + "temperature_amplitude" => 0.5, + "temperature_phase" => 0.0), + "run_name" => "finite_difference", + "evolve_moments_density" => false, + "evolve_moments_parallel_flow" => false, + "evolve_moments_parallel_pressure" => false, + "evolve_moments_conservation" => true, + "charge_exchange_frequency" => 2*π*0.1, + "ionization_frequency" => 0.0, + "timestepping" => OptionsDict("nstep" => 100, + "dt" => 0.001, + "nwrite" => 100, + "nwrite_dfns" => 100, + "split_operators" => false), + "r" => OptionsDict("ngrid" => 1, + "nelement" => 1, + "bc" => "periodic", + "discretization" => "finite_difference"), + "z" => OptionsDict("ngrid" => 100, + "nelement" => 1, + "bc" => "periodic", + "discretization" => "finite_difference"), + "vpa" => OptionsDict("ngrid" => 400, + "nelement" => 1, + "L" => vpa_L, + "bc" => "periodic", + "discretization" => "finite_difference"), + "vz" => OptionsDict("ngrid" => 400, + "nelement" => 1, + "L" => vpa_L, + "bc" => "periodic", + "discretization" => "finite_difference"), + ) test_input_finite_difference_split_1_moment = - merge(test_input_finite_difference, - Dict("run_name" => "finite_difference_split_1_moment", - "evolve_moments_density" => true)) + recursive_merge(test_input_finite_difference, + OptionsDict("run_name" => "finite_difference_split_1_moment", + "evolve_moments_density" => true)) test_input_finite_difference_split_2_moments = - merge(test_input_finite_difference_split_1_moment, - Dict("run_name" => "finite_difference_split_2_moments", - "evolve_moments_parallel_flow" => true)) + recursive_merge(test_input_finite_difference_split_1_moment, + OptionsDict("run_name" => "finite_difference_split_2_moments", + "evolve_moments_parallel_flow" => true)) test_input_finite_difference_split_3_moments = - merge(test_input_finite_difference_split_2_moments, - Dict("run_name" => "finite_difference_split_3_moments", - "evolve_moments_parallel_pressure" => true, - "vpa_L" => 12.0, "vz_L" => 12.0)) + recursive_merge(test_input_finite_difference_split_2_moments, + OptionsDict("run_name" => "finite_difference_split_3_moments", + "evolve_moments_parallel_pressure" => true, + "vpa" => OptionsDict("L" => 12.0), + "vz" => OptionsDict("L" => 12.0), + )) -test_input_chebyshev = merge(test_input_finite_difference, - Dict("run_name" => "chebyshev_pseudospectral", - "z_discretization" => "chebyshev_pseudospectral", - "z_ngrid" => 9, - "z_nelement" => 4, - "vpa_discretization" => "chebyshev_pseudospectral", - "vpa_ngrid" => 17, - "vpa_nelement" => 8, - "vz_discretization" => "chebyshev_pseudospectral", - "vz_ngrid" => 17, - "vz_nelement" => 8)) +test_input_chebyshev = recursive_merge(test_input_finite_difference, + OptionsDict("run_name" => "chebyshev_pseudospectral", + "z" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 9, + "nelement" => 4), + "vpa" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 17, + "nelement" => 8), + "vz" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 17, + "nelement" => 8)), + ) if global_size[] > 2 && global_size[] % 2 == 0 # Test using distributed-memory - test_input_chebyshev["z_nelement_local"] = test_input_chebyshev["z_nelement"] ÷ 2 + test_input_chebyshev["z"]["nelement_local"] = test_input_chebyshev["z"]["nelement"] ÷ 2 end test_input_chebyshev_split_1_moment = - merge(test_input_chebyshev, - Dict("run_name" => "chebyshev_pseudospectral_split_1_moment", - "evolve_moments_density" => true)) + recursive_merge(test_input_chebyshev, + OptionsDict("run_name" => "chebyshev_pseudospectral_split_1_moment", + "evolve_moments_density" => true)) test_input_chebyshev_split_2_moments = - merge(test_input_chebyshev_split_1_moment, - Dict("run_name" => "chebyshev_pseudospectral_split_2_moments", - "evolve_moments_parallel_flow" => true)) + recursive_merge(test_input_chebyshev_split_1_moment, + OptionsDict("run_name" => "chebyshev_pseudospectral_split_2_moments", + "evolve_moments_parallel_flow" => true)) test_input_chebyshev_split_3_moments = - merge(test_input_chebyshev_split_2_moments, - Dict("run_name" => "chebyshev_pseudospectral_split_3_moments", - "evolve_moments_parallel_pressure" => true, - "vpa_L" => 12.0, "vz_L" => 12.0)) - - + recursive_merge(test_input_chebyshev_split_2_moments, + OptionsDict("run_name" => "chebyshev_pseudospectral_split_3_moments", + "evolve_moments_parallel_pressure" => true, + "vpa" => OptionsDict("L" => 12.0), + "vz" => OptionsDict("L" => 12.0), + )) diff --git a/moment_kinetics/test/nonlinear_sound_wave_tests.jl b/moment_kinetics/test/nonlinear_sound_wave_tests.jl index 7e3a7efd6..8b53dcad5 100644 --- a/moment_kinetics/test/nonlinear_sound_wave_tests.jl +++ b/moment_kinetics/test/nonlinear_sound_wave_tests.jl @@ -4,12 +4,10 @@ include("setup.jl") using Base.Filesystem: tempname -using moment_kinetics.coordinates: define_coordinate -using moment_kinetics.input_structs: grid_input, advection_input using moment_kinetics.interpolation: interpolate_to_grid_z, interpolate_to_grid_vpa using moment_kinetics.load_data: get_run_info_no_setup, close_run_info, postproc_load_variable -using moment_kinetics.type_definitions: mk_float, OptionsDict +using moment_kinetics.type_definitions: mk_float using moment_kinetics.utils: merge_dict_with_kwargs! const analytical_rtol = 3.e-2 diff --git a/moment_kinetics/test/recycling_fraction_tests.jl b/moment_kinetics/test/recycling_fraction_tests.jl index b371da032..ba6aead65 100644 --- a/moment_kinetics/test/recycling_fraction_tests.jl +++ b/moment_kinetics/test/recycling_fraction_tests.jl @@ -9,164 +9,164 @@ include("setup.jl") using Base.Filesystem: tempname using MPI -using moment_kinetics.coordinates: define_coordinate -using moment_kinetics.input_structs: grid_input, advection_input using moment_kinetics.interpolation: interpolate_to_grid_z using moment_kinetics.load_data: get_run_info_no_setup, close_run_info, postproc_load_variable -using moment_kinetics.type_definitions: OptionsDict using moment_kinetics.utils: merge_dict_with_kwargs! # default inputs for tests -test_input = Dict("composition" => OptionsDict("n_ion_species" => 1, - "n_neutral_species" => 1, - "electron_physics" => "boltzmann_electron_response", - "T_e" => 0.2, - "T_wall" => 0.1, - "recycling_fraction" => 0.5), - "ion_species_1" => OptionsDict("initial_density" => 1.0, - "initial_temperature" => 1.0), - "z_IC_ion_species_1" => OptionsDict("initialization_option" => "gaussian", - "density_amplitude" => 0.0, - "density_phase" => 0.0, - "upar_amplitude" => 1.0, - "upar_phase" => 0.0, - "temperature_amplitude" => 0.0, - "temperature_phase" => 0.0), - "vpa_IC_ion_species_1" => OptionsDict("initialization_option" => "gaussian", - "density_amplitude" => 1.0, - "density_phase" => 0.0, - "upar_amplitude" => 0.0, - "upar_phase" => 0.0, - "temperature_amplitude" => 0.0, - "temperature_phase" => 0.0), - "neutral_species_1" => OptionsDict("initial_density" => 1.0, +test_input = OptionsDict("composition" => OptionsDict("n_ion_species" => 1, + "n_neutral_species" => 1, + "electron_physics" => "boltzmann_electron_response", + "T_e" => 0.2, + "T_wall" => 0.1, + "recycling_fraction" => 0.5), + "ion_species_1" => OptionsDict("initial_density" => 1.0, "initial_temperature" => 1.0), - "z_IC_neutral_species_1" => OptionsDict("initialization_option" => "gaussian", - "density_amplitude" => 0.001, + "z_IC_ion_species_1" => OptionsDict("initialization_option" => "gaussian", + "density_amplitude" => 0.0, "density_phase" => 0.0, - "upar_amplitude" => -1.0, + "upar_amplitude" => 1.0, "upar_phase" => 0.0, "temperature_amplitude" => 0.0, - "temperature_phase" => 0.0), - "vpa_IC_neutral_species_1" => OptionsDict("initialization_option" => "gaussian", - "density_amplitude" => 1.0, - "density_phase" => 0.0, - "upar_amplitude" => 0.0, - "upar_phase" => 0.0, - "temperature_amplitude" => 0.0, - "temperature_phase" => 0.0), - "run_name" => "full-f", - "evolve_moments_density" => false, - "evolve_moments_parallel_flow" => false, - "evolve_moments_parallel_pressure" => false, - "evolve_moments_conservation" => false, - "charge_exchange_frequency" => 0.75, - "ionization_frequency" => 0.5, - "constant_ionization_rate" => false, - "timestepping" => OptionsDict("nstep" => 1000, - "dt" => 1.0e-4, - "nwrite" => 1000, - "split_operators" => false), - "r_ngrid" => 1, - "r_nelement" => 1, - "z_ngrid" => 9, - "z_nelement" => 8, - "z_bc" => "wall", - "z_discretization" => "chebyshev_pseudospectral", - "z_element_spacing_option" => "sqrt", - "vpa_ngrid" => 10, - "vpa_nelement" => 15, - "vpa_L" => 18.0, - "vpa_bc" => "zero", - "vpa_discretization" => "chebyshev_pseudospectral", - "vpa_element_spacing_option" => "coarse_tails", - "vz_ngrid" => 10, - "vz_nelement" => 15, - "vz_L" => 18.0, - "vz_bc" => "zero", - "vz_discretization" => "chebyshev_pseudospectral", - "vz_element_spacing_option" => "coarse_tails", - "ion_source" => Dict("active" => true, - "z_profile" => "gaussian", - "z_width" => 0.125, - "source_strength" => 2.0, - "source_T" => 2.0)) + "temperature_phase" => 0.0), + "vpa_IC_ion_species_1" => OptionsDict("initialization_option" => "gaussian", + "density_amplitude" => 1.0, + "density_phase" => 0.0, + "upar_amplitude" => 0.0, + "upar_phase" => 0.0, + "temperature_amplitude" => 0.0, + "temperature_phase" => 0.0), + "neutral_species_1" => OptionsDict("initial_density" => 1.0, + "initial_temperature" => 1.0), + "z_IC_neutral_species_1" => OptionsDict("initialization_option" => "gaussian", + "density_amplitude" => 0.001, + "density_phase" => 0.0, + "upar_amplitude" => -1.0, + "upar_phase" => 0.0, + "temperature_amplitude" => 0.0, + "temperature_phase" => 0.0), + "vz_IC_neutral_species_1" => OptionsDict("initialization_option" => "gaussian", + "density_amplitude" => 1.0, + "density_phase" => 0.0, + "upar_amplitude" => 0.0, + "upar_phase" => 0.0, + "temperature_amplitude" => 0.0, + "temperature_phase" => 0.0), + "run_name" => "full-f", + "evolve_moments_density" => false, + "evolve_moments_parallel_flow" => false, + "evolve_moments_parallel_pressure" => false, + "evolve_moments_conservation" => false, + "charge_exchange_frequency" => 0.75, + "ionization_frequency" => 0.5, + "constant_ionization_rate" => false, + "timestepping" => OptionsDict("nstep" => 1000, + "dt" => 1.0e-4, + "nwrite" => 1000, + "split_operators" => false), + "r" => OptionsDict("ngrid" => 1, + "nelement" => 1), + "z" => OptionsDict("ngrid" => 9, + "nelement" => 8, + "bc" => "wall", + "discretization" => "chebyshev_pseudospectral", + "element_spacing_option" => "sqrt"), + "vpa" => OptionsDict("ngrid" => 10, + "nelement" => 15, + "L" => 18.0, + "bc" => "zero", + "discretization" => "chebyshev_pseudospectral", + "element_spacing_option" => "coarse_tails"), + "vz" => OptionsDict("ngrid" => 10, + "nelement" => 15, + "L" => 18.0, + "bc" => "zero", + "discretization" => "chebyshev_pseudospectral", + "element_spacing_option" => "coarse_tails"), + "ion_source" => OptionsDict("active" => true, + "z_profile" => "gaussian", + "z_width" => 0.125, + "source_strength" => 2.0, + "source_T" => 2.0), + ) if global_size[] > 2 && global_size[] % 2 == 0 # Test using distributed-memory - test_input["z_nelement_local"] = test_input["z_nelement"] ÷ 2 + test_input["z"]["nelement_local"] = test_input["z"]["nelement"] ÷ 2 end -test_input_split1 = merge(test_input, - Dict("run_name" => "split1", - "evolve_moments_density" => true, - "evolve_moments_conservation" => true)) -test_input_split2 = merge(test_input_split1, - Dict("run_name" => "split2", - "evolve_moments_parallel_flow" => true)) -test_input_split3 = merge(test_input_split2, - Dict("run_name" => "split3", - "z_nelement" => 16, - "vpa_nelement" => 31, - "vz_nelement" => 31, - "evolve_moments_parallel_pressure" => true, - "ion_numerical_dissipation" => OptionsDict("force_minimum_pdf_value" => 0.0, "vpa_dissipation_coefficient" => 1e-2), - "neutral_numerical_dissipation" => OptionsDict("force_minimum_pdf_value" => 0.0, "vz_dissipation_coefficient" => 1e-2))) -test_input_split3["timestepping"] = merge(test_input_split3["timestepping"], - Dict("dt" => 1.0e-5, - "write_error_diagnostics" => true, - "write_steady_state_diagnostics" => true)) +test_input_split1 = recursive_merge(test_input, + OptionsDict("run_name" => "split1", + "evolve_moments_density" => true, + "evolve_moments_conservation" => true)) +test_input_split2 = recursive_merge(test_input_split1, + OptionsDict("run_name" => "split2", + "evolve_moments_parallel_flow" => true)) +test_input_split3 = recursive_merge(test_input_split2, + OptionsDict("run_name" => "split3", + "z" => OptionsDict("nelement" => 16), + "vpa" => OptionsDict("nelement" => 31), + "vz" => OptionsDict("nelement" => 31), + "evolve_moments_parallel_pressure" => true, + "ion_numerical_dissipation" => OptionsDict("force_minimum_pdf_value" => 0.0, "vpa_dissipation_coefficient" => 1e-2), + "neutral_numerical_dissipation" => OptionsDict("force_minimum_pdf_value" => 0.0, "vz_dissipation_coefficient" => 1e-2))) +test_input_split3["timestepping"] = recursive_merge(test_input_split3["timestepping"], + OptionsDict("dt" => 1.0e-5, + "write_error_diagnostics" => true, + "write_steady_state_diagnostics" => true)) # default inputs for adaptive timestepping tests -test_input_adaptive = merge(test_input, - OptionsDict("run_name" => "adaptive full-f", - "z_ngrid" => 5, - "z_nelement" => 16, - "vpa_ngrid" => 6, - "vpa_nelement" => 31, - "vz_ngrid" => 6, - "vz_nelement" => 31)) +test_input_adaptive = recursive_merge(test_input, + OptionsDict("run_name" => "adaptive full-f", + "z" => OptionsDict("ngrid" => 5, + "nelement" => 16), + "vpa" => OptionsDict("ngrid" => 6, + "nelement" => 31), + "vz" => OptionsDict("ngrid" => 6, + "nelement" => 31)), + ) # Note, use excessively conservative timestepping settings here, because # we want to avoid any timestep failures in the test. If failures # occur, the number or when exactly they occur could depend on the # round-off error, which could make the results less reproducible (even # though the difference should be negligible compared to the # discretization error of the simulation). -test_input_adaptive["timestepping"] = merge(test_input_adaptive["timestepping"], - OptionsDict("type" => "Fekete4(3)", - "nstep" => 5000, - "dt" => 1.0e-5, - "minimum_dt" => 1.0e-5, - "CFL_prefactor" => 1.0, - "step_update_prefactor" => 0.5, - "nwrite" => 1000, - "split_operators" => false)) - -test_input_adaptive_split1 = merge(test_input_adaptive, - Dict("run_name" => "adaptive split1", - "evolve_moments_density" => true, - "evolve_moments_conservation" => true)) -test_input_adaptive_split2 = merge(test_input_adaptive_split1, - Dict("run_name" => "adaptive split2", - "evolve_moments_parallel_flow" => true)) -test_input_adaptive_split2["timestepping"] = merge(test_input_adaptive_split2["timestepping"], - OptionsDict("step_update_prefactor" => 0.4)) -test_input_adaptive_split3 = merge(test_input_adaptive_split2, - Dict("run_name" => "adaptive split3", - "evolve_moments_parallel_pressure" => true, - "numerical_dissipation" => OptionsDict("force_minimum_pdf_value" => 0.0, - "vpa_dissipation_coefficient" => 1e-2))) +test_input_adaptive["timestepping"] = recursive_merge(test_input_adaptive["timestepping"], + OptionsDict("type" => "Fekete4(3)", + "nstep" => 5000, + "dt" => 1.0e-5, + "minimum_dt" => 1.0e-5, + "CFL_prefactor" => 1.0, + "step_update_prefactor" => 0.5, + "nwrite" => 1000, + "split_operators" => false), + ) + +test_input_adaptive_split1 = recursive_merge(test_input_adaptive, + OptionsDict("run_name" => "adaptive split1", + "evolve_moments_density" => true, + "evolve_moments_conservation" => true)) +test_input_adaptive_split2 = recursive_merge(test_input_adaptive_split1, + OptionsDict("run_name" => "adaptive split2", + "evolve_moments_parallel_flow" => true)) +test_input_adaptive_split2["timestepping"] = recursive_merge(test_input_adaptive_split2["timestepping"], + OptionsDict("step_update_prefactor" => 0.4)) +test_input_adaptive_split3 = recursive_merge(test_input_adaptive_split2, + OptionsDict("run_name" => "adaptive split3", + "evolve_moments_parallel_pressure" => true, + "numerical_dissipation" => OptionsDict("force_minimum_pdf_value" => 0.0, + "vpa_dissipation_coefficient" => 1e-2))) # The initial conditions seem to make the split3 case hard to advance without any # failures. In a real simulation, would just set the minimum_dt higher to try to get # through this without crashing. For this test, want the timestep to adapt (not just sit # at minimum_dt), so just set a very small timestep. -test_input_adaptive_split3["timestepping"] = merge(test_input_adaptive_split3["timestepping"], - OptionsDict("dt" => 1.0e-7, - "rtol" => 2.0e-4, - "atol" => 2.0e-10, - "minimum_dt" => 1.0e-7, - "step_update_prefactor" => 0.064)) +test_input_adaptive_split3["timestepping"] = recursive_merge(test_input_adaptive_split3["timestepping"], + OptionsDict("dt" => 1.0e-7, + "rtol" => 2.0e-4, + "atol" => 2.0e-10, + "minimum_dt" => 1.0e-7, + "step_update_prefactor" => 0.064)) """ Run a test for a single set of parameters diff --git a/moment_kinetics/test/restart_interpolation_tests.jl b/moment_kinetics/test/restart_interpolation_tests.jl index 3995e536e..51851bd9f 100644 --- a/moment_kinetics/test/restart_interpolation_tests.jl +++ b/moment_kinetics/test/restart_interpolation_tests.jl @@ -7,9 +7,8 @@ include("setup.jl") using Base.Filesystem: tempname using moment_kinetics.communication -using moment_kinetics.coordinates: define_coordinate using moment_kinetics.file_io: io_has_parallel -using moment_kinetics.input_structs: grid_input, advection_input, hdf5 +using moment_kinetics.input_structs: hdf5 using moment_kinetics.load_data: open_readonly_output_file, load_coordinate_data, load_species_data, load_fields_data, load_ion_moments_data, load_pdf_data, @@ -18,7 +17,7 @@ using moment_kinetics.load_data: open_readonly_output_file, load_coordinate_data using moment_kinetics.interpolation: interpolate_to_grid_z, interpolate_to_grid_vpa using moment_kinetics.load_data: get_run_info_no_setup, close_run_info, postproc_load_variable -using moment_kinetics.type_definitions: mk_float, OptionsDict +using moment_kinetics.type_definitions: mk_float using moment_kinetics.utils: merge_dict_with_kwargs! include("nonlinear_sound_wave_inputs_and_expected_data.jl") @@ -29,39 +28,43 @@ base_input["timestepping"]["nwrite"] = 50 base_input["timestepping"]["nwrite_dfns"] = 50 if global_size[] > 1 && global_size[] % 2 == 0 # Test using distributed-memory - base_input["z_nelement_local"] = base_input["z_nelement"] ÷ 2 + base_input["z"]["nelement_local"] = base_input["z"]["nelement"] ÷ 2 end base_input["output"] = OptionsDict("parallel_io" => false) restart_test_input_chebyshev = - merge(deepcopy(base_input), - OptionsDict("run_name" => "restart_chebyshev_pseudospectral", - "r_ngrid" => 3, "r_nelement" => 2, - "r_discretization" => "chebyshev_pseudospectral", - "z_ngrid" => 17, "z_nelement" => 2, - "vpa_ngrid" => 9, "vpa_nelement" => 32, - "vz_ngrid" => 9, "vz_nelement" => 32)) +recursive_merge(deepcopy(base_input), + OptionsDict("run_name" => "restart_chebyshev_pseudospectral", + "r" => OptionsDict("ngrid" => 3, "nelement" => 2, + "discretization" => "chebyshev_pseudospectral"), + "z" => OptionsDict("ngrid" => 17, "nelement" => 2), + "vpa" => OptionsDict("ngrid" => 9, "nelement" => 32), + "vz" => OptionsDict("ngrid" => 9, "nelement" => 32)), + ) if global_size[] > 1 && global_size[] % 2 == 0 # Test using distributed-memory - restart_test_input_chebyshev["z_nelement_local"] = restart_test_input_chebyshev["z_nelement"] ÷ 2 + restart_test_input_chebyshev["z"]["nelement_local"] = restart_test_input_chebyshev["z"]["nelement"] ÷ 2 end restart_test_input_chebyshev_split_1_moment = - merge(deepcopy(restart_test_input_chebyshev), - OptionsDict("run_name" => "restart_chebyshev_pseudospectral_split_1_moment", - "evolve_moments_density" => true)) + recursive_merge(deepcopy(restart_test_input_chebyshev), + OptionsDict("run_name" => "restart_chebyshev_pseudospectral_split_1_moment", + "evolve_moments_density" => true), + ) restart_test_input_chebyshev_split_2_moments = - merge(deepcopy(restart_test_input_chebyshev_split_1_moment), - OptionsDict("run_name" => "restart_chebyshev_pseudospectral_split_2_moments", - "r_ngrid" => 1, "r_nelement" => 1, - "evolve_moments_parallel_flow" => true)) + recursive_merge(deepcopy(restart_test_input_chebyshev_split_1_moment), + OptionsDict("run_name" => "restart_chebyshev_pseudospectral_split_2_moments", + "r" => OptionsDict("ngrid" => 1, "nelement" => 1), + "evolve_moments_parallel_flow" => true), + ) restart_test_input_chebyshev_split_3_moments = - merge(deepcopy(restart_test_input_chebyshev_split_2_moments), - OptionsDict("run_name" => "restart_chebyshev_pseudospectral_split_3_moments", - "evolve_moments_parallel_pressure" => true, - "vpa_L" => 1.5*vpa_L, "vz_L" => 1.5*vpa_L)) + recursive_merge(deepcopy(restart_test_input_chebyshev_split_2_moments), + OptionsDict("run_name" => "restart_chebyshev_pseudospectral_split_3_moments", + "evolve_moments_parallel_pressure" => true, + "vpa" => OptionsDict("L" => 1.5*vpa_L), "vz" => OptionsDict("L" => 1.5*vpa_L)), + ) """ Run a sound-wave test for a single set of parameters @@ -89,15 +92,20 @@ function run_test(test_input, base, message, rtol, atol; tol_3V, args...) if isa(value, AbstractDict) return string(string(key)[1], (stringify_arg(k, v) for (k, v) in value)...) else - return string(string(key)[1], value) + if isa(value, AbstractString) + return string(string(key)[1], value[1]) + else + return string(string(key)[1], value) + end end end name = input["run_name"] if length(args) > 0 name = string(name, "_", (stringify_arg(k, v) for (k, v) in args)...) - - # Remove trailing "_" - name = chop(name) + end + # Make sure name is not too long + if length(name) > 90 + name = name[1:90] end if parallel_io name *= "parallel-io" @@ -298,16 +306,22 @@ function runtests() parallel_io = base_input["output"]["parallel_io"] base_input_full_f = deepcopy(base_input) - base_input_full_f["timestepping"] = merge(base_input["timestepping"], - OptionsDict("nstep" => nstep)) - base_input_evolve_density = merge(base_input_full_f, - OptionsDict("evolve_moments_density" => true)) - base_input_evolve_upar = merge(base_input_evolve_density, - OptionsDict("evolve_moments_parallel_flow" => true, - "vpa_L" => 1.5*vpa_L, "vz_L" => 1.5*vpa_L)) - base_input_evolve_ppar = merge(base_input_evolve_upar, - OptionsDict("evolve_moments_parallel_pressure" => true, - "vpa_L" => 1.5*vpa_L, "vz_L" => 1.5*vpa_L)) + base_input_full_f["timestepping"] = recursive_merge(base_input["timestepping"], + OptionsDict("nstep" => nstep), + ) + base_input_evolve_density = recursive_merge(base_input_full_f, + OptionsDict("evolve_moments_density" => true), + ) + base_input_evolve_upar = recursive_merge(base_input_evolve_density, + OptionsDict("evolve_moments_parallel_flow" => true, + "vpa" => OptionsDict("L" => 1.5*vpa_L), + "vz" => OptionsDict("L" => 1.5*vpa_L)), + ) + base_input_evolve_ppar = recursive_merge(base_input_evolve_upar, + OptionsDict("evolve_moments_parallel_pressure" => true, + "vpa" => OptionsDict("L" => 1.5*vpa_L), + "vz" => OptionsDict("L" => 1.5*vpa_L)), + ) for (base, base_label) ∈ ((base_input_full_f, "full-f"), (base_input_evolve_density, "split 1"), @@ -375,10 +389,14 @@ function runtests() # interpolation used for ion-neutral coupling in 2V/3V case has low accuracy, so # use looser tolerance for various things. @long do_tests(", 2V/3V", 1.0e-1, 98, false; tol_3V=0.3, - timestepping=OptionsDict("nstep" => 2), r_ngrid=1, r_nelement=1, - vperp_ngrid=17, vperp_nelement=4, vperp_L=vpa_L, vpa_ngrid=17, - vpa_nelement=8, vzeta_ngrid=17, vzeta_nelement=4, vzeta_L=vpa_L, - vr_ngrid=17, vr_nelement=4, vr_L=vpa_L, vz_ngrid=17, vz_nelement=8) + timestepping=OptionsDict("nstep" => 2), + r=OptionsDict("ngrid" => 1, "nelement" => 1), + vperp=OptionsDict("ngrid" => 17, "nelement" => 4, "L" => vpa_L, "ngrid" => 17), + vpa=OptionsDict("nelement" => 8), + vzeta=OptionsDict("ngrid" => 17, "nelement" => 4, "L" => vpa_L), + vr=OptionsDict("ngrid" => 17, "nelement" => 4, "L" => vpa_L), + vz=OptionsDict("ngrid" => 17, "nelement" => 8), + ) if io_has_parallel(Val(hdf5)) orig_base_input = deepcopy(base_input) @@ -392,11 +410,14 @@ function runtests() # interpolation used for ion-neutral coupling in 2V/3V case has low accuracy, # so use looser tolerance for various things. @long do_tests(", 2V/3V, parallel I/O", 2.0e-1, 98, false; tol_3V=0.3, - timestepping=OptionsDict("nstep" => 2), r_ngrid=1, - r_nelement=1, vperp_ngrid=17, vperp_nelement=4, vperp_L=vpa_L, - vpa_ngrid=17, vpa_nelement=8, vzeta_ngrid=17, vzeta_nelement=4, - vzeta_L=vpa_L, vr_ngrid=17, vr_nelement=4, vr_L=vpa_L, - vz_ngrid=17, vz_nelement=8) + timestepping=OptionsDict("nstep" => 2), + r=OptionsDict("ngrid" => 1, "nelement" => 1), + vperp=OptionsDict("ngrid" => 17, "nelement" => 4, "L" => vpa_L, "ngrid" => 17), + vpa=OptionsDict("nelement" => 8), + vzeta=OptionsDict("ngrid" => 17, "nelement" => 4, "L" => vpa_L), + vr=OptionsDict("ngrid" => 17, "nelement" => 4, "L" => vpa_L), + vz=OptionsDict("ngrid" => 17, "nelement" => 8), + ) global base_input = orig_base_input end diff --git a/moment_kinetics/test/setup.jl b/moment_kinetics/test/setup.jl index 8657bd170..7e9ec9cc8 100644 --- a/moment_kinetics/test/setup.jl +++ b/moment_kinetics/test/setup.jl @@ -13,10 +13,11 @@ using moment_kinetics module MKTestUtilities export use_verbose, force_optional_dependencies, @long, quietoutput, get_MPI_tempdir, - global_rank, global_size, maxabs_norm, @testset_skip, recursive_merge + global_rank, global_size, maxabs_norm, @testset_skip, recursive_merge, OptionsDict using moment_kinetics.communication: comm_world, global_rank, global_size using moment_kinetics.command_line_options: get_options +using moment_kinetics.type_definitions: OptionsDict using moment_kinetics.utils: recursive_merge using MPI diff --git a/moment_kinetics/test/sound_wave_tests.jl b/moment_kinetics/test/sound_wave_tests.jl index 9716b74bc..b2264520f 100644 --- a/moment_kinetics/test/sound_wave_tests.jl +++ b/moment_kinetics/test/sound_wave_tests.jl @@ -13,7 +13,6 @@ using moment_kinetics.load_data: load_fields_data, load_time_data using moment_kinetics.load_data: load_species_data, load_coordinate_data using moment_kinetics.analysis: analyze_fields_data using moment_kinetics.analysis: fit_delta_phi_mode -using moment_kinetics.type_definitions: OptionsDict using moment_kinetics.utils: merge_dict_with_kwargs! const analytical_rtol = 3.e-2 @@ -26,107 +25,113 @@ const binary_format = (force_optional_dependencies || io_has_implementation(netc "netcdf" : "hdf5" # default inputs for tests -test_input_finite_difference = Dict("composition" => OptionsDict("n_ion_species" => 1, - "n_neutral_species" => 1, - "electron_physics" => "boltzmann_electron_response", - "T_e" => 1.0), - "ion_species_1" => OptionsDict("initial_density" => 0.5, - "initial_temperature" => 1.0), - "z_IC_ion_species_1" => OptionsDict("initialization_option" => "sinusoid", - "density_amplitude" => 0.001, - "density_phase" => 0.0, - "upar_amplitude" => 0.0, - "upar_phase" => 0.0, - "temperature_amplitude" => 0.0, - "temperature_phase" => 0.0), - "neutral_species_1" => OptionsDict("initial_density" => 0.5, - "initial_temperature" => 1.0), - "z_IC_neutral_species_1" => OptionsDict("initialization_option" => "sinusoid", - "density_amplitude" => 0.001, - "density_phase" => 0.0, - "upar_amplitude" => 0.0, - "upar_phase" => 0.0, - "temperature_amplitude" => 0.0, - "temperature_phase" => 0.0), - "run_name" => "finite_difference", - "evolve_moments_density" => false, - "evolve_moments_parallel_flow" => false, - "evolve_moments_parallel_pressure" => false, - "evolve_moments_conservation" => true, - "charge_exchange_frequency" => 2*π*0.1, - "ionization_frequency" => 0.0, - "timestepping" => OptionsDict("nstep" => 1500, - "dt" => 0.002, - "nwrite" => 20, - "split_operators" => false), - "r_ngrid" => 1, - "r_nelement" => 1, - "r_bc" => "periodic", - "r_discretization" => "finite_difference", - "z_ngrid" => 100, - "z_nelement" => 1, - "z_bc" => "periodic", - "z_discretization" => "finite_difference", - "vperp_ngrid" => 1, - "vperp_nelement" => 1, - "vperp_L" => 1.0, - "vperp_discretization" => "finite_difference", - "vpa_ngrid" => 180, - "vpa_nelement" => 1, - "vpa_L" => 8.0, - "vpa_bc" => "periodic", - "vpa_discretization" => "finite_difference", - "vz_ngrid" => 180, - "vz_nelement" => 1, - "vz_L" => 8.0, - "vz_bc" => "periodic", - "vz_discretization" => "finite_difference", - "output" => OptionsDict("binary_format" => binary_format) - ) +test_input_finite_difference = OptionsDict("composition" => OptionsDict("n_ion_species" => 1, + "n_neutral_species" => 1, + "electron_physics" => "boltzmann_electron_response", + "T_e" => 1.0), + "ion_species_1" => OptionsDict("initial_density" => 0.5, + "initial_temperature" => 1.0), + "z_IC_ion_species_1" => OptionsDict("initialization_option" => "sinusoid", + "density_amplitude" => 0.001, + "density_phase" => 0.0, + "upar_amplitude" => 0.0, + "upar_phase" => 0.0, + "temperature_amplitude" => 0.0, + "temperature_phase" => 0.0), + "neutral_species_1" => OptionsDict("initial_density" => 0.5, + "initial_temperature" => 1.0), + "z_IC_neutral_species_1" => OptionsDict("initialization_option" => "sinusoid", + "density_amplitude" => 0.001, + "density_phase" => 0.0, + "upar_amplitude" => 0.0, + "upar_phase" => 0.0, + "temperature_amplitude" => 0.0, + "temperature_phase" => 0.0), + "run_name" => "finite_difference", + "evolve_moments_density" => false, + "evolve_moments_parallel_flow" => false, + "evolve_moments_parallel_pressure" => false, + "evolve_moments_conservation" => true, + "charge_exchange_frequency" => 2*π*0.1, + "ionization_frequency" => 0.0, + "timestepping" => OptionsDict("nstep" => 1500, + "dt" => 0.002, + "nwrite" => 20, + "split_operators" => false), + "r" => OptionsDict("ngrid" => 1, + "nelement" => 1, + "bc" => "periodic", + "discretization" => "finite_difference"), + "z" => OptionsDict("ngrid" => 100, + "nelement" => 1, + "bc" => "periodic", + "discretization" => "finite_difference"), + "vperp" => OptionsDict("ngrid" => 1, + "nelement" => 1, + "L" => 1.0, + "discretization" => "finite_difference"), + "vpa" => OptionsDict("ngrid" => 180, + "nelement" => 1, + "L" => 8.0, + "bc" => "periodic", + "discretization" => "finite_difference"), + "vz" => OptionsDict("ngrid" => 180, + "nelement" => 1, + "L" => 8.0, + "bc" => "periodic", + "discretization" => "finite_difference"), + "output" => OptionsDict("binary_format" => binary_format), + ) test_input_finite_difference_split_1_moment = - merge(test_input_finite_difference, - Dict("run_name" => "finite_difference_split_1_moment", - "evolve_moments_density" => true)) + recursive_merge(test_input_finite_difference, + OptionsDict("run_name" => "finite_difference_split_1_moment", + "evolve_moments_density" => true) + ) test_input_finite_difference_split_2_moments = - merge(test_input_finite_difference_split_1_moment, - Dict("run_name" => "finite_difference_split_2_moments", - "evolve_moments_parallel_flow" => true, "vpa_ngrid" => 270, "vpa_L" => - 12.0, "vz_ngrid" => 270, "vz_L" => 12.0)) + recursive_merge(test_input_finite_difference_split_1_moment, + OptionsDict("run_name" => "finite_difference_split_2_moments", + "evolve_moments_parallel_flow" => true, + "vpa" => OptionsDict("ngrid" => 270, "L" => 12.0), + "vz" => OptionsDict("ngrid" => 270, "L" => 12.0)) + ) test_input_finite_difference_split_3_moments = - merge(test_input_finite_difference_split_2_moments, - Dict("run_name" => "finite_difference_split_3_moments", - "evolve_moments_parallel_pressure" => true, "vpa_ngrid" => 270, "vpa_L" => - 12.0, "vz_ngrid" => 270, "vz_L" => 12.0)) - -test_input_chebyshev = merge(test_input_finite_difference, - Dict("run_name" => "chebyshev_pseudospectral", - "z_discretization" => "chebyshev_pseudospectral", - "z_ngrid" => 9, - "z_nelement" => 2, - "vpa_discretization" => "chebyshev_pseudospectral", - "vpa_ngrid" => 17, - "vpa_nelement" => 8, - "vz_discretization" => "chebyshev_pseudospectral", - "vz_ngrid" => 17, - "vz_nelement" => 8)) + recursive_merge(test_input_finite_difference_split_2_moments, + OptionsDict("run_name" => "finite_difference_split_3_moments", + "evolve_moments_parallel_pressure" => true, + "vpa" => OptionsDict("ngrid" => 270, "L" => 12.0), + "vz" => OptionsDict("ngrid" => 270, "L" => 12.0)) + ) + +test_input_chebyshev = recursive_merge(test_input_finite_difference, + OptionsDict("run_name" => "chebyshev_pseudospectral", + "z" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 9, + "nelement" => 2), + "vpa" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 17, + "nelement" => 8), + "vz" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 17, + "nelement" => 8), + )) test_input_chebyshev_split_1_moment = - merge(test_input_chebyshev, - Dict("run_name" => "chebyshev_pseudospectral_split_1_moment", - "evolve_moments_density" => true)) + recursive_merge(test_input_chebyshev, + OptionsDict("run_name" => "chebyshev_pseudospectral_split_1_moment", + "evolve_moments_density" => true)) test_input_chebyshev_split_2_moments = - merge(test_input_chebyshev_split_1_moment, - Dict("run_name" => "chebyshev_pseudospectral_split_2_moments", - "evolve_moments_parallel_flow" => true)) + recursive_merge(test_input_chebyshev_split_1_moment, + OptionsDict("run_name" => "chebyshev_pseudospectral_split_2_moments", + "evolve_moments_parallel_flow" => true)) test_input_chebyshev_split_3_moments = - merge(test_input_chebyshev_split_2_moments, - Dict("run_name" => "chebyshev_pseudospectral_split_3_moments", - "evolve_moments_parallel_pressure" => true)) + recursive_merge(test_input_chebyshev_split_2_moments, + OptionsDict("run_name" => "chebyshev_pseudospectral_split_3_moments", + "evolve_moments_parallel_pressure" => true)) """ @@ -427,7 +432,7 @@ function run_test_set_finite_difference_split_2_moments() [-0.34706673733456106, -0.3470627566790802, -0.3470579059173919, -0.347052193699157, -0.34704563020982493, -0.3470382271523149], 30; composition = OptionsDict("T_e" => 0.5), - timestepping = OptionsDict("nstep" => 1300), z_ngrid=150, + timestepping = OptionsDict("nstep" => 1300), z = OptionsDict("ngrid" => 150), charge_exchange_frequency=2*π*0.0) run_test(test_input_finite_difference_split_2_moments, 2*π*0.0, -2*π*0.2727, [-0.34705779901310196, -0.34704885164065513, -0.3470379898466833, diff --git a/moment_kinetics/test/velocity_integral_tests.jl b/moment_kinetics/test/velocity_integral_tests.jl index 365f92905..5f51f5b61 100644 --- a/moment_kinetics/test/velocity_integral_tests.jl +++ b/moment_kinetics/test/velocity_integral_tests.jl @@ -2,7 +2,6 @@ module VelocityIntegralTests include("setup.jl") -using moment_kinetics.input_structs: grid_input, advection_input using moment_kinetics.coordinates: define_coordinate using moment_kinetics.velocity_moments: get_density, get_upar, get_ppar, get_pperp, get_pressure using moment_kinetics.array_allocation: allocate_float @@ -23,34 +22,36 @@ function runtests() Lvpa = 18.0 #physical box size in reference units Lvperp = 9.0 #physical box size in reference units bc = "" #not required to take a particular value, not used - # fd_option and adv_input not actually used so given values unimportant discretization = "chebyshev_pseudospectral" - fd_option = "fourth_order_centered" cheb_option = "FFT" - adv_input = advection_input("default", 1.0, 0.0, 0.0) - nrank = 1 - irank = 0 - comm = MPI.COMM_NULL - # create the 'input' struct containing input info needed to create a - # coordinate - vr_input = grid_input("vperp", 1, 1, 1, nrank, irank, 1.0, discretization, - fd_option, cheb_option, bc, adv_input, comm, "uniform") - vz_input = grid_input("vpa", ngrid, nelement_global, nelement_local, nrank, irank, - Lvpa, discretization, fd_option, cheb_option, bc, adv_input, comm, - "uniform") - vpa_input = grid_input("vpa", ngrid, nelement_global, nelement_local, nrank, - irank, Lvpa, discretization, fd_option, cheb_option, bc, adv_input, - comm, "uniform") - vperp_input = grid_input("vperp", ngrid, nelement_global, nelement_local, nrank, - irank, Lvperp, discretization, fd_option, cheb_option, bc, adv_input, - comm, "uniform") - # create the coordinate struct 'x' - # This test runs effectively in serial, so use `ignore_MPI=true` to avoid - # errors due to communicators not being fully set up. - vpa, vpa_spectral = define_coordinate(vpa_input; ignore_MPI=true) - vperp, vperp_spectral = define_coordinate(vperp_input; ignore_MPI=true) - vz, vz_spectral = define_coordinate(vz_input; ignore_MPI=true) - vr, vr_spectral = define_coordinate(vr_input; ignore_MPI=true) + # create the 'input' struct containing input info needed to create + # coordinates + coords_input = OptionsDict("vperp1d"=>OptionsDict("ngrid"=>1, "nelement"=>1, "nelement_local"=>1, "L"=>1.0, + "discretization"=>discretization, + "cheb_option"=>cheb_option, "bc"=>bc, + "element_spacing_option"=>"uniform"), + "vpa1d"=>OptionsDict("ngrid"=>ngrid, "nelement"=>nelement_global, + "nelement_local"=>nelement_local, "L"=>Lvpa, + "discretization"=>discretization, + "cheb_option"=>cheb_option, "bc"=>bc, + "element_spacing_option"=>"uniform"), + "vperp"=>OptionsDict("ngrid"=>ngrid, "nelement"=>nelement_global, + "nelement_local"=>nelement_local, "L"=>Lvperp, + "discretization"=>discretization, + "cheb_option"=>cheb_option, "bc"=>bc, + "element_spacing_option"=>"uniform"), + "vpa"=>OptionsDict("ngrid"=>ngrid, "nelement"=>nelement_global, + "nelement_local"=>nelement_local, "L"=>Lvpa, + "discretization"=>discretization, + "cheb_option"=>cheb_option, "bc"=>bc, + "element_spacing_option"=>"uniform"), + ) + + # create the coordinate structs + vpa, vpa_spectral = define_coordinate(coords_input, "vpa"; ignore_MPI=true) + vperp, vperp_spectral = define_coordinate(coords_input, "vperp"; ignore_MPI=true) + vz, vz_spectral = define_coordinate(coords_input, "vpa1d"; ignore_MPI=true) + vr, vr_spectral = define_coordinate(coords_input, "vperp1d"; ignore_MPI=true) dfn = allocate_float(vpa.n,vperp.n) dfn1D = allocate_float(vz.n, vr.n) diff --git a/moment_kinetics/test/wall_bc_tests.jl b/moment_kinetics/test/wall_bc_tests.jl index e95502719..cebd176f9 100644 --- a/moment_kinetics/test/wall_bc_tests.jl +++ b/moment_kinetics/test/wall_bc_tests.jl @@ -9,122 +9,124 @@ using Base.Filesystem: tempname using MPI using moment_kinetics.coordinates: define_coordinate -using moment_kinetics.input_structs: grid_input, using moment_kinetics.interpolation: interpolate_to_grid_z using moment_kinetics.load_data: open_readonly_output_file using moment_kinetics.load_data: load_fields_data, load_pdf_data, load_time_data, load_species_data -using moment_kinetics.type_definitions: OptionsDict using moment_kinetics.utils: merge_dict_with_kwargs! # default inputs for tests -test_input_finite_difference = Dict("composition" => OptionsDict("n_ion_species" => 1, - "n_neutral_species" => 1, - "electron_physics" => "boltzmann_electron_response", - "T_e" => 1.0, - "T_wall" => 1.0), - "ion_species_1" => OptionsDict("initial_density" => 1.0, - "initial_temperature" => 1.0), - "z_IC_ion_species_1" => OptionsDict("initialization_option" => "gaussian", - "density_amplitude" => 0.0, - "density_phase" => 0.0, - "upar_amplitude" => 0.0, - "upar_phase" => 0.0, - "temperature_amplitude" => 0.0, - "temperature_phase" => 0.0), - "vpa_IC_ion_species_1" => OptionsDict("initialization_option" => "gaussian", - "density_amplitude" => 1.0, - "density_phase" => 0.0, - "upar_amplitude" => 0.0, - "upar_phase" => 0.0, - "temperature_amplitude" => 0.0, - "temperature_phase" => 0.0), - "neutral_species_1" => OptionsDict("initial_density" => 1.0, - "initial_temperature" => 1.0), - "z_IC_neutral_species_1" => OptionsDict("initialization_option" => "gaussian", - "density_amplitude" => 0.001, - "density_phase" => 0.0, - "upar_amplitude" => 0.0, - "upar_phase" => 0.0, - "temperature_amplitude" => 0.0, - "temperature_phase" => 0.0), - "vpa_IC_neutral_species_1" => OptionsDict("initialization_option" => "gaussian", +test_input_finite_difference = OptionsDict("composition" => OptionsDict("n_ion_species" => 1, + "n_neutral_species" => 1, + "electron_physics" => "boltzmann_electron_response", + "T_e" => 1.0, + "T_wall" => 1.0), + "ion_species_1" => OptionsDict("initial_density" => 1.0, + "initial_temperature" => 1.0), + "z_IC_ion_species_1" => OptionsDict("initialization_option" => "gaussian", + "density_amplitude" => 0.0, + "density_phase" => 0.0, + "upar_amplitude" => 0.0, + "upar_phase" => 0.0, + "temperature_amplitude" => 0.0, + "temperature_phase" => 0.0), + "vpa_IC_ion_species_1" => OptionsDict("initialization_option" => "gaussian", "density_amplitude" => 1.0, "density_phase" => 0.0, "upar_amplitude" => 0.0, "upar_phase" => 0.0, "temperature_amplitude" => 0.0, - "temperature_phase" => 0.0), - "run_name" => "finite_difference", - "evolve_moments_density" => false, - "evolve_moments_parallel_flow" => false, - "evolve_moments_parallel_pressure" => false, - "evolve_moments_conservation" => false, - "charge_exchange_frequency" => 2.0, - "ionization_frequency" => 2.0, - "constant_ionization_rate" => false, - "timestepping" => OptionsDict("nstep" => 10000, - "dt" => 1.0e-5, - "nwrite" => 100, - "split_operators" => false), - "r_ngrid" => 1, - "r_nelement" => 1, - "r_bc" => "periodic", - "r_discretization" => "finite_difference", - "z_ngrid" => 200, - "z_nelement" => 1, - "z_bc" => "wall", - "z_discretization" => "finite_difference", - "z_element_spacing_option" => "uniform", - "vpa_ngrid" => 400, - "vpa_nelement" => 1, - "vpa_L" => 8.0, - "vpa_bc" => "periodic", - "vpa_discretization" => "finite_difference", - "vz_ngrid" => 400, - "vz_nelement" => 1, - "vz_L" => 8.0, - "vz_bc" => "periodic", - "vz_discretization" => "finite_difference") + "temperature_phase" => 0.0), + "neutral_species_1" => OptionsDict("initial_density" => 1.0, + "initial_temperature" => 1.0), + "z_IC_neutral_species_1" => OptionsDict("initialization_option" => "gaussian", + "density_amplitude" => 0.001, + "density_phase" => 0.0, + "upar_amplitude" => 0.0, + "upar_phase" => 0.0, + "temperature_amplitude" => 0.0, + "temperature_phase" => 0.0), + "vz_IC_neutral_species_1" => OptionsDict("initialization_option" => "gaussian", + "density_amplitude" => 1.0, + "density_phase" => 0.0, + "upar_amplitude" => 0.0, + "upar_phase" => 0.0, + "temperature_amplitude" => 0.0, + "temperature_phase" => 0.0), + "run_name" => "finite_difference", + "evolve_moments_density" => false, + "evolve_moments_parallel_flow" => false, + "evolve_moments_parallel_pressure" => false, + "evolve_moments_conservation" => false, + "charge_exchange_frequency" => 2.0, + "ionization_frequency" => 2.0, + "constant_ionization_rate" => false, + "timestepping" => OptionsDict("nstep" => 10000, + "dt" => 1.0e-5, + "nwrite" => 100, + "split_operators" => false), + "r" => OptionsDict("ngrid" => 1, + "nelement" => 1, + "bc" => "periodic", + "discretization" => "finite_difference"), + "z" => OptionsDict("ngrid" => 200, + "nelement" => 1, + "bc" => "wall", + "discretization" => "finite_difference", + "element_spacing_option" => "uniform"), + "vpa" => OptionsDict("ngrid" => 400, + "nelement" => 1, + "L" => 8.0, + "bc" => "periodic", + "discretization" => "finite_difference"), + "vz" => OptionsDict("ngrid" => 400, + "nelement" => 1, + "L" => 8.0, + "bc" => "periodic", + "discretization" => "finite_difference"), + ) -test_input_chebyshev = merge(test_input_finite_difference, - Dict("run_name" => "chebyshev_pseudospectral", - "z_discretization" => "chebyshev_pseudospectral", - "z_ngrid" => 9, - "z_nelement" => 2, - "z_element_spacing_option" => "uniform", - "vpa_discretization" => "chebyshev_pseudospectral", - "vpa_ngrid" => 17, - "vpa_nelement" => 10, - "vz_discretization" => "chebyshev_pseudospectral", - "vz_ngrid" => 17, - "vz_nelement" => 10)) +test_input_chebyshev = recursive_merge(test_input_finite_difference, + OptionsDict("run_name" => "chebyshev_pseudospectral", + "z" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 9, + "nelement" => 2, + "element_spacing_option" => "uniform"), + "vpa" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 17, + "nelement" => 10), + "vz" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 17, + "nelement" => 10), + )) -test_input_chebyshev_sqrt_grid_odd = merge(test_input_finite_difference, - Dict("run_name" => "chebyshev_pseudospectral", - "z_discretization" => "chebyshev_pseudospectral", - "z_ngrid" => 9, - "z_nelement" => 5, # minimum nontrival nelement (odd) - "z_element_spacing_option" => "sqrt", - "vpa_discretization" => "chebyshev_pseudospectral", - "vpa_ngrid" => 17, - "vpa_nelement" => 10, - "vz_discretization" => "chebyshev_pseudospectral", - "vz_ngrid" => 17, - "vz_nelement" => 10)) -test_input_chebyshev_sqrt_grid_even = merge(test_input_finite_difference, - Dict("run_name" => "chebyshev_pseudospectral", - "z_discretization" => "chebyshev_pseudospectral", - "z_ngrid" => 9, - "z_nelement" => 6, # minimum nontrival nelement (even) - "z_element_spacing_option" => "sqrt", - "vpa_discretization" => "chebyshev_pseudospectral", - "vpa_ngrid" => 17, - "vpa_nelement" => 10, - "vz_discretization" => "chebyshev_pseudospectral", - "vz_ngrid" => 17, - "vz_nelement" => 10)) +test_input_chebyshev_sqrt_grid_odd = recursive_merge(test_input_finite_difference, + OptionsDict("run_name" => "chebyshev_pseudospectral", + "z" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 9, + "nelement" => 5, # minimum nontrival nelement (odd) + "element_spacing_option" => "sqrt"), + "vpa" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 17, + "nelement" => 10), + "vz" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 17, + "nelement" => 10), + )) +test_input_chebyshev_sqrt_grid_even = recursive_merge(test_input_finite_difference, + OptionsDict("run_name" => "chebyshev_pseudospectral", + "z" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 9, + "nelement" => 6, # minimum nontrival nelement (even) + "element_spacing_option" => "sqrt"), + "vpa" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 17, + "nelement" => 10), + "vz" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 17, + "nelement" => 10), + )) # Reference output interpolated onto a common set of points for comparing # different discretizations, taken from a Chebyshev run with z_grid=9, @@ -147,7 +149,7 @@ function run_test(test_input, expected_phi, tolerance; args...) input = deepcopy(test_input) # Convert keyword arguments to a unique name - name = input["run_name"] * ", with element spacing: " * input["z_element_spacing_option"] + name = input["run_name"] * ", with element spacing: " * input["z"]["element_spacing_option"] if length(args) > 0 name = string(name, "_", (string(k, "-", v, "_") for (k, v) in args)...) @@ -203,23 +205,10 @@ function run_test(test_input, expected_phi, tolerance; args...) end # Create coordinates - # - # create the 'input' struct containing input info needed to create a coordinate - # adv_input not actually used in this test so given values unimportant - adv_input = advection_input("default", 1.0, 0.0, 0.0) - cheb_option = "FFT" - nrank_per_block = 0 # dummy value - irank = 0 # dummy value - comm = MPI.COMM_NULL # dummy value - element_spacing_option = "uniform" - input = grid_input("coord", test_input["z_ngrid"], test_input["z_nelement"], - test_input["z_nelement"], nrank_per_block, irank, 1.0, - test_input["z_discretization"], "", cheb_option, test_input["z_bc"], - adv_input, comm, test_input["z_element_spacing_option"]) - z, z_spectral = define_coordinate(input; ignore_MPI=true) + z, z_spectral = define_coordinate(test_input, "z"; ignore_MPI=true) # Cross comparison of all discretizations to same benchmark - if test_input["z_element_spacing_option"] == "uniform" + if test_input["z"]["element_spacing_option"] == "uniform" # Only support this test for uniform element spacing. # phi is better resolved by "sqrt" spacing grid, so disagrees with benchmark data from # simulation with uniform element spacing. diff --git a/performance-tests/plot_performance.jl b/performance-tests/plot_performance.jl index 0328fa60c..44d0aa6e8 100644 --- a/performance-tests/plot_performance.jl +++ b/performance-tests/plot_performance.jl @@ -287,13 +287,13 @@ function get_grid_sizes(prefix) inputs_list = SoundWavePerformance.inputs_list # Use nz as the 'grid size' because that is the outer-loop in most of the 1D1V # code (basically everything apart from z_advection!()). - grid_sizes = [input["z_nelement"] * (input["z_ngrid"] - 1) + 1 + grid_sizes = [input["z"]["nelement"] * (input["z"]["ngrid"] - 1) + 1 for input in inputs_list] elseif prefix == "sound_wave-2xres" inputs_list = SoundWave2xResPerformance.inputs_list # Use nz as the 'grid size' because that is the outer-loop in most of the 1D1V # code (basically everything apart from z_advection!()). - grid_sizes = [input["z_nelement"] * (input["z_ngrid"] - 1) + 1 + grid_sizes = [input["z"]["nelement"] * (input["z"]["ngrid"] - 1) + 1 for input in inputs_list] else error("Unrecognized prefix $prefix") diff --git a/performance-tests/sound_wave-2xres.jl b/performance-tests/sound_wave-2xres.jl index 9622c0c12..d5c7ce1f7 100644 --- a/performance-tests/sound_wave-2xres.jl +++ b/performance-tests/sound_wave-2xres.jl @@ -2,6 +2,7 @@ module SoundWave2xResPerformance include("utils.jl") using .PerformanceTestUtils +using moment_kinetics.utils: recursive_merge const test_name = "sound_wave-2xres" @@ -14,100 +15,102 @@ const z_L = 1.0 # always 1 in normalized units? const vpa_L = 8.0 # default inputs for tests -test_input_finite_difference = Dict("n_ion_species" => 1, - "n_neutral_species" => 1, - "boltzmann_electron_response" => true, - "run_name" => "finite_difference", - "base_directory" => test_output_directory, - "evolve_moments_density" => false, - "evolve_moments_parallel_flow" => false, - "evolve_moments_parallel_pressure" => false, - "evolve_moments_conservation" => true, - "T_e" => 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.5, - "z_IC_density_phase1" => 0.0, - "z_IC_upar_amplitude1" => 0.0, - "z_IC_upar_phase1" => 0.0, - "z_IC_temperature_amplitude1" => 0.5, - "z_IC_temperature_phase1" => Float64(π), - "z_IC_option2" => "sinusoid", - "z_IC_density_amplitude2" => 0.5, - "z_IC_density_phase2" => Float64(π), - "z_IC_upar_amplitude2" => 0.0, - "z_IC_upar_phase2" => 0.0, - "z_IC_temperature_amplitude2" => 0.5, - "z_IC_temperature_phase2" => 0.0, - "charge_exchange_frequency" => 2*Float64(π)*0.1, - "ionization_frequency" => 0.0, - "timestepping" => Dict("nstep" => 100, - "dt" => 0.0002, - "nwrite" => 200, - "use_semi_lagrange" => false, - "n_rk_stages" => 4, - "split_operators" => false), - "r_ngrid" => 1, - "r_nelement" => 1, - "z_ngrid" => 161, - "z_nelement" => 1, - "z_bc" => "periodic", - "z_discretization" => "finite_difference", - "vpa_ngrid" => 481, - "vpa_nelement" => 1, - "vpa_L" => vpa_L, - "vpa_bc" => "periodic", - "vpa_discretization" => "finite_difference", - "vz_ngrid" => 481, - "vz_nelement" => 1, - "vz_L" => vpa_L, - "vz_bc" => "periodic", - "vz_discretization" => "finite_difference") +test_input_finite_difference = OptionsDict("n_ion_species" => 1, + "n_neutral_species" => 1, + "boltzmann_electron_response" => true, + "run_name" => "finite_difference", + "base_directory" => test_output_directory, + "evolve_moments_density" => false, + "evolve_moments_parallel_flow" => false, + "evolve_moments_parallel_pressure" => false, + "evolve_moments_conservation" => true, + "T_e" => 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.5, + "z_IC_density_phase1" => 0.0, + "z_IC_upar_amplitude1" => 0.0, + "z_IC_upar_phase1" => 0.0, + "z_IC_temperature_amplitude1" => 0.5, + "z_IC_temperature_phase1" => Float64(π), + "z_IC_option2" => "sinusoid", + "z_IC_density_amplitude2" => 0.5, + "z_IC_density_phase2" => Float64(π), + "z_IC_upar_amplitude2" => 0.0, + "z_IC_upar_phase2" => 0.0, + "z_IC_temperature_amplitude2" => 0.5, + "z_IC_temperature_phase2" => 0.0, + "charge_exchange_frequency" => 2*Float64(π)*0.1, + "ionization_frequency" => 0.0, + "timestepping" => Dict("nstep" => 100, + "dt" => 0.0002, + "nwrite" => 200, + "use_semi_lagrange" => false, + "n_rk_stages" => 4, + "split_operators" => false), + "r" => OptionsDict("ngrid" => 1, + "nelement" => 1), + "z" => OptionsDict("ngrid" => 161, + "nelement" => 1, + "bc" => "periodic", + "discretization" => "finite_difference"), + "vpa" => OptionsDict("ngrid" => 481, + "nelement" => 1, + "L" => vpa_L, + "bc" => "periodic", + "discretization" => "finite_difference"), + "vz" => OptionsDict("ngrid" => 481, + "nelement" => 1, + "L" => vpa_L, + "bc" => "periodic", + "discretization" => "finite_difference"), + ) test_input_finite_difference_split_1_moment = merge(test_input_finite_difference, - Dict("run_name" => "finite_difference_split_1_moment", - "evolve_moments_density" => true)) + OptionsDict("run_name" => "finite_difference_split_1_moment", + "evolve_moments_density" => true)) test_input_finite_difference_split_2_moments = merge(test_input_finite_difference_split_1_moment, - Dict("run_name" => "finite_difference_split_2_moments", - "evolve_moments_parallel_flow" => true)) + OptionsDict("run_name" => "finite_difference_split_2_moments", + "evolve_moments_parallel_flow" => true)) test_input_finite_difference_split_3_moments = merge(test_input_finite_difference_split_2_moments, - Dict("run_name" => "finite_difference_split_3_moments", - "evolve_moments_parallel_pressure" => true)) - -test_input_chebyshev = merge(test_input_finite_difference, - Dict("run_name" => "chebyshev_pseudospectral", - "z_discretization" => "chebyshev_pseudospectral", - "z_ngrid" => 9, - "z_nelement" => 20, - "vpa_discretization" => "chebyshev_pseudospectral", - "vpa_ngrid" => 34, - "vpa_nelement" => 15, - "vz_discretization" => "chebyshev_pseudospectral", - "vz_ngrid" => 34, - "vz_nelement" => 15)) + OptionsDict("run_name" => "finite_difference_split_3_moments", + "evolve_moments_parallel_pressure" => true)) + +test_input_chebyshev = recursive_merge(test_input_finite_difference, + OptionsDict("run_name" => "chebyshev_pseudospectral", + "z" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 9, + "nelement" => 20), + "vpa" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 34, + "nelement" => 15), + "vz" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 34, + "nelement" => 15), + )) test_input_chebyshev_split_1_moment = merge(test_input_chebyshev, - Dict("run_name" => "chebyshev_pseudospectral_split_1_moment", - "evolve_moments_density" => true)) + OptionsDict("run_name" => "chebyshev_pseudospectral_split_1_moment", + "evolve_moments_density" => true)) test_input_chebyshev_split_2_moments = merge(test_input_chebyshev_split_1_moment, - Dict("run_name" => "chebyshev_pseudospectral_split_2_moments", - "evolve_moments_parallel_flow" => true)) + OptionsDict("run_name" => "chebyshev_pseudospectral_split_2_moments", + "evolve_moments_parallel_flow" => true)) test_input_chebyshev_split_3_moments = merge(test_input_chebyshev_split_2_moments, - Dict("run_name" => "chebyshev_pseudospectral_split_3_moments", - "evolve_moments_parallel_pressure" => true)) + OptionsDict("run_name" => "chebyshev_pseudospectral_split_3_moments", + "evolve_moments_parallel_pressure" => true)) inputs_list = (test_input_finite_difference, test_input_finite_difference_split_1_moment, diff --git a/performance-tests/sound_wave.jl b/performance-tests/sound_wave.jl index 787c77189..9782bdfa5 100644 --- a/performance-tests/sound_wave.jl +++ b/performance-tests/sound_wave.jl @@ -2,6 +2,7 @@ module SoundWavePerformance include("utils.jl") using .PerformanceTestUtils +using moment_kinetics.utils: recursive_merge const test_name = "sound_wave" @@ -14,100 +15,102 @@ const z_L = 1.0 # always 1 in normalized units? const vpa_L = 8.0 # default inputs for tests -test_input_finite_difference = Dict("n_ion_species" => 1, - "n_neutral_species" => 1, - "boltzmann_electron_response" => true, - "run_name" => "finite_difference", - "base_directory" => test_output_directory, - "evolve_moments_density" => false, - "evolve_moments_parallel_flow" => false, - "evolve_moments_parallel_pressure" => false, - "evolve_moments_conservation" => true, - "T_e" => 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.5, - "z_IC_density_phase1" => 0.0, - "z_IC_upar_amplitude1" => 0.0, - "z_IC_upar_phase1" => 0.0, - "z_IC_temperature_amplitude1" => 0.5, - "z_IC_temperature_phase1" => Float64(π), - "z_IC_option2" => "sinusoid", - "z_IC_density_amplitude2" => 0.5, - "z_IC_density_phase2" => Float64(π), - "z_IC_upar_amplitude2" => 0.0, - "z_IC_upar_phase2" => 0.0, - "z_IC_temperature_amplitude2" => 0.5, - "z_IC_temperature_phase2" => 0.0, - "charge_exchange_frequency" => 2*Float64(π)*0.1, - "ionization_frequency" => 0.0, - "timestepping" => Dict( "nstep" => 100, - "dt" => 0.0005, - "nwrite" => 200, - "use_semi_lagrange" => false, - "n_rk_stages" => 4, - "split_operators" => false), - "r_ngrid" => 1, - "r_nelement" => 1, - "z_ngrid" => 81, - "z_nelement" => 1, - "z_bc" => "periodic", - "z_discretization" => "finite_difference", - "vpa_ngrid" => 241, - "vpa_nelement" => 1, - "vpa_L" => vpa_L, - "vpa_bc" => "periodic", - "vpa_discretization" => "finite_difference", - "vz_ngrid" => 241, - "vz_nelement" => 1, - "vz_L" => vpa_L, - "vz_bc" => "periodic", - "vz_discretization" => "finite_difference") +test_input_finite_difference = OptionsDict("n_ion_species" => 1, + "n_neutral_species" => 1, + "boltzmann_electron_response" => true, + "run_name" => "finite_difference", + "base_directory" => test_output_directory, + "evolve_moments_density" => false, + "evolve_moments_parallel_flow" => false, + "evolve_moments_parallel_pressure" => false, + "evolve_moments_conservation" => true, + "T_e" => 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.5, + "z_IC_density_phase1" => 0.0, + "z_IC_upar_amplitude1" => 0.0, + "z_IC_upar_phase1" => 0.0, + "z_IC_temperature_amplitude1" => 0.5, + "z_IC_temperature_phase1" => Float64(π), + "z_IC_option2" => "sinusoid", + "z_IC_density_amplitude2" => 0.5, + "z_IC_density_phase2" => Float64(π), + "z_IC_upar_amplitude2" => 0.0, + "z_IC_upar_phase2" => 0.0, + "z_IC_temperature_amplitude2" => 0.5, + "z_IC_temperature_phase2" => 0.0, + "charge_exchange_frequency" => 2*Float64(π)*0.1, + "ionization_frequency" => 0.0, + "timestepping" => OptionsDict( "nstep" => 100, + "dt" => 0.0005, + "nwrite" => 200, + "use_semi_lagrange" => false, + "n_rk_stages" => 4, + "split_operators" => false), + "r" => OptionsDict("ngrid" => 1, + "nelement" => 1), + "z" => OptionsDict("ngrid" => 81, + "nelement" => 1, + "bc" => "periodic", + "discretization" => "finite_difference"), + "vpa" => OptionsDict("ngrid" => 241, + "nelement" => 1, + "L" => vpa_L, + "bc" => "periodic", + "discretization" => "finite_difference"), + "vz" => OptionsDict("ngrid" => 241, + "nelement" => 1, + "L" => vpa_L, + "bc" => "periodic", + "discretization" => "finite_difference"), + ) test_input_finite_difference_split_1_moment = merge(test_input_finite_difference, - Dict("run_name" => "finite_difference_split_1_moment", - "evolve_moments_density" => true)) + OptionsDict("run_name" => "finite_difference_split_1_moment", + "evolve_moments_density" => true)) test_input_finite_difference_split_2_moments = merge(test_input_finite_difference_split_1_moment, - Dict("run_name" => "finite_difference_split_2_moments", - "evolve_moments_parallel_flow" => true)) + OptionsDict("run_name" => "finite_difference_split_2_moments", + "evolve_moments_parallel_flow" => true)) test_input_finite_difference_split_3_moments = merge(test_input_finite_difference_split_2_moments, - Dict("run_name" => "finite_difference_split_3_moments", - "evolve_moments_parallel_pressure" => true)) - -test_input_chebyshev = merge(test_input_finite_difference, - Dict("run_name" => "chebyshev_pseudospectral", - "z_discretization" => "chebyshev_pseudospectral", - "z_ngrid" => 9, - "z_nelement" => 10, - "vpa_discretization" => "chebyshev_pseudospectral", - "vpa_ngrid" => 17, - "vpa_nelement" => 15, - "vz_discretization" => "chebyshev_pseudospectral", - "vz_ngrid" => 17, - "vz_nelement" => 15)) + OptionsDict("run_name" => "finite_difference_split_3_moments", + "evolve_moments_parallel_pressure" => true)) + +test_input_chebyshev = recursive_merge(test_input_finite_difference, + OptionsDict("run_name" => "chebyshev_pseudospectral", + "z" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 9, + "nelement" => 10), + "vpa" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 17, + "nelement" => 15), + "vz" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 17, + "nelement" => 15), + )) test_input_chebyshev_split_1_moment = merge(test_input_chebyshev, - Dict("run_name" => "chebyshev_pseudospectral_split_1_moment", - "evolve_moments_density" => true)) + OptionsDict("run_name" => "chebyshev_pseudospectral_split_1_moment", + "evolve_moments_density" => true)) test_input_chebyshev_split_2_moments = merge(test_input_chebyshev_split_1_moment, - Dict("run_name" => "chebyshev_pseudospectral_split_2_moments", - "evolve_moments_parallel_flow" => true)) + OptionsDict("run_name" => "chebyshev_pseudospectral_split_2_moments", + "evolve_moments_parallel_flow" => true)) test_input_chebyshev_split_3_moments = merge(test_input_chebyshev_split_2_moments, - Dict("run_name" => "chebyshev_pseudospectral_split_3_moments", - "evolve_moments_parallel_pressure" => true)) + OptionsDict("run_name" => "chebyshev_pseudospectral_split_3_moments", + "evolve_moments_parallel_pressure" => true)) inputs_list = (test_input_finite_difference, test_input_finite_difference_split_1_moment, 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 a186acf1f..bb229c6f3 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 @@ -36,7 +36,6 @@ using moment_kinetics: check_so_newer_than_code using moment_kinetics.communication using moment_kinetics.quadrature: composite_simpson_weights using moment_kinetics.array_allocation: allocate_float -using moment_kinetics.coordinates: define_coordinate using moment_kinetics.file_io: open_ascii_output_file using moment_kinetics.type_definitions: mk_float, mk_int, OptionsDict using moment_kinetics.load_data: open_readonly_output_file, get_group, load_input, diff --git a/profiling/sound_wave_chebyshev.toml b/profiling/sound_wave_chebyshev.toml index 7f61d5c13..c5f070b49 100644 --- a/profiling/sound_wave_chebyshev.toml +++ b/profiling/sound_wave_chebyshev.toml @@ -24,15 +24,19 @@ z_IC_upar_phase2 = 0.0 z_IC_temperature_amplitude2 = 0.5 z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = 0.6283185307179586 -z_ngrid = 9 -z_nelement = 10 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 15 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" + +[z] +ngrid = 9 +nelement = 10 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 17 +nelement = 15 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" [timestepping] nstep = 100 diff --git a/profiling/sound_wave_chebyshev_split_1_moment.toml b/profiling/sound_wave_chebyshev_split_1_moment.toml index aa1f7fda2..5e01dbe80 100644 --- a/profiling/sound_wave_chebyshev_split_1_moment.toml +++ b/profiling/sound_wave_chebyshev_split_1_moment.toml @@ -25,15 +25,19 @@ z_IC_temperature_amplitude2 = 0.5 z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = 0.6283185307179586 ionization_frequency = 0.0 -z_ngrid = 9 -z_nelement = 10 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 15 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" + +[z] +ngrid = 9 +nelement = 10 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 17 +nelement = 15 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" [timestepping] nstep = 100 diff --git a/profiling/sound_wave_chebyshev_split_2_moments.toml b/profiling/sound_wave_chebyshev_split_2_moments.toml index f669c5e87..b7f2bd713 100644 --- a/profiling/sound_wave_chebyshev_split_2_moments.toml +++ b/profiling/sound_wave_chebyshev_split_2_moments.toml @@ -25,15 +25,19 @@ z_IC_temperature_amplitude2 = 0.5 z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = 0.6283185307179586 ionization_frequency = 0.0 -z_ngrid = 9 -z_nelement = 10 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 15 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" + +[z] +ngrid = 9 +nelement = 10 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 17 +nelement = 15 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" [timestepping] nstep = 100 diff --git a/profiling/sound_wave_chebyshev_split_3_moments.toml b/profiling/sound_wave_chebyshev_split_3_moments.toml index d7d85d963..0f8a71f5d 100644 --- a/profiling/sound_wave_chebyshev_split_3_moments.toml +++ b/profiling/sound_wave_chebyshev_split_3_moments.toml @@ -25,15 +25,19 @@ z_IC_temperature_amplitude2 = 0.5 z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = 0.6283185307179586 ionization_frequency = 0.0 -z_ngrid = 9 -z_nelement = 10 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 15 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" + +[z] +ngrid = 9 +nelement = 10 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 17 +nelement = 15 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" [timestepping] nstep = 100 diff --git a/profiling/sound_wave_finite_difference.toml b/profiling/sound_wave_finite_difference.toml index bd7b657ff..2f4aeb181 100644 --- a/profiling/sound_wave_finite_difference.toml +++ b/profiling/sound_wave_finite_difference.toml @@ -24,17 +24,23 @@ z_IC_upar_phase2 = 0.0 z_IC_temperature_amplitude2 = 0.5 z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = 0.6283185307179586 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 81 -z_nelement = 1 -z_bc = "periodic" -z_discretization = "finite_difference" -vpa_ngrid = 241 -vpa_nelement = 1 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "finite_difference" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 81 +nelement = 1 +bc = "periodic" +discretization = "finite_difference" + +[vpa] +ngrid = 241 +nelement = 1 +L = 8.0 +bc = "periodic" +discretization = "finite_difference" [timestepping] nstep = 100 diff --git a/profiling/sound_wave_finite_difference_split_1_moment.toml b/profiling/sound_wave_finite_difference_split_1_moment.toml index 1da0de40c..326b9927c 100644 --- a/profiling/sound_wave_finite_difference_split_1_moment.toml +++ b/profiling/sound_wave_finite_difference_split_1_moment.toml @@ -25,15 +25,19 @@ z_IC_temperature_amplitude2 = 0.5 z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = 0.6283185307179586 ionization_frequency = 0.0 -z_ngrid = 81 -z_nelement = 1 -z_bc = "periodic" -z_discretization = "finite_difference" -vpa_ngrid = 241 -vpa_nelement = 1 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "finite_difference" + +[z] +ngrid = 81 +nelement = 1 +bc = "periodic" +discretization = "finite_difference" + +[vpa] +ngrid = 241 +nelement = 1 +L = 8.0 +bc = "periodic" +discretization = "finite_difference" [timestepping] nstep = 100 diff --git a/profiling/sound_wave_finite_difference_split_2_moments.toml b/profiling/sound_wave_finite_difference_split_2_moments.toml index 103855ee7..9d82d9257 100644 --- a/profiling/sound_wave_finite_difference_split_2_moments.toml +++ b/profiling/sound_wave_finite_difference_split_2_moments.toml @@ -25,15 +25,19 @@ z_IC_temperature_amplitude2 = 0.5 z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = 0.6283185307179586 ionization_frequency = 0.0 -z_ngrid = 81 -z_nelement = 1 -z_bc = "periodic" -z_discretization = "finite_difference" -vpa_ngrid = 241 -vpa_nelement = 1 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "finite_difference" + +[z] +ngrid = 81 +nelement = 1 +bc = "periodic" +discretization = "finite_difference" + +[vpa] +ngrid = 241 +nelement = 1 +L = 8.0 +bc = "periodic" +discretization = "finite_difference" [timestepping] nstep = 100 diff --git a/profiling/sound_wave_finite_difference_split_3_moments.toml b/profiling/sound_wave_finite_difference_split_3_moments.toml index 6813dc3b6..24530c809 100644 --- a/profiling/sound_wave_finite_difference_split_3_moments.toml +++ b/profiling/sound_wave_finite_difference_split_3_moments.toml @@ -25,15 +25,19 @@ z_IC_temperature_amplitude2 = 0.5 z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = 0.6283185307179586 ionization_frequency = 0.0 -z_ngrid = 81 -z_nelement = 1 -z_bc = "periodic" -z_discretization = "finite_difference" -vpa_ngrid = 241 -vpa_nelement = 1 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "finite_difference" + +[z] +ngrid = 81 +nelement = 1 +bc = "periodic" +discretization = "finite_difference" + +[vpa] +ngrid = 241 +nelement = 1 +L = 8.0 +bc = "periodic" +discretization = "finite_difference" [timestepping] nstep = 100 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25.toml index 1326c87f1..a0938b0df 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25.toml @@ -27,22 +27,30 @@ z_IC_temperature_amplitude2 = 0.0 z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0] ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 17 -z_nelement = 2 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 8 -vpa_L = 4.0 -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 17 -vz_nelement = 8 -vz_L = 4.0 -vz_bc = "periodic" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 17 +nelement = 2 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 17 +nelement = 8 +L = 4.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 17 +nelement = 8 +L = 4.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" [timestepping] nstep = 1500 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split1.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split1.toml index 504d09589..7bb514b8a 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split1.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split1.toml @@ -27,22 +27,30 @@ z_IC_temperature_amplitude2 = 0.0 z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0] ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 17 -z_nelement = 2 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 8 -vpa_L = 4.0 -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 17 -vz_nelement = 8 -vz_L = 4.0 -vz_bc = "periodic" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 17 +nelement = 2 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 17 +nelement = 8 +L = 4.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 17 +nelement = 8 +L = 4.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" [timestepping] nstep = 1500 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split2.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split2.toml index 1ab1b753d..62b4543e3 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split2.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split2.toml @@ -27,22 +27,30 @@ z_IC_temperature_amplitude2 = 0.0 z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0] ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 17 -z_nelement = 2 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 8 -vpa_L = 4.0 -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 17 -vz_nelement = 8 -vz_L = 4.0 -vz_bc = "periodic" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 17 +nelement = 2 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 17 +nelement = 8 +L = 4.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 17 +nelement = 8 +L = 4.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" [timestepping] nstep = 1500 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split3.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split3.toml index fb6e88def..47b861a82 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split3.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split3.toml @@ -27,22 +27,30 @@ z_IC_temperature_amplitude2 = 0.0 z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0] ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 17 -z_nelement = 2 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 8 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 17 -vz_nelement = 8 -vz_L = 8.0 -vz_bc = "periodic" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 17 +nelement = 2 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 17 +nelement = 8 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 17 +nelement = 8 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" [timestepping] nstep = 1500 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5.toml index 782281348..6af74a930 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5.toml @@ -27,22 +27,30 @@ z_IC_temperature_amplitude2 = 0.0 z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4] ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 17 -z_nelement = 2 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 8 -vpa_L = 5.65685424949238 # 8/sqrt(2) -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 17 -vz_nelement = 8 -vz_L = 5.65685424949238 # 8/sqrt(2) -vz_bc = "periodic" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 17 +nelement = 2 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 17 +nelement = 8 +L = 5.65685424949238 # 8/sqrt(2) +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 17 +nelement = 8 +L = 5.65685424949238 # 8/sqrt(2) +bc = "periodic" +discretization = "chebyshev_pseudospectral" [timestepping] nstep = 1500 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split1.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split1.toml index b1c49ec79..c5731138f 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split1.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split1.toml @@ -27,22 +27,30 @@ z_IC_temperature_amplitude2 = 0.0 z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4] ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 17 -z_nelement = 2 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 8 -vpa_L = 5.65685424949238 # 8/sqrt(2) -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 17 -vz_nelement = 8 -vz_L = 5.65685424949238 # 8/sqrt(2) -vz_bc = "periodic" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 17 +nelement = 2 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 17 +nelement = 8 +L = 5.65685424949238 # 8/sqrt(2) +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 17 +nelement = 8 +L = 5.65685424949238 # 8/sqrt(2) +bc = "periodic" +discretization = "chebyshev_pseudospectral" [timestepping] nstep = 1500 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split2.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split2.toml index 71927242e..df1a136b1 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split2.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split2.toml @@ -27,22 +27,30 @@ z_IC_temperature_amplitude2 = 0.0 z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4] ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 17 -z_nelement = 2 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 8 -vpa_L = 5.65685424949238 # 8/sqrt(2) -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 17 -vz_nelement = 8 -vz_L = 5.65685424949238 # 8/sqrt(2) -vz_bc = "periodic" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 17 +nelement = 2 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 17 +nelement = 8 +L = 5.65685424949238 # 8/sqrt(2) +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 17 +nelement = 8 +L = 5.65685424949238 # 8/sqrt(2) +bc = "periodic" +discretization = "chebyshev_pseudospectral" [timestepping] nstep = 1500 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split3.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split3.toml index bfc24253b..901757332 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split3.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split3.toml @@ -27,22 +27,30 @@ z_IC_temperature_amplitude2 = 0.0 z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4] ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 17 -z_nelement = 2 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 8 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 17 -vz_nelement = 8 -vz_L = 8.0 -vz_bc = "periodic" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 17 +nelement = 2 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 17 +nelement = 8 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 17 +nelement = 8 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" [timestepping] nstep = 1500 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1.toml index 6a520568f..da37d3200 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1.toml @@ -27,22 +27,30 @@ z_IC_temperature_amplitude2 = 0.0 z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0, 5.2, 5.4, 5.6, 5.8, 6.0, 6.2] ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 17 -z_nelement = 2 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 8 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 17 -vz_nelement = 8 -vz_L = 8.0 -vz_bc = "periodic" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 17 +nelement = 2 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 17 +nelement = 8 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 17 +nelement = 8 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" [timestepping] nstep = 2500 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split1.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split1.toml index 37bbb8379..0f92f42eb 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split1.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split1.toml @@ -27,22 +27,30 @@ z_IC_temperature_amplitude2 = 0.0 z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0, 5.2, 5.4, 5.6, 5.8, 6.0, 6.2] ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 17 -z_nelement = 2 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 8 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 17 -vz_nelement = 8 -vz_L = 8.0 -vz_bc = "periodic" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 17 +nelement = 2 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 17 +nelement = 8 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 17 +nelement = 8 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" [timestepping] nstep = 2500 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split2.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split2.toml index acb8fae9a..a86119a79 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split2.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split2.toml @@ -27,22 +27,30 @@ z_IC_temperature_amplitude2 = 0.0 z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0, 5.2, 5.4, 5.6, 5.8, 6.0, 6.2] ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 17 -z_nelement = 2 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 8 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 17 -vz_nelement = 8 -vz_L = 8.0 -vz_bc = "periodic" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 17 +nelement = 2 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 17 +nelement = 8 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 17 +nelement = 8 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" [timestepping] nstep = 2500 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split3.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split3.toml index 6d6ee0b12..4d6d075ed 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split3.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split3.toml @@ -27,22 +27,30 @@ z_IC_temperature_amplitude2 = 0.0 z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0, 5.2, 5.4, 5.6, 5.8, 6.0, 6.2] ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 17 -z_nelement = 2 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 8 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 17 -vz_nelement = 8 -vz_L = 8.0 -vz_bc = "periodic" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 17 +nelement = 2 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 17 +nelement = 8 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 17 +nelement = 8 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" [timestepping] nstep = 2500 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2.toml index b3821d3d0..0cec40a73 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2.toml @@ -29,22 +29,30 @@ z_IC_temperature_amplitude2 = 0.0 z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.3, 0.6, 0.9, 1.2, 1.5, 1.8, 2.1, 2.4, 2.7, 3.0, 3.3, 3.6, 3.9, 4.2, 4.5, 4.8, 5.1, 5.4, 5.7, 6.0, 6.3, 6.6, 6.9, 7.2, 7.5, 7.8, 8.1, 8.4, 8.7] ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 17 -z_nelement = 2 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 8 -vpa_L = 11.313708498984761 # = 8*sqrt(2) -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 17 -vz_nelement = 8 -vz_L = 11.313708498984761 # = 8*sqrt(2) -vz_bc = "periodic" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 17 +nelement = 2 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 17 +nelement = 8 +L = 11.313708498984761 # = 8*sqrt(2) +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 17 +nelement = 8 +L = 11.313708498984761 # = 8*sqrt(2) +bc = "periodic" +discretization = "chebyshev_pseudospectral" [timestepping] nstep = 1800 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split1.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split1.toml index 45637d5c2..399ce5913 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split1.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split1.toml @@ -29,22 +29,30 @@ z_IC_temperature_amplitude2 = 0.0 z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.3, 0.6, 0.9, 1.2, 1.5, 1.8, 2.1, 2.4, 2.7, 3.0, 3.3, 3.6, 3.9, 4.2, 4.5, 4.8, 5.1, 5.4, 5.7, 6.0, 6.3, 6.6, 6.9, 7.2, 7.5, 7.8, 8.1, 8.4, 8.7] ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 17 -z_nelement = 2 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 8 -vpa_L = 11.313708498984761 # = 8*sqrt(2) -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 17 -vz_nelement = 8 -vz_L = 11.313708498984761 # = 8*sqrt(2) -vz_bc = "periodic" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 17 +nelement = 2 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 17 +nelement = 8 +L = 11.313708498984761 # = 8*sqrt(2) +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 17 +nelement = 8 +L = 11.313708498984761 # = 8*sqrt(2) +bc = "periodic" +discretization = "chebyshev_pseudospectral" [timestepping] nstep = 1800 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split2.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split2.toml index be029379d..e266e0e5e 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split2.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split2.toml @@ -29,22 +29,30 @@ z_IC_temperature_amplitude2 = 0.0 z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.3, 0.6, 0.9, 1.2, 1.5, 1.8, 2.1, 2.4, 2.7, 3.0, 3.3, 3.6, 3.9, 4.2, 4.5, 4.8, 5.1, 5.4, 5.7, 6.0, 6.3, 6.6, 6.9, 7.2, 7.5, 7.8, 8.1, 8.4, 8.7] ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 17 -z_nelement = 2 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 8 -vpa_L = 11.313708498984761 # = 8*sqrt(2) -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 17 -vz_nelement = 8 -vz_L = 11.313708498984761 # = 8*sqrt(2) -vz_bc = "periodic" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 17 +nelement = 2 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 17 +nelement = 8 +L = 11.313708498984761 # = 8*sqrt(2) +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 17 +nelement = 8 +L = 11.313708498984761 # = 8*sqrt(2) +bc = "periodic" +discretization = "chebyshev_pseudospectral" [timestepping] nstep = 1800 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split3.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split3.toml index ea349b6f9..c3a40e43d 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split3.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split3.toml @@ -29,22 +29,30 @@ z_IC_temperature_amplitude2 = 0.0 z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.3, 0.6, 0.9, 1.2, 1.5, 1.8, 2.1, 2.4, 2.7, 3.0, 3.3, 3.6, 3.9, 4.2, 4.5, 4.8, 5.1, 5.4, 5.7, 6.0, 6.3, 6.6, 6.9, 7.2, 7.5, 7.8, 8.1, 8.4, 8.7] ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 17 -z_nelement = 2 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 8 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 17 -vz_nelement = 8 -vz_L = 8.0 -vz_bc = "periodic" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 17 +nelement = 2 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 17 +nelement = 8 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 17 +nelement = 8 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" [timestepping] nstep = 1800 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4.toml index acb50aee4..20c5b69fa 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4.toml @@ -29,22 +29,30 @@ z_IC_temperature_amplitude2 = 0.0 z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.4, 0.8, 1.2, 1.6, 2.0, 2.4, 2.8, 3.2, 3.6, 4.0, 4.4, 4.8, 5.2, 5.6, 6.0, 6.4, 6.8, 7.2, 7.6, 8.0, 8.4, 8.8, 9.2, 9.6, 10.0, 10.4, 10.8, 11.2, 11.6, 12.0, 12.4] ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 17 -z_nelement = 2 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 8 -vpa_L = 16.0 -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 17 -vz_nelement = 8 -vz_L = 16.0 -vz_bc = "periodic" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 17 +nelement = 2 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 17 +nelement = 8 +L = 16.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 17 +nelement = 8 +L = 16.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" [timestepping] nstep = 3000 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split1.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split1.toml index 8d593b0c5..ba6605e97 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split1.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split1.toml @@ -29,22 +29,30 @@ z_IC_temperature_amplitude2 = 0.0 z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.4, 0.8, 1.2, 1.6, 2.0, 2.4, 2.8, 3.2, 3.6, 4.0, 4.4, 4.8, 5.2, 5.6, 6.0, 6.4, 6.8, 7.2, 7.6, 8.0, 8.4, 8.8, 9.2, 9.6, 10.0, 10.4, 10.8, 11.2, 11.6, 12.0, 12.4] ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 17 -z_nelement = 2 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 8 -vpa_L = 16.0 -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 17 -vz_nelement = 8 -vz_L = 16.0 -vz_bc = "periodic" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 17 +nelement = 2 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 17 +nelement = 8 +L = 16.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 17 +nelement = 8 +L = 16.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" [timestepping] nstep = 3000 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split2.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split2.toml index 50351e929..6de13c549 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split2.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split2.toml @@ -29,22 +29,30 @@ z_IC_temperature_amplitude2 = 0.0 z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.4, 0.8, 1.2, 1.6, 2.0, 2.4, 2.8, 3.2, 3.6, 4.0, 4.4, 4.8, 5.2, 5.6, 6.0, 6.4, 6.8, 7.2, 7.6, 8.0, 8.4, 8.8, 9.2, 9.6, 10.0, 10.4, 10.8, 11.2, 11.6, 12.0, 12.4] ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 17 -z_nelement = 2 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 8 -vpa_L = 16.0 -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 17 -vz_nelement = 8 -vz_L = 16.0 -vz_bc = "periodic" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 17 +nelement = 2 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 17 +nelement = 8 +L = 16.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 17 +nelement = 8 +L = 16.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" [timestepping] nstep = 3000 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split3.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split3.toml index 45420535f..d97c16f2b 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split3.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split3.toml @@ -29,22 +29,30 @@ z_IC_temperature_amplitude2 = 0.0 z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.4, 0.8, 1.2, 1.6, 2.0, 2.4, 2.8, 3.2, 3.6, 4.0, 4.4, 4.8, 5.2, 5.6, 6.0, 6.4, 6.8, 7.2, 7.6, 8.0, 8.4, 8.8, 9.2, 9.6, 10.0, 10.4, 10.8, 11.2, 11.6, 12.0, 12.4] ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 17 -z_nelement = 2 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 8 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 17 -vz_nelement = 8 -vz_L = 8.0 -vz_bc = "periodic" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 17 +nelement = 2 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 17 +nelement = 8 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 17 +nelement = 8 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" [timestepping] nstep = 3000 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio.toml index 4ea96b399..4ca582094 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio.toml @@ -27,22 +27,30 @@ z_IC_temperature_amplitude2 = 0.0 z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0, 5.2, 5.4, 5.6, 5.8, 6.0, 6.2] ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 17 -z_nelement = 2 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 8 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 17 -vz_nelement = 8 -vz_L = 8.0 -vz_bc = "periodic" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 17 +nelement = 2 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 17 +nelement = 8 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 17 +nelement = 8 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" [timestepping] nstep = 2500 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split1.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split1.toml index 56130d08c..315f41a1b 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split1.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split1.toml @@ -27,22 +27,30 @@ z_IC_temperature_amplitude2 = 0.0 z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0, 5.2, 5.4, 5.6, 5.8, 6.0, 6.2] ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 17 -z_nelement = 2 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 8 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 17 -vz_nelement = 8 -vz_L = 8.0 -vz_bc = "periodic" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 17 +nelement = 2 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 17 +nelement = 8 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 17 +nelement = 8 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" [timestepping] nstep = 2500 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split2.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split2.toml index 894acd85b..b7ece2021 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split2.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split2.toml @@ -27,22 +27,30 @@ z_IC_temperature_amplitude2 = 0.0 z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0, 5.2, 5.4, 5.6, 5.8, 6.0, 6.2] ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 17 -z_nelement = 2 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 8 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 17 -vz_nelement = 8 -vz_L = 8.0 -vz_bc = "periodic" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 17 +nelement = 2 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +pa_ngrid = 17 +pa_nelement = 8 +pa_L = 8.0 +pa_bc = "periodic" +pa_discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 17 +nelement = 8 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" [timestepping] nstep = 2500 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split3.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split3.toml index 4550dd608..bc7e695b7 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split3.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split3.toml @@ -27,22 +27,30 @@ z_IC_temperature_amplitude2 = 0.0 z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0, 5.2, 5.4, 5.6, 5.8, 6.0, 6.2] ionization_frequency = 0.0 -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 17 -z_nelement = 2 -z_bc = "periodic" -z_discretization = "chebyshev_pseudospectral" -vpa_ngrid = 17 -vpa_nelement = 8 -vpa_L = 8.0 -vpa_bc = "periodic" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 17 -vz_nelement = 8 -vz_L = 8.0 -vz_bc = "periodic" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 17 +nelement = 2 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vpa] +ngrid = 17 +nelement = 8 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 17 +nelement = 8 +L = 8.0 +bc = "periodic" +discretization = "chebyshev_pseudospectral" [timestepping] nstep = 2500 diff --git a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5.toml b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5.toml index 8943ac402..d44aa2bc4 100644 --- a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5.toml +++ b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5.toml @@ -47,24 +47,32 @@ vpa_IC_temperature_phase2 = 0.0 charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 9 -z_nelement = 32 -z_nelement_local = 4 -z_bc = "wall" -z_discretization = "chebyshev_pseudospectral" -z_element_spacing_option = "sqrt" -vpa_ngrid = 10 -vpa_nelement = 63 -vpa_L = 18.0 -vpa_bc = "zero" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 10 -vz_nelement = 63 -vz_L = 18.0 -vz_bc = "zero" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 9 +nelement = 32 +nelement_local = 4 +bc = "wall" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "sqrt" + +[vpa] +ngrid = 10 +nelement = 63 +L = 18.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 10 +nelement = 63 +L = 18.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" [timestepping] #nstep = 50000 diff --git a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split1.toml b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split1.toml index f7a1484d7..1a32e4ab0 100644 --- a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split1.toml +++ b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split1.toml @@ -47,24 +47,32 @@ vpa_IC_temperature_phase2 = 0.0 charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 9 -z_nelement = 32 -z_nelement_local = 4 -z_bc = "wall" -z_discretization = "chebyshev_pseudospectral" -z_element_spacing_option = "sqrt" -vpa_ngrid = 10 -vpa_nelement = 63 -vpa_L = 18.0 -vpa_bc = "zero" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 10 -vz_nelement = 63 -vz_L = 18.0 -vz_bc = "zero" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 9 +nelement = 32 +nelement_local = 4 +bc = "wall" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "sqrt" + +[vpa] +ngrid = 10 +nelement = 63 +L = 18.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 10 +nelement = 63 +L = 18.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" [timestepping] #nstep = 50000 diff --git a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split2.toml b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split2.toml index ef1a221cb..a1510e719 100644 --- a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split2.toml +++ b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split2.toml @@ -47,24 +47,32 @@ vpa_IC_temperature_phase2 = 0.0 charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 9 -z_nelement = 32 -z_nelement_local = 4 -z_bc = "wall" -z_discretization = "chebyshev_pseudospectral" -z_element_spacing_option = "sqrt" -vpa_ngrid = 10 -vpa_nelement = 63 -vpa_L = 18.0 -vpa_bc = "zero" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 10 -vz_nelement = 63 -vz_L = 18.0 -vz_bc = "zero" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 9 +nelement = 32 +nelement_local = 4 +bc = "wall" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "sqrt" + +[vpa] +ngrid = 10 +nelement = 63 +L = 18.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 10 +nelement = 63 +L = 18.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" [timestepping] #nstep = 50000 diff --git a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split3.toml b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split3.toml index 79c01a3be..fb6b51fcc 100644 --- a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split3.toml +++ b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split3.toml @@ -47,24 +47,32 @@ vpa_IC_temperature_phase2 = 0.0 charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false -r_ngrid = 1 -r_nelement = 1 -z_ngrid = 9 -z_nelement = 32 -z_nelement_local = 4 -z_bc = "wall" -z_discretization = "chebyshev_pseudospectral" -z_element_spacing_option = "sqrt" -vpa_ngrid = 10 -vpa_nelement = 63 -vpa_L = 36.0 -vpa_bc = "zero" -vpa_discretization = "chebyshev_pseudospectral" -vz_ngrid = 10 -vz_nelement = 63 -vz_L = 36.0 -vz_bc = "zero" -vz_discretization = "chebyshev_pseudospectral" + +[r] +ngrid = 1 +nelement = 1 + +[z] +ngrid = 9 +nelement = 32 +nelement_local = 4 +bc = "wall" +discretization = "chebyshev_pseudospectral" +element_spacing_option = "sqrt" + +[vpa] +ngrid = 10 +nelement = 63 +L = 36.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" + +[vz] +ngrid = 10 +nelement = 63 +L = 36.0 +bc = "zero" +discretization = "chebyshev_pseudospectral" [timestepping] #nstep = 50000 diff --git a/test_scripts/2D_FEM_assembly_test.jl b/test_scripts/2D_FEM_assembly_test.jl index 6dcfec726..bdb499490 100644 --- a/test_scripts/2D_FEM_assembly_test.jl +++ b/test_scripts/2D_FEM_assembly_test.jl @@ -7,11 +7,10 @@ using Measures using Dates import moment_kinetics using moment_kinetics.array_allocation: allocate_float, allocate_shared_float -using moment_kinetics.input_structs: grid_input, advection_input using moment_kinetics.coordinates: define_coordinate using moment_kinetics.chebyshev: setup_chebyshev_pseudospectral using moment_kinetics.gauss_legendre: setup_gausslegendre_pseudospectral, get_QQ_local! -using moment_kinetics.type_definitions: mk_float, mk_int +using moment_kinetics.type_definitions: mk_float, mk_int, OptionsDict using moment_kinetics.fokker_planck: init_fokker_planck_collisions_weak_form using moment_kinetics.fokker_planck: fokker_planck_collision_operator_weak_form! using moment_kinetics.fokker_planck: conserving_corrections! @@ -96,31 +95,29 @@ end # fd_option and adv_input not actually used so given values unimportant #discretization = "chebyshev_pseudospectral" discretization = "gausslegendre_pseudospectral" - fd_option = "fourth_order_centered" - cheb_option = "matrix" - adv_input = advection_input("default", 1.0, 0.0, 0.0) - nrank = 1 - irank = 0 - comm = MPI.COMM_NULL - # create the 'input' struct containing input info needed to create a - # coordinate element_spacing_option = "uniform" - vpa_input = grid_input("vpa", ngrid, nelement_global_vpa, nelement_local_vpa, - nrank, irank, Lvpa, discretization, fd_option, cheb_option, bc, adv_input,comm,element_spacing_option) - vperp_input = grid_input("vperp", ngrid, nelement_global_vperp, nelement_local_vperp, - nrank, irank, Lvperp, discretization, fd_option, cheb_option, bc, adv_input,comm,element_spacing_option) - # create the coordinate struct 'x' - println("made inputs") - println("vpa: ngrid: ",ngrid," nelement: ",nelement_local_vpa, " Lvpa: ",Lvpa) - println("vperp: ngrid: ",ngrid," nelement: ",nelement_local_vperp, " Lvperp: ",Lvperp) # Set up MPI if standalone initialize_comms!() end setup_distributed_memory_MPI(1,1,1,1) - vpa, vpa_spectral = define_coordinate(vpa_input) - vperp, vperp_spectral = define_coordinate(vperp_input) + coords_input = OptionsDict( + "vperp"=>OptionsDict("ngrid"=>ngrid, "nelement"=>nelement_global_vperp, + "nelement_local"=>nelement_local_vperp, "L"=>Lvperp, + "discretization"=>discretization, + "element_spacing_option"=>element_spacing_option), + "vpa"=>OptionsDict("ngrid"=>ngrid, "nelement"=>nelement_global_vpa, + "nelement_local"=>nelement_local_vpa, "L"=>Lvpa, + "discretization"=>discretization, + "element_spacing_option"=>element_spacing_option), + ) + println("made inputs") + println("vpa: ngrid: ",ngrid," nelement: ",nelement_local_vpa, " Lvpa: ",Lvpa) + println("vperp: ngrid: ",ngrid," nelement: ",nelement_local_vperp, " Lvperp: ",Lvperp) + # create the coordinate structs + vperp, vperp_spectral = define_coordinate(coords_input, "vperp") + vpa, vpa_spectral = define_coordinate(coords_input, "vpa") looping.setup_loop_ranges!(block_rank[], block_size[]; s=1, sn=1, r=1, z=1, vperp=vperp.n, vpa=vpa.n, diff --git a/test_scripts/GaussLobattoLegendre_test.jl b/test_scripts/GaussLobattoLegendre_test.jl index 80b865716..42fedec56 100644 --- a/test_scripts/GaussLobattoLegendre_test.jl +++ b/test_scripts/GaussLobattoLegendre_test.jl @@ -11,10 +11,10 @@ using Measures import moment_kinetics using moment_kinetics.gauss_legendre -using moment_kinetics.input_structs: grid_input, advection_input using moment_kinetics.coordinates: define_coordinate using moment_kinetics.calculus: derivative!, second_derivative!, laplacian_derivative! using moment_kinetics.calculus: mass_matrix_solve! +using moment_kinetics.type_definitions: OptionsDict function print_matrix(matrix,name,n,m) @@ -48,12 +48,6 @@ using moment_kinetics.calculus: mass_matrix_solve! bc = "zero" discretization = "gausslegendre_pseudospectral" # fd_option and adv_input not actually used so given values unimportant - fd_option = "fourth_order_centered" - cheb_option = "matrix" - adv_input = advection_input("default", 1.0, 0.0, 0.0) - nrank = 1 - irank = 0#1 - comm = MPI.COMM_NULL element_spacing_option = "uniform" # create the 'input' struct containing input info needed to create a # coordinate @@ -66,11 +60,14 @@ using moment_kinetics.calculus: mass_matrix_solve! else y_L = 2*L_in end - y_input = grid_input(y_name, y_ngrid, y_nelement_global, y_nelement_local, - nrank, irank, y_L, discretization, fd_option, cheb_option, bc, adv_input,comm,element_spacing_option) - - # create the coordinate structs - y, y_spectral = define_coordinate(y_input,init_YY=false) + input = OptionsDict(y_name => OptionsDict("ngrid"=>y_ngrid, "nelement"=>y_nelement_global, + "nelement_local"=>y_nelement_local, "L"=>y_L, + "discretization"=>discretization, + "element_spacing_option"=>element_spacing_option)) + # create the coordinate struct 'x' + # This test runs effectively in serial, so use `ignore_MPI=true` to avoid + # errors due to communicators not being fully set up. + y, y_spectral = define_coordinate(input, y_name; collision_operator_dim=true, ignore_MPI=true) #print_matrix(Mmat,"Mmat",y.n,y.n) #print_matrix(y_spectral.radau.M0,"local radau mass matrix M0",y.ngrid,y.ngrid) #print_matrix(y_spectral.radau.M1,"local radau mass matrix M1",y.ngrid,y.ngrid) diff --git a/test_scripts/cheb_matrix_test.jl b/test_scripts/cheb_matrix_test.jl index 9c6324ecd..311611c1d 100644 --- a/test_scripts/cheb_matrix_test.jl +++ b/test_scripts/cheb_matrix_test.jl @@ -4,676 +4,648 @@ using LaTeXStrings using MPI using Measures -if abspath(PROGRAM_FILE) == @__FILE__ - using Pkg - Pkg.activate(".") +using Pkg +Pkg.activate(".") - import moment_kinetics - using moment_kinetics.input_structs: grid_input, advection_input - using moment_kinetics.coordinates: define_coordinate - using moment_kinetics.chebyshev: setup_chebyshev_pseudospectral, chebyshev_radau_derivative_single_element! - using moment_kinetics.calculus: derivative!, integral - #import LinearAlgebra - #using IterativeSolvers: jacobi!, gauss_seidel!, idrs! - using LinearAlgebra: mul!, lu, cond, det - using SparseArrays: sparse - using SpecialFunctions: erf - zero = 1.0e-10 - - function print_matrix(matrix,name,n,m) - println("\n ",name," \n") - for i in 1:n - for j in 1:m - @printf("%.1f ", matrix[i,j]) - end - println("") - end - println("\n") - end - - function print_vector(vector,name,m) - println("\n ",name," \n") +import moment_kinetics + using moment_kinetics.coordinates: define_coordinate + using moment_kinetics.chebyshev: setup_chebyshev_pseudospectral, chebyshev_radau_derivative_single_element! + using moment_kinetics.calculus: derivative!, integral +using moment_kinetics.type_definitions: OptionsDict +#import LinearAlgebra +#using IterativeSolvers: jacobi!, gauss_seidel!, idrs! +using LinearAlgebra: mul!, lu, cond, det +using SparseArrays: sparse +using SpecialFunctions: erf +zero = 1.0e-10 + +function print_matrix(matrix,name,n,m) + println("\n ",name," \n") + for i in 1:n for j in 1:m - @printf("%.3f ", vector[j]) + @printf("%.1f ", matrix[i,j]) end println("") - println("\n") - end - - function Djj(x::Array{Float64,1},j::Int64) - return -0.5*x[j]/( 1.0 - x[j]^2) end - function Djk(x::Array{Float64,1},j::Int64,k::Int64,c_j::Float64,c_k::Float64) - return (c_j/c_k)*((-1)^(k+j))/(x[j] - x[k]) + println("\n") +end + +function print_vector(vector,name,m) + println("\n ",name," \n") + for j in 1:m + @printf("%.3f ", vector[j]) end + println("") + println("\n") +end + +function Djj(x::Array{Float64,1},j::Int64) + return -0.5*x[j]/( 1.0 - x[j]^2) +end +function Djk(x::Array{Float64,1},j::Int64,k::Int64,c_j::Float64,c_k::Float64) + return (c_j/c_k)*((-1)^(k+j))/(x[j] - x[k]) +end + +""" +The function below is based on the numerical method outlined in +Chapter 8.2 from Trefethen 1994 +https://people.maths.ox.ac.uk/trefethen/8all.pdf +full list of Chapters may be obtained here +https://people.maths.ox.ac.uk/trefethen/pdetext.html +""" + +function cheb_derivative_matrix!(D::Array{Float64,2},x::Array{Float64,1},n) + D[:,:] .= 0.0 - """ - The function below is based on the numerical method outlined in - Chapter 8.2 from Trefethen 1994 - https://people.maths.ox.ac.uk/trefethen/8all.pdf - full list of Chapters may be obtained here - https://people.maths.ox.ac.uk/trefethen/pdetext.html - """ + # top left, bottom right + D[1,1] = (2.0*(n - 1.0)^2 + 1.0)/6.0 + D[n,n] = -(2.0*(n - 1.0)^2 + 1.0)/6.0 - function cheb_derivative_matrix!(D::Array{Float64,2},x::Array{Float64,1},n) - D[:,:] .= 0.0 - - # top left, bottom right - D[1,1] = (2.0*(n - 1.0)^2 + 1.0)/6.0 - D[n,n] = -(2.0*(n - 1.0)^2 + 1.0)/6.0 - - # top row - j = 1 - c_j = 2.0 - c_k = 1.0 - for k in 2:n-1 - D[j,k] = Djk(x,j,k,c_j,c_k) - end - k = n - c_k = 2.0 - D[j,k] = Djk(x,j,k,c_j,c_k) - - # bottom row - j = n - c_j = 2.0 - c_k = 1.0 - for k in 2:n-1 - D[j,k] = Djk(x,j,k,c_j,c_k) - end - k = 1 - c_k = 2.0 + # top row + j = 1 + c_j = 2.0 + c_k = 1.0 + for k in 2:n-1 D[j,k] = Djk(x,j,k,c_j,c_k) - - #left column - k = 1 - c_j = 1.0 - c_k = 2.0 - for j in 2:n-1 - D[j,k] = Djk(x,j,k,c_j,c_k) - end - - #right column - k = n - c_j = 1.0 - c_k = 2.0 - for j in 2:n-1 - D[j,k] = Djk(x,j,k,c_j,c_k) - end - - # interior rows and columns - for j in 2:n-1 - D[j,j] = Djj(x,j) - #D[j,j] = -0.5*x[j]/( 1.0 - x[j]^2) - for k in 2:n-1 - if j == k - continue - end - c_k = 1.0 - c_j = 1.0 - #D[j,k] = (c_j/c_k)*((-1)^(k+j))/(x[j] - x[k]) - D[j,k] = Djk(x,j,k,c_j,c_k) - end - end - end - - function cheb_derivative_matrix_reversed!(D::Array{Float64,2},x) - D_elementwise = Array{Float64,2}(undef,x.ngrid,x.ngrid) - cheb_derivative_matrix_elementwise_reversed!(D_elementwise,x.ngrid,x.L,x.nelement_global) - if x.ngrid < 8 - println("\n D_elementwise \n") - for i in 1:x.ngrid - for j in 1:x.ngrid - @printf("%.1f ", D_elementwise[i,j]) - end - println("") - end - end - assign_cheb_derivative_matrix!(D,D_elementwise,x) end + k = n + c_k = 2.0 + D[j,k] = Djk(x,j,k,c_j,c_k) - function cheb_second_derivative_matrix_reversed!(D::Array{Float64,2},x) - D_elementwise = Array{Float64,2}(undef,x.ngrid,x.ngrid) - cheb_derivative_matrix_elementwise_reversed!(D_elementwise,x.ngrid,x.L,x.nelement_global) - D2_elementwise = Array{Float64,2}(undef,x.ngrid,x.ngrid) - mul!(D2_elementwise,D_elementwise,D_elementwise) - if x.ngrid < 8 - print_matrix(D2_elementwise,"D2_elementwise",x.ngrid,x.ngrid) - end - assign_cheb_derivative_matrix!(D,D2_elementwise,x) + # bottom row + j = n + c_j = 2.0 + c_k = 1.0 + for k in 2:n-1 + D[j,k] = Djk(x,j,k,c_j,c_k) end + k = 1 + c_k = 2.0 + D[j,k] = Djk(x,j,k,c_j,c_k) - function assign_cheb_derivative_matrix!(D::Array{Float64,2},D_elementwise::Array{Float64,2},x) - - # zero output matrix before assignment - D[:,:] .= 0.0 - imin = x.imin - imax = x.imax - - zero_bc_upper_boundary = x.bc == "zero" || x.bc == "zero_upper" - zero_bc_lower_boundary = x.bc == "zero" || x.bc == "zero_lower" - - # fill in first element - j = 1 - if zero_bc_lower_boundary #x.bc == "zero" - D[imin[j],imin[j]:imax[j]] .+= D_elementwise[1,:]./2.0 #contributions from this element/2 - D[imin[j],imin[j]] += D_elementwise[x.ngrid,x.ngrid]/2.0 #contribution from missing `zero' element/2 - else - D[imin[j],imin[j]:imax[j]] .+= D_elementwise[1,:] - end - for k in 2:imax[j]-imin[j] - D[k,imin[j]:imax[j]] .+= D_elementwise[k,:] - end - if zero_bc_upper_boundary && x.nelement_local == 1 - D[imax[j],imin[j]-1:imax[j]] .+= D_elementwise[x.ngrid,:]./2.0 #contributions from this element/2 - D[imax[j],imax[j]] += D_elementwise[1,1]/2.0 #contribution from missing `zero' element/2 - elseif x.nelement_local > 1 #x.bc == "zero" - D[imax[j],imin[j]:imax[j]] .+= D_elementwise[x.ngrid,:]./2.0 - else - D[imax[j],imin[j]:imax[j]] .+= D_elementwise[x.ngrid,:] - end - # remaining elements recalling definitions of imax and imin - for j in 2:x.nelement_local - #lower boundary condition on element - D[imin[j]-1,imin[j]-1:imax[j]] .+= D_elementwise[1,:]./2.0 - for k in 2:imax[j]-imin[j]+1 - D[k+imin[j]-2,imin[j]-1:imax[j]] .+= D_elementwise[k,:] - end - # upper boundary condition on element - if j == x.nelement_local && !(zero_bc_upper_boundary) - D[imax[j],imin[j]-1:imax[j]] .+= D_elementwise[x.ngrid,:] - elseif j == x.nelement_local && zero_bc_upper_boundary - D[imax[j],imin[j]-1:imax[j]] .+= D_elementwise[x.ngrid,:]./2.0 #contributions from this element/2 - D[imax[j],imax[j]] += D_elementwise[1,1]/2.0 #contribution from missing `zero' element/2 - else - D[imax[j],imin[j]-1:imax[j]] .+= D_elementwise[x.ngrid,:]./2.0 - end - end - + #left column + k = 1 + c_j = 1.0 + c_k = 2.0 + for j in 2:n-1 + D[j,k] = Djk(x,j,k,c_j,c_k) end - function cheb_derivative_matrix_elementwise_reversed!(D::Array{Float64,2},n::Int64,L::Float64,nelement::Int64) - - #define Chebyshev points in reversed order x_j = { -1, ... , 1} - x = Array{Float64,1}(undef,n) - for j in 1:n - x[j] = cospi((n-j)/(n-1)) - end - - # zero matrix before allocating values - D[:,:] .= 0.0 - - # top row - j = 1 - c_j = 2.0 - c_k = 1.0 - for k in 2:n-1 - D[j,k] = Djk(x,j,k,c_j,c_k) - end - k = n - c_k = 2.0 + #right column + k = n + c_j = 1.0 + c_k = 2.0 + for j in 2:n-1 D[j,k] = Djk(x,j,k,c_j,c_k) - - # bottom row - j = n - c_j = 2.0 - c_k = 1.0 + end + + # interior rows and columns + for j in 2:n-1 + D[j,j] = Djj(x,j) + #D[j,j] = -0.5*x[j]/( 1.0 - x[j]^2) for k in 2:n-1 + if j == k + continue + end + c_k = 1.0 + c_j = 1.0 + #D[j,k] = (c_j/c_k)*((-1)^(k+j))/(x[j] - x[k]) D[j,k] = Djk(x,j,k,c_j,c_k) end - k = 1 - c_k = 2.0 - D[j,k] = Djk(x,j,k,c_j,c_k) - - #left column - k = 1 - c_j = 1.0 - c_k = 2.0 - for j in 2:n-1 - D[j,k] = Djk(x,j,k,c_j,c_k) - end - - #right column - k = n - c_j = 1.0 - c_k = 2.0 - for j in 2:n-1 - D[j,k] = Djk(x,j,k,c_j,c_k) - end - - - # top left, bottom right - #D[n,n] = (2.0*(n - 1.0)^2 + 1.0)/6.0 - #D[1,1] = -(2.0*(n - 1.0)^2 + 1.0)/6.0 - # interior rows and columns - for j in 2:n-1 - #D[j,j] = Djj(x,j) - for k in 2:n-1 - if j == k - continue - end - c_k = 1.0 - c_j = 1.0 - D[j,k] = Djk(x,j,k,c_j,c_k) + end +end + +function cheb_derivative_matrix_reversed!(D::Array{Float64,2},x) + D_elementwise = Array{Float64,2}(undef,x.ngrid,x.ngrid) + cheb_derivative_matrix_elementwise_reversed!(D_elementwise,x.ngrid,x.L,x.nelement_global) + if x.ngrid < 8 + println("\n D_elementwise \n") + for i in 1:x.ngrid + for j in 1:x.ngrid + @printf("%.1f ", D_elementwise[i,j]) end + println("") end - - # calculate diagonal entries to guarantee that - # D * (1, 1, ..., 1, 1) = (0, 0, ..., 0, 0) - for j in 1:n - D[j,j] = -sum(D[j,:]) - end - - #multiply by scale factor for element length - D .= (2.0*float(nelement)/L).*D end + assign_cheb_derivative_matrix!(D,D_elementwise,x) +end + +function cheb_second_derivative_matrix_reversed!(D::Array{Float64,2},x) + D_elementwise = Array{Float64,2}(undef,x.ngrid,x.ngrid) + cheb_derivative_matrix_elementwise_reversed!(D_elementwise,x.ngrid,x.L,x.nelement_global) + D2_elementwise = Array{Float64,2}(undef,x.ngrid,x.ngrid) + mul!(D2_elementwise,D_elementwise,D_elementwise) + if x.ngrid < 8 + print_matrix(D2_elementwise,"D2_elementwise",x.ngrid,x.ngrid) + end + assign_cheb_derivative_matrix!(D,D2_elementwise,x) +end + +function assign_cheb_derivative_matrix!(D::Array{Float64,2},D_elementwise::Array{Float64,2},x) + + # zero output matrix before assignment + D[:,:] .= 0.0 + imin = x.imin + imax = x.imax - """ - derivative matrix for radau grid - """ - function calculate_chebyshev_radau_D_matrix_via_FFT!(D::Array{Float64,2}, coord, spectral) - ff_buffer = Array{Float64,1}(undef,coord.ngrid) - df_buffer = Array{Float64,1}(undef,coord.ngrid) - # use response matrix approach to calculate derivative matrix D - for j in 1:coord.ngrid - ff_buffer .= 0.0 - ff_buffer[j] = 1.0 - @views chebyshev_radau_derivative_single_element!(df_buffer[:], ff_buffer[:], - spectral.radau.f[:,1], spectral.radau.df, spectral.radau.fext, spectral.radau.forward, coord) - @. D[:,j] = df_buffer[:] # assign appropriate column of derivative matrix + zero_bc_upper_boundary = x.bc == "zero" || x.bc == "zero_upper" + zero_bc_lower_boundary = x.bc == "zero" || x.bc == "zero_lower" + + # fill in first element + j = 1 + if zero_bc_lower_boundary #x.bc == "zero" + D[imin[j],imin[j]:imax[j]] .+= D_elementwise[1,:]./2.0 #contributions from this element/2 + D[imin[j],imin[j]] += D_elementwise[x.ngrid,x.ngrid]/2.0 #contribution from missing `zero' element/2 + else + D[imin[j],imin[j]:imax[j]] .+= D_elementwise[1,:] + end + for k in 2:imax[j]-imin[j] + D[k,imin[j]:imax[j]] .+= D_elementwise[k,:] + end + if zero_bc_upper_boundary && x.nelement_local == 1 + D[imax[j],imin[j]-1:imax[j]] .+= D_elementwise[x.ngrid,:]./2.0 #contributions from this element/2 + D[imax[j],imax[j]] += D_elementwise[1,1]/2.0 #contribution from missing `zero' element/2 + elseif x.nelement_local > 1 #x.bc == "zero" + D[imax[j],imin[j]:imax[j]] .+= D_elementwise[x.ngrid,:]./2.0 + else + D[imax[j],imin[j]:imax[j]] .+= D_elementwise[x.ngrid,:] + end + # remaining elements recalling definitions of imax and imin + for j in 2:x.nelement_local + #lower boundary condition on element + D[imin[j]-1,imin[j]-1:imax[j]] .+= D_elementwise[1,:]./2.0 + for k in 2:imax[j]-imin[j]+1 + D[k+imin[j]-2,imin[j]-1:imax[j]] .+= D_elementwise[k,:] end - # correct diagonal elements to gurantee numerical stability - # gives D*[1.0, 1.0, ... 1.0] = [0.0, 0.0, ... 0.0] - for j in 1:coord.ngrid - D[j,j] = 0.0 - D[j,j] = -sum(D[j,:]) + # upper boundary condition on element + if j == x.nelement_local && !(zero_bc_upper_boundary) + D[imax[j],imin[j]-1:imax[j]] .+= D_elementwise[x.ngrid,:] + elseif j == x.nelement_local && zero_bc_upper_boundary + D[imax[j],imin[j]-1:imax[j]] .+= D_elementwise[x.ngrid,:]./2.0 #contributions from this element/2 + D[imax[j],imax[j]] += D_elementwise[1,1]/2.0 #contribution from missing `zero' element/2 + else + D[imax[j],imin[j]-1:imax[j]] .+= D_elementwise[x.ngrid,:]./2.0 end - - #multiply by scale factor for element length - D .= (2.0*float(coord.nelement_global)/coord.L).*D end - function cheb_radau_derivative_matrix_reversed!(D::Array{Float64,2},x,x_spectral) - D_lobotto_elementwise = Array{Float64,2}(undef,x.ngrid,x.ngrid) - cheb_derivative_matrix_elementwise_reversed!(D_lobotto_elementwise,x.ngrid,x.L,x.nelement_global) +end - D_radau_elementwise = Array{Float64,2}(undef,x.ngrid,x.ngrid) - calculate_chebyshev_radau_D_matrix_via_FFT!(D_radau_elementwise,x,x_spectral) - if x.ngrid < 8 - print_matrix(D_lobotto_elementwise,"D_lobotto_elementwise",x.ngrid,x.ngrid) - print_matrix(D_radau_elementwise,"D_radau_elementwise",x.ngrid,x.ngrid) - end - assign_cheb_derivative_matrix!(D,D_lobotto_elementwise,D_radau_elementwise,x) +function cheb_derivative_matrix_elementwise_reversed!(D::Array{Float64,2},n::Int64,L::Float64,nelement::Int64) + + #define Chebyshev points in reversed order x_j = { -1, ... , 1} + x = Array{Float64,1}(undef,n) + for j in 1:n + x[j] = cospi((n-j)/(n-1)) end - - function cheb_radau_second_derivative_matrix_reversed!(D::Array{Float64,2},x,x_spectral) - D_lobotto_elementwise = Array{Float64,2}(undef,x.ngrid,x.ngrid) - cheb_derivative_matrix_elementwise_reversed!(D_lobotto_elementwise,x.ngrid,x.L,x.nelement_global) - D2_lobotto_elementwise = Array{Float64,2}(undef,x.ngrid,x.ngrid) - mul!(D2_lobotto_elementwise,D_lobotto_elementwise,D_lobotto_elementwise) - - D_radau_elementwise = Array{Float64,2}(undef,x.ngrid,x.ngrid) - calculate_chebyshev_radau_D_matrix_via_FFT!(D_radau_elementwise,x,x_spectral) - D2_radau_elementwise = Array{Float64,2}(undef,x.ngrid,x.ngrid) - mul!(D2_radau_elementwise,D_radau_elementwise,D_radau_elementwise) - - if x.ngrid < 8 - #print_matrix(D_lobotto_elementwise,"D_lobotto_elementwise",x.ngrid,x.ngrid) - print_matrix(D2_lobotto_elementwise,"D2_lobotto_elementwise",x.ngrid,x.ngrid) - #print_matrix(D_radau_elementwise,"D_radau_elementwise",x.ngrid,x.ngrid) - print_matrix(D2_radau_elementwise,"D2_radau_elementwise",x.ngrid,x.ngrid) - end - assign_cheb_derivative_matrix!(D,D2_lobotto_elementwise,D2_radau_elementwise,x) + + # zero matrix before allocating values + D[:,:] .= 0.0 + + # top row + j = 1 + c_j = 2.0 + c_k = 1.0 + for k in 2:n-1 + D[j,k] = Djk(x,j,k,c_j,c_k) end + k = n + c_k = 2.0 + D[j,k] = Djk(x,j,k,c_j,c_k) + # bottom row + j = n + c_j = 2.0 + c_k = 1.0 + for k in 2:n-1 + D[j,k] = Djk(x,j,k,c_j,c_k) + end + k = 1 + c_k = 2.0 + D[j,k] = Djk(x,j,k,c_j,c_k) - function assign_cheb_derivative_matrix!(D::Array{Float64,2},D_lobotto_elementwise::Array{Float64,2},D_radau_elementwise::Array{Float64,2},x) - - # zero output matrix before assignment - D[:,:] .= 0.0 - imin = x.imin - imax = x.imax - - zero_bc_upper_boundary = x.bc == "zero" || x.bc == "zero_upper" - zero_bc_lower_boundary = x.bc == "zero" || x.bc == "zero_lower" - - # fill in first element - j = 1 - if zero_bc_lower_boundary #x.bc == "zero" - D[imin[j],imin[j]:imax[j]] .+= D_radau_elementwise[1,:]./2.0 #contributions from this element/2 - D[imin[j],imin[j]] += D_radau_elementwise[x.ngrid,x.ngrid]/2.0 #contribution from missing `zero' element/2 - else - D[imin[j],imin[j]:imax[j]] .+= D_radau_elementwise[1,:] - end - for k in 2:imax[j]-imin[j] - D[k,imin[j]:imax[j]] .+= D_radau_elementwise[k,:] - end - if zero_bc_upper_boundary && x.nelement_local == 1 - D[imax[j],imin[j]-1:imax[j]] .+= D_radau_elementwise[x.ngrid,:]./2.0 #contributions from this element/2 - D[imax[j],imax[j]] += D_lobotto_elementwise[1,1]/2.0 #contribution from missing `zero' element/2 - elseif x.nelement_local > 1 #x.bc == "zero" - D[imax[j],imin[j]:imax[j]] .+= D_radau_elementwise[x.ngrid,:]./2.0 - else - D[imax[j],imin[j]:imax[j]] .+= D_radau_elementwise[x.ngrid,:] - end - # remaining elements recalling definitions of imax and imin - for j in 2:x.nelement_local - #lower boundary condition on element - D[imin[j]-1,imin[j]-1:imax[j]] .+= D_lobotto_elementwise[1,:]./2.0 - for k in 2:imax[j]-imin[j]+1 - D[k+imin[j]-2,imin[j]-1:imax[j]] .+= D_lobotto_elementwise[k,:] - end - # upper boundary condition on element - if j == x.nelement_local && !(zero_bc_upper_boundary) - D[imax[j],imin[j]-1:imax[j]] .+= D_lobotto_elementwise[x.ngrid,:] - elseif j == x.nelement_local && zero_bc_upper_boundary - D[imax[j],imin[j]-1:imax[j]] .+= D_lobotto_elementwise[x.ngrid,:]./2.0 #contributions from this element/2 - D[imax[j],imax[j]] += D_lobotto_elementwise[1,1]/2.0 #contribution from missing `zero' element/2 - else - D[imax[j],imin[j]-1:imax[j]] .+= D_lobotto_elementwise[x.ngrid,:]./2.0 - end - end - + #left column + k = 1 + c_j = 1.0 + c_k = 2.0 + for j in 2:n-1 + D[j,k] = Djk(x,j,k,c_j,c_k) end - """ - function integrating d y / d t = f(t) - """ - function forward_euler_step!(ynew,yold,f,dt,n) - for i in 1:n - ynew[i] = yold[i] + dt*f[i] - end + #right column + k = n + c_j = 1.0 + c_k = 2.0 + for j in 2:n-1 + D[j,k] = Djk(x,j,k,c_j,c_k) end - """ - function creating lu object for A = I - dt*nu*D2 - """ - function diffusion_matrix(D2,n,dt,nu;return_A=false) - A = Array{Float64,2}(undef,n,n) - for i in 1:n - for j in 1:n - A[i,j] = - dt*nu*D2[i,j] + + + # top left, bottom right + #D[n,n] = (2.0*(n - 1.0)^2 + 1.0)/6.0 + #D[1,1] = -(2.0*(n - 1.0)^2 + 1.0)/6.0 + # interior rows and columns + for j in 2:n-1 + #D[j,j] = Djj(x,j) + for k in 2:n-1 + if j == k + continue end - A[i,i] += 1.0 - end - lu_obj = lu(A) - if return_A - return lu_obj, A - else - return lu_obj + c_k = 1.0 + c_j = 1.0 + D[j,k] = Djk(x,j,k,c_j,c_k) end end - """ - functions for Rosenbluth potential tests - """ - function dH_Maxwellian_dvpa(vpa,vperp,ivpa,ivperp) - # speed variable - eta = sqrt(vpa.grid[ivpa]^2 + vperp.grid[ivperp]^2) - zero = 1.0e-10 - if eta < zero - dHdvpa = -(4.0*vpa.grid[ivpa])/(3.0*sqrt(pi)) - else - dHdvpa = (vpa.grid[ivpa]/eta)*((2.0/sqrt(pi))*(exp(-eta^2)/eta) - (erf(eta)/(eta^2))) - end - return dHdvpa + # calculate diagonal entries to guarantee that + # D * (1, 1, ..., 1, 1) = (0, 0, ..., 0, 0) + for j in 1:n + D[j,j] = -sum(D[j,:]) end - function d2H_Maxwellian_dvpa2(vpa,vperp,ivpa,ivperp) - # speed variable - eta = sqrt(vpa.grid[ivpa]^2 + vperp.grid[ivperp]^2) - zero = 1.0e-10 - if eta < zero - dHdeta_over_eta = -4.0/(3.0*sqrt(pi)) - d2Hdeta2 = -4.0/(3.0*sqrt(pi)) - else - dHdeta_over_eta = (2.0/sqrt(pi))*(exp(-eta^2)/eta^2) - (erf(eta)/(eta^3)) - d2Hdeta2 = 2.0*(erf(eta)/(eta^3)) - (4.0/sqrt(pi))*(1.0 + (1.0/eta^2))*exp(-eta^2) - end - d2Hdvpa2 = ((vperp.grid[ivperp]^2)/(eta^2))*dHdeta_over_eta + ((vpa.grid[ivpa]^2)/(eta^2))*d2Hdeta2 - return d2Hdvpa2 + + #multiply by scale factor for element length + D .= (2.0*float(nelement)/L).*D +end + +""" +derivative matrix for radau grid +""" +function calculate_chebyshev_radau_D_matrix_via_FFT!(D::Array{Float64,2}, coord, spectral) + ff_buffer = Array{Float64,1}(undef,coord.ngrid) + df_buffer = Array{Float64,1}(undef,coord.ngrid) + # use response matrix approach to calculate derivative matrix D + for j in 1:coord.ngrid + ff_buffer .= 0.0 + ff_buffer[j] = 1.0 + @views chebyshev_radau_derivative_single_element!(df_buffer[:], ff_buffer[:], + spectral.radau.f[:,1], spectral.radau.df, spectral.radau.fext, spectral.radau.forward, coord) + @. D[:,j] = df_buffer[:] # assign appropriate column of derivative matrix end - function d2G_Maxwellian_dvpa2(vpa,vperp,ivpa,ivperp) - # speed variable - eta = sqrt(vpa.grid[ivpa]^2 + vperp.grid[ivperp]^2) - zero = 1.0e-10 - if eta < zero - dGdeta_over_eta = 4.0/(3.0*sqrt(pi)) - d2Gdeta2 = 4.0/(3.0*sqrt(pi)) - else - dGdeta_over_eta = (1.0/sqrt(pi))*(exp(-eta^2)/(eta^2)) + (1.0 - (0.5/eta^2))*erf(eta)/eta - d2Gdeta2 = (erf(eta)/(eta^3)) - (2.0/sqrt(pi))*exp(-eta^2)/eta^2 - end - d2Gdvpa2 = ((vperp.grid[ivperp]^2)/(eta^2))*dGdeta_over_eta + ((vpa.grid[ivpa]^2)/(eta^2))*d2Gdeta2 - return d2Gdvpa2 + # correct diagonal elements to gurantee numerical stability + # gives D*[1.0, 1.0, ... 1.0] = [0.0, 0.0, ... 0.0] + for j in 1:coord.ngrid + D[j,j] = 0.0 + D[j,j] = -sum(D[j,:]) end - function dHdvpa_inf(vpa,vperp,ivpa,ivperp) - eta = sqrt(vpa.grid[ivpa]^2 + vperp.grid[ivperp]^2) - dHdvpa_inf = -vpa.grid[ivpa]/eta^3 - return dHdvpa_inf - end - function d2Gdvpa2_inf(vpa,vperp,ivpa,ivperp) - eta = sqrt(vpa.grid[ivpa]^2 + vperp.grid[ivperp]^2) - d2Gdvpa2_inf = ((vpa.grid[ivpa]^2)/eta^5) + ((vperp.grid[ivperp]^2)/eta^3)*( 1.0 - (0.5/eta^2)) - return d2Gdvpa2_inf + #multiply by scale factor for element length + D .= (2.0*float(coord.nelement_global)/coord.L).*D +end + +function cheb_radau_derivative_matrix_reversed!(D::Array{Float64,2},x,x_spectral) + D_lobotto_elementwise = Array{Float64,2}(undef,x.ngrid,x.ngrid) + cheb_derivative_matrix_elementwise_reversed!(D_lobotto_elementwise,x.ngrid,x.L,x.nelement_global) + + D_radau_elementwise = Array{Float64,2}(undef,x.ngrid,x.ngrid) + calculate_chebyshev_radau_D_matrix_via_FFT!(D_radau_elementwise,x,x_spectral) + if x.ngrid < 8 + print_matrix(D_lobotto_elementwise,"D_lobotto_elementwise",x.ngrid,x.ngrid) + print_matrix(D_radau_elementwise,"D_radau_elementwise",x.ngrid,x.ngrid) + end + assign_cheb_derivative_matrix!(D,D_lobotto_elementwise,D_radau_elementwise,x) +end + +function cheb_radau_second_derivative_matrix_reversed!(D::Array{Float64,2},x,x_spectral) + D_lobotto_elementwise = Array{Float64,2}(undef,x.ngrid,x.ngrid) + cheb_derivative_matrix_elementwise_reversed!(D_lobotto_elementwise,x.ngrid,x.L,x.nelement_global) + D2_lobotto_elementwise = Array{Float64,2}(undef,x.ngrid,x.ngrid) + mul!(D2_lobotto_elementwise,D_lobotto_elementwise,D_lobotto_elementwise) + + D_radau_elementwise = Array{Float64,2}(undef,x.ngrid,x.ngrid) + calculate_chebyshev_radau_D_matrix_via_FFT!(D_radau_elementwise,x,x_spectral) + D2_radau_elementwise = Array{Float64,2}(undef,x.ngrid,x.ngrid) + mul!(D2_radau_elementwise,D_radau_elementwise,D_radau_elementwise) + + if x.ngrid < 8 + #print_matrix(D_lobotto_elementwise,"D_lobotto_elementwise",x.ngrid,x.ngrid) + print_matrix(D2_lobotto_elementwise,"D2_lobotto_elementwise",x.ngrid,x.ngrid) + #print_matrix(D_radau_elementwise,"D_radau_elementwise",x.ngrid,x.ngrid) + print_matrix(D2_radau_elementwise,"D2_radau_elementwise",x.ngrid,x.ngrid) end + assign_cheb_derivative_matrix!(D,D2_lobotto_elementwise,D2_radau_elementwise,x) +end + + +function assign_cheb_derivative_matrix!(D::Array{Float64,2},D_lobotto_elementwise::Array{Float64,2},D_radau_elementwise::Array{Float64,2},x) + # zero output matrix before assignment + D[:,:] .= 0.0 + imin = x.imin + imax = x.imax - #using LinearAlgebra.mul - discretization = "chebyshev_pseudospectral" - #discretization = "finite_difference" - etol = 1.0e-15 - outprefix = "derivative_test" - ################### - ## df/dx Nonperiodic (No) BC test - ################### - - # define inputs needed for the test - ngrid = 17 #number of points per element - nelement_local = 20 # number of elements per rank - nelement_global = nelement_local # total number of elements - L = 1.0 #physical box size in reference units - bc = "" #not required to take a particular value, not used - # fd_option and adv_input not actually used so given values unimportant - fd_option = "fourth_order_centered" - adv_input = advection_input("default", 1.0, 0.0, 0.0) - nrank = 1 - irank = 0 - comm = MPI.COMM_NULL - # create the 'input' struct containing input info needed to create a - # coordinate - input = grid_input("coord", ngrid, nelement_global, nelement_local, - nrank, irank, L, discretization, fd_option, bc, adv_input,comm) - # create the coordinate struct 'x' - println("made inputs") - x = define_coordinate(input) - println("made x") - Dx = Array{Float64,2}(undef, x.n, x.n) - xchebgrid = Array{Float64,1}(undef, x.n) - for i in 1:x.n - xchebgrid[i] = cos(pi*(i - 1)/(x.n - 1)) + zero_bc_upper_boundary = x.bc == "zero" || x.bc == "zero_upper" + zero_bc_lower_boundary = x.bc == "zero" || x.bc == "zero_lower" + + # fill in first element + j = 1 + if zero_bc_lower_boundary #x.bc == "zero" + D[imin[j],imin[j]:imax[j]] .+= D_radau_elementwise[1,:]./2.0 #contributions from this element/2 + D[imin[j],imin[j]] += D_radau_elementwise[x.ngrid,x.ngrid]/2.0 #contribution from missing `zero' element/2 + else + D[imin[j],imin[j]:imax[j]] .+= D_radau_elementwise[1,:] + end + for k in 2:imax[j]-imin[j] + D[k,imin[j]:imax[j]] .+= D_radau_elementwise[k,:] + end + if zero_bc_upper_boundary && x.nelement_local == 1 + D[imax[j],imin[j]-1:imax[j]] .+= D_radau_elementwise[x.ngrid,:]./2.0 #contributions from this element/2 + D[imax[j],imax[j]] += D_lobotto_elementwise[1,1]/2.0 #contribution from missing `zero' element/2 + elseif x.nelement_local > 1 #x.bc == "zero" + D[imax[j],imin[j]:imax[j]] .+= D_radau_elementwise[x.ngrid,:]./2.0 + else + D[imax[j],imin[j]:imax[j]] .+= D_radau_elementwise[x.ngrid,:] + end + # remaining elements recalling definitions of imax and imin + for j in 2:x.nelement_local + #lower boundary condition on element + D[imin[j]-1,imin[j]-1:imax[j]] .+= D_lobotto_elementwise[1,:]./2.0 + for k in 2:imax[j]-imin[j]+1 + D[k+imin[j]-2,imin[j]-1:imax[j]] .+= D_lobotto_elementwise[k,:] + end + # upper boundary condition on element + if j == x.nelement_local && !(zero_bc_upper_boundary) + D[imax[j],imin[j]-1:imax[j]] .+= D_lobotto_elementwise[x.ngrid,:] + elseif j == x.nelement_local && zero_bc_upper_boundary + D[imax[j],imin[j]-1:imax[j]] .+= D_lobotto_elementwise[x.ngrid,:]./2.0 #contributions from this element/2 + D[imax[j],imax[j]] += D_lobotto_elementwise[1,1]/2.0 #contribution from missing `zero' element/2 + else + D[imax[j],imin[j]-1:imax[j]] .+= D_lobotto_elementwise[x.ngrid,:]./2.0 + end end - #println("x",xchebgrid[:]) - cheb_derivative_matrix!(Dx,xchebgrid,x.n) - #println("") - #println("Dx \n") - #for i in 1:x.n - # println(Dx[i,:]) - #end - # create array for the function f(x) to be differentiated/integrated - f = Array{Float64,1}(undef, x.n) - # create array for the derivative df/dx - df = Array{Float64,1}(undef, x.n) - df2 = Array{Float64,1}(undef, x.n) - df2cheb = Array{Float64,1}(undef, x.n) - df_exact = Array{Float64,1}(undef, x.n) - df2_exact = Array{Float64,1}(undef, x.n) - df_err = Array{Float64,1}(undef, x.n) - df2_err = Array{Float64,1}(undef, x.n) - df2cheb_err = Array{Float64,1}(undef, x.n) +end - for ix in 1:x.n - f[ix] = sin(pi*xchebgrid[ix]) - df_exact[ix] = (pi)*cos(pi*xchebgrid[ix]) +""" +function integrating d y / d t = f(t) +""" +function forward_euler_step!(ynew,yold,f,dt,n) + for i in 1:n + ynew[i] = yold[i] + dt*f[i] end - mul!(df,Dx,f) - for ix in 1:x.n - df_err[ix] = df[ix]-df_exact[ix] +end +""" +function creating lu object for A = I - dt*nu*D2 +""" +function diffusion_matrix(D2,n,dt,nu;return_A=false) + A = Array{Float64,2}(undef,n,n) + for i in 1:n + for j in 1:n + A[i,j] = - dt*nu*D2[i,j] + end + A[i,i] += 1.0 end - # test standard cheb D f = df - #println("df \n",df) - #println("df_exact \n",df_exact) - #println("df_err \n",df_err) - input = grid_input("coord", ngrid, nelement_global, nelement_local, - nrank, irank, L, discretization, fd_option, "zero", adv_input,comm) - # create the coordinate struct 'x' - x = define_coordinate(input) - - Dxreverse = Array{Float64,2}(undef, x.n, x.n) - cheb_derivative_matrix_reversed!(Dxreverse,x) - Dxreverse2 = Array{Float64,2}(undef, x.n, x.n) - mul!(Dxreverse2,Dxreverse,Dxreverse) - D2xreverse = Array{Float64,2}(undef, x.n, x.n) - cheb_second_derivative_matrix_reversed!(D2xreverse,x) - - Dxreverse2[1,1] = 2.0*Dxreverse2[1,1] - Dxreverse2[end,end] = 2.0*Dxreverse2[end,end] - #println("x.grid \n",x.grid) - if x.n < 20 - print_matrix(Dxreverse,"\n Dxreverse \n",x.n,x.n) - print_matrix(Dxreverse2,"\n Dxreverse*Dxreverse \n",x.n,x.n) - print_matrix(D2xreverse,"\n D2xreverse \n",x.n,x.n) - println("\n") + lu_obj = lu(A) + if return_A + return lu_obj, A + else + return lu_obj end +end - alpha = 512.0 - for ix in 1:x.n -# f[ix] = sin(2.0*pi*x.grid[ix]/x.L) -# df_exact[ix] = (2.0*pi/x.L)*cos(2.0*pi*x.grid[ix]/x.L) -# df2_exact[ix] = -(2.0*pi/x.L)*(2.0*pi/x.L)*sin(2.0*pi*x.grid[ix]/x.L) - - f[ix] = exp(-alpha*(x.grid[ix])^2) - df_exact[ix] = -2.0*alpha*x.grid[ix]*exp(-alpha*(x.grid[ix])^2) - df2_exact[ix] = ((2.0*alpha*x.grid[ix])^2 - 2.0*alpha)*exp(-alpha*(x.grid[ix])^2) - end - #println("test f: \n",f) - # calculate d f / d x from matrix - mul!(df,Dxreverse,f) - # calculate d^2 f / d x from second application of Dx matrix - mul!(df2,Dxreverse2,f) - # calculate d^2 f / d x from applition of D2x matrix - mul!(df2cheb,D2xreverse,f) - for ix in 1:x.n - df_err[ix] = df[ix]-df_exact[ix] - df2_err[ix] = df2[ix]-df2_exact[ix] - df2cheb_err[ix] = df2cheb[ix]-df2_exact[ix] +""" +functions for Rosenbluth potential tests +""" +function dH_Maxwellian_dvpa(vpa,vperp,ivpa,ivperp) + # speed variable + eta = sqrt(vpa.grid[ivpa]^2 + vperp.grid[ivperp]^2) + zero = 1.0e-10 + if eta < zero + dHdvpa = -(4.0*vpa.grid[ivpa])/(3.0*sqrt(pi)) + else + dHdvpa = (vpa.grid[ivpa]/eta)*((2.0/sqrt(pi))*(exp(-eta^2)/eta) - (erf(eta)/(eta^2))) end - println("Reversed - multiple elements") - #println("df \n",df) - #println("df_exact \n",df_exact) - #println("df_err \n",df_err) - #println("df2 \n",df2) - #println("df2_exact \n",df2_exact) - #println("df2_err \n",df2_err) - #println("df2cheb_err \n",df2cheb_err) - - println("max(df_err) \n",maximum(abs.(df_err))) - println("max(df2_err) \n",maximum(abs.(df2_err))) - println("max(df2cheb_err) \n",maximum(abs.(df2cheb_err))) - - ### attempt at matrix inversion via LU decomposition - Dt = 0.1 - Nu = 1.0 - lu_obj, AA = diffusion_matrix(Dxreverse2,x.n,Dt,Nu,return_A=true) - #AA = Array{Float64,2}(undef,x.n,x.n) - #for i in 1:x.n - # for j in 1:x.n - # AA[i,j] = - Dt*Nu*Dxreverse2[i,j] - # end - # AA[i,i] += 1.0 - #end - #lu_obj = lu(AA) - if x.n < 20 - println("L : \n",lu_obj.L) - println("U : \n",lu_obj.U) - println("p vector : \n",lu_obj.p) + return dHdvpa +end +function d2H_Maxwellian_dvpa2(vpa,vperp,ivpa,ivperp) + # speed variable + eta = sqrt(vpa.grid[ivpa]^2 + vperp.grid[ivperp]^2) + zero = 1.0e-10 + if eta < zero + dHdeta_over_eta = -4.0/(3.0*sqrt(pi)) + d2Hdeta2 = -4.0/(3.0*sqrt(pi)) + else + dHdeta_over_eta = (2.0/sqrt(pi))*(exp(-eta^2)/eta^2) - (erf(eta)/(eta^3)) + d2Hdeta2 = 2.0*(erf(eta)/(eta^3)) - (4.0/sqrt(pi))*(1.0 + (1.0/eta^2))*exp(-eta^2) end - LUtest = true - AA_test_lhs = lu_obj.L*lu_obj.U - AA_test_rhs = AA[lu_obj.p,:] - for i in 1:x.n - for j in 1:x.n - if abs.(AA_test_lhs[i,j]-AA_test_rhs[i,j]) > zero - global LUtest = false - end - end + d2Hdvpa2 = ((vperp.grid[ivperp]^2)/(eta^2))*dHdeta_over_eta + ((vpa.grid[ivpa]^2)/(eta^2))*d2Hdeta2 + return d2Hdvpa2 +end +function d2G_Maxwellian_dvpa2(vpa,vperp,ivpa,ivperp) + # speed variable + eta = sqrt(vpa.grid[ivpa]^2 + vperp.grid[ivperp]^2) + zero = 1.0e-10 + if eta < zero + dGdeta_over_eta = 4.0/(3.0*sqrt(pi)) + d2Gdeta2 = 4.0/(3.0*sqrt(pi)) + else + dGdeta_over_eta = (1.0/sqrt(pi))*(exp(-eta^2)/(eta^2)) + (1.0 - (0.5/eta^2))*erf(eta)/eta + d2Gdeta2 = (erf(eta)/(eta^3)) - (2.0/sqrt(pi))*exp(-eta^2)/eta^2 end - println("LU == AA : \n",LUtest) + d2Gdvpa2 = ((vperp.grid[ivperp]^2)/(eta^2))*dGdeta_over_eta + ((vpa.grid[ivpa]^2)/(eta^2))*d2Gdeta2 + return d2Gdvpa2 +end + +function dHdvpa_inf(vpa,vperp,ivpa,ivperp) + eta = sqrt(vpa.grid[ivpa]^2 + vperp.grid[ivperp]^2) + dHdvpa_inf = -vpa.grid[ivpa]/eta^3 + return dHdvpa_inf +end +function d2Gdvpa2_inf(vpa,vperp,ivpa,ivperp) + eta = sqrt(vpa.grid[ivpa]^2 + vperp.grid[ivperp]^2) + d2Gdvpa2_inf = ((vpa.grid[ivpa]^2)/eta^5) + ((vperp.grid[ivperp]^2)/eta^3)*( 1.0 - (0.5/eta^2)) + return d2Gdvpa2_inf +end + + +#using LinearAlgebra.mul +discretization = "chebyshev_pseudospectral" +#discretization = "finite_difference" + etol = 1.0e-15 +outprefix = "derivative_test" + ################### + ## df/dx Nonperiodic (No) BC test + ################### - #bb = ones(x.n) try this for bc = "" rather than bc = "zero" - bb = Array{Float64,1}(undef,x.n) - yy = Array{Float64,1}(undef,x.n) - #for i in 1:x.n - # bb[i] = f[i]#exp(-(4.0*x.grid[i]/x.L)^2) - #end - #yy = lu_obj \ bb # solution to AA yy = bb - #println("result", yy) - #println("check result", AA*yy, bb) - MMS_test = false - evolution_test = false#true - elliptic_solve_test = false#true - elliptic_solve_1D_infinite_domain_test = false#true - elliptic_2Dsolve_test = true - if MMS_test - ntest = 5 - MMS_errors = Array{Float64,1}(undef,ntest) - Dt_list = Array{Float64,1}(undef,ntest) - fac_list = Array{Int64,1}(undef,ntest) - fac_list .= [1, 10, 100, 1000, 10000] - #for itest in [1, 10, 100, 1000, 10000] - for itest in 1:ntest - fac = fac_list[itest] - #println(fac) - ntime = 1000*fac - nwrite = 100*fac - dt = 0.001/fac - #println(ntime," ",dt) - nu = 1.0 - LU_obj = diffusion_matrix(Dxreverse2,x.n,dt,nu) - - time = Array{Float64,1}(undef,ntime) - ff = Array{Float64,2}(undef,x.n,ntime) - ss = Array{Float64,1}(undef,x.n) #source + # define inputs needed for the test + ngrid = 17 #number of points per element + nelement_local = 20 # number of elements per rank + nelement_global = nelement_local # total number of elements + L = 1.0 #physical box size in reference units + bc = "" #not required to take a particular value, not used + # fd_option and adv_input not actually used so given values unimportant + fd_option = "fourth_order_centered" + nrank = 1 +irank = 0 +comm = MPI.COMM_NULL +# create the 'input' struct containing input info needed to create a +# coordinate +input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, + "nelement"=>nelement_global, + "nelement_local"=>nelement_local, "L"=>L, + "discretization"=>discretization, + "finite_difference_option"=>fd_option, + "bc"=>bc)) +# create the coordinate struct 'x' +# This test runs effectively in serial, so use `ignore_MPI=true` to avoid +# errors due to communicators not being fully set up. +x, spectral = define_coordinate(input, "coord"; ignore_MPI=true) + println("made x") +Dx = Array{Float64,2}(undef, x.n, x.n) +xchebgrid = Array{Float64,1}(undef, x.n) +for i in 1:x.n + xchebgrid[i] = cos(pi*(i - 1)/(x.n - 1)) +end +#println("x",xchebgrid[:]) +cheb_derivative_matrix!(Dx,xchebgrid,x.n) +#println("") +#println("Dx \n") +#for i in 1:x.n +# println(Dx[i,:]) +#end - time[1] = 0.0 - ff[:,1] .= f[:] #initial condition - for i in 1:ntime-1 - time[i+1] = (i+1)*dt - bb .= ff[:,i] - yy .= LU_obj\bb # implicit backward euler diffusion step - @. ss = -nu*df2_exact # source term - # explicit forward_euler_step with source - @views forward_euler_step!(ff[:,i+1],yy,ss,dt,x.n) - end + # create array for the function f(x) to be differentiated/integrated + f = Array{Float64,1}(undef, x.n) + # create array for the derivative df/dx + df = Array{Float64,1}(undef, x.n) + df2 = Array{Float64,1}(undef, x.n) + df2cheb = Array{Float64,1}(undef, x.n) +df_exact = Array{Float64,1}(undef, x.n) +df2_exact = Array{Float64,1}(undef, x.n) +df_err = Array{Float64,1}(undef, x.n) +df2_err = Array{Float64,1}(undef, x.n) +df2cheb_err = Array{Float64,1}(undef, x.n) + +for ix in 1:x.n + f[ix] = sin(pi*xchebgrid[ix]) + df_exact[ix] = (pi)*cos(pi*xchebgrid[ix]) +end +mul!(df,Dx,f) +for ix in 1:x.n + df_err[ix] = df[ix]-df_exact[ix] +end +# test standard cheb D f = df +#println("df \n",df) +#println("df_exact \n",df_exact) +#println("df_err \n",df_err) +input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, + "nelement"=>nelement_global, + "nelement_local"=>nelement_local, "L"=>L, + "discretization"=>discretization, + "finite_difference_option"=>fd_option, + "bc"=>"zero")) +# create the coordinate struct 'x' +# This test runs effectively in serial, so use `ignore_MPI=true` to avoid +# errors due to communicators not being fully set up. +x, spectral = define_coordinate(input, "coord"; ignore_MPI=true) + +Dxreverse = Array{Float64,2}(undef, x.n, x.n) +cheb_derivative_matrix_reversed!(Dxreverse,x) +Dxreverse2 = Array{Float64,2}(undef, x.n, x.n) +mul!(Dxreverse2,Dxreverse,Dxreverse) +D2xreverse = Array{Float64,2}(undef, x.n, x.n) +cheb_second_derivative_matrix_reversed!(D2xreverse,x) + +Dxreverse2[1,1] = 2.0*Dxreverse2[1,1] +Dxreverse2[end,end] = 2.0*Dxreverse2[end,end] +#println("x.grid \n",x.grid) +if x.n < 20 + print_matrix(Dxreverse,"\n Dxreverse \n",x.n,x.n) + print_matrix(Dxreverse2,"\n Dxreverse*Dxreverse \n",x.n,x.n) + print_matrix(D2xreverse,"\n D2xreverse \n",x.n,x.n) + println("\n") +end + +alpha = 512.0 +for ix in 1:x.n +# f[ix] = sin(2.0*pi*x.grid[ix]/x.L) +# df_exact[ix] = (2.0*pi/x.L)*cos(2.0*pi*x.grid[ix]/x.L) +# df2_exact[ix] = -(2.0*pi/x.L)*(2.0*pi/x.L)*sin(2.0*pi*x.grid[ix]/x.L) + + f[ix] = exp(-alpha*(x.grid[ix])^2) + df_exact[ix] = -2.0*alpha*x.grid[ix]*exp(-alpha*(x.grid[ix])^2) + df2_exact[ix] = ((2.0*alpha*x.grid[ix])^2 - 2.0*alpha)*exp(-alpha*(x.grid[ix])^2) +end +#println("test f: \n",f) +# calculate d f / d x from matrix +mul!(df,Dxreverse,f) +# calculate d^2 f / d x from second application of Dx matrix +mul!(df2,Dxreverse2,f) +# calculate d^2 f / d x from applition of D2x matrix +mul!(df2cheb,D2xreverse,f) +for ix in 1:x.n + df_err[ix] = df[ix]-df_exact[ix] + df2_err[ix] = df2[ix]-df2_exact[ix] + df2cheb_err[ix] = df2cheb[ix]-df2_exact[ix] +end +println("Reversed - multiple elements") +#println("df \n",df) +#println("df_exact \n",df_exact) +#println("df_err \n",df_err) +#println("df2 \n",df2) +#println("df2_exact \n",df2_exact) +#println("df2_err \n",df2_err) +#println("df2cheb_err \n",df2cheb_err) + +println("max(df_err) \n",maximum(abs.(df_err))) +println("max(df2_err) \n",maximum(abs.(df2_err))) +println("max(df2cheb_err) \n",maximum(abs.(df2cheb_err))) - ff_error = Array{Float64,1}(undef,x.n) - ff_error[:] .= abs.(ff[:,end] - ff[:,1]) - maxfferr = maximum(ff_error) - #println("ff_error \n",ff_error) - println("max(ff_error) \n",maxfferr) - #println("t[end]: ",time[end]) - MMS_errors[itest] = maxfferr - Dt_list[itest] = dt - end - @views plot(Dt_list, [MMS_errors, 100.0*Dt_list], label=[L"max(\epsilon(f))" L"100\Delta t"], - xlabel=L"\Delta t", ylabel="", xscale=:log10, yscale=:log10, shape =:circle) - outfile = string("ff_err_vs_dt.pdf") - savefig(outfile) +### attempt at matrix inversion via LU decomposition +Dt = 0.1 +Nu = 1.0 +lu_obj, AA = diffusion_matrix(Dxreverse2,x.n,Dt,Nu,return_A=true) +#AA = Array{Float64,2}(undef,x.n,x.n) +#for i in 1:x.n +# for j in 1:x.n +# AA[i,j] = - Dt*Nu*Dxreverse2[i,j] +# end +# AA[i,i] += 1.0 +#end +#lu_obj = lu(AA) +if x.n < 20 + println("L : \n",lu_obj.L) + println("U : \n",lu_obj.U) + println("p vector : \n",lu_obj.p) +end +LUtest = true +AA_test_lhs = lu_obj.L*lu_obj.U +AA_test_rhs = AA[lu_obj.p,:] +for i in 1:x.n + for j in 1:x.n + if abs.(AA_test_lhs[i,j]-AA_test_rhs[i,j]) > zero + global LUtest = false + end end - - if evolution_test - ntime = 100 - nwrite = 1 - dt = 0.001 +end +println("LU == AA : \n",LUtest) + +#bb = ones(x.n) try this for bc = "" rather than bc = "zero" +bb = Array{Float64,1}(undef,x.n) +yy = Array{Float64,1}(undef,x.n) +#for i in 1:x.n +# bb[i] = f[i]#exp(-(4.0*x.grid[i]/x.L)^2) +#end +#yy = lu_obj \ bb # solution to AA yy = bb +#println("result", yy) +#println("check result", AA*yy, bb) +MMS_test = false +evolution_test = false#true +elliptic_solve_test = false#true +elliptic_solve_1D_infinite_domain_test = false#true +elliptic_2Dsolve_test = true +if MMS_test + ntest = 5 + MMS_errors = Array{Float64,1}(undef,ntest) + Dt_list = Array{Float64,1}(undef,ntest) + fac_list = Array{Int64,1}(undef,ntest) + fac_list .= [1, 10, 100, 1000, 10000] + #for itest in [1, 10, 100, 1000, 10000] + for itest in 1:ntest + fac = fac_list[itest] + #println(fac) + ntime = 1000*fac + nwrite = 100*fac + dt = 0.001/fac + #println(ntime," ",dt) nu = 1.0 LU_obj = diffusion_matrix(Dxreverse2,x.n,dt,nu) @@ -687,566 +659,638 @@ if abspath(PROGRAM_FILE) == @__FILE__ time[i+1] = (i+1)*dt bb .= ff[:,i] yy .= LU_obj\bb # implicit backward euler diffusion step - @. ss = 0.0 # source term + @. ss = -nu*df2_exact # source term # explicit forward_euler_step with source @views forward_euler_step!(ff[:,i+1],yy,ss,dt,x.n) end - ffmin = minimum(ff) - ffmax = maximum(ff) - anim = @animate for i in 1:nwrite:ntime - @views plot(x.grid, ff[:,i], xlabel="x", ylabel="f", ylims = (ffmin,ffmax)) - end - outfile = string("ff_vs_x.gif") - gif(anim, outfile, fps=5) + ff_error = Array{Float64,1}(undef,x.n) + ff_error[:] .= abs.(ff[:,end] - ff[:,1]) + maxfferr = maximum(ff_error) + #println("ff_error \n",ff_error) + println("max(ff_error) \n",maxfferr) + #println("t[end]: ",time[end]) + MMS_errors[itest] = maxfferr + Dt_list[itest] = dt + end + @views plot(Dt_list, [MMS_errors, 100.0*Dt_list], label=[L"max(\epsilon(f))" L"100\Delta t"], + xlabel=L"\Delta t", ylabel="", xscale=:log10, yscale=:log10, shape =:circle) + outfile = string("ff_err_vs_dt.pdf") + savefig(outfile) +end + +if evolution_test + ntime = 100 + nwrite = 1 + dt = 0.001 + nu = 1.0 + LU_obj = diffusion_matrix(Dxreverse2,x.n,dt,nu) + + time = Array{Float64,1}(undef,ntime) + ff = Array{Float64,2}(undef,x.n,ntime) + ss = Array{Float64,1}(undef,x.n) #source + + time[1] = 0.0 + ff[:,1] .= f[:] #initial condition + for i in 1:ntime-1 + time[i+1] = (i+1)*dt + bb .= ff[:,i] + yy .= LU_obj\bb # implicit backward euler diffusion step + @. ss = 0.0 # source term + # explicit forward_euler_step with source + @views forward_euler_step!(ff[:,i+1],yy,ss,dt,x.n) end + + ffmin = minimum(ff) + ffmax = maximum(ff) + anim = @animate for i in 1:nwrite:ntime + @views plot(x.grid, ff[:,i], xlabel="x", ylabel="f", ylims = (ffmin,ffmax)) + end + outfile = string("ff_vs_x.gif") + gif(anim, outfile, fps=5) +end + +if elliptic_solve_test + println("elliptic solve test") + ngrid = 25 + nelement_local = 50 + L = 8 + nelement_global = nelement_local + radau = true #false + if radau + input = OptionsDict("vperp" => OptionsDict("ngrid"=>ngrid, + "nelement"=>nelement_global, + "nelement_local"=>nelement_local, "L"=>L, + "discretization"=>discretization, + "finite_difference_option"=>fd_option, + "bc"=>"zero_upper")) + # create the coordinate struct 'x' + # This test runs effectively in serial, so use `ignore_MPI=true` to avoid + # errors due to communicators not being fully set up. + y, y_spectral = define_coordinate(input, "vperp"; ignore_MPI=true) + Dy = Array{Float64,2}(undef, y.n, y.n) + cheb_radau_derivative_matrix_reversed!(Dy,y,y_spectral) + else #lobotto + input = OptionsDict("vpa" => OptionsDict("ngrid"=>ngrid, + "nelement"=>nelement_global, + "nelement_local"=>nelement_local, + "L"=>L, + "discretization"=>discretization, + "finite_difference_option"=>fd_option, + "bc"=>"zero_upper")) + # create the coordinate struct 'x' + # This test runs effectively in serial, so use `ignore_MPI=true` to avoid + # errors due to communicators not being fully set up. + y, y_spectral = define_coordinate(input, "vpa"; ignore_MPI=true) + @. y.grid += y.L/2 + Dy = Array{Float64,2}(undef, y.n, y.n) + cheb_derivative_matrix_reversed!(Dy,y) + end - if elliptic_solve_test - println("elliptic solve test") - ngrid = 25 - nelement_local = 50 - L = 8 - nelement_global = nelement_local - radau = true #false - if radau - input = grid_input("vperp", ngrid, nelement_global, nelement_local, - nrank, irank, L, discretization, fd_option, "zero_upper", adv_input,comm) - y = define_coordinate(input) - y_spectral = setup_chebyshev_pseudospectral(y) - Dy = Array{Float64,2}(undef, y.n, y.n) - cheb_radau_derivative_matrix_reversed!(Dy,y,y_spectral) - else #lobotto - input = grid_input("vpa", ngrid, nelement_global, nelement_local, - nrank, irank, L, discretization, fd_option, "zero_upper", adv_input,comm) - y = define_coordinate(input) - @. y.grid += y.L/2 - Dy = Array{Float64,2}(undef, y.n, y.n) - cheb_derivative_matrix_reversed!(Dy,y) + yDy = Array{Float64,2}(undef, y.n, y.n) + for iy in 1:y.n + @. yDy[iy,:] = y.grid[iy]*Dy[iy,:] + end + + + Dy_yDy = Array{Float64,2}(undef, y.n, y.n) + mul!(Dy_yDy,Dy,yDy) + #Dy_yDy[1,1] = 2.0*Dy_yDy[1,1] + #Dy_yDy[end,end] = 2.0*Dy_yDy[end,end] + + D2y = Array{Float64,2}(undef, y.n, y.n) + mul!(D2y,Dy,Dy) + #Dy_yDy[1,1] = 2.0*Dy_yDy[1,1] + D2y[end,end] = 2.0*D2y[end,end] + yD2y = Array{Float64,2}(undef, y.n, y.n) + for iy in 1:y.n + @. yD2y[iy,:] = y.grid[iy]*D2y[iy,:] + end + + if y.n < 20 + print_matrix(Dy,"Dy",y.n,y.n) + print_matrix(yDy,"yDy",y.n,y.n) + print_matrix(Dy_yDy,"Dy_yDy",y.n,y.n) + print_matrix(yD2y+Dy,"yD2y+Dy",y.n,y.n) + end + Sy = Array{Float64,1}(undef, y.n) + Fy = Array{Float64,1}(undef, y.n) + Fy_exact = Array{Float64,1}(undef, y.n) + Fy_err = Array{Float64,1}(undef, y.n) + for iy in 1:y.n + #Sy[iy] = (y.grid[iy] - 1.0)*exp(-y.grid[iy]) + #Fy_exact[iy] = exp(-y.grid[iy]) + Sy[iy] = 4.0*y.grid[iy]*(y.grid[iy]^2 - 1.0)*exp(-y.grid[iy]^2) + Fy_exact[iy] = exp(-y.grid[iy]^2) + end + LL = Array{Float64,2}(undef, y.n, y.n) + #@. LL = yD2y + Dy + for iy in 1:y.n + #@. LL[iy,:] = Dy_yDy[iy,:] #*(1.0/y.grid[iy]) + @. LL[iy,:] = yD2y[iy,:] + Dy[iy,:] #*(1.0/y.grid[iy]) + end + Dirichlet = true + if Dirichlet + # fixed value at orgin -- doesn't work well + #@. LL[1,:] = 0.0 + #Sy[1] = Fy_exact[1] + set_flux = false + if set_flux + # set flux at origin + @. LL[1,:] = 0.0 + ilim = y.imax[1] + @. LL[1,:] = yDy[ilim,:] + + print_vector(Sy,"Sy before",y.n) + integrand = Array{Float64,1}(undef,ilim) + @. integrand[1:ilim] = Sy[1:ilim]*y.wgts[1:ilim]/(2.0*y.grid[1:ilim]) + + print_vector(integrand,"integrand",ilim) + print_vector(y.wgts,"wgts",y.n) + #@. integrand[1:ilim] = y.grid[1:ilim]*Sy[1:ilim]*y.wgts[1:ilim] + flux = sum(integrand) + Sy[1] = flux end - - yDy = Array{Float64,2}(undef, y.n, y.n) - for iy in 1:y.n - @. yDy[iy,:] = y.grid[iy]*Dy[iy,:] - end - - - Dy_yDy = Array{Float64,2}(undef, y.n, y.n) - mul!(Dy_yDy,Dy,yDy) - #Dy_yDy[1,1] = 2.0*Dy_yDy[1,1] - #Dy_yDy[end,end] = 2.0*Dy_yDy[end,end] - - D2y = Array{Float64,2}(undef, y.n, y.n) - mul!(D2y,Dy,Dy) - #Dy_yDy[1,1] = 2.0*Dy_yDy[1,1] - D2y[end,end] = 2.0*D2y[end,end] - yD2y = Array{Float64,2}(undef, y.n, y.n) - for iy in 1:y.n - @. yD2y[iy,:] = y.grid[iy]*D2y[iy,:] - end - - if y.n < 20 - print_matrix(Dy,"Dy",y.n,y.n) - print_matrix(yDy,"yDy",y.n,y.n) - print_matrix(Dy_yDy,"Dy_yDy",y.n,y.n) - print_matrix(yD2y+Dy,"yD2y+Dy",y.n,y.n) - end - Sy = Array{Float64,1}(undef, y.n) - Fy = Array{Float64,1}(undef, y.n) - Fy_exact = Array{Float64,1}(undef, y.n) - Fy_err = Array{Float64,1}(undef, y.n) - for iy in 1:y.n - #Sy[iy] = (y.grid[iy] - 1.0)*exp(-y.grid[iy]) - #Fy_exact[iy] = exp(-y.grid[iy]) - Sy[iy] = 4.0*y.grid[iy]*(y.grid[iy]^2 - 1.0)*exp(-y.grid[iy]^2) - Fy_exact[iy] = exp(-y.grid[iy]^2) - end - LL = Array{Float64,2}(undef, y.n, y.n) - #@. LL = yD2y + Dy - for iy in 1:y.n - #@. LL[iy,:] = Dy_yDy[iy,:] #*(1.0/y.grid[iy]) - @. LL[iy,:] = yD2y[iy,:] + Dy[iy,:] #*(1.0/y.grid[iy]) - end - Dirichlet = true - if Dirichlet - # fixed value at orgin -- doesn't work well - #@. LL[1,:] = 0.0 - #Sy[1] = Fy_exact[1] - set_flux = false - if set_flux - # set flux at origin - @. LL[1,:] = 0.0 - ilim = y.imax[1] - @. LL[1,:] = yDy[ilim,:] - - print_vector(Sy,"Sy before",y.n) - integrand = Array{Float64,1}(undef,ilim) - @. integrand[1:ilim] = Sy[1:ilim]*y.wgts[1:ilim]/(2.0*y.grid[1:ilim]) - - print_vector(integrand,"integrand",ilim) - print_vector(y.wgts,"wgts",y.n) - #@. integrand[1:ilim] = y.grid[1:ilim]*Sy[1:ilim]*y.wgts[1:ilim] - flux = sum(integrand) - Sy[1] = flux - end - # zero at infinity - @. LL[end,:] = 0.0 - LL[end,end] = 1.0 - #LL[1,1] = 1.0 + # zero at infinity + @. LL[end,:] = 0.0 + LL[end,end] = 1.0 + #LL[1,1] = 1.0 # @. LL[1,:] = 2.0*D2y[1,:] - Sy[end] = Fy_exact[end] - - #print_matrix(LL,"LL",y.n,y.n) - #print_vector(Sy,"Sy",y.n) - end + Sy[end] = Fy_exact[end] - #lu_solver = false - #gauss_seidel_solver = true - #if lu_solver - println("det: ", det(LL)) - println("condition number: ", cond(LL)) - LL_lu_obj = lu(sparse(LL)) - - # do elliptic solve - Fy = LL_lu_obj\Sy - #elseif gauss_seidel_solver - # niter=100 - # @. Fy[:] = Fy_exact[:] # initial guess - # gauss_seidel!(Fy,sparse(LL),Sy,maxiter=niter) - #else - # println("no solution method prescribed") - #end - @. Fy_err = abs(Fy - Fy_exact) - println("maximum(Fy_err)",maximum(Fy_err)) - #println("Fy_err",Fy_err) - #println("Fy_exact",Fy_exact) - #println("Fy",Fy) - plot([y.grid,y.grid,y.grid], [Fy,Fy_exact,Fy_err], xlabel="y", ylabel="", label=["F" "F_exact" "F_err"], - shape =:circle, markersize = 5, linewidth=2) - outfile = "1D_elliptic_solve_test.pdf" - savefig(outfile) - plot([y.grid], [Fy_err], xlabel="x", ylabel="", label=["F_err"], - shape =:circle, markersize = 5, linewidth=2) - outfile = "1D_elliptic_solve_test_err.pdf" - savefig(outfile) - + #print_matrix(LL,"LL",y.n,y.n) + #print_vector(Sy,"Sy",y.n) end - if elliptic_solve_1D_infinite_domain_test - println("elliptic solve 1D infinite domain test") - ngrid = 17 - nelement_local = 50 - L = 25 - nelement_global = nelement_local - input = grid_input("vpa", ngrid, nelement_global, nelement_local, - nrank, irank, L, discretization, fd_option, "zero", adv_input,comm) - x = define_coordinate(input) - Dx = Array{Float64,2}(undef, x.n, x.n) - cheb_derivative_matrix_reversed!(Dx,x) + #lu_solver = false + #gauss_seidel_solver = true + #if lu_solver + println("det: ", det(LL)) + println("condition number: ", cond(LL)) + LL_lu_obj = lu(sparse(LL)) - D2x = Array{Float64,2}(undef, x.n, x.n) - mul!(D2x,Dx,Dx) - Dirichlet= true - if Dirichlet - # Dirichlet BC? - @. D2x[1,:] = 0.0 - @. D2x[end,:] = 0.0 - D2x[1,1] = 1.0 - D2x[end,end] = 1.0 - else - # FD-like zero - BC - D2x[1,1] = 2.0*D2x[1,1] - D2x[end,end] = 2.0*D2x[end,end] - end - - if x.n < 20 - print_matrix(Dx,"Dx",x.n,x.n) - print_matrix(D2x,"D2x",x.n,x.n) - end - LLx = Array{Float64,2}(undef, x.n, x.n) - @. LLx = D2x - - Sx = Array{Float64,1}(undef, x.n) - Fx = Array{Float64,1}(undef, x.n) - Fx_exact = Array{Float64,1}(undef, x.n) - Fx_err = Array{Float64,1}(undef, x.n) - for ix in 1:x.n - Sx[ix] = (4.0*x.grid[ix]^2 - 2.0)*exp(-x.grid[ix]^2) - Fx_exact[ix] = exp(-x.grid[ix]^2) - end # do elliptic solve - if Dirichlet - Sx[1] = 0.0; Sx[end] = 0.0 #Dirichlet BC values - end - - println("condition number: ", cond(LLx)) - LLx_lu_obj = lu(sparse(LLx)) - lu_solver = true#false - #iterative_solver= false#true - if lu_solver - Fx = LLx_lu_obj\Sx - #elseif iterative_solver - # niter=1000 - # @. Fx[:] = 1.0/(x.grid[:]^8 + 1.0) # initial guess Fx_exact[:] - # Fx[1] =0.0; Fx[end] =0.0 - # #gauss_seidel!(Fx,sparse(LLx),Sx,maxiter=niter) - # #jacobi!(Fx,sparse(LLx),Sx,maxiter=niter) - # #idrs!(Fx,sparse(LLx),Sx;abstol=10^(-10)) - else - println("no solution method prescribed") - end - @. Fx_err = abs(Fx - Fx_exact) - - println("test 1: maximum(Fx_err)",maximum(Fx_err)) - #println("Fx_err",Fx_err) - #println("Fx_exact",Fx_exact) - #println("Fx",Fx) - plot([x.grid,x.grid,x.grid], [Fx,Fx_exact,Fx_err], xlabel="x", ylabel="", label=["F" "F_exact" "F_err"], - shape =:circle, markersize = 5, linewidth=2) - outfile = "1D_infinite_domain_elliptic_solve_test.pdf" - savefig(outfile) - plot([x.grid], [Fx_err], xlabel="x", ylabel="", label=["F_err"], - shape =:circle, markersize = 5, linewidth=2) - outfile = "1D_infinite_domain_elliptic_solve_test_err.pdf" - savefig(outfile) - - for ix in 1:x.n - Sx[ix] = exp(-x.grid[ix]^2) - Fx_exact[ix] = (sqrt(pi)/2.0)*x.grid[ix]*erf(x.grid[ix]) + exp(-x.grid[ix]^2)/2.0 - end - if Dirichlet - Sx[1] = 0.0; Sx[end] = 0.0 #Dirichlet BC values - end - - if lu_solver - Fx = LLx_lu_obj\Sx - elseif iterative_solver - niter=1000 - @. Fx[:] = 1.0/(x.grid[:]^8 + 1.0) # initial guess Fx_exact[:] - Fx[1] =0.0; Fx[end] =0.0 - #gauss_seidel!(Fx,sparse(LLx),Sx,maxiter=niter) - #jacobi!(Fx,sparse(LLx),Sx,maxiter=niter) - idrs!(Fx,sparse(LLx),Sx) - else - println("no solution method prescribed") - end - - @. Fx += (sqrt(pi)/2.0)*x.grid[end] - @. Fx_err = abs(Fx - Fx_exact) - println("test 2: maximum(Fx_err)",maximum(Fx_err)) - plot([x.grid], [Fx], xlabel="x", ylabel="", label=["Fx"], - shape =:circle, markersize = 5, linewidth=2) - outfile = "1D_infinite_domain_elliptic_solve_gaussian_source.pdf" - savefig(outfile) - plot([x.grid], [Fx_err], xlabel="x", ylabel="", label=["F_err"], - shape =:circle, markersize = 5, linewidth=2) - outfile = "1D_infinite_domain_elliptic_solve_gaussian_source_err.pdf" - savefig(outfile) + Fy = LL_lu_obj\Sy + #elseif gauss_seidel_solver + # niter=100 + # @. Fy[:] = Fy_exact[:] # initial guess + # gauss_seidel!(Fy,sparse(LL),Sy,maxiter=niter) + #else + # println("no solution method prescribed") + #end + @. Fy_err = abs(Fy - Fy_exact) + println("maximum(Fy_err)",maximum(Fy_err)) + #println("Fy_err",Fy_err) + #println("Fy_exact",Fy_exact) + #println("Fy",Fy) + plot([y.grid,y.grid,y.grid], [Fy,Fy_exact,Fy_err], xlabel="y", ylabel="", label=["F" "F_exact" "F_err"], + shape =:circle, markersize = 5, linewidth=2) + outfile = "1D_elliptic_solve_test.pdf" + savefig(outfile) + plot([y.grid], [Fy_err], xlabel="x", ylabel="", label=["F_err"], + shape =:circle, markersize = 5, linewidth=2) + outfile = "1D_elliptic_solve_test_err.pdf" + savefig(outfile) + +end + +if elliptic_solve_1D_infinite_domain_test + println("elliptic solve 1D infinite domain test") + ngrid = 17 + nelement_local = 50 + L = 25 + nelement_global = nelement_local + input = OptionsDict("vpa" => OptionsDict("ngrid"=>ngrid, + "nelement"=>nelement_global, + "nelement_local"=>nelement_local, + "L"=>L, + "discretization"=>discretization, + "finite_difference_option"=>fd_option, + "bc"=>"zero")) + # create the coordinate struct 'x' + # This test runs effectively in serial, so use `ignore_MPI=true` to avoid + # errors due to communicators not being fully set up. + x, x_spectral = define_coordinate(input, "vpa"; ignore_MPI=true) + Dx = Array{Float64,2}(undef, x.n, x.n) + cheb_derivative_matrix_reversed!(Dx,x) + + D2x = Array{Float64,2}(undef, x.n, x.n) + mul!(D2x,Dx,Dx) + Dirichlet= true + if Dirichlet + # Dirichlet BC? + @. D2x[1,:] = 0.0 + @. D2x[end,:] = 0.0 + D2x[1,1] = 1.0 + D2x[end,end] = 1.0 + else + # FD-like zero - BC + D2x[1,1] = 2.0*D2x[1,1] + D2x[end,end] = 2.0*D2x[end,end] + end + + if x.n < 20 + print_matrix(Dx,"Dx",x.n,x.n) + print_matrix(D2x,"D2x",x.n,x.n) + end + LLx = Array{Float64,2}(undef, x.n, x.n) + @. LLx = D2x + + Sx = Array{Float64,1}(undef, x.n) + Fx = Array{Float64,1}(undef, x.n) + Fx_exact = Array{Float64,1}(undef, x.n) + Fx_err = Array{Float64,1}(undef, x.n) + for ix in 1:x.n + Sx[ix] = (4.0*x.grid[ix]^2 - 2.0)*exp(-x.grid[ix]^2) + Fx_exact[ix] = exp(-x.grid[ix]^2) + end + # do elliptic solve + if Dirichlet + Sx[1] = 0.0; Sx[end] = 0.0 #Dirichlet BC values + end + + println("condition number: ", cond(LLx)) + LLx_lu_obj = lu(sparse(LLx)) + lu_solver = true#false + #iterative_solver= false#true + if lu_solver + Fx = LLx_lu_obj\Sx + #elseif iterative_solver + # niter=1000 + # @. Fx[:] = 1.0/(x.grid[:]^8 + 1.0) # initial guess Fx_exact[:] + # Fx[1] =0.0; Fx[end] =0.0 + # #gauss_seidel!(Fx,sparse(LLx),Sx,maxiter=niter) + # #jacobi!(Fx,sparse(LLx),Sx,maxiter=niter) + # #idrs!(Fx,sparse(LLx),Sx;abstol=10^(-10)) + else + println("no solution method prescribed") + end + @. Fx_err = abs(Fx - Fx_exact) + + println("test 1: maximum(Fx_err)",maximum(Fx_err)) + #println("Fx_err",Fx_err) + #println("Fx_exact",Fx_exact) + #println("Fx",Fx) + plot([x.grid,x.grid,x.grid], [Fx,Fx_exact,Fx_err], xlabel="x", ylabel="", label=["F" "F_exact" "F_err"], + shape =:circle, markersize = 5, linewidth=2) + outfile = "1D_infinite_domain_elliptic_solve_test.pdf" + savefig(outfile) + plot([x.grid], [Fx_err], xlabel="x", ylabel="", label=["F_err"], + shape =:circle, markersize = 5, linewidth=2) + outfile = "1D_infinite_domain_elliptic_solve_test_err.pdf" + savefig(outfile) + + for ix in 1:x.n + Sx[ix] = exp(-x.grid[ix]^2) + Fx_exact[ix] = (sqrt(pi)/2.0)*x.grid[ix]*erf(x.grid[ix]) + exp(-x.grid[ix]^2)/2.0 + end + if Dirichlet + Sx[1] = 0.0; Sx[end] = 0.0 #Dirichlet BC values + end + + if lu_solver + Fx = LLx_lu_obj\Sx + elseif iterative_solver + niter=1000 + @. Fx[:] = 1.0/(x.grid[:]^8 + 1.0) # initial guess Fx_exact[:] + Fx[1] =0.0; Fx[end] =0.0 + #gauss_seidel!(Fx,sparse(LLx),Sx,maxiter=niter) + #jacobi!(Fx,sparse(LLx),Sx,maxiter=niter) + idrs!(Fx,sparse(LLx),Sx) + else + println("no solution method prescribed") + end + + @. Fx += (sqrt(pi)/2.0)*x.grid[end] + @. Fx_err = abs(Fx - Fx_exact) + println("test 2: maximum(Fx_err)",maximum(Fx_err)) + plot([x.grid], [Fx], xlabel="x", ylabel="", label=["Fx"], + shape =:circle, markersize = 5, linewidth=2) + outfile = "1D_infinite_domain_elliptic_solve_gaussian_source.pdf" + savefig(outfile) + plot([x.grid], [Fx_err], xlabel="x", ylabel="", label=["F_err"], + shape =:circle, markersize = 5, linewidth=2) + outfile = "1D_infinite_domain_elliptic_solve_gaussian_source_err.pdf" + savefig(outfile) + +end +if elliptic_2Dsolve_test + println("elliptic 2D solve test") + x_ngrid = 17 + x_nelement_local = 4 + x_L = 12 + y_L = 6 + y_ngrid = 17 + y_nelement_local = 2 + + x_nelement_global = x_nelement_local + y_nelement_global = y_nelement_local + # bc option + dirichlet_zero = true#false# + dirichlet_fixed_value = false#true# + # test option + secular_decay_test = false#true + exponential_decay_test = true#false + dHdvpa_test = false + d2Gdvpa2_test = false#true + # second derivative option + # default = false -> if true then use D2coord matrices based on D_elementwise^2 + second_derivative_elementwise = false#true + + input = OptionsDict("vpa" => OptionsDict("ngrid"=>x_ngrid, + "nelement"=>x_nelement_global, + "nelement_local"=>x_nelement_local, + "L"=>L, + "discretization"=>discretization, + "finite_difference_option"=>fd_option, + "bc"=>"zero")) + # create the coordinate struct 'x' + # This test runs effectively in serial, so use `ignore_MPI=true` to avoid + # errors due to communicators not being fully set up. + x, x_spectral = define_coordinate(input, "vpa"; ignore_MPI=true) + + Dx = Array{Float64,2}(undef, x.n, x.n) + cheb_derivative_matrix_reversed!(Dx,x) + D2x = Array{Float64,2}(undef, x.n, x.n) + if second_derivative_elementwise + cheb_second_derivative_matrix_reversed!(D2x,x) + else + mul!(D2x,Dx,Dx) end + # set x bc on D2x + if dirichlet_zero + D2x[1,1] = 2.0*D2x[1,1] + D2x[end,end] = 2.0*D2x[end,end] + elseif dirichlet_fixed_value + @. D2x[1,:] = 0.0 + @. D2x[end,:] = 0.0 + D2x[1,1] = 1.0 + D2x[end,end] = 1.0 + end - if elliptic_2Dsolve_test - println("elliptic 2D solve test") - x_ngrid = 17 - x_nelement_local = 4 - x_L = 12 - y_L = 6 - y_ngrid = 17 - y_nelement_local = 2 - - x_nelement_global = x_nelement_local - y_nelement_global = y_nelement_local - # bc option - dirichlet_zero = true#false# - dirichlet_fixed_value = false#true# - # test option - secular_decay_test = false#true - exponential_decay_test = true#false - dHdvpa_test = false - d2Gdvpa2_test = false#true - # second derivative option - # default = false -> if true then use D2coord matrices based on D_elementwise^2 - second_derivative_elementwise = false#true - - input = grid_input("vpa", x_ngrid, x_nelement_global, x_nelement_local, - nrank, irank, x_L, discretization, fd_option, "zero", adv_input, comm) - x = define_coordinate(input) - x_spectral = setup_chebyshev_pseudospectral(x) - - Dx = Array{Float64,2}(undef, x.n, x.n) - cheb_derivative_matrix_reversed!(Dx,x) - D2x = Array{Float64,2}(undef, x.n, x.n) - if second_derivative_elementwise - cheb_second_derivative_matrix_reversed!(D2x,x) - else - mul!(D2x,Dx,Dx) - end - # set x bc on D2x - if dirichlet_zero - D2x[1,1] = 2.0*D2x[1,1] - D2x[end,end] = 2.0*D2x[end,end] - elseif dirichlet_fixed_value - @. D2x[1,:] = 0.0 - @. D2x[end,:] = 0.0 - D2x[1,1] = 1.0 - D2x[end,end] = 1.0 - end - - IIx = Array{Float64,2}(undef,x.n,x.n) - @. IIx = 0.0 - for ix in 1:x.n - IIx[ix,ix] = 1.0 - end - - if x.n < 20 - print_matrix(Dx,"Dx",x.n,x.n) - print_matrix(D2x,"D2x",x.n,x.n) - print_matrix(IIx,"IIx",x.n,x.n) - end - - input = grid_input("vperp", y_ngrid, y_nelement_global, y_nelement_local, - nrank, irank, y_L, discretization, fd_option, "zero_upper", adv_input, comm) - y = define_coordinate(input) - y_spectral = setup_chebyshev_pseudospectral(y) - Dy = Array{Float64,2}(undef, y.n, y.n) - cheb_radau_derivative_matrix_reversed!(Dy,y,y_spectral) - - D2y = Array{Float64,2}(undef, y.n, y.n) - if second_derivative_elementwise - cheb_radau_second_derivative_matrix_reversed!(D2y,y,y_spectral) - else - mul!(D2y,Dy,Dy) - end - if dirichlet_zero - D2y[end,end] = 2.0*D2y[end,end] - end - # y derivative operator - LLy = Array{Float64,2}(undef,y.n,y.n) - for iy in 1:y.n - @. LLy[iy,:] = D2y[iy,:] + (1.0/y.grid[iy])*Dy[iy,:] - end - if dirichlet_fixed_value - @. LLy[end,:] = 0.0 - LLy[end,end] = 1.0 - end - IIy = Array{Float64,2}(undef,y.n,y.n) - @. IIy = 0.0 - for iy in 1:y.n - IIy[iy,iy] = 1.0 - end - if y.n < 20 - print_matrix(Dy,"Dy",y.n,y.n) - print_matrix(D2y,"D2y",y.n,y.n) - print_matrix(LLy,"LLy",y.n,y.n) - print_matrix(IIy,"IIy",y.n,y.n) - end - println("Initialised 1D arrays") - ### now form 2D matrix to invert and corresponding sources - - # Array in 2D form - nx = x.n - ny = y.n - Sxy = Array{Float64,2}(undef, nx, ny) - Sxy_check = Array{Float64,2}(undef, nx, ny) - Sxy_check_err = Array{Float64,2}(undef, nx, ny) - Txy = Array{Float64,2}(undef, nx, ny) - Fxy = Array{Float64,2}(undef, nx, ny) - Fxy_exact = Array{Float64,2}(undef, nx, ny) - Fxy_err = Array{Float64,2}(undef, nx, ny) - #LLxy = Array{Float64,4}(undef, nx, ny, nx, ny) - # Array in compound 1D form - # ic = (ix-1) + nx*(iy-1) + 1 - # iy = mod(ic,nx) + 1 - # ix = rem(ic,nx) - function icfunc(ix,iy,nx) - return ix + nx*(iy-1) + IIx = Array{Float64,2}(undef,x.n,x.n) + @. IIx = 0.0 + for ix in 1:x.n + IIx[ix,ix] = 1.0 + end + + if x.n < 20 + print_matrix(Dx,"Dx",x.n,x.n) + print_matrix(D2x,"D2x",x.n,x.n) + print_matrix(IIx,"IIx",x.n,x.n) + end + + input = OptionsDict("vperp" => OptionsDict("ngrid"=>y_ngrid, + "nelement"=>y_nelement_global, + "nelement_local"=>y_nelement_local, + "L"=>L, + "discretization"=>discretization, + "finite_difference_option"=>fd_option, + "bc"=>"zero_upper")) + # create the coordinate struct 'x' + # This test runs effectively in serial, so use `ignore_MPI=true` to avoid + # errors due to communicators not being fully set up. + y, y_spectral = define_coordinate(input, "vperp"; ignore_MPI=true) + Dy = Array{Float64,2}(undef, y.n, y.n) + cheb_radau_derivative_matrix_reversed!(Dy,y,y_spectral) + + D2y = Array{Float64,2}(undef, y.n, y.n) + if second_derivative_elementwise + cheb_radau_second_derivative_matrix_reversed!(D2y,y,y_spectral) + else + mul!(D2y,Dy,Dy) + end + if dirichlet_zero + D2y[end,end] = 2.0*D2y[end,end] + end + # y derivative operator + LLy = Array{Float64,2}(undef,y.n,y.n) + for iy in 1:y.n + @. LLy[iy,:] = D2y[iy,:] + (1.0/y.grid[iy])*Dy[iy,:] + end + if dirichlet_fixed_value + @. LLy[end,:] = 0.0 + LLy[end,end] = 1.0 + end + IIy = Array{Float64,2}(undef,y.n,y.n) + @. IIy = 0.0 + for iy in 1:y.n + IIy[iy,iy] = 1.0 + end + if y.n < 20 + print_matrix(Dy,"Dy",y.n,y.n) + print_matrix(D2y,"D2y",y.n,y.n) + print_matrix(LLy,"LLy",y.n,y.n) + print_matrix(IIy,"IIy",y.n,y.n) + end + println("Initialised 1D arrays") + ### now form 2D matrix to invert and corresponding sources + + # Array in 2D form + nx = x.n + ny = y.n + Sxy = Array{Float64,2}(undef, nx, ny) + Sxy_check = Array{Float64,2}(undef, nx, ny) + Sxy_check_err = Array{Float64,2}(undef, nx, ny) + Txy = Array{Float64,2}(undef, nx, ny) + Fxy = Array{Float64,2}(undef, nx, ny) + Fxy_exact = Array{Float64,2}(undef, nx, ny) + Fxy_err = Array{Float64,2}(undef, nx, ny) + #LLxy = Array{Float64,4}(undef, nx, ny, nx, ny) + # Array in compound 1D form + # ic = (ix-1) + nx*(iy-1) + 1 + # iy = mod(ic,nx) + 1 + # ix = rem(ic,nx) + function icfunc(ix,iy,nx) + return ix + nx*(iy-1) + end + function iyfunc(ic,nx) + #return mod(ic,nx) + 1 + return floor(Int64,(ic-1)/nx) + 1 + end + function ixfunc(ic,nx) + ix = ic - nx*(iyfunc(ic,nx) - 1) + #return rem(ic,nx) + return ix + end + function kronecker_delta(i,j) + delta = 0.0 + if i == j + delta = 1.0 end - function iyfunc(ic,nx) - #return mod(ic,nx) + 1 - return floor(Int64,(ic-1)/nx) + 1 + return delta + end + nc = nx*ny + Fc = Array{Float64,1}(undef, nc) + Sc = Array{Float64,1}(undef, nc) + LLc = Array{Float64,2}(undef, nc, nc) + + if exponential_decay_test + for iy in 1:ny + for ix in 1:nx + # Exponential test inputs below + Sxy[ix,iy] = ((4.0*x.grid[ix]^2 - 2.0) + (4.0*y.grid[iy]^2 - 4.0))*exp(-y.grid[iy]^2-x.grid[ix]^2) + Fxy_exact[ix,iy] = exp(-x.grid[ix]^2 - y.grid[iy]^2) + end end - function ixfunc(ic,nx) - ix = ic - nx*(iyfunc(ic,nx) - 1) - #return rem(ic,nx) - return ix + elseif secular_decay_test + for iy in 1:ny + for ix in 1:nx + # secular test inputs below + eta2 = x.grid[ix]^2 + y.grid[iy]^2 + zero = 1.0e-10 + if eta2 < zero + Sxy[ix,iy] = 0.0 + Fxy_exact[ix,iy] = 0.5 + else + Sxy[ix,iy] = exp(-1.0/eta2)*(1.0/eta2^2 - 2.0/eta2^3) + Fxy_exact[ix,iy] = 0.5 - 0.5*exp(-1.0/eta2) + end + end end - function kronecker_delta(i,j) - delta = 0.0 - if i == j - delta = 1.0 + elseif dHdvpa_test + for iy in 1:ny + for ix in 1:nx + # Rosenbluth dHdvpa test + Sxy[ix,iy] = -(4.0/sqrt(pi))*(-2.0*x.grid[ix]*exp(-y.grid[iy]^2-x.grid[ix]^2)) + Fxy_exact[ix,iy] = dH_Maxwellian_dvpa(x,y,ix,iy) end - return delta end - nc = nx*ny - Fc = Array{Float64,1}(undef, nc) - Sc = Array{Float64,1}(undef, nc) - LLc = Array{Float64,2}(undef, nc, nc) - - if exponential_decay_test - for iy in 1:ny - for ix in 1:nx - # Exponential test inputs below - Sxy[ix,iy] = ((4.0*x.grid[ix]^2 - 2.0) + (4.0*y.grid[iy]^2 - 4.0))*exp(-y.grid[iy]^2-x.grid[ix]^2) - Fxy_exact[ix,iy] = exp(-x.grid[ix]^2 - y.grid[iy]^2) - end + elseif d2Gdvpa2_test + for iy in 1:ny + for ix in 1:nx + # Rosenbluth d2Gdvpa2 test + Sxy[ix,iy] = 2.0*d2H_Maxwellian_dvpa2(x,y,ix,iy) + Fxy_exact[ix,iy] = d2G_Maxwellian_dvpa2(x,y,ix,iy) + Txy[ix,iy] = 2.0*dH_Maxwellian_dvpa(x,y,ix,iy) end - elseif secular_decay_test - for iy in 1:ny - for ix in 1:nx - # secular test inputs below - eta2 = x.grid[ix]^2 + y.grid[iy]^2 - zero = 1.0e-10 - if eta2 < zero - Sxy[ix,iy] = 0.0 - Fxy_exact[ix,iy] = 0.5 - else - Sxy[ix,iy] = exp(-1.0/eta2)*(1.0/eta2^2 - 2.0/eta2^3) - Fxy_exact[ix,iy] = 0.5 - 0.5*exp(-1.0/eta2) - end - end + @views derivative!(Sxy_check[:,iy],Txy[:,iy],x,x_spectral) + end + @. Sxy_check_err = abs(Sxy - Sxy_check) + println("maximum(Sxy_check_err)",maximum(Sxy_check_err)) + #@views heatmap(y.grid, x.grid, Sxy[:,:], xlabel=L"y", ylabel=L"x", c = :deep, interpolation = :cubic, + # windowsize = (360,240), margin = 15pt) + # outfile = string("Sxy_exact_2D_solve.pdf") + # savefig(outfile) + #@views heatmap(y.grid, x.grid, Sxy_check[:,:], xlabel=L"y", ylabel=L"x", c = :deep, interpolation = :cubic, + # windowsize = (360,240), margin = 15pt) + # outfile = string("Sxy_num_2D_solve.pdf") + # savefig(outfile) + else + println("No Sxy or Fxy_exact specified") + end + + if dirichlet_fixed_value + # set boundary values + if dHdvpa_test + for ix in 1:nx + Sxy[ix,ny] = dHdvpa_inf(x,y,ix,ny) end - elseif dHdvpa_test for iy in 1:ny - for ix in 1:nx - # Rosenbluth dHdvpa test - Sxy[ix,iy] = -(4.0/sqrt(pi))*(-2.0*x.grid[ix]*exp(-y.grid[iy]^2-x.grid[ix]^2)) - Fxy_exact[ix,iy] = dH_Maxwellian_dvpa(x,y,ix,iy) - end + Sxy[1,iy] = dHdvpa_inf(x,y,1,iy) + Sxy[nx,iy] = dHdvpa_inf(x,y,nx,iy) end elseif d2Gdvpa2_test - for iy in 1:ny - for ix in 1:nx - # Rosenbluth d2Gdvpa2 test - Sxy[ix,iy] = 2.0*d2H_Maxwellian_dvpa2(x,y,ix,iy) - Fxy_exact[ix,iy] = d2G_Maxwellian_dvpa2(x,y,ix,iy) - Txy[ix,iy] = 2.0*dH_Maxwellian_dvpa(x,y,ix,iy) - end - @views derivative!(Sxy_check[:,iy],Txy[:,iy],x,x_spectral) + for ix in 1:nx + Sxy[ix,ny] = d2Gdvpa2_inf(x,y,ix,ny) end - @. Sxy_check_err = abs(Sxy - Sxy_check) - println("maximum(Sxy_check_err)",maximum(Sxy_check_err)) - #@views heatmap(y.grid, x.grid, Sxy[:,:], xlabel=L"y", ylabel=L"x", c = :deep, interpolation = :cubic, - # windowsize = (360,240), margin = 15pt) - # outfile = string("Sxy_exact_2D_solve.pdf") - # savefig(outfile) - #@views heatmap(y.grid, x.grid, Sxy_check[:,:], xlabel=L"y", ylabel=L"x", c = :deep, interpolation = :cubic, - # windowsize = (360,240), margin = 15pt) - # outfile = string("Sxy_num_2D_solve.pdf") - # savefig(outfile) - else - println("No Sxy or Fxy_exact specified") + for iy in 1:ny + Sxy[1,iy] = d2Gdvpa2_inf(x,y,1,iy) + Sxy[nx,iy] = d2Gdvpa2_inf(x,y,nx,iy) + end end - - if dirichlet_fixed_value - # set boundary values - if dHdvpa_test - for ix in 1:nx - Sxy[ix,ny] = dHdvpa_inf(x,y,ix,ny) - end - for iy in 1:ny - Sxy[1,iy] = dHdvpa_inf(x,y,1,iy) - Sxy[nx,iy] = dHdvpa_inf(x,y,nx,iy) - end - elseif d2Gdvpa2_test - for ix in 1:nx - Sxy[ix,ny] = d2Gdvpa2_inf(x,y,ix,ny) - end - for iy in 1:ny - Sxy[1,iy] = d2Gdvpa2_inf(x,y,1,iy) - Sxy[nx,iy] = d2Gdvpa2_inf(x,y,nx,iy) - end - end - println("Check boundary specification") - #println(Sxy[:,ny]) - #println(Fxy_exact[:,ny]) - println(abs.(Sxy[:,ny] .- Fxy_exact[:,ny])) - println(abs.(Sxy[1,:] .- Fxy_exact[1,:])) - println(abs.(Sxy[nx,:] .- Fxy_exact[nx,:])) - #println(Sxy[1,:]) - #println(Fxy_exact[1,:]) - #println(Sxy[nx,:]) - #println(Fxy_exact[nx,:]) + println("Check boundary specification") + #println(Sxy[:,ny]) + #println(Fxy_exact[:,ny]) + println(abs.(Sxy[:,ny] .- Fxy_exact[:,ny])) + println(abs.(Sxy[1,:] .- Fxy_exact[1,:])) + println(abs.(Sxy[nx,:] .- Fxy_exact[nx,:])) + #println(Sxy[1,:]) + #println(Fxy_exact[1,:]) + #println(Sxy[nx,:]) + #println(Fxy_exact[nx,:]) + end + # assign values to arrays in compound coordinates + @. LLc = 0.0 + for ic in 1:nc + ix = ixfunc(ic,nx) + iy = iyfunc(ic,nx) + Sc[ic] = Sxy[ix,iy] + for icp in 1:nc + ixp = ixfunc(icp,nx) + iyp = iyfunc(icp,nx) + #println("ic: ",ic," ix: ", ix," iy: ",iy," icp: ",icp," ixp: ", ixp," iyp: ",iyp) + LLc[icp,ic] = D2x[ixp,ix]*IIy[iyp,iy] + LLy[iyp,iy]*IIx[ixp,ix] end - # assign values to arrays in compound coordinates - @. LLc = 0.0 - for ic in 1:nc - ix = ixfunc(ic,nx) - iy = iyfunc(ic,nx) - Sc[ic] = Sxy[ix,iy] - for icp in 1:nc - ixp = ixfunc(icp,nx) - iyp = iyfunc(icp,nx) - #println("ic: ",ic," ix: ", ix," iy: ",iy," icp: ",icp," ixp: ", ixp," iyp: ",iyp) - LLc[icp,ic] = D2x[ixp,ix]*IIy[iyp,iy] + LLy[iyp,iy]*IIx[ixp,ix] - end + end + #set fixed bc in LLc directly + if dirichlet_fixed_value + ix = 1; ixp = 1 + for iyp in 1:ny + for iy in 1:ny + ic = icfunc(ix,iy,nx) + icp = icfunc(ixp,iyp,nx) + LLc[icp,ic] = IIy[iyp,iy] + end end - #set fixed bc in LLc directly - if dirichlet_fixed_value - ix = 1; ixp = 1 - for iyp in 1:ny - for iy in 1:ny - ic = icfunc(ix,iy,nx) - icp = icfunc(ixp,iyp,nx) - LLc[icp,ic] = IIy[iyp,iy] - end - end - ix = nx; ixp = nx - for iyp in 1:ny - for iy in 1:ny - ic = icfunc(ix,iy,nx) - icp = icfunc(ixp,iyp,nx) - LLc[icp,ic] = IIy[iyp,iy] - end - end - iy = ny; iyp = ny - for ixp in 1:nx - for ix in 1:nx - ic = icfunc(ix,iy,nx) - icp = icfunc(ixp,iyp,nx) - LLc[icp,ic] = IIx[ixp,ix] - end - end + ix = nx; ixp = nx + for iyp in 1:ny + for iy in 1:ny + ic = icfunc(ix,iy,nx) + icp = icfunc(ixp,iyp,nx) + LLc[icp,ic] = IIy[iyp,iy] + end end - println("Initialised 2D arrays") - if nc < 30 - print_matrix(LLc,"LLc",nc,nc) - end - println("condition number(LLc): ", cond(LLc)) - println("determinant(LLc): ", det(LLc)) - LLc_lu_obj = lu(LLc) - println("Initialised 2D solve") - # do elliptic solve - Fc = LLc_lu_obj\Sc - #reshape to 2D vector - for ic in 1:nc - ix = ixfunc(ic,nx) - iy = iyfunc(ic,nx) - Fxy[ix,iy] = Fc[ic] + iy = ny; iyp = ny + for ixp in 1:nx + for ix in 1:nx + ic = icfunc(ix,iy,nx) + icp = icfunc(ixp,iyp,nx) + LLc[icp,ic] = IIx[ixp,ix] + end end - #if dHdvpa_test && dirichlet_zero - # for iy in 1:ny - # for ix in 1:nx - # Fxy[ix,iy] += dHdvpa_inf(x,y,ix,iy) - # end - # end - #end - println("Finished 2D solve") - @. Fxy_err = abs(Fxy - Fxy_exact) - - println("maximum(Fxy_err)",maximum(Fxy_err)) - #println("Fxy_err",Fxy_err[1,:]) - #println("Fxy_exact",Fxy_exact[1,:]) - #println("Fxy",Fxy[1,:]) - @views heatmap(y.grid, x.grid, Fxy_exact[:,:], xlabel=L"y", ylabel=L"x", c = :deep, interpolation = :cubic, - windowsize = (360,240), margin = 15pt) - outfile = string("Fxy_exact_2D_solve.pdf") - savefig(outfile) - @views heatmap(y.grid, x.grid, Fxy[:,:], xlabel=L"y", ylabel=L"x", c = :deep, interpolation = :cubic, - windowsize = (360,240), margin = 15pt) - outfile = string("Fxy_num_2D_solve.pdf") - savefig(outfile) - @views heatmap(y.grid, x.grid, Fxy_err[:,:], xlabel=L"y", ylabel=L"x", c = :deep, interpolation = :cubic, - windowsize = (360,240), margin = 15pt) - outfile = string("Fxy_err_2D_solve.pdf") - savefig(outfile) end + println("Initialised 2D arrays") + if nc < 30 + print_matrix(LLc,"LLc",nc,nc) + end + println("condition number(LLc): ", cond(LLc)) + println("determinant(LLc): ", det(LLc)) + LLc_lu_obj = lu(LLc) + println("Initialised 2D solve") + # do elliptic solve + Fc = LLc_lu_obj\Sc + #reshape to 2D vector + for ic in 1:nc + ix = ixfunc(ic,nx) + iy = iyfunc(ic,nx) + Fxy[ix,iy] = Fc[ic] + end + #if dHdvpa_test && dirichlet_zero + # for iy in 1:ny + # for ix in 1:nx + # Fxy[ix,iy] += dHdvpa_inf(x,y,ix,iy) + # end + # end + #end + println("Finished 2D solve") + @. Fxy_err = abs(Fxy - Fxy_exact) + + println("maximum(Fxy_err)",maximum(Fxy_err)) + #println("Fxy_err",Fxy_err[1,:]) + #println("Fxy_exact",Fxy_exact[1,:]) + #println("Fxy",Fxy[1,:]) + @views heatmap(y.grid, x.grid, Fxy_exact[:,:], xlabel=L"y", ylabel=L"x", c = :deep, interpolation = :cubic, + windowsize = (360,240), margin = 15pt) + outfile = string("Fxy_exact_2D_solve.pdf") + savefig(outfile) + @views heatmap(y.grid, x.grid, Fxy[:,:], xlabel=L"y", ylabel=L"x", c = :deep, interpolation = :cubic, + windowsize = (360,240), margin = 15pt) + outfile = string("Fxy_num_2D_solve.pdf") + savefig(outfile) + @views heatmap(y.grid, x.grid, Fxy_err[:,:], xlabel=L"y", ylabel=L"x", c = :deep, interpolation = :cubic, + windowsize = (360,240), margin = 15pt) + outfile = string("Fxy_err_2D_solve.pdf") + savefig(outfile) end diff --git a/test_scripts/chebyshev_radau_test.jl b/test_scripts/chebyshev_radau_test.jl index a4d7d6b65..b832c9412 100644 --- a/test_scripts/chebyshev_radau_test.jl +++ b/test_scripts/chebyshev_radau_test.jl @@ -5,9 +5,9 @@ using MPI import moment_kinetics using moment_kinetics.chebyshev -using moment_kinetics.input_structs: grid_input, advection_input using moment_kinetics.coordinates: define_coordinate using moment_kinetics.calculus: derivative! +using moment_kinetics.type_definitions: OptionsDict function print_matrix(matrix,name,n,m) @@ -46,10 +46,8 @@ 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" - # fd_option and adv_input not actually used so given values unimportant fd_option = "fourth_order_centered" cheb_option = "matrix" - adv_input = advection_input("default", 1.0, 0.0, 0.0) nrank = 1 irank = 0#1 comm = MPI.COMM_NULL @@ -57,9 +55,16 @@ function chebyshevradau_test(; ngrid=5, L_in=3.0, discretization="chebyshev_pseu # create the 'input' struct containing input info needed to create a # coordinate y_name = "vperp" # to use radau grid - y_input = grid_input(y_name, y_ngrid, y_nelement_global, y_nelement_local, - nrank, irank, y_L, discretization, fd_option, cheb_option, bc, adv_input,comm,element_spacing_option) - y, y_spectral = define_coordinate(y_input) + input = OptionsDict(y_name => OptionsDict("ngrid"=>y_ngrid, "nelement"=>y_nelement_global, + "nelement_local"=>y_nelement_local, "L"=>y_L, + "discretization"=>discretization, + "finite_difference_option"=>fd_option, + "cheb_option"=>cheb_option, "bc"=>bc, + "element_spacing_option"=>element_spacing_option)) + # create the coordinate struct 'x' + # This test runs effectively in serial, so use `ignore_MPI=true` to avoid + # errors due to communicators not being fully set up. + y, y_spectral = define_coordinate(input, y_name; ignore_MPI=true) Dmat = y_spectral.radau.Dmat print_matrix(Dmat,"Radau Dmat",y.ngrid,y.ngrid) diff --git a/test_scripts/fkpl_direct_integration_test.jl b/test_scripts/fkpl_direct_integration_test.jl index 06e6aeec2..da286fd07 100644 --- a/test_scripts/fkpl_direct_integration_test.jl +++ b/test_scripts/fkpl_direct_integration_test.jl @@ -8,7 +8,6 @@ using MPI using Dates import moment_kinetics -using moment_kinetics.input_structs: grid_input, advection_input using moment_kinetics.coordinates: define_coordinate using moment_kinetics.fokker_planck: init_fokker_planck_collisions_direct_integration using moment_kinetics.fokker_planck_calculus: calculate_rosenbluth_potentials_via_direct_integration! @@ -78,21 +77,20 @@ function init_grids(nelement,ngrid) fd_option = "fourth_order_centered" cheb_option = "matrix" element_spacing_option = "uniform" - adv_input = advection_input("default", 1.0, 0.0, 0.0) - nrank = 1 - irank = 0 - comm = MPI.COMM_NULL # create the 'input' struct containing input info needed to create a # coordinate - vpa_input = grid_input("vpa", vpa_ngrid, vpa_nelement_global, vpa_nelement_local, - nrank, irank, vpa_L, discretization, fd_option, cheb_option, bc, adv_input,comm,element_spacing_option) - vperp_input = grid_input("vperp", vperp_ngrid, vperp_nelement_global, vperp_nelement_local, - nrank, irank, vperp_L, discretization, fd_option, cheb_option, bc, adv_input,comm,element_spacing_option) - + coords_input = OptionsDict( + "vperp"=>OptionsDict("ngrid"=>vperp_ngrid, "nelement"=>vperp_nelement_global, + "nelement_local"=>vperp_nelement_local, "L"=>vperp_L, + "element_spacing_option"=>element_spacing_option), + "vpa"=>OptionsDict("ngrid"=>vpa_ngrid, "nelement"=>vpa_nelement_global, + "nelement_local"=>vpa_nelement_local, "L"=>vpa_L, + "discretization"=>discretization, + "element_spacing_option"=>element_spacing_option), + ) # create the coordinate structs - #println("made inputs") - vpa, vpa_spectral = define_coordinate(vpa_input) - vperp, vperp_spectral = define_coordinate(vperp_input) + vperp, vperp_spectral = define_coordinate(coords_input, "vperp") + vpa, vpa_spectral = define_coordinate(coords_input, "vpa") return vpa, vperp, vpa_spectral, vperp_spectral end diff --git a/test_scripts/gyroaverage_test.jl b/test_scripts/gyroaverage_test.jl index eb1c3bcb6..5550e33b4 100644 --- a/test_scripts/gyroaverage_test.jl +++ b/test_scripts/gyroaverage_test.jl @@ -8,14 +8,15 @@ using Measures using SpecialFunctions: besselj0 import moment_kinetics -using moment_kinetics.input_structs using moment_kinetics.coordinates: define_coordinate +using moment_kinetics.input_structs using moment_kinetics.geo: init_magnetic_geometry using moment_kinetics.communication using moment_kinetics.looping using moment_kinetics.array_allocation: allocate_float, allocate_shared_float using moment_kinetics.gyroaverages: gyroaverage_pdf! using moment_kinetics.gyroaverages: gyroaverage_field!, init_gyro_operators +using moment_kinetics.species_input: get_species_input using moment_kinetics.type_definitions: mk_float, mk_int function print_matrix(matrix,name::String,n::mk_int,m::mk_int) @@ -71,41 +72,62 @@ function gyroaverage_test(;rhostar=0.1, pitch=0.5, ngrid=5, kr=2, kz=2, phaser=0 gyrophase_discretization = "finite_difference" gyrophase_L = 2.0*pi - # fd_option and adv_input not actually used so given values unimportant fd_option = "fourth_order_centered" cheb_option = "matrix" - adv_input = advection_input("default", 1.0, 0.0, 0.0) - nrank = 1 - irank = 0#1 - comm = MPI.COMM_NULL element_spacing_option = "uniform" # create the 'input' struct containing input info needed to create a # coordinate - r_input = grid_input("r", r_ngrid, r_nelement_global, r_nelement_local, - nrank, irank, r_L, discretization, fd_option, cheb_option, r_bc, adv_input,comm,element_spacing_option) - z_input = grid_input("z", z_ngrid, z_nelement_global, z_nelement_local, - nrank, irank, z_L, discretization, fd_option, cheb_option, z_bc, adv_input,comm,element_spacing_option) - vperp_input = grid_input("vperp", vperp_ngrid, vperp_nelement_global, vperp_nelement_local, - nrank, irank, vperp_L, discretization, fd_option, cheb_option, vperp_bc, adv_input,comm,element_spacing_option) - vpa_input = grid_input("vpa", vpa_ngrid, vpa_nelement_global, vpa_nelement_local, - nrank, irank, vpa_L, discretization, fd_option, cheb_option, vpa_bc, adv_input,comm,element_spacing_option) - gyrophase_input = grid_input("gyrophase", gyrophase_ngrid, gyrophase_nelement_global, gyrophase_nelement_local, - nrank, irank, gyrophase_L, gyrophase_discretization, fd_option, cheb_option, "periodic", adv_input,comm,element_spacing_option) + coords_input = OptionsDict( + "r"=>OptionsDict("ngrid"=>r_ngrid, "nelement"=>r_nelement_global, + "nelement_local"=>r_nelement_local, "L"=>r_L, + "discretization"=>discretization, + "finite_difference_option"=>fd_option, + "cheb_option"=>cheb_option, "bc"=>r_bc, + "element_spacing_option"=>element_spacing_option), + "z"=>OptionsDict("ngrid"=>z_ngrid, "nelement"=>z_nelement_global, + "nelement_local"=>z_nelement_local, "L"=>z_L, + "discretization"=>discretization, + "finite_difference_option"=>fd_option, + "cheb_option"=>cheb_option, "bc"=>z_bc, + "element_spacing_option"=>element_spacing_option), + "vperp"=>OptionsDict("ngrid"=>vperp_ngrid, "nelement"=>vperp_nelement_global, + "nelement_local"=>vperp_nelement_local, "L"=>vperp_L, + "discretization"=>discretization, + "finite_difference_option"=>fd_option, + "cheb_option"=>cheb_option, "bc"=>vperp_bc, + "element_spacing_option"=>element_spacing_option), + "vpa"=>OptionsDict("ngrid"=>vpa_ngrid, "nelement"=>vpa_nelement_global, + "nelement_local"=>vpa_nelement_local, "L"=>vpa_L, + "discretization"=>discretization, + "finite_difference_option"=>fd_option, + "cheb_option"=>cheb_option, "bc"=>vpa_bc, + "element_spacing_option"=>element_spacing_option), + "gyrophase"=>OptionsDict("ngrid"=>gyrophase_ngrid, + "nelement"=>gyrophase_nelement_global, + "nelement_local"=>gyrophase_nelement_local, + "L"=>gyrophase_L, "discretization"=>discretization, + "finite_difference_option"=>fd_option, + "cheb_option"=>cheb_option, "bc"=>"periodic", + "element_spacing_option"=>element_spacing_option), + ) # create the coordinate structs - r, r_spectral = define_coordinate(r_input,init_YY=false) - z, z_spectral = define_coordinate(z_input,init_YY=false) - vperp, vperp_spectral = define_coordinate(vperp_input,init_YY=false) - vpa, vpa_spectral = define_coordinate(vpa_input,init_YY=false) - gyrophase, gyrophase_spectral = define_coordinate(gyrophase_input,init_YY=false) + r, r_spectral = define_coordinate(coords_input, "r"; collision_operator_dim=false) + z, z_spectral = define_coordinate(coords_input, "z"; collision_operator_dim=false) + vperp, vperp_spectral = define_coordinate(coords_input, "vperp"; + collision_operator_dim=false) + vpa, vpa_spectral = define_coordinate(coords_input, "vpa"; + collision_operator_dim=false) + gyrophase, gyrophase_spectral = define_coordinate(coords_input, "gyrophase"; + collision_operator_dim=false) # create test geometry #rhostar = 0.1 #rhostar of ions for ExB drift option = "constant-helical" #pitch = 1.0 DeltaB = 1.0 - geometry_in = geometry_input(rhostar,option,pitch,DeltaB) + geometry_in = geometry_input(rhostar,option,pitch,DeltaB,0.0,0.0,0.0,0.0) geometry = init_magnetic_geometry(geometry_in,z,r) # create test composition @@ -132,7 +154,7 @@ function gyroaverage_test(;rhostar=0.1, pitch=0.5, ngrid=5, kr=2, kz=2, phaser=0 end # gyroaverage phi - gyroaverage_field!(gphi,phi,gyro,vperp,z,r) + gyroaverage_field!(gphi,phi,gyro,vperp,z,r,composition) # compute errors begin_serial_region() @@ -214,9 +236,13 @@ function create_test_composition() # `recycling_fraction` to account for ions absorbed by the wall. recycling_fraction = 1.0 gyrokinetic_ions = true - return 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, gyrokinetic_ions, allocate_float(n_species)) + species_opts = OptionsDict("n_ion_species" => n_ion_species, + "n_neutral_species" => n_neutral_species, "T_e" => T_e, + "T_wall" => T_wall, "phi_wall" => phi_wall, + "mn_over_mi" => mn_over_mi, "me_over_mi" => me_over_mi, + "recycling_fraction" => recycling_fraction, + "gyrokinetic_ions" => gyrokinetic_ions) + return get_species_input(OptionsDict("composition" => species_opts)) end function fill_test_arrays!(phi,gphi,vperp,z,r,geometry,kz,kr,phasez,phaser) diff --git a/test_scripts/spline_derivatives_test.jl b/test_scripts/spline_derivatives_test.jl index 1deb5d718..1c65e711d 100644 --- a/test_scripts/spline_derivatives_test.jl +++ b/test_scripts/spline_derivatives_test.jl @@ -1,95 +1,95 @@ -if abspath(PROGRAM_FILE) == @__FILE__ - using Pkg - Pkg.activate(".") +using Pkg +Pkg.activate(".") - import moment_kinetics - using moment_kinetics.input_structs: grid_input, advection_input - using moment_kinetics.coordinates: define_coordinate - using moment_kinetics.chebyshev: setup_chebyshev_pseudospectral - using moment_kinetics.calculus: derivative!, integral #derivative_handle_wall_bc! - using Plots - - discretization = "chebyshev_pseudospectral" - #discretization = "finite_difference" - etol = 1.0e-15 - outprefix = "derivative_test" - ################### - ## df/dx Nonperiodic (No) BC test - ################### - - # define inputs needed for the test - ngrid = 17 #number of points per element - nelement_local = 4 # number of elements per rank - nelement_global = nelement_local # total number of elements - L = 1.0 #physical box size in reference units - # fd_option and adv_input not actually used so given values unimportant - fd_option = "fourth_order_centered" - adv_input = advection_input("default", 1.0, 0.0, 0.0) - nrank = 1 - irank = 0 - comm = false - # create the 'input' struct containing input info needed to create a - # coordinate - x_input = grid_input("coord", ngrid, nelement_global, nelement_local, - nrank, irank, L, discretization, fd_option, "", adv_input,comm) - z_input = grid_input("coord", ngrid, nelement_global, nelement_local, - nrank, irank, L, discretization, fd_option, "wall", adv_input,comm) - # create the coordinate struct 'x' - println("made inputs") - x = define_coordinate(x_input) - z = define_coordinate(z_input) - println("made x") - # create arrays needed for Chebyshev pseudospectral treatment in x - # and create the plans for the forward and backward fast Chebyshev - # transforms - if discretization == "chebyshev_pseudospectral" - spectral = setup_chebyshev_pseudospectral(x) - else - spectral = false - end - println("made spectral") - # create array for the function f(x) to be differentiated/integrated - f = Array{Float64,1}(undef, x.n) - # create array for the derivative df/dx - df = Array{Float64,1}(undef, x.n) - df_opt = Array{Float64,1}(undef, x.n) - df_exact = Array{Float64,1}(undef, x.n) - vz = Array{Float64,1}(undef,x.n) +import moment_kinetics + using moment_kinetics.input_structs: grid_input, advection_input + using moment_kinetics.coordinates: define_coordinate + using moment_kinetics.chebyshev: setup_chebyshev_pseudospectral + using moment_kinetics.calculus: derivative!, integral #derivative_handle_wall_bc! + using Plots + +discretization = "chebyshev_pseudospectral" +#discretization = "finite_difference" + etol = 1.0e-15 +outprefix = "derivative_test" + ################### + ## df/dx Nonperiodic (No) BC test + ################### + # define inputs needed for the test + ngrid = 17 #number of points per element + nelement_local = 4 # number of elements per rank + nelement_global = nelement_local # total number of elements + L = 1.0 #physical box size in reference units + # create the 'input' struct containing input info needed to create a + # coordinate + x_input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, + "nelement"=>nelement_global, + "nelement_local"=>nelement_local, + "L"=>L, + "discretization"=>discretization, + "bc"=>"")) + z_input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, + "nelement"=>nelement_global, + "nelement_local"=>nelement_local, + "L"=>L, + "discretization"=>discretization, + "bc"=>"wall")) + println("made inputs") + # create the coordinate struct 'x' + # This test runs effectively in serial, so use `ignore_MPI=true` to avoid + # errors due to communicators not being fully set up. + x, spectral = define_coordinate(x_input, "coord"; ignore_MPI=true) + z, spectral = define_coordinate(z_input, "coord"; ignore_MPI=true) + println("made x") + # create arrays needed for Chebyshev pseudospectral treatment in x + # and create the plans for the forward and backward fast Chebyshev + # transforms + if discretization == "chebyshev_pseudospectral" + spectral = setup_chebyshev_pseudospectral(x) + else + spectral = false +end +println("made spectral") + # create array for the function f(x) to be differentiated/integrated + f = Array{Float64,1}(undef, x.n) + # create array for the derivative df/dx + df = Array{Float64,1}(undef, x.n) + df_opt = Array{Float64,1}(undef, x.n) +df_exact = Array{Float64,1}(undef, x.n) +vz = Array{Float64,1}(undef,x.n) - xcut = 0.125 - teststring = ".x2."*string(xcut) - ## x^2 test - for ix in 1:x.n - vz[ix] = x.grid[ix] - xcut - if x.grid[ix] > xcut - f[ix] = (x.grid[ix] - xcut)^2 - df_exact[ix] = 2.0*(x.grid[ix] - xcut) - else - f[ix] = 0.0 - df_exact[ix] = 0.0 - end + +xcut = 0.125 +teststring = ".x2."*string(xcut) +## x^2 test +for ix in 1:x.n + vz[ix] = x.grid[ix] - xcut + if x.grid[ix] > xcut + f[ix] = (x.grid[ix] - xcut)^2 + df_exact[ix] = 2.0*(x.grid[ix] - xcut) + else + f[ix] = 0.0 + df_exact[ix] = 0.0 end - - # differentiate f using standard Chebyshev method - derivative!(df, f, x, spectral) - # differentiate f using Chebyshev with spline for subgrid differentiation - iz = 1 # a wall boundary point - derivative!(df_opt, f, x, spectral, iz, z, vz) +end - # plot df, df_opt & df_exact - plot([x.grid,x.grid,x.grid], [vz, f,df_opt,df_exact], xlabel="x", ylabel="", label=["vz" "f" "df_opt" "df_exact"], - shape =:circle, markersize = 5, linewidth=2) - outfile = outprefix*teststring*".onlyspline.pdf" - savefig(outfile) - plot([x.grid,x.grid,x.grid], [f,df,df_opt,df_exact], xlabel="x", ylabel="", label=["f" "df_cheb" "df_opt" "df_exact"], - shape =:circle, markersize = 5, linewidth=2) - outfile = outprefix*teststring*".withspline.pdf" - savefig(outfile) - plot([x.grid,x.grid,x.grid], [f,df,df_exact], xlabel="x", ylabel="", label=["f" "df_cheb" "df_exact"], - shape =:circle, markersize = 5, linewidth=2) - outfile = outprefix*teststring*".pdf" - savefig(outfile) +# differentiate f using standard Chebyshev method +derivative!(df, f, x, spectral) +# differentiate f using Chebyshev with spline for subgrid differentiation +iz = 1 # a wall boundary point +derivative!(df_opt, f, x, spectral, iz, z, vz) -end - +# plot df, df_opt & df_exact +plot([x.grid,x.grid,x.grid], [vz, f,df_opt,df_exact], xlabel="x", ylabel="", label=["vz" "f" "df_opt" "df_exact"], + shape =:circle, markersize = 5, linewidth=2) +outfile = outprefix*teststring*".onlyspline.pdf" +savefig(outfile) +plot([x.grid,x.grid,x.grid], [f,df,df_opt,df_exact], xlabel="x", ylabel="", label=["f" "df_cheb" "df_opt" "df_exact"], + shape =:circle, markersize = 5, linewidth=2) +outfile = outprefix*teststring*".withspline.pdf" +savefig(outfile) +plot([x.grid,x.grid,x.grid], [f,df,df_exact], xlabel="x", ylabel="", label=["f" "df_cheb" "df_exact"], + shape =:circle, markersize = 5, linewidth=2) +outfile = outprefix*teststring*".pdf" +savefig(outfile) diff --git a/util/precompile_makie_plots.jl b/util/precompile_makie_plots.jl index 132556e93..2019a62dd 100644 --- a/util/precompile_makie_plots.jl +++ b/util/precompile_makie_plots.jl @@ -7,42 +7,42 @@ test_output_directory = tempname() run_name = "precompilation" mkpath(test_output_directory) -input_dict = Dict("run_name"=>run_name, - "base_directory" => test_output_directory, - "r_ngrid" => 5, - "r_nelement" => 1, - "r_bc" => "periodic", - "r_discretization" => "chebyshev_pseudospectral", - "z_ngrid" => 5, - "z_nelement" => 1, - "z_bc" => "wall", - "z_discretization" => "chebyshev_pseudospectral", - "vperp_ngrid" => 5, - "vperp_nelement" => 1, - #"vperp_bc" => "periodic", - "vperp_L" => 4.0, - "vperp_discretization" => "chebyshev_pseudospectral", - "vpa_ngrid" => 7, - "vpa_nelement" => 1, - "vpa_bc" => "periodic", - "vpa_L" => 4.0, - "vpa_discretization" => "chebyshev_pseudospectral", - "vzeta_ngrid" => 7, - "vzeta_nelement" => 1, - "vzeta_bc" => "periodic", - "vzeta_L" => 4.0, - "vzeta_discretization" => "chebyshev_pseudospectral", - "vr_ngrid" => 7, - "vr_nelement" => 1, - "vr_bc" => "periodic", - "vr_L" => 4.0, - "vr_discretization" => "chebyshev_pseudospectral", - "vz_ngrid" => 7, - "vz_nelement" => 1, - "vz_bc" => "periodic", - "vz_L" => 4.0, - "vz_discretization" => "chebyshev_pseudospectral", - "timestepping" => OptionsDict("nstep" => 1, "dt" => 2.0e-11)) +input_dict = OptionsDict("run_name"=>run_name, + "base_directory" => test_output_directory, + "r" => OptionsDict("ngrid" => 5, + "nelement" => 1, + "bc" => "periodic", + "discretization" => "chebyshev_pseudospectral"), + "z" => OptionsDict("ngrid" => 5, + "nelement" => 1, + "bc" => "wall", + "discretization" => "chebyshev_pseudospectral"), + "vperp" => OptionsDict("ngrid" => 5, + "nelement" => 1, + #"bc" => "periodic", + "L" => 4.0, + "discretization" => "chebyshev_pseudospectral"), + "vpa" => OptionsDict("ngrid" => 7, + "nelement" => 1, + "bc" => "periodic", + "L" => 4.0, + "discretization" => "chebyshev_pseudospectral"), + "vzeta" => OptionsDict("ngrid" => 7, + "nelement" => 1, + "bc" => "periodic", + "L" => 4.0, + "discretization" => "chebyshev_pseudospectral"), + "vr" => OptionsDict("ngrid" => 7, + "nelement" => 1, + "bc" => "periodic", + "L" => 4.0, + "discretization" => "chebyshev_pseudospectral"), + "vz" => OptionsDict("ngrid" => 7, + "nelement" => 1, + "bc" => "periodic", + "L" => 4.0, + "discretization" => "chebyshev_pseudospectral"), + "timestepping" => OptionsDict("nstep" => 1, "dt" => 2.0e-11)) run_moment_kinetics(input_dict) diff --git a/util/precompile_plots_plots.jl b/util/precompile_plots_plots.jl index e299919fc..17cb7061d 100644 --- a/util/precompile_plots_plots.jl +++ b/util/precompile_plots_plots.jl @@ -7,42 +7,42 @@ test_output_directory = tempname() run_name = "precompilation" mkpath(test_output_directory) -input_dict = Dict("run_name"=>run_name, - "base_directory" => test_output_directory, - "r_ngrid" => 5, - "r_nelement" => 1, - "r_bc" => "periodic", - "r_discretization" => "chebyshev_pseudospectral", - "z_ngrid" => 5, - "z_nelement" => 1, - "z_bc" => "wall", - "z_discretization" => "chebyshev_pseudospectral", - "vperp_ngrid" => 5, - "vperp_nelement" => 1, - #"vperp_bc" => "periodic", - "vperp_L" => 4.0, - "vperp_discretization" => "chebyshev_pseudospectral", - "vpa_ngrid" => 7, - "vpa_nelement" => 1, - "vpa_bc" => "periodic", - "vpa_L" => 4.0, - "vpa_discretization" => "chebyshev_pseudospectral", - "vzeta_ngrid" => 7, - "vzeta_nelement" => 1, - "vzeta_bc" => "periodic", - "vzeta_L" => 4.0, - "vzeta_discretization" => "chebyshev_pseudospectral", - "vr_ngrid" => 7, - "vr_nelement" => 1, - "vr_bc" => "periodic", - "vr_L" => 4.0, - "vr_discretization" => "chebyshev_pseudospectral", - "vz_ngrid" => 7, - "vz_nelement" => 1, - "vz_bc" => "periodic", - "vz_L" => 4.0, - "vz_discretization" => "chebyshev_pseudospectral", - "timestepping" => OptionsDict("nstep" => 1, "dt" => 2.0e-11)) +input_dict = OptionsDict("run_name"=>run_name, + "base_directory" => test_output_directory, + "r" => OptionsDict("ngrid" => 5, + "nelement" => 1, + "bc" => "periodic", + "discretization" => "chebyshev_pseudospectral"), + "z" => OptionsDict("ngrid" => 5, + "nelement" => 1, + "bc" => "wall", + "discretization" => "chebyshev_pseudospectral"), + "vperp" => OptionsDict("ngrid" => 5, + "nelement" => 1, + #"bc" => "periodic", + "L" => 4.0, + "discretization" => "chebyshev_pseudospectral"), + "vpa" => OptionsDict("ngrid" => 7, + "nelement" => 1, + "bc" => "periodic", + "L" => 4.0, + "discretization" => "chebyshev_pseudospectral"), + "vzeta" => OptionsDict("ngrid" => 7, + "nelement" => 1, + "bc" => "periodic", + "L" => 4.0, + "discretization" => "chebyshev_pseudospectral"), + "vr" => OptionsDict("ngrid" => 7, + "nelement" => 1, + "bc" => "periodic", + "L" => 4.0, + "discretization" => "chebyshev_pseudospectral"), + "vz" => OptionsDict("ngrid" => 7, + "nelement" => 1, + "bc" => "periodic", + "L" => 4.0, + "discretization" => "chebyshev_pseudospectral"), + "timestepping" => OptionsDict("nstep" => 1, "dt" => 2.0e-11)) run_moment_kinetics(input_dict) diff --git a/util/precompile_run.jl b/util/precompile_run.jl index 41f6b1d57..bf83be31b 100644 --- a/util/precompile_run.jl +++ b/util/precompile_run.jl @@ -3,105 +3,107 @@ using Pkg Pkg.activate(".") using moment_kinetics +using moment_kinetics.utils: recursive_merge using moment_kinetics.type_definitions: OptionsDict # Create a temporary directory for test output test_output_directory = tempname() mkpath(test_output_directory) -base_input = Dict("run_name" => "precompilation", - "base_directory" => test_output_directory, - "r_ngrid" => 5, - "r_nelement" => 3, - "r_bc" => "periodic", - "r_discretization" => "finite_difference", - "z_ngrid" => 5, - "z_nelement" => 3, - "z_bc" => "periodic", - "z_discretization" => "finite_difference", - "vperp_ngrid" => 5, - "vperp_nelement" => 3, - "vperp_bc" => "zero", - "vperp_L" => 4.0, - "vperp_discretization" => "finite_difference", - "vpa_ngrid" => 7, - "vpa_nelement" => 3, - "vpa_bc" => "zero", - "vpa_L" => 8.0, - "vpa_discretization" => "finite_difference", - "vzeta_ngrid" => 5, - "vzeta_nelement" => 3, - "vzeta_bc" => "zero", - "vzeta_L" => 4.0, - "vzeta_discretization" => "finite_difference", - "vr_ngrid" => 5, - "vr_nelement" => 3, - "vr_bc" => "zero", - "vr_L" => 4.0, - "vr_discretization" => "finite_difference", - "vz_ngrid" => 7, - "vz_nelement" => 3, - "vz_bc" => "zero", - "vz_L" => 8.0, - "vz_discretization" => "finite_difference", - "timestepping" => OptionsDict("nstep" => 1, "dt" => 2.0e-11)) -cheb_input = merge(base_input, Dict("r_discretization" => "chebyshev_pseudospectral", - "z_discretization" => "chebyshev_pseudospectral", - "vperp_discretization" => "chebyshev_pseudospectral", - "vpa_discretization" => "chebyshev_pseudospectral")) -wall_bc_input = merge(base_input, Dict("z_bc" => "wall")) -wall_bc_cheb_input = merge(cheb_input, Dict("z_bc" => "wall")) +base_input = OptionsDict("run_name" => "precompilation", + "base_directory" => test_output_directory, + "r" => OptionsDict("ngrid" => 5, + "nelement" => 3, + "bc" => "periodic", + "discretization" => "finite_difference"), + "z" => OptionsDict("ngrid" => 5, + "nelement" => 3, + "bc" => "periodic", + "discretization" => "finite_difference"), + "vperp" => OptionsDict("ngrid" => 5, + "nelement" => 3, + "bc" => "zero", + "L" => 4.0, + "discretization" => "finite_difference"), + "vpa" => OptionsDict("ngrid" => 7, + "nelement" => 3, + "bc" => "zero", + "L" => 8.0, + "discretization" => "finite_difference"), + "vzeta" => OptionsDict("ngrid" => 5, + "nelement" => 3, + "bc" => "zero", + "L" => 4.0, + "discretization" => "finite_difference"), + "vr" => OptionsDict("ngrid" => 5, + "nelement" => 3, + "bc" => "zero", + "L" => 4.0, + "discretization" => "finite_difference"), + "vz" => OptionsDict("ngrid" => 7, + "nelement" => 3, + "bc" => "zero", + "L" => 8.0, + "discretization" => "finite_difference"), + "timestepping" => OptionsDict("nstep" => 1, "dt" => 2.0e-11)) +cheb_input = recursive_merge(base_input, OptionsDict("r" => OptionsDict("discretization" => "chebyshev_pseudospectral"), + "z" => OptionsDict("discretization" => "chebyshev_pseudospectral"), + "vperp" => OptionsDict("discretization" => "chebyshev_pseudospectral"), + "vpa" => OptionsDict("discretization" => "chebyshev_pseudospectral"))) +wall_bc_input = recursive_merge(base_input, OptionsDict("z" => OptionsDict("bc" => "wall"))) +wall_bc_cheb_input = recursive_merge(cheb_input, OptionsDict("z" => OptionsDict("bc" => "wall"))) -inputs_list = Vector{Dict{String, Any}}(undef, 0) +inputs_list = Vector{OptionsDict}(undef, 0) for input ∈ [base_input, cheb_input, wall_bc_input, wall_bc_cheb_input] push!(inputs_list, input) - x = merge(input, Dict("evolve_moments_density" => true, "ionization_frequency" => 0.0, - "r_ngrid" => 1, "r_nelement" => 1, "vperp_ngrid" => 1, - "vperp_nelement" => 1, "vzeta_ngrid" => 1, - "vzeta_nelement" => 1, "vr_ngrid" => 1, "vr_nelement" => 1)) + x = recursive_merge(input, OptionsDict("evolve_moments_density" => true, "ionization_frequency" => 0.0, + "r" => OptionsDict("ngrid" => 1, "nelement" => 1), + "vperp" => OptionsDict("ngrid" => 1, "nelement" => 1), + "vzeta" => OptionsDict("ngrid" => 1, "nelement" => 1), + "vr" => OptionsDict("ngrid" => 1, "nelement" => 1))) push!(inputs_list, x) - x = merge(x, Dict("evolve_moments_parallel_flow" => true)) + x = merge(x, OptionsDict("evolve_moments_parallel_flow" => true)) push!(inputs_list, x) - x = merge(x, Dict("evolve_moments_parallel_pressure" => true)) + x = merge(x, OptionsDict("evolve_moments_parallel_pressure" => true)) push!(inputs_list, x) end -collisions_input1 = merge(wall_bc_cheb_input, Dict( "composition" => OptionsDict("n_neutral_species" => 0), - "krook_collisions" => OptionsDict("use_krook" => true), - "fokker_planck_collisions" => OptionsDict("use_fokker_planck" => true, "self_collisions" => true, "slowing_down_test" => true), - "vperp_discretization" => "gausslegendre_pseudospectral", - "vpa_discretization" => "gausslegendre_pseudospectral", - )) -collisions_input2 = merge(wall_bc_cheb_input, Dict("composition" => OptionsDict("n_neutral_species" => 0), - "krook_collisions" => OptionsDict("use_krook" => true), - "fokker_planck_collisions" => OptionsDict("use_fokker_planck" => true, "self_collisions" => true, "slowing_down_test" => true), - "vperp_discretization" => "gausslegendre_pseudospectral", - "vpa_discretization" => "gausslegendre_pseudospectral", - "vperp_bc" => "zero-impose-regularity", - )) +collisions_input1 = recursive_merge(wall_bc_cheb_input, OptionsDict("composition" => OptionsDict("n_neutral_species" => 0), + "krook_collisions" => OptionsDict("use_krook" => true), + "fokker_planck_collisions" => OptionsDict("use_fokker_planck" => true, "self_collisions" => true, "slowing_down_test" => true), + "vperp" => OptionsDict("discretization" => "gausslegendre_pseudospectral"), + "vpa" => OptionsDict("discretization" => "gausslegendre_pseudospectral"), + )) +collisions_input2 = recursive_merge(wall_bc_cheb_input, OptionsDict("composition" => OptionsDict("n_neutral_species" => 0), + "krook_collisions" => OptionsDict("use_krook" => true), + "fokker_planck_collisions" => OptionsDict("use_fokker_planck" => true, "self_collisions" => true, "slowing_down_test" => true), + "vperp" => OptionsDict("discretization" => "gausslegendre_pseudospectral", + "bc" => "zero-impose-regularity"), + "vpa" => OptionsDict("discretization" => "gausslegendre_pseudospectral"), + )) # add an additional input for every geometry option available in addition to the default -geo_input1 = merge(wall_bc_cheb_input, Dict("composition" => OptionsDict("n_neutral_species" => 0), - "geometry" => OptionsDict("option" => "1D-mirror", "DeltaB" => 0.5, "pitch" => 0.5, "rhostar" => 1.0))) +geo_input1 = recursive_merge(wall_bc_cheb_input, OptionsDict("composition" => OptionsDict("n_neutral_species" => 0), + "geometry" => OptionsDict("option" => "1D-mirror", "DeltaB" => 0.5, "pitch" => 0.5, "rhostar" => 1.0))) -kinetic_electron_input = merge(cheb_input, Dict("evolve_moments_density" => true, - "evolve_moments_parallel_flow" => true, - "evolve_moments_parallel_pressure" => true, - "r_ngrid" => 1, - "r_nelement" => 1, - "vperp_ngrid" => 1, - "vperp_nelement" => 1, - "vzeta_ngrid" => 1, - "vzeta_nelement" => 1, - "vr_ngrid" => 1, - "vr_nelement" => 1, - "composition" => OptionsDict("electron_physics" => "kinetic_electrons"), - "electron_timestepping" => OptionsDict("nstep" => 1, - "dt" => 2.0e-11, - "initialization_residual_value" => 1.0e10, - "converged_residual_value" => 1.0e10, - "rtol" => 1.0e10, - "no_restart" => true), - )) +kinetic_electron_input = recursive_merge(cheb_input, OptionsDict("evolve_moments_density" => true, + "evolve_moments_parallel_flow" => true, + "evolve_moments_parallel_pressure" => true, + "r" => OptionsDict("ngrid" => 1, + "nelement" => 1), + "vperp" => OptionsDict("ngrid" => 1, + "nelement" => 1), + "vzeta" => OptionsDict("ngrid" => 1, + "nelement" => 1), + "vr" => OptionsDict("ngrid" => 1, + "nelement" => 1), + "composition" => OptionsDict("electron_physics" => "kinetic_electrons"), + "electron_timestepping" => OptionsDict("nstep" => 1, + "dt" => 2.0e-11, + "initialization_residual_value" => 1.0e10, + "converged_residual_value" => 1.0e10, + "rtol" => 1.0e10, + "no_restart" => true), + )) push!(inputs_list, collisions_input1, collisions_input2, geo_input1, kinetic_electron_input) diff --git a/util/precompile_run_kinetic-electrons.jl b/util/precompile_run_kinetic-electrons.jl index 212d9f9bf..0f0f3c2f5 100644 --- a/util/precompile_run_kinetic-electrons.jl +++ b/util/precompile_run_kinetic-electrons.jl @@ -9,53 +9,53 @@ using moment_kinetics.type_definitions: OptionsDict test_output_directory = tempname() mkpath(test_output_directory) -input = Dict("run_name" => "precompilation", - "base_directory" => test_output_directory, - "evolve_moments_density" => true, - "evolve_moments_parallel_flow" => true, - "evolve_moments_parallel_pressure" => true, - "composition" => OptionsDict("electron_physics" => "kinetic_electrons"), - "r_ngrid" => 1, - "r_nelement" => 1, - "r_bc" => "periodic", - "r_discretization" => "chebyshev_pseudospectral", - "z_ngrid" => 5, - "z_nelement" => 4, - "z_bc" => "wall", - "z_discretization" => "chebyshev_pseudospectral", - "vperp_ngrid" => 1, - "vperp_nelement" => 1, - "vperp_bc" => "zero", - "vperp_L" => 4.0, - "vperp_discretization" => "chebyshev_pseudospectral", - "vpa_ngrid" => 7, - "vpa_nelement" => 8, - "vpa_bc" => "zero", - "vpa_L" => 8.0, - "vpa_discretization" => "chebyshev_pseudospectral", - "vzeta_ngrid" => 1, - "vzeta_nelement" => 1, - "vzeta_bc" => "zero", - "vzeta_L" => 4.0, - "vzeta_discretization" => "chebyshev_pseudospectral", - "vr_ngrid" => 1, - "vr_nelement" => 1, - "vr_bc" => "zero", - "vr_L" => 4.0, - "vr_discretization" => "chebyshev_pseudospectral", - "vz_ngrid" => 7, - "vz_nelement" => 8, - "vz_bc" => "zero", - "vz_L" => 8.0, - "vz_discretization" => "chebyshev_pseudospectral", - "timestepping" => OptionsDict("nstep" => 1, - "dt" => 2.0e-11), - "electron_timestepping" => OptionsDict("nstep" => 1, - "dt" => 2.0e-11, - "initialization_residual_value" => 1.0e10, - "converged_residual_value" => 1.0e10, - "rtol" => 1.0e10, - "no_restart" => true)) +input = OptionsDict("run_name" => "precompilation", + "base_directory" => test_output_directory, + "evolve_moments_density" => true, + "evolve_moments_parallel_flow" => true, + "evolve_moments_parallel_pressure" => true, + "composition" => OptionsDict("electron_physics" => "kinetic_electrons"), + "r" => OptionsDict("ngrid" => 1, + "nelement" => 1, + "bc" => "periodic", + "discretization" => "chebyshev_pseudospectral"), + "z" => OptionsDict("ngrid" => 5, + "nelement" => 4, + "bc" => "wall", + "discretization" => "chebyshev_pseudospectral"), + "vperp" => OptionsDict("ngrid" => 1, + "nelement" => 1, + "bc" => "zero", + "L" => 4.0, + "discretization" => "chebyshev_pseudospectral"), + "vpa" => OptionsDict("ngrid" => 7, + "nelement" => 8, + "bc" => "zero", + "L" => 8.0, + "discretization" => "chebyshev_pseudospectral"), + "vzeta" => OptionsDict("ngrid" => 1, + "nelement" => 1, + "bc" => "zero", + "L" => 4.0, + "discretization" => "chebyshev_pseudospectral"), + "vr" => OptionsDict("ngrid" => 1, + "nelement" => 1, + "bc" => "zero", + "L" => 4.0, + "discretization" => "chebyshev_pseudospectral"), + "vz" => OptionsDict("ngrid" => 7, + "nelement" => 8, + "bc" => "zero", + "L" => 8.0, + "discretization" => "chebyshev_pseudospectral"), + "timestepping" => OptionsDict("nstep" => 1, + "dt" => 2.0e-11), + "electron_timestepping" => OptionsDict("nstep" => 1, + "dt" => 2.0e-11, + "initialization_residual_value" => 1.0e10, + "converged_residual_value" => 1.0e10, + "rtol" => 1.0e10, + "no_restart" => true)) run_moment_kinetics(input) diff --git a/util/precompile_run_long.jl b/util/precompile_run_long.jl index 441935757..9f498f315 100644 --- a/util/precompile_run_long.jl +++ b/util/precompile_run_long.jl @@ -7,35 +7,36 @@ Pkg.activate(".") using moment_kinetics using moment_kinetics.type_definitions: OptionsDict +using moment_kinetics.utils: recursive_merge # Create a temporary directory for test output test_output_directory = tempname() mkpath(test_output_directory) -base_input = Dict("run_name"=>"precompilation", - "base_directory" => test_output_directory, - "z_ngrid" => 5, - "z_nelement" => 1, - "z_bc" => "periodic", - "z_discretization" => "finite_difference", - "vpa_ngrid" => 5, - "vpa_nelement" => 1, - "vpa_bc" => "periodic", - "vpa_discretization" => "finite_difference", - "timestepping" => OptionsDict("nstep" => 1, "dt" => 2.0e-11)) -cheb_input = merge(base_input, Dict("z_discretization" => "chebyshev_pseudospectral", - "vpa_discretization" => "chebyshev_pseudospectral")) -wall_bc_input = merge(base_input, Dict("z_bc" => "wall")) -wall_bc_cheb_input = merge(cheb_input, Dict("z_bc" => "wall")) +base_input = OptionsDict("run_name"=>"precompilation", + "base_directory" => test_output_directory, + "z" => OptionsDict("ngrid" => 5, + "nelement" => 1, + "bc" => "periodic", + "discretization" => "finite_difference"), + "vpa" => OptionsDict("ngrid" => 5, + "nelement" => 1, + "bc" => "periodic", + "discretization" => "finite_difference"), + "timestepping" => OptionsDict("nstep" => 1, "dt" => 2.0e-11)) +cheb_input = recursive_merge(base_input, OptionsDict("z" => OptionsDict("discretization" => "chebyshev_pseudospectral"), + "vpa" => OptionsDict("discretization" => "chebyshev_pseudospectral"))) +wall_bc_input = recursive_merge(base_input, OptionsDict("z" => OptionsDict("bc" => "wall"))) +wall_bc_cheb_input = recursive_merge(cheb_input, OptionsDict("z" => OptionsDict("bc" => "wall"))) inputs_list = Vector{OptionsDict}(undef, 0) for input ∈ [base_input, cheb_input, wall_bc_input, wall_bc_cheb_input] push!(inputs_list, input) - x = merge(input, Dict("evolve_moments_density" => true, "ionization_frequency" => 0.0)) + x = merge(input, OptionsDict("evolve_moments_density" => true, "ionization_frequency" => 0.0)) push!(inputs_list, x) - x = merge(x, Dict("evolve_moments_parallel_flow" => true)) + x = merge(x, OptionsDict("evolve_moments_parallel_flow" => true)) push!(inputs_list, x) - x = merge(x, Dict("evolve_moments_parallel_pressure" => true)) + x = merge(x, OptionsDict("evolve_moments_parallel_pressure" => true)) push!(inputs_list, x) end diff --git a/util/precompile_run_long_debug1.jl b/util/precompile_run_long_debug1.jl index dbc009bfa..abce1f115 100644 --- a/util/precompile_run_long_debug1.jl +++ b/util/precompile_run_long_debug1.jl @@ -7,35 +7,36 @@ Pkg.activate(".") using moment_kinetics using moment_kinetics.type_definitions: OptionsDict +using moment_kinetics.utils: recursive_merge # Create a temporary directory for test output test_output_directory = tempname() mkpath(test_output_directory) -base_input = Dict("run_name"=>"precompilation", - "base_directory" => test_output_directory, - "z_ngrid" => 5, - "z_nelement" => 1, - "z_bc" => "periodic", - "z_discretization" => "finite_difference", - "vpa_ngrid" => 5, - "vpa_nelement" => 1, - "vpa_bc" => "periodic", - "vpa_discretization" => "finite_difference", - "timestepping" => OptionsDict("nstep" => 1, "dt" => 2.0e-11)) -cheb_input = merge(base_input, Dict("z_discretization" => "chebyshev_pseudospectral", - "vpa_discretization" => "chebyshev_pseudospectral")) -wall_bc_input = merge(base_input, Dict("z_bc" => "wall")) -wall_bc_cheb_input = merge(cheb_input, Dict("z_bc" => "wall")) +base_input = OptionsDict("run_name"=>"precompilation", + "base_directory" => test_output_directory, + "z" => OptionsDict("ngrid" => 5, + "nelement" => 1, + "bc" => "periodic", + "discretization" => "finite_difference"), + "vpa" => OptionsDict("ngrid" => 5, + "nelement" => 1, + "bc" => "periodic", + "discretization" => "finite_difference"), + "timestepping" => OptionsDict("nstep" => 1, "dt" => 2.0e-11)) +cheb_input = recursive_merge(base_input, OptionsDict("z" => OptionsDict("discretization" => "chebyshev_pseudospectral"), + "vpa" => OptionsDict("discretization" => "chebyshev_pseudospectral"))) +wall_bc_input = recursive_merge(base_input, OptionsDict("z" => OptionsDict("bc" => "wall"))) +wall_bc_cheb_input = recursive_merge(cheb_input, OptionsDict("z" => OptionsDict("bc" => "wall"))) inputs_list = Vector{OptionsDict}(undef, 0) for input ∈ [base_input, cheb_input, wall_bc_input, wall_bc_cheb_input] push!(inputs_list, input) - x = merge(input, Dict("evolve_moments_density" => true, "ionization_frequency" => 0.0)) + x = merge(input, OptionsDict("evolve_moments_density" => true, "ionization_frequency" => 0.0)) push!(inputs_list, x) - x = merge(x, Dict("evolve_moments_parallel_flow" => true)) + x = merge(x, OptionsDict("evolve_moments_parallel_flow" => true)) push!(inputs_list, x) - x = merge(x, Dict("evolve_moments_parallel_pressure" => true)) + x = merge(x, OptionsDict("evolve_moments_parallel_pressure" => true)) push!(inputs_list, x) end From be1cffb19a9f35b66f502da9e53357ea2f63138a Mon Sep 17 00:00:00 2001 From: John Omotani Date: Sat, 7 Sep 2024 00:09:55 +0100 Subject: [PATCH 22/87] Fix handling of periodic bc in gauss_legendre --- moment_kinetics/src/gauss_legendre.jl | 30 ++++++++++++++++++--------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/moment_kinetics/src/gauss_legendre.jl b/moment_kinetics/src/gauss_legendre.jl index 9a0afb6b3..5361547cc 100644 --- a/moment_kinetics/src/gauss_legendre.jl +++ b/moment_kinetics/src/gauss_legendre.jl @@ -850,7 +850,6 @@ function setup_global_weak_form_matrix!(QQ_global::Array{mk_float,2}, # a radau element is used for the vperp grid (see get_QQ_local!()) get_QQ_local!(QQ_j,j,lobatto,radau,coord,option) if coord.bc == "periodic" && coord.nrank == 1 - QQ_global[imax[end], imin[j]:imax[j]] .+= QQ_j[1,:] ./ 2.0 QQ_global[imin[j],imin[j]:imax[j]] .+= QQ_j[1,:] ./ 2.0 else QQ_global[imin[j],imin[j]:imax[j]] .+= QQ_j[1,:] @@ -858,8 +857,14 @@ function setup_global_weak_form_matrix!(QQ_global::Array{mk_float,2}, for k in 2:imax[j]-imin[j] QQ_global[k,imin[j]:imax[j]] .+= QQ_j[k,:] end - if coord.nelement_local > 1 || (coord.bc == "periodic" && coord.nrank == 1) + if coord.nelement_local > 1 QQ_global[imax[j],imin[j]:imax[j]] .+= QQ_j[ngrid,:]./2.0 + elseif coord.bc == "periodic" && coord.nrank == 1 + QQ_global[imin[1],imin[j]:imax[j]] .+= QQ_j[ngrid,:]./2.0 + # Enforce continuity at the periodic boundary + QQ_global[imax[j],imin[j]:imax[j]] .= 0.0 + QQ_global[imax[j],1] = 1.0 + QQ_global[imax[j],end] = -1.0 else QQ_global[imax[j],imin[j]:imax[j]] .+= QQ_j[ngrid,:] end @@ -874,8 +879,11 @@ function setup_global_weak_form_matrix!(QQ_global::Array{mk_float,2}, # upper boundary assembly on element if j == coord.nelement_local if coord.bc == "periodic" && coord.nrank == 1 - QQ_global[imax[j],imin[j]-1:imax[j]] .+= QQ_j[ngrid,:] / 2.0 QQ_global[imin[1],imin[j]-1:imax[j]] .+= QQ_j[ngrid,:] / 2.0 + # Enforce continuity at the periodic boundary + QQ_global[imax[j],imin[j]-1:imax[j]] .= 0.0 + QQ_global[imax[j],1] = 1.0 + QQ_global[imax[j],end] = -1.0 else QQ_global[imax[j],imin[j]-1:imax[j]] .+= QQ_j[ngrid,:] end @@ -1016,7 +1024,7 @@ function get_KK_local!(QQ,ielement, end else # assume integrals of form int^infty_-infty (.) d vpa @. QQ = lobatto.K0/scale_factor - if coord.bc !== "periodic" + if coord.bc != "periodic" # boundary terms from integration by parts if explicit_BC_terms && ielement == 1 && coord.irank == 0 @. QQ[1,:] -= lobatto.Dmat[1,:]/scale_factor @@ -1086,12 +1094,14 @@ function get_LL_local!(QQ,ielement, end else # d^2 (.) d vpa^2 -- assume integrals of form int^infty_-infty (.) d vpa @. QQ = lobatto.K0/scale_factor - # boundary terms from integration by parts - if explicit_BC_terms && ielement == 1 && coord.irank == 0 - @. QQ[1,:] -= lobatto.Dmat[1,:]/scale_factor - end - if explicit_BC_terms && ielement == nelement && coord.irank == coord.nrank - 1 - @. QQ[coord.ngrid,:] += lobatto.Dmat[coord.ngrid,:]/scale_factor + if coord.bc != "periodic" + # boundary terms from integration by parts + if explicit_BC_terms && ielement == 1 && coord.irank == 0 + @. QQ[1,:] -= lobatto.Dmat[1,:]/scale_factor + end + if explicit_BC_terms && ielement == nelement && coord.irank == coord.nrank - 1 + @. QQ[coord.ngrid,:] += lobatto.Dmat[coord.ngrid,:]/scale_factor + end end end return nothing From 6a4e6138ce41060447391423da41c1812e323173 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Sat, 7 Sep 2024 22:55:54 +0100 Subject: [PATCH 23/87] Comment out nelement_local in some recyclefraction examples The Github CI check for the examples does not use distributed MPI, so nelement_local should not be set in the examples. --- .../recycling-fraction/wall-bc_recyclefraction0.5-init.toml | 2 +- examples/recycling-fraction/wall-bc_recyclefraction0.5.toml | 2 +- .../recycling-fraction/wall-bc_recyclefraction0.5_split1.toml | 2 +- .../recycling-fraction/wall-bc_recyclefraction0.5_split2.toml | 2 +- .../wall-bc_recyclefraction0.5_split3-init.toml | 2 +- .../recycling-fraction/wall-bc_recyclefraction0.5_split3.toml | 2 +- .../wall-bc_recyclefraction0.5_split3_SSPRK4.toml | 2 +- .../wall-bc_recyclefraction0.5_split3_fekete104.toml | 2 +- .../wall-bc_recyclefraction0.5_split3_fekete42.toml | 2 +- .../wall-bc_recyclefraction0.5_split3_fekete64.toml | 2 +- .../wall-bc_recyclefraction0.5_split3_rkf54.toml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5-init.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5-init.toml index ffbca9ebd..0a2186d93 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5-init.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5-init.toml @@ -13,7 +13,7 @@ nelement = 1 [z] ngrid = 5 nelement = 32 -nelement_local = 16 +#nelement_local = 16 bc = "wall" discretization = "chebyshev_pseudospectral" element_spacing_option = "sqrt" diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5.toml index 4e3511752..24f0b6b70 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5.toml @@ -13,7 +13,7 @@ nelement = 1 [z] ngrid = 9 nelement = 32 -nelement_local = 16 +#nelement_local = 16 bc = "wall" discretization = "chebyshev_pseudospectral" element_spacing_option = "sqrt" diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split1.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split1.toml index 881adbc94..165ae5a48 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split1.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split1.toml @@ -13,7 +13,7 @@ nelement = 1 [z] ngrid = 9 nelement = 32 -nelement_local = 16 +#nelement_local = 16 bc = "wall" discretization = "chebyshev_pseudospectral" element_spacing_option = "sqrt" diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split2.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split2.toml index d6b120767..76cf09e94 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split2.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split2.toml @@ -13,7 +13,7 @@ nelement = 1 [z] ngrid = 9 nelement = 32 -nelement_local = 16 +#nelement_local = 16 bc = "wall" discretization = "chebyshev_pseudospectral" element_spacing_option = "sqrt" diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3-init.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3-init.toml index a442890df..fff0cdcb0 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3-init.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3-init.toml @@ -13,7 +13,7 @@ nelement = 1 [z] ngrid = 5 nelement = 32 -nelement_local = 16 +#nelement_local = 16 bc = "wall" discretization = "chebyshev_pseudospectral" element_spacing_option = "sqrt" diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3.toml index 2d81d4845..a4c85c6e5 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3.toml @@ -13,7 +13,7 @@ nelement = 1 [z] ngrid = 9 nelement = 32 -nelement_local = 16 +#nelement_local = 16 bc = "wall" discretization = "chebyshev_pseudospectral" element_spacing_option = "sqrt" diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_SSPRK4.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_SSPRK4.toml index 4e0065cae..593f60110 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_SSPRK4.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_SSPRK4.toml @@ -13,7 +13,7 @@ nelement = 1 [z] ngrid = 9 nelement = 32 -nelement_local = 16 +#nelement_local = 16 bc = "wall" discretization = "chebyshev_pseudospectral" element_spacing_option = "sqrt" diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete104.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete104.toml index f41ff30b8..c2821297a 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete104.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete104.toml @@ -14,7 +14,7 @@ nelement = 1 [z] ngrid = 9 nelement = 32 -nelement_local = 16 +#nelement_local = 16 bc = "wall" discretization = "chebyshev_pseudospectral" element_spacing_option = "sqrt" diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete42.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete42.toml index dd17b2e45..c7097e364 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete42.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete42.toml @@ -14,7 +14,7 @@ nelement = 1 [z] ngrid = 9 nelement = 32 -nelement_local = 16 +#nelement_local = 16 bc = "wall" discretization = "chebyshev_pseudospectral" element_spacing_option = "sqrt" diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete64.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete64.toml index 7776446b2..73f22d2a0 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete64.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete64.toml @@ -14,7 +14,7 @@ nelement = 1 [z] ngrid = 9 nelement = 32 -nelement_local = 16 +#nelement_local = 16 bc = "wall" discretization = "chebyshev_pseudospectral" element_spacing_option = "sqrt" diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_rkf54.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_rkf54.toml index 3502216ec..8c8b9a72a 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_rkf54.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_rkf54.toml @@ -14,7 +14,7 @@ nelement = 1 [z] ngrid = 9 nelement = 32 -nelement_local = 16 +#nelement_local = 16 bc = "wall" discretization = "chebyshev_pseudospectral" element_spacing_option = "sqrt" From 1944de710a124925c5b780efd8809c021f4abc79 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Sat, 7 Sep 2024 18:11:09 +0100 Subject: [PATCH 24/87] Remove spline_derivatives_test.jl script This tests a feature that was never added to moment_kinetics. --- test_scripts/spline_derivatives_test.jl | 95 ------------------------- 1 file changed, 95 deletions(-) delete mode 100644 test_scripts/spline_derivatives_test.jl diff --git a/test_scripts/spline_derivatives_test.jl b/test_scripts/spline_derivatives_test.jl deleted file mode 100644 index 1c65e711d..000000000 --- a/test_scripts/spline_derivatives_test.jl +++ /dev/null @@ -1,95 +0,0 @@ -using Pkg -Pkg.activate(".") - -import moment_kinetics - using moment_kinetics.input_structs: grid_input, advection_input - using moment_kinetics.coordinates: define_coordinate - using moment_kinetics.chebyshev: setup_chebyshev_pseudospectral - using moment_kinetics.calculus: derivative!, integral #derivative_handle_wall_bc! - using Plots - -discretization = "chebyshev_pseudospectral" -#discretization = "finite_difference" - etol = 1.0e-15 -outprefix = "derivative_test" - ################### - ## df/dx Nonperiodic (No) BC test - ################### - - # define inputs needed for the test - ngrid = 17 #number of points per element - nelement_local = 4 # number of elements per rank - nelement_global = nelement_local # total number of elements - L = 1.0 #physical box size in reference units - # create the 'input' struct containing input info needed to create a - # coordinate - x_input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, - "nelement"=>nelement_global, - "nelement_local"=>nelement_local, - "L"=>L, - "discretization"=>discretization, - "bc"=>"")) - z_input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, - "nelement"=>nelement_global, - "nelement_local"=>nelement_local, - "L"=>L, - "discretization"=>discretization, - "bc"=>"wall")) - println("made inputs") - # create the coordinate struct 'x' - # This test runs effectively in serial, so use `ignore_MPI=true` to avoid - # errors due to communicators not being fully set up. - x, spectral = define_coordinate(x_input, "coord"; ignore_MPI=true) - z, spectral = define_coordinate(z_input, "coord"; ignore_MPI=true) - println("made x") - # create arrays needed for Chebyshev pseudospectral treatment in x - # and create the plans for the forward and backward fast Chebyshev - # transforms - if discretization == "chebyshev_pseudospectral" - spectral = setup_chebyshev_pseudospectral(x) - else - spectral = false -end -println("made spectral") - # create array for the function f(x) to be differentiated/integrated - f = Array{Float64,1}(undef, x.n) - # create array for the derivative df/dx - df = Array{Float64,1}(undef, x.n) - df_opt = Array{Float64,1}(undef, x.n) -df_exact = Array{Float64,1}(undef, x.n) -vz = Array{Float64,1}(undef,x.n) - - -xcut = 0.125 -teststring = ".x2."*string(xcut) -## x^2 test -for ix in 1:x.n - vz[ix] = x.grid[ix] - xcut - if x.grid[ix] > xcut - f[ix] = (x.grid[ix] - xcut)^2 - df_exact[ix] = 2.0*(x.grid[ix] - xcut) - else - f[ix] = 0.0 - df_exact[ix] = 0.0 - end -end - -# differentiate f using standard Chebyshev method -derivative!(df, f, x, spectral) -# differentiate f using Chebyshev with spline for subgrid differentiation -iz = 1 # a wall boundary point -derivative!(df_opt, f, x, spectral, iz, z, vz) - -# plot df, df_opt & df_exact -plot([x.grid,x.grid,x.grid], [vz, f,df_opt,df_exact], xlabel="x", ylabel="", label=["vz" "f" "df_opt" "df_exact"], - shape =:circle, markersize = 5, linewidth=2) -outfile = outprefix*teststring*".onlyspline.pdf" -savefig(outfile) -plot([x.grid,x.grid,x.grid], [f,df,df_opt,df_exact], xlabel="x", ylabel="", label=["f" "df_cheb" "df_opt" "df_exact"], - shape =:circle, markersize = 5, linewidth=2) -outfile = outprefix*teststring*".withspline.pdf" -savefig(outfile) -plot([x.grid,x.grid,x.grid], [f,df,df_exact], xlabel="x", ylabel="", label=["f" "df_cheb" "df_exact"], - shape =:circle, markersize = 5, linewidth=2) -outfile = outprefix*teststring*".pdf" -savefig(outfile) From b06af35230c114b11cb31f3c334497b333cdb8fd Mon Sep 17 00:00:00 2001 From: John Omotani Date: Sat, 7 Sep 2024 18:13:41 +0100 Subject: [PATCH 25/87] Add Github workflow that checks the 'test_scripts' run without errors --- .github/workflows/test_scripts.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .github/workflows/test_scripts.yml diff --git a/.github/workflows/test_scripts.yml b/.github/workflows/test_scripts.yml new file mode 100644 index 000000000..858159d1a --- /dev/null +++ b/.github/workflows/test_scripts.yml @@ -0,0 +1,25 @@ +# Based on example from https://github.com/julia-actions/julia-runtest +name: Check test_scripts + +on: [push, pull_request, workflow_dispatch] + +jobs: + examples: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macOS-latest] + fail-fast: false + timeout-minutes: 35 + + steps: + - uses: actions/checkout@v4 + - uses: julia-actions/setup-julia@latest + with: + version: '1.10' + - uses: julia-actions/cache@v1 + - name: Test test_scripts + run: | + touch Project.toml + julia -O3 --project -e 'import Pkg; Pkg.develop(path="moment_kinetics/"); Pkg.add(["FastGaussQuadrature", "LaTeXStrings", "LegendrePolynomials", "Measures", "MPI", "Plots", "SpecialFunctions"]); Pkg.precompile()' + julia -O3 --project -e 'include("test_scripts/2D_FEM_assembly_test.jl"); run_assembly_test(); include("test_scripts/chebyshev_radau_test.jl"); chebyshevradau_test(); include("test_scripts/fkpl_direct_integration_test.jl"); test_rosenbluth_potentials_direct_integration(); include("test_scripts/GaussLobattoLegendre_test.jl"); gausslegendre_test(); include("test_scripts/gyroaverage_test.jl"); gyroaverage_test()' From d006a8c1e93ac1ff5054d56fc5c23397db535ccb Mon Sep 17 00:00:00 2001 From: John Omotani Date: Sun, 8 Sep 2024 14:06:07 +0100 Subject: [PATCH 26/87] [em_fields] section in input Create a section to contain the `force_Er_zero_at_wall` option (and others in future). Remove the unused `drive_input` structs. --- moment_kinetics/src/em_fields.jl | 5 ++-- moment_kinetics/src/input_structs.jl | 25 ------------------- moment_kinetics/src/moment_kinetics.jl | 5 ++-- moment_kinetics/src/moment_kinetics_input.jl | 21 +++++++--------- .../src/moment_kinetics_structs.jl | 5 ---- 5 files changed, 14 insertions(+), 47 deletions(-) diff --git a/moment_kinetics/src/em_fields.jl b/moment_kinetics/src/em_fields.jl index 9f26f009c..c08ff6bb3 100644 --- a/moment_kinetics/src/em_fields.jl +++ b/moment_kinetics/src/em_fields.jl @@ -21,7 +21,7 @@ using MPI """ """ -function setup_em_fields(nvperp, nz, nr, n_ion_species, force_phi, drive_amplitude, drive_frequency, force_Er_zero) +function setup_em_fields(nvperp, nz, nr, n_ion_species, em_input) phi = allocate_shared_float(nz,nr) phi0 = allocate_shared_float(nz,nr) Er = allocate_shared_float(nz,nr) @@ -29,7 +29,8 @@ function setup_em_fields(nvperp, nz, nr, n_ion_species, force_phi, drive_amplitu gphi = allocate_shared_float(nvperp,nz,nr,n_ion_species) gEr = allocate_shared_float(nvperp,nz,nr,n_ion_species) gEz = allocate_shared_float(nvperp,nz,nr,n_ion_species) - return em_fields_struct(phi, phi0, Er, Ez, gphi, gEr, gEz, force_phi, drive_amplitude, drive_frequency, force_Er_zero) + return em_fields_struct(phi, phi0, Er, Ez, gphi, gEr, gEz, + em_input.force_Er_zero_at_wall) end """ diff --git a/moment_kinetics/src/input_structs.jl b/moment_kinetics/src/input_structs.jl index 8b681178d..ddaf3960d 100644 --- a/moment_kinetics/src/input_structs.jl +++ b/moment_kinetics/src/input_structs.jl @@ -10,7 +10,6 @@ export initial_condition_input, initial_condition_input_mutable export spatial_initial_condition_input, velocity_initial_condition_input export ion_species_parameters, neutral_species_parameters, species_parameters_mutable export species_composition -export drive_input, drive_input_mutable export collisions_input, krook_collisions_input, fkpl_collisions_input export io_input export pp_input @@ -330,30 +329,6 @@ Base.@kwdef struct species_composition neutral::Vector{neutral_species_parameters} end -""" -""" -mutable struct drive_input_mutable - # if drive.phi = true, include external electrostatic potential - force_phi::Bool - # if external field included, it is of the form - # phi(z,t=0)*amplitude*sinpi(t*frequency) - amplitude::mk_float - frequency::mk_float -end - -""" -""" -struct drive_input - # if drive.phi = true, include external electrostatic potential - force_phi::Bool - # if external field included, it is of the form - # phi(z,t=0)*amplitude*sinpi(t*frequency) - amplitude::mk_float - frequency::mk_float - # if true, forces Er = 0.0 at wall plates - force_Er_zero_at_wall::Bool -end - """ Structs set up for the collision operators so far in use. These will each be contained in the main collisions_input struct below, as substructs. diff --git a/moment_kinetics/src/moment_kinetics.jl b/moment_kinetics/src/moment_kinetics.jl index 4c57e6ed8..255a6d0a5 100644 --- a/moment_kinetics/src/moment_kinetics.jl +++ b/moment_kinetics/src/moment_kinetics.jl @@ -232,7 +232,7 @@ function setup_moment_kinetics(input_dict::AbstractDict; 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, + em_input, external_source_settings, num_diss_params, manufactured_solns_input = input # Create loop range variables for shared-memory-parallel loops @@ -258,8 +258,7 @@ function setup_moment_kinetics(input_dict::AbstractDict; # create the "fields" structure that contains arrays # for the electrostatic potential phi and the electromagnetic fields fields = setup_em_fields(vperp.n, z.n, r.n, composition.n_ion_species, - drive_input.force_phi, drive_input.amplitude, - drive_input.frequency, drive_input.force_Er_zero_at_wall) + em_input) # Allocate arrays and create the pdf and moments structs pdf, moments, boundary_distributions = diff --git a/moment_kinetics/src/moment_kinetics_input.jl b/moment_kinetics/src/moment_kinetics_input.jl index 037a1c195..e264ba357 100644 --- a/moment_kinetics/src/moment_kinetics_input.jl +++ b/moment_kinetics/src/moment_kinetics_input.jl @@ -67,6 +67,7 @@ function mk_input(scan_input=OptionsDict(); save_inputs_to_txt=false, ignore_MPI "finite_difference_option", "element_spacing_option", "bc") )..., + "force_Er_zero_at_wall", ) for opt in removed_options_list if opt ∈ keys(scan_input) @@ -81,7 +82,7 @@ function mk_input(scan_input=OptionsDict(); save_inputs_to_txt=false, ignore_MPI n_ion_species = composition.n_ion_species n_neutral_species = composition.n_neutral_species - drive, evolve_moments = load_defaults() + evolve_moments = load_defaults() # this is the prefix for all output files associated with this run run_name = get(scan_input, "run_name", "wallBC") @@ -351,8 +352,11 @@ function mk_input(scan_input=OptionsDict(); save_inputs_to_txt=false, ignore_MPI _block_synchronize() end - force_Er_zero = get(scan_input, "force_Er_zero_at_wall", false) - drive_immutable = drive_input(drive.force_phi, drive.amplitude, drive.frequency, force_Er_zero) + em_fields_settings = set_defaults_and_check_section!( + scan_input, "em_fields"; + force_Er_zero_at_wall=false, + ) + em_input = Dict_to_NamedTuple(em_fields_settings) # inputs for file I/O io_settings = set_defaults_and_check_section!( @@ -466,7 +470,7 @@ function mk_input(scan_input=OptionsDict(); save_inputs_to_txt=false, ignore_MPI r_spectral, vpa, vpa_spectral, vperp, vperp_spectral, gyrophase, gyrophase_spectral, vz, vz_spectral, vr, vr_spectral, vzeta, vzeta_spectral, composition, species_immutable, collisions, geometry, - drive_immutable, external_source_settings, num_diss_params, + em_input, external_source_settings, num_diss_params, manufactured_solns_input) println(io, "\nAll inputs returned from mk_input():") println(io, all_inputs) @@ -487,14 +491,7 @@ function load_defaults() evolve_moments = evolve_moments_options(evolve_density, evolve_parallel_flow, evolve_parallel_pressure, conservation)#advective_form) #################### parameters related to the z grid ###################### - # if drive_phi = true, include external electrostatic potential of form - # phi(z,t=0)*drive_amplitude*sinpi(time*drive_frequency) - drive_phi = false - drive_amplitude = 1.0 - drive_frequency = 1.0 - drive = drive_input_mutable(drive_phi, drive_amplitude, drive_frequency) - - return drive, evolve_moments + return evolve_moments end """ diff --git a/moment_kinetics/src/moment_kinetics_structs.jl b/moment_kinetics/src/moment_kinetics_structs.jl index acb1a378e..1d87db819 100644 --- a/moment_kinetics/src/moment_kinetics_structs.jl +++ b/moment_kinetics/src/moment_kinetics_structs.jl @@ -56,11 +56,6 @@ struct em_fields_struct gEr::MPISharedArray{mk_float,4} # gEz is the gyroaveraged parallel electric field gEz::MPISharedArray{mk_float,4} - # if including an external forcing for phi, it is of the form - # phi_external = phi0*drive_amplitude*sinpi(t*drive_frequency) - force_phi::Bool - drive_amplitude::mk_float - drive_frequency::mk_float # if true, force Er = 0 at wall plates force_Er_zero_at_wall::Bool end From 855421cef9dcfa28449319cc3f10ec4307596e57 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Sun, 8 Sep 2024 14:27:35 +0100 Subject: [PATCH 27/87] [evolve_moments] section in input --- ...lanck-1D2V-even_nz-shorttest-nstep200.toml | 10 +- ...-planck-relaxation-report-resolutions.toml | 10 +- ...planck-relaxation-slowing-down-alphas.toml | 10 +- ...fokker-planck-relaxation-slowing-down.toml | 10 +- .../fokker-planck-relaxation.toml | 10 +- ...lowing-down-alphas-no-self-collisions.toml | 10 +- ...lanck-source-sink-slowing-down-alphas.toml | 10 +- examples/geometry/1D-mirror.toml | 10 +- examples/gk-ions/2D-periodic-gk.toml | 10 +- .../periodic_split3_boltzmann.toml | 10 +- .../periodic_split3_braginskii-IMEX.toml | 10 +- .../periodic_split3_braginskii.toml | 10 +- .../periodic_split3_kinetic-IMEX.toml | 10 +- .../periodic_split3_kinetic.toml | 10 +- ...ic_split3_kinetic_high-collisionality.toml | 10 +- .../wall+sheath-bc_boltzmann_loworder.toml | 10 +- .../wall+sheath-bc_kinetic.toml | 10 +- ...wall+sheath-bc_kinetic_krook_loworder.toml | 10 +- .../wall+sheath-bc_kinetic_loworder.toml | 10 +- ...on0.5_split3_braginskii-vpadiss0-IMEX.toml | 10 +- ...lefraction0.5_split3_kinetic-vpadiss0.toml | 10 +- .../nonlinear-sound-wave_cheb_split1.toml | 10 +- .../nonlinear-sound-wave_cheb_split2.toml | 10 +- .../nonlinear-sound-wave_cheb_split3.toml | 10 +- .../nonlinear-sound-wave_fd.toml | 10 +- .../nonlinear-sound-wave_fd_split1.toml | 10 +- .../nonlinear-sound-wave_fd_split2.toml | 10 +- .../nonlinear-sound-wave_fd_split3.toml | 10 +- .../num-diss-relaxation.toml | 10 +- .../wall-bc_recyclefraction0.5-init.toml | 10 +- .../wall-bc_recyclefraction0.5.toml | 10 +- .../wall-bc_recyclefraction0.5_split1.toml | 10 +- .../wall-bc_recyclefraction0.5_split2.toml | 10 +- ...all-bc_recyclefraction0.5_split3-init.toml | 10 +- .../wall-bc_recyclefraction0.5_split3.toml | 10 +- ...l-bc_recyclefraction0.5_split3_SSPRK4.toml | 10 +- ...c_recyclefraction0.5_split3_fekete104.toml | 10 +- ...bc_recyclefraction0.5_split3_fekete42.toml | 10 +- ...bc_recyclefraction0.5_split3_fekete64.toml | 10 +- ...ll-bc_recyclefraction0.5_split3_rkf54.toml | 10 +- .../sheath-bc_cheb_test.toml | 10 +- .../wall-bc_cheb_test.toml | 10 +- examples/sound-wave/sound-wave_cheb.toml | 10 +- .../sound-wave/sound-wave_cheb_split1.toml | 10 +- .../sound-wave/sound-wave_cheb_split2.toml | 10 +- .../sound-wave/sound-wave_cheb_split3.toml | 10 +- examples/sound-wave/sound-wave_fd.toml | 10 +- examples/sound-wave/sound-wave_fd_split1.toml | 10 +- examples/sound-wave/sound-wave_fd_split2.toml | 10 +- examples/sound-wave/sound-wave_fd_split3.toml | 10 +- examples/wall-bc/wall+sheath-bc.toml | 10 +- examples/wall-bc/wall-bc_cheb.toml | 10 +- examples/wall-bc/wall-bc_cheb_split1.toml | 10 +- examples/wall-bc/wall-bc_cheb_split2.toml | 10 +- examples/wall-bc/wall-bc_cheb_split3.toml | 10 +- examples/wall-bc/wall-bc_no-neutrals.toml | 10 +- .../wall-bc/wall-bc_no-neutrals_split1.toml | 10 +- .../wall-bc/wall-bc_no-neutrals_split2.toml | 10 +- .../wall-bc/wall-bc_no-neutrals_split3.toml | 10 +- examples/wall-bc/wall-bc_volumerecycle.toml | 10 +- .../wall-bc/wall-bc_volumerecycle_split1.toml | 10 +- .../wall-bc/wall-bc_volumerecycle_split2.toml | 10 +- .../wall-bc/wall-bc_volumerecycle_split3.toml | 10 +- .../fokker_planck_collisions_inputs.jl | 8 +- .../debug_test/gyroaverage_inputs.jl | 8 +- .../debug_test/kinetic_electron_inputs.jl | 8 +- moment_kinetics/debug_test/mms_inputs.jl | 8 +- .../debug_test/recycling_fraction_inputs.jl | 34 +-- .../restart_interpolation_inputs.jl | 30 +- .../debug_test/sound_wave_inputs.jl | 288 +++++++++--------- moment_kinetics/debug_test/wall_bc_inputs.jl | 26 +- moment_kinetics/src/initial_conditions.jl | 2 +- moment_kinetics/src/input_structs.jl | 11 - moment_kinetics/src/moment_kinetics_input.jl | 46 ++- .../test/Krook_collisions_tests.jl | 30 +- .../test/braginskii_electrons_imex_tests.jl | 8 +- .../fokker_planck_time_evolution_tests.jl | 8 +- moment_kinetics/test/harrisonthompson.jl | 16 +- ...ear_sound_wave_inputs_and_expected_data.jl | 20 +- .../test/nonlinear_sound_wave_tests.jl | 12 +- .../test/recycling_fraction_tests.jl | 24 +- .../test/restart_interpolation_tests.jl | 24 +- moment_kinetics/test/sound_wave_tests.jl | 20 +- moment_kinetics/test/wall_bc_tests.jl | 8 +- .../sound-wave/scan_sound-wave_T0.25.toml | 10 +- .../scan_sound-wave_T0.25_split1.toml | 10 +- .../scan_sound-wave_T0.25_split2.toml | 10 +- .../scan_sound-wave_T0.25_split3.toml | 10 +- .../sound-wave/scan_sound-wave_T0.5.toml | 10 +- .../scan_sound-wave_T0.5_split1.toml | 10 +- .../scan_sound-wave_T0.5_split2.toml | 10 +- .../scan_sound-wave_T0.5_split3.toml | 10 +- .../sound-wave/scan_sound-wave_T1.toml | 10 +- .../sound-wave/scan_sound-wave_T1_split1.toml | 10 +- .../sound-wave/scan_sound-wave_T1_split2.toml | 10 +- .../sound-wave/scan_sound-wave_T1_split3.toml | 10 +- .../sound-wave/scan_sound-wave_T2.toml | 10 +- .../sound-wave/scan_sound-wave_T2_split1.toml | 10 +- .../sound-wave/scan_sound-wave_T2_split2.toml | 10 +- .../sound-wave/scan_sound-wave_T2_split3.toml | 10 +- .../sound-wave/scan_sound-wave_T4.toml | 10 +- .../sound-wave/scan_sound-wave_T4_split1.toml | 10 +- .../sound-wave/scan_sound-wave_T4_split2.toml | 10 +- .../sound-wave/scan_sound-wave_T4_split3.toml | 10 +- .../sound-wave/scan_sound-wave_nratio.toml | 10 +- .../scan_sound-wave_nratio_split1.toml | 10 +- .../scan_sound-wave_nratio_split2.toml | 10 +- .../scan_sound-wave_nratio_split3.toml | 10 +- .../wall-bc/wall-bc_recyclefraction0.5.toml | 10 +- .../wall-bc_recyclefraction0.5_split1.toml | 10 +- .../wall-bc_recyclefraction0.5_split2.toml | 10 +- .../wall-bc_recyclefraction0.5_split3.toml | 10 +- util/precompile_run.jl | 13 +- util/precompile_run_kinetic-electrons.jl | 6 +- util/precompile_run_long.jl | 7 +- util/precompile_run_long_debug1.jl | 7 +- 116 files changed, 874 insertions(+), 708 deletions(-) diff --git a/examples/fokker-planck-1D2V/fokker-planck-1D2V-even_nz-shorttest-nstep200.toml b/examples/fokker-planck-1D2V/fokker-planck-1D2V-even_nz-shorttest-nstep200.toml index 34e8a84f2..99bb647de 100644 --- a/examples/fokker-planck-1D2V/fokker-planck-1D2V-even_nz-shorttest-nstep200.toml +++ b/examples/fokker-planck-1D2V/fokker-planck-1D2V-even_nz-shorttest-nstep200.toml @@ -1,11 +1,13 @@ -evolve_moments_density = false -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = false charge_exchange_frequency = 0.0 ionization_frequency = 1.0 constant_ionization_rate = true +[evolve_moments] +density = false +parallel_flow = false +parallel_pressure = false +moments_conservation = false + [z] ngrid = 5 nelement = 16 diff --git a/examples/fokker-planck/fokker-planck-relaxation-report-resolutions.toml b/examples/fokker-planck/fokker-planck-relaxation-report-resolutions.toml index e5583d33a..fb892e565 100644 --- a/examples/fokker-planck/fokker-planck-relaxation-report-resolutions.toml +++ b/examples/fokker-planck/fokker-planck-relaxation-report-resolutions.toml @@ -1,12 +1,14 @@ # cheap input file for a 0D2V relaxation to a collisional Maxwellian distribution with self-ion collisions. -evolve_moments_density = false -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = false charge_exchange_frequency = 0.0 ionization_frequency = 0.0 constant_ionization_rate = false +[evolve_moments] +density = false +parallel_flow = false +parallel_pressure = false +moments_conservation = false + [z] ngrid = 1 nelement = 1 diff --git a/examples/fokker-planck/fokker-planck-relaxation-slowing-down-alphas.toml b/examples/fokker-planck/fokker-planck-relaxation-slowing-down-alphas.toml index fbc9a881a..36293750e 100644 --- a/examples/fokker-planck/fokker-planck-relaxation-slowing-down-alphas.toml +++ b/examples/fokker-planck/fokker-planck-relaxation-slowing-down-alphas.toml @@ -1,13 +1,15 @@ # cheap input file for a 0D2V relaxation to a collisional Maxwellian distribution with self-ion collisions and collisions with fixed Maxwellian background of cold ions and electrons. -evolve_moments_density = false -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = false charge_exchange_frequency = 0.0 ionization_frequency = 0.0 constant_ionization_rate = false +[evolve_moments] +density = false +parallel_flow = false +parallel_pressure = false +moments_conservation = false + [z] ngrid = 1 nelement = 1 diff --git a/examples/fokker-planck/fokker-planck-relaxation-slowing-down.toml b/examples/fokker-planck/fokker-planck-relaxation-slowing-down.toml index 98e890945..c192772ef 100644 --- a/examples/fokker-planck/fokker-planck-relaxation-slowing-down.toml +++ b/examples/fokker-planck/fokker-planck-relaxation-slowing-down.toml @@ -1,12 +1,14 @@ # cheap input file for a 0D2V relaxation to a collisional Maxwellian distribution with self-ion collisions. -evolve_moments_density = false -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = false charge_exchange_frequency = 0.0 ionization_frequency = 0.0 constant_ionization_rate = false +[evolve_moments] +density = false +parallel_flow = false +parallel_pressure = false +moments_conservation = false + [z] ngrid = 1 nelement = 1 diff --git a/examples/fokker-planck/fokker-planck-relaxation.toml b/examples/fokker-planck/fokker-planck-relaxation.toml index b5156939c..9f0c4f8f7 100644 --- a/examples/fokker-planck/fokker-planck-relaxation.toml +++ b/examples/fokker-planck/fokker-planck-relaxation.toml @@ -1,12 +1,14 @@ # cheap input file for a 0D2V relaxation to a collisional Maxwellian distribution with self-ion collisions. -evolve_moments_density = false -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = false charge_exchange_frequency = 0.0 ionization_frequency = 0.0 constant_ionization_rate = false +[evolve_moments] +density = false +parallel_flow = false +parallel_pressure = false +moments_conservation = false + [z] ngrid = 1 nelement = 1 diff --git a/examples/fokker-planck/fokker-planck-source-sink-slowing-down-alphas-no-self-collisions.toml b/examples/fokker-planck/fokker-planck-source-sink-slowing-down-alphas-no-self-collisions.toml index cff4b6251..4e8631f72 100644 --- a/examples/fokker-planck/fokker-planck-source-sink-slowing-down-alphas-no-self-collisions.toml +++ b/examples/fokker-planck/fokker-planck-source-sink-slowing-down-alphas-no-self-collisions.toml @@ -1,12 +1,14 @@ # cheap input file for a 0D2V relaxation to a collisional Maxwellian distribution with self-ion collisions and collisions with fixed Maxwellian background of cold ions and electrons. -evolve_moments_density = false -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = false charge_exchange_frequency = 0.0 ionization_frequency = 0.0 constant_ionization_rate = false +[evolve_moments] +density = false +parallel_flow = false +parallel_pressure = false +moments_conservation = false + [z] ngrid = 1 nelement = 1 diff --git a/examples/fokker-planck/fokker-planck-source-sink-slowing-down-alphas.toml b/examples/fokker-planck/fokker-planck-source-sink-slowing-down-alphas.toml index cb9e4e076..5bd2d1ff0 100644 --- a/examples/fokker-planck/fokker-planck-source-sink-slowing-down-alphas.toml +++ b/examples/fokker-planck/fokker-planck-source-sink-slowing-down-alphas.toml @@ -1,12 +1,14 @@ # cheap input file for a 0D2V relaxation to a collisional Maxwellian distribution with self-ion collisions and collisions with fixed Maxwellian background of cold ions and electrons. -evolve_moments_density = false -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = false charge_exchange_frequency = 0.0 ionization_frequency = 0.0 constant_ionization_rate = false +[evolve_moments] +density = false +parallel_flow = false +parallel_pressure = false +moments_conservation = false + [z] ngrid = 1 nelement = 1 diff --git a/examples/geometry/1D-mirror.toml b/examples/geometry/1D-mirror.toml index 45ce9ba6d..eebd26e51 100644 --- a/examples/geometry/1D-mirror.toml +++ b/examples/geometry/1D-mirror.toml @@ -1,11 +1,13 @@ -evolve_moments_density = false -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = false charge_exchange_frequency = 0.5 ionization_frequency = 0.05 constant_ionization_rate = true +[evolve_moments] +density = false +parallel_flow = false +parallel_pressure = false +moments_conservation = false + [r] ngrid = 1 nelement = 1 diff --git a/examples/gk-ions/2D-periodic-gk.toml b/examples/gk-ions/2D-periodic-gk.toml index 6cffea952..4a0483af3 100644 --- a/examples/gk-ions/2D-periodic-gk.toml +++ b/examples/gk-ions/2D-periodic-gk.toml @@ -1,11 +1,13 @@ -evolve_moments_density = false -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = false charge_exchange_frequency = 0.0 ionization_frequency = 0.05 constant_ionization_rate = true +[evolve_moments] +density = false +parallel_flow = false +parallel_pressure = false +moments_conservation = false + [r] ngrid = 5 nelement = 2 diff --git a/examples/kinetic-electrons/periodic_split3_boltzmann.toml b/examples/kinetic-electrons/periodic_split3_boltzmann.toml index a5105138f..9a6997869 100644 --- a/examples/kinetic-electrons/periodic_split3_boltzmann.toml +++ b/examples/kinetic-electrons/periodic_split3_boltzmann.toml @@ -1,13 +1,15 @@ #runtime_plots = true -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = true -evolve_moments_conservation = true charge_exchange_frequency = 0.75 ionization_frequency = 0.0 constant_ionization_rate = false nu_ei = 1000.0 +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = true +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/kinetic-electrons/periodic_split3_braginskii-IMEX.toml b/examples/kinetic-electrons/periodic_split3_braginskii-IMEX.toml index b2655403b..a36bd7da9 100644 --- a/examples/kinetic-electrons/periodic_split3_braginskii-IMEX.toml +++ b/examples/kinetic-electrons/periodic_split3_braginskii-IMEX.toml @@ -1,13 +1,15 @@ #runtime_plots = true -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = true -evolve_moments_conservation = true charge_exchange_frequency = 0.75 ionization_frequency = 0.0 constant_ionization_rate = false nu_ei = 1000.0 +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = true +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/kinetic-electrons/periodic_split3_braginskii.toml b/examples/kinetic-electrons/periodic_split3_braginskii.toml index b3b971397..2441cb923 100644 --- a/examples/kinetic-electrons/periodic_split3_braginskii.toml +++ b/examples/kinetic-electrons/periodic_split3_braginskii.toml @@ -1,13 +1,15 @@ #runtime_plots = true -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = true -evolve_moments_conservation = true charge_exchange_frequency = 0.75 ionization_frequency = 0.0 constant_ionization_rate = false nu_ei = 1000.0 +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = true +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/kinetic-electrons/periodic_split3_kinetic-IMEX.toml b/examples/kinetic-electrons/periodic_split3_kinetic-IMEX.toml index 268f52889..0343096ed 100644 --- a/examples/kinetic-electrons/periodic_split3_kinetic-IMEX.toml +++ b/examples/kinetic-electrons/periodic_split3_kinetic-IMEX.toml @@ -1,13 +1,15 @@ #runtime_plots = true -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = true -evolve_moments_conservation = true charge_exchange_frequency = 0.75 ionization_frequency = 0.0 constant_ionization_rate = false nu_ei = 1000.0 +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = true +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/kinetic-electrons/periodic_split3_kinetic.toml b/examples/kinetic-electrons/periodic_split3_kinetic.toml index 465de6619..778ecf97e 100644 --- a/examples/kinetic-electrons/periodic_split3_kinetic.toml +++ b/examples/kinetic-electrons/periodic_split3_kinetic.toml @@ -1,13 +1,15 @@ #runtime_plots = true -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = true -evolve_moments_conservation = true charge_exchange_frequency = 0.75 ionization_frequency = 0.0 constant_ionization_rate = false nu_ei = 1000.0 +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = true +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/kinetic-electrons/periodic_split3_kinetic_high-collisionality.toml b/examples/kinetic-electrons/periodic_split3_kinetic_high-collisionality.toml index d94684ba1..78347d9d3 100644 --- a/examples/kinetic-electrons/periodic_split3_kinetic_high-collisionality.toml +++ b/examples/kinetic-electrons/periodic_split3_kinetic_high-collisionality.toml @@ -1,13 +1,15 @@ #runtime_plots = true -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = true -evolve_moments_conservation = true charge_exchange_frequency = 0.75 ionization_frequency = 0.0 constant_ionization_rate = false nu_ei = 1000.0 +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = true +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/kinetic-electrons/wall+sheath-bc_boltzmann_loworder.toml b/examples/kinetic-electrons/wall+sheath-bc_boltzmann_loworder.toml index 727121f5b..768fd8115 100644 --- a/examples/kinetic-electrons/wall+sheath-bc_boltzmann_loworder.toml +++ b/examples/kinetic-electrons/wall+sheath-bc_boltzmann_loworder.toml @@ -1,9 +1,5 @@ steady_state_residual = true converged_residual_value = 1.0e-3 -evolve_moments_density = false -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = false charge_exchange_frequency = 2.0 electron_charge_exchange_frequency = 0.0 nu_ei = 0.0 @@ -12,6 +8,12 @@ ionization_frequency = 2.0 #ionization_energy = 1.0 constant_ionization_rate = false +[evolve_moments] +density = false +parallel_flow = false +parallel_pressure = false +moments_conservation = false + [r] ngrid = 1 nelement = 1 diff --git a/examples/kinetic-electrons/wall+sheath-bc_kinetic.toml b/examples/kinetic-electrons/wall+sheath-bc_kinetic.toml index 66da6581b..1f3bc62c4 100644 --- a/examples/kinetic-electrons/wall+sheath-bc_kinetic.toml +++ b/examples/kinetic-electrons/wall+sheath-bc_kinetic.toml @@ -1,7 +1,3 @@ -evolve_moments_density = false -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = false charge_exchange_frequency = 2.0 electron_charge_exchange_frequency = 0.0 nu_ei = 0.0 @@ -10,6 +6,12 @@ electron_ionization_frequency = 2.0 ionization_energy = 1.0 constant_ionization_rate = false +[evolve_moments] +density = false +parallel_flow = false +parallel_pressure = false +moments_conservation = false + [r] ngrid = 1 nelement = 1 diff --git a/examples/kinetic-electrons/wall+sheath-bc_kinetic_krook_loworder.toml b/examples/kinetic-electrons/wall+sheath-bc_kinetic_krook_loworder.toml index 06b996e56..fa2b76153 100644 --- a/examples/kinetic-electrons/wall+sheath-bc_kinetic_krook_loworder.toml +++ b/examples/kinetic-electrons/wall+sheath-bc_kinetic_krook_loworder.toml @@ -1,7 +1,3 @@ -evolve_moments_density = false -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = false charge_exchange_frequency = 2.0 electron_charge_exchange_frequency = 0.0 nu_ei = 0.0 @@ -10,6 +6,12 @@ electron_ionization_frequency = 2.0 ionization_energy = 1.0 constant_ionization_rate = false +[evolve_moments] +density = false +parallel_flow = false +parallel_pressure = false +moments_conservation = false + [r] ngrid = 1 nelement = 1 diff --git a/examples/kinetic-electrons/wall+sheath-bc_kinetic_loworder.toml b/examples/kinetic-electrons/wall+sheath-bc_kinetic_loworder.toml index d481945bd..b8d9d2383 100644 --- a/examples/kinetic-electrons/wall+sheath-bc_kinetic_loworder.toml +++ b/examples/kinetic-electrons/wall+sheath-bc_kinetic_loworder.toml @@ -1,9 +1,5 @@ steady_state_residual = true converged_residual_value = 1.0e-3 -evolve_moments_density = false -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = false charge_exchange_frequency = 2.0 electron_charge_exchange_frequency = 0.0 nu_ei = 0.0 @@ -12,6 +8,12 @@ ionization_frequency = 2.0 #ionization_energy = 1.0 constant_ionization_rate = false +[evolve_moments] +density = false +parallel_flow = false +parallel_pressure = false +moments_conservation = false + [r] ngrid = 1 nelement = 1 diff --git a/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_braginskii-vpadiss0-IMEX.toml b/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_braginskii-vpadiss0-IMEX.toml index 50759a94c..f59062dee 100644 --- a/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_braginskii-vpadiss0-IMEX.toml +++ b/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_braginskii-vpadiss0-IMEX.toml @@ -1,13 +1,15 @@ #runtime_plots = true -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = true -evolve_moments_conservation = true charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false nu_ei = 1000.0 +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = true +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_kinetic-vpadiss0.toml b/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_kinetic-vpadiss0.toml index 3776a0287..86980b6b6 100644 --- a/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_kinetic-vpadiss0.toml +++ b/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_kinetic-vpadiss0.toml @@ -1,12 +1,14 @@ #runtime_plots = true -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = true -evolve_moments_conservation = true charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = true +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/nonlinear-sound-wave/nonlinear-sound-wave_cheb_split1.toml b/examples/nonlinear-sound-wave/nonlinear-sound-wave_cheb_split1.toml index 167a8611b..0b5bace4c 100644 --- a/examples/nonlinear-sound-wave/nonlinear-sound-wave_cheb_split1.toml +++ b/examples/nonlinear-sound-wave/nonlinear-sound-wave_cheb_split1.toml @@ -1,10 +1,12 @@ -evolve_moments_density = true -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 +[evolve_moments] +density = true +parallel_flow = false +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/nonlinear-sound-wave/nonlinear-sound-wave_cheb_split2.toml b/examples/nonlinear-sound-wave/nonlinear-sound-wave_cheb_split2.toml index 99e9ec127..90fecb742 100644 --- a/examples/nonlinear-sound-wave/nonlinear-sound-wave_cheb_split2.toml +++ b/examples/nonlinear-sound-wave/nonlinear-sound-wave_cheb_split2.toml @@ -1,10 +1,12 @@ -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/nonlinear-sound-wave/nonlinear-sound-wave_cheb_split3.toml b/examples/nonlinear-sound-wave/nonlinear-sound-wave_cheb_split3.toml index 65ce1cb0f..1dbee53d4 100644 --- a/examples/nonlinear-sound-wave/nonlinear-sound-wave_cheb_split3.toml +++ b/examples/nonlinear-sound-wave/nonlinear-sound-wave_cheb_split3.toml @@ -1,10 +1,12 @@ -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = true -evolve_moments_conservation = true charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = true +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd.toml b/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd.toml index 2994d865d..57f08163e 100644 --- a/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd.toml +++ b/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd.toml @@ -1,10 +1,12 @@ -evolve_moments_density = false -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 +[evolve_moments] +density = false +parallel_flow = false +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd_split1.toml b/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd_split1.toml index 0f060b8ef..f1d2e0cb8 100644 --- a/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd_split1.toml +++ b/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd_split1.toml @@ -1,10 +1,12 @@ -evolve_moments_density = true -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 +[evolve_moments] +density = true +parallel_flow = false +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd_split2.toml b/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd_split2.toml index a22fa0eee..5d29359f5 100644 --- a/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd_split2.toml +++ b/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd_split2.toml @@ -1,10 +1,12 @@ -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd_split3.toml b/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd_split3.toml index ab4fa6715..09fed2159 100644 --- a/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd_split3.toml +++ b/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd_split3.toml @@ -1,10 +1,12 @@ -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = true -evolve_moments_conservation = true charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = true +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/numerical-dissipation/num-diss-relaxation.toml b/examples/numerical-dissipation/num-diss-relaxation.toml index 2486495dd..b23184c3e 100644 --- a/examples/numerical-dissipation/num-diss-relaxation.toml +++ b/examples/numerical-dissipation/num-diss-relaxation.toml @@ -1,13 +1,15 @@ # cheap input file for a 0D2V relaxation with numerical diffusion terms d^2 F / dvpa^2 and d^2 F / vperp^2. -evolve_moments_density = false -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = false charge_exchange_frequency = 0.0 ionization_frequency = 0.0 constant_ionization_rate = false nuii = 0.0 +[evolve_moments] +density = false +parallel_flow = false +parallel_pressure = false +moments_conservation = false + [z] ngrid = 1 nelement = 1 diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5-init.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5-init.toml index 0a2186d93..1956049b1 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5-init.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5-init.toml @@ -1,11 +1,13 @@ -evolve_moments_density = false -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = false charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false +[evolve_moments] +density = false +parallel_flow = false +parallel_pressure = false +moments_conservation = false + [r] ngrid = 1 nelement = 1 diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5.toml index 24f0b6b70..79f90e62c 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5.toml @@ -1,11 +1,13 @@ -evolve_moments_density = false -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = false charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false +[evolve_moments] +density = false +parallel_flow = false +parallel_pressure = false +moments_conservation = false + [r] ngrid = 1 nelement = 1 diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split1.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split1.toml index 165ae5a48..c0e76d0c0 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split1.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split1.toml @@ -1,11 +1,13 @@ -evolve_moments_density = true -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false +[evolve_moments] +density = true +parallel_flow = false +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split2.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split2.toml index 76cf09e94..eddd63c66 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split2.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split2.toml @@ -1,11 +1,13 @@ -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3-init.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3-init.toml index fff0cdcb0..f836b07d5 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3-init.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3-init.toml @@ -1,11 +1,13 @@ -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = true -evolve_moments_conservation = true charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = true +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3.toml index a4c85c6e5..4e0888561 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3.toml @@ -1,11 +1,13 @@ -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = true -evolve_moments_conservation = true charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = true +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_SSPRK4.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_SSPRK4.toml index 593f60110..31bc27b08 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_SSPRK4.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_SSPRK4.toml @@ -1,11 +1,13 @@ -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = true -evolve_moments_conservation = true charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = true +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete104.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete104.toml index c2821297a..e794efd8e 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete104.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete104.toml @@ -1,12 +1,14 @@ #runtime_plots = true -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = true -evolve_moments_conservation = true charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = true +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete42.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete42.toml index c7097e364..885c94c4f 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete42.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete42.toml @@ -1,12 +1,14 @@ #runtime_plots = true -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = true -evolve_moments_conservation = true charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = true +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete64.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete64.toml index 73f22d2a0..08dfb3e90 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete64.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete64.toml @@ -1,12 +1,14 @@ #runtime_plots = true -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = true -evolve_moments_conservation = true charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = true +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_rkf54.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_rkf54.toml index 8c8b9a72a..91d442b15 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_rkf54.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_rkf54.toml @@ -1,12 +1,14 @@ #runtime_plots = true -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = true -evolve_moments_conservation = true charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = true +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/sheath+wall-bc_test/sheath-bc_cheb_test.toml b/examples/sheath+wall-bc_test/sheath-bc_cheb_test.toml index bc223dcdb..96336b4ad 100644 --- a/examples/sheath+wall-bc_test/sheath-bc_cheb_test.toml +++ b/examples/sheath+wall-bc_test/sheath-bc_cheb_test.toml @@ -1,11 +1,13 @@ -evolve_moments_density = false -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = false charge_exchange_frequency = 2.0 ionization_frequency = 2.0 constant_ionization_rate = false +[evolve_moments] +density = false +parallel_flow = false +parallel_pressure = false +moments_conservation = false + [r] ngrid = 1 nelement = 1 diff --git a/examples/sheath+wall-bc_test/wall-bc_cheb_test.toml b/examples/sheath+wall-bc_test/wall-bc_cheb_test.toml index 22a942e8c..0cbebcd22 100644 --- a/examples/sheath+wall-bc_test/wall-bc_cheb_test.toml +++ b/examples/sheath+wall-bc_test/wall-bc_cheb_test.toml @@ -1,11 +1,13 @@ -evolve_moments_density = false -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = false charge_exchange_frequency = 2.0 ionization_frequency = 2.0 constant_ionization_rate = false +[evolve_moments] +density = false +parallel_flow = false +parallel_pressure = false +moments_conservation = false + [r] ngrid = 1 nelement = 1 diff --git a/examples/sound-wave/sound-wave_cheb.toml b/examples/sound-wave/sound-wave_cheb.toml index cf5ca9331..3524112a1 100644 --- a/examples/sound-wave/sound-wave_cheb.toml +++ b/examples/sound-wave/sound-wave_cheb.toml @@ -1,10 +1,12 @@ -evolve_moments_density = false -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 +[evolve_moments] +density = false +parallel_flow = false +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/sound-wave/sound-wave_cheb_split1.toml b/examples/sound-wave/sound-wave_cheb_split1.toml index e26556303..3e9bf7d19 100644 --- a/examples/sound-wave/sound-wave_cheb_split1.toml +++ b/examples/sound-wave/sound-wave_cheb_split1.toml @@ -1,10 +1,12 @@ -evolve_moments_density = true -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 +[evolve_moments] +density = true +parallel_flow = false +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/sound-wave/sound-wave_cheb_split2.toml b/examples/sound-wave/sound-wave_cheb_split2.toml index 4fa8275f4..f81527824 100644 --- a/examples/sound-wave/sound-wave_cheb_split2.toml +++ b/examples/sound-wave/sound-wave_cheb_split2.toml @@ -1,10 +1,12 @@ -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/sound-wave/sound-wave_cheb_split3.toml b/examples/sound-wave/sound-wave_cheb_split3.toml index a18e377d6..a1b1edf52 100644 --- a/examples/sound-wave/sound-wave_cheb_split3.toml +++ b/examples/sound-wave/sound-wave_cheb_split3.toml @@ -1,10 +1,12 @@ -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = true -evolve_moments_conservation = true charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = true +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/sound-wave/sound-wave_fd.toml b/examples/sound-wave/sound-wave_fd.toml index 3d228f230..18c7b3379 100644 --- a/examples/sound-wave/sound-wave_fd.toml +++ b/examples/sound-wave/sound-wave_fd.toml @@ -1,10 +1,12 @@ -evolve_moments_density = false -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 +[evolve_moments] +density = false +parallel_flow = false +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/sound-wave/sound-wave_fd_split1.toml b/examples/sound-wave/sound-wave_fd_split1.toml index 7c5914e8f..0f0639a5c 100644 --- a/examples/sound-wave/sound-wave_fd_split1.toml +++ b/examples/sound-wave/sound-wave_fd_split1.toml @@ -1,10 +1,12 @@ -evolve_moments_density = true -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 +[evolve_moments] +density = true +parallel_flow = false +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/sound-wave/sound-wave_fd_split2.toml b/examples/sound-wave/sound-wave_fd_split2.toml index 622627963..762903ada 100644 --- a/examples/sound-wave/sound-wave_fd_split2.toml +++ b/examples/sound-wave/sound-wave_fd_split2.toml @@ -1,10 +1,12 @@ -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/sound-wave/sound-wave_fd_split3.toml b/examples/sound-wave/sound-wave_fd_split3.toml index 51366f2da..4e943451d 100644 --- a/examples/sound-wave/sound-wave_fd_split3.toml +++ b/examples/sound-wave/sound-wave_fd_split3.toml @@ -1,10 +1,12 @@ -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = true -evolve_moments_conservation = true charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = true +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/wall-bc/wall+sheath-bc.toml b/examples/wall-bc/wall+sheath-bc.toml index c4a936255..38cd03da0 100644 --- a/examples/wall-bc/wall+sheath-bc.toml +++ b/examples/wall-bc/wall+sheath-bc.toml @@ -1,11 +1,13 @@ -evolve_moments_density = false -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = false charge_exchange_frequency = 2.0 ionization_frequency = 2.0 constant_ionization_rate = false +[evolve_moments] +density = false +parallel_flow = false +parallel_pressure = false +moments_conservation = false + [r] ngrid = 1 nelement = 1 diff --git a/examples/wall-bc/wall-bc_cheb.toml b/examples/wall-bc/wall-bc_cheb.toml index b5095d937..b552848c8 100644 --- a/examples/wall-bc/wall-bc_cheb.toml +++ b/examples/wall-bc/wall-bc_cheb.toml @@ -1,11 +1,13 @@ -evolve_moments_density = false -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = false charge_exchange_frequency = 0.5 ionization_frequency = 0.75 constant_ionization_rate = false +[evolve_moments] +density = false +parallel_flow = false +parallel_pressure = false +moments_conservation = false + [r] ngrid = 1 nelement = 1 diff --git a/examples/wall-bc/wall-bc_cheb_split1.toml b/examples/wall-bc/wall-bc_cheb_split1.toml index d40deb978..3bd3a0944 100644 --- a/examples/wall-bc/wall-bc_cheb_split1.toml +++ b/examples/wall-bc/wall-bc_cheb_split1.toml @@ -1,12 +1,14 @@ #runtime_plots = true -evolve_moments_density = true -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true charge_exchange_frequency = 0.5 ionization_frequency = 0.75 constant_ionization_rate = false +[evolve_moments] +density = true +parallel_flow = false +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/wall-bc/wall-bc_cheb_split2.toml b/examples/wall-bc/wall-bc_cheb_split2.toml index 06cf14dec..7480c957b 100644 --- a/examples/wall-bc/wall-bc_cheb_split2.toml +++ b/examples/wall-bc/wall-bc_cheb_split2.toml @@ -1,12 +1,14 @@ #runtime_plots = true -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true charge_exchange_frequency = 0.5 ionization_frequency = 0.75 constant_ionization_rate = false +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/wall-bc/wall-bc_cheb_split3.toml b/examples/wall-bc/wall-bc_cheb_split3.toml index ca668cb8e..ad2361074 100644 --- a/examples/wall-bc/wall-bc_cheb_split3.toml +++ b/examples/wall-bc/wall-bc_cheb_split3.toml @@ -1,12 +1,14 @@ #runtime_plots = true -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = true -evolve_moments_conservation = true charge_exchange_frequency = 0.5 ionization_frequency = 0.75 constant_ionization_rate = false +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = true +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/wall-bc/wall-bc_no-neutrals.toml b/examples/wall-bc/wall-bc_no-neutrals.toml index b937712fc..c312c943e 100644 --- a/examples/wall-bc/wall-bc_no-neutrals.toml +++ b/examples/wall-bc/wall-bc_no-neutrals.toml @@ -1,10 +1,12 @@ steady_state_residual = true converged_residual_value = 1.0e-3 runtime_plots = true -evolve_moments_density = false -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true + +[evolve_moments] +density = false +parallel_flow = false +parallel_pressure = false +moments_conservation = true [r] ngrid = 1 diff --git a/examples/wall-bc/wall-bc_no-neutrals_split1.toml b/examples/wall-bc/wall-bc_no-neutrals_split1.toml index 51e2f11ac..13e40d68b 100644 --- a/examples/wall-bc/wall-bc_no-neutrals_split1.toml +++ b/examples/wall-bc/wall-bc_no-neutrals_split1.toml @@ -1,10 +1,12 @@ steady_state_residual = true converged_residual_value = 1.0e-3 runtime_plots = true -evolve_moments_density = true -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true + +[evolve_moments] +density = true +parallel_flow = false +parallel_pressure = false +moments_conservation = true [r] ngrid = 1 diff --git a/examples/wall-bc/wall-bc_no-neutrals_split2.toml b/examples/wall-bc/wall-bc_no-neutrals_split2.toml index dfdfa2cb9..fab70061c 100644 --- a/examples/wall-bc/wall-bc_no-neutrals_split2.toml +++ b/examples/wall-bc/wall-bc_no-neutrals_split2.toml @@ -1,10 +1,12 @@ steady_state_residual = true converged_residual_value = 1.0e-3 runtime_plots = true -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true + +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = false +moments_conservation = true [r] ngrid = 1 diff --git a/examples/wall-bc/wall-bc_no-neutrals_split3.toml b/examples/wall-bc/wall-bc_no-neutrals_split3.toml index d05352b43..5c58cc7d0 100644 --- a/examples/wall-bc/wall-bc_no-neutrals_split3.toml +++ b/examples/wall-bc/wall-bc_no-neutrals_split3.toml @@ -1,10 +1,12 @@ steady_state_residual = true converged_residual_value = 1.0e-3 runtime_plots = true -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = true -evolve_moments_conservation = true + +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = true +moments_conservation = true [r] ngrid = 1 diff --git a/examples/wall-bc/wall-bc_volumerecycle.toml b/examples/wall-bc/wall-bc_volumerecycle.toml index 918cafa2f..44ccfba08 100644 --- a/examples/wall-bc/wall-bc_volumerecycle.toml +++ b/examples/wall-bc/wall-bc_volumerecycle.toml @@ -1,14 +1,16 @@ steady_state_residual = true converged_residual_value = 1.0e-3 #runtime_plots = true -evolve_moments_density = false -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false +[evolve_moments] +density = false +parallel_flow = false +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/wall-bc/wall-bc_volumerecycle_split1.toml b/examples/wall-bc/wall-bc_volumerecycle_split1.toml index b1649dc74..0d2910d81 100644 --- a/examples/wall-bc/wall-bc_volumerecycle_split1.toml +++ b/examples/wall-bc/wall-bc_volumerecycle_split1.toml @@ -1,14 +1,16 @@ steady_state_residual = true converged_residual_value = 1.0e-3 #runtime_plots = true -evolve_moments_density = true -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false +[evolve_moments] +density = true +parallel_flow = false +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/wall-bc/wall-bc_volumerecycle_split2.toml b/examples/wall-bc/wall-bc_volumerecycle_split2.toml index 94adb5859..9588966c9 100644 --- a/examples/wall-bc/wall-bc_volumerecycle_split2.toml +++ b/examples/wall-bc/wall-bc_volumerecycle_split2.toml @@ -1,14 +1,16 @@ steady_state_residual = true converged_residual_value = 1.0e-3 #runtime_plots = true -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/examples/wall-bc/wall-bc_volumerecycle_split3.toml b/examples/wall-bc/wall-bc_volumerecycle_split3.toml index 9abeb6950..e3d53461d 100644 --- a/examples/wall-bc/wall-bc_volumerecycle_split3.toml +++ b/examples/wall-bc/wall-bc_volumerecycle_split3.toml @@ -1,14 +1,16 @@ steady_state_residual = true converged_residual_value = 1.0e-3 #runtime_plots = true -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = true -evolve_moments_conservation = true charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = true +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/moment_kinetics/debug_test/fokker_planck_collisions_inputs.jl b/moment_kinetics/debug_test/fokker_planck_collisions_inputs.jl index bedfe1a0c..b9d6d17a4 100644 --- a/moment_kinetics/debug_test/fokker_planck_collisions_inputs.jl +++ b/moment_kinetics/debug_test/fokker_planck_collisions_inputs.jl @@ -13,10 +13,10 @@ test_input_full_f = OptionsDict( "T_e" => 1.0, "T_wall" => 1.0, "electron_physics" => "boltzmann_electron_response"), - "evolve_moments_conservation" => false, - "evolve_moments_density" => false, - "evolve_moments_parallel_flow" => false, - "evolve_moments_parallel_pressure" => false, + "evolve_moments" => OptionsDict("moments_conservation" => false, + "density" => false, + "parallel_flow" => false, + "parallel_pressure" => false), "ion_species_1" => OptionsDict("initial_density" => 0.5, "initial_temperature" => 1.0), "z_IC_ion_species_1" => OptionsDict("density_amplitude" => 0.001, diff --git a/moment_kinetics/debug_test/gyroaverage_inputs.jl b/moment_kinetics/debug_test/gyroaverage_inputs.jl index fe0543a80..854d58a4c 100644 --- a/moment_kinetics/debug_test/gyroaverage_inputs.jl +++ b/moment_kinetics/debug_test/gyroaverage_inputs.jl @@ -9,10 +9,10 @@ test_input = OptionsDict( "gyrokinetic_ions" => true, "T_e" => 1.0, "T_wall" => 1.0), - "evolve_moments_density" => false, - "evolve_moments_parallel_flow" => false, - "evolve_moments_parallel_pressure" => false, - "evolve_moments_conservation" => false, + "evolve_moments" => OptionsDict("density" => false, + "parallel_flow" => false, + "parallel_pressure" => false, + "moments_conservation" => false), "ion_species_1" => OptionsDict("initial_density" => 1.0, "initial_temperature" => 1.0), "z_IC_ion_species_1" => OptionsDict("initialization_option" => "gaussian", diff --git a/moment_kinetics/debug_test/kinetic_electron_inputs.jl b/moment_kinetics/debug_test/kinetic_electron_inputs.jl index 2ceb7eee2..913209d21 100644 --- a/moment_kinetics/debug_test/kinetic_electron_inputs.jl +++ b/moment_kinetics/debug_test/kinetic_electron_inputs.jl @@ -9,10 +9,10 @@ test_input = OptionsDict("composition" => OptionsDict("n_ion_species" => 1, "T_wall" => 0.1), "run_name" => "kinetic_electron", "base_directory" => test_output_directory, - "evolve_moments_density" => true, - "evolve_moments_parallel_flow" => true, - "evolve_moments_parallel_pressure" => true, - "evolve_moments_conservation" => true, + "evolve_moments" => OptionsDict("density" => true, + "parallel_flow" => true, + "parallel_pressure" => true, + "moments_conservation" => true), "ion_species_1" => OptionsDict("initial_density" => 1.0, "initial_temperature" => 1.0), "z_IC_ion_species_1" => OptionsDict("initialization_option" => "gaussian", diff --git a/moment_kinetics/debug_test/mms_inputs.jl b/moment_kinetics/debug_test/mms_inputs.jl index e9ca8a483..204d822a1 100644 --- a/moment_kinetics/debug_test/mms_inputs.jl +++ b/moment_kinetics/debug_test/mms_inputs.jl @@ -4,10 +4,10 @@ test_type = "MMS" # default inputs for tests test_input = OptionsDict( "manufactured_solns" => OptionsDict("use_for_advance"=>true), - "evolve_moments_density" => false, - "evolve_moments_parallel_flow" => false, - "evolve_moments_parallel_pressure" => false, - "evolve_moments_conservation" => false, + "evolve_moments" => OptionsDict("density" => false, + "parallel_flow" => false, + "parallel_pressure" => false, + "moments_conservation" => false), "composition" => OptionsDict("n_ion_species" => 1, "n_neutral_species" => 1, "electron_physics" => "boltzmann_electron_response", diff --git a/moment_kinetics/debug_test/recycling_fraction_inputs.jl b/moment_kinetics/debug_test/recycling_fraction_inputs.jl index ab519c68b..5834e9150 100644 --- a/moment_kinetics/debug_test/recycling_fraction_inputs.jl +++ b/moment_kinetics/debug_test/recycling_fraction_inputs.jl @@ -12,10 +12,10 @@ test_input = OptionsDict("composition" => OptionsDict("n_ion_species" => 1, "initial_temperature" => 1.0), "run_name" => "full-f", "base_directory" => test_output_directory, - "evolve_moments_density" => false, - "evolve_moments_parallel_flow" => false, - "evolve_moments_parallel_pressure" => false, - "evolve_moments_conservation" => false, + "evolve_moments" => OptionsDict("density" => false, + "parallel_flow" => false, + "parallel_pressure" => false, + "moments_conservation" => false), "krook_collisions" => OptionsDict("use_krook" => true), "z_IC_ion_species_1" => OptionsDict("density_amplitude" => 0.001, "density_phase" => 0.0, @@ -82,25 +82,25 @@ test_input = OptionsDict("composition" => OptionsDict("n_ion_species" => 1, "source_T" => 2.0)) -test_input_split1 = merge(test_input, - OptionsDict("run_name" => "split1", - "evolve_moments_density" => true, - "evolve_moments_conservation" => true)) -test_input_split2 = merge(test_input_split1, - OptionsDict("run_name" => "split2", - "evolve_moments_parallel_flow" => true)) -test_input_split2["timestepping"] = merge(test_input_split2["timestepping"], - OptionsDict("step_update_prefactor" => 0.4)) +test_input_split1 = recursive_merge(test_input, + OptionsDict("run_name" => "split1", + "evolve_moments" => OptionsDict("density" => true, + "moments_conservation" => true))) +test_input_split2 = recursive_merge(test_input_split1, + OptionsDict("run_name" => "split2", + "evolve_moments" => OptionsDict("parallel_flow" => true))) +test_input_split2["timestepping"] = recursive_merge(test_input_split2["timestepping"], + OptionsDict("step_update_prefactor" => 0.4)) test_input_split3 = recursive_merge(test_input_split2, OptionsDict("run_name" => "split3", - "evolve_moments_parallel_pressure" => true, + "evolve_moments" => OptionsDict("parallel_pressure" => true), "vpa" => OptionsDict("nelement" => 8), "vz" => OptionsDict("nelement" => 8), "numerical_dissipation" => OptionsDict("force_minimum_pdf_value" => 0.0, "vpa_dissipation_coefficient" => 1e-2))) -test_input_split3["timestepping"] = merge(test_input_split3["timestepping"], - OptionsDict("dt" => 1.0e-9, - "minimum_dt" => 1.0e-9)) +test_input_split3["timestepping"] = recursive_merge(test_input_split3["timestepping"], + OptionsDict("dt" => 1.0e-9, + "minimum_dt" => 1.0e-9)) test_input_list = [ diff --git a/moment_kinetics/debug_test/restart_interpolation_inputs.jl b/moment_kinetics/debug_test/restart_interpolation_inputs.jl index 45e725c82..fe74867e5 100644 --- a/moment_kinetics/debug_test/restart_interpolation_inputs.jl +++ b/moment_kinetics/debug_test/restart_interpolation_inputs.jl @@ -10,10 +10,10 @@ base_input = OptionsDict( "electron_physics" => "boltzmann_electron_response", "T_e" => 1.0), "base_directory" => test_output_directory, - "evolve_moments_density" => false, - "evolve_moments_parallel_flow" => false, - "evolve_moments_parallel_pressure" => false, - "evolve_moments_conservation" => true, + "evolve_moments" => OptionsDict("density" => false, + "parallel_flow" => false, + "parallel_pressure" => false, + "moments_conservation" => true), "charge_exchange_frequency" => 2*π*0.1, "ionization_frequency" => 0.0, "timestepping" => OptionsDict("nstep" => 3, @@ -54,19 +54,19 @@ test_input = "vz" => OptionsDict("nelement" => 3))) test_input_split1 = - merge(test_input, - OptionsDict("run_name" => "split1", - "evolve_moments_density" => true)) + recursive_merge(test_input, + OptionsDict("run_name" => "split1", + "evolve_moments" => OptionsDict("density" => true))) -test_input_split2 = - merge(test_input_split1 , - OptionsDict("run_name" => "split2", - "evolve_moments_parallel_flow" => true)) + test_input_split2 = + recursive_merge(test_input_split1 , + OptionsDict("run_name" => "split2", + "evolve_moments" => OptionsDict("parallel_flow" => true))) -test_input_split3 = - merge(test_input_split2, - OptionsDict("run_name" => "split3", - "evolve_moments_parallel_pressure" => true)) + test_input_split3 = + recursive_merge(test_input_split2, + OptionsDict("run_name" => "split3", + "evolve_moments" => OptionsDict("parallel_pressure" => true))) test_input_list = [ test_input, diff --git a/moment_kinetics/debug_test/sound_wave_inputs.jl b/moment_kinetics/debug_test/sound_wave_inputs.jl index a94c4a6ce..087adbb00 100644 --- a/moment_kinetics/debug_test/sound_wave_inputs.jl +++ b/moment_kinetics/debug_test/sound_wave_inputs.jl @@ -1,5 +1,6 @@ test_type = "sound_wave" using moment_kinetics.type_definitions: OptionsDict +using moment_kinetics.utils: recursive_merge # default inputs for tests test_input_finite_difference_1D1V = OptionsDict("run_name" => "finite_difference_1D1V", @@ -8,10 +9,10 @@ test_input_finite_difference_1D1V = OptionsDict("run_name" => "finite_difference "electron_physics" => "boltzmann_electron_response", "T_e" => 1.0), "base_directory" => test_output_directory, - "evolve_moments_density" => false, - "evolve_moments_parallel_flow" => false, - "evolve_moments_parallel_pressure" => false, - "evolve_moments_conservation" => true, + "evolve_moments" => OptionsDict("density" => false, + "parallel_flow" => false, + "parallel_pressure" => false, + "moments_conservation" => true), "charge_exchange_frequency" => 2*π*0.1, "ionization_frequency" => 0.0, "timestepping" => OptionsDict("nstep" => 3, @@ -44,203 +45,204 @@ test_input_finite_difference_1D1V = OptionsDict("run_name" => "finite_difference ) test_input_finite_difference_1D1V_split_1_moment = - merge(test_input_finite_difference_1D1V, - OptionsDict("run_name" => "finite_difference_1D1V_split_1_moment", - "evolve_moments_density" => true)) +recursive_merge(test_input_finite_difference_1D1V, + OptionsDict("run_name" => "finite_difference_1D1V_split_1_moment", + "evolve_moments" => OptionsDict("density" => true))) test_input_finite_difference_1D1V_split_2_moments = - merge(test_input_finite_difference_1D1V_split_1_moment, - OptionsDict("run_name" => "finite_difference_1D1V_split_2_moments", - "evolve_moments_parallel_flow" => true)) +recursive_merge(test_input_finite_difference_1D1V_split_1_moment, + OptionsDict("run_name" => "finite_difference_1D1V_split_2_moments", + "evolve_moments" => OptionsDict("parallel_flow" => true))) test_input_finite_difference_1D1V_split_3_moments = - merge(test_input_finite_difference_1D1V_split_2_moments, - OptionsDict("run_name" => "finite_difference_1D1V_split_3_moments", - "evolve_moments_parallel_pressure" => true)) +recursive_merge(test_input_finite_difference_1D1V_split_2_moments, + OptionsDict("run_name" => "finite_difference_1D1V_split_3_moments", + "evolve_moments" => OptionsDict("parallel_pressure" => true))) test_input_finite_difference_cx0_1D1V = - merge(test_input_finite_difference_1D1V, - OptionsDict("run_name" => "finite_difference_cx0_1D1V", - "charge_exchange_frequency" => 0.0)) +recursive_merge(test_input_finite_difference_1D1V, + OptionsDict("run_name" => "finite_difference_cx0_1D1V", + "charge_exchange_frequency" => 0.0)) test_input_finite_difference_cx0_1D1V_split_1_moment = - merge(test_input_finite_difference_cx0_1D1V, - OptionsDict("run_name" => "finite_difference_cx0_1D1V_split_1_moment", - "evolve_moments_density" => true)) +recursive_merge(test_input_finite_difference_cx0_1D1V, + OptionsDict("run_name" => "finite_difference_cx0_1D1V_split_1_moment", + "evolve_moments" => OptionsDict("density" => true))) test_input_finite_difference_cx0_1D1V_split_2_moments = - merge(test_input_finite_difference_cx0_1D1V_split_1_moment, - OptionsDict("run_name" => "finite_difference_cx0_1D1V_split_2_moments", - "evolve_moments_parallel_flow" => true)) +recursive_merge(test_input_finite_difference_cx0_1D1V_split_1_moment, + OptionsDict("run_name" => "finite_difference_cx0_1D1V_split_2_moments", + "evolve_moments" => OptionsDict("parallel_flow" => true))) test_input_finite_difference_cx0_1D1V_split_3_moments = - merge(test_input_finite_difference_cx0_1D1V_split_2_moments, - OptionsDict("run_name" => "finite_difference_cx0_1D1V_split_3_moments", - "evolve_moments_parallel_pressure" => true)) +recursive_merge(test_input_finite_difference_cx0_1D1V_split_2_moments, + OptionsDict("run_name" => "finite_difference_cx0_1D1V_split_3_moments", + "evolve_moments" => OptionsDict("parallel_pressure" => true))) test_input_finite_difference = - merge(test_input_finite_difference_1D1V, - OptionsDict("run_name" => "finite_difference", - "r" => OptionsDict("ngrid" => 4, - "nelement" => 1, - "discretization" => "finite_difference"), - "vperp" => OptionsDict("ngrid" => 4, - "nelement" => 1, - "discretization" => "finite_difference"), - "vz" => OptionsDict("ngrid" => 4, - "nelement" => 1, - "discretization" => "finite_difference"), - "vr" => OptionsDict("ngrid" => 4, - "nelement" => 1, - "discretization" => "finite_difference"), - "vzeta" => OptionsDict("ngrid" => 4, - "nelement" => 1, - "discretization" => "finite_difference"), - )) +recursive_merge(test_input_finite_difference_1D1V, + OptionsDict("run_name" => "finite_difference", + "r" => OptionsDict("ngrid" => 4, + "nelement" => 1, + "discretization" => "finite_difference"), + "vperp" => OptionsDict("ngrid" => 4, + "nelement" => 1, + "discretization" => "finite_difference"), + "vz" => OptionsDict("ngrid" => 4, + "nelement" => 1, + "discretization" => "finite_difference"), + "vr" => OptionsDict("ngrid" => 4, + "nelement" => 1, + "discretization" => "finite_difference"), + "vzeta" => OptionsDict("ngrid" => 4, + "nelement" => 1, + "discretization" => "finite_difference"), + )) test_input_finite_difference_split_1_moment = - merge(test_input_finite_difference, - OptionsDict("run_name" => "finite_difference_split_1_moment", - "evolve_moments_density" => true)) +recursive_merge(test_input_finite_difference, + OptionsDict("run_name" => "finite_difference_split_1_moment", + "evolve_moments" => OptionsDict("density" => true))) test_input_finite_difference_split_2_moments = - merge(test_input_finite_difference_split_1_moment, - OptionsDict("run_name" => "finite_difference_split_2_moments", - "evolve_moments_parallel_flow" => true)) +recursive_merge(test_input_finite_difference_split_1_moment, + OptionsDict("run_name" => "finite_difference_split_2_moments", + "evolve_moments" => OptionsDict("parallel_flow" => true))) test_input_finite_difference_split_3_moments = - merge(test_input_finite_difference_split_2_moments, - OptionsDict("run_name" => "finite_difference_split_3_moments", - "evolve_moments_parallel_pressure" => true)) +recursive_merge(test_input_finite_difference_split_2_moments, + OptionsDict("run_name" => "finite_difference_split_3_moments", + "evolve_moments" => OptionsDict("parallel_pressure" => true))) test_input_finite_difference_cx0 = - merge(test_input_finite_difference, - OptionsDict("run_name" => "finite_difference_cx0", - "charge_exchange_frequency" => 0.0)) +recursive_merge(test_input_finite_difference, + OptionsDict("run_name" => "finite_difference_cx0", + "charge_exchange_frequency" => 0.0)) test_input_finite_difference_cx0_split_1_moment = - merge(test_input_finite_difference_cx0, - OptionsDict("run_name" => "finite_difference_cx0_split_1_moment", - "evolve_moments_density" => true)) +recursive_merge(test_input_finite_difference_cx0, + OptionsDict("run_name" => "finite_difference_cx0_split_1_moment", + "evolve_moments" => OptionsDict("density" => true))) test_input_finite_difference_cx0_split_2_moments = - merge(test_input_finite_difference_cx0_split_1_moment, - OptionsDict("run_name" => "finite_difference_cx0_split_2_moments", - "evolve_moments_parallel_flow" => true)) +recursive_merge(test_input_finite_difference_cx0_split_1_moment, + OptionsDict("run_name" => "finite_difference_cx0_split_2_moments", + "evolve_moments" => OptionsDict("parallel_flow" => true))) test_input_finite_difference_cx0_split_3_moments = - merge(test_input_finite_difference_cx0_split_2_moments, - OptionsDict("run_name" => "finite_difference_cx0_split_3_moments", - "evolve_moments_parallel_pressure" => true)) - -test_input_chebyshev = merge(test_input_finite_difference, - OptionsDict("run_name" => "chebyshev_pseudospectral", - "r" => OptionsDict("discretization" => "chebyshev_pseudospectral", - "ngrid" => 3, - "nelement" => 1), - "z" => OptionsDict("discretization" => "chebyshev_pseudospectral", - "ngrid" => 3, - "nelement" => 2), - "vperp" => OptionsDict("discretization" => "chebyshev_pseudospectral", - "ngrid" => 3, - "nelement" => 1), - "vpa" => OptionsDict("discretization" => "chebyshev_pseudospectral", - "ngrid" => 3, - "nelement" => 2), - "vz" => OptionsDict("discretization" => "chebyshev_pseudospectral", - "ngrid" => 3, - "nelement" => 2), - "vr" => OptionsDict("discretization" => "chebyshev_pseudospectral", - "ngrid" => 3, - "nelement" => 1), - "vzeta" => OptionsDict("discretization" => "chebyshev_pseudospectral", - "ngrid" => 3, - "nelement" => 1), - )) +recursive_merge(test_input_finite_difference_cx0_split_2_moments, + OptionsDict("run_name" => "finite_difference_cx0_split_3_moments", + "evolve_moments" => OptionsDict("parallel_pressure" => true))) + +test_input_chebyshev = recursive_merge(test_input_finite_difference, + OptionsDict("run_name" => "chebyshev_pseudospectral", + "r" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 3, + "nelement" => 1), + "z" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 3, + "nelement" => 2), + "vperp" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 3, + "nelement" => 1), + "vpa" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 3, + "nelement" => 2), + "vz" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 3, + "nelement" => 2), + "vr" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 3, + "nelement" => 1), + "vzeta" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 3, + "nelement" => 1), + )) test_input_chebyshev_split_1_moment = - merge(test_input_chebyshev, - OptionsDict("run_name" => "chebyshev_pseudospectral_split_1_moment", - "evolve_moments_density" => true)) +recursive_merge(test_input_chebyshev, + OptionsDict("run_name" => "chebyshev_pseudospectral_split_1_moment", + "evolve_moments" => OptionsDict("density" => true))) test_input_chebyshev_split_2_moments = - merge(test_input_chebyshev_split_1_moment, - OptionsDict("run_name" => "chebyshev_pseudospectral_split_2_moments", - "evolve_moments_parallel_flow" => true)) +recursive_merge(test_input_chebyshev_split_1_moment, + OptionsDict("run_name" => "chebyshev_pseudospectral_split_2_moments", + "evolve_moments" => OptionsDict("parallel_flow" => true))) test_input_chebyshev_split_3_moments = - merge(test_input_chebyshev_split_2_moments, - OptionsDict("run_name" => "chebyshev_pseudospectral_split_3_moments", - "evolve_moments_parallel_pressure" => true)) +recursive_merge(test_input_chebyshev_split_2_moments, + OptionsDict("run_name" => "chebyshev_pseudospectral_split_3_moments", + "evolve_moments" => OptionsDict("parallel_pressure" => true))) test_input_chebyshev_cx0 = - merge(test_input_chebyshev, - OptionsDict("run_name" => "chebyshev_pseudospectral_cx0", - "charge_exchange_frequency" => 0.0)) +recursive_merge(test_input_chebyshev, + OptionsDict("run_name" => "chebyshev_pseudospectral_cx0", + "charge_exchange_frequency" => 0.0)) test_input_chebyshev_cx0_split_1_moment = - merge(test_input_chebyshev_cx0, - OptionsDict("run_name" => "chebyshev_pseudospectral_cx0_split_1_moment", - "evolve_moments_density" => true)) +recursive_merge(test_input_chebyshev_cx0, + OptionsDict("run_name" => "chebyshev_pseudospectral_cx0_split_1_moment", + "evolve_moments" => OptionsDict("density" => true))) test_input_chebyshev_cx0_split_2_moments = - merge(test_input_chebyshev_cx0_split_1_moment, - OptionsDict("run_name" => "chebyshev_pseudospectral_cx0_split_2_moments", - "evolve_moments_parallel_flow" => true)) +recursive_merge(test_input_chebyshev_cx0_split_1_moment, + OptionsDict("run_name" => "chebyshev_pseudospectral_cx0_split_2_moments", + "evolve_moments" => OptionsDict("parallel_flow" => true))) test_input_chebyshev_cx0_split_3_moments = - merge(test_input_chebyshev_cx0_split_2_moments, - OptionsDict("run_name" => "chebyshev_pseudospectral_cx0_split_3_moments", - "evolve_moments_parallel_pressure" => true)) +recursive_merge(test_input_chebyshev_cx0_split_2_moments, + OptionsDict("run_name" => "chebyshev_pseudospectral_cx0_split_3_moments", + "evolve_moments" => OptionsDict("parallel_pressure" => true))) test_input_chebyshev_1D1V = - merge(test_input_finite_difference_1D1V, - OptionsDict("run_name" => "chebyshev_pseudospectral_1D1V", - "z" => OptionsDict("discretization" => "chebyshev_pseudospectral", - "ngrid" => 3, - "nelement" => 2), - "vpa" => OptionsDict("discretization" => "chebyshev_pseudospectral", - "ngrid" => 3, - "nelement" => 2), - "vz" => OptionsDict("discretization" => "chebyshev_pseudospectral", - "ngrid" => 3, - "nelement" => 2), - )) +recursive_merge(test_input_finite_difference_1D1V, + OptionsDict("run_name" => "chebyshev_pseudospectral_1D1V", + "z" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 3, + "nelement" => 2), + "vpa" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 3, + "nelement" => 2), + "vz" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 3, + "nelement" => 2), + )) test_input_chebyshev_1D1V_split_1_moment = - merge(test_input_chebyshev_1D1V, - OptionsDict("run_name" => "chebyshev_pseudospectral_1D1V_split_1_moment", - "evolve_moments_density" => true)) +recursive_merge(test_input_chebyshev_1D1V, + OptionsDict("run_name" => "chebyshev_pseudospectral_1D1V_split_1_moment", + "evolve_moments" => OptionsDict("density" => true))) test_input_chebyshev_1D1V_split_2_moments = - merge(test_input_chebyshev_1D1V_split_1_moment, - OptionsDict("run_name" => "chebyshev_pseudospectral_1D1V_split_2_moments", - "evolve_moments_parallel_flow" => true)) +recursive_merge(test_input_chebyshev_1D1V_split_1_moment, + OptionsDict("run_name" => "chebyshev_pseudospectral_1D1V_split_2_moments", + "evolve_moments" => OptionsDict("parallel_flow" => true))) test_input_chebyshev_1D1V_split_3_moments = - merge(test_input_chebyshev_1D1V_split_2_moments, - OptionsDict("run_name" => "chebyshev_pseudospectral_1D1V_split_3_moments", - "evolve_moments_parallel_pressure" => true, "runtime_plots" => true)) +recursive_merge(test_input_chebyshev_1D1V_split_2_moments, + OptionsDict("run_name" => "chebyshev_pseudospectral_1D1V_split_3_moments", + "evolve_moments" => OptionsDict("parallel_pressure" => true), + "runtime_plots" => true)) test_input_chebyshev_cx0_1D1V = - merge(test_input_chebyshev_1D1V, - OptionsDict("run_name" => "chebyshev_pseudospectral_cx0_1D1V", - "charge_exchange_frequency" => 0.0)) +recursive_merge(test_input_chebyshev_1D1V, + OptionsDict("run_name" => "chebyshev_pseudospectral_cx0_1D1V", + "charge_exchange_frequency" => 0.0)) test_input_chebyshev_cx0_1D1V_split_1_moment = - merge(test_input_chebyshev_cx0_1D1V, - OptionsDict("run_name" => "chebyshev_pseudospectral_cx0_1D1V_split_1_moment", - "evolve_moments_density" => true)) +recursive_merge(test_input_chebyshev_cx0_1D1V, + OptionsDict("run_name" => "chebyshev_pseudospectral_cx0_1D1V_split_1_moment", + "evolve_moments" => OptionsDict("density" => true))) test_input_chebyshev_cx0_1D1V_split_2_moments = - merge(test_input_chebyshev_cx0_1D1V_split_1_moment, - OptionsDict("run_name" => "chebyshev_pseudospectral_cx0_1D1V_split_2_moments", - "evolve_moments_parallel_flow" => true)) +recursive_merge(test_input_chebyshev_cx0_1D1V_split_1_moment, + OptionsDict("run_name" => "chebyshev_pseudospectral_cx0_1D1V_split_2_moments", + "evolve_moments" => OptionsDict("parallel_flow" => true))) test_input_chebyshev_cx0_1D1V_split_3_moments = - merge(test_input_chebyshev_cx0_1D1V_split_2_moments, - OptionsDict("run_name" => "chebyshev_pseudospectral_cx0_1D1V_split_3_moments", - "evolve_moments_parallel_pressure" => true)) +recursive_merge(test_input_chebyshev_cx0_1D1V_split_2_moments, + OptionsDict("run_name" => "chebyshev_pseudospectral_cx0_1D1V_split_3_moments", + "evolve_moments" => OptionsDict("parallel_pressure" => true))) test_input_list = [ test_input_finite_difference, diff --git a/moment_kinetics/debug_test/wall_bc_inputs.jl b/moment_kinetics/debug_test/wall_bc_inputs.jl index c7b109ec7..8038f327d 100644 --- a/moment_kinetics/debug_test/wall_bc_inputs.jl +++ b/moment_kinetics/debug_test/wall_bc_inputs.jl @@ -11,10 +11,10 @@ test_input_finite_difference_1D1V = OptionsDict( "T_e" => 1.0, "T_wall" => 1.0), "base_directory" => test_output_directory, - "evolve_moments_density" => false, - "evolve_moments_parallel_flow" => false, - "evolve_moments_parallel_pressure" => false, - "evolve_moments_conservation" => true, + "evolve_moments" => OptionsDict("density" => false, + "parallel_flow" => false, + "parallel_pressure" => false, + "moments_conservation" => true), "charge_exchange_frequency" => 2.0, "ionization_frequency" => 2.0, "constant_ionization_rate" => false, @@ -91,17 +91,17 @@ test_input_chebyshev_1D1V = recursive_merge( "nelement" => 2), )) -test_input_chebyshev_split1_1D1V = merge(test_input_chebyshev_1D1V, - OptionsDict("run_name" => "chebyshev_pseudospectral_split1_1D1V", - "evolve_moments_density" => true)) +test_input_chebyshev_split1_1D1V = recursive_merge(test_input_chebyshev_1D1V, + OptionsDict("run_name" => "chebyshev_pseudospectral_split1_1D1V", + "evolve_moments" => OptionsDict("density" => true))) -test_input_chebyshev_split2_1D1V = merge(test_input_chebyshev_split1_1D1V, - OptionsDict("run_name" => "chebyshev_pseudospectral_split2_1D1V", - "evolve_moments_parallel_flow" => true)) +test_input_chebyshev_split2_1D1V = recursive_merge(test_input_chebyshev_split1_1D1V, + OptionsDict("run_name" => "chebyshev_pseudospectral_split2_1D1V", + "evolve_moments" => OptionsDict("parallel_flow" => true))) -test_input_chebyshev_split3_1D1V = merge(test_input_chebyshev_split2_1D1V, - OptionsDict("run_name" => "chebyshev_pseudospectral_split3_1D1V", - "evolve_moments_parallel_pressure" => true)) +test_input_chebyshev_split3_1D1V = recursive_merge(test_input_chebyshev_split2_1D1V, + OptionsDict("run_name" => "chebyshev_pseudospectral_split3_1D1V", + "evolve_moments" => OptionsDict("parallel_pressure" => true))) test_input_chebyshev_simple_sheath_1D1V = recursive_merge( diff --git a/moment_kinetics/src/initial_conditions.jl b/moment_kinetics/src/initial_conditions.jl index 8d7db7598..d8bc62900 100644 --- a/moment_kinetics/src/initial_conditions.jl +++ b/moment_kinetics/src/initial_conditions.jl @@ -85,7 +85,7 @@ function allocate_pdf_and_moments(composition, r, z, vperp, vpa, vzeta, vr, vz, moments = moments_struct(ion, electron, neutral, evolve_moments.density, particle_number_conserved, - evolve_moments.conservation, + evolve_moments.moments_conservation, evolve_moments.parallel_flow, evolve_moments.parallel_pressure) diff --git a/moment_kinetics/src/input_structs.jl b/moment_kinetics/src/input_structs.jl index ddaf3960d..5bec6cee3 100644 --- a/moment_kinetics/src/input_structs.jl +++ b/moment_kinetics/src/input_structs.jl @@ -3,7 +3,6 @@ module input_structs export advance_info -export evolve_moments_options export time_info export advection_input export initial_condition_input, initial_condition_input_mutable @@ -23,16 +22,6 @@ using ..type_definitions: mk_float, mk_int using MPI using TOML -""" -""" -mutable struct evolve_moments_options - density::Bool - parallel_flow::Bool - parallel_pressure::Bool - conservation::Bool - #advective_form::Bool -end - """ `t_error_sum` is included so that a type which might be mk_float or Float128 can be set by an option but known at compile time when a `time_info` struct is passed as a function diff --git a/moment_kinetics/src/moment_kinetics_input.jl b/moment_kinetics/src/moment_kinetics_input.jl index e264ba357..ff22b3182 100644 --- a/moment_kinetics/src/moment_kinetics_input.jl +++ b/moment_kinetics/src/moment_kinetics_input.jl @@ -67,13 +67,17 @@ function mk_input(scan_input=OptionsDict(); save_inputs_to_txt=false, ignore_MPI "finite_difference_option", "element_spacing_option", "bc") )..., - "force_Er_zero_at_wall", + "force_Er_zero_at_wall", "evolve_moments_density", + "evolve_moments_parallel_flow", + "evolve_moments_parallel_pressure", + "evolve_moments_conservation", ) 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.") + error("Option '$opt' is no longer used. Please update your input file. The " + * "option may have been moved into an input file section. You may need " + * "to set some new options to replicate the effect of the removed ones." + ) end end @@ -82,8 +86,6 @@ function mk_input(scan_input=OptionsDict(); save_inputs_to_txt=false, ignore_MPI n_ion_species = composition.n_ion_species n_neutral_species = composition.n_neutral_species - evolve_moments = load_defaults() - # this is the prefix for all output files associated with this run run_name = get(scan_input, "run_name", "wallBC") # this is the directory where the simulation data will be stored @@ -92,10 +94,14 @@ function mk_input(scan_input=OptionsDict(); save_inputs_to_txt=false, ignore_MPI # if evolve_moments.density = true, evolve density via continuity eqn # and g = f/n via modified drift kinetic equation - evolve_moments.density = get(scan_input, "evolve_moments_density", false) - evolve_moments.parallel_flow = get(scan_input, "evolve_moments_parallel_flow", false) - evolve_moments.parallel_pressure = get(scan_input, "evolve_moments_parallel_pressure", false) - evolve_moments.conservation = get(scan_input, "evolve_moments_conservation", false) + evolve_moments_settings = set_defaults_and_check_section!( + scan_input, "evolve_moments"; + density=false, + parallel_flow=false, + parallel_pressure=false, + moments_conservation=false, + ) + evolve_moments = Dict_to_NamedTuple(evolve_moments_settings) # Reference parameters that define the conversion between physical quantities and # normalised values used in the code. @@ -479,21 +485,6 @@ function mk_input(scan_input=OptionsDict(); save_inputs_to_txt=false, ignore_MPI return all_inputs end -""" -""" -function load_defaults() - ############## options related to the equations being solved ############### - evolve_density = false - evolve_parallel_flow = false - evolve_parallel_pressure = false - conservation = true - #advective_form = false - evolve_moments = evolve_moments_options(evolve_density, evolve_parallel_flow, evolve_parallel_pressure, conservation)#advective_form) - #################### parameters related to the z grid ###################### - - return evolve_moments -end - """ check various input options to ensure they are all valid/consistent """ @@ -511,9 +502,8 @@ function check_input(io, output_dir, nstep, dt, r, z, vpa, vperp, composition, s check_coordinate_input(vperp, "vperp", io) # if the parallel flow is evolved separately, then the density must also be evolved separately if evolve_moments.parallel_flow && !evolve_moments.density - print(io,">evolve_moments.parallel_flow = true, but evolve_moments.density = false.") - println(io, "this is not a supported option. forcing evolve_moments.density = true.") - evolve_moments.density = true + error("evolve_moments.parallel_flow = true, but evolve_moments.density = false." + * "this is not a supported option.") end if collisions.fkpl.nuii > 0.0 # check that the grids support the collision operator diff --git a/moment_kinetics/test/Krook_collisions_tests.jl b/moment_kinetics/test/Krook_collisions_tests.jl index b4991f8d7..98becafab 100644 --- a/moment_kinetics/test/Krook_collisions_tests.jl +++ b/moment_kinetics/test/Krook_collisions_tests.jl @@ -108,10 +108,10 @@ test_input_full_f = OptionsDict("composition" => OptionsDict("n_ion_species" => "temperature_amplitude" => 0.5, "temperature_phase" => 0.0), "run_name" => "full_f", - "evolve_moments_density" => false, - "evolve_moments_parallel_flow" => false, - "evolve_moments_parallel_pressure" => false, - "evolve_moments_conservation" => true, + "evolve_moments" => OptionsDict("density" => false, + "parallel_flow" => false, + "parallel_pressure" => false, + "moments_conservation" => true), "krook_collisions" => OptionsDict("use_krook" => true,"frequency_option" => "reference_parameters"), "charge_exchange_frequency" => 2*π*0.1, "ionization_frequency" => 0.0, @@ -142,18 +142,18 @@ test_input_full_f = OptionsDict("composition" => OptionsDict("n_ion_species" => test_input_split_1_moment = recursive_merge(test_input_full_f, - OptionsDict("run_name" => "split_1_moment", - "evolve_moments_density" => true)) + OptionsDict("run_name" => "split_1_moment", + "evolve_moments" => OptionsDict("density" => true))) test_input_split_2_moments = recursive_merge(test_input_split_1_moment, - OptionsDict("run_name" => "split_2_moments", - "evolve_moments_parallel_flow" => true)) + OptionsDict("run_name" => "split_2_moments", + "evolve_moments" => OptionsDict("parallel_flow" => true))) test_input_split_3_moments = recursive_merge(test_input_split_2_moments, OptionsDict("run_name" => "split_3_moments", - "evolve_moments_parallel_pressure" => true, + "evolve_moments" => OptionsDict("parallel_pressure" => true), "vpa" => OptionsDict("L" => 12.0), "vz" => OptionsDict("L" => 12.0), )) @@ -256,7 +256,7 @@ function run_test(test_input, rtol, atol; args...) f_neutral = f_neutral_vzvrvzetazrst[:,1,1,:,1,:,:] # Unnormalize f - if input["evolve_moments_density"] + if input["evolve_moments"]["density"] for it ∈ 1:length(time), is ∈ 1:n_ion_species, iz ∈ 1:z.n f_ion[:,iz,is,it] .*= n_ion[iz,is,it] end @@ -264,7 +264,7 @@ function run_test(test_input, rtol, atol; args...) f_neutral[:,iz,isn,it] .*= n_neutral[iz,isn,it] end end - if input["evolve_moments_parallel_pressure"] + if input["evolve_moments"]["parallel_pressure"] for it ∈ 1:length(time), is ∈ 1:n_ion_species, iz ∈ 1:z.n f_ion[:,iz,is,it] ./= v_t_ion[iz,is,it] end @@ -358,10 +358,10 @@ function run_test(test_input, rtol, atol; args...) size(newgrid_f_ion, 4)) for iz ∈ 1:length(expected.z) wpa = copy(expected.vpa) - if input["evolve_moments_parallel_flow"] + if input["evolve_moments"]["parallel_flow"] wpa .-= newgrid_upar_ion[iz,1] end - if input["evolve_moments_parallel_pressure"] + if input["evolve_moments"]["parallel_pressure"] wpa ./= newgrid_vth_ion[iz,1] end newgrid_f_ion[:,iz,1] = interpolate_to_grid_vpa(wpa, temp[:,iz,1], vpa, vpa_spectral) @@ -389,10 +389,10 @@ function run_test(test_input, rtol, atol; args...) size(newgrid_f_neutral, 4)) for iz ∈ 1:length(expected.z) wpa = copy(expected.vpa) - if input["evolve_moments_parallel_flow"] + if input["evolve_moments"]["parallel_flow"] wpa .-= newgrid_upar_neutral[iz,1] end - if input["evolve_moments_parallel_pressure"] + if input["evolve_moments"]["parallel_pressure"] wpa ./= newgrid_vth_neutral[iz,1] end newgrid_f_neutral[:,iz,1] = interpolate_to_grid_vpa(wpa, temp[:,iz,1], vpa, vpa_spectral) diff --git a/moment_kinetics/test/braginskii_electrons_imex_tests.jl b/moment_kinetics/test/braginskii_electrons_imex_tests.jl index d23484000..e6381e535 100644 --- a/moment_kinetics/test/braginskii_electrons_imex_tests.jl +++ b/moment_kinetics/test/braginskii_electrons_imex_tests.jl @@ -19,10 +19,10 @@ test_input = OptionsDict( "composition" => OptionsDict("n_ion_species" => 1, "electron_physics" => "braginskii_fluid", "T_e" => 0.2), "run_name" => "braginskii-electrons-imex", - "evolve_moments_density" => true, - "evolve_moments_parallel_flow" => true, - "evolve_moments_parallel_pressure" => true, - "evolve_moments_conservation" => true, + "evolve_moments" => OptionsDict("density" => true, + "parallel_flow" => true, + "parallel_pressure" => true, + "moments_conservation" => true), "ion_species_1" => OptionsDict("initial_density" => 1.0, "initial_temperature" => 1.0), "z_IC_ion_species_1" => OptionsDict("initialization_option" => "sinusoid", diff --git a/moment_kinetics/test/fokker_planck_time_evolution_tests.jl b/moment_kinetics/test/fokker_planck_time_evolution_tests.jl index 981d1e228..dfab25dd0 100644 --- a/moment_kinetics/test/fokker_planck_time_evolution_tests.jl +++ b/moment_kinetics/test/fokker_planck_time_evolution_tests.jl @@ -250,10 +250,10 @@ test_input_gauss_legendre = OptionsDict("run_name" => "gausslegendre_pseudospect "ionization_frequency" => 0.0, "charge_exchange_frequency" => 0.0, "fokker_planck_collisions" => OptionsDict("use_fokker_planck" => true, "nuii" => 1.0, "frequency_option" => "manual"), - "evolve_moments_parallel_pressure" => false, - "evolve_moments_conservation" => false, - "evolve_moments_parallel_flow" => false, - "evolve_moments_density" => false, + "evolve_moments" => OptionsDict("parallel_pressure" => false, + "moments_conservation" => false, + "parallel_flow" => false, + "density" => false), "z" => OptionsDict("discretization" => "chebyshev_pseudospectral", "ngrid" => 1, "nelement_local" => 1, diff --git a/moment_kinetics/test/harrisonthompson.jl b/moment_kinetics/test/harrisonthompson.jl index 3b0accfc5..b6272d16d 100644 --- a/moment_kinetics/test/harrisonthompson.jl +++ b/moment_kinetics/test/harrisonthompson.jl @@ -84,10 +84,10 @@ test_input_finite_difference = Dict("composition" => OptionsDict("n_ion_species" "temperature_amplitude" => 0.0, "temperature_phase" => 0.0), "run_name" => "finite_difference", - "evolve_moments_density" => false, - "evolve_moments_parallel_flow" => false, - "evolve_moments_parallel_pressure" => false, - "evolve_moments_conservation" => false, + "evolve_moments" => OptionsDict("density" => false, + "parallel_flow" => false, + "parallel_pressure" => false, + "moments_conservation" => false), "charge_exchange_frequency" => 0.0, "ionization_frequency" => 0.0, "constant_ionization_rate" => true, @@ -135,19 +135,19 @@ test_input_chebyshev = recursive_merge(test_input_finite_difference, test_input_chebyshev_split1 = recursive_merge(test_input_chebyshev, OptionsDict("run_name" => "chebyshev_pseudospectral_split1", - "evolve_moments_density" => true, - "evolve_moments_conservation" => true, + "evolve_moments" => OptionsDict("density" => true, + "moments_conservation" => true), )) test_input_chebyshev_split2 = recursive_merge(test_input_chebyshev_split1, OptionsDict("run_name" => "chebyshev_pseudospectral_split2", - "evolve_moments_parallel_flow" => true, + "evolve_moments" => OptionsDict("parallel_flow" => true), "ion_numerical_dissipation" => OptionsDict("force_minimum_pdf_value" => 0.0), )) test_input_chebyshev_split3 = recursive_merge(test_input_chebyshev_split2, OptionsDict("run_name" => "chebyshev_pseudospectral_split3", - "evolve_moments_parallel_pressure" => true, + "evolve_moments" => OptionsDict("parallel_pressure" => true), )) """ diff --git a/moment_kinetics/test/nonlinear_sound_wave_inputs_and_expected_data.jl b/moment_kinetics/test/nonlinear_sound_wave_inputs_and_expected_data.jl index f534a6020..597753279 100644 --- a/moment_kinetics/test/nonlinear_sound_wave_inputs_and_expected_data.jl +++ b/moment_kinetics/test/nonlinear_sound_wave_inputs_and_expected_data.jl @@ -105,10 +105,10 @@ test_input_finite_difference = OptionsDict("composition" => OptionsDict("n_ion_s "temperature_amplitude" => 0.5, "temperature_phase" => 0.0), "run_name" => "finite_difference", - "evolve_moments_density" => false, - "evolve_moments_parallel_flow" => false, - "evolve_moments_parallel_pressure" => false, - "evolve_moments_conservation" => true, + "evolve_moments" => OptionsDict("density" => false, + "parallel_flow" => false, + "parallel_pressure" => false, + "moments_conservation" => true), "charge_exchange_frequency" => 2*π*0.1, "ionization_frequency" => 0.0, "timestepping" => OptionsDict("nstep" => 100, @@ -139,17 +139,17 @@ test_input_finite_difference = OptionsDict("composition" => OptionsDict("n_ion_s test_input_finite_difference_split_1_moment = recursive_merge(test_input_finite_difference, OptionsDict("run_name" => "finite_difference_split_1_moment", - "evolve_moments_density" => true)) + "evolve_moments" => OptionsDict("density" => true))) test_input_finite_difference_split_2_moments = recursive_merge(test_input_finite_difference_split_1_moment, OptionsDict("run_name" => "finite_difference_split_2_moments", - "evolve_moments_parallel_flow" => true)) + "evolve_moments" => OptionsDict("parallel_flow" => true))) test_input_finite_difference_split_3_moments = recursive_merge(test_input_finite_difference_split_2_moments, OptionsDict("run_name" => "finite_difference_split_3_moments", - "evolve_moments_parallel_pressure" => true, + "evolve_moments" => OptionsDict("parallel_pressure" => true), "vpa" => OptionsDict("L" => 12.0), "vz" => OptionsDict("L" => 12.0), )) @@ -175,17 +175,17 @@ end test_input_chebyshev_split_1_moment = recursive_merge(test_input_chebyshev, OptionsDict("run_name" => "chebyshev_pseudospectral_split_1_moment", - "evolve_moments_density" => true)) + "evolve_moments" => OptionsDict("density" => true))) test_input_chebyshev_split_2_moments = recursive_merge(test_input_chebyshev_split_1_moment, OptionsDict("run_name" => "chebyshev_pseudospectral_split_2_moments", - "evolve_moments_parallel_flow" => true)) + "evolve_moments" => OptionsDict("parallel_flow" => true))) test_input_chebyshev_split_3_moments = recursive_merge(test_input_chebyshev_split_2_moments, OptionsDict("run_name" => "chebyshev_pseudospectral_split_3_moments", - "evolve_moments_parallel_pressure" => true, + "evolve_moments" => OptionsDict("parallel_pressure" => true), "vpa" => OptionsDict("L" => 12.0), "vz" => OptionsDict("L" => 12.0), )) diff --git a/moment_kinetics/test/nonlinear_sound_wave_tests.jl b/moment_kinetics/test/nonlinear_sound_wave_tests.jl index 8b53dcad5..1346e6a47 100644 --- a/moment_kinetics/test/nonlinear_sound_wave_tests.jl +++ b/moment_kinetics/test/nonlinear_sound_wave_tests.jl @@ -124,7 +124,7 @@ function run_test(test_input, rtol, atol, upar_rtol=nothing; args...) f_neutral = f_neutral_vzvrvzetazrst[:,1,1,:,1,:,:] # Unnormalize f - if input["evolve_moments_density"] + if input["evolve_moments"]["density"] for it ∈ 1:length(time), is ∈ 1:n_ion_species, iz ∈ 1:z.n f_ion[:,iz,is,it] .*= n_ion[iz,is,it] end @@ -132,7 +132,7 @@ function run_test(test_input, rtol, atol, upar_rtol=nothing; args...) f_neutral[:,iz,isn,it] .*= n_neutral[iz,isn,it] end end - if input["evolve_moments_parallel_pressure"] + if input["evolve_moments"]["parallel_pressure"] for it ∈ 1:length(time), is ∈ 1:n_ion_species, iz ∈ 1:z.n f_ion[:,iz,is,it] ./= v_t_ion[iz,is,it] end @@ -226,10 +226,10 @@ function run_test(test_input, rtol, atol, upar_rtol=nothing; args...) size(newgrid_f_ion, 4)) for iz ∈ 1:length(expected.z) wpa = copy(expected.vpa) - if input["evolve_moments_parallel_flow"] + if input["evolve_moments"]["parallel_flow"] wpa .-= newgrid_upar_ion[iz,1] end - if input["evolve_moments_parallel_pressure"] + if input["evolve_moments"]["parallel_pressure"] wpa ./= newgrid_vth_ion[iz,1] end newgrid_f_ion[:,iz,1] = interpolate_to_grid_vpa(wpa, temp[:,iz,1], vpa, vpa_spectral) @@ -257,10 +257,10 @@ function run_test(test_input, rtol, atol, upar_rtol=nothing; args...) size(newgrid_f_neutral, 4)) for iz ∈ 1:length(expected.z) wpa = copy(expected.vpa) - if input["evolve_moments_parallel_flow"] + if input["evolve_moments"]["parallel_flow"] wpa .-= newgrid_upar_neutral[iz,1] end - if input["evolve_moments_parallel_pressure"] + if input["evolve_moments"]["parallel_pressure"] wpa ./= newgrid_vth_neutral[iz,1] end newgrid_f_neutral[:,iz,1] = interpolate_to_grid_vpa(wpa, temp[:,iz,1], vpa, vpa_spectral) diff --git a/moment_kinetics/test/recycling_fraction_tests.jl b/moment_kinetics/test/recycling_fraction_tests.jl index ba6aead65..509c9135d 100644 --- a/moment_kinetics/test/recycling_fraction_tests.jl +++ b/moment_kinetics/test/recycling_fraction_tests.jl @@ -54,10 +54,10 @@ test_input = OptionsDict("composition" => OptionsDict("n_ion_species" => 1, "temperature_amplitude" => 0.0, "temperature_phase" => 0.0), "run_name" => "full-f", - "evolve_moments_density" => false, - "evolve_moments_parallel_flow" => false, - "evolve_moments_parallel_pressure" => false, - "evolve_moments_conservation" => false, + "evolve_moments" => OptionsDict("density" => false, + "parallel_flow" => false, + "parallel_pressure" => false, + "moments_conservation" => false), "charge_exchange_frequency" => 0.75, "ionization_frequency" => 0.5, "constant_ionization_rate" => false, @@ -98,17 +98,17 @@ end test_input_split1 = recursive_merge(test_input, OptionsDict("run_name" => "split1", - "evolve_moments_density" => true, - "evolve_moments_conservation" => true)) + "evolve_moments" => OptionsDict("density" => true, + "moments_conservation" => true))) test_input_split2 = recursive_merge(test_input_split1, OptionsDict("run_name" => "split2", - "evolve_moments_parallel_flow" => true)) + "evolve_moments" => OptionsDict("parallel_flow" => true))) test_input_split3 = recursive_merge(test_input_split2, OptionsDict("run_name" => "split3", "z" => OptionsDict("nelement" => 16), "vpa" => OptionsDict("nelement" => 31), "vz" => OptionsDict("nelement" => 31), - "evolve_moments_parallel_pressure" => true, + "evolve_moments" => OptionsDict("parallel_pressure" => true), "ion_numerical_dissipation" => OptionsDict("force_minimum_pdf_value" => 0.0, "vpa_dissipation_coefficient" => 1e-2), "neutral_numerical_dissipation" => OptionsDict("force_minimum_pdf_value" => 0.0, "vz_dissipation_coefficient" => 1e-2))) test_input_split3["timestepping"] = recursive_merge(test_input_split3["timestepping"], @@ -145,16 +145,16 @@ test_input_adaptive["timestepping"] = recursive_merge(test_input_adaptive["times test_input_adaptive_split1 = recursive_merge(test_input_adaptive, OptionsDict("run_name" => "adaptive split1", - "evolve_moments_density" => true, - "evolve_moments_conservation" => true)) + "evolve_moments" => OptionsDict("density" => true, + "moments_conservation" => true))) test_input_adaptive_split2 = recursive_merge(test_input_adaptive_split1, OptionsDict("run_name" => "adaptive split2", - "evolve_moments_parallel_flow" => true)) + "evolve_moments" => OptionsDict("parallel_flow" => true))) test_input_adaptive_split2["timestepping"] = recursive_merge(test_input_adaptive_split2["timestepping"], OptionsDict("step_update_prefactor" => 0.4)) test_input_adaptive_split3 = recursive_merge(test_input_adaptive_split2, OptionsDict("run_name" => "adaptive split3", - "evolve_moments_parallel_pressure" => true, + "evolve_moments" => OptionsDict("parallel_pressure" => true), "numerical_dissipation" => OptionsDict("force_minimum_pdf_value" => 0.0, "vpa_dissipation_coefficient" => 1e-2))) # The initial conditions seem to make the split3 case hard to advance without any diff --git a/moment_kinetics/test/restart_interpolation_tests.jl b/moment_kinetics/test/restart_interpolation_tests.jl index 51851bd9f..056cfe866 100644 --- a/moment_kinetics/test/restart_interpolation_tests.jl +++ b/moment_kinetics/test/restart_interpolation_tests.jl @@ -49,20 +49,20 @@ end restart_test_input_chebyshev_split_1_moment = recursive_merge(deepcopy(restart_test_input_chebyshev), OptionsDict("run_name" => "restart_chebyshev_pseudospectral_split_1_moment", - "evolve_moments_density" => true), + "evolve_moments" => OptionsDict("density" => true)), ) restart_test_input_chebyshev_split_2_moments = recursive_merge(deepcopy(restart_test_input_chebyshev_split_1_moment), OptionsDict("run_name" => "restart_chebyshev_pseudospectral_split_2_moments", "r" => OptionsDict("ngrid" => 1, "nelement" => 1), - "evolve_moments_parallel_flow" => true), + "evolve_moments" => OptionsDict("parallel_flow" => true)), ) restart_test_input_chebyshev_split_3_moments = recursive_merge(deepcopy(restart_test_input_chebyshev_split_2_moments), OptionsDict("run_name" => "restart_chebyshev_pseudospectral_split_3_moments", - "evolve_moments_parallel_pressure" => true, + "evolve_moments" => OptionsDict("parallel_pressure" => true), "vpa" => OptionsDict("L" => 1.5*vpa_L), "vz" => OptionsDict("L" => 1.5*vpa_L)), ) @@ -208,7 +208,7 @@ function run_test(test_input, base, message, rtol, atol; tol_3V, args...) f_neutral = f_neutral_vzvrvzetazrst[:,:,1,:,:] # Unnormalize f - if input["evolve_moments_density"] + if input["evolve_moments"]["density"] for it ∈ 1:length(time), is ∈ 1:n_ion_species, iz ∈ 1:z.n f_ion[:,iz,is,it] .*= n_ion[iz,is,it] end @@ -216,7 +216,7 @@ function run_test(test_input, base, message, rtol, atol; tol_3V, args...) f_neutral[:,iz,isn,it] .*= n_neutral[iz,isn,it] end end - if input["evolve_moments_parallel_pressure"] + if input["evolve_moments"]["parallel_pressure"] for it ∈ 1:length(time), is ∈ 1:n_ion_species, iz ∈ 1:z.n f_ion[:,iz,is,it] ./= v_t_ion[iz,is,it] end @@ -250,10 +250,10 @@ function run_test(test_input, base, message, rtol, atol; tol_3V, args...) size(newgrid_f_ion, 4)) for iz ∈ 1:length(expected.z) wpa = copy(expected.vpa) - if input["evolve_moments_parallel_flow"] + if input["evolve_moments"]["parallel_flow"] wpa .-= newgrid_upar_ion[iz,1] end - if input["evolve_moments_parallel_pressure"] + if input["evolve_moments"]["parallel_pressure"] wpa ./= newgrid_vth_ion[iz,1] end newgrid_f_ion[:,iz,1] = interpolate_to_grid_vpa(wpa, temp[:,iz,1], vpa, vpa_spectral) @@ -284,10 +284,10 @@ function run_test(test_input, base, message, rtol, atol; tol_3V, args...) size(newgrid_f_neutral, 4)) for iz ∈ 1:length(expected.z) wpa = copy(expected.vpa) - if input["evolve_moments_parallel_flow"] + if input["evolve_moments"]["parallel_flow"] wpa .-= newgrid_upar_neutral[iz,1] end - if input["evolve_moments_parallel_pressure"] + if input["evolve_moments"]["parallel_pressure"] wpa ./= newgrid_vth_neutral[iz,1] end newgrid_f_neutral[:,iz,1] = interpolate_to_grid_vpa(wpa, temp[:,iz,1], vz, vz_spectral) @@ -310,15 +310,15 @@ function runtests() OptionsDict("nstep" => nstep), ) base_input_evolve_density = recursive_merge(base_input_full_f, - OptionsDict("evolve_moments_density" => true), + OptionsDict("evolve_moments" => OptionsDict("density" => true)), ) base_input_evolve_upar = recursive_merge(base_input_evolve_density, - OptionsDict("evolve_moments_parallel_flow" => true, + OptionsDict("evolve_moments" => OptionsDict("parallel_flow" => true), "vpa" => OptionsDict("L" => 1.5*vpa_L), "vz" => OptionsDict("L" => 1.5*vpa_L)), ) base_input_evolve_ppar = recursive_merge(base_input_evolve_upar, - OptionsDict("evolve_moments_parallel_pressure" => true, + OptionsDict("evolve_moments" => OptionsDict("parallel_pressure" => true), "vpa" => OptionsDict("L" => 1.5*vpa_L), "vz" => OptionsDict("L" => 1.5*vpa_L)), ) diff --git a/moment_kinetics/test/sound_wave_tests.jl b/moment_kinetics/test/sound_wave_tests.jl index b2264520f..a66066f2b 100644 --- a/moment_kinetics/test/sound_wave_tests.jl +++ b/moment_kinetics/test/sound_wave_tests.jl @@ -48,10 +48,10 @@ test_input_finite_difference = OptionsDict("composition" => OptionsDict("n_ion_s "temperature_amplitude" => 0.0, "temperature_phase" => 0.0), "run_name" => "finite_difference", - "evolve_moments_density" => false, - "evolve_moments_parallel_flow" => false, - "evolve_moments_parallel_pressure" => false, - "evolve_moments_conservation" => true, + "evolve_moments" => OptionsDict("density" => false, + "parallel_flow" => false, + "parallel_pressure" => false, + "moments_conservation" => true), "charge_exchange_frequency" => 2*π*0.1, "ionization_frequency" => 0.0, "timestepping" => OptionsDict("nstep" => 1500, @@ -86,13 +86,13 @@ test_input_finite_difference = OptionsDict("composition" => OptionsDict("n_ion_s test_input_finite_difference_split_1_moment = recursive_merge(test_input_finite_difference, OptionsDict("run_name" => "finite_difference_split_1_moment", - "evolve_moments_density" => true) + "evolve_moments" => OptionsDict("density" => true)) ) test_input_finite_difference_split_2_moments = recursive_merge(test_input_finite_difference_split_1_moment, OptionsDict("run_name" => "finite_difference_split_2_moments", - "evolve_moments_parallel_flow" => true, + "evolve_moments" => OptionsDict("parallel_flow" => true), "vpa" => OptionsDict("ngrid" => 270, "L" => 12.0), "vz" => OptionsDict("ngrid" => 270, "L" => 12.0)) ) @@ -100,7 +100,7 @@ test_input_finite_difference_split_2_moments = test_input_finite_difference_split_3_moments = recursive_merge(test_input_finite_difference_split_2_moments, OptionsDict("run_name" => "finite_difference_split_3_moments", - "evolve_moments_parallel_pressure" => true, + "evolve_moments" => OptionsDict("parallel_pressure" => true), "vpa" => OptionsDict("ngrid" => 270, "L" => 12.0), "vz" => OptionsDict("ngrid" => 270, "L" => 12.0)) ) @@ -121,17 +121,17 @@ test_input_chebyshev = recursive_merge(test_input_finite_difference, test_input_chebyshev_split_1_moment = recursive_merge(test_input_chebyshev, OptionsDict("run_name" => "chebyshev_pseudospectral_split_1_moment", - "evolve_moments_density" => true)) + "evolve_moments" => OptionsDict("density" => true))) test_input_chebyshev_split_2_moments = recursive_merge(test_input_chebyshev_split_1_moment, OptionsDict("run_name" => "chebyshev_pseudospectral_split_2_moments", - "evolve_moments_parallel_flow" => true)) + "evolve_moments" => OptionsDict("parallel_flow" => true))) test_input_chebyshev_split_3_moments = recursive_merge(test_input_chebyshev_split_2_moments, OptionsDict("run_name" => "chebyshev_pseudospectral_split_3_moments", - "evolve_moments_parallel_pressure" => true)) + "evolve_moments" => OptionsDict("parallel_pressure" => true))) """ diff --git a/moment_kinetics/test/wall_bc_tests.jl b/moment_kinetics/test/wall_bc_tests.jl index cebd176f9..6f8db0ac8 100644 --- a/moment_kinetics/test/wall_bc_tests.jl +++ b/moment_kinetics/test/wall_bc_tests.jl @@ -55,10 +55,10 @@ test_input_finite_difference = OptionsDict("composition" => OptionsDict("n_ion_s "temperature_amplitude" => 0.0, "temperature_phase" => 0.0), "run_name" => "finite_difference", - "evolve_moments_density" => false, - "evolve_moments_parallel_flow" => false, - "evolve_moments_parallel_pressure" => false, - "evolve_moments_conservation" => false, + "evolve_moments" => OptionsDict("density" => false, + "parallel_flow" => false, + "parallel_pressure" => false, + "moments_conservation" => false), "charge_exchange_frequency" => 2.0, "ionization_frequency" => 2.0, "constant_ionization_rate" => false, diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25.toml index a0938b0df..bf8e7c825 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25.toml @@ -2,10 +2,6 @@ n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true -evolve_moments_density = false -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true T_e = 1.0 initial_density1 = 1.0 initial_temperature1 = 0.25 @@ -28,6 +24,12 @@ z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0] ionization_frequency = 0.0 +[evolve_moments] +density = false +parallel_flow = false +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split1.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split1.toml index 7bb514b8a..5846198a3 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split1.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split1.toml @@ -2,10 +2,6 @@ n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true -evolve_moments_density = true -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true T_e = 1.0 initial_density1 = 1.0 initial_temperature1 = 0.25 @@ -28,6 +24,12 @@ z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0] ionization_frequency = 0.0 +[evolve_moments] +density = true +parallel_flow = false +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split2.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split2.toml index 62b4543e3..89def9819 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split2.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split2.toml @@ -2,10 +2,6 @@ n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true T_e = 1.0 initial_density1 = 1.0 initial_temperature1 = 0.25 @@ -28,6 +24,12 @@ z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0] ionization_frequency = 0.0 +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split3.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split3.toml index 47b861a82..45b33495c 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split3.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split3.toml @@ -2,10 +2,6 @@ n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = true -evolve_moments_conservation = true T_e = 1.0 initial_density1 = 1.0 initial_temperature1 = 0.25 @@ -28,6 +24,12 @@ z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0] ionization_frequency = 0.0 +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = true +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5.toml index 6af74a930..3c5b7273f 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5.toml @@ -2,10 +2,6 @@ n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true -evolve_moments_density = false -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true T_e = 1.0 initial_density1 = 1.0 initial_temperature1 = 0.5 @@ -28,6 +24,12 @@ z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4] ionization_frequency = 0.0 +[evolve_moments] +density = false +parallel_flow = false +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split1.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split1.toml index c5731138f..00484fac2 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split1.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split1.toml @@ -2,10 +2,6 @@ n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true -evolve_moments_density = true -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true T_e = 1.0 initial_density1 = 1.0 initial_temperature1 = 0.5 @@ -28,6 +24,12 @@ z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4] ionization_frequency = 0.0 +[evolve_moments] +density = true +parallel_flow = false +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split2.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split2.toml index df1a136b1..01243b9ba 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split2.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split2.toml @@ -2,10 +2,6 @@ n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true T_e = 1.0 initial_density1 = 1.0 initial_temperature1 = 0.5 @@ -28,6 +24,12 @@ z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4] ionization_frequency = 0.0 +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split3.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split3.toml index 901757332..1ea2a6e2f 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split3.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split3.toml @@ -2,10 +2,6 @@ n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = true -evolve_moments_conservation = true T_e = 1.0 initial_density1 = 1.0 initial_temperature1 = 0.5 @@ -28,6 +24,12 @@ z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4] ionization_frequency = 0.0 +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = true +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1.toml index da37d3200..579ee0180 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1.toml @@ -2,10 +2,6 @@ n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true -evolve_moments_density = false -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true T_e = 1.0 initial_density1 = 1.0 initial_temperature1 = 1.0 @@ -28,6 +24,12 @@ z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0, 5.2, 5.4, 5.6, 5.8, 6.0, 6.2] ionization_frequency = 0.0 +[evolve_moments] +density = false +parallel_flow = false +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split1.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split1.toml index 0f92f42eb..8ea1bfcd7 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split1.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split1.toml @@ -2,10 +2,6 @@ n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true -evolve_moments_density = true -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true T_e = 1.0 initial_density1 = 1.0 initial_temperature1 = 1.0 @@ -28,6 +24,12 @@ z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0, 5.2, 5.4, 5.6, 5.8, 6.0, 6.2] ionization_frequency = 0.0 +[evolve_moments] +density = true +parallel_flow = false +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split2.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split2.toml index a86119a79..c38218c08 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split2.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split2.toml @@ -2,10 +2,6 @@ n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true T_e = 1.0 initial_density1 = 1.0 initial_temperature1 = 1.0 @@ -28,6 +24,12 @@ z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0, 5.2, 5.4, 5.6, 5.8, 6.0, 6.2] ionization_frequency = 0.0 +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split3.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split3.toml index 4d6d075ed..6bdcdd1e6 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split3.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split3.toml @@ -2,10 +2,6 @@ n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = true -evolve_moments_conservation = true T_e = 1.0 initial_density1 = 1.0 initial_temperature1 = 1.0 @@ -28,6 +24,12 @@ z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0, 5.2, 5.4, 5.6, 5.8, 6.0, 6.2] ionization_frequency = 0.0 +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = true +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2.toml index 0cec40a73..16aa4ee80 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2.toml @@ -2,10 +2,6 @@ n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true -evolve_moments_density = false -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true T_e = 1.0 initial_density1 = 1.0 initial_temperature1 = 2.0 @@ -30,6 +26,12 @@ z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.3, 0.6, 0.9, 1.2, 1.5, 1.8, 2.1, 2.4, 2.7, 3.0, 3.3, 3.6, 3.9, 4.2, 4.5, 4.8, 5.1, 5.4, 5.7, 6.0, 6.3, 6.6, 6.9, 7.2, 7.5, 7.8, 8.1, 8.4, 8.7] ionization_frequency = 0.0 +[evolve_moments] +density = false +parallel_flow = false +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split1.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split1.toml index 399ce5913..b7db6fe1e 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split1.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split1.toml @@ -2,10 +2,6 @@ n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true -evolve_moments_density = true -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true T_e = 1.0 initial_density1 = 1.0 initial_temperature1 = 2.0 @@ -30,6 +26,12 @@ z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.3, 0.6, 0.9, 1.2, 1.5, 1.8, 2.1, 2.4, 2.7, 3.0, 3.3, 3.6, 3.9, 4.2, 4.5, 4.8, 5.1, 5.4, 5.7, 6.0, 6.3, 6.6, 6.9, 7.2, 7.5, 7.8, 8.1, 8.4, 8.7] ionization_frequency = 0.0 +[evolve_moments] +density = true +parallel_flow = false +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split2.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split2.toml index e266e0e5e..ef3ce7ed2 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split2.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split2.toml @@ -2,10 +2,6 @@ n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true T_e = 1.0 initial_density1 = 1.0 initial_temperature1 = 2.0 @@ -30,6 +26,12 @@ z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.3, 0.6, 0.9, 1.2, 1.5, 1.8, 2.1, 2.4, 2.7, 3.0, 3.3, 3.6, 3.9, 4.2, 4.5, 4.8, 5.1, 5.4, 5.7, 6.0, 6.3, 6.6, 6.9, 7.2, 7.5, 7.8, 8.1, 8.4, 8.7] ionization_frequency = 0.0 +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split3.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split3.toml index c3a40e43d..11207a3a0 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split3.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split3.toml @@ -2,10 +2,6 @@ n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = true -evolve_moments_conservation = true T_e = 1.0 initial_density1 = 1.0 initial_temperature1 = 2.0 @@ -30,6 +26,12 @@ z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.3, 0.6, 0.9, 1.2, 1.5, 1.8, 2.1, 2.4, 2.7, 3.0, 3.3, 3.6, 3.9, 4.2, 4.5, 4.8, 5.1, 5.4, 5.7, 6.0, 6.3, 6.6, 6.9, 7.2, 7.5, 7.8, 8.1, 8.4, 8.7] ionization_frequency = 0.0 +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = true +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4.toml index 20c5b69fa..9d6f4c967 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4.toml @@ -2,10 +2,6 @@ n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true -evolve_moments_density = false -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true T_e = 1.0 initial_density1 = 1.0 initial_temperature1 = 4.0 @@ -30,6 +26,12 @@ z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.4, 0.8, 1.2, 1.6, 2.0, 2.4, 2.8, 3.2, 3.6, 4.0, 4.4, 4.8, 5.2, 5.6, 6.0, 6.4, 6.8, 7.2, 7.6, 8.0, 8.4, 8.8, 9.2, 9.6, 10.0, 10.4, 10.8, 11.2, 11.6, 12.0, 12.4] ionization_frequency = 0.0 +[evolve_moments] +density = false +parallel_flow = false +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split1.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split1.toml index ba6605e97..c53b67536 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split1.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split1.toml @@ -2,10 +2,6 @@ n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true -evolve_moments_density = true -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true T_e = 1.0 initial_density1 = 1.0 initial_temperature1 = 4.0 @@ -30,6 +26,12 @@ z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.4, 0.8, 1.2, 1.6, 2.0, 2.4, 2.8, 3.2, 3.6, 4.0, 4.4, 4.8, 5.2, 5.6, 6.0, 6.4, 6.8, 7.2, 7.6, 8.0, 8.4, 8.8, 9.2, 9.6, 10.0, 10.4, 10.8, 11.2, 11.6, 12.0, 12.4] ionization_frequency = 0.0 +[evolve_moments] +density = true +parallel_flow = false +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split2.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split2.toml index 6de13c549..19b439740 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split2.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split2.toml @@ -2,10 +2,6 @@ n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true T_e = 1.0 initial_density1 = 1.0 initial_temperature1 = 4.0 @@ -30,6 +26,12 @@ z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.4, 0.8, 1.2, 1.6, 2.0, 2.4, 2.8, 3.2, 3.6, 4.0, 4.4, 4.8, 5.2, 5.6, 6.0, 6.4, 6.8, 7.2, 7.6, 8.0, 8.4, 8.8, 9.2, 9.6, 10.0, 10.4, 10.8, 11.2, 11.6, 12.0, 12.4] ionization_frequency = 0.0 +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split3.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split3.toml index d97c16f2b..78fbbdaa0 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split3.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split3.toml @@ -2,10 +2,6 @@ n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = true -evolve_moments_conservation = true T_e = 1.0 initial_density1 = 1.0 initial_temperature1 = 4.0 @@ -30,6 +26,12 @@ z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.4, 0.8, 1.2, 1.6, 2.0, 2.4, 2.8, 3.2, 3.6, 4.0, 4.4, 4.8, 5.2, 5.6, 6.0, 6.4, 6.8, 7.2, 7.6, 8.0, 8.4, 8.8, 9.2, 9.6, 10.0, 10.4, 10.8, 11.2, 11.6, 12.0, 12.4] ionization_frequency = 0.0 +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = true +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio.toml index 4ca582094..de5d9f502 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio.toml @@ -2,10 +2,6 @@ combine_outer = ["charge_exchange_frequency"] n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true -evolve_moments_density = false -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true T_e = 1.0 initial_density1 = [1.0e-5, 0.5, 1.0, 1.5, 1.99999] initial_temperature1 = 1.0 @@ -28,6 +24,12 @@ z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0, 5.2, 5.4, 5.6, 5.8, 6.0, 6.2] ionization_frequency = 0.0 +[evolve_moments] +density = false +parallel_flow = false +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split1.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split1.toml index 315f41a1b..b9d344468 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split1.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split1.toml @@ -2,10 +2,6 @@ combine_outer = ["charge_exchange_frequency"] n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true -evolve_moments_density = true -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true T_e = 1.0 initial_density1 = [1.0e-5, 0.5, 1.0, 1.5, 1.99999] initial_temperature1 = 1.0 @@ -28,6 +24,12 @@ z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0, 5.2, 5.4, 5.6, 5.8, 6.0, 6.2] ionization_frequency = 0.0 +[evolve_moments] +density = true +parallel_flow = false +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split2.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split2.toml index b7ece2021..d13ea7922 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split2.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split2.toml @@ -2,10 +2,6 @@ combine_outer = ["charge_exchange_frequency"] n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true T_e = 1.0 initial_density1 = [1.0e-5, 0.5, 1.0, 1.5, 1.99999] initial_temperature1 = 1.0 @@ -28,6 +24,12 @@ z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0, 5.2, 5.4, 5.6, 5.8, 6.0, 6.2] ionization_frequency = 0.0 +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split3.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split3.toml index bc7e695b7..dcf6ab027 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split3.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split3.toml @@ -2,10 +2,6 @@ combine_outer = ["charge_exchange_frequency"] n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = true -evolve_moments_conservation = true T_e = 1.0 initial_density1 = [1.0e-5, 0.5, 1.0, 1.5, 1.99999] initial_temperature1 = 1.0 @@ -28,6 +24,12 @@ z_IC_temperature_phase2 = 0.0 charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0, 5.2, 5.4, 5.6, 5.8, 6.0, 6.2] ionization_frequency = 0.0 +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = true +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5.toml b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5.toml index d44aa2bc4..724358eda 100644 --- a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5.toml +++ b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5.toml @@ -4,10 +4,6 @@ converged_residual_value = 1.0e-3 n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true -evolve_moments_density = false -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true recycling_fraction = 0.5 krook_collisions_option = "reference_parameters" T_e = 0.2 # 1.0 @@ -48,6 +44,12 @@ charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false +[evolve_moments] +density = false +parallel_flow = false +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split1.toml b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split1.toml index 1a32e4ab0..6788b8d9a 100644 --- a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split1.toml +++ b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split1.toml @@ -4,10 +4,6 @@ converged_residual_value = 1.0e-3 n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true -evolve_moments_density = true -evolve_moments_parallel_flow = false -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true recycling_fraction = 0.5 krook_collisions_option = "reference_parameters" T_e = 0.2 # 1.0 @@ -48,6 +44,12 @@ charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false +[evolve_moments] +density = true +parallel_flow = false +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split2.toml b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split2.toml index a1510e719..312921532 100644 --- a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split2.toml +++ b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split2.toml @@ -4,10 +4,6 @@ converged_residual_value = 1.0e-3 n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = false -evolve_moments_conservation = true recycling_fraction = 0.5 krook_collisions_option = "reference_parameters" T_e = 0.2 # 1.0 @@ -48,6 +44,12 @@ charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = false +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split3.toml b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split3.toml index fb6b51fcc..4704bfe42 100644 --- a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split3.toml +++ b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split3.toml @@ -4,10 +4,6 @@ converged_residual_value = 1.0e-3 n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true -evolve_moments_density = true -evolve_moments_parallel_flow = true -evolve_moments_parallel_pressure = true -evolve_moments_conservation = true recycling_fraction = 0.5 krook_collisions_option = "reference_parameters" T_e = 0.2 # 1.0 @@ -48,6 +44,12 @@ charge_exchange_frequency = 0.75 ionization_frequency = 0.5 constant_ionization_rate = false +[evolve_moments] +density = true +parallel_flow = true +parallel_pressure = true +moments_conservation = true + [r] ngrid = 1 nelement = 1 diff --git a/util/precompile_run.jl b/util/precompile_run.jl index bf83be31b..b0f16ecd3 100644 --- a/util/precompile_run.jl +++ b/util/precompile_run.jl @@ -56,15 +56,16 @@ wall_bc_cheb_input = recursive_merge(cheb_input, OptionsDict("z" => OptionsDict( inputs_list = Vector{OptionsDict}(undef, 0) for input ∈ [base_input, cheb_input, wall_bc_input, wall_bc_cheb_input] push!(inputs_list, input) - x = recursive_merge(input, OptionsDict("evolve_moments_density" => true, "ionization_frequency" => 0.0, + x = recursive_merge(input, OptionsDict("evolve_moments" => OptionsDict("density" => true), + "ionization_frequency" => 0.0, "r" => OptionsDict("ngrid" => 1, "nelement" => 1), "vperp" => OptionsDict("ngrid" => 1, "nelement" => 1), "vzeta" => OptionsDict("ngrid" => 1, "nelement" => 1), "vr" => OptionsDict("ngrid" => 1, "nelement" => 1))) push!(inputs_list, x) - x = merge(x, OptionsDict("evolve_moments_parallel_flow" => true)) + x = recursive_merge(x, OptionsDict("evolve_moments" => OptionsDict("parallel_flow" => true))) push!(inputs_list, x) - x = merge(x, OptionsDict("evolve_moments_parallel_pressure" => true)) + x = recursive_merge(x, OptionsDict("evolve_moments" => OptionsDict("parallel_pressure" => true))) push!(inputs_list, x) end @@ -85,9 +86,9 @@ collisions_input2 = recursive_merge(wall_bc_cheb_input, OptionsDict("composition geo_input1 = recursive_merge(wall_bc_cheb_input, OptionsDict("composition" => OptionsDict("n_neutral_species" => 0), "geometry" => OptionsDict("option" => "1D-mirror", "DeltaB" => 0.5, "pitch" => 0.5, "rhostar" => 1.0))) -kinetic_electron_input = recursive_merge(cheb_input, OptionsDict("evolve_moments_density" => true, - "evolve_moments_parallel_flow" => true, - "evolve_moments_parallel_pressure" => true, +kinetic_electron_input = recursive_merge(cheb_input, OptionsDict("evolve_moments" => OptionsDict("density" => true, + "parallel_flow" => true, + "parallel_pressure" => true), "r" => OptionsDict("ngrid" => 1, "nelement" => 1), "vperp" => OptionsDict("ngrid" => 1, diff --git a/util/precompile_run_kinetic-electrons.jl b/util/precompile_run_kinetic-electrons.jl index 0f0f3c2f5..4f9dd0ff7 100644 --- a/util/precompile_run_kinetic-electrons.jl +++ b/util/precompile_run_kinetic-electrons.jl @@ -11,9 +11,9 @@ mkpath(test_output_directory) input = OptionsDict("run_name" => "precompilation", "base_directory" => test_output_directory, - "evolve_moments_density" => true, - "evolve_moments_parallel_flow" => true, - "evolve_moments_parallel_pressure" => true, + "evolve_moments" => OptionsDict("density" => true, + "parallel_flow" => true, + "parallel_pressure" => true), "composition" => OptionsDict("electron_physics" => "kinetic_electrons"), "r" => OptionsDict("ngrid" => 1, "nelement" => 1, diff --git a/util/precompile_run_long.jl b/util/precompile_run_long.jl index 9f498f315..3626cb0c7 100644 --- a/util/precompile_run_long.jl +++ b/util/precompile_run_long.jl @@ -32,11 +32,12 @@ wall_bc_cheb_input = recursive_merge(cheb_input, OptionsDict("z" => OptionsDict( inputs_list = Vector{OptionsDict}(undef, 0) for input ∈ [base_input, cheb_input, wall_bc_input, wall_bc_cheb_input] push!(inputs_list, input) - x = merge(input, OptionsDict("evolve_moments_density" => true, "ionization_frequency" => 0.0)) + x = recursive_merge(input, OptionsDict("evolve_moments" => OptionsDict("density" => true), + "ionization_frequency" => 0.0)) push!(inputs_list, x) - x = merge(x, OptionsDict("evolve_moments_parallel_flow" => true)) + x = recursive_merge(x, OptionsDict("evolve_moments" => OptionsDict("parallel_flow" => true))) push!(inputs_list, x) - x = merge(x, OptionsDict("evolve_moments_parallel_pressure" => true)) + x = recursive_merge(x, OptionsDict("evolve_moments" => OptionsDict("parallel_pressure" => true))) push!(inputs_list, x) end diff --git a/util/precompile_run_long_debug1.jl b/util/precompile_run_long_debug1.jl index abce1f115..3f6c16b66 100644 --- a/util/precompile_run_long_debug1.jl +++ b/util/precompile_run_long_debug1.jl @@ -32,11 +32,12 @@ wall_bc_cheb_input = recursive_merge(cheb_input, OptionsDict("z" => OptionsDict( inputs_list = Vector{OptionsDict}(undef, 0) for input ∈ [base_input, cheb_input, wall_bc_input, wall_bc_cheb_input] push!(inputs_list, input) - x = merge(input, OptionsDict("evolve_moments_density" => true, "ionization_frequency" => 0.0)) + x = merge(input, OptionsDict("evolve_moments" => OptionsDict("density" => true), + "ionization_frequency" => 0.0)) push!(inputs_list, x) - x = merge(x, OptionsDict("evolve_moments_parallel_flow" => true)) + x = merge(x, OptionsDict("evolve_moments" => OptionsDict("parallel_flow" => true))) push!(inputs_list, x) - x = merge(x, OptionsDict("evolve_moments_parallel_pressure" => true)) + x = merge(x, OptionsDict("evolve_moments" => OptionsDict("parallel_pressure" => true))) push!(inputs_list, x) end From fc725ca512410b1cbb2ee679d48274a0d443324c Mon Sep 17 00:00:00 2001 From: John Omotani Date: Sun, 8 Sep 2024 15:56:57 +0100 Subject: [PATCH 28/87] Remove modified default for neutral vz_dissipation in 1V case This is probably more confusing than helpful. By removing it, all dissipation coefficients have to be set explicitly. --- moment_kinetics/src/numerical_dissipation.jl | 8 -------- 1 file changed, 8 deletions(-) diff --git a/moment_kinetics/src/numerical_dissipation.jl b/moment_kinetics/src/numerical_dissipation.jl index f48a158c6..7de7d4600 100644 --- a/moment_kinetics/src/numerical_dissipation.jl +++ b/moment_kinetics/src/numerical_dissipation.jl @@ -84,14 +84,6 @@ end function setup_numerical_dissipation(ion_input::Dict, electron_input::Dict, neutral_input::Dict, is_1V) - if is_1V && "vpa_dissipation_coefficient" ∈ keys(ion_input) - # Set default for vz_dissipation_coefficient the same as - # ion_vpa_dissipation_coefficient for 1V case - neutral_input["vz_dissipation_coefficient"] = - get(neutral_input, "vz_dissipation_coefficient", - ion_input["vpa_dissipation_coefficient"]) - end - ion_input_dict = Dict(Symbol(k)=>v for (k,v) in ion_input) ion_params = ion_num_diss_params(; ion_input_dict...) electron_input_dict = Dict(Symbol(k)=>v for (k,v) in electron_input) From c79ccc5b28d535f3430551cbd30ccf8ac388fc55 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Sun, 8 Sep 2024 16:05:43 +0100 Subject: [PATCH 29/87] Use set_defaults_and_check_section!() for numerical dissipation inputs --- moment_kinetics/src/moment_kinetics_input.jl | 10 +- moment_kinetics/src/numerical_dissipation.jl | 98 ++++++++++---------- 2 files changed, 49 insertions(+), 59 deletions(-) diff --git a/moment_kinetics/src/moment_kinetics_input.jl b/moment_kinetics/src/moment_kinetics_input.jl index ff22b3182..2e2743658 100644 --- a/moment_kinetics/src/moment_kinetics_input.jl +++ b/moment_kinetics/src/moment_kinetics_input.jl @@ -440,15 +440,7 @@ function mk_input(scan_input=OptionsDict(); save_inputs_to_txt=false, ignore_MPI external_source_settings = setup_external_sources!(scan_input, r, z, composition.electron_physics) - is_1V = (vperp.ngrid == vperp.nelement_global == 1 && vzeta.ngrid == - vzeta.nelement_global == 1 && vr.ngrid == vr.nelement_global == 1) - - ion_num_diss_param_dict = get(scan_input, "ion_numerical_dissipation", OptionsDict()) - electron_num_diss_param_dict = get(scan_input, "electron_numerical_dissipation", OptionsDict()) - neutral_num_diss_param_dict = get(scan_input, "neutral_numerical_dissipation", OptionsDict()) - num_diss_params = setup_numerical_dissipation(ion_num_diss_param_dict, - electron_num_diss_param_dict, - neutral_num_diss_param_dict, is_1V) + num_diss_params = setup_numerical_dissipation(scan_input) if global_rank[] == 0 && save_inputs_to_txt # Make file to log some information about inputs into. diff --git a/moment_kinetics/src/numerical_dissipation.jl b/moment_kinetics/src/numerical_dissipation.jl index 7de7d4600..589cdce55 100644 --- a/moment_kinetics/src/numerical_dissipation.jl +++ b/moment_kinetics/src/numerical_dissipation.jl @@ -15,6 +15,7 @@ using ..looping using ..calculus: derivative!, second_derivative!, laplacian_derivative! using ..derivatives: derivative_r!, derivative_z!, second_derivative_r!, second_derivative_z! +using ..input_structs using ..type_definitions: mk_float @@ -41,57 +42,54 @@ vz_dissipation_coefficient There will still be the -1.0 default parameters. """ +function setup_numerical_dissipation(input_dict) + ion_settings = set_defaults_and_check_section!( + input_dict, "ion_numerical_dissipation"; + vpa_boundary_buffer_damping_rate=-1.0, + vpa_boundary_buffer_diffusion_coefficient=-1.0, + vpa_dissipation_coefficient=-1.0, + vperp_dissipation_coefficient=-1.0, + z_dissipation_coefficient=-1.0, + r_dissipation_coefficient=-1.0, + moment_dissipation_coefficient=-1.0, + force_minimum_pdf_value=-Inf, + ) + ion_settings = deepcopy(ion_settings) + if ion_settings["force_minimum_pdf_value"] == -Inf + ion_settings["force_minimum_pdf_value"] = nothing + end + ion_params = Dict_to_NamedTuple(ion_settings) + electron_settings = set_defaults_and_check_section!( + input_dict, "electron_numerical_dissipation"; + vpa_boundary_buffer_damping_rate=-1.0, + vpa_boundary_buffer_diffusion_coefficient=-1.0, + vpa_dissipation_coefficient=-1.0, + vperp_dissipation_coefficient=-1.0, + z_dissipation_coefficient=-1.0, + r_dissipation_coefficient=-1.0, + moment_dissipation_coefficient=-1.0, + force_minimum_pdf_value=-Inf, + ) + electron_settings = deepcopy(electron_settings) + if electron_settings["force_minimum_pdf_value"] == -Inf + electron_settings["force_minimum_pdf_value"] = nothing + end + electron_params = Dict_to_NamedTuple(electron_settings) + neutral_settings = set_defaults_and_check_section!( + input_dict, "neutral_numerical_dissipation"; + vz_dissipation_coefficient=-1.0, + z_dissipation_coefficient=-1.0, + r_dissipation_coefficient=-1.0, + moment_dissipation_coefficient=-1.0, + force_minimum_pdf_value=-Inf, + ) + neutral_settings = deepcopy(neutral_settings) + if neutral_settings["force_minimum_pdf_value"] == -Inf + neutral_settings["force_minimum_pdf_value"] = nothing + end + neutral_params = Dict_to_NamedTuple(neutral_settings) -# define individual structs for each species with their particular parameters -Base.@kwdef struct ion_num_diss_params - vpa_boundary_buffer_damping_rate::mk_float = -1.0 - vpa_boundary_buffer_diffusion_coefficient::mk_float = -1.0 - vpa_dissipation_coefficient::mk_float = -1.0 - vperp_dissipation_coefficient::mk_float = -1.0 - z_dissipation_coefficient::mk_float = -1.0 - r_dissipation_coefficient::mk_float = -1.0 - moment_dissipation_coefficient::mk_float = -1.0 - force_minimum_pdf_value::Union{Nothing,mk_float} = nothing -end - -Base.@kwdef struct electron_num_diss_params - vpa_boundary_buffer_damping_rate::mk_float = -1.0 - vpa_boundary_buffer_diffusion_coefficient::mk_float = -1.0 - vpa_dissipation_coefficient::mk_float = -1.0 - vperp_dissipation_coefficient::mk_float = -1.0 - z_dissipation_coefficient::mk_float = -1.0 - r_dissipation_coefficient::mk_float = -1.0 - moment_dissipation_coefficient::mk_float = -1.0 - force_minimum_pdf_value::Union{Nothing,mk_float} = nothing -end - -Base.@kwdef struct neutral_num_diss_params - vz_dissipation_coefficient::mk_float = -1.0 - z_dissipation_coefficient::mk_float = -1.0 - r_dissipation_coefficient::mk_float = -1.0 - moment_dissipation_coefficient::mk_float = -1.0 - force_minimum_pdf_value::Union{Nothing,mk_float} = nothing -end - -struct numerical_dissipation_parameters - ion::ion_num_diss_params - electron::electron_num_diss_params - neutral::neutral_num_diss_params -end - -######### End Of Numerical Dissipation Parameter setup ######### -################################################################ - -function setup_numerical_dissipation(ion_input::Dict, electron_input::Dict, - neutral_input::Dict, is_1V) - ion_input_dict = Dict(Symbol(k)=>v for (k,v) in ion_input) - ion_params = ion_num_diss_params(; ion_input_dict...) - electron_input_dict = Dict(Symbol(k)=>v for (k,v) in electron_input) - electron_params = electron_num_diss_params(; electron_input_dict...) - neutral_input_dict = Dict(Symbol(k)=>v for (k,v) in neutral_input) - neutral_params = neutral_num_diss_params(; neutral_input_dict...) - - return numerical_dissipation_parameters(ion_params, electron_params, neutral_params) + return (ion=ion_params, electron=electron_params, neutral=neutral_params) end """ From f4ddc0eb20f7a161e9bf47632860182a85531c54 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Sun, 8 Sep 2024 18:17:13 +0100 Subject: [PATCH 30/87] [reactions] and [electron_fluid_collisions] sections in input --- ...lanck-1D2V-even_nz-shorttest-nstep200.toml | 7 +- ...-planck-relaxation-report-resolutions.toml | 2 +- ...planck-relaxation-slowing-down-alphas.toml | 3 +- ...fokker-planck-relaxation-slowing-down.toml | 2 +- .../fokker-planck-relaxation.toml | 2 +- ...lowing-down-alphas-no-self-collisions.toml | 2 +- ...lanck-source-sink-slowing-down-alphas.toml | 2 +- examples/geometry/1D-mirror.toml | 7 +- examples/gk-ions/2D-periodic-gk.toml | 7 +- .../periodic_split3_boltzmann.toml | 5 +- .../periodic_split3_braginskii-IMEX.toml | 5 +- .../periodic_split3_braginskii.toml | 5 +- .../periodic_split3_kinetic-IMEX.toml | 5 +- .../periodic_split3_kinetic.toml | 5 +- ...ic_split3_kinetic_high-collisionality.toml | 5 +- .../wall+sheath-bc_boltzmann_loworder.toml | 10 +- .../wall+sheath-bc_kinetic.toml | 6 +- ...wall+sheath-bc_kinetic_krook_loworder.toml | 6 +- .../wall+sheath-bc_kinetic_loworder.toml | 10 +- ...on0.5_split3_braginskii-vpadiss0-IMEX.toml | 5 +- ...lefraction0.5_split3_kinetic-vpadiss0.toml | 3 +- .../nonlinear-sound-wave_cheb_split1.toml | 1 + .../nonlinear-sound-wave_cheb_split2.toml | 1 + .../nonlinear-sound-wave_cheb_split3.toml | 1 + .../nonlinear-sound-wave_fd.toml | 1 + .../nonlinear-sound-wave_fd_split1.toml | 1 + .../nonlinear-sound-wave_fd_split2.toml | 1 + .../nonlinear-sound-wave_fd_split3.toml | 1 + .../num-diss-relaxation.toml | 5 +- .../wall-bc_recyclefraction0.5-init.toml | 2 +- .../wall-bc_recyclefraction0.5.toml | 2 +- .../wall-bc_recyclefraction0.5_split1.toml | 2 +- .../wall-bc_recyclefraction0.5_split2.toml | 2 +- ...all-bc_recyclefraction0.5_split3-init.toml | 2 +- .../wall-bc_recyclefraction0.5_split3.toml | 2 +- ...l-bc_recyclefraction0.5_split3_SSPRK4.toml | 2 +- ...c_recyclefraction0.5_split3_fekete104.toml | 3 +- ...bc_recyclefraction0.5_split3_fekete42.toml | 3 +- ...bc_recyclefraction0.5_split3_fekete64.toml | 3 +- ...ll-bc_recyclefraction0.5_split3_rkf54.toml | 3 +- .../sheath-bc_cheb_test.toml | 2 +- .../wall-bc_cheb_test.toml | 2 +- examples/sound-wave/sound-wave_cheb.toml | 1 + .../sound-wave/sound-wave_cheb_split1.toml | 1 + .../sound-wave/sound-wave_cheb_split2.toml | 1 + .../sound-wave/sound-wave_cheb_split3.toml | 1 + examples/sound-wave/sound-wave_fd.toml | 1 + examples/sound-wave/sound-wave_fd_split1.toml | 1 + examples/sound-wave/sound-wave_fd_split2.toml | 1 + examples/sound-wave/sound-wave_fd_split3.toml | 1 + examples/wall-bc/wall+sheath-bc.toml | 2 +- examples/wall-bc/wall-bc_cheb.toml | 2 +- examples/wall-bc/wall-bc_cheb_split1.toml | 3 +- examples/wall-bc/wall-bc_cheb_split2.toml | 3 +- examples/wall-bc/wall-bc_cheb_split3.toml | 3 +- examples/wall-bc/wall-bc_volumerecycle.toml | 7 +- .../wall-bc/wall-bc_volumerecycle_split1.toml | 7 +- .../wall-bc/wall-bc_volumerecycle_split2.toml | 7 +- .../wall-bc/wall-bc_volumerecycle_split3.toml | 7 +- .../fokker_planck_collisions_inputs.jl | 5 +- .../debug_test/gyroaverage_inputs.jl | 6 +- .../debug_test/kinetic_electron_inputs.jl | 5 +- moment_kinetics/debug_test/mms_inputs.jl | 4 +- .../debug_test/recycling_fraction_inputs.jl | 5 +- .../restart_interpolation_inputs.jl | 4 +- .../debug_test/sound_wave_inputs.jl | 12 +- moment_kinetics/debug_test/wall_bc_inputs.jl | 5 +- moment_kinetics/ext/manufactured_solns_ext.jl | 4 +- .../src/electron_fluid_equations.jl | 41 ++++--- .../src/electron_kinetic_equation.jl | 3 +- moment_kinetics/src/em_fields.jl | 7 +- moment_kinetics/src/energy_equation.jl | 20 +-- moment_kinetics/src/file_io.jl | 6 +- moment_kinetics/src/force_balance.jl | 20 +-- moment_kinetics/src/initial_conditions.jl | 16 +-- moment_kinetics/src/input_structs.jl | 18 +-- moment_kinetics/src/ionization.jl | 13 +- moment_kinetics/src/moment_kinetics_input.jl | 27 ++-- moment_kinetics/src/neutral_vz_advection.jl | 16 ++- moment_kinetics/src/source_terms.jl | 16 ++- moment_kinetics/src/time_advance.jl | 40 +++--- moment_kinetics/src/utils.jl | 6 +- moment_kinetics/src/vpa_advection.jl | 24 ++-- .../test/Krook_collisions_tests.jl | 4 +- .../test/braginskii_electrons_imex_tests.jl | 9 +- .../fokker_planck_time_evolution_tests.jl | 4 +- moment_kinetics/test/harrisonthompson.jl | 5 +- ...ear_sound_wave_inputs_and_expected_data.jl | 4 +- .../test/recycling_fraction_tests.jl | 5 +- moment_kinetics/test/sound_wave_tests.jl | 116 +++++++++--------- moment_kinetics/test/wall_bc_tests.jl | 5 +- util/precompile_run.jl | 2 +- util/precompile_run_long.jl | 2 +- 93 files changed, 366 insertions(+), 308 deletions(-) diff --git a/examples/fokker-planck-1D2V/fokker-planck-1D2V-even_nz-shorttest-nstep200.toml b/examples/fokker-planck-1D2V/fokker-planck-1D2V-even_nz-shorttest-nstep200.toml index 99bb647de..5675a30d6 100644 --- a/examples/fokker-planck-1D2V/fokker-planck-1D2V-even_nz-shorttest-nstep200.toml +++ b/examples/fokker-planck-1D2V/fokker-planck-1D2V-even_nz-shorttest-nstep200.toml @@ -1,6 +1,7 @@ -charge_exchange_frequency = 0.0 -ionization_frequency = 1.0 -constant_ionization_rate = true +[ion_source] +z_profile = "constant" +source_strength = 1.0 +source_T = 0.25 [evolve_moments] density = false diff --git a/examples/fokker-planck/fokker-planck-relaxation-report-resolutions.toml b/examples/fokker-planck/fokker-planck-relaxation-report-resolutions.toml index fb892e565..879ee5d9e 100644 --- a/examples/fokker-planck/fokker-planck-relaxation-report-resolutions.toml +++ b/examples/fokker-planck/fokker-planck-relaxation-report-resolutions.toml @@ -1,7 +1,7 @@ # cheap input file for a 0D2V relaxation to a collisional Maxwellian distribution with self-ion collisions. +[reactions] charge_exchange_frequency = 0.0 ionization_frequency = 0.0 -constant_ionization_rate = false [evolve_moments] density = false diff --git a/examples/fokker-planck/fokker-planck-relaxation-slowing-down-alphas.toml b/examples/fokker-planck/fokker-planck-relaxation-slowing-down-alphas.toml index 36293750e..e0474be55 100644 --- a/examples/fokker-planck/fokker-planck-relaxation-slowing-down-alphas.toml +++ b/examples/fokker-planck/fokker-planck-relaxation-slowing-down-alphas.toml @@ -1,8 +1,7 @@ # cheap input file for a 0D2V relaxation to a collisional Maxwellian distribution with self-ion collisions and collisions with fixed Maxwellian background of cold ions and electrons. - +[reactions] charge_exchange_frequency = 0.0 ionization_frequency = 0.0 -constant_ionization_rate = false [evolve_moments] density = false diff --git a/examples/fokker-planck/fokker-planck-relaxation-slowing-down.toml b/examples/fokker-planck/fokker-planck-relaxation-slowing-down.toml index c192772ef..1512eb3a3 100644 --- a/examples/fokker-planck/fokker-planck-relaxation-slowing-down.toml +++ b/examples/fokker-planck/fokker-planck-relaxation-slowing-down.toml @@ -1,7 +1,7 @@ # cheap input file for a 0D2V relaxation to a collisional Maxwellian distribution with self-ion collisions. +[reactions] charge_exchange_frequency = 0.0 ionization_frequency = 0.0 -constant_ionization_rate = false [evolve_moments] density = false diff --git a/examples/fokker-planck/fokker-planck-relaxation.toml b/examples/fokker-planck/fokker-planck-relaxation.toml index 9f0c4f8f7..94b65dbc4 100644 --- a/examples/fokker-planck/fokker-planck-relaxation.toml +++ b/examples/fokker-planck/fokker-planck-relaxation.toml @@ -1,7 +1,7 @@ # cheap input file for a 0D2V relaxation to a collisional Maxwellian distribution with self-ion collisions. +[reactions] charge_exchange_frequency = 0.0 ionization_frequency = 0.0 -constant_ionization_rate = false [evolve_moments] density = false diff --git a/examples/fokker-planck/fokker-planck-source-sink-slowing-down-alphas-no-self-collisions.toml b/examples/fokker-planck/fokker-planck-source-sink-slowing-down-alphas-no-self-collisions.toml index 4e8631f72..d45258d06 100644 --- a/examples/fokker-planck/fokker-planck-source-sink-slowing-down-alphas-no-self-collisions.toml +++ b/examples/fokker-planck/fokker-planck-source-sink-slowing-down-alphas-no-self-collisions.toml @@ -1,7 +1,7 @@ # cheap input file for a 0D2V relaxation to a collisional Maxwellian distribution with self-ion collisions and collisions with fixed Maxwellian background of cold ions and electrons. +[reactions] charge_exchange_frequency = 0.0 ionization_frequency = 0.0 -constant_ionization_rate = false [evolve_moments] density = false diff --git a/examples/fokker-planck/fokker-planck-source-sink-slowing-down-alphas.toml b/examples/fokker-planck/fokker-planck-source-sink-slowing-down-alphas.toml index 5bd2d1ff0..64c228af1 100644 --- a/examples/fokker-planck/fokker-planck-source-sink-slowing-down-alphas.toml +++ b/examples/fokker-planck/fokker-planck-source-sink-slowing-down-alphas.toml @@ -1,7 +1,7 @@ # cheap input file for a 0D2V relaxation to a collisional Maxwellian distribution with self-ion collisions and collisions with fixed Maxwellian background of cold ions and electrons. +[reactions] charge_exchange_frequency = 0.0 ionization_frequency = 0.0 -constant_ionization_rate = false [evolve_moments] density = false diff --git a/examples/geometry/1D-mirror.toml b/examples/geometry/1D-mirror.toml index eebd26e51..26223c68c 100644 --- a/examples/geometry/1D-mirror.toml +++ b/examples/geometry/1D-mirror.toml @@ -1,6 +1,7 @@ -charge_exchange_frequency = 0.5 -ionization_frequency = 0.05 -constant_ionization_rate = true +[ion_source] +z_profile = "constant" +source_strength = 0.05 +source_T = 0.25 [evolve_moments] density = false diff --git a/examples/gk-ions/2D-periodic-gk.toml b/examples/gk-ions/2D-periodic-gk.toml index 4a0483af3..3e913e4bf 100644 --- a/examples/gk-ions/2D-periodic-gk.toml +++ b/examples/gk-ions/2D-periodic-gk.toml @@ -1,6 +1,7 @@ -charge_exchange_frequency = 0.0 -ionization_frequency = 0.05 -constant_ionization_rate = true +[ion_source] +z_profile = "constant" +source_strength = 0.05 +source_T = 0.25 [evolve_moments] density = false diff --git a/examples/kinetic-electrons/periodic_split3_boltzmann.toml b/examples/kinetic-electrons/periodic_split3_boltzmann.toml index 9a6997869..b0bbdc4ee 100644 --- a/examples/kinetic-electrons/periodic_split3_boltzmann.toml +++ b/examples/kinetic-electrons/periodic_split3_boltzmann.toml @@ -1,7 +1,8 @@ -#runtime_plots = true +[reactions] charge_exchange_frequency = 0.75 ionization_frequency = 0.0 -constant_ionization_rate = false + +[electron_fluid_collisions] nu_ei = 1000.0 [evolve_moments] diff --git a/examples/kinetic-electrons/periodic_split3_braginskii-IMEX.toml b/examples/kinetic-electrons/periodic_split3_braginskii-IMEX.toml index a36bd7da9..c4fadf9d5 100644 --- a/examples/kinetic-electrons/periodic_split3_braginskii-IMEX.toml +++ b/examples/kinetic-electrons/periodic_split3_braginskii-IMEX.toml @@ -1,7 +1,8 @@ -#runtime_plots = true +[reactions] charge_exchange_frequency = 0.75 ionization_frequency = 0.0 -constant_ionization_rate = false + +[electron_fluid_collisions] nu_ei = 1000.0 [evolve_moments] diff --git a/examples/kinetic-electrons/periodic_split3_braginskii.toml b/examples/kinetic-electrons/periodic_split3_braginskii.toml index 2441cb923..308c76ba9 100644 --- a/examples/kinetic-electrons/periodic_split3_braginskii.toml +++ b/examples/kinetic-electrons/periodic_split3_braginskii.toml @@ -1,7 +1,8 @@ -#runtime_plots = true +[reactions] charge_exchange_frequency = 0.75 ionization_frequency = 0.0 -constant_ionization_rate = false + +[electron_fluid_collisions] nu_ei = 1000.0 [evolve_moments] diff --git a/examples/kinetic-electrons/periodic_split3_kinetic-IMEX.toml b/examples/kinetic-electrons/periodic_split3_kinetic-IMEX.toml index 0343096ed..a67591698 100644 --- a/examples/kinetic-electrons/periodic_split3_kinetic-IMEX.toml +++ b/examples/kinetic-electrons/periodic_split3_kinetic-IMEX.toml @@ -1,7 +1,8 @@ -#runtime_plots = true +[reactions] charge_exchange_frequency = 0.75 ionization_frequency = 0.0 -constant_ionization_rate = false + +[electron_fluid_collisions] nu_ei = 1000.0 [evolve_moments] diff --git a/examples/kinetic-electrons/periodic_split3_kinetic.toml b/examples/kinetic-electrons/periodic_split3_kinetic.toml index 778ecf97e..b99a5afb0 100644 --- a/examples/kinetic-electrons/periodic_split3_kinetic.toml +++ b/examples/kinetic-electrons/periodic_split3_kinetic.toml @@ -1,7 +1,8 @@ -#runtime_plots = true +[reactions] charge_exchange_frequency = 0.75 ionization_frequency = 0.0 -constant_ionization_rate = false + +[electron_fluid_collisions] nu_ei = 1000.0 [evolve_moments] diff --git a/examples/kinetic-electrons/periodic_split3_kinetic_high-collisionality.toml b/examples/kinetic-electrons/periodic_split3_kinetic_high-collisionality.toml index 78347d9d3..8a7e9ea3a 100644 --- a/examples/kinetic-electrons/periodic_split3_kinetic_high-collisionality.toml +++ b/examples/kinetic-electrons/periodic_split3_kinetic_high-collisionality.toml @@ -1,7 +1,8 @@ -#runtime_plots = true +[reactions] charge_exchange_frequency = 0.75 ionization_frequency = 0.0 -constant_ionization_rate = false + +[electron_fluid_collisions] nu_ei = 1000.0 [evolve_moments] diff --git a/examples/kinetic-electrons/wall+sheath-bc_boltzmann_loworder.toml b/examples/kinetic-electrons/wall+sheath-bc_boltzmann_loworder.toml index 768fd8115..a06f36b1e 100644 --- a/examples/kinetic-electrons/wall+sheath-bc_boltzmann_loworder.toml +++ b/examples/kinetic-electrons/wall+sheath-bc_boltzmann_loworder.toml @@ -1,12 +1,12 @@ -steady_state_residual = true -converged_residual_value = 1.0e-3 +[reactions] charge_exchange_frequency = 2.0 electron_charge_exchange_frequency = 0.0 -nu_ei = 0.0 ionization_frequency = 2.0 #electron_ionization_frequency = 2.0 #ionization_energy = 1.0 -constant_ionization_rate = false + +[electron_fluid_collisions] +nu_ei = 0.0 [evolve_moments] density = false @@ -112,6 +112,8 @@ nstep = 1000000 dt = 1.0e-5 nwrite = 10000 nwrite_dfns = 10000 +steady_state_residual = true +converged_residual_value = 1.0e-3 [electron_numerical_dissipation] diff --git a/examples/kinetic-electrons/wall+sheath-bc_kinetic.toml b/examples/kinetic-electrons/wall+sheath-bc_kinetic.toml index 1f3bc62c4..84fb66008 100644 --- a/examples/kinetic-electrons/wall+sheath-bc_kinetic.toml +++ b/examples/kinetic-electrons/wall+sheath-bc_kinetic.toml @@ -1,10 +1,12 @@ +[reactions] charge_exchange_frequency = 2.0 electron_charge_exchange_frequency = 0.0 -nu_ei = 0.0 ionization_frequency = 2.0 electron_ionization_frequency = 2.0 ionization_energy = 1.0 -constant_ionization_rate = false + +[electron_fluid_collisions] +nu_ei = 0.0 [evolve_moments] density = false diff --git a/examples/kinetic-electrons/wall+sheath-bc_kinetic_krook_loworder.toml b/examples/kinetic-electrons/wall+sheath-bc_kinetic_krook_loworder.toml index fa2b76153..3520c6deb 100644 --- a/examples/kinetic-electrons/wall+sheath-bc_kinetic_krook_loworder.toml +++ b/examples/kinetic-electrons/wall+sheath-bc_kinetic_krook_loworder.toml @@ -1,10 +1,12 @@ +[reactions] charge_exchange_frequency = 2.0 electron_charge_exchange_frequency = 0.0 -nu_ei = 0.0 ionization_frequency = 2.0 electron_ionization_frequency = 2.0 ionization_energy = 1.0 -constant_ionization_rate = false + +[electron_fluid_collisions] +nu_ei = 0.0 [evolve_moments] density = false diff --git a/examples/kinetic-electrons/wall+sheath-bc_kinetic_loworder.toml b/examples/kinetic-electrons/wall+sheath-bc_kinetic_loworder.toml index b8d9d2383..6abaa537c 100644 --- a/examples/kinetic-electrons/wall+sheath-bc_kinetic_loworder.toml +++ b/examples/kinetic-electrons/wall+sheath-bc_kinetic_loworder.toml @@ -1,12 +1,12 @@ -steady_state_residual = true -converged_residual_value = 1.0e-3 +[reactions] charge_exchange_frequency = 2.0 electron_charge_exchange_frequency = 0.0 -nu_ei = 0.0 ionization_frequency = 2.0 #electron_ionization_frequency = 2.0 #ionization_energy = 1.0 -constant_ionization_rate = false + +[electron_fluid_collisions] +nu_ei = 0.0 [evolve_moments] density = false @@ -112,6 +112,8 @@ dt = 5.0e-5 nwrite = 200 nwrite_dfns = 10000 type = "SSPRK4" +steady_state_residual = true +converged_residual_value = 1.0e-3 [electron_timestepping] nstep = 5000000 diff --git a/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_braginskii-vpadiss0-IMEX.toml b/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_braginskii-vpadiss0-IMEX.toml index f59062dee..d11c2ea92 100644 --- a/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_braginskii-vpadiss0-IMEX.toml +++ b/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_braginskii-vpadiss0-IMEX.toml @@ -1,7 +1,8 @@ -#runtime_plots = true +[reactions] charge_exchange_frequency = 0.75 ionization_frequency = 0.5 -constant_ionization_rate = false + +[electron_fluid_collisions] nu_ei = 1000.0 [evolve_moments] diff --git a/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_kinetic-vpadiss0.toml b/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_kinetic-vpadiss0.toml index 86980b6b6..b12aa0079 100644 --- a/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_kinetic-vpadiss0.toml +++ b/examples/kinetic-electrons/wall-bc_recyclefraction0.5_split3_kinetic-vpadiss0.toml @@ -1,7 +1,6 @@ -#runtime_plots = true +[reactions] charge_exchange_frequency = 0.75 ionization_frequency = 0.5 -constant_ionization_rate = false [evolve_moments] density = true diff --git a/examples/nonlinear-sound-wave/nonlinear-sound-wave_cheb_split1.toml b/examples/nonlinear-sound-wave/nonlinear-sound-wave_cheb_split1.toml index 0b5bace4c..b451b391f 100644 --- a/examples/nonlinear-sound-wave/nonlinear-sound-wave_cheb_split1.toml +++ b/examples/nonlinear-sound-wave/nonlinear-sound-wave_cheb_split1.toml @@ -1,3 +1,4 @@ +[reactions] charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 diff --git a/examples/nonlinear-sound-wave/nonlinear-sound-wave_cheb_split2.toml b/examples/nonlinear-sound-wave/nonlinear-sound-wave_cheb_split2.toml index 90fecb742..430a8c986 100644 --- a/examples/nonlinear-sound-wave/nonlinear-sound-wave_cheb_split2.toml +++ b/examples/nonlinear-sound-wave/nonlinear-sound-wave_cheb_split2.toml @@ -1,3 +1,4 @@ +[reactions] charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 diff --git a/examples/nonlinear-sound-wave/nonlinear-sound-wave_cheb_split3.toml b/examples/nonlinear-sound-wave/nonlinear-sound-wave_cheb_split3.toml index 1dbee53d4..0a15cb08e 100644 --- a/examples/nonlinear-sound-wave/nonlinear-sound-wave_cheb_split3.toml +++ b/examples/nonlinear-sound-wave/nonlinear-sound-wave_cheb_split3.toml @@ -1,3 +1,4 @@ +[reactions] charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 diff --git a/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd.toml b/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd.toml index 57f08163e..b9b86dbd6 100644 --- a/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd.toml +++ b/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd.toml @@ -1,3 +1,4 @@ +[reactions] charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 diff --git a/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd_split1.toml b/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd_split1.toml index f1d2e0cb8..b5ec2f939 100644 --- a/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd_split1.toml +++ b/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd_split1.toml @@ -1,3 +1,4 @@ +[reactions] charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 diff --git a/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd_split2.toml b/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd_split2.toml index 5d29359f5..32983adcf 100644 --- a/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd_split2.toml +++ b/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd_split2.toml @@ -1,3 +1,4 @@ +[reactions] charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 diff --git a/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd_split3.toml b/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd_split3.toml index 09fed2159..c483575bb 100644 --- a/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd_split3.toml +++ b/examples/nonlinear-sound-wave/nonlinear-sound-wave_fd_split3.toml @@ -1,3 +1,4 @@ +[reactions] charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 diff --git a/examples/numerical-dissipation/num-diss-relaxation.toml b/examples/numerical-dissipation/num-diss-relaxation.toml index b23184c3e..06c0a3fe2 100644 --- a/examples/numerical-dissipation/num-diss-relaxation.toml +++ b/examples/numerical-dissipation/num-diss-relaxation.toml @@ -1,7 +1,10 @@ # cheap input file for a 0D2V relaxation with numerical diffusion terms d^2 F / dvpa^2 and d^2 F / vperp^2. +[reactions] charge_exchange_frequency = 0.0 ionization_frequency = 0.0 -constant_ionization_rate = false + +[fokker_planck_collisions] +use_fokker_planck = true nuii = 0.0 [evolve_moments] diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5-init.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5-init.toml index 1956049b1..c9ab9b087 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5-init.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5-init.toml @@ -1,6 +1,6 @@ +[reactions] charge_exchange_frequency = 0.75 ionization_frequency = 0.5 -constant_ionization_rate = false [evolve_moments] density = false diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5.toml index 79f90e62c..864b11204 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5.toml @@ -1,6 +1,6 @@ +[reactions] charge_exchange_frequency = 0.75 ionization_frequency = 0.5 -constant_ionization_rate = false [evolve_moments] density = false diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split1.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split1.toml index c0e76d0c0..bfe2e651d 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split1.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split1.toml @@ -1,6 +1,6 @@ +[reactions] charge_exchange_frequency = 0.75 ionization_frequency = 0.5 -constant_ionization_rate = false [evolve_moments] density = true diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split2.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split2.toml index eddd63c66..3df610516 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split2.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split2.toml @@ -1,6 +1,6 @@ +[reactions] charge_exchange_frequency = 0.75 ionization_frequency = 0.5 -constant_ionization_rate = false [evolve_moments] density = true diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3-init.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3-init.toml index f836b07d5..67f936f3d 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3-init.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3-init.toml @@ -1,6 +1,6 @@ +[reactions] charge_exchange_frequency = 0.75 ionization_frequency = 0.5 -constant_ionization_rate = false [evolve_moments] density = true diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3.toml index 4e0888561..5c0b33d63 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3.toml @@ -1,6 +1,6 @@ +[reactions] charge_exchange_frequency = 0.75 ionization_frequency = 0.5 -constant_ionization_rate = false [evolve_moments] density = true diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_SSPRK4.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_SSPRK4.toml index 31bc27b08..852803c31 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_SSPRK4.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_SSPRK4.toml @@ -1,6 +1,6 @@ +[reactions] charge_exchange_frequency = 0.75 ionization_frequency = 0.5 -constant_ionization_rate = false [evolve_moments] density = true diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete104.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete104.toml index e794efd8e..f43c1542c 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete104.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete104.toml @@ -1,7 +1,6 @@ -#runtime_plots = true +[reactions] charge_exchange_frequency = 0.75 ionization_frequency = 0.5 -constant_ionization_rate = false [evolve_moments] density = true diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete42.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete42.toml index 885c94c4f..62fb507bc 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete42.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete42.toml @@ -1,7 +1,6 @@ -#runtime_plots = true +[reactions] charge_exchange_frequency = 0.75 ionization_frequency = 0.5 -constant_ionization_rate = false [evolve_moments] density = true diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete64.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete64.toml index 08dfb3e90..d12f5d367 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete64.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete64.toml @@ -1,7 +1,6 @@ -#runtime_plots = true +[reactions] charge_exchange_frequency = 0.75 ionization_frequency = 0.5 -constant_ionization_rate = false [evolve_moments] density = true diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_rkf54.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_rkf54.toml index 91d442b15..ae6ceea48 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_rkf54.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_rkf54.toml @@ -1,7 +1,6 @@ -#runtime_plots = true +[reactions] charge_exchange_frequency = 0.75 ionization_frequency = 0.5 -constant_ionization_rate = false [evolve_moments] density = true diff --git a/examples/sheath+wall-bc_test/sheath-bc_cheb_test.toml b/examples/sheath+wall-bc_test/sheath-bc_cheb_test.toml index 96336b4ad..3ad8cd193 100644 --- a/examples/sheath+wall-bc_test/sheath-bc_cheb_test.toml +++ b/examples/sheath+wall-bc_test/sheath-bc_cheb_test.toml @@ -1,6 +1,6 @@ +[reactions] charge_exchange_frequency = 2.0 ionization_frequency = 2.0 -constant_ionization_rate = false [evolve_moments] density = false diff --git a/examples/sheath+wall-bc_test/wall-bc_cheb_test.toml b/examples/sheath+wall-bc_test/wall-bc_cheb_test.toml index 0cbebcd22..11f54c595 100644 --- a/examples/sheath+wall-bc_test/wall-bc_cheb_test.toml +++ b/examples/sheath+wall-bc_test/wall-bc_cheb_test.toml @@ -1,6 +1,6 @@ +[reactions] charge_exchange_frequency = 2.0 ionization_frequency = 2.0 -constant_ionization_rate = false [evolve_moments] density = false diff --git a/examples/sound-wave/sound-wave_cheb.toml b/examples/sound-wave/sound-wave_cheb.toml index 3524112a1..1c688d0b0 100644 --- a/examples/sound-wave/sound-wave_cheb.toml +++ b/examples/sound-wave/sound-wave_cheb.toml @@ -1,3 +1,4 @@ +[reactions] charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 diff --git a/examples/sound-wave/sound-wave_cheb_split1.toml b/examples/sound-wave/sound-wave_cheb_split1.toml index 3e9bf7d19..e83289a3d 100644 --- a/examples/sound-wave/sound-wave_cheb_split1.toml +++ b/examples/sound-wave/sound-wave_cheb_split1.toml @@ -1,3 +1,4 @@ +[reactions] charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 diff --git a/examples/sound-wave/sound-wave_cheb_split2.toml b/examples/sound-wave/sound-wave_cheb_split2.toml index f81527824..12423bfae 100644 --- a/examples/sound-wave/sound-wave_cheb_split2.toml +++ b/examples/sound-wave/sound-wave_cheb_split2.toml @@ -1,3 +1,4 @@ +[reactions] charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 diff --git a/examples/sound-wave/sound-wave_cheb_split3.toml b/examples/sound-wave/sound-wave_cheb_split3.toml index a1b1edf52..486edd65a 100644 --- a/examples/sound-wave/sound-wave_cheb_split3.toml +++ b/examples/sound-wave/sound-wave_cheb_split3.toml @@ -1,3 +1,4 @@ +[reactions] charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 diff --git a/examples/sound-wave/sound-wave_fd.toml b/examples/sound-wave/sound-wave_fd.toml index 18c7b3379..6374483d1 100644 --- a/examples/sound-wave/sound-wave_fd.toml +++ b/examples/sound-wave/sound-wave_fd.toml @@ -1,3 +1,4 @@ +[reactions] charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 diff --git a/examples/sound-wave/sound-wave_fd_split1.toml b/examples/sound-wave/sound-wave_fd_split1.toml index 0f0639a5c..962cc1a90 100644 --- a/examples/sound-wave/sound-wave_fd_split1.toml +++ b/examples/sound-wave/sound-wave_fd_split1.toml @@ -1,3 +1,4 @@ +[reactions] charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 diff --git a/examples/sound-wave/sound-wave_fd_split2.toml b/examples/sound-wave/sound-wave_fd_split2.toml index 762903ada..36e0cb809 100644 --- a/examples/sound-wave/sound-wave_fd_split2.toml +++ b/examples/sound-wave/sound-wave_fd_split2.toml @@ -1,3 +1,4 @@ +[reactions] charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 diff --git a/examples/sound-wave/sound-wave_fd_split3.toml b/examples/sound-wave/sound-wave_fd_split3.toml index 4e943451d..7e46898d8 100644 --- a/examples/sound-wave/sound-wave_fd_split3.toml +++ b/examples/sound-wave/sound-wave_fd_split3.toml @@ -1,3 +1,4 @@ +[reactions] charge_exchange_frequency = 0.62831853071 ionization_frequency = 0.0 diff --git a/examples/wall-bc/wall+sheath-bc.toml b/examples/wall-bc/wall+sheath-bc.toml index 38cd03da0..af58d4b18 100644 --- a/examples/wall-bc/wall+sheath-bc.toml +++ b/examples/wall-bc/wall+sheath-bc.toml @@ -1,6 +1,6 @@ +[reactions] charge_exchange_frequency = 2.0 ionization_frequency = 2.0 -constant_ionization_rate = false [evolve_moments] density = false diff --git a/examples/wall-bc/wall-bc_cheb.toml b/examples/wall-bc/wall-bc_cheb.toml index b552848c8..fdd9c8c24 100644 --- a/examples/wall-bc/wall-bc_cheb.toml +++ b/examples/wall-bc/wall-bc_cheb.toml @@ -1,6 +1,6 @@ +[reactions] charge_exchange_frequency = 0.5 ionization_frequency = 0.75 -constant_ionization_rate = false [evolve_moments] density = false diff --git a/examples/wall-bc/wall-bc_cheb_split1.toml b/examples/wall-bc/wall-bc_cheb_split1.toml index 3bd3a0944..07269f7eb 100644 --- a/examples/wall-bc/wall-bc_cheb_split1.toml +++ b/examples/wall-bc/wall-bc_cheb_split1.toml @@ -1,7 +1,6 @@ -#runtime_plots = true +[reactions] charge_exchange_frequency = 0.5 ionization_frequency = 0.75 -constant_ionization_rate = false [evolve_moments] density = true diff --git a/examples/wall-bc/wall-bc_cheb_split2.toml b/examples/wall-bc/wall-bc_cheb_split2.toml index 7480c957b..8b0a9ab85 100644 --- a/examples/wall-bc/wall-bc_cheb_split2.toml +++ b/examples/wall-bc/wall-bc_cheb_split2.toml @@ -1,7 +1,6 @@ -#runtime_plots = true +[reactions] charge_exchange_frequency = 0.5 ionization_frequency = 0.75 -constant_ionization_rate = false [evolve_moments] density = true diff --git a/examples/wall-bc/wall-bc_cheb_split3.toml b/examples/wall-bc/wall-bc_cheb_split3.toml index ad2361074..911634d85 100644 --- a/examples/wall-bc/wall-bc_cheb_split3.toml +++ b/examples/wall-bc/wall-bc_cheb_split3.toml @@ -1,7 +1,6 @@ -#runtime_plots = true +[reactions] charge_exchange_frequency = 0.5 ionization_frequency = 0.75 -constant_ionization_rate = false [evolve_moments] density = true diff --git a/examples/wall-bc/wall-bc_volumerecycle.toml b/examples/wall-bc/wall-bc_volumerecycle.toml index 44ccfba08..0bbf6a01e 100644 --- a/examples/wall-bc/wall-bc_volumerecycle.toml +++ b/examples/wall-bc/wall-bc_volumerecycle.toml @@ -1,9 +1,6 @@ -steady_state_residual = true -converged_residual_value = 1.0e-3 -#runtime_plots = true +[reactions] charge_exchange_frequency = 0.75 ionization_frequency = 0.5 -constant_ionization_rate = false [evolve_moments] density = false @@ -95,6 +92,8 @@ dt = 3.0e-5 nwrite = 10000 nwrite_dfns = 10000 split_operators = false +steady_state_residual = true +converged_residual_value = 1.0e-3 [ion_source] active = true diff --git a/examples/wall-bc/wall-bc_volumerecycle_split1.toml b/examples/wall-bc/wall-bc_volumerecycle_split1.toml index 0d2910d81..295363829 100644 --- a/examples/wall-bc/wall-bc_volumerecycle_split1.toml +++ b/examples/wall-bc/wall-bc_volumerecycle_split1.toml @@ -1,9 +1,6 @@ -steady_state_residual = true -converged_residual_value = 1.0e-3 -#runtime_plots = true +[reactions] charge_exchange_frequency = 0.75 ionization_frequency = 0.5 -constant_ionization_rate = false [evolve_moments] density = true @@ -95,6 +92,8 @@ dt = 3.0e-5 nwrite = 10000 nwrite_dfns = 10000 split_operators = false +steady_state_residual = true +converged_residual_value = 1.0e-3 [ion_source] active = true diff --git a/examples/wall-bc/wall-bc_volumerecycle_split2.toml b/examples/wall-bc/wall-bc_volumerecycle_split2.toml index 9588966c9..c305e3201 100644 --- a/examples/wall-bc/wall-bc_volumerecycle_split2.toml +++ b/examples/wall-bc/wall-bc_volumerecycle_split2.toml @@ -1,9 +1,6 @@ -steady_state_residual = true -converged_residual_value = 1.0e-3 -#runtime_plots = true +[reactions] charge_exchange_frequency = 0.75 ionization_frequency = 0.5 -constant_ionization_rate = false [evolve_moments] density = true @@ -95,6 +92,8 @@ dt = 3.0e-5 nwrite = 10000 nwrite_dfns = 10000 split_operators = false +steady_state_residual = true +converged_residual_value = 1.0e-3 [ion_source] active = true diff --git a/examples/wall-bc/wall-bc_volumerecycle_split3.toml b/examples/wall-bc/wall-bc_volumerecycle_split3.toml index e3d53461d..3e7b4a8e4 100644 --- a/examples/wall-bc/wall-bc_volumerecycle_split3.toml +++ b/examples/wall-bc/wall-bc_volumerecycle_split3.toml @@ -1,9 +1,6 @@ -steady_state_residual = true -converged_residual_value = 1.0e-3 -#runtime_plots = true +[reactions] charge_exchange_frequency = 0.75 ionization_frequency = 0.5 -constant_ionization_rate = false [evolve_moments] density = true @@ -95,6 +92,8 @@ dt = 1.0e-5 nwrite = 10000 nwrite_dfns = 10000 split_operators = false +steady_state_residual = true +converged_residual_value = 1.0e-3 [ion_source] active = true diff --git a/moment_kinetics/debug_test/fokker_planck_collisions_inputs.jl b/moment_kinetics/debug_test/fokker_planck_collisions_inputs.jl index b9d6d17a4..331bacdfb 100644 --- a/moment_kinetics/debug_test/fokker_planck_collisions_inputs.jl +++ b/moment_kinetics/debug_test/fokker_planck_collisions_inputs.jl @@ -26,9 +26,8 @@ test_input_full_f = OptionsDict( "temperature_phase" => 0.0, "upar_amplitude" => 0.0, "upar_phase" => 0.0), - "charge_exchange_frequency" => 0.0, - "ionization_frequency" => 0.0, - "constant_ionization_rate" => false, + "reactions" => OptionsDict("charge_exchange_frequency" => 0.0, + "ionization_frequency" => 0.0), "fokker_planck_collisions" => OptionsDict("use_fokker_planck" => true, "nuii" => 1.0, "frequency_option" => "manual"), diff --git a/moment_kinetics/debug_test/gyroaverage_inputs.jl b/moment_kinetics/debug_test/gyroaverage_inputs.jl index 854d58a4c..47ebb78a5 100644 --- a/moment_kinetics/debug_test/gyroaverage_inputs.jl +++ b/moment_kinetics/debug_test/gyroaverage_inputs.jl @@ -29,9 +29,9 @@ test_input = OptionsDict( "upar_phase" => 0.0, "temperature_amplitude" => 0.0, "temperature_phase" => 0.0), - "charge_exchange_frequency" => 0.0, - "ionization_frequency" => 0.05, - "constant_ionization_rate" => true, + "ion_source" => OptionsDict("z_profile" => "constant", + "source_strength" => 0.05, + "source_T" => 0.25), "timestepping" => OptionsDict("nstep" => 3, "dt" => 1.0e-12, "nwrite" => 2, diff --git a/moment_kinetics/debug_test/kinetic_electron_inputs.jl b/moment_kinetics/debug_test/kinetic_electron_inputs.jl index 913209d21..8401049e8 100644 --- a/moment_kinetics/debug_test/kinetic_electron_inputs.jl +++ b/moment_kinetics/debug_test/kinetic_electron_inputs.jl @@ -45,9 +45,8 @@ test_input = OptionsDict("composition" => OptionsDict("n_ion_species" => 1, "upar_phase" => 0.0, "temperature_amplitude" => 0.0, "temperature_phase" => 0.0), - "charge_exchange_frequency" => 0.75, - "ionization_frequency" => 0.5, - "constant_ionization_rate" => false, + "reactions" => OptionsDict("charge_exchange_frequency" => 0.75, + "ionization_frequency" => 0.5), "timestepping" => OptionsDict("type" => "Fekete4(3)", "nstep" => 3, "dt" => 2.0e-8, diff --git a/moment_kinetics/debug_test/mms_inputs.jl b/moment_kinetics/debug_test/mms_inputs.jl index 204d822a1..4d69e9abf 100644 --- a/moment_kinetics/debug_test/mms_inputs.jl +++ b/moment_kinetics/debug_test/mms_inputs.jl @@ -14,8 +14,8 @@ test_input = OptionsDict( "T_e" => 1.0, "T_wall" => 1.0), "run_name" => "MMS-2D-wall_cheb-with-neutrals", - "charge_exchange_frequency" => 0.0, - "ionization_frequency" => 0.0, + "recations" => OptionsDict("charge_exchange_frequency" => 0.0, + "ionization_frequency" => 0.0), "timestepping" => OptionsDict("nstep" => 3, "dt" => 1.e-8, "nwrite" => 2, diff --git a/moment_kinetics/debug_test/recycling_fraction_inputs.jl b/moment_kinetics/debug_test/recycling_fraction_inputs.jl index 5834e9150..6d4a8e2a7 100644 --- a/moment_kinetics/debug_test/recycling_fraction_inputs.jl +++ b/moment_kinetics/debug_test/recycling_fraction_inputs.jl @@ -47,9 +47,8 @@ test_input = OptionsDict("composition" => OptionsDict("n_ion_species" => 1, "upar_phase" => 0.0, "temperature_amplitude" => 0.0, "temperature_phase" => 0.0), - "charge_exchange_frequency" => 0.75, - "ionization_frequency" => 0.5, - "constant_ionization_rate" => false, + "reactions" => OptionsDict("charge_exchange_frequency" => 0.75, + "ionization_frequency" => 0.5), "timestepping" => OptionsDict("type" => "Fekete4(3)", "nstep" => 3, "dt" => 1.0e-8, diff --git a/moment_kinetics/debug_test/restart_interpolation_inputs.jl b/moment_kinetics/debug_test/restart_interpolation_inputs.jl index fe74867e5..0f4c9a118 100644 --- a/moment_kinetics/debug_test/restart_interpolation_inputs.jl +++ b/moment_kinetics/debug_test/restart_interpolation_inputs.jl @@ -14,8 +14,8 @@ base_input = OptionsDict( "parallel_flow" => false, "parallel_pressure" => false, "moments_conservation" => true), - "charge_exchange_frequency" => 2*π*0.1, - "ionization_frequency" => 0.0, + "reactions" => OptionsDict("charge_exchange_frequency" => 2*π*0.1, + "ionization_frequency" => 0.0), "timestepping" => OptionsDict("nstep" => 3, "dt" => 0.0, "nwrite" => 2, diff --git a/moment_kinetics/debug_test/sound_wave_inputs.jl b/moment_kinetics/debug_test/sound_wave_inputs.jl index 087adbb00..c46d4d208 100644 --- a/moment_kinetics/debug_test/sound_wave_inputs.jl +++ b/moment_kinetics/debug_test/sound_wave_inputs.jl @@ -13,8 +13,8 @@ test_input_finite_difference_1D1V = OptionsDict("run_name" => "finite_difference "parallel_flow" => false, "parallel_pressure" => false, "moments_conservation" => true), - "charge_exchange_frequency" => 2*π*0.1, - "ionization_frequency" => 0.0, + "reactions" => OptionsDict("charge_exchange_frequency" => 2*π*0.1, + "ionization_frequency" => 0.0), "timestepping" => OptionsDict("nstep" => 3, "dt" => 1.e-8, "nwrite" => 2, @@ -62,7 +62,7 @@ recursive_merge(test_input_finite_difference_1D1V_split_2_moments, test_input_finite_difference_cx0_1D1V = recursive_merge(test_input_finite_difference_1D1V, OptionsDict("run_name" => "finite_difference_cx0_1D1V", - "charge_exchange_frequency" => 0.0)) + "reactions" => OptionsDict("charge_exchange_frequency" => 0.0))) test_input_finite_difference_cx0_1D1V_split_1_moment = recursive_merge(test_input_finite_difference_cx0_1D1V, @@ -117,7 +117,7 @@ recursive_merge(test_input_finite_difference_split_2_moments, test_input_finite_difference_cx0 = recursive_merge(test_input_finite_difference, OptionsDict("run_name" => "finite_difference_cx0", - "charge_exchange_frequency" => 0.0)) + "reactions" => OptionsDict("charge_exchange_frequency" => 0.0))) test_input_finite_difference_cx0_split_1_moment = recursive_merge(test_input_finite_difference_cx0, @@ -177,7 +177,7 @@ recursive_merge(test_input_chebyshev_split_2_moments, test_input_chebyshev_cx0 = recursive_merge(test_input_chebyshev, OptionsDict("run_name" => "chebyshev_pseudospectral_cx0", - "charge_exchange_frequency" => 0.0)) + "reactions" => OptionsDict("charge_exchange_frequency" => 0.0))) test_input_chebyshev_cx0_split_1_moment = recursive_merge(test_input_chebyshev_cx0, @@ -227,7 +227,7 @@ recursive_merge(test_input_chebyshev_1D1V_split_2_moments, test_input_chebyshev_cx0_1D1V = recursive_merge(test_input_chebyshev_1D1V, OptionsDict("run_name" => "chebyshev_pseudospectral_cx0_1D1V", - "charge_exchange_frequency" => 0.0)) + "reactions" => OptionsDict("charge_exchange_frequency" => 0.0))) test_input_chebyshev_cx0_1D1V_split_1_moment = recursive_merge(test_input_chebyshev_cx0_1D1V, diff --git a/moment_kinetics/debug_test/wall_bc_inputs.jl b/moment_kinetics/debug_test/wall_bc_inputs.jl index 8038f327d..3eff3ad89 100644 --- a/moment_kinetics/debug_test/wall_bc_inputs.jl +++ b/moment_kinetics/debug_test/wall_bc_inputs.jl @@ -15,9 +15,8 @@ test_input_finite_difference_1D1V = OptionsDict( "parallel_flow" => false, "parallel_pressure" => false, "moments_conservation" => true), - "charge_exchange_frequency" => 2.0, - "ionization_frequency" => 2.0, - "constant_ionization_rate" => false, + "reactions" => OptionsDict("charge_exchange_frequency" => 2.0, + "ionization_frequency" => 2.0), "timestepping" => OptionsDict("nstep" => 3, "dt" => 1.0e-8, "nwrite" => 2, diff --git a/moment_kinetics/ext/manufactured_solns_ext.jl b/moment_kinetics/ext/manufactured_solns_ext.jl index e65c964db..fcfeaca74 100644 --- a/moment_kinetics/ext/manufactured_solns_ext.jl +++ b/moment_kinetics/ext/manufactured_solns_ext.jl @@ -605,8 +605,8 @@ using IfElse 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 - ionization_frequency = collisions.ionization + cx_frequency = collisions.reactions.charge_exchange_frequency + ionization_frequency = collisions.reactions.ionization_frequency else cx_frequency = 0.0 ionization_frequency = 0.0 diff --git a/moment_kinetics/src/electron_fluid_equations.jl b/moment_kinetics/src/electron_fluid_equations.jl index 395a94f4c..dea2f6a7d 100644 --- a/moment_kinetics/src/electron_fluid_equations.jl +++ b/moment_kinetics/src/electron_fluid_equations.jl @@ -137,8 +137,9 @@ function calculate_electron_moments!(scratch, pdf, moments, composition, collisi update_electron_vth_temperature!(moments, scratch.electron_ppar, scratch.electron_density, composition) calculate_electron_qpar!(moments.electron, pdf.electron, scratch.electron_ppar, - scratch.electron_upar, scratch.upar, collisions.nu_ei, - composition.me_over_mi, composition.electron_physics, vpa) + scratch.electron_upar, scratch.upar, + collisions.electron_fluid.nu_ei, composition.me_over_mi, + composition.electron_physics, vpa) if composition.electron_physics == braginskii_fluid electron_fluid_qpar_boundary_condition!(scratch.electron_ppar, scratch.electron_upar, @@ -170,7 +171,7 @@ function electron_energy_equation!(ppar_out, ppar_in, electron_density, electron begin_r_z_region() # define some abbreviated variables for convenient use in rest of function me_over_mi = composition.me_over_mi - nu_ei = collisions.nu_ei + nu_ei = collisions.electron_fluid.nu_ei T_in = moments.temp # calculate contribution to rhs of energy equation (formulated in terms of pressure) # arising from derivatives of ppar, qpar and upar @@ -204,23 +205,26 @@ function electron_energy_equation!(ppar_out, ppar_in, electron_density, electron end end # add in contributions due to charge exchange/ionization collisions + charge_exchange_electron = collisions.reactions.electron_charge_exchange_frequency + ionization_electron = collisions.reactions.electron_ionization_frequency + ionization_energy = collisions.reactions.ionization_energy if composition.n_neutral_species > 0 - if abs(collisions.charge_exchange_electron) > 0.0 + if abs(charge_exchange_electron) > 0.0 @loop_sn_r_z isn ir iz begin ppar_out[iz,ir] += - dt * 2.0 * me_over_mi * collisions.charge_exchange_electron * ( + dt * 2.0 * me_over_mi * charge_exchange_electron * ( 2*(pz_neutral[iz,ir,isn] - density_neutral[iz,ir,isn]*ppar_in[iz,ir]/electron_density[iz,ir]) + (2/3)*density_neutral[iz,ir,isn] * (uz_neutral[iz,ir,isn] - electron_upar[iz,ir])^2) end end - if abs(collisions.ionization_electron) > 0.0 + if abs(ionization_electron) > 0.0 @loop_sn_r_z isn ir iz begin ppar_out[iz,ir] += - dt * 2.0 * collisions.ionization_electron * density_neutral[iz,ir,isn] * ( + dt * 2.0 * ionization_electron * density_neutral[iz,ir,isn] * ( ppar_in[iz,ir] / electron_density[iz,ir] - - collisions.ionization_energy) + ionization_energy) end end end @@ -244,7 +248,7 @@ function electron_energy_equation!(ppar_out, ppar_in, electron_density, electron begin_r_z_region() # define some abbreviated variables for convenient use in rest of function me_over_mi = composition.me_over_mi - nu_ei = collisions.nu_ei + nu_ei = collisions.electron_fluid.nu_ei # calculate contribution to rhs of energy equation (formulated in terms of pressure) # arising from derivatives of ppar, qpar and upar @loop_r_z ir iz begin @@ -280,28 +284,31 @@ function electron_energy_equation!(ppar_out, ppar_in, electron_density, electron end # add in contributions due to charge exchange/ionization collisions if composition.n_neutral_species > 0 - if abs(collisions.charge_exchange_electron) > 0.0 + charge_exchange_electron = collisions.reactions.electron_charge_exchange_frequency + ionization_electron = collisions.reactions.electron_ionization_frequency + ionization_energy = collisions.reactions.ionization_energy + if abs(charge_exchange_electron) > 0.0 @loop_sn_r_z isn ir iz begin ppar_out[iz,ir] += - dt * me_over_mi * collisions.charge_exchange_electron * ( + dt * me_over_mi * charge_exchange_electron * ( 2*(electron_density[iz,ir]*pz_neutral[iz,ir,isn] - density_neutral[iz,ir,isn]*ppar_in[iz,ir]) + (2/3)*electron_density[iz,ir]*density_neutral[iz,ir,isn] * (uz_neutral[iz,ir,isn] - electron_upar[iz,ir])^2) end end - if abs(collisions.ionization_electron) > 0.0 + if abs(ionization_electron) > 0.0 # @loop_s_r_z is ir iz begin # ppar_out[iz,ir] += - # dt * collisions.ionization_electron * density_neutral[iz,ir,is] * ( + # dt * ionization_electron * density_neutral[iz,ir,is] * ( # ppar_in[iz,ir] - - # (2/3)*electron_density[iz,ir] * collisions.ionization_energy) + # (2/3)*electron_density[iz,ir] * ionization_energy) # end @loop_sn_r_z isn ir iz begin ppar_out[iz,ir] += - dt * collisions.ionization_electron * density_neutral[iz,ir,isn] * ( + dt * ionization_electron * density_neutral[iz,ir,isn] * ( ppar_in[iz,ir] - - electron_density[iz,ir] * collisions.ionization_energy) + electron_density[iz,ir] * ionization_energy) end end end @@ -381,7 +388,7 @@ function electron_braginskii_conduction!(ppar_out::AbstractVector{mk_float}, z) electron_moments.qpar_updated[] = false calculate_electron_qpar!(electron_moments, nothing, ppar_in, upar_e, upar_i, - collisions.nu_ei, composition.me_over_mi, + collisions.electron_fluid.nu_ei, composition.me_over_mi, composition.electron_physics, nothing) electron_fluid_qpar_boundary_condition!(ppar_in, upar_e, dens, electron_moments, z) derivative_z!(dqpar_dz, qpar, buffer_r_1, buffer_r_2, buffer_r_3, buffer_r_4, diff --git a/moment_kinetics/src/electron_kinetic_equation.jl b/moment_kinetics/src/electron_kinetic_equation.jl index fe1aeeb1e..60093b520 100644 --- a/moment_kinetics/src/electron_kinetic_equation.jl +++ b/moment_kinetics/src/electron_kinetic_equation.jl @@ -770,7 +770,8 @@ function implicit_electron_advance!(fvec_out, fvec_in, pdf, scratch_electron, mo calculate_electron_parallel_friction_force!( moments.electron.parallel_friction, fvec_out.electron_density, fvec_out.electron_upar, fvec_out.upar, moments.electron.dT_dz, - composition.me_over_mi, collisions.nu_ei, composition.electron_physics) + composition.me_over_mi, collisions.electron_fluid.nu_ei, + composition.electron_physics) # Solve for EM fields now that electrons are updated. update_phi!(fields, fvec_out, vperp, z, r, composition, collisions, moments, diff --git a/moment_kinetics/src/em_fields.jl b/moment_kinetics/src/em_fields.jl index c08ff6bb3..462d23959 100644 --- a/moment_kinetics/src/em_fields.jl +++ b/moment_kinetics/src/em_fields.jl @@ -117,9 +117,10 @@ function update_phi!(fields, fvec, vperp, z, r, composition, collisions, moments elseif composition.electron_physics ∈ (braginskii_fluid, kinetic_electrons, kinetic_electrons_with_temperature_equation) calculate_Epar_from_electron_force_balance!(fields.Ez, dens_e, moments.electron.dppar_dz, - collisions.nu_ei, moments.electron.parallel_friction, - composition.n_neutral_species, collisions.charge_exchange_electron, composition.me_over_mi, - fvec.density_neutral, fvec.uz_neutral, fvec.electron_upar) + collisions.electron_fluid.nu_ei, moments.electron.parallel_friction, + composition.n_neutral_species, collisions.reactions.electron_charge_exchange_frequency, + composition.me_over_mi, fvec.density_neutral, fvec.uz_neutral, + fvec.electron_upar) calculate_phi_from_Epar!(fields.phi, fields.Ez, r, z) end ## can calculate phi at z = L and hence phi_wall(z=L) using jpar_i at z =L if needed diff --git a/moment_kinetics/src/energy_equation.jl b/moment_kinetics/src/energy_equation.jl index 8890be3b6..c2fe09157 100644 --- a/moment_kinetics/src/energy_equation.jl +++ b/moment_kinetics/src/energy_equation.jl @@ -39,20 +39,22 @@ function energy_equation!(ppar, fvec, moments, collisions, dt, spectral, composi # add in contributions due to charge exchange/ionization collisions if composition.n_neutral_species > 0 - if abs(collisions.charge_exchange) > 0.0 + charge_exchange = collisions.reactions.charge_exchange_frequency + ionization = collisions.reactions.ionization_frequency + if abs(charge_exchange) > 0.0 @loop_s_r_z is ir iz begin ppar[iz,ir,is] -= - dt*collisions.charge_exchange*( + dt*charge_exchange*( fvec.density_neutral[iz,ir,is]*fvec.ppar[iz,ir,is] - fvec.density[iz,ir,is]*fvec.pz_neutral[iz,ir,is] - fvec.density[iz,ir,is]*fvec.density_neutral[iz,ir,is] * (fvec.upar[iz,ir,is] - fvec.uz_neutral[iz,ir,is])^2) end end - if abs(collisions.ionization) > 0.0 + if abs(ionization) > 0.0 @loop_s_r_z is ir iz begin ppar[iz,ir,is] += - dt*collisions.ionization*fvec.density[iz,ir,is] * ( + dt*ionization*fvec.density[iz,ir,is] * ( fvec.pz_neutral[iz,ir,is] + fvec.density_neutral[iz,ir,is] * (fvec.upar[iz,ir,is]-fvec.uz_neutral[iz,ir,is])^2) @@ -91,20 +93,22 @@ function neutral_energy_equation!(pz, fvec, moments, collisions, dt, spectral, # add in contributions due to charge exchange/ionization collisions if composition.n_neutral_species > 0 - if abs(collisions.charge_exchange) > 0.0 + charge_exchange = collisions.reactions.charge_exchange_frequency + ionization = collisions.reactions.ionization_frequency + if abs(charge_exchange) > 0.0 @loop_sn_r_z isn ir iz begin pz[iz,ir,isn] -= - dt*collisions.charge_exchange*( + dt*charge_exchange*( fvec.density[iz,ir,isn]*fvec.pz_neutral[iz,ir,isn] - fvec.density_neutral[iz,ir,isn]*fvec.ppar[iz,ir,isn] - fvec.density_neutral[iz,ir,isn]*fvec.density[iz,ir,isn] * (fvec.uz_neutral[iz,ir,isn] - fvec.upar[iz,ir,isn])^2) end end - if abs(collisions.ionization) > 0.0 + if abs(ionization) > 0.0 @loop_sn_r_z isn ir iz begin pz[iz,ir,isn] -= - dt*collisions.ionization*fvec.density[iz,ir,isn]*fvec.pz_neutral[iz,ir,isn] + dt*ionization*fvec.density[iz,ir,isn]*fvec.pz_neutral[iz,ir,isn] end end end diff --git a/moment_kinetics/src/file_io.jl b/moment_kinetics/src/file_io.jl index 2b2b77ff8..15b18b59e 100644 --- a/moment_kinetics/src/file_io.jl +++ b/moment_kinetics/src/file_io.jl @@ -630,10 +630,10 @@ function write_overview!(fid, composition, collisions, parallel_io, evolve_densi write_single_value!(overview, "T_e", composition.T_e, parallel_io=parallel_io, description="fixed electron temperature") write_single_value!(overview, "charge_exchange_frequency", - collisions.charge_exchange, parallel_io=parallel_io, + collisions.reactions.charge_exchange_frequency, parallel_io=parallel_io, description="quantity related to the charge exchange frequency") - write_single_value!(overview, "ionization_frequency", collisions.ionization, - parallel_io=parallel_io, + write_single_value!(overview, "ionization_frequency", + collisions.reactions.ionization_frequency, parallel_io=parallel_io, description="quantity related to the ionization frequency") write_single_value!(overview, "evolve_density", evolve_density, parallel_io=parallel_io, diff --git a/moment_kinetics/src/force_balance.jl b/moment_kinetics/src/force_balance.jl index 902c3901e..b23b3538d 100644 --- a/moment_kinetics/src/force_balance.jl +++ b/moment_kinetics/src/force_balance.jl @@ -48,15 +48,17 @@ function force_balance!(pflx, density_out, fvec, moments, fields, collisions, dt # if neutrals present account for charge exchange and/or ionization collisions if composition.n_neutral_species > 0 # account for collisional friction between ions and neutrals - if abs(collisions.charge_exchange) > 0.0 + charge_exchange = collisions.reactions.charge_exchange_frequency + ionization = collisions.reactions.ionization_frequency + if abs(charge_exchange) > 0.0 @loop_s_r_z is ir iz begin - pflx[iz,ir,is] += dt*collisions.charge_exchange*density[iz,ir,is]*fvec.density_neutral[iz,ir,is]*(fvec.uz_neutral[iz,ir,is]-upar[iz,ir,is]) + pflx[iz,ir,is] += dt*charge_exchange*density[iz,ir,is]*fvec.density_neutral[iz,ir,is]*(fvec.uz_neutral[iz,ir,is]-upar[iz,ir,is]) end end # account for ionization collisions - if abs(collisions.ionization) > 0.0 + if abs(ionization) > 0.0 @loop_s_r_z is ir iz begin - pflx[iz,ir,is] += dt*collisions.ionization*density[iz,ir,is]*fvec.density_neutral[iz,ir,is]*fvec.uz_neutral[iz,ir,is] + pflx[iz,ir,is] += dt*ionization*density[iz,ir,is]*fvec.density_neutral[iz,ir,is]*fvec.uz_neutral[iz,ir,is] end end end @@ -102,15 +104,17 @@ function neutral_force_balance!(pflx, density_out, fvec, moments, fields, collis # if neutrals present account for charge exchange and/or ionization collisions if composition.n_neutral_species > 0 # account for collisional friction between ions and neutrals - if abs(collisions.charge_exchange) > 0.0 + charge_exchange = collisions.reactions.charge_exchange_frequency + ionization = collisions.reactions.ionization_frequency + if abs(charge_exchange) > 0.0 @loop_sn_r_z isn ir iz begin - pflx[iz,ir,isn] += dt*collisions.charge_exchange*density[iz,ir,isn]*fvec.density[iz,ir,isn]*(fvec.upar[iz,ir,isn]-uz[iz,ir,isn]) + pflx[iz,ir,isn] += dt*charge_exchange*density[iz,ir,isn]*fvec.density[iz,ir,isn]*(fvec.upar[iz,ir,isn]-uz[iz,ir,isn]) end end # account for ionization collisions - if abs(collisions.ionization) > 0.0 + if abs(ionization) > 0.0 @loop_sn_r_z isn ir iz begin - pflx[iz,ir,isn] -= dt*collisions.ionization*fvec.density[iz,ir,isn]*density[iz,ir,isn]*uz[iz,ir,isn] + pflx[iz,ir,isn] -= dt*ionization*fvec.density[iz,ir,isn]*density[iz,ir,isn]*uz[iz,ir,isn] end end end diff --git a/moment_kinetics/src/initial_conditions.jl b/moment_kinetics/src/initial_conditions.jl index d8bc62900..56416bcf0 100644 --- a/moment_kinetics/src/initial_conditions.jl +++ b/moment_kinetics/src/initial_conditions.jl @@ -74,7 +74,7 @@ function allocate_pdf_and_moments(composition, r, z, vperp, vpa, vzeta, vr, vz, evolve_moments.parallel_pressure, external_source_settings.neutral, num_diss_params) - if abs(collisions.ionization) > 0.0 || z.bc == "wall" + if abs(collisions.reactions.ionization_frequency) > 0.0 || z.bc == "wall" # if ionization collisions are included or wall BCs are enforced, then particle # number is not conserved within each species particle_number_conserved = false @@ -362,10 +362,11 @@ function initialize_electrons!(pdf, moments, fields, geometry, composition, r, z # and this is only a rough initial condition anyway # # q at the boundaries tells us dTe/dz for Braginskii electrons + nu_ei = collisions.electron_fluid.nu_ei if z.irank == 0 dTe_dz_lower = @. -moments.electron.qpar[1,:] * 2.0 / 3.16 / moments.electron.ppar[1,:] * - composition.me_over_mi * collisions.nu_ei + composition.me_over_mi * nu_ei else dTe_dz_lower = nothing end @@ -374,7 +375,7 @@ function initialize_electrons!(pdf, moments, fields, geometry, composition, r, z if z.irank == z.nrank - 1 dTe_dz_upper = @. -moments.electron.qpar[end,:] * 2.0 / 3.16 / moments.electron.ppar[end,:] * - composition.me_over_mi * collisions.nu_ei + composition.me_over_mi * nu_ei else dTe_dz_upper = nothing end @@ -421,8 +422,8 @@ function initialize_electrons!(pdf, moments, fields, geometry, composition, r, z end moments.electron.qpar_updated[] = false calculate_electron_qpar!(moments.electron, pdf.electron, moments.electron.ppar, - moments.electron.upar, moments.ion.upar, collisions.nu_ei, composition.me_over_mi, - composition.electron_physics, vpa) + moments.electron.upar, moments.ion.upar, collisions.electron_fluid.nu_ei, + composition.me_over_mi, composition.electron_physics, vpa) if composition.electron_physics == braginskii_fluid electron_fluid_qpar_boundary_condition!( moments.electron.ppar, moments.electron.upar, moments.electron.dens, @@ -435,7 +436,8 @@ function initialize_electrons!(pdf, moments, fields, geometry, composition, r, z # calculate the electron-ion parallel friction force calculate_electron_parallel_friction_force!(moments.electron.parallel_friction, moments.electron.dens, moments.electron.upar, moments.ion.upar, moments.electron.dT_dz, - composition.me_over_mi, collisions.nu_ei, composition.electron_physics) + composition.me_over_mi, collisions.electron_fluid.nu_ei, + composition.electron_physics) # initialize the scratch arrays containing pdfs and moments for the first RK stage # the electron pdf is yet to be initialised but with the current code logic, the scratch @@ -651,7 +653,7 @@ function initialize_electron_pdf!(scratch, scratch_electron, pdf, moments, field moments.electron.qpar_updated[] = false calculate_electron_qpar!(moments.electron, pdf.electron, moments.electron.ppar, moments.electron.upar, moments.ion.upar, - collisions.nu_ei, composition.me_over_mi, + collisions.electron_fluid.nu_ei, composition.me_over_mi, composition.electron_physics, vpa) # update dqpar/dz for electrons # calculate the zed derivative of the initial electron parallel heat flux diff --git a/moment_kinetics/src/input_structs.jl b/moment_kinetics/src/input_structs.jl index 5bec6cee3..897654d2a 100644 --- a/moment_kinetics/src/input_structs.jl +++ b/moment_kinetics/src/input_structs.jl @@ -381,19 +381,11 @@ end Collisions input struct to contain all the different collisions substructs and overall collision input parameters. """ -struct collisions_input - # ion-neutral charge exchange collision frequency - charge_exchange::mk_float - # electron-neutral charge exchange collision frequency - charge_exchange_electron::mk_float - # ionization collision frequency - ionization::mk_float - # ionization collision frequency for electrons (probably should be same as for ions) - ionization_electron::mk_float - # ionization energy cost - ionization_energy::mk_float - # electron-ion collision frequency - nu_ei::mk_float +struct collisions_input{Treactions,Telectronfluid} + # atomic reaction parameters + reactions::Treactions + # electron fluid collision parameters + electron_fluid::Telectronfluid # struct of parameters for the Krook operator krook::krook_collisions_input # struct of parameters for the Fokker-Planck operator diff --git a/moment_kinetics/src/ionization.jl b/moment_kinetics/src/ionization.jl index e1becf468..0620f0717 100644 --- a/moment_kinetics/src/ionization.jl +++ b/moment_kinetics/src/ionization.jl @@ -75,9 +75,10 @@ function ion_ionization_collisions_1V!(f_out, fvec_in, vz, vpa, vperp, z, r, vz_ # no need to interpolate if neither upar or ppar evolved separately from pdf vpa.scratch2 .= fvec_in.pdf_neutral[:,1,1,iz,ir,isn] end + ionization = collisions.reactions.ionization_frequency @loop_vpa ivpa begin f_out[ivpa,1,iz,ir,is] += - dt*collisions.ionization*fvec_in.density_neutral[iz,ir,isn]* + dt*ionization*fvec_in.density_neutral[iz,ir,isn]* (vpa.scratch2[ivpa]*vth_ratio - fvec_in.pdf[ivpa,1,iz,ir,is]) end end @@ -88,6 +89,7 @@ function ion_ionization_collisions_1V!(f_out, fvec_in, vz, vpa, vperp, z, r, vz_ # no gyroaverage here as 1V code #NB: used quasineutrality to replace electron density n_e with ion density #NEEDS GENERALISATION TO n_ion_species > 1 (missing species charge: Sum_i Z_i n_i = n_e) + ionization = collisions.reactions.ionization_frequency isn = is @loop_r_z ir iz begin @views interpolate_to_grid_vpa!(vpa.scratch, vpa.grid, @@ -95,7 +97,7 @@ function ion_ionization_collisions_1V!(f_out, fvec_in, vz, vpa, vperp, z, r, vz_ vz_spectral) @loop_vpa ivpa begin # apply ionization collisions to all ion species - f_out[ivpa,1,iz,ir,is] += dt*collisions.ionization*vpa.scratch[ivpa]*fvec_in.density[iz,ir,is] + f_out[ivpa,1,iz,ir,is] += dt*ionization*vpa.scratch[ivpa]*fvec_in.density[iz,ir,is] end end end @@ -117,6 +119,7 @@ function neutral_ionization_collisions_1V!(f_neutral_out, fvec_in, vz, vpa, vper if !moments.evolve_density begin_sn_r_z_vz_region() + ionization = collisions.reactions.ionization_frequency @loop_sn isn begin # ion ionisation rate = < f_n > n_e R_ion # neutral "ionisation" (depopulation) rate = - f_n n_e R_ion @@ -126,7 +129,7 @@ function neutral_ionization_collisions_1V!(f_neutral_out, fvec_in, vz, vpa, vper is = isn @loop_r_z_vz ir iz ivz begin # apply ionization collisions to all neutral species - f_neutral_out[ivz,1,1,iz,ir,isn] -= dt*collisions.ionization*fvec_in.pdf_neutral[ivz,1,1,iz,ir,isn]*fvec_in.density[iz,ir,is] + f_neutral_out[ivz,1,1,iz,ir,isn] -= dt*ionization*fvec_in.pdf_neutral[ivz,1,1,iz,ir,isn]*fvec_in.density[iz,ir,is] end end end @@ -145,7 +148,7 @@ function ion_ionization_collisions_3V!(f_out, f_neutral_gav_in, fvec_in, composi @boundscheck r.n == size(f_neutral_gav_in,4) || throw(BoundsError(f_neutral_gav_in)) @boundscheck composition.n_neutral_species == size(f_neutral_gav_in,5) || throw(BoundsError(f_neutral_gav_in)) - ionization_frequency = collisions.ionization + ionization_frequency = collisions.reactions.ionization_frequency begin_s_r_z_vperp_vpa_region() @@ -173,7 +176,7 @@ function neutral_ionization_collisions_3V!(f_neutral_out, fvec_in, composition, @boundscheck r.n == size(f_neutral_out,5) || throw(BoundsError(f_neutral_out)) @boundscheck composition.n_neutral_species == size(f_neutral_out,6) || throw(BoundsError(f_neutral_out)) - ionization_frequency = collisions.ionization + ionization_frequency = collisions.reactions.ionization_frequency # ion ionization rate = < f_n > n_e R_ion # neutral "ionization" (depopulation) rate = - f_n n_e R_ion diff --git a/moment_kinetics/src/moment_kinetics_input.jl b/moment_kinetics/src/moment_kinetics_input.jl index 2e2743658..c935101de 100644 --- a/moment_kinetics/src/moment_kinetics_input.jl +++ b/moment_kinetics/src/moment_kinetics_input.jl @@ -70,7 +70,9 @@ function mk_input(scan_input=OptionsDict(); save_inputs_to_txt=false, ignore_MPI "force_Er_zero_at_wall", "evolve_moments_density", "evolve_moments_parallel_flow", "evolve_moments_parallel_pressure", - "evolve_moments_conservation", + "evolve_moments_conservation", "charge_exchange_frequency", + "electron_charge_exchange_frequency", "ionization_frequency", + "electron_ionization_frequency", "ionization_energy", "nu_ei", ) for opt in removed_options_list if opt ∈ keys(scan_input) @@ -110,12 +112,20 @@ function mk_input(scan_input=OptionsDict(); save_inputs_to_txt=false, ignore_MPI ## set geometry_input geometry_in = setup_geometry_input(scan_input) - charge_exchange = get(scan_input, "charge_exchange_frequency", 2.0*sqrt(composition.ion[1].initial_temperature)) - charge_exchange_electron = get(scan_input, "electron_charge_exchange_frequency", 0.0) - ionization = get(scan_input, "ionization_frequency", charge_exchange) - ionization_electron = get(scan_input, "electron_ionization_frequency", ionization) - ionization_energy = get(scan_input, "ionization_energy", 0.0) - nu_ei = get(scan_input, "nu_ei", 0.0) + reactions_settings = set_defaults_and_check_section!( + scan_input, "reactions"; + charge_exchange_frequency=2.0*sqrt(composition.ion[1].initial_temperature), + electron_charge_exchange_frequency=0.0, + ionization_frequency=2.0*sqrt(composition.ion[1].initial_temperature), + electron_ionization_frequency=0.0, + ionization_energy=0.0, + ) + reactions_input = Dict_to_NamedTuple(reactions_settings) + electron_fluid_collisions_settings = set_defaults_and_check_section!( + scan_input, "electron_fluid_collisions"; + nu_ei=0.0, + ) + electron_fluid_collisions_input = Dict_to_NamedTuple(electron_fluid_collisions_settings) # set up krook collision inputs krook_input = setup_krook_collisions_input(scan_input) # set up Fokker-Planck collision inputs @@ -125,8 +135,7 @@ function mk_input(scan_input=OptionsDict(); save_inputs_to_txt=false, ignore_MPI # write total collision struct using the structs above, as each setup function # for the collisions outputs itself a struct of the type of collision, which # is a substruct of the overall collisions_input struct. - collisions = collisions_input(charge_exchange, charge_exchange_electron, ionization, - ionization_electron, ionization_energy, nu_ei, + collisions = collisions_input(reactions_input, electron_fluid_collisions_input, krook_input, fkpl_input, mxwl_diff_input) # parameters related to the time stepping diff --git a/moment_kinetics/src/neutral_vz_advection.jl b/moment_kinetics/src/neutral_vz_advection.jl index 96b61cd39..88517ab32 100644 --- a/moment_kinetics/src/neutral_vz_advection.jl +++ b/moment_kinetics/src/neutral_vz_advection.jl @@ -111,10 +111,12 @@ function update_speed_n_u_p_evolution_neutral!(advect, fvec, moments, vz, z, r, end end # add in contributions from charge exchange and ionization collisions - if abs(collisions.charge_exchange) > 0.0 || abs(collisions.ionization) > 0.0 + charge_exchange = collisions.reactions.charge_exchange_frequency + ionization = collisions.reactions.ionization_frequency + if abs(charge_exchange) > 0.0 || abs(ionization) > 0.0 @loop_r_z_vzeta_vr ir iz ivzeta ivr begin @views @. advect[isn].speed[:,ivr,ivzeta,iz,ir] += - collisions.charge_exchange * + charge_exchange * (0.5*vz.grid/fvec.pz_neutral[iz,ir,isn] * (fvec.density[iz,ir,isn]*fvec.pz_neutral[iz,ir,isn] - fvec.density_neutral[iz,ir,isn]*fvec.ppar[iz,ir,isn] @@ -173,13 +175,14 @@ function update_speed_n_p_evolution_neutral!(advect, fields, fvec, moments, vz, vz.grid*moments.neutral.duz_dz[iz,ir,isn] end end - if abs(collisions.charge_exchange) > 0.0 + charge_exchange = collisions.reactions.charge_exchange_frequency + if abs(charge_exchange) > 0.0 # add in contributions from charge exchange and ionization collisions error("suspect the charge exchange and ionization contributions here may be " * "wrong because (upar[is]-upar[isp])^2 type terms were missed in the " * "energy equation when it was substituted in to derive them.") @loop_r_z_vzeta_vr ir iz ivzeta ivr begin - @views @. advect[is].speed[:,ivr,ivzeta,iz,ir] += collisions.charge_exchange * + @views @. advect[is].speed[:,ivr,ivzeta,iz,ir] += charge_exchange * 0.5*vz.grid*fvec.density_neutral[iz,ir,is] * (1.0-fvec.ppar[iz,ir,is]/fvec.pz_neutral[iz,ir,is]) end end @@ -212,10 +215,11 @@ function update_speed_n_u_evolution_neutral!(advect, fvec, moments, vz, z, r, co # if neutrals present compute contribution to parallel acceleration due to charge exchange # and/or ionization collisions betweens ions and neutrals - if abs(collisions.charge_exchange) > 0.0 + charge_exchange = collisions.reactions.charge_exchange_frequency + if abs(charge_exchange) > 0.0 # include contribution to neutral acceleration due to collisional friction with ions @loop_r_z_vzeta_vr ir iz ivzeta ivr begin - @views @. advect[isn].speed[:,ivr,ivzeta,iz,ir] -= collisions.charge_exchange*fvec.density[iz,ir,isn]*(fvec.upar[iz,ir,isn]-fvec.uz_neutral[iz,ir,isn]) + @views @. advect[isn].speed[:,ivr,ivzeta,iz,ir] -= charge_exchange*fvec.density[iz,ir,isn]*(fvec.upar[iz,ir,isn]-fvec.uz_neutral[iz,ir,isn]) end end end diff --git a/moment_kinetics/src/source_terms.jl b/moment_kinetics/src/source_terms.jl index 9850d6f23..5839bc84e 100644 --- a/moment_kinetics/src/source_terms.jl +++ b/moment_kinetics/src/source_terms.jl @@ -27,7 +27,7 @@ function source_terms!(pdf_out, fvec_in, moments, vpa, z, r, dt, spectral, compo moments.ion.dvth_dz[:,:,is], moments.ion.dqpar_dz[:,:,is], moments, z, r, dt, spectral, ion_source_settings) if composition.n_neutral_species > 0 - if abs(collisions.charge_exchange) > 0.0 || abs(collisions.ionization) > 0.0 + if abs(collisions.reactions.charge_exchange_frequency) > 0.0 || abs(collisions.reactions.ionization_frequency) > 0.0 @views source_terms_evolve_ppar_collisions!( pdf_out[:,:,:,:,is], fvec_in.pdf[:,:,:,:,is], fvec_in.density[:,:,is], fvec_in.upar[:,:,is], @@ -120,14 +120,16 @@ kinetic equation arising due to the re-normalization of the pdf as g = f * vth / function source_terms_evolve_ppar_collisions!(pdf_out, pdf_in, dens, upar, ppar, dens_neutral, upar_neutral, ppar_neutral, composition, collisions, dt, z, r) + charge_exchange = collisions.reactions.charge_exchange_frequency + ionization = collisions.reactions.ionization_frequency @loop_r_z_vperp_vpa ir iz ivperp ivpa begin @views pdf_out[ivpa,ivperp,iz,ir] -= 0.5*dt*pdf_in[ivpa,ivperp,iz,ir] * - (collisions.charge_exchange + (charge_exchange * (dens_neutral[iz,ir]*ppar[iz,ir] - dens[iz,ir]*ppar_neutral[iz,ir] - dens[iz,ir]*dens_neutral[iz,ir] * (upar[iz,ir] - upar_neutral[iz,ir])^2) / ppar[iz,ir] - + collisions.ionization + + ionization * (3.0*dens_neutral[iz,ir] - dens[iz,ir]*(ppar_neutral[iz,ir] + dens_neutral[iz,ir]*(upar[iz,ir] - upar_neutral[iz,ir])^2) @@ -155,7 +157,7 @@ function source_terms_neutral!(pdf_out, fvec_in, moments, vpa, z, r, dt, spectra moments.neutral.qz[:,:,isn], moments.neutral.ddens_dz[:,:,isn], moments.neutral.dvth_dz[:,:,isn], moments.neutral.dqz_dz[:,:,isn], moments, z, r, dt, spectral, neutral_source_settings) - if abs(collisions.charge_exchange) > 0.0 || abs(collisions.ionization) > 0.0 + if abs(collisions.reactions.charge_exchange_frequency) > 0.0 || abs(collisions.reactions.ionization_frequency) > 0.0 @views source_terms_evolve_ppar_collisions_neutral!( pdf_out[:,:,:,:,:,isn], fvec_in.pdf_neutral[:,:,:,:,:,isn], fvec_in.density_neutral[:,:,isn], fvec_in.uz_neutral[:,:,isn], @@ -247,13 +249,15 @@ kinetic equation arising due to the re-normalization of the pdf as g = f * vth / function source_terms_evolve_ppar_collisions_neutral!(pdf_out, pdf_in, dens, upar, ppar, dens_ion, upar_ion, ppar_ion, composition, collisions, dt, z, r) + charge_exchange = collisions.reactions.charge_exchange_frequency + ionization = collisions.reactions.ionization_frequency @loop_r_z_vzeta_vr_vz ir iz ivzeta ivr ivz begin @views pdf_out[ivz,ivr,ivzeta,iz,ir] -= 0.5*dt*pdf_in[ivz,ivr,ivzeta,iz,ir] * - (collisions.charge_exchange + (charge_exchange * (dens_ion[iz,ir]*ppar[iz,ir] - dens[iz,ir]*ppar_ion[iz,ir] - dens[iz,ir]*dens_ion[iz,ir] * (upar[iz,ir] - upar_ion[iz,ir])^2)/ppar[iz,ir] - - 2.0*collisions.ionization*dens_ion[iz,ir]) + - 2.0*ionization*dens_ion[iz,ir]) end return nothing end diff --git a/moment_kinetics/src/time_advance.jl b/moment_kinetics/src/time_advance.jl index 774028179..153267f4f 100644 --- a/moment_kinetics/src/time_advance.jl +++ b/moment_kinetics/src/time_advance.jl @@ -795,7 +795,8 @@ function setup_time_advance!(pdf, fields, vz, vr, vzeta, vpa, vperp, z, r, gyrop # calculate the electron-ion parallel friction force calculate_electron_parallel_friction_force!(moments.electron.parallel_friction, moments.electron.dens, moments.electron.upar, moments.ion.upar, moments.electron.dT_dz, - composition.me_over_mi, collisions.nu_ei, composition.electron_physics) + composition.me_over_mi, collisions.electron_fluid.nu_ei, + composition.electron_physics) # initialize the electrostatic potential begin_serial_region() update_phi!(fields, scratch[1], vperp, z, r, composition, collisions, moments, @@ -1025,7 +1026,7 @@ function setup_time_advance!(pdf, fields, vz, vr, vzeta, vpa, vperp, z, r, gyrop scratch_dummy.buffer_rs_4[:,1], z_spectral, z) # calculate the electron parallel heat flux calculate_electron_qpar!(moments.electron, pdf.electron, moments.electron.ppar, - moments.electron.upar, moments.ion.upar, collisions.nu_ei, + moments.electron.upar, moments.ion.upar, collisions.electron_fluid.nu_ei, composition.me_over_mi, composition.electron_physics, vpa) if composition.electron_physics == braginskii_fluid electron_fluid_qpar_boundary_condition!( @@ -1062,7 +1063,8 @@ function setup_time_advance!(pdf, fields, vz, vr, vzeta, vpa, vperp, z, r, gyrop # calculate the electron-ion parallel friction force calculate_electron_parallel_friction_force!(moments.electron.parallel_friction, moments.electron.dens, moments.electron.upar, moments.ion.upar, moments.electron.dT_dz, - composition.me_over_mi, collisions.nu_ei, composition.electron_physics) + composition.me_over_mi, collisions.electron_fluid.nu_ei, + composition.electron_physics) calculate_ion_moment_derivatives!(moments, scratch[1], scratch_dummy, z, z_spectral, ion_mom_diss_coeff) @@ -1157,7 +1159,7 @@ function setup_advance_flags(moments, composition, t_params, collisions, end # if charge exchange collision frequency non-zero, # account for charge exchange collisions - if abs(collisions.charge_exchange) > 0.0 + if abs(collisions.reactions.charge_exchange_frequency) > 0.0 if vperp.n == 1 && vr.n == 1 && vzeta.n == 1 advance_ion_cx_1V = !t_params.implicit_ion_advance advance_neutral_cx_1V = true @@ -1172,7 +1174,7 @@ function setup_advance_flags(moments, composition, t_params, collisions, end # if ionization collision frequency non-zero, # account for ionization collisions - if abs(collisions.ionization) > 0.0 + if abs(collisions.reactions.ionization_frequency) > 0.0 if vperp.n == 1 && vr.n == 1 && vzeta.n == 1 advance_ion_ionization_1V = !t_params.implicit_ion_advance advance_neutral_ionization_1V = true @@ -1346,7 +1348,7 @@ function setup_implicit_advance_flags(moments, composition, t_params, collisions advance_vperp_advection = vperp.n > 1 && z.n > 1 advance_z_advection = z.n > 1 advance_r_advection = r.n > 1 - if abs(collisions.charge_exchange) > 0.0 + if abs(collisions.reactions.charge_exchange_frequency) > 0.0 if vperp.n == 1 && vr.n == 1 && vzeta.n == 1 advance_ion_cx_1V = true elseif vperp.n > 1 && vr.n > 1 && vzeta.n > 1 @@ -1357,7 +1359,7 @@ function setup_implicit_advance_flags(moments, composition, t_params, collisions * "vpa.n=$(vpa.n), vz.n=$(vz.n)") end end - if abs(collisions.ionization) > 0.0 + if abs(collisions.reactions.ionization_frequency) > 0.0 if vperp.n == 1 && vr.n == 1 && vzeta.n == 1 advance_ion_ionization_1V = true elseif vperp.n > 1 && vr.n > 1 && vzeta.n > 1 @@ -2074,7 +2076,7 @@ function time_advance_split_operators!(pdf, scratch, scratch_implicit, scratch_e advance.z_advection = false # account for charge exchange collisions between ions and neutrals if composition.n_neutral_species > 0 - if collisions.charge_exchange > 0.0 + if collisions.reactions.charge_exchange_frequency > 0.0 advance.ion_cx_collisions = true time_advance_no_splitting!(pdf, scratch, scratch_implicit, scratch_electron, t_params, vpa, z, vpa_spectral, z_spectral, @@ -2090,7 +2092,7 @@ function time_advance_split_operators!(pdf, scratch, scratch_implicit, scratch_e advance_implicit, istep) advance.neutral_cx_collisions = false end - if collisions.ionization > 0.0 + if collisions.reactions.ionization_frequency > 0.0 advance.ion_ionization_collisions = true time_advance_no_splitting!(pdf, scratch, scratch_implicit, scratch_electron, t_params, z, vpa, z_spectral, vpa_spectral, @@ -2192,7 +2194,7 @@ function time_advance_split_operators!(pdf, scratch, scratch_implicit, scratch_e end # account for charge exchange collisions between ions and neutrals if composition.n_neutral_species > 0 - if collisions.ionization > 0.0 + if collisions.reactions.ionization_frequency > 0.0 advance.neutral_ionization = true time_advance_no_splitting!(pdf, scratch, scratch_implicit, scratch_electron, t_params, z, vpa, z_spectral, vpa_spectral, @@ -2208,7 +2210,7 @@ function time_advance_split_operators!(pdf, scratch, scratch_implicit, scratch_e advance_implicit, istep) advance.ion_ionization = false end - if collisions.charge_exchange > 0.0 + if collisions.reactions.charge_exchange_frequency > 0.0 advance.neutral_cx_collisions = true time_advance_no_splitting!(pdf, scratch, scratch_implicit, scratch_electron, t_params, vpa, z, vpa_spectral, z_spectral, @@ -2420,7 +2422,8 @@ function apply_all_bcs_constraints_update_moments!( calculate_electron_parallel_friction_force!( moments.electron.parallel_friction, this_scratch.electron_density, this_scratch.electron_upar, this_scratch.upar, moments.electron.dT_dz, - composition.me_over_mi, collisions.nu_ei, composition.electron_physics) + composition.me_over_mi, collisions.electron_fluid.nu_ei, + composition.electron_physics) # update the electrostatic potential phi update_phi!(fields, this_scratch, vperp, z, r, composition, collisions, moments, @@ -3298,22 +3301,22 @@ function euler_time_advance!(fvec_out, fvec_in, pdf, fields, moments, # account for charge exchange collisions between ions and neutrals if advance.ion_cx_collisions_1V ion_charge_exchange_collisions_1V!(fvec_out.pdf, fvec_in, moments, composition, - vpa, vz, collisions.charge_exchange, + vpa, vz, collisions.reactions.charge_exchange_frequency, vpa_spectral, vz_spectral, dt) elseif advance.ion_cx_collisions ion_charge_exchange_collisions_3V!(fvec_out.pdf, pdf.ion.buffer, fvec_in, composition, vz, vr, vzeta, vpa, vperp, z, r, - collisions.charge_exchange, dt) + collisions.reactions.charge_exchange_frequency, dt) end if advance.neutral_cx_collisions_1V neutral_charge_exchange_collisions_1V!(fvec_out.pdf_neutral, fvec_in, moments, composition, vpa, vz, - collisions.charge_exchange, vpa_spectral, + collisions.reactions.charge_exchange_frequency, vpa_spectral, vz_spectral, dt) elseif advance.neutral_cx_collisions neutral_charge_exchange_collisions_3V!(fvec_out.pdf_neutral, pdf.neutral.buffer, fvec_in, composition, vz, vr, vzeta, vpa, - vperp, z, r, collisions.charge_exchange, + vperp, z, r, collisions.reactions.charge_exchange_frequency, dt) end # account for ionization collisions between ions and neutrals @@ -3406,7 +3409,7 @@ function euler_time_advance!(fvec_out, fvec_in, pdf, fields, moments, end if advance.continuity continuity_equation!(fvec_out.density, fvec_in, moments, composition, dt, - z_spectral, collisions.ionization, + z_spectral, collisions.reactions.ionization_frequency, external_source_settings.ion, num_diss_params) end if advance.force_balance @@ -3428,7 +3431,8 @@ function euler_time_advance!(fvec_out, fvec_in, pdf, fields, moments, end if advance.neutral_continuity neutral_continuity_equation!(fvec_out.density_neutral, fvec_in, moments, - composition, dt, z_spectral, collisions.ionization, + composition, dt, z_spectral, + collisions.reactions.ionization_frequency, external_source_settings.neutral, num_diss_params) end if advance.neutral_force_balance diff --git a/moment_kinetics/src/utils.jl b/moment_kinetics/src/utils.jl index af6d76368..35b9206a0 100644 --- a/moment_kinetics/src/utils.jl +++ b/moment_kinetics/src/utils.jl @@ -72,10 +72,10 @@ function get_unnormalized_parameters(input::Dict) parameters["T_e"] = Tnorm * composition.T_e parameters["T_wall"] = Tnorm * composition.T_wall - parameters["CX_rate_coefficient"] = collisions.charge_exchange / Nnorm / timenorm - parameters["ionization_rate_coefficient"] = collisions.ionization / Nnorm / timenorm + parameters["CX_rate_coefficient"] = collisions.reactions.charge_exchange_frequency / Nnorm / timenorm + parameters["ionization_rate_coefficient"] = collisions.reactions.ionization_frequency / Nnorm / timenorm parameters["coulomb_collision_frequency0"] = - collisions.coulomb_collision_frequency_prefactor / timenorm + collisions.krook.nu_ii0 / timenorm return parameters end diff --git a/moment_kinetics/src/vpa_advection.jl b/moment_kinetics/src/vpa_advection.jl index bd70b3503..1dac86986 100644 --- a/moment_kinetics/src/vpa_advection.jl +++ b/moment_kinetics/src/vpa_advection.jl @@ -404,13 +404,15 @@ function update_speed_n_u_p_evolution!(advect, fvec, moments, vpa, z, r, composi end end # add in contributions from charge exchange and ionization collisions + charge_exchange = collisions.reactions.charge_exchange_frequency + ionization = collisions.reactions.ionization_frequency if composition.n_neutral_species > 0 && - (abs(collisions.charge_exchange) > 0.0 || abs(collisions.ionization) > 0.0) + (abs(charge_exchange) > 0.0 || abs(ionization) > 0.0) @loop_s is begin @loop_r_z_vperp ir iz ivperp begin @views @. advect[is].speed[:,ivperp,iz,ir] += - collisions.charge_exchange * + charge_exchange * (0.5*vpa.grid/fvec.ppar[iz,ir,is] * (fvec.density_neutral[iz,ir,is]*fvec.ppar[iz,ir,is] - fvec.density[iz,ir,is]*fvec.pz_neutral[iz,ir,is] @@ -419,7 +421,7 @@ function update_speed_n_u_p_evolution!(advect, fvec, moments, vpa, z, r, composi - fvec.density_neutral[iz,ir,is] * (fvec.uz_neutral[iz,ir,is]-fvec.upar[iz,ir,is]) / moments.ion.vth[iz,ir,is]) + - collisions.ionization * + ionization * (0.5*vpa.grid * (fvec.density_neutral[iz,ir,is] - fvec.density[iz,ir,is]*fvec.pz_neutral[iz,ir,is] @@ -485,10 +487,12 @@ function update_speed_n_p_evolution!(advect, fields, fvec, moments, vpa, z, r, error("suspect the charge exchange and ionization contributions here may be " * "wrong because (upar[is]-upar[isp])^2 type terms were missed in the " * "energy equation when it was substituted in to derive them.") - if abs(collisions.charge_exchange + collisions.ionization) > 0.0 + charge_exchange = collisions.reactions.charge_exchange_frequency + ionization = collisions.reactions.ionization_frequency + if abs(charge_exchange + ionization) > 0.0 @loop_s is begin @loop_r_z_vperp ir iz ivperp begin - @views @. advect[is].speed[:,ivperp,iz,ir] += (collisions.charge_exchange + collisions.ionization) * + @views @. advect[is].speed[:,ivperp,iz,ir] += (charge_exchange + ionization) * 0.5*vpa.grid*fvec.density[iz,ir,is] * (1.0-fvec.pz_neutral[iz,ir,is]/fvec.ppar[iz,ir,is]) end end @@ -523,17 +527,19 @@ function update_speed_n_u_evolution!(advect, fvec, moments, vpa, z, r, compositi # and/or ionization collisions betweens ions and neutrals if composition.n_neutral_species > 0 # account for collisional charge exchange friction between ions and neutrals - if abs(collisions.charge_exchange) > 0.0 + charge_exchange = collisions.reactions.charge_exchange_frequency + ionization = collisions.reactions.ionization_frequency + if abs(charge_exchange) > 0.0 @loop_s is begin @loop_r_z_vperp ir iz ivperp begin - @views @. advect[is].speed[:,ivperp,iz,ir] -= collisions.charge_exchange*fvec.density_neutral[iz,ir,is]*(fvec.uz_neutral[iz,ir,is]-fvec.upar[iz,ir,is]) + @views @. advect[is].speed[:,ivperp,iz,ir] -= charge_exchange*fvec.density_neutral[iz,ir,is]*(fvec.uz_neutral[iz,ir,is]-fvec.upar[iz,ir,is]) end end end - if abs(collisions.ionization) > 0.0 + if abs(ionization) > 0.0 @loop_s is begin @loop_r_z_vperp ir iz ivperp begin - @views @. advect[is].speed[:,ivperp,iz,ir] -= collisions.ionization*fvec.density_neutral[iz,ir,is]*(fvec.uz_neutral[iz,ir,is]-fvec.upar[iz,ir,is]) + @views @. advect[is].speed[:,ivperp,iz,ir] -= ionization*fvec.density_neutral[iz,ir,is]*(fvec.uz_neutral[iz,ir,is]-fvec.upar[iz,ir,is]) end end end diff --git a/moment_kinetics/test/Krook_collisions_tests.jl b/moment_kinetics/test/Krook_collisions_tests.jl index 98becafab..81603105e 100644 --- a/moment_kinetics/test/Krook_collisions_tests.jl +++ b/moment_kinetics/test/Krook_collisions_tests.jl @@ -113,8 +113,8 @@ test_input_full_f = OptionsDict("composition" => OptionsDict("n_ion_species" => "parallel_pressure" => false, "moments_conservation" => true), "krook_collisions" => OptionsDict("use_krook" => true,"frequency_option" => "reference_parameters"), - "charge_exchange_frequency" => 2*π*0.1, - "ionization_frequency" => 0.0, + "reactions" => OptionsDict("charge_exchange_frequency" => 2*π*0.1, + "ionization_frequency" => 0.0), "timestepping" => OptionsDict("nstep" => 100, "dt" => 0.001, "nwrite" => 100, diff --git a/moment_kinetics/test/braginskii_electrons_imex_tests.jl b/moment_kinetics/test/braginskii_electrons_imex_tests.jl index e6381e535..938399546 100644 --- a/moment_kinetics/test/braginskii_electrons_imex_tests.jl +++ b/moment_kinetics/test/braginskii_electrons_imex_tests.jl @@ -55,10 +55,11 @@ test_input = OptionsDict( "composition" => OptionsDict("n_ion_species" => 1, "upar_phase" => 0.0, "temperature_amplitude" => 0.0, "temperature_phase" => 0.0), - "nu_ei" => 1.0e3, - "charge_exchange_frequency" => 0.75, - "ionization_frequency" => 0.5, - "constant_ionization_rate" => false, + "electron_fluid_collisions" => OptionsDict("nu_ei" => 1.0e3), + "reactions" => OptionsDict("charge_exchange_frequency" => 0.75, + "electron_charge_exchange_frequency" => 0.0, + "ionization_frequency" => 0.5, + "electron_ionization_frequency" => 0.5), "timestepping" => OptionsDict("type" => "KennedyCarpenterARK324", "implicit_ion_advance" => false, "implicit_vpa_advection" => false, diff --git a/moment_kinetics/test/fokker_planck_time_evolution_tests.jl b/moment_kinetics/test/fokker_planck_time_evolution_tests.jl index dfab25dd0..a957d4896 100644 --- a/moment_kinetics/test/fokker_planck_time_evolution_tests.jl +++ b/moment_kinetics/test/fokker_planck_time_evolution_tests.jl @@ -247,8 +247,8 @@ test_input_gauss_legendre = OptionsDict("run_name" => "gausslegendre_pseudospect "nelement" => 3, "L" => 3.0, "discretization" => "gausslegendre_pseudospectral"), - "ionization_frequency" => 0.0, - "charge_exchange_frequency" => 0.0, + "reactions" => OptionsDict("ionization_frequency" => 0.0, + "charge_exchange_frequency" => 0.0), "fokker_planck_collisions" => OptionsDict("use_fokker_planck" => true, "nuii" => 1.0, "frequency_option" => "manual"), "evolve_moments" => OptionsDict("parallel_pressure" => false, "moments_conservation" => false, diff --git a/moment_kinetics/test/harrisonthompson.jl b/moment_kinetics/test/harrisonthompson.jl index b6272d16d..28491467a 100644 --- a/moment_kinetics/test/harrisonthompson.jl +++ b/moment_kinetics/test/harrisonthompson.jl @@ -88,9 +88,8 @@ test_input_finite_difference = Dict("composition" => OptionsDict("n_ion_species" "parallel_flow" => false, "parallel_pressure" => false, "moments_conservation" => false), - "charge_exchange_frequency" => 0.0, - "ionization_frequency" => 0.0, - "constant_ionization_rate" => true, + "reactions" => OptionsDict("charge_exchange_frequency" => 0.0, + "ionization_frequency" => 0.0), "timestepping" => OptionsDict("nstep" => 9000, "dt" => 0.0005, "nwrite" => 9000, diff --git a/moment_kinetics/test/nonlinear_sound_wave_inputs_and_expected_data.jl b/moment_kinetics/test/nonlinear_sound_wave_inputs_and_expected_data.jl index 597753279..5b6768e1d 100644 --- a/moment_kinetics/test/nonlinear_sound_wave_inputs_and_expected_data.jl +++ b/moment_kinetics/test/nonlinear_sound_wave_inputs_and_expected_data.jl @@ -109,8 +109,8 @@ test_input_finite_difference = OptionsDict("composition" => OptionsDict("n_ion_s "parallel_flow" => false, "parallel_pressure" => false, "moments_conservation" => true), - "charge_exchange_frequency" => 2*π*0.1, - "ionization_frequency" => 0.0, + "reactions" => OptionsDict("charge_exchange_frequency" => 2*π*0.1, + "ionization_frequency" => 0.0), "timestepping" => OptionsDict("nstep" => 100, "dt" => 0.001, "nwrite" => 100, diff --git a/moment_kinetics/test/recycling_fraction_tests.jl b/moment_kinetics/test/recycling_fraction_tests.jl index 509c9135d..2f2ca42c1 100644 --- a/moment_kinetics/test/recycling_fraction_tests.jl +++ b/moment_kinetics/test/recycling_fraction_tests.jl @@ -58,9 +58,8 @@ test_input = OptionsDict("composition" => OptionsDict("n_ion_species" => 1, "parallel_flow" => false, "parallel_pressure" => false, "moments_conservation" => false), - "charge_exchange_frequency" => 0.75, - "ionization_frequency" => 0.5, - "constant_ionization_rate" => false, + "reactions" => OptionsDict("charge_exchange_frequency" => 0.75, + "ionization_frequency" => 0.5), "timestepping" => OptionsDict("nstep" => 1000, "dt" => 1.0e-4, "nwrite" => 1000, diff --git a/moment_kinetics/test/sound_wave_tests.jl b/moment_kinetics/test/sound_wave_tests.jl index a66066f2b..5e13533dc 100644 --- a/moment_kinetics/test/sound_wave_tests.jl +++ b/moment_kinetics/test/sound_wave_tests.jl @@ -52,8 +52,8 @@ test_input_finite_difference = OptionsDict("composition" => OptionsDict("n_ion_s "parallel_flow" => false, "parallel_pressure" => false, "moments_conservation" => true), - "charge_exchange_frequency" => 2*π*0.1, - "ionization_frequency" => 0.0, + "reactions" => OptionsDict("charge_exchange_frequency" => 2*π*0.1, + "ionization_frequency" => 0.0), "timestepping" => OptionsDict("nstep" => 1500, "dt" => 0.002, "nwrite" => 20, @@ -256,18 +256,18 @@ function run_test_set_finite_difference() @long run_test(test_input_finite_difference, 2*π*1.4467, -2*π*0.6020, [-0.6941155980262039, -0.6940977032813103, -0.6940759796933667, -0.6940505149819431, -0.6940214119659553, -0.6939887881451088]; - charge_exchange_frequency=2*π*0.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*0.0)) run_test(test_input_finite_difference, 2*π*1.4240, -2*π*0.6379, [-0.6941155980262039, -0.6940977032813103, -0.6940759796933667, -0.6940505149819431, -0.6940214119659553, -0.6939887881451088]) @long run_test(test_input_finite_difference, 2*π*0.0, -2*π*0.3235, [-0.6941155980262039, -0.6940977032813103, -0.6940759796933667, -0.6940505149819431, -0.6940214119659553, -0.6939887881451088]; - charge_exchange_frequency=2*π*1.8) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*1.8)) @long run_test(test_input_finite_difference, 2*π*0.0, -2*π*0.2963, [-0.6941155980262039, -0.6940977032813103, -0.6940759796933667, -0.6940505149819431, -0.6940214119659553, -0.6939887881451088]; - charge_exchange_frequency=2*π*2.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*2.0)) # n_i>>n_n T_e=1 @long run_test(test_input_finite_difference, 2*π*1.4467, -2*π*0.6020, @@ -282,7 +282,7 @@ function run_test_set_finite_difference() -0.000941612585497573]; ion_species_1 = OptionsDict("initial_density" => 0.9999), neutral_species_1 = OptionsDict("initial_density" => 0.0001), - charge_exchange_frequency=2*π*2.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*2.0)) # n_i< 0.0001), neutral_species_1 = OptionsDict("initial_density" => 0.9999), - charge_exchange_frequency=2*π*2.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*2.0)) # n_i=n_n T_e=0.5 @long run_test(test_input_finite_difference, 2*π*1.2671, -2*π*0.8033, @@ -303,12 +303,12 @@ function run_test_set_finite_difference() -0.3470252574909716, -0.3470107059829777, -0.3469943940725544], 30; composition = OptionsDict("T_e" => 0.5), timestepping = OptionsDict("nstep" => 1300), - charge_exchange_frequency=2*π*0.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*0.0)) @long run_test(test_input_finite_difference, 2*π*0.0, -2*π*0.2727, [-0.34705779901310196, -0.34704885164065513, -0.3470379898466833, -0.3470252574909716, -0.3470107059829777, -0.3469943940725544]; composition = OptionsDict("T_e" => 0.5), - charge_exchange_frequency=2*π*2.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*2.0)) # n_i=n_n T_e=4 @long run_test(test_input_finite_difference, 2*π*1.9919, -2*π*0.2491, @@ -323,18 +323,18 @@ function run_test_set_finite_difference_split_1_moment() run_test(test_input_finite_difference_split_1_moment, 2*π*1.4467, -2*π*0.6020, [-0.6941155980262039, -0.6940977032813103, -0.6940759796933667, -0.6940505149819431, -0.6940214119659553, -0.6939887881451088]; - charge_exchange_frequency=2*π*0.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*0.0)) run_test(test_input_finite_difference_split_1_moment, 2*π*1.4240, -2*π*0.6379, [-0.6941155980262039, -0.6940977032813103, -0.6940759796933667, -0.6940505149819431, -0.6940214119659553, -0.6939887881451088]) run_test(test_input_finite_difference_split_1_moment, 2*π*0.0, -2*π*0.3235, [-0.6941155980262039, -0.6940977032813103, -0.6940759796933667, -0.6940505149819431, -0.6940214119659553, -0.6939887881451088]; - charge_exchange_frequency=2*π*1.8) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*1.8)) run_test(test_input_finite_difference_split_1_moment, 2*π*0.0, -2*π*0.2963, [-0.6941155980262039, -0.6940977032813103, -0.6940759796933667, -0.6940505149819431, -0.6940214119659553, -0.6939887881451088]; - charge_exchange_frequency=2*π*2.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*2.0)) # n_i>>n_n T_e=1 run_test(test_input_finite_difference_split_1_moment, 2*π*1.4467, -2*π*0.6020, @@ -347,7 +347,7 @@ function run_test_set_finite_difference_split_1_moment() -0.0010033394223312585, -0.0009742364063434105, -0.0009416125854969064]; ion_species_1 = OptionsDict("initial_density" => 0.9999), neutral_species_1 = OptionsDict("initial_density" => 0.0001), - charge_exchange_frequency=2*π*2.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*2.0)) # n_i< 0.0001), neutral_species_1 = OptionsDict("initial_density" => 0.9999), - charge_exchange_frequency=2*π*2.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*2.0)) # n_i=n_n T_e=0.5 run_test(test_input_finite_difference_split_1_moment, 2*π*1.2671, -2*π*0.8033, @@ -368,12 +368,12 @@ function run_test_set_finite_difference_split_1_moment() -0.3470252574909716, -0.3470107059829777, -0.3469943940725544], 30; composition = OptionsDict("T_e" => 0.5), timestepping = OptionsDict("nstep" => 1300), - charge_exchange_frequency=2*π*0.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*0.0)) run_test(test_input_finite_difference_split_1_moment, 2*π*0.0, -2*π*0.2727, [-0.34705779901310196, -0.34704885164065513, -0.3470379898466833, -0.3470252574909716, -0.3470107059829777, -0.3469943940725544]; composition = OptionsDict("T_e" => 0.5), - charge_exchange_frequency=2*π*2.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*2.0)) # n_i=n_n T_e=4 run_test(test_input_finite_difference_split_1_moment, 2*π*1.9919, -2*π*0.2491, @@ -388,18 +388,18 @@ function run_test_set_finite_difference_split_2_moments() run_test(test_input_finite_difference_split_2_moments, 2*π*1.4467, -2*π*0.6020, [-0.6941155980262039, -0.6940977032813103, -0.6940759796933667, -0.6940505149819431, -0.6940214119659553, -0.6939887881451088]; - charge_exchange_frequency=2*π*0.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*0.0)) run_test(test_input_finite_difference_split_2_moments, 2*π*1.4240, -2*π*0.6379, [-0.6941155980262039, -0.6940977032813103, -0.6940759796933667, -0.6940505149819431, -0.6940214119659553, -0.6939887881451088]) run_test(test_input_finite_difference_split_2_moments, 2*π*0.0, -2*π*0.3235, [-0.6941155980262039, -0.6940977032813103, -0.6940759796933667, -0.6940505149819431, -0.6940214119659553, -0.6939887881451088]; - charge_exchange_frequency=2*π*1.8) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*1.8)) run_test(test_input_finite_difference_split_2_moments, 2*π*0.0, -2*π*0.2963, [-0.6941155980262039, -0.6940977032813103, -0.6940759796933667, -0.6940505149819431, -0.6940214119659553, -0.6939887881451088]; - charge_exchange_frequency=2*π*2.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*2.0)) # n_i>>n_n T_e=1 run_test(test_input_finite_difference_split_2_moments, 2*π*1.4467, -2*π*0.6020, @@ -412,7 +412,7 @@ function run_test_set_finite_difference_split_2_moments() -0.0010033394223312585, -0.0009742364063434105, -0.0009416125854969064]; ion_species_1 = OptionsDict("initial_density" => 0.9999), neutral_species_1 = OptionsDict("initial_density" => 0.0001), - charge_exchange_frequency=2*π*2.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*2.0)) # n_i< 0.0001), neutral_species_1 = OptionsDict("initial_density" => 0.9999), - charge_exchange_frequency=2*π*2.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*2.0)) # n_i=n_n T_e=0.5 run_test(test_input_finite_difference_split_2_moments, 2*π*1.2671, -2*π*0.8033, @@ -433,12 +433,12 @@ function run_test_set_finite_difference_split_2_moments() -0.347052193699157, -0.34704563020982493, -0.3470382271523149], 30; composition = OptionsDict("T_e" => 0.5), timestepping = OptionsDict("nstep" => 1300), z = OptionsDict("ngrid" => 150), - charge_exchange_frequency=2*π*0.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*0.0)) run_test(test_input_finite_difference_split_2_moments, 2*π*0.0, -2*π*0.2727, [-0.34705779901310196, -0.34704885164065513, -0.3470379898466833, -0.3470252574909716, -0.3470107059829777, -0.3469943940725544]; composition = OptionsDict("T_e" => 0.5), - charge_exchange_frequency=2*π*2.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*2.0)) # n_i=n_n T_e=4 run_test(test_input_finite_difference_split_2_moments, 2*π*1.9919, -2*π*0.2491, @@ -454,18 +454,18 @@ function run_test_set_finite_difference_split_3_moments() -2*π*0.6020, [-0.6941155980262039, -0.6940977032813103, -0.6940759796933667, -0.6940505149819431, -0.6940214119659553, -0.6939887881451088]; - charge_exchange_frequency=2*π*0.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*0.0)) run_test(test_input_finite_difference_split_3_moments, 2*π*1.4240, -2*π*0.6379, [-0.6941155980262039, -0.6940977032813103, -0.6940759796933667, -0.6940505149819431, -0.6940214119659553, -0.6939887881451088]) @long run_test(test_input_finite_difference_split_3_moments, 2*π*0.0, -2*π*0.3235, [-0.6941155980262039, -0.6940977032813103, -0.6940759796933667, -0.6940505149819431, -0.6940214119659553, -0.6939887881451088]; - charge_exchange_frequency=2*π*1.8) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*1.8)) @long run_test(test_input_finite_difference_split_3_moments, 2*π*0.0, -2*π*0.2963, [-0.6941155980262039, -0.6940977032813103, -0.6940759796933667, -0.6940505149819431, -0.6940214119659553, -0.6939887881451088]; - charge_exchange_frequency=2*π*2.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*2.0)) # n_i>>n_n T_e=1 @long run_test(test_input_finite_difference_split_3_moments, 2*π*1.4467, @@ -480,7 +480,7 @@ function run_test_set_finite_difference_split_3_moments() -0.0009742364063434105, -0.0009416125854969064]; ion_species_1 = OptionsDict("initial_density" => 0.9999), neutral_species_1 = OptionsDict("initial_density" => 0.0001), - charge_exchange_frequency=2*π*2.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*2.0)) # n_i< 0.0001), neutral_species_1 = OptionsDict("initial_density" => 0.9999), - charge_exchange_frequency=2*π*2.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*2.0)) # n_i=n_n T_e=0.5 @long run_test(test_input_finite_difference_split_3_moments, 2*π*1.2671, @@ -503,12 +503,12 @@ function run_test_set_finite_difference_split_3_moments() -0.3470107059829777, -0.3469943940725544], 30; composition = OptionsDict("T_e" => 0.5), timestepping = OptionsDict("nstep" => 1300), - charge_exchange_frequency=2*π*0.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*0.0)) @long run_test(test_input_finite_difference_split_3_moments, 2*π*0.0, -2*π*0.2727, [-0.34705779901310196, -0.34704885164065513, -0.3470379898466833, -0.3470252574909716, -0.3470107059829777, -0.3469943940725544]; composition = OptionsDict("T_e" => 0.5), - charge_exchange_frequency=2*π*2.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*2.0)) # n_i=n_n T_e=4 @long run_test(test_input_finite_difference_split_3_moments, 2*π*1.9919, @@ -524,18 +524,18 @@ function run_test_set_chebyshev() @long run_test(test_input_chebyshev, 2*π*1.4467, -2*π*0.6020, [-0.6931471805599453, -0.6925817758085663, -0.6922515628093567, -0.6921548130694323, -0.6921476802268619, -0.6921548130694323]; - charge_exchange_frequency=2*π*0.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*0.0)) run_test(test_input_chebyshev, 2*π*1.4240, -2*π*0.6379, [-0.6931471805599453, -0.6925817758085663, -0.6922515628093567, -0.6921548130694323, -0.6921476802268619, -0.6921548130694323]) @long run_test(test_input_chebyshev, 2*π*0.0, -2*π*0.3235, [-0.6931471805599453, -0.6925817758085663, -0.6922515628093567, -0.6921548130694323, -0.6921476802268619, -0.6921548130694323]; - charge_exchange_frequency=2*π*1.8) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*1.8)) @long run_test(test_input_chebyshev, 2*π*0.0, -2*π*0.2963, [-0.6931471805599453, -0.6925817758085663, -0.6922515628093567, -0.6921548130694323, -0.6921476802268619, -0.6921548130694323]; - charge_exchange_frequency=2*π*2.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*2.0)) # n_i>>n_n T_e=1 @long run_test(test_input_chebyshev, 2*π*1.4467, -2*π*0.6020, @@ -548,7 +548,7 @@ function run_test_set_chebyshev() 0.0008923624901804128, 0.0008994953327500175, 0.0008923624901804128]; ion_species_1 = OptionsDict("initial_density" => 0.9999), neutral_species_1 = OptionsDict("initial_density" => 0.0001), - charge_exchange_frequency=2*π*2.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*2.0)) # n_i< 0.0001), neutral_species_1 = OptionsDict("initial_density" => 0.9999), - charge_exchange_frequency=2*π*2.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*2.0)) # n_i=n_n T_e=0.5 @long run_test(test_input_chebyshev, 2*π*1.2671, -2*π*0.8033, @@ -569,12 +569,12 @@ function run_test_set_chebyshev() -0.34607740653471614, -0.34607384011343095, -0.34607740653471614], 30; composition = OptionsDict("T_e" => 0.5), timestepping = OptionsDict("nstep" => 1300), - charge_exchange_frequency=2*π*0.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*0.0)) @long run_test(test_input_chebyshev, 2*π*0.0, -2*π*0.2727, [-0.34657359027997264, -0.34629088790428314, -0.34612578140467837, -0.34607740653471614, -0.34607384011343095, -0.34607740653471614]; composition = OptionsDict("T_e" => 0.5), - charge_exchange_frequency=2*π*2.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*2.0)) # n_i=n_n T_e=4 @long run_test(test_input_chebyshev, 2*π*1.9919, -2*π*0.2491, @@ -589,18 +589,18 @@ function run_test_set_chebyshev_split_1_moment() @long run_test(test_input_chebyshev_split_1_moment, 2*π*1.4467, -2*π*0.6020, [-0.6931471805599453, -0.6925817758085663, -0.6922515628093567, -0.6921548130694323, -0.6921476802268619, -0.6921548130694323]; - charge_exchange_frequency=2*π*0.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*0.0)) run_test(test_input_chebyshev_split_1_moment, 2*π*1.4240, -2*π*0.6379, [-0.6931471805599453, -0.6925817758085663, -0.6922515628093567, -0.6921548130694323, -0.6921476802268619, -0.6921548130694323]) @long run_test(test_input_chebyshev_split_1_moment, 2*π*0.0, -2*π*0.3235, [-0.6931471805599453, -0.6925817758085663, -0.6922515628093567, -0.6921548130694323, -0.6921476802268619, -0.6921548130694323]; - charge_exchange_frequency=2*π*1.8) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*1.8)) @long run_test(test_input_chebyshev_split_1_moment, 2*π*0.0, -2*π*0.2963, [-0.6931471805599453, -0.6925817758085663, -0.6922515628093567, -0.6921548130694323, -0.6921476802268619, -0.6921548130694323]; - charge_exchange_frequency=2*π*2.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*2.0)) # n_i>>n_n T_e=1 @long run_test(test_input_chebyshev_split_1_moment, 2*π*1.4467, -2*π*0.6020, @@ -615,7 +615,7 @@ function run_test_set_chebyshev_split_1_moment() 0.0008923624901797472]; ion_species_1 = OptionsDict("initial_density" => 0.9999), neutral_species_1 = OptionsDict("initial_density" => 0.0001), - charge_exchange_frequency=2*π*2.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*2.0)) # n_i< 0.0001), neutral_species_1 = OptionsDict("initial_density" => 0.9999), - charge_exchange_frequency=2*π*2.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*2.0)) # n_i=n_n T_e=0.5 @long run_test(test_input_chebyshev_split_1_moment, 2*π*1.2671, -2*π*0.8033, @@ -636,12 +636,12 @@ function run_test_set_chebyshev_split_1_moment() -0.34607740653471614, -0.34607384011343095, -0.34607740653471614], 30; composition = OptionsDict("T_e" => 0.5), timestepping = OptionsDict("nstep" => 1300), - charge_exchange_frequency=2*π*0.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*0.0)) @long run_test(test_input_chebyshev_split_1_moment, 2*π*0.0, -2*π*0.2727, [-0.34657359027997264, -0.34629088790428314, -0.34612578140467837, -0.34607740653471614, -0.34607384011343095, -0.34607740653471614]; composition = OptionsDict("T_e" => 0.5), - charge_exchange_frequency=2*π*2.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*2.0)) # n_i=n_n T_e=4 @long run_test(test_input_chebyshev_split_1_moment, 2*π*1.9919, -2*π*0.2491, @@ -656,18 +656,18 @@ function run_test_set_chebyshev_split_2_moments() @long run_test(test_input_chebyshev_split_2_moments, 2*π*1.4467, -2*π*0.6020, [-0.6931471805599453, -0.6925817758085663, -0.6922515628093567, -0.6921548130694323, -0.6921476802268619, -0.6921548130694323]; - charge_exchange_frequency=2*π*0.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*0.0)) run_test(test_input_chebyshev_split_2_moments, 2*π*1.4240, -2*π*0.6379, [-0.6931471805599453, -0.6925817758085663, -0.6922515628093567, -0.6921548130694323, -0.6921476802268619, -0.6921548130694323]) @long run_test(test_input_chebyshev_split_2_moments, 2*π*0.0, -2*π*0.3235, [-0.6931471805599453, -0.6925817758085663, -0.6922515628093567, -0.6921548130694323, -0.6921476802268619, -0.6921548130694323]; - charge_exchange_frequency=2*π*1.8) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*1.8)) @long run_test(test_input_chebyshev_split_2_moments, 2*π*0.0, -2*π*0.2963, [-0.6931471805599453, -0.6925817758085663, -0.6922515628093567, -0.6921548130694323, -0.6921476802268619, -0.6921548130694323]; - charge_exchange_frequency=2*π*2.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*2.0)) # n_i>>n_n T_e=1 @long run_test(test_input_chebyshev_split_2_moments, 2*π*1.4467, -2*π*0.6020, @@ -682,7 +682,7 @@ function run_test_set_chebyshev_split_2_moments() 0.0008923624901797472]; ion_species_1 = OptionsDict("initial_density" => 0.9999), neutral_species_1 = OptionsDict("initial_density" => 0.0001), - charge_exchange_frequency=2*π*2.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*2.0)) # n_i< 0.0001), neutral_species_1 = OptionsDict("initial_density" => 0.9999), - charge_exchange_frequency=2*π*2.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*2.0)) # n_i=n_n T_e=0.5 @long run_test(test_input_chebyshev_split_2_moments, 2*π*1.2671, -2*π*0.8033, @@ -703,12 +703,12 @@ function run_test_set_chebyshev_split_2_moments() -0.34607740653471614, -0.34607384011343095, -0.34607740653471614], 40; composition = OptionsDict("T_e" => 0.5), timestepping = OptionsDict("nstep" => 1300, "nwrite" => 10), - charge_exchange_frequency=2*π*0.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*0.0)) @long run_test(test_input_chebyshev_split_2_moments, 2*π*0.0, -2*π*0.2727, [-0.34657359027997264, -0.34629088790428314, -0.34612578140467837, -0.34607740653471614, -0.34607384011343095, -0.34607740653471614]; composition = OptionsDict("T_e" => 0.5), - charge_exchange_frequency=2*π*2.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*2.0)) # n_i=n_n T_e=4 @long run_test(test_input_chebyshev_split_2_moments, 2*π*1.9919, -2*π*0.2491, @@ -723,18 +723,18 @@ function run_test_set_chebyshev_split_3_moments() @long run_test(test_input_chebyshev_split_3_moments, 2*π*1.4467, -2*π*0.6020, [-0.6931471805599453, -0.6925817758085663, -0.6922515628093567, -0.6921548130694323, -0.6921476802268619, -0.6921548130694323]; - charge_exchange_frequency=2*π*0.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*0.0)) run_test(test_input_chebyshev_split_3_moments, 2*π*1.4240, -2*π*0.6379, [-0.6931471805599453, -0.6925817758085663, -0.6922515628093567, -0.6921548130694323, -0.6921476802268619, -0.6921548130694323]) @long run_test(test_input_chebyshev_split_3_moments, 2*π*0.0, -2*π*0.3235, [-0.6931471805599453, -0.6925817758085663, -0.6922515628093567, -0.6921548130694323, -0.6921476802268619, -0.6921548130694323]; - charge_exchange_frequency=2*π*1.8) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*1.8)) @long run_test(test_input_chebyshev_split_3_moments, 2*π*0.0, -2*π*0.2963, [-0.6931471805599453, -0.6925817758085663, -0.6922515628093567, -0.6921548130694323, -0.6921476802268619, -0.6921548130694323]; - charge_exchange_frequency=2*π*2.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*2.0)) # n_i>>n_n T_e=1 @long run_test(test_input_chebyshev_split_3_moments, 2*π*1.4467, -2*π*0.6020, @@ -749,7 +749,7 @@ function run_test_set_chebyshev_split_3_moments() 0.0008923624901797472]; ion_species_1 = OptionsDict("initial_density" => 0.9999), neutral_species_1 = OptionsDict("initial_density" => 0.0001), - charge_exchange_frequency=2*π*2.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*2.0)) # n_i< 0.0001), neutral_species_1 = OptionsDict("initial_density" => 0.9999), - charge_exchange_frequency=2*π*2.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*2.0)) # n_i=n_n T_e=0.5 @long run_test(test_input_chebyshev_split_3_moments, 2*π*1.2671, -2*π*0.8033, @@ -770,12 +770,12 @@ function run_test_set_chebyshev_split_3_moments() -0.34607740653471614, -0.34607384011343095, -0.34607740653471614], 80; composition = OptionsDict("T_e" => 0.5), timestepping = OptionsDict("nstep" => 1300, "nwrite" => 5), - charge_exchange_frequency=2*π*0.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*0.0)) @long run_test(test_input_chebyshev_split_3_moments, 2*π*0.0, -2*π*0.2727, [-0.34657359027997264, -0.34629088790428314, -0.34612578140467837, -0.34607740653471614, -0.34607384011343095, -0.34607740653471614]; composition = OptionsDict("T_e" => 0.5), - charge_exchange_frequency=2*π*2.0) + reactions=OptionsDict("charge_exchange_frequency"=>2*π*2.0)) # n_i=n_n T_e=4 @long run_test(test_input_chebyshev_split_3_moments, 2*π*1.9919, -2*π*0.2491, diff --git a/moment_kinetics/test/wall_bc_tests.jl b/moment_kinetics/test/wall_bc_tests.jl index 6f8db0ac8..2f04c10ad 100644 --- a/moment_kinetics/test/wall_bc_tests.jl +++ b/moment_kinetics/test/wall_bc_tests.jl @@ -59,9 +59,8 @@ test_input_finite_difference = OptionsDict("composition" => OptionsDict("n_ion_s "parallel_flow" => false, "parallel_pressure" => false, "moments_conservation" => false), - "charge_exchange_frequency" => 2.0, - "ionization_frequency" => 2.0, - "constant_ionization_rate" => false, + "reactions" => OptionsDict("charge_exchange_frequency" => 2.0, + "ionization_frequency" => 2.0), "timestepping" => OptionsDict("nstep" => 10000, "dt" => 1.0e-5, "nwrite" => 100, diff --git a/util/precompile_run.jl b/util/precompile_run.jl index b0f16ecd3..bb1f460fe 100644 --- a/util/precompile_run.jl +++ b/util/precompile_run.jl @@ -57,7 +57,7 @@ inputs_list = Vector{OptionsDict}(undef, 0) for input ∈ [base_input, cheb_input, wall_bc_input, wall_bc_cheb_input] push!(inputs_list, input) x = recursive_merge(input, OptionsDict("evolve_moments" => OptionsDict("density" => true), - "ionization_frequency" => 0.0, + "reactions" => OptionsDict("ionization_frequency" => 0.0), "r" => OptionsDict("ngrid" => 1, "nelement" => 1), "vperp" => OptionsDict("ngrid" => 1, "nelement" => 1), "vzeta" => OptionsDict("ngrid" => 1, "nelement" => 1), diff --git a/util/precompile_run_long.jl b/util/precompile_run_long.jl index 3626cb0c7..53274805b 100644 --- a/util/precompile_run_long.jl +++ b/util/precompile_run_long.jl @@ -33,7 +33,7 @@ inputs_list = Vector{OptionsDict}(undef, 0) for input ∈ [base_input, cheb_input, wall_bc_input, wall_bc_cheb_input] push!(inputs_list, input) x = recursive_merge(input, OptionsDict("evolve_moments" => OptionsDict("density" => true), - "ionization_frequency" => 0.0)) + "reactions" => OptionsDict("ionization_frequency" => 0.0))) push!(inputs_list, x) x = recursive_merge(x, OptionsDict("evolve_moments" => OptionsDict("parallel_flow" => true))) push!(inputs_list, x) From 554dc7eead027615a3dafafb997bbce7414def32 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Sun, 8 Sep 2024 21:33:13 +0100 Subject: [PATCH 31/87] Update performance-tests and publication_inputs with new input sections --- performance-tests/sound_wave-2xres.jl | 56 ++++++------ performance-tests/sound_wave.jl | 56 ++++++------ .../sound-wave/plot_dispersion_relation.jl | 2 +- .../sound-wave/scan_sound-wave_T0.25.toml | 48 ++++++---- .../scan_sound-wave_T0.25_split1.toml | 48 ++++++---- .../scan_sound-wave_T0.25_split2.toml | 48 ++++++---- .../scan_sound-wave_T0.25_split3.toml | 48 ++++++---- .../sound-wave/scan_sound-wave_T0.5.toml | 48 ++++++---- .../scan_sound-wave_T0.5_split1.toml | 48 ++++++---- .../scan_sound-wave_T0.5_split2.toml | 48 ++++++---- .../scan_sound-wave_T0.5_split3.toml | 48 ++++++---- .../sound-wave/scan_sound-wave_T1.toml | 48 ++++++---- .../sound-wave/scan_sound-wave_T1_split1.toml | 48 ++++++---- .../sound-wave/scan_sound-wave_T1_split2.toml | 48 ++++++---- .../sound-wave/scan_sound-wave_T1_split3.toml | 48 ++++++---- .../sound-wave/scan_sound-wave_T2.toml | 52 ++++++----- .../sound-wave/scan_sound-wave_T2_split1.toml | 52 ++++++----- .../sound-wave/scan_sound-wave_T2_split2.toml | 52 ++++++----- .../sound-wave/scan_sound-wave_T2_split3.toml | 52 ++++++----- .../sound-wave/scan_sound-wave_T4.toml | 52 ++++++----- .../sound-wave/scan_sound-wave_T4_split1.toml | 52 ++++++----- .../sound-wave/scan_sound-wave_T4_split2.toml | 52 ++++++----- .../sound-wave/scan_sound-wave_T4_split3.toml | 52 ++++++----- .../sound-wave/scan_sound-wave_nratio.toml | 48 ++++++---- .../scan_sound-wave_nratio_split1.toml | 48 ++++++---- .../scan_sound-wave_nratio_split2.toml | 48 ++++++---- .../scan_sound-wave_nratio_split3.toml | 48 ++++++---- .../wall-bc/wall-bc_recyclefraction0.5.toml | 90 +++++++++++-------- .../wall-bc_recyclefraction0.5_split1.toml | 90 +++++++++++-------- .../wall-bc_recyclefraction0.5_split2.toml | 90 +++++++++++-------- .../wall-bc_recyclefraction0.5_split3.toml | 90 +++++++++++-------- 31 files changed, 985 insertions(+), 673 deletions(-) diff --git a/performance-tests/sound_wave-2xres.jl b/performance-tests/sound_wave-2xres.jl index d5c7ce1f7..89cf2e0b8 100644 --- a/performance-tests/sound_wave-2xres.jl +++ b/performance-tests/sound_wave-2xres.jl @@ -15,36 +15,36 @@ const z_L = 1.0 # always 1 in normalized units? const vpa_L = 8.0 # default inputs for tests -test_input_finite_difference = OptionsDict("n_ion_species" => 1, - "n_neutral_species" => 1, - "boltzmann_electron_response" => true, +test_input_finite_difference = OptionsDict("composition" => OptionsDict("n_ion_species" => 1, + "n_neutral_species" => 1, + "boltzmann_electron_response" => true, + "T_e" => 1.0), "run_name" => "finite_difference", "base_directory" => test_output_directory, - "evolve_moments_density" => false, - "evolve_moments_parallel_flow" => false, - "evolve_moments_parallel_pressure" => false, - "evolve_moments_conservation" => true, - "T_e" => 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.5, - "z_IC_density_phase1" => 0.0, - "z_IC_upar_amplitude1" => 0.0, - "z_IC_upar_phase1" => 0.0, - "z_IC_temperature_amplitude1" => 0.5, - "z_IC_temperature_phase1" => Float64(π), - "z_IC_option2" => "sinusoid", - "z_IC_density_amplitude2" => 0.5, - "z_IC_density_phase2" => Float64(π), - "z_IC_upar_amplitude2" => 0.0, - "z_IC_upar_phase2" => 0.0, - "z_IC_temperature_amplitude2" => 0.5, - "z_IC_temperature_phase2" => 0.0, - "charge_exchange_frequency" => 2*Float64(π)*0.1, - "ionization_frequency" => 0.0, + "evolve_moments" => OptionsDict("density" => false, + "parallel_flow" => false, + "parallel_pressure" => false, + "moments_conservation" => true), + "ion_species_1" => OptionsDict("initial_density" => 0.5, + "initial_temperature" => 1.0), + "neutral_species_1" => OptionsDict("initial_density" => 0.5, + "initial_temperature" => 1.0), + "z_IC_ion_species_1" => OptionsDict("initialization_option" => "sinusoid", + "density_amplitude" => 0.5, + "density_phase" => 0.0, + "upar_amplitude" => 0.0, + "upar_phase" => 0.0, + "temperature_amplitude" => 0.5, + "temperature_phase" => Float64(π)), + "z_IC_neutral_species_1" => OptionsDict("initialization_option2" => "sinusoid", + "density_amplitude" => 0.5, + "density_phase" => Float64(π), + "upar_amplitude" => 0.0, + "upar_phase" => 0.0, + "temperature_amplitude" => 0.5, + "temperature_phase" => 0.0), + "reactions" => OptionsDict("charge_exchange_frequency" => 2*Float64(π)*0.1, + "ionization_frequency" => 0.0), "timestepping" => Dict("nstep" => 100, "dt" => 0.0002, "nwrite" => 200, diff --git a/performance-tests/sound_wave.jl b/performance-tests/sound_wave.jl index 9782bdfa5..fcbf60fe5 100644 --- a/performance-tests/sound_wave.jl +++ b/performance-tests/sound_wave.jl @@ -15,36 +15,36 @@ const z_L = 1.0 # always 1 in normalized units? const vpa_L = 8.0 # default inputs for tests -test_input_finite_difference = OptionsDict("n_ion_species" => 1, - "n_neutral_species" => 1, - "boltzmann_electron_response" => true, +test_input_finite_difference = OptionsDict("composition" => OptionsDict("n_ion_species" => 1, + "n_neutral_species" => 1, + "boltzmann_electron_response" => true, + "T_e" => 1.0), "run_name" => "finite_difference", "base_directory" => test_output_directory, - "evolve_moments_density" => false, - "evolve_moments_parallel_flow" => false, - "evolve_moments_parallel_pressure" => false, - "evolve_moments_conservation" => true, - "T_e" => 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.5, - "z_IC_density_phase1" => 0.0, - "z_IC_upar_amplitude1" => 0.0, - "z_IC_upar_phase1" => 0.0, - "z_IC_temperature_amplitude1" => 0.5, - "z_IC_temperature_phase1" => Float64(π), - "z_IC_option2" => "sinusoid", - "z_IC_density_amplitude2" => 0.5, - "z_IC_density_phase2" => Float64(π), - "z_IC_upar_amplitude2" => 0.0, - "z_IC_upar_phase2" => 0.0, - "z_IC_temperature_amplitude2" => 0.5, - "z_IC_temperature_phase2" => 0.0, - "charge_exchange_frequency" => 2*Float64(π)*0.1, - "ionization_frequency" => 0.0, + "evolve_moments" => OptionsDict("density" => false, + "parallel_flow" => false, + "parallel_pressure" => false, + "moments_conservation" => true), + "ion_species_1" => OptionsDict("initial_density" => 0.5, + "initial_temperature" => 1.0), + "neutral_species_1" => OptionsDict("initial_density" => 0.5, + "initial_temperature" => 1.0), + "z_IC_ion_species_1" => OptionsDict("initialization_option" => "sinusoid", + "z_IC_density_amplitude" => 0.5, + "z_IC_density_phase" => 0.0, + "z_IC_upar_amplitude" => 0.0, + "z_IC_upar_phase" => 0.0, + "z_IC_temperature_amplitude" => 0.5, + "z_IC_temperature_phase" => Float64(π)), + "z_IC_neutral_species_1" => OptionsDict("initialization_option" => "sinusoid", + "density_amplitude" => 0.5, + "density_phase" => Float64(π), + "upar_amplitude" => 0.0, + "upar_phase" => 0.0, + "temperature_amplitude" => 0.5, + "temperature_phase" => 0.0), + "reactions" => OptionsDict("charge_exchange_frequency" => 2*Float64(π)*0.1, + "ionization_frequency" => 0.0), "timestepping" => OptionsDict( "nstep" => 100, "dt" => 0.0005, "nwrite" => 200, diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/plot_dispersion_relation.jl b/publication_inputs/2023_EFTC_jto-poster/sound-wave/plot_dispersion_relation.jl index 81b4e7fc9..e70ea22e5 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/plot_dispersion_relation.jl +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/plot_dispersion_relation.jl @@ -322,7 +322,7 @@ function plot_sim_output!(ax_omega, ax_gamma, sims, ni, nn, Th, Te; kwargs...) omega = zeros(length(sims)) gamma = zeros(length(sims)) for (i, s) ∈ enumerate(sims) - Ri[i] = s["charge_exchange_frequency"] + Ri[i] = s["reactions"]["charge_exchange_frequency"] omega[i], gamma[i] = get_sim_omega_gamma(s) end diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25.toml index bf8e7c825..e54769974 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25.toml @@ -1,26 +1,36 @@ -#combine_outer = ["charge_exchange_frequency"] +[composition] n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true T_e = 1.0 -initial_density1 = 1.0 -initial_temperature1 = 0.25 -initial_density2 = 1.0 -initial_temperature2 = 0.25 -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 + +[ion_species_1] +initial_density = 1.0 +initial_temperature = 0.25 + +[neutral_species_1] +initial_density = 1.0 +initial_temperature = 0.25 + +[z_IC_ion_species_1] +initialization_option = "sinusoid" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[z_IC_neutral_species_1] +initialization_option = "sinusoid" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[reactions] charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0] ionization_frequency = 0.0 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split1.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split1.toml index 5846198a3..db007115c 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split1.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split1.toml @@ -1,26 +1,36 @@ -#combine_outer = ["charge_exchange_frequency"] +[composition] n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true T_e = 1.0 -initial_density1 = 1.0 -initial_temperature1 = 0.25 -initial_density2 = 1.0 -initial_temperature2 = 0.25 -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 + +[ion_species_1] +initial_density = 1.0 +initial_temperature = 0.25 + +[neutral_species_1] +initial_density = 1.0 +initial_temperature = 0.25 + +[z_IC_ion_species_1] +initialization_option = "sinusoid" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[z_IC_neutral_species_1] +initialization_option = "sinusoid" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[reactions] charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0] ionization_frequency = 0.0 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split2.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split2.toml index 89def9819..9d1de4309 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split2.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split2.toml @@ -1,26 +1,36 @@ -#combine_outer = ["charge_exchange_frequency"] +[composition] n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true T_e = 1.0 -initial_density1 = 1.0 -initial_temperature1 = 0.25 -initial_density2 = 1.0 -initial_temperature2 = 0.25 -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 + +[ion_species_1] +initial_density = 1.0 +initial_temperature = 0.25 + +[neutral_species_1] +initial_density = 1.0 +initial_temperature = 0.25 + +[z_IC_ion_species_1] +initialization_option = "sinusoid" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[z_IC_neutral_species_1] +initialization_option = "sinusoid" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[reactions] charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0] ionization_frequency = 0.0 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split3.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split3.toml index 45b33495c..f5df609a0 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split3.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split3.toml @@ -1,26 +1,36 @@ -#combine_outer = ["charge_exchange_frequency"] +[composition] n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true T_e = 1.0 -initial_density1 = 1.0 -initial_temperature1 = 0.25 -initial_density2 = 1.0 -initial_temperature2 = 0.25 -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 + +[ion_species_1] +initial_density = 1.0 +initial_temperature = 0.25 + +[neutral_species_1] +initial_density = 1.0 +initial_temperature = 0.25 + +[z_IC_ion_species_1] +initialization_option = "sinusoid" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[z_IC_neutral_species_1] +initialization_option = "sinusoid" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[reactions] charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0] ionization_frequency = 0.0 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5.toml index 3c5b7273f..cf51ff298 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5.toml @@ -1,26 +1,36 @@ -#combine_outer = ["charge_exchange_frequency"] +[composition] n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true T_e = 1.0 -initial_density1 = 1.0 -initial_temperature1 = 0.5 -initial_density2 = 1.0 -initial_temperature2 = 0.5 -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 + +[ion_species_1] +initial_density = 1.0 +initial_temperature = 0.5 + +[neutral_species_1] +initial_density = 1.0 +initial_temperature = 0.5 + +[z_IC_ion_species_1] +initialization_option = "sinusoid" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[z_IC_neutral_species_1] +initialization_option = "sinusoid" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[reactions] charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4] ionization_frequency = 0.0 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split1.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split1.toml index 00484fac2..4ca0d7910 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split1.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split1.toml @@ -1,26 +1,36 @@ -#combine_outer = ["charge_exchange_frequency"] +[composition] n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true T_e = 1.0 -initial_density1 = 1.0 -initial_temperature1 = 0.5 -initial_density2 = 1.0 -initial_temperature2 = 0.5 -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 + +[ion_species_1] +initial_density = 1.0 +initial_temperature = 0.5 + +[neutral_species_1] +initial_density = 1.0 +initial_temperature = 0.5 + +[z_IC_ion_species_1] +initialization_option = "sinusoid" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[z_IC_neutral_species_1] +initialization_option = "sinusoid" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[reactions] charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4] ionization_frequency = 0.0 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split2.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split2.toml index 01243b9ba..5d4612b37 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split2.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split2.toml @@ -1,26 +1,36 @@ -#combine_outer = ["charge_exchange_frequency"] +[composition] n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true T_e = 1.0 -initial_density1 = 1.0 -initial_temperature1 = 0.5 -initial_density2 = 1.0 -initial_temperature2 = 0.5 -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 + +[ion_species_1] +initial_density = 1.0 +initial_temperature = 0.5 + +[neutral_species_1] +initial_density = 1.0 +initial_temperature = 0.5 + +[z_IC_ion_species_1] +initialization_option = "sinusoid" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[z_IC_neutral_species_1] +initialization_option = "sinusoid" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[reactions] charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4] ionization_frequency = 0.0 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split3.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split3.toml index 1ea2a6e2f..9c7c02a85 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split3.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split3.toml @@ -1,26 +1,36 @@ -#combine_outer = ["charge_exchange_frequency"] +[composition] n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true T_e = 1.0 -initial_density1 = 1.0 -initial_temperature1 = 0.5 -initial_density2 = 1.0 -initial_temperature2 = 0.5 -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 + +[ion_species_1] +initial_density = 1.0 +initial_temperature = 0.5 + +[neutral_species_1] +initial_density = 1.0 +initial_temperature = 0.5 + +[z_IC_ion_species_1] +initialization_option = "sinusoid" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[z_IC_neutral_species_1] +initialization_option = "sinusoid" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[reactions] charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4] ionization_frequency = 0.0 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1.toml index 579ee0180..70852e647 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1.toml @@ -1,26 +1,36 @@ -#combine_outer = ["charge_exchange_frequency"] +[composition] n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true T_e = 1.0 -initial_density1 = 1.0 -initial_temperature1 = 1.0 -initial_density2 = 1.0 -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 + +[ion_species_1] +initial_density = 1.0 +initial_temperature = 1.0 + +[neutral_species_1] +initial_density = 1.0 +initial_temperature = 1.0 + +[z_IC_ion_species_1] +initialization_option = "sinusoid" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[z_IC_neutral_species_1] +initialization_option = "sinusoid" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[reactions] charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0, 5.2, 5.4, 5.6, 5.8, 6.0, 6.2] ionization_frequency = 0.0 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split1.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split1.toml index 8ea1bfcd7..981eda062 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split1.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split1.toml @@ -1,26 +1,36 @@ -#combine_outer = ["charge_exchange_frequency"] +[composition] n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true T_e = 1.0 -initial_density1 = 1.0 -initial_temperature1 = 1.0 -initial_density2 = 1.0 -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 + +[ion_species_1] +initial_density = 1.0 +initial_temperature = 1.0 + +[neutral_species_1] +initial_density = 1.0 +initial_temperature = 1.0 + +[z_IC_ion_species_1] +initialization_option = "sinusoid" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[z_IC_neutral_species_1] +initialization_option = "sinusoid" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[reactions] charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0, 5.2, 5.4, 5.6, 5.8, 6.0, 6.2] ionization_frequency = 0.0 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split2.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split2.toml index c38218c08..d1a21053f 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split2.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split2.toml @@ -1,26 +1,36 @@ -#combine_outer = ["charge_exchange_frequency"] +[composition] n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true T_e = 1.0 -initial_density1 = 1.0 -initial_temperature1 = 1.0 -initial_density2 = 1.0 -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 + +[ion_species_1] +initial_density = 1.0 +initial_temperature = 1.0 + +[neutral_species_1] +initial_density = 1.0 +initial_temperature = 1.0 + +[z_IC_ion_species_1] +initialization_option = "sinusoid" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[z_IC_neutral_species_1] +initialization_option = "sinusoid" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[reactions] charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0, 5.2, 5.4, 5.6, 5.8, 6.0, 6.2] ionization_frequency = 0.0 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split3.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split3.toml index 6bdcdd1e6..283f10461 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split3.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split3.toml @@ -1,26 +1,36 @@ -#combine_outer = ["charge_exchange_frequency"] +[composition] n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true T_e = 1.0 -initial_density1 = 1.0 -initial_temperature1 = 1.0 -initial_density2 = 1.0 -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 + +[ion_species_1] +initial_density = 1.0 +initial_temperature = 1.0 + +[neutral_species_1] +initial_density = 1.0 +initial_temperature = 1.0 + +[z_IC_ion_species_1] +initialization_option = "sinusoid" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[z_IC_neutral_species_1] +initialization_option = "sinusoid" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[reactions] charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0, 5.2, 5.4, 5.6, 5.8, 6.0, 6.2] ionization_frequency = 0.0 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2.toml index 16aa4ee80..679af654d 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2.toml @@ -1,28 +1,38 @@ -#combine_outer = ["charge_exchange_frequency"] +[composition] n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true T_e = 1.0 -initial_density1 = 1.0 -initial_temperature1 = 2.0 -initial_density2 = 1.0 -initial_temperature2 = 2.0 -z_IC_option1 = "sinusoid" -#z_IC_density_amplitude1 = 0.001 -z_IC_density_amplitude1 = 0.01 -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_amplitude2 = 0.01 -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 + +[ion_species_1] +initial_density = 1.0 +initial_temperature = 2.0 + +[neutral_species_1] +initial_density = 1.0 +initial_temperature = 2.0 + +[z_IC_ion_species_1] +initialization_option1 = "sinusoid" +#density_amplitude = 0.001 +density_amplitude = 0.01 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[z_IC_neutral_species_1] +initialization_option = "sinusoid" +#density_amplitude = 0.001 +density_amplitude = 0.01 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[reactions] charge_exchange_frequency = [0.0, 0.3, 0.6, 0.9, 1.2, 1.5, 1.8, 2.1, 2.4, 2.7, 3.0, 3.3, 3.6, 3.9, 4.2, 4.5, 4.8, 5.1, 5.4, 5.7, 6.0, 6.3, 6.6, 6.9, 7.2, 7.5, 7.8, 8.1, 8.4, 8.7] ionization_frequency = 0.0 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split1.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split1.toml index b7db6fe1e..a1a3dcbe4 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split1.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split1.toml @@ -1,28 +1,38 @@ -#combine_outer = ["charge_exchange_frequency"] +[composition] n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true T_e = 1.0 -initial_density1 = 1.0 -initial_temperature1 = 2.0 -initial_density2 = 1.0 -initial_temperature2 = 2.0 -z_IC_option1 = "sinusoid" -#z_IC_density_amplitude1 = 0.001 -z_IC_density_amplitude1 = 0.01 -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_amplitude2 = 0.01 -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 + +[ion_species_1] +initial_density = 1.0 +initial_temperature = 2.0 + +[neutral_species_1] +initial_density = 1.0 +initial_temperature = 2.0 + +[z_IC_ion_species_1] +initialization_option = "sinusoid" +#density_amplitude = 0.001 +density_amplitude = 0.01 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[z_IC_neutral_species_1] +initialization_option = "sinusoid" +#density_amplitude = 0.001 +density_amplitude = 0.01 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[reactions] charge_exchange_frequency = [0.0, 0.3, 0.6, 0.9, 1.2, 1.5, 1.8, 2.1, 2.4, 2.7, 3.0, 3.3, 3.6, 3.9, 4.2, 4.5, 4.8, 5.1, 5.4, 5.7, 6.0, 6.3, 6.6, 6.9, 7.2, 7.5, 7.8, 8.1, 8.4, 8.7] ionization_frequency = 0.0 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split2.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split2.toml index ef3ce7ed2..82ae1e54c 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split2.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split2.toml @@ -1,28 +1,38 @@ -#combine_outer = ["charge_exchange_frequency"] +[composition] n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true T_e = 1.0 -initial_density1 = 1.0 -initial_temperature1 = 2.0 -initial_density2 = 1.0 -initial_temperature2 = 2.0 -z_IC_option1 = "sinusoid" -#z_IC_density_amplitude1 = 0.001 -z_IC_density_amplitude1 = 0.01 -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_amplitude2 = 0.01 -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 + +[ion_species_1] +initial_density = 1.0 +initial_temperature = 2.0 + +[neutral_species_1] +initial_density = 1.0 +initial_temperature = 2.0 + +[z_IC_ion_species_1] +initialization_option = "sinusoid" +#density_amplitude = 0.001 +density_amplitude = 0.01 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[z_IC_neutral_species_1] +initialization_option = "sinusoid" +#density_amplitude = 0.001 +density_amplitude = 0.01 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[reactions] charge_exchange_frequency = [0.0, 0.3, 0.6, 0.9, 1.2, 1.5, 1.8, 2.1, 2.4, 2.7, 3.0, 3.3, 3.6, 3.9, 4.2, 4.5, 4.8, 5.1, 5.4, 5.7, 6.0, 6.3, 6.6, 6.9, 7.2, 7.5, 7.8, 8.1, 8.4, 8.7] ionization_frequency = 0.0 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split3.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split3.toml index 11207a3a0..c09c17a8d 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split3.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split3.toml @@ -1,28 +1,38 @@ -#combine_outer = ["charge_exchange_frequency"] +[composition] n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true T_e = 1.0 -initial_density1 = 1.0 -initial_temperature1 = 2.0 -initial_density2 = 1.0 -initial_temperature2 = 2.0 -z_IC_option1 = "sinusoid" -#z_IC_density_amplitude1 = 0.001 -z_IC_density_amplitude1 = 0.01 -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_amplitude2 = 0.01 -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 + +[ion_species_1] +initial_density = 1.0 +initial_temperature = 2.0 + +[neutral_species_1] +initial_density = 1.0 +initial_temperature = 2.0 + +[z_IC_ion_species_1] +initialization_option = "sinusoid" +#density_amplitude = 0.001 +density_amplitude = 0.01 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[z_IC_neutral_species_1] +initialization_option = "sinusoid" +#density_amplitude = 0.001 +density_amplitude = 0.01 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[reactions] charge_exchange_frequency = [0.0, 0.3, 0.6, 0.9, 1.2, 1.5, 1.8, 2.1, 2.4, 2.7, 3.0, 3.3, 3.6, 3.9, 4.2, 4.5, 4.8, 5.1, 5.4, 5.7, 6.0, 6.3, 6.6, 6.9, 7.2, 7.5, 7.8, 8.1, 8.4, 8.7] ionization_frequency = 0.0 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4.toml index 9d6f4c967..3e49f9451 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4.toml @@ -1,28 +1,38 @@ -#combine_outer = ["charge_exchange_frequency"] +[composition] n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true T_e = 1.0 -initial_density1 = 1.0 -initial_temperature1 = 4.0 -initial_density2 = 1.0 -initial_temperature2 = 4.0 -z_IC_option1 = "sinusoid" -#z_IC_density_amplitude1 = 0.001 -z_IC_density_amplitude1 = 0.01 -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_amplitude2 = 0.01 -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 + +[ion_species_1] +initial_density = 1.0 +initial_temperature = 4.0 + +[neutral_species_1] +initial_density = 1.0 +initial_temperature = 4.0 + +[z_IC_ion_species_1] +initialization_option = "sinusoid" +#density_amplitude = 0.001 +density_amplitude = 0.01 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[z_IC_neutral_species_1] +initialization_option = "sinusoid" +#density_amplitude = 0.001 +density_amplitude = 0.01 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[reactions] charge_exchange_frequency = [0.0, 0.4, 0.8, 1.2, 1.6, 2.0, 2.4, 2.8, 3.2, 3.6, 4.0, 4.4, 4.8, 5.2, 5.6, 6.0, 6.4, 6.8, 7.2, 7.6, 8.0, 8.4, 8.8, 9.2, 9.6, 10.0, 10.4, 10.8, 11.2, 11.6, 12.0, 12.4] ionization_frequency = 0.0 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split1.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split1.toml index c53b67536..67d423e57 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split1.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split1.toml @@ -1,28 +1,38 @@ -#combine_outer = ["charge_exchange_frequency"] +[composition] n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true T_e = 1.0 -initial_density1 = 1.0 -initial_temperature1 = 4.0 -initial_density2 = 1.0 -initial_temperature2 = 4.0 -z_IC_option1 = "sinusoid" -#z_IC_density_amplitude1 = 0.001 -z_IC_density_amplitude1 = 0.01 -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_amplitude2 = 0.01 -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 + +[ion_species_1] +initial_density = 1.0 +initial_temperature = 4.0 + +[neutral_species_1] +initial_density = 1.0 +initial_temperature = 4.0 + +[z_IC_ion_species_1] +initialization_option = "sinusoid" +#density_amplitude = 0.001 +density_amplitude = 0.01 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[z_IC_neutral_species_1] +initialization_option = "sinusoid" +#density_amplitude = 0.001 +density_amplitude = 0.01 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[reactions] charge_exchange_frequency = [0.0, 0.4, 0.8, 1.2, 1.6, 2.0, 2.4, 2.8, 3.2, 3.6, 4.0, 4.4, 4.8, 5.2, 5.6, 6.0, 6.4, 6.8, 7.2, 7.6, 8.0, 8.4, 8.8, 9.2, 9.6, 10.0, 10.4, 10.8, 11.2, 11.6, 12.0, 12.4] ionization_frequency = 0.0 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split2.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split2.toml index 19b439740..27da1a60a 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split2.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split2.toml @@ -1,28 +1,38 @@ -#combine_outer = ["charge_exchange_frequency"] +[composition] n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true T_e = 1.0 -initial_density1 = 1.0 -initial_temperature1 = 4.0 -initial_density2 = 1.0 -initial_temperature2 = 4.0 -z_IC_option1 = "sinusoid" -#z_IC_density_amplitude1 = 0.001 -z_IC_density_amplitude1 = 0.01 -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_amplitude2 = 0.01 -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 + +[ion_species_1] +initial_density = 1.0 +initial_temperature = 4.0 + +[neutral_species_1] +initial_density = 1.0 +initial_temperature = 4.0 + +[z_IC_ion_species_1] +initialization_option = "sinusoid" +#density_amplitude = 0.001 +density_amplitude = 0.01 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[z_IC_neutral_species_1] +initialization_option = "sinusoid" +#density_amplitude = 0.001 +density_amplitude = 0.01 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[reactions] charge_exchange_frequency = [0.0, 0.4, 0.8, 1.2, 1.6, 2.0, 2.4, 2.8, 3.2, 3.6, 4.0, 4.4, 4.8, 5.2, 5.6, 6.0, 6.4, 6.8, 7.2, 7.6, 8.0, 8.4, 8.8, 9.2, 9.6, 10.0, 10.4, 10.8, 11.2, 11.6, 12.0, 12.4] ionization_frequency = 0.0 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split3.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split3.toml index 78fbbdaa0..fa4145c0f 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split3.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split3.toml @@ -1,28 +1,38 @@ -#combine_outer = ["charge_exchange_frequency"] +[composition] n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true T_e = 1.0 -initial_density1 = 1.0 -initial_temperature1 = 4.0 -initial_density2 = 1.0 -initial_temperature2 = 4.0 -z_IC_option1 = "sinusoid" -#z_IC_density_amplitude1 = 0.001 -z_IC_density_amplitude1 = 0.01 -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_amplitude2 = 0.01 -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 + +[ion_species_1] +initial_density = 1.0 +initial_temperature = 4.0 + +[neutral_species_1] +initial_density = 1.0 +initial_temperature = 4.0 + +[z_IC_ion_species_1] +initialization_option = "sinusoid" +#density_amplitude = 0.001 +density_amplitude = 0.01 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[z_IC_neutral_species_1] +initialization_option = "sinusoid" +#density_amplitude = 0.001 +density_amplitude = 0.01 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[reactions] charge_exchange_frequency = [0.0, 0.4, 0.8, 1.2, 1.6, 2.0, 2.4, 2.8, 3.2, 3.6, 4.0, 4.4, 4.8, 5.2, 5.6, 6.0, 6.4, 6.8, 7.2, 7.6, 8.0, 8.4, 8.8, 9.2, 9.6, 10.0, 10.4, 10.8, 11.2, 11.6, 12.0, 12.4] ionization_frequency = 0.0 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio.toml index de5d9f502..6f35c0f67 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio.toml @@ -1,26 +1,38 @@ combine_outer = ["charge_exchange_frequency"] + +[composition] n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true T_e = 1.0 -initial_density1 = [1.0e-5, 0.5, 1.0, 1.5, 1.99999] -initial_temperature1 = 1.0 -initial_density2 = [1.99999, 1.5, 1.0, 0.5, 1.0e-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 + +[ion_species_1] +initial_density = [1.0e-5, 0.5, 1.0, 1.5, 1.99999] +initial_temperature = 1.0 + +[neutral_species_1] +initial_density = [1.99999, 1.5, 1.0, 0.5, 1.0e-5] +initial_temperature = 1.0 + +[z_IC_ion_species_1] +initialization_option = "sinusoid" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[z_IC_neutral_species_1] +initialization_option = "sinusoid" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[reactions] charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0, 5.2, 5.4, 5.6, 5.8, 6.0, 6.2] ionization_frequency = 0.0 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split1.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split1.toml index b9d344468..10806bd86 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split1.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split1.toml @@ -1,26 +1,38 @@ combine_outer = ["charge_exchange_frequency"] + +[composition] n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true T_e = 1.0 -initial_density1 = [1.0e-5, 0.5, 1.0, 1.5, 1.99999] -initial_temperature1 = 1.0 -initial_density2 = [1.99999, 1.5, 1.0, 0.5, 1.0e-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 + +[ion_species_1] +initial_density = [1.0e-5, 0.5, 1.0, 1.5, 1.99999] +initial_temperature = 1.0 + +[neutral_species_1] +initial_density = [1.99999, 1.5, 1.0, 0.5, 1.0e-5] +initial_temperature = 1.0 + +[z_IC_ion_species_1] +initialization_option = "sinusoid" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[z_IC_neutral_species_1] +initialization_option = "sinusoid" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[reactions] charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0, 5.2, 5.4, 5.6, 5.8, 6.0, 6.2] ionization_frequency = 0.0 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split2.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split2.toml index d13ea7922..e5b2640be 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split2.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split2.toml @@ -1,26 +1,38 @@ combine_outer = ["charge_exchange_frequency"] + +[composition] n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true T_e = 1.0 -initial_density1 = [1.0e-5, 0.5, 1.0, 1.5, 1.99999] -initial_temperature1 = 1.0 -initial_density2 = [1.99999, 1.5, 1.0, 0.5, 1.0e-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 + +[z_IC_ion_species_1] +initial_density = [1.0e-5, 0.5, 1.0, 1.5, 1.99999] +initial_temperature = 1.0 + +[neutral_species_1] +initial_density = [1.99999, 1.5, 1.0, 0.5, 1.0e-5] +initial_temperature = 1.0 + +[z_IC_ion_species_1] +initialization_option = "sinusoid" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[z_IC_neutral_species_1] +initialization_option = "sinusoid" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[reactions] charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0, 5.2, 5.4, 5.6, 5.8, 6.0, 6.2] ionization_frequency = 0.0 diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split3.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split3.toml index dcf6ab027..057498646 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split3.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split3.toml @@ -1,26 +1,38 @@ combine_outer = ["charge_exchange_frequency"] + +[composition] n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true T_e = 1.0 -initial_density1 = [1.0e-5, 0.5, 1.0, 1.5, 1.99999] -initial_temperature1 = 1.0 -initial_density2 = [1.99999, 1.5, 1.0, 0.5, 1.0e-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 + +[ion_species_1] +initial_density = [1.0e-5, 0.5, 1.0, 1.5, 1.99999] +initial_temperature = 1.0 + +[neutral_species_1] +initial_density = [1.99999, 1.5, 1.0, 0.5, 1.0e-5] +initial_temperature = 1.0 + +[z_IC_ion_species_1] +initialization_option = "sinusoid" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[z_IC_neutral_species_1] +initialization_option = "sinusoid" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[reactions] charge_exchange_frequency = [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0, 5.2, 5.4, 5.6, 5.8, 6.0, 6.2] ionization_frequency = 0.0 diff --git a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5.toml b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5.toml index 724358eda..610092090 100644 --- a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5.toml +++ b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5.toml @@ -1,48 +1,62 @@ -steady_state_residual = true -converged_residual_value = 1.0e-3 -#runtime_plots = true +[composition] n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true recycling_fraction = 0.5 -krook_collisions_option = "reference_parameters" T_e = 0.2 # 1.0 T_wall = 0.1 -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 + +[krook_collisions] +use_krook = true +frequency_option = "reference_parameters" + +[ion_species_1] +initial_density = 1.0 +initial_temperature = 1.0 + +[z_IC_ion_species_1] +initialization_option = "gaussian" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = 1.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[vpa_IC_ion_species_1] +initialization_option = "gaussian" +density_amplitude = 1.0 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[neutral_species_1] +initial_density = 1.0 +initial_temperature = 1.0 + +[z_IC_neutral_species_1] +initialization_option = "gaussian" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = -1.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[vz_IC_neutral_species_1] +initialization_option = "gaussian" +density_amplitude = 1.0 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[reactions] charge_exchange_frequency = 0.75 ionization_frequency = 0.5 -constant_ionization_rate = false [evolve_moments] density = false @@ -84,6 +98,8 @@ nwrite = 10000 nwrite_dfns = 10000 n_rk_stages = 4 split_operators = false +steady_state_residual = true +converged_residual_value = 1.0e-3 [ion_source] active = true diff --git a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split1.toml b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split1.toml index 6788b8d9a..612d2995f 100644 --- a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split1.toml +++ b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split1.toml @@ -1,48 +1,62 @@ -steady_state_residual = true -converged_residual_value = 1.0e-3 -#runtime_plots = true +[composition] n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true recycling_fraction = 0.5 -krook_collisions_option = "reference_parameters" T_e = 0.2 # 1.0 T_wall = 0.1 -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 + +[krook_collisions] +use_krook = true +frequency_option = "reference_parameters" + +[ion_species_1] +initial_density = 1.0 +initial_temperature = 1.0 + +[z_IC_ion_species_1] +initialization_option = "gaussian" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = 1.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[vpa_IC_ion_species_1] +initialization_option = "gaussian" +density_amplitude = 1.0 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[neutral_species_1] +initial_density = 1.0 +initial_temperature = 1.0 + +[z_IC_neutral_species_1] +initialization_option = "gaussian" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = -1.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[vz_IC_neutral_species_1] +initialization_option = "gaussian" +density_amplitude = 1.0 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[reactions] charge_exchange_frequency = 0.75 ionization_frequency = 0.5 -constant_ionization_rate = false [evolve_moments] density = true @@ -84,6 +98,8 @@ nwrite = 10000 nwrite_dfns = 10000 n_rk_stages = 4 split_operators = false +steady_state_residual = true +converged_residual_value = 1.0e-3 [ion_source] active = true diff --git a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split2.toml b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split2.toml index 312921532..6cecf1645 100644 --- a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split2.toml +++ b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split2.toml @@ -1,48 +1,62 @@ -steady_state_residual = true -converged_residual_value = 1.0e-3 -#runtime_plots = true +[composition] n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true recycling_fraction = 0.5 -krook_collisions_option = "reference_parameters" T_e = 0.2 # 1.0 T_wall = 0.1 -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 + +[krook_collisions] +use_krook = true +frequency_option = "reference_parameters" + +[ion_species_1] +initial_density = 1.0 +initial_temperature = 1.0 + +[z_IC_ion_species_1] +initialization_option = "gaussian" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = 1.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[vpa_IC_ion_species_1] +initialization_option = "gaussian" +density_amplitude = 1.0 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[neutral_species_1] +initial_density = 1.0 +initial_temperature = 1.0 + +[z_IC_neutral_species_1] +initialization_option = "gaussian" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = -1.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[vz_IC_neutral_species_1] +initialization_option = "gaussian" +density_amplitude = 1.0 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[reactions] charge_exchange_frequency = 0.75 ionization_frequency = 0.5 -constant_ionization_rate = false [evolve_moments] density = true @@ -84,6 +98,8 @@ nwrite = 10000 nwrite_dfns = 10000 n_rk_stages = 4 split_operators = false +steady_state_residual = true +converged_residual_value = 1.0e-3 [ion_source] active = true diff --git a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split3.toml b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split3.toml index 4704bfe42..3e4044b2a 100644 --- a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split3.toml +++ b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split3.toml @@ -1,48 +1,62 @@ -steady_state_residual = true -converged_residual_value = 1.0e-3 -#runtime_plots = true +[composition] n_ion_species = 1 n_neutral_species = 1 boltzmann_electron_response = true recycling_fraction = 0.5 -krook_collisions_option = "reference_parameters" T_e = 0.2 # 1.0 T_wall = 0.1 -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 + +[krook_collisions] +use_krook = true +frequency_option = "reference_parameters" + +[ion_species_1] +initial_density = 1.0 +initial_temperature = 1.0 + +[z_IC_ion_species_1] +initialization_option = "gaussian" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = 1.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[vpa_IC_ion_species_1] +initialization_option = "gaussian" +density_amplitude = 1.0 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[neutral_species_1] +initial_density = 1.0 +initial_temperature = 1.0 + +[z_IC_neutral_species_1] +initialization_option = "gaussian" +density_amplitude = 0.001 +density_phase = 0.0 +upar_amplitude = -1.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[vz_IC_neutral_species_1] +initialization_option = "gaussian" +density_amplitude = 1.0 +density_phase = 0.0 +upar_amplitude = 0.0 +upar_phase = 0.0 +temperature_amplitude = 0.0 +temperature_phase = 0.0 + +[reactions] charge_exchange_frequency = 0.75 ionization_frequency = 0.5 -constant_ionization_rate = false [evolve_moments] density = true @@ -84,6 +98,8 @@ nwrite = 10000 nwrite_dfns = 10000 n_rk_stages = 4 split_operators = false +steady_state_residual = true +converged_residual_value = 1.0e-3 [ion_source] active = true From dfc19343041549cfa31241ceb59b79a3b3bfc9fd Mon Sep 17 00:00:00 2001 From: John Omotani Date: Sun, 8 Sep 2024 22:34:56 +0100 Subject: [PATCH 32/87] Move "run_name" and "base_directory" into [output] section --- .../runtest_template.jl | 4 +- .../fokker_planck_collisions_inputs.jl | 2 +- .../debug_test/gyroaverage_inputs.jl | 2 +- .../debug_test/kinetic_electron_inputs.jl | 4 +- moment_kinetics/debug_test/mms_inputs.jl | 2 +- .../debug_test/recycling_fraction_inputs.jl | 10 +-- .../restart_interpolation_inputs.jl | 12 ++-- .../debug_test/restart_interpolation_tests.jl | 4 +- .../debug_test/runtest_template.jl | 2 +- .../debug_test/sound_wave_inputs.jl | 66 +++++++++---------- moment_kinetics/debug_test/wall_bc_inputs.jl | 24 +++---- moment_kinetics/src/moment_kinetics_input.jl | 39 ++++++----- moment_kinetics/src/parameter_scans.jl | 16 ++--- moment_kinetics/src/utils.jl | 2 +- .../test/Krook_collisions_tests.jl | 22 +++---- .../test/braginskii_electrons_imex_tests.jl | 14 ++-- .../fokker_planck_time_evolution_tests.jl | 10 +-- moment_kinetics/test/harrisonthompson.jl | 26 ++++---- ...ear_sound_wave_inputs_and_expected_data.jl | 60 ++++++++--------- .../test/nonlinear_sound_wave_tests.jl | 22 +++---- .../test/recycling_fraction_tests.jl | 42 ++++++------ .../test/restart_interpolation_tests.jl | 42 ++++++------ moment_kinetics/test/sound_wave_tests.jl | 40 +++++------ moment_kinetics/test/wall_bc_tests.jl | 22 +++---- performance-tests/sound_wave-2xres.jl | 18 ++--- performance-tests/sound_wave.jl | 18 ++--- performance-tests/utils.jl | 2 +- .../sound-wave/plot_dispersion_relation.jl | 4 +- util/get-run-name.jl | 3 + util/precompile_makie_plots.jl | 4 +- util/precompile_plots_plots.jl | 4 +- util/precompile_run.jl | 4 +- util/precompile_run_kinetic-electrons.jl | 4 +- util/precompile_run_long.jl | 4 +- util/precompile_run_long_debug1.jl | 4 +- util/precompile_run_short.jl | 4 +- 36 files changed, 287 insertions(+), 275 deletions(-) diff --git a/moment_kinetics/debug_test/debug_redundant_synchronization/runtest_template.jl b/moment_kinetics/debug_test/debug_redundant_synchronization/runtest_template.jl index 32050ead4..17b37e1c9 100644 --- a/moment_kinetics/debug_test/debug_redundant_synchronization/runtest_template.jl +++ b/moment_kinetics/debug_test/debug_redundant_synchronization/runtest_template.jl @@ -7,7 +7,7 @@ function run_test(test_input; args...) # update the default inputs # Convert keyword arguments to a unique name - name = test_input["run_name"] + name = test_input["output"]["run_name"] if length(args) > 0 name = string(name, "_", (string(k, "-", v, "_") for (k, v) in args)...) @@ -25,7 +25,7 @@ function run_test(test_input; args...) # Update default inputs with values to be changed input = merge(test_input, modified_inputs) - input["run_name"] = name + input["output"]["run_name"] = name # run simulation run_moment_kinetics(input) diff --git a/moment_kinetics/debug_test/fokker_planck_collisions_inputs.jl b/moment_kinetics/debug_test/fokker_planck_collisions_inputs.jl index 331bacdfb..6ea191525 100644 --- a/moment_kinetics/debug_test/fokker_planck_collisions_inputs.jl +++ b/moment_kinetics/debug_test/fokker_planck_collisions_inputs.jl @@ -3,7 +3,7 @@ test_type = "Fokker-Planck collisions" # default input for test test_input_full_f = OptionsDict( - "run_name" => "full_f", + "output" => OptionsDict("run_name" => "full_f"), "timestepping" => OptionsDict("dt" => 0.0, "nstep" => 3, "nwrite" => 2, diff --git a/moment_kinetics/debug_test/gyroaverage_inputs.jl b/moment_kinetics/debug_test/gyroaverage_inputs.jl index 47ebb78a5..660df7203 100644 --- a/moment_kinetics/debug_test/gyroaverage_inputs.jl +++ b/moment_kinetics/debug_test/gyroaverage_inputs.jl @@ -3,7 +3,7 @@ test_type = "gyroaverage" # default inputs for tests test_input = OptionsDict( - "run_name" => "gyroaverage", + "output" => OptionsDict("run_name" => "gyroaverage"), "composition" => OptionsDict("n_ion_species" => 1, "n_neutral_species" => 0, "gyrokinetic_ions" => true, diff --git a/moment_kinetics/debug_test/kinetic_electron_inputs.jl b/moment_kinetics/debug_test/kinetic_electron_inputs.jl index 8401049e8..c1304f595 100644 --- a/moment_kinetics/debug_test/kinetic_electron_inputs.jl +++ b/moment_kinetics/debug_test/kinetic_electron_inputs.jl @@ -7,8 +7,8 @@ test_input = OptionsDict("composition" => OptionsDict("n_ion_species" => 1, "recycling_fraction" => 0.5, "T_e" => 0.2, "T_wall" => 0.1), - "run_name" => "kinetic_electron", - "base_directory" => test_output_directory, + "output" => OptionsDict("run_name" => "kinetic_electron", + "base_directory" => test_output_directory), "evolve_moments" => OptionsDict("density" => true, "parallel_flow" => true, "parallel_pressure" => true, diff --git a/moment_kinetics/debug_test/mms_inputs.jl b/moment_kinetics/debug_test/mms_inputs.jl index 4d69e9abf..ce6ddf196 100644 --- a/moment_kinetics/debug_test/mms_inputs.jl +++ b/moment_kinetics/debug_test/mms_inputs.jl @@ -13,7 +13,7 @@ test_input = OptionsDict( "electron_physics" => "boltzmann_electron_response", "T_e" => 1.0, "T_wall" => 1.0), - "run_name" => "MMS-2D-wall_cheb-with-neutrals", + "output" => OptionsDict("run_name" => "MMS-2D-wall_cheb-with-neutrals"), "recations" => OptionsDict("charge_exchange_frequency" => 0.0, "ionization_frequency" => 0.0), "timestepping" => OptionsDict("nstep" => 3, diff --git a/moment_kinetics/debug_test/recycling_fraction_inputs.jl b/moment_kinetics/debug_test/recycling_fraction_inputs.jl index 6d4a8e2a7..5ee3f4b22 100644 --- a/moment_kinetics/debug_test/recycling_fraction_inputs.jl +++ b/moment_kinetics/debug_test/recycling_fraction_inputs.jl @@ -10,8 +10,8 @@ test_input = OptionsDict("composition" => OptionsDict("n_ion_species" => 1, "T_wall" => 2.0), "ion_species_1" => OptionsDict("initial_density" => 1.0, "initial_temperature" => 1.0), - "run_name" => "full-f", - "base_directory" => test_output_directory, + "output" => OptionsDict("run_name" => "full-f", + "base_directory" => test_output_directory), "evolve_moments" => OptionsDict("density" => false, "parallel_flow" => false, "parallel_pressure" => false, @@ -82,16 +82,16 @@ test_input = OptionsDict("composition" => OptionsDict("n_ion_species" => 1, test_input_split1 = recursive_merge(test_input, - OptionsDict("run_name" => "split1", + OptionsDict("output" => OptionsDict("run_name" => "split1"), "evolve_moments" => OptionsDict("density" => true, "moments_conservation" => true))) test_input_split2 = recursive_merge(test_input_split1, - OptionsDict("run_name" => "split2", + OptionsDict("output" => OptionsDict("run_name" => "split2"), "evolve_moments" => OptionsDict("parallel_flow" => true))) test_input_split2["timestepping"] = recursive_merge(test_input_split2["timestepping"], OptionsDict("step_update_prefactor" => 0.4)) test_input_split3 = recursive_merge(test_input_split2, - OptionsDict("run_name" => "split3", + OptionsDict("output" => OptionsDict("run_name" => "split3"), "evolve_moments" => OptionsDict("parallel_pressure" => true), "vpa" => OptionsDict("nelement" => 8), "vz" => OptionsDict("nelement" => 8), diff --git a/moment_kinetics/debug_test/restart_interpolation_inputs.jl b/moment_kinetics/debug_test/restart_interpolation_inputs.jl index 0f4c9a118..6c70b5d30 100644 --- a/moment_kinetics/debug_test/restart_interpolation_inputs.jl +++ b/moment_kinetics/debug_test/restart_interpolation_inputs.jl @@ -4,12 +4,12 @@ using moment_kinetics.utils: recursive_merge # default inputs for tests base_input = OptionsDict( - "run_name" => "base", + "output" => OptionsDict("run_name" => "base", + "base_directory" => test_output_directory), "composition" => OptionsDict("n_ion_species" => 2, "n_neutral_species" => 2, "electron_physics" => "boltzmann_electron_response", "T_e" => 1.0), - "base_directory" => test_output_directory, "evolve_moments" => OptionsDict("density" => false, "parallel_flow" => false, "parallel_pressure" => false, @@ -48,24 +48,24 @@ base_input = OptionsDict( test_input = recursive_merge(base_input, - OptionsDict("run_name" => "full-f", + OptionsDict("output" => OptionsDict("run_name" => "full-f"), "z" => OptionsDict("nelement" => 3), "vpa" => OptionsDict("nelement" => 3), "vz" => OptionsDict("nelement" => 3))) test_input_split1 = recursive_merge(test_input, - OptionsDict("run_name" => "split1", + OptionsDict("output" => OptionsDict("run_name" => "split1"), "evolve_moments" => OptionsDict("density" => true))) test_input_split2 = recursive_merge(test_input_split1 , - OptionsDict("run_name" => "split2", + OptionsDict("output" => OptionsDict("run_name" => "split2"), "evolve_moments" => OptionsDict("parallel_flow" => true))) test_input_split3 = recursive_merge(test_input_split2, - OptionsDict("run_name" => "split3", + OptionsDict("output" => OptionsDict("run_name" => "split3"), "evolve_moments" => OptionsDict("parallel_pressure" => true))) test_input_list = [ diff --git a/moment_kinetics/debug_test/restart_interpolation_tests.jl b/moment_kinetics/debug_test/restart_interpolation_tests.jl index 21faff756..8fea9a42b 100644 --- a/moment_kinetics/debug_test/restart_interpolation_tests.jl +++ b/moment_kinetics/debug_test/restart_interpolation_tests.jl @@ -12,9 +12,9 @@ include("restart_interpolation_inputs.jl") run_moment_kinetics(base_input) if moment_kinetics.file_io.io_has_parallel(Val(moment_kinetics.file_io.hdf5)) - base_output_file = realpath(joinpath(base_input["base_directory"], base_input["run_name"], string(base_input["run_name"], ".dfns.h5"))) + base_output_file = realpath(joinpath(base_input["output"]["base_directory"], base_input["output"]["run_name"], string(base_input["output"]["run_name"], ".dfns.h5"))) else - base_output_file = realpath(joinpath(base_input["base_directory"], base_input["run_name"], string(base_input["run_name"], ".dfns.0.h5"))) + base_output_file = realpath(joinpath(base_input["output"]["base_directory"], base_input["output"]["run_name"], string(base_input["output"]["run_name"], ".dfns.0.h5"))) end # Defines the test functions, using variables defined in the *_inputs.jl file diff --git a/moment_kinetics/debug_test/runtest_template.jl b/moment_kinetics/debug_test/runtest_template.jl index 6f1cb0b4e..224c57ce7 100644 --- a/moment_kinetics/debug_test/runtest_template.jl +++ b/moment_kinetics/debug_test/runtest_template.jl @@ -12,7 +12,7 @@ Run a test for a single set of parameters # Note 'name' should not be shared by any two tests in this file function run_test(test_input, debug_loop_type, debug_loop_parallel_dims; restart=false) - name = test_input["run_name"] + name = test_input["output"]["run_name"] @testset "$name" begin # Provide some progress info diff --git a/moment_kinetics/debug_test/sound_wave_inputs.jl b/moment_kinetics/debug_test/sound_wave_inputs.jl index c46d4d208..03badf889 100644 --- a/moment_kinetics/debug_test/sound_wave_inputs.jl +++ b/moment_kinetics/debug_test/sound_wave_inputs.jl @@ -3,12 +3,12 @@ using moment_kinetics.type_definitions: OptionsDict using moment_kinetics.utils: recursive_merge # default inputs for tests -test_input_finite_difference_1D1V = OptionsDict("run_name" => "finite_difference_1D1V", +test_input_finite_difference_1D1V = OptionsDict("output" => OptionsDict("run_name" => "finite_difference_1D1V", + "base_directory" => test_output_directory), "composition" => OptionsDict("n_ion_species" => 2, "n_neutral_species" => 2, "electron_physics" => "boltzmann_electron_response", "T_e" => 1.0), - "base_directory" => test_output_directory, "evolve_moments" => OptionsDict("density" => false, "parallel_flow" => false, "parallel_pressure" => false, @@ -46,42 +46,42 @@ test_input_finite_difference_1D1V = OptionsDict("run_name" => "finite_difference test_input_finite_difference_1D1V_split_1_moment = recursive_merge(test_input_finite_difference_1D1V, - OptionsDict("run_name" => "finite_difference_1D1V_split_1_moment", + OptionsDict("output" => OptionsDict("run_name" => "finite_difference_1D1V_split_1_moment"), "evolve_moments" => OptionsDict("density" => true))) test_input_finite_difference_1D1V_split_2_moments = recursive_merge(test_input_finite_difference_1D1V_split_1_moment, - OptionsDict("run_name" => "finite_difference_1D1V_split_2_moments", + OptionsDict("output" => OptionsDict("run_name" => "finite_difference_1D1V_split_2_moments"), "evolve_moments" => OptionsDict("parallel_flow" => true))) test_input_finite_difference_1D1V_split_3_moments = recursive_merge(test_input_finite_difference_1D1V_split_2_moments, - OptionsDict("run_name" => "finite_difference_1D1V_split_3_moments", + OptionsDict("output" => OptionsDict("run_name" => "finite_difference_1D1V_split_3_moments"), "evolve_moments" => OptionsDict("parallel_pressure" => true))) test_input_finite_difference_cx0_1D1V = recursive_merge(test_input_finite_difference_1D1V, - OptionsDict("run_name" => "finite_difference_cx0_1D1V", + OptionsDict("output" => OptionsDict("run_name" => "finite_difference_cx0_1D1V"), "reactions" => OptionsDict("charge_exchange_frequency" => 0.0))) test_input_finite_difference_cx0_1D1V_split_1_moment = recursive_merge(test_input_finite_difference_cx0_1D1V, - OptionsDict("run_name" => "finite_difference_cx0_1D1V_split_1_moment", + OptionsDict("output" => OptionsDict("run_name" => "finite_difference_cx0_1D1V_split_1_moment"), "evolve_moments" => OptionsDict("density" => true))) test_input_finite_difference_cx0_1D1V_split_2_moments = recursive_merge(test_input_finite_difference_cx0_1D1V_split_1_moment, - OptionsDict("run_name" => "finite_difference_cx0_1D1V_split_2_moments", + OptionsDict("output" => OptionsDict("run_name" => "finite_difference_cx0_1D1V_split_2_moments"), "evolve_moments" => OptionsDict("parallel_flow" => true))) test_input_finite_difference_cx0_1D1V_split_3_moments = recursive_merge(test_input_finite_difference_cx0_1D1V_split_2_moments, - OptionsDict("run_name" => "finite_difference_cx0_1D1V_split_3_moments", + OptionsDict("output" => OptionsDict("run_name" => "finite_difference_cx0_1D1V_split_3_moments"), "evolve_moments" => OptionsDict("parallel_pressure" => true))) test_input_finite_difference = recursive_merge(test_input_finite_difference_1D1V, - OptionsDict("run_name" => "finite_difference", + OptionsDict("output" => OptionsDict("run_name" => "finite_difference"), "r" => OptionsDict("ngrid" => 4, "nelement" => 1, "discretization" => "finite_difference"), @@ -101,41 +101,41 @@ recursive_merge(test_input_finite_difference_1D1V, test_input_finite_difference_split_1_moment = recursive_merge(test_input_finite_difference, - OptionsDict("run_name" => "finite_difference_split_1_moment", + OptionsDict("output" => OptionsDict("run_name" => "finite_difference_split_1_moment"), "evolve_moments" => OptionsDict("density" => true))) test_input_finite_difference_split_2_moments = recursive_merge(test_input_finite_difference_split_1_moment, - OptionsDict("run_name" => "finite_difference_split_2_moments", + OptionsDict("output" => OptionsDict("run_name" => "finite_difference_split_2_moments"), "evolve_moments" => OptionsDict("parallel_flow" => true))) test_input_finite_difference_split_3_moments = recursive_merge(test_input_finite_difference_split_2_moments, - OptionsDict("run_name" => "finite_difference_split_3_moments", + OptionsDict("output" => OptionsDict("run_name" => "finite_difference_split_3_moments"), "evolve_moments" => OptionsDict("parallel_pressure" => true))) test_input_finite_difference_cx0 = recursive_merge(test_input_finite_difference, - OptionsDict("run_name" => "finite_difference_cx0", + OptionsDict("output" => OptionsDict("run_name" => "finite_difference_cx0"), "reactions" => OptionsDict("charge_exchange_frequency" => 0.0))) test_input_finite_difference_cx0_split_1_moment = recursive_merge(test_input_finite_difference_cx0, - OptionsDict("run_name" => "finite_difference_cx0_split_1_moment", + OptionsDict("output" => OptionsDict("run_name" => "finite_difference_cx0_split_1_moment"), "evolve_moments" => OptionsDict("density" => true))) test_input_finite_difference_cx0_split_2_moments = recursive_merge(test_input_finite_difference_cx0_split_1_moment, - OptionsDict("run_name" => "finite_difference_cx0_split_2_moments", + OptionsDict("output" => OptionsDict("run_name" => "finite_difference_cx0_split_2_moments"), "evolve_moments" => OptionsDict("parallel_flow" => true))) test_input_finite_difference_cx0_split_3_moments = recursive_merge(test_input_finite_difference_cx0_split_2_moments, - OptionsDict("run_name" => "finite_difference_cx0_split_3_moments", + OptionsDict("output" => OptionsDict("run_name" => "finite_difference_cx0_split_3_moments"), "evolve_moments" => OptionsDict("parallel_pressure" => true))) test_input_chebyshev = recursive_merge(test_input_finite_difference, - OptionsDict("run_name" => "chebyshev_pseudospectral", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral"), "r" => OptionsDict("discretization" => "chebyshev_pseudospectral", "ngrid" => 3, "nelement" => 1), @@ -161,42 +161,42 @@ test_input_chebyshev = recursive_merge(test_input_finite_difference, test_input_chebyshev_split_1_moment = recursive_merge(test_input_chebyshev, - OptionsDict("run_name" => "chebyshev_pseudospectral_split_1_moment", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral_split_1_moment"), "evolve_moments" => OptionsDict("density" => true))) test_input_chebyshev_split_2_moments = recursive_merge(test_input_chebyshev_split_1_moment, - OptionsDict("run_name" => "chebyshev_pseudospectral_split_2_moments", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral_split_2_moments"), "evolve_moments" => OptionsDict("parallel_flow" => true))) test_input_chebyshev_split_3_moments = recursive_merge(test_input_chebyshev_split_2_moments, - OptionsDict("run_name" => "chebyshev_pseudospectral_split_3_moments", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral_split_3_moments"), "evolve_moments" => OptionsDict("parallel_pressure" => true))) test_input_chebyshev_cx0 = recursive_merge(test_input_chebyshev, - OptionsDict("run_name" => "chebyshev_pseudospectral_cx0", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral_cx0"), "reactions" => OptionsDict("charge_exchange_frequency" => 0.0))) test_input_chebyshev_cx0_split_1_moment = recursive_merge(test_input_chebyshev_cx0, - OptionsDict("run_name" => "chebyshev_pseudospectral_cx0_split_1_moment", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral_cx0_split_1_moment"), "evolve_moments" => OptionsDict("density" => true))) test_input_chebyshev_cx0_split_2_moments = recursive_merge(test_input_chebyshev_cx0_split_1_moment, - OptionsDict("run_name" => "chebyshev_pseudospectral_cx0_split_2_moments", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral_cx0_split_2_moments"), "evolve_moments" => OptionsDict("parallel_flow" => true))) test_input_chebyshev_cx0_split_3_moments = recursive_merge(test_input_chebyshev_cx0_split_2_moments, - OptionsDict("run_name" => "chebyshev_pseudospectral_cx0_split_3_moments", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral_cx0_split_3_moments"), "evolve_moments" => OptionsDict("parallel_pressure" => true))) test_input_chebyshev_1D1V = recursive_merge(test_input_finite_difference_1D1V, - OptionsDict("run_name" => "chebyshev_pseudospectral_1D1V", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral_1D1V"), "z" => OptionsDict("discretization" => "chebyshev_pseudospectral", "ngrid" => 3, "nelement" => 2), @@ -210,38 +210,38 @@ recursive_merge(test_input_finite_difference_1D1V, test_input_chebyshev_1D1V_split_1_moment = recursive_merge(test_input_chebyshev_1D1V, - OptionsDict("run_name" => "chebyshev_pseudospectral_1D1V_split_1_moment", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral_1D1V_split_1_moment"), "evolve_moments" => OptionsDict("density" => true))) test_input_chebyshev_1D1V_split_2_moments = recursive_merge(test_input_chebyshev_1D1V_split_1_moment, - OptionsDict("run_name" => "chebyshev_pseudospectral_1D1V_split_2_moments", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral_1D1V_split_2_moments"), "evolve_moments" => OptionsDict("parallel_flow" => true))) test_input_chebyshev_1D1V_split_3_moments = recursive_merge(test_input_chebyshev_1D1V_split_2_moments, - OptionsDict("run_name" => "chebyshev_pseudospectral_1D1V_split_3_moments", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral_1D1V_split_3_moments"), "evolve_moments" => OptionsDict("parallel_pressure" => true), "runtime_plots" => true)) test_input_chebyshev_cx0_1D1V = recursive_merge(test_input_chebyshev_1D1V, - OptionsDict("run_name" => "chebyshev_pseudospectral_cx0_1D1V", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral_cx0_1D1V"), "reactions" => OptionsDict("charge_exchange_frequency" => 0.0))) test_input_chebyshev_cx0_1D1V_split_1_moment = recursive_merge(test_input_chebyshev_cx0_1D1V, - OptionsDict("run_name" => "chebyshev_pseudospectral_cx0_1D1V_split_1_moment", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral_cx0_1D1V_split_1_moment"), "evolve_moments" => OptionsDict("density" => true))) test_input_chebyshev_cx0_1D1V_split_2_moments = recursive_merge(test_input_chebyshev_cx0_1D1V_split_1_moment, - OptionsDict("run_name" => "chebyshev_pseudospectral_cx0_1D1V_split_2_moments", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral_cx0_1D1V_split_2_moments"), "evolve_moments" => OptionsDict("parallel_flow" => true))) test_input_chebyshev_cx0_1D1V_split_3_moments = recursive_merge(test_input_chebyshev_cx0_1D1V_split_2_moments, - OptionsDict("run_name" => "chebyshev_pseudospectral_cx0_1D1V_split_3_moments", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral_cx0_1D1V_split_3_moments"), "evolve_moments" => OptionsDict("parallel_pressure" => true))) test_input_list = [ diff --git a/moment_kinetics/debug_test/wall_bc_inputs.jl b/moment_kinetics/debug_test/wall_bc_inputs.jl index 3eff3ad89..eb1341ccc 100644 --- a/moment_kinetics/debug_test/wall_bc_inputs.jl +++ b/moment_kinetics/debug_test/wall_bc_inputs.jl @@ -4,13 +4,13 @@ using moment_kinetics.utils: recursive_merge # default inputs for tests test_input_finite_difference_1D1V = OptionsDict( - "run_name" => "finite_difference_1D1V", + "output" => OptionsDict("run_name" => "finite_difference_1D1V", + "base_directory" => test_output_directory), "composition" => OptionsDict("n_ion_species" => 2, "n_neutral_species" => 2, "electron_physics" => "boltzmann_electron_response", "T_e" => 1.0, "T_wall" => 1.0), - "base_directory" => test_output_directory, "evolve_moments" => OptionsDict("density" => false, "parallel_flow" => false, "parallel_pressure" => false, @@ -48,12 +48,12 @@ test_input_finite_difference_1D1V = OptionsDict( test_input_finite_difference_simple_sheath_1D1V = recursive_merge( test_input_finite_difference_1D1V, - OptionsDict("run_name" => "finite_difference_simple_sheath_1D1V", + OptionsDict("output" => OptionsDict("run_name" => "finite_difference_simple_sheath_1D1V"), "composition" => OptionsDict("electron_physics" => "boltzmann_electron_response_with_simple_sheath"))) test_input_finite_difference = recursive_merge( test_input_finite_difference_1D1V, - OptionsDict("run_name" => "finite_difference", + OptionsDict("output" => OptionsDict("run_name" => "finite_difference"), "r" => OptionsDict("ngrid" => 4, "nelement" => 1, "discretization" => "finite_difference"), @@ -73,12 +73,12 @@ test_input_finite_difference = recursive_merge( test_input_finite_difference_simple_sheath = recursive_merge( test_input_finite_difference, - OptionsDict("run_name" => "finite_difference_simple_sheath", + OptionsDict("output" => OptionsDict("run_name" => "finite_difference_simple_sheath"), "composition" => OptionsDict("electron_physics" => "boltzmann_electron_response_with_simple_sheath"))) test_input_chebyshev_1D1V = recursive_merge( test_input_finite_difference_1D1V, - OptionsDict("run_name" => "chebyshev_pseudospectral_1D1V", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral_1D1V"), "z" => OptionsDict("discretization" => "chebyshev_pseudospectral", "ngrid" => 3, "nelement" => 2), @@ -91,26 +91,26 @@ test_input_chebyshev_1D1V = recursive_merge( )) test_input_chebyshev_split1_1D1V = recursive_merge(test_input_chebyshev_1D1V, - OptionsDict("run_name" => "chebyshev_pseudospectral_split1_1D1V", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral_split1_1D1V"), "evolve_moments" => OptionsDict("density" => true))) test_input_chebyshev_split2_1D1V = recursive_merge(test_input_chebyshev_split1_1D1V, - OptionsDict("run_name" => "chebyshev_pseudospectral_split2_1D1V", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral_split2_1D1V"), "evolve_moments" => OptionsDict("parallel_flow" => true))) test_input_chebyshev_split3_1D1V = recursive_merge(test_input_chebyshev_split2_1D1V, - OptionsDict("run_name" => "chebyshev_pseudospectral_split3_1D1V", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral_split3_1D1V"), "evolve_moments" => OptionsDict("parallel_pressure" => true))) test_input_chebyshev_simple_sheath_1D1V = recursive_merge( test_input_chebyshev_1D1V, - OptionsDict("run_name" => "chebyshev_pseudospectral_simple_sheath_1D1V", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral_simple_sheath_1D1V"), "composition" => OptionsDict("electron_physics" => "boltzmann_electron_response_with_simple_sheath"))) test_input_chebyshev = recursive_merge( test_input_chebyshev_1D1V, - OptionsDict("run_name" => "chebyshev_pseudospectral", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral"), "r" => OptionsDict("discretization" => "chebyshev_pseudospectral", "ngrid" => 3, "nelement" => 1), @@ -130,7 +130,7 @@ test_input_chebyshev = recursive_merge( test_input_chebyshev_simple_sheath = recursive_merge( test_input_chebyshev, - OptionsDict("run_name" => "chebyshev_pseudospectral_simple_sheath", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral_simple_sheath"), "composition" => OptionsDict("electron_physics" => "boltzmann_electron_response_with_simple_sheath"))) test_input_list = [ diff --git a/moment_kinetics/src/moment_kinetics_input.jl b/moment_kinetics/src/moment_kinetics_input.jl index c935101de..2fe9e7c2d 100644 --- a/moment_kinetics/src/moment_kinetics_input.jl +++ b/moment_kinetics/src/moment_kinetics_input.jl @@ -33,8 +33,11 @@ function read_input_file(input_filename::String) input = TOML.parsefile(input_filename) # Use input_filename (without the extension) as default for "run_name" - if !("run_name" in keys(input)) - input["run_name"] = splitdir(splitext(input_filename)[1])[end] + if !("output" ∈ keys(input) && "run_name" in keys(input["output"])) + if !("output" ∈ keys(input)) + input["output"] = OptionsDict() + end + input["output"]["run_name"] = splitdir(splitext(input_filename)[1])[end] end return input @@ -73,6 +76,7 @@ function mk_input(scan_input=OptionsDict(); save_inputs_to_txt=false, ignore_MPI "evolve_moments_conservation", "charge_exchange_frequency", "electron_charge_exchange_frequency", "ionization_frequency", "electron_ionization_frequency", "ionization_energy", "nu_ei", + "run_name", "base_directory", ) for opt in removed_options_list if opt ∈ keys(scan_input) @@ -88,11 +92,23 @@ function mk_input(scan_input=OptionsDict(); save_inputs_to_txt=false, ignore_MPI n_ion_species = composition.n_ion_species n_neutral_species = composition.n_neutral_species - # this is the prefix for all output files associated with this run - run_name = get(scan_input, "run_name", "wallBC") + # Start processing inputs for file I/O. This is done early because we need to work + # out what `output_dir` should be. The setup is completed later, after some other + # sections have been read. + io_settings = set_defaults_and_check_section!( + scan_input, "output"; + run_name="", + base_directory="runs", + ascii_output=false, + binary_format=hdf5, + parallel_io=nothing, + ) + if io_settings["run_name"] == "" + error("When passing a Dict directly for input, it is required to set `run_name` " + * "in the `[output]` section") + end # this is the directory where the simulation data will be stored - base_directory = get(scan_input, "base_directory", "runs") - output_dir = joinpath(base_directory, run_name) + output_dir = joinpath(io_settings["base_directory"], io_settings["run_name"]) # if evolve_moments.density = true, evolve density via continuity eqn # and g = f/n via modified drift kinetic equation @@ -373,13 +389,7 @@ function mk_input(scan_input=OptionsDict(); save_inputs_to_txt=false, ignore_MPI ) em_input = Dict_to_NamedTuple(em_fields_settings) - # inputs for file I/O - io_settings = set_defaults_and_check_section!( - scan_input, "output"; - ascii_output=false, - binary_format=hdf5, - parallel_io=nothing, - ) + # Complete setup of io_settings if io_settings["parallel_io"] === nothing io_settings["parallel_io"] = io_has_parallel(Val(io_settings["binary_format"])) end @@ -395,7 +405,6 @@ function mk_input(scan_input=OptionsDict(); save_inputs_to_txt=false, ignore_MPI end io_settings["run_id"] = run_id io_settings["output_dir"] = output_dir - io_settings["run_name"] = run_name io_settings["write_error_diagnostics"] = timestepping_section["write_error_diagnostics"] io_settings["write_steady_state_diagnostics"] = timestepping_section["write_steady_state_diagnostics"] io_settings["write_electron_error_diagnostics"] = timestepping_section["electron_t_input"]["write_error_diagnostics"] @@ -453,7 +462,7 @@ function mk_input(scan_input=OptionsDict(); save_inputs_to_txt=false, ignore_MPI if global_rank[] == 0 && save_inputs_to_txt # Make file to log some information about inputs into. - io = open_ascii_output_file(string(output_dir,"/",run_name), "input") + io = open_ascii_output_file(string(output_dir,"/",io_settings["run_name"]), "input") else io = devnull end diff --git a/moment_kinetics/src/parameter_scans.jl b/moment_kinetics/src/parameter_scans.jl index 4cd896e0e..fc7ebcf28 100644 --- a/moment_kinetics/src/parameter_scans.jl +++ b/moment_kinetics/src/parameter_scans.jl @@ -33,10 +33,10 @@ parameter scan. function get_scan_inputs(scan_inputs::AbstractDict) scan_inputs = OrderedDict{String,Any}(scan_inputs) - if "base_directory" ∉ keys(scan_inputs) + if "base_directory" ∉ keys(scan_inputs["output"]) # Set up base_directory so that the runs in the scan are created in subdirectories # under a directory for the whole scan. - scan_inputs["base_directory"] = joinpath("runs", scan_inputs["run_name"]) + scan_inputs["output"]["base_directory"] = joinpath("runs", scan_inputs["output"]["run_name"]) end combine_outer = pop!(scan_inputs, "combine_outer", String[]) @@ -64,7 +64,7 @@ function get_scan_inputs(scan_inputs::AbstractDict) result = Vector{OrderedDict}(undef, length_inner_product) for i ∈ 1:length_inner_product - run_name = scan_inputs["run_name"] + run_name = scan_inputs["output"]["run_name"] result[i] = OrderedDict{String,Any}() for (k,v) ∈ scan_inputs if v isa Vector @@ -76,7 +76,7 @@ function get_scan_inputs(scan_inputs::AbstractDict) result[i][k] = v end end - result[i]["run_name"] = run_name + result[i]["output"]["run_name"] = run_name end # Combine 'result' with 'combine_outer' fields @@ -104,7 +104,7 @@ function get_scan_inputs(scan_inputs::AbstractDict) new_dict[key] = vals[j] # Truncate `key` - seems that if file names are too long, HDF5 has a # buffer overflow - new_dict["run_name"] = new_dict["run_name"] * + new_dict["output"]["run_name"] = new_dict["output"]["run_name"] * "_$(key[1:min(3, length(key))])_$(vals[j])" new_scan_inputs[count] = new_dict end @@ -122,7 +122,7 @@ function get_scan_inputs(scan_inputs::AbstractDict) println("Running scan:") for x in result - println(x["run_name"]) + println(x["output"]["run_name"]) end return result @@ -178,12 +178,12 @@ function generate_scan_input_files(scan_input::AbstractDict, dirname::AbstractSt for input ∈ input_dicts # Write the file, but do not overwrite - filename = joinpath(dirname, input["run_name"] * ".toml") + filename = joinpath(dirname, input["output"]["run_name"] * ".toml") ispath(filename) && error("The file $filename already exists.") open(filename, "w") do io # The run name will be created from the name of the input file, so do not need # to save "run_name" in the file. - pop!(input, "run_name") + pop!(input["output"], "run_name") options_to_TOML(io, input) end end diff --git a/moment_kinetics/src/utils.jl b/moment_kinetics/src/utils.jl index 35b9206a0..b5b0863bb 100644 --- a/moment_kinetics/src/utils.jl +++ b/moment_kinetics/src/utils.jl @@ -54,7 +54,7 @@ function get_unnormalized_parameters(input::Dict) mi = reference_params.mref * Unitful.kg parameters = OrderedDict{String,Any}() - parameters["run_name"] = run_name + parameters["run_name"] = io_input.run_name parameters["Nnorm"] = Nnorm parameters["Tnorm"] = Tnorm diff --git a/moment_kinetics/test/Krook_collisions_tests.jl b/moment_kinetics/test/Krook_collisions_tests.jl index 81603105e..b3768217b 100644 --- a/moment_kinetics/test/Krook_collisions_tests.jl +++ b/moment_kinetics/test/Krook_collisions_tests.jl @@ -107,7 +107,7 @@ test_input_full_f = OptionsDict("composition" => OptionsDict("n_ion_species" => "upar_phase" => 0.0, "temperature_amplitude" => 0.5, "temperature_phase" => 0.0), - "run_name" => "full_f", + "output" => OptionsDict("run_name" => "full_f"), "evolve_moments" => OptionsDict("density" => false, "parallel_flow" => false, "parallel_pressure" => false, @@ -142,17 +142,17 @@ test_input_full_f = OptionsDict("composition" => OptionsDict("n_ion_species" => test_input_split_1_moment = recursive_merge(test_input_full_f, - OptionsDict("run_name" => "split_1_moment", + OptionsDict("output" => OptionsDict("run_name" => "split_1_moment"), "evolve_moments" => OptionsDict("density" => true))) test_input_split_2_moments = recursive_merge(test_input_split_1_moment, - OptionsDict("run_name" => "split_2_moments", + OptionsDict("output" => OptionsDict("run_name" => "split_2_moments"), "evolve_moments" => OptionsDict("parallel_flow" => true))) test_input_split_3_moments = recursive_merge(test_input_split_2_moments, - OptionsDict("run_name" => "split_3_moments", + OptionsDict("output" => OptionsDict("run_name" => "split_3_moments"), "evolve_moments" => OptionsDict("parallel_pressure" => true), "vpa" => OptionsDict("L" => 12.0), "vz" => OptionsDict("L" => 12.0), @@ -172,7 +172,7 @@ function run_test(test_input, rtol, atol; args...) input = deepcopy(test_input) # Convert keyword arguments to a unique name - name = input["run_name"] + name = input["output"]["run_name"] if length(args) > 0 name = string(name, "_", (string(k, "-", v, "_") for (k, v) in args)...) @@ -185,7 +185,7 @@ function run_test(test_input, rtol, atol; args...) # Update default inputs with values to be changed merge_dict_with_kwargs!(input; args...) - input["run_name"] = name + input["output"]["run_name"] = name # Suppress console output while running quietoutput() do @@ -211,7 +211,7 @@ function run_test(test_input, rtol, atol; args...) # Load and analyse output ######################### - path = joinpath(realpath(input["base_directory"]), name, name) + path = joinpath(realpath(input["output"]["base_directory"]), name, name) # open the netcdf file containing moments data and give it the handle 'fid' fid = open_readonly_output_file(path, "moments") @@ -419,19 +419,19 @@ function runtests() # Benchmark data is taken from this run (full-f with no splitting) @testset "full-f" begin - test_input_full_f["base_directory"] = test_output_directory + test_input_full_f["output"]["base_directory"] = test_output_directory run_test(test_input_full_f, 1.e-10, 3.e-16) end @testset "split 1" begin - test_input_split_1_moment["base_directory"] = test_output_directory + test_input_split_1_moment["output"]["base_directory"] = test_output_directory run_test(test_input_split_1_moment, 1.e-3, 1.e-15) end @testset "split 2" begin - test_input_split_2_moments["base_directory"] = test_output_directory + test_input_split_2_moments["output"]["base_directory"] = test_output_directory run_test(test_input_split_2_moments, 1.e-3, 1.e-15) end @testset "split 3" begin - test_input_split_3_moments["base_directory"] = test_output_directory + test_input_split_3_moments["output"]["base_directory"] = test_output_directory run_test(test_input_split_3_moments, 1.e-3, 1.e-15) end end diff --git a/moment_kinetics/test/braginskii_electrons_imex_tests.jl b/moment_kinetics/test/braginskii_electrons_imex_tests.jl index 938399546..5a2ba1daa 100644 --- a/moment_kinetics/test/braginskii_electrons_imex_tests.jl +++ b/moment_kinetics/test/braginskii_electrons_imex_tests.jl @@ -18,7 +18,7 @@ test_input = OptionsDict( "composition" => OptionsDict("n_ion_species" => 1, "n_neutral_species" => 1, "electron_physics" => "braginskii_fluid", "T_e" => 0.2), - "run_name" => "braginskii-electrons-imex", + "output" => OptionsDict("run_name" => "braginskii-electrons-imex"), "evolve_moments" => OptionsDict("density" => true, "parallel_flow" => true, "parallel_pressure" => true, @@ -109,7 +109,7 @@ function run_test(test_input, expected_p, expected_q, expected_vt; rtol=1.e-6, input = deepcopy(test_input) # Convert keyword arguments to a unique name - name = input["run_name"] + name = input["output"]["run_name"] if length(args) > 0 name = string(name, "_", (string(k, "-", v, "_") for (k, v) in args)...) @@ -122,7 +122,7 @@ function run_test(test_input, expected_p, expected_q, expected_vt; rtol=1.e-6, # Update default inputs with values to be changed merge_dict_with_kwargs!(input; args...) - input["run_name"] = name + input["output"]["run_name"] = name # Suppress console output while running p = undef @@ -138,7 +138,7 @@ function run_test(test_input, expected_p, expected_q, expected_vt; rtol=1.e-6, # Load and analyse output ######################### - path = joinpath(realpath(input["base_directory"]), name) + path = joinpath(realpath(input["output"]["base_directory"]), name) # open the output file run_info = get_run_info_no_setup(path) @@ -282,15 +282,15 @@ function runtests() end else @testset "Split 3" begin - test_input["base_directory"] = test_output_directory + test_input["output"]["base_directory"] = test_output_directory run_test(test_input, expected_p, expected_q, expected_vt) end @long @testset "Check other timestep - $type" for type ∈ ("KennedyCarpenterARK437",) timestep_check_input = deepcopy(test_input) - timestep_check_input["base_directory"] = test_output_directory - timestep_check_input["run_name"] = type + timestep_check_input["output"]["base_directory"] = test_output_directory + timestep_check_input["output"]["run_name"] = type timestep_check_input["timestepping"]["type"] = type run_test(timestep_check_input, expected_p, expected_q, expected_vt, rtol=2.e-4, atol=1.e-10) diff --git a/moment_kinetics/test/fokker_planck_time_evolution_tests.jl b/moment_kinetics/test/fokker_planck_time_evolution_tests.jl index a957d4896..41cf44957 100644 --- a/moment_kinetics/test/fokker_planck_time_evolution_tests.jl +++ b/moment_kinetics/test/fokker_planck_time_evolution_tests.jl @@ -222,8 +222,8 @@ for k in 1:ntind end """ # default inputs for tests -test_input_gauss_legendre = OptionsDict("run_name" => "gausslegendre_pseudospectral", - "base_directory" => test_output_directory, +test_input_gauss_legendre = OptionsDict("output" => OptionsDict("run_name" => "gausslegendre_pseudospectral", + "base_directory" => test_output_directory), "composition" => OptionsDict("n_ion_species" => 1, "n_neutral_species" => 0, "electron_physics" => "boltzmann_electron_response", @@ -295,7 +295,7 @@ function run_test(test_input, expected, rtol, atol, upar_rtol=nothing; args...) return string(string(key)[1], value) end end - name = input["run_name"] + name = input["output"]["run_name"] if length(args) > 0 name = string(name, "_", (stringify_arg(k, v) for (k, v) in args)...) end @@ -305,7 +305,7 @@ function run_test(test_input, expected, rtol, atol, upar_rtol=nothing; args...) # Update default inputs with values to be changed merge_dict_with_kwargs!(input; args...) - input["run_name"] = name + input["output"]["run_name"] = name # Suppress console output while running quietoutput() do # run simulation @@ -331,7 +331,7 @@ function run_test(test_input, expected, rtol, atol, upar_rtol=nothing; args...) # Load and analyse output ######################### - path = joinpath(realpath(input["base_directory"]), name, name) + path = joinpath(realpath(input["output"]["base_directory"]), name, name) # open the netcdf file containing moments data and give it the handle 'fid' fid = open_readonly_output_file(path, "moments") diff --git a/moment_kinetics/test/harrisonthompson.jl b/moment_kinetics/test/harrisonthompson.jl index 28491467a..6c5f0e1ae 100644 --- a/moment_kinetics/test/harrisonthompson.jl +++ b/moment_kinetics/test/harrisonthompson.jl @@ -83,7 +83,7 @@ test_input_finite_difference = Dict("composition" => OptionsDict("n_ion_species" "upar_phase" => 0.0, "temperature_amplitude" => 0.0, "temperature_phase" => 0.0), - "run_name" => "finite_difference", + "output" => OptionsDict("run_name" => "finite_difference"), "evolve_moments" => OptionsDict("density" => false, "parallel_flow" => false, "parallel_pressure" => false, @@ -120,7 +120,7 @@ test_input_finite_difference = Dict("composition" => OptionsDict("n_ion_species" ) test_input_chebyshev = recursive_merge(test_input_finite_difference, - OptionsDict("run_name" => "chebyshev_pseudospectral", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral"), "z" => OptionsDict("discretization" => "chebyshev_pseudospectral", "ngrid" => 9, "nelement" => 2), @@ -133,19 +133,19 @@ test_input_chebyshev = recursive_merge(test_input_finite_difference, )) test_input_chebyshev_split1 = recursive_merge(test_input_chebyshev, - OptionsDict("run_name" => "chebyshev_pseudospectral_split1", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral_split1"), "evolve_moments" => OptionsDict("density" => true, "moments_conservation" => true), )) test_input_chebyshev_split2 = recursive_merge(test_input_chebyshev_split1, - OptionsDict("run_name" => "chebyshev_pseudospectral_split2", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral_split2"), "evolve_moments" => OptionsDict("parallel_flow" => true), "ion_numerical_dissipation" => OptionsDict("force_minimum_pdf_value" => 0.0), )) test_input_chebyshev_split3 = recursive_merge(test_input_chebyshev_split2, - OptionsDict("run_name" => "chebyshev_pseudospectral_split3", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral_split3"), "evolve_moments" => OptionsDict("parallel_pressure" => true), )) @@ -163,7 +163,7 @@ function run_test(test_input, analytic_rtol, analytic_atol, expected_phi, input = deepcopy(test_input) # Convert keyword arguments to a unique name - name = input["run_name"] + name = input["output"]["run_name"] if length(args) > 0 name = string(name, "_", (string(k, "-", v, "_") for (k, v) in args)...) @@ -176,7 +176,7 @@ function run_test(test_input, analytic_rtol, analytic_atol, expected_phi, # Update default inputs with values to be changed merge_dict_with_kwargs!(input; args...) - input["run_name"] = name + input["output"]["run_name"] = name # Suppress console output while running phi = nothing @@ -193,7 +193,7 @@ function run_test(test_input, analytic_rtol, analytic_atol, expected_phi, # Load and analyse output ######################### - path = joinpath(realpath(input["base_directory"]), name, name) + path = joinpath(realpath(input["output"]["base_directory"]), name, name) # open the netcdf file and give it the handle 'fid' fid = open_readonly_output_file(path,"moments") @@ -239,12 +239,12 @@ function runtests() println("Harrison-Thompson wall boundary condition tests") @testset_skip "FD version forms discontinuity in vpa at z=±L/2" "finite difference" begin - test_input_finite_difference["base_directory"] = test_output_directory + test_input_finite_difference["output"]["base_directory"] = test_output_directory run_test(test_input_finite_difference, 1.e-3, 1.e-4, zeros(100), 1.e-14, 1.e-15) end @testset "Chebyshev" begin - test_input_chebyshev["base_directory"] = test_output_directory + test_input_chebyshev["output"]["base_directory"] = test_output_directory run_test(test_input_chebyshev, 3.e-2, 3.e-3, [-0.8270506736528097, -0.6647482045160528, -0.43595102198197894, -0.2930090302314022, -0.19789542449264944, -0.14560099229503182, @@ -254,7 +254,7 @@ function runtests() -0.6647482045160534, -0.8270506736528144], 5.0e-9, 1.e-15) end @testset "Chebyshev split 1" begin - test_input_chebyshev_split1["base_directory"] = test_output_directory + test_input_chebyshev_split1["output"]["base_directory"] = test_output_directory run_test(test_input_chebyshev_split1, 3.e-2, 3.e-3, [-0.8089566460734486, -0.6619131832543634, -0.43082918688434424, -0.29582033972847016, -0.1934419000612522, -0.14925142084423915, @@ -264,7 +264,7 @@ function runtests() -0.6619131832543697, -0.808956646073445], 5.0e-9, 1.e-15) end @testset "Chebyshev split 2" begin - test_input_chebyshev_split2["base_directory"] = test_output_directory + test_input_chebyshev_split2["output"]["base_directory"] = test_output_directory run_test(test_input_chebyshev_split2, 6.e-2, 3.e-3, [-0.7798736739831602, -0.661568214314525, -0.409872886370737, -0.24444487132869974, -0.17244646306807737, -0.11761557291772232, @@ -276,7 +276,7 @@ function runtests() # The 'split 3' test is pretty badly resolved, but don't want to increase # run-time! @testset "Chebyshev split 3" begin - test_input_chebyshev_split3["base_directory"] = test_output_directory + test_input_chebyshev_split3["output"]["base_directory"] = test_output_directory run_test(test_input_chebyshev_split3, 2.5e-1, 3.e-3, [-0.5012994554414933, -0.4624277373138882, -0.35356695432752266, -0.22371207174875177, -0.14096934539193717, -0.10082423314545275, diff --git a/moment_kinetics/test/nonlinear_sound_wave_inputs_and_expected_data.jl b/moment_kinetics/test/nonlinear_sound_wave_inputs_and_expected_data.jl index 5b6768e1d..2a5736037 100644 --- a/moment_kinetics/test/nonlinear_sound_wave_inputs_and_expected_data.jl +++ b/moment_kinetics/test/nonlinear_sound_wave_inputs_and_expected_data.jl @@ -104,7 +104,7 @@ test_input_finite_difference = OptionsDict("composition" => OptionsDict("n_ion_s "upar_phase" => 0.0, "temperature_amplitude" => 0.5, "temperature_phase" => 0.0), - "run_name" => "finite_difference", + "output" => OptionsDict("run_name" => "finite_difference"), "evolve_moments" => OptionsDict("density" => false, "parallel_flow" => false, "parallel_pressure" => false, @@ -138,34 +138,34 @@ test_input_finite_difference = OptionsDict("composition" => OptionsDict("n_ion_s test_input_finite_difference_split_1_moment = recursive_merge(test_input_finite_difference, - OptionsDict("run_name" => "finite_difference_split_1_moment", - "evolve_moments" => OptionsDict("density" => true))) + OptionsDict("output" => OptionsDict("run_name" => "finite_difference_split_1_moment"), + "evolve_moments" => OptionsDict("density" => true))) test_input_finite_difference_split_2_moments = recursive_merge(test_input_finite_difference_split_1_moment, - OptionsDict("run_name" => "finite_difference_split_2_moments", - "evolve_moments" => OptionsDict("parallel_flow" => true))) + OptionsDict("output" => OptionsDict("run_name" => "finite_difference_split_2_moments"), + "evolve_moments" => OptionsDict("parallel_flow" => true))) test_input_finite_difference_split_3_moments = recursive_merge(test_input_finite_difference_split_2_moments, - OptionsDict("run_name" => "finite_difference_split_3_moments", - "evolve_moments" => OptionsDict("parallel_pressure" => true), - "vpa" => OptionsDict("L" => 12.0), - "vz" => OptionsDict("L" => 12.0), - )) + OptionsDict("output" => OptionsDict("run_name" => "finite_difference_split_3_moments"), + "evolve_moments" => OptionsDict("parallel_pressure" => true), + "vpa" => OptionsDict("L" => 12.0), + "vz" => OptionsDict("L" => 12.0), + )) test_input_chebyshev = recursive_merge(test_input_finite_difference, - OptionsDict("run_name" => "chebyshev_pseudospectral", - "z" => OptionsDict("discretization" => "chebyshev_pseudospectral", - "ngrid" => 9, - "nelement" => 4), - "vpa" => OptionsDict("discretization" => "chebyshev_pseudospectral", - "ngrid" => 17, - "nelement" => 8), - "vz" => OptionsDict("discretization" => "chebyshev_pseudospectral", - "ngrid" => 17, - "nelement" => 8)), - ) + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral"), + "z" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 9, + "nelement" => 4), + "vpa" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 17, + "nelement" => 8), + "vz" => OptionsDict("discretization" => "chebyshev_pseudospectral", + "ngrid" => 17, + "nelement" => 8)), + ) if global_size[] > 2 && global_size[] % 2 == 0 # Test using distributed-memory @@ -174,18 +174,18 @@ end test_input_chebyshev_split_1_moment = recursive_merge(test_input_chebyshev, - OptionsDict("run_name" => "chebyshev_pseudospectral_split_1_moment", - "evolve_moments" => OptionsDict("density" => true))) + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral_split_1_moment"), + "evolve_moments" => OptionsDict("density" => true))) test_input_chebyshev_split_2_moments = recursive_merge(test_input_chebyshev_split_1_moment, - OptionsDict("run_name" => "chebyshev_pseudospectral_split_2_moments", - "evolve_moments" => OptionsDict("parallel_flow" => true))) + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral_split_2_moments"), + "evolve_moments" => OptionsDict("parallel_flow" => true))) test_input_chebyshev_split_3_moments = recursive_merge(test_input_chebyshev_split_2_moments, - OptionsDict("run_name" => "chebyshev_pseudospectral_split_3_moments", - "evolve_moments" => OptionsDict("parallel_pressure" => true), - "vpa" => OptionsDict("L" => 12.0), - "vz" => OptionsDict("L" => 12.0), - )) + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral_split_3_moments"), + "evolve_moments" => OptionsDict("parallel_pressure" => true), + "vpa" => OptionsDict("L" => 12.0), + "vz" => OptionsDict("L" => 12.0), + )) diff --git a/moment_kinetics/test/nonlinear_sound_wave_tests.jl b/moment_kinetics/test/nonlinear_sound_wave_tests.jl index 1346e6a47..6540162f0 100644 --- a/moment_kinetics/test/nonlinear_sound_wave_tests.jl +++ b/moment_kinetics/test/nonlinear_sound_wave_tests.jl @@ -32,7 +32,7 @@ function run_test(test_input, rtol, atol, upar_rtol=nothing; args...) end # Convert keyword arguments to a unique name - name = input["run_name"] + name = input["output"]["run_name"] if length(args) > 0 name = string(name, "_", (string(k, "-", v, "_") for (k, v) in args)...) @@ -45,7 +45,7 @@ function run_test(test_input, rtol, atol, upar_rtol=nothing; args...) # Update default inputs with values to be changed merge_dict_with_kwargs!(input; args...) - input["run_name"] = name + input["output"]["run_name"] = name # Suppress console output while running quietoutput() do @@ -71,7 +71,7 @@ function run_test(test_input, rtol, atol, upar_rtol=nothing; args...) # Load and analyse output ######################### - path = joinpath(realpath(input["base_directory"]), name) + path = joinpath(realpath(input["output"]["base_directory"]), name) # open the output file(s) run_info = get_run_info_no_setup(path; dfns=true) @@ -287,38 +287,38 @@ function runtests() # finite difference @testset "FD base" begin - test_input_finite_difference["base_directory"] = test_output_directory + test_input_finite_difference["output"]["base_directory"] = test_output_directory run_test(test_input_finite_difference, 1.e-3, 1.e-11, 2.e-3) end @testset "FD split 1" begin - test_input_finite_difference_split_1_moment["base_directory"] = test_output_directory + test_input_finite_difference_split_1_moment["output"]["base_directory"] = test_output_directory run_test(test_input_finite_difference_split_1_moment, 1.e-3, 1.e-11) end @testset "FD split 2" begin - test_input_finite_difference_split_2_moments["base_directory"] = test_output_directory + test_input_finite_difference_split_2_moments["output"]["base_directory"] = test_output_directory run_test(test_input_finite_difference_split_2_moments, 1.e-3, 1.e-11) end @testset "FD split 3" begin - test_input_finite_difference_split_3_moments["base_directory"] = test_output_directory + test_input_finite_difference_split_3_moments["output"]["base_directory"] = test_output_directory run_test(test_input_finite_difference_split_3_moments, 1.e-3, 1.e-11) end # Chebyshev pseudospectral # Benchmark data is taken from this run (Chebyshev with no splitting) @testset "Chebyshev base" begin - test_input_chebyshev["base_directory"] = test_output_directory + test_input_chebyshev["output"]["base_directory"] = test_output_directory run_test(test_input_chebyshev, 1.e-10, 3.e-16) end @testset "Chebyshev split 1" begin - test_input_chebyshev_split_1_moment["base_directory"] = test_output_directory + test_input_chebyshev_split_1_moment["output"]["base_directory"] = test_output_directory run_test(test_input_chebyshev_split_1_moment, 1.e-3, 1.e-15) end @testset "Chebyshev split 2" begin - test_input_chebyshev_split_2_moments["base_directory"] = test_output_directory + test_input_chebyshev_split_2_moments["output"]["base_directory"] = test_output_directory run_test(test_input_chebyshev_split_2_moments, 1.e-3, 1.e-15) end @testset "Chebyshev split 3" begin - test_input_chebyshev_split_3_moments["base_directory"] = test_output_directory + test_input_chebyshev_split_3_moments["output"]["base_directory"] = test_output_directory run_test(test_input_chebyshev_split_3_moments, 1.e-3, 1.e-15) end end diff --git a/moment_kinetics/test/recycling_fraction_tests.jl b/moment_kinetics/test/recycling_fraction_tests.jl index 2f2ca42c1..96f2ef32c 100644 --- a/moment_kinetics/test/recycling_fraction_tests.jl +++ b/moment_kinetics/test/recycling_fraction_tests.jl @@ -53,7 +53,7 @@ test_input = OptionsDict("composition" => OptionsDict("n_ion_species" => 1, "upar_phase" => 0.0, "temperature_amplitude" => 0.0, "temperature_phase" => 0.0), - "run_name" => "full-f", + "output" => OptionsDict("run_name" => "full-f"), "evolve_moments" => OptionsDict("density" => false, "parallel_flow" => false, "parallel_pressure" => false, @@ -96,14 +96,14 @@ if global_size[] > 2 && global_size[] % 2 == 0 end test_input_split1 = recursive_merge(test_input, - OptionsDict("run_name" => "split1", + OptionsDict("output" => OptionsDict("run_name" => "split1"), "evolve_moments" => OptionsDict("density" => true, "moments_conservation" => true))) test_input_split2 = recursive_merge(test_input_split1, - OptionsDict("run_name" => "split2", + OptionsDict("output" => OptionsDict("run_name" => "split2"), "evolve_moments" => OptionsDict("parallel_flow" => true))) test_input_split3 = recursive_merge(test_input_split2, - OptionsDict("run_name" => "split3", + OptionsDict("output" => OptionsDict("run_name" => "split3"), "z" => OptionsDict("nelement" => 16), "vpa" => OptionsDict("nelement" => 31), "vz" => OptionsDict("nelement" => 31), @@ -117,7 +117,7 @@ test_input_split3["timestepping"] = recursive_merge(test_input_split3["timestepp # default inputs for adaptive timestepping tests test_input_adaptive = recursive_merge(test_input, - OptionsDict("run_name" => "adaptive full-f", + OptionsDict("output" => OptionsDict("run_name" => "adaptive full-f"), "z" => OptionsDict("ngrid" => 5, "nelement" => 16), "vpa" => OptionsDict("ngrid" => 6, @@ -143,16 +143,16 @@ test_input_adaptive["timestepping"] = recursive_merge(test_input_adaptive["times ) test_input_adaptive_split1 = recursive_merge(test_input_adaptive, - OptionsDict("run_name" => "adaptive split1", + OptionsDict("output" => OptionsDict("run_name" => "adaptive split1"), "evolve_moments" => OptionsDict("density" => true, "moments_conservation" => true))) test_input_adaptive_split2 = recursive_merge(test_input_adaptive_split1, - OptionsDict("run_name" => "adaptive split2", + OptionsDict("output" => OptionsDict("run_name" => "adaptive split2"), "evolve_moments" => OptionsDict("parallel_flow" => true))) test_input_adaptive_split2["timestepping"] = recursive_merge(test_input_adaptive_split2["timestepping"], OptionsDict("step_update_prefactor" => 0.4)) test_input_adaptive_split3 = recursive_merge(test_input_adaptive_split2, - OptionsDict("run_name" => "adaptive split3", + OptionsDict("output" => OptionsDict("run_name" => "adaptive split3"), "evolve_moments" => OptionsDict("parallel_pressure" => true), "numerical_dissipation" => OptionsDict("force_minimum_pdf_value" => 0.0, "vpa_dissipation_coefficient" => 1e-2))) @@ -179,7 +179,7 @@ function run_test(test_input, expected_phi; rtol=4.e-14, atol=1.e-15, args...) input = deepcopy(test_input) # Convert keyword arguments to a unique name - name = input["run_name"] + name = input["output"]["run_name"] if length(args) > 0 name = string(name, "_", (string(k, "-", v, "_") for (k, v) in args)...) @@ -192,7 +192,7 @@ function run_test(test_input, expected_phi; rtol=4.e-14, atol=1.e-15, args...) # Update default inputs with values to be changed merge_dict_with_kwargs!(input; args...) - input["run_name"] = name + input["output"]["run_name"] = name # Suppress console output while running phi = undef @@ -206,7 +206,7 @@ function run_test(test_input, expected_phi; rtol=4.e-14, atol=1.e-15, args...) # Load and analyse output ######################### - path = joinpath(realpath(input["base_directory"]), name) + path = joinpath(realpath(input["output"]["base_directory"]), name) # open the output file(s) run_info = get_run_info_no_setup(path) @@ -239,7 +239,7 @@ function runtests() println("Recycling fraction tests") @long @testset "Full-f" begin - test_input["base_directory"] = test_output_directory + test_input["output"]["base_directory"] = test_output_directory run_test(test_input, [-0.0546579889285807, -0.019016549127873168, -0.0014860800466385304, 0.0009959205072609873, 0.0018297472055798175, 0.001071042733974246, @@ -251,7 +251,7 @@ function runtests() -0.04842263416979855]) end @long @testset "Split 1" begin - test_input_split1["base_directory"] = test_output_directory + test_input_split1["output"]["base_directory"] = test_output_directory run_test(test_input_split1, [-0.054564400690150644, -0.01880050885497155, -0.0013804889155909434, 0.0009426267362423344, 0.0018708794999890794, 0.0010048035580616115, @@ -263,7 +263,7 @@ function runtests() -0.04820698953610652]) end @long @testset "Split 2" begin - test_input_split2["base_directory"] = test_output_directory + test_input_split2["output"]["base_directory"] = test_output_directory run_test(test_input_split2, [-0.055351930552923125, -0.0200209368236471, -0.0010274232338285407, 0.0011445828881595096, 0.001990016623266284, 0.0011847791295251302, @@ -275,7 +275,7 @@ function runtests() -0.04714624635817171]) end @long @testset "Split 3" begin - test_input_split3["base_directory"] = test_output_directory + test_input_split3["output"]["base_directory"] = test_output_directory run_test(test_input_split3, [-0.036195418620494954, -0.030489030308458488, -0.028975057418733397, -0.02856021807109163, -0.025513413807863268, -0.0219696963676536, @@ -306,12 +306,12 @@ function runtests() -0.00942148866222427, -0.011607485576226423, -0.020871221194795328, -0.03762871759968933] @testset "Adaptive timestep - full-f" begin - test_input_adaptive["base_directory"] = test_output_directory + test_input_adaptive["output"]["base_directory"] = test_output_directory run_test(test_input_adaptive, fullf_expected_output, rtol=6.0e-4, atol=2.0e-12) end @testset "Adaptive timestep - split 1" begin - test_input_adaptive_split1["base_directory"] = test_output_directory + test_input_adaptive_split1["output"]["base_directory"] = test_output_directory run_test(test_input_adaptive_split1, [-0.04375862714017892, -0.022363510973059945, -0.012739964397542611, -0.010806509398868007, -0.007052551067569563, @@ -324,7 +324,7 @@ function runtests() atol=2.0e-12) end @testset "Adaptive timestep - split 2" begin - test_input_adaptive_split2["base_directory"] = test_output_directory + test_input_adaptive_split2["output"]["base_directory"] = test_output_directory run_test(test_input_adaptive_split2, [-0.0440004026002034, -0.022740771274011903, -0.012908307424861458, -0.010957840207013755, -0.007098397545728348, @@ -337,7 +337,7 @@ function runtests() -0.03785398593006839], rtol=6.0e-4, atol=2.0e-12) end @testset "Adaptive timestep - split 3" begin - test_input_adaptive_split3["base_directory"] = test_output_directory + test_input_adaptive_split3["output"]["base_directory"] = test_output_directory run_test(test_input_adaptive_split3, [-0.034623352735472034, -0.03200541773193755, -0.02714032291656093, -0.020924986472905527, -0.01015057042512689, 0.0027893133203071574, @@ -354,8 +354,8 @@ function runtests() "SSPRK2", "SSPRK1") timestep_check_input = deepcopy(test_input_adaptive) - timestep_check_input["base_directory"] = test_output_directory - timestep_check_input["run_name"] = type + timestep_check_input["output"]["base_directory"] = test_output_directory + timestep_check_input["output"]["run_name"] = type timestep_check_input["timestepping"]["type"] = type run_test(timestep_check_input, fullf_expected_output, rtol=8.e-4, atol=1.e-10) diff --git a/moment_kinetics/test/restart_interpolation_tests.jl b/moment_kinetics/test/restart_interpolation_tests.jl index 056cfe866..a1d6c436e 100644 --- a/moment_kinetics/test/restart_interpolation_tests.jl +++ b/moment_kinetics/test/restart_interpolation_tests.jl @@ -30,11 +30,11 @@ if global_size[] > 1 && global_size[] % 2 == 0 # Test using distributed-memory base_input["z"]["nelement_local"] = base_input["z"]["nelement"] ÷ 2 end -base_input["output"] = OptionsDict("parallel_io" => false) +base_input["output"]["parallel_io"] = false restart_test_input_chebyshev = recursive_merge(deepcopy(base_input), - OptionsDict("run_name" => "restart_chebyshev_pseudospectral", + OptionsDict("output" => OptionsDict("run_name" => "restart_chebyshev_pseudospectral"), "r" => OptionsDict("ngrid" => 3, "nelement" => 2, "discretization" => "chebyshev_pseudospectral"), "z" => OptionsDict("ngrid" => 17, "nelement" => 2), @@ -48,20 +48,20 @@ end restart_test_input_chebyshev_split_1_moment = recursive_merge(deepcopy(restart_test_input_chebyshev), - OptionsDict("run_name" => "restart_chebyshev_pseudospectral_split_1_moment", + OptionsDict("output" => OptionsDict("run_name" => "restart_chebyshev_pseudospectral_split_1_moment"), "evolve_moments" => OptionsDict("density" => true)), ) restart_test_input_chebyshev_split_2_moments = recursive_merge(deepcopy(restart_test_input_chebyshev_split_1_moment), - OptionsDict("run_name" => "restart_chebyshev_pseudospectral_split_2_moments", + OptionsDict("output" => OptionsDict("run_name" => "restart_chebyshev_pseudospectral_split_2_moments"), "r" => OptionsDict("ngrid" => 1, "nelement" => 1), "evolve_moments" => OptionsDict("parallel_flow" => true)), ) restart_test_input_chebyshev_split_3_moments = recursive_merge(deepcopy(restart_test_input_chebyshev_split_2_moments), - OptionsDict("run_name" => "restart_chebyshev_pseudospectral_split_3_moments", + OptionsDict("output" => OptionsDict("run_name" => "restart_chebyshev_pseudospectral_split_3_moments"), "evolve_moments" => OptionsDict("parallel_pressure" => true), "vpa" => OptionsDict("L" => 1.5*vpa_L), "vz" => OptionsDict("L" => 1.5*vpa_L)), ) @@ -99,7 +99,7 @@ function run_test(test_input, base, message, rtol, atol; tol_3V, args...) end end end - name = input["run_name"] + name = input["output"]["run_name"] if length(args) > 0 name = string(name, "_", (stringify_arg(k, v) for (k, v) in args)...) end @@ -115,19 +115,19 @@ function run_test(test_input, base, message, rtol, atol; tol_3V, args...) println(" - testing ", message) merge_dict_with_kwargs!(input; args...) - input["run_name"] = name + input["output"]["run_name"] = name # Suppress console output while running quietoutput() do # run simulation if parallel_io - restart_filename = joinpath(base["base_directory"], - base["run_name"], - base["run_name"] * ".dfns.h5") + restart_filename = joinpath(base["output"]["base_directory"], + base["output"]["run_name"], + base["output"]["run_name"] * ".dfns.h5") else - restart_filename = joinpath(base["base_directory"], - base["run_name"], - base["run_name"] * ".dfns.0.h5") + restart_filename = joinpath(base["output"]["base_directory"], + base["output"]["run_name"], + base["output"]["run_name"] * ".dfns.0.h5") end run_moment_kinetics(input; restart=restart_filename) end @@ -152,7 +152,7 @@ function run_test(test_input, base, message, rtol, atol; tol_3V, args...) ######################### # Read the output data - path = joinpath(realpath(input["base_directory"]), name) + path = joinpath(realpath(input["output"]["base_directory"]), name) run_info = get_run_info_no_setup((path, -1); dfns=true) z = run_info.z @@ -191,7 +191,7 @@ function run_test(test_input, base, message, rtol, atol; tol_3V, args...) close_run_info(run_info) # Delete output because output files for 3V tests can be large - rm(joinpath(realpath(input["base_directory"]), name); recursive=true) + rm(joinpath(realpath(input["output"]["base_directory"]), name); recursive=true) phi = phi_zrt[:,1,:] n_ion = n_ion_zrst[:,1,:,:] @@ -329,7 +329,7 @@ function runtests() (base_input_evolve_ppar, "split 3")) test_output_directory = get_MPI_tempdir() - base["base_directory"] = test_output_directory + base["output"]["base_directory"] = test_output_directory # Base run, from which tests are restarted # Suppress console output while running @@ -345,7 +345,7 @@ function runtests() # simulation) don't test upar. upar and uz end up with large 'errors' # (~50%), and it is not clear why, but ignore this so test can pass. this_input = deepcopy(restart_test_input_chebyshev) - this_input["base_directory"] = test_output_directory + this_input["output"]["base_directory"] = test_output_directory this_input["output"]["parallel_io"] = parallel_io run_test(this_input, base, message, rtol, 1.e-15; tol_3V=tol_3V, args...) end @@ -353,21 +353,21 @@ function runtests() message = "restart split 1 from $base_label$label" @testset "$message" begin this_input = deepcopy(restart_test_input_chebyshev_split_1_moment) - this_input["base_directory"] = test_output_directory + this_input["output"]["base_directory"] = test_output_directory this_input["output"]["parallel_io"] = parallel_io run_test(this_input, base, message, rtol, 1.e-15; tol_3V=tol_3V, args...) end message = "restart split 2 from $base_label$label" @testset "$message" begin this_input = deepcopy(restart_test_input_chebyshev_split_2_moments) - this_input["base_directory"] = test_output_directory + this_input["output"]["base_directory"] = test_output_directory this_input["output"]["parallel_io"] = parallel_io run_test(this_input, base, message, rtol, 1.e-15; tol_3V=tol_3V, args...) end message = "restart split 3 from $base_label$label" @testset "$message" begin this_input = deepcopy(restart_test_input_chebyshev_split_3_moments) - this_input["base_directory"] = test_output_directory + this_input["output"]["base_directory"] = test_output_directory this_input["output"]["parallel_io"] = parallel_io run_test(this_input, base, message, rtol, 1.e-15; tol_3V=tol_3V, args...) end @@ -402,7 +402,7 @@ function runtests() orig_base_input = deepcopy(base_input) # Also test not using parallel_io base_input["output"]["parallel_io"] = true - base_input["run_name"] *= "_parallel_io" + base_input["output"]["run_name"] *= "_parallel_io" do_tests(", parallel I/O") diff --git a/moment_kinetics/test/sound_wave_tests.jl b/moment_kinetics/test/sound_wave_tests.jl index 5e13533dc..006b18a69 100644 --- a/moment_kinetics/test/sound_wave_tests.jl +++ b/moment_kinetics/test/sound_wave_tests.jl @@ -47,7 +47,8 @@ test_input_finite_difference = OptionsDict("composition" => OptionsDict("n_ion_s "upar_phase" => 0.0, "temperature_amplitude" => 0.0, "temperature_phase" => 0.0), - "run_name" => "finite_difference", + "output" => OptionsDict("run_name" => "finite_difference", + "binary_format" => binary_format), "evolve_moments" => OptionsDict("density" => false, "parallel_flow" => false, "parallel_pressure" => false, @@ -80,18 +81,17 @@ test_input_finite_difference = OptionsDict("composition" => OptionsDict("n_ion_s "L" => 8.0, "bc" => "periodic", "discretization" => "finite_difference"), - "output" => OptionsDict("binary_format" => binary_format), ) test_input_finite_difference_split_1_moment = recursive_merge(test_input_finite_difference, - OptionsDict("run_name" => "finite_difference_split_1_moment", + OptionsDict("output" => OptionsDict("run_name" => "finite_difference_split_1_moment"), "evolve_moments" => OptionsDict("density" => true)) ) test_input_finite_difference_split_2_moments = recursive_merge(test_input_finite_difference_split_1_moment, - OptionsDict("run_name" => "finite_difference_split_2_moments", + OptionsDict("output" => OptionsDict("run_name" => "finite_difference_split_2_moments"), "evolve_moments" => OptionsDict("parallel_flow" => true), "vpa" => OptionsDict("ngrid" => 270, "L" => 12.0), "vz" => OptionsDict("ngrid" => 270, "L" => 12.0)) @@ -99,14 +99,14 @@ test_input_finite_difference_split_2_moments = test_input_finite_difference_split_3_moments = recursive_merge(test_input_finite_difference_split_2_moments, - OptionsDict("run_name" => "finite_difference_split_3_moments", + OptionsDict("output" => OptionsDict("run_name" => "finite_difference_split_3_moments"), "evolve_moments" => OptionsDict("parallel_pressure" => true), "vpa" => OptionsDict("ngrid" => 270, "L" => 12.0), "vz" => OptionsDict("ngrid" => 270, "L" => 12.0)) ) test_input_chebyshev = recursive_merge(test_input_finite_difference, - OptionsDict("run_name" => "chebyshev_pseudospectral", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral"), "z" => OptionsDict("discretization" => "chebyshev_pseudospectral", "ngrid" => 9, "nelement" => 2), @@ -120,17 +120,17 @@ test_input_chebyshev = recursive_merge(test_input_finite_difference, test_input_chebyshev_split_1_moment = recursive_merge(test_input_chebyshev, - OptionsDict("run_name" => "chebyshev_pseudospectral_split_1_moment", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral_split_1_moment"), "evolve_moments" => OptionsDict("density" => true))) test_input_chebyshev_split_2_moments = recursive_merge(test_input_chebyshev_split_1_moment, - OptionsDict("run_name" => "chebyshev_pseudospectral_split_2_moments", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral_split_2_moments"), "evolve_moments" => OptionsDict("parallel_flow" => true))) test_input_chebyshev_split_3_moments = recursive_merge(test_input_chebyshev_split_2_moments, - OptionsDict("run_name" => "chebyshev_pseudospectral_split_3_moments", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral_split_3_moments"), "evolve_moments" => OptionsDict("parallel_pressure" => true))) @@ -155,7 +155,7 @@ function run_test(test_input, analytic_frequency, analytic_growth_rate, return string(string(key)[1], value) end end - name = input["run_name"] + name = input["output"]["run_name"] shortname = name if length(args) > 0 name = string(name, "_", (string(k, "-", v, "_") for (k, v) in args)...) @@ -170,7 +170,7 @@ function run_test(test_input, analytic_frequency, analytic_growth_rate, # Update default inputs with values to be changed merge_dict_with_kwargs!(input; args...) - input["run_name"] = shortname + input["output"]["run_name"] = shortname # Suppress console output while running phi_fit = undef @@ -186,7 +186,7 @@ function run_test(test_input, analytic_frequency, analytic_growth_rate, # Load and analyse output ######################### - path = joinpath(realpath(input["base_directory"]), shortname, shortname) + path = joinpath(realpath(input["output"]["base_directory"]), shortname, shortname) # open the netcdf file and give it the handle 'fid' fid = open_readonly_output_file(path,"moments") @@ -793,30 +793,30 @@ function runtests() println("sound wave tests") @testset "finite difference" begin - test_input_finite_difference["base_directory"] = test_output_directory + test_input_finite_difference["output"]["base_directory"] = test_output_directory run_test_set_finite_difference() - test_input_finite_difference_split_1_moment["base_directory"] = test_output_directory + test_input_finite_difference_split_1_moment["output"]["base_directory"] = test_output_directory @long run_test_set_finite_difference_split_1_moment() - test_input_finite_difference_split_2_moments["base_directory"] = test_output_directory + test_input_finite_difference_split_2_moments["output"]["base_directory"] = test_output_directory @long run_test_set_finite_difference_split_2_moments() - test_input_finite_difference_split_3_moments["base_directory"] = test_output_directory + test_input_finite_difference_split_3_moments["output"]["base_directory"] = test_output_directory run_test_set_finite_difference_split_3_moments() end @testset "Chebyshev" begin - test_input_chebyshev["base_directory"] = test_output_directory + test_input_chebyshev["output"]["base_directory"] = test_output_directory run_test_set_chebyshev() - test_input_chebyshev_split_1_moment["base_directory"] = test_output_directory + test_input_chebyshev_split_1_moment["output"]["base_directory"] = test_output_directory run_test_set_chebyshev_split_1_moment() - test_input_chebyshev_split_2_moments["base_directory"] = test_output_directory + test_input_chebyshev_split_2_moments["output"]["base_directory"] = test_output_directory run_test_set_chebyshev_split_2_moments() - test_input_chebyshev_split_3_moments["base_directory"] = test_output_directory + test_input_chebyshev_split_3_moments["output"]["base_directory"] = test_output_directory run_test_set_chebyshev_split_3_moments() end end diff --git a/moment_kinetics/test/wall_bc_tests.jl b/moment_kinetics/test/wall_bc_tests.jl index 2f04c10ad..91cd2fa2d 100644 --- a/moment_kinetics/test/wall_bc_tests.jl +++ b/moment_kinetics/test/wall_bc_tests.jl @@ -54,7 +54,7 @@ test_input_finite_difference = OptionsDict("composition" => OptionsDict("n_ion_s "upar_phase" => 0.0, "temperature_amplitude" => 0.0, "temperature_phase" => 0.0), - "run_name" => "finite_difference", + "output" => OptionsDict("run_name" => "finite_difference"), "evolve_moments" => OptionsDict("density" => false, "parallel_flow" => false, "parallel_pressure" => false, @@ -87,7 +87,7 @@ test_input_finite_difference = OptionsDict("composition" => OptionsDict("n_ion_s ) test_input_chebyshev = recursive_merge(test_input_finite_difference, - OptionsDict("run_name" => "chebyshev_pseudospectral", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral"), "z" => OptionsDict("discretization" => "chebyshev_pseudospectral", "ngrid" => 9, "nelement" => 2, @@ -101,7 +101,7 @@ test_input_chebyshev = recursive_merge(test_input_finite_difference, )) test_input_chebyshev_sqrt_grid_odd = recursive_merge(test_input_finite_difference, - OptionsDict("run_name" => "chebyshev_pseudospectral", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral"), "z" => OptionsDict("discretization" => "chebyshev_pseudospectral", "ngrid" => 9, "nelement" => 5, # minimum nontrival nelement (odd) @@ -114,7 +114,7 @@ test_input_chebyshev_sqrt_grid_odd = recursive_merge(test_input_finite_differenc "nelement" => 10), )) test_input_chebyshev_sqrt_grid_even = recursive_merge(test_input_finite_difference, - OptionsDict("run_name" => "chebyshev_pseudospectral", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral"), "z" => OptionsDict("discretization" => "chebyshev_pseudospectral", "ngrid" => 9, "nelement" => 6, # minimum nontrival nelement (even) @@ -148,7 +148,7 @@ function run_test(test_input, expected_phi, tolerance; args...) input = deepcopy(test_input) # Convert keyword arguments to a unique name - name = input["run_name"] * ", with element spacing: " * input["z"]["element_spacing_option"] + name = input["output"]["run_name"] * ", with element spacing: " * input["z"]["element_spacing_option"] if length(args) > 0 name = string(name, "_", (string(k, "-", v, "_") for (k, v) in args)...) @@ -161,7 +161,7 @@ function run_test(test_input, expected_phi, tolerance; args...) # Update default inputs with values to be changed merge_dict_with_kwargs!(input; args...) - input["run_name"] = name + input["output"]["run_name"] = name # Suppress console output while running phi = undef @@ -175,7 +175,7 @@ function run_test(test_input, expected_phi, tolerance; args...) # Load and analyse output ######################### - path = joinpath(realpath(input["base_directory"]), name, name) + path = joinpath(realpath(input["output"]["base_directory"]), name, name) # open the netcdf file and give it the handle 'fid' fid = open_readonly_output_file(path,"moments") @@ -225,12 +225,12 @@ function runtests() println("Wall boundary condition tests") @testset_skip "FD test case does not conserve density" "finite difference" begin - test_input_finite_difference["base_directory"] = test_output_directory + test_input_finite_difference["output"]["base_directory"] = test_output_directory run_test(test_input_finite_difference, nothing, 2.e-3) end @testset "Chebyshev uniform" begin - test_input_chebyshev["base_directory"] = test_output_directory + test_input_chebyshev["output"]["base_directory"] = test_output_directory run_test(test_input_chebyshev, [-1.168944495073113, -0.747950464799219, -0.6947560093910274, -0.6917252594440765, -0.7180152693147238, -0.9980114030684668], @@ -238,7 +238,7 @@ function runtests() end @testset "Chebyshev sqrt grid odd" begin - test_input_chebyshev_sqrt_grid_odd["base_directory"] = test_output_directory + test_input_chebyshev_sqrt_grid_odd["output"]["base_directory"] = test_output_directory run_test(test_input_chebyshev_sqrt_grid_odd, [-1.2047298844053338, -0.9431378244038217, -0.8084332486925859, -0.7812620574297168, -0.7233303715713063, -0.700387877851292, @@ -248,7 +248,7 @@ function runtests() 2.e-3) end @testset "Chebyshev sqrt grid even" begin - test_input_chebyshev_sqrt_grid_even["base_directory"] = test_output_directory + test_input_chebyshev_sqrt_grid_even["output"]["base_directory"] = test_output_directory run_test(test_input_chebyshev_sqrt_grid_even, [-1.213617044609117, -1.0054529856551995, -0.8714447622540997, -0.836017704148175, -0.7552111126205924, -0.7264644278204795, diff --git a/performance-tests/sound_wave-2xres.jl b/performance-tests/sound_wave-2xres.jl index 89cf2e0b8..5c8f01e41 100644 --- a/performance-tests/sound_wave-2xres.jl +++ b/performance-tests/sound_wave-2xres.jl @@ -19,8 +19,8 @@ test_input_finite_difference = OptionsDict("composition" => OptionsDict("n_ion_s "n_neutral_species" => 1, "boltzmann_electron_response" => true, "T_e" => 1.0), - "run_name" => "finite_difference", - "base_directory" => test_output_directory, + "output" => OptionsDict("run_name" => "finite_difference", + "base_directory" => test_output_directory), "evolve_moments" => OptionsDict("density" => false, "parallel_flow" => false, "parallel_pressure" => false, @@ -71,21 +71,21 @@ test_input_finite_difference = OptionsDict("composition" => OptionsDict("n_ion_s test_input_finite_difference_split_1_moment = merge(test_input_finite_difference, - OptionsDict("run_name" => "finite_difference_split_1_moment", + OptionsDict("output" => OptionsDict("run_name" => "finite_difference_split_1_moment"), "evolve_moments_density" => true)) test_input_finite_difference_split_2_moments = merge(test_input_finite_difference_split_1_moment, - OptionsDict("run_name" => "finite_difference_split_2_moments", + OptionsDict("output" => OptionsDict("run_name" => "finite_difference_split_2_moments"), "evolve_moments_parallel_flow" => true)) test_input_finite_difference_split_3_moments = merge(test_input_finite_difference_split_2_moments, - OptionsDict("run_name" => "finite_difference_split_3_moments", + OptionsDict("output" => OptionsDict("run_name" => "finite_difference_split_3_moments"), "evolve_moments_parallel_pressure" => true)) test_input_chebyshev = recursive_merge(test_input_finite_difference, - OptionsDict("run_name" => "chebyshev_pseudospectral", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral"), "z" => OptionsDict("discretization" => "chebyshev_pseudospectral", "ngrid" => 9, "nelement" => 20), @@ -99,17 +99,17 @@ test_input_chebyshev = recursive_merge(test_input_finite_difference, test_input_chebyshev_split_1_moment = merge(test_input_chebyshev, - OptionsDict("run_name" => "chebyshev_pseudospectral_split_1_moment", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral_split_1_moment"), "evolve_moments_density" => true)) test_input_chebyshev_split_2_moments = merge(test_input_chebyshev_split_1_moment, - OptionsDict("run_name" => "chebyshev_pseudospectral_split_2_moments", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral_split_2_moments"), "evolve_moments_parallel_flow" => true)) test_input_chebyshev_split_3_moments = merge(test_input_chebyshev_split_2_moments, - OptionsDict("run_name" => "chebyshev_pseudospectral_split_3_moments", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral_split_3_moments"), "evolve_moments_parallel_pressure" => true)) inputs_list = (test_input_finite_difference, diff --git a/performance-tests/sound_wave.jl b/performance-tests/sound_wave.jl index fcbf60fe5..f2f7526be 100644 --- a/performance-tests/sound_wave.jl +++ b/performance-tests/sound_wave.jl @@ -19,8 +19,8 @@ test_input_finite_difference = OptionsDict("composition" => OptionsDict("n_ion_s "n_neutral_species" => 1, "boltzmann_electron_response" => true, "T_e" => 1.0), - "run_name" => "finite_difference", - "base_directory" => test_output_directory, + "output" => OptionsDict("run_name" => "finite_difference", + "base_directory" => test_output_directory), "evolve_moments" => OptionsDict("density" => false, "parallel_flow" => false, "parallel_pressure" => false, @@ -71,21 +71,21 @@ test_input_finite_difference = OptionsDict("composition" => OptionsDict("n_ion_s test_input_finite_difference_split_1_moment = merge(test_input_finite_difference, - OptionsDict("run_name" => "finite_difference_split_1_moment", + OptionsDict("output" => OptionsDict("run_name" => "finite_difference_split_1_moment"), "evolve_moments_density" => true)) test_input_finite_difference_split_2_moments = merge(test_input_finite_difference_split_1_moment, - OptionsDict("run_name" => "finite_difference_split_2_moments", + OptionsDict("output" => OptionsDict("run_name" => "finite_difference_split_2_moments"), "evolve_moments_parallel_flow" => true)) test_input_finite_difference_split_3_moments = merge(test_input_finite_difference_split_2_moments, - OptionsDict("run_name" => "finite_difference_split_3_moments", + OptionsDict("output" => OptionsDict("run_name" => "finite_difference_split_3_moments"), "evolve_moments_parallel_pressure" => true)) test_input_chebyshev = recursive_merge(test_input_finite_difference, - OptionsDict("run_name" => "chebyshev_pseudospectral", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral"), "z" => OptionsDict("discretization" => "chebyshev_pseudospectral", "ngrid" => 9, "nelement" => 10), @@ -99,17 +99,17 @@ test_input_chebyshev = recursive_merge(test_input_finite_difference, test_input_chebyshev_split_1_moment = merge(test_input_chebyshev, - OptionsDict("run_name" => "chebyshev_pseudospectral_split_1_moment", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral_split_1_moment"), "evolve_moments_density" => true)) test_input_chebyshev_split_2_moments = merge(test_input_chebyshev_split_1_moment, - OptionsDict("run_name" => "chebyshev_pseudospectral_split_2_moments", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral_split_2_moments"), "evolve_moments_parallel_flow" => true)) test_input_chebyshev_split_3_moments = merge(test_input_chebyshev_split_2_moments, - OptionsDict("run_name" => "chebyshev_pseudospectral_split_3_moments", + OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral_split_3_moments"), "evolve_moments_parallel_pressure" => true)) inputs_list = (test_input_finite_difference, diff --git a/performance-tests/utils.jl b/performance-tests/utils.jl index 89f634179..09a4cbcfd 100644 --- a/performance-tests/utils.jl +++ b/performance-tests/utils.jl @@ -246,7 +246,7 @@ Returns [minimum time, median time, maximum time] """ function run_test(input) - message = input["run_name"] * " ($(block_size[]) procs)" + message = input["output"]["run_name"] * " ($(block_size[]) procs)" _println0(message) _println0("=" ^ length(message)) _println0() diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/plot_dispersion_relation.jl b/publication_inputs/2023_EFTC_jto-poster/sound-wave/plot_dispersion_relation.jl index e70ea22e5..110844dc9 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/plot_dispersion_relation.jl +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/plot_dispersion_relation.jl @@ -293,7 +293,7 @@ end function get_sim_omega_gamma(sim) try s = nothing - open(joinpath("..", "..", sim["base_directory"], sim["run_name"], basename(sim["run_name"]) * ".frequency_fit.txt"), + open(joinpath("..", "..", sim["output"]["base_directory"], sim["output"]["run_name"], basename(sim["output"]["run_name"]) * ".frequency_fit.txt"), "r") do io s = split(readline(io)) end @@ -310,7 +310,7 @@ function get_sim_omega_gamma(sim) return omega, gamma catch e - println("Error for ", sim["run_name"], " ", e) + println("Error for ", sim["output"]["run_name"], " ", e) return NaN, NaN end end diff --git a/util/get-run-name.jl b/util/get-run-name.jl index fdbb66a59..ae228182d 100755 --- a/util/get-run-name.jl +++ b/util/get-run-name.jl @@ -20,7 +20,10 @@ end input = TOML.parsefile(inputfile) if "run_name" ∈ keys(input) + # Old position for option run_name = input["run_name"] +elseif "output" ∈ keys(input) && "run_name" ∈ keys(input["output"]) + run_name = input["output"]["run_name"] else # For branch with run name from input file name, should handle that here... run_name = basename(splitext(inputfile)[1]) diff --git a/util/precompile_makie_plots.jl b/util/precompile_makie_plots.jl index 2019a62dd..7ef17e57f 100644 --- a/util/precompile_makie_plots.jl +++ b/util/precompile_makie_plots.jl @@ -7,8 +7,8 @@ test_output_directory = tempname() run_name = "precompilation" mkpath(test_output_directory) -input_dict = OptionsDict("run_name"=>run_name, - "base_directory" => test_output_directory, +input_dict = OptionsDict("output" => OptionsDict("run_name"=>run_name, + "base_directory" => test_output_directory), "r" => OptionsDict("ngrid" => 5, "nelement" => 1, "bc" => "periodic", diff --git a/util/precompile_plots_plots.jl b/util/precompile_plots_plots.jl index 17cb7061d..595f7d42a 100644 --- a/util/precompile_plots_plots.jl +++ b/util/precompile_plots_plots.jl @@ -7,8 +7,8 @@ test_output_directory = tempname() run_name = "precompilation" mkpath(test_output_directory) -input_dict = OptionsDict("run_name"=>run_name, - "base_directory" => test_output_directory, +input_dict = OptionsDict("output" => OptionsDict("run_name"=>run_name, + "base_directory" => test_output_directory), "r" => OptionsDict("ngrid" => 5, "nelement" => 1, "bc" => "periodic", diff --git a/util/precompile_run.jl b/util/precompile_run.jl index bb1f460fe..09158e055 100644 --- a/util/precompile_run.jl +++ b/util/precompile_run.jl @@ -10,8 +10,8 @@ using moment_kinetics.type_definitions: OptionsDict test_output_directory = tempname() mkpath(test_output_directory) -base_input = OptionsDict("run_name" => "precompilation", - "base_directory" => test_output_directory, +base_input = OptionsDict("output" => OptionsDict("run_name" => "precompilation", + "base_directory" => test_output_directory), "r" => OptionsDict("ngrid" => 5, "nelement" => 3, "bc" => "periodic", diff --git a/util/precompile_run_kinetic-electrons.jl b/util/precompile_run_kinetic-electrons.jl index 4f9dd0ff7..28e8957e7 100644 --- a/util/precompile_run_kinetic-electrons.jl +++ b/util/precompile_run_kinetic-electrons.jl @@ -9,8 +9,8 @@ using moment_kinetics.type_definitions: OptionsDict test_output_directory = tempname() mkpath(test_output_directory) -input = OptionsDict("run_name" => "precompilation", - "base_directory" => test_output_directory, +input = OptionsDict("output" => OptionsDict("run_name" => "precompilation", + "base_directory" => test_output_directory), "evolve_moments" => OptionsDict("density" => true, "parallel_flow" => true, "parallel_pressure" => true), diff --git a/util/precompile_run_long.jl b/util/precompile_run_long.jl index 53274805b..ce139406b 100644 --- a/util/precompile_run_long.jl +++ b/util/precompile_run_long.jl @@ -13,8 +13,8 @@ using moment_kinetics.utils: recursive_merge test_output_directory = tempname() mkpath(test_output_directory) -base_input = OptionsDict("run_name"=>"precompilation", - "base_directory" => test_output_directory, +base_input = OptionsDict("output" => OptionsDict("run_name"=>"precompilation", + "base_directory" => test_output_directory), "z" => OptionsDict("ngrid" => 5, "nelement" => 1, "bc" => "periodic", diff --git a/util/precompile_run_long_debug1.jl b/util/precompile_run_long_debug1.jl index 3f6c16b66..228be341b 100644 --- a/util/precompile_run_long_debug1.jl +++ b/util/precompile_run_long_debug1.jl @@ -13,8 +13,8 @@ using moment_kinetics.utils: recursive_merge test_output_directory = tempname() mkpath(test_output_directory) -base_input = OptionsDict("run_name"=>"precompilation", - "base_directory" => test_output_directory, +base_input = OptionsDict("output" => OptionsDict("run_name"=>"precompilation", + "base_directory" => test_output_directory), "z" => OptionsDict("ngrid" => 5, "nelement" => 1, "bc" => "periodic", diff --git a/util/precompile_run_short.jl b/util/precompile_run_short.jl index 458cf803f..468ce6149 100644 --- a/util/precompile_run_short.jl +++ b/util/precompile_run_short.jl @@ -9,8 +9,8 @@ using moment_kinetics.type_definitions: OptionsDict test_output_directory = tempname() mkpath(test_output_directory) -input_dict = Dict("run_name"=>"precompilation", - "base_directory" => test_output_directory, +input_dict = Dict("output" => OptionsDict("run_name"=>"precompilation", + "base_directory" => test_output_directory), "timestepping" => OptionsDict("nstep" => 1, "dt" => 2.0e-11)) to = TimerOutput() From 6c147bcbb27090f95621a8cb5138b0822460c875 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Mon, 9 Sep 2024 15:17:09 +0100 Subject: [PATCH 33/87] Check that no unexpected section names were used in an input file Unexpected section names are probably typos, so we error so that the user can fix them rather than having any options in them be silently ignored. --- .../src/makie_post_processing.jl | 3 + moment_kinetics/src/input_structs.jl | 47 ++++++++++- moment_kinetics/src/moment_kinetics_input.jl | 30 ++++--- moment_kinetics/src/nonlinear_solvers.jl | 9 +- moment_kinetics/src/time_advance.jl | 82 ++++++++----------- .../test/nonlinear_solver_tests.jl | 20 +++-- 6 files changed, 124 insertions(+), 67 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 9ed10e13a..7e57dc3ab 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 @@ -817,6 +817,9 @@ function _setup_single_input!(this_input_dict::OrderedDict{String,Any}, animate_steady_state_residual=false, ) + # We allow top-level options in the post-processing input file + check_sections!(this_input_dict; check_no_top_level_options=false) + return nothing end diff --git a/moment_kinetics/src/input_structs.jl b/moment_kinetics/src/input_structs.jl index 897654d2a..8c1aaf350 100644 --- a/moment_kinetics/src/input_structs.jl +++ b/moment_kinetics/src/input_structs.jl @@ -14,7 +14,7 @@ export io_input export pp_input export geometry_input export set_defaults_and_check_top_level!, set_defaults_and_check_section!, - options_to_TOML, Dict_to_NamedTuple + check_sections!, options_to_TOML, Dict_to_NamedTuple using ..communication using ..type_definitions: mk_float, mk_int @@ -660,6 +660,8 @@ function set_defaults_and_check_top_level!(options::AbstractDict; kwargs...) return options end +const _section_check_store_name = "_section_check_store" + """ Set the defaults for options in a section, and check that there are not any unexpected options (i.e. options that have no default). @@ -701,9 +703,52 @@ function set_defaults_and_check_section!(options::AbstractDict, section_name; section[key] = get(section, key, default_value) end + # Record the defined section_name in a temporary, private subsection of `options`, so + # we can use it to check the existing sections later. + if !(_section_check_store_name ∈ keys(options)) + # If section is not present, create it + options[_section_check_store_name] = String[] + end + push!(options[_section_check_store_name], section_name) + return section end +""" + check_sections!(options::AbstractDict) + +Check that there are no unexpected sections in `options`. The 'expected sections' are the +ones that were defined with [`set_defaults_and_check_section!`](@ref). +""" +function check_sections!(options::AbstractDict; check_no_top_level_options=true) + + expected_section_names = pop!(options, _section_check_store_name) + + unexpected_section_names = String[] + unexpected_top_level_options = String[] + for (k,v) ∈ pairs(options) + if isa(v, AbstractDict) + if k ∉ expected_section_names + push!(unexpected_section_names, k) + end + elseif check_no_top_level_options + push!(unexpected_top_level_options, k) + end + end + + if length(unexpected_section_names) > 0 && length(unexpected_top_level_options) > 0 + error("Input had unexpected sections $unexpected_section_names, and unexpected " + * "options in the top level $unexpected_top_level_options") + elseif length(unexpected_section_names) > 0 + error("Input had unexpected sections $unexpected_section_names.") + elseif length(unexpected_top_level_options) > 0 + error("Input had unexpected options in the top level " + * "$unexpected_top_level_options") + end + + return nothing +end + """ Convert a Dict whose keys are String or Symbol to a NamedTuple diff --git a/moment_kinetics/src/moment_kinetics_input.jl b/moment_kinetics/src/moment_kinetics_input.jl index 2fe9e7c2d..d783ae72f 100644 --- a/moment_kinetics/src/moment_kinetics_input.jl +++ b/moment_kinetics/src/moment_kinetics_input.jl @@ -81,9 +81,10 @@ function mk_input(scan_input=OptionsDict(); save_inputs_to_txt=false, ignore_MPI for opt in removed_options_list if opt ∈ keys(scan_input) error("Option '$opt' is no longer used. Please update your input file. The " - * "option may have been moved into an input file section. You may need " - * "to set some new options to replicate the effect of the removed ones." - ) + * "option may have been moved into an input file section - there are " + * "no longer any top-level options (i.e. ones not in a section). You " + * "may need to set some new options to replicate the effect of the " + * "removed ones.") end end @@ -460,13 +461,6 @@ function mk_input(scan_input=OptionsDict(); save_inputs_to_txt=false, ignore_MPI num_diss_params = setup_numerical_dissipation(scan_input) - if global_rank[] == 0 && save_inputs_to_txt - # Make file to log some information about inputs into. - io = open_ascii_output_file(string(output_dir,"/",io_settings["run_name"]), "input") - else - io = devnull - end - geometry = init_magnetic_geometry(geometry_in,z,r) if any(geometry.dBdz .!= 0.0) && (evolve_moments.density || evolve_moments.parallel_flow || @@ -475,6 +469,22 @@ function mk_input(scan_input=OptionsDict(); save_inputs_to_txt=false, ignore_MPI end species_immutable = (ion = composition.ion, neutral = composition.neutral) + + # Ideally `check_sections!(scan_input) would be called here to check that no + # unexpected sections or top-level options were passed (helps to catch typos in input + # files). However, it needs to be called after calls to `setup_nonlinear_solve()` + # because the inputs for nonlinear solvers are only read there, but before electron + # setup, because `input_dict` needs to be written to the output files, and it cannot + # be with the `_section_check_store` variable still contained in it (which is used and + # removed by `check_sections!()`) - it therefore has to be called in the middle of + # `setup_time_advance!()`. + + if global_rank[] == 0 && save_inputs_to_txt + # Make file to log some information about inputs into. + io = open_ascii_output_file(string(output_dir,"/",io_settings["run_name"]), "input") + else + io = devnull + end # check input (and initialized coordinate structs) to catch errors/unsupported options check_input(io, output_dir, timestepping_section["nstep"], timestepping_section["dt"], r, z, diff --git a/moment_kinetics/src/nonlinear_solvers.jl b/moment_kinetics/src/nonlinear_solvers.jl index 365b91295..5726da782 100644 --- a/moment_kinetics/src/nonlinear_solvers.jl +++ b/moment_kinetics/src/nonlinear_solvers.jl @@ -74,7 +74,7 @@ layout of the variable to be solved (i.e. fastest-varying first). The nonlinear solver will be called inside a loop over `outer_coords`, so we might need for example a preconditioner object for each point in that outer loop. """ -function setup_nonlinear_solve(input_dict, coords, outer_coords=(); default_rtol=1.0e-5, +function setup_nonlinear_solve(active, input_dict, coords, outer_coords=(); default_rtol=1.0e-5, default_atol=1.0e-12, serial_solve=false, electron_ppar_pdf_solve=false, preconditioner_type=nothing) nl_solver_section = set_defaults_and_check_section!( @@ -88,6 +88,13 @@ function setup_nonlinear_solve(input_dict, coords, outer_coords=(); default_rtol linear_max_restarts=0, preconditioner_update_interval=300, ) + + if !active + # This solver will not be used. Return here, after reading the options, so that we + # can always check that input file sections are supposed to exist. + return nothing + end + nl_solver_input = Dict_to_NamedTuple(nl_solver_section) coord_sizes = Tuple(isa(c, coordinate) ? c.n : c for c ∈ coords) diff --git a/moment_kinetics/src/time_advance.jl b/moment_kinetics/src/time_advance.jl index 153267f4f..f2309c579 100644 --- a/moment_kinetics/src/time_advance.jl +++ b/moment_kinetics/src/time_advance.jl @@ -655,52 +655,34 @@ function setup_time_advance!(pdf, fields, vz, vr, vzeta, vpa, vperp, z, r, gyrop # Set up parameters for Jacobian-free Newton-Krylov solver used for implicit part of # timesteps. - if t_params.implicit_braginskii_conduction - # Should really have options to set solver tolerance, etc. - electron_conduction_nl_solve_parameters = setup_nonlinear_solve(input_dict, (z=z,); - default_rtol=t_params.rtol / 10.0, - default_atol=t_params.atol / 10.0) - else - electron_conduction_nl_solve_parameters = nothing - end - if t_params.implicit_electron_advance - nl_solver_electron_advance_params = - setup_nonlinear_solve(input_dict, - (r=r, z=z, vperp=vperp, vpa=vpa), - (); - default_rtol=t_params.rtol / 10.0, - default_atol=t_params.atol / 10.0, - electron_ppar_pdf_solve=true, - preconditioner_type="lu") - else - nl_solver_electron_advance_params = nothing - end - if t_params.implicit_ion_advance - # Implicit solve for vpa_advection term should be done in serial, as it will be - # called within a parallelised s_r_z_vperp loop. - nl_solver_ion_advance_params = - setup_nonlinear_solve(input_dict, - (s=composition.n_ion_species, r=r, z=z, vperp=vperp, - vpa=vpa), - (); - default_rtol=t_params.rtol / 10.0, - default_atol=t_params.atol / 10.0, - preconditioner_type="lu") - else - nl_solver_ion_advance_params = nothing - end - if t_params.implicit_vpa_advection - # Implicit solve for vpa_advection term should be done in serial, as it will be - # called within a parallelised s_r_z_vperp loop. - nl_solver_vpa_advection_params = - setup_nonlinear_solve(input_dict, (vpa=vpa,), - (composition.n_ion_species, r, z, vperp); - default_rtol=t_params.rtol / 10.0, - default_atol=t_params.atol / 10.0, - serial_solve=true, preconditioner_type="lu") - else - nl_solver_vpa_advection_params = nothing - end + electron_conduction_nl_solve_parameters = setup_nonlinear_solve(t_params.implicit_braginskii_conduction, + input_dict, (z=z,); + default_rtol=t_params.rtol / 10.0, + default_atol=t_params.atol / 10.0) + nl_solver_electron_advance_params = + setup_nonlinear_solve(t_params.implicit_electron_advance, input_dict, + (r=r, z=z, vperp=vperp, vpa=vpa), + (); + default_rtol=t_params.rtol / 10.0, + default_atol=t_params.atol / 10.0, + electron_ppar_pdf_solve=true, + preconditioner_type="lu") + nl_solver_ion_advance_params = + setup_nonlinear_solve(t_params.implicit_ion_advance, input_dict, + (s=composition.n_ion_species, r=r, z=z, vperp=vperp, + vpa=vpa), + (); + default_rtol=t_params.rtol / 10.0, + default_atol=t_params.atol / 10.0, + preconditioner_type="lu") + # Implicit solve for vpa_advection term should be done in serial, as it will be called + # within a parallelised s_r_z_vperp loop. + nl_solver_vpa_advection_params = + setup_nonlinear_solve(t_params.implicit_vpa_advection, input_dict, (vpa=vpa,), + (composition.n_ion_species, r, z, vperp); + default_rtol=t_params.rtol / 10.0, + default_atol=t_params.atol / 10.0, + serial_solve=true, preconditioner_type="lu") if nl_solver_ion_advance_params !== nothing && nl_solver_vpa_advection_params !== nothing error("Cannot use implicit_ion_advance and implicit_vpa_advection at the same " @@ -715,6 +697,14 @@ function setup_time_advance!(pdf, fields, vz, vr, vzeta, vpa, vperp, z, r, gyrop ion_advance=nl_solver_ion_advance_params, vpa_advection=nl_solver_vpa_advection_params,) + # Check that no unexpected sections or top-level options were passed (helps to catch + # typos in input files). Needs to be called after calls to `setup_nonlinear_solve()` + # because the inputs for nonlinear solvers are only read there, but before electron + # setup, because `input_dict` needs to be written to the output files, and it cannot + # be with the `_section_check_store` variable still contained in it (which is used and + # removed by `check_sections!()`). + check_sections!(input_dict) + begin_serial_region() # create an array of structs containing scratch arrays for the pdf and low-order moments diff --git a/moment_kinetics/test/nonlinear_solver_tests.jl b/moment_kinetics/test/nonlinear_solver_tests.jl index 4b70e57c7..806f399e3 100644 --- a/moment_kinetics/test/nonlinear_solver_tests.jl +++ b/moment_kinetics/test/nonlinear_solver_tests.jl @@ -113,11 +113,12 @@ function linear_test() end nl_solver_params = setup_nonlinear_solve( + true, OptionsDict("nonlinear_solver" => - OptionsDict("rtol" => 0.0, - "atol" => atol, - "linear_restart" => restart, - "linear_max_restarts" => max_restarts)), + OptionsDict("rtol" => 0.0, + "atol" => atol, + "linear_restart" => restart, + "linear_max_restarts" => max_restarts)), coords; serial_solve=serial_solve) newton_solve!(x, rhs_func!, residual, delta_x, rhs_delta, v, w, nl_solver_params; @@ -245,12 +246,13 @@ function nonlinear_test() end nl_solver_params = setup_nonlinear_solve( + true, OptionsDict("nonlinear_solver" => - OptionsDict("rtol" => 0.0, - "atol" => atol, - "linear_restart" => restart, - "linear_max_restarts" => max_restarts, - "nonlinear_max_iterations" => 100)), + OptionsDict("rtol" => 0.0, + "atol" => atol, + "linear_restart" => restart, + "linear_max_restarts" => max_restarts, + "nonlinear_max_iterations" => 100)), coords; serial_solve=serial_solve) newton_solve!(x, rhs_func!, residual, delta_x, rhs_delta, v, w, nl_solver_params; From 94ef6c13cc6bcd20e8e8171fb7e4869e57c09666 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Mon, 9 Sep 2024 15:27:51 +0100 Subject: [PATCH 34/87] Fix override of "write_error_diagnostics" setting This setting is now in the [timestepping] section. --- moment_kinetics/src/time_advance.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/moment_kinetics/src/time_advance.jl b/moment_kinetics/src/time_advance.jl index f2309c579..b593c6c1c 100644 --- a/moment_kinetics/src/time_advance.jl +++ b/moment_kinetics/src/time_advance.jl @@ -325,7 +325,7 @@ function setup_time_info(t_input, n_variables, code_time, dt_reload, # Makes no sense to use write_error_diagnostics because non-adaptive schemes have # no error estimate - input_dict["write_error_diagnostics"] = false + input_dict["timestepping"]["write_error_diagnostics"] = false end if adaptive && t_input["write_error_diagnostics"] && !t_input["write_after_fixed_step_count"] From 02e10d7266c2773429ead4f84c21b4cdfd194257 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Mon, 9 Sep 2024 16:38:13 +0100 Subject: [PATCH 35/87] Remove/update unused options from inputs --- examples/geometry/1D-mirror.toml | 3 ++- .../wall-bc_recyclefraction0.5_split3_fekete42.toml | 5 ++++- .../wall-bc_recyclefraction0.5_split3_fekete64.toml | 11 +++++++---- .../wall-bc_recyclefraction0.5_split3_rkf54.toml | 5 ++++- examples/wall-bc/wall+sheath-bc.toml | 4 ++-- examples/wall-bc/wall-bc_no-neutrals.toml | 6 ++---- examples/wall-bc/wall-bc_no-neutrals_split1.toml | 6 ++---- examples/wall-bc/wall-bc_no-neutrals_split2.toml | 6 ++---- examples/wall-bc/wall-bc_no-neutrals_split3.toml | 6 ++---- moment_kinetics/debug_test/gyroaverage_inputs.jl | 4 ++-- moment_kinetics/debug_test/kinetic_electron_inputs.jl | 8 ++++++-- .../debug_test/recycling_fraction_inputs.jl | 6 ++++-- moment_kinetics/debug_test/sound_wave_inputs.jl | 3 +-- moment_kinetics/test/recycling_fraction_tests.jl | 6 ++++-- .../sound-wave/scan_sound-wave_T0.25.toml | 1 - .../sound-wave/scan_sound-wave_T0.25_split1.toml | 1 - .../sound-wave/scan_sound-wave_T0.25_split2.toml | 1 - .../sound-wave/scan_sound-wave_T0.25_split3.toml | 1 - .../sound-wave/scan_sound-wave_T0.5.toml | 1 - .../sound-wave/scan_sound-wave_T0.5_split1.toml | 1 - .../sound-wave/scan_sound-wave_T0.5_split2.toml | 1 - .../sound-wave/scan_sound-wave_T0.5_split3.toml | 1 - .../sound-wave/scan_sound-wave_T1.toml | 1 - .../sound-wave/scan_sound-wave_T1_split1.toml | 1 - .../sound-wave/scan_sound-wave_T1_split2.toml | 1 - .../sound-wave/scan_sound-wave_T1_split3.toml | 1 - .../sound-wave/scan_sound-wave_T2.toml | 1 - .../sound-wave/scan_sound-wave_T2_split1.toml | 1 - .../sound-wave/scan_sound-wave_T2_split2.toml | 1 - .../sound-wave/scan_sound-wave_T2_split3.toml | 1 - .../sound-wave/scan_sound-wave_T4.toml | 1 - .../sound-wave/scan_sound-wave_T4_split1.toml | 1 - .../sound-wave/scan_sound-wave_T4_split2.toml | 1 - .../sound-wave/scan_sound-wave_T4_split3.toml | 1 - .../sound-wave/scan_sound-wave_nratio.toml | 1 - .../sound-wave/scan_sound-wave_nratio_split1.toml | 1 - .../sound-wave/scan_sound-wave_nratio_split2.toml | 1 - .../wall-bc/wall-bc_recyclefraction0.5.toml | 1 - .../wall-bc/wall-bc_recyclefraction0.5_split1.toml | 1 - .../wall-bc/wall-bc_recyclefraction0.5_split2.toml | 1 - .../wall-bc/wall-bc_recyclefraction0.5_split3.toml | 1 - 41 files changed, 44 insertions(+), 62 deletions(-) diff --git a/examples/geometry/1D-mirror.toml b/examples/geometry/1D-mirror.toml index 26223c68c..b9e0a7123 100644 --- a/examples/geometry/1D-mirror.toml +++ b/examples/geometry/1D-mirror.toml @@ -46,7 +46,8 @@ n_neutral_species = 0 electron_physics = "boltzmann_electron_response" T_e = 1.0 T_wall = 1.0 -[ion_species] + +[ion_species_1] initial_density = 1.0 initial_temperature = 1.0 diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete42.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete42.toml index 62fb507bc..f1bd9f217 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete42.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete42.toml @@ -114,8 +114,11 @@ z_width = 0.125 source_strength = 2.0 source_T = 2.0 -[numerical_dissipation] +[ion_numerical_dissipation] #vpa_dissipation_coefficient = 1.0e-1 #vpa_dissipation_coefficient = 1.0e-2 #vpa_dissipation_coefficient = 1.0e-3 force_minimum_pdf_value = 0.0 + +[neutral_numerical_dissipation] +force_minimum_pdf_value = 0.0 diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete64.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete64.toml index d12f5d367..a5033a9c9 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete64.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_fekete64.toml @@ -114,8 +114,11 @@ z_width = 0.125 source_strength = 2.0 source_T = 2.0 -[numerical_dissipation] -#vz_dissipation_coefficient = 1.0e-1 -#vz_dissipation_coefficient = 1.0e-2 -#vz_dissipation_coefficient = 1.0e-3 +[ion_numerical_dissipation] +#vpa_dissipation_coefficient = 1.0e-1 +#vpa_dissipation_coefficient = 1.0e-2 +#vpa_dissipation_coefficient = 1.0e-3 +force_minimum_pdf_value = 0.0 + +[neutral_numerical_dissipation] force_minimum_pdf_value = 0.0 diff --git a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_rkf54.toml b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_rkf54.toml index ae6ceea48..783dd3a73 100644 --- a/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_rkf54.toml +++ b/examples/recycling-fraction/wall-bc_recyclefraction0.5_split3_rkf54.toml @@ -114,8 +114,11 @@ z_width = 0.125 source_strength = 2.0 source_T = 2.0 -[numerical_dissipation] +[ion_numerical_dissipation] #vpa_dissipation_coefficient = 1.0e-1 #vpa_dissipation_coefficient = 1.0e-2 #vpa_dissipation_coefficient = 1.0e-3 force_minimum_pdf_value = 0.0 + +[neutral_numerical_dissipation] +force_minimum_pdf_value = 0.0 diff --git a/examples/wall-bc/wall+sheath-bc.toml b/examples/wall-bc/wall+sheath-bc.toml index af58d4b18..cb62a6173 100644 --- a/examples/wall-bc/wall+sheath-bc.toml +++ b/examples/wall-bc/wall+sheath-bc.toml @@ -65,7 +65,7 @@ temperature_phase = 0.0 initial_density = 1.0 initial_temperature = 1.0 -[z_IC_eutral_species_1] +[z_IC_neutral_species_1] initialization_option = "gaussian" density_amplitude = 0.001 density_phase = 0.0 @@ -74,7 +74,7 @@ upar_phase = 0.0 temperature_amplitude = 0.0 temperature_phase = 0.0 -[vpa_IC_eutral_species_1] +[vz_IC_neutral_species_1] initialization_option = "gaussian" density_amplitude = 1.0 density_phase = 0.0 diff --git a/examples/wall-bc/wall-bc_no-neutrals.toml b/examples/wall-bc/wall-bc_no-neutrals.toml index c312c943e..4a609dc44 100644 --- a/examples/wall-bc/wall-bc_no-neutrals.toml +++ b/examples/wall-bc/wall-bc_no-neutrals.toml @@ -1,7 +1,3 @@ -steady_state_residual = true -converged_residual_value = 1.0e-3 -runtime_plots = true - [evolve_moments] density = false parallel_flow = false @@ -69,6 +65,8 @@ dt = 5.0e-4 nwrite = 5000 nwrite_dfns = 5000 split_operators = false +steady_state_residual = true +converged_residual_value = 1.0e-3 [ion_source] active = true diff --git a/examples/wall-bc/wall-bc_no-neutrals_split1.toml b/examples/wall-bc/wall-bc_no-neutrals_split1.toml index 13e40d68b..c67dc4ef7 100644 --- a/examples/wall-bc/wall-bc_no-neutrals_split1.toml +++ b/examples/wall-bc/wall-bc_no-neutrals_split1.toml @@ -1,7 +1,3 @@ -steady_state_residual = true -converged_residual_value = 1.0e-3 -runtime_plots = true - [evolve_moments] density = true parallel_flow = false @@ -69,6 +65,8 @@ dt = 1.0e-4 nwrite = 5000 nwrite_dfns = 5000 split_operators = false +steady_state_residual = true +converged_residual_value = 1.0e-3 [ion_source] active = true diff --git a/examples/wall-bc/wall-bc_no-neutrals_split2.toml b/examples/wall-bc/wall-bc_no-neutrals_split2.toml index fab70061c..f5dbd5f05 100644 --- a/examples/wall-bc/wall-bc_no-neutrals_split2.toml +++ b/examples/wall-bc/wall-bc_no-neutrals_split2.toml @@ -1,7 +1,3 @@ -steady_state_residual = true -converged_residual_value = 1.0e-3 -runtime_plots = true - [evolve_moments] density = true parallel_flow = true @@ -69,6 +65,8 @@ dt = 1.0e-4 nwrite = 5000 nwrite_dfns = 5000 split_operators = false +steady_state_residual = true +converged_residual_value = 1.0e-3 [ion_source] active = true diff --git a/examples/wall-bc/wall-bc_no-neutrals_split3.toml b/examples/wall-bc/wall-bc_no-neutrals_split3.toml index 5c58cc7d0..0b0c525eb 100644 --- a/examples/wall-bc/wall-bc_no-neutrals_split3.toml +++ b/examples/wall-bc/wall-bc_no-neutrals_split3.toml @@ -1,7 +1,3 @@ -steady_state_residual = true -converged_residual_value = 1.0e-3 -runtime_plots = true - [evolve_moments] density = true parallel_flow = true @@ -69,6 +65,8 @@ dt = 1.0e-4 nwrite = 5000 nwrite_dfns = 5000 split_operators = false +steady_state_residual = true +converged_residual_value = 1.0e-3 [ion_source] active = true diff --git a/moment_kinetics/debug_test/gyroaverage_inputs.jl b/moment_kinetics/debug_test/gyroaverage_inputs.jl index 660df7203..677c47689 100644 --- a/moment_kinetics/debug_test/gyroaverage_inputs.jl +++ b/moment_kinetics/debug_test/gyroaverage_inputs.jl @@ -58,8 +58,8 @@ test_input = OptionsDict( "L" => 6.0, "bc" => "zero", "discretization" => "chebyshev_pseudospectral"), - "numerical_dissipation" => OptionsDict("vpa_dissipation_coefficient" => 1.0e-3, - "vperp_dissipation_coefficient" => 1.0e-3), + "ion_numerical_dissipation" => OptionsDict("vpa_dissipation_coefficient" => 1.0e-3, + "vperp_dissipation_coefficient" => 1.0e-3), "geometry" => OptionsDict("DeltaB"=>0.0, "option"=>"constant-helical", "pitch"=>0.1, diff --git a/moment_kinetics/debug_test/kinetic_electron_inputs.jl b/moment_kinetics/debug_test/kinetic_electron_inputs.jl index c1304f595..48c96c95d 100644 --- a/moment_kinetics/debug_test/kinetic_electron_inputs.jl +++ b/moment_kinetics/debug_test/kinetic_electron_inputs.jl @@ -87,8 +87,12 @@ test_input = OptionsDict("composition" => OptionsDict("n_ion_species" => 1, "source_strength" => 2.0, "source_T" => 2.0), "krook_collisions" => OptionsDict("use_krook" => true), - "numerical_dissipation" => OptionsDict("force_minimum_pdf_value" => 0.0, - "vpa_dissipation_coefficient" => 1e-2)) + "ion_numerical_dissipation" => OptionsDict("force_minimum_pdf_value" => 0.0, + "vpa_dissipation_coefficient" => 1e-2), + "electron_numerical_dissipation" => OptionsDict("force_minimum_pdf_value" => 0.0, + "vpa_dissipation_coefficient" => 1e-2), + "neutral_numerical_dissipation" => OptionsDict("force_minimum_pdf_value" => 0.0, + "vz_dissipation_coefficient" => 1e-2)) test_input_list = [ diff --git a/moment_kinetics/debug_test/recycling_fraction_inputs.jl b/moment_kinetics/debug_test/recycling_fraction_inputs.jl index 5ee3f4b22..4ef4e428b 100644 --- a/moment_kinetics/debug_test/recycling_fraction_inputs.jl +++ b/moment_kinetics/debug_test/recycling_fraction_inputs.jl @@ -95,8 +95,10 @@ test_input_split3 = recursive_merge(test_input_split2, "evolve_moments" => OptionsDict("parallel_pressure" => true), "vpa" => OptionsDict("nelement" => 8), "vz" => OptionsDict("nelement" => 8), - "numerical_dissipation" => OptionsDict("force_minimum_pdf_value" => 0.0, - "vpa_dissipation_coefficient" => 1e-2))) + "ion_numerical_dissipation" => OptionsDict("force_minimum_pdf_value" => 0.0, + "vpa_dissipation_coefficient" => 1e-2), + "neutral_numerical_dissipation" => OptionsDict("force_minimum_pdf_value" => 0.0, + "vz_dissipation_coefficient" => 1e-2))) test_input_split3["timestepping"] = recursive_merge(test_input_split3["timestepping"], OptionsDict("dt" => 1.0e-9, "minimum_dt" => 1.0e-9)) diff --git a/moment_kinetics/debug_test/sound_wave_inputs.jl b/moment_kinetics/debug_test/sound_wave_inputs.jl index 03badf889..9f91fa239 100644 --- a/moment_kinetics/debug_test/sound_wave_inputs.jl +++ b/moment_kinetics/debug_test/sound_wave_inputs.jl @@ -221,8 +221,7 @@ recursive_merge(test_input_chebyshev_1D1V_split_1_moment, test_input_chebyshev_1D1V_split_3_moments = recursive_merge(test_input_chebyshev_1D1V_split_2_moments, OptionsDict("output" => OptionsDict("run_name" => "chebyshev_pseudospectral_1D1V_split_3_moments"), - "evolve_moments" => OptionsDict("parallel_pressure" => true), - "runtime_plots" => true)) + "evolve_moments" => OptionsDict("parallel_pressure" => true))) test_input_chebyshev_cx0_1D1V = recursive_merge(test_input_chebyshev_1D1V, diff --git a/moment_kinetics/test/recycling_fraction_tests.jl b/moment_kinetics/test/recycling_fraction_tests.jl index 96f2ef32c..29ab2e773 100644 --- a/moment_kinetics/test/recycling_fraction_tests.jl +++ b/moment_kinetics/test/recycling_fraction_tests.jl @@ -154,8 +154,10 @@ test_input_adaptive_split2["timestepping"] = recursive_merge(test_input_adaptive test_input_adaptive_split3 = recursive_merge(test_input_adaptive_split2, OptionsDict("output" => OptionsDict("run_name" => "adaptive split3"), "evolve_moments" => OptionsDict("parallel_pressure" => true), - "numerical_dissipation" => OptionsDict("force_minimum_pdf_value" => 0.0, - "vpa_dissipation_coefficient" => 1e-2))) + "ion_numerical_dissipation" => OptionsDict("force_minimum_pdf_value" => 0.0, + "vpa_dissipation_coefficient" => 1e-2), + "neutral_numerical_dissipation" => OptionsDict("force_minimum_pdf_value" => 0.0, + "vz_dissipation_coefficient" => 1e-2))) # The initial conditions seem to make the split3 case hard to advance without any # failures. In a real simulation, would just set the minimum_dt higher to try to get # through this without crashing. For this test, want the timestep to adapt (not just sit diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25.toml index e54769974..ef16d2b89 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25.toml @@ -68,5 +68,4 @@ discretization = "chebyshev_pseudospectral" nstep = 1500 dt = 0.004 nwrite = 20 -n_rk_stages = 4 split_operators = false diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split1.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split1.toml index db007115c..5ac6820c9 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split1.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split1.toml @@ -68,5 +68,4 @@ discretization = "chebyshev_pseudospectral" nstep = 1500 dt = 0.004 nwrite = 20 -n_rk_stages = 4 split_operators = false diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split2.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split2.toml index 9d1de4309..8a75ac738 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split2.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split2.toml @@ -68,5 +68,4 @@ discretization = "chebyshev_pseudospectral" nstep = 1500 dt = 0.004 nwrite = 20 -n_rk_stages = 4 split_operators = false diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split3.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split3.toml index f5df609a0..c111cc009 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split3.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.25_split3.toml @@ -68,5 +68,4 @@ discretization = "chebyshev_pseudospectral" nstep = 1500 dt = 0.004 nwrite = 20 -n_rk_stages = 4 split_operators = false diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5.toml index cf51ff298..77717feea 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5.toml @@ -68,5 +68,4 @@ discretization = "chebyshev_pseudospectral" nstep = 1500 dt = 0.00282842712474619 nwrite = 20 -n_rk_stages = 4 split_operators = false diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split1.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split1.toml index 4ca0d7910..783b9071b 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split1.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split1.toml @@ -68,5 +68,4 @@ discretization = "chebyshev_pseudospectral" nstep = 1500 dt = 0.00282842712474619 nwrite = 20 -n_rk_stages = 4 split_operators = false diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split2.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split2.toml index 5d4612b37..afb97b3e2 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split2.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split2.toml @@ -68,5 +68,4 @@ discretization = "chebyshev_pseudospectral" nstep = 1500 dt = 0.00282842712474619 nwrite = 20 -n_rk_stages = 4 split_operators = false diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split3.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split3.toml index 9c7c02a85..7306f9af0 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split3.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T0.5_split3.toml @@ -68,5 +68,4 @@ discretization = "chebyshev_pseudospectral" nstep = 1500 dt = 0.00282842712474619 nwrite = 20 -n_rk_stages = 4 split_operators = false diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1.toml index 70852e647..7cfd8c368 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1.toml @@ -68,5 +68,4 @@ discretization = "chebyshev_pseudospectral" nstep = 2500 dt = 0.002 nwrite = 20 -n_rk_stages = 4 split_operators = false diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split1.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split1.toml index 981eda062..e76b33bfb 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split1.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split1.toml @@ -68,5 +68,4 @@ discretization = "chebyshev_pseudospectral" nstep = 2500 dt = 0.002 nwrite = 20 -n_rk_stages = 4 split_operators = false diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split2.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split2.toml index d1a21053f..1290a8c0a 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split2.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split2.toml @@ -68,5 +68,4 @@ discretization = "chebyshev_pseudospectral" nstep = 2500 dt = 0.002 nwrite = 20 -n_rk_stages = 4 split_operators = false diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split3.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split3.toml index 283f10461..669bcda72 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split3.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T1_split3.toml @@ -68,5 +68,4 @@ discretization = "chebyshev_pseudospectral" nstep = 2500 dt = 0.002 nwrite = 20 -n_rk_stages = 4 split_operators = false diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2.toml index 679af654d..93444128c 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2.toml @@ -70,5 +70,4 @@ discretization = "chebyshev_pseudospectral" nstep = 1800 dt = 0.001414213562373095 nwrite = 20 -n_rk_stages = 4 split_operators = false diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split1.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split1.toml index a1a3dcbe4..1a74238dd 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split1.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split1.toml @@ -70,5 +70,4 @@ discretization = "chebyshev_pseudospectral" nstep = 1800 dt = 0.001414213562373095 nwrite = 20 -n_rk_stages = 4 split_operators = false diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split2.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split2.toml index 82ae1e54c..4cc7cff2f 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split2.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split2.toml @@ -70,5 +70,4 @@ discretization = "chebyshev_pseudospectral" nstep = 1800 dt = 0.001414213562373095 nwrite = 20 -n_rk_stages = 4 split_operators = false diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split3.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split3.toml index c09c17a8d..cb3acd490 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split3.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T2_split3.toml @@ -70,5 +70,4 @@ discretization = "chebyshev_pseudospectral" nstep = 1800 dt = 0.001414213562373095 nwrite = 20 -n_rk_stages = 4 split_operators = false diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4.toml index 3e49f9451..658527119 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4.toml @@ -71,5 +71,4 @@ nstep = 3000 dt = 1.0e-3 nwrite = 20 #nwrite_dfns = 20 #80 -n_rk_stages = 4 split_operators = false diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split1.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split1.toml index 67d423e57..9f2f411bf 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split1.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split1.toml @@ -71,5 +71,4 @@ nstep = 3000 dt = 1.0e-3 nwrite = 20 #nwrite_dfns = 20 #80 -n_rk_stages = 4 split_operators = false diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split2.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split2.toml index 27da1a60a..aba4c978c 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split2.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split2.toml @@ -71,5 +71,4 @@ nstep = 3000 dt = 1.0e-3 nwrite = 20 #nwrite_dfns = 20 #80 -n_rk_stages = 4 split_operators = false diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split3.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split3.toml index fa4145c0f..8e6719274 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split3.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_T4_split3.toml @@ -71,5 +71,4 @@ nstep = 3000 dt = 1.0e-3 nwrite = 20 #nwrite_dfns = 20 #80 -n_rk_stages = 4 split_operators = false diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio.toml index 6f35c0f67..eae8fde3f 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio.toml @@ -70,5 +70,4 @@ discretization = "chebyshev_pseudospectral" nstep = 2500 dt = 2.0e-3 nwrite = 20 -n_rk_stages = 4 split_operators = false diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split1.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split1.toml index 10806bd86..7159cd582 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split1.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split1.toml @@ -70,5 +70,4 @@ discretization = "chebyshev_pseudospectral" nstep = 2500 dt = 2.0e-3 nwrite = 20 -n_rk_stages = 4 split_operators = false diff --git a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split2.toml b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split2.toml index e5b2640be..72ad80657 100644 --- a/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split2.toml +++ b/publication_inputs/2023_EFTC_jto-poster/sound-wave/scan_sound-wave_nratio_split2.toml @@ -70,5 +70,4 @@ discretization = "chebyshev_pseudospectral" nstep = 2500 dt = 2.0e-3 nwrite = 20 -n_rk_stages = 4 split_operators = false diff --git a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5.toml b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5.toml index 610092090..251a3d9e3 100644 --- a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5.toml +++ b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5.toml @@ -96,7 +96,6 @@ nstep = 1000000 dt = 3.0e-5 nwrite = 10000 nwrite_dfns = 10000 -n_rk_stages = 4 split_operators = false steady_state_residual = true converged_residual_value = 1.0e-3 diff --git a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split1.toml b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split1.toml index 612d2995f..c90b14f79 100644 --- a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split1.toml +++ b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split1.toml @@ -96,7 +96,6 @@ nstep = 1000000 dt = 3.0e-5 nwrite = 10000 nwrite_dfns = 10000 -n_rk_stages = 4 split_operators = false steady_state_residual = true converged_residual_value = 1.0e-3 diff --git a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split2.toml b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split2.toml index 6cecf1645..3d203a921 100644 --- a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split2.toml +++ b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split2.toml @@ -96,7 +96,6 @@ nstep = 1000000 dt = 3.0e-5 nwrite = 10000 nwrite_dfns = 10000 -n_rk_stages = 4 split_operators = false steady_state_residual = true converged_residual_value = 1.0e-3 diff --git a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split3.toml b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split3.toml index 3e4044b2a..2abe8f536 100644 --- a/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split3.toml +++ b/publication_inputs/2023_EFTC_jto-poster/wall-bc/wall-bc_recyclefraction0.5_split3.toml @@ -96,7 +96,6 @@ nstep = 1000000 dt = 1.0e-5 nwrite = 10000 nwrite_dfns = 10000 -n_rk_stages = 4 split_operators = false steady_state_residual = true converged_residual_value = 1.0e-3 From fcdbaf3bb5d35da07ec117110ecb320d75e9da4c Mon Sep 17 00:00:00 2001 From: John Omotani Date: Mon, 9 Sep 2024 17:17:30 +0100 Subject: [PATCH 36/87] Rename `scan_input` variable to `input_dict` in mk_input() This variable is no longer only used to set up parameter scans, so give it a more logical name. --- moment_kinetics/src/moment_kinetics_input.jl | 58 ++++++++++---------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/moment_kinetics/src/moment_kinetics_input.jl b/moment_kinetics/src/moment_kinetics_input.jl index d783ae72f..cb6faa459 100644 --- a/moment_kinetics/src/moment_kinetics_input.jl +++ b/moment_kinetics/src/moment_kinetics_input.jl @@ -52,7 +52,7 @@ false for other situations (e.g. when post-processing). `ignore_MPI` should be false when actually running a simulation, but defaults to true for other situations (e.g. when post-processing). """ -function mk_input(scan_input=OptionsDict(); save_inputs_to_txt=false, ignore_MPI=true) +function mk_input(input_dict=OptionsDict(); 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. @@ -79,7 +79,7 @@ function mk_input(scan_input=OptionsDict(); save_inputs_to_txt=false, ignore_MPI "run_name", "base_directory", ) for opt in removed_options_list - if opt ∈ keys(scan_input) + if opt ∈ keys(input_dict) error("Option '$opt' is no longer used. Please update your input file. The " * "option may have been moved into an input file section - there are " * "no longer any top-level options (i.e. ones not in a section). You " @@ -89,7 +89,7 @@ function mk_input(scan_input=OptionsDict(); save_inputs_to_txt=false, ignore_MPI end # read composition and species data - composition = get_species_input(scan_input) + composition = get_species_input(input_dict) n_ion_species = composition.n_ion_species n_neutral_species = composition.n_neutral_species @@ -97,7 +97,7 @@ function mk_input(scan_input=OptionsDict(); save_inputs_to_txt=false, ignore_MPI # out what `output_dir` should be. The setup is completed later, after some other # sections have been read. io_settings = set_defaults_and_check_section!( - scan_input, "output"; + input_dict, "output"; run_name="", base_directory="runs", ascii_output=false, @@ -114,7 +114,7 @@ function mk_input(scan_input=OptionsDict(); save_inputs_to_txt=false, ignore_MPI # if evolve_moments.density = true, evolve density via continuity eqn # and g = f/n via modified drift kinetic equation evolve_moments_settings = set_defaults_and_check_section!( - scan_input, "evolve_moments"; + input_dict, "evolve_moments"; density=false, parallel_flow=false, parallel_pressure=false, @@ -124,13 +124,13 @@ function mk_input(scan_input=OptionsDict(); save_inputs_to_txt=false, ignore_MPI # Reference parameters that define the conversion between physical quantities and # normalised values used in the code. - reference_params = setup_reference_parameters(scan_input) + reference_params = setup_reference_parameters(input_dict) ## set geometry_input - geometry_in = setup_geometry_input(scan_input) + geometry_in = setup_geometry_input(input_dict) reactions_settings = set_defaults_and_check_section!( - scan_input, "reactions"; + input_dict, "reactions"; charge_exchange_frequency=2.0*sqrt(composition.ion[1].initial_temperature), electron_charge_exchange_frequency=0.0, ionization_frequency=2.0*sqrt(composition.ion[1].initial_temperature), @@ -139,16 +139,16 @@ function mk_input(scan_input=OptionsDict(); save_inputs_to_txt=false, ignore_MPI ) reactions_input = Dict_to_NamedTuple(reactions_settings) electron_fluid_collisions_settings = set_defaults_and_check_section!( - scan_input, "electron_fluid_collisions"; + input_dict, "electron_fluid_collisions"; nu_ei=0.0, ) electron_fluid_collisions_input = Dict_to_NamedTuple(electron_fluid_collisions_settings) # set up krook collision inputs - krook_input = setup_krook_collisions_input(scan_input) + krook_input = setup_krook_collisions_input(input_dict) # set up Fokker-Planck collision inputs - fkpl_input = setup_fkpl_collisions_input(scan_input) + fkpl_input = setup_fkpl_collisions_input(input_dict) # set up maxwell diffusion collision inputs - mxwl_diff_input = setup_mxwl_diff_collisions_input(scan_input) + mxwl_diff_input = setup_mxwl_diff_collisions_input(input_dict) # write total collision struct using the structs above, as each setup function # for the collisions outputs itself a struct of the type of collision, which # is a substruct of the overall collisions_input struct. @@ -157,7 +157,7 @@ function mk_input(scan_input=OptionsDict(); save_inputs_to_txt=false, ignore_MPI # parameters related to the time stepping timestepping_section = set_defaults_and_check_section!( - scan_input, "timestepping"; + input_dict, "timestepping"; nstep=5, dt=0.00025/sqrt(composition.ion[1].initial_temperature), CFL_prefactor=-1.0, @@ -201,7 +201,7 @@ function mk_input(scan_input=OptionsDict(); save_inputs_to_txt=false, ignore_MPI # parameters related to electron time stepping electron_timestepping_section = set_defaults_and_check_section!( - scan_input, "electron_timestepping"; + input_dict, "electron_timestepping"; nstep=50000, dt=timestepping_section["dt"] * sqrt(composition.me_over_mi), CFL_prefactor=timestepping_section["CFL_prefactor"], @@ -320,10 +320,10 @@ function mk_input(scan_input=OptionsDict(); save_inputs_to_txt=false, ignore_MPI error("maximum_dt=$(timestepping_section["maximum_dt"]) must be positive") end - use_for_init_is_default = !(("manufactured_solns" ∈ keys(scan_input)) && - ("use_for_init" ∈ keys(scan_input["manufactured_solns"]))) + use_for_init_is_default = !(("manufactured_solns" ∈ keys(input_dict)) && + ("use_for_init" ∈ keys(input_dict["manufactured_solns"]))) manufactured_solns_section = set_defaults_and_check_section!( - scan_input, "manufactured_solns"; + input_dict, "manufactured_solns"; use_for_advance=false, use_for_init=false, # constant to be used to control Ez divergence in MMS tests @@ -362,8 +362,8 @@ function mk_input(scan_input=OptionsDict(); save_inputs_to_txt=false, ignore_MPI # set up distributed-memory MPI information for z and r coords # need grid and MPI information to determine these values # MRH just put dummy values now - r_coord_input = get_coordinate_input(scan_input, "r"; ignore_MPI=ignore_MPI) - z_coord_input = get_coordinate_input(scan_input, "z"; ignore_MPI=ignore_MPI) + r_coord_input = get_coordinate_input(input_dict, "r"; ignore_MPI=ignore_MPI) + z_coord_input = get_coordinate_input(input_dict, "z"; ignore_MPI=ignore_MPI) if ignore_MPI irank_z = irank_r = 0 nrank_z = nrank_r = 1 @@ -385,7 +385,7 @@ function mk_input(scan_input=OptionsDict(); save_inputs_to_txt=false, ignore_MPI end em_fields_settings = set_defaults_and_check_section!( - scan_input, "em_fields"; + input_dict, "em_fields"; force_Er_zero_at_wall=false, ) em_input = Dict_to_NamedTuple(em_fields_settings) @@ -426,40 +426,40 @@ function mk_input(scan_input=OptionsDict(); save_inputs_to_txt=false, ignore_MPI run_directory=run_directory, ignore_MPI=ignore_MPI, irank=irank_r, nrank=nrank_r, comm=comm_sub_r) # initialize vpa grid and write grid point locations to file - vpa, vpa_spectral = define_coordinate(scan_input, "vpa"; + vpa, vpa_spectral = define_coordinate(input_dict, "vpa"; parallel_io=io_immutable.parallel_io, run_directory=run_directory, ignore_MPI=ignore_MPI) # initialize vperp grid and write grid point locations to file - vperp, vperp_spectral = define_coordinate(scan_input, "vperp"; + vperp, vperp_spectral = define_coordinate(input_dict, "vperp"; parallel_io=io_immutable.parallel_io, run_directory=run_directory, ignore_MPI=ignore_MPI) # initialize gyrophase grid and write grid point locations to file - gyrophase, gyrophase_spectral = define_coordinate(scan_input, "gyrophase"; + gyrophase, gyrophase_spectral = define_coordinate(input_dict, "gyrophase"; parallel_io=io_immutable.parallel_io, run_directory=run_directory, ignore_MPI=ignore_MPI) # initialize vz grid and write grid point locations to file - vz, vz_spectral = define_coordinate(scan_input, "vz"; + vz, vz_spectral = define_coordinate(input_dict, "vz"; parallel_io=io_immutable.parallel_io, run_directory=run_directory, ignore_MPI=ignore_MPI) # initialize vr grid and write grid point locations to file - vr, vr_spectral = define_coordinate(scan_input, "vr"; + vr, vr_spectral = define_coordinate(input_dict, "vr"; parallel_io=io_immutable.parallel_io, run_directory=run_directory, ignore_MPI=ignore_MPI) # initialize vr grid and write grid point locations to file - vzeta, vzeta_spectral = define_coordinate(scan_input, "vzeta"; + vzeta, vzeta_spectral = define_coordinate(input_dict, "vzeta"; parallel_io=io_immutable.parallel_io, run_directory=run_directory, ignore_MPI=ignore_MPI) - external_source_settings = setup_external_sources!(scan_input, r, z, + external_source_settings = setup_external_sources!(input_dict, r, z, composition.electron_physics) - num_diss_params = setup_numerical_dissipation(scan_input) + num_diss_params = setup_numerical_dissipation(input_dict) geometry = init_magnetic_geometry(geometry_in,z,r) if any(geometry.dBdz .!= 0.0) && @@ -470,7 +470,7 @@ function mk_input(scan_input=OptionsDict(); save_inputs_to_txt=false, ignore_MPI species_immutable = (ion = composition.ion, neutral = composition.neutral) - # Ideally `check_sections!(scan_input) would be called here to check that no + # Ideally `check_sections!(input_dict) would be called here to check that no # unexpected sections or top-level options were passed (helps to catch typos in input # files). However, it needs to be called after calls to `setup_nonlinear_solve()` # because the inputs for nonlinear solvers are only read there, but before electron From d5faab8638383cbb773408062db4456ae1ce4e36 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Mon, 9 Sep 2024 17:30:12 +0100 Subject: [PATCH 37/87] Fix ASCII I/O option ...so that it at least works for the 1D1V case, and errors otherwise. --- ...wall+sheath-bc_kinetic_krook_loworder.toml | 4 +-- moment_kinetics/src/file_io.jl | 27 +++++++++++++------ moment_kinetics/src/moment_kinetics.jl | 4 +-- moment_kinetics/src/time_advance.jl | 6 ++--- 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/examples/kinetic-electrons/wall+sheath-bc_kinetic_krook_loworder.toml b/examples/kinetic-electrons/wall+sheath-bc_kinetic_krook_loworder.toml index 3520c6deb..843b7696a 100644 --- a/examples/kinetic-electrons/wall+sheath-bc_kinetic_krook_loworder.toml +++ b/examples/kinetic-electrons/wall+sheath-bc_kinetic_krook_loworder.toml @@ -37,8 +37,8 @@ discretization = "chebyshev_pseudospectral" #discretization = "gausslegendre_pseudospectral" [vz] -ngrid = 17 -nelement = 10 +ngrid = 5 +nelement = 80 L = 8.0 bc = "zero" discretization = "chebyshev_pseudospectral" diff --git a/moment_kinetics/src/file_io.jl b/moment_kinetics/src/file_io.jl index 15b18b59e..76d29bb39 100644 --- a/moment_kinetics/src/file_io.jl +++ b/moment_kinetics/src/file_io.jl @@ -2994,21 +2994,32 @@ include("file_io_hdf5.jl") """ """ -function write_data_to_ascii(pdf, moments, fields, vpa, vperp, z, r, t, n_ion_species, - n_neutral_species, ascii_io::Union{ascii_ios,Nothing}) +function write_data_to_ascii(pdf, moments, fields, vz, vr, vzeta, vpa, vperp, z, r, t, + n_ion_species, n_neutral_species, + ascii_io::Union{ascii_ios,Nothing}) if ascii_io === nothing || ascii_io.moments_ion === nothing # ascii I/O is disabled return nothing end + if r.n > 1 || vperp.n > 1 || vzeta.n > 1 || vr.n > 1 + error("Ascii I/O is only implemented for 1D1V case") + end + if vz.n != vpa.n + error("ASCII I/O is only implemented when vz.n($(vz.n))==vpa.n($(vpa.n))") + end + if n_neutral_species != n_ion_species + error("ASCII I/O is only implemented when n_neutral_species($(n_neutral_species))==n_ion_species($(n_ion_species))") + end + @serial_region begin # Only read/write from first process in each 'block' - write_f_ascii(pdf, z, vpa, t, ascii_io.ff) + @views write_f_ascii(pdf, z, vpa, t, ascii_io.ff) write_moments_ion_ascii(moments.ion, z, r, t, n_ion_species, ascii_io.moments_ion) write_moments_electron_ascii(moments.electron, z, r, t, ascii_io.moments_electron) if n_neutral_species > 0 - write_moments_neutral_ascii(moments.neutral, z, r, t, n_neutral_species, ascii_io.moments_neutral) + @views write_moments_neutral_ascii(moments.neutral, z, r, t, n_neutral_species, ascii_io.moments_neutral) end write_fields_ascii(fields, z, r, t, ascii_io.fields) end @@ -3025,11 +3036,11 @@ function write_f_ascii(f, z, vpa, t, ascii_io) @inbounds begin #n_species = size(f,3) #for is ∈ 1:n_species - for j ∈ 1:vpa.n - for i ∈ 1:z.n + for i ∈ 1:z.n + for j ∈ 1:vpa.n println(ascii_io,"t: ", t, " z: ", z.grid[i], - " vpa: ", vpa.grid[j], " fion: ", f.ion.norm[i,j,1], - " fneutral: ", f.neutral.norm[i,j,1]) + " vpa: ", vpa.grid[j], " fion: ", f.ion.norm[j,1,i,1,1], + " fneutral: ", f.neutral.norm[j,1,1,i,1,1]) end println(ascii_io) end diff --git a/moment_kinetics/src/moment_kinetics.jl b/moment_kinetics/src/moment_kinetics.jl index 255a6d0a5..aa3150de3 100644 --- a/moment_kinetics/src/moment_kinetics.jl +++ b/moment_kinetics/src/moment_kinetics.jl @@ -361,8 +361,8 @@ function setup_moment_kinetics(input_dict::AbstractDict; restart_time_index, previous_runs_info, time_for_setup, t_params, nl_solver_params) # write initial data to ascii files - write_data_to_ascii(pdf, moments, fields, vpa, vperp, z, r, t_params.t[], - composition.n_ion_species, composition.n_neutral_species, ascii_io) + write_data_to_ascii(pdf, moments, fields, vz, vr, vzeta, vpa, vperp, z, r, + t_params.t[], composition.n_ion_species, composition.n_neutral_species, ascii_io) # write initial data to binary files t_params.moments_output_counter[] += 1 diff --git a/moment_kinetics/src/time_advance.jl b/moment_kinetics/src/time_advance.jl index b593c6c1c..73cfe69e5 100644 --- a/moment_kinetics/src/time_advance.jl +++ b/moment_kinetics/src/time_advance.jl @@ -1896,9 +1896,9 @@ function time_advance!(pdf, scratch, scratch_implicit, scratch_electron, t_param print(Dates.format(now(), dateformat"H:MM:SS")) end end - write_data_to_ascii(pdf, moments, fields, vpa, vperp, z, r, t_params.t[], - composition.n_ion_species, composition.n_neutral_species, - ascii_io) + write_data_to_ascii(pdf, moments, fields, vz, vr, vzeta, vpa, vperp, z, r, + t_params.t[], composition.n_ion_species, + composition.n_neutral_species, ascii_io) write_all_moments_data_to_binary(scratch, moments, fields, composition.n_ion_species, composition.n_neutral_species, io_moments, From f72d09d83c16638cd255015e3107966709dbc2c4 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Mon, 9 Sep 2024 17:37:58 +0100 Subject: [PATCH 38/87] Fix edge case for electron I/O counter --- moment_kinetics/src/initial_conditions.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/moment_kinetics/src/initial_conditions.jl b/moment_kinetics/src/initial_conditions.jl index 56416bcf0..ea7c20f70 100644 --- a/moment_kinetics/src/initial_conditions.jl +++ b/moment_kinetics/src/initial_conditions.jl @@ -684,7 +684,7 @@ function initialize_electron_pdf!(scratch, scratch_electron, pdf, moments, field end if code_time > 0.0 tind = searchsortedfirst(t_params.electron.moments_output_times, code_time) - n_truncated = length(t_params.electron.moments_output_times) - tind + n_truncated = max(length(t_params.electron.moments_output_times) - tind, 0) truncated_times = t_params.electron.moments_output_times[tind+1:end] resize!(t_params.electron.moments_output_times, n_truncated) t_params.electron.moments_output_times .= truncated_times From 0a983f9c55b118effb12540ad242e32f53233f3d Mon Sep 17 00:00:00 2001 From: John Omotani Date: Mon, 9 Sep 2024 19:25:33 +0100 Subject: [PATCH 39/87] Fix Dict type to OptionsDict in gyroaverage_tests.jl --- moment_kinetics/test/gyroaverage_tests.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/moment_kinetics/test/gyroaverage_tests.jl b/moment_kinetics/test/gyroaverage_tests.jl index 44c96e3a2..b42564709 100644 --- a/moment_kinetics/test/gyroaverage_tests.jl +++ b/moment_kinetics/test/gyroaverage_tests.jl @@ -166,7 +166,7 @@ function gyroaverage_test(absolute_error; rhostar=0.1, pitch=0.5, ngrid=5, kr=2, # create test geometry option = "constant-helical" - inputdict = Dict("geometry" => Dict("option" => option, "rhostar" => rhostar, "pitch" => pitch)) + inputdict = OptionsDict("geometry" => OptionsDict("option" => option, "rhostar" => rhostar, "pitch" => pitch)) geometry_in = setup_geometry_input(inputdict) geometry = init_magnetic_geometry(geometry_in,z,r) From 1521935ab95033707b597760e479b50bd91f00c2 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Mon, 9 Sep 2024 20:17:22 +0100 Subject: [PATCH 40/87] Reduce allowed filename length for HDF5 files A current test case (long tests in restart_interpolation_tests.jl, before adding a workaround for the run_name length in that test) crashes when the filename is 245 characters, and not when the filename is 243 characters. --- moment_kinetics/src/file_io_hdf5.jl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/moment_kinetics/src/file_io_hdf5.jl b/moment_kinetics/src/file_io_hdf5.jl index 271d79fee..47ebccdb1 100644 --- a/moment_kinetics/src/file_io_hdf5.jl +++ b/moment_kinetics/src/file_io_hdf5.jl @@ -11,7 +11,10 @@ function open_output_file_implementation(::Val{hdf5}, prefix, io_input, io_comm, # the hdf5 file will be given by output_dir/run_name with .h5 appended filename = string(prefix, ".h5") - if length(filename) > 255 + # JTO thought the maximum filename length should be 255 according to HDF5.jl, but can + # no longer find the HDF5.jl check for length. However on one test a filename of + # length 245 caused a crash, while 243 was OK, so limit to 243. + if length(filename) > 243 error("Length of filename '$filename' is too long ($(length(filename)) " * "characters), which will cause an error in HDF5.") end From 9edfff3e24e334eb31f662bdcc2ea74e1ad938bf Mon Sep 17 00:00:00 2001 From: John Omotani Date: Mon, 9 Sep 2024 22:43:52 +0100 Subject: [PATCH 41/87] Remove unused mutable structs from `input_structs` --- moment_kinetics/src/input_structs.jl | 40 ++-------------------------- 1 file changed, 2 insertions(+), 38 deletions(-) diff --git a/moment_kinetics/src/input_structs.jl b/moment_kinetics/src/input_structs.jl index 8c1aaf350..b0f7c557f 100644 --- a/moment_kinetics/src/input_structs.jl +++ b/moment_kinetics/src/input_structs.jl @@ -5,9 +5,9 @@ module input_structs export advance_info export time_info export advection_input -export initial_condition_input, initial_condition_input_mutable +export initial_condition_input export spatial_initial_condition_input, velocity_initial_condition_input -export ion_species_parameters, neutral_species_parameters, species_parameters_mutable +export ion_species_parameters, neutral_species_parameters export species_composition export collisions_input, krook_collisions_input, fkpl_collisions_input export io_input @@ -157,25 +157,6 @@ export braginskii_fluid export kinetic_electrons export kinetic_electrons_with_temperature_equation -""" -""" -mutable struct initial_condition_input_mutable - # initialization inputs for one coordinate of a separable distribution function - initialization_option::String - # inputs for "gaussian" initial condition - width::mk_float - # inputs for "sinusoid" initial condition - wavenumber::mk_int - density_amplitude::mk_float - density_phase::mk_float - upar_amplitude::mk_float - upar_phase::mk_float - temperature_amplitude::mk_float - temperature_phase::mk_float - # inputs for "monomial" initial condition - monomial_degree::mk_int -end - """ """ Base.@kwdef struct spatial_initial_condition_input @@ -219,23 +200,6 @@ Base.@kwdef struct velocity_initial_condition_input vperp0::mk_float end -""" -""" -mutable struct species_parameters_mutable - # type is the type of species; options are 'ion' or 'neutral' - type::String - # array containing the initial line-averaged temperature for this species - initial_temperature::mk_float - # array containing the initial line-averaged density for this species - initial_density::mk_float - # struct containing the initial condition info in z for this species - z_IC::initial_condition_input_mutable - # struct containing the initial condition info in r for this species - r_IC::initial_condition_input_mutable - # struct containing the initial condition info in vpa for this species - vpa_IC::initial_condition_input_mutable -end - """ """ Base.@kwdef struct ion_species_parameters From 68449edc43f43fe8679698d606ba178699f8717c Mon Sep 17 00:00:00 2001 From: John Omotani Date: Mon, 9 Sep 2024 23:45:01 +0100 Subject: [PATCH 42/87] fix grid_input --- makie_post_processing/makie_post_processing/src/shared_utils.jl | 2 +- .../plots_post_processing/src/plots_post_processing.jl | 2 +- 2 files changed, 2 insertions(+), 2 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 7ce536326..c01d55bc3 100644 --- a/makie_post_processing/makie_post_processing/src/shared_utils.jl +++ b/makie_post_processing/makie_post_processing/src/shared_utils.jl @@ -7,7 +7,7 @@ using moment_kinetics.array_allocation: allocate_float using moment_kinetics.coordinates: define_coordinate using moment_kinetics.input_structs: boltzmann_electron_response, boltzmann_electron_response_with_simple_sheath, - grid_input, geometry_input, species_composition + geometry_input, species_composition using moment_kinetics.type_definitions: mk_float, mk_int using moment_kinetics.reference_parameters: setup_reference_parameters using moment_kinetics.geo: init_magnetic_geometry, setup_geometry_input 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 bb229c6f3..caa9d1f6f 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 @@ -59,7 +59,7 @@ using moment_kinetics.manufactured_solns: manufactured_solutions, manufactured_electric_fields, manufactured_geometry using moment_kinetics.moment_kinetics_input: mk_input, get -using moment_kinetics.input_structs: geometry_input, grid_input, species_composition +using moment_kinetics.input_structs: geometry_input, species_composition using moment_kinetics.input_structs: boltzmann_electron_response, #electron_physics_type, boltzmann_electron_response_with_simple_sheath using moment_kinetics.species_input: get_species_input From b83b8db88f7fd540b4fc21505c97598735b25258 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Mon, 9 Sep 2024 23:53:43 +0100 Subject: [PATCH 43/87] Add new modules to docs --- docs/src/zz_electron_fluid_equations.md | 6 ++++++ docs/src/zz_electron_kinetic_equation.md | 6 ++++++ docs/src/zz_electron_vpa_advection.md | 6 ++++++ docs/src/zz_electron_z_advection.md | 6 ++++++ docs/src/zz_maxwell_diffusion.md | 6 ++++++ docs/src/zz_nonlinear_solvers.md | 6 ++++++ docs/src/zz_species_input.md | 6 ++++++ moment_kinetics/src/electron_fluid_equations.jl | 2 +- moment_kinetics/src/external_sources.jl | 2 +- 9 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 docs/src/zz_electron_fluid_equations.md create mode 100644 docs/src/zz_electron_kinetic_equation.md create mode 100644 docs/src/zz_electron_vpa_advection.md create mode 100644 docs/src/zz_electron_z_advection.md create mode 100644 docs/src/zz_maxwell_diffusion.md create mode 100644 docs/src/zz_nonlinear_solvers.md create mode 100644 docs/src/zz_species_input.md diff --git a/docs/src/zz_electron_fluid_equations.md b/docs/src/zz_electron_fluid_equations.md new file mode 100644 index 000000000..82cb31e65 --- /dev/null +++ b/docs/src/zz_electron_fluid_equations.md @@ -0,0 +1,6 @@ +`electron_fluid_equations` +========================== + +```@autodocs +Modules = [moment_kinetics.electron_fluid_equations] +``` diff --git a/docs/src/zz_electron_kinetic_equation.md b/docs/src/zz_electron_kinetic_equation.md new file mode 100644 index 000000000..5c37a3ef4 --- /dev/null +++ b/docs/src/zz_electron_kinetic_equation.md @@ -0,0 +1,6 @@ +`electron_kinetic_equation` +=========================== + +```@autodocs +Modules = [moment_kinetics.electron_kinetic_equation] +``` diff --git a/docs/src/zz_electron_vpa_advection.md b/docs/src/zz_electron_vpa_advection.md new file mode 100644 index 000000000..2243b0a9e --- /dev/null +++ b/docs/src/zz_electron_vpa_advection.md @@ -0,0 +1,6 @@ +`electron_vpa_advection` +======================== + +```@autodocs +Modules = [moment_kinetics.electron_vpa_advection] +``` diff --git a/docs/src/zz_electron_z_advection.md b/docs/src/zz_electron_z_advection.md new file mode 100644 index 000000000..cba681571 --- /dev/null +++ b/docs/src/zz_electron_z_advection.md @@ -0,0 +1,6 @@ +`electron_z_advection` +====================== + +```@autodocs +Modules = [moment_kinetics.electron_z_advection] +``` diff --git a/docs/src/zz_maxwell_diffusion.md b/docs/src/zz_maxwell_diffusion.md new file mode 100644 index 000000000..d3fd77d27 --- /dev/null +++ b/docs/src/zz_maxwell_diffusion.md @@ -0,0 +1,6 @@ +`maxwell_diffusion` +=================== + +```@autodocs +Modules = [moment_kinetics.maxwell_diffusion] +``` diff --git a/docs/src/zz_nonlinear_solvers.md b/docs/src/zz_nonlinear_solvers.md new file mode 100644 index 000000000..be7d75a22 --- /dev/null +++ b/docs/src/zz_nonlinear_solvers.md @@ -0,0 +1,6 @@ +`nonlinear_solvers` +=================== + +```@autodocs +Modules = [moment_kinetics.nonlinear_solvers] +``` diff --git a/docs/src/zz_species_input.md b/docs/src/zz_species_input.md new file mode 100644 index 000000000..afd5ab66b --- /dev/null +++ b/docs/src/zz_species_input.md @@ -0,0 +1,6 @@ +`species_input` +=============== + +```@autodocs +Modules = [moment_kinetics.species_input] +``` diff --git a/moment_kinetics/src/electron_fluid_equations.jl b/moment_kinetics/src/electron_fluid_equations.jl index dea2f6a7d..bb369714a 100644 --- a/moment_kinetics/src/electron_fluid_equations.jl +++ b/moment_kinetics/src/electron_fluid_equations.jl @@ -52,7 +52,7 @@ end """ use charge conservation equation to solve for the electron parallel flow density: d/dz(sum_i n_i upar_i - n_e upar_e) = 0 - ==> [sum_i n_i upar_i](z) - [sum_i n_i upar_i](zbound) = [n_e upar_e](z) - [n_e upar_e](zbound) + ==> {sum_i n_i upar_i}(z) - {sum_i n_i upar_i}(zbound) = {n_e upar_e}(z) - {n_e upar_e}(zbound) inputs: upar_e = should contain updated electron parallel flow at boundaries in zed updated = flag indicating whether the electron parallel flow is already updated diff --git a/moment_kinetics/src/external_sources.jl b/moment_kinetics/src/external_sources.jl index 98fe4169c..2beed8f58 100644 --- a/moment_kinetics/src/external_sources.jl +++ b/moment_kinetics/src/external_sources.jl @@ -1035,7 +1035,7 @@ external source amplitude. As the electron density source must be equal to the ion density source in order not to inject charge into the simulation, the electron source (at least in some modes of -operation) depends on the ion source, so [`external_ion_source_controller`](@ref) must be +operation) depends on the ion source, so [`external_ion_source_controller!`](@ref) must be called before this function is called so that `moments.ion.external_source_amplitude` is up to date. """ From 20af36bd4a5874831c9aced441f55b4ede21ce91 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Tue, 10 Sep 2024 09:34:45 +0100 Subject: [PATCH 44/87] Alternative form of set_defaults_and_check_section!() for @kwdef struct --- moment_kinetics/src/input_structs.jl | 95 ++++++++++++++++++++++------ 1 file changed, 75 insertions(+), 20 deletions(-) diff --git a/moment_kinetics/src/input_structs.jl b/moment_kinetics/src/input_structs.jl index b0f7c557f..4e57255e9 100644 --- a/moment_kinetics/src/input_structs.jl +++ b/moment_kinetics/src/input_structs.jl @@ -624,17 +624,8 @@ function set_defaults_and_check_top_level!(options::AbstractDict; kwargs...) return options end -const _section_check_store_name = "_section_check_store" - -""" -Set the defaults for options in a section, and check that there are not any unexpected -options (i.e. options that have no default). +function _get_section_and_check_option_names(options, section_name, section_keys) -Modifies the options[section_name]::Dict by adding defaults for any values that are not -already present. -""" -function set_defaults_and_check_section!(options::AbstractDict, section_name; - kwargs...) DictType = typeof(options) if !(section_name ∈ keys(options)) @@ -651,22 +642,20 @@ function set_defaults_and_check_section!(options::AbstractDict, section_name; # Check for any unexpected values in the section - all options that are set should be # present in the kwargs of this function call - section_keys_symbols = keys(kwargs) - section_keys = (String(k) for k ∈ section_keys_symbols) + unexpected_options = String[] for (key, value) in section if !(key ∈ section_keys) - error("Unexpected option '$key=$value' in section '$section_name'") + push!(unexpected_options, key) end end - - # Set default values if a key was not set explicitly - for (key_sym, default_value) ∈ kwargs - key = String(key_sym) - # Use `Base.get()` here to take advantage of our `Enum`-handling method of - # `Base.get()` defined above. - section[key] = get(section, key, default_value) + if length(unexpected_options) > 0 + error("Unexpected options $(join(("$k=$(section[k])" for k ∈ unexpected_options), ", ", ", and ")) in section '$section_name'") end + return section +end + +function _store_section_name_for_check!(options, section_name) # Record the defined section_name in a temporary, private subsection of `options`, so # we can use it to check the existing sections later. if !(_section_check_store_name ∈ keys(options)) @@ -675,9 +664,75 @@ function set_defaults_and_check_section!(options::AbstractDict, section_name; end push!(options[_section_check_store_name], section_name) + return nothing +end + +const _section_check_store_name = "_section_check_store" + +""" +Set the defaults for options in a section, and check that there are not any unexpected +options (i.e. options that have no default). + +Modifies the options[section_name]::Dict by adding defaults for any values that are not +already present. +""" +function set_defaults_and_check_section!(options::AbstractDict, section_name; + kwargs...) + + section_keys_symbols = keys(kwargs) + section_keys = (String(k) for k ∈ section_keys_symbols) + section = _get_section_and_check_option_names(options, section_name, section_keys) + + # Set default values if a key was not set explicitly + for (key_sym, default_value) ∈ kwargs + key = String(key_sym) + # Use `Base.get()` here to take advantage of our `Enum`-handling method of + # `Base.get()` defined above. + section[key] = get(section, key, default_value) + end + + _store_section_name_for_check!(options, section_name) + return section end +""" + set_defaults_and_check_section!(options::AbstractDict, struct_type::Type, + name::Union{String,Nothing}=nothing) + +Alternative form to be used when the options should be stored in a struct of type +`struct_type` rather than a `NamedTuple`. `struct_type` must be defined using `@kwdef`. + +The returned instance of `struct_type` is immutable, so if you need to modify the settings +- e.g. to apply some logic to set defaults depending on other settings/parameters - then +you should use the 'standard' version of [`set_defaults_and_check_section!`](@ref) that +returns a `Dict` that can be modified, and then use that `Dict` to initialise the +`struct_type`. + +The name of the section in the options that will be read defaults to the name of +`struct_type`, but can be set using the `section_name` argument. + +Returns an instance of `struct_type`. +""" +function set_defaults_and_check_section!(options::AbstractDict, struct_type::Type, + section_name::Union{String,Nothing}=nothing) + + if section_name === nothing + section_name = String(nameof(struct_type)) + end + section_keys = (String(key) for key ∈ fieldnames(struct_type)) + section = _get_section_and_check_option_names(options, section_name, section_keys) + + # Pass the settings in `section` as kwargs to the constructor for `struct_type`. + # `struct_type` is an `@kwdef` struct, so this constructor takes care of the default + # values. + settings_instance = struct_type(; (Symbol(k) => v for (k,v) ∈ pairs(section))...) + + _store_section_name_for_check!(options, section_name) + + return settings_instance +end + """ check_sections!(options::AbstractDict) From 3ad41d673d3cd6d4ea147d4494b24393764f600f Mon Sep 17 00:00:00 2001 From: John Omotani Date: Tue, 10 Sep 2024 10:42:21 +0100 Subject: [PATCH 45/87] Move initial condition defaults to the @kwdef struct definition Removes duplication of variable names. --- moment_kinetics/src/initial_conditions.jl | 8 +- moment_kinetics/src/input_structs.jl | 64 +++++----- moment_kinetics/src/species_input.jl | 136 +++++----------------- 3 files changed, 59 insertions(+), 149 deletions(-) diff --git a/moment_kinetics/src/initial_conditions.jl b/moment_kinetics/src/initial_conditions.jl index ea7c20f70..6fa0de8f4 100644 --- a/moment_kinetics/src/initial_conditions.jl +++ b/moment_kinetics/src/initial_conditions.jl @@ -1294,7 +1294,7 @@ function init_neutral_pdf_over_density!(pdf, boundary_distributions, spec, compo #if spec.vz_IC.initialization_option == "gaussian" # For now, continue to use 'vpa' initialization options for neutral species - if spec.vpa_IC.initialization_option == "gaussian" + if spec.vz_IC.initialization_option == "gaussian" # initial condition is a Gaussian in the peculiar velocity if z.bc != "wall" for iz ∈ 1:z.n @@ -1518,20 +1518,20 @@ function init_neutral_pdf_over_density!(pdf, boundary_distributions, spec, compo end end #elseif spec.vz_IC.initialization_option == "vzgaussian" - elseif spec.vpa_IC.initialization_option == "vzgaussian" + elseif spec.vz_IC.initialization_option == "vzgaussian" @loop_z_vzeta_vr iz ivzeta ivr begin @. pdf[:,ivr,ivzeta,iz] = vz.grid^2*exp(-vz.scratch^2 - vr[ivr]^2 - vzeta[ivzeta]^2) / vth[iz] end #elseif spec.vz_IC.initialization_option == "sinusoid" - elseif spec.vpa_IC.initialization_option == "sinusoid" + elseif spec.vz_IC.initialization_option == "sinusoid" # initial condition is sinusoid in vz @loop_z_vzeta_vr iz ivzeta ivr begin @. pdf[:,ivr,ivzeta,iz] = spec.vz_IC.amplitude*cospi(2.0*spec.vz_IC.wavenumber*vz.grid/vz.L) end #elseif spec.vz_IC.initialization_option == "monomial" - elseif spec.vpa_IC.initialization_option == "monomial" + elseif spec.vz_IC.initialization_option == "monomial" # linear variation in vz, with offset so that # function passes through zero at upwind boundary @loop_z_vzeta_vr iz ivzeta ivr begin diff --git a/moment_kinetics/src/input_structs.jl b/moment_kinetics/src/input_structs.jl index 4e57255e9..a88b820ac 100644 --- a/moment_kinetics/src/input_structs.jl +++ b/moment_kinetics/src/input_structs.jl @@ -161,43 +161,43 @@ export kinetic_electrons_with_temperature_equation """ Base.@kwdef struct spatial_initial_condition_input # initialization inputs for one coordinate of a separable distribution function - initialization_option::String + initialization_option::String = "gaussian" # inputs for "gaussian" initial condition - width::mk_float + width::mk_float = 0.125 # inputs for "sinusoid" initial condition - wavenumber::mk_int - density_amplitude::mk_float - density_phase::mk_float - upar_amplitude::mk_float - upar_phase::mk_float - temperature_amplitude::mk_float - temperature_phase::mk_float + wavenumber::mk_int = 1 + density_amplitude::mk_float = 0.001 + density_phase::mk_float = 0.0 + upar_amplitude::mk_float = 0.0 + upar_phase::mk_float = 0.0 + temperature_amplitude::mk_float = 0.0 + temperature_phase::mk_float = 0.0 # inputs for "monomial" initial condition - monomial_degree::mk_int + monomial_degree::mk_int = 2 end """ """ Base.@kwdef struct velocity_initial_condition_input # initialization inputs for one coordinate of a separable distribution function - initialization_option::String + initialization_option::String = "gaussian" # inputs for "gaussian" initial condition - width::mk_float + width::mk_float = 1.0 # inputs for "sinusoid" initial condition - wavenumber::mk_int - density_amplitude::mk_float - density_phase::mk_float - upar_amplitude::mk_float - upar_phase::mk_float - temperature_amplitude::mk_float - temperature_phase::mk_float + wavenumber::mk_int = 1 + density_amplitude::mk_float = 1.0 + density_phase::mk_float = 0.0 + upar_amplitude::mk_float = 0.0 + upar_phase::mk_float = 0.0 + temperature_amplitude::mk_float = 0.0 + temperature_phase::mk_float = 0.0 # inputs for "monomial" initial condition - monomial_degree::mk_int + monomial_degree::mk_int = 2 # inputs for "isotropic-beam", "directed-beam" initial conditions - v0::mk_float - vth0::mk_float - vpa0::mk_float - vperp0::mk_float + v0::mk_float = 1.0 + vth0::mk_float = 1.0 + vpa0::mk_float = 1.0 + vperp0::mk_float = 1.0 end """ @@ -236,8 +236,8 @@ Base.@kwdef struct neutral_species_parameters z_IC::spatial_initial_condition_input # struct containing the initial condition info in r for this species r_IC::spatial_initial_condition_input - # struct containing the initial condition info in vpa for this species - vpa_IC::velocity_initial_condition_input + # struct containing the initial condition info in vz for this species + vz_IC::velocity_initial_condition_input end """ @@ -382,18 +382,6 @@ end @enum binary_format_type hdf5 netcdf export binary_format_type, hdf5, netcdf -""" -Settings and input for setting up file I/O -""" -Base.@kwdef struct io_input - output_dir::String - run_name::String - ascii_output::Bool - binary_format::binary_format_type - parallel_io::Bool - run_id::String -end - """ """ struct pp_input diff --git a/moment_kinetics/src/species_input.jl b/moment_kinetics/src/species_input.jl index 35d8755e0..59d7043fe 100644 --- a/moment_kinetics/src/species_input.jl +++ b/moment_kinetics/src/species_input.jl @@ -67,61 +67,22 @@ function get_species_input(toml_input) # initial temperature initial_temperature = 1.0) - z_IC_section = set_defaults_and_check_section!(toml_input, "z_IC_ion_species_$is", - # [ion_z_IC_species_1], [ion_z_IC_species_2], etc - initialization_option = "gaussian", - width = 0.125, - wavenumber = 1, - density_amplitude = 0.001, - density_phase = 0.0, - upar_amplitude = 0.0, - upar_phase = 0.0, - temperature_amplitude = 0.0, - temperature_phase = 0.0, - monomial_degree = 2) - z_IC_input = Dict(Symbol(k)=>v for (k,v) in z_IC_section) - z_IC = spatial_initial_condition_input(; z_IC_input...) + z_IC = set_defaults_and_check_section!(toml_input, + spatial_initial_condition_input, + "z_IC_ion_species_$is") - r_IC_section = set_defaults_and_check_section!(toml_input, "r_IC_ion_species_$is", - # [ion_r_IC_species_1], [ion_r_IC_species_2], etc - initialization_option = "gaussian", - width = 0.125, - wavenumber = 1, - density_amplitude = 0.001, - density_phase = 0.0, - upar_amplitude = 0.0, - upar_phase = 0.0, - temperature_amplitude = 0.0, - temperature_phase = 0.0, - monomial_degree = 2) - r_IC_input= Dict(Symbol(k)=>v for (k,v) in r_IC_section) - r_IC = spatial_initial_condition_input(; r_IC_input...) + r_IC = set_defaults_and_check_section!(toml_input, + spatial_initial_condition_input, + "r_IC_ion_species_$is") - vpa_IC_section = set_defaults_and_check_section!(toml_input, "vpa_IC_ion_species_$is", - # [ion_vpa_IC_species_1], [ion_vpa_IC_species_2], etc - initialization_option = "gaussian", - width = 1.0, - wavenumber = 1, - density_amplitude = 1.0, - density_phase = 0.0, - upar_amplitude = 0.0, - upar_phase = 0.0, - temperature_amplitude = 0.0, - temperature_phase = 0.0, - monomial_degree = 2, - # need to read resolutions before setting defaults here - v0 = 1.0, - vth0 = 1.0, - vpa0 = 1.0, - vperp0 = 1.0) - vpa_IC_input= Dict(Symbol(k)=>v for (k,v) in vpa_IC_section) - vpa_IC = velocity_initial_condition_input(; vpa_IC_input...) + vpa_IC = set_defaults_and_check_section!(toml_input, + velocity_initial_condition_input, + "vpa_IC_ion_species_$is") - IC_input = Dict("z_IC" => z_IC, "r_IC" => r_IC, "vpa_IC" => vpa_IC) - type_input = Dict("type" => "ion") - spec_section = merge(spec_section, IC_input, type_input) spec_input = Dict(Symbol(k)=>v for (k,v) in spec_section) - ion_spec_params_list[is] = ion_species_parameters(; spec_input...) + ion_spec_params_list[is] = ion_species_parameters(; type="ion", z_IC=z_IC, + r_IC=r_IC, vpa_IC=vpa_IC, + spec_input...) end for isn in 1:nspec_neutral spec_section = set_defaults_and_check_section!(toml_input, "neutral_species_$isn", @@ -133,68 +94,29 @@ function get_species_input(toml_input) # initial temperature initial_temperature = 1.0) - z_IC_section = set_defaults_and_check_section!(toml_input, "z_IC_neutral_species_$isn", - # [neutral_z_IC_species_1], [neutral_z_IC_species_2], etc - initialization_option = "gaussian", - width = 0.125, - wavenumber = 1, - density_amplitude = 0.001, - density_phase = 0.0, - upar_amplitude = 0.0, - upar_phase = 0.0, - temperature_amplitude = 0.0, - temperature_phase = 0.0, - monomial_degree = 2) - z_IC_input = Dict(Symbol(k)=>v for (k,v) in z_IC_section) - z_IC = spatial_initial_condition_input(; z_IC_input...) + z_IC = set_defaults_and_check_section!(toml_input, + spatial_initial_condition_input, + "z_IC_neutral_species_$isn") - r_IC_section = set_defaults_and_check_section!(toml_input, "r_IC_neutral_species_$isn", - # [neutral_r_IC_species_1], [neutral_r_IC_species_2], etc - initialization_option = "gaussian", - width = 0.125, - wavenumber = 1, - density_amplitude = 0.001, - density_phase = 0.0, - upar_amplitude = 0.0, - upar_phase = 0.0, - temperature_amplitude = 0.0, - temperature_phase = 0.0, - monomial_degree = 2) - r_IC_input= Dict(Symbol(k)=>v for (k,v) in r_IC_section) - r_IC = spatial_initial_condition_input(; r_IC_input...) + r_IC = set_defaults_and_check_section!(toml_input, + spatial_initial_condition_input, + "r_IC_neutral_species_$isn") - vpa_IC_section = set_defaults_and_check_section!(toml_input, "vz_IC_neutral_species_$isn", - # [neutral_vpa_IC_species_1], [neutral_vpa_IC_species_2], etc - initialization_option = "gaussian", - width = 1.0, - wavenumber = 1, - density_amplitude = 1.0, - density_phase = 0.0, - upar_amplitude = 0.0, - upar_phase = 0.0, - temperature_amplitude = 0.0, - temperature_phase = 0.0, - monomial_degree = 2, - # need to read resolutions before setting defaults here - v0 = 1.0, - vth0 = 1.0, - vpa0 = 1.0, - vperp0 = 1.0) - vpa_IC_input= Dict(Symbol(k)=>v for (k,v) in vpa_IC_section) - vpa_IC = velocity_initial_condition_input(; vpa_IC_input...) + vz_IC = set_defaults_and_check_section!(toml_input, + velocity_initial_condition_input, + "vz_IC_neutral_species_$isn") - IC_input = Dict("z_IC" => z_IC, "r_IC" => r_IC, "vpa_IC" => vpa_IC) - type_input = Dict("type" => "neutral") - spec_section = merge(spec_section, IC_input, type_input) spec_input = Dict(Symbol(k)=>v for (k,v) in spec_section) - neutral_spec_params_list[isn] = neutral_species_parameters(; spec_input...) + neutral_spec_params_list[isn] = neutral_species_parameters(; type="neutral", + z_IC=z_IC, r_IC=r_IC, + vz_IC=vz_IC, + spec_input...) end - # construct composition dict - species_dict = Dict("n_species" => nspec_tot, "ion" => ion_spec_params_list, "neutral" => neutral_spec_params_list) - composition_section = merge(composition_section,species_dict) - input = Dict(Symbol(k)=>v for (k,v) in composition_section) # construct composition struct - composition = species_composition(; input...) + composition_input = Dict(Symbol(k)=>v for (k,v) in composition_section) + composition = species_composition(; n_species=nspec_tot, ion=ion_spec_params_list, + neutral=neutral_spec_params_list, + composition_input...) ## checks and errors if !(0.0 <= composition.recycling_fraction <= 1.0) From 8dd90254c183b7642e9c1b6b1792f8155471b0d8 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Tue, 10 Sep 2024 14:51:11 +0100 Subject: [PATCH 46/87] Allow NamedTuple 'coords' in create_dynamic_variable!() This change makes it simple to add an extra dimension for which there is not a `coordinate` struct, replacing the special-purpose arguments for n_ion_species, n_neutral_species and diagnostic_var_size. --- moment_kinetics/ext/file_io_netcdf.jl | 103 ++------- moment_kinetics/src/file_io.jl | 290 ++++++++++++-------------- moment_kinetics/src/file_io_hdf5.jl | 94 ++------- 3 files changed, 176 insertions(+), 311 deletions(-) diff --git a/moment_kinetics/ext/file_io_netcdf.jl b/moment_kinetics/ext/file_io_netcdf.jl index bb7a86f2b..fa22f99c3 100644 --- a/moment_kinetics/ext/file_io_netcdf.jl +++ b/moment_kinetics/ext/file_io_netcdf.jl @@ -97,9 +97,17 @@ end function write_single_value!(file_or_group::NCDataset, name, value::Union{Number, AbstractString, AbstractArray{T,N}}, - coords...; parallel_io, n_ion_species=nothing, - n_neutral_species=nothing, description=nothing, - units=nothing) where {T,N} + coords::Union{coordinate,NamedTuple}...; parallel_io, + description=nothing, units=nothing) where {T,N} + + if any(c.n < 0 for c ∈ coords) + error("Got a negative `n` in $coords") + end + if any(c.n == 0 for c ∈ coords) + # No data to write + return nothing + end + if description !== nothing || units !== nothing attributes = Dict{String, Any}() if description !== nothing @@ -112,11 +120,6 @@ function write_single_value!(file_or_group::NCDataset, name, attributes = () end - if n_ion_species !== nothing && n_neutral_species != nothing - error("Cannot have both ion-species and neutral species dimensions." * - "Got n_ion_species=$n_ion_species, n_neutral_species=$n_neutral_species") - end - if isa(value, Number) || isa(value, AbstractString) coords !== () && error("cannot pass coordinates with a scalar") @@ -134,26 +137,6 @@ function write_single_value!(file_or_group::NCDataset, name, maybe_create_netcdf_dim(file_or_group, c) end dims = Tuple(c.name for c in coords) - - if n_ion_species !== nothing - if n_ion_species < 0 - error("n_ion_species must be non-negative, got $n_ion_species") - elseif n_ion_species == 0 - # No data to write - return nothing - end - maybe_create_netcdf_dim(file_or_group, "ion_species", n_ion_species) - dims = tuple(dims..., "ion_species") - elseif n_neutral_species !== nothing - if n_neutral_species < 0 - error("n_neutral_species must be non-negative, got $n_neutral_species") - elseif n_neutral_species == 0 - # No data to write - return nothing - end - maybe_create_netcdf_dim(file_or_group, "neutral_species", n_neutral_species) - dims = tuple(dims..., "neutral_species") - end end if isa(value, Bool) # As a hack, write bools to NetCDF as Char, as NetCDF does not support bools (?), @@ -169,50 +152,20 @@ function write_single_value!(file_or_group::NCDataset, name, end function create_dynamic_variable!(file_or_group::NCDataset, name, type, - coords::coordinate...; parallel_io, - n_ion_species=nothing, n_neutral_species=nothing, - diagnostic_var_size=nothing, description=nothing, - units=nothing) - - if n_ion_species !== nothing && n_neutral_species !== nothing - error("Variable should not contain both ion and neutral species dimensions. " - * "Got n_ion_species=$n_ion_species and " - * "n_neutral_species=$n_neutral_species") - end - if diagnostic_var_size !== nothing && n_ion_species !== nothing - error("Diagnostic variable should not contain both ion species dimension. Got " - * "diagnostic_var_size=$diagnostic_var_size and " - * "n_ion_species=$n_ion_species") + coords::Union{coordinate,NamedTuple}...; parallel_io, + description=nothing, units=nothing) + + if any(c.n < 0 for c ∈ coords) + error("Got a negative `n` in $coords") end - if diagnostic_var_size !== nothing && n_neutral_species !== nothing - error("Diagnostic variable should not contain both neutral species dimension. " - * "Got diagnostic_var_size=$diagnostic_var_size and " - * "n_neutral_species=$n_neutral_species") + if any(c.n == 0 for c ∈ coords) + # No data to write + return nothing end # Create time dimension if necessary maybe_create_netcdf_dim(file_or_group, "time", Inf) - # Create species dimension if necessary - if n_ion_species !== nothing - if n_ion_species < 0 - error("n_ion_species must be non-negative, got $n_ion_species") - elseif n_ion_species == 0 - # No data to write - return nothing - end - maybe_create_netcdf_dim(file_or_group, "ion_species", n_ion_species) - end - if n_neutral_species !== nothing - if n_neutral_species < 0 - error("n_neutral_species must be non-negative, got $n_neutral_species") - elseif n_neutral_species == 0 - # No data to write - return nothing - end - maybe_create_netcdf_dim(file_or_group, "neutral_species", n_neutral_species) - end - # Create other dimensions if necessary for c ∈ coords maybe_create_netcdf_dim(file_or_group, c) @@ -221,23 +174,7 @@ function create_dynamic_variable!(file_or_group::NCDataset, name, type, # create the variable so it can be expanded indefinitely (up to the largest unsigned # integer in size) in the time dimension coord_dims = Tuple(c.name for c ∈ coords) - if diagnostic_var_size !== nothing - if isa(diagnostic_var_size, Number) - # Make diagnostic_var_size a Tuple - diagnostic_var_size = (diagnostic_var_size,) - end - for (i,dim_size) ∈ enumerate(diagnostic_var_size) - maybe_create_netcdf_dim(file_or_group, "$name$i", dim_size) - end - fixed_dims = Tuple("$name$i" for i ∈ 1:length(diagnostic_var_size)) - elseif n_ion_species !== nothing - fixed_dims = tuple(coord_dims..., "ion_species") - elseif n_neutral_species !== nothing - fixed_dims = tuple(coord_dims..., "neutral_species") - else - fixed_dims = coord_dims - end - dims = tuple(fixed_dims..., "time") + dims = tuple(coord_dims..., "time") # create the variable so it can be expanded indefinitely (up to the largest unsigned # integer in size) in the time dimension diff --git a/moment_kinetics/src/file_io.jl b/moment_kinetics/src/file_io.jl index 5f6adab0d..0b058278f 100644 --- a/moment_kinetics/src/file_io.jl +++ b/moment_kinetics/src/file_io.jl @@ -459,8 +459,7 @@ function setup_electron_io(io_input, vpa, vperp, z, r, composition, collisions, if io_input.write_electron_error_diagnostics io_f_electron_loworder = create_dynamic_variable!(dynamic, "f_electron_loworder", mk_float, - vpa, vperp, z, r; - n_ion_species=composition.n_ion_species, + vpa, vperp, z, r, parallel_io=parallel_io, description="low-order approximation to electron distribution function, used to diagnose timestepping error") else @@ -469,8 +468,7 @@ function setup_electron_io(io_input, vpa, vperp, z, r, composition, collisions, if io_input.write_electron_steady_state_diagnostics io_f_electron_start_last_timestep = create_dynamic_variable!(dynamic, "f_electron_start_last_timestep", - mk_float, vpa, vperp, z, r; - n_ion_species=composition.n_ion_species, + mk_float, vpa, vperp, z, r, parallel_io=parallel_io, description="electron distribution function at the start of the last electron pseudo-timestep before output, used to measure steady state residual") else @@ -599,7 +597,10 @@ Get names of all variables function get_variable_keys end """ - write_single_value!(file_or_group, name, value; description=nothing, units=nothing) + write_single_value!(file_or_group, name, + data::Union{Number, AbstractString, AbstractArray{T,N}}, + coords::Union{coordinate,mk_int,NamedTuple}...; parallel_io, + description=nothing, units=nothing) where {T,N} Write a single variable to a file or group. If a description or units are passed, add as attributes of the variable. @@ -773,21 +774,24 @@ function write_boundary_distributions!(fid, boundary_distributions, parallel_io, @serial_region begin boundary_distributions_io = create_io_group(fid, "boundary_distributions") + n_ion_species_coord = (name="n_ion_species", n=composition.n_ion_species) + n_neutral_species_coord = (name="n_neutral_species", + n=composition.n_neutral_species) write_single_value!(boundary_distributions_io, "pdf_rboundary_ion_left", boundary_distributions.pdf_rboundary_ion[:,:,:,1,:], vpa, vperp, z, - parallel_io=parallel_io, n_ion_species=composition.n_ion_species, + n_ion_species_coord; parallel_io=parallel_io, description="Initial ion-particle pdf at left radial boundary") write_single_value!(boundary_distributions_io, "pdf_rboundary_ion_right", boundary_distributions.pdf_rboundary_ion[:,:,:,2,:], vpa, vperp, z, - parallel_io=parallel_io, n_ion_species=composition.n_ion_species, + n_ion_species_coord; parallel_io=parallel_io, description="Initial ion-particle pdf at right radial boundary") write_single_value!(boundary_distributions_io, "pdf_rboundary_neutral_left", boundary_distributions.pdf_rboundary_neutral[:,:,:,:,1,:], vz, vr, vzeta, z, - parallel_io=parallel_io, n_neutral_species=composition.n_neutral_species, + n_neutral_species_coord; parallel_io=parallel_io, description="Initial neutral-particle pdf at left radial boundary") write_single_value!(boundary_distributions_io, "pdf_rboundary_neutral_right", boundary_distributions.pdf_rboundary_neutral[:,:,:,:,2,:], vz, vr, vzeta, z, - parallel_io=parallel_io, n_neutral_species=composition.n_neutral_species, + n_neutral_species_coord; parallel_io=parallel_io, description="Initial neutral-particle pdf at right radial boundary") end return nothing @@ -967,21 +971,16 @@ function define_io_coordinate!(parent, coord, coord_name, description, parallel_ end """ - create_dynamic_variable!(file_or_group, name, type, coords::coordinate...; - n_ion_species=1, n_neutral_species=1, - diagnostic_var_size=nothing, description=nothing, - units=nothing) + create_dynamic_variable!(file_or_group, name, type, + coords::{coordinate,NamedTuple}...; + description=nothing, units=nothing) Create a time-evolving variable in `file_or_group` named `name` of type `type`. `coords` are the coordinates corresponding to the dimensions of the array, in the order of the -array dimensions. The species dimension does not have a `coordinate`, so the number of -species is passed as `nspecies`. A description and/or units can be added with the keyword -arguments. - -If a Tuple giving an array size is passed to `diagnostic_var_size`, a 'diagnostic' -variable is created - i.e. one that does not depend on the coordinates, so is assumed to -be the same on all processes and only needs to be written from the root process (for each -output file). +array dimensions - they may be either `coordinate` structs or `NamedTuple`s that contain +at least the fields `name`, `n`. The species dimension does not have a `coordinate`, so +the number of species is passed as `nspecies`. A description and/or units can be added +with the keyword arguments. """ function create_dynamic_variable! end @@ -1078,13 +1077,13 @@ function define_dynamic_moment_variables!(fid, n_ion_species, n_neutral_species, n_failure_vars = length(t_params.failure_caused_by) io_failure_caused_by = create_dynamic_variable!( - dynamic, "failure_caused_by", mk_int; diagnostic_var_size=n_failure_vars, + dynamic, "failure_caused_by", mk_int, (name="n_failure_vars", n=n_failure_vars); parallel_io=parallel_io, description="cumulative count of how many times each variable caused a " * "timestep failure for the run") n_limit_vars = length(t_params.limit_caused_by) io_limit_caused_by = create_dynamic_variable!( - dynamic, "limit_caused_by", mk_int; diagnostic_var_size=n_limit_vars, + dynamic, "limit_caused_by", mk_int, (name="n_limit_vars", n=n_limit_vars); parallel_io=parallel_io, description="cumulative count of how many times each factor limited the " * "timestep for the run") @@ -1203,17 +1202,17 @@ function define_dynamic_ion_moment_variables!(fid, n_ion_species, r::coordinate, evolve_ppar, write_error_diagnostics, write_steady_state_diagnostics) dynamic = get_group(fid, "dynamic_data") + n_ion_species_coord = (name="n_ion_species", n=n_ion_species) # io_density is the handle for the ion particle density - io_density = create_dynamic_variable!(dynamic, "density", mk_float, z, r; - n_ion_species=n_ion_species, - parallel_io=parallel_io, + io_density = create_dynamic_variable!(dynamic, "density", mk_float, z, r, + n_ion_species_coord; parallel_io=parallel_io, description="ion species density", units="n_ref") if write_error_diagnostics io_density_loworder = - create_dynamic_variable!(dynamic, "density_loworder", mk_float, z, r; - n_ion_species=n_ion_species, parallel_io=parallel_io, + create_dynamic_variable!(dynamic, "density_loworder", mk_float, z, r, + n_ion_species_coord; parallel_io=parallel_io, description="low-order approximation to ion species density, used to diagnose timestepping error", units="n_ref") else @@ -1221,8 +1220,8 @@ function define_dynamic_ion_moment_variables!(fid, n_ion_species, r::coordinate, end if write_steady_state_diagnostics io_density_start_last_timestep = - create_dynamic_variable!(dynamic, "density_start_last_timestep", mk_float, z, r; - n_ion_species=n_ion_species, parallel_io=parallel_io, + create_dynamic_variable!(dynamic, "density_start_last_timestep", mk_float, z, r, + n_ion_species_coord; parallel_io=parallel_io, description="ion species density at the start of the last timestep before output, used to measure steady state residual", units="n_ref") else @@ -1230,15 +1229,14 @@ function define_dynamic_ion_moment_variables!(fid, n_ion_species, r::coordinate, end # io_upar is the handle for the ion parallel flow density - io_upar = create_dynamic_variable!(dynamic, "parallel_flow", mk_float, z, r; - n_ion_species=n_ion_species, - parallel_io=parallel_io, + io_upar = create_dynamic_variable!(dynamic, "parallel_flow", mk_float, z, r, + n_ion_species_coord; parallel_io=parallel_io, description="ion species parallel flow", units="c_ref = sqrt(2*T_ref/mi)") if write_error_diagnostics io_upar_loworder = - create_dynamic_variable!(dynamic, "parallel_flow_loworder", mk_float, z, r; - n_ion_species=n_ion_species, parallel_io=parallel_io, + create_dynamic_variable!(dynamic, "parallel_flow_loworder", mk_float, z, r, + n_ion_species_coord; parallel_io=parallel_io, description="low-order approximation to ion species parallel flow, used to diagnose timestepping error", units="c_ref = sqrt(2*T_ref/mi)") else @@ -1247,7 +1245,7 @@ function define_dynamic_ion_moment_variables!(fid, n_ion_species, r::coordinate, if write_steady_state_diagnostics io_upar_start_last_timestep = create_dynamic_variable!(dynamic, "parallel_flow_start_last_timestep", - mk_float, z, r; n_ion_species=n_ion_species, + mk_float, z, r, n_ion_species_coord; parallel_io=parallel_io, description="ion species parallel flow at the start of the last timestep before output, used to measure steady state residual", units="c_ref = sqrt(2*T_ref/mi)") @@ -1256,15 +1254,14 @@ function define_dynamic_ion_moment_variables!(fid, n_ion_species, r::coordinate, end # io_ppar is the handle for the ion parallel pressure - io_ppar = create_dynamic_variable!(dynamic, "parallel_pressure", mk_float, z, r; - n_ion_species=n_ion_species, - parallel_io=parallel_io, + io_ppar = create_dynamic_variable!(dynamic, "parallel_pressure", mk_float, z, r, + n_ion_species_coord; parallel_io=parallel_io, description="ion species parallel pressure", units="n_ref*T_ref") if write_error_diagnostics io_ppar_loworder = - create_dynamic_variable!(dynamic, "parallel_pressure_loworder", mk_float, z, r; - n_ion_species=n_ion_species, parallel_io=parallel_io, + create_dynamic_variable!(dynamic, "parallel_pressure_loworder", mk_float, z, r, + n_ion_species_coord; parallel_io=parallel_io, description="low-order approximation to ion species parallel pressure, used to diagnose timestepping error", units="n_ref*T_ref") else @@ -1273,7 +1270,7 @@ function define_dynamic_ion_moment_variables!(fid, n_ion_species, r::coordinate, if write_steady_state_diagnostics io_ppar_start_last_timestep = create_dynamic_variable!(dynamic, "parallel_pressure_start_last_timestep", - mk_float, z, r; n_ion_species=n_ion_species, + mk_float, z, r, n_ion_species_coord; parallel_io=parallel_io, description="ion species parallel pressure at the start of the last timestep before output, used to measure steady state residual", units="n_ref*T_ref") @@ -1282,15 +1279,14 @@ function define_dynamic_ion_moment_variables!(fid, n_ion_species, r::coordinate, end # io_pperp is the handle for the ion parallel pressure - io_pperp = create_dynamic_variable!(dynamic, "perpendicular_pressure", mk_float, z, r; - n_ion_species=n_ion_species, - parallel_io=parallel_io, + io_pperp = create_dynamic_variable!(dynamic, "perpendicular_pressure", mk_float, z, r, + n_ion_species_coord; parallel_io=parallel_io, description="ion species perpendicular pressure", units="n_ref*T_ref") if write_error_diagnostics io_pperp_loworder = - create_dynamic_variable!(dynamic, "perpendicular_pressure_loworder", mk_float, z, - r; n_ion_species=n_ion_species, parallel_io=parallel_io, + create_dynamic_variable!(dynamic, "perpendicular_pressure_loworder", mk_float, + z, r, n_ion_species_coord; parallel_io=parallel_io, description="low-order approximation to ion species perpendicular pressure, used to diagnose timestepping error", units="n_ref*T_ref") else @@ -1299,7 +1295,7 @@ function define_dynamic_ion_moment_variables!(fid, n_ion_species, r::coordinate, if write_steady_state_diagnostics io_pperp_start_last_timestep = create_dynamic_variable!(dynamic, "perpendicular_pressure_start_last_timestep", - mk_float, z, r; n_ion_species=n_ion_species, + mk_float, z, r, n_ion_species_coord; parallel_io=parallel_io, description="ion species perpendicular pressure at the start of the last timestep before output, used to measure steady state residual", units="n_ref*T_ref") @@ -1308,23 +1304,20 @@ function define_dynamic_ion_moment_variables!(fid, n_ion_species, r::coordinate, end # io_qpar is the handle for the ion parallel heat flux - io_qpar = create_dynamic_variable!(dynamic, "parallel_heat_flux", mk_float, z, r; - n_ion_species=n_ion_species, - parallel_io=parallel_io, + io_qpar = create_dynamic_variable!(dynamic, "parallel_heat_flux", mk_float, z, r, + n_ion_species_coord; parallel_io=parallel_io, description="ion species parallel heat flux", units="n_ref*T_ref*c_ref") # io_vth is the handle for the ion thermal speed - io_vth = create_dynamic_variable!(dynamic, "thermal_speed", mk_float, z, r; - n_ion_species=n_ion_species, - parallel_io=parallel_io, + io_vth = create_dynamic_variable!(dynamic, "thermal_speed", mk_float, z, r, + n_ion_species_coord; parallel_io=parallel_io, description="ion species thermal speed", units="c_ref") # io_dSdt is the handle for the entropy production (due to collisions) - io_dSdt = create_dynamic_variable!(dynamic, "entropy_production", mk_float, z, r; - n_ion_species=n_ion_species, - parallel_io=parallel_io, + io_dSdt = create_dynamic_variable!(dynamic, "entropy_production", mk_float, z, r, + n_ion_species_coord; parallel_io=parallel_io, description="ion species entropy production", units="") @@ -1384,41 +1377,38 @@ function define_dynamic_ion_moment_variables!(fid, n_ion_species, r::coordinate, if parallel_io || z.irank == 0 # io_chodura_lower is the handle for the ion thermal speed - io_chodura_lower = create_dynamic_variable!(dynamic, "chodura_integral_lower", mk_float, r; - n_ion_species=n_ion_species, - parallel_io=parallel_io, - description="Generalised Chodura integral lower sheath entrance", - units="c_ref") + io_chodura_lower = create_dynamic_variable!(dynamic, "chodura_integral_lower", mk_float, r, + n_ion_species_coord; + parallel_io=parallel_io, + description="Generalised Chodura integral lower sheath entrance", + units="c_ref") else io_chodura_lower = nothing end if parallel_io || z.irank == z.nrank - 1 # io_chodura_upper is the handle for the ion thermal speed - io_chodura_upper = create_dynamic_variable!(dynamic, "chodura_integral_upper", mk_float, r; - n_ion_species=n_ion_species, - parallel_io=parallel_io, - description="Generalised Chodura integral upper sheath entrance", - units="c_ref") + io_chodura_upper = create_dynamic_variable!(dynamic, "chodura_integral_upper", mk_float, r, + n_ion_species_coord; + parallel_io=parallel_io, + description="Generalised Chodura integral upper sheath entrance", + units="c_ref") else io_chodura_upper = nothing end if evolve_density || evolve_upar || evolve_ppar ion_constraints_A_coefficient = - create_dynamic_variable!(dynamic, "ion_constraints_A_coefficient", mk_float, z, r; - n_ion_species=n_ion_species, - parallel_io=parallel_io, - description="'A' coefficient enforcing density constraint for ions") + create_dynamic_variable!(dynamic, "ion_constraints_A_coefficient", mk_float, + z, r, n_ion_species_coord; parallel_io=parallel_io, + description="'A' coefficient enforcing density constraint for ions") ion_constraints_B_coefficient = - create_dynamic_variable!(dynamic, "ion_constraints_B_coefficient", mk_float, z, r; - n_ion_species=n_ion_species, - parallel_io=parallel_io, - description="'B' coefficient enforcing flow constraint for ions") + create_dynamic_variable!(dynamic, "ion_constraints_B_coefficient", mk_float, + z, r, n_ion_species_coord; parallel_io=parallel_io, + description="'B' coefficient enforcing flow constraint for ions") ion_constraints_C_coefficient = - create_dynamic_variable!(dynamic, "ion_constraints_C_coefficient", mk_float, z, r; - n_ion_species=n_ion_species, - parallel_io=parallel_io, - description="'C' coefficient enforcing pressure constraint for ions") + create_dynamic_variable!(dynamic, "ion_constraints_C_coefficient", mk_float, + z, r, n_ion_species_coord; parallel_io=parallel_io, + description="'C' coefficient enforcing pressure constraint for ions") else ion_constraints_A_coefficient = nothing ion_constraints_B_coefficient = nothing @@ -1449,9 +1439,9 @@ function define_dynamic_electron_moment_variables!(fid, r::coordinate, z::coordi if !electron_only_io # io_density is the handle for the ion particle density io_electron_density = create_dynamic_variable!(dynamic, "electron_density", mk_float, z, r; - parallel_io=parallel_io, - description="electron species density", - units="n_ref") + parallel_io=parallel_io, + description="electron species density", + units="n_ref") if write_error_diagnostics io_electron_density_loworder = create_dynamic_variable!(dynamic, "electron_density_loworder", mk_float, z, r; @@ -1473,9 +1463,9 @@ function define_dynamic_electron_moment_variables!(fid, r::coordinate, z::coordi # io_electron_upar is the handle for the electron parallel flow density io_electron_upar = create_dynamic_variable!(dynamic, "electron_parallel_flow", mk_float, z, r; - parallel_io=parallel_io, - description="electron species parallel flow", - units="c_ref = sqrt(2*T_ref/mi)") + parallel_io=parallel_io, + description="electron species parallel flow", + units="c_ref = sqrt(2*T_ref/mi)") if write_error_diagnostics io_electron_upar_loworder = create_dynamic_variable!(dynamic, "electron_parallel_flow_loworder", mk_float, z, @@ -1530,15 +1520,15 @@ function define_dynamic_electron_moment_variables!(fid, r::coordinate, z::coordi # io_electron_qpar is the handle for the electron parallel heat flux io_electron_qpar = create_dynamic_variable!(dynamic, "electron_parallel_heat_flux", mk_float, z, r; - parallel_io=parallel_io, - description="electron species parallel heat flux", - units="n_ref*T_ref*c_ref") + parallel_io=parallel_io, + description="electron species parallel heat flux", + units="n_ref*T_ref*c_ref") # io_electron_vth is the handle for the electron thermal speed io_electron_vth = create_dynamic_variable!(dynamic, "electron_thermal_speed", mk_float, z, r; - parallel_io=parallel_io, - description="electron species thermal speed", - units="c_ref") + parallel_io=parallel_io, + description="electron species thermal speed", + units="c_ref") electron_source_settings = external_source_settings.electron if electron_source_settings.active @@ -1567,16 +1557,16 @@ function define_dynamic_electron_moment_variables!(fid, r::coordinate, z::coordi electron_constraints_A_coefficient = create_dynamic_variable!(dynamic, "electron_constraints_A_coefficient", mk_float, z, r; - parallel_io=parallel_io, - description="'A' coefficient enforcing density constraint for electrons") + parallel_io=parallel_io, + description="'A' coefficient enforcing density constraint for electrons") electron_constraints_B_coefficient = create_dynamic_variable!(dynamic, "electron_constraints_B_coefficient", mk_float, z, r; - parallel_io=parallel_io, - description="'B' coefficient enforcing flow constraint for electrons") + parallel_io=parallel_io, + description="'B' coefficient enforcing flow constraint for electrons") electron_constraints_C_coefficient = create_dynamic_variable!(dynamic, "electron_constraints_C_coefficient", mk_float, z, r; - parallel_io=parallel_io, - description="'C' coefficient enforcing pressure constraint for electrons") + parallel_io=parallel_io, + description="'C' coefficient enforcing pressure constraint for electrons") if electron_physics ∈ (kinetic_electrons, kinetic_electrons_with_temperature_equation) io_electron_step_counter = create_dynamic_variable!( @@ -1601,15 +1591,15 @@ function define_dynamic_electron_moment_variables!(fid, r::coordinate, z::coordi n_failure_vars = length(t_params.failure_caused_by) io_electron_failure_caused_by = create_dynamic_variable!( - dynamic, "electron_failure_caused_by", mk_int; - diagnostic_var_size=n_failure_vars, parallel_io=parallel_io, + dynamic, "electron_failure_caused_by", mk_int, + (name="n_failure_vars", n=n_failure_vars); parallel_io=parallel_io, description="cumulative count of how many times each variable caused an " * "electron pseudo-timestep failure for the run") n_limit_vars = length(t_params.limit_caused_by) io_electron_limit_caused_by = create_dynamic_variable!( - dynamic, "electron_limit_caused_by", mk_int; diagnostic_var_size=n_limit_vars, - parallel_io=parallel_io, + dynamic, "electron_limit_caused_by", mk_int, + (name="n_limit_vars", n=n_limit_vars); parallel_io=parallel_io, description="cumulative count of how many times each factor limited the " * "electron pseudo-timestep for the run") @@ -1652,18 +1642,18 @@ function define_dynamic_neutral_moment_variables!(fid, n_neutral_species, r::coo evolve_ppar, write_error_diagnostics, write_steady_state_diagnostics) dynamic = get_group(fid, "dynamic_data") + n_neutral_species_coord = (name="n_neutral_species", n=n_neutral_species) # io_density_neutral is the handle for the neutral particle density - io_density_neutral = create_dynamic_variable!(dynamic, "density_neutral", mk_float, z, r; - n_neutral_species=n_neutral_species, + io_density_neutral = create_dynamic_variable!(dynamic, "density_neutral", mk_float, z, + r, n_neutral_species_coord; parallel_io=parallel_io, description="neutral species density", units="n_ref") if write_error_diagnostics io_density_neutral_loworder = - create_dynamic_variable!(dynamic, "density_neutral_loworder", mk_float, z, r; - n_neutral_species=n_neutral_species, - parallel_io=parallel_io, + create_dynamic_variable!(dynamic, "density_neutral_loworder", mk_float, z, r, + n_neutral_species_coord; parallel_io=parallel_io, description="low-order approximation to neutral species density, used to diagnose timestepping error", units="n_ref") else @@ -1671,9 +1661,8 @@ function define_dynamic_neutral_moment_variables!(fid, n_neutral_species, r::coo end if write_steady_state_diagnostics io_density_neutral_start_last_timestep = - create_dynamic_variable!(dynamic, "density_neutral_start_last_timestep", mk_float, z, r; - n_neutral_species=n_neutral_species, - parallel_io=parallel_io, + create_dynamic_variable!(dynamic, "density_neutral_start_last_timestep", mk_float, z, r, + n_neutral_species_coord; parallel_io=parallel_io, description="neutral species density at the start of the last timestep before output, used to measure steady state residual", units="n_ref") else @@ -1681,16 +1670,15 @@ function define_dynamic_neutral_moment_variables!(fid, n_neutral_species, r::coo end # io_uz_neutral is the handle for the neutral z momentum density - io_uz_neutral = create_dynamic_variable!(dynamic, "uz_neutral", mk_float, z, r; - n_neutral_species=n_neutral_species, + io_uz_neutral = create_dynamic_variable!(dynamic, "uz_neutral", mk_float, z, r, + n_neutral_species_coord; parallel_io=parallel_io, description="neutral species mean z velocity", units="c_ref = sqrt(2*T_ref/mi)") if write_error_diagnostics io_uz_neutral_loworder = - create_dynamic_variable!(dynamic, "uz_neutral_loworder", mk_float, z, r; - n_neutral_species=n_neutral_species, - parallel_io=parallel_io, + create_dynamic_variable!(dynamic, "uz_neutral_loworder", mk_float, z, r, + n_neutral_species_coord; parallel_io=parallel_io, description="low-order approximation to neutral species mean z velocity, used to diagnose timestepping error", units="c_ref = sqrt(2*T_ref/mi)") else @@ -1698,8 +1686,8 @@ function define_dynamic_neutral_moment_variables!(fid, n_neutral_species, r::coo end if write_steady_state_diagnostics io_uz_neutral_start_last_timestep = - create_dynamic_variable!(dynamic, "uz_neutral_start_last_timestep", mk_float, z, r; - n_neutral_species=n_neutral_species, + create_dynamic_variable!(dynamic, "uz_neutral_start_last_timestep", mk_float, + z, r, n_neutral_species_coord; parallel_io=parallel_io, description="neutral species mean z velocity at the start of the last timestep before output, used to measure steady state residual", units="c_ref = sqrt(2*T_ref/mi)") @@ -1708,16 +1696,15 @@ function define_dynamic_neutral_moment_variables!(fid, n_neutral_species, r::coo end # io_pz_neutral is the handle for the neutral species zz pressure - io_pz_neutral = create_dynamic_variable!(dynamic, "pz_neutral", mk_float, z, r; - n_neutral_species=n_neutral_species, + io_pz_neutral = create_dynamic_variable!(dynamic, "pz_neutral", mk_float, z, r, + n_neutral_species_coord; parallel_io=parallel_io, description="neutral species mean zz pressure", units="n_ref*T_ref") if write_error_diagnostics io_pz_neutral_loworder = - create_dynamic_variable!(dynamic, "pz_neutral_loworder", mk_float, z, r; - n_neutral_species=n_neutral_species, - parallel_io=parallel_io, + create_dynamic_variable!(dynamic, "pz_neutral_loworder", mk_float, z, r, + n_neutral_species_coord; parallel_io=parallel_io, description="low-order approximation to neutral species mean zz pressure, used to diagnose timestepping error", units="n_ref*T_ref") else @@ -1725,8 +1712,8 @@ function define_dynamic_neutral_moment_variables!(fid, n_neutral_species, r::coo end if write_steady_state_diagnostics io_pz_neutral_start_last_timestep = - create_dynamic_variable!(dynamic, "pz_neutral_start_last_timestep", mk_float, z, r; - n_neutral_species=n_neutral_species, + create_dynamic_variable!(dynamic, "pz_neutral_start_last_timestep", mk_float, + z, r, n_neutral_species_coord; parallel_io=parallel_io, description="neutral species mean zz pressure at the start of the last timestep before output, used to measure steady state residual", units="n_ref*T_ref") @@ -1735,16 +1722,15 @@ function define_dynamic_neutral_moment_variables!(fid, n_neutral_species, r::coo end # io_qz_neutral is the handle for the neutral z heat flux - io_qz_neutral = create_dynamic_variable!(dynamic, "qz_neutral", mk_float, z, r; - n_neutral_species=n_neutral_species, + io_qz_neutral = create_dynamic_variable!(dynamic, "qz_neutral", mk_float, z, r, + n_neutral_species_coord; parallel_io=parallel_io, description="neutral species z heat flux", units="n_ref*T_ref*c_ref") # io_thermal_speed_neutral is the handle for the neutral thermal speed io_thermal_speed_neutral = create_dynamic_variable!( - dynamic, "thermal_speed_neutral", mk_float, z, r; - n_neutral_species=n_neutral_species, + dynamic, "thermal_speed_neutral", mk_float, z, r, n_neutral_species_coord; parallel_io=parallel_io, description="neutral species thermal speed", units="c_ref") @@ -1804,20 +1790,20 @@ function define_dynamic_neutral_moment_variables!(fid, n_neutral_species, r::coo if evolve_density || evolve_upar || evolve_ppar neutral_constraints_A_coefficient = - create_dynamic_variable!(dynamic, "neutral_constraints_A_coefficient", mk_float, z, r; - n_neutral_species=n_neutral_species, - parallel_io=parallel_io, - description="'A' coefficient enforcing density constraint for neutrals") + create_dynamic_variable!(dynamic, "neutral_constraints_A_coefficient", + mk_float, z, r, n_neutral_species_coord; + parallel_io=parallel_io, + description="'A' coefficient enforcing density constraint for neutrals") neutral_constraints_B_coefficient = - create_dynamic_variable!(dynamic, "neutral_constraints_B_coefficient", mk_float, z, r; - n_neutral_species=n_neutral_species, - parallel_io=parallel_io, - description="'B' coefficient enforcing flow constraint for neutrals") + create_dynamic_variable!(dynamic, "neutral_constraints_B_coefficient", + mk_float, z, r, n_neutral_species_coord; + parallel_io=parallel_io, + description="'B' coefficient enforcing flow constraint for neutrals") neutral_constraints_C_coefficient = - create_dynamic_variable!(dynamic, "neutral_constraints_C_coefficient", mk_float, z, r; - n_neutral_species=n_neutral_species, - parallel_io=parallel_io, - description="'C' coefficient enforcing pressure constraint for neutrals") + create_dynamic_variable!(dynamic, "neutral_constraints_C_coefficient", + mk_float, z, r, n_neutral_species_coord; + parallel_io=parallel_io, + description="'C' coefficient enforcing pressure constraint for neutrals") else neutral_constraints_A_coefficient = nothing neutral_constraints_B_coefficient = nothing @@ -1856,16 +1842,15 @@ function define_dynamic_dfn_variables!(fid, r, z, vperp, vpa, vzeta, vr, vz, com nl_solver_params) dynamic = get_group(fid, "dynamic_data") + n_ion_species_coord = (name="n_ion_species", n=composition.n_ion_species) # io_f is the handle for the ion pdf - io_f = create_dynamic_variable!(dynamic, "f", mk_float, vpa, vperp, z, r; - n_ion_species=composition.n_ion_species, - parallel_io=parallel_io, + io_f = create_dynamic_variable!(dynamic, "f", mk_float, vpa, vperp, z, r, + n_ion_species_coord; parallel_io=parallel_io, description="ion species distribution function") if io_input.write_error_diagnostics io_f_loworder = create_dynamic_variable!(dynamic, "f_loworder", mk_float, vpa, - vperp, z, r; - n_ion_species=composition.n_ion_species, + vperp, z, r, n_ion_species_coord; parallel_io=parallel_io, description="low-order approximation to ion species distribution function, used to diagnose timestepping error") else @@ -1874,8 +1859,7 @@ function define_dynamic_dfn_variables!(fid, r, z, vperp, vpa, vzeta, vr, vz, com if io_input.write_steady_state_diagnostics io_f_start_last_timestep = create_dynamic_variable!(dynamic, "f_start_last_timestep", mk_float, vpa, - vperp, z, r; - n_ion_species=composition.n_ion_species, + vperp, z, r, n_ion_species_coord; parallel_io=parallel_io, description="ion species distribution function at the start of the last timestep before output, used to measure steady state residual") else @@ -1913,16 +1897,17 @@ function define_dynamic_dfn_variables!(fid, r, z, vperp, vpa, vzeta, vr, vz, com io_f_electron_start_last_timestep = nothing end + n_neutral_species_coord = (name="n_neutral_species", n=composition.n_neutral_species) + # io_f_neutral is the handle for the neutral pdf - io_f_neutral = create_dynamic_variable!(dynamic, "f_neutral", mk_float, vz, vr, vzeta, z, r; - n_neutral_species=composition.n_neutral_species, + io_f_neutral = create_dynamic_variable!(dynamic, "f_neutral", mk_float, vz, vr, vzeta, z, r, + n_neutral_species_coord; parallel_io=parallel_io, description="neutral species distribution function") if io_input.write_error_diagnostics io_f_neutral_loworder = create_dynamic_variable!(dynamic, "f_neutral_loworder", mk_float, vz, vr, - vzeta, z, r; - n_ion_species=composition.n_ion_species, + vzeta, z, r, n_neutral_species_coord; parallel_io=parallel_io, description="low-order approximation to neutral species distribution function, used to diagnose timestepping error") else @@ -1931,9 +1916,8 @@ function define_dynamic_dfn_variables!(fid, r, z, vperp, vpa, vzeta, vr, vz, com if io_input.write_steady_state_diagnostics io_f_neutral_start_last_timestep = create_dynamic_variable!(dynamic, "f_neutral_start_last_timestep", - mk_float, vz, vr, vzeta, z, r; - n_ion_species=composition.n_ion_species, - parallel_io=parallel_io, + mk_float, vz, vr, vzeta, z, r, + n_neutral_species_coord; parallel_io=parallel_io, description="neutral species distribution function at the start of the last timestep before output, used to measure steady state residual") else io_f_neutral_start_last_timestep = nothing diff --git a/moment_kinetics/src/file_io_hdf5.jl b/moment_kinetics/src/file_io_hdf5.jl index 271d79fee..53675051c 100644 --- a/moment_kinetics/src/file_io_hdf5.jl +++ b/moment_kinetics/src/file_io_hdf5.jl @@ -85,8 +85,7 @@ end # HDF5.H5DataStore is the supertype for HDF5.File and HDF5.Group function write_single_value!(file_or_group::HDF5.H5DataStore, name, data::Union{Number, AbstractString, AbstractArray{T,N}}, - coords::Union{coordinate,mk_int}...; parallel_io, - n_ion_species=nothing, n_neutral_species=nothing, + coords::Union{coordinate,mk_int,NamedTuple}...; parallel_io, description=nothing, units=nothing) where {T,N} if isa(data, Union{Number, AbstractString}) file_or_group[name] = data @@ -99,32 +98,18 @@ function write_single_value!(file_or_group::HDF5.H5DataStore, name, return nothing end - if n_ion_species !== nothing && n_neutral_species != nothing - error("Cannot have both ion-species and neutral species dimensions." * - "Got n_ion_species=$n_ion_species, n_neutral_species=$n_neutral_species") + if any(isa(c, mk_int) ? c < 0 : c.n < 0 for c ∈ coords) + error("Got a negative `n` in $coords") end - - if n_ion_species !== nothing - if n_ion_species < 0 - error("n_ion_species must be non-negative, got $n_ion_species") - elseif n_ion_species == 0 - # No data to write - return nothing - end - coords = tuple(coords..., n_ion_species) - elseif n_neutral_species !== nothing - if n_neutral_species < 0 - error("n_neutral_species must be non-negative, got $n_neutral_species") - elseif n_neutral_species == 0 - # No data to write - return nothing - end - coords = tuple(coords..., n_neutral_species) + if any(isa(c, mk_int) ? c == 0 : c.n == 0 for c ∈ coords) + # No data to write + return nothing end + dim_sizes, chunk_sizes = hdf5_get_fixed_dim_sizes(coords, parallel_io) io_var = create_dataset(file_or_group, name, T, dim_sizes, chunk=chunk_sizes) - local_ranges = Tuple(isa(c, mk_int) ? (1:c) : c.local_io_range for c ∈ coords) - global_ranges = Tuple(isa(c, mk_int) ? (1:c) : c.global_io_range for c ∈ coords) + local_ranges = Tuple(isa(c, mk_int) ? (1:c) : isa(c, coordinate) ? c.local_io_range : c.n for c ∈ coords) + global_ranges = Tuple(isa(c, mk_int) ? (1:c) : isa(c, coordinate) ? c.global_io_range : c.n for c ∈ coords) if N == 1 io_var[global_ranges[1]] = @view data[local_ranges[1]] @@ -176,7 +161,7 @@ of species). """ function hdf5_get_fixed_dim_sizes(coords, parallel_io) if parallel_io - dim_sizes = Tuple(isa(c, mk_int) ? c : c.n_global for c in coords) + dim_sizes = Tuple(isa(c, mk_int) ? c : (isa(c, coordinate) ? c.n_global : c.n) for c in coords) else dim_sizes = Tuple(isa(c, mk_int) ? c : c.n for c in coords) end @@ -209,65 +194,24 @@ function hdf5_get_dynamic_dim_sizes(fixed_coords, parallel_io) end function create_dynamic_variable!(file_or_group::HDF5.H5DataStore, name, type, - coords::coordinate...; parallel_io, - n_ion_species=nothing, n_neutral_species=nothing, - diagnostic_var_size=nothing, description=nothing, - units=nothing) - - if n_ion_species !== nothing && n_neutral_species !== nothing - error("Variable should not contain both ion and neutral species dimensions. " - * "Got n_ion_species=$n_ion_species and " - * "n_neutral_species=$n_neutral_species") - end - if diagnostic_var_size !== nothing && n_ion_species !== nothing - error("Diagnostic variable should not contain both ion species dimension. Got " - * "diagnostic_var_size=$diagnostic_var_size and " - * "n_ion_species=$n_ion_species") + coords::Union{coordinate,NamedTuple}...; parallel_io, + description=nothing, units=nothing) + + if any(isa(c, mk_int) ? c < 0 : c.n < 0 for c ∈ coords) + error("Got a negative `n` in $coords") end - if diagnostic_var_size !== nothing && n_neutral_species !== nothing - error("Diagnostic variable should not contain both neutral species dimension. " - * "Got diagnostic_var_size=$diagnostic_var_size and " - * "n_neutral_species=$n_neutral_species") + if any(isa(c, mk_int) ? c == 0 : c.n == 0 for c ∈ coords) + # No data to write + return nothing end - # Add the number of species to the spatial/velocity-space coordinates - if diagnostic_var_size !== nothing - if isa(diagnostic_var_size, Number) - # Make diagnostic_var_size a Tuple - diagnostic_var_size = (diagnostic_var_size,) - end - fixed_coords = diagnostic_var_size - elseif n_ion_species !== nothing - if n_ion_species < 0 - error("n_ion_species must be non-negative, got $n_ion_species") - elseif n_ion_species == 0 - # No data to write - return nothing - end - fixed_coords = tuple(coords..., n_ion_species) - elseif n_neutral_species !== nothing - if n_neutral_species < 0 - error("n_neutral_species must be non-negative, got $n_neutral_species") - elseif n_neutral_species == 0 - # No data to write - return nothing - end - fixed_coords = tuple(coords..., n_neutral_species) - else - fixed_coords = coords - end initial_dim_sizes, max_dim_sizes, chunk_size = - hdf5_get_dynamic_dim_sizes(fixed_coords, parallel_io) + hdf5_get_dynamic_dim_sizes(coords, parallel_io) var = create_dataset(file_or_group, name, type, (initial_dim_sizes, max_dim_sizes), chunk=chunk_size) # Add attribute listing the dimensions belonging to this variable dim_names = Tuple(c.name for c ∈ coords) - if n_ion_species !== nothing - dim_names = tuple(dim_names..., "ion_species") - elseif n_neutral_species !== nothing - dim_names = tuple(dim_names..., "neutral_species") - end add_attribute!(var, "dims", join(dim_names, ",")) if description !== nothing From eb270a9727f6dd86eb2f6a0e0fc93188dd0db271 Mon Sep 17 00:00:00 2001 From: Michael Hardman <29800382+mrhardman@users.noreply.github.com> Date: Wed, 11 Sep 2024 09:27:39 +0100 Subject: [PATCH 47/87] Remove unused external modules from test. --- test_scripts/GaussLobattoLegendre_test.jl | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test_scripts/GaussLobattoLegendre_test.jl b/test_scripts/GaussLobattoLegendre_test.jl index 42fedec56..19f14dc5f 100644 --- a/test_scripts/GaussLobattoLegendre_test.jl +++ b/test_scripts/GaussLobattoLegendre_test.jl @@ -1,8 +1,6 @@ export gausslegendre_test -using FastGaussQuadrature -using LegendrePolynomials: Pl -using LinearAlgebra: mul!, lu, inv, cond +using LinearAlgebra: mul!, cond using Printf using Plots using LaTeXStrings From 5255900ae9b0e1eb527877bcc1d34aca50ded345 Mon Sep 17 00:00:00 2001 From: Michael Hardman <29800382+mrhardman@users.noreply.github.com> Date: Wed, 11 Sep 2024 09:29:55 +0100 Subject: [PATCH 48/87] Refactor 1D matrix assembly, make it clear that boundary conditions should only be imposed if the matrices are being used for solving ODEs, not for differentiation. Periodic and Dirichlet BC options are not tested. Remove dirichlet_bc flag from setup_gausslegendre_pseudospectral(). To use the matrices with boundary conditions, new instances of K,L, etc should be created. --- moment_kinetics/src/gauss_legendre.jl | 102 +++++++++++--------------- 1 file changed, 43 insertions(+), 59 deletions(-) diff --git a/moment_kinetics/src/gauss_legendre.jl b/moment_kinetics/src/gauss_legendre.jl index 5361547cc..88f5bb795 100644 --- a/moment_kinetics/src/gauss_legendre.jl +++ b/moment_kinetics/src/gauss_legendre.jl @@ -100,7 +100,7 @@ struct gausslegendre_info{TSparse, TLU} <: weak_discretization_info Qmat::Array{mk_float,2} end -function setup_gausslegendre_pseudospectral(coord; collision_operator_dim=true, dirichlet_bc=false) +function setup_gausslegendre_pseudospectral(coord; collision_operator_dim=true) lobatto = setup_gausslegendre_pseudospectral_lobatto(coord,collision_operator_dim=collision_operator_dim) radau = setup_gausslegendre_pseudospectral_radau(coord,collision_operator_dim=collision_operator_dim) @@ -114,9 +114,9 @@ function setup_gausslegendre_pseudospectral(coord; collision_operator_dim=true, K_matrix = allocate_float(coord.n,coord.n) L_matrix = allocate_float(coord.n,coord.n) - setup_global_weak_form_matrix!(mass_matrix, lobatto, radau, coord, "M"; dirichlet_bc=dirichlet_bc) - setup_global_weak_form_matrix!(K_matrix, lobatto, radau, coord, "K_with_BC_terms"; dirichlet_bc=dirichlet_bc) - setup_global_weak_form_matrix!(L_matrix, lobatto, radau, coord, "L_with_BC_terms"; dirichlet_bc=dirichlet_bc) + setup_global_weak_form_matrix!(mass_matrix, lobatto, radau, coord, "M") + setup_global_weak_form_matrix!(K_matrix, lobatto, radau, coord, "K_with_BC_terms") + setup_global_weak_form_matrix!(L_matrix, lobatto, radau, coord, "L_with_BC_terms") mass_matrix_lu = lu(sparse(mass_matrix)) Qmat = allocate_float(coord.ngrid,coord.ngrid) @@ -820,78 +820,54 @@ The 'option' variable is a flag for choosing the type of matrix to be constructed. Currently the function is set up to assemble the elemental matrices without imposing boundary conditions on the -first and final rows of the matrix. This means that +first and final rows of the matrix by default. This means that the operators constructed from this function can only be used -for differentiation, and not solving 1D ODEs. -The shared points in the element assembly are -averaged (instead of simply added) to be consistent with the -derivative_elements_to_full_grid!() function in calculus.jl, -which is used to form the RHS of the equation +for differentiation, and not solving 1D ODEs. To solve 1D ODEs +with periodic or dirichlet boundary conditions, set + +periodic_bc = true + +or + +dirichlet_bc = true + +in the function call, and create new matrices for this purpose +in the gausslegendre_info struct. + +This assembly function assumes that the +coordinate is not distributed. To extend this function to support +distributed-memory MPI, addition of off-memory matrix elements +to the exterior points would be required. + +The typical use of this function is to assemble matrixes M and K in M * d2f = K * f -where M is the mass matrix and K is the stiffness matrix. +where M is the mass matrix and K is the stiffness matrix, and we wish to +solve for d2f given f. """ function setup_global_weak_form_matrix!(QQ_global::Array{mk_float,2}, lobatto::gausslegendre_base_info, radau::gausslegendre_base_info, - coord,option; dirichlet_bc=false) + coord,option; dirichlet_bc=false, periodic_bc=false) QQ_j = allocate_float(coord.ngrid,coord.ngrid) - QQ_jp1 = allocate_float(coord.ngrid,coord.ngrid) ngrid = coord.ngrid imin = coord.imin imax = coord.imax @. QQ_global = 0.0 - # fill in first element - j = 1 - # N.B. QQ varies with ielement for vperp, but not vpa - # a radau element is used for the vperp grid (see get_QQ_local!()) - get_QQ_local!(QQ_j,j,lobatto,radau,coord,option) - if coord.bc == "periodic" && coord.nrank == 1 - QQ_global[imin[j],imin[j]:imax[j]] .+= QQ_j[1,:] ./ 2.0 - else - QQ_global[imin[j],imin[j]:imax[j]] .+= QQ_j[1,:] - end - for k in 2:imax[j]-imin[j] - QQ_global[k,imin[j]:imax[j]] .+= QQ_j[k,:] - end - if coord.nelement_local > 1 - QQ_global[imax[j],imin[j]:imax[j]] .+= QQ_j[ngrid,:]./2.0 - elseif coord.bc == "periodic" && coord.nrank == 1 - QQ_global[imin[1],imin[j]:imax[j]] .+= QQ_j[ngrid,:]./2.0 - # Enforce continuity at the periodic boundary - QQ_global[imax[j],imin[j]:imax[j]] .= 0.0 - QQ_global[imax[j],1] = 1.0 - QQ_global[imax[j],end] = -1.0 - else - QQ_global[imax[j],imin[j]:imax[j]] .+= QQ_j[ngrid,:] - end - # remaining elements recalling definitions of imax and imin - for j in 2:coord.nelement_local + # assembly below assumes no contributions + # from elements outside of local domain + k = 0 + for j in 1:coord.nelement_local get_QQ_local!(QQ_j,j,lobatto,radau,coord,option) - #lower boundary assembly on element - QQ_global[imin[j]-1,imin[j]-1:imax[j]] .+= QQ_j[1,:]./2.0 - for k in 2:imax[j]-imin[j]+1 - QQ_global[k+imin[j]-2,imin[j]-1:imax[j]] .+= QQ_j[k,:] - end - # upper boundary assembly on element - if j == coord.nelement_local - if coord.bc == "periodic" && coord.nrank == 1 - QQ_global[imin[1],imin[j]-1:imax[j]] .+= QQ_j[ngrid,:] / 2.0 - # Enforce continuity at the periodic boundary - QQ_global[imax[j],imin[j]-1:imax[j]] .= 0.0 - QQ_global[imax[j],1] = 1.0 - QQ_global[imax[j],end] = -1.0 - else - QQ_global[imax[j],imin[j]-1:imax[j]] .+= QQ_j[ngrid,:] - end - else - QQ_global[imax[j],imin[j]-1:imax[j]] .+= QQ_j[ngrid,:]./2.0 - end + iminl = imin[j]-k + imaxl = imax[j] + @. QQ_global[iminl:imaxl,iminl:imaxl] += QQ_j[:,:] + k = 1 end - + if dirichlet_bc # Make matrix diagonal for first/last grid points so it does not change the values # there @@ -907,6 +883,14 @@ function setup_global_weak_form_matrix!(QQ_global::Array{mk_float,2}, QQ_global[end,end] = 1.0 end end + if periodic_bc + # Make periodic boundary condition by modifying elements of matrix for duplicate point + # Enforce continuity at the periodic boundary + j = nelement_local + QQ_global[imax[j],:] .= 0.0 + QQ_global[imax[j],1] = 1.0 + QQ_global[imax[j],end] = -1.0 + end return nothing end From 0d085d3b039e6bb201202670032b4f6706b3d545 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Wed, 11 Sep 2024 09:26:47 +0100 Subject: [PATCH 49/87] Fix default value for "vperp" coordinate --- moment_kinetics/src/coordinates.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/moment_kinetics/src/coordinates.jl b/moment_kinetics/src/coordinates.jl index 18cb0b04a..f4e274fee 100644 --- a/moment_kinetics/src/coordinates.jl +++ b/moment_kinetics/src/coordinates.jl @@ -139,7 +139,7 @@ function get_coordinate_input(input_dict, name; ignore_MPI=false) elseif name == "r" default_bc = "periodic" elseif name == "vperp" - default_bc = "zero" + default_bc = "default" else default_bc = "zero" end From 17dff2d38dd5e70ffba7bf06eb7e0d1963e985dd Mon Sep 17 00:00:00 2001 From: John Omotani Date: Wed, 11 Sep 2024 10:05:22 +0100 Subject: [PATCH 50/87] Add define_test_coordinate() function Makes setup for a few tests slightly less verbose. --- moment_kinetics/src/coordinates.jl | 32 +- moment_kinetics/test/calculus_tests.jl | 362 +++++++++----------- moment_kinetics/test/interpolation_tests.jl | 16 +- 3 files changed, 196 insertions(+), 214 deletions(-) diff --git a/moment_kinetics/src/coordinates.jl b/moment_kinetics/src/coordinates.jl index f4e274fee..b2c54269e 100644 --- a/moment_kinetics/src/coordinates.jl +++ b/moment_kinetics/src/coordinates.jl @@ -7,7 +7,7 @@ export equally_spaced_grid export set_element_boundaries using LinearAlgebra -using ..type_definitions: mk_float, mk_int +using ..type_definitions: mk_float, mk_int, OptionsDict using ..array_allocation: allocate_float, allocate_shared_float, allocate_int using ..calculus: derivative! using ..chebyshev: scaled_chebyshev_grid, scaled_chebyshev_radau_grid, setup_chebyshev_pseudospectral @@ -381,6 +381,36 @@ function define_coordinate(coord_input::NamedTuple; parallel_io::Bool=false, return coord, spectral end +""" + define_test_coordinate(input_dict::AbstractDict; kwargs...) + define_test_coordinate(name; collision_operator_dim=true, kwargs...) + +Wrapper for `define_coordinate()` to make creating a coordinate for tests slightly less +verbose. + +When passing `input_dict`, it must contain a "name" field, and can contain other settings +- "ngrid", "nelement", etc. Options other than "name" will be set using defaults if they +are not passed. `kwargs` are the keyword arguments for [`define_coordinate`](@ref). + +The second form allows the coordinate input options to be passed as keyword arguments. For +this form, apart from `collision_operator_dim`, the keyword arguments of +[`define_coordinate`](@ref) cannot be passed, and `ignore_MPI=true` is always set, as this +is most often useful for tests. +""" +function define_test_coordinate end +function define_test_coordinate(input_dict::AbstractDict; kwargs...) + input_dict = deepcopy(input_dict) + name = pop!(input_dict, "name") + return define_coordinate(OptionsDict(name => input_dict), name; kwargs...) +end +function define_test_coordinate(name; collision_operator_dim=true, kwargs...) + coord_input_dict = OptionsDict(String(k) => v for (k,v) in kwargs) + coord_input_dict["name"] = name + return define_test_coordinate(coord_input_dict; + collision_operator_dim=collision_operator_dim, + ignore_MPI=true) +end + function set_element_boundaries(nelement_global, L, element_spacing_option, coord_name) # set global element boundaries between [-L/2,L/2] element_boundaries = allocate_float(nelement_global+1) diff --git a/moment_kinetics/test/calculus_tests.jl b/moment_kinetics/test/calculus_tests.jl index d6a871cba..8a85cd849 100644 --- a/moment_kinetics/test/calculus_tests.jl +++ b/moment_kinetics/test/calculus_tests.jl @@ -2,7 +2,7 @@ module CalculusTests include("setup.jl") -using moment_kinetics.coordinates: define_coordinate +using moment_kinetics.coordinates: define_test_coordinate using moment_kinetics.calculus: derivative!, second_derivative!, integral using moment_kinetics.calculus: laplacian_derivative! @@ -34,19 +34,17 @@ function runtests() bc = "none" end fd_option = "" - # create the 'input' struct containing input info needed to create a - # coordinate - input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, "nelement"=>nelement, - "L"=>L, - "discretization"=>discretization, - "finite_difference_option"=>fd_option, - "cheb_option"=>cheb_option, - "bc"=>bc, - "element_spacing_option"=>element_spacing_option)) # create the coordinate struct 'x' - # This test runs effectively in serial, so use `ignore_MPI=true` to avoid - # errors due to communicators not being fully set up. - x, spectral = define_coordinate(input, "coord"; ignore_MPI=true, collision_operator_dim=false) + # This test runs effectively in serial, so implicitly uses + # `ignore_MPI=true` to avoid errors due to communicators not being fully + # set up. + x, spectral = define_test_coordinate("coord"; ngrid=ngrid, + nelement=nelement, L=L, + discretization=discretization, + finite_difference_option=fd_option, + cheb_option=cheb_option, bc=bc, + element_spacing_option=element_spacing_option, + collision_operator_dim=false) # create array for the function f(x) to be differentiated/integrated f = Array{Float64,1}(undef, x.n) # create array for the derivative df/dx @@ -81,20 +79,18 @@ function runtests() L = 6.0 bc = "periodic" fd_option = "" - # create the 'input' struct containing input info needed to create a - # coordinate - nelement_local = nelement element_spacing_option = "uniform" # dummy value - input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, "nelement"=>nelement, - "L"=>L, - "discretization"=>"finite_difference", - "finite_difference_option"=>fd_option, - "bc"=>bc, - "element_spacing_option"=>element_spacing_option)) # create the coordinate struct 'x' - # This test runs effectively in serial, so use `ignore_MPI=true` to avoid - # errors due to communicators not being fully set up. - x, spectral = define_coordinate(input, "coord"; ignore_MPI=true) + # This test runs effectively in serial, so implicitly uses + # `ignore_MPI=true` to avoid errors due to communicators not being fully + # set up. + x, spectral = define_test_coordinate("coord"; ngrid=ngrid, + nelement=nelement, L=L, + discretization="finite_difference", + finite_difference_option=fd_option, + bc=bc, + element_spacing_option=element_spacing_option, + collision_operator_dim=false) # create array for the derivative df/dx and the expected result df = Array{Float64,1}(undef, x.n) @@ -129,20 +125,18 @@ function runtests() L = 6.0 bc = "periodic" fd_option = "fourth_order_centered" - # create the 'input' struct containing input info needed to create a - # coordinate - nelement_local = nelement element_spacing_option = "uniform" # dummy value - input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, "nelement"=>nelement, - "L"=>L, - "discretization"=>"finite_difference", - "finite_difference_option"=>fd_option, - "bc"=>bc, - "element_spacing_option"=>element_spacing_option)) # create the coordinate struct 'x' - # This test runs effectively in serial, so use `ignore_MPI=true` to avoid - # errors due to communicators not being fully set up. - x, spectral = define_coordinate(input, "coord"; ignore_MPI=true) + # This test runs effectively in serial, so implicitly uses + # `ignore_MPI=true` to avoid errors due to communicators not being fully + # set up. + x, spectral = define_test_coordinate("coord"; ngrid=ngrid, + nelement=nelement, L=L, + discretization="finite_difference", + finite_difference_option=fd_option, + bc=bc, + element_spacing_option=element_spacing_option, + collision_operator_dim=false) # create array for the derivative df/dx and the expected result df = Array{Float64,1}(undef, x.n) @@ -173,20 +167,18 @@ function runtests() # define inputs needed for the test L = 6.0 fd_option = "" - # create the 'input' struct containing input info needed to create a - # coordinate - nelement_local = nelement element_spacing_option = "uniform" # dummy value - input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, "nelement"=>nelement, - "L"=>L, - "discretization"=>"finite_difference", - "finite_difference_option"=>fd_option, - "bc"=>bc, - "element_spacing_option"=>element_spacing_option)) # create the coordinate struct 'x' - # This test runs effectively in serial, so use `ignore_MPI=true` to avoid - # errors due to communicators not being fully set up. - x, spectral = define_coordinate(input, "coord"; ignore_MPI=true) + # This test runs effectively in serial, so implicitly uses + # `ignore_MPI=true` to avoid errors due to communicators not being fully + # set up. + x, spectral = define_test_coordinate("coord"; ngrid=ngrid, + nelement=nelement, L=L, + discretization="finite_difference", + finite_difference_option=fd_option, + bc=bc, + element_spacing_option=element_spacing_option, + collision_operator_dim=false) # create array for the derivative df/dx and the expected result df = Array{Float64,1}(undef, x.n) @@ -225,20 +217,18 @@ function runtests() # define inputs needed for the test L = 6.0 - # create the 'input' struct containing input info needed to create a - # coordinate - nelement_local = nelement element_spacing_option = "uniform" # dummy value - input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, "nelement"=>nelement, - "L"=>L, - "discretization"=>"finite_difference", - "finite_difference_option"=>fd_option, - "bc"=>bc, - "element_spacing_option"=>element_spacing_option)) # create the coordinate struct 'x' - # This test runs effectively in serial, so use `ignore_MPI=true` to avoid - # errors due to communicators not being fully set up. - x, spectral = define_coordinate(input, "coord"; ignore_MPI=true) + # This test runs effectively in serial, so implicitly uses + # `ignore_MPI=true` to avoid errors due to communicators not being fully + # set up. + x, spectral = define_test_coordinate("coord"; ngrid=ngrid, + nelement=nelement, L=L, + discretization="finite_difference", + finite_difference_option=fd_option, + bc=bc, + element_spacing_option=element_spacing_option, + collision_operator_dim=false) # create array for the derivative df/dx and the expected result df = Array{Float64,1}(undef, x.n) @@ -439,20 +429,17 @@ function runtests() # define inputs needed for the test L = 6.0 bc = "periodic" - # create the 'input' struct containing input info needed to create a - # coordinate - nelement_local = nelement element_spacing_option = "uniform" - input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, "nelement"=>nelement, - "L"=>L, - "discretization"=>"chebyshev_pseudospectral", - "cheb_option"=>cheb_option, - "bc"=>bc, - "element_spacing_option"=>element_spacing_option)) # create the coordinate struct 'x' - # This test runs effectively in serial, so use `ignore_MPI=true` to avoid - # errors due to communicators not being fully set up. - x, spectral = define_coordinate(input, "coord"; ignore_MPI=true) + # This test runs effectively in serial, so implicitly uses + # `ignore_MPI=true` to avoid errors due to communicators not being fully + # set up. + x, spectral = define_test_coordinate("coord"; ngrid=ngrid, + nelement=nelement, L=L, + discretization="chebyshev_pseudospectral", + cheb_option=cheb_option, bc=bc, + element_spacing_option=element_spacing_option, + collision_operator_dim=false) offset = randn(rng) f = @. sinpi(2.0 * x.grid / L) + offset @@ -633,20 +620,17 @@ function runtests() # define inputs needed for the test L = 6.0 bc = "periodic" - # create the 'input' struct containing input info needed to create a - # coordinate - nelement_local = nelement element_spacing_option = "uniform" - input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, "nelement"=>nelement, - "L"=>L, - "discretization"=>"chebyshev_pseudospectral", - "cheb_option"=>cheb_option, - "bc"=>bc, - "element_spacing_option"=>element_spacing_option)) # create the coordinate struct 'x' - # This test runs effectively in serial, so use `ignore_MPI=true` to avoid - # errors due to communicators not being fully set up. - x, spectral = define_coordinate(input, "coord"; ignore_MPI=true) + # This test runs effectively in serial, so implicitly uses + # `ignore_MPI=true` to avoid errors due to communicators not being fully + # set up. + x, spectral = define_test_coordinate("coord"; ngrid=ngrid, + nelement=nelement, L=L, + discretization="chebyshev_pseudospectral", + cheb_option=cheb_option, bc=bc, + element_spacing_option=element_spacing_option, + collision_operator_dim=false) offset = randn(rng) f = @. sinpi(2.0 * x.grid / L) + offset @@ -675,19 +659,16 @@ function runtests() # define inputs needed for the test L = 1.0 bc = "constant" - # create the 'input' struct containing input info needed to create a - # coordinate - nelement_local = nelement - input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, "nelement"=>nelement, - "L"=>L, - "discretization"=>"chebyshev_pseudospectral", - "cheb_option"=>cheb_option, - "bc"=>bc, - "element_spacing_option"=>element_spacing_option)) # create the coordinate struct 'x' - # This test runs effectively in serial, so use `ignore_MPI=true` to avoid - # errors due to communicators not being fully set up. - x, spectral = define_coordinate(input, "coord"; ignore_MPI=true) + # This test runs effectively in serial, so implicitly uses + # `ignore_MPI=true` to avoid errors due to communicators not being fully + # set up. + x, spectral = define_test_coordinate("coord"; ngrid=ngrid, + nelement=nelement, L=L, + discretization="chebyshev_pseudospectral", + cheb_option=cheb_option, bc=bc, + element_spacing_option=element_spacing_option, + collision_operator_dim=false) # test polynomials up to order ngrid-1 for n ∈ 0:ngrid-1 # create array for the function f(x) to be differentiated/integrated @@ -723,19 +704,16 @@ function runtests() # define inputs needed for the test L = 1.0 bc = "constant" - # create the 'input' struct containing input info needed to create a - # coordinate - nelement_local = nelement - input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, "nelement"=>nelement, - "L"=>L, - "discretization"=>"chebyshev_pseudospectral", - "cheb_option"=>cheb_option, - "bc"=>bc, - "element_spacing_option"=>element_spacing_option)) # create the coordinate struct 'x' - # This test runs effectively in serial, so use `ignore_MPI=true` to avoid - # errors due to communicators not being fully set up. - x, spectral = define_coordinate(input, "coord"; ignore_MPI=true) + # This test runs effectively in serial, so implicitly uses + # `ignore_MPI=true` to avoid errors due to communicators not being fully + # set up. + x, spectral = define_test_coordinate("coord"; ngrid=ngrid, + nelement=nelement, L=L, + discretization="chebyshev_pseudospectral", + cheb_option=cheb_option, bc=bc, + element_spacing_option=element_spacing_option, + collision_operator_dim=false) # test polynomials up to order ngrid-1 for n ∈ 0:ngrid-1 # create array for the function f(x) to be differentiated/integrated @@ -855,17 +833,15 @@ function runtests() # define inputs needed for the test L = 6.0 bc = "periodic" - # create the 'input' struct containing input info needed to create a - # coordinate - nelement_local = nelement - input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, "nelement"=>nelement, - "L"=>L, - "discretization"=>"gausslegendre_pseudospectral", - "bc"=>bc)) # create the coordinate struct 'x' - # This test runs effectively in serial, so use `ignore_MPI=true` to avoid - # errors due to communicators not being fully set up. - x, spectral = define_coordinate(input, "coord"; ignore_MPI=true, collision_operator_dim=false) + # This test runs effectively in serial, so implicitly uses + # `ignore_MPI=true` to avoid errors due to communicators not being fully + # set up. + x, spectral = define_test_coordinate("coord"; ngrid=ngrid, + nelement=nelement, L=L, + discretization="gausslegendre_pseudospectral", + bc=bc, + collision_operator_dim=false) offset = randn(rng) f = @. sinpi(2.0 * x.grid / L) + offset @@ -966,19 +942,17 @@ function runtests() # define inputs needed for the test L = 6.0 bc = "periodic" - # create the 'input' struct containing input info needed to create a - # coordinate - nelement_local = nelement element_spacing_option = "uniform" - input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, "nelement"=>nelement, - "L"=>L, - "discretization"=>"gausslegendre_pseudospectral", - "bc"=>bc, - "element_spacing_option"=>element_spacing_option)) # create the coordinate struct 'x' - # This test runs effectively in serial, so use `ignore_MPI=true` to avoid - # errors due to communicators not being fully set up. - x, spectral = define_coordinate(input, "coord"; ignore_MPI=true, collision_operator_dim=false) + # This test runs effectively in serial, so implicitly uses + # `ignore_MPI=true` to avoid errors due to communicators not being fully + # set up. + x, spectral = define_test_coordinate("coord"; ngrid=ngrid, + nelement=nelement, L=L, + discretization="gausslegendre_pseudospectral", + bc=bc, + element_spacing_option=element_spacing_option, + collision_operator_dim=false) offset = randn(rng) f = @. sinpi(2.0 * x.grid / L) + offset @@ -1007,18 +981,16 @@ function runtests() # define inputs needed for the test L = 1.0 bc = "constant" - # create the 'input' struct containing input info needed to create a - # coordinate - nelement_local = nelement - input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, "nelement"=>nelement, - "L"=>L, - "discretization"=>"gausslegendre_pseudospectral", - "bc"=>bc, - "element_spacing_option"=>element_spacing_option)) # create the coordinate struct 'x' - # This test runs effectively in serial, so use `ignore_MPI=true` to avoid - # errors due to communicators not being fully set up. - x, spectral = define_coordinate(input, "coord"; ignore_MPI=true, collision_operator_dim=false) + # This test runs effectively in serial, so implicitly uses + # `ignore_MPI=true` to avoid errors due to communicators not being fully + # set up. + x, spectral = define_test_coordinate("coord"; ngrid=ngrid, + nelement=nelement, L=L, + discretization="gausslegendre_pseudospectral", + bc=bc, + element_spacing_option=element_spacing_option, + collision_operator_dim=false) # test polynomials up to order ngrid-1 for n ∈ 0:ngrid-1 # create array for the function f(x) to be differentiated/integrated @@ -1054,18 +1026,16 @@ function runtests() # define inputs needed for the test L = 1.0 bc = "constant" - # create the 'input' struct containing input info needed to create a - # coordinate - nelement_local = nelement - input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, "nelement"=>nelement, - "L"=>L, - "discretization"=>"gausslegendre_pseudospectral", - "bc"=>bc, - "element_spacing_option"=>element_spacing_option)) # create the coordinate struct 'x' - # This test runs effectively in serial, so use `ignore_MPI=true` to avoid - # errors due to communicators not being fully set up. - x, spectral = define_coordinate(input, "coord"; ignore_MPI=true, collision_operator_dim=false) + # This test runs effectively in serial, so implicitly uses + # `ignore_MPI=true` to avoid errors due to communicators not being fully + # set up. + x, spectral = define_test_coordinate("coord"; ngrid=ngrid, + nelement=nelement, L=L, + discretization="gausslegendre_pseudospectral", + bc=bc, + element_spacing_option=element_spacing_option, + collision_operator_dim=false) # test polynomials up to order ngrid-1 for n ∈ 0:ngrid-1 # create array for the function f(x) to be differentiated/integrated @@ -1264,20 +1234,17 @@ function runtests() # define inputs needed for the test L = 6.0 bc = "periodic" - # create the 'input' struct containing input info needed to create a - # coordinate - nelement_local = nelement element_spacing_option = "uniform" - input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, "nelement"=>nelement, - "L"=>L, - "discretization"=>"chebyshev_pseudospectral", - "cheb_option"=>cheb_option, - "bc"=>bc, - "element_spacing_option"=>element_spacing_option)) # create the coordinate struct 'x' - # This test runs effectively in serial, so use `ignore_MPI=true` to avoid - # errors due to communicators not being fully set up. - x, spectral = define_coordinate(input, "coord"; ignore_MPI=true) + # This test runs effectively in serial, so implicitly uses + # `ignore_MPI=true` to avoid errors due to communicators not being fully + # set up. + x, spectral = define_test_coordinate("coord"; ngrid=ngrid, + nelement=nelement, L=L, + discretization="chebyshev_pseudospectral", + cheb_option=cheb_option, bc=bc, + element_spacing_option=element_spacing_option, + collision_operator_dim=false) offset = randn(rng) f = @. sinpi(2.0 * x.grid / L) + offset @@ -1357,23 +1324,17 @@ function runtests() # define inputs needed for the test L = 6.0 bc = "zero" - # create the 'input' struct containing input info needed to create a - # coordinate - nelement_local = nelement element_spacing_option = "uniform" - # create the coordinate struct 'x' and info for derivatives, etc. - # This test runs effectively in serial, so use `ignore_MPI=true` to avoid - # errors due to communicators not being fully set up. - input = OptionsDict("vperp" => OptionsDict("ngrid"=>ngrid, "nelement"=>nelement, - "L"=>L, - "discretization"=>"chebyshev_pseudospectral", - "cheb_option"=>cheb_option, - "bc"=>bc, - "element_spacing_option"=>element_spacing_option)) # create the coordinate struct 'x' - # This test runs effectively in serial, so use `ignore_MPI=true` to avoid - # errors due to communicators not being fully set up. - x, spectral = define_coordinate(input, "vperp"; ignore_MPI=true) + # This test runs effectively in serial, so implicitly uses + # `ignore_MPI=true` to avoid errors due to communicators not being fully + # set up. + x, spectral = define_test_coordinate("vperp"; ngrid=ngrid, + nelement=nelement, L=L, + discretization="chebyshev_pseudospectral", + cheb_option=cheb_option, bc=bc, + element_spacing_option=element_spacing_option, + collision_operator_dim=false) f = @. exp(-x.grid^2) expected_d2f = @. 4.0*(x.grid^2 - 1.0)*exp(-x.grid^2) @@ -1463,19 +1424,17 @@ function runtests() # define inputs needed for the test L = 6.0 bc = "periodic" - # create the 'input' struct containing input info needed to create a - # coordinate - nelement_local = nelement element_spacing_option = "uniform" - input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, "nelement"=>nelement, - "L"=>L, - "discretization"=>"gausslegendre_pseudospectral", - "bc"=>bc, - "element_spacing_option"=>element_spacing_option)) # create the coordinate struct 'x' - # This test runs effectively in serial, so use `ignore_MPI=true` to avoid - # errors due to communicators not being fully set up. - x, spectral = define_coordinate(input, "coord"; ignore_MPI=true, collision_operator_dim=false) + # This test runs effectively in serial, so implicitly uses + # `ignore_MPI=true` to avoid errors due to communicators not being fully + # set up. + x, spectral = define_test_coordinate("coord"; ngrid=ngrid, + nelement=nelement, L=L, + discretization="gausslegendre_pseudospectral", + bc=bc, + element_spacing_option=element_spacing_option, + collision_operator_dim=false) offset = randn(rng) f = @. sinpi(2.0 * x.grid / L) + offset @@ -1564,22 +1523,17 @@ function runtests() # define inputs needed for the test L = 6.0 bc = "zero" - # create the 'input' struct containing input info needed to create a - # coordinate - nelement_local = nelement element_spacing_option = "uniform" - # create the coordinate struct 'x' and info for derivatives, etc. - # This test runs effectively in serial, so use `ignore_MPI=true` to avoid - # errors due to communicators not being fully set up. - input = OptionsDict("vperp" => OptionsDict("ngrid"=>ngrid, "nelement"=>nelement, - "L"=>L, - "discretization"=>"gausslegendre_pseudospectral", - "bc"=>bc, - "element_spacing_option"=>element_spacing_option)) # create the coordinate struct 'x' - # This test runs effectively in serial, so use `ignore_MPI=true` to avoid - # errors due to communicators not being fully set up. - x, spectral = define_coordinate(input, "vperp"; ignore_MPI=true, collision_operator_dim=false) + # This test runs effectively in serial, so implicitly uses + # `ignore_MPI=true` to avoid errors due to communicators not being fully + # set up. + x, spectral = define_test_coordinate("vperp"; ngrid=ngrid, + nelement=nelement, L=L, + discretization="gausslegendre_pseudospectral", + bc=bc, + element_spacing_option=element_spacing_option, + collision_operator_dim=false) f = @. exp(-x.grid^2) expected_d2f = @. 4.0*(x.grid^2 - 1.0)*exp(-x.grid^2) diff --git a/moment_kinetics/test/interpolation_tests.jl b/moment_kinetics/test/interpolation_tests.jl index c9525e770..a38506a2f 100644 --- a/moment_kinetics/test/interpolation_tests.jl +++ b/moment_kinetics/test/interpolation_tests.jl @@ -2,7 +2,7 @@ module InterpolationTests include("setup.jl") -using moment_kinetics.coordinates: define_coordinate +using moment_kinetics.coordinates: define_test_coordinate using moment_kinetics.interpolation: interpolate_to_grid_1d, interpolate_to_grid_z, interpolate_to_grid_vpa @@ -33,17 +33,15 @@ function runtests() # create the 'input' struct containing input info needed to create a coordinate nelement_local = nelement cheb_option = "FFT" - input = OptionsDict("coord" => OptionsDict("ngrid"=>ngrid, "nelement"=>nelement, - "L"=>L, - "discretization"=>discretization, - "cheb_option"=>cheb_option, - "bc"=>bc, - "element_spacing_option"=>element_spacing_option)) + input = OptionsDict("name"=>"coord", "ngrid"=>ngrid, "nelement"=>nelement, + "L"=>L, "discretization"=>discretization, + "cheb_option"=>cheb_option, "bc"=>bc, + "element_spacing_option"=>element_spacing_option) # create the coordinate struct 'z' # This test runs effectively in serial, so use `ignore_MPI=true` to avoid # errors due to communicators not being fully set up. - z, spectral = define_coordinate(input, "coord"; ignore_MPI=true, - collision_operator_dim=false) + z, spectral = define_test_coordinate(input; ignore_MPI=true, + collision_operator_dim=false) test_grid = [z for z in range(-zlim, zlim, length=ntest)] From 4df2ea640e3af2ed445a5064c576d4624b25d490 Mon Sep 17 00:00:00 2001 From: Michael Hardman <29800382+mrhardman@users.noreply.github.com> Date: Wed, 11 Sep 2024 12:33:23 +0100 Subject: [PATCH 51/87] Test and correct boundary conditions for solving 1D ODE with Laplacian operator with periodic and Dirichlet (zero) boundaries. --- moment_kinetics/src/gauss_legendre.jl | 57 ++++++---- test_scripts/GaussLobattoLegendre_test.jl | 120 +++++++++++++++++----- 2 files changed, 131 insertions(+), 46 deletions(-) diff --git a/moment_kinetics/src/gauss_legendre.jl b/moment_kinetics/src/gauss_legendre.jl index 88f5bb795..8b3953667 100644 --- a/moment_kinetics/src/gauss_legendre.jl +++ b/moment_kinetics/src/gauss_legendre.jl @@ -94,8 +94,12 @@ struct gausslegendre_info{TSparse, TLU} <: weak_discretization_info K_matrix::TSparse # global (1D) weak Laplacian derivative matrix L_matrix::TSparse - # global (1D) LU object + # global (1D) weak Laplacian derivative matrix with boundary conditions + L_matrix_with_bc::TSparse + # mass matrix global (1D) LU object mass_matrix_lu::TLU + # Laplacian global (1D) LU object + L_matrix_lu::TLU # dummy matrix for local operators Qmat::Array{mk_float,2} end @@ -113,14 +117,20 @@ function setup_gausslegendre_pseudospectral(coord; collision_operator_dim=true) mass_matrix = allocate_float(coord.n,coord.n) K_matrix = allocate_float(coord.n,coord.n) L_matrix = allocate_float(coord.n,coord.n) + L_matrix_with_bc = allocate_float(coord.n,coord.n) setup_global_weak_form_matrix!(mass_matrix, lobatto, radau, coord, "M") setup_global_weak_form_matrix!(K_matrix, lobatto, radau, coord, "K_with_BC_terms") setup_global_weak_form_matrix!(L_matrix, lobatto, radau, coord, "L_with_BC_terms") + dirichlet_bc = (coord.bc == "zero") # and further options in future + periodic_bc = (coord.bc == "periodic") + setup_global_weak_form_matrix!(L_matrix_with_bc, lobatto, radau, coord, "L", dirichlet_bc=dirichlet_bc, periodic_bc=periodic_bc) mass_matrix_lu = lu(sparse(mass_matrix)) + L_matrix_lu = lu(sparse(L_matrix_with_bc)) Qmat = allocate_float(coord.ngrid,coord.ngrid) - return gausslegendre_info(lobatto,radau,mass_matrix,sparse(S_matrix),sparse(K_matrix),sparse(L_matrix),mass_matrix_lu,Qmat) + return gausslegendre_info(lobatto,radau,mass_matrix,sparse(S_matrix),sparse(K_matrix),sparse(L_matrix),sparse(L_matrix_with_bc), + mass_matrix_lu,L_matrix_lu,Qmat) end function setup_gausslegendre_pseudospectral_lobatto(coord; collision_operator_dim=true) @@ -822,18 +832,7 @@ Currently the function is set up to assemble the elemental matrices without imposing boundary conditions on the first and final rows of the matrix by default. This means that the operators constructed from this function can only be used -for differentiation, and not solving 1D ODEs. To solve 1D ODEs -with periodic or dirichlet boundary conditions, set - -periodic_bc = true - -or - -dirichlet_bc = true - -in the function call, and create new matrices for this purpose -in the gausslegendre_info struct. - +for differentiation, and not solving 1D ODEs. This assembly function assumes that the coordinate is not distributed. To extend this function to support distributed-memory MPI, addition of off-memory matrix elements @@ -844,7 +843,22 @@ The typical use of this function is to assemble matrixes M and K in M * d2f = K * f where M is the mass matrix and K is the stiffness matrix, and we wish to -solve for d2f given f. +solve for d2f given f. To solve 1D ODEs + +K * f = b = M * d2f + +for f given boundary data on f +with periodic or dirichlet boundary conditions, set + +periodic_bc = true, b[end] = 0 + +or + +dirichlet_bc = true, b[1] = f[1] (except for cylindrical coordinates), b[end] = f[end] + +in the function call, and create new matrices for this purpose +in the gausslegendre_info struct. Currently the Laplacian matrix +is supported with boundary conditions. """ function setup_global_weak_form_matrix!(QQ_global::Array{mk_float,2}, lobatto::gausslegendre_base_info, @@ -882,14 +896,19 @@ function setup_global_weak_form_matrix!(QQ_global::Array{mk_float,2}, QQ_global[end,:] .= 0.0 QQ_global[end,end] = 1.0 end + # requires RHS vector b[1],b[end] = boundary values end if periodic_bc # Make periodic boundary condition by modifying elements of matrix for duplicate point + # add assembly contribution to lower endpoint from upper endpoint + j = coord.nelement_local + get_QQ_local!(QQ_j,j,lobatto,radau,coord,option) + QQ_global[1,end] += QQ_j[end,end] # Enforce continuity at the periodic boundary - j = nelement_local - QQ_global[imax[j],:] .= 0.0 - QQ_global[imax[j],1] = 1.0 - QQ_global[imax[j],end] = -1.0 + QQ_global[end,:] .= 0.0 + QQ_global[end,1] = 1.0 + QQ_global[end,end] = -1.0 + # requires RHS vector b[end] = 0 end return nothing diff --git a/test_scripts/GaussLobattoLegendre_test.jl b/test_scripts/GaussLobattoLegendre_test.jl index 19f14dc5f..b178ee689 100644 --- a/test_scripts/GaussLobattoLegendre_test.jl +++ b/test_scripts/GaussLobattoLegendre_test.jl @@ -1,6 +1,6 @@ export gausslegendre_test -using LinearAlgebra: mul!, cond +using LinearAlgebra: mul!, cond, ldiv! using Printf using Plots using LaTeXStrings @@ -42,26 +42,31 @@ using moment_kinetics.type_definitions: OptionsDict #nelement = 4 y_ngrid = ngrid #number of points per element y_nelement_local = nelement # number of elements per rank - y_nelement_global = y_nelement_local # total number of elements - bc = "zero" + y_nelement_global = y_nelement_local # total number of elements discretization = "gausslegendre_pseudospectral" # fd_option and adv_input not actually used so given values unimportant element_spacing_option = "uniform" # create the 'input' struct containing input info needed to create a # coordinate - for y_name in ["vpa","vperp"] + for y_name in ["vpa","vperp","z"] println("") println("$y_name test") println("") if y_name == "vperp" - y_L = L_in #physical box size in reference units - else + y_L = L_in #physical box size in reference units + bc = "zero" + elseif y_name =="vpa" y_L = 2*L_in + bc = "zero" + elseif y_name == "z" + y_L = L_in + bc = "periodic" end input = OptionsDict(y_name => OptionsDict("ngrid"=>y_ngrid, "nelement"=>y_nelement_global, "nelement_local"=>y_nelement_local, "L"=>y_L, "discretization"=>discretization, - "element_spacing_option"=>element_spacing_option)) + "element_spacing_option"=>element_spacing_option, + "bc"=>bc)) # create the coordinate struct 'x' # This test runs effectively in serial, so use `ignore_MPI=true` to avoid # errors due to communicators not being fully set up. @@ -91,11 +96,15 @@ using moment_kinetics.type_definitions: OptionsDict #print_vector(y_spectral.lobatto.D0,"local lobatto D matrix D0",y.ngrid) f_exact = Array{Float64,1}(undef,y.n) + f_num = Array{Float64,1}(undef,y.n) + f_err = Array{Float64,1}(undef,y.n) df_exact = Array{Float64,1}(undef,y.n) df_num = Array{Float64,1}(undef,y.n) df_err = Array{Float64,1}(undef,y.n) g_exact = Array{Float64,1}(undef,y.n) h_exact = Array{Float64,1}(undef,y.n) + h_num = Array{Float64,1}(undef,y.n) + h_err = Array{Float64,1}(undef,y.n) divg_exact = Array{Float64,1}(undef,y.n) divg_num = Array{Float64,1}(undef,y.n) divg_err = Array{Float64,1}(undef,y.n) @@ -105,6 +114,12 @@ using moment_kinetics.type_definitions: OptionsDict d2f_exact = Array{Float64,1}(undef,y.n) d2f_num = Array{Float64,1}(undef,y.n) d2f_err = Array{Float64,1}(undef,y.n) + fperiodic_err = Array{Float64,1}(undef,y.n) + fperiodic_num = Array{Float64,1}(undef,y.n) + fperiodic_exact = Array{Float64,1}(undef,y.n) + d2fperiodic_exact = Array{Float64,1}(undef,y.n) + d2fperiodic_num = Array{Float64,1}(undef,y.n) + d2fperiodic_err = Array{Float64,1}(undef,y.n) b = Array{Float64,1}(undef,y.n) for iy in 1:y.n f_exact[iy] = exp(-y.grid[iy]^2) @@ -119,28 +134,32 @@ using moment_kinetics.type_definitions: OptionsDict #h_exact[iy] = exp(-y.grid[iy]^3) #laph_exact[iy] = 9.0*y.grid[iy]*(y.grid[iy]^3 - 1.0)*exp(-y.grid[iy]^3) #f_exact[iy] = -2.0*y.grid[iy]*exp(-y.grid[iy]^2) - - end - if y.name == "vpa" - F_exact = sqrt(pi) - elseif y.name == "vperp" - F_exact = 1.0 + fperiodic_exact[iy] = sin(2.0*pi*y.grid[iy]/y.L) + d2fperiodic_exact[iy] = -((2.0*pi/y.L)^2)*sin(2.0*pi*y.grid[iy]/y.L) end - # do a test integration - #println(f_exact) - F_num = sum(y.wgts.*f_exact) - F_err = abs(F_num - F_exact) - #for ix in 1:ngrid - # F_num += w[ix]*df_exact[ix] - #end - println("F_err: ", F_err, " F_exact: ",F_exact, " F_num: ", F_num) - derivative!(df_num, f_exact, y, y_spectral) - @. df_err = df_num - df_exact - println("max(df_err) (interpolation): ",maximum(df_err)) - derivative!(d2f_num, df_num, y, y_spectral) - @. d2f_err = d2f_num - d2f_exact - println("max(d2f_err) (double first derivative by interpolation): ",maximum(d2f_err)) + if y.name in ["vpa","vperp"] + if y.name == "vpa" + F_exact = sqrt(pi) + elseif y.name == "vperp" + F_exact = 1.0 + end + # do a test integration + #println(f_exact) + F_num = sum(y.wgts.*f_exact) + F_err = abs(F_num - F_exact) + #for ix in 1:ngrid + # F_num += w[ix]*df_exact[ix] + #end + println("F_err: ", F_err, " F_exact: ",F_exact, " F_num: ", F_num) + + derivative!(df_num, f_exact, y, y_spectral) + @. df_err = df_num - df_exact + println("max(df_err) (interpolation): ",maximum(df_err)) + derivative!(d2f_num, df_num, y, y_spectral) + @. d2f_err = d2f_num - d2f_exact + println("max(d2f_err) (double first derivative by interpolation): ",maximum(d2f_err)) + end if y.name == "vpa" mul!(b,y_spectral.S_matrix,f_exact) mass_matrix_solve!(df_num,b,y_spectral) @@ -159,6 +178,20 @@ using moment_kinetics.type_definitions: OptionsDict outfile = "vpa_test.pdf" savefig(outfile) + # test 1D ODE solve + # form RHS vector + mul!(b,y_spectral.mass_matrix,d2f_exact) + # Dirichlet zero BCs + b[1] = 0.0 + b[end] = 0.0 + # solve ODE + ldiv!(f_num,y_spectral.L_matrix_lu,b) + @. f_err = abs(f_num - f_exact) + println("max(f_err) (weak form): ",maximum(f_err)) + plot([y.grid, y.grid], [f_num, f_exact], xlabel="vpa", label=["num" "exact"], ylabel="") + outfile = "vpa_test_ode.pdf" + savefig(outfile) + elseif y.name == "vperp" #println("condition: ",cond(y_spectral.mass_matrix)) mul!(b,y_spectral.S_matrix,g_exact) @@ -207,6 +240,39 @@ using moment_kinetics.type_definitions: OptionsDict @. laph_err = abs(laph_num - laph_exact) println("max(laph_err) (interpolation): ",maximum(laph_err)) + # test 1D ODE solve + # form RHS vector + mul!(b,y_spectral.mass_matrix,laph_exact) + # Dirichlet zero BC at upper endpoint + b[end] = 0.0 + # solve ODE + ldiv!(h_num,y_spectral.L_matrix_lu,b) + @. h_err = abs(h_num - h_exact) + println("max(h_err) (weak form): ",maximum(h_err)) + plot([y.grid, y.grid], [h_num, h_exact], xlabel="vperp", label=["num" "exact"], ylabel="") + outfile = "vperp_test_ode.pdf" + savefig(outfile) + elseif y.name == "z" + # test 1D differentiation + second_derivative!(d2fperiodic_num, fperiodic_exact, y, y_spectral) + @. d2fperiodic_err = abs(d2fperiodic_num - d2fperiodic_exact) + println("max(d2fperiodic_err) (weak form): ",maximum(d2fperiodic_err)) + + # test 1D ODE solve + # form RHS vector + mul!(b,y_spectral.mass_matrix,d2fperiodic_exact) + b[end] = 0.0 + # solve ODE + ldiv!(fperiodic_num,y_spectral.L_matrix_lu,b) + # subtract constant piece (constant offset is allowed solution) + F_num = sum(y.wgts.*fperiodic_num)/sum(y.wgts) + @. fperiodic_num -= F_num + @. fperiodic_err = abs(fperiodic_num - fperiodic_exact) + println("max(fperiodic_err) (weak form): ",maximum(fperiodic_err)) + plot([y.grid, y.grid], [fperiodic_num, fperiodic_exact], xlabel="z", label=["num" "exact"], ylabel="") + outfile = "periodic_test_ode.pdf" + savefig(outfile) + end end end From 6d50921145872cff239177e1b2e58741dadede3e Mon Sep 17 00:00:00 2001 From: Michael Hardman <29800382+mrhardman@users.noreply.github.com> Date: Wed, 11 Sep 2024 15:12:35 +0100 Subject: [PATCH 52/87] Avoid LU decomposition of singular matrix when no valid boundary conditions are supplied for a 1D ODE solve. --- moment_kinetics/src/gauss_legendre.jl | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/moment_kinetics/src/gauss_legendre.jl b/moment_kinetics/src/gauss_legendre.jl index 8b3953667..652aa1f90 100644 --- a/moment_kinetics/src/gauss_legendre.jl +++ b/moment_kinetics/src/gauss_legendre.jl @@ -120,19 +120,35 @@ function setup_gausslegendre_pseudospectral(coord; collision_operator_dim=true) L_matrix_with_bc = allocate_float(coord.n,coord.n) setup_global_weak_form_matrix!(mass_matrix, lobatto, radau, coord, "M") + mass_matrix_lu = lu(sparse(mass_matrix)) setup_global_weak_form_matrix!(K_matrix, lobatto, radau, coord, "K_with_BC_terms") setup_global_weak_form_matrix!(L_matrix, lobatto, radau, coord, "L_with_BC_terms") - dirichlet_bc = (coord.bc == "zero") # and further options in future + dirichlet_bc = (coord.bc in ["zero", "constant"]) # and further options in future periodic_bc = (coord.bc == "periodic") - setup_global_weak_form_matrix!(L_matrix_with_bc, lobatto, radau, coord, "L", dirichlet_bc=dirichlet_bc, periodic_bc=periodic_bc) - mass_matrix_lu = lu(sparse(mass_matrix)) + if dirichlet_bc || periodic_bc + setup_global_weak_form_matrix!(L_matrix_with_bc, lobatto, radau, coord, "L", dirichlet_bc=dirichlet_bc, periodic_bc=periodic_bc) + else + # Fill matrix with invertible identity matrix to avoid singular LU decomposition errors + # when no valid boundary condition supplied + identity_matrix!(L_matrix_with_bc, coord.n) + println("WARNING: L_matrix_with_bc replaced with identiy: 1D ODE solver requires boundary conditions") + end L_matrix_lu = lu(sparse(L_matrix_with_bc)) + Qmat = allocate_float(coord.ngrid,coord.ngrid) return gausslegendre_info(lobatto,radau,mass_matrix,sparse(S_matrix),sparse(K_matrix),sparse(L_matrix),sparse(L_matrix_with_bc), mass_matrix_lu,L_matrix_lu,Qmat) end +function identity_matrix!(I,n) + @. I[:,:] = 0.0 + for i in 1:n + I[i,i] = 1.0 + end + return nothing +end + function setup_gausslegendre_pseudospectral_lobatto(coord; collision_operator_dim=true) x, w = gausslobatto(coord.ngrid) Dmat = allocate_float(coord.ngrid, coord.ngrid) From 8d61d1e895210725015835a0030bf4647f991728 Mon Sep 17 00:00:00 2001 From: Lucas McConnell Date: Wed, 11 Sep 2024 15:21:08 +0100 Subject: [PATCH 53/87] Allow output of all sources as one variable (after John's update to allow create_dynamic_variable() to take in not just coords but NamedTuples to help define dimensions of an array) --- moment_kinetics/src/file_io.jl | 81 ++++++++++++++++++---------------- 1 file changed, 43 insertions(+), 38 deletions(-) diff --git a/moment_kinetics/src/file_io.jl b/moment_kinetics/src/file_io.jl index b81243b9c..614caede7 100644 --- a/moment_kinetics/src/file_io.jl +++ b/moment_kinetics/src/file_io.jl @@ -1323,13 +1323,14 @@ function define_dynamic_ion_moment_variables!(fid, n_ion_species, r::coordinate, ion_source_settings = external_source_settings.ion if any(x -> x.active, ion_source_settings) + n_sources = (name="n_ion_sources", n=length(ion_source_settings)) external_source_amplitude = create_dynamic_variable!( - dynamic, "external_source_amplitude", mk_float, z, r; + dynamic, "external_source_amplitude", mk_float, z, r, n_sources; parallel_io=parallel_io, description="Amplitude of the external source for ions", units="n_ref/c_ref^3*c_ref/L_ref") if evolve_density external_source_density_amplitude = create_dynamic_variable!( - dynamic, "external_source_density_amplitude", mk_float, z, r; + dynamic, "external_source_density_amplitude", mk_float, z, r, n_sources; parallel_io=parallel_io, description="Amplitude of the external density source for ions", units="n_ref*c_ref/L_ref") else @@ -1337,7 +1338,7 @@ function define_dynamic_ion_moment_variables!(fid, n_ion_species, r::coordinate, end if evolve_upar external_source_momentum_amplitude = create_dynamic_variable!( - dynamic, "external_source_momentum_amplitude", mk_float, z, r; + dynamic, "external_source_momentum_amplitude", mk_float, z, r, n_sources; parallel_io=parallel_io, description="Amplitude of the external momentum source for ions", units="m_ref*n_ref*c_ref*c_ref/L_ref") else @@ -1345,7 +1346,7 @@ function define_dynamic_ion_moment_variables!(fid, n_ion_species, r::coordinate, end if evolve_ppar external_source_pressure_amplitude = create_dynamic_variable!( - dynamic, "external_source_pressure_amplitude", mk_float, z, r; + dynamic, "external_source_pressure_amplitude", mk_float, z, r, n_sources; parallel_io=parallel_io, description="Amplitude of the external pressure source for ions", units="m_ref*n_ref*c_ref^2*c_ref/L_ref") else @@ -1355,7 +1356,7 @@ function define_dynamic_ion_moment_variables!(fid, n_ion_species, r::coordinate, ("density_profile_control", "density_midpoint_control"), ion_source_settings) if any(x -> x.source_type == "density_profile_control", ion_source_settings) external_source_controller_integral = create_dynamic_variable!( - dynamic, "external_source_controller_integral", mk_float, z, r; + dynamic, "external_source_controller_integral", mk_float, z, r, n_sources; parallel_io=parallel_io, description="Integral term for the PID controller of the external source for ions") else @@ -1532,20 +1533,21 @@ function define_dynamic_electron_moment_variables!(fid, r::coordinate, z::coordi electron_source_settings = external_source_settings.electron if any(x -> x.active, electron_source_settings) + n_sources = (name="n_electron_sources", n=length(electron_source_settings)) external_source_electron_amplitude = create_dynamic_variable!( - dynamic, "external_source_electron_amplitude", mk_float, z, r; + dynamic, "external_source_electron_amplitude", mk_float, z, r, n_sources; parallel_io=parallel_io, description="Amplitude of the external source for electrons", units="n_ref/c_ref^3*c_ref/L_ref") external_source_electron_density_amplitude = create_dynamic_variable!( - dynamic, "external_source_electron_density_amplitude", mk_float, z, r; + dynamic, "external_source_electron_density_amplitude", mk_float, z, r, n_sources; parallel_io=parallel_io, description="Amplitude of the external density source for electrons", units="n_ref*c_ref/L_ref") external_source_electron_momentum_amplitude = create_dynamic_variable!( - dynamic, "external_source_electron_momentum_amplitude", mk_float, z, r; + dynamic, "external_source_electron_momentum_amplitude", mk_float, z, r, n_sources; parallel_io=parallel_io, description="Amplitude of the external momentum source for electrons", units="m_ref*n_ref*c_ref*c_ref/L_ref") external_source_electron_pressure_amplitude = create_dynamic_variable!( - dynamic, "external_source_electron_pressure_amplitude", mk_float, z, r; + dynamic, "external_source_electron_pressure_amplitude", mk_float, z, r, n_sources; parallel_io=parallel_io, description="Amplitude of the external pressure source for electrons", units="m_ref*n_ref*c_ref^2*c_ref/L_ref") else @@ -1736,13 +1738,14 @@ function define_dynamic_neutral_moment_variables!(fid, n_neutral_species, r::coo neutral_source_settings = external_source_settings.neutral if n_neutral_species > 0 && any(x -> x.active, neutral_source_settings) + n_sources = (name="n_neutral_sources", n=length(neutral_source_settings)) external_source_neutral_amplitude = create_dynamic_variable!( - dynamic, "external_source_neutral_amplitude", mk_float, z, r; + dynamic, "external_source_neutral_amplitude", mk_float, z, r, n_sources; parallel_io=parallel_io, description="Amplitude of the external source for neutrals", units="n_ref/c_ref^3*c_ref/L_ref") if evolve_density external_source_neutral_density_amplitude = create_dynamic_variable!( - dynamic, "external_source_neutral_density_amplitude", mk_float, z, r; + dynamic, "external_source_neutral_density_amplitude", mk_float, z, r, n_sources; parallel_io=parallel_io, description="Amplitude of the external density source for neutrals", units="n_ref*c_ref/L_ref") else @@ -1750,7 +1753,7 @@ function define_dynamic_neutral_moment_variables!(fid, n_neutral_species, r::coo end if evolve_upar external_source_neutral_momentum_amplitude = create_dynamic_variable!( - dynamic, "external_source_neutral_momentum_amplitude", mk_float, z, r; + dynamic, "external_source_neutral_momentum_amplitude", mk_float, z, r, n_sources; parallel_io=parallel_io, description="Amplitude of the external momentum source for neutrals", units="m_ref*n_ref*c_ref*c_ref/L_ref") else @@ -1758,7 +1761,7 @@ function define_dynamic_neutral_moment_variables!(fid, n_neutral_species, r::coo end if evolve_ppar external_source_neutral_pressure_amplitude = create_dynamic_variable!( - dynamic, "external_source_neutral_pressure_amplitude", mk_float, z, r; + dynamic, "external_source_neutral_pressure_amplitude", mk_float, z, r, n_sources; parallel_io=parallel_io, description="Amplitude of the external pressure source for neutrals", units="m_ref*n_ref*c_ref^2*c_ref/L_ref") else @@ -1768,7 +1771,7 @@ function define_dynamic_neutral_moment_variables!(fid, n_neutral_species, r::coo ("density_profile_control", "density_midpoint_control"), neutral_source_settings) if any(x -> x.source_type == "density_profile_control", neutral_source_settings) external_source_neutral_controller_integral = create_dynamic_variable!( - dynamic, "external_source_neutral_controller_integral", mk_float, z, r; + dynamic, "external_source_neutral_controller_integral", mk_float, z, r, n_sources; parallel_io=parallel_io, description="Integral term for the PID controller of the external source for neutrals") else @@ -2492,34 +2495,35 @@ function write_ion_moments_data_to_binary(scratch, moments, n_ion_species, t_par parallel_io, 0, n_ion_species) end if io_moments.external_source_amplitude !== nothing + n_sources = size(moments.ion.external_source_amplitude)[3] append_to_dynamic_var(io_moments.external_source_amplitude, - moments.ion.external_source_amplitude[:, :, 1], t_idx, - parallel_io, z, r) + moments.ion.external_source_amplitude, t_idx, + parallel_io, z, r, n_sources) if moments.evolve_density append_to_dynamic_var(io_moments.external_source_density_amplitude, - moments.ion.external_source_density_amplitude[:, :, 1], - t_idx, parallel_io, z, r) + moments.ion.external_source_density_amplitude, + t_idx, parallel_io, z, r, n_sources) end if moments.evolve_upar append_to_dynamic_var(io_moments.external_source_momentum_amplitude, - moments.ion.external_source_momentum_amplitude[:, :, 1], - t_idx, parallel_io, z, r) + moments.ion.external_source_momentum_amplitude, + t_idx, parallel_io, z, r, n_sources) end if moments.evolve_ppar append_to_dynamic_var(io_moments.external_source_pressure_amplitude, - moments.ion.external_source_pressure_amplitude[:, :, 1], - t_idx, parallel_io, z, r) + moments.ion.external_source_pressure_amplitude, + t_idx, parallel_io, z, r, n_sources) end end if io_moments.external_source_controller_integral !== nothing - if size(moments.ion.external_source_controller_integral) == (1,1) + if size(moments.ion.external_source_controller_integral) == (1,1, n_sources) append_to_dynamic_var(io_moments.external_source_controller_integral, - moments.ion.external_source_controller_integral[1,1], + moments.ion.external_source_controller_integral, t_idx, parallel_io) else append_to_dynamic_var(io_moments.external_source_controller_integral, moments.ion.external_source_controller_integral, - t_idx, parallel_io, z, r) + t_idx, parallel_io, z, r, n_sources) end end if moments.evolve_density || moments.evolve_upar || moments.evolve_ppar @@ -2590,18 +2594,19 @@ function write_electron_moments_data_to_binary(scratch, moments, t_params, elect append_to_dynamic_var(io_moments.electron_thermal_speed, moments.electron.vth, t_idx, parallel_io, z, r) if io_moments.external_source_electron_amplitude !== nothing + n_sources = size(moments.electron.external_source_amplitude)[3] append_to_dynamic_var(io_moments.external_source_electron_amplitude, - moments.electron.external_source_amplitude[:, :, 1], t_idx, - parallel_io, z, r) + moments.electron.external_source_amplitude, t_idx, + parallel_io, z, r, n_sources) append_to_dynamic_var(io_moments.external_source_electron_density_amplitude, - moments.electron.external_source_density_amplitude[:, :, 1], - t_idx, parallel_io, z, r) + moments.electron.external_source_density_amplitude, + t_idx, parallel_io, z, r, n_sources) append_to_dynamic_var(io_moments.external_source_electron_momentum_amplitude, - moments.electron.external_source_momentum_amplitude[:, :, 1], - t_idx, parallel_io, z, r) + moments.electron.external_source_momentum_amplitude, + t_idx, parallel_io, z, r, n_sources) append_to_dynamic_var(io_moments.external_source_electron_pressure_amplitude, - moments.electron.external_source_pressure_amplitude[:, :, 1], - t_idx, parallel_io, z, r) + moments.electron.external_source_pressure_amplitude, + t_idx, parallel_io, z, r, n_sources) end append_to_dynamic_var(io_moments.electron_constraints_A_coefficient, moments.electron.constraints_A_coefficient, t_idx, @@ -2703,28 +2708,28 @@ function write_neutral_moments_data_to_binary(scratch, moments, n_neutral_specie t_idx, parallel_io, z, r, n_neutral_species) if io_moments.external_source_neutral_amplitude !== nothing append_to_dynamic_var(io_moments.external_source_neutral_amplitude, - moments.neutral.external_source_amplitude[:, :, 1], t_idx, + moments.neutral.external_source_amplitude, t_idx, parallel_io, z, r) if moments.evolve_density append_to_dynamic_var(io_moments.external_source_neutral_density_amplitude, - moments.neutral.external_source_density_amplitude[:, :, 1], + moments.neutral.external_source_density_amplitude, t_idx, parallel_io, z, r) end if moments.evolve_upar append_to_dynamic_var(io_moments.external_source_neutral_momentum_amplitude, - moments.neutral.external_source_momentum_amplitude[:, :, 1], + moments.neutral.external_source_momentum_amplitude, t_idx, parallel_io, z, r) end if moments.evolve_ppar append_to_dynamic_var(io_moments.external_source_neutral_pressure_amplitude, - moments.neutral.external_source_pressure_amplitude[:, :, 1], + moments.neutral.external_source_pressure_amplitude, t_idx, parallel_io, z, r) end end if io_moments.external_source_neutral_controller_integral !== nothing if size(moments.neutral.external_source_neutral_controller_integral) == (1,1) append_to_dynamic_var(io_moments.external_source_neutral_controller_integral, - moments.neutral.external_source_controller_integral[1,1], + moments.neutral.external_source_controller_integral, t_idx, parallel_io) else append_to_dynamic_var(io_moments.external_source_neutral_controller_integral, From d4dd56525edb57f18e7e7389979bd9361eab01b5 Mon Sep 17 00:00:00 2001 From: Lucas McConnell Date: Wed, 11 Sep 2024 16:23:13 +0100 Subject: [PATCH 54/87] bug fixes for plotting sources in makie_post_processing --- .../src/makie_post_processing.jl | 27 ++++++++++--------- moment_kinetics/src/load_data.jl | 14 ++++++++-- 2 files changed, 27 insertions(+), 14 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 fb5aeefa0..65a9ab301 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 @@ -40,7 +40,8 @@ using moment_kinetics.load_data: close_run_info, get_run_info_no_setup, get_vari neutral_moment_variables, all_moment_variables, ion_dfn_variables, electron_dfn_variables, neutral_dfn_variables, all_dfn_variables, ion_variables, - neutral_variables, all_variables + neutral_variables, all_variables, ion_source_variables, + neutral_source_variables, electron_source_variables using moment_kinetics.initial_conditions: vpagrid_to_dzdt using .shared_utils: calculate_and_write_frequencies using moment_kinetics.type_definitions: mk_float, mk_int @@ -233,14 +234,6 @@ function makie_post_process(run_dir::Union{String,Tuple}, # Plots from moment variables ############################# - moment_variable_list = tuple(em_variables..., ion_moment_variables...) - if has_electrons - moment_variable_list = tuple(moment_variable_list..., electron_moment_variables...) - end - if has_neutrals - moment_variable_list = tuple(moment_variable_list..., neutral_moment_variables...) - end - if any(ri !== nothing for ri ∈ run_info_moments) has_moments = true @@ -276,7 +269,7 @@ function makie_post_process(run_dir::Union{String,Tuple}, end do_steady_state_residuals = any(input_dict[v]["steady_state_residual"] - for v ∈ moment_variable_list) + for v ∈ all_moment_variables) if do_steady_state_residuals textoutput_files = Tuple(ri.run_prefix * "_residuals.txt" for ri in run_info if ri !== nothing) @@ -299,7 +292,7 @@ function makie_post_process(run_dir::Union{String,Tuple}, steady_state_residual_fig_axes = nothing end - for variable_name ∈ moment_variable_list + for variable_name ∈ all_moment_variables plots_for_variable(run_info, variable_name; plot_prefix=plot_prefix, has_rdim=has_rdim, has_zdim=has_zdim, is_1V=is_1V, steady_state_residual_fig_axes=steady_state_residual_fig_axes) @@ -1030,8 +1023,18 @@ function plots_for_variable(run_info, variable_name; plot_prefix, has_rdim=true, elseif variable_name ∈ neutral_moment_variables || variable_name ∈ neutral_dfn_variables species_indices = 1:maximum(ri.n_neutral_species for ri ∈ run_info) - else + elseif variable_name ∈ ion_moment_variables || + variable_name ∈ ion_dfn_variables species_indices = 1:maximum(ri.n_ion_species for ri ∈ run_info) + elseif variable_name in ion_source_variables + species_indices = 1:maximum(length(ri.external_source_settings.ion) for ri ∈ run_info) + elseif variable_name in electron_source_variables + species_indices = 1:maximum(length(ri.external_source_settings.electron) for ri ∈ run_info) + elseif variable_name in neutral_source_variables + species_indices = 1:maximum(length(ri.external_source_settings.neutral) for ri ∈ run_info) + else + species_indices = 1:1 + #error("variable_name=$variable_name not found in any defined group") end for is ∈ species_indices if is !== nothing diff --git a/moment_kinetics/src/load_data.jl b/moment_kinetics/src/load_data.jl index 99c260372..cf9f56883 100644 --- a/moment_kinetics/src/load_data.jl +++ b/moment_kinetics/src/load_data.jl @@ -66,10 +66,20 @@ const neutral_moment_variables = ("density_neutral", "uz_neutral", "pz_neutral", "thermal_speed_neutral", "temperature_neutral", "qz_neutral", "total_energy_neutral", "total_energy_flux_neutral") +const ion_source_variables = ("external_source_amplitude", "external_source_density_amplitude", + "external_source_momentum_amplitude", "external_source_pressure_amplitude", + "external_source_controller_integral") +const neutral_source_variables = ("external_source_neutral_amplitude", "external_source_neutral_density_amplitude", + "external_source_neutral_momentum_amplitude", "external_source_neutral_pressure_amplitude", + "external_source_neutral_controller_integral") +const electron_source_variables = ("external_source_electron_amplitude", "external_source_electron_density_amplitude", + "external_source_electron_momentum_amplitude", "external_source_electron_pressure_amplitude") const all_moment_variables = tuple(em_variables..., ion_moment_variables..., electron_moment_variables..., - neutral_moment_variables...) - + neutral_moment_variables..., + ion_source_variables..., + electron_source_variables..., + neutral_source_variables...) const ion_dfn_variables = ("f",) const electron_dfn_variables = ("f_electron",) const neutral_dfn_variables = ("f_neutral",) From 92f73f9984973759dca571905018f58d1c15746a Mon Sep 17 00:00:00 2001 From: John Omotani Date: Wed, 11 Sep 2024 18:04:47 +0100 Subject: [PATCH 55/87] Fix periodic boundary conditions for weak-form second derivative Thanks to Patrick Farrell for guidance on periodic boundary conditions in finite element codes! --- moment_kinetics/src/calculus.jl | 16 +++------------- moment_kinetics/src/gauss_legendre.jl | 25 ++++++++++++++++--------- 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/moment_kinetics/src/calculus.jl b/moment_kinetics/src/calculus.jl index 2b473a232..f1f8f7297 100644 --- a/moment_kinetics/src/calculus.jl +++ b/moment_kinetics/src/calculus.jl @@ -64,7 +64,7 @@ function derivative!(df, f, coord, spectral::Union{null_spatial_dimension_info, return nothing end -function second_derivative!(d2f, f, coord, spectral; handle_periodic=true) +function second_derivative!(d2f, f, coord, spectral) # computes d^2f / d(coord)^2 # For spectral element methods, calculate second derivative by applying first # derivative twice, with special treatment for element boundaries @@ -131,7 +131,7 @@ function second_derivative!(d2f, f, coord, spectral; handle_periodic=true) return nothing end -function laplacian_derivative!(d2f, f, coord, spectral; handle_periodic=true) +function laplacian_derivative!(d2f, f, coord, spectral) # computes (1/coord) d / coord ( coord d f / d(coord)) for vperp coordinate # For spectral element methods, calculate second derivative by applying first # derivative twice, with special treatment for element boundaries @@ -207,23 +207,13 @@ is an input. """ function mass_matrix_solve! end -function second_derivative!(d2f, f, coord, spectral::weak_discretization_info; handle_periodic=true) +function second_derivative!(d2f, f, coord, spectral::weak_discretization_info) # obtain the RHS of numerical weak-form of the equation # g = d^2 f / d coord^2, which is # M * g = K * f, with M the mass matrix and K an appropriate stiffness matrix # by multiplying by basis functions and integrating by parts mul!(coord.scratch3, spectral.K_matrix, f) - if handle_periodic && coord.bc == "periodic" - if coord.nrank > 1 - error("second_derivative!() cannot handle periodic boundaries for a " - * "distributed coordinate") - end - - coord.scratch3[1] = 0.5 * (coord.scratch3[1] + coord.scratch3[end]) - coord.scratch3[end] = coord.scratch3[1] - end - # solve weak form matrix problem M * g = K * f to obtain g = d^2 f / d coord^2 if coord.nrank > 1 error("mass_matrix_solve!() does not support a " diff --git a/moment_kinetics/src/gauss_legendre.jl b/moment_kinetics/src/gauss_legendre.jl index 652aa1f90..ec759fc38 100644 --- a/moment_kinetics/src/gauss_legendre.jl +++ b/moment_kinetics/src/gauss_legendre.jl @@ -119,13 +119,13 @@ function setup_gausslegendre_pseudospectral(coord; collision_operator_dim=true) L_matrix = allocate_float(coord.n,coord.n) L_matrix_with_bc = allocate_float(coord.n,coord.n) - setup_global_weak_form_matrix!(mass_matrix, lobatto, radau, coord, "M") - mass_matrix_lu = lu(sparse(mass_matrix)) - setup_global_weak_form_matrix!(K_matrix, lobatto, radau, coord, "K_with_BC_terms") - setup_global_weak_form_matrix!(L_matrix, lobatto, radau, coord, "L_with_BC_terms") dirichlet_bc = (coord.bc in ["zero", "constant"]) # and further options in future periodic_bc = (coord.bc == "periodic") - if dirichlet_bc || periodic_bc + setup_global_weak_form_matrix!(mass_matrix, lobatto, radau, coord, "M"; periodic_bc=periodic_bc) + setup_global_weak_form_matrix!(K_matrix, lobatto, radau, coord, "K_with_BC_terms"; periodic_bc=periodic_bc) + setup_global_weak_form_matrix!(L_matrix, lobatto, radau, coord, "L_with_BC_terms") + mass_matrix_lu = lu(sparse(mass_matrix)) + if dirichlet_bc #|| periodic_bc setup_global_weak_form_matrix!(L_matrix_with_bc, lobatto, radau, coord, "L", dirichlet_bc=dirichlet_bc, periodic_bc=periodic_bc) else # Fill matrix with invertible identity matrix to avoid singular LU decomposition errors @@ -919,12 +919,19 @@ function setup_global_weak_form_matrix!(QQ_global::Array{mk_float,2}, # add assembly contribution to lower endpoint from upper endpoint j = coord.nelement_local get_QQ_local!(QQ_j,j,lobatto,radau,coord,option) - QQ_global[1,end] += QQ_j[end,end] + iminl = imin[j] - (coord.nelement_local > 1) + imaxl = imax[j] + QQ_global[1,iminl:imaxl] .+= QQ_j[end,:] # Enforce continuity at the periodic boundary + # All-zero row in RHS matrix sets last element of `b` vector in + # `mass_matrix.x = b` to zero QQ_global[end,:] .= 0.0 - QQ_global[end,1] = 1.0 - QQ_global[end,end] = -1.0 - # requires RHS vector b[end] = 0 + if option == "M" + # enforce periodicity `x[1] = x[end]` using the last row of the + # `mass_matrix.x = b` system. + QQ_global[end,1] = 1.0 + QQ_global[end,end] = -1.0 + end end return nothing From e9997538f790c6eabc5c7ff5e909c71d0682162d Mon Sep 17 00:00:00 2001 From: John Omotani Date: Wed, 11 Sep 2024 18:06:21 +0100 Subject: [PATCH 56/87] Include a phase in periodic test functions in calculus_tests.jl Helps to prevent special properties of test function (e.g. symmetry, or being zero on the periodic boundary - not sure what is actually relevant!) from masking errors in the implementation. --- moment_kinetics/test/calculus_tests.jl | 150 +++++++++++++------------ 1 file changed, 79 insertions(+), 71 deletions(-) diff --git a/moment_kinetics/test/calculus_tests.jl b/moment_kinetics/test/calculus_tests.jl index d6a871cba..2e74e7617 100644 --- a/moment_kinetics/test/calculus_tests.jl +++ b/moment_kinetics/test/calculus_tests.jl @@ -101,8 +101,9 @@ function runtests() # initialize f and expected df offset = randn(rng) - f = @. sinpi(2.0 * x.grid / L) + offset - expected_df = @. 2.0 * π / L * cospi(2.0 * x.grid / L) + phase = 0.42 + f = @. sinpi(2.0 * x.grid / L + phase) + offset + expected_df = @. 2.0 * π / L * cospi(2.0 * x.grid / L + phase) # differentiate f derivative!(df, f, x, spectral) @@ -149,8 +150,9 @@ function runtests() # initialize f and expected df offset = randn(rng) - f = @. sinpi(2.0 * x.grid / L) + offset - expected_df = @. 2.0 * π / L * cospi(2.0 * x.grid / L) + phase = 0.42 + f = @. sinpi(2.0 * x.grid / L + phase) + offset + expected_df = @. 2.0 * π / L * cospi(2.0 * x.grid / L + phase) for advection ∈ (-1.0, 0.0, 1.0) adv_fac = similar(f) @@ -285,13 +287,13 @@ function runtests() (1, 9, 5.e-3), (1, 10, 3.e-3), (1, 11, 1.e-4), - (1, 12, 5.e-6), + (1, 12, 1.e-5), (1, 13, 3.e-6), - (1, 14, 8.e-8), + (1, 14, 1.e-7), (1, 15, 4.e-8), - (1, 16, 8.e-10), + (1, 16, 1.e-8), (1, 17, 4.e-10), - (1, 18, 4.e-12), + (1, 18, 1.e-10), (1, 19, 2.e-12), (1, 20, 2.e-13), (1, 21, 2.e-13), @@ -311,15 +313,15 @@ function runtests() (2, 4, 2.e-1), (2, 5, 4.e-2), (2, 6, 2.e-2), - (2, 7, 4.e-4), + (2, 7, 1.e-3), (2, 8, 2.e-4), - (2, 9, 4.e-6), + (2, 9, 1.e-5), (2, 10, 2.e-6), - (2, 11, 2.e-8), + (2, 11, 1.e-7), (2, 12, 1.e-8), - (2, 13, 1.e-10), + (2, 13, 1.e-9), (2, 14, 5.e-11), - (2, 15, 4.e-13), + (2, 15, 1.e-12), (2, 16, 2.e-13), (2, 17, 2.e-13), (2, 18, 2.e-13), @@ -455,8 +457,9 @@ function runtests() x, spectral = define_coordinate(input, "coord"; ignore_MPI=true) offset = randn(rng) - f = @. sinpi(2.0 * x.grid / L) + offset - expected_df = @. 2.0 * π / L * cospi(2.0 * x.grid / L) + phase = 0.42 + f = @. sinpi(2.0 * x.grid / L + phase) + offset + expected_df = @. 2.0 * π / L * cospi(2.0 * x.grid / L + phase) # create array for the derivative df/dx df = similar(f) @@ -475,17 +478,17 @@ function runtests() (1, 5, 8.e-1), (1, 6, 2.e-1), (1, 7, 1.e-1), - (1, 8, 1.e-2), + (1, 8, 5.e-2), (1, 9, 5.e-3), (1, 10, 3.e-3), (1, 11, 1.e-4), - (1, 12, 5.e-6), + (1, 12, 3.e-5), (1, 13, 3.e-6), - (1, 14, 8.e-8), + (1, 14, 4.e-7), (1, 15, 4.e-8), - (1, 16, 8.e-10), + (1, 16, 4.e-9), (1, 17, 4.e-10), - (1, 18, 4.e-12), + (1, 18, 4.e-11), (1, 19, 2.e-12), (1, 20, 2.e-13), (1, 21, 2.e-13), @@ -503,17 +506,17 @@ function runtests() (1, 33, 2.e-13), (2, 4, 2.e-1), - (2, 5, 4.e-2), + (2, 5, 6.e-2), (2, 6, 2.e-2), - (2, 7, 4.e-4), + (2, 7, 2.e-3), (2, 8, 2.e-4), - (2, 9, 4.e-6), + (2, 9, 2.e-5), (2, 10, 2.e-6), - (2, 11, 2.e-8), + (2, 11, 1.e-7), (2, 12, 1.e-8), - (2, 13, 1.e-10), + (2, 13, 1.e-9), (2, 14, 5.e-11), - (2, 15, 4.e-13), + (2, 15, 2.e-12), (2, 16, 2.e-13), (2, 17, 2.e-13), (2, 18, 2.e-13), @@ -649,8 +652,9 @@ function runtests() x, spectral = define_coordinate(input, "coord"; ignore_MPI=true) offset = randn(rng) - f = @. sinpi(2.0 * x.grid / L) + offset - expected_df = @. 2.0 * π / L * cospi(2.0 * x.grid / L) + phase = 0.42 + f = @. sinpi(2.0 * x.grid / L + phase) + offset + expected_df = @. 2.0 * π / L * cospi(2.0 * x.grid / L + phase) # create array for the derivative df/dx df = similar(f) @@ -780,26 +784,26 @@ function runtests() (1, 9, 5.e-3), (1, 10, 3.e-3), (1, 11, 5.e-4), - (1, 12, 5.e-6), + (1, 12, 1.e-5), (1, 13, 3.e-6), - (1, 14, 8.e-8), + (1, 14, 3.e-7), (1, 15, 4.e-8), - (1, 16, 8.e-10), + (1, 16, 4.e-9), (1, 17, 8.e-10), (2, 4, 2.e-1), (2, 5, 4.e-2), (2, 6, 2.e-2), - (2, 7, 4.e-4), + (2, 7, 1.e-3), (2, 8, 2.e-4), - (2, 9, 4.e-6), + (2, 9, 1.e-5), (2, 10, 2.e-6), - (2, 11, 2.e-8), + (2, 11, 1.e-7), (2, 12, 1.e-8), - (2, 13, 1.e-10), + (2, 13, 1.e-9), (2, 14, 5.e-11), - (2, 15, 4.e-13), + (2, 15, 2.e-12), (2, 16, 2.e-13), (2, 17, 2.e-13), @@ -868,8 +872,9 @@ function runtests() x, spectral = define_coordinate(input, "coord"; ignore_MPI=true, collision_operator_dim=false) offset = randn(rng) - f = @. sinpi(2.0 * x.grid / L) + offset - expected_df = @. 2.0 * π / L * cospi(2.0 * x.grid / L) + phase = 0.42 + f = @. sinpi(2.0 * x.grid / L + phase) + offset + expected_df = @. 2.0 * π / L * cospi(2.0 * x.grid / L + phase) # create array for the derivative df/dx df = similar(f) @@ -886,31 +891,31 @@ function runtests() @testset "$nelement $ngrid" for (nelement, ngrid, rtol) ∈ ( (1, 5, 8.e-1), - (1, 6, 2.e-1), + (1, 6, 3.e-1), (1, 7, 1.e-1), - (1, 8, 1.e-2), + (1, 8, 2.e-2), (1, 9, 5.e-3), (1, 10, 3.e-3), (1, 11, 8.e-4), - (1, 12, 5.e-6), + (1, 12, 3.e-5), (1, 13, 3.e-6), - (1, 14, 8.e-8), + (1, 14, 5.e-7), (1, 15, 4.e-8), - (1, 16, 8.e-10), + (1, 16, 8.e-9), (1, 17, 8.e-10), (2, 4, 2.e-1), - (2, 5, 4.e-2), + (2, 5, 8.e-2), (2, 6, 2.e-2), - (2, 7, 4.e-4), + (2, 7, 2.e-3), (2, 8, 2.e-4), - (2, 9, 4.e-6), + (2, 9, 2.e-5), (2, 10, 2.e-6), - (2, 11, 2.e-8), + (2, 11, 2.e-7), (2, 12, 1.e-8), - (2, 13, 1.e-10), + (2, 13, 1.e-9), (2, 14, 5.e-11), - (2, 15, 4.e-13), + (2, 15, 5.e-12), (2, 16, 2.e-13), (2, 17, 2.e-13), @@ -939,7 +944,7 @@ function runtests() (4, 9, 8.e-8), (4, 10, 4.e-9), (4, 11, 5.e-10), - (4, 12, 4.e-12), + (4, 12, 1.e-11), (4, 13, 2.e-13), (4, 14, 2.e-13), (4, 15, 2.e-13), @@ -949,7 +954,7 @@ function runtests() (5, 3, 2.e-1), (5, 4, 2.e-2), (5, 5, 2.e-3), - (5, 6, 1.e-4), + (5, 6, 2.e-4), (5, 7, 1.e-5), (5, 8, 4.e-7), (5, 9, 2.e-8), @@ -981,8 +986,9 @@ function runtests() x, spectral = define_coordinate(input, "coord"; ignore_MPI=true, collision_operator_dim=false) offset = randn(rng) - f = @. sinpi(2.0 * x.grid / L) + offset - expected_df = @. 2.0 * π / L * cospi(2.0 * x.grid / L) + phase = 0.42 + f = @. sinpi(2.0 * x.grid / L + phase) + offset + expected_df = @. 2.0 * π / L * cospi(2.0 * x.grid / L + phase) # create array for the derivative df/dx df = similar(f) @@ -1106,17 +1112,17 @@ function runtests() (1, 5, 8.e-1), (1, 6, 2.e-1), (1, 7, 1.e-1), - (1, 8, 1.e-2), + (1, 8, 4.e-2), (1, 9, 5.e-3), (1, 10, 3.e-3), (1, 11, 2.e-4), - (1, 12, 5.e-6), - (1, 13, 4.e-6), - (1, 14, 1.e-7), + (1, 12, 2.e-4), + (1, 13, 8.e-6), + (1, 14, 4.e-6), (1, 15, 1.e-7), - (1, 16, 2.e-9), + (1, 16, 1.e-7), (1, 17, 1.e-9), - (1, 18, 4.e-12), + (1, 18, 1.e-9), (1, 19, 2.e-12), (1, 20, 2.e-13), (1, 21, 2.e-13), @@ -1134,15 +1140,15 @@ function runtests() (1, 33, 2.e-13), (2, 4, 2.e-1), - (2, 5, 4.e-2), + (2, 5, 8.e-2), (2, 6, 2.e-2), - (2, 7, 4.e-4), - (2, 8, 2.e-4), - (2, 9, 4.e-6), + (2, 7, 8.e-3), + (2, 8, 4.e-4), + (2, 9, 2.e-4), (2, 10, 4.e-6), - (2, 11, 4.e-8), + (2, 11, 2.e-6), (2, 12, 4.e-8), - (2, 13, 2.e-10), + (2, 13, 2.e-8), (2, 14, 2.e-10), (2, 15, 4.e-13), (2, 16, 2.e-13), @@ -1167,7 +1173,7 @@ function runtests() (3, 3, 4.e-1), (3, 4, 1.e-1), (3, 5, 2.e-2), - (3, 6, 4.e-3), + (3, 6, 8.e-3), (3, 7, 1.e-3), (3, 8, 1.e-4), (3, 9, 1.e-5), @@ -1230,7 +1236,7 @@ function runtests() (5, 3, 4.e-1), (5, 4, 4.e-2), - (5, 5, 4.e-3), + (5, 5, 8.e-3), (5, 6, 1.e-3), (5, 7, 4.e-5), (5, 8, 1.e-5), @@ -1280,8 +1286,9 @@ function runtests() x, spectral = define_coordinate(input, "coord"; ignore_MPI=true) offset = randn(rng) - f = @. sinpi(2.0 * x.grid / L) + offset - expected_d2f = @. -4.0 * π^2 / L^2 * sinpi(2.0 * x.grid / L) + phase = 0.42 + f = @. sinpi(2.0 * x.grid / L + phase) + offset + expected_d2f = @. -4.0 * π^2 / L^2 * sinpi(2.0 * x.grid / L + phase) # create array for the derivative d2f/dx2 d2f = similar(f) @@ -1478,8 +1485,9 @@ function runtests() x, spectral = define_coordinate(input, "coord"; ignore_MPI=true, collision_operator_dim=false) offset = randn(rng) - f = @. sinpi(2.0 * x.grid / L) + offset - expected_d2f = @. -4.0 * π^2 / L^2 * sinpi(2.0 * x.grid / L) + phase = 0.42 + f = @. sinpi(2.0 * x.grid / L + phase) + offset + expected_d2f = @. -4.0 * π^2 / L^2 * sinpi(2.0 * x.grid / L + phase) # create array for the derivative d2f/dx2 d2f = similar(f) From ad9af460147bb40e73e7c615dd7e21edcdc604d2 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Wed, 11 Sep 2024 21:18:36 +0100 Subject: [PATCH 57/87] Ensure second derivatives give exactly periodic results ...without even rounding errors, as these might drift and accumulate into a non-negligible error after many timesteps. --- moment_kinetics/src/calculus.jl | 21 ++++++++++++++++++++- moment_kinetics/test/calculus_tests.jl | 24 +++++++++++++++++------- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/moment_kinetics/src/calculus.jl b/moment_kinetics/src/calculus.jl index f1f8f7297..47036e077 100644 --- a/moment_kinetics/src/calculus.jl +++ b/moment_kinetics/src/calculus.jl @@ -124,7 +124,15 @@ function second_derivative!(d2f, f, coord, spectral) error("Distributed memory MPI not yet supported here") end d2f[1] -= C * coord.scratch2_2d[end,end] - d2f[end] += C * coord.scratch2_2d[1,1] + # With the first derivative from the opposite end of the grid, d2f[end] here + # should be equal to d2f[1] up to rounding errors... + @boundscheck isapprox(d2f[end] + C * coord.scratch2_2d[1,1], d2f[1]; atol=1.0e-14) + # ...but because arithmetic operations were in a different order, there may be + # rounding errors, so set the two ends exactly equal to ensure consistency for the + # rest of the code - we assume that duplicate versions of the 'same point' on + # element boundaries (due to periodic bc or distributed-MPI block boundaries) are + # exactly equal. + d2f[end] = d2f[1] else error("Unsupported bc '$(coord.bc)'") end @@ -220,6 +228,17 @@ function second_derivative!(d2f, f, coord, spectral::weak_discretization_info) * "distributed coordinate") end mass_matrix_solve!(d2f, coord.scratch3, spectral) + + if coord.bc == "periodic" + # d2f[end] here should be equal to d2f[1] up to rounding errors... + @boundscheck isapprox(d2f[end], d2f[1]; atol=1.0e-14) + # ...but in the matrix operations arithmetic operations are not necessarily in + # exactly the same order, there may be rounding errors, so set the two ends + # exactly equal to ensure consistency for the rest of the code - we assume that + # duplicate versions of the 'same point' on element boundaries (due to periodic bc + # or distributed-MPI block boundaries) are exactly equal. + d2f[end] = d2f[1] + end end function laplacian_derivative!(d2f, f, coord, spectral::weak_discretization_info) diff --git a/moment_kinetics/test/calculus_tests.jl b/moment_kinetics/test/calculus_tests.jl index 2e74e7617..b2d363f8c 100644 --- a/moment_kinetics/test/calculus_tests.jl +++ b/moment_kinetics/test/calculus_tests.jl @@ -13,7 +13,7 @@ function runtests() @testset "calculus" verbose=use_verbose begin println("calculus tests") @testset "fundamental theorem of calculus" begin - @testset "$discretization $ngrid $nelement" for + @testset "$discretization $ngrid $nelement $cheb_option" for (discretization, element_spacing_option, etol, cheb_option) ∈ (("finite_difference", "uniform", 1.0e-15, ""), ("chebyshev_pseudospectral", "uniform", 1.0e-15, "FFT"), ("chebyshev_pseudospectral", "uniform", 2.0e-15, "matrix"), ("chebyshev_pseudospectral", "sqrt", 1.0e-2, "FFT"), ("gausslegendre_pseudospectral", "uniform", 1.0e-14, "")), ngrid ∈ (5,6,7,8,9,10), nelement ∈ (1, 2, 3, 4, 5) @@ -111,6 +111,7 @@ function runtests() rtol = 1.e2 / (nelement*(ngrid-1))^4 @test isapprox(df, expected_df, rtol=rtol, atol=1.e-15, norm=maxabs_norm) + @test df[1] == df[end] end end @@ -164,6 +165,7 @@ function runtests() rtol = 1.e2 / (nelement*(ngrid-1))^order @test isapprox(df, expected_df, rtol=rtol, atol=1.e-15, norm=maxabs_norm) + df[1] == df[end] end end end @@ -278,7 +280,7 @@ function runtests() end @testset "Chebyshev pseudospectral derivatives (4 argument), periodic" verbose=false begin - @testset "$nelement $ngrid" for (nelement, ngrid, rtol) ∈ + @testset "$nelement $ngrid $cheb_option" for (nelement, ngrid, rtol) ∈ ( (1, 5, 8.e-1), (1, 6, 2.e-1), @@ -469,11 +471,12 @@ function runtests() @test isapprox(df, expected_df, rtol=rtol, atol=1.e-14, norm=maxabs_norm) + @test df[1] == df[end] end end @testset "Chebyshev pseudospectral derivatives upwinding (5 argument), periodic" verbose=false begin - @testset "$nelement $ngrid" for (nelement, ngrid, rtol) ∈ + @testset "$nelement $ngrid $cheb_option" for (nelement, ngrid, rtol) ∈ ( (1, 5, 8.e-1), (1, 6, 2.e-1), @@ -668,12 +671,14 @@ function runtests() @test isapprox(df, expected_df, rtol=rtol, atol=1.e-12, norm=maxabs_norm) + @test df[1] == df[end] end end end @testset "Chebyshev pseudospectral derivatives (4 argument), polynomials" verbose=false begin - @testset "$nelement $ngrid" for bc ∈ ("constant", "zero"), element_spacing_option ∈ ("uniform", "sqrt"), + @testset "$nelement $ngrid $bc $element_spacing_option $cheb_option" for + bc ∈ ("constant", "zero"), element_spacing_option ∈ ("uniform", "sqrt"), nelement ∈ (1:5), ngrid ∈ (3:33), cheb_option in ("FFT","matrix") # define inputs needed for the test @@ -721,7 +726,8 @@ function runtests() end @testset "Chebyshev pseudospectral derivatives upwinding (5 argument), polynomials" verbose=false begin - @testset "$nelement $ngrid" for bc ∈ ("constant", "zero"), element_spacing_option ∈ ("uniform", "sqrt"), + @testset "$nelement $ngrid $bc $element_spacing_option $cheb_option" for + bc ∈ ("constant", "zero"), element_spacing_option ∈ ("uniform", "sqrt"), nelement ∈ (1:5), ngrid ∈ (3:33), cheb_option in ("FFT","matrix") # define inputs needed for the test @@ -884,6 +890,7 @@ function runtests() @test isapprox(df, expected_df, rtol=rtol, atol=1.e-14, norm=maxabs_norm) + @test df[1] == df[end] end end @@ -1002,6 +1009,7 @@ function runtests() @test isapprox(df, expected_df, rtol=rtol, atol=1.e-12, norm=maxabs_norm) + @test df[1] == df[end] end end end @@ -1107,7 +1115,7 @@ function runtests() end @testset "Chebyshev pseudospectral second derivatives (4 argument), periodic" verbose=false begin - @testset "$nelement $ngrid" for (nelement, ngrid, rtol) ∈ + @testset "$nelement $ngrid $cheb_option" for (nelement, ngrid, rtol) ∈ ( (1, 5, 8.e-1), (1, 6, 2.e-1), @@ -1298,11 +1306,12 @@ function runtests() @test isapprox(d2f, expected_d2f, rtol=rtol, atol=1.e-10, norm=maxabs_norm) + @test d2f[1] == d2f[end] end end @testset "Chebyshev pseudospectral cylindrical laplacian derivatives (4 argument), zero" verbose=false begin - @testset "$nelement $ngrid" for (nelement, ngrid, rtol) ∈ + @testset "$nelement $ngrid $cheb_option" for (nelement, ngrid, rtol) ∈ ( (4, 7, 2.e-1), (4, 8, 2.e-1), @@ -1497,6 +1506,7 @@ function runtests() @test isapprox(d2f, expected_d2f, rtol=rtol, atol=1.e-10, norm=maxabs_norm) + @test d2f[1] == d2f[end] end end From 734ab81e800af240dcae80755bbe96f34c78c479 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Wed, 11 Sep 2024 22:40:57 +0100 Subject: [PATCH 58/87] Set L_matrix_with_bc to `nothing` when not implemented Ensures an error will be thrown if `L_matrix` is used when it has not been implemented, and removes the need for a noisy warning. --- moment_kinetics/src/gauss_legendre.jl | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/moment_kinetics/src/gauss_legendre.jl b/moment_kinetics/src/gauss_legendre.jl index ec759fc38..be035bc5e 100644 --- a/moment_kinetics/src/gauss_legendre.jl +++ b/moment_kinetics/src/gauss_legendre.jl @@ -82,7 +82,7 @@ struct gausslegendre_base_info Y31::Array{mk_float,3} end -struct gausslegendre_info{TSparse, TLU} <: weak_discretization_info +struct gausslegendre_info{TSparse, TLU, TLmat, TLmatLU} <: weak_discretization_info lobatto::gausslegendre_base_info radau::gausslegendre_base_info # global (1D) mass matrix @@ -94,12 +94,14 @@ struct gausslegendre_info{TSparse, TLU} <: weak_discretization_info K_matrix::TSparse # global (1D) weak Laplacian derivative matrix L_matrix::TSparse - # global (1D) weak Laplacian derivative matrix with boundary conditions - L_matrix_with_bc::TSparse + # global (1D) weak Laplacian derivative matrix with boundary conditions - might be + # `nothing` if boundary conditions are not supported + L_matrix_with_bc::TLmat # mass matrix global (1D) LU object mass_matrix_lu::TLU - # Laplacian global (1D) LU object - L_matrix_lu::TLU + # Laplacian global (1D) LU object - might be + # `nothing` if boundary conditions are not supported + L_matrix_lu::TLmatLU # dummy matrix for local operators Qmat::Array{mk_float,2} end @@ -117,7 +119,6 @@ function setup_gausslegendre_pseudospectral(coord; collision_operator_dim=true) mass_matrix = allocate_float(coord.n,coord.n) K_matrix = allocate_float(coord.n,coord.n) L_matrix = allocate_float(coord.n,coord.n) - L_matrix_with_bc = allocate_float(coord.n,coord.n) dirichlet_bc = (coord.bc in ["zero", "constant"]) # and further options in future periodic_bc = (coord.bc == "periodic") @@ -126,18 +127,18 @@ function setup_gausslegendre_pseudospectral(coord; collision_operator_dim=true) setup_global_weak_form_matrix!(L_matrix, lobatto, radau, coord, "L_with_BC_terms") mass_matrix_lu = lu(sparse(mass_matrix)) if dirichlet_bc #|| periodic_bc + L_matrix_with_bc = allocate_float(coord.n,coord.n) setup_global_weak_form_matrix!(L_matrix_with_bc, lobatto, radau, coord, "L", dirichlet_bc=dirichlet_bc, periodic_bc=periodic_bc) + L_matrix_with_bc = sparse(L_matrix_with_bc ) + L_matrix_lu = lu(sparse(L_matrix_with_bc)) else - # Fill matrix with invertible identity matrix to avoid singular LU decomposition errors - # when no valid boundary condition supplied - identity_matrix!(L_matrix_with_bc, coord.n) - println("WARNING: L_matrix_with_bc replaced with identiy: 1D ODE solver requires boundary conditions") + L_matrix_with_bc = nothing + L_matrix_lu = nothing end - L_matrix_lu = lu(sparse(L_matrix_with_bc)) Qmat = allocate_float(coord.ngrid,coord.ngrid) - return gausslegendre_info(lobatto,radau,mass_matrix,sparse(S_matrix),sparse(K_matrix),sparse(L_matrix),sparse(L_matrix_with_bc), + return gausslegendre_info(lobatto,radau,mass_matrix,sparse(S_matrix),sparse(K_matrix),sparse(L_matrix),L_matrix_with_bc, mass_matrix_lu,L_matrix_lu,Qmat) end From b76c05db70da13663ba8dd5e82d5fc58a1c57005 Mon Sep 17 00:00:00 2001 From: Michael Hardman <29800382+mrhardman@users.noreply.github.com> Date: Thu, 12 Sep 2024 12:51:35 +0100 Subject: [PATCH 59/87] Try to rescue periodic ODE solver in latest changes by distinguishing between periodic BC modifications required for matrices on LHS or RHS in LHS.x = RHS. The ODE solver in the script sets RHS[end] = 0.0 so second version of mass matrix is avoided. However, L_matrix_with_bc appears to be singular in some examples, suggesting a continuing problem. --- moment_kinetics/src/gauss_legendre.jl | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/moment_kinetics/src/gauss_legendre.jl b/moment_kinetics/src/gauss_legendre.jl index be035bc5e..0d056e9b7 100644 --- a/moment_kinetics/src/gauss_legendre.jl +++ b/moment_kinetics/src/gauss_legendre.jl @@ -122,13 +122,13 @@ function setup_gausslegendre_pseudospectral(coord; collision_operator_dim=true) dirichlet_bc = (coord.bc in ["zero", "constant"]) # and further options in future periodic_bc = (coord.bc == "periodic") - setup_global_weak_form_matrix!(mass_matrix, lobatto, radau, coord, "M"; periodic_bc=periodic_bc) - setup_global_weak_form_matrix!(K_matrix, lobatto, radau, coord, "K_with_BC_terms"; periodic_bc=periodic_bc) + setup_global_weak_form_matrix!(mass_matrix, lobatto, radau, coord, "M"; periodic_bc_lhs=periodic_bc) + setup_global_weak_form_matrix!(K_matrix, lobatto, radau, coord, "K_with_BC_terms"; periodic_bc_rhs=periodic_bc) setup_global_weak_form_matrix!(L_matrix, lobatto, radau, coord, "L_with_BC_terms") mass_matrix_lu = lu(sparse(mass_matrix)) - if dirichlet_bc #|| periodic_bc + if dirichlet_bc || periodic_bc L_matrix_with_bc = allocate_float(coord.n,coord.n) - setup_global_weak_form_matrix!(L_matrix_with_bc, lobatto, radau, coord, "L", dirichlet_bc=dirichlet_bc, periodic_bc=periodic_bc) + setup_global_weak_form_matrix!(L_matrix_with_bc, lobatto, radau, coord, "L", dirichlet_bc=dirichlet_bc, periodic_bc_lhs=periodic_bc) L_matrix_with_bc = sparse(L_matrix_with_bc ) L_matrix_lu = lu(sparse(L_matrix_with_bc)) else @@ -880,7 +880,7 @@ is supported with boundary conditions. function setup_global_weak_form_matrix!(QQ_global::Array{mk_float,2}, lobatto::gausslegendre_base_info, radau::gausslegendre_base_info, - coord,option; dirichlet_bc=false, periodic_bc=false) + coord,option; dirichlet_bc=false, periodic_bc_lhs=false, periodic_bc_rhs=false) QQ_j = allocate_float(coord.ngrid,coord.ngrid) ngrid = coord.ngrid @@ -915,19 +915,19 @@ function setup_global_weak_form_matrix!(QQ_global::Array{mk_float,2}, end # requires RHS vector b[1],b[end] = boundary values end - if periodic_bc + if periodic_bc_lhs || periodic_bc_rhs # Make periodic boundary condition by modifying elements of matrix for duplicate point # add assembly contribution to lower endpoint from upper endpoint j = coord.nelement_local get_QQ_local!(QQ_j,j,lobatto,radau,coord,option) - iminl = imin[j] - (coord.nelement_local > 1) + iminl = imin[j] - mk_int(coord.nelement_local > 1) imaxl = imax[j] QQ_global[1,iminl:imaxl] .+= QQ_j[end,:] # Enforce continuity at the periodic boundary # All-zero row in RHS matrix sets last element of `b` vector in # `mass_matrix.x = b` to zero QQ_global[end,:] .= 0.0 - if option == "M" + if periodic_bc_lhs # enforce periodicity `x[1] = x[end]` using the last row of the # `mass_matrix.x = b` system. QQ_global[end,1] = 1.0 From 8b286294c0b6c179fc44b6be384a0088d3269535 Mon Sep 17 00:00:00 2001 From: Michael Hardman <29800382+mrhardman@users.noreply.github.com> Date: Thu, 12 Sep 2024 15:36:33 +0100 Subject: [PATCH 60/87] Note that L_matrix_with_bc requires two boundary conditions. In the periodic case, this is one to make the system periodic, and one to fix the constant offset. This should remove the problems with a singular L matrix. --- moment_kinetics/src/gauss_legendre.jl | 4 ++++ test_scripts/GaussLobattoLegendre_test.jl | 9 +++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/moment_kinetics/src/gauss_legendre.jl b/moment_kinetics/src/gauss_legendre.jl index 0d056e9b7..13110694e 100644 --- a/moment_kinetics/src/gauss_legendre.jl +++ b/moment_kinetics/src/gauss_legendre.jl @@ -932,6 +932,10 @@ function setup_global_weak_form_matrix!(QQ_global::Array{mk_float,2}, # `mass_matrix.x = b` system. QQ_global[end,1] = 1.0 QQ_global[end,end] = -1.0 + if option == "L" # or any other derivative (ODE) matrix requiring two BC (periodicity + value at endpoint) + QQ_global[1,:] .= 0.0 + QQ_global[1,1] = 1.0 + end end end diff --git a/test_scripts/GaussLobattoLegendre_test.jl b/test_scripts/GaussLobattoLegendre_test.jl index b178ee689..74292aa1e 100644 --- a/test_scripts/GaussLobattoLegendre_test.jl +++ b/test_scripts/GaussLobattoLegendre_test.jl @@ -261,12 +261,13 @@ using moment_kinetics.type_definitions: OptionsDict # test 1D ODE solve # form RHS vector mul!(b,y_spectral.mass_matrix,d2fperiodic_exact) - b[end] = 0.0 + b[1] = 0.0 # fixes constant piece of solution + b[end] = 0.0 # makes sure periodicity is enforced # solve ODE ldiv!(fperiodic_num,y_spectral.L_matrix_lu,b) - # subtract constant piece (constant offset is allowed solution) - F_num = sum(y.wgts.*fperiodic_num)/sum(y.wgts) - @. fperiodic_num -= F_num + ## subtract constant piece (constant offset is allowed solution) + #F_num = sum(y.wgts.*fperiodic_num)/sum(y.wgts) + #@. fperiodic_num -= F_num @. fperiodic_err = abs(fperiodic_num - fperiodic_exact) println("max(fperiodic_err) (weak form): ",maximum(fperiodic_err)) plot([y.grid, y.grid], [fperiodic_num, fperiodic_exact], xlabel="z", label=["num" "exact"], ylabel="") From e8f29265a200c8cea6efa13783bac2f7387e5011 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Thu, 12 Sep 2024 20:33:15 +0100 Subject: [PATCH 61/87] Use ion_sources directly instead of `counter` to set up electron sources `counter` is not the same as `length(ion_sources)` when one or more ion source sections are found. It is simpler to directly iterate over `ion_sources`. --- moment_kinetics/src/external_sources.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/moment_kinetics/src/external_sources.jl b/moment_kinetics/src/external_sources.jl index b53e8b71e..0aaa408e9 100644 --- a/moment_kinetics/src/external_sources.jl +++ b/moment_kinetics/src/external_sources.jl @@ -358,9 +358,9 @@ function setup_external_sources!(input_dict, r, z, electron_physics) electron_sources = electron_source_data[] if electron_physics ∈ (braginskii_fluid, kinetic_electrons, kinetic_electrons_with_temperature_equation) - electron_sources = [get_settings_electrons(ion_sources[i]) for i ∈ 1:counter] + electron_sources = [get_settings_electrons(this_source) for this_source ∈ ion_sources] else - electron_sources = [get_settings_electrons(get_settings_ions(1, false)) for i ∈ 1:counter] + electron_sources = [get_settings_electrons(get_settings_ions(1, false))] end # put all neutral sources into neutral_source_data struct vector From 150d05a039761acb422b127eee8462271d2efe25 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Thu, 12 Sep 2024 21:53:08 +0100 Subject: [PATCH 62/87] Fix import of external source function in electron_kinetic_equation --- moment_kinetics/src/electron_kinetic_equation.jl | 2 +- moment_kinetics/src/external_sources.jl | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/moment_kinetics/src/electron_kinetic_equation.jl b/moment_kinetics/src/electron_kinetic_equation.jl index ce89fdc81..78772beed 100644 --- a/moment_kinetics/src/electron_kinetic_equation.jl +++ b/moment_kinetics/src/electron_kinetic_equation.jl @@ -23,7 +23,7 @@ using ..electron_fluid_equations: electron_energy_equation!, electron_energy_res using ..electron_z_advection: electron_z_advection!, update_electron_speed_z! using ..electron_vpa_advection: electron_vpa_advection!, update_electron_speed_vpa! using ..em_fields: update_phi! -using ..external_sources: external_electron_source! +using ..external_sources: total_external_electron_sources! using ..file_io: get_electron_io_info, write_electron_state, finish_electron_io using ..krook_collisions: electron_krook_collisions! using ..moment_constraints: hard_force_moment_constraints!, diff --git a/moment_kinetics/src/external_sources.jl b/moment_kinetics/src/external_sources.jl index 0aaa408e9..07474ca76 100644 --- a/moment_kinetics/src/external_sources.jl +++ b/moment_kinetics/src/external_sources.jl @@ -16,7 +16,8 @@ export setup_external_sources!, external_ion_source!, external_neutral_source!, initialize_external_source_amplitude!, initialize_external_source_controller_integral!, total_external_ion_sources!, total_external_neutral_sources!, - total_external_ion_source_controllers!, total_external_neutral_source_controllers! + total_external_ion_source_controllers!, total_external_neutral_source_controllers!, + external_electron_source!, total_external_electron_sources! using ..array_allocation: allocate_float, allocate_shared_float using ..calculus From fe922fa9df9290cd6dff7529883ed78f582e5d8e Mon Sep 17 00:00:00 2001 From: John Omotani Date: Thu, 12 Sep 2024 22:10:03 +0100 Subject: [PATCH 63/87] Fix typo in external_electron_source!() --- moment_kinetics/src/external_sources.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/moment_kinetics/src/external_sources.jl b/moment_kinetics/src/external_sources.jl index 07474ca76..444833d11 100644 --- a/moment_kinetics/src/external_sources.jl +++ b/moment_kinetics/src/external_sources.jl @@ -935,7 +935,8 @@ function total_external_electron_sources!(pdf_out, pdf_in, electron_density, ele end """ - external_electron_source!(pdf, fvec, moments, electron_source_settings, vperp, + external_electron_source!(pdf_out, pdf_in, electron_density, electron_upar, + moments, composition, electron_source, index, vperp, vpa, dt) Add external source term to the electron kinetic equation. @@ -974,7 +975,7 @@ function external_electron_source!(pdf_out, pdf_in, electron_density, electron_u end end - if electron_source_settings.source_type == "energy" + if electron_source.source_type == "energy" # Take particles out of pdf so source does not change density @loop_r_z_vperp_vpa ir iz ivperp ivpa begin pdf_out[ivpa,ivperp,iz,ir] -= dt * source_amplitude[iz,ir] * From 5ecabac4e89173f3fa76e28a9250f76e487080c8 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Thu, 12 Sep 2024 22:24:18 +0100 Subject: [PATCH 64/87] Fix output of neutral source terms --- moment_kinetics/src/file_io.jl | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/moment_kinetics/src/file_io.jl b/moment_kinetics/src/file_io.jl index 614caede7..3b02b6b7e 100644 --- a/moment_kinetics/src/file_io.jl +++ b/moment_kinetics/src/file_io.jl @@ -2707,23 +2707,24 @@ function write_neutral_moments_data_to_binary(scratch, moments, n_neutral_specie append_to_dynamic_var(io_moments.thermal_speed_neutral, moments.neutral.vth, t_idx, parallel_io, z, r, n_neutral_species) if io_moments.external_source_neutral_amplitude !== nothing + n_sources = size(moments.neutral.external_source_amplitude)[3] append_to_dynamic_var(io_moments.external_source_neutral_amplitude, moments.neutral.external_source_amplitude, t_idx, - parallel_io, z, r) + parallel_io, z, r, n_sources) if moments.evolve_density append_to_dynamic_var(io_moments.external_source_neutral_density_amplitude, moments.neutral.external_source_density_amplitude, - t_idx, parallel_io, z, r) + t_idx, parallel_io, z, r, n_sources) end if moments.evolve_upar append_to_dynamic_var(io_moments.external_source_neutral_momentum_amplitude, moments.neutral.external_source_momentum_amplitude, - t_idx, parallel_io, z, r) + t_idx, parallel_io, z, r, n_sources) end if moments.evolve_ppar append_to_dynamic_var(io_moments.external_source_neutral_pressure_amplitude, moments.neutral.external_source_pressure_amplitude, - t_idx, parallel_io, z, r) + t_idx, parallel_io, z, r, n_sources) end end if io_moments.external_source_neutral_controller_integral !== nothing From b6fac48eabdf7a5ee07f3f8e759f9d8769ad355e Mon Sep 17 00:00:00 2001 From: John Omotani Date: Thu, 12 Sep 2024 22:49:02 +0100 Subject: [PATCH 65/87] Remove distinction between periodic_bc_lhs and periodic_bc_rhs As the input can be assumed to be periodic when using periodic bc, it is not necessary to zero out the last row of the 'rhs' matrix - it is ok to use a similar form (1 0 0 ... 0 0 -1) as the last row of the 'lhs' matrix, because the two non-zero entries will cancel exactly due to the periodicity. This is convenient because it means we do not need to distinguish between 'lhs' and 'rhs' matrices - we can use the same matrix for both functions. --- moment_kinetics/src/gauss_legendre.jl | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/moment_kinetics/src/gauss_legendre.jl b/moment_kinetics/src/gauss_legendre.jl index 13110694e..93366a60c 100644 --- a/moment_kinetics/src/gauss_legendre.jl +++ b/moment_kinetics/src/gauss_legendre.jl @@ -122,13 +122,13 @@ function setup_gausslegendre_pseudospectral(coord; collision_operator_dim=true) dirichlet_bc = (coord.bc in ["zero", "constant"]) # and further options in future periodic_bc = (coord.bc == "periodic") - setup_global_weak_form_matrix!(mass_matrix, lobatto, radau, coord, "M"; periodic_bc_lhs=periodic_bc) - setup_global_weak_form_matrix!(K_matrix, lobatto, radau, coord, "K_with_BC_terms"; periodic_bc_rhs=periodic_bc) + setup_global_weak_form_matrix!(mass_matrix, lobatto, radau, coord, "M"; periodic_bc=periodic_bc) + setup_global_weak_form_matrix!(K_matrix, lobatto, radau, coord, "K_with_BC_terms"; periodic_bc=periodic_bc) setup_global_weak_form_matrix!(L_matrix, lobatto, radau, coord, "L_with_BC_terms") mass_matrix_lu = lu(sparse(mass_matrix)) if dirichlet_bc || periodic_bc L_matrix_with_bc = allocate_float(coord.n,coord.n) - setup_global_weak_form_matrix!(L_matrix_with_bc, lobatto, radau, coord, "L", dirichlet_bc=dirichlet_bc, periodic_bc_lhs=periodic_bc) + setup_global_weak_form_matrix!(L_matrix_with_bc, lobatto, radau, coord, "L", dirichlet_bc=dirichlet_bc, periodic_bc=periodic_bc) L_matrix_with_bc = sparse(L_matrix_with_bc ) L_matrix_lu = lu(sparse(L_matrix_with_bc)) else @@ -880,7 +880,7 @@ is supported with boundary conditions. function setup_global_weak_form_matrix!(QQ_global::Array{mk_float,2}, lobatto::gausslegendre_base_info, radau::gausslegendre_base_info, - coord,option; dirichlet_bc=false, periodic_bc_lhs=false, periodic_bc_rhs=false) + coord,option; dirichlet_bc=false, periodic_bc=false) QQ_j = allocate_float(coord.ngrid,coord.ngrid) ngrid = coord.ngrid @@ -915,7 +915,7 @@ function setup_global_weak_form_matrix!(QQ_global::Array{mk_float,2}, end # requires RHS vector b[1],b[end] = boundary values end - if periodic_bc_lhs || periodic_bc_rhs + if periodic_bc # Make periodic boundary condition by modifying elements of matrix for duplicate point # add assembly contribution to lower endpoint from upper endpoint j = coord.nelement_local @@ -927,15 +927,13 @@ function setup_global_weak_form_matrix!(QQ_global::Array{mk_float,2}, # All-zero row in RHS matrix sets last element of `b` vector in # `mass_matrix.x = b` to zero QQ_global[end,:] .= 0.0 - if periodic_bc_lhs - # enforce periodicity `x[1] = x[end]` using the last row of the - # `mass_matrix.x = b` system. - QQ_global[end,1] = 1.0 - QQ_global[end,end] = -1.0 - if option == "L" # or any other derivative (ODE) matrix requiring two BC (periodicity + value at endpoint) - QQ_global[1,:] .= 0.0 - QQ_global[1,1] = 1.0 - end + # enforce periodicity `x[1] = x[end]` using the last row of the + # `A.x = b` system. + QQ_global[end,1] = 1.0 + QQ_global[end,end] = -1.0 + if option == "L" # or any other derivative (ODE) matrix requiring two BC (periodicity + value at endpoint) + QQ_global[1,:] .= 0.0 + QQ_global[1,1] = 1.0 end end From acfd6188fb76c3fd5e5ac71f1c30b42b3db2d3fd Mon Sep 17 00:00:00 2001 From: John Omotani Date: Mon, 16 Sep 2024 09:44:31 +0100 Subject: [PATCH 66/87] Use explicitly defined structs for numerical dissipation parameters The explicitly defined structs for numerical dissipation parameters were removed to use `get_defaults_and_check_section!()`, but now that `get_defaults_and_check_section!()` can handle an `@kwdef struct`, it makes sense to put the structs back. --- moment_kinetics/src/moment_kinetics_input.jl | 4 +- moment_kinetics/src/numerical_dissipation.jl | 86 ++++++++++---------- 2 files changed, 45 insertions(+), 45 deletions(-) diff --git a/moment_kinetics/src/moment_kinetics_input.jl b/moment_kinetics/src/moment_kinetics_input.jl index cb6faa459..83a1cb6e1 100644 --- a/moment_kinetics/src/moment_kinetics_input.jl +++ b/moment_kinetics/src/moment_kinetics_input.jl @@ -155,6 +155,8 @@ function mk_input(input_dict=OptionsDict(); save_inputs_to_txt=false, ignore_MPI collisions = collisions_input(reactions_input, electron_fluid_collisions_input, krook_input, fkpl_input, mxwl_diff_input) + num_diss_params = setup_numerical_dissipation(input_dict) + # parameters related to the time stepping timestepping_section = set_defaults_and_check_section!( input_dict, "timestepping"; @@ -459,8 +461,6 @@ function mk_input(input_dict=OptionsDict(); save_inputs_to_txt=false, ignore_MPI external_source_settings = setup_external_sources!(input_dict, r, z, composition.electron_physics) - num_diss_params = setup_numerical_dissipation(input_dict) - geometry = init_magnetic_geometry(geometry_in,z,r) if any(geometry.dBdz .!= 0.0) && (evolve_moments.density || evolve_moments.parallel_flow || diff --git a/moment_kinetics/src/numerical_dissipation.jl b/moment_kinetics/src/numerical_dissipation.jl index 589cdce55..bb3d7afd1 100644 --- a/moment_kinetics/src/numerical_dissipation.jl +++ b/moment_kinetics/src/numerical_dissipation.jl @@ -18,6 +18,42 @@ using ..derivatives: derivative_r!, derivative_z!, second_derivative_r!, using ..input_structs using ..type_definitions: mk_float +# define individual structs for each species with their particular parameters +Base.@kwdef struct ion_num_diss_params + vpa_boundary_buffer_damping_rate::mk_float = -1.0 + vpa_boundary_buffer_diffusion_coefficient::mk_float = -1.0 + vpa_dissipation_coefficient::mk_float = -1.0 + vperp_dissipation_coefficient::mk_float = -1.0 + z_dissipation_coefficient::mk_float = -1.0 + r_dissipation_coefficient::mk_float = -1.0 + moment_dissipation_coefficient::mk_float = -1.0 + force_minimum_pdf_value::Union{Nothing,mk_float} = nothing +end + +Base.@kwdef struct electron_num_diss_params + vpa_boundary_buffer_damping_rate::mk_float = -1.0 + vpa_boundary_buffer_diffusion_coefficient::mk_float = -1.0 + vpa_dissipation_coefficient::mk_float = -1.0 + vperp_dissipation_coefficient::mk_float = -1.0 + z_dissipation_coefficient::mk_float = -1.0 + r_dissipation_coefficient::mk_float = -1.0 + moment_dissipation_coefficient::mk_float = -1.0 + force_minimum_pdf_value::Union{Nothing,mk_float} = nothing +end + +Base.@kwdef struct neutral_num_diss_params + vz_dissipation_coefficient::mk_float = -1.0 + z_dissipation_coefficient::mk_float = -1.0 + r_dissipation_coefficient::mk_float = -1.0 + moment_dissipation_coefficient::mk_float = -1.0 + force_minimum_pdf_value::Union{Nothing,mk_float} = nothing +end + +struct numerical_dissipation_parameters + ion::ion_num_diss_params + electron::electron_num_diss_params + neutral::neutral_num_diss_params +end ############################################################# ########### Numerical Dissipation Parameter setup ########### @@ -43,53 +79,17 @@ vz_dissipation_coefficient There will still be the -1.0 default parameters. """ function setup_numerical_dissipation(input_dict) - ion_settings = set_defaults_and_check_section!( - input_dict, "ion_numerical_dissipation"; - vpa_boundary_buffer_damping_rate=-1.0, - vpa_boundary_buffer_diffusion_coefficient=-1.0, - vpa_dissipation_coefficient=-1.0, - vperp_dissipation_coefficient=-1.0, - z_dissipation_coefficient=-1.0, - r_dissipation_coefficient=-1.0, - moment_dissipation_coefficient=-1.0, - force_minimum_pdf_value=-Inf, + ion_params = set_defaults_and_check_section!( + input_dict, ion_num_diss_params, "ion_numerical_dissipation" ) - ion_settings = deepcopy(ion_settings) - if ion_settings["force_minimum_pdf_value"] == -Inf - ion_settings["force_minimum_pdf_value"] = nothing - end - ion_params = Dict_to_NamedTuple(ion_settings) - electron_settings = set_defaults_and_check_section!( - input_dict, "electron_numerical_dissipation"; - vpa_boundary_buffer_damping_rate=-1.0, - vpa_boundary_buffer_diffusion_coefficient=-1.0, - vpa_dissipation_coefficient=-1.0, - vperp_dissipation_coefficient=-1.0, - z_dissipation_coefficient=-1.0, - r_dissipation_coefficient=-1.0, - moment_dissipation_coefficient=-1.0, - force_minimum_pdf_value=-Inf, + electron_params = set_defaults_and_check_section!( + input_dict, electron_num_diss_params, "electron_numerical_dissipation" ) - electron_settings = deepcopy(electron_settings) - if electron_settings["force_minimum_pdf_value"] == -Inf - electron_settings["force_minimum_pdf_value"] = nothing - end - electron_params = Dict_to_NamedTuple(electron_settings) - neutral_settings = set_defaults_and_check_section!( - input_dict, "neutral_numerical_dissipation"; - vz_dissipation_coefficient=-1.0, - z_dissipation_coefficient=-1.0, - r_dissipation_coefficient=-1.0, - moment_dissipation_coefficient=-1.0, - force_minimum_pdf_value=-Inf, + neutral_params = set_defaults_and_check_section!( + input_dict, neutral_num_diss_params, "neutral_numerical_dissipation" ) - neutral_settings = deepcopy(neutral_settings) - if neutral_settings["force_minimum_pdf_value"] == -Inf - neutral_settings["force_minimum_pdf_value"] = nothing - end - neutral_params = Dict_to_NamedTuple(neutral_settings) - return (ion=ion_params, electron=electron_params, neutral=neutral_params) + return numerical_dissipation_parameters(ion_params, electron_params, neutral_params) end """ From 580e99a3373e9559229236973302a3da9355bafb Mon Sep 17 00:00:00 2001 From: John Omotani Date: Mon, 16 Sep 2024 09:53:20 +0100 Subject: [PATCH 67/87] Improve docstring for `define_coordinate()` --- moment_kinetics/src/coordinates.jl | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/moment_kinetics/src/coordinates.jl b/moment_kinetics/src/coordinates.jl index b2c54269e..a49c52d02 100644 --- a/moment_kinetics/src/coordinates.jl +++ b/moment_kinetics/src/coordinates.jl @@ -201,10 +201,18 @@ end define_coordinate(input_dict, name; parallel_io::Bool=false, run_directory=nothing, ignore_MPI=false, collision_operator_dim::Bool=true) + define_coordinate(coord_input::NamedTuple; parallel_io::Bool=false, + run_directory=nothing, ignore_MPI=false, + collision_operator_dim::Bool=true, irank=0, nrank=1, + comm=MPI.COMM_NULL) + +Create arrays associated with a given coordinate, setup the coordinate grid, and populate +the coordinate structure containing all of this information. + +When `input_dict` is passed, any missing settings will be set with default values. -create arrays associated with a given coordinate, -setup the coordinate grid, and populate the coordinate structure -containing all of this information +When `coord_input` is passed, it should be a `NamedTuple` as generated by +[`get_coordinate_input`](@ref), which contains a field for every coordinate input option. """ function define_coordinate end From e0b7614f41082c08f6b8ac0a1839f547d60b81d2 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Mon, 16 Sep 2024 13:11:52 +0100 Subject: [PATCH 68/87] Change default for charge exchange and ionization frequencies to 0 Having constant defaults rather than ones that depend on other input parameters makes the setup easier to define, and the previous defaults were not physically meaningful anyway. --- moment_kinetics/src/moment_kinetics_input.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/moment_kinetics/src/moment_kinetics_input.jl b/moment_kinetics/src/moment_kinetics_input.jl index 83a1cb6e1..efdfe2b5e 100644 --- a/moment_kinetics/src/moment_kinetics_input.jl +++ b/moment_kinetics/src/moment_kinetics_input.jl @@ -131,9 +131,9 @@ function mk_input(input_dict=OptionsDict(); save_inputs_to_txt=false, ignore_MPI reactions_settings = set_defaults_and_check_section!( input_dict, "reactions"; - charge_exchange_frequency=2.0*sqrt(composition.ion[1].initial_temperature), + charge_exchange_frequency=0.0, electron_charge_exchange_frequency=0.0, - ionization_frequency=2.0*sqrt(composition.ion[1].initial_temperature), + ionization_frequency=0.0, electron_ionization_frequency=0.0, ionization_energy=0.0, ) From eeac89d8be3253fbb07a1a89af3421af11f208e9 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Mon, 16 Sep 2024 10:22:20 +0100 Subject: [PATCH 69/87] Use explicitly defined structs for reactions, electron_fluid_collisions --- moment_kinetics/src/input_structs.jl | 28 ++++++++++++++------ moment_kinetics/src/moment_kinetics_input.jl | 16 +++-------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/moment_kinetics/src/input_structs.jl b/moment_kinetics/src/input_structs.jl index 11bcf2054..a65a09869 100644 --- a/moment_kinetics/src/input_structs.jl +++ b/moment_kinetics/src/input_structs.jl @@ -10,7 +10,8 @@ export spatial_initial_condition_input, velocity_initial_condition_input export ion_species_parameters, neutral_species_parameters export species_composition export ion_source_data, electron_source_data, neutral_source_data -export collisions_input, krook_collisions_input, fkpl_collisions_input +export collisions_input, reactions, electron_fluid_collisions, krook_collisions_input, + fkpl_collisions_input, mxwl_diff_collisions_input export io_input export pp_input export geometry_input @@ -426,10 +427,21 @@ Base.@kwdef struct neutral_source_data # in the event that the code is running with mk_int = Int32 but the rank is set to 0::Int64 end -""" -Structs set up for the collision operators so far in use. These will each -be contained in the main collisions_input struct below, as substructs. -""" +#Structs set up for the collision operators so far in use. These will each +#be contained in the main collisions_input struct below, as substructs. + +Base.@kwdef struct reactions + charge_exchange_frequency::mk_float = 0.0 + electron_charge_exchange_frequency::mk_float = 0.0 + ionization_frequency::mk_float = 0.0 + electron_ionization_frequency::mk_float = 0.0 + ionization_energy::mk_float = 0.0 +end + +Base.@kwdef struct electron_fluid_collisions + nu_ei::mk_float = 0.0 +end + Base.@kwdef struct mxwl_diff_collisions_input use_maxwell_diffusion::Bool # different diffusion coefficients for each species, has units of @@ -489,11 +501,11 @@ end Collisions input struct to contain all the different collisions substructs and overall collision input parameters. """ -struct collisions_input{Treactions,Telectronfluid} +struct collisions_input # atomic reaction parameters - reactions::Treactions + reactions::reactions # electron fluid collision parameters - electron_fluid::Telectronfluid + electron_fluid::electron_fluid_collisions # struct of parameters for the Krook operator krook::krook_collisions_input # struct of parameters for the Fokker-Planck operator diff --git a/moment_kinetics/src/moment_kinetics_input.jl b/moment_kinetics/src/moment_kinetics_input.jl index efdfe2b5e..fff9f7f27 100644 --- a/moment_kinetics/src/moment_kinetics_input.jl +++ b/moment_kinetics/src/moment_kinetics_input.jl @@ -129,20 +129,12 @@ function mk_input(input_dict=OptionsDict(); save_inputs_to_txt=false, ignore_MPI ## set geometry_input geometry_in = setup_geometry_input(input_dict) - reactions_settings = set_defaults_and_check_section!( - input_dict, "reactions"; - charge_exchange_frequency=0.0, - electron_charge_exchange_frequency=0.0, - ionization_frequency=0.0, - electron_ionization_frequency=0.0, - ionization_energy=0.0, + reactions_input = set_defaults_and_check_section!( + input_dict, reactions ) - reactions_input = Dict_to_NamedTuple(reactions_settings) - electron_fluid_collisions_settings = set_defaults_and_check_section!( - input_dict, "electron_fluid_collisions"; - nu_ei=0.0, + electron_fluid_collisions_input = set_defaults_and_check_section!( + input_dict, electron_fluid_collisions ) - electron_fluid_collisions_input = Dict_to_NamedTuple(electron_fluid_collisions_settings) # set up krook collision inputs krook_input = setup_krook_collisions_input(input_dict) # set up Fokker-Planck collision inputs From 469c813f30d196b6a637bd740820cac276f7bd50 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Mon, 16 Sep 2024 10:31:34 +0100 Subject: [PATCH 70/87] Move manufactured solutions input to setup_manufactured_solutions() --- moment_kinetics/src/manufactured_solns.jl | 38 ++++++++++++++++++++ moment_kinetics/src/moment_kinetics_input.jl | 38 ++------------------ 2 files changed, 41 insertions(+), 35 deletions(-) diff --git a/moment_kinetics/src/manufactured_solns.jl b/moment_kinetics/src/manufactured_solns.jl index c5feaa503..d3daa22ef 100644 --- a/moment_kinetics/src/manufactured_solns.jl +++ b/moment_kinetics/src/manufactured_solns.jl @@ -8,6 +8,7 @@ export manufactured_electric_fields export manufactured_geometry using ..array_allocation: allocate_shared_float +using ..input_structs using ..looping using ..type_definitions: mk_float, mk_int @@ -27,6 +28,43 @@ function __init__() end end +function setup_manufactured_solutions(input_dict) + use_for_init_is_default = !(("manufactured_solns" ∈ keys(input_dict)) && + ("use_for_init" ∈ keys(input_dict["manufactured_solns"]))) + manufactured_solns_section = set_defaults_and_check_section!( + input_dict, "manufactured_solns"; + use_for_advance=false, + use_for_init=false, + # constant to be used to control Ez divergence in MMS tests + epsilon_offset=0.001, + # 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", + ) + if use_for_init_is_default && manufactured_solns_section["use_for_advance"] + # if manufactured_solns_section["use_for_init"] was set by default, set + # manufactured_solns_section["use_for_init"] == true + manufactured_solns_section["use_for_init"] = true + end + if manufactured_solns_section["use_for_init"] || manufactured_solns_section["use_for_advance"] + manufactured_solutions_ext = Base.get_extension(@__MODULE__, :manufactured_solns_ext) + if manufactured_solutions_ext === nothing + # If Symbolics is not installed, then the extension manufactured_solns_ext + # will not be loaded, in which case we cannot use manufactured solutions. + error("Symbolics package is not installed, so manufactured solutions are not " + * "available. Re-run machines/machine-setup.sh and activate " + * "manufactured solutions, or install Symbolics.") + end + end + if manufactured_solns_section["use_vpabar_in_mms_dfni"] + manufactured_solns_section["alpha_switch"] = 1.0 + else + manufactured_solns_section["alpha_switch"] = 0.0 + end + return Dict_to_NamedTuple(manufactured_solns_section) +end + # This function is defined here rather than in the extension, because the looping macros # break if used outside the moment_kinetics module. function manufactured_sources(manufactured_solns_input, r_coord, z_coord, vperp_coord, diff --git a/moment_kinetics/src/moment_kinetics_input.jl b/moment_kinetics/src/moment_kinetics_input.jl index fff9f7f27..5bf0d256a 100644 --- a/moment_kinetics/src/moment_kinetics_input.jl +++ b/moment_kinetics/src/moment_kinetics_input.jl @@ -18,6 +18,7 @@ using ..maxwell_diffusion: setup_mxwl_diff_collisions_input using ..fokker_planck: setup_fkpl_collisions_input using ..finite_differences: fd_check_option using ..input_structs +using ..manufactured_solns: setup_manufactured_solutions using ..numerical_dissipation: setup_numerical_dissipation using ..reference_parameters using ..geo: init_magnetic_geometry, setup_geometry_input @@ -129,6 +130,8 @@ function mk_input(input_dict=OptionsDict(); save_inputs_to_txt=false, ignore_MPI ## set geometry_input geometry_in = setup_geometry_input(input_dict) + manufactured_solns_input = setup_manufactured_solutions(input_dict) + reactions_input = set_defaults_and_check_section!( input_dict, reactions ) @@ -314,41 +317,6 @@ function mk_input(input_dict=OptionsDict(); save_inputs_to_txt=false, ignore_MPI error("maximum_dt=$(timestepping_section["maximum_dt"]) must be positive") end - use_for_init_is_default = !(("manufactured_solns" ∈ keys(input_dict)) && - ("use_for_init" ∈ keys(input_dict["manufactured_solns"]))) - manufactured_solns_section = set_defaults_and_check_section!( - input_dict, "manufactured_solns"; - use_for_advance=false, - use_for_init=false, - # constant to be used to control Ez divergence in MMS tests - epsilon_offset=0.001, - # 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", - ) - if use_for_init_is_default && manufactured_solns_section["use_for_advance"] - # if manufactured_solns_section["use_for_init"] was set by default, set - # manufactured_solns_section["use_for_init"] == true - manufactured_solns_section["use_for_init"] = true - end - if manufactured_solns_section["use_for_init"] || manufactured_solns_section["use_for_advance"] - manufactured_solutions_ext = Base.get_extension(@__MODULE__, :manufactured_solns_ext) - if manufactured_solutions_ext === nothing - # If Symbolics is not installed, then the extension manufactured_solns_ext - # will not be loaded, in which case we cannot use manufactured solutions. - error("Symbolics package is not installed, so manufactured solutions are not " - * "available. Re-run machines/machine-setup.sh and activate " - * "manufactured solutions, or install Symbolics.") - end - end - if manufactured_solns_section["use_vpabar_in_mms_dfni"] - manufactured_solns_section["alpha_switch"] = 1.0 - else - manufactured_solns_section["alpha_switch"] = 0.0 - end - manufactured_solns_input = Dict_to_NamedTuple(manufactured_solns_section) - ######################################################################### ########## end user inputs. do not modify following code! ############### ######################################################################### From 5e8db0977b3c72b9598f208b286d6489030d89ce Mon Sep 17 00:00:00 2001 From: John Omotani Date: Mon, 16 Sep 2024 10:35:36 +0100 Subject: [PATCH 71/87] Explicitly defined struct for em_fields_input --- moment_kinetics/src/input_structs.jl | 8 ++++++++ moment_kinetics/src/moment_kinetics_input.jl | 10 ++++------ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/moment_kinetics/src/input_structs.jl b/moment_kinetics/src/input_structs.jl index a65a09869..0c093b89f 100644 --- a/moment_kinetics/src/input_structs.jl +++ b/moment_kinetics/src/input_structs.jl @@ -9,6 +9,7 @@ export initial_condition_input export spatial_initial_condition_input, velocity_initial_condition_input export ion_species_parameters, neutral_species_parameters export species_composition +export em_fields_input export ion_source_data, electron_source_data, neutral_source_data export collisions_input, reactions, electron_fluid_collisions, krook_collisions_input, fkpl_collisions_input, mxwl_diff_collisions_input @@ -284,6 +285,13 @@ Base.@kwdef struct species_composition neutral::Vector{neutral_species_parameters} end +""" +Settings for electronmagenetic fields +""" +Base.@kwdef struct em_fields_input + force_Er_zero_at_wall::Bool = false +end + """ Source profile structs for ions and electrons which allows them to have any number of different sources (from wall perhaps, superposition of core sources, etc.). These diff --git a/moment_kinetics/src/moment_kinetics_input.jl b/moment_kinetics/src/moment_kinetics_input.jl index 5bf0d256a..4989b9695 100644 --- a/moment_kinetics/src/moment_kinetics_input.jl +++ b/moment_kinetics/src/moment_kinetics_input.jl @@ -130,6 +130,10 @@ function mk_input(input_dict=OptionsDict(); save_inputs_to_txt=false, ignore_MPI ## set geometry_input geometry_in = setup_geometry_input(input_dict) + em_input = set_defaults_and_check_section!( + input_dict, em_fields_input, "em_fields" + ) + manufactured_solns_input = setup_manufactured_solutions(input_dict) reactions_input = set_defaults_and_check_section!( @@ -346,12 +350,6 @@ function mk_input(input_dict=OptionsDict(); save_inputs_to_txt=false, ignore_MPI _block_synchronize() end - em_fields_settings = set_defaults_and_check_section!( - input_dict, "em_fields"; - force_Er_zero_at_wall=false, - ) - em_input = Dict_to_NamedTuple(em_fields_settings) - # Complete setup of io_settings if io_settings["parallel_io"] === nothing io_settings["parallel_io"] = io_has_parallel(Val(io_settings["binary_format"])) From 0cafc56ab808b0485f611a0a12f643993578bb34 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Mon, 16 Sep 2024 12:12:47 +0100 Subject: [PATCH 72/87] Hard-code the name for the 'stop file' The name for the 'stop file' used to be changeable in the timestepping options, but if it was set would have to be set with either an absolute path or a path relative to where `julia` is running, not relative to the output directory, so this option wasn't very helpful anyway. Now remove the option, and just hard code the name to "stop". --- moment_kinetics/src/moment_kinetics_input.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/moment_kinetics/src/moment_kinetics_input.jl b/moment_kinetics/src/moment_kinetics_input.jl index 4989b9695..b095add90 100644 --- a/moment_kinetics/src/moment_kinetics_input.jl +++ b/moment_kinetics/src/moment_kinetics_input.jl @@ -166,7 +166,6 @@ function mk_input(input_dict=OptionsDict(); save_inputs_to_txt=false, ignore_MPI nwrite_dfns=nothing, type="SSPRK4", split_operators=false, - stopfile_name=joinpath(output_dir, "stop"), steady_state_residual=false, converged_residual_value=-1.0, rtol=1.0e-5, @@ -241,7 +240,7 @@ function mk_input(input_dict=OptionsDict(); save_inputs_to_txt=false, ignore_MPI # do not want to add a value to the `input_dict`. We also add a few dummy inputs that # are not actually used for electrons. electron_timestepping_section = copy(electron_timestepping_section) - electron_timestepping_section["stopfile_name"] = timestepping_section["stopfile_name"] + electron_timestepping_section["stopfile_name"] = joinpath(output_dir, "stop") electron_timestepping_section["atol_upar"] = NaN electron_timestepping_section["steady_state_residual"] = true if !(0.0 < electron_timestepping_section["step_update_prefactor"] < 1.0) @@ -287,6 +286,7 @@ function mk_input(input_dict=OptionsDict(); save_inputs_to_txt=false, ignore_MPI # `electron_timestepping_section` into the Dict that is used to make # `timestepping_input`, so that it becomes part of `timestepping_input`. timestepping_section = copy(timestepping_section) + timestepping_section["stopfile_name"] = joinpath(output_dir, "stop") timestepping_section["electron_t_input"] = electron_timestepping_section if !(0.0 < timestepping_section["step_update_prefactor"] < 1.0) error("step_update_prefactor=$(timestepping_section["step_update_prefactor"]) must " From 0cc775129dcda2100ac1c1c5efba9f6206173353 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Mon, 16 Sep 2024 11:55:45 +0100 Subject: [PATCH 73/87] Explicitly defined struct for I/O input Also define a `setup_io_input()` function to simplify `mk_input()`. --- moment_kinetics/src/file_io.jl | 82 +++++++++++++++++--- moment_kinetics/src/moment_kinetics_input.jl | 69 ++++------------ 2 files changed, 86 insertions(+), 65 deletions(-) diff --git a/moment_kinetics/src/file_io.jl b/moment_kinetics/src/file_io.jl index 48be4f326..5ca3af970 100644 --- a/moment_kinetics/src/file_io.jl +++ b/moment_kinetics/src/file_io.jl @@ -5,6 +5,7 @@ module file_io export input_option_error export get_group export open_output_file, open_ascii_output_file +export setup_io_input export setup_file_io, finish_file_io export write_data_to_ascii @@ -19,6 +20,7 @@ using ..type_definitions: mk_float, mk_int using LibGit2 using MPI using Pkg +using UUIDs @debug_shared_array using ..communication: DebugMPISharedArray @@ -32,6 +34,23 @@ function __init__() end end +""" +Container for I/O settings +""" +Base.@kwdef struct io_input_struct + run_name::String + base_directory::String + ascii_output::Bool + binary_format::binary_format_type + parallel_io::Bool + run_id::String + output_dir::String + write_error_diagnostics::Bool + write_steady_state_diagnostics::Bool + write_electron_error_diagnostics::Bool + write_electron_steady_state_diagnostics::Bool +end + """ structure containing the various input/output streams """ @@ -56,8 +75,7 @@ struct io_moments_info{Tfile, Ttime, Tphi, Tmomi, Tmome, Tmomn, Tchodura_lower, Tchodura_upper, Texti1, Texti2, Texti3, Texti4, Texti5, Textn1, Textn2, Textn3, Textn4, Textn5, Texte1, Texte2, Texte3, Texte4, Tconstri, Tconstrn, Tconstre, Tint, Tfailcause, - Telectrontime, Telectronint, Telectronfailcause, Tnldiagnostics, - Tinput} + Telectrontime, Telectronint, Telectronfailcause, Tnldiagnostics} # file identifier for the binary file to which data is written fid::Tfile # handle for the time variable @@ -211,14 +229,14 @@ struct io_moments_info{Tfile, Ttime, Tphi, Tmomi, Tmome, Tmomn, Tchodura_lower, nl_solver_diagnostics::Tnldiagnostics # Settings for I/O - io_input::Tinput + io_input::io_input_struct end """ structure containing the data/metadata needed for binary file i/o distribution function data only """ -struct io_dfns_info{Tfile, Tfi, Tfe, Tfn, Tmoments, Tinput} +struct io_dfns_info{Tfile, Tfi, Tfe, Tfn, Tmoments} # file identifier for the binary file to which data is written fid::Tfile # handle for the ion species distribution function variable @@ -241,7 +259,7 @@ struct io_dfns_info{Tfile, Tfi, Tfe, Tfn, Tmoments, Tinput} f_neutral_start_last_timestep::Union{Tfn,Nothing} # Settings for I/O - io_input::Tinput + io_input::io_input_struct # Handles for moment variables io_moments::Tmoments @@ -252,8 +270,7 @@ structure containing the data/metadata needed for binary file i/o for electron initialization """ struct io_initial_electron_info{Tfile, Tfe, Tmom, Texte1, Texte2, Texte3, Texte4, - Tconstr, Telectrontime, Telectronint, Telectronfailcause, - Tinput} + Tconstr, Telectrontime, Telectronint, Telectronfailcause} # file identifier for the binary file to which data is written fid::Tfile time::Telectrontime @@ -313,7 +330,54 @@ struct io_initial_electron_info{Tfile, Tfe, Tmom, Texte1, Texte2, Texte3, Texte4 electron_dt_before_last_fail::Telectrontime # Settings for I/O - io_input::Tinput + io_input::io_input_struct +end + +""" +Read the settings for I/O +""" +function setup_io_input(input_dict, timestepping_section; ignore_MPI=false) + io_settings = set_defaults_and_check_section!( + input_dict, "output"; + run_name="", + base_directory="runs", + ascii_output=false, + binary_format=hdf5, + parallel_io=nothing, + ) + if io_settings["run_name"] == "" + error("When passing a Dict directly for input, it is required to set `run_name` " + * "in the `[output]` section") + end + if io_settings["parallel_io"] === nothing + io_settings["parallel_io"] = io_has_parallel(Val(io_settings["binary_format"])) + end + # Make copy of the section to avoid modifying the passed-in Dict + io_settings = copy(io_settings) + run_id = string(uuid4()) + if !ignore_MPI + # Communicate run_id to all blocks + # Need to convert run_id to a Vector{Char} for MPI + run_id_chars = [run_id...] + MPI.Bcast!(run_id_chars, 0, comm_world) + run_id = string(run_id_chars...) + end + io_settings["run_id"] = run_id + io_settings["output_dir"] = joinpath(io_settings["base_directory"], io_settings["run_name"]) + io_settings["write_error_diagnostics"] = timestepping_section["write_error_diagnostics"] + io_settings["write_steady_state_diagnostics"] = timestepping_section["write_steady_state_diagnostics"] + io_settings["write_electron_error_diagnostics"] = timestepping_section["electron_t_input"]["write_error_diagnostics"] + io_settings["write_electron_steady_state_diagnostics"] = timestepping_section["electron_t_input"]["write_steady_state_diagnostics"] + + # Create output_dir if it does not exist. + if !ignore_MPI + if global_rank[] == 0 + mkpath(io_settings["output_dir"]) + end + _block_synchronize() + end + + return io_input_struct(; (Symbol(k) => v for (k,v) ∈ io_settings)...) end """ @@ -1931,7 +1995,7 @@ function define_dynamic_dfn_variables!(fid, r, z, vperp, vpa, vzeta, vr, vz, com io_f_electron, io_f_electron_loworder, io_f_electron_start_last_timestep, io_f_neutral, io_f_neutral_loworder, io_f_neutral_start_last_timestep, - parallel_io, io_moments) + io_input, io_moments) end # For processes other than the root process of each shared-memory group... diff --git a/moment_kinetics/src/moment_kinetics_input.jl b/moment_kinetics/src/moment_kinetics_input.jl index b095add90..0e731820e 100644 --- a/moment_kinetics/src/moment_kinetics_input.jl +++ b/moment_kinetics/src/moment_kinetics_input.jl @@ -12,7 +12,8 @@ using ..array_allocation: allocate_float using ..communication using ..coordinates: define_coordinate, get_coordinate_input using ..external_sources -using ..file_io: io_has_parallel, input_option_error, open_ascii_output_file +using ..file_io: io_has_parallel, input_option_error, open_ascii_output_file, + setup_io_input using ..krook_collisions: setup_krook_collisions_input using ..maxwell_diffusion: setup_mxwl_diff_collisions_input using ..fokker_planck: setup_fkpl_collisions_input @@ -25,7 +26,6 @@ using ..geo: init_magnetic_geometry, setup_geometry_input using ..species_input: get_species_input using MPI using TOML -using UUIDs """ Read input from a TOML file @@ -94,24 +94,6 @@ function mk_input(input_dict=OptionsDict(); save_inputs_to_txt=false, ignore_MPI n_ion_species = composition.n_ion_species n_neutral_species = composition.n_neutral_species - # Start processing inputs for file I/O. This is done early because we need to work - # out what `output_dir` should be. The setup is completed later, after some other - # sections have been read. - io_settings = set_defaults_and_check_section!( - input_dict, "output"; - run_name="", - base_directory="runs", - ascii_output=false, - binary_format=hdf5, - parallel_io=nothing, - ) - if io_settings["run_name"] == "" - error("When passing a Dict directly for input, it is required to set `run_name` " - * "in the `[output]` section") - end - # this is the directory where the simulation data will be stored - output_dir = joinpath(io_settings["base_directory"], io_settings["run_name"]) - # if evolve_moments.density = true, evolve density via continuity eqn # and g = f/n via modified drift kinetic equation evolve_moments_settings = set_defaults_and_check_section!( @@ -240,7 +222,6 @@ function mk_input(input_dict=OptionsDict(); save_inputs_to_txt=false, ignore_MPI # do not want to add a value to the `input_dict`. We also add a few dummy inputs that # are not actually used for electrons. electron_timestepping_section = copy(electron_timestepping_section) - electron_timestepping_section["stopfile_name"] = joinpath(output_dir, "stop") electron_timestepping_section["atol_upar"] = NaN electron_timestepping_section["steady_state_residual"] = true if !(0.0 < electron_timestepping_section["step_update_prefactor"] < 1.0) @@ -286,7 +267,6 @@ function mk_input(input_dict=OptionsDict(); save_inputs_to_txt=false, ignore_MPI # `electron_timestepping_section` into the Dict that is used to make # `timestepping_input`, so that it becomes part of `timestepping_input`. timestepping_section = copy(timestepping_section) - timestepping_section["stopfile_name"] = joinpath(output_dir, "stop") timestepping_section["electron_t_input"] = electron_timestepping_section if !(0.0 < timestepping_section["step_update_prefactor"] < 1.0) error("step_update_prefactor=$(timestepping_section["step_update_prefactor"]) must " @@ -342,41 +322,17 @@ function mk_input(input_dict=OptionsDict(); save_inputs_to_txt=false, ignore_MPI r_coord_input.nelement_local) end - # Create output_dir if it does not exist. - if !ignore_MPI - if global_rank[] == 0 - mkpath(output_dir) - end - _block_synchronize() - end - - # Complete setup of io_settings - if io_settings["parallel_io"] === nothing - io_settings["parallel_io"] = io_has_parallel(Val(io_settings["binary_format"])) - end - # Make copy of the section to avoid modifying the passed-in Dict - io_settings = copy(io_settings) - run_id = string(uuid4()) - if !ignore_MPI - # Communicate run_id to all blocks - # Need to convert run_id to a Vector{Char} for MPI - run_id_chars = [run_id...] - MPI.Bcast!(run_id_chars, 0, comm_world) - run_id = string(run_id_chars...) - end - io_settings["run_id"] = run_id - io_settings["output_dir"] = output_dir - io_settings["write_error_diagnostics"] = timestepping_section["write_error_diagnostics"] - io_settings["write_steady_state_diagnostics"] = timestepping_section["write_steady_state_diagnostics"] - io_settings["write_electron_error_diagnostics"] = timestepping_section["electron_t_input"]["write_error_diagnostics"] - io_settings["write_electron_steady_state_diagnostics"] = timestepping_section["electron_t_input"]["write_steady_state_diagnostics"] - io_immutable = Dict_to_NamedTuple(io_settings) + io_immutable = setup_io_input(input_dict, timestepping_section; ignore_MPI=ignore_MPI) + + # this is the directory where the simulation data will be stored + timestepping_section["stopfile_name"] = joinpath(io_immutable.output_dir, "stop") + electron_timestepping_section["stopfile_name"] = joinpath(io_immutable.output_dir, "stop") # initialize z grid and write grid point locations to file if ignore_MPI run_directory = nothing else - run_directory = output_dir + run_directory = io_immutable.output_dir end z, z_spectral = define_coordinate(z_coord_input; parallel_io=io_immutable.parallel_io, run_directory=run_directory, ignore_MPI=ignore_MPI, @@ -439,15 +395,16 @@ function mk_input(input_dict=OptionsDict(); save_inputs_to_txt=false, ignore_MPI if global_rank[] == 0 && save_inputs_to_txt # Make file to log some information about inputs into. - io = open_ascii_output_file(string(output_dir,"/",io_settings["run_name"]), "input") + io = open_ascii_output_file(joinpath(io_immutable.output_dir, io_immutable.run_name), "input") else io = devnull end # check input (and initialized coordinate structs) to catch errors/unsupported options - check_input(io, output_dir, timestepping_section["nstep"], timestepping_section["dt"], r, z, - vpa, vperp, composition, species_immutable, evolve_moments, - num_diss_params, save_inputs_to_txt, collisions) + check_input(io, io_immutable.output_dir, timestepping_section["nstep"], + timestepping_section["dt"], r, z, vpa, vperp, composition, + species_immutable, evolve_moments, num_diss_params, save_inputs_to_txt, + collisions) # return immutable structs for z, vpa, species and composition all_inputs = (io_immutable, evolve_moments, timestepping_section, z, z_spectral, r, From 0458ab068da214b7de53129543f2511e4c729b98 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Mon, 16 Sep 2024 13:01:18 +0100 Subject: [PATCH 74/87] Remove outdated comment Comment said "end user inputs. do not modify following code!" but some setup functions have to come later, e.g. because they use coordinates, and users have not had to modify the `mk_input()` function to change parameters for a long time. --- moment_kinetics/src/moment_kinetics_input.jl | 4 ---- 1 file changed, 4 deletions(-) diff --git a/moment_kinetics/src/moment_kinetics_input.jl b/moment_kinetics/src/moment_kinetics_input.jl index 0e731820e..207d66aaf 100644 --- a/moment_kinetics/src/moment_kinetics_input.jl +++ b/moment_kinetics/src/moment_kinetics_input.jl @@ -301,10 +301,6 @@ function mk_input(input_dict=OptionsDict(); save_inputs_to_txt=false, ignore_MPI error("maximum_dt=$(timestepping_section["maximum_dt"]) must be positive") end - ######################################################################### - ########## end user inputs. do not modify following code! ############### - ######################################################################### - # set up distributed-memory MPI information for z and r coords # need grid and MPI information to determine these values # MRH just put dummy values now From e60c61db3867474cd0eaa71fbb441a03fbfa193b Mon Sep 17 00:00:00 2001 From: John Omotani Date: Sun, 15 Sep 2024 20:55:11 +0100 Subject: [PATCH 75/87] Set electron temperature to constant when using Boltzmann response Previously the electron temperature (and corresponding thermal speed) variables were unused, but set equal to the ion temperature, which has the potential to be confusing. --- moment_kinetics/src/initial_conditions.jl | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/moment_kinetics/src/initial_conditions.jl b/moment_kinetics/src/initial_conditions.jl index 2549e07f4..ea9fc5f92 100644 --- a/moment_kinetics/src/initial_conditions.jl +++ b/moment_kinetics/src/initial_conditions.jl @@ -281,7 +281,7 @@ function initialize_electrons!(pdf, moments, fields, geometry, composition, r, z # Not restarting, so create initial profiles # initialise the electron thermal speed profile - init_electron_vth!(moments.electron.vth, moments.ion.vth, composition.T_e, composition.me_over_mi, z.grid) + init_electron_vth!(moments.electron.vth, moments.ion.vth, composition, z.grid) begin_r_z_region() # calculate the electron temperature from the thermal speed @loop_r_z ir iz begin @@ -1063,14 +1063,18 @@ initialise the electron thermal speed profile. for now the only initialisation option for the temperature is constant in z. returns vth0 = sqrt(2*Ts/Te) """ -function init_electron_vth!(vth_e, vth_i, T_e, me_over_mi, z) +function init_electron_vth!(vth_e, vth_i, composition, z) begin_r_z_region() - # @loop_r_z ir iz begin - # vth_e[iz,ir] = sqrt(T_e) - # end - @loop_r_z ir iz begin - vth_e[iz,ir] = vth_i[iz,ir,1] / sqrt(me_over_mi) - #vth_e[iz,ir] = exp(-5*(z[iz]/z[end])^2)/sqrt(me_over_mi) + if composition.electron_physics ∈ (boltzmann_electron_response, + boltzmann_electron_response_with_simple_sheath) + @loop_r_z ir iz begin + vth_e[iz,ir] = sqrt(composition.T_e / composition.me_over_mi) + end + else + @loop_r_z ir iz begin + vth_e[iz,ir] = vth_i[iz,ir,1] / sqrt(composition.me_over_mi) + #vth_e[iz,ir] = exp(-5*(z[iz]/z[end])^2)/sqrt(composition.me_over_mi) + end end end From bfe6211e313d29cbc13911850c4185d6b41e9b26 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Sun, 15 Sep 2024 20:56:20 +0100 Subject: [PATCH 76/87] Set electron parallel flow equal to the ion one for Boltzmann response The electron parallel flow is not used when Boltzmann response is used, but most sensible thing is probably to set zero current. This version assumes a single ion species, and sets the electron parallel flow equal to the parallel flow of ion species 1. --- moment_kinetics/src/electron_fluid_equations.jl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/moment_kinetics/src/electron_fluid_equations.jl b/moment_kinetics/src/electron_fluid_equations.jl index 1ddc44046..1b92038c5 100644 --- a/moment_kinetics/src/electron_fluid_equations.jl +++ b/moment_kinetics/src/electron_fluid_equations.jl @@ -111,6 +111,11 @@ function calculate_electron_upar_from_charge_conservation!(upar_e, updated, dens # convert from parallel particle flux to parallel particle density upar_e[iz,ir] /= dens_e[iz,ir] end + else + begin_r_z_region() + @loop_r_z ir iz begin + upar_e[iz,ir] = upar_i[iz,ir,1] + end end updated[] = true end From afb6ba95826f6152ea5ce5a1ce479d93c49ca79e Mon Sep 17 00:00:00 2001 From: John Omotani Date: Mon, 16 Sep 2024 14:39:44 +0100 Subject: [PATCH 77/87] Skip electron moment plots for Boltzmann electron runs The electron moment plots are not helpful in Boltzmann electron runs, as they just replicate ion moments or a constant T_e, so skip those plots. --- .../makie_post_processing/src/makie_post_processing.jl | 4 ++++ 1 file changed, 4 insertions(+) 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 65a9ab301..00ccbe3fd 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 @@ -1004,6 +1004,10 @@ function plots_for_variable(run_info, variable_name; plot_prefix, has_rdim=true, all(ri.collisions.krook_collisions_option == "none" for ri ∈ run_info) # No Krook collisions active, so do not make plots. return nothing + elseif variable_name ∈ union(electron_moment_variables, electron_source_variables, electron_dfn_variables) && + all(ri.composition.electron_physics ∈ (boltzmann_electron_response, boltzmann_electron_response_with_simple_sheath) + for ri ∈ run_info) + return nothing end println("Making plots for $variable_name") From 9318084686d94dc7d058774d51487a4a5185b5bd Mon Sep 17 00:00:00 2001 From: Lucas McConnell Date: Mon, 16 Sep 2024 17:33:20 +0100 Subject: [PATCH 78/87] Add individual loop for electrons in external_sources initialisation, so that in the boltzmann case they can have a different number of sources than the ions. --- moment_kinetics/src/external_sources.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/moment_kinetics/src/external_sources.jl b/moment_kinetics/src/external_sources.jl index 444833d11..0c49c83b4 100644 --- a/moment_kinetics/src/external_sources.jl +++ b/moment_kinetics/src/external_sources.jl @@ -506,8 +506,10 @@ function initialize_external_source_amplitude!(moments, external_source_settings end end end + end - # now do same for electron sources, which (if present) are mostly mirrors of ion sources + # now do same for electron sources, which (if present) are mostly mirrors of ion sources + for index ∈ eachindex(electron_source_settings) if electron_source_settings[index].active if electron_source_settings[index].source_type == "energy" @loop_r_z ir iz begin From 29e3a9411ebd38972091aff4f842a48bc5e489c3 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Fri, 6 Sep 2024 20:19:20 +0100 Subject: [PATCH 79/87] Add some explanation of MPISharedArray type to the docs --- docs/src/developing.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/docs/src/developing.md b/docs/src/developing.md index 3ec2536de..ebe7b5f3c 100644 --- a/docs/src/developing.md +++ b/docs/src/developing.md @@ -28,6 +28,29 @@ julia> run_moment_kinetics("input.toml") It might be convenient to add `using Revise` to your `startup.jl` file (`~/julia/config/startup.jl`) so it's always loaded. +## Array types + +Most arrays in `moment_kinetics` are declared using a custom array type +`MPISharedArray`. Most of the time this type is just an alias for `Array`, and +so it needs the same template parameters (see [Julia's Array +documentation](https://docs.julialang.org/en/v1/manual/arrays/)) - the data +type and the number of dimensions, e.g. `MPISharedArray{mk_float,3}`. Although +these arrays use shared memory, Julia does not know about this. We use +`MPI.Win_allocate_shared()` to allocate the shared memory, then wrap it in an +`Array` in [`moment_kinetics.communication.allocate_shared`](@ref). + +The reason for using the alias, is that when the shared-memory debugging mode +is activated, we instead create arrays using a type `DebugMPISharedArray`, +which allows us to track some debugging information along with the array, see +[Shared memory debugging](@ref), and make `MPISharedArray` an alias for +`DebugMPISharedArray` instead. The reason for the alias is that if we declared +our structs with just `Array` type, then when debugging is activated we would +not be able to store `DebugMPISharedArray` instances in those structs, and if +we declared the structs with `AbstractArray`, they would not be concretely +typed, which could impact performance by creating code that is not 'type +stable' (i.e. all concrete types are known at compile time). + + ## Parallelization The code is parallelized at the moment using MPI and shared-memory arrays. Arrays representing the pdf, moments, etc. are shared between all processes. Using shared memory means, for example, we can take derivatives along one dimension while parallelising the other for any dimension without having to communicate to re-distribute the arrays. Using shared memory instead of (in future as well as) distributed memory parallelism has the advantage that it is easier to split up the points within each element between processors, giving a finer-grained parallelism which should let the code use larger numbers of processors efficiently. From f5949f8cfc3f3eb90d93c3c38faeb9f1b7992090 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Sat, 7 Sep 2024 12:03:37 +0100 Subject: [PATCH 80/87] Docstring for MPISharedArray --- docs/src/developing.md | 5 +++-- moment_kinetics/src/communication.jl | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/src/developing.md b/docs/src/developing.md index ebe7b5f3c..1ce3064f0 100644 --- a/docs/src/developing.md +++ b/docs/src/developing.md @@ -31,8 +31,9 @@ It might be convenient to add `using Revise` to your `startup.jl` file (`~/julia ## Array types Most arrays in `moment_kinetics` are declared using a custom array type -`MPISharedArray`. Most of the time this type is just an alias for `Array`, and -so it needs the same template parameters (see [Julia's Array +[`moment_kinetics.communication.MPISharedArray`](@ref). Most of the time this +type is just an alias for `Array`, and so it needs the same template parameters +(see [Julia's Array documentation](https://docs.julialang.org/en/v1/manual/arrays/)) - the data type and the number of dimensions, e.g. `MPISharedArray{mk_float,3}`. Although these arrays use shared memory, Julia does not know about this. We use diff --git a/moment_kinetics/src/communication.jl b/moment_kinetics/src/communication.jl index f8fa46fff..394446a4a 100644 --- a/moment_kinetics/src/communication.jl +++ b/moment_kinetics/src/communication.jl @@ -544,6 +544,9 @@ end end """ +Type used to declare a shared-memory array. When debugging is not active `MPISharedArray` +is just an alias for `Array`, but when `@debug_shared_array` is activated, it is instead +defined as an alias for `DebugMPISharedArray`. """ const MPISharedArray = @debug_shared_array_ifelse(DebugMPISharedArray, Array) From 5b036b82ff3babfa79639fd066dd4d90a0b6ff2b Mon Sep 17 00:00:00 2001 From: John Omotani Date: Mon, 16 Sep 2024 21:52:31 +0100 Subject: [PATCH 81/87] When we catch an exception, print it to stderr before calling MPI.Abort Previously, we were printing to stdout, but this makes it more likely for the error message and stack trace to get lost, e.g. when `quietoutput()` is used in the tests. --- moment_kinetics/src/moment_kinetics.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/moment_kinetics/src/moment_kinetics.jl b/moment_kinetics/src/moment_kinetics.jl index 4c57e6ed8..2fe755af2 100644 --- a/moment_kinetics/src/moment_kinetics.jl +++ b/moment_kinetics/src/moment_kinetics.jl @@ -148,8 +148,8 @@ function run_moment_kinetics(to::Union{TimerOutput,Nothing}, input_dict=Dict(); # Stop code from hanging when running on multiple processes if only one of them # throws an error if global_size[] > 1 - println("$(typeof(e)) on process $(global_rank[]):") - showerror(stdout, e, catch_backtrace()) + println(stderr, "$(typeof(e)) on process $(global_rank[]):") + showerror(stderr, e, catch_backtrace()) flush(stdout) flush(stderr) MPI.Abort(comm_world, 1) From 3cd263e7b27f05071c67fdcbf70b3946891dabfb Mon Sep 17 00:00:00 2001 From: John Omotani Date: Tue, 17 Sep 2024 13:45:10 +0100 Subject: [PATCH 82/87] Use Julia-provided OpenMPI for CI test --- .github/workflows/debug_checks.yml | 5 +++-- .github/workflows/parallel_test.yml | 14 ++++++++------ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/.github/workflows/debug_checks.yml b/.github/workflows/debug_checks.yml index 55eef9e63..ef2883ab1 100644 --- a/.github/workflows/debug_checks.yml +++ b/.github/workflows/debug_checks.yml @@ -31,7 +31,8 @@ jobs: sed -i -e "s/_debug_level = get_options.*/_debug_level = 2/" moment_kinetics/src/debugging.jl touch Project.toml - julia --project -O3 --check-bounds=yes -e 'using Pkg; Pkg.add(["MPI", "MPIPreferences", "PackageCompiler", "Symbolics"]); using MPIPreferences; MPIPreferences.use_system_binary()' + julia --project -O3 --check-bounds=yes -e 'using Pkg; Pkg.add(["MPI", "MPIPreferences", "PackageCompiler", "Symbolics"]); using MPIPreferences; MPIPreferences.use_jll_binary("OpenMPI_jll")' + julia --project -O3 --check-bounds=no -e 'using MPI; MPI.install_mpiexecjl(; destdir=".")' julia --project -O3 --check-bounds=yes -e 'using Pkg; Pkg.develop(path="moment_kinetics/"); Pkg.precompile()' julia --project -O3 --check-bounds=yes precompile.jl --debug 2 @@ -42,4 +43,4 @@ jobs: # terrible performance when oversubscribing. ## Don't use --compiled-modules=no for now, as it currently breaks Symbolics.jl #mpiexec -np 4 --mca rmaps_base_oversubscribe 1 julia --project --check-bounds=yes --compiled-modules=no moment_kinetics/debug_test/sound_wave_tests.jl --debug 2 - mpiexec -np 4 --mca rmaps_base_oversubscribe 1 julia --project -Jmoment_kinetics.so -O3 --check-bounds=yes moment_kinetics/debug_test/runtests.jl --debug 2 + ./mpiexecjl -np 4 --mca rmaps_base_oversubscribe 1 julia --project -Jmoment_kinetics.so -O3 --check-bounds=yes moment_kinetics/debug_test/runtests.jl --debug 2 diff --git a/.github/workflows/parallel_test.yml b/.github/workflows/parallel_test.yml index b811cff94..1627f8a3d 100644 --- a/.github/workflows/parallel_test.yml +++ b/.github/workflows/parallel_test.yml @@ -24,7 +24,8 @@ jobs: - uses: julia-actions/cache@v1 - run: | touch Project.toml - julia --project -O3 --check-bounds=no -e 'import Pkg; Pkg.add(["MPI", "MPIPreferences"]); using MPIPreferences; MPIPreferences.use_system_binary()' + julia --project -O3 --check-bounds=no -e 'import Pkg; Pkg.add(["MPI", "MPIPreferences"]); using MPIPreferences; MPIPreferences.use_jll_binary("OpenMPI_jll")' + julia --project -O3 --check-bounds=no -e 'using MPI; MPI.install_mpiexecjl(; destdir=".")' julia --project -O3 --check-bounds=no -e 'import Pkg; Pkg.add(["NCDatasets", "Random", "SpecialFunctions", "Test"]); Pkg.develop(path="moment_kinetics/")' julia --project -O3 --check-bounds=no -e 'import Pkg; Pkg.precompile()' # Need to use openmpi so that the following arguments work: @@ -32,9 +33,9 @@ jobs: # than physical cores). # * `--mca mpi_yield_when_idle 1` changes a setting to prevent excessively # terrible performance when oversubscribing. - mpiexec -np 3 --mca rmaps_base_oversubscribe 1 julia --project -O3 --check-bounds=no moment_kinetics/test/runtests.jl --debug 1 --force-optional-dependencies - mpiexec -np 4 --mca rmaps_base_oversubscribe 1 julia --project -O3 --check-bounds=no moment_kinetics/test/runtests.jl --debug 1 --force-optional-dependencies - mpiexec -np 2 --mca rmaps_base_oversubscribe 1 julia --project -O3 --check-bounds=no moment_kinetics/test/runtests.jl --debug 1 --long --force-optional-dependencies + ./mpiexecjl -np 3 --mca rmaps_base_oversubscribe 1 julia --project -O3 --check-bounds=no moment_kinetics/test/runtests.jl --debug 1 --force-optional-dependencies + ./mpiexecjl -np 4 --mca rmaps_base_oversubscribe 1 julia --project -O3 --check-bounds=no moment_kinetics/test/runtests.jl --debug 1 --force-optional-dependencies + ./mpiexecjl -np 2 --mca rmaps_base_oversubscribe 1 julia --project -O3 --check-bounds=no moment_kinetics/test/runtests.jl --debug 1 --long --force-optional-dependencies # Note: MPI.jl's default implementation is mpich, which has a similar option # `--with-device=ch3:sock`, but that needs to be set when compiling mpich. shell: bash @@ -56,7 +57,8 @@ jobs: - run: | export MPILIBPATH=$(find /opt/homebrew/Cellar/open-mpi/ -name libmpi.dylib) touch Project.toml - julia --project -O3 --check-bounds=no -e "import Pkg; Pkg.add([\"MPI\", \"MPIPreferences\"]); using MPIPreferences; MPIPreferences.use_system_binary(library_names=\"$MPILIBPATH\")" + julia --project -O3 --check-bounds=no -e 'import Pkg; Pkg.add(["MPI", "MPIPreferences"]); using MPIPreferences; MPIPreferences.use_jll_binary("OpenMPI_jll")' + julia --project -O3 --check-bounds=no -e 'using MPI; MPI.install_mpiexecjl(; destdir=".")' julia --project -O3 --check-bounds=no -e 'import Pkg; Pkg.add(["NCDatasets", "Random", "SpecialFunctions", "Test"]); Pkg.develop(path="moment_kinetics/")' julia --project -O3 --check-bounds=no -e 'import Pkg; Pkg.precompile()' # Need to use openmpi so that the following arguments work: @@ -64,7 +66,7 @@ jobs: # than physical cores). # * `--mca mpi_yield_when_idle 1` changes a setting to prevent excessively # terrible performance when oversubscribing. - mpiexec -np 4 --mca rmaps_base_oversubscribe 1 julia --project -O3 --check-bounds=no moment_kinetics/test/runtests.jl --debug 1 --force-optional-dependencies + ./mpiexecjl -np 4 --mca rmaps_base_oversubscribe 1 julia --project -O3 --check-bounds=no moment_kinetics/test/runtests.jl --debug 1 --force-optional-dependencies # Note: MPI.jl's default implementation is mpich, which has a similar option # `--with-device=ch3:sock`, but that needs to be set when compiling mpich. shell: bash From e7a908c1b6e3f7ecfe271ca31ccdee39cdb5fe7f Mon Sep 17 00:00:00 2001 From: John Omotani Date: Tue, 17 Sep 2024 16:10:59 +0100 Subject: [PATCH 83/87] Remove NetCDF from parallel CI tests NetCDF seems to break the parallel tests. Don't understand why. --- .github/workflows/parallel_test.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/parallel_test.yml b/.github/workflows/parallel_test.yml index 1627f8a3d..e0b1aea43 100644 --- a/.github/workflows/parallel_test.yml +++ b/.github/workflows/parallel_test.yml @@ -26,16 +26,16 @@ jobs: touch Project.toml julia --project -O3 --check-bounds=no -e 'import Pkg; Pkg.add(["MPI", "MPIPreferences"]); using MPIPreferences; MPIPreferences.use_jll_binary("OpenMPI_jll")' julia --project -O3 --check-bounds=no -e 'using MPI; MPI.install_mpiexecjl(; destdir=".")' - julia --project -O3 --check-bounds=no -e 'import Pkg; Pkg.add(["NCDatasets", "Random", "SpecialFunctions", "Test"]); Pkg.develop(path="moment_kinetics/")' + julia --project -O3 --check-bounds=no -e 'import Pkg; Pkg.add(["Random", "SpecialFunctions", "Test"]); Pkg.develop(path="moment_kinetics/")' julia --project -O3 --check-bounds=no -e 'import Pkg; Pkg.precompile()' # Need to use openmpi so that the following arguments work: # * `--mca rmaps_base_oversubscribe 1` allows oversubscription (more processes # than physical cores). # * `--mca mpi_yield_when_idle 1` changes a setting to prevent excessively # terrible performance when oversubscribing. - ./mpiexecjl -np 3 --mca rmaps_base_oversubscribe 1 julia --project -O3 --check-bounds=no moment_kinetics/test/runtests.jl --debug 1 --force-optional-dependencies - ./mpiexecjl -np 4 --mca rmaps_base_oversubscribe 1 julia --project -O3 --check-bounds=no moment_kinetics/test/runtests.jl --debug 1 --force-optional-dependencies - ./mpiexecjl -np 2 --mca rmaps_base_oversubscribe 1 julia --project -O3 --check-bounds=no moment_kinetics/test/runtests.jl --debug 1 --long --force-optional-dependencies + ./mpiexecjl -np 3 --mca rmaps_base_oversubscribe 1 julia --project -O3 --check-bounds=no moment_kinetics/test/runtests.jl --debug 1 + ./mpiexecjl -np 4 --mca rmaps_base_oversubscribe 1 julia --project -O3 --check-bounds=no moment_kinetics/test/runtests.jl --debug 1 + ./mpiexecjl -np 2 --mca rmaps_base_oversubscribe 1 julia --project -O3 --check-bounds=no moment_kinetics/test/runtests.jl --debug 1 --long # Note: MPI.jl's default implementation is mpich, which has a similar option # `--with-device=ch3:sock`, but that needs to be set when compiling mpich. shell: bash @@ -59,14 +59,14 @@ jobs: touch Project.toml julia --project -O3 --check-bounds=no -e 'import Pkg; Pkg.add(["MPI", "MPIPreferences"]); using MPIPreferences; MPIPreferences.use_jll_binary("OpenMPI_jll")' julia --project -O3 --check-bounds=no -e 'using MPI; MPI.install_mpiexecjl(; destdir=".")' - julia --project -O3 --check-bounds=no -e 'import Pkg; Pkg.add(["NCDatasets", "Random", "SpecialFunctions", "Test"]); Pkg.develop(path="moment_kinetics/")' + julia --project -O3 --check-bounds=no -e 'import Pkg; Pkg.add(["Random", "SpecialFunctions", "Test"]); Pkg.develop(path="moment_kinetics/")' julia --project -O3 --check-bounds=no -e 'import Pkg; Pkg.precompile()' # Need to use openmpi so that the following arguments work: # * `--mca rmaps_base_oversubscribe 1` allows oversubscription (more processes # than physical cores). # * `--mca mpi_yield_when_idle 1` changes a setting to prevent excessively # terrible performance when oversubscribing. - ./mpiexecjl -np 4 --mca rmaps_base_oversubscribe 1 julia --project -O3 --check-bounds=no moment_kinetics/test/runtests.jl --debug 1 --force-optional-dependencies + ./mpiexecjl -np 4 --mca rmaps_base_oversubscribe 1 julia --project -O3 --check-bounds=no moment_kinetics/test/runtests.jl --debug 1 # Note: MPI.jl's default implementation is mpich, which has a similar option # `--with-device=ch3:sock`, but that needs to be set when compiling mpich. shell: bash From 9903ca3632edd49daedf1849c792b559bfffeb98 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Tue, 17 Sep 2024 21:21:37 +0100 Subject: [PATCH 84/87] Save defaults from `@kwdef structs` in `options` When an `@kwdef struct` is passed to `set_defaults_and_check_section!()` so that the defaults are applied by the struct, also load the final values back into the `options` Dict so that they can be saved to the output file. Note that there is no null value in TOML, or in HDF5, so default values of `nothing` are not allowed, as these could not be saved. Throw a helpful error if `nothing` is found in options, also add a note in the docs about this. Some defaults in [numerical_dissipation], [timestepping], [electron_timestepping] and [output] sections had to be changed from `nothing`. --- docs/src/developing.md | 14 ++++++++++++++ moment_kinetics/src/file_io.jl | 4 ++-- moment_kinetics/src/input_structs.jl | 19 +++++++++++++++++++ moment_kinetics/src/moment_kinetics_input.jl | 16 ++++++++-------- moment_kinetics/src/numerical_dissipation.jl | 8 ++++---- 5 files changed, 47 insertions(+), 14 deletions(-) diff --git a/docs/src/developing.md b/docs/src/developing.md index 3ec2536de..a3e7ee39a 100644 --- a/docs/src/developing.md +++ b/docs/src/developing.md @@ -28,6 +28,20 @@ julia> run_moment_kinetics("input.toml") It might be convenient to add `using Revise` to your `startup.jl` file (`~/julia/config/startup.jl`) so it's always loaded. +## Input options and defaults + +The input is read from a `.toml` file. It is also written to the output HDF5 +(or NetCDF) file, after all defaults are applied, both as a TOML-formatted +String and as a tree of HDF5 variables. + +!!! warning + Neither TOML nor HDF5 have a 'null' type, so there is no convenient way to + store Julia's `nothing` when writing to TOML or HDF5. Therefore `nothing` + should not be used as a default for any input option. If the code should + use `nothing` as a default for some setting, that is fine, but must be done + after the input is read, and not stored in the `input_dict`. + + ## Parallelization The code is parallelized at the moment using MPI and shared-memory arrays. Arrays representing the pdf, moments, etc. are shared between all processes. Using shared memory means, for example, we can take derivatives along one dimension while parallelising the other for any dimension without having to communicate to re-distribute the arrays. Using shared memory instead of (in future as well as) distributed memory parallelism has the advantage that it is easier to split up the points within each element between processors, giving a finer-grained parallelism which should let the code use larger numbers of processors efficiently. diff --git a/moment_kinetics/src/file_io.jl b/moment_kinetics/src/file_io.jl index 5ca3af970..9b0fafd54 100644 --- a/moment_kinetics/src/file_io.jl +++ b/moment_kinetics/src/file_io.jl @@ -343,13 +343,13 @@ function setup_io_input(input_dict, timestepping_section; ignore_MPI=false) base_directory="runs", ascii_output=false, binary_format=hdf5, - parallel_io=nothing, + parallel_io="", ) if io_settings["run_name"] == "" error("When passing a Dict directly for input, it is required to set `run_name` " * "in the `[output]` section") end - if io_settings["parallel_io"] === nothing + if io_settings["parallel_io"] == "" io_settings["parallel_io"] = io_has_parallel(Val(io_settings["binary_format"])) end # Make copy of the section to avoid modifying the passed-in Dict diff --git a/moment_kinetics/src/input_structs.jl b/moment_kinetics/src/input_structs.jl index 0c093b89f..c4fffaaec 100644 --- a/moment_kinetics/src/input_structs.jl +++ b/moment_kinetics/src/input_structs.jl @@ -807,6 +807,15 @@ function _get_section_and_check_option_names(options, section_name, section_keys return section end +function _check_for_nothing(section, section_name) + nothing_defaults = Tuple((k,v) for (k,v) ∈ section if v === nothing) + if length(nothing_defaults) > 0 + error("`nothing` cannot be used as a default value, because it cannot be written " + * "to TOML or HDF5. In section [$section_name], found " + * "$(join(("$k=$v" for (k,v) ∈ nothing_defaults), ", ", ", and ")).") + end +end + function _store_section_name_for_check!(options, section_name) # Record the defined section_name in a temporary, private subsection of `options`, so # we can use it to check the existing sections later. @@ -843,6 +852,8 @@ function set_defaults_and_check_section!(options::AbstractDict, section_name; section[key] = get(section, key, default_value) end + _check_for_nothing(section, section_name) + _store_section_name_for_check!(options, section_name) return section @@ -880,6 +891,14 @@ function set_defaults_and_check_section!(options::AbstractDict, struct_type::Typ # values. settings_instance = struct_type(; (Symbol(k) => v for (k,v) ∈ pairs(section))...) + # Save the settings with defaults applied back into `options` so they can be stored in + # the output file. + for k ∈ fieldnames(struct_type) + section[String(k)] = getfield(settings_instance, k) + end + + _check_for_nothing(section, section_name) + _store_section_name_for_check!(options, section_name) return settings_instance diff --git a/moment_kinetics/src/moment_kinetics_input.jl b/moment_kinetics/src/moment_kinetics_input.jl index 207d66aaf..4016c47ff 100644 --- a/moment_kinetics/src/moment_kinetics_input.jl +++ b/moment_kinetics/src/moment_kinetics_input.jl @@ -145,14 +145,14 @@ function mk_input(input_dict=OptionsDict(); save_inputs_to_txt=false, ignore_MPI dt=0.00025/sqrt(composition.ion[1].initial_temperature), CFL_prefactor=-1.0, nwrite=1, - nwrite_dfns=nothing, + nwrite_dfns=-1, type="SSPRK4", split_operators=false, steady_state_residual=false, converged_residual_value=-1.0, rtol=1.0e-5, atol=1.0e-12, - atol_upar=nothing, + atol_upar=-1.0, step_update_prefactor=0.9, max_increase_factor=1.05, max_increase_factor_near_last_fail=Inf, @@ -172,12 +172,12 @@ function mk_input(input_dict=OptionsDict(); save_inputs_to_txt=false, ignore_MPI if timestepping_section["nwrite"] > timestepping_section["nstep"] timestepping_section["nwrite"] = timestepping_section["nstep"] end - if timestepping_section["nwrite_dfns"] === nothing + if timestepping_section["nwrite_dfns"] < 0 timestepping_section["nwrite_dfns"] = timestepping_section["nstep"] elseif timestepping_section["nwrite_dfns"] > timestepping_section["nstep"] timestepping_section["nwrite_dfns"] = timestepping_section["nstep"] end - if timestepping_section["atol_upar"] === nothing + if timestepping_section["atol_upar"] < 0.0 timestepping_section["atol_upar"] = 1.0e-2 * timestepping_section["rtol"] end @@ -187,8 +187,8 @@ function mk_input(input_dict=OptionsDict(); save_inputs_to_txt=false, ignore_MPI nstep=50000, dt=timestepping_section["dt"] * sqrt(composition.me_over_mi), CFL_prefactor=timestepping_section["CFL_prefactor"], - nwrite=nothing, - nwrite_dfns=nothing, + nwrite=-1, + nwrite_dfns=-1, type=timestepping_section["type"], split_operators=false, converged_residual_value=1.0e-3, @@ -208,12 +208,12 @@ function mk_input(input_dict=OptionsDict(); save_inputs_to_txt=false, ignore_MPI no_restart=false, debug_io=false, ) - if electron_timestepping_section["nwrite"] === nothing + if electron_timestepping_section["nwrite"] < 0 electron_timestepping_section["nwrite"] = electron_timestepping_section["nstep"] elseif electron_timestepping_section["nwrite"] > electron_timestepping_section["nstep"] electron_timestepping_section["nwrite"] = electron_timestepping_section["nstep"] end - if electron_timestepping_section["nwrite_dfns"] === nothing + if electron_timestepping_section["nwrite_dfns"] < 0 electron_timestepping_section["nwrite_dfns"] = electron_timestepping_section["nstep"] elseif electron_timestepping_section["nwrite_dfns"] > electron_timestepping_section["nstep"] electron_timestepping_section["nwrite_dfns"] = electron_timestepping_section["nstep"] diff --git a/moment_kinetics/src/numerical_dissipation.jl b/moment_kinetics/src/numerical_dissipation.jl index bb3d7afd1..911375341 100644 --- a/moment_kinetics/src/numerical_dissipation.jl +++ b/moment_kinetics/src/numerical_dissipation.jl @@ -27,7 +27,7 @@ Base.@kwdef struct ion_num_diss_params z_dissipation_coefficient::mk_float = -1.0 r_dissipation_coefficient::mk_float = -1.0 moment_dissipation_coefficient::mk_float = -1.0 - force_minimum_pdf_value::Union{Nothing,mk_float} = nothing + force_minimum_pdf_value::mk_float = -Inf end Base.@kwdef struct electron_num_diss_params @@ -38,7 +38,7 @@ Base.@kwdef struct electron_num_diss_params z_dissipation_coefficient::mk_float = -1.0 r_dissipation_coefficient::mk_float = -1.0 moment_dissipation_coefficient::mk_float = -1.0 - force_minimum_pdf_value::Union{Nothing,mk_float} = nothing + force_minimum_pdf_value::mk_float = -Inf end Base.@kwdef struct neutral_num_diss_params @@ -46,7 +46,7 @@ Base.@kwdef struct neutral_num_diss_params z_dissipation_coefficient::mk_float = -1.0 r_dissipation_coefficient::mk_float = -1.0 moment_dissipation_coefficient::mk_float = -1.0 - force_minimum_pdf_value::Union{Nothing,mk_float} = nothing + force_minimum_pdf_value::mk_float = -Inf end struct numerical_dissipation_parameters @@ -564,7 +564,7 @@ force_minimum_pdf_value = 0.0 """ function force_minimum_pdf_value!(f, minval) - if minval === nothing + if minval == -Inf return nothing end From 60d9414fc93a286aff792feefabfe64b7808cffd Mon Sep 17 00:00:00 2001 From: John Omotani Date: Tue, 17 Sep 2024 21:46:26 +0100 Subject: [PATCH 85/87] Fix formatting in setup_global_weak_form_matrix() docstring --- moment_kinetics/src/gauss_legendre.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/moment_kinetics/src/gauss_legendre.jl b/moment_kinetics/src/gauss_legendre.jl index 93366a60c..7d4b5f2e1 100644 --- a/moment_kinetics/src/gauss_legendre.jl +++ b/moment_kinetics/src/gauss_legendre.jl @@ -867,11 +867,11 @@ K * f = b = M * d2f for f given boundary data on f with periodic or dirichlet boundary conditions, set -periodic_bc = true, b[end] = 0 +`periodic_bc = true`, `b[end] = 0` or -dirichlet_bc = true, b[1] = f[1] (except for cylindrical coordinates), b[end] = f[end] +`dirichlet_bc = true`, `b[1] = f[1]` (except for cylindrical coordinates), `b[end] = f[end]` in the function call, and create new matrices for this purpose in the gausslegendre_info struct. Currently the Laplacian matrix From e7804d793360e3b941970396dd7d9b808dbcefdf Mon Sep 17 00:00:00 2001 From: John Omotani Date: Tue, 17 Sep 2024 21:52:48 +0100 Subject: [PATCH 86/87] Make documentation builds strict on CI To ensure that we are notified of any warnings introduced, e.g. by mistakes in docstrings, so we know to fix them before we merge the PR and deploy the new docs. --- docs/make.jl | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/make.jl b/docs/make.jl index 18aa253e6..c5c25b0d7 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -9,10 +9,19 @@ Pkg.instantiate() using Documenter using moment_kinetics, makie_post_processing, plots_post_processing +if get(ENV, "CI", nothing) == "true" + # On the CI, run in strict mode to turn warnings into errors, so that we don't deploy + # documentation with formatting bugs. + strict = true +else + strict = false +end + makedocs( sitename = "moment_kinetics", format = Documenter.HTML(prettyurls = get(ENV, "CI", nothing) == "true"), - modules = [moment_kinetics, makie_post_processing, plots_post_processing] + modules = [moment_kinetics, makie_post_processing, plots_post_processing], + strict = strict, ) if get(ENV, "CI", nothing) == "true" From 9019c3298925d1ca06bb96dce956ae35a30d003f Mon Sep 17 00:00:00 2001 From: John Omotani Date: Wed, 18 Sep 2024 10:19:16 +0100 Subject: [PATCH 87/87] Reduce max output file path lengths in restart_interpolation_tests.jl In the macOS CI job, temp directories have longer paths than on Linux, so our output file names must be a bit shorter. --- moment_kinetics/test/restart_interpolation_tests.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/moment_kinetics/test/restart_interpolation_tests.jl b/moment_kinetics/test/restart_interpolation_tests.jl index a1d6c436e..936040e28 100644 --- a/moment_kinetics/test/restart_interpolation_tests.jl +++ b/moment_kinetics/test/restart_interpolation_tests.jl @@ -104,8 +104,8 @@ function run_test(test_input, base, message, rtol, atol; tol_3V, args...) name = string(name, "_", (stringify_arg(k, v) for (k, v) in args)...) end # Make sure name is not too long - if length(name) > 90 - name = name[1:90] + if length(name) > 80 + name = name[1:80] end if parallel_io name *= "parallel-io"