Skip to content

Commit

Permalink
CPL: Add optional field exclusions list for nonlinear maps.
Browse files Browse the repository at this point in the history
Add the user_nl_cpl namelist option nlmaps_exclude_fields. This is a list of
fields that are to be excluded from the set that are nonlinearly mapped. For
these excluded fields, the low-order linear map is used instead. The default is
   nlmaps_exclude_fields =
     'Faxa_rainc', 'Faxa_rainl', 'Faxa_snowc', 'Faxa_snowl'
  • Loading branch information
ambrad committed Dec 1, 2023
1 parent 88488dc commit 597b6a2
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 16 deletions.
18 changes: 17 additions & 1 deletion driver-mct/cime_config/namelist_definition_drv.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1713,14 +1713,30 @@
<group>seq_infodata_inparm</group>
<desc>
Measure and print information about nonlinearly mapped fields. 0 means no
analysis is done or printed. >= 1 triggers analysis written to cpl.log.
analysis is done or printed. >= 1 triggers analysis written to
cpl.log. Modify user_nl_cpl to edit this.
default: 0
</desc>
<values>
<value>0</value>
</values>
</entry>

<entry id="nlmaps_exclude_fields">
<type>char(20)</type>
<category>nlmaps</category>
<group>seq_infodata_inparm</group>
<desc>
List of fields that are to be excluded from the set that are nonlinearly
mapped. For these excluded fields, the low-order linear map is used,
instead. Modify user_nl_cpl to edit this.
default: 'Faxa_rainc', 'Faxa_rainl', 'Faxa_snowc', 'Faxa_snowl'
</desc>
<values>
<value>'Faxa_rainc', 'Faxa_rainl', 'Faxa_snowc', 'Faxa_snowl'</value>
</values>
</entry>

<!-- =========================== -->
<!-- group seq_timemgr_inparm -->
<!-- =========================== -->
Expand Down
8 changes: 6 additions & 2 deletions driver-mct/main/cime_comp_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ module cime_comp_mod
use seq_infodata_mod, only: seq_infodata_init, seq_infodata_exchange
use seq_infodata_mod, only: seq_infodata_type, seq_infodata_orb_variable_year
use seq_infodata_mod, only: seq_infodata_print, seq_infodata_init2
use seq_infodata_mod, only: nlmaps_exclude_max_number, nlmaps_exclude_nchar

! domain related routines
use seq_domain_mct, only : seq_domain_check
Expand Down Expand Up @@ -1026,6 +1027,7 @@ subroutine cime_pre_init2()
integer(i8) :: end_count ! end time
integer(i8) :: irtc_rate ! factor to convert time to seconds
integer :: nlmaps_verbosity
character(nlmaps_exclude_nchar) :: nlmaps_exclude_fields(nlmaps_exclude_max_number)

!----------------------------------------------------------
!| Timer initialization (has to be after mpi init)
Expand Down Expand Up @@ -1176,7 +1178,8 @@ subroutine cime_pre_init2()
reprosum_diffmax=reprosum_diffmax , &
reprosum_recompute=reprosum_recompute , &
max_cplstep_time=max_cplstep_time , &
nlmaps_verbosity=nlmaps_verbosity)
nlmaps_verbosity=nlmaps_verbosity , &
nlmaps_exclude_fields=nlmaps_exclude_fields)

! above - cpl_decomp is set to pass the cpl_decomp value to seq_mctext_decomp
! (via a use statement)
Expand All @@ -1189,7 +1192,8 @@ subroutine cime_pre_init2()
repro_sum_rel_diff_max_in = reprosum_diffmax, &
repro_sum_recompute_in = reprosum_recompute)

call seq_nlmap_setopts(nlmaps_verbosity_in = nlmaps_verbosity)
call seq_nlmap_setopts(nlmaps_verbosity_in = nlmaps_verbosity, &
nlmaps_exclude_fields_in = nlmaps_exclude_fields)

! Check cpl_seq_option

