Skip to content

Commit 7846b80

Browse files
Hallberg-NOAAmarshallward
authored andcommitted
+Add a vector of defaults to get_param_array_int
The `default=` optional argument to get_param() only provides a uniform value to initialize an array of integers. This commit adds an optional `defaults=` argument to get_param_int_array(), doc_param_int_array() and log_param_int_array() to allow for the specification of an array of default values. These additions are analogous to what had previously been added for real arrays in github.com//pull/760. This commit also adds the new internal function int_array_string(), analogous to real_array_string(), in MOM_document. This differs slightly from its real array counterpart in that it only uses the syntax like `3*75` for lists of integers that are longer than we would use to specify dates and times or pairs of layout parameters, because "(0, 0)" seems more readily interpretable than "(2*0)". The new defaults argument is now used in the get_param calls for LAYOUT and IO_LAYOUT, and in setting the tidal reference dates. Several spelling errors in comments were also corrected in the files that were being edited. All answers are bitwise identical, but there are minor changes in many MOM_parameter_doc.layout files and some MOM_parameter_doc.all files.
1 parent 81ea4b6 commit 7846b80

File tree

5 files changed

+92
-27
lines changed

5 files changed

+92
-27
lines changed

src/core/MOM_open_boundary.F90

+3-3
Original file line numberDiff line numberDiff line change
@@ -1188,7 +1188,7 @@ subroutine initialize_obc_tides(OBC, US, param_file)
11881188

11891189
call get_param(param_file, mdl, "OBC_TIDE_NODAL_REF_DATE", nodal_ref_date, &
11901190
"Fixed reference date to use for nodal modulation of boundary tides.", &
1191-
fail_if_missing=.false., default=0)
1191+
fail_if_missing=.false., defaults=(/0, 0, 0/))
11921192

11931193
if (.not. OBC%add_eq_phase) then
11941194
! If equilibrium phase argument is not added, the input phases
@@ -1200,7 +1200,7 @@ subroutine initialize_obc_tides(OBC, US, param_file)
12001200
read(tide_constituent_str, *) OBC%tide_names
12011201

12021202
! Set reference time (t = 0) for boundary tidal forcing.
1203-
OBC%time_ref = set_date(tide_ref_date(1), tide_ref_date(2), tide_ref_date(3))
1203+
OBC%time_ref = set_date(tide_ref_date(1), tide_ref_date(2), tide_ref_date(3), 0, 0, 0)
12041204

12051205
! Find relevant lunar and solar longitudes at the reference time
12061206
if (OBC%add_eq_phase) call astro_longitudes_init(OBC%time_ref, OBC%tidal_longitudes)
@@ -1210,7 +1210,7 @@ subroutine initialize_obc_tides(OBC, US, param_file)
12101210
if (OBC%add_nodal_terms) then
12111211
if (sum(nodal_ref_date) /= 0) then
12121212
! A reference date was provided for the nodal correction
1213-
nodal_time = set_date(nodal_ref_date(1), nodal_ref_date(2), nodal_ref_date(3))
1213+
nodal_time = set_date(nodal_ref_date(1), nodal_ref_date(2), nodal_ref_date(3), 0, 0, 0)
12141214
call astro_longitudes_init(nodal_time, nodal_longitudes)
12151215
elseif (OBC%add_eq_phase) then
12161216
! Astronomical longitudes were already calculated for use in equilibrium phases,

src/framework/MOM_document.F90

