Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

soft code parameters in f.90 code 1

Status
Not open for further replies.

DustBunnie

Technical User
Jan 10, 2011
9
CA
Hello FORTRAN Gurus,
I have written a program, which I have used for different study areas. Currently the code has 30 (or more) integer parameters that are used to, read input files, allocate arrays, carry out calculations, and name output files. In the past I have changed the input parameters in an 'include file', recompiled the program and incorporated the 'Include para.inc' statement in every program, subroutine and module. I'd like to write some code that would allow these 30 parameters to be input from an external file so that the code does not have to be recompiled every time I use the program.
First, is this possible? If it were possible, how would I go about it?
All suggestions welcome.
I am using the Intel Visual FORTRAN 9.1 compiler.
I'm enclosing an editted version of the code as it is you give some idea as to what I have been doing.
Thank you for your time.
Code:
! Parameters (para.inc)
  
! --- longitude and latitude of study area 
      integer, parameter :: nlong=90, nlat=264 ! study area 90 (nlong)columns, 264 (nlat)rows
          
! --- number of days simulated and number of data by day   
		integer, parameter :: nday=1, nhour=24 ! 

Module arrays 
! using this to define all arrays that were in common blocks before
implicit none !changing all implicit to none so all will be declared!!!
      include 'para.inc' !contains parameters
      real(8), Dimension (nlong,nlat,nday,nhour):: wind ! array of 10m wind speeds m/s
 End Module arrays

Program main
use arrays 
Implicit none
 ! --- open 'nhour' output files one for every hour
      call write_output
 ! read in the external input files for wind and soil class and veg files
     call read_data
! --- beginning of computations 
      call begin_comp

      end program main
 
DustBunnie said:
I'd like to write some code that would allow these 30 parameters to be input from an external file so that the code does not have to be recompiled every time I use the program.
First, is this possible? If it were possible, how would I go about it?
Yes it's possible, but you need to write the procedure which parses your config file and extracts the desired parameters.
Some time ago I posted a minimalistic example here:
Maybe, it helps you to start.
 
Thank you mikrom,
Your example does give me a place to start. I'll work on it today.
DustBunnie
 
Mikrom,
The sample code you provided does allow we to read the parameters from an external file (e.g. config_file.txt).
Can you provide an example as to how to create a COMMON BLOCK or some other type of program component so that these parameters can use used in the subroutines, functions, and modules within the program (like the para.inc file in the code posted)?
DustBunnie
 
DustBunnie,
I think, with newer fortran standards (f90 and later) common blocks are now obsolete. If you need to use values from the configuration file as global variables in your program, then IMHO instead of using COMMON, the simpler way is to define them in one module (together with the parsing procedures) and then use the module in your program.

Here are some older threads with examples of global variables with common blocks and modules:
 
I must be thick. I've spent all day trying to create a module that will both 'parse' the input file and make the variable global based on the examples already provided. However, once the code is compiled only the declared parameters in the module have values associated with them. As a matter of fact, it appears that the subroutine parse doesn't even run.
These are the input variables in the file config_file2.txt
Input variables
number of days: 1
number of hours per day: 3
number of columns for study area: 4
number of rows for study area: 5

Here's my code
Code:
module globalvar
implicit none
!declare parameters to be used throughout program
real, parameter :: VK=0.4, z=10 !von Karmen's constant, anemometer height (m) both for u* calculations
! values for array assignments, functions and do loops
integer :: nlong, nlat, nats, nspe, ntype, ninfo, ndays, nhours
contains
subroutine readvar
call parse

end subroutine readvar
        end module Globalvar
    
    program tstread
use globalvar 
    implicit none
    ! Variables all declared in globalvar

    write (*, '(80A)') '*******************************************************' 
    ! Print the parameters found in config file
    write(*,*)
    write(*, '(80A)') 'Configure parameters found:'
    write(*,*) 'Number of days                      =', ndays
    write(*,*) 'Number of hours                     =', nhours
    write(*,*) 'Number of columns for study area    =', nlong
    write(*,*) 'Number of rows for study area       =', nlat
    write(*,*) 'Parameters                          =', z, VK
   
        call subr_pause
    
    end program tstread