Expand Down
67 changes: 58 additions & 9 deletions driver-mct/main/seq_nlmap_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ module seq_nlmap_mod
!
!-----------------------------------------------------------------------------

use shr_kind_mod , only: R8 => SHR_KIND_R8, IN => SHR_KIND_IN, I8 => SHR_KIND_I8
use shr_kind_mod , only: R8 => SHR_KIND_R8, IN => SHR_KIND_IN, I8 => SHR_KIND_I8, &
SHR_KIND_CS
use shr_kind_mod , only: CX => SHR_KIND_CX
use shr_sys_mod
use shr_const_mod
Expand All @@ -128,6 +129,7 @@ module seq_nlmap_mod
use seq_map_type_mod
use shr_reprosum_mod , only: shr_reprosum_calc
use shr_infnan_mod , only: shr_infnan_isnan, shr_infnan_isinf
use seq_infodata_mod , only: nlmaps_exclude_max_number, nlmaps_exclude_nchar
use perf_mod

implicit none
Expand All @@ -139,14 +141,37 @@ module seq_nlmap_mod
public :: seq_nlmap_check_matrices
public :: seq_nlmap_avNormArr

! Measure and print information about nonlinearly mapped fields. 0 means no
! analysis is done or printed. >= 1 triggers analysis written to cpl.log.
integer :: nlmaps_verbosity
! List of fields that are to be excluded from the set that are nonlinearly
! mapped. For these excluded fields, the low-order linear map is used,
! instead.
character(nlmaps_exclude_nchar) :: nlmaps_exclude_fields(nlmaps_exclude_max_number)
integer :: nlmaps_exclude_n_fields, nlmaps_exclude_max_nchar

contains

subroutine seq_nlmap_setopts(nlmaps_verbosity_in)
subroutine seq_nlmap_setopts(nlmaps_verbosity_in, nlmaps_exclude_fields_in)
integer, optional, intent(in) :: nlmaps_verbosity_in
character(nlmaps_exclude_nchar), optional, intent(in) :: nlmaps_exclude_fields_in(nlmaps_exclude_max_number)

integer :: i, n

if (present(nlmaps_verbosity_in)) nlmaps_verbosity = nlmaps_verbosity_in

nlmaps_exclude_n_fields = 0
nlmaps_exclude_max_nchar = 0
if (present(nlmaps_exclude_fields_in)) then
do i = 1, nlmaps_exclude_max_number
n = len(trim(nlmaps_exclude_fields_in(i)))
if (n > 0) then
nlmaps_exclude_n_fields = nlmaps_exclude_n_fields + 1
nlmaps_exclude_fields(nlmaps_exclude_n_fields) = nlmaps_exclude_fields_in(i)
nlmaps_exclude_max_nchar = max(nlmaps_exclude_max_nchar, n)
end if
end do
end if
end subroutine seq_nlmap_setopts

subroutine seq_nlmap_check_matrices(m)
Expand Down Expand Up @@ -274,15 +299,19 @@ subroutine seq_nlmap_avNormArr(mapper, avp_i, avp_o, lnorm)
character(len=*),parameter :: ffld = 'norm8wt'
character(len=*), parameter :: afldname = 'aream'
character(len=128) :: msg
logical :: amroot, verbose
logical :: amroot, verbose, found
integer(IN) :: mpicom, ierr, k, natt, nsum, nfld, kArea, lidata(2), gidata(2), i, n
real(r8) :: tmp, area, lo, hi, y
real(r8), allocatable, dimension(:) :: lmins, gmins, lmaxs, gmaxs, glbl_masses, gwts
real(r8), allocatable, dimension(:,:) :: dof_masses, caas_wgt, oglims, lcl_lo, lcl_hi
type(mct_string) :: mstring
character(CL) :: fldname

! BFB speedups to do:
! * Combine matvecs into one routine that shares the X->X' comm.
! * Combine the min/max reductions using a custom reduce.
! * Cleaner handling of the excludes list would remove computation and
! communication for vectors in the list.

