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

Check flds for nan #1765

Merged
merged 11 commits into from
Jul 28, 2017
15 changes: 14 additions & 1 deletion src/drivers/mct/cime_config/namelist_definition_drv.xml
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,19 @@
</values>
</entry>

<entry id="nan_check_component_fields">
<type>logical</type>
<category>seq_flds</category>
<group>seq_cplflds_inparm</group>
<desc>
.true. means that all fields passed to coupler are checked for NaN values
</desc>
<values>
<value>.false.</value>
<value cime_model='cesm'>.true.</value>
</values>
</entry>

<!-- =========================== -->
<!-- -group seq_cplflds_custom -->
<!-- =========================== -->
Expand Down Expand Up @@ -2677,7 +2690,7 @@
<group>ccsm_pes</group>
<desc>
Determines what ESMF log files (if any) are generated when
USE_ESMF_LIB is TRUE.
USE_ESMF_LIB is TRUE.
ESMF_LOGKIND_SINGLE: Use a single log file, combining messages from
all of the PETs. Not supported on some platforms.
ESMF_LOGKIND_MULTI: Use multiple log files — one per PET.
Expand Down
19 changes: 16 additions & 3 deletions src/drivers/mct/main/component_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ module component_mod
use mct_mod ! mct_ wrappers for mct lib
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There still seems to be a lot of white space diffs. Can we remove them?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have removed all whitespace in #1766 accepting that will remove the differences in this one.

use perf_mod
use ESMF

use seq_flds_mod, only: nan_check_component_fields
implicit none

#include <mpif.h>
Expand Down Expand Up @@ -213,8 +213,11 @@ end subroutine comp_init
endif

if (.not. associated(comp(eci)%x2c_cc)) allocate(comp(eci)%x2c_cc)
if (.not. associated(comp(eci)%c2x_cc)) allocate(comp(eci)%c2x_cc)