Subroutine parse
implicit none
    ! Variables
    integer stat
    character(80) :: line
    integer :: ndays, nhours, nlong, nlat
    
! open file
    open (1, file='config_file2.txt', status='old', iostat=stat)
        if (stat .ne. 0)then
        write (*,*) 'config_file can not be opened'
        close (1) ! close file
        Stop ! stop run
        go to 99
        end if
    write (*, '(80A)') 'config_file2 opened' ! note when compiled code run this does not appear on screen
    ! process config file
    do while (.true.)
        read (1, '(A)', end=99) line
        write(*, '(80A)') line !write on screen, note not written to screen
        Call process_line(adjustl(trim(line)), ndays, nhours, nlong, nlat)
        enddo
        ! close file
    99 continue
        close (1)
        end subroutine parse

subroutine process_line(line, ndays, nhours, nlong, nlat)
! parse settings for config line

!line = input line
character(*), intent(in) :: line
!output parameters
!integer :: ndays, nhours, nlong, nlat
character(30) :: cfg_param

!parameter part of config line
cfg_param = adjustl(line(index(line, ':')+1:))
if (index(line,'number of days') > 0) then
! convert substring into integer number
read (cfg_param, '(I3)') ndays    
else if (index(line, 'number of hours per day') > 0) then
    ! convert substring into integer number
read (cfg_param, '(I3)') nhours
else if (index(line, 'number of columns for study area') > 0) then
    ! convert substring into integer number
read (cfg_param, '(I3)') nlong
else if (index(line, 'number of rows for study area') > 0) then
    ! convert substring into integer number
read (cfg_param, '(I3)') nlat

end if 
end subroutine process_line

subroutine subr_pause
  integer :: cmd_rc ! command return code
  character(*), parameter :: cmd_string = "pause"
  call system (cmd_string, cmd_rc)
end subroutine subr_pause

This is what I get when I run the tstread.exe:
*********************************************

Configure parameters found:
Number of days = 0
Number of hours = 0
Number of columns for study area = 0
Number of rows for study area = 0
Parameters = 10.00000 0.400000


What am I doing wrong?
 
You dind't call the subroutine in the main program
 
Other issue was, that you need to use globalvar not only in the main program, but in the process_line subroutine too, because this subroutine fills the global variables which you then use in your main program.

I changed the code a little bit:

