22 #define MAXFIELDS_ 250 25 #ifndef MAXFIELDMETHODS_ 26 #define MAXFIELDMETHODS_ 250 196 use fms_mod,
only : lowercase, &
204 #include<file_version.h> 319 character(len=11),
parameter,
public,
dimension(NUM_MODELS) :: &
320 model_names=(/
'atmospheric',
'oceanic ',
'land ',
'ice ',
'coupler '/)
330 character (len=fm_field_name_len),
dimension(:),
pointer :: names => null()
369 character(len=fm_string_len) :: method_name
370 character(len=fm_string_len) :: method_control
390 character(len=fm_string_len) :: method_name
470 character(len=1),
parameter ::
comma =
"," 472 character(len=1),
parameter ::
dquote =
'"' 473 character(len=1),
parameter ::
equal =
'=' 475 character(len=1),
parameter ::
space =
' ' 476 character(len=1),
parameter ::
squote =
"'" 477 character(len=1),
parameter ::
tab = char(9)
497 character(len=fm_field_name_len) :: field_type
498 character(len=fm_string_len) :: field_name
499 integer :: model, num_methods
504 character(len=fm_field_name_len) :: fld_type
505 character(len=fm_field_name_len) :: mod_name
506 character(len=fm_string_len) :: fld_name
510 character(len=fm_field_name_len) :: fld_type
511 character(len=fm_field_name_len) :: mod_name
515 character (len=fm_field_name_len) :: name
518 integer :: field_type
524 integer,
pointer,
dimension(:) :: i_value => null()
525 logical,
pointer,
dimension(:) :: l_value => null()
526 real,
pointer,
dimension(:) :: r_value => null()
527 character(len=fm_string_len),
pointer,
dimension(:) :: s_value => null()
547 character(len=52) ::
set =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" 550 character(len=50) ::
set_nonexp =
"ABCDFGHIJKLMNOPQRSTUVWXYZabcdfghijklmnopqrstuvwxyz" 553 character(len=13) ::
setnum =
"0123456789+-." 590 integer,
intent(out),
optional :: nfields
597 character(len=fm_string_len),
intent(in),
optional :: table_name
602 character(len=18),
parameter :: sub_name =
'field_manager_init' 603 character(len=64),
parameter :: error_header =
'==>Error from ' // trim(
module_name) // &
604 '(' // trim(sub_name) //
'): ' 605 character(len=64),
parameter :: warn_header =
'==>Warning from ' // trim(
module_name) // &
606 '(' // trim(sub_name) //
'): ' 607 character(len=64),
parameter :: note_header =
'==>Note from ' // trim(
module_name) // &
608 '(' // trim(sub_name) //
'): ' 613 character(len=1024) :: record
614 character(len=fm_path_name_len) :: control_str
615 character(len=fm_path_name_len) :: list_name
616 character(len=fm_path_name_len) :: method_name
617 character(len=fm_path_name_len) :: name_str
618 character(len=fm_path_name_len) :: type_str
619 character(len=fm_path_name_len) :: val_name
620 character(len=fm_string_len) :: tbl_name
624 integer :: index_list_name
633 logical :: flag_method
634 logical :: fm_success
648 #ifdef PRESERVE_UNIT_CASE 654 call mpp_error(note,trim(note_header)//
"Preserving the unit's case is experimental.")
662 if (.not.
PRESENT(table_name))
then 663 tbl_name =
'field_table' 665 tbl_name = trim(table_name)
668 if (.not. file_exist(trim(tbl_name)))
then 672 if (mpp_pe() == mpp_root_pe())
then 674 call mpp_error(note, trim(warn_header)// &
675 'No field table ('//trim(tbl_name)//
') available, so no fields are being registered.')
678 if(
present(nfields)) nfields = 0
683 call mpp_open(iunit,file=trim(tbl_name), form=mpp_ascii, action=mpp_rdonly)
685 call write_version_number(
"FIELD_MANAGER_MOD", version)
688 read(iunit,
'(a)',end=89,err=99) record
689 write( log_unit,
'(a)' )record
690 if (record(1:1) ==
"#" ) cycle
691 ltrec = len_trim(record)
692 if (ltrec .le. 0 ) cycle
697 if (record(l:l) ==
'"' )
then 708 if (icount > 6 )
then 709 call mpp_error(fatal,trim(error_header)//
'Too many fields in field table header entry.'//trim(record))
714 read(record,*,end=79,err=79) text_names
715 text_names%fld_type = lowercase(trim(text_names%fld_type))
716 text_names%mod_name = lowercase(trim(text_names%mod_name))
717 text_names%fld_name = lowercase(trim(text_names%fld_name))
720 read(record,*,end=79,err=79) text_names_short
721 text_names%fld_type = lowercase(trim(text_names_short%fld_type))
722 text_names%mod_name = lowercase(trim(text_names_short%mod_name))
723 text_names%fld_name = lowercase(trim(text_names_short%mod_name))
726 read(record,*,end=79,err=79) text_names_short
727 text_names%fld_type = lowercase(trim(text_names_short%fld_type))
728 text_names%mod_name = lowercase(trim(text_names_short%mod_name))
729 text_names%fld_name = lowercase(trim(text_names_short%mod_name))
733 text_names%fld_type =
" " 734 text_names%mod_name = lowercase(trim(record))
735 text_names%fld_name =
" " 742 list_name =
list_sep//trim(text_names%mod_name)//
list_sep//trim(text_names%fld_type)//&
744 if (mpp_pe() == mpp_root_pe() )
then 749 call mpp_error(note, trim(note_header)//
'Creating list name = '//trim(list_name))
753 index_list_name =
fm_new_list(list_name, create = .true.)
757 if ( index_list_name ==
no_field ) &
758 call mpp_error(fatal, trim(error_header)//
'Could not set field list for '//trim(list_name))
761 select case (text_names%mod_name)
778 call mpp_error(fatal, trim(error_header)//
'The model name is unrecognised : '//trim(text_names%mod_name))
795 if ( record(len_trim(record):len_trim(record)) ==
list_sep) cycle
799 do while (flag_method)
800 read(iunit,
'(a)',end=99,err=99) record
802 if (len_trim(record) .le. 0) cycle
804 if ( record(len_trim(record):len_trim(record)) ==
list_sep)
then 805 flag_method = .false.
806 if (len_trim(record) == 1) cycle
807 record = record(:len_trim(record)-1)
810 if (len_trim(record) .le. 0) cycle
812 if (record(1:1) ==
comment ) cycle
815 do l= 1, len_trim(record)
816 if (record(l:l) ==
dquote )
then 828 if (icount > 6 )
call mpp_error(fatal,trim(error_header)//
'Too many fields in field entry.'//trim(record))
831 call mpp_error(fatal, trim(error_header)//
'Could not change to '//trim(list_name)//
' list')
835 read(record,*,end=99,err=99) text_method
836 fields(
num_fields)%methods(m)%method_type = lowercase(trim(text_method%method_type))
837 fields(
num_fields)%methods(m)%method_name = lowercase(trim(text_method%method_name))
838 fields(
num_fields)%methods(m)%method_control = lowercase(trim(text_method%method_control))
840 type_str = text_method%method_type
841 name_str = text_method%method_name
842 control_str = text_method%method_control
846 read(record,*,end=99,err=99) text_method_short
848 & lowercase(trim(text_method_short%method_type))
849 #ifdef PRESERVE_UNIT_CASE 854 & trim(text_method_short%method_name)
857 & lowercase(trim(text_method_short%method_name))
861 & lowercase(trim(text_method_short%method_name))
865 type_str = text_method_short%method_type
867 control_str = text_method_short%method_name
871 read(record,*,end=99,err=99) text_method_very_short
872 fields(
num_fields)%methods(m)%method_type = lowercase(trim(text_method_very_short%method_type))
878 control_str = text_method_very_short%method_type
881 read(record,
'(A)',end=99,err=99) control_str
888 call mpp_error(fatal,trim(error_header)//
'Unterminated field in field entry.'//trim(record))
901 ltrec= len_trim(control_str)
902 control_array(:,1) = 1
903 control_array(:,2:3) = ltrec
906 if (control_str(l:l) ==
equal )
then 908 control_array(icount,2) = l
909 elseif (control_str(l:l) ==
comma )
then 910 if (icount .eq. 0)
then 914 call mpp_error(fatal,trim(error_header) // &
915 ' Bad format for field entry (comma without equals sign): ''' // &
916 trim(control_str) //
'''')
923 call mpp_error(fatal,trim(error_header) // &
924 ' Too many fields in field entry: ''' // &
925 trim(control_str) //
'''')
930 control_array(icount,3) = l-1
941 if (control_str(ltrec:ltrec) .ne.
comma)
then 942 control_array(
max(1,icount),3) = ltrec
946 if ( icount == 0 )
then 947 method_name = type_str
948 if (len_trim(method_name) > 0 )
then 949 method_name = trim(method_name)//
list_sep// trim(name_str)
951 method_name = trim(name_str)
953 val_name = control_str
955 call new_name(list_name, method_name, val_name )
960 startcont = control_array(l,1)
961 midcont = control_array(l,2)
962 endcont = control_array(l,3)
964 method_name = trim(type_str)
965 if (len_trim(method_name) > 0 )
then 966 method_name = trim(method_name)//
list_sep// trim(name_str)
968 method_name = trim(name_str)
971 if (len_trim(method_name) > 0 )
then 972 method_name = trim(method_name)//
list_sep//&
973 trim(control_str(startcont:midcont-1))
975 method_name = trim(control_str(startcont:midcont-1))
977 val_name = trim(control_str(midcont+1:endcont))
979 call new_name(list_name, method_name, val_name )
989 call mpp_error(fatal,trim(error_header)//
'Maximum number of methods for field exceeded')
997 if (mpp_pe() == 0)
then 999 call mpp_error(warning, trim(warn_header)// &
1000 'Field with identical name and model name duplicate found, skipping')
1003 flag_method = .true.
1004 do while (flag_method)
1005 read(iunit,
'(A)',end=99,err=99) record
1006 if ( record(len_trim(record):len_trim(record)) ==
list_sep)
then 1007 flag_method = .false.
1031 call mpp_error(fatal,trim(error_header)//
' Error reading field table. Record = '//trim(record))
1044 if (mpp_pe() .eq. mpp_root_pe())
then 1045 call mpp_error(warning,
'Error in field_manager_mod. Duplicate field name: Field type='//trim(
fields(i)%field_type)// &
1047 ', Duplicated name='//trim(
fields(i)%field_name))
1072 subroutine new_name ( list_name, method_name_in , val_name_in)
1079 character(len=*),
intent(in) :: list_name
1080 character(len=*),
intent(in) :: method_name_in
1085 character(len=*),
intent(inout) :: val_name_in
1090 character(len=8),
parameter :: sub_name =
'new_name' 1091 character(len=64),
parameter :: error_header =
'==>Error from ' // trim(
module_name) // &
1092 '(' // trim(sub_name) //
'): ' 1093 character(len=64),
parameter :: warn_header =
'==>Warning from ' // trim(
module_name) // &
1094 '(' // trim(sub_name) //
'): ' 1095 character(len=64),
parameter :: note_header =
'==>Note from ' // trim(
module_name) // &
1096 '(' // trim(sub_name) //
'): ' 1101 character(len=fm_string_len) :: method_name
1102 character(len=fm_string_len) :: val_list
1103 character(len=fm_string_len) :: val_name
1104 integer,
dimension(MAX_FIELDS) :: end_val
1105 integer,
dimension(MAX_FIELDS) :: start_val
1114 logical :: append_new
1115 logical :: val_logic
1120 method_name = trim(method_name_in)
1125 append_new = .false.
1127 end_val(:) = len_trim(val_name_in)
1132 do i = 1, len_trim(val_name_in)
1133 if ( val_name_in(i:i) ==
comma )
then 1134 end_val(num_elem) = i-1
1135 start_val(num_elem+1) = i+1
1136 num_elem = num_elem + 1
1141 left_br = scan(method_name,
'[')
1142 right_br = scan(method_name,
']')
1143 if ( num_elem .eq. 1 )
then 1147 if ( left_br > 0 .and. right_br == 0 ) &
1148 call mpp_error(fatal, trim(error_header)//
"Left bracket present without right bracket in "//trim(method_name))
1152 if ( left_br== 0 .and. right_br > 0 ) &
1153 call mpp_error(fatal, trim(error_header)//
"Right bracket present without left bracket in "//trim(method_name))
1156 if ( left_br > 0 .and. right_br > 0 )
then 1160 if ( scan( method_name(left_br+1:right_br -1),
set ) > 0 ) &
1161 call mpp_error(fatal, trim(error_header)//
"Using a non-numeric value for index in "//trim(method_name))
1162 read(method_name(left_br+1:right_br -1), *) index_t
1163 method_name = method_name(:left_br -1)
1170 if ( left_br > 0 .or. right_br > 0 ) &
1172 trim(error_header)//
"Using a comma delimited list with an indexed array element in "//trim(method_name))
1178 if ( i .gt. 1 .or. index_t .eq. 0 )
then 1183 val_name = val_name_in(start_val(i):end_val(i))
1192 length = len_trim(val_name)
1193 if (val_name(1:1) .eq.
squote)
then 1195 if (val_name(length:length) .eq.
squote)
then 1196 val_name = val_name(2:length-1)
1198 elseif (val_name(length:length) .eq.
dquote)
then 1199 call mpp_error(fatal, trim(error_header) //
' Quotes do not match in ' // trim(val_name) // &
1200 ' for ' // trim(method_name) //
' of ' // trim(list_name))
1202 call mpp_error(fatal, trim(error_header) //
' No trailing quote in ' // trim(val_name) // &
1203 ' for ' // trim(method_name) //
' of ' // trim(list_name))
1206 elseif (val_name(1:1) .eq.
dquote .or. val_name(length:length) .eq.
dquote)
then 1208 call mpp_error(fatal, trim(error_header) //
' Double quotes not allowed in ' // trim(val_name) // &
1209 ' for ' // trim(method_name) //
' of ' // trim(list_name))
1211 elseif (val_name(length:length) .eq.
squote)
then 1213 call mpp_error(fatal, trim(error_header) //
' No leading quote in ' // trim(val_name) // &
1214 ' for ' // trim(method_name) //
' of ' // trim(list_name))
1222 if ( scan(val_name(1:1),
setnum ) > 0 )
then 1231 call mpp_error(warning, trim(warn_header)// &
1232 'First character of value is numerical but the value does not appear to be numerical.')
1234 trim(method_name)//
' Value = '// trim(val_name))
1239 if ( scan(val_name,
'.') > 0 .or. scan(val_name,
'e') > 0 .or. scan(val_name,
'E') > 0)
then 1240 read(val_name, *) val_real
1243 read(val_name, *) val_int
1251 if ( len_trim(val_name) == 1 .or. len_trim(val_name) == 3)
then 1252 if ( val_name ==
't' .or. val_name ==
'T' .or. val_name ==
'.t.' .or. val_name ==
'.T.' )
then 1256 if ( val_name ==
'f' .or. val_name ==
'F' .or. val_name ==
'.f.' .or. val_name ==
'.F.' )
then 1261 if ( trim(lowercase(val_name)) ==
'true' .or. trim(lowercase(val_name)) ==
'.true.' )
then 1265 if ( trim(lowercase(val_name)) ==
'false' .or. trim(lowercase(val_name)) ==
'.false.' )
then 1271 select case(val_type)
1274 if (
fm_new_value( method_name, val_int, create = .true., index = index_t, append = append_new ) < 0 ) &
1275 call mpp_error(fatal, trim(error_header)//
'Could not set "' // trim(val_name) //
'" for '//trim(method_name)//&
1276 ' (I) for '//trim(list_name))
1279 if (
fm_new_value( method_name, val_logic, create = .true., index = index_t, append = append_new) < 0 ) &
1280 call mpp_error(fatal, trim(error_header)//
'Could not set "' // trim(val_name) //
'" for '//trim(method_name)//&
1281 ' (L) for '//trim(list_name))
1284 if (
fm_new_value( method_name, val_real, create = .true., index = index_t, append = append_new) < 0 ) &
1285 call mpp_error(fatal, trim(error_header)//
'Could not set "' // trim(val_name) //
'" for '//trim(method_name)//&
1286 ' (R) for '//trim(list_name))
1289 if (
fm_new_value( method_name, val_name, create = .true., index = index_t, append = append_new) < 0 ) &
1290 call mpp_error(fatal, trim(error_header)//
'Could not set "' // trim(val_name) //
'" for '//trim(method_name)//&
1291 ' (S) for '//trim(list_name))
1293 call mpp_error(fatal, trim(error_header)//
'Could not find a valid type to set the '//trim(method_name)//&
1294 ' for '//trim(list_name))
1298 if (mpp_pe() == mpp_root_pe() )
then 1301 write (out_unit,*) trim(note_header),
'Creating new value = ', trim(method_name),
' ', trim(val_name)
1329 character(len=17),
parameter :: sub_name =
'field_manager_end' 1330 character(len=64),
parameter :: note_header =
'==>Note from ' // trim(
module_name) // &
1331 '(' // trim(sub_name) //
'): ' 1335 call write_version_number(
"FIELD_MANAGER_MOD", version)
1336 if ( mpp_pe() == mpp_root_pe() )
then 1338 write (unit,
'(/,(a))') trim(note_header),
'Exiting field_manager, have a nice day ...' 1340 write (unit,
'(/,(a))') trim(note_header),
'Exiting field_manager, have a nice day ...' 1363 character(len=*),
intent(inout) :: name
1372 do i = 1,len_trim(name)
1373 if ( .not. (name(i:i) .eq.
space .or. &
1374 name(i:i) .eq.
tab))
then 1413 integer,
intent(in) :: model
1414 character(len=*),
intent(in) :: field_name
1424 if (
fields(i)%model == model .and.
fields(i)%field_name == lowercase(field_name))
then 1442 character(len=*),
intent(in) :: field_name
1476 integer,
intent(in) :: n
1493 character (len=*),
intent(out) :: fld_type, fld_name
1494 integer,
intent(out) :: model, num_methods
1499 character(len=14),
parameter :: sub_name =
'get_field_info' 1500 character(len=64),
parameter :: error_header =
'==>Error from ' // trim(
module_name) // &
1501 '(' // trim(sub_name) //
'): ' 1507 if (n < 1 .or. n >
num_fields)
call mpp_error(fatal,trim(error_header)//
'Invalid field index')
1509 fld_type =
fields(n)%field_type
1510 fld_name =
fields(n)%field_name
1512 num_methods =
fields(n)%num_methods
1542 integer,
intent(in) :: n
1543 integer,
intent(in) :: m
1549 character(len=16),
parameter :: sub_name =
'get_field_method' 1550 character(len=64),
parameter :: error_header =
'==>Error from ' // trim(
module_name) // &
1551 '(' // trim(sub_name) //
'): ' 1557 if (n < 1 .or. n >
num_fields)
call mpp_error(fatal,trim(error_header)//
'Invalid field index')
1563 if (m < 1 .or. m >
fields(n)%num_methods)
call mpp_error(fatal,trim(error_header)//
'Invalid method index')
1565 method =
fields(n)%methods(m)
1592 integer,
intent(in) :: n
1599 character(len=17),
parameter :: sub_name =
'get_field_methods' 1600 character(len=64),
parameter :: error_header =
'==>Error from ' // trim(
module_name) // &
1601 '(' // trim(sub_name) //
'): ' 1606 character(len=fm_path_name_len),
dimension(size(methods(:))) :: control
1607 character(len=fm_path_name_len),
dimension(size(methods(:))) :: method
1608 logical :: found_methods
1614 call mpp_error(fatal,trim(error_header)//
'Invalid field index')
1619 if (
size(methods(:)) <
fields(n)%num_methods) &
1620 call mpp_error(fatal,trim(error_header)//
'Method array too small')
1649 function parse_reals ( text, label, values )
result (parse)
1665 character(len=*),
intent(in) :: text, label
1666 real,
intent(out) :: values(:)
1676 character(len=*),
intent(in) :: text, label
1677 integer,
intent(out) :: values(:)
1685 function parse_strings ( text, label, values )
result (parse)
1686 character(len=*),
intent(in) :: text, label
1687 character(len=*),
intent(out) :: values(:)
1697 function parse_real ( text, label, value )
result (parse)
1698 character(len=*),
intent(in) :: text, label
1699 real,
intent(out) :: value
1705 if (
parse > 0)
value = values(1)
1711 function parse_integer ( text, label, value )
result (parse)
1712 character(len=*),
intent(in) :: text, label
1713 integer,
intent(out) :: value
1716 integer :: values(1)
1719 if (
parse > 0)
value = values(1)
1725 function parse_string ( text, label, value )
result (parse)
1726 character(len=*),
intent(in) :: text, label
1727 character(len=*),
intent(out) :: value
1730 character(len=len(value)) :: values(1)
1733 if (
parse > 0)
value = values(1)
1775 character(len=*),
intent(in) :: name
1780 character(len=12),
parameter :: sub_name =
'create_field' 1781 character(len=64),
parameter :: error_header =
'==>Error from ' // trim(
module_name) // &
1782 '(' // trim(sub_name) //
'): ' 1783 character(len=64),
parameter :: warn_header =
'==>Warning from ' // trim(
module_name) // &
1784 '(' // trim(sub_name) //
'): ' 1789 integer :: error, out_unit
1794 if (.not.
associated(parent_p))
then 1797 write (out_unit,*) trim(warn_header),
'Unnassociated pointer' &
1798 ,
' for ', trim(name)
1804 if (name .eq.
' ')
then 1806 write (out_unit,*) trim(warn_header),
'Empty name for ' &
1815 allocate(list_p, stat = error)
1816 if (error .ne. 0)
then 1817 write (out_unit,*) trim(error_header),
'Error ', error, &
1818 ' allocating memory for list ', trim(name)
1827 nullify(list_p%next)
1828 list_p%prev => parent_p%last_field
1829 nullify(list_p%first_field)
1830 nullify(list_p%last_field)
1833 list_p%max_index = 0
1834 list_p%array_dim = 0
1835 if (
associated(list_p%i_value))
deallocate(list_p%i_value)
1836 if (
associated(list_p%l_value))
deallocate(list_p%l_value)
1837 if (
associated(list_p%r_value))
deallocate(list_p%r_value)
1838 if (
associated(list_p%s_value))
deallocate(list_p%s_value)
1843 if (parent_p%length .le. 0)
then 1844 parent_p%first_field => list_p
1846 parent_p%last_field%next => list_p
1851 parent_p%last_field => list_p
1855 parent_p%length = parent_p%length + 1
1859 list_p%index = parent_p%length
1863 list_p%parent => parent_p
1886 logical recursive function dump_list(list_p, recursive, depth, out_unit)
result(success)
1904 logical,
intent(in) :: recursive
1905 integer,
intent(in) :: depth
1906 integer,
intent(in) :: out_unit
1909 character(len=64),
parameter :: warn_header =
'==>Warning from ' // trim(
module_name) //
'(dump_list): ' 1913 character(len=fm_field_name_len) :: num, scratch
1914 type(
field_def),
pointer :: this_field_p
1915 character(len=depth+fm_field_name_len) :: blank
1921 if (.not.
associated(list_p))
then 1924 elseif (list_p%field_type .ne.
list_type)
then 1925 if (
verb >
verb_level_warn)
write (out_unit,*) trim(warn_header), trim(list_p%name),
' is not a list' 1933 write (out_unit,
'(a,a,a)') blank(1:depth), trim(list_p%name),
list_sep 1940 this_field_p => list_p%first_field
1942 do while (
associated(this_field_p))
1944 select case(this_field_p%field_type)
1949 success =
dump_list(this_field_p, .true., depthp1, out_unit)
1950 if (.not.success)
exit 1952 write (out_unit,
'(a,a,a)') blank(1:depthp1), trim(this_field_p%name),
list_sep 1956 if (this_field_p%max_index .eq. 0)
then 1957 write (out_unit,
'(a,a,a)') blank(1:depthp1), trim(this_field_p%name),
' = NULL' 1958 elseif (this_field_p%max_index .eq. 1)
then 1959 write (scratch,*) this_field_p%i_value(1)
1960 write (out_unit,
'(a,a,a,a)') blank(1:depthp1), trim(this_field_p%name),
' = ', &
1961 trim(adjustl(scratch))
1963 do j = 1, this_field_p%max_index
1964 write (scratch,*) this_field_p%i_value(j)
1966 write (out_unit,
'(a,a,a,a,a,a)') blank(1:depthp1), trim(this_field_p%name), &
1967 '[', trim(adjustl(num)),
'] = ', trim(adjustl(scratch))
1972 if (this_field_p%max_index .eq. 0)
then 1973 write (out_unit,
'(a,a,a)') blank(1:depthp1), trim(this_field_p%name),
' = NULL' 1974 elseif (this_field_p%max_index .eq. 1)
then 1975 write (scratch,
'(l1)') this_field_p%l_value(1)
1976 write (out_unit,
'(a,a,a,a)') blank(1:depthp1), trim(this_field_p%name),
' = ', &
1977 trim(adjustl(scratch))
1979 do j = 1, this_field_p%max_index
1980 write (scratch,
'(l1)') this_field_p%l_value(j)
1982 write (out_unit,
'(a,a,a,a,a,a)') blank(1:depthp1), trim(this_field_p%name), &
1983 '[', trim(adjustl(num)),
'] = ', trim(adjustl(scratch))
1988 if (this_field_p%max_index .eq. 0)
then 1989 write (out_unit,
'(a,a,a)') blank(1:depthp1), trim(this_field_p%name),
' = NULL' 1990 elseif (this_field_p%max_index .eq. 1)
then 1991 write (scratch,*) this_field_p%r_value(1)
1992 write (out_unit,
'(a,a,a,a)') blank(1:depthp1), trim(this_field_p%name),
' = ', &
1993 trim(adjustl(scratch))
1995 do j = 1, this_field_p%max_index
1996 write (scratch,*) this_field_p%r_value(j)
1998 write (out_unit,
'(a,a,a,a,a,a)') blank(1:depthp1), trim(this_field_p%name), &
1999 '[', trim(adjustl(num)),
'] = ', trim(adjustl(scratch))
2004 if (this_field_p%max_index .eq. 0)
then 2005 write (out_unit,
'(a,a,a)') blank(1:depthp1), trim(this_field_p%name),
' = NULL' 2006 elseif (this_field_p%max_index .eq. 1)
then 2007 write (out_unit,
'(a,a,a,a)') blank(1:depthp1), trim(this_field_p%name),
' = ', &
2008 ''''//trim(this_field_p%s_value(1))//
'''' 2010 do j = 1, this_field_p%max_index
2012 write (out_unit,
'(a,a,a,a,a,a)') blank(1:depthp1), trim(this_field_p%name), &
2013 '[', trim(adjustl(num)),
'] = ',
''''//trim(this_field_p%s_value(j))//
'''' 2019 write (out_unit,*) trim(warn_header),
'Undefined type for ', trim(this_field_p%name)
2026 this_field_p => this_field_p%next
2064 character(len=*),
intent(in) :: name
2065 character(len=*),
intent(out) :: path
2066 character(len=*),
intent(out) :: base
2079 length =
max(len_trim(name),0)
2081 if (length .eq. 0)
then 2092 do while (name(length:length) .eq.
list_sep)
2094 if (length .eq. 0)
then 2098 if (length .eq. 0)
then 2109 i = index(name(1:length),
list_sep, back = .true.)
2116 base = name(1:length)
2123 base = name(i+1:length)
2168 character(len=*),
intent(in) :: name
2174 type(
field_def),
pointer,
save :: temp_p
2179 if (name .eq.
'.')
then 2184 field_p => this_list_p
2185 elseif (name .eq.
'..')
then 2189 field_p => this_list_p%parent
2194 temp_p => this_list_p%first_field
2196 do while (
associated(temp_p))
2201 if (temp_p%name .eq. name)
then 2206 temp_p => temp_p%next
2248 character(len=*),
intent(in) :: name
2249 character(len=*),
intent(out) :: head
2250 character(len=*),
intent(out) :: rest
2264 do while (i .le. len(name))
2265 if (name(i+1:i+1) .eq.
list_sep)
then 2279 elseif (i .eq. len(name))
then 2318 function find_list(path, relative_p, create) &
2340 character(len=*),
intent(in) :: path
2342 logical,
intent(in) :: create
2347 character(len=9),
parameter :: sub_name =
'find_list' 2348 character(len=64),
parameter :: warn_header =
'==>Warning from ' // trim(
module_name) // &
2349 '(' // trim(sub_name) //
'): ' 2350 character(len=64),
parameter :: note_header =
'==>Note from ' // trim(
module_name) // &
2351 '(' // trim(sub_name) //
'): ' 2355 character(len=fm_path_name_len) :: working_path
2356 character(len=fm_path_name_len) :: rest
2357 character(len=fm_field_name_len) :: this_list
2358 integer :: i, out_unit
2359 type(
field_def),
pointer,
save :: working_path_p
2360 type(
field_def),
pointer,
save :: this_list_p
2368 if (path .eq.
' ')
then 2370 list_p => relative_p
2380 working_path = path(2:)
2382 working_path_p => relative_p
2388 do while (working_path .ne.
' ')
2392 call find_head(working_path, this_list, rest)
2397 if (this_list .eq.
' ')
then 2404 i = len_trim(this_list)
2405 do while (i .gt. 0 .and. this_list(i:i) .eq.
list_sep)
2406 this_list(i:i) =
' ' 2412 this_list_p =>
find_field(this_list, working_path_p)
2414 if (.not.
associated(this_list_p))
then 2419 this_list_p =>
make_list(working_path_p, this_list)
2420 if (.not.
associated(this_list_p))
then 2422 write (out_unit,*) trim(warn_header),
'List "', &
2423 trim(this_list),
'" could not be created in ', &
2435 write (out_unit,*) trim(note_header),
'List "', &
2436 trim(this_list),
'" does not exist in ', trim(path)
2446 if (this_list_p%field_type .eq.
list_type)
then 2447 working_path_p => this_list_p
2451 write (out_unit,*) trim(warn_header),
'"', &
2452 trim(this_list),
'" is not a list in ', trim(path)
2458 list_p => working_path_p
2500 character(len=*),
intent(in) :: name
2505 type(
field_def),
pointer,
save :: temp_p
2517 if (
associated(temp_p))
then 2566 character(len=*),
intent(in) :: name
2571 character(len=14),
parameter :: sub_name =
'fm_change_root' 2572 character(len=64),
parameter :: warn_header =
'==>Warning from ' // trim(
module_name) // &
2573 '(' // trim(sub_name) //
'): ' 2577 type(
field_def),
pointer,
save :: temp_list_p
2589 if (name .eq.
' ')
then 2591 write (out_unit,*) trim(warn_header),
'Must supply a field name' 2601 if (
associated(temp_list_p))
then 2635 write (out_unit,*) trim(warn_header), &
2636 'Could not find list ', trim(name)
2661 logical function fm_dump_list(name, recursive, unit)
result (success)
2662 character(len=*),
intent(in) :: name
2663 logical,
intent(in),
optional :: recursive
2664 integer,
intent(in),
optional :: unit
2678 character(len=12),
parameter :: sub_name =
'fm_dump_list' 2679 character(len=64),
parameter :: warn_header =
'==>Warning from ' // trim(
module_name) // &
2680 '(' // trim(sub_name) //
'): ' 2682 logical :: recursive_t
2683 type(
field_def),
pointer,
save :: temp_list_p
2686 if (
present(unit))
then 2692 recursive_t = .false.
2693 if (
present(
recursive)) recursive_t =
recursive 2696 if (name .eq.
' ')
then 2703 if (
associated(temp_list_p))
then 2708 write (out_unit,*) trim(warn_header),
'Could not follow path for ', trim(name)
2715 success =
dump_list(temp_list_p, recursive_t, 0, out_unit)
2753 character(len=*),
intent(in) :: name
2758 type(
field_def),
pointer,
save :: dummy_p
2769 success =
associated(dummy_p)
2808 character(len=*),
intent(in) :: name
2813 character(len=12),
parameter :: sub_name =
'fm_get_index' 2814 character(len=64),
parameter :: warn_header =
'==>Warning from ' // trim(
module_name) // &
2815 '(' // trim(sub_name) //
'): ' 2819 type(
field_def),
pointer,
save :: temp_field_p
2832 if (name .eq.
' ')
then 2834 write (out_unit,*) trim(warn_header),
'Must supply a field name' 2843 if (
associated(temp_field_p))
then 2847 index = temp_field_p%index
2853 write (out_unit,*) trim(warn_header),
'Could not follow path for ', trim(name)
2886 character(len=fm_path_name_len) :: path
2894 type(
field_def),
pointer,
save :: temp_list_p
2908 do while (
associated(temp_list_p))
2913 if (temp_list_p%name .eq.
' ')
then 2919 path =
list_sep // trim(temp_list_p%name) // path
2923 temp_list_p => temp_list_p%parent
2926 if (.not.
associated(temp_list_p))
then 2932 elseif (path .eq.
' ')
then 2976 character(len=*),
intent(in) :: name
2981 character(len=13),
parameter :: sub_name =
'fm_get_length' 2982 character(len=64),
parameter :: warn_header =
'==>Warning from ' // trim(
module_name) // &
2983 '(' // trim(sub_name) //
'): ' 2987 type(
field_def),
pointer,
save :: temp_field_p
3000 if (name .eq.
' ')
then 3002 write (out_unit,*) trim(warn_header),
'Must supply a field name' 3012 if (
associated(temp_field_p))
then 3016 if (temp_field_p%field_type .eq.
list_type)
then 3017 length = temp_field_p%length
3019 length = temp_field_p%max_index
3027 write (out_unit,*) trim(warn_header), &
3028 'Could not follow path for ', trim(name)
3055 result(name_field_type)
3065 character(len=8) :: name_field_type
3069 character(len=*),
intent(in) :: name
3074 character(len=11),
parameter :: sub_name =
'fm_get_type' 3075 character(len=64),
parameter :: warn_header =
'==>Warning from ' // trim(
module_name) // &
3076 '(' // trim(sub_name) //
'): ' 3080 type(
field_def),
pointer,
save :: temp_field_p
3093 if (name .eq.
' ')
then 3095 write (out_unit,*) trim(warn_header),
'Must supply a field name' 3097 name_field_type =
' ' 3105 if (
associated(temp_field_p))
then 3116 write (out_unit,*) trim(warn_header), &
3117 'Could not follow path for ', trim(name)
3119 name_field_type =
' ' 3165 character(len=*),
intent(in) :: name
3166 integer,
intent(out) :: value
3167 integer,
intent(in),
optional :: index
3172 character(len=20),
parameter :: sub_name =
'fm_get_value_integer' 3173 character(len=64),
parameter :: warn_header =
'==>Warning from ' // trim(
module_name) // &
3174 '(' // trim(sub_name) //
'): ' 3179 type(
field_def),
pointer,
save :: temp_field_p
3192 if (name .eq.
' ')
then 3194 write (out_unit,*) trim(warn_header),
'Must supply a field name' 3203 if (
present(index))
then 3213 if (
associated(temp_field_p))
then 3218 if (index_t .lt. 1)
then 3224 write (out_unit,*) trim(warn_header), &
3225 'Optional index for ', trim(name), &
3226 ' not positive: ', index_t
3230 elseif (index_t .gt. temp_field_p%max_index)
then 3236 write (out_unit,*) trim(warn_header), &
3237 'Optional index for ', trim(name), &
3238 ' too large: ', index_t,
' > ', temp_field_p%max_index
3246 value = temp_field_p%i_value(index_t)
3255 write (out_unit,*) trim(warn_header), &
3256 'Field not type integer ', trim(name)
3267 write (out_unit,*) trim(warn_header), &
3268 'Could not follow path for ', trim(name)
3288 character(len=*),
intent(in) :: name
3289 logical,
intent(out) :: value
3290 integer,
intent(in),
optional :: index
3295 character(len=20),
parameter :: sub_name =
'fm_get_value_logical' 3296 character(len=64),
parameter :: warn_header =
'==>Warning from ' // trim(
module_name) // &
3297 '(' // trim(sub_name) //
'): ' 3302 type(
field_def),
pointer,
save :: temp_field_p
3315 if (name .eq.
' ')
then 3317 write (out_unit,*) trim(warn_header),
'Must supply a field name' 3326 if (
present(index))
then 3336 if (
associated(temp_field_p))
then 3342 if (index_t .lt. 1)
then 3348 write (out_unit,*) trim(warn_header), &
3349 'Optional index for ', trim(name), &
3350 ' not positive: ', index_t
3355 elseif (index_t .gt. temp_field_p%max_index)
then 3361 write (out_unit,*) trim(warn_header), &
3362 'Optional index for ', trim(name), &
3363 ' too large: ', index_t,
' > ', temp_field_p%max_index
3372 value = temp_field_p%l_value(index_t)
3381 write (out_unit,*) trim(warn_header), &
3382 'Field not type logical ', trim(name)
3393 write (out_unit,*) trim(warn_header), &
3394 'Could not follow path for ', trim(name)
3414 character(len=*),
intent(in) :: name
3415 real,
intent(out) :: value
3416 integer,
intent(in),
optional :: index
3421 character(len=17),
parameter :: sub_name =
'fm_get_value_real' 3422 character(len=64),
parameter :: warn_header =
'==>Warning from ' // trim(
module_name) // &
3423 '(' // trim(sub_name) //
'): ' 3428 type(
field_def),
pointer,
save :: temp_field_p
3441 if (name .eq.
' ')
then 3443 write (out_unit,*) trim(warn_header),
'Must supply a field name' 3452 if (
present(index))
then 3462 if (
associated(temp_field_p))
then 3466 if (temp_field_p%field_type .eq.
real_type)
then 3468 if (index_t .lt. 1)
then 3475 write (out_unit,*) trim(warn_header), &
3476 'Optional index for ', trim(name), &
3477 ' not positive: ', index_t
3482 elseif (index_t .gt. temp_field_p%max_index)
then 3489 write (out_unit,*) trim(warn_header), &
3490 'Optional index for ', trim(name), &
3491 ' too large: ', index_t,
' > ', temp_field_p%max_index
3501 value = temp_field_p%r_value(index_t)
3510 write (out_unit,*) trim(warn_header), &
3511 'Field not type real ', trim(name)
3522 write (out_unit,*) trim(warn_header), &
3523 'Could not follow path for ', trim(name)
3543 character(len=*),
intent(in) :: name
3544 character(len=*),
intent(out) :: value
3545 integer,
intent(in),
optional :: index
3550 character(len=19),
parameter :: sub_name =
'fm_get_value_string' 3551 character(len=64),
parameter :: warn_header =
'==>Warning from ' // trim(
module_name) // &
3552 '(' // trim(sub_name) //
'): ' 3557 type(
field_def),
pointer,
save :: temp_field_p
3570 if (name .eq.
' ')
then 3572 write (out_unit,*) trim(warn_header),
'Must supply a field name' 3581 if (
present(index))
then 3591 if (
associated(temp_field_p))
then 3595 if (temp_field_p%field_type .eq.
string_type)
then 3596 if (index_t .lt. 1)
then 3602 write (out_unit,*) trim(warn_header), &
3603 'Optional index for ', trim(name), &
3604 ' not positive: ', index_t
3609 elseif (index_t .gt. temp_field_p%max_index)
then 3615 write (out_unit,*) trim(warn_header), &
3616 'Optional index for ', trim(name), &
3617 ' too large: ', index_t,
' > ', temp_field_p%max_index
3625 value = temp_field_p%s_value(index_t)
3638 write (out_unit,*) trim(warn_header), &
3639 'Field not type string ', trim(name)
3650 write (out_unit,*) trim(warn_header), &
3651 'Could not follow path for ', trim(name)
3698 integer,
intent(in) :: dim
3699 character(len=*),
intent(in) :: lists(dim)
3704 character(len=15),
parameter :: sub_name =
'fm_intersection' 3705 character(len=64),
parameter :: error_header =
'==>Error from ' // trim(
module_name) // &
3706 '(' // trim(sub_name) //
'): ' 3707 character(len=64),
parameter :: warn_header =
'==>Warning from ' // trim(
module_name) // &
3708 '(' // trim(sub_name) //
'): ' 3712 character (len=fm_field_name_len) :: name
3713 character (len=fm_field_name_len), &
3714 dimension(:),
allocatable :: names
3715 character (len=fm_type_name_len) :: field_type
3722 type(
field_def),
pointer,
save :: temp_p
3737 if (dim .le. 0)
then 3739 write (out_unit,*) trim(warn_header),
'Non-positive dimension: ', dim
3752 if (
associated(temp_p))
then 3753 if (count .eq. -1)
then 3754 count = temp_p%length
3757 if (count .gt. temp_p%length)
then 3758 count = temp_p%length
3764 write (out_unit,*) trim(warn_header), &
3765 'List does not exist: "', trim(lists(n)),
'"' 3774 allocate( return_p, stat = error)
3775 if (error .ne. 0)
then 3776 write (out_unit,*) trim(error_header),
'Error ', error &
3777 ,
' allocating memory for return_p ' 3781 if (
associated(return_p%names))
deallocate(return_p%names)
3785 if (count .eq. 0)
then 3792 if (dim .eq. 1)
then 3796 allocate( return_p%names(count), stat = error)
3797 if (error .ne. 0)
then 3798 write (out_unit,*) trim(error_header),
'Error ', error &
3799 ,
' allocating memory for names in return_p ' 3806 return_p%names(count) = name
3813 allocate( names(count), stat = error)
3814 if (error .ne. 0)
then 3815 write (out_unit,*) trim(error_header),
'Error ', error &
3816 ,
' allocating memory for names ' 3828 if (n .ne. shortest)
then 3831 if (.not.
associated(temp_p))
then 3845 allocate( return_p%names(count), stat = error)
3846 if (error .ne. 0)
then 3847 write (out_unit,*) trim(error_header),
'Error ', error &
3848 ,
' allocating memory for names in return_p ' 3857 return_p%names(n) = names(n)
3859 return_p%length = count
3906 character(len=*),
intent(in) :: list
3907 character(len=*),
intent(out) :: name
3908 character(len=fm_type_name_len),
intent(out) :: field_type
3909 integer,
intent(out) :: index
3914 character(len=17),
parameter :: sub_name =
'fm_loop_over_list' 3915 character(len=64),
parameter :: warn_header =
'==>Warning from ' // trim(
module_name) // &
3916 '(' // trim(sub_name) //
'): ' 3920 type(
field_def),
pointer,
save :: temp_list_p
3937 elseif (list .eq.
' ')
then 3959 write (out_unit,*) trim(warn_header), &
3960 'Could not follow path for ', trim(list)
4020 if (
associated(iter%ptr)) iter%ptr => iter%ptr%first_field
4029 result(success) ;
logical success
4031 character(len=*),
intent(out) :: name
4032 character(len=*),
intent(out) :: field_type
4033 integer ,
intent(out) :: index
4036 if (
associated(iter%ptr))
then 4037 name = iter%ptr%name
4039 index = iter%ptr%index
4041 iter%ptr => iter%ptr%next
4087 character(len=*),
intent(in) :: name
4088 logical,
intent(in),
optional :: create
4089 logical,
intent(in),
optional :: keep
4094 character(len=11),
parameter :: sub_name =
'fm_new_list' 4095 character(len=64),
parameter :: warn_header =
'==>Warning from ' // trim(
module_name) // &
4096 '(' // trim(sub_name) //
'): ' 4102 character(len=fm_path_name_len) :: path
4103 character(len=fm_field_name_len) :: base
4104 type(
field_def),
pointer,
save :: temp_list_p
4117 if (name .eq.
' ')
then 4119 write (out_unit,*) trim(warn_header),
'Must supply a list name' 4127 if (
present(create))
then 4133 if (
present(keep))
then 4145 if (
associated(temp_list_p))
then 4149 temp_list_p =>
make_list(temp_list_p, base)
4150 if (
associated(temp_list_p))
then 4157 index = temp_list_p%index
4164 write (out_unit,*) trim(warn_header), &
4165 'Could not create list ', trim(name)
4176 write (out_unit,*) trim(warn_header), &
4177 'Could not follow path for ', trim(name)
4233 integer :: field_index
4237 character(len=*),
intent(in) :: name
4238 integer,
intent(in) :: value
4239 logical,
intent(in),
optional :: create
4240 integer,
intent(in),
optional :: index
4241 logical,
intent(in),
optional :: append
4246 character(len=20),
parameter :: sub_name =
'fm_new_value_integer' 4247 character(len=64),
parameter :: warn_header =
'==>Warning from ' // trim(
module_name) // &
4248 '(' // trim(sub_name) //
'): ' 4255 integer,
pointer,
dimension(:) :: temp_i_value
4256 character(len=fm_path_name_len) :: path
4257 character(len=fm_field_name_len) :: base
4258 type(
field_def),
pointer,
save :: temp_list_p
4259 type(
field_def),
pointer,
save :: temp_field_p
4272 if (name .eq.
' ')
then 4274 write (out_unit,*) trim(warn_header),
'Must supply a field name' 4282 if (
present(create))
then 4291 if (
present(index) .and.
present(append))
then 4292 if (append .and. index .gt. 0)
then 4294 write (out_unit,*) trim(warn_header), &
4295 'Index and Append both set for ', trim(name)
4304 if (
present(index))
then 4306 if (index_t .lt. 0)
then 4312 write (out_unit,*) trim(warn_header), &
4313 'Optional index for ', trim(name), &
4314 ' negative: ', index_t
4328 if (
associated(temp_list_p))
then 4329 temp_field_p =>
find_field(base, temp_list_p)
4330 if (.not.
associated(temp_field_p))
then 4336 if (
associated(temp_field_p))
then 4341 if (temp_field_p%field_type ==
real_type )
then 4345 else if (temp_field_p%field_type /=
integer_type )
then 4348 temp_field_p%max_index = 0
4349 if (temp_field_p%field_type /=
null_type )
then 4351 write (out_unit,*) trim(warn_header), &
4352 'Changing type of ', trim(name),
' from ', &
4366 if (
present(append))
then 4368 index_t = temp_field_p%max_index + 1
4372 if (index_t .gt. temp_field_p%max_index + 1)
then 4379 write (out_unit,*) trim(warn_header), &
4380 'Index too large for ', trim(name),
': ', index_t
4385 elseif (index_t .eq. 0 .and. &
4386 temp_field_p%max_index .gt. 0)
then 4392 write (out_unit,*) trim(warn_header), &
4393 'Trying to nullify a non-null field: ', &
4399 elseif (.not.
associated(temp_field_p%i_value) .and. &
4400 index_t .gt. 0)
then 4404 allocate(temp_field_p%i_value(1))
4405 temp_field_p%max_index = 1
4406 temp_field_p%array_dim = 1
4407 elseif (index_t .gt. temp_field_p%array_dim)
then 4413 allocate (temp_i_value(temp_field_p%array_dim))
4414 do i = 1, temp_field_p%max_index
4415 temp_i_value(i) = temp_field_p%i_value(i)
4417 if (
associated (temp_field_p%i_value))
deallocate(temp_field_p%i_value)
4418 temp_field_p%i_value => temp_i_value
4419 temp_field_p%max_index = index_t
4425 if (index_t .gt. 0)
then 4426 temp_field_p%i_value(index_t) =
value 4427 if (index_t .gt. temp_field_p%max_index)
then 4428 temp_field_p%max_index = index_t
4431 field_index = temp_field_p%index
4439 write (out_unit,*) trim(warn_header), &
4440 'Could not create integer value field ', &
4451 write (out_unit,*) trim(warn_header), &
4452 'Could not follow path for ', &
4468 integer :: field_index
4472 character(len=*),
intent(in) :: name
4473 logical,
intent(in) :: value
4474 logical,
intent(in),
optional :: create
4475 integer,
intent(in),
optional :: index
4476 logical,
intent(in),
optional :: append
4481 character(len=20),
parameter :: sub_name =
'fm_new_value_logical' 4482 character(len=64),
parameter :: warn_header =
'==>Warning from ' // trim(
module_name) // &
4483 '(' // trim(sub_name) //
'): ' 4487 character(len=fm_path_name_len) :: path
4488 character(len=fm_field_name_len) :: base
4492 logical,
dimension(:),
pointer :: temp_l_value
4493 type(
field_def),
pointer,
save :: temp_list_p
4494 type(
field_def),
pointer,
save :: temp_field_p
4507 if (name .eq.
' ')
then 4509 write (out_unit,*) trim(warn_header),
'Must supply a field name' 4517 if (
present(create))
then 4525 if (
present(index) .and.
present(append))
then 4526 if (append .and. index .gt. 0)
then 4528 write (out_unit,*) trim(warn_header), &
4529 'Index and Append both set for ', trim(name)
4539 if (
present(index))
then 4541 if (index_t .lt. 0)
then 4547 write (out_unit,*) trim(warn_header), &
4548 'Optional index for ', trim(name), &
4549 ' negative: ', index_t
4563 if (
associated(temp_list_p))
then 4564 temp_field_p =>
find_field(base, temp_list_p)
4565 if (.not.
associated(temp_field_p))
then 4571 if (
associated(temp_field_p))
then 4577 temp_field_p%max_index = 0
4578 if (temp_field_p%field_type /=
null_type )
then 4580 write (out_unit,*) trim(warn_header), &
4581 'Changing type of ', trim(name),
' from ', &
4595 if (
present(append))
then 4597 index_t = temp_field_p%max_index + 1
4601 if (index_t .gt. temp_field_p%max_index + 1)
then 4608 write (out_unit,*) trim(warn_header), &
4609 'Index too large for ', trim(name),
': ', index_t
4614 elseif (index_t .eq. 0 .and. &
4615 temp_field_p%max_index .gt. 0)
then 4622 write (out_unit,*) trim(warn_header), &
4623 'Trying to nullify a non-null field: ', trim(name)
4628 elseif (.not.
associated(temp_field_p%l_value) .and. &
4629 index_t .gt. 0)
then 4635 allocate(temp_field_p%l_value(1))
4636 temp_field_p%max_index = 1
4637 temp_field_p%array_dim = 1
4639 elseif (index_t .gt. temp_field_p%array_dim)
then 4646 allocate (temp_l_value(temp_field_p%array_dim))
4647 do i = 1, temp_field_p%max_index
4648 temp_l_value(i) = temp_field_p%l_value(i)
4650 if (
associated(temp_field_p%l_value))
deallocate(temp_field_p%l_value)
4651 temp_field_p%l_value => temp_l_value
4652 temp_field_p%max_index = index_t
4661 if (index_t .gt. 0)
then 4662 temp_field_p%l_value(index_t) =
value 4663 if (index_t .gt. temp_field_p%max_index)
then 4664 temp_field_p%max_index = index_t
4667 field_index = temp_field_p%index
4674 write (out_unit,*) trim(warn_header), &
4675 'Could not create logical value field ', &
4686 write (out_unit,*) trim(warn_header), &
4687 'Could not follow path for ', &
4703 integer :: field_index
4707 character(len=*),
intent(in) :: name
4708 real,
intent(in) :: value
4709 logical,
intent(in),
optional :: create
4710 integer,
intent(in),
optional :: index
4711 logical,
intent(in),
optional :: append
4716 character(len=17),
parameter :: sub_name =
'fm_new_value_real' 4717 character(len=64),
parameter :: warn_header =
'==>Warning from ' // trim(
module_name) // &
4718 '(' // trim(sub_name) //
'): ' 4726 real,
pointer,
dimension(:) :: temp_r_value
4727 character(len=fm_path_name_len) :: path
4728 character(len=fm_field_name_len) :: base
4729 type(
field_def),
pointer,
save :: temp_list_p
4730 type(
field_def),
pointer,
save :: temp_field_p
4743 if (name .eq.
' ')
then 4745 write (out_unit,*) trim(warn_header),
'Must supply a field name' 4753 if (
present(create))
then 4761 if (
present(index) .and.
present(append))
then 4762 if (append .and. index .gt. 0)
then 4764 write (out_unit,*) trim(warn_header), &
4765 'Index and Append both set for ', trim(name)
4775 if (
present(index))
then 4777 if (index_t .lt. 0)
then 4783 write (out_unit,*) trim(warn_header), &
4784 'Optional index for ', trim(name), &
4785 ' negative: ', index_t
4800 if (
associated(temp_list_p))
then 4801 temp_field_p =>
find_field(base, temp_list_p)
4802 if (.not.
associated(temp_field_p))
then 4808 if (
associated(temp_field_p))
then 4815 allocate(temp_field_p%r_value(
size(temp_field_p%i_value)))
4816 do i = 1,
size(temp_field_p%i_value)
4817 temp_field_p%r_value(i) = temp_field_p%i_value(i)
4820 deallocate(temp_field_p%i_value)
4821 else if (temp_field_p%field_type /=
real_type )
then 4826 temp_field_p%max_index = 0
4827 if (temp_field_p%field_type /=
null_type )
then 4829 write (out_unit,*) trim(warn_header), &
4830 'Changing type of ', trim(name),
' from ', &
4843 if (
present(append))
then 4845 index_t = temp_field_p%max_index + 1
4848 if (index_t .gt. temp_field_p%max_index + 1)
then 4854 write (out_unit,*) trim(warn_header), &
4855 'Index too large for ', trim(name),
': ', index_t
4859 elseif (index_t .eq. 0 .and. &
4860 temp_field_p%max_index .gt. 0)
then 4866 write (out_unit,*) trim(warn_header), &
4867 'Trying to nullify a non-null field: ', &
4872 elseif (.not.
associated(temp_field_p%r_value) .and. &
4873 index_t .gt. 0)
then 4877 allocate(temp_field_p%r_value(1))
4878 temp_field_p%max_index = 1
4879 temp_field_p%array_dim = 1
4880 elseif (index_t .gt. temp_field_p%array_dim)
then 4886 allocate (temp_r_value(temp_field_p%array_dim))
4887 do i = 1, temp_field_p%max_index
4888 temp_r_value(i) = temp_field_p%r_value(i)
4890 if (
associated(temp_field_p%r_value))
deallocate(temp_field_p%r_value)
4891 temp_field_p%r_value => temp_r_value
4892 temp_field_p%max_index = index_t
4898 if (index_t .gt. 0)
then 4899 temp_field_p%r_value(index_t) =
value 4900 if (index_t .gt. temp_field_p%max_index)
then 4901 temp_field_p%max_index = index_t
4904 field_index = temp_field_p%index
4911 write (out_unit,*) trim(warn_header), &
4912 'Could not create real value field ', trim(name)
4922 write (out_unit,*) trim(warn_header), &
4923 'Could not follow path for ', trim(name)
4938 integer :: field_index
4942 character(len=*),
intent(in) :: name
4943 character(len=*),
intent(in) :: value
4944 logical,
intent(in),
optional :: create
4945 integer,
intent(in),
optional :: index
4946 logical,
intent(in),
optional :: append
4951 character(len=19),
parameter :: sub_name =
'fm_new_value_string' 4952 character(len=64),
parameter :: warn_header =
'==>Warning from ' // trim(
module_name) // &
4953 '(' // trim(sub_name) //
'): ' 4958 character(len=fm_string_len),
dimension(:),
pointer :: temp_s_value
4959 character(len=fm_path_name_len) :: path
4960 character(len=fm_field_name_len) :: base
4964 type(
field_def),
save,
pointer :: temp_list_p
4965 type(
field_def),
save,
pointer :: temp_field_p
4978 if (name .eq.
' ')
then 4980 write (out_unit,*) trim(warn_header),
'Must supply a field name' 4988 if (
present(create))
then 4997 if (
present(index) .and.
present(append))
then 4998 if (append .and. index .gt. 0)
then 5000 write (out_unit,*) trim(warn_header), &
5001 'Index and Append both set for ', trim(name)
5010 if (
present(index))
then 5012 if (index_t .lt. 0)
then 5018 write (out_unit,*) trim(warn_header), &
5019 'Optional index for ', trim(name), &
5020 ' negative: ', index_t
5035 if (
associated(temp_list_p))
then 5036 temp_field_p =>
find_field(base, temp_list_p)
5037 if (.not.
associated(temp_field_p))
then 5043 if (
associated(temp_field_p))
then 5049 temp_field_p%max_index = 0
5050 if (temp_field_p%field_type /=
null_type )
then 5052 write (out_unit,*) trim(warn_header), &
5053 'Changing type of ', trim(name),
' from ', &
5067 if (
present(append))
then 5069 index_t = temp_field_p%max_index + 1
5073 if (index_t .gt. temp_field_p%max_index + 1)
then 5080 write (out_unit,*) trim(warn_header), &
5081 'Index too large for ', trim(name),
': ', index_t
5086 elseif (index_t .eq. 0 .and. &
5087 temp_field_p%max_index .gt. 0)
then 5094 write (out_unit,*) trim(warn_header), &
5095 'Trying to nullify a non-null field: ', &
5101 elseif (.not.
associated(temp_field_p%s_value) .and. &
5102 index_t .gt. 0)
then 5108 allocate(temp_field_p%s_value(1))
5109 temp_field_p%max_index = 1
5110 temp_field_p%array_dim = 1
5112 elseif (index_t .gt. temp_field_p%array_dim)
then 5119 allocate (temp_s_value(temp_field_p%array_dim))
5120 do i = 1, temp_field_p%max_index
5121 temp_s_value(i) = temp_field_p%s_value(i)
5123 if (
associated(temp_field_p%s_value))
deallocate(temp_field_p%s_value)
5124 temp_field_p%s_value => temp_s_value
5125 temp_field_p%max_index = index_t
5134 if (index_t .gt. 0)
then 5135 temp_field_p%s_value(index_t) =
value 5136 if (index_t .gt. temp_field_p%max_index)
then 5137 temp_field_p%max_index = index_t
5140 field_index = temp_field_p%index
5147 write (out_unit,*) trim(warn_header), &
5148 'Could not create string value field ', &
5159 write (out_unit,*) trim(warn_header), &
5160 'Could not follow path for ', trim(name)
5292 character(len=*),
intent(in) :: name
5297 character(len=fm_path_name_len) :: path
5298 character(len=fm_field_name_len) :: base
5299 type(
field_def),
pointer,
save :: temp_p
5309 if (path .ne.
' ')
then 5310 temp_p =>
find_list(path, this_list_p, .false.)
5311 if (
associated(temp_p))
then 5361 character(len=*),
intent(in) :: oldname
5362 character(len=*),
intent(in) :: newname
5366 character(len=fm_path_name_len) :: path
5367 character(len=fm_field_name_len) :: base
5368 type(
field_def),
pointer,
save :: list_p
5369 type(
field_def),
pointer,
save :: temp_p
5378 if (path .ne.
' ')
then 5380 if (
associated(temp_p))
then 5382 if (
associated(list_p))
then 5383 list_p%name = newname
5391 if (
associated(list_p))
then 5392 list_p%name = newname
5445 nullify(
root%first_field)
5446 nullify(
root%last_field)
5449 if (
associated(
root%i_value))
deallocate(
root%i_value)
5450 if (
associated(
root%l_value))
deallocate(
root%l_value)
5451 if (
associated(
root%r_value))
deallocate(
root%r_value)
5452 if (
associated(
root%s_value))
deallocate(
root%s_value)
5509 character(len=*),
intent(in) :: name
5513 character(len=9),
parameter :: sub_name =
'make_list' 5514 character(len=64),
parameter :: warn_header =
'==>Warning from ' // trim(
module_name) // &
5515 '(' // trim(sub_name) //
'): ' 5520 type(
field_def),
pointer,
save :: dummy_p
5530 if (
associated(dummy_p))
then 5535 write (out_unit,*) trim(warn_header),
'List ', &
5536 trim(name),
' already exists' 5547 if (.not.
associated(list_p))
then 5549 write (out_unit,*) trim(warn_header), &
5550 'Could not create field ', trim(name)
5560 if (
associated(list_p%i_value))
deallocate(list_p%i_value)
5561 if (
associated(list_p%l_value))
deallocate(list_p%l_value)
5562 if (
associated(list_p%r_value))
deallocate(list_p%r_value)
5563 if (
associated(list_p%s_value))
deallocate(list_p%s_value)
5610 character(len=*),
intent(in) :: name
5611 character(len=*),
intent(out) :: method_name
5612 character(len=*),
intent(out) :: method_control
5616 character(len=15),
parameter :: sub_name =
'fm_query_method' 5617 character(len=64),
parameter :: warn_header =
'==>Warning from ' // trim(
module_name) // &
5618 '(' // trim(sub_name) //
'): ' 5622 character(len=fm_path_name_len) :: path
5623 character(len=fm_path_name_len) :: base
5624 character(len=fm_path_name_len) :: name_loc
5625 logical :: recursive_t
5626 type(
field_def),
pointer,
save :: temp_list_p
5627 type(
field_def),
pointer,
save :: temp_value_p
5628 type(
field_def),
pointer,
save :: this_field_p
5633 recursive_t = .true.
5635 method_control =
" " 5640 name_loc = lowercase(name)
5645 if (
associated(temp_list_p))
then 5647 success =
query_method(temp_list_p, recursive_t, base, method_name, method_control)
5653 if (
associated(temp_value_p))
then 5655 this_field_p => temp_value_p%first_field
5657 do while (
associated(this_field_p))
5658 if ( this_field_p%name == base )
then 5659 method_name = this_field_p%s_value(1)
5666 this_field_p => this_field_p%next
5674 write (out_unit,*) trim(warn_header),
'Could not follow path for ', trim(path)
5700 recursive function query_method(list_p, recursive, name, method_name, method_control) &
5726 logical,
intent(in) :: recursive
5727 character(len=*),
intent(in) :: name
5728 character(len=*),
intent(out) :: method_name, method_control
5731 character(len=12),
parameter :: sub_name =
'query_method' 5732 character(len=64),
parameter :: warn_header =
'==>Warning from ' // trim(
module_name) // &
5733 '(' // trim(sub_name) //
'): ' 5736 character(len=64) :: scratch
5737 type(
field_def),
pointer :: this_field_p
5743 if (.not.
associated(list_p))
then 5745 write (out_unit,*) trim(warn_header),
'Invalid list pointer' 5748 elseif (list_p%field_type .ne.
list_type)
then 5750 write (out_unit,*) trim(warn_header), trim(list_p%name)//
' is not a list' 5758 this_field_p => list_p%first_field
5760 do while (
associated(this_field_p))
5761 select case(this_field_p%field_type)
5765 if (.not.
query_method(this_field_p, .true., this_field_p%name, method_name, method_control))
then 5769 method_name = trim(method_name)//trim(this_field_p%name)
5775 write (scratch,*) this_field_p%i_value
5776 call concat_strings(method_control,
comma//trim(this_field_p%name)//
' = '//trim(adjustl(scratch)))
5779 write (scratch,
'(l1)')this_field_p%l_value
5780 call concat_strings(method_control,
comma//trim(this_field_p%name)//
' = '//trim(adjustl(scratch)))
5783 write (scratch,*) this_field_p%r_value
5784 call concat_strings(method_control,
comma//trim(this_field_p%name)//
' = '//trim(adjustl(scratch)))
5787 call concat_strings(method_control,
comma//trim(this_field_p%name)//
' = '//trim(this_field_p%s_value(1)))
5788 do i = 2, this_field_p%max_index
5794 write (out_unit,*) trim(warn_header),
'Undefined type for ', trim(this_field_p%name)
5800 this_field_p => this_field_p%next
5809 character(*),
intent(inout) :: str1
5810 character(*),
intent(in) :: str2
5812 character(64) :: n1,n2
5814 if (len_trim(str1)+len_trim(str2)>len(str1))
then 5815 write(n1,*)len(str1)
5816 write(n2,*)len_trim(str1)+len_trim(str2)
5817 call mpp_error(fatal,
'length of output string ('//trim(adjustl(n1))&
5818 //
') is not enough for the result of concatenation (len='&
5819 //trim(adjustl(n2))//
')')
5821 str1 = trim(str1)//trim(str2)
5862 character(len=*),
intent(in) :: list_name
5863 character(len=*),
intent(in) :: suffix
5864 logical,
intent(in),
optional :: create
5869 character(len=12),
parameter :: sub_name =
'fm_copy_list' 5870 character(len=64),
parameter :: error_header =
'==>Error from ' // trim(
module_name) // &
5871 '(' // trim(sub_name) //
'): ' 5872 character(len=64),
parameter :: warn_header =
'==>Warning from ' // trim(
module_name) // &
5873 '(' // trim(sub_name) //
'): ' 5877 character(len=fm_string_len),
dimension(MAX_FIELD_METHODS) :: control
5878 character(len=fm_string_len),
dimension(MAX_FIELD_METHODS) :: method
5879 character(len=fm_string_len) :: head
5880 character(len=fm_string_len) :: list_name_new
5881 character(len=fm_string_len) :: tail
5882 character(len=fm_string_len) :: val_str
5886 logical :: found_methods
5887 logical :: got_value
5888 logical :: recursive_t
5890 logical :: val_logical
5892 type(
field_def),
pointer,
save :: temp_field_p
5893 type(
field_def),
pointer,
save :: temp_list_p
5900 list_name_new = trim(list_name)//trim(suffix)
5902 recursive_t = .true.
5910 if (list_name .eq.
' ')
then 5921 if (
associated(temp_list_p))
then 5928 write (out_unit,*) trim(warn_header),
'Could not follow path for ', trim(list_name)
5942 if (len_trim(method(n)) > 0 )
then 5946 temp_field_p =>
find_field(tail,temp_field_p)
5947 select case (temp_field_p%field_type)
5951 create = create, append = .true.) < 0 ) &
5952 call mpp_error(fatal, trim(error_header)//
'Could not set the '//trim(method(n))//&
5953 ' for '//trim(list_name)//trim(suffix))
5958 create = create, append = .true.) < 0 ) &
5959 call mpp_error(fatal, trim(error_header)//
'Could not set the '//trim(method(n))//&
5960 ' for '//trim(list_name)//trim(suffix))
5965 create = create, append = .true.) < 0 ) &
5966 call mpp_error(fatal, trim(error_header)//
'Could not set the '//trim(method(n))//&
5967 ' for '//trim(list_name)//trim(suffix))
5972 create = create, append = .true.) < 0 ) &
5973 call mpp_error(fatal, trim(error_header)//
'Could not set the '//trim(method(n))//&
5974 ' for '//trim(list_name)//trim(suffix))
6023 character(len=*),
intent(in) :: list_name
6024 character(len=*),
intent(out),
dimension(:) :: methods
6025 character(len=*),
intent(out),
dimension(:) :: control
6030 character(len=15),
parameter :: sub_name =
'fm_find_methods' 6031 character(len=64),
parameter :: warn_header =
'==>Warning from ' // trim(
module_name) // &
6032 '(' // trim(sub_name) //
'): ' 6037 logical :: recursive_t
6038 type(
field_def),
pointer,
save :: temp_list_p
6046 recursive_t = .true.
6055 if (list_name .eq.
' ')
then 6066 if (
associated(temp_list_p))
then 6073 write (out_unit,*) trim(warn_header),
'Could not follow path for ', trim(list_name)
6083 success =
find_method(temp_list_p, recursive_t, num_meth, methods, control)
6106 recursive function find_method(list_p, recursive, num_meth, method, control) &
6135 logical,
intent(in) :: recursive
6136 integer,
intent(inout) :: num_meth
6137 character(len=*),
intent(out),
dimension(:) :: method
6138 character(len=*),
intent(out),
dimension(:) :: control
6142 character(len=11),
parameter :: sub_name =
'find_method' 6143 character(len=64),
parameter :: warn_header =
'==>Warning from ' // trim(
module_name) // &
6144 '(' // trim(sub_name) //
'): ' 6148 character(len=fm_path_name_len) :: scratch
6154 type(
field_def),
pointer,
save :: this_field_p
6161 if (.not.
associated(list_p))
then 6163 write (out_unit,*) trim(warn_header),
'Invalid list pointer' 6166 elseif (list_p%field_type .ne.
list_type)
then 6168 write (out_unit,*) trim(warn_header), trim(list_p%name),
' is not a list' 6177 this_field_p => list_p%first_field
6179 do while (
associated(this_field_p))
6180 select case(this_field_p%field_type)
6185 if ( this_field_p%length > 1)
then 6186 do n = num_meth+1, num_meth + this_field_p%length - 1
6187 write (method(n),
'(a,a,a,$)') trim(method(num_meth)), &
6190 write (method(num_meth),
'(a,a,a,$)') trim(method(num_meth)), &
6193 write (method(num_meth),
'(a,a,a,$)') trim(method(num_meth)), &
6196 success =
find_method(this_field_p, .true., num_meth, method, control)
6199 write (scratch,*) this_field_p%i_value
6201 write (method(num_meth),
'(a,a)') trim(method(num_meth)), &
6202 trim(this_field_p%name)
6203 write (control(num_meth),
'(a)') &
6205 num_meth = num_meth + 1
6210 write (method(num_meth),
'(a,a)') trim(method(num_meth)), &
6211 trim(this_field_p%name)
6212 write (control(num_meth),
'(l1)') &
6213 this_field_p%l_value
6214 num_meth = num_meth + 1
6218 write (scratch,*) this_field_p%r_value
6220 write (method(num_meth),
'(a,a)') trim(method(num_meth)), &
6221 trim(this_field_p%name)
6222 write (control(num_meth),
'(a)') &
6224 num_meth = num_meth + 1
6228 write (method(num_meth),
'(a,a)') trim(method(num_meth)), &
6229 trim(this_field_p%name)
6230 write (control(num_meth),
'(a)') &
6231 trim(this_field_p%s_value(1))
6232 do i = 2, this_field_p%max_index
6233 write (control(num_meth),
'(a,a,$)')
comma//trim(this_field_p%s_value(i))
6235 num_meth = num_meth + 1
6240 write (out_unit,*) trim(warn_header),
'Undefined type for ', trim(this_field_p%name)
6247 this_field_p => this_field_p%next
6282 integer,
intent(in),
optional :: verbosity
6288 character(len=16),
parameter :: sub_name =
'fm_set_verbosity' 6289 character(len=64),
parameter :: note_header =
'==>Note from ' // trim(
module_name) // &
6290 '(' // trim(sub_name) //
'): ' 6302 if (
present(verbosity))
then 6304 if (verbosity .le. 0)
then 6314 if (
verb .eq. 0)
then 6323 write (out_unit,*) trim(note_header), &
6324 'Verbosity now at level ',
verb 6332 #ifdef test_field_manager 6343 integer :: i, j, nfields, num_methods, model
6344 character(len=fm_string_len) :: field_type, field_name, str, name_field_type, path
6345 character(len=512) :: method_name, method_control
6347 integer :: flag, index
6358 write(*,*)
"Here's a baseline listing" 6360 write(*,*)
'+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+' 6363 write(*,*)
"Here's a recursive listing" 6365 write(*,*)
'+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+' 6368 write(*,*)
'Dumping last field changed to by field_manager using fm_change_list' 6370 write(*,*)
'+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+' 6373 write(*,*)
'Changing list to land_mod' 6375 write(*,*)
'Dumping last list changed to by field_manager using fm_change_list i.e list of land model fields' 6377 write(*,*)
'+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+' 6382 write(*,*)
"ADDING convection = off TO RADON LIST" 6384 if (
fm_exists(
'/atmos_mod/tracer/radon'))
then 6385 write(*,*)
"'/atmos_mod/tracer/radon' exists " 6393 call mpp_error(note,
"Method names for radon is/are "//trim(method_name))
6394 call mpp_error(note,
"Method controls for radon is/are "//trim(method_control))
6396 call mpp_error(note,
"There is no atmos model radon field defined in the field_table")
6399 success =
fm_dump_list(
"/atmos_mod/tracer/radon", .true.)
6400 if (.not. success )
call mpp_error(note,
"There is no atmos model radon field defined in the field_table")
6401 write(*,*)
'+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+' 6406 write(*,*)
'Current path is ',trim(path)
6407 write(*,*)
'+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+' 6410 write(*,*)
"MODIFYING RADON FIELD CONVECTION ATTRIBUTE TO convection = RAS_off " 6414 success =
fm_dump_list(
"/atmos_mod/tracer/radon", .true.)
6415 write(*,*)
'+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+' 6421 write(*,*)
"ORIGINAL OCEAN MODEL TRACER FIELDS" 6425 write(*,*)
'+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+' 6429 write(*,*)
"The length of the current list '/ocean_mod/tracer' is ",index,
" i.e." 6431 write(*,*)
'+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+' 6434 name_field_type =
fm_get_type(
'/ocean_mod/tracer/biotic1/diff_horiz/linear/slope')
6435 write(*,*)
'The type for /ocean_mod/tracer/biotic1/diff_horiz/linear/slope is ',name_field_type
6437 success =
fm_get_value(
'/ocean_mod/tracer/biotic1/diff_horiz/linear/slope',str)
6438 write(*,*)
'The value for /ocean_mod/tracer/biotic1/diff_horiz/linear/slope is (character) ',str
6441 write(*,*)
'+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+' 6443 write(*,*)
"MODIFYING BIOTIC1 FIELD slope ATTRIBUTE TO slope = 0.95 " 6444 if (
fm_change_list(
'/ocean_mod/tracer/biotic1/diff_horiz/linear')) &
6448 success =
fm_dump_list(
"/ocean_mod/tracer/biotic1", .true.)
6449 write(*,*)
'+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+' 6451 name_field_type =
fm_get_type(
'/ocean_mod/tracer/biotic1/diff_horiz/linear/slope')
6452 write(*,*)
'Now the type for /ocean_mod/tracer/biotic1/diff_horiz/linear/slope is ',name_field_type
6453 success =
fm_get_value(
'/ocean_mod/tracer/biotic1/diff_horiz/linear/slope',param)
6454 write(*,*)
'The value for /ocean_mod/tracer/biotic1/diff_horiz/linear/slope is (real) ',param
6455 write(*,*)
'+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+' 6457 write(*,*)
'Changing the name of biotic1 to biotic_control' 6458 success =
fm_modify_name(
'/ocean_mod/tracer/biotic1',
'biotic_control')
6461 success =
fm_dump_list(
"/ocean_mod/tracer/biotic_control", .true.)
6464 success =
fm_dump_list(
"/ocean_mod/tracer/biotic1", .true.)
6465 if (.not. success )
call mpp_error(note,
"Ocean model tracer biotic1 does not exist anymore.")
6466 write(*,*)
'+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+' 6471 write(*,*)
"Now we'll add a new list to this list" 6476 write(*,*)
"Now we'll give it a value" 6482 write(*,*)
'+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+'
character(len=8) function, public fm_get_type(name)
integer, parameter, public model_ice
integer function, public fm_get_index(name)
type(fm_array_list_def) function, pointer, public fm_intersection(lists, dim)
type(field_def) function, pointer, private find_list(path, relative_p, create)
integer, parameter, public fm_path_name_len
function parse_reals(text, label, values)
integer, parameter, public model_atmos
character(len=fm_field_name_len) save_root_name
type(field_def) function, pointer, private get_field(name, this_list_p)
character(len=1), parameter equal
logical function, public fm_get_value_string(name, value, index)
character(len=1), parameter bracket_left
integer function, public fm_new_value_real(name, value, create, index, append)
integer, parameter, public set
logical function, public fm_get_value_real(name, value, index)
recursive logical function find_method(list_p, recursive, num_meth, method, control)
function parse_integers(text, label, values)
integer function, public fm_new_value_logical(name, value, create, index, append)
subroutine, private find_base(name, path, base)
integer, parameter string_type
integer, parameter real_type
integer, parameter, public no_field
subroutine, public field_manager_end
character(len=1), parameter comment
integer function, public fm_new_list(name, create, keep)
subroutine, private find_head(name, head, rest)
integer, parameter, public fm_string_len
subroutine check_for_name_duplication
type(field_def) function, pointer, private make_list(this_list_p, name)
integer, parameter, public model_ocean
integer, parameter list_type
integer function, public find_field_index_new(field_name)
subroutine, public get_field_info(n, fld_type, fld_name, model, num_methods)
type(field_def), pointer current_list_p
logical function, public fm_find_methods(list_name, methods, control)
type(field_mgr_type), dimension(max_fields), private fields
type(field_def) function, pointer, private create_field(parent_p, name)
integer, parameter, public model_land
logical function, public fm_change_list(name)
character(len=1), parameter bracket_right
integer function parse_string(text, label, value)
type(method_type), public default_method
integer, parameter max_fields
type(field_def), pointer save_root_parent_p
subroutine, public fm_init_loop(loop_list, iter)
integer, parameter null_type
subroutine concat_strings(str1, str2)
l_size ! loop over number of fields ke do je do ie to je n if(.NOT. d_comm%R_do_buf(list)) cycle from_pe
integer, parameter logical_type
integer, parameter, public fm_type_name_len
integer function, public fm_new_value_integer(name, value, create, index, append)
subroutine, private initialize
************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software 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 see< http:! ***********************************************************************!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! MPP_TRANSMIT !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! subroutine MPP_TRANSMIT_(put_data, put_len, to_pe, get_data, get_len, from_pe, block, tag, recv_request, send_request)!a message-passing routine intended to be reminiscent equally of both MPI and SHMEM!put_data and get_data are contiguous MPP_TYPE_ arrays!at each call, your put_data array is put to to_pe 's get_data! your get_data array is got from from_pe 's put_data!i.e we assume that typically(e.g updating halo regions) each PE performs a put _and_ a get!special PE designations:! NULL_PE:to disable a put or a get(e.g at boundaries)! ANY_PE:if remote PE for the put or get is to be unspecific! ALL_PES:broadcast and collect operations(collect not yet implemented)!ideally we would not pass length, but this f77-style call performs better(arrays passed by address, not descriptor)!further, this permits< length > contiguous words from an array of any rank to be passed(avoiding f90 rank conformance check)!caller is responsible for completion checks(mpp_sync_self) before and after integer, intent(in) ::put_len, to_pe, get_len, from_pe MPP_TYPE_, intent(in) ::put_data(*) MPP_TYPE_, intent(out) ::get_data(*) logical, intent(in), optional ::block integer, intent(in), optional ::tag integer, intent(out), optional ::recv_request, send_request logical ::block_comm integer ::i MPP_TYPE_, allocatable, save ::local_data(:) !local copy used by non-parallel code(no SHMEM or MPI) integer ::comm_tag integer ::rsize if(.NOT.module_is_initialized) call mpp_error(FATAL, 'MPP_TRANSMIT:You must first call mpp_init.') if(to_pe.EQ.NULL_PE .AND. from_pe.EQ.NULL_PE) return block_comm=.true. if(PRESENT(block)) block_comm=block if(debug) then call SYSTEM_CLOCK(tick) write(stdout_unit,'(a, i18, a, i6, a, 2i6, 2i8)')&'T=', tick, ' PE=', pe, ' MPP_TRANSMIT begin:to_pe, from_pe, put_len, get_len=', to_pe, from_pe, put_len, get_len end if comm_tag=DEFAULT_TAG if(present(tag)) comm_tag=tag!do put first and then get if(to_pe.GE.0 .AND. to_pe.LT.npes) then!use non-blocking sends if(debug .and.(current_clock.NE.0)) call SYSTEM_CLOCK(start_tick)!z1l:truly non-blocking send.! if(request(to_pe).NE.MPI_REQUEST_NULL) then !only one message from pe-> to_pe in queue *PE waiting for to_pe ! call error else get_len so only do gets but you cannot have a pure get with MPI call mpp_error(FATAL, 'MPP_TRANSMIT:you cannot transmit to ANY_PE using MPI.') else if(to_pe.NE.NULL_PE) then !no other valid cases except NULL_PE call mpp_error(FATAL
logical function fm_loop_over_list_old(list, name, field_type, index)
type(field_def) function, pointer, private find_field(name, this_list_p)
type(field_def), pointer loop_list_p
character(len=1), parameter comma
character(len=1), parameter dquote
integer function, public fm_new_value_string(name, value, create, index, append)
logical function, public fm_get_value_integer(name, value, index)
recursive logical function query_method(list_p, recursive, name, method_name, method_control)
integer, parameter line_len
subroutine, public fm_set_verbosity(verbosity)
integer, parameter array_increment
character(len=50) set_nonexp
integer function parse_integer(text, label, value)
logical function, public fm_dump_list(name, recursive, unit)
logical module_is_initialized
logical function, public fm_exists(name)
logical recursive function, private dump_list(list_p, recursive, depth, out_unit)
logical function, public fm_query_method(name, method_name, method_control)
subroutine, public get_field_method(n, m, method)
subroutine new_name(list_name, method_name_in, val_name_in)
character(len=11), dimension(num_models), parameter, public model_names
subroutine, public fm_reset_loop
logical function, public fm_modify_name(oldname, newname)
logical function set_list_stuff()
type(field_def), target, save root
integer, parameter, public num_models
integer, parameter num_types
integer, parameter max_field_methods
character(len=1), parameter space
character(len=1), parameter squote
subroutine, public fm_return_root
integer default_verbosity
integer function, public fm_copy_list(list_name, suffix, create)
integer, parameter, public model_coupler
type(field_def), pointer root_p
character(len=1), parameter tab
character(len=fm_type_name_len), dimension(num_types) field_type_name
logical function fm_loop_over_list_new(iter, name, field_type, index)
integer function parse_real(text, label, value)
character(len=1), parameter list_sep
subroutine strip_front_blanks(name)
function parse_strings(text, label, values)
character(len=fm_path_name_len) loop_list
integer function, public fm_get_length(name)
integer function, public find_field_index_old(model, field_name)
subroutine, public get_field_methods(n, methods)
logical function, public fm_change_root(name)
integer, parameter integer_type
character(len=fm_path_name_len) function, public fm_get_current_list()
integer, parameter, public fm_field_name_len
character(len=17), parameter module_name
logical function, public fm_get_value_logical(name, value, index)
subroutine, public field_manager_init(nfields, table_name)