if (.not. associated(comp(eci)%c2x_cc)) then
allocate(comp(eci)%c2x_cc)
! this is needed for check_fields
nullify(comp(eci)%c2x_cc%rattr)
endif
if (comp(eci)%iamin_compid .and. comp(eci)%present) then
if (drv_threading) call seq_comm_setnthreads(comp(eci)%nthreads_compid)
call shr_sys_flush(logunit)
Expand All @@ -226,6 +229,11 @@ end subroutine comp_init
call t_set_prefixf(comp(1)%oneletterid//"_i:")
call comp_init( EClock, comp(eci)%cdata_cc, comp(eci)%x2c_cc, comp(eci)%c2x_cc, &
NLFilename=NLFilename )
if(nan_check_component_fields) then
call t_drvstartf ('check_fields')
call check_fields(comp(eci), eci)
call t_drvstopf ('check_fields')
end If
call t_unset_prefixf()

if (present(seq_flds_c2x_fluxes)) then
Expand Down Expand Up @@ -679,6 +687,11 @@ end subroutine comp_run

call t_set_prefixf(comp(1)%oneletterid//":")
call comp_run(EClock, comp(eci)%cdata_cc, comp(eci)%x2c_cc, comp(eci)%c2x_cc)
if(nan_check_component_fields) then
call t_drvstartf ('check_fields')
call check_fields(comp(eci), eci)
call t_drvstopf ('check_fields')
endif
call t_unset_prefixf()

if ((phase == 1) .and. present(seq_flds_c2x_fluxes)) then
Expand Down
38 changes: 38 additions & 0 deletions src/drivers/mct/main/component_type_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module component_type_mod
use shr_kind_mod , only: r8 => SHR_KIND_R8
use shr_kind_mod , only: cs => SHR_KIND_CS
use shr_kind_mod , only: cl => SHR_KIND_CL
use shr_kind_mod , only: IN => SHR_KIND_IN
use seq_cdata_mod , only: seq_cdata
use seq_map_type_mod , only: seq_map
use seq_comm_mct , only: seq_comm_namelen
Expand All @@ -29,6 +30,7 @@ module component_type_mod
public :: component_get_gsmap_cc
public :: component_get_cdata_cc
public :: component_get_iamroot_compid
public :: check_fields
!
! on cpl pes
public :: component_get_x2c_cx
Expand Down Expand Up @@ -224,4 +226,40 @@ function component_get_mapper_Cx2c(comp)
component_get_mapper_Cx2c => comp%mapper_Cx2c
end function component_get_mapper_Cx2c

subroutine check_fields(comp, comp_index)
use shr_infnan_mod, only: shr_infnan_isnan
use mct_mod, only: mct_avect_getrlist2c, mct_gsMap_orderedPoints
type(component_type), intent(in) :: comp
integer(in), intent(in) :: comp_index

integer(IN) :: lsize ! size of attr vect
integer(IN) :: nflds ! number of attr vects
integer(in) :: fld, n ! iterators
integer(IN) :: rank
integer(IN) :: ierr
integer(IN), pointer :: gpts(:)
character(len=CL) :: msg

if(associated(comp%c2x_cc) .and. associated(comp%c2x_cc%rattr)) then
lsize = mct_avect_lsize(comp%c2x_cc)
nflds = size(comp%c2x_cc%rattr,1)
! c2x_cc is allocated even if not used such as in stub models
! do not test this case.
if(lsize <= 1 .and. nflds <= 1) return
if(any(shr_infnan_isnan(comp%c2x_cc%rattr))) then
do fld=1,nflds
do n=1,lsize
if(shr_infnan_isnan(comp%c2x_cc%rattr(fld,n))) then
call mpi_comm_rank(comp%mpicom_compid, rank, ierr)
call mct_gsMap_orderedPoints(comp%gsmap_cc, rank, gpts)
write(msg,*)'component_mod:check_fields NaN found in ',trim(comp%name),' instance: ',&
comp_index,' field ',trim(mct_avect_getRList2c(fld, comp%c2x_cc)), ' 1d global index: ',gpts(n)
call shr_sys_abort(msg)
endif
enddo
enddo
endif
endif
end subroutine check_fields

end module component_type_mod
7 changes: 6 additions & 1 deletion src/drivers/mct/shr/seq_flds_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,9 @@ module seq_flds_mod
character(32) :: wavname='wav'
character(32) :: rofname='rof'

! namelist variables
logical :: nan_check_component_fields

!----------------------------------------------------------------------------
contains
!----------------------------------------------------------------------------
Expand Down Expand Up @@ -347,7 +350,7 @@ subroutine seq_flds_set(nmlfile, ID, infodata)

namelist /seq_cplflds_inparm/ &
flds_co2a, flds_co2b, flds_co2c, flds_co2_dmsa, flds_wiso, glc_nec, &
ice_ncat, seq_flds_i2o_per_cat, flds_bgc
ice_ncat, seq_flds_i2o_per_cat, flds_bgc, nan_check_component_fields

! user specified new fields
integer, parameter :: nfldmax = 200
Expand Down Expand Up @@ -381,6 +384,7 @@ subroutine seq_flds_set(nmlfile, ID, infodata)
glc_nec = 0
ice_ncat = 1
seq_flds_i2o_per_cat = .false.
nan_check_component_fields = .false.

unitn = shr_file_getUnit()
write(logunit,"(A)") subname//': read seq_cplflds_inparm namelist from: '&
Expand All @@ -406,6 +410,7 @@ subroutine seq_flds_set(nmlfile, ID, infodata)
call shr_mpi_bcast(glc_nec , mpicom)
call shr_mpi_bcast(ice_ncat , mpicom)
call shr_mpi_bcast(seq_flds_i2o_per_cat, mpicom)
call shr_mpi_bcast(nan_check_component_fields, mpicom)

call glc_elevclass_init(glc_nec)

Expand Down
4 changes: 2 additions & 2 deletions src/drivers/mct/shr/seq_infodata_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -276,11 +276,11 @@ MODULE seq_infodata_mod
!===============================================================================
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment about white space diffs.

!BOP ===========================================================================
!
! !IROUTINE: seq_infodata_Init -- read in CCSM shared namelist
! !IROUTINE: seq_infodata_Init -- read in CIME shared namelist
!
! !DESCRIPTION:
!
! Read in input from seq_infodata_inparm namelist, output ccsm derived type for
! Read in input from seq_infodata_inparm namelist, output cime derived type for
! miscillaneous info.
!
! !INTERFACE: ------------------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions src/drivers/mct/unit_test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,4 @@ add_subdirectory(seq_map_test)
add_subdirectory(glc_elevclass_test)
add_subdirectory(map_glc2lnd_test)
add_subdirectory(map_lnd2rof_irrig_test)
add_subdirectory(check_fields_test)
4 changes: 4 additions & 0 deletions src/drivers/mct/unit_test/check_fields_test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
create_pFUnit_test(check_fields check_fields_exe
"test_check_fields.pf" "")

target_link_libraries(check_fields_exe ${DRV_UNIT_TEST_LIBS})
99 changes: 99 additions & 0 deletions src/drivers/mct/unit_test/check_fields_test/test_check_fields.pf
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
module test_check_fields

! Tests of check_fields in the component_type_mod, check_fields looks for NaN values
! in fields passed from components to the coupler

use pfunit_mod
use component_type_mod
use mct_mod
use mct_wrapper_mod, only : mct_init, mct_clean
use avect_wrapper_mod
use create_mapper_mod
use shr_kind_mod, only : r8 => shr_kind_r8
use shr_infnan_mod, only : shr_infnan_nan, assignment(=)
implicit none

@TestCase
type, extends(TestCase) :: TestCheckFields
type(component_type) :: comp
contains
procedure :: setUp
procedure :: tearDown
end type TestCheckFields

contains

subroutine setUp(this)
class(TestCheckFields), intent(inout) :: this

call mct_init()
end subroutine setUp

subroutine tearDown(this)
class(TestCheckFields), intent(inout) :: this
call mct_aVect_clean(this%comp%c2x_cc)
call mct_clean()
end subroutine tearDown

@Test
subroutine createAVectWithoutData_1Field_checkField(this)
class(TestCheckFields), intent(inout) :: this
character(len=*), parameter :: attr_tag = 'foo'
integer, parameter :: lsize = 5 !
character(len=64) :: actual_rlist
real(r8) :: nan

nan = shr_infnan_nan
if(.not. associated(this%comp%c2x_cc)) allocate(this%comp%c2x_cc)
call create_aVect_without_data(this%comp%c2x_cc, [attr_tag], lsize)

actual_rlist = mct_aVect_exportRList2c(this%comp%c2x_cc)
@assertEqual('foo', trim(actual_rlist))

this%comp%c2x_cc%rattr(1,3) = nan

this%comp%name = 'pfunittest'

if(.not. associated(this%comp%gsmap_cc)) allocate(this%comp%gsmap_cc)

call create_gsmap(this%comp%gsmap_cc, lsize)

call check_fields(this%comp, 1)
@assertExceptionRaised('ABORTED: component_mod:check_fields NaN found in pfunittest instance: 1 field foo 1d global index: 3')

end subroutine createAVectWithoutData_1Field_checkField

@Test
subroutine createAVectWithoutData_3Field_checkFields(this)
class(TestCheckFields), intent(inout) :: this
character(len=*), parameter :: attr_tag1 = 'foo1'
character(len=*), parameter :: attr_tag2 = 'foo2'
character(len=*), parameter :: attr_tag3 = 'bar '
character(len=*), parameter :: expected_rlist = 'foo1:foo2:bar'
integer, parameter :: lsize = 5 ! not important for this test
character(len=64) :: actual_rlist
real(r8) :: nan

nan = shr_infnan_nan

this%comp%name = 'pfunittest'

if(.not. associated(this%comp%c2x_cc)) allocate(this%comp%c2x_cc)

call create_aVect_without_data(this%comp%c2x_cc, [attr_tag1, attr_tag2, attr_tag3], lsize)

actual_rlist = mct_aVect_exportRList2c(this%comp%c2x_cc)
@assertEqual(expected_rlist, actual_rlist)

if(.not. associated(this%comp%gsmap_cc)) allocate(this%comp%gsmap_cc)

this%comp%c2x_cc%rattr(2,3) = nan

call create_gsmap(this%comp%gsmap_cc, lsize)

call check_fields(this%comp, 1)

@assertExceptionRaised('ABORTED: component_mod:check_fields NaN found in pfunittest instance: 1 field foo2 1d global index: 3')
end subroutine createAVectWithoutData_3Field_checkFields

end module test_check_fields
1 change: 1 addition & 0 deletions src/drivers/mct/unit_test/utils/create_mapper_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ module create_mapper_mod

public :: create_mapper ! create a simple mapper
public :: clean_mapper ! deallocate memory associated with a mapper
public :: create_gsmap ! used in test_check_fields

contains

Expand Down