!===============================================================================
!
! module_input.F90
!
!-------------------------------------------------------------------------------
!
! Copyright (C) 2003-2017 Hinnerk Stueben, Yoshifumi Nakamura
!
! This file is part of BQCD -- Berlin Quantum ChromoDynamics program
!
! BQCD is free software: you can redistribute it and/or modify
! it under the terms of the GNU General Public License as published by
! the Free Software Foundation, either version 3 of the License, or
! (at your option) any later version.
!
! BQCD is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
! GNU General Public License for more details.
!
! You should have received a copy of the GNU General Public License
! along with BQCD.  If not, see <http://www.gnu.org/licenses/>.
!
!-------------------------------------------------------------------------------
!
! Simple module to read "keyword value" formatted input.  The keywords
! are defined in "module_input.h" together with a type definition and a
! default value.  The input is stored in the structure "input".  The
! components are called "input%<keyword>".
!
! New input/keywords can be added or modified in "module_input.h".  It
! suffices to modify "module_input.h" execpt for input of type
! INPUT_ARRAY_ENSEMBLES for which (re)allocation and initialisation
! routines have to be provided in this file (in subroutines "input_allocate"
! and "input_reallocate").
!
!// 2006-07-11: input lines beginning with # are ignored
!// 2006-09-19: PERCENT macro to be used with fpp (Fortran preprocessing) script
!// 2008-08-28: INPUT_OR introduced for preprocessing Fortran's .or. with icc
!// 2009-05-13: PERCENT -> FORTRAN_PERCENT
!//             INPUT_OR -> FORTRAN_OR
!
!-------------------------------------------------------------------------------
! Added some structures to handle PF and tRHMC
!
! Editor: Taylor Haar
! Last modified: 01/05/2017
!-------------------------------------------------------------------------------
# include "defs.h"

# define INPUT_ARRAY_DIM integer, dimension(DIM)
# define INPUT_ARRAY_ENSEMBLES character(para_len), dimension(:), pointer
# define INPUT_DEFAULT_ENSEMBLES 1

!-------------------------------------------------------------------------------
module module_input

  implicit none

  !-----------------------------------------------------------------------------
  public :: type_input  ! data structure declaration
  public :: input       ! variable containing data structure
  public :: input_init  ! subroutine input_init()
  public :: input_read  ! subroutine input_read(file)
  public :: input_dump  ! subroutine input_dump(unit)
  public :: input_dump_to_string  ! subroutine input_dump_to string(string)
  !-----------------------------------------------------------------------------

  private

  integer, parameter :: comment_len  =  80
  integer, parameter :: keyword_len  =  32
  integer, parameter :: para_len     =  32
  integer, parameter :: word_len     =   8
  integer, parameter :: url_len      = 256
  integer, parameter :: string_len   =  80

  type type_input

REAL :: nf1_kappa(6)
REAL :: nf2_kappa(6)
REAL :: nf1_lambda(6)
REAL :: nf2_lambda(6)
REAL :: nf1_em_charge(6)
REAL :: nf2_em_charge(6)
REAL :: nf2_rho(6,3)
integer :: nf1_kpnpf(6)
integer :: nf1_kpnth(6)
integer :: nf2_dsf(6,4)
integer :: nf1_dsf(6)

! Structures for PFHMC
REAL :: nf2_mu(6)
REAL :: nf2_nu(6)
integer :: nf2_porder(6,3)
FILENAME :: nf2_polyfile(6,3)
integer :: nf2_dsfp(6,3)

integer :: nf1_porder(6,1)
FILENAME :: nf1_polyfile(6,3)
integer :: nf1_dsfp(6,3)

! Structures for tRHMC
integer :: nf1_trunc(6,3)
integer :: nf1_dsft(6,3)

#define INPUT_INPUT(var, type, default) type :: var
#define INPUT_IGNORE(var, type, default) type :: var
#include "module_input.h"

  end type type_input

  type(type_input), save :: input

