!***********************************************************************
!* GNU Lesser General Public License
!*
!* This file is part of the GFDL Flexible Modeling System (FMS).
!*
!* FMS is free software: you can redistribute it and/or modify it under
!* the terms of the GNU Lesser General Public License as published by
!* the Free Software Foundation, either version 3 of the License, or (at
!* your option) any later version.
!*
!* FMS 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 Lesser General Public
!* License along with FMS. If not, see .
!***********************************************************************
module fm_util_mod !{
!
! Richard D. Slater
!
!
! John P. Dunne
!
!
!
! Utility routines for the field manager
!
!
!
! This module provides utility routines for the field manager.
! Basically, it provides for error catching, reporting and
! termination while interfacing with the field manager.
!
!
!
!
!
use field_manager_mod, only: fm_string_len, fm_path_name_len, fm_field_name_len, fm_type_name_len
use field_manager_mod, only: fm_get_type, fm_get_index, fm_get_length
use field_manager_mod, only: fm_get_current_list, fm_new_list, fm_change_list, fm_loop_over_list
use field_manager_mod, only: fm_new_value, fm_get_value
use field_manager_mod, only: fm_exists, fm_dump_list
use fms_mod, only: FATAL, stdout
use mpp_mod, only: mpp_error
implicit none
private
public fm_util_start_namelist
public fm_util_end_namelist
public fm_util_check_for_bad_fields
public fm_util_set_caller
public fm_util_reset_caller
public fm_util_set_no_overwrite
public fm_util_reset_no_overwrite
public fm_util_set_good_name_list
public fm_util_reset_good_name_list
public fm_util_get_length
public fm_util_get_integer
public fm_util_get_logical
public fm_util_get_real
public fm_util_get_string
public fm_util_get_integer_array
public fm_util_get_logical_array
public fm_util_get_real_array
public fm_util_get_string_array
public fm_util_set_value
public fm_util_set_value_integer_array
public fm_util_set_value_logical_array
public fm_util_set_value_real_array
public fm_util_set_value_string_array
public fm_util_set_value_integer
public fm_util_set_value_logical
public fm_util_set_value_real
public fm_util_set_value_string
!public fm_util_get_index
public fm_util_get_index_list
public fm_util_get_index_string
!
! Public variables
!
character(len=128), public :: fm_util_default_caller = ' '
!
! private parameters
!
character(len=48), parameter :: mod_name = 'fm_util_mod'
!
! Private variables
!
character(len=128) :: save_default_caller = ' '
character(len=128) :: default_good_name_list = ' '
character(len=128) :: save_default_good_name_list = ' '
logical :: default_no_overwrite = .false.
logical :: save_default_no_overwrite = .false.
character(len=fm_path_name_len) :: save_current_list
character(len=fm_path_name_len) :: save_path
character(len=fm_path_name_len) :: save_name
! Include variable "version" to be written to log file.
#include
!
! Interface definitions for overloaded routines
!
!interface fm_util_get_value !{
!module procedure fm_util_get_value_integer
!module procedure fm_util_get_value_logical
!module procedure fm_util_get_value_real
!module procedure fm_util_get_value_string
!module procedure fm_util_get_value_integer_array
!module procedure fm_util_get_value_logical_array
!module procedure fm_util_get_value_real_array
!module procedure fm_util_get_value_string_array
!end interface !}
interface fm_util_set_value !{
module procedure fm_util_set_value_integer_array
module procedure fm_util_set_value_logical_array
module procedure fm_util_set_value_real_array
module procedure fm_util_set_value_string_array
module procedure fm_util_set_value_integer
module procedure fm_util_set_value_logical
module procedure fm_util_set_value_real
module procedure fm_util_set_value_string
end interface !}
!interface fm_util_get_index !{
!module procedure fm_util_get_index_list
!module procedure fm_util_get_index_string
!end interface !}
contains
!#######################################################################
!
!
!
! Set the default value for the optional "caller" variable used in many of these
! subroutines. If the argument is blank, then set the default to blank, otherwise
! the deault will have brackets placed around the argument.
!
!
!
subroutine fm_util_set_caller(caller) !{
implicit none
!
! arguments
!
character(len=*), intent(in) :: caller
!
! Local variables
!
!
! save the default caller string
!
save_default_caller = fm_util_default_caller
!
! set the default caller string
!
if (caller .eq. ' ') then !{
fm_util_default_caller = ' '
else !}{
fm_util_default_caller = '[' // trim(caller) // ']'
endif !}
return
end subroutine fm_util_set_caller !}
! NAME="fm_util_set_caller"
!#######################################################################
!
!
!
! Reset the default value for the optional "caller" variable used in many of these
! subroutines to blank.
!
!
!
subroutine fm_util_reset_caller !{
implicit none
!
! arguments
!
!
! Local variables
!
!
! reset the default caller string
!
fm_util_default_caller = save_default_caller
save_default_caller = ' '
return
end subroutine fm_util_reset_caller !}
! NAME="fm_util_reset_caller"
!#######################################################################
!
!
!
! Set the default value for the optional "good_name_list" variable used in many of these
! subroutines.
!
!
!
subroutine fm_util_set_good_name_list(good_name_list) !{
implicit none
!
! arguments
!
character(len=*), intent(in) :: good_name_list
!
! Local variables
!
!
! save the default good_name_list string
!
save_default_good_name_list = default_good_name_list
!
! set the default good_name_list string
!
default_good_name_list = good_name_list
return
end subroutine fm_util_set_good_name_list !}
! NAME="fm_util_set_good_name_list"
!#######################################################################
!
!
!
! Reset the default value for the optional "good_name_list" variable used in many of these
! subroutines to the saved value.
!
!
!
subroutine fm_util_reset_good_name_list !{
implicit none
!
! arguments
!
!
! Local variables
!
!
! reset the default good_name_list string
!
default_good_name_list = save_default_good_name_list
save_default_good_name_list = ' '
return
end subroutine fm_util_reset_good_name_list !}
! NAME="fm_util_reset_good_name_list"
!#######################################################################
!
!
!
! Set the default value for the optional "no_overwrite" variable used in some of these
! subroutines.
!
!
!
subroutine fm_util_set_no_overwrite(no_overwrite) !{
implicit none
!
! arguments
!
logical, intent(in) :: no_overwrite
!
! Local variables
!
!
! save the default no_overwrite string
!
save_default_no_overwrite = default_no_overwrite
!
! set the default no_overwrite value
!
default_no_overwrite = no_overwrite
return
end subroutine fm_util_set_no_overwrite !}
! NAME="fm_util_set_no_overwrite"
!#######################################################################
!
!
!
! Reset the default value for the optional "no_overwrite" variable used in some of these
! subroutines to false.
!
!
!
subroutine fm_util_reset_no_overwrite !{
implicit none
!
! arguments
!
!
! Local variables
!
!
! reset the default no_overwrite value
!
default_no_overwrite = save_default_no_overwrite
save_default_no_overwrite = .false.
return
end subroutine fm_util_reset_no_overwrite !}
! NAME="fm_util_reset_no_overwrite"
!#######################################################################
!
!
!
! Check for unrecognized fields in a list
!
!
!
subroutine fm_util_check_for_bad_fields(list, good_fields, caller) !{
implicit none
!
! arguments
!
character(len=*), intent(in) :: list
character(len=*), intent(in), dimension(:) :: good_fields
character(len=*), intent(in), optional :: caller
!
! Local parameters
!
character(len=48), parameter :: sub_name = 'fm_util_check_for_bad_fields'
!
! Local variables
!
logical :: fm_success
integer :: i
integer :: ind
integer :: list_length
integer :: good_length
character(len=fm_type_name_len) :: typ
character(len=fm_field_name_len) :: name
logical :: found
character(len=256) :: error_header
character(len=256) :: warn_header
character(len=256) :: note_header
character(len=128) :: caller_str
integer :: out_unit
out_unit = stdout()
!
! set the caller string and headers
!
if (present(caller)) then !{
caller_str = '[' // trim(caller) // ']'
else !}{
caller_str = fm_util_default_caller
endif !}
error_header = '==>Error from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
warn_header = '==>Warning from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
note_header = '==>Note from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
!
! check that a list is given (fatal if not)
!
if (list .eq. ' ') then !{
write (out_unit,*) trim(error_header) // ' Empty list given'
call mpp_error(FATAL, trim(error_header) // ' Empty list given')
endif !}
!
! Check that we have been given a list
!
if (fm_get_type(list) .ne. 'list') then !{
write (out_unit,*) trim(error_header) // ' Not given a list: ' // trim(list)
call mpp_error(FATAL, trim(error_header) // ' Not given a list: ' // trim(list))
endif !}
!
! Get the list length
!
list_length = fm_get_length(list)
if (list_length .lt. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Problem getting length of ' // trim(list))
endif !}
!
! Get the number of good fields
!
good_length = size(good_fields)
if (list_length .lt. good_length) then !{
!
! If the list length is less than the number of good fields this is an error
! as the list should be fully populated and we'll check which extra fields
! are given in good_fields
!
write (out_unit,*) trim(error_header), ' List length < number of good fields (', &
list_length, ' < ', good_length, ') in list ', trim(list)
write (out_unit,*)
write (out_unit,*) 'The list contains the following fields:'
fm_success= fm_dump_list(list, .false.)
write (out_unit,*)
write (out_unit,*) 'The supposed list of good fields is:'
do i = 1, good_length !{
if (fm_exists(trim(list) // '/' // good_fields(i))) then !{
write (out_unit,*) 'List field: "', trim(good_fields(i)), '"'
else !}{
write (out_unit,*) 'EXTRA good field: "', trim(good_fields(i)), '"'
endif !}
enddo !} i
write (out_unit,*)
call mpp_error(FATAL, trim(error_header) // &
' List length < number of good fields for list: ' // trim(list))
elseif (list_length .gt. good_length) then !}{
!
! If the list length is greater than the number of good fields this is an error
! as the there should not be any more fields than those given in the good fields list
! and we'll check which extra fields are given in the list
!
write (out_unit,*) trim(warn_header), 'List length > number of good fields (', &
list_length, ' > ', good_length, ') in list ', trim(list)
write (out_unit,*) trim(error_header), ' Start of list of fields'
do while (fm_loop_over_list(list, name, typ, ind)) !{
found = .false.
do i = 1, good_length !{
found = found .or. (name .eq. good_fields(i))
enddo !} i
if (found) then !{
write (out_unit,*) 'Good list field: "', trim(name), '"'
else !}{
write (out_unit,*) 'EXTRA list field: "', trim(name), '"'
endif !}
enddo !}
write (out_unit,*) trim(error_header), ' End of list of fields'
call mpp_error(FATAL, trim(error_header) // &
' List length > number of good fields for list: ' // trim(list))
endif !}
!
! If the list length equals the number of good fields then all is good
!
return
end subroutine fm_util_check_for_bad_fields !}
! NAME="fm_util_check_for_bad_fields"
!#######################################################################
!
!
!
! Get the length of an element of the Field Manager tree
!
!
function fm_util_get_length(name, caller) &
result (field_length) !{
implicit none
!
! Return type
!
integer :: field_length
!
! arguments
!
character(len=*), intent(in) :: name
character(len=*), intent(in), optional :: caller
!
! Local parameters
!
character(len=48), parameter :: sub_name = 'fm_util_get_length'
!
! Local variables
!
character(len=256) :: error_header
character(len=256) :: warn_header
character(len=256) :: note_header
character(len=128) :: caller_str
!
! set the caller string and headers
!
if (present(caller)) then !{
caller_str = '[' // trim(caller) // ']'
else !}{
caller_str = fm_util_default_caller
endif !}
error_header = '==>Error from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
warn_header = '==>Warning from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
note_header = '==>Note from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
!
! check that a name is given (fatal if not)
!
if (name .eq. ' ') then !{
call mpp_error(FATAL, trim(error_header) // ' Empty name given')
endif !}
!
! Get the field's length
!
field_length = fm_get_length(name)
if (field_length .lt. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Problem getting length of ' // trim(name))
endif !}
return
end function fm_util_get_length !}
! NAME="fm_util_get_length"
!#######################################################################
!
!
!
! Get the index of an element of a string in the Field Manager tree
!
!
function fm_util_get_index_string(name, string, caller) &
result (fm_index) !{
implicit none
!
! Return type
!
integer :: fm_index
!
! arguments
!
character(len=*), intent(in) :: name
character(len=*), intent(in) :: string
character(len=*), intent(in), optional :: caller
!
! Local parameters
!
character(len=48), parameter :: sub_name = 'fm_util_get_index_string'
!
! Local variables
!
character(len=256) :: error_header
character(len=256) :: warn_header
character(len=256) :: note_header
character(len=128) :: caller_str
character(len=32) :: index_str
character(len=fm_type_name_len) :: fm_type
character(len=fm_string_len) :: fm_string
integer :: i
integer :: length
!
! set the caller string and headers
!
if (present(caller)) then !{
caller_str = '[' // trim(caller) // ']'
else !}{
caller_str = fm_util_default_caller
endif !}
error_header = '==>Error from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
warn_header = '==>Warning from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
note_header = '==>Note from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
!
! check that a name is given (fatal if not)
!
if (name .eq. ' ') then !{
call mpp_error(FATAL, trim(error_header) // ' Empty name given')
endif !}
!
! Check the field's type and get the index
!
fm_index = 0
fm_type = fm_get_type(name)
if (fm_type .eq. 'string') then !{
length = fm_get_length(name)
if (length .lt. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Problem getting length of ' // trim(name))
endif !}
if (length .gt. 0) then !{
do i = 1, length !{
if (.not. fm_get_value(name, fm_string, index = i)) then !{
write (index_str,*) '(', i, ')'
call mpp_error(FATAL, trim(error_header) // ' Problem getting ' // trim(name) // trim(index_str))
endif !}
if (fm_string .eq. string) then !{
fm_index = i
exit
endif !}
enddo !} i
endif !}
elseif (fm_type .eq. ' ') then !}{
call mpp_error(FATAL, trim(error_header) // ' Array does not exist: ' // trim(name))
else !}{
call mpp_error(FATAL, trim(error_header) // ' Wrong type for ' // trim(name) // ', found (' // trim(fm_type) // ')')
endif !}
!if (fm_index .eq. 0) then !{
!call mpp_error(FATAL, trim(error_header) // ' "' // trim(string) // '" does not exist in ' // trim(name))
!endif !}
return
end function fm_util_get_index_string !}
! NAME="fm_util_get_index_string"
!#######################################################################
!
!
!
! Get the length of an element of the Field Manager tree
!
!
function fm_util_get_index_list(name, caller) &
result (fm_index) !{
implicit none
!
! Return type
!
integer :: fm_index
!
! arguments
!
character(len=*), intent(in) :: name
character(len=*), intent(in), optional :: caller
!
! Local parameters
!
character(len=48), parameter :: sub_name = 'fm_util_get_index_list'
!
! Local variables
!
character(len=256) :: error_header
character(len=256) :: warn_header
character(len=256) :: note_header
character(len=128) :: caller_str
character(len=fm_type_name_len) :: fm_type
!
! set the caller string and headers
!
if (present(caller)) then !{
caller_str = '[' // trim(caller) // ']'
else !}{
caller_str = fm_util_default_caller
endif !}
error_header = '==>Error from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
warn_header = '==>Warning from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
note_header = '==>Note from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
!
! check that a name is given (fatal if not)
!
if (name .eq. ' ') then !{
call mpp_error(FATAL, trim(error_header) // ' Empty name given')
endif !}
!
! Check the field's type and get the index
!
fm_index = 0
fm_type = fm_get_type(name)
if (fm_type .eq. 'list') then !{
fm_index = fm_get_index(name)
if (fm_index .le. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' List does not exist: ' // trim(name))
endif !}
elseif (fm_type .eq. ' ') then !}{
call mpp_error(FATAL, trim(error_header) // ' List does not exist: ' // trim(name))
else !}{
call mpp_error(FATAL, trim(error_header) // ' Wrong type for ' // trim(name) // ', found (' // trim(fm_type) // ')')
endif !}
return
end function fm_util_get_index_list !}
! NAME="fm_util_get_index_list"
!#######################################################################
!
!
!
! Get an integer value from the Field Manager tree.
!
!
function fm_util_get_integer_array(name, caller) &
result (array) !{
implicit none
!
! Return type
!
integer, pointer, dimension(:) :: array
!
! arguments
!
character(len=*), intent(in) :: name
character(len=*), intent(in), optional :: caller
!
! Local parameters
!
character(len=48), parameter :: sub_name = 'fm_util_get_integer_array'
!
! Local variables
!
character(len=256) :: error_header
character(len=256) :: warn_header
character(len=256) :: note_header
character(len=128) :: caller_str
character(len=32) :: index_str
character(len=fm_type_name_len) :: fm_type
integer :: i
integer :: length
nullify(array)
!
! set the caller string and headers
!
if (present(caller)) then !{
caller_str = '[' // trim(caller) // ']'
else !}{
caller_str = fm_util_default_caller
endif !}
error_header = '==>Error from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
warn_header = '==>Warning from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
note_header = '==>Note from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
!
! check that a name is given (fatal if not)
!
if (name .eq. ' ') then !{
call mpp_error(FATAL, trim(error_header) // ' Empty name given')
endif !}
fm_type = fm_get_type(name)
if (fm_type .eq. 'integer') then !{
length = fm_get_length(name)
if (length .lt. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Problem getting length of ' // trim(name))
endif !}
if (length .gt. 0) then !{
allocate(array(length))
do i = 1, length !{
if (.not. fm_get_value(name, array(i), index = i)) then !{
write (index_str,*) '(', i, ')'
call mpp_error(FATAL, trim(error_header) // ' Problem getting ' // trim(name) // trim(index_str))
endif !}
enddo !} i
endif !}
elseif (fm_type .eq. ' ') then !}{
call mpp_error(FATAL, trim(error_header) // ' Array does not exist: ' // trim(name))
else !}{
call mpp_error(FATAL, trim(error_header) // ' Wrong type for ' // trim(name) // ', found (' // trim(fm_type) // ')')
endif !}
return
end function fm_util_get_integer_array !}
! NAME="fm_util_get_integer_array"
!#######################################################################
!
!
!
! Get a logical value from the Field Manager tree.
!
!
function fm_util_get_logical_array(name, caller) &
result (array) !{
implicit none
!
! Return type
!
logical, pointer, dimension(:) :: array
!
! arguments
!
character(len=*), intent(in) :: name
character(len=*), intent(in), optional :: caller
!
! Local parameters
!
character(len=48), parameter :: sub_name = 'fm_util_get_logical_array'
!
! Local variables
!
character(len=256) :: error_header
character(len=256) :: warn_header
character(len=256) :: note_header
character(len=128) :: caller_str
character(len=32) :: index_str
character(len=fm_type_name_len) :: fm_type
integer :: i
integer :: length
nullify(array)
!
! set the caller string and headers
!
if (present(caller)) then !{
caller_str = '[' // trim(caller) // ']'
else !}{
caller_str = fm_util_default_caller
endif !}
error_header = '==>Error from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
warn_header = '==>Warning from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
note_header = '==>Note from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
!
! check that a name is given (fatal if not)
!
if (name .eq. ' ') then !{
call mpp_error(FATAL, trim(error_header) // ' Empty name given')
endif !}
fm_type = fm_get_type(name)
if (fm_type .eq. 'logical') then !{
length = fm_get_length(name)
if (length .lt. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Problem getting length of ' // trim(name))
endif !}
if (length .gt. 0) then !{
allocate(array(length))
do i = 1, length !{
if (.not. fm_get_value(name, array(i), index = i)) then !{
write (index_str,*) '(', i, ')'
call mpp_error(FATAL, trim(error_header) // ' Problem getting ' // trim(name) // trim(index_str))
endif !}
enddo !} i
endif !}
elseif (fm_type .eq. ' ') then !}{
call mpp_error(FATAL, trim(error_header) // ' Array does not exist: ' // trim(name))
else !}{
call mpp_error(FATAL, trim(error_header) // ' Wrong type for ' // trim(name) // ', found (' // trim(fm_type) // ')')
endif !}
return
end function fm_util_get_logical_array !}
! NAME="fm_util_get_logical_array"
!#######################################################################
!
!
!
! Get a real value from the Field Manager tree.
!
!
function fm_util_get_real_array(name, caller) &
result (array) !{
implicit none
!
! Return type
!
real, pointer, dimension(:) :: array
!
! arguments
!
character(len=*), intent(in) :: name
character(len=*), intent(in), optional :: caller
!
! Local parameters
!
character(len=48), parameter :: sub_name = 'fm_util_get_real_array'
!
! Local variables
!
character(len=256) :: error_header
character(len=256) :: warn_header
character(len=256) :: note_header
character(len=128) :: caller_str
character(len=32) :: index_str
character(len=fm_type_name_len) :: fm_type
integer :: i
integer :: length
nullify(array)
!
! set the caller string and headers
!
if (present(caller)) then !{
caller_str = '[' // trim(caller) // ']'
else !}{
caller_str = fm_util_default_caller
endif !}
error_header = '==>Error from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
warn_header = '==>Warning from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
note_header = '==>Note from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
!
! check that a name is given (fatal if not)
!
if (name .eq. ' ') then !{
call mpp_error(FATAL, trim(error_header) // ' Empty name given')
endif !}
fm_type = fm_get_type(name)
if (fm_type .eq. 'real') then !{
length = fm_get_length(name)
if (length .lt. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Problem getting length of ' // trim(name))
endif !}
if (length .gt. 0) then !{
allocate(array(length))
do i = 1, length !{
if (.not. fm_get_value(name, array(i), index = i)) then !{
write (index_str,*) '(', i, ')'
call mpp_error(FATAL, trim(error_header) // ' Problem getting ' // trim(name) // trim(index_str))
endif !}
enddo !} i
endif !}
elseif (fm_type .eq. ' ') then !}{
call mpp_error(FATAL, trim(error_header) // ' Array does not exist: ' // trim(name))
else !}{
call mpp_error(FATAL, trim(error_header) // ' Wrong type for ' // trim(name) // ', found (' // trim(fm_type) // ')')
endif !}
return
end function fm_util_get_real_array !}
! NAME="fm_util_get_real_array"
!#######################################################################
!
!
!
! Get a string value from the Field Manager tree.
!
!
function fm_util_get_string_array(name, caller) &
result (array) !{
implicit none
!
! Return type
!
character(len=fm_string_len), pointer, dimension(:) :: array
!
! arguments
!
character(len=*), intent(in) :: name
character(len=*), intent(in), optional :: caller
!
! Local parameters
!
character(len=48), parameter :: sub_name = 'fm_util_get_string_array'
!
! Local variables
!
character(len=256) :: error_header
character(len=256) :: warn_header
character(len=256) :: note_header
character(len=128) :: caller_str
character(len=32) :: index_str
character(len=fm_type_name_len) :: fm_type
integer :: i
integer :: length
nullify(array)
!
! set the caller string and headers
!
if (present(caller)) then !{
caller_str = '[' // trim(caller) // ']'
else !}{
caller_str = fm_util_default_caller
endif !}
error_header = '==>Error from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
warn_header = '==>Warning from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
note_header = '==>Note from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
!
! check that a name is given (fatal if not)
!
if (name .eq. ' ') then !{
call mpp_error(FATAL, trim(error_header) // ' Empty name given')
endif !}
fm_type = fm_get_type(name)
if (fm_type .eq. 'string') then !{
length = fm_get_length(name)
if (length .lt. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Problem getting length of ' // trim(name))
endif !}
if (length .gt. 0) then !{
allocate(array(length))
do i = 1, length !{
if (.not. fm_get_value(name, array(i), index = i)) then !{
write (index_str,*) '(', i, ')'
call mpp_error(FATAL, trim(error_header) // ' Problem getting ' // trim(name) // trim(index_str))
endif !}
enddo !} i
endif !}
elseif (fm_type .eq. ' ') then !}{
call mpp_error(FATAL, trim(error_header) // ' Array does not exist: ' // trim(name))
else !}{
call mpp_error(FATAL, trim(error_header) // ' Wrong type for ' // trim(name) // ', found (' // trim(fm_type) // ')')
endif !}
return
end function fm_util_get_string_array !}
! NAME="fm_util_get_string_array"
!#######################################################################
!
!
!
! Get an integer value from the Field Manager tree.
!
!
function fm_util_get_integer(name, caller, index, default_value, scalar) &
result (value) !{
implicit none
!
! Return type
!
integer :: value
!
! arguments
!
character(len=*), intent(in) :: name
character(len=*), intent(in), optional :: caller
integer, intent(in), optional :: index
integer, intent(in), optional :: default_value
logical, intent(in), optional :: scalar
!
! Local parameters
!
character(len=48), parameter :: sub_name = 'fm_util_get_integer'
!
! Local variables
!
character(len=256) :: error_header
character(len=256) :: warn_header
character(len=256) :: note_header
character(len=128) :: caller_str
integer :: index_t
character(len=fm_type_name_len) :: fm_type
integer :: field_length
!
! set the caller string and headers
!
if (present(caller)) then !{
caller_str = '[' // trim(caller) // ']'
else !}{
caller_str = fm_util_default_caller
endif !}
error_header = '==>Error from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
warn_header = '==>Warning from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
note_header = '==>Note from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
!
! check that a name is given (fatal if not)
!
if (name .eq. ' ') then !{
call mpp_error(FATAL, trim(error_header) // ' Empty name given')
endif !}
!
! Check whether we require a scalar (length=1) and return
! an error if we do, and it isn't
!
if (present(scalar)) then !{
if (scalar) then !{
field_length = fm_get_length(name)
if (field_length .lt. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Problem getting length of ' // trim(name))
elseif (field_length .gt. 1) then !}{
call mpp_error(FATAL, trim(error_header) // trim(name) // ' not scalar')
endif !}
endif !}
endif !}
!
! set the index
!
if (present(index)) then !{
index_t = index
if (index .le. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Index not positive')
endif !}
else !}{
index_t = 1
endif !}
fm_type = fm_get_type(name)
if (fm_type .eq. 'integer') then !{
if (.not. fm_get_value(name, value, index = index_t)) then !{
call mpp_error(FATAL, trim(error_header) // ' Problem getting ' // trim(name))
endif !}
elseif (fm_type .eq. ' ' .and. present(default_value)) then !}{
value = default_value
elseif (fm_type .eq. ' ') then !}{
call mpp_error(FATAL, trim(error_header) // ' Field does not exist: ' // trim(name))
else !}{
call mpp_error(FATAL, trim(error_header) // ' Wrong type for ' // trim(name) // ', found (' // trim(fm_type) // ')')
endif !}
return
end function fm_util_get_integer !}
! NAME="fm_util_get_integer"
!#######################################################################
!
!
!
! Get a logical value from the Field Manager tree.
!
!
function fm_util_get_logical(name, caller, index, default_value, scalar) &
result (value) !{
implicit none
!
! Return type
!
logical :: value
!
! arguments
!
character(len=*), intent(in) :: name
character(len=*), intent(in), optional :: caller
integer, intent(in), optional :: index
logical, intent(in), optional :: default_value
logical, intent(in), optional :: scalar
!
! Local parameters
!
character(len=48), parameter :: sub_name = 'fm_util_get_logical'
!
! Local variables
!
character(len=256) :: error_header
character(len=256) :: warn_header
character(len=256) :: note_header
character(len=128) :: caller_str
integer :: index_t
character(len=fm_type_name_len) :: fm_type
integer :: field_length
!
! set the caller string and headers
!
if (present(caller)) then !{
caller_str = '[' // trim(caller) // ']'
else !}{
caller_str = fm_util_default_caller
endif !}
error_header = '==>Error from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
warn_header = '==>Warning from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
note_header = '==>Note from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
!
! check that a name is given (fatal if not)
!
if (name .eq. ' ') then !{
call mpp_error(FATAL, trim(error_header) // ' Empty name given')
endif !}
!
! Check whether we require a scalar (length=1) and return
! an error if we do, and it isn't
!
if (present(scalar)) then !{
if (scalar) then !{
field_length = fm_get_length(name)
if (field_length .lt. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Problem getting length of ' // trim(name))
elseif (field_length .gt. 1) then !}{
call mpp_error(FATAL, trim(error_header) // trim(name) // ' not scalar')
endif !}
endif !}
endif !}
!
! set the index
!
if (present(index)) then !{
index_t = index
if (index .le. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Index not positive')
endif !}
else !}{
index_t = 1
endif !}
fm_type = fm_get_type(name)
if (fm_type .eq. 'logical') then !{
if (.not. fm_get_value(name, value, index = index_t)) then !{
call mpp_error(FATAL, trim(error_header) // ' Problem getting ' // trim(name))
endif !}
elseif (fm_type .eq. ' ' .and. present(default_value)) then !}{
value = default_value
elseif (fm_type .eq. ' ') then !}{
call mpp_error(FATAL, trim(error_header) // ' Field does not exist: ' // trim(name))
else !}{
call mpp_error(FATAL, trim(error_header) // ' Wrong type for ' // trim(name) // ', found (' // trim(fm_type) // ')')
endif !}
return
end function fm_util_get_logical !}
! NAME="fm_util_get_logical"
!#######################################################################
!
!
!
! Get a real value from the Field Manager tree.
!
!
function fm_util_get_real(name, caller, index, default_value, scalar) &
result (value) !{
implicit none
!
! Return type
!
real :: value
!
! arguments
!
character(len=*), intent(in) :: name
character(len=*), intent(in), optional :: caller
integer, intent(in), optional :: index
real, intent(in), optional :: default_value
logical, intent(in), optional :: scalar
!
! Local parameters
!
character(len=48), parameter :: sub_name = 'fm_util_get_real'
!
! Local variables
!
character(len=256) :: error_header
character(len=256) :: warn_header
character(len=256) :: note_header
character(len=128) :: caller_str
integer :: index_t
character(len=fm_type_name_len) :: fm_type
integer :: field_length
integer :: ivalue
!
! set the caller string and headers
!
if (present(caller)) then !{
caller_str = '[' // trim(caller) // ']'
else !}{
caller_str = fm_util_default_caller
endif !}
error_header = '==>Error from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
warn_header = '==>Warning from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
note_header = '==>Note from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
!
! check that a name is given (fatal if not)
!
if (name .eq. ' ') then !{
call mpp_error(FATAL, trim(error_header) // ' Empty name given')
endif !}
!
! Check whether we require a scalar (length=1) and return
! an error if we do, and it isn't
!
if (present(scalar)) then !{
if (scalar) then !{
field_length = fm_get_length(name)
if (field_length .lt. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Problem getting length of ' // trim(name))
elseif (field_length .gt. 1) then !}{
call mpp_error(FATAL, trim(error_header) // trim(name) // ' not scalar')
endif !}
endif !}
endif !}
!
! set the index
!
if (present(index)) then !{
index_t = index
if (index .le. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Index not positive')
endif !}
else !}{
index_t = 1
endif !}
fm_type = fm_get_type(name)
if (fm_type .eq. 'real') then !{
if (.not. fm_get_value(name, value, index = index_t)) then !{
call mpp_error(FATAL, trim(error_header) // ' Problem getting ' // trim(name))
endif !}
else if (fm_type .eq. 'integer') then
if (.not. fm_get_value(name, ivalue, index = index_t)) then
call mpp_error(FATAL, trim(error_header) // ' Problem getting ' // trim(name))
endif
value = ivalue
elseif (fm_type .eq. ' ' .and. present(default_value)) then !}{
value = default_value
elseif (fm_type .eq. ' ') then !}{
call mpp_error(FATAL, trim(error_header) // ' Field does not exist: ' // trim(name))
else !}{
call mpp_error(FATAL, trim(error_header) // ' Wrong type for ' // trim(name) // ', found (' // trim(fm_type) // ')')
endif !}
return
end function fm_util_get_real !}
! NAME="fm_util_get_real"
!#######################################################################
!
!
!
! Get a string value from the Field Manager tree.
!
!
function fm_util_get_string(name, caller, index, default_value, scalar) &
result (value) !{
implicit none
!
! Return type
!
character(len=fm_string_len) :: value
!
! arguments
!
character(len=*), intent(in) :: name
character(len=*), intent(in), optional :: caller
integer, intent(in), optional :: index
character(len=*), intent(in), optional :: default_value
logical, intent(in), optional :: scalar
!
! Local parameters
!
character(len=48), parameter :: sub_name = 'fm_util_get_string'
!
! Local variables
!
character(len=256) :: error_header
character(len=256) :: warn_header
character(len=256) :: note_header
character(len=128) :: caller_str
integer :: index_t
character(len=fm_type_name_len) :: fm_type
integer :: field_length
!
! set the caller string and headers
!
if (present(caller)) then !{
caller_str = '[' // trim(caller) // ']'
else !}{
caller_str = fm_util_default_caller
endif !}
error_header = '==>Error from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
warn_header = '==>Warning from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
note_header = '==>Note from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
!
! check that a name is given (fatal if not)
!
if (name .eq. ' ') then !{
call mpp_error(FATAL, trim(error_header) // ' Empty name given')
endif !}
!
! Check whether we require a scalar (length=1) and return
! an error if we do, and it isn't
!
if (present(scalar)) then !{
if (scalar) then !{
field_length = fm_get_length(name)
if (field_length .lt. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Problem getting length of ' // trim(name))
elseif (field_length .gt. 1) then !}{
call mpp_error(FATAL, trim(error_header) // trim(name) // ' not scalar')
endif !}
endif !}
endif !}
!
! set the index
!
if (present(index)) then !{
index_t = index
if (index .le. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Index not positive')
endif !}
else !}{
index_t = 1
endif !}
fm_type = fm_get_type(name)
if (fm_type .eq. 'string') then !{
if (.not. fm_get_value(name, value, index = index_t)) then !{
call mpp_error(FATAL, trim(error_header) // ' Problem getting ' // trim(name))
endif !}
elseif (fm_type .eq. ' ' .and. present(default_value)) then !}{
value = default_value
elseif (fm_type .eq. ' ') then !}{
call mpp_error(FATAL, trim(error_header) // ' Field does not exist: ' // trim(name))
else !}{
call mpp_error(FATAL, trim(error_header) // ' Wrong type for ' // trim(name) // ', found (' // trim(fm_type) // ')')
endif !}
return
end function fm_util_get_string !}
! NAME="fm_util_get_string"
!#######################################################################
!
!
!
! Set an integer array in the Field Manager tree.
!
!
subroutine fm_util_set_value_integer_array(name, value, length, caller, no_overwrite, good_name_list) !{
implicit none
!
! arguments
!
character(len=*), intent(in) :: name
integer, intent(in) :: length
integer, intent(in) :: value(length)
character(len=*), intent(in), optional :: caller
logical, intent(in), optional :: no_overwrite
character(len=fm_path_name_len), intent(in), optional :: good_name_list
!
! Local parameters
!
character(len=48), parameter :: sub_name = 'fm_util_set_value_integer_array'
!
! Local variables
!
character(len=256) :: error_header
character(len=256) :: warn_header
character(len=256) :: note_header
character(len=128) :: caller_str
character(len=32) :: str_error
integer :: field_index
integer :: field_length
integer :: n
logical :: no_overwrite_use
character(len=fm_path_name_len) :: good_name_list_use
logical :: add_name
!
! set the caller string and headers
!
if (present(caller)) then !{
caller_str = '[' // trim(caller) // ']'
else !}{
caller_str = fm_util_default_caller
endif !}
error_header = '==>Error from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
warn_header = '==>Warning from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
note_header = '==>Note from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
!
! check that a name is given (fatal if not)
!
if (name .eq. ' ') then !{
call mpp_error(FATAL, trim(error_header) // ' Empty name given')
endif !}
!
! check that the length is non-negative
!
if (length .lt. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Negative array length')
endif !}
!
! check for whether to overwrite existing values
!
if (present(no_overwrite)) then !{
no_overwrite_use = no_overwrite
else !}{
no_overwrite_use = default_no_overwrite
endif !}
!
! check for whether to save the name in a list
!
if (present(good_name_list)) then !{
good_name_list_use = good_name_list
else !}{
good_name_list_use = default_good_name_list
endif !}
!
! write the data array
!
if (length .eq. 0) then !{
if (.not. (no_overwrite_use .and. fm_exists(name))) then !{
field_index = fm_new_value(name, 0, index = 0)
if (field_index .le. 0) then !{
write (str_error,*) ' with length = ', length
call mpp_error(FATAL, trim(error_header) // ' Problem setting ' // trim(name) // trim(str_error))
endif !}
endif !}
else !}{
if (no_overwrite_use .and. fm_exists(name)) then !{
field_length = fm_get_length(name)
if (field_length .lt. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Problem getting length of ' // trim(name))
endif !}
do n = field_length + 1, length !{
field_index = fm_new_value(name, value(n), index = n)
if (field_index .le. 0) then !{
write (str_error,*) ' with index = ', n
call mpp_error(FATAL, trim(error_header) // ' Problem setting ' // trim(name) // trim(str_error))
endif !}
enddo !} n
else !}{
field_index = fm_new_value(name, value(1))
if (field_index .le. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Problem setting ' // trim(name))
endif !}
do n = 2, length !{
field_index = fm_new_value(name, value(n), index = n)
if (field_index .le. 0) then !{
write (str_error,*) ' with index = ', n
call mpp_error(FATAL, trim(error_header) // ' Problem setting ' // trim(name) // trim(str_error))
endif !}
enddo !} n
endif !}
endif !}
!
! Add the variable name to the list of good names, to be used
! later for a consistency check
!
if (good_name_list_use .ne. ' ') then !{
if (fm_exists(good_name_list_use)) then !{
add_name = fm_util_get_index_string(good_name_list_use, name, &
caller = caller_str) .le. 0 ! true if name does not exist in string array
else !}{
add_name = .true. ! always add to new list
endif !}
if (add_name .and. fm_exists(name)) then !{
if (fm_new_value(good_name_list_use, name, append = .true., create = .true.) .le. 0) then !{
call mpp_error(FATAL, trim(error_header) // &
' Could not add ' // trim(name) // ' to "' // trim(good_name_list_use) // '" list')
endif !}
endif !}
endif !}
return
end subroutine fm_util_set_value_integer_array !}
! NAME="fm_util_set_value_integer_array"
!#######################################################################
!
!
!
! Set a logical array in the Field Manager tree.
!
!
subroutine fm_util_set_value_logical_array(name, value, length, caller, no_overwrite, good_name_list) !{
implicit none
!
! arguments
!
character(len=*), intent(in) :: name
integer, intent(in) :: length
logical, intent(in) :: value(length)
character(len=*), intent(in), optional :: caller
logical, intent(in), optional :: no_overwrite
character(len=fm_path_name_len), intent(in), optional :: good_name_list
!
! Local parameters
!
character(len=48), parameter :: sub_name = 'fm_util_set_value_logical_array'
!
! Local variables
!
character(len=256) :: error_header
character(len=256) :: warn_header
character(len=256) :: note_header
character(len=128) :: caller_str
character(len=32) :: str_error
integer :: field_index
integer :: field_length
integer :: n
logical :: no_overwrite_use
character(len=fm_path_name_len) :: good_name_list_use
logical :: add_name
!
! set the caller string and headers
!
if (present(caller)) then !{
caller_str = '[' // trim(caller) // ']'
else !}{
caller_str = fm_util_default_caller
endif !}
error_header = '==>Error from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
warn_header = '==>Warning from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
note_header = '==>Note from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
!
! check that a name is given (fatal if not)
!
if (name .eq. ' ') then !{
call mpp_error(FATAL, trim(error_header) // ' Empty name given')
endif !}
!
! check that the length is non-negative
!
if (length .lt. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Negative array length')
endif !}
!
! check for whether to overwrite existing values
!
if (present(no_overwrite)) then !{
no_overwrite_use = no_overwrite
else !}{
no_overwrite_use = default_no_overwrite
endif !}
!
! check for whether to save the name in a list
!
if (present(good_name_list)) then !{
good_name_list_use = good_name_list
else !}{
good_name_list_use = default_good_name_list
endif !}
!
! write the data array
!
if (length .eq. 0) then !{
if (.not. (no_overwrite_use .and. fm_exists(name))) then !{
field_index = fm_new_value(name, .false., index = 0)
if (field_index .le. 0) then !{
write (str_error,*) ' with length = ', length
call mpp_error(FATAL, trim(error_header) // ' Problem setting ' // trim(name) // trim(str_error))
endif !}
endif !}
else !}{
if (no_overwrite_use .and. fm_exists(name)) then !{
field_length = fm_get_length(name)
if (field_length .lt. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Problem getting length of ' // trim(name))
endif !}
do n = field_length + 1, length !{
field_index = fm_new_value(name, value(n), index = n)
if (field_index .le. 0) then !{
write (str_error,*) ' with index = ', n
call mpp_error(FATAL, trim(error_header) // ' Problem setting ' // trim(name) // trim(str_error))
endif !}
enddo !} n
else !}{
field_index = fm_new_value(name, value(1))
if (field_index .le. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Problem setting ' // trim(name))
endif !}
do n = 2, length !{
field_index = fm_new_value(name, value(n), index = n)
if (field_index .le. 0) then !{
write (str_error,*) ' with index = ', n
call mpp_error(FATAL, trim(error_header) // ' Problem setting ' // trim(name) // trim(str_error))
endif !}
enddo !} n
endif !}
endif !}
!
! Add the variable name to the list of good names, to be used
! later for a consistency check
!
if (good_name_list_use .ne. ' ') then !{
if (fm_exists(good_name_list_use)) then !{
add_name = fm_util_get_index_string(good_name_list_use, name, &
caller = caller_str) .le. 0 ! true if name does not exist in string array
else !}{
add_name = .true. ! always add to new list
endif !}
if (add_name .and. fm_exists(name)) then !{
if (fm_new_value(good_name_list_use, name, append = .true., create = .true.) .le. 0) then !{
call mpp_error(FATAL, trim(error_header) // &
' Could not add ' // trim(name) // ' to "' // trim(good_name_list_use) // '" list')
endif !}
endif !}
endif !}
return
end subroutine fm_util_set_value_logical_array !}
! NAME="fm_util_set_value_logical_array"
!#######################################################################
!
!
!
! Set a real array in the Field Manager tree.
!
!
subroutine fm_util_set_value_real_array(name, value, length, caller, no_overwrite, good_name_list) !{
implicit none
!
! arguments
!
character(len=*), intent(in) :: name
integer, intent(in) :: length
real, intent(in) :: value(length)
character(len=*), intent(in), optional :: caller
logical, intent(in), optional :: no_overwrite
character(len=fm_path_name_len), intent(in), optional :: good_name_list
!
! Local parameters
!
character(len=48), parameter :: sub_name = 'fm_util_set_value_real_array'
!
! Local variables
!
character(len=256) :: error_header
character(len=256) :: warn_header
character(len=256) :: note_header
character(len=128) :: caller_str
character(len=32) :: str_error
integer :: field_index
integer :: field_length
integer :: n
logical :: no_overwrite_use
character(len=fm_path_name_len) :: good_name_list_use
logical :: add_name
!
! set the caller string and headers
!
if (present(caller)) then !{
caller_str = '[' // trim(caller) // ']'
else !}{
caller_str = fm_util_default_caller
endif !}
error_header = '==>Error from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
warn_header = '==>Warning from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
note_header = '==>Note from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
!
! check that a name is given (fatal if not)
!
if (name .eq. ' ') then !{
call mpp_error(FATAL, trim(error_header) // ' Empty name given')
endif !}
!
! check that the length is non-negative
!
if (length .lt. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Negative array length')
endif !}
!
! check for whether to overwrite existing values
!
if (present(no_overwrite)) then !{
no_overwrite_use = no_overwrite
else !}{
no_overwrite_use = default_no_overwrite
endif !}
!
! check for whether to save the name in a list
!
if (present(good_name_list)) then !{
good_name_list_use = good_name_list
else !}{
good_name_list_use = default_good_name_list
endif !}
!
! write the data array
!
if (length .eq. 0) then !{
if (.not. (no_overwrite_use .and. fm_exists(name))) then !{
field_index = fm_new_value(name, 0.0, index = 0)
if (field_index .le. 0) then !{
write (str_error,*) ' with length = ', length
call mpp_error(FATAL, trim(error_header) // ' Problem setting ' // trim(name) // trim(str_error))
endif !}
endif !}
else !}{
if (no_overwrite_use .and. fm_exists(name)) then !{
field_length = fm_get_length(name)
if (field_length .lt. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Problem getting length of ' // trim(name))
endif !}
do n = field_length + 1, length !{
field_index = fm_new_value(name, value(n), index = n)
if (field_index .le. 0) then !{
write (str_error,*) ' with index = ', n
call mpp_error(FATAL, trim(error_header) // ' Problem setting ' // trim(name) // trim(str_error))
endif !}
enddo !} n
else !}{
field_index = fm_new_value(name, value(1))
if (field_index .le. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Problem setting ' // trim(name))
endif !}
do n = 2, length !{
field_index = fm_new_value(name, value(n), index = n)
if (field_index .le. 0) then !{
write (str_error,*) ' with index = ', n
call mpp_error(FATAL, trim(error_header) // ' Problem setting ' // trim(name) // trim(str_error))
endif !}
enddo !} n
endif !}
endif !}
!
! Add the variable name to the list of good names, to be used
! later for a consistency check
!
if (good_name_list_use .ne. ' ') then !{
if (fm_exists(good_name_list_use)) then !{
add_name = fm_util_get_index_string(good_name_list_use, name, &
caller = caller_str) .le. 0 ! true if name does not exist in string array
else !}{
add_name = .true. ! always add to new list
endif !}
if (add_name .and. fm_exists(name)) then !{
if (fm_new_value(good_name_list_use, name, append = .true., create = .true.) .le. 0) then !{
call mpp_error(FATAL, trim(error_header) // &
' Could not add ' // trim(name) // ' to "' // trim(good_name_list_use) // '" list')
endif !}
endif !}
endif !}
return
end subroutine fm_util_set_value_real_array !}
! NAME="fm_util_set_value_real_array"
!#######################################################################
!
!
!
! Set a string array in the Field Manager tree.
!
!
subroutine fm_util_set_value_string_array(name, value, length, caller, no_overwrite, good_name_list) !{
implicit none
!
! arguments
!
character(len=*), intent(in) :: name
integer, intent(in) :: length
character(len=*), intent(in) :: value(length)
character(len=*), intent(in), optional :: caller
logical, intent(in), optional :: no_overwrite
character(len=fm_path_name_len), intent(in), optional :: good_name_list
!
! Local parameters
!
character(len=48), parameter :: sub_name = 'fm_util_set_value_string_array'
!
! Local variables
!
character(len=256) :: error_header
character(len=256) :: warn_header
character(len=256) :: note_header
character(len=128) :: caller_str
character(len=32) :: str_error
integer :: field_index
integer :: field_length
integer :: n
logical :: no_overwrite_use
character(len=fm_path_name_len) :: good_name_list_use
logical :: add_name
!
! set the caller string and headers
!
if (present(caller)) then !{
caller_str = '[' // trim(caller) // ']'
else !}{
caller_str = fm_util_default_caller
endif !}
error_header = '==>Error from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
warn_header = '==>Warning from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
note_header = '==>Note from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
!
! check that a name is given (fatal if not)
!
if (name .eq. ' ') then !{
call mpp_error(FATAL, trim(error_header) // ' Empty name given')
endif !}
!
! check that the length is non-negative
!
if (length .lt. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Negative array length')
endif !}
!
! check for whether to overwrite existing values
!
if (present(no_overwrite)) then !{
no_overwrite_use = no_overwrite
else !}{
no_overwrite_use = default_no_overwrite
endif !}
!
! check for whether to save the name in a list
!
if (present(good_name_list)) then !{
good_name_list_use = good_name_list
else !}{
good_name_list_use = default_good_name_list
endif !}
!
! write the data array
!
if (length .eq. 0) then !{
if (.not. (no_overwrite_use .and. fm_exists(name))) then !{
field_index = fm_new_value(name, ' ', index = 0)
if (field_index .le. 0) then !{
write (str_error,*) ' with length = ', length
call mpp_error(FATAL, trim(error_header) // ' Problem setting ' // trim(name) // trim(str_error))
endif !}
endif !}
else !}{
if (no_overwrite_use .and. fm_exists(name)) then !{
field_length = fm_get_length(name)
if (field_length .lt. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Problem getting length of ' // trim(name))
endif !}
do n = field_length + 1, length !{
field_index = fm_new_value(name, value(n), index = n)
if (field_index .le. 0) then !{
write (str_error,*) ' with index = ', n
call mpp_error(FATAL, trim(error_header) // ' Problem setting ' // trim(name) // trim(str_error))
endif !}
enddo !} n
else !}{
field_index = fm_new_value(name, value(1))
if (field_index .le. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Problem setting ' // trim(name))
endif !}
do n = 2, length !{
field_index = fm_new_value(name, value(n), index = n)
if (field_index .le. 0) then !{
write (str_error,*) ' with index = ', n
call mpp_error(FATAL, trim(error_header) // ' Problem setting ' // trim(name) // trim(str_error))
endif !}
enddo !} n
endif !}
endif !}
!
! Add the variable name to the list of good names, to be used
! later for a consistency check
!
if (good_name_list_use .ne. ' ') then !{
if (fm_exists(good_name_list_use)) then !{
add_name = fm_util_get_index_string(good_name_list_use, name, &
caller = caller_str) .le. 0 ! true if name does not exist in string array
else !}{
add_name = .true. ! always add to new list
endif !}
if (add_name .and. fm_exists(name)) then !{
if (fm_new_value(good_name_list_use, name, append = .true., create = .true.) .le. 0) then !{
call mpp_error(FATAL, trim(error_header) // &
' Could not add ' // trim(name) // ' to "' // trim(good_name_list_use) // '" list')
endif !}
endif !}
endif !}
return
end subroutine fm_util_set_value_string_array !}
! NAME="fm_util_set_value_string_array"
!#######################################################################
!
!
!
! Set an integer value in the Field Manager tree.
!
!
subroutine fm_util_set_value_integer(name, value, caller, index, append, no_create, &
no_overwrite, good_name_list) !{
implicit none
!
! arguments
!
character(len=*), intent(in) :: name
integer, intent(in) :: value
character(len=*), intent(in), optional :: caller
integer, intent(in), optional :: index
logical, intent(in), optional :: append
logical, intent(in), optional :: no_create
logical, intent(in), optional :: no_overwrite
character(len=*), intent(in), optional :: good_name_list
!
! Local parameters
!
character(len=48), parameter :: sub_name = 'fm_util_set_value_integer'
!
! Local variables
!
character(len=256) :: error_header
character(len=256) :: warn_header
character(len=256) :: note_header
character(len=128) :: caller_str
character(len=32) :: str_error
integer :: field_index
logical :: no_overwrite_use
integer :: field_length
character(len=fm_path_name_len) :: good_name_list_use
logical :: create
logical :: add_name
!
! set the caller string and headers
!
if (present(caller)) then !{
caller_str = '[' // trim(caller) // ']'
else !}{
caller_str = fm_util_default_caller
endif !}
error_header = '==>Error from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
warn_header = '==>Warning from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
note_header = '==>Note from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
!
! check that a name is given (fatal if not)
!
if (name .eq. ' ') then !{
call mpp_error(FATAL, trim(error_header) // ' Empty name given')
endif !}
!
! check that append and index are not both given
!
if (present(index) .and. present(append)) then !{
call mpp_error(FATAL, trim(error_header) // ' Append and index both given as arguments')
endif !}
!
! check for whether to overwrite existing values
!
if (present(no_overwrite)) then !{
no_overwrite_use = no_overwrite
else !}{
no_overwrite_use = default_no_overwrite
endif !}
!
! check for whether to save the name in a list
!
if (present(good_name_list)) then !{
good_name_list_use = good_name_list
else !}{
good_name_list_use = default_good_name_list
endif !}
if (present(no_create)) then !{
create = .not. no_create
if (no_create .and. (present(append) .or. present(index))) then !{
call mpp_error(FATAL, trim(error_header) // ' append or index are present when no_create is true for ' // trim(name))
endif !}
else !}{
create = .true.
endif !}
if (present(index)) then !{
if (fm_exists(name)) then !{
field_length = fm_get_length(name)
if (field_length .lt. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Problem getting length of ' // trim(name))
endif !}
if (.not. (no_overwrite_use .and. field_length .ge. index)) then !{
field_index = fm_new_value(name, value, index = index)
if (field_index .le. 0) then !{
write (str_error,*) ' with index = ', index
call mpp_error(FATAL, trim(error_header) // ' Problem overwriting ' // trim(name) // trim(str_error))
endif !}
endif !}
else !}{
field_index = fm_new_value(name, value, index = index)
if (field_index .le. 0) then !{
write (str_error,*) ' with index = ', index
call mpp_error(FATAL, trim(error_header) // ' Problem setting ' // trim(name) // trim(str_error))
endif !}
endif !}
elseif (present(append)) then !}{
field_index = fm_new_value(name, value, append = append)
if (field_index .le. 0) then !{
write (str_error,*) ' with append = ', append
call mpp_error(FATAL, trim(error_header) // ' Problem setting ' // trim(name) // trim(str_error))
endif !}
else !}{
if (fm_exists(name)) then !{
if (.not. no_overwrite_use) then !{
field_index = fm_new_value(name, value)
if (field_index .le. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Problem overwriting ' // trim(name))
endif !}
endif !}
elseif (create) then !}{
field_index = fm_new_value(name, value)
if (field_index .le. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Problem creating ' // trim(name))
endif !}
endif !}
endif !}
!
! Add the variable name to the list of good names, to be used
! later for a consistency check, unless the field did not exist and we did not create it
!
if (good_name_list_use .ne. ' ') then !{
if (fm_exists(good_name_list_use)) then !{
add_name = fm_util_get_index_string(good_name_list_use, name, &
caller = caller_str) .le. 0 ! true if name does not exist in string array
else !}{
add_name = .true. ! always add to new list
endif !}
if (add_name .and. fm_exists(name)) then !{
if (fm_new_value(good_name_list_use, name, append = .true., create = .true.) .le. 0) then !{
call mpp_error(FATAL, trim(error_header) // &
' Could not add ' // trim(name) // ' to "' // trim(good_name_list_use) // '" list')
endif !}
endif !}
endif !}
return
end subroutine fm_util_set_value_integer !}
! NAME="fm_util_set_value_integer"
!#######################################################################
!
!
!
! Set a logical value in the Field Manager tree.
!
!
subroutine fm_util_set_value_logical(name, value, caller, index, append, no_create, &
no_overwrite, good_name_list) !{
implicit none
!
! arguments
!
character(len=*), intent(in) :: name
logical, intent(in) :: value
character(len=*), intent(in), optional :: caller
integer, intent(in), optional :: index
logical, intent(in), optional :: append
logical, intent(in), optional :: no_create
logical, intent(in), optional :: no_overwrite
character(len=*), intent(in), optional :: good_name_list
!
! Local parameters
!
character(len=48), parameter :: sub_name = 'fm_util_set_value_logical'
!
! Local variables
!
character(len=256) :: error_header
character(len=256) :: warn_header
character(len=256) :: note_header
character(len=128) :: caller_str
character(len=32) :: str_error
integer :: field_index
logical :: no_overwrite_use
integer :: field_length
character(len=fm_path_name_len) :: good_name_list_use
logical :: create
logical :: add_name
!
! set the caller string and headers
!
if (present(caller)) then !{
caller_str = '[' // trim(caller) // ']'
else !}{
caller_str = fm_util_default_caller
endif !}
error_header = '==>Error from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
warn_header = '==>Warning from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
note_header = '==>Note from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
!
! check that a name is given (fatal if not)
!
if (name .eq. ' ') then !{
call mpp_error(FATAL, trim(error_header) // ' Empty name given')
endif !}
!
! check that append and index are not both given
!
if (present(index) .and. present(append)) then !{
call mpp_error(FATAL, trim(error_header) // ' Append and index both given as arguments')
endif !}
!
! check for whether to overwrite existing values
!
if (present(no_overwrite)) then !{
no_overwrite_use = no_overwrite
else !}{
no_overwrite_use = default_no_overwrite
endif !}
!
! check for whether to save the name in a list
!
if (present(good_name_list)) then !{
good_name_list_use = good_name_list
else !}{
good_name_list_use = default_good_name_list
endif !}
if (present(no_create)) then !{
create = .not. no_create
if (no_create .and. (present(append) .or. present(index))) then !{
call mpp_error(FATAL, trim(error_header) // ' append or index are present when no_create is true for ' // trim(name))
endif !}
else !}{
create = .true.
endif !}
if (present(index)) then !{
if (fm_exists(name)) then !{
field_length = fm_get_length(name)
if (field_length .lt. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Problem getting length of ' // trim(name))
endif !}
if (.not. (no_overwrite_use .and. field_length .ge. index)) then !{
field_index = fm_new_value(name, value, index = index)
if (field_index .le. 0) then !{
write (str_error,*) ' with index = ', index
call mpp_error(FATAL, trim(error_header) // ' Problem overwriting ' // trim(name) // trim(str_error))
endif !}
endif !}
else !}{
field_index = fm_new_value(name, value, index = index)
if (field_index .le. 0) then !{
write (str_error,*) ' with index = ', index
call mpp_error(FATAL, trim(error_header) // ' Problem setting ' // trim(name) // trim(str_error))
endif !}
endif !}
elseif (present(append)) then !}{
field_index = fm_new_value(name, value, append = append)
if (field_index .le. 0) then !{
write (str_error,*) ' with append = ', append
call mpp_error(FATAL, trim(error_header) // ' Problem setting ' // trim(name) // trim(str_error))
endif !}
else !}{
if (fm_exists(name)) then !{
if (.not. no_overwrite_use) then !{
field_index = fm_new_value(name, value)
if (field_index .le. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Problem overwriting ' // trim(name))
endif !}
endif !}
elseif (create) then !}{
field_index = fm_new_value(name, value)
if (field_index .le. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Problem creating ' // trim(name))
endif !}
endif !}
endif !}
!
! Add the variable name to the list of good names, to be used
! later for a consistency check, unless the field did not exist and we did not create it
!
if (good_name_list_use .ne. ' ') then !{
if (fm_exists(good_name_list_use)) then !{
add_name = fm_util_get_index_string(good_name_list_use, name, &
caller = caller_str) .le. 0 ! true if name does not exist in string array
else !}{
add_name = .true. ! always add to new list
endif !}
if (add_name .and. fm_exists(name)) then !{
if (fm_new_value(good_name_list_use, name, append = .true., create = .true.) .le. 0) then !{
call mpp_error(FATAL, trim(error_header) // &
' Could not add ' // trim(name) // ' to "' // trim(good_name_list_use) // '" list')
endif !}
endif !}
endif !}
return
end subroutine fm_util_set_value_logical !}
! NAME="fm_util_set_value_logical"
!#######################################################################
!
!
!
! Set a real value in the Field Manager tree.
!
!
subroutine fm_util_set_value_real(name, value, caller, index, append, no_create, &
no_overwrite, good_name_list) !{
implicit none
!
! arguments
!
character(len=*), intent(in) :: name
real, intent(in) :: value
character(len=*), intent(in), optional :: caller
integer, intent(in), optional :: index
logical, intent(in), optional :: append
logical, intent(in), optional :: no_create
logical, intent(in), optional :: no_overwrite
character(len=*), intent(in), optional :: good_name_list
!
! Local parameters
!
character(len=48), parameter :: sub_name = 'fm_util_set_value_real'
!
! Local variables
!
character(len=256) :: error_header
character(len=256) :: warn_header
character(len=256) :: note_header
character(len=128) :: caller_str
character(len=32) :: str_error
integer :: field_index
logical :: no_overwrite_use
integer :: field_length
character(len=fm_path_name_len) :: good_name_list_use
logical :: create
logical :: add_name
!
! set the caller string and headers
!
if (present(caller)) then !{
caller_str = '[' // trim(caller) // ']'
else !}{
caller_str = fm_util_default_caller
endif !}
error_header = '==>Error from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
warn_header = '==>Warning from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
note_header = '==>Note from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
!
! check that a name is given (fatal if not)
!
if (name .eq. ' ') then !{
call mpp_error(FATAL, trim(error_header) // ' Empty name given')
endif !}
!
! check that append and index are not both given
!
if (present(index) .and. present(append)) then !{
call mpp_error(FATAL, trim(error_header) // ' Append and index both given as arguments')
endif !}
!
! check for whether to overwrite existing values
!
if (present(no_overwrite)) then !{
no_overwrite_use = no_overwrite
else !}{
no_overwrite_use = default_no_overwrite
endif !}
!
! check for whether to save the name in a list
!
if (present(good_name_list)) then !{
good_name_list_use = good_name_list
else !}{
good_name_list_use = default_good_name_list
endif !}
if (present(no_create)) then !{
create = .not. no_create
if (no_create .and. (present(append) .or. present(index))) then !{
call mpp_error(FATAL, trim(error_header) // ' append or index are present when no_create is true for ' // trim(name))
endif !}
else !}{
create = .true.
endif !}
if (present(index)) then !{
if (fm_exists(name)) then !{
field_length = fm_get_length(name)
if (field_length .lt. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Problem getting length of ' // trim(name))
endif !}
if (.not. (no_overwrite_use .and. field_length .ge. index)) then !{
field_index = fm_new_value(name, value, index = index)
if (field_index .le. 0) then !{
write (str_error,*) ' with index = ', index
call mpp_error(FATAL, trim(error_header) // ' Problem overwriting ' // trim(name) // trim(str_error))
endif !}
endif !}
else !}{
field_index = fm_new_value(name, value, index = index)
if (field_index .le. 0) then !{
write (str_error,*) ' with index = ', index
call mpp_error(FATAL, trim(error_header) // ' Problem setting ' // trim(name) // trim(str_error))
endif !}
endif !}
elseif (present(append)) then !}{
field_index = fm_new_value(name, value, append = append)
if (field_index .le. 0) then !{
write (str_error,*) ' with append = ', append
call mpp_error(FATAL, trim(error_header) // ' Problem setting ' // trim(name) // trim(str_error))
endif !}
else !}{
if (fm_exists(name)) then !{
if (.not. no_overwrite_use) then !{
field_index = fm_new_value(name, value)
if (field_index .le. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Problem overwriting ' // trim(name))
endif !}
endif !}
elseif (create) then !}{
field_index = fm_new_value(name, value)
if (field_index .le. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Problem creating ' // trim(name))
endif !}
endif !}
endif !}
!
! Add the variable name to the list of good names, to be used
! later for a consistency check, unless the field did not exist and we did not create it
!
if (good_name_list_use .ne. ' ') then !{
if (fm_exists(good_name_list_use)) then !{
add_name = fm_util_get_index_string(good_name_list_use, name, &
caller = caller_str) .le. 0 ! true if name does not exist in string array
else !}{
add_name = .true. ! always add to new list
endif !}
if (add_name .and. fm_exists(name)) then !{
if (fm_new_value(good_name_list_use, name, append = .true., create = .true.) .le. 0) then !{
call mpp_error(FATAL, trim(error_header) // &
' Could not add ' // trim(name) // ' to "' // trim(good_name_list_use) // '" list')
endif !}
endif !}
endif !}
return
end subroutine fm_util_set_value_real !}
! NAME="fm_util_set_value_real"
!#######################################################################
!
!
!
! Set a string value in the Field Manager tree.
!
!
subroutine fm_util_set_value_string(name, value, caller, index, append, no_create, &
no_overwrite, good_name_list) !{
implicit none
!
! arguments
!
character(len=*), intent(in) :: name
character(len=*), intent(in) :: value
character(len=*), intent(in), optional :: caller
integer, intent(in), optional :: index
logical, intent(in), optional :: append
logical, intent(in), optional :: no_create
logical, intent(in), optional :: no_overwrite
character(len=*), intent(in), optional :: good_name_list
!
! Local parameters
!
character(len=48), parameter :: sub_name = 'fm_util_set_value_string'
!
! Local variables
!
character(len=256) :: error_header
character(len=256) :: warn_header
character(len=256) :: note_header
character(len=128) :: caller_str
character(len=32) :: str_error
integer :: field_index
logical :: no_overwrite_use
integer :: field_length
character(len=fm_path_name_len) :: good_name_list_use
logical :: create
logical :: add_name
!
! set the caller string and headers
!
if (present(caller)) then !{
caller_str = '[' // trim(caller) // ']'
else !}{
caller_str = fm_util_default_caller
endif !}
error_header = '==>Error from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
warn_header = '==>Warning from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
note_header = '==>Note from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
!
! check that a name is given (fatal if not)
!
if (name .eq. ' ') then !{
call mpp_error(FATAL, trim(error_header) // ' Empty name given')
endif !}
!
! check that append and index are not both given
!
if (present(index) .and. present(append)) then !{
call mpp_error(FATAL, trim(error_header) // ' Append and index both given as arguments')
endif !}
!
! check for whether to overwrite existing values
!
if (present(no_overwrite)) then !{
no_overwrite_use = no_overwrite
else !}{
no_overwrite_use = default_no_overwrite
endif !}
!
! check for whether to save the name in a list
!
if (present(good_name_list)) then !{
good_name_list_use = good_name_list
else !}{
good_name_list_use = default_good_name_list
endif !}
if (present(no_create)) then !{
create = .not. no_create
if (no_create .and. (present(append) .or. present(index))) then !{
call mpp_error(FATAL, trim(error_header) // ' append or index are present when no_create is true for ' // trim(name))
endif !}
else !}{
create = .true.
endif !}
if (present(index)) then !{
if (fm_exists(name)) then !{
field_length = fm_get_length(name)
if (field_length .lt. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Problem getting length of ' // trim(name))
endif !}
if (.not. (no_overwrite_use .and. field_length .ge. index)) then !{
field_index = fm_new_value(name, value, index = index)
if (field_index .le. 0) then !{
write (str_error,*) ' with index = ', index
call mpp_error(FATAL, trim(error_header) // ' Problem overwriting ' // trim(name) // trim(str_error))
endif !}
endif !}
else !}{
field_index = fm_new_value(name, value, index = index)
if (field_index .le. 0) then !{
write (str_error,*) ' with index = ', index
call mpp_error(FATAL, trim(error_header) // ' Problem setting ' // trim(name) // trim(str_error))
endif !}
endif !}
elseif (present(append)) then !}{
field_index = fm_new_value(name, value, append = append)
if (field_index .le. 0) then !{
write (str_error,*) ' with append = ', append
call mpp_error(FATAL, trim(error_header) // ' Problem setting ' // trim(name) // trim(str_error))
endif !}
else !}{
if (fm_exists(name)) then !{
if (.not. no_overwrite_use) then !{
field_index = fm_new_value(name, value)
if (field_index .le. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Problem overwriting ' // trim(name))
endif !}
endif !}
elseif (create) then !}{
field_index = fm_new_value(name, value)
if (field_index .le. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Problem creating ' // trim(name))
endif !}
endif !}
endif !}
!
! Add the variable name to the list of good names, to be used
! later for a consistency check, unless the field did not exist and we did not create it
!
if (good_name_list_use .ne. ' ') then !{
if (fm_exists(good_name_list_use)) then !{
add_name = fm_util_get_index_string(good_name_list_use, name, &
caller = caller_str) .le. 0 ! true if name does not exist in string array
else !}{
add_name = .true. ! always add to new list
endif !}
if (add_name .and. fm_exists(name)) then !{
if (fm_new_value(good_name_list_use, name, append = .true., create = .true.) .le. 0) then !{
call mpp_error(FATAL, trim(error_header) // &
' Could not add ' // trim(name) // ' to "' // trim(good_name_list_use) // '" list')
endif !}
endif !}
endif !}
return
end subroutine fm_util_set_value_string !}
! NAME="fm_util_set_value_string"
!#######################################################################
!
!
!
! Start processing a namelist
!
!
subroutine fm_util_start_namelist(path, name, caller, no_overwrite, check) !{
implicit none
!
! arguments
!
character(len=*), intent(in) :: path
character(len=*), intent(in) :: name
character(len=*), intent(in), optional :: caller
logical, intent(in), optional :: no_overwrite
logical, intent(in), optional :: check
!
! Local parameters
!
character(len=48), parameter :: sub_name = 'fm_util_start_namelist'
!
! Local variables
!
integer :: namelist_index
character(len=fm_path_name_len) :: path_name
character(len=256) :: error_header
character(len=256) :: warn_header
character(len=256) :: note_header
character(len=128) :: caller_str
integer :: out_unit
out_unit = stdout()
!
! set the caller string and headers
!
if (present(caller)) then !{
caller_str = '[' // trim(caller) // ']'
else !}{
caller_str = fm_util_default_caller
endif !}
error_header = '==>Error from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
warn_header = '==>Warning from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
note_header = '==>Note from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
!
! check that a name is given (fatal if not)
!
if (name .eq. ' ') then !{
call mpp_error(FATAL, trim(error_header) // ' Empty name given')
endif !}
!
! Concatenate the path and name
!
if (path .eq. ' ') then !{
path_name = name
else !}{
path_name = trim(path) // '/' // name
endif !}
save_path = path
save_name = name
!
! set the default caller string, if desired
!
if (present(caller)) then !{
call fm_util_set_caller(caller)
else !}{
call fm_util_reset_caller
endif !}
!
! set the default no_overwrite flag, if desired
!
if (present(no_overwrite)) then !{
call fm_util_set_no_overwrite(no_overwrite)
else !}{
call fm_util_reset_no_overwrite
endif !}
!
! set the default good_name_list string, if desired
!
if (present(check)) then !{
if (check) then !{
call fm_util_set_good_name_list('/ocean_mod/GOOD/namelists/' // trim(path_name) // '/good_list')
else !}{
call fm_util_reset_good_name_list
endif !}
else !}{
call fm_util_reset_good_name_list
endif !}
!
! Process the namelist
!
write (out_unit,*)
write (out_unit,*) trim(note_header), ' Processing namelist ', trim(path_name)
!
! Check whether the namelist already exists. If so, then use that one
!
namelist_index = fm_get_index('/ocean_mod/namelists/' // trim(path_name))
if (namelist_index .gt. 0) then !{
!write (out_unit,*) trim(note_header), ' Namelist already set with index ', namelist_index
else !}{
!
! Set a new namelist and get its index
!
namelist_index = fm_new_list('/ocean_mod/namelists/' // trim(path_name), create = .true.)
if (namelist_index .le. 0) then !{
call mpp_error(FATAL, trim(error_header) // ' Could not set namelist ' // trim(path_name))
endif !}
endif !}
!
! Add the namelist name to the list of good namelists, to be used
! later for a consistency check
!
if (fm_new_value('/ocean_mod/GOOD/namelists/' // trim(path) // '/good_values', &
name, append = .true., create = .true.) .le. 0) then !{
call mpp_error(FATAL, trim(error_header) // &
' Could not add ' // trim(name) // ' to "' // trim(path) // '/good_values" list')
endif !}
!
! Change to the new namelist, first saving the current list
!
save_current_list = fm_get_current_list()
if (save_current_list .eq. ' ') then !{
call mpp_error(FATAL, trim(error_header) // ' Could not get the current list')
endif !}
if (.not. fm_change_list('/ocean_mod/namelists/' // trim(path_name))) then !{
call mpp_error(FATAL, trim(error_header) // ' Could not change to the namelist ' // trim(path_name))
endif !}
return
end subroutine fm_util_start_namelist !}
! NAME="fm_util_start_namelist"
!#######################################################################
!
!
!
! Finish up processing a namelist
!
!
subroutine fm_util_end_namelist(path, name, caller, check) !{
implicit none
!
! arguments
!
character(len=*), intent(in) :: path
character(len=*), intent(in) :: name
character(len=*), intent(in), optional :: caller
logical, intent(in), optional :: check
!
! Local parameters
!
character(len=48), parameter :: sub_name = 'fm_util_end_namelist'
!
! Local variables
!
character(len=fm_string_len), pointer, dimension(:) :: good_list => NULL()
character(len=fm_path_name_len) :: path_name
character(len=256) :: error_header
character(len=256) :: warn_header
character(len=256) :: note_header
character(len=128) :: caller_str
!
! set the caller string and headers
!
if (present(caller)) then !{
caller_str = '[' // trim(caller) // ']'
else !}{
caller_str = fm_util_default_caller
endif !}
error_header = '==>Error from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
warn_header = '==>Warning from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
note_header = '==>Note from ' // trim(mod_name) // &
'(' // trim(sub_name) // ')' // trim(caller_str) // ':'
!
! check that a path is given (fatal if not)
!
if (name .eq. ' ') then !{
call mpp_error(FATAL, trim(error_header) // ' Empty name given')
endif !}
!
! Check that the path ane name match the preceding call to
! fm_util_start_namelist
!
if (path .ne. save_path) then !{
call mpp_error(FATAL, trim(error_header) // ' Path "' // trim(path) // '" does not match saved path "' // trim(save_path) // '"')
elseif (name .ne. save_name) then !}{
call mpp_error(FATAL, trim(error_header) // ' Name "' // trim(name) // '" does not match saved name "' // trim(save_name) // '"')
endif !}
!
! Concatenate the path and name
!
if (path .eq. ' ') then !{
path_name = name
else !}{
path_name = trim(path) // '/' // name
endif !}
save_path = ' '
save_name = ' '
!
! Check for any errors in the number of fields in this list
!
if (present(check)) then !{
if (check) then !{
if (caller_str .eq. ' ') then !{
caller_str = trim(mod_name) // '(' // trim(sub_name) // ')'
endif !}
good_list => fm_util_get_string_array('/ocean_mod/GOOD/namelists/' // trim(path_name) // '/good_list', &
caller = trim(mod_name) // '(' // trim(sub_name) // ')')
if (associated(good_list)) then !{
call fm_util_check_for_bad_fields('/ocean_mod/namelists/' // trim(path_name), good_list, caller = caller_str)
deallocate(good_list)
else !}{
call mpp_error(FATAL, trim(error_header) // ' Empty "' // trim(path_name) // '" list')
endif !}
endif !}
endif !}
!
! Change back to the saved list
!
if (save_current_list .ne. ' ') then !{
if (.not. fm_change_list(save_current_list)) then !{
call mpp_error(FATAL, trim(error_header) // ' Could not change to the saved list: ' // trim(save_current_list))
endif !}
endif !}
save_current_list = ' '
!
! reset the default caller string
!
call fm_util_reset_caller
!
! reset the default no_overwrite string
!
call fm_util_reset_no_overwrite
!
! reset the default good_name_list string
!
call fm_util_reset_good_name_list
return
end subroutine fm_util_end_namelist !}
! NAME="fm_util_end_namelist"
end module fm_util_mod !}