diff --git a/makie_post_processing/makie_post_processing/src/setup_defaults.jl b/makie_post_processing/makie_post_processing/src/setup_defaults.jl index 286cdd4fc..4b34d0bce 100644 --- a/makie_post_processing/makie_post_processing/src/setup_defaults.jl +++ b/makie_post_processing/makie_post_processing/src/setup_defaults.jl @@ -100,6 +100,9 @@ end function _setup_single_input!(this_input_dict::OrderedDict{String,Any}, new_input_dict::AbstractDict{String,Any}, run_info, dfns::Bool) + # Error on unexpected options, so that the user can fix them. + warn_unexpected = false + # Remove all existing entries from this_input_dict clear_Dict!(this_input_dict) @@ -172,7 +175,7 @@ function _setup_single_input!(this_input_dict::OrderedDict{String,Any}, only_global_options = ("itime_min", "itime_max", "itime_skip", "itime_min_dfns", "itime_max_dfns", "itime_skip_dfns", "handle_errors") - set_defaults_and_check_top_level!(this_input_dict; + set_defaults_and_check_top_level!(this_input_dict, warn_unexpected; # Options that only apply at the global level (not per-variable) ################################################################ # Options that provide the defaults for per-variable settings @@ -231,7 +234,7 @@ function _setup_single_input!(this_input_dict::OrderedDict{String,Any}, !(k ∈ only_global_options)) for variable_name ∈ tuple(all_moment_variables..., timestep_diagnostic_variables...) set_defaults_and_check_section!( - this_input_dict, variable_name; + this_input_dict, variable_name, warn_unexpected; OrderedDict(Symbol(k)=>v for (k,v) ∈ section_defaults)...) end @@ -245,7 +248,7 @@ function _setup_single_input!(this_input_dict::OrderedDict{String,Any}, animate_log_options_2d = Tuple(Symbol(:animate_log_vs_, d2, :_, d1) for (d1, d2) ∈ two_dimension_combinations_no_t) for variable_name ∈ all_dfn_variables set_defaults_and_check_section!( - this_input_dict, variable_name; + this_input_dict, variable_name, warn_unexpected; check_moments=false, (o=>false for o ∈ plot_options_1d if String(o) ∉ keys(section_defaults))..., (o=>false for o ∈ plot_log_options_1d if String(o) ∉ keys(section_defaults))..., @@ -277,7 +280,7 @@ function _setup_single_input!(this_input_dict::OrderedDict{String,Any}, end set_defaults_and_check_section!( - this_input_dict, "wall_pdf"; + this_input_dict, "wall_pdf", warn_unexpected; plot=false, animate=false, advection_velocity=false, @@ -287,7 +290,7 @@ function _setup_single_input!(this_input_dict::OrderedDict{String,Any}, ) set_defaults_and_check_section!( - this_input_dict, "wall_pdf_electron"; + this_input_dict, "wall_pdf_electron", warn_unexpected; plot=false, animate=false, advection_velocity=false, @@ -297,7 +300,7 @@ function _setup_single_input!(this_input_dict::OrderedDict{String,Any}, ) set_defaults_and_check_section!( - this_input_dict, "wall_pdf_neutral"; + this_input_dict, "wall_pdf_neutral", warn_unexpected; plot=false, animate=false, advection_velocity=false, @@ -307,7 +310,7 @@ function _setup_single_input!(this_input_dict::OrderedDict{String,Any}, ) set_defaults_and_check_section!( - this_input_dict, "constraints"; + this_input_dict, "constraints", warn_unexpected; plot=false, animate=false, it0=this_input_dict["it0"], @@ -323,7 +326,7 @@ function _setup_single_input!(this_input_dict::OrderedDict{String,Any}, ) set_defaults_and_check_section!( - this_input_dict, "Chodura_condition"; + this_input_dict, "Chodura_condition", warn_unexpected; plot_vs_t=false, plot_vs_r=false, plot_vs_r_t=false, @@ -335,7 +338,7 @@ function _setup_single_input!(this_input_dict::OrderedDict{String,Any}, ) set_defaults_and_check_section!( - this_input_dict, "instability2D"; + this_input_dict, "instability2D", warn_unexpected; plot_1d=false, plot_2d=false, animate_perturbations=false, @@ -344,7 +347,7 @@ function _setup_single_input!(this_input_dict::OrderedDict{String,Any}, ) set_defaults_and_check_section!( - this_input_dict, "sound_wave_fit"; + this_input_dict, "sound_wave_fit", warn_unexpected; calculate_frequency=false, plot=false, ir0=this_input_dict["ir0"], @@ -352,7 +355,7 @@ function _setup_single_input!(this_input_dict::OrderedDict{String,Any}, ) set_defaults_and_check_section!( - this_input_dict, "manufactured_solns"; + this_input_dict, "manufactured_solns", warn_unexpected; calculate_error_norms=true, wall_plots=false, (o=>false for o ∈ plot_options_1d)..., @@ -371,7 +374,7 @@ function _setup_single_input!(this_input_dict::OrderedDict{String,Any}, sort!(this_input_dict["manufactured_solns"]) set_defaults_and_check_section!( - this_input_dict, "timestep_diagnostics"; + this_input_dict, "timestep_diagnostics", warn_unexpected; plot=true, animate_CFL=false, plot_timestep_residual=false, @@ -383,7 +386,7 @@ function _setup_single_input!(this_input_dict::OrderedDict{String,Any}, ) set_defaults_and_check_section!( - this_input_dict, "collisionality_plots"; + this_input_dict, "collisionality_plots", warn_unexpected; plot=true, plot_dT_dz_vs_z=false, animate_dT_dz_vs_z=false, @@ -405,7 +408,7 @@ function _setup_single_input!(this_input_dict::OrderedDict{String,Any}, ) set_defaults_and_check_section!( - this_input_dict, "timing_data"; + this_input_dict, "timing_data", warn_unexpected; plot=false, threshold=1.0e-2, include_patterns=String[], diff --git a/moment_kinetics/src/coordinates.jl b/moment_kinetics/src/coordinates.jl index 7f71fd12a..e4611fa01 100644 --- a/moment_kinetics/src/coordinates.jl +++ b/moment_kinetics/src/coordinates.jl @@ -148,11 +148,13 @@ struct coordinate{T <: AbstractVector{mk_float}, Ti <: AbstractVector{mk_int}, T end """ - get_coordinate_input(input_dict, name) + get_coordinate_input(input_dict, name; ignore_MPI=false, + warn_unexpected::Bool=false) Read the input for coordinate `name` from `input_dict`, setting defaults, etc. """ -function get_coordinate_input(input_dict, name; ignore_MPI=false) +function get_coordinate_input(input_dict, name; ignore_MPI=false, + warn_unexpected::Bool=false) if name == "z" default_bc = "wall" elseif name == "r" @@ -163,7 +165,7 @@ function get_coordinate_input(input_dict, name; ignore_MPI=false) default_bc = "zero" end coord_input_dict = set_defaults_and_check_section!( - input_dict, name; + input_dict, name, warn_unexpected; # ngrid is number of grid points per element ngrid=1, # nelement is the number of elements in total @@ -223,7 +225,7 @@ function get_coordinate_input(input_dict, name; ignore_MPI=false) boundary_parameters_defaults[:epsz] = 0.0 end boundary_parameters_input = set_defaults_and_check_section!( - input_dict, "$(name)_boundary_condition_parameters"; + input_dict, "$(name)_boundary_condition_parameters", warn_unexpected; boundary_parameters_defaults... ) boundary_parameters = Dict_to_NamedTuple(boundary_parameters_input) @@ -256,9 +258,9 @@ When `coord_input` is passed, it should be a `NamedTuple` as generated by """ function define_coordinate end -function define_coordinate(input_dict, name; kwargs...) +function define_coordinate(input_dict, name, warn_unexpected::Bool=false; kwargs...) - coord_input = get_coordinate_input(input_dict, name) + coord_input = get_coordinate_input(input_dict, name, warn_unexpected=warn_unexpected) return define_coordinate(coord_input; kwargs...) end diff --git a/moment_kinetics/src/external_sources.jl b/moment_kinetics/src/external_sources.jl index 00ea31958..a35fc86c3 100644 --- a/moment_kinetics/src/external_sources.jl +++ b/moment_kinetics/src/external_sources.jl @@ -46,10 +46,11 @@ and z-coordinates. 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; ignore_MPI=false) +function setup_external_sources!(input_dict, r, z, electron_physics, + warn_unexpected::Bool; ignore_MPI=false) function get_settings_ions(source_index, active_flag) input = set_defaults_and_check_section!( - input_dict, "ion_source_$source_index"; + input_dict, "ion_source_$source_index", warn_unexpected; active=active_flag, source_strength=1.0, source_n=1.0, @@ -229,7 +230,7 @@ function setup_external_sources!(input_dict, r, z, electron_physics; ignore_MPI= function get_settings_neutrals(source_index, active_flag) input = set_defaults_and_check_section!( - input_dict, "neutral_source_$source_index"; + input_dict, "neutral_source_$source_index", warn_unexpected; active=active_flag, source_strength=1.0, source_n=1.0, @@ -393,7 +394,7 @@ function setup_external_sources!(input_dict, r, z, electron_physics; ignore_MPI= # electrons. `source_T` can be set independently, and when using # `source_type="energy"`, the `source_strength` could also be set. input = set_defaults_and_check_section!( - input_dict, "electron_source_$i"; + input_dict, "electron_source_$i", warn_unexpected; source_strength=ion_settings.source_strength, source_T=ion_settings.source_T, ) diff --git a/moment_kinetics/src/file_io.jl b/moment_kinetics/src/file_io.jl index a2d8eaddf..e1ac98012 100644 --- a/moment_kinetics/src/file_io.jl +++ b/moment_kinetics/src/file_io.jl @@ -347,9 +347,10 @@ end """ Read the settings for I/O """ -function setup_io_input(input_dict, timestepping_section; ignore_MPI=false) +function setup_io_input(input_dict, timestepping_section, warn_unexpected::Bool; + ignore_MPI=false) io_settings = set_defaults_and_check_section!( - input_dict, "output"; + input_dict, "output", warn_unexpected; run_name="", base_directory="runs", ascii_output=false, diff --git a/moment_kinetics/src/fokker_planck.jl b/moment_kinetics/src/fokker_planck.jl index e6e717bf5..2507be3c5 100644 --- a/moment_kinetics/src/fokker_planck.jl +++ b/moment_kinetics/src/fokker_planck.jl @@ -84,26 +84,27 @@ Structure the namelist as follows. nuii = 1.0 frequency_option = "manual" """ -function setup_fkpl_collisions_input(toml_input::AbstractDict) - reference_params = setup_reference_parameters(toml_input) +function setup_fkpl_collisions_input(toml_input::AbstractDict, warn_unexpected::Bool) + reference_params = setup_reference_parameters(toml_input, warn_unexpected) # get reference collision frequency (note factor of 1/2 due to definition choices) nuii_fkpl_default = 0.5*get_reference_collision_frequency_ii(reference_params) # read the input toml and specify a sensible default - input_section = set_defaults_and_check_section!(toml_input, "fokker_planck_collisions", - # begin default inputs (as kwargs) - use_fokker_planck = false, - nuii = -1.0, - frequency_option = "reference_parameters", - self_collisions = true, - use_conserving_corrections = true, - boundary_data_option = direct_integration, - slowing_down_test = false, - sd_density = 1.0, - sd_temp = 0.01, - sd_q = 1.0, - sd_mi = 0.25, - sd_me = 0.25/1836.0, - Zi = 1.0) + input_section = set_defaults_and_check_section!( + toml_input, "fokker_planck_collisions", warn_unexpected; + # begin default inputs (as kwargs) + use_fokker_planck = false, + nuii = -1.0, + frequency_option = "reference_parameters", + self_collisions = true, + use_conserving_corrections = true, + boundary_data_option = direct_integration, + slowing_down_test = false, + sd_density = 1.0, + sd_temp = 0.01, + sd_q = 1.0, + sd_mi = 0.25, + sd_me = 0.25/1836.0, + Zi = 1.0) # ensure that the collision frequency is consistent with the input option frequency_option = input_section["frequency_option"] if frequency_option == "reference_parameters" diff --git a/moment_kinetics/src/geo.jl b/moment_kinetics/src/geo.jl index 933598a65..64a122c6d 100644 --- a/moment_kinetics/src/geo.jl +++ b/moment_kinetics/src/geo.jl @@ -83,12 +83,13 @@ DeltaB = 0.0 option = "" """ -function setup_geometry_input(toml_input::AbstractDict) +function setup_geometry_input(toml_input::AbstractDict, warn_unexpected::Bool) - reference_params = setup_reference_parameters(toml_input) + reference_params = setup_reference_parameters(toml_input, warn_unexpected) reference_rhostar = get_default_rhostar(reference_params) # read the input toml and specify a sensible default - input_section = set_defaults_and_check_section!(toml_input, "geometry", + input_section = set_defaults_and_check_section!( + toml_input, "geometry", warn_unexpected; # begin default inputs (as kwargs) # rhostar ion (ref) rhostar = reference_rhostar, #used to premultiply ExB drift terms diff --git a/moment_kinetics/src/input_structs.jl b/moment_kinetics/src/input_structs.jl index 84707eb0f..1fc5317c8 100644 --- a/moment_kinetics/src/input_structs.jl +++ b/moment_kinetics/src/input_structs.jl @@ -796,7 +796,8 @@ are not already present. Ignores any sections, as these will be checked separately. """ -function set_defaults_and_check_top_level!(options::OptionsDict; kwargs...) +function set_defaults_and_check_top_level!(options::OptionsDict, warn_unexpected::Bool; + kwargs...) # Check for any unexpected values in the options - all options that are set should be # present in the kwargs of this function call options_keys_symbols = keys(kwargs) @@ -804,7 +805,12 @@ function set_defaults_and_check_top_level!(options::OptionsDict; kwargs...) for (key, value) in options # Ignore any ssections when checking if !(isa(value, AbstractDict) || key ∈ options_keys) - error("Unexpected option '$key=$value' in top-level options") + if warn_unexpected + println("Unexpected option '$key=$value' in top-level options") + pop!(options, key) + else + error("Unexpected option '$key=$value' in top-level options") + end end end @@ -821,7 +827,7 @@ function set_defaults_and_check_top_level!(options::OptionsDict; kwargs...) end function _get_section_and_check_option_names(options::OptionsDict, section_name, - section_keys) + section_keys, warn_unexpected::Bool) if !(section_name ∈ keys(options)) # If section is not present, create it @@ -844,7 +850,14 @@ function _get_section_and_check_option_names(options::OptionsDict, section_name, end end if length(unexpected_options) > 0 - error("Unexpected options $(join(("$k=$(section[k])" for k ∈ unexpected_options), ", ", ", and ")) in section '$section_name'") + if warn_unexpected + println("Unexpected options $(join(("$k=$(section[k])" for k ∈ unexpected_options), ", ", ", and ")) in section '$section_name'") + for key ∈ unexpected_options + pop!(section, key) + end + else + error("Unexpected options $(join(("$k=$(section[k])" for k ∈ unexpected_options), ", ", ", and ")) in section '$section_name'") + end end return section @@ -880,11 +893,13 @@ options (i.e. options that have no default). Modifies the options[section_name]::OptionsDict by adding defaults for any values that are not already present. """ -function set_defaults_and_check_section!(options::OptionsDict, section_name; kwargs...) +function set_defaults_and_check_section!(options::OptionsDict, section_name::String, + warn_unexpected::Bool; 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) + section = _get_section_and_check_option_names(options, section_name, section_keys, + warn_unexpected) # Set default values if a key was not set explicitly for (key_sym, default_value) ∈ kwargs @@ -920,13 +935,15 @@ The name of the section in the options that will be read defaults to the name of Returns an instance of `struct_type`. """ function set_defaults_and_check_section!(options::OptionsDict, struct_type::Type, + warn_unexpected::Bool, 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) + section = _get_section_and_check_option_names(options, section_name, section_keys, + warn_unexpected) # 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 diff --git a/moment_kinetics/src/krook_collisions.jl b/moment_kinetics/src/krook_collisions.jl index 14e209a89..31a5c1c88 100644 --- a/moment_kinetics/src/krook_collisions.jl +++ b/moment_kinetics/src/krook_collisions.jl @@ -22,20 +22,21 @@ use_krook = true nuii0 = 1.0 frequency_option = "manual" """ -function setup_krook_collisions_input(toml_input::AbstractDict) - reference_params = setup_reference_parameters(toml_input) +function setup_krook_collisions_input(toml_input::AbstractDict, warn_unexpected::Bool) + reference_params = setup_reference_parameters(toml_input, warn_unexpected) # get reference collision frequency nuii_krook_default = get_reference_collision_frequency_ii(reference_params) nuee_krook_default = get_reference_collision_frequency_ee(reference_params) nuei_krook_default = get_reference_collision_frequency_ei(reference_params) # read the input toml and specify a sensible default - input_section = input_section = set_defaults_and_check_section!(toml_input, "krook_collisions", - # begin default inputs (as kwargs) - use_krook = false, - nuii0 = -1.0, - nuee0 = -1.0, - nuei0 = -1.0, - frequency_option = "reference_parameters") + input_section = input_section = set_defaults_and_check_section!( + toml_input, "krook_collisions", warn_unexpected; + # begin default inputs (as kwargs) + use_krook = false, + nuii0 = -1.0, + nuee0 = -1.0, + nuei0 = -1.0, + frequency_option = "reference_parameters") # ensure that the collision frequency is consistent with the input option frequency_option = input_section["frequency_option"] diff --git a/moment_kinetics/src/load_data.jl b/moment_kinetics/src/load_data.jl index 15de297ab..c17844424 100644 --- a/moment_kinetics/src/load_data.jl +++ b/moment_kinetics/src/load_data.jl @@ -3522,7 +3522,7 @@ function get_run_info_no_setup(run_dir::Union{AbstractString,Tuple{AbstractStrin # and check input to catch errors io_input, evolve_moments, t_input, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, composition, species, collisions, geometry, drive_input, external_source_settings, - num_diss_params, manufactured_solns_input = mk_input(input) + num_diss_params, manufactured_solns_input = mk_input(input; warn_unexpected=true) n_ion_species, n_neutral_species = load_species_data(file_final_restart) evolve_density, evolve_upar, evolve_ppar = load_mk_options(file_final_restart) diff --git a/moment_kinetics/src/manufactured_solns.jl b/moment_kinetics/src/manufactured_solns.jl index 06768c22b..ad5f3b51f 100644 --- a/moment_kinetics/src/manufactured_solns.jl +++ b/moment_kinetics/src/manufactured_solns.jl @@ -29,11 +29,11 @@ function __init__() end end -function setup_manufactured_solutions(input_dict) +function setup_manufactured_solutions(input_dict, warn_unexpected::Bool) 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"; + input_dict, "manufactured_solns", warn_unexpected; use_for_advance=false, use_for_init=false, # constant to be used to control Ez divergence in MMS tests diff --git a/moment_kinetics/src/maxwell_diffusion.jl b/moment_kinetics/src/maxwell_diffusion.jl index 85d2d4639..a1ce6f393 100644 --- a/moment_kinetics/src/maxwell_diffusion.jl +++ b/moment_kinetics/src/maxwell_diffusion.jl @@ -32,20 +32,21 @@ use_maxwell_diffusion = true D_ii = 1.0 diffusion_coefficient_option = "manual" """ -function setup_mxwl_diff_collisions_input(toml_input::AbstractDict) - reference_params = setup_reference_parameters(toml_input) +function setup_mxwl_diff_collisions_input(toml_input::AbstractDict, warn_unexpected::Bool) + reference_params = setup_reference_parameters(toml_input, warn_unexpected) # get reference diffusion coefficient, made up of collision frequency and # thermal speed for now. NOTE THAT THIS CONSTANT PRODUCES ERRORS. DO NOT USE D_ii_mxwl_diff_default = get_reference_collision_frequency_ii(reference_params)# * #2 * reference_params.Tref/reference_params.mref D_nn_mxwl_diff_default = D_ii_mxwl_diff_default # read the input toml and specify a sensible default - input_section = set_defaults_and_check_section!(toml_input, "maxwell_diffusion_collisions", - # begin default inputs (as kwargs) - use_maxwell_diffusion = false, - D_ii = -1.0, - D_nn = -1.0, - diffusion_coefficient_option = "reference_parameters") + input_section = set_defaults_and_check_section!( + toml_input, "maxwell_diffusion_collisions", warn_unexpected; + # begin default inputs (as kwargs) + use_maxwell_diffusion = false, + D_ii = -1.0, + D_nn = -1.0, + diffusion_coefficient_option = "reference_parameters") # ensure that the diffusion coefficient is consistent with the input option diffusion_coefficient_option = input_section["diffusion_coefficient_option"] diff --git a/moment_kinetics/src/moment_kinetics_input.jl b/moment_kinetics/src/moment_kinetics_input.jl index cb5c29c01..9f0928df0 100644 --- a/moment_kinetics/src/moment_kinetics_input.jl +++ b/moment_kinetics/src/moment_kinetics_input.jl @@ -53,7 +53,8 @@ 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(input_dict=OptionsDict(); save_inputs_to_txt=false, ignore_MPI=true) +function mk_input(input_dict=OptionsDict(); save_inputs_to_txt=false, ignore_MPI=true, + warn_unexpected=false) # 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. @@ -90,14 +91,14 @@ function mk_input(input_dict=OptionsDict(); save_inputs_to_txt=false, ignore_MPI end # read composition and species data - composition = get_species_input(input_dict) + composition = get_species_input(input_dict, warn_unexpected) n_ion_species = composition.n_ion_species n_neutral_species = composition.n_neutral_species # 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!( - input_dict, "evolve_moments"; + input_dict, "evolve_moments", warn_unexpected; density=false, parallel_flow=false, parallel_pressure=false, @@ -107,40 +108,40 @@ function mk_input(input_dict=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(input_dict) + reference_params = setup_reference_parameters(input_dict, warn_unexpected) ## set geometry_input - geometry_in = setup_geometry_input(input_dict) + geometry_in = setup_geometry_input(input_dict, warn_unexpected) em_input = set_defaults_and_check_section!( - input_dict, em_fields_input, "em_fields" + input_dict, em_fields_input, warn_unexpected, "em_fields" ) - manufactured_solns_input = setup_manufactured_solutions(input_dict) + manufactured_solns_input = setup_manufactured_solutions(input_dict, warn_unexpected) reactions_input = set_defaults_and_check_section!( - input_dict, reactions + input_dict, reactions, warn_unexpected ) electron_fluid_collisions_input = set_defaults_and_check_section!( - input_dict, electron_fluid_collisions + input_dict, electron_fluid_collisions, warn_unexpected ) # set up krook collision inputs - krook_input = setup_krook_collisions_input(input_dict) + krook_input = setup_krook_collisions_input(input_dict, warn_unexpected) # set up Fokker-Planck collision inputs - fkpl_input = setup_fkpl_collisions_input(input_dict) + fkpl_input = setup_fkpl_collisions_input(input_dict, warn_unexpected) # set up maxwell diffusion collision inputs - mxwl_diff_input = setup_mxwl_diff_collisions_input(input_dict) + mxwl_diff_input = setup_mxwl_diff_collisions_input(input_dict, warn_unexpected) # 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(reactions_input, electron_fluid_collisions_input, krook_input, fkpl_input, mxwl_diff_input) - num_diss_params = setup_numerical_dissipation(input_dict) + num_diss_params = setup_numerical_dissipation(input_dict, warn_unexpected) # parameters related to the time stepping timestepping_section = set_defaults_and_check_section!( - input_dict, "timestepping"; + input_dict, "timestepping", warn_unexpected; nstep=5, dt=0.00025/sqrt(composition.ion[1].initial_temperature), CFL_prefactor=-1.0, @@ -186,7 +187,7 @@ function mk_input(input_dict=OptionsDict(); save_inputs_to_txt=false, ignore_MPI # parameters related to electron time stepping electron_timestepping_section = set_defaults_and_check_section!( - input_dict, "electron_timestepping"; + input_dict, "electron_timestepping", warn_unexpected; nstep=50000, dt=timestepping_section["dt"] * sqrt(composition.me_over_mi), CFL_prefactor=timestepping_section["CFL_prefactor"], @@ -314,8 +315,10 @@ function mk_input(input_dict=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(input_dict, "r"; ignore_MPI=ignore_MPI) - z_coord_input = get_coordinate_input(input_dict, "z"; ignore_MPI=ignore_MPI) + r_coord_input = get_coordinate_input(input_dict, "r"; ignore_MPI=ignore_MPI, + warn_unexpected=warn_unexpected) + z_coord_input = get_coordinate_input(input_dict, "z"; ignore_MPI=ignore_MPI, + warn_unexpected=warn_unexpected) if ignore_MPI irank_z = irank_r = 0 nrank_z = nrank_r = 1 @@ -328,7 +331,8 @@ function mk_input(input_dict=OptionsDict(); save_inputs_to_txt=false, ignore_MPI r_coord_input.nelement_local) end - io_immutable = setup_io_input(input_dict, timestepping_section; ignore_MPI=ignore_MPI) + io_immutable = setup_io_input(input_dict, timestepping_section, warn_unexpected; + 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") @@ -348,38 +352,40 @@ function mk_input(input_dict=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(input_dict, "vpa"; + vpa, vpa_spectral = define_coordinate(input_dict, "vpa", warn_unexpected; 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(input_dict, "vperp"; + vperp, vperp_spectral = define_coordinate(input_dict, "vperp", warn_unexpected; 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(input_dict, "gyrophase"; + gyrophase, gyrophase_spectral = define_coordinate(input_dict, "gyrophase", + warn_unexpected; 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(input_dict, "vz"; + vz, vz_spectral = define_coordinate(input_dict, "vz", warn_unexpected; 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(input_dict, "vr"; + vr, vr_spectral = define_coordinate(input_dict, "vr", warn_unexpected; 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(input_dict, "vzeta"; + vzeta, vzeta_spectral = define_coordinate(input_dict, "vzeta", warn_unexpected; parallel_io=io_immutable.parallel_io, run_directory=run_directory, ignore_MPI=ignore_MPI) external_source_settings = setup_external_sources!(input_dict, r, z, - composition.electron_physics; + composition.electron_physics, + warn_unexpected; ignore_MPI=ignore_MPI) geometry = init_magnetic_geometry(geometry_in,z,r) diff --git a/moment_kinetics/src/nonlinear_solvers.jl b/moment_kinetics/src/nonlinear_solvers.jl index 361547970..21cf86145 100644 --- a/moment_kinetics/src/nonlinear_solvers.jl +++ b/moment_kinetics/src/nonlinear_solvers.jl @@ -88,9 +88,10 @@ for example a preconditioner object for each point in that outer loop. """ 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=Val(:none)) + electron_ppar_pdf_solve=false, + preconditioner_type=Val(:none), warn_unexpected=false) nl_solver_section = set_defaults_and_check_section!( - input_dict, "nonlinear_solver"; + input_dict, "nonlinear_solver", warn_unexpected; rtol=default_rtol, atol=default_atol, nonlinear_max_iterations=20, diff --git a/moment_kinetics/src/numerical_dissipation.jl b/moment_kinetics/src/numerical_dissipation.jl index cfa355d42..35c0a40bf 100644 --- a/moment_kinetics/src/numerical_dissipation.jl +++ b/moment_kinetics/src/numerical_dissipation.jl @@ -79,15 +79,17 @@ vz_dissipation_coefficient There will still be the -1.0 default parameters. """ -function setup_numerical_dissipation(input_dict) +function setup_numerical_dissipation(input_dict, warn_unexpected::Bool) ion_params = set_defaults_and_check_section!( - input_dict, ion_num_diss_params, "ion_numerical_dissipation" + input_dict, ion_num_diss_params, warn_unexpected, "ion_numerical_dissipation" ) electron_params = set_defaults_and_check_section!( - input_dict, electron_num_diss_params, "electron_numerical_dissipation" + input_dict, electron_num_diss_params, warn_unexpected, + "electron_numerical_dissipation" ) neutral_params = set_defaults_and_check_section!( - input_dict, neutral_num_diss_params, "neutral_numerical_dissipation" + input_dict, neutral_num_diss_params, warn_unexpected, + "neutral_numerical_dissipation" ) return numerical_dissipation_parameters(ion_params, electron_params, neutral_params) diff --git a/moment_kinetics/src/reference_parameters.jl b/moment_kinetics/src/reference_parameters.jl index 97b771228..8fc4509cf 100644 --- a/moment_kinetics/src/reference_parameters.jl +++ b/moment_kinetics/src/reference_parameters.jl @@ -16,10 +16,10 @@ using ..input_structs """ """ -function setup_reference_parameters(input_dict) +function setup_reference_parameters(input_dict, warn_unexpected::Bool) # Get reference parameters for normalizations reference_parameter_section = copy(set_defaults_and_check_section!( - input_dict, "reference_params"; + input_dict, "reference_params", warn_unexpected; Bref=1.0, Lref=10.0, Nref=1.0e19, diff --git a/moment_kinetics/src/species_input.jl b/moment_kinetics/src/species_input.jl index dae8137ab..1d7df3aa6 100644 --- a/moment_kinetics/src/species_input.jl +++ b/moment_kinetics/src/species_input.jl @@ -16,12 +16,13 @@ using ..reference_parameters: setup_reference_parameters using OrderedCollections: OrderedDict -function get_species_input(toml_input) +function get_species_input(toml_input, warn_unexpected::Bool) - reference_params = setup_reference_parameters(toml_input) + reference_params = setup_reference_parameters(toml_input, warn_unexpected) # read general composition parameters - composition_section = set_defaults_and_check_section!(toml_input, "composition", + composition_section = set_defaults_and_check_section!( + toml_input, "composition", warn_unexpected; # n_ion_species is the number of evolved ion species n_ion_species = 1, # n_neutral_species is the number of evolved neutral species @@ -65,7 +66,8 @@ function get_species_input(toml_input) ion_spec_params_list = Array{ion_species_parameters,1}(undef,nspec_ion) neutral_spec_params_list = Array{neutral_species_parameters,1}(undef,nspec_neutral) for is in 1:nspec_ion - spec_section = set_defaults_and_check_section!(toml_input, "ion_species_$is", + spec_section = set_defaults_and_check_section!( + toml_input, "ion_species_$is", warn_unexpected; # [ion_species_1], [ion_species_2], etc # mass of ion species mass = 1.0, @@ -78,14 +80,15 @@ function get_species_input(toml_input) z_IC = set_defaults_and_check_section!(toml_input, spatial_initial_condition_input, - "z_IC_ion_species_$is") + warn_unexpected, "z_IC_ion_species_$is") r_IC = set_defaults_and_check_section!(toml_input, spatial_initial_condition_input, - "r_IC_ion_species_$is") + warn_unexpected, "r_IC_ion_species_$is") vpa_IC = set_defaults_and_check_section!(toml_input, velocity_initial_condition_input, + warn_unexpected, "vpa_IC_ion_species_$is") spec_input = OrderedDict(Symbol(k)=>v for (k,v) in spec_section) @@ -94,7 +97,8 @@ function get_species_input(toml_input) spec_input...) end for isn in 1:nspec_neutral - spec_section = set_defaults_and_check_section!(toml_input, "neutral_species_$isn", + spec_section = set_defaults_and_check_section!( + toml_input, "neutral_species_$isn", warn_unexpected; # [neutral_species_1], [neutral_species_2], etc # mass of neutral species mass = 1.0, @@ -105,14 +109,17 @@ function get_species_input(toml_input) z_IC = set_defaults_and_check_section!(toml_input, spatial_initial_condition_input, + warn_unexpected, "z_IC_neutral_species_$isn") r_IC = set_defaults_and_check_section!(toml_input, spatial_initial_condition_input, + warn_unexpected, "r_IC_neutral_species_$isn") vz_IC = set_defaults_and_check_section!(toml_input, velocity_initial_condition_input, + warn_unexpected, "vz_IC_neutral_species_$isn") spec_input = OrderedDict(Symbol(k)=>v for (k,v) in spec_section) diff --git a/moment_kinetics/test/gyroaverage_tests.jl b/moment_kinetics/test/gyroaverage_tests.jl index 4f89f46d8..799ce0ad1 100644 --- a/moment_kinetics/test/gyroaverage_tests.jl +++ b/moment_kinetics/test/gyroaverage_tests.jl @@ -167,7 +167,7 @@ function gyroaverage_test(absolute_error; rhostar=0.1, pitch=0.5, ngrid=5, kr=2, # create test geometry option = "constant-helical" inputdict = OptionsDict("geometry" => OptionsDict("option" => option, "rhostar" => rhostar, "pitch" => pitch)) - geometry_in = setup_geometry_input(inputdict) + geometry_in = setup_geometry_input(inputdict, true) geometry = init_magnetic_geometry(geometry_in,z,r) # create test composition