initial gray CLI work
This lays down the basis for the gray command-line interface. All options works but currently --units and -v/-q have no effect.
This commit is contained in:
parent
93d936ce24
commit
01a6f9145c
6
Makefile
6
Makefile
@ -20,6 +20,8 @@ BINDIR = build/bin
|
||||
LIBDIR = build/lib
|
||||
OBJDIR = build/obj
|
||||
|
||||
PREFIX ?= /usr/bin
|
||||
|
||||
# Directories that need to be created
|
||||
DIRS = $(BINDIR) $(OBJDIR) $(LIBDIR) $(SHAREDIR)
|
||||
|
||||
@ -62,8 +64,8 @@ GIT_DIRTY ?= $(shell test -n "$$(git status --porcelain)" && echo "-dirty")
|
||||
# Note: can't use ?= for FC because GNU Make defaults to f77
|
||||
FC = gfortran
|
||||
LD = gfortran
|
||||
FFLAGS += -O3 -J$(OBJDIR)
|
||||
CPPFLAGS += -DREVISION=\"$(GIT_REV)$(GIT_DIRTY)\"
|
||||
FFLAGS += -O3 -J$(OBJDIR) -ffree-line-length-none
|
||||
CPPFLAGS += -DREVISION=\"$(GIT_REV)$(GIT_DIRTY)\" -DPREFIX=\"$(PREFIX)\"
|
||||
|
||||
# Static build options
|
||||
ifdef STATIC
|
||||
|
199
src/gray_cli.f90
Normal file
199
src/gray_cli.f90
Normal file
@ -0,0 +1,199 @@
|
||||
! This module implements the command-line interface (CLI) of GRAY
|
||||
module gray_cli
|
||||
|
||||
implicit none
|
||||
|
||||
! GRAY command line options
|
||||
! See print_help() for a description.
|
||||
! Note: if you change these, remember to update:
|
||||
! 1. the print_help() subroutine
|
||||
! 2. the print_cli_options() subroutine
|
||||
type cli_options
|
||||
! Switches
|
||||
logical :: verbose
|
||||
logical :: quiet
|
||||
! Files
|
||||
character(len=:), allocatable :: output_dir
|
||||
character(len=:), allocatable :: params_file
|
||||
character(len=:), allocatable :: sum_filelist
|
||||
! others
|
||||
integer, allocatable :: units(:)
|
||||
end type
|
||||
|
||||
private
|
||||
public :: cli_options, print_cli_options, parse_cli_options
|
||||
|
||||
contains
|
||||
|
||||
subroutine print_help()
|
||||
! Prints the usage screen
|
||||
|
||||
print '(a)', 'Usage: gray [OPTIONS]'
|
||||
print '(a)', ''
|
||||
print '(a)', 'GRAY is a beam-tracing code for Electron Cyclotron (EC) waves in a tokamak.'
|
||||
print '(a)', 'It is based on the complex eikonal theory (quasi-optics), which can accurately'
|
||||
print '(a)', 'describe the propagation of a Gaussian beam, diffraction effects included.'
|
||||
print '(a)', 'In addition, power absoption and current drive are computed using the fully'
|
||||
print '(a)', 'relativistic dispersion relation and a neoclassical response function,'
|
||||
print '(a)', 'respectively.'
|
||||
print '(a)', ''
|
||||
print '(a)', 'Options:'
|
||||
print '(a)', ' -h, --help display this help and exit'
|
||||
print '(a)', ' -V, --version display version information and exit'
|
||||
print '(a)', ' -v, --verbose print additional information messages'
|
||||
print '(a)', ' -q, --quiet suppress all messages on standard output'
|
||||
print '(a)', ' -o, --output-dir DIR specify where to write the output files'
|
||||
print '(a)', ' (default: current directory)'
|
||||
print '(a)', ' -p, --params-file FILE set the parameters file'
|
||||
print '(a)', ' (default: gray_params.data)'
|
||||
print '(a)', ' -s, --sum FILE sum the output profiles from a list of files'
|
||||
print '(a)', ' -u, --units ID[,ID...] select which units to output (default: 4, 7)'
|
||||
print '(a)', ''
|
||||
print '(a)', '*Exit status*'
|
||||
print '(a)', ' 0 if OK,'
|
||||
print '(a)', ' 1 if technical problems (e.g., invalid arguments, missing input files),'
|
||||
print '(a)', ' 2 if serious trouble (e.g., computation failed).'
|
||||
print '(a)', ''
|
||||
print '(a)', 'Full documentation is available at'
|
||||
print '(a)', '<file://'//PREFIX//'/share/doc/manual.html>'
|
||||
end subroutine
|
||||
|
||||
|
||||
subroutine print_version()
|
||||
! Prints the version information
|
||||
|
||||
print '(a)', 'gray revision ' // REVISION
|
||||
print '(a)', ''
|
||||
print '(a)', 'Written by D. Farina, L. Figini, A. Mariani and M. Guerini Rocco.'
|
||||
end subroutine
|
||||
|
||||
|
||||
subroutine print_cli_options(opts)
|
||||
! Prints the parsed CLI options (for debugging)
|
||||
|
||||
implicit none
|
||||
|
||||
! subroutine arguments
|
||||
type(cli_options), intent(in) :: opts
|
||||
|
||||
print '(a)' , 'switches:'
|
||||
print '(a,l)' , ' - verbose: ' , opts%verbose
|
||||
print '(a,l)' , ' - quiet: ' , opts%quiet
|
||||
print '(a)' , 'files:'
|
||||
print '(a,a)' , ' output-dir: ' , opts%output_dir
|
||||
print '(a,a)' , ' param-file: ' , opts%params_file
|
||||
print '(a,a)' , ' sum: ' , opts%sum_filelist
|
||||
print '(a)' , 'others:'
|
||||
print '(a,20i3)' , ' - units: ' , opts%units
|
||||
end subroutine
|
||||
|
||||
|
||||
subroutine parse_cli_options(opts)
|
||||
! Parse the CLI arguments and initialise the options
|
||||
|
||||
use units, only : ucenr, usumm
|
||||
|
||||
implicit none
|
||||
|
||||
! subroutine arguments
|
||||
type(cli_options), intent(out) :: opts
|
||||
|
||||
! local variables
|
||||
character(len=:), allocatable :: argument, temp
|
||||
logical :: skip_next = .false.
|
||||
integer :: i, nargs
|
||||
integer :: error, commas
|
||||
|
||||
! Default option values
|
||||
opts%verbose = .false.
|
||||
opts%quiet = .false.
|
||||
opts%params_file = 'gray_params.data'
|
||||
opts%units = [ucenr, usumm]
|
||||
|
||||
nargs = command_argument_count()
|
||||
do i = 1, nargs
|
||||
call get_command_string(i, argument)
|
||||
|
||||
! skip one cycle if the last argument was a value
|
||||
if (skip_next) then
|
||||
skip_next = .false.
|
||||
cycle
|
||||
end if
|
||||
|
||||
! parse an argument (and possibly a value)
|
||||
select case (argument)
|
||||
case ('-h', '--help')
|
||||
call print_help()
|
||||
call exit(0)
|
||||
|
||||
case ('-V', '--version')
|
||||
call print_version()
|
||||
call exit(0)
|
||||
|
||||
case ('-v', '--verbose')
|
||||
opts%verbose = .true.
|
||||
|
||||
case ('-q', '--quiet')
|
||||
opts%quiet = .true.
|
||||
|
||||
case ('-o', '--output-dir')
|
||||
call get_command_string(i + 1, opts%output_dir)
|
||||
skip_next = .true.
|
||||
|
||||
case ('-p', '--params-file')
|
||||
call get_command_string(i + 1, opts%params_file)
|
||||
skip_next = .true.
|
||||
|
||||
case ('-s', '--sum')
|
||||
call get_command_string(i + 1, opts%sum_filelist)
|
||||
skip_next = .true.
|
||||
|
||||
case ('-u', '--units')
|
||||
call get_command_string(i + 1, temp)
|
||||
|
||||
! resize the array
|
||||
commas = count([(temp(i:i) == ',', i = 1, len(temp))])
|
||||
deallocate(opts%units)
|
||||
allocate(opts%units(commas + 1))
|
||||
|
||||
! read the list of table IDs
|
||||
read(temp, *, iostat=error) opts%units
|
||||
if (error .gt. 0) then
|
||||
print '(a,a)', 'invalid table IDs: ', temp
|
||||
call exit(1)
|
||||
end if
|
||||
deallocate(temp)
|
||||
skip_next = .true.
|
||||
|
||||
case default
|
||||
print '(a,a,/)', 'Unknown option: ', argument
|
||||
call print_help()
|
||||
call exit(1)
|
||||
|
||||
end select
|
||||
end do
|
||||
|
||||
! free temporary string
|
||||
if (nargs .gt. 0) deallocate(argument)
|
||||
end subroutine
|
||||
|
||||
|
||||
subroutine get_command_string(i, arg)
|
||||
! Reads a CLI argument into a deferred-length string
|
||||
|
||||
implicit none
|
||||
|
||||
! subroutine arguments
|
||||
integer, intent(in) :: i
|
||||
character(len=:), allocatable, intent(inout) :: arg
|
||||
|
||||
! local variables
|
||||
integer :: len
|
||||
|
||||
if (allocated(arg)) deallocate(arg) ! free memory (if needed)
|
||||
call get_command_argument(i, length=len) ! get the arg length
|
||||
allocate(character(len) :: arg) ! allocate memory
|
||||
call get_command_argument(i, arg) ! copy
|
||||
end subroutine
|
||||
|
||||
end module gray_cli
|
@ -240,8 +240,8 @@ contains
|
||||
|
||||
open(u, file=filename, status='old', action='read', iostat=iostat)
|
||||
if (iostat > 0) then
|
||||
print '(a)', 'gray_params file not found!'
|
||||
call EXIT(1)
|
||||
print '(3a)', 'gray_params file (', filename ,') not found!'
|
||||
call exit(1)
|
||||
end if
|
||||
|
||||
! Raytracing
|
||||
@ -335,6 +335,16 @@ contains
|
||||
read(u, *) params%output%istpr, params%output%istpl
|
||||
|
||||
close(u)
|
||||
|
||||
! Convert all filenames to absolute paths
|
||||
! Note: `filenm` is assumed to be a path relative to the
|
||||
! gray_params.data file.
|
||||
block
|
||||
use utils, only : dirname
|
||||
params%antenna%filenm = dirname(filename) // params%antenna%filenm
|
||||
params%equilibrium%filenm = dirname(filename) // params%equilibrium%filenm
|
||||
params%profiles%filenm = dirname(filename) // params%profiles%filenm
|
||||
end block
|
||||
end subroutine read_parameters
|
||||
|
||||
|
||||
|
21
src/main.f90
21
src/main.f90
@ -1,21 +1,26 @@
|
||||
program main
|
||||
use const_and_precisions, only : wp_, one, zero
|
||||
use gray_cli, only : cli_options, parse_cli_options
|
||||
use gray_core, only : gray_main
|
||||
use gray_params, only : gray_parameters, gray_data, gray_results, &
|
||||
read_parameters, params_set_globals => set_globals
|
||||
implicit none
|
||||
|
||||
! CLI options
|
||||
type(cli_options) :: opts
|
||||
|
||||
! gray_main subroutine arguments
|
||||
type(gray_parameters) :: params ! Inputs
|
||||
type(gray_data) :: data !
|
||||
type(gray_results) :: results ! Outputs
|
||||
integer :: error ! Exit code
|
||||
|
||||
logical :: sum_mode = .false.
|
||||
! Parse the command-line options
|
||||
call parse_cli_options(opts)
|
||||
|
||||
! Load the parameters and also copy them into
|
||||
! global variables exported by the gray_params
|
||||
call read_parameters('gray_params.data', params)
|
||||
call read_parameters(opts%params_file, params)
|
||||
call params_set_globals(params)
|
||||
|
||||
! Read the input data into set the global variables
|
||||
@ -25,7 +30,15 @@ program main
|
||||
call init_antenna(params%antenna)
|
||||
call init_misc(params, data)
|
||||
|
||||
if (sum_mode) then
|
||||
! Change the current directory to output files here
|
||||
if (allocated(opts%output_dir)) then
|
||||
if (chdir(opts%output_dir) /= 0) then
|
||||
print '(3a)', 'chdir to output_dir (', opts%output_dir, ') failed!'
|
||||
call exit(1)
|
||||
end if
|
||||
end if
|
||||
|
||||
if (allocated(opts%sum_filelist)) then
|
||||
sum: block
|
||||
real(wp_) :: pabs, icd, pec
|
||||
real(wp_), dimension(:), allocatable :: dpdv, jcd, jphi
|
||||
@ -39,7 +52,7 @@ program main
|
||||
pins(params%output%nrho), rtin(params%output%nrho), &
|
||||
rpin(params%output%nrho))
|
||||
|
||||
open(100, file='filelist.txt', action='read', status='old')
|
||||
open(100, file=opts%sum_filelist, action='read', status='old')
|
||||
read(100, *) n, ngam
|
||||
do i=1,n
|
||||
read(100, *) filename
|
||||
|
@ -275,4 +275,26 @@ contains
|
||||
end do
|
||||
end function get_free_unit
|
||||
|
||||
end module utils
|
||||
|
||||
function dirname(filepath) result(directory)
|
||||
! Get the parent `directory` of `filepath`
|
||||
|
||||
! function arguments
|
||||
character(*), intent(in) :: filepath
|
||||
character(:), allocatable :: directory
|
||||
|
||||
! local variables
|
||||
character(255) :: cwd
|
||||
integer :: last_sep
|
||||
|
||||
last_sep = scan(filepath, '/', back=.true.)
|
||||
directory = filepath(1:last_sep)
|
||||
|
||||
! append the cwd to relative paths
|
||||
if (filepath(1:1) /= '/') then
|
||||
call getcwd(cwd)
|
||||
directory = trim(cwd) // '/' // directory
|
||||
end if
|
||||
end function dirname
|
||||
|
||||
end module utils
|
||||
|
Loading…
Reference in New Issue
Block a user