!> @file option_registry.f90 !> @brief Canonical string tokens for runtime-selectable solver options. !! !! Centralises the valid scheme, limiter, boundary-condition, and config-enum !! names that are accepted throughout the solver. Modules that dispatch on a !! string token should import the corresponding named constants from here !! instead of duplicating string literals locally. module option_registry implicit none private ! Flux schemes character(len=*), parameter, public :: flux_lax_friedrichs = 'lax_friedrichs' character(len=*), parameter, public :: flux_steger_warming = 'steger_warming' character(len=*), parameter, public :: flux_van_leer = 'van_leer' character(len=*), parameter, public :: flux_ausm_plus = 'ausm_plus' character(len=*), parameter, public :: flux_hll = 'hll' character(len=*), parameter, public :: flux_hllc = 'hllc' character(len=*), parameter, public :: flux_roe = 'roe' ! Reconstruction schemes character(len=*), parameter, public :: recon_weno5 = 'weno5' character(len=*), parameter, public :: recon_weno5z = 'weno5z' character(len=*), parameter, public :: recon_weno_cu6 = 'weno_cu6' character(len=*), parameter, public :: recon_weno7 = 'weno7' character(len=*), parameter, public :: recon_weno9 = 'weno9' character(len=*), parameter, public :: recon_weno11 = 'weno11' character(len=*), parameter, public :: recon_eno3 = 'eno3' character(len=*), parameter, public :: recon_muscl = 'muscl' character(len=*), parameter, public :: recon_mp5 = 'mp5' character(len=*), parameter, public :: recon_teno5 = 'teno5' character(len=*), parameter, public :: recon_upwind1 = 'upwind1' character(len=*), parameter, public :: recon_upwind2 = 'upwind2' character(len=*), parameter, public :: recon_central2 = 'central2' ! Time integrators character(len=*), parameter, public :: time_euler = 'euler' character(len=*), parameter, public :: time_ssprk22 = 'ssprk22' character(len=*), parameter, public :: time_rk3 = 'rk3' character(len=*), parameter, public :: time_rk4 = 'rk4' character(len=*), parameter, public :: time_ssprk54 = 'ssprk54' character(len=*), parameter, public :: time_beuler = 'beuler' character(len=*), parameter, public :: time_bdf2 = 'bdf2' ! MUSCL limiters character(len=*), parameter, public :: limiter_minmod = 'minmod' character(len=*), parameter, public :: limiter_superbee = 'superbee' character(len=*), parameter, public :: limiter_mc = 'mc' character(len=*), parameter, public :: limiter_van_leer = 'van_leer' character(len=*), parameter, public :: limiter_koren = 'koren' ! Problem types character(len=*), parameter, public :: problem_sod = 'sod' character(len=*), parameter, public :: problem_shu_osher = 'shu_osher' character(len=*), parameter, public :: problem_smooth_wave = 'smooth_wave' character(len=*), parameter, public :: problem_linear_advection = 'linear_advection' character(len=*), parameter, public :: problem_woodward_colella = 'woodward_colella' character(len=*), parameter, public :: problem_lax = 'lax' character(len=*), parameter, public :: problem_from_file = 'from_file' character(len=*), parameter, public :: problem_udf = 'udf' character(len=*), parameter, public :: problem_acoustic_pulse = 'acoustic_pulse' ! Boundary conditions character(len=*), parameter, public :: bc_dirichlet = 'dirichlet' character(len=*), parameter, public :: bc_inflow = 'inflow' character(len=*), parameter, public :: bc_outflow = 'outflow' character(len=*), parameter, public :: bc_reflecting = 'reflecting' character(len=*), parameter, public :: bc_periodic = 'periodic' character(len=*), parameter, public :: bc_nonreflecting = 'nonreflecting' character(len=*), parameter, public :: bc_supersonic_inlet = 'supersonic_inlet' character(len=*), parameter, public :: bc_subsonic_inlet = 'subsonic_inlet' character(len=*), parameter, public :: bc_supersonic_outlet = 'supersonic_outlet' character(len=*), parameter, public :: bc_subsonic_outlet = 'subsonic_outlet' character(len=*), parameter, public :: bc_neumann = 'neumann' character(len=*), parameter, public :: bc_neumann_gradient = 'neumann_gradient' character(len=*), parameter, public :: bc_farfield = 'farfield' ! Enum-like mode values character(len=*), parameter, public :: char_proj_auto = 'auto' character(len=*), parameter, public :: char_proj_yes = 'yes' character(len=*), parameter, public :: char_proj_no = 'no' character(len=*), parameter, public :: nrbc_mode_pressure = 'pressure' character(len=*), parameter, public :: nrbc_mode_characteristic = 'characteristic' character(len=*), parameter, public :: hybrid_sensor_jameson = 'jameson' character(len=*), parameter, public :: hybrid_sensor_density_gradient = 'density_gradient' character(len=*), parameter, public :: hybrid_sensor_weno_beta = 'weno_beta' character(len=32), parameter, public :: flux_scheme_names(7) = [character(len=32) :: & flux_lax_friedrichs, flux_steger_warming, flux_van_leer, & flux_ausm_plus, flux_hll, flux_hllc, flux_roe] character(len=32), parameter, public :: recon_scheme_names(13) = [character(len=32) :: & recon_weno5, recon_weno5z, recon_weno_cu6, recon_weno7, & recon_weno9, recon_weno11, recon_eno3, recon_muscl, & recon_mp5, recon_teno5, recon_upwind1, recon_upwind2, & recon_central2] character(len=16), parameter, public :: time_scheme_names(7) = [character(len=16) :: & time_euler, time_ssprk22, time_rk3, time_rk4, time_ssprk54, & time_beuler, time_bdf2] character(len=16), parameter, public :: limiter_names(5) = [character(len=16) :: & limiter_minmod, limiter_superbee, limiter_mc, limiter_van_leer, & limiter_koren] character(len=32), parameter, public :: problem_type_names(9) = [character(len=32) :: & problem_sod, problem_shu_osher, problem_smooth_wave, & problem_linear_advection, & problem_woodward_colella, problem_lax, problem_from_file, & problem_udf, problem_acoustic_pulse] character(len=32), parameter, public :: boundary_condition_names(12) = [character(len=32) :: & bc_dirichlet, bc_inflow, bc_outflow, bc_reflecting, & bc_periodic, bc_nonreflecting, & bc_supersonic_inlet, bc_subsonic_inlet, & bc_supersonic_outlet, bc_subsonic_outlet, & bc_neumann, bc_neumann_gradient] character(len=8), parameter, public :: char_proj_mode_names(3) = [character(len=8) :: & char_proj_auto, char_proj_yes, char_proj_no] character(len=16), parameter, public :: nrbc_mode_names(2) = [character(len=16) :: & nrbc_mode_pressure, nrbc_mode_characteristic] character(len=32), parameter, public :: hybrid_sensor_names(3) = [character(len=32) :: & hybrid_sensor_jameson, hybrid_sensor_density_gradient, & hybrid_sensor_weno_beta] ! Discretization methods (1D) character(len=*), parameter, public :: method_fdm = 'fdm' character(len=*), parameter, public :: method_fvm = 'fvm' character(len=8), parameter, public :: method_names(2) = [character(len=8) :: & method_fdm, method_fvm] ! --- 2D solver token sets (euler_2d) --------------------------------------- ! These are NARROWER, dimension-specific subsets/variants of the 1D sets ! above: euler_2d implements only a fraction of the 1D scheme/BC zoo, plus ! its own initial conditions. Each array MUST mirror the live 2D `select case` ! dispatch (schemes_2d.f90 / boundary_2d.f90 / euler_riemann_2d.f90 / ! time_integration_2d.f90); do not widen them to the 1D arrays. ! 2D-only scalar tokens (no 1D named equivalent): !> 2D-only Rusanov flux selector (euler_riemann_2d.f90 `face_flux_2d`). character(len=*), parameter, public :: flux_rusanov = 'rusanov' !> 2D-only initial-condition / problem-type selectors (disjoint from `problem_*`). character(len=*), parameter, public :: problem_2d_uniform = 'uniform' character(len=*), parameter, public :: problem_2d_isentropic_vortex = 'isentropic_vortex' character(len=*), parameter, public :: problem_2d_sedov = 'sedov' character(len=*), parameter, public :: problem_2d_toro_explosion = 'toro_explosion' character(len=*), parameter, public :: problem_2d_riemann2d_config3 = 'riemann2d_config3' character(len=*), parameter, public :: problem_2d_freestream = 'freestream' !> Valid 2D numerical-flux selectors. Mirrors `face_flux_2d` !! (euler_riemann_2d.f90): explicit `rusanov`, plus `hllc` (the `case default` !! target and documented default). `rusanov` is 2D-only (no 1D named token). !! FVS schemes (`lax_friedrichs`, `steger_warming`, `van_leer`) are FDM-only. character(len=32), parameter, public :: flux_scheme_2d_names(5) = [character(len=32) :: & flux_hllc, flux_rusanov, & flux_lax_friedrichs, flux_steger_warming, & flux_van_leer] !> Valid 2D reconstruction selectors. Mirrors the live `select case` in !! `init_recon_scheme_2d` (schemes_2d.f90); `weno5` is also the `case default` !! target and the config default. A strict subset of `recon_scheme_names`. character(len=32), parameter, public :: recon_scheme_2d_names(8) = [character(len=32) :: & recon_weno5, recon_weno7, recon_weno9, recon_mp5, & recon_teno5, recon_muscl, recon_upwind1, recon_upwind2] !> Valid 2D time-integration selectors. Mirrors `resolve_time_scheme_2d` !! (time_integration_2d.f90): explicit `euler`, `ssprk22`, `rk4`, and !! `ssprk54` (R2: shared stepper_kernels adapters), plus `rk3` — the !! user-facing name for the `case default` target and the config default. character(len=16), parameter, public :: time_scheme_2d_names(5) = [character(len=16) :: & time_rk3, time_euler, time_ssprk22, & time_rk4, time_ssprk54] !> Valid 2D initial-condition / problem-type selectors (extended as ICs are !! added). These are 2D-only and disjoint from the 1D `problem_type_names`. character(len=32), parameter, public :: problem_type_2d_names(6) = [character(len=32) :: & problem_2d_uniform, problem_2d_isentropic_vortex, & problem_2d_sedov, problem_2d_toro_explosion, & problem_2d_riemann2d_config3, problem_2d_freestream] !> Valid 2D per-edge boundary-condition selectors. Mirrors the live 2D BC !! dispatch (boundary_2d.f90). A strict subset of `boundary_condition_names`. character(len=32), parameter, public :: bc_2d_names(5) = [character(len=32) :: & bc_periodic, bc_reflecting, bc_outflow, bc_supersonic_inlet, & bc_farfield] public :: is_valid_flux_scheme, is_valid_recon_scheme, is_valid_time_scheme public :: is_valid_limiter, is_valid_problem_type, is_valid_boundary_condition public :: is_valid_char_proj_mode, is_valid_nrbc_mode, is_valid_hybrid_sensor public :: is_valid_method public :: join_token_list, token_in_list public :: recon_uses_char_proj_by_default, is_fds_flux_scheme contains pure logical function is_valid_flux_scheme(scheme) character(len=*), intent(in) :: scheme is_valid_flux_scheme = token_in_list(scheme, flux_scheme_names) end function is_valid_flux_scheme pure logical function is_valid_recon_scheme(scheme) character(len=*), intent(in) :: scheme is_valid_recon_scheme = token_in_list(scheme, recon_scheme_names) end function is_valid_recon_scheme pure logical function is_valid_time_scheme(scheme) character(len=*), intent(in) :: scheme is_valid_time_scheme = token_in_list(scheme, time_scheme_names) end function is_valid_time_scheme pure logical function is_valid_limiter(limiter) character(len=*), intent(in) :: limiter is_valid_limiter = token_in_list(limiter, limiter_names) end function is_valid_limiter pure logical function is_valid_problem_type(problem_type) character(len=*), intent(in) :: problem_type is_valid_problem_type = token_in_list(problem_type, problem_type_names) end function is_valid_problem_type pure logical function is_valid_boundary_condition(bc_type) character(len=*), intent(in) :: bc_type is_valid_boundary_condition = token_in_list(bc_type, boundary_condition_names) end function is_valid_boundary_condition pure logical function is_valid_char_proj_mode(mode) character(len=*), intent(in) :: mode is_valid_char_proj_mode = token_in_list(mode, char_proj_mode_names) end function is_valid_char_proj_mode pure logical function is_valid_nrbc_mode(mode) character(len=*), intent(in) :: mode is_valid_nrbc_mode = token_in_list(mode, nrbc_mode_names) end function is_valid_nrbc_mode pure logical function is_valid_hybrid_sensor(sensor_name) character(len=*), intent(in) :: sensor_name is_valid_hybrid_sensor = token_in_list(sensor_name, hybrid_sensor_names) end function is_valid_hybrid_sensor pure logical function is_valid_method(method) character(len=*), intent(in) :: method is_valid_method = token_in_list(method, method_names) end function is_valid_method pure logical function recon_uses_char_proj_by_default(scheme) character(len=*), intent(in) :: scheme select case (trim(scheme)) case (recon_weno5, recon_weno5z, recon_weno_cu6, recon_weno7, recon_weno9, & recon_weno11, recon_eno3, recon_mp5, recon_teno5) recon_uses_char_proj_by_default = .true. case default recon_uses_char_proj_by_default = .false. end select end function recon_uses_char_proj_by_default pure logical function is_fds_flux_scheme(scheme) character(len=*), intent(in) :: scheme select case (trim(scheme)) case (flux_ausm_plus, flux_hll, flux_hllc, flux_roe, flux_rusanov) is_fds_flux_scheme = .true. case default is_fds_flux_scheme = .false. end select end function is_fds_flux_scheme function join_token_list(valid_values) result(joined) character(len=*), intent(in) :: valid_values(:) character(len=512) :: joined integer :: i joined = '' do i = 1, size(valid_values) if (i > 1) then joined = trim(joined)//' '//trim(valid_values(i)) else joined = trim(valid_values(i)) end if end do end function join_token_list pure logical function token_in_list(token, valid_values) character(len=*), intent(in) :: token character(len=*), intent(in) :: valid_values(:) integer :: i token_in_list = .false. do i = 1, size(valid_values) if (trim(token) == trim(valid_values(i))) then token_in_list = .true. return end if end do end function token_in_list end module option_registry