call t_startf('seq_nlmap_avNormArr')

Expand Down Expand Up @@ -443,8 +472,8 @@ subroutine seq_nlmap_avNormArr(mapper, avp_i, avp_o, lnorm)
end do
end if

! Adjust high-order solution and set avp_o. The adjustment consists of a
! clip, if needed, and adding or removing mass up to the capacity.
! Adjust high-order solution. The adjustment consists of a clip, if
! needed, and adding or removing mass up to the capacity.
do k = 1,natt
if (gwts(k) > 0) then
tmp = gwts(2*natt+k)
Expand All @@ -457,7 +486,7 @@ subroutine seq_nlmap_avNormArr(mapper, avp_i, avp_o, lnorm)
hi = hi*avp_o%rAttr(natt+1,j)
end if
y = max(lo, min(hi, nl_avp_o%rAttr(k,j)))
avp_o%rAttr(k,j) = y + ((hi - y)/tmp)*gwts(k)
nl_avp_o%rAttr(k,j) = y + ((hi - y)/tmp)*gwts(k)
end do
end if
else if (gwts(k) < 0) then
Expand All @@ -471,22 +500,42 @@ subroutine seq_nlmap_avNormArr(mapper, avp_i, avp_o, lnorm)
hi = hi*avp_o%rAttr(natt+1,j)
end if
y = max(lo, min(hi, nl_avp_o%rAttr(k,j)))
avp_o%rAttr(k,j) = y + ((y - lo)/tmp)*gwts(k)
nl_avp_o%rAttr(k,j) = y + ((y - lo)/tmp)*gwts(k)
end do
end if
end if
end do
deallocate(gwts, lcl_lo, lcl_hi)
call mct_aVect_clean(nl_avp_o)

! Clip for numerics, just against the global extrema.
do j = 1,lsize_o
do k = 1,natt
if (avp_o%rAttr(k,j) == 0) cycle ! 0-mask
avp_o%rAttr(k,j) = max(gmins(k), min(gmaxs(k), avp_o%rAttr(k,j)))
nl_avp_o%rAttr(k,j) = max(gmins(k), min(gmaxs(k), nl_avp_o%rAttr(k,j)))
end do
end do

! Set avp_o.
do k = 1,natt
call mct_aVect_getRList(mstring, k, avp_i)
fldname = mct_string_toChar(mstring)
call mct_string_clean(mstring)
found = .false.
do j = 1, nlmaps_exclude_n_fields
if ( trim(fldname (1:nlmaps_exclude_max_nchar)) == &
trim(nlmaps_exclude_fields(j)(1:nlmaps_exclude_max_nchar))) then
found = .true.
exit
end if
end do
if (found) cycle
do j = 1,lsize_o
avp_o%rAttr(k,j) = nl_avp_o%rAttr(k,j)
end do
end do

call mct_aVect_clean(nl_avp_o)

if (verbose) then
! Final diagnostics.
! Check global mass.
Expand Down
27 changes: 23 additions & 4 deletions driver-mct/shr/seq_infodata_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ MODULE seq_infodata_mod
character(len=*), public, parameter :: seq_infodata_orb_variable_year = 'variable_year'
character(len=*), public, parameter :: seq_infodata_orb_fixed_parameters = 'fixed_parameters'

! For seq_nlmap_mod.
integer, public, parameter :: nlmaps_exclude_max_number = 20
integer, public, parameter :: nlmaps_exclude_nchar = SHR_KIND_CS

! InputInfo derived type

type seq_infodata_type
Expand Down Expand Up @@ -171,7 +175,8 @@ MODULE seq_infodata_mod
real(SHR_KIND_R8) :: eps_oarea ! ocn area error tolerance
logical :: mct_usealltoall ! flag for mct alltoall
logical :: mct_usevector ! flag for mct vector
integer :: nlmaps_verbosity ! see seq_nlmap_mod
integer :: nlmaps_verbosity ! see seq_nlmap_mod
character(nlmaps_exclude_nchar) :: nlmaps_exclude_fields(nlmaps_exclude_max_number) ! see seq_nlmap_mod

