Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CPL: Add field exclusions list for nonlinear maps. #6094

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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