contains

  !=============================================================================
  subroutine input_init()

    call input_allocate(INPUT_DEFAULT_ENSEMBLES)
    call input_defaults()
  end subroutine input_init

  !-----------------------------------------------------------------------------
  subroutine input_read(flags)

    use typedef_flags
    type(type_flags), intent(in) :: flags
    integer :: iostat
    character(keyword_len) :: keyword

    call input_init()

    open(UINPUT, file = trim(flags%input), action = "read", status = "old")

    ! check file format
    read(UINPUT, *) keyword
    if (keyword == ">BeginConfInfoHeader") then  ! input is conf_info format
       CHECK(flags%convert_to_ildg)              ! works with --convert-to-ildg
       call pos_keyword(UINPUT, ">BeginInput")   ! search begin of Input section
       read(UINPUT,*)
    else
       CHECK(.not. flags%convert_to_ildg)        ! does not work with --convert-to-ildg
       backspace(UINPUT)
    endif

    ! read input
    do
       read(UINPUT, *, iostat = iostat) keyword
       if (iostat /= 0) exit             ! end of file
       if (keyword(1:1) == '#') cycle    ! comment
       if (keyword == ">EndInput") exit  ! end of Input section in a conf_info file
       backspace(UINPUT)
       select case (keyword)

#undef INPUT_INPUT
#define INPUT_INPUT(var, type, default) \
              case (#var); read(UINPUT, *) keyword, STRCAT3(input,FORTRAN_PERCENT,var)
#undef INPUT_IGNORE
#define INPUT_IGNORE(var, type, default) \
              case(#var); read(UINPUT, *); call warn("input_read(): " FORTRAN_STRCAT #var FORTRAN_STRCAT " ignored")
#include "module_input.h"
              case default
                 call die("input_read(): " // trim(keyword)  &
                                           // ": unknown keyword")
       end select

       if (keyword == "ensembles") then
          call input_reallocate(input%ensembles)
       endif

    enddo
    close(UINPUT)

    input%nf1_kappa(1) = input%nf1_kappa1
    input%nf1_kappa(2) = input%nf1_kappa2
    input%nf1_kappa(3) = input%nf1_kappa3
    input%nf1_kappa(4) = input%nf1_kappa4
    input%nf1_kappa(5) = input%nf1_kappa5
    input%nf1_kappa(6) = input%nf1_kappa6
    input%nf2_kappa(1) = input%nf2_kappa1
    input%nf2_kappa(2) = input%nf2_kappa2
    input%nf2_kappa(3) = input%nf2_kappa3
    input%nf2_kappa(4) = input%nf2_kappa4
    input%nf2_kappa(5) = input%nf2_kappa5
    input%nf2_kappa(6) = input%nf2_kappa6

    input%nf1_kpnpf(1) = input%nf1_kappa1npf
    input%nf1_kpnpf(2) = input%nf1_kappa2npf
    input%nf1_kpnpf(3) = input%nf1_kappa3npf
    input%nf1_kpnpf(4) = input%nf1_kappa4npf
    input%nf1_kpnpf(5) = input%nf1_kappa5npf
    input%nf1_kpnpf(6) = input%nf1_kappa6npf
    input%nf1_kpnth(1) = input%nf1_kappa1nth
    input%nf1_kpnth(2) = input%nf1_kappa2nth
    input%nf1_kpnth(3) = input%nf1_kappa3nth
    input%nf1_kpnth(4) = input%nf1_kappa4nth
    input%nf1_kpnth(5) = input%nf1_kappa5nth
    input%nf1_kpnth(6) = input%nf1_kappa6nth

    input%nf1_lambda(1) = input%nf1_lambda1
    input%nf1_lambda(2) = input%nf1_lambda2
    input%nf1_lambda(3) = input%nf1_lambda3
    input%nf1_lambda(4) = input%nf1_lambda4
    input%nf1_lambda(5) = input%nf1_lambda5
    input%nf1_lambda(6) = input%nf1_lambda6
    input%nf2_lambda(1) = input%nf2_lambda1
    input%nf2_lambda(2) = input%nf2_lambda2
    input%nf2_lambda(3) = input%nf2_lambda3
    input%nf2_lambda(4) = input%nf2_lambda4
    input%nf2_lambda(5) = input%nf2_lambda5
    input%nf2_lambda(6) = input%nf2_lambda6

    input%nf1_em_charge(1) = dble(input%nf1_em_charge1_x3) / THREE
    input%nf1_em_charge(2) = dble(input%nf1_em_charge2_x3) / THREE
    input%nf1_em_charge(3) = dble(input%nf1_em_charge3_x3) / THREE
    input%nf1_em_charge(4) = dble(input%nf1_em_charge4_x3) / THREE
    input%nf1_em_charge(5) = dble(input%nf1_em_charge5_x3) / THREE
    input%nf1_em_charge(6) = dble(input%nf1_em_charge6_x3) / THREE
    input%nf2_em_charge(1) = dble(input%nf2_em_charge1_x3) / THREE
    input%nf2_em_charge(2) = dble(input%nf2_em_charge2_x3) / THREE
    input%nf2_em_charge(3) = dble(input%nf2_em_charge3_x3) / THREE
    input%nf2_em_charge(4) = dble(input%nf2_em_charge4_x3) / THREE
    input%nf2_em_charge(5) = dble(input%nf2_em_charge5_x3) / THREE
    input%nf2_em_charge(6) = dble(input%nf2_em_charge6_x3) / THREE

    input%nf2_rho(1,1) = input%nf2_kappa1h1
    input%nf2_rho(2,1) = input%nf2_kappa2h1
    input%nf2_rho(3,1) = input%nf2_kappa3h1
    input%nf2_rho(4,1) = input%nf2_kappa4h1
    input%nf2_rho(5,1) = input%nf2_kappa5h1
    input%nf2_rho(6,1) = input%nf2_kappa6h1
    input%nf2_rho(1,2) = input%nf2_kappa1h2
    input%nf2_rho(2,2) = input%nf2_kappa2h2
    input%nf2_rho(3,2) = input%nf2_kappa3h2
    input%nf2_rho(4,2) = input%nf2_kappa4h2
    input%nf2_rho(5,2) = input%nf2_kappa5h2
    input%nf2_rho(6,2) = input%nf2_kappa6h2
    input%nf2_rho(1,3) = input%nf2_kappa1h3
    input%nf2_rho(2,3) = input%nf2_kappa2h3
    input%nf2_rho(3,3) = input%nf2_kappa3h3
    input%nf2_rho(4,3) = input%nf2_kappa4h3
    input%nf2_rho(5,3) = input%nf2_kappa5h3
    input%nf2_rho(6,3) = input%nf2_kappa6h3

    input%nf2_dsf(1,1) = input%hmc_dsf_k11
    input%nf2_dsf(1,2) = input%hmc_dsf_k12
    input%nf2_dsf(1,3) = input%hmc_dsf_k13
    input%nf2_dsf(1,4) = input%hmc_dsf_k14
    input%nf2_dsf(2,1) = input%hmc_dsf_k21
    input%nf2_dsf(2,2) = input%hmc_dsf_k22
    input%nf2_dsf(2,3) = input%hmc_dsf_k23
    input%nf2_dsf(2,4) = input%hmc_dsf_k24
    input%nf2_dsf(3,1) = input%hmc_dsf_k31
    input%nf2_dsf(3,2) = input%hmc_dsf_k32
    input%nf2_dsf(3,3) = input%hmc_dsf_k33
    input%nf2_dsf(3,4) = input%hmc_dsf_k34
    input%nf2_dsf(4,1) = input%hmc_dsf_k41
    input%nf2_dsf(4,2) = input%hmc_dsf_k42
    input%nf2_dsf(4,3) = input%hmc_dsf_k43
    input%nf2_dsf(4,4) = input%hmc_dsf_k44
    input%nf2_dsf(5,1) = input%hmc_dsf_k51
    input%nf2_dsf(5,2) = input%hmc_dsf_k52
    input%nf2_dsf(5,3) = input%hmc_dsf_k53
    input%nf2_dsf(5,4) = input%hmc_dsf_k54
    input%nf2_dsf(6,1) = input%hmc_dsf_k61
    input%nf2_dsf(6,2) = input%hmc_dsf_k62
    input%nf2_dsf(6,3) = input%hmc_dsf_k63
    input%nf2_dsf(6,4) = input%hmc_dsf_k64

    input%nf1_dsf(1)   = input%hmc_dsfr_k1
    input%nf1_dsf(2)   = input%hmc_dsfr_k2
    input%nf1_dsf(3)   = input%hmc_dsfr_k3
    input%nf1_dsf(4)   = input%hmc_dsfr_k4
    input%nf1_dsf(5)   = input%hmc_dsfr_k5
    input%nf1_dsf(6)   = input%hmc_dsfr_k6

    ! Read in poly input params

    ! nf=2 Chebyshev approx parameters
    input%nf2_mu(1) = input%nf2_k1_mu
    input%nf2_mu(2) = input%nf2_k2_mu
    input%nf2_mu(3) = input%nf2_k3_mu
    input%nf2_mu(4) = input%nf2_k4_mu
    input%nf2_mu(5) = input%nf2_k5_mu
    input%nf2_mu(6) = input%nf2_k6_mu
    input%nf2_nu(1) = input%nf2_k1_nu
    input%nf2_nu(2) = input%nf2_k2_nu
    input%nf2_nu(3) = input%nf2_k3_nu
    input%nf2_nu(4) = input%nf2_k4_nu
    input%nf2_nu(5) = input%nf2_k5_nu
    input%nf2_nu(6) = input%nf2_k6_nu

    ! Polynomial orders
    input%nf2_porder(1,1) = input%nf2_k1p1
    input%nf2_porder(2,1) = input%nf2_k2p1
    input%nf2_porder(3,1) = input%nf2_k3p1
    input%nf2_porder(4,1) = input%nf2_k4p1
    input%nf2_porder(5,1) = input%nf2_k5p1
    input%nf2_porder(6,1) = input%nf2_k6p1

    input%nf2_porder(1,2) = input%nf2_k1p2
    input%nf2_porder(2,2) = input%nf2_k2p2
    input%nf2_porder(3,2) = input%nf2_k3p2
    input%nf2_porder(4,2) = input%nf2_k4p2
    input%nf2_porder(5,2) = input%nf2_k5p2
    input%nf2_porder(6,2) = input%nf2_k6p2

    input%nf2_porder(1,3) = input%nf2_k1p3
    input%nf2_porder(2,3) = input%nf2_k2p3
    input%nf2_porder(3,3) = input%nf2_k3p3
    input%nf2_porder(4,3) = input%nf2_k4p3
    input%nf2_porder(5,3) = input%nf2_k5p3
    input%nf2_porder(6,3) = input%nf2_k6p3

    ! Polynomial time-scales
    input%nf2_dsfp(1,1) = input%hmc_dsfp_k11
    input%nf2_dsfp(2,1) = input%hmc_dsfp_k21
    input%nf2_dsfp(3,1) = input%hmc_dsfp_k31
    input%nf2_dsfp(4,1) = input%hmc_dsfp_k41
    input%nf2_dsfp(5,1) = input%hmc_dsfp_k51
    input%nf2_dsfp(6,1) = input%hmc_dsfp_k61

    input%nf2_dsfp(1,2) = input%hmc_dsfp_k12
    input%nf2_dsfp(2,2) = input%hmc_dsfp_k22
    input%nf2_dsfp(3,2) = input%hmc_dsfp_k32
    input%nf2_dsfp(4,2) = input%hmc_dsfp_k42
    input%nf2_dsfp(5,2) = input%hmc_dsfp_k52
    input%nf2_dsfp(6,2) = input%hmc_dsfp_k62

    input%nf2_dsfp(1,3) = input%hmc_dsfp_k13
    input%nf2_dsfp(2,3) = input%hmc_dsfp_k23
    input%nf2_dsfp(3,3) = input%hmc_dsfp_k33
    input%nf2_dsfp(4,3) = input%hmc_dsfp_k43
    input%nf2_dsfp(5,3) = input%hmc_dsfp_k53
    input%nf2_dsfp(6,3) = input%hmc_dsfp_k63

    ! PFRHMC params
    input%nf1_porder(1,1) = input%nf1_k1p1
    input%nf1_porder(2,1) = input%nf1_k2p1
    input%nf1_porder(3,1) = input%nf1_k3p1
    input%nf1_porder(4,1) = input%nf1_k4p1
    input%nf1_porder(5,1) = input%nf1_k5p1
    input%nf1_porder(6,1) = input%nf1_k6p1

    ! Polynomial filter files: double flavour
    input%nf2_polyfile(1,1) = input%nf2_k1p1file
    input%nf2_polyfile(2,1) = input%nf2_k2p1file
    input%nf2_polyfile(3,1) = input%nf2_k3p1file
    input%nf2_polyfile(4,1) = input%nf2_k4p1file
    input%nf2_polyfile(5,1) = input%nf2_k5p1file
    input%nf2_polyfile(6,1) = input%nf2_k6p1file

    input%nf2_polyfile(1,2) = input%nf2_k1p2file
    input%nf2_polyfile(2,2) = input%nf2_k2p2file
    input%nf2_polyfile(3,2) = input%nf2_k3p2file
    input%nf2_polyfile(4,2) = input%nf2_k4p2file
    input%nf2_polyfile(5,2) = input%nf2_k5p2file
    input%nf2_polyfile(6,2) = input%nf2_k6p2file

    input%nf2_polyfile(1,3) = input%nf2_k1p3file
    input%nf2_polyfile(2,3) = input%nf2_k2p3file
    input%nf2_polyfile(3,3) = input%nf2_k3p3file
    input%nf2_polyfile(4,3) = input%nf2_k4p3file
    input%nf2_polyfile(5,3) = input%nf2_k5p3file
    input%nf2_polyfile(6,3) = input%nf2_k6p3file

    ! Polynomial filter files: single flavour
    input%nf1_polyfile(1,1) = input%nf1_k1p1file
    input%nf1_polyfile(2,1) = input%nf1_k2p1file
    input%nf1_polyfile(3,1) = input%nf1_k3p1file
    input%nf1_polyfile(4,1) = input%nf1_k4p1file
    input%nf1_polyfile(5,1) = input%nf1_k5p1file
    input%nf1_polyfile(6,1) = input%nf1_k6p1file

    input%nf1_polyfile(1,2) = input%nf1_k1p2file
    input%nf1_polyfile(2,2) = input%nf1_k2p2file
    input%nf1_polyfile(3,2) = input%nf1_k3p2file
    input%nf1_polyfile(4,2) = input%nf1_k4p2file
    input%nf1_polyfile(5,2) = input%nf1_k5p2file
    input%nf1_polyfile(6,2) = input%nf1_k6p2file

    input%nf1_polyfile(1,3) = input%nf1_k1p3file
    input%nf1_polyfile(2,3) = input%nf1_k2p3file
    input%nf1_polyfile(3,3) = input%nf1_k3p3file
    input%nf1_polyfile(4,3) = input%nf1_k4p3file
    input%nf1_polyfile(5,3) = input%nf1_k5p3file
    input%nf1_polyfile(6,3) = input%nf1_k6p3file

    ! Single flavour poly time scales
    input%nf1_dsfp(1,1) = input%hmc_dsfr_k1p1
    input%nf1_dsfp(2,1) = input%hmc_dsfr_k2p1
    input%nf1_dsfp(3,1) = input%hmc_dsfr_k3p1
    input%nf1_dsfp(4,1) = input%hmc_dsfr_k4p1
    input%nf1_dsfp(5,1) = input%hmc_dsfr_k5p1
    input%nf1_dsfp(6,1) = input%hmc_dsfr_k6p1

    input%nf1_dsfp(1,2) = input%hmc_dsfr_k1p2
    input%nf1_dsfp(2,2) = input%hmc_dsfr_k2p2
    input%nf1_dsfp(3,2) = input%hmc_dsfr_k3p2
    input%nf1_dsfp(4,2) = input%hmc_dsfr_k4p2
    input%nf1_dsfp(5,2) = input%hmc_dsfr_k5p2
    input%nf1_dsfp(6,2) = input%hmc_dsfr_k6p2

    input%nf1_dsfp(1,3) = input%hmc_dsfr_k1p3
    input%nf1_dsfp(2,3) = input%hmc_dsfr_k2p3
    input%nf1_dsfp(3,3) = input%hmc_dsfr_k3p3
    input%nf1_dsfp(4,3) = input%hmc_dsfr_k4p3
    input%nf1_dsfp(5,3) = input%hmc_dsfr_k5p3
    input%nf1_dsfp(6,3) = input%hmc_dsfr_k6p3

    ! tRHMC params
    input%nf1_trunc(1,1) = input%nf1_k1_trunc1
    input%nf1_trunc(1,2) = input%nf1_k1_trunc2
    input%nf1_trunc(1,3) = input%nf1_k1_trunc3
    input%nf1_trunc(2,1) = input%nf1_k2_trunc1
    input%nf1_trunc(2,2) = input%nf1_k2_trunc2
    input%nf1_trunc(2,3) = input%nf1_k2_trunc3
    input%nf1_trunc(3,1) = input%nf1_k3_trunc1
    input%nf1_trunc(3,2) = input%nf1_k3_trunc2
    input%nf1_trunc(3,3) = input%nf1_k3_trunc3
    input%nf1_trunc(4,1) = input%nf1_k4_trunc1
    input%nf1_trunc(4,2) = input%nf1_k4_trunc2
    input%nf1_trunc(4,3) = input%nf1_k4_trunc3
    input%nf1_trunc(5,1) = input%nf1_k5_trunc1
    input%nf1_trunc(5,2) = input%nf1_k5_trunc2
    input%nf1_trunc(5,3) = input%nf1_k5_trunc3
    input%nf1_trunc(6,1) = input%nf1_k6_trunc1
    input%nf1_trunc(6,2) = input%nf1_k6_trunc2
    input%nf1_trunc(6,3) = input%nf1_k6_trunc3

    input%nf1_dsft(1,1) = input%hmc_dsfr_k1t1
    input%nf1_dsft(1,2) = input%hmc_dsfr_k1t2
    input%nf1_dsft(1,3) = input%hmc_dsfr_k1t3
    input%nf1_dsft(2,1) = input%hmc_dsfr_k2t1
    input%nf1_dsft(2,2) = input%hmc_dsfr_k2t2
    input%nf1_dsft(2,3) = input%hmc_dsfr_k2t3
    input%nf1_dsft(3,1) = input%hmc_dsfr_k3t1
    input%nf1_dsft(3,2) = input%hmc_dsfr_k3t2
    input%nf1_dsft(3,3) = input%hmc_dsfr_k3t3
    input%nf1_dsft(4,1) = input%hmc_dsfr_k4t1
    input%nf1_dsft(4,2) = input%hmc_dsfr_k4t2
    input%nf1_dsft(4,3) = input%hmc_dsfr_k4t3
    input%nf1_dsft(5,1) = input%hmc_dsfr_k5t1
    input%nf1_dsft(5,2) = input%hmc_dsfr_k5t2
    input%nf1_dsft(5,3) = input%hmc_dsfr_k5t3
    input%nf1_dsft(6,1) = input%hmc_dsfr_k6t1
    input%nf1_dsft(6,2) = input%hmc_dsfr_k6t2
    input%nf1_dsft(6,3) = input%hmc_dsfr_k6t3

  end subroutine input_read

  !-----------------------------------------------------------------------------
  subroutine input_dump(unit)
    integer :: unit
    character(4) :: t
    character(keyword_len) :: k

    if (.not. associated(input%beta)) call input_init()

#undef INPUT_IGNORE
#define INPUT_IGNORE(var, type, default)

#undef INPUT_INPUT
#define INPUT_INPUT(var, type, default) t= #type; \
k= #var; \
if (t=="char" FORTRAN_OR t=="FILE" FORTRAN_OR k=="start_info_file") then; \
call dump_string(unit, k, STRCAT3(input,FORTRAN_PERCENT,var)); else; \
write(unit,*) k, " ", STRCAT3(input,FORTRAN_PERCENT,var); endif
#include "module_input.h"

  end subroutine input_dump

  !-----------------------------------------------------------------------------
  subroutine input_dump_to_string(s)
    character(*) :: s
    character(4) :: t
    character(keyword_len) :: k
    character(256) :: line
    integer :: ps, len_s, len_line

    character(1), parameter :: ascii_newline = achar(10)
    character(*), parameter :: msg = "input_dump_to_string(): string too short"

    if (.not. associated(input%beta)) call input_init()

    len_s = len(s)
    s = " "
    ps = 0

#undef INPUT_IGNORE
#define INPUT_IGNORE(var, type, default)

#undef INPUT_INPUT
#define INPUT_INPUT(var, type, default) t= #type; \
k= #var; \
if (t=="char" FORTRAN_OR t=="FILE" FORTRAN_OR k=="start_info_file") then; \
call dump_string_to_string(line, k, STRCAT3(input,FORTRAN_PERCENT,var)); else; \
write(line,*) k, " ", STRCAT3(input,FORTRAN_PERCENT,var); endif; \
len_line = len(trim(line)) + 1; \
if (ps + len_line > len_s) call die(msg); \
s(ps+1:) = trim(line); \
ps = ps + len_line; \
s(ps:ps) = ascii_newline

#include "module_input.h"

  end subroutine input_dump_to_string

  !-----------------------------------------------------------------------------
  subroutine input_defaults()

#undef INPUT_INPUT
#define INPUT_INPUT(var, type, default) STRCAT3(input,FORTRAN_PERCENT,var) = default
#undef INPUT_IGNORE
#define INPUT_IGNORE(var, type, default) STRCAT3(input,FORTRAN_PERCENT,var) = default
#include "module_input.h"

    !!read(input%kappa_strange(1), *) input%nf1_kappa1
    !!read(input%kappa(1), *)         input%nf2_kappa1

    input%nf1_em_charge(1) = input%nf1_em_charge1_x3 / THREE
    input%nf1_em_charge(2) = input%nf1_em_charge2_x3 / THREE
    input%nf1_em_charge(3) = input%nf1_em_charge3_x3 / THREE
    input%nf1_em_charge(4) = input%nf1_em_charge4_x3 / THREE
    input%nf1_em_charge(5) = input%nf1_em_charge5_x3 / THREE
    input%nf1_em_charge(6) = input%nf1_em_charge6_x3 / THREE
    input%nf2_em_charge(1) = input%nf2_em_charge1_x3 / THREE
    input%nf2_em_charge(2) = input%nf2_em_charge2_x3 / THREE
    input%nf2_em_charge(3) = input%nf2_em_charge3_x3 / THREE
    input%nf2_em_charge(4) = input%nf2_em_charge4_x3 / THREE
    input%nf2_em_charge(5) = input%nf2_em_charge5_x3 / THREE
    input%nf2_em_charge(6) = input%nf2_em_charge6_x3 / THREE

  end subroutine input_defaults

  !-----------------------------------------------------------------------------
  subroutine input_allocate(size)

    integer :: size

    allocate(input%beta(size))
    allocate(input%beta_qed(size))
    allocate(input%kappa_axion(size))
    allocate(input%finv_axion(size))
    allocate(input%kappa(size))
    allocate(input%kappa_strange(size))
    allocate(input%csw(size))
    allocate(input%h(size))
    allocate(input%hmc_trajectory_length(size))
    allocate(input%hmc_steps(size))
    allocate(input%hmc_m_scale(size))
    allocate(input%hmc_m_scale2(size))
    allocate(input%hmc_m_scale3(size))
    allocate(input%hmc_m_scale4(size))
    allocate(input%hmc_m_scale5(size))
    allocate(input%n_stout(size))
    allocate(input%alpha(size))
    allocate(input%theta(size))
    allocate(input%chemi(size))
    allocate(input%chemi_i(size))
    allocate(input%start_info_file(size))

    input%beta = "0.0"
    input%beta_qed = "0.0"
    input%kappa_axion = "0.0"
    input%finv_axion = "0.0"
    input%kappa = "0.0"
    input%kappa_strange = "0.0"
    input%csw = "0.0"
    input%h = "0.0"
    input%hmc_trajectory_length = "1"
    input%hmc_steps = "0"
    input%hmc_m_scale = "1"
    input%hmc_m_scale2 = "1"
    input%hmc_m_scale3 = "1"
    input%hmc_m_scale4 = "1"
    input%hmc_m_scale5 = "1"
    input%n_stout = "0"
    input%alpha = "0.0"
    input%theta = "0.0"
    input%chemi = "0.0"
    input%chemi_i = "0.0"
    input%start_info_file = ""

  end subroutine input_allocate


  !-----------------------------------------------------------------------------
  subroutine input_reallocate(size)

    integer :: size

    if (size > INPUT_DEFAULT_ENSEMBLES) then
       deallocate(input%beta)
       deallocate(input%beta_qed)
       deallocate(input%kappa_axion)
       deallocate(input%finv_axion)
       deallocate(input%kappa)
       deallocate(input%kappa_strange)
       deallocate(input%csw)
       deallocate(input%h)
       deallocate(input%hmc_trajectory_length)
       deallocate(input%hmc_steps)
       deallocate(input%hmc_m_scale)
       deallocate(input%hmc_m_scale2)
       deallocate(input%hmc_m_scale3)
       deallocate(input%hmc_m_scale4)
       deallocate(input%hmc_m_scale5)
       deallocate(input%n_stout)
       deallocate(input%alpha)
       deallocate(input%theta)
       deallocate(input%chemi)
       deallocate(input%chemi_i)
       deallocate(input%start_info_file)

       call input_allocate(size)
    endif
  end subroutine input_reallocate

end module module_input
!===============================================================================