logical :: reprosum_use_ddpdd ! use ddpdd algorithm
logical :: reprosum_allow_infnan ! allow INF and NaN summands
Expand Down Expand Up @@ -433,6 +438,7 @@ SUBROUTINE seq_infodata_Init( infodata, nmlfile, ID, pioid, cpl_tag)
real(shr_kind_r8) :: max_cplstep_time ! abort if cplstep time exceeds this value
character(SHR_KIND_CL) :: model_doi_url
integer(SHR_KIND_IN) :: nlmaps_verbosity ! see seq_nlmap_mod
character(nlmaps_exclude_nchar) :: nlmaps_exclude_fields(nlmaps_exclude_max_number) ! see seq_nlmap_mod

namelist /seq_infodata_inparm/ &
cime_model, case_desc, case_name, start_type, tchkpt_dir, &
Expand Down Expand Up @@ -473,7 +479,7 @@ SUBROUTINE seq_infodata_Init( infodata, nmlfile, ID, pioid, cpl_tag)
reprosum_use_ddpdd, reprosum_allow_infnan, &
reprosum_diffmax, reprosum_recompute, &
mct_usealltoall, mct_usevector, max_cplstep_time, model_doi_url, &
nlmaps_verbosity
nlmaps_verbosity, nlmaps_exclude_fields

!-------------------------------------------------------------------------------

Expand Down Expand Up @@ -595,6 +601,7 @@ SUBROUTINE seq_infodata_Init( infodata, nmlfile, ID, pioid, cpl_tag)
max_cplstep_time = 0.0
model_doi_url = 'unset'
nlmaps_verbosity = 0
nlmaps_exclude_fields(:) = ' '

!---------------------------------------------------------------------------
! Read in namelist
Expand Down Expand Up @@ -730,6 +737,7 @@ SUBROUTINE seq_infodata_Init( infodata, nmlfile, ID, pioid, cpl_tag)
infodata%mct_usealltoall = mct_usealltoall
infodata%mct_usevector = mct_usevector
infodata%nlmaps_verbosity = nlmaps_verbosity
infodata%nlmaps_exclude_fields = nlmaps_exclude_fields

infodata%info_debug = info_debug
infodata%bfbflag = bfbflag
Expand Down Expand Up @@ -1033,7 +1041,7 @@ SUBROUTINE seq_infodata_GetData_explicit( infodata, cime_model, case_name, case_
reprosum_use_ddpdd, reprosum_allow_infnan, &
reprosum_diffmax, reprosum_recompute, &
mct_usealltoall, mct_usevector, max_cplstep_time, model_doi_url, &
glc_valid_input, nlmaps_verbosity)
glc_valid_input, nlmaps_verbosity, nlmaps_exclude_fields)