tstread.f95
Code:
[COLOR=#a020f0]module[/color] globalvar
  [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]
  [COLOR=#0000ff]!declare parameters to be used throughout program[/color]
  [COLOR=#0000ff]!von Karmen's constant, anemometer height (m) both for u* calculations[/color]
[COLOR=#2e8b57][b]  real[/b][/color], [COLOR=#2e8b57][b]parameter[/b][/color] :: VK[COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]0.4[/color], z[COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]10[/color]
  [COLOR=#0000ff]! values for array assignments, functions and do loops[/color]
  [COLOR=#2e8b57][b]integer[/b][/color] :: nlong, nlat, nats, nspe, ntype, ninfo, ndays, nhours
[COLOR=#a020f0]end module[/color] globalvar
    
[COLOR=#a020f0]program[/color] tstread
  [COLOR=#a020f0]use[/color] globalvar 
  [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]

  [COLOR=#0000ff]! Parse config file[/color]
  [COLOR=#008080]call[/color] parse_config_file 

  [COLOR=#804040][b]write[/b][/color] ([COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]'(80A)'[/color]) [COLOR=#ff00ff]'*******************************************************'[/color] 
  [COLOR=#0000ff]! Print the parameters found in config file[/color]
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color])
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]'(80A)'[/color]) [COLOR=#ff00ff]'Configure parameters found:'[/color]
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]'Number of days                      ='[/color], ndays
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]'Number of hours                     ='[/color], nhours
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]'Number of columns for study area    ='[/color], nlong
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]'Number of rows for study area       ='[/color], nlat
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]'Parameters                          ='[/color], z, VK 
  [COLOR=#008080]call[/color] subr_pause
    
[COLOR=#a020f0]end program[/color] tstread

[COLOR=#a020f0]subroutine[/color] parse_config_file
  [COLOR=#0000ff]!use globalvar  [/color]
  [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]
  [COLOR=#0000ff]! Variables[/color]
  [COLOR=#2e8b57][b]integer[/b][/color] stat
  [COLOR=#2e8b57][b]character[/b][/color]([COLOR=#ff00ff]80[/color]) :: line
    
  [COLOR=#0000ff]! open file[/color]
  [COLOR=#804040][b]open[/b][/color] ([COLOR=#ff00ff]1[/color], [COLOR=#804040][b]file[/b][/color][COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]'config_file2.txt'[/color], [COLOR=#804040][b]status[/b][/color][COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]'old'[/color], [COLOR=#804040][b]iostat[/b][/color][COLOR=#804040][b]=[/b][/color]stat)
  [COLOR=#804040][b]if[/b][/color] (stat [COLOR=#804040][b].ne.[/b][/color] [COLOR=#ff00ff]0[/color])[COLOR=#804040][b]then[/b][/color]
    [COLOR=#804040][b]write[/b][/color] ([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]'config_file can not be opened'[/color]
    [COLOR=#804040][b]go to[/b][/color] [COLOR=#ff00ff]99[/color]
  [COLOR=#804040][b]end if[/b][/color]

  [COLOR=#804040][b]write[/b][/color] ([COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]'(80A)'[/color]) [COLOR=#ff00ff]'config_file2 opened'[/color] 
  [COLOR=#0000ff]! process config file[/color]
  [COLOR=#804040][b]do[/b][/color] [COLOR=#804040][b]while[/b][/color] ([COLOR=#ff00ff].true.[/color])
    [COLOR=#804040][b]read[/b][/color] ([COLOR=#ff00ff]1[/color], [COLOR=#ff00ff]'(A)'[/color], [COLOR=#804040][b]end[/b][/color][COLOR=#804040][b]=[/b][/color][COLOR=#804040][b]99[/b][/color]) line
    [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]'(80A)'[/color]) line [COLOR=#0000ff]!write on screen[/color]
    [COLOR=#008080]Call[/color] process_line([COLOR=#008080]adjustl[/color]([COLOR=#008080]trim[/color](line)))
  [COLOR=#804040][b]enddo[/b][/color]
  [COLOR=#0000ff]! close file[/color]
[COLOR=#804040][b]  99 continue[/b][/color]
  [COLOR=#804040][b]close[/b][/color] ([COLOR=#ff00ff]1[/color])
[COLOR=#a020f0]end subroutine[/color] parse_config_file

[COLOR=#a020f0]subroutine[/color] process_line(line)
  [COLOR=#a020f0]use[/color] globalvar 
  [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]
  [COLOR=#0000ff]! parse settings for config line[/color]

  [COLOR=#0000ff]!line = input line[/color]
  [COLOR=#2e8b57][b]character[/b][/color]([COLOR=#804040][b]*[/b][/color]), [COLOR=#2e8b57][b]intent[/b][/color]([COLOR=#2e8b57][b]in[/b][/color]) :: line
  [COLOR=#0000ff]!output parameters[/color]
  [COLOR=#0000ff]!integer :: ndays, nhours, nlong, nlat[/color]
  [COLOR=#2e8b57][b]character[/b][/color]([COLOR=#ff00ff]30[/color]) :: cfg_param

  [COLOR=#0000ff]!parameter part of config line[/color]
  cfg_param [COLOR=#804040][b]=[/b][/color] [COLOR=#008080]adjustl[/color](line([COLOR=#008080]index[/color](line, [COLOR=#ff00ff]':'[/color])[COLOR=#804040][b]+[/b][/color][COLOR=#ff00ff]1[/color]:))
  [COLOR=#804040][b]if[/b][/color] ([COLOR=#008080]index[/color](line,[COLOR=#ff00ff]'number of days'[/color]) [COLOR=#804040][b]>[/b][/color] [COLOR=#ff00ff]0[/color]) [COLOR=#804040][b]then[/b][/color]
    [COLOR=#0000ff]! convert substring into integer number[/color]
    [COLOR=#804040][b]read[/b][/color] (cfg_param, [COLOR=#ff00ff]'(I3)'[/color]) ndays    
  [COLOR=#804040][b]else[/b][/color] [COLOR=#804040][b]if[/b][/color] ([COLOR=#008080]index[/color](line, [COLOR=#ff00ff]'number of hours per day'[/color]) [COLOR=#804040][b]>[/b][/color] [COLOR=#ff00ff]0[/color]) [COLOR=#804040][b]then[/b][/color]
    [COLOR=#0000ff]! convert substring into integer number[/color]
    [COLOR=#804040][b]read[/b][/color] (cfg_param, [COLOR=#ff00ff]'(I3)'[/color]) nhours
  [COLOR=#804040][b]else[/b][/color] [COLOR=#804040][b]if[/b][/color] ([COLOR=#008080]index[/color](line, [COLOR=#ff00ff]'number of columns for study area'[/color]) [COLOR=#804040][b]>[/b][/color] [COLOR=#ff00ff]0[/color]) [COLOR=#804040][b]then[/b][/color]
    [COLOR=#0000ff]! convert substring into integer number[/color]
    [COLOR=#804040][b]read[/b][/color] (cfg_param, [COLOR=#ff00ff]'(I3)'[/color]) nlong
  [COLOR=#804040][b]else[/b][/color] [COLOR=#804040][b]if[/b][/color] ([COLOR=#008080]index[/color](line, [COLOR=#ff00ff]'number of rows for study area'[/color]) [COLOR=#804040][b]>[/b][/color] [COLOR=#ff00ff]0[/color]) [COLOR=#804040][b]then[/b][/color]
    [COLOR=#0000ff]! convert substring into integer number[/color]
    [COLOR=#804040][b]read[/b][/color] (cfg_param, [COLOR=#ff00ff]'(I3)'[/color]) nlat
  [COLOR=#804040][b]end if[/b][/color] 
[COLOR=#a020f0]end subroutine[/color] process_line

[COLOR=#a020f0]subroutine[/color] subr_pause
  [COLOR=#2e8b57][b]integer[/b][/color] :: cmd_rc [COLOR=#0000ff]! command return code[/color]
  [COLOR=#2e8b57][b]character[/b][/color]([COLOR=#804040][b]*[/b][/color]), [COLOR=#2e8b57][b]parameter[/b][/color] :: cmd_string [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]"pause"[/color]
  [COLOR=#008080]call[/color] system (cmd_string, cmd_rc)
[COLOR=#a020f0]end subroutine[/color] subr_pause
Now, having this config file
config_file2.txt
Code:
# Input variables
number of days: 1
number of hours per day: 3
number of columns for study area: 4
number of rows for study area: 5
we get the result
Code:
$ gfortran tstread.f95 -o tstread

$ tstread
config_file2 opened
# Input variables                                                               
number of days: 1                                                               
number of hours per day: 3                                                      
number of columns for study area: 4                                             
number of rows for study area: 5                                                
*******************************************************

Configure parameters found:
 Number of days                      =           1
 Number of hours                     =           3
 Number of columns for study area    =           4
 Number of rows for study area       =           5
 Parameters                          =  10.0000000      0.40000001    
Press any key to continue . . .
 
YES!!!!
I've been away for a few days and what a nice way to start back to work on this program. I too get the correct output now. I'm ready to work on incorporating all 70 parameters and integrating this into the rest of the program. I really appreciate your patience and time spent on helping me out. It's going to be good and productive week!
DustBunnie
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top