smartpars

August 5, 2025 ยท View on GitHub

Fortran package to work with parameters

Getting Started

Define user's parameter type

For each parameter, the following must be specified

  • integer / real
  • scalar / vector (for vectors number of components must be specified)
  • name (keyword in file or code)
  • default value for the parameter

Use the following code template to define the new user type "localpars_t"

 module localpars_mod
    use smartpars_mod, only : smartpars_at, rule_t, DP
    implicit none (type, external)
    private

    ! ***Step 1***
    ! We define the following parameters:
    ! pis, prs, sis, srs
    ! ...are scalar integer and real parameters
    ! piarr3, prarr2, siarr3, srarr2 
    ! ...are vector integer and real parameter
    !
    ! These pointers will be linked
    ! during initialization with internals of the object.
    ! User then can access and modify these pointers at will
    !
    type, public, extends(smartpars_at) :: localpars_t
      integer, pointer  :: pis, piarr3(:)
      real(DP), pointer :: prs, prarr2(:)
      integer, pointer  :: sis, siarr3(:)
      real(DP), pointer :: srs, srarr2(:)
    contains
      procedure :: localize
    end type

  contains

    ! ***Step 2***
    ! User should provide this procedure defining the individual
    ! parameters. It will be run during initialization. User is
    ! not suppossed to run it directly
    pure subroutine localize(this)
      class(localpars_t), intent(inout), target :: this

      ! scalar parameters without default values
      call this%addrule(rule_t('pis'), this%pis)
      call this%addrule(rule_t('prs'), this%prs)

      ! vector parameters without default values,
      ! vector size must be provided
      call this%addrule(rule_t('piarr3'), 3, this%piarr3)
      call this%addrule(rule_t('prarr2'), 2, this%prarr2)

      ! parameters with default values,
      ! the number of default values must correspond to size of vectors
      call this%addrule(rule_t('sis', 15), this%sis)
      call this%addrule(rule_t('srs', 30.0_DP), this%srs)
      call this%addrule(rule_t('siarr3',[10,20,30]), 3, this%siarr3)
      call this%addrule(rule_t('srarr2',[42._DP, 69._DP]), 2, this%srarr2)
    end subroutine localize
  end module localpars_mod

Use user parameter type

Declare and initialize structures "pars"

    use localpars_mod, only : pars_t => localpars_t
    :
    type(pars_t) :: pars, pars2
    :
    call pars%init()

Set default values to components with default values

    call pars%setdefvals()

Load values of components from the file

    character(len=:), allocatable :: errmsg
    :
    call pars%loadfromfile('myfile.txt',errmsg=errmsg,overwrite=.true.)
    if (allocated(errmsg)) then
      print *, 'ERROR -'//errmsg
      stop 1
    else
      print *, 'Loading ok...'
    end if

Check if all components are defined

    print *, 'All defined? ', pars%all_defined()

Dump values to specified unit

    call pars%write2unit(output_unit, include_undefined=.true.)

Copy to another structure and show

    pars2 = pars
    call pars2%print()

Use parameter values in the code

You can directly access the pointers in own code

  x = pars%pis
  pars%pis = 11