implicit none
Expand Down Expand Up @@ -1151,6 +1159,7 @@ SUBROUTINE seq_infodata_GetData_explicit( infodata, cime_model, case_name, case_
logical, optional, intent(OUT) :: mct_usealltoall ! flag for mct alltoall
logical, optional, intent(OUT) :: mct_usevector ! flag for mct vector
integer(SHR_KIND_IN), optional, intent(OUT) :: nlmaps_verbosity
character(nlmaps_exclude_nchar), optional, intent(OUT) :: nlmaps_exclude_fields(nlmaps_exclude_max_number)

integer(SHR_KIND_IN), optional, intent(OUT) :: info_debug
logical, optional, intent(OUT) :: bfbflag
Expand Down Expand Up @@ -1336,6 +1345,7 @@ SUBROUTINE seq_infodata_GetData_explicit( infodata, cime_model, case_name, case_
if ( present(mct_usealltoall)) mct_usealltoall = infodata%mct_usealltoall
if ( present(mct_usevector) ) mct_usevector = infodata%mct_usevector
if ( present(nlmaps_verbosity)) nlmaps_verbosity = infodata%nlmaps_verbosity
if ( present(nlmaps_exclude_fields)) nlmaps_exclude_fields = infodata%nlmaps_exclude_fields

if ( present(info_debug) ) info_debug = infodata%info_debug
if ( present(bfbflag) ) bfbflag = infodata%bfbflag
Expand Down Expand Up @@ -1584,7 +1594,8 @@ SUBROUTINE seq_infodata_PutData_explicit( infodata, cime_model, case_name, case_
eps_agrid, eps_aarea, eps_omask, eps_ogrid, eps_oarea, &
reprosum_use_ddpdd, reprosum_allow_infnan, &
reprosum_diffmax, reprosum_recompute, &
mct_usealltoall, mct_usevector, glc_valid_input, nlmaps_verbosity)
mct_usealltoall, mct_usevector, glc_valid_input, &
nlmaps_verbosity, nlmaps_exclude_fields)


implicit none
Expand Down Expand Up @@ -1701,6 +1712,7 @@ SUBROUTINE seq_infodata_PutData_explicit( infodata, cime_model, case_name, case_
logical, optional, intent(IN) :: mct_usealltoall ! flag for mct alltoall
logical, optional, intent(IN) :: mct_usevector ! flag for mct vector
integer(SHR_KIND_IN), optional, intent(IN) :: nlmaps_verbosity
character(nlmaps_exclude_nchar), optional, intent(IN) :: nlmaps_exclude_fields(nlmaps_exclude_max_number)

integer(SHR_KIND_IN), optional, intent(IN) :: info_debug
logical, optional, intent(IN) :: bfbflag
Expand Down Expand Up @@ -1885,6 +1897,7 @@ SUBROUTINE seq_infodata_PutData_explicit( infodata, cime_model, case_name, case_
if ( present(mct_usealltoall)) infodata%mct_usealltoall = mct_usealltoall
if ( present(mct_usevector) ) infodata%mct_usevector = mct_usevector
if ( present(nlmaps_verbosity)) infodata%nlmaps_verbosity = nlmaps_verbosity
if ( present(nlmaps_exclude_fields)) infodata%nlmaps_exclude_fields = nlmaps_exclude_fields

if ( present(info_debug) ) infodata%info_debug = info_debug
if ( present(bfbflag) ) infodata%bfbflag = bfbflag
Expand Down Expand Up @@ -2081,6 +2094,8 @@ subroutine seq_infodata_bcast(infodata,mpicom)

!----- local -----

integer :: i

!-------------------------------------------------------------------------------
! Notes:
!-------------------------------------------------------------------------------
Expand Down Expand Up @@ -2192,6 +2207,9 @@ subroutine seq_infodata_bcast(infodata,mpicom)
call shr_mpi_bcast(infodata%mct_usealltoall, mpicom)
call shr_mpi_bcast(infodata%mct_usevector, mpicom)
call shr_mpi_bcast(infodata%nlmaps_verbosity, mpicom)
do i = 1, nlmaps_exclude_max_number
call shr_mpi_bcast(infodata%nlmaps_exclude_fields(i), mpicom)
end do

call shr_mpi_bcast(infodata%info_debug, mpicom)
call shr_mpi_bcast(infodata%bfbflag, mpicom)
Expand Down Expand Up @@ -2903,6 +2921,7 @@ SUBROUTINE seq_infodata_print( infodata )
write(logunit,F0L) subname,'mct_usevector = ', infodata%mct_usevector

write(logunit,F0I) subname,'nlmaps_verbosity = ', infodata%nlmaps_verbosity
write(logunit,F0I) subname,'nlmaps_exclude_fields = ', infodata%nlmaps_exclude_fields

write(logunit,F0S) subname,'info_debug = ', infodata%info_debug
write(logunit,F0L) subname,'bfbflag = ', infodata%bfbflag
Expand Down

0 comments on commit 597b6a2

Please sign in to comment.