FMS  2025.02.01
Flexible Modeling System
fm_util.F90
1 !***********************************************************************
2 !* GNU Lesser General Public License
3 !*
4 !* This file is part of the GFDL Flexible Modeling System (FMS).
5 !*
6 !* FMS is free software: you can redistribute it and/or modify it under
7 !* the terms of the GNU Lesser General Public License as published by
8 !* the Free Software Foundation, either version 3 of the License, or (at
9 !* your option) any later version.
10 !*
11 !* FMS is distributed in the hope that it will be useful, but WITHOUT
12 !* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 !* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 !* for more details.
15 !*
16 !* You should have received a copy of the GNU Lesser General Public
17 !* License along with FMS. If not, see <http://www.gnu.org/licenses/>.
18 !***********************************************************************
19 !> @defgroup fm_util_mod fm_util_mod
20 !> @ingroup field_manager
21 !> @brief This module provides utility routines for the field manager.
22 !!
23 !> Routines for error catching, reporting and
24 !! termination while interfacing with the field manager.
25 !> @author Richard D. Slater
26 
27 !> @addtogroup fm_util_mod
28 !> @{
29 module fm_util_mod !{
30 
31 use field_manager_mod, only: fm_string_len, fm_field_name_len, fm_type_name_len
32 use field_manager_mod, only: fm_get_type, fm_get_index, fm_get_length
34 use field_manager_mod, only: fm_new_value, fm_get_value
35 use field_manager_mod, only: fm_exists, fm_dump_list
36 use fms_mod, only: fatal, stdout
37 use mpp_mod, only: mpp_error
38 use platform_mod, only: r4_kind, r8_kind, fms_path_len
39 
40 implicit none
41 
42 private
43 
47 public fm_util_set_caller
53 public fm_util_get_length
56 public fm_util_get_real
57 public fm_util_get_string
62 public fm_util_set_value
63 !public fm_util_get_index
66 
67 !
68 ! Public variables
69 !
70 
71 character(len=128), public :: fm_util_default_caller = ' '
72 
73 !
74 ! private parameters
75 !
76 
77 character(len=48), parameter :: mod_name = 'fm_util_mod'
78 
79 !
80 ! Private variables
81 !
82 
83 character(len=128) :: save_default_caller = ' '
84 character(len=128) :: default_good_name_list = ' '
85 character(len=128) :: save_default_good_name_list = ' '
86 logical :: default_no_overwrite = .false.
87 logical :: save_default_no_overwrite = .false.
88 character(len=FMS_PATH_LEN) :: save_current_list
89 character(len=FMS_PATH_LEN) :: save_path
90 character(len=FMS_PATH_LEN) :: save_name
91 ! Include variable "version" to be written to log file.
92 #include<file_version.h>
93 
94 !
95 ! Interface definitions for overloaded routines
96 !
97 
98 !> @}
99 
101  module procedure fm_util_set_value_real_r4
102  module procedure fm_util_set_value_real_r8
103 end interface fm_util_set_value_real
104 
106  module procedure fm_util_set_value_real_array_r4
107  module procedure fm_util_set_value_real_array_r8
108 end interface fm_util_set_value_real_array
109 
110 !> @ingroup fm_util_mod
111 interface fm_util_set_value !{
112  module procedure fm_util_set_value_integer_array
113  module procedure fm_util_set_value_real_array_r4
114  module procedure fm_util_set_value_real_array_r8
115  module procedure fm_util_set_value_logical_array
116  module procedure fm_util_set_value_string_array
117  module procedure fm_util_set_value_real_r4
118  module procedure fm_util_set_value_real_r8
119  module procedure fm_util_set_value_integer
120  module procedure fm_util_set_value_logical
121  module procedure fm_util_set_value_string
122 end interface !}
123 
124 !interface fm_util_get_index !{
125  !module procedure fm_util_get_index_list
126  !module procedure fm_util_get_index_string
127 !end interface !}
128 
129 !> @addtogroup fm_util_mod
130 !> @{
131 
132 contains
133 
134 !> Set the default value for the optional "caller" variable used in many of these
135 !! subroutines. If the argument is blank, then set the default to blank, otherwise
136 !! the deault will have brackets placed around the argument.
137 subroutine fm_util_set_caller(caller) !{
138 
139 implicit none
140 
141 !
142 ! arguments
143 !
144 
145 character(len=*), intent(in) :: caller
146 
147 !
148 ! Local variables
149 !
150 
151 !
152 ! save the default caller string
153 !
154 
155 save_default_caller = fm_util_default_caller
156 
157 !
158 ! set the default caller string
159 !
160 
161 if (caller .eq. ' ') then !{
162  fm_util_default_caller = ' '
163 else !}{
164  fm_util_default_caller = '[' // trim(caller) // ']'
165 endif !}
166 
167 return
168 
169 end subroutine fm_util_set_caller !}
170 
171 !#######################################################################
172 
173 !> Reset the default value for the optional "caller" variable used in many of these
174 !! subroutines to blank.
175 subroutine fm_util_reset_caller !{
176 
177 implicit none
178 
179 !
180 ! arguments
181 !
182 
183 !
184 ! Local variables
185 !
186 
187 !
188 ! reset the default caller string
189 !
190 
191 fm_util_default_caller = save_default_caller
192 save_default_caller = ' '
193 
194 return
195 
196 end subroutine fm_util_reset_caller !}
197 
198 !#######################################################################
199 
200 !> Set the default value for the optional "good_name_list" variable used in many of these
201 !! subroutines.
202 subroutine fm_util_set_good_name_list(good_name_list) !{
203 
204 implicit none
205 
206 !
207 ! arguments
208 !
209 
210 character(len=*), intent(in) :: good_name_list
211 
212 !
213 ! Local variables
214 !
215 
216 !
217 ! save the default good_name_list string
218 !
219 
220 save_default_good_name_list = default_good_name_list
221 
222 !
223 ! set the default good_name_list string
224 !
225 
226 default_good_name_list = good_name_list
227 
228 return
229 
230 end subroutine fm_util_set_good_name_list !}
231 
232 !#######################################################################
233 
234 !> Reset the default value for the optional "good_name_list" variable used in many of these
235 !! subroutines to the saved value.
237 
238 implicit none
239 
240 !
241 ! arguments
242 !
243 
244 !
245 ! Local variables
246 !
247 
248 !
249 ! reset the default good_name_list string
250 !
251 
252 default_good_name_list = save_default_good_name_list
253 save_default_good_name_list = ' '
254 
255 return
256 
257 end subroutine fm_util_reset_good_name_list !}
258 
259 !#######################################################################
260 
261 !> Set the default value for the optional "no_overwrite" variable used in some of these
262 !! subroutines.
263 subroutine fm_util_set_no_overwrite(no_overwrite) !{
264 
265 implicit none
266 
267 !
268 ! arguments
269 !
270 
271 logical, intent(in) :: no_overwrite
272 
273 !
274 ! Local variables
275 !
276 
277 !
278 ! save the default no_overwrite string
279 !
280 
281 save_default_no_overwrite = default_no_overwrite
282 
283 !
284 ! set the default no_overwrite value
285 !
286 
287 default_no_overwrite = no_overwrite
288 
289 return
290 
291 end subroutine fm_util_set_no_overwrite !}
292 
293 !#######################################################################
294 
295 !> Reset the default value for the optional "no_overwrite" variable used in some of these
296 !! subroutines to false.
298 
299 implicit none
300 
301 !
302 ! arguments
303 !
304 
305 !
306 ! Local variables
307 !
308 
309 !
310 ! reset the default no_overwrite value
311 !
312 
313 default_no_overwrite = save_default_no_overwrite
314 save_default_no_overwrite = .false.
315 
316 return
317 
318 end subroutine fm_util_reset_no_overwrite !}
319 
320 !#######################################################################
321 
322 !> Check for unrecognized fields in a list
323 subroutine fm_util_check_for_bad_fields(list, good_fields, caller) !{
324 
325 implicit none
326 
327 !
328 ! arguments
329 !
330 
331 character(len=*), intent(in) :: list
332 character(len=*), intent(in), dimension(:) :: good_fields
333 character(len=*), intent(in), optional :: caller
334 
335 !
336 ! Local parameters
337 !
338 
339 character(len=48), parameter :: sub_name = 'fm_util_check_for_bad_fields'
340 
341 !
342 ! Local variables
343 !
344 
345 logical :: fm_success
346 integer :: i
347 integer :: ind
348 integer :: list_length
349 integer :: good_length
350 character(len=fm_type_name_len) :: typ
351 character(len=fm_field_name_len) :: name
352 logical :: found
353 character(len=256) :: error_header
354 character(len=256) :: warn_header
355 character(len=256) :: note_header
356 character(len=128) :: caller_str
357 integer :: out_unit
358 
359 out_unit = stdout()
360 
361 !
362 ! set the caller string and headers
363 !
364 
365 if (present(caller)) then !{
366  caller_str = '[' // trim(caller) // ']'
367 else !}{
368  caller_str = fm_util_default_caller
369 endif !}
370 
371 error_header = '==>Error from ' // trim(mod_name) // &
372  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
373 warn_header = '==>Warning from ' // trim(mod_name) // &
374  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
375 note_header = '==>Note from ' // trim(mod_name) // &
376  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
377 
378 !
379 ! check that a list is given (fatal if not)
380 !
381 
382 if (list .eq. ' ') then !{
383  write (out_unit,*) trim(error_header) // ' Empty list given'
384  call mpp_error(fatal, trim(error_header) // ' Empty list given')
385 endif !}
386 
387 !
388 ! Check that we have been given a list
389 !
390 
391 if (fm_get_type(list) .ne. 'list') then !{
392  write (out_unit,*) trim(error_header) // ' Not given a list: ' // trim(list)
393  call mpp_error(fatal, trim(error_header) // ' Not given a list: ' // trim(list))
394 endif !}
395 
396 !
397 ! Get the list length
398 !
399 
400 list_length = fm_get_length(list)
401 if (list_length .lt. 0) then !{
402  call mpp_error(fatal, trim(error_header) // ' Problem getting length of ' // trim(list))
403 endif !}
404 
405 !
406 ! Get the number of good fields
407 !
408 
409 good_length = size(good_fields)
410 
411 if (list_length .lt. good_length) then !{
412 
413 !
414 ! If the list length is less than the number of good fields this is an error
415 ! as the list should be fully populated and we'll check which extra fields
416 ! are given in good_fields
417 !
418 
419  write (out_unit,*) trim(error_header), ' List length < number of good fields (', &
420  list_length, ' < ', good_length, ') in list ', trim(list)
421 
422  write (out_unit,*)
423  write (out_unit,*) 'The list contains the following fields:'
424  fm_success= fm_dump_list(list, .false.)
425  write (out_unit,*)
426  write (out_unit,*) 'The supposed list of good fields is:'
427  do i = 1, good_length !{
428  if (fm_exists(trim(list) // '/' // good_fields(i))) then !{
429  write (out_unit,*) 'List field: "', trim(good_fields(i)), '"'
430  else !}{
431  write (out_unit,*) 'EXTRA good field: "', trim(good_fields(i)), '"'
432  endif !}
433  enddo !} i
434  write (out_unit,*)
435 
436  call mpp_error(fatal, trim(error_header) // &
437  ' List length < number of good fields for list: ' // trim(list))
438 
439 elseif (list_length .gt. good_length) then !}{
440 
441 !
442 ! If the list length is greater than the number of good fields this is an error
443 ! as the there should not be any more fields than those given in the good fields list
444 ! and we'll check which extra fields are given in the list
445 !
446 
447  write (out_unit,*) trim(warn_header), 'List length > number of good fields (', &
448  list_length, ' > ', good_length, ') in list ', trim(list)
449 
450  write (out_unit,*) trim(error_header), ' Start of list of fields'
451  do while (fm_loop_over_list(list, name, typ, ind)) !{
452  found = .false.
453  do i = 1, good_length !{
454  found = found .or. (name .eq. good_fields(i))
455  enddo !} i
456  if (found) then !{
457  write (out_unit,*) 'Good list field: "', trim(name), '"'
458  else !}{
459  write (out_unit,*) 'EXTRA list field: "', trim(name), '"'
460  endif !}
461  enddo !}
462  write (out_unit,*) trim(error_header), ' End of list of fields'
463 
464  call mpp_error(fatal, trim(error_header) // &
465  ' List length > number of good fields for list: ' // trim(list))
466 
467 endif !}
468 
469 !
470 ! If the list length equals the number of good fields then all is good
471 !
472 
473 return
474 
475 end subroutine fm_util_check_for_bad_fields !}
476 
477 !#######################################################################
478 
479 !> Get the length of an element of the Field Manager tree
480 function fm_util_get_length(name, caller) &
481  result(field_length) !{
482 
483 implicit none
484 
485 !
486 ! Return type
487 !
488 
489 integer :: field_length
490 
491 !
492 ! arguments
493 !
494 
495 character(len=*), intent(in) :: name
496 character(len=*), intent(in), optional :: caller
497 
498 !
499 ! Local parameters
500 !
501 
502 character(len=48), parameter :: sub_name = 'fm_util_get_length'
503 
504 !
505 ! Local variables
506 !
507 
508 character(len=256) :: error_header
509 character(len=256) :: warn_header
510 character(len=256) :: note_header
511 character(len=128) :: caller_str
512 
513 !
514 ! set the caller string and headers
515 !
516 
517 if (present(caller)) then !{
518  caller_str = '[' // trim(caller) // ']'
519 else !}{
520  caller_str = fm_util_default_caller
521 endif !}
522 
523 error_header = '==>Error from ' // trim(mod_name) // &
524  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
525 warn_header = '==>Warning from ' // trim(mod_name) // &
526  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
527 note_header = '==>Note from ' // trim(mod_name) // &
528  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
529 
530 !
531 ! check that a name is given (fatal if not)
532 !
533 
534 if (name .eq. ' ') then !{
535  call mpp_error(fatal, trim(error_header) // ' Empty name given')
536 endif !}
537 
538 !
539 ! Get the field's length
540 !
541 
542 field_length = fm_get_length(name)
543 if (field_length .lt. 0) then !{
544  call mpp_error(fatal, trim(error_header) // ' Problem getting length of ' // trim(name))
545 endif !}
546 
547 return
548 
549 end function fm_util_get_length !}
550 
551 !#######################################################################
552 
553 !> Get the index of an element of a string in the Field Manager tree
554 function fm_util_get_index_string(name, string, caller) &
555  result(fm_index) !{
556 
557 implicit none
558 
559 !
560 ! Return type
561 !
562 
563 integer :: fm_index
564 
565 !
566 ! arguments
567 !
568 
569 character(len=*), intent(in) :: name
570 character(len=*), intent(in) :: string
571 character(len=*), intent(in), optional :: caller
572 
573 !
574 ! Local parameters
575 !
576 
577 character(len=48), parameter :: sub_name = 'fm_util_get_index_string'
578 
579 !
580 ! Local variables
581 !
582 
583 character(len=256) :: error_header
584 character(len=256) :: warn_header
585 character(len=256) :: note_header
586 character(len=128) :: caller_str
587 character(len=32) :: index_str
588 character(len=fm_type_name_len) :: fm_type
589 character(len=fm_string_len) :: fm_string
590 integer :: i
591 integer :: length
592 
593 !
594 ! set the caller string and headers
595 !
596 
597 if (present(caller)) then !{
598  caller_str = '[' // trim(caller) // ']'
599 else !}{
600  caller_str = fm_util_default_caller
601 endif !}
602 
603 error_header = '==>Error from ' // trim(mod_name) // &
604  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
605 warn_header = '==>Warning from ' // trim(mod_name) // &
606  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
607 note_header = '==>Note from ' // trim(mod_name) // &
608  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
609 
610 !
611 ! check that a name is given (fatal if not)
612 !
613 
614 if (name .eq. ' ') then !{
615  call mpp_error(fatal, trim(error_header) // ' Empty name given')
616 endif !}
617 
618 !
619 ! Check the field's type and get the index
620 !
621 
622 fm_index = 0
623 fm_type = fm_get_type(name)
624 if (fm_type .eq. 'string') then !{
625  length = fm_get_length(name)
626  if (length .lt. 0) then !{
627  call mpp_error(fatal, trim(error_header) // ' Problem getting length of ' // trim(name))
628  endif !}
629  if (length .gt. 0) then !{
630  do i = 1, length !{
631  if (.not. fm_get_value(name, fm_string, index = i)) then !{
632  write (index_str,*) '(', i, ')'
633  call mpp_error(fatal, trim(error_header) // ' Problem getting ' // trim(name) // trim(index_str))
634  endif !}
635  if (fm_string .eq. string) then !{
636  fm_index = i
637  exit
638  endif !}
639  enddo !} i
640  endif !}
641 elseif (fm_type .eq. ' ') then !}{
642  call mpp_error(fatal, trim(error_header) // ' Array does not exist: ' // trim(name))
643 else !}{
644  call mpp_error(fatal, trim(error_header) // ' Wrong type for ' // trim(name) // ', found (' // trim(fm_type) // ')')
645 endif !}
646 
647 !if (fm_index .eq. 0) then !{
648  !call mpp_error(FATAL, trim(error_header) // ' "' // trim(string) // '" does not exist in ' // trim(name))
649 !endif !}
650 
651 return
652 
653 end function fm_util_get_index_string !}
654 
655 !#######################################################################
656 
657 !> Get the length of an element of the Field Manager tree
658 function fm_util_get_index_list(name, caller) &
659  result(fm_index) !{
660 
661 implicit none
662 
663 !
664 ! Return type
665 !
666 
667 integer :: fm_index
668 
669 !
670 ! arguments
671 !
672 
673 character(len=*), intent(in) :: name
674 character(len=*), intent(in), optional :: caller
675 
676 !
677 ! Local parameters
678 !
679 
680 character(len=48), parameter :: sub_name = 'fm_util_get_index_list'
681 
682 !
683 ! Local variables
684 !
685 
686 character(len=256) :: error_header
687 character(len=256) :: warn_header
688 character(len=256) :: note_header
689 character(len=128) :: caller_str
690 character(len=fm_type_name_len) :: fm_type
691 
692 !
693 ! set the caller string and headers
694 !
695 
696 if (present(caller)) then !{
697  caller_str = '[' // trim(caller) // ']'
698 else !}{
699  caller_str = fm_util_default_caller
700 endif !}
701 
702 error_header = '==>Error from ' // trim(mod_name) // &
703  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
704 warn_header = '==>Warning from ' // trim(mod_name) // &
705  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
706 note_header = '==>Note from ' // trim(mod_name) // &
707  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
708 
709 !
710 ! check that a name is given (fatal if not)
711 !
712 
713 if (name .eq. ' ') then !{
714  call mpp_error(fatal, trim(error_header) // ' Empty name given')
715 endif !}
716 
717 !
718 ! Check the field's type and get the index
719 !
720 
721 fm_index = 0
722 fm_type = fm_get_type(name)
723 if (fm_type .eq. 'list') then !{
724  fm_index = fm_get_index(name)
725  if (fm_index .le. 0) then !{
726  call mpp_error(fatal, trim(error_header) // ' List does not exist: ' // trim(name))
727  endif !}
728 elseif (fm_type .eq. ' ') then !}{
729  call mpp_error(fatal, trim(error_header) // ' List does not exist: ' // trim(name))
730 else !}{
731  call mpp_error(fatal, trim(error_header) // ' Wrong type for ' // trim(name) // ', found (' // trim(fm_type) // ')')
732 endif !}
733 
734 
735 return
736 
737 end function fm_util_get_index_list !}
738 
739 
740 !#######################################################################
741 
742 !> Get an integer value from the Field Manager tree.
743 function fm_util_get_integer_array(name, caller) &
744  result(array) !{
745 
746 implicit none
747 
748 !
749 ! Return type
750 !
751 
752 integer, pointer, dimension(:) :: array
753 
754 !
755 ! arguments
756 !
757 
758 character(len=*), intent(in) :: name
759 character(len=*), intent(in), optional :: caller
760 
761 !
762 ! Local parameters
763 !
764 
765 character(len=48), parameter :: sub_name = 'fm_util_get_integer_array'
766 
767 !
768 ! Local variables
769 !
770 
771 character(len=256) :: error_header
772 character(len=256) :: warn_header
773 character(len=256) :: note_header
774 character(len=128) :: caller_str
775 character(len=32) :: index_str
776 character(len=fm_type_name_len) :: fm_type
777 integer :: i
778 integer :: length
779 
780 nullify(array)
781 
782 !
783 ! set the caller string and headers
784 !
785 
786 if (present(caller)) then !{
787  caller_str = '[' // trim(caller) // ']'
788 else !}{
789  caller_str = fm_util_default_caller
790 endif !}
791 
792 error_header = '==>Error from ' // trim(mod_name) // &
793  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
794 warn_header = '==>Warning from ' // trim(mod_name) // &
795  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
796 note_header = '==>Note from ' // trim(mod_name) // &
797  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
798 
799 !
800 ! check that a name is given (fatal if not)
801 !
802 
803 if (name .eq. ' ') then !{
804  call mpp_error(fatal, trim(error_header) // ' Empty name given')
805 endif !}
806 
807 fm_type = fm_get_type(name)
808 if (fm_type .eq. 'integer') then !{
809  length = fm_get_length(name)
810  if (length .lt. 0) then !{
811  call mpp_error(fatal, trim(error_header) // ' Problem getting length of ' // trim(name))
812  endif !}
813  if (length .gt. 0) then !{
814  allocate(array(length))
815  do i = 1, length !{
816  if (.not. fm_get_value(name, array(i), index = i)) then !{
817  write (index_str,*) '(', i, ')'
818  call mpp_error(fatal, trim(error_header) // ' Problem getting ' // trim(name) // trim(index_str))
819  endif !}
820  enddo !} i
821  endif !}
822 elseif (fm_type .eq. ' ') then !}{
823  call mpp_error(fatal, trim(error_header) // ' Array does not exist: ' // trim(name))
824 else !}{
825  call mpp_error(fatal, trim(error_header) // ' Wrong type for ' // trim(name) // ', found (' // trim(fm_type) // ')')
826 endif !}
827 
828 return
829 
830 end function fm_util_get_integer_array !}
831 
832 !#######################################################################
833 
834 !> Get a logical value from the Field Manager tree.
835 function fm_util_get_logical_array(name, caller) &
836  result(array) !{
837 
838 implicit none
839 
840 !
841 ! Return type
842 !
843 
844 logical, pointer, dimension(:) :: array
845 
846 !
847 ! arguments
848 !
849 
850 character(len=*), intent(in) :: name
851 character(len=*), intent(in), optional :: caller
852 
853 !
854 ! Local parameters
855 !
856 
857 character(len=48), parameter :: sub_name = 'fm_util_get_logical_array'
858 
859 !
860 ! Local variables
861 !
862 
863 character(len=256) :: error_header
864 character(len=256) :: warn_header
865 character(len=256) :: note_header
866 character(len=128) :: caller_str
867 character(len=32) :: index_str
868 character(len=fm_type_name_len) :: fm_type
869 integer :: i
870 integer :: length
871 
872 nullify(array)
873 
874 !
875 ! set the caller string and headers
876 !
877 
878 if (present(caller)) then !{
879  caller_str = '[' // trim(caller) // ']'
880 else !}{
881  caller_str = fm_util_default_caller
882 endif !}
883 
884 error_header = '==>Error from ' // trim(mod_name) // &
885  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
886 warn_header = '==>Warning from ' // trim(mod_name) // &
887  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
888 note_header = '==>Note from ' // trim(mod_name) // &
889  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
890 
891 !
892 ! check that a name is given (fatal if not)
893 !
894 
895 if (name .eq. ' ') then !{
896  call mpp_error(fatal, trim(error_header) // ' Empty name given')
897 endif !}
898 
899 fm_type = fm_get_type(name)
900 if (fm_type .eq. 'logical') then !{
901  length = fm_get_length(name)
902  if (length .lt. 0) then !{
903  call mpp_error(fatal, trim(error_header) // ' Problem getting length of ' // trim(name))
904  endif !}
905  if (length .gt. 0) then !{
906  allocate(array(length))
907  do i = 1, length !{
908  if (.not. fm_get_value(name, array(i), index = i)) then !{
909  write (index_str,*) '(', i, ')'
910  call mpp_error(fatal, trim(error_header) // ' Problem getting ' // trim(name) // trim(index_str))
911  endif !}
912  enddo !} i
913  endif !}
914 elseif (fm_type .eq. ' ') then !}{
915  call mpp_error(fatal, trim(error_header) // ' Array does not exist: ' // trim(name))
916 else !}{
917  call mpp_error(fatal, trim(error_header) // ' Wrong type for ' // trim(name) // ', found (' // trim(fm_type) // ')')
918 endif !}
919 
920 return
921 
922 end function fm_util_get_logical_array !}
923 
924 !#######################################################################
925 
926 !> Get a real value from the Field Manager tree.
927 function fm_util_get_real_array(name, caller) &
928  result(array) !{
929 
930 implicit none
931 
932 !
933 ! Return type
934 !
935 
936 real(r8_kind), pointer, dimension(:) :: array
937 
938 !
939 ! arguments
940 !
941 
942 character(len=*), intent(in) :: name
943 character(len=*), intent(in), optional :: caller
944 
945 !
946 ! Local parameters
947 !
948 
949 character(len=48), parameter :: sub_name = 'fm_util_get_real_array'
950 
951 !
952 ! Local variables
953 !
954 
955 character(len=256) :: error_header
956 character(len=256) :: warn_header
957 character(len=256) :: note_header
958 character(len=128) :: caller_str
959 character(len=32) :: index_str
960 character(len=fm_type_name_len) :: fm_type
961 integer :: i
962 integer :: length
963 
964 nullify(array)
965 
966 !
967 ! set the caller string and headers
968 !
969 
970 if (present(caller)) then !{
971  caller_str = '[' // trim(caller) // ']'
972 else !}{
973  caller_str = fm_util_default_caller
974 endif !}
975 
976 error_header = '==>Error from ' // trim(mod_name) // &
977  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
978 warn_header = '==>Warning from ' // trim(mod_name) // &
979  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
980 note_header = '==>Note from ' // trim(mod_name) // &
981  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
982 
983 !
984 ! check that a name is given (fatal if not)
985 !
986 
987 if (name .eq. ' ') then !{
988  call mpp_error(fatal, trim(error_header) // ' Empty name given')
989 endif !}
990 
991 fm_type = fm_get_type(name)
992 if (fm_type .eq. 'real') then !{
993  length = fm_get_length(name)
994  if (length .lt. 0) then !{
995  call mpp_error(fatal, trim(error_header) // ' Problem getting length of ' // trim(name))
996  endif !}
997  if (length .gt. 0) then !{
998  allocate(array(length))
999  do i = 1, length !{
1000  if (.not. fm_get_value(name, array(i), index = i)) then !{
1001  write (index_str,*) '(', i, ')'
1002  call mpp_error(fatal, trim(error_header) // ' Problem getting ' // trim(name) // trim(index_str))
1003  endif !}
1004  enddo !} i
1005  endif !}
1006 elseif (fm_type .eq. ' ') then !}{
1007  call mpp_error(fatal, trim(error_header) // ' Array does not exist: ' // trim(name))
1008 else !}{
1009  call mpp_error(fatal, trim(error_header) // ' Wrong type for ' // trim(name) // ', found (' // trim(fm_type) // ')')
1010 endif !}
1011 
1012 return
1013 
1014 end function fm_util_get_real_array !}
1015 
1016 !#######################################################################
1017 
1018 
1019 !> Get a string value from the Field Manager tree.
1020 function fm_util_get_string_array(name, caller) &
1021  result(array) !{
1022 
1023 implicit none
1024 
1025 !
1026 ! Return type
1027 !
1028 
1029 character(len=fm_string_len), pointer, dimension(:) :: array
1030 
1031 !
1032 ! arguments
1033 !
1034 
1035 character(len=*), intent(in) :: name
1036 character(len=*), intent(in), optional :: caller
1037 
1038 !
1039 ! Local parameters
1040 !
1041 
1042 character(len=48), parameter :: sub_name = 'fm_util_get_string_array'
1043 
1044 !
1045 ! Local variables
1046 !
1047 
1048 character(len=256) :: error_header
1049 character(len=256) :: warn_header
1050 character(len=256) :: note_header
1051 character(len=128) :: caller_str
1052 character(len=32) :: index_str
1053 character(len=fm_type_name_len) :: fm_type
1054 integer :: i
1055 integer :: length
1056 
1057 nullify(array)
1058 
1059 !
1060 ! set the caller string and headers
1061 !
1062 
1063 if (present(caller)) then !{
1064  caller_str = '[' // trim(caller) // ']'
1065 else !}{
1066  caller_str = fm_util_default_caller
1067 endif !}
1068 
1069 error_header = '==>Error from ' // trim(mod_name) // &
1070  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
1071 warn_header = '==>Warning from ' // trim(mod_name) // &
1072  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
1073 note_header = '==>Note from ' // trim(mod_name) // &
1074  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
1075 
1076 !
1077 ! check that a name is given (fatal if not)
1078 !
1079 
1080 if (name .eq. ' ') then !{
1081  call mpp_error(fatal, trim(error_header) // ' Empty name given')
1082 endif !}
1083 
1084 fm_type = fm_get_type(name)
1085 if (fm_type .eq. 'string') then !{
1086  length = fm_get_length(name)
1087  if (length .lt. 0) then !{
1088  call mpp_error(fatal, trim(error_header) // ' Problem getting length of ' // trim(name))
1089  endif !}
1090  if (length .gt. 0) then !{
1091  allocate(array(length))
1092  do i = 1, length !{
1093  if (.not. fm_get_value(name, array(i), index = i)) then !{
1094  write (index_str,*) '(', i, ')'
1095  call mpp_error(fatal, trim(error_header) // ' Problem getting ' // trim(name) // trim(index_str))
1096  endif !}
1097  enddo !} i
1098  endif !}
1099 elseif (fm_type .eq. ' ') then !}{
1100  call mpp_error(fatal, trim(error_header) // ' Array does not exist: ' // trim(name))
1101 else !}{
1102  call mpp_error(fatal, trim(error_header) // ' Wrong type for ' // trim(name) // ', found (' // trim(fm_type) // ')')
1103 endif !}
1104 
1105 return
1106 
1107 end function fm_util_get_string_array !}
1108 
1109 !#######################################################################
1110 
1111 !> Get an integer value from the Field Manager tree.
1112 function fm_util_get_integer(name, caller, index, default_value, scalar) &
1113  result(ival) !{
1114 
1115 implicit none
1116 
1117 !
1118 ! Return type
1119 !
1120 
1121 integer :: ival
1122 
1123 !
1124 ! arguments
1125 !
1126 
1127 character(len=*), intent(in) :: name
1128 character(len=*), intent(in), optional :: caller
1129 integer, intent(in), optional :: index
1130 integer, intent(in), optional :: default_value
1131 logical, intent(in), optional :: scalar
1132 
1133 !
1134 ! Local parameters
1135 !
1136 
1137 character(len=48), parameter :: sub_name = 'fm_util_get_integer'
1138 
1139 !
1140 ! Local variables
1141 !
1142 
1143 character(len=256) :: error_header
1144 character(len=256) :: warn_header
1145 character(len=256) :: note_header
1146 character(len=128) :: caller_str
1147 integer :: index_t
1148 character(len=fm_type_name_len) :: fm_type
1149 integer :: field_length
1150 
1151 !
1152 ! set the caller string and headers
1153 !
1154 
1155 if (present(caller)) then !{
1156  caller_str = '[' // trim(caller) // ']'
1157 else !}{
1158  caller_str = fm_util_default_caller
1159 endif !}
1160 
1161 error_header = '==>Error from ' // trim(mod_name) // &
1162  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
1163 warn_header = '==>Warning from ' // trim(mod_name) // &
1164  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
1165 note_header = '==>Note from ' // trim(mod_name) // &
1166  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
1167 
1168 !
1169 ! check that a name is given (fatal if not)
1170 !
1171 
1172 if (name .eq. ' ') then !{
1173  call mpp_error(fatal, trim(error_header) // ' Empty name given')
1174 endif !}
1175 
1176 !
1177 ! Check whether we require a scalar (length=1) and return
1178 ! an error if we do, and it isn't
1179 !
1180 
1181 if (present(scalar)) then !{
1182  if (scalar) then !{
1183  field_length = fm_get_length(name)
1184  if (field_length .lt. 0) then !{
1185  call mpp_error(fatal, trim(error_header) // ' Problem getting length of ' // trim(name))
1186  elseif (field_length .gt. 1) then !}{
1187  call mpp_error(fatal, trim(error_header) // trim(name) // ' not scalar')
1188  endif !}
1189  endif !}
1190 endif !}
1191 
1192 !
1193 ! set the index
1194 !
1195 
1196 if (present(index)) then !{
1197  index_t = index
1198  if (index .le. 0) then !{
1199  call mpp_error(fatal, trim(error_header) // ' Index not positive')
1200  endif !}
1201 else !}{
1202  index_t = 1
1203 endif !}
1204 
1205 fm_type = fm_get_type(name)
1206 if (fm_type .eq. 'integer') then !{
1207  if (.not. fm_get_value(name, ival, index = index_t)) then !{
1208  call mpp_error(fatal, trim(error_header) // ' Problem getting ' // trim(name))
1209  endif !}
1210 elseif (fm_type .eq. ' ' .and. present(default_value)) then !}{
1211  ival = default_value
1212 elseif (fm_type .eq. ' ') then !}{
1213  call mpp_error(fatal, trim(error_header) // ' Field does not exist: ' // trim(name))
1214 else !}{
1215  call mpp_error(fatal, trim(error_header) // ' Wrong type for ' // trim(name) // ', found (' // trim(fm_type) // ')')
1216 endif !}
1217 
1218 return
1219 
1220 end function fm_util_get_integer !}
1221 
1222 !#######################################################################
1223 
1224 !> Get a logical value from the Field Manager tree.
1225 function fm_util_get_logical(name, caller, index, default_value, scalar) &
1226  result(lval) !{
1227 
1228 implicit none
1229 
1230 !
1231 ! Return type
1232 !
1233 
1234 logical :: lval
1235 
1236 !
1237 ! arguments
1238 !
1239 
1240 character(len=*), intent(in) :: name
1241 character(len=*), intent(in), optional :: caller
1242 integer, intent(in), optional :: index
1243 logical, intent(in), optional :: default_value
1244 logical, intent(in), optional :: scalar
1245 
1246 !
1247 ! Local parameters
1248 !
1249 
1250 character(len=48), parameter :: sub_name = 'fm_util_get_logical'
1251 
1252 !
1253 ! Local variables
1254 !
1255 
1256 character(len=256) :: error_header
1257 character(len=256) :: warn_header
1258 character(len=256) :: note_header
1259 character(len=128) :: caller_str
1260 integer :: index_t
1261 character(len=fm_type_name_len) :: fm_type
1262 integer :: field_length
1263 
1264 !
1265 ! set the caller string and headers
1266 !
1267 
1268 if (present(caller)) then !{
1269  caller_str = '[' // trim(caller) // ']'
1270 else !}{
1271  caller_str = fm_util_default_caller
1272 endif !}
1273 
1274 error_header = '==>Error from ' // trim(mod_name) // &
1275  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
1276 warn_header = '==>Warning from ' // trim(mod_name) // &
1277  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
1278 note_header = '==>Note from ' // trim(mod_name) // &
1279  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
1280 
1281 !
1282 ! check that a name is given (fatal if not)
1283 !
1284 
1285 if (name .eq. ' ') then !{
1286  call mpp_error(fatal, trim(error_header) // ' Empty name given')
1287 endif !}
1288 
1289 !
1290 ! Check whether we require a scalar (length=1) and return
1291 ! an error if we do, and it isn't
1292 !
1293 
1294 if (present(scalar)) then !{
1295  if (scalar) then !{
1296  field_length = fm_get_length(name)
1297  if (field_length .lt. 0) then !{
1298  call mpp_error(fatal, trim(error_header) // ' Problem getting length of ' // trim(name))
1299  elseif (field_length .gt. 1) then !}{
1300  call mpp_error(fatal, trim(error_header) // trim(name) // ' not scalar')
1301  endif !}
1302  endif !}
1303 endif !}
1304 
1305 !
1306 ! set the index
1307 !
1308 
1309 if (present(index)) then !{
1310  index_t = index
1311  if (index .le. 0) then !{
1312  call mpp_error(fatal, trim(error_header) // ' Index not positive')
1313  endif !}
1314 else !}{
1315  index_t = 1
1316 endif !}
1317 
1318 fm_type = fm_get_type(name)
1319 if (fm_type .eq. 'logical') then !{
1320  if (.not. fm_get_value(name, lval, index = index_t)) then !{
1321  call mpp_error(fatal, trim(error_header) // ' Problem getting ' // trim(name))
1322  endif !}
1323 elseif (fm_type .eq. ' ' .and. present(default_value)) then !}{
1324  lval = default_value
1325 elseif (fm_type .eq. ' ') then !}{
1326  call mpp_error(fatal, trim(error_header) // ' Field does not exist: ' // trim(name))
1327 else !}{
1328  call mpp_error(fatal, trim(error_header) // ' Wrong type for ' // trim(name) // ', found (' // trim(fm_type) // ')')
1329 endif !}
1330 
1331 return
1332 
1333 end function fm_util_get_logical !}
1334 
1335 !#######################################################################
1336 
1337 
1338 !> Get a real value from the Field Manager tree.
1339 function fm_util_get_real(name, caller, index, default_value, scalar) &
1340  result(rval) !{
1341 
1342 implicit none
1343 
1344 !
1345 ! Return type
1346 !
1347 
1348 real(r8_kind) :: rval
1349 
1350 !
1351 ! arguments
1352 !
1353 
1354 character(len=*), intent(in) :: name
1355 character(len=*), intent(in), optional :: caller
1356 integer, intent(in), optional :: index
1357 real(r8_kind), intent(in), optional :: default_value
1358 logical, intent(in), optional :: scalar
1359 
1360 !
1361 ! Local parameters
1362 !
1363 
1364 character(len=48), parameter :: sub_name = 'fm_util_get_real'
1365 
1366 !
1367 ! Local variables
1368 !
1369 
1370 character(len=256) :: error_header
1371 character(len=256) :: warn_header
1372 character(len=256) :: note_header
1373 character(len=128) :: caller_str
1374 integer :: index_t
1375 character(len=fm_type_name_len) :: fm_type
1376 integer :: field_length
1377 integer :: ivalue
1378 
1379 !
1380 ! set the caller string and headers
1381 !
1382 
1383 if (present(caller)) then !{
1384  caller_str = '[' // trim(caller) // ']'
1385 else !}{
1386  caller_str = fm_util_default_caller
1387 endif !}
1388 
1389 error_header = '==>Error from ' // trim(mod_name) // &
1390  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
1391 warn_header = '==>Warning from ' // trim(mod_name) // &
1392  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
1393 note_header = '==>Note from ' // trim(mod_name) // &
1394  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
1395 
1396 !
1397 ! check that a name is given (fatal if not)
1398 !
1399 
1400 if (name .eq. ' ') then !{
1401  call mpp_error(fatal, trim(error_header) // ' Empty name given')
1402 endif !}
1403 
1404 !
1405 ! Check whether we require a scalar (length=1) and return
1406 ! an error if we do, and it isn't
1407 !
1408 
1409 if (present(scalar)) then !{
1410  if (scalar) then !{
1411  field_length = fm_get_length(name)
1412  if (field_length .lt. 0) then !{
1413  call mpp_error(fatal, trim(error_header) // ' Problem getting length of ' // trim(name))
1414  elseif (field_length .gt. 1) then !}{
1415  call mpp_error(fatal, trim(error_header) // trim(name) // ' not scalar')
1416  endif !}
1417  endif !}
1418 endif !}
1419 
1420 !
1421 ! set the index
1422 !
1423 
1424 if (present(index)) then !{
1425  index_t = index
1426  if (index .le. 0) then !{
1427  call mpp_error(fatal, trim(error_header) // ' Index not positive')
1428  endif !}
1429 else !}{
1430  index_t = 1
1431 endif !}
1432 
1433 fm_type = fm_get_type(name)
1434 if (fm_type .eq. 'real') then !{
1435  if (.not. fm_get_value(name, rval, index = index_t)) then !{
1436  call mpp_error(fatal, trim(error_header) // ' Problem getting ' // trim(name))
1437  endif !}
1438 else if (fm_type .eq. 'integer') then
1439  if (.not. fm_get_value(name, ivalue, index = index_t)) then
1440  call mpp_error(fatal, trim(error_header) // ' Problem getting ' // trim(name))
1441  endif
1442  rval = real(ivalue,r8_kind)
1443 elseif (fm_type .eq. ' ' .and. present(default_value)) then !}{
1444  rval = default_value
1445 elseif (fm_type .eq. ' ') then !}{
1446  call mpp_error(fatal, trim(error_header) // ' Field does not exist: ' // trim(name))
1447 else !}{
1448  call mpp_error(fatal, trim(error_header) // ' Wrong type for ' // trim(name) // ', found (' // trim(fm_type) // ')')
1449 endif !}
1450 
1451 return
1452 
1453 end function fm_util_get_real !}
1454 
1455 
1456 !#######################################################################
1457 
1458 
1459 !> Get a string value from the Field Manager tree.
1460 function fm_util_get_string(name, caller, index, default_value, scalar) &
1461  result(sval) !{
1462 
1463 implicit none
1464 
1465 !
1466 ! Return type
1467 !
1468 
1469 character(len=fm_string_len) :: sval
1470 
1471 !
1472 ! arguments
1473 !
1474 
1475 character(len=*), intent(in) :: name
1476 character(len=*), intent(in), optional :: caller
1477 integer, intent(in), optional :: index
1478 character(len=*), intent(in), optional :: default_value
1479 logical, intent(in), optional :: scalar
1480 
1481 !
1482 ! Local parameters
1483 !
1484 
1485 character(len=48), parameter :: sub_name = 'fm_util_get_string'
1486 
1487 !
1488 ! Local variables
1489 !
1490 
1491 character(len=256) :: error_header
1492 character(len=256) :: warn_header
1493 character(len=256) :: note_header
1494 character(len=128) :: caller_str
1495 integer :: index_t
1496 character(len=fm_type_name_len) :: fm_type
1497 integer :: field_length
1498 
1499 !
1500 ! set the caller string and headers
1501 !
1502 
1503 if (present(caller)) then !{
1504  caller_str = '[' // trim(caller) // ']'
1505 else !}{
1506  caller_str = fm_util_default_caller
1507 endif !}
1508 
1509 error_header = '==>Error from ' // trim(mod_name) // &
1510  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
1511 warn_header = '==>Warning from ' // trim(mod_name) // &
1512  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
1513 note_header = '==>Note from ' // trim(mod_name) // &
1514  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
1515 
1516 !
1517 ! check that a name is given (fatal if not)
1518 !
1519 
1520 if (name .eq. ' ') then !{
1521  call mpp_error(fatal, trim(error_header) // ' Empty name given')
1522 endif !}
1523 
1524 !
1525 ! Check whether we require a scalar (length=1) and return
1526 ! an error if we do, and it isn't
1527 !
1528 
1529 if (present(scalar)) then !{
1530  if (scalar) then !{
1531  field_length = fm_get_length(name)
1532  if (field_length .lt. 0) then !{
1533  call mpp_error(fatal, trim(error_header) // ' Problem getting length of ' // trim(name))
1534  elseif (field_length .gt. 1) then !}{
1535  call mpp_error(fatal, trim(error_header) // trim(name) // ' not scalar')
1536  endif !}
1537  endif !}
1538 endif !}
1539 
1540 !
1541 ! set the index
1542 !
1543 
1544 if (present(index)) then !{
1545  index_t = index
1546  if (index .le. 0) then !{
1547  call mpp_error(fatal, trim(error_header) // ' Index not positive')
1548  endif !}
1549 else !}{
1550  index_t = 1
1551 endif !}
1552 
1553 fm_type = fm_get_type(name)
1554 if (fm_type .eq. 'string') then !{
1555  if (.not. fm_get_value(name, sval, index = index_t)) then !{
1556  call mpp_error(fatal, trim(error_header) // ' Problem getting ' // trim(name))
1557  endif !}
1558 elseif (fm_type .eq. ' ' .and. present(default_value)) then !}{
1559  sval = default_value
1560 elseif (fm_type .eq. ' ') then !}{
1561  call mpp_error(fatal, trim(error_header) // ' Field does not exist: ' // trim(name))
1562 else !}{
1563  call mpp_error(fatal, trim(error_header) // ' Wrong type for ' // trim(name) // ', found (' // trim(fm_type) // ')')
1564 endif !}
1565 
1566 return
1567 
1568 end function fm_util_get_string !}
1569 
1570 !#######################################################################
1571 
1572 !> Set an integer array in the Field Manager tree.
1573 subroutine fm_util_set_value_integer_array(name, ival, length, caller, no_overwrite, good_name_list) !{
1574 
1575 implicit none
1576 
1577 !
1578 ! arguments
1579 !
1580 
1581 character(len=*), intent(in) :: name
1582 integer, intent(in) :: length
1583 integer, intent(in) :: ival(length)
1584 character(len=*), intent(in), optional :: caller
1585 logical, intent(in), optional :: no_overwrite
1586 character(len=*), intent(in), optional :: good_name_list
1587 
1588 !
1589 ! Local parameters
1590 !
1591 
1592 character(len=48), parameter :: sub_name = 'fm_util_set_value_integer_array'
1593 
1594 !
1595 ! Local variables
1596 !
1597 
1598 character(len=256) :: error_header
1599 character(len=256) :: warn_header
1600 character(len=256) :: note_header
1601 character(len=128) :: caller_str
1602 character(len=32) :: str_error
1603 integer :: field_index
1604 integer :: field_length
1605 integer :: n
1606 logical :: no_overwrite_use
1607 character(len=FMS_PATH_LEN) :: good_name_list_use
1608 logical :: add_name
1609 
1610 !
1611 ! set the caller string and headers
1612 !
1613 
1614 if (present(caller)) then !{
1615  caller_str = '[' // trim(caller) // ']'
1616 else !}{
1617  caller_str = fm_util_default_caller
1618 endif !}
1619 
1620 error_header = '==>Error from ' // trim(mod_name) // &
1621  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
1622 warn_header = '==>Warning from ' // trim(mod_name) // &
1623  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
1624 note_header = '==>Note from ' // trim(mod_name) // &
1625  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
1626 
1627 !
1628 ! check that a name is given (fatal if not)
1629 !
1630 
1631 if (name .eq. ' ') then !{
1632  call mpp_error(fatal, trim(error_header) // ' Empty name given')
1633 endif !}
1634 
1635 !
1636 ! check that the length is non-negative
1637 !
1638 
1639 if (length .lt. 0) then !{
1640  call mpp_error(fatal, trim(error_header) // ' Negative array length')
1641 endif !}
1642 
1643 !
1644 ! check for whether to overwrite existing values
1645 !
1646 
1647 if (present(no_overwrite)) then !{
1648  no_overwrite_use = no_overwrite
1649 else !}{
1650  no_overwrite_use = default_no_overwrite
1651 endif !}
1652 
1653 !
1654 ! check for whether to save the name in a list
1655 !
1656 
1657 if (present(good_name_list)) then !{
1658  good_name_list_use = good_name_list
1659 else !}{
1660  good_name_list_use = default_good_name_list
1661 endif !}
1662 
1663 !
1664 ! write the data array
1665 !
1666 
1667 if (length .eq. 0) then !{
1668  if (.not. (no_overwrite_use .and. fm_exists(name))) then !{
1669  field_index = fm_new_value(name, 0, index = 0)
1670  if (field_index .le. 0) then !{
1671  write (str_error,*) ' with length = ', length
1672  call mpp_error(fatal, trim(error_header) // ' Problem setting ' // trim(name) // trim(str_error))
1673  endif !}
1674  endif !}
1675 else !}{
1676  if (no_overwrite_use .and. fm_exists(name)) then !{
1677  field_length = fm_get_length(name)
1678  if (field_length .lt. 0) then !{
1679  call mpp_error(fatal, trim(error_header) // ' Problem getting length of ' // trim(name))
1680  endif !}
1681  do n = field_length + 1, length !{
1682  field_index = fm_new_value(name, ival(n), index = n)
1683  if (field_index .le. 0) then !{
1684  write (str_error,*) ' with index = ', n
1685  call mpp_error(fatal, trim(error_header) // ' Problem setting ' // trim(name) // trim(str_error))
1686  endif !}
1687  enddo !} n
1688  else !}{
1689  field_index = fm_new_value(name, ival(1))
1690  if (field_index .le. 0) then !{
1691  call mpp_error(fatal, trim(error_header) // ' Problem setting ' // trim(name))
1692  endif !}
1693  do n = 2, length !{
1694  field_index = fm_new_value(name, ival(n), index = n)
1695  if (field_index .le. 0) then !{
1696  write (str_error,*) ' with index = ', n
1697  call mpp_error(fatal, trim(error_header) // ' Problem setting ' // trim(name) // trim(str_error))
1698  endif !}
1699  enddo !} n
1700  endif !}
1701 endif !}
1702 
1703 !
1704 ! Add the variable name to the list of good names, to be used
1705 ! later for a consistency check
1706 !
1707 
1708 if (good_name_list_use .ne. ' ') then !{
1709  if (fm_exists(good_name_list_use)) then !{
1710  add_name = fm_util_get_index_string(good_name_list_use, name, &
1711  caller = caller_str) .le. 0 ! true if name does not exist in string array
1712  else !}{
1713  add_name = .true. ! always add to new list
1714  endif !}
1715  if (add_name .and. fm_exists(name)) then !{
1716  if (fm_new_value(good_name_list_use, name, append = .true., create = .true.) .le. 0) then !{
1717  call mpp_error(fatal, trim(error_header) // &
1718  ' Could not add ' // trim(name) // ' to "' // trim(good_name_list_use) // '" list')
1719  endif !}
1720  endif !}
1721 endif !}
1722 
1723 return
1724 
1725 end subroutine fm_util_set_value_integer_array !}
1726 
1727 !#######################################################################
1728 
1729 !> Set a logical array in the Field Manager tree.
1730 subroutine fm_util_set_value_logical_array(name, lval, length, caller, no_overwrite, good_name_list) !{
1731 
1732 implicit none
1733 
1734 !
1735 ! arguments
1736 !
1737 
1738 character(len=*), intent(in) :: name
1739 integer, intent(in) :: length
1740 logical, intent(in) :: lval(length)
1741 character(len=*), intent(in), optional :: caller
1742 logical, intent(in), optional :: no_overwrite
1743 character(len=*), intent(in), optional :: good_name_list
1744 
1745 !
1746 ! Local parameters
1747 !
1748 
1749 character(len=48), parameter :: sub_name = 'fm_util_set_value_logical_array'
1750 
1751 !
1752 ! Local variables
1753 !
1754 
1755 character(len=256) :: error_header
1756 character(len=256) :: warn_header
1757 character(len=256) :: note_header
1758 character(len=128) :: caller_str
1759 character(len=32) :: str_error
1760 integer :: field_index
1761 integer :: field_length
1762 integer :: n
1763 logical :: no_overwrite_use
1764 character(len=FMS_PATH_LEN) :: good_name_list_use
1765 logical :: add_name
1766 
1767 !
1768 ! set the caller string and headers
1769 !
1770 
1771 if (present(caller)) then !{
1772  caller_str = '[' // trim(caller) // ']'
1773 else !}{
1774  caller_str = fm_util_default_caller
1775 endif !}
1776 
1777 error_header = '==>Error from ' // trim(mod_name) // &
1778  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
1779 warn_header = '==>Warning from ' // trim(mod_name) // &
1780  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
1781 note_header = '==>Note from ' // trim(mod_name) // &
1782  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
1783 
1784 !
1785 ! check that a name is given (fatal if not)
1786 !
1787 
1788 if (name .eq. ' ') then !{
1789  call mpp_error(fatal, trim(error_header) // ' Empty name given')
1790 endif !}
1791 
1792 !
1793 ! check that the length is non-negative
1794 !
1795 
1796 if (length .lt. 0) then !{
1797  call mpp_error(fatal, trim(error_header) // ' Negative array length')
1798 endif !}
1799 
1800 !
1801 ! check for whether to overwrite existing values
1802 !
1803 
1804 if (present(no_overwrite)) then !{
1805  no_overwrite_use = no_overwrite
1806 else !}{
1807  no_overwrite_use = default_no_overwrite
1808 endif !}
1809 
1810 !
1811 ! check for whether to save the name in a list
1812 !
1813 
1814 if (present(good_name_list)) then !{
1815  good_name_list_use = good_name_list
1816 else !}{
1817  good_name_list_use = default_good_name_list
1818 endif !}
1819 
1820 !
1821 ! write the data array
1822 !
1823 
1824 if (length .eq. 0) then !{
1825  if (.not. (no_overwrite_use .and. fm_exists(name))) then !{
1826  field_index = fm_new_value(name, .false., index = 0)
1827  if (field_index .le. 0) then !{
1828  write (str_error,*) ' with length = ', length
1829  call mpp_error(fatal, trim(error_header) // ' Problem setting ' // trim(name) // trim(str_error))
1830  endif !}
1831  endif !}
1832 else !}{
1833  if (no_overwrite_use .and. fm_exists(name)) then !{
1834  field_length = fm_get_length(name)
1835  if (field_length .lt. 0) then !{
1836  call mpp_error(fatal, trim(error_header) // ' Problem getting length of ' // trim(name))
1837  endif !}
1838  do n = field_length + 1, length !{
1839  field_index = fm_new_value(name, lval(n), index = n)
1840  if (field_index .le. 0) then !{
1841  write (str_error,*) ' with index = ', n
1842  call mpp_error(fatal, trim(error_header) // ' Problem setting ' // trim(name) // trim(str_error))
1843  endif !}
1844  enddo !} n
1845  else !}{
1846  field_index = fm_new_value(name, lval(1))
1847  if (field_index .le. 0) then !{
1848  call mpp_error(fatal, trim(error_header) // ' Problem setting ' // trim(name))
1849  endif !}
1850  do n = 2, length !{
1851  field_index = fm_new_value(name, lval(n), index = n)
1852  if (field_index .le. 0) then !{
1853  write (str_error,*) ' with index = ', n
1854  call mpp_error(fatal, trim(error_header) // ' Problem setting ' // trim(name) // trim(str_error))
1855  endif !}
1856  enddo !} n
1857  endif !}
1858 endif !}
1859 
1860 !
1861 ! Add the variable name to the list of good names, to be used
1862 ! later for a consistency check
1863 !
1864 
1865 if (good_name_list_use .ne. ' ') then !{
1866  if (fm_exists(good_name_list_use)) then !{
1867  add_name = fm_util_get_index_string(good_name_list_use, name, &
1868  caller = caller_str) .le. 0 ! true if name does not exist in string array
1869  else !}{
1870  add_name = .true. ! always add to new list
1871  endif !}
1872  if (add_name .and. fm_exists(name)) then !{
1873  if (fm_new_value(good_name_list_use, name, append = .true., create = .true.) .le. 0) then !{
1874  call mpp_error(fatal, trim(error_header) // &
1875  ' Could not add ' // trim(name) // ' to "' // trim(good_name_list_use) // '" list')
1876  endif !}
1877  endif !}
1878 endif !}
1879 
1880 return
1881 
1882 end subroutine fm_util_set_value_logical_array !}
1883 
1884 !#######################################################################
1885 
1886 !> Set a string array in the Field Manager tree.
1887 subroutine fm_util_set_value_string_array(name, sval, length, caller, no_overwrite, good_name_list) !{
1888 
1889 implicit none
1890 
1891 !
1892 ! arguments
1893 !
1894 
1895 character(len=*), intent(in) :: name
1896 integer, intent(in) :: length
1897 character(len=*), intent(in) :: sval(length)
1898 character(len=*), intent(in), optional :: caller
1899 logical, intent(in), optional :: no_overwrite
1900 character(len=*), intent(in), optional :: good_name_list
1901 
1902 !
1903 ! Local parameters
1904 !
1905 
1906 character(len=48), parameter :: sub_name = 'fm_util_set_value_string_array'
1907 
1908 !
1909 ! Local variables
1910 !
1911 
1912 character(len=256) :: error_header
1913 character(len=256) :: warn_header
1914 character(len=256) :: note_header
1915 character(len=128) :: caller_str
1916 character(len=32) :: str_error
1917 integer :: field_index
1918 integer :: field_length
1919 integer :: n
1920 logical :: no_overwrite_use
1921 character(len=FMS_PATH_LEN) :: good_name_list_use
1922 logical :: add_name
1923 
1924 !
1925 ! set the caller string and headers
1926 !
1927 
1928 if (present(caller)) then !{
1929  caller_str = '[' // trim(caller) // ']'
1930 else !}{
1931  caller_str = fm_util_default_caller
1932 endif !}
1933 
1934 error_header = '==>Error from ' // trim(mod_name) // &
1935  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
1936 warn_header = '==>Warning from ' // trim(mod_name) // &
1937  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
1938 note_header = '==>Note from ' // trim(mod_name) // &
1939  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
1940 
1941 !
1942 ! check that a name is given (fatal if not)
1943 !
1944 
1945 if (name .eq. ' ') then !{
1946  call mpp_error(fatal, trim(error_header) // ' Empty name given')
1947 endif !}
1948 
1949 !
1950 ! check that the length is non-negative
1951 !
1952 
1953 if (length .lt. 0) then !{
1954  call mpp_error(fatal, trim(error_header) // ' Negative array length')
1955 endif !}
1956 
1957 !
1958 ! check for whether to overwrite existing values
1959 !
1960 
1961 if (present(no_overwrite)) then !{
1962  no_overwrite_use = no_overwrite
1963 else !}{
1964  no_overwrite_use = default_no_overwrite
1965 endif !}
1966 
1967 !
1968 ! check for whether to save the name in a list
1969 !
1970 
1971 if (present(good_name_list)) then !{
1972  good_name_list_use = good_name_list
1973 else !}{
1974  good_name_list_use = default_good_name_list
1975 endif !}
1976 
1977 !
1978 ! write the data array
1979 !
1980 
1981 if (length .eq. 0) then !{
1982  if (.not. (no_overwrite_use .and. fm_exists(name))) then !{
1983  field_index = fm_new_value(name, ' ', index = 0)
1984  if (field_index .le. 0) then !{
1985  write (str_error,*) ' with length = ', length
1986  call mpp_error(fatal, trim(error_header) // ' Problem setting ' // trim(name) // trim(str_error))
1987  endif !}
1988  endif !}
1989 else !}{
1990  if (no_overwrite_use .and. fm_exists(name)) then !{
1991  field_length = fm_get_length(name)
1992  if (field_length .lt. 0) then !{
1993  call mpp_error(fatal, trim(error_header) // ' Problem getting length of ' // trim(name))
1994  endif !}
1995  do n = field_length + 1, length !{
1996  field_index = fm_new_value(name, sval(n), index = n)
1997  if (field_index .le. 0) then !{
1998  write (str_error,*) ' with index = ', n
1999  call mpp_error(fatal, trim(error_header) // ' Problem setting ' // trim(name) // trim(str_error))
2000  endif !}
2001  enddo !} n
2002  else !}{
2003  field_index = fm_new_value(name, sval(1))
2004  if (field_index .le. 0) then !{
2005  call mpp_error(fatal, trim(error_header) // ' Problem setting ' // trim(name))
2006  endif !}
2007  do n = 2, length !{
2008  field_index = fm_new_value(name, sval(n), index = n)
2009  if (field_index .le. 0) then !{
2010  write (str_error,*) ' with index = ', n
2011  call mpp_error(fatal, trim(error_header) // ' Problem setting ' // trim(name) // trim(str_error))
2012  endif !}
2013  enddo !} n
2014  endif !}
2015 endif !}
2016 
2017 !
2018 ! Add the variable name to the list of good names, to be used
2019 ! later for a consistency check
2020 !
2021 
2022 if (good_name_list_use .ne. ' ') then !{
2023  if (fm_exists(good_name_list_use)) then !{
2024  add_name = fm_util_get_index_string(good_name_list_use, name, &
2025  caller = caller_str) .le. 0 ! true if name does not exist in string array
2026  else !}{
2027  add_name = .true. ! always add to new list
2028  endif !}
2029  if (add_name .and. fm_exists(name)) then !{
2030  if (fm_new_value(good_name_list_use, name, append = .true., create = .true.) .le. 0) then !{
2031  call mpp_error(fatal, trim(error_header) // &
2032  ' Could not add ' // trim(name) // ' to "' // trim(good_name_list_use) // '" list')
2033  endif !}
2034  endif !}
2035 endif !}
2036 
2037 return
2038 
2039 end subroutine fm_util_set_value_string_array !}
2040 
2041 !#######################################################################
2042 
2043 !> Set an integer value in the Field Manager tree.
2044 subroutine fm_util_set_value_integer(name, ival, caller, index, append, no_create, &
2045  no_overwrite, good_name_list) !{
2046 
2047 implicit none
2048 
2049 !
2050 ! arguments
2051 !
2052 
2053 character(len=*), intent(in) :: name
2054 integer, intent(in) :: ival
2055 character(len=*), intent(in), optional :: caller
2056 integer, intent(in), optional :: index
2057 logical, intent(in), optional :: append
2058 logical, intent(in), optional :: no_create
2059 logical, intent(in), optional :: no_overwrite
2060 character(len=*), intent(in), optional :: good_name_list
2061 
2062 !
2063 ! Local parameters
2064 !
2065 
2066 character(len=48), parameter :: sub_name = 'fm_util_set_value_integer'
2067 
2068 !
2069 ! Local variables
2070 !
2071 
2072 character(len=256) :: error_header
2073 character(len=256) :: warn_header
2074 character(len=256) :: note_header
2075 character(len=128) :: caller_str
2076 character(len=32) :: str_error
2077 integer :: field_index
2078 logical :: no_overwrite_use
2079 integer :: field_length
2080 character(len=FMS_PATH_LEN) :: good_name_list_use
2081 logical :: create
2082 logical :: add_name
2083 
2084 !
2085 ! set the caller string and headers
2086 !
2087 
2088 if (present(caller)) then !{
2089  caller_str = '[' // trim(caller) // ']'
2090 else !}{
2091  caller_str = fm_util_default_caller
2092 endif !}
2093 
2094 error_header = '==>Error from ' // trim(mod_name) // &
2095  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
2096 warn_header = '==>Warning from ' // trim(mod_name) // &
2097  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
2098 note_header = '==>Note from ' // trim(mod_name) // &
2099  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
2100 
2101 !
2102 ! check that a name is given (fatal if not)
2103 !
2104 
2105 if (name .eq. ' ') then !{
2106  call mpp_error(fatal, trim(error_header) // ' Empty name given')
2107 endif !}
2108 
2109 !
2110 ! check that append and index are not both given
2111 !
2112 
2113 if (present(index) .and. present(append)) then !{
2114  call mpp_error(fatal, trim(error_header) // ' Append and index both given as arguments')
2115 endif !}
2116 
2117 !
2118 ! check for whether to overwrite existing values
2119 !
2120 
2121 if (present(no_overwrite)) then !{
2122  no_overwrite_use = no_overwrite
2123 else !}{
2124  no_overwrite_use = default_no_overwrite
2125 endif !}
2126 
2127 !
2128 ! check for whether to save the name in a list
2129 !
2130 
2131 if (present(good_name_list)) then !{
2132  good_name_list_use = good_name_list
2133 else !}{
2134  good_name_list_use = default_good_name_list
2135 endif !}
2136 
2137 if (present(no_create)) then !{
2138  create = .not. no_create
2139  if (no_create .and. (present(append) .or. present(index))) then !{
2140  call mpp_error(fatal, trim(error_header) // &
2141  & ' append or index are present when no_create is true for ' // trim(name))
2142  endif !}
2143 else !}{
2144  create = .true.
2145 endif !}
2146 
2147 if (present(index)) then !{
2148  if (fm_exists(name)) then !{
2149  field_length = fm_get_length(name)
2150  if (field_length .lt. 0) then !{
2151  call mpp_error(fatal, trim(error_header) // ' Problem getting length of ' // trim(name))
2152  endif !}
2153  if (.not. (no_overwrite_use .and. field_length .ge. index)) then !{
2154  field_index = fm_new_value(name, ival, index = index)
2155  if (field_index .le. 0) then !{
2156  write (str_error,*) ' with index = ', index
2157  call mpp_error(fatal, trim(error_header) // ' Problem overwriting ' // trim(name) // trim(str_error))
2158  endif !}
2159  endif !}
2160  else !}{
2161  field_index = fm_new_value(name, ival, index = index)
2162  if (field_index .le. 0) then !{
2163  write (str_error,*) ' with index = ', index
2164  call mpp_error(fatal, trim(error_header) // ' Problem setting ' // trim(name) // trim(str_error))
2165  endif !}
2166  endif !}
2167 elseif (present(append)) then !}{
2168  field_index = fm_new_value(name, ival, append = append)
2169  if (field_index .le. 0) then !{
2170  write (str_error,*) ' with append = ', append
2171  call mpp_error(fatal, trim(error_header) // ' Problem setting ' // trim(name) // trim(str_error))
2172  endif !}
2173 else !}{
2174  if (fm_exists(name)) then !{
2175  if (.not. no_overwrite_use) then !{
2176  field_index = fm_new_value(name, ival)
2177  if (field_index .le. 0) then !{
2178  call mpp_error(fatal, trim(error_header) // ' Problem overwriting ' // trim(name))
2179  endif !}
2180  endif !}
2181  elseif (create) then !}{
2182  field_index = fm_new_value(name, ival)
2183  if (field_index .le. 0) then !{
2184  call mpp_error(fatal, trim(error_header) // ' Problem creating ' // trim(name))
2185  endif !}
2186  endif !}
2187 endif !}
2188 
2189 !
2190 ! Add the variable name to the list of good names, to be used
2191 ! later for a consistency check, unless the field did not exist and we did not create it
2192 !
2193 
2194 if (good_name_list_use .ne. ' ') then !{
2195  if (fm_exists(good_name_list_use)) then !{
2196  add_name = fm_util_get_index_string(good_name_list_use, name, &
2197  caller = caller_str) .le. 0 ! true if name does not exist in string array
2198  else !}{
2199  add_name = .true. ! always add to new list
2200  endif !}
2201  if (add_name .and. fm_exists(name)) then !{
2202  if (fm_new_value(good_name_list_use, name, append = .true., create = .true.) .le. 0) then !{
2203  call mpp_error(fatal, trim(error_header) // &
2204  ' Could not add ' // trim(name) // ' to "' // trim(good_name_list_use) // '" list')
2205  endif !}
2206  endif !}
2207 endif !}
2208 
2209 return
2210 
2211 end subroutine fm_util_set_value_integer !}
2212 
2213 !#######################################################################
2214 
2215 !> Set a logical value in the Field Manager tree.
2216 subroutine fm_util_set_value_logical(name, lval, caller, index, append, no_create, &
2217  no_overwrite, good_name_list) !{
2218 
2219 implicit none
2220 
2221 !
2222 ! arguments
2223 !
2224 
2225 character(len=*), intent(in) :: name
2226 logical, intent(in) :: lval
2227 character(len=*), intent(in), optional :: caller
2228 integer, intent(in), optional :: index
2229 logical, intent(in), optional :: append
2230 logical, intent(in), optional :: no_create
2231 logical, intent(in), optional :: no_overwrite
2232 character(len=*), intent(in), optional :: good_name_list
2233 
2234 !
2235 ! Local parameters
2236 !
2237 
2238 character(len=48), parameter :: sub_name = 'fm_util_set_value_logical'
2239 
2240 !
2241 ! Local variables
2242 !
2243 
2244 character(len=256) :: error_header
2245 character(len=256) :: warn_header
2246 character(len=256) :: note_header
2247 character(len=128) :: caller_str
2248 character(len=32) :: str_error
2249 integer :: field_index
2250 logical :: no_overwrite_use
2251 integer :: field_length
2252 character(len=FMS_PATH_LEN) :: good_name_list_use
2253 logical :: create
2254 logical :: add_name
2255 
2256 !
2257 ! set the caller string and headers
2258 !
2259 
2260 if (present(caller)) then !{
2261  caller_str = '[' // trim(caller) // ']'
2262 else !}{
2263  caller_str = fm_util_default_caller
2264 endif !}
2265 
2266 error_header = '==>Error from ' // trim(mod_name) // &
2267  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
2268 warn_header = '==>Warning from ' // trim(mod_name) // &
2269  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
2270 note_header = '==>Note from ' // trim(mod_name) // &
2271  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
2272 
2273 !
2274 ! check that a name is given (fatal if not)
2275 !
2276 
2277 if (name .eq. ' ') then !{
2278  call mpp_error(fatal, trim(error_header) // ' Empty name given')
2279 endif !}
2280 
2281 !
2282 ! check that append and index are not both given
2283 !
2284 
2285 if (present(index) .and. present(append)) then !{
2286  call mpp_error(fatal, trim(error_header) // ' Append and index both given as arguments')
2287 endif !}
2288 
2289 !
2290 ! check for whether to overwrite existing values
2291 !
2292 
2293 if (present(no_overwrite)) then !{
2294  no_overwrite_use = no_overwrite
2295 else !}{
2296  no_overwrite_use = default_no_overwrite
2297 endif !}
2298 
2299 !
2300 ! check for whether to save the name in a list
2301 !
2302 
2303 if (present(good_name_list)) then !{
2304  good_name_list_use = good_name_list
2305 else !}{
2306  good_name_list_use = default_good_name_list
2307 endif !}
2308 
2309 if (present(no_create)) then !{
2310  create = .not. no_create
2311  if (no_create .and. (present(append) .or. present(index))) then !{
2312  call mpp_error(fatal, trim(error_header) // &
2313  & ' append or index are present when no_create is true for ' // trim(name))
2314  endif !}
2315 else !}{
2316  create = .true.
2317 endif !}
2318 
2319 if (present(index)) then !{
2320  if (fm_exists(name)) then !{
2321  field_length = fm_get_length(name)
2322  if (field_length .lt. 0) then !{
2323  call mpp_error(fatal, trim(error_header) // ' Problem getting length of ' // trim(name))
2324  endif !}
2325  if (.not. (no_overwrite_use .and. field_length .ge. index)) then !{
2326  field_index = fm_new_value(name, lval, index = index)
2327  if (field_index .le. 0) then !{
2328  write (str_error,*) ' with index = ', index
2329  call mpp_error(fatal, trim(error_header) // ' Problem overwriting ' // trim(name) // trim(str_error))
2330  endif !}
2331  endif !}
2332  else !}{
2333  field_index = fm_new_value(name, lval, index = index)
2334  if (field_index .le. 0) then !{
2335  write (str_error,*) ' with index = ', index
2336  call mpp_error(fatal, trim(error_header) // ' Problem setting ' // trim(name) // trim(str_error))
2337  endif !}
2338  endif !}
2339 elseif (present(append)) then !}{
2340  field_index = fm_new_value(name, lval, append = append)
2341  if (field_index .le. 0) then !{
2342  write (str_error,*) ' with append = ', append
2343  call mpp_error(fatal, trim(error_header) // ' Problem setting ' // trim(name) // trim(str_error))
2344  endif !}
2345 else !}{
2346  if (fm_exists(name)) then !{
2347  if (.not. no_overwrite_use) then !{
2348  field_index = fm_new_value(name, lval)
2349  if (field_index .le. 0) then !{
2350  call mpp_error(fatal, trim(error_header) // ' Problem overwriting ' // trim(name))
2351  endif !}
2352  endif !}
2353  elseif (create) then !}{
2354  field_index = fm_new_value(name, lval)
2355  if (field_index .le. 0) then !{
2356  call mpp_error(fatal, trim(error_header) // ' Problem creating ' // trim(name))
2357  endif !}
2358  endif !}
2359 endif !}
2360 
2361 !
2362 ! Add the variable name to the list of good names, to be used
2363 ! later for a consistency check, unless the field did not exist and we did not create it
2364 !
2365 
2366 if (good_name_list_use .ne. ' ') then !{
2367  if (fm_exists(good_name_list_use)) then !{
2368  add_name = fm_util_get_index_string(good_name_list_use, name, &
2369  caller = caller_str) .le. 0 ! true if name does not exist in string array
2370  else !}{
2371  add_name = .true. ! always add to new list
2372  endif !}
2373  if (add_name .and. fm_exists(name)) then !{
2374  if (fm_new_value(good_name_list_use, name, append = .true., create = .true.) .le. 0) then !{
2375  call mpp_error(fatal, trim(error_header) // &
2376  ' Could not add ' // trim(name) // ' to "' // trim(good_name_list_use) // '" list')
2377  endif !}
2378  endif !}
2379 endif !}
2380 
2381 return
2382 
2383 end subroutine fm_util_set_value_logical !}
2384 
2385 !#######################################################################
2386 !> Set a string value in the Field Manager tree.
2387 subroutine fm_util_set_value_string(name, sval, caller, index, append, no_create, &
2388  no_overwrite, good_name_list) !{
2389 
2390 implicit none
2391 
2392 !
2393 ! arguments
2394 !
2395 
2396 character(len=*), intent(in) :: name
2397 character(len=*), intent(in) :: sval
2398 character(len=*), intent(in), optional :: caller
2399 integer, intent(in), optional :: index
2400 logical, intent(in), optional :: append
2401 logical, intent(in), optional :: no_create
2402 logical, intent(in), optional :: no_overwrite
2403 character(len=*), intent(in), optional :: good_name_list
2404 
2405 !
2406 ! Local parameters
2407 !
2408 
2409 character(len=48), parameter :: sub_name = 'fm_util_set_value_string'
2410 
2411 !
2412 ! Local variables
2413 !
2414 
2415 character(len=256) :: error_header
2416 character(len=256) :: warn_header
2417 character(len=256) :: note_header
2418 character(len=128) :: caller_str
2419 character(len=32) :: str_error
2420 integer :: field_index
2421 logical :: no_overwrite_use
2422 integer :: field_length
2423 character(len=FMS_PATH_LEN) :: good_name_list_use
2424 logical :: create
2425 logical :: add_name
2426 
2427 !
2428 ! set the caller string and headers
2429 !
2430 
2431 if (present(caller)) then !{
2432  caller_str = '[' // trim(caller) // ']'
2433 else !}{
2434  caller_str = fm_util_default_caller
2435 endif !}
2436 
2437 error_header = '==>Error from ' // trim(mod_name) // &
2438  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
2439 warn_header = '==>Warning from ' // trim(mod_name) // &
2440  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
2441 note_header = '==>Note from ' // trim(mod_name) // &
2442  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
2443 
2444 !
2445 ! check that a name is given (fatal if not)
2446 !
2447 
2448 if (name .eq. ' ') then !{
2449  call mpp_error(fatal, trim(error_header) // ' Empty name given')
2450 endif !}
2451 
2452 !
2453 ! check that append and index are not both given
2454 !
2455 
2456 if (present(index) .and. present(append)) then !{
2457  call mpp_error(fatal, trim(error_header) // ' Append and index both given as arguments')
2458 endif !}
2459 
2460 !
2461 ! check for whether to overwrite existing values
2462 !
2463 
2464 if (present(no_overwrite)) then !{
2465  no_overwrite_use = no_overwrite
2466 else !}{
2467  no_overwrite_use = default_no_overwrite
2468 endif !}
2469 
2470 !
2471 ! check for whether to save the name in a list
2472 !
2473 
2474 if (present(good_name_list)) then !{
2475  good_name_list_use = good_name_list
2476 else !}{
2477  good_name_list_use = default_good_name_list
2478 endif !}
2479 
2480 if (present(no_create)) then !{
2481  create = .not. no_create
2482  if (no_create .and. (present(append) .or. present(index))) then !{
2483  call mpp_error(fatal, trim(error_header) // &
2484  & ' append or index are present when no_create is true for ' // trim(name))
2485  endif !}
2486 else !}{
2487  create = .true.
2488 endif !}
2489 
2490 if (present(index)) then !{
2491  if (fm_exists(name)) then !{
2492  field_length = fm_get_length(name)
2493  if (field_length .lt. 0) then !{
2494  call mpp_error(fatal, trim(error_header) // ' Problem getting length of ' // trim(name))
2495  endif !}
2496  if (.not. (no_overwrite_use .and. field_length .ge. index)) then !{
2497  field_index = fm_new_value(name, sval, index = index)
2498  if (field_index .le. 0) then !{
2499  write (str_error,*) ' with index = ', index
2500  call mpp_error(fatal, trim(error_header) // ' Problem overwriting ' // trim(name) // trim(str_error))
2501  endif !}
2502  endif !}
2503  else !}{
2504  field_index = fm_new_value(name, sval, index = index)
2505  if (field_index .le. 0) then !{
2506  write (str_error,*) ' with index = ', index
2507  call mpp_error(fatal, trim(error_header) // ' Problem setting ' // trim(name) // trim(str_error))
2508  endif !}
2509  endif !}
2510 elseif (present(append)) then !}{
2511  field_index = fm_new_value(name, sval, append = append)
2512  if (field_index .le. 0) then !{
2513  write (str_error,*) ' with append = ', append
2514  call mpp_error(fatal, trim(error_header) // ' Problem setting ' // trim(name) // trim(str_error))
2515  endif !}
2516 else !}{
2517  if (fm_exists(name)) then !{
2518  if (.not. no_overwrite_use) then !{
2519  field_index = fm_new_value(name, sval)
2520  if (field_index .le. 0) then !{
2521  call mpp_error(fatal, trim(error_header) // ' Problem overwriting ' // trim(name))
2522  endif !}
2523  endif !}
2524  elseif (create) then !}{
2525  field_index = fm_new_value(name, sval)
2526  if (field_index .le. 0) then !{
2527  call mpp_error(fatal, trim(error_header) // ' Problem creating ' // trim(name))
2528  endif !}
2529  endif !}
2530 endif !}
2531 
2532 !
2533 ! Add the variable name to the list of good names, to be used
2534 ! later for a consistency check, unless the field did not exist and we did not create it
2535 !
2536 
2537 if (good_name_list_use .ne. ' ') then !{
2538  if (fm_exists(good_name_list_use)) then !{
2539  add_name = fm_util_get_index_string(good_name_list_use, name, &
2540  caller = caller_str) .le. 0 ! true if name does not exist in string array
2541  else !}{
2542  add_name = .true. ! always add to new list
2543  endif !}
2544  if (add_name .and. fm_exists(name)) then !{
2545  if (fm_new_value(good_name_list_use, name, append = .true., create = .true.) .le. 0) then !{
2546  call mpp_error(fatal, trim(error_header) // &
2547  ' Could not add ' // trim(name) // ' to "' // trim(good_name_list_use) // '" list')
2548  endif !}
2549  endif !}
2550 endif !}
2551 
2552 return
2553 
2554 end subroutine fm_util_set_value_string !}
2555 
2556 !#######################################################################
2557 
2558 !> Start processing a namelist
2559 subroutine fm_util_start_namelist(path, name, caller, no_overwrite, check) !{
2560 
2561 implicit none
2562 
2563 !
2564 ! arguments
2565 !
2566 
2567 character(len=*), intent(in) :: path
2568 character(len=*), intent(in) :: name
2569 character(len=*), intent(in), optional :: caller
2570 logical, intent(in), optional :: no_overwrite
2571 logical, intent(in), optional :: check
2572 
2573 !
2574 ! Local parameters
2575 !
2576 
2577 character(len=48), parameter :: sub_name = 'fm_util_start_namelist'
2578 
2579 !
2580 ! Local variables
2581 !
2582 
2583 integer :: namelist_index
2584 character(len=FMS_PATH_LEN) :: path_name
2585 character(len=256) :: error_header
2586 character(len=256) :: warn_header
2587 character(len=256) :: note_header
2588 character(len=128) :: caller_str
2589 integer :: out_unit
2590 
2591 out_unit = stdout()
2592 
2593 !
2594 ! set the caller string and headers
2595 !
2596 
2597 if (present(caller)) then !{
2598  caller_str = '[' // trim(caller) // ']'
2599 else !}{
2600  caller_str = fm_util_default_caller
2601 endif !}
2602 
2603 error_header = '==>Error from ' // trim(mod_name) // &
2604  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
2605 warn_header = '==>Warning from ' // trim(mod_name) // &
2606  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
2607 note_header = '==>Note from ' // trim(mod_name) // &
2608  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
2609 
2610 !
2611 ! check that a name is given (fatal if not)
2612 !
2613 
2614 if (name .eq. ' ') then !{
2615  call mpp_error(fatal, trim(error_header) // ' Empty name given')
2616 endif !}
2617 
2618 !
2619 ! Concatenate the path and name
2620 !
2621 
2622 if (path .eq. ' ') then !{
2623  path_name = name
2624 else !}{
2625  path_name = trim(path) // '/' // name
2626 endif !}
2627 save_path = path
2628 save_name = name
2629 
2630 !
2631 ! set the default caller string, if desired
2632 !
2633 
2634 if (present(caller)) then !{
2635  call fm_util_set_caller(caller)
2636 else !}{
2638 endif !}
2639 
2640 !
2641 ! set the default no_overwrite flag, if desired
2642 !
2643 
2644 if (present(no_overwrite)) then !{
2645  call fm_util_set_no_overwrite(no_overwrite)
2646 else !}{
2648 endif !}
2649 
2650 !
2651 ! set the default good_name_list string, if desired
2652 !
2653 
2654 if (present(check)) then !{
2655  if (check) then !{
2656  call fm_util_set_good_name_list('/ocean_mod/GOOD/namelists/' // trim(path_name) // '/good_list')
2657  else !}{
2659  endif !}
2660 else !}{
2662 endif !}
2663 
2664 !
2665 ! Process the namelist
2666 !
2667 
2668 write (out_unit,*)
2669 write (out_unit,*) trim(note_header), ' Processing namelist ', trim(path_name)
2670 
2671 !
2672 ! Check whether the namelist already exists. If so, then use that one
2673 !
2674 
2675 namelist_index = fm_get_index('/ocean_mod/namelists/' // trim(path_name))
2676 if (namelist_index .gt. 0) then !{
2677 
2678  !write (out_unit,*) trim(note_header), ' Namelist already set with index ', namelist_index
2679 
2680 else !}{
2681 
2682 !
2683 ! Set a new namelist and get its index
2684 !
2685 
2686  namelist_index = fm_new_list('/ocean_mod/namelists/' // trim(path_name), create = .true.)
2687  if (namelist_index .le. 0) then !{
2688  call mpp_error(fatal, trim(error_header) // ' Could not set namelist ' // trim(path_name))
2689  endif !}
2690 
2691 endif !}
2692 
2693 !
2694 ! Add the namelist name to the list of good namelists, to be used
2695 ! later for a consistency check
2696 !
2697 
2698 if (fm_new_value('/ocean_mod/GOOD/namelists/' // trim(path) // '/good_values', &
2699  name, append = .true., create = .true.) .le. 0) then !{
2700  call mpp_error(fatal, trim(error_header) // &
2701  ' Could not add ' // trim(name) // ' to "' // trim(path) // '/good_values" list')
2702 endif !}
2703 
2704 !
2705 ! Change to the new namelist, first saving the current list
2706 !
2707 
2708 save_current_list = fm_get_current_list()
2709 if (save_current_list .eq. ' ') then !{
2710  call mpp_error(fatal, trim(error_header) // ' Could not get the current list')
2711 endif !}
2712 
2713 if (.not. fm_change_list('/ocean_mod/namelists/' // trim(path_name))) then !{
2714  call mpp_error(fatal, trim(error_header) // ' Could not change to the namelist ' // trim(path_name))
2715 endif !}
2716 
2717 return
2718 
2719 end subroutine fm_util_start_namelist !}
2720 
2721 !#######################################################################
2722 
2723 !> Finish up processing a namelist
2724 subroutine fm_util_end_namelist(path, name, caller, check) !{
2725 
2726 implicit none
2727 
2728 !
2729 ! arguments
2730 !
2731 
2732 character(len=*), intent(in) :: path
2733 character(len=*), intent(in) :: name
2734 character(len=*), intent(in), optional :: caller
2735 logical, intent(in), optional :: check
2736 
2737 !
2738 ! Local parameters
2739 !
2740 
2741 character(len=48), parameter :: sub_name = 'fm_util_end_namelist'
2742 
2743 !
2744 ! Local variables
2745 !
2746 
2747 character(len=fm_string_len), pointer, dimension(:) :: good_list => null()
2748 character(len=FMS_PATH_LEN) :: path_name
2749 character(len=256) :: error_header
2750 character(len=256) :: warn_header
2751 character(len=256) :: note_header
2752 character(len=128) :: caller_str
2753 
2754 !
2755 ! set the caller string and headers
2756 !
2757 
2758 if (present(caller)) then !{
2759  caller_str = '[' // trim(caller) // ']'
2760 else !}{
2761  caller_str = fm_util_default_caller
2762 endif !}
2763 
2764 error_header = '==>Error from ' // trim(mod_name) // &
2765  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
2766 warn_header = '==>Warning from ' // trim(mod_name) // &
2767  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
2768 note_header = '==>Note from ' // trim(mod_name) // &
2769  '(' // trim(sub_name) // ')' // trim(caller_str) // ':'
2770 
2771 !
2772 ! check that a path is given (fatal if not)
2773 !
2774 
2775 if (name .eq. ' ') then !{
2776  call mpp_error(fatal, trim(error_header) // ' Empty name given')
2777 endif !}
2778 
2779 !
2780 ! Check that the path ane name match the preceding call to
2781 ! fm_util_start_namelist
2782 !
2783 
2784 if (path .ne. save_path) then !{
2785  call mpp_error(fatal, trim(error_header) // &
2786  & ' Path "' // trim(path) // '" does not match saved path "' // trim(save_path) // '"')
2787 elseif (name .ne. save_name) then !}{
2788  call mpp_error(fatal, trim(error_header) // &
2789  & ' Name "' // trim(name) // '" does not match saved name "' // trim(save_name) // '"')
2790 endif !}
2791 
2792 !
2793 ! Concatenate the path and name
2794 !
2795 
2796 if (path .eq. ' ') then !{
2797  path_name = name
2798 else !}{
2799  path_name = trim(path) // '/' // name
2800 endif !}
2801 save_path = ' '
2802 save_name = ' '
2803 
2804 !
2805 ! Check for any errors in the number of fields in this list
2806 !
2807 
2808 if (present(check)) then !{
2809  if (check) then !{
2810  if (caller_str .eq. ' ') then !{
2811  caller_str = trim(mod_name) // '(' // trim(sub_name) // ')'
2812  endif !}
2813  good_list => fm_util_get_string_array('/ocean_mod/GOOD/namelists/' // trim(path_name) // '/good_list', &
2814  caller = trim(mod_name) // '(' // trim(sub_name) // ')')
2815  if (associated(good_list)) then !{
2816  call fm_util_check_for_bad_fields('/ocean_mod/namelists/' // trim(path_name), good_list, caller = caller_str)
2817  deallocate(good_list)
2818  else !}{
2819  call mpp_error(fatal, trim(error_header) // ' Empty "' // trim(path_name) // '" list')
2820  endif !}
2821  endif !}
2822 endif !}
2823 
2824 !
2825 ! Change back to the saved list
2826 !
2827 
2828 if (save_current_list .ne. ' ') then !{
2829  if (.not. fm_change_list(save_current_list)) then !{
2830  call mpp_error(fatal, trim(error_header) // ' Could not change to the saved list: ' // trim(save_current_list))
2831  endif !}
2832 endif !}
2833 save_current_list = ' '
2834 
2835 !
2836 ! reset the default caller string
2837 !
2838 
2840 
2841 !
2842 ! reset the default no_overwrite string
2843 !
2844 
2846 
2847 !
2848 ! reset the default good_name_list string
2849 !
2850 
2852 
2853 return
2854 
2855 end subroutine fm_util_end_namelist !}
2856 
2857 #include "fm_util_r4.fh"
2858 #include "fm_util_r8.fh"
2859 
2860 end module fm_util_mod !}
2861 !> @}
2862 ! close documentation grouping
integer, parameter, public fm_string_len
The length of a character string representing character values for the field.
integer function, public fm_get_length(name)
A function to return how many elements are contained within the named list or entry.
character(len=8) function, public fm_get_type(name)
A function to return the type of the named field.
logical function, public fm_exists(name)
A function to test whether a named field exists.
logical function, public fm_change_list(name)
Change the current list. Return true on success, false otherwise.
integer function, public fm_new_list(name, create, keep)
A function to create a new list.
character(len=fms_path_len) function, public fm_get_current_list()
A function to return the full path of the current list.
integer function, public fm_get_index(name)
A function to return the index of a named field.
integer, parameter, public fm_field_name_len
The length of a character string representing the field name.
integer, parameter, public fm_type_name_len
The length of a character string representing the various types that the values of the field can take...
logical function, public fm_dump_list(name, recursive, unit)
A function to list properties associated with a field.
An overloaded function to find and extract a value for a named field.
A function for looping over a list.
An overloaded function to assign a value to a field.
subroutine fm_util_set_value_logical_array(name, lval, length, caller, no_overwrite, good_name_list)
Set a logical array in the Field Manager tree.
Definition: fm_util.F90:1731
subroutine fm_util_set_value_logical(name, lval, caller, index, append, no_create, no_overwrite, good_name_list)
Set a logical value in the Field Manager tree.
Definition: fm_util.F90:2218
subroutine, public fm_util_reset_no_overwrite
Reset the default value for the optional "no_overwrite" variable used in some of these subroutines to...
Definition: fm_util.F90:298
subroutine, public fm_util_start_namelist(path, name, caller, no_overwrite, check)
Start processing a namelist.
Definition: fm_util.F90:2560
subroutine fm_util_set_value_integer_array(name, ival, length, caller, no_overwrite, good_name_list)
Set an integer array in the Field Manager tree.
Definition: fm_util.F90:1574
subroutine, public fm_util_set_no_overwrite(no_overwrite)
Set the default value for the optional "no_overwrite" variable used in some of these subroutines.
Definition: fm_util.F90:264
logical function, dimension(:), pointer, public fm_util_get_logical_array(name, caller)
Get a logical value from the Field Manager tree.
Definition: fm_util.F90:837
subroutine, public fm_util_end_namelist(path, name, caller, check)
Finish up processing a namelist.
Definition: fm_util.F90:2725
subroutine, public fm_util_check_for_bad_fields(list, good_fields, caller)
Check for unrecognized fields in a list.
Definition: fm_util.F90:324
integer function, public fm_util_get_index_list(name, caller)
Get the length of an element of the Field Manager tree.
Definition: fm_util.F90:660
integer function, public fm_util_get_length(name, caller)
Get the length of an element of the Field Manager tree.
Definition: fm_util.F90:482
subroutine fm_util_set_value_string_array(name, sval, length, caller, no_overwrite, good_name_list)
Set a string array in the Field Manager tree.
Definition: fm_util.F90:1888
logical function, public fm_util_get_logical(name, caller, index, default_value, scalar)
Get a logical value from the Field Manager tree.
Definition: fm_util.F90:1227
subroutine, public fm_util_set_caller(caller)
Set the default value for the optional "caller" variable used in many of these subroutines....
Definition: fm_util.F90:138
subroutine, public fm_util_reset_caller
Reset the default value for the optional "caller" variable used in many of these subroutines to blank...
Definition: fm_util.F90:176
integer function, dimension(:), pointer, public fm_util_get_integer_array(name, caller)
Get an integer value from the Field Manager tree.
Definition: fm_util.F90:745
subroutine, public fm_util_reset_good_name_list
Reset the default value for the optional "good_name_list" variable used in many of these subroutines ...
Definition: fm_util.F90:237
subroutine fm_util_set_value_string(name, sval, caller, index, append, no_create, no_overwrite, good_name_list)
Set a string value in the Field Manager tree.
Definition: fm_util.F90:2389
real(r8_kind) function, public fm_util_get_real(name, caller, index, default_value, scalar)
Get a real value from the Field Manager tree.
Definition: fm_util.F90:1341
integer function, public fm_util_get_integer(name, caller, index, default_value, scalar)
Get an integer value from the Field Manager tree.
Definition: fm_util.F90:1114
character(len=fm_string_len) function, dimension(:), pointer, public fm_util_get_string_array(name, caller)
Get a string value from the Field Manager tree.
Definition: fm_util.F90:1022
subroutine fm_util_set_value_integer(name, ival, caller, index, append, no_create, no_overwrite, good_name_list)
Set an integer value in the Field Manager tree.
Definition: fm_util.F90:2046
integer function, public fm_util_get_index_string(name, string, caller)
Get the index of an element of a string in the Field Manager tree.
Definition: fm_util.F90:556
subroutine, public fm_util_set_good_name_list(good_name_list)
Set the default value for the optional "good_name_list" variable used in many of these subroutines.
Definition: fm_util.F90:203
real(r8_kind) function, dimension(:), pointer, public fm_util_get_real_array(name, caller)
Get a real value from the Field Manager tree.
Definition: fm_util.F90:929
character(len=fm_string_len) function, public fm_util_get_string(name, caller, index, default_value, scalar)
Get a string value from the Field Manager tree.
Definition: fm_util.F90:1462
integer function stdout()
This function returns the current standard fortran unit numbers for output.
Definition: mpp_util.inc:43
Error handler.
Definition: mpp.F90:382