+59-4
Original file line numberDiff line numberDiff line change
@@ -221,15 +221,16 @@ subroutine doc_param_int(doc, varname, desc, units, val, default, &
221221
end subroutine doc_param_int
222222

223223
!> This subroutine handles parameter documentation for arrays of integers.
224-
subroutine doc_param_int_array(doc, varname, desc, units, vals, default, &
224+
subroutine doc_param_int_array(doc, varname, desc, units, vals, default, defaults, &
225225
layoutParam, debuggingParam, like_default)
226226
type(doc_type), pointer :: doc !< A pointer to a structure that controls where the
227227
!! documentation occurs and its formatting
228228
character(len=*), intent(in) :: varname !< The name of the parameter being documented
229229
character(len=*), intent(in) :: desc !< A description of the parameter being documented
230230
character(len=*), intent(in) :: units !< The units of the parameter being documented
231231
integer, intent(in) :: vals(:) !< The array of values to record
232-
integer, optional, intent(in) :: default !< The default value of this parameter
232+
integer, optional, intent(in) :: default !< The uniform default value of this parameter
233+
integer, optional, intent(in) :: defaults(:) !< The element-wise default values of this parameter
233234
logical, optional, intent(in) :: layoutParam !< If present and true, this is a layout parameter.
234235
logical, optional, intent(in) :: debuggingParam !< If present and true, this is a debugging parameter.
235236
logical, optional, intent(in) :: like_default !< If present and true, log this parameter as though
@@ -257,6 +258,11 @@ subroutine doc_param_int_array(doc, varname, desc, units, vals, default, &
257258
do i=1,size(vals) ; if (vals(i) /= default) equalsDefault = .false. ; enddo
258259
mesg = trim(mesg)//" default = "//(trim(int_string(default)))
259260
endif
261+
if (present(defaults)) then
262+
equalsDefault = .true.
263+
do i=1,size(vals) ; if (vals(i) /= defaults(i)) equalsDefault = .false. ; enddo
264+
mesg = trim(mesg)//" default = "//trim(int_array_string(defaults))
265+
endif
260266
if (present(like_default)) then ; if (like_default) equalsDefault = .true. ; endif
261267

262268
if (mesgHasBeenDocumented(doc, varName, mesg)) return ! Avoid duplicates
@@ -479,7 +485,7 @@ subroutine doc_param_time(doc, varname, desc, val, default, units, debuggingPara
479485

480486
end subroutine doc_param_time
481487

482-
!> This subroutine writes out the message and description to the documetation files.
488+
!> This subroutine writes out the message and description to the documentation files.
483489
subroutine writeMessageAndDesc(doc, vmesg, desc, valueWasDefault, indent, &
484490
layoutParam, debuggingParam)
485491
type(doc_type), intent(in) :: doc !< A pointer to a structure that controls where the
@@ -719,6 +725,55 @@ function real_array_string(vals, sep)
719725
enddo
720726
end function real_array_string
721727

728+
729+
!> Returns a character string of a comma-separated, compact formatted, integers
730+
!> e.g. "1, 2, 7*3, 500", that give the list of values.
731+
function int_array_string(vals, sep)
732+
character(len=:), allocatable :: int_array_string !< The output string listing vals
733+
integer, intent(in) :: vals(:) !< The array of values to record
734+
character(len=*), &
735+
optional, intent(in) :: sep !< The separator between successive values,
736+
!! by default it is ', '.
737+
738+
! Local variables
739+
integer :: j, m, n, ns
740+
logical :: doWrite
741+
character(len=10) :: separator
742+
n = 1 ; doWrite = .true. ; int_array_string = ''
743+
if (present(sep)) then
744+
separator = sep ; ns = len(sep)
745+
else
746+
separator = ', ' ; ns = 2
747+
endif
748+
do j=1,size(vals)
749+
doWrite = .true.
750+
if (j < size(vals)) then
751+
if (vals(j) == vals(j+1)) then
752+
n = n+1
753+
doWrite = .false.
754+
endif
755+
endif
756+
if (doWrite) then
757+
if (len(int_array_string) > 0) then ! Write separator if a number has already been written
758+
int_array_string = int_array_string // separator(1:ns)
759+
endif
760+
if (n>1) then
761+
if (size(vals) > 6) then ! The n*val syntax is convenient in long lists of integers.
762+
int_array_string = int_array_string // trim(int_string(n)) // "*" // trim(int_string(vals(j)))
763+
else ! For short lists of integers, do not use the n*val syntax as it is less convenient.
764+
do m=1,n-1
765+
int_array_string = int_array_string // trim(int_string(vals(j))) // separator(1:ns)
766+
enddo
767+
int_array_string = int_array_string // trim(int_string(vals(j)))
768+
endif
769+
else
770+
int_array_string = int_array_string // trim(int_string(vals(j)))
771+
endif
772+
n=1
773+
endif
774+
enddo
775+
end function int_array_string
776+
722777
!> This function tests whether a real value is encoded in a string.
723778
function testFormattedFloatIsReal(str, val)
724779
character(len=*), intent(in) :: str !< The string that match val
@@ -1007,7 +1062,7 @@ function find_unused_unit_number()
10071062
"doc_init failed to find an unused unit number.")
10081063
end function find_unused_unit_number
10091064

1010-
!> This subroutine closes the the files controlled by doc, and sets flags in
1065+
!> This subroutine closes the files controlled by doc, and sets flags in
10111066
!! doc to indicate that parameterization is no longer permitted.
10121067
subroutine doc_end(doc)
10131068
type(doc_type), pointer :: doc !< A pointer to a structure that controls where the

src/framework/MOM_domains.F90

+2-2
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ subroutine MOM_domains_init(MOM_dom, param_file, symmetric, static_memory, &
350350
else
351351
call get_param(param_file, mdl, trim(layout_nm), layout, &
352352
"The processor layout to be used, or 0, 0 to automatically set the layout "//&
353-
"based on the number of processors.", default=0, do_not_log=.true.)
353+
"based on the number of processors.", defaults=(/0, 0/), do_not_log=.true.)
354354
call get_param(param_file, mdl, trim(niproc_nm), nip_parsed, &
355355
"The number of processors in the x-direction.", default=-1, do_not_log=.true.)
356356
call get_param(param_file, mdl, trim(njproc_nm), njp_parsed, &
@@ -436,7 +436,7 @@ subroutine MOM_domains_init(MOM_dom, param_file, symmetric, static_memory, &
436436
else
437437
call get_param(param_file, mdl, trim(io_layout_nm), io_layout, &
438438
"The processor layout to be used, or 0,0 to automatically set the io_layout "//&
439-
"to be the same as the layout.", default=1, layoutParam=.true.)
439+
"to be the same as the layout.", defaults=(/1, 1/), layoutParam=.true.)
440440
endif
441441

442442
call create_MOM_domain(MOM_dom, n_global, n_halo, reentrant, tripolar_N, layout, &

src/framework/MOM_file_parser.F90

+23-13
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ module MOM_file_parser
125125

126126
contains
127127

128-
!> Make the contents of a parameter input file availalble in a param_file_type
128+
!> Make the contents of a parameter input file available in a param_file_type
129129
subroutine open_param_file(filename, CS, checkable, component, doc_file_dir, ensemble_num)
130130
character(len=*), intent(in) :: filename !< An input file name, optionally with the full path
131131
type(param_file_type), intent(inout) :: CS !< The control structure for the file_parser module,
@@ -562,10 +562,10 @@ function removeComments(string)
562562
removeComments(:last)=adjustl(string(:last)) ! Copy only the non-comment part of string
563563
end function removeComments
564564

565-
!> Constructs a string with all repeated whitespace replaced with single blanks
565+
!> Constructs a string with all repeated white space replaced with single blanks
566566
!! and insert white space where it helps delineate tokens (e.g. around =)
567567
function simplifyWhiteSpace(string)
568-
character(len=*), intent(in) :: string !< A string to modify to simpify white space
568+
character(len=*), intent(in) :: string !< A string to modify to simplify white space
569569
character(len=len(string)+16) :: simplifyWhiteSpace
570570

571571
! Local variables
@@ -583,7 +583,7 @@ function simplifyWhiteSpace(string)
583583
if (string(j:j)==quoteChar) insideString=.false. ! End of string
584584
else ! The following is outside of string delimiters
585585
if (string(j:j)==" " .or. string(j:j)==achar(9)) then ! Space or tab
586-
if (nonBlank) then ! Only copy a blank if the preceeding character was non-blank
586+
if (nonBlank) then ! Only copy a blank if the preceding character was non-blank
587587
i=i+1
588588
simplifyWhiteSpace(i:i)=" " ! Not string(j:j) so that tabs are replace by blanks
589589
nonBlank=.false.
@@ -989,7 +989,7 @@ function max_input_line_length(CS, pf_num) result(max_len)
989989
end function max_input_line_length
990990

991991
!> This subroutine extracts the contents of lines in the param_file_type that refer to
992-
!! a named parameter. The value_string that is returned must be interepreted in a way
992+
!! a named parameter. The value_string that is returned must be interpreted in a way
993993
!! that depends on the type of this variable.
994994
subroutine get_variable_line(CS, varname, found, defined, value_string, paramIsLogical)
995995
type(param_file_type), intent(in) :: CS !< The control structure for the file_parser module,
@@ -1391,7 +1391,7 @@ end subroutine log_param_int
13911391

13921392
!> Log the name and values of an array of integer model parameter in documentation files.
13931393
subroutine log_param_int_array(CS, modulename, varname, value, desc, &
1394-
units, default, layoutParam, debuggingParam, like_default)
1394+
units, default, defaults, layoutParam, debuggingParam, like_default)
13951395
type(param_file_type), intent(in) :: CS !< The control structure for the file_parser module,
13961396
!! it is also a structure to parse for run-time parameters
13971397
character(len=*), intent(in) :: modulename !< The name of the module using this parameter
@@ -1400,7 +1400,8 @@ subroutine log_param_int_array(CS, modulename, varname, value, desc, &
14001400
character(len=*), optional, intent(in) :: desc !< A description of this variable; if not
14011401
!! present, this parameter is not written to a doc file
14021402
character(len=*), optional, intent(in) :: units !< The units of this parameter
1403-
integer, optional, intent(in) :: default !< The default value of the parameter
1403+
integer, optional, intent(in) :: default !< The uniform default value of this parameter
1404+
integer, optional, intent(in) :: defaults(:) !< The element-wise default values of this parameter
14041405
logical, optional, intent(in) :: layoutParam !< If present and true, this parameter is
14051406
!! logged in the layout parameter file
14061407
logical, optional, intent(in) :: debuggingParam !< If present and true, this parameter is
@@ -1419,7 +1420,7 @@ subroutine log_param_int_array(CS, modulename, varname, value, desc, &
14191420

14201421
myunits=" "; if (present(units)) write(myunits(1:240),'(A)') trim(units)
14211422
if (present(desc)) &
1422-
call doc_param(CS%doc, varname, desc, myunits, value, default, &
1423+
call doc_param(CS%doc, varname, desc, myunits, value, default, defaults, &
14231424
layoutParam=layoutParam, debuggingParam=debuggingParam, like_default=like_default)
14241425

14251426
end subroutine log_param_int_array
@@ -1745,7 +1746,7 @@ end subroutine get_param_int
17451746
!> This subroutine reads the values of an array of integer model parameters from a parameter file
17461747
!! and logs them in documentation files.
17471748
subroutine get_param_int_array(CS, modulename, varname, value, desc, units, &
1748-
default, fail_if_missing, do_not_read, do_not_log, &
1749+
default, defaults, fail_if_missing, do_not_read, do_not_log, &
17491750
layoutParam, debuggingParam)
17501751
type(param_file_type), intent(in) :: CS !< The control structure for the file_parser module,
17511752
!! it is also a structure to parse for run-time parameters
@@ -1756,7 +1757,8 @@ subroutine get_param_int_array(CS, modulename, varname, value, desc, units, &
17561757
character(len=*), optional, intent(in) :: desc !< A description of this variable; if not
17571758
!! present, this parameter is not written to a doc file
17581759
character(len=*), optional, intent(in) :: units !< The units of this parameter
1759-
integer, optional, intent(in) :: default !< The default value of the parameter
1760+
integer, optional, intent(in) :: default !< The uniform default value of this parameter
1761+
integer, optional, intent(in) :: defaults(:) !< The element-wise default values of this parameter
17601762
logical, optional, intent(in) :: fail_if_missing !< If present and true, a fatal error occurs
17611763
!! if this variable is not found in the parameter file
17621764
logical, optional, intent(in) :: do_not_read !< If present and true, do not read a
@@ -1773,14 +1775,22 @@ subroutine get_param_int_array(CS, modulename, varname, value, desc, units, &
17731775
do_read = .true. ; if (present(do_not_read)) do_read = .not.do_not_read
17741776
do_log = .true. ; if (present(do_not_log)) do_log = .not.do_not_log
17751777

1778+
if (present(defaults)) then
1779+
if (present(default)) call MOM_error(FATAL, &
1780+
"get_param_int_array: Only one of default and defaults can be specified at a time.")
1781+
if (size(defaults) /= size(value)) call MOM_error(FATAL, &
1782+
"get_param_int_array: The size of defaults and value are not the same.")
1783+
endif
1784+
17761785
if (do_read) then
17771786
if (present(default)) value(:) = default
1787+
if (present(defaults)) value(:) = defaults(:)
17781788
call read_param_int_array(CS, varname, value, fail_if_missing)
17791789
endif
17801790

17811791
if (do_log) then
1782-
call log_param_int_array(CS, modulename, varname, value, desc, &
1783-
units, default, layoutParam, debuggingParam)
1792+
call log_param_int_array(CS, modulename, varname, value, desc, units, &
1793+
default, defaults, layoutParam, debuggingParam)
17841794
endif
17851795

17861796
end subroutine get_param_int_array
@@ -1871,7 +1881,7 @@ subroutine get_param_real_array(CS, modulename, varname, value, desc, units, &
18711881
if (present(default)) call MOM_error(FATAL, &
18721882
"get_param_real_array: Only one of default and defaults can be specified at a time.")
18731883
if (size(defaults) /= size(value)) call MOM_error(FATAL, &
1874-
"get_param_real_array: The size of defaults nad value are not the same.")
1884+
"get_param_real_array: The size of defaults and value are not the same.")
18751885
endif
18761886

18771887
if (do_read) then

src/parameterizations/lateral/MOM_tidal_forcing.F90

+5-5
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ subroutine astro_longitudes_init(time_ref, longitudes)
9595
real :: T !> Time in Julian centuries [centuries]
9696
real, parameter :: PI = 4.0 * atan(1.0) !> 3.14159... [nondim]
9797

98-
! Find date at time_ref in days since 1900-01-01
99-
D = time_type_to_real(time_ref - set_date(1900, 1, 1)) / (24.0 * 3600.0)
98+
! Find date at time_ref in days since midnight at the start of 1900-01-01
99+
D = time_type_to_real(time_ref - set_date(1900, 1, 1, 0, 0, 0)) / (24.0 * 3600.0)
100100
! Time since 1900-01-01 in Julian centuries
101101
! Kowalik and Luick use 36526, but Schureman uses 36525 which I think is correct.
102102
T = D / 36525.0
@@ -385,22 +385,22 @@ subroutine tidal_forcing_init(Time, G, US, param_file, CS, HA_CS)
385385
call get_param(param_file, mdl, "TIDE_REF_DATE", tide_ref_date, &
386386
"Year,month,day to use as reference date for tidal forcing. "//&
387387
"If not specified, defaults to 0.", &
388-
default=0)
388+
defaults=(/0, 0, 0/))
389389

390390
call get_param(param_file, mdl, "TIDE_USE_EQ_PHASE", CS%use_eq_phase, &
391391
"Correct phases by calculating equilibrium phase arguments for TIDE_REF_DATE. ", &
392392
default=.false., fail_if_missing=.false.)
393393

394394
if (sum(tide_ref_date) == 0) then ! tide_ref_date defaults to 0.
395-
CS%time_ref = set_date(1, 1, 1)
395+
CS%time_ref = set_date(1, 1, 1, 0, 0, 0)
396396
else
397397
if (.not. CS%use_eq_phase) then
398398
! Using a reference date but not using phase relative to equilibrium.
399399
! This makes sense as long as either phases are overridden, or
400400
! correctly simulating tidal phases is not desired.
401401
call MOM_mesg('Tidal phases will *not* be corrected with equilibrium arguments.')
402402
endif
403-
CS%time_ref = set_date(tide_ref_date(1), tide_ref_date(2), tide_ref_date(3))
403+
CS%time_ref = set_date(tide_ref_date(1), tide_ref_date(2), tide_ref_date(3), 0, 0, 0)
404404
endif
405405

406406
! Initialize reference time for tides and find relevant lunar and solar

0 commit comments

Comments
 (0)