!> @file config_dim.f90 !> @brief Dimension pre-pass: read only the &control group from a namelist file. !! !! The unified namelist surface declares the problem dimension once, at the top, !! in a `&control` group: `dim = 1 | 2 | 3`. This module reads ONLY that group so !! the `euler` launcher can route to the right solver before the dimension-specific !! config reader runs. A file with no `&control` group defaults to `dim = 1`, so !! every pre-existing 1D namelist keeps working unchanged. module config_dim use, intrinsic :: iso_fortran_env, only: iostat_end implicit none private public :: read_dim contains !> Read the problem dimension from the &control group of `filename`. !! !! @param[in] filename path to the namelist file !! @param[out] dim 1, 2, or 3 (defaults to 1 when &control is absent) !! @param[out] ok .true. on success; .false. on open/parse/range error !! @param[out] message human-readable error when ok is .false. subroutine read_dim(filename, dim, ok, message) character(len=*), intent(in) :: filename integer, intent(out) :: dim logical, intent(out) :: ok character(len=*), intent(out) :: message integer :: u, ios, cstat namelist /control/ dim ok = .false. message = '' dim = 1 ! default when &control is absent open (newunit=u, file=filename, status='old', action='read', iostat=ios) if (ios /= 0) then message = 'config_dim: cannot open "'//trim(filename)//'"' return end if rewind (u) ! defensive: ensure position at start before the single group read read (u, nml=control, iostat=ios) close (u, iostat=cstat) if (ios /= 0 .and. ios /= iostat_end) then message = 'config_dim: parse error in &control namelist' return end if if (dim < 1 .or. dim > 3) then write (message, '(a,i0,a)') 'config_dim: dim must be 1, 2, or 3 (got ', dim, ')' return end if ok = .true. end subroutine read_dim end